From f98f78a5bd2673f1cc62e798f18b09fc16f35491 Mon Sep 17 00:00:00 2001 From: Nicholas Wallace Date: Thu, 10 Oct 2024 21:14:51 -0700 Subject: [PATCH 1/5] Podcast search strings --- client/pages/library/_library/podcast/search.vue | 10 +++++----- client/strings/en-us.json | 5 +++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/client/pages/library/_library/podcast/search.vue b/client/pages/library/_library/podcast/search.vue index b80ca2f8..983b9025 100644 --- a/client/pages/library/_library/podcast/search.vue +++ b/client/pages/library/_library/podcast/search.vue @@ -5,7 +5,7 @@
- + {{ $strings.ButtonSubmit }} @@ -108,7 +108,7 @@ export default { if (!txt || !txt.includes(' tag not found OR an tag was not found') + this.$toast.error(this.$strings.MessageTaskOpmlParseFastFail) this.processing = false return } @@ -117,7 +117,7 @@ export default { .$post(`/api/podcasts/opml/parse`, { opmlText: txt }) .then((data) => { if (!data.feeds?.length) { - this.$toast.error('No feeds found in OPML file') + this.$toast.error(this.$strings.MessageTaskOpmlParseNoneFound) } else { this.opmlFeeds = data.feeds || [] this.showOPMLFeedsModal = true @@ -125,7 +125,7 @@ export default { }) .catch((error) => { console.error('Failed', error) - this.$toast.error('Failed to parse OPML file') + this.$toast.error(this.$strings.MessageTaskOpmlParseFailed) }) .finally(() => { this.processing = false @@ -191,7 +191,7 @@ export default { return } if (!podcast.feedUrl) { - this.$toast.error('Invalid podcast - no feed') + this.$toast.error(this.$strings.MessageNoPodcastFeed) return } this.processing = true diff --git a/client/strings/en-us.json b/client/strings/en-us.json index 34b014dc..bbc29146 100644 --- a/client/strings/en-us.json +++ b/client/strings/en-us.json @@ -746,6 +746,7 @@ "MessageNoLogs": "No Logs", "MessageNoMediaProgress": "No Media Progress", "MessageNoNotifications": "No Notifications", + "MessageNoPodcastFeed": "Invalid podcast: No Feed", "MessageNoPodcastsFound": "No podcasts found", "MessageNoResults": "No Results", "MessageNoSearchResultsFor": "No search results for \"{0}\"", @@ -762,6 +763,7 @@ "MessagePlaylistCreateFromCollection": "Create playlist from collection", "MessagePleaseWait": "Please wait...", "MessagePodcastHasNoRSSFeedForMatching": "Podcast has no RSS feed url to use for matching", + "MessagePodcastSearchField": "Enter search term or RSS feed URL", "MessageQuickMatchDescription": "Populate empty item details & cover with first match result from '{0}'. Does not overwrite details unless 'Prefer matched metadata' server setting is enabled.", "MessageRemoveChapter": "Remove chapter", "MessageRemoveEpisodes": "Remove {0} episode(s)", @@ -804,6 +806,9 @@ "MessageTaskOpmlImportFeedPodcastExists": "Podcast already exists at path", "MessageTaskOpmlImportFeedPodcastFailed": "Failed to create podcast", "MessageTaskOpmlImportFinished": "Added {0} podcasts", + "MessageTaskOpmlParseFailed": "Failed to parse OPML file", + "MessageTaskOpmlParseFastFail": "Invalid OPML file tag not found OR an tag was not found", + "MessageTaskOpmlParseNoneFound": "No feeds found in OPML file", "MessageTaskScanItemsAdded": "{0} added", "MessageTaskScanItemsMissing": "{0} missing", "MessageTaskScanItemsUpdated": "{0} updated", From 29db5f199095693522cf2e715ebd9c5eab944ae4 Mon Sep 17 00:00:00 2001 From: Nicholas Wallace Date: Thu, 10 Oct 2024 21:21:15 -0700 Subject: [PATCH 2/5] Update: tools strings --- client/components/modals/item/tabs/Tools.vue | 8 ++++---- client/strings/en-us.json | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/client/components/modals/item/tabs/Tools.vue b/client/components/modals/item/tabs/Tools.vue index ad9435c4..5f148c3d 100644 --- a/client/components/modals/item/tabs/Tools.vue +++ b/client/components/modals/item/tabs/Tools.vue @@ -33,18 +33,18 @@ launch - Quick Embed + {{ $strings.ButtonQuickEmbed }}
-

Queued for metadata embed ({{ queuedEmbedLIds.length }} in queue)

+

{{ $getString('MessageQuickEmbedQueue', [queuedEmbedLIds.length]) }}

-

Currently embedding metadata

+

{{ $strings.MessageQuickEmbedInProgress }}

@@ -113,7 +113,7 @@ export default { methods: { quickEmbed() { const payload = { - message: 'Warning! Quick embed will not backup your audio files. Make sure that you have a backup of your audio files.

Would you like to continue?', + message: this.$strings.MessageConfirmQuickEmbed, callback: (confirmed) => { if (confirmed) { this.$axios diff --git a/client/strings/en-us.json b/client/strings/en-us.json index bbc29146..cd8f7684 100644 --- a/client/strings/en-us.json +++ b/client/strings/en-us.json @@ -66,6 +66,7 @@ "ButtonPurgeItemsCache": "Purge Items Cache", "ButtonQueueAddItem": "Add to queue", "ButtonQueueRemoveItem": "Remove from queue", + "ButtonQuickEmbed": "Quick Embed", "ButtonQuickEmbedMetadata": "Quick Embed Metadata", "ButtonQuickMatch": "Quick Match", "ButtonReScan": "Re-Scan", @@ -764,6 +765,8 @@ "MessagePleaseWait": "Please wait...", "MessagePodcastHasNoRSSFeedForMatching": "Podcast has no RSS feed url to use for matching", "MessagePodcastSearchField": "Enter search term or RSS feed URL", + "MessageQuickEmbedInProgress": "Quick embed in progress", + "MessageQuickEmbedQueue": "Queued for quick embed ({0} in queue)", "MessageQuickMatchDescription": "Populate empty item details & cover with first match result from '{0}'. Does not overwrite details unless 'Prefer matched metadata' server setting is enabled.", "MessageRemoveChapter": "Remove chapter", "MessageRemoveEpisodes": "Remove {0} episode(s)", From c33b470fcaf660eb7a59be57dc55587230b00e57 Mon Sep 17 00:00:00 2001 From: Nicholas Wallace Date: Thu, 10 Oct 2024 21:58:17 -0700 Subject: [PATCH 3/5] Tools Manager strings --- client/pages/audiobook/_id/manage.vue | 34 +++++++++++++-------------- client/strings/en-us.json | 16 +++++++++++++ 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/client/pages/audiobook/_id/manage.vue b/client/pages/audiobook/_id/manage.vue index 7de82b51..fb5ccc29 100644 --- a/client/pages/audiobook/_id/manage.vue +++ b/client/pages/audiobook/_id/manage.vue @@ -63,11 +63,11 @@
-

Audiobook is queued for metadata embed ({{ queuedEmbedLIds.length }} in queue)

+

{{ $getString('MessageEmbedQueue', [queuedEmbedLIds.length]) }}

- +
@@ -78,7 +78,7 @@
@@ -94,11 +94,11 @@
- - - + + +
-

Warning: Do not update these settings unless you are familiar with ffmpeg encoding options.

+

{{ $strings.LabelEncodingWarningAdvancedSettings }}

@@ -106,36 +106,36 @@
star -

Metadata will be embedded in the audio tracks inside your audiobook folder.

+

{{ $strings.LabelEncodingInfoEmbedded }}

star

- Finished M4B will be put into your audiobook folder at .../{{ libraryItemRelPath }}/. + {{ $strings.LabelEncodingFinishedM4B }} .../{{ libraryItemRelPath }}/.

star

- A backup of your original audio files will be stored in /metadata/cache/items/{{ libraryItemId }}/. Make sure to periodically purge items cache. + {{ $strings.LabelEncodingBackupLocation }} /metadata/cache/items/{{ libraryItemId }}/. {{ $strings.LabelEncodingClearItemCache }}

star -

Chapters are not embedded in multi-track audiobooks.

+

{{ $strings.LabelEncodingChaptersNotEmbedded }}

star -

Encoding can take up to 30 minutes.

+

{{ $strings.LabelEncodingTimeWarning }}

star -

If you have the watcher disabled you will need to re-scan this audiobook afterwards.

+

{{ $strings.LabelEncodingWatcherDisabled }}

star -

Once the task is started you can navigate away from this page.

+

{{ $strings.LabelEncodingStartedNavigation }}

@@ -269,11 +269,11 @@ export default { }, availableTools() { if (this.isSingleM4b) { - return [{ value: 'embed', text: 'Embed Metadata' }] + return [{ value: 'embed', text: this.$strings.LabelToolsEmbedMetadata }] } else { return [ - { value: 'embed', text: 'Embed Metadata' }, - { value: 'm4b', text: 'M4B Encoder' } + { value: 'embed', text: this.$strings.LabelToolsEmbedMetadata }, + { value: 'm4b', text: this.$strings.LabelToolsM4bEncoder } ] } }, diff --git a/client/strings/en-us.json b/client/strings/en-us.json index cd8f7684..4370851d 100644 --- a/client/strings/en-us.json +++ b/client/strings/en-us.json @@ -226,6 +226,9 @@ "LabelAllUsersIncludingGuests": "All users including guests", "LabelAlreadyInYourLibrary": "Already in your library", "LabelAppend": "Append", + "LabelAudioBitrate": "Audio Bitrate (e.g. 128k)", + "LabelAudioChannels": "Audio Channels (1 or 2)", + "LabelAudioCodec": "Audio Codec", "LabelAuthor": "Author", "LabelAuthorFirstLast": "Author (First Last)", "LabelAuthorLastFirst": "Author (Last, First)", @@ -238,6 +241,7 @@ "LabelAutoRegister": "Auto Register", "LabelAutoRegisterDescription": "Automatically create new users after logging in", "LabelBackToUser": "Back to User", + "LabelBackupAudioFiles": "Backup Audio Files", "LabelBackupLocation": "Backup Location", "LabelBackupsEnableAutomaticBackups": "Enable automatic backups", "LabelBackupsEnableAutomaticBackupsHelp": "Backups saved in /metadata/backups", @@ -304,6 +308,15 @@ "LabelEmailSettingsTestAddress": "Test Address", "LabelEmbeddedCover": "Embedded Cover", "LabelEnable": "Enable", + "LabelEncodingBackupLocation": "A backup of your original audio files will be stored in:", + "LabelEncodingChaptersNotEmbedded": "Chapters are not embedded in multi-track audiobooks.", + "LabelEncodingClearItemCache": "Make sure to periodically purge items cache.", + "LabelEncodingFinishedM4B": "Finished M4B will be put into your audiobook folder at:", + "LabelEncodingInfoEmbedded": "Metadata will be embedded in the audio tracks inside your audiobook folder.", + "LabelEncodingStartedNavigation": "Once the task is started you can navigate away from this page.", + "LabelEncodingTimeWarning": "Encoding can take up to 30 minutes.", + "LabelEncodingWarningAdvancedSettings": "Warning: Do not update these settings unless you are familiar with ffmpeg encoding options.", + "LabelEncodingWatcherDisabled": "If you have the watcher disabled you will need to re-scan this audiobook afterwards.", "LabelEnd": "End", "LabelEndOfChapter": "End of Chapter", "LabelEpisode": "Episode", @@ -597,6 +610,7 @@ "LabelTitle": "Title", "LabelToolsEmbedMetadata": "Embed Metadata", "LabelToolsEmbedMetadataDescription": "Embed metadata into audio files including cover image and chapters.", + "LabelToolsM4bEncoder": "M4B Encoder", "LabelToolsMakeM4b": "Make M4B Audiobook File", "LabelToolsMakeM4bDescription": "Generate a .M4B audiobook file with embedded metadata, cover image, and chapters.", "LabelToolsSplitM4b": "Split M4B to MP3's", @@ -622,6 +636,7 @@ "LabelUploaderDragAndDrop": "Drag & drop files or folders", "LabelUploaderDropFiles": "Drop files", "LabelUploaderItemFetchMetadataHelp": "Automatically fetch title, author, and series", + "LabelUseAdvancedOptions": "Use Advanced Options", "LabelUseChapterTrack": "Use chapter track", "LabelUseFullTrack": "Use full track", "LabelUser": "User", @@ -703,6 +718,7 @@ "MessageDragFilesIntoTrackOrder": "Drag files into correct track order", "MessageEmbedFailed": "Embed Failed!", "MessageEmbedFinished": "Embed Finished!", + "MessageEmbedQueue": "Queued for metadata embed ({0} in queue)", "MessageEpisodesQueuedForDownload": "{0} Episode(s) queued for download", "MessageEreaderDevices": "To ensure delivery of ebooks, you may need to add the above email address as a valid sender for each device listed below.", "MessageFeedURLWillBe": "Feed URL will be {0}", From 8a20510cde0286eca1790210c471d5bdb59ec2c5 Mon Sep 17 00:00:00 2001 From: Nicholas Wallace Date: Thu, 10 Oct 2024 22:12:31 -0700 Subject: [PATCH 4/5] Localize: subtitle `books` --- client/components/cards/LazyBookCard.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/components/cards/LazyBookCard.vue b/client/components/cards/LazyBookCard.vue index ae2cdd5b..09424b3c 100644 --- a/client/components/cards/LazyBookCard.vue +++ b/client/components/cards/LazyBookCard.vue @@ -325,7 +325,7 @@ export default { }, displaySubtitle() { if (!this.libraryItem) return '\u00A0' - if (this.collapsedSeries) return this.collapsedSeries.numBooks === 1 ? '1 book' : `${this.collapsedSeries.numBooks} books` + if (this.collapsedSeries) return `${this.collapsedSeries.numBooks} ${this.$strings.LabelBooks}` if (this.mediaMetadata.subtitle) return this.mediaMetadata.subtitle if (this.mediaMetadata.seriesName) return this.mediaMetadata.seriesName return '' From df6afc957f51e2b46955d6dab7e1fd8649ce6fdd Mon Sep 17 00:00:00 2001 From: advplyr Date: Sat, 12 Oct 2024 15:22:21 -0500 Subject: [PATCH 5/5] Add localization for notification descriptions --- .../modals/notification/NotificationEditModal.vue | 8 +++++++- client/strings/en-us.json | 4 ++++ server/utils/notifications.js | 4 ++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/client/components/modals/notification/NotificationEditModal.vue b/client/components/modals/notification/NotificationEditModal.vue index 32fa20ea..83b5a9d0 100644 --- a/client/components/modals/notification/NotificationEditModal.vue +++ b/client/components/modals/notification/NotificationEditModal.vue @@ -77,7 +77,13 @@ export default { return this.notificationData.events || [] }, eventOptions() { - return this.notificationEvents.map((e) => ({ value: e.name, text: e.name, subtext: e.description })) + return this.notificationEvents.map((e) => { + return { + value: e.name, + text: e.name, + subtext: this.$strings[e.descriptionKey] || e.description + } + }) }, selectedEventData() { return this.notificationEvents.find((e) => e.name === this.newNotification.eventName) diff --git a/client/strings/en-us.json b/client/strings/en-us.json index 4370851d..edad1672 100644 --- a/client/strings/en-us.json +++ b/client/strings/en-us.json @@ -852,6 +852,10 @@ "NoteUploaderFoldersWithMediaFiles": "Folders with media files will be handled as separate library items.", "NoteUploaderOnlyAudioFiles": "If uploading only audio files then each audio file will be handled as a separate audiobook.", "NoteUploaderUnsupportedFiles": "Unsupported files are ignored. When choosing or dropping a folder, other files that are not in an item folder are ignored.", + "NotificationOnBackupCompletedDescription": "Triggered when a backup is completed", + "NotificationOnBackupFailedDescription": "Triggered when a backup fails", + "NotificationOnEpisodeDownloadedDescription": "Triggered when a podcast episode is auto-downloaded", + "NotificationOnTestDescription": "Event for testing the notification system", "PlaceholderNewCollection": "New collection name", "PlaceholderNewFolderPath": "New folder path", "PlaceholderNewPlaylist": "New playlist name", diff --git a/server/utils/notifications.js b/server/utils/notifications.js index 96e8ddf8..7a3e1198 100644 --- a/server/utils/notifications.js +++ b/server/utils/notifications.js @@ -7,6 +7,7 @@ module.exports.notificationData = { requiresLibrary: true, libraryMediaType: 'podcast', description: 'Triggered when a podcast episode is auto-downloaded', + descriptionKey: 'NotificationOnEpisodeDownloadedDescription', variables: ['libraryItemId', 'libraryId', 'podcastTitle', 'podcastAuthor', 'podcastDescription', 'podcastGenres', 'episodeTitle', 'episodeSubtitle', 'episodeDescription', 'libraryName', 'episodeId', 'mediaTags'], defaults: { title: 'New {{podcastTitle}} Episode!', @@ -31,6 +32,7 @@ module.exports.notificationData = { name: 'onBackupCompleted', requiresLibrary: false, description: 'Triggered when a backup is completed', + descriptionKey: 'NotificationOnBackupCompletedDescription', variables: ['completionTime', 'backupPath', 'backupSize', 'backupCount', 'removedOldest'], defaults: { title: 'Backup Completed', @@ -48,6 +50,7 @@ module.exports.notificationData = { name: 'onBackupFailed', requiresLibrary: false, description: 'Triggered when a backup fails', + descriptionKey: 'NotificationOnBackupFailedDescription', variables: ['errorMsg'], defaults: { title: 'Backup Failed', @@ -61,6 +64,7 @@ module.exports.notificationData = { name: 'onTest', requiresLibrary: false, description: 'Event for testing the notification system', + descriptionKey: 'NotificationOnTestDescription', variables: ['version'], defaults: { title: 'Test Notification on Abs {{version}}',