diff --git a/Music Tools.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Music Tools.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/Music Tools.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/Music Tools/Model/LiveUser.swift b/Music Tools/Model/LiveUser.swift index 7ae0381..c76aec1 100644 --- a/Music Tools/Model/LiveUser.swift +++ b/Music Tools/Model/LiveUser.swift @@ -54,9 +54,8 @@ class LiveUser: ObservableObject { self.isRefreshingPlaylists = false let encoder = JSONEncoder() - let defaults = UserDefaults.standard do { - defaults.set(String(data: try encoder.encode(playlists), encoding: .utf8), forKey: "playlists") + UserDefaults.standard.set(String(data: try encoder.encode(playlists), encoding: .utf8), forKey: "playlists") } catch { print("error encoding playlists: \(error)") } @@ -85,9 +84,8 @@ class LiveUser: ObservableObject { self.isRefreshingTags = false let encoder = JSONEncoder() - let defaults = UserDefaults.standard do { - defaults.set(String(data: try encoder.encode(tags), encoding: .utf8), forKey: "tags") + UserDefaults.standard.set(String(data: try encoder.encode(tags), encoding: .utf8), forKey: "tags") } catch { print("error encoding tags: \(error)") } @@ -103,11 +101,15 @@ class LiveUser: ObservableObject { do { if let _strPlaylists = _strPlaylists { - self.playlists = (try decoder.decode([Playlist].self, from: _strPlaylists.data(using: .utf8)!)).sorted(by: { $0.name.lowercased() < $1.name.lowercased() }) + if _strPlaylists.count > 0 { + self.playlists = (try decoder.decode([Playlist].self, from: _strPlaylists.data(using: .utf8)!)).sorted(by: { $0.name.lowercased() < $1.name.lowercased() }) + } } if let _strTags = _strTags { - self.tags = (try decoder.decode([Tag].self, from: _strTags.data(using: .utf8)!)).sorted(by: { $0.name.lowercased() < $1.name.lowercased() }) + if _strTags.count > 0 { + self.tags = (try decoder.decode([Tag].self, from: _strTags.data(using: .utf8)!)).sorted(by: { $0.name.lowercased() < $1.name.lowercased() }) + } } } catch { print("error decoding: \(error)") diff --git a/Music Tools/Model/Playlist.swift b/Music Tools/Model/Playlist.swift index 00c3071..b64928c 100644 --- a/Music Tools/Model/Playlist.swift +++ b/Music Tools/Model/Playlist.swift @@ -30,7 +30,7 @@ class Playlist: Identifiable, Equatable, Codable { var description_overwrite: String? var description_suffix: String? - var last_updated: String + var last_updated: String? var lastfm_stat_count: Int var lastfm_stat_album_count: Int @@ -55,7 +55,7 @@ class Playlist: Identifiable, Equatable, Codable { } } - var lastfm_stat_last_refresh: String + var lastfm_stat_last_refresh: String? private enum CodingKeys: String, CodingKey { case name @@ -105,7 +105,7 @@ class Playlist: Identifiable, Equatable, Codable { description_overwrite: String? = nil, description_suffix: String? = nil, - last_updated: String = "", + last_updated: String? = "", lastfm_stat_count: Int = 0, lastfm_stat_album_count: Int = 0, @@ -115,23 +115,11 @@ class Playlist: Identifiable, Equatable, Codable { lastfm_stat_album_percent: Float = 0, lastfm_stat_artist_percent: Float = 0, - lastfm_stat_last_refresh: String = ""){ + lastfm_stat_last_refresh: String? = ""){ self.name = name self.uri = uri self.username = username - - self.include_recommendations = include_recommendations - self.recommendation_sample = recommendation_sample - self.include_library_tracks = include_library_tracks - - self.parts = parts - self.playlist_references = playlist_references - self.shuffle = shuffle - - self.sort = sort - self.description_overwrite = description_overwrite - self.description_suffix = description_suffix self.last_updated = last_updated @@ -144,6 +132,18 @@ class Playlist: Identifiable, Equatable, Codable { self.lastfm_stat_artist_percent = lastfm_stat_artist_percent self.lastfm_stat_last_refresh = lastfm_stat_last_refresh + + self.include_recommendations = include_recommendations + self.recommendation_sample = recommendation_sample + self.include_library_tracks = include_library_tracks + + self.parts = parts + self.playlist_references = playlist_references + self.shuffle = shuffle + + self.sort = sort + self.description_overwrite = description_overwrite + self.description_suffix = description_suffix } var link: String { @@ -162,15 +162,6 @@ class Playlist: Identifiable, Equatable, Codable { uri = try container.decode(String.self, forKey: .uri) // username = try container.decode(String.self, forKey: .username) - include_recommendations = try container.decode(Bool.self, forKey: .include_recommendations) - recommendation_sample = try container.decode(Int.self, forKey: .recommendation_sample) - include_library_tracks = try container.decode(Bool.self, forKey: .include_library_tracks) - - parts = try container.decode([String].self, forKey: .parts) - playlist_references = try container.decode([String].self, forKey: .playlist_references) - shuffle = try container.decode(Bool.self, forKey: .shuffle) - - sort = try container.decode(String.self, forKey: .sort) // description_overwrite = try container.decode(String.self, forKey: .description_overwrite) // description_suffix = try container.decode(String.self, forKey: .description_suffix) @@ -186,6 +177,15 @@ class Playlist: Identifiable, Equatable, Codable { lastfm_stat_last_refresh = try container.decode(String.self, forKey: .lastfm_stat_last_refresh) + include_recommendations = try container.decode(Bool.self, forKey: .include_recommendations) + recommendation_sample = try container.decode(Int.self, forKey: .recommendation_sample) + include_library_tracks = try container.decode(Bool.self, forKey: .include_library_tracks) + + parts = try container.decode([String].self, forKey: .parts) + playlist_references = try container.decode([String].self, forKey: .playlist_references) + shuffle = try container.decode(Bool.self, forKey: .shuffle) + + sort = try container.decode(String.self, forKey: .sort) } } diff --git a/Music Tools/Model/Tag.swift b/Music Tools/Model/Tag.swift index fbeb398..3f99b3f 100644 --- a/Music Tools/Model/Tag.swift +++ b/Music Tools/Model/Tag.swift @@ -9,7 +9,7 @@ import UIKit import SwiftyJSON -class Tag: Identifiable, Equatable, Decodable { +class Tag: Identifiable, Equatable, Codable { //MARK: Properties @@ -31,7 +31,7 @@ class Tag: Identifiable, Equatable, Decodable { var proportion: Double var total_user_scrobbles: Int - var last_updated: String + var last_updated: String? //MARK: Initialization @@ -47,7 +47,7 @@ class Tag: Identifiable, Equatable, Decodable { proportion: Double, total_user_scrobbles: Int, - last_updated: String){ + last_updated: String?){ self.tag_id = tag_id self.name = name diff --git a/Music Tools/Network/NetworkPersister.swift b/Music Tools/Network/NetworkPersister.swift index f93f502..29202e3 100644 --- a/Music Tools/Network/NetworkPersister.swift +++ b/Music Tools/Network/NetworkPersister.swift @@ -8,27 +8,30 @@ import Foundation -@propertyWrapper -struct NetworkPersister: Codable { - - enum ObjectType: String, Codable { - case playlist - case tag - case user - } - - var objType: ObjectType - var key: String -// -// init(_ objType: ObjectType, key: String) { -// self.objType = objType -// self.key = key -// } - - var wrappedValue: Value { - didSet { - print("set") - } - } - +enum ObjectType: String, Codable { + case playlist + case tag + case user } + +//@propertyWrapper public struct NetworkPersister: Codable { +// +//// var objType: ObjectType +//// var key: String +//// var value: Value +// +//// var sets = 0 +// +//// public init(wrappedValue: Value) { +////// self.objType = objType +////// self.key = key +//// self.value = wrappedValue +//// } +// +// public var wrappedValue: Value { +// didSet(newValue) { +// print(newValue) +// } +// } +// +//} diff --git a/Music Tools/Views/Playlist/AddPlaylistSheet.swift b/Music Tools/Views/Playlist/AddPlaylistSheet.swift index 337bd78..7eaec28 100644 --- a/Music Tools/Views/Playlist/AddPlaylistSheet.swift +++ b/Music Tools/Views/Playlist/AddPlaylistSheet.swift @@ -16,7 +16,8 @@ struct AddPlaylistSheet: View { @State private var errorMessage = "" @State private var isLoading = false - @Binding var state: Bool + @Environment(\.presentationMode) var presentationMode + @Binding var playlists: Array @Binding var username: String @@ -95,13 +96,13 @@ struct AddPlaylistSheet: View { self.playlists = self.playlists.sorted(by: { $0.name.lowercased() < $1.name.lowercased() }) self.isLoading = false - self.state = false + self.presentationMode.wrappedValue.dismiss() } } } struct AddPlaylistSheet_Previews: PreviewProvider { static var previews: some View { - AddPlaylistSheet(state: .constant(true), playlists: .constant([]), username: .constant("username")) + AddPlaylistSheet(playlists: .constant([]), username: .constant("username")) } } diff --git a/Music Tools/Views/Playlist/PlaylistInputList.swift b/Music Tools/Views/Playlist/PlaylistInputList.swift index 9fb451c..64735c7 100644 --- a/Music Tools/Views/Playlist/PlaylistInputList.swift +++ b/Music Tools/Views/Playlist/PlaylistInputList.swift @@ -15,12 +15,12 @@ struct Name: Identifiable, Hashable { struct PlaylistInputList: View { - var names: Array = [] + @Binding var names: [String] var nameType: String - init(names: Array, nameType: String){ + init(names: Binding<[String]>, nameType: String){ self.nameType = nameType - self.names = names.sorted(by: { $0.lowercased() < $1.lowercased() }) + self._names = names } var body: some View { @@ -52,8 +52,8 @@ struct PlaylistInputList: View { struct PlaylistInputList_Previews: PreviewProvider { static var previews: some View { - PlaylistInputList(names: [ + PlaylistInputList(names: .constant([ "name" - ], nameType: "Spotify Playlists") + ]), nameType: "Spotify Playlists") } } diff --git a/Music Tools/Views/Playlist/PlaylistView.swift b/Music Tools/Views/Playlist/PlaylistView.swift index a01dc67..f121a53 100644 --- a/Music Tools/Views/Playlist/PlaylistView.swift +++ b/Music Tools/Views/Playlist/PlaylistView.swift @@ -163,7 +163,7 @@ struct PlaylistView: View { } } Section(header: Text("Inputs")){ - NavigationLink(destination: PlaylistInputList(names: self.playlist.playlist_references, nameType: "Managed Playlists")) { + NavigationLink(destination: PlaylistInputList(names: self.$playlist.playlist_references, nameType: "Managed Playlists")) { HStack { Text("Managed Playlists") Spacer() @@ -172,7 +172,7 @@ struct PlaylistView: View { } } - NavigationLink(destination: PlaylistInputList(names: self.playlist.parts, nameType: "Spotify Playlists")) { + NavigationLink(destination: PlaylistInputList(names: self.$playlist.parts, nameType: "Spotify Playlists")) { HStack { Text("Spotify Playlists") Spacer() @@ -183,8 +183,8 @@ struct PlaylistView: View { } Section(header: Text("Actions"), footer: VStack(alignment: .leading) { - Text("Last Updated \(self.playlist.last_updated)") - Text("Stats Updated \(self.playlist.lastfm_stat_last_refresh)") + Text("Last Updated \(self.playlist.last_updated ?? "never")") + Text("Stats Updated \(self.playlist.lastfm_stat_last_refresh ?? "never")") }){ Button(action: { self.runPlaylist() }) { Text("Update") diff --git a/Music Tools/Views/RootView.swift b/Music Tools/Views/RootView.swift index eca3da0..a81cca6 100644 --- a/Music Tools/Views/RootView.swift +++ b/Music Tools/Views/RootView.swift @@ -59,7 +59,7 @@ struct RootView: View { action: { self.showAdd = true }, label: { Text("Add") } ).sheet(isPresented: $showAdd) { - AddPlaylistSheet(state: self.$showAdd, playlists: self.$liveUser.playlists, username: self.$liveUser.username) + AddPlaylistSheet(playlists: self.$liveUser.playlists, username: self.$liveUser.username) } ) } @@ -108,7 +108,7 @@ struct RootView: View { action: { self.showAdd = true }, label: { Text("Add") } ).sheet(isPresented: $showAdd) { - AddTagSheet(state: self.$showAdd, tags: self.$liveUser.tags, username: self.$liveUser.username) + AddTagSheet(tags: self.$liveUser.tags, username: self.$liveUser.username) } ) } diff --git a/Music Tools/Views/Tag/AddTagSheet.swift b/Music Tools/Views/Tag/AddTagSheet.swift index a0f40f2..bebd5ea 100644 --- a/Music Tools/Views/Tag/AddTagSheet.swift +++ b/Music Tools/Views/Tag/AddTagSheet.swift @@ -15,7 +15,8 @@ struct AddTagSheet: View { @State private var errorMessage = "" @State private var isLoading = false - @Binding var state: Bool + @Environment(\.presentationMode) var presentationMode + @Binding var tags: Array @Binding var username: String @@ -49,7 +50,6 @@ struct AddTagSheet: View { } func create(){ - debugPrint(name) let tag_id = self.$name.wrappedValue.replacingOccurrences(of: " ", with: "_") if tag_id.count == 0 { @@ -78,13 +78,13 @@ struct AddTagSheet: View { self.tags = self.tags.sorted(by: { $0.name.lowercased() < $1.name.lowercased() }) self.isLoading = false - self.state = false + self.presentationMode.wrappedValue.dismiss() } } } struct AddTagSheet_Previews: PreviewProvider { static var previews: some View { - AddTagSheet(state: .constant(true), tags: .constant([]), username: .constant("username")) + AddTagSheet(tags: .constant([]), username: .constant("username")) } } diff --git a/Music Tools/Views/Tag/TagView.swift b/Music Tools/Views/Tag/TagView.swift index 4b783ef..de6ef6e 100644 --- a/Music Tools/Views/Tag/TagView.swift +++ b/Music Tools/Views/Tag/TagView.swift @@ -104,7 +104,7 @@ struct TagView: View { Spacer() } Section(header: Text("Actions"), - footer: Text("Last Updated \(self.tag.last_updated)")){ + footer: Text("Last Updated \(self.tag.last_updated ?? "never")")){ Button(action: { self.runTag() }) { Text("Update") }