fixing tag loading on full refresh, smart skipping

This commit is contained in:
Andy Pack 2023-01-08 22:22:57 +00:00
parent d25a9d8b88
commit 509aea0b42
Signed by: sarsoo
GPG Key ID: A55BA3536A5E0ED7
3 changed files with 164 additions and 128 deletions

View File

@ -47,9 +47,9 @@ class LiveUser: ObservableObject {
Logger.sys.debug("failed to get APNS token")
}
@Published var isInitiallyRefreshingUser = true
@Published var isInitiallyRefreshingPlaylists = true
@Published var isInitiallyRefreshingTags = true
@Published var isFullRefreshingUser = true
@Published var isFullRefreshingPlaylists = true
@Published var isFullRefreshingTags = true
@Published var isRefreshingUser = false
@Published var isRefreshingPlaylists = false
@ -71,8 +71,10 @@ class LiveUser: ObservableObject {
self.user = user
}
func lastfm_connected() -> Bool {
return username.count > 0
var lastfm_connected: Bool {
get {
return user.lastfm_username.count > 0
}
}
func logout() {
@ -109,154 +111,188 @@ class LiveUser: ObservableObject {
}
func refresh_user(onSuccess: (() -> Void)? = nil, onFailure: (() -> Void)? = nil) {
self.isRefreshingUser = true
Logger.sys.info("refreshing user")
if !isRefreshingUser {
self.isRefreshingUser = true
let api = UserApi.getUser
RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in
Logger.sys.info("refreshing user")
if self.check_network_response(response: response) {
let api = UserApi.getUser
RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in
guard let data = response.data else {
Logger.net.error("error getting user")
return
}
if self.check_network_response(response: response) {
guard let json = try? JSON(data: data) else {
Logger.parse.error("error parsing user")
return
}
guard let data = response.data else {
Logger.net.error("error getting user")
return
}
// update state
self.user = UserApi.fromJSON(user: json)
guard let json = try? JSON(data: data) else {
Logger.parse.error("error parsing user")
return
}
self.isRefreshingUser = false
self.isInitiallyRefreshingUser = false
// update state
self.user = UserApi.fromJSON(user: json)
if let success = onSuccess {
Logger.sys.debug("successfully refreshed user")
success()
}
self.isRefreshingUser = false
self.isFullRefreshingUser = false
} else {
if let success = onSuccess {
Logger.sys.debug("successfully refreshed user")
success()
}
if let failure = onFailure {
Logger.net.error("failed to refresh user")
failure()
} else {
if let failure = onFailure {
Logger.net.error("failed to refresh user")
failure()
}
}
}
}
else
{
Logger.sys.info("skipping refreshing user, already refreshing")
}
}
func refresh_playlists(onSuccess: (() -> Void)? = nil, onFailure: (() -> Void)? = nil) {
self.isRefreshingPlaylists = true
Logger.sys.info("refreshing playlists")
if !isRefreshingPlaylists {
self.isRefreshingPlaylists = true
let api = PlaylistApi.getPlaylists
RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in
Logger.sys.info("refreshing playlists")
if self.check_network_response(response: response) {
let api = PlaylistApi.getPlaylists
RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in
guard let data = response.data else {
Logger.net.error("error getting playlists from net request")
return
}
if self.check_network_response(response: response) {
guard let json = try? JSON(data: data) else {
Logger.parse.error("error parsing playlists reponse")
return
}
guard let data = response.data else {
Logger.net.error("error getting playlists from net request")
return
}
let playlists = json["playlists"].arrayValue
guard let json = try? JSON(data: data) else {
Logger.parse.error("error parsing playlists reponse")
return
}
// update state
self.playlists = PlaylistApi.fromJSON(playlist: playlists).sorted(by: { $0.name.lowercased() < $1.name.lowercased() })
let playlists = json["playlists"].arrayValue
self.isRefreshingPlaylists = false
self.isInitiallyRefreshingPlaylists = false
// update state
self.playlists = PlaylistApi.fromJSON(playlist: playlists).sorted(by: { $0.name.lowercased() < $1.name.lowercased() })
if let success = onSuccess {
Logger.sys.debug("successfully refreshed playlists")
success()
}
self.isRefreshingPlaylists = false
self.isFullRefreshingPlaylists = false
let encoder = JSONEncoder()
do {
UserDefaults.standard.set(String(data: try encoder.encode(playlists), encoding: .utf8), forKey: "playlists")
} catch {
Logger.parse.error("error encoding playlists: \(error)")
}
if let success = onSuccess {
Logger.sys.debug("successfully refreshed playlists")
success()
}
} else {
let encoder = JSONEncoder()
do {
UserDefaults.standard.set(String(data: try encoder.encode(playlists), encoding: .utf8), forKey: "playlists")
} catch {
Logger.parse.error("error encoding playlists: \(error)")
}
if let failure = onFailure {
Logger.net.error("failed to refresh playlists")
failure()
} else {
if let failure = onFailure {
Logger.net.error("failed to refresh playlists")
failure()
}
}
}
}
else
{
Logger.sys.info("skipping refreshing playlists, already refreshing")
}
}
func refresh_tags(onSuccess: (() -> Void)? = nil, onFailure: (() -> Void)? = nil) {
self.isRefreshingTags = true
Logger.sys.info("refreshing tags")
if !isRefreshingTags {
self.isRefreshingTags = true
let api = TagApi.getTags
RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in
Logger.sys.info("refreshing tags")
if self.check_network_response(response: response) {
let api = TagApi.getTags
RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in
guard let data = response.data else {
Logger.net.error("error getting tags")
return
}
if self.check_network_response(response: response) {
guard let json = try? JSON(data: data) else {
Logger.parse.error("error parsing tags response")
return
}
guard let data = response.data else {
Logger.net.error("error getting tags")
return
}
let tags = json["tags"].arrayValue
guard let json = try? JSON(data: data) else {
Logger.parse.error("error parsing tags response")
return
}
// update state
self.tags = TagApi.fromJSON(tag: tags).sorted(by: { $0.name.lowercased() < $1.name.lowercased() })
let tags = json["tags"].arrayValue
self.isRefreshingTags = false
self.isInitiallyRefreshingTags = false
// update state
self.tags = TagApi.fromJSON(tag: tags).sorted(by: { $0.name.lowercased() < $1.name.lowercased() })
if let success = onSuccess {
Logger.sys.debug("successfully refreshed tags")
success()
}
self.isRefreshingTags = false
self.isFullRefreshingTags = false
let encoder = JSONEncoder()
do {
UserDefaults.standard.set(String(data: try encoder.encode(tags), encoding: .utf8), forKey: "tags")
} catch {
Logger.parse.error("error encoding tags: \(error)")
}
if let success = onSuccess {
Logger.sys.debug("successfully refreshed tags")
success()
}
} else {
let encoder = JSONEncoder()
do {
UserDefaults.standard.set(String(data: try encoder.encode(tags), encoding: .utf8), forKey: "tags")
} catch {
Logger.parse.error("error encoding tags: \(error)")
}
if let failure = onFailure {
Logger.net.error("failed to refresh tags")
failure()
} else {
if let failure = onFailure {
Logger.net.error("failed to refresh tags")
failure()
}
}
}
}
else
{
Logger.sys.info("skipping refreshing tags, already refreshing")
}
}
var isFullRefreshing: Bool {
get {
return isFullRefreshingTags || isFullRefreshingPlaylists || isFullRefreshingUser
}
}
func full_refresh() {
self.isInitiallyRefreshingUser = true
self.isInitiallyRefreshingPlaylists = true
self.isInitiallyRefreshingTags = true
self.refresh_user()
self.refresh_playlists()
self.refresh_tags()
if !isFullRefreshing {
self.isFullRefreshingUser = true
self.isFullRefreshingPlaylists = true
self.isFullRefreshingTags = true
self.refresh_user()
self.refresh_playlists()
self.refresh_tags()
}
else
{
Logger.sys.info("skipping full refresh, already refreshing")
}
}
func check_network_response(response: AFDataResponse<Any>) -> Bool {

View File

@ -18,9 +18,9 @@ struct AppSkeleton: View {
var body: some View {
if self.liveUser.isInitiallyRefreshingUser
|| self.liveUser.isInitiallyRefreshingPlaylists
|| self.liveUser.isInitiallyRefreshingTags
if self.liveUser.isFullRefreshingUser
|| self.liveUser.isFullRefreshingPlaylists
|| self.liveUser.isFullRefreshingTags
{
LoadingScreen()
.onAppear {
@ -39,7 +39,7 @@ struct AppSkeleton: View {
}
.tag(0)
if liveUser.lastfm_connected() {
if liveUser.lastfm_connected {
TagList()
.tabItem {

View File

@ -27,7 +27,7 @@ struct PlaylistView: View {
var body: some View {
Form {
if liveUser.lastfm_connected() {
if liveUser.lastfm_connected {
PlaylistStatsSection(playlist: $playlist, showingToast: $showingToast, toastText: $toastText, toastSuccess: $toastSuccess)
}