팔로잉/팔로워 리스트 - 팔로우와 알림설정
- 팔로잉 상태에서 알림 켜기/끄기 상태 추가
This commit is contained in:
		| @@ -12,7 +12,7 @@ struct FollowerListItemView: View { | |||||||
|      |      | ||||||
|     let item: GetFollowerListResponseItem |     let item: GetFollowerListResponseItem | ||||||
|     let creatorFollow: (Int) -> Void |     let creatorFollow: (Int) -> Void | ||||||
|     let creatorUnFollow: (Int) -> Void |     let showCreatorFollowNotifyDialog: (Int) -> Void | ||||||
|      |      | ||||||
|     var body: some View { |     var body: some View { | ||||||
|         VStack(spacing: 13.3) { |         VStack(spacing: 13.3) { | ||||||
| @@ -29,13 +29,18 @@ struct FollowerListItemView: View { | |||||||
|                  |                  | ||||||
|                 Spacer() |                 Spacer() | ||||||
|                  |                  | ||||||
|                 if let isFollow = item.isFollow { |                 if let isFollow = item.isFollow, let isNotify = item.isNotify { | ||||||
|                     Image(isFollow ? "btn_following_big" : "btn_follow_big") |                     Image(isFollow ? | ||||||
|                         .onTapGesture { |                           isNotify ? | ||||||
|                             isFollow ? |                           "btn_following_big" : | ||||||
|                             creatorUnFollow(item.userId) : |                             "btn_following_no_alarm_big" : | ||||||
|                             creatorFollow(item.userId) |                             "btn_follow_big" | ||||||
|                         } |                     ) | ||||||
|  |                     .onTapGesture { | ||||||
|  |                         isFollow ? | ||||||
|  |                         showCreatorFollowNotifyDialog(item.userId) : | ||||||
|  |                         creatorFollow(item.userId) | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             .padding(.top, 13.3) |             .padding(.top, 13.3) | ||||||
| @@ -59,7 +64,7 @@ struct FollowerListItemView_Previews: PreviewProvider { | |||||||
|                 isFollow: false |                 isFollow: false | ||||||
|             ), |             ), | ||||||
|             creatorFollow: { _ in }, |             creatorFollow: { _ in }, | ||||||
|             creatorUnFollow: { _ in } |             showCreatorFollowNotifyDialog: { _ in } | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -12,6 +12,10 @@ struct FollowerListView: View { | |||||||
|     let userId: Int |     let userId: Int | ||||||
|     @StateObject var viewModel = FollowerListViewModel() |     @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 { |     var body: some View { | ||||||
|         BaseView(isLoading: $viewModel.isLoading) { |         BaseView(isLoading: $viewModel.isLoading) { | ||||||
|             VStack(spacing: 0) { |             VStack(spacing: 0) { | ||||||
| @@ -20,11 +24,11 @@ struct FollowerListView: View { | |||||||
|                 HStack(spacing: 4) { |                 HStack(spacing: 4) { | ||||||
|                     Text("전체") |                     Text("전체") | ||||||
|                         .font(.custom(Font.bold.rawValue, size: 18.3)) |                         .font(.custom(Font.bold.rawValue, size: 18.3)) | ||||||
|                         .foregroundColor(Color(hex: "eeeeee")) |                         .foregroundColor(Color.grayee) | ||||||
|                      |                      | ||||||
|                     Text("\(viewModel.totalCount)") |                     Text("\(viewModel.totalCount)") | ||||||
|                         .font(.custom(Font.medium.rawValue, size: 18.3)) |                         .font(.custom(Font.medium.rawValue, size: 18.3)) | ||||||
|                         .foregroundColor(Color(hex: "9970ff")) |                         .foregroundColor(Color.button) | ||||||
|                      |                      | ||||||
|                     Spacer() |                     Spacer() | ||||||
|                 } |                 } | ||||||
| @@ -38,10 +42,12 @@ struct FollowerListView: View { | |||||||
|                             FollowerListItemView( |                             FollowerListItemView( | ||||||
|                                 item: item, |                                 item: item, | ||||||
|                                 creatorFollow: { |                                 creatorFollow: { | ||||||
|                                     viewModel.creatorFollow(userId: $0) |                                     viewModel.creatorFollow(creatorId: $0, index: index) | ||||||
|                                 }, |                                 }, | ||||||
|                                 creatorUnFollow: { |                                 showCreatorFollowNotifyDialog: { | ||||||
|                                     viewModel.creatorUnFollow(userId: $0) |                                     creatorId = $0 | ||||||
|  |                                     selectedItemIndex = index | ||||||
|  |                                     isShowFollowNotifyDialog = true | ||||||
|                                 } |                                 } | ||||||
|                             ) |                             ) | ||||||
|                             .onAppear { |                             .onAppear { | ||||||
| @@ -55,6 +61,42 @@ struct FollowerListView: View { | |||||||
|                     .padding(.bottom, 20) |                     .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) { |         .popup(isPresented: $viewModel.isShowPopup, type: .toast, position: .bottom, autohideIn: 2) { | ||||||
|             HStack { |             HStack { | ||||||
| @@ -63,7 +105,7 @@ struct FollowerListView: View { | |||||||
|                     .padding(.vertical, 13.3) |                     .padding(.vertical, 13.3) | ||||||
|                     .frame(width: screenSize().width - 66.7, alignment: .center) |                     .frame(width: screenSize().width - 66.7, alignment: .center) | ||||||
|                     .font(.custom(Font.medium.rawValue, size: 12)) |                     .font(.custom(Font.medium.rawValue, size: 12)) | ||||||
|                     .background(Color(hex: "9970ff")) |                     .background(Color.button) | ||||||
|                     .foregroundColor(Color.white) |                     .foregroundColor(Color.white) | ||||||
|                     .multilineTextAlignment(.leading) |                     .multilineTextAlignment(.leading) | ||||||
|                     .cornerRadius(20) |                     .cornerRadius(20) | ||||||
|   | |||||||
| @@ -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 |         isLoading = true | ||||||
|          |          | ||||||
|         userRepository.creatorFollow(creatorId: userId) |         userRepository.creatorFollow(creatorId: creatorId, follow: follow, notify: notify) | ||||||
|             .sink { result in |             .sink { result in | ||||||
|                 switch result { |                 switch result { | ||||||
|                 case .finished: |                 case .finished: | ||||||
| @@ -96,53 +96,11 @@ final class FollowerListViewModel: ObservableObject { | |||||||
|                     let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData) |                     let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData) | ||||||
|                      |                      | ||||||
|                     if decoded.success { |                     if decoded.success { | ||||||
|                         self.isLast = false |                         var follower = self.followerListItems[index] | ||||||
|                         self.page = 1 |                         follower.isFollow = follow | ||||||
|                         DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { |                         follower.isNotify = notify | ||||||
|                             self.getFollowerList() |                         self.followerListItems.remove(at: index) | ||||||
|                         } |                         self.followerListItems.insert(follower, 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 |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             .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() |  | ||||||
|                         } |  | ||||||
|                     } else { |                     } else { | ||||||
|                         if let message = decoded.message { |                         if let message = decoded.message { | ||||||
|                             self.errorMessage = message |                             self.errorMessage = message | ||||||
|   | |||||||
| @@ -16,5 +16,6 @@ struct GetFollowerListResponseItem: Decodable { | |||||||
|     let userId: Int |     let userId: Int | ||||||
|     let profileImage: String |     let profileImage: String | ||||||
|     let nickname: String |     let nickname: String | ||||||
|     let isFollow: Bool? |     var isFollow: Bool? | ||||||
|  |     var isNotify: Bool? | ||||||
| } | } | ||||||
|   | |||||||
| @@ -12,9 +12,7 @@ struct FollowCreatorItemView: View { | |||||||
|      |      | ||||||
|     let creator: GetCreatorFollowingAllListItem |     let creator: GetCreatorFollowingAllListItem | ||||||
|     let onClickFollow: (Int) -> Void |     let onClickFollow: (Int) -> Void | ||||||
|     let onClickUnFollow: (Int) -> Void |     let showCreatorFollowNotifyDialog: (Int) -> Void | ||||||
|      |  | ||||||
|     @State private var isFollow = true |  | ||||||
|      |      | ||||||
|     var body: some View { |     var body: some View { | ||||||
|         VStack(spacing: 13.3) { |         VStack(spacing: 13.3) { | ||||||
| @@ -26,29 +24,30 @@ struct FollowCreatorItemView: View { | |||||||
|                  |                  | ||||||
|                 Text(creator.nickname) |                 Text(creator.nickname) | ||||||
|                     .font(.custom(Font.bold.rawValue, size: 16.7)) |                     .font(.custom(Font.bold.rawValue, size: 16.7)) | ||||||
|                     .foregroundColor(Color(hex: "eeeeee")) |                     .foregroundColor(Color.grayee) | ||||||
|                     .padding(.leading, 13.3) |                     .padding(.leading, 13.3) | ||||||
|                  |                  | ||||||
|                 Spacer() |                 Spacer() | ||||||
|                  |                  | ||||||
|                 Image(isFollow ? "btn_following_big" : "btn_follow_big") |                 Image( | ||||||
|                     .onTapGesture { |                     creator.isFollow ? | ||||||
|                         if isFollow { |                     creator.isNotify ? | ||||||
|                             onClickUnFollow(creator.creatorId) |                     "btn_following_big" : | ||||||
|                         } else { |                         "btn_following_no_alarm_big" : | ||||||
|                             onClickFollow(creator.creatorId) |                         "btn_follow_big" | ||||||
|                         } |                 ) | ||||||
|                          |                 .onTapGesture { | ||||||
|                         isFollow = !isFollow |                     if creator.isFollow { | ||||||
|  |                         showCreatorFollowNotifyDialog(creator.creatorId) | ||||||
|  |                     } else { | ||||||
|  |                         onClickFollow(creator.creatorId) | ||||||
|                     } |                     } | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|              |              | ||||||
|             Rectangle() |             Rectangle() | ||||||
|                 .foregroundColor(Color(hex: "595959")) |                 .foregroundColor(Color.gray59) | ||||||
|                 .frame(height: 0.5) |                 .frame(height: 0.5) | ||||||
|         } |         } | ||||||
|         .onAppear { |  | ||||||
|             isFollow = creator.isFollow |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -11,6 +11,10 @@ struct FollowCreatorView: View { | |||||||
|      |      | ||||||
|     @StateObject var viewModel = FollowCreatorViewModel() |     @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 { |     var body: some View { | ||||||
|         BaseView(isLoading: $viewModel.isLoading) { |         BaseView(isLoading: $viewModel.isLoading) { | ||||||
|             VStack(spacing: 0) { |             VStack(spacing: 0) { | ||||||
| @@ -42,8 +46,14 @@ struct FollowCreatorView: View { | |||||||
|                                  |                                  | ||||||
|                                 FollowCreatorItemView( |                                 FollowCreatorItemView( | ||||||
|                                     creator: creator, |                                     creator: creator, | ||||||
|                                     onClickFollow: { viewModel.creatorFollow(userId: $0) }, |                                     onClickFollow: { | ||||||
|                                     onClickUnFollow: { viewModel.creatorUnFollow(userId: $0) } |                                         viewModel.creatorFollow(creatorId: $0, index: index) | ||||||
|  |                                     }, | ||||||
|  |                                     showCreatorFollowNotifyDialog: { | ||||||
|  |                                         creatorId = $0 | ||||||
|  |                                         selectedItemIndex = index | ||||||
|  |                                         isShowFollowNotifyDialog = true | ||||||
|  |                                     } | ||||||
|                                 ) |                                 ) | ||||||
|                                 .padding(.horizontal, 20) |                                 .padding(.horizontal, 20) | ||||||
|                                 .onTapGesture { |                                 .onTapGesture { | ||||||
| @@ -84,6 +94,42 @@ struct FollowCreatorView: View { | |||||||
|                     Spacer() |                     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 | ||||||
|  |                     } | ||||||
|  |                 ) | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -80,8 +80,9 @@ final class FollowCreatorViewModel: ObservableObject { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     func creatorFollow(userId: Int) { |     func creatorFollow(creatorId: Int, index: Int, follow: Bool = true, notify: Bool = true) { | ||||||
|         userRepository.creatorFollow(creatorId: userId) |         isLoading = true | ||||||
|  |         userRepository.creatorFollow(creatorId: creatorId, follow: follow, notify: notify) | ||||||
|             .sink { result in |             .sink { result in | ||||||
|                 switch result { |                 switch result { | ||||||
|                 case .finished: |                 case .finished: | ||||||
| @@ -89,20 +90,34 @@ final class FollowCreatorViewModel: ObservableObject { | |||||||
|                 case .failure(let error): |                 case .failure(let error): | ||||||
|                     ERROR_LOG(error.localizedDescription) |                     ERROR_LOG(error.localizedDescription) | ||||||
|                 } |                 } | ||||||
|             } receiveValue: { _ in } |             } receiveValue: { [unowned self] response in | ||||||
|             .store(in: &subscription) |                 self.isLoading = false | ||||||
|     } |                 let responseData = response.data | ||||||
|                  |                  | ||||||
|     func creatorUnFollow(userId: Int) { |                 do { | ||||||
|         userRepository.creatorUnFollow(creatorId: userId) |                     let jsonDecoder = JSONDecoder() | ||||||
|             .sink { result in |                     let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData) | ||||||
|                 switch result { |                      | ||||||
|                 case .finished: |                     if decoded.success { | ||||||
|                     DEBUG_LOG("finish") |                         var creator = self.creatorList[index] | ||||||
|                 case .failure(let error): |                         creator.isFollow = follow | ||||||
|                     ERROR_LOG(error.localizedDescription) |                         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) |             .store(in: &subscription) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -16,5 +16,6 @@ struct GetCreatorFollowingAllListItem: Decodable { | |||||||
|     let creatorId: Int |     let creatorId: Int | ||||||
|     let nickname: String |     let nickname: String | ||||||
|     let profileImageUrl: String |     let profileImageUrl: String | ||||||
|     let isFollow: Bool |     var isFollow: Bool | ||||||
|  |     var isNotify: Bool | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Yu Sung
					Yu Sung