From 286185329d50695761653b87d2d8e54d2ad5431b Mon Sep 17 00:00:00 2001 From: mikiher Date: Wed, 22 Jan 2025 08:53:23 +0200 Subject: [PATCH 01/66] Support rich text book descriptions --- client/assets/defaultStyles.css | 15 ++- client/assets/trix.css | 11 +- client/components/cards/BookMatchCard.vue | 2 +- client/components/modals/item/tabs/Match.vue | 4 +- .../components/modals/podcast/ViewEpisode.vue | 2 +- client/components/ui/RichTextEditor.vue | 51 ++------- client/components/ui/VueTrix.vue | 103 +++++++++++++----- client/components/widgets/BookDetailsEdit.vue | 2 +- client/pages/item/_id/index.vue | 5 +- server/finders/BookFinder.js | 7 ++ server/models/Book.js | 4 + server/providers/Audible.js | 3 +- server/providers/iTunes.js | 2 +- server/utils/htmlSanitizer.js | 8 +- 14 files changed, 136 insertions(+), 83 deletions(-) diff --git a/client/assets/defaultStyles.css b/client/assets/defaultStyles.css index 027ccdf23..e0ca79e29 100644 --- a/client/assets/defaultStyles.css +++ b/client/assets/defaultStyles.css @@ -52,4 +52,17 @@ text-indent: 0px !important; text-align: start !important; text-align-last: start !important; -} \ No newline at end of file +} + +.default-style.less-spacing p { + margin-block-start: 0; +} + +.default-style.less-spacing ul { + margin-block-start: 0; +} + +.default-style.less-spacing ol { + margin-block-start: 0; +} + diff --git a/client/assets/trix.css b/client/assets/trix.css index 8f88c61f1..7432b25f4 100644 --- a/client/assets/trix.css +++ b/client/assets/trix.css @@ -446,7 +446,7 @@ trix-editor .attachment__metadata .attachment__size { } .trix-content { - line-height: 1.5; + line-height: inherit; } .trix-content * { @@ -455,6 +455,13 @@ trix-editor .attachment__metadata .attachment__size { padding: 0; } +.trix-content p { + box-sizing: border-box; + margin-top: 0; + margin-bottom: 0.5em; + padding: 0; +} + .trix-content h1 { font-size: 1.2em; line-height: 1.2; @@ -560,4 +567,4 @@ trix-editor .attachment__metadata .attachment__size { .trix-content .attachment-gallery.attachment-gallery--4 .attachment { flex-basis: 50%; max-width: 50%; -} \ No newline at end of file +} diff --git a/client/components/cards/BookMatchCard.vue b/client/components/cards/BookMatchCard.vue index d5355e915..4fa24c1f3 100644 --- a/client/components/cards/BookMatchCard.vue +++ b/client/components/cards/BookMatchCard.vue @@ -24,7 +24,7 @@
-

{{ book.description }}

+

{{ book.descriptionPlain }}

diff --git a/client/components/modals/item/tabs/Match.vue b/client/components/modals/item/tabs/Match.vue index c7247d513..623ef2a18 100644 --- a/client/components/modals/item/tabs/Match.vue +++ b/client/components/modals/item/tabs/Match.vue @@ -94,9 +94,9 @@ diff --git a/client/components/modals/podcast/ViewEpisode.vue b/client/components/modals/podcast/ViewEpisode.vue index af67242ae..6c1a678cb 100644 --- a/client/components/modals/podcast/ViewEpisode.vue +++ b/client/components/modals/podcast/ViewEpisode.vue @@ -16,7 +16,7 @@

{{ title }}

-
+

{{ $strings.MessageNoDescription }}

diff --git a/client/components/ui/RichTextEditor.vue b/client/components/ui/RichTextEditor.vue index c5ae6d832..51bdc5ae1 100644 --- a/client/components/ui/RichTextEditor.vue +++ b/client/components/ui/RichTextEditor.vue @@ -1,9 +1,9 @@ @@ -12,7 +12,10 @@ export default { props: { value: String, label: String, - disabled: Boolean + disabled: { + type: Boolean, + default: false + } }, data() { return {} @@ -25,49 +28,19 @@ export default { set(val) { this.$emit('input', val) } - }, - config() { - return { - toolbar: { - getDefaultHTML: () => `
- - - - - - - - - - - - - - - - -
-
- -
` - } - } } }, methods: { trixFileAccept(e) { e.preventDefault() + }, + blur() { + if (this.$refs.input && this.$refs.input.blur) { + this.$refs.input.blur() + } } }, mounted() {}, beforeDestroy() {} } - \ No newline at end of file + diff --git a/client/components/ui/VueTrix.vue b/client/components/ui/VueTrix.vue index 5d351c724..8bbb42dfa 100644 --- a/client/components/ui/VueTrix.vue +++ b/client/components/ui/VueTrix.vue @@ -1,6 +1,37 @@ @@ -14,6 +45,30 @@ import Trix from 'trix' import '@/assets/trix.css' +function enableBreakParagraphOnReturn() { + // Trix works with divs by default, we want paragraphs instead + Trix.config.blockAttributes.default.tagName = 'p' + // Enable break paragraph on Enter (Shift + Enter will still create a line break) + Trix.config.blockAttributes.default.breakOnReturn = true + + // Hack to fix buggy paragraph breaks + // Copied from https://github.com/basecamp/trix/issues/680#issuecomment-735742942 + Trix.Block.prototype.breaksOnReturn = function () { + const attr = this.getLastAttribute() + const config = Trix.getBlockConfig(attr ? attr : 'default') + return config ? config.breakOnReturn : false + } + Trix.LineBreakInsertion.prototype.shouldInsertBlockBreak = function () { + if (this.block.hasAttributes() && this.block.isListItem() && !this.block.isEmpty()) { + return this.startLocation.offset > 0 + } else { + return !this.shouldBreakFormattedBlock() ? this.breaksOnReturn : false + } + } +} + +enableBreakParagraphOnReturn() + export default { name: 'vue-trix', model: { @@ -134,6 +189,9 @@ export default { * Compute a random id of hidden input * when it haven't been specified. */ + toolbarId() { + return `trix-toolbar-${this.generateId}` + }, generateId() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { var r = (Math.random() * 16) | 0 @@ -223,13 +281,17 @@ export default { decorateDisabledEditor(editorState) { /** Disable toolbar and editor by pointer events styling */ if (editorState) { - this.$refs.trix.toolbarElement.style['pointer-events'] = 'none' + this.$refs.trix.disabled = true this.$refs.trix.contentEditable = false - this.$refs.trix.style['background'] = '#e9ecef' + this.$refs.trix.style['pointer-events'] = 'none' + this.$refs.trix.style['background-color'] = '#444' + this.$refs.trix.style['color'] = '#bbb' } else { - this.$refs.trix.toolbarElement.style['pointer-events'] = 'unset' + this.$refs.trix.disabled = false + this.$refs.trix.contentEditable = true this.$refs.trix.style['pointer-events'] = 'unset' - this.$refs.trix.style['background'] = 'transparent' + this.$refs.trix.style['background-color'] = '' + this.$refs.trix.style['color'] = '' } }, overrideConfig(config) { @@ -250,32 +312,15 @@ export default { } return target }, - enableBreakParagraphOnReturn() { - // Trix works with divs by default, we want paragraphs instead - Trix.config.blockAttributes.default.tagName = 'p' - // Enable break paragraph on Enter (Shift + Enter will still create a line break) - Trix.config.blockAttributes.default.breakOnReturn = true - - // Hack to fix buggy paragraph breaks - // Copied from https://github.com/basecamp/trix/issues/680#issuecomment-735742942 - Trix.Block.prototype.breaksOnReturn = function () { - const attr = this.getLastAttribute() - const config = Trix.getBlockConfig(attr ? attr : 'default') - return config ? config.breakOnReturn : false - } - Trix.LineBreakInsertion.prototype.shouldInsertBlockBreak = function () { - if (this.block.hasAttributes() && this.block.isListItem() && !this.block.isEmpty()) { - return this.startLocation.offset > 0 - } else { - return !this.shouldBreakFormattedBlock() ? this.breaksOnReturn : false - } + blur() { + if (this.$refs.trix && this.$refs.trix.blur) { + this.$refs.trix.blur() } } }, mounted() { /** Override editor configuration */ this.overrideConfig(this.config) - this.enableBreakParagraphOnReturn() /** Check if editor read-only mode is required */ this.decorateDisabledEditor(this.disabledEditor) this.$nextTick(() => { @@ -305,4 +350,12 @@ export default { .trix_container .trix-content { background-color: white; } +trix-editor { + max-height: calc(4 * 1lh); + overflow-y: auto; +} + +trix-editor * { + pointer-events: inherit; +} diff --git a/client/components/widgets/BookDetailsEdit.vue b/client/components/widgets/BookDetailsEdit.vue index 5fbcaa20b..fa26bcf52 100644 --- a/client/components/widgets/BookDetailsEdit.vue +++ b/client/components/widgets/BookDetailsEdit.vue @@ -26,7 +26,7 @@
- +
diff --git a/client/pages/item/_id/index.vue b/client/pages/item/_id/index.vue index a0cadc1d4..714e326ca 100644 --- a/client/pages/item/_id/index.vue +++ b/client/pages/item/_id/index.vue @@ -123,7 +123,7 @@
-

{{ description }}

+

@@ -804,8 +804,7 @@ export default { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; - max-height: 6.25rem; - transition: all 0.3s ease-in-out; + max-height: calc(6 * 1lh); } #item-description.show-full { -webkit-line-clamp: unset; diff --git a/server/finders/BookFinder.js b/server/finders/BookFinder.js index f43230946..8fde7bc49 100644 --- a/server/finders/BookFinder.js +++ b/server/finders/BookFinder.js @@ -8,6 +8,7 @@ const AudiobookCovers = require('../providers/AudiobookCovers') const CustomProviderAdapter = require('../providers/CustomProviderAdapter') const Logger = require('../Logger') const { levenshteinDistance, escapeRegExp } = require('../utils/index') +const htmlSanitizer = require('../utils/htmlSanitizer') class BookFinder { #providerResponseTimeout = 30000 @@ -463,6 +464,12 @@ class BookFinder { } else { books = await this.getGoogleBooksResults(title, author) } + books.forEach((book) => { + if (book.description) { + book.description = htmlSanitizer.sanitize(book.description) + book.descriptionPlain = htmlSanitizer.stripAllTags(book.description) + } + }) return books } diff --git a/server/models/Book.js b/server/models/Book.js index 5a4eee54a..4f7d12695 100644 --- a/server/models/Book.js +++ b/server/models/Book.js @@ -2,6 +2,7 @@ const { DataTypes, Model } = require('sequelize') const Logger = require('../Logger') const { getTitlePrefixAtEnd, getTitleIgnorePrefix } = require('../utils') const parseNameString = require('../utils/parsers/parseNameString') +const htmlSanitizer = require('../utils/htmlSanitizer') /** * @typedef EBookFileObject @@ -343,6 +344,7 @@ class Book extends Model { publishedDate: this.publishedDate, publisher: this.publisher, description: this.description, + descriptionPlain: this.description ? htmlSanitizer.stripAllTags(this.description) : null, isbn: this.isbn, asin: this.asin, language: this.language, @@ -542,6 +544,7 @@ class Book extends Model { publishedDate: this.publishedDate, publisher: this.publisher, description: this.description, + descriptionPlain: this.description ? htmlSanitizer.stripAllTags(this.description) : null, isbn: this.isbn, asin: this.asin, language: this.language, @@ -564,6 +567,7 @@ class Book extends Model { publishedDate: this.publishedDate, publisher: this.publisher, description: this.description, + descriptionPlain: this.description ? htmlSanitizer.stripAllTags(this.description) : null, isbn: this.isbn, asin: this.asin, language: this.language, diff --git a/server/providers/Audible.js b/server/providers/Audible.js index 505b8f0ee..e68160823 100644 --- a/server/providers/Audible.js +++ b/server/providers/Audible.js @@ -1,5 +1,4 @@ const axios = require('axios').default -const htmlSanitizer = require('../utils/htmlSanitizer') const Logger = require('../Logger') const { isValidASIN } = require('../utils/index') @@ -68,7 +67,7 @@ class Audible { narrator: narrators ? narrators.map(({ name }) => name).join(', ') : null, publisher: publisherName, publishedYear: releaseDate ? releaseDate.split('-')[0] : null, - description: summary ? htmlSanitizer.stripAllTags(summary) : null, + description: summary || null, cover: image, asin, genres: genresFiltered.length ? genresFiltered : null, diff --git a/server/providers/iTunes.js b/server/providers/iTunes.js index 1ec051d1a..57a47d0d1 100644 --- a/server/providers/iTunes.js +++ b/server/providers/iTunes.js @@ -112,7 +112,7 @@ class iTunes { artistId: data.artistId, title: data.collectionName, author, - description: htmlSanitizer.stripAllTags(data.description || ''), + description: data.description || null, publishedYear: data.releaseDate ? data.releaseDate.split('-')[0] : null, genres: data.primaryGenreName ? [data.primaryGenreName] : null, cover: this.getCoverArtwork(data) diff --git a/server/utils/htmlSanitizer.js b/server/utils/htmlSanitizer.js index 68d92c859..cab92392b 100644 --- a/server/utils/htmlSanitizer.js +++ b/server/utils/htmlSanitizer.js @@ -1,11 +1,9 @@ const sanitizeHtml = require('../libs/sanitizeHtml') -const { entities } = require("./htmlEntities"); +const { entities } = require('./htmlEntities') function sanitize(html) { const sanitizerOptions = { - allowedTags: [ - 'p', 'ol', 'ul', 'li', 'a', 'strong', 'em', 'del', 'br' - ], + allowedTags: ['p', 'ol', 'ul', 'li', 'a', 'strong', 'em', 'del', 'br', 'b', 'i'], disallowedTagsMode: 'discard', allowedAttributes: { a: ['href', 'name', 'target'] @@ -34,6 +32,6 @@ function decodeHTMLEntities(strToDecode) { if (entity in entities) { return entities[entity] } - return entity; + return entity }) } From 9fbf57bbefeb0ed5074a392e0b86bf680ec5055c Mon Sep 17 00:00:00 2001 From: adjokic <15988225+adjokic@users.noreply.github.com> Date: Wed, 22 Jan 2025 22:10:38 -0600 Subject: [PATCH 02/66] Update README on using websockets with Apache as a reverse proxy --- readme.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/readme.md b/readme.md index 19ede3ce2..34f770c5a 100644 --- a/readme.md +++ b/readme.md @@ -165,6 +165,15 @@ For this to work you must enable at least the following mods using `a2enmod`: ``` +If using Apache >= 2.4.47 you can use the following, without having to use any of the `RewriteEngine`, `RewriteCond`, or `RewriteRule` directives. For example: +```xml + + ProxyPreserveHost on + ProxyPass http://localhost:/audiobookshelf upgrade=websocket + ProxyPassReverse http://localhost:/audiobookshelf + +``` + Some SSL certificates like those signed by Let's Encrypt require ACME validation. To allow Let's Encrypt to write and confirm the ACME challenge, edit your VirtualHost definition to prevent proxying traffic that queries `/.well-known` and instead serve that directly: ```bash From 647a722b06cee1429adedefc0772eb9b62a9cd21 Mon Sep 17 00:00:00 2001 From: advplyr Date: Fri, 24 Jan 2025 17:21:11 -0600 Subject: [PATCH 03/66] Update readme for subdirectory --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 34f770c5a..3eb4cef7a 100644 --- a/readme.md +++ b/readme.md @@ -47,7 +47,6 @@ Check out the web client demo: https://audiobooks.dev/ (thanks for hosting [@Vit Username/password: `demo`/`demo` (user account) - ### Android App (beta) Try it out on the [Google Play Store](https://play.google.com/store/apps/details?id=com.audiobookshelf.app) @@ -86,7 +85,7 @@ See [install docs](https://www.audiobookshelf.org/docs) #### Important! Audiobookshelf requires a websocket connection. -#### Note: Subfolder paths (e.g. /audiobooks) are not supported yet. See [issue](https://github.com/advplyr/audiobookshelf/issues/385) +#### Note: Using a subfolder is supported with no additional changes but the path must be `/audiobookshelf` (this is not changeable). See [discussion](https://github.com/advplyr/audiobookshelf/discussions/3535) ### NGINX Proxy Manager @@ -166,6 +165,7 @@ For this to work you must enable at least the following mods using `a2enmod`: ``` If using Apache >= 2.4.47 you can use the following, without having to use any of the `RewriteEngine`, `RewriteCond`, or `RewriteRule` directives. For example: + ```xml ProxyPreserveHost on From f77dd6b1adeb6154a18aa46530be70a323902f3a Mon Sep 17 00:00:00 2001 From: Andreas Morell-Reng Date: Tue, 21 Jan 2025 10:08:34 +0000 Subject: [PATCH 04/66] Translated using Weblate (Danish) Currently translated at 74.1% (802 of 1082 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/da/ --- client/strings/da.json | 51 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/client/strings/da.json b/client/strings/da.json index f678fc623..2eb96cb75 100644 --- a/client/strings/da.json +++ b/client/strings/da.json @@ -258,6 +258,7 @@ "LabelBitrate": "Bitrate", "LabelBonus": "Bonus", "LabelBooks": "Bøger", + "LabelButtonText": "Knap tekst", "LabelByAuthor": "af {0}", "LabelChangePassword": "Ændre Adgangskode", "LabelChannels": "Kanaler", @@ -270,6 +271,7 @@ "LabelClosePlayer": "Luk afspiller", "LabelCodec": "Kodeks", "LabelCollapseSeries": "Fold Serier Sammen", + "LabelCollapseSubSeries": "Fold underserie sammen", "LabelCollection": "Samling", "LabelCollections": "Samlinger", "LabelComplete": "Fuldfør", @@ -286,17 +288,21 @@ "LabelCustomCronExpression": "Brugerdefineret Cron Udtryk:", "LabelDatetime": "Dato og Tid", "LabelDays": "Dage", + "LabelDeleteFromFileSystemCheckbox": "Slet fra filsystem (afmarker kun for at fjerne fra databasen)", "LabelDescription": "Beskrivelse", "LabelDeselectAll": "Fravælg Alle", "LabelDevice": "Enheds", "LabelDeviceInfo": "Enhedsinformation", + "LabelDeviceIsAvailableTo": "Enhed er tilgængelig for...", "LabelDirectory": "Mappe", "LabelDiscFromFilename": "Disk fra Filnavn", "LabelDiscFromMetadata": "Disk fra Metadata", "LabelDiscover": "Opdag", "LabelDownload": "Download", "LabelDownloadNEpisodes": "Download {0} episoder", + "LabelDownloadable": "Downloadbar", "LabelDuration": "Varighed", + "LabelDurationComparisonExactMatch": "(præcis match)", "LabelDurationComparisonLonger": "({0} længere)", "LabelDurationComparisonShorter": "({0} kortere)", "LabelDurationFound": "Fundet varighed:", @@ -313,37 +319,66 @@ "LabelEnable": "Aktivér", "LabelEncodingBackupLocation": "En sikkerhedskopi af dine originale lydfiler vil blive gemt under:", "LabelEncodingChaptersNotEmbedded": "Kapitler er ikke indlejret i multi spors lydbøger.", + "LabelEncodingClearItemCache": "Sørg for periodisk at rense indholdscachen.", + "LabelEncodingFinishedM4B": "Færdiggjort M4B som vil blive placeret i din lydbogsmappe ved:", + "LabelEncodingInfoEmbedded": "Metadata vil blive indlejret i lydfiler i lydbogsmappen.", + "LabelEncodingStartedNavigation": "Når opgaven er startet kan du navigere væk fra denne side.", + "LabelEncodingTimeWarning": "Indkodning kan tage op til 30 minutter.", + "LabelEncodingWarningAdvancedSettings": "Advarsel: Opdater ikke disse indstillinger med mindre du kender til ffmpeg indkodningsindstillinger.", "LabelEnd": "Slut", "LabelEndOfChapter": "Slutningen af kapitel", "LabelEpisode": "Episode", + "LabelEpisodeNotLinkedToRssFeed": "Afsnit er ikke koblet til RSS feed", + "LabelEpisodeNumber": "Afsnit #{0}", "LabelEpisodeTitle": "Episodetitel", "LabelEpisodeType": "Episodetype", + "LabelEpisodeUrlFromRssFeed": "Afsnit URL fra RSS feed", + "LabelEpisodes": "Afsnit", + "LabelEpisodic": "Afsnit", "LabelExample": "Eksempel", + "LabelExpandSeries": "Udfold serie", + "LabelExpandSubSeries": "Udfold underserie", "LabelExplicit": "Eksplisit", + "LabelExplicitChecked": "Eksplicit (markeret)", + "LabelExplicitUnchecked": "Ikke eksplicit (ikke markeret)", + "LabelExportOPML": "Eksport OPML", "LabelFeedURL": "Feed URL", + "LabelFetchingMetadata": "Henter metadata", "LabelFile": "Fil", "LabelFileBirthtime": "Oprettelsestidspunkt for fil", + "LabelFileBornDate": "Født {0}", "LabelFileModified": "Fil ændret", + "LabelFileModifiedDate": "Opdateret {0}", "LabelFilename": "Filnavn", "LabelFilterByUser": "Filtrér efter bruger", "LabelFindEpisodes": "Find episoder", "LabelFinished": "Færdig", "LabelFolder": "Mappe", "LabelFolders": "Mapper", + "LabelFontBold": "Fed", "LabelFontBoldness": "Skrift tykkelse", "LabelFontFamily": "Fontfamilie", + "LabelFontItalic": "Kursiv", "LabelFontScale": "Skriftstørrelse", + "LabelFontStrikethrough": "Gennemstreget", + "LabelFormat": "Format", + "LabelFull": "Fuld", "LabelGenre": "Genre", "LabelGenres": "Genrer", "LabelHardDeleteFile": "Permanent slet fil", "LabelHasEbook": "Har e-bog", "LabelHasSupplementaryEbook": "Har supplerende e-bog", + "LabelHideSubtitles": "Skjul undertitler", + "LabelHighestPriority": "Højeste prioritet", "LabelHost": "Vært", "LabelHour": "Time", + "LabelHours": "Timer", "LabelIcon": "Ikon", + "LabelImageURLFromTheWeb": "Billede URL fra nettet", "LabelInProgress": "I gang", "LabelIncludeInTracklist": "Inkluder i afspilningsliste", "LabelIncomplete": "Ufuldstændig", + "LabelInterval": "Interval", "LabelIntervalCustomDailyWeekly": "Tilpasset dagligt/ugentligt", "LabelIntervalEvery12Hours": "Hver 12. time", "LabelIntervalEvery15Minutes": "Hver 15. minut", @@ -354,8 +389,11 @@ "LabelIntervalEveryHour": "Hver time", "LabelInvert": "Inverter", "LabelItem": "Element", + "LabelJumpBackwardAmount": "Spring bagud mængde", + "LabelJumpForwardAmount": "Spring fremad mængde", "LabelLanguage": "Sprog", "LabelLanguageDefaultServer": "Standard server sprog", + "LabelLanguages": "Sprog", "LabelLastBookAdded": "Senest tilføjede bog", "LabelLastBookUpdated": "Senest opdaterede bog", "LabelLastSeen": "Sidst set", @@ -367,6 +405,7 @@ "LabelLess": "Mindre", "LabelLibrariesAccessibleToUser": "Biblioteker tilgængelige for bruger", "LabelLibrary": "Bibliotek", + "LabelLibraryFilterSublistEmpty": "Nej {0}", "LabelLibraryItem": "Bibliotekselement", "LabelLibraryName": "Biblioteksnavn", "LabelLimit": "Grænse", @@ -376,13 +415,25 @@ "LabelLogLevelInfo": "Information", "LabelLogLevelWarn": "Advarsel", "LabelLookForNewEpisodesAfterDate": "Søg efter nye episoder efter denne dato", + "LabelLowestPriority": "Laveste prioritet", + "LabelMatchExistingUsersBy": "Match eksisterende brugere ved", + "LabelMatchExistingUsersByDescription": "Anvendt for at forbinde brugere. Når forbundet, brugere vil blive matchet ved unikt id fra din SSO udbyder", + "LabelMaxEpisodesToDownload": "Max # afsnit for at downloade. Anvend 0 for ubegrænset.", + "LabelMaxEpisodesToDownloadPerCheck": "Max # afsnit til at downloade per check", + "LabelMaxEpisodesToKeep": "Max # afsnit at beholde", + "LabelMaxEpisodesToKeepHelp": "Værdi af 0 sætter intet maks begrænsning. After et nyt afsnit er automatisk downloaded vil det ældste afsnit blive slettet hvis du har mere end X afsnit. Dette vil kun slette 1 afsnit for hvert nye download.", "LabelMediaPlayer": "Medieafspiller", "LabelMediaType": "Medietype", "LabelMetaTag": "Meta-tag", "LabelMetaTags": "Meta-tags", + "LabelMetadataOrderOfPrecedenceDescription": "Højeste prioritet metadata kilder vil overskrive de lavest prioriterede metadata kilder", "LabelMetadataProvider": "Metadataudbyder", "LabelMinute": "Minut", + "LabelMinutes": "Minutter", "LabelMissing": "Mangler", + "LabelMissingEbook": "Har ingen ebog", + "LabelMissingSupplementaryEbook": "Har ingen tillægsbog", + "LabelMobileRedirectURIs": "Godkendte mobil redirect URI'er", "LabelMore": "Mere", "LabelMoreInfo": "Mere info", "LabelName": "Navn", From fc116ce1ed43f7e9cb8178a32e2d9c261895ee2b Mon Sep 17 00:00:00 2001 From: Jan-Eric Myhrgren Date: Tue, 21 Jan 2025 08:20:41 +0000 Subject: [PATCH 05/66] Translated using Weblate (Swedish) Currently translated at 83.4% (903 of 1082 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/sv/ --- client/strings/sv.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/strings/sv.json b/client/strings/sv.json index 908b2b3a7..970e7f281 100644 --- a/client/strings/sv.json +++ b/client/strings/sv.json @@ -556,7 +556,7 @@ "LabelTags": "Taggar", "LabelTagsAccessibleToUser": "Taggar användaren har tillgång till", "LabelTagsNotAccessibleToUser": "Taggar inte tillgängliga för användaren", - "LabelTasks": "Körande uppgifter", + "LabelTasks": "Pågående aktivitet", "LabelTextEditorBulletedList": "Punktlista", "LabelTextEditorNumberedList": "Numrerad lista", "LabelTheme": "Utseende", From a4a7cddcff226ac36609a4c544741099a3ef1eb2 Mon Sep 17 00:00:00 2001 From: Andreas Morell-Reng Date: Tue, 21 Jan 2025 10:20:10 +0000 Subject: [PATCH 06/66] Translated using Weblate (Danish) Currently translated at 74.1% (802 of 1082 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/da/ --- client/strings/da.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/strings/da.json b/client/strings/da.json index 2eb96cb75..b7be25540 100644 --- a/client/strings/da.json +++ b/client/strings/da.json @@ -51,7 +51,7 @@ "ButtonNext": "Næste", "ButtonNextChapter": "Næste Kapitel", "ButtonNextItemInQueue": "Næste Element i Køen", - "ButtonOk": "OK", + "ButtonOk": "Ok", "ButtonOpenFeed": "Åbn feed", "ButtonOpenManager": "Åbn manager", "ButtonPause": "Pause", From 254558f7a66d5b9b7b09b2012bc5125d5db51a9d Mon Sep 17 00:00:00 2001 From: Andreas Morell-Reng Date: Tue, 21 Jan 2025 10:21:22 +0000 Subject: [PATCH 07/66] Translated using Weblate (Danish) Currently translated at 74.1% (802 of 1082 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/da/ --- client/strings/da.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/strings/da.json b/client/strings/da.json index b7be25540..deec29030 100644 --- a/client/strings/da.json +++ b/client/strings/da.json @@ -459,7 +459,7 @@ "LabelNotificationsMaxQueueSize": "Maksimal køstørrelse for meddelelseshændelser", "LabelNotificationsMaxQueueSizeHelp": "Hændelser begrænses til at udløse en gang pr. sekund. Hændelser ignoreres, hvis køen er fyldt. Dette forhindrer meddelelsesspam.", "LabelNumberOfBooks": "Antal bøger", - "LabelNumberOfEpisodes": "Antal episoder", + "LabelNumberOfEpisodes": "# afsnit", "LabelOpenRSSFeed": "Åbn RSS-feed", "LabelOverwrite": "Overskriv", "LabelPassword": "Kodeord", From 6f2384e4f20116d5921816f501d06f16f9ae3962 Mon Sep 17 00:00:00 2001 From: Andreas Morell-Reng Date: Tue, 21 Jan 2025 10:29:07 +0000 Subject: [PATCH 08/66] Translated using Weblate (Danish) Currently translated at 74.1% (802 of 1082 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/da/ --- client/strings/da.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/strings/da.json b/client/strings/da.json index deec29030..65c1754aa 100644 --- a/client/strings/da.json +++ b/client/strings/da.json @@ -492,7 +492,7 @@ "LabelRSSFeedURL": "RSS-feed-URL", "LabelRandomly": "Tilfældigt", "LabelRead": "Læst", - "LabelReadAgain": "Læs igen", + "LabelReadAgain": "Læs Igen", "LabelReadEbookWithoutProgress": "Læs e-bog uden at følge fremskridt", "LabelRecentSeries": "Seneste serier", "LabelRecentlyAdded": "Senest tilføjet", From a9dd67cf750c0b056b9f88facb9808fe23e22b18 Mon Sep 17 00:00:00 2001 From: Andreas Morell-Reng Date: Tue, 21 Jan 2025 10:29:21 +0000 Subject: [PATCH 09/66] Translated using Weblate (Danish) Currently translated at 74.2% (803 of 1082 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/da/ --- client/strings/da.json | 1 + 1 file changed, 1 insertion(+) diff --git a/client/strings/da.json b/client/strings/da.json index 65c1754aa..4d7605cb4 100644 --- a/client/strings/da.json +++ b/client/strings/da.json @@ -549,6 +549,7 @@ "LabelShowAll": "Vis alle", "LabelSize": "Størrelse", "LabelSleepTimer": "Søvntimer", + "LabelStart": "Start", "LabelStartTime": "Starttid", "LabelStarted": "Startet", "LabelStartedAt": "Startet klokken", From 7a89836c3e9e7f31af038374e884ab204613db9c Mon Sep 17 00:00:00 2001 From: Andreas Morell-Reng Date: Tue, 21 Jan 2025 11:06:18 +0000 Subject: [PATCH 10/66] Translated using Weblate (Danish) Currently translated at 100.0% (1082 of 1082 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/da/ --- client/strings/da.json | 279 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 277 insertions(+), 2 deletions(-) diff --git a/client/strings/da.json b/client/strings/da.json index 4d7605cb4..d36011fda 100644 --- a/client/strings/da.json +++ b/client/strings/da.json @@ -312,6 +312,7 @@ "LabelEmail": "E-mail", "LabelEmailSettingsFromAddress": "Fra Adresse", "LabelEmailSettingsRejectUnauthorized": "Afvis uautoriserede certifikater", + "LabelEmailSettingsRejectUnauthorizedHelp": "Deaktivering af SSL certifikat validering kan udsætte din forbindelse for sikkerhedsrisici, eksempelvis man-in-the-middle angreb. Deaktiver kun denne indstilling hvis du forstår de potentielle implikationer og stoler på den mailserver du forbinder til.", "LabelEmailSettingsSecure": "Sikker", "LabelEmailSettingsSecureHelp": "Hvis sandt, vil forbindelsen bruge TLS ved tilslutning til serveren. Hvis falsk, bruges TLS, hvis serveren understøtter STARTTLS-udvidelsen. I de fleste tilfælde skal denne værdi sættes til sandt, hvis du tilslutter til port 465. Til port 587 eller 25 skal du holde det falsk. (fra nodemailer.com/smtp/#authentication)", "LabelEmailSettingsTestAddress": "Test Adresse", @@ -325,9 +326,10 @@ "LabelEncodingStartedNavigation": "Når opgaven er startet kan du navigere væk fra denne side.", "LabelEncodingTimeWarning": "Indkodning kan tage op til 30 minutter.", "LabelEncodingWarningAdvancedSettings": "Advarsel: Opdater ikke disse indstillinger med mindre du kender til ffmpeg indkodningsindstillinger.", + "LabelEncodingWatcherDisabled": "Hvis du har watcheren deaktiveret skal du gen-scanne denne lydbog bagefter.", "LabelEnd": "Slut", "LabelEndOfChapter": "Slutningen af kapitel", - "LabelEpisode": "Episode", + "LabelEpisode": "Afsnit", "LabelEpisodeNotLinkedToRssFeed": "Afsnit er ikke koblet til RSS feed", "LabelEpisodeNumber": "Afsnit #{0}", "LabelEpisodeTitle": "Episodetitel", @@ -434,6 +436,7 @@ "LabelMissingEbook": "Har ingen ebog", "LabelMissingSupplementaryEbook": "Har ingen tillægsbog", "LabelMobileRedirectURIs": "Godkendte mobil redirect URI'er", + "LabelMobileRedirectURIsDescription": "Dete vil whiteliste en gyldig omdirigerings URL for mobile apps. Den standarde er audiobookshelf://oauth som du kan fjerne eller supplere med flere URI'er for tredjeparts app integration. Anvend en stjerne (*) som den eneste indstilling for at tilade en hvilkensomhelst URI.", "LabelMore": "Mere", "LabelMoreInfo": "Mere info", "LabelName": "Navn", @@ -445,6 +448,7 @@ "LabelNewestEpisodes": "Nyeste episoder", "LabelNextBackupDate": "Næste sikkerhedskopi dato", "LabelNextScheduledRun": "Næste planlagte kørsel", + "LabelNoCustomMetadataProviders": "Ingen brugerdefinerede metadata udbydere", "LabelNoEpisodesSelected": "Ingen episoder valgt", "LabelNotFinished": "Ikke færdig", "LabelNotStarted": "Ikke påbegyndt", @@ -460,30 +464,46 @@ "LabelNotificationsMaxQueueSizeHelp": "Hændelser begrænses til at udløse en gang pr. sekund. Hændelser ignoreres, hvis køen er fyldt. Dette forhindrer meddelelsesspam.", "LabelNumberOfBooks": "Antal bøger", "LabelNumberOfEpisodes": "# afsnit", + "LabelOpenIDAdvancedPermsClaimDescription": "Navnet af OpenID claimet som indeholder avancerede brugerhandlinger inden i applikationen som vil gælde for ikke administrative roller (hvis konfigureret). Hvis et claim mangler fra svaret vil adgang til ABS blive nægtet. Hvis en enkelt indstilling/option mangler, vil det bliver behandlet som false. Sørg for at identity provider's claim matcher den forventede struktur:", + "LabelOpenIDClaims": "Efterlad de følgende indstillinger tomme for at deaktivere avancerede grupper og adgangsstyring for automatisk at tilføje dem til 'User' gruppen.", + "LabelOpenIDGroupClaimDescription": "Navnet af det OpenID claim som skal indeholde brugerens grupper. Mest kendt som groups. hvis konfigureret, vil applikationen automatiske tildele roller baseret p[ brugerens gruppemedlemsskaber, givet disse grupper er navngivet (uden forbehold for store og små bogstaver) 'admin', 'user' eller 'guest' i claimet. Claimet burde indeholde en liste (og hvis brugeren tilhøre flere grupper) som applikationen vil tildele roller med højeste adgangsnvieau. Hvis ingen grupper matcher vil adgang blive nægtet.", "LabelOpenRSSFeed": "Åbn RSS-feed", "LabelOverwrite": "Overskriv", + "LabelPaginationPageXOfY": "Side {0} af {1}", "LabelPassword": "Kodeord", "LabelPath": "Sti", + "LabelPermanent": "Permanent", "LabelPermissionsAccessAllLibraries": "Kan få adgang til alle biblioteker", "LabelPermissionsAccessAllTags": "Kan få adgang til alle tags", "LabelPermissionsAccessExplicitContent": "Kan få adgang til eksplicit indhold", + "LabelPermissionsCreateEreader": "Kan oprette elæser", "LabelPermissionsDelete": "Kan slette", "LabelPermissionsDownload": "Kan downloade", "LabelPermissionsUpdate": "Kan opdatere", "LabelPermissionsUpload": "Kan uploade", + "LabelPersonalYearReview": "Dit år i review ({0})", "LabelPhotoPathURL": "Foto sti/URL", "LabelPlayMethod": "Afspilningsmetode", + "LabelPlayerChapterNumberMarker": "{0} af {1}", "LabelPlaylists": "Afspilningslister", + "LabelPodcast": "Podcast", "LabelPodcastSearchRegion": "Podcast søgeområde", "LabelPodcastType": "Podcast type", + "LabelPodcasts": "Podcast", + "LabelPort": "Port", "LabelPrefixesToIgnore": "Præfikser der skal ignoreres (skal ikke skelne mellem store og små bogstaver)", "LabelPreventIndexing": "Forhindrer, at dit feed bliver indekseret af iTunes og Google podcastkataloger", "LabelPrimaryEbook": "Primær e-bog", "LabelProgress": "Fremskridt", "LabelProvider": "Udbyder", + "LabelProviderAuthorizationValue": "Authorization Header værdi", "LabelPubDate": "Udgivelsesdato", "LabelPublishYear": "Udgivelsesår", + "LabelPublishedDate": "Publiceret {0}", + "LabelPublishedDecade": "Publiceret årti", + "LabelPublishedDecades": "Publiceret årtier", "LabelPublisher": "Forlag", + "LabelPublishers": "Forlag", "LabelRSSFeedCustomOwnerEmail": "Brugerdefineret ejerens e-mail", "LabelRSSFeedCustomOwnerName": "Brugerdefineret ejerens navn", "LabelRSSFeedOpen": "Åben RSS-feed", @@ -491,27 +511,42 @@ "LabelRSSFeedSlug": "RSS-feed-slug", "LabelRSSFeedURL": "RSS-feed-URL", "LabelRandomly": "Tilfældigt", + "LabelReAddSeriesToContinueListening": "Gentilføj serier til Fortsæt Lytning", "LabelRead": "Læst", "LabelReadAgain": "Læs Igen", "LabelReadEbookWithoutProgress": "Læs e-bog uden at følge fremskridt", "LabelRecentSeries": "Seneste serier", "LabelRecentlyAdded": "Senest tilføjet", "LabelRecommended": "Anbefalet", + "LabelRedo": "Gøre igen", + "LabelRegion": "Region", "LabelReleaseDate": "Udgivelsesdato", + "LabelRemoveAllMetadataAbs": "Fjern alle metadata.abs filer", + "LabelRemoveAllMetadataJson": "Fjern alle metadata.json filer", "LabelRemoveCover": "Fjern omslag", + "LabelRemoveMetadataFile": "Fjern alle metadata filer i biblioteksmapper", + "LabelRemoveMetadataFileHelp": "Fjern alle metadata.json og metadata.abs filer i dine {0} mapper.", + "LabelRowsPerPage": "Rækker per side", "LabelSearchTerm": "Søgeterm", "LabelSearchTitle": "Søg efter titel", "LabelSearchTitleOrASIN": "Søg efter titel eller ASIN", "LabelSeason": "Sæson", + "LabelSeasonNumber": "Sæson {0}", + "LabelSelectAll": "Vælg alle", "LabelSelectAllEpisodes": "Vælg alle episoder", "LabelSelectEpisodesShowing": "Vælg {0} episoder vist", + "LabelSelectUsers": "Valgte brugere", "LabelSendEbookToDevice": "Send e-bog til...", "LabelSequence": "Sekvens", + "LabelSerial": "Seriel", "LabelSeries": "Serie", "LabelSeriesName": "Serienavn", "LabelSeriesProgress": "Seriefremskridt", + "LabelServerLogLevel": "Server log niveau", + "LabelServerYearReview": "Server år i review ({0})", "LabelSetEbookAsPrimary": "Indstil som primær", "LabelSetEbookAsSupplementary": "Indstil som supplerende", + "LabelSettingsAllowIframe": "Tillad embedding i en iframe", "LabelSettingsAudiobooksOnly": "Kun lydbøger", "LabelSettingsAudiobooksOnlyHelp": "Aktivering af denne indstilling vil ignorere e-bogsfiler, medmindre de er inde i en lydbogmappe, hvor de vil blive indstillet som supplerende e-bøger", "LabelSettingsBookshelfViewHelp": "Skeumorfisk design med træhylder", @@ -523,6 +558,8 @@ "LabelSettingsEnableWatcher": "Aktiver overvågning", "LabelSettingsEnableWatcherForLibrary": "Aktiver mappeovervågning for bibliotek", "LabelSettingsEnableWatcherHelp": "Aktiverer automatisk tilføjelse/opdatering af elementer, når filændringer registreres. *Kræver servergenstart", + "LabelSettingsEpubsAllowScriptedContent": "Tillad scriptet indhold i epub", + "LabelSettingsEpubsAllowScriptedContentHelp": "Tillad epub filer at køre scripts. Det anbefales at holde denne indstilling deaktiveret med mindre du stoler på kilderne af epub filerne.", "LabelSettingsExperimentalFeatures": "Eksperimentelle funktioner", "LabelSettingsExperimentalFeaturesHelp": "Funktioner under udvikling, der kunne bruge din feedback og hjælp til test. Klik for at åbne Github-diskussionen.", "LabelSettingsFindCovers": "Find omslag", @@ -531,6 +568,11 @@ "LabelSettingsHideSingleBookSeriesHelp": "Serier med en enkelt bog vil blive skjult fra serie-siden og hjemmesidehylder.", "LabelSettingsHomePageBookshelfView": "Brug bogreolvisning på startside", "LabelSettingsLibraryBookshelfView": "Brug bogreolvisning i biblioteket", + "LabelSettingsLibraryMarkAsFinishedPercentComplete": "Procent gennemført er større end", + "LabelSettingsLibraryMarkAsFinishedTimeRemaining": "Tid tilbage er mindre end (sekunder)", + "LabelSettingsLibraryMarkAsFinishedWhen": "Marker medie indhold som færdigt når", + "LabelSettingsOnlyShowLaterBooksInContinueSeries": "Spring til tidligere bøger i Fortsæt serie", + "LabelSettingsOnlyShowLaterBooksInContinueSeriesHelp": "Fortsæt Serien siden hylde viser de første bøger som ikke er startet i serier med mindst en bog som ikke er startet og ingen bøger i gang. Aktivering af denne indstilling vil fortsætte serien fra den sidst gennemførte bog modsat den først ikke startede bog.", "LabelSettingsParseSubtitles": "Fortolk undertekster", "LabelSettingsParseSubtitlesHelp": "Udtræk undertekster fra lydbogsmappenavne.
Undertitler skal adskilles af \" - \"
f.eks. \"Bogtitel - En undertitel her\" har undertitlen \"En undertitel her\"", "LabelSettingsPreferMatchedMetadata": "Foretræk matchede metadata", @@ -546,9 +588,18 @@ "LabelSettingsStoreMetadataWithItem": "Gem metadata med element", "LabelSettingsStoreMetadataWithItemHelp": "Som standard gemmes metadatafiler i /metadata/items, aktivering af denne indstilling vil gemme metadatafiler i dine bibliotekselementmapper", "LabelSettingsTimeFormat": "Tidsformat", + "LabelShare": "Del", + "LabelShareDownloadableHelp": "Tillad brugere at dele link til at downloade en zip fil af dette biblioteksindhold.", + "LabelShareOpen": "Del åben", + "LabelShareURL": "Del URL", "LabelShowAll": "Vis alle", + "LabelShowSeconds": "Vis sekunder", + "LabelShowSubtitles": "Vis undertitler", "LabelSize": "Størrelse", "LabelSleepTimer": "Søvntimer", + "LabelSlug": "Snegl", + "LabelSortAscending": "Stigende", + "LabelSortDescending": "Faldende", "LabelStart": "Start", "LabelStartTime": "Starttid", "LabelStarted": "Startet", @@ -575,10 +626,19 @@ "LabelTagsAccessibleToUser": "Mærker tilgængelige for bruger", "LabelTagsNotAccessibleToUser": "Mærker ikke tilgængelige for bruger", "LabelTasks": "Kører opgaver", + "LabelTextEditorBulletedList": "Punktopstilling", + "LabelTextEditorLink": "Link", + "LabelTextEditorNumberedList": "Nummeropstilling", + "LabelTextEditorUnlink": "Aflink", "LabelTheme": "Tema", "LabelThemeDark": "Mørk", "LabelThemeLight": "Lys", "LabelTimeBase": "Tidsbase", + "LabelTimeDurationXHours": "{0} timer", + "LabelTimeDurationXMinutes": "{0} minutter", + "LabelTimeDurationXSeconds": "{0} sekunder", + "LabelTimeInMinutes": "Tid i minutter", + "LabelTimeLeft": "{0} tilbage", "LabelTimeListened": "Tid hørt", "LabelTimeListenedToday": "Tid hørt i dag", "LabelTimeRemaining": "{0} tilbage", @@ -586,6 +646,7 @@ "LabelTitle": "Titel", "LabelToolsEmbedMetadata": "Indlejre metadata", "LabelToolsEmbedMetadataDescription": "Indlejr metadata i lydfiler, inklusive omslag og kapitler.", + "LabelToolsM4bEncoder": "M4B indkoder", "LabelToolsMakeM4b": "Lav M4B lydbogsfil", "LabelToolsMakeM4bDescription": "Generer en .M4B lydbogsfil med indlejret metadata, omslag og kapitler.", "LabelToolsSplitM4b": "Opdel M4B til MP3'er", @@ -598,25 +659,41 @@ "LabelTracksMultiTrack": "Flerspors", "LabelTracksNone": "Ingen spor", "LabelTracksSingleTrack": "Enkeltspors", + "LabelTrailer": "Trailer", + "LabelType": "Type", "LabelUnabridged": "Uforkortet", + "LabelUndo": "Undo", "LabelUnknown": "Ukendt", + "LabelUnknownPublishDate": "Ukendt publiceringsdato", "LabelUpdateCover": "Opdater omslag", "LabelUpdateCoverHelp": "Tillad overskrivning af eksisterende omslag for de valgte bøger, når der findes en match", "LabelUpdateDetails": "Opdater detaljer", "LabelUpdateDetailsHelp": "Tillad overskrivning af eksisterende detaljer for de valgte bøger, når der findes en match", "LabelUpdatedAt": "Opdateret ved", "LabelUploaderDragAndDrop": "Træk og slip filer eller mapper", + "LabelUploaderDragAndDropFilesOnly": "Træk og slip filer", "LabelUploaderDropFiles": "Smid filer", + "LabelUploaderItemFetchMetadataHelp": "Automatisk hent titel, forfatter og serie", + "LabelUseAdvancedOptions": "Anvend avancerede indstillinger", "LabelUseChapterTrack": "Brug kapitel-spor", "LabelUseFullTrack": "Brug fuldt spor", + "LabelUseZeroForUnlimited": "Anvend 0 for ubegrænset", "LabelUser": "Bruger", "LabelUsername": "Brugernavn", "LabelValue": "Værdi", + "LabelVersion": "Version", "LabelViewBookmarks": "Se bogmærker", "LabelViewChapters": "Se kapitler", + "LabelViewPlayerSettings": "Vis afspiller indstillinger", "LabelViewQueue": "Se afspilningskø", "LabelVolume": "Volumen", + "LabelWebRedirectURLsDescription": "Godkend disse URL'er i din OAuth udgiver for at tillade omdirigering tilbage til hjemmesiden efter login:", + "LabelWebRedirectURLsSubfolder": "Undermapper for omdirigerings URL'er", "LabelWeekdaysToRun": "Ugedage til kørsel", + "LabelXBooks": "{0} bøger", + "LabelXItems": "{0} genstande", + "LabelYearReviewHide": "Skjul år i review", + "LabelYearReviewShow": "Vis år i review", "LabelYourAudiobookDuration": "Din lydbogsvarighed", "LabelYourBookmarks": "Dine bogmærker", "LabelYourPlaylists": "Dine spillelister", @@ -624,10 +701,14 @@ "MessageAddToPlayerQueue": "Tilføj til afspilningskø", "MessageAppriseDescription": "For at bruge denne funktion skal du have en instans af Apprise API kørende eller en API, der håndterer de samme anmodninger.
Apprise API-webadressen skal være den fulde URL-sti for at sende underretningen, f.eks. hvis din API-instans er tilgængelig på http://192.168.1.1:8337, så skal du bruge http://192.168.1.1:8337/notify.", "MessageBackupsDescription": "Backups inkluderer brugere, brugerfremskridt, biblioteksvareoplysninger, serverindstillinger og billeder gemt i /metadata/items og /metadata/authors. Backups inkluderer ikke nogen filer gemt i dine biblioteksmapper.", + "MessageBackupsLocationEditNote": "Note: Opdatering af backup sti vil ikke fjerne eller modificere eksisterende backups", + "MessageBackupsLocationNoEditNote": "Note: Backup sti er sat igennem miljøvariabel og kan ikke ændres her.", + "MessageBackupsLocationPathEmpty": "Backup sti kan ikke være tom", "MessageBatchQuickMatchDescription": "Quick Match vil forsøge at tilføje manglende omslag og metadata til de valgte elementer. Aktivér indstillingerne nedenfor for at tillade Quick Match at overskrive eksisterende omslag og/eller metadata.", "MessageBookshelfNoCollections": "Du har ikke oprettet nogen samlinger endnu", "MessageBookshelfNoRSSFeeds": "Ingen RSS-feeds er åbne", "MessageBookshelfNoResultsForFilter": "Ingen resultater for filter \"{0}: {1}\"", + "MessageBookshelfNoResultsForQuery": "Intet resultat for query", "MessageBookshelfNoSeries": "Du har ingen serier", "MessageChapterEndIsAfter": "Kapitelslutningen er efter slutningen af din lydbog", "MessageChapterErrorFirstNotZero": "Første kapitel skal starte ved 0", @@ -637,19 +718,35 @@ "MessageCheckingCron": "Tjekker cron...", "MessageConfirmCloseFeed": "Er du sikker på, at du vil lukke dette feed?", "MessageConfirmDeleteBackup": "Er du sikker på, at du vil slette backup for {0}?", + "MessageConfirmDeleteDevice": "Er du sikker på at du vil fjerne elæser enhed \"{0}\"?", "MessageConfirmDeleteFile": "Dette vil slette filen fra dit filsystem. Er du sikker?", "MessageConfirmDeleteLibrary": "Er du sikker på, at du vil slette biblioteket permanent \"{0}\"?", + "MessageConfirmDeleteLibraryItem": "Dette vil slette biblioteksgenstanden fra databasen og dit filsystem. Er du sikker?", + "MessageConfirmDeleteLibraryItems": "Dette vil slette {0} biblioteksgenstande fra din database og filsystem. Er du sikker?", + "MessageConfirmDeleteMetadataProvider": "Er du sikker på at du vil fjerne brugerdefineret metadata udgiver \"{0}\"?", + "MessageConfirmDeleteNotification": "Er du sikker på at du vil fjerne denne notifikation?", "MessageConfirmDeleteSession": "Er du sikker på, at du vil slette denne session?", + "MessageConfirmEmbedMetadataInAudioFiles": "Er du sikker på at du vil indlejre metadata i {0} lydbogsfiler?", "MessageConfirmForceReScan": "Er du sikker på, at du vil tvinge en genindlæsning?", "MessageConfirmMarkAllEpisodesFinished": "Er du sikker på, at du vil markere alle episoder som afsluttet?", "MessageConfirmMarkAllEpisodesNotFinished": "Er du sikker på, at du vil markere alle episoder som ikke afsluttet?", + "MessageConfirmMarkItemFinished": "Er du sikker på at du vil markere \"{0}\" som færdig?", + "MessageConfirmMarkItemNotFinished": "Er du sikker på at du vil markere \"{0}\" som ikke færdige?", "MessageConfirmMarkSeriesFinished": "Er du sikker på, at du vil markere alle bøger i denne serie som afsluttet?", "MessageConfirmMarkSeriesNotFinished": "Er du sikker på, at du vil markere alle bøger i denne serie som ikke afsluttet?", + "MessageConfirmNotificationTestTrigger": "Trigger denne notifikation med testdata?", + "MessageConfirmPurgeCache": "Rensning af cache vil slette hele mappen ved /metadata/cache.

Er dy sikker på at du vil fjerne cache mappen?", + "MessageConfirmPurgeItemsCache": "Rensning af cache vil slette hele mappen ved /metadata/cache/items.
Er du sikker?", + "MessageConfirmQuickEmbed": "Advarsel! Hurtigindlejring vil ikke backe dine lydfiler op. S'rg for at du har en backup af dine lydfiler.

Vil du fortsætte?", + "MessageConfirmQuickMatchEpisodes": "Hurtig match af afsnit vil overskrive detaljer givet et match kan findes. Kun ikke-matchede vil blive opdateret. Er du sikker?", + "MessageConfirmReScanLibraryItems": "Er du sikker på at du vil genscanne {0} genstande?", "MessageConfirmRemoveAllChapters": "Er du sikker på, at du vil fjerne alle kapitler?", "MessageConfirmRemoveAuthor": "Er du sikker på, at du vil fjerne forfatteren \"{0}\"?", "MessageConfirmRemoveCollection": "Er du sikker på, at du vil fjerne samlingen \"{0}\"?", "MessageConfirmRemoveEpisode": "Er du sikker på, at du vil fjerne episoden \"{0}\"?", "MessageConfirmRemoveEpisodes": "Er du sikker på, at du vil fjerne {0} episoder?", + "MessageConfirmRemoveListeningSessions": "Er du sikker på at du vil fjerne {0} lytte sessioner?", + "MessageConfirmRemoveMetadataFiles": "Er du sikker på at du vil fjerne alle metadata.{0} filer i dine biblioteksfoldere?", "MessageConfirmRemoveNarrator": "Er du sikker på, at du vil fjerne fortælleren \"{0}\"?", "MessageConfirmRemovePlaylist": "Er du sikker på, at du vil fjerne din spilleliste \"{0}\"?", "MessageConfirmRenameGenre": "Er du sikker på, at du vil omdøbe genre \"{0}\" til \"{1}\" for alle elementer?", @@ -658,11 +755,17 @@ "MessageConfirmRenameTag": "Er du sikker på, at du vil omdøbe tag \"{0}\" til \"{1}\" for alle elementer?", "MessageConfirmRenameTagMergeNote": "Bemærk: Dette tag findes allerede, så de vil blive fusioneret.", "MessageConfirmRenameTagWarning": "Advarsel! Et lignende tag med en anden skrivemåde eksisterer allerede \"{0}\".", + "MessageConfirmResetProgress": "Er du sikker på at du vil nulstille dit fremskridt?", "MessageConfirmSendEbookToDevice": "Er du sikker på, at du vil sende {0} e-bog \"{1}\" til enhed \"{2}\"?", + "MessageConfirmUnlinkOpenId": "Er du sikker på at du vil fjerne linket mellem denne bruger og OpenID?", + "MessageDaysListenedInTheLastYear": "{0} dage lyttet i løbet af det sidste år", "MessageDownloadingEpisode": "Downloader episode", "MessageDragFilesIntoTrackOrder": "Træk filer ind i korrekt spororden", + "MessageEmbedFailed": "Indlejring fejlede!", "MessageEmbedFinished": "Indlejring færdig!", + "MessageEmbedQueue": "Sat i kø for metadata indlejring ({0} i kø)", "MessageEpisodesQueuedForDownload": "{0} episoder er sat i kø til download", + "MessageEreaderDevices": "For at sikre levering af ebøger, skal du eventuelt tilføje mailadressen som en gyldig afsender for hver enhed angivet forneden.", "MessageFeedURLWillBe": "Feed-URL vil være {0}", "MessageFetching": "Henter...", "MessageForceReScanDescription": "vil scanne alle filer igen som en frisk scanning. Lydfilens ID3-tags, OPF-filer og tekstfiler scannes som nye.", @@ -673,6 +776,7 @@ "MessageJoinUsOn": "Deltag i os på", "MessageLoading": "Indlæser...", "MessageLoadingFolders": "Indlæser mapper...", + "MessageLogsDescription": "Logfiler er gemt i /metadata/logs som JSON filer. Crash log er gemt i /metadata/logs/crash_logs.txt.", "MessageM4BFailed": "M4B mislykkedes!", "MessageM4BFinished": "M4B afsluttet!", "MessageMapChapterTitles": "Tilknyt kapiteloverskrifter til dine eksisterende lydbogskapitler uden at justere tidsstempler", @@ -689,6 +793,7 @@ "MessageNoCollections": "Ingen samlinger", "MessageNoCoversFound": "Ingen omslag fundet", "MessageNoDescription": "Ingen beskrivelse", + "MessageNoDevices": "Ingen enheder", "MessageNoDownloadsInProgress": "Ingen downloads i gang lige nu", "MessageNoDownloadsQueued": "Ingen downloads i kø", "MessageNoEpisodeMatchesFound": "Ingen episode-matcher fundet", @@ -702,6 +807,7 @@ "MessageNoLogs": "Ingen logfiler", "MessageNoMediaProgress": "Ingen medieforløb", "MessageNoNotifications": "Ingen meddelelser", + "MessageNoPodcastFeed": "Invalid podcast: Intet feed", "MessageNoPodcastsFound": "Ingen podcasts fundet", "MessageNoResults": "Ingen resultater", "MessageNoSearchResultsFor": "Ingen søgeresultater for \"{0}\"", @@ -711,11 +817,17 @@ "MessageNoUpdatesWereNecessary": "Ingen opdateringer var nødvendige", "MessageNoUserPlaylists": "Du har ingen afspilningslister", "MessageNotYetImplemented": "Endnu ikke implementeret", + "MessageOpmlPreviewNote": "Note: Dette er en forhåndsvisning af den indlæste OPML fil. Podcast titel vil blive taget fra RSS feedet.", "MessageOr": "eller", "MessagePauseChapter": "Pause kapitelafspilning", "MessagePlayChapter": "Lyt til begyndelsen af kapitlet", "MessagePlaylistCreateFromCollection": "Opret afspilningsliste fra samling", + "MessagePleaseWait": "Vent venligst...", "MessagePodcastHasNoRSSFeedForMatching": "Podcast har ingen RSS-feed-URL at bruge til matchning", + "MessagePodcastSearchField": "Indtast søgeterm eller RSS URL", + "MessageQuickEmbedInProgress": "Hurtig indlejring igang", + "MessageQuickEmbedQueue": "I kø for hurtigindlejring ({0} i kø)", + "MessageQuickMatchAllEpisodes": "Hurtig match alle afsnit", "MessageQuickMatchDescription": "Udfyld tomme elementoplysninger og omslag med første matchresultat fra '{0}'. Overskriver ikke oplysninger, medmindre serverindstillingen 'Foretræk matchet metadata' er aktiveret.", "MessageRemoveChapter": "Fjern kapitel", "MessageRemoveEpisodes": "Fjern {0} episode(r)", @@ -725,10 +837,50 @@ "MessageResetChaptersConfirm": "Er du sikker på, at du vil nulstille kapitler og annullere ændringerne, du har foretaget?", "MessageRestoreBackupConfirm": "Er du sikker på, at du vil gendanne sikkerhedskopien oprettet den", "MessageRestoreBackupWarning": "Gendannelse af en sikkerhedskopi vil overskrive hele databasen, som er placeret på /config, og omslagsbilleder i /metadata/items & /metadata/authors.

Sikkerhedskopier ændrer ikke nogen filer i dine biblioteksmapper. Hvis du har aktiveret serverindstillinger for at gemme omslagskunst og metadata i dine biblioteksmapper, sikkerhedskopieres eller overskrives disse ikke.

Alle klienter, der bruger din server, opdateres automatisk.", + "MessageScheduleLibraryScanNote": "For de fleste brugere, er det anbefalet at efterlade denne funktion deaktiveret for at holde mappe lurer indstilling aktiveret. Mappe lureren vil automatisk opdage ændringer i biblioteksmapper. Mappe lureren virker ikke for alle filsystemer (så som NFS) så schedulerede biblioteksscans vil blive anvendt.", "MessageSearchResultsFor": "Søgeresultater for", + "MessageSelected": "{0} valgt", "MessageServerCouldNotBeReached": "Serveren kunne ikke nås", "MessageSetChaptersFromTracksDescription": "Indstil kapitler ved at bruge hver lydfil som et kapitel og kapiteloverskrift som lydfilnavn", + "MessageShareExpirationWillBe": "Udløb vil være {0}", + "MessageShareExpiresIn": "Udløber om {0}", + "MessageShareURLWillBe": "Del URL vil være {0}", "MessageStartPlaybackAtTime": "Start afspilning for \"{0}\" kl. {1}?", + "MessageTaskAudioFileNotWritable": "Lydbogsfil \"{0}\" er ikke skrivebar", + "MessageTaskCanceledByUser": "Opgave annulleret af bruger", + "MessageTaskDownloadingEpisodeDescription": "Download afsnit \"{0}\"", + "MessageTaskEmbeddingMetadata": "Indlejring af metadata", + "MessageTaskEmbeddingMetadataDescription": "Indlejring af metadata i lydbog \"{0}\"", + "MessageTaskEncodingM4b": "Indkodning M4B", + "MessageTaskEncodingM4bDescription": "Indkodning lydog \"{0}\" ind i en enkelt M4B fil", + "MessageTaskFailed": "Fejlet", + "MessageTaskFailedToBackupAudioFile": "Fejlede backup af lydbogsfil \"{0}\"", + "MessageTaskFailedToCreateCacheDirectory": "Fejlede at oprette cache mappe", + "MessageTaskFailedToEmbedMetadataInFile": "Fejlede at indkode metadata i fil \"{0}\"", + "MessageTaskFailedToMergeAudioFiles": "Fejlede at sammenflette lydbogsfiler", + "MessageTaskFailedToMoveM4bFile": "Fejlede i at flytte M4B fil", + "MessageTaskFailedToWriteMetadataFile": "Fejlede i at skrive metadata fil", + "MessageTaskMatchingBooksInLibrary": "Matchede bøger i bibliotek \"{0}\"", + "MessageTaskNoFilesToScan": "Ingen filer at scanne", + "MessageTaskOpmlImport": "OPML import", + "MessageTaskOpmlImportDescription": "Oprettelse af podcasts fra {0} RSS feeds", + "MessageTaskOpmlImportFeed": "OPML importering fejlede", + "MessageTaskOpmlImportFeedDescription": "Importering af RSS feed \"{0}\"", + "MessageTaskOpmlImportFeedFailed": "Fejlede at hente podcast feed", + "MessageTaskOpmlImportFeedPodcastDescription": "Opretter podcast \"{0}\"", + "MessageTaskOpmlImportFeedPodcastExists": "Podcast ligger allerede på filsti", + "MessageTaskOpmlImportFeedPodcastFailed": "Fejlede i at oprette podcast", + "MessageTaskOpmlImportFinished": "Tilføjede {0} podcasts", + "MessageTaskOpmlParseFailed": "Fejlede i at læse OPML fil", + "MessageTaskOpmlParseFastFail": "Forkert OPML tag ikke fundet ELLER et tag var ikke fundet", + "MessageTaskOpmlParseNoneFound": "Ingen feeds fundet i OPML fil", + "MessageTaskScanItemsAdded": "{0} tilføjet", + "MessageTaskScanItemsMissing": "{0} mangler", + "MessageTaskScanItemsUpdated": "{0} opdateret", + "MessageTaskScanNoChangesNeeded": "Ingen ændringer nødvendigt", + "MessageTaskScanningFileChanges": "Scanner filændringer i \"{0}\"", + "MessageTaskScanningLibrary": "Scanning af \"{0}\" bibliotek", + "MessageTaskTargetDirectoryNotWritable": "Mål sti er ikke skrivebar", "MessageThinking": "Tænker...", "MessageUploaderItemFailed": "Fejl ved upload", "MessageUploaderItemSuccess": "Uploadet med succes!", @@ -746,38 +898,102 @@ "NoteUploaderFoldersWithMediaFiles": "Mapper med mediefiler håndteres som separate bibliotekselementer.", "NoteUploaderOnlyAudioFiles": "Hvis du kun uploader lydfiler, håndteres hver lydfil som en separat lydbog.", "NoteUploaderUnsupportedFiles": "Ikke-understøttede filer ignoreres. Når du vælger eller slipper en mappe, ignoreres andre filer, der ikke er i en emnemappe.", + "NotificationOnBackupCompletedDescription": "Udløst når backup er færdig", + "NotificationOnBackupFailedDescription": "Udløst når backup fejler", + "NotificationOnEpisodeDownloadedDescription": "Udløst når et podcast afsnit er automatisk downloadet", + "NotificationOnTestDescription": "Event for test af notifikationssystemet", "PlaceholderNewCollection": "Nyt samlingnavn", "PlaceholderNewFolderPath": "Ny mappes sti", "PlaceholderNewPlaylist": "Nyt afspilningslistnavn", "PlaceholderSearch": "Søg..", "PlaceholderSearchEpisode": "Søg efter episode..", + "StatsAuthorsAdded": "forfattere tilføjet", + "StatsBooksAdded": "bøger tilføjet", + "StatsBooksAdditional": "Nogle tilføjelser inkludere…", + "StatsBooksFinished": "bøger færdige", + "StatsBooksFinishedThisYear": "Nogle bøger færdiggjort i år.…", + "StatsBooksListenedTo": "bøger lyttet til", + "StatsCollectionGrewTo": "Din bog kollektion voksede til…", + "StatsSessions": "sessioner", + "StatsSpentListening": "brugt at lytte", + "StatsTopAuthor": "TOP FORFATTER", + "StatsTopAuthors": "TOP FORFATTERE", + "StatsTopGenre": "TOP GENRE", + "StatsTopGenres": "TOP GENRER", + "StatsTopMonth": "TOP MÅNED", + "StatsTopNarrator": "TOP OPLÆSER", + "StatsTopNarrators": "TOP OPLÆSERE", + "StatsTotalDuration": "Med den totale varighed af…", + "StatsYearInReview": "ÅR I REVIEW", "ToastAccountUpdateSuccess": "Konto opdateret", + "ToastAppriseUrlRequired": "Skal indtaste en Apprise URL", + "ToastAsinRequired": "ASIN er påkrævet", "ToastAuthorImageRemoveSuccess": "Forfatterbillede fjernet", + "ToastAuthorNotFound": "Forfatter \"{0}\" ikke fundet", + "ToastAuthorRemoveSuccess": "Forfatter fjernet", + "ToastAuthorSearchNotFound": "Forfatter ikke fundet", "ToastAuthorUpdateMerged": "Forfatter fusioneret", "ToastAuthorUpdateSuccess": "Forfatter opdateret", "ToastAuthorUpdateSuccessNoImageFound": "Forfatter opdateret (ingen billede fundet)", + "ToastBackupAppliedSuccess": "Backup indlæst", "ToastBackupCreateFailed": "Mislykkedes oprettelse af sikkerhedskopi", "ToastBackupCreateSuccess": "Sikkerhedskopi oprettet", "ToastBackupDeleteFailed": "Mislykkedes sletning af sikkerhedskopi", "ToastBackupDeleteSuccess": "Sikkerhedskopi slettet", + "ToastBackupInvalidMaxKeep": "Forkert antal backups at beholde", + "ToastBackupInvalidMaxSize": "Forkert maks backup størrelse", "ToastBackupRestoreFailed": "Mislykkedes gendannelse af sikkerhedskopi", "ToastBackupUploadFailed": "Mislykkedes upload af sikkerhedskopi", "ToastBackupUploadSuccess": "Sikkerhedskopi uploadet", + "ToastBatchDeleteFailed": "Batch slet fejlede", + "ToastBatchDeleteSuccess": "Batch slet succes", + "ToastBatchQuickMatchFailed": "Batch Hurtig Match fejlede!", + "ToastBatchQuickMatchStarted": "Batch Hurtig Match af {0} bøger startet!", "ToastBatchUpdateFailed": "Mislykkedes batchopdatering", "ToastBatchUpdateSuccess": "Batchopdatering lykkedes", "ToastBookmarkCreateFailed": "Mislykkedes oprettelse af bogmærke", "ToastBookmarkCreateSuccess": "Bogmærke tilføjet", "ToastBookmarkRemoveSuccess": "Bogmærke fjernet", + "ToastCachePurgeFailed": "Fejlede at opryde cache", + "ToastCachePurgeSuccess": "Cache ryddet op i succesfuldt", "ToastChaptersHaveErrors": "Kapitler har fejl", "ToastChaptersMustHaveTitles": "Kapitler skal have titler", + "ToastChaptersRemoved": "Kapitler fjernet", + "ToastChaptersUpdated": "Kapitler opdateret", + "ToastCollectionItemsAddFailed": "Genstand(e) tilføjet til kollektion fejlet", "ToastCollectionRemoveSuccess": "Samling fjernet", "ToastCollectionUpdateSuccess": "Samling opdateret", + "ToastCoverUpdateFailed": "Cover opdatering fejlede", + "ToastDateTimeInvalidOrIncomplete": "Dato og tid er forkert eller ufærdig", + "ToastDeleteFileFailed": "Slet fil fejlede", + "ToastDeleteFileSuccess": "Fil slettet", + "ToastDeviceAddFailed": "Fejlede at tilføje enhed", + "ToastDeviceNameAlreadyExists": "Elæser enhed med det navn eksistere allerede", + "ToastDeviceTestEmailFailed": "Fejlede at sende test mail", + "ToastDeviceTestEmailSuccess": "Test mail sendt", + "ToastEmailSettingsUpdateSuccess": "Mail indstillinger opdateret", + "ToastEncodeCancelFailed": "Fejlede at afbryde indkodning", + "ToastEncodeCancelSucces": "Indkodning afbrudt", + "ToastEpisodeDownloadQueueClearFailed": "Fejlede at rydde op i kø", + "ToastEpisodeDownloadQueueClearSuccess": "Afsnit download kø renset", + "ToastEpisodeUpdateSuccess": "{0} afsnit opdateret", + "ToastErrorCannotShare": "Kan ikke dele på denne enhed", + "ToastFailedToLoadData": "Fejlede at indlæse data", + "ToastFailedToMatch": "Fejlet match", + "ToastFailedToShare": "Fejlet deling", + "ToastFailedToUpdate": "Fejlet opdatering", + "ToastInvalidImageUrl": "Forkert billede URL", + "ToastInvalidMaxEpisodesToDownload": "Forkert maks afsnit at hente", + "ToastInvalidUrl": "Forkert URL", "ToastItemCoverUpdateSuccess": "Varens omslag opdateret", + "ToastItemDeletedFailed": "Fejlede at slette genstand", + "ToastItemDeletedSuccess": "Genstand slettet", "ToastItemDetailsUpdateSuccess": "Varedetaljer opdateret", "ToastItemMarkedAsFinishedFailed": "Mislykkedes markering som afsluttet", "ToastItemMarkedAsFinishedSuccess": "Vare markeret som afsluttet", "ToastItemMarkedAsNotFinishedFailed": "Mislykkedes markering som ikke afsluttet", "ToastItemMarkedAsNotFinishedSuccess": "Vare markeret som ikke afsluttet", + "ToastItemUpdateSuccess": "Genstand opdateret", "ToastLibraryCreateFailed": "Mislykkedes oprettelse af bibliotek", "ToastLibraryCreateSuccess": "Bibliotek \"{0}\" oprettet", "ToastLibraryDeleteFailed": "Mislykkedes sletning af bibliotek", @@ -785,25 +1001,84 @@ "ToastLibraryScanFailedToStart": "Mislykkedes start af skanning", "ToastLibraryScanStarted": "Biblioteksskanning startet", "ToastLibraryUpdateSuccess": "Bibliotek \"{0}\" opdateret", + "ToastMatchAllAuthorsFailed": "Fejlede at matche alle forfattere", + "ToastMetadataFilesRemovedError": "Fejlet at fjerne metadata.{0} filer", + "ToastMetadataFilesRemovedNoneFound": "Ingen metadata.{0} filer fundet i bibliotek", + "ToastMetadataFilesRemovedNoneRemoved": "Ingen metadata.{0} filer slettet", + "ToastMetadataFilesRemovedSuccess": "{0} metadata.{1} filer slettet", + "ToastMustHaveAtLeastOnePath": "Skal have mindst en sti", + "ToastNameEmailRequired": "Navn og email påkrævet", + "ToastNameRequired": "Navn påkrævet", + "ToastNewEpisodesFound": "{0} nye afsnit fundet", + "ToastNewUserCreatedFailed": "Fejlede at oprette konto: \"{0}\"", + "ToastNewUserCreatedSuccess": "Ny konto oprettet", + "ToastNewUserLibraryError": "Skal vælge mindst et bibliotek", + "ToastNewUserPasswordError": "Skal have et password, kun root brugeren kan have et tomt password", + "ToastNewUserTagError": "Skal vælge mindst et tag", + "ToastNewUserUsernameError": "Angiv brugernavn", + "ToastNoNewEpisodesFound": "Ingen nye afsnit fundet", + "ToastNoRSSFeed": "Podcast har ingen RSS feed", + "ToastNoUpdatesNecessary": "Ingen opdateringer nødvendige", + "ToastNotificationCreateFailed": "Fejlede at oprette notifikation", + "ToastNotificationDeleteFailed": "Fejlede at slette notifikation", + "ToastNotificationFailedMaximum": "Maks forsøg skal være >= 0", + "ToastNotificationQueueMaximum": "Maks notifikationskø skal være >= 0", + "ToastNotificationSettingsUpdateSuccess": "Notifikationsindstillinger opdateret", + "ToastNotificationTestTriggerFailed": "Fejlede at oprette en test notifikation", + "ToastNotificationTestTriggerSuccess": "Test notifikation oprettet", + "ToastNotificationUpdateSuccess": "Notifikation opdateret", "ToastPlaylistCreateFailed": "Mislykkedes oprettelse af afspilningsliste", "ToastPlaylistCreateSuccess": "Afspilningsliste oprettet", "ToastPlaylistRemoveSuccess": "Afspilningsliste fjernet", "ToastPlaylistUpdateSuccess": "Afspilningsliste opdateret", "ToastPodcastCreateFailed": "Mislykkedes oprettelse af podcast", "ToastPodcastCreateSuccess": "Podcast oprettet med succes", + "ToastPodcastGetFeedFailed": "Fejlede at hente podcast feed", + "ToastPodcastNoEpisodesInFeed": "Ingen nye afsnit fundet i RSS feed", + "ToastPodcastNoRssFeed": "Podcast har ingen RSS feed", + "ToastProgressIsNotBeingSynced": "Fremskridt ikke synkroniseret, genstart afspilning", + "ToastProviderCreatedFailed": "Fejlede at tilføje udbyder", + "ToastProviderCreatedSuccess": "Ny udbyder tilføjet", + "ToastProviderNameAndUrlRequired": "Navn og URL påkrævet", + "ToastProviderRemoveSuccess": "Udbyder fjernet", "ToastRSSFeedCloseFailed": "Mislykkedes lukning af RSS-feed", "ToastRSSFeedCloseSuccess": "RSS-feed lukket", + "ToastRemoveFailed": "Fejlede at slette", "ToastRemoveItemFromCollectionFailed": "Mislykkedes fjernelse af element fra samling", "ToastRemoveItemFromCollectionSuccess": "Element fjernet fra samling", + "ToastRemoveItemsWithIssuesFailed": "Fejlede at slette genstande med fejl", + "ToastRemoveItemsWithIssuesSuccess": "Slettede genstande med fejl", + "ToastRenameFailed": "Fejlede at omdøbe", + "ToastRescanFailed": "Genscan fejlede for {0}", + "ToastRescanRemoved": "Genscan gennemført, genstand blev fjernet", + "ToastRescanUpToDate": "Genscan gennemført, genstand var opdateret", + "ToastRescanUpdated": "Genscan gennemført, genstand blev opdateret", + "ToastScanFailed": "Fejlede at scanne biblioteksgenstand", + "ToastSelectAtLeastOneUser": "Vælg mindst en bruger", "ToastSendEbookToDeviceFailed": "Mislykkedes afsendelse af e-bog til enhed", "ToastSendEbookToDeviceSuccess": "E-bog afsendt til enhed \"{0}\"", "ToastSeriesUpdateFailed": "Mislykkedes opdatering af serie", "ToastSeriesUpdateSuccess": "Serieopdatering lykkedes", + "ToastServerSettingsUpdateSuccess": "Server indstillinger opdateret", + "ToastSessionCloseFailed": "Luk session fejlede", "ToastSessionDeleteFailed": "Mislykkedes sletning af session", "ToastSessionDeleteSuccess": "Session slettet", + "ToastSleepTimerDone": "Sleep timer færdig... zZzzZz", + "ToastSlugMustChange": "Snegl indeholder ugyldige karakterer", + "ToastSlugRequired": "Snegl påkrævet", "ToastSocketConnected": "Socket forbundet", "ToastSocketDisconnected": "Socket afbrudt", "ToastSocketFailedToConnect": "Socket kunne ikke oprettes", + "ToastSortingPrefixesEmptyError": "Skal indeholde mindst 1 sorteringspræfiks", + "ToastSortingPrefixesUpdateSuccess": "Sortering af præfiks opdateret ({0} genstande)", + "ToastTitleRequired": "Titel påkrævet", + "ToastUnknownError": "Ukendt fejl", + "ToastUnlinkOpenIdFailed": "Fejlede i af afkoble bruger fra OpenID", + "ToastUnlinkOpenIdSuccess": "Bruger afkoblet fra OpenID", "ToastUserDeleteFailed": "Mislykkedes sletning af bruger", - "ToastUserDeleteSuccess": "Bruger slettet" + "ToastUserDeleteSuccess": "Bruger slettet", + "ToastUserPasswordChangeSuccess": "Password ændret", + "ToastUserPasswordMismatch": "Passwords passer ikke sammen", + "ToastUserPasswordMustChange": "Nyt password må ikke være det gamle", + "ToastUserRootRequireName": "Skal indholde et root brugernavn" } From d25b46e9fa6081e7307eb4c31b7c49dd57ce7c68 Mon Sep 17 00:00:00 2001 From: Charlie Date: Tue, 21 Jan 2025 21:44:09 +0000 Subject: [PATCH 11/66] Translated using Weblate (French) Currently translated at 100.0% (1082 of 1082 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/fr/ --- client/strings/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/strings/fr.json b/client/strings/fr.json index fd5d2182d..8b640a6bf 100644 --- a/client/strings/fr.json +++ b/client/strings/fr.json @@ -546,7 +546,7 @@ "LabelServerYearReview": "Bilan de l’année du serveur ({0})", "LabelSetEbookAsPrimary": "Définir comme principale", "LabelSetEbookAsSupplementary": "Définir comme supplémentaire", - "LabelSettingsAllowIframe": "Autoriser l'intégration dans une iframe", + "LabelSettingsAllowIframe": "Autoriser l’intégration dans une iframe", "LabelSettingsAudiobooksOnly": "Livres audios seulement", "LabelSettingsAudiobooksOnlyHelp": "L’activation de ce paramètre ignorera les fichiers de type « livre numériques », sauf s’ils se trouvent dans un dossier spécifique , auquel cas ils seront définis comme des livres numériques supplémentaires", "LabelSettingsBookshelfViewHelp": "Interface skeumorphique avec étagères en bois", From 9b561e43670d64a0cd5cf0b8fc093193a0e654fa Mon Sep 17 00:00:00 2001 From: Milo Ivir Date: Tue, 21 Jan 2025 20:47:34 +0000 Subject: [PATCH 12/66] Translated using Weblate (Croatian) Currently translated at 100.0% (1082 of 1082 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/hr/ --- client/strings/hr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/strings/hr.json b/client/strings/hr.json index bc5245ea2..84912f9a5 100644 --- a/client/strings/hr.json +++ b/client/strings/hr.json @@ -51,7 +51,7 @@ "ButtonNext": "Sljedeće", "ButtonNextChapter": "Sljedeće poglavlje", "ButtonNextItemInQueue": "Sljedeća stavka u redu", - "ButtonOk": "OK", + "ButtonOk": "U redu", "ButtonOpenFeed": "Otvori izvor", "ButtonOpenManager": "Otvori Upravitelja", "ButtonPause": "Pauziraj", From e6244b8676bce42e98464bbb2285f50079d65ad1 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 23 Jan 2025 00:26:39 +0000 Subject: [PATCH 13/66] Translated using Weblate (Spanish) Currently translated at 99.9% (1081 of 1082 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/es/ --- client/strings/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/strings/es.json b/client/strings/es.json index dae735d04..8868ea6ef 100644 --- a/client/strings/es.json +++ b/client/strings/es.json @@ -51,7 +51,7 @@ "ButtonNext": "Siguiente", "ButtonNextChapter": "Siguiente Capítulo", "ButtonNextItemInQueue": "El siguiente elemento en cola", - "ButtonOk": "De acuerdo", + "ButtonOk": "Bueno", "ButtonOpenFeed": "Abrir fuente", "ButtonOpenManager": "Abrir Editor", "ButtonPause": "Pausar", From 36dd96fd87d6750713e2b726ee8fa7bdb6f5a3e4 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 23 Jan 2025 00:38:01 +0000 Subject: [PATCH 14/66] Translated using Weblate (Spanish) Currently translated at 100.0% (1082 of 1082 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/es/ --- client/strings/es.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/strings/es.json b/client/strings/es.json index 8868ea6ef..f26457975 100644 --- a/client/strings/es.json +++ b/client/strings/es.json @@ -1,5 +1,5 @@ { - "ButtonAdd": "Agregaro", + "ButtonAdd": "Agregar", "ButtonAddChapters": "Agregar", "ButtonAddDevice": "Agregar Dispositivo", "ButtonAddLibrary": "Crear Biblioteca", @@ -837,6 +837,7 @@ "MessageResetChaptersConfirm": "¿Está seguro de que desea deshacer los cambios y revertir los capítulos a su estado original?", "MessageRestoreBackupConfirm": "¿Está seguro de que desea para restaurar del respaldo creado en", "MessageRestoreBackupWarning": "Restaurar sobrescribirá toda la base de datos localizada en /config y las imágenes de portadas en /metadata/items y /metadata/authors.

El respaldo no modifica ningún archivo en las carpetas de su biblioteca. Si ha habilitado la opción del servidor para almacenar portadas y metadata en las carpetas de su biblioteca, esos archivos no se respaldan o sobrescriben.

Todos los clientes que usen su servidor se actualizarán automáticamente.", + "MessageScheduleLibraryScanNote": "Para la mayoría de los usuarios, se recomienda dejar esta función desactivada y mantener activada la configuración del observador de carpetas. El observador de carpetas detectará automáticamente los cambios en las carpetas de la biblioteca. El observador de carpetas no funciona para todos los sistemas de archivos (como NFS), por lo que se pueden utilizar exploraciones programadas de la biblioteca en su lugar.", "MessageSearchResultsFor": "Resultados de la búsqueda de", "MessageSelected": "{0} seleccionado(s)", "MessageServerCouldNotBeReached": "No se pudo establecer la conexión con el servidor", From 7dff571fd50c07451d094c62840e235d81ac8bfc Mon Sep 17 00:00:00 2001 From: Jan-Eric Myhrgren Date: Thu, 23 Jan 2025 07:48:51 +0000 Subject: [PATCH 15/66] Translated using Weblate (Swedish) Currently translated at 83.4% (903 of 1082 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/sv/ --- client/strings/sv.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/strings/sv.json b/client/strings/sv.json index 970e7f281..43e220ea2 100644 --- a/client/strings/sv.json +++ b/client/strings/sv.json @@ -276,7 +276,7 @@ "LabelDirectory": "Katalog", "LabelDiscFromFilename": "Skiva från filnamn", "LabelDiscFromMetadata": "Skiva från metadata", - "LabelDiscover": "Upptäck", + "LabelDiscover": "Några förslag", "LabelDownload": "Ladda ner", "LabelDownloadNEpisodes": "Ladda ner {0} avsnitt", "LabelDownloadable": "Nedladdningsbar", @@ -453,7 +453,7 @@ "LabelRead": "Läst", "LabelReadAgain": "Läs igen", "LabelReadEbookWithoutProgress": "Läs e-bok utan att behålla framsteg", - "LabelRecentSeries": "Senaste serierna", + "LabelRecentSeries": "Nyaste serierna", "LabelRecentlyAdded": "Nyligen tillagda", "LabelRecommended": "Rekommenderad", "LabelRegion": "Region", From 32819860aa52907fc6fbfbe0f09f253406e1a483 Mon Sep 17 00:00:00 2001 From: Jan-Eric Myhrgren Date: Thu, 23 Jan 2025 17:54:35 +0000 Subject: [PATCH 16/66] Translated using Weblate (Swedish) Currently translated at 84.4% (914 of 1082 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/sv/ --- client/strings/sv.json | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/client/strings/sv.json b/client/strings/sv.json index 43e220ea2..a5fb27ad1 100644 --- a/client/strings/sv.json +++ b/client/strings/sv.json @@ -12,7 +12,7 @@ "ButtonBack": "Tillbaka", "ButtonBrowseForFolder": "Bläddra efter mapp", "ButtonCancel": "Avbryt", - "ButtonCancelEncode": "Avbryt kodning", + "ButtonCancelEncode": "Avbryt omkodning", "ButtonChangeRootPassword": "Ändra lösenordet för root", "ButtonCheckAndDownloadNewEpisodes": "Kontrollera och ladda ner nya avsnitt", "ButtonChooseAFolder": "Välj en mapp", @@ -76,7 +76,7 @@ "ButtonRemoveFromContinueListening": "Radera från 'Fortsätt läsa/lyssna'", "ButtonRemoveFromContinueReading": "Ta bort från Fortsätt läsa", "ButtonRemoveSeriesFromContinueSeries": "Radera från 'Fortsätt med serien'", - "ButtonReset": "Återställ", + "ButtonReset": "Tillbaka", "ButtonResetToDefault": "Återställ till standard", "ButtonRestore": "Återställ", "ButtonSave": "Spara", @@ -91,7 +91,7 @@ "ButtonShare": "Dela", "ButtonShiftTimes": "Förskjut tider", "ButtonShow": "Visa", - "ButtonStartM4BEncode": "Starta M4B-kodning", + "ButtonStartM4BEncode": "Starta M4B-omkodning", "ButtonStartMetadataEmbed": "Starta inbäddning av metadata", "ButtonStats": "Statistik", "ButtonSubmit": "Spara", @@ -150,7 +150,7 @@ "HeaderMapDetails": "Karta detaljer", "HeaderMatch": "Matcha", "HeaderMetadataOrderOfPrecedence": "Prioriteringsordning vid inläsning av metadata", - "HeaderMetadataToEmbed": "Metadata att bädda in", + "HeaderMetadataToEmbed": "Metadata som kommer att adderas", "HeaderNewAccount": "Nytt konto", "HeaderNewLibrary": "Nytt bibliotek", "HeaderNotifications": "Meddelanden", @@ -206,7 +206,7 @@ "LabelActivity": "Aktivitet", "LabelAddToCollection": "Lägg till i en samling", "LabelAddToCollectionBatch": "Lägg till {0} böcker i en Samling", - "LabelAddToPlaylist": "Lägg till i Spellista", + "LabelAddToPlaylist": "Lägg till i en spellista", "LabelAddToPlaylistBatch": "Lägg till {0} objekt i Spellistan", "LabelAddedAt": "Datum adderad", "LabelAddedDate": "Adderad {0}", @@ -218,6 +218,9 @@ "LabelAlreadyInYourLibrary": "Redan i din samling", "LabelApiToken": "API-token", "LabelAppend": "Lägg till", + "LabelAudioBitrate": "Bitrate för ljud (t.ex. 128k)", + "LabelAudioChannels": "Ljudkanaler (1 eller 2)", + "LabelAudioCodec": "Codec för ljud", "LabelAuthor": "Författare", "LabelAuthorFirstLast": "Författare (För-, Efternamn)", "LabelAuthorLastFirst": "Författare (Efter-, Förnamn)", @@ -243,7 +246,7 @@ "LabelChangePassword": "Ändra lösenord", "LabelChannels": "Kanaler", "LabelChapterCount": "{0} kapitel", - "LabelChapterTitle": "Kapitelrubrik", + "LabelChapterTitle": "Titel på kapitel", "LabelChapters": "Kapitel", "LabelChaptersFound": "hittade kapitel", "LabelClickForMoreInfo": "Klicka för mer information", @@ -295,7 +298,14 @@ "LabelEmailSettingsTestAddress": "E-postadress för test", "LabelEmbeddedCover": "Inbäddat bokomslag", "LabelEnable": "Aktivera", - "LabelEncodingBackupLocation": "En säkerhetskopia av dina orginalljudfiler kommer att lagras i:", + "LabelEncodingBackupLocation": "En säkerhetskopia av dina orginalljudfiler kommer att placeras i katalogen:", + "LabelEncodingClearItemCache": "Kom ihåg att regelbundet radera cachen för föremål. Du hittar funktionen längst ner på sidan 'Inställningar'.", + "LabelEncodingFinishedM4B": "Den färdiga M4B-filen kommer att placeras i katalogen:", + "LabelEncodingInfoEmbedded": "Metadata kommer att adderas i ljudfilerna i mappen med ljudboken.", + "LabelEncodingStartedNavigation": "När du startad omkodningen kan du lämna denna sida. Omkodningen fortsätter i bakgrunden.", + "LabelEncodingTimeWarning": "Avkodningen kan ta upp till 30 minuter eller ännu längre för riktigt stora filer.", + "LabelEncodingWarningAdvancedSettings": "VARNING: Ändra inte inställningarna om du inte är bekant med inställningarna för omkodning med 'ffmpeg'.", + "LabelEncodingWatcherDisabled": "Om funktionen 'Watcher' är avstängd behöver du göra en ny skanning av ljudboken efteråt.", "LabelEnd": "Slut", "LabelEndOfChapter": "Slut av kapitel", "LabelEpisode": "Avsnitt", @@ -375,8 +385,8 @@ "LabelLowestPriority": "Lägst prioritet", "LabelMediaPlayer": "Mediaspelare", "LabelMediaType": "Mediatyp", - "LabelMetaTag": "Metamärke", - "LabelMetaTags": "Metamärken", + "LabelMetaTag": "Metadata", + "LabelMetaTags": "Metadata", "LabelMetadataOrderOfPrecedenceDescription": "Källor för metadata med högre prioritet har företräde före källor med lägre prioritet", "LabelMetadataProvider": "Källa för metadata", "LabelMinute": "Minut", @@ -391,7 +401,7 @@ "LabelNarrators": "Uppläsare", "LabelNew": "Nytt", "LabelNewPassword": "Nytt lösenord", - "LabelNewestAuthors": "Senast adderade författare", + "LabelNewestAuthors": "Senaste författarna", "LabelNewestEpisodes": "Senast tillagda avsnitt", "LabelNextBackupDate": "Nästa datum för säkerhetskopiering", "LabelNextScheduledRun": "Nästa schemalagda körning", @@ -528,10 +538,10 @@ "LabelShowSeconds": "Visa sekunder", "LabelShowSubtitles": "Visa underrubriker", "LabelSize": "Storlek", - "LabelSleepTimer": "Timer för sova", + "LabelSleepTimer": "Sovtimer", "LabelSortAscending": "Stigande", "LabelSortDescending": "Fallande", - "LabelStart": "Starta", + "LabelStart": "Start", "LabelStartTime": "Starttid", "LabelStarted": "Startad", "LabelStartedAt": "Startades", @@ -573,9 +583,9 @@ "LabelTimeRemaining": "{0} återstår", "LabelTimeToShift": "Tid att skifta i sekunder", "LabelTitle": "Titel", - "LabelToolsEmbedMetadata": "Bädda in metadata", + "LabelToolsEmbedMetadata": "Infoga metadata", "LabelToolsEmbedMetadataDescription": "Bädda in metadata i ljudfiler, inklusive omslagsbild och kapitel.", - "LabelToolsMakeM4b": "Skapa M4B ljudbok", + "LabelToolsMakeM4b": "Skapa ljudboksfil i M4B-format", "LabelToolsMakeM4bDescription": "Skapa en ljudboksfil i M4B-format med inbäddad metadata, omslagsbild och kapitel.", "LabelToolsSplitM4b": "Dela upp M4B-fil i MP3-filer", "LabelToolsSplitM4bDescription": "Skapa MP3-filer från en M4B-fil uppdelad i kapitel med inbäddad metadata, omslagsbild och kapitel.", @@ -756,6 +766,7 @@ "MessageSetChaptersFromTracksDescription": "Ställ in kapitel med varje ljudfil som ett kapitel och kapitelrubrik som ljudfilens namn", "MessageStartPlaybackAtTime": "Starta uppspelning av \"{0}\" vid tidpunkt {1}?", "MessageTaskCanceledByUser": "Uppgiften avslutades av användaren", + "MessageTaskEncodingM4bDescription": "Omkodning av ljudbok \"{0}\" till en M4B-fil", "MessageTaskFailed": "Misslyckades", "MessageTaskFailedToCreateCacheDirectory": "Misslyckades med att skapa bibliotek för cachen", "MessageTaskMatchingBooksInLibrary": "Matchar böcker i biblioteket \"{0}\"", From 358c3a15b5ef116212b088b29644f5bd876a94fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=93=D0=BE=D1=80?= =?UTF-8?q?=D0=BF=D0=B8=D0=BD=D1=96=D1=87?= Date: Fri, 24 Jan 2025 09:40:28 +0000 Subject: [PATCH 17/66] Translated using Weblate (Ukrainian) Currently translated at 100.0% (1086 of 1086 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/uk/ --- client/strings/uk.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/strings/uk.json b/client/strings/uk.json index c88c34056..ebdc37901 100644 --- a/client/strings/uk.json +++ b/client/strings/uk.json @@ -10,6 +10,8 @@ "ButtonApplyChapters": "Зберегти глави", "ButtonAuthors": "Автори", "ButtonBack": "Назад", + "ButtonBatchEditPopulateFromExisting": "Заповнити з наявних", + "ButtonBatchEditPopulateMapDetails": "Заповнити деталі карти", "ButtonBrowseForFolder": "Огляд тек", "ButtonCancel": "Скасувати", "ButtonCancelEncode": "Скасувати кодування", @@ -704,6 +706,8 @@ "MessageBackupsLocationEditNote": "Примітка: оновлення розташування резервної копії не переносить та не змінює існуючих копій", "MessageBackupsLocationNoEditNote": "Примітка: розташування резервної копії встановлюється за допомогою змінної середовища та не може бути змінене тут.", "MessageBackupsLocationPathEmpty": "Шлях розташування резервної копії не може бути порожнім", + "MessageBatchEditPopulateMapDetailsAllHelp": "Заповнити увімкнені поля даними з усіх елементів. Поля з кількома значеннями буде об’єднано", + "MessageBatchEditPopulateMapDetailsItemHelp": "Заповніть увімкнені поля деталей карти даними з цього елемента", "MessageBatchQuickMatchDescription": "Швидкий пошук спробує знайти відсутні обкладинки та метадані обраних елементів. Увімкніть налаштування нижче, аби дозволити заміну наявних обкладинок та/або метаданих під час швидкого пошуку.", "MessageBookshelfNoCollections": "Ви не створили жодної добірки", "MessageBookshelfNoRSSFeeds": "Немає відкритих RSS-каналів", From c6f724edfffdf58e4df5dab531c8362630bda87d Mon Sep 17 00:00:00 2001 From: thehijacker Date: Fri, 24 Jan 2025 10:52:11 +0000 Subject: [PATCH 18/66] Translated using Weblate (Slovenian) Currently translated at 100.0% (1086 of 1086 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/sl/ --- client/strings/sl.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/strings/sl.json b/client/strings/sl.json index 73c2504be..47cbb49ec 100644 --- a/client/strings/sl.json +++ b/client/strings/sl.json @@ -10,6 +10,8 @@ "ButtonApplyChapters": "Uveljavi poglavja", "ButtonAuthors": "Avtorji", "ButtonBack": "Nazaj", + "ButtonBatchEditPopulateFromExisting": "Napolni iz obstoječega", + "ButtonBatchEditPopulateMapDetails": "Izpolnite podrobnosti zemljevida", "ButtonBrowseForFolder": "Prebrskaj pot do mape", "ButtonCancel": "Prekliči", "ButtonCancelEncode": "Prekliči prekodiranje", @@ -704,6 +706,8 @@ "MessageBackupsLocationEditNote": "Opomba: Posodabljanje lokacije varnostne kopije ne bo premaknilo ali spremenilo obstoječih varnostnih kopij", "MessageBackupsLocationNoEditNote": "Opomba: Lokacija varnostne kopije je nastavljena s spremenljivko okolja in je tu ni mogoče spremeniti.", "MessageBackupsLocationPathEmpty": "Pot do lokacije varnostne kopije ne sme biti prazna", + "MessageBatchEditPopulateMapDetailsAllHelp": "Napolni omogočena polja s podatki iz vseh elementov. Polja z več vrednostmi bodo združena", + "MessageBatchEditPopulateMapDetailsItemHelp": "Napolni omogočena polja s podrobnostmi zemljevida s podatki iz tega elementa", "MessageBatchQuickMatchDescription": "Hitro ujemanje bo poskušal dodati manjkajoče naslovnice in metapodatke za izbrane elemente. Omogočite spodnje možnosti, da omogočite hitremu ujemanju, da prepiše obstoječe naslovnice in/ali metapodatke.", "MessageBookshelfNoCollections": "Ustvaril nisi še nobene zbirke", "MessageBookshelfNoRSSFeeds": "Noben vir RSS ni odprt", From 9e3010681e2baa6511a9d09b45be25ff7440aa43 Mon Sep 17 00:00:00 2001 From: advplyr Date: Fri, 24 Jan 2025 17:52:51 +0100 Subject: [PATCH 19/66] Added translation using Weblate (Japanese) --- client/strings/ja.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 client/strings/ja.json diff --git a/client/strings/ja.json b/client/strings/ja.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/client/strings/ja.json @@ -0,0 +1 @@ +{} From d4ba8b9d9f27efd98645a8552472a0d499aae760 Mon Sep 17 00:00:00 2001 From: advplyr Date: Fri, 24 Jan 2025 17:24:37 -0600 Subject: [PATCH 20/66] Fix server crash on failed to extract epub image #3889 --- server/utils/parsers/parseEpubMetadata.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/utils/parsers/parseEpubMetadata.js b/server/utils/parsers/parseEpubMetadata.js index b0b3724b7..25d8821d4 100644 --- a/server/utils/parsers/parseEpubMetadata.js +++ b/server/utils/parsers/parseEpubMetadata.js @@ -56,7 +56,9 @@ async function extractCoverImage(epubPath, epubImageFilepath, outputCoverPath) { return false }) - await zip.close() + await zip.close().catch((error) => { + Logger.error(`[parseEpubMetadata] Failed to close zip`, error) + }) return success } From 3eefe937d947d74c55bfa209c77395a400422792 Mon Sep 17 00:00:00 2001 From: Greg Lorenzen Date: Sat, 25 Jan 2025 01:57:41 +0000 Subject: [PATCH 21/66] Add user setting value for playbackRateIncrementDecrement --- client/store/user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/client/store/user.js b/client/store/user.js index 0e4cc0ccf..d5aad19b6 100644 --- a/client/store/user.js +++ b/client/store/user.js @@ -5,6 +5,7 @@ export const state = () => ({ orderDesc: false, filterBy: 'all', playbackRate: 1, + playbackRateIncrementDecrement: 0.1, bookshelfCoverSize: 120, collapseSeries: false, collapseBookSeries: false, From 7c4bcfb4f965f88e862c7c8d0da15c1f3b44f439 Mon Sep 17 00:00:00 2001 From: Greg Lorenzen Date: Sat, 25 Jan 2025 01:58:13 +0000 Subject: [PATCH 22/66] Add dropdown to player settings modal to set the playbackRateIncrementDecrement amount --- client/components/modals/PlayerSettingsModal.vue | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/client/components/modals/PlayerSettingsModal.vue b/client/components/modals/PlayerSettingsModal.vue index 88cb91e18..dfac28cfd 100644 --- a/client/components/modals/PlayerSettingsModal.vue +++ b/client/components/modals/PlayerSettingsModal.vue @@ -11,9 +11,12 @@
-
+
+
+ +
@@ -35,7 +38,9 @@ export default { { text: this.$getString('LabelTimeDurationXMinutes', ['5']), value: 300 } ], jumpForwardAmount: 10, - jumpBackwardAmount: 10 + jumpBackwardAmount: 10, + playbackRateIncrementDecrementValues: [0.1, 0.05], + playbackRateIncrementDecrement: 0.1 } }, computed: { @@ -60,10 +65,15 @@ export default { this.jumpBackwardAmount = val this.$store.dispatch('user/updateUserSettings', { jumpBackwardAmount: val }) }, + setPlaybackRateIncrementDecrementAmount(val) { + this.playbackRateIncrementDecrement = val + this.$store.dispatch('user/updateUserSettings', { playbackRateIncrementDecrement: val }) + }, settingsUpdated() { this.useChapterTrack = this.$store.getters['user/getUserSetting']('useChapterTrack') this.jumpForwardAmount = this.$store.getters['user/getUserSetting']('jumpForwardAmount') this.jumpBackwardAmount = this.$store.getters['user/getUserSetting']('jumpBackwardAmount') + this.playbackRateIncrementDecrement = this.$store.getters['user/getUserSetting']('playbackRateIncrementDecrement') } }, mounted() { From 1ea1e60d4bcb088279eb5a2e762d1ca804605c13 Mon Sep 17 00:00:00 2001 From: Greg Lorenzen Date: Sat, 25 Jan 2025 01:58:48 +0000 Subject: [PATCH 23/66] Add string for LabelPlaybackRateIncrementDecrement --- client/strings/en-us.json | 1 + 1 file changed, 1 insertion(+) diff --git a/client/strings/en-us.json b/client/strings/en-us.json index b4ac1389c..01d94ac68 100644 --- a/client/strings/en-us.json +++ b/client/strings/en-us.json @@ -485,6 +485,7 @@ "LabelPermissionsUpload": "Can Upload", "LabelPersonalYearReview": "Your Year in Review ({0})", "LabelPhotoPathURL": "Photo Path/URL", + "LabelPlaybackRateIncrementDecrement": "Playback Rate Increment/Decrement Amount", "LabelPlayMethod": "Play Method", "LabelPlayerChapterNumberMarker": "{0} of {1}", "LabelPlaylists": "Playlists", From f258782e2e00fc8c68a901bb93d0ffab37f3c7eb Mon Sep 17 00:00:00 2001 From: Greg Lorenzen Date: Sat, 25 Jan 2025 01:59:24 +0000 Subject: [PATCH 24/66] Handle playback rate increment and decrmenet value in UI --- .../controls/PlaybackSpeedControl.vue | 20 +++++++++++-------- client/components/player/PlayerUi.vue | 9 ++++++--- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/client/components/controls/PlaybackSpeedControl.vue b/client/components/controls/PlaybackSpeedControl.vue index 9e9f0d54c..2c9105477 100644 --- a/client/components/controls/PlaybackSpeedControl.vue +++ b/client/components/controls/PlaybackSpeedControl.vue @@ -33,6 +33,10 @@ export default { value: { type: [String, Number], default: 1 + }, + playbackRateIncrementDecrement: { + type: Number, + default: 0.1 } }, data() { @@ -58,10 +62,10 @@ export default { return [0.5, 1, 1.2, 1.5, 2] }, canIncrement() { - return this.playbackRate + 0.1 <= this.MAX_SPEED + return this.playbackRate + this.playbackRateIncrementDecrement <= this.MAX_SPEED }, canDecrement() { - return this.playbackRate - 0.1 >= this.MIN_SPEED + return this.playbackRate - this.playbackRateIncrementDecrement >= this.MIN_SPEED } }, methods: { @@ -73,14 +77,14 @@ export default { this.$nextTick(() => this.setShowMenu(false)) }, increment() { - if (this.playbackRate + 0.1 > this.MAX_SPEED) return - var newPlaybackRate = this.playbackRate + 0.1 - this.playbackRate = Number(newPlaybackRate.toFixed(1)) + if (this.playbackRate + this.playbackRateIncrementDecrement > this.MAX_SPEED) return + var newPlaybackRate = this.playbackRate + this.playbackRateIncrementDecrement + this.playbackRate = Number(newPlaybackRate.toFixed(2)) }, decrement() { - if (this.playbackRate - 0.1 < this.MIN_SPEED) return - var newPlaybackRate = this.playbackRate - 0.1 - this.playbackRate = Number(newPlaybackRate.toFixed(1)) + if (this.playbackRate - this.playbackRateIncrementDecrement < this.MIN_SPEED) return + var newPlaybackRate = this.playbackRate - this.playbackRateIncrementDecrement + this.playbackRate = Number(newPlaybackRate.toFixed(2)) }, updateMenuPositions() { if (!this.$refs.wrapper) return diff --git a/client/components/player/PlayerUi.vue b/client/components/player/PlayerUi.vue index 31267c7a0..f4ad59d15 100644 --- a/client/components/player/PlayerUi.vue +++ b/client/components/player/PlayerUi.vue @@ -2,7 +2,7 @@
- +
-

+

+
From 9b4732c207c092711137afb13477181d9cac7b1a Mon Sep 17 00:00:00 2001 From: mikiher Date: Sun, 26 Jan 2025 12:21:54 +0200 Subject: [PATCH 27/66] Add bookSeries id attribute to findAllExpandedWhere --- server/models/LibraryItem.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/models/LibraryItem.js b/server/models/LibraryItem.js index d581c3097..3ed4e31e2 100644 --- a/server/models/LibraryItem.js +++ b/server/models/LibraryItem.js @@ -155,7 +155,7 @@ class LibraryItem extends Model { { model: this.sequelize.models.series, through: { - attributes: ['sequence'] + attributes: ['id', 'sequence'] } } ] From 23067e1818751dcc8aed9087745db266e846b0be Mon Sep 17 00:00:00 2001 From: mikiher Date: Sun, 26 Jan 2025 13:44:57 +0200 Subject: [PATCH 28/66] Allows setting of some pragma values through environment variables --- server/Database.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/server/Database.js b/server/Database.js index 82a8fbd11..c9e2d52ac 100644 --- a/server/Database.js +++ b/server/Database.js @@ -226,6 +226,28 @@ class Database { try { await this.sequelize.authenticate() + + // Set SQLite pragmas from environment variables + const allowedPragmas = [ + { name: 'mmap_size', env: 'SQLITE_MMAP_SIZE' }, + { name: 'cache_size', env: 'SQLITE_CACHE_SIZE' }, + { name: 'temp_store', env: 'SQLITE_TEMP_STORE' } + ] + + for (const pragma of allowedPragmas) { + const value = process.env[pragma.env] + if (value !== undefined) { + try { + Logger.info(`[Database] Running "PRAGMA ${pragma.name} = ${value}"`) + await this.sequelize.query(`PRAGMA ${pragma.name} = ${value}`) + const [result] = await this.sequelize.query(`PRAGMA ${pragma.name}`) + Logger.debug(`[Database] "PRAGMA ${pragma.name}" query result:`, result) + } catch (error) { + Logger.error(`[Database] Failed to set SQLite pragma ${pragma.name}`, error) + } + } + } + if (process.env.NUSQLITE3_PATH) { await this.loadExtension(process.env.NUSQLITE3_PATH) Logger.info(`[Database] Db supports unaccent and unicode foldings`) From 558173e086298d63dd99e39cfeb8a57109f14c52 Mon Sep 17 00:00:00 2001 From: advplyr Date: Sun, 26 Jan 2025 10:51:18 -0600 Subject: [PATCH 29/66] Update custom metadata provider results to sanitize html descriptions #3880 --- server/libs/sanitizeHtml/index.js | 112 ---------------------- server/providers/CustomProviderAdapter.js | 3 +- server/utils/htmlSanitizer.js | 10 ++ 3 files changed, 12 insertions(+), 113 deletions(-) diff --git a/server/libs/sanitizeHtml/index.js b/server/libs/sanitizeHtml/index.js index 3fee985e0..701a36f2f 100644 --- a/server/libs/sanitizeHtml/index.js +++ b/server/libs/sanitizeHtml/index.js @@ -7,12 +7,6 @@ */ const htmlparser = require('htmlparser2'); -// const escapeStringRegexp = require('escape-string-regexp'); -// const { isPlainObject } = require('is-plain-object'); -// const deepmerge = require('deepmerge'); -// const parseSrcset = require('parse-srcset'); -// const { parse: postcssParse } = require('postcss'); -// Tags that can conceivably represent stand-alone media. // ABS UPDATE: Packages not necessary // SOURCE: https://github.com/sindresorhus/escape-string-regexp/blob/main/index.js @@ -76,17 +70,6 @@ function has(obj, key) { return ({}).hasOwnProperty.call(obj, key); } -// Returns those elements of `a` for which `cb(a)` returns truthy -function filter(a, cb) { - const n = []; - each(a, function (v) { - if (cb(v)) { - n.push(v); - } - }); - return n; -} - function isEmptyObject(obj) { for (const key in obj) { if (has(obj, key)) { @@ -96,21 +79,6 @@ function isEmptyObject(obj) { return true; } -function stringifySrcset(parsedSrcset) { - return parsedSrcset.map(function (part) { - if (!part.url) { - throw new Error('URL missing'); - } - - return ( - part.url + - (part.w ? ` ${part.w}w` : '') + - (part.h ? ` ${part.h}h` : '') + - (part.d ? ` ${part.d}x` : '') - ); - }).join(', '); -} - module.exports = sanitizeHtml; // A valid attribute name. @@ -714,86 +682,6 @@ function sanitizeHtml(html, options, _recursing) { return !options.allowedSchemes || options.allowedSchemes.indexOf(scheme) === -1; } - /** - * Filters user input css properties by allowlisted regex attributes. - * Modifies the abstractSyntaxTree object. - * - * @param {object} abstractSyntaxTree - Object representation of CSS attributes. - * @property {array[Declaration]} abstractSyntaxTree.nodes[0] - Each object cointains prop and value key, i.e { prop: 'color', value: 'red' }. - * @param {object} allowedStyles - Keys are properties (i.e color), value is list of permitted regex rules (i.e /green/i). - * @return {object} - The modified tree. - */ - // function filterCss(abstractSyntaxTree, allowedStyles) { - // if (!allowedStyles) { - // return abstractSyntaxTree; - // } - - // const astRules = abstractSyntaxTree.nodes[0]; - // let selectedRule; - - // // Merge global and tag-specific styles into new AST. - // if (allowedStyles[astRules.selector] && allowedStyles['*']) { - // selectedRule = deepmerge( - // allowedStyles[astRules.selector], - // allowedStyles['*'] - // ); - // } else { - // selectedRule = allowedStyles[astRules.selector] || allowedStyles['*']; - // } - - // if (selectedRule) { - // abstractSyntaxTree.nodes[0].nodes = astRules.nodes.reduce(filterDeclarations(selectedRule), []); - // } - - // return abstractSyntaxTree; - // } - - /** - * Extracts the style attributes from an AbstractSyntaxTree and formats those - * values in the inline style attribute format. - * - * @param {AbstractSyntaxTree} filteredAST - * @return {string} - Example: "color:yellow;text-align:center !important;font-family:helvetica;" - */ - function stringifyStyleAttributes(filteredAST) { - return filteredAST.nodes[0].nodes - .reduce(function (extractedAttributes, attrObject) { - extractedAttributes.push( - `${attrObject.prop}:${attrObject.value}${attrObject.important ? ' !important' : ''}` - ); - return extractedAttributes; - }, []) - .join(';'); - } - - /** - * Filters the existing attributes for the given property. Discards any attributes - * which don't match the allowlist. - * - * @param {object} selectedRule - Example: { color: red, font-family: helvetica } - * @param {array} allowedDeclarationsList - List of declarations which pass the allowlist. - * @param {object} attributeObject - Object representing the current css property. - * @property {string} attributeObject.type - Typically 'declaration'. - * @property {string} attributeObject.prop - The CSS property, i.e 'color'. - * @property {string} attributeObject.value - The corresponding value to the css property, i.e 'red'. - * @return {function} - When used in Array.reduce, will return an array of Declaration objects - */ - function filterDeclarations(selectedRule) { - return function (allowedDeclarationsList, attributeObject) { - // If this property is allowlisted... - if (has(selectedRule, attributeObject.prop)) { - const matchesRegex = selectedRule[attributeObject.prop].some(function (regularExpression) { - return regularExpression.test(attributeObject.value); - }); - - if (matchesRegex) { - allowedDeclarationsList.push(attributeObject); - } - } - return allowedDeclarationsList; - }; - } - function filterClasses(classes, allowed, allowedGlobs) { if (!allowed) { // The class attribute is allowed without filtering on this tag diff --git a/server/providers/CustomProviderAdapter.js b/server/providers/CustomProviderAdapter.js index fe6537fd0..911a09e95 100644 --- a/server/providers/CustomProviderAdapter.js +++ b/server/providers/CustomProviderAdapter.js @@ -1,6 +1,7 @@ const axios = require('axios').default const Database = require('../Database') const Logger = require('../Logger') +const htmlSanitizer = require('../utils/htmlSanitizer') class CustomProviderAdapter { #responseTimeout = 30000 @@ -74,7 +75,7 @@ class CustomProviderAdapter { narrator, publisher, publishedYear, - description, + description: htmlSanitizer.sanitize(description), cover, isbn, asin, diff --git a/server/utils/htmlSanitizer.js b/server/utils/htmlSanitizer.js index cab92392b..4ed30e727 100644 --- a/server/utils/htmlSanitizer.js +++ b/server/utils/htmlSanitizer.js @@ -1,7 +1,17 @@ const sanitizeHtml = require('../libs/sanitizeHtml') const { entities } = require('./htmlEntities') +/** + * + * @param {string} html + * @returns {string} + * @throws {Error} if input is not a string + */ function sanitize(html) { + if (typeof html !== 'string') { + throw new Error('sanitizeHtml: input must be a string') + } + const sanitizerOptions = { allowedTags: ['p', 'ol', 'ul', 'li', 'a', 'strong', 'em', 'del', 'br', 'b', 'i'], disallowedTagsMode: 'discard', From e701a0a32e6d2ab1d51fbedd73c4bedcd12e90bf Mon Sep 17 00:00:00 2001 From: advplyr Date: Mon, 27 Jan 2025 16:46:32 -0600 Subject: [PATCH 30/66] Update playback rate display value number of decimals --- client/components/controls/PlaybackSpeedControl.vue | 11 +++++++++-- client/strings/en-us.json | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/client/components/controls/PlaybackSpeedControl.vue b/client/components/controls/PlaybackSpeedControl.vue index 2c9105477..98f40866a 100644 --- a/client/components/controls/PlaybackSpeedControl.vue +++ b/client/components/controls/PlaybackSpeedControl.vue @@ -1,7 +1,7 @@
-
-

{{ $strings.MessageNoCollections }}

+
+
+

{{ $strings.MessageNoUserPlaylists }}

+

+ {{ $strings.MessageBookshelfNoCollectionsHelp }} + + + help_outline + + +

+
+
diff --git a/client/components/modals/playlists/AddCreateModal.vue b/client/components/modals/playlists/AddCreateModal.vue index d1f910b85..51f7e475c 100644 --- a/client/components/modals/playlists/AddCreateModal.vue +++ b/client/components/modals/playlists/AddCreateModal.vue @@ -19,8 +19,18 @@
-
-

{{ $strings.MessageNoUserPlaylists }}

+
+
+

{{ $strings.MessageNoUserPlaylists }}

+

+ {{ $strings.MessageNoUserPlaylistsHelp }} + + + help_outline + + +

+
From c3aad9486c6036c6fcc30102a2e988a8ae198fbd Mon Sep 17 00:00:00 2001 From: advplyr Date: Thu, 30 Jan 2025 17:27:32 -0600 Subject: [PATCH 39/66] Fix Logger.fatal to be a promise to ensure crash_logs.txt write --- server/Logger.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/Logger.js b/server/Logger.js index 5d1a7fa59..e4487f0ac 100644 --- a/server/Logger.js +++ b/server/Logger.js @@ -117,7 +117,7 @@ class Logger { if (level < LogLevel.FATAL && level < this.logLevel) return const consoleMethod = Logger.ConsoleMethods[levelName] console[consoleMethod](`[${this.timestamp}] ${levelName}:`, ...args) - this.#logToFileAndListeners(level, levelName, args, source) + return this.#logToFileAndListeners(level, levelName, args, source) } trace(...args) { @@ -141,7 +141,7 @@ class Logger { } fatal(...args) { - this.#log('FATAL', this.source, ...args) + return this.#log('FATAL', this.source, ...args) } note(...args) { From 2e13c5bd5021adf37ba63e3c16e2e5647996240d Mon Sep 17 00:00:00 2001 From: advplyr Date: Thu, 30 Jan 2025 17:47:41 -0600 Subject: [PATCH 40/66] Fix no collections message, ui updates --- .../components/modals/collections/AddCreateModal.vue | 12 ++++++------ .../components/modals/playlists/AddCreateModal.vue | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/client/components/modals/collections/AddCreateModal.vue b/client/components/modals/collections/AddCreateModal.vue index ee4651874..c4878adc8 100644 --- a/client/components/modals/collections/AddCreateModal.vue +++ b/client/components/modals/collections/AddCreateModal.vue @@ -19,20 +19,20 @@
-
+
-

{{ $strings.MessageNoUserPlaylists }}

-

- {{ $strings.MessageBookshelfNoCollectionsHelp }} +

{{ $strings.MessageNoCollections }}

+
+

{{ $strings.MessageBookshelfNoCollectionsHelp }}

help_outline -

+
-
+
diff --git a/client/components/modals/playlists/AddCreateModal.vue b/client/components/modals/playlists/AddCreateModal.vue index 51f7e475c..4a7daad94 100644 --- a/client/components/modals/playlists/AddCreateModal.vue +++ b/client/components/modals/playlists/AddCreateModal.vue @@ -19,17 +19,17 @@
-
+
-

{{ $strings.MessageNoUserPlaylists }}

-

- {{ $strings.MessageNoUserPlaylistsHelp }} +

{{ $strings.MessageNoUserPlaylists }}

+
+

{{ $strings.MessageNoUserPlaylistsHelp }}

help_outline -

+
From 4a76ba0226a37fe57531740acf2414c2d74fbbb9 Mon Sep 17 00:00:00 2001 From: advplyr Date: Fri, 31 Jan 2025 17:11:57 -0600 Subject: [PATCH 41/66] Remove copy of series numbers on book cards --- client/components/cards/LazyBookCard.vue | 7 ------- 1 file changed, 7 deletions(-) diff --git a/client/components/cards/LazyBookCard.vue b/client/components/cards/LazyBookCard.vue index 544b7fec2..91e7d9c83 100644 --- a/client/components/cards/LazyBookCard.vue +++ b/client/components/cards/LazyBookCard.vue @@ -31,13 +31,6 @@
-
-

#{{ seriesSequenceList }}

-
-
-

{{ booksInSeries }}

-
-
From a58d486c444eebc61983bbe089acddba7ea4553d Mon Sep 17 00:00:00 2001 From: advplyr Date: Fri, 31 Jan 2025 17:18:23 -0600 Subject: [PATCH 42/66] Fix:Collapsed subseries showing parent series name on hover #3713 --- client/components/cards/LazyBookCard.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/client/components/cards/LazyBookCard.vue b/client/components/cards/LazyBookCard.vue index 91e7d9c83..d506a1b7d 100644 --- a/client/components/cards/LazyBookCard.vue +++ b/client/components/cards/LazyBookCard.vue @@ -237,6 +237,7 @@ export default { return this.mediaMetadata.series }, seriesName() { + if (this.collapsedSeries?.name) return this.collapsedSeries.name return this.series?.name || null }, seriesSequence() { From aebb3ff4137793ecb1ebaa9c9c6e667a35ba2edd Mon Sep 17 00:00:00 2001 From: advplyr Date: Sat, 1 Feb 2025 16:47:36 -0600 Subject: [PATCH 43/66] Fix API including basepath in tracks contentUrl --- client/pages/audiobook/_id/chapters.vue | 5 +---- client/players/AudioTrack.js | 13 ++++++++++--- client/players/PlayerHandler.js | 2 +- server/models/Book.js | 2 +- server/models/PodcastEpisode.js | 2 +- server/objects/files/AudioTrack.js | 4 ++-- 6 files changed, 16 insertions(+), 12 deletions(-) diff --git a/client/pages/audiobook/_id/chapters.vue b/client/pages/audiobook/_id/chapters.vue index d7a8f9e18..9fe5773c9 100644 --- a/client/pages/audiobook/_id/chapters.vue +++ b/client/pages/audiobook/_id/chapters.vue @@ -414,11 +414,8 @@ export default { const audioEl = this.audioEl || document.createElement('audio') var src = audioTrack.contentUrl + `?token=${this.userToken}` - if (this.$isDev) { - src = `${process.env.serverUrl}${src}` - } - audioEl.src = src + audioEl.src = `${process.env.serverUrl}${src}` audioEl.id = 'chapter-audio' document.body.appendChild(audioEl) diff --git a/client/players/AudioTrack.js b/client/players/AudioTrack.js index 9627d3cda..05f11ad95 100644 --- a/client/players/AudioTrack.js +++ b/client/players/AudioTrack.js @@ -1,5 +1,5 @@ export default class AudioTrack { - constructor(track, userToken) { + constructor(track, userToken, routerBasePath) { this.index = track.index || 0 this.startOffset = track.startOffset || 0 // Total time of all previous tracks this.duration = track.duration || 0 @@ -9,20 +9,27 @@ export default class AudioTrack { this.metadata = track.metadata || {} this.userToken = userToken + this.routerBasePath = routerBasePath || '' } + /** + * Used for CastPlayer + */ get fullContentUrl() { if (!this.contentUrl || this.contentUrl.startsWith('http')) return this.contentUrl if (process.env.NODE_ENV === 'development') { return `${process.env.serverUrl}${this.contentUrl}?token=${this.userToken}` } - return `${window.location.origin}${this.contentUrl}?token=${this.userToken}` + return `${window.location.origin}${this.routerBasePath}${this.contentUrl}?token=${this.userToken}` } + /** + * Used for LocalPlayer + */ get relativeContentUrl() { if (!this.contentUrl || this.contentUrl.startsWith('http')) return this.contentUrl - return this.contentUrl + `?token=${this.userToken}` + return `${this.routerBasePath}${this.contentUrl}?token=${this.userToken}` } } diff --git a/client/players/PlayerHandler.js b/client/players/PlayerHandler.js index ba71fc6c7..6e4baa45e 100644 --- a/client/players/PlayerHandler.js +++ b/client/players/PlayerHandler.js @@ -226,7 +226,7 @@ export default class PlayerHandler { console.log('[PlayerHandler] Preparing Session', session) - var audioTracks = session.audioTracks.map((at) => new AudioTrack(at, this.userToken)) + var audioTracks = session.audioTracks.map((at) => new AudioTrack(at, this.userToken, this.ctx.$config.routerBasePath)) this.ctx.playerLoading = true this.isHlsTranscode = true diff --git a/server/models/Book.js b/server/models/Book.js index 527960eab..94e017f51 100644 --- a/server/models/Book.js +++ b/server/models/Book.js @@ -286,7 +286,7 @@ class Book extends Model { const track = structuredClone(af) track.title = af.metadata.filename track.startOffset = startOffset - track.contentUrl = `${global.RouterBasePath}/api/items/${libraryItemId}/file/${track.ino}` + track.contentUrl = `/api/items/${libraryItemId}/file/${track.ino}` startOffset += track.duration return track }) diff --git a/server/models/PodcastEpisode.js b/server/models/PodcastEpisode.js index 9eb146322..08baa4be3 100644 --- a/server/models/PodcastEpisode.js +++ b/server/models/PodcastEpisode.js @@ -169,7 +169,7 @@ class PodcastEpisode extends Model { const track = structuredClone(this.audioFile) track.startOffset = 0 track.title = this.audioFile.metadata.filename - track.contentUrl = `${global.RouterBasePath}/api/items/${libraryItemId}/file/${track.ino}` + track.contentUrl = `/api/items/${libraryItemId}/file/${track.ino}` return track } diff --git a/server/objects/files/AudioTrack.js b/server/objects/files/AudioTrack.js index b50d3e3f8..a27c2a016 100644 --- a/server/objects/files/AudioTrack.js +++ b/server/objects/files/AudioTrack.js @@ -29,7 +29,7 @@ class AudioTrack { this.duration = audioFile.duration this.title = audioFile.metadata.filename || '' - this.contentUrl = `${global.RouterBasePath}/api/items/${itemId}/file/${audioFile.ino}` + this.contentUrl = `/api/items/${itemId}/file/${audioFile.ino}` this.mimeType = audioFile.mimeType this.codec = audioFile.codec || null this.metadata = audioFile.metadata.clone() @@ -44,4 +44,4 @@ class AudioTrack { this.mimeType = 'application/vnd.apple.mpegurl' } } -module.exports = AudioTrack \ No newline at end of file +module.exports = AudioTrack From bcf8f6b732032a12a46ce94a9c0c111c7a83daf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=BB=D1=8C=D1=8F=20=D0=A7=D0=B5=D1=80=D0=B2=D0=BE?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D0=B9?= Date: Sat, 25 Jan 2025 11:45:09 +0000 Subject: [PATCH 44/66] Translated using Weblate (Russian) Currently translated at 100.0% (1086 of 1086 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/ru/ --- client/strings/ru.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/strings/ru.json b/client/strings/ru.json index 84a176f21..853052a46 100644 --- a/client/strings/ru.json +++ b/client/strings/ru.json @@ -10,6 +10,8 @@ "ButtonApplyChapters": "Применить главы", "ButtonAuthors": "Авторы", "ButtonBack": "Назад", + "ButtonBatchEditPopulateFromExisting": "Заполнить из существующих", + "ButtonBatchEditPopulateMapDetails": "Заполнить данные карты", "ButtonBrowseForFolder": "Выбрать папку", "ButtonCancel": "Отмена", "ButtonCancelEncode": "Отменить кодирование", @@ -704,6 +706,8 @@ "MessageBackupsLocationEditNote": "Примечание: Обновление местоположения резервной копии не приведет к перемещению или изменению существующих резервных копий", "MessageBackupsLocationNoEditNote": "Примечание: Местоположение резервного копирования задается с помощью переменной среды и не может быть изменено здесь.", "MessageBackupsLocationPathEmpty": "Путь к расположению резервной копии не может быть пустым", + "MessageBatchEditPopulateMapDetailsAllHelp": "Заполнить включенные поля данными из всех элементов. Поля с несколькими значениями будут объединены", + "MessageBatchEditPopulateMapDetailsItemHelp": "Заполнить активированные поля сведений о карте данными из этого элемента", "MessageBatchQuickMatchDescription": "Быстрый Поиск попытается добавить отсутствующие обложки и метаданные для выбранных элементов. Включите параметры ниже, чтобы разрешить Быстрому Поиску перезаписывать существующие обложки и/или метаданные.", "MessageBookshelfNoCollections": "Вы еще не создали ни одной коллекции", "MessageBookshelfNoRSSFeeds": "Нет открытых RSS-каналов", From d245c93da47e7140c3ab3a3c2432e92983f84bd2 Mon Sep 17 00:00:00 2001 From: Jan-Eric Myhrgren Date: Sat, 25 Jan 2025 11:12:32 +0000 Subject: [PATCH 45/66] Translated using Weblate (Swedish) Currently translated at 85.1% (925 of 1086 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/sv/ --- client/strings/sv.json | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/client/strings/sv.json b/client/strings/sv.json index a5fb27ad1..b4a129826 100644 --- a/client/strings/sv.json +++ b/client/strings/sv.json @@ -110,7 +110,7 @@ "HeaderAccount": "Konto", "HeaderAddCustomMetadataProvider": "Addera egen källa för metadata", "HeaderAdvanced": "Avancerad", - "HeaderAppriseNotificationSettings": "Apprise Meddelandeinställningar", + "HeaderAppriseNotificationSettings": "Inställningar av meddelanden med Apprise", "HeaderAudioTracks": "Ljudspår", "HeaderAudiobookTools": "Hantering av ljudboksfil", "HeaderAuthentication": "Autentisering", @@ -483,7 +483,7 @@ "LabelSelectEpisodesShowing": "Välj {0} avsnitt som visas", "LabelSelectUsers": "Välj användare", "LabelSendEbookToDevice": "Skicka e-bok till...", - "LabelSequence": "Sekvens", + "LabelSequence": "Sekvensnummer", "LabelSeries": "Serier", "LabelSeriesName": "Serienamn", "LabelSeriesProgress": "Status för serier", @@ -851,7 +851,9 @@ "ToastDeviceTestEmailFailed": "Misslyckades med att skicka ett testmail", "ToastDeviceTestEmailSuccess": "Ett testmail har skickats", "ToastEmailSettingsUpdateSuccess": "Inställningarna av e-post har uppdaterats", + "ToastEncodeCancelSucces": "Omkodningen avbruten", "ToastFailedToLoadData": "Misslyckades med att ladda data", + "ToastFailedToUpdate": "Misslyckades med att uppdatera", "ToastInvalidImageUrl": "Felaktig URL-adress till omslagsbilden", "ToastInvalidMaxEpisodesToDownload": "Ogiltigt maximalt antal avsnitt att ladda ner", "ToastInvalidUrl": "Felaktig URL-adress", @@ -878,7 +880,12 @@ "ToastNameRequired": "Ett namn måste anges", "ToastNewUserCreatedFailed": "Misslyckades med att skapa kontot \"{0}\"", "ToastNewUserCreatedSuccess": "Ett nytt konto har skapats", + "ToastNewUserLibraryError": "Minst ett bibliotek måste anges", + "ToastNewUserPasswordError": "Ett lösenord måste anges. Endast användaren 'root' kan vara utan lösenord.", + "ToastNewUserUsernameError": "Ange ett användarnamn", "ToastNoUpdatesNecessary": "Inga uppdateringar var nödvändiga", + "ToastNotificationCreateFailed": "Misslyckades med att skapa meddelandet", + "ToastNotificationDeleteFailed": "Misslyckades med att radera meddelandet", "ToastPlaylistCreateFailed": "Det gick inte att skapa spellistan", "ToastPlaylistCreateSuccess": "Spellistan skapad", "ToastPlaylistRemoveSuccess": "Spellistan har tagits bort", @@ -887,11 +894,14 @@ "ToastPodcastCreateSuccess": "Podcasten skapad framgångsrikt", "ToastProviderCreatedFailed": "Misslyckades med att addera en källa", "ToastProviderCreatedSuccess": "En ny källa har adderats", + "ToastProviderNameAndUrlRequired": "Ett namn och en URL-adress krävs", "ToastProviderRemoveSuccess": "Källan har tagits bort", "ToastRSSFeedCloseFailed": "Misslyckades med att stänga RSS-flödet", "ToastRSSFeedCloseSuccess": "RSS-flödet stängt", + "ToastRemoveFailed": "Misslyckades med att radera", "ToastRemoveItemFromCollectionFailed": "Misslyckades med att ta bort objektet från samlingen", "ToastRemoveItemFromCollectionSuccess": "Objektet borttaget från samlingen", + "ToastRenameFailed": "Misslyckades med att ändra namn", "ToastSelectAtLeastOneUser": "Åtminstone en användare måste väljas", "ToastSendEbookToDeviceFailed": "Misslyckades med att skicka e-boken till enheten", "ToastSendEbookToDeviceSuccess": "E-boken skickad till enheten \"{0}\"", @@ -912,5 +922,6 @@ "ToastUserDeleteSuccess": "Användaren borttagen", "ToastUserPasswordChangeSuccess": "Lösenordet har ändrats", "ToastUserPasswordMismatch": "Lösenorden är inte identiska", - "ToastUserPasswordMustChange": "Det nya lösenordet kan inte vara samma som det gamla" + "ToastUserPasswordMustChange": "Det nya lösenordet kan inte vara samma som det gamla", + "ToastUserRootRequireName": "Ett användarnamn för 'root' måste anges" } From a38a92b948a6846a806b1a3d7613d36c445eb99f Mon Sep 17 00:00:00 2001 From: SunSpring Date: Sat, 25 Jan 2025 10:46:07 +0000 Subject: [PATCH 46/66] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (1086 of 1086 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/zh_Hans/ --- client/strings/zh-cn.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/strings/zh-cn.json b/client/strings/zh-cn.json index 1c5362751..53c8484e2 100644 --- a/client/strings/zh-cn.json +++ b/client/strings/zh-cn.json @@ -10,6 +10,8 @@ "ButtonApplyChapters": "应用到章节", "ButtonAuthors": "作者", "ButtonBack": "返回", + "ButtonBatchEditPopulateFromExisting": "用现有内容填充", + "ButtonBatchEditPopulateMapDetails": "填充地图详细信息", "ButtonBrowseForFolder": "浏览文件夹", "ButtonCancel": "取消", "ButtonCancelEncode": "取消编码", @@ -704,6 +706,8 @@ "MessageBackupsLocationEditNote": "注意: 更新备份位置不会移动或修改现有备份", "MessageBackupsLocationNoEditNote": "注意: 备份位置是通过环境变量设置的, 不能在此处更改.", "MessageBackupsLocationPathEmpty": "备份位置路径不能为空", + "MessageBatchEditPopulateMapDetailsAllHelp": "使用所有项目的数据填充已启用的字段. 具有多个值的字段将被合并", + "MessageBatchEditPopulateMapDetailsItemHelp": "使用此项目的数据填充已启用的地图详细信息字段", "MessageBatchQuickMatchDescription": "快速匹配将尝试为所选项目添加缺少的封面和元数据. 启用以下选项以允许快速匹配覆盖现有封面和或元数据.", "MessageBookshelfNoCollections": "你尚未进行任何收藏", "MessageBookshelfNoRSSFeeds": "没有打开的 RSS 源", From 0a29b549df18033c9fc5a56c06bd5c3015725281 Mon Sep 17 00:00:00 2001 From: Simple16 Date: Sat, 25 Jan 2025 11:59:03 +0000 Subject: [PATCH 47/66] Translated using Weblate (Russian) Currently translated at 100.0% (1086 of 1086 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/ru/ --- client/strings/ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/strings/ru.json b/client/strings/ru.json index 853052a46..644621b9f 100644 --- a/client/strings/ru.json +++ b/client/strings/ru.json @@ -465,7 +465,7 @@ "LabelNotificationsMaxQueueSize": "Макс. размер очереди для событий уведомлений", "LabelNotificationsMaxQueueSizeHelp": "События ограничены 1 в секунду. События будут игнорированы если в очереди максимальное количество. Это предотвращает спам сообщениями.", "LabelNumberOfBooks": "Количество книг", - "LabelNumberOfEpisodes": "# Эпизодов", + "LabelNumberOfEpisodes": "# из эпизодов", "LabelOpenIDAdvancedPermsClaimDescription": "Имя утверждения OpenID, содержащего расширенные разрешения на действия пользователя в приложении, которые будут применяться к ролям, не являющимся администраторами (если они настроены). Если утверждение отсутствует в ответе, в доступе к ABS будет отказано. Если одна опция отсутствует, она будет рассматриваться как false. Убедитесь, что утверждение поставщика удостоверений соответствует ожидаемой структуре:", "LabelOpenIDClaims": "Оставьте следующие параметры пустыми, чтобы отключить расширенное назначение групп и разрешений, будет автоматически присвоена группа «Пользователь».", "LabelOpenIDGroupClaimDescription": "Имя утверждения OpenID, содержащего список групп пользователя. Обычно их называют groups. Если эта настройка настроена, приложение будет автоматически назначать роли на основе членства пользователя в группах при условии, что эти группы названы в утверждении без учета регистра \"admin\", \"user\" или \"guest\". Утверждение должно содержать список, и если пользователь принадлежит к нескольким группам, то приложение назначит роль, соответствующую самому высокому уровню доступа. Если ни одна из групп не совпадает, доступ будет запрещен.", From 35eb5bcfc0686d1238b3e8dfa1d34737aca8e710 Mon Sep 17 00:00:00 2001 From: biuklija Date: Sat, 25 Jan 2025 20:56:42 +0000 Subject: [PATCH 48/66] Translated using Weblate (Croatian) Currently translated at 100.0% (1086 of 1086 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/hr/ --- client/strings/hr.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/client/strings/hr.json b/client/strings/hr.json index 84912f9a5..f65a8d4b2 100644 --- a/client/strings/hr.json +++ b/client/strings/hr.json @@ -10,6 +10,8 @@ "ButtonApplyChapters": "Primijeni poglavlja", "ButtonAuthors": "Autori", "ButtonBack": "Natrag", + "ButtonBatchEditPopulateFromExisting": "Popuni iz postojećeg", + "ButtonBatchEditPopulateMapDetails": "Popuni mapirane pojedinosti", "ButtonBrowseForFolder": "Pronađi mapu", "ButtonCancel": "Odustani", "ButtonCancelEncode": "Otkaži kodiranje", @@ -288,7 +290,7 @@ "LabelCustomCronExpression": "Prilagođeni CRON izraz:", "LabelDatetime": "Datum i vrijeme", "LabelDays": "Dani", - "LabelDeleteFromFileSystemCheckbox": "Izbriši datoteke (uklonite oznaku ako stavku želite izbrisati samo iz baze podataka)", + "LabelDeleteFromFileSystemCheckbox": "Izbriši datoteke (uklonite kvačicu ako stavku želite izbrisati samo iz baze podataka)", "LabelDescription": "Opis", "LabelDeselectAll": "Odznači sve", "LabelDevice": "Uređaj", @@ -704,6 +706,8 @@ "MessageBackupsLocationEditNote": "Napomena: Uređivanje lokacije za sigurnosne kopije ne premješta ili mijenja postojeće sigurnosne kopije", "MessageBackupsLocationNoEditNote": "Napomena: Lokacija za sigurnosne kopije zadana je kroz varijablu okoline i ovdje se ne može izmijeniti.", "MessageBackupsLocationPathEmpty": "Putanja do lokacije za sigurnosne kopije ne može ostati prazna", + "MessageBatchEditPopulateMapDetailsAllHelp": "Nadopunjuje omogućena polja podatcima iz svih stavki. Polja s višestrukim podatcima će se spojiti", + "MessageBatchEditPopulateMapDetailsItemHelp": "Popuni omogućena polja mapiranih pojedinosti s podatcima iz ove stavke", "MessageBatchQuickMatchDescription": "Brzo prepoznavanje za odabrane će stavke pokušati dodati naslovnice i meta-podatke koji nedostaju. Uključite donje opcije ako želite da Brzo prepoznavanje prepiše postojeće naslovnice i/ili meta-podatke.", "MessageBookshelfNoCollections": "Niste izradili niti jednu zbirku", "MessageBookshelfNoRSSFeeds": "Nema otvorenih RSS izvora", @@ -721,7 +725,7 @@ "MessageConfirmDeleteDevice": "Sigurno želite izbrisati e-čitač \"{0}\"?", "MessageConfirmDeleteFile": "Ovo će izbrisati datoteke s datotečnog sustava. Jeste li sigurni?", "MessageConfirmDeleteLibrary": "Sigurno želite trajno izbrisati knjižnicu \"{0}\"?", - "MessageConfirmDeleteLibraryItem": "Ovo će izbrisati knjižničku stavku iz datoteke i vašeg datotečnog sustava. Jeste li sigurni?", + "MessageConfirmDeleteLibraryItem": "Ovo će izbrisati knjižničku stavku iz baze podataka i s datotečnog sustava. Jeste li sigurni?", "MessageConfirmDeleteLibraryItems": "Ovo će izbrisati {0} knjižničkih stavki iz baze podataka i datotečnog sustava. Jeste li sigurni?", "MessageConfirmDeleteMetadataProvider": "Sigurno želite izbrisati prilagođenog pružatelja meta-podataka \"{0}\"?", "MessageConfirmDeleteNotification": "Sigurno želite izbrisati ovu obavijest?", From 74c87a0bbd2c3f8b9ed1ca02cee4c0de1cb73a1a Mon Sep 17 00:00:00 2001 From: Andreas Morell-Reng Date: Mon, 27 Jan 2025 07:07:40 +0000 Subject: [PATCH 49/66] Translated using Weblate (Danish) Currently translated at 100.0% (1086 of 1086 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/da/ --- client/strings/da.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/client/strings/da.json b/client/strings/da.json index d36011fda..9816ab11c 100644 --- a/client/strings/da.json +++ b/client/strings/da.json @@ -10,6 +10,8 @@ "ButtonApplyChapters": "Anvend kapitler", "ButtonAuthors": "Forfattere", "ButtonBack": "Tilbage", + "ButtonBatchEditPopulateFromExisting": "Opret fra eksisterende", + "ButtonBatchEditPopulateMapDetails": "Opret fra kortlægnings detaljer", "ButtonBrowseForFolder": "Gennemse mappe", "ButtonCancel": "Annuller", "ButtonCancelEncode": "Annuller kodning", @@ -465,7 +467,7 @@ "LabelNumberOfBooks": "Antal bøger", "LabelNumberOfEpisodes": "# afsnit", "LabelOpenIDAdvancedPermsClaimDescription": "Navnet af OpenID claimet som indeholder avancerede brugerhandlinger inden i applikationen som vil gælde for ikke administrative roller (hvis konfigureret). Hvis et claim mangler fra svaret vil adgang til ABS blive nægtet. Hvis en enkelt indstilling/option mangler, vil det bliver behandlet som false. Sørg for at identity provider's claim matcher den forventede struktur:", - "LabelOpenIDClaims": "Efterlad de følgende indstillinger tomme for at deaktivere avancerede grupper og adgangsstyring for automatisk at tilføje dem til 'User' gruppen.", + "LabelOpenIDClaims": "Efterlad de følgende indstillinger tomme for at deaktivere avanceret gruppe og adgangsindstilling, ved automatisk at assigne 'Bruger' grupper.", "LabelOpenIDGroupClaimDescription": "Navnet af det OpenID claim som skal indeholde brugerens grupper. Mest kendt som groups. hvis konfigureret, vil applikationen automatiske tildele roller baseret p[ brugerens gruppemedlemsskaber, givet disse grupper er navngivet (uden forbehold for store og små bogstaver) 'admin', 'user' eller 'guest' i claimet. Claimet burde indeholde en liste (og hvis brugeren tilhøre flere grupper) som applikationen vil tildele roller med højeste adgangsnvieau. Hvis ingen grupper matcher vil adgang blive nægtet.", "LabelOpenRSSFeed": "Åbn RSS-feed", "LabelOverwrite": "Overskriv", @@ -662,7 +664,7 @@ "LabelTrailer": "Trailer", "LabelType": "Type", "LabelUnabridged": "Uforkortet", - "LabelUndo": "Undo", + "LabelUndo": "Fortryd", "LabelUnknown": "Ukendt", "LabelUnknownPublishDate": "Ukendt publiceringsdato", "LabelUpdateCover": "Opdater omslag", @@ -704,6 +706,8 @@ "MessageBackupsLocationEditNote": "Note: Opdatering af backup sti vil ikke fjerne eller modificere eksisterende backups", "MessageBackupsLocationNoEditNote": "Note: Backup sti er sat igennem miljøvariabel og kan ikke ændres her.", "MessageBackupsLocationPathEmpty": "Backup sti kan ikke være tom", + "MessageBatchEditPopulateMapDetailsAllHelp": "Opret felter slået til med data fra alle genstande. Felter med flere værdier vil blive sammenflettet", + "MessageBatchEditPopulateMapDetailsItemHelp": "Opret kort med værdier der er slået til fra felter med data fra denne genstand", "MessageBatchQuickMatchDescription": "Quick Match vil forsøge at tilføje manglende omslag og metadata til de valgte elementer. Aktivér indstillingerne nedenfor for at tillade Quick Match at overskrive eksisterende omslag og/eller metadata.", "MessageBookshelfNoCollections": "Du har ikke oprettet nogen samlinger endnu", "MessageBookshelfNoRSSFeeds": "Ingen RSS-feeds er åbne", From f82697cbbfac88b7ac9f62ef793d1c8863c9b214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=93=D0=BE=D1=80?= =?UTF-8?q?=D0=BF=D0=B8=D0=BD=D1=96=D1=87?= Date: Mon, 27 Jan 2025 11:06:11 +0000 Subject: [PATCH 50/66] Translated using Weblate (Ukrainian) Currently translated at 100.0% (1086 of 1086 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/uk/ --- client/strings/uk.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/strings/uk.json b/client/strings/uk.json index ebdc37901..d09ea1ba4 100644 --- a/client/strings/uk.json +++ b/client/strings/uk.json @@ -434,7 +434,7 @@ "LabelMetadataProvider": "Джерело метаданих", "LabelMinute": "Хвилина", "LabelMinutes": "Хвилини", - "LabelMissing": "Бракує", + "LabelMissing": "Відсутня", "LabelMissingEbook": "Без електронної книги", "LabelMissingSupplementaryEbook": "Без додаткової електронної книги", "LabelMobileRedirectURIs": "Дозволені адреси перенаправлення", From 437c8dd09c6101329b34431cd7da71f7d31c1500 Mon Sep 17 00:00:00 2001 From: thehijacker Date: Mon, 27 Jan 2025 06:22:23 +0000 Subject: [PATCH 51/66] Translated using Weblate (Slovenian) Currently translated at 100.0% (1086 of 1086 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/sl/ --- client/strings/sl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/strings/sl.json b/client/strings/sl.json index 47cbb49ec..7d6bb93d8 100644 --- a/client/strings/sl.json +++ b/client/strings/sl.json @@ -434,7 +434,7 @@ "LabelMetadataProvider": "Ponudnik metapodatkov", "LabelMinute": "Minuta", "LabelMinutes": "Minute", - "LabelMissing": "Manjkajoče", + "LabelMissing": "Manjka", "LabelMissingEbook": "Nima nobene e-knjige", "LabelMissingSupplementaryEbook": "Nima nobene dodatne e-knjige", "LabelMobileRedirectURIs": "Dovoljeni mobilni preusmeritveni URI-ji", From 8bd336a4bac0952a1cf8d55a73bf00f9f2f8a1d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=93=D0=BE=D1=80?= =?UTF-8?q?=D0=BF=D0=B8=D0=BD=D1=96=D1=87?= Date: Tue, 28 Jan 2025 11:47:18 +0000 Subject: [PATCH 52/66] Translated using Weblate (Ukrainian) Currently translated at 100.0% (1087 of 1087 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/uk/ --- client/strings/uk.json | 1 + 1 file changed, 1 insertion(+) diff --git a/client/strings/uk.json b/client/strings/uk.json index d09ea1ba4..d630bb8f6 100644 --- a/client/strings/uk.json +++ b/client/strings/uk.json @@ -486,6 +486,7 @@ "LabelPersonalYearReview": "Ваші підсумки року ({0})", "LabelPhotoPathURL": "Шлях/URL фото", "LabelPlayMethod": "Метод відтворення", + "LabelPlaybackRateIncrementDecrement": "Величина збільшення/зменшення швидкості відтворення", "LabelPlayerChapterNumberMarker": "{0} з {1}", "LabelPlaylists": "Списки відтворення", "LabelPodcast": "Подкаст", From 4cc97a22f63bec229747d1e30a24406d9a4d1279 Mon Sep 17 00:00:00 2001 From: Will Forde Date: Tue, 28 Jan 2025 00:18:21 +0000 Subject: [PATCH 53/66] Translated using Weblate (Japanese) Currently translated at 0.1% (1 of 1087 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/ja/ --- client/strings/ja.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/strings/ja.json b/client/strings/ja.json index 0967ef424..80af12d81 100644 --- a/client/strings/ja.json +++ b/client/strings/ja.json @@ -1 +1,3 @@ -{} +{ + "ButtonAdd": "追加" +} From 989388d3ed21508363fc6b075ac40e9b44889751 Mon Sep 17 00:00:00 2001 From: Michel Neuba Date: Wed, 29 Jan 2025 15:01:30 +0000 Subject: [PATCH 54/66] Translated using Weblate (French) Currently translated at 99.7% (1084 of 1087 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/fr/ --- client/strings/fr.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/strings/fr.json b/client/strings/fr.json index 8b640a6bf..dbefb5550 100644 --- a/client/strings/fr.json +++ b/client/strings/fr.json @@ -10,6 +10,8 @@ "ButtonApplyChapters": "Appliquer aux chapitres", "ButtonAuthors": "Auteurs", "ButtonBack": "Retour", + "ButtonBatchEditPopulateFromExisting": "Remplir à partir de l'existant", + "ButtonBatchEditPopulateMapDetails": "Remplir les détails de la carte", "ButtonBrowseForFolder": "Naviguer vers le répertoire", "ButtonCancel": "Annuler", "ButtonCancelEncode": "Annuler l’encodage", @@ -484,6 +486,7 @@ "LabelPersonalYearReview": "Bilan de l’année ({0})", "LabelPhotoPathURL": "Chemin / URL des photos", "LabelPlayMethod": "Méthode d’écoute", + "LabelPlaybackRateIncrementDecrement": "Augmentation/Diminition de la vitesse de lecture", "LabelPlayerChapterNumberMarker": "{0} sur {1}", "LabelPlaylists": "Listes de lecture", "LabelPodcast": "Podcast", @@ -704,6 +707,7 @@ "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", + "MessageBatchEditPopulateMapDetailsAllHelp": "Remplir les champs disponibles avec les données de tous les éléments. les champs avec des valeurs multiples seront fusionnés", "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", "MessageBookshelfNoRSSFeeds": "Aucun flux RSS n’est ouvert", From c62a6fbffd7a37b775ada947baf8c1a0e2b97ba8 Mon Sep 17 00:00:00 2001 From: biuklija Date: Wed, 29 Jan 2025 11:53:11 +0000 Subject: [PATCH 55/66] Translated using Weblate (Croatian) Currently translated at 100.0% (1087 of 1087 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/hr/ --- client/strings/hr.json | 1 + 1 file changed, 1 insertion(+) diff --git a/client/strings/hr.json b/client/strings/hr.json index f65a8d4b2..2871c0c8c 100644 --- a/client/strings/hr.json +++ b/client/strings/hr.json @@ -486,6 +486,7 @@ "LabelPersonalYearReview": "Vaš godišnji pregled ({0})", "LabelPhotoPathURL": "Putanja ili URL fotografije", "LabelPlayMethod": "Način reprodukcije", + "LabelPlaybackRateIncrementDecrement": "Korak povećanja/smanjenja brzine reprodukcije", "LabelPlayerChapterNumberMarker": "{0} od {1}", "LabelPlaylists": "Popisi za izvođenje", "LabelPodcast": "Podcast", From 88c10ad61987b3accb62351079dd3ab024156e49 Mon Sep 17 00:00:00 2001 From: Jan-Eric Myhrgren Date: Thu, 30 Jan 2025 07:58:19 +0000 Subject: [PATCH 56/66] Translated using Weblate (Swedish) Currently translated at 85.4% (929 of 1087 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/sv/ --- client/strings/sv.json | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/client/strings/sv.json b/client/strings/sv.json index b4a129826..6180652f1 100644 --- a/client/strings/sv.json +++ b/client/strings/sv.json @@ -153,6 +153,7 @@ "HeaderMetadataToEmbed": "Metadata som kommer att adderas", "HeaderNewAccount": "Nytt konto", "HeaderNewLibrary": "Nytt bibliotek", + "HeaderNotificationCreate": "Addera ett meddelande", "HeaderNotifications": "Meddelanden", "HeaderOpenRSSFeed": "Öppna RSS-flöde", "HeaderOtherFiles": "Andra filer", @@ -205,7 +206,7 @@ "LabelAccountTypeUser": "Användare", "LabelActivity": "Aktivitet", "LabelAddToCollection": "Lägg till i en samling", - "LabelAddToCollectionBatch": "Lägg till {0} böcker i en Samling", + "LabelAddToCollectionBatch": "Lägg till {0} böcker i samlingen", "LabelAddToPlaylist": "Lägg till i en spellista", "LabelAddToPlaylistBatch": "Lägg till {0} objekt i Spellistan", "LabelAddedAt": "Datum adderad", @@ -215,7 +216,7 @@ "LabelAllUsers": "Alla användare", "LabelAllUsersExcludingGuests": "Alla användare utom gäster", "LabelAllUsersIncludingGuests": "Alla användare inklusive gäster", - "LabelAlreadyInYourLibrary": "Redan i din samling", + "LabelAlreadyInYourLibrary": "Finns redan i samlingen", "LabelApiToken": "API-token", "LabelAppend": "Lägg till", "LabelAudioBitrate": "Bitrate för ljud (t.ex. 128k)", @@ -637,7 +638,7 @@ "MessageAddToPlayerQueue": "Lägg till i spellistan", "MessageAppriseDescription": "För att använda den här funktionen behöver du ha en instans av Apprise API igång eller en API som hanterar dessa begäranden.
Apprise API-urlen bör vara hela URL-sökvägen för att skicka meddelandet, t.ex., om din API-instans är tillgänglig på http://192.168.1.1:8337, bör du ange http://192.168.1.1:8337/notify.", "MessageBackupsDescription": "Säkerhetskopior inkluderar användare, användarnas framsteg, biblioteksobjekt, serverinställningar
och bilder lagrade i /metadata/items & /metadata/authors.
De inkluderar INTE några filer lagrade i dina biblioteksmappar.", - "MessageBackupsLocationEditNote": "OBS: När du ändrar plats för säkerhetskopiorna så flyttas INTE gamla säkerhetskopior dit", + "MessageBackupsLocationEditNote": "OBS: När du ändrar plats för säkerhetskopiorna så flyttas INTE gamla säkerhetskopior dit.", "MessageBackupsLocationNoEditNote": "OBS: Platsen där säkerhetskopiorna lagras bestäms av en central inställning och kan inte ändras här.", "MessageBackupsLocationPathEmpty": "Uppgiften om platsen för lagring av säkerhetskopior kan inte lämnas tom", "MessageBatchQuickMatchDescription": "Quick Match kommer försöka lägga till saknade omslag och metadata för de valda föremålen. Aktivera alternativen nedan för att tillåta Quick Match att överskriva befintliga omslag och/eller metadata.", @@ -660,8 +661,10 @@ "MessageConfirmDeleteLibraryItem": "Detta kommer att radera objektet från databasen och ditt filsystem. Är du säker?", "MessageConfirmDeleteLibraryItems": "Detta kommer att radera {0} biblioteksobjekt från databasen och ditt filsystem. Är du säker?", "MessageConfirmDeleteMetadataProvider": "Är du säker på att du vill radera din egen källa för metadata \"{0}\"?", + "MessageConfirmDeleteNotification": "Är du säker på att du vill radera detta meddelande?", "MessageConfirmDeleteSession": "Är du säker på att du vill radera detta lyssningstillfälle?", - "MessageConfirmForceReScan": "Är du säker på att du vill tvinga omgenomsökning?", + "MessageConfirmEmbedMetadataInAudioFiles": "Är du säker på att du vill infoga metadata i {0} ljudfiler?", + "MessageConfirmForceReScan": "Är du säker på att du vill starta en ny skanning?", "MessageConfirmMarkAllEpisodesFinished": "Är du säker på att du vill markera alla avsnitt som avslutade?", "MessageConfirmMarkAllEpisodesNotFinished": "Är du säker på att du vill markera alla avsnitt som ej avslutade?", "MessageConfirmMarkItemFinished": "Är du säker på att du vill markera \"{0}\" som avslutad?", @@ -678,7 +681,7 @@ "MessageConfirmRemoveEpisode": "Är du säker på att du vill ta bort avsnittet \"{0}\"?", "MessageConfirmRemoveEpisodes": "Är du säker på att du vill ta bort {0} avsnitt?", "MessageConfirmRemoveListeningSessions": "Är du säker på att du vill radera {0} lyssningstillfällen?", - "MessageConfirmRemoveMetadataFiles": "Är du säker på att du vill radera 'metadata.{0}' filerna i alla mappar i ditt bibliotek?", + "MessageConfirmRemoveMetadataFiles": "Är du säker på att du vill radera filerna 'metadata.{0}' i alla mappar i ditt bibliotek?", "MessageConfirmRemoveNarrator": "Är du säker på att du vill ta bort uppläsaren \"{0}\"?", "MessageConfirmRemovePlaylist": "Är du säker på att du vill ta bort din spellista \"{0}\"?", "MessageConfirmRenameGenre": "Är du säker på att du vill byta namn på kategorin \"{0}\" till \"{1}\" för alla objekt?", @@ -748,7 +751,7 @@ "MessageOr": "eller", "MessagePauseChapter": "Pausa kapiteluppspelning", "MessagePlayChapter": "Lyssna på kapitlets början", - "MessagePlaylistCreateFromCollection": "Skapa spellista från samling", + "MessagePlaylistCreateFromCollection": "Skapa en spellista från samlingen", "MessagePleaseWait": "Vänta ett ögonblick...", "MessagePodcastHasNoRSSFeedForMatching": "Podcasten har ingen RSS-flödes-URL att använda för matchning", "MessageQuickMatchDescription": "Adderar uppgifter som saknas samt en omslagsbild från
första träffen i resultatet vid sökningen från '{0}'.
Skriver inte över befintliga uppgifter om inte
inställningen 'Prioritera matchad metadata' är aktiverad.", @@ -760,6 +763,7 @@ "MessageResetChaptersConfirm": "Är du säker på att du vill återställa alla kapitel och ångra de ändringarna du gjort?", "MessageRestoreBackupConfirm": "Är du säker på att du vill läsa in säkerhetskopian som skapades den", "MessageRestoreBackupWarning": "Att återställa en säkerhetskopia kommer att skriva över hela databasen som finns i /config och omslagsbilder i /metadata/items & /metadata/authors.

Säkerhetskopior ändrar inte några filer i dina biblioteksmappar. Om du har aktiverat serverinställningar för att lagra omslagskonst och metadata i dina biblioteksmappar säkerhetskopieras eller skrivs de inte över.

Alla klienter som använder din server kommer att uppdateras automatiskt.", + "MessageScheduleLibraryScanNote": "För de flesta användare rekommenderas att denna funktion ej aktiveras. Istället bör funktionen 'Watcher' vara aktiverad. Watcher kommer då automatiskt identifiera förändringar i biblioteket. För vissa filsystem (som t.ex. NFS) fungerar inte Watcher. Då kan schemalagda skanningar av biblioteken användas istället.", "MessageSearchResultsFor": "Sökresultat för", "MessageSelected": "{0} valda", "MessageServerCouldNotBeReached": "Servern kunde inte nås", @@ -783,15 +787,15 @@ "MessageXLibraryIsEmpty": "Biblioteket {0} är tomt!", "MessageYourAudiobookDurationIsLonger": "Varaktigheten på din ljudbok är längre än den hittade varaktigheten", "MessageYourAudiobookDurationIsShorter": "Varaktigheten på din ljudbok är kortare än den hittade varaktigheten", - "NoteChangeRootPassword": "Rotanvändaren är den enda användaren som kan ha ett tomt lösenord", + "NoteChangeRootPassword": "Användaren 'root' är den enda användaren som kan vara utan lösenord", "NoteChapterEditorTimes": "OBS: Starttiden för första kapitlet måste vara 0:00 och starttiden för det sista kapitlet får inte överstiga ljudbokens totala varaktighet.", - "NoteFolderPicker": "Obs: Mappar som redan är kartlagda kommer inte att visas", - "NoteRSSFeedPodcastAppsHttps": "Varning: De flesta podcastappar kräver att RSS-flödets URL används med HTTPS", - "NoteRSSFeedPodcastAppsPubDate": "Varning: 1 eller flera av dina avsnitt har inte ett publiceringsdatum. Vissa podcastappar kräver detta.", - "NoteUploaderFoldersWithMediaFiles": "Mappar med flera mediefiler hanteras som separata objekt i biblioteket.", + "NoteFolderPicker": "OBS: Mappar som redan är kopplade kommer inte att visas", + "NoteRSSFeedPodcastAppsHttps": "VARNING: De flesta applikationer för podcasts kräver att URL:en för RSS-flödet använder HTTPS", + "NoteRSSFeedPodcastAppsPubDate": "VARNING: Ett eller flera av dina avsnitt har inte ett publiceringsdatum. Vissa applikationer för podcasts kräver detta.", + "NoteUploaderFoldersWithMediaFiles": "Mappar som innehåller mediefiler hanteras som separata objekt i biblioteket.", "NoteUploaderOnlyAudioFiles": "Om du bara laddar upp ljudfiler kommer varje ljudfil att hanteras som en separat ljudbok.", "NoteUploaderUnsupportedFiles": "Oaccepterade filer ignoreras. När du väljer eller släpper en mapp ignoreras andra filer som inte finns i ett objektmapp.", - "PlaceholderNewCollection": "Nytt samlingsnamn", + "PlaceholderNewCollection": "Nytt namn på samlingen", "PlaceholderNewFolderPath": "Nytt sökväg till mappen", "PlaceholderNewPlaylist": "Nytt namn på spellistan", "PlaceholderSearch": "Sök...", From 9abd6698aef4d5ef37ef183e73d9cacda01e8201 Mon Sep 17 00:00:00 2001 From: thehijacker Date: Thu, 30 Jan 2025 06:52:41 +0000 Subject: [PATCH 57/66] Translated using Weblate (Slovenian) Currently translated at 100.0% (1087 of 1087 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/sl/ --- client/strings/sl.json | 1 + 1 file changed, 1 insertion(+) diff --git a/client/strings/sl.json b/client/strings/sl.json index 7d6bb93d8..d991150bb 100644 --- a/client/strings/sl.json +++ b/client/strings/sl.json @@ -486,6 +486,7 @@ "LabelPersonalYearReview": "Pregled tvojega leta ({0})", "LabelPhotoPathURL": "Slika pot/URL", "LabelPlayMethod": "Metoda predvajanja", + "LabelPlaybackRateIncrementDecrement": "Korak povečanja/zmanjšanja hitrosti predvajanja", "LabelPlayerChapterNumberMarker": "{0} od {1}", "LabelPlaylists": "Seznami predvajanja", "LabelPodcast": "Podcast", From 1fce94ad4a39ae0d462b4e2d512a09d2461aebff Mon Sep 17 00:00:00 2001 From: Andreas Morell-Reng Date: Fri, 31 Jan 2025 09:36:09 +0000 Subject: [PATCH 58/66] Translated using Weblate (Danish) Currently translated at 100.0% (1089 of 1089 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/da/ --- client/strings/da.json | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/client/strings/da.json b/client/strings/da.json index 9816ab11c..226da6558 100644 --- a/client/strings/da.json +++ b/client/strings/da.json @@ -5,7 +5,7 @@ "ButtonAddLibrary": "Tilføj Bibliotek", "ButtonAddPodcasts": "Tilføj podcasts", "ButtonAddUser": "Tilføj bruger", - "ButtonAddYourFirstLibrary": "Tilføj din første bibliotek", + "ButtonAddYourFirstLibrary": "Tilføj dit første bibliotek", "ButtonApply": "Anvend", "ButtonApplyChapters": "Anvend kapitler", "ButtonAuthors": "Forfattere", @@ -93,7 +93,7 @@ "ButtonScrollLeft": "Rul til Venstre", "ButtonScrollRight": "Rul til Højre", "ButtonSearch": "Søg", - "ButtonSelectFolderPath": "Vælg Mappen Sti", + "ButtonSelectFolderPath": "Vælg Mappe Sti", "ButtonSeries": "Serier", "ButtonSetChaptersFromTracks": "Sæt kapitler fra spor", "ButtonShare": "Del", @@ -215,7 +215,7 @@ "LabelAbridgedChecked": "Forkortet (kontrolleret)", "LabelAbridgedUnchecked": "Uforkortet (ikke kontrolleret)", "LabelAccessibleBy": "Tilgængelig af", - "LabelAccountType": "Kontotype", + "LabelAccountType": "Brugertype", "LabelAccountTypeAdmin": "Administrator", "LabelAccountTypeGuest": "Gæst", "LabelAccountTypeUser": "Bruger", @@ -226,7 +226,7 @@ "LabelAddToPlaylistBatch": "Tilføj {0} Elementer til Afspilningsliste", "LabelAddedAt": "Tilføjet", "LabelAddedDate": "Tilføjet {0}", - "LabelAdminUsersOnly": "Kun Administratorbrugere", + "LabelAdminUsersOnly": "Kun Administratorer", "LabelAll": "Alle", "LabelAllUsers": "Alle Brugere", "LabelAllUsersExcludingGuests": "Alle bruger eksklusiv gæster", @@ -445,7 +445,7 @@ "LabelNarrator": "Fortæller", "LabelNarrators": "Fortællere", "LabelNew": "Ny", - "LabelNewPassword": "Nyt kodeord", + "LabelNewPassword": "Ny adgangskode", "LabelNewestAuthors": "Nyeste forfattere", "LabelNewestEpisodes": "Nyeste episoder", "LabelNextBackupDate": "Næste sikkerhedskopi dato", @@ -472,7 +472,7 @@ "LabelOpenRSSFeed": "Åbn RSS-feed", "LabelOverwrite": "Overskriv", "LabelPaginationPageXOfY": "Side {0} af {1}", - "LabelPassword": "Kodeord", + "LabelPassword": "Adgangskode", "LabelPath": "Sti", "LabelPermanent": "Permanent", "LabelPermissionsAccessAllLibraries": "Kan få adgang til alle biblioteker", @@ -486,6 +486,7 @@ "LabelPersonalYearReview": "Dit år i review ({0})", "LabelPhotoPathURL": "Foto sti/URL", "LabelPlayMethod": "Afspilningsmetode", + "LabelPlaybackRateIncrementDecrement": "Afspilningshastighed øges/sænkes med", "LabelPlayerChapterNumberMarker": "{0} af {1}", "LabelPlaylists": "Afspilningslister", "LabelPodcast": "Podcast", @@ -575,12 +576,12 @@ "LabelSettingsLibraryMarkAsFinishedWhen": "Marker medie indhold som færdigt når", "LabelSettingsOnlyShowLaterBooksInContinueSeries": "Spring til tidligere bøger i Fortsæt serie", "LabelSettingsOnlyShowLaterBooksInContinueSeriesHelp": "Fortsæt Serien siden hylde viser de første bøger som ikke er startet i serier med mindst en bog som ikke er startet og ingen bøger i gang. Aktivering af denne indstilling vil fortsætte serien fra den sidst gennemførte bog modsat den først ikke startede bog.", - "LabelSettingsParseSubtitles": "Fortolk undertekster", + "LabelSettingsParseSubtitles": "Fortolk undertitler", "LabelSettingsParseSubtitlesHelp": "Udtræk undertekster fra lydbogsmappenavne.
Undertitler skal adskilles af \" - \"
f.eks. \"Bogtitel - En undertitel her\" har undertitlen \"En undertitel her\"", "LabelSettingsPreferMatchedMetadata": "Foretræk matchede metadata", "LabelSettingsPreferMatchedMetadataHelp": "Matchede data vil tilsidesætte elementdetaljer ved brug af Hurtig Match. Som standard udfylder Hurtig Match kun manglende detaljer.", "LabelSettingsSkipMatchingBooksWithASIN": "Spring over matchende bøger, der allerede har en ASIN", - "LabelSettingsSkipMatchingBooksWithISBN": "Spring over matchende bøger, der allerede har en ISBN", + "LabelSettingsSkipMatchingBooksWithISBN": "Spring matchende bøger over, som allerede har et ISBN-nummer", "LabelSettingsSortingIgnorePrefixes": "Ignorer præfikser ved sortering", "LabelSettingsSortingIgnorePrefixesHelp": "f.eks. for præfikset \"the\" vil bogtitlen \"The Book Title\" blive sorteret som \"Book Title, The\"", "LabelSettingsSquareBookCovers": "Brug kvadratiske bogomslag", @@ -710,6 +711,7 @@ "MessageBatchEditPopulateMapDetailsItemHelp": "Opret kort med værdier der er slået til fra felter med data fra denne genstand", "MessageBatchQuickMatchDescription": "Quick Match vil forsøge at tilføje manglende omslag og metadata til de valgte elementer. Aktivér indstillingerne nedenfor for at tillade Quick Match at overskrive eksisterende omslag og/eller metadata.", "MessageBookshelfNoCollections": "Du har ikke oprettet nogen samlinger endnu", + "MessageBookshelfNoCollectionsHelp": "Samlinger er offentlige. Alle brugere med adgang til biblioteket kan se dem.", "MessageBookshelfNoRSSFeeds": "Ingen RSS-feeds er åbne", "MessageBookshelfNoResultsForFilter": "Ingen resultater for filter \"{0}: {1}\"", "MessageBookshelfNoResultsForQuery": "Intet resultat for query", @@ -820,6 +822,7 @@ "MessageNoTasksRunning": "Ingen opgaver kører", "MessageNoUpdatesWereNecessary": "Ingen opdateringer var nødvendige", "MessageNoUserPlaylists": "Du har ingen afspilningslister", + "MessageNoUserPlaylistsHelp": "Playlister er private. Kun brugere som opretter dem kan se dem.", "MessageNotYetImplemented": "Endnu ikke implementeret", "MessageOpmlPreviewNote": "Note: Dette er en forhåndsvisning af den indlæste OPML fil. Podcast titel vil blive taget fra RSS feedet.", "MessageOr": "eller", From b62309ead23df4bdf57903af3bfe544e056167f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=93=D0=BE=D1=80?= =?UTF-8?q?=D0=BF=D0=B8=D0=BD=D1=96=D1=87?= Date: Fri, 31 Jan 2025 05:50:24 +0000 Subject: [PATCH 59/66] Translated using Weblate (Ukrainian) Currently translated at 100.0% (1089 of 1089 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/uk/ --- client/strings/uk.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/strings/uk.json b/client/strings/uk.json index d630bb8f6..ba1a2d214 100644 --- a/client/strings/uk.json +++ b/client/strings/uk.json @@ -711,6 +711,7 @@ "MessageBatchEditPopulateMapDetailsItemHelp": "Заповніть увімкнені поля деталей карти даними з цього елемента", "MessageBatchQuickMatchDescription": "Швидкий пошук спробує знайти відсутні обкладинки та метадані обраних елементів. Увімкніть налаштування нижче, аби дозволити заміну наявних обкладинок та/або метаданих під час швидкого пошуку.", "MessageBookshelfNoCollections": "Ви не створили жодної добірки", + "MessageBookshelfNoCollectionsHelp": "Колекції публічні. Їх можуть бачити всі користувачі, які мають доступ до бібліотеки.", "MessageBookshelfNoRSSFeeds": "Немає відкритих RSS-каналів", "MessageBookshelfNoResultsForFilter": "Немає результатів з фільтром \"{0}: {1}\"", "MessageBookshelfNoResultsForQuery": "Немає результатів за запитом", @@ -821,6 +822,7 @@ "MessageNoTasksRunning": "Немає активних завдань", "MessageNoUpdatesWereNecessary": "Оновлень не потрібно", "MessageNoUserPlaylists": "У вас немає списків відтворення", + "MessageNoUserPlaylistsHelp": "Списки відтворення приватні. Лише користувач, який їх створює, може бачити їх.", "MessageNotYetImplemented": "Ще не реалізовано", "MessageOpmlPreviewNote": "Примітка: це попередній перегляд OPML-файлу. Актуальна назва подкасту буде завантажена з RSS-каналу.", "MessageOr": "або", From 3d9100e5b84b4399c2b94f4ba789812c61f22654 Mon Sep 17 00:00:00 2001 From: Simple16 Date: Sat, 1 Feb 2025 03:16:01 +0000 Subject: [PATCH 60/66] Translated using Weblate (Russian) Currently translated at 100.0% (1089 of 1089 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/ru/ --- client/strings/ru.json | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/client/strings/ru.json b/client/strings/ru.json index 644621b9f..a2c66d8ca 100644 --- a/client/strings/ru.json +++ b/client/strings/ru.json @@ -303,7 +303,7 @@ "LabelDownload": "Скачать", "LabelDownloadNEpisodes": "Скачать {0} эпизодов", "LabelDownloadable": "Загружаемый", - "LabelDuration": "Длина", + "LabelDuration": "Продолжительность", "LabelDurationComparisonExactMatch": "(точное совпадение)", "LabelDurationComparisonLonger": "({0} дольше)", "LabelDurationComparisonShorter": "({0} короче)", @@ -434,7 +434,7 @@ "LabelMetadataProvider": "Провайдер", "LabelMinute": "Минуты", "LabelMinutes": "Минуты", - "LabelMissing": "Потеряно", + "LabelMissing": "Отсутствует", "LabelMissingEbook": "Нет e-книги", "LabelMissingSupplementaryEbook": "Нет дополнительной e-книги", "LabelMobileRedirectURIs": "Разрешенные URI перенаправления с мобильных устройств", @@ -486,6 +486,7 @@ "LabelPersonalYearReview": "Итоги прошедшего года ({0})", "LabelPhotoPathURL": "Путь к фото/URL", "LabelPlayMethod": "Метод воспроизведения", + "LabelPlaybackRateIncrementDecrement": "Величина увеличения/уменьшения скорости воспроизведения", "LabelPlayerChapterNumberMarker": "{0} из {1}", "LabelPlaylists": "Плейлисты", "LabelPodcast": "Подкаст", @@ -653,7 +654,7 @@ "LabelToolsMakeM4bDescription": "Создает .M4B файл аудиокниги с встроенными метаданными, обложкой и главами.", "LabelToolsSplitM4b": "Разделить M4B на MP3 файлы", "LabelToolsSplitM4bDescription": "Создает MP3 файла из M4B, разделяет на главы с встроенными метаданными, обложкой и главами.", - "LabelTotalDuration": "Общая длина", + "LabelTotalDuration": "Общая продолжительность", "LabelTotalTimeListened": "Всего прослушано", "LabelTrackFromFilename": "Трек из Имени файла", "LabelTrackFromMetadata": "Трек из Метаданных", @@ -710,6 +711,7 @@ "MessageBatchEditPopulateMapDetailsItemHelp": "Заполнить активированные поля сведений о карте данными из этого элемента", "MessageBatchQuickMatchDescription": "Быстрый Поиск попытается добавить отсутствующие обложки и метаданные для выбранных элементов. Включите параметры ниже, чтобы разрешить Быстрому Поиску перезаписывать существующие обложки и/или метаданные.", "MessageBookshelfNoCollections": "Вы еще не создали ни одной коллекции", + "MessageBookshelfNoCollectionsHelp": "Коллекции являются общедоступными. Все пользователи, имеющие доступ к библиотеке, могут их просматривать.", "MessageBookshelfNoRSSFeeds": "Нет открытых RSS-каналов", "MessageBookshelfNoResultsForFilter": "Нет Результатов для фильтра \"{0}: {1}\"", "MessageBookshelfNoResultsForQuery": "Нет результатов для запроса", @@ -820,6 +822,7 @@ "MessageNoTasksRunning": "Нет выполняемых задач", "MessageNoUpdatesWereNecessary": "Обновления не требовались", "MessageNoUserPlaylists": "У вас нет плейлистов", + "MessageNoUserPlaylistsHelp": "Списки воспроизведения являются конфиденциальными. Только пользователь, который их создает, может их видеть.", "MessageNotYetImplemented": "Пока не реализовано", "MessageOpmlPreviewNote": "Примечание: Это предварительный просмотр разобранного файла OPML. Фактическое название подкаста будет взято из RSS-канала.", "MessageOr": "или", From 13f353596b96623c4d67ea6f839ff75e868193c5 Mon Sep 17 00:00:00 2001 From: SunSpring Date: Sat, 1 Feb 2025 01:38:03 +0000 Subject: [PATCH 61/66] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (1089 of 1089 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/zh_Hans/ --- client/strings/zh-cn.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/strings/zh-cn.json b/client/strings/zh-cn.json index 53c8484e2..2ebec7381 100644 --- a/client/strings/zh-cn.json +++ b/client/strings/zh-cn.json @@ -434,7 +434,7 @@ "LabelMetadataProvider": "元数据提供商", "LabelMinute": "分钟", "LabelMinutes": "分钟", - "LabelMissing": "丢失", + "LabelMissing": "丢失的", "LabelMissingEbook": "没有电子书", "LabelMissingSupplementaryEbook": "没有补充电子书", "LabelMobileRedirectURIs": "允许移动应用重定向 URI", @@ -486,6 +486,7 @@ "LabelPersonalYearReview": "你的年度回顾 ({0})", "LabelPhotoPathURL": "图片路径或 URL", "LabelPlayMethod": "播放方法", + "LabelPlaybackRateIncrementDecrement": "播放速率增加/减少量", "LabelPlayerChapterNumberMarker": "{0} 于 {1}", "LabelPlaylists": "播放列表", "LabelPodcast": "播客", @@ -710,6 +711,7 @@ "MessageBatchEditPopulateMapDetailsItemHelp": "使用此项目的数据填充已启用的地图详细信息字段", "MessageBatchQuickMatchDescription": "快速匹配将尝试为所选项目添加缺少的封面和元数据. 启用以下选项以允许快速匹配覆盖现有封面和或元数据.", "MessageBookshelfNoCollections": "你尚未进行任何收藏", + "MessageBookshelfNoCollectionsHelp": "收藏是公开的. 所有有权访问图书馆的用户都可以看到它们.", "MessageBookshelfNoRSSFeeds": "没有打开的 RSS 源", "MessageBookshelfNoResultsForFilter": "过滤器无结果 \"{0}: {1}\"", "MessageBookshelfNoResultsForQuery": "没有可查询的结果", @@ -820,6 +822,7 @@ "MessageNoTasksRunning": "没有正在运行的任务", "MessageNoUpdatesWereNecessary": "无需更新", "MessageNoUserPlaylists": "你没有播放列表", + "MessageNoUserPlaylistsHelp": "播放列表是私密的. 只有创建播放列表的用户才能看到.", "MessageNotYetImplemented": "尚未实施", "MessageOpmlPreviewNote": "注意: 这是解析的OPML文件的预览. 实际的播客标题将从 RSS 提要中获取.", "MessageOr": "或", From 5fa4c5a2c3f59f61acf25d1cfcca958fd526af33 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Sat, 1 Feb 2025 12:27:05 +0000 Subject: [PATCH 62/66] Translated using Weblate (German) Currently translated at 99.3% (1082 of 1089 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/de/ --- client/strings/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/strings/de.json b/client/strings/de.json index 99d5bb1e7..b31fedc9c 100644 --- a/client/strings/de.json +++ b/client/strings/de.json @@ -645,7 +645,7 @@ "LabelTimeToShift": "Zeit bis zum Wechsel in Sekunden", "LabelTitle": "Titel", "LabelToolsEmbedMetadata": "Metadaten einbetten", - "LabelToolsEmbedMetadataDescription": "Bettet die Metadaten einschließlich des Titelbildes und der Kapitel in die Audiodatein ein.", + "LabelToolsEmbedMetadataDescription": "Bettet die Metadaten einschließlich des Titelbildes und der Kapitel in die Audiodateien ein.", "LabelToolsM4bEncoder": "M4B Kodierer", "LabelToolsMakeM4b": "M4B-Datei erstellen", "LabelToolsMakeM4bDescription": "Erstellt eine M4B-Datei (Endung \".m4b\") welche mehrere mp3-Dateien in einer einzigen Datei inkl. derer Metadaten (Beschreibung, Titelbild, Kapitel, ...) zusammenfasst. M4B-Datei können darüber hinaus Lesezeichen speichern und mit einem Abspielschutz (Passwort) versehen werden.", From 3465790fe969bbf73f71ef38a1e479c96c63161b Mon Sep 17 00:00:00 2001 From: biuklija Date: Sat, 1 Feb 2025 10:09:26 +0000 Subject: [PATCH 63/66] Translated using Weblate (Croatian) Currently translated at 100.0% (1089 of 1089 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/hr/ --- client/strings/hr.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/strings/hr.json b/client/strings/hr.json index 2871c0c8c..eda11cfa1 100644 --- a/client/strings/hr.json +++ b/client/strings/hr.json @@ -401,7 +401,7 @@ "LabelLastBookAdded": "Zadnja dodana knjiga", "LabelLastBookUpdated": "Zadnja ažurirana knjiga", "LabelLastSeen": "Zadnji puta viđen", - "LabelLastTime": "Zadnji puta", + "LabelLastTime": "Zadnje vrijeme", "LabelLastUpdate": "Zadnje ažuriranje", "LabelLayout": "Prikaz", "LabelLayoutSinglePage": "Jedna stranica", @@ -711,6 +711,7 @@ "MessageBatchEditPopulateMapDetailsItemHelp": "Popuni omogućena polja mapiranih pojedinosti s podatcima iz ove stavke", "MessageBatchQuickMatchDescription": "Brzo prepoznavanje za odabrane će stavke pokušati dodati naslovnice i meta-podatke koji nedostaju. Uključite donje opcije ako želite da Brzo prepoznavanje prepiše postojeće naslovnice i/ili meta-podatke.", "MessageBookshelfNoCollections": "Niste izradili niti jednu zbirku", + "MessageBookshelfNoCollectionsHelp": "Zbirke su javne. Svi korisnici s pristupom knjižnici mogu ih vidjeti.", "MessageBookshelfNoRSSFeeds": "Nema otvorenih RSS izvora", "MessageBookshelfNoResultsForFilter": "Nema rezultata za filter \"{0}: {1}\"", "MessageBookshelfNoResultsForQuery": "Vaš upit nema rezultata", @@ -821,6 +822,7 @@ "MessageNoTasksRunning": "Nema zadataka koji se izvode", "MessageNoUpdatesWereNecessary": "Ažuriranje nije bilo potrebno", "MessageNoUserPlaylists": "Nemate popisa za izvođenje", + "MessageNoUserPlaylistsHelp": "Popisi za izvođenje su privatni. Može ih vidjeti samo korisnik koji ih je izradio.", "MessageNotYetImplemented": "Još nije implementirano", "MessageOpmlPreviewNote": "Napomena: Ovo je pretpregled raščlanjene OPML datoteke. Stvarni naslov podcasta preuzet će se iz RSS izvora.", "MessageOr": "ili", From 4464276a6e2ef1876faeea0f7a269189a8f413e1 Mon Sep 17 00:00:00 2001 From: thehijacker Date: Sat, 1 Feb 2025 13:51:58 +0000 Subject: [PATCH 64/66] Translated using Weblate (Slovenian) Currently translated at 100.0% (1089 of 1089 strings) Translation: Audiobookshelf/Abs Web Client Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-web-client/sl/ --- client/strings/sl.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/strings/sl.json b/client/strings/sl.json index d991150bb..33e6da865 100644 --- a/client/strings/sl.json +++ b/client/strings/sl.json @@ -711,6 +711,7 @@ "MessageBatchEditPopulateMapDetailsItemHelp": "Napolni omogočena polja s podrobnostmi zemljevida s podatki iz tega elementa", "MessageBatchQuickMatchDescription": "Hitro ujemanje bo poskušal dodati manjkajoče naslovnice in metapodatke za izbrane elemente. Omogočite spodnje možnosti, da omogočite hitremu ujemanju, da prepiše obstoječe naslovnice in/ali metapodatke.", "MessageBookshelfNoCollections": "Ustvaril nisi še nobene zbirke", + "MessageBookshelfNoCollectionsHelp": "Zbirke so javne. Vsi uporabniki z dostopom do knjižnice jih lahko vidijo.", "MessageBookshelfNoRSSFeeds": "Noben vir RSS ni odprt", "MessageBookshelfNoResultsForFilter": "Ni rezultatov za filter \"{0}: {1}\"", "MessageBookshelfNoResultsForQuery": "Ni rezultatov za poizvedbo", @@ -821,6 +822,7 @@ "MessageNoTasksRunning": "Nobeno opravili ne teče", "MessageNoUpdatesWereNecessary": "Posodobitve niso bile potrebne", "MessageNoUserPlaylists": "Nimate seznamov predvajanja", + "MessageNoUserPlaylistsHelp": "Seznami predvajanj so zasebni. Samo uporabniki, ki jih ustvarijo, jih lahko vidijo.", "MessageNotYetImplemented": "Še ni implementirano", "MessageOpmlPreviewNote": "Opomba: To je predogled razčlenjene datoteke OPML. Dejanski naslov podcasta bo vzet iz vira RSS.", "MessageOr": "ali", From eeaae5f9345036213a2c6dd9908ed7c5a4b3c56d Mon Sep 17 00:00:00 2001 From: advplyr Date: Sun, 2 Feb 2025 22:06:22 +0100 Subject: [PATCH 65/66] Added translation using Weblate (Turkish) --- client/strings/tr.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 client/strings/tr.json diff --git a/client/strings/tr.json b/client/strings/tr.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/client/strings/tr.json @@ -0,0 +1 @@ +{} From 82ab95ab028711626b01838a2c562c796b36c2b0 Mon Sep 17 00:00:00 2001 From: advplyr Date: Sun, 2 Feb 2025 15:39:46 -0600 Subject: [PATCH 66/66] Version bump v2.19.0 --- client/package-lock.json | 4 ++-- client/package.json | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index cf6ed8629..7aa99d67d 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,12 +1,12 @@ { "name": "audiobookshelf-client", - "version": "2.18.1", + "version": "2.19.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "audiobookshelf-client", - "version": "2.18.1", + "version": "2.19.0", "license": "ISC", "dependencies": { "@nuxtjs/axios": "^5.13.6", diff --git a/client/package.json b/client/package.json index ee50f38d5..7b09854ac 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "audiobookshelf-client", - "version": "2.18.1", + "version": "2.19.0", "buildNumber": 1, "description": "Self-hosted audiobook and podcast client", "main": "index.js", diff --git a/package-lock.json b/package-lock.json index 8d37a6d3b..f0bca0185 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "audiobookshelf", - "version": "2.18.1", + "version": "2.19.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "audiobookshelf", - "version": "2.18.1", + "version": "2.19.0", "license": "GPL-3.0", "dependencies": { "axios": "^0.27.2", diff --git a/package.json b/package.json index f194b6755..ce36e229f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "audiobookshelf", - "version": "2.18.1", + "version": "2.19.0", "buildNumber": 1, "description": "Self-hosted audiobook and podcast server", "main": "index.js",