diff --git a/Music Tools/Network/PlaylistApi.swift b/Music Tools/Network/PlaylistApi.swift index 6ea9581..83c4cd5 100644 --- a/Music Tools/Network/PlaylistApi.swift +++ b/Music Tools/Network/PlaylistApi.swift @@ -25,6 +25,7 @@ public enum PlaylistApi { case deletePlaylist(name: String) case newPlaylist(name: String, type: PlaylistType) case getPlaylist(name: String) + case refreshStats(name: String) } extension PlaylistApi: ApiRequest { @@ -46,6 +47,8 @@ extension PlaylistApi: ApiRequest { return "api/playlist" case .getPlaylist: return "api/playlist" + case .refreshStats: + return "api/spotfm/playlist/refresh" } } @@ -63,6 +66,8 @@ extension PlaylistApi: ApiRequest { return .put case .getPlaylist: return .get + case .refreshStats: + return .get } } @@ -82,6 +87,8 @@ extension PlaylistApi: ApiRequest { return JSON(["name": name, "type": txTypeHeaders[type.rawValue]]) case .getPlaylist(let name): return JSON(["name": name]) + case .refreshStats(let name): + return JSON(["name": name]) } } @@ -99,6 +106,8 @@ extension PlaylistApi: ApiRequest { return JSONParameterEncoder.default case .getPlaylist: return URLEncodedFormParameterEncoder() + case .refreshStats: + return URLEncodedFormParameterEncoder() } } diff --git a/Music Tools/Views/Playlist/PlaylistView.swift b/Music Tools/Views/Playlist/PlaylistView.swift index 421c360..a01dc67 100644 --- a/Music Tools/Views/Playlist/PlaylistView.swift +++ b/Music Tools/Views/Playlist/PlaylistView.swift @@ -9,6 +9,7 @@ import SwiftUI import SwiftUIRefresh import SwiftyJSON +import SwiftUICharts struct PlaylistView: View { @@ -25,6 +26,13 @@ struct PlaylistView: View { @State private var isRefreshing = false + var chartStyle: ChartStyle { + get { + let _style = ChartStyle(backgroundColor: .white, accentColor: .red, gradientColor: GradientColors.bluPurpl, textColor: .black, legendTextColor: .gray) + return _style + } + } + var body: some View { List { Section(header: Text("Stats")){ @@ -58,7 +66,38 @@ struct PlaylistView: View { .font(.body) .foregroundColor(Color.gray) } + Button(action: { + self.refreshStats() + }){ + Text("Refresh") + } } + + VStack { + HStack { + Spacer() + PieChartView( + data: [Double(self.playlist.lastfm_stat_percent), Double(100 - self.playlist.lastfm_stat_percent)], + title: "Tracks", + legend:"Listening", + style: chartStyle, + form: ChartForm.medium) + PieChartView( + data: [Double(self.playlist.lastfm_stat_album_percent), Double(100 - self.playlist.lastfm_stat_album_percent)], + title: "Albums", + legend:"Listening", + style: chartStyle, + form: ChartForm.medium) + Spacer() + } + PieChartView( + data: [Double(self.playlist.lastfm_stat_artist_percent), Double(100 - self.playlist.lastfm_stat_artist_percent)], + title: "Artists", + legend:"Listening", + style: chartStyle, + form: ChartForm.medium) + } + Section(header: Text("Options")){ Toggle(isOn: self.$playlist.include_recommendations) { Text("Spotify Recommendations") @@ -190,6 +229,14 @@ struct PlaylistView: View { //TODO: do better error checking } + func refreshStats() { + let api = PlaylistApi.refreshStats(name: playlist.name) + RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in + + } + //TODO: do better error checking + } + func openPlaylist() { if let url = URL(string: self.playlist.link) { UIApplication.shared.open(url) diff --git a/Music Tools/Views/Settings/SettingsList.swift b/Music Tools/Views/Settings/SettingsList.swift index 77d2c24..f33c329 100644 --- a/Music Tools/Views/Settings/SettingsList.swift +++ b/Music Tools/Views/Settings/SettingsList.swift @@ -18,29 +18,55 @@ struct SettingsList: View { var body: some View { VStack{ List{ - Button(action: { - if let url = URL(string: "https://music.sarsoo.xyz") { - UIApplication.shared.open(url) + Section { + Button(action: { + if let url = URL(string: "https://music.sarsoo.xyz") { + UIApplication.shared.open(url) + } + }) { + Text("Launch Web Version") } - }) { - Text("Open Web") - } - Button(action: { - let keychain = Keychain(service: "xyz.sarsoo.music.login") - do { - try keychain.remove("username") - try keychain.remove("password") - } catch let error { - debugPrint("Could not clear keychain, \(error)") + Button(action: { + let keychain = Keychain(service: "xyz.sarsoo.music.login") + do { + try keychain.remove("username") + try keychain.remove("password") + } catch let error { + debugPrint("Could not clear keychain, \(error)") + } + }) { + Text("Log out") } - }) { - Text("Log out") } - } - Image("APFooter") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 100.0) + Section( + header: + Text("Development"), + footer: + HStack{ + Spacer() + Image("APFooter") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 100.0) + Spacer() + } + ) { + Button(action: { + if let url = URL(string: "https://github.com/sarsoo/music-tools") { + UIApplication.shared.open(url) + } + }) { + Text("Server Source") + } + Button(action: { + if let url = URL(string: "https://github.com/sarsoo/music-tools-ios") { + UIApplication.shared.open(url) + } + }) { + Text("iOS Source") + } + } + }.listStyle(GroupedListStyle()) } } } diff --git a/Music Tools/Views/Tag/TagView.swift b/Music Tools/Views/Tag/TagView.swift index 6119276..4b783ef 100644 --- a/Music Tools/Views/Tag/TagView.swift +++ b/Music Tools/Views/Tag/TagView.swift @@ -89,11 +89,13 @@ struct TagView: View { .filter { $0["count"].intValue > 0 } - .map { + .sorted { + $0["name"].stringValue.lowercased() < $1["name"].stringValue.lowercased() + }.map { ($0["name"].stringValue, $0["count"].intValue) }), - title: "Scrobbles", - style: chartStyle, + title: self.tag.name, + legend: "Scrobbles", style: chartStyle, form: ChartForm.medium, cornerImage: Image(systemName: "music.note") )