From ae706bc8bce7d87615adca81ad05ada779c4aeaa Mon Sep 17 00:00:00 2001 From: Sven Date: Sat, 11 Apr 2026 11:30:42 +0200 Subject: [PATCH] Add a "clear cache" function --- Mobile Music Assistant/Localizable.xcstrings | 88 +++++++++++++++++++ .../ServicesMALibraryManager.swift | 30 +++++++ Mobile Music Assistant/ViewsMainTabView.swift | 19 +++- 3 files changed, 136 insertions(+), 1 deletion(-) diff --git a/Mobile Music Assistant/Localizable.xcstrings b/Mobile Music Assistant/Localizable.xcstrings index 8ef5673..756f60e 100644 --- a/Mobile Music Assistant/Localizable.xcstrings +++ b/Mobile Music Assistant/Localizable.xcstrings @@ -716,6 +716,94 @@ } } }, + "Clear Cache" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cache leeren" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Borrar caché" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vider le cache" + } + } + } + }, + "Clear Cache?" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cache leeren?" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¿Borrar caché?" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vider le cache ?" + } + } + } + }, + "This will delete all locally cached artwork and library data. The next launch or reload may take longer while everything is fetched again." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dadurch werden alle lokal gespeicherten Bilder und Bibliotheksdaten gelöscht. Der nächste Start oder das nächste Laden kann länger dauern, während alles neu abgerufen wird." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Esto eliminará todas las ilustraciones y datos de biblioteca almacenados localmente. El siguiente inicio o recarga puede tardar más mientras todo se vuelve a descargar." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cela supprimera toutes les illustrations et données de bibliothèque stockées localement. Le prochain démarrage ou rechargement peut prendre plus de temps pendant que tout est à nouveau récupéré." + } + } + } + }, + "Clearing the cache removes all locally stored artwork and library data. The next launch or reload may take longer." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Das Leeren des Caches entfernt alle lokal gespeicherten Bilder und Bibliotheksdaten. Der nächste Start oder das nächste Laden kann länger dauern." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Borrar el caché elimina todas las ilustraciones y datos de biblioteca almacenados localmente. El siguiente inicio o recarga puede tardar más." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vider le cache supprime toutes les illustrations et données de bibliothèque stockées localement. Le prochain démarrage ou rechargement peut prendre plus de temps." + } + } + } + }, "Connect" : { "localizations" : { "de" : { diff --git a/Mobile Music Assistant/ServicesMALibraryManager.swift b/Mobile Music Assistant/ServicesMALibraryManager.swift index 0e14878..70d402e 100644 --- a/Mobile Music Assistant/ServicesMALibraryManager.swift +++ b/Mobile Music Assistant/ServicesMALibraryManager.swift @@ -145,6 +145,36 @@ final class MALibraryManager { return try? JSONDecoder().decode(T.self, from: data) } + /// Clears all cached library data from memory and disk. + func clearAll() { + artists = [] + albumArtists = [] + albums = [] + playlists = [] + podcasts = [] + favoriteURIs = [] + artistsOffset = 0 + albumArtistsOffset = 0 + albumsOffset = 0 + hasMoreArtists = true + hasMoreAlbumArtists = true + hasMoreAlbums = true + lastArtistsRefresh = nil + lastAlbumArtistsRefresh = nil + lastAlbumsRefresh = nil + lastPlaylistsRefresh = nil + lastPodcastsRefresh = nil + + let ud = UserDefaults.standard + for key in ["lib.lastArtistsRefresh", "lib.lastAlbumArtistsRefresh", + "lib.lastAlbumsRefresh", "lib.lastPlaylistsRefresh", "lib.lastPodcastsRefresh"] { + ud.removeObject(forKey: key) + } + + try? FileManager.default.removeItem(at: cacheDirectory) + try? FileManager.default.createDirectory(at: cacheDirectory, withIntermediateDirectories: true) + } + private func markRefreshed(_ key: String) -> Date { let now = Date() UserDefaults.standard.set(now, forKey: key) diff --git a/Mobile Music Assistant/ViewsMainTabView.swift b/Mobile Music Assistant/ViewsMainTabView.swift index a1d468e..20ede2b 100644 --- a/Mobile Music Assistant/ViewsMainTabView.swift +++ b/Mobile Music Assistant/ViewsMainTabView.swift @@ -392,7 +392,8 @@ struct SettingsView: View { @Environment(\.localeManager) private var localeManager @Environment(MAStoreManager.self) private var storeManager @State private var showThankYou = false - + @State private var showClearCacheConfirm = false + var body: some View { NavigationStack { Form { @@ -476,12 +477,19 @@ struct SettingsView: View { // Actions Section Section { + Button(role: .destructive) { + showClearCacheConfirm = true + } label: { + Label("Clear Cache", systemImage: "trash") + } Button(role: .destructive) { service.disconnect() service.authManager.logout() } label: { Label("Disconnect", systemImage: "arrow.right.square") } + } footer: { + Text("Clearing the cache removes all locally stored artwork and library data. The next launch or reload may take longer.") } // Support Development Section @@ -536,6 +544,15 @@ struct SettingsView: View { .task { await storeManager.loadProducts() } + .alert("Clear Cache?", isPresented: $showClearCacheConfirm) { + Button("Clear", role: .destructive) { + ImageCache.shared.clearAll() + service.libraryManager.clearAll() + } + Button("Cancel", role: .cancel) { } + } message: { + Text("This will delete all locally cached artwork and library data. The next launch or reload may take longer while everything is fetched again.") + } .alert("Thank You!", isPresented: $showThankYou) { Button("You're welcome!", role: .cancel) { } } message: {