diff --git a/artifacts/2026-02-26/match_dialog_default_provider.md b/artifacts/2026-02-26/match_dialog_default_provider.md new file mode 100644 index 000000000..6a3378039 --- /dev/null +++ b/artifacts/2026-02-26/match_dialog_default_provider.md @@ -0,0 +1,28 @@ +# Match Dialog Default Provider + +This specification artifact details the changes made to the "Match" and "Edit" dialogs within the audiobookshelf application to ensure the default metadata provider corresponds to the library's default setting, rather than a globally persisted user selection. + +## Background + +Previously, when matching a book in the "Match" tab of the Edit modal, changing the metadata provider (e.g., from "Audible" to "Google Books") would save that choice to `localStorage` under the key `book-provider`. Subsequent visits to the Match tab for any other book would initialize the provider dropdown with this last-used value. + +This behavior led to a suboptimal user experience, specifically for users who manage multiple libraries with different default metadata providers or specifically want their library's default provider to take precedence by default. + +## Implementation Details + +### Removal of `localStorage` Persistence + +The `Match.vue` component has been updated to remove the persistence of `book-provider` to `localStorage`. + +- The `persistProvider()` method has been removed. +- The `submitSearch()` method no longer triggers persistence. + +### Initialization from Library Settings + +The initial provider selection logic in `getDefaultBookProvider()` inside `Match.vue` (and similarly `Cover.vue`) has been refactored: + +- It now queries the Vuex store (`this.$store.getters['libraries/getLibraryProvider']`) utilizing the `libraryId` of the current item. +- If the current library has a customized provider, it correctly defaults to that provider. +- It falls back to `"google"` safely if no library setting is found or the retrieved provider is invalid. + +This ensures that closing and reopening the Match dialog for another item accurately respects the library's established metadata source configuration. diff --git a/client/components/modals/item/tabs/Cover.vue b/client/components/modals/item/tabs/Cover.vue index be17f9636..289df65e7 100644 --- a/client/components/modals/item/tabs/Cover.vue +++ b/client/components/modals/item/tabs/Cover.vue @@ -244,17 +244,8 @@ export default { this.searchAuthor = this.mediaMetadata.authorName || '' if (this.isPodcast) this.provider = 'itunes' else { - // Migrate from 'all' to 'best' (only once) - const migrationKey = 'book-cover-provider-migrated' - const currentProvider = localStorage.getItem('book-cover-provider') || localStorage.getItem('book-provider') || 'google' - - if (!localStorage.getItem(migrationKey) && currentProvider === 'all') { - localStorage.setItem('book-cover-provider', 'best') - localStorage.setItem(migrationKey, 'true') - this.provider = 'best' - } else { - this.provider = currentProvider - } + const libraryProvider = this.$store.getters['libraries/getLibraryProvider'](this.libraryItem.libraryId) || 'google' + this.provider = libraryProvider === 'all' ? 'best' : libraryProvider } }, removeCover() { @@ -304,13 +295,7 @@ export default { if (this.isPodcast) searchQuery += '&podcast=1' return searchQuery }, - persistProvider() { - try { - localStorage.setItem('book-cover-provider', this.provider) - } catch (error) { - console.error('PersistProvider', error) - } - }, + generateRequestId() { return `cover-search-${Date.now()}-${Math.random().toString(36).substr(2, 9)}` }, @@ -398,9 +383,6 @@ export default { this.cancelCurrentSearch() } - // Store provider in local storage - this.persistProvider() - // Setup socket listeners if not already done this.addSocketListeners() diff --git a/client/components/modals/item/tabs/Match.vue b/client/components/modals/item/tabs/Match.vue index ffbd124cb..744b22abc 100644 --- a/client/components/modals/item/tabs/Match.vue +++ b/client/components/modals/item/tabs/Match.vue @@ -381,20 +381,12 @@ export default { checkboxToggled() { this.selectAll = Object.values(this.selectedMatchUsage).findIndex((v) => v == false) < 0 }, - persistProvider() { - try { - localStorage.setItem('book-provider', this.provider) - } catch (error) { - console.error('PersistProvider', error) - } - }, getDefaultBookProvider() { - let provider = localStorage.getItem('book-provider') - if (!provider) return 'google' + const provider = this.$store.getters['libraries/getLibraryProvider'](this.libraryItem.libraryId) || 'google' + // Validate book provider if (!this.$store.getters['scanners/checkBookProviderExists'](provider)) { - console.error('Stored book provider does not exist', provider) - localStorage.removeItem('book-provider') + console.error('Library default book provider does not exist', provider) return 'google' } return provider @@ -411,9 +403,6 @@ export default { this.$toast.warning(this.$strings.ToastTitleRequired) return } - if (!this.isPodcast) { - this.persistProvider() - } this.runSearch() }, async runSearch() {