From 43b7ccd61ae378f97068700da2ed17432262ec5a Mon Sep 17 00:00:00 2001 From: Greg Lorenzen <31518305+glorenzen@users.noreply.github.com> Date: Fri, 12 Jul 2024 15:52:48 -0700 Subject: [PATCH 01/38] WIP: Add adjustable skip amount (#3113) * Add playback settings string to en-us * Add playback settings UI for jump forwards and jump backwards * Remove jump forwards and jump backwards settings * Remove jump forwards and jump backwards en-us strings * Update player UI to include player settings button * Add label view player settings string * Add PlayerSettingsModal component Includes a toggle switch for enabling/disabling the chapter track feature. * Add player settings modal component to MediaPlayerContainer * Handle useChapterTrack changes in PlayerUI * Add jump forwards and jump backwards settings to user store * Add jump forwards and jump backwards label strings * Add jump forwards and jump backwards settings to PlayerSettingsModal * Update jump forwards and jump backwards to handle user state values in PlayerHandler * Update jump backwards icon in PlayerPlaybackControls * Add playback settings string to en-us * Add playback settings UI for jump forwards and jump backwards * Remove jump forwards and jump backwards settings * Remove jump forwards and jump backwards en-us strings * Update player UI to include player settings button * Add label view player settings string * Add PlayerSettingsModal component Includes a toggle switch for enabling/disabling the chapter track feature. * Add player settings modal component to MediaPlayerContainer * Handle useChapterTrack changes in PlayerUI * Add jump forwards and jump backwards settings to user store * Add jump forwards and jump backwards label strings * Add jump forwards and jump backwards settings to PlayerSettingsModal * Update jump forwards and jump backwards to handle user state values in PlayerHandler * Update jump backwards icon in PlayerPlaybackControls * Add jump amounts to playback controls tooltips * Fix merge issues and add new Material Symbols to player ui * Alphabetize strings in en-us.json * Update dropdown component with SelectInput to support menu overflowing modal * Update localization for player settings * Update en-us strings order --------- Co-authored-by: advplyr --- .../components/app/MediaPlayerContainer.vue | 4 + .../components/modals/PlayerSettingsModal.vue | 70 ++++++++ .../player/PlayerPlaybackControls.vue | 34 +++- client/components/player/PlayerUi.vue | 20 ++- client/components/ui/SelectInput.vue | 151 ++++++++++++++++++ client/players/PlayerHandler.js | 12 +- client/store/user.js | 4 +- client/strings/en-us.json | 6 + 8 files changed, 283 insertions(+), 18 deletions(-) create mode 100644 client/components/modals/PlayerSettingsModal.vue create mode 100644 client/components/ui/SelectInput.vue diff --git a/client/components/app/MediaPlayerContainer.vue b/client/components/app/MediaPlayerContainer.vue index 3c99a6da..5c04d053 100644 --- a/client/components/app/MediaPlayerContainer.vue +++ b/client/components/app/MediaPlayerContainer.vue @@ -51,6 +51,7 @@ @showBookmarks="showBookmarks" @showSleepTimer="showSleepTimerModal = true" @showPlayerQueueItems="showPlayerQueueItemsModal = true" + @showPlayerSettings="showPlayerSettingsModal = true" /> @@ -58,6 +59,8 @@ + + @@ -76,6 +79,7 @@ export default { currentTime: 0, showSleepTimerModal: false, showPlayerQueueItemsModal: false, + showPlayerSettingsModal: false, sleepTimerSet: false, sleepTimerTime: 0, sleepTimerRemaining: 0, diff --git a/client/components/modals/PlayerSettingsModal.vue b/client/components/modals/PlayerSettingsModal.vue new file mode 100644 index 00000000..10c3cd65 --- /dev/null +++ b/client/components/modals/PlayerSettingsModal.vue @@ -0,0 +1,70 @@ + + + diff --git a/client/components/player/PlayerPlaybackControls.vue b/client/components/player/PlayerPlaybackControls.vue index 6a70b28c..664385bd 100644 --- a/client/components/player/PlayerPlaybackControls.vue +++ b/client/components/player/PlayerPlaybackControls.vue @@ -7,17 +7,17 @@ first_page - - - - @@ -56,6 +56,12 @@ export default { set(val) { this.$emit('update:playbackRate', val) } + }, + jumpForwardText() { + return this.getJumpText('jumpForwardAmount', this.$strings.ButtonJumpForward) + }, + jumpBackwardText() { + return this.getJumpText('jumpBackwardAmount', this.$strings.ButtonJumpBackward) } }, methods: { @@ -83,8 +89,22 @@ export default { this.$store.dispatch('user/updateUserSettings', { playbackRate }).catch((err) => { console.error('Failed to update settings', err) }) + }, + getJumpText(setting, prefix) { + const amount = this.$store.getters['user/getUserSetting'](setting) + if (!amount) return prefix + + let formattedTime = '' + if (amount <= 60) { + formattedTime = this.$getString('LabelJumpAmountSeconds', [amount]) + } else { + const minutes = Math.floor(amount / 60) + formattedTime = this.$getString('LabelJumpAmountMinutes', [minutes]) + } + + return `${prefix} - ${formattedTime}` } }, mounted() {} } - \ No newline at end of file + diff --git a/client/components/player/PlayerUi.vue b/client/components/player/PlayerUi.vue index 3093975f..21d1b7aa 100644 --- a/client/components/player/PlayerUi.vue +++ b/client/components/player/PlayerUi.vue @@ -36,9 +36,9 @@ - - @@ -90,13 +90,16 @@ export default { seekLoading: false, showChaptersModal: false, currentTime: 0, - duration: 0, - useChapterTrack: false + duration: 0 } }, watch: { playbackRate() { this.updateTimestamp() + }, + useChapterTrack() { + if (this.$refs.trackbar) this.$refs.trackbar.setUseChapterTrack(this.useChapterTrack) + this.updateTimestamp() } }, computed: { @@ -162,6 +165,10 @@ export default { }, playerQueueItems() { return this.$store.state.playerQueueItems || [] + }, + useChapterTrack() { + const _useChapterTrack = this.$store.getters['user/getUserSetting']('useChapterTrack') || false + return this.chapters.length ? _useChapterTrack : false } }, methods: { @@ -310,9 +317,6 @@ export default { init() { this.playbackRate = this.$store.getters['user/getUserSetting']('playbackRate') || 1 - const _useChapterTrack = this.$store.getters['user/getUserSetting']('useChapterTrack') || false - this.useChapterTrack = this.chapters.length ? _useChapterTrack : false - if (this.$refs.trackbar) this.$refs.trackbar.setUseChapterTrack(this.useChapterTrack) this.setPlaybackRate(this.playbackRate) }, diff --git a/client/components/ui/SelectInput.vue b/client/components/ui/SelectInput.vue new file mode 100644 index 00000000..e7c302d5 --- /dev/null +++ b/client/components/ui/SelectInput.vue @@ -0,0 +1,151 @@ + + + diff --git a/client/players/PlayerHandler.js b/client/players/PlayerHandler.js index 660ca2c1..0f806d81 100644 --- a/client/players/PlayerHandler.js +++ b/client/players/PlayerHandler.js @@ -51,6 +51,12 @@ export default class PlayerHandler { if (!this.episodeId) return null return this.libraryItem.media.episodes.find(ep => ep.id === this.episodeId) } + get jumpForwardAmount() { + return this.ctx.$store.getters['user/getUserSetting']('jumpForwardAmount') + } + get jumpBackwardAmount() { + return this.ctx.$store.getters['user/getUserSetting']('jumpBackwardAmount') + } setSessionId(sessionId) { this.currentSessionId = sessionId @@ -381,13 +387,15 @@ export default class PlayerHandler { jumpBackward() { if (!this.player) return var currentTime = this.getCurrentTime() - this.seek(Math.max(0, currentTime - 10)) + const jumpAmount = this.jumpBackwardAmount + this.seek(Math.max(0, currentTime - jumpAmount)) } jumpForward() { if (!this.player) return var currentTime = this.getCurrentTime() - this.seek(Math.min(currentTime + 10, this.getDuration())) + const jumpAmount = this.jumpForwardAmount + this.seek(Math.min(currentTime + jumpAmount, this.getDuration())) } setVolume(volume) { diff --git a/client/store/user.js b/client/store/user.js index 3555d63e..7571f916 100644 --- a/client/store/user.js +++ b/client/store/user.js @@ -14,7 +14,9 @@ export const state = () => ({ seriesSortDesc: false, seriesFilterBy: 'all', authorSortBy: 'name', - authorSortDesc: false + authorSortDesc: false, + jumpForwardAmount: 10, + jumpBackwardAmount: 10, } }) diff --git a/client/strings/en-us.json b/client/strings/en-us.json index f713cb11..f39901b6 100644 --- a/client/strings/en-us.json +++ b/client/strings/en-us.json @@ -155,6 +155,7 @@ "HeaderPasswordAuthentication": "Password Authentication", "HeaderPermissions": "Permissions", "HeaderPlayerQueue": "Player Queue", + "HeaderPlayerSettings": "Player Settings", "HeaderPlaylist": "Playlist", "HeaderPlaylistItems": "Playlist Items", "HeaderPodcastsToAdd": "Podcasts to Add", @@ -343,6 +344,10 @@ "LabelIntervalEveryHour": "Every hour", "LabelInvert": "Invert", "LabelItem": "Item", + "LabelJumpAmountMinutes": "{0} minutes", + "LabelJumpAmountSeconds": "{0} seconds", + "LabelJumpBackwardAmount": "Jump backward amount", + "LabelJumpForwardAmount": "Jump forward amount", "LabelLanguage": "Language", "LabelLanguageDefaultServer": "Default Server Language", "LabelLanguages": "Languages", @@ -598,6 +603,7 @@ "LabelVersion": "Version", "LabelViewBookmarks": "View bookmarks", "LabelViewChapters": "View chapters", + "LabelViewPlayerSettings": "View player settings", "LabelViewQueue": "View player queue", "LabelVolume": "Volume", "LabelWeekdaysToRun": "Weekdays to run", From eabfa90121edf39ca20ad9870b1423d3379ab91b Mon Sep 17 00:00:00 2001 From: advplyr Date: Sat, 13 Jul 2024 15:26:07 -0500 Subject: [PATCH 02/38] Update:Move library stats page to SideRail #3134 --- client/components/app/ConfigSideNav.vue | 6 +- client/components/app/SideRail.vue | 13 +- client/pages/config.vue | 3 +- client/pages/config/library-stats.vue | 175 ----------------------- client/pages/library/_library/stats.vue | 181 ++++++++++++++++++++++++ client/strings/en-us.json | 1 + server/Server.js | 1 + 7 files changed, 199 insertions(+), 181 deletions(-) delete mode 100644 client/pages/config/library-stats.vue create mode 100644 client/pages/library/_library/stats.vue diff --git a/client/components/app/ConfigSideNav.vue b/client/components/app/ConfigSideNav.vue index b4835255..2b46eb7c 100644 --- a/client/components/app/ConfigSideNav.vue +++ b/client/components/app/ConfigSideNav.vue @@ -114,9 +114,9 @@ export default { if (this.currentLibraryId) { configRoutes.push({ - id: 'config-library-stats', + id: 'library-stats', title: this.$strings.HeaderLibraryStats, - path: '/config/library-stats' + path: `/library/${this.currentLibraryId}/stats` }) configRoutes.push({ id: 'config-stats', @@ -182,4 +182,4 @@ export default { } } } - \ No newline at end of file + diff --git a/client/components/app/SideRail.vue b/client/components/app/SideRail.vue index 7475f7ed..2c1538ec 100644 --- a/client/components/app/SideRail.vue +++ b/client/components/app/SideRail.vue @@ -79,6 +79,14 @@
+ + monitoring + +

{{ $strings.ButtonStats }}

+ +
+ + @@ -103,7 +111,7 @@
- + warning

{{ $strings.ButtonIssues }}

@@ -194,6 +202,9 @@ export default { isPlaylistsPage() { return this.paramId === 'playlists' }, + isStatsPage() { + return this.$route.name === 'library-library-stats' + }, libraryBookshelfPage() { return this.$route.name === 'library-library-bookshelf-id' }, diff --git a/client/pages/config.vue b/client/pages/config.vue index 957cef52..4492bbfd 100644 --- a/client/pages/config.vue +++ b/client/pages/config.vue @@ -52,7 +52,6 @@ export default { else if (pageName === 'notifications') return this.$strings.HeaderNotifications else if (pageName === 'sessions') return this.$strings.HeaderListeningSessions else if (pageName === 'stats') return this.$strings.HeaderYourStats - else if (pageName === 'library-stats') return this.$strings.HeaderLibraryStats else if (pageName === 'users') return this.$strings.HeaderUsers else if (pageName === 'item-metadata-utils') return this.$strings.HeaderItemMetadataUtils else if (pageName === 'rss-feeds') return this.$strings.HeaderRSSFeeds @@ -94,4 +93,4 @@ export default { max-width: 100%; } } - \ No newline at end of file + diff --git a/client/pages/config/library-stats.vue b/client/pages/config/library-stats.vue deleted file mode 100644 index 1a95c630..00000000 --- a/client/pages/config/library-stats.vue +++ /dev/null @@ -1,175 +0,0 @@ - - - diff --git a/client/pages/library/_library/stats.vue b/client/pages/library/_library/stats.vue new file mode 100644 index 00000000..7cd97248 --- /dev/null +++ b/client/pages/library/_library/stats.vue @@ -0,0 +1,181 @@ + + + diff --git a/client/strings/en-us.json b/client/strings/en-us.json index f39901b6..eaaa5d7c 100644 --- a/client/strings/en-us.json +++ b/client/strings/en-us.json @@ -89,6 +89,7 @@ "ButtonShow": "Show", "ButtonStartM4BEncode": "Start M4B Encode", "ButtonStartMetadataEmbed": "Start Metadata Embed", + "ButtonStats": "Stats", "ButtonSubmit": "Submit", "ButtonTest": "Test", "ButtonUpload": "Upload", diff --git a/server/Server.js b/server/Server.js index 76d8466d..8649c5ad 100644 --- a/server/Server.js +++ b/server/Server.js @@ -285,6 +285,7 @@ class Server { '/library/:library/bookshelf/:id?', '/library/:library/authors', '/library/:library/narrators', + '/library/:library/stats', '/library/:library/series/:id?', '/library/:library/podcast/search', '/library/:library/podcast/latest', From 618e69775c04da8211e9f20a5c7a58b344ac9d93 Mon Sep 17 00:00:00 2001 From: Greg Lorenzen Date: Sun, 14 Jul 2024 05:25:56 +0000 Subject: [PATCH 03/38] Add responsive limit for displayed items on personalized shelves on home page --- client/components/app/BookShelfCategorized.vue | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/client/components/app/BookShelfCategorized.vue b/client/components/app/BookShelfCategorized.vue index c8a70a2a..23f9bc67 100644 --- a/client/components/app/BookShelfCategorized.vue +++ b/client/components/app/BookShelfCategorized.vue @@ -167,8 +167,19 @@ export default { this.loaded = true }, async fetchCategories() { + // Sets the limit for the number of items to be displayed based on the viewport width. + const viewportWidth = window.innerWidth + let limit + if (viewportWidth >= 3240 && viewportWidth <= 3440) { + limit = 15 + } else if (viewportWidth >= 2880 && viewportWidth < 3240) { + limit = 12 + } + + const limitQuery = limit ? `&limit=${limit}` : '' + const categories = await this.$axios - .$get(`/api/libraries/${this.currentLibraryId}/personalized?include=rssfeed,numEpisodesIncomplete,share`) + .$get(`/api/libraries/${this.currentLibraryId}/personalized?include=rssfeed,numEpisodesIncomplete,share${limitQuery}`) .then((data) => { return data }) From 733f61075f2fd5dc2965d996979836eb1403b936 Mon Sep 17 00:00:00 2001 From: Greg Lorenzen <31518305+glorenzen@users.noreply.github.com> Date: Sun, 14 Jul 2024 11:56:48 -0700 Subject: [PATCH 04/38] WIP: Add "End of chapter" option for sleep timer (#3151) * Add SleepTimerTypes for countdown and chapter * Add functionality for 'end of chapter' sleep timer * Fix custom time for sleep timer * Include end of chapter string for sleep timer * Increase chapter end tolerance to 0.75 * Show sleep time options in modal when timer is active * Add SleepTimerTypes for countdown and chapter * Add functionality for 'end of chapter' sleep timer * Fix custom time for sleep timer * Include end of chapter string for sleep timer * Increase chapter end tolerance to 0.75 * Show sleep time options in modal when timer is active * Sleep timer cleanup * Localization for sleep timer modal, UI updates --------- Co-authored-by: advplyr --- .../components/app/MediaPlayerContainer.vue | 45 ++++-- .../components/modals/PlayerSettingsModal.vue | 12 +- client/components/modals/SleepTimerModal.vue | 137 ++++++++++-------- .../player/PlayerPlaybackControls.vue | 4 +- client/components/player/PlayerUi.vue | 29 ++-- client/plugins/constants.js | 8 +- client/strings/en-us.json | 7 +- 7 files changed, 147 insertions(+), 95 deletions(-) diff --git a/client/components/app/MediaPlayerContainer.vue b/client/components/app/MediaPlayerContainer.vue index 5c04d053..cbc76803 100644 --- a/client/components/app/MediaPlayerContainer.vue +++ b/client/components/app/MediaPlayerContainer.vue @@ -35,11 +35,13 @@ - + @@ -81,8 +83,8 @@ export default { showPlayerQueueItemsModal: false, showPlayerSettingsModal: false, sleepTimerSet: false, - sleepTimerTime: 0, sleepTimerRemaining: 0, + sleepTimerType: null, sleepTimer: null, displayTitle: null, currentPlaybackRate: 1, @@ -149,6 +151,9 @@ export default { if (this.streamEpisode) return this.streamEpisode.chapters || [] return this.media.chapters || [] }, + currentChapter() { + return this.chapters.find((chapter) => chapter.start <= this.currentTime && this.currentTime < chapter.end) + }, title() { if (this.playerHandler.displayTitle) return this.playerHandler.displayTitle return this.mediaMetadata.title || 'No Title' @@ -208,14 +213,18 @@ export default { this.$store.commit('setIsPlaying', isPlaying) this.updateMediaSessionPlaybackState() }, - setSleepTimer(seconds) { + setSleepTimer(time) { this.sleepTimerSet = true - this.sleepTimerTime = seconds - this.sleepTimerRemaining = seconds - this.runSleepTimer() this.showSleepTimerModal = false + + this.sleepTimerType = time.timerType + if (this.sleepTimerType === this.$constants.SleepTimerTypes.COUNTDOWN) { + this.runSleepTimer(time) + } }, - runSleepTimer() { + runSleepTimer(time) { + this.sleepTimerRemaining = time.seconds + var lastTick = Date.now() clearInterval(this.sleepTimer) this.sleepTimer = setInterval(() => { @@ -224,12 +233,23 @@ export default { this.sleepTimerRemaining -= elapsed / 1000 if (this.sleepTimerRemaining <= 0) { - this.clearSleepTimer() - this.playerHandler.pause() - this.$toast.info('Sleep Timer Done.. zZzzZz') + this.sleepTimerEnd() } }, 1000) }, + checkChapterEnd(time) { + if (!this.currentChapter) return + const chapterEndTime = this.currentChapter.end + const tolerance = 0.75 + if (time >= chapterEndTime - tolerance) { + this.sleepTimerEnd() + } + }, + sleepTimerEnd() { + this.clearSleepTimer() + this.playerHandler.pause() + this.$toast.info('Sleep Timer Done.. zZzzZz') + }, cancelSleepTimer() { this.showSleepTimerModal = false this.clearSleepTimer() @@ -239,6 +259,7 @@ export default { this.sleepTimerRemaining = 0 this.sleepTimer = null this.sleepTimerSet = false + this.sleepTimerType = null }, incrementSleepTimer(amount) { if (!this.sleepTimerSet) return @@ -279,6 +300,10 @@ export default { if (this.$refs.audioPlayer) { this.$refs.audioPlayer.setCurrentTime(time) } + + if (this.sleepTimerType === this.$constants.SleepTimerTypes.CHAPTER && this.sleepTimerSet) { + this.checkChapterEnd(time) + } }, setDuration(duration) { this.totalDuration = duration diff --git a/client/components/modals/PlayerSettingsModal.vue b/client/components/modals/PlayerSettingsModal.vue index 10c3cd65..ec178d9c 100644 --- a/client/components/modals/PlayerSettingsModal.vue +++ b/client/components/modals/PlayerSettingsModal.vue @@ -27,12 +27,12 @@ export default { return { useChapterTrack: false, jumpValues: [ - { text: this.$getString('LabelJumpAmountSeconds', ['10']), value: 10 }, - { text: this.$getString('LabelJumpAmountSeconds', ['15']), value: 15 }, - { text: this.$getString('LabelJumpAmountSeconds', ['30']), value: 30 }, - { text: this.$getString('LabelJumpAmountSeconds', ['60']), value: 60 }, - { text: this.$getString('LabelJumpAmountMinutes', ['2']), value: 120 }, - { text: this.$getString('LabelJumpAmountMinutes', ['5']), value: 300 } + { text: this.$getString('LabelTimeDurationXSeconds', ['10']), value: 10 }, + { text: this.$getString('LabelTimeDurationXSeconds', ['15']), value: 15 }, + { text: this.$getString('LabelTimeDurationXSeconds', ['30']), value: 30 }, + { text: this.$getString('LabelTimeDurationXSeconds', ['60']), value: 60 }, + { text: this.$getString('LabelTimeDurationXMinutes', ['2']), value: 120 }, + { text: this.$getString('LabelTimeDurationXMinutes', ['5']), value: 300 } ], jumpForwardAmount: 10, jumpBackwardAmount: 10 diff --git a/client/components/modals/SleepTimerModal.vue b/client/components/modals/SleepTimerModal.vue index 051c5d3d..43b55217 100644 --- a/client/components/modals/SleepTimerModal.vue +++ b/client/components/modals/SleepTimerModal.vue @@ -6,34 +6,36 @@
-
-
+
+
- + Set
-
-
- +
+
+ +
+ remove - 30m + 30m - + -

{{ $secondsToTimestamp(remaining) }}

+

{{ $secondsToTimestamp(remaining) }}

- + - + add - 30m + 30m
{{ $strings.ButtonCancel }} @@ -47,52 +49,13 @@ export default { props: { value: Boolean, timerSet: Boolean, - timerTime: Number, - remaining: Number + timerType: String, + remaining: Number, + hasChapters: Boolean }, data() { return { - customTime: null, - sleepTimes: [ - { - seconds: 60 * 5, - text: '5 minutes' - }, - { - seconds: 60 * 15, - text: '15 minutes' - }, - { - seconds: 60 * 20, - text: '20 minutes' - }, - { - seconds: 60 * 30, - text: '30 minutes' - }, - { - seconds: 60 * 45, - text: '45 minutes' - }, - { - seconds: 60 * 60, - text: '60 minutes' - }, - { - seconds: 60 * 90, - text: '90 minutes' - }, - { - seconds: 60 * 120, - text: '2 hours' - } - ] - } - }, - watch: { - show(newVal) { - if (newVal) { - } + customTime: null } }, computed: { @@ -103,6 +66,54 @@ export default { set(val) { this.$emit('input', val) } + }, + sleepTimes() { + const times = [ + { + seconds: 60 * 5, + text: this.$getString('LabelTimeDurationXMinutes', ['5']), + timerType: this.$constants.SleepTimerTypes.COUNTDOWN + }, + { + seconds: 60 * 15, + text: this.$getString('LabelTimeDurationXMinutes', ['15']), + timerType: this.$constants.SleepTimerTypes.COUNTDOWN + }, + { + seconds: 60 * 20, + text: this.$getString('LabelTimeDurationXMinutes', ['20']), + timerType: this.$constants.SleepTimerTypes.COUNTDOWN + }, + { + seconds: 60 * 30, + text: this.$getString('LabelTimeDurationXMinutes', ['30']), + timerType: this.$constants.SleepTimerTypes.COUNTDOWN + }, + { + seconds: 60 * 45, + text: this.$getString('LabelTimeDurationXMinutes', ['45']), + timerType: this.$constants.SleepTimerTypes.COUNTDOWN + }, + { + seconds: 60 * 60, + text: this.$getString('LabelTimeDurationXMinutes', ['60']), + timerType: this.$constants.SleepTimerTypes.COUNTDOWN + }, + { + seconds: 60 * 90, + text: this.$getString('LabelTimeDurationXMinutes', ['90']), + timerType: this.$constants.SleepTimerTypes.COUNTDOWN + }, + { + seconds: 60 * 120, + text: this.$getString('LabelTimeDurationXHours', ['2']), + timerType: this.$constants.SleepTimerTypes.COUNTDOWN + } + ] + if (this.hasChapters) { + times.push({ seconds: -1, text: this.$strings.LabelEndOfChapter, timerType: this.$constants.SleepTimerTypes.CHAPTER }) + } + return times } }, methods: { @@ -113,10 +124,14 @@ export default { } const timeInSeconds = Math.round(Number(this.customTime) * 60) - this.setTime(timeInSeconds) + const time = { + seconds: timeInSeconds, + timerType: this.$constants.SleepTimerTypes.COUNTDOWN + } + this.setTime(time) }, - setTime(seconds) { - this.$emit('set', seconds) + setTime(time) { + this.$emit('set', time) }, increment(amount) { this.$emit('increment', amount) @@ -130,4 +145,4 @@ export default { } } } - \ No newline at end of file + diff --git a/client/components/player/PlayerPlaybackControls.vue b/client/components/player/PlayerPlaybackControls.vue index 664385bd..76397e98 100644 --- a/client/components/player/PlayerPlaybackControls.vue +++ b/client/components/player/PlayerPlaybackControls.vue @@ -96,10 +96,10 @@ export default { let formattedTime = '' if (amount <= 60) { - formattedTime = this.$getString('LabelJumpAmountSeconds', [amount]) + formattedTime = this.$getString('LabelTimeDurationXSeconds', [amount]) } else { const minutes = Math.floor(amount / 60) - formattedTime = this.$getString('LabelJumpAmountMinutes', [minutes]) + formattedTime = this.$getString('LabelTimeDurationXMinutes', [minutes]) } return `${prefix} - ${formattedTime}` diff --git a/client/components/player/PlayerUi.vue b/client/components/player/PlayerUi.vue index 21d1b7aa..68452061 100644 --- a/client/components/player/PlayerUi.vue +++ b/client/components/player/PlayerUi.vue @@ -13,7 +13,7 @@ snooze
snooze -

{{ sleepTimerRemainingString }}

+

{{ sleepTimerRemainingString }}

@@ -72,12 +72,14 @@ export default { type: Array, default: () => [] }, + currentChapter: Object, bookmarks: { type: Array, default: () => [] }, sleepTimerSet: Boolean, sleepTimerRemaining: Number, + sleepTimerType: String, isPodcast: Boolean, hideBookmarks: Boolean, hideSleepTimer: Boolean @@ -104,16 +106,20 @@ export default { }, computed: { sleepTimerRemainingString() { - var rounded = Math.round(this.sleepTimerRemaining) - if (rounded < 90) { - return `${rounded}s` + if (this.sleepTimerType === this.$constants.SleepTimerTypes.CHAPTER) { + return 'EoC' + } else { + var rounded = Math.round(this.sleepTimerRemaining) + if (rounded < 90) { + return `${rounded}s` + } + var minutesRounded = Math.round(rounded / 60) + if (minutesRounded <= 90) { + return `${minutesRounded}m` + } + var hoursRounded = Math.round(minutesRounded / 60) + return `${hoursRounded}h` } - var minutesRounded = Math.round(rounded / 60) - if (minutesRounded < 90) { - return `${minutesRounded}m` - } - var hoursRounded = Math.round(minutesRounded / 60) - return `${hoursRounded}h` }, token() { return this.$store.getters['user/getToken'] @@ -138,9 +144,6 @@ export default { if (!duration) return 0 return Math.round((100 * time) / duration) }, - currentChapter() { - return this.chapters.find((chapter) => chapter.start <= this.currentTime && this.currentTime < chapter.end) - }, currentChapterName() { return this.currentChapter ? this.currentChapter.title : '' }, diff --git a/client/plugins/constants.js b/client/plugins/constants.js index f001f6ce..d89fbbbd 100644 --- a/client/plugins/constants.js +++ b/client/plugins/constants.js @@ -32,12 +32,18 @@ const PlayMethod = { LOCAL: 3 } +const SleepTimerTypes = { + COUNTDOWN: 'countdown', + CHAPTER: 'chapter' +} + const Constants = { SupportedFileTypes, DownloadStatus, BookCoverAspectRatio, BookshelfView, - PlayMethod + PlayMethod, + SleepTimerTypes } const KeyNames = { diff --git a/client/strings/en-us.json b/client/strings/en-us.json index eaaa5d7c..a0933d4d 100644 --- a/client/strings/en-us.json +++ b/client/strings/en-us.json @@ -292,6 +292,7 @@ "LabelEmbeddedCover": "Embedded Cover", "LabelEnable": "Enable", "LabelEnd": "End", + "LabelEndOfChapter": "End of Chapter", "LabelEpisode": "Episode", "LabelEpisodeTitle": "Episode Title", "LabelEpisodeType": "Episode Type", @@ -345,8 +346,6 @@ "LabelIntervalEveryHour": "Every hour", "LabelInvert": "Invert", "LabelItem": "Item", - "LabelJumpAmountMinutes": "{0} minutes", - "LabelJumpAmountSeconds": "{0} seconds", "LabelJumpBackwardAmount": "Jump backward amount", "LabelJumpForwardAmount": "Jump forward amount", "LabelLanguage": "Language", @@ -565,6 +564,10 @@ "LabelThemeDark": "Dark", "LabelThemeLight": "Light", "LabelTimeBase": "Time Base", + "LabelTimeDurationXHours": "{0} hours", + "LabelTimeDurationXMinutes": "{0} minutes", + "LabelTimeDurationXSeconds": "{0} seconds", + "LabelTimeInMinutes": "Time in minutes", "LabelTimeListened": "Time Listened", "LabelTimeListenedToday": "Time Listened Today", "LabelTimeRemaining": "{0} remaining", From ea11153032fc3ef0113ee0e9845253e326b3e2e1 Mon Sep 17 00:00:00 2001 From: Greg Lorenzen Date: Mon, 15 Jul 2024 15:15:06 +0000 Subject: [PATCH 05/38] Update responsive limit for displayed items on personalized shelves on home page --- client/components/app/BookShelfCategorized.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/components/app/BookShelfCategorized.vue b/client/components/app/BookShelfCategorized.vue index 23f9bc67..d7d850d5 100644 --- a/client/components/app/BookShelfCategorized.vue +++ b/client/components/app/BookShelfCategorized.vue @@ -170,7 +170,7 @@ export default { // Sets the limit for the number of items to be displayed based on the viewport width. const viewportWidth = window.innerWidth let limit - if (viewportWidth >= 3240 && viewportWidth <= 3440) { + if (viewportWidth >= 3240) { limit = 15 } else if (viewportWidth >= 2880 && viewportWidth < 3240) { limit = 12 From bc3b1d9565113769d2d27a50462728c92e793cb8 Mon Sep 17 00:00:00 2001 From: Ahetek Date: Mon, 8 Jul 2024 06:04:30 +0000 Subject: [PATCH 06/38] Translated using Weblate (Polish) Currently translated at 90.8% (756 of 832 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/pl/ --- client/strings/pl.json | 51 +++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/client/strings/pl.json b/client/strings/pl.json index 92dd2735..14aad2aa 100644 --- a/client/strings/pl.json +++ b/client/strings/pl.json @@ -62,8 +62,8 @@ "ButtonQuickMatch": "Szybkie dopasowanie", "ButtonReScan": "Ponowne skanowanie", "ButtonRead": "Czytaj", - "ButtonReadLess": "Read less", - "ButtonReadMore": "Read more", + "ButtonReadLess": "Pokaż mniej", + "ButtonReadMore": "Pokaż więcej", "ButtonRefresh": "Odśwież", "ButtonRemove": "Usuń", "ButtonRemoveAll": "Usuń wszystko", @@ -130,13 +130,13 @@ "HeaderIgnoredFiles": "Zignoruj pliki", "HeaderItemFiles": "Pliki", "HeaderItemMetadataUtils": "Item Metadata Utils", - "HeaderLastListeningSession": "Ostatnio odtwarzana sesja", + "HeaderLastListeningSession": "Ostatnia sesja słuchania", "HeaderLatestEpisodes": "Najnowsze odcinki", "HeaderLibraries": "Biblioteki", "HeaderLibraryFiles": "Pliki w bibliotece", "HeaderLibraryStats": "Statystyki biblioteki", "HeaderListeningSessions": "Sesje słuchania", - "HeaderListeningStats": "Statystyki odtwarzania", + "HeaderListeningStats": "Statystyki słuchania", "HeaderLogin": "Zaloguj się", "HeaderLogs": "Logi", "HeaderManageGenres": "Zarządzaj gatunkami", @@ -175,7 +175,7 @@ "HeaderSettingsScanner": "Skanowanie", "HeaderSleepTimer": "Wyłącznik czasowy", "HeaderStatsLargestItems": "Największe pozycje", - "HeaderStatsLongestItems": "Najdłuższe pozycje (hrs)", + "HeaderStatsLongestItems": "Najdłuższe pozycje (godziny)", "HeaderStatsMinutesListeningChart": "Czas słuchania w minutach (ostatnie 7 dni)", "HeaderStatsRecentSessions": "Ostatnie sesje", "HeaderStatsTop10Authors": "Top 10 Autorów", @@ -200,8 +200,8 @@ "LabelActivity": "Aktywność", "LabelAddToCollection": "Dodaj do kolekcji", "LabelAddToCollectionBatch": "Dodaj {0} książki do kolekcji", - "LabelAddToPlaylist": "Add to Playlist", - "LabelAddToPlaylistBatch": "Add {0} Items to Playlist", + "LabelAddToPlaylist": "Dodaj do playlisty", + "LabelAddToPlaylistBatch": "Dodaj {0} pozycji do playlisty", "LabelAdded": "Dodane", "LabelAddedAt": "Dodano", "LabelAdminUsersOnly": "Tylko użytkownicy administracyjni", @@ -226,14 +226,14 @@ "LabelBackupLocation": "Lokalizacja kopii zapasowej", "LabelBackupsEnableAutomaticBackups": "Włącz automatyczne kopie zapasowe", "LabelBackupsEnableAutomaticBackupsHelp": "Kopie zapasowe są zapisywane w folderze /metadata/backups", - "LabelBackupsMaxBackupSize": "Maksymalny łączny rozmiar backupów (w GB)", + "LabelBackupsMaxBackupSize": "Maksymalny rozmiar kopii zapasowej (w GB)", "LabelBackupsMaxBackupSizeHelp": "Jako zabezpieczenie przed błędną konfiguracją, kopie zapasowe nie będą wykonywane, jeśli przekroczą skonfigurowany rozmiar.", "LabelBackupsNumberToKeep": "Liczba kopii zapasowych do przechowywania", "LabelBackupsNumberToKeepHelp": "Tylko 1 kopia zapasowa zostanie usunięta, więc jeśli masz już więcej kopii zapasowych, powinieneś je ręcznie usunąć.", "LabelBitrate": "Bitrate", "LabelBooks": "Książki", "LabelButtonText": "Button Text", - "LabelByAuthor": "by {0}", + "LabelByAuthor": "autorstwa {0}", "LabelChangePassword": "Zmień hasło", "LabelChannels": "Kanały", "LabelChapterTitle": "Tytuł rozdziału", @@ -247,7 +247,7 @@ "LabelCollections": "Kolekcje", "LabelComplete": "Ukończone", "LabelConfirmPassword": "Potwierdź hasło", - "LabelContinueListening": "Kontynuuj odtwarzanie", + "LabelContinueListening": "Kontynuuj słuchanie", "LabelContinueReading": "Kontynuuj czytanie", "LabelContinueSeries": "Kontynuuj serię", "LabelCover": "Okładka", @@ -413,7 +413,7 @@ "LabelOverwrite": "Nadpisz", "LabelPassword": "Hasło", "LabelPath": "Ścieżka", - "LabelPermanent": "Trwały", + "LabelPermanent": "Stałe", "LabelPermissionsAccessAllLibraries": "Ma dostęp do wszystkich bibliotek", "LabelPermissionsAccessAllTags": "Ma dostęp do wszystkich tagów", "LabelPermissionsAccessExplicitContent": "Ma dostęp do treści oznacznych jako nieprzyzwoite", @@ -534,10 +534,10 @@ "LabelStatsItemsFinished": "Pozycje zakończone", "LabelStatsItemsInLibrary": "Pozycje w bibliotece", "LabelStatsMinutes": "Minuty", - "LabelStatsMinutesListening": "Minuty odtwarzania", + "LabelStatsMinutesListening": "Minuty słuchania", "LabelStatsOverallDays": "Całkowity czas (dni)", "LabelStatsOverallHours": "Całkowity czas (godziny)", - "LabelStatsWeekListening": "Tydzień odtwarzania", + "LabelStatsWeekListening": "Tydzień słuchania", "LabelSubtitle": "Podtytuł", "LabelSupportedFileTypes": "Obsługiwane typy plików", "LabelTag": "Tag", @@ -642,7 +642,7 @@ "MessageConfirmRemoveEpisodes": "Czy na pewno chcesz usunąć {0} odcinki?", "MessageConfirmRemoveListeningSessions": "Czy na pewno chcesz usunąć {0} sesji słuchania?", "MessageConfirmRemoveNarrator": "Are you sure you want to remove narrator \"{0}\"?", - "MessageConfirmRemovePlaylist": "Are you sure you want to remove your playlist \"{0}\"?", + "MessageConfirmRemovePlaylist": "Czy jesteś pewien, że chcesz usunąć twoją playlistę \"{0}\"?", "MessageConfirmRenameGenre": "Are you sure you want to rename genre \"{0}\" to \"{1}\" for all items?", "MessageConfirmRenameGenreMergeNote": "Note: This genre already exists so they will be merged.", "MessageConfirmRenameGenreWarning": "Warning! A similar genre with a different casing already exists \"{0}\".", @@ -663,7 +663,7 @@ "MessageItemsSelected": "{0} zaznaczone elementy", "MessageItemsUpdated": "{0} Items Updated", "MessageJoinUsOn": "Dołącz do nas na", - "MessageListeningSessionsInTheLastYear": "{0} sesje odsłuchowe w ostatnim roku", + "MessageListeningSessionsInTheLastYear": "Sesje słuchania w ostatnim roku: {0}", "MessageLoading": "Ładowanie...", "MessageLoadingFolders": "Ładowanie folderów...", "MessageLogsDescription": "Logi zapisane są w /metadata/logs jako pliki JSON. Logi awaryjne są zapisane w /metadata/logs/crash_logs.txt.", @@ -692,7 +692,7 @@ "MessageNoIssues": "Brak problemów", "MessageNoItems": "Brak elementów", "MessageNoItemsFound": "Nie znaleziono żadnych elementów", - "MessageNoListeningSessions": "Brak sesji odtwarzania", + "MessageNoListeningSessions": "Brak sesji słuchania", "MessageNoLogs": "Brak logów", "MessageNoMediaProgress": "Brak postępu", "MessageNoNotifications": "Brak powiadomień", @@ -709,7 +709,7 @@ "MessageOr": "lub", "MessagePauseChapter": "Zatrzymaj odtwarzanie rozdziały", "MessagePlayChapter": "Rozpocznij odtwarzanie od początku rozdziału", - "MessagePlaylistCreateFromCollection": "Utwórz listę odtwarznia na podstawie kolekcji", + "MessagePlaylistCreateFromCollection": "Utwórz listę odtwarzania na podstawie kolekcji", "MessagePodcastHasNoRSSFeedForMatching": "Podcast nie ma adresu url kanału RSS, który mógłby zostać użyty do dopasowania", "MessageQuickMatchDescription": "Wypełnij puste informacje i okładkę pierwszym wynikiem dopasowania z '{0}'. Nie nadpisuje szczegółów, chyba że włączone jest ustawienie serwera 'Preferuj dopasowane metadane'.", "MessageRemoveChapter": "Usuń rozdział", @@ -724,8 +724,9 @@ "MessageSelected": "{0} wybranych", "MessageServerCouldNotBeReached": "Nie udało się uzyskać połączenia z serwerem", "MessageSetChaptersFromTracksDescription": "Set chapters using each audio file as a chapter and chapter title as the audio file name", + "MessageShareExpirationWillBe": "Czas udostępniania {0}", "MessageShareExpiresIn": "Wygaśnie za {0}", - "MessageShareURLWillBe": "URL udziału będzie {0}", + "MessageShareURLWillBe": "Udostępnione pod linkiem {0}", "MessageStartPlaybackAtTime": "Rozpoczęcie odtwarzania \"{0}\" od {1}?", "MessageThinking": "Myślę...", "MessageUploaderItemFailed": "Nie udało się przesłać", @@ -746,7 +747,7 @@ "NoteUploaderUnsupportedFiles": "Nieobsługiwane pliki są ignorowane. Podczas dodawania folderu, inne pliki, które nie znajdują się w folderze elementu, są ignorowane.", "PlaceholderNewCollection": "Nowa nazwa kolekcji", "PlaceholderNewFolderPath": "Nowa ścieżka folderu", - "PlaceholderNewPlaylist": "New playlist name", + "PlaceholderNewPlaylist": "Nowa nazwa playlisty", "PlaceholderSearch": "Szukanie..", "PlaceholderSearchEpisode": "Szukanie odcinka..", "ToastAccountUpdateFailed": "Nie udało się zaktualizować konta", @@ -802,12 +803,12 @@ "ToastLibraryScanStarted": "Rozpoczęto skanowanie biblioteki", "ToastLibraryUpdateFailed": "Nie udało się zaktualizować biblioteki", "ToastLibraryUpdateSuccess": "Zaktualizowano \"{0}\" pozycji", - "ToastPlaylistCreateFailed": "Failed to create playlist", - "ToastPlaylistCreateSuccess": "Playlist created", - "ToastPlaylistRemoveFailed": "Failed to remove playlist", - "ToastPlaylistRemoveSuccess": "Playlist removed", - "ToastPlaylistUpdateFailed": "Failed to update playlist", - "ToastPlaylistUpdateSuccess": "Playlist updated", + "ToastPlaylistCreateFailed": "Nie udało się utworzyć playlisty", + "ToastPlaylistCreateSuccess": "Playlista utworzona", + "ToastPlaylistRemoveFailed": "Nie udało się usunąć playlisty", + "ToastPlaylistRemoveSuccess": "Playlista usunięta", + "ToastPlaylistUpdateFailed": "Nie udało się zaktualizować playlisty", + "ToastPlaylistUpdateSuccess": "Playlista zaktualizowana", "ToastPodcastCreateFailed": "Nie udało się utworzyć podcastu", "ToastPodcastCreateSuccess": "Podcast został pomyślnie utworzony", "ToastRSSFeedCloseFailed": "Zamknięcie kanału RSS nie powiodło się", From df65ef2191935a92733754f70d1f7dbd87ee0e90 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 8 Jul 2024 07:51:53 +0000 Subject: [PATCH 07/38] Translated using Weblate (German) Currently translated at 100.0% (832 of 832 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/de/ --- client/strings/de.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/strings/de.json b/client/strings/de.json index af57225f..6d48c741 100644 --- a/client/strings/de.json +++ b/client/strings/de.json @@ -512,7 +512,7 @@ "LabelSettingsStoreMetadataWithItemHelp": "Standardmäßig werden die Metadaten in /metadata/items gespeichert. Wenn diese Option aktiviert ist, werden die Metadaten als OPF-Datei (Textdatei) in dem gleichen Ordner gespeichert in welchem sich auch das Medium befindet", "LabelSettingsTimeFormat": "Zeitformat", "LabelShare": "Teilen", - "LabelShareOpen": "Teilen Offen", + "LabelShareOpen": "Teilen öffnen", "LabelShareURL": "URL teilen", "LabelShowAll": "Alles anzeigen", "LabelShowSeconds": "Zeige Sekunden", @@ -638,7 +638,7 @@ "MessageConfirmRemoveAllChapters": "Alle Kapitel werden entfernt! Bist du dir sicher?", "MessageConfirmRemoveAuthor": "Autor \"{0}\" wird enfernt! Bist du dir sicher?", "MessageConfirmRemoveCollection": "Sammlung \"{0}\" wird gelöscht! Bist du dir sicher?", - "MessageConfirmRemoveEpisode": "Episode \"{0}\" wird geloscht! Bist du dir sicher?", + "MessageConfirmRemoveEpisode": "Episode \"{0}\" wird gelöscht! Bist du dir sicher?", "MessageConfirmRemoveEpisodes": "{0} Episoden werden gelöscht! Bist du dir sicher?", "MessageConfirmRemoveListeningSessions": "Bist du dir sicher, dass du {0} Hörsitzungen enfernen möchtest?", "MessageConfirmRemoveNarrator": "Erzähler \"{0}\" wird gelöscht! Bist du dir sicher?", From 0efdf5082133bfe365726e41f93fd881f4fda894 Mon Sep 17 00:00:00 2001 From: Valentin Date: Mon, 8 Jul 2024 08:00:11 +0000 Subject: [PATCH 08/38] Translated using Weblate (German) Currently translated at 100.0% (832 of 832 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/de/ --- client/strings/de.json | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/client/strings/de.json b/client/strings/de.json index 6d48c741..319ce2a4 100644 --- a/client/strings/de.json +++ b/client/strings/de.json @@ -66,11 +66,11 @@ "ButtonReadMore": "Mehr anzeigen", "ButtonRefresh": "Neu Laden", "ButtonRemove": "Entfernen", - "ButtonRemoveAll": "Alles löschen", - "ButtonRemoveAllLibraryItems": "Lösche alle Bibliothekseinträge", - "ButtonRemoveFromContinueListening": "Lösche den Eintrag aus der Fortsetzungsliste", - "ButtonRemoveFromContinueReading": "Lösche die Serie aus der Lesefortsetzungsliste", - "ButtonRemoveSeriesFromContinueSeries": "Lösche die Serie aus der Serienfortsetzungsliste", + "ButtonRemoveAll": "Alles entfernen", + "ButtonRemoveAllLibraryItems": "Entferne alle Bibliothekseinträge", + "ButtonRemoveFromContinueListening": "Entferne den Eintrag aus der Fortsetzungsliste", + "ButtonRemoveFromContinueReading": "Entferne die Serie aus der Lesefortsetzungsliste", + "ButtonRemoveSeriesFromContinueSeries": "Entferne die Serie aus der Serienfortsetzungsliste", "ButtonReset": "Zurücksetzen", "ButtonResetToDefault": "Zurücksetzen auf Standard", "ButtonRestore": "Wiederherstellen", @@ -161,8 +161,8 @@ "HeaderRSSFeedGeneral": "RSS Details", "HeaderRSSFeedIsOpen": "RSS-Feed ist geöffnet", "HeaderRSSFeeds": "RSS-Feeds", - "HeaderRemoveEpisode": "Episode löschen", - "HeaderRemoveEpisodes": "Lösche {0} Episoden", + "HeaderRemoveEpisode": "Episode entfernen", + "HeaderRemoveEpisodes": "Entferne {0} Episoden", "HeaderSavedMediaProgress": "Gespeicherte Hörfortschritte", "HeaderSchedule": "Zeitplan", "HeaderScheduleLibraryScans": "Automatische Bibliotheksscans", @@ -259,7 +259,7 @@ "LabelCustomCronExpression": "Benutzerdefinierter Cron-Ausdruck:", "LabelDatetime": "Datum & Uhrzeit", "LabelDays": "Tage", - "LabelDeleteFromFileSystemCheckbox": "Löschen von der Festplatte + Datenbank (deaktivieren um nur aus der Datenbank zu löschen)", + "LabelDeleteFromFileSystemCheckbox": "Löschen von der Festplatte + Datenbank (deaktivieren um nur aus der Datenbank zu entfernen)", "LabelDescription": "Beschreibung", "LabelDeselectAll": "Alles abwählen", "LabelDevice": "Gerät", @@ -455,7 +455,7 @@ "LabelRedo": "Wiederholen", "LabelRegion": "Region", "LabelReleaseDate": "Veröffentlichungsdatum", - "LabelRemoveCover": "Lösche Titelbild", + "LabelRemoveCover": "Entferne Titelbild", "LabelRowsPerPage": "Zeilen pro Seite", "LabelSearchTerm": "Begriff suchen", "LabelSearchTitle": "Titel suchen", @@ -637,7 +637,7 @@ "MessageConfirmReScanLibraryItems": "{0} Elemente werden erneut gescannt! Bist du dir sicher?", "MessageConfirmRemoveAllChapters": "Alle Kapitel werden entfernt! Bist du dir sicher?", "MessageConfirmRemoveAuthor": "Autor \"{0}\" wird enfernt! Bist du dir sicher?", - "MessageConfirmRemoveCollection": "Sammlung \"{0}\" wird gelöscht! Bist du dir sicher?", + "MessageConfirmRemoveCollection": "Sammlung \"{0}\" wird entfernt! Bist du dir sicher?", "MessageConfirmRemoveEpisode": "Episode \"{0}\" wird gelöscht! Bist du dir sicher?", "MessageConfirmRemoveEpisodes": "{0} Episoden werden gelöscht! Bist du dir sicher?", "MessageConfirmRemoveListeningSessions": "Bist du dir sicher, dass du {0} Hörsitzungen enfernen möchtest?", @@ -712,9 +712,9 @@ "MessagePlaylistCreateFromCollection": "Erstelle eine Wiedergabeliste aus der Sammlung", "MessagePodcastHasNoRSSFeedForMatching": "Der Podcast hat keine RSS-Feed-Url welche für den Online-Abgleich verwendet werden kann", "MessageQuickMatchDescription": "Füllt leere Details und Titelbilder mit dem ersten Treffer aus '{0}'. Überschreibt keine Details, es sei denn, die Server-Einstellung \"Passende Metadaten bevorzugen\" ist aktiviert.", - "MessageRemoveChapter": "Kapitel löschen", + "MessageRemoveChapter": "Kapitel entfernen", "MessageRemoveEpisodes": "Entferne {0} Episode(n)", - "MessageRemoveFromPlayerQueue": "Aus der Abspielwarteliste löschen", + "MessageRemoveFromPlayerQueue": "Aus der Abspielwarteliste entfernen", "MessageRemoveUserWarning": "Benutzer \"{0}\" wird dauerhaft gelöscht! Bist du dir sicher?", "MessageReportBugsAndContribute": "Fehler melden, Funktionen anfordern und mitwirken", "MessageResetChaptersConfirm": "Kapitel und vorgenommenen Änderungen werden zurückgesetzt und rückgängig gemacht! Bist du dir sicher?", @@ -769,8 +769,8 @@ "ToastBatchUpdateSuccess": "Stapelaktualisierung erfolgreich", "ToastBookmarkCreateFailed": "Lesezeichen konnte nicht erstellt werden", "ToastBookmarkCreateSuccess": "Lesezeichen hinzugefügt", - "ToastBookmarkRemoveFailed": "Lesezeichen konnte nicht gelöscht werden", - "ToastBookmarkRemoveSuccess": "Lesezeichen gelöscht", + "ToastBookmarkRemoveFailed": "Lesezeichen konnte nicht entfernt werden", + "ToastBookmarkRemoveSuccess": "Lesezeichen entfernt", "ToastBookmarkUpdateFailed": "Lesezeichenaktualisierung fehlgeschlagen", "ToastBookmarkUpdateSuccess": "Lesezeichen aktualisiert", "ToastCachePurgeFailed": "Cache leeren fehlgeschlagen", @@ -780,7 +780,7 @@ "ToastCollectionItemsRemoveFailed": "Fehler beim Entfernen der Medien aus der Sammlung", "ToastCollectionItemsRemoveSuccess": "Medien aus der Sammlung entfernt", "ToastCollectionRemoveFailed": "Sammlung konnte nicht entfernt werden", - "ToastCollectionRemoveSuccess": "Sammlung gelöscht", + "ToastCollectionRemoveSuccess": "Sammlung entfernt", "ToastCollectionUpdateFailed": "Sammlung konnte nicht aktualisiert werden", "ToastCollectionUpdateSuccess": "Sammlung aktualisiert", "ToastDeleteFileFailed": "Die Datei konnte nicht gelöscht werden", From 1c650473f864b5d1d05d2710f21059e6543aaa65 Mon Sep 17 00:00:00 2001 From: Valentin Date: Mon, 8 Jul 2024 08:03:30 +0000 Subject: [PATCH 09/38] Translated using Weblate (German) Currently translated at 100.0% (832 of 832 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/de/ --- client/strings/de.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/strings/de.json b/client/strings/de.json index 319ce2a4..a3c0d604 100644 --- a/client/strings/de.json +++ b/client/strings/de.json @@ -638,10 +638,10 @@ "MessageConfirmRemoveAllChapters": "Alle Kapitel werden entfernt! Bist du dir sicher?", "MessageConfirmRemoveAuthor": "Autor \"{0}\" wird enfernt! Bist du dir sicher?", "MessageConfirmRemoveCollection": "Sammlung \"{0}\" wird entfernt! Bist du dir sicher?", - "MessageConfirmRemoveEpisode": "Episode \"{0}\" wird gelöscht! Bist du dir sicher?", - "MessageConfirmRemoveEpisodes": "{0} Episoden werden gelöscht! Bist du dir sicher?", + "MessageConfirmRemoveEpisode": "Episode \"{0}\" wird entfernt! Bist du dir sicher?", + "MessageConfirmRemoveEpisodes": "{0} Episoden werden entfernt! Bist du dir sicher?", "MessageConfirmRemoveListeningSessions": "Bist du dir sicher, dass du {0} Hörsitzungen enfernen möchtest?", - "MessageConfirmRemoveNarrator": "Erzähler \"{0}\" wird gelöscht! Bist du dir sicher?", + "MessageConfirmRemoveNarrator": "Erzähler \"{0}\" wird entfernt! Bist du dir sicher?", "MessageConfirmRemovePlaylist": "Wiedergabeliste \"{0}\" wird entfernt! Bist du dir sicher?", "MessageConfirmRenameGenre": "Kategorie \"{0}\" in \"{1}\" für alle Hörbücher/Podcasts werden umbenannt! Bist du dir sicher?", "MessageConfirmRenameGenreMergeNote": "Hinweis: Kategorie existiert bereits -> Kategorien werden zusammengelegt.", From 075ec15f025e30c21e46c6f9d1de82394fb2011a Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Mon, 8 Jul 2024 21:21:33 +0000 Subject: [PATCH 10/38] Translated using Weblate (Spanish) Currently translated at 100.0% (832 of 832 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/es/ --- client/strings/es.json | 1 + 1 file changed, 1 insertion(+) diff --git a/client/strings/es.json b/client/strings/es.json index 93a99abc..32a7d7c4 100644 --- a/client/strings/es.json +++ b/client/strings/es.json @@ -512,6 +512,7 @@ "LabelSettingsStoreMetadataWithItemHelp": "Por defecto, los archivos de metadatos se almacenan en /metadata/items. Si habilita esta opción, los archivos de metadatos se guardarán en la carpeta de elementos de su biblioteca", "LabelSettingsTimeFormat": "Formato de Tiempo", "LabelShare": "Compartir", + "LabelShareOpen": "abrir un recurso compartido", "LabelShareURL": "Compartir la URL", "LabelShowAll": "Mostrar Todos", "LabelShowSeconds": "Mostrar segundos", From af9aee76cf969f9e1594bcc62038aa8a072d78fe Mon Sep 17 00:00:00 2001 From: Lode Smets Date: Mon, 8 Jul 2024 17:01:16 +0000 Subject: [PATCH 11/38] Translated using Weblate (Dutch) Currently translated at 86.7% (722 of 832 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/nl/ --- client/strings/nl.json | 59 ++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/client/strings/nl.json b/client/strings/nl.json index 18bb4218..e209c3a5 100644 --- a/client/strings/nl.json +++ b/client/strings/nl.json @@ -1,15 +1,15 @@ { "ButtonAdd": "Toevoegen", "ButtonAddChapters": "Hoofdstukken toevoegen", - "ButtonAddDevice": "Add Device", - "ButtonAddLibrary": "Add Library", + "ButtonAddDevice": "Toestel toevoegen", + "ButtonAddLibrary": "Bibliotheek toevoegen", "ButtonAddPodcasts": "Podcasts toevoegen", - "ButtonAddUser": "Add User", + "ButtonAddUser": "Gebruiker toevoegen", "ButtonAddYourFirstLibrary": "Voeg je eerste bibliotheek toe", "ButtonApply": "Pas toe", "ButtonApplyChapters": "Hoofdstukken toepassen", "ButtonAuthors": "Auteurs", - "ButtonBack": "Back", + "ButtonBack": "Terug", "ButtonBrowseForFolder": "Bladeren naar map", "ButtonCancel": "Annuleren", "ButtonCancelEncode": "Encoding annuleren", @@ -32,9 +32,9 @@ "ButtonFullPath": "Volledig pad", "ButtonHide": "Verberg", "ButtonHome": "Home", - "ButtonIssues": "Issues", - "ButtonJumpBackward": "Jump Backward", - "ButtonJumpForward": "Jump Forward", + "ButtonIssues": "Problemen", + "ButtonJumpBackward": "Spring achteruit", + "ButtonJumpForward": "Spring vooruit", "ButtonLatest": "Meest recent", "ButtonLibrary": "Bibliotheek", "ButtonLogout": "Log uit", @@ -44,17 +44,17 @@ "ButtonMatchAllAuthors": "Alle auteurs matchen", "ButtonMatchBooks": "Alle boeken matchen", "ButtonNevermind": "Laat maar", - "ButtonNext": "Next", - "ButtonNextChapter": "Next Chapter", + "ButtonNext": "Volgende", + "ButtonNextChapter": "Volgend hoofdstuk", "ButtonOk": "Ok", "ButtonOpenFeed": "Feed openen", "ButtonOpenManager": "Manager openen", - "ButtonPause": "Pause", + "ButtonPause": "Pauze", "ButtonPlay": "Afspelen", "ButtonPlaying": "Speelt", "ButtonPlaylists": "Afspeellijsten", - "ButtonPrevious": "Previous", - "ButtonPreviousChapter": "Previous Chapter", + "ButtonPrevious": "Vorige", + "ButtonPreviousChapter": "Vorig hoofdstuk", "ButtonPurgeAllCache": "Volledige cache legen", "ButtonPurgeItemsCache": "Onderdelen-cache legen", "ButtonQueueAddItem": "In wachtrij zetten", @@ -62,14 +62,14 @@ "ButtonQuickMatch": "Snelle match", "ButtonReScan": "Nieuwe scan", "ButtonRead": "Lees", - "ButtonReadLess": "Read less", - "ButtonReadMore": "Read more", - "ButtonRefresh": "Refresh", + "ButtonReadLess": "Lees minder", + "ButtonReadMore": "Lees meer", + "ButtonRefresh": "Verversen", "ButtonRemove": "Verwijder", "ButtonRemoveAll": "Alles verwijderen", "ButtonRemoveAllLibraryItems": "Verwijder volledige bibliotheekinhoud", "ButtonRemoveFromContinueListening": "Vewijder uit Verder luisteren", - "ButtonRemoveFromContinueReading": "Remove from Continue Reading", + "ButtonRemoveFromContinueReading": "Verwijder van Verder luisteren", "ButtonRemoveSeriesFromContinueSeries": "Verwijder serie uit Serie vervolgen", "ButtonReset": "Reset", "ButtonResetToDefault": "Reset to default", @@ -83,7 +83,7 @@ "ButtonSelectFolderPath": "Maplocatie selecteren", "ButtonSeries": "Series", "ButtonSetChaptersFromTracks": "Maak hoofdstukken op basis van tracks", - "ButtonShare": "Share", + "ButtonShare": "Deel", "ButtonShiftTimes": "Tijden verschuiven", "ButtonShow": "Toon", "ButtonStartM4BEncode": "Start M4B-encoding", @@ -98,9 +98,9 @@ "ButtonUserEdit": "Wijzig gebruiker {0}", "ButtonViewAll": "Toon alle", "ButtonYes": "Ja", - "ErrorUploadFetchMetadataAPI": "Error fetching metadata", - "ErrorUploadFetchMetadataNoResults": "Could not fetch metadata - try updating title and/or author", - "ErrorUploadLacksTitle": "Must have a title", + "ErrorUploadFetchMetadataAPI": "Error metadata ophalen", + "ErrorUploadFetchMetadataNoResults": "Kan metadata niet ophalen - probeer de titel en/of auteur te updaten", + "ErrorUploadLacksTitle": "Moet een titel hebben", "HeaderAccount": "Account", "HeaderAdvanced": "Geavanceerd", "HeaderAppriseNotificationSettings": "Apprise-notificatie instellingen", @@ -113,13 +113,13 @@ "HeaderChooseAFolder": "Map kiezen", "HeaderCollection": "Collectie", "HeaderCollectionItems": "Collectie-objecten", - "HeaderCover": "Cover", + "HeaderCover": "Omslag", "HeaderCurrentDownloads": "Huidige downloads", "HeaderCustomMessageOnLogin": "Custom Message on Login", "HeaderCustomMetadataProviders": "Custom Metadata Providers", "HeaderDetails": "Details", "HeaderDownloadQueue": "Download-wachtrij", - "HeaderEbookFiles": "Ebook Files", + "HeaderEbookFiles": "Ebook bestanden", "HeaderEmail": "E-mail", "HeaderEmailSettings": "E-mail instellingen", "HeaderEpisodes": "Afleveringen", @@ -239,11 +239,11 @@ "LabelChapterTitle": "Hoofdstuktitel", "LabelChapters": "Hoofdstukken", "LabelChaptersFound": "Hoofdstukken gevonden", - "LabelClickForMoreInfo": "Click for more info", + "LabelClickForMoreInfo": "Klik voor meer informatie", "LabelClosePlayer": "Sluit speler", "LabelCodec": "Codec", "LabelCollapseSeries": "Series inklappen", - "LabelCollection": "Collection", + "LabelCollection": "Collectie", "LabelCollections": "Collecties", "LabelComplete": "Compleet", "LabelConfirmPassword": "Bevestig wachtwoord", @@ -258,6 +258,7 @@ "LabelCurrently": "Op dit moment:", "LabelCustomCronExpression": "Aangepaste Cron-uitdrukking:", "LabelDatetime": "Datum-tijd", + "LabelDays": "Dagen", "LabelDeleteFromFileSystemCheckbox": "Delete from file system (uncheck to only remove from database)", "LabelDescription": "Beschrijving", "LabelDeselectAll": "Deselecteer alle", @@ -296,7 +297,7 @@ "LabelExplicitChecked": "Explicit (checked)", "LabelExplicitUnchecked": "Not Explicit (unchecked)", "LabelFeedURL": "Feed URL", - "LabelFetchingMetadata": "Fetching Metadata", + "LabelFetchingMetadata": "Metadata ophalen", "LabelFile": "Bestand", "LabelFileBirthtime": "Aanmaaktijd bestand", "LabelFileModified": "Bestand gewijzigd", @@ -306,7 +307,7 @@ "LabelFinished": "Voltooid", "LabelFolder": "Map", "LabelFolders": "Mappen", - "LabelFontBold": "Bold", + "LabelFontBold": "Vetgedrukt", "LabelFontBoldness": "Font Boldness", "LabelFontFamily": "Lettertypefamilie", "LabelFontItalic": "Italic", @@ -321,6 +322,7 @@ "LabelHighestPriority": "Highest priority", "LabelHost": "Host", "LabelHour": "Uur", + "LabelHours": "Uren", "LabelIcon": "Icoon", "LabelImageURLFromTheWeb": "Image URL from the web", "LabelInProgress": "Bezig", @@ -567,7 +569,7 @@ "LabelTracksSingleTrack": "Enkele track", "LabelType": "Type", "LabelUnabridged": "Onverkort", - "LabelUndo": "Undo", + "LabelUndo": "Ongedaan maken", "LabelUnknown": "Onbekend", "LabelUpdateCover": "Cover bijwerken", "LabelUpdateCoverHelp": "Sta overschrijven van bestaande covers toe voor de geselecteerde boeken wanneer een match is gevonden", @@ -630,7 +632,7 @@ "MessageConfirmRemoveCollection": "Weet je zeker dat je de collectie \"{0}\" wil verwijderen?", "MessageConfirmRemoveEpisode": "Weet je zeker dat je de aflevering \"{0}\" wil verwijderen?", "MessageConfirmRemoveEpisodes": "Weet je zeker dat je {0} afleveringen wil verwijderen?", - "MessageConfirmRemoveListeningSessions": "Are you sure you want to remove {0} listening sessions?", + "MessageConfirmRemoveListeningSessions": "Weet je zeker dat je {0} luistersessies wilt verwijderen?", "MessageConfirmRemoveNarrator": "Weet je zeker dat je verteller \"{0}\" wil verwijderen?", "MessageConfirmRemovePlaylist": "Weet je zeker dat je je afspeellijst \"{0}\" wil verwijderen?", "MessageConfirmRenameGenre": "Weet je zeker dat je genre \"{0}\" wil hernoemen naar \"{1}\" voor alle onderdelen?", @@ -714,6 +716,7 @@ "MessageSelected": "{0} selected", "MessageServerCouldNotBeReached": "Server niet bereikbaar", "MessageSetChaptersFromTracksDescription": "Stel hoofdstukken in met ieder audiobestand als een hoofdstuk en de audiobestandsnaam als hoofdstuktitel", + "MessageShareExpiresIn": "Vervalt in {0}", "MessageStartPlaybackAtTime": "Afspelen van \"{0}\" beginnen op {1}?", "MessageThinking": "Aan het denken...", "MessageUploaderItemFailed": "Uploaden mislukt", From 7fb499b301af68ad290b047693ee9df74dc5210d Mon Sep 17 00:00:00 2001 From: Charlie Date: Tue, 9 Jul 2024 06:54:21 +0000 Subject: [PATCH 12/38] Translated using Weblate (French) Currently translated at 100.0% (832 of 832 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/fr/ --- client/strings/fr.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/client/strings/fr.json b/client/strings/fr.json index 5aceef63..afab77a1 100644 --- a/client/strings/fr.json +++ b/client/strings/fr.json @@ -258,6 +258,7 @@ "LabelCurrently": "Actuellement :", "LabelCustomCronExpression": "Expression cron personnalisée :", "LabelDatetime": "Date", + "LabelDays": "Jours", "LabelDeleteFromFileSystemCheckbox": "Supprimer du système de fichiers (décocher pour ne supprimer que de la base de données)", "LabelDescription": "Description", "LabelDeselectAll": "Tout déselectionner", @@ -321,6 +322,7 @@ "LabelHighestPriority": "Priorité la plus élevée", "LabelHost": "Hôte", "LabelHour": "Heure", + "LabelHours": "Heures", "LabelIcon": "Icône", "LabelImageURLFromTheWeb": "URL de l’image à partir du web", "LabelInProgress": "En cours", @@ -371,6 +373,7 @@ "LabelMetadataOrderOfPrecedenceDescription": "Les sources de métadonnées ayant une priorité plus élevée auront la priorité sur celles ayant une priorité moins élevée", "LabelMetadataProvider": "Fournisseur de métadonnées", "LabelMinute": "Minute", + "LabelMinutes": "Minutes", "LabelMissing": "Manquant", "LabelMissingEbook": "Ne possède aucun livre numérique", "LabelMissingSupplementaryEbook": "Ne possède aucun livre numérique supplémentaire", @@ -410,6 +413,7 @@ "LabelOverwrite": "Écraser", "LabelPassword": "Mot de passe", "LabelPath": "Chemin", + "LabelPermanent": "Permanent", "LabelPermissionsAccessAllLibraries": "Peut accéder à toutes les bibliothèque", "LabelPermissionsAccessAllTags": "Peut accéder à toutes les étiquettes", "LabelPermissionsAccessExplicitContent": "Peut accéder au contenu restreint", @@ -507,6 +511,9 @@ "LabelSettingsStoreMetadataWithItem": "Enregistrer les métadonnées avec l’élément", "LabelSettingsStoreMetadataWithItemHelp": "Par défaut, les fichiers de métadonnées sont stockés dans /metadata/items. En activant ce paramètre, les fichiers de métadonnées seront stockés dans les dossiers des éléments de votre bibliothèque", "LabelSettingsTimeFormat": "Format d’heure", + "LabelShare": "Partager", + "LabelShareOpen": "Ouvrir le partage", + "LabelShareURL": "Partager l’URL", "LabelShowAll": "Tout afficher", "LabelShowSeconds": "Afficher les seondes", "LabelSize": "Taille", @@ -598,6 +605,7 @@ "MessageAppriseDescription": "Nécessite une instance d’API Apprise pour utiliser cette fonctionnalité ou une api qui prend en charge les mêmes requêtes.
L’URL de l’API Apprise doit comprendre le chemin complet pour envoyer la notification. Par exemple, si votre instance écoute sur http://192.168.1.1:8337 alors vous devez mettre http://192.168.1.1:8337/notify.", "MessageBackupsDescription": "Les sauvegardes incluent les utilisateurs, la progression des utilisateurs, les détails des éléments de la bibliothèque, les paramètres du serveur et les images stockées dans /metadata/items & /metadata/authors. Les sauvegardes n’incluent pas les fichiers stockés dans les dossiers de votre bibliothèque.", "MessageBackupsLocationEditNote": "Remarque : Mettre à jour l'emplacement de sauvegarde ne déplacera pas ou ne modifiera pas les sauvegardes existantes", + "MessageBackupsLocationNoEditNote": "Remarque : l’emplacement de sauvegarde est défini via une variable d’environnement et ne peut pas être modifié ici.", "MessageBackupsLocationPathEmpty": "L'emplacement de secours ne peut pas être vide", "MessageBatchQuickMatchDescription": "La recherche par correspondance rapide tentera d’ajouter les couvertures et métadonnées manquantes pour les éléments sélectionnés. Activez les options ci-dessous pour permettre la Recherche par correspondance d’écraser les couvertures et/ou métadonnées existantes.", "MessageBookshelfNoCollections": "Vous n’avez pas encore de collections", @@ -716,6 +724,9 @@ "MessageSelected": "{0} sélectionnés", "MessageServerCouldNotBeReached": "Serveur inaccessible", "MessageSetChaptersFromTracksDescription": "Positionne un chapitre par fichier audio, avec le titre du fichier comme titre de chapitre", + "MessageShareExpirationWillBe": "Expire le {0}", + "MessageShareExpiresIn": "Expire dans {0}", + "MessageShareURLWillBe": "L’adresse de partage sera {0}", "MessageStartPlaybackAtTime": "Démarrer la lecture pour « {0} » à {1} ?", "MessageThinking": "Je cherche…", "MessageUploaderItemFailed": "Échec du téléversement", @@ -730,7 +741,7 @@ "NoteChapterEditorTimes": "Information : l’horodatage du premier chapitre doit être à 0:00 et celui du dernier chapitre ne peut se situer au-delà de la durée du livre audio.", "NoteFolderPicker": "Information : les dossiers déjà surveillés ne sont pas affichés", "NoteRSSFeedPodcastAppsHttps": "Attention : la majorité des application de podcast nécessite une adresse de flux HTTPS", - "NoteRSSFeedPodcastAppsPubDate": "Attention : un ou plusieurs de vos épisodes ne possèdent pas de date de publication. Certaines applications de podcast le requièrent.", + "NoteRSSFeedPodcastAppsPubDate": "Attention : un ou plusieurs de vos épisodes ne possèdent pas de date de publication. Certaines applications de podcast le requièrent.", "NoteUploaderFoldersWithMediaFiles": "Les dossiers contenant des fichiers multimédias seront traités comme des éléments distincts de la bibliothèque.", "NoteUploaderOnlyAudioFiles": "Si vous téléversez uniquement des fichiers audio, chaque fichier audio sera traité comme un livre audio distinct.", "NoteUploaderUnsupportedFiles": "Les fichiers non pris en charge sont ignorés. Lorsque vous choisissez ou déposez un dossier, les autres fichiers qui ne sont pas dans un dossier d’élément sont ignorés.", From 2a98e2c361c9f69761d510ebe197787789a4dad6 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 10 Jul 2024 07:08:03 +0000 Subject: [PATCH 13/38] Translated using Weblate (German) Currently translated at 100.0% (838 of 838 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/de/ --- client/strings/de.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/strings/de.json b/client/strings/de.json index a3c0d604..ba3bc869 100644 --- a/client/strings/de.json +++ b/client/strings/de.json @@ -59,6 +59,7 @@ "ButtonPurgeItemsCache": "Lösche Medien-Cache", "ButtonQueueAddItem": "Zur Warteschlange hinzufügen", "ButtonQueueRemoveItem": "Aus der Warteschlange entfernen", + "ButtonQuickEmbedMetadata": "Schnelles Hinzufügen von Metadaten", "ButtonQuickMatch": "Schnellabgleich", "ButtonReScan": "Neu scannen", "ButtonRead": "Lesen", @@ -293,9 +294,11 @@ "LabelEpisodeTitle": "Episodentitel", "LabelEpisodeType": "Episodentyp", "LabelExample": "Beispiel", + "LabelExpandSeries": "Serie erweitern", "LabelExplicit": "Explizit (Altersbeschränkung)", "LabelExplicitChecked": "Explicit (Altersbeschränkung) (angehakt)", "LabelExplicitUnchecked": "Not Explicit (Altersbeschränkung) (nicht angehakt)", + "LabelExportOPML": "OPML exportieren", "LabelFeedURL": "Feed URL", "LabelFetchingMetadata": "Abholen der Metadaten", "LabelFile": "Datei", @@ -319,6 +322,7 @@ "LabelHardDeleteFile": "Datei dauerhaft löschen", "LabelHasEbook": "E-Book verfügbar", "LabelHasSupplementaryEbook": "Ergänzendes E-Book verfügbar", + "LabelHideSubtitles": "Untertitel ausblenden", "LabelHighestPriority": "Höchste Priorität", "LabelHost": "Host", "LabelHour": "Stunde", @@ -446,6 +450,7 @@ "LabelRSSFeedPreventIndexing": "Indizierung verhindern", "LabelRSSFeedSlug": "RSS-Feed-Schlagwort", "LabelRSSFeedURL": "RSS Feed URL", + "LabelReAddSeriesToContinueListening": "Serien erneut zur Fortsetzungsliste hinzufügen", "LabelRead": "Lesen", "LabelReadAgain": "Noch einmal Lesen", "LabelReadEbookWithoutProgress": "E-Book lesen und Fortschritt verwerfen", @@ -516,6 +521,7 @@ "LabelShareURL": "URL teilen", "LabelShowAll": "Alles anzeigen", "LabelShowSeconds": "Zeige Sekunden", + "LabelShowSubtitles": "Untertitel anzeigen", "LabelSize": "Größe", "LabelSleepTimer": "Schlummerfunktion", "LabelSlug": "URL Teil", From 7ea5e7dc95d58067817eeb8dab47df786e77749f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pomara=C5=84ski?= Date: Wed, 10 Jul 2024 08:58:47 +0000 Subject: [PATCH 14/38] Translated using Weblate (Polish) Currently translated at 90.4% (758 of 838 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/pl/ --- client/strings/pl.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/strings/pl.json b/client/strings/pl.json index 14aad2aa..9a945e9e 100644 --- a/client/strings/pl.json +++ b/client/strings/pl.json @@ -148,7 +148,7 @@ "HeaderNewAccount": "Nowe konto", "HeaderNewLibrary": "Nowa biblioteka", "HeaderNotifications": "Powiadomienia", - "HeaderOpenIDConnectAuthentication": "OpenID Connect Authentication", + "HeaderOpenIDConnectAuthentication": "Uwierzytelnianie OpenID Connect", "HeaderOpenRSSFeed": "Utwórz kanał RSS", "HeaderOtherFiles": "Inne pliki", "HeaderPasswordAuthentication": "Uwierzytelnianie hasłem", @@ -319,6 +319,7 @@ "LabelHardDeleteFile": "Usuń trwale plik", "LabelHasEbook": "Ma ebooka", "LabelHasSupplementaryEbook": "Posiada dodatkowy ebook", + "LabelHideSubtitles": "Ukryj napisy", "LabelHighestPriority": "Najwyższy priorytet", "LabelHost": "Host", "LabelHour": "Godzina", From 11c6fc7d903b4c5056a169d116188e932ed0c1c2 Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Thu, 11 Jul 2024 10:03:22 +0000 Subject: [PATCH 15/38] Translated using Weblate (Spanish) Currently translated at 100.0% (838 of 838 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/es/ --- client/strings/es.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/strings/es.json b/client/strings/es.json index 32a7d7c4..660d3658 100644 --- a/client/strings/es.json +++ b/client/strings/es.json @@ -59,6 +59,7 @@ "ButtonPurgeItemsCache": "Purgar Elementos de Cache", "ButtonQueueAddItem": "Agregar a la Fila", "ButtonQueueRemoveItem": "Remover de la Fila", + "ButtonQuickEmbedMetadata": "Agregue metadatos rápidamente", "ButtonQuickMatch": "Encontrar Rápido", "ButtonReScan": "Re-Escanear", "ButtonRead": "Leer", @@ -293,9 +294,11 @@ "LabelEpisodeTitle": "Titulo de Episodio", "LabelEpisodeType": "Tipo de Episodio", "LabelExample": "Ejemplo", + "LabelExpandSeries": "Ampliar serie", "LabelExplicit": "Explicito", "LabelExplicitChecked": "Explícito (marcado)", "LabelExplicitUnchecked": "No Explícito (sin marcar)", + "LabelExportOPML": "Exportar OPML", "LabelFeedURL": "Fuente de URL", "LabelFetchingMetadata": "Obteniendo metadatos", "LabelFile": "Archivo", @@ -319,6 +322,7 @@ "LabelHardDeleteFile": "Eliminar Definitivamente", "LabelHasEbook": "Tiene un libro", "LabelHasSupplementaryEbook": "Tiene un libro complementario", + "LabelHideSubtitles": "Ocultar subtítulos", "LabelHighestPriority": "Mayor prioridad", "LabelHost": "Host", "LabelHour": "Hora", @@ -446,6 +450,7 @@ "LabelRSSFeedPreventIndexing": "Prevenir indexado", "LabelRSSFeedSlug": "Fuente RSS Slug", "LabelRSSFeedURL": "URL de Fuente RSS", + "LabelReAddSeriesToContinueListening": "Volver a agregar la serie para continuar escuchándola", "LabelRead": "Leído", "LabelReadAgain": "Volver a leer", "LabelReadEbookWithoutProgress": "Leer Ebook sin guardar progreso", @@ -516,6 +521,7 @@ "LabelShareURL": "Compartir la URL", "LabelShowAll": "Mostrar Todos", "LabelShowSeconds": "Mostrar segundos", + "LabelShowSubtitles": "Mostrar subtítulos", "LabelSize": "Tamaño", "LabelSleepTimer": "Temporizador de apagado", "LabelSlug": "Slug", From fec94c18aa8379183aa0f0b50f9a295a46d44525 Mon Sep 17 00:00:00 2001 From: Mario Date: Sat, 13 Jul 2024 12:24:32 +0000 Subject: [PATCH 16/38] Translated using Weblate (German) Currently translated at 100.0% (844 of 844 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/de/ --- client/strings/de.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/strings/de.json b/client/strings/de.json index ba3bc869..cbab04d4 100644 --- a/client/strings/de.json +++ b/client/strings/de.json @@ -155,6 +155,7 @@ "HeaderPasswordAuthentication": "Passwort Authentifizierung", "HeaderPermissions": "Berechtigungen", "HeaderPlayerQueue": "Player Warteschlange", + "HeaderPlayerSettings": "Player Einstellungen", "HeaderPlaylist": "Wiedergabeliste", "HeaderPlaylistItems": "Einträge in der Wiedergabeliste", "HeaderPodcastsToAdd": "Podcasts zum Hinzufügen", @@ -343,6 +344,10 @@ "LabelIntervalEveryHour": "Jede Stunde", "LabelInvert": "Umkehren", "LabelItem": "Medium", + "LabelJumpAmountMinutes": "{0} Minuten", + "LabelJumpAmountSeconds": "{0} Sekunden", + "LabelJumpBackwardAmount": "Zurückspringen Zeit", + "LabelJumpForwardAmount": "Vorwärtsspringn Zeit", "LabelLanguage": "Sprache", "LabelLanguageDefaultServer": "Standard-Server-Sprache", "LabelLanguages": "Sprachen", @@ -598,6 +603,7 @@ "LabelVersion": "Version", "LabelViewBookmarks": "Lesezeichen anzeigen", "LabelViewChapters": "Kapitel anzeigen", + "LabelViewPlayerSettings": "Zeige player Einstellungen", "LabelViewQueue": "Player-Warteschlange anzeigen", "LabelVolume": "Lautstärke", "LabelWeekdaysToRun": "Wochentage für die Ausführung", From da671e3fd52f3648be008900498ac3676d1a8bc6 Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Sat, 13 Jul 2024 09:24:07 +0000 Subject: [PATCH 17/38] Translated using Weblate (Spanish) Currently translated at 100.0% (844 of 844 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/es/ --- client/strings/es.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/strings/es.json b/client/strings/es.json index 660d3658..b8550677 100644 --- a/client/strings/es.json +++ b/client/strings/es.json @@ -155,6 +155,7 @@ "HeaderPasswordAuthentication": "Autenticación por contraseña", "HeaderPermissions": "Permisos", "HeaderPlayerQueue": "Fila del Reproductor", + "HeaderPlayerSettings": "Ajustes del reproductor", "HeaderPlaylist": "Lista de reproducción", "HeaderPlaylistItems": "Elementos de lista de reproducción", "HeaderPodcastsToAdd": "Podcasts para agregar", @@ -343,6 +344,10 @@ "LabelIntervalEveryHour": "Cada Hora", "LabelInvert": "Invertir", "LabelItem": "Elemento", + "LabelJumpAmountMinutes": "{0} minutos", + "LabelJumpAmountSeconds": "{0} segundos", + "LabelJumpBackwardAmount": "Cantidad de saltos hacia atrás", + "LabelJumpForwardAmount": "Cantidad de saltos hacia adelante", "LabelLanguage": "Idioma", "LabelLanguageDefaultServer": "Lenguaje Predeterminado del Servidor", "LabelLanguages": "Idiomas", @@ -598,6 +603,7 @@ "LabelVersion": "Versión", "LabelViewBookmarks": "Ver Marcadores", "LabelViewChapters": "Ver Capítulos", + "LabelViewPlayerSettings": "Ver los ajustes del reproductor", "LabelViewQueue": "Ver Fila del Reproductor", "LabelVolume": "Volumen", "LabelWeekdaysToRun": "Correr en Días de la Semana", From 0befe913607f0107e03a0f11954ffc42364525ce Mon Sep 17 00:00:00 2001 From: Ori Z Date: Sat, 13 Jul 2024 09:57:45 +0000 Subject: [PATCH 18/38] Translated using Weblate (Hebrew) Currently translated at 92.2% (779 of 844 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/he/ --- client/strings/he.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/strings/he.json b/client/strings/he.json index aa6eb986..51463940 100644 --- a/client/strings/he.json +++ b/client/strings/he.json @@ -9,7 +9,7 @@ "ButtonApply": "החל", "ButtonApplyChapters": "החל פרקים", "ButtonAuthors": "יוצרים", - "ButtonBack": "Back", + "ButtonBack": "חזור", "ButtonBrowseForFolder": "עיין בתיקייה", "ButtonCancel": "בטל", "ButtonCancelEncode": "בטל קידוד", @@ -62,8 +62,8 @@ "ButtonQuickMatch": "התאמה מהירה", "ButtonReScan": "סרוק מחדש", "ButtonRead": "קרא", - "ButtonReadLess": "Read less", - "ButtonReadMore": "Read more", + "ButtonReadLess": "קרא פחות", + "ButtonReadMore": "קרא יותר", "ButtonRefresh": "רענן", "ButtonRemove": "הסר", "ButtonRemoveAll": "הסר הכל", @@ -115,7 +115,7 @@ "HeaderCollectionItems": "פריטי אוסף", "HeaderCover": "כריכה", "HeaderCurrentDownloads": "הורדות נוכחיות", - "HeaderCustomMessageOnLogin": "Custom Message on Login", + "HeaderCustomMessageOnLogin": "הודעה מותאמת אישית בהתחברות", "HeaderCustomMetadataProviders": "ספקי מטא-נתונים מותאמים אישית", "HeaderDetails": "פרטים", "HeaderDownloadQueue": "תור הורדה", @@ -806,8 +806,8 @@ "ToastSendEbookToDeviceSuccess": "הספר נשלח אל המכשיר \"{0}\"", "ToastSeriesUpdateFailed": "עדכון הסדרה נכשל", "ToastSeriesUpdateSuccess": "הסדרה עודכנה בהצלחה", - "ToastServerSettingsUpdateFailed": "Failed to update server settings", - "ToastServerSettingsUpdateSuccess": "Server settings updated", + "ToastServerSettingsUpdateFailed": "כשל בעדכון הגדרות שרת", + "ToastServerSettingsUpdateSuccess": "הגדרות שרת עודכנו בהצלחה", "ToastSessionDeleteFailed": "מחיקת הפעולה נכשלה", "ToastSessionDeleteSuccess": "הפעולה נמחקה בהצלחה", "ToastSocketConnected": "קצה תקשורת חובר", From f422c9b8205670f5e2854e07d9613f6ff0b4ed82 Mon Sep 17 00:00:00 2001 From: tonttula Date: Sat, 13 Jul 2024 10:59:23 +0000 Subject: [PATCH 19/38] Translated using Weblate (Finnish) Currently translated at 21.4% (181 of 844 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/fi/ --- client/strings/fi.json | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/client/strings/fi.json b/client/strings/fi.json index 88b2cee3..b26255b9 100644 --- a/client/strings/fi.json +++ b/client/strings/fi.json @@ -152,11 +152,34 @@ "LabelContinueReading": "Jatka lukemista", "LabelContinueSeries": "Jatka sarjoja", "LabelDescription": "Kuvaus", + "LabelDownload": "Lataa", "LabelDuration": "Kesto", "LabelEbook": "E-kirja", "LabelEbooks": "E-kirjat", + "LabelEnable": "Ota käyttöön", "LabelFile": "Tiedosto", "LabelFileBirthtime": "Tiedoston syntymäaika", "LabelFileModified": "Muutettu tiedosto", - "LabelFilename": "Tiedostonimi" + "LabelFilename": "Tiedostonimi", + "LabelFolder": "Kansio", + "LabelLanguage": "Kieli", + "LabelMore": "Lisää", + "LabelNarrator": "Lukija", + "LabelNarrators": "Lukijat", + "LabelNewestAuthors": "Uusimmat kirjailijat", + "LabelNewestEpisodes": "Uusimmat jaksot", + "LabelPassword": "Salasana", + "LabelPath": "Polku", + "LabelRead": "Lue", + "LabelReadAgain": "Lue uudelleen", + "LabelSeason": "Kausi", + "LabelShowAll": "Näytä kaikki", + "LabelSize": "Koko", + "LabelSleepTimer": "Uniajastin", + "LabelTheme": "Teema", + "LabelThemeDark": "Tumma", + "LabelThemeLight": "Kirkas", + "LabelUser": "Käyttäjä", + "LabelUsername": "Käyttäjätunnus", + "MessageDownloadingEpisode": "Ladataan jaksoa" } From b99885c806b87bd6588d0f3cc2129b9579e99fe2 Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Sat, 13 Jul 2024 23:55:40 +0000 Subject: [PATCH 20/38] Translated using Weblate (Spanish) Currently translated at 100.0% (845 of 845 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/es/ --- client/strings/es.json | 1 + 1 file changed, 1 insertion(+) diff --git a/client/strings/es.json b/client/strings/es.json index b8550677..8b908a78 100644 --- a/client/strings/es.json +++ b/client/strings/es.json @@ -89,6 +89,7 @@ "ButtonShow": "Mostrar", "ButtonStartM4BEncode": "Iniciar Codificación M4B", "ButtonStartMetadataEmbed": "Iniciar la Inserción de Metadata", + "ButtonStats": "Estadísticas", "ButtonSubmit": "Enviar", "ButtonTest": "Prueba", "ButtonUpload": "Subir", From b6a1014c7225312f50baf763f7dc6cfbbf11bc6d Mon Sep 17 00:00:00 2001 From: Vito0912 Date: Sun, 14 Jul 2024 06:46:50 +0000 Subject: [PATCH 21/38] Translated using Weblate (German) Currently translated at 100.0% (845 of 845 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/de/ --- client/strings/de.json | 1 + 1 file changed, 1 insertion(+) diff --git a/client/strings/de.json b/client/strings/de.json index cbab04d4..908d23fb 100644 --- a/client/strings/de.json +++ b/client/strings/de.json @@ -89,6 +89,7 @@ "ButtonShow": "Anzeigen", "ButtonStartM4BEncode": "M4B-Kodierung starten", "ButtonStartMetadataEmbed": "Metadateneinbettung starten", + "ButtonStats": "Statistiken", "ButtonSubmit": "Ok", "ButtonTest": "Test", "ButtonUpload": "Hochladen", From 4d2bdb6eee12d4eaed3597c2c7e43253917456b7 Mon Sep 17 00:00:00 2001 From: Marcin Martela Date: Sun, 14 Jul 2024 12:53:48 +0000 Subject: [PATCH 22/38] Translated using Weblate (Polish) Currently translated at 90.2% (763 of 845 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/pl/ --- client/strings/pl.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/strings/pl.json b/client/strings/pl.json index 9a945e9e..0fe8535d 100644 --- a/client/strings/pl.json +++ b/client/strings/pl.json @@ -88,6 +88,7 @@ "ButtonShow": "Pokaż", "ButtonStartM4BEncode": "Eksportuj jako plik M4B", "ButtonStartMetadataEmbed": "Osadź metadane", + "ButtonStats": "Statystyki", "ButtonSubmit": "Zaloguj", "ButtonTest": "Test", "ButtonUpload": "Wgraj", @@ -154,6 +155,7 @@ "HeaderPasswordAuthentication": "Uwierzytelnianie hasłem", "HeaderPermissions": "Uprawnienia", "HeaderPlayerQueue": "Kolejka odtwarzania", + "HeaderPlayerSettings": "Ustawienia Odtwarzania", "HeaderPlaylist": "Playlista", "HeaderPlaylistItems": "Pozycje listy odtwarzania", "HeaderPodcastsToAdd": "Podcasty do dodania", @@ -447,6 +449,7 @@ "LabelRSSFeedPreventIndexing": "Zapobiegaj indeksowaniu", "LabelRSSFeedSlug": "RSS Feed Slug", "LabelRSSFeedURL": "URL kanały RSS", + "LabelReAddSeriesToContinueListening": "Ponownie Dodaj Serię do sekcji Kontunuuj Odtwarzanie", "LabelRead": "Czytaj", "LabelReadAgain": "Czytaj ponownie", "LabelReadEbookWithoutProgress": "Czytaj książkę bez zapamiętywania postępu", @@ -517,6 +520,7 @@ "LabelShareURL": "Link do udziału", "LabelShowAll": "Pokaż wszystko", "LabelShowSeconds": "Pokaż sekundy", + "LabelShowSubtitles": "Pokaż Napisy", "LabelSize": "Rozmiar", "LabelSleepTimer": "Wyłącznik czasowy", "LabelSlug": "Slug", @@ -593,6 +597,7 @@ "LabelVersion": "Wersja", "LabelViewBookmarks": "Wyświetlaj zakładki", "LabelViewChapters": "Wyświetlaj rozdziały", + "LabelViewPlayerSettings": "Zobacz ustawienia odtwarzacza", "LabelViewQueue": "Wyświetlaj kolejkę odtwarzania", "LabelVolume": "Głośność", "LabelWeekdaysToRun": "Dni tygodnia", From d17f9b0687461868bd568a586fe643cabfdd434b Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Sun, 14 Jul 2024 20:56:55 +0200 Subject: [PATCH 23/38] Update translation files Updated by "Cleanup translation files" add-on in Weblate. Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/ --- client/strings/de.json | 2 -- client/strings/es.json | 2 -- 2 files changed, 4 deletions(-) diff --git a/client/strings/de.json b/client/strings/de.json index 908d23fb..46753d6b 100644 --- a/client/strings/de.json +++ b/client/strings/de.json @@ -345,8 +345,6 @@ "LabelIntervalEveryHour": "Jede Stunde", "LabelInvert": "Umkehren", "LabelItem": "Medium", - "LabelJumpAmountMinutes": "{0} Minuten", - "LabelJumpAmountSeconds": "{0} Sekunden", "LabelJumpBackwardAmount": "Zurückspringen Zeit", "LabelJumpForwardAmount": "Vorwärtsspringn Zeit", "LabelLanguage": "Sprache", diff --git a/client/strings/es.json b/client/strings/es.json index 8b908a78..728051ce 100644 --- a/client/strings/es.json +++ b/client/strings/es.json @@ -345,8 +345,6 @@ "LabelIntervalEveryHour": "Cada Hora", "LabelInvert": "Invertir", "LabelItem": "Elemento", - "LabelJumpAmountMinutes": "{0} minutos", - "LabelJumpAmountSeconds": "{0} segundos", "LabelJumpBackwardAmount": "Cantidad de saltos hacia atrás", "LabelJumpForwardAmount": "Cantidad de saltos hacia adelante", "LabelLanguage": "Idioma", From bbd6c51eb6c138b215917ba2e5779f61a8c57dc9 Mon Sep 17 00:00:00 2001 From: Petteri Hjort Date: Sun, 14 Jul 2024 20:18:08 +0000 Subject: [PATCH 24/38] Translated using Weblate (Finnish) Currently translated at 21.4% (182 of 848 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/fi/ --- client/strings/fi.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/strings/fi.json b/client/strings/fi.json index b26255b9..ecda586c 100644 --- a/client/strings/fi.json +++ b/client/strings/fi.json @@ -136,7 +136,7 @@ "HeaderYourStats": "Tilastosi", "LabelAddToPlaylist": "Lisää soittolistaan", "LabelAdded": "Lisätty", - "LabelAddedAt": "Lisätty", + "LabelAddedAt": "Lisätty listalle", "LabelAll": "Kaikki", "LabelAuthor": "Tekijä", "LabelAuthorFirstLast": "Tekijä (Etunimi Sukunimi)", From 5c7a38c29270a99737eeb48f263317a3fe289e06 Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Mon, 15 Jul 2024 10:48:55 +0000 Subject: [PATCH 25/38] Translated using Weblate (Spanish) Currently translated at 100.0% (848 of 848 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/es/ --- client/strings/es.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/strings/es.json b/client/strings/es.json index 728051ce..d5af9736 100644 --- a/client/strings/es.json +++ b/client/strings/es.json @@ -292,6 +292,7 @@ "LabelEmbeddedCover": "Portada Integrada", "LabelEnable": "Habilitar", "LabelEnd": "Fin", + "LabelEndOfChapter": "Fin del capítulo", "LabelEpisode": "Episodio", "LabelEpisodeTitle": "Titulo de Episodio", "LabelEpisodeType": "Tipo de Episodio", @@ -563,6 +564,10 @@ "LabelThemeDark": "Oscuro", "LabelThemeLight": "Claro", "LabelTimeBase": "Tiempo Base", + "LabelTimeDurationXHours": "{0} horas", + "LabelTimeDurationXMinutes": "{0} minutos", + "LabelTimeDurationXSeconds": "{0} segundos", + "LabelTimeInMinutes": "Tiempo en minutos", "LabelTimeListened": "Tiempo Escuchando", "LabelTimeListenedToday": "Tiempo Escuchando Hoy", "LabelTimeRemaining": "{0} restante", From b1bc472205c894797185783646eeba6fe1be5614 Mon Sep 17 00:00:00 2001 From: advplyr Date: Mon, 15 Jul 2024 17:38:13 -0500 Subject: [PATCH 26/38] Update:Incrase icon font size for more context menu and player loading --- client/components/player/PlayerPlaybackControls.vue | 2 +- client/components/ui/ContextMenuDropdown.vue | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/components/player/PlayerPlaybackControls.vue b/client/components/player/PlayerPlaybackControls.vue index 76397e98..1a92480b 100644 --- a/client/components/player/PlayerPlaybackControls.vue +++ b/client/components/player/PlayerPlaybackControls.vue @@ -29,7 +29,7 @@
diff --git a/client/components/ui/ContextMenuDropdown.vue b/client/components/ui/ContextMenuDropdown.vue index 172c4999..e6e4e6e5 100644 --- a/client/components/ui/ContextMenuDropdown.vue +++ b/client/components/ui/ContextMenuDropdown.vue @@ -2,7 +2,7 @@
@@ -116,4 +116,4 @@ export default { }, mounted() {} } - \ No newline at end of file + From 2bc949fae3e96a8f77e354f447e7a92149ef1421 Mon Sep 17 00:00:00 2001 From: Andrew Leonard Date: Mon, 15 Jul 2024 23:58:05 -0400 Subject: [PATCH 27/38] feat: adds support for allowing backups of unlimited size --- client/pages/config/backups.vue | 7 +++---- server/managers/BackupManager.js | 20 +++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/client/pages/config/backups.vue b/client/pages/config/backups.vue index f7845119..a88cfc23 100644 --- a/client/pages/config/backups.vue +++ b/client/pages/config/backups.vue @@ -64,7 +64,7 @@ -

{{ $strings.LabelBackupsMaxBackupSize }} info

+

{{ $strings.LabelBackupsMaxBackupSize }} (0 for unlimited) info

@@ -170,7 +170,7 @@ export default { }) }, updateBackupsSettings() { - if (isNaN(this.maxBackupSize) || this.maxBackupSize <= 0) { + if (isNaN(this.maxBackupSize) || this.maxBackupSize < 0) { this.$toast.error('Invalid maximum backup size') return } @@ -200,10 +200,9 @@ export default { }, initServerSettings() { this.newServerSettings = this.serverSettings ? { ...this.serverSettings } : {} - this.backupsToKeep = this.newServerSettings.backupsToKeep || 2 this.enableBackups = !!this.newServerSettings.backupSchedule - this.maxBackupSize = this.newServerSettings.maxBackupSize || 1 + this.maxBackupSize = this.newServerSettings.maxBackupSize || 0 this.cronExpression = this.newServerSettings.backupSchedule || '30 1 * * *' } }, diff --git a/server/managers/BackupManager.js b/server/managers/BackupManager.js index 88772c58..13493952 100644 --- a/server/managers/BackupManager.js +++ b/server/managers/BackupManager.js @@ -42,7 +42,7 @@ class BackupManager { } get maxBackupSize() { - return global.ServerSettings.maxBackupSize || 1 + return global.ServerSettings.maxBackupSize || Infinity } async init() { @@ -419,14 +419,16 @@ class BackupManager { reject(err) }) archive.on('progress', ({ fs: fsobj }) => { - const maxBackupSizeInBytes = this.maxBackupSize * 1000 * 1000 * 1000 - if (fsobj.processedBytes > maxBackupSizeInBytes) { - Logger.error(`[BackupManager] Archiver is too large - aborting to prevent endless loop, Bytes Processed: ${fsobj.processedBytes}`) - archive.abort() - setTimeout(() => { - this.removeBackup(backup) - output.destroy('Backup too large') // Promise is reject in write stream error evt - }, 500) + if (this.maxBackupSize !== Infinity) { + const maxBackupSizeInBytes = this.maxBackupSize * 1000 * 1000 * 1000 + if (fsobj.processedBytes > maxBackupSizeInBytes) { + Logger.error(`[BackupManager] Archiver is too large - aborting to prevent endless loop, Bytes Processed: ${fsobj.processedBytes}`) + archive.abort() + setTimeout(() => { + this.removeBackup(backup) + output.destroy('Backup too large') // Promise is reject in write stream error evt + }, 500) + } } }) From e230b6640f0b24e1369a8410feb42531ff2d12b4 Mon Sep 17 00:00:00 2001 From: Andrew Leonard Date: Tue, 16 Jul 2024 01:11:20 -0400 Subject: [PATCH 28/38] feat: adds unlimited text to text label --- client/pages/config/backups.vue | 2 +- client/strings/en-us.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/pages/config/backups.vue b/client/pages/config/backups.vue index a88cfc23..d72c2bc8 100644 --- a/client/pages/config/backups.vue +++ b/client/pages/config/backups.vue @@ -64,7 +64,7 @@ -

{{ $strings.LabelBackupsMaxBackupSize }} (0 for unlimited) info

+

{{ $strings.LabelBackupsMaxBackupSize }} info

diff --git a/client/strings/en-us.json b/client/strings/en-us.json index a0933d4d..9fdff867 100644 --- a/client/strings/en-us.json +++ b/client/strings/en-us.json @@ -229,7 +229,7 @@ "LabelBackupLocation": "Backup Location", "LabelBackupsEnableAutomaticBackups": "Enable automatic backups", "LabelBackupsEnableAutomaticBackupsHelp": "Backups saved in /metadata/backups", - "LabelBackupsMaxBackupSize": "Maximum backup size (in GB)", + "LabelBackupsMaxBackupSize": "Maximum backup size (in GB) (0 for unlimited)", "LabelBackupsMaxBackupSizeHelp": "As a safeguard against misconfiguration, backups will fail if they exceed the configured size.", "LabelBackupsNumberToKeep": "Number of backups to keep", "LabelBackupsNumberToKeepHelp": "Only 1 backup will be removed at a time so if you already have more backups than this you should manually remove them.", From 4b482488defe34ced7359de5db40c61d2fa85137 Mon Sep 17 00:00:00 2001 From: Andrew Leonard Date: Tue, 16 Jul 2024 01:30:00 -0400 Subject: [PATCH 29/38] feat: remember setting of 0 on server side --- server/objects/settings/ServerSettings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/objects/settings/ServerSettings.js b/server/objects/settings/ServerSettings.js index 6ade11a9..6d070dcc 100644 --- a/server/objects/settings/ServerSettings.js +++ b/server/objects/settings/ServerSettings.js @@ -102,7 +102,7 @@ class ServerSettings { this.backupPath = settings.backupPath || Path.join(global.MetadataPath, 'backups') this.backupSchedule = settings.backupSchedule || false this.backupsToKeep = settings.backupsToKeep || 2 - this.maxBackupSize = settings.maxBackupSize || 1 + this.maxBackupSize = settings.maxBackupSize === 0 ? 0 : settings.maxBackupSize || 1 this.loggerDailyLogsToKeep = settings.loggerDailyLogsToKeep || 7 this.loggerScannerLogsToKeep = settings.loggerScannerLogsToKeep || 2 From ff788e3591dcb51e9c3a2ee48af5720ade267486 Mon Sep 17 00:00:00 2001 From: Andrew Leonard Date: Tue, 16 Jul 2024 01:31:12 -0400 Subject: [PATCH 30/38] feat: adds better conditional for max backup size --- client/pages/config/backups.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/pages/config/backups.vue b/client/pages/config/backups.vue index d72c2bc8..44a92f2e 100644 --- a/client/pages/config/backups.vue +++ b/client/pages/config/backups.vue @@ -202,7 +202,7 @@ export default { this.newServerSettings = this.serverSettings ? { ...this.serverSettings } : {} this.backupsToKeep = this.newServerSettings.backupsToKeep || 2 this.enableBackups = !!this.newServerSettings.backupSchedule - this.maxBackupSize = this.newServerSettings.maxBackupSize || 0 + this.maxBackupSize = this.newServerSettings.maxBackupSize === 0 ? 0 : this.newServerSettings.maxBackupSize || 1 this.cronExpression = this.newServerSettings.backupSchedule || '30 1 * * *' } }, From 26db20f63d20c6467689056273ce1e0705a156b9 Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 16 Jul 2024 08:37:48 +0000 Subject: [PATCH 31/38] Translated using Weblate (German) Currently translated at 100.0% (848 of 848 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/de/ --- client/strings/de.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/strings/de.json b/client/strings/de.json index 46753d6b..ac3650cb 100644 --- a/client/strings/de.json +++ b/client/strings/de.json @@ -292,6 +292,7 @@ "LabelEmbeddedCover": "Eingebettetes Cover", "LabelEnable": "Aktivieren", "LabelEnd": "Ende", + "LabelEndOfChapter": "Ende des Kapitels", "LabelEpisode": "Episode", "LabelEpisodeTitle": "Episodentitel", "LabelEpisodeType": "Episodentyp", @@ -563,6 +564,10 @@ "LabelThemeDark": "Dunkel", "LabelThemeLight": "Hell", "LabelTimeBase": "Basiszeit", + "LabelTimeDurationXHours": "{0} Stunden", + "LabelTimeDurationXMinutes": "{0} Minuten", + "LabelTimeDurationXSeconds": "{0} Sekunden", + "LabelTimeInMinutes": "Zeit in Minuten", "LabelTimeListened": "Gehörte Zeit", "LabelTimeListenedToday": "Heute gehörte Zeit", "LabelTimeRemaining": "{0} verbleibend", From 37ad1cced29b8001d108e39936f6fdf1a882c873 Mon Sep 17 00:00:00 2001 From: advplyr Date: Tue, 16 Jul 2024 17:05:52 -0500 Subject: [PATCH 32/38] Fix:Large OPML import timeouts #3118 - Added OPML Api endpoints for /parse and /create, removed old - Show task for OPML import and create failed tasks for failed feeds --- .../modals/podcast/OpmlFeedsModal.vue | 90 ++++--------- .../pages/library/_library/podcast/search.vue | 17 ++- client/strings/en-us.json | 1 + server/controllers/PodcastController.js | 57 +++++++- server/managers/PodcastManager.js | 126 +++++++++++++++++- server/managers/TaskManager.js | 42 ++++-- server/models/Library.js | 2 +- server/routers/ApiRouter.js | 4 +- server/utils/parsers/parseOPML.js | 12 +- 9 files changed, 258 insertions(+), 93 deletions(-) diff --git a/client/components/modals/podcast/OpmlFeedsModal.vue b/client/components/modals/podcast/OpmlFeedsModal.vue index 7d7327d2..41a75225 100644 --- a/client/components/modals/podcast/OpmlFeedsModal.vue +++ b/client/components/modals/podcast/OpmlFeedsModal.vue @@ -16,11 +16,18 @@
-

{{ $strings.HeaderPodcastsToAdd }}

+

{{ $strings.HeaderPodcastsToAdd }}

+

{{ $strings.MessageOpmlPreviewNote }}

-