콘텐츠 상세 - 콘텐츠 고정/해제 기능 추가
This commit is contained in:
		
							
								
								
									
										21
									
								
								SodaLive/Resources/Assets.xcassets/ic_pin.imageset/Contents.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								SodaLive/Resources/Assets.xcassets/ic_pin.imageset/Contents.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | { | ||||||
|  |   "images" : [ | ||||||
|  |     { | ||||||
|  |       "idiom" : "universal", | ||||||
|  |       "scale" : "1x" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "idiom" : "universal", | ||||||
|  |       "scale" : "2x" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "filename" : "ic_pin.png", | ||||||
|  |       "idiom" : "universal", | ||||||
|  |       "scale" : "3x" | ||||||
|  |     } | ||||||
|  |   ], | ||||||
|  |   "info" : { | ||||||
|  |     "author" : "xcode", | ||||||
|  |     "version" : 1 | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										
											BIN
										
									
								
								SodaLive/Resources/Assets.xcassets/ic_pin.imageset/ic_pin.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								SodaLive/Resources/Assets.xcassets/ic_pin.imageset/ic_pin.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 1.3 KiB | 
							
								
								
									
										21
									
								
								SodaLive/Resources/Assets.xcassets/ic_pin_cancel.imageset/Contents.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								SodaLive/Resources/Assets.xcassets/ic_pin_cancel.imageset/Contents.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | { | ||||||
|  |   "images" : [ | ||||||
|  |     { | ||||||
|  |       "idiom" : "universal", | ||||||
|  |       "scale" : "1x" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "idiom" : "universal", | ||||||
|  |       "scale" : "2x" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "filename" : "ic_pin_cancel.png", | ||||||
|  |       "idiom" : "universal", | ||||||
|  |       "scale" : "3x" | ||||||
|  |     } | ||||||
|  |   ], | ||||||
|  |   "info" : { | ||||||
|  |     "author" : "xcode", | ||||||
|  |     "version" : 1 | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										
											BIN
										
									
								
								SodaLive/Resources/Assets.xcassets/ic_pin_cancel.imageset/ic_pin_cancel.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								SodaLive/Resources/Assets.xcassets/ic_pin_cancel.imageset/ic_pin_cancel.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 1.5 KiB | 
							
								
								
									
										21
									
								
								SodaLive/Resources/Assets.xcassets/ic_trash_can.imageset/Contents.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								SodaLive/Resources/Assets.xcassets/ic_trash_can.imageset/Contents.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | { | ||||||
|  |   "images" : [ | ||||||
|  |     { | ||||||
|  |       "idiom" : "universal", | ||||||
|  |       "scale" : "1x" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "idiom" : "universal", | ||||||
|  |       "scale" : "2x" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "filename" : "ic_trash_can.png", | ||||||
|  |       "idiom" : "universal", | ||||||
|  |       "scale" : "3x" | ||||||
|  |     } | ||||||
|  |   ], | ||||||
|  |   "info" : { | ||||||
|  |     "author" : "xcode", | ||||||
|  |     "version" : 1 | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										
											BIN
										
									
								
								SodaLive/Resources/Assets.xcassets/ic_trash_can.imageset/ic_trash_can.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								SodaLive/Resources/Assets.xcassets/ic_trash_can.imageset/ic_trash_can.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 787 B | 
| @@ -34,6 +34,8 @@ enum ContentApi { | |||||||
|     case getAudioContentListByCurationId(curationId: Int, page: Int, size: Int, sort: ContentCurationViewModel.Sort) |     case getAudioContentListByCurationId(curationId: Int, page: Int, size: Int, sort: ContentCurationViewModel.Sort) | ||||||
|     case getContentRanking(page: Int, size: Int, sortType: String) |     case getContentRanking(page: Int, size: Int, sortType: String) | ||||||
|     case getContentRankingSortType |     case getContentRankingSortType | ||||||
|  |     case pinContent(contentId: Int) | ||||||
|  |     case unpinContent(contentId: Int) | ||||||
| } | } | ||||||
|  |  | ||||||
| extension ContentApi: TargetType { | extension ContentApi: TargetType { | ||||||
| @@ -117,6 +119,12 @@ extension ContentApi: TargetType { | |||||||
|              |              | ||||||
|         case .getContentRankingSortType: |         case .getContentRankingSortType: | ||||||
|             return  "/audio-content/ranking-sort-type" |             return  "/audio-content/ranking-sort-type" | ||||||
|  |              | ||||||
|  |         case .pinContent(let contentId): | ||||||
|  |             return  "/audio-content/pin-to-the-top/\(contentId)" | ||||||
|  |              | ||||||
|  |         case .unpinContent(let contentId): | ||||||
|  |             return  "/audio-content/unpin-at-the-top/\(contentId)" | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|      |      | ||||||
| @@ -131,10 +139,10 @@ extension ContentApi: TargetType { | |||||||
|         case .getMainBannerList, .getMainOrderList, .getNewContentUploadCreatorList, .getCurationList: |         case .getMainBannerList, .getMainOrderList, .getNewContentUploadCreatorList, .getCurationList: | ||||||
|             return .get |             return .get | ||||||
|              |              | ||||||
|         case .likeContent, .modifyAudioContent, .modifyComment: |         case .likeContent, .modifyAudioContent, .modifyComment, .unpinContent: | ||||||
|             return .put |             return .put | ||||||
|              |              | ||||||
|         case .registerComment, .orderAudioContent, .addAllPlaybackTracking, .uploadAudioContent, .donation: |         case .registerComment, .orderAudioContent, .addAllPlaybackTracking, .uploadAudioContent, .donation, .pinContent: | ||||||
|             return .post |             return .post | ||||||
|              |              | ||||||
|         case .deleteAudioContent: |         case .deleteAudioContent: | ||||||
| @@ -259,6 +267,9 @@ extension ContentApi: TargetType { | |||||||
|             ] as [String : Any] |             ] as [String : Any] | ||||||
|              |              | ||||||
|             return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString) |             return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString) | ||||||
|  |              | ||||||
|  |         case .pinContent, .unpinContent: | ||||||
|  |             return .requestPlain | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|   | |||||||
| @@ -112,4 +112,12 @@ final class ContentRepository { | |||||||
|     func getContentRanking(page: Int, size: Int, sortType: String = "매출") -> AnyPublisher<Response, MoyaError> { |     func getContentRanking(page: Int, size: Int, sortType: String = "매출") -> AnyPublisher<Response, MoyaError> { | ||||||
|         return api.requestPublisher(.getContentRanking(page: page, size: size, sortType: sortType)) |         return api.requestPublisher(.getContentRanking(page: page, size: size, sortType: sortType)) | ||||||
|     } |     } | ||||||
|  |      | ||||||
|  |     func pinContent(contentId: Int) -> AnyPublisher<Response, MoyaError> { | ||||||
|  |         return api.requestPublisher(.pinContent(contentId: contentId)) | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     func unpinContent(contentId: Int) -> AnyPublisher<Response, MoyaError> { | ||||||
|  |         return api.requestPublisher(.unpinContent(contentId: contentId)) | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -11,7 +11,10 @@ struct ContentDetailMenuView: View { | |||||||
|      |      | ||||||
|     @Binding var isShowing: Bool |     @Binding var isShowing: Bool | ||||||
|      |      | ||||||
|  |     let isPin: Bool | ||||||
|     let isShowCreatorMenu: Bool |     let isShowCreatorMenu: Bool | ||||||
|  |      | ||||||
|  |     let pinAction: () -> Void | ||||||
|     let modifyAction: () -> Void |     let modifyAction: () -> Void | ||||||
|     let deleteAction: () -> Void |     let deleteAction: () -> Void | ||||||
|     let reportAction: () -> Void |     let reportAction: () -> Void | ||||||
| @@ -28,7 +31,26 @@ struct ContentDetailMenuView: View { | |||||||
|                  |                  | ||||||
|                 VStack(spacing: 13.3) { |                 VStack(spacing: 13.3) { | ||||||
|                     if isShowCreatorMenu { |                     if isShowCreatorMenu { | ||||||
|                         HStack(spacing: 0) { |                         HStack(spacing: 13.3) { | ||||||
|  |                             Image(isPin ? "ic_pin_cancel" : "ic_pin") | ||||||
|  |                              | ||||||
|  |                             Text(isPin ? "내 채널에 고정 취소" : "내 채널에 고정") | ||||||
|  |                                 .font(.custom(Font.medium.rawValue, size: 16.7)) | ||||||
|  |                                 .foregroundColor(.white) | ||||||
|  |                              | ||||||
|  |                             Spacer() | ||||||
|  |                         } | ||||||
|  |                         .padding(.vertical, 8) | ||||||
|  |                         .padding(.horizontal, 26.7) | ||||||
|  |                         .contentShape(Rectangle()) | ||||||
|  |                         .onTapGesture { | ||||||
|  |                             isShowing = false | ||||||
|  |                             pinAction() | ||||||
|  |                         } | ||||||
|  |                          | ||||||
|  |                         HStack(spacing: 13.3) { | ||||||
|  |                             Image("ic_make_message") | ||||||
|  |                              | ||||||
|                             Text("수정") |                             Text("수정") | ||||||
|                                 .font(.custom(Font.medium.rawValue, size: 16.7)) |                                 .font(.custom(Font.medium.rawValue, size: 16.7)) | ||||||
|                                 .foregroundColor(.white) |                                 .foregroundColor(.white) | ||||||
| @@ -43,7 +65,9 @@ struct ContentDetailMenuView: View { | |||||||
|                             modifyAction() |                             modifyAction() | ||||||
|                         } |                         } | ||||||
|                          |                          | ||||||
|                         HStack(spacing: 0) { |                         HStack(spacing: 13.3) { | ||||||
|  |                             Image("ic_trash_can") | ||||||
|  |                              | ||||||
|                             Text("삭제") |                             Text("삭제") | ||||||
|                                 .font(.custom(Font.medium.rawValue, size: 16.7)) |                                 .font(.custom(Font.medium.rawValue, size: 16.7)) | ||||||
|                                 .foregroundColor(.white) |                                 .foregroundColor(.white) | ||||||
|   | |||||||
| @@ -219,7 +219,19 @@ struct ContentDetailView: View { | |||||||
|                         VStack(spacing: 0) { |                         VStack(spacing: 0) { | ||||||
|                             ContentDetailMenuView( |                             ContentDetailMenuView( | ||||||
|                                 isShowing: $viewModel.isShowReportMenu, |                                 isShowing: $viewModel.isShowReportMenu, | ||||||
|  |                                 isPin: viewModel.audioContent!.isPin, | ||||||
|                                 isShowCreatorMenu: viewModel.audioContent!.creator.creatorId == UserDefaults.int(forKey: .userId), |                                 isShowCreatorMenu: viewModel.audioContent!.creator.creatorId == UserDefaults.int(forKey: .userId), | ||||||
|  |                                 pinAction: { | ||||||
|  |                                     if viewModel.audioContent!.isPin { | ||||||
|  |                                         viewModel.unpinContent(contentId: contentId) | ||||||
|  |                                     } else { | ||||||
|  |                                         if viewModel.audioContent!.isAvailablePin { | ||||||
|  |                                             viewModel.pinContent(contentId: contentId) | ||||||
|  |                                         } else { | ||||||
|  |                                             viewModel.isShowNoticePinContentPopup = true | ||||||
|  |                                         } | ||||||
|  |                                     } | ||||||
|  |                                 }, | ||||||
|                                 modifyAction: { |                                 modifyAction: { | ||||||
|                                     if viewModel.audioContent!.creator.creatorId == UserDefaults.int(forKey: .userId) { |                                     if viewModel.audioContent!.creator.creatorId == UserDefaults.int(forKey: .userId) { | ||||||
|                                         AppState |                                         AppState | ||||||
| @@ -284,6 +296,21 @@ struct ContentDetailView: View { | |||||||
|                             viewModel.donation(can: can, comment: comment) |                             viewModel.donation(can: can, comment: comment) | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  |                      | ||||||
|  |                     if viewModel.isShowNoticePinContentPopup { | ||||||
|  |                         SodaDialog( | ||||||
|  |                             title: "고정 한도 도달", | ||||||
|  |                             desc: "이 콘텐츠를 고정하시겠어요? " + | ||||||
|  |                             "채널에 콘텐츠를 최대 3개까지 고정할 수 있습니다." + | ||||||
|  |                             "이 콘텐츠를 고정하면 가장 오래된 콘텐츠가 대체됩니다.", | ||||||
|  |                             confirmButtonTitle: "확인", | ||||||
|  |                             confirmButtonAction: { | ||||||
|  |                                 viewModel.pinContent(contentId: contentId) | ||||||
|  |                             }, | ||||||
|  |                             cancelButtonTitle: "취소", | ||||||
|  |                             cancelButtonAction: {} | ||||||
|  |                         ) | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             .sheet( |             .sheet( | ||||||
|   | |||||||
| @@ -34,6 +34,7 @@ final class ContentDetailViewModel: ObservableObject { | |||||||
|     @Published var isShowReportMenu = false |     @Published var isShowReportMenu = false | ||||||
|     @Published var isShowReportView = false |     @Published var isShowReportView = false | ||||||
|     @Published var isShowDeleteConfirm = false |     @Published var isShowDeleteConfirm = false | ||||||
|  |     @Published var isShowNoticePinContentPopup = false | ||||||
|      |      | ||||||
|     var contentId: Int = 0 { |     var contentId: Int = 0 { | ||||||
|         didSet { |         didSet { | ||||||
| @@ -448,4 +449,84 @@ final class ContentDetailViewModel: ObservableObject { | |||||||
|                 .store(in: &subscription) |                 .store(in: &subscription) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |      | ||||||
|  |     func pinContent(contentId: Int) { | ||||||
|  |         isLoading = true | ||||||
|  |         repository.pinContent(contentId: contentId) | ||||||
|  |             .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 | ||||||
|  |                          | ||||||
|  |                         self.getAudioContentDetail() | ||||||
|  |                     } 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 unpinContent(contentId: Int) { | ||||||
|  |         isLoading = true | ||||||
|  |         repository.unpinContent(contentId: contentId) | ||||||
|  |             .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 | ||||||
|  |                          | ||||||
|  |                         self.getAudioContentDetail() | ||||||
|  |                     } 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) | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -32,6 +32,8 @@ struct GetAudioContentDetailResponse: Decodable { | |||||||
|     let likeCount: Int |     let likeCount: Int | ||||||
|     let commentList: [GetAudioContentCommentListItem] |     let commentList: [GetAudioContentCommentListItem] | ||||||
|     let commentCount: Int |     let commentCount: Int | ||||||
|  |     let isPin: Bool | ||||||
|  |     let isAvailablePin: Bool | ||||||
|     let creator: AudioContentCreator |     let creator: AudioContentCreator | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -67,7 +67,7 @@ struct CreatorCommunityAllView: View { | |||||||
|                 ZStack { |                 ZStack { | ||||||
|                     if viewModel.isShowReportMenu { |                     if viewModel.isShowReportMenu { | ||||||
|                         VStack(spacing: 0) { |                         VStack(spacing: 0) { | ||||||
|                             ContentDetailMenuView( |                             CreatorCommunityMenuView( | ||||||
|                                 isShowing: $viewModel.isShowReportMenu, |                                 isShowing: $viewModel.isShowReportMenu, | ||||||
|                                 isShowCreatorMenu: creatorId == UserDefaults.int(forKey: .userId), |                                 isShowCreatorMenu: creatorId == UserDefaults.int(forKey: .userId), | ||||||
|                                 modifyAction: { |                                 modifyAction: { | ||||||
|   | |||||||
| @@ -0,0 +1,97 @@ | |||||||
|  | // | ||||||
|  | //  CreatorCommunityMenuView.swift | ||||||
|  | //  SodaLive | ||||||
|  | // | ||||||
|  | //  Created by klaus on 1/29/24. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | import SwiftUI | ||||||
|  |  | ||||||
|  | struct CreatorCommunityMenuView: View { | ||||||
|  |     @Binding var isShowing: Bool | ||||||
|  |      | ||||||
|  |     let isShowCreatorMenu: Bool | ||||||
|  |      | ||||||
|  |     let modifyAction: () -> Void | ||||||
|  |     let deleteAction: () -> Void | ||||||
|  |     let reportAction: () -> Void | ||||||
|  |      | ||||||
|  |     var body: some View { | ||||||
|  |         ZStack { | ||||||
|  |             Color.black | ||||||
|  |                 .opacity(0.7) | ||||||
|  |                 .ignoresSafeArea() | ||||||
|  |                 .onTapGesture { isShowing = false } | ||||||
|  |              | ||||||
|  |             VStack(spacing: 0) { | ||||||
|  |                 Spacer() | ||||||
|  |                  | ||||||
|  |                 VStack(spacing: 13.3) { | ||||||
|  |                     if isShowCreatorMenu { | ||||||
|  |                         HStack(spacing: 13.3) { | ||||||
|  |                             Image("ic_make_message") | ||||||
|  |                              | ||||||
|  |                             Text("수정") | ||||||
|  |                                 .font(.custom(Font.medium.rawValue, size: 16.7)) | ||||||
|  |                                 .foregroundColor(.white) | ||||||
|  |                              | ||||||
|  |                             Spacer() | ||||||
|  |                         } | ||||||
|  |                         .padding(.vertical, 8) | ||||||
|  |                         .padding(.horizontal, 26.7) | ||||||
|  |                         .contentShape(Rectangle()) | ||||||
|  |                         .onTapGesture { | ||||||
|  |                             isShowing = false | ||||||
|  |                             modifyAction() | ||||||
|  |                         } | ||||||
|  |                          | ||||||
|  |                         HStack(spacing: 13.3) { | ||||||
|  |                             Image("ic_trash_can") | ||||||
|  |                              | ||||||
|  |                             Text("삭제") | ||||||
|  |                                 .font(.custom(Font.medium.rawValue, size: 16.7)) | ||||||
|  |                                 .foregroundColor(.white) | ||||||
|  |                              | ||||||
|  |                             Spacer() | ||||||
|  |                         } | ||||||
|  |                         .padding(.vertical, 8) | ||||||
|  |                         .padding(.horizontal, 26.7) | ||||||
|  |                         .contentShape(Rectangle()) | ||||||
|  |                         .onTapGesture { | ||||||
|  |                             isShowing = false | ||||||
|  |                             deleteAction() | ||||||
|  |                         } | ||||||
|  |                     } else { | ||||||
|  |                         HStack(spacing: 0) { | ||||||
|  |                             Text("신고") | ||||||
|  |                                 .font(.custom(Font.medium.rawValue, size: 16.7)) | ||||||
|  |                                 .foregroundColor(.white) | ||||||
|  |                              | ||||||
|  |                             Spacer() | ||||||
|  |                         } | ||||||
|  |                         .padding(.vertical, 8) | ||||||
|  |                         .padding(.horizontal, 26.7) | ||||||
|  |                         .contentShape(Rectangle()) | ||||||
|  |                         .onTapGesture { | ||||||
|  |                             isShowing = false | ||||||
|  |                             reportAction() | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 .padding(24) | ||||||
|  |                 .background(Color(hex: "222222")) | ||||||
|  |                 .cornerRadius(13.3, corners: [.topLeft, .topRight]) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #Preview { | ||||||
|  |     CreatorCommunityMenuView( | ||||||
|  |         isShowing: .constant(true), | ||||||
|  |         isShowCreatorMenu: true, | ||||||
|  |         modifyAction: {}, | ||||||
|  |         deleteAction: {}, | ||||||
|  |         reportAction: {} | ||||||
|  |     ) | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user
	 Yu Sung
					Yu Sung