From f3e2e05bd74b0aab8441e57acf56b9fe430b755c Mon Sep 17 00:00:00 2001 From: Ching Date: Sat, 3 Jun 2023 18:36:08 +0800 Subject: [PATCH] =?UTF-8?q?feat(View):=20=E5=A2=9E=E5=8A=A0=20proile=20?= =?UTF-8?q?=E9=A1=B5=20status=20tags?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加 proile 页 status tags Signed-off-by: Ching --- duduji.xcodeproj/project.pbxproj | 4 + duduji/Core/MainTab/Views/MainTabView.swift | 2 +- .../ProfileTabFilterViewModel.swift | 28 ++ duduji/Core/Profile/Views/ProfileView.swift | 277 ++++++++++++++---- 4 files changed, 246 insertions(+), 65 deletions(-) create mode 100644 duduji/Core/Profile/ViewModels/ProfileTabFilterViewModel.swift diff --git a/duduji.xcodeproj/project.pbxproj b/duduji.xcodeproj/project.pbxproj index 9b25ca8..aa1289c 100644 --- a/duduji.xcodeproj/project.pbxproj +++ b/duduji.xcodeproj/project.pbxproj @@ -25,6 +25,7 @@ 24C1E59C2A07BB5C00F09364 /* NotificationRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24C1E59B2A07BB5C00F09364 /* NotificationRow.swift */; }; 24C1E5A12A07C9DE00F09364 /* ProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24C1E5A02A07C9DE00F09364 /* ProfileView.swift */; }; 24C1E5A32A07CA0000F09364 /* ProfileTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24C1E5A22A07CA0000F09364 /* ProfileTabView.swift */; }; + 24C1E5A52A222BA900F09364 /* ProfileTabFilterViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24C1E5A42A222BA900F09364 /* ProfileTabFilterViewModel.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -48,6 +49,7 @@ 24C1E59B2A07BB5C00F09364 /* NotificationRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationRow.swift; sourceTree = ""; }; 24C1E5A02A07C9DE00F09364 /* ProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileView.swift; sourceTree = ""; }; 24C1E5A22A07CA0000F09364 /* ProfileTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileTabView.swift; sourceTree = ""; }; + 24C1E5A42A222BA900F09364 /* ProfileTabFilterViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileTabFilterViewModel.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -267,6 +269,7 @@ 24C1E59F2A07C9D300F09364 /* ViewModels */ = { isa = PBXGroup; children = ( + 24C1E5A42A222BA900F09364 /* ProfileTabFilterViewModel.swift */, ); path = ViewModels; sourceTree = ""; @@ -347,6 +350,7 @@ 24C1E5962A07A9D300F09364 /* Avatar.swift in Sources */, 24A07CFC2A07A26A00F4ECA8 /* TimeLineTabView.swift in Sources */, 24A07CF32A03E80200F4ECA8 /* TimeLineView.swift in Sources */, + 24C1E5A52A222BA900F09364 /* ProfileTabFilterViewModel.swift in Sources */, 24C1E59C2A07BB5C00F09364 /* NotificationRow.swift in Sources */, 24A07CD02A026DDA00F4ECA8 /* dudujiApp.swift in Sources */, 24C1E5A12A07C9DE00F09364 /* ProfileView.swift in Sources */, diff --git a/duduji/Core/MainTab/Views/MainTabView.swift b/duduji/Core/MainTab/Views/MainTabView.swift index 6bec957..07ef641 100644 --- a/duduji/Core/MainTab/Views/MainTabView.swift +++ b/duduji/Core/MainTab/Views/MainTabView.swift @@ -44,7 +44,7 @@ struct MainTabView: View { Label("私信", systemImage: "tray.fill") } .tag(3) - TimeLineView() + ProfileView() .onTapGesture { self.selectedIndex = 4 } diff --git a/duduji/Core/Profile/ViewModels/ProfileTabFilterViewModel.swift b/duduji/Core/Profile/ViewModels/ProfileTabFilterViewModel.swift new file mode 100644 index 0000000..c21677f --- /dev/null +++ b/duduji/Core/Profile/ViewModels/ProfileTabFilterViewModel.swift @@ -0,0 +1,28 @@ +// +// ProfileTabFilterViewModel.swift +// duduji +// +// Created by ching on 2023/5/27. +// + +import Foundation + +enum ProfileTabFilterVeiwModel: Int, CaseIterable { + case statuses, favorites, bookmarks, followedTags, postsAndReplies, media, lists + + static var currentAccountTabs: [ProfileTabFilterVeiwModel] { + [.statuses, .favorites, .bookmarks, .followedTags, .lists] + } + + var iconName: String { + switch self { + case .statuses: return "bubble.right" + case .favorites: return "star" + case .bookmarks: return "bookmark" + case .followedTags: return "tag" + case .postsAndReplies: return "bubble.left.and.bubble.right" + case .media: return "photo.on.rectangle.angled" + case .lists: return "list.bullet" + } + } +} diff --git a/duduji/Core/Profile/Views/ProfileView.swift b/duduji/Core/Profile/Views/ProfileView.swift index 1d1a316..b7d3097 100644 --- a/duduji/Core/Profile/Views/ProfileView.swift +++ b/duduji/Core/Profile/Views/ProfileView.swift @@ -8,75 +8,224 @@ import SwiftUI struct ProfileView: View { + @State private var selectedTag: ProfileTabFilterVeiwModel = .statuses + var body: some View { - VStack(alignment: .leading) { - // banner & avarta - HStack { - Color(.systemRed) - } - .frame(height: 192) -// .ignoresSafeArea() + ScrollView { + VStack(alignment: .leading) { + bannerView + + avartarAndUserStatView + + userInfoView + + profileMetadataView + + featuredTagsView + + statusTagsFilterView + + TimeLineView() - // user stats - HStack(alignment: .top, spacing: 12) { - RoundedRectangle(cornerRadius: 6) - .fill(Color.blue) - .frame(width: 96, height: 96) - .overlay( - RoundedRectangle(cornerRadius: 6) - .stroke(.gray.opacity(0.5), lineWidth: 2) - ) - .padding(.horizontal) - .offset(y: -40) Spacer() - VStack { - Text("1234") - .bold() - .font(.title3) - .foregroundColor(.cyan) - Text("嘟文") - .foregroundColor(.gray) - } - VStack { - Text("1234") - .bold() - .font(.title3) - .foregroundColor(.cyan) - Text("关注") - .foregroundColor(.gray) - } - VStack { - Text("1234") - .bold() - .font(.title3) - .foregroundColor(.cyan) - Text("粉丝") - .foregroundColor(.gray) - } } - .padding(.bottom, -50) - .padding(.trailing) - - // user info - HStack(alignment: .firstTextBaseline) { - VStack(alignment: .leading, spacing: 6) { - Text("科代") - .font(.title3) - .bold() - Text("@Kedai") - .foregroundColor(.gray) - HStack(spacing: 2) { - Image(systemName: "calendar") - Text("加入于 2021 年 11 月 12 日") - } - .foregroundColor(.gray) - .font(.caption) - } - .padding() - } - - Spacer() } + .ignoresSafeArea() + } +} + +extension ProfileView { + var bannerView: some View { + // banner & avarta + HStack { + Color(.systemRed) +// .ignoresSafeArea() + } + .frame(height: 192) + } + + var avartarAndUserStatView: some View { + // user stats + HStack(alignment: .top, spacing: 12) { + RoundedRectangle(cornerRadius: 6) + .fill(Color.blue) + .frame(width: 96, height: 96) + .overlay( + RoundedRectangle(cornerRadius: 6) + .stroke(.gray.opacity(0.5), lineWidth: 2) + ) + .padding(.horizontal) + .offset(y: -40) + Spacer() + VStack { + Text("1234") + .bold() + .font(.title3) + .foregroundColor(.cyan) + Text("嘟文") + .foregroundColor(.gray) + } + VStack { + Text("1234") + .bold() + .font(.title3) + .foregroundColor(.cyan) + Text("关注") + .foregroundColor(.gray) + } + VStack { + Text("1234") + .bold() + .font(.title3) + .foregroundColor(.cyan) + Text("粉丝") + .foregroundColor(.gray) + } + } + .padding(.bottom, -50) + .padding(.trailing) + } + + var userInfoView: some View { + // user info + HStack(alignment: .firstTextBaseline) { + VStack(alignment: .leading, spacing: 6) { + Text("科代") + .font(.title3) + .bold() + Text("@Kedai") + .foregroundColor(.gray) + HStack(spacing: 2) { + Image(systemName: "calendar") + Text("加入于 2021 年 11 月 12 日") + } + .foregroundColor(.gray) + .font(.caption) + } + .padding([.horizontal, .top]) + } + } + + var profileMetadataView: some View { + HStack { + VStack(alignment: .leading) { + VStack(alignment: .leading, spacing: 2) { + Text("MFGA") + .bold() + Text("Make Fanfou Great Again!") + .foregroundColor(.cyan) + Divider() + .padding(.vertical, 4) + } + VStack(alignment: .leading, spacing: 4) { + Text("MFGA") + .bold() + + HStack { + Image(systemName: "checkmark.seal") + .foregroundColor(Color.green.opacity(0.80)) + Text("Make Fanfou Great Again!") + .foregroundColor(.cyan) + } + Divider() + .padding(.vertical, 4) + } + VStack(alignment: .leading, spacing: 2) { + Text("MFGA") + .bold() + Text("Make Fanfou Great Again!") + .foregroundColor(.cyan) + Divider() + .padding(.vertical, 4) + } + VStack(alignment: .leading, spacing: 2) { + Text("MFGA") + .bold() + Text("Make Fanfou Great Again!") + .foregroundColor(.cyan) + } + } + .padding(8) + .background(.gray.opacity(0.2)) + .cornerRadius(4) + .overlay( + RoundedRectangle(cornerRadius: 4) + .stroke(.gray.opacity(0.35), lineWidth: 1) + ) + } + .padding([.horizontal, .top]) + } + + var featuredTagsView: some View { + HStack { + ScrollView(.horizontal, showsIndicators: false) { + HStack(spacing: 4) { + Button { + // tags page + } label: { + VStack(alignment: .leading, spacing: 0) { + Text("#广东歌") + Text("45 条嘟文") + .font(.caption) + } + }.buttonStyle(.bordered) + Button { + // tags page + } label: { + VStack(alignment: .leading, spacing: 0) { + Text("#广东") + Text("45 条嘟文") + .font(.caption) + } + }.buttonStyle(.bordered) + + Button { + // tags page + } label: { + VStack(alignment: .leading, spacing: 0) { + Text("#广东歌") + Text("45 条嘟文") + .font(.caption) + } + }.buttonStyle(.bordered) + + Button { + // tags page + } label: { + VStack(alignment: .leading, spacing: 0) { + Text("#广东") + Text("4 条嘟文") + .font(.caption) + } + }.buttonStyle(.bordered) + + Button { + // tags page + } label: { + VStack(alignment: .leading, spacing: 0) { + Text("#广东歌") + Text("45 条嘟文") + .font(.caption) + } + }.buttonStyle(.bordered) + } + } + } + .padding([.horizontal, .top]) + } + + var statusTagsFilterView: some View { + HStack { + ScrollView { + Picker("tags", selection: $selectedTag) { + ForEach(ProfileTabFilterVeiwModel.currentAccountTabs, id: \.rawValue) { tag in + Image(systemName: tag.iconName) + } + } + .pickerStyle(.segmented) + } + } + .padding() } }