diff --git a/SodaLive/Sources/Content/Playlist/ContentPlaylistListRepository.swift b/SodaLive/Sources/Content/Playlist/ContentPlaylistListRepository.swift index 0724c62..b31cae2 100644 --- a/SodaLive/Sources/Content/Playlist/ContentPlaylistListRepository.swift +++ b/SodaLive/Sources/Content/Playlist/ContentPlaylistListRepository.swift @@ -23,4 +23,8 @@ class ContentPlaylistListRepository { func getPlaylistDetail(playlistId: Int) -> AnyPublisher { return api.requestPublisher(.getPlaylistDetail(playlistId: playlistId)) } + + func deletePlaylist(playlistId: Int) -> AnyPublisher { + return api.requestPublisher(.deletePlaylist(playlistId: playlistId)) + } } diff --git a/SodaLive/Sources/Content/Playlist/Detail/ContentPlaylistDetailView.swift b/SodaLive/Sources/Content/Playlist/Detail/ContentPlaylistDetailView.swift index ee72ad5..c2ec741 100644 --- a/SodaLive/Sources/Content/Playlist/Detail/ContentPlaylistDetailView.swift +++ b/SodaLive/Sources/Content/Playlist/Detail/ContentPlaylistDetailView.swift @@ -15,6 +15,9 @@ struct ContentPlaylistDetailView: View { @Binding var isShowing: Bool @Binding var reloadData: Bool + @State private var isShowPopupMenu = false + @State private var isShowDeleteConfirm = false + var body: some View { BaseView(isLoading: $viewModel.isLoading) { VStack(spacing: 21.3) { @@ -37,6 +40,7 @@ struct ContentPlaylistDetailView: View { Image("ic_seemore_vertical_white") .padding(8) .onTapGesture { + isShowPopupMenu = true } } .padding(.horizontal, 13.3) @@ -184,6 +188,61 @@ struct ContentPlaylistDetailView: View { .onAppear { viewModel.playlistId = playlistId } + + if isShowPopupMenu { + ZStack { + Color.black + .opacity(0.7) + .ignoresSafeArea() + .onTapGesture { isShowPopupMenu = false } + + VStack(spacing: 0) { + Spacer() + + HStack(spacing: 13.3) { + Text("삭제") + .font(.custom(Font.medium.rawValue, size: 13.3)) + .foregroundColor(Color.grayee) + + Spacer() + } + .padding(.vertical, 8) + .padding(.horizontal, 26.7) + .contentShape(Rectangle()) + .onTapGesture { + isShowPopupMenu = false + isShowDeleteConfirm = true + } + .padding(24) + .background(Color.gray22) + .cornerRadius(13.3, corners: [.topLeft, .topRight]) + } + } + } + + if isShowDeleteConfirm { + ZStack { + Color.black + .opacity(0.7) + .ignoresSafeArea() + .onTapGesture { isShowDeleteConfirm = false } + + SodaDialog( + title: "재생 목록 삭제", + desc: viewModel.response != nil ? "\(viewModel.response!.title)을 삭제하시겠습니까?" : "삭제하시겠습니까?", + confirmButtonTitle: "삭제", + confirmButtonAction: { + isShowDeleteConfirm = false + viewModel.deletePlaylist { + reloadData = true + isShowing = false + } + }, + cancelButtonTitle: "취소", + cancelButtonAction: { isShowDeleteConfirm = false } + ) + } + } } } } diff --git a/SodaLive/Sources/Content/Playlist/Detail/ContentPlaylistDetailViewModel.swift b/SodaLive/Sources/Content/Playlist/Detail/ContentPlaylistDetailViewModel.swift index 9ac5635..4e88e22 100644 --- a/SodaLive/Sources/Content/Playlist/Detail/ContentPlaylistDetailViewModel.swift +++ b/SodaLive/Sources/Content/Playlist/Detail/ContentPlaylistDetailViewModel.swift @@ -64,4 +64,48 @@ final class ContentPlaylistDetailViewModel: ObservableObject { } .store(in: &subscription) } + + func deletePlaylist(onSuccess: @escaping () -> Void) { + isLoading = true + + repository.deletePlaylist(playlistId: playlistId) + .sink { result in + switch result { + case .finished: + DEBUG_LOG("finish") + case .failure(let error): + ERROR_LOG(error.localizedDescription) + } + } receiveValue: { [unowned self] response in + 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 + } + + self.isLoading = false + } + .store(in: &subscription) + } } diff --git a/SodaLive/Sources/Content/Playlist/PlaylistApi.swift b/SodaLive/Sources/Content/Playlist/PlaylistApi.swift index ff4a592..4e940c2 100644 --- a/SodaLive/Sources/Content/Playlist/PlaylistApi.swift +++ b/SodaLive/Sources/Content/Playlist/PlaylistApi.swift @@ -12,6 +12,7 @@ enum PlaylistApi { case getPlaylistList case createPlaylist(request: CreatePlaylistRequest) case getPlaylistDetail(playlistId: Int) + case deletePlaylist(playlistId: Int) } extension PlaylistApi: TargetType { @@ -26,6 +27,9 @@ extension PlaylistApi: TargetType { case .getPlaylistDetail(let playlistId): return "/audio-content/playlist/\(playlistId)" + + case .deletePlaylist(let playlistId): + return "/audio-content/playlist/\(playlistId)" } } @@ -36,12 +40,15 @@ extension PlaylistApi: TargetType { case .createPlaylist: return .post + + case .deletePlaylist: + return .delete } } var task: Moya.Task { switch self { - case .getPlaylistList, .getPlaylistDetail: + case .getPlaylistList, .getPlaylistDetail, .deletePlaylist: return .requestPlain case .createPlaylist(let request):