커뮤니티 수정 UI, API 추가
This commit is contained in:
		| @@ -115,4 +115,6 @@ enum AppStep { | ||||
|     case creatorCommunityAll(creatorId: Int) | ||||
|      | ||||
|     case creatorCommunityWrite(onSuccess: () -> Void) | ||||
|      | ||||
|     case creatorCommunityModify(postId: Int, onSuccess: () -> Void) | ||||
| } | ||||
|   | ||||
| @@ -169,6 +169,9 @@ struct ContentView: View { | ||||
|             case .creatorCommunityWrite(let onSuccess): | ||||
|                 CreatorCommunityWriteView(onSuccess: onSuccess) | ||||
|                  | ||||
|             case .creatorCommunityModify(let postId, let onSuccess): | ||||
|                 CreatorCommunityModifyView(postId: postId, onSuccess: onSuccess) | ||||
|                  | ||||
|             default: | ||||
|                 EmptyView() | ||||
|                     .frame(width: 0, height: 0, alignment: .topLeading) | ||||
|   | ||||
| @@ -125,6 +125,8 @@ struct CreatorCommunityAllItemView_Previews: PreviewProvider { | ||||
|                 imageUrl: "https://test-cf.sodalive.net/profile/default-profile.png", | ||||
|                 content: "너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!", | ||||
|                 date: "3일전", | ||||
|                 isCommentAvailable: false, | ||||
|                 isAdult: false, | ||||
|                 isLike: true, | ||||
|                 likeCount: 10, | ||||
|                 commentCount: 0, | ||||
|   | ||||
| @@ -71,6 +71,15 @@ struct CreatorCommunityAllView: View { | ||||
|                                 isShowing: $viewModel.isShowReportMenu, | ||||
|                                 isShowCreatorMenu: creatorId == UserDefaults.int(forKey: .userId), | ||||
|                                 modifyAction: { | ||||
|                                     let postId = viewModel.postId | ||||
|                                     AppState.shared | ||||
|                                         .setAppStep( | ||||
|                                             step: .creatorCommunityModify( | ||||
|                                                 postId: postId, | ||||
|                                                 onSuccess: creatorCommunityModifySuccess | ||||
|                                             ) | ||||
|                                         ) | ||||
|                                     viewModel.postId = 0 | ||||
|                                 }, | ||||
|                                 deleteAction: { | ||||
|                                     if creatorId == UserDefaults.int(forKey: .userId) { | ||||
| @@ -137,6 +146,10 @@ struct CreatorCommunityAllView: View { | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     private func creatorCommunityModifySuccess() { | ||||
|         viewModel.getCommunityPostList() | ||||
|     } | ||||
| } | ||||
|  | ||||
| struct CreatorCommunityAllView_Previews: PreviewProvider { | ||||
|   | ||||
| @@ -12,6 +12,7 @@ enum CreatorCommunityApi { | ||||
|     case createCommunityPost(parameters: [MultipartFormData]) | ||||
|     case modifyCommunityPost(parameters: [MultipartFormData]) | ||||
|     case getCommunityPostList(creatorId: Int, page: Int, size: Int) | ||||
|     case getCommunityPostDetail(postId: Int) | ||||
|     case communityPostLike(postId: Int) | ||||
|     case createCommunityPostComment(comment: String, postId: Int, parentId: Int?) | ||||
|     case getCommunityPostCommentList(postId: Int, page: Int, size: Int) | ||||
| @@ -40,6 +41,9 @@ extension CreatorCommunityApi: TargetType { | ||||
|              | ||||
|         case .getCommentReplyList(let commentId, _, _): | ||||
|             return "/creator-community/comment/\(commentId)" | ||||
|              | ||||
|         case .getCommunityPostDetail(let postId): | ||||
|             return "/creator-community/\(postId)" | ||||
|         } | ||||
|     } | ||||
|      | ||||
| @@ -48,7 +52,7 @@ extension CreatorCommunityApi: TargetType { | ||||
|         case .createCommunityPost, .communityPostLike, .createCommunityPostComment: | ||||
|             return .post | ||||
|              | ||||
|         case .getCommunityPostList, .getCommunityPostCommentList, .getCommentReplyList: | ||||
|         case .getCommunityPostList, .getCommunityPostCommentList, .getCommentReplyList, .getCommunityPostDetail: | ||||
|             return .get | ||||
|              | ||||
|         case .modifyComment, .modifyCommunityPost: | ||||
| @@ -99,7 +103,10 @@ extension CreatorCommunityApi: TargetType { | ||||
|              | ||||
|         case .modifyComment(let request): | ||||
|             return .requestJSONEncodable(request) | ||||
|              | ||||
|          | ||||
|         case .getCommunityPostDetail: | ||||
|             let parameters = ["timezone": TimeZone.current.identifier] as [String: Any] | ||||
|             return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString) | ||||
|         } | ||||
|     } | ||||
|      | ||||
|   | ||||
| @@ -91,6 +91,8 @@ struct CreatorCommunityItemView_Previews: PreviewProvider { | ||||
|                 imageUrl: "https://test-cf.sodalive.net/profile/default-profile.png", | ||||
|                 content: "안녕하세요", | ||||
|                 date: "3일전", | ||||
|                 isCommentAvailable: false, | ||||
|                 isAdult: false, | ||||
|                 isLike: false, | ||||
|                 likeCount: 10, | ||||
|                 commentCount: 0, | ||||
|   | ||||
| @@ -25,6 +25,10 @@ class CreatorCommunityRepository { | ||||
|         return api.requestPublisher(.getCommunityPostList(creatorId: creatorId, page: page, size: size)) | ||||
|     } | ||||
|      | ||||
|     func getCommunityPostDetail(postId: Int) -> AnyPublisher<Response, MoyaError> { | ||||
|         return api.requestPublisher(.getCommunityPostDetail(postId: postId)) | ||||
|     } | ||||
|      | ||||
|     func communityPostLike(postId: Int) -> AnyPublisher<Response, MoyaError> { | ||||
|         return api.requestPublisher(.communityPostLike(postId: postId)) | ||||
|     } | ||||
|   | ||||
| @@ -12,6 +12,8 @@ struct GetCommunityPostListResponse: Decodable { | ||||
|     let imageUrl: String? | ||||
|     let content: String | ||||
|     let date: String | ||||
|     let isCommentAvailable: Bool | ||||
|     let isAdult: Bool | ||||
|     let isLike: Bool | ||||
|     let likeCount: Int | ||||
|     let commentCount: Int | ||||
|   | ||||
| @@ -0,0 +1,271 @@ | ||||
| // | ||||
| //  CreatorCommunityModifyView.swift | ||||
| //  SodaLive | ||||
| // | ||||
| //  Created by klaus on 2023/12/21. | ||||
| // | ||||
|  | ||||
| import SwiftUI | ||||
| import Kingfisher | ||||
|  | ||||
| struct CreatorCommunityModifyView: View { | ||||
|      | ||||
|     let postId: Int | ||||
|     @StateObject var keyboardHandler = KeyboardHandler() | ||||
|     @StateObject private var viewModel = CreatorCommunityModifyViewModel() | ||||
|      | ||||
|     @State private var isShowPhotoPicker = false | ||||
|     let onSuccess: () -> Void | ||||
|      | ||||
|     var body: some View { | ||||
|         BaseView(isLoading: $viewModel.isLoading) { | ||||
|             GeometryReader { proxy in | ||||
|                 ZStack { | ||||
|                     VStack(spacing: 0) { | ||||
|                         DetailNavigationBar(title: "게시글 수정") | ||||
|                          | ||||
|                         ScrollView(.vertical, showsIndicators: false) { | ||||
|                             VStack(spacing: 0) { | ||||
|                                 VStack(spacing: 0) { | ||||
|                                     Text("이미지") | ||||
|                                         .font(.custom(Font.bold.rawValue, size: 16.7)) | ||||
|                                         .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                         .frame(maxWidth: .infinity, alignment: .leading) | ||||
|                                      | ||||
|                                     ZStack { | ||||
|                                         if let selectedImage = viewModel.postImage { | ||||
|                                             Image(uiImage: selectedImage) | ||||
|                                                 .resizable() | ||||
|                                                 .scaledToFill() | ||||
|                                                 .frame(width: 107, height: 107) | ||||
|                                                 .background(Color(hex: "3e3358")) | ||||
|                                                 .cornerRadius(8) | ||||
|                                                 .clipped() | ||||
|                                         } else if let postImageUrl = viewModel.postImageUrl { | ||||
|                                             KFImage(URL(string: postImageUrl)) | ||||
|                                                 .resizable() | ||||
|                                                 .scaledToFill() | ||||
|                                                 .frame(width: 107, height: 107) | ||||
|                                                 .background(Color(hex: "3e3358")) | ||||
|                                                 .cornerRadius(8) | ||||
|                                                 .clipped() | ||||
|                                         } else { | ||||
|                                             Image("ic_logo2") | ||||
|                                                 .resizable() | ||||
|                                                 .scaledToFit() | ||||
|                                                 .padding(13.3) | ||||
|                                                 .frame(width: 107, height: 107) | ||||
|                                                 .background(Color(hex: "13181B")) | ||||
|                                                 .cornerRadius(8) | ||||
|                                                 .clipped() | ||||
|                                         } | ||||
|                                          | ||||
|                                         Image("ic_camera") | ||||
|                                             .padding(10) | ||||
|                                             .background(Color(hex: "3BB9F1")) | ||||
|                                             .cornerRadius(30) | ||||
|                                             .offset(x: 50, y: 36) | ||||
|                                     } | ||||
|                                     .frame(alignment: .bottomTrailing) | ||||
|                                     .contentShape(Rectangle()) | ||||
|                                     .onTapGesture { isShowPhotoPicker = true } | ||||
|                                      | ||||
|                                     HStack(alignment: .top, spacing: 0) { | ||||
|                                         Text("※ ") | ||||
|                                             .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                                             .foregroundColor(Color(hex: "777777")) | ||||
|                                          | ||||
|                                         Text("등록할 이미지가 없으면 이미지 없이 게시글만 등록 하셔도 됩니다.") | ||||
|                                             .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                                             .foregroundColor(Color(hex: "777777")) | ||||
|                                     } | ||||
|                                     .frame(maxWidth: .infinity, alignment: .leading) | ||||
|                                     .padding(.top, 24) | ||||
|                                      | ||||
|                                     HStack(spacing: 0) { | ||||
|                                         Text("내용") | ||||
|                                             .font(.custom(Font.bold.rawValue, size: 16.7)) | ||||
|                                             .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                          | ||||
|                                         Spacer() | ||||
|                                          | ||||
|                                         Text("\(viewModel.content.count)자") | ||||
|                                             .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                                             .foregroundColor(Color(hex: "ff5c49")) + | ||||
|                                         Text(" / 최대 500자") | ||||
|                                             .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                                             .foregroundColor(Color(hex: "777777")) | ||||
|                                     } | ||||
|                                     .padding(.top, 26.7) | ||||
|                                      | ||||
|                                     TextViewWrapper( | ||||
|                                         text: $viewModel.content, | ||||
|                                         placeholder: viewModel.placeholder, | ||||
|                                         textColorHex: "eeeeee", | ||||
|                                         backgroundColorHex: "222222" | ||||
|                                     ) | ||||
|                                     .frame(height: 184) | ||||
|                                     .cornerRadius(6.7) | ||||
|                                     .padding(.top, 13.3) | ||||
|                                      | ||||
|                                     VStack(spacing: 13.3) { | ||||
|                                         Text("댓글 가능 여부") | ||||
|                                             .font(.custom(Font.bold.rawValue, size: 16.7)) | ||||
|                                             .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                             .frame(maxWidth: .infinity, alignment: .leading) | ||||
|                                          | ||||
|                                         HStack(spacing: 13.3) { | ||||
|                                             SelectButtonView( | ||||
|                                                 title: "댓글 가능", | ||||
|                                                 isChecked: viewModel.isAvailableComment | ||||
|                                             ) { | ||||
|                                                 if !viewModel.isAvailableComment { | ||||
|                                                     viewModel.isAvailableComment = true | ||||
|                                                 } | ||||
|                                             } | ||||
|                                              | ||||
|                                             SelectButtonView( | ||||
|                                                 title: "댓글 불가", | ||||
|                                                 isChecked: !viewModel.isAvailableComment | ||||
|                                             ) { | ||||
|                                                 if viewModel.isAvailableComment { | ||||
|                                                     viewModel.isAvailableComment = false | ||||
|                                                 } | ||||
|                                             } | ||||
|                                         } | ||||
|                                     } | ||||
|                                     .padding(.top, 26.7) | ||||
|                                      | ||||
|                                     VStack(spacing: 13.3) { | ||||
|                                         Text("연령 제한") | ||||
|                                             .font(.custom(Font.bold.rawValue, size: 16.7)) | ||||
|                                             .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                             .frame(maxWidth: .infinity, alignment: .leading) | ||||
|                                          | ||||
|                                         HStack(spacing: 13.3) { | ||||
|                                             SelectButtonView( | ||||
|                                                 title: "전체 연령", | ||||
|                                                 isChecked: !viewModel.isAdult | ||||
|                                             ) { | ||||
|                                                 if viewModel.isAdult { | ||||
|                                                     viewModel.isAdult = false | ||||
|                                                 } | ||||
|                                             } | ||||
|                                              | ||||
|                                             SelectButtonView( | ||||
|                                                 title: "19세 이상", | ||||
|                                                 isChecked: viewModel.isAdult | ||||
|                                             ) { | ||||
|                                                 if !viewModel.isAdult { | ||||
|                                                     viewModel.isAdult = true | ||||
|                                                 } | ||||
|                                             } | ||||
|                                         } | ||||
|                                     } | ||||
|                                     .padding(.top, 26.7) | ||||
|                                 } | ||||
|                                 .padding(13.3) | ||||
|                                  | ||||
|                                 VStack(spacing: 0) { | ||||
|                                     HStack(spacing: 13.3) { | ||||
|                                         Text("닫기") | ||||
|                                             .font(.custom(Font.bold.rawValue, size: 18.3)) | ||||
|                                             .foregroundColor(Color(hex: "3BB9F1")) | ||||
|                                             .frame(maxWidth: .infinity) | ||||
|                                             .frame(height: 50) | ||||
|                                             .background(Color(hex: "13181B")) | ||||
|                                             .cornerRadius(10) | ||||
|                                             .overlay( | ||||
|                                                 RoundedRectangle(cornerRadius: 8) | ||||
|                                                     .stroke(Color(hex: "3BB9F1"), lineWidth: 1) | ||||
|                                             ) | ||||
|                                             .onTapGesture { | ||||
|                                                 hideKeyboard() | ||||
|                                                 AppState.shared.back() | ||||
|                                             } | ||||
|                                          | ||||
|                                         Text("수정") | ||||
|                                             .font(.custom(Font.bold.rawValue, size: 18.3)) | ||||
|                                             .foregroundColor(Color.white) | ||||
|                                             .frame(maxWidth: .infinity) | ||||
|                                             .frame(height: 50) | ||||
|                                             .background(Color(hex: "3BB9F1")) | ||||
|                                             .cornerRadius(10) | ||||
|                                             .onTapGesture { | ||||
|                                                 hideKeyboard() | ||||
|                                                 viewModel.modifyCommunityPost { | ||||
|                                                     AppState.shared.back() | ||||
|                                                      | ||||
|                                                     DispatchQueue.main.async { | ||||
|                                                         onSuccess() | ||||
|                                                     } | ||||
|                                                 } | ||||
|                                             } | ||||
|                                     } | ||||
|                                     .padding(13.3) | ||||
|                                     .frame(maxWidth: .infinity) | ||||
|                                     .background(Color(hex: "222222")) | ||||
|                                     .cornerRadius(16.7, corners: [.topLeft, .topRight]) | ||||
|                                      | ||||
|                                     Rectangle() | ||||
|                                         .foregroundColor(Color(hex: "222222")) | ||||
|                                         .frame(height: keyboardHandler.keyboardHeight) | ||||
|                                         .frame(maxWidth: .infinity) | ||||
|                                      | ||||
|                                     if proxy.safeAreaInsets.bottom > 0 { | ||||
|                                         Rectangle() | ||||
|                                             .foregroundColor(Color(hex: "222222")) | ||||
|                                             .frame(height: 15.3) | ||||
|                                             .frame(maxWidth: .infinity) | ||||
|                                     } | ||||
|                                 } | ||||
|                                 .padding(.top, 100) | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                      | ||||
|                     if isShowPhotoPicker { | ||||
|                         ImagePicker( | ||||
|                             isShowing: $isShowPhotoPicker, | ||||
|                             selectedImage: $viewModel.postImage, | ||||
|                             sourceType: .photoLibrary | ||||
|                         ) | ||||
|                     } | ||||
|                 } | ||||
|                 .onTapGesture { hideKeyboard() } | ||||
|                 .edgesIgnoringSafeArea(.bottom) | ||||
|                 .popup(isPresented: $viewModel.isShowPopup, type: .toast, position: .top, autohideIn: 2) { | ||||
|                     GeometryReader { geo in | ||||
|                         HStack { | ||||
|                             Spacer() | ||||
|                             Text(viewModel.errorMessage) | ||||
|                                 .padding(.vertical, 13.3) | ||||
|                                 .frame(width: screenSize().width - 66.7, alignment: .center) | ||||
|                                 .font(.custom(Font.medium.rawValue, size: 12)) | ||||
|                                 .background(Color(hex: "9970ff")) | ||||
|                                 .foregroundColor(Color.white) | ||||
|                                 .multilineTextAlignment(.center) | ||||
|                                 .cornerRadius(20) | ||||
|                                 .padding(.top, 66.7) | ||||
|                             Spacer() | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 .onAppear { | ||||
|                     viewModel.postId = postId | ||||
|                     viewModel.getCommunityPostDetail { | ||||
|                         DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { | ||||
|                             AppState.shared.back() | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| struct CreatorCommunityModifyView_Previews: PreviewProvider { | ||||
|     static var previews: some View { | ||||
|         CreatorCommunityModifyView(postId: 0) {} | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,166 @@ | ||||
| // | ||||
| //  CreatorCommunityModifyViewModel.swift | ||||
| //  SodaLive | ||||
| // | ||||
| //  Created by klaus on 2023/12/21. | ||||
| // | ||||
|  | ||||
| import UIKit | ||||
| import Moya | ||||
| import Combine | ||||
|  | ||||
| final class CreatorCommunityModifyViewModel: ObservableObject { | ||||
|     private let repository = CreatorCommunityRepository() | ||||
|     private var subscription = Set<AnyCancellable>() | ||||
|      | ||||
|     @Published var isLoading = false | ||||
|     @Published var errorMessage = "" | ||||
|     @Published var isShowPopup = false | ||||
|      | ||||
|     @Published var content = "" | ||||
|     @Published var isAdult = false | ||||
|     @Published var isAvailableComment = true | ||||
|     @Published var postImage: UIImage? = nil | ||||
|     @Published var postImageUrl: String? = nil | ||||
|     @Published private(set) var communityPost: GetCommunityPostListResponse? | ||||
|      | ||||
|     var placeholder = "내용을 입력하세요" | ||||
|     var postId = 0 | ||||
|      | ||||
|     func getCommunityPostDetail(onFailure: (() -> Void)? = nil) { | ||||
|         communityPost = nil | ||||
|         isLoading = true | ||||
|          | ||||
|         repository.getCommunityPostDetail(postId: postId) | ||||
|             .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(ApiResponse<GetCommunityPostListResponse>.self, from: responseData) | ||||
|                      | ||||
|                     if let data = decoded.data, decoded.success { | ||||
|                         self.communityPost = data | ||||
|                          | ||||
|                         self.content = data.content | ||||
|                         self.isAdult = data.isAdult | ||||
|                         self.isAvailableComment = data.isCommentAvailable | ||||
|                         self.postImageUrl = data.imageUrl | ||||
|                     } else { | ||||
|                         if let message = decoded.message { | ||||
|                             self.errorMessage = message | ||||
|                         } else { | ||||
|                             self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." | ||||
|                         } | ||||
|                          | ||||
|                         self.isShowPopup = true | ||||
|                         if let onFailure = onFailure { | ||||
|                             onFailure() | ||||
|                         } | ||||
|                     } | ||||
|                 } catch { | ||||
|                     self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." | ||||
|                     self.isShowPopup = true | ||||
|                     if let onFailure = onFailure { | ||||
|                         onFailure() | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             .store(in: &subscription) | ||||
|          | ||||
|     } | ||||
|      | ||||
|     func modifyCommunityPost(onSuccess: @escaping () -> Void) { | ||||
|         if !isLoading && validateData() { | ||||
|             isLoading = true | ||||
|              | ||||
|             let request = ModifyCommunityPostRequest( | ||||
|                 creatorCommunityId: postId, | ||||
|                 content: communityPost!.content != content ? content : nil, | ||||
|                 isCommentAvailable: communityPost!.isCommentAvailable != isAvailableComment ? isAvailableComment : nil, | ||||
|                 isAdult: communityPost!.isAdult != isAdult ? isAdult : nil | ||||
|             ) | ||||
|             var multipartData = [MultipartFormData]() | ||||
|              | ||||
|             let encoder = JSONEncoder() | ||||
|             encoder.outputFormatting = .withoutEscapingSlashes | ||||
|             let jsonData = try? encoder.encode(request) | ||||
|              | ||||
|             if let jsonData = jsonData { | ||||
|                 if let postImage = postImage, let imageData = postImage.jpegData(compressionQuality: 0.8) { | ||||
|                     multipartData.append( | ||||
|                         MultipartFormData( | ||||
|                             provider: .data(imageData), | ||||
|                             name: "postImage", | ||||
|                             fileName: "\(UUID().uuidString)_\(Date().timeIntervalSince1970 * 1000).jpg", | ||||
|                             mimeType: "image/*") | ||||
|                     ) | ||||
|                 } | ||||
|                  | ||||
|                 multipartData.append(MultipartFormData(provider: .data(jsonData), name: "request")) | ||||
|                  | ||||
|                 repository | ||||
|                     .modifyCommunityPost(parameters: multipartData) | ||||
|                     .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.errorMessage = "게시물이 수정되었습니다." | ||||
|                                 self.isShowPopup = true | ||||
|                                  | ||||
|                                 DispatchQueue.main.asyncAfter(deadline: .now() + 1) { | ||||
|                                     onSuccess() | ||||
|                                 } | ||||
|                             } 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) | ||||
|             } else { | ||||
|                 self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." | ||||
|                 self.isShowPopup = true | ||||
|                 self.isLoading = false | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     private func validateData() -> Bool { | ||||
|         if content.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || content.count < 5 { | ||||
|             errorMessage = "내용을 5자 이상 입력해 주세요." | ||||
|             isShowPopup = true | ||||
|             return false | ||||
|         } | ||||
|          | ||||
|         return true | ||||
|     } | ||||
| } | ||||
| @@ -93,7 +93,6 @@ final class CreatorCommunityWriteViewModel: ObservableObject { | ||||
|                 self.isShowPopup = true | ||||
|                 self.isLoading = false | ||||
|             } | ||||
|  | ||||
|         } | ||||
|     } | ||||
|      | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Yu Sung
					Yu Sung