using environment for sheet dismissal, binding playlist part names
This commit is contained in:
parent
4e8668a4b2
commit
49e558fa85
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>PreviewsEnabled</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
@ -54,9 +54,8 @@ class LiveUser: ObservableObject {
|
|||||||
self.isRefreshingPlaylists = false
|
self.isRefreshingPlaylists = false
|
||||||
|
|
||||||
let encoder = JSONEncoder()
|
let encoder = JSONEncoder()
|
||||||
let defaults = UserDefaults.standard
|
|
||||||
do {
|
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 {
|
} catch {
|
||||||
print("error encoding playlists: \(error)")
|
print("error encoding playlists: \(error)")
|
||||||
}
|
}
|
||||||
@ -85,9 +84,8 @@ class LiveUser: ObservableObject {
|
|||||||
self.isRefreshingTags = false
|
self.isRefreshingTags = false
|
||||||
|
|
||||||
let encoder = JSONEncoder()
|
let encoder = JSONEncoder()
|
||||||
let defaults = UserDefaults.standard
|
|
||||||
do {
|
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 {
|
} catch {
|
||||||
print("error encoding tags: \(error)")
|
print("error encoding tags: \(error)")
|
||||||
}
|
}
|
||||||
@ -103,11 +101,15 @@ class LiveUser: ObservableObject {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
if let _strPlaylists = _strPlaylists {
|
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 {
|
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 {
|
} catch {
|
||||||
print("error decoding: \(error)")
|
print("error decoding: \(error)")
|
||||||
|
@ -30,7 +30,7 @@ class Playlist: Identifiable, Equatable, Codable {
|
|||||||
var description_overwrite: String?
|
var description_overwrite: String?
|
||||||
var description_suffix: String?
|
var description_suffix: String?
|
||||||
|
|
||||||
var last_updated: String
|
var last_updated: String?
|
||||||
|
|
||||||
var lastfm_stat_count: Int
|
var lastfm_stat_count: Int
|
||||||
var lastfm_stat_album_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 {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case name
|
case name
|
||||||
@ -105,7 +105,7 @@ class Playlist: Identifiable, Equatable, Codable {
|
|||||||
description_overwrite: String? = nil,
|
description_overwrite: String? = nil,
|
||||||
description_suffix: String? = nil,
|
description_suffix: String? = nil,
|
||||||
|
|
||||||
last_updated: String = "",
|
last_updated: String? = "",
|
||||||
|
|
||||||
lastfm_stat_count: Int = 0,
|
lastfm_stat_count: Int = 0,
|
||||||
lastfm_stat_album_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_album_percent: Float = 0,
|
||||||
lastfm_stat_artist_percent: Float = 0,
|
lastfm_stat_artist_percent: Float = 0,
|
||||||
|
|
||||||
lastfm_stat_last_refresh: String = ""){
|
lastfm_stat_last_refresh: String? = ""){
|
||||||
|
|
||||||
self.name = name
|
self.name = name
|
||||||
self.uri = uri
|
self.uri = uri
|
||||||
self.username = username
|
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
|
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_artist_percent = lastfm_stat_artist_percent
|
||||||
|
|
||||||
self.lastfm_stat_last_refresh = lastfm_stat_last_refresh
|
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 {
|
var link: String {
|
||||||
@ -162,15 +162,6 @@ class Playlist: Identifiable, Equatable, Codable {
|
|||||||
uri = try container.decode(String.self, forKey: .uri)
|
uri = try container.decode(String.self, forKey: .uri)
|
||||||
// username = try container.decode(String.self, forKey: .username)
|
// 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_overwrite = try container.decode(String.self, forKey: .description_overwrite)
|
||||||
// description_suffix = try container.decode(String.self, forKey: .description_suffix)
|
// 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)
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import SwiftyJSON
|
import SwiftyJSON
|
||||||
|
|
||||||
class Tag: Identifiable, Equatable, Decodable {
|
class Tag: Identifiable, Equatable, Codable {
|
||||||
|
|
||||||
//MARK: Properties
|
//MARK: Properties
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ class Tag: Identifiable, Equatable, Decodable {
|
|||||||
var proportion: Double
|
var proportion: Double
|
||||||
var total_user_scrobbles: Int
|
var total_user_scrobbles: Int
|
||||||
|
|
||||||
var last_updated: String
|
var last_updated: String?
|
||||||
|
|
||||||
//MARK: Initialization
|
//MARK: Initialization
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ class Tag: Identifiable, Equatable, Decodable {
|
|||||||
proportion: Double,
|
proportion: Double,
|
||||||
total_user_scrobbles: Int,
|
total_user_scrobbles: Int,
|
||||||
|
|
||||||
last_updated: String){
|
last_updated: String?){
|
||||||
|
|
||||||
self.tag_id = tag_id
|
self.tag_id = tag_id
|
||||||
self.name = name
|
self.name = name
|
||||||
|
@ -8,27 +8,30 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@propertyWrapper
|
enum ObjectType: String, Codable {
|
||||||
struct NetworkPersister<Value: Codable>: Codable {
|
case playlist
|
||||||
|
case tag
|
||||||
enum ObjectType: String, Codable {
|
case user
|
||||||
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")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//@propertyWrapper public struct NetworkPersister<Value: Codable>: 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)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
@ -16,7 +16,8 @@ struct AddPlaylistSheet: View {
|
|||||||
@State private var errorMessage = ""
|
@State private var errorMessage = ""
|
||||||
@State private var isLoading = false
|
@State private var isLoading = false
|
||||||
|
|
||||||
@Binding var state: Bool
|
@Environment(\.presentationMode) var presentationMode
|
||||||
|
|
||||||
@Binding var playlists: Array<Playlist>
|
@Binding var playlists: Array<Playlist>
|
||||||
@Binding var username: String
|
@Binding var username: String
|
||||||
|
|
||||||
@ -95,13 +96,13 @@ struct AddPlaylistSheet: View {
|
|||||||
self.playlists = self.playlists.sorted(by: { $0.name.lowercased() < $1.name.lowercased() })
|
self.playlists = self.playlists.sorted(by: { $0.name.lowercased() < $1.name.lowercased() })
|
||||||
|
|
||||||
self.isLoading = false
|
self.isLoading = false
|
||||||
self.state = false
|
self.presentationMode.wrappedValue.dismiss()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AddPlaylistSheet_Previews: PreviewProvider {
|
struct AddPlaylistSheet_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
AddPlaylistSheet(state: .constant(true), playlists: .constant([]), username: .constant("username"))
|
AddPlaylistSheet(playlists: .constant([]), username: .constant("username"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,12 +15,12 @@ struct Name: Identifiable, Hashable {
|
|||||||
|
|
||||||
struct PlaylistInputList: View {
|
struct PlaylistInputList: View {
|
||||||
|
|
||||||
var names: Array<String> = []
|
@Binding var names: [String]
|
||||||
var nameType: String
|
var nameType: String
|
||||||
|
|
||||||
init(names: Array<String>, nameType: String){
|
init(names: Binding<[String]>, nameType: String){
|
||||||
self.nameType = nameType
|
self.nameType = nameType
|
||||||
self.names = names.sorted(by: { $0.lowercased() < $1.lowercased() })
|
self._names = names
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@ -52,8 +52,8 @@ struct PlaylistInputList: View {
|
|||||||
|
|
||||||
struct PlaylistInputList_Previews: PreviewProvider {
|
struct PlaylistInputList_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
PlaylistInputList(names: [
|
PlaylistInputList(names: .constant([
|
||||||
"name"
|
"name"
|
||||||
], nameType: "Spotify Playlists")
|
]), nameType: "Spotify Playlists")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ struct PlaylistView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Section(header: Text("Inputs")){
|
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 {
|
HStack {
|
||||||
Text("Managed Playlists")
|
Text("Managed Playlists")
|
||||||
Spacer()
|
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 {
|
HStack {
|
||||||
Text("Spotify Playlists")
|
Text("Spotify Playlists")
|
||||||
Spacer()
|
Spacer()
|
||||||
@ -183,8 +183,8 @@ struct PlaylistView: View {
|
|||||||
}
|
}
|
||||||
Section(header: Text("Actions"),
|
Section(header: Text("Actions"),
|
||||||
footer: VStack(alignment: .leading) {
|
footer: VStack(alignment: .leading) {
|
||||||
Text("Last Updated \(self.playlist.last_updated)")
|
Text("Last Updated \(self.playlist.last_updated ?? "never")")
|
||||||
Text("Stats Updated \(self.playlist.lastfm_stat_last_refresh)")
|
Text("Stats Updated \(self.playlist.lastfm_stat_last_refresh ?? "never")")
|
||||||
}){
|
}){
|
||||||
Button(action: { self.runPlaylist() }) {
|
Button(action: { self.runPlaylist() }) {
|
||||||
Text("Update")
|
Text("Update")
|
||||||
|
@ -59,7 +59,7 @@ struct RootView: View {
|
|||||||
action: { self.showAdd = true },
|
action: { self.showAdd = true },
|
||||||
label: { Text("Add") }
|
label: { Text("Add") }
|
||||||
).sheet(isPresented: $showAdd) {
|
).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 },
|
action: { self.showAdd = true },
|
||||||
label: { Text("Add") }
|
label: { Text("Add") }
|
||||||
).sheet(isPresented: $showAdd) {
|
).sheet(isPresented: $showAdd) {
|
||||||
AddTagSheet(state: self.$showAdd, tags: self.$liveUser.tags, username: self.$liveUser.username)
|
AddTagSheet(tags: self.$liveUser.tags, username: self.$liveUser.username)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,8 @@ struct AddTagSheet: View {
|
|||||||
@State private var errorMessage = ""
|
@State private var errorMessage = ""
|
||||||
@State private var isLoading = false
|
@State private var isLoading = false
|
||||||
|
|
||||||
@Binding var state: Bool
|
@Environment(\.presentationMode) var presentationMode
|
||||||
|
|
||||||
@Binding var tags: Array<Tag>
|
@Binding var tags: Array<Tag>
|
||||||
@Binding var username: String
|
@Binding var username: String
|
||||||
|
|
||||||
@ -49,7 +50,6 @@ struct AddTagSheet: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func create(){
|
func create(){
|
||||||
debugPrint(name)
|
|
||||||
let tag_id = self.$name.wrappedValue.replacingOccurrences(of: " ", with: "_")
|
let tag_id = self.$name.wrappedValue.replacingOccurrences(of: " ", with: "_")
|
||||||
|
|
||||||
if tag_id.count == 0 {
|
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.tags = self.tags.sorted(by: { $0.name.lowercased() < $1.name.lowercased() })
|
||||||
|
|
||||||
self.isLoading = false
|
self.isLoading = false
|
||||||
self.state = false
|
self.presentationMode.wrappedValue.dismiss()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AddTagSheet_Previews: PreviewProvider {
|
struct AddTagSheet_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
AddTagSheet(state: .constant(true), tags: .constant([]), username: .constant("username"))
|
AddTagSheet(tags: .constant([]), username: .constant("username"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ struct TagView: View {
|
|||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
Section(header: Text("Actions"),
|
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() }) {
|
Button(action: { self.runTag() }) {
|
||||||
Text("Update")
|
Text("Update")
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user