diff --git a/client/components/tables/podcast/EpisodesTable.vue b/client/components/tables/podcast/EpisodesTable.vue index 888329a9..fcfe705e 100644 --- a/client/components/tables/podcast/EpisodesTable.vue +++ b/client/components/tables/podcast/EpisodesTable.vue @@ -58,7 +58,6 @@ export default { selectedEpisodes: [], episodesToRemove: [], processing: false, - quickMatchingEpisodes: false, search: null, searchTimeout: null, searchText: null @@ -78,6 +77,10 @@ export default { { text: 'Quick match all episodes', action: 'quick-match-episodes' + }, + { + text: this.allEpisodesFinished ? this.$strings.MessageMarkAllEpisodesNotFinished : this.$strings.MessageMarkAllEpisodesFinished, + action: 'batch-mark-as-finished' } ] }, @@ -169,9 +172,15 @@ export default { }, selectedIsFinished() { // Find an item that is not finished, if none then all items finished - return !this.selectedEpisodes.find((episode) => { - var itemProgress = this.$store.getters['user/getUserMediaProgress'](this.libraryItem.id, episode.id) - return !itemProgress || !itemProgress.isFinished + return !this.selectedEpisodes.some((episode) => { + const itemProgress = this.$store.getters['user/getUserMediaProgress'](this.libraryItem.id, episode.id) + return !itemProgress?.isFinished + }) + }, + allEpisodesFinished() { + return !this.episodesSorted.some((episode) => { + const itemProgress = this.$store.getters['user/getUserMediaProgress'](this.libraryItem.id, episode.id) + return !itemProgress?.isFinished }) }, dateFormat() { @@ -194,17 +203,34 @@ export default { }, contextMenuAction({ action }) { if (action === 'quick-match-episodes') { - if (this.quickMatchingEpisodes) return + if (this.processing) return this.quickMatchAllEpisodes() + } else if (action === 'batch-mark-as-finished') { + if (this.processing) return + + this.markAllEpisodesFinished() } }, + markAllEpisodesFinished() { + const newIsFinished = !this.allEpisodesFinished + const payload = { + message: newIsFinished ? this.$strings.MessageConfirmMarkAllEpisodesFinished : this.$strings.MessageConfirmMarkAllEpisodesNotFinished, + callback: (confirmed) => { + if (confirmed) { + this.batchUpdateEpisodesFinished(this.episodesSorted, newIsFinished) + } + }, + type: 'yesNo' + } + this.$store.commit('globals/setConfirmPrompt', payload) + }, quickMatchAllEpisodes() { if (!this.mediaMetadata.feedUrl) { this.$toast.error(this.$strings.MessagePodcastHasNoRSSFeedForMatching) return } - this.quickMatchingEpisodes = true + this.processing = true const payload = { message: 'Quick matching episodes will overwrite details if a match is found. Only unmatched episodes will be updated. Are you sure?', @@ -224,7 +250,7 @@ export default { this.$toast.error('Failed to match episodes') }) } - this.quickMatchingEpisodes = false + this.processing = false }, type: 'yesNo' } @@ -248,17 +274,19 @@ export default { this.$store.commit('addItemToQueue', queueItem) }, toggleBatchFinished() { + this.batchUpdateEpisodesFinished(this.selectedEpisodes, !this.selectedIsFinished) + }, + batchUpdateEpisodesFinished(episodes, newIsFinished) { this.processing = true - var newIsFinished = !this.selectedIsFinished - var updateProgressPayloads = this.selectedEpisodes.map((episode) => { + + const updateProgressPayloads = episodes.map((episode) => { return { libraryItemId: this.libraryItem.id, episodeId: episode.id, isFinished: newIsFinished } }) - - this.$axios + return this.$axios .patch(`/api/me/progress/batch/update`, updateProgressPayloads) .then(() => { this.$toast.success(this.$strings.ToastBatchUpdateSuccess) diff --git a/client/strings/de.json b/client/strings/de.json index 7627f5f3..4d4ccb53 100644 --- a/client/strings/de.json +++ b/client/strings/de.json @@ -519,6 +519,8 @@ "MessageConfirmDeleteLibrary": "Sind Sie sicher, dass Sie die Bibliothek \"{0}\" dauerhaft löschen wollen?", "MessageConfirmDeleteSession": "Sind Sie sicher, dass Sie diese Sitzung löschen möchten?", "MessageConfirmForceReScan": "Sind Sie sicher, dass Sie einen erneuten Scanvorgang erzwingen wollen?", + "MessageConfirmMarkAllEpisodesFinished": "Are you sure you want to mark all episodes as finished?", + "MessageConfirmMarkAllEpisodesNotFinished": "Are you sure you want to mark all episodes as not finished?", "MessageConfirmMarkSeriesFinished": "Sind Sie sicher, dass Sie alle Medien dieser Reihe als abgeschlossen markieren wollen?", "MessageConfirmMarkSeriesNotFinished": "Sind Sie sicher, dass Sie alle Medien dieser Reihe als nicht abgeschlossen markieren wollen?", "MessageConfirmRemoveAllChapters": "Sind Sie sicher, dass Sie alle Kapitel entfernen möchten?", @@ -552,6 +554,8 @@ "MessageM4BFailed": "M4B fehlgeschlagen!", "MessageM4BFinished": "M4B beendet!", "MessageMapChapterTitles": "Zuordnen von Kapiteltiteln zu Ihren vorhandenen Medienkapiteln ohne Anpassung der Zeitangaben", + "MessageMarkAllEpisodesFinished": "Mark all episodes finished", + "MessageMarkAllEpisodesNotFinished": "Mark all episodes not finished", "MessageMarkAsFinished": "Als beendet markieren", "MessageMarkAsNotFinished": "Als nicht abgeschlossen markieren", "MessageMatchBooksDescription": "versucht, Bücher in der Bibliothek mit einem Buch des ausgewählten Suchanbieters abzugleichen und leere Details und das Titelbild auszufüllen. Details werden nicht überschrieben.", diff --git a/client/strings/en-us.json b/client/strings/en-us.json index cdab08f1..65a753c7 100644 --- a/client/strings/en-us.json +++ b/client/strings/en-us.json @@ -519,6 +519,8 @@ "MessageConfirmDeleteLibrary": "Are you sure you want to permanently delete library \"{0}\"?", "MessageConfirmDeleteSession": "Are you sure you want to delete this session?", "MessageConfirmForceReScan": "Are you sure you want to force re-scan?", + "MessageConfirmMarkAllEpisodesFinished": "Are you sure you want to mark all episodes as finished?", + "MessageConfirmMarkAllEpisodesNotFinished": "Are you sure you want to mark all episodes as not finished?", "MessageConfirmMarkSeriesFinished": "Are you sure you want to mark all books in this series as finished?", "MessageConfirmMarkSeriesNotFinished": "Are you sure you want to mark all books in this series as not finished?", "MessageConfirmRemoveAllChapters": "Are you sure you want to remove all chapters?", @@ -552,6 +554,8 @@ "MessageM4BFailed": "M4B Failed!", "MessageM4BFinished": "M4B Finished!", "MessageMapChapterTitles": "Map chapter titles to your existing audiobook chapters without adjusting timestamps", + "MessageMarkAllEpisodesFinished": "Mark all episodes finished", + "MessageMarkAllEpisodesNotFinished": "Mark all episodes not finished", "MessageMarkAsFinished": "Mark as Finished", "MessageMarkAsNotFinished": "Mark as Not Finished", "MessageMatchBooksDescription": "will attempt to match books in the library with a book from the selected search provider and fill in empty details and cover art. Does not overwrite details.", diff --git a/client/strings/es.json b/client/strings/es.json index cfd940ea..363ef4a6 100644 --- a/client/strings/es.json +++ b/client/strings/es.json @@ -519,6 +519,8 @@ "MessageConfirmDeleteLibrary": "Esta seguro que desea eliminar permanentemente la biblioteca \"{0}\"?", "MessageConfirmDeleteSession": "Esta seguro que desea eliminar esta session?", "MessageConfirmForceReScan": "Esta seguro que desea forzar re-escanear?", + "MessageConfirmMarkAllEpisodesFinished": "Are you sure you want to mark all episodes as finished?", + "MessageConfirmMarkAllEpisodesNotFinished": "Are you sure you want to mark all episodes as not finished?", "MessageConfirmMarkSeriesFinished": "Esta seguro que desea marcar todos los libros en esta serie como terminados?", "MessageConfirmMarkSeriesNotFinished": "Esta seguro que desea marcar todos los libros en esta serie como no terminados?", "MessageConfirmRemoveAllChapters": "Esta seguro que desea remover todos los capitulos?", @@ -552,6 +554,8 @@ "MessageM4BFailed": "M4B Fallo!", "MessageM4BFinished": "M4B Terminado!", "MessageMapChapterTitles": "Map chapter titles to your existing audiobook chapters without adjusting timestamps", + "MessageMarkAllEpisodesFinished": "Mark all episodes finished", + "MessageMarkAllEpisodesNotFinished": "Mark all episodes not finished", "MessageMarkAsFinished": "Marcar como Terminado", "MessageMarkAsNotFinished": "Marcar como No Terminado", "MessageMatchBooksDescription": "intentará hacer coincidir los libros de la biblioteca con un libro del proveedor de búsqueda seleccionado y rellenará los detalles vacíos y la portada. No sobrescribe los detalles.", diff --git a/client/strings/fr.json b/client/strings/fr.json index 06581158..2ee8bd16 100644 --- a/client/strings/fr.json +++ b/client/strings/fr.json @@ -519,6 +519,8 @@ "MessageConfirmDeleteLibrary": "Êtes-vous sûr de vouloir supprimer définitivement la bibliothèque « {0} » ?", "MessageConfirmDeleteSession": "Êtes-vous sûr de vouloir supprimer cette session ?", "MessageConfirmForceReScan": "Êtes-vous sûr de vouloir lancer une Analyse Forcée ?", + "MessageConfirmMarkAllEpisodesFinished": "Are you sure you want to mark all episodes as finished?", + "MessageConfirmMarkAllEpisodesNotFinished": "Are you sure you want to mark all episodes as not finished?", "MessageConfirmMarkSeriesFinished": "Êtes-vous sûr de vouloir marquer comme terminé tous les livres de cette série ?", "MessageConfirmMarkSeriesNotFinished": "Êtes-vous sûr de vouloir marquer comme non terminé tous les livres de cette série ?", "MessageConfirmRemoveAllChapters": "Êtes-vous sûr de vouloir supprimer tous les chapitres ?", @@ -552,6 +554,8 @@ "MessageM4BFailed": "M4B en échec !", "MessageM4BFinished": "M4B terminé !", "MessageMapChapterTitles": "Faire correspondre les titres des chapitres aux chapitres existants de votre livre audio sans ajuster l’horodatage.", + "MessageMarkAllEpisodesFinished": "Mark all episodes finished", + "MessageMarkAllEpisodesNotFinished": "Mark all episodes not finished", "MessageMarkAsFinished": "Marquer comme terminé", "MessageMarkAsNotFinished": "Marquer comme non Terminé", "MessageMatchBooksDescription": "tentera de faire correspondre les livres de la bibliothèque avec les livres du fournisseur sélectionné pour combler les détails et couverture manquants. N’écrase pas les données existantes.", diff --git a/client/strings/gu.json b/client/strings/gu.json index 8a6130db..04915ef7 100644 --- a/client/strings/gu.json +++ b/client/strings/gu.json @@ -519,6 +519,8 @@ "MessageConfirmDeleteLibrary": "Are you sure you want to permanently delete library \"{0}\"?", "MessageConfirmDeleteSession": "Are you sure you want to delete this session?", "MessageConfirmForceReScan": "Are you sure you want to force re-scan?", + "MessageConfirmMarkAllEpisodesFinished": "Are you sure you want to mark all episodes as finished?", + "MessageConfirmMarkAllEpisodesNotFinished": "Are you sure you want to mark all episodes as not finished?", "MessageConfirmMarkSeriesFinished": "Are you sure you want to mark all books in this series as finished?", "MessageConfirmMarkSeriesNotFinished": "Are you sure you want to mark all books in this series as not finished?", "MessageConfirmRemoveAllChapters": "Are you sure you want to remove all chapters?", @@ -552,6 +554,8 @@ "MessageM4BFailed": "M4B Failed!", "MessageM4BFinished": "M4B Finished!", "MessageMapChapterTitles": "Map chapter titles to your existing audiobook chapters without adjusting timestamps", + "MessageMarkAllEpisodesFinished": "Mark all episodes finished", + "MessageMarkAllEpisodesNotFinished": "Mark all episodes not finished", "MessageMarkAsFinished": "Mark as Finished", "MessageMarkAsNotFinished": "Mark as Not Finished", "MessageMatchBooksDescription": "will attempt to match books in the library with a book from the selected search provider and fill in empty details and cover art. Does not overwrite details.", diff --git a/client/strings/hi.json b/client/strings/hi.json index 2a11ff34..d0bb3435 100644 --- a/client/strings/hi.json +++ b/client/strings/hi.json @@ -519,6 +519,8 @@ "MessageConfirmDeleteLibrary": "Are you sure you want to permanently delete library \"{0}\"?", "MessageConfirmDeleteSession": "Are you sure you want to delete this session?", "MessageConfirmForceReScan": "Are you sure you want to force re-scan?", + "MessageConfirmMarkAllEpisodesFinished": "Are you sure you want to mark all episodes as finished?", + "MessageConfirmMarkAllEpisodesNotFinished": "Are you sure you want to mark all episodes as not finished?", "MessageConfirmMarkSeriesFinished": "Are you sure you want to mark all books in this series as finished?", "MessageConfirmMarkSeriesNotFinished": "Are you sure you want to mark all books in this series as not finished?", "MessageConfirmRemoveAllChapters": "Are you sure you want to remove all chapters?", @@ -552,6 +554,8 @@ "MessageM4BFailed": "M4B Failed!", "MessageM4BFinished": "M4B Finished!", "MessageMapChapterTitles": "Map chapter titles to your existing audiobook chapters without adjusting timestamps", + "MessageMarkAllEpisodesFinished": "Mark all episodes finished", + "MessageMarkAllEpisodesNotFinished": "Mark all episodes not finished", "MessageMarkAsFinished": "Mark as Finished", "MessageMarkAsNotFinished": "Mark as Not Finished", "MessageMatchBooksDescription": "will attempt to match books in the library with a book from the selected search provider and fill in empty details and cover art. Does not overwrite details.", diff --git a/client/strings/hr.json b/client/strings/hr.json index 5cd244e2..1f3e9ecd 100644 --- a/client/strings/hr.json +++ b/client/strings/hr.json @@ -519,6 +519,8 @@ "MessageConfirmDeleteLibrary": "Jeste li sigurni da želite trajno obrisati biblioteku \"{0}\"?", "MessageConfirmDeleteSession": "Jeste li sigurni da želite obrisati ovu sesiju?", "MessageConfirmForceReScan": "Jeste li sigurni da želite ponovno skenirati?", + "MessageConfirmMarkAllEpisodesFinished": "Are you sure you want to mark all episodes as finished?", + "MessageConfirmMarkAllEpisodesNotFinished": "Are you sure you want to mark all episodes as not finished?", "MessageConfirmMarkSeriesFinished": "Are you sure you want to mark all books in this series as finished?", "MessageConfirmMarkSeriesNotFinished": "Are you sure you want to mark all books in this series as not finished?", "MessageConfirmRemoveAllChapters": "Are you sure you want to remove all chapters?", @@ -552,6 +554,8 @@ "MessageM4BFailed": "M4B neuspješan!", "MessageM4BFinished": "M4B završio!", "MessageMapChapterTitles": "Mapiraj imena poglavlja u postoječa poglavlja bez izmijene timestampova.", + "MessageMarkAllEpisodesFinished": "Mark all episodes finished", + "MessageMarkAllEpisodesNotFinished": "Mark all episodes not finished", "MessageMarkAsFinished": "Označi kao završeno", "MessageMarkAsNotFinished": "Označi kao nezavršeno", "MessageMatchBooksDescription": "će probati matchati knjige iz biblioteke sa knjigom od odabranog poslužitelja i popuniti prazne detalje i cover. Ne briše postojeće detalje.", diff --git a/client/strings/it.json b/client/strings/it.json index ae1c89b5..7ed44f73 100644 --- a/client/strings/it.json +++ b/client/strings/it.json @@ -519,6 +519,8 @@ "MessageConfirmDeleteLibrary": "Sei sicuro di voler eliminare definitivamente la libreria \"{0}\"?", "MessageConfirmDeleteSession": "Sei sicuro di voler eliminare questa sessione?", "MessageConfirmForceReScan": "Sei sicuro di voler forzare una nuova scansione?", + "MessageConfirmMarkAllEpisodesFinished": "Are you sure you want to mark all episodes as finished?", + "MessageConfirmMarkAllEpisodesNotFinished": "Are you sure you want to mark all episodes as not finished?", "MessageConfirmMarkSeriesFinished": "Sei sicuro di voler contrassegnare tutti i libri di questa serie come completati?", "MessageConfirmMarkSeriesNotFinished": "Sei sicuro di voler contrassegnare tutti i libri di questa serie come non completati?", "MessageConfirmRemoveAllChapters": "Are you sure you want to remove all chapters?", @@ -552,6 +554,8 @@ "MessageM4BFailed": "M4B Fallito!", "MessageM4BFinished": "M4B Finito!", "MessageMapChapterTitles": "Associa i titoli dei capitoli ai capitoli dell'audiolibro esistente senza modificare i timestamp", + "MessageMarkAllEpisodesFinished": "Mark all episodes finished", + "MessageMarkAllEpisodesNotFinished": "Mark all episodes not finished", "MessageMarkAsFinished": "Segna come finito", "MessageMarkAsNotFinished": "Segna come da completare", "MessageMatchBooksDescription": "tenterà di abbinare i libri nella biblioteca con un libro del provider di ricerca selezionato e inserirà i dettagli vuoti e la copertina. Non sovrascrive i dettagli.", diff --git a/client/strings/nl.json b/client/strings/nl.json index 9f8bfe89..dd23773c 100644 --- a/client/strings/nl.json +++ b/client/strings/nl.json @@ -519,6 +519,8 @@ "MessageConfirmDeleteLibrary": "Weet je zeker dat je de bibliotheek \"{0}\" permanent wil verwijderen?", "MessageConfirmDeleteSession": "Weet je zeker dat je deze sessie wil verwijderen?", "MessageConfirmForceReScan": "Weet je zeker dat je geforceerd opnieuw wil scannen?", + "MessageConfirmMarkAllEpisodesFinished": "Are you sure you want to mark all episodes as finished?", + "MessageConfirmMarkAllEpisodesNotFinished": "Are you sure you want to mark all episodes as not finished?", "MessageConfirmMarkSeriesFinished": "Weet je zeker dat je alle boeken in deze serie wil markeren als voltooid?", "MessageConfirmMarkSeriesNotFinished": "Weet je zeker dat je alle boeken in deze serie wil markeren als niet voltooid?", "MessageConfirmRemoveAllChapters": "Weet je zeker dat je alle hoofdstukken wil verwijderen?", @@ -552,6 +554,8 @@ "MessageM4BFailed": "M4B mislukt!", "MessageM4BFinished": "M4B voltooid!", "MessageMapChapterTitles": "Map hoofdstuktitels naar je bestaande audioboekhoofdstukken zonder aanpassing van tijden", + "MessageMarkAllEpisodesFinished": "Mark all episodes finished", + "MessageMarkAllEpisodesNotFinished": "Mark all episodes not finished", "MessageMarkAsFinished": "Markeer als Voltooid", "MessageMarkAsNotFinished": "Markeer als Niet Voltooid", "MessageMatchBooksDescription": "zal proberen boeken in de bibliotheek te matchen met een boek uit de geselecteerde bron en lege details en coverafbeelding te vullen. Overschrijft details niet.", diff --git a/client/strings/pl.json b/client/strings/pl.json index fb5a3898..1b7e40e7 100644 --- a/client/strings/pl.json +++ b/client/strings/pl.json @@ -519,6 +519,8 @@ "MessageConfirmDeleteLibrary": "Czy na pewno chcesz trwale usunąć bibliotekę \"{0}\"?", "MessageConfirmDeleteSession": "Czy na pewno chcesz usunąć tę sesję?", "MessageConfirmForceReScan": "Czy na pewno chcesz wymusić ponowne skanowanie?", + "MessageConfirmMarkAllEpisodesFinished": "Are you sure you want to mark all episodes as finished?", + "MessageConfirmMarkAllEpisodesNotFinished": "Are you sure you want to mark all episodes as not finished?", "MessageConfirmMarkSeriesFinished": "Are you sure you want to mark all books in this series as finished?", "MessageConfirmMarkSeriesNotFinished": "Are you sure you want to mark all books in this series as not finished?", "MessageConfirmRemoveAllChapters": "Are you sure you want to remove all chapters?", @@ -552,6 +554,8 @@ "MessageM4BFailed": "Tworzenie pliku M4B nie powiodło się", "MessageM4BFinished": "Tworzenie pliku M4B zakończyło się!", "MessageMapChapterTitles": "Mapowanie tytułów rozdziałów do istniejących rozdziałów audiobooka bez dostosowywania znaczników czasu", + "MessageMarkAllEpisodesFinished": "Mark all episodes finished", + "MessageMarkAllEpisodesNotFinished": "Mark all episodes not finished", "MessageMarkAsFinished": "Oznacz jako ukończone", "MessageMarkAsNotFinished": "Oznacz jako nieukończone", "MessageMatchBooksDescription": "spróbuje dopasować książki w bibliotece bez plików audio, korzystając z wybranego dostawcy wyszukiwania i wypełnić puste szczegóły i okładki. Nie nadpisuje informacji.", diff --git a/client/strings/ru.json b/client/strings/ru.json index abf391e5..bf02f1e2 100644 --- a/client/strings/ru.json +++ b/client/strings/ru.json @@ -519,6 +519,8 @@ "MessageConfirmDeleteLibrary": "Вы уверены, что хотите навсегда удалить библиотеку \"{0}\"?", "MessageConfirmDeleteSession": "Вы уверены, что хотите удалить этот сеанс?", "MessageConfirmForceReScan": "Вы уверены, что хотите принудительно выполнить повторное сканирование?", + "MessageConfirmMarkAllEpisodesFinished": "Are you sure you want to mark all episodes as finished?", + "MessageConfirmMarkAllEpisodesNotFinished": "Are you sure you want to mark all episodes as not finished?", "MessageConfirmMarkSeriesFinished": "Вы уверены, что хотите отметить все книги этой серии как законченные?", "MessageConfirmMarkSeriesNotFinished": "Вы уверены, что хотите отметить все книги этой серии как незаконченные?", "MessageConfirmRemoveAllChapters": "Вы уверены, что хотите удалить все главы?", @@ -552,6 +554,8 @@ "MessageM4BFailed": "M4B Ошибка!", "MessageM4BFinished": "M4B Завершено!", "MessageMapChapterTitles": "Сопоставление названий глав с существующими главами аудиокниги без корректировки временных меток", + "MessageMarkAllEpisodesFinished": "Mark all episodes finished", + "MessageMarkAllEpisodesNotFinished": "Mark all episodes not finished", "MessageMarkAsFinished": "Отметить, как завершенную", "MessageMarkAsNotFinished": "Отметить, как не завершенную", "MessageMatchBooksDescription": "попытается сопоставить книги в библиотеке с книгой из выбранного поставщика поиска и заполнить пустые детали и обложку. Не перезаписывает сведения.", diff --git a/client/strings/zh-cn.json b/client/strings/zh-cn.json index 3451288b..db40c2b8 100644 --- a/client/strings/zh-cn.json +++ b/client/strings/zh-cn.json @@ -519,6 +519,8 @@ "MessageConfirmDeleteLibrary": "你确定要永久删除媒体库 \"{0}\"?", "MessageConfirmDeleteSession": "你确定要删除此会话吗?", "MessageConfirmForceReScan": "你确定要强制重新扫描吗?", + "MessageConfirmMarkAllEpisodesFinished": "Are you sure you want to mark all episodes as finished?", + "MessageConfirmMarkAllEpisodesNotFinished": "Are you sure you want to mark all episodes as not finished?", "MessageConfirmMarkSeriesFinished": "你确定要将此系列中的所有书籍都标记为已听完吗?", "MessageConfirmMarkSeriesNotFinished": "你确定要将此系列中的所有书籍都标记为未听完吗?", "MessageConfirmRemoveAllChapters": "你确定要移除所有章节吗?", @@ -552,6 +554,8 @@ "MessageM4BFailed": "M4B 失败!", "MessageM4BFinished": "M4B 完成!", "MessageMapChapterTitles": "将章节标题映射到现有的有声读物章节, 无需调整时间戳", + "MessageMarkAllEpisodesFinished": "Mark all episodes finished", + "MessageMarkAllEpisodesNotFinished": "Mark all episodes not finished", "MessageMarkAsFinished": "标记为已听完", "MessageMarkAsNotFinished": "标记为未听完", "MessageMatchBooksDescription": "尝试将媒体库中的图书与所选搜索提供商的图书进行匹配, 并填写空白的详细信息和封面. 不覆盖详细信息.",