재생 목록 상세

- 삭제 기능 추가
This commit is contained in:
Yu Sung 2024-12-10 03:44:49 +09:00
parent d03fee372a
commit 8d60e500c0
4 changed files with 115 additions and 1 deletions

View File

@ -23,4 +23,8 @@ class ContentPlaylistListRepository {
func getPlaylistDetail(playlistId: Int) -> AnyPublisher<Response, MoyaError> { func getPlaylistDetail(playlistId: Int) -> AnyPublisher<Response, MoyaError> {
return api.requestPublisher(.getPlaylistDetail(playlistId: playlistId)) return api.requestPublisher(.getPlaylistDetail(playlistId: playlistId))
} }
func deletePlaylist(playlistId: Int) -> AnyPublisher<Response, MoyaError> {
return api.requestPublisher(.deletePlaylist(playlistId: playlistId))
}
} }

View File

@ -15,6 +15,9 @@ struct ContentPlaylistDetailView: View {
@Binding var isShowing: Bool @Binding var isShowing: Bool
@Binding var reloadData: Bool @Binding var reloadData: Bool
@State private var isShowPopupMenu = false
@State private var isShowDeleteConfirm = false
var body: some View { var body: some View {
BaseView(isLoading: $viewModel.isLoading) { BaseView(isLoading: $viewModel.isLoading) {
VStack(spacing: 21.3) { VStack(spacing: 21.3) {
@ -37,6 +40,7 @@ struct ContentPlaylistDetailView: View {
Image("ic_seemore_vertical_white") Image("ic_seemore_vertical_white")
.padding(8) .padding(8)
.onTapGesture { .onTapGesture {
isShowPopupMenu = true
} }
} }
.padding(.horizontal, 13.3) .padding(.horizontal, 13.3)
@ -184,6 +188,61 @@ struct ContentPlaylistDetailView: View {
.onAppear { .onAppear {
viewModel.playlistId = playlistId 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 }
)
}
}
} }
} }
} }

View File

@ -64,4 +64,48 @@ final class ContentPlaylistDetailViewModel: ObservableObject {
} }
.store(in: &subscription) .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)
}
} }

View File

@ -12,6 +12,7 @@ enum PlaylistApi {
case getPlaylistList case getPlaylistList
case createPlaylist(request: CreatePlaylistRequest) case createPlaylist(request: CreatePlaylistRequest)
case getPlaylistDetail(playlistId: Int) case getPlaylistDetail(playlistId: Int)
case deletePlaylist(playlistId: Int)
} }
extension PlaylistApi: TargetType { extension PlaylistApi: TargetType {
@ -26,6 +27,9 @@ extension PlaylistApi: TargetType {
case .getPlaylistDetail(let playlistId): case .getPlaylistDetail(let playlistId):
return "/audio-content/playlist/\(playlistId)" return "/audio-content/playlist/\(playlistId)"
case .deletePlaylist(let playlistId):
return "/audio-content/playlist/\(playlistId)"
} }
} }
@ -36,12 +40,15 @@ extension PlaylistApi: TargetType {
case .createPlaylist: case .createPlaylist:
return .post return .post
case .deletePlaylist:
return .delete
} }
} }
var task: Moya.Task { var task: Moya.Task {
switch self { switch self {
case .getPlaylistList, .getPlaylistDetail: case .getPlaylistList, .getPlaylistDetail, .deletePlaylist:
return .requestPlain return .requestPlain
case .createPlaylist(let request): case .createPlaylist(let request):