Show errors when handling playlists

This commit is contained in:
Arkadiusz Fal 2021-12-17 20:53:05 +01:00
parent 923f0c0356
commit 201e91a3cc
3 changed files with 71 additions and 24 deletions

View File

@ -52,14 +52,22 @@ final class PlaylistsModel: ObservableObject {
} }
} }
func addVideo(playlistID: Playlist.ID, videoID: Video.ID, onSuccess: @escaping () -> Void = {}) { func addVideo(
playlistID: Playlist.ID,
videoID: Video.ID,
onSuccess: @escaping () -> Void = {},
onFailure: @escaping (RequestError) -> Void = { _ in }
) {
let resource = accounts.api.playlistVideos(playlistID) let resource = accounts.api.playlistVideos(playlistID)
let body = ["videoId": videoID] let body = ["videoId": videoID]
resource?.request(.post, json: body).onSuccess { _ in resource?
.request(.post, json: body)
.onSuccess { _ in
self.load(force: true) self.load(force: true)
onSuccess() onSuccess()
} }
.onFailure(onFailure)
} }
func removeVideo(videoIndexID: String, playlistID: Playlist.ID, onSuccess: @escaping () -> Void = {}) { func removeVideo(videoIndexID: String, playlistID: Playlist.ID, onSuccess: @escaping () -> Void = {}) {

View File

@ -7,8 +7,12 @@ struct AddToPlaylistView: View {
@State private var selectedPlaylistID: Playlist.ID = "" @State private var selectedPlaylistID: Playlist.ID = ""
@State private var error = ""
@State private var presentingErrorAlert = false
@Environment(\.colorScheme) private var colorScheme @Environment(\.colorScheme) private var colorScheme
@Environment(\.presentationMode) private var presentationMode @Environment(\.presentationMode) private var presentationMode
@EnvironmentObject<PlaylistsModel> private var model @EnvironmentObject<PlaylistsModel> private var model
var body: some View { var body: some View {
@ -120,6 +124,12 @@ struct AddToPlaylistView: View {
Button("Add to Playlist", action: addToPlaylist) Button("Add to Playlist", action: addToPlaylist)
.disabled(selectedPlaylist.isNil) .disabled(selectedPlaylist.isNil)
.padding(.top, 30) .padding(.top, 30)
.alert(isPresented: $presentingErrorAlert) {
Alert(
title: Text("Error when accessing playlist"),
message: Text(error)
)
}
#if !os(tvOS) #if !os(tvOS)
.keyboardShortcut(.defaultAction) .keyboardShortcut(.defaultAction)
#endif #endif
@ -155,9 +165,17 @@ struct AddToPlaylistView: View {
Defaults[.lastUsedPlaylistID] = id Defaults[.lastUsedPlaylistID] = id
model.addVideo(playlistID: id, videoID: video.videoID) { model.addVideo(
playlistID: id,
videoID: video.videoID,
onSuccess: {
presentationMode.wrappedValue.dismiss() presentationMode.wrappedValue.dismiss()
},
onFailure: { requestError in
error = "(\(requestError.httpStatusCode ?? -1)) \(requestError.userMessage)"
presentingErrorAlert = true
} }
)
} }
private var selectedPlaylist: Playlist? { private var selectedPlaylist: Playlist? {

View File

@ -8,7 +8,10 @@ struct PlaylistFormView: View {
@State private var visibility = Playlist.Visibility.public @State private var visibility = Playlist.Visibility.public
@State private var valid = false @State private var valid = false
@State private var showingDeleteConfirmation = false @State private var presentingDeleteConfirmation = false
@State private var formError = ""
@State private var presentingErrorAlert = false
@Environment(\.colorScheme) private var colorScheme @Environment(\.colorScheme) private var colorScheme
@Environment(\.presentationMode) private var presentationMode @Environment(\.presentationMode) private var presentationMode
@ -57,6 +60,12 @@ struct PlaylistFormView: View {
Button("Save", action: submitForm) Button("Save", action: submitForm)
.disabled(!valid) .disabled(!valid)
.alert(isPresented: $presentingErrorAlert) {
Alert(
title: Text("Error when accessing playlist"),
message: Text(formError)
)
}
.keyboardShortcut(.defaultAction) .keyboardShortcut(.defaultAction)
} }
.frame(minHeight: 35) .frame(minHeight: 35)
@ -165,7 +174,9 @@ struct PlaylistFormView: View {
let body = ["title": name, "privacy": visibility.rawValue] let body = ["title": name, "privacy": visibility.rawValue]
resource?.request(editing ? .patch : .post, json: body).onSuccess { response in resource?
.request(editing ? .patch : .post, json: body)
.onSuccess { response in
if let modifiedPlaylist: Playlist = response.typedContent() { if let modifiedPlaylist: Playlist = response.typedContent() {
playlist = modifiedPlaylist playlist = modifiedPlaylist
} }
@ -174,6 +185,10 @@ struct PlaylistFormView: View {
presentationMode.wrappedValue.dismiss() presentationMode.wrappedValue.dismiss()
} }
.onFailure { error in
formError = "(\(error.httpStatusCode ?? -1)) \(error.userMessage)"
presentingErrorAlert = true
}
} }
var resource: Resource? { var resource: Resource? {
@ -207,9 +222,9 @@ struct PlaylistFormView: View {
var deletePlaylistButton: some View { var deletePlaylistButton: some View {
Button("Delete") { Button("Delete") {
showingDeleteConfirmation = true presentingDeleteConfirmation = true
} }
.alert(isPresented: $showingDeleteConfirmation) { .alert(isPresented: $presentingDeleteConfirmation) {
Alert( Alert(
title: Text("Are you sure you want to delete playlist?"), title: Text("Are you sure you want to delete playlist?"),
message: Text("Playlist \"\(playlist.title)\" will be deleted.\nIt cannot be undone."), message: Text("Playlist \"\(playlist.title)\" will be deleted.\nIt cannot be undone."),
@ -221,11 +236,17 @@ struct PlaylistFormView: View {
} }
func deletePlaylistAndDismiss() { func deletePlaylistAndDismiss() {
accounts.api.playlist(playlist.id)?.request(.delete).onSuccess { _ in accounts.api.playlist(playlist.id)?
.request(.delete)
.onSuccess { _ in
playlist = nil playlist = nil
playlists.load(force: true) playlists.load(force: true)
presentationMode.wrappedValue.dismiss() presentationMode.wrappedValue.dismiss()
} }
.onFailure { error in
formError = "(\(error.httpStatusCode ?? -1)) \(error.localizedDescription)"
presentingErrorAlert = true
}
} }
} }