From 6c8f3eb8bb1333461aa10f4d5390038f5fdbaada Mon Sep 17 00:00:00 2001 From: Yu Sung Date: Mon, 23 Sep 2024 17:54:35 +0900 Subject: [PATCH] =?UTF-8?q?=ED=8C=94=EB=A1=9C=EC=9E=89/=ED=8C=94=EB=A1=9C?= =?UTF-8?q?=EC=9B=8C=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20-=20=ED=8C=94?= =?UTF-8?q?=EB=A1=9C=EC=9A=B0=EC=99=80=20=EC=95=8C=EB=A6=BC=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20-=20=ED=8C=94=EB=A1=9C=EC=9E=89=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=EC=97=90=EC=84=9C=20=EC=95=8C=EB=A6=BC=20=EC=BC=9C?= =?UTF-8?q?=EA=B8=B0/=EB=81=84=EA=B8=B0=20=EC=83=81=ED=83=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FollowerList/FollowerListItemView.swift | 23 +++++--- .../FollowerList/FollowerListView.swift | 54 ++++++++++++++++-- .../FollowerList/FollowerListViewModel.swift | 56 +++---------------- .../GetFollowerListResponse.swift | 3 +- .../Follow/FollowCreatorItemView.swift | 33 ++++++----- .../Sources/Follow/FollowCreatorView.swift | 50 ++++++++++++++++- .../Follow/FollowCreatorViewModel.swift | 45 ++++++++++----- .../GetCreatorFollowingAllListResponse.swift | 3 +- 8 files changed, 167 insertions(+), 100 deletions(-) diff --git a/SodaLive/Sources/Explorer/Profile/FollowerList/FollowerListItemView.swift b/SodaLive/Sources/Explorer/Profile/FollowerList/FollowerListItemView.swift index 9c47a30..eee31d3 100644 --- a/SodaLive/Sources/Explorer/Profile/FollowerList/FollowerListItemView.swift +++ b/SodaLive/Sources/Explorer/Profile/FollowerList/FollowerListItemView.swift @@ -12,7 +12,7 @@ struct FollowerListItemView: View { let item: GetFollowerListResponseItem let creatorFollow: (Int) -> Void - let creatorUnFollow: (Int) -> Void + let showCreatorFollowNotifyDialog: (Int) -> Void var body: some View { VStack(spacing: 13.3) { @@ -29,13 +29,18 @@ struct FollowerListItemView: View { Spacer() - if let isFollow = item.isFollow { - Image(isFollow ? "btn_following_big" : "btn_follow_big") - .onTapGesture { - isFollow ? - creatorUnFollow(item.userId) : - creatorFollow(item.userId) - } + if let isFollow = item.isFollow, let isNotify = item.isNotify { + Image(isFollow ? + isNotify ? + "btn_following_big" : + "btn_following_no_alarm_big" : + "btn_follow_big" + ) + .onTapGesture { + isFollow ? + showCreatorFollowNotifyDialog(item.userId) : + creatorFollow(item.userId) + } } } .padding(.top, 13.3) @@ -59,7 +64,7 @@ struct FollowerListItemView_Previews: PreviewProvider { isFollow: false ), creatorFollow: { _ in }, - creatorUnFollow: { _ in } + showCreatorFollowNotifyDialog: { _ in } ) } } diff --git a/SodaLive/Sources/Explorer/Profile/FollowerList/FollowerListView.swift b/SodaLive/Sources/Explorer/Profile/FollowerList/FollowerListView.swift index e2da3fb..5872be6 100644 --- a/SodaLive/Sources/Explorer/Profile/FollowerList/FollowerListView.swift +++ b/SodaLive/Sources/Explorer/Profile/FollowerList/FollowerListView.swift @@ -12,6 +12,10 @@ struct FollowerListView: View { let userId: Int @StateObject var viewModel = FollowerListViewModel() + @State private var isShowFollowNotifyDialog: Bool = false + @State private var creatorId: Int = 0 + @State private var selectedItemIndex: Int = 0 + var body: some View { BaseView(isLoading: $viewModel.isLoading) { VStack(spacing: 0) { @@ -20,11 +24,11 @@ struct FollowerListView: View { HStack(spacing: 4) { Text("전체") .font(.custom(Font.bold.rawValue, size: 18.3)) - .foregroundColor(Color(hex: "eeeeee")) + .foregroundColor(Color.grayee) Text("\(viewModel.totalCount)") .font(.custom(Font.medium.rawValue, size: 18.3)) - .foregroundColor(Color(hex: "9970ff")) + .foregroundColor(Color.button) Spacer() } @@ -38,10 +42,12 @@ struct FollowerListView: View { FollowerListItemView( item: item, creatorFollow: { - viewModel.creatorFollow(userId: $0) + viewModel.creatorFollow(creatorId: $0, index: index) }, - creatorUnFollow: { - viewModel.creatorUnFollow(userId: $0) + showCreatorFollowNotifyDialog: { + creatorId = $0 + selectedItemIndex = index + isShowFollowNotifyDialog = true } ) .onAppear { @@ -55,6 +61,42 @@ struct FollowerListView: View { .padding(.bottom, 20) } } + + if isShowFollowNotifyDialog { + CreatorFollowNotifyDialog( + isShowing: $isShowFollowNotifyDialog, + onClickNotifyAll: { + viewModel.creatorFollow( + creatorId: creatorId, + index: selectedItemIndex, + follow: true, + notify: true + ) + creatorId = 0 + selectedItemIndex = -1 + }, + onClickNotifyNone: { + viewModel.creatorFollow( + creatorId: creatorId, + index: selectedItemIndex, + follow: true, + notify: false + ) + creatorId = 0 + selectedItemIndex = -1 + }, + onClickUnFollow: { + viewModel.creatorFollow( + creatorId: creatorId, + index: selectedItemIndex, + follow: false, + notify: false + ) + creatorId = 0 + selectedItemIndex = -1 + } + ) + } } .popup(isPresented: $viewModel.isShowPopup, type: .toast, position: .bottom, autohideIn: 2) { HStack { @@ -63,7 +105,7 @@ struct FollowerListView: View { .padding(.vertical, 13.3) .frame(width: screenSize().width - 66.7, alignment: .center) .font(.custom(Font.medium.rawValue, size: 12)) - .background(Color(hex: "9970ff")) + .background(Color.button) .foregroundColor(Color.white) .multilineTextAlignment(.leading) .cornerRadius(20) diff --git a/SodaLive/Sources/Explorer/Profile/FollowerList/FollowerListViewModel.swift b/SodaLive/Sources/Explorer/Profile/FollowerList/FollowerListViewModel.swift index 12f4360..739eac0 100644 --- a/SodaLive/Sources/Explorer/Profile/FollowerList/FollowerListViewModel.swift +++ b/SodaLive/Sources/Explorer/Profile/FollowerList/FollowerListViewModel.swift @@ -76,10 +76,10 @@ final class FollowerListViewModel: ObservableObject { } } - func creatorFollow(userId: Int) { + func creatorFollow(creatorId: Int, index: Int, follow: Bool = true, notify: Bool = true) { isLoading = true - userRepository.creatorFollow(creatorId: userId) + userRepository.creatorFollow(creatorId: creatorId, follow: follow, notify: notify) .sink { result in switch result { case .finished: @@ -96,53 +96,11 @@ final class FollowerListViewModel: ObservableObject { let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData) if decoded.success { - self.isLast = false - self.page = 1 - DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { - self.getFollowerList() - } - } else { - if let message = decoded.message { - self.errorMessage = message - } else { - self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." - } - - self.isShowPopup = true - } - } catch { - self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." - self.isShowPopup = true - } - } - .store(in: &subscription) - } - - func creatorUnFollow(userId: Int) { - isLoading = true - - userRepository.creatorUnFollow(creatorId: userId) - .sink { result in - switch result { - case .finished: - DEBUG_LOG("finish") - case .failure(let error): - ERROR_LOG(error.localizedDescription) - } - } receiveValue: { [unowned self] response in - self.isLoading = false - let responseData = response.data - - do { - let jsonDecoder = JSONDecoder() - let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData) - - if decoded.success { - self.isLast = false - self.page = 1 - DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { - self.getFollowerList() - } + var follower = self.followerListItems[index] + follower.isFollow = follow + follower.isNotify = notify + self.followerListItems.remove(at: index) + self.followerListItems.insert(follower, at: index) } else { if let message = decoded.message { self.errorMessage = message diff --git a/SodaLive/Sources/Explorer/Profile/FollowerList/GetFollowerListResponse.swift b/SodaLive/Sources/Explorer/Profile/FollowerList/GetFollowerListResponse.swift index 2162522..f3cb838 100644 --- a/SodaLive/Sources/Explorer/Profile/FollowerList/GetFollowerListResponse.swift +++ b/SodaLive/Sources/Explorer/Profile/FollowerList/GetFollowerListResponse.swift @@ -16,5 +16,6 @@ struct GetFollowerListResponseItem: Decodable { let userId: Int let profileImage: String let nickname: String - let isFollow: Bool? + var isFollow: Bool? + var isNotify: Bool? } diff --git a/SodaLive/Sources/Follow/FollowCreatorItemView.swift b/SodaLive/Sources/Follow/FollowCreatorItemView.swift index 0277192..cf39e65 100644 --- a/SodaLive/Sources/Follow/FollowCreatorItemView.swift +++ b/SodaLive/Sources/Follow/FollowCreatorItemView.swift @@ -12,9 +12,7 @@ struct FollowCreatorItemView: View { let creator: GetCreatorFollowingAllListItem let onClickFollow: (Int) -> Void - let onClickUnFollow: (Int) -> Void - - @State private var isFollow = true + let showCreatorFollowNotifyDialog: (Int) -> Void var body: some View { VStack(spacing: 13.3) { @@ -26,29 +24,30 @@ struct FollowCreatorItemView: View { Text(creator.nickname) .font(.custom(Font.bold.rawValue, size: 16.7)) - .foregroundColor(Color(hex: "eeeeee")) + .foregroundColor(Color.grayee) .padding(.leading, 13.3) Spacer() - Image(isFollow ? "btn_following_big" : "btn_follow_big") - .onTapGesture { - if isFollow { - onClickUnFollow(creator.creatorId) - } else { - onClickFollow(creator.creatorId) - } - - isFollow = !isFollow + Image( + creator.isFollow ? + creator.isNotify ? + "btn_following_big" : + "btn_following_no_alarm_big" : + "btn_follow_big" + ) + .onTapGesture { + if creator.isFollow { + showCreatorFollowNotifyDialog(creator.creatorId) + } else { + onClickFollow(creator.creatorId) } + } } Rectangle() - .foregroundColor(Color(hex: "595959")) + .foregroundColor(Color.gray59) .frame(height: 0.5) } - .onAppear { - isFollow = creator.isFollow - } } } diff --git a/SodaLive/Sources/Follow/FollowCreatorView.swift b/SodaLive/Sources/Follow/FollowCreatorView.swift index 52e5079..911cebe 100644 --- a/SodaLive/Sources/Follow/FollowCreatorView.swift +++ b/SodaLive/Sources/Follow/FollowCreatorView.swift @@ -11,6 +11,10 @@ struct FollowCreatorView: View { @StateObject var viewModel = FollowCreatorViewModel() + @State private var isShowFollowNotifyDialog: Bool = false + @State private var creatorId: Int = 0 + @State private var selectedItemIndex: Int = 0 + var body: some View { BaseView(isLoading: $viewModel.isLoading) { VStack(spacing: 0) { @@ -42,8 +46,14 @@ struct FollowCreatorView: View { FollowCreatorItemView( creator: creator, - onClickFollow: { viewModel.creatorFollow(userId: $0) }, - onClickUnFollow: { viewModel.creatorUnFollow(userId: $0) } + onClickFollow: { + viewModel.creatorFollow(creatorId: $0, index: index) + }, + showCreatorFollowNotifyDialog: { + creatorId = $0 + selectedItemIndex = index + isShowFollowNotifyDialog = true + } ) .padding(.horizontal, 20) .onTapGesture { @@ -84,6 +94,42 @@ struct FollowCreatorView: View { Spacer() } } + + if isShowFollowNotifyDialog { + CreatorFollowNotifyDialog( + isShowing: $isShowFollowNotifyDialog, + onClickNotifyAll: { + viewModel.creatorFollow( + creatorId: creatorId, + index: selectedItemIndex, + follow: true, + notify: true + ) + creatorId = 0 + selectedItemIndex = -1 + }, + onClickNotifyNone: { + viewModel.creatorFollow( + creatorId: creatorId, + index: selectedItemIndex, + follow: true, + notify: false + ) + creatorId = 0 + selectedItemIndex = -1 + }, + onClickUnFollow: { + viewModel.creatorFollow( + creatorId: creatorId, + index: selectedItemIndex, + follow: false, + notify: false + ) + creatorId = 0 + selectedItemIndex = -1 + } + ) + } } } } diff --git a/SodaLive/Sources/Follow/FollowCreatorViewModel.swift b/SodaLive/Sources/Follow/FollowCreatorViewModel.swift index c6754bb..b4516d6 100644 --- a/SodaLive/Sources/Follow/FollowCreatorViewModel.swift +++ b/SodaLive/Sources/Follow/FollowCreatorViewModel.swift @@ -80,8 +80,9 @@ final class FollowCreatorViewModel: ObservableObject { } } - func creatorFollow(userId: Int) { - userRepository.creatorFollow(creatorId: userId) + func creatorFollow(creatorId: Int, index: Int, follow: Bool = true, notify: Bool = true) { + isLoading = true + userRepository.creatorFollow(creatorId: creatorId, follow: follow, notify: notify) .sink { result in switch result { case .finished: @@ -89,20 +90,34 @@ final class FollowCreatorViewModel: ObservableObject { case .failure(let error): ERROR_LOG(error.localizedDescription) } - } receiveValue: { _ in } - .store(in: &subscription) - } - - func creatorUnFollow(userId: Int) { - userRepository.creatorUnFollow(creatorId: userId) - .sink { result in - switch result { - case .finished: - DEBUG_LOG("finish") - case .failure(let error): - ERROR_LOG(error.localizedDescription) + } receiveValue: { [unowned self] response in + self.isLoading = false + let responseData = response.data + + do { + let jsonDecoder = JSONDecoder() + let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData) + + if decoded.success { + var creator = self.creatorList[index] + creator.isFollow = follow + creator.isNotify = notify + self.creatorList.remove(at: index) + self.creatorList.insert(creator, at: index) + } else { + if let message = decoded.message { + self.errorMessage = message + } else { + self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." + } + + self.isShowPopup = true + } + } catch { + self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." + self.isShowPopup = true } - } receiveValue: { _ in } + } .store(in: &subscription) } } diff --git a/SodaLive/Sources/Follow/GetCreatorFollowingAllListResponse.swift b/SodaLive/Sources/Follow/GetCreatorFollowingAllListResponse.swift index 759def7..d93ac86 100644 --- a/SodaLive/Sources/Follow/GetCreatorFollowingAllListResponse.swift +++ b/SodaLive/Sources/Follow/GetCreatorFollowingAllListResponse.swift @@ -16,5 +16,6 @@ struct GetCreatorFollowingAllListItem: Decodable { let creatorId: Int let nickname: String let profileImageUrl: String - let isFollow: Bool + var isFollow: Bool + var isNotify: Bool }