implemented codable for network json decoding and userdefault storage
This commit is contained in:
parent
43de19246e
commit
d012566f04
@ -30,7 +30,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
|
||||
var controller: UIViewController
|
||||
if keychain["username"] != nil && keychain["password"] != nil {
|
||||
let liveUser = LiveUser(playlists: [], tags: [], username: keychain["username"]!)
|
||||
let liveUser = LiveUser(playlists: [], tags: [], username: keychain["username"]!).loadUserDefaults()
|
||||
controller = UIHostingController(rootView: contentView.environmentObject(liveUser))
|
||||
} else {
|
||||
let storyboard = UIStoryboard(name: "Main", bundle: nil)
|
||||
|
@ -7,6 +7,8 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Alamofire
|
||||
import SwiftyJSON
|
||||
|
||||
class LiveUser: ObservableObject {
|
||||
|
||||
@ -26,4 +28,80 @@ class LiveUser: ObservableObject {
|
||||
}
|
||||
self.playlists[index] = playlistIn
|
||||
}
|
||||
|
||||
func refreshPlaylists() {
|
||||
let api = PlaylistApi.getPlaylists
|
||||
RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in
|
||||
|
||||
guard let data = response.data else {
|
||||
fatalError("error getting playlists")
|
||||
}
|
||||
|
||||
guard let json = try? JSON(data: data) else {
|
||||
fatalError("error parsing reponse")
|
||||
}
|
||||
|
||||
let playlists = json["playlists"].arrayValue
|
||||
|
||||
// update state
|
||||
self.playlists = PlaylistApi.fromJSON(playlist: playlists).sorted(by: { $0.name.lowercased() < $1.name.lowercased() })
|
||||
|
||||
let encoder = JSONEncoder()
|
||||
let defaults = UserDefaults.standard
|
||||
do {
|
||||
defaults.set(String(data: try encoder.encode(playlists), encoding: .utf8), forKey: "playlists")
|
||||
} catch {
|
||||
print("error encoding playlists: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func refreshTags() {
|
||||
let api = TagApi.getTags
|
||||
RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in
|
||||
|
||||
guard let data = response.data else {
|
||||
fatalError("error getting tags")
|
||||
}
|
||||
|
||||
guard let json = try? JSON(data: data) else {
|
||||
fatalError("error parsing reponse")
|
||||
}
|
||||
|
||||
let tags = json["tags"].arrayValue
|
||||
|
||||
// update state
|
||||
self.tags = TagApi.fromJSON(tag: tags).sorted(by: { $0.name.lowercased() < $1.name.lowercased() })
|
||||
|
||||
let encoder = JSONEncoder()
|
||||
let defaults = UserDefaults.standard
|
||||
do {
|
||||
defaults.set(String(data: try encoder.encode(tags), encoding: .utf8), forKey: "tags")
|
||||
} catch {
|
||||
print("error encoding tags: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func loadUserDefaults() -> LiveUser {
|
||||
let defaults = UserDefaults.standard
|
||||
let decoder = JSONDecoder()
|
||||
|
||||
let _strPlaylists = defaults.string(forKey: "playlists")
|
||||
let _strTags = defaults.string(forKey: "tags")
|
||||
|
||||
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 let _strTags = _strTags {
|
||||
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)")
|
||||
}
|
||||
|
||||
return self
|
||||
}
|
||||
}
|
||||
|
@ -6,16 +6,17 @@
|
||||
// Copyright © 2020 Sarsoo. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import SwiftyJSON
|
||||
|
||||
class Playlist: Identifiable, Equatable {
|
||||
class Playlist: Identifiable, Equatable, Codable {
|
||||
|
||||
//MARK: Properties
|
||||
|
||||
var name: String
|
||||
var uri: String
|
||||
var username: String
|
||||
var username: String?
|
||||
|
||||
var include_recommendations: Bool
|
||||
var recommendation_sample: Int
|
||||
@ -23,89 +24,111 @@ class Playlist: Identifiable, Equatable {
|
||||
|
||||
var parts: Array<String>
|
||||
var playlist_references: Array<String>
|
||||
|
||||
var shuffle: Bool
|
||||
|
||||
var sort: String
|
||||
var description_overwrite: String?
|
||||
var description_suffix: String?
|
||||
|
||||
var last_updated: String
|
||||
|
||||
var lastfm_stat_count: Int
|
||||
var lastfm_stat_album_count: Int
|
||||
var lastfm_stat_artist_count: Int
|
||||
|
||||
var lastfm_stat_percent: Float
|
||||
var lastfm_stat_album_percent: Float
|
||||
var lastfm_stat_artist_percent: Float
|
||||
|
||||
var lastfm_stat_last_refresh: String
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case name
|
||||
case uri
|
||||
case username
|
||||
|
||||
case include_recommendations
|
||||
case recommendation_sample
|
||||
case include_library_tracks
|
||||
|
||||
case parts
|
||||
case playlist_references
|
||||
case shuffle
|
||||
|
||||
case sort
|
||||
case description_overwrite
|
||||
case description_suffix
|
||||
|
||||
case last_updated
|
||||
|
||||
case lastfm_stat_count
|
||||
case lastfm_stat_album_count
|
||||
case lastfm_stat_artist_count
|
||||
|
||||
case lastfm_stat_percent
|
||||
case lastfm_stat_album_percent
|
||||
case lastfm_stat_artist_percent
|
||||
|
||||
case lastfm_stat_last_refresh
|
||||
}
|
||||
|
||||
//MARK: Initialization
|
||||
|
||||
init(name: String,
|
||||
uri: String,
|
||||
username: String,
|
||||
uri: String = "spotify::",
|
||||
username: String = "NO USER",
|
||||
|
||||
include_recommendations: Bool = false,
|
||||
recommendation_sample: Int = 0,
|
||||
include_library_tracks: Bool = false,
|
||||
|
||||
parts: Array<String> = [],
|
||||
playlist_references: Array<String> = [],
|
||||
shuffle: Bool = false,
|
||||
|
||||
include_recommendations: Bool,
|
||||
recommendation_sample: Int,
|
||||
include_library_tracks: Bool,
|
||||
sort: String = "NO SORT",
|
||||
description_overwrite: String? = nil,
|
||||
description_suffix: String? = nil,
|
||||
|
||||
parts: Array<String>,
|
||||
playlist_references: Array<String>,
|
||||
last_updated: String = "",
|
||||
|
||||
shuffle: Bool){
|
||||
|
||||
lastfm_stat_count: Int = 0,
|
||||
lastfm_stat_album_count: Int = 0,
|
||||
lastfm_stat_artist_count: Int = 0,
|
||||
|
||||
lastfm_stat_percent: Float = 0,
|
||||
lastfm_stat_album_percent: Float = 0,
|
||||
lastfm_stat_artist_percent: Float = 0,
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
static func fromDict(dictionary: JSON) -> Playlist? {
|
||||
switch dictionary["type"].string {
|
||||
case "default":
|
||||
return Playlist(name: dictionary["name"].stringValue,
|
||||
uri: dictionary["uri"].stringValue,
|
||||
username: dictionary["username"].stringValue,
|
||||
|
||||
include_recommendations: dictionary["include_recommendations"].boolValue,
|
||||
recommendation_sample: dictionary["recommendation_sample"].intValue,
|
||||
include_library_tracks: dictionary["include_library_tracks"].boolValue,
|
||||
|
||||
parts: dictionary["parts"].arrayObject as! Array<String>,
|
||||
playlist_references: dictionary["playlist_references"].arrayObject as! Array<String>,
|
||||
|
||||
shuffle: dictionary["shuffle"].boolValue)
|
||||
case "recents":
|
||||
return RecentsPlaylist(name: dictionary["name"].stringValue,
|
||||
uri: dictionary["uri"].stringValue,
|
||||
username: dictionary["username"].stringValue,
|
||||
|
||||
include_recommendations: dictionary["include_recommendations"].boolValue,
|
||||
recommendation_sample: dictionary["recommendation_sample"].intValue,
|
||||
include_library_tracks: dictionary["include_library_tracks"].boolValue,
|
||||
self.sort = sort
|
||||
self.description_overwrite = description_overwrite
|
||||
self.description_suffix = description_suffix
|
||||
|
||||
parts: dictionary["parts"].arrayObject as! Array<String>,
|
||||
playlist_references: dictionary["playlist_references"].arrayObject as! Array<String>,
|
||||
|
||||
shuffle: dictionary["shuffle"].boolValue,
|
||||
|
||||
add_last_month: dictionary["add_last_month"].boolValue,
|
||||
add_this_month: dictionary["add_this_month"].boolValue,
|
||||
day_boundary: dictionary["day_boundary"].intValue)
|
||||
case "fmchart":
|
||||
return LastFMChartPlaylist(name: dictionary["name"].stringValue,
|
||||
uri: dictionary["uri"].stringValue,
|
||||
username: dictionary["username"].stringValue,
|
||||
|
||||
include_recommendations: dictionary["include_recommendations"].boolValue,
|
||||
recommendation_sample: dictionary["recommendation_sample"].intValue,
|
||||
include_library_tracks: dictionary["include_library_tracks"].boolValue,
|
||||
self.last_updated = last_updated
|
||||
|
||||
parts: dictionary["parts"].arrayObject as! Array<String>,
|
||||
playlist_references: dictionary["playlist_references"].arrayObject as! Array<String>,
|
||||
|
||||
shuffle: dictionary["shuffle"].boolValue,
|
||||
|
||||
chart_range: LastFmRange(rawValue: dictionary["chart_range"].stringValue)!,
|
||||
chart_limit: dictionary["chart_limit"].intValue)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
self.lastfm_stat_count = lastfm_stat_count
|
||||
self.lastfm_stat_album_count = lastfm_stat_album_count
|
||||
self.lastfm_stat_artist_count = lastfm_stat_artist_count
|
||||
|
||||
self.lastfm_stat_percent = lastfm_stat_percent
|
||||
self.lastfm_stat_album_percent = lastfm_stat_album_percent
|
||||
self.lastfm_stat_artist_percent = lastfm_stat_artist_percent
|
||||
|
||||
self.lastfm_stat_last_refresh = lastfm_stat_last_refresh
|
||||
}
|
||||
|
||||
var link: String {
|
||||
@ -117,6 +140,38 @@ class Playlist: Identifiable, Equatable {
|
||||
return lhs.name == rhs.name
|
||||
// && lhs.username == rhs.username
|
||||
}
|
||||
required init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
name = try container.decode(String.self, forKey: .name)
|
||||
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)
|
||||
|
||||
last_updated = try container.decode(String.self, forKey: .last_updated)
|
||||
|
||||
lastfm_stat_count = try container.decode(Int.self, forKey: .lastfm_stat_count)
|
||||
lastfm_stat_album_count = try container.decode(Int.self, forKey: .lastfm_stat_album_count)
|
||||
lastfm_stat_artist_count = try container.decode(Int.self, forKey: .lastfm_stat_artist_count)
|
||||
|
||||
lastfm_stat_percent = try container.decode(Float.self, forKey: .lastfm_stat_percent)
|
||||
lastfm_stat_album_percent = try container.decode(Float.self, forKey: .lastfm_stat_album_percent)
|
||||
lastfm_stat_artist_percent = try container.decode(Float.self, forKey: .lastfm_stat_artist_percent)
|
||||
|
||||
lastfm_stat_last_refresh = try container.decode(String.self, forKey: .lastfm_stat_last_refresh)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -128,34 +183,36 @@ class RecentsPlaylist: Playlist {
|
||||
var add_this_month: Bool
|
||||
var day_boundary: Int
|
||||
|
||||
private enum CodingKeys: String, CodingKey { case add_last_month; case add_this_month; case day_boundary }
|
||||
|
||||
//MARK: Initialization
|
||||
|
||||
init(name: String,
|
||||
uri: String,
|
||||
username: String,
|
||||
username: String = "NO USER",
|
||||
|
||||
include_recommendations: Bool,
|
||||
recommendation_sample: Int,
|
||||
include_library_tracks: Bool,
|
||||
|
||||
parts: Array<String>,
|
||||
playlist_references: Array<String>,
|
||||
|
||||
shuffle: Bool,
|
||||
|
||||
add_last_month: Bool,
|
||||
add_this_month: Bool,
|
||||
day_boundary: Int){
|
||||
|
||||
add_last_month: Bool = false,
|
||||
add_this_month: Bool = false,
|
||||
day_boundary: Int = 14){
|
||||
|
||||
self.add_last_month = add_last_month
|
||||
self.add_this_month = add_this_month
|
||||
self.day_boundary = day_boundary
|
||||
|
||||
super.init(name: name, uri: uri, username: username, include_recommendations: include_recommendations, recommendation_sample: recommendation_sample, include_library_tracks: include_library_tracks, parts: parts, playlist_references: playlist_references, shuffle: shuffle)
|
||||
super.init(name: name, username: username)
|
||||
}
|
||||
|
||||
required init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
add_last_month = try container.decode(Bool.self, forKey: .add_last_month)
|
||||
add_this_month = try container.decode(Bool.self, forKey: .add_this_month)
|
||||
day_boundary = try container.decode(Int.self, forKey: .day_boundary)
|
||||
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
}
|
||||
|
||||
enum LastFmRange: String {
|
||||
enum LastFmRange: String, Decodable {
|
||||
case overall = "OVERALL"
|
||||
case week = "WEEK"
|
||||
case month = "MONTH"
|
||||
@ -171,27 +228,28 @@ class LastFMChartPlaylist: Playlist {
|
||||
var chart_range: LastFmRange
|
||||
var chart_limit: Int
|
||||
|
||||
private enum CodingKeys: String, CodingKey { case chart_range; case chart_limit }
|
||||
|
||||
//MARK: Initialization
|
||||
|
||||
init(name: String,
|
||||
uri: String,
|
||||
username: String,
|
||||
username: String = "NO USER",
|
||||
|
||||
include_recommendations: Bool,
|
||||
recommendation_sample: Int,
|
||||
include_library_tracks: Bool,
|
||||
|
||||
parts: Array<String>,
|
||||
playlist_references: Array<String>,
|
||||
|
||||
shuffle: Bool,
|
||||
|
||||
chart_range: LastFmRange,
|
||||
chart_limit: Int){
|
||||
|
||||
chart_range: LastFmRange = .overall,
|
||||
chart_limit: Int = 10){
|
||||
|
||||
self.chart_range = chart_range
|
||||
self.chart_limit = chart_limit
|
||||
|
||||
super.init(name: name, uri: uri, username: username, include_recommendations: include_recommendations, recommendation_sample: recommendation_sample, include_library_tracks: include_library_tracks, parts: parts, playlist_references: playlist_references, shuffle: shuffle)
|
||||
super.init(name: name, username: username)
|
||||
}
|
||||
|
||||
required init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
chart_range = try LastFmRange(rawValue: container.decode(String.self, forKey: .chart_range))!
|
||||
chart_limit = try container.decode(Int.self, forKey: .chart_limit)
|
||||
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
import UIKit
|
||||
import SwiftyJSON
|
||||
|
||||
class Tag: Identifiable, Equatable {
|
||||
class Tag: Identifiable, Equatable, Decodable {
|
||||
|
||||
//MARK: Properties
|
||||
|
||||
@ -32,48 +32,32 @@ class Tag: Identifiable, Equatable {
|
||||
init(tag_id: String,
|
||||
name: String,
|
||||
username: String,
|
||||
|
||||
|
||||
tracks: [JSON],
|
||||
albums: [JSON],
|
||||
artists: [JSON],
|
||||
|
||||
|
||||
count: Int,
|
||||
proportion: Double,
|
||||
total_user_scrobbles: Int,
|
||||
|
||||
|
||||
last_updated: String){
|
||||
|
||||
|
||||
self.tag_id = tag_id
|
||||
self.name = name
|
||||
self.username = username
|
||||
|
||||
|
||||
self.tracks = tracks
|
||||
self.albums = albums
|
||||
self.artists = artists
|
||||
|
||||
|
||||
self.count = count
|
||||
self.proportion = proportion
|
||||
self.total_user_scrobbles = total_user_scrobbles
|
||||
|
||||
|
||||
self.last_updated = last_updated
|
||||
}
|
||||
|
||||
static func fromDict(dictionary: JSON) -> Tag {
|
||||
return Tag(tag_id: dictionary["tag_id"].stringValue,
|
||||
name: dictionary["name"].stringValue,
|
||||
username: dictionary["username"].stringValue,
|
||||
|
||||
tracks: dictionary["tracks"].arrayValue,
|
||||
albums: dictionary["albums"].arrayValue,
|
||||
artists: dictionary["artists"].arrayValue,
|
||||
|
||||
count: dictionary["count"].intValue,
|
||||
proportion: dictionary["proportion"].doubleValue,
|
||||
total_user_scrobbles: dictionary["total_user_scrobbles"].intValue,
|
||||
|
||||
last_updated: dictionary["last_updated"].stringValue)
|
||||
}
|
||||
|
||||
static func == (lhs: Tag, rhs: Tag) -> Bool {
|
||||
return lhs.tag_id == rhs.tag_id
|
||||
// && lhs.username == rhs.username
|
||||
|
@ -9,12 +9,12 @@
|
||||
import UIKit
|
||||
import SwiftyJSON
|
||||
|
||||
enum UserType: String {
|
||||
enum UserType: String, Decodable {
|
||||
case user = "user"
|
||||
case admin = "admin"
|
||||
}
|
||||
|
||||
class User: Identifiable {
|
||||
class User: Identifiable, Decodable {
|
||||
|
||||
//MARK: Properties
|
||||
|
||||
@ -43,16 +43,6 @@ class User: Identifiable {
|
||||
self.last_login = last_login
|
||||
self.spotify_linked = spotify_linked
|
||||
self.lastfm_username = lastfm_username
|
||||
}
|
||||
|
||||
static func fromDict(dictionary: JSON) -> User {
|
||||
return User(username: dictionary["username"].stringValue,
|
||||
email: dictionary["username"].stringValue,
|
||||
type: UserType(rawValue: dictionary["type"].stringValue) ?? .user,
|
||||
last_login: dictionary["last_login"].stringValue,
|
||||
spotify_linked: dictionary["spotify_linked"].boolValue,
|
||||
lastfm_username: dictionary["lastfm_username"].stringValue)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,6 +110,68 @@ extension PlaylistApi: ApiRequest {
|
||||
return ApiRequestDefaults.authMethod
|
||||
}
|
||||
|
||||
static func fromJSON(playlist: Data) -> Playlist? {
|
||||
|
||||
let decoder = JSONDecoder()
|
||||
do {
|
||||
let json = try JSON(data: playlist)
|
||||
switch json["type"].string {
|
||||
case "default":
|
||||
let playlist = try decoder.decode(Playlist.self, from: playlist)
|
||||
return playlist
|
||||
case "recents":
|
||||
let playlist = try decoder.decode(RecentsPlaylist.self, from: playlist)
|
||||
return playlist
|
||||
case "fmchart":
|
||||
let playlist = try decoder.decode(LastFMChartPlaylist.self, from: playlist)
|
||||
return playlist
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
} catch {
|
||||
print(error)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
static func fromJSON(playlist: JSON) -> Playlist? {
|
||||
|
||||
let _json = playlist.rawString()?.data(using: .utf8)
|
||||
|
||||
if let data = _json {
|
||||
let decoder = JSONDecoder()
|
||||
do {
|
||||
switch playlist["type"].string {
|
||||
case "default":
|
||||
let playlist = try decoder.decode(Playlist.self, from: data)
|
||||
return playlist
|
||||
case "recents":
|
||||
let playlist = try decoder.decode(RecentsPlaylist.self, from: data)
|
||||
return playlist
|
||||
case "fmchart":
|
||||
let playlist = try decoder.decode(LastFMChartPlaylist.self, from: data)
|
||||
return playlist
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
} catch {
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
print(playlist)
|
||||
return nil
|
||||
}
|
||||
|
||||
static func fromJSON(playlist: [JSON]) -> [Playlist] {
|
||||
var _playlists: [Playlist] = []
|
||||
for dict in playlist {
|
||||
let _iter = self.fromJSON(playlist: dict)
|
||||
if let returned = _iter {
|
||||
_playlists.append(returned)
|
||||
}
|
||||
}
|
||||
return _playlists
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -100,6 +100,32 @@ extension TagApi: ApiRequest {
|
||||
return ApiRequestDefaults.authMethod
|
||||
}
|
||||
|
||||
static func fromJSON(tag: JSON) -> Tag? {
|
||||
|
||||
let _json = tag.rawString()?.data(using: .utf8)
|
||||
|
||||
if let data = _json {
|
||||
let decoder = JSONDecoder()
|
||||
do {
|
||||
let _tag = try decoder.decode(Tag.self, from: data)
|
||||
return _tag
|
||||
} catch {
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO this loop could be condensed
|
||||
static func fromJSON(tag: [JSON]) -> [Tag] {
|
||||
var _tags: [Tag] = []
|
||||
for dict in tag {
|
||||
let _iter = self.fromJSON(tag: dict)
|
||||
if let returned = _iter {
|
||||
_tags.append(returned)
|
||||
}
|
||||
}
|
||||
return _tags
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,13 +77,13 @@ struct AddPlaylistSheet: View {
|
||||
var playlist: Playlist? = nil
|
||||
switch PlaylistType(rawValue: selectedType) ?? .defaultPlaylist {
|
||||
case .defaultPlaylist:
|
||||
playlist = Playlist(name: name, uri: "", username: username, include_recommendations: false, recommendation_sample: 10, include_library_tracks: false, parts: [], playlist_references: [], shuffle: false)
|
||||
playlist = Playlist(name: name, username: username)
|
||||
break
|
||||
case .recents:
|
||||
playlist = RecentsPlaylist(name: name, uri: "", username: username, include_recommendations: false, recommendation_sample: 10, include_library_tracks: false, parts: [], playlist_references: [], shuffle: false, add_last_month: false, add_this_month: false, day_boundary: 14)
|
||||
playlist = RecentsPlaylist(name: name, username: username)
|
||||
break
|
||||
case .fmchart:
|
||||
playlist = LastFMChartPlaylist(name: name, uri: "", username: username, include_recommendations: false, recommendation_sample: 10, include_library_tracks: false, parts: [], playlist_references: [], shuffle: false, chart_range: .month, chart_limit: 10)
|
||||
playlist = LastFMChartPlaylist(name: name, username: username)
|
||||
break
|
||||
}
|
||||
|
||||
|
@ -46,8 +46,8 @@ struct PlaylistRow: View {
|
||||
|
||||
struct PlaylistRow_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
PlaylistRow(playlist:
|
||||
.constant(Playlist(name: "", uri: "", username: "", include_recommendations: true, recommendation_sample: 1, include_library_tracks: true, parts: [], playlist_references: [], shuffle: true))
|
||||
)
|
||||
PlaylistView(playlist: .constant(
|
||||
Playlist(name: "playlist name", username: "username")
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -180,10 +180,7 @@ struct PlaylistView: View {
|
||||
fatalError("error getting playlist")
|
||||
}
|
||||
|
||||
guard let json = try? JSON(data: data) else {
|
||||
fatalError("error parsing reponse")
|
||||
}
|
||||
self.playlist = Playlist.fromDict(dictionary: json)!
|
||||
self.playlist = PlaylistApi.fromJSON(playlist: data)!
|
||||
self.isRefreshing = false
|
||||
}
|
||||
//TODO: do better error checking
|
||||
@ -193,18 +190,7 @@ struct PlaylistView: View {
|
||||
struct PlaylistView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
PlaylistView(playlist: .constant(
|
||||
Playlist(name: "playlist name",
|
||||
uri: "uri",
|
||||
username: "username",
|
||||
|
||||
include_recommendations: true,
|
||||
recommendation_sample: 5,
|
||||
include_library_tracks: true,
|
||||
|
||||
parts: ["name"],
|
||||
playlist_references: ["ref name"],
|
||||
|
||||
shuffle: true)
|
||||
Playlist(name: "playlist name", username: "username")
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,8 @@ struct RootView: View {
|
||||
}
|
||||
}
|
||||
.pullToRefresh(isShowing: $isRefreshingPlaylists) {
|
||||
self.refreshPlaylists()
|
||||
self.liveUser.refreshPlaylists()
|
||||
self.isRefreshingPlaylists = false
|
||||
}
|
||||
.navigationBarTitle(Text("Playlists").font(.title))
|
||||
|
||||
@ -85,7 +86,8 @@ struct RootView: View {
|
||||
}
|
||||
}
|
||||
.pullToRefresh(isShowing: $isRefreshingTags) {
|
||||
self.refreshTags()
|
||||
self.liveUser.refreshTags()
|
||||
self.isRefreshingTags = false
|
||||
}
|
||||
.navigationBarTitle(Text("Tags").font(.title))
|
||||
|
||||
@ -124,61 +126,8 @@ struct RootView: View {
|
||||
}
|
||||
|
||||
private func fetchAll() {
|
||||
refreshPlaylists()
|
||||
refreshTags()
|
||||
}
|
||||
|
||||
public func refreshPlaylists() {
|
||||
let api = PlaylistApi.getPlaylists
|
||||
RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in
|
||||
|
||||
guard let data = response.data else {
|
||||
fatalError("error getting playlists")
|
||||
}
|
||||
|
||||
guard let json = try? JSON(data: data) else {
|
||||
fatalError("error parsing reponse")
|
||||
}
|
||||
|
||||
let playlists = json["playlists"].arrayValue
|
||||
// parse playlists
|
||||
.map({ dict in
|
||||
Playlist.fromDict(dictionary: dict)!
|
||||
})
|
||||
// sort
|
||||
.sorted(by: { $0.name.lowercased() < $1.name.lowercased() })
|
||||
|
||||
// update state
|
||||
self.liveUser.playlists = playlists
|
||||
self.isRefreshingPlaylists = false
|
||||
}
|
||||
//TODO: do better error checking
|
||||
}
|
||||
|
||||
public func refreshTags() {
|
||||
let tagApi = TagApi.getTags
|
||||
RequestBuilder.buildRequest(apiRequest: tagApi).responseJSON{ response in
|
||||
|
||||
guard let data = response.data else {
|
||||
fatalError("error getting playlists")
|
||||
}
|
||||
|
||||
guard let json = try? JSON(data: data) else {
|
||||
fatalError("error parsing reponse")
|
||||
}
|
||||
|
||||
let tags = json["tags"].arrayValue
|
||||
// parse playlists
|
||||
.map({ dict in
|
||||
Tag.fromDict(dictionary: dict)
|
||||
})
|
||||
// sort
|
||||
.sorted(by: { $0.name.lowercased() < $1.name.lowercased() })
|
||||
|
||||
// update state
|
||||
self.liveUser.tags = tags
|
||||
self.isRefreshingTags = false
|
||||
}
|
||||
self.liveUser.refreshPlaylists()
|
||||
self.liveUser.refreshTags()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,10 @@ struct TagView: View {
|
||||
guard let json = try? JSON(data: data) else {
|
||||
fatalError("error parsing reponse")
|
||||
}
|
||||
self.tag = Tag.fromDict(dictionary: json["tag"])
|
||||
let _tag = TagApi.fromJSON(tag: json["tag"])
|
||||
if let tag = _tag {
|
||||
self.tag = tag
|
||||
}
|
||||
self.isRefreshing = false
|
||||
}
|
||||
//TODO: do better error checking
|
||||
|
Loading…
Reference in New Issue
Block a user