From 435e84c5247c404d3072abc6d69dd8a4177b8e3f Mon Sep 17 00:00:00 2001 From: JIWON1923 Date: Sun, 18 Jun 2023 23:08:13 +0900 Subject: [PATCH 01/53] =?UTF-8?q?[Style]=20#468=20init=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HappyAnding/HappyAnding/Model/Curation.swift | 22 ++++++++++++++++++++ HappyAnding/HappyAnding/Model/User.swift | 14 +++++++++++++ 2 files changed, 36 insertions(+) diff --git a/HappyAnding/HappyAnding/Model/Curation.swift b/HappyAnding/HappyAnding/Model/Curation.swift index 664a3445..1ef2833c 100644 --- a/HappyAnding/HappyAnding/Model/Curation.swift +++ b/HappyAnding/HappyAnding/Model/Curation.swift @@ -22,6 +22,28 @@ struct Curation: Identifiable, Equatable, Codable, Hashable { let data = (try? JSONEncoder().encode(self)) ?? Data() return (try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any]) ?? [:] } + + init(title: String, subtitle: String, isAdmin: Bool, background: String, author: String, shortcuts: [ShortcutCellModel]) { + self.id = UUID().uuidString + self.title = title + self.subtitle = subtitle + self.dateTime = Date().getDate() + self.isAdmin = isAdmin + self.background = background + self.author = author + self.shortcuts = shortcuts + } + + init() { + self.id = UUID().uuidString + self.title = "" + self.subtitle = "" + self.dateTime = Date().getDate() + self.isAdmin = false + self.background = "" + self.author = "" + self.shortcuts = [] + } } struct ShortcutCellModel: Identifiable, Codable, Equatable, Hashable { diff --git a/HappyAnding/HappyAnding/Model/User.swift b/HappyAnding/HappyAnding/Model/User.swift index 7c482f69..6ce01633 100644 --- a/HappyAnding/HappyAnding/Model/User.swift +++ b/HappyAnding/HappyAnding/Model/User.swift @@ -17,6 +17,20 @@ struct User: Identifiable, Codable, Hashable { let data = (try? JSONEncoder().encode(self)) ?? Data() return (try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any]) ?? [:] } + + init() { + self.id = "" + self.nickname = "" + self.likedShortcuts = [] + self.downloadedShortcuts = [] + } + + init(id: String, nickname: String, likedShortcuts: [String], downloadedShortcuts: [DownloadedShortcut]) { + self.id = id + self.nickname = nickname + self.likedShortcuts = likedShortcuts + self.downloadedShortcuts = downloadedShortcuts + } } struct DownloadedShortcut: Identifiable, Codable, Hashable { From 784843afea92943cecc1051f723e091782c8c9d7 Mon Sep 17 00:00:00 2001 From: JIWON1923 Date: Sun, 18 Jun 2023 23:10:18 +0900 Subject: [PATCH 02/53] =?UTF-8?q?[Feat]=20View=20Model=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: jim4020key --- .../HappyAnding.xcodeproj/project.pbxproj | 8 ++ .../Extensions/View/View+Navigation.swift | 4 +- .../ViewModel/ReadCurationViewModel.swift | 56 ++++++++++++ .../Components/UserCurationListView.swift | 5 +- .../ReadCurationView.swift | 87 +++++++------------ .../HappyAnding/Views/HappyAndingApp.swift | 2 +- .../WriteCurationSetView.swift | 13 +-- 7 files changed, 99 insertions(+), 76 deletions(-) create mode 100644 HappyAnding/HappyAnding/ViewModel/ReadCurationViewModel.swift diff --git a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj index e68c9c0a..c5b4439d 100644 --- a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj +++ b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj @@ -36,6 +36,9 @@ 8792478D2918CE450040D5C3 /* UINavigationContoller+Gesture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8792478C2918CE450040D5C3 /* UINavigationContoller+Gesture.swift */; }; 8792479B291BDF820040D5C3 /* SearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8792479A291BDF820040D5C3 /* SearchView.swift */; }; 8795A170292AB945004B765F /* UIScreen+Size.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8795A16F292AB945004B765F /* UIScreen+Size.swift */; }; + 8795A172292ABFDE004B765F /* ReadShortcutVersionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8795A171292ABFDE004B765F /* ReadShortcutVersionView.swift */; }; + 8795A174292ACA50004B765F /* ReadShortcutCommentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8795A173292ACA50004B765F /* ReadShortcutCommentView.swift */; }; + 87B47F3B2A3DC2740009E75F /* ReadCurationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87B47F3A2A3DC2740009E75F /* ReadCurationViewModel.swift */; }; 87CFD8492939187200F97B86 /* NicknameTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87CFD8482939187200F97B86 /* NicknameTextField.swift */; }; 87DBFB062A2127C0000CC442 /* CheckVersionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87DBFB052A2127C0000CC442 /* CheckVersionView.swift */; }; 87E606B0291062F900C3DA13 /* AppleAuthCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87E606AF291062F900C3DA13 /* AppleAuthCoordinator.swift */; }; @@ -206,6 +209,9 @@ 8792478C2918CE450040D5C3 /* UINavigationContoller+Gesture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationContoller+Gesture.swift"; sourceTree = ""; }; 8792479A291BDF820040D5C3 /* SearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchView.swift; sourceTree = ""; }; 8795A16F292AB945004B765F /* UIScreen+Size.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIScreen+Size.swift"; sourceTree = ""; }; + 8795A171292ABFDE004B765F /* ReadShortcutVersionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadShortcutVersionView.swift; sourceTree = ""; }; + 8795A173292ACA50004B765F /* ReadShortcutCommentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadShortcutCommentView.swift; sourceTree = ""; }; + 87B47F3A2A3DC2740009E75F /* ReadCurationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadCurationViewModel.swift; sourceTree = ""; }; 87CFD8482939187200F97B86 /* NicknameTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NicknameTextField.swift; sourceTree = ""; }; 87DBFB052A2127C0000CC442 /* CheckVersionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckVersionView.swift; sourceTree = ""; }; 87E606AD2910623C00C3DA13 /* HappyAnding.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = HappyAnding.entitlements; sourceTree = ""; }; @@ -596,6 +602,7 @@ A0F822AB2910B8F100AF4448 /* ShortcutsZipViewModel.swift */, 4D61A766291E1EE8000EF531 /* NavigationViewModel.swift */, F9AC2BB52935201C00165820 /* CheckUpdateVersion.swift */, + 87B47F3A2A3DC2740009E75F /* ReadCurationViewModel.swift */, ); path = ViewModel; sourceTree = ""; @@ -927,6 +934,7 @@ F9724BBF292755E400860F8A /* Comment.swift in Sources */, 87E99CA328FFF22E009B691F /* ExploreCurationView.swift in Sources */, A0F822B729164D2300AF4448 /* ListCategoryShortcutView.swift in Sources */, + 87B47F3B2A3DC2740009E75F /* ReadCurationViewModel.swift in Sources */, 872B5D3D2A2E0FF9008DCC57 /* CurationType.swift in Sources */, 4D3DBB88292E67E600DE8160 /* EditNicknameView.swift in Sources */, 87E99CE82907C6E6009B691F /* Shortcuts.swift in Sources */, diff --git a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift index 4e6df8e1..6df69992 100644 --- a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift +++ b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift @@ -82,7 +82,7 @@ extension View { case is NavigationReadShortcutType: ReadShortcutView(data: data as! NavigationReadShortcutType) case is NavigationReadCurationType: - ReadCurationView(data: data as! NavigationReadCurationType) + ReadCurationView(viewModel: ExploreCurationViewModel(data: data as! NavigationReadCurationType)) case is CurationType: ListCurationView(curationType: data as! CurationType) case is NavigationProfile: @@ -119,7 +119,7 @@ struct NavigationViewModifier: ViewModifier { ShowProfileView(data: data) } .navigationDestination(for: NavigationReadCurationType.self) { data in - ReadCurationView(data: data) + ReadCurationView(viewModel: ExploreCurationViewModel(data: data)) } .navigationDestination(for: CurationType.self) { data in ListCurationView(curationType: data) diff --git a/HappyAnding/HappyAnding/ViewModel/ReadCurationViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ReadCurationViewModel.swift new file mode 100644 index 00000000..97e5405b --- /dev/null +++ b/HappyAnding/HappyAnding/ViewModel/ReadCurationViewModel.swift @@ -0,0 +1,56 @@ +// +// ReadCurationViewModel.swift +// HappyAnding +// +// Created by 이지원 on 2023/06/17. +// + +import SwiftUI + + +final class ExploreCurationViewModel: ObservableObject { + var shortcutsZipViewModel = ShortcutsZipViewModel.share + + @Published var isWriting = false + @Published var isTappedDeleteButton = false + @Published var curation: Curation + @Published var shortcuts = [ShortcutCellModel]() + @Published var authInformation: User + @Published var gradeImage = Image(systemName: "person.crop.circle.fill") + @Published private(set) var isAdmin = false + + init(data: NavigationReadCurationType) { + self.curation = data.curation + self.authInformation = User() + fetchUserGrade() + } + + private func fetchUserGrade() { + shortcutsZipViewModel.fetchUser(userID: curation.author, + isCurrentUser: false) { user in + self.authInformation = user + let grade = self.shortcutsZipViewModel.checkShortcutGrade(userID: self.authInformation.id) + let image = self.shortcutsZipViewModel.fetchShortcutGradeImage(isBig: false, shortcutGrade: grade) + self.gradeImage = image + } + } + + func checkAuthor() -> Bool { + return curation.author == shortcutsZipViewModel.currentUser() + } + + func deleteCuration() { + shortcutsZipViewModel.deleteData(model: curation) + shortcutsZipViewModel.curationsMadeByUser = shortcutsZipViewModel.curationsMadeByUser.filter { $0.id != curation.id } + } + + func shareCuration() { + guard let deepLink = URL(string: "ShortcutsZip://myPage/CurationDetailView?curationID=\(curation.id)") else { return } + + let activityVC = UIActivityViewController(activityItems: [deepLink], applicationActivities: nil) + let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene + guard let window = windowScene?.windows.first else { return } + window.rootViewController?.present(activityVC, animated: true, completion: nil) + } +} + diff --git a/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift b/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift index 936f4c45..1f5139c1 100644 --- a/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift +++ b/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift @@ -18,6 +18,7 @@ struct UserCurationListView: View { @State var isWriting = false @State var data: CurationType + @State var curation = Curation() var body: some View { VStack(spacing: 0) { @@ -78,9 +79,7 @@ struct UserCurationListView: View { @ViewBuilder private func writeCurationView() -> some View { - WriteCurationSetView(isWriting: $isWriting - , isEdit: false - ) + WriteCurationSetView(isWriting: $isWriting, curation: $curation, isEdit: false) .navigationDestination(for: WriteCurationInfoType.self) { data in WriteCurationInfoView(data: data, isWriting: $isWriting) } diff --git a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift index adf759c0..8f3ed684 100644 --- a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift @@ -9,33 +9,24 @@ import SwiftUI struct ReadCurationView: View { @Environment(\.presentationMode) var presentation: Binding - - @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel @StateObject var writeCurationNavigation = WriteCurationNavigation() - - @State var authorInformation: User? = nil - @State var isWriting = false - @State var isTappedEditButton = false - @State var isTappedShareButton = false - @State var isTappedDeleteButton = false - @State var data: NavigationReadCurationType - @State var index = 0 + @StateObject var viewModel: ExploreCurationViewModel var body: some View { ScrollView(showsIndicators: false) { - if data.isAdmin { + if viewModel.isAdmin { adminCuration } else { userCuration } VStack(spacing: 0) { - ForEach(shortcutsZipViewModel.userCurations[index].shortcuts, id: \.self) { shortcut in + ForEach($viewModel.curation.shortcuts, id: \.self) { shortcut in let data = NavigationReadShortcutType(shortcutID: shortcut.id, - navigationParentView: self.data.navigationParentView) - ShortcutCell(shortcutCell: shortcut, - navigationParentView: self.data.navigationParentView) + navigationParentView: .curations) + ShortcutCell(shortcutCell: shortcut.wrappedValue, + navigationParentView: .curations) .navigationLinkRouter(data: data) } @@ -48,20 +39,19 @@ struct ReadCurationView: View { .edgesIgnoringSafeArea(.top) .navigationBarTitleDisplayMode(.inline) .navigationBarItems(trailing: readCurationViewButtonByUser()) - .fullScreenCover(isPresented: $isWriting) { + .fullScreenCover(isPresented: $viewModel.isWriting) { NavigationRouter(content: editView, path: $writeCurationNavigation.navigationPath) .environmentObject(writeCurationNavigation) } - .alert(TextLiteral.readCurationViewDeletionTitle, isPresented: $isTappedDeleteButton) { + .alert(TextLiteral.readCurationViewDeletionTitle, isPresented: $viewModel.isTappedDeleteButton) { Button(role: .cancel) { - self.isTappedDeleteButton.toggle() + viewModel.isTappedDeleteButton.toggle() } label: { Text(TextLiteral.cancel) } Button(role: .destructive) { - shortcutsZipViewModel.deleteData(model: self.data.curation) - shortcutsZipViewModel.curationsMadeByUser = shortcutsZipViewModel.curationsMadeByUser.filter { $0.id != self.data.curation.id } + viewModel.deleteCuration() presentation.wrappedValue.dismiss() } label: { Text(TextLiteral.delete) @@ -80,7 +70,7 @@ struct ReadCurationView: View { userInformation .padding(EdgeInsets(top: 103, leading: 16, bottom: 0, trailing: 16)) - UserCurationCell(curation: data.curation, navigationParentView: data.navigationParentView) + UserCurationCell(curation: viewModel.curation, navigationParentView: .curations) } } .padding(.bottom, 8) @@ -90,13 +80,13 @@ struct ReadCurationView: View { var adminCuration: some View { VStack { - StickyHeader(height: 304, image: data.curation.background) + StickyHeader(height: 304, image: viewModel.curation.background) .padding(.bottom, 20) HStack { VStack(alignment: .leading, spacing: 4) { - SubtitleTextView(text: data.curation.title) - Text(data.curation.subtitle.replacingOccurrences(of: "\\n", with: "\n")) + SubtitleTextView(text: viewModel.curation.title) + Text(viewModel.curation.subtitle.replacingOccurrences(of: "\\n", with: "\n")) .shortcutsZipBody2() .foregroundColor(.gray4) } @@ -108,16 +98,7 @@ struct ReadCurationView: View { } var userInformation: some View { ZStack { - UserNameCell(userInformation: self.authorInformation, gradeImage: shortcutsZipViewModel.fetchShortcutGradeImage(isBig: false, shortcutGrade: shortcutsZipViewModel.checkShortcutGrade(userID: authorInformation?.id ?? "!"))) - } - .onAppear { - shortcutsZipViewModel.fetchUser(userID: self.data.curation.author, - isCurrentUser: false) { user in - authorInformation = user - } - if let index = shortcutsZipViewModel.userCurations.firstIndex(where: { $0.id == data.curation.id}) { - self.index = index - } + UserNameCell(userInformation: viewModel.authInformation, gradeImage: viewModel.gradeImage) } } } @@ -127,18 +108,18 @@ extension ReadCurationView { @ViewBuilder private func editView() -> some View { - WriteCurationSetView(isWriting: $isWriting, - curation: shortcutsZipViewModel.userCurations[index] + WriteCurationSetView(isWriting: $viewModel.isWriting, + curation: $viewModel.curation ,isEdit: true ) .navigationDestination(for: WriteCurationInfoType.self) { data in - WriteCurationInfoView(data: data, isWriting: $isWriting) + WriteCurationInfoView(data: data, isWriting: $viewModel.isWriting) } } @ViewBuilder private func readCurationViewButtonByUser() -> some View { - if self.data.curation.author == shortcutsZipViewModel.currentUser() { + if viewModel.checkAuthor() { myCurationMenu } else { shareButton @@ -146,30 +127,30 @@ extension ReadCurationView { } private var myCurationMenu: some View { - Menu(content: { + Menu { Section { editButton shareButton deleteButton } - }, label: { + } label: { Image(systemName: "ellipsis") .foregroundColor(.gray4) - }) + } } private var editButton: some View { Button { - self.isWriting.toggle() + self.viewModel.isWriting.toggle() } label: { Label(TextLiteral.edit, systemImage: "square.and.pencil") } } private var shareButton: some View { - Button(action: { - shareCuration() - }) { + Button { + viewModel.shareCuration() + } label: { Label(TextLiteral.share, systemImage: "square.and.arrow.up") .foregroundColor(.gray4) .fontWeight(.medium) @@ -177,20 +158,10 @@ extension ReadCurationView { } private var deleteButton: some View { - Button(role: .destructive, action: { - isTappedDeleteButton.toggle() - }) { + Button(role: .destructive) { + viewModel.isTappedDeleteButton.toggle() + } label: { Label(TextLiteral.delete, systemImage: "trash.fill") } } - - private func shareCuration() { - guard let deepLink = URL(string: "ShortcutsZip://myPage/CurationDetailView?curationID=\(data.curation.id)") else { return } - - let activityVC = UIActivityViewController(activityItems: [deepLink], applicationActivities: nil) - let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene - guard let window = windowScene?.windows.first else { return } - window.rootViewController?.present(activityVC, animated: true, completion: nil) - } } - diff --git a/HappyAnding/HappyAnding/Views/HappyAndingApp.swift b/HappyAnding/HappyAnding/Views/HappyAndingApp.swift index b086a81b..918638ef 100644 --- a/HappyAnding/HappyAnding/Views/HappyAndingApp.swift +++ b/HappyAnding/HappyAnding/Views/HappyAndingApp.swift @@ -16,7 +16,7 @@ struct HappyAndingApp: App { @Environment(\.scenePhase) var scenePhase @Environment(\.openURL) private var openURL - @StateObject var shortcutsZipViewModel = ShortcutsZipViewModel() + @StateObject var shortcutsZipViewModel = ShortcutsZipViewModel.share @StateObject var loginAlerter = Alerter() @StateObject var gradeAlerter = Alerter() diff --git a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift index 54624019..0705abfe 100644 --- a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift +++ b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift @@ -16,12 +16,7 @@ struct WriteCurationSetView: View { @State var shortcutCells = [ShortcutCellModel]() @State var isSelected = false - @State var curation = Curation(title: "", - subtitle: "", - isAdmin: false, - background: "White", - author: "", - shortcuts: [ShortcutCellModel]()) + @Binding var curation: Curation @State var isTappedQuestionMark: Bool = false @State var deletedShortcutCells = [ShortcutCellModel]() @@ -123,9 +118,3 @@ struct WriteCurationSetView: View { .padding(.bottom, 20) } } - -struct WriteCurationSetView_Previews: PreviewProvider { - static var previews: some View { - WriteCurationSetView(isWriting: .constant(false), isEdit: false) - } -} From 63370d5bbf2ae2afd2d30bad4755663048b0d6b3 Mon Sep 17 00:00:00 2001 From: JIWON1923 Date: Sun, 18 Jun 2023 23:10:48 +0900 Subject: [PATCH 03/53] =?UTF-8?q?[Refactor]=20Curation=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=ED=99=9C=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: jim4020key --- .../Views/Components/UserCurationCell.swift | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/HappyAnding/HappyAnding/Views/Components/UserCurationCell.swift b/HappyAnding/HappyAnding/Views/Components/UserCurationCell.swift index bddd709b..fc2bd461 100644 --- a/HappyAnding/HappyAnding/Views/Components/UserCurationCell.swift +++ b/HappyAnding/HappyAnding/Views/Components/UserCurationCell.swift @@ -14,7 +14,6 @@ struct UserCurationCell: View { @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel @State var curation: Curation - @State var index = 0 var lineLimit: Int? let navigationParentView: NavigationParentView @@ -25,7 +24,7 @@ struct UserCurationCell: View { //MARK: - 단축어 아이콘 배열 HStack { - ForEach(shortcutsZipViewModel.userCurations[index].shortcuts.prefix(4), id: \.self) { shortcut in + ForEach(curation.shortcuts.prefix(4), id: \.self) { shortcut in ZStack { Rectangle() .fill(Color.fetchGradient(color: shortcut.color)) @@ -38,7 +37,7 @@ struct UserCurationCell: View { } //단축어가 4개 이상인 경우에만 그리는 아이콘 - if shortcutsZipViewModel.userCurations[index].shortcuts.count > 4 { + if curation.shortcuts.count > 4 { ZStack(alignment: .center) { Rectangle() .fill(Color.gray2) @@ -47,7 +46,7 @@ struct UserCurationCell: View { HStack(spacing: 0) { Image(systemName: "plus") .smallIcon() - Text("\(shortcutsZipViewModel.userCurations[index].shortcuts.count-4)") + Text("\(curation.shortcuts.count-4)") .shortcutsZipFootnote() } .foregroundColor(.gray5) @@ -59,11 +58,11 @@ struct UserCurationCell: View { //MARK: - curation title, subtitle - Text(shortcutsZipViewModel.userCurations[index].title) + Text(curation.title) .shortcutsZipHeadline() .foregroundColor(Color.gray5) .frame(maxWidth: .infinity, alignment: .leading) - Text(shortcutsZipViewModel.userCurations[index].subtitle.lineBreaking) + Text(curation.subtitle.lineBreaking) .shortcutsZipBody2() .multilineTextAlignment(.leading) .lineLimit(lineLimit) @@ -71,11 +70,6 @@ struct UserCurationCell: View { .padding(.bottom, 20) .fixedSize(horizontal: false, vertical: true) } - .onAppear() { - if let index = shortcutsZipViewModel.userCurations.firstIndex(of: curation) { - self.index = index - } - } .padding(.horizontal, 24) .background(Color.backgroudList) .overlay( From 94e3b873a652be73c90422d325921edc4cc8c8d0 Mon Sep 17 00:00:00 2001 From: JIWON1923 Date: Sun, 25 Jun 2023 18:46:03 +0900 Subject: [PATCH 04/53] =?UTF-8?q?[Style]=20#468=20-=20=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=20=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{ => ExploreCurationViewModels}/ReadCurationViewModel.swift | 2 +- .../Views/ExploreCurationViews/ReadCurationView.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename HappyAnding/HappyAnding/ViewModel/{ => ExploreCurationViewModels}/ReadCurationViewModel.swift (97%) diff --git a/HappyAnding/HappyAnding/ViewModel/ReadCurationViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift similarity index 97% rename from HappyAnding/HappyAnding/ViewModel/ReadCurationViewModel.swift rename to HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift index 97e5405b..e8d569e2 100644 --- a/HappyAnding/HappyAnding/ViewModel/ReadCurationViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift @@ -8,7 +8,7 @@ import SwiftUI -final class ExploreCurationViewModel: ObservableObject { +final class ReadCurationViewModel: ObservableObject { var shortcutsZipViewModel = ShortcutsZipViewModel.share @Published var isWriting = false diff --git a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift index 8f3ed684..5dbc6c8f 100644 --- a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift @@ -10,7 +10,7 @@ import SwiftUI struct ReadCurationView: View { @Environment(\.presentationMode) var presentation: Binding @StateObject var writeCurationNavigation = WriteCurationNavigation() - @StateObject var viewModel: ExploreCurationViewModel + @StateObject var viewModel: ReadCurationViewModel var body: some View { ScrollView(showsIndicators: false) { From 400f320bfd1a6cd2ae4e0bd7d4237e3f8488b2e1 Mon Sep 17 00:00:00 2001 From: JIWON1923 Date: Sun, 25 Jun 2023 18:48:02 +0900 Subject: [PATCH 05/53] =?UTF-8?q?[Feat]=20#472=20-=20ListCurationViewModel?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ListCurationViewModel.swift | 36 +++++++++++++++++++ .../ViewModel/ShortcutsZipViewModel.swift | 6 +++- .../ListCurationView.swift | 25 ++++--------- 3 files changed, 47 insertions(+), 20 deletions(-) create mode 100644 HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ListCurationViewModel.swift diff --git a/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ListCurationViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ListCurationViewModel.swift new file mode 100644 index 00000000..99668538 --- /dev/null +++ b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ListCurationViewModel.swift @@ -0,0 +1,36 @@ +// +// ListCurationViewModel.swift +// HappyAnding +// +// Created by 이지원 on 2023/06/25. +// + +import Foundation + +final class ListCurationViewModel: ObservableObject { + var shortcutsZipViewModel = ShortcutsZipViewModel.share + + @Published var curationType: CurationType + @Published private(set) var curationList = [Curation]() + @Published private(set) var sectionTitle: String = "" + + init(data: CurationType) { + self.curationType = data + self.curationList = curationType.filterCuration(from: shortcutsZipViewModel) + self.sectionTitle = fetchSectionTitle() + print("new viewModel: ", curationType, curationList) + } + + private func fetchSectionTitle() -> String { + switch curationType { + case .personalCuration: + return (shortcutsZipViewModel.userInfo?.nickname ?? "") + curationType.title + default: + return curationType.title + } + } + + func getEmptyContentsWording() -> String { + "아직 \(sectionTitle)\(sectionTitle.contains("단축어") ? "가" : "이") 없어요" + } +} diff --git a/HappyAnding/HappyAnding/ViewModel/ShortcutsZipViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ShortcutsZipViewModel.swift index 61208df4..6e3c3d64 100644 --- a/HappyAnding/HappyAnding/ViewModel/ShortcutsZipViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ShortcutsZipViewModel.swift @@ -32,7 +32,11 @@ class ShortcutsZipViewModel: ObservableObject { @Published var shortcutsInCategory: [[Shortcuts]] = [[Shortcuts]].init(repeating: [], count: Category.allCases.count) // Category에서 사용할 숏컷 배열 @Published var curationsMadeByUser: [Curation] = [] // 유저가 만든 큐레이션배열 - @Published var userCurations: [Curation] = [] + @Published var userCurations: [Curation] = [] { + didSet { + self.refreshPersonalCurations() + } + } @Published var personalCurations: [Curation] = [] // "땡땡님을 위한 모음집" 큐레이션배열 @Published var adminCurations: [Curation] = [] diff --git a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ListCurationView.swift b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ListCurationView.swift index 08cd740e..1caa61c7 100644 --- a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ListCurationView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ListCurationView.swift @@ -15,23 +15,12 @@ import SwiftUI struct ListCurationView: View { - @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel - - @State var curationType: CurationType - @State var curations = [Curation]() - - private var sectionTitle: String { - if curationType == .personalCuration { - return (shortcutsZipViewModel.userInfo?.nickname ?? "") + curationType.title - } else { - return curationType.title - } - } + @StateObject var viewModel: ListCurationViewModel var body: some View { VStack { - if curations.isEmpty { - Text("아직 \(sectionTitle)\(sectionTitle.contains("단축어") ? "가" : "이") 없어요") + if viewModel.curationList.isEmpty { + Text(viewModel.getEmptyContentsWording()) .shortcutsZipBody2() .foregroundColor(Color.gray4) .frame(maxWidth: .infinity, maxHeight: .infinity) @@ -41,7 +30,7 @@ struct ListCurationView: View { LazyVStack(spacing: 0) { Spacer() .frame(height: 20) - makeCurationCellList(curations) + makeCurationCellList(viewModel.curationList) Spacer() .frame(height: 32) @@ -55,16 +44,14 @@ struct ListCurationView: View { .background(Color.shortcutsZipBackground.ignoresSafeArea(.all, edges: .all)) .navigationBarBackground ({ Color.shortcutsZipBackground }) .navigationBarTitleDisplayMode(.inline) - .navigationTitle(sectionTitle) - .onAppear { - curations = curationType.filterCuration(from: shortcutsZipViewModel) - } + .navigationTitle(viewModel.sectionTitle) } @ViewBuilder private func makeCurationCellList(_ curations: [Curation]) -> some View { ForEach(Array(curations.enumerated()), id: \.offset) { index, curation in + // TODO: ReadcurationViewModels과 통합 let data = NavigationReadCurationType(curation: curation, navigationParentView: .curations) From e37e62445507a06ca692dc03f7e5eecb22ea73e5 Mon Sep 17 00:00:00 2001 From: JIWON1923 Date: Sun, 25 Jun 2023 18:48:33 +0900 Subject: [PATCH 06/53] =?UTF-8?q?[Feat]=20#472=20-=20Explore=20Curation=20?= =?UTF-8?q?View=20Model=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ExploreCurationViewModel.swift | 36 +++++++++++++++++++ .../ExploreCurationView.swift | 21 +++-------- .../Views/TabView/ShortcutTabView.swift | 2 +- 3 files changed, 41 insertions(+), 18 deletions(-) create mode 100644 HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ExploreCurationViewModel.swift diff --git a/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ExploreCurationViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ExploreCurationViewModel.swift new file mode 100644 index 00000000..36c2188f --- /dev/null +++ b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ExploreCurationViewModel.swift @@ -0,0 +1,36 @@ +// +// ExploreCurationViewModel.swift +// HappyAnding +// +// Created by 이지원 on 2023/06/25. +// + +import Foundation + +final class ExploreCurationViewModel: ObservableObject { + var shortcutsZipViewModel = ShortcutsZipViewModel.share + @Published var adminCurationList = [Curation]() + @Published var personalCurationList = [Curation]() + @Published var userCurationList = [Curation]() + + init() { + fetchAdminCurationList() + } + + private func fetchAdminCurationList() { + self.adminCurationList = shortcutsZipViewModel.adminCurations + } + + func getCurationList(with curationType: CurationType) -> [Curation] { + curationType.filterCuration(from: shortcutsZipViewModel) + } + + func getSectionTitle(with curationType: CurationType) -> String { + switch curationType { + case .personalCuration: + return (shortcutsZipViewModel.userInfo?.nickname ?? "") + curationType.title + default: + return curationType.title + } + } +} diff --git a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ExploreCurationView.swift b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ExploreCurationView.swift index 78014dd2..eeb34765 100644 --- a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ExploreCurationView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ExploreCurationView.swift @@ -9,8 +9,7 @@ import SwiftUI struct ExploreCurationView: View { - @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel - + @StateObject var viewModel: ExploreCurationViewModel @AppStorage("useWithoutSignIn") var useWithoutSignIn = false var body: some View { @@ -27,9 +26,6 @@ struct ExploreCurationView: View { } .padding(.top, 20) .padding(.bottom, 44) - .onChange(of: shortcutsZipViewModel.userCurations) { _ in - shortcutsZipViewModel.refreshPersonalCurations() - } } .navigationBarTitle(TextLiteral.exploreCurationViewTitle) .navigationBarTitleDisplayMode(.large) @@ -48,7 +44,7 @@ struct ExploreCurationView: View { ScrollView(.horizontal, showsIndicators: false) { HStack(spacing: 0) { - ForEach(shortcutsZipViewModel.adminCurations, id: \.id) { curation in + ForEach(viewModel.adminCurationList, id: \.id) { curation in AdminCurationCell(adminCuration: curation) .navigationLinkRouter(data: NavigationReadCurationType(isAdmin: true, curation: curation, @@ -64,19 +60,10 @@ struct ExploreCurationView: View { @ViewBuilder private func sectionView(with sectionType: CurationType) -> some View { - let curations = sectionType.filterCuration(from: shortcutsZipViewModel) - var sectionTitle: String { - if sectionType == .personalCuration { - return (shortcutsZipViewModel.userInfo?.nickname ?? "") + sectionType.title - } else { - return sectionType.title - } - } - VStack(spacing: 0) { HStack(alignment: .bottom) { - SubtitleTextView(text: sectionTitle) + SubtitleTextView(text: viewModel.getSectionTitle(with: sectionType)) Spacer() @@ -86,7 +73,7 @@ struct ExploreCurationView: View { .padding(.bottom, 12) .padding(.horizontal, 16) - ForEach(curations.prefix(2), id: \.self) { curation in + ForEach(viewModel.getCurationList(with:sectionType).prefix(2), id: \.self) { curation in let data = NavigationReadCurationType(curation: curation, navigationParentView: .curations) diff --git a/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift b/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift index f6750129..e0e4c94f 100644 --- a/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift +++ b/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift @@ -121,7 +121,7 @@ struct ShortcutTabView: View { @ViewBuilder private func secondTab() -> some View { - ExploreCurationView() + ExploreCurationView(viewModel: ExploreCurationViewModel()) .modifierNavigation() .navigationBarBackground ({ Color.shortcutsZipBackground }) .id(secondTabID) From fe76a7c4de6b2b5c65755a6e415a694893a62b1d Mon Sep 17 00:00:00 2001 From: JIWON1923 Date: Sun, 25 Jun 2023 18:48:46 +0900 Subject: [PATCH 07/53] =?UTF-8?q?[Feat]=20#472=20-=20ViewModel=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HappyAnding.xcodeproj/project.pbxproj | 22 ++++++++++++++----- .../Extensions/View/View+Navigation.swift | 8 +++---- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj index c5b4439d..58ab1920 100644 --- a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj +++ b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj @@ -33,11 +33,11 @@ 8786B33C29ABA588000B46A1 /* View+Gesture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8786B33B29ABA588000B46A1 /* View+Gesture.swift */; }; 8786B33E29ABA5A9000B46A1 /* View+Shape.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8786B33D29ABA5A9000B46A1 /* View+Shape.swift */; }; 8788374A2920D549009B3F54 /* Binding+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 878837492920D549009B3F54 /* Binding+Extension.swift */; }; + 8788E19D2A475AB3007C3852 /* ListCurationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8788E19C2A475AB3007C3852 /* ListCurationViewModel.swift */; }; + 8788E1A02A48408F007C3852 /* ExploreCurationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8788E19F2A48408F007C3852 /* ExploreCurationViewModel.swift */; }; 8792478D2918CE450040D5C3 /* UINavigationContoller+Gesture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8792478C2918CE450040D5C3 /* UINavigationContoller+Gesture.swift */; }; 8792479B291BDF820040D5C3 /* SearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8792479A291BDF820040D5C3 /* SearchView.swift */; }; 8795A170292AB945004B765F /* UIScreen+Size.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8795A16F292AB945004B765F /* UIScreen+Size.swift */; }; - 8795A172292ABFDE004B765F /* ReadShortcutVersionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8795A171292ABFDE004B765F /* ReadShortcutVersionView.swift */; }; - 8795A174292ACA50004B765F /* ReadShortcutCommentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8795A173292ACA50004B765F /* ReadShortcutCommentView.swift */; }; 87B47F3B2A3DC2740009E75F /* ReadCurationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87B47F3A2A3DC2740009E75F /* ReadCurationViewModel.swift */; }; 87CFD8492939187200F97B86 /* NicknameTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87CFD8482939187200F97B86 /* NicknameTextField.swift */; }; 87DBFB062A2127C0000CC442 /* CheckVersionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87DBFB052A2127C0000CC442 /* CheckVersionView.swift */; }; @@ -206,11 +206,11 @@ 8786B33B29ABA588000B46A1 /* View+Gesture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Gesture.swift"; sourceTree = ""; }; 8786B33D29ABA5A9000B46A1 /* View+Shape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Shape.swift"; sourceTree = ""; }; 878837492920D549009B3F54 /* Binding+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Binding+Extension.swift"; sourceTree = ""; }; + 8788E19C2A475AB3007C3852 /* ListCurationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListCurationViewModel.swift; sourceTree = ""; }; + 8788E19F2A48408F007C3852 /* ExploreCurationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExploreCurationViewModel.swift; sourceTree = ""; }; 8792478C2918CE450040D5C3 /* UINavigationContoller+Gesture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationContoller+Gesture.swift"; sourceTree = ""; }; 8792479A291BDF820040D5C3 /* SearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchView.swift; sourceTree = ""; }; 8795A16F292AB945004B765F /* UIScreen+Size.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIScreen+Size.swift"; sourceTree = ""; }; - 8795A171292ABFDE004B765F /* ReadShortcutVersionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadShortcutVersionView.swift; sourceTree = ""; }; - 8795A173292ACA50004B765F /* ReadShortcutCommentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadShortcutCommentView.swift; sourceTree = ""; }; 87B47F3A2A3DC2740009E75F /* ReadCurationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadCurationViewModel.swift; sourceTree = ""; }; 87CFD8482939187200F97B86 /* NicknameTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NicknameTextField.swift; sourceTree = ""; }; 87DBFB052A2127C0000CC442 /* CheckVersionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckVersionView.swift; sourceTree = ""; }; @@ -362,6 +362,16 @@ path = View; sourceTree = ""; }; + 8788E19E2A483FDF007C3852 /* ExploreCurationViewModels */ = { + isa = PBXGroup; + children = ( + 87B47F3A2A3DC2740009E75F /* ReadCurationViewModel.swift */, + 8788E19C2A475AB3007C3852 /* ListCurationViewModel.swift */, + 8788E19F2A48408F007C3852 /* ExploreCurationViewModel.swift */, + ); + path = ExploreCurationViewModels; + sourceTree = ""; + }; 87E606AE291062D300C3DA13 /* SignInViews */ = { isa = PBXGroup; children = ( @@ -599,10 +609,10 @@ A0F822AA2910B8B900AF4448 /* ViewModel */ = { isa = PBXGroup; children = ( + 8788E19E2A483FDF007C3852 /* ExploreCurationViewModels */, A0F822AB2910B8F100AF4448 /* ShortcutsZipViewModel.swift */, 4D61A766291E1EE8000EF531 /* NavigationViewModel.swift */, F9AC2BB52935201C00165820 /* CheckUpdateVersion.swift */, - 87B47F3A2A3DC2740009E75F /* ReadCurationViewModel.swift */, ); path = ViewModel; sourceTree = ""; @@ -888,6 +898,7 @@ 4D7D16072986BBD7008B3332 /* TextLiteral.swift in Sources */, 87E99CC128FFF2B5009B691F /* CategoryModalView.swift in Sources */, 87E606B829114FB200C3DA13 /* UserAuth.swift in Sources */, + 8788E1A02A48408F007C3852 /* ExploreCurationViewModel.swift in Sources */, 8786B33E29ABA5A9000B46A1 /* View+Shape.swift in Sources */, A3C404D62A23D0E800C3BA75 /* UpdateInfoView.swift in Sources */, F91A72C1299915C500CA135A /* MoreCaptionTextView.swift in Sources */, @@ -910,6 +921,7 @@ 87E606B22910649B00C3DA13 /* SignInWithAppleView.swift in Sources */, F91F09DF29AE0B5E00E04FA0 /* GradeAlertView.swift in Sources */, 87E99CEC29080C30009B691F /* Curation.swift in Sources */, + 8788E19D2A475AB3007C3852 /* ListCurationViewModel.swift in Sources */, F9136EB6293612310034AAB2 /* ShortcutsZipView.swift in Sources */, 87E99CB128FFF273009B691F /* WriteCurationSetView.swift in Sources */, 4D61A767291E1EE8000EF531 /* NavigationViewModel.swift in Sources */, diff --git a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift index 6df69992..132c0e66 100644 --- a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift +++ b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift @@ -82,9 +82,9 @@ extension View { case is NavigationReadShortcutType: ReadShortcutView(data: data as! NavigationReadShortcutType) case is NavigationReadCurationType: - ReadCurationView(viewModel: ExploreCurationViewModel(data: data as! NavigationReadCurationType)) + ReadCurationView(viewModel: ReadCurationViewModel(data: data as! NavigationReadCurationType)) case is CurationType: - ListCurationView(curationType: data as! CurationType) + ListCurationView(viewModel: ListCurationViewModel(data: data as! CurationType)) case is NavigationProfile: ShowProfileView(data: data as! NavigationProfile) case is NavigationSearch: @@ -119,10 +119,10 @@ struct NavigationViewModifier: ViewModifier { ShowProfileView(data: data) } .navigationDestination(for: NavigationReadCurationType.self) { data in - ReadCurationView(viewModel: ExploreCurationViewModel(data: data)) + ReadCurationView(viewModel: ReadCurationViewModel(data: data)) } .navigationDestination(for: CurationType.self) { data in - ListCurationView(curationType: data) + ListCurationView(viewModel: ListCurationViewModel(data: data)) } .navigationDestination(for: NavigationReadShortcutType.self) { data in ReadShortcutView(data: data) From 949476cb3701e747aff1543d5cb0fc14a3585b36 Mon Sep 17 00:00:00 2001 From: JIWON1923 Date: Sun, 25 Jun 2023 18:51:25 +0900 Subject: [PATCH 08/53] =?UTF-8?q?[Style]=20#472=20-=20=EB=B7=B0=EB=AA=A8?= =?UTF-8?q?=EB=8D=B8=20=ED=8F=B4=EB=8D=94=20=EA=B5=AC=EC=A1=B0=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HappyAnding.xcodeproj/project.pbxproj | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj index 58ab1920..a2ec4dac 100644 --- a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj +++ b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj @@ -372,6 +372,41 @@ path = ExploreCurationViewModels; sourceTree = ""; }; + 8788E1A12A484518007C3852 /* ExploreShortcutViewModels */ = { + isa = PBXGroup; + children = ( + ); + path = ExploreShortcutViewModels; + sourceTree = ""; + }; + 8788E1A22A484528007C3852 /* WriteShortcutViewModels */ = { + isa = PBXGroup; + children = ( + ); + path = WriteShortcutViewModels; + sourceTree = ""; + }; + 8788E1A32A484533007C3852 /* ReadShortcutViewModels */ = { + isa = PBXGroup; + children = ( + ); + path = ReadShortcutViewModels; + sourceTree = ""; + }; + 8788E1A42A484542007C3852 /* WriteCurationViewModels */ = { + isa = PBXGroup; + children = ( + ); + path = WriteCurationViewModels; + sourceTree = ""; + }; + 8788E1A52A48456E007C3852 /* MyPageViewModels */ = { + isa = PBXGroup; + children = ( + ); + path = MyPageViewModels; + sourceTree = ""; + }; 87E606AE291062D300C3DA13 /* SignInViews */ = { isa = PBXGroup; children = ( @@ -609,7 +644,12 @@ A0F822AA2910B8B900AF4448 /* ViewModel */ = { isa = PBXGroup; children = ( + 8788E1A12A484518007C3852 /* ExploreShortcutViewModels */, + 8788E1A22A484528007C3852 /* WriteShortcutViewModels */, + 8788E1A32A484533007C3852 /* ReadShortcutViewModels */, 8788E19E2A483FDF007C3852 /* ExploreCurationViewModels */, + 8788E1A42A484542007C3852 /* WriteCurationViewModels */, + 8788E1A52A48456E007C3852 /* MyPageViewModels */, A0F822AB2910B8F100AF4448 /* ShortcutsZipViewModel.swift */, 4D61A766291E1EE8000EF531 /* NavigationViewModel.swift */, F9AC2BB52935201C00165820 /* CheckUpdateVersion.swift */, From 7a1afe9bc4ad655728b8ce82917af76647ec1684 Mon Sep 17 00:00:00 2001 From: JIWON1923 Date: Sun, 25 Jun 2023 19:10:43 +0900 Subject: [PATCH 09/53] =?UTF-8?q?[Feat]=20#472=20-=20NavigationCurationTyp?= =?UTF-8?q?e=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Extensions/View/View+Navigation.swift | 6 +++--- .../HappyAnding/Model/NavigationStackModel.swift | 15 --------------- .../ReadCurationViewModel.swift | 5 +++-- .../Views/Components/UserCurationListView.swift | 4 +--- .../ExploreCurationView.swift | 8 ++------ .../ExploreCurationViews/ListCurationView.swift | 6 +----- .../Views/ReadShortcutViews/ShowProfileView.swift | 7 +++---- .../Views/TabView/ShortcutTabView.swift | 4 +--- 8 files changed, 14 insertions(+), 41 deletions(-) diff --git a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift index 132c0e66..d3722e17 100644 --- a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift +++ b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift @@ -81,8 +81,8 @@ extension View { ListShortcutView(data: data as! NavigationListShortcutType) case is NavigationReadShortcutType: ReadShortcutView(data: data as! NavigationReadShortcutType) - case is NavigationReadCurationType: - ReadCurationView(viewModel: ReadCurationViewModel(data: data as! NavigationReadCurationType)) + case is Curation: + ReadCurationView(viewModel: ReadCurationViewModel(data: data as! Curation)) case is CurationType: ListCurationView(viewModel: ListCurationViewModel(data: data as! CurationType)) case is NavigationProfile: @@ -118,7 +118,7 @@ struct NavigationViewModifier: ViewModifier { .navigationDestination(for: NavigationProfile.self) { data in ShowProfileView(data: data) } - .navigationDestination(for: NavigationReadCurationType.self) { data in + .navigationDestination(for: Curation.self) { data in ReadCurationView(viewModel: ReadCurationViewModel(data: data)) } .navigationDestination(for: CurationType.self) { data in diff --git a/HappyAnding/HappyAnding/Model/NavigationStackModel.swift b/HappyAnding/HappyAnding/Model/NavigationStackModel.swift index 0a4d41a7..5760ec24 100644 --- a/HappyAnding/HappyAnding/Model/NavigationStackModel.swift +++ b/HappyAnding/HappyAnding/Model/NavigationStackModel.swift @@ -23,21 +23,6 @@ struct NavigationReadShortcutType: Identifiable, Hashable { let navigationParentView: NavigationParentView } -struct NavigationReadCurationType: Identifiable, Hashable { - var id = UUID().uuidString - - var isAdmin: Bool = false - let curation: Curation - let navigationParentView: NavigationParentView -} - -struct NavigationListCurationType: Identifiable, Hashable { - var id = UUID().uuidString - - var type: CurationType - let navigationParentView: NavigationParentView -} - struct NavigationProfile: Identifiable, Hashable { var id = UUID().uuidString diff --git a/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift index e8d569e2..8706259b 100644 --- a/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift @@ -19,9 +19,10 @@ final class ReadCurationViewModel: ObservableObject { @Published var gradeImage = Image(systemName: "person.crop.circle.fill") @Published private(set) var isAdmin = false - init(data: NavigationReadCurationType) { - self.curation = data.curation + init(data: Curation) { + self.curation = data self.authInformation = User() + self.isAdmin = curation.isAdmin fetchUserGrade() } diff --git a/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift b/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift index 1f5139c1..2e45eae7 100644 --- a/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift +++ b/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift @@ -59,12 +59,10 @@ struct UserCurationListView: View { ForEach(Array(shortcutsZipViewModel.curationsMadeByUser.enumerated()), id: \.offset) { index, curation in if index < 2 { - let data = NavigationReadCurationType(curation: curation, - navigationParentView: .curations) UserCurationCell(curation: curation, lineLimit: 2, navigationParentView: .curations) - .navigationLinkRouter(data: data) + .navigationLinkRouter(data: curation) } } diff --git a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ExploreCurationView.swift b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ExploreCurationView.swift index eeb34765..86e29f7f 100644 --- a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ExploreCurationView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ExploreCurationView.swift @@ -46,9 +46,7 @@ struct ExploreCurationView: View { HStack(spacing: 0) { ForEach(viewModel.adminCurationList, id: \.id) { curation in AdminCurationCell(adminCuration: curation) - .navigationLinkRouter(data: NavigationReadCurationType(isAdmin: true, - curation: curation, - navigationParentView: .curations)) + .navigationLinkRouter(data: curation) } } .padding(.trailing, 8) @@ -74,13 +72,11 @@ struct ExploreCurationView: View { .padding(.horizontal, 16) ForEach(viewModel.getCurationList(with:sectionType).prefix(2), id: \.self) { curation in - let data = NavigationReadCurationType(curation: curation, - navigationParentView: .curations) UserCurationCell(curation: curation, lineLimit: 2, navigationParentView: .curations) - .navigationLinkRouter(data: data) + .navigationLinkRouter(data: curation) } } } diff --git a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ListCurationView.swift b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ListCurationView.swift index 1caa61c7..70f0dcc8 100644 --- a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ListCurationView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ListCurationView.swift @@ -51,14 +51,10 @@ struct ListCurationView: View { private func makeCurationCellList(_ curations: [Curation]) -> some View { ForEach(Array(curations.enumerated()), id: \.offset) { index, curation in - // TODO: ReadcurationViewModels과 통합 - let data = NavigationReadCurationType(curation: curation, - navigationParentView: .curations) - UserCurationCell(curation: curation, lineLimit: 2, navigationParentView: .curations) - .navigationLinkRouter(data: data) + .navigationLinkRouter(data: curation) .listRowInsets(EdgeInsets()) .listRowSeparator(.hidden) .listRowBackground(Color.shortcutsZipBackground) diff --git a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift index 652b1a46..3fc3a211 100644 --- a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift +++ b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift @@ -165,12 +165,11 @@ extension ShowProfileView { VStack(spacing: 0) { ForEach(curations, id: \.self) { curation in - let data = NavigationReadCurationType(curation: curation, - navigationParentView: .shortcuts) + // TODO: navigation parent view 삭제 UserCurationCell(curation: curation, lineLimit: 2, - navigationParentView: data.navigationParentView) - .navigationLinkRouter(data: data) + navigationParentView: .curations) + .navigationLinkRouter(data: curation) } Spacer() diff --git a/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift b/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift index e0e4c94f..db91ece5 100644 --- a/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift +++ b/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift @@ -175,9 +175,7 @@ struct ShortcutTabView: View { isCurationDeeplink = true if let curation = shortcutsZipViewModel.fetchCurationDetail(curationID: tempCurationId) { - let data = NavigationReadCurationType(curation: curation, - navigationParentView: .myPage) - navigateLink(data: data) + navigateLink(data: curation) } } From 21f7f14a2ac5dd5bf8f5ed3f4adf77decf56c733 Mon Sep 17 00:00:00 2001 From: JIWON1923 Date: Sun, 25 Jun 2023 19:34:16 +0900 Subject: [PATCH 10/53] =?UTF-8?q?[Refactor]=20#468=20-=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: jim4020key --- .../ReadCurationViewModel.swift | 5 ++--- .../Views/ExploreCurationViews/ReadCurationView.swift | 11 +++-------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift index 8706259b..41c37834 100644 --- a/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift @@ -14,9 +14,8 @@ final class ReadCurationViewModel: ObservableObject { @Published var isWriting = false @Published var isTappedDeleteButton = false @Published var curation: Curation - @Published var shortcuts = [ShortcutCellModel]() - @Published var authInformation: User - @Published var gradeImage = Image(systemName: "person.crop.circle.fill") + @Published private(set) var authInformation: User + @Published private(set) var gradeImage = Image(systemName: "person.crop.circle.fill") @Published private(set) var isAdmin = false init(data: Curation) { diff --git a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift index 5dbc6c8f..291a764c 100644 --- a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift @@ -67,7 +67,7 @@ struct ReadCurationView: View { StickyHeader(height: 100) VStack(spacing: 16) { - userInformation + UserNameCell(userInformation: viewModel.authInformation, gradeImage: viewModel.gradeImage) .padding(EdgeInsets(top: 103, leading: 16, bottom: 0, trailing: 16)) UserCurationCell(curation: viewModel.curation, navigationParentView: .curations) @@ -96,11 +96,6 @@ struct ReadCurationView: View { .padding(.bottom, 8) } } - var userInformation: some View { - ZStack { - UserNameCell(userInformation: viewModel.authInformation, gradeImage: viewModel.gradeImage) - } - } } @@ -109,8 +104,8 @@ extension ReadCurationView { @ViewBuilder private func editView() -> some View { WriteCurationSetView(isWriting: $viewModel.isWriting, - curation: $viewModel.curation - ,isEdit: true + curation: $viewModel.curation, + isEdit: true ) .navigationDestination(for: WriteCurationInfoType.self) { data in WriteCurationInfoView(data: data, isWriting: $viewModel.isWriting) From 3a50e444abba9f98966ac9b5e5cdcc9ef99b0ff9 Mon Sep 17 00:00:00 2001 From: JIWON1923 Date: Sun, 25 Jun 2023 19:45:35 +0900 Subject: [PATCH 11/53] =?UTF-8?q?[Fix]=20#468=20-=20=ED=83=88=ED=87=B4?= =?UTF-8?q?=ED=95=9C=20=ED=9A=8C=EC=9B=90=20=EC=A0=95=EB=B3=B4=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HappyAnding/Views/Components/UserNameCell.swift | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/HappyAnding/HappyAnding/Views/Components/UserNameCell.swift b/HappyAnding/HappyAnding/Views/Components/UserNameCell.swift index af160989..ab5dd37a 100644 --- a/HappyAnding/HappyAnding/Views/Components/UserNameCell.swift +++ b/HappyAnding/HappyAnding/Views/Components/UserNameCell.swift @@ -31,9 +31,15 @@ struct UserNameCell: View { .frame(width: 24, height: 24) .foregroundColor(.gray3) - Text(userInformation?.nickname ?? TextLiteral.withdrawnUser) - .shortcutsZipBody2() - .foregroundColor(.gray4) + if let userInformation, !userInformation.nickname.isEmpty { + Text(userInformation.nickname) + .shortcutsZipBody2() + .foregroundColor(.gray4) + } else { + Text(TextLiteral.withdrawnUser) + .shortcutsZipBody2() + .foregroundColor(.gray4) + } Spacer() From e01ab0db559472c4da922865d4c0a8f7783f6932 Mon Sep 17 00:00:00 2001 From: Jeon Jimin Date: Sun, 25 Jun 2023 20:32:40 +0900 Subject: [PATCH 12/53] =?UTF-8?q?[Feat]=20#470=20-=20WriteCurationViewMode?= =?UTF-8?q?l=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 변수 위치 수정 - NavigationStack 변수 타입 변경 -> WriteCurationViewModel.Self todo: - CheckBoxShortcutCell 합치기 - 좋아요&작성한 단축어 정렬 확인하기 --- .../HappyAnding.xcodeproj/project.pbxproj | 4 ++ .../Extensions/View/View+Navigation.swift | 4 +- .../ViewModel/WriteCurationViewModel.swift | 67 +++++++++++++++++++ .../Components/UserCurationListView.swift | 10 ++- .../ReadCurationView.swift | 9 +-- .../WriteCurationInfoView.swift | 37 +++------- .../WriteCurationSetView.swift | 53 ++++----------- 7 files changed, 103 insertions(+), 81 deletions(-) create mode 100644 HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift diff --git a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj index e68c9c0a..f4168910 100644 --- a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj +++ b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj @@ -124,6 +124,7 @@ F94B435F2907B19A00987819 /* FirebaseAuth in Frameworks */ = {isa = PBXBuildFile; productRef = F94B435E2907B19A00987819 /* FirebaseAuth */; }; F94B43612907B19A00987819 /* FirebaseFirestore in Frameworks */ = {isa = PBXBuildFile; productRef = F94B43602907B19A00987819 /* FirebaseFirestore */; }; F94B43632907B19A00987819 /* FirebaseFirestoreCombine-Community in Frameworks */ = {isa = PBXBuildFile; productRef = F94B43622907B19A00987819 /* FirebaseFirestoreCombine-Community */; }; + F95F26542A45C89400B534EB /* WriteCurationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F95F26532A45C89400B534EB /* WriteCurationViewModel.swift */; }; F96D45B72980301F000C2441 /* SubtitleTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96D45B62980301F000C2441 /* SubtitleTextView.swift */; }; F96D45BB29804057000C2441 /* EnvironmentValues+Alerter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96D45BA29804057000C2441 /* EnvironmentValues+Alerter.swift */; }; F96D45BD29816578000C2441 /* StickyHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96D45BC29816578000C2441 /* StickyHeader.swift */; }; @@ -277,6 +278,7 @@ F91F09DC29AE012600E04FA0 /* ShortcutGrade.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutGrade.swift; sourceTree = ""; }; F91F09DE29AE0B5E00E04FA0 /* GradeAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradeAlertView.swift; sourceTree = ""; }; F94B432D2907088400987819 /* UserCurationListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserCurationListView.swift; sourceTree = ""; }; + F95F26532A45C89400B534EB /* WriteCurationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WriteCurationViewModel.swift; sourceTree = ""; }; F96D45B62980301F000C2441 /* SubtitleTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubtitleTextView.swift; sourceTree = ""; }; F96D45BA29804057000C2441 /* EnvironmentValues+Alerter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EnvironmentValues+Alerter.swift"; sourceTree = ""; }; F96D45BC29816578000C2441 /* StickyHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickyHeader.swift; sourceTree = ""; }; @@ -596,6 +598,7 @@ A0F822AB2910B8F100AF4448 /* ShortcutsZipViewModel.swift */, 4D61A766291E1EE8000EF531 /* NavigationViewModel.swift */, F9AC2BB52935201C00165820 /* CheckUpdateVersion.swift */, + F95F26532A45C89400B534EB /* WriteCurationViewModel.swift */, ); path = ViewModel; sourceTree = ""; @@ -863,6 +866,7 @@ 87E99CD929042536009B691F /* SectionType.swift in Sources */, 872A7D8F2918393B004A05B8 /* PrivacyPolicyView.swift in Sources */, A38115BA292B447D0043E8B8 /* ShortcutCardCell.swift in Sources */, + F95F26542A45C89400B534EB /* WriteCurationViewModel.swift in Sources */, 8792479B291BDF820040D5C3 /* SearchView.swift in Sources */, A3FF018E291ACFA500384211 /* WithdrawalView.swift in Sources */, 4D778A34290A53BA00C15AC4 /* UIApplication+Keyboard.swift in Sources */, diff --git a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift index 4e6df8e1..7b042c34 100644 --- a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift +++ b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift @@ -67,8 +67,8 @@ extension View { @ViewBuilder func getDestination(data: T, isPresented: Binding) -> some View { switch data { - case is WriteCurationInfoType: - WriteCurationInfoView(data: data as! WriteCurationInfoType, isWriting: isPresented) + case is WriteCurationViewModel: + WriteCurationInfoView(viewModel: data as! WriteCurationViewModel) default: EmptyView() } diff --git a/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift b/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift new file mode 100644 index 00000000..7c08911b --- /dev/null +++ b/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift @@ -0,0 +1,67 @@ +// +// WriteCurationViewModel.swift +// HappyAnding +// +// Created by JeonJimin on 2023/06/23. +// + +import SwiftUI + +final class WriteCurationViewModel: ObservableObject, Hashable { + + static func == (lhs: WriteCurationViewModel, rhs: WriteCurationViewModel) -> Bool { + return false + } + func hash(into hasher: inout Hasher) { + hasher.combine(curation) + } + + private var shortcutsZipViewModel = ShortcutsZipViewModel.share + + //WriteCurationSet + @Published var isWriting = false + @Published var isEdit = false + + //좋아요 + 내가 작성한 단축어 목록 + @Published var shortcutCells = [ShortcutCellModel]() + //모음집 편집 시 전달받는 기존 모음집 정보 + @Published var curation = Curation(title: "", subtitle: "", isAdmin: false, background: "", author: "", shortcuts: [ShortcutCellModel]()) + + @Published var isTappedQuestionMark = false + //기존 선택 -> 편집 시 선택 해제 되어 기존 모음집 정보에서 삭제해야할 단축어 배열 + @Published var deletedShortcutCells = [ShortcutCellModel]() + + + //WriteCurationInfo + @Published var writeCurationNavigation = WriteCurationNavigation() + @Published var isValidTitle = false + @Published var isValidDescription = false + + var isIncomplete: Bool { + !(isValidTitle && isValidDescription) + } + + init() { + + } + + init(data: Curation) { + self.curation = data + } + + func fetchMakeCuration() { + shortcutCells = shortcutsZipViewModel.fetchShortcutMakeCuration().sorted { $0.title < $1.title } + if isEdit { + deletedShortcutCells = curation.shortcuts + } + } + + func addCuration() { + shortcutsZipViewModel.addCuration(curation: curation, isEdit: isEdit, deletedShortcutCells: deletedShortcutCells) + + self.isWriting.toggle() + if #available(iOS 16.1, *) { + writeCurationNavigation.navigationPath = .init() + } + } +} diff --git a/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift b/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift index 936f4c45..e4d42119 100644 --- a/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift +++ b/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift @@ -78,12 +78,10 @@ struct UserCurationListView: View { @ViewBuilder private func writeCurationView() -> some View { - WriteCurationSetView(isWriting: $isWriting - , isEdit: false - ) - .navigationDestination(for: WriteCurationInfoType.self) { data in - WriteCurationInfoView(data: data, isWriting: $isWriting) - } + WriteCurationSetView(viewModel: WriteCurationViewModel()) + .navigationDestination(for: WriteCurationViewModel.self) { data in + WriteCurationInfoView(viewModel: data) + } } } diff --git a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift index adf759c0..bd832e37 100644 --- a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift @@ -127,12 +127,9 @@ extension ReadCurationView { @ViewBuilder private func editView() -> some View { - WriteCurationSetView(isWriting: $isWriting, - curation: shortcutsZipViewModel.userCurations[index] - ,isEdit: true - ) - .navigationDestination(for: WriteCurationInfoType.self) { data in - WriteCurationInfoView(data: data, isWriting: $isWriting) + WriteCurationSetView(viewModel: WriteCurationViewModel(data: data.curation)) + .navigationDestination(for: WriteCurationViewModel.self) { data in + WriteCurationInfoView(viewModel: data) } } diff --git a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationInfoView.swift b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationInfoView.swift index 52a023ae..14b382ec 100644 --- a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationInfoView.swift +++ b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationInfoView.swift @@ -8,22 +8,10 @@ import SwiftUI struct WriteCurationInfoView: View { - - @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel - @EnvironmentObject var writeCurationNavigation: WriteCurationNavigation + @StateObject var viewModel: WriteCurationViewModel @FocusState var isDescriptionFieldFocused: Bool - @State var data: WriteCurationInfoType - @Binding var isWriting: Bool - - @State var isValidTitle = false - @State var isValidDescription = false - - private var isIncomplete: Bool { - !(isValidTitle && isValidDescription) - } - var body: some View { VStack(spacing: 24) { ProgressView(value: 2, total: 2) @@ -34,8 +22,8 @@ struct WriteCurationInfoView: View { placeholder: TextLiteral.writeCurationInfoViewNamePlaceholder, lengthLimit: 20, isDownloadLinkTextField: false, - content: $data.curation.title, - isValid: $isValidTitle) + content: $viewModel.curation.title, + isValid: $viewModel.isValidTitle) .padding(.top, 12) .onSubmit { isDescriptionFieldFocused = true @@ -49,9 +37,8 @@ struct WriteCurationInfoView: View { lengthLimit: 40, isDownloadLinkTextField: false, inputHeight: 72, - content: Binding(get: {data.curation.subtitle}, - set: {data.curation.subtitle = $0}), - isValid: $isValidDescription) + content: $viewModel.curation.subtitle, + isValid: $viewModel.isValidDescription) .focused($isDescriptionFieldFocused) Spacer() @@ -60,23 +47,17 @@ struct WriteCurationInfoView: View { .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button { - - shortcutsZipViewModel.addCuration(curation: data.curation, isEdit: data.isEdit, deletedShortcutCells: data.deletedShortcutCells) - - self.isWriting.toggle() - if #available(iOS 16.1, *) { - writeCurationNavigation.navigationPath = .init() - } + viewModel.addCuration() } label: { Text(TextLiteral.upload) .shortcutsZipHeadline() - .foregroundColor(isIncomplete ? .shortcutsZipPrimary.opacity(0.3) : .shortcutsZipPrimary) + .foregroundColor(viewModel.isIncomplete ? .shortcutsZipPrimary.opacity(0.3) : .shortcutsZipPrimary) } - .disabled(isIncomplete) + .disabled(viewModel.isIncomplete) } } .background(Color.shortcutsZipBackground) - .navigationBarTitle(data.isEdit ? TextLiteral.writeCurationInfoViewEdit : TextLiteral.wrietCurationInfoViewPost) + .navigationBarTitle(viewModel.isEdit ? TextLiteral.writeCurationInfoViewEdit : TextLiteral.wrietCurationInfoViewPost) .onAppear(perform : UIApplication.shared.hideKeyboard) } } diff --git a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift index 54624019..3da6d3ad 100644 --- a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift +++ b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift @@ -9,23 +9,7 @@ import SwiftUI struct WriteCurationSetView: View { - @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel - @EnvironmentObject var writeCurationNavigation: WriteCurationNavigation - - @Binding var isWriting: Bool - - @State var shortcutCells = [ShortcutCellModel]() - @State var isSelected = false - @State var curation = Curation(title: "", - subtitle: "", - isAdmin: false, - background: "White", - author: "", - shortcuts: [ShortcutCellModel]()) - @State var isTappedQuestionMark: Bool = false - @State var deletedShortcutCells = [ShortcutCellModel]() - - let isEdit: Bool + @StateObject var viewModel: WriteCurationViewModel var body: some View { VStack { @@ -34,7 +18,7 @@ struct WriteCurationSetView: View { listHeader infomation - if shortcutCells.isEmpty { + if viewModel.shortcutCells.isEmpty { Spacer() Text(TextLiteral.writeCurationSetViewNoShortcuts) .shortcutsZipBody2() @@ -47,31 +31,28 @@ struct WriteCurationSetView: View { } } .background(Color.shortcutsZipBackground) - .navigationTitle(isEdit ? TextLiteral.writeCurationSetViewEdit : TextLiteral.writeCurationSetViewPost) + .navigationTitle(viewModel.isEdit ? TextLiteral.writeCurationSetViewEdit : TextLiteral.writeCurationSetViewPost) .navigationBarTitleDisplayMode(.inline) .onAppear { - self.shortcutCells = shortcutsZipViewModel.fetchShortcutMakeCuration().sorted { $0.title < $1.title } - if isEdit { - deletedShortcutCells = curation.shortcuts - } + viewModel.fetchMakeCuration() } .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button { - self.isWriting.toggle() + viewModel.isWriting.toggle() } label: { Text(TextLiteral.cancel) .shortcutsZipBody1() .foregroundColor(.gray4) } } - + ToolbarItem(placement: .navigationBarTrailing) { Text(TextLiteral.next) - .navigationLinkRouter(data: WriteCurationInfoType(curation: curation, deletedShortcutCells: deletedShortcutCells, isEdit: isEdit), isPresented: $isWriting) + .navigationLinkRouter(data: viewModel, isPresented: $viewModel.isWriting) .shortcutsZipHeadline() - .foregroundColor(curation.shortcuts.isEmpty ? .shortcutsZipPrimary.opacity(0.3) : .shortcutsZipPrimary) - .disabled(curation.shortcuts.isEmpty) + .foregroundColor(viewModel.curation.shortcuts.isEmpty ? .shortcutsZipPrimary.opacity(0.3) : .shortcutsZipPrimary) + .disabled(viewModel.curation.shortcuts.isEmpty) } } } @@ -86,7 +67,7 @@ struct WriteCurationSetView: View { .shortcutsZipFootnote() .foregroundColor(.gray3) Spacer() - Text("\(curation.shortcuts.count)개") + Text("\(viewModel.curation.shortcuts.count)개") .shortcutsZipBody2() .foregroundColor(.shortcutsZipPrimary) } @@ -97,11 +78,11 @@ struct WriteCurationSetView: View { var shortcutList: some View { ScrollView { - ForEach(Array(shortcutCells)) { shortcut in + ForEach(Array(viewModel.shortcutCells)) { shortcut in CheckBoxShortcutCell( - selectedShortcutCells: $curation.shortcuts, isShortcutTapped: curation.shortcuts.contains(shortcut), - shortcutCell: shortcut - ) + selectedShortcutCells: $viewModel.curation.shortcuts, + isShortcutTapped: $viewModel.curation.shortcuts.contains{$0.id == shortcut.id}, + shortcutCell: shortcut) } } .frame(maxWidth: .infinity) @@ -123,9 +104,3 @@ struct WriteCurationSetView: View { .padding(.bottom, 20) } } - -struct WriteCurationSetView_Previews: PreviewProvider { - static var previews: some View { - WriteCurationSetView(isWriting: .constant(false), isEdit: false) - } -} From d636f8d608edd3451a0045e9f2c9c539721ea09a Mon Sep 17 00:00:00 2001 From: Jeon Jimin Date: Fri, 30 Jun 2023 21:26:33 +0900 Subject: [PATCH 13/53] =?UTF-8?q?[Feat]=20#470=20-=20checkbox=20shortcut?= =?UTF-8?q?=20=EB=B7=B0=EB=AA=A8=EB=8D=B8=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewModel/WriteCurationViewModel.swift | 32 ++++++++++-- .../CheckBoxShortcutCell.swift | 49 ++++++------------- .../WriteCurationSetView.swift | 7 +-- 3 files changed, 45 insertions(+), 43 deletions(-) diff --git a/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift b/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift index 7c08911b..ad1e25f1 100644 --- a/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift @@ -24,6 +24,9 @@ final class WriteCurationViewModel: ObservableObject, Hashable { //좋아요 + 내가 작성한 단축어 목록 @Published var shortcutCells = [ShortcutCellModel]() + //CheckboxShortcutCell 선택 여부 저장 + @Published var isShortcutsTapped: [Bool] = [] + //모음집 편집 시 전달받는 기존 모음집 정보 @Published var curation = Curation(title: "", subtitle: "", isAdmin: false, background: "", author: "", shortcuts: [ShortcutCellModel]()) @@ -41,9 +44,7 @@ final class WriteCurationViewModel: ObservableObject, Hashable { !(isValidTitle && isValidDescription) } - init() { - - } + init() { } init(data: Curation) { self.curation = data @@ -54,6 +55,14 @@ final class WriteCurationViewModel: ObservableObject, Hashable { if isEdit { deletedShortcutCells = curation.shortcuts } + + //isShortcutsTapped 초기화 + isShortcutsTapped = [Bool](repeating: false, count: shortcutCells.count) + for shortcut in curation.shortcuts { + if let index = shortcutCells.firstIndex(of: shortcut) { + isShortcutsTapped[index] = true + } + } } func addCuration() { @@ -64,4 +73,21 @@ final class WriteCurationViewModel: ObservableObject, Hashable { writeCurationNavigation.navigationPath = .init() } } + + func checkboxCellTapGesture(idx: Int) { + if isShortcutsTapped[idx] { + isShortcutsTapped[idx] = false + // TODO: 현재는 name을 기준으로 검색중, id로 검색해서 삭제해야함 / Shortcuts 자체를 배열에 저장해야함 + + if let index = curation.shortcuts.firstIndex(of: shortcutCells[idx]) { + curation.shortcuts.remove(at: index) + } + } + else { + if curation.shortcuts.count < 10 { + curation.shortcuts.append(shortcutCells[idx]) + isShortcutsTapped[idx] = true + } + } + } } diff --git a/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift b/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift index 5a2dedf8..b763d5d2 100644 --- a/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift +++ b/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift @@ -9,11 +9,9 @@ import SwiftUI struct CheckBoxShortcutCell: View { - @Binding var selectedShortcutCells: [ShortcutCellModel] - - @State var isShortcutTapped: Bool = false - - let shortcutCell: ShortcutCellModel + @StateObject var viewModel: WriteCurationViewModel + + let idx: Int var body: some View { @@ -31,30 +29,16 @@ struct CheckBoxShortcutCell: View { .padding(.horizontal, 16) } .onTapGesture { - if isShortcutTapped { - isShortcutTapped = false - - // TODO: 현재는 name을 기준으로 검색중, id로 검색해서 삭제해야함 / Shortcuts 자체를 배열에 저장해야함 - - if let index = selectedShortcutCells.firstIndex(of: shortcutCell) { - selectedShortcutCells.remove(at: index) - } - } - else { - if selectedShortcutCells.count < 10 { - isShortcutTapped = true - selectedShortcutCells.append(shortcutCell) - } - } + viewModel.checkboxCellTapGesture(idx: idx) } .padding(.top, 0) .background(Color.shortcutsZipBackground) } var toggle: some View { - Image(systemName: isShortcutTapped ? "checkmark.square.fill" : "square") + Image(systemName: viewModel.isShortcutsTapped[idx] ? "checkmark.square.fill" : "square") .smallIcon() - .foregroundColor(isShortcutTapped ? .shortcutsZipPrimary : .gray3) + .foregroundColor(viewModel.isShortcutsTapped[idx] ? .shortcutsZipPrimary : .gray3) .padding(.leading, 20) } @@ -62,11 +46,11 @@ struct CheckBoxShortcutCell: View { ZStack(alignment: .center) { Rectangle() - .fill(Color.fetchGradient(color: shortcutCell.color)) + .fill(Color.fetchGradient(color: viewModel.shortcutCells[idx].color)) .cornerRadius(8) .frame(width: 52, height: 52) - Image(systemName: shortcutCell.sfSymbol) + Image(systemName: viewModel.shortcutCells[idx].sfSymbol) .mediumShortcutIcon() .foregroundColor(.white) } @@ -76,11 +60,11 @@ struct CheckBoxShortcutCell: View { var shortcutInfo: some View { VStack(alignment: .leading, spacing: 4) { - Text(shortcutCell.title) + Text(viewModel.shortcutCells[idx].title) .shortcutsZipHeadline() .foregroundColor(.gray5) .lineLimit(1) - Text(shortcutCell.subtitle) + Text(viewModel.shortcutCells[idx].subtitle) .shortcutsZipFootnote() .foregroundColor(.gray3) .lineLimit(2) @@ -92,15 +76,10 @@ struct CheckBoxShortcutCell: View { var background: some View { RoundedRectangle(cornerRadius: 12) - .fill(isShortcutTapped ? Color.shortcutsZipWhite : Color.backgroudList) + .fill(viewModel.isShortcutsTapped[idx] ? Color.shortcutsZipWhite : Color.backgroudList) .overlay( RoundedRectangle(cornerRadius: 12) - .strokeBorder(isShortcutTapped ? Color.shortcutsZipPrimary : Color.backgroudListBorder) + .strokeBorder(viewModel.isShortcutsTapped[idx] ? Color.shortcutsZipPrimary : Color.backgroudListBorder) ) - }} - -//struct CheckBoxShortcutCell_Previews: PreviewProvider { -// static var previews: some View { -// CheckBoxShortcutCell(color: "Blue", sfSymbol: "books.vertical.fill", name: "ShortcutsTitle", description: "DescriptionDescription") -// } -//} + } +} diff --git a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift index 3da6d3ad..738b694c 100644 --- a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift +++ b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift @@ -78,11 +78,8 @@ struct WriteCurationSetView: View { var shortcutList: some View { ScrollView { - ForEach(Array(viewModel.shortcutCells)) { shortcut in - CheckBoxShortcutCell( - selectedShortcutCells: $viewModel.curation.shortcuts, - isShortcutTapped: $viewModel.curation.shortcuts.contains{$0.id == shortcut.id}, - shortcutCell: shortcut) + ForEach(Array(viewModel.shortcutCells.enumerated()), id: \.offset) { index, shortcut in + CheckBoxShortcutCell(viewModel: viewModel, idx: index) } } .frame(maxWidth: .infinity) From aee2cbcf0a626b4a4303aacbe6a71ac41bcd3426 Mon Sep 17 00:00:00 2001 From: Jeon Jimin Date: Sat, 8 Jul 2023 12:52:23 +0900 Subject: [PATCH 14/53] =?UTF-8?q?[Feat]=20#470=20-=20checkboxCell=20?= =?UTF-8?q?=ED=95=A9=EC=B9=98=EA=B8=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - viewBuilder 이용 - idx -> index로 수정 --- .../ViewModel/WriteCurationViewModel.swift | 14 +- .../CheckBoxShortcutCell.swift | 164 +++++++++--------- .../WriteCurationSetView.swift | 59 ++++++- 3 files changed, 147 insertions(+), 90 deletions(-) diff --git a/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift b/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift index ad1e25f1..01895694 100644 --- a/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift @@ -74,19 +74,19 @@ final class WriteCurationViewModel: ObservableObject, Hashable { } } - func checkboxCellTapGesture(idx: Int) { - if isShortcutsTapped[idx] { - isShortcutsTapped[idx] = false + func checkboxCellTapGesture(index: Int) { + if isShortcutsTapped[index] { + isShortcutsTapped[index] = false // TODO: 현재는 name을 기준으로 검색중, id로 검색해서 삭제해야함 / Shortcuts 자체를 배열에 저장해야함 - if let index = curation.shortcuts.firstIndex(of: shortcutCells[idx]) { - curation.shortcuts.remove(at: index) + if let firstIndex = curation.shortcuts.firstIndex(of: shortcutCells[index]) { + curation.shortcuts.remove(at: firstIndex) } } else { if curation.shortcuts.count < 10 { - curation.shortcuts.append(shortcutCells[idx]) - isShortcutsTapped[idx] = true + curation.shortcuts.append(shortcutCells[index]) + isShortcutsTapped[index] = true } } } diff --git a/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift b/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift index b763d5d2..2f576e0a 100644 --- a/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift +++ b/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift @@ -1,85 +1,85 @@ +//// +//// CheckBoxShortcutCell.swift +//// HappyAnding +//// +//// Created by HanGyeongjun on 2022/10/26. +//// // -// CheckBoxShortcutCell.swift -// HappyAnding +//import SwiftUI // -// Created by HanGyeongjun on 2022/10/26. +//struct CheckBoxShortcutCell: View { // - -import SwiftUI - -struct CheckBoxShortcutCell: View { - - @StateObject var viewModel: WriteCurationViewModel - - let idx: Int - - var body: some View { - - ZStack { - Color.shortcutsZipBackground - - HStack { - toggle - icon - shortcutInfo - Spacer() - } - .padding(.vertical, 20) - .background( background ) - .padding(.horizontal, 16) - } - .onTapGesture { - viewModel.checkboxCellTapGesture(idx: idx) - } - .padding(.top, 0) - .background(Color.shortcutsZipBackground) - } - - var toggle: some View { - Image(systemName: viewModel.isShortcutsTapped[idx] ? "checkmark.square.fill" : "square") - .smallIcon() - .foregroundColor(viewModel.isShortcutsTapped[idx] ? .shortcutsZipPrimary : .gray3) - .padding(.leading, 20) - } - - var icon: some View { - - ZStack(alignment: .center) { - Rectangle() - .fill(Color.fetchGradient(color: viewModel.shortcutCells[idx].color)) - .cornerRadius(8) - .frame(width: 52, height: 52) - - Image(systemName: viewModel.shortcutCells[idx].sfSymbol) - .mediumShortcutIcon() - .foregroundColor(.white) - } - .padding(.leading, 12) - } - - var shortcutInfo: some View { - - VStack(alignment: .leading, spacing: 4) { - Text(viewModel.shortcutCells[idx].title) - .shortcutsZipHeadline() - .foregroundColor(.gray5) - .lineLimit(1) - Text(viewModel.shortcutCells[idx].subtitle) - .shortcutsZipFootnote() - .foregroundColor(.gray3) - .lineLimit(2) - } - .padding(.leading, 12) - .padding(.trailing, 20) - } - - var background: some View { - - RoundedRectangle(cornerRadius: 12) - .fill(viewModel.isShortcutsTapped[idx] ? Color.shortcutsZipWhite : Color.backgroudList) - .overlay( - RoundedRectangle(cornerRadius: 12) - .strokeBorder(viewModel.isShortcutsTapped[idx] ? Color.shortcutsZipPrimary : Color.backgroudListBorder) - ) - } -} +// @StateObject var viewModel: WriteCurationViewModel +// +// let idx: Int +// +// var body: some View { +// +// ZStack { +// Color.shortcutsZipBackground +// +// HStack { +// toggle +// icon +// shortcutInfo +// Spacer() +// } +// .padding(.vertical, 20) +// .background( background ) +// .padding(.horizontal, 16) +// } +// .onTapGesture { +// viewModel.checkboxCellTapGesture(idx: idx) +// } +// .padding(.top, 0) +// .background(Color.shortcutsZipBackground) +// } +// +// var toggle: some View { +// Image(systemName: viewModel.isShortcutsTapped[idx] ? "checkmark.square.fill" : "square") +// .smallIcon() +// .foregroundColor(viewModel.isShortcutsTapped[idx] ? .shortcutsZipPrimary : .gray3) +// .padding(.leading, 20) +// } +// +// var icon: some View { +// +// ZStack(alignment: .center) { +// Rectangle() +// .fill(Color.fetchGradient(color: viewModel.shortcutCells[idx].color)) +// .cornerRadius(8) +// .frame(width: 52, height: 52) +// +// Image(systemName: viewModel.shortcutCells[idx].sfSymbol) +// .mediumShortcutIcon() +// .foregroundColor(.white) +// } +// .padding(.leading, 12) +// } +// +// var shortcutInfo: some View { +// +// VStack(alignment: .leading, spacing: 4) { +// Text(viewModel.shortcutCells[idx].title) +// .shortcutsZipHeadline() +// .foregroundColor(.gray5) +// .lineLimit(1) +// Text(viewModel.shortcutCells[idx].subtitle) +// .shortcutsZipFootnote() +// .foregroundColor(.gray3) +// .lineLimit(2) +// } +// .padding(.leading, 12) +// .padding(.trailing, 20) +// } +// +// var background: some View { +// +// RoundedRectangle(cornerRadius: 12) +// .fill(viewModel.isShortcutsTapped[idx] ? Color.shortcutsZipWhite : Color.backgroudList) +// .overlay( +// RoundedRectangle(cornerRadius: 12) +// .strokeBorder(viewModel.isShortcutsTapped[idx] ? Color.shortcutsZipPrimary : Color.backgroudListBorder) +// ) +// } +//} diff --git a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift index 738b694c..33e1c600 100644 --- a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift +++ b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift @@ -79,7 +79,7 @@ struct WriteCurationSetView: View { ScrollView { ForEach(Array(viewModel.shortcutCells.enumerated()), id: \.offset) { index, shortcut in - CheckBoxShortcutCell(viewModel: viewModel, idx: index) + checkBoxShortcutCell(viewModel: viewModel, index: index) } } .frame(maxWidth: .infinity) @@ -100,4 +100,61 @@ struct WriteCurationSetView: View { .padding(.horizontal, 16) .padding(.bottom, 20) } + + @ViewBuilder + private func checkBoxShortcutCell(viewModel: WriteCurationViewModel, index: Int) -> some View { + + ZStack { + Color.shortcutsZipBackground + + HStack { + Image(systemName: viewModel.isShortcutsTapped[index] ? "checkmark.square.fill" : "square") + .smallIcon() + .foregroundColor(viewModel.isShortcutsTapped[index] ? .shortcutsZipPrimary : .gray3) + .padding(.leading, 20) + + ZStack(alignment: .center) { + Rectangle() + .fill(Color.fetchGradient(color: viewModel.shortcutCells[index].color)) + .cornerRadius(8) + .frame(width: 52, height: 52) + + Image(systemName: viewModel.shortcutCells[index].sfSymbol) + .mediumShortcutIcon() + .foregroundColor(.white) + } + .padding(.leading, 12) + + VStack(alignment: .leading, spacing: 4) { + Text(viewModel.shortcutCells[index].title) + .shortcutsZipHeadline() + .foregroundColor(.gray5) + .lineLimit(1) + Text(viewModel.shortcutCells[index].subtitle) + .shortcutsZipFootnote() + .foregroundColor(.gray3) + .lineLimit(2) + } + .padding(.leading, 12) + .padding(.trailing, 20) + + Spacer() + } + .padding(.vertical, 20) + .background( + RoundedRectangle(cornerRadius: 12) + .fill(viewModel.isShortcutsTapped[index] ? Color.shortcutsZipWhite : Color.backgroudList) + .overlay( + RoundedRectangle(cornerRadius: 12) + .strokeBorder(viewModel.isShortcutsTapped[index] ? Color.shortcutsZipPrimary : Color.backgroudListBorder) + ) + ) + .padding(.horizontal, 16) + } + .onTapGesture { + viewModel.checkboxCellTapGesture(index: index) + } + .padding(.top, 0) + .background(Color.shortcutsZipBackground) + } } From c2a2621d91777ed1a0f0028c6c32dba0962ad9c3 Mon Sep 17 00:00:00 2001 From: Jeon Jimin Date: Thu, 20 Jul 2023 02:26:23 +0900 Subject: [PATCH 15/53] =?UTF-8?q?[Style]=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HappyAnding.xcodeproj/project.pbxproj | 4 - .../CheckBoxShortcutCell.swift | 85 ------------------- 2 files changed, 89 deletions(-) delete mode 100644 HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift diff --git a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj index f4168910..014ad5c3 100644 --- a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj +++ b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj @@ -78,7 +78,6 @@ A31F1844292A637300AF4A82 /* Date+String.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9CAEF822914855900224B0A /* Date+String.swift */; }; A31F1846292A638700AF4A82 /* (null) in Sources */ = {isa = PBXBuildFile; }; A31F1848292A64D700AF4A82 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 87E99C7128F94EA8009B691F /* Assets.xcassets */; }; - A33F74AE2908D8C800B8D0D0 /* CheckBoxShortcutCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A33F74AD2908D8C800B8D0D0 /* CheckBoxShortcutCell.swift */; }; A3439AF529395A100043E273 /* UserAuth.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87E606B729114FB200C3DA13 /* UserAuth.swift */; }; A3439AF629395A3A0043E273 /* CustomTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87276C372933F6AB00C92F4C /* CustomTextEditor.swift */; }; A3439AFB2939B0E80043E273 /* UserDefaults+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3439AFA2939B0E80043E273 /* UserDefaults+Extension.swift */; }; @@ -251,7 +250,6 @@ A0DD085629276608008177BB /* URL+DeepLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+DeepLink.swift"; sourceTree = ""; }; A0F822AB2910B8F100AF4448 /* ShortcutsZipViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutsZipViewModel.swift; sourceTree = ""; }; A0F822B629164D2300AF4448 /* ListCategoryShortcutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListCategoryShortcutView.swift; sourceTree = ""; }; - A33F74AD2908D8C800B8D0D0 /* CheckBoxShortcutCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckBoxShortcutCell.swift; sourceTree = ""; }; A3439AFA2939B0E80043E273 /* UserDefaults+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserDefaults+Extension.swift"; sourceTree = ""; }; A34BF82729AF3D55009BC946 /* AnnouncementCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnnouncementCell.swift; sourceTree = ""; }; A34BF82C29AFC34F009BC946 /* AboutShortcutGradeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutShortcutGradeView.swift; sourceTree = ""; }; @@ -473,7 +471,6 @@ children = ( 87E99CB028FFF273009B691F /* WriteCurationSetView.swift */, 87E99CB428FFF282009B691F /* WriteCurationInfoView.swift */, - A33F74AD2908D8C800B8D0D0 /* CheckBoxShortcutCell.swift */, ); path = WriteCurationViews; sourceTree = ""; @@ -903,7 +900,6 @@ F99569182901DC4D0060AAEF /* UIFont+Extension.swift in Sources */, F91A72C32999160E00CA135A /* Alerter.swift in Sources */, 87E99CAD28FFF261009B691F /* ReadShortcutView.swift in Sources */, - A33F74AE2908D8C800B8D0D0 /* CheckBoxShortcutCell.swift in Sources */, 87E606B22910649B00C3DA13 /* SignInWithAppleView.swift in Sources */, F91F09DF29AE0B5E00E04FA0 /* GradeAlertView.swift in Sources */, 87E99CEC29080C30009B691F /* Curation.swift in Sources */, diff --git a/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift b/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift deleted file mode 100644 index 2f576e0a..00000000 --- a/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift +++ /dev/null @@ -1,85 +0,0 @@ -//// -//// CheckBoxShortcutCell.swift -//// HappyAnding -//// -//// Created by HanGyeongjun on 2022/10/26. -//// -// -//import SwiftUI -// -//struct CheckBoxShortcutCell: View { -// -// @StateObject var viewModel: WriteCurationViewModel -// -// let idx: Int -// -// var body: some View { -// -// ZStack { -// Color.shortcutsZipBackground -// -// HStack { -// toggle -// icon -// shortcutInfo -// Spacer() -// } -// .padding(.vertical, 20) -// .background( background ) -// .padding(.horizontal, 16) -// } -// .onTapGesture { -// viewModel.checkboxCellTapGesture(idx: idx) -// } -// .padding(.top, 0) -// .background(Color.shortcutsZipBackground) -// } -// -// var toggle: some View { -// Image(systemName: viewModel.isShortcutsTapped[idx] ? "checkmark.square.fill" : "square") -// .smallIcon() -// .foregroundColor(viewModel.isShortcutsTapped[idx] ? .shortcutsZipPrimary : .gray3) -// .padding(.leading, 20) -// } -// -// var icon: some View { -// -// ZStack(alignment: .center) { -// Rectangle() -// .fill(Color.fetchGradient(color: viewModel.shortcutCells[idx].color)) -// .cornerRadius(8) -// .frame(width: 52, height: 52) -// -// Image(systemName: viewModel.shortcutCells[idx].sfSymbol) -// .mediumShortcutIcon() -// .foregroundColor(.white) -// } -// .padding(.leading, 12) -// } -// -// var shortcutInfo: some View { -// -// VStack(alignment: .leading, spacing: 4) { -// Text(viewModel.shortcutCells[idx].title) -// .shortcutsZipHeadline() -// .foregroundColor(.gray5) -// .lineLimit(1) -// Text(viewModel.shortcutCells[idx].subtitle) -// .shortcutsZipFootnote() -// .foregroundColor(.gray3) -// .lineLimit(2) -// } -// .padding(.leading, 12) -// .padding(.trailing, 20) -// } -// -// var background: some View { -// -// RoundedRectangle(cornerRadius: 12) -// .fill(viewModel.isShortcutsTapped[idx] ? Color.shortcutsZipWhite : Color.backgroudList) -// .overlay( -// RoundedRectangle(cornerRadius: 12) -// .strokeBorder(viewModel.isShortcutsTapped[idx] ? Color.shortcutsZipPrimary : Color.backgroudListBorder) -// ) -// } -//} From 70cc4e078775973a534906837c9f481c325c8920 Mon Sep 17 00:00:00 2001 From: "Soi (Jiwon Lee)" Date: Sat, 22 Jul 2023 14:50:08 +0900 Subject: [PATCH 16/53] Update HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ExploreCurationViewModel.swift Co-authored-by: GREEN (JIMIN KIM) <76623853+jim4020key@users.noreply.github.com> --- .../ExploreCurationViewModels/ExploreCurationViewModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ExploreCurationViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ExploreCurationViewModel.swift index 36c2188f..e7f57a8c 100644 --- a/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ExploreCurationViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ExploreCurationViewModel.swift @@ -8,7 +8,7 @@ import Foundation final class ExploreCurationViewModel: ObservableObject { - var shortcutsZipViewModel = ShortcutsZipViewModel.share + private let shortcutsZipViewModel = ShortcutsZipViewModel.share @Published var adminCurationList = [Curation]() @Published var personalCurationList = [Curation]() @Published var userCurationList = [Curation]() From 06499034e182367636d055b881e4a540c5d8b8de Mon Sep 17 00:00:00 2001 From: "Soi (Jiwon Lee)" Date: Sat, 22 Jul 2023 14:50:35 +0900 Subject: [PATCH 17/53] [Refactor] #472 - Private Co-authored-by: GREEN (JIMIN KIM) <76623853+jim4020key@users.noreply.github.com> --- .../ExploreCurationViewModels/ListCurationViewModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ListCurationViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ListCurationViewModel.swift index 99668538..23082377 100644 --- a/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ListCurationViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ListCurationViewModel.swift @@ -8,7 +8,7 @@ import Foundation final class ListCurationViewModel: ObservableObject { - var shortcutsZipViewModel = ShortcutsZipViewModel.share + private let shortcutsZipViewModel = ShortcutsZipViewModel.share @Published var curationType: CurationType @Published private(set) var curationList = [Curation]() From 4ecac9c17757d9ad30b72ec209570258e37d7773 Mon Sep 17 00:00:00 2001 From: "Soi (Jiwon Lee)" Date: Sat, 22 Jul 2023 14:50:42 +0900 Subject: [PATCH 18/53] [Refactor] #472 - Private Co-authored-by: GREEN (JIMIN KIM) <76623853+jim4020key@users.noreply.github.com> --- .../ExploreCurationViewModels/ReadCurationViewModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift index 41c37834..f65a0ecc 100644 --- a/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift @@ -9,7 +9,7 @@ import SwiftUI final class ReadCurationViewModel: ObservableObject { - var shortcutsZipViewModel = ShortcutsZipViewModel.share + private let shortcutsZipViewModel = ShortcutsZipViewModel.share @Published var isWriting = false @Published var isTappedDeleteButton = false From 7f322fa9602f5eb503af78dff36f62b8a0242c00 Mon Sep 17 00:00:00 2001 From: jim4020key Date: Mon, 10 Jul 2023 16:58:52 +0900 Subject: [PATCH 19/53] [Feat] #473 - Add ShowProfileViewModel --- .../HappyAnding.xcodeproj/project.pbxproj | 4 ++ .../Extensions/View/View+Navigation.swift | 8 +-- .../ViewModel/ShowProfileViewModel.swift | 39 ++++++++++++ .../Views/Components/UserNameCell.swift | 2 +- .../ReadShortcutViews/ShowProfileView.swift | 63 +++++++++---------- 5 files changed, 77 insertions(+), 39 deletions(-) create mode 100644 HappyAnding/HappyAnding/ViewModel/ShowProfileViewModel.swift diff --git a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj index a2ec4dac..0a35bf03 100644 --- a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj +++ b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ 4D778A34290A53BA00C15AC4 /* UIApplication+Keyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D778A33290A53BA00C15AC4 /* UIApplication+Keyboard.swift */; }; 4D7D16072986BBD7008B3332 /* TextLiteral.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D7D16062986BBD7008B3332 /* TextLiteral.swift */; }; 4D7D16082986BBDE008B3332 /* TextLiteral.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D7D16062986BBD7008B3332 /* TextLiteral.swift */; }; + 4D93D06F2A5956E60042CBA8 /* ShowProfileViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D93D06E2A5956E60042CBA8 /* ShowProfileViewModel.swift */; }; 4DAD635E292AB61700ABF8C1 /* UpdateShortcutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DAD635D292AB61700ABF8C1 /* UpdateShortcutView.swift */; }; 4DF62DD52A0550ED00A8B377 /* UIScreen+Size.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8795A16F292AB945004B765F /* UIScreen+Size.swift */; }; 87276C382933F6AB00C92F4C /* CustomTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87276C372933F6AB00C92F4C /* CustomTextEditor.swift */; }; @@ -192,6 +193,7 @@ 4D6A9F0029A3A92E00D02522 /* wrappinghstack+license.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "wrappinghstack+license.txt"; sourceTree = ""; }; 4D778A33290A53BA00C15AC4 /* UIApplication+Keyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIApplication+Keyboard.swift"; sourceTree = ""; }; 4D7D16062986BBD7008B3332 /* TextLiteral.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TextLiteral.swift; path = HappyAnding/TextLiteral.swift; sourceTree = SOURCE_ROOT; }; + 4D93D06E2A5956E60042CBA8 /* ShowProfileViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowProfileViewModel.swift; sourceTree = ""; }; 4DAD635D292AB61700ABF8C1 /* UpdateShortcutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateShortcutView.swift; sourceTree = ""; }; 87276C372933F6AB00C92F4C /* CustomTextEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTextEditor.swift; sourceTree = ""; }; 872A7D8E2918393B004A05B8 /* PrivacyPolicyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyPolicyView.swift; sourceTree = ""; }; @@ -653,6 +655,7 @@ A0F822AB2910B8F100AF4448 /* ShortcutsZipViewModel.swift */, 4D61A766291E1EE8000EF531 /* NavigationViewModel.swift */, F9AC2BB52935201C00165820 /* CheckUpdateVersion.swift */, + 4D93D06E2A5956E60042CBA8 /* ShowProfileViewModel.swift */, ); path = ViewModel; sourceTree = ""; @@ -912,6 +915,7 @@ A0F822AC2910B8F100AF4448 /* ShortcutsZipViewModel.swift in Sources */, 87276C382933F6AB00C92F4C /* CustomTextEditor.swift in Sources */, A34BF82D29AFC34F009BC946 /* AboutShortcutGradeView.swift in Sources */, + 4D93D06F2A5956E60042CBA8 /* ShowProfileViewModel.swift in Sources */, 87E99CC429014572009B691F /* Color+Extension.swift in Sources */, 87CFD8492939187200F97B86 /* NicknameTextField.swift in Sources */, 4D3DBB962934E31A00DE8160 /* ShowProfileView.swift in Sources */, diff --git a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift index d3722e17..8f659162 100644 --- a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift +++ b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift @@ -85,8 +85,8 @@ extension View { ReadCurationView(viewModel: ReadCurationViewModel(data: data as! Curation)) case is CurationType: ListCurationView(viewModel: ListCurationViewModel(data: data as! CurationType)) - case is NavigationProfile: - ShowProfileView(data: data as! NavigationProfile) + case is User: + ShowProfileView(viewModel: ShowProfileViewModel(data: data as! User)) case is NavigationSearch: SearchView() case is NavigationListCategoryShortcutType: @@ -115,8 +115,8 @@ struct NavigationViewModifier: ViewModifier { func body(content: Content) -> some View { content - .navigationDestination(for: NavigationProfile.self) { data in - ShowProfileView(data: data) + .navigationDestination(for: User?.self) { data in + ShowProfileView(viewModel: ShowProfileViewModel(data: data ?? User())) } .navigationDestination(for: Curation.self) { data in ReadCurationView(viewModel: ReadCurationViewModel(data: data)) diff --git a/HappyAnding/HappyAnding/ViewModel/ShowProfileViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ShowProfileViewModel.swift new file mode 100644 index 00000000..e659af83 --- /dev/null +++ b/HappyAnding/HappyAnding/ViewModel/ShowProfileViewModel.swift @@ -0,0 +1,39 @@ +// +// ShowProfileViewModel.swift +// HappyAnding +// +// Created by kimjimin on 2023/07/08. +// + +import SwiftUI + +final class ShowProfileViewModel: ObservableObject { + + var shortcutsZipViewModel = ShortcutsZipViewModel.share + + @Published var user: User + @Published private(set) var shortcuts: [Shortcuts] = [] + @Published private(set) var curations: [Curation] = [] + @Published private(set) var userGrade = Image(systemName: "person.crop.circle.fill") + @Published var currentTab: Int = 0 + @Published var animationAmount = 0.0 + + init(data: User) { + self.user = data + fetchUserGrade() + fetchShortcuts() + fetchCurations() + } + + private func fetchUserGrade() { + self.userGrade = shortcutsZipViewModel.fetchShortcutGradeImage(isBig: true, shortcutGrade: shortcutsZipViewModel.checkShortcutGrade(userID: user.id)) + } + + private func fetchShortcuts() { + self.shortcuts = shortcutsZipViewModel.allShortcuts.filter { $0.author == user.id } + } + + private func fetchCurations() { + self.curations = shortcutsZipViewModel.fetchCurationByAuthor(author: user.id) + } +} diff --git a/HappyAnding/HappyAnding/Views/Components/UserNameCell.swift b/HappyAnding/HappyAnding/Views/Components/UserNameCell.swift index ab5dd37a..ce0ce231 100644 --- a/HappyAnding/HappyAnding/Views/Components/UserNameCell.swift +++ b/HappyAnding/HappyAnding/Views/Components/UserNameCell.swift @@ -56,7 +56,7 @@ struct UserNameCell: View { RoundedRectangle(cornerRadius: 12) .foregroundColor(.gray1) ) - .navigationLinkRouter(data: NavigationProfile(userInfo: self.userInformation)) + .navigationLinkRouter(data: self.userInformation) .disabled(self.userInformation == nil) } } diff --git a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift index 3fc3a211..3613ae4b 100644 --- a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift +++ b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift @@ -9,46 +9,46 @@ import SwiftUI struct ShowProfileView: View { - @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel - - @State var data: NavigationProfile - - @State var shortcuts: [Shortcuts] = [] - @State var curations: [Curation] = [] - @State var currentTab: Int = 0 - - @State private var animationAmount = 0.0 + @StateObject var viewModel: ShowProfileViewModel @Namespace var namespace - + private let tabItems = [TextLiteral.showProfileViewShortcutTabTitle, TextLiteral.showProfileViewCurationTabTitle] var body: some View { ScrollView { VStack(spacing: 0) { - StickyHeader(height: 24) //MARK: 프로필이미지 및 닉네임 VStack(spacing: 8) { Button { withAnimation(.interpolatingSpring(stiffness: 10, damping: 3)) { - self.animationAmount += 360 + viewModel.animationAmount += 360 } } label: { - ZStack(alignment: .center) { - Circle() + if viewModel.shortcuts.isEmpty { + viewModel.userGrade + .resizable() .frame(width: 72, height: 72) - .foregroundColor(.gray1) - shortcutsZipViewModel.fetchShortcutGradeImage(isBig: true, shortcutGrade: shortcutsZipViewModel.checkShortcutGrade(userID: data.userInfo?.id ?? "")) - .rotation3DEffect( - .degrees(animationAmount), axis: (x: 0.0, y: 1.0, z: 0.0)) + .foregroundColor(.gray3) + } else { + ZStack(alignment: .center) { + Circle() + .frame(width: 72, height: 72) + .foregroundColor(.gray1) + viewModel.userGrade + .rotation3DEffect( + .degrees(viewModel.animationAmount), axis: (x: 0.0, y: 1.0, z: 0.0)) + } } } - Text(data.userInfo?.nickname ?? TextLiteral.defaultUser) + + Text(viewModel.user.nickname) .shortcutsZipTitle1() .foregroundColor(.gray5) } + .disabled(viewModel.shortcuts.isEmpty) .frame(maxWidth: .infinity) .padding(.bottom, 35) .background(Color.shortcutsZipWhite) @@ -66,16 +66,11 @@ struct ShowProfileView: View { .background(Color.shortcutsZipBackground) .toolbar(.visible, for: .tabBar) .onAppear { - shortcuts = shortcutsZipViewModel.allShortcuts.filter { $0.author == self.data.userInfo?.id } - curations = shortcutsZipViewModel.fetchCurationByAuthor(author: data.userInfo?.id ?? "") withAnimation(.interpolatingSpring(stiffness: 10, damping: 3)) { - self.animationAmount += 360 + viewModel.animationAmount += 360 } } } -} - -extension ShowProfileView { //MARK: 탭바 var tabBarView: some View { @@ -91,10 +86,10 @@ extension ShowProfileView { private func tabBarItem(string: String, tab: Int) -> some View { Button { - self.currentTab = tab + viewModel.currentTab = tab } label: { VStack { - if self.currentTab == tab { + if viewModel.currentTab == tab { Text(string) .shortcutsZipHeadline() .foregroundColor(.gray5) @@ -110,7 +105,7 @@ extension ShowProfileView { .frame(height: 2) } } - .animation(.spring(), value: currentTab) + .animation(.spring(), value: viewModel.currentTab) } .buttonStyle(.plain) } @@ -119,16 +114,16 @@ extension ShowProfileView { var profileContentView: some View { VStack { ZStack { - TabView(selection: self.$currentTab) { + TabView(selection: $viewModel.currentTab) { Color.clear.tag(0) Color.clear.tag(1) } .frame(minHeight: UIScreen.screenHeight / 2) .tabViewStyle(.page(indexDisplayMode: .never)) - switch(currentTab) { + switch(viewModel.currentTab) { case 0: - if shortcuts.isEmpty { + if viewModel.shortcuts.isEmpty { VStack { Text(TextLiteral.showProfileViewNoShortcuts) .padding(.top, 16) @@ -139,7 +134,7 @@ extension ShowProfileView { } VStack(spacing: 0) { - ForEach(shortcuts, id:\.self) { shortcut in + ForEach(viewModel.shortcuts, id:\.self) { shortcut in let data = NavigationReadShortcutType(shortcutID:shortcut.id, navigationParentView: .shortcuts) @@ -153,7 +148,7 @@ extension ShowProfileView { } .padding(.bottom, 44) case 1: - if curations.isEmpty { + if viewModel.curations.isEmpty { VStack{ Text(TextLiteral.showProfileViewNoCurations) .padding(.top, 16) @@ -179,7 +174,7 @@ extension ShowProfileView { EmptyView() } } - .animation(.easeInOut, value: currentTab) + .animation(.easeInOut, value: viewModel.currentTab) } } } From 69a9c149268765920e20df7d49ab096c8a9e55de Mon Sep 17 00:00:00 2001 From: jim4020key Date: Sun, 16 Jul 2023 18:42:09 +0900 Subject: [PATCH 20/53] [Feat] #473 - Add ReadShortcutViewModel --- .../HappyAnding.xcodeproj/project.pbxproj | 4 + .../Extensions/View/View+Navigation.swift | 8 +- .../Model/NavigationStackModel.swift | 7 - .../ViewModel/ReadShortcutViewModel.swift | 111 +++++++++ .../Components/MyShortcutCardListView.swift | 5 +- .../ReadCurationView.swift | 7 +- .../ExploreShortcutView.swift | 10 +- .../ListCategoryShortcutView.swift | 6 +- .../ListShortcutView.swift | 12 +- .../ReadShortcutViews/ReadShortcutView.swift | 214 ++++++------------ .../ReadShortcutViews/ShowProfileView.swift | 7 +- .../UpdateShortcutView.swift | 8 +- .../HappyAnding/Views/SearchView.swift | 5 +- .../Views/TabView/ShortcutTabView.swift | 3 +- 14 files changed, 214 insertions(+), 193 deletions(-) create mode 100644 HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift diff --git a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj index 0a35bf03..f69c149a 100644 --- a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj +++ b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ 4D7D16072986BBD7008B3332 /* TextLiteral.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D7D16062986BBD7008B3332 /* TextLiteral.swift */; }; 4D7D16082986BBDE008B3332 /* TextLiteral.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D7D16062986BBD7008B3332 /* TextLiteral.swift */; }; 4D93D06F2A5956E60042CBA8 /* ShowProfileViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D93D06E2A5956E60042CBA8 /* ShowProfileViewModel.swift */; }; + 4D93D0752A61D0D10042CBA8 /* ReadShortcutViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D93D0742A61D0D10042CBA8 /* ReadShortcutViewModel.swift */; }; 4DAD635E292AB61700ABF8C1 /* UpdateShortcutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DAD635D292AB61700ABF8C1 /* UpdateShortcutView.swift */; }; 4DF62DD52A0550ED00A8B377 /* UIScreen+Size.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8795A16F292AB945004B765F /* UIScreen+Size.swift */; }; 87276C382933F6AB00C92F4C /* CustomTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87276C372933F6AB00C92F4C /* CustomTextEditor.swift */; }; @@ -194,6 +195,7 @@ 4D778A33290A53BA00C15AC4 /* UIApplication+Keyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIApplication+Keyboard.swift"; sourceTree = ""; }; 4D7D16062986BBD7008B3332 /* TextLiteral.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TextLiteral.swift; path = HappyAnding/TextLiteral.swift; sourceTree = SOURCE_ROOT; }; 4D93D06E2A5956E60042CBA8 /* ShowProfileViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowProfileViewModel.swift; sourceTree = ""; }; + 4D93D0742A61D0D10042CBA8 /* ReadShortcutViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadShortcutViewModel.swift; sourceTree = ""; }; 4DAD635D292AB61700ABF8C1 /* UpdateShortcutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateShortcutView.swift; sourceTree = ""; }; 87276C372933F6AB00C92F4C /* CustomTextEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTextEditor.swift; sourceTree = ""; }; 872A7D8E2918393B004A05B8 /* PrivacyPolicyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyPolicyView.swift; sourceTree = ""; }; @@ -656,6 +658,7 @@ 4D61A766291E1EE8000EF531 /* NavigationViewModel.swift */, F9AC2BB52935201C00165820 /* CheckUpdateVersion.swift */, 4D93D06E2A5956E60042CBA8 /* ShowProfileViewModel.swift */, + 4D93D0742A61D0D10042CBA8 /* ReadShortcutViewModel.swift */, ); path = ViewModel; sourceTree = ""; @@ -969,6 +972,7 @@ F9136EB6293612310034AAB2 /* ShortcutsZipView.swift in Sources */, 87E99CB128FFF273009B691F /* WriteCurationSetView.swift in Sources */, 4D61A767291E1EE8000EF531 /* NavigationViewModel.swift in Sources */, + 4D93D0752A61D0D10042CBA8 /* ReadShortcutViewModel.swift in Sources */, F96D45BD29816578000C2441 /* StickyHeader.swift in Sources */, 87E99CEE29080D33009B691F /* User.swift in Sources */, F976E82C29368E0D0088BBA1 /* Version.swift in Sources */, diff --git a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift index 8f659162..f36e8a5e 100644 --- a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift +++ b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift @@ -79,8 +79,8 @@ extension View { switch data { case is NavigationListShortcutType: ListShortcutView(data: data as! NavigationListShortcutType) - case is NavigationReadShortcutType: - ReadShortcutView(data: data as! NavigationReadShortcutType) + case is Shortcuts: + ReadShortcutView(viewModel: ReadShortcutViewModel(data: data as! Shortcuts)) case is Curation: ReadCurationView(viewModel: ReadCurationViewModel(data: data as! Curation)) case is CurationType: @@ -124,8 +124,8 @@ struct NavigationViewModifier: ViewModifier { .navigationDestination(for: CurationType.self) { data in ListCurationView(viewModel: ListCurationViewModel(data: data)) } - .navigationDestination(for: NavigationReadShortcutType.self) { data in - ReadShortcutView(data: data) + .navigationDestination(for: Shortcuts.self) { data in + ReadShortcutView(viewModel: ReadShortcutViewModel(data: data)) } .navigationDestination(for: NavigationListShortcutType.self) { data in ListShortcutView(data: data) diff --git a/HappyAnding/HappyAnding/Model/NavigationStackModel.swift b/HappyAnding/HappyAnding/Model/NavigationStackModel.swift index 5760ec24..21d0f376 100644 --- a/HappyAnding/HappyAnding/Model/NavigationStackModel.swift +++ b/HappyAnding/HappyAnding/Model/NavigationStackModel.swift @@ -15,13 +15,6 @@ struct NavigationListShortcutType: Identifiable, Hashable { let navigationParentView: NavigationParentView } -struct NavigationReadShortcutType: Identifiable, Hashable { - var id = UUID().uuidString - - var shortcut: Shortcuts? - let shortcutID: String - let navigationParentView: NavigationParentView -} struct NavigationProfile: Identifiable, Hashable { var id = UUID().uuidString diff --git a/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift new file mode 100644 index 00000000..dea9e37d --- /dev/null +++ b/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift @@ -0,0 +1,111 @@ +// +// ReadShortcutViewModel.swift +// HappyAnding +// +// Created by kimjimin on 2023/07/15. +// + +import SwiftUI + +final class ReadShortcutViewModel: ObservableObject { + + var shortcutsZipViewModel = ShortcutsZipViewModel.share + + @Published var shortcut: Shortcuts + + @Published var isDeletingShortcut = false + @Published var isEditingShortcut = false + @Published var isUpdatingShortcut = false + + @Published var isMyLike = false + @Published var isMyFirstLike = false + @Published var isDownloadingShortcut = false + @Published var isDowngradingUserLevel = false + + @Published var currentTab: Int = 0 + @Published var comments: Comments = Comments(id: "", comments: []) + @Published var comment: Comment = Comment(user_nickname: "", user_id: "", date: "", depth: 0, contents: "") + @Published var nestedCommentTarget: String = "" + @Published var commentText = "" + + @Published var isEditingComment = false + @Published var isUndoingCommentEdit = false + + init(data: Shortcuts) { + self.shortcut = shortcutsZipViewModel.fetchShortcutDetail(id: data.id) ?? data + self.isMyLike = shortcutsZipViewModel.checkLikedShortrcut(shortcutID: data.id) + self.isMyFirstLike = isMyLike + self.comments = shortcutsZipViewModel.fetchComment(shortcutID: data.id) + } + + func checkIfDownloaded() { + if (shortcutsZipViewModel.userInfo?.downloadedShortcuts.firstIndex(where: { $0.id == shortcut.id })) == nil { + shortcut.numberOfDownload += 1 + } + self.isDownloadingShortcut = true + } + + func updateNumberOfDownload() { + shortcutsZipViewModel.updateNumberOfDownload(shortcut: shortcut, downloadlinkIndex: 0) + } + + func onViewDissapear() { + if isMyLike != isMyFirstLike { + shortcutsZipViewModel.updateNumberOfLike(isMyLike: isMyLike, shortcut: shortcut) + } + } + + func deleteShortcut() { + shortcutsZipViewModel.deleteShortcutIDInUser(shortcutID: shortcut.id) + shortcutsZipViewModel.deleteShortcutInCuration(curationsIDs: shortcut.curationIDs, shortcutID: shortcut.id) + shortcutsZipViewModel.deleteData(model: shortcut) + shortcutsZipViewModel.shortcutsMadeByUser = shortcutsZipViewModel.shortcutsMadeByUser.filter { $0.id != shortcut.id } + shortcutsZipViewModel.updateShortcutGrade() + } + + func cancelEditingComment() { + self.isEditingComment.toggle() + self.comment = self.comment.resetComment() + self.commentText = "" + } + + func postComment() { + if !isEditingComment { + comment.contents = commentText + comment.date = Date().getDate() + comment.user_id = shortcutsZipViewModel.userInfo!.id + comment.user_nickname = shortcutsZipViewModel.userInfo!.nickname + comments.comments.append(comment) + } else { + if let index = comments.comments.firstIndex(where: { $0.id == comment.id }) { + comments.comments[index].contents = commentText + } + isEditingComment = false + } + shortcutsZipViewModel.setData(model: comments) + commentText = "" + comment = comment.resetComment() + } + + func cancelNestedComment() { + comment.bundle_id = "\(Date().getDate())_\(UUID().uuidString)" + comment.depth = 0 + } + + func checkAuthor() -> Bool { + return self.shortcut.author == shortcutsZipViewModel.currentUser() + } + + func shareShortcut() { + guard let deepLink = URL(string: "ShortcutsZip://myPage/detailView?shortcutID=\(shortcut.id)") else { return } + let activityVC = UIActivityViewController(activityItems: [deepLink], applicationActivities: nil) + let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene + guard let window = windowScene?.windows.first else { return } + window.rootViewController?.present(activityVC, animated: true, completion: nil) + } + + func checkDowngrade() { + isDeletingShortcut.toggle() + isDowngradingUserLevel = shortcutsZipViewModel.isShortcutDowngrade() + } +} diff --git a/HappyAnding/HappyAnding/Views/Components/MyShortcutCardListView.swift b/HappyAnding/HappyAnding/Views/Components/MyShortcutCardListView.swift index 70d5634b..416c36d9 100644 --- a/HappyAnding/HappyAnding/Views/Components/MyShortcutCardListView.swift +++ b/HappyAnding/HappyAnding/Views/Components/MyShortcutCardListView.swift @@ -56,13 +56,10 @@ struct MyShortcutCardListView: View { if let shortcuts { ForEach(Array((shortcuts.enumerated())), id: \.offset) { index, shortcut in if index < 7 { - let data = NavigationReadShortcutType(shortcutID: shortcut.id, - navigationParentView: self.navigationParentView) - MyShortcutCardView(myShortcutIcon: shortcut.sfSymbol, myShortcutName: shortcut.title, myShortcutColor: shortcut.color) - .navigationLinkRouter(data: data) + .navigationLinkRouter(data: shortcut) } } } diff --git a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift index 291a764c..ecd4ae97 100644 --- a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift @@ -23,11 +23,10 @@ struct ReadCurationView: View { VStack(spacing: 0) { ForEach($viewModel.curation.shortcuts, id: \.self) { shortcut in - let data = NavigationReadShortcutType(shortcutID: shortcut.id, - navigationParentView: .curations) - ShortcutCell(shortcutCell: shortcut.wrappedValue, + + ShortcutCell(shortcutCell: shortcut, navigationParentView: .curations) - .navigationLinkRouter(data: data) + .navigationLinkRouter(data: shortcut) } } diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView/ExploreShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView/ExploreShortcutView.swift index a5ff6dde..3e8f1fbf 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView/ExploreShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView/ExploreShortcutView.swift @@ -133,13 +133,11 @@ extension ExploreShortcutView { ForEach(Array(shortcuts.enumerated()), id:\.offset) { index, shortcut in if index < 3 { - let data = NavigationReadShortcutType(shortcutID:shortcut.id, - navigationParentView: .shortcuts) ShortcutCell(shortcut: shortcut, rankNumber: index + 1, navigationParentView: .shortcuts) - .navigationLinkRouter(data: data) + .navigationLinkRouter(data: shortcut) } } .background(Color.shortcutsZipBackground) @@ -168,15 +166,11 @@ extension ExploreShortcutView { HStack { ForEach(Array((shortcutsZipViewModel.shortcutsInCategory[randomCategories[0].index].enumerated())), id: \.offset) { index, shortcut in if index < 7 { - let data = NavigationReadShortcutType( - shortcutID: shortcut.id, - navigationParentView: .shortcuts) - ShortcutCardCell( categoryShortcutIcon: shortcut.sfSymbol, categoryShortcutName: shortcut.title, categoryShortcutColor: shortcut.color) - .navigationLinkRouter(data: data) + .navigationLinkRouter(data: shortcut) } } } diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift index 2cb26e76..dc535672 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift @@ -22,12 +22,10 @@ struct ListCategoryShortcutView: View { LazyVStack(spacing: 0) { ForEach(data.shortcuts, id: \.self) { shortcut in - let data = NavigationReadShortcutType(shortcut: shortcut, - shortcutID: shortcut.id, - navigationParentView: self.data.navigationParentView) + ShortcutCell(shortcut: shortcut, navigationParentView: self.data.navigationParentView) - .navigationLinkRouter(data: data) + .navigationLinkRouter(data: shortcut) .listRowInsets(EdgeInsets()) .listRowSeparator(.hidden) } diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift index 5d21a150..7d140e5a 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift @@ -67,13 +67,11 @@ struct ListShortcutView: View { @ViewBuilder private func makeShortcutCellList(_ shortcuts: [Shortcuts]) -> some View { ForEach(shortcuts, id: \.self) { shortcut in - let navigationData = NavigationReadShortcutType(shortcut: shortcut, - shortcutID: shortcut.id, - navigationParentView: self.data.navigationParentView) + ShortcutCell(shortcut: shortcut, sectionType: data.sectionType, navigationParentView: data.navigationParentView) - .navigationLinkRouter(data: navigationData) + .navigationLinkRouter(data: shortcut) } } @@ -81,13 +79,11 @@ struct ListShortcutView: View { @ViewBuilder private func makeIndexShortcutCellList(_ shortcuts: [Shortcuts]) -> some View { ForEach(Array(shortcuts.enumerated()), id: \.offset) { index, shortcut in - let navigationData = NavigationReadShortcutType(shortcut: shortcut, - shortcutID: shortcut.id, - navigationParentView: self.data.navigationParentView) + ShortcutCell(shortcut: shortcut, rankNumber: index + 1, navigationParentView: data.navigationParentView) - .navigationLinkRouter(data: navigationData) + .navigationLinkRouter(data: shortcut) .listRowInsets(EdgeInsets()) .listRowSeparator(.hidden) } diff --git a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift index 367bbe9a..10f11943 100644 --- a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift @@ -14,29 +14,9 @@ struct ReadShortcutView: View { @Environment(\.openURL) private var openURL @Environment(\.loginAlertKey) var loginAlerter - @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel - + @StateObject var viewModel: ReadShortcutViewModel @StateObject var writeNavigation = WriteShortcutNavigation() - @State var isDeletingShortcut = false - @State var isEditingShortcut = false - @State var isUpdatingShortcut = false - - @State var isMyLike = false - @State var isMyFirstLike = false - @State var isDownloadingShortcut = false - @State var isDowngradingUserLevel = false - - @State var currentTab: Int = 0 - @State var data: NavigationReadShortcutType - @State var comments: Comments = Comments(id: "", comments: []) - @State var comment: Comment = Comment(user_nickname: "", user_id: "", date: "", depth: 0, contents: "") - @State var nestedCommentTarget: String = "" - @State var commentText = "" - - @State var isEditingComment = false - @State var isUndoingCommentEdit = false - @AppStorage("useWithoutSignIn") var useWithoutSignIn: Bool = false @FocusState private var isFocused: Bool @Namespace var namespace @@ -49,18 +29,18 @@ struct ReadShortcutView: View { ScrollViewReader { proxy in ScrollView { VStack(spacing: 0) { - if data.shortcut != nil { + if viewModel.shortcut != nil { StickyHeader(height: 40) /// 단축어 타이틀 - ReadShortcutViewHeader(shortcut: $data.shortcut.unwrap()!, isMyLike: $isMyLike) + ReadShortcutViewHeader(shortcut: $viewModel.shortcut, isMyLike: $viewModel.isMyLike) /// 탭뷰 (기본 정보, 버전 정보, 댓글) LazyVStack(pinnedViews: [.sectionHeaders]) { Section(header: tabBarView) { ZStack { - TabView(selection: self.$currentTab) { + TabView(selection: $viewModel.currentTab) { Color.clear .tag(0) Color.clear @@ -71,24 +51,24 @@ struct ReadShortcutView: View { .tabViewStyle(.page(indexDisplayMode: .never)) .frame(minHeight: UIScreen.screenHeight / 2) - switch currentTab { + switch viewModel.currentTab { case 0: - ReadShortcutContentView(shortcut: $data.shortcut.unwrap()!) + ReadShortcutContentView(shortcut: $viewModel.shortcut) case 1: - ReadShortcutVersionView(shortcut: $data.shortcut.unwrap()!, isUpdating: $isUpdatingShortcut) + ReadShortcutVersionView(shortcut: $viewModel.shortcut, isUpdating: $viewModel.isUpdatingShortcut) case 2: ReadShortcutCommentView(isFocused: _isFocused, - newComment: $comment, - comments: $comments, - nestedCommentTarget: $nestedCommentTarget, - isEditingComment: $isEditingComment, - shortcutID: data.shortcutID) + newComment: $viewModel.comment, + comments: $viewModel.comments, + nestedCommentTarget: $viewModel.nestedCommentTarget, + isEditingComment: $viewModel.isEditingComment, + shortcutID: viewModel.shortcut.id) .id(bottomID) default: EmptyView() } } - .animation(.easeInOut, value: currentTab) + .animation(.easeInOut, value: viewModel.currentTab) .padding(.top, 4) .padding(.horizontal, 16) } @@ -100,14 +80,14 @@ struct ReadShortcutView: View { NotificationCenter.default.addObserver(forName: UIResponder.keyboardDidShowNotification, object: nil, queue: .main) { notification in withAnimation { - if currentTab == 2 && !isEditingComment && comment.depth == 0 { + if viewModel.currentTab == 2 && !viewModel.isEditingComment && viewModel.comment.depth == 0 { proxy.scrollTo(bottomID, anchor: .bottom) } } } } } - .scrollDisabled(isEditingComment) + .scrollDisabled(viewModel.isEditingComment) .background(Color.shortcutsZipBackground) .navigationBarBackground ({ Color.shortcutsZipWhite }) .navigationBarTitleDisplayMode(NavigationBarItem.TitleDisplayMode.inline) @@ -117,33 +97,28 @@ struct ReadShortcutView: View { /// Safe Area에 고정된 댓글창, 다운로드 버튼 VStack { - if !isEditingComment { - if currentTab == 2 { + if !viewModel.isEditingComment { + if viewModel.currentTab == 2 { commentTextField } if !isFocused { - if let shortcut = data.shortcut { - Button { - if !useWithoutSignIn { - if let url = URL(string: shortcut.downloadLink[0]) { - if (shortcutsZipViewModel.userInfo?.downloadedShortcuts.firstIndex(where: { $0.id == data.shortcutID })) == nil { - data.shortcut?.numberOfDownload += 1 - } - isDownloadingShortcut = true - openURL(url) - } - shortcutsZipViewModel.updateNumberOfDownload(shortcut: shortcut, downloadlinkIndex: 0) - } else { - loginAlerter.isPresented = true + Button { + if !useWithoutSignIn { + if let url = URL(string: viewModel.shortcut.downloadLink[0]) { + viewModel.checkIfDownloaded() + openURL(url) } - } label: { - Text("다운로드 | \(Image(systemName: "arrow.down.app.fill")) \(shortcut.numberOfDownload)") - .shortcutsZipBody1() - .foregroundColor(Color.textIcon) - .padding() - .frame(maxWidth: .infinity) - .background(Color.shortcutsZipPrimary) + viewModel.updateNumberOfDownload() + } else { + loginAlerter.isPresented = true } + } label: { + Text("다운로드 | \(Image(systemName: "arrow.down.app.fill")) \(viewModel.shortcut.numberOfDownload)") + .shortcutsZipBody1() + .foregroundColor(Color.textIcon) + .padding() + .frame(maxWidth: .infinity) + .background(Color.shortcutsZipPrimary) } } } @@ -152,58 +127,45 @@ struct ReadShortcutView: View { } .onAppear { UINavigationBar.appearance().standardAppearance.configureWithTransparentBackground() - data.shortcut = shortcutsZipViewModel.fetchShortcutDetail(id: data.shortcutID) - isMyLike = shortcutsZipViewModel.checkLikedShortrcut(shortcutID: data.shortcutID) - isMyFirstLike = isMyLike - self.comments = shortcutsZipViewModel.fetchComment(shortcutID: data.shortcutID) - } - .onChange(of: isEditingShortcut || isUpdatingShortcut) { _ in - if !isEditingShortcut || !isUpdatingShortcut { - data.shortcut = shortcutsZipViewModel.fetchShortcutDetail(id: data.shortcutID) - } - } - .onChange(of: shortcutsZipViewModel.allComments) { _ in - self.comments = shortcutsZipViewModel.fetchComment(shortcutID: data.shortcutID) } +// .onChange(of: viewModel.isEditingShortcut || viewModel.isUpdatingShortcut) { _ in +// if !isEditingShortcut || !isUpdatingShortcut { +// data.shortcut = shortcutsZipViewModel.fetchShortcutDetail(id: data.shortcutID) +// } +// } +// .onChange(of: viewModel.shortcutsZipViewModel.allComments) { _ in +// self.comments = shortcutsZipViewModel.fetchComment(shortcutID: data.shortcutID) +// } .onDisappear { - if let shortcut = data.shortcut { - if isMyLike != isMyFirstLike { - shortcutsZipViewModel.updateNumberOfLike(isMyLike: isMyLike, shortcut: shortcut) - } - } + viewModel.onViewDissapear() } - .alert(TextLiteral.readShortcutViewDeletionTitle, isPresented: $isDeletingShortcut) { + .alert(TextLiteral.readShortcutViewDeletionTitle, isPresented: $viewModel.isDeletingShortcut) { Button(role: .cancel) { } label: { Text(TextLiteral.cancel) } Button(role: .destructive) { - if let shortcut = data.shortcut { - shortcutsZipViewModel.deleteShortcutIDInUser(shortcutID: shortcut.id) - shortcutsZipViewModel.deleteShortcutInCuration(curationsIDs: shortcut.curationIDs, shortcutID: shortcut.id) - shortcutsZipViewModel.deleteData(model: shortcut) - shortcutsZipViewModel.shortcutsMadeByUser = shortcutsZipViewModel.shortcutsMadeByUser.filter { $0.id != shortcut.id } - shortcutsZipViewModel.updateShortcutGrade() - self.presentation.wrappedValue.dismiss() - } + viewModel.deleteShortcut() + self.presentation.wrappedValue.dismiss() } label: { Text(TextLiteral.delete) } } message: { - Text(isDowngradingUserLevel ? TextLiteral.readShortcutViewDeletionMessageDowngrade : TextLiteral.readShortcutViewDeletionMessage) + Text(viewModel.isDowngradingUserLevel ? TextLiteral.readShortcutViewDeletionMessageDowngrade : TextLiteral.readShortcutViewDeletionMessage) } - .fullScreenCover(isPresented: $isEditingShortcut) { + .fullScreenCover(isPresented: $viewModel.isEditingShortcut) { NavigationRouter(content: writeShortcutView, path: $writeNavigation.navigationPath) .environmentObject(writeNavigation) } - .fullScreenCover(isPresented: $isUpdatingShortcut) { - UpdateShortcutView(isUpdating: $isUpdatingShortcut, shortcut: $data.shortcut) + //TODO: update shortcut + .fullScreenCover(isPresented: $viewModel.isUpdatingShortcut) { + UpdateShortcutView(isUpdating: $viewModel.isUpdatingShortcut, shortcut: $viewModel.shortcut) } /// 댓글 수정할 때 뒷 배경을 어둡게 만들기 위한 뷰 - if isEditingComment { + if viewModel.isEditingComment { Color.black .ignoresSafeArea() .opacity(0.4) @@ -218,13 +180,13 @@ struct ReadShortcutView: View { } } .onAppear { - commentText = comment.contents + viewModel.commentText = viewModel.comment.contents } .onTapGesture(count: 1) { isFocused.toggle() - isUndoingCommentEdit.toggle() + viewModel.isUndoingCommentEdit.toggle() } - .alert(TextLiteral.readShortcutViewDeleteFixesTitle, isPresented: $isUndoingCommentEdit) { + .alert(TextLiteral.readShortcutViewDeleteFixesTitle, isPresented: $viewModel.isUndoingCommentEdit) { Button(role: .cancel) { isFocused.toggle() } label: { @@ -233,9 +195,7 @@ struct ReadShortcutView: View { Button(role: .destructive) { withAnimation(.easeInOut) { - isEditingComment.toggle() - comment = comment.resetComment() - commentText = "" + viewModel.cancelEditingComment() } } label: { Text(TextLiteral.delete) @@ -250,11 +210,9 @@ struct ReadShortcutView: View { @ViewBuilder private func writeShortcutView() -> some View { - if let shortcut = data.shortcut { - WriteShortcutView(isWriting: $isEditingShortcut, - shortcut: shortcut, - isEdit: true) - } + WriteShortcutView(isWriting: $viewModel.isEditingShortcut, + shortcut: viewModel.shortcut, + isEdit: true) } } @@ -265,57 +223,43 @@ extension ReadShortcutView { private var commentTextField: some View { VStack(spacing: 0) { - if comment.depth == 1 && !isEditingComment { + if viewModel.comment.depth == 1 && !viewModel.isEditingComment { nestedCommentTargetView } HStack { - if comment.depth == 1 && !isEditingComment { + if viewModel.comment.depth == 1 && !viewModel.isEditingComment { Image(systemName: "arrow.turn.down.right") .smallIcon() .foregroundColor(.gray4) } - TextField(useWithoutSignIn ? TextLiteral.readShortcutViewCommentDescriptionBeforeLogin : TextLiteral.readShortcutViewCommentDescription, text: $commentText, axis: .vertical) + TextField(useWithoutSignIn ? TextLiteral.readShortcutViewCommentDescriptionBeforeLogin : TextLiteral.readShortcutViewCommentDescription, text: $viewModel.commentText, axis: .vertical) .keyboardType(.twitter) .disabled(useWithoutSignIn) .disableAutocorrection(true) .textInputAutocapitalization(.never) .shortcutsZipBody2() - .lineLimit(comment.depth == 1 ? 2 : 4) + .lineLimit(viewModel.comment.depth == 1 ? 2 : 4) .focused($isFocused) .onAppear { UIApplication.shared.hideKeyboard() } Button { - if !isEditingComment { - comment.contents = commentText - comment.date = Date().getDate() - comment.user_id = shortcutsZipViewModel.userInfo!.id - comment.user_nickname = shortcutsZipViewModel.userInfo!.nickname - comments.comments.append(comment) - } else { - if let index = comments.comments.firstIndex(where: { $0.id == comment.id }) { - comments.comments[index].contents = commentText - } - isEditingComment = false - } - shortcutsZipViewModel.setData(model: comments) - commentText = "" - comment = comment.resetComment() + viewModel.postComment() isFocused.toggle() } label: { Image(systemName: "paperplane.fill") .mediumIcon() - .foregroundColor(commentText == "" ? Color.gray2 : Color.gray5) + .foregroundColor(viewModel.commentText == "" ? Color.gray2 : Color.gray5) } - .disabled(commentText == "" ? true : false) + .disabled(viewModel.commentText == "" ? true : false) } .padding(.vertical, 12) .padding(.horizontal, 16) .background( Rectangle() .fill(Color.gray1) - .cornerRadius(12 ,corners: (comment.depth == 1) && (!isEditingComment) ? [.bottomLeft, .bottomRight] : .allCorners) + .cornerRadius(12 ,corners: (viewModel.comment.depth == 1) && (!viewModel.isEditingComment) ? [.bottomLeft, .bottomRight] : .allCorners) ) .padding(.horizontal, 16) .padding(.bottom, 20) @@ -325,15 +269,14 @@ extension ReadShortcutView { private var nestedCommentTargetView: some View { HStack { - Text("@ \(nestedCommentTarget)") + Text("@ \(viewModel.nestedCommentTarget)") .shortcutsZipFootnote() .foregroundColor(.gray5) Spacer() Button { - comment.bundle_id = "\(Date().getDate())_\(UUID().uuidString)" - comment.depth = 0 + viewModel.cancelNestedComment() } label: { Image(systemName: "xmark") .smallIcon() @@ -354,7 +297,7 @@ extension ReadShortcutView { @ViewBuilder private func readShortcutViewNavigationBarItems() -> some View { - if self.data.shortcut?.author == shortcutsZipViewModel.currentUser() { + if viewModel.checkAuthor() { Menu { Section { editButton @@ -374,7 +317,7 @@ extension ReadShortcutView { private var editButton: some View { Button { - isEditingShortcut.toggle() + viewModel.isEditingShortcut.toggle() } label: { Label(TextLiteral.edit, systemImage: "square.and.pencil") } @@ -382,7 +325,7 @@ extension ReadShortcutView { private var updateButton: some View { Button { - isUpdatingShortcut.toggle() + viewModel.isUpdatingShortcut.toggle() } label: { Label(TextLiteral.update, systemImage: "clock.arrow.circlepath") } @@ -390,13 +333,7 @@ extension ReadShortcutView { private var shareButton: some View { Button { - if let shortcut = data.shortcut { - guard let deepLink = URL(string: "ShortcutsZip://myPage/detailView?shortcutID=\(shortcut.id)") else { return } - let activityVC = UIActivityViewController(activityItems: [deepLink], applicationActivities: nil) - let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene - guard let window = windowScene?.windows.first else { return } - window.rootViewController?.present(activityVC, animated: true, completion: nil) - } + viewModel.shareShortcut() } label: { Label(TextLiteral.share, systemImage: "square.and.arrow.up") .foregroundColor(.gray4) @@ -406,8 +343,7 @@ extension ReadShortcutView { private var deleteButton: some View { Button(role: .destructive) { - isDeletingShortcut.toggle() - isDowngradingUserLevel = shortcutsZipViewModel.isShortcutDowngrade() + viewModel.checkDowngrade() } label: { Label(TextLiteral.delete, systemImage: "trash.fill") } @@ -428,10 +364,10 @@ extension ReadShortcutView { private func tabBarItem(string: String, tab: Int) -> some View { Button { - self.currentTab = tab + viewModel.currentTab = tab } label: { VStack { - if self.currentTab == tab { + if viewModel.currentTab == tab { Text(string) .shortcutsZipHeadline() .foregroundColor(.gray5) @@ -446,7 +382,7 @@ extension ReadShortcutView { Color.clear.frame(height: 2) } } - .animation(.spring(), value: currentTab) + .animation(.spring(), value: viewModel.currentTab) } .buttonStyle(.plain) } diff --git a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift index 3613ae4b..143f3fc0 100644 --- a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift +++ b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift @@ -135,12 +135,9 @@ struct ShowProfileView: View { VStack(spacing: 0) { ForEach(viewModel.shortcuts, id:\.self) { shortcut in - let data = NavigationReadShortcutType(shortcutID:shortcut.id, - navigationParentView: .shortcuts) - ShortcutCell(shortcut: shortcut, - navigationParentView: data.navigationParentView) - .navigationLinkRouter(data: data) + navigationParentView: .shortcuts) + .navigationLinkRouter(data: shortcut) } Spacer() diff --git a/HappyAnding/HappyAnding/Views/ReadShortcutViews/UpdateShortcutView.swift b/HappyAnding/HappyAnding/Views/ReadShortcutViews/UpdateShortcutView.swift index 8b6a72ba..e1ea8660 100644 --- a/HappyAnding/HappyAnding/Views/ReadShortcutViews/UpdateShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ReadShortcutViews/UpdateShortcutView.swift @@ -14,7 +14,7 @@ struct UpdateShortcutView: View { @FocusState var isDescriptionFieldFocused: Bool @Binding var isUpdating: Bool - @Binding var shortcut: Shortcuts? + @Binding var shortcut: Shortcuts @State var updatedLink = "" @State var updateDescription = "" @@ -72,9 +72,9 @@ struct UpdateShortcutView: View { Spacer() Button(action: { - if let shortcut { - shortcutsZipViewModel.updateShortcutVersion(shortcut: shortcut, updateDescription: updateDescription, updateLink: updatedLink) - } + shortcutsZipViewModel.updateShortcutVersion(shortcut: shortcut, + updateDescription: updateDescription, + updateLink: updatedLink) isUpdating.toggle() }, label: { ZStack { diff --git a/HappyAnding/HappyAnding/Views/SearchView.swift b/HappyAnding/HappyAnding/Views/SearchView.swift index 614746ea..2657da96 100644 --- a/HappyAnding/HappyAnding/Views/SearchView.swift +++ b/HappyAnding/HappyAnding/Views/SearchView.swift @@ -37,12 +37,9 @@ struct SearchView: View { VStack(spacing: 0) { ForEach(shortcutResults.sorted(by: { $0.title < $1.title }), id: \.self) { shortcut in - let data = NavigationReadShortcutType(shortcutID: shortcut.id, - navigationParentView: .shortcuts) - ShortcutCell(shortcut: shortcut, navigationParentView: NavigationParentView.shortcuts) - .navigationLinkRouter(data: data) + .navigationLinkRouter(data: shortcut) .listRowInsets(EdgeInsets()) .listRowSeparator(.hidden) } diff --git a/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift b/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift index db91ece5..eb164a81 100644 --- a/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift +++ b/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift @@ -152,8 +152,7 @@ struct ShortcutTabView: View { tempShortcutId = shortcutIDfromURL isShortcutDeeplink = true - let data = NavigationReadShortcutType(shortcutID: self.tempShortcutId, - navigationParentView: .myPage) + let data = shortcutsZipViewModel.fetchShortcutDetail(id: tempShortcutId) navigateLink(data: data) } From c39b1bd8580472c758df872286a564bb8668d808 Mon Sep 17 00:00:00 2001 From: jim4020key Date: Sun, 16 Jul 2023 18:56:05 +0900 Subject: [PATCH 21/53] [Feat] #473 - Add ReadShortcutViewModel to UpdateShortcutView --- .../ViewModel/ReadShortcutViewModel.swift | 14 +++ .../ReadShortcutViews/ReadShortcutView.swift | 90 ++++++++----------- .../UpdateShortcutView.swift | 31 +++---- 3 files changed, 63 insertions(+), 72 deletions(-) diff --git a/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift index dea9e37d..db65c3aa 100644 --- a/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift @@ -31,6 +31,12 @@ final class ReadShortcutViewModel: ObservableObject { @Published var isEditingComment = false @Published var isUndoingCommentEdit = false + /// UpdateShortcutView + @Published var updatedLink = "" + @Published var updateDescription = "" + @Published var isLinkValid = false + @Published var isDescriptionValid = false + init(data: Shortcuts) { self.shortcut = shortcutsZipViewModel.fetchShortcutDetail(id: data.id) ?? data self.isMyLike = shortcutsZipViewModel.checkLikedShortrcut(shortcutID: data.id) @@ -108,4 +114,12 @@ final class ReadShortcutViewModel: ObservableObject { isDeletingShortcut.toggle() isDowngradingUserLevel = shortcutsZipViewModel.isShortcutDowngrade() } + + func updateShortcut() { + shortcutsZipViewModel.updateShortcutVersion(shortcut: shortcut, + updateDescription: updateDescription, + updateLink: updatedLink) + self.shortcut = shortcutsZipViewModel.fetchShortcutDetail(id: shortcut.id) ?? shortcut + isUpdatingShortcut.toggle() + } } diff --git a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift index 10f11943..71c1ec7c 100644 --- a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift @@ -29,49 +29,46 @@ struct ReadShortcutView: View { ScrollViewReader { proxy in ScrollView { VStack(spacing: 0) { - if viewModel.shortcut != nil { - - StickyHeader(height: 40) - - /// 단축어 타이틀 - ReadShortcutViewHeader(shortcut: $viewModel.shortcut, isMyLike: $viewModel.isMyLike) - - /// 탭뷰 (기본 정보, 버전 정보, 댓글) - LazyVStack(pinnedViews: [.sectionHeaders]) { - Section(header: tabBarView) { - ZStack { - TabView(selection: $viewModel.currentTab) { - Color.clear - .tag(0) - Color.clear - .tag(1) - Color.clear - .tag(2) - } - .tabViewStyle(.page(indexDisplayMode: .never)) - .frame(minHeight: UIScreen.screenHeight / 2) - - switch viewModel.currentTab { - case 0: - ReadShortcutContentView(shortcut: $viewModel.shortcut) - case 1: - ReadShortcutVersionView(shortcut: $viewModel.shortcut, isUpdating: $viewModel.isUpdatingShortcut) - case 2: - ReadShortcutCommentView(isFocused: _isFocused, - newComment: $viewModel.comment, - comments: $viewModel.comments, - nestedCommentTarget: $viewModel.nestedCommentTarget, - isEditingComment: $viewModel.isEditingComment, - shortcutID: viewModel.shortcut.id) - .id(bottomID) - default: - EmptyView() - } + StickyHeader(height: 40) + + /// 단축어 타이틀 + ReadShortcutViewHeader(shortcut: $viewModel.shortcut, isMyLike: $viewModel.isMyLike) + + /// 탭뷰 (기본 정보, 버전 정보, 댓글) + LazyVStack(pinnedViews: [.sectionHeaders]) { + Section(header: tabBarView) { + ZStack { + TabView(selection: $viewModel.currentTab) { + Color.clear + .tag(0) + Color.clear + .tag(1) + Color.clear + .tag(2) + } + .tabViewStyle(.page(indexDisplayMode: .never)) + .frame(minHeight: UIScreen.screenHeight / 2) + + switch viewModel.currentTab { + case 0: + ReadShortcutContentView(shortcut: $viewModel.shortcut) + case 1: + ReadShortcutVersionView(shortcut: $viewModel.shortcut, isUpdating: $viewModel.isUpdatingShortcut) + case 2: + ReadShortcutCommentView(isFocused: _isFocused, + newComment: $viewModel.comment, + comments: $viewModel.comments, + nestedCommentTarget: $viewModel.nestedCommentTarget, + isEditingComment: $viewModel.isEditingComment, + shortcutID: viewModel.shortcut.id) + .id(bottomID) + default: + EmptyView() } - .animation(.easeInOut, value: viewModel.currentTab) - .padding(.top, 4) - .padding(.horizontal, 16) } + .animation(.easeInOut, value: viewModel.currentTab) + .padding(.top, 4) + .padding(.horizontal, 16) } } } @@ -128,14 +125,6 @@ struct ReadShortcutView: View { .onAppear { UINavigationBar.appearance().standardAppearance.configureWithTransparentBackground() } -// .onChange(of: viewModel.isEditingShortcut || viewModel.isUpdatingShortcut) { _ in -// if !isEditingShortcut || !isUpdatingShortcut { -// data.shortcut = shortcutsZipViewModel.fetchShortcutDetail(id: data.shortcutID) -// } -// } -// .onChange(of: viewModel.shortcutsZipViewModel.allComments) { _ in -// self.comments = shortcutsZipViewModel.fetchComment(shortcutID: data.shortcutID) -// } .onDisappear { viewModel.onViewDissapear() } @@ -159,9 +148,8 @@ struct ReadShortcutView: View { path: $writeNavigation.navigationPath) .environmentObject(writeNavigation) } - //TODO: update shortcut .fullScreenCover(isPresented: $viewModel.isUpdatingShortcut) { - UpdateShortcutView(isUpdating: $viewModel.isUpdatingShortcut, shortcut: $viewModel.shortcut) + UpdateShortcutView(viewModel: self.viewModel) } /// 댓글 수정할 때 뒷 배경을 어둡게 만들기 위한 뷰 diff --git a/HappyAnding/HappyAnding/Views/ReadShortcutViews/UpdateShortcutView.swift b/HappyAnding/HappyAnding/Views/ReadShortcutViews/UpdateShortcutView.swift index e1ea8660..f01c79b9 100644 --- a/HappyAnding/HappyAnding/Views/ReadShortcutViews/UpdateShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ReadShortcutViews/UpdateShortcutView.swift @@ -9,23 +9,15 @@ import SwiftUI struct UpdateShortcutView: View { - @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel + @StateObject var viewModel: ReadShortcutViewModel @FocusState var isDescriptionFieldFocused: Bool - @Binding var isUpdating: Bool - @Binding var shortcut: Shortcuts - - @State var updatedLink = "" - @State var updateDescription = "" - @State var isLinkValid = false - @State var isDescriptionValid = false - var body: some View { VStack { HStack { Button(action: { - isUpdating.toggle() + viewModel.isUpdatingShortcut.toggle() }, label: { Text(TextLiteral.cancel) .foregroundColor(.gray5) @@ -48,8 +40,8 @@ struct UpdateShortcutView: View { placeholder: TextLiteral.updateShortcutViewLinkPlaceholder, lengthLimit: 100, isDownloadLinkTextField: true, - content: $updatedLink, - isValid: $isLinkValid + content: $viewModel.updatedLink, + isValid: $viewModel.isLinkValid ) .onSubmit { isDescriptionFieldFocused = true @@ -64,29 +56,26 @@ struct UpdateShortcutView: View { placeholder: TextLiteral.updateShortcutViewDescriptionPlaceholder, lengthLimit: 50, isDownloadLinkTextField: false, - content: $updateDescription, - isValid: $isDescriptionValid + content: $viewModel.updateDescription, + isValid: $viewModel.isDescriptionValid ) .focused($isDescriptionFieldFocused) Spacer() Button(action: { - shortcutsZipViewModel.updateShortcutVersion(shortcut: shortcut, - updateDescription: updateDescription, - updateLink: updatedLink) - isUpdating.toggle() + viewModel.updateShortcut() }, label: { ZStack { RoundedRectangle(cornerRadius: 12) - .foregroundColor(isLinkValid && isDescriptionValid ? .shortcutsZipPrimary : .shortcutsZipPrimary.opacity(0.13)) + .foregroundColor(viewModel.isLinkValid && viewModel.isDescriptionValid ? .shortcutsZipPrimary : .shortcutsZipPrimary.opacity(0.13)) .frame(maxWidth: .infinity, maxHeight: 52) Text(TextLiteral.update) - .foregroundColor(isLinkValid && isDescriptionValid ? .textButton : .textButtonDisable) + .foregroundColor(viewModel.isLinkValid && viewModel.isDescriptionValid ? .textButton : .textButtonDisable) .shortcutsZipBody1() } }) - .disabled(!isLinkValid || !isDescriptionValid) + .disabled(!viewModel.isLinkValid || !viewModel.isDescriptionValid) .padding(.horizontal, 16) .padding(.bottom, 24) } From 30d67061be825ad8cacff44a1c9a105b541f3dbc Mon Sep 17 00:00:00 2001 From: jim4020key Date: Sun, 16 Jul 2023 19:35:08 +0900 Subject: [PATCH 22/53] [Feat] #473 - Move properties to view model --- .../ViewModel/ReadShortcutViewModel.swift | 31 ++++- .../ReadShortcutViews/ReadShortcutView.swift | 128 +++++++----------- 2 files changed, 74 insertions(+), 85 deletions(-) diff --git a/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift index db65c3aa..92e32ea3 100644 --- a/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift @@ -13,6 +13,7 @@ final class ReadShortcutViewModel: ObservableObject { @Published var shortcut: Shortcuts + /// ReadShortcutView @Published var isDeletingShortcut = false @Published var isEditingShortcut = false @Published var isUpdatingShortcut = false @@ -31,6 +32,15 @@ final class ReadShortcutViewModel: ObservableObject { @Published var isEditingComment = false @Published var isUndoingCommentEdit = false + /// ReadShortcutViewHeader + @Published var userInformation: User? = nil + @Published var numberOfLike = 0 + @Published var userGrade = Image(systemName: "person.crop.circle.fill") + + /// ReadShortcutCommentView + @Published var isDeletingComment = false + @Published var deletedComment = Comment(user_nickname: "", user_id: "", date: "", depth: 0, contents: "") + /// UpdateShortcutView @Published var updatedLink = "" @Published var updateDescription = "" @@ -42,17 +52,22 @@ final class ReadShortcutViewModel: ObservableObject { self.isMyLike = shortcutsZipViewModel.checkLikedShortrcut(shortcutID: data.id) self.isMyFirstLike = isMyLike self.comments = shortcutsZipViewModel.fetchComment(shortcutID: data.id) + shortcutsZipViewModel.fetchUser(userID: data.author, + isCurrentUser: false) { user in + self.userInformation = user + } + self.userGrade = shortcutsZipViewModel.fetchShortcutGradeImage(isBig: false, shortcutGrade: shortcutsZipViewModel.checkShortcutGrade(userID: userInformation?.id ?? "!")) + self.numberOfLike = data.numberOfLike } func checkIfDownloaded() { if (shortcutsZipViewModel.userInfo?.downloadedShortcuts.firstIndex(where: { $0.id == shortcut.id })) == nil { shortcut.numberOfDownload += 1 } - self.isDownloadingShortcut = true } - func updateNumberOfDownload() { - shortcutsZipViewModel.updateNumberOfDownload(shortcut: shortcut, downloadlinkIndex: 0) + func updateNumberOfDownload(index: Int) { + shortcutsZipViewModel.updateNumberOfDownload(shortcut: shortcut, downloadlinkIndex: index) } func onViewDissapear() { @@ -122,4 +137,14 @@ final class ReadShortcutViewModel: ObservableObject { self.shortcut = shortcutsZipViewModel.fetchShortcutDetail(id: shortcut.id) ?? shortcut isUpdatingShortcut.toggle() } + + func deleteComment() { + if deletedComment.depth == 0 { + comments.comments.removeAll(where: { $0.bundle_id == deletedComment.bundle_id}) + } else { + comments.comments.removeAll(where: { $0.id == deletedComment.id}) + } + + shortcutsZipViewModel.setData(model: comments) + } } diff --git a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift index 71c1ec7c..a6a234e7 100644 --- a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift @@ -32,7 +32,7 @@ struct ReadShortcutView: View { StickyHeader(height: 40) /// 단축어 타이틀 - ReadShortcutViewHeader(shortcut: $viewModel.shortcut, isMyLike: $viewModel.isMyLike) + ReadShortcutViewHeader(viewModel: self.viewModel) /// 탭뷰 (기본 정보, 버전 정보, 댓글) LazyVStack(pinnedViews: [.sectionHeaders]) { @@ -51,17 +51,12 @@ struct ReadShortcutView: View { switch viewModel.currentTab { case 0: - ReadShortcutContentView(shortcut: $viewModel.shortcut) + ReadShortcutContentView(viewModel: self.viewModel) case 1: - ReadShortcutVersionView(shortcut: $viewModel.shortcut, isUpdating: $viewModel.isUpdatingShortcut) + ReadShortcutVersionView(viewModel: self.viewModel) case 2: - ReadShortcutCommentView(isFocused: _isFocused, - newComment: $viewModel.comment, - comments: $viewModel.comments, - nestedCommentTarget: $viewModel.nestedCommentTarget, - isEditingComment: $viewModel.isEditingComment, - shortcutID: viewModel.shortcut.id) - .id(bottomID) + ReadShortcutCommentView(viewModel: self.viewModel) + .id(bottomID) default: EmptyView() } @@ -103,9 +98,10 @@ struct ReadShortcutView: View { if !useWithoutSignIn { if let url = URL(string: viewModel.shortcut.downloadLink[0]) { viewModel.checkIfDownloaded() + viewModel.isDownloadingShortcut = true openURL(url) } - viewModel.updateNumberOfDownload() + viewModel.updateNumberOfDownload(index: 0) } else { loginAlerter.isPresented = true } @@ -384,13 +380,9 @@ extension ReadShortcutView { @Environment(\.loginAlertKey) var loginAlerter @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel - @AppStorage("useWithoutSignIn") var useWithoutSignIn: Bool = false - - @Binding var shortcut: Shortcuts - @Binding var isMyLike: Bool + @StateObject var viewModel: ReadShortcutViewModel - @State var userInformation: User? = nil - @State var numberOfLike = 0 + @AppStorage("useWithoutSignIn") var useWithoutSignIn: Bool = false var body: some View { VStack(alignment: .leading, spacing: 16) { @@ -398,27 +390,27 @@ extension ReadShortcutView { /// 단축어 아이콘 VStack { - Image(systemName: shortcut.sfSymbol) + Image(systemName: viewModel.shortcut.sfSymbol) .mediumShortcutIcon() .foregroundColor(Color.textIcon) } .frame(width: 52, height: 52) - .background(Color.fetchGradient(color: shortcut.color)) + .background(Color.fetchGradient(color: viewModel.shortcut.color)) .cornerRadius(8) Spacer() /// 좋아요 버튼 - Text("\(isMyLike ? Image(systemName: "heart.fill") : Image(systemName: "heart")) \(numberOfLike)") + Text("\(viewModel.isMyLike ? Image(systemName: "heart.fill") : Image(systemName: "heart")) \(viewModel.numberOfLike)") .shortcutsZipBody2() .padding(10) - .foregroundColor(isMyLike ? Color.textIcon : Color.gray4) - .background(isMyLike ? Color.shortcutsZipPrimary : Color.gray1) + .foregroundColor(viewModel.isMyLike ? Color.textIcon : Color.gray4) + .background(viewModel.isMyLike ? Color.shortcutsZipPrimary : Color.gray1) .cornerRadius(12) .onTapGesture { if !useWithoutSignIn { - isMyLike.toggle() - numberOfLike += isMyLike ? 1 : -1 + viewModel.isMyLike.toggle() + viewModel.numberOfLike += viewModel.isMyLike ? 1 : -1 } else { loginAlerter.isPresented = true } @@ -427,34 +419,24 @@ extension ReadShortcutView { /// 단축어 이름, 한 줄 설명 VStack(alignment: .leading, spacing: 4) { - Text("\(shortcut.title)") + Text("\(viewModel.shortcut.title)") .shortcutsZipTitle1() .foregroundColor(Color.gray5) .fixedSize(horizontal: false, vertical: true) - Text("\(shortcut.subtitle)") + Text("\(viewModel.shortcut.subtitle)") .shortcutsZipBody1() .foregroundColor(Color.gray3) .fixedSize(horizontal: false, vertical: true) } /// 단축어 작성자 닉네임 - UserNameCell(userInformation: userInformation, gradeImage: shortcutsZipViewModel.fetchShortcutGradeImage(isBig: false, shortcutGrade: shortcutsZipViewModel.checkShortcutGrade(userID: userInformation?.id ?? "!"))) + UserNameCell(userInformation: viewModel.userInformation, gradeImage: viewModel.userGrade) } .frame(maxWidth: .infinity, minHeight: 160, alignment: .leading) .padding(.bottom, 20) .padding(.horizontal, 16) .background(Color.shortcutsZipWhite) - .onAppear { - shortcutsZipViewModel.fetchUser(userID: shortcut.author, - isCurrentUser: false) { user in - userInformation = user - } - numberOfLike = shortcut.numberOfLike - } - .onDisappear { - self.shortcut.numberOfLike = numberOfLike - } } } @@ -462,8 +444,7 @@ extension ReadShortcutView { struct ReadShortcutContentView: View { - @Binding var shortcut: Shortcuts - + @StateObject var viewModel: ReadShortcutViewModel var body: some View { VStack(alignment: .leading, spacing: 24) { @@ -472,16 +453,16 @@ extension ReadShortcutView { Text(TextLiteral.readShortcutContentViewDescription) .shortcutsZipBody2() .foregroundColor(Color.gray4) - Text(shortcut.description) + Text(viewModel.shortcut.description) .shortcutsZipBody2() .foregroundColor(Color.gray5) .lineLimit(nil) } - splitList(title: TextLiteral.readShortcutContentViewCategory, content: shortcut.category) + splitList(title: TextLiteral.readShortcutContentViewCategory, content: viewModel.shortcut.category) - if !shortcut.requiredApp.isEmpty { - splitList(title: TextLiteral.readShortcutContentViewRequiredApps, content: shortcut.requiredApp) + if !viewModel.shortcut.requiredApp.isEmpty { + splitList(title: TextLiteral.readShortcutContentViewRequiredApps, content: viewModel.shortcut.requiredApp) } Spacer() @@ -527,15 +508,14 @@ extension ReadShortcutView { @Environment(\.loginAlertKey) var loginAlerter @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel - @AppStorage("useWithoutSignIn") var useWithoutSignIn: Bool = false + @StateObject var viewModel: ReadShortcutViewModel - @Binding var shortcut: Shortcuts - @Binding var isUpdating: Bool + @AppStorage("useWithoutSignIn") var useWithoutSignIn: Bool = false var body: some View { VStack(alignment: .leading, spacing: 16) { - if shortcut.updateDescription.count == 1 { + if viewModel.shortcut.updateDescription.count == 1 { Text(TextLiteral.readShortcutVersionViewNoUpdates) .shortcutsZipBody2() .foregroundColor(.gray4) @@ -556,16 +536,16 @@ extension ReadShortcutView { private var versionView: some View { - ForEach(Array(zip(shortcut.updateDescription, shortcut.updateDescription.indices)), id: \.0) { data, index in + ForEach(Array(zip(viewModel.shortcut.updateDescription, viewModel.shortcut.updateDescription.indices)), id: \.0) { data, index in VStack(alignment: .leading, spacing: 12) { HStack { - Text("Ver \(shortcut.updateDescription.count - index).0") + Text("Ver \(viewModel.shortcut.updateDescription.count - index).0") .shortcutsZipBody2() .foregroundColor(.gray5) Spacer() - Text(shortcut.date[index].getVersionUpdateDateFormat()) + Text(viewModel.shortcut.date[index].getVersionUpdateDateFormat()) .shortcutsZipBody2() .foregroundColor(.gray3) } @@ -579,11 +559,9 @@ extension ReadShortcutView { if index != 0 { Button { if !useWithoutSignIn { - if let url = URL(string: shortcut.downloadLink[index]) { - if (shortcutsZipViewModel.userInfo?.downloadedShortcuts.firstIndex(where: { $0.id == shortcut.id })) == nil { - shortcut.numberOfDownload += 1 - } - shortcutsZipViewModel.updateNumberOfDownload(shortcut: shortcut, downloadlinkIndex: index) + if let url = URL(string: viewModel.shortcut.downloadLink[index]) { + viewModel.checkIfDownloaded() + viewModel.updateNumberOfDownload(index: index) openURL(url) } } else { @@ -609,24 +587,16 @@ extension ReadShortcutView { @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel + @StateObject var viewModel: ReadShortcutViewModel + @AppStorage("useWithoutSignIn") var useWithoutSignIn: Bool = false @FocusState var isFocused: Bool - @Binding var newComment: Comment /// 추가되는 댓글 - @Binding var comments: Comments /// 화면에 나타나는 모든 댓글 - @Binding var nestedCommentTarget: String /// 대댓글 작성 시 텍스트필드 위에 뜨는 작성자 정보 - @Binding var isEditingComment: Bool - - @State var isDeletingComment = false - @State var deletedComment = Comment(user_nickname: "", user_id: "", date: "", depth: 0, contents: "") - - let shortcutID: String - var body: some View { VStack(alignment: .leading) { - if comments.comments.isEmpty { + if viewModel.comments.comments.isEmpty { Text(TextLiteral.readShortcutCommentViewNoComments) .shortcutsZipBody2() .foregroundColor(.gray4) @@ -639,7 +609,7 @@ extension ReadShortcutView { .frame(maxHeight: .infinity) } .padding(.top, 16) - .alert(TextLiteral.readShortcutCommentViewDeletionTitle, isPresented: $isDeletingComment) { + .alert(TextLiteral.readShortcutCommentViewDeletionTitle, isPresented: $viewModel.isDeletingComment) { Button(role: .cancel) { } label: { @@ -647,13 +617,7 @@ extension ReadShortcutView { } Button(role: .destructive) { - if deletedComment.depth == 0 { - comments.comments.removeAll(where: { $0.bundle_id == deletedComment.bundle_id}) - } else { - comments.comments.removeAll(where: { $0.id == deletedComment.id}) - } - - shortcutsZipViewModel.setData(model: comments) + viewModel.deleteComment() } label: { Text(TextLiteral.delete) } @@ -664,7 +628,7 @@ extension ReadShortcutView { private var commentView: some View { - ForEach(comments.comments, id: \.self) { comment in + ForEach(viewModel.comments.comments, id: \.self) { comment in HStack(alignment: .top, spacing: 8) { if comment.depth == 1 { @@ -700,9 +664,9 @@ extension ReadShortcutView { HStack(spacing: 0) { if !useWithoutSignIn { Button { - nestedCommentTarget = comment.user_nickname - newComment.bundle_id = comment.bundle_id - newComment.depth = 1 + viewModel.nestedCommentTarget = comment.user_nickname + viewModel.comment.bundle_id = comment.bundle_id + viewModel.comment.depth = 1 isFocused = true } label: { Text(TextLiteral.readShortcutCommentViewReply) @@ -716,8 +680,8 @@ extension ReadShortcutView { if user.id == comment.user_id { Button { withAnimation(.easeInOut) { - isEditingComment.toggle() - newComment = comment + viewModel.isEditingComment.toggle() + viewModel.comment = comment } } label: { Text(TextLiteral.readShortcutCommentViewEdit) @@ -727,8 +691,8 @@ extension ReadShortcutView { } Button { - isDeletingComment.toggle() - deletedComment = comment + viewModel.isDeletingComment.toggle() + viewModel.deletedComment = comment } label: { Text(TextLiteral.delete) .shortcutsZipFootnote() From 2d7c12b227b2911b0deef0a68e2c1ddf7d95641a Mon Sep 17 00:00:00 2001 From: jim4020key Date: Sun, 16 Jul 2023 20:48:11 +0900 Subject: [PATCH 23/53] [Feat] #473 - Sort comments --- .../HappyAnding/ViewModel/ReadShortcutViewModel.swift | 5 +++++ .../Views/ReadShortcutViews/ReadShortcutView.swift | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift index 92e32ea3..34dbcf51 100644 --- a/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift @@ -106,6 +106,7 @@ final class ReadShortcutViewModel: ObservableObject { shortcutsZipViewModel.setData(model: comments) commentText = "" comment = comment.resetComment() + self.comments.comments = comments.fetchSortedComment() } func cancelNestedComment() { @@ -147,4 +148,8 @@ final class ReadShortcutViewModel: ObservableObject { shortcutsZipViewModel.setData(model: comments) } + + func fetchUserGrade(id: String) -> Image { + shortcutsZipViewModel.fetchShortcutGradeImage(isBig: false, shortcutGrade: shortcutsZipViewModel.checkShortcutGrade(userID: id)) + } } diff --git a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift index a6a234e7..cc4693b1 100644 --- a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift @@ -642,7 +642,7 @@ extension ReadShortcutView { /// 유저 정보 HStack(spacing: 8) { - shortcutsZipViewModel.fetchShortcutGradeImage(isBig: false, shortcutGrade: shortcutsZipViewModel.checkShortcutGrade(userID: comment.user_id )) + viewModel.fetchUserGrade(id: comment.user_id) .font(.system(size: 24, weight: .medium)) .frame(width: 24, height: 24) .foregroundColor(.gray3) @@ -653,7 +653,6 @@ extension ReadShortcutView { } .padding(.bottom, 4) - /// 댓글 내용 Text(comment.contents) .shortcutsZipBody2() From 2db183912a277f494f405627ea4a1a951c714dbc Mon Sep 17 00:00:00 2001 From: jim4020key Date: Sun, 16 Jul 2023 20:53:52 +0900 Subject: [PATCH 24/53] [Style] #473 - Fix typo --- HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift | 2 +- .../HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift index 34dbcf51..d6ca0ade 100644 --- a/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift @@ -70,7 +70,7 @@ final class ReadShortcutViewModel: ObservableObject { shortcutsZipViewModel.updateNumberOfDownload(shortcut: shortcut, downloadlinkIndex: index) } - func onViewDissapear() { + func onViewDisappear() { if isMyLike != isMyFirstLike { shortcutsZipViewModel.updateNumberOfLike(isMyLike: isMyLike, shortcut: shortcut) } diff --git a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift index cc4693b1..0598d7bc 100644 --- a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift @@ -122,7 +122,7 @@ struct ReadShortcutView: View { UINavigationBar.appearance().standardAppearance.configureWithTransparentBackground() } .onDisappear { - viewModel.onViewDissapear() + viewModel.onViewDisappear() } .alert(TextLiteral.readShortcutViewDeletionTitle, isPresented: $viewModel.isDeletingShortcut) { Button(role: .cancel) { From ae563edebe1994e509ececa5fc9e5af248872fb0 Mon Sep 17 00:00:00 2001 From: jim4020key Date: Thu, 20 Jul 2023 17:02:10 +0900 Subject: [PATCH 25/53] [Feat] #473 - Add .onDisappear method --- .../HappyAnding/ViewModel/ReadShortcutViewModel.swift | 10 +++++++--- .../Views/ReadShortcutViews/ReadShortcutView.swift | 3 +++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift index d6ca0ade..55f4f8e0 100644 --- a/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift @@ -9,9 +9,9 @@ import SwiftUI final class ReadShortcutViewModel: ObservableObject { - var shortcutsZipViewModel = ShortcutsZipViewModel.share + private let shortcutsZipViewModel = ShortcutsZipViewModel.share - @Published var shortcut: Shortcuts + @Published private(set) var shortcut: Shortcuts /// ReadShortcutView @Published var isDeletingShortcut = false @@ -35,7 +35,7 @@ final class ReadShortcutViewModel: ObservableObject { /// ReadShortcutViewHeader @Published var userInformation: User? = nil @Published var numberOfLike = 0 - @Published var userGrade = Image(systemName: "person.crop.circle.fill") + @Published private(set) var userGrade = Image(systemName: "person.crop.circle.fill") /// ReadShortcutCommentView @Published var isDeletingComment = false @@ -152,4 +152,8 @@ final class ReadShortcutViewModel: ObservableObject { func fetchUserGrade(id: String) -> Image { shortcutsZipViewModel.fetchShortcutGradeImage(isBig: false, shortcutGrade: shortcutsZipViewModel.checkShortcutGrade(userID: id)) } + + func refreshShortcut() { + self.shortcut = shortcutsZipViewModel.fetchShortcutDetail(id: shortcut.id) ?? shortcut + } } diff --git a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift index 0598d7bc..b49a5c08 100644 --- a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift @@ -143,6 +143,9 @@ struct ReadShortcutView: View { NavigationRouter(content: writeShortcutView, path: $writeNavigation.navigationPath) .environmentObject(writeNavigation) + .onDisappear { + viewModel.refreshShortcut() + } } .fullScreenCover(isPresented: $viewModel.isUpdatingShortcut) { UpdateShortcutView(viewModel: self.viewModel) From ff46b6ea2078c8314b6ed0e35834f8babdfeff76 Mon Sep 17 00:00:00 2001 From: jim4020key Date: Tue, 25 Jul 2023 00:41:05 +0900 Subject: [PATCH 26/53] [Feat] #473 - Disable withdrawn user --- .../Extensions/View/View+Navigation.swift | 4 ++-- .../ViewModel/ReadShortcutViewModel.swift | 23 ++++++++++++------- .../Views/Components/UserNameCell.swift | 14 +++++------ 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift index f36e8a5e..56e03800 100644 --- a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift +++ b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift @@ -115,8 +115,8 @@ struct NavigationViewModifier: ViewModifier { func body(content: Content) -> some View { content - .navigationDestination(for: User?.self) { data in - ShowProfileView(viewModel: ShowProfileViewModel(data: data ?? User())) + .navigationDestination(for: User.self) { data in + ShowProfileView(viewModel: ShowProfileViewModel(data: data)) } .navigationDestination(for: Curation.self) { data in ReadCurationView(viewModel: ReadCurationViewModel(data: data)) diff --git a/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift index 55f4f8e0..eb9e8fcc 100644 --- a/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift @@ -13,7 +13,7 @@ final class ReadShortcutViewModel: ObservableObject { @Published private(set) var shortcut: Shortcuts - /// ReadShortcutView + // ReadShortcutView @Published var isDeletingShortcut = false @Published var isEditingShortcut = false @Published var isUpdatingShortcut = false @@ -32,32 +32,39 @@ final class ReadShortcutViewModel: ObservableObject { @Published var isEditingComment = false @Published var isUndoingCommentEdit = false - /// ReadShortcutViewHeader - @Published var userInformation: User? = nil + // ReadShortcutViewHeader + @Published var userInformation: User @Published var numberOfLike = 0 @Published private(set) var userGrade = Image(systemName: "person.crop.circle.fill") - /// ReadShortcutCommentView + // ReadShortcutCommentView @Published var isDeletingComment = false @Published var deletedComment = Comment(user_nickname: "", user_id: "", date: "", depth: 0, contents: "") - /// UpdateShortcutView + // UpdateShortcutView @Published var updatedLink = "" @Published var updateDescription = "" @Published var isLinkValid = false @Published var isDescriptionValid = false init(data: Shortcuts) { + self.userInformation = User() self.shortcut = shortcutsZipViewModel.fetchShortcutDetail(id: data.id) ?? data self.isMyLike = shortcutsZipViewModel.checkLikedShortrcut(shortcutID: data.id) self.isMyFirstLike = isMyLike self.comments = shortcutsZipViewModel.fetchComment(shortcutID: data.id) - shortcutsZipViewModel.fetchUser(userID: data.author, + self.numberOfLike = data.numberOfLike + fetchUser() + } + + private func fetchUser() { + shortcutsZipViewModel.fetchUser(userID: shortcut.author, isCurrentUser: false) { user in self.userInformation = user + let grade = self.shortcutsZipViewModel.checkShortcutGrade(userID: self.userInformation.id) + let image = self.shortcutsZipViewModel.fetchShortcutGradeImage(isBig: false, shortcutGrade: grade) + self.userGrade = image } - self.userGrade = shortcutsZipViewModel.fetchShortcutGradeImage(isBig: false, shortcutGrade: shortcutsZipViewModel.checkShortcutGrade(userID: userInformation?.id ?? "!")) - self.numberOfLike = data.numberOfLike } func checkIfDownloaded() { diff --git a/HappyAnding/HappyAnding/Views/Components/UserNameCell.swift b/HappyAnding/HappyAnding/Views/Components/UserNameCell.swift index ce0ce231..b0da346c 100644 --- a/HappyAnding/HappyAnding/Views/Components/UserNameCell.swift +++ b/HappyAnding/HappyAnding/Views/Components/UserNameCell.swift @@ -18,11 +18,11 @@ import SwiftUI - description: - 해당 뷰는 넓이가 부모 프레임에 꽉차도록 만들어졌습니다. 여백이 필요한 경우 부모프레임 또는 해당 뷰를 불러온 후 설정해주세요. - + */ struct UserNameCell: View { - var userInformation: User? - var gradeImage: Image? + var userInformation: User + var gradeImage: Image var body: some View { HStack { @@ -31,7 +31,7 @@ struct UserNameCell: View { .frame(width: 24, height: 24) .foregroundColor(.gray3) - if let userInformation, !userInformation.nickname.isEmpty { + if !userInformation.nickname.isEmpty { Text(userInformation.nickname) .shortcutsZipBody2() .foregroundColor(.gray4) @@ -43,7 +43,7 @@ struct UserNameCell: View { Spacer() - if userInformation?.nickname != nil { + if !userInformation.id.isEmpty { Image(systemName: "chevron.right") .shortcutsZipFootnote() .foregroundColor(.gray4) @@ -57,12 +57,12 @@ struct UserNameCell: View { .foregroundColor(.gray1) ) .navigationLinkRouter(data: self.userInformation) - .disabled(self.userInformation == nil) + .disabled(self.userInformation.id.isEmpty) } } struct UserNameCell_Previews: PreviewProvider { static var previews: some View { - UserNameCell() + UserNameCell(userInformation: User(), gradeImage: Image(systemName: "person.crop.circle.fill")) } } From aedd75400a0a0095368044025229a702eea33fab Mon Sep 17 00:00:00 2001 From: jim4020key Date: Tue, 25 Jul 2023 01:03:18 +0900 Subject: [PATCH 27/53] [Feat] #473 - Add functions to ShowProfileViewModel --- .../ViewModel/ShowProfileViewModel.swift | 22 ++++++++----------- .../ReadShortcutViews/ShowProfileView.swift | 18 +++++++-------- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/HappyAnding/HappyAnding/ViewModel/ShowProfileViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ShowProfileViewModel.swift index e659af83..8b780d99 100644 --- a/HappyAnding/HappyAnding/ViewModel/ShowProfileViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ShowProfileViewModel.swift @@ -9,31 +9,27 @@ import SwiftUI final class ShowProfileViewModel: ObservableObject { - var shortcutsZipViewModel = ShortcutsZipViewModel.share + private let shortcutsZipViewModel = ShortcutsZipViewModel.share @Published var user: User @Published private(set) var shortcuts: [Shortcuts] = [] @Published private(set) var curations: [Curation] = [] @Published private(set) var userGrade = Image(systemName: "person.crop.circle.fill") @Published var currentTab: Int = 0 - @Published var animationAmount = 0.0 + @Published private(set) var animationAmount = 0.0 init(data: User) { self.user = data - fetchUserGrade() - fetchShortcuts() - fetchCurations() - } - - private func fetchUserGrade() { - self.userGrade = shortcutsZipViewModel.fetchShortcutGradeImage(isBig: true, shortcutGrade: shortcutsZipViewModel.checkShortcutGrade(userID: user.id)) + self.userGrade = shortcutsZipViewModel.fetchShortcutGradeImage(isBig: true, shortcutGrade: shortcutsZipViewModel.checkShortcutGrade(userID: data.id)) + self.shortcuts = shortcutsZipViewModel.allShortcuts.filter { $0.author == data.id } + self.curations = shortcutsZipViewModel.fetchCurationByAuthor(author: data.id) } - private func fetchShortcuts() { - self.shortcuts = shortcutsZipViewModel.allShortcuts.filter { $0.author == user.id } + func profileDidTap() { + self.animationAmount += 360 } - private func fetchCurations() { - self.curations = shortcutsZipViewModel.fetchCurationByAuthor(author: user.id) + func moveTab(to tab: Int) { + self.currentTab = tab } } diff --git a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift index 143f3fc0..49f2bac1 100644 --- a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift +++ b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift @@ -12,7 +12,7 @@ struct ShowProfileView: View { @StateObject var viewModel: ShowProfileViewModel @Namespace var namespace - + private let tabItems = [TextLiteral.showProfileViewShortcutTabTitle, TextLiteral.showProfileViewCurationTabTitle] var body: some View { @@ -24,7 +24,7 @@ struct ShowProfileView: View { VStack(spacing: 8) { Button { withAnimation(.interpolatingSpring(stiffness: 10, damping: 3)) { - viewModel.animationAmount += 360 + viewModel.profileDidTap() } } label: { if viewModel.shortcuts.isEmpty { @@ -67,7 +67,7 @@ struct ShowProfileView: View { .toolbar(.visible, for: .tabBar) .onAppear { withAnimation(.interpolatingSpring(stiffness: 10, damping: 3)) { - viewModel.animationAmount += 360 + viewModel.profileDidTap() } } } @@ -76,7 +76,7 @@ struct ShowProfileView: View { var tabBarView: some View { HStack(spacing: 20) { ForEach(Array(zip(self.tabItems.indices, self.tabItems)), id: \.0) { index, name in - tabBarItem(string: name, tab: index) + tabBarItem(title: name, tabID: index) } } .padding(.horizontal, 16) @@ -84,13 +84,13 @@ struct ShowProfileView: View { .background(Color.shortcutsZipWhite) } - private func tabBarItem(string: String, tab: Int) -> some View { + private func tabBarItem(title: String, tabID: Int) -> some View { Button { - viewModel.currentTab = tab + viewModel.moveTab(to: tabID) } label: { VStack { - if viewModel.currentTab == tab { - Text(string) + if viewModel.currentTab == tabID { + Text(title) .shortcutsZipHeadline() .foregroundColor(.gray5) Color.gray5 @@ -98,7 +98,7 @@ struct ShowProfileView: View { .matchedGeometryEffect(id: "underline", in: namespace, properties: .frame) } else { - Text(string) + Text(title) .shortcutsZipBody1() .foregroundColor(.gray3) Color.clear From 597055dcd6078c8042e172f60b47df9a1a884ce2 Mon Sep 17 00:00:00 2001 From: jim4020key Date: Tue, 25 Jul 2023 05:11:16 +0900 Subject: [PATCH 28/53] [Style] #473 - Modify properties --- HappyAnding/HappyAnding/Model/Comment.swift | 26 +++++++++++++ .../ViewModel/ReadShortcutViewModel.swift | 38 +++++++++++++------ .../ReadShortcutViews/ReadShortcutView.swift | 20 +++++----- .../UpdateShortcutView.swift | 20 +++++----- 4 files changed, 71 insertions(+), 33 deletions(-) diff --git a/HappyAnding/HappyAnding/Model/Comment.swift b/HappyAnding/HappyAnding/Model/Comment.swift index 898d0c82..fb3ed8a6 100644 --- a/HappyAnding/HappyAnding/Model/Comment.swift +++ b/HappyAnding/HappyAnding/Model/Comment.swift @@ -15,6 +15,16 @@ struct Comments: Identifiable, Codable, Equatable { let data = (try? JSONEncoder().encode(self)) ?? Data() return (try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any]) ?? [:] } + + init() { + self.id = "" + self.comments = [] + } + + init(id: String, comments: [Comment]) { + self.id = id + self.comments = comments + } } struct Comment: Identifiable, Codable, Hashable { @@ -25,6 +35,22 @@ struct Comment: Identifiable, Codable, Hashable { var date: String //처음 작성한 날짜만 저장 var depth: Int //0이면 원댓글, 1이면 대댓글 var contents: String + + init() { + self.user_nickname = "" + self.user_id = "" + self.date = "" + self.depth = 0 + self.contents = "" + } + + init(user_nickname: String, user_id: String, date: String, depth: Int, contents: String) { + self.user_nickname = user_nickname + self.user_id = user_id + self.date = date + self.depth = depth + self.contents = contents + } } extension Comments { diff --git a/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift index eb9e8fcc..eb945867 100644 --- a/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift @@ -19,13 +19,13 @@ final class ReadShortcutViewModel: ObservableObject { @Published var isUpdatingShortcut = false @Published var isMyLike = false - @Published var isMyFirstLike = false + @Published private var isMyFirstLike = false @Published var isDownloadingShortcut = false - @Published var isDowngradingUserLevel = false + @Published private(set) var isDowngradingUserLevel = false @Published var currentTab: Int = 0 - @Published var comments: Comments = Comments(id: "", comments: []) - @Published var comment: Comment = Comment(user_nickname: "", user_id: "", date: "", depth: 0, contents: "") + @Published private(set) var comments: Comments = Comments() + @Published var comment: Comment = Comment() @Published var nestedCommentTarget: String = "" @Published var commentText = "" @@ -33,13 +33,13 @@ final class ReadShortcutViewModel: ObservableObject { @Published var isUndoingCommentEdit = false // ReadShortcutViewHeader - @Published var userInformation: User + @Published private(set) var author: User @Published var numberOfLike = 0 @Published private(set) var userGrade = Image(systemName: "person.crop.circle.fill") // ReadShortcutCommentView @Published var isDeletingComment = false - @Published var deletedComment = Comment(user_nickname: "", user_id: "", date: "", depth: 0, contents: "") + @Published var deletedComment = Comment() // UpdateShortcutView @Published var updatedLink = "" @@ -47,26 +47,40 @@ final class ReadShortcutViewModel: ObservableObject { @Published var isLinkValid = false @Published var isDescriptionValid = false + var isUpdateValid: Bool { + isLinkValid && isDescriptionValid + } + init(data: Shortcuts) { - self.userInformation = User() + self.author = User() self.shortcut = shortcutsZipViewModel.fetchShortcutDetail(id: data.id) ?? data self.isMyLike = shortcutsZipViewModel.checkLikedShortrcut(shortcutID: data.id) self.isMyFirstLike = isMyLike self.comments = shortcutsZipViewModel.fetchComment(shortcutID: data.id) self.numberOfLike = data.numberOfLike - fetchUser() + fetchAuthor() } - private func fetchUser() { + private func fetchAuthor() { shortcutsZipViewModel.fetchUser(userID: shortcut.author, isCurrentUser: false) { user in - self.userInformation = user - let grade = self.shortcutsZipViewModel.checkShortcutGrade(userID: self.userInformation.id) + self.author = user + let grade = self.shortcutsZipViewModel.checkShortcutGrade(userID: self.author.id) let image = self.shortcutsZipViewModel.fetchShortcutGradeImage(isBig: false, shortcutGrade: grade) self.userGrade = image } } + func moveTab(to tab: Int) { + self.currentTab = tab + } + + func setReply(to comment: Comment) { + self.nestedCommentTarget = comment.user_nickname + self.comment.bundle_id = comment.bundle_id + self.comment.depth = 1 + } + func checkIfDownloaded() { if (shortcutsZipViewModel.userInfo?.downloadedShortcuts.firstIndex(where: { $0.id == shortcut.id })) == nil { shortcut.numberOfDownload += 1 @@ -133,7 +147,7 @@ final class ReadShortcutViewModel: ObservableObject { window.rootViewController?.present(activityVC, animated: true, completion: nil) } - func checkDowngrade() { + func checkDowngrading() { isDeletingShortcut.toggle() isDowngradingUserLevel = shortcutsZipViewModel.isShortcutDowngrade() } diff --git a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift index b49a5c08..fe8d264d 100644 --- a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ReadShortcutView.swift @@ -330,7 +330,7 @@ extension ReadShortcutView { private var deleteButton: some View { Button(role: .destructive) { - viewModel.checkDowngrade() + viewModel.checkDowngrading() } label: { Label(TextLiteral.delete, systemImage: "trash.fill") } @@ -341,7 +341,7 @@ extension ReadShortcutView { private var tabBarView: some View { HStack(spacing: 20) { ForEach(Array(zip(self.tabItems.indices, self.tabItems)), id: \.0) { index, name in - tabBarItem(string: name, tab: index) + tabBarItem(title: name, tabID: index) } } .padding(.horizontal, 16) @@ -349,13 +349,13 @@ extension ReadShortcutView { .background(Color.shortcutsZipWhite) } - private func tabBarItem(string: String, tab: Int) -> some View { + private func tabBarItem(title: String, tabID: Int) -> some View { Button { - viewModel.currentTab = tab + viewModel.moveTab(to: tabID) } label: { VStack { - if viewModel.currentTab == tab { - Text(string) + if viewModel.currentTab == tabID { + Text(title) .shortcutsZipHeadline() .foregroundColor(.gray5) Color.gray5 @@ -363,7 +363,7 @@ extension ReadShortcutView { .matchedGeometryEffect(id: "underline", in: namespace, properties: .frame) } else { - Text(string) + Text(title) .shortcutsZipBody1() .foregroundColor(.gray3) Color.clear.frame(height: 2) @@ -434,7 +434,7 @@ extension ReadShortcutView { } /// 단축어 작성자 닉네임 - UserNameCell(userInformation: viewModel.userInformation, gradeImage: viewModel.userGrade) + UserNameCell(userInformation: viewModel.author, gradeImage: viewModel.userGrade) } .frame(maxWidth: .infinity, minHeight: 160, alignment: .leading) .padding(.bottom, 20) @@ -666,9 +666,7 @@ extension ReadShortcutView { HStack(spacing: 0) { if !useWithoutSignIn { Button { - viewModel.nestedCommentTarget = comment.user_nickname - viewModel.comment.bundle_id = comment.bundle_id - viewModel.comment.depth = 1 + viewModel.setReply(to: comment) isFocused = true } label: { Text(TextLiteral.readShortcutCommentViewReply) diff --git a/HappyAnding/HappyAnding/Views/ReadShortcutViews/UpdateShortcutView.swift b/HappyAnding/HappyAnding/Views/ReadShortcutViews/UpdateShortcutView.swift index f01c79b9..ebd438de 100644 --- a/HappyAnding/HappyAnding/Views/ReadShortcutViews/UpdateShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ReadShortcutViews/UpdateShortcutView.swift @@ -16,12 +16,12 @@ struct UpdateShortcutView: View { var body: some View { VStack { HStack { - Button(action: { + Button { viewModel.isUpdatingShortcut.toggle() - }, label: { + } label: { Text(TextLiteral.cancel) .foregroundColor(.gray5) - }) + } .frame(maxWidth: .infinity, alignment: .leading) Text(TextLiteral.update) @@ -47,7 +47,7 @@ struct UpdateShortcutView: View { isDescriptionFieldFocused = true } .submitLabel(.next) - .onAppear(perform : UIApplication.shared.hideKeyboard) + .onAppear(perform: UIApplication.shared.hideKeyboard) .padding(.top, 30) ValidationCheckTextField(textType: .mandatory, @@ -63,19 +63,19 @@ struct UpdateShortcutView: View { Spacer() - Button(action: { + Button { viewModel.updateShortcut() - }, label: { + } label: { ZStack { RoundedRectangle(cornerRadius: 12) - .foregroundColor(viewModel.isLinkValid && viewModel.isDescriptionValid ? .shortcutsZipPrimary : .shortcutsZipPrimary.opacity(0.13)) + .foregroundColor(viewModel.isUpdateValid ? .shortcutsZipPrimary : .shortcutsZipPrimary.opacity(0.13)) .frame(maxWidth: .infinity, maxHeight: 52) Text(TextLiteral.update) - .foregroundColor(viewModel.isLinkValid && viewModel.isDescriptionValid ? .textButton : .textButtonDisable) + .foregroundColor(viewModel.isUpdateValid ? .textButton : .textButtonDisable) .shortcutsZipBody1() } - }) - .disabled(!viewModel.isLinkValid || !viewModel.isDescriptionValid) + } + .disabled(!viewModel.isUpdateValid) .padding(.horizontal, 16) .padding(.bottom, 24) } From 8172fa2dcc1ffb715841bb363f8552f7d765cdef Mon Sep 17 00:00:00 2001 From: jim4020key Date: Tue, 25 Jul 2023 06:08:59 +0900 Subject: [PATCH 29/53] [Feat] #473 - Resolve Conflicts --- .../HappyAnding.xcodeproj/project.pbxproj | 4 +-- .../Model/NavigationStackModel.swift | 8 ----- HappyAnding/HappyAnding/Model/Shortcuts.swift | 32 +++++++++++++++++++ .../ReadCurationViewModel.swift | 4 +++ .../ReadShortcutViewModel.swift | 0 .../ShowProfileViewModel.swift | 0 .../ReadCurationView.swift | 6 ++-- .../ReadShortcutViews/ShowProfileView.swift | 2 +- 8 files changed, 42 insertions(+), 14 deletions(-) rename HappyAnding/HappyAnding/ViewModel/{ => ReadShortcutViewModels}/ReadShortcutViewModel.swift (100%) rename HappyAnding/HappyAnding/ViewModel/{ => ReadShortcutViewModels}/ShowProfileViewModel.swift (100%) diff --git a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj index f69c149a..5873c7a3 100644 --- a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj +++ b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj @@ -393,6 +393,8 @@ 8788E1A32A484533007C3852 /* ReadShortcutViewModels */ = { isa = PBXGroup; children = ( + 4D93D0742A61D0D10042CBA8 /* ReadShortcutViewModel.swift */, + 4D93D06E2A5956E60042CBA8 /* ShowProfileViewModel.swift */, ); path = ReadShortcutViewModels; sourceTree = ""; @@ -657,8 +659,6 @@ A0F822AB2910B8F100AF4448 /* ShortcutsZipViewModel.swift */, 4D61A766291E1EE8000EF531 /* NavigationViewModel.swift */, F9AC2BB52935201C00165820 /* CheckUpdateVersion.swift */, - 4D93D06E2A5956E60042CBA8 /* ShowProfileViewModel.swift */, - 4D93D0742A61D0D10042CBA8 /* ReadShortcutViewModel.swift */, ); path = ViewModel; sourceTree = ""; diff --git a/HappyAnding/HappyAnding/Model/NavigationStackModel.swift b/HappyAnding/HappyAnding/Model/NavigationStackModel.swift index 21d0f376..9ed04806 100644 --- a/HappyAnding/HappyAnding/Model/NavigationStackModel.swift +++ b/HappyAnding/HappyAnding/Model/NavigationStackModel.swift @@ -15,13 +15,6 @@ struct NavigationListShortcutType: Identifiable, Hashable { let navigationParentView: NavigationParentView } - -struct NavigationProfile: Identifiable, Hashable { - var id = UUID().uuidString - - var userInfo: User? -} - struct NavigationListCategoryShortcutType: Identifiable, Hashable { var id = UUID().uuidString @@ -60,7 +53,6 @@ enum NavigationNicknameView: Hashable, Equatable { case first } - enum NavigationLisence: Hashable, Equatable { case first } diff --git a/HappyAnding/HappyAnding/Model/Shortcuts.swift b/HappyAnding/HappyAnding/Model/Shortcuts.swift index 696163fd..8847812d 100644 --- a/HappyAnding/HappyAnding/Model/Shortcuts.swift +++ b/HappyAnding/HappyAnding/Model/Shortcuts.swift @@ -31,4 +31,36 @@ struct Shortcuts: Identifiable, Codable, Equatable, Hashable { let data = (try? JSONEncoder().encode(self)) ?? Data() return (try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any]) ?? [:] } + + init() { + self.sfSymbol = "" + self.color = "" + self.title = "" + self.subtitle = "" + self.description = "" + self.category = [] + self.requiredApp = [] + self.numberOfLike = 0 + self.numberOfDownload = 0 + self.author = "" + self.shortcutRequirements = "" + self.downloadLink = [] + self.curationIDs = [] + } + + init(sfSymbol: String, color: String, title: String, subtitle: String, description: String, category: [String], requiredApp: [String], numberOfLike: Int, numberOfDownload: Int, author: String, shortcutRequirements: String, downloadLink: [String], curationIDs: [String]) { + self.sfSymbol = sfSymbol + self.color = color + self.title = title + self.subtitle = subtitle + self.description = description + self.category = category + self.requiredApp = requiredApp + self.numberOfLike = numberOfLike + self.numberOfDownload = numberOfDownload + self.author = author + self.shortcutRequirements = shortcutRequirements + self.downloadLink = downloadLink + self.curationIDs = curationIDs + } } diff --git a/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift index f65a0ecc..0d2a9bd7 100644 --- a/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift @@ -52,5 +52,9 @@ final class ReadCurationViewModel: ObservableObject { guard let window = windowScene?.windows.first else { return } window.rootViewController?.present(activityVC, animated: true, completion: nil) } + + func fetchShortcut(from shortcutCellModel: ShortcutCellModel) -> Shortcuts { + shortcutsZipViewModel.fetchShortcutDetail(id: shortcutCellModel.id) ?? Shortcuts() + } } diff --git a/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModels/ReadShortcutViewModel.swift similarity index 100% rename from HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModel.swift rename to HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModels/ReadShortcutViewModel.swift diff --git a/HappyAnding/HappyAnding/ViewModel/ShowProfileViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModels/ShowProfileViewModel.swift similarity index 100% rename from HappyAnding/HappyAnding/ViewModel/ShowProfileViewModel.swift rename to HappyAnding/HappyAnding/ViewModel/ReadShortcutViewModels/ShowProfileViewModel.swift diff --git a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift index ecd4ae97..111d438e 100644 --- a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift @@ -22,11 +22,11 @@ struct ReadCurationView: View { } VStack(spacing: 0) { - ForEach($viewModel.curation.shortcuts, id: \.self) { shortcut in + ForEach(viewModel.curation.shortcuts, id: \.self) { shortcutCellModel in - ShortcutCell(shortcutCell: shortcut, + ShortcutCell(shortcutCell: shortcutCellModel, navigationParentView: .curations) - .navigationLinkRouter(data: shortcut) + .navigationLinkRouter(data: viewModel.fetchShortcut(from: shortcutCellModel)) } } diff --git a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift index 49f2bac1..b2c871d0 100644 --- a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift +++ b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift @@ -156,7 +156,7 @@ struct ShowProfileView: View { } VStack(spacing: 0) { - ForEach(curations, id: \.self) { curation in + ForEach(viewModel.curations, id: \.self) { curation in // TODO: navigation parent view 삭제 UserCurationCell(curation: curation, lineLimit: 2, From bf10a440159816a347491f0aefaea15c74fc0022 Mon Sep 17 00:00:00 2001 From: jim4020key Date: Sun, 25 Jun 2023 01:40:47 +0900 Subject: [PATCH 30/53] [Chore] #471 - Move ExploreShortcutView to the right folder --- .../HappyAnding.xcodeproj/project.pbxproj | 8 +- .../ExploreShortcutView.swift | 195 +++++++++++++++- .../ExploreShortcutView.swift | 208 ------------------ 3 files changed, 188 insertions(+), 223 deletions(-) delete mode 100644 HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView/ExploreShortcutView.swift diff --git a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj index a2ec4dac..3cf164bb 100644 --- a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj +++ b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 4D061BB82A47531800F76835 /* ExploreShortcutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D061BB72A47531800F76835 /* ExploreShortcutView.swift */; }; 4D3DBB88292E67E600DE8160 /* EditNicknameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D3DBB87292E67E500DE8160 /* EditNicknameView.swift */; }; 4D3DBB962934E31A00DE8160 /* ShowProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D3DBB952934E31A00DE8160 /* ShowProfileView.swift */; }; 4D61A767291E1EE8000EF531 /* NavigationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D61A766291E1EE8000EF531 /* NavigationViewModel.swift */; }; @@ -55,7 +56,6 @@ 87E99CA128FFF225009B691F /* MyPageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87E99CA028FFF225009B691F /* MyPageView.swift */; }; 87E99CA328FFF22E009B691F /* ExploreCurationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87E99CA228FFF22E009B691F /* ExploreCurationView.swift */; }; 87E99CA728FFF23E009B691F /* ListCurationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87E99CA628FFF23E009B691F /* ListCurationView.swift */; }; - 87E99CA928FFF24F009B691F /* ExploreShortcutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87E99CA828FFF24F009B691F /* ExploreShortcutView.swift */; }; 87E99CAD28FFF261009B691F /* ReadShortcutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87E99CAC28FFF261009B691F /* ReadShortcutView.swift */; }; 87E99CB128FFF273009B691F /* WriteCurationSetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87E99CB028FFF273009B691F /* WriteCurationSetView.swift */; }; 87E99CB528FFF282009B691F /* WriteCurationInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87E99CB428FFF282009B691F /* WriteCurationInfoView.swift */; }; @@ -186,6 +186,7 @@ /* Begin PBXFileReference section */ 3D41EE06290A458B008BE986 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 3D41EE07290A4C18008BE986 /* Launch Screen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = ""; }; + 4D061BB72A47531800F76835 /* ExploreShortcutView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExploreShortcutView.swift; sourceTree = ""; }; 4D3DBB87292E67E500DE8160 /* EditNicknameView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditNicknameView.swift; sourceTree = ""; }; 4D3DBB952934E31A00DE8160 /* ShowProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowProfileView.swift; sourceTree = ""; }; 4D61A766291E1EE8000EF531 /* NavigationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationViewModel.swift; sourceTree = ""; }; @@ -233,7 +234,6 @@ 87E99CA028FFF225009B691F /* MyPageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyPageView.swift; sourceTree = ""; }; 87E99CA228FFF22E009B691F /* ExploreCurationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExploreCurationView.swift; sourceTree = ""; }; 87E99CA628FFF23E009B691F /* ListCurationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListCurationView.swift; sourceTree = ""; }; - 87E99CA828FFF24F009B691F /* ExploreShortcutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ExploreShortcutView.swift; path = ExploreShortcutView/ExploreShortcutView.swift; sourceTree = ""; }; 87E99CAC28FFF261009B691F /* ReadShortcutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadShortcutView.swift; sourceTree = ""; }; 87E99CB028FFF273009B691F /* WriteCurationSetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WriteCurationSetView.swift; sourceTree = ""; }; 87E99CB428FFF282009B691F /* WriteCurationInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WriteCurationInfoView.swift; sourceTree = ""; }; @@ -540,7 +540,7 @@ 87E99C9B28FFF1F4009B691F /* ExploreShortcutViews */ = { isa = PBXGroup; children = ( - 87E99CA828FFF24F009B691F /* ExploreShortcutView.swift */, + 4D061BB72A47531800F76835 /* ExploreShortcutView.swift */, 87E99CC8290145B8009B691F /* ListShortcutView.swift */, A0F822B629164D2300AF4448 /* ListCategoryShortcutView.swift */, ); @@ -945,7 +945,6 @@ 4DAD635E292AB61700ABF8C1 /* UpdateShortcutView.swift in Sources */, 87E99C9F28FFF21B009B691F /* SettingView.swift in Sources */, A34BF82829AF3D55009BC946 /* AnnouncementCell.swift in Sources */, - 87E99CA928FFF24F009B691F /* ExploreShortcutView.swift in Sources */, A04ACB082903DECC004A85A6 /* MyShortcutCardListView.swift in Sources */, 8786B2EC29A7FAD2000B46A1 /* UIColor+Extension.swift in Sources */, 87E99CA128FFF225009B691F /* MyPageView.swift in Sources */, @@ -960,6 +959,7 @@ A33F74AE2908D8C800B8D0D0 /* CheckBoxShortcutCell.swift in Sources */, 87E606B22910649B00C3DA13 /* SignInWithAppleView.swift in Sources */, F91F09DF29AE0B5E00E04FA0 /* GradeAlertView.swift in Sources */, + 4D061BB82A47531800F76835 /* ExploreShortcutView.swift in Sources */, 87E99CEC29080C30009B691F /* Curation.swift in Sources */, 8788E19D2A475AB3007C3852 /* ListCurationViewModel.swift in Sources */, F9136EB6293612310034AAB2 /* ShortcutsZipView.swift in Sources */, diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift index 8a2fe41b..a5ff6dde 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift @@ -9,27 +9,200 @@ import SwiftUI struct ExploreShortcutView: View { - let firebase = FirebaseService() - @State var shortcutsArray: [Shortcuts] = [] + @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel + + // TODO: 추후 UpdateInfoView 제작 시 true로 변경해서 cell 보이게 하기 + @AppStorage("isUpdateAnnnouncementShow") var isUpdateAnnnouncementShow: Bool = false + + @Binding var isCategoryCellViewFolded: Bool + + @State var isTappedAnnouncementCell = false + @State private var numberOfDisplayedCategories = 6 + + let randomCategories: [Category] var body: some View { - Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) - .onAppear { - firebase.fetchShortcut(model: "Shortcut") { shortcuts in - shortcutsArray = shortcuts + ScrollView { + VStack(spacing: 32) { + if isUpdateAnnnouncementShow { + Button { + isTappedAnnouncementCell = true + } label: { + AnnouncementCell(icon: "updateAppIcon", + tagName: TextLiteral.updateTag, + discription: TextLiteral.updateCellDescription, + isAnnouncementShow: $isUpdateAnnnouncementShow) + } + .id(000) } + + sectionView(with: .recent) + .id(111) + + categoryCardView(with: randomCategories[0]) + + sectionView(with: .download) + + categoryCardView(with: randomCategories[1]) + + sectionView(with: .popular) + + VStack { + HStack { + SubtitleTextView(text: TextLiteral.categoryViewTitle) + + Spacer() + + Button(action: { + self.isCategoryCellViewFolded.toggle() + }, label: { + MoreCaptionTextView(text: isCategoryCellViewFolded ? TextLiteral.categoryViewUnfold : TextLiteral.categoryViewFold) + }) + .onChange(of: isCategoryCellViewFolded) { _ in + numberOfDisplayedCategories = isCategoryCellViewFolded ? 6 : 12 + } + } + .padding(.horizontal, 16) + + LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())]) { + ForEach(Array(Category.allCases.enumerated()), id: \.offset) { index, value in + + let data = NavigationListCategoryShortcutType(shortcuts: [], + categoryName: value, + navigationParentView: .shortcuts) + + if index < numberOfDisplayedCategories { + + categoryCellView(with: value.translateName()) + .navigationLinkRouter(data: data) + + } + } + } + .padding(.horizontal, 16) + .padding(.bottom, 16) + .id(999) + } + } + .padding(.top, 20) + .padding(.bottom, 44) + } + .scrollIndicators(.hidden) + .navigationBarTitle(TextLiteral.exploreShortcutViewTitle) + .navigationBarTitleDisplayMode(.large) + .background(Color.shortcutsZipBackground) + .toolbar { + ToolbarItem { + Image(systemName: "magnifyingglass") + .shortcutsZipHeadline() + .foregroundColor(.gray5) + .navigationLinkRouter(data: NavigationSearch.first) } - .onTapGesture { - firebase.fetchCategoryLikedList(category: "education") { shortcuts in - shortcutsArray = shortcuts - print(shortcutsArray) + } + .navigationBarBackground ({ Color.shortcutsZipBackground }) + .sheet(isPresented: $isTappedAnnouncementCell) { + UpdateInfoView() + .presentationDetents([.large]) + .presentationDragIndicator(.visible) + } + } + +} + +// MARK: ViewBuilder +extension ExploreShortcutView { + + @ViewBuilder + private func sectionView(with sectionType: SectionType) -> some View { + + let shortcuts = sectionType.filterShortcuts(from: shortcutsZipViewModel) + + VStack(spacing: 0) { + HStack { + SubtitleTextView(text: sectionType.title) + + Spacer() + + MoreCaptionTextView(text: TextLiteral.more) + .navigationLinkRouter(data: NavigationListShortcutType(sectionType: sectionType, + shortcuts: shortcuts, + navigationParentView: .shortcuts)) + } + .padding(.horizontal, 16) + .padding(.bottom, 12) + + ForEach(Array(shortcuts.enumerated()), id:\.offset) { index, shortcut in + if index < 3 { + let data = NavigationReadShortcutType(shortcutID:shortcut.id, + navigationParentView: .shortcuts) + + ShortcutCell(shortcut: shortcut, + rankNumber: index + 1, + navigationParentView: .shortcuts) + .navigationLinkRouter(data: data) } } + .background(Color.shortcutsZipBackground) + } + } + + @ViewBuilder + private func categoryCardView(with category: Category) -> some View { + + VStack(spacing: 0) { + HStack { + + SubtitleTextView(text: category.translateName()) + + Spacer() + + MoreCaptionTextView(text: TextLiteral.more) + .navigationLinkRouter(data: NavigationListCategoryShortcutType(shortcuts: [], + categoryName: category, + navigationParentView: .shortcuts)) + } + .padding(.horizontal, 16) + .padding(.bottom, 12) + + ScrollView(.horizontal, showsIndicators: false) { + HStack { + ForEach(Array((shortcutsZipViewModel.shortcutsInCategory[randomCategories[0].index].enumerated())), id: \.offset) { index, shortcut in + if index < 7 { + let data = NavigationReadShortcutType( + shortcutID: shortcut.id, + navigationParentView: .shortcuts) + + ShortcutCardCell( + categoryShortcutIcon: shortcut.sfSymbol, + categoryShortcutName: shortcut.title, + categoryShortcutColor: shortcut.color) + .navigationLinkRouter(data: data) + } + } + } + .padding(.horizontal, 16) + } + } + } + + @ViewBuilder + private func categoryCellView(with categoryName: String) -> some View { + RoundedRectangle(cornerSize: CGSize(width: 12, height: 12)) + .strokeBorder(Color.gray1, lineWidth: 1) + .background(Color.shortcutsZipWhite) + .cornerRadius(12) + .frame(maxWidth: .infinity, minHeight:48, maxHeight: 48) + .overlay { + Text(categoryName) + .shortcutsZipBody2() + .foregroundColor(Color.gray5) + } } } struct ExploreShortcutView_Previews: PreviewProvider { static var previews: some View { - ExploreShortcutView() + ExploreShortcutView(isCategoryCellViewFolded: .constant(true), randomCategories: [Category.lifestyle, Category.utility]) } } + diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView/ExploreShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView/ExploreShortcutView.swift deleted file mode 100644 index a5ff6dde..00000000 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView/ExploreShortcutView.swift +++ /dev/null @@ -1,208 +0,0 @@ -// -// ExploreShortcutView.swift -// HappyAnding -// -// Created by 이지원 on 2022/10/19. -// - -import SwiftUI - -struct ExploreShortcutView: View { - - @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel - - // TODO: 추후 UpdateInfoView 제작 시 true로 변경해서 cell 보이게 하기 - @AppStorage("isUpdateAnnnouncementShow") var isUpdateAnnnouncementShow: Bool = false - - @Binding var isCategoryCellViewFolded: Bool - - @State var isTappedAnnouncementCell = false - @State private var numberOfDisplayedCategories = 6 - - let randomCategories: [Category] - - var body: some View { - ScrollView { - VStack(spacing: 32) { - if isUpdateAnnnouncementShow { - Button { - isTappedAnnouncementCell = true - } label: { - AnnouncementCell(icon: "updateAppIcon", - tagName: TextLiteral.updateTag, - discription: TextLiteral.updateCellDescription, - isAnnouncementShow: $isUpdateAnnnouncementShow) - } - .id(000) - } - - sectionView(with: .recent) - .id(111) - - categoryCardView(with: randomCategories[0]) - - sectionView(with: .download) - - categoryCardView(with: randomCategories[1]) - - sectionView(with: .popular) - - VStack { - HStack { - SubtitleTextView(text: TextLiteral.categoryViewTitle) - - Spacer() - - Button(action: { - self.isCategoryCellViewFolded.toggle() - }, label: { - MoreCaptionTextView(text: isCategoryCellViewFolded ? TextLiteral.categoryViewUnfold : TextLiteral.categoryViewFold) - }) - .onChange(of: isCategoryCellViewFolded) { _ in - numberOfDisplayedCategories = isCategoryCellViewFolded ? 6 : 12 - } - } - .padding(.horizontal, 16) - - LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())]) { - ForEach(Array(Category.allCases.enumerated()), id: \.offset) { index, value in - - let data = NavigationListCategoryShortcutType(shortcuts: [], - categoryName: value, - navigationParentView: .shortcuts) - - if index < numberOfDisplayedCategories { - - categoryCellView(with: value.translateName()) - .navigationLinkRouter(data: data) - - } - } - } - .padding(.horizontal, 16) - .padding(.bottom, 16) - .id(999) - } - } - .padding(.top, 20) - .padding(.bottom, 44) - } - .scrollIndicators(.hidden) - .navigationBarTitle(TextLiteral.exploreShortcutViewTitle) - .navigationBarTitleDisplayMode(.large) - .background(Color.shortcutsZipBackground) - .toolbar { - ToolbarItem { - Image(systemName: "magnifyingglass") - .shortcutsZipHeadline() - .foregroundColor(.gray5) - .navigationLinkRouter(data: NavigationSearch.first) - } - } - .navigationBarBackground ({ Color.shortcutsZipBackground }) - .sheet(isPresented: $isTappedAnnouncementCell) { - UpdateInfoView() - .presentationDetents([.large]) - .presentationDragIndicator(.visible) - } - } - -} - -// MARK: ViewBuilder -extension ExploreShortcutView { - - @ViewBuilder - private func sectionView(with sectionType: SectionType) -> some View { - - let shortcuts = sectionType.filterShortcuts(from: shortcutsZipViewModel) - - VStack(spacing: 0) { - HStack { - SubtitleTextView(text: sectionType.title) - - Spacer() - - MoreCaptionTextView(text: TextLiteral.more) - .navigationLinkRouter(data: NavigationListShortcutType(sectionType: sectionType, - shortcuts: shortcuts, - navigationParentView: .shortcuts)) - } - .padding(.horizontal, 16) - .padding(.bottom, 12) - - ForEach(Array(shortcuts.enumerated()), id:\.offset) { index, shortcut in - if index < 3 { - let data = NavigationReadShortcutType(shortcutID:shortcut.id, - navigationParentView: .shortcuts) - - ShortcutCell(shortcut: shortcut, - rankNumber: index + 1, - navigationParentView: .shortcuts) - .navigationLinkRouter(data: data) - } - } - .background(Color.shortcutsZipBackground) - } - } - - @ViewBuilder - private func categoryCardView(with category: Category) -> some View { - - VStack(spacing: 0) { - HStack { - - SubtitleTextView(text: category.translateName()) - - Spacer() - - MoreCaptionTextView(text: TextLiteral.more) - .navigationLinkRouter(data: NavigationListCategoryShortcutType(shortcuts: [], - categoryName: category, - navigationParentView: .shortcuts)) - } - .padding(.horizontal, 16) - .padding(.bottom, 12) - - ScrollView(.horizontal, showsIndicators: false) { - HStack { - ForEach(Array((shortcutsZipViewModel.shortcutsInCategory[randomCategories[0].index].enumerated())), id: \.offset) { index, shortcut in - if index < 7 { - let data = NavigationReadShortcutType( - shortcutID: shortcut.id, - navigationParentView: .shortcuts) - - ShortcutCardCell( - categoryShortcutIcon: shortcut.sfSymbol, - categoryShortcutName: shortcut.title, - categoryShortcutColor: shortcut.color) - .navigationLinkRouter(data: data) - } - } - } - .padding(.horizontal, 16) - } - } - } - - @ViewBuilder - private func categoryCellView(with categoryName: String) -> some View { - RoundedRectangle(cornerSize: CGSize(width: 12, height: 12)) - .strokeBorder(Color.gray1, lineWidth: 1) - .background(Color.shortcutsZipWhite) - .cornerRadius(12) - .frame(maxWidth: .infinity, minHeight:48, maxHeight: 48) - .overlay { - Text(categoryName) - .shortcutsZipBody2() - .foregroundColor(Color.gray5) - } - } -} - -struct ExploreShortcutView_Previews: PreviewProvider { - static var previews: some View { - ExploreShortcutView(isCategoryCellViewFolded: .constant(true), randomCategories: [Category.lifestyle, Category.utility]) - } -} - From f716f83a83214e92dfbeccc9df168bd045bcc6a0 Mon Sep 17 00:00:00 2001 From: jim4020key Date: Fri, 30 Jun 2023 17:40:03 +0900 Subject: [PATCH 31/53] [Feat] #471 - Add ExploreShortcutViewModel --- .../HappyAnding.xcodeproj/project.pbxproj | 4 + .../ViewModel/ExploreShortcutViewModel.swift | 31 ++++ .../ExploreShortcutView.swift | 157 ++++++++---------- .../Views/TabView/ShortcutTabView.swift | 9 +- 4 files changed, 109 insertions(+), 92 deletions(-) create mode 100644 HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModel.swift diff --git a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj index 3cf164bb..ba2c1e4b 100644 --- a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj +++ b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 4D061BB82A47531800F76835 /* ExploreShortcutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D061BB72A47531800F76835 /* ExploreShortcutView.swift */; }; + 4D061BBA2A475EE800F76835 /* ExploreShortcutViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D061BB92A475EE800F76835 /* ExploreShortcutViewModel.swift */; }; 4D3DBB88292E67E600DE8160 /* EditNicknameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D3DBB87292E67E500DE8160 /* EditNicknameView.swift */; }; 4D3DBB962934E31A00DE8160 /* ShowProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D3DBB952934E31A00DE8160 /* ShowProfileView.swift */; }; 4D61A767291E1EE8000EF531 /* NavigationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D61A766291E1EE8000EF531 /* NavigationViewModel.swift */; }; @@ -187,6 +188,7 @@ 3D41EE06290A458B008BE986 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 3D41EE07290A4C18008BE986 /* Launch Screen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = ""; }; 4D061BB72A47531800F76835 /* ExploreShortcutView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExploreShortcutView.swift; sourceTree = ""; }; + 4D061BB92A475EE800F76835 /* ExploreShortcutViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExploreShortcutViewModel.swift; sourceTree = ""; }; 4D3DBB87292E67E500DE8160 /* EditNicknameView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditNicknameView.swift; sourceTree = ""; }; 4D3DBB952934E31A00DE8160 /* ShowProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowProfileView.swift; sourceTree = ""; }; 4D61A766291E1EE8000EF531 /* NavigationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationViewModel.swift; sourceTree = ""; }; @@ -653,6 +655,7 @@ A0F822AB2910B8F100AF4448 /* ShortcutsZipViewModel.swift */, 4D61A766291E1EE8000EF531 /* NavigationViewModel.swift */, F9AC2BB52935201C00165820 /* CheckUpdateVersion.swift */, + 4D061BB92A475EE800F76835 /* ExploreShortcutViewModel.swift */, ); path = ViewModel; sourceTree = ""; @@ -909,6 +912,7 @@ F9131B6B2922D38D00868A0E /* Keyword.swift in Sources */, F94B432E2907088400987819 /* UserCurationListView.swift in Sources */, A3FF0183291648A300384211 /* MailView.swift in Sources */, + 4D061BBA2A475EE800F76835 /* ExploreShortcutViewModel.swift in Sources */, A0F822AC2910B8F100AF4448 /* ShortcutsZipViewModel.swift in Sources */, 87276C382933F6AB00C92F4C /* CustomTextEditor.swift in Sources */, A34BF82D29AFC34F009BC946 /* AboutShortcutGradeView.swift in Sources */, diff --git a/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModel.swift new file mode 100644 index 00000000..8ae69669 --- /dev/null +++ b/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModel.swift @@ -0,0 +1,31 @@ +// +// ExploreShortcutViewModel.swift +// HappyAnding +// +// Created by kimjimin on 2023/06/25. +// + +import SwiftUI + +final class ExploreShortcutViewModel: ObservableObject { + + var shortcutsZipViewModel = ShortcutsZipViewModel.share + + @Published private(set) var isCategoryCellViewFolded = true + @Published var isTappedAnnouncementCell = false + @Published private(set) var numberOfDisplayedCategories = 6 + @Published private(set) var randomCategories = Category.allCases.shuffled().prefix(2) + + func changeNumberOfCategories() { + isCategoryCellViewFolded.toggle() + numberOfDisplayedCategories = isCategoryCellViewFolded ? 6 : 12 + } + + func isShowingAnnouncement() { + isTappedAnnouncementCell = true + } + + func fetchShortcutsByCategories(category: Category) -> [Shortcuts] { + shortcutsZipViewModel.shortcutsInCategory[category.index] + } +} diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift index a5ff6dde..fa2d353b 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift @@ -9,83 +9,80 @@ import SwiftUI struct ExploreShortcutView: View { - @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel + @StateObject var viewModel: ExploreShortcutViewModel // TODO: 추후 UpdateInfoView 제작 시 true로 변경해서 cell 보이게 하기 @AppStorage("isUpdateAnnnouncementShow") var isUpdateAnnnouncementShow: Bool = false - @Binding var isCategoryCellViewFolded: Bool - - @State var isTappedAnnouncementCell = false - @State private var numberOfDisplayedCategories = 6 - - let randomCategories: [Category] - var body: some View { - ScrollView { - VStack(spacing: 32) { - if isUpdateAnnnouncementShow { - Button { - isTappedAnnouncementCell = true - } label: { - AnnouncementCell(icon: "updateAppIcon", - tagName: TextLiteral.updateTag, - discription: TextLiteral.updateCellDescription, - isAnnouncementShow: $isUpdateAnnnouncementShow) - } - .id(000) - } - - sectionView(with: .recent) - .id(111) - - categoryCardView(with: randomCategories[0]) - - sectionView(with: .download) - - categoryCardView(with: randomCategories[1]) - - sectionView(with: .popular) - - VStack { - HStack { - SubtitleTextView(text: TextLiteral.categoryViewTitle) - - Spacer() - - Button(action: { - self.isCategoryCellViewFolded.toggle() - }, label: { - MoreCaptionTextView(text: isCategoryCellViewFolded ? TextLiteral.categoryViewUnfold : TextLiteral.categoryViewFold) - }) - .onChange(of: isCategoryCellViewFolded) { _ in - numberOfDisplayedCategories = isCategoryCellViewFolded ? 6 : 12 + ScrollViewReader { proxy in + ScrollView { + VStack(spacing: 32) { + if isUpdateAnnnouncementShow { + Button { + viewModel.isShowingAnnouncement() + } label: { + AnnouncementCell(icon: "updateAppIcon", + tagName: TextLiteral.updateTag, + discription: TextLiteral.updateCellDescription, + isAnnouncementShow: $isUpdateAnnnouncementShow) } + .id(000) } - .padding(.horizontal, 16) - LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())]) { - ForEach(Array(Category.allCases.enumerated()), id: \.offset) { index, value in + sectionView(with: .recent) + .id(111) + + categoryCardView(with: viewModel.randomCategories[0]) + + sectionView(with: .download) + + categoryCardView(with: viewModel.randomCategories[1]) + + sectionView(with: .popular) + + VStack { + HStack { + SubtitleTextView(text: TextLiteral.categoryViewTitle) - let data = NavigationListCategoryShortcutType(shortcuts: [], - categoryName: value, - navigationParentView: .shortcuts) + Spacer() - if index < numberOfDisplayedCategories { + Button { + viewModel.changeNumberOfCategories() + } label: { + MoreCaptionTextView(text: viewModel.isCategoryCellViewFolded ? TextLiteral.categoryViewUnfold : TextLiteral.categoryViewFold) + } + } + .padding(.horizontal, 16) + + LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())]) { + ForEach(Array(Category.allCases.enumerated()), id: \.offset) { index, value in - categoryCellView(with: value.translateName()) - .navigationLinkRouter(data: data) + let data = NavigationListCategoryShortcutType(shortcuts: [], + categoryName: value, + navigationParentView: .shortcuts) + if index < viewModel.numberOfDisplayedCategories { + + categoryCellView(with: value.translateName()) + .navigationLinkRouter(data: data) + + } } } + .padding(.horizontal, 16) + .padding(.bottom, 16) + .id(999) } - .padding(.horizontal, 16) - .padding(.bottom, 16) - .id(999) + } + .padding(.top, 20) + .padding(.bottom, 44) + } + .onChange(of: viewModel.isCategoryCellViewFolded) { _ in + withAnimation { + proxy.scrollTo(999, anchor: .bottom) } } - .padding(.top, 20) - .padding(.bottom, 44) } .scrollIndicators(.hidden) .navigationBarTitle(TextLiteral.exploreShortcutViewTitle) @@ -100,7 +97,7 @@ struct ExploreShortcutView: View { } } .navigationBarBackground ({ Color.shortcutsZipBackground }) - .sheet(isPresented: $isTappedAnnouncementCell) { + .sheet(isPresented: $viewModel.isTappedAnnouncementCell) { UpdateInfoView() .presentationDetents([.large]) .presentationDragIndicator(.visible) @@ -115,7 +112,7 @@ extension ExploreShortcutView { @ViewBuilder private func sectionView(with sectionType: SectionType) -> some View { - let shortcuts = sectionType.filterShortcuts(from: shortcutsZipViewModel) + let shortcuts = sectionType.filterShortcuts(from: viewModel.shortcutsZipViewModel) VStack(spacing: 0) { HStack { @@ -151,11 +148,11 @@ extension ExploreShortcutView { VStack(spacing: 0) { HStack { - + SubtitleTextView(text: category.translateName()) - + Spacer() - + MoreCaptionTextView(text: TextLiteral.more) .navigationLinkRouter(data: NavigationListCategoryShortcutType(shortcuts: [], categoryName: category, @@ -163,21 +160,19 @@ extension ExploreShortcutView { } .padding(.horizontal, 16) .padding(.bottom, 12) - + ScrollView(.horizontal, showsIndicators: false) { HStack { - ForEach(Array((shortcutsZipViewModel.shortcutsInCategory[randomCategories[0].index].enumerated())), id: \.offset) { index, shortcut in - if index < 7 { - let data = NavigationReadShortcutType( - shortcutID: shortcut.id, - navigationParentView: .shortcuts) - - ShortcutCardCell( - categoryShortcutIcon: shortcut.sfSymbol, - categoryShortcutName: shortcut.title, - categoryShortcutColor: shortcut.color) - .navigationLinkRouter(data: data) - } + ForEach(viewModel.fetchShortcutsByCategories(category: category).prefix(7), id: \.self) { shortcut in + let data = NavigationReadShortcutType( + shortcutID: shortcut.id, + navigationParentView: .shortcuts) + + ShortcutCardCell( + categoryShortcutIcon: shortcut.sfSymbol, + categoryShortcutName: shortcut.title, + categoryShortcutColor: shortcut.color) + .navigationLinkRouter(data: data) } } .padding(.horizontal, 16) @@ -200,9 +195,3 @@ extension ExploreShortcutView { } } -struct ExploreShortcutView_Previews: PreviewProvider { - static var previews: some View { - ExploreShortcutView(isCategoryCellViewFolded: .constant(true), randomCategories: [Category.lifestyle, Category.utility]) - } -} - diff --git a/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift b/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift index db91ece5..4b17c112 100644 --- a/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift +++ b/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift @@ -27,8 +27,6 @@ struct ShortcutTabView: View { @State private var tempShortcutId = "" @State private var tempCurationId = "" - @State private var randomCategories = Category.allCases.shuffled().prefix(2) - @State var isFolded = true @State private var twiceTappedTab = 0 @State private var firstTabID = UUID() @@ -72,11 +70,6 @@ struct ShortcutTabView: View { } self.twiceTappedTab = 0 } - .onChange(of: isFolded) { _ in - withAnimation { - proxy.scrollTo(999, anchor: .bottom) - } - } .environmentObject(shortcutNavigation) .tabItem { Label("단축어", systemImage: "square.stack.3d.up.fill") @@ -113,7 +106,7 @@ struct ShortcutTabView: View { @ViewBuilder private func firstTab() -> some View { - ExploreShortcutView(isCategoryCellViewFolded: $isFolded, randomCategories: Array(randomCategories)) + ExploreShortcutView(viewModel: ExploreShortcutViewModel()) .modifierNavigation() .navigationBarBackground ({ Color.shortcutsZipBackground }) .id(firstTabID) From 2a5c32a995ffa9b5cf9e03e29a4bf9b61debc9f3 Mon Sep 17 00:00:00 2001 From: jim4020key Date: Fri, 30 Jun 2023 17:46:15 +0900 Subject: [PATCH 32/53] [Feat] #471 - Add ListShortcutViewModel --- .../HappyAnding.xcodeproj/project.pbxproj | 4 + .../Extensions/View/View+Navigation.swift | 4 +- .../ViewModel/ListShortcutViewModel.swift | 33 ++++++++ .../ListShortcutView.swift | 83 ++++++++----------- 4 files changed, 72 insertions(+), 52 deletions(-) create mode 100644 HappyAnding/HappyAnding/ViewModel/ListShortcutViewModel.swift diff --git a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj index ba2c1e4b..9c23fb66 100644 --- a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj +++ b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj @@ -18,6 +18,7 @@ 4D7D16072986BBD7008B3332 /* TextLiteral.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D7D16062986BBD7008B3332 /* TextLiteral.swift */; }; 4D7D16082986BBDE008B3332 /* TextLiteral.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D7D16062986BBD7008B3332 /* TextLiteral.swift */; }; 4DAD635E292AB61700ABF8C1 /* UpdateShortcutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DAD635D292AB61700ABF8C1 /* UpdateShortcutView.swift */; }; + 4DF15D732A4ECC7D0014F854 /* ListShortcutViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DF15D722A4ECC7D0014F854 /* ListShortcutViewModel.swift */; }; 4DF62DD52A0550ED00A8B377 /* UIScreen+Size.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8795A16F292AB945004B765F /* UIScreen+Size.swift */; }; 87276C382933F6AB00C92F4C /* CustomTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87276C372933F6AB00C92F4C /* CustomTextEditor.swift */; }; 872A7D8F2918393B004A05B8 /* PrivacyPolicyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 872A7D8E2918393B004A05B8 /* PrivacyPolicyView.swift */; }; @@ -196,6 +197,7 @@ 4D778A33290A53BA00C15AC4 /* UIApplication+Keyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIApplication+Keyboard.swift"; sourceTree = ""; }; 4D7D16062986BBD7008B3332 /* TextLiteral.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TextLiteral.swift; path = HappyAnding/TextLiteral.swift; sourceTree = SOURCE_ROOT; }; 4DAD635D292AB61700ABF8C1 /* UpdateShortcutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateShortcutView.swift; sourceTree = ""; }; + 4DF15D722A4ECC7D0014F854 /* ListShortcutViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListShortcutViewModel.swift; sourceTree = ""; }; 87276C372933F6AB00C92F4C /* CustomTextEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTextEditor.swift; sourceTree = ""; }; 872A7D8E2918393B004A05B8 /* PrivacyPolicyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyPolicyView.swift; sourceTree = ""; }; 872B5D3C2A2E0FF9008DCC57 /* CurationType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurationType.swift; sourceTree = ""; }; @@ -656,6 +658,7 @@ 4D61A766291E1EE8000EF531 /* NavigationViewModel.swift */, F9AC2BB52935201C00165820 /* CheckUpdateVersion.swift */, 4D061BB92A475EE800F76835 /* ExploreShortcutViewModel.swift */, + 4DF15D722A4ECC7D0014F854 /* ListShortcutViewModel.swift */, ); path = ViewModel; sourceTree = ""; @@ -926,6 +929,7 @@ A38115BA292B447D0043E8B8 /* ShortcutCardCell.swift in Sources */, 8792479B291BDF820040D5C3 /* SearchView.swift in Sources */, A3FF018E291ACFA500384211 /* WithdrawalView.swift in Sources */, + 4DF15D732A4ECC7D0014F854 /* ListShortcutViewModel.swift in Sources */, 4D778A34290A53BA00C15AC4 /* UIApplication+Keyboard.swift in Sources */, A3766B232904330300708F83 /* ReadCurationView.swift in Sources */, 87E606B0291062F900C3DA13 /* AppleAuthCoordinator.swift in Sources */, diff --git a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift index d3722e17..dc604c1e 100644 --- a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift +++ b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift @@ -78,7 +78,7 @@ extension View { func getDestination(data: T) -> some View { switch data { case is NavigationListShortcutType: - ListShortcutView(data: data as! NavigationListShortcutType) + ListShortcutView(viewModel: ListShortcutViewModel(data: data as! NavigationListShortcutType)) case is NavigationReadShortcutType: ReadShortcutView(data: data as! NavigationReadShortcutType) case is Curation: @@ -128,7 +128,7 @@ struct NavigationViewModifier: ViewModifier { ReadShortcutView(data: data) } .navigationDestination(for: NavigationListShortcutType.self) { data in - ListShortcutView(data: data) + ListShortcutView(viewModel: ListShortcutViewModel(data: data)) } .navigationDestination(for: NavigationListCategoryShortcutType.self) { data in ListCategoryShortcutView(data: data) diff --git a/HappyAnding/HappyAnding/ViewModel/ListShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ListShortcutViewModel.swift new file mode 100644 index 00000000..b02c3216 --- /dev/null +++ b/HappyAnding/HappyAnding/ViewModel/ListShortcutViewModel.swift @@ -0,0 +1,33 @@ +// +// ListShortcutViewModel.swift +// HappyAnding +// +// Created by kimjimin on 2023/06/30. +// + +import SwiftUI + +final class ListShortcutViewModel: ObservableObject { + + var shortcutsZipViewModel = ShortcutsZipViewModel.share + + @Published private(set) var shortcuts: [Shortcuts] = [] + @Published private(set) var sectionType: SectionType = .download + + + init(data: NavigationListShortcutType) { + shortcuts = data.shortcuts ?? [] + sectionType = data.sectionType + } + + func fetchShortcutsBySectionType() -> [Shortcuts] { + switch self.sectionType { + case .recent: return shortcutsZipViewModel.allShortcuts + case .download: return shortcutsZipViewModel.sortedShortcutsByDownload + case .popular: return shortcutsZipViewModel.sortedShortcutsByLike + case .myDownloadShortcut: return shortcutsZipViewModel.shortcutsUserDownloaded + case .myLovingShortcut: return shortcutsZipViewModel.shortcutsUserLiked + case .myShortcut: return shortcutsZipViewModel.shortcutsMadeByUser + } + } +} diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift index 5d21a150..f3c6bc8d 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift @@ -11,56 +11,39 @@ import SwiftUI /// sectionType: 다운로드 순위에서 접근할 시, .download를, 사랑받는 앱에서 접근시 .popular를 넣어주세요. struct ListShortcutView: View { - @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel - - @State var data: NavigationListShortcutType - @State private var isLastItem = false + @StateObject var viewModel: ListShortcutViewModel var body: some View { - if let shortcuts = data.shortcuts { - if shortcuts.count == 0 { - Text("아직 \(data.sectionType.title)가 없어요") - .shortcutsZipBody2() - .foregroundColor(Color.gray4) - .frame(maxWidth: .infinity, maxHeight: .infinity) - - .background(Color.shortcutsZipBackground.ignoresSafeArea(.all, edges: .all)) - .navigationTitle(data.sectionType.title) - .navigationBarTitleDisplayMode(.inline) - } else { - ScrollView { - LazyVStack(spacing: 0) { - - //TODO: 무한 스크롤을 위한 업데이트 함수 필요 - switch data.sectionType { - case .recent: - makeShortcutCellList(shortcutsZipViewModel.allShortcuts) - case .download: - makeIndexShortcutCellList(shortcutsZipViewModel.sortedShortcutsByDownload) - case .popular: - makeShortcutCellList(shortcutsZipViewModel.sortedShortcutsByLike) - case .myDownloadShortcut: - makeShortcutCellList(shortcutsZipViewModel.shortcutsUserDownloaded) - case .myLovingShortcut: - makeShortcutCellList(shortcutsZipViewModel.shortcutsUserLiked) - case .myShortcut: - makeShortcutCellList(shortcutsZipViewModel.shortcutsMadeByUser) - } - Rectangle() - .fill(Color.shortcutsZipBackground) - .frame(height: 44) - .listRowInsets(EdgeInsets()) - .listRowSeparator(.hidden) - } - } - .listRowBackground(Color.shortcutsZipBackground) - .listStyle(.plain) + if viewModel.shortcuts.count == 0 { + Text("아직 \(viewModel.sectionType.title)가 없어요") + .shortcutsZipBody2() + .foregroundColor(Color.gray4) + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color.shortcutsZipBackground.ignoresSafeArea(.all, edges: .all)) - .scrollContentBackground(.hidden) - .navigationTitle(data.sectionType.title) + .navigationTitle(viewModel.sectionType.title) .navigationBarTitleDisplayMode(.inline) - .navigationBarBackground ({ Color.shortcutsZipBackground }) + } else { + ScrollView { + LazyVStack(spacing: 0) { + + //TODO: 무한 스크롤을 위한 업데이트 함수 필요 + makeShortcutCellList(viewModel.fetchShortcutsBySectionType()) + + Rectangle() + .fill(Color.shortcutsZipBackground) + .frame(height: 44) + .listRowInsets(EdgeInsets()) + .listRowSeparator(.hidden) + } } + .listRowBackground(Color.shortcutsZipBackground) + .listStyle(.plain) + .background(Color.shortcutsZipBackground.ignoresSafeArea(.all, edges: .all)) + .scrollContentBackground(.hidden) + .navigationTitle(viewModel.sectionType.title) + .navigationBarTitleDisplayMode(.inline) + .navigationBarBackground ({ Color.shortcutsZipBackground }) } } @@ -69,10 +52,10 @@ struct ListShortcutView: View { ForEach(shortcuts, id: \.self) { shortcut in let navigationData = NavigationReadShortcutType(shortcut: shortcut, shortcutID: shortcut.id, - navigationParentView: self.data.navigationParentView) + navigationParentView: .shortcuts) ShortcutCell(shortcut: shortcut, - sectionType: data.sectionType, - navigationParentView: data.navigationParentView) + sectionType: viewModel.sectionType, + navigationParentView: .shortcuts) .navigationLinkRouter(data: navigationData) } @@ -83,10 +66,10 @@ struct ListShortcutView: View { ForEach(Array(shortcuts.enumerated()), id: \.offset) { index, shortcut in let navigationData = NavigationReadShortcutType(shortcut: shortcut, shortcutID: shortcut.id, - navigationParentView: self.data.navigationParentView) + navigationParentView: .shortcuts) ShortcutCell(shortcut: shortcut, rankNumber: index + 1, - navigationParentView: data.navigationParentView) + navigationParentView: .shortcuts) .navigationLinkRouter(data: navigationData) .listRowInsets(EdgeInsets()) .listRowSeparator(.hidden) From d7a5c37c41629fc643979282f9f082d5ed81f0b6 Mon Sep 17 00:00:00 2001 From: jim4020key Date: Fri, 30 Jun 2023 18:35:13 +0900 Subject: [PATCH 33/53] [Feat] #471 - Add ListCategoryShortcutViewModel --- .../HappyAnding.xcodeproj/project.pbxproj | 4 ++++ .../Extensions/View/View+Navigation.swift | 4 ++-- .../ListCategoryShortcutViewModel.swift | 22 +++++++++++++++++++ .../ListCategoryShortcutView.swift | 21 ++++++------------ 4 files changed, 35 insertions(+), 16 deletions(-) create mode 100644 HappyAnding/HappyAnding/ViewModel/ListCategoryShortcutViewModel.swift diff --git a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj index 9c23fb66..b26ee96a 100644 --- a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj +++ b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj @@ -19,6 +19,7 @@ 4D7D16082986BBDE008B3332 /* TextLiteral.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D7D16062986BBD7008B3332 /* TextLiteral.swift */; }; 4DAD635E292AB61700ABF8C1 /* UpdateShortcutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DAD635D292AB61700ABF8C1 /* UpdateShortcutView.swift */; }; 4DF15D732A4ECC7D0014F854 /* ListShortcutViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DF15D722A4ECC7D0014F854 /* ListShortcutViewModel.swift */; }; + 4DF15D752A4ECE1F0014F854 /* ListCategoryShortcutViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DF15D742A4ECE1F0014F854 /* ListCategoryShortcutViewModel.swift */; }; 4DF62DD52A0550ED00A8B377 /* UIScreen+Size.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8795A16F292AB945004B765F /* UIScreen+Size.swift */; }; 87276C382933F6AB00C92F4C /* CustomTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87276C372933F6AB00C92F4C /* CustomTextEditor.swift */; }; 872A7D8F2918393B004A05B8 /* PrivacyPolicyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 872A7D8E2918393B004A05B8 /* PrivacyPolicyView.swift */; }; @@ -198,6 +199,7 @@ 4D7D16062986BBD7008B3332 /* TextLiteral.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TextLiteral.swift; path = HappyAnding/TextLiteral.swift; sourceTree = SOURCE_ROOT; }; 4DAD635D292AB61700ABF8C1 /* UpdateShortcutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateShortcutView.swift; sourceTree = ""; }; 4DF15D722A4ECC7D0014F854 /* ListShortcutViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListShortcutViewModel.swift; sourceTree = ""; }; + 4DF15D742A4ECE1F0014F854 /* ListCategoryShortcutViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListCategoryShortcutViewModel.swift; sourceTree = ""; }; 87276C372933F6AB00C92F4C /* CustomTextEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTextEditor.swift; sourceTree = ""; }; 872A7D8E2918393B004A05B8 /* PrivacyPolicyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyPolicyView.swift; sourceTree = ""; }; 872B5D3C2A2E0FF9008DCC57 /* CurationType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurationType.swift; sourceTree = ""; }; @@ -659,6 +661,7 @@ F9AC2BB52935201C00165820 /* CheckUpdateVersion.swift */, 4D061BB92A475EE800F76835 /* ExploreShortcutViewModel.swift */, 4DF15D722A4ECC7D0014F854 /* ListShortcutViewModel.swift */, + 4DF15D742A4ECE1F0014F854 /* ListCategoryShortcutViewModel.swift */, ); path = ViewModel; sourceTree = ""; @@ -937,6 +940,7 @@ 8795A170292AB945004B765F /* UIScreen+Size.swift in Sources */, 8786B2E629A7F987000B46A1 /* String+Date.swift in Sources */, F96D45B72980301F000C2441 /* SubtitleTextView.swift in Sources */, + 4DF15D752A4ECE1F0014F854 /* ListCategoryShortcutViewModel.swift in Sources */, 87E99CDB29042CCA009B691F /* Category.swift in Sources */, 876B4F6F299E3D91009672D9 /* NavigationRouter.swift in Sources */, A04ACB062903D0B2004A85A6 /* MyShortcutCardView.swift in Sources */, diff --git a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift index dc604c1e..7657eb24 100644 --- a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift +++ b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift @@ -90,7 +90,7 @@ extension View { case is NavigationSearch: SearchView() case is NavigationListCategoryShortcutType: - ListCategoryShortcutView(data: data as! NavigationListCategoryShortcutType) + ListCategoryShortcutView(viewModel: ListCategoryShortcutViewModel(data: data as! NavigationListCategoryShortcutType)) case is NavigationNicknameView: EditNicknameView() case is NavigationSettingView: @@ -131,7 +131,7 @@ struct NavigationViewModifier: ViewModifier { ListShortcutView(viewModel: ListShortcutViewModel(data: data)) } .navigationDestination(for: NavigationListCategoryShortcutType.self) { data in - ListCategoryShortcutView(data: data) + ListCategoryShortcutView(viewModel: ListCategoryShortcutViewModel(data: data)) } .navigationDestination(for: NavigationLisence.self) { value in LicenseView() diff --git a/HappyAnding/HappyAnding/ViewModel/ListCategoryShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ListCategoryShortcutViewModel.swift new file mode 100644 index 00000000..c111e5b8 --- /dev/null +++ b/HappyAnding/HappyAnding/ViewModel/ListCategoryShortcutViewModel.swift @@ -0,0 +1,22 @@ +// +// ListCategoryShortcutViewModel.swift +// HappyAnding +// +// Created by kimjimin on 2023/06/30. +// + +import SwiftUI + +final class ListCategoryShortcutViewModel: ObservableObject { + + var shortcutsZipViewModel = ShortcutsZipViewModel.share + + @Published private(set) var shortcuts: [Shortcuts] = [] + @Published private(set) var categoryName: Category = .business + + init(data: NavigationListCategoryShortcutType) { + shortcuts = shortcutsZipViewModel.shortcutsInCategory[data.categoryName.index] + categoryName = data.categoryName + } + +} diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift index 2cb26e76..2d749b88 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift @@ -1,5 +1,5 @@ // -// ShortcutsListView.swift +// ListCategoryShortcutView.swift // HappyAnding // // Created by KiWoong Hong on 2022/11/05. @@ -9,11 +9,7 @@ import SwiftUI struct ListCategoryShortcutView: View { - @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel - - @State var navigationTitle = "" - @State var isLastShortcut: Bool = false - @State var data: NavigationListCategoryShortcutType + @StateObject var viewModel: ListCategoryShortcutViewModel var body: some View { ScrollView { @@ -21,12 +17,12 @@ struct ListCategoryShortcutView: View { scrollHeader LazyVStack(spacing: 0) { - ForEach(data.shortcuts, id: \.self) { shortcut in + ForEach(viewModel.shortcuts, id: \.self) { shortcut in let data = NavigationReadShortcutType(shortcut: shortcut, shortcutID: shortcut.id, - navigationParentView: self.data.navigationParentView) + navigationParentView: .shortcuts) ShortcutCell(shortcut: shortcut, - navigationParentView: self.data.navigationParentView) + navigationParentView: .shortcuts) .navigationLinkRouter(data: data) .listRowInsets(EdgeInsets()) .listRowSeparator(.hidden) @@ -34,18 +30,15 @@ struct ListCategoryShortcutView: View { } .padding(.bottom, 44) } - .navigationBarTitle(data.categoryName.translateName()) + .navigationBarTitle(viewModel.categoryName.translateName()) .navigationBarTitleDisplayMode(.inline) .background(Color.shortcutsZipBackground) .navigationBarBackground ({ Color.shortcutsZipBackground }) - .onAppear { - self.data.shortcuts = shortcutsZipViewModel.shortcutsInCategory[data.categoryName.index] - } } var scrollHeader: some View { VStack { - Text(data.categoryName.fetchDescription().lineBreaking) + Text(viewModel.categoryName.fetchDescription().lineBreaking) } .foregroundColor(.gray5) .shortcutsZipBody2() From b4317c4b800261f6a25bcb6cd6908d60a8d00d9d Mon Sep 17 00:00:00 2001 From: jim4020key Date: Fri, 30 Jun 2023 19:03:30 +0900 Subject: [PATCH 34/53] [Feat] #471 - Remove NavigationListShortcutType --- .../HappyAnding/Extensions/View/View+Navigation.swift | 6 +++--- HappyAnding/HappyAnding/Model/NavigationStackModel.swift | 8 -------- .../HappyAnding/ViewModel/ListShortcutViewModel.swift | 6 +++--- .../Views/Components/MyShortcutCardListView.swift | 7 +------ .../Views/ExploreShortcutViews/ExploreShortcutView.swift | 4 +--- .../Views/ExploreShortcutViews/ListShortcutView.swift | 2 +- .../HappyAnding/Views/MyPageViews/MyPageView.swift | 7 +------ 7 files changed, 10 insertions(+), 30 deletions(-) diff --git a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift index 7657eb24..92c0798d 100644 --- a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift +++ b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift @@ -77,8 +77,8 @@ extension View { @ViewBuilder func getDestination(data: T) -> some View { switch data { - case is NavigationListShortcutType: - ListShortcutView(viewModel: ListShortcutViewModel(data: data as! NavigationListShortcutType)) + case is SectionType: + ListShortcutView(viewModel: ListShortcutViewModel(data: data as! SectionType)) case is NavigationReadShortcutType: ReadShortcutView(data: data as! NavigationReadShortcutType) case is Curation: @@ -127,7 +127,7 @@ struct NavigationViewModifier: ViewModifier { .navigationDestination(for: NavigationReadShortcutType.self) { data in ReadShortcutView(data: data) } - .navigationDestination(for: NavigationListShortcutType.self) { data in + .navigationDestination(for: SectionType.self) { data in ListShortcutView(viewModel: ListShortcutViewModel(data: data)) } .navigationDestination(for: NavigationListCategoryShortcutType.self) { data in diff --git a/HappyAnding/HappyAnding/Model/NavigationStackModel.swift b/HappyAnding/HappyAnding/Model/NavigationStackModel.swift index 5760ec24..dc562151 100644 --- a/HappyAnding/HappyAnding/Model/NavigationStackModel.swift +++ b/HappyAnding/HappyAnding/Model/NavigationStackModel.swift @@ -7,14 +7,6 @@ import SwiftUI -struct NavigationListShortcutType: Identifiable, Hashable { - var id = UUID().uuidString - - var sectionType: SectionType - var shortcuts: [Shortcuts]? - let navigationParentView: NavigationParentView -} - struct NavigationReadShortcutType: Identifiable, Hashable { var id = UUID().uuidString diff --git a/HappyAnding/HappyAnding/ViewModel/ListShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ListShortcutViewModel.swift index b02c3216..77fcf0c3 100644 --- a/HappyAnding/HappyAnding/ViewModel/ListShortcutViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ListShortcutViewModel.swift @@ -15,9 +15,9 @@ final class ListShortcutViewModel: ObservableObject { @Published private(set) var sectionType: SectionType = .download - init(data: NavigationListShortcutType) { - shortcuts = data.shortcuts ?? [] - sectionType = data.sectionType + init(data: SectionType) { + sectionType = data + shortcuts = fetchShortcutsBySectionType() } func fetchShortcutsBySectionType() -> [Shortcuts] { diff --git a/HappyAnding/HappyAnding/Views/Components/MyShortcutCardListView.swift b/HappyAnding/HappyAnding/Views/Components/MyShortcutCardListView.swift index 70d5634b..f480d218 100644 --- a/HappyAnding/HappyAnding/Views/Components/MyShortcutCardListView.swift +++ b/HappyAnding/HappyAnding/Views/Components/MyShortcutCardListView.swift @@ -21,11 +21,6 @@ struct MyShortcutCardListView: View { @State var isGradeAlertPresented = false var shortcuts: [Shortcuts]? - var data: NavigationListShortcutType { - NavigationListShortcutType(sectionType: .myShortcut, - shortcuts: self.shortcuts, - navigationParentView: self.navigationParentView) - } let navigationParentView: NavigationParentView @@ -37,7 +32,7 @@ struct MyShortcutCardListView: View { Spacer() MoreCaptionTextView(text: TextLiteral.more) - .navigationLinkRouter(data: data) + .navigationLinkRouter(data: SectionType.myShortcut) } .padding(.horizontal, 16) diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift index fa2d353b..8c9a66d0 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift @@ -121,9 +121,7 @@ extension ExploreShortcutView { Spacer() MoreCaptionTextView(text: TextLiteral.more) - .navigationLinkRouter(data: NavigationListShortcutType(sectionType: sectionType, - shortcuts: shortcuts, - navigationParentView: .shortcuts)) + .navigationLinkRouter(data: sectionType) } .padding(.horizontal, 16) .padding(.bottom, 12) diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift index f3c6bc8d..25e3d711 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift @@ -28,7 +28,7 @@ struct ListShortcutView: View { LazyVStack(spacing: 0) { //TODO: 무한 스크롤을 위한 업데이트 함수 필요 - makeShortcutCellList(viewModel.fetchShortcutsBySectionType()) + makeShortcutCellList(viewModel.shortcuts) Rectangle() .fill(Color.shortcutsZipBackground) diff --git a/HappyAnding/HappyAnding/Views/MyPageViews/MyPageView.swift b/HappyAnding/HappyAnding/Views/MyPageViews/MyPageView.swift index 24d32177..8189d867 100644 --- a/HappyAnding/HappyAnding/Views/MyPageViews/MyPageView.swift +++ b/HappyAnding/HappyAnding/Views/MyPageViews/MyPageView.swift @@ -88,11 +88,6 @@ struct MyPageShortcutListCell: View { var type: SectionType let shortcuts: [Shortcuts] - var data: NavigationListShortcutType { - NavigationListShortcutType(sectionType: self.type, - shortcuts: self.shortcuts, - navigationParentView: .myPage) - } var body: some View { HStack() { Text(type == .myLovingShortcut ? TextLiteral.myPageViewLikedShortcuts : TextLiteral.myPageViewDownloadedShortcuts) @@ -119,6 +114,6 @@ struct MyPageShortcutListCell: View { } .frame(maxWidth: .infinity, alignment: .leading) .padding(.horizontal, 16) - .navigationLinkRouter(data: data) + .navigationLinkRouter(data: self.type) } } From 526b90b8923beafaca03f17e3c1b0dd624dc5939 Mon Sep 17 00:00:00 2001 From: jim4020key Date: Fri, 30 Jun 2023 19:13:44 +0900 Subject: [PATCH 35/53] [Feat] #471 - Remove NavigationListCategoryShortcutType --- .../HappyAnding/Extensions/View/View+Navigation.swift | 6 +++--- HappyAnding/HappyAnding/Model/NavigationStackModel.swift | 9 --------- .../ViewModel/ListCategoryShortcutViewModel.swift | 8 ++++---- .../Views/ExploreShortcutViews/ExploreShortcutView.swift | 8 ++------ .../ExploreShortcutViews/ListCategoryShortcutView.swift | 4 ++-- 5 files changed, 11 insertions(+), 24 deletions(-) diff --git a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift index 92c0798d..cd1bf32c 100644 --- a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift +++ b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift @@ -89,8 +89,8 @@ extension View { ShowProfileView(data: data as! NavigationProfile) case is NavigationSearch: SearchView() - case is NavigationListCategoryShortcutType: - ListCategoryShortcutView(viewModel: ListCategoryShortcutViewModel(data: data as! NavigationListCategoryShortcutType)) + case is Category: + ListCategoryShortcutView(viewModel: ListCategoryShortcutViewModel(data: data as! Category)) case is NavigationNicknameView: EditNicknameView() case is NavigationSettingView: @@ -130,7 +130,7 @@ struct NavigationViewModifier: ViewModifier { .navigationDestination(for: SectionType.self) { data in ListShortcutView(viewModel: ListShortcutViewModel(data: data)) } - .navigationDestination(for: NavigationListCategoryShortcutType.self) { data in + .navigationDestination(for: Category.self) { data in ListCategoryShortcutView(viewModel: ListCategoryShortcutViewModel(data: data)) } .navigationDestination(for: NavigationLisence.self) { value in diff --git a/HappyAnding/HappyAnding/Model/NavigationStackModel.swift b/HappyAnding/HappyAnding/Model/NavigationStackModel.swift index dc562151..0e58a781 100644 --- a/HappyAnding/HappyAnding/Model/NavigationStackModel.swift +++ b/HappyAnding/HappyAnding/Model/NavigationStackModel.swift @@ -21,15 +21,6 @@ struct NavigationProfile: Identifiable, Hashable { var userInfo: User? } -struct NavigationListCategoryShortcutType: Identifiable, Hashable { - - var id = UUID().uuidString - - var shortcuts: [Shortcuts] - var categoryName: Category - var navigationParentView: NavigationParentView -} - struct WriteCurationInfoType: Identifiable, Hashable { var id = UUID().uuidString diff --git a/HappyAnding/HappyAnding/ViewModel/ListCategoryShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ListCategoryShortcutViewModel.swift index c111e5b8..dd6f6db3 100644 --- a/HappyAnding/HappyAnding/ViewModel/ListCategoryShortcutViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ListCategoryShortcutViewModel.swift @@ -12,11 +12,11 @@ final class ListCategoryShortcutViewModel: ObservableObject { var shortcutsZipViewModel = ShortcutsZipViewModel.share @Published private(set) var shortcuts: [Shortcuts] = [] - @Published private(set) var categoryName: Category = .business + @Published private(set) var category: Category = .business - init(data: NavigationListCategoryShortcutType) { - shortcuts = shortcutsZipViewModel.shortcutsInCategory[data.categoryName.index] - categoryName = data.categoryName + init(data: Category) { + shortcuts = shortcutsZipViewModel.shortcutsInCategory[data.index] + category = data } } diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift index 8c9a66d0..72b10137 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift @@ -58,9 +58,7 @@ struct ExploreShortcutView: View { LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())]) { ForEach(Array(Category.allCases.enumerated()), id: \.offset) { index, value in - let data = NavigationListCategoryShortcutType(shortcuts: [], - categoryName: value, - navigationParentView: .shortcuts) + let data = value if index < viewModel.numberOfDisplayedCategories { @@ -152,9 +150,7 @@ extension ExploreShortcutView { Spacer() MoreCaptionTextView(text: TextLiteral.more) - .navigationLinkRouter(data: NavigationListCategoryShortcutType(shortcuts: [], - categoryName: category, - navigationParentView: .shortcuts)) + .navigationLinkRouter(data: category) } .padding(.horizontal, 16) .padding(.bottom, 12) diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift index 2d749b88..b7043037 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift @@ -30,7 +30,7 @@ struct ListCategoryShortcutView: View { } .padding(.bottom, 44) } - .navigationBarTitle(viewModel.categoryName.translateName()) + .navigationBarTitle(viewModel.category.translateName()) .navigationBarTitleDisplayMode(.inline) .background(Color.shortcutsZipBackground) .navigationBarBackground ({ Color.shortcutsZipBackground }) @@ -38,7 +38,7 @@ struct ListCategoryShortcutView: View { var scrollHeader: some View { VStack { - Text(viewModel.categoryName.fetchDescription().lineBreaking) + Text(viewModel.category.fetchDescription().lineBreaking) } .foregroundColor(.gray5) .shortcutsZipBody2() From fa73943d3882ed2353362717ef79441550140887 Mon Sep 17 00:00:00 2001 From: jim4020key Date: Fri, 30 Jun 2023 19:54:57 +0900 Subject: [PATCH 36/53] [Style] #471 - Remove unused lines --- .../ExploreShortcutView.swift | 4 +--- .../ListCategoryShortcutView.swift | 9 ++++----- .../ExploreShortcutViews/ListShortcutView.swift | 15 --------------- 3 files changed, 5 insertions(+), 23 deletions(-) diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift index 72b10137..c633d7cb 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift @@ -58,12 +58,10 @@ struct ExploreShortcutView: View { LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())]) { ForEach(Array(Category.allCases.enumerated()), id: \.offset) { index, value in - let data = value - if index < viewModel.numberOfDisplayedCategories { categoryCellView(with: value.translateName()) - .navigationLinkRouter(data: data) + .navigationLinkRouter(data: value) } } diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift index b7043037..872540c0 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift @@ -12,9 +12,10 @@ struct ListCategoryShortcutView: View { @StateObject var viewModel: ListCategoryShortcutViewModel var body: some View { + ScrollView { - scrollHeader + categoryHeader LazyVStack(spacing: 0) { ForEach(viewModel.shortcuts, id: \.self) { shortcut in @@ -36,10 +37,8 @@ struct ListCategoryShortcutView: View { .navigationBarBackground ({ Color.shortcutsZipBackground }) } - var scrollHeader: some View { - VStack { - Text(viewModel.category.fetchDescription().lineBreaking) - } + var categoryHeader: some View { + Text(viewModel.category.fetchDescription().lineBreaking) .foregroundColor(.gray5) .shortcutsZipBody2() .padding(16) diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift index 25e3d711..9aeac984 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift @@ -60,19 +60,4 @@ struct ListShortcutView: View { } } - - @ViewBuilder - private func makeIndexShortcutCellList(_ shortcuts: [Shortcuts]) -> some View { - ForEach(Array(shortcuts.enumerated()), id: \.offset) { index, shortcut in - let navigationData = NavigationReadShortcutType(shortcut: shortcut, - shortcutID: shortcut.id, - navigationParentView: .shortcuts) - ShortcutCell(shortcut: shortcut, - rankNumber: index + 1, - navigationParentView: .shortcuts) - .navigationLinkRouter(data: navigationData) - .listRowInsets(EdgeInsets()) - .listRowSeparator(.hidden) - } - } } From 44476df0e6320ad316275ca17b08e63299a5434e Mon Sep 17 00:00:00 2001 From: jim4020key Date: Fri, 30 Jun 2023 20:10:28 +0900 Subject: [PATCH 37/53] [Feat] #471 - Relocate property --- .../HappyAnding/ViewModel/ExploreShortcutViewModel.swift | 1 - .../Views/ExploreShortcutViews/ExploreShortcutView.swift | 6 ++++-- HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModel.swift index 8ae69669..9e0b5fc3 100644 --- a/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModel.swift @@ -14,7 +14,6 @@ final class ExploreShortcutViewModel: ObservableObject { @Published private(set) var isCategoryCellViewFolded = true @Published var isTappedAnnouncementCell = false @Published private(set) var numberOfDisplayedCategories = 6 - @Published private(set) var randomCategories = Category.allCases.shuffled().prefix(2) func changeNumberOfCategories() { isCategoryCellViewFolded.toggle() diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift index c633d7cb..7692a3b3 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift @@ -14,6 +14,8 @@ struct ExploreShortcutView: View { // TODO: 추후 UpdateInfoView 제작 시 true로 변경해서 cell 보이게 하기 @AppStorage("isUpdateAnnnouncementShow") var isUpdateAnnnouncementShow: Bool = false + let randomCategories: [Category] + var body: some View { ScrollViewReader { proxy in ScrollView { @@ -33,11 +35,11 @@ struct ExploreShortcutView: View { sectionView(with: .recent) .id(111) - categoryCardView(with: viewModel.randomCategories[0]) + categoryCardView(with: randomCategories[0]) sectionView(with: .download) - categoryCardView(with: viewModel.randomCategories[1]) + categoryCardView(with: randomCategories[1]) sectionView(with: .popular) diff --git a/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift b/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift index 4b17c112..cfadb0a0 100644 --- a/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift +++ b/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift @@ -27,6 +27,7 @@ struct ShortcutTabView: View { @State private var tempShortcutId = "" @State private var tempCurationId = "" + @State private var randomCategories = Category.allCases.shuffled().prefix(2) @State private var twiceTappedTab = 0 @State private var firstTabID = UUID() @@ -106,7 +107,7 @@ struct ShortcutTabView: View { @ViewBuilder private func firstTab() -> some View { - ExploreShortcutView(viewModel: ExploreShortcutViewModel()) + ExploreShortcutView(viewModel: ExploreShortcutViewModel(), randomCategories: Array(randomCategories)) .modifierNavigation() .navigationBarBackground ({ Color.shortcutsZipBackground }) .id(firstTabID) From d51f2f4a838a427c3492246250dded04af05d395 Mon Sep 17 00:00:00 2001 From: jim4020key Date: Tue, 25 Jul 2023 07:35:13 +0900 Subject: [PATCH 38/53] [Feat] #471 - Set Access Modifiers --- .../HappyAnding/ViewModel/ExploreShortcutViewModel.swift | 8 ++++++-- .../ViewModel/ListCategoryShortcutViewModel.swift | 2 +- .../HappyAnding/ViewModel/ListShortcutViewModel.swift | 3 +-- .../Views/ExploreShortcutViews/ExploreShortcutView.swift | 4 ++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModel.swift index 9e0b5fc3..9c6ebfb1 100644 --- a/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModel.swift @@ -9,7 +9,7 @@ import SwiftUI final class ExploreShortcutViewModel: ObservableObject { - var shortcutsZipViewModel = ShortcutsZipViewModel.share + private let shortcutsZipViewModel = ShortcutsZipViewModel.share @Published private(set) var isCategoryCellViewFolded = true @Published var isTappedAnnouncementCell = false @@ -24,7 +24,11 @@ final class ExploreShortcutViewModel: ObservableObject { isTappedAnnouncementCell = true } - func fetchShortcutsByCategories(category: Category) -> [Shortcuts] { + func fetchShortcuts(by category: Category) -> [Shortcuts] { shortcutsZipViewModel.shortcutsInCategory[category.index] } + + func fetchShortcuts(by sectionType: SectionType) -> [Shortcuts] { + sectionType.filterShortcuts(from: shortcutsZipViewModel) + } } diff --git a/HappyAnding/HappyAnding/ViewModel/ListCategoryShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ListCategoryShortcutViewModel.swift index dd6f6db3..a90df18e 100644 --- a/HappyAnding/HappyAnding/ViewModel/ListCategoryShortcutViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ListCategoryShortcutViewModel.swift @@ -9,7 +9,7 @@ import SwiftUI final class ListCategoryShortcutViewModel: ObservableObject { - var shortcutsZipViewModel = ShortcutsZipViewModel.share + private let shortcutsZipViewModel = ShortcutsZipViewModel.share @Published private(set) var shortcuts: [Shortcuts] = [] @Published private(set) var category: Category = .business diff --git a/HappyAnding/HappyAnding/ViewModel/ListShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ListShortcutViewModel.swift index 77fcf0c3..187add77 100644 --- a/HappyAnding/HappyAnding/ViewModel/ListShortcutViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ListShortcutViewModel.swift @@ -9,12 +9,11 @@ import SwiftUI final class ListShortcutViewModel: ObservableObject { - var shortcutsZipViewModel = ShortcutsZipViewModel.share + private let shortcutsZipViewModel = ShortcutsZipViewModel.share @Published private(set) var shortcuts: [Shortcuts] = [] @Published private(set) var sectionType: SectionType = .download - init(data: SectionType) { sectionType = data shortcuts = fetchShortcutsBySectionType() diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift index 7692a3b3..bb96dbf2 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift @@ -110,7 +110,7 @@ extension ExploreShortcutView { @ViewBuilder private func sectionView(with sectionType: SectionType) -> some View { - let shortcuts = sectionType.filterShortcuts(from: viewModel.shortcutsZipViewModel) + let shortcuts = viewModel.fetchShortcuts(by: sectionType) VStack(spacing: 0) { HStack { @@ -157,7 +157,7 @@ extension ExploreShortcutView { ScrollView(.horizontal, showsIndicators: false) { HStack { - ForEach(viewModel.fetchShortcutsByCategories(category: category).prefix(7), id: \.self) { shortcut in + ForEach(viewModel.fetchShortcuts(by: category).prefix(7), id: \.self) { shortcut in let data = NavigationReadShortcutType( shortcutID: shortcut.id, navigationParentView: .shortcuts) From 8b51a77017cd76332d7bccce565d79ad3f916c87 Mon Sep 17 00:00:00 2001 From: jim4020key Date: Tue, 25 Jul 2023 07:40:51 +0900 Subject: [PATCH 39/53] [Chore] #471 - Change location of files --- HappyAnding/HappyAnding.xcodeproj/project.pbxproj | 6 +++--- .../ExploreShortcutViewModel.swift | 0 .../ListCategoryShortcutViewModel.swift | 0 .../ListShortcutViewModel.swift | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename HappyAnding/HappyAnding/ViewModel/{ => ExploreShortcutViewModels}/ExploreShortcutViewModel.swift (100%) rename HappyAnding/HappyAnding/ViewModel/{ => ExploreShortcutViewModels}/ListCategoryShortcutViewModel.swift (100%) rename HappyAnding/HappyAnding/ViewModel/{ => ExploreShortcutViewModels}/ListShortcutViewModel.swift (100%) diff --git a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj index b26ee96a..640674cb 100644 --- a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj +++ b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj @@ -381,6 +381,9 @@ 8788E1A12A484518007C3852 /* ExploreShortcutViewModels */ = { isa = PBXGroup; children = ( + 4D061BB92A475EE800F76835 /* ExploreShortcutViewModel.swift */, + 4DF15D722A4ECC7D0014F854 /* ListShortcutViewModel.swift */, + 4DF15D742A4ECE1F0014F854 /* ListCategoryShortcutViewModel.swift */, ); path = ExploreShortcutViewModels; sourceTree = ""; @@ -659,9 +662,6 @@ A0F822AB2910B8F100AF4448 /* ShortcutsZipViewModel.swift */, 4D61A766291E1EE8000EF531 /* NavigationViewModel.swift */, F9AC2BB52935201C00165820 /* CheckUpdateVersion.swift */, - 4D061BB92A475EE800F76835 /* ExploreShortcutViewModel.swift */, - 4DF15D722A4ECC7D0014F854 /* ListShortcutViewModel.swift */, - 4DF15D742A4ECE1F0014F854 /* ListCategoryShortcutViewModel.swift */, ); path = ViewModel; sourceTree = ""; diff --git a/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModels/ExploreShortcutViewModel.swift similarity index 100% rename from HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModel.swift rename to HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModels/ExploreShortcutViewModel.swift diff --git a/HappyAnding/HappyAnding/ViewModel/ListCategoryShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModels/ListCategoryShortcutViewModel.swift similarity index 100% rename from HappyAnding/HappyAnding/ViewModel/ListCategoryShortcutViewModel.swift rename to HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModels/ListCategoryShortcutViewModel.swift diff --git a/HappyAnding/HappyAnding/ViewModel/ListShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModels/ListShortcutViewModel.swift similarity index 100% rename from HappyAnding/HappyAnding/ViewModel/ListShortcutViewModel.swift rename to HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModels/ListShortcutViewModel.swift From 6536aa1ede5a660397d20a5d1ae6f4b052cde018 Mon Sep 17 00:00:00 2001 From: jim4020key Date: Tue, 25 Jul 2023 07:49:49 +0900 Subject: [PATCH 40/53] [Style] #471 - Rename properties --- .../ExploreShortcutViewModel.swift | 16 ++++++++-------- .../ListCategoryShortcutViewModel.swift | 4 ++-- .../ListShortcutViewModel.swift | 4 ++-- .../ExploreShortcutView.swift | 6 +++--- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModels/ExploreShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModels/ExploreShortcutViewModel.swift index 9c6ebfb1..dca00d12 100644 --- a/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModels/ExploreShortcutViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModels/ExploreShortcutViewModel.swift @@ -12,23 +12,23 @@ final class ExploreShortcutViewModel: ObservableObject { private let shortcutsZipViewModel = ShortcutsZipViewModel.share @Published private(set) var isCategoryCellViewFolded = true - @Published var isTappedAnnouncementCell = false + @Published var isAnnouncementCellShowing = false @Published private(set) var numberOfDisplayedCategories = 6 - func changeNumberOfCategories() { - isCategoryCellViewFolded.toggle() - numberOfDisplayedCategories = isCategoryCellViewFolded ? 6 : 12 + func changeDisplayedCategories() { + self.isCategoryCellViewFolded.toggle() + self.numberOfDisplayedCategories = isCategoryCellViewFolded ? 6 : 12 } - func isShowingAnnouncement() { - isTappedAnnouncementCell = true + func announcementCellDidTap() { + self.isAnnouncementCellShowing = true } func fetchShortcuts(by category: Category) -> [Shortcuts] { - shortcutsZipViewModel.shortcutsInCategory[category.index] + self.shortcutsZipViewModel.shortcutsInCategory[category.index] } func fetchShortcuts(by sectionType: SectionType) -> [Shortcuts] { - sectionType.filterShortcuts(from: shortcutsZipViewModel) + sectionType.filterShortcuts(from: self.shortcutsZipViewModel) } } diff --git a/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModels/ListCategoryShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModels/ListCategoryShortcutViewModel.swift index a90df18e..e029f62e 100644 --- a/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModels/ListCategoryShortcutViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModels/ListCategoryShortcutViewModel.swift @@ -15,8 +15,8 @@ final class ListCategoryShortcutViewModel: ObservableObject { @Published private(set) var category: Category = .business init(data: Category) { - shortcuts = shortcutsZipViewModel.shortcutsInCategory[data.index] - category = data + self.shortcuts = shortcutsZipViewModel.shortcutsInCategory[data.index] + self.category = data } } diff --git a/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModels/ListShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModels/ListShortcutViewModel.swift index 187add77..06e1b292 100644 --- a/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModels/ListShortcutViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModels/ListShortcutViewModel.swift @@ -15,8 +15,8 @@ final class ListShortcutViewModel: ObservableObject { @Published private(set) var sectionType: SectionType = .download init(data: SectionType) { - sectionType = data - shortcuts = fetchShortcutsBySectionType() + self.sectionType = data + self.shortcuts = fetchShortcutsBySectionType() } func fetchShortcutsBySectionType() -> [Shortcuts] { diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift index bb96dbf2..39dd83be 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift @@ -22,7 +22,7 @@ struct ExploreShortcutView: View { VStack(spacing: 32) { if isUpdateAnnnouncementShow { Button { - viewModel.isShowingAnnouncement() + viewModel.announcementCellDidTap() } label: { AnnouncementCell(icon: "updateAppIcon", tagName: TextLiteral.updateTag, @@ -50,7 +50,7 @@ struct ExploreShortcutView: View { Spacer() Button { - viewModel.changeNumberOfCategories() + viewModel.changeDisplayedCategories() } label: { MoreCaptionTextView(text: viewModel.isCategoryCellViewFolded ? TextLiteral.categoryViewUnfold : TextLiteral.categoryViewFold) } @@ -95,7 +95,7 @@ struct ExploreShortcutView: View { } } .navigationBarBackground ({ Color.shortcutsZipBackground }) - .sheet(isPresented: $viewModel.isTappedAnnouncementCell) { + .sheet(isPresented: $viewModel.isAnnouncementCellShowing) { UpdateInfoView() .presentationDetents([.large]) .presentationDragIndicator(.visible) From 99f5b04fe814c9f015b096b4cabd1179d63b3607 Mon Sep 17 00:00:00 2001 From: jim4020key Date: Sat, 12 Aug 2023 23:17:01 +0900 Subject: [PATCH 41/53] [Fix] #473 - Resolve warning --- .../HappyAnding/ViewModel/ShortcutsZipViewModel.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/HappyAnding/HappyAnding/ViewModel/ShortcutsZipViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ShortcutsZipViewModel.swift index 6e3c3d64..9ca66768 100644 --- a/HappyAnding/HappyAnding/ViewModel/ShortcutsZipViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ShortcutsZipViewModel.swift @@ -917,8 +917,9 @@ extension ShortcutsZipViewModel { func fetchComment(shortcutID: String) -> Comments { if let index = allComments.firstIndex(where: {$0.id == shortcutID}) { - allComments[index].comments = allComments[index].fetchSortedComment() - return allComments[index] + var allComments = self.allComments[index] + allComments.comments = allComments.fetchSortedComment() + return allComments } return Comments(id: shortcutID, comments: []) } From d2c29f7bf3e7ad5792690b290e5a3f24a71a826f Mon Sep 17 00:00:00 2001 From: jim4020key Date: Sat, 12 Aug 2023 23:47:11 +0900 Subject: [PATCH 42/53] [Chore] #471 - Resolve Conflicts --- .../ExploreShortcutView.swift | 16 +++++----------- .../ListCategoryShortcutView.swift | 14 ++++++-------- .../ExploreShortcutViews/ListShortcutView.swift | 6 ++---- 3 files changed, 13 insertions(+), 23 deletions(-) diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift index 39dd83be..73741917 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift @@ -126,13 +126,11 @@ extension ExploreShortcutView { ForEach(Array(shortcuts.enumerated()), id:\.offset) { index, shortcut in if index < 3 { - let data = NavigationReadShortcutType(shortcutID:shortcut.id, - navigationParentView: .shortcuts) ShortcutCell(shortcut: shortcut, rankNumber: index + 1, navigationParentView: .shortcuts) - .navigationLinkRouter(data: data) + .navigationLinkRouter(data: shortcut) } } .background(Color.shortcutsZipBackground) @@ -158,15 +156,11 @@ extension ExploreShortcutView { ScrollView(.horizontal, showsIndicators: false) { HStack { ForEach(viewModel.fetchShortcuts(by: category).prefix(7), id: \.self) { shortcut in - let data = NavigationReadShortcutType( - shortcutID: shortcut.id, - navigationParentView: .shortcuts) - ShortcutCardCell( - categoryShortcutIcon: shortcut.sfSymbol, - categoryShortcutName: shortcut.title, - categoryShortcutColor: shortcut.color) - .navigationLinkRouter(data: data) + ShortcutCardCell(categoryShortcutIcon: shortcut.sfSymbol, + categoryShortcutName: shortcut.title, + categoryShortcutColor: shortcut.color) + .navigationLinkRouter(data: shortcut) } } .padding(.horizontal, 16) diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift index 872540c0..0e138458 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListCategoryShortcutView.swift @@ -19,14 +19,12 @@ struct ListCategoryShortcutView: View { LazyVStack(spacing: 0) { ForEach(viewModel.shortcuts, id: \.self) { shortcut in - let data = NavigationReadShortcutType(shortcut: shortcut, - shortcutID: shortcut.id, - navigationParentView: .shortcuts) - ShortcutCell(shortcut: shortcut, - navigationParentView: .shortcuts) - .navigationLinkRouter(data: data) - .listRowInsets(EdgeInsets()) - .listRowSeparator(.hidden) + + ShortcutCell(shortcut: shortcut, navigationParentView: .shortcuts) + .navigationLinkRouter(data: shortcut) + .listRowInsets(EdgeInsets()) + .listRowSeparator(.hidden) + } } .padding(.bottom, 44) diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift index 9aeac984..df6fe15c 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ListShortcutView.swift @@ -50,13 +50,11 @@ struct ListShortcutView: View { @ViewBuilder private func makeShortcutCellList(_ shortcuts: [Shortcuts]) -> some View { ForEach(shortcuts, id: \.self) { shortcut in - let navigationData = NavigationReadShortcutType(shortcut: shortcut, - shortcutID: shortcut.id, - navigationParentView: .shortcuts) + ShortcutCell(shortcut: shortcut, sectionType: viewModel.sectionType, navigationParentView: .shortcuts) - .navigationLinkRouter(data: navigationData) + .navigationLinkRouter(data: shortcut) } } From bcb08032d382994e184e30833a77157ff5c88353 Mon Sep 17 00:00:00 2001 From: Jeon Jimin Date: Sun, 25 Jun 2023 20:32:40 +0900 Subject: [PATCH 43/53] =?UTF-8?q?[Feat]=20#470=20-=20WriteCurationViewMode?= =?UTF-8?q?l=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 변수 위치 수정 - NavigationStack 변수 타입 변경 -> WriteCurationViewModel.Self todo: - CheckBoxShortcutCell 합치기 - 좋아요&작성한 단축어 정렬 확인하기 --- .../HappyAnding.xcodeproj/project.pbxproj | 4 ++ .../Extensions/View/View+Navigation.swift | 4 +- .../ViewModel/WriteCurationViewModel.swift | 67 +++++++++++++++++++ .../Components/UserCurationListView.swift | 8 +-- .../ReadCurationView.swift | 9 +-- .../WriteCurationInfoView.swift | 37 +++------- .../WriteCurationSetView.swift | 43 ++++-------- 7 files changed, 103 insertions(+), 69 deletions(-) create mode 100644 HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift diff --git a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj index 539e4ad0..a2c53144 100644 --- a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj +++ b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj @@ -132,6 +132,7 @@ F94B435F2907B19A00987819 /* FirebaseAuth in Frameworks */ = {isa = PBXBuildFile; productRef = F94B435E2907B19A00987819 /* FirebaseAuth */; }; F94B43612907B19A00987819 /* FirebaseFirestore in Frameworks */ = {isa = PBXBuildFile; productRef = F94B43602907B19A00987819 /* FirebaseFirestore */; }; F94B43632907B19A00987819 /* FirebaseFirestoreCombine-Community in Frameworks */ = {isa = PBXBuildFile; productRef = F94B43622907B19A00987819 /* FirebaseFirestoreCombine-Community */; }; + F95F26542A45C89400B534EB /* WriteCurationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F95F26532A45C89400B534EB /* WriteCurationViewModel.swift */; }; F96D45B72980301F000C2441 /* SubtitleTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96D45B62980301F000C2441 /* SubtitleTextView.swift */; }; F96D45BB29804057000C2441 /* EnvironmentValues+Alerter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96D45BA29804057000C2441 /* EnvironmentValues+Alerter.swift */; }; F96D45BD29816578000C2441 /* StickyHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96D45BC29816578000C2441 /* StickyHeader.swift */; }; @@ -293,6 +294,7 @@ F91F09DC29AE012600E04FA0 /* ShortcutGrade.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutGrade.swift; sourceTree = ""; }; F91F09DE29AE0B5E00E04FA0 /* GradeAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradeAlertView.swift; sourceTree = ""; }; F94B432D2907088400987819 /* UserCurationListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserCurationListView.swift; sourceTree = ""; }; + F95F26532A45C89400B534EB /* WriteCurationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WriteCurationViewModel.swift; sourceTree = ""; }; F96D45B62980301F000C2441 /* SubtitleTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubtitleTextView.swift; sourceTree = ""; }; F96D45BA29804057000C2441 /* EnvironmentValues+Alerter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EnvironmentValues+Alerter.swift"; sourceTree = ""; }; F96D45BC29816578000C2441 /* StickyHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickyHeader.swift; sourceTree = ""; }; @@ -668,6 +670,7 @@ A0F822AB2910B8F100AF4448 /* ShortcutsZipViewModel.swift */, 4D61A766291E1EE8000EF531 /* NavigationViewModel.swift */, F9AC2BB52935201C00165820 /* CheckUpdateVersion.swift */, + F95F26532A45C89400B534EB /* WriteCurationViewModel.swift */, ); path = ViewModel; sourceTree = ""; @@ -937,6 +940,7 @@ 87E99CD929042536009B691F /* SectionType.swift in Sources */, 872A7D8F2918393B004A05B8 /* PrivacyPolicyView.swift in Sources */, A38115BA292B447D0043E8B8 /* ShortcutCardCell.swift in Sources */, + F95F26542A45C89400B534EB /* WriteCurationViewModel.swift in Sources */, 8792479B291BDF820040D5C3 /* SearchView.swift in Sources */, A3FF018E291ACFA500384211 /* WithdrawalView.swift in Sources */, 4DF15D732A4ECC7D0014F854 /* ListShortcutViewModel.swift in Sources */, diff --git a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift index 37dbc21c..5351c8bf 100644 --- a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift +++ b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift @@ -67,8 +67,8 @@ extension View { @ViewBuilder func getDestination(data: T, isPresented: Binding) -> some View { switch data { - case is WriteCurationInfoType: - WriteCurationInfoView(data: data as! WriteCurationInfoType, isWriting: isPresented) + case is WriteCurationViewModel: + WriteCurationInfoView(viewModel: data as! WriteCurationViewModel) default: EmptyView() } diff --git a/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift b/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift new file mode 100644 index 00000000..7c08911b --- /dev/null +++ b/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift @@ -0,0 +1,67 @@ +// +// WriteCurationViewModel.swift +// HappyAnding +// +// Created by JeonJimin on 2023/06/23. +// + +import SwiftUI + +final class WriteCurationViewModel: ObservableObject, Hashable { + + static func == (lhs: WriteCurationViewModel, rhs: WriteCurationViewModel) -> Bool { + return false + } + func hash(into hasher: inout Hasher) { + hasher.combine(curation) + } + + private var shortcutsZipViewModel = ShortcutsZipViewModel.share + + //WriteCurationSet + @Published var isWriting = false + @Published var isEdit = false + + //좋아요 + 내가 작성한 단축어 목록 + @Published var shortcutCells = [ShortcutCellModel]() + //모음집 편집 시 전달받는 기존 모음집 정보 + @Published var curation = Curation(title: "", subtitle: "", isAdmin: false, background: "", author: "", shortcuts: [ShortcutCellModel]()) + + @Published var isTappedQuestionMark = false + //기존 선택 -> 편집 시 선택 해제 되어 기존 모음집 정보에서 삭제해야할 단축어 배열 + @Published var deletedShortcutCells = [ShortcutCellModel]() + + + //WriteCurationInfo + @Published var writeCurationNavigation = WriteCurationNavigation() + @Published var isValidTitle = false + @Published var isValidDescription = false + + var isIncomplete: Bool { + !(isValidTitle && isValidDescription) + } + + init() { + + } + + init(data: Curation) { + self.curation = data + } + + func fetchMakeCuration() { + shortcutCells = shortcutsZipViewModel.fetchShortcutMakeCuration().sorted { $0.title < $1.title } + if isEdit { + deletedShortcutCells = curation.shortcuts + } + } + + func addCuration() { + shortcutsZipViewModel.addCuration(curation: curation, isEdit: isEdit, deletedShortcutCells: deletedShortcutCells) + + self.isWriting.toggle() + if #available(iOS 16.1, *) { + writeCurationNavigation.navigationPath = .init() + } + } +} diff --git a/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift b/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift index 2e45eae7..904d3a06 100644 --- a/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift +++ b/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift @@ -77,10 +77,10 @@ struct UserCurationListView: View { @ViewBuilder private func writeCurationView() -> some View { - WriteCurationSetView(isWriting: $isWriting, curation: $curation, isEdit: false) - .navigationDestination(for: WriteCurationInfoType.self) { data in - WriteCurationInfoView(data: data, isWriting: $isWriting) - } + WriteCurationSetView(viewModel: WriteCurationViewModel()) + .navigationDestination(for: WriteCurationViewModel.self) { data in + WriteCurationInfoView(viewModel: data) + } } } diff --git a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift index 111d438e..feed6380 100644 --- a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift @@ -102,12 +102,9 @@ extension ReadCurationView { @ViewBuilder private func editView() -> some View { - WriteCurationSetView(isWriting: $viewModel.isWriting, - curation: $viewModel.curation, - isEdit: true - ) - .navigationDestination(for: WriteCurationInfoType.self) { data in - WriteCurationInfoView(data: data, isWriting: $viewModel.isWriting) + WriteCurationSetView(viewModel: WriteCurationViewModel(data: data.curation)) + .navigationDestination(for: WriteCurationViewModel.self) { data in + WriteCurationInfoView(viewModel: data) } } diff --git a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationInfoView.swift b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationInfoView.swift index 52a023ae..14b382ec 100644 --- a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationInfoView.swift +++ b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationInfoView.swift @@ -8,22 +8,10 @@ import SwiftUI struct WriteCurationInfoView: View { - - @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel - @EnvironmentObject var writeCurationNavigation: WriteCurationNavigation + @StateObject var viewModel: WriteCurationViewModel @FocusState var isDescriptionFieldFocused: Bool - @State var data: WriteCurationInfoType - @Binding var isWriting: Bool - - @State var isValidTitle = false - @State var isValidDescription = false - - private var isIncomplete: Bool { - !(isValidTitle && isValidDescription) - } - var body: some View { VStack(spacing: 24) { ProgressView(value: 2, total: 2) @@ -34,8 +22,8 @@ struct WriteCurationInfoView: View { placeholder: TextLiteral.writeCurationInfoViewNamePlaceholder, lengthLimit: 20, isDownloadLinkTextField: false, - content: $data.curation.title, - isValid: $isValidTitle) + content: $viewModel.curation.title, + isValid: $viewModel.isValidTitle) .padding(.top, 12) .onSubmit { isDescriptionFieldFocused = true @@ -49,9 +37,8 @@ struct WriteCurationInfoView: View { lengthLimit: 40, isDownloadLinkTextField: false, inputHeight: 72, - content: Binding(get: {data.curation.subtitle}, - set: {data.curation.subtitle = $0}), - isValid: $isValidDescription) + content: $viewModel.curation.subtitle, + isValid: $viewModel.isValidDescription) .focused($isDescriptionFieldFocused) Spacer() @@ -60,23 +47,17 @@ struct WriteCurationInfoView: View { .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button { - - shortcutsZipViewModel.addCuration(curation: data.curation, isEdit: data.isEdit, deletedShortcutCells: data.deletedShortcutCells) - - self.isWriting.toggle() - if #available(iOS 16.1, *) { - writeCurationNavigation.navigationPath = .init() - } + viewModel.addCuration() } label: { Text(TextLiteral.upload) .shortcutsZipHeadline() - .foregroundColor(isIncomplete ? .shortcutsZipPrimary.opacity(0.3) : .shortcutsZipPrimary) + .foregroundColor(viewModel.isIncomplete ? .shortcutsZipPrimary.opacity(0.3) : .shortcutsZipPrimary) } - .disabled(isIncomplete) + .disabled(viewModel.isIncomplete) } } .background(Color.shortcutsZipBackground) - .navigationBarTitle(data.isEdit ? TextLiteral.writeCurationInfoViewEdit : TextLiteral.wrietCurationInfoViewPost) + .navigationBarTitle(viewModel.isEdit ? TextLiteral.writeCurationInfoViewEdit : TextLiteral.wrietCurationInfoViewPost) .onAppear(perform : UIApplication.shared.hideKeyboard) } } diff --git a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift index 0705abfe..4c91c2a7 100644 --- a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift +++ b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift @@ -9,19 +9,7 @@ import SwiftUI struct WriteCurationSetView: View { - @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel - @EnvironmentObject var writeCurationNavigation: WriteCurationNavigation - - @Binding var isWriting: Bool - - @State var shortcutCells = [ShortcutCellModel]() - @State var isSelected = false - @Binding var curation: Curation - @State var isTappedQuestionMark: Bool = false - @State var deletedShortcutCells = [ShortcutCellModel]() - - let isEdit: Bool - + @StateObject var viewModel: WriteCurationViewModel var body: some View { VStack { ProgressView(value: 1, total: 2) @@ -29,7 +17,7 @@ struct WriteCurationSetView: View { listHeader infomation - if shortcutCells.isEmpty { + if viewModel.shortcutCells.isEmpty { Spacer() Text(TextLiteral.writeCurationSetViewNoShortcuts) .shortcutsZipBody2() @@ -42,31 +30,28 @@ struct WriteCurationSetView: View { } } .background(Color.shortcutsZipBackground) - .navigationTitle(isEdit ? TextLiteral.writeCurationSetViewEdit : TextLiteral.writeCurationSetViewPost) + .navigationTitle(viewModel.isEdit ? TextLiteral.writeCurationSetViewEdit : TextLiteral.writeCurationSetViewPost) .navigationBarTitleDisplayMode(.inline) .onAppear { - self.shortcutCells = shortcutsZipViewModel.fetchShortcutMakeCuration().sorted { $0.title < $1.title } - if isEdit { - deletedShortcutCells = curation.shortcuts - } + viewModel.fetchMakeCuration() } .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button { - self.isWriting.toggle() + viewModel.isWriting.toggle() } label: { Text(TextLiteral.cancel) .shortcutsZipBody1() .foregroundColor(.gray4) } } - + ToolbarItem(placement: .navigationBarTrailing) { Text(TextLiteral.next) - .navigationLinkRouter(data: WriteCurationInfoType(curation: curation, deletedShortcutCells: deletedShortcutCells, isEdit: isEdit), isPresented: $isWriting) + .navigationLinkRouter(data: viewModel, isPresented: $viewModel.isWriting) .shortcutsZipHeadline() - .foregroundColor(curation.shortcuts.isEmpty ? .shortcutsZipPrimary.opacity(0.3) : .shortcutsZipPrimary) - .disabled(curation.shortcuts.isEmpty) + .foregroundColor(viewModel.curation.shortcuts.isEmpty ? .shortcutsZipPrimary.opacity(0.3) : .shortcutsZipPrimary) + .disabled(viewModel.curation.shortcuts.isEmpty) } } } @@ -81,7 +66,7 @@ struct WriteCurationSetView: View { .shortcutsZipFootnote() .foregroundColor(.gray3) Spacer() - Text("\(curation.shortcuts.count)개") + Text("\(viewModel.curation.shortcuts.count)개") .shortcutsZipBody2() .foregroundColor(.shortcutsZipPrimary) } @@ -92,11 +77,11 @@ struct WriteCurationSetView: View { var shortcutList: some View { ScrollView { - ForEach(Array(shortcutCells)) { shortcut in + ForEach(Array(viewModel.shortcutCells)) { shortcut in CheckBoxShortcutCell( - selectedShortcutCells: $curation.shortcuts, isShortcutTapped: curation.shortcuts.contains(shortcut), - shortcutCell: shortcut - ) + selectedShortcutCells: $viewModel.curation.shortcuts, + isShortcutTapped: $viewModel.curation.shortcuts.contains{$0.id == shortcut.id}, + shortcutCell: shortcut) } } .frame(maxWidth: .infinity) From b1ebefa62d38d4ce3ef73cb2034501bbfabd14da Mon Sep 17 00:00:00 2001 From: Jeon Jimin Date: Fri, 30 Jun 2023 21:26:33 +0900 Subject: [PATCH 44/53] =?UTF-8?q?[Feat]=20#470=20-=20checkbox=20shortcut?= =?UTF-8?q?=20=EB=B7=B0=EB=AA=A8=EB=8D=B8=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewModel/WriteCurationViewModel.swift | 32 ++++++++++-- .../CheckBoxShortcutCell.swift | 49 ++++++------------- .../WriteCurationSetView.swift | 7 +-- 3 files changed, 45 insertions(+), 43 deletions(-) diff --git a/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift b/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift index 7c08911b..ad1e25f1 100644 --- a/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift @@ -24,6 +24,9 @@ final class WriteCurationViewModel: ObservableObject, Hashable { //좋아요 + 내가 작성한 단축어 목록 @Published var shortcutCells = [ShortcutCellModel]() + //CheckboxShortcutCell 선택 여부 저장 + @Published var isShortcutsTapped: [Bool] = [] + //모음집 편집 시 전달받는 기존 모음집 정보 @Published var curation = Curation(title: "", subtitle: "", isAdmin: false, background: "", author: "", shortcuts: [ShortcutCellModel]()) @@ -41,9 +44,7 @@ final class WriteCurationViewModel: ObservableObject, Hashable { !(isValidTitle && isValidDescription) } - init() { - - } + init() { } init(data: Curation) { self.curation = data @@ -54,6 +55,14 @@ final class WriteCurationViewModel: ObservableObject, Hashable { if isEdit { deletedShortcutCells = curation.shortcuts } + + //isShortcutsTapped 초기화 + isShortcutsTapped = [Bool](repeating: false, count: shortcutCells.count) + for shortcut in curation.shortcuts { + if let index = shortcutCells.firstIndex(of: shortcut) { + isShortcutsTapped[index] = true + } + } } func addCuration() { @@ -64,4 +73,21 @@ final class WriteCurationViewModel: ObservableObject, Hashable { writeCurationNavigation.navigationPath = .init() } } + + func checkboxCellTapGesture(idx: Int) { + if isShortcutsTapped[idx] { + isShortcutsTapped[idx] = false + // TODO: 현재는 name을 기준으로 검색중, id로 검색해서 삭제해야함 / Shortcuts 자체를 배열에 저장해야함 + + if let index = curation.shortcuts.firstIndex(of: shortcutCells[idx]) { + curation.shortcuts.remove(at: index) + } + } + else { + if curation.shortcuts.count < 10 { + curation.shortcuts.append(shortcutCells[idx]) + isShortcutsTapped[idx] = true + } + } + } } diff --git a/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift b/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift index 5a2dedf8..b763d5d2 100644 --- a/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift +++ b/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift @@ -9,11 +9,9 @@ import SwiftUI struct CheckBoxShortcutCell: View { - @Binding var selectedShortcutCells: [ShortcutCellModel] - - @State var isShortcutTapped: Bool = false - - let shortcutCell: ShortcutCellModel + @StateObject var viewModel: WriteCurationViewModel + + let idx: Int var body: some View { @@ -31,30 +29,16 @@ struct CheckBoxShortcutCell: View { .padding(.horizontal, 16) } .onTapGesture { - if isShortcutTapped { - isShortcutTapped = false - - // TODO: 현재는 name을 기준으로 검색중, id로 검색해서 삭제해야함 / Shortcuts 자체를 배열에 저장해야함 - - if let index = selectedShortcutCells.firstIndex(of: shortcutCell) { - selectedShortcutCells.remove(at: index) - } - } - else { - if selectedShortcutCells.count < 10 { - isShortcutTapped = true - selectedShortcutCells.append(shortcutCell) - } - } + viewModel.checkboxCellTapGesture(idx: idx) } .padding(.top, 0) .background(Color.shortcutsZipBackground) } var toggle: some View { - Image(systemName: isShortcutTapped ? "checkmark.square.fill" : "square") + Image(systemName: viewModel.isShortcutsTapped[idx] ? "checkmark.square.fill" : "square") .smallIcon() - .foregroundColor(isShortcutTapped ? .shortcutsZipPrimary : .gray3) + .foregroundColor(viewModel.isShortcutsTapped[idx] ? .shortcutsZipPrimary : .gray3) .padding(.leading, 20) } @@ -62,11 +46,11 @@ struct CheckBoxShortcutCell: View { ZStack(alignment: .center) { Rectangle() - .fill(Color.fetchGradient(color: shortcutCell.color)) + .fill(Color.fetchGradient(color: viewModel.shortcutCells[idx].color)) .cornerRadius(8) .frame(width: 52, height: 52) - Image(systemName: shortcutCell.sfSymbol) + Image(systemName: viewModel.shortcutCells[idx].sfSymbol) .mediumShortcutIcon() .foregroundColor(.white) } @@ -76,11 +60,11 @@ struct CheckBoxShortcutCell: View { var shortcutInfo: some View { VStack(alignment: .leading, spacing: 4) { - Text(shortcutCell.title) + Text(viewModel.shortcutCells[idx].title) .shortcutsZipHeadline() .foregroundColor(.gray5) .lineLimit(1) - Text(shortcutCell.subtitle) + Text(viewModel.shortcutCells[idx].subtitle) .shortcutsZipFootnote() .foregroundColor(.gray3) .lineLimit(2) @@ -92,15 +76,10 @@ struct CheckBoxShortcutCell: View { var background: some View { RoundedRectangle(cornerRadius: 12) - .fill(isShortcutTapped ? Color.shortcutsZipWhite : Color.backgroudList) + .fill(viewModel.isShortcutsTapped[idx] ? Color.shortcutsZipWhite : Color.backgroudList) .overlay( RoundedRectangle(cornerRadius: 12) - .strokeBorder(isShortcutTapped ? Color.shortcutsZipPrimary : Color.backgroudListBorder) + .strokeBorder(viewModel.isShortcutsTapped[idx] ? Color.shortcutsZipPrimary : Color.backgroudListBorder) ) - }} - -//struct CheckBoxShortcutCell_Previews: PreviewProvider { -// static var previews: some View { -// CheckBoxShortcutCell(color: "Blue", sfSymbol: "books.vertical.fill", name: "ShortcutsTitle", description: "DescriptionDescription") -// } -//} + } +} diff --git a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift index 4c91c2a7..c508271b 100644 --- a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift +++ b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift @@ -77,11 +77,8 @@ struct WriteCurationSetView: View { var shortcutList: some View { ScrollView { - ForEach(Array(viewModel.shortcutCells)) { shortcut in - CheckBoxShortcutCell( - selectedShortcutCells: $viewModel.curation.shortcuts, - isShortcutTapped: $viewModel.curation.shortcuts.contains{$0.id == shortcut.id}, - shortcutCell: shortcut) + ForEach(Array(viewModel.shortcutCells.enumerated()), id: \.offset) { index, shortcut in + CheckBoxShortcutCell(viewModel: viewModel, idx: index) } } .frame(maxWidth: .infinity) From 46cf7cedf921f3565a456a81da8b5ffa498bdef0 Mon Sep 17 00:00:00 2001 From: Jeon Jimin Date: Sat, 8 Jul 2023 12:52:23 +0900 Subject: [PATCH 45/53] =?UTF-8?q?[Feat]=20#470=20-=20checkboxCell=20?= =?UTF-8?q?=ED=95=A9=EC=B9=98=EA=B8=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - viewBuilder 이용 - idx -> index로 수정 --- .../ViewModel/WriteCurationViewModel.swift | 14 +- .../CheckBoxShortcutCell.swift | 164 +++++++++--------- .../WriteCurationSetView.swift | 59 ++++++- 3 files changed, 147 insertions(+), 90 deletions(-) diff --git a/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift b/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift index ad1e25f1..01895694 100644 --- a/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift @@ -74,19 +74,19 @@ final class WriteCurationViewModel: ObservableObject, Hashable { } } - func checkboxCellTapGesture(idx: Int) { - if isShortcutsTapped[idx] { - isShortcutsTapped[idx] = false + func checkboxCellTapGesture(index: Int) { + if isShortcutsTapped[index] { + isShortcutsTapped[index] = false // TODO: 현재는 name을 기준으로 검색중, id로 검색해서 삭제해야함 / Shortcuts 자체를 배열에 저장해야함 - if let index = curation.shortcuts.firstIndex(of: shortcutCells[idx]) { - curation.shortcuts.remove(at: index) + if let firstIndex = curation.shortcuts.firstIndex(of: shortcutCells[index]) { + curation.shortcuts.remove(at: firstIndex) } } else { if curation.shortcuts.count < 10 { - curation.shortcuts.append(shortcutCells[idx]) - isShortcutsTapped[idx] = true + curation.shortcuts.append(shortcutCells[index]) + isShortcutsTapped[index] = true } } } diff --git a/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift b/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift index b763d5d2..2f576e0a 100644 --- a/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift +++ b/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift @@ -1,85 +1,85 @@ +//// +//// CheckBoxShortcutCell.swift +//// HappyAnding +//// +//// Created by HanGyeongjun on 2022/10/26. +//// // -// CheckBoxShortcutCell.swift -// HappyAnding +//import SwiftUI // -// Created by HanGyeongjun on 2022/10/26. +//struct CheckBoxShortcutCell: View { // - -import SwiftUI - -struct CheckBoxShortcutCell: View { - - @StateObject var viewModel: WriteCurationViewModel - - let idx: Int - - var body: some View { - - ZStack { - Color.shortcutsZipBackground - - HStack { - toggle - icon - shortcutInfo - Spacer() - } - .padding(.vertical, 20) - .background( background ) - .padding(.horizontal, 16) - } - .onTapGesture { - viewModel.checkboxCellTapGesture(idx: idx) - } - .padding(.top, 0) - .background(Color.shortcutsZipBackground) - } - - var toggle: some View { - Image(systemName: viewModel.isShortcutsTapped[idx] ? "checkmark.square.fill" : "square") - .smallIcon() - .foregroundColor(viewModel.isShortcutsTapped[idx] ? .shortcutsZipPrimary : .gray3) - .padding(.leading, 20) - } - - var icon: some View { - - ZStack(alignment: .center) { - Rectangle() - .fill(Color.fetchGradient(color: viewModel.shortcutCells[idx].color)) - .cornerRadius(8) - .frame(width: 52, height: 52) - - Image(systemName: viewModel.shortcutCells[idx].sfSymbol) - .mediumShortcutIcon() - .foregroundColor(.white) - } - .padding(.leading, 12) - } - - var shortcutInfo: some View { - - VStack(alignment: .leading, spacing: 4) { - Text(viewModel.shortcutCells[idx].title) - .shortcutsZipHeadline() - .foregroundColor(.gray5) - .lineLimit(1) - Text(viewModel.shortcutCells[idx].subtitle) - .shortcutsZipFootnote() - .foregroundColor(.gray3) - .lineLimit(2) - } - .padding(.leading, 12) - .padding(.trailing, 20) - } - - var background: some View { - - RoundedRectangle(cornerRadius: 12) - .fill(viewModel.isShortcutsTapped[idx] ? Color.shortcutsZipWhite : Color.backgroudList) - .overlay( - RoundedRectangle(cornerRadius: 12) - .strokeBorder(viewModel.isShortcutsTapped[idx] ? Color.shortcutsZipPrimary : Color.backgroudListBorder) - ) - } -} +// @StateObject var viewModel: WriteCurationViewModel +// +// let idx: Int +// +// var body: some View { +// +// ZStack { +// Color.shortcutsZipBackground +// +// HStack { +// toggle +// icon +// shortcutInfo +// Spacer() +// } +// .padding(.vertical, 20) +// .background( background ) +// .padding(.horizontal, 16) +// } +// .onTapGesture { +// viewModel.checkboxCellTapGesture(idx: idx) +// } +// .padding(.top, 0) +// .background(Color.shortcutsZipBackground) +// } +// +// var toggle: some View { +// Image(systemName: viewModel.isShortcutsTapped[idx] ? "checkmark.square.fill" : "square") +// .smallIcon() +// .foregroundColor(viewModel.isShortcutsTapped[idx] ? .shortcutsZipPrimary : .gray3) +// .padding(.leading, 20) +// } +// +// var icon: some View { +// +// ZStack(alignment: .center) { +// Rectangle() +// .fill(Color.fetchGradient(color: viewModel.shortcutCells[idx].color)) +// .cornerRadius(8) +// .frame(width: 52, height: 52) +// +// Image(systemName: viewModel.shortcutCells[idx].sfSymbol) +// .mediumShortcutIcon() +// .foregroundColor(.white) +// } +// .padding(.leading, 12) +// } +// +// var shortcutInfo: some View { +// +// VStack(alignment: .leading, spacing: 4) { +// Text(viewModel.shortcutCells[idx].title) +// .shortcutsZipHeadline() +// .foregroundColor(.gray5) +// .lineLimit(1) +// Text(viewModel.shortcutCells[idx].subtitle) +// .shortcutsZipFootnote() +// .foregroundColor(.gray3) +// .lineLimit(2) +// } +// .padding(.leading, 12) +// .padding(.trailing, 20) +// } +// +// var background: some View { +// +// RoundedRectangle(cornerRadius: 12) +// .fill(viewModel.isShortcutsTapped[idx] ? Color.shortcutsZipWhite : Color.backgroudList) +// .overlay( +// RoundedRectangle(cornerRadius: 12) +// .strokeBorder(viewModel.isShortcutsTapped[idx] ? Color.shortcutsZipPrimary : Color.backgroudListBorder) +// ) +// } +//} diff --git a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift index c508271b..acd609b9 100644 --- a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift +++ b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift @@ -78,7 +78,7 @@ struct WriteCurationSetView: View { ScrollView { ForEach(Array(viewModel.shortcutCells.enumerated()), id: \.offset) { index, shortcut in - CheckBoxShortcutCell(viewModel: viewModel, idx: index) + checkBoxShortcutCell(viewModel: viewModel, index: index) } } .frame(maxWidth: .infinity) @@ -99,4 +99,61 @@ struct WriteCurationSetView: View { .padding(.horizontal, 16) .padding(.bottom, 20) } + + @ViewBuilder + private func checkBoxShortcutCell(viewModel: WriteCurationViewModel, index: Int) -> some View { + + ZStack { + Color.shortcutsZipBackground + + HStack { + Image(systemName: viewModel.isShortcutsTapped[index] ? "checkmark.square.fill" : "square") + .smallIcon() + .foregroundColor(viewModel.isShortcutsTapped[index] ? .shortcutsZipPrimary : .gray3) + .padding(.leading, 20) + + ZStack(alignment: .center) { + Rectangle() + .fill(Color.fetchGradient(color: viewModel.shortcutCells[index].color)) + .cornerRadius(8) + .frame(width: 52, height: 52) + + Image(systemName: viewModel.shortcutCells[index].sfSymbol) + .mediumShortcutIcon() + .foregroundColor(.white) + } + .padding(.leading, 12) + + VStack(alignment: .leading, spacing: 4) { + Text(viewModel.shortcutCells[index].title) + .shortcutsZipHeadline() + .foregroundColor(.gray5) + .lineLimit(1) + Text(viewModel.shortcutCells[index].subtitle) + .shortcutsZipFootnote() + .foregroundColor(.gray3) + .lineLimit(2) + } + .padding(.leading, 12) + .padding(.trailing, 20) + + Spacer() + } + .padding(.vertical, 20) + .background( + RoundedRectangle(cornerRadius: 12) + .fill(viewModel.isShortcutsTapped[index] ? Color.shortcutsZipWhite : Color.backgroudList) + .overlay( + RoundedRectangle(cornerRadius: 12) + .strokeBorder(viewModel.isShortcutsTapped[index] ? Color.shortcutsZipPrimary : Color.backgroudListBorder) + ) + ) + .padding(.horizontal, 16) + } + .onTapGesture { + viewModel.checkboxCellTapGesture(index: index) + } + .padding(.top, 0) + .background(Color.shortcutsZipBackground) + } } From 45d051a952dcfa464a6fb2f3b79604177c743c4f Mon Sep 17 00:00:00 2001 From: Jeon Jimin Date: Thu, 20 Jul 2023 02:26:23 +0900 Subject: [PATCH 46/53] =?UTF-8?q?[Style]=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HappyAnding.xcodeproj/project.pbxproj | 4 - .../CheckBoxShortcutCell.swift | 85 ------------------- 2 files changed, 89 deletions(-) delete mode 100644 HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift diff --git a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj index a2c53144..ef190551 100644 --- a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj +++ b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj @@ -86,7 +86,6 @@ A31F1844292A637300AF4A82 /* Date+String.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9CAEF822914855900224B0A /* Date+String.swift */; }; A31F1846292A638700AF4A82 /* (null) in Sources */ = {isa = PBXBuildFile; }; A31F1848292A64D700AF4A82 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 87E99C7128F94EA8009B691F /* Assets.xcassets */; }; - A33F74AE2908D8C800B8D0D0 /* CheckBoxShortcutCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A33F74AD2908D8C800B8D0D0 /* CheckBoxShortcutCell.swift */; }; A3439AF529395A100043E273 /* UserAuth.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87E606B729114FB200C3DA13 /* UserAuth.swift */; }; A3439AF629395A3A0043E273 /* CustomTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87276C372933F6AB00C92F4C /* CustomTextEditor.swift */; }; A3439AFB2939B0E80043E273 /* UserDefaults+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3439AFA2939B0E80043E273 /* UserDefaults+Extension.swift */; }; @@ -267,7 +266,6 @@ A0DD085629276608008177BB /* URL+DeepLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+DeepLink.swift"; sourceTree = ""; }; A0F822AB2910B8F100AF4448 /* ShortcutsZipViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutsZipViewModel.swift; sourceTree = ""; }; A0F822B629164D2300AF4448 /* ListCategoryShortcutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListCategoryShortcutView.swift; sourceTree = ""; }; - A33F74AD2908D8C800B8D0D0 /* CheckBoxShortcutCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckBoxShortcutCell.swift; sourceTree = ""; }; A3439AFA2939B0E80043E273 /* UserDefaults+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserDefaults+Extension.swift"; sourceTree = ""; }; A34BF82729AF3D55009BC946 /* AnnouncementCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnnouncementCell.swift; sourceTree = ""; }; A34BF82C29AFC34F009BC946 /* AboutShortcutGradeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutShortcutGradeView.swift; sourceTree = ""; }; @@ -539,7 +537,6 @@ children = ( 87E99CB028FFF273009B691F /* WriteCurationSetView.swift */, 87E99CB428FFF282009B691F /* WriteCurationInfoView.swift */, - A33F74AD2908D8C800B8D0D0 /* CheckBoxShortcutCell.swift */, ); path = WriteCurationViews; sourceTree = ""; @@ -979,7 +976,6 @@ F99569182901DC4D0060AAEF /* UIFont+Extension.swift in Sources */, F91A72C32999160E00CA135A /* Alerter.swift in Sources */, 87E99CAD28FFF261009B691F /* ReadShortcutView.swift in Sources */, - A33F74AE2908D8C800B8D0D0 /* CheckBoxShortcutCell.swift in Sources */, 87E606B22910649B00C3DA13 /* SignInWithAppleView.swift in Sources */, F91F09DF29AE0B5E00E04FA0 /* GradeAlertView.swift in Sources */, 4D061BB82A47531800F76835 /* ExploreShortcutView.swift in Sources */, diff --git a/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift b/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift deleted file mode 100644 index 2f576e0a..00000000 --- a/HappyAnding/HappyAnding/Views/WriteCurationViews/CheckBoxShortcutCell.swift +++ /dev/null @@ -1,85 +0,0 @@ -//// -//// CheckBoxShortcutCell.swift -//// HappyAnding -//// -//// Created by HanGyeongjun on 2022/10/26. -//// -// -//import SwiftUI -// -//struct CheckBoxShortcutCell: View { -// -// @StateObject var viewModel: WriteCurationViewModel -// -// let idx: Int -// -// var body: some View { -// -// ZStack { -// Color.shortcutsZipBackground -// -// HStack { -// toggle -// icon -// shortcutInfo -// Spacer() -// } -// .padding(.vertical, 20) -// .background( background ) -// .padding(.horizontal, 16) -// } -// .onTapGesture { -// viewModel.checkboxCellTapGesture(idx: idx) -// } -// .padding(.top, 0) -// .background(Color.shortcutsZipBackground) -// } -// -// var toggle: some View { -// Image(systemName: viewModel.isShortcutsTapped[idx] ? "checkmark.square.fill" : "square") -// .smallIcon() -// .foregroundColor(viewModel.isShortcutsTapped[idx] ? .shortcutsZipPrimary : .gray3) -// .padding(.leading, 20) -// } -// -// var icon: some View { -// -// ZStack(alignment: .center) { -// Rectangle() -// .fill(Color.fetchGradient(color: viewModel.shortcutCells[idx].color)) -// .cornerRadius(8) -// .frame(width: 52, height: 52) -// -// Image(systemName: viewModel.shortcutCells[idx].sfSymbol) -// .mediumShortcutIcon() -// .foregroundColor(.white) -// } -// .padding(.leading, 12) -// } -// -// var shortcutInfo: some View { -// -// VStack(alignment: .leading, spacing: 4) { -// Text(viewModel.shortcutCells[idx].title) -// .shortcutsZipHeadline() -// .foregroundColor(.gray5) -// .lineLimit(1) -// Text(viewModel.shortcutCells[idx].subtitle) -// .shortcutsZipFootnote() -// .foregroundColor(.gray3) -// .lineLimit(2) -// } -// .padding(.leading, 12) -// .padding(.trailing, 20) -// } -// -// var background: some View { -// -// RoundedRectangle(cornerRadius: 12) -// .fill(viewModel.isShortcutsTapped[idx] ? Color.shortcutsZipWhite : Color.backgroudList) -// .overlay( -// RoundedRectangle(cornerRadius: 12) -// .strokeBorder(viewModel.isShortcutsTapped[idx] ? Color.shortcutsZipPrimary : Color.backgroudListBorder) -// ) -// } -//} From caf5adf2b338dc083cf9107baa27b842b1ca9bcc Mon Sep 17 00:00:00 2001 From: jeonjimin Date: Sun, 13 Aug 2023 13:54:23 +0900 Subject: [PATCH 47/53] =?UTF-8?q?[Feat]=20#470=20-=20isWriting=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HappyAnding/Extensions/View/View+Navigation.swift | 2 +- .../HappyAnding/ViewModel/WriteCurationViewModel.swift | 2 -- .../HappyAnding/Views/Components/UserCurationListView.swift | 6 +++--- .../Views/ExploreCurationViews/ReadCurationView.swift | 4 ++-- .../Views/WriteCurationViews/WriteCurationInfoView.swift | 4 +++- .../Views/WriteCurationViews/WriteCurationSetView.swift | 5 +++-- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift index 5351c8bf..76888014 100644 --- a/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift +++ b/HappyAnding/HappyAnding/Extensions/View/View+Navigation.swift @@ -68,7 +68,7 @@ extension View { func getDestination(data: T, isPresented: Binding) -> some View { switch data { case is WriteCurationViewModel: - WriteCurationInfoView(viewModel: data as! WriteCurationViewModel) + WriteCurationInfoView(viewModel: data as! WriteCurationViewModel, isWriting: isPresented) default: EmptyView() } diff --git a/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift b/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift index 01895694..fa5f22c0 100644 --- a/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift @@ -19,7 +19,6 @@ final class WriteCurationViewModel: ObservableObject, Hashable { private var shortcutsZipViewModel = ShortcutsZipViewModel.share //WriteCurationSet - @Published var isWriting = false @Published var isEdit = false //좋아요 + 내가 작성한 단축어 목록 @@ -68,7 +67,6 @@ final class WriteCurationViewModel: ObservableObject, Hashable { func addCuration() { shortcutsZipViewModel.addCuration(curation: curation, isEdit: isEdit, deletedShortcutCells: deletedShortcutCells) - self.isWriting.toggle() if #available(iOS 16.1, *) { writeCurationNavigation.navigationPath = .init() } diff --git a/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift b/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift index 904d3a06..e2ea1d31 100644 --- a/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift +++ b/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift @@ -23,7 +23,7 @@ struct UserCurationListView: View { var body: some View { VStack(spacing: 0) { HStack(alignment: .bottom) { - SubtitleTextView(text: data.title ?? "") + SubtitleTextView(text: data.title ) .onTapGesture { } Spacer() @@ -77,9 +77,9 @@ struct UserCurationListView: View { @ViewBuilder private func writeCurationView() -> some View { - WriteCurationSetView(viewModel: WriteCurationViewModel()) + WriteCurationSetView(isWriting: $isWriting, viewModel: WriteCurationViewModel()) .navigationDestination(for: WriteCurationViewModel.self) { data in - WriteCurationInfoView(viewModel: data) + WriteCurationInfoView(viewModel: data, isWriting: $isWriting) } } } diff --git a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift index feed6380..035989fe 100644 --- a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift @@ -102,9 +102,9 @@ extension ReadCurationView { @ViewBuilder private func editView() -> some View { - WriteCurationSetView(viewModel: WriteCurationViewModel(data: data.curation)) + WriteCurationSetView(isWriting: $viewModel.isWriting, viewModel: WriteCurationViewModel(data: viewModel.curation)) .navigationDestination(for: WriteCurationViewModel.self) { data in - WriteCurationInfoView(viewModel: data) + WriteCurationInfoView(viewModel: data, isWriting: $viewModel.isWriting) } } diff --git a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationInfoView.swift b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationInfoView.swift index 14b382ec..6bc51712 100644 --- a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationInfoView.swift +++ b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationInfoView.swift @@ -9,7 +9,8 @@ import SwiftUI struct WriteCurationInfoView: View { @StateObject var viewModel: WriteCurationViewModel - + @Binding var isWriting: Bool + @FocusState var isDescriptionFieldFocused: Bool var body: some View { @@ -48,6 +49,7 @@ struct WriteCurationInfoView: View { ToolbarItem(placement: .navigationBarTrailing) { Button { viewModel.addCuration() + self.isWriting.toggle() } label: { Text(TextLiteral.upload) .shortcutsZipHeadline() diff --git a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift index a7f44ebc..abe30425 100644 --- a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift +++ b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationSetView.swift @@ -9,6 +9,7 @@ import SwiftUI struct WriteCurationSetView: View { + @Binding var isWriting: Bool @StateObject var viewModel: WriteCurationViewModel var body: some View { VStack { @@ -38,7 +39,7 @@ struct WriteCurationSetView: View { .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button { - viewModel.isWriting.toggle() + self.isWriting.toggle() } label: { Text(TextLiteral.cancel) .shortcutsZipBody1() @@ -48,7 +49,7 @@ struct WriteCurationSetView: View { ToolbarItem(placement: .navigationBarTrailing) { Text(TextLiteral.next) - .navigationLinkRouter(data: viewModel, isPresented: $viewModel.isWriting) + .navigationLinkRouter(data: viewModel, isPresented: $isWriting) .shortcutsZipHeadline() .foregroundColor(viewModel.curation.shortcuts.isEmpty ? .shortcutsZipPrimary.opacity(0.3) : .shortcutsZipPrimary) .disabled(viewModel.curation.shortcuts.isEmpty) From 89eff6375c4c39b47142f2695eeea7494759fcbe Mon Sep 17 00:00:00 2001 From: jeonjimin Date: Sun, 13 Aug 2023 22:14:44 +0900 Subject: [PATCH 48/53] =?UTF-8?q?[Style]=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EB=B6=80=EB=B6=84=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HappyAnding/HappyAnding/Model/NavigationStackModel.swift | 9 --------- 1 file changed, 9 deletions(-) diff --git a/HappyAnding/HappyAnding/Model/NavigationStackModel.swift b/HappyAnding/HappyAnding/Model/NavigationStackModel.swift index a80d83c8..f0927503 100644 --- a/HappyAnding/HappyAnding/Model/NavigationStackModel.swift +++ b/HappyAnding/HappyAnding/Model/NavigationStackModel.swift @@ -7,15 +7,6 @@ import SwiftUI -struct WriteCurationInfoType: Identifiable, Hashable { - - var id = UUID().uuidString - - var curation: Curation - var deletedShortcutCells: [ShortcutCellModel] - var isEdit: Bool -} - enum NavigationSearch: Hashable, Equatable { case first } From 20b0b7604b87b370bdb181a1220611468c72feb1 Mon Sep 17 00:00:00 2001 From: jeonjimin Date: Sun, 13 Aug 2023 23:04:02 +0900 Subject: [PATCH 49/53] =?UTF-8?q?[Feat]=20#470=20-=20userCurationCell=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ExploreCurationViewModels/ReadCurationViewModel.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift index 0d2a9bd7..fe2a8b64 100644 --- a/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/ExploreCurationViewModels/ReadCurationViewModel.swift @@ -53,6 +53,13 @@ final class ReadCurationViewModel: ObservableObject { window.rootViewController?.present(activityVC, animated: true, completion: nil) } + func fetchCuration() { + if let index = shortcutsZipViewModel.userCurations.firstIndex(where: {$0.id == self.curation.id}) { + self.curation = shortcutsZipViewModel.userCurations[index] + print("curation", self.curation) + } + } + func fetchShortcut(from shortcutCellModel: ShortcutCellModel) -> Shortcuts { shortcutsZipViewModel.fetchShortcutDetail(id: shortcutCellModel.id) ?? Shortcuts() } From 7f5e7e61f1b732d30ea42c455254e0698dc75434 Mon Sep 17 00:00:00 2001 From: jeonjimin Date: Sun, 13 Aug 2023 23:05:20 +0900 Subject: [PATCH 50/53] =?UTF-8?q?[Feat]=20#470=20-=20userCurationCell?= =?UTF-8?q?=EC=9D=98=20curation=EC=9D=84=20Binding=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HappyAnding/Views/Components/UserCurationCell.swift | 2 +- .../HappyAnding/Views/Components/UserCurationListView.swift | 2 +- .../Views/ExploreCurationViews/ExploreCurationView.swift | 2 +- .../Views/ExploreCurationViews/ListCurationView.swift | 2 +- .../Views/ExploreCurationViews/ReadCurationView.swift | 5 ++++- .../Views/ReadShortcutViews/ShowProfileView.swift | 2 +- 6 files changed, 9 insertions(+), 6 deletions(-) diff --git a/HappyAnding/HappyAnding/Views/Components/UserCurationCell.swift b/HappyAnding/HappyAnding/Views/Components/UserCurationCell.swift index fc2bd461..b978fefe 100644 --- a/HappyAnding/HappyAnding/Views/Components/UserCurationCell.swift +++ b/HappyAnding/HappyAnding/Views/Components/UserCurationCell.swift @@ -13,7 +13,7 @@ struct UserCurationCell: View { @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel - @State var curation: Curation + @Binding var curation: Curation var lineLimit: Int? let navigationParentView: NavigationParentView diff --git a/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift b/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift index e2ea1d31..5ef0fee3 100644 --- a/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift +++ b/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift @@ -59,7 +59,7 @@ struct UserCurationListView: View { ForEach(Array(shortcutsZipViewModel.curationsMadeByUser.enumerated()), id: \.offset) { index, curation in if index < 2 { - UserCurationCell(curation: curation, + UserCurationCell(curation: .constant(curation), lineLimit: 2, navigationParentView: .curations) .navigationLinkRouter(data: curation) diff --git a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ExploreCurationView.swift b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ExploreCurationView.swift index 86e29f7f..93a5f20f 100644 --- a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ExploreCurationView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ExploreCurationView.swift @@ -73,7 +73,7 @@ struct ExploreCurationView: View { ForEach(viewModel.getCurationList(with:sectionType).prefix(2), id: \.self) { curation in - UserCurationCell(curation: curation, + UserCurationCell(curation: .constant(curation), lineLimit: 2, navigationParentView: .curations) .navigationLinkRouter(data: curation) diff --git a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ListCurationView.swift b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ListCurationView.swift index 70f0dcc8..fcfdaa34 100644 --- a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ListCurationView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ListCurationView.swift @@ -51,7 +51,7 @@ struct ListCurationView: View { private func makeCurationCellList(_ curations: [Curation]) -> some View { ForEach(Array(curations.enumerated()), id: \.offset) { index, curation in - UserCurationCell(curation: curation, + UserCurationCell(curation: .constant(curation), lineLimit: 2, navigationParentView: .curations) .navigationLinkRouter(data: curation) diff --git a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift index 035989fe..f9662d69 100644 --- a/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreCurationViews/ReadCurationView.swift @@ -41,6 +41,9 @@ struct ReadCurationView: View { .fullScreenCover(isPresented: $viewModel.isWriting) { NavigationRouter(content: editView, path: $writeCurationNavigation.navigationPath) .environmentObject(writeCurationNavigation) + .onDisappear() { + viewModel.fetchCuration() + } } .alert(TextLiteral.readCurationViewDeletionTitle, isPresented: $viewModel.isTappedDeleteButton) { Button(role: .cancel) { @@ -69,7 +72,7 @@ struct ReadCurationView: View { UserNameCell(userInformation: viewModel.authInformation, gradeImage: viewModel.gradeImage) .padding(EdgeInsets(top: 103, leading: 16, bottom: 0, trailing: 16)) - UserCurationCell(curation: viewModel.curation, navigationParentView: .curations) + UserCurationCell(curation: $viewModel.curation, navigationParentView: .curations) } } .padding(.bottom, 8) diff --git a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift index b2c871d0..6a6f6ff4 100644 --- a/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift +++ b/HappyAnding/HappyAnding/Views/ReadShortcutViews/ShowProfileView.swift @@ -158,7 +158,7 @@ struct ShowProfileView: View { VStack(spacing: 0) { ForEach(viewModel.curations, id: \.self) { curation in // TODO: navigation parent view 삭제 - UserCurationCell(curation: curation, + UserCurationCell(curation: .constant(curation), lineLimit: 2, navigationParentView: .curations) .navigationLinkRouter(data: curation) From 788e06b69275b5a3ac882924c2cc0917afef4ec2 Mon Sep 17 00:00:00 2001 From: jeonjimin Date: Sun, 13 Aug 2023 23:06:48 +0900 Subject: [PATCH 51/53] [Fix] resolve error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Publishing changes from within view updates 해결 -> DispatchQueue.main.async - 텍스트필드 focused된 채로 업로드 버튼 클릭 시 앱이 멈추는 에러 해결 -> focused 해제 후 업로드 동작하도록 수정 --- .../HappyAnding/Views/Components/CustomTextEditor.swift | 4 +++- .../Views/WriteCurationViews/WriteCurationInfoView.swift | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/HappyAnding/HappyAnding/Views/Components/CustomTextEditor.swift b/HappyAnding/HappyAnding/Views/Components/CustomTextEditor.swift index f37218d4..8b935ee5 100644 --- a/HappyAnding/HappyAnding/Views/Components/CustomTextEditor.swift +++ b/HappyAnding/HappyAnding/Views/Components/CustomTextEditor.swift @@ -54,7 +54,9 @@ struct CustomTextEditor: UIViewRepresentable { } func textViewDidChangeSelection(_ textView: UITextView) { - self.text = textView.text ?? "" + DispatchQueue.main.async { + self.text = textView.text ?? "" + } } func textViewDidBeginEditing(_ textView: UITextView) { diff --git a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationInfoView.swift b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationInfoView.swift index 6bc51712..f3b71817 100644 --- a/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationInfoView.swift +++ b/HappyAnding/HappyAnding/Views/WriteCurationViews/WriteCurationInfoView.swift @@ -48,6 +48,7 @@ struct WriteCurationInfoView: View { .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button { + isDescriptionFieldFocused = false viewModel.addCuration() self.isWriting.toggle() } label: { From a98e5683c6010fbb9f5982bc33755c35011944db Mon Sep 17 00:00:00 2001 From: jeonjimin Date: Mon, 14 Aug 2023 00:13:05 +0900 Subject: [PATCH 52/53] =?UTF-8?q?[Feat]=20#470=20-=20=EB=84=A4=EB=B9=84?= =?UTF-8?q?=EA=B2=8C=EC=9D=B4=EC=85=98=20=EC=B4=88=EA=B8=B0=ED=99=94=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HappyAnding/Views/Components/UserCurationListView.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift b/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift index 5ef0fee3..d7e76575 100644 --- a/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift +++ b/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift @@ -80,6 +80,9 @@ struct UserCurationListView: View { WriteCurationSetView(isWriting: $isWriting, viewModel: WriteCurationViewModel()) .navigationDestination(for: WriteCurationViewModel.self) { data in WriteCurationInfoView(viewModel: data, isWriting: $isWriting) + .onDisappear() { + writeCurationNavigation.navigationPath = NavigationPath() + } } } } From a53867bd54bc2612cf4af22d257a1ad333ba522b Mon Sep 17 00:00:00 2001 From: jeonjimin Date: Mon, 14 Aug 2023 01:23:44 +0900 Subject: [PATCH 53/53] [Fix] resolve update NavigationAuthority bound path tried to update multiple times per frame --- .../HappyAnding/ViewModel/WriteCurationViewModel.swift | 7 +------ .../Views/Components/UserCurationListView.swift | 6 ++++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift b/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift index fa5f22c0..5b410068 100644 --- a/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift +++ b/HappyAnding/HappyAnding/ViewModel/WriteCurationViewModel.swift @@ -29,13 +29,12 @@ final class WriteCurationViewModel: ObservableObject, Hashable { //모음집 편집 시 전달받는 기존 모음집 정보 @Published var curation = Curation(title: "", subtitle: "", isAdmin: false, background: "", author: "", shortcuts: [ShortcutCellModel]()) - @Published var isTappedQuestionMark = false //기존 선택 -> 편집 시 선택 해제 되어 기존 모음집 정보에서 삭제해야할 단축어 배열 @Published var deletedShortcutCells = [ShortcutCellModel]() //WriteCurationInfo - @Published var writeCurationNavigation = WriteCurationNavigation() +// @Published var writeCurationNavigation = WriteCurationNavigation() @Published var isValidTitle = false @Published var isValidDescription = false @@ -66,10 +65,6 @@ final class WriteCurationViewModel: ObservableObject, Hashable { func addCuration() { shortcutsZipViewModel.addCuration(curation: curation, isEdit: isEdit, deletedShortcutCells: deletedShortcutCells) - - if #available(iOS 16.1, *) { - writeCurationNavigation.navigationPath = .init() - } } func checkboxCellTapGesture(index: Int) { diff --git a/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift b/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift index d7e76575..8e289728 100644 --- a/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift +++ b/HappyAnding/HappyAnding/Views/Components/UserCurationListView.swift @@ -80,8 +80,10 @@ struct UserCurationListView: View { WriteCurationSetView(isWriting: $isWriting, viewModel: WriteCurationViewModel()) .navigationDestination(for: WriteCurationViewModel.self) { data in WriteCurationInfoView(viewModel: data, isWriting: $isWriting) - .onDisappear() { - writeCurationNavigation.navigationPath = NavigationPath() + .onDisappear(){ + if #available(iOS 16.1, *) { + writeCurationNavigation.navigationPath = .init() + } } } }