diff --git a/Mixonomer.xcodeproj/project.pbxproj b/Mixonomer.xcodeproj/project.pbxproj index 37369ab..ea2fa0a 100644 --- a/Mixonomer.xcodeproj/project.pbxproj +++ b/Mixonomer.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ A10C8D29281302050018AE12 /* ToastUI in Frameworks */ = {isa = PBXBuildFile; productRef = A10C8D28281302050018AE12 /* ToastUI */; }; A11AC70628A188AE00645043 /* AuthApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11AC70528A188AE00645043 /* AuthApi.swift */; }; + A1DBCDA628A51869002CF730 /* AdminList.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1DBCDA528A51869002CF730 /* AdminList.swift */; }; E906F7F42414019C004E1E31 /* NetworkPersister.swift in Sources */ = {isa = PBXBuildFile; fileRef = E906F7F32414019C004E1E31 /* NetworkPersister.swift */; }; E906F7F724143AA7004E1E31 /* SwiftUICharts in Frameworks */ = {isa = PBXBuildFile; productRef = E906F7F624143AA7004E1E31 /* SwiftUICharts */; }; E934AC99240DD0E4009869F4 /* AddTagSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = E934AC98240DD0E4009869F4 /* AddTagSheet.swift */; }; @@ -65,6 +66,7 @@ /* Begin PBXFileReference section */ A11AC70528A188AE00645043 /* AuthApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthApi.swift; sourceTree = ""; }; A146915A28118F940052999D /* Mixonomer.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Mixonomer.entitlements; sourceTree = ""; }; + A1DBCDA528A51869002CF730 /* AdminList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminList.swift; sourceTree = ""; }; E906F7F32414019C004E1E31 /* NetworkPersister.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkPersister.swift; sourceTree = ""; }; E934AC98240DD0E4009869F4 /* AddTagSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddTagSheet.swift; sourceTree = ""; }; E971F8B8245462D500B543B6 /* Router.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Router.swift; sourceTree = ""; }; @@ -133,6 +135,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + A1DBCDA428A5184D002CF730 /* Admin */ = { + isa = PBXGroup; + children = ( + A1DBCDA528A51869002CF730 /* AdminList.swift */, + ); + path = Admin; + sourceTree = ""; + }; E98254BE23F9BD540056D9D3 /* Model */ = { isa = PBXGroup; children = ( @@ -160,6 +170,7 @@ E98254C023F9FFDD0056D9D3 /* Views */ = { isa = PBXGroup; children = ( + A1DBCDA428A5184D002CF730 /* Admin */, E9E30C3423FF256100574EEF /* Settings */, E9E30C2F23FEACF700574EEF /* Tag */, E9E30C2E23FEACDE00574EEF /* Playlist */, @@ -431,6 +442,7 @@ E9CCD5BD2454C64300B5CD6C /* TagList.swift in Sources */, E9E30C2A23FEAA3A00574EEF /* TagRow.swift in Sources */, E9CCD5BB2454C57300B5CD6C /* PlaylistList.swift in Sources */, + A1DBCDA628A51869002CF730 /* AdminList.swift in Sources */, E97AF46023FC85D600635494 /* PlaylistApi.swift in Sources */, A11AC70628A188AE00645043 /* AuthApi.swift in Sources */, E9EA690F23F9A5430012C3E8 /* AppSkeleton.swift in Sources */, diff --git a/Mixonomer/Model/LiveUser.swift b/Mixonomer/Model/LiveUser.swift index 8409cf0..6f60308 100644 --- a/Mixonomer/Model/LiveUser.swift +++ b/Mixonomer/Model/LiveUser.swift @@ -15,6 +15,7 @@ class LiveUser: ObservableObject { @Published var playlists: [Playlist] @Published var tags: [Tag] @Published var username: String + @Published var user: User? @Published var loggedIn: Bool { didSet { @@ -22,6 +23,7 @@ class LiveUser: ObservableObject { } } + @Published var isRefreshingUser = false @Published var isRefreshingPlaylists = false @Published var isRefreshingTags = false @@ -39,17 +41,48 @@ class LiveUser: ObservableObject { self.playlists[index] = playlistIn } - func refreshPlaylists() { + func refreshUser(onSuccess: (() -> Void)? = nil, onFailure: (() -> Void)? = nil) { + self.isRefreshingUser = true + + let api = UserApi.getUser + RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in + + if self.checkNetworkResponse(response: response) { + + guard let data = response.data else { + fatalError("error getting user") + } + + guard let json = try? JSON(data: data) else { + fatalError("error parsing user") + } + + // update state + self.user = UserApi.fromJSON(user: json) + + self.isRefreshingUser = false + + if let success = onSuccess { + success() + } + + } else { + + if let failure = onFailure { + failure() + } + } + } + } + + func refreshPlaylists(onSuccess: (() -> Void)? = nil, onFailure: (() -> Void)? = nil) { self.isRefreshingPlaylists = true let api = PlaylistApi.getPlaylists RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in - self.checkNetworkResponse(response: response) - - switch response.response?.statusCode { - case 200, 201: - + if self.checkNetworkResponse(response: response) { + guard let data = response.data else { fatalError("error getting playlists") } @@ -65,6 +98,10 @@ class LiveUser: ObservableObject { self.isRefreshingPlaylists = false + if let success = onSuccess { + success() + } + let encoder = JSONEncoder() do { UserDefaults.standard.set(String(data: try encoder.encode(playlists), encoding: .utf8), forKey: "playlists") @@ -72,23 +109,23 @@ class LiveUser: ObservableObject { print("error encoding playlists: \(error)") } - case _: - break + } else { + + if let failure = onFailure { + failure() + } } } } - func refreshTags() { + func refreshTags(onSuccess: (() -> Void)? = nil, onFailure: (() -> Void)? = nil) { self.isRefreshingTags = true let api = TagApi.getTags RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in - self.checkNetworkResponse(response: response) - - switch response.response?.statusCode { - case 200, 201: - + if self.checkNetworkResponse(response: response) { + guard let data = response.data else { fatalError("error getting tags") } @@ -104,6 +141,10 @@ class LiveUser: ObservableObject { self.isRefreshingTags = false + if let success = onSuccess { + success() + } + let encoder = JSONEncoder() do { UserDefaults.standard.set(String(data: try encoder.encode(tags), encoding: .utf8), forKey: "tags") @@ -111,20 +152,32 @@ class LiveUser: ObservableObject { print("error encoding tags: \(error)") } - case _: - break + } else { + + if let failure = onFailure { + failure() + } } } } - func checkNetworkResponse(response: AFDataResponse) { + func checkNetworkResponse(response: AFDataResponse) -> Bool { - switch response.response?.statusCode { - case 401: - self.loggedIn = false - case _: - print("error making request") + if let statusCode = response.response?.statusCode { + switch statusCode { + case 401: // token has expired + self.loggedIn = false + return false + case 400..<500: + return false + case 500..<600: + return false + case _: // 200 -> Success + return true + } } + + return false } func loadUserDefaults() -> LiveUser { diff --git a/Mixonomer/Model/Playlist.swift b/Mixonomer/Model/Playlist.swift index 87f3b07..06a91b8 100644 --- a/Mixonomer/Model/Playlist.swift +++ b/Mixonomer/Model/Playlist.swift @@ -116,7 +116,7 @@ class Playlist: Identifiable, Equatable, Codable, ObservableObject { func updatePlaylist(updates: JSON) { let api = PlaylistApi.updatePlaylist(name: self.name, updates: updates) - RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in + RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in switch response.response?.statusCode { case 200, 201: break @@ -269,13 +269,13 @@ class Playlist: Identifiable, Equatable, Codable, ObservableObject { do{ description_overwrite = try container.decode(String.self, forKey: .description_overwrite) }catch { - debugPrint("no description overwrite") +// debugPrint("no description overwrite") } do{ description_suffix = try container.decode(String.self, forKey: .description_suffix) }catch { - debugPrint("no description suffix") +// debugPrint("no description suffix") } last_updated = try container.decode(String.self, forKey: .last_updated) diff --git a/Mixonomer/Model/User.swift b/Mixonomer/Model/User.swift index ab3d923..5ea1f2d 100644 --- a/Mixonomer/Model/User.swift +++ b/Mixonomer/Model/User.swift @@ -23,6 +23,8 @@ class User: Identifiable, Decodable { var type: UserType var last_login: String + var last_keygen: String + var spotify_linked: Bool var lastfm_username: String? @@ -33,6 +35,7 @@ class User: Identifiable, Decodable { type: UserType = .user, last_login: String, + last_keygen: String, spotify_linked: Bool, lastfm_username: String?){ @@ -41,6 +44,7 @@ class User: Identifiable, Decodable { self.type = type self.last_login = last_login + self.last_keygen = last_keygen self.spotify_linked = spotify_linked self.lastfm_username = lastfm_username } diff --git a/Mixonomer/Network/PlaylistApi.swift b/Mixonomer/Network/PlaylistApi.swift index 53e88d6..6a03a7f 100644 --- a/Mixonomer/Network/PlaylistApi.swift +++ b/Mixonomer/Network/PlaylistApi.swift @@ -144,7 +144,6 @@ extension PlaylistApi: ApiRequest { print(error) } } - print(playlist) return nil } diff --git a/Mixonomer/Network/TagApi.swift b/Mixonomer/Network/TagApi.swift index 5de4999..43a44b0 100644 --- a/Mixonomer/Network/TagApi.swift +++ b/Mixonomer/Network/TagApi.swift @@ -30,7 +30,7 @@ extension TagApi: ApiRequest { return "api/tag" case .runTag(let tag_id): return "api/tag/\(tag_id)/update" - case .updateTag(let tag_id): + case .updateTag(let tag_id, _): return "api/tag/\(tag_id)" case .deleteTag(let tag_id): return "api/tag/\(tag_id)" @@ -64,7 +64,7 @@ extension TagApi: ApiRequest { return nil case .runTag: return nil - case .updateTag(let _, let updates): + case .updateTag(_, let updates): return updates case .deleteTag: return nil diff --git a/Mixonomer/Views/Admin/AdminList.swift b/Mixonomer/Views/Admin/AdminList.swift new file mode 100644 index 0000000..064b9be --- /dev/null +++ b/Mixonomer/Views/Admin/AdminList.swift @@ -0,0 +1,29 @@ +// +// AdminList.swift +// Mixonomer +// +// Created by Andy Pack on 11/08/2022. +// Copyright © 2022 Sarsoo. All rights reserved. +// + +import SwiftUI + +struct AdminList: View { + var body: some View { + NavigationView { + List{ + Section { + + } + } + .listStyle(GroupedListStyle()) + .navigationBarTitle(Text("Admin 🚨")) + } + } +} + +struct AdminList_Previews: PreviewProvider { + static var previews: some View { + AdminList() + } +} diff --git a/Mixonomer/Views/AppSkeleton.swift b/Mixonomer/Views/AppSkeleton.swift index 17953b4..1e0d20f 100644 --- a/Mixonomer/Views/AppSkeleton.swift +++ b/Mixonomer/Views/AppSkeleton.swift @@ -28,14 +28,31 @@ struct AppSkeleton: View { } .tag(0) - TagList() - .tabItem { - VStack { - Image(systemName: "tag") - Text("Tags") - } + if let user = liveUser.user { + if let _ = user.lastfm_username { + TagList() + .tabItem { + VStack { + Image(systemName: "tag") + Text("Tags") + } + } + .tag(1) } - .tag(1) + } + + if let user = liveUser.user { + if user.type == .admin { + AdminList() + .tabItem( { + VStack { + Image(systemName: "person.badge.key.fill") + Text("Admin") + } + }) + .tag(2) + } + } SettingsList() .tabItem { @@ -44,7 +61,7 @@ struct AppSkeleton: View { Text("Settings") } } - .tag(2) + .tag(3) }.onAppear { self.fetchAll() @@ -52,6 +69,7 @@ struct AppSkeleton: View { } private func fetchAll() { + self.liveUser.refreshUser() self.liveUser.refreshPlaylists() self.liveUser.refreshTags() } @@ -60,5 +78,6 @@ struct AppSkeleton: View { struct RootView_Previews: PreviewProvider { static var previews: some View { AppSkeleton() + .environmentObject(LiveUser(playlists: [], tags: [], username: "user", loggedIn: false)) } } diff --git a/Mixonomer/Views/LoginScreen.swift b/Mixonomer/Views/LoginScreen.swift index 2452b14..44050bd 100644 --- a/Mixonomer/Views/LoginScreen.swift +++ b/Mixonomer/Views/LoginScreen.swift @@ -184,6 +184,11 @@ struct LoginScreen: View { .buttonStyle(.bordered) } } + .toast(isPresented: $showingToast, dismissAfter: 3.0){ + ToastView(toastText) + .toastViewStyle(.failure) + } + .toastDimmedBackground(false) .padding() } } diff --git a/Mixonomer/Views/Playlist/AddPlaylistSheet.swift b/Mixonomer/Views/Playlist/AddPlaylistSheet.swift index 4298d5b..1ebb1ad 100644 --- a/Mixonomer/Views/Playlist/AddPlaylistSheet.swift +++ b/Mixonomer/Views/Playlist/AddPlaylistSheet.swift @@ -94,19 +94,16 @@ struct AddPlaylistSheet: View { type: PlaylistType(rawValue: selectedType) ?? .defaultPlaylist) RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in - self.liveUser.checkNetworkResponse(response: response) - - switch response.response?.statusCode { - case 200, 201: - + if self.liveUser.checkNetworkResponse(response: response) { + self.playlists.append(playlist) self.playlists = self.playlists.sorted(by: { $0.name.lowercased() < $1.name.lowercased() }) self.isLoading = false self.presentationMode.wrappedValue.dismiss() - case _: - break + } else { + } } } @@ -115,5 +112,6 @@ struct AddPlaylistSheet: View { struct AddPlaylistSheet_Previews: PreviewProvider { static var previews: some View { AddPlaylistSheet(playlists: .constant([]), username: .constant("username")) + .environmentObject(LiveUser(playlists: [], tags: [], username: "user", loggedIn: false)) } } diff --git a/Mixonomer/Views/Playlist/PlaylistList.swift b/Mixonomer/Views/Playlist/PlaylistList.swift index c217ce3..0d1c277 100644 --- a/Mixonomer/Views/Playlist/PlaylistList.swift +++ b/Mixonomer/Views/Playlist/PlaylistList.swift @@ -7,12 +7,17 @@ // import SwiftUI +import ToastUI struct PlaylistList: View { @EnvironmentObject var liveUser: LiveUser @State private var showAdd = false // State for showing add modal view + @State private var showingToast = false + @State private var toastText = "" + @State private var toastSuccess = true + var body: some View { NavigationView { List{ @@ -25,13 +30,11 @@ struct PlaylistList: View { indexSet.forEach { index in let api = PlaylistApi.deletePlaylist(name: self.liveUser.playlists[index].name) RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in - self.liveUser.checkNetworkResponse(response: response) - switch response.response?.statusCode { - case 200, 201: - break - case _: - break + if self.liveUser.checkNetworkResponse(response: response) { + + } else { + } } } @@ -44,7 +47,19 @@ struct PlaylistList: View { } .refreshable { - self.liveUser.refreshPlaylists() + self.liveUser.refreshPlaylists(onSuccess: { + + toastText = "Refreshed!" + toastSuccess = true + showingToast = true + + }, onFailure: { + + toastText = "Refresh Failed" + toastSuccess = false + showingToast = true + + }) } .navigationBarTitle(Text("Playlists 📻")) .navigationBarItems(trailing: @@ -55,6 +70,18 @@ struct PlaylistList: View { AddPlaylistSheet(playlists: self.$liveUser.playlists, username: self.$liveUser.username) } ) + .toast(isPresented: $showingToast, dismissAfter: 3.0){ + + if toastSuccess { + ToastView(toastText) + .toastViewStyle(.success) + } + else { + ToastView(toastText) + .toastViewStyle(.failure) + } + } + .toastDimmedBackground(false) } } } @@ -62,5 +89,6 @@ struct PlaylistList: View { struct PlaylistList_Previews: PreviewProvider { static var previews: some View { PlaylistList() + .environmentObject(LiveUser(playlists: [], tags: [], username: "user", loggedIn: false)) } } diff --git a/Mixonomer/Views/Playlist/PlaylistRow.swift b/Mixonomer/Views/Playlist/PlaylistRow.swift index 39f0657..36da480 100644 --- a/Mixonomer/Views/Playlist/PlaylistRow.swift +++ b/Mixonomer/Views/Playlist/PlaylistRow.swift @@ -31,14 +31,12 @@ struct PlaylistRow: View { .validate() .responseJSON{ response in - self.liveUser.checkNetworkResponse(response: response) + if self.liveUser.checkNetworkResponse(response: response) { - switch response.response?.statusCode { - case 200, 201: - break - case _: - self.showingNetworkError = true - } + } + else { + self.showingNetworkError = true + } } }) { Text("Refresh") @@ -65,5 +63,6 @@ struct PlaylistRow_Previews: PreviewProvider { PlaylistView(playlist: .constant( Playlist(name: "playlist name", username: "username") )) + .environmentObject(LiveUser(playlists: [], tags: [], username: "user", loggedIn: false)) } } diff --git a/Mixonomer/Views/Playlist/PlaylistView.swift b/Mixonomer/Views/Playlist/PlaylistView.swift index 638619c..3852564 100644 --- a/Mixonomer/Views/Playlist/PlaylistView.swift +++ b/Mixonomer/Views/Playlist/PlaylistView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import ToastUI import SwiftyJSON import SwiftUICharts @@ -17,7 +18,11 @@ struct PlaylistView: View { @State private var showingSheet = false @State private var isRefreshing = false - @State private var showingNetworkError = false + + // TOAST + @State private var showingToast = false + @State private var toastText = "" + @State private var toastSuccess = true var chartStyle: ChartStyle { get { @@ -194,14 +199,18 @@ struct PlaylistView: View { Text("Open") } } - - - // alert seems to need to be within list root element - // else weird crash on half drag back - .alert(isPresented: $showingNetworkError) { - Alert(title: Text("Network Error"), - message: Text("Could not refresh playlist")) + .toast(isPresented: $showingToast, dismissAfter: 3.0){ + + if toastSuccess { + ToastView(toastText) + .toastViewStyle(.success) + } + else { + ToastView(toastText) + .toastViewStyle(.failure) + } } + .toastDimmedBackground(false) } .navigationBarTitle(Text(playlist.name)) @@ -216,32 +225,39 @@ struct PlaylistView: View { .validate() .responseJSON{ response in - self.liveUser.checkNetworkResponse(response: response) + if self.liveUser.checkNetworkResponse(response: response) { - switch response.response?.statusCode { - case 200, 201: - break - case _: - self.showingNetworkError = true - } + toastText = "Running!" + toastSuccess = true + showingToast = true + + } else { + + toastText = "Run Request Failed" + toastSuccess = false + showingToast = true + } } - //TODO: do better error checking } func refreshStats() { let api = PlaylistApi.refreshStats(name: playlist.name) RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in - self.liveUser.checkNetworkResponse(response: response) - - switch response.response?.statusCode { - case 200, 201: - break - case _: - break + if self.liveUser.checkNetworkResponse(response: response) { + + toastText = "Refreshing Stats!" + toastSuccess = true + showingToast = true + + } else { + + toastText = "Stat Refresh Failed" + toastSuccess = false + showingToast = true + } } - //TODO: do better error checking } func openPlaylist() { @@ -254,12 +270,9 @@ struct PlaylistView: View { let api = PlaylistApi.updatePlaylist(name: playlist.name, updates: updates) RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in - self.liveUser.checkNetworkResponse(response: response) - - switch response.response?.statusCode { - case 200, 201: + if self.liveUser.checkNetworkResponse(response: response) { debugPrint("success") - case _: + } else { debugPrint("error") } } @@ -270,10 +283,7 @@ struct PlaylistView: View { let api = PlaylistApi.getPlaylist(name: self.playlist.name) RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in - self.liveUser.checkNetworkResponse(response: response) - - switch response.response?.statusCode { - case 200, 201: + if self.liveUser.checkNetworkResponse(response: response) { guard let data = response.data else { fatalError("error getting playlist") @@ -281,13 +291,20 @@ struct PlaylistView: View { self.playlist = PlaylistApi.fromJSON(playlist: data)! - case _: - break + toastText = "Refreshed!" + toastSuccess = true + showingToast = true + + } else { + + toastText = "Refresh Failed" + toastSuccess = false + showingToast = true + } self.isRefreshing = false } - //TODO: do better error checking } } @@ -301,6 +318,7 @@ struct PlaylistView_Previews: PreviewProvider { lastfm_stat_artist_percent: 80 ) )) + .environmentObject(LiveUser(playlists: [], tags: [], username: "user", loggedIn: false)) } } diff --git a/Mixonomer/Views/Tag/AddTagSheet.swift b/Mixonomer/Views/Tag/AddTagSheet.swift index b2263ed..235989d 100644 --- a/Mixonomer/Views/Tag/AddTagSheet.swift +++ b/Mixonomer/Views/Tag/AddTagSheet.swift @@ -76,19 +76,16 @@ struct AddTagSheet: View { let api = TagApi.newTag(tag_id: tag_id) RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in - self.liveUser.checkNetworkResponse(response: response) - - switch response.response?.statusCode { - case 200, 201: - + if self.liveUser.checkNetworkResponse(response: response) { + self.tags.append(tag) self.tags = self.tags.sorted(by: { $0.name.lowercased() < $1.name.lowercased() }) self.isLoading = false self.presentationMode.wrappedValue.dismiss() - case _: - break + } else { + } } } @@ -97,5 +94,6 @@ struct AddTagSheet: View { struct AddTagSheet_Previews: PreviewProvider { static var previews: some View { AddTagSheet(tags: .constant([]), username: .constant("username")) + .environmentObject(LiveUser(playlists: [], tags: [], username: "user", loggedIn: false)) } } diff --git a/Mixonomer/Views/Tag/TagList.swift b/Mixonomer/Views/Tag/TagList.swift index c4ffb3d..ecc8313 100644 --- a/Mixonomer/Views/Tag/TagList.swift +++ b/Mixonomer/Views/Tag/TagList.swift @@ -7,12 +7,17 @@ // import SwiftUI +import ToastUI struct TagList: View { @EnvironmentObject var liveUser: LiveUser @State private var showAdd = false // State for showing add modal view + @State private var showingToast = false + @State private var toastText = "" + @State private var toastSuccess = true + var body: some View { NavigationView { List{ @@ -26,13 +31,11 @@ struct TagList: View { let api = TagApi.deleteTag(tag_id: self.liveUser.tags[index].tag_id) RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in - self.liveUser.checkNetworkResponse(response: response) - - switch response.response?.statusCode { - case 200, 201: - break - case _: - break + if self.liveUser.checkNetworkResponse(response: response) { + + } + else { + } } } @@ -44,7 +47,19 @@ struct TagList: View { } } .refreshable { - self.liveUser.refreshTags() + self.liveUser.refreshTags(onSuccess: { + + toastText = "Refreshed!" + toastSuccess = true + showingToast = true + + }, onFailure: { + + toastText = "Refresh Failed" + toastSuccess = false + showingToast = true + + }) } .navigationBarTitle(Text("Tags 🎷")) .navigationBarItems( @@ -59,6 +74,18 @@ struct TagList: View { AddTagSheet(tags: self.$liveUser.tags, username: self.$liveUser.username) } ) + .toast(isPresented: $showingToast, dismissAfter: 3.0){ + + if toastSuccess { + ToastView(toastText) + .toastViewStyle(.success) + } + else { + ToastView(toastText) + .toastViewStyle(.failure) + } + } + .toastDimmedBackground(false) } } } @@ -66,5 +93,6 @@ struct TagList: View { struct TagList_Previews: PreviewProvider { static var previews: some View { TagList() + .environmentObject(LiveUser(playlists: [], tags: [], username: "user", loggedIn: false)) } } diff --git a/Mixonomer/Views/Tag/TagRow.swift b/Mixonomer/Views/Tag/TagRow.swift index 5f0b772..be3b91f 100644 --- a/Mixonomer/Views/Tag/TagRow.swift +++ b/Mixonomer/Views/Tag/TagRow.swift @@ -31,12 +31,9 @@ struct TagRow: View { .validate() .responseJSON{ response in - self.liveUser.checkNetworkResponse(response: response) - - switch response.response?.statusCode { - case 200, 201: - break - case _: + if self.liveUser.checkNetworkResponse(response: response) { + + } else { self.showingNetworkError = true } } @@ -69,5 +66,6 @@ struct TagRow_Previews: PreviewProvider { last_updated: "10th Feb") )) + .environmentObject(LiveUser(playlists: [], tags: [], username: "user", loggedIn: false)) } } diff --git a/Mixonomer/Views/Tag/TagView.swift b/Mixonomer/Views/Tag/TagView.swift index ff3c780..ca6017a 100644 --- a/Mixonomer/Views/Tag/TagView.swift +++ b/Mixonomer/Views/Tag/TagView.swift @@ -120,13 +120,10 @@ struct TagView: View { let api = TagApi.runTag(tag_id: tag.tag_id) RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in - self.liveUser.checkNetworkResponse(response: response) - - switch response.response?.statusCode { - case 200, 201: - break - case _: - break + if self.liveUser.checkNetworkResponse(response: response) { + + } else { + } } //TODO: do better error checking @@ -136,13 +133,10 @@ struct TagView: View { let api = TagApi.updateTag(tag_id: tag.tag_id, updates: updates) RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in - self.liveUser.checkNetworkResponse(response: response) - - switch response.response?.statusCode { - case 200, 201: - break - case _: - break + if self.liveUser.checkNetworkResponse(response: response) { + + } else { + } } //TODO: do better error checking @@ -152,10 +146,7 @@ struct TagView: View { let api = TagApi.getTag(tag_id: self.tag.tag_id) RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in - self.liveUser.checkNetworkResponse(response: response) - - switch response.response?.statusCode { - case 200, 201: + if self.liveUser.checkNetworkResponse(response: response) { guard let data = response.data else { fatalError("error getting tag") @@ -169,8 +160,8 @@ struct TagView: View { self.tag = tag } - case _: - break + } else { + } self.isRefreshing = false @@ -196,5 +187,6 @@ struct TagView_Previews: PreviewProvider { last_updated: "10th Feb") )) + .environmentObject(LiveUser(playlists: [], tags: [], username: "user", loggedIn: false)) } }