mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-06-06 02:32:44 +02:00
Compare commits
284 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d80752cc9d | |||
| b764e848c7 | |||
| b037c4e8a3 | |||
| 6ba2360790 | |||
| ca4eb507f0 | |||
| 965b094470 | |||
| 0fe313ecfd | |||
| 35a2f8d44f | |||
| 50797879d5 | |||
| 9327331ee9 | |||
| 1c15007e32 | |||
| 2151ffa114 | |||
| 49ed208a54 | |||
| d668462529 | |||
| f2102a0a23 | |||
| 5efc6b82c1 | |||
| 1e4e9768da | |||
| cc5109c305 | |||
| e858d6a1d5 | |||
| b4cd5d2862 | |||
| 0633a44cfb | |||
| 5748126b83 | |||
| 06375743a3 | |||
| 2a41c186aa | |||
| af51b7254c | |||
| f63dfd769f | |||
| a1512f3174 | |||
| 245751e2ce | |||
| 37001d9425 | |||
| 9d1f51c6ba | |||
| cb234fe1fc | |||
| cb85e0255b | |||
| 61b4cfdab7 | |||
| d2c405c126 | |||
| cbca560f92 | |||
| 2d7b63b4cf | |||
| 217038b085 | |||
| 13dd4edd6a | |||
| a7288b4fbf | |||
| 3020e8104e | |||
| 8fdeeaaf38 | |||
| 42616b59de | |||
| bf16681bea | |||
| 027190b5a4 | |||
| 241c02be30 | |||
| dd87268848 | |||
| f2ac24e623 | |||
| 80e0cac474 | |||
| 37273dd51c | |||
| 926a85fff0 | |||
| 70273ba2ba | |||
| 158cdeed57 | |||
| ba9595a1be | |||
| 347e3ff674 | |||
| 2b6fb46cdb | |||
| 465775bd55 | |||
| 44e82fc454 | |||
| c4963d0de8 | |||
| ff81d70cb1 | |||
| d7a543e143 | |||
| cba547083d | |||
| 47b1d2a2c2 | |||
| abc378954c | |||
| fdf871af17 | |||
| 83fcb0efdc | |||
| 0c43f3d15a | |||
| 88e087d50f | |||
| a9fb6eb8bc | |||
| 08acfdcd24 | |||
| 576eb9106f | |||
| ddd2c0ae4e | |||
| e58d7db03b | |||
| 1cac42aec5 | |||
| f94449a659 | |||
| df6afc957f | |||
| 99ffd3050c | |||
| 69dd82d329 | |||
| 076f71d490 | |||
| 33eae1e03a | |||
| 8a20510cde | |||
| c33b470fca | |||
| 29db5f1990 | |||
| f98f78a5bd | |||
| d258b42e01 | |||
| a6da32430f | |||
| cfae607310 | |||
| 7653e72e88 | |||
| f38b6636e3 | |||
| e42db121ea | |||
| 0adceaa3f0 | |||
| e6db1495ab | |||
| e6e494a92c | |||
| 549f95b259 | |||
| d92626071e | |||
| a7ac82b023 | |||
| 64b78b5822 | |||
| 8ba17db877 | |||
| 6820d9ae4e | |||
| 0bdc2fb05e | |||
| cf5598aeb9 | |||
| 8cf3d648ea | |||
| 212311a980 | |||
| c9522dc25d | |||
| 37af753402 | |||
| d8c5627cf8 | |||
| 4f926b37db | |||
| fefc16bd13 | |||
| 1b1b71a9b6 | |||
| 086532652e | |||
| 4e8b4720a1 | |||
| 4a7ada28fb | |||
| 1710285674 | |||
| a6bb61d998 | |||
| 5ec05dfa84 | |||
| 83e854aa13 | |||
| 634f809159 | |||
| e5cf141834 | |||
| 8610b68d3f | |||
| f3e3bddc94 | |||
| 7ef3284cc5 | |||
| 3494586f77 | |||
| faaf99e6bb | |||
| 1078ba2111 | |||
| 2ad69300f5 | |||
| d2f3fa7fdf | |||
| 64fcb6270b | |||
| 562c30cff4 | |||
| 7108501d24 | |||
| 37eae3406c | |||
| 501dc938e6 | |||
| c5ecd35fe9 | |||
| 7cd8d7f44d | |||
| 567a9a4e58 | |||
| 58f4a0cfbb | |||
| e6c0b697aa | |||
| 35f60d699d | |||
| c219be0970 | |||
| c72ce843fa | |||
| c606059a3a | |||
| 049a8bdc6d | |||
| 9752f744ca | |||
| 4be6fb789c | |||
| afc56e5259 | |||
| d47f8521d5 | |||
| 7f853d426a | |||
| e9008c615d | |||
| 01f081ef5a | |||
| 7ee174e0d5 | |||
| 24439f86e0 | |||
| fbd3ce3b72 | |||
| 96f8b54b51 | |||
| 9c94a78e29 | |||
| a14e3dd137 | |||
| e37673bd67 | |||
| 6aa10d20a1 | |||
| 68a92acb7a | |||
| 8aa7cc9ca5 | |||
| e6c087c3bb | |||
| 39a2097152 | |||
| 6a8003917e | |||
| d5a17ddc8c | |||
| 48bbf0d649 | |||
| 0bc58c254f | |||
| b2d41f0583 | |||
| 0d31d20f0f | |||
| 5154e31c1c | |||
| c67b5e950e | |||
| 8a7b5cc87d | |||
| bb7938f66d | |||
| 5b22e945da | |||
| decde230aa | |||
| 1dec8ae122 | |||
| 8512d5e693 | |||
| bb481ccfb4 | |||
| 12bce48ef5 | |||
| 013c7c776e | |||
| 8f96d20a23 | |||
| 1a8811b69a | |||
| d796849d74 | |||
| 942bd0859f | |||
| 072028c740 | |||
| 0d08aecd56 | |||
| 66b290577c | |||
| 22ad16e11b | |||
| 2f49a08c7d | |||
| fcacda74cb | |||
| fa0c90de70 | |||
| c1197314ac | |||
| 0b31792660 | |||
| 8b95dd65d9 | |||
| 691ed88096 | |||
| 836d772cd4 | |||
| 999ada03d1 | |||
| b35fabbe55 | |||
| 8cd8a157a6 | |||
| 86aece6828 | |||
| f9edadbafd | |||
| 6a388cd4fe | |||
| 9d17e9ff48 | |||
| 662b7d01b8 | |||
| a19bc4b4e4 | |||
| a545aa5c39 | |||
| fa451f362b | |||
| 868659a2f1 | |||
| 8ae62da138 | |||
| bedba39af9 | |||
| 8493e56b11 | |||
| 21c77dccce | |||
| 55164803b0 | |||
| c163f84aec | |||
| 2711b989e1 | |||
| 5c49a8ce6a | |||
| 854f308eae | |||
| 16ba6b53ba | |||
| 0af29a378a | |||
| def34a860b | |||
| f8034e1b78 | |||
| 01fbea02f1 | |||
| 3d9af89e24 | |||
| d430d9f3ed | |||
| 0c24a1e626 | |||
| 1099dbe642 | |||
| 2df3277dcd | |||
| 6ae14213f5 | |||
| 61bd029303 | |||
| 5b09bd8242 | |||
| 703477b157 | |||
| 03ff5d8ae1 | |||
| 220f7ef7cd | |||
| 682a99dd43 | |||
| fac5de582d | |||
| 7cbf9de8ca | |||
| ce213c3d89 | |||
| 32cd0360e6 | |||
| 1ec23a5699 | |||
| 48330f6432 | |||
| 28358debbc | |||
| 54b7ed6117 | |||
| 0cfd2ee63b | |||
| 37a0990741 | |||
| 7a0cd1eb34 | |||
| ac3277da09 | |||
| 65d1e7be56 | |||
| 80685afa7e | |||
| f892453892 | |||
| 422bb8c31c | |||
| 6fb1202c1c | |||
| 4ddd2788f0 | |||
| 8a28029809 | |||
| 423a2129d1 | |||
| a338097514 | |||
| 84b67abb03 | |||
| 5ec8406653 | |||
| b3ce300d32 | |||
| 3f93b93d9e | |||
| e32c83db63 | |||
| 0344a63b48 | |||
| 24923c0009 | |||
| a9036c9738 | |||
| f9f7fbed33 | |||
| 53b5bee736 | |||
| d0b3726905 | |||
| 7a6864507e | |||
| e20563f2e1 | |||
| fea5f8f3d4 | |||
| f9bb529b85 | |||
| 60e348fcc1 | |||
| f194c5be0e | |||
| 47712e63f1 | |||
| 790c1fb34a | |||
| 9cca731acc | |||
| 48f232790a | |||
| 3c55aa5f43 | |||
| 8c1edb30a6 | |||
| 5e64af4448 | |||
| 9f60017cfe | |||
| b6a86d11d2 | |||
| db86bfd63d | |||
| 7ff72a8920 | |||
| 2c4f86d148 | |||
| 1a9f26e804 | |||
| 42f8194bde | |||
| 8634b7058c | |||
| fc276b330a |
@@ -70,6 +70,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v3
|
uses: docker/build-push-action@v3
|
||||||
with:
|
with:
|
||||||
tags: ${{ github.event.inputs.tags || steps.meta.outputs.tags }}
|
tags: ${{ github.event.inputs.tags || steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
context: .
|
context: .
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: true
|
push: true
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
/ffmpeg*
|
/ffmpeg*
|
||||||
/ffprobe*
|
/ffprobe*
|
||||||
/unicode*
|
/unicode*
|
||||||
|
/libnusqlite3*
|
||||||
|
|
||||||
sw.*
|
sw.*
|
||||||
.DS_STORE
|
.DS_STORE
|
||||||
|
|||||||
+24
-9
@@ -11,20 +11,35 @@ FROM node:20-alpine
|
|||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
RUN apk update && \
|
RUN apk update && \
|
||||||
apk add --no-cache --update \
|
apk add --no-cache --update \
|
||||||
curl \
|
curl \
|
||||||
tzdata \
|
tzdata \
|
||||||
ffmpeg \
|
ffmpeg \
|
||||||
make \
|
make \
|
||||||
gcompat \
|
python3 \
|
||||||
python3 \
|
g++ \
|
||||||
g++ \
|
tini \
|
||||||
tini
|
unzip
|
||||||
|
|
||||||
COPY --from=build /client/dist /client/dist
|
COPY --from=build /client/dist /client/dist
|
||||||
COPY index.js package* /
|
COPY index.js package* /
|
||||||
COPY server server
|
COPY server server
|
||||||
|
|
||||||
|
ARG TARGETPLATFORM
|
||||||
|
|
||||||
|
ENV NUSQLITE3_DIR="/usr/local/lib/nusqlite3"
|
||||||
|
ENV NUSQLITE3_PATH="${NUSQLITE3_DIR}/libnusqlite3.so"
|
||||||
|
|
||||||
|
RUN case "$TARGETPLATFORM" in \
|
||||||
|
"linux/amd64") \
|
||||||
|
curl -L -o /tmp/library.zip "https://github.com/mikiher/nunicode-sqlite/releases/download/v1.2/libnusqlite3-linux-musl-x64.zip" ;; \
|
||||||
|
"linux/arm64") \
|
||||||
|
curl -L -o /tmp/library.zip "https://github.com/mikiher/nunicode-sqlite/releases/download/v1.2/libnusqlite3-linux-musl-arm64.zip" ;; \
|
||||||
|
*) echo "Unsupported platform: $TARGETPLATFORM" && exit 1 ;; \
|
||||||
|
esac && \
|
||||||
|
unzip /tmp/library.zip -d $NUSQLITE3_DIR && \
|
||||||
|
rm /tmp/library.zip
|
||||||
|
|
||||||
RUN npm ci --only=production
|
RUN npm ci --only=production
|
||||||
|
|
||||||
RUN apk del make python3 g++
|
RUN apk del make python3 g++
|
||||||
|
|||||||
@@ -264,7 +264,6 @@ export default {
|
|||||||
libraryItems.forEach((item) => {
|
libraryItems.forEach((item) => {
|
||||||
let subtitle = ''
|
let subtitle = ''
|
||||||
if (item.mediaType === 'book') subtitle = item.media.metadata.authors.map((au) => au.name).join(', ')
|
if (item.mediaType === 'book') subtitle = item.media.metadata.authors.map((au) => au.name).join(', ')
|
||||||
else if (item.mediaType === 'music') subtitle = item.media.metadata.artists.join(', ')
|
|
||||||
queueItems.push({
|
queueItems.push({
|
||||||
libraryItemId: item.id,
|
libraryItemId: item.id,
|
||||||
libraryId: item.libraryId,
|
libraryId: item.libraryId,
|
||||||
|
|||||||
@@ -347,6 +347,13 @@ export default {
|
|||||||
libraryItemsAdded(libraryItems) {
|
libraryItemsAdded(libraryItems) {
|
||||||
console.log('libraryItems added', libraryItems)
|
console.log('libraryItems added', libraryItems)
|
||||||
|
|
||||||
|
// First items added to library
|
||||||
|
const isThisLibrary = libraryItems.some((li) => li.libraryId === this.currentLibraryId)
|
||||||
|
if (!this.shelves.length && !this.search && isThisLibrary) {
|
||||||
|
this.fetchCategories()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const recentlyAddedShelf = this.shelves.find((shelf) => shelf.id === 'recently-added')
|
const recentlyAddedShelf = this.shelves.find((shelf) => shelf.id === 'recently-added')
|
||||||
if (!recentlyAddedShelf) return
|
if (!recentlyAddedShelf) return
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="shelf.type === 'authors'" class="flex items-center">
|
<div v-if="shelf.type === 'authors'" class="flex items-center">
|
||||||
<template v-for="entity in shelf.entities">
|
<template v-for="entity in shelf.entities">
|
||||||
<cards-author-card :key="entity.id" :author="entity" @hook:updated="updatedBookCard" class="mx-2e" @edit="editAuthor" />
|
<cards-author-card :key="entity.id" :authorMount="entity" @hook:updated="updatedBookCard" class="mx-2e" @edit="editAuthor" />
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="shelf.type === 'narrators'" class="flex items-center">
|
<div v-if="shelf.type === 'narrators'" class="flex items-center">
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
<p v-if="isCollectionsPage" class="text-sm">{{ $strings.ButtonCollections }}</p>
|
<p v-if="isCollectionsPage" class="text-sm">{{ $strings.ButtonCollections }}</p>
|
||||||
<span v-else class="material-symbols text-lg"></span>
|
<span v-else class="material-symbols text-lg"></span>
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
<nuxt-link v-if="isBookLibrary" :to="`/library/${currentLibraryId}/authors`" class="flex-grow h-full flex justify-center items-center" :class="isAuthorsPage ? 'bg-primary bg-opacity-80' : 'bg-primary bg-opacity-40'">
|
<nuxt-link v-if="isBookLibrary" :to="`/library/${currentLibraryId}/bookshelf/authors`" class="flex-grow h-full flex justify-center items-center" :class="isAuthorsPage ? 'bg-primary bg-opacity-80' : 'bg-primary bg-opacity-40'">
|
||||||
<p v-if="isAuthorsPage" class="text-sm">{{ $strings.ButtonAuthors }}</p>
|
<p v-if="isAuthorsPage" class="text-sm">{{ $strings.ButtonAuthors }}</p>
|
||||||
<svg v-else class="w-5 h-5" viewBox="0 0 24 24">
|
<svg v-else class="w-5 h-5" viewBox="0 0 24 24">
|
||||||
<path
|
<path
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
{{ seriesName }}
|
{{ seriesName }}
|
||||||
</p>
|
</p>
|
||||||
<div class="w-6 h-6 rounded-full bg-black bg-opacity-30 flex items-center justify-center ml-3">
|
<div class="w-6 h-6 rounded-full bg-black bg-opacity-30 flex items-center justify-center ml-3">
|
||||||
<span class="font-mono">{{ numShowing }}</span>
|
<span class="font-mono">{{ $formatNumber(numShowing) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-grow" />
|
<div class="flex-grow" />
|
||||||
|
|
||||||
@@ -62,8 +62,8 @@
|
|||||||
<ui-context-menu-dropdown v-if="!isBatchSelecting && seriesContextMenuItems.length" :items="seriesContextMenuItems" class="mx-px" @action="seriesContextMenuAction" />
|
<ui-context-menu-dropdown v-if="!isBatchSelecting && seriesContextMenuItems.length" :items="seriesContextMenuItems" class="mx-px" @action="seriesContextMenuAction" />
|
||||||
</template>
|
</template>
|
||||||
<!-- library & collections page -->
|
<!-- library & collections page -->
|
||||||
<template v-else-if="page !== 'search' && page !== 'podcast-search' && page !== 'recent-episodes' && !isHome">
|
<template v-else-if="page !== 'search' && page !== 'podcast-search' && page !== 'recent-episodes' && !isHome && !isAuthorsPage">
|
||||||
<p class="hidden md:block">{{ numShowing }} {{ entityName }}</p>
|
<p class="hidden md:block">{{ $formatNumber(numShowing) }} {{ entityName }}</p>
|
||||||
|
|
||||||
<div class="flex-grow hidden sm:inline-block" />
|
<div class="flex-grow hidden sm:inline-block" />
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
<controls-sort-select v-if="isSeriesPage && !isBatchSelecting" v-model="settings.seriesSortBy" :descending.sync="settings.seriesSortDesc" :items="seriesSortItems" class="w-36 sm:w-44 md:w-48 h-7.5 ml-1 sm:ml-4" @change="updateSeriesSort" />
|
<controls-sort-select v-if="isSeriesPage && !isBatchSelecting" v-model="settings.seriesSortBy" :descending.sync="settings.seriesSortDesc" :items="seriesSortItems" class="w-36 sm:w-44 md:w-48 h-7.5 ml-1 sm:ml-4" @change="updateSeriesSort" />
|
||||||
|
|
||||||
<!-- issues page remove all button -->
|
<!-- issues page remove all button -->
|
||||||
<ui-btn v-if="isIssuesFilter && userCanDelete && !isBatchSelecting" :loading="processingIssues" color="error" small class="ml-4" @click="removeAllIssues">{{ $strings.ButtonRemoveAll }} {{ numShowing }} {{ entityName }}</ui-btn>
|
<ui-btn v-if="isIssuesFilter && userCanDelete && !isBatchSelecting" :loading="processingIssues" color="error" small class="ml-4" @click="removeAllIssues">{{ $strings.ButtonRemoveAll }} {{ $formatNumber(numShowing) }} {{ entityName }}</ui-btn>
|
||||||
|
|
||||||
<ui-context-menu-dropdown v-if="contextMenuItems.length" :items="contextMenuItems" :menu-width="110" class="ml-2" @action="contextMenuAction" />
|
<ui-context-menu-dropdown v-if="contextMenuItems.length" :items="contextMenuItems" :menu-width="110" class="ml-2" @action="contextMenuAction" />
|
||||||
</template>
|
</template>
|
||||||
@@ -92,12 +92,14 @@
|
|||||||
<ui-context-menu-dropdown v-if="contextMenuItems.length" :items="contextMenuItems" :menu-width="110" class="ml-2" @action="contextMenuAction" />
|
<ui-context-menu-dropdown v-if="contextMenuItems.length" :items="contextMenuItems" :menu-width="110" class="ml-2" @action="contextMenuAction" />
|
||||||
</template>
|
</template>
|
||||||
<!-- authors page -->
|
<!-- authors page -->
|
||||||
<template v-else-if="page === 'authors'">
|
<template v-else-if="isAuthorsPage">
|
||||||
<div class="flex-grow" />
|
<p class="hidden md:block">{{ $formatNumber(numShowing) }} {{ entityName }}</p>
|
||||||
<ui-btn v-if="userCanUpdate && authors?.length && !isBatchSelecting" :loading="processingAuthors" color="primary" small @click="matchAllAuthors">{{ $strings.ButtonMatchAllAuthors }}</ui-btn>
|
|
||||||
|
<div class="flex-grow hidden sm:inline-block" />
|
||||||
|
<ui-btn v-if="userCanUpdate && !isBatchSelecting" :loading="processingAuthors" color="primary" small @click="matchAllAuthors">{{ $strings.ButtonMatchAllAuthors }}</ui-btn>
|
||||||
|
|
||||||
<!-- author sort select -->
|
<!-- author sort select -->
|
||||||
<controls-sort-select v-if="authors?.length" v-model="settings.authorSortBy" :descending.sync="settings.authorSortDesc" :items="authorSortItems" class="w-36 sm:w-44 md:w-48 h-7.5 ml-1 sm:ml-4" @change="updateAuthorSort" />
|
<controls-sort-select v-model="settings.authorSortBy" :descending.sync="settings.authorSortDesc" :items="authorSortItems" class="w-36 sm:w-44 md:w-48 h-7.5 ml-1 sm:ml-4" @change="updateAuthorSort" />
|
||||||
</template>
|
</template>
|
||||||
<!-- home page -->
|
<!-- home page -->
|
||||||
<template v-else-if="isHome">
|
<template v-else-if="isHome">
|
||||||
@@ -117,11 +119,7 @@ export default {
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: () => null
|
default: () => null
|
||||||
},
|
},
|
||||||
searchQuery: String,
|
searchQuery: String
|
||||||
authors: {
|
|
||||||
type: Array,
|
|
||||||
default: () => []
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -246,9 +244,6 @@ export default {
|
|||||||
isPodcastLibrary() {
|
isPodcastLibrary() {
|
||||||
return this.currentLibraryMediaType === 'podcast'
|
return this.currentLibraryMediaType === 'podcast'
|
||||||
},
|
},
|
||||||
isMusicLibrary() {
|
|
||||||
return this.currentLibraryMediaType === 'music'
|
|
||||||
},
|
|
||||||
isLibraryPage() {
|
isLibraryPage() {
|
||||||
return this.page === ''
|
return this.page === ''
|
||||||
},
|
},
|
||||||
@@ -271,7 +266,7 @@ export default {
|
|||||||
return this.$route.name === 'library-library-podcast-latest'
|
return this.$route.name === 'library-library-podcast-latest'
|
||||||
},
|
},
|
||||||
isAuthorsPage() {
|
isAuthorsPage() {
|
||||||
return this.$route.name === 'library-library-authors'
|
return this.page === 'authors'
|
||||||
},
|
},
|
||||||
isAlbumsPage() {
|
isAlbumsPage() {
|
||||||
return this.page === 'albums'
|
return this.page === 'albums'
|
||||||
@@ -281,13 +276,13 @@ export default {
|
|||||||
},
|
},
|
||||||
entityName() {
|
entityName() {
|
||||||
if (this.isAlbumsPage) return 'Albums'
|
if (this.isAlbumsPage) return 'Albums'
|
||||||
if (this.isMusicLibrary) return 'Tracks'
|
|
||||||
|
|
||||||
if (this.isPodcastLibrary) return this.$strings.LabelPodcasts
|
if (this.isPodcastLibrary) return this.$strings.LabelPodcasts
|
||||||
if (!this.page) return this.$strings.LabelBooks
|
if (!this.page) return this.$strings.LabelBooks
|
||||||
if (this.isSeriesPage) return this.$strings.LabelSeries
|
if (this.isSeriesPage) return this.$strings.LabelSeries
|
||||||
if (this.isCollectionsPage) return this.$strings.LabelCollections
|
if (this.isCollectionsPage) return this.$strings.LabelCollections
|
||||||
if (this.isPlaylistsPage) return this.$strings.LabelPlaylists
|
if (this.isPlaylistsPage) return this.$strings.LabelPlaylists
|
||||||
|
if (this.isAuthorsPage) return this.$strings.LabelAuthors
|
||||||
return ''
|
return ''
|
||||||
},
|
},
|
||||||
seriesId() {
|
seriesId() {
|
||||||
@@ -477,42 +472,54 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to re-add series to continue listening', error)
|
console.error('Failed to re-add series to continue listening', error)
|
||||||
this.$toast.error(this.$strings.ToastItemUpdateFailed)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.processingSeries = false
|
this.processingSeries = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
async fetchAllAuthors() {
|
||||||
|
// fetch all authors from the server, in the order that they are currently displayed
|
||||||
|
const response = await this.$axios.$get(`/api/libraries/${this.currentLibraryId}/authors?sort=${this.settings.authorSortBy}&desc=${this.settings.authorSortDesc}`)
|
||||||
|
return response.authors
|
||||||
|
},
|
||||||
async matchAllAuthors() {
|
async matchAllAuthors() {
|
||||||
this.processingAuthors = true
|
this.processingAuthors = true
|
||||||
|
|
||||||
for (const author of this.authors) {
|
try {
|
||||||
const payload = {}
|
const authors = await this.fetchAllAuthors()
|
||||||
if (author.asin) payload.asin = author.asin
|
|
||||||
else payload.q = author.name
|
|
||||||
|
|
||||||
payload.region = 'us'
|
for (const author of authors) {
|
||||||
if (this.libraryProvider.startsWith('audible.')) {
|
const payload = {}
|
||||||
payload.region = this.libraryProvider.split('.').pop() || 'us'
|
if (author.asin) payload.asin = author.asin
|
||||||
|
else payload.q = author.name
|
||||||
|
|
||||||
|
payload.region = 'us'
|
||||||
|
if (this.libraryProvider.startsWith('audible.')) {
|
||||||
|
payload.region = this.libraryProvider.split('.').pop() || 'us'
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$eventBus.$emit(`searching-author-${author.id}`, true)
|
||||||
|
|
||||||
|
var response = await this.$axios.$post(`/api/authors/${author.id}/match`, payload).catch((error) => {
|
||||||
|
console.error('Failed', error)
|
||||||
|
return null
|
||||||
|
})
|
||||||
|
if (!response) {
|
||||||
|
console.error(`Author ${author.name} not found`)
|
||||||
|
this.$toast.error(this.$getString('ToastAuthorNotFound', [author.name]))
|
||||||
|
} else if (response.updated) {
|
||||||
|
if (response.author.imagePath) console.log(`Author ${response.author.name} was updated`)
|
||||||
|
else console.log(`Author ${response.author.name} was updated (no image found)`)
|
||||||
|
} else {
|
||||||
|
console.log(`No updates were made for Author ${response.author.name}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$eventBus.$emit(`searching-author-${author.id}`, false)
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
this.$eventBus.$emit(`searching-author-${author.id}`, true)
|
console.error('Failed to match all authors', error)
|
||||||
|
this.$toast.error(this.$strings.ToastMatchAllAuthorsFailed)
|
||||||
var response = await this.$axios.$post(`/api/authors/${author.id}/match`, payload).catch((error) => {
|
|
||||||
console.error('Failed', error)
|
|
||||||
return null
|
|
||||||
})
|
|
||||||
if (!response) {
|
|
||||||
console.error(`Author ${author.name} not found`)
|
|
||||||
this.$toast.error(this.$getString('ToastAuthorNotFound', [author.name]))
|
|
||||||
} else if (response.updated) {
|
|
||||||
if (response.author.imagePath) console.log(`Author ${response.author.name} was updated`)
|
|
||||||
else console.log(`Author ${response.author.name} was updated (no image found)`)
|
|
||||||
} else {
|
|
||||||
console.log(`No updates were made for Author ${response.author.name}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$eventBus.$emit(`searching-author-${author.id}`, false)
|
|
||||||
}
|
}
|
||||||
this.processingAuthors = false
|
this.processingAuthors = false
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ export default {
|
|||||||
if (this.page === 'series') return this.$strings.MessageBookshelfNoSeries
|
if (this.page === 'series') return this.$strings.MessageBookshelfNoSeries
|
||||||
if (this.page === 'collections') return this.$strings.MessageBookshelfNoCollections
|
if (this.page === 'collections') return this.$strings.MessageBookshelfNoCollections
|
||||||
if (this.page === 'playlists') return this.$strings.MessageNoUserPlaylists
|
if (this.page === 'playlists') return this.$strings.MessageNoUserPlaylists
|
||||||
|
if (this.page === 'authors') return this.$strings.MessageNoAuthors
|
||||||
if (this.hasFilter) {
|
if (this.hasFilter) {
|
||||||
if (this.filterName === 'Issues') return this.$strings.MessageNoIssues
|
if (this.filterName === 'Issues') return this.$strings.MessageNoIssues
|
||||||
else if (this.filterName === 'Feed-open') return this.$strings.MessageBookshelfNoRSSFeeds
|
else if (this.filterName === 'Feed-open') return this.$strings.MessageBookshelfNoRSSFeeds
|
||||||
@@ -111,6 +112,12 @@ export default {
|
|||||||
seriesFilterBy() {
|
seriesFilterBy() {
|
||||||
return this.$store.getters['user/getUserSetting']('seriesFilterBy')
|
return this.$store.getters['user/getUserSetting']('seriesFilterBy')
|
||||||
},
|
},
|
||||||
|
authorSortBy() {
|
||||||
|
return this.$store.getters['user/getUserSetting']('authorSortBy')
|
||||||
|
},
|
||||||
|
authorSortDesc() {
|
||||||
|
return !!this.$store.getters['user/getUserSetting']('authorSortDesc')
|
||||||
|
},
|
||||||
orderBy() {
|
orderBy() {
|
||||||
return this.$store.getters['user/getUserSetting']('orderBy')
|
return this.$store.getters['user/getUserSetting']('orderBy')
|
||||||
},
|
},
|
||||||
@@ -217,6 +224,8 @@ export default {
|
|||||||
this.$store.commit('globals/setEditCollection', entity)
|
this.$store.commit('globals/setEditCollection', entity)
|
||||||
} else if (this.entityName === 'playlists') {
|
} else if (this.entityName === 'playlists') {
|
||||||
this.$store.commit('globals/setEditPlaylist', entity)
|
this.$store.commit('globals/setEditPlaylist', entity)
|
||||||
|
} else if (this.entityName === 'authors') {
|
||||||
|
this.$store.commit('globals/showEditAuthorModal', entity)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
clearSelectedEntities() {
|
clearSelectedEntities() {
|
||||||
@@ -457,6 +466,9 @@ export default {
|
|||||||
if (this.collapseBookSeries) {
|
if (this.collapseBookSeries) {
|
||||||
searchParams.set('collapseseries', 1)
|
searchParams.set('collapseseries', 1)
|
||||||
}
|
}
|
||||||
|
} else if (this.page === 'authors') {
|
||||||
|
searchParams.set('sort', this.authorSortBy)
|
||||||
|
searchParams.set('desc', this.authorSortDesc ? 1 : 0)
|
||||||
} else {
|
} else {
|
||||||
if (this.filterBy && this.filterBy !== 'all') {
|
if (this.filterBy && this.filterBy !== 'all') {
|
||||||
searchParams.set('filter', this.filterBy)
|
searchParams.set('filter', this.filterBy)
|
||||||
@@ -601,6 +613,34 @@ export default {
|
|||||||
this.executeRebuild()
|
this.executeRebuild()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
authorAdded(author) {
|
||||||
|
if (this.entityName !== 'authors') return
|
||||||
|
console.log(`[LazyBookshelf] authorAdded ${author.id}`, author)
|
||||||
|
this.resetEntities()
|
||||||
|
},
|
||||||
|
authorUpdated(author) {
|
||||||
|
if (this.entityName !== 'authors') return
|
||||||
|
console.log(`[LazyBookshelf] authorUpdated ${author.id}`, author)
|
||||||
|
const indexOf = this.entities.findIndex((ent) => ent && ent.id === author.id)
|
||||||
|
if (indexOf >= 0) {
|
||||||
|
this.entities[indexOf] = author
|
||||||
|
if (this.entityComponentRefs[indexOf]) {
|
||||||
|
this.entityComponentRefs[indexOf].setEntity(author)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
authorRemoved(author) {
|
||||||
|
if (this.entityName !== 'authors') return
|
||||||
|
console.log(`[LazyBookshelf] authorRemoved ${author.id}`, author)
|
||||||
|
const indexOf = this.entities.findIndex((ent) => ent && ent.id === author.id)
|
||||||
|
if (indexOf >= 0) {
|
||||||
|
this.entities = this.entities.filter((ent) => ent.id !== author.id)
|
||||||
|
this.totalEntities--
|
||||||
|
this.$eventBus.$emit('bookshelf-total-entities', this.totalEntities)
|
||||||
|
this.executeRebuild()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
shareOpen(mediaItemShare) {
|
shareOpen(mediaItemShare) {
|
||||||
if (this.entityName === 'items' || this.entityName === 'series-books') {
|
if (this.entityName === 'items' || this.entityName === 'series-books') {
|
||||||
var indexOf = this.entities.findIndex((ent) => ent?.media?.id === mediaItemShare.mediaItemId)
|
var indexOf = this.entities.findIndex((ent) => ent?.media?.id === mediaItemShare.mediaItemId)
|
||||||
@@ -727,6 +767,9 @@ export default {
|
|||||||
this.$root.socket.on('playlist_added', this.playlistAdded)
|
this.$root.socket.on('playlist_added', this.playlistAdded)
|
||||||
this.$root.socket.on('playlist_updated', this.playlistUpdated)
|
this.$root.socket.on('playlist_updated', this.playlistUpdated)
|
||||||
this.$root.socket.on('playlist_removed', this.playlistRemoved)
|
this.$root.socket.on('playlist_removed', this.playlistRemoved)
|
||||||
|
this.$root.socket.on('author_added', this.authorAdded)
|
||||||
|
this.$root.socket.on('author_updated', this.authorUpdated)
|
||||||
|
this.$root.socket.on('author_removed', this.authorRemoved)
|
||||||
this.$root.socket.on('share_open', this.shareOpen)
|
this.$root.socket.on('share_open', this.shareOpen)
|
||||||
this.$root.socket.on('share_closed', this.shareClosed)
|
this.$root.socket.on('share_closed', this.shareClosed)
|
||||||
} else {
|
} else {
|
||||||
@@ -756,6 +799,9 @@ export default {
|
|||||||
this.$root.socket.off('playlist_added', this.playlistAdded)
|
this.$root.socket.off('playlist_added', this.playlistAdded)
|
||||||
this.$root.socket.off('playlist_updated', this.playlistUpdated)
|
this.$root.socket.off('playlist_updated', this.playlistUpdated)
|
||||||
this.$root.socket.off('playlist_removed', this.playlistRemoved)
|
this.$root.socket.off('playlist_removed', this.playlistRemoved)
|
||||||
|
this.$root.socket.off('author_added', this.authorAdded)
|
||||||
|
this.$root.socket.off('author_updated', this.authorUpdated)
|
||||||
|
this.$root.socket.off('author_removed', this.authorRemoved)
|
||||||
this.$root.socket.off('share_open', this.shareOpen)
|
this.$root.socket.off('share_open', this.shareOpen)
|
||||||
this.$root.socket.off('share_closed', this.shareClosed)
|
this.$root.socket.off('share_closed', this.shareClosed)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="streamLibraryItem" id="mediaPlayerContainer" class="w-full fixed bottom-0 left-0 right-0 h-48 lg:h-40 z-50 bg-primary px-2 lg:px-4 pb-1 lg:pb-4 pt-2">
|
<div v-if="streamLibraryItem" id="mediaPlayerContainer" class="w-full fixed bottom-0 left-0 right-0 h-48 lg:h-40 z-50 bg-primary px-2 lg:px-4 pb-1 lg:pb-4 pt-2">
|
||||||
<div id="videoDock" />
|
|
||||||
<div class="absolute left-2 top-2 lg:left-4 cursor-pointer">
|
<div class="absolute left-2 top-2 lg:left-4 cursor-pointer">
|
||||||
<covers-book-cover expand-on-click :library-item="streamLibraryItem" :width="bookCoverWidth" :book-cover-aspect-ratio="coverAspectRatio" />
|
<covers-book-cover expand-on-click :library-item="streamLibraryItem" :width="bookCoverWidth" :book-cover-aspect-ratio="coverAspectRatio" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-start mb-6 lg:mb-0" :class="playerHandler.isVideo ? 'ml-4 pl-96' : isSquareCover ? 'pl-18 sm:pl-24' : 'pl-12 sm:pl-16'">
|
<div class="flex items-start mb-6 lg:mb-0" :class="isSquareCover ? 'pl-18 sm:pl-24' : 'pl-12 sm:pl-16'">
|
||||||
<div class="min-w-0 w-full">
|
<div class="min-w-0 w-full">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<nuxt-link :to="`/item/${streamLibraryItem.id}`" class="hover:underline cursor-pointer text-sm sm:text-lg block truncate">
|
<nuxt-link :to="`/item/${streamLibraryItem.id}`" class="hover:underline cursor-pointer text-sm sm:text-lg block truncate">
|
||||||
@@ -12,10 +11,9 @@
|
|||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
<widgets-explicit-indicator v-if="isExplicit" />
|
<widgets-explicit-indicator v-if="isExplicit" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!playerHandler.isVideo" class="text-gray-400 flex items-center w-1/2 sm:w-4/5 lg:w-2/5">
|
<div class="text-gray-400 flex items-center w-1/2 sm:w-4/5 lg:w-2/5">
|
||||||
<span class="material-symbols text-sm">person</span>
|
<span class="material-symbols text-sm">person</span>
|
||||||
<div v-if="podcastAuthor" class="pl-1 sm:pl-1.5 text-xs sm:text-base">{{ podcastAuthor }}</div>
|
<div v-if="podcastAuthor" class="pl-1 sm:pl-1.5 text-xs sm:text-base">{{ podcastAuthor }}</div>
|
||||||
<div v-else-if="musicArtists" class="pl-1 sm:pl-1.5 text-xs sm:text-base">{{ musicArtists }}</div>
|
|
||||||
<div v-else-if="authors.length" class="pl-1 sm:pl-1.5 text-xs sm:text-base truncate">
|
<div v-else-if="authors.length" class="pl-1 sm:pl-1.5 text-xs sm:text-base truncate">
|
||||||
<nuxt-link v-for="(author, index) in authors" :key="index" :to="`/author/${author.id}`" class="hover:underline">{{ author.name }}<span v-if="index < authors.length - 1">, </span></nuxt-link>
|
<nuxt-link v-for="(author, index) in authors" :key="index" :to="`/author/${author.id}`" class="hover:underline">{{ author.name }}<span v-if="index < authors.length - 1">, </span></nuxt-link>
|
||||||
</div>
|
</div>
|
||||||
@@ -140,9 +138,6 @@ export default {
|
|||||||
isPodcast() {
|
isPodcast() {
|
||||||
return this.streamLibraryItem?.mediaType === 'podcast'
|
return this.streamLibraryItem?.mediaType === 'podcast'
|
||||||
},
|
},
|
||||||
isMusic() {
|
|
||||||
return this.streamLibraryItem?.mediaType === 'music'
|
|
||||||
},
|
|
||||||
isExplicit() {
|
isExplicit() {
|
||||||
return !!this.mediaMetadata.explicit
|
return !!this.mediaMetadata.explicit
|
||||||
},
|
},
|
||||||
@@ -172,11 +167,7 @@ export default {
|
|||||||
},
|
},
|
||||||
podcastAuthor() {
|
podcastAuthor() {
|
||||||
if (!this.isPodcast) return null
|
if (!this.isPodcast) return null
|
||||||
return this.mediaMetadata.author || 'Unknown'
|
return this.mediaMetadata.author || this.$strings.LabelUnknown
|
||||||
},
|
|
||||||
musicArtists() {
|
|
||||||
if (!this.isMusic) return null
|
|
||||||
return this.mediaMetadata.artists.join(', ')
|
|
||||||
},
|
},
|
||||||
hasNextItemInQueue() {
|
hasNextItemInQueue() {
|
||||||
return this.currentPlayerQueueIndex < this.playerQueueItems.length - 1
|
return this.currentPlayerQueueIndex < this.playerQueueItems.length - 1
|
||||||
@@ -260,7 +251,7 @@ export default {
|
|||||||
sleepTimerEnd() {
|
sleepTimerEnd() {
|
||||||
this.clearSleepTimer()
|
this.clearSleepTimer()
|
||||||
this.playerHandler.pause()
|
this.playerHandler.pause()
|
||||||
this.$toast.info('Sleep Timer Done.. zZzzZz')
|
this.$toast.info(this.$strings.ToastSleepTimerDone)
|
||||||
},
|
},
|
||||||
cancelSleepTimer() {
|
cancelSleepTimer() {
|
||||||
this.showSleepTimerModal = false
|
this.showSleepTimerModal = false
|
||||||
@@ -534,7 +525,7 @@ export default {
|
|||||||
},
|
},
|
||||||
showFailedProgressSyncs() {
|
showFailedProgressSyncs() {
|
||||||
if (!isNaN(this.syncFailedToast)) this.$toast.dismiss(this.syncFailedToast)
|
if (!isNaN(this.syncFailedToast)) this.$toast.dismiss(this.syncFailedToast)
|
||||||
this.syncFailedToast = this.$toast('Progress is not being synced. Restart playback', { timeout: false, type: 'error' })
|
this.syncFailedToast = this.$toast(this.$strings.ToastProgressIsNotBeingSynced, { timeout: false, type: 'error' })
|
||||||
},
|
},
|
||||||
sessionClosedEvent(sessionId) {
|
sessionClosedEvent(sessionId) {
|
||||||
if (this.playerHandler.currentSessionId === sessionId) {
|
if (this.playerHandler.currentSessionId === sessionId) {
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
<div v-show="isPlaylistsPage" class="h-full w-0.5 bg-yellow-400 absolute top-0 left-0" />
|
<div v-show="isPlaylistsPage" class="h-full w-0.5 bg-yellow-400 absolute top-0 left-0" />
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
|
|
||||||
<nuxt-link v-if="isBookLibrary" :to="`/library/${currentLibraryId}/authors`" class="w-full h-20 flex flex-col items-center justify-center text-white text-opacity-80 border-b border-primary border-opacity-70 hover:bg-primary cursor-pointer relative" :class="isAuthorsPage ? 'bg-primary bg-opacity-80' : 'bg-bg bg-opacity-60'">
|
<nuxt-link v-if="isBookLibrary" :to="`/library/${currentLibraryId}/bookshelf/authors`" class="w-full h-20 flex flex-col items-center justify-center text-white text-opacity-80 border-b border-primary border-opacity-70 hover:bg-primary cursor-pointer relative" :class="isAuthorsPage ? 'bg-primary bg-opacity-80' : 'bg-bg bg-opacity-60'">
|
||||||
<svg class="w-6 h-6" viewBox="0 0 24 24">
|
<svg class="w-6 h-6" viewBox="0 0 24 24">
|
||||||
<path
|
<path
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
@@ -95,14 +95,6 @@
|
|||||||
<div v-show="isPodcastSearchPage" class="h-full w-0.5 bg-yellow-400 absolute top-0 left-0" />
|
<div v-show="isPodcastSearchPage" class="h-full w-0.5 bg-yellow-400 absolute top-0 left-0" />
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
|
|
||||||
<nuxt-link v-if="isMusicLibrary" :to="`/library/${currentLibraryId}/bookshelf/albums`" class="w-full h-20 flex flex-col items-center justify-center text-white text-opacity-80 border-b border-primary border-opacity-70 hover:bg-primary cursor-pointer relative" :class="isMusicAlbumsPage ? 'bg-primary bg-opacity-80' : 'bg-bg bg-opacity-60'">
|
|
||||||
<span class="material-symbols text-xl">album</span>
|
|
||||||
|
|
||||||
<p class="pt-1.5 text-center leading-4" style="font-size: 0.9rem">Albums</p>
|
|
||||||
|
|
||||||
<div v-show="isMusicAlbumsPage" class="h-full w-0.5 bg-yellow-400 absolute top-0 left-0" />
|
|
||||||
</nuxt-link>
|
|
||||||
|
|
||||||
<nuxt-link v-if="isPodcastLibrary && userIsAdminOrUp" :to="`/library/${currentLibraryId}/podcast/download-queue`" class="w-full h-20 flex flex-col items-center justify-center text-white text-opacity-80 border-b border-primary border-opacity-70 hover:bg-primary cursor-pointer relative" :class="isPodcastDownloadQueuePage ? 'bg-primary bg-opacity-80' : 'bg-bg bg-opacity-60'">
|
<nuxt-link v-if="isPodcastLibrary && userIsAdminOrUp" :to="`/library/${currentLibraryId}/podcast/download-queue`" class="w-full h-20 flex flex-col items-center justify-center text-white text-opacity-80 border-b border-primary border-opacity-70 hover:bg-primary cursor-pointer relative" :class="isPodcastDownloadQueuePage ? 'bg-primary bg-opacity-80' : 'bg-bg bg-opacity-60'">
|
||||||
<span class="material-symbols text-2xl"></span>
|
<span class="material-symbols text-2xl"></span>
|
||||||
|
|
||||||
@@ -172,9 +164,6 @@ export default {
|
|||||||
isPodcastLibrary() {
|
isPodcastLibrary() {
|
||||||
return this.currentLibraryMediaType === 'podcast'
|
return this.currentLibraryMediaType === 'podcast'
|
||||||
},
|
},
|
||||||
isMusicLibrary() {
|
|
||||||
return this.currentLibraryMediaType === 'music'
|
|
||||||
},
|
|
||||||
isPodcastDownloadQueuePage() {
|
isPodcastDownloadQueuePage() {
|
||||||
return this.$route.name === 'library-library-podcast-download-queue'
|
return this.$route.name === 'library-library-podcast-download-queue'
|
||||||
},
|
},
|
||||||
@@ -184,9 +173,6 @@ export default {
|
|||||||
isPodcastLatestPage() {
|
isPodcastLatestPage() {
|
||||||
return this.$route.name === 'library-library-podcast-latest'
|
return this.$route.name === 'library-library-podcast-latest'
|
||||||
},
|
},
|
||||||
isMusicAlbumsPage() {
|
|
||||||
return this.paramId === 'albums'
|
|
||||||
},
|
|
||||||
homePage() {
|
homePage() {
|
||||||
return this.$route.name === 'library-library'
|
return this.$route.name === 'library-library'
|
||||||
},
|
},
|
||||||
@@ -194,7 +180,7 @@ export default {
|
|||||||
return this.$route.name === 'library-library-series-id' || this.paramId === 'series'
|
return this.$route.name === 'library-library-series-id' || this.paramId === 'series'
|
||||||
},
|
},
|
||||||
isAuthorsPage() {
|
isAuthorsPage() {
|
||||||
return this.$route.name === 'library-library-authors'
|
return this.libraryBookshelfPage && this.paramId === 'authors'
|
||||||
},
|
},
|
||||||
isNarratorsPage() {
|
isNarratorsPage() {
|
||||||
return this.$route.name === 'library-library-narrators'
|
return this.$route.name === 'library-library-narrators'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :style="{ minWidth: cardWidth + 'px', maxWidth: cardWidth + 'px' }">
|
<div class="pb-3e" :style="{ minWidth: cardWidth + 'px', maxWidth: cardWidth + 'px' }">
|
||||||
<nuxt-link :to="`/author/${author.id}`">
|
<nuxt-link :to="`/author/${author?.id}`">
|
||||||
<div cy-id="card" @mouseover="mouseover" @mouseleave="mouseleave">
|
<div cy-id="card" @mouseover="mouseover" @mouseleave="mouseleave">
|
||||||
<div cy-id="imageArea" :style="{ height: cardHeight + 'px' }" class="bg-primary box-shadow-book rounded-md relative overflow-hidden">
|
<div cy-id="imageArea" :style="{ height: cardHeight + 'px' }" class="bg-primary box-shadow-book rounded-md relative overflow-hidden">
|
||||||
<!-- Image or placeholder -->
|
<!-- Image or placeholder -->
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
author: {
|
authorMount: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {}
|
default: () => {}
|
||||||
},
|
},
|
||||||
@@ -57,7 +57,8 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
searching: false,
|
searching: false,
|
||||||
isHovering: false
|
isHovering: false,
|
||||||
|
author: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -68,34 +69,37 @@ export default {
|
|||||||
return this.height * this.sizeMultiplier
|
return this.height * this.sizeMultiplier
|
||||||
},
|
},
|
||||||
userToken() {
|
userToken() {
|
||||||
return this.$store.getters['user/getToken']
|
return this.store.getters['user/getToken']
|
||||||
},
|
},
|
||||||
_author() {
|
_author() {
|
||||||
return this.author || {}
|
return this.author || {}
|
||||||
},
|
},
|
||||||
authorId() {
|
authorId() {
|
||||||
return this._author.id
|
return this._author?.id || ''
|
||||||
},
|
},
|
||||||
name() {
|
name() {
|
||||||
return this._author.name || ''
|
return this._author?.name || ''
|
||||||
},
|
},
|
||||||
asin() {
|
asin() {
|
||||||
return this._author.asin || ''
|
return this._author?.asin || ''
|
||||||
},
|
},
|
||||||
numBooks() {
|
numBooks() {
|
||||||
return this._author.numBooks || 0
|
return this._author?.numBooks || 0
|
||||||
|
},
|
||||||
|
store() {
|
||||||
|
return this.$store || this.$nuxt.$store
|
||||||
},
|
},
|
||||||
userCanUpdate() {
|
userCanUpdate() {
|
||||||
return this.$store.getters['user/getUserCanUpdate']
|
return this.store.getters['user/getUserCanUpdate']
|
||||||
},
|
},
|
||||||
currentLibraryId() {
|
currentLibraryId() {
|
||||||
return this.$store.state.libraries.currentLibraryId
|
return this.store.state.libraries.currentLibraryId
|
||||||
},
|
},
|
||||||
libraryProvider() {
|
libraryProvider() {
|
||||||
return this.$store.getters['libraries/getLibraryProvider'](this.currentLibraryId) || 'google'
|
return this.store.getters['libraries/getLibraryProvider'](this.currentLibraryId) || 'google'
|
||||||
},
|
},
|
||||||
sizeMultiplier() {
|
sizeMultiplier() {
|
||||||
return this.$store.getters['user/getSizeMultiplier']
|
return this.store.getters['user/getSizeMultiplier']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -121,24 +125,54 @@ export default {
|
|||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
if (!response) {
|
if (!response) {
|
||||||
this.$toast.error(`Author ${this.name} not found`)
|
this.$toast.error(this.$getString('ToastAuthorNotFound', [this.name]))
|
||||||
} else if (response.updated) {
|
} else if (response.updated) {
|
||||||
if (response.author.imagePath) this.$toast.success(`Author ${response.author.name} was updated`)
|
if (response.author.imagePath) {
|
||||||
else this.$toast.success(`Author ${response.author.name} was updated (no image found)`)
|
this.$toast.success(this.$strings.ToastAuthorUpdateSuccess)
|
||||||
|
} else {
|
||||||
|
this.$toast.success(this.$strings.ToastAuthorUpdateSuccessNoImageFound)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.$toast.info(`No updates were made for Author ${response.author.name}`)
|
this.$toast.info(this.$strings.ToastNoUpdatesNecessary)
|
||||||
}
|
}
|
||||||
this.searching = false
|
this.searching = false
|
||||||
},
|
},
|
||||||
setSearching(isSearching) {
|
setSearching(isSearching) {
|
||||||
this.searching = isSearching
|
this.searching = isSearching
|
||||||
}
|
},
|
||||||
|
setEntity(author) {
|
||||||
|
this.removeListeners()
|
||||||
|
this.author = author
|
||||||
|
this.addListeners()
|
||||||
|
},
|
||||||
|
addListeners() {
|
||||||
|
if (this.author) {
|
||||||
|
this.$eventBus.$on(`searching-author-${this.authorId}`, this.setSearching)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeListeners() {
|
||||||
|
if (this.author) {
|
||||||
|
this.$eventBus.$off(`searching-author-${this.authorId}`, this.setSearching)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
destroy() {
|
||||||
|
// destroy the vue listeners, etc
|
||||||
|
this.$destroy()
|
||||||
|
|
||||||
|
// remove the element from the DOM
|
||||||
|
if (this.$el && this.$el.parentNode) {
|
||||||
|
this.$el.parentNode.removeChild(this.$el)
|
||||||
|
} else if (this.$el && this.$el.remove) {
|
||||||
|
this.$el.remove()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setSelectionMode(val) {}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$eventBus.$on(`searching-author-${this.authorId}`, this.setSearching)
|
if (this.authorMount) this.setEntity(this.authorMount)
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.$eventBus.$off(`searching-author-${this.authorId}`, this.setSearching)
|
this.removeListeners()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
<p class="truncate text-sm">{{ title }}</p>
|
<p class="truncate text-sm">{{ title }}</p>
|
||||||
|
|
||||||
<p class="truncate text-xs text-gray-300">{{ description }}</p>
|
<p class="truncate text-xs text-gray-300">{{ description }}</p>
|
||||||
|
<p v-if="specialMessage" class="truncate text-xs text-gray-300">{{ specialMessage }}</p>
|
||||||
|
|
||||||
<p v-if="isFailed && failedMessage" class="text-xs truncate text-red-500">{{ failedMessage }}</p>
|
<p v-if="isFailed && failedMessage" class="text-xs truncate text-red-500">{{ failedMessage }}</p>
|
||||||
<p v-else-if="!isFinished && cancelingScan" class="text-xs truncate">Canceling...</p>
|
<p v-else-if="!isFinished && cancelingScan" class="text-xs truncate">Canceling...</p>
|
||||||
@@ -26,7 +27,16 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
cancelingScan: false
|
cancelingScan: false,
|
||||||
|
specialMessage: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
task: {
|
||||||
|
immediate: true,
|
||||||
|
handler() {
|
||||||
|
this.initTask()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -34,14 +44,17 @@ export default {
|
|||||||
return this.$store.getters['user/getIsAdminOrUp']
|
return this.$store.getters['user/getIsAdminOrUp']
|
||||||
},
|
},
|
||||||
title() {
|
title() {
|
||||||
|
if (this.task.titleKey && this.$strings[this.task.titleKey]) {
|
||||||
|
return this.$getString(this.task.titleKey, this.task.titleSubs)
|
||||||
|
}
|
||||||
return this.task.title || 'No Title'
|
return this.task.title || 'No Title'
|
||||||
},
|
},
|
||||||
description() {
|
description() {
|
||||||
|
if (this.task.descriptionKey && this.$strings[this.task.descriptionKey]) {
|
||||||
|
return this.$getString(this.task.descriptionKey, this.task.descriptionSubs)
|
||||||
|
}
|
||||||
return this.task.description || ''
|
return this.task.description || ''
|
||||||
},
|
},
|
||||||
details() {
|
|
||||||
return this.task.details || 'Unknown'
|
|
||||||
},
|
|
||||||
isFinished() {
|
isFinished() {
|
||||||
return !!this.task.isFinished
|
return !!this.task.isFinished
|
||||||
},
|
},
|
||||||
@@ -52,6 +65,9 @@ export default {
|
|||||||
return this.isFinished && !this.isFailed
|
return this.isFinished && !this.isFailed
|
||||||
},
|
},
|
||||||
failedMessage() {
|
failedMessage() {
|
||||||
|
if (this.task.errorKey && this.$strings[this.task.errorKey]) {
|
||||||
|
return this.$getString(this.task.errorKey, this.task.errorSubs)
|
||||||
|
}
|
||||||
return this.task.error || ''
|
return this.task.error || ''
|
||||||
},
|
},
|
||||||
action() {
|
action() {
|
||||||
@@ -87,6 +103,21 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
initTask() {
|
||||||
|
// special message for library scan tasks
|
||||||
|
if (this.task?.data?.scanResults) {
|
||||||
|
const scanResults = this.task.data.scanResults
|
||||||
|
const strs = []
|
||||||
|
if (scanResults.added) strs.push(this.$getString('MessageTaskScanItemsAdded', [scanResults.added]))
|
||||||
|
if (scanResults.updated) strs.push(this.$getString('MessageTaskScanItemsUpdated', [scanResults.updated]))
|
||||||
|
if (scanResults.missing) strs.push(this.$getString('MessageTaskScanItemsMissing', [scanResults.missing]))
|
||||||
|
const changesDetected = strs.length > 0 ? strs.join(', ') : this.$strings.MessageTaskScanNoChangesNeeded
|
||||||
|
const timeElapsed = scanResults.elapsed ? ` (${this.$elapsedPretty(scanResults.elapsed / 1000, false, true)})` : ''
|
||||||
|
this.specialMessage = `${changesDetected}${timeElapsed}`
|
||||||
|
} else {
|
||||||
|
this.specialMessage = ''
|
||||||
|
}
|
||||||
|
},
|
||||||
cancelScan() {
|
cancelScan() {
|
||||||
const libraryId = this.task?.data?.libraryId
|
const libraryId = this.task?.data?.libraryId
|
||||||
if (!libraryId) {
|
if (!libraryId) {
|
||||||
|
|||||||
@@ -226,9 +226,6 @@ export default {
|
|||||||
isPodcast() {
|
isPodcast() {
|
||||||
return this.mediaType === 'podcast' || this.store.getters['libraries/getCurrentLibraryMediaType'] === 'podcast'
|
return this.mediaType === 'podcast' || this.store.getters['libraries/getCurrentLibraryMediaType'] === 'podcast'
|
||||||
},
|
},
|
||||||
isMusic() {
|
|
||||||
return this.mediaType === 'music'
|
|
||||||
},
|
|
||||||
isExplicit() {
|
isExplicit() {
|
||||||
return this.mediaMetadata.explicit || false
|
return this.mediaMetadata.explicit || false
|
||||||
},
|
},
|
||||||
@@ -328,7 +325,7 @@ export default {
|
|||||||
},
|
},
|
||||||
displaySubtitle() {
|
displaySubtitle() {
|
||||||
if (!this.libraryItem) return '\u00A0'
|
if (!this.libraryItem) return '\u00A0'
|
||||||
if (this.collapsedSeries) return this.collapsedSeries.numBooks === 1 ? '1 book' : `${this.collapsedSeries.numBooks} books`
|
if (this.collapsedSeries) return `${this.collapsedSeries.numBooks} ${this.$strings.LabelBooks}`
|
||||||
if (this.mediaMetadata.subtitle) return this.mediaMetadata.subtitle
|
if (this.mediaMetadata.subtitle) return this.mediaMetadata.subtitle
|
||||||
if (this.mediaMetadata.seriesName) return this.mediaMetadata.seriesName
|
if (this.mediaMetadata.seriesName) return this.mediaMetadata.seriesName
|
||||||
return ''
|
return ''
|
||||||
@@ -336,7 +333,6 @@ export default {
|
|||||||
displayLineTwo() {
|
displayLineTwo() {
|
||||||
if (this.recentEpisode) return this.title
|
if (this.recentEpisode) return this.title
|
||||||
if (this.isPodcast) return this.author
|
if (this.isPodcast) return this.author
|
||||||
if (this.isMusic) return this.artist
|
|
||||||
if (this.collapsedSeries) return ''
|
if (this.collapsedSeries) return ''
|
||||||
if (this.isAuthorBookshelfView) {
|
if (this.isAuthorBookshelfView) {
|
||||||
return this.mediaMetadata.publishedYear || ''
|
return this.mediaMetadata.publishedYear || ''
|
||||||
@@ -364,7 +360,6 @@ export default {
|
|||||||
return this.store.getters['user/getUserMediaProgress'](this.libraryItemId, this.recentEpisode.id)
|
return this.store.getters['user/getUserMediaProgress'](this.libraryItemId, this.recentEpisode.id)
|
||||||
},
|
},
|
||||||
userProgress() {
|
userProgress() {
|
||||||
if (this.isMusic) return null
|
|
||||||
if (this.episodeProgress) return this.episodeProgress
|
if (this.episodeProgress) return this.episodeProgress
|
||||||
return this.store.getters['user/getUserMediaProgress'](this.libraryItemId)
|
return this.store.getters['user/getUserMediaProgress'](this.libraryItemId)
|
||||||
},
|
},
|
||||||
@@ -420,7 +415,7 @@ export default {
|
|||||||
return !this.isSelectionMode && !this.showPlayButton && this.ebookFormat
|
return !this.isSelectionMode && !this.showPlayButton && this.ebookFormat
|
||||||
},
|
},
|
||||||
showPlayButton() {
|
showPlayButton() {
|
||||||
return !this.isSelectionMode && !this.isMissing && !this.isInvalid && !this.isStreaming && (this.numTracks || this.recentEpisode || this.isMusic)
|
return !this.isSelectionMode && !this.isMissing && !this.isInvalid && !this.isStreaming && (this.numTracks || this.recentEpisode)
|
||||||
},
|
},
|
||||||
showSmallEBookIcon() {
|
showSmallEBookIcon() {
|
||||||
return !this.isSelectionMode && this.ebookFormat
|
return !this.isSelectionMode && this.ebookFormat
|
||||||
@@ -464,8 +459,6 @@ export default {
|
|||||||
return this.store.getters['user/getIsAdminOrUp']
|
return this.store.getters['user/getIsAdminOrUp']
|
||||||
},
|
},
|
||||||
moreMenuItems() {
|
moreMenuItems() {
|
||||||
if (this.isMusic) return []
|
|
||||||
|
|
||||||
if (this.recentEpisode) {
|
if (this.recentEpisode) {
|
||||||
const items = [
|
const items = [
|
||||||
{
|
{
|
||||||
@@ -823,7 +816,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to remove series from home', error)
|
console.error('Failed to remove series from home', error)
|
||||||
this.$toast.error(this.$strings.ToastFailedToUpdateUser)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.processing = false
|
this.processing = false
|
||||||
@@ -841,7 +834,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to hide item from home', error)
|
console.error('Failed to hide item from home', error)
|
||||||
this.$toast.error(this.$strings.ToastFailedToUpdateUser)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.processing = false
|
this.processing = false
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to update notification', error)
|
console.error('Failed to update notification', error)
|
||||||
this.$toast.error(this.$strings.ToastNotificationUpdateFailed)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.enabling = false
|
this.enabling = false
|
||||||
|
|||||||
@@ -27,38 +27,6 @@
|
|||||||
<nuxt-link :to="`/library/${libraryId}/bookshelf?filter=publishers.${$encode(publisher)}`" class="hover:underline">{{ publisher }}</nuxt-link>
|
<nuxt-link :to="`/library/${libraryId}/bookshelf?filter=publishers.${$encode(publisher)}`" class="hover:underline">{{ publisher }}</nuxt-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="musicAlbum" class="flex py-0.5">
|
|
||||||
<div class="w-24 min-w-24 sm:w-32 sm:min-w-32">
|
|
||||||
<span class="text-white text-opacity-60 uppercase text-sm">Album</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{{ musicAlbum }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="musicAlbumArtist" class="flex py-0.5">
|
|
||||||
<div class="w-24 min-w-24 sm:w-32 sm:min-w-32">
|
|
||||||
<span class="text-white text-opacity-60 uppercase text-sm">Album Artist</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{{ musicAlbumArtist }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="musicTrackPretty" class="flex py-0.5">
|
|
||||||
<div class="w-24 min-w-24 sm:w-32 sm:min-w-32">
|
|
||||||
<span class="text-white text-opacity-60 uppercase text-sm">Track</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{{ musicTrackPretty }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="musicDiscPretty" class="flex py-0.5">
|
|
||||||
<div class="w-24 min-w-24 sm:w-32 sm:min-w-32">
|
|
||||||
<span class="text-white text-opacity-60 uppercase text-sm">Disc</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{{ musicDiscPretty }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="podcastType" class="flex py-0.5">
|
<div v-if="podcastType" class="flex py-0.5">
|
||||||
<div class="w-24 min-w-24 sm:w-32 sm:min-w-32">
|
<div class="w-24 min-w-24 sm:w-32 sm:min-w-32">
|
||||||
<span class="text-white text-opacity-60 uppercase text-sm">{{ $strings.LabelPodcastType }}</span>
|
<span class="text-white text-opacity-60 uppercase text-sm">{{ $strings.LabelPodcastType }}</span>
|
||||||
@@ -97,7 +65,7 @@
|
|||||||
<nuxt-link :to="`/library/${libraryId}/bookshelf?filter=languages.${$encode(language)}`" class="hover:underline">{{ language }}</nuxt-link>
|
<nuxt-link :to="`/library/${libraryId}/bookshelf?filter=languages.${$encode(language)}`" class="hover:underline">{{ language }}</nuxt-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="tracks.length || audioFile || (isPodcast && totalPodcastDuration)" class="flex py-0.5">
|
<div v-if="tracks.length || (isPodcast && totalPodcastDuration)" class="flex py-0.5">
|
||||||
<div class="w-24 min-w-24 sm:w-32 sm:min-w-32">
|
<div class="w-24 min-w-24 sm:w-32 sm:min-w-32">
|
||||||
<span class="text-white text-opacity-60 uppercase text-sm">{{ $strings.LabelDuration }}</span>
|
<span class="text-white text-opacity-60 uppercase text-sm">{{ $strings.LabelDuration }}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -134,10 +102,6 @@ export default {
|
|||||||
isPodcast() {
|
isPodcast() {
|
||||||
return this.libraryItem.mediaType === 'podcast'
|
return this.libraryItem.mediaType === 'podcast'
|
||||||
},
|
},
|
||||||
audioFile() {
|
|
||||||
// Music track
|
|
||||||
return this.media.audioFile
|
|
||||||
},
|
|
||||||
media() {
|
media() {
|
||||||
return this.libraryItem.media || {}
|
return this.libraryItem.media || {}
|
||||||
},
|
},
|
||||||
@@ -168,25 +132,6 @@ export default {
|
|||||||
publisher() {
|
publisher() {
|
||||||
return this.mediaMetadata.publisher || ''
|
return this.mediaMetadata.publisher || ''
|
||||||
},
|
},
|
||||||
musicArtists() {
|
|
||||||
return this.mediaMetadata.artists || []
|
|
||||||
},
|
|
||||||
musicAlbum() {
|
|
||||||
return this.mediaMetadata.album || ''
|
|
||||||
},
|
|
||||||
musicAlbumArtist() {
|
|
||||||
return this.mediaMetadata.albumArtist || ''
|
|
||||||
},
|
|
||||||
musicTrackPretty() {
|
|
||||||
if (!this.mediaMetadata.trackNumber) return null
|
|
||||||
if (!this.mediaMetadata.trackTotal) return this.mediaMetadata.trackNumber
|
|
||||||
return `${this.mediaMetadata.trackNumber} / ${this.mediaMetadata.trackTotal}`
|
|
||||||
},
|
|
||||||
musicDiscPretty() {
|
|
||||||
if (!this.mediaMetadata.discNumber) return null
|
|
||||||
if (!this.mediaMetadata.discTotal) return this.mediaMetadata.discNumber
|
|
||||||
return `${this.mediaMetadata.discNumber} / ${this.mediaMetadata.discTotal}`
|
|
||||||
},
|
|
||||||
narrators() {
|
narrators() {
|
||||||
return this.mediaMetadata.narrators || []
|
return this.mediaMetadata.narrators || []
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -98,9 +98,6 @@ export default {
|
|||||||
isPodcast() {
|
isPodcast() {
|
||||||
return this.libraryMediaType === 'podcast'
|
return this.libraryMediaType === 'podcast'
|
||||||
},
|
},
|
||||||
isMusic() {
|
|
||||||
return this.libraryMediaType === 'music'
|
|
||||||
},
|
|
||||||
seriesItems() {
|
seriesItems() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@@ -192,6 +189,12 @@ export default {
|
|||||||
value: 'publishers',
|
value: 'publishers',
|
||||||
sublist: true
|
sublist: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: this.$strings.LabelPublishedDecade,
|
||||||
|
textPlural: this.$strings.LabelPublishedDecades,
|
||||||
|
value: 'publishedDecades',
|
||||||
|
sublist: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
text: this.$strings.LabelLanguage,
|
text: this.$strings.LabelLanguage,
|
||||||
textPlural: this.$strings.LabelLanguages,
|
textPlural: this.$strings.LabelLanguages,
|
||||||
@@ -274,35 +277,9 @@ export default {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
musicItems() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
text: this.$strings.LabelAll,
|
|
||||||
value: 'all'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: this.$strings.LabelGenre,
|
|
||||||
textPlural: this.$strings.LabelGenres,
|
|
||||||
value: 'genres',
|
|
||||||
sublist: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: this.$strings.LabelTag,
|
|
||||||
textPlural: this.$strings.LabelTags,
|
|
||||||
value: 'tags',
|
|
||||||
sublist: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: this.$strings.ButtonIssues,
|
|
||||||
value: 'issues',
|
|
||||||
sublist: false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
selectItems() {
|
selectItems() {
|
||||||
if (this.isSeries) return this.seriesItems
|
if (this.isSeries) return this.seriesItems
|
||||||
if (this.isPodcast) return this.podcastItems
|
if (this.isPodcast) return this.podcastItems
|
||||||
if (this.isMusic) return this.musicItems
|
|
||||||
return this.bookItems
|
return this.bookItems
|
||||||
},
|
},
|
||||||
selectedItemSublist() {
|
selectedItemSublist() {
|
||||||
@@ -367,6 +344,9 @@ export default {
|
|||||||
publishers() {
|
publishers() {
|
||||||
return this.filterData.publishers || []
|
return this.filterData.publishers || []
|
||||||
},
|
},
|
||||||
|
publishedDecades() {
|
||||||
|
return this.filterData.publishedDecades || []
|
||||||
|
},
|
||||||
progress() {
|
progress() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@@ -433,21 +413,17 @@ export default {
|
|||||||
id: 'isbn',
|
id: 'isbn',
|
||||||
name: 'ISBN'
|
name: 'ISBN'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 'subtitle',
|
|
||||||
name: this.$strings.LabelSubtitle
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: 'authors',
|
id: 'authors',
|
||||||
name: this.$strings.LabelAuthor
|
name: this.$strings.LabelAuthor
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'publishedYear',
|
id: 'chapters',
|
||||||
name: this.$strings.LabelPublishYear
|
name: this.$strings.LabelChapters
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'series',
|
id: 'cover',
|
||||||
name: this.$strings.LabelSeries
|
name: this.$strings.LabelCover
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'description',
|
id: 'description',
|
||||||
@@ -458,24 +434,32 @@ export default {
|
|||||||
name: this.$strings.LabelGenres
|
name: this.$strings.LabelGenres
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tags',
|
id: 'language',
|
||||||
name: this.$strings.LabelTags
|
name: this.$strings.LabelLanguage
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'narrators',
|
id: 'narrators',
|
||||||
name: this.$strings.LabelNarrator
|
name: this.$strings.LabelNarrator
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'publishedYear',
|
||||||
|
name: this.$strings.LabelPublishYear
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'publisher',
|
id: 'publisher',
|
||||||
name: this.$strings.LabelPublisher
|
name: this.$strings.LabelPublisher
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'language',
|
id: 'series',
|
||||||
name: this.$strings.LabelLanguage
|
name: this.$strings.LabelSeries
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'cover',
|
id: 'subtitle',
|
||||||
name: this.$strings.LabelCover
|
name: this.$strings.LabelSubtitle
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'tags',
|
||||||
|
name: this.$strings.LabelTags
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -56,9 +56,6 @@ export default {
|
|||||||
isPodcast() {
|
isPodcast() {
|
||||||
return this.libraryMediaType === 'podcast'
|
return this.libraryMediaType === 'podcast'
|
||||||
},
|
},
|
||||||
isMusic() {
|
|
||||||
return this.libraryMediaType === 'music'
|
|
||||||
},
|
|
||||||
podcastItems() {
|
podcastItems() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@@ -148,40 +145,10 @@ export default {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
musicItems() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
text: this.$strings.LabelTitle,
|
|
||||||
value: 'media.metadata.title'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: this.$strings.LabelAddedAt,
|
|
||||||
value: 'addedAt'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: this.$strings.LabelSize,
|
|
||||||
value: 'size'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: this.$strings.LabelDuration,
|
|
||||||
value: 'media.duration'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: this.$strings.LabelFileBirthtime,
|
|
||||||
value: 'birthtimeMs'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: this.$strings.LabelFileModified,
|
|
||||||
value: 'mtimeMs'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
selectItems() {
|
selectItems() {
|
||||||
let items = null
|
let items = null
|
||||||
if (this.isPodcast) {
|
if (this.isPodcast) {
|
||||||
items = this.podcastItems
|
items = this.podcastItems
|
||||||
} else if (this.isMusic) {
|
|
||||||
items = this.musicItems
|
|
||||||
} else if (this.$store.getters['user/getUserSetting']('filterBy').startsWith('series.')) {
|
} else if (this.$store.getters['user/getUserSetting']('filterBy').startsWith('series.')) {
|
||||||
items = this.seriesItems
|
items = this.seriesItems
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="wrapper" class="relative ml-4 sm:ml-8" v-click-outside="clickOutside">
|
<div ref="wrapper" class="relative ml-4 sm:ml-8" v-click-outside="clickOutside">
|
||||||
<div class="flex items-center justify-center text-gray-300 cursor-pointer h-full" @mousedown.prevent @mouseup.prevent @click="setShowMenu(true)">
|
<div class="flex items-center justify-center text-gray-300 cursor-pointer h-full" @mousedown.prevent @mouseup.prevent @click="setShowMenu(true)">
|
||||||
<span class="font-mono uppercase text-gray-200 text-sm sm:text-base">{{ playbackRate.toFixed(1) }}<span class="text-base">x</span></span>
|
<span class="text-gray-200 text-sm sm:text-base">{{ playbackRate.toFixed(1) }}<span class="text-base">x</span></span>
|
||||||
</div>
|
</div>
|
||||||
<div v-show="showMenu" class="absolute -top-20 z-20 bg-bg border-black-200 border shadow-xl rounded-lg" :style="{ left: menuLeft + 'px' }">
|
<div v-show="showMenu" class="absolute -top-[5.5rem] z-20 bg-bg border-black-200 border shadow-xl rounded-lg" :style="{ left: menuLeft + 'px' }">
|
||||||
<div class="absolute -bottom-1.5 right-0 w-full flex justify-center" :style="{ left: arrowLeft + 'px' }">
|
<div class="absolute -bottom-1.5 right-0 w-full flex justify-center" :style="{ left: arrowLeft + 'px' }">
|
||||||
<div class="arrow-down" />
|
<div class="arrow-down" />
|
||||||
</div>
|
</div>
|
||||||
@@ -11,12 +11,12 @@
|
|||||||
<template v-for="rate in rates">
|
<template v-for="rate in rates">
|
||||||
<div :key="rate" class="h-full border-black-300 w-11 cursor-pointer border rounded-sm" :class="value === rate ? 'bg-black-100' : 'hover:bg-black hover:bg-opacity-10'" style="min-width: 44px; max-width: 44px" @click="set(rate)">
|
<div :key="rate" class="h-full border-black-300 w-11 cursor-pointer border rounded-sm" :class="value === rate ? 'bg-black-100' : 'hover:bg-black hover:bg-opacity-10'" style="min-width: 44px; max-width: 44px" @click="set(rate)">
|
||||||
<div class="w-full h-full flex justify-center items-center">
|
<div class="w-full h-full flex justify-center items-center">
|
||||||
<p class="text-xs text-center font-mono">{{ rate }}<span class="text-sm">x</span></p>
|
<p class="text-xs text-center">{{ rate }}<span class="text-sm">x</span></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full py-1 px-4">
|
<div class="w-full py-1 px-1">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<ui-icon-btn :disabled="!canDecrement" icon="remove" @click="decrement" />
|
<ui-icon-btn :disabled="!canDecrement" icon="remove" @click="decrement" />
|
||||||
<p class="px-2 text-2xl sm:text-3xl">{{ playbackRate }}<span class="text-2xl">x</span></p>
|
<p class="px-2 text-2xl sm:text-3xl">{{ playbackRate }}<span class="text-2xl">x</span></p>
|
||||||
@@ -41,7 +41,7 @@ export default {
|
|||||||
currentPlaybackRate: 0,
|
currentPlaybackRate: 0,
|
||||||
MIN_SPEED: 0.5,
|
MIN_SPEED: 0.5,
|
||||||
MAX_SPEED: 10,
|
MAX_SPEED: 10,
|
||||||
menuLeft: -92,
|
menuLeft: -96,
|
||||||
arrowLeft: 0
|
arrowLeft: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -89,9 +89,9 @@ export default {
|
|||||||
if (boundingBox.left + 110 > window.innerWidth - 10) {
|
if (boundingBox.left + 110 > window.innerWidth - 10) {
|
||||||
this.menuLeft = window.innerWidth - 230 - boundingBox.left
|
this.menuLeft = window.innerWidth - 230 - boundingBox.left
|
||||||
|
|
||||||
this.arrowLeft = Math.abs(this.menuLeft) - 92
|
this.arrowLeft = Math.abs(this.menuLeft) - 96
|
||||||
} else {
|
} else {
|
||||||
this.menuLeft = -92
|
this.menuLeft = -96
|
||||||
this.arrowLeft = 0
|
this.arrowLeft = 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
<span class="material-symbols text-2xl sm:text-3xl">{{ volumeIcon }}</span>
|
<span class="material-symbols text-2xl sm:text-3xl">{{ volumeIcon }}</span>
|
||||||
</button>
|
</button>
|
||||||
<transition name="menux">
|
<transition name="menux">
|
||||||
<div v-show="isOpen" class="volumeMenu h-6 absolute bottom-2 w-28 px-2 bg-bg shadow-sm rounded-lg" style="left: -116px">
|
<div v-show="isOpen" class="volumeMenu h-28 absolute bottom-2 w-6 py-2 bg-bg shadow-sm rounded-lg" style="top: -116px">
|
||||||
<div ref="volumeTrack" class="h-1 w-full bg-gray-500 my-2.5 relative cursor-pointer rounded-full" @mousedown="mousedownTrack" @click="clickVolumeTrack">
|
<div ref="volumeTrack" class="w-1 h-full bg-gray-500 mx-2.5 relative cursor-pointer rounded-full" @mousedown="mousedownTrack" @click="clickVolumeTrack">
|
||||||
<div class="bg-gray-100 h-full absolute left-0 top-0 pointer-events-none rounded-full" :style="{ width: volume * trackWidth + 'px' }" />
|
<div class="bg-gray-100 w-full absolute left-0 bottom-0 pointer-events-none rounded-full" :style="{ height: volume * trackHeight + 'px' }" />
|
||||||
<div class="w-2.5 h-2.5 bg-white shadow-sm rounded-full absolute pointer-events-none" :class="isDragging ? 'transform scale-125 origin-center' : ''" :style="{ left: cursorLeft + 'px', top: '-3px' }" />
|
<div class="w-2.5 h-2.5 bg-white shadow-sm rounded-full absolute pointer-events-none" :class="isDragging ? 'transform scale-125 origin-center' : ''" :style="{ bottom: cursorBottom + 'px', left: '-3px' }" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
@@ -24,10 +24,10 @@ export default {
|
|||||||
isOpen: false,
|
isOpen: false,
|
||||||
isDragging: false,
|
isDragging: false,
|
||||||
isHovering: false,
|
isHovering: false,
|
||||||
posX: 0,
|
posY: 0,
|
||||||
lastValue: 0.5,
|
lastValue: 0.5,
|
||||||
isMute: false,
|
isMute: false,
|
||||||
trackWidth: 112 - 20,
|
trackHeight: 112 - 20,
|
||||||
openTimeout: null
|
openTimeout: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -45,9 +45,9 @@ export default {
|
|||||||
this.$emit('input', val)
|
this.$emit('input', val)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
cursorLeft() {
|
cursorBottom() {
|
||||||
var left = this.trackWidth * this.volume
|
var bottom = this.trackHeight * this.volume
|
||||||
return left - 3
|
return bottom - 3
|
||||||
},
|
},
|
||||||
volumeIcon() {
|
volumeIcon() {
|
||||||
if (this.volume <= 0) return 'volume_mute'
|
if (this.volume <= 0) return 'volume_mute'
|
||||||
@@ -89,17 +89,10 @@ export default {
|
|||||||
}, 600)
|
}, 600)
|
||||||
},
|
},
|
||||||
mousemove(e) {
|
mousemove(e) {
|
||||||
var diff = this.posX - e.x
|
var diff = this.posY - e.y
|
||||||
this.posX = e.x
|
this.posY = e.y
|
||||||
var volShift = 0
|
var volShift = diff / this.trackHeight
|
||||||
if (diff < 0) {
|
var newVol = this.volume + volShift
|
||||||
// Volume up
|
|
||||||
volShift = diff / this.trackWidth
|
|
||||||
} else {
|
|
||||||
// volume down
|
|
||||||
volShift = diff / this.trackWidth
|
|
||||||
}
|
|
||||||
var newVol = this.volume - volShift
|
|
||||||
newVol = Math.min(Math.max(0, newVol), 1)
|
newVol = Math.min(Math.max(0, newVol), 1)
|
||||||
this.volume = newVol
|
this.volume = newVol
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
@@ -113,8 +106,8 @@ export default {
|
|||||||
},
|
},
|
||||||
mousedownTrack(e) {
|
mousedownTrack(e) {
|
||||||
this.isDragging = true
|
this.isDragging = true
|
||||||
this.posX = e.x
|
this.posY = e.y
|
||||||
var vol = e.offsetX / this.trackWidth
|
var vol = 1 - e.offsetY / this.trackHeight
|
||||||
vol = Math.min(Math.max(vol, 0), 1)
|
vol = Math.min(Math.max(vol, 0), 1)
|
||||||
this.volume = vol
|
this.volume = vol
|
||||||
document.body.addEventListener('mousemove', this.mousemove)
|
document.body.addEventListener('mousemove', this.mousemove)
|
||||||
@@ -137,7 +130,7 @@ export default {
|
|||||||
this.clickVolumeIcon()
|
this.clickVolumeIcon()
|
||||||
},
|
},
|
||||||
clickVolumeTrack(e) {
|
clickVolumeTrack(e) {
|
||||||
var vol = e.offsetX / this.trackWidth
|
var vol = 1 - e.offsetY / this.trackHeight
|
||||||
vol = Math.min(Math.max(vol, 0), 1)
|
vol = Math.min(Math.max(vol, 0), 1)
|
||||||
this.volume = vol
|
this.volume = vol
|
||||||
}
|
}
|
||||||
@@ -147,7 +140,7 @@ export default {
|
|||||||
this.isMute = true
|
this.isMute = true
|
||||||
}
|
}
|
||||||
const storageVolume = localStorage.getItem('volume')
|
const storageVolume = localStorage.getItem('volume')
|
||||||
if (storageVolume) {
|
if (storageVolume && !isNaN(storageVolume)) {
|
||||||
this.volume = parseFloat(storageVolume)
|
this.volume = parseFloat(storageVolume)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -56,24 +56,15 @@ export default {
|
|||||||
},
|
},
|
||||||
imgSrc() {
|
imgSrc() {
|
||||||
if (!this.imagePath) return null
|
if (!this.imagePath) return null
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
return `${this.$config.routerBasePath}/api/authors/${this.authorId}/image?token=${this.userToken}&ts=${this.updatedAt}`
|
||||||
// Testing
|
|
||||||
return `http://localhost:3333${this.$config.routerBasePath}/api/authors/${this.authorId}/image?token=${this.userToken}&ts=${this.updatedAt}`
|
|
||||||
}
|
|
||||||
return `/api/authors/${this.authorId}/image?token=${this.userToken}&ts=${this.updatedAt}`
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
imageLoaded() {
|
imageLoaded() {
|
||||||
var aspectRatio = 1.25
|
|
||||||
if (this.$refs.wrapper) {
|
|
||||||
aspectRatio = this.$refs.wrapper.clientHeight / this.$refs.wrapper.clientWidth
|
|
||||||
}
|
|
||||||
if (this.$refs.img) {
|
if (this.$refs.img) {
|
||||||
var { naturalWidth, naturalHeight } = this.$refs.img
|
var { naturalWidth, naturalHeight } = this.$refs.img
|
||||||
var imgAr = naturalHeight / naturalWidth
|
var imgAr = naturalHeight / naturalWidth
|
||||||
var arDiff = Math.abs(imgAr - aspectRatio)
|
if (imgAr < 0.5 || imgAr > 2) {
|
||||||
if (arDiff > 0.15) {
|
|
||||||
this.showCoverBg = true
|
this.showCoverBg = true
|
||||||
} else {
|
} else {
|
||||||
this.showCoverBg = false
|
this.showCoverBg = false
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ export default {
|
|||||||
.then((data) => {
|
.then((data) => {
|
||||||
this.processing = false
|
this.processing = false
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
this.$toast.error(`${this.$strings.ToastAccountUpdateFailed}: ${data.error}`)
|
this.$toast.error(`${this.$strings.ToastFailedToUpdate}: ${data.error}`)
|
||||||
} else {
|
} else {
|
||||||
console.log('Account updated', data.user)
|
console.log('Account updated', data.user)
|
||||||
|
|
||||||
@@ -313,7 +313,7 @@ export default {
|
|||||||
this.processing = false
|
this.processing = false
|
||||||
console.error('Failed to update account', error)
|
console.error('Failed to update account', error)
|
||||||
var errMsg = error.response ? error.response.data || '' : ''
|
var errMsg = error.response ? error.response.data || '' : ''
|
||||||
this.$toast.error(errMsg || this.$strings.ToastFailedToUpdateAccount)
|
this.$toast.error(errMsg || this.$strings.ToastFailedToUpdate)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
submitCreateAccount() {
|
submitCreateAccount() {
|
||||||
@@ -351,7 +351,7 @@ export default {
|
|||||||
update: type === 'admin',
|
update: type === 'admin',
|
||||||
delete: type === 'admin',
|
delete: type === 'admin',
|
||||||
upload: type === 'admin',
|
upload: type === 'admin',
|
||||||
accessExplicitContent: true,
|
accessExplicitContent: type === 'admin',
|
||||||
accessAllLibraries: true,
|
accessAllLibraries: true,
|
||||||
accessAllTags: true,
|
accessAllTags: true,
|
||||||
selectedTagsNotAccessible: false
|
selectedTagsNotAccessible: false
|
||||||
@@ -386,7 +386,7 @@ export default {
|
|||||||
upload: false,
|
upload: false,
|
||||||
accessAllLibraries: true,
|
accessAllLibraries: true,
|
||||||
accessAllTags: true,
|
accessAllTags: true,
|
||||||
accessExplicitContent: true,
|
accessExplicitContent: false,
|
||||||
selectedTagsNotAccessible: false
|
selectedTagsNotAccessible: false
|
||||||
},
|
},
|
||||||
librariesAccessible: [],
|
librariesAccessible: [],
|
||||||
|
|||||||
@@ -116,10 +116,10 @@ export default {
|
|||||||
libraryItemIds: this.selectedBookIds
|
libraryItemIds: this.selectedBookIds
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$toast.info('Batch quick match of ' + this.selectedBookIds.length + ' books started!')
|
this.$toast.info(this.$getString('ToastBatchQuickMatchStarted', [this.selectedBookIds.length]))
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
this.$toast.error('Batch quick match failed')
|
this.$toast.error(this.$strings.ToastBatchQuickMatchFailed)
|
||||||
console.error('Failed to batch quick match', error)
|
console.error('Failed to batch quick match', error)
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ export default {
|
|||||||
this.$toast.success(this.$strings.ToastBookmarkUpdateSuccess)
|
this.$toast.success(this.$strings.ToastBookmarkUpdateSuccess)
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
this.$toast.error(this.$strings.ToastBookmarkUpdateFailed)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
console.error(error)
|
console.error(error)
|
||||||
})
|
})
|
||||||
this.show = false
|
this.show = false
|
||||||
|
|||||||
@@ -112,11 +112,11 @@ export default {
|
|||||||
return this.$store.state.user.user
|
return this.$store.state.user.user
|
||||||
},
|
},
|
||||||
demoShareUrl() {
|
demoShareUrl() {
|
||||||
return `${window.origin}/share/${this.newShareSlug}`
|
return `${window.origin}${this.$config.routerBasePath}/share/${this.newShareSlug}`
|
||||||
},
|
},
|
||||||
currentShareUrl() {
|
currentShareUrl() {
|
||||||
if (!this.currentShare) return ''
|
if (!this.currentShare) return ''
|
||||||
return `${window.origin}/share/${this.currentShare.slug}`
|
return `${window.origin}${this.$config.routerBasePath}/share/${this.currentShare.slug}`
|
||||||
},
|
},
|
||||||
currentShareTimeRemaining() {
|
currentShareTimeRemaining() {
|
||||||
if (!this.currentShare) return 'Error'
|
if (!this.currentShare) return 'Error'
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ export default {
|
|||||||
var result = await this.$axios.$patch(`/api/authors/${this.authorId}`, updatePayload).catch((error) => {
|
var result = await this.$axios.$patch(`/api/authors/${this.authorId}`, updatePayload).catch((error) => {
|
||||||
console.error('Failed', error)
|
console.error('Failed', error)
|
||||||
const errorMsg = error.response ? error.response.data : null
|
const errorMsg = error.response ? error.response.data : null
|
||||||
this.$toast.error(errorMsg || this.$strings.ToastAuthorUpdateFailed)
|
this.$toast.error(errorMsg || this.$strings.ToastFailedToUpdate)
|
||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
if (result) {
|
if (result) {
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ export default {
|
|||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to update collection', error)
|
console.error('Failed to update collection', error)
|
||||||
this.processing = false
|
this.processing = false
|
||||||
this.$toast.error(this.$strings.ToastCollectionUpdateFailed)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to update device', error)
|
console.error('Failed to update device', error)
|
||||||
this.$toast.error(this.$strings.ToastDeviceUpdateFailed)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.processing = false
|
this.processing = false
|
||||||
|
|||||||
@@ -108,9 +108,9 @@ export default {
|
|||||||
if (res.warning) {
|
if (res.warning) {
|
||||||
this.$toast.warning(res.warning)
|
this.$toast.warning(res.warning)
|
||||||
} else if (res.updated) {
|
} else if (res.updated) {
|
||||||
this.$toast.success(this.$strings.ToastNoUpdatesNecessary)
|
this.$toast.success(this.$strings.ToastItemDetailsUpdateSuccess)
|
||||||
} else {
|
} else {
|
||||||
this.$toast.info(this.$strings.ToastItemDetailsUpdateUnneeded)
|
this.$toast.info(this.$strings.ToastNoUpdatesNecessary)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
@@ -170,7 +170,7 @@ export default {
|
|||||||
this.isProcessing = false
|
this.isProcessing = false
|
||||||
if (updateResult) {
|
if (updateResult) {
|
||||||
if (updateResult.updated) {
|
if (updateResult.updated) {
|
||||||
this.$toast.success(this.$strings.MessageItemDetailsUpdated)
|
this.$toast.success(this.$strings.ToastItemDetailsUpdateSuccess)
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
this.$toast.info(this.$strings.MessageNoUpdatesWereNecessary)
|
this.$toast.info(this.$strings.MessageNoUpdatesWereNecessary)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<ui-text-input-with-label ref="maxEpisodesInput" v-model="maxEpisodesToDownload" :disabled="checkingNewEpisodes" type="number" :label="$strings.LabelLimit" class="w-16 mr-2" input-class="h-10">
|
<ui-text-input-with-label ref="maxEpisodesInput" v-model="maxEpisodesToDownload" :disabled="checkingNewEpisodes" type="number" :label="$strings.LabelLimit" class="w-16 mr-2" input-class="h-10">
|
||||||
<div class="flex -mb-0.5">
|
<div class="flex -mb-0.5">
|
||||||
<p class="px-1 text-sm font-semibold" :class="{ 'text-gray-400': checkingNewEpisodes }">{{ $strings.LabelLimit }}</p>
|
<p class="px-1 text-sm font-semibold" :class="{ 'text-gray-400': checkingNewEpisodes }">{{ $strings.LabelLimit }}</p>
|
||||||
<ui-tooltip direction="top" text="Max # of episodes to download. Use 0 for unlimited.">
|
<ui-tooltip direction="top" :text="$strings.LabelMaxEpisodesToDownload">
|
||||||
<span class="material-symbols text-base">info</span>
|
<span class="material-symbols text-base">info</span>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
</div>
|
</div>
|
||||||
@@ -99,7 +99,7 @@ export default {
|
|||||||
|
|
||||||
if (this.maxEpisodesToDownload < 0) {
|
if (this.maxEpisodesToDownload < 0) {
|
||||||
this.maxEpisodesToDownload = 3
|
this.maxEpisodesToDownload = 3
|
||||||
this.$toast.error('Invalid max episodes to download')
|
this.$toast.error(this.$strings.ToastInvalidMaxEpisodesToDownload)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,9 +120,9 @@ export default {
|
|||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.episodes && response.episodes.length) {
|
if (response.episodes && response.episodes.length) {
|
||||||
console.log('New episodes', response.episodes.length)
|
console.log('New episodes', response.episodes.length)
|
||||||
this.$toast.success(`${response.episodes.length} new episodes found!`)
|
this.$toast.success(this.$getString('ToastNewEpisodesFound', [response.episodes.length]))
|
||||||
} else {
|
} else {
|
||||||
this.$toast.info('No new episodes found')
|
this.$toast.info(this.$strings.ToastNoNewEpisodesFound)
|
||||||
}
|
}
|
||||||
this.checkingNewEpisodes = false
|
this.checkingNewEpisodes = false
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
<div class="flex-grow ml-4">
|
<div class="flex-grow ml-4">
|
||||||
<ui-text-input-with-label v-model="selectedMatch.title" :disabled="!selectedMatchUsage.title" :label="$strings.LabelTitle" />
|
<ui-text-input-with-label v-model="selectedMatch.title" :disabled="!selectedMatchUsage.title" :label="$strings.LabelTitle" />
|
||||||
<p v-if="mediaMetadata.title" class="text-xs ml-1 text-white text-opacity-60">
|
<p v-if="mediaMetadata.title" class="text-xs ml-1 text-white text-opacity-60">
|
||||||
{{ $strings.LabelCurrently }} <a title="Click to use current value" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('title', mediaMetadata.title)">{{ mediaMetadata.title || '' }}</a>
|
{{ $strings.LabelCurrently }} <a :title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('title', mediaMetadata.title)">{{ mediaMetadata.title || '' }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
<div class="flex-grow ml-4">
|
<div class="flex-grow ml-4">
|
||||||
<ui-text-input-with-label v-model="selectedMatch.subtitle" :disabled="!selectedMatchUsage.subtitle" :label="$strings.LabelSubtitle" />
|
<ui-text-input-with-label v-model="selectedMatch.subtitle" :disabled="!selectedMatchUsage.subtitle" :label="$strings.LabelSubtitle" />
|
||||||
<p v-if="mediaMetadata.subtitle" class="text-xs ml-1 text-white text-opacity-60">
|
<p v-if="mediaMetadata.subtitle" class="text-xs ml-1 text-white text-opacity-60">
|
||||||
{{ $strings.LabelCurrently }} <a title="Click to use current value" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('subtitle', mediaMetadata.subtitle)">{{ mediaMetadata.subtitle }}</a>
|
{{ $strings.LabelCurrently }} <a :title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('subtitle', mediaMetadata.subtitle)">{{ mediaMetadata.subtitle }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
<div class="flex-grow ml-4">
|
<div class="flex-grow ml-4">
|
||||||
<ui-text-input-with-label v-model="selectedMatch.author" :disabled="!selectedMatchUsage.author" :label="$strings.LabelAuthor" />
|
<ui-text-input-with-label v-model="selectedMatch.author" :disabled="!selectedMatchUsage.author" :label="$strings.LabelAuthor" />
|
||||||
<p v-if="mediaMetadata.authorName" class="text-xs ml-1 text-white text-opacity-60">
|
<p v-if="mediaMetadata.authorName" class="text-xs ml-1 text-white text-opacity-60">
|
||||||
{{ $strings.LabelCurrently }} <a title="Click to use current value" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('author', mediaMetadata.authorName)">{{ mediaMetadata.authorName }}</a>
|
{{ $strings.LabelCurrently }} <a title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('author', mediaMetadata.authorName)">{{ mediaMetadata.authorName }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -87,7 +87,7 @@
|
|||||||
<div class="flex-grow ml-4">
|
<div class="flex-grow ml-4">
|
||||||
<ui-multi-select v-model="selectedMatch.narrator" :items="narrators" :disabled="!selectedMatchUsage.narrator" :label="$strings.LabelNarrators" />
|
<ui-multi-select v-model="selectedMatch.narrator" :items="narrators" :disabled="!selectedMatchUsage.narrator" :label="$strings.LabelNarrators" />
|
||||||
<p v-if="mediaMetadata.narratorName" class="text-xs ml-1 text-white text-opacity-60">
|
<p v-if="mediaMetadata.narratorName" class="text-xs ml-1 text-white text-opacity-60">
|
||||||
{{ $strings.LabelCurrently }} <a title="Click to use current value" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('narrator', mediaMetadata.narrators)">{{ mediaMetadata.narratorName }}</a>
|
{{ $strings.LabelCurrently }} <a title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('narrator', mediaMetadata.narrators)">{{ mediaMetadata.narratorName }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
<div class="flex-grow ml-4">
|
<div class="flex-grow ml-4">
|
||||||
<ui-textarea-with-label v-model="selectedMatch.description" :rows="3" :disabled="!selectedMatchUsage.description" :label="$strings.LabelDescription" />
|
<ui-textarea-with-label v-model="selectedMatch.description" :rows="3" :disabled="!selectedMatchUsage.description" :label="$strings.LabelDescription" />
|
||||||
<p v-if="mediaMetadata.description" class="text-xs ml-1 text-white text-opacity-60">
|
<p v-if="mediaMetadata.description" class="text-xs ml-1 text-white text-opacity-60">
|
||||||
{{ $strings.LabelCurrently }} <a title="Click to use current value" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('description', mediaMetadata.description)">{{ mediaMetadata.description.substr(0, 100) + (mediaMetadata.description.length > 100 ? '...' : '') }}</a>
|
{{ $strings.LabelCurrently }} <a title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('description', mediaMetadata.description)">{{ mediaMetadata.description.substr(0, 100) + (mediaMetadata.description.length > 100 ? '...' : '') }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -105,7 +105,7 @@
|
|||||||
<div class="flex-grow ml-4">
|
<div class="flex-grow ml-4">
|
||||||
<ui-text-input-with-label v-model="selectedMatch.publisher" :disabled="!selectedMatchUsage.publisher" :label="$strings.LabelPublisher" />
|
<ui-text-input-with-label v-model="selectedMatch.publisher" :disabled="!selectedMatchUsage.publisher" :label="$strings.LabelPublisher" />
|
||||||
<p v-if="mediaMetadata.publisher" class="text-xs ml-1 text-white text-opacity-60">
|
<p v-if="mediaMetadata.publisher" class="text-xs ml-1 text-white text-opacity-60">
|
||||||
{{ $strings.LabelCurrently }} <a title="Click to use current value" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('publisher', mediaMetadata.publisher)">{{ mediaMetadata.publisher }}</a>
|
{{ $strings.LabelCurrently }} <a title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('publisher', mediaMetadata.publisher)">{{ mediaMetadata.publisher }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -114,7 +114,7 @@
|
|||||||
<div class="flex-grow ml-4">
|
<div class="flex-grow ml-4">
|
||||||
<ui-text-input-with-label v-model="selectedMatch.publishedYear" :disabled="!selectedMatchUsage.publishedYear" :label="$strings.LabelPublishYear" />
|
<ui-text-input-with-label v-model="selectedMatch.publishedYear" :disabled="!selectedMatchUsage.publishedYear" :label="$strings.LabelPublishYear" />
|
||||||
<p v-if="mediaMetadata.publishedYear" class="text-xs ml-1 text-white text-opacity-60">
|
<p v-if="mediaMetadata.publishedYear" class="text-xs ml-1 text-white text-opacity-60">
|
||||||
{{ $strings.LabelCurrently }} <a title="Click to use current value" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('publishedYear', mediaMetadata.publishedYear)">{{ mediaMetadata.publishedYear }}</a>
|
{{ $strings.LabelCurrently }} <a title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('publishedYear', mediaMetadata.publishedYear)">{{ mediaMetadata.publishedYear }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -124,7 +124,7 @@
|
|||||||
<div class="flex-grow ml-4">
|
<div class="flex-grow ml-4">
|
||||||
<widgets-series-input-widget v-model="selectedMatch.series" :disabled="!selectedMatchUsage.series" />
|
<widgets-series-input-widget v-model="selectedMatch.series" :disabled="!selectedMatchUsage.series" />
|
||||||
<p v-if="mediaMetadata.seriesName" class="text-xs ml-1 text-white text-opacity-60">
|
<p v-if="mediaMetadata.seriesName" class="text-xs ml-1 text-white text-opacity-60">
|
||||||
{{ $strings.LabelCurrently }} <a title="Click to use current value" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('series', mediaMetadata.series)">{{ mediaMetadata.seriesName }}</a>
|
{{ $strings.LabelCurrently }} <a :title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('series', mediaMetadata.series)">{{ mediaMetadata.seriesName }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
<div class="flex-grow ml-4">
|
<div class="flex-grow ml-4">
|
||||||
<ui-multi-select v-model="selectedMatch.genres" :items="genres" :disabled="!selectedMatchUsage.genres" :label="$strings.LabelGenres" />
|
<ui-multi-select v-model="selectedMatch.genres" :items="genres" :disabled="!selectedMatchUsage.genres" :label="$strings.LabelGenres" />
|
||||||
<p v-if="mediaMetadata.genres?.length" class="text-xs ml-1 text-white text-opacity-60">
|
<p v-if="mediaMetadata.genres?.length" class="text-xs ml-1 text-white text-opacity-60">
|
||||||
{{ $strings.LabelCurrently }} <a title="Click to use current value" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('genres', mediaMetadata.genres)">{{ mediaMetadata.genres.join(', ') }}</a>
|
{{ $strings.LabelCurrently }} <a :title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('genres', mediaMetadata.genres)">{{ mediaMetadata.genres.join(', ') }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -142,7 +142,7 @@
|
|||||||
<div class="flex-grow ml-4">
|
<div class="flex-grow ml-4">
|
||||||
<ui-multi-select v-model="selectedMatch.tags" :items="tags" :disabled="!selectedMatchUsage.tags" :label="$strings.LabelTags" />
|
<ui-multi-select v-model="selectedMatch.tags" :items="tags" :disabled="!selectedMatchUsage.tags" :label="$strings.LabelTags" />
|
||||||
<p v-if="media.tags?.length" class="text-xs ml-1 text-white text-opacity-60">
|
<p v-if="media.tags?.length" class="text-xs ml-1 text-white text-opacity-60">
|
||||||
{{ $strings.LabelCurrently }} <a title="Click to use current value" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('tags', media.tags)">{{ media.tags.join(', ') }}</a>
|
{{ $strings.LabelCurrently }} <a :title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('tags', media.tags)">{{ media.tags.join(', ') }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -151,7 +151,7 @@
|
|||||||
<div class="flex-grow ml-4">
|
<div class="flex-grow ml-4">
|
||||||
<ui-text-input-with-label v-model="selectedMatch.language" :disabled="!selectedMatchUsage.language" :label="$strings.LabelLanguage" />
|
<ui-text-input-with-label v-model="selectedMatch.language" :disabled="!selectedMatchUsage.language" :label="$strings.LabelLanguage" />
|
||||||
<p v-if="mediaMetadata.language" class="text-xs ml-1 text-white text-opacity-60">
|
<p v-if="mediaMetadata.language" class="text-xs ml-1 text-white text-opacity-60">
|
||||||
{{ $strings.LabelCurrently }} <a title="Click to use current value" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('language', mediaMetadata.language)">{{ mediaMetadata.language }}</a>
|
{{ $strings.LabelCurrently }} <a :title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('language', mediaMetadata.language)">{{ mediaMetadata.language }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -160,7 +160,7 @@
|
|||||||
<div class="flex-grow ml-4">
|
<div class="flex-grow ml-4">
|
||||||
<ui-text-input-with-label v-model="selectedMatch.isbn" :disabled="!selectedMatchUsage.isbn" label="ISBN" />
|
<ui-text-input-with-label v-model="selectedMatch.isbn" :disabled="!selectedMatchUsage.isbn" label="ISBN" />
|
||||||
<p v-if="mediaMetadata.isbn" class="text-xs ml-1 text-white text-opacity-60">
|
<p v-if="mediaMetadata.isbn" class="text-xs ml-1 text-white text-opacity-60">
|
||||||
{{ $strings.LabelCurrently }} <a title="Click to use current value" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('isbn', mediaMetadata.isbn)">{{ mediaMetadata.isbn }}</a>
|
{{ $strings.LabelCurrently }} <a :title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('isbn', mediaMetadata.isbn)">{{ mediaMetadata.isbn }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -169,7 +169,7 @@
|
|||||||
<div class="flex-grow ml-4">
|
<div class="flex-grow ml-4">
|
||||||
<ui-text-input-with-label v-model="selectedMatch.asin" :disabled="!selectedMatchUsage.asin" label="ASIN" />
|
<ui-text-input-with-label v-model="selectedMatch.asin" :disabled="!selectedMatchUsage.asin" label="ASIN" />
|
||||||
<p v-if="mediaMetadata.asin" class="text-xs ml-1 text-white text-opacity-60">
|
<p v-if="mediaMetadata.asin" class="text-xs ml-1 text-white text-opacity-60">
|
||||||
{{ $strings.LabelCurrently }} <a title="Click to use current value" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('asin', mediaMetadata.asin)">{{ mediaMetadata.asin }}</a>
|
{{ $strings.LabelCurrently }} <a :title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('asin', mediaMetadata.asin)">{{ mediaMetadata.asin }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -179,7 +179,7 @@
|
|||||||
<div class="flex-grow ml-4">
|
<div class="flex-grow ml-4">
|
||||||
<ui-text-input-with-label v-model="selectedMatch.itunesId" type="number" :disabled="!selectedMatchUsage.itunesId" label="iTunes ID" />
|
<ui-text-input-with-label v-model="selectedMatch.itunesId" type="number" :disabled="!selectedMatchUsage.itunesId" label="iTunes ID" />
|
||||||
<p v-if="mediaMetadata.itunesId" class="text-xs ml-1 text-white text-opacity-60">
|
<p v-if="mediaMetadata.itunesId" class="text-xs ml-1 text-white text-opacity-60">
|
||||||
{{ $strings.LabelCurrently }} <a title="Click to use current value" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('itunesId', mediaMetadata.itunesId)">{{ mediaMetadata.itunesId }}</a>
|
{{ $strings.LabelCurrently }} <a :title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('itunesId', mediaMetadata.itunesId)">{{ mediaMetadata.itunesId }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -188,7 +188,7 @@
|
|||||||
<div class="flex-grow ml-4">
|
<div class="flex-grow ml-4">
|
||||||
<ui-text-input-with-label v-model="selectedMatch.feedUrl" :disabled="!selectedMatchUsage.feedUrl" label="RSS Feed URL" />
|
<ui-text-input-with-label v-model="selectedMatch.feedUrl" :disabled="!selectedMatchUsage.feedUrl" label="RSS Feed URL" />
|
||||||
<p v-if="mediaMetadata.feedUrl" class="text-xs ml-1 text-white text-opacity-60">
|
<p v-if="mediaMetadata.feedUrl" class="text-xs ml-1 text-white text-opacity-60">
|
||||||
{{ $strings.LabelCurrently }} <a title="Click to use current value" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('feedUrl', mediaMetadata.feedUrl)">{{ mediaMetadata.feedUrl }}</a>
|
{{ $strings.LabelCurrently }} <a :title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('feedUrl', mediaMetadata.feedUrl)">{{ mediaMetadata.feedUrl }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -197,7 +197,7 @@
|
|||||||
<div class="flex-grow ml-4">
|
<div class="flex-grow ml-4">
|
||||||
<ui-text-input-with-label v-model="selectedMatch.itunesPageUrl" :disabled="!selectedMatchUsage.itunesPageUrl" label="iTunes Page URL" />
|
<ui-text-input-with-label v-model="selectedMatch.itunesPageUrl" :disabled="!selectedMatchUsage.itunesPageUrl" label="iTunes Page URL" />
|
||||||
<p v-if="mediaMetadata.itunesPageUrl" class="text-xs ml-1 text-white text-opacity-60">
|
<p v-if="mediaMetadata.itunesPageUrl" class="text-xs ml-1 text-white text-opacity-60">
|
||||||
{{ $strings.LabelCurrently }} <a title="Click to use current value" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('itunesPageUrl', mediaMetadata.itunesPageUrl)">{{ mediaMetadata.itunesPageUrl }}</a>
|
{{ $strings.LabelCurrently }} <a :title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('itunesPageUrl', mediaMetadata.itunesPageUrl)">{{ mediaMetadata.itunesPageUrl }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -206,7 +206,7 @@
|
|||||||
<div class="flex-grow ml-4">
|
<div class="flex-grow ml-4">
|
||||||
<ui-text-input-with-label v-model="selectedMatch.releaseDate" :disabled="!selectedMatchUsage.releaseDate" :label="$strings.LabelReleaseDate" />
|
<ui-text-input-with-label v-model="selectedMatch.releaseDate" :disabled="!selectedMatchUsage.releaseDate" :label="$strings.LabelReleaseDate" />
|
||||||
<p v-if="mediaMetadata.releaseDate" class="text-xs ml-1 text-white text-opacity-60">
|
<p v-if="mediaMetadata.releaseDate" class="text-xs ml-1 text-white text-opacity-60">
|
||||||
{{ $strings.LabelCurrently }} <a title="Click to use current value" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('releaseDate', mediaMetadata.releaseDate)">{{ mediaMetadata.releaseDate }}</a>
|
{{ $strings.LabelCurrently }} <a :title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('releaseDate', mediaMetadata.releaseDate)">{{ mediaMetadata.releaseDate }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -623,7 +623,7 @@ export default {
|
|||||||
this.clearSelectedMatch()
|
this.clearSelectedMatch()
|
||||||
this.$emit('selectTab', 'details')
|
this.$emit('selectTab', 'details')
|
||||||
} else {
|
} else {
|
||||||
this.$toast.error(this.$strings.ToastItemDetailsUpdateFailed)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.clearSelectedMatch()
|
this.clearSelectedMatch()
|
||||||
|
|||||||
@@ -2,28 +2,28 @@
|
|||||||
<div class="w-full h-full relative">
|
<div class="w-full h-full relative">
|
||||||
<div id="scheduleWrapper" class="w-full overflow-y-auto px-2 py-4 md:px-6 md:py-6">
|
<div id="scheduleWrapper" class="w-full overflow-y-auto px-2 py-4 md:px-6 md:py-6">
|
||||||
<template v-if="!feedUrl">
|
<template v-if="!feedUrl">
|
||||||
<widgets-alert type="warning" class="text-base mb-4">No RSS feed URL is set for this podcast</widgets-alert>
|
<widgets-alert type="warning" class="text-base mb-4">{{ $strings.ToastPodcastNoRssFeed }}</widgets-alert>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="feedUrl || autoDownloadEpisodes">
|
<template v-if="feedUrl || autoDownloadEpisodes">
|
||||||
<div class="flex items-center justify-between mb-4">
|
<div class="flex items-center justify-between mb-4">
|
||||||
<p class="text-base md:text-xl font-semibold">Schedule Automatic Episode Downloads</p>
|
<p class="text-base md:text-xl font-semibold">{{ $strings.HeaderScheduleEpisodeDownloads }}</p>
|
||||||
<ui-checkbox v-model="enableAutoDownloadEpisodes" label="Enable" medium checkbox-bg="bg" label-class="pl-2 text-base md:text-lg" />
|
<ui-checkbox v-model="enableAutoDownloadEpisodes" :label="$strings.LabelEnable" medium checkbox-bg="bg" label-class="pl-2 text-base md:text-lg" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="enableAutoDownloadEpisodes" class="flex items-center py-2">
|
<div v-if="enableAutoDownloadEpisodes" class="flex items-center py-2">
|
||||||
<ui-text-input ref="maxEpisodesInput" type="number" v-model="newMaxEpisodesToKeep" no-spinner :padding-x="1" text-center class="w-10 text-base" @change="updatedMaxEpisodesToKeep" />
|
<ui-text-input ref="maxEpisodesInput" type="number" v-model="newMaxEpisodesToKeep" no-spinner :padding-x="1" text-center class="w-10 text-base" @change="updatedMaxEpisodesToKeep" />
|
||||||
<ui-tooltip text="Value of 0 sets no max limit. After a new episode is auto-downloaded this will delete the oldest episode if you have more than X episodes. <br>This will only delete 1 episode per new download.">
|
<ui-tooltip :text="$strings.LabelMaxEpisodesToKeepHelp">
|
||||||
<p class="pl-4 text-base">
|
<p class="pl-4 text-base">
|
||||||
Max episodes to keep
|
{{ $strings.LabelMaxEpisodesToKeep }}
|
||||||
<span class="material-symbols icon-text">info</span>
|
<span class="material-symbols icon-text">info</span>
|
||||||
</p>
|
</p>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="enableAutoDownloadEpisodes" class="flex items-center py-2">
|
<div v-if="enableAutoDownloadEpisodes" class="flex items-center py-2">
|
||||||
<ui-text-input ref="maxEpisodesToDownloadInput" type="number" v-model="newMaxNewEpisodesToDownload" no-spinner :padding-x="1" text-center class="w-10 text-base" @change="updateMaxNewEpisodesToDownload" />
|
<ui-text-input ref="maxEpisodesToDownloadInput" type="number" v-model="newMaxNewEpisodesToDownload" no-spinner :padding-x="1" text-center class="w-10 text-base" @change="updateMaxNewEpisodesToDownload" />
|
||||||
<ui-tooltip text="Value of 0 sets no max limit. When checking for new episodes this is the max number of episodes that will be downloaded.">
|
<ui-tooltip :text="$strings.LabelUseZeroForUnlimited">
|
||||||
<p class="pl-4 text-base">
|
<p class="pl-4 text-base">
|
||||||
Max new episodes to download per check
|
{{ $strings.LabelMaxEpisodesToDownloadPerCheck }}
|
||||||
<span class="material-symbols icon-text">info</span>
|
<span class="material-symbols icon-text">info</span>
|
||||||
</p>
|
</p>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
<div v-if="feedUrl || autoDownloadEpisodes" class="absolute bottom-0 left-0 w-full py-2 md:py-4 bg-bg border-t border-white border-opacity-5">
|
<div v-if="feedUrl || autoDownloadEpisodes" class="absolute bottom-0 left-0 w-full py-2 md:py-4 bg-bg border-t border-white border-opacity-5">
|
||||||
<div class="flex items-center px-2 md:px-4">
|
<div class="flex items-center px-2 md:px-4">
|
||||||
<div class="flex-grow" />
|
<div class="flex-grow" />
|
||||||
<ui-btn @click="save" :disabled="!isUpdated" :color="isUpdated ? 'success' : 'primary'" class="mx-2">{{ isUpdated ? 'Save' : 'No update necessary' }}</ui-btn>
|
<ui-btn @click="save" :disabled="!isUpdated" :color="isUpdated ? 'success' : 'primary'" class="mx-2">{{ isUpdated ? $strings.ButtonSave : $strings.MessageNoUpdatesWereNecessary }}</ui-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -33,18 +33,18 @@
|
|||||||
<span class="material-symbols text-lg ml-2">launch</span>
|
<span class="material-symbols text-lg ml-2">launch</span>
|
||||||
</ui-btn>
|
</ui-btn>
|
||||||
|
|
||||||
<ui-btn v-if="!isMetadataEmbedQueued && !isEmbedTaskRunning" class="w-full mt-4" small @click.stop="quickEmbed">Quick Embed</ui-btn>
|
<ui-btn v-if="!isMetadataEmbedQueued && !isEmbedTaskRunning" class="w-full mt-4" small @click.stop="quickEmbed">{{ $strings.ButtonQuickEmbed }}</ui-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- queued alert -->
|
<!-- queued alert -->
|
||||||
<widgets-alert v-if="isMetadataEmbedQueued" type="warning" class="mt-4">
|
<widgets-alert v-if="isMetadataEmbedQueued" type="warning" class="mt-4">
|
||||||
<p class="text-lg">Queued for metadata embed ({{ queuedEmbedLIds.length }} in queue)</p>
|
<p class="text-lg">{{ $getString('MessageQuickEmbedQueue', [queuedEmbedLIds.length]) }}</p>
|
||||||
</widgets-alert>
|
</widgets-alert>
|
||||||
|
|
||||||
<!-- processing alert -->
|
<!-- processing alert -->
|
||||||
<widgets-alert v-if="isEmbedTaskRunning" type="warning" class="mt-4">
|
<widgets-alert v-if="isEmbedTaskRunning" type="warning" class="mt-4">
|
||||||
<p class="text-lg">Currently embedding metadata</p>
|
<p class="text-lg">{{ $strings.MessageQuickEmbedInProgress }}</p>
|
||||||
</widgets-alert>
|
</widgets-alert>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
quickEmbed() {
|
quickEmbed() {
|
||||||
const payload = {
|
const payload = {
|
||||||
message: 'Warning! Quick embed will not backup your audio files. Make sure that you have a backup of your audio files. <br><br>Would you like to continue?',
|
message: this.$strings.MessageConfirmQuickEmbed,
|
||||||
callback: (confirmed) => {
|
callback: (confirmed) => {
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
this.$axios
|
this.$axios
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ export default {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (!this.libraryCopy.folders.length) {
|
if (!this.libraryCopy.folders.length) {
|
||||||
this.$toast.error('Library must have at least 1 path')
|
this.$toast.error(this.$strings.ToastMustHaveAtLeastOnePath)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,7 +222,7 @@ export default {
|
|||||||
if (error.response && error.response.data) {
|
if (error.response && error.response.data) {
|
||||||
this.$toast.error(error.response.data)
|
this.$toast.error(error.response.data)
|
||||||
} else {
|
} else {
|
||||||
this.$toast.error(this.$strings.ToastLibraryUpdateFailed)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
}
|
}
|
||||||
this.processing = false
|
this.processing = false
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
<div class="w-full border border-black-200 p-4 my-8">
|
<div class="w-full border border-black-200 p-4 my-8">
|
||||||
<div class="flex flex-wrap items-center">
|
<div class="flex flex-wrap items-center">
|
||||||
<div>
|
<div>
|
||||||
<p class="text-lg">Remove metadata files in library item folders</p>
|
<p class="text-lg">{{ $strings.LabelRemoveMetadataFile }}</p>
|
||||||
<p class="max-w-sm text-sm pt-2 text-gray-300">Remove all metadata.json or metadata.abs files in your {{ mediaType }} folders</p>
|
<p class="max-w-sm text-sm pt-2 text-gray-300">{{ $getString('LabelRemoveMetadataFileHelp', [mediaType]) }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-grow" />
|
<div class="flex-grow" />
|
||||||
<div>
|
<div>
|
||||||
<ui-btn class="mb-4 block" @click.stop="removeAllMetadataClick('json')">Remove all metadata.json</ui-btn>
|
<ui-btn class="mb-4 block" @click.stop="removeAllMetadataClick('json')">{{ $strings.LabelRemoveAllMetadataJson }}</ui-btn>
|
||||||
<ui-btn @click.stop="removeAllMetadataClick('abs')">Remove all metadata.abs</ui-btn>
|
<ui-btn @click.stop="removeAllMetadataClick('abs')">{{ $strings.LabelRemoveAllMetadataAbs }}</ui-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -43,7 +43,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
removeAllMetadataClick(ext) {
|
removeAllMetadataClick(ext) {
|
||||||
const payload = {
|
const payload = {
|
||||||
message: `Are you sure you want to remove all metadata.${ext} files in your library item folders?`,
|
message: this.$getString('MessageConfirmRemoveMetadataFiles', [ext]),
|
||||||
persistent: true,
|
persistent: true,
|
||||||
callback: (confirmed) => {
|
callback: (confirmed) => {
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
@@ -60,16 +60,16 @@ export default {
|
|||||||
.$post(`/api/libraries/${this.libraryId}/remove-metadata?ext=${ext}`)
|
.$post(`/api/libraries/${this.libraryId}/remove-metadata?ext=${ext}`)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (!data.found) {
|
if (!data.found) {
|
||||||
this.$toast.info(`No metadata.${ext} files were found in library`)
|
this.$toast.info(this.$getString('ToastMetadataFilesRemovedNoneFound', [ext]))
|
||||||
} else if (!data.removed) {
|
} else if (!data.removed) {
|
||||||
this.$toast.success(`No metadata.${ext} files removed`)
|
this.$toast.success(this.$getString('ToastMetadataFilesRemovedNoneRemoved', [ext]))
|
||||||
} else {
|
} else {
|
||||||
this.$toast.success(`Successfully removed ${data.removed} metadata.${ext} files`)
|
this.$toast.success(this.$getString('ToastMetadataFilesRemovedSuccess', [data.removed, ext]))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to remove metadata files', error)
|
console.error('Failed to remove metadata files', error)
|
||||||
this.$toast.error('Failed to remove metadata files')
|
this.$toast.error(this.$getString('ToastMetadataFilesRemovedError', [ext]))
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.$emit('update:processing', false)
|
this.$emit('update:processing', false)
|
||||||
|
|||||||
@@ -77,7 +77,13 @@ export default {
|
|||||||
return this.notificationData.events || []
|
return this.notificationData.events || []
|
||||||
},
|
},
|
||||||
eventOptions() {
|
eventOptions() {
|
||||||
return this.notificationEvents.map((e) => ({ value: e.name, text: e.name, subtext: e.description }))
|
return this.notificationEvents.map((e) => {
|
||||||
|
return {
|
||||||
|
value: e.name,
|
||||||
|
text: e.name,
|
||||||
|
subtext: this.$strings[e.descriptionKey] || e.description
|
||||||
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
selectedEventData() {
|
selectedEventData() {
|
||||||
return this.notificationEvents.find((e) => e.name === this.newNotification.eventName)
|
return this.notificationEvents.find((e) => e.name === this.newNotification.eventName)
|
||||||
@@ -132,7 +138,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to update notification', error)
|
console.error('Failed to update notification', error)
|
||||||
this.$toast.error(this.$strings.ToastNotificationUpdateFailed)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.processing = false
|
this.processing = false
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to remove items from playlist', error)
|
console.error('Failed to remove items from playlist', error)
|
||||||
this.$toast.error(this.$strings.ToastPlaylistUpdateFailed)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
this.processing = false
|
this.processing = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -153,7 +153,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to add items to playlist', error)
|
console.error('Failed to add items to playlist', error)
|
||||||
this.$toast.error(this.$strings.ToastPlaylistUpdateFailed)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
this.processing = false
|
this.processing = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ export default {
|
|||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to update playlist', error)
|
console.error('Failed to update playlist', error)
|
||||||
this.processing = false
|
this.processing = false
|
||||||
this.$toast.error(this.$strings.ToastPlaylistUpdateFailed)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -156,7 +156,12 @@ export default {
|
|||||||
return this.selectedFolder.fullPath
|
return this.selectedFolder.fullPath
|
||||||
},
|
},
|
||||||
podcastTypes() {
|
podcastTypes() {
|
||||||
return this.$store.state.globals.podcastTypes || []
|
return this.$store.state.globals.podcastTypes.map((e) => {
|
||||||
|
return {
|
||||||
|
text: this.$strings[e.descriptionKey] || e.text,
|
||||||
|
value: e.value
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@@ -33,11 +33,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="enclosureUrl" class="pb-4 pt-6">
|
<div v-if="enclosureUrl" class="pb-4 pt-6">
|
||||||
<ui-text-input-with-label :value="enclosureUrl" readonly class="text-xs">
|
<ui-text-input-with-label :value="enclosureUrl" readonly class="text-xs">
|
||||||
<label class="px-1 text-xs text-gray-200 font-semibold">Episode URL from RSS feed</label>
|
<label class="px-1 text-xs text-gray-200 font-semibold">{{ $strings.LabelEpisodeUrlFromRssFeed }}</label>
|
||||||
</ui-text-input-with-label>
|
</ui-text-input-with-label>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="py-4">
|
<div v-else class="py-4">
|
||||||
<p class="text-xs text-gray-300 font-semibold">Episode not linked to RSS feed episode</p>
|
<p class="text-xs text-gray-300 font-semibold">{{ $strings.LabelEpisodeNotLinkedToRssFeed }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -97,7 +97,12 @@ export default {
|
|||||||
return this.enclosure.url
|
return this.enclosure.url
|
||||||
},
|
},
|
||||||
episodeTypes() {
|
episodeTypes() {
|
||||||
return this.$store.state.globals.episodeTypes || []
|
return this.$store.state.globals.episodeTypes.map((e) => {
|
||||||
|
return {
|
||||||
|
text: this.$strings[e.descriptionKey] || e.text,
|
||||||
|
value: e.value
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -152,14 +157,14 @@ export default {
|
|||||||
const updateResult = await this.$axios.$patch(`/api/podcasts/${this.libraryItem.id}/episode/${this.episodeId}`, updatedDetails).catch((error) => {
|
const updateResult = await this.$axios.$patch(`/api/podcasts/${this.libraryItem.id}/episode/${this.episodeId}`, updatedDetails).catch((error) => {
|
||||||
console.error('Failed update episode', error)
|
console.error('Failed update episode', error)
|
||||||
this.isProcessing = false
|
this.isProcessing = false
|
||||||
this.$toast.error(error?.response?.data || 'Failed to update episode')
|
this.$toast.error(error?.response?.data || this.$strings.ToastFailedToUpdate)
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
|
||||||
this.isProcessing = false
|
this.isProcessing = false
|
||||||
if (updateResult) {
|
if (updateResult) {
|
||||||
if (updateResult) {
|
if (updateResult) {
|
||||||
this.$toast.success('Podcast episode updated')
|
this.$toast.success(this.$strings.ToastItemUpdateSuccess)
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
this.$toast.info(this.$strings.MessageNoUpdatesWereNecessary)
|
this.$toast.info(this.$strings.MessageNoUpdatesWereNecessary)
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ export default {
|
|||||||
slug: this.newFeedSlug,
|
slug: this.newFeedSlug,
|
||||||
metadataDetails: this.metadataDetails
|
metadataDetails: this.metadataDetails
|
||||||
}
|
}
|
||||||
if (this.$isDev) payload.serverAddress = `http://localhost:3333${this.$config.routerBasePath}`
|
if (this.$isDev) payload.serverAddress = process.env.serverUrl
|
||||||
|
|
||||||
console.log('Payload', payload)
|
console.log('Payload', payload)
|
||||||
this.$axios
|
this.$axios
|
||||||
|
|||||||
@@ -1,38 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex items-center pt-4 pb-2 lg:pt-0 lg:pb-2">
|
<div class="flex justify-center pt-4 pb-2 lg:pt-0 lg:pb-2">
|
||||||
<div class="flex-grow" />
|
<div class="flex items-center justify-center flex-grow">
|
||||||
<template v-if="!loading">
|
<template v-if="!loading">
|
||||||
<ui-tooltip direction="top" :text="$strings.ButtonPreviousChapter" class="mr-4 lg:mr-8">
|
<ui-tooltip direction="top" :text="$strings.ButtonPreviousChapter" class="mr-4 lg:mr-8">
|
||||||
<button :aria-label="$strings.ButtonPreviousChapter" class="text-gray-300" @mousedown.prevent @mouseup.prevent @click.stop="prevChapter">
|
<button :aria-label="$strings.ButtonPreviousChapter" class="text-gray-300" @mousedown.prevent @mouseup.prevent @click.stop="prevChapter">
|
||||||
<span class="material-symbols text-2xl sm:text-3xl">first_page</span>
|
<span class="material-symbols text-2xl sm:text-3xl">first_page</span>
|
||||||
|
</button>
|
||||||
|
</ui-tooltip>
|
||||||
|
<ui-tooltip direction="top" :text="jumpBackwardText">
|
||||||
|
<button :aria-label="jumpForwardText" class="text-gray-300" @mousedown.prevent @mouseup.prevent @click.stop="jumpBackward">
|
||||||
|
<span class="material-symbols text-2xl sm:text-3xl">replay</span>
|
||||||
|
</button>
|
||||||
|
</ui-tooltip>
|
||||||
|
<button :aria-label="paused ? $strings.ButtonPlay : $strings.ButtonPause" class="p-2 shadow-sm bg-accent flex items-center justify-center rounded-full text-primary mx-4 lg:mx-8" :class="seekLoading ? 'animate-spin' : ''" @mousedown.prevent @mouseup.prevent @click.stop="playPause">
|
||||||
|
<span class="material-symbols fill text-2xl">{{ seekLoading ? 'autorenew' : paused ? 'play_arrow' : 'pause' }}</span>
|
||||||
</button>
|
</button>
|
||||||
</ui-tooltip>
|
<ui-tooltip direction="top" :text="jumpForwardText">
|
||||||
<ui-tooltip direction="top" :text="jumpBackwardText">
|
<button :aria-label="jumpForwardText" class="text-gray-300" @mousedown.prevent @mouseup.prevent @click.stop="jumpForward">
|
||||||
<button :aria-label="jumpForwardText" class="text-gray-300" @mousedown.prevent @mouseup.prevent @click.stop="jumpBackward">
|
<span class="material-symbols text-2xl sm:text-3xl">forward_media</span>
|
||||||
<span class="material-symbols text-2xl sm:text-3xl">replay</span>
|
</button>
|
||||||
</button>
|
</ui-tooltip>
|
||||||
</ui-tooltip>
|
<ui-tooltip direction="top" :text="hasNextLabel" class="ml-4 lg:ml-8">
|
||||||
<button :aria-label="paused ? $strings.ButtonPlay : $strings.ButtonPause" class="p-2 shadow-sm bg-accent flex items-center justify-center rounded-full text-primary mx-4 lg:mx-8" :class="seekLoading ? 'animate-spin' : ''" @mousedown.prevent @mouseup.prevent @click.stop="playPause">
|
<button :aria-label="hasNextLabel" :disabled="!hasNext" class="text-gray-300 disabled:text-gray-500" @mousedown.prevent @mouseup.prevent @click.stop="next">
|
||||||
<span class="material-symbols fill text-2xl">{{ seekLoading ? 'autorenew' : paused ? 'play_arrow' : 'pause' }}</span>
|
<span class="material-symbols text-2xl sm:text-3xl">last_page</span>
|
||||||
</button>
|
</button>
|
||||||
<ui-tooltip direction="top" :text="jumpForwardText">
|
</ui-tooltip>
|
||||||
<button :aria-label="jumpForwardText" class="text-gray-300" @mousedown.prevent @mouseup.prevent @click.stop="jumpForward">
|
</template>
|
||||||
<span class="material-symbols text-2xl sm:text-3xl">forward_media</span>
|
<template v-else>
|
||||||
</button>
|
<div class="cursor-pointer p-2 shadow-sm bg-accent flex items-center justify-center rounded-full text-primary mx-8 animate-spin">
|
||||||
</ui-tooltip>
|
<span class="material-symbols text-2xl">autorenew</span>
|
||||||
<ui-tooltip direction="top" :text="hasNextLabel" class="ml-4 lg:ml-8">
|
</div>
|
||||||
<button :aria-label="hasNextLabel" :disabled="!hasNext" class="text-gray-300 disabled:text-gray-500" @mousedown.prevent @mouseup.prevent @click.stop="next">
|
</template>
|
||||||
<span class="material-symbols text-2xl sm:text-3xl">last_page</span>
|
</div>
|
||||||
</button>
|
|
||||||
</ui-tooltip>
|
|
||||||
<controls-playback-speed-control v-model="playbackRateInput" @input="playbackRateUpdated" @change="playbackRateChanged" />
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<div class="cursor-pointer p-2 shadow-sm bg-accent flex items-center justify-center rounded-full text-primary mx-8 animate-spin">
|
|
||||||
<span class="material-symbols text-2xl">autorenew</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div class="flex-grow" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -41,7 +40,6 @@ export default {
|
|||||||
props: {
|
props: {
|
||||||
loading: Boolean,
|
loading: Boolean,
|
||||||
seekLoading: Boolean,
|
seekLoading: Boolean,
|
||||||
playbackRate: Number,
|
|
||||||
paused: Boolean,
|
paused: Boolean,
|
||||||
hasNextChapter: Boolean,
|
hasNextChapter: Boolean,
|
||||||
hasNextItemInQueue: Boolean
|
hasNextItemInQueue: Boolean
|
||||||
@@ -50,14 +48,6 @@ export default {
|
|||||||
return {}
|
return {}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
playbackRateInput: {
|
|
||||||
get() {
|
|
||||||
return this.playbackRate
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$emit('update:playbackRate', val)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
jumpForwardText() {
|
jumpForwardText() {
|
||||||
return this.getJumpText('jumpForwardAmount', this.$strings.ButtonJumpForward)
|
return this.getJumpText('jumpForwardAmount', this.$strings.ButtonJumpForward)
|
||||||
},
|
},
|
||||||
@@ -89,15 +79,6 @@ export default {
|
|||||||
jumpForward() {
|
jumpForward() {
|
||||||
this.$emit('jumpForward')
|
this.$emit('jumpForward')
|
||||||
},
|
},
|
||||||
playbackRateUpdated(playbackRate) {
|
|
||||||
this.$emit('setPlaybackRate', playbackRate)
|
|
||||||
},
|
|
||||||
playbackRateChanged(playbackRate) {
|
|
||||||
this.$emit('setPlaybackRate', playbackRate)
|
|
||||||
this.$store.dispatch('user/updateUserSettings', { playbackRate }).catch((err) => {
|
|
||||||
console.error('Failed to update settings', err)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getJumpText(setting, prefix) {
|
getJumpText(setting, prefix) {
|
||||||
const amount = this.$store.getters['user/getUserSetting'](setting)
|
const amount = this.$store.getters['user/getUserSetting'](setting)
|
||||||
if (!amount) return prefix
|
if (!amount) return prefix
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
<div class="w-full -mt-6">
|
<div class="w-full -mt-6">
|
||||||
<div class="w-full relative mb-1">
|
<div class="w-full relative mb-1">
|
||||||
<div class="absolute -top-10 lg:top-0 right-0 lg:right-2 flex items-center h-full">
|
<div class="absolute -top-10 lg:top-0 right-0 lg:right-2 flex items-center h-full">
|
||||||
<!-- <span class="material-symbols text-2xl cursor-pointer" @click="toggleFullscreen(true)">expand_less</span> -->
|
<controls-playback-speed-control v-model="playbackRate" @input="setPlaybackRate" @change="playbackRateChanged" class="mx-2 block" />
|
||||||
|
|
||||||
<ui-tooltip direction="top" :text="$strings.LabelVolume">
|
<ui-tooltip direction="left" :text="$strings.LabelVolume">
|
||||||
<controls-volume-control ref="volumeControl" v-model="volume" @input="setVolume" class="mx-2 hidden sm:block" />
|
<controls-volume-control ref="volumeControl" v-model="volume" @input="setVolume" class="mx-2 hidden sm:block" />
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
<span v-if="!sleepTimerSet" class="material-symbols text-2xl">snooze</span>
|
<span v-if="!sleepTimerSet" class="material-symbols text-2xl">snooze</span>
|
||||||
<div v-else class="flex items-center">
|
<div v-else class="flex items-center">
|
||||||
<span class="material-symbols text-lg text-warning">snooze</span>
|
<span class="material-symbols text-lg text-warning">snooze</span>
|
||||||
<p class="text-sm sm:text-lg text-warning font-mono font-semibold text-center px-0.5 sm:pb-0.5 sm:min-w-8">{{ sleepTimerRemainingString }}</p>
|
<p class="text-sm sm:text-lg text-warning font-semibold text-center px-0.5 sm:pb-0.5 sm:min-w-8">{{ sleepTimerRemainingString }}</p>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
@@ -48,15 +48,19 @@
|
|||||||
|
|
||||||
<player-track-bar ref="trackbar" :loading="loading" :chapters="chapters" :duration="duration" :current-chapter="currentChapter" :playback-rate="playbackRate" @seek="seek" />
|
<player-track-bar ref="trackbar" :loading="loading" :chapters="chapters" :duration="duration" :current-chapter="currentChapter" :playback-rate="playbackRate" @seek="seek" />
|
||||||
|
|
||||||
<div class="flex">
|
<div class="relative flex items-center justify-between">
|
||||||
<p ref="currentTimestamp" class="font-mono text-xxs sm:text-sm text-gray-100 pointer-events-auto">00:00:00</p>
|
<div class="flex-grow flex items-center">
|
||||||
<p class="font-mono text-sm hidden sm:block text-gray-100 pointer-events-auto"> / {{ progressPercent }}%</p>
|
<p ref="currentTimestamp" class="font-mono text-xxs sm:text-sm text-gray-100 pointer-events-auto">00:00:00</p>
|
||||||
<div class="flex-grow" />
|
<p class="font-mono text-sm hidden sm:block text-gray-100 pointer-events-auto"> / {{ progressPercent }}%</p>
|
||||||
<p class="text-xs sm:text-sm text-gray-300 pt-0.5 px-2 truncate">
|
</div>
|
||||||
{{ currentChapterName }} <span v-if="useChapterTrack" class="text-xs text-gray-400"> ({{ $getString('LabelPlayerChapterNumberMarker', [currentChapterIndex + 1, chapters.length]) }})</span>
|
<div class="absolute left-1/2 transform -translate-x-1/2">
|
||||||
</p>
|
<p class="text-xs sm:text-sm text-gray-300 pt-0.5 px-2 truncate">
|
||||||
<div class="flex-grow" />
|
{{ currentChapterName }} <span v-if="useChapterTrack" class="text-xs text-gray-400"> ({{ $getString('LabelPlayerChapterNumberMarker', [currentChapterIndex + 1, chapters.length]) }})</span>
|
||||||
<p class="font-mono text-xxs sm:text-sm text-gray-100 pointer-events-auto">{{ timeRemainingPretty }}</p>
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="flex-grow flex items-center justify-end">
|
||||||
|
<p class="font-mono text-xxs sm:text-sm text-gray-100 pointer-events-auto">{{ timeRemainingPretty }}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<modals-chapters-modal v-model="showChaptersModal" :current-chapter="currentChapter" :playback-rate="playbackRate" :chapters="chapters" @select="selectChapter" />
|
<modals-chapters-modal v-model="showChaptersModal" :current-chapter="currentChapter" :playback-rate="playbackRate" :chapters="chapters" @select="selectChapter" />
|
||||||
@@ -178,22 +182,6 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
toggleFullscreen(isFullscreen) {
|
toggleFullscreen(isFullscreen) {
|
||||||
this.$store.commit('setPlayerIsFullscreen', isFullscreen)
|
this.$store.commit('setPlayerIsFullscreen', isFullscreen)
|
||||||
|
|
||||||
var videoPlayerEl = document.getElementById('video-player')
|
|
||||||
if (videoPlayerEl) {
|
|
||||||
if (isFullscreen) {
|
|
||||||
videoPlayerEl.style.width = '100vw'
|
|
||||||
videoPlayerEl.style.height = '100vh'
|
|
||||||
videoPlayerEl.style.top = '0px'
|
|
||||||
videoPlayerEl.style.left = '0px'
|
|
||||||
} else {
|
|
||||||
videoPlayerEl.style.width = '384px'
|
|
||||||
videoPlayerEl.style.height = '216px'
|
|
||||||
videoPlayerEl.style.top = 'unset'
|
|
||||||
videoPlayerEl.style.bottom = '80px'
|
|
||||||
videoPlayerEl.style.left = '16px'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
setDuration(duration) {
|
setDuration(duration) {
|
||||||
this.duration = duration
|
this.duration = duration
|
||||||
@@ -240,6 +228,12 @@ export default {
|
|||||||
this.playbackRate = Number((this.playbackRate - 0.1).toFixed(1))
|
this.playbackRate = Number((this.playbackRate - 0.1).toFixed(1))
|
||||||
this.setPlaybackRate(this.playbackRate)
|
this.setPlaybackRate(this.playbackRate)
|
||||||
},
|
},
|
||||||
|
playbackRateChanged(playbackRate) {
|
||||||
|
this.setPlaybackRate(playbackRate)
|
||||||
|
this.$store.dispatch('user/updateUserSettings', { playbackRate }).catch((err) => {
|
||||||
|
console.error('Failed to update settings', err)
|
||||||
|
})
|
||||||
|
},
|
||||||
setPlaybackRate(playbackRate) {
|
setPlaybackRate(playbackRate) {
|
||||||
this.$emit('setPlaybackRate', playbackRate)
|
this.$emit('setPlaybackRate', playbackRate)
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -35,22 +35,22 @@
|
|||||||
<div class="flex justify-between pt-12">
|
<div class="flex justify-between pt-12">
|
||||||
<div>
|
<div>
|
||||||
<p class="text-sm text-center">{{ $strings.LabelStatsWeekListening }}</p>
|
<p class="text-sm text-center">{{ $strings.LabelStatsWeekListening }}</p>
|
||||||
<p class="text-5xl font-semibold text-center" style="line-height: 0.85">{{ totalMinutesListeningThisWeek }}</p>
|
<p class="text-5xl font-semibold text-center" style="line-height: 0.85">{{ $formatNumber(totalMinutesListeningThisWeek) }}</p>
|
||||||
<p class="text-sm text-center">{{ $strings.LabelStatsMinutes }}</p>
|
<p class="text-sm text-center">{{ $strings.LabelStatsMinutes }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="text-sm text-center">{{ $strings.LabelStatsDailyAverage }}</p>
|
<p class="text-sm text-center">{{ $strings.LabelStatsDailyAverage }}</p>
|
||||||
<p class="text-5xl font-semibold text-center" style="line-height: 0.85">{{ averageMinutesPerDay }}</p>
|
<p class="text-5xl font-semibold text-center" style="line-height: 0.85">{{ $formatNumber(averageMinutesPerDay) }}</p>
|
||||||
<p class="text-sm text-center">{{ $strings.LabelStatsMinutes }}</p>
|
<p class="text-sm text-center">{{ $strings.LabelStatsMinutes }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="text-sm text-center">{{ $strings.LabelStatsBestDay }}</p>
|
<p class="text-sm text-center">{{ $strings.LabelStatsBestDay }}</p>
|
||||||
<p class="text-5xl font-semibold text-center" style="line-height: 0.85">{{ mostListenedDay }}</p>
|
<p class="text-5xl font-semibold text-center" style="line-height: 0.85">{{ $formatNumber(mostListenedDay) }}</p>
|
||||||
<p class="text-sm text-center">{{ $strings.LabelStatsMinutes }}</p>
|
<p class="text-sm text-center">{{ $strings.LabelStatsMinutes }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="text-sm text-center">{{ $strings.LabelStatsDays }}</p>
|
<p class="text-sm text-center">{{ $strings.LabelStatsDays }}</p>
|
||||||
<p class="text-5xl font-semibold text-center" style="line-height: 0.85">{{ daysInARow }}</p>
|
<p class="text-5xl font-semibold text-center" style="line-height: 0.85">{{ $formatNumber(daysInARow) }}</p>
|
||||||
<p class="text-sm text-center">{{ $strings.LabelStatsInARow }}</p>
|
<p class="text-sm text-center">{{ $strings.LabelStatsInARow }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to update collection', error)
|
console.error('Failed to update collection', error)
|
||||||
this.$toast.error(this.$strings.ToastCollectionUpdateFailed)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
editBook(book) {
|
editBook(book) {
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to update playlist', error)
|
console.error('Failed to update playlist', error)
|
||||||
this.$toast.error(this.$strings.ToastPlaylistUpdateFailed)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
init() {
|
init() {
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to remove item from playlist', error)
|
console.error('Failed to remove item from playlist', error)
|
||||||
this.$toast.error(this.$strings.ToastPlaylistUpdateFailed)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.processingRemove = false
|
this.processingRemove = false
|
||||||
|
|||||||
@@ -12,10 +12,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="h-8 flex items-center">
|
<div class="h-8 flex items-center">
|
||||||
<div class="w-full inline-flex justify-between max-w-xl">
|
<div class="w-full inline-flex justify-between max-w-xl">
|
||||||
<p v-if="episode?.season" class="text-sm text-gray-300">Season #{{ episode.season }}</p>
|
<p v-if="episode?.season" class="text-sm text-gray-300">{{ $getString('LabelSeasonNumber', [episode.season]) }}</p>
|
||||||
<p v-if="episode?.episode" class="text-sm text-gray-300">Episode #{{ episode.episode }}</p>
|
<p v-if="episode?.episode" class="text-sm text-gray-300">{{ $getString('LabelEpisodeNumber', [episode.episode]) }}</p>
|
||||||
<p v-if="episode?.chapters?.length" class="text-sm text-gray-300">{{ episode.chapters.length }} Chapters</p>
|
<p v-if="episode?.chapters?.length" class="text-sm text-gray-300">{{ $getString('LabelChapterCount', [episode.chapters.length]) }}</p>
|
||||||
<p v-if="publishedAt" class="text-sm text-gray-300">Published {{ $formatDate(publishedAt, dateFormat) }}</p>
|
<p v-if="publishedAt" class="text-sm text-gray-300">{{ $getString('LabelPublishedDate', [$formatDate(publishedAt, dateFormat)]) }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -132,13 +132,13 @@ export default {
|
|||||||
return this.store.state.streamIsPlaying && this.isStreaming
|
return this.store.state.streamIsPlaying && this.isStreaming
|
||||||
},
|
},
|
||||||
timeRemaining() {
|
timeRemaining() {
|
||||||
if (this.streamIsPlaying) return 'Playing'
|
if (this.streamIsPlaying) return this.$strings.ButtonPlaying
|
||||||
if (!this.itemProgress) return this.$elapsedPretty(this.episode?.duration || 0)
|
if (!this.itemProgress) return this.$elapsedPretty(this.episode?.duration || 0)
|
||||||
if (this.userIsFinished) return 'Finished'
|
if (this.userIsFinished) return this.$strings.LabelFinished
|
||||||
|
|
||||||
const duration = this.itemProgress.duration || this.episode?.duration || 0
|
const duration = this.itemProgress.duration || this.episode?.duration || 0
|
||||||
const remaining = Math.floor(duration - this.itemProgress.currentTime)
|
const remaining = Math.floor(duration - this.itemProgress.currentTime)
|
||||||
return `${this.$elapsedPretty(remaining)} left`
|
return this.$getString('LabelTimeLeft', [this.$elapsedPretty(remaining)])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -182,7 +182,7 @@ export default {
|
|||||||
toggleFinished(confirmed = false) {
|
toggleFinished(confirmed = false) {
|
||||||
if (!this.userIsFinished && this.itemProgressPercent > 0 && !confirmed) {
|
if (!this.userIsFinished && this.itemProgressPercent > 0 && !confirmed) {
|
||||||
const payload = {
|
const payload = {
|
||||||
message: `Are you sure you want to mark "${this.episodeTitle}" as finished?`,
|
message: this.$getString('MessageConfirmMarkItemFinished', [this.episodeTitle]),
|
||||||
callback: (confirmed) => {
|
callback: (confirmed) => {
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
this.toggleFinished(true)
|
this.toggleFinished(true)
|
||||||
|
|||||||
@@ -93,17 +93,18 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
contextMenuItems() {
|
contextMenuItems() {
|
||||||
if (!this.userIsAdminOrUp) return []
|
const menuItems = []
|
||||||
return [
|
if (this.userIsAdminOrUp) {
|
||||||
{
|
menuItems.push({
|
||||||
text: 'Quick match all episodes',
|
text: this.$strings.MessageQuickMatchAllEpisodes,
|
||||||
action: 'quick-match-episodes'
|
action: 'quick-match-episodes'
|
||||||
},
|
})
|
||||||
{
|
}
|
||||||
text: this.allEpisodesFinished ? this.$strings.MessageMarkAllEpisodesNotFinished : this.$strings.MessageMarkAllEpisodesFinished,
|
menuItems.push({
|
||||||
action: 'batch-mark-as-finished'
|
text: this.allEpisodesFinished ? this.$strings.MessageMarkAllEpisodesNotFinished : this.$strings.MessageMarkAllEpisodesFinished,
|
||||||
}
|
action: 'batch-mark-as-finished'
|
||||||
]
|
})
|
||||||
|
return menuItems
|
||||||
},
|
},
|
||||||
sortItems() {
|
sortItems() {
|
||||||
return [
|
return [
|
||||||
@@ -261,21 +262,21 @@ export default {
|
|||||||
this.processing = true
|
this.processing = true
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
message: 'Quick matching episodes will overwrite details if a match is found. Only unmatched episodes will be updated. Are you sure?',
|
message: this.$strings.MessageConfirmQuickMatchEpisodes,
|
||||||
callback: (confirmed) => {
|
callback: (confirmed) => {
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
this.$axios
|
this.$axios
|
||||||
.$post(`/api/podcasts/${this.libraryItem.id}/match-episodes?override=1`)
|
.$post(`/api/podcasts/${this.libraryItem.id}/match-episodes?override=1`)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (data.numEpisodesUpdated) {
|
if (data.numEpisodesUpdated) {
|
||||||
this.$toast.success(`${data.numEpisodesUpdated} episodes updated`)
|
this.$toast.success(this.$getString('ToastEpisodeUpdateSuccess', [data.numEpisodesUpdated]))
|
||||||
} else {
|
} else {
|
||||||
this.$toast.info(this.$strings.ToastNoUpdatesNecessary)
|
this.$toast.info(this.$strings.ToastNoUpdatesNecessary)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to request match episodes', error)
|
console.error('Failed to request match episodes', error)
|
||||||
this.$toast.error('Failed to match episodes')
|
this.$toast.error(this.$strings.ToastFailedToMatch)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.processing = false
|
this.processing = false
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<ui-tooltip v-if="alreadyInLibrary" :text="$strings.LabelAlreadyInYourLibrary" direction="top">
|
<ui-tooltip :text="$strings.LabelAlreadyInYourLibrary" direction="top" class="inline-flex">
|
||||||
<span class="material-symbols ml-1 text-success" style="font-size: 0.8rem">check_circle</span>
|
<span class="material-symbols ml-1 text-sm text-success">check_circle</span>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: {
|
|
||||||
alreadyInLibrary: Boolean
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {}
|
return {}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,67 +3,67 @@
|
|||||||
<form class="w-full h-full px-2 md:px-4 py-6" @submit.prevent="submitForm">
|
<form class="w-full h-full px-2 md:px-4 py-6" @submit.prevent="submitForm">
|
||||||
<div class="flex flex-wrap -mx-1">
|
<div class="flex flex-wrap -mx-1">
|
||||||
<div class="w-full md:w-1/2 px-1">
|
<div class="w-full md:w-1/2 px-1">
|
||||||
<ui-text-input-with-label ref="titleInput" v-model="details.title" :label="$strings.LabelTitle" />
|
<ui-text-input-with-label ref="titleInput" v-model="details.title" :label="$strings.LabelTitle" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-grow px-1 mt-2 md:mt-0">
|
<div class="flex-grow px-1 mt-2 md:mt-0">
|
||||||
<ui-text-input-with-label ref="subtitleInput" v-model="details.subtitle" :label="$strings.LabelSubtitle" />
|
<ui-text-input-with-label ref="subtitleInput" v-model="details.subtitle" :label="$strings.LabelSubtitle" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-wrap mt-2 -mx-1">
|
<div class="flex flex-wrap mt-2 -mx-1">
|
||||||
<div class="w-full md:w-3/4 px-1">
|
<div class="w-full md:w-3/4 px-1">
|
||||||
<!-- Authors filter only contains authors in this library, uses filter data -->
|
<!-- Authors filter only contains authors in this library, uses filter data -->
|
||||||
<ui-multi-select-query-input ref="authorsSelect" v-model="details.authors" :label="$strings.LabelAuthors" filter-key="authors" />
|
<ui-multi-select-query-input ref="authorsSelect" v-model="details.authors" :label="$strings.LabelAuthors" filter-key="authors" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-grow px-1 mt-2 md:mt-0">
|
<div class="flex-grow px-1 mt-2 md:mt-0">
|
||||||
<ui-text-input-with-label ref="publishYearInput" v-model="details.publishedYear" type="number" :label="$strings.LabelPublishYear" />
|
<ui-text-input-with-label ref="publishYearInput" v-model="details.publishedYear" type="number" :label="$strings.LabelPublishYear" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex mt-2 -mx-1">
|
<div class="flex mt-2 -mx-1">
|
||||||
<div class="flex-grow px-1">
|
<div class="flex-grow px-1">
|
||||||
<widgets-series-input-widget v-model="details.series" />
|
<widgets-series-input-widget v-model="details.series" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ui-textarea-with-label ref="descriptionInput" v-model="details.description" :rows="3" :label="$strings.LabelDescription" class="mt-2" />
|
<ui-textarea-with-label ref="descriptionInput" v-model="details.description" :rows="3" :label="$strings.LabelDescription" class="mt-2" @input="handleInputChange" />
|
||||||
|
|
||||||
<div class="flex flex-wrap mt-2 -mx-1">
|
<div class="flex flex-wrap mt-2 -mx-1">
|
||||||
<div class="w-full md:w-1/2 px-1">
|
<div class="w-full md:w-1/2 px-1">
|
||||||
<ui-multi-select ref="genresSelect" v-model="details.genres" :label="$strings.LabelGenres" :items="genres" />
|
<ui-multi-select ref="genresSelect" v-model="details.genres" :label="$strings.LabelGenres" :items="genres" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-grow px-1 mt-2 md:mt-0">
|
<div class="flex-grow px-1 mt-2 md:mt-0">
|
||||||
<ui-multi-select ref="tagsSelect" v-model="newTags" :label="$strings.LabelTags" :items="tags" />
|
<ui-multi-select ref="tagsSelect" v-model="newTags" :label="$strings.LabelTags" :items="tags" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-wrap mt-2 -mx-1">
|
<div class="flex flex-wrap mt-2 -mx-1">
|
||||||
<div class="w-full md:w-1/2 px-1">
|
<div class="w-full md:w-1/2 px-1">
|
||||||
<ui-multi-select ref="narratorsSelect" v-model="details.narrators" :label="$strings.LabelNarrators" :items="narrators" />
|
<ui-multi-select ref="narratorsSelect" v-model="details.narrators" :label="$strings.LabelNarrators" :items="narrators" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
<div class="w-1/2 md:w-1/4 px-1 mt-2 md:mt-0">
|
<div class="w-1/2 md:w-1/4 px-1 mt-2 md:mt-0">
|
||||||
<ui-text-input-with-label ref="isbnInput" v-model="details.isbn" label="ISBN" />
|
<ui-text-input-with-label ref="isbnInput" v-model="details.isbn" label="ISBN" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
<div class="w-1/2 md:w-1/4 px-1 mt-2 md:mt-0">
|
<div class="w-1/2 md:w-1/4 px-1 mt-2 md:mt-0">
|
||||||
<ui-text-input-with-label ref="asinInput" v-model="details.asin" label="ASIN" />
|
<ui-text-input-with-label ref="asinInput" v-model="details.asin" label="ASIN" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-wrap mt-2 -mx-1">
|
<div class="flex flex-wrap mt-2 -mx-1">
|
||||||
<div class="w-full md:w-1/4 px-1">
|
<div class="w-full md:w-1/4 px-1">
|
||||||
<ui-text-input-with-label ref="publisherInput" v-model="details.publisher" :label="$strings.LabelPublisher" />
|
<ui-text-input-with-label ref="publisherInput" v-model="details.publisher" :label="$strings.LabelPublisher" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
<div class="w-1/2 md:w-1/4 px-1 mt-2 md:mt-0">
|
<div class="w-1/2 md:w-1/4 px-1 mt-2 md:mt-0">
|
||||||
<ui-text-input-with-label ref="languageInput" v-model="details.language" :label="$strings.LabelLanguage" />
|
<ui-text-input-with-label ref="languageInput" v-model="details.language" :label="$strings.LabelLanguage" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-grow px-1 pt-6 mt-2 md:mt-0">
|
<div class="flex-grow px-1 pt-6 mt-2 md:mt-0">
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<ui-checkbox v-model="details.explicit" :label="$strings.LabelExplicit" checkbox-bg="primary" border-color="gray-600" label-class="pl-2 text-base font-semibold" />
|
<ui-checkbox v-model="details.explicit" :label="$strings.LabelExplicit" checkbox-bg="primary" border-color="gray-600" label-class="pl-2 text-base font-semibold" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-grow px-1 pt-6 mt-2 md:mt-0">
|
<div class="flex-grow px-1 pt-6 mt-2 md:mt-0">
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<ui-checkbox v-model="details.abridged" :label="$strings.LabelAbridged" checkbox-bg="primary" border-color="gray-600" label-class="pl-2 text-base font-semibold" />
|
<ui-checkbox v-model="details.abridged" :label="$strings.LabelAbridged" checkbox-bg="primary" border-color="gray-600" label-class="pl-2 text-base font-semibold" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -132,6 +132,12 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
handleInputChange() {
|
||||||
|
this.$emit('change', {
|
||||||
|
libraryItemId: this.libraryItem.id,
|
||||||
|
hasChanges: this.checkForChanges().hasChanges
|
||||||
|
})
|
||||||
|
},
|
||||||
getDetails() {
|
getDetails() {
|
||||||
this.forceBlur()
|
this.forceBlur()
|
||||||
return this.checkForChanges()
|
return this.checkForChanges()
|
||||||
@@ -172,6 +178,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.handleInputChange()
|
||||||
},
|
},
|
||||||
forceBlur() {
|
forceBlur() {
|
||||||
if (this.$refs.titleInput) this.$refs.titleInput.blur()
|
if (this.$refs.titleInput) this.$refs.titleInput.blur()
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ export default {
|
|||||||
},
|
},
|
||||||
authors: {
|
authors: {
|
||||||
component: 'cards-author-card',
|
component: 'cards-author-card',
|
||||||
itemPropName: 'author',
|
itemPropName: 'author-mount',
|
||||||
itemIdFunc: (item) => item.id
|
itemIdFunc: (item) => item.id
|
||||||
},
|
},
|
||||||
narrators: {
|
narrators: {
|
||||||
|
|||||||
@@ -3,45 +3,45 @@
|
|||||||
<form class="w-full h-full px-4 py-6" @submit.prevent="submitForm">
|
<form class="w-full h-full px-4 py-6" @submit.prevent="submitForm">
|
||||||
<div class="flex -mx-1">
|
<div class="flex -mx-1">
|
||||||
<div class="w-1/2 px-1">
|
<div class="w-1/2 px-1">
|
||||||
<ui-text-input-with-label ref="titleInput" v-model="details.title" :label="$strings.LabelTitle" />
|
<ui-text-input-with-label ref="titleInput" v-model="details.title" :label="$strings.LabelTitle" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-grow px-1">
|
<div class="flex-grow px-1">
|
||||||
<ui-text-input-with-label ref="authorInput" v-model="details.author" :label="$strings.LabelAuthor" />
|
<ui-text-input-with-label ref="authorInput" v-model="details.author" :label="$strings.LabelAuthor" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ui-text-input-with-label ref="feedUrlInput" v-model="details.feedUrl" :label="$strings.LabelRSSFeedURL" class="mt-2" />
|
<ui-text-input-with-label ref="feedUrlInput" v-model="details.feedUrl" :label="$strings.LabelRSSFeedURL" class="mt-2" @input="handleInputChange" />
|
||||||
|
|
||||||
<ui-textarea-with-label ref="descriptionInput" v-model="details.description" :rows="3" :label="$strings.LabelDescription" class="mt-2" />
|
<ui-textarea-with-label ref="descriptionInput" v-model="details.description" :rows="3" :label="$strings.LabelDescription" class="mt-2" @input="handleInputChange" />
|
||||||
|
|
||||||
<div class="flex mt-2 -mx-1">
|
<div class="flex mt-2 -mx-1">
|
||||||
<div class="w-1/2 px-1">
|
<div class="w-1/2 px-1">
|
||||||
<ui-multi-select ref="genresSelect" v-model="details.genres" :label="$strings.LabelGenres" :items="genres" />
|
<ui-multi-select ref="genresSelect" v-model="details.genres" :label="$strings.LabelGenres" :items="genres" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-grow px-1">
|
<div class="flex-grow px-1">
|
||||||
<ui-multi-select ref="tagsSelect" v-model="newTags" :label="$strings.LabelTags" :items="tags" />
|
<ui-multi-select ref="tagsSelect" v-model="newTags" :label="$strings.LabelTags" :items="tags" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex mt-2 -mx-1">
|
<div class="flex mt-2 -mx-1">
|
||||||
<div class="w-1/4 px-1">
|
<div class="w-1/4 px-1">
|
||||||
<ui-text-input-with-label ref="releaseDateInput" v-model="details.releaseDate" :label="$strings.LabelReleaseDate" />
|
<ui-text-input-with-label ref="releaseDateInput" v-model="details.releaseDate" :label="$strings.LabelReleaseDate" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
<div class="w-1/4 px-1">
|
<div class="w-1/4 px-1">
|
||||||
<ui-text-input-with-label ref="itunesIdInput" v-model="details.itunesId" label="iTunes ID" />
|
<ui-text-input-with-label ref="itunesIdInput" v-model="details.itunesId" label="iTunes ID" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
<div class="w-1/4 px-1">
|
<div class="w-1/4 px-1">
|
||||||
<ui-text-input-with-label ref="languageInput" v-model="details.language" :label="$strings.LabelLanguage" />
|
<ui-text-input-with-label ref="languageInput" v-model="details.language" :label="$strings.LabelLanguage" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-grow px-1 pt-6">
|
<div class="flex-grow px-1 pt-6">
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<ui-checkbox v-model="details.explicit" :label="$strings.LabelExplicit" checkbox-bg="primary" border-color="gray-600" label-class="pl-2 text-base font-semibold" />
|
<ui-checkbox v-model="details.explicit" :label="$strings.LabelExplicit" checkbox-bg="primary" border-color="gray-600" label-class="pl-2 text-base font-semibold" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex mt-2 -mx-1">
|
<div class="flex mt-2 -mx-1">
|
||||||
<div class="w-1/4 px-1">
|
<div class="w-1/4 px-1">
|
||||||
<ui-dropdown :label="$strings.LabelPodcastType" v-model="details.type" :items="podcastTypes" small class="max-w-52" />
|
<ui-dropdown :label="$strings.LabelPodcastType" v-model="details.type" :items="podcastTypes" small class="max-w-52" @input="handleInputChange" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@@ -101,10 +101,21 @@ export default {
|
|||||||
return this.$store.state.libraries.filterData || {}
|
return this.$store.state.libraries.filterData || {}
|
||||||
},
|
},
|
||||||
podcastTypes() {
|
podcastTypes() {
|
||||||
return this.$store.state.globals.podcastTypes || []
|
return this.$store.state.globals.podcastTypes.map((e) => {
|
||||||
|
return {
|
||||||
|
text: this.$strings[e.descriptionKey] || e.text,
|
||||||
|
value: e.value
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
handleInputChange() {
|
||||||
|
this.$emit('change', {
|
||||||
|
libraryItemId: this.libraryItem.id,
|
||||||
|
hasChanges: this.checkForChanges().hasChanges
|
||||||
|
})
|
||||||
|
},
|
||||||
getDetails() {
|
getDetails() {
|
||||||
this.forceBlur()
|
this.forceBlur()
|
||||||
return this.checkForChanges()
|
return this.checkForChanges()
|
||||||
@@ -136,6 +147,8 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.handleInputChange()
|
||||||
},
|
},
|
||||||
forceBlur() {
|
forceBlur() {
|
||||||
if (this.$refs.titleInput) this.$refs.titleInput.blur()
|
if (this.$refs.titleInput) this.$refs.titleInput.blur()
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ import Tooltip from '@/components/ui/Tooltip.vue'
|
|||||||
import LoadingSpinner from '@/components/widgets/LoadingSpinner.vue'
|
import LoadingSpinner from '@/components/widgets/LoadingSpinner.vue'
|
||||||
|
|
||||||
describe('AuthorCard', () => {
|
describe('AuthorCard', () => {
|
||||||
const author = {
|
const authorMount = {
|
||||||
id: 1,
|
id: 1,
|
||||||
name: 'John Doe',
|
name: 'John Doe',
|
||||||
numBooks: 5
|
numBooks: 5
|
||||||
}
|
}
|
||||||
|
|
||||||
const propsData = {
|
const propsData = {
|
||||||
author,
|
authorMount,
|
||||||
nameBelow: false
|
nameBelow: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -357,7 +357,8 @@ export default {
|
|||||||
teardown: false,
|
teardown: false,
|
||||||
transports: ['websocket'],
|
transports: ['websocket'],
|
||||||
upgrade: false,
|
upgrade: false,
|
||||||
reconnection: true
|
reconnection: true,
|
||||||
|
path: `${this.$config.routerBasePath}/socket.io`
|
||||||
})
|
})
|
||||||
this.$root.socket = this.socket
|
this.$root.socket = this.socket
|
||||||
console.log('Socket initialized')
|
console.log('Socket initialized')
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import LazySeriesCard from '@/components/cards/LazySeriesCard'
|
|||||||
import LazyCollectionCard from '@/components/cards/LazyCollectionCard'
|
import LazyCollectionCard from '@/components/cards/LazyCollectionCard'
|
||||||
import LazyPlaylistCard from '@/components/cards/LazyPlaylistCard'
|
import LazyPlaylistCard from '@/components/cards/LazyPlaylistCard'
|
||||||
import LazyAlbumCard from '@/components/cards/LazyAlbumCard'
|
import LazyAlbumCard from '@/components/cards/LazyAlbumCard'
|
||||||
|
import AuthorCard from '@/components/cards/AuthorCard'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
@@ -20,6 +21,7 @@ export default {
|
|||||||
if (this.entityName === 'collections') return Vue.extend(LazyCollectionCard)
|
if (this.entityName === 'collections') return Vue.extend(LazyCollectionCard)
|
||||||
if (this.entityName === 'playlists') return Vue.extend(LazyPlaylistCard)
|
if (this.entityName === 'playlists') return Vue.extend(LazyPlaylistCard)
|
||||||
if (this.entityName === 'albums') return Vue.extend(LazyAlbumCard)
|
if (this.entityName === 'albums') return Vue.extend(LazyAlbumCard)
|
||||||
|
if (this.entityName === 'authors') return Vue.extend(AuthorCard)
|
||||||
return Vue.extend(LazyBookCard)
|
return Vue.extend(LazyBookCard)
|
||||||
},
|
},
|
||||||
getComponentName() {
|
getComponentName() {
|
||||||
@@ -27,6 +29,7 @@ export default {
|
|||||||
if (this.entityName === 'collections') return 'cards-lazy-collection-card'
|
if (this.entityName === 'collections') return 'cards-lazy-collection-card'
|
||||||
if (this.entityName === 'playlists') return 'cards-lazy-playlist-card'
|
if (this.entityName === 'playlists') return 'cards-lazy-playlist-card'
|
||||||
if (this.entityName === 'albums') return 'cards-lazy-album-card'
|
if (this.entityName === 'albums') return 'cards-lazy-album-card'
|
||||||
|
if (this.entityName === 'authors') return 'cards-author-card'
|
||||||
return 'cards-lazy-book-card'
|
return 'cards-lazy-book-card'
|
||||||
},
|
},
|
||||||
async setCardSize() {
|
async setCardSize() {
|
||||||
@@ -46,13 +49,14 @@ export default {
|
|||||||
props.orderBy = this.seriesSortBy
|
props.orderBy = this.seriesSortBy
|
||||||
}
|
}
|
||||||
const instance = new ComponentClass({
|
const instance = new ComponentClass({
|
||||||
propsData: props
|
propsData: props,
|
||||||
|
parent: this
|
||||||
})
|
})
|
||||||
instance.$mount()
|
instance.$mount()
|
||||||
this.resizeObserver = new ResizeObserver((entries) => {
|
this.resizeObserver = new ResizeObserver((entries) => {
|
||||||
for (let entry of entries) {
|
for (let entry of entries) {
|
||||||
this.cardWidth = entry.contentRect.width
|
this.cardWidth = entry.borderBoxSize[0].inlineSize
|
||||||
this.cardHeight = entry.contentRect.height
|
this.cardHeight = entry.borderBoxSize[0].blockSize
|
||||||
this.resizeObserver.disconnect()
|
this.resizeObserver.disconnect()
|
||||||
this.$refs.bookshelf.removeChild(instance.$el)
|
this.$refs.bookshelf.removeChild(instance.$el)
|
||||||
}
|
}
|
||||||
@@ -72,7 +76,7 @@ export default {
|
|||||||
})
|
})
|
||||||
const timeAfter = performance.now()
|
const timeAfter = performance.now()
|
||||||
},
|
},
|
||||||
async mountEntityCard(index) {
|
mountEntityCard(index) {
|
||||||
var shelf = Math.floor(index / this.entitiesPerShelf)
|
var shelf = Math.floor(index / this.entitiesPerShelf)
|
||||||
var shelfEl = document.getElementById(`shelf-${shelf}`)
|
var shelfEl = document.getElementById(`shelf-${shelf}`)
|
||||||
if (!shelfEl) {
|
if (!shelfEl) {
|
||||||
@@ -114,6 +118,7 @@ export default {
|
|||||||
const _this = this
|
const _this = this
|
||||||
const instance = new ComponentClass({
|
const instance = new ComponentClass({
|
||||||
propsData: props,
|
propsData: props,
|
||||||
|
parent: this,
|
||||||
created() {
|
created() {
|
||||||
this.$on('edit', (entity) => {
|
this.$on('edit', (entity) => {
|
||||||
if (_this.editEntity) _this.editEntity(entity)
|
if (_this.editEntity) _this.editEntity(entity)
|
||||||
|
|||||||
+39
-52
@@ -1,19 +1,24 @@
|
|||||||
const pkg = require('./package.json')
|
const pkg = require('./package.json')
|
||||||
|
|
||||||
|
const routerBasePath = process.env.ROUTER_BASE_PATH || ''
|
||||||
|
const serverHostUrl = process.env.NODE_ENV === 'production' ? '' : 'http://localhost:3333'
|
||||||
|
const serverPaths = ['api/', 'public/', 'hls/', 'auth/', 'feed/', 'status', 'login', 'logout', 'init']
|
||||||
|
const proxy = Object.fromEntries(serverPaths.map((path) => [`${routerBasePath}/${path}`, { target: process.env.NODE_ENV !== 'production' ? serverHostUrl : '/' }]))
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode
|
// Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode
|
||||||
ssr: false,
|
ssr: false,
|
||||||
target: 'static',
|
target: 'static',
|
||||||
dev: process.env.NODE_ENV !== 'production',
|
dev: process.env.NODE_ENV !== 'production',
|
||||||
env: {
|
env: {
|
||||||
serverUrl: process.env.NODE_ENV === 'production' ? process.env.ROUTER_BASE_PATH || '' : 'http://localhost:3333',
|
serverUrl: serverHostUrl + routerBasePath,
|
||||||
chromecastReceiver: 'FD1F76C5'
|
chromecastReceiver: 'FD1F76C5'
|
||||||
},
|
},
|
||||||
telemetry: false,
|
telemetry: false,
|
||||||
|
|
||||||
publicRuntimeConfig: {
|
publicRuntimeConfig: {
|
||||||
version: pkg.version,
|
version: pkg.version,
|
||||||
routerBasePath: process.env.ROUTER_BASE_PATH || ''
|
routerBasePath
|
||||||
},
|
},
|
||||||
|
|
||||||
// Global page headers: https://go.nuxtjs.dev/config-head
|
// Global page headers: https://go.nuxtjs.dev/config-head
|
||||||
@@ -22,38 +27,23 @@ module.exports = {
|
|||||||
htmlAttrs: {
|
htmlAttrs: {
|
||||||
lang: 'en'
|
lang: 'en'
|
||||||
},
|
},
|
||||||
meta: [
|
meta: [{ charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }, { hid: 'description', name: 'description', content: '' }, { hid: 'robots', name: 'robots', content: 'noindex' }],
|
||||||
{ charset: 'utf-8' },
|
|
||||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
|
||||||
{ hid: 'description', name: 'description', content: '' },
|
|
||||||
{ hid: 'robots', name: 'robots', content: 'noindex' }
|
|
||||||
],
|
|
||||||
script: [],
|
script: [],
|
||||||
link: [
|
link: [
|
||||||
{ rel: 'icon', type: 'image/x-icon', href: (process.env.ROUTER_BASE_PATH || '') + '/favicon.ico' },
|
{ rel: 'icon', type: 'image/x-icon', href: routerBasePath + '/favicon.ico' },
|
||||||
{ rel: 'apple-touch-icon', href: (process.env.ROUTER_BASE_PATH || '') + '/ios_icon.png' }
|
{ rel: 'apple-touch-icon', href: routerBasePath + '/ios_icon.png' }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
router: {
|
router: {
|
||||||
base: process.env.ROUTER_BASE_PATH || ''
|
base: routerBasePath
|
||||||
},
|
},
|
||||||
|
|
||||||
// Global CSS: https://go.nuxtjs.dev/config-css
|
// Global CSS: https://go.nuxtjs.dev/config-css
|
||||||
css: [
|
css: ['@/assets/tailwind.css', '@/assets/app.css'],
|
||||||
'@/assets/tailwind.css',
|
|
||||||
'@/assets/app.css'
|
|
||||||
],
|
|
||||||
|
|
||||||
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
|
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
|
||||||
plugins: [
|
plugins: ['@/plugins/constants.js', '@/plugins/init.client.js', '@/plugins/axios.js', '@/plugins/toast.js', '@/plugins/utils.js', '@/plugins/i18n.js'],
|
||||||
'@/plugins/constants.js',
|
|
||||||
'@/plugins/init.client.js',
|
|
||||||
'@/plugins/axios.js',
|
|
||||||
'@/plugins/toast.js',
|
|
||||||
'@/plugins/utils.js',
|
|
||||||
'@/plugins/i18n.js'
|
|
||||||
],
|
|
||||||
|
|
||||||
// Auto import components: https://go.nuxtjs.dev/config-components
|
// Auto import components: https://go.nuxtjs.dev/config-components
|
||||||
components: true,
|
components: true,
|
||||||
@@ -65,30 +55,25 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
|
|
||||||
// Modules: https://go.nuxtjs.dev/config-modules
|
// Modules: https://go.nuxtjs.dev/config-modules
|
||||||
modules: [
|
modules: ['nuxt-socket-io', '@nuxtjs/axios', '@nuxtjs/proxy'],
|
||||||
'nuxt-socket-io',
|
|
||||||
'@nuxtjs/axios',
|
|
||||||
'@nuxtjs/proxy'
|
|
||||||
],
|
|
||||||
|
|
||||||
proxy: {
|
proxy,
|
||||||
'/api/': { target: process.env.NODE_ENV !== 'production' ? 'http://localhost:3333' : '/' },
|
|
||||||
'/dev/': { target: 'http://localhost:3333', pathRewrite: { '^/dev/': '' } }
|
|
||||||
},
|
|
||||||
|
|
||||||
io: {
|
io: {
|
||||||
sockets: [{
|
sockets: [
|
||||||
name: 'dev',
|
{
|
||||||
url: 'http://localhost:3333'
|
name: 'dev',
|
||||||
},
|
url: serverHostUrl
|
||||||
{
|
},
|
||||||
name: 'prod'
|
{
|
||||||
}]
|
name: 'prod'
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
// Axios module configuration: https://go.nuxtjs.dev/config-axios
|
// Axios module configuration: https://go.nuxtjs.dev/config-axios
|
||||||
axios: {
|
axios: {
|
||||||
baseURL: process.env.ROUTER_BASE_PATH || ''
|
baseURL: routerBasePath
|
||||||
},
|
},
|
||||||
|
|
||||||
// nuxt/pwa https://pwa.nuxtjs.org
|
// nuxt/pwa https://pwa.nuxtjs.org
|
||||||
@@ -108,11 +93,11 @@ module.exports = {
|
|||||||
background_color: '#232323',
|
background_color: '#232323',
|
||||||
icons: [
|
icons: [
|
||||||
{
|
{
|
||||||
src: (process.env.ROUTER_BASE_PATH || '') + '/icon.svg',
|
src: routerBasePath + '/icon.svg',
|
||||||
sizes: 'any'
|
sizes: 'any'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
src: (process.env.ROUTER_BASE_PATH || '') + '/icon192.png',
|
src: routerBasePath + '/icon192.png',
|
||||||
type: 'image/png',
|
type: 'image/png',
|
||||||
sizes: 'any'
|
sizes: 'any'
|
||||||
}
|
}
|
||||||
@@ -129,10 +114,12 @@ module.exports = {
|
|||||||
// Build Configuration: https://go.nuxtjs.dev/config-build
|
// Build Configuration: https://go.nuxtjs.dev/config-build
|
||||||
build: {
|
build: {
|
||||||
postcss: {
|
postcss: {
|
||||||
plugins: {
|
postcssOptions: {
|
||||||
tailwindcss: {},
|
plugins: {
|
||||||
autoprefixer: {},
|
tailwindcss: {},
|
||||||
},
|
autoprefixer: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watchers: {
|
watchers: {
|
||||||
@@ -147,12 +134,12 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Temporary workaround for @nuxt-community/tailwindcss-module.
|
* Temporary workaround for @nuxt-community/tailwindcss-module.
|
||||||
*
|
*
|
||||||
* Reported: 2022-05-23
|
* Reported: 2022-05-23
|
||||||
* See: [Issue tracker](https://github.com/nuxt-community/tailwindcss-module/issues/480)
|
* See: [Issue tracker](https://github.com/nuxt-community/tailwindcss-module/issues/480)
|
||||||
*/
|
*/
|
||||||
devServerHandlers: [],
|
devServerHandlers: [],
|
||||||
|
|
||||||
ignore: ["**/*.test.*", "**/*.cy.*"]
|
ignore: ['**/*.test.*', '**/*.cy.*']
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+3106
-2020
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "audiobookshelf-client",
|
"name": "audiobookshelf-client",
|
||||||
"version": "2.13.0",
|
"version": "2.15.1",
|
||||||
"buildNumber": 1,
|
"buildNumber": 1,
|
||||||
"description": "Self-hosted audiobook and podcast client",
|
"description": "Self-hosted audiobook and podcast client",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
"fast-average-color": "^9.4.0",
|
"fast-average-color": "^9.4.0",
|
||||||
"hls.js": "^1.5.7",
|
"hls.js": "^1.5.7",
|
||||||
"libarchive.js": "^1.3.0",
|
"libarchive.js": "^1.3.0",
|
||||||
"nuxt": "^2.17.3",
|
"nuxt": "^2.18.1",
|
||||||
"nuxt-socket-io": "^1.1.18",
|
"nuxt-socket-io": "^1.1.18",
|
||||||
"trix": "^1.3.1",
|
"trix": "^1.3.1",
|
||||||
"v-click-outside": "^3.1.2",
|
"v-click-outside": "^3.1.2",
|
||||||
|
|||||||
@@ -415,7 +415,7 @@ export default {
|
|||||||
const audioEl = this.audioEl || document.createElement('audio')
|
const audioEl = this.audioEl || document.createElement('audio')
|
||||||
var src = audioTrack.contentUrl + `?token=${this.userToken}`
|
var src = audioTrack.contentUrl + `?token=${this.userToken}`
|
||||||
if (this.$isDev) {
|
if (this.$isDev) {
|
||||||
src = `http://localhost:3333${this.$config.routerBasePath}${src}`
|
src = `${process.env.serverUrl}${src}`
|
||||||
}
|
}
|
||||||
|
|
||||||
audioEl.src = src
|
audioEl.src = src
|
||||||
@@ -486,7 +486,7 @@ export default {
|
|||||||
.then((data) => {
|
.then((data) => {
|
||||||
this.saving = false
|
this.saving = false
|
||||||
if (data.updated) {
|
if (data.updated) {
|
||||||
this.$toast.success('Chapters updated')
|
this.$toast.success(this.$strings.ToastChaptersUpdated)
|
||||||
if (this.previousRoute) {
|
if (this.previousRoute) {
|
||||||
this.$router.push(this.previousRoute)
|
this.$router.push(this.previousRoute)
|
||||||
} else {
|
} else {
|
||||||
@@ -499,7 +499,7 @@ export default {
|
|||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
this.saving = false
|
this.saving = false
|
||||||
console.error('Failed to update chapters', error)
|
console.error('Failed to update chapters', error)
|
||||||
this.$toast.error('Failed to update chapters')
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
applyChapterNamesOnly() {
|
applyChapterNamesOnly() {
|
||||||
@@ -533,7 +533,7 @@ export default {
|
|||||||
},
|
},
|
||||||
findChapters() {
|
findChapters() {
|
||||||
if (!this.asinInput) {
|
if (!this.asinInput) {
|
||||||
this.$toast.error('Must input an ASIN')
|
this.$toast.error(this.$strings.ToastAsinRequired)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -628,15 +628,27 @@ export default {
|
|||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.saving = false
|
this.saving = false
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
libraryItemUpdated(libraryItem) {
|
||||||
|
if (libraryItem.id === this.libraryItem.id) {
|
||||||
|
if (!!libraryItem.media.metadata.asin && this.mediaMetadata.asin !== libraryItem.media.metadata.asin) {
|
||||||
|
this.asinInput = libraryItem.media.metadata.asin
|
||||||
|
}
|
||||||
|
this.libraryItem = libraryItem
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.regionInput = localStorage.getItem('audibleRegion') || 'US'
|
this.regionInput = localStorage.getItem('audibleRegion') || 'US'
|
||||||
this.asinInput = this.mediaMetadata.asin || null
|
this.asinInput = this.mediaMetadata.asin || null
|
||||||
this.initChapters()
|
this.initChapters()
|
||||||
|
|
||||||
|
this.$eventBus.$on(`${this.libraryItem.id}_updated`, this.libraryItemUpdated)
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.destroyAudioEl()
|
this.destroyAudioEl()
|
||||||
|
|
||||||
|
this.$eventBus.$off(`${this.libraryItem.id}_updated`, this.libraryItemUpdated)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -63,11 +63,11 @@
|
|||||||
<div class="w-full max-w-4xl mx-auto">
|
<div class="w-full max-w-4xl mx-auto">
|
||||||
<!-- queued alert -->
|
<!-- queued alert -->
|
||||||
<widgets-alert v-if="isMetadataEmbedQueued" type="warning" class="mb-4">
|
<widgets-alert v-if="isMetadataEmbedQueued" type="warning" class="mb-4">
|
||||||
<p class="text-lg">Audiobook is queued for metadata embed ({{ queuedEmbedLIds.length }} in queue)</p>
|
<p class="text-lg">{{ $getString('MessageEmbedQueue', [queuedEmbedLIds.length]) }}</p>
|
||||||
</widgets-alert>
|
</widgets-alert>
|
||||||
<!-- metadata embed action buttons -->
|
<!-- metadata embed action buttons -->
|
||||||
<div v-else-if="isEmbedTool" class="w-full flex justify-end items-center mb-4">
|
<div v-else-if="isEmbedTool" class="w-full flex justify-end items-center mb-4">
|
||||||
<ui-checkbox v-if="!isTaskFinished" v-model="shouldBackupAudioFiles" :disabled="processing" label="Backup audio files" medium checkbox-bg="bg" label-class="pl-2 text-base md:text-lg" @input="toggleBackupAudioFiles" />
|
<ui-checkbox v-if="!isTaskFinished" v-model="shouldBackupAudioFiles" :disabled="processing" :label="$strings.LabelBackupAudioFiles" medium checkbox-bg="bg" label-class="pl-2 text-base md:text-lg" @input="toggleBackupAudioFiles" />
|
||||||
|
|
||||||
<div class="flex-grow" />
|
<div class="flex-grow" />
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
<!-- m4b embed action buttons -->
|
<!-- m4b embed action buttons -->
|
||||||
<div v-else class="w-full flex items-center mb-4">
|
<div v-else class="w-full flex items-center mb-4">
|
||||||
<button :disabled="processing" class="text-sm uppercase text-gray-200 flex items-center pt-px pl-1 pr-2 hover:bg-white/5 rounded-md" @click="showEncodeOptions = !showEncodeOptions">
|
<button :disabled="processing" class="text-sm uppercase text-gray-200 flex items-center pt-px pl-1 pr-2 hover:bg-white/5 rounded-md" @click="showEncodeOptions = !showEncodeOptions">
|
||||||
<span class="material-symbols text-xl">{{ showEncodeOptions || usingCustomEncodeOptions ? 'check_box' : 'check_box_outline_blank' }}</span> <span class="pl-1">Use Advanced Options</span>
|
<span class="material-symbols text-xl">{{ showEncodeOptions || usingCustomEncodeOptions ? 'check_box' : 'check_box_outline_blank' }}</span> <span class="pl-1">{{ $strings.LabelUseAdvancedOptions }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="flex-grow" />
|
<div class="flex-grow" />
|
||||||
@@ -94,11 +94,11 @@
|
|||||||
<transition name="slide">
|
<transition name="slide">
|
||||||
<div v-if="showEncodeOptions || usingCustomEncodeOptions" class="mb-4 pb-4 border-b border-white/10">
|
<div v-if="showEncodeOptions || usingCustomEncodeOptions" class="mb-4 pb-4 border-b border-white/10">
|
||||||
<div class="flex flex-wrap -mx-2">
|
<div class="flex flex-wrap -mx-2">
|
||||||
<ui-text-input-with-label ref="bitrateInput" v-model="encodingOptions.bitrate" :disabled="processing || isTaskFinished" :label="'Audio Bitrate (e.g. 128k)'" class="m-2 max-w-40" @input="bitrateChanged" />
|
<ui-text-input-with-label ref="bitrateInput" v-model="encodingOptions.bitrate" :disabled="processing || isTaskFinished" :label="$strings.LabelAudioBitrate" class="m-2 max-w-40" @input="bitrateChanged" />
|
||||||
<ui-text-input-with-label ref="channelsInput" v-model="encodingOptions.channels" :disabled="processing || isTaskFinished" :label="'Audio Channels (1 or 2)'" class="m-2 max-w-40" @input="channelsChanged" />
|
<ui-text-input-with-label ref="channelsInput" v-model="encodingOptions.channels" :disabled="processing || isTaskFinished" :label="$strings.LabelAudioChannels" class="m-2 max-w-40" @input="channelsChanged" />
|
||||||
<ui-text-input-with-label ref="codecInput" v-model="encodingOptions.codec" :disabled="processing || isTaskFinished" :label="'Audio Codec'" class="m-2 max-w-40" @input="codecChanged" />
|
<ui-text-input-with-label ref="codecInput" v-model="encodingOptions.codec" :disabled="processing || isTaskFinished" :label="$strings.LabelAudioCodec" class="m-2 max-w-40" @input="codecChanged" />
|
||||||
</div>
|
</div>
|
||||||
<p class="text-sm text-warning">Warning: Do not update these settings unless you are familiar with ffmpeg encoding options.</p>
|
<p class="text-sm text-warning">{{ $strings.LabelEncodingWarningAdvancedSettings }}</p>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
@@ -106,36 +106,36 @@
|
|||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<div v-if="isEmbedTool" class="flex items-start mb-2">
|
<div v-if="isEmbedTool" class="flex items-start mb-2">
|
||||||
<span class="material-symbols text-base text-warning pt-1">star</span>
|
<span class="material-symbols text-base text-warning pt-1">star</span>
|
||||||
<p class="text-gray-200 ml-2">Metadata will be embedded in the audio tracks inside your audiobook folder.</p>
|
<p class="text-gray-200 ml-2">{{ $strings.LabelEncodingInfoEmbedded }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="flex items-start mb-2">
|
<div v-else class="flex items-start mb-2">
|
||||||
<span class="material-symbols text-base text-warning pt-1">star</span>
|
<span class="material-symbols text-base text-warning pt-1">star</span>
|
||||||
<p class="text-gray-200 ml-2">
|
<p class="text-gray-200 ml-2">
|
||||||
Finished M4B will be put into your audiobook folder at <span class="rounded-md bg-neutral-600 text-sm text-white py-0.5 px-1 font-mono">.../{{ libraryItemRelPath }}/</span>.
|
{{ $strings.LabelEncodingFinishedM4B }} <span class="rounded-md bg-neutral-600 text-sm text-white py-0.5 px-1 font-mono">.../{{ libraryItemRelPath }}/</span>.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="shouldBackupAudioFiles || isM4BTool" class="flex items-start mb-2">
|
<div v-if="shouldBackupAudioFiles || isM4BTool" class="flex items-start mb-2">
|
||||||
<span class="material-symbols text-base text-warning pt-1">star</span>
|
<span class="material-symbols text-base text-warning pt-1">star</span>
|
||||||
<p class="text-gray-200 ml-2">
|
<p class="text-gray-200 ml-2">
|
||||||
A backup of your original audio files will be stored in <span class="rounded-md bg-neutral-600 text-sm text-white py-0.5 px-1 font-mono">/metadata/cache/items/{{ libraryItemId }}/</span>. Make sure to periodically purge items cache.
|
{{ $strings.LabelEncodingBackupLocation }} <span class="rounded-md bg-neutral-600 text-sm text-white py-0.5 px-1 font-mono">/metadata/cache/items/{{ libraryItemId }}/</span>. {{ $strings.LabelEncodingClearItemCache }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isEmbedTool && audioFiles.length > 1" class="flex items-start mb-2">
|
<div v-if="isEmbedTool && audioFiles.length > 1" class="flex items-start mb-2">
|
||||||
<span class="material-symbols text-base text-warning pt-1">star</span>
|
<span class="material-symbols text-base text-warning pt-1">star</span>
|
||||||
<p class="text-gray-200 ml-2">Chapters are not embedded in multi-track audiobooks.</p>
|
<p class="text-gray-200 ml-2">{{ $strings.LabelEncodingChaptersNotEmbedded }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isM4BTool" class="flex items-start mb-2">
|
<div v-if="isM4BTool" class="flex items-start mb-2">
|
||||||
<span class="material-symbols text-base text-warning pt-1">star</span>
|
<span class="material-symbols text-base text-warning pt-1">star</span>
|
||||||
<p class="text-gray-200 ml-2">Encoding can take up to 30 minutes.</p>
|
<p class="text-gray-200 ml-2">{{ $strings.LabelEncodingTimeWarning }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isM4BTool" class="flex items-start mb-2">
|
<div v-if="isM4BTool" class="flex items-start mb-2">
|
||||||
<span class="material-symbols text-base text-warning pt-1">star</span>
|
<span class="material-symbols text-base text-warning pt-1">star</span>
|
||||||
<p class="text-gray-200 ml-2">If you have the watcher disabled you will need to re-scan this audiobook afterwards.</p>
|
<p class="text-gray-200 ml-2">{{ $strings.LabelEncodingWatcherDisabled }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-start mb-2">
|
<div class="flex items-start mb-2">
|
||||||
<span class="material-symbols text-base text-warning pt-1">star</span>
|
<span class="material-symbols text-base text-warning pt-1">star</span>
|
||||||
<p class="text-gray-200 ml-2">Once the task is started you can navigate away from this page.</p>
|
<p class="text-gray-200 ml-2">{{ $strings.LabelEncodingStartedNavigation }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -269,11 +269,11 @@ export default {
|
|||||||
},
|
},
|
||||||
availableTools() {
|
availableTools() {
|
||||||
if (this.isSingleM4b) {
|
if (this.isSingleM4b) {
|
||||||
return [{ value: 'embed', text: 'Embed Metadata' }]
|
return [{ value: 'embed', text: this.$strings.LabelToolsEmbedMetadata }]
|
||||||
} else {
|
} else {
|
||||||
return [
|
return [
|
||||||
{ value: 'embed', text: 'Embed Metadata' },
|
{ value: 'embed', text: this.$strings.LabelToolsEmbedMetadata },
|
||||||
{ value: 'm4b', text: 'M4B Encoder' }
|
{ value: 'm4b', text: this.$strings.LabelToolsM4bEncoder }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -370,7 +370,7 @@ export default {
|
|||||||
},
|
},
|
||||||
embedClick() {
|
embedClick() {
|
||||||
const payload = {
|
const payload = {
|
||||||
message: `Are you sure you want to embed metadata in ${this.audioFiles.length} audio files?`,
|
message: this.$getString('MessageConfirmEmbedMetadataInAudioFiles', [this.audioFiles.length]),
|
||||||
callback: (confirmed) => {
|
callback: (confirmed) => {
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
this.updateAudioFileMetadata()
|
this.updateAudioFileMetadata()
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export default {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (!author) {
|
if (!author) {
|
||||||
return redirect(`/library/${store.state.libraries.currentLibraryId}/authors`)
|
return redirect(`/library/${store.state.libraries.currentLibraryId}/bookshelf/authors`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (store.state.libraries.currentLibraryId !== author.libraryId || !store.state.libraries.filterData) {
|
if (store.state.libraries.currentLibraryId !== author.libraryId || !store.state.libraries.filterData) {
|
||||||
@@ -109,7 +109,7 @@ export default {
|
|||||||
authorRemoved(author) {
|
authorRemoved(author) {
|
||||||
if (author.id === this.author.id) {
|
if (author.id === this.author.id) {
|
||||||
console.warn('Author was removed')
|
console.warn('Author was removed')
|
||||||
this.$router.replace(`/library/${this.currentLibraryId}/authors`)
|
this.$router.replace(`/library/${this.currentLibraryId}/bookshelf/authors`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -97,8 +97,8 @@
|
|||||||
<div class="flex justify-center flex-wrap">
|
<div class="flex justify-center flex-wrap">
|
||||||
<template v-for="libraryItem in libraryItemCopies">
|
<template v-for="libraryItem in libraryItemCopies">
|
||||||
<div :key="libraryItem.id" class="w-full max-w-3xl border border-black-300 p-6 -ml-px -mt-px">
|
<div :key="libraryItem.id" class="w-full max-w-3xl border border-black-300 p-6 -ml-px -mt-px">
|
||||||
<widgets-book-details-edit v-if="libraryItem.mediaType === 'book'" :ref="`itemForm-${libraryItem.id}`" :library-item="libraryItem" />
|
<widgets-book-details-edit v-if="libraryItem.mediaType === 'book'" :ref="`itemForm-${libraryItem.id}`" :library-item="libraryItem" @change="handleItemChange" />
|
||||||
<widgets-podcast-details-edit v-else :ref="`itemForm-${libraryItem.id}`" :library-item="libraryItem" />
|
<widgets-podcast-details-edit v-else :ref="`itemForm-${libraryItem.id}`" :library-item="libraryItem" @change="handleItemChange" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
|
|
||||||
<div :class="isScrollable ? 'fixed left-0 box-shadow-lg-up bg-primary' : ''" class="w-full h-20 px-4 flex items-center border-t border-bg z-40" :style="{ bottom: streamLibraryItem ? '165px' : '0px' }">
|
<div :class="isScrollable ? 'fixed left-0 box-shadow-lg-up bg-primary' : ''" class="w-full h-20 px-4 flex items-center border-t border-bg z-40" :style="{ bottom: streamLibraryItem ? '165px' : '0px' }">
|
||||||
<div class="flex-grow" />
|
<div class="flex-grow" />
|
||||||
<ui-btn color="success" :padding-x="8" class="text-lg" :loading="isProcessing" @click.prevent="saveClick">{{ $strings.ButtonSave }}</ui-btn>
|
<ui-btn color="success" :padding-x="8" class="text-lg" :loading="isProcessing" :disabled="!hasChanges" @click.prevent="saveClick">{{ $strings.ButtonSave }}</ui-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -170,7 +170,8 @@ export default {
|
|||||||
abridged: false
|
abridged: false
|
||||||
},
|
},
|
||||||
appendableKeys: ['authors', 'genres', 'tags', 'narrators', 'series'],
|
appendableKeys: ['authors', 'genres', 'tags', 'narrators', 'series'],
|
||||||
openMapOptions: false
|
openMapOptions: false,
|
||||||
|
itemsWithChanges: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -221,9 +222,19 @@ export default {
|
|||||||
},
|
},
|
||||||
hasSelectedBatchUsage() {
|
hasSelectedBatchUsage() {
|
||||||
return Object.values(this.selectedBatchUsage).some((b) => !!b)
|
return Object.values(this.selectedBatchUsage).some((b) => !!b)
|
||||||
|
},
|
||||||
|
hasChanges() {
|
||||||
|
return this.itemsWithChanges.length > 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
handleItemChange(itemChange) {
|
||||||
|
if (!itemChange.hasChanges) {
|
||||||
|
this.itemsWithChanges = this.itemsWithChanges.filter((id) => id !== itemChange.libraryItemId)
|
||||||
|
} else if (!this.itemsWithChanges.includes(itemChange.libraryItemId)) {
|
||||||
|
this.itemsWithChanges.push(itemChange.libraryItemId)
|
||||||
|
}
|
||||||
|
},
|
||||||
blurBatchForm() {
|
blurBatchForm() {
|
||||||
if (this.$refs.seriesSelect && this.$refs.seriesSelect.isFocused) {
|
if (this.$refs.seriesSelect && this.$refs.seriesSelect.isFocused) {
|
||||||
this.$refs.seriesSelect.forceBlur()
|
this.$refs.seriesSelect.forceBlur()
|
||||||
@@ -283,38 +294,10 @@ export default {
|
|||||||
removedSeriesItem(item) {},
|
removedSeriesItem(item) {},
|
||||||
newNarratorItem(item) {},
|
newNarratorItem(item) {},
|
||||||
removedNarratorItem(item) {},
|
removedNarratorItem(item) {},
|
||||||
newTagItem(item) {
|
newTagItem(item) {},
|
||||||
// if (item && !this.newTagItems.includes(item)) {
|
removedTagItem(item) {},
|
||||||
// this.newTagItems.push(item)
|
newGenreItem(item) {},
|
||||||
// }
|
removedGenreItem(item) {},
|
||||||
},
|
|
||||||
removedTagItem(item) {
|
|
||||||
// If newly added, remove if not used on any other items
|
|
||||||
// if (item && this.newTagItems.includes(item)) {
|
|
||||||
// var usedByOtherAb = this.libraryItemCopies.find((ab) => {
|
|
||||||
// return ab.tags && ab.tags.includes(item)
|
|
||||||
// })
|
|
||||||
// if (!usedByOtherAb) {
|
|
||||||
// this.newTagItems = this.newTagItems.filter((t) => t !== item)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
},
|
|
||||||
newGenreItem(item) {
|
|
||||||
// if (item && !this.newGenreItems.includes(item)) {
|
|
||||||
// this.newGenreItems.push(item)
|
|
||||||
// }
|
|
||||||
},
|
|
||||||
removedGenreItem(item) {
|
|
||||||
// If newly added, remove if not used on any other items
|
|
||||||
// if (item && this.newGenreItems.includes(item)) {
|
|
||||||
// var usedByOtherAb = this.libraryItemCopies.find((ab) => {
|
|
||||||
// return ab.book.genres && ab.book.genres.includes(item)
|
|
||||||
// })
|
|
||||||
// if (!usedByOtherAb) {
|
|
||||||
// this.newGenreItems = this.newGenreItems.filter((t) => t !== item)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
},
|
|
||||||
init() {
|
init() {
|
||||||
// TODO: Better deep cloning of library items
|
// TODO: Better deep cloning of library items
|
||||||
this.libraryItemCopies = this.libraryItems.map((li) => {
|
this.libraryItemCopies = this.libraryItems.map((li) => {
|
||||||
@@ -376,6 +359,7 @@ export default {
|
|||||||
.then((data) => {
|
.then((data) => {
|
||||||
this.isProcessing = false
|
this.isProcessing = false
|
||||||
if (data.updates) {
|
if (data.updates) {
|
||||||
|
this.itemsWithChanges = []
|
||||||
this.$toast.success(`Successfully updated ${data.updates} items`)
|
this.$toast.success(`Successfully updated ${data.updates} items`)
|
||||||
this.$router.replace(`/library/${this.currentLibraryId}/bookshelf`)
|
this.$router.replace(`/library/${this.currentLibraryId}/bookshelf`)
|
||||||
} else {
|
} else {
|
||||||
@@ -387,10 +371,28 @@ export default {
|
|||||||
this.$toast.error('Failed to batch update')
|
this.$toast.error('Failed to batch update')
|
||||||
this.isProcessing = false
|
this.isProcessing = false
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
beforeUnload(e) {
|
||||||
|
if (!e || !this.hasChanges) return
|
||||||
|
e.preventDefault()
|
||||||
|
e.returnValue = ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeRouteLeave(to, from, next) {
|
||||||
|
if (this.hasChanges) {
|
||||||
|
next(false)
|
||||||
|
window.location = to.path
|
||||||
|
} else {
|
||||||
|
next()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.init()
|
this.init()
|
||||||
|
|
||||||
|
window.addEventListener('beforeunload', this.beforeUnload)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('beforeunload', this.beforeUnload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
<ui-btn v-if="showPlayButton" :disabled="streaming" color="success" :padding-x="4" small class="flex items-center h-9 mr-2" @click="clickPlay">
|
<ui-btn v-if="showPlayButton" :disabled="streaming" color="success" :padding-x="4" small class="flex items-center h-9 mr-2" @click="clickPlay">
|
||||||
<span v-show="!streaming" class="material-symbols fill text-2xl -ml-2 pr-1 text-white">play_arrow</span>
|
<span v-show="!streaming" class="material-symbols fill text-2xl -ml-2 pr-1 text-white">play_arrow</span>
|
||||||
{{ streaming ? $strings.ButtonPlaying : $strings.ButtonPlay }}
|
{{ streaming ? $strings.ButtonPlaying : $strings.ButtonPlayAll }}
|
||||||
</ui-btn>
|
</ui-btn>
|
||||||
|
|
||||||
<!-- RSS feed -->
|
<!-- RSS feed -->
|
||||||
|
|||||||
@@ -317,7 +317,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to update server settings', error)
|
console.error('Failed to update server settings', error)
|
||||||
this.$toast.error(this.$strings.ToastServerSettingsUpdateFailed)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.savingSettings = false
|
this.savingSettings = false
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to save backup path', error)
|
console.error('Failed to save backup path', error)
|
||||||
const errorMsg = error.response?.data || this.$strings.ToastBackupPathUpdateFailed
|
const errorMsg = error.response?.data || this.$strings.ToastFailedToUpdate
|
||||||
this.$toast.error(errorMsg)
|
this.$toast.error(errorMsg)
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to update email settings', error)
|
console.error('Failed to update email settings', error)
|
||||||
this.$toast.error(this.$strings.ToastEmailSettingsUpdateFailed)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.savingSettings = false
|
this.savingSettings = false
|
||||||
|
|||||||
@@ -290,7 +290,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to update prefixes', error)
|
console.error('Failed to update prefixes', error)
|
||||||
this.$toast.error(this.$strings.ToastSortingPrefixesUpdateFailed)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.savingPrefixes = false
|
this.savingPrefixes = false
|
||||||
@@ -328,7 +328,6 @@ export default {
|
|||||||
.dispatch('updateServerSettings', payload)
|
.dispatch('updateServerSettings', payload)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.updatingServerSettings = false
|
this.updatingServerSettings = false
|
||||||
this.$toast.success(this.$strings.ToastServerSettingsUpdateSuccess)
|
|
||||||
|
|
||||||
if (payload.language) {
|
if (payload.language) {
|
||||||
// Updating language after save allows for re-rendering
|
// Updating language after save allows for re-rendering
|
||||||
@@ -338,7 +337,7 @@ export default {
|
|||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to update server settings', error)
|
console.error('Failed to update server settings', error)
|
||||||
this.updatingServerSettings = false
|
this.updatingServerSettings = false
|
||||||
this.$toast.error(this.$strings.ToastServerSettingsUpdateFailed)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
initServerSettings() {
|
initServerSettings() {
|
||||||
|
|||||||
@@ -10,9 +10,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="flex justify-between mb-2 place-items-end">
|
<div class="flex justify-between mb-2 place-items-end">
|
||||||
<ui-text-input ref="input" v-model="search" placeholder="Search filter.." @input="inputUpdate" clearable class="w-full sm:w-40 h-8 text-sm sm:mb-0" />
|
<ui-text-input ref="input" v-model="search" :placeholder="$strings.PlaceholderSearch" @input="inputUpdate" clearable class="w-full sm:w-40 h-8 text-sm sm:mb-0" />
|
||||||
|
|
||||||
<ui-dropdown v-model="newServerSettings.logLevel" label="Server Log Level" :items="logLevelItems" @input="logLevelUpdated" class="w-full sm:w-44" />
|
<ui-dropdown v-model="newServerSettings.logLevel" :label="$strings.LabelServerLogLevel" :items="logLevelItems" @input="logLevelUpdated" class="w-full sm:w-44" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to update notification settings', error)
|
console.error('Failed to update notification settings', error)
|
||||||
this.$toast.error(this.$strings.ToastNotificationSettingsUpdateFailed)
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.savingSettings = false
|
this.savingSettings = false
|
||||||
|
|||||||
@@ -39,16 +39,11 @@
|
|||||||
><span :key="index" v-if="index < seriesList.length - 1">, </span>
|
><span :key="index" v-if="index < seriesList.length - 1">, </span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-if="!isVideo">
|
<p v-if="isPodcast" class="mb-2 mt-0.5 text-gray-200 text-lg md:text-xl">{{ $getString('LabelByAuthor', [podcastAuthor]) }}</p>
|
||||||
<p v-if="isPodcast" class="mb-2 mt-0.5 text-gray-200 text-lg md:text-xl">{{ $getString('LabelByAuthor', [podcastAuthor]) }}</p>
|
<p v-else-if="authors.length" class="mb-2 mt-0.5 text-gray-200 text-lg md:text-xl max-w-[calc(100vw-2rem)] overflow-hidden overflow-ellipsis">
|
||||||
<p v-else-if="musicArtists.length" class="mb-2 mt-0.5 text-gray-200 text-lg md:text-xl max-w-[calc(100vw-2rem)] overflow-hidden overflow-ellipsis">
|
by <nuxt-link v-for="(author, index) in authors" :key="index" :to="`/author/${author.id}`" class="hover:underline">{{ author.name }}<span v-if="index < authors.length - 1">, </span></nuxt-link>
|
||||||
<nuxt-link v-for="(artist, index) in musicArtists" :key="index" :to="`/artist/${$encode(artist)}`" class="hover:underline">{{ artist }}<span v-if="index < musicArtists.length - 1">, </span></nuxt-link>
|
</p>
|
||||||
</p>
|
<p v-else class="mb-2 mt-0.5 text-gray-200 text-xl">by Unknown</p>
|
||||||
<p v-else-if="authors.length" class="mb-2 mt-0.5 text-gray-200 text-lg md:text-xl max-w-[calc(100vw-2rem)] overflow-hidden overflow-ellipsis">
|
|
||||||
by <nuxt-link v-for="(author, index) in authors" :key="index" :to="`/author/${author.id}`" class="hover:underline">{{ author.name }}<span v-if="index < authors.length - 1">, </span></nuxt-link>
|
|
||||||
</p>
|
|
||||||
<p v-else class="mb-2 mt-0.5 text-gray-200 text-xl">by Unknown</p>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<content-library-item-details :library-item="libraryItem" />
|
<content-library-item-details :library-item="libraryItem" />
|
||||||
</div>
|
</div>
|
||||||
@@ -109,7 +104,7 @@
|
|||||||
<ui-icon-btn icon="" outlined class="mx-0.5" @click="editClick" />
|
<ui-icon-btn icon="" outlined class="mx-0.5" @click="editClick" />
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|
||||||
<ui-tooltip v-if="!isPodcast && !isMusic" :text="userIsFinished ? $strings.MessageMarkAsNotFinished : $strings.MessageMarkAsFinished" direction="top">
|
<ui-tooltip v-if="!isPodcast" :text="userIsFinished ? $strings.MessageMarkAsNotFinished : $strings.MessageMarkAsFinished" direction="top">
|
||||||
<ui-read-icon-btn :disabled="isProcessingReadUpdate" :is-read="userIsFinished" class="mx-0.5" @click="toggleFinished" />
|
<ui-read-icon-btn :disabled="isProcessingReadUpdate" :is-read="userIsFinished" class="mx-0.5" @click="toggleFinished" />
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|
||||||
@@ -220,12 +215,6 @@ export default {
|
|||||||
isPodcast() {
|
isPodcast() {
|
||||||
return this.libraryItem.mediaType === 'podcast'
|
return this.libraryItem.mediaType === 'podcast'
|
||||||
},
|
},
|
||||||
isVideo() {
|
|
||||||
return this.libraryItem.mediaType === 'video'
|
|
||||||
},
|
|
||||||
isMusic() {
|
|
||||||
return this.libraryItem.mediaType === 'music'
|
|
||||||
},
|
|
||||||
isMissing() {
|
isMissing() {
|
||||||
return this.libraryItem.isMissing
|
return this.libraryItem.isMissing
|
||||||
},
|
},
|
||||||
@@ -240,8 +229,6 @@ export default {
|
|||||||
},
|
},
|
||||||
showPlayButton() {
|
showPlayButton() {
|
||||||
if (this.isMissing || this.isInvalid) return false
|
if (this.isMissing || this.isInvalid) return false
|
||||||
if (this.isMusic) return !!this.audioFile
|
|
||||||
if (this.isVideo) return !!this.videoFile
|
|
||||||
if (this.isPodcast) return this.podcastEpisodes.length
|
if (this.isPodcast) return this.podcastEpisodes.length
|
||||||
return this.tracks.length
|
return this.tracks.length
|
||||||
},
|
},
|
||||||
@@ -292,9 +279,6 @@ export default {
|
|||||||
authors() {
|
authors() {
|
||||||
return this.mediaMetadata.authors || []
|
return this.mediaMetadata.authors || []
|
||||||
},
|
},
|
||||||
musicArtists() {
|
|
||||||
return this.mediaMetadata.artists || []
|
|
||||||
},
|
|
||||||
series() {
|
series() {
|
||||||
return this.mediaMetadata.series || []
|
return this.mediaMetadata.series || []
|
||||||
},
|
},
|
||||||
@@ -309,7 +293,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
duration() {
|
duration() {
|
||||||
if (!this.tracks.length && !this.audioFile) return 0
|
if (!this.tracks.length) return 0
|
||||||
return this.media.duration
|
return this.media.duration
|
||||||
},
|
},
|
||||||
libraryFiles() {
|
libraryFiles() {
|
||||||
@@ -321,18 +305,10 @@ export default {
|
|||||||
ebookFile() {
|
ebookFile() {
|
||||||
return this.media.ebookFile
|
return this.media.ebookFile
|
||||||
},
|
},
|
||||||
videoFile() {
|
|
||||||
return this.media.videoFile
|
|
||||||
},
|
|
||||||
audioFile() {
|
|
||||||
// Music track
|
|
||||||
return this.media.audioFile
|
|
||||||
},
|
|
||||||
description() {
|
description() {
|
||||||
return this.mediaMetadata.description || ''
|
return this.mediaMetadata.description || ''
|
||||||
},
|
},
|
||||||
userMediaProgress() {
|
userMediaProgress() {
|
||||||
if (this.isMusic) return null
|
|
||||||
return this.$store.getters['user/getUserMediaProgress'](this.libraryItemId)
|
return this.$store.getters['user/getUserMediaProgress'](this.libraryItemId)
|
||||||
},
|
},
|
||||||
userIsFinished() {
|
userIsFinished() {
|
||||||
|
|||||||
@@ -1,115 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="page" :class="streamLibraryItem ? 'streaming' : ''">
|
|
||||||
<app-book-shelf-toolbar page="authors" is-home :authors="authors" />
|
|
||||||
<div id="bookshelf" class="w-full h-full p-8e overflow-y-auto" :style="{ fontSize: sizeMultiplier + 'rem' }">
|
|
||||||
<!-- Cover size widget -->
|
|
||||||
<widgets-cover-size-widget class="fixed right-4 z-50" :style="{ bottom: streamLibraryItem ? '181px' : '16px' }" />
|
|
||||||
<div class="flex flex-wrap justify-center">
|
|
||||||
<template v-for="author in authorsSorted">
|
|
||||||
<cards-author-card :key="author.id" :author="author" class="p-3e" @edit="editAuthor" />
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
async asyncData({ store, params, redirect, query, app }) {
|
|
||||||
var libraryId = params.library
|
|
||||||
var libraryData = await store.dispatch('libraries/fetch', libraryId)
|
|
||||||
if (!libraryData) {
|
|
||||||
return redirect('/oops?message=Library not found')
|
|
||||||
}
|
|
||||||
|
|
||||||
const library = libraryData.library
|
|
||||||
if (library.mediaType === 'podcast') {
|
|
||||||
return redirect(`/library/${libraryId}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
libraryId
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
authors: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
sizeMultiplier() {
|
|
||||||
return this.$store.getters['user/getSizeMultiplier']
|
|
||||||
},
|
|
||||||
streamLibraryItem() {
|
|
||||||
return this.$store.state.streamLibraryItem
|
|
||||||
},
|
|
||||||
currentLibraryId() {
|
|
||||||
return this.$store.state.libraries.currentLibraryId
|
|
||||||
},
|
|
||||||
selectedAuthor() {
|
|
||||||
return this.$store.state.globals.selectedAuthor
|
|
||||||
},
|
|
||||||
authorSortBy() {
|
|
||||||
return this.$store.getters['user/getUserSetting']('authorSortBy') || 'name'
|
|
||||||
},
|
|
||||||
authorSortDesc() {
|
|
||||||
return !!this.$store.getters['user/getUserSetting']('authorSortDesc')
|
|
||||||
},
|
|
||||||
authorsSorted() {
|
|
||||||
const sortProp = this.authorSortBy
|
|
||||||
const bDesc = this.authorSortDesc ? -1 : 1
|
|
||||||
return this.authors.sort((a, b) => {
|
|
||||||
if (typeof a[sortProp] === 'number' && typeof b[sortProp] === 'number') {
|
|
||||||
// Fallback to name sort if equal
|
|
||||||
if (a[sortProp] === b[sortProp]) return a.name.localeCompare(b.name, undefined, { sensitivity: 'base' }) * bDesc
|
|
||||||
return a[sortProp] > b[sortProp] ? bDesc : -bDesc
|
|
||||||
}
|
|
||||||
return a[sortProp]?.localeCompare(b[sortProp], undefined, { sensitivity: 'base' }) * bDesc
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async init() {
|
|
||||||
this.authors = await this.$axios
|
|
||||||
.$get(`/api/libraries/${this.currentLibraryId}/authors`)
|
|
||||||
.then((response) => response.authors)
|
|
||||||
.catch((error) => {
|
|
||||||
console.error('Failed to load authors', error)
|
|
||||||
return []
|
|
||||||
})
|
|
||||||
this.loading = false
|
|
||||||
},
|
|
||||||
authorAdded(author) {
|
|
||||||
if (!this.authors.some((au) => au.id === author.id)) {
|
|
||||||
this.authors.push(author)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
authorUpdated(author) {
|
|
||||||
this.authors = this.authors.map((au) => {
|
|
||||||
if (au.id === author.id) {
|
|
||||||
return author
|
|
||||||
}
|
|
||||||
return au
|
|
||||||
})
|
|
||||||
},
|
|
||||||
authorRemoved(author) {
|
|
||||||
this.authors = this.authors.filter((au) => au.id !== author.id)
|
|
||||||
},
|
|
||||||
editAuthor(author) {
|
|
||||||
this.$store.commit('globals/showEditAuthorModal', author)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.init()
|
|
||||||
this.$root.socket.on('author_added', this.authorAdded)
|
|
||||||
this.$root.socket.on('author_updated', this.authorUpdated)
|
|
||||||
this.$root.socket.on('author_removed', this.authorRemoved)
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
this.$root.socket.off('author_added', this.authorAdded)
|
|
||||||
this.$root.socket.off('author_updated', this.authorUpdated)
|
|
||||||
this.$root.socket.off('author_removed', this.authorRemoved)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -27,7 +27,7 @@ export default {
|
|||||||
|
|
||||||
// Redirect podcast libraries
|
// Redirect podcast libraries
|
||||||
const library = libraryData.library
|
const library = libraryData.library
|
||||||
if (library.mediaType === 'podcast' && (params.id === 'collections' || params.id === 'series')) {
|
if (library.mediaType === 'podcast' && (params.id === 'collections' || params.id === 'series' || params.id === 'authors')) {
|
||||||
return redirect(`/library/${libraryId}`)
|
return redirect(`/library/${libraryId}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to updated narrator', error)
|
console.error('Failed to updated narrator', error)
|
||||||
this.$toast.error('Failed to update narrator')
|
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<div id="bookshelf" class="w-full overflow-y-auto px-2 py-6 sm:px-4 md:p-12 relative">
|
<div id="bookshelf" class="w-full overflow-y-auto px-2 py-6 sm:px-4 md:p-12 relative">
|
||||||
<div class="w-full max-w-4xl mx-auto flex">
|
<div class="w-full max-w-4xl mx-auto flex">
|
||||||
<form @submit.prevent="submit" class="flex flex-grow">
|
<form @submit.prevent="submit" class="flex flex-grow">
|
||||||
<ui-text-input v-model="searchInput" type="search" :disabled="processing" placeholder="Enter search term or RSS feed URL" class="flex-grow mr-2 text-sm md:text-base" />
|
<ui-text-input v-model="searchInput" type="search" :disabled="processing" :placeholder="$strings.MessagePodcastSearchField" class="flex-grow mr-2 text-sm md:text-base" />
|
||||||
<ui-btn type="submit" :disabled="processing" class="hidden md:block">{{ $strings.ButtonSubmit }}</ui-btn>
|
<ui-btn type="submit" :disabled="processing" class="hidden md:block">{{ $strings.ButtonSubmit }}</ui-btn>
|
||||||
<ui-btn type="submit" :disabled="processing" class="block md:hidden" small>{{ $strings.ButtonSubmit }}</ui-btn>
|
<ui-btn type="submit" :disabled="processing" class="block md:hidden" small>{{ $strings.ButtonSubmit }}</ui-btn>
|
||||||
</form>
|
</form>
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<a :href="podcast.pageUrl" class="text-base md:text-lg text-gray-200 hover:underline" target="_blank" @click.stop>{{ podcast.title }}</a>
|
<a :href="podcast.pageUrl" class="text-base md:text-lg text-gray-200 hover:underline" target="_blank" @click.stop>{{ podcast.title }}</a>
|
||||||
<widgets-explicit-indicator v-if="podcast.explicit" />
|
<widgets-explicit-indicator v-if="podcast.explicit" />
|
||||||
<widgets-already-in-library-indicator :already-in-library="podcast.alreadyInLibrary" />
|
<widgets-already-in-library-indicator v-if="podcast.alreadyInLibrary" />
|
||||||
</div>
|
</div>
|
||||||
<p class="text-sm md:text-base text-gray-300 whitespace-nowrap truncate">{{ $getString('LabelByAuthor', [podcast.artistName]) }}</p>
|
<p class="text-sm md:text-base text-gray-300 whitespace-nowrap truncate">{{ $getString('LabelByAuthor', [podcast.artistName]) }}</p>
|
||||||
<p class="text-xs text-gray-400 leading-5">{{ podcast.genres.join(', ') }}</p>
|
<p class="text-xs text-gray-400 leading-5">{{ podcast.genres.join(', ') }}</p>
|
||||||
@@ -108,7 +108,7 @@ export default {
|
|||||||
|
|
||||||
if (!txt || !txt.includes('<opml') || !txt.includes('<outline ')) {
|
if (!txt || !txt.includes('<opml') || !txt.includes('<outline ')) {
|
||||||
// Quick lazy check for valid OPML
|
// Quick lazy check for valid OPML
|
||||||
this.$toast.error('Invalid OPML file <opml> tag not found OR an <outline> tag was not found')
|
this.$toast.error(this.$strings.MessageTaskOpmlParseFastFail)
|
||||||
this.processing = false
|
this.processing = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -117,7 +117,7 @@ export default {
|
|||||||
.$post(`/api/podcasts/opml/parse`, { opmlText: txt })
|
.$post(`/api/podcasts/opml/parse`, { opmlText: txt })
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (!data.feeds?.length) {
|
if (!data.feeds?.length) {
|
||||||
this.$toast.error('No feeds found in OPML file')
|
this.$toast.error(this.$strings.MessageTaskOpmlParseNoneFound)
|
||||||
} else {
|
} else {
|
||||||
this.opmlFeeds = data.feeds || []
|
this.opmlFeeds = data.feeds || []
|
||||||
this.showOPMLFeedsModal = true
|
this.showOPMLFeedsModal = true
|
||||||
@@ -125,7 +125,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed', error)
|
console.error('Failed', error)
|
||||||
this.$toast.error('Failed to parse OPML file')
|
this.$toast.error(this.$strings.MessageTaskOpmlParseFailed)
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.processing = false
|
this.processing = false
|
||||||
@@ -191,7 +191,7 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!podcast.feedUrl) {
|
if (!podcast.feedUrl) {
|
||||||
this.$toast.error('Invalid podcast - no feed')
|
this.$toast.error(this.$strings.MessageNoPodcastFeed)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.processing = true
|
this.processing = true
|
||||||
@@ -211,15 +211,15 @@ export default {
|
|||||||
async fetchExistentPodcastsInYourLibrary() {
|
async fetchExistentPodcastsInYourLibrary() {
|
||||||
this.processing = true
|
this.processing = true
|
||||||
|
|
||||||
const podcasts = await this.$axios.$get(`/api/libraries/${this.currentLibraryId}/items?page=0&minified=1`).catch((error) => {
|
const podcastsResponse = await this.$axios.$get(`/api/libraries/${this.currentLibraryId}/podcast-titles`).catch((error) => {
|
||||||
console.error('Failed to fetch podcasts', error)
|
console.error('Failed to fetch podcasts', error)
|
||||||
return []
|
return []
|
||||||
})
|
})
|
||||||
this.existentPodcasts = podcasts.results.map((p) => {
|
this.existentPodcasts = podcastsResponse.podcasts.map((p) => {
|
||||||
return {
|
return {
|
||||||
title: p.media.metadata.title.toLowerCase(),
|
title: p.title.toLowerCase(),
|
||||||
itunesId: p.media.metadata.itunesId,
|
itunesId: p.itunesId,
|
||||||
id: p.id
|
id: p.libraryItemId
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.processing = false
|
this.processing = false
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
<ui-btn v-if="showPlayButton" :disabled="streaming" color="success" :padding-x="4" small class="flex items-center h-9 mr-2" @click="clickPlay">
|
<ui-btn v-if="showPlayButton" :disabled="streaming" color="success" :padding-x="4" small class="flex items-center h-9 mr-2" @click="clickPlay">
|
||||||
<span v-show="!streaming" class="material-symbols fill text-2xl -ml-2 pr-1 text-white">play_arrow</span>
|
<span v-show="!streaming" class="material-symbols fill text-2xl -ml-2 pr-1 text-white">play_arrow</span>
|
||||||
{{ streaming ? $strings.ButtonPlaying : $strings.ButtonPlay }}
|
{{ streaming ? $strings.ButtonPlaying : $strings.ButtonPlayAll }}
|
||||||
</ui-btn>
|
</ui-btn>
|
||||||
|
|
||||||
<ui-icon-btn icon="edit" class="mx-0.5" @click="editClick" />
|
<ui-icon-btn icon="edit" class="mx-0.5" @click="editClick" />
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<p v-if="mediaItemShare.playbackSession.displayAuthor" class="text-lg lg:text-xl text-slate-400 font-semibold text-center mb-1 truncate">{{ mediaItemShare.playbackSession.displayAuthor }}</p>
|
<p v-if="mediaItemShare.playbackSession.displayAuthor" class="text-lg lg:text-xl text-slate-400 font-semibold text-center mb-1 truncate">{{ mediaItemShare.playbackSession.displayAuthor }}</p>
|
||||||
|
|
||||||
<div class="w-full pt-16">
|
<div class="w-full pt-16">
|
||||||
<player-ui ref="audioPlayer" :chapters="chapters" :paused="isPaused" :loading="!hasLoaded" :is-podcast="false" hide-bookmarks hide-sleep-timer @playPause="playPause" @jumpForward="jumpForward" @jumpBackward="jumpBackward" @setVolume="setVolume" @setPlaybackRate="setPlaybackRate" @seek="seek" />
|
<player-ui ref="audioPlayer" :chapters="chapters" :current-chapter="currentChapter" :paused="isPaused" :loading="!hasLoaded" :is-podcast="false" hide-bookmarks hide-sleep-timer @playPause="playPause" @jumpForward="jumpForward" @jumpBackward="jumpBackward" @setVolume="setVolume" @setPlaybackRate="setPlaybackRate" @seek="seek" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -51,7 +51,8 @@ export default {
|
|||||||
windowHeight: 0,
|
windowHeight: 0,
|
||||||
listeningTimeSinceSync: 0,
|
listeningTimeSinceSync: 0,
|
||||||
coverRgb: null,
|
coverRgb: null,
|
||||||
coverBgIsLight: false
|
coverBgIsLight: false,
|
||||||
|
currentTime: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -60,16 +61,10 @@ export default {
|
|||||||
},
|
},
|
||||||
coverUrl() {
|
coverUrl() {
|
||||||
if (!this.playbackSession.coverPath) return `${this.$config.routerBasePath}/book_placeholder.jpg`
|
if (!this.playbackSession.coverPath) return `${this.$config.routerBasePath}/book_placeholder.jpg`
|
||||||
if (process.env.NODE_ENV === 'development') {
|
return `${this.$config.routerBasePath}/public/share/${this.mediaItemShare.slug}/cover`
|
||||||
return `http://localhost:3333/public/share/${this.mediaItemShare.slug}/cover`
|
|
||||||
}
|
|
||||||
return `/public/share/${this.mediaItemShare.slug}/cover`
|
|
||||||
},
|
},
|
||||||
audioTracks() {
|
audioTracks() {
|
||||||
return (this.playbackSession.audioTracks || []).map((track) => {
|
return (this.playbackSession.audioTracks || []).map((track) => {
|
||||||
if (process.env.NODE_ENV === 'development') {
|
|
||||||
track.contentUrl = `${process.env.serverUrl}${track.contentUrl}`
|
|
||||||
}
|
|
||||||
track.relativeContentUrl = track.contentUrl
|
track.relativeContentUrl = track.contentUrl
|
||||||
return track
|
return track
|
||||||
})
|
})
|
||||||
@@ -83,6 +78,9 @@ export default {
|
|||||||
chapters() {
|
chapters() {
|
||||||
return this.playbackSession.chapters || []
|
return this.playbackSession.chapters || []
|
||||||
},
|
},
|
||||||
|
currentChapter() {
|
||||||
|
return this.chapters.find((chapter) => chapter.start <= this.currentTime && this.currentTime < chapter.end)
|
||||||
|
},
|
||||||
coverAspectRatio() {
|
coverAspectRatio() {
|
||||||
const coverAspectRatio = this.playbackSession.coverAspectRatio
|
const coverAspectRatio = this.playbackSession.coverAspectRatio
|
||||||
return coverAspectRatio === this.$constants.BookCoverAspectRatio.STANDARD ? 1.6 : 1
|
return coverAspectRatio === this.$constants.BookCoverAspectRatio.STANDARD ? 1.6 : 1
|
||||||
@@ -154,6 +152,7 @@ export default {
|
|||||||
|
|
||||||
// Update UI
|
// Update UI
|
||||||
this.$refs.audioPlayer.setCurrentTime(time)
|
this.$refs.audioPlayer.setCurrentTime(time)
|
||||||
|
this.currentTime = time
|
||||||
},
|
},
|
||||||
setDuration() {
|
setDuration() {
|
||||||
if (!this.localAudioPlayer) return
|
if (!this.localAudioPlayer) return
|
||||||
|
|||||||
@@ -384,12 +384,6 @@ export default {
|
|||||||
else itemsFailed++
|
else itemsFailed++
|
||||||
this.updateItemCardStatus(item.index, result ? 'success' : 'failed')
|
this.updateItemCardStatus(item.index, result ? 'success' : 'failed')
|
||||||
}
|
}
|
||||||
if (itemsUploaded) {
|
|
||||||
this.$toast.success(`Successfully uploaded ${itemsUploaded} item${itemsUploaded > 1 ? 's' : ''}`)
|
|
||||||
}
|
|
||||||
if (itemsFailed) {
|
|
||||||
this.$toast.success(`Failed to upload ${itemsFailed} item${itemsFailed > 1 ? 's' : ''}`)
|
|
||||||
}
|
|
||||||
this.processing = false
|
this.processing = false
|
||||||
this.uploadFinished = true
|
this.uploadFinished = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,10 +23,6 @@ export default class AudioTrack {
|
|||||||
get relativeContentUrl() {
|
get relativeContentUrl() {
|
||||||
if (!this.contentUrl || this.contentUrl.startsWith('http')) return this.contentUrl
|
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 this.contentUrl + `?token=${this.userToken}`
|
return this.contentUrl + `?token=${this.userToken}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,260 +0,0 @@
|
|||||||
import Hls from 'hls.js'
|
|
||||||
import EventEmitter from 'events'
|
|
||||||
|
|
||||||
export default class LocalVideoPlayer extends EventEmitter {
|
|
||||||
constructor(ctx) {
|
|
||||||
super()
|
|
||||||
|
|
||||||
this.ctx = ctx
|
|
||||||
this.player = null
|
|
||||||
|
|
||||||
this.libraryItem = null
|
|
||||||
this.videoTrack = null
|
|
||||||
this.isHlsTranscode = null
|
|
||||||
this.hlsInstance = null
|
|
||||||
this.usingNativeplayer = false
|
|
||||||
this.startTime = 0
|
|
||||||
this.playWhenReady = false
|
|
||||||
this.defaultPlaybackRate = 1
|
|
||||||
|
|
||||||
this.playableMimeTypes = []
|
|
||||||
|
|
||||||
this.initialize()
|
|
||||||
}
|
|
||||||
|
|
||||||
initialize() {
|
|
||||||
if (document.getElementById('video-player')) {
|
|
||||||
document.getElementById('video-player').remove()
|
|
||||||
}
|
|
||||||
var videoEl = document.createElement('video')
|
|
||||||
videoEl.id = 'video-player'
|
|
||||||
// videoEl.style.display = 'none'
|
|
||||||
videoEl.className = 'absolute bg-black z-50'
|
|
||||||
videoEl.style.height = '216px'
|
|
||||||
videoEl.style.width = '384px'
|
|
||||||
videoEl.style.bottom = '80px'
|
|
||||||
videoEl.style.left = '16px'
|
|
||||||
document.body.appendChild(videoEl)
|
|
||||||
this.player = videoEl
|
|
||||||
|
|
||||||
this.player.addEventListener('play', this.evtPlay.bind(this))
|
|
||||||
this.player.addEventListener('pause', this.evtPause.bind(this))
|
|
||||||
this.player.addEventListener('progress', this.evtProgress.bind(this))
|
|
||||||
this.player.addEventListener('ended', this.evtEnded.bind(this))
|
|
||||||
this.player.addEventListener('error', this.evtError.bind(this))
|
|
||||||
this.player.addEventListener('loadedmetadata', this.evtLoadedMetadata.bind(this))
|
|
||||||
this.player.addEventListener('timeupdate', this.evtTimeupdate.bind(this))
|
|
||||||
|
|
||||||
var mimeTypes = ['video/mp4']
|
|
||||||
var mimeTypeCanPlayMap = {}
|
|
||||||
mimeTypes.forEach((mt) => {
|
|
||||||
var canPlay = this.player.canPlayType(mt)
|
|
||||||
mimeTypeCanPlayMap[mt] = canPlay
|
|
||||||
if (canPlay) this.playableMimeTypes.push(mt)
|
|
||||||
})
|
|
||||||
console.log(`[LocalVideoPlayer] Supported mime types`, mimeTypeCanPlayMap, this.playableMimeTypes)
|
|
||||||
}
|
|
||||||
|
|
||||||
evtPlay() {
|
|
||||||
this.emit('stateChange', 'PLAYING')
|
|
||||||
}
|
|
||||||
evtPause() {
|
|
||||||
this.emit('stateChange', 'PAUSED')
|
|
||||||
}
|
|
||||||
evtProgress() {
|
|
||||||
var lastBufferTime = this.getLastBufferedTime()
|
|
||||||
this.emit('buffertimeUpdate', lastBufferTime)
|
|
||||||
}
|
|
||||||
evtEnded() {
|
|
||||||
console.log(`[LocalVideoPlayer] Ended`)
|
|
||||||
this.emit('finished')
|
|
||||||
}
|
|
||||||
evtError(error) {
|
|
||||||
console.error('Player error', error)
|
|
||||||
this.emit('error', error)
|
|
||||||
}
|
|
||||||
evtLoadedMetadata(data) {
|
|
||||||
if (!this.isHlsTranscode) {
|
|
||||||
this.player.currentTime = this.startTime
|
|
||||||
}
|
|
||||||
|
|
||||||
this.emit('stateChange', 'LOADED')
|
|
||||||
if (this.playWhenReady) {
|
|
||||||
this.playWhenReady = false
|
|
||||||
this.play()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
evtTimeupdate() {
|
|
||||||
if (this.player.paused) {
|
|
||||||
this.emit('timeupdate', this.getCurrentTime())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
destroy() {
|
|
||||||
this.destroyHlsInstance()
|
|
||||||
if (this.player) {
|
|
||||||
this.player.remove()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
set(libraryItem, videoTrack, isHlsTranscode, startTime, playWhenReady = false) {
|
|
||||||
this.libraryItem = libraryItem
|
|
||||||
this.videoTrack = videoTrack
|
|
||||||
this.isHlsTranscode = isHlsTranscode
|
|
||||||
this.playWhenReady = playWhenReady
|
|
||||||
this.startTime = startTime
|
|
||||||
|
|
||||||
if (this.hlsInstance) {
|
|
||||||
this.destroyHlsInstance()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isHlsTranscode) {
|
|
||||||
this.setHlsStream()
|
|
||||||
} else {
|
|
||||||
this.setDirectPlay()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setHlsStream() {
|
|
||||||
// iOS does not support Media Elements but allows for HLS in the native video player
|
|
||||||
if (!Hls.isSupported()) {
|
|
||||||
console.warn('HLS is not supported - fallback to using video element')
|
|
||||||
this.usingNativeplayer = true
|
|
||||||
this.player.src = this.videoTrack.relativeContentUrl
|
|
||||||
this.player.currentTime = this.startTime
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var hlsOptions = {
|
|
||||||
startPosition: this.startTime || -1
|
|
||||||
// No longer needed because token is put in a query string
|
|
||||||
// xhrSetup: (xhr) => {
|
|
||||||
// xhr.setRequestHeader('Authorization', `Bearer ${this.token}`)
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
this.hlsInstance = new Hls(hlsOptions)
|
|
||||||
|
|
||||||
this.hlsInstance.attachMedia(this.player)
|
|
||||||
this.hlsInstance.on(Hls.Events.MEDIA_ATTACHED, () => {
|
|
||||||
this.hlsInstance.loadSource(this.videoTrack.relativeContentUrl)
|
|
||||||
|
|
||||||
this.hlsInstance.on(Hls.Events.MANIFEST_PARSED, () => {
|
|
||||||
console.log('[HLS] Manifest Parsed')
|
|
||||||
})
|
|
||||||
|
|
||||||
this.hlsInstance.on(Hls.Events.ERROR, (e, data) => {
|
|
||||||
console.error('[HLS] Error', data.type, data.details, data)
|
|
||||||
if (data.details === Hls.ErrorDetails.BUFFER_STALLED_ERROR) {
|
|
||||||
console.error('[HLS] BUFFER STALLED ERROR')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.hlsInstance.on(Hls.Events.DESTROYING, () => {
|
|
||||||
console.log('[HLS] Destroying HLS Instance')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
setDirectPlay() {
|
|
||||||
this.player.src = this.videoTrack.relativeContentUrl
|
|
||||||
console.log(`[LocalVideoPlayer] Loading track src ${this.videoTrack.relativeContentUrl}`)
|
|
||||||
this.player.load()
|
|
||||||
}
|
|
||||||
|
|
||||||
destroyHlsInstance() {
|
|
||||||
if (!this.hlsInstance) return
|
|
||||||
if (this.hlsInstance.destroy) {
|
|
||||||
var temp = this.hlsInstance
|
|
||||||
temp.destroy()
|
|
||||||
}
|
|
||||||
this.hlsInstance = null
|
|
||||||
}
|
|
||||||
|
|
||||||
async resetStream(startTime) {
|
|
||||||
this.destroyHlsInstance()
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
|
||||||
this.set(this.libraryItem, this.videoTrack, this.isHlsTranscode, startTime, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
playPause() {
|
|
||||||
if (!this.player) return
|
|
||||||
if (this.player.paused) this.play()
|
|
||||||
else this.pause()
|
|
||||||
}
|
|
||||||
|
|
||||||
play() {
|
|
||||||
if (this.player) this.player.play()
|
|
||||||
}
|
|
||||||
|
|
||||||
pause() {
|
|
||||||
if (this.player) this.player.pause()
|
|
||||||
}
|
|
||||||
|
|
||||||
getCurrentTime() {
|
|
||||||
return this.player ? this.player.currentTime : 0
|
|
||||||
}
|
|
||||||
|
|
||||||
getDuration() {
|
|
||||||
return this.videoTrack.duration
|
|
||||||
}
|
|
||||||
|
|
||||||
setPlaybackRate(playbackRate) {
|
|
||||||
if (!this.player) return
|
|
||||||
this.defaultPlaybackRate = playbackRate
|
|
||||||
this.player.playbackRate = playbackRate
|
|
||||||
}
|
|
||||||
|
|
||||||
seek(time) {
|
|
||||||
if (!this.player) return
|
|
||||||
this.player.currentTime = Math.max(0, time)
|
|
||||||
}
|
|
||||||
|
|
||||||
setVolume(volume) {
|
|
||||||
if (!this.player) return
|
|
||||||
this.player.volume = volume
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utils
|
|
||||||
isValidDuration(duration) {
|
|
||||||
if (duration && !isNaN(duration) && duration !== Number.POSITIVE_INFINITY && duration !== Number.NEGATIVE_INFINITY) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
getBufferedRanges() {
|
|
||||||
if (!this.player) return []
|
|
||||||
const ranges = []
|
|
||||||
const seekable = this.player.buffered || []
|
|
||||||
|
|
||||||
let offset = 0
|
|
||||||
|
|
||||||
for (let i = 0, length = seekable.length; i < length; i++) {
|
|
||||||
let start = seekable.start(i)
|
|
||||||
let end = seekable.end(i)
|
|
||||||
if (!this.isValidDuration(start)) {
|
|
||||||
start = 0
|
|
||||||
}
|
|
||||||
if (!this.isValidDuration(end)) {
|
|
||||||
end = 0
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
ranges.push({
|
|
||||||
start: start + offset,
|
|
||||||
end: end + offset
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return ranges
|
|
||||||
}
|
|
||||||
|
|
||||||
getLastBufferedTime() {
|
|
||||||
var bufferedRanges = this.getBufferedRanges()
|
|
||||||
if (!bufferedRanges.length) return 0
|
|
||||||
|
|
||||||
var buff = bufferedRanges.find((buff) => buff.start < this.player.currentTime && buff.end > this.player.currentTime)
|
|
||||||
if (buff) return buff.end
|
|
||||||
|
|
||||||
var last = bufferedRanges[bufferedRanges.length - 1]
|
|
||||||
return last.end
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
import LocalAudioPlayer from './LocalAudioPlayer'
|
import LocalAudioPlayer from './LocalAudioPlayer'
|
||||||
import LocalVideoPlayer from './LocalVideoPlayer'
|
|
||||||
import CastPlayer from './CastPlayer'
|
import CastPlayer from './CastPlayer'
|
||||||
import AudioTrack from './AudioTrack'
|
import AudioTrack from './AudioTrack'
|
||||||
import VideoTrack from './VideoTrack'
|
|
||||||
|
|
||||||
export default class PlayerHandler {
|
export default class PlayerHandler {
|
||||||
constructor(ctx) {
|
constructor(ctx) {
|
||||||
@@ -16,8 +14,6 @@ export default class PlayerHandler {
|
|||||||
this.player = null
|
this.player = null
|
||||||
this.playerState = 'IDLE'
|
this.playerState = 'IDLE'
|
||||||
this.isHlsTranscode = false
|
this.isHlsTranscode = false
|
||||||
this.isVideo = false
|
|
||||||
this.isMusic = false
|
|
||||||
this.currentSessionId = null
|
this.currentSessionId = null
|
||||||
this.startTimeOverride = undefined // Used for starting playback at a specific time (i.e. clicking bookmark from library item page)
|
this.startTimeOverride = undefined // Used for starting playback at a specific time (i.e. clicking bookmark from library item page)
|
||||||
this.startTime = 0
|
this.startTime = 0
|
||||||
@@ -65,12 +61,10 @@ export default class PlayerHandler {
|
|||||||
|
|
||||||
load(libraryItem, episodeId, playWhenReady, playbackRate, startTimeOverride = undefined) {
|
load(libraryItem, episodeId, playWhenReady, playbackRate, startTimeOverride = undefined) {
|
||||||
this.libraryItem = libraryItem
|
this.libraryItem = libraryItem
|
||||||
this.isVideo = libraryItem.mediaType === 'video'
|
|
||||||
this.isMusic = libraryItem.mediaType === 'music'
|
|
||||||
|
|
||||||
this.episodeId = episodeId
|
this.episodeId = episodeId
|
||||||
this.playWhenReady = playWhenReady
|
this.playWhenReady = playWhenReady
|
||||||
this.initialPlaybackRate = this.isMusic ? 1 : playbackRate
|
this.initialPlaybackRate = playbackRate
|
||||||
|
|
||||||
this.startTimeOverride = startTimeOverride == null || isNaN(startTimeOverride) ? undefined : Number(startTimeOverride)
|
this.startTimeOverride = startTimeOverride == null || isNaN(startTimeOverride) ? undefined : Number(startTimeOverride)
|
||||||
|
|
||||||
@@ -97,7 +91,7 @@ export default class PlayerHandler {
|
|||||||
this.playWhenReady = playWhenReady
|
this.playWhenReady = playWhenReady
|
||||||
this.prepare()
|
this.prepare()
|
||||||
}
|
}
|
||||||
} else if (!this.isCasting && !(this.player instanceof LocalAudioPlayer) && !(this.player instanceof LocalVideoPlayer)) {
|
} else if (!this.isCasting && !(this.player instanceof LocalAudioPlayer)) {
|
||||||
console.log('[PlayerHandler] Switching to local player')
|
console.log('[PlayerHandler] Switching to local player')
|
||||||
|
|
||||||
this.stopPlayInterval()
|
this.stopPlayInterval()
|
||||||
@@ -107,11 +101,7 @@ export default class PlayerHandler {
|
|||||||
this.player.destroy()
|
this.player.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isVideo) {
|
this.player = new LocalAudioPlayer(this.ctx)
|
||||||
this.player = new LocalVideoPlayer(this.ctx)
|
|
||||||
} else {
|
|
||||||
this.player = new LocalAudioPlayer(this.ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setPlayerListeners()
|
this.setPlayerListeners()
|
||||||
|
|
||||||
@@ -203,7 +193,7 @@ export default class PlayerHandler {
|
|||||||
supportedMimeTypes: this.player.playableMimeTypes,
|
supportedMimeTypes: this.player.playableMimeTypes,
|
||||||
mediaPlayer: this.isCasting ? 'chromecast' : 'html5',
|
mediaPlayer: this.isCasting ? 'chromecast' : 'html5',
|
||||||
forceTranscode,
|
forceTranscode,
|
||||||
forceDirectPlay: this.isCasting || this.isVideo // TODO: add transcode support for chromecast
|
forceDirectPlay: this.isCasting // TODO: add transcode support for chromecast
|
||||||
}
|
}
|
||||||
|
|
||||||
const path = this.episodeId ? `/api/items/${this.libraryItem.id}/play/${this.episodeId}` : `/api/items/${this.libraryItem.id}/play`
|
const path = this.episodeId ? `/api/items/${this.libraryItem.id}/play/${this.episodeId}` : `/api/items/${this.libraryItem.id}/play`
|
||||||
@@ -218,7 +208,6 @@ export default class PlayerHandler {
|
|||||||
if (!this.player) this.switchPlayer() // Must set player first for open sessions
|
if (!this.player) this.switchPlayer() // Must set player first for open sessions
|
||||||
|
|
||||||
this.libraryItem = session.libraryItem
|
this.libraryItem = session.libraryItem
|
||||||
this.isVideo = session.libraryItem.mediaType === 'video'
|
|
||||||
this.playWhenReady = false
|
this.playWhenReady = false
|
||||||
this.initialPlaybackRate = playbackRate
|
this.initialPlaybackRate = playbackRate
|
||||||
this.startTimeOverride = undefined
|
this.startTimeOverride = undefined
|
||||||
@@ -237,28 +226,16 @@ export default class PlayerHandler {
|
|||||||
|
|
||||||
console.log('[PlayerHandler] Preparing Session', session)
|
console.log('[PlayerHandler] Preparing Session', session)
|
||||||
|
|
||||||
if (session.videoTrack) {
|
var audioTracks = session.audioTracks.map((at) => new AudioTrack(at, this.userToken))
|
||||||
var videoTrack = new VideoTrack(session.videoTrack, this.userToken)
|
|
||||||
|
|
||||||
this.ctx.playerLoading = true
|
this.ctx.playerLoading = true
|
||||||
this.isHlsTranscode = true
|
this.isHlsTranscode = true
|
||||||
if (session.playMethod === this.ctx.$constants.PlayMethod.DIRECTPLAY) {
|
if (session.playMethod === this.ctx.$constants.PlayMethod.DIRECTPLAY) {
|
||||||
this.isHlsTranscode = false
|
this.isHlsTranscode = false
|
||||||
}
|
|
||||||
|
|
||||||
this.player.set(this.libraryItem, videoTrack, this.isHlsTranscode, this.startTime, this.playWhenReady)
|
|
||||||
} else {
|
|
||||||
var audioTracks = session.audioTracks.map((at) => new AudioTrack(at, this.userToken))
|
|
||||||
|
|
||||||
this.ctx.playerLoading = true
|
|
||||||
this.isHlsTranscode = true
|
|
||||||
if (session.playMethod === this.ctx.$constants.PlayMethod.DIRECTPLAY) {
|
|
||||||
this.isHlsTranscode = false
|
|
||||||
}
|
|
||||||
|
|
||||||
this.player.set(this.libraryItem, audioTracks, this.isHlsTranscode, this.startTime, this.playWhenReady)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.player.set(this.libraryItem, audioTracks, this.isHlsTranscode, this.startTime, this.playWhenReady)
|
||||||
|
|
||||||
// browser media session api
|
// browser media session api
|
||||||
this.ctx.setMediaSession()
|
this.ctx.setMediaSession()
|
||||||
}
|
}
|
||||||
@@ -333,8 +310,6 @@ export default class PlayerHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sendProgressSync(currentTime) {
|
sendProgressSync(currentTime) {
|
||||||
if (this.isMusic) return
|
|
||||||
|
|
||||||
const diffSinceLastSync = Math.abs(this.lastSyncTime - currentTime)
|
const diffSinceLastSync = Math.abs(this.lastSyncTime - currentTime)
|
||||||
if (diffSinceLastSync < 1) return
|
if (diffSinceLastSync < 1) return
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
export default class VideoTrack {
|
|
||||||
constructor(track, userToken) {
|
|
||||||
this.index = track.index || 0
|
|
||||||
this.startOffset = track.startOffset || 0 // Total time of all previous tracks
|
|
||||||
this.duration = track.duration || 0
|
|
||||||
this.title = track.title || ''
|
|
||||||
this.contentUrl = track.contentUrl || null
|
|
||||||
this.mimeType = track.mimeType
|
|
||||||
this.metadata = track.metadata || {}
|
|
||||||
|
|
||||||
this.userToken = userToken
|
|
||||||
}
|
|
||||||
|
|
||||||
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}`
|
|
||||||
}
|
|
||||||
|
|
||||||
get relativeContentUrl() {
|
|
||||||
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 this.contentUrl + `?token=${this.userToken}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
export default function ({ $axios, store, $config }) {
|
export default function ({ $axios, store, $config }) {
|
||||||
$axios.onRequest(config => {
|
$axios.onRequest((config) => {
|
||||||
if (!config.url) {
|
if (!config.url) {
|
||||||
console.error('Axios request invalid config', config)
|
console.error('Axios request invalid config', config)
|
||||||
return
|
return
|
||||||
@@ -13,12 +13,11 @@ export default function ({ $axios, store, $config }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
config.url = `/dev${config.url}`
|
|
||||||
console.log('Making request to ' + config.url)
|
console.log('Making request to ' + config.url)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
$axios.onError(error => {
|
$axios.onError((error) => {
|
||||||
const code = parseInt(error.response && error.response.status)
|
const code = parseInt(error.response && error.response.status)
|
||||||
const message = error.response ? error.response.data || 'Unknown Error' : 'Unknown Error'
|
const message = error.response ? error.response.data || 'Unknown Error' : 'Unknown Error'
|
||||||
console.error('Axios error', code, message)
|
console.error('Axios error', code, message)
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ const languageCodeMap = {
|
|||||||
pl: { label: 'Polski', dateFnsLocale: 'pl' },
|
pl: { label: 'Polski', dateFnsLocale: 'pl' },
|
||||||
'pt-br': { label: 'Português (Brasil)', dateFnsLocale: 'ptBR' },
|
'pt-br': { label: 'Português (Brasil)', dateFnsLocale: 'ptBR' },
|
||||||
ru: { label: 'Русский', dateFnsLocale: 'ru' },
|
ru: { label: 'Русский', dateFnsLocale: 'ru' },
|
||||||
|
sl: { label: 'Slovenščina', dateFnsLocale: 'sl' },
|
||||||
sv: { label: 'Svenska', dateFnsLocale: 'sv' },
|
sv: { label: 'Svenska', dateFnsLocale: 'sv' },
|
||||||
uk: { label: 'Українська', dateFnsLocale: 'uk' },
|
uk: { label: 'Українська', dateFnsLocale: 'uk' },
|
||||||
'vi-vn': { label: 'Tiếng Việt', dateFnsLocale: 'vi' },
|
'vi-vn': { label: 'Tiếng Việt', dateFnsLocale: 'vi' },
|
||||||
@@ -88,10 +89,10 @@ Vue.prototype.$strings = { ...enUsStrings }
|
|||||||
* Get string and substitute
|
* Get string and substitute
|
||||||
*
|
*
|
||||||
* @param {string} key
|
* @param {string} key
|
||||||
* @param {string[]} subs
|
* @param {string[]} [subs=[]]
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
Vue.prototype.$getString = (key, subs) => {
|
Vue.prototype.$getString = (key, subs = []) => {
|
||||||
if (!Vue.prototype.$strings[key]) return ''
|
if (!Vue.prototype.$strings[key]) return ''
|
||||||
if (subs?.length && Array.isArray(subs)) {
|
if (subs?.length && Array.isArray(subs)) {
|
||||||
return supplant(Vue.prototype.$strings[key], subs)
|
return supplant(Vue.prototype.$strings[key], subs)
|
||||||
|
|||||||
@@ -11,14 +11,17 @@ Vue.prototype.$bytesPretty = (bytes, decimals = 2) => {
|
|||||||
if (isNaN(bytes) || bytes == 0) {
|
if (isNaN(bytes) || bytes == 0) {
|
||||||
return '0 Bytes'
|
return '0 Bytes'
|
||||||
}
|
}
|
||||||
const k = 1024
|
const k = 1000
|
||||||
const dm = decimals < 0 ? 0 : decimals
|
const dm = decimals < 0 ? 0 : decimals
|
||||||
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
||||||
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
||||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
Vue.prototype.$elapsedPretty = (seconds, useFullNames = false) => {
|
Vue.prototype.$elapsedPretty = (seconds, useFullNames = false, useMilliseconds = false) => {
|
||||||
|
if (useMilliseconds && seconds > 0 && seconds < 1) {
|
||||||
|
return `${Math.floor(seconds * 1000)} ms`
|
||||||
|
}
|
||||||
if (seconds < 60) {
|
if (seconds < 60) {
|
||||||
return `${Math.floor(seconds)} sec${useFullNames ? 'onds' : ''}`
|
return `${Math.floor(seconds)} sec${useFullNames ? 'onds' : ''}`
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-15
@@ -72,13 +72,13 @@ export const state = () => ({
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
podcastTypes: [
|
podcastTypes: [
|
||||||
{ text: 'Episodic', value: 'episodic' },
|
{ text: 'Episodic', value: 'episodic', descriptionKey: 'LabelEpisodic' },
|
||||||
{ text: 'Serial', value: 'serial' }
|
{ text: 'Serial', value: 'serial', descriptionKey: 'LabelSerial' }
|
||||||
],
|
],
|
||||||
episodeTypes: [
|
episodeTypes: [
|
||||||
{ text: 'Full', value: 'full' },
|
{ text: 'Full', value: 'full', descriptionKey: 'LabelFull' },
|
||||||
{ text: 'Trailer', value: 'trailer' },
|
{ text: 'Trailer', value: 'trailer', descriptionKey: 'LabelTrailer' },
|
||||||
{ text: 'Bonus', value: 'bonus' }
|
{ text: 'Bonus', value: 'bonus', descriptionKey: 'LabelBonus' }
|
||||||
],
|
],
|
||||||
libraryIcons: ['database', 'audiobookshelf', 'books-1', 'books-2', 'book-1', 'microphone-1', 'microphone-3', 'radio', 'podcast', 'rss', 'headphones', 'music', 'file-picture', 'rocket', 'power', 'star', 'heart']
|
libraryIcons: ['database', 'audiobookshelf', 'books-1', 'books-2', 'book-1', 'microphone-1', 'microphone-3', 'radio', 'podcast', 'rss', 'headphones', 'music', 'file-picture', 'rocket', 'power', 'star', 'heart']
|
||||||
})
|
})
|
||||||
@@ -98,12 +98,6 @@ export const getters = {
|
|||||||
const userToken = rootGetters['user/getToken']
|
const userToken = rootGetters['user/getToken']
|
||||||
const lastUpdate = libraryItem.updatedAt || Date.now()
|
const lastUpdate = libraryItem.updatedAt || Date.now()
|
||||||
const libraryItemId = libraryItem.libraryItemId || libraryItem.id // Workaround for /users/:id page showing media progress covers
|
const libraryItemId = libraryItem.libraryItemId || libraryItem.id // Workaround for /users/:id page showing media progress covers
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
|
||||||
// Testing
|
|
||||||
return `http://localhost:3333${rootState.routerBasePath}/api/items/${libraryItemId}/cover?token=${userToken}&ts=${lastUpdate}${raw ? '&raw=1' : ''}`
|
|
||||||
}
|
|
||||||
|
|
||||||
return `${rootState.routerBasePath}/api/items/${libraryItemId}/cover?token=${userToken}&ts=${lastUpdate}${raw ? '&raw=1' : ''}`
|
return `${rootState.routerBasePath}/api/items/${libraryItemId}/cover?token=${userToken}&ts=${lastUpdate}${raw ? '&raw=1' : ''}`
|
||||||
},
|
},
|
||||||
getLibraryItemCoverSrcById:
|
getLibraryItemCoverSrcById:
|
||||||
@@ -112,10 +106,6 @@ export const getters = {
|
|||||||
const placeholder = `${rootState.routerBasePath}/book_placeholder.jpg`
|
const placeholder = `${rootState.routerBasePath}/book_placeholder.jpg`
|
||||||
if (!libraryItemId) return placeholder
|
if (!libraryItemId) return placeholder
|
||||||
const userToken = rootGetters['user/getToken']
|
const userToken = rootGetters['user/getToken']
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
|
||||||
// Testing
|
|
||||||
return `http://localhost:3333${rootState.routerBasePath}/api/items/${libraryItemId}/cover?token=${userToken}${raw ? '&raw=1' : ''}${timestamp ? `&ts=${timestamp}` : ''}`
|
|
||||||
}
|
|
||||||
return `${rootState.routerBasePath}/api/items/${libraryItemId}/cover?token=${userToken}${raw ? '&raw=1' : ''}${timestamp ? `&ts=${timestamp}` : ''}`
|
return `${rootState.routerBasePath}/api/items/${libraryItemId}/cover?token=${userToken}${raw ? '&raw=1' : ''}${timestamp ? `&ts=${timestamp}` : ''}`
|
||||||
},
|
},
|
||||||
getIsBatchSelectingMediaItems: (state) => {
|
getIsBatchSelectingMediaItems: (state) => {
|
||||||
|
|||||||
@@ -240,7 +240,8 @@ export const mutations = {
|
|||||||
series: [],
|
series: [],
|
||||||
narrators: [],
|
narrators: [],
|
||||||
languages: [],
|
languages: [],
|
||||||
publishers: []
|
publishers: [],
|
||||||
|
publishedDecades: []
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
const mediaMetadata = libraryItem.media.metadata
|
const mediaMetadata = libraryItem.media.metadata
|
||||||
@@ -307,6 +308,16 @@ export const mutations = {
|
|||||||
state.filterData.publishers.sort((a, b) => a.localeCompare(b))
|
state.filterData.publishers.sort((a, b) => a.localeCompare(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add publishedDecades
|
||||||
|
if (mediaMetadata.publishedYear && !isNaN(mediaMetadata.publishedYear)) {
|
||||||
|
const publishedYear = parseInt(mediaMetadata.publishedYear, 10)
|
||||||
|
const decade = (Math.floor(publishedYear / 10) * 10).toString()
|
||||||
|
if (!state.filterData.publishedDecades.includes(decade)) {
|
||||||
|
state.filterData.publishedDecades.push(decade)
|
||||||
|
state.filterData.publishedDecades.sort((a, b) => a - b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add language
|
// Add language
|
||||||
if (mediaMetadata.language && !state.filterData.languages.includes(mediaMetadata.language)) {
|
if (mediaMetadata.language && !state.filterData.languages.includes(mediaMetadata.language)) {
|
||||||
state.filterData.languages.push(mediaMetadata.language)
|
state.filterData.languages.push(mediaMetadata.language)
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ export const actions = {
|
|||||||
if (state.settings.orderBy == 'media.metadata.publishedYear') {
|
if (state.settings.orderBy == 'media.metadata.publishedYear') {
|
||||||
settingsUpdate.orderBy = 'media.metadata.title'
|
settingsUpdate.orderBy = 'media.metadata.title'
|
||||||
}
|
}
|
||||||
const invalidFilters = ['series', 'authors', 'narrators', 'publishers', 'languages', 'progress', 'issues', 'ebooks', 'abridged']
|
const invalidFilters = ['series', 'authors', 'narrators', 'publishers', 'publishedDecades', 'languages', 'progress', 'issues', 'ebooks', 'abridged']
|
||||||
const filterByFirstPart = (state.settings.filterBy || '').split('.').shift()
|
const filterByFirstPart = (state.settings.filterBy || '').split('.').shift()
|
||||||
if (invalidFilters.includes(filterByFirstPart)) {
|
if (invalidFilters.includes(filterByFirstPart)) {
|
||||||
settingsUpdate.filterBy = 'all'
|
settingsUpdate.filterBy = 'all'
|
||||||
|
|||||||
@@ -711,10 +711,8 @@
|
|||||||
"PlaceholderNewPlaylist": "Ново име на плейлиста",
|
"PlaceholderNewPlaylist": "Ново име на плейлиста",
|
||||||
"PlaceholderSearch": "Търсене...",
|
"PlaceholderSearch": "Търсене...",
|
||||||
"PlaceholderSearchEpisode": "Търсене на Епизоди...",
|
"PlaceholderSearchEpisode": "Търсене на Епизоди...",
|
||||||
"ToastAccountUpdateFailed": "Неуспешно обновяване на акаунта",
|
|
||||||
"ToastAccountUpdateSuccess": "Успешно обновяване на акаунта",
|
"ToastAccountUpdateSuccess": "Успешно обновяване на акаунта",
|
||||||
"ToastAuthorImageRemoveSuccess": "Авторската снимка е премахната",
|
"ToastAuthorImageRemoveSuccess": "Авторската снимка е премахната",
|
||||||
"ToastAuthorUpdateFailed": "Неуспешно обновяване на автора",
|
|
||||||
"ToastAuthorUpdateMerged": "Обновяване на автора сливано",
|
"ToastAuthorUpdateMerged": "Обновяване на автора сливано",
|
||||||
"ToastAuthorUpdateSuccess": "Автора обновен",
|
"ToastAuthorUpdateSuccess": "Автора обновен",
|
||||||
"ToastAuthorUpdateSuccessNoImageFound": "Автор обновен (не е намерена снимка)",
|
"ToastAuthorUpdateSuccessNoImageFound": "Автор обновен (не е намерена снимка)",
|
||||||
@@ -728,17 +726,13 @@
|
|||||||
"ToastBookmarkCreateFailed": "Неуспешно създаване на отметка",
|
"ToastBookmarkCreateFailed": "Неуспешно създаване на отметка",
|
||||||
"ToastBookmarkCreateSuccess": "Отметката е създадена",
|
"ToastBookmarkCreateSuccess": "Отметката е създадена",
|
||||||
"ToastBookmarkRemoveSuccess": "Отметката е премахната",
|
"ToastBookmarkRemoveSuccess": "Отметката е премахната",
|
||||||
"ToastBookmarkUpdateFailed": "Неуспешно обновяване на отметка",
|
|
||||||
"ToastBookmarkUpdateSuccess": "Отметката е обновена",
|
"ToastBookmarkUpdateSuccess": "Отметката е обновена",
|
||||||
"ToastChaptersHaveErrors": "Главите имат грешки",
|
"ToastChaptersHaveErrors": "Главите имат грешки",
|
||||||
"ToastChaptersMustHaveTitles": "Главите трябва да имат заглавия",
|
"ToastChaptersMustHaveTitles": "Главите трябва да имат заглавия",
|
||||||
"ToastCollectionItemsRemoveSuccess": "Елемент(и) премахнати от колекция",
|
"ToastCollectionItemsRemoveSuccess": "Елемент(и) премахнати от колекция",
|
||||||
"ToastCollectionRemoveSuccess": "Колекцията е премахната",
|
"ToastCollectionRemoveSuccess": "Колекцията е премахната",
|
||||||
"ToastCollectionUpdateFailed": "Неуспешно обновяване на колекция",
|
|
||||||
"ToastCollectionUpdateSuccess": "Колекцията е обновена",
|
"ToastCollectionUpdateSuccess": "Колекцията е обновена",
|
||||||
"ToastItemCoverUpdateFailed": "Неуспешно обновяване на корица на елемент",
|
|
||||||
"ToastItemCoverUpdateSuccess": "Корицата на елемента е обновена",
|
"ToastItemCoverUpdateSuccess": "Корицата на елемента е обновена",
|
||||||
"ToastItemDetailsUpdateFailed": "Неуспешно обновяване на детайли на елемент",
|
|
||||||
"ToastItemDetailsUpdateSuccess": "Детайлите на елемента са обновени",
|
"ToastItemDetailsUpdateSuccess": "Детайлите на елемента са обновени",
|
||||||
"ToastItemMarkedAsFinishedFailed": "Неуспешно маркиране като завършено",
|
"ToastItemMarkedAsFinishedFailed": "Неуспешно маркиране като завършено",
|
||||||
"ToastItemMarkedAsFinishedSuccess": "Елементът е маркиран като завършен",
|
"ToastItemMarkedAsFinishedSuccess": "Елементът е маркиран като завършен",
|
||||||
@@ -750,12 +744,10 @@
|
|||||||
"ToastLibraryDeleteSuccess": "Библиотеката е изтрита",
|
"ToastLibraryDeleteSuccess": "Библиотеката е изтрита",
|
||||||
"ToastLibraryScanFailedToStart": "Неуспешно стартиране на сканиране",
|
"ToastLibraryScanFailedToStart": "Неуспешно стартиране на сканиране",
|
||||||
"ToastLibraryScanStarted": "Сканирането на библиотеката е стартирано",
|
"ToastLibraryScanStarted": "Сканирането на библиотеката е стартирано",
|
||||||
"ToastLibraryUpdateFailed": "Неуспешно обновяване на библиотека",
|
|
||||||
"ToastLibraryUpdateSuccess": "Библиотеката \"{0}\" е обновена",
|
"ToastLibraryUpdateSuccess": "Библиотеката \"{0}\" е обновена",
|
||||||
"ToastPlaylistCreateFailed": "Неуспешно създаване на плейлист",
|
"ToastPlaylistCreateFailed": "Неуспешно създаване на плейлист",
|
||||||
"ToastPlaylistCreateSuccess": "Плейлистът е създаден",
|
"ToastPlaylistCreateSuccess": "Плейлистът е създаден",
|
||||||
"ToastPlaylistRemoveSuccess": "Плейлистът е премахнат",
|
"ToastPlaylistRemoveSuccess": "Плейлистът е премахнат",
|
||||||
"ToastPlaylistUpdateFailed": "Неуспешно обновяване на плейлист",
|
|
||||||
"ToastPlaylistUpdateSuccess": "Плейлистът е обновен",
|
"ToastPlaylistUpdateSuccess": "Плейлистът е обновен",
|
||||||
"ToastPodcastCreateFailed": "Неуспешно създаване на подкаст",
|
"ToastPodcastCreateFailed": "Неуспешно създаване на подкаст",
|
||||||
"ToastPodcastCreateSuccess": "Подкастът е създаден",
|
"ToastPodcastCreateSuccess": "Подкастът е създаден",
|
||||||
|
|||||||
+237
-22
@@ -8,7 +8,8 @@
|
|||||||
"ButtonAddYourFirstLibrary": "আপনার প্রথম লাইব্রেরি যোগ করুন",
|
"ButtonAddYourFirstLibrary": "আপনার প্রথম লাইব্রেরি যোগ করুন",
|
||||||
"ButtonApply": "প্রয়োগ করুন",
|
"ButtonApply": "প্রয়োগ করুন",
|
||||||
"ButtonApplyChapters": "অধ্যায় প্রয়োগ করুন",
|
"ButtonApplyChapters": "অধ্যায় প্রয়োগ করুন",
|
||||||
"ButtonAuthors": "লেখক",
|
"ButtonAuthors": "লেখকগণ",
|
||||||
|
"ButtonBack": "পেছনে যান",
|
||||||
"ButtonBrowseForFolder": "ফোল্ডারের জন্য ব্রাউজ করুন",
|
"ButtonBrowseForFolder": "ফোল্ডারের জন্য ব্রাউজ করুন",
|
||||||
"ButtonCancel": "বাতিল করুন",
|
"ButtonCancel": "বাতিল করুন",
|
||||||
"ButtonCancelEncode": "এনকোড বাতিল করুন",
|
"ButtonCancelEncode": "এনকোড বাতিল করুন",
|
||||||
@@ -18,6 +19,7 @@
|
|||||||
"ButtonChooseFiles": "ফাইল চয়ন করুন",
|
"ButtonChooseFiles": "ফাইল চয়ন করুন",
|
||||||
"ButtonClearFilter": "ফিল্টার পরিষ্কার করুন",
|
"ButtonClearFilter": "ফিল্টার পরিষ্কার করুন",
|
||||||
"ButtonCloseFeed": "ফিড বন্ধ করুন",
|
"ButtonCloseFeed": "ফিড বন্ধ করুন",
|
||||||
|
"ButtonCloseSession": "খোলা সেশন বন্ধ করুন",
|
||||||
"ButtonCollections": "সংগ্রহ",
|
"ButtonCollections": "সংগ্রহ",
|
||||||
"ButtonConfigureScanner": "স্ক্যানার কনফিগার করুন",
|
"ButtonConfigureScanner": "স্ক্যানার কনফিগার করুন",
|
||||||
"ButtonCreate": "তৈরি করুন",
|
"ButtonCreate": "তৈরি করুন",
|
||||||
@@ -27,6 +29,9 @@
|
|||||||
"ButtonEdit": "সম্পাদনা করুন",
|
"ButtonEdit": "সম্পাদনা করুন",
|
||||||
"ButtonEditChapters": "অধ্যায় সম্পাদনা করুন",
|
"ButtonEditChapters": "অধ্যায় সম্পাদনা করুন",
|
||||||
"ButtonEditPodcast": "পডকাস্ট সম্পাদনা করুন",
|
"ButtonEditPodcast": "পডকাস্ট সম্পাদনা করুন",
|
||||||
|
"ButtonEnable": "সক্রিয় করুন",
|
||||||
|
"ButtonFireAndFail": "সক্রিয় এবং ব্যর্থ",
|
||||||
|
"ButtonFireOnTest": "পরীক্ষামূলক ইভেন্টে সক্রিয় করুন",
|
||||||
"ButtonForceReScan": "জোরপূর্বক পুনরায় স্ক্যান করুন",
|
"ButtonForceReScan": "জোরপূর্বক পুনরায় স্ক্যান করুন",
|
||||||
"ButtonFullPath": "সম্পূর্ণ পথ",
|
"ButtonFullPath": "সম্পূর্ণ পথ",
|
||||||
"ButtonHide": "লুকান",
|
"ButtonHide": "লুকান",
|
||||||
@@ -45,22 +50,28 @@
|
|||||||
"ButtonNevermind": "কিছু মনে করবেন না",
|
"ButtonNevermind": "কিছু মনে করবেন না",
|
||||||
"ButtonNext": "পরবর্তী",
|
"ButtonNext": "পরবর্তী",
|
||||||
"ButtonNextChapter": "পরবর্তী অধ্যায়",
|
"ButtonNextChapter": "পরবর্তী অধ্যায়",
|
||||||
|
"ButtonNextItemInQueue": "সারিতে পরের আইটেম",
|
||||||
"ButtonOk": "ঠিক আছে",
|
"ButtonOk": "ঠিক আছে",
|
||||||
"ButtonOpenFeed": "ফিড খুলুন",
|
"ButtonOpenFeed": "ফিড খুলুন",
|
||||||
"ButtonOpenManager": "ম্যানেজার খুলুন",
|
"ButtonOpenManager": "ম্যানেজার খুলুন",
|
||||||
"ButtonPause": "বিরতি",
|
"ButtonPause": "বিরতি",
|
||||||
"ButtonPlay": "বাজান",
|
"ButtonPlay": "বাজান",
|
||||||
|
"ButtonPlayAll": "সব চালান",
|
||||||
"ButtonPlaying": "বাজছে",
|
"ButtonPlaying": "বাজছে",
|
||||||
"ButtonPlaylists": "প্লেলিস্ট",
|
"ButtonPlaylists": "প্লেলিস্ট",
|
||||||
"ButtonPrevious": "পূর্ববর্তী",
|
"ButtonPrevious": "পূর্ববর্তী",
|
||||||
"ButtonPreviousChapter": "আগের অধ্যায়",
|
"ButtonPreviousChapter": "আগের অধ্যায়",
|
||||||
|
"ButtonProbeAudioFile": "প্রোব অডিও ফাইল",
|
||||||
"ButtonPurgeAllCache": "সমস্ত ক্যাশে পরিষ্কার করুন",
|
"ButtonPurgeAllCache": "সমস্ত ক্যাশে পরিষ্কার করুন",
|
||||||
"ButtonPurgeItemsCache": "আইটেম ক্যাশে পরিষ্কার করুন",
|
"ButtonPurgeItemsCache": "আইটেম ক্যাশে পরিষ্কার করুন",
|
||||||
"ButtonQueueAddItem": "সারিতে যোগ করুন",
|
"ButtonQueueAddItem": "সারিতে যোগ করুন",
|
||||||
"ButtonQueueRemoveItem": "সারি থেকে মুছে ফেলুন",
|
"ButtonQueueRemoveItem": "সারি থেকে মুছে ফেলুন",
|
||||||
|
"ButtonQuickEmbedMetadata": "মেটাডেটা দ্রুত এম্বেড করুন",
|
||||||
"ButtonQuickMatch": "দ্রুত ম্যাচ",
|
"ButtonQuickMatch": "দ্রুত ম্যাচ",
|
||||||
"ButtonReScan": "পুনরায় স্ক্যান",
|
"ButtonReScan": "পুনরায় স্ক্যান",
|
||||||
"ButtonRead": "পড়ুন",
|
"ButtonRead": "পড়ুন",
|
||||||
|
"ButtonReadLess": "সংক্ষিপ্ত",
|
||||||
|
"ButtonReadMore": "বিস্তারিত পড়ুন",
|
||||||
"ButtonRefresh": "রিফ্রেশ",
|
"ButtonRefresh": "রিফ্রেশ",
|
||||||
"ButtonRemove": "মুছে ফেলুন",
|
"ButtonRemove": "মুছে ফেলুন",
|
||||||
"ButtonRemoveAll": "সব মুছে ফেলুন",
|
"ButtonRemoveAll": "সব মুছে ফেলুন",
|
||||||
@@ -85,8 +96,10 @@
|
|||||||
"ButtonShow": "দেখান",
|
"ButtonShow": "দেখান",
|
||||||
"ButtonStartM4BEncode": "M4B এনকোড শুরু করুন",
|
"ButtonStartM4BEncode": "M4B এনকোড শুরু করুন",
|
||||||
"ButtonStartMetadataEmbed": "মেটাডেটা এম্বেড শুরু করুন",
|
"ButtonStartMetadataEmbed": "মেটাডেটা এম্বেড শুরু করুন",
|
||||||
|
"ButtonStats": "পরিসংখ্যান",
|
||||||
"ButtonSubmit": "জমা দিন",
|
"ButtonSubmit": "জমা দিন",
|
||||||
"ButtonTest": "পরীক্ষা",
|
"ButtonTest": "পরীক্ষা",
|
||||||
|
"ButtonUnlinkOpenId": "ওপেন আইডি লিঙ্কমুক্ত করুন",
|
||||||
"ButtonUpload": "আপলোড",
|
"ButtonUpload": "আপলোড",
|
||||||
"ButtonUploadBackup": "আপলোড ব্যাকআপ",
|
"ButtonUploadBackup": "আপলোড ব্যাকআপ",
|
||||||
"ButtonUploadCover": "কভার আপলোড করুন",
|
"ButtonUploadCover": "কভার আপলোড করুন",
|
||||||
@@ -99,9 +112,10 @@
|
|||||||
"ErrorUploadFetchMetadataNoResults": "মেটাডেটা আনা যায়নি - শিরোনাম এবং/অথবা লেখক আপডেট করার চেষ্টা করুন",
|
"ErrorUploadFetchMetadataNoResults": "মেটাডেটা আনা যায়নি - শিরোনাম এবং/অথবা লেখক আপডেট করার চেষ্টা করুন",
|
||||||
"ErrorUploadLacksTitle": "একটি শিরোনাম থাকতে হবে",
|
"ErrorUploadLacksTitle": "একটি শিরোনাম থাকতে হবে",
|
||||||
"HeaderAccount": "অ্যাকাউন্ট",
|
"HeaderAccount": "অ্যাকাউন্ট",
|
||||||
|
"HeaderAddCustomMetadataProvider": "কাস্টম মেটাডেটা সরবরাহকারী যোগ করুন",
|
||||||
"HeaderAdvanced": "অ্যাডভান্সড",
|
"HeaderAdvanced": "অ্যাডভান্সড",
|
||||||
"HeaderAppriseNotificationSettings": "বিজ্ঞপ্তি সেটিংস অবহিত করুন",
|
"HeaderAppriseNotificationSettings": "বিজ্ঞপ্তি সেটিংস অবহিত করুন",
|
||||||
"HeaderAudioTracks": "অডিও ট্র্যাকস",
|
"HeaderAudioTracks": "অডিও ট্র্যাকসগুলো",
|
||||||
"HeaderAudiobookTools": "অডিওবই ফাইল ম্যানেজমেন্ট টুলস",
|
"HeaderAudiobookTools": "অডিওবই ফাইল ম্যানেজমেন্ট টুলস",
|
||||||
"HeaderAuthentication": "প্রমাণীকরণ",
|
"HeaderAuthentication": "প্রমাণীকরণ",
|
||||||
"HeaderBackups": "ব্যাকআপ",
|
"HeaderBackups": "ব্যাকআপ",
|
||||||
@@ -112,6 +126,7 @@
|
|||||||
"HeaderCollectionItems": "সংগ্রহ আইটেম",
|
"HeaderCollectionItems": "সংগ্রহ আইটেম",
|
||||||
"HeaderCover": "কভার",
|
"HeaderCover": "কভার",
|
||||||
"HeaderCurrentDownloads": "বর্তমান ডাউনলোডগুলি",
|
"HeaderCurrentDownloads": "বর্তমান ডাউনলোডগুলি",
|
||||||
|
"HeaderCustomMessageOnLogin": "লগইন এ কাস্টম বার্তা",
|
||||||
"HeaderCustomMetadataProviders": "কাস্টম মেটাডেটা প্রদানকারী",
|
"HeaderCustomMetadataProviders": "কাস্টম মেটাডেটা প্রদানকারী",
|
||||||
"HeaderDetails": "বিস্তারিত",
|
"HeaderDetails": "বিস্তারিত",
|
||||||
"HeaderDownloadQueue": "ডাউনলোড সারি",
|
"HeaderDownloadQueue": "ডাউনলোড সারি",
|
||||||
@@ -143,6 +158,8 @@
|
|||||||
"HeaderMetadataToEmbed": "এম্বেড করার জন্য মেটাডেটা",
|
"HeaderMetadataToEmbed": "এম্বেড করার জন্য মেটাডেটা",
|
||||||
"HeaderNewAccount": "নতুন অ্যাকাউন্ট",
|
"HeaderNewAccount": "নতুন অ্যাকাউন্ট",
|
||||||
"HeaderNewLibrary": "নতুন লাইব্রেরি",
|
"HeaderNewLibrary": "নতুন লাইব্রেরি",
|
||||||
|
"HeaderNotificationCreate": "বিজ্ঞপ্তি তৈরি করুন",
|
||||||
|
"HeaderNotificationUpdate": "বিজ্ঞপ্তি আপডেট করুন",
|
||||||
"HeaderNotifications": "বিজ্ঞপ্তি",
|
"HeaderNotifications": "বিজ্ঞপ্তি",
|
||||||
"HeaderOpenIDConnectAuthentication": "ওপেনআইডি সংযোগ প্রমাণীকরণ",
|
"HeaderOpenIDConnectAuthentication": "ওপেনআইডি সংযোগ প্রমাণীকরণ",
|
||||||
"HeaderOpenRSSFeed": "আরএসএস ফিড খুলুন",
|
"HeaderOpenRSSFeed": "আরএসএস ফিড খুলুন",
|
||||||
@@ -150,6 +167,7 @@
|
|||||||
"HeaderPasswordAuthentication": "পাসওয়ার্ড প্রমাণীকরণ",
|
"HeaderPasswordAuthentication": "পাসওয়ার্ড প্রমাণীকরণ",
|
||||||
"HeaderPermissions": "অনুমতি",
|
"HeaderPermissions": "অনুমতি",
|
||||||
"HeaderPlayerQueue": "প্লেয়ার সারি",
|
"HeaderPlayerQueue": "প্লেয়ার সারি",
|
||||||
|
"HeaderPlayerSettings": "প্লেয়ার সেটিংস",
|
||||||
"HeaderPlaylist": "প্লেলিস্ট",
|
"HeaderPlaylist": "প্লেলিস্ট",
|
||||||
"HeaderPlaylistItems": "প্লেলিস্ট আইটেম",
|
"HeaderPlaylistItems": "প্লেলিস্ট আইটেম",
|
||||||
"HeaderPodcastsToAdd": "যোগ করার জন্য পডকাস্ট",
|
"HeaderPodcastsToAdd": "যোগ করার জন্য পডকাস্ট",
|
||||||
@@ -186,6 +204,9 @@
|
|||||||
"HeaderYearReview": "বাৎসরিক পর্যালোচনা {0}",
|
"HeaderYearReview": "বাৎসরিক পর্যালোচনা {0}",
|
||||||
"HeaderYourStats": "আপনার পরিসংখ্যান",
|
"HeaderYourStats": "আপনার পরিসংখ্যান",
|
||||||
"LabelAbridged": "সংক্ষিপ্ত",
|
"LabelAbridged": "সংক্ষিপ্ত",
|
||||||
|
"LabelAbridgedChecked": "সংক্ষিপ্ত (চেক)",
|
||||||
|
"LabelAbridgedUnchecked": "অসংক্ষেপিত (চেক করা হয়নি)",
|
||||||
|
"LabelAccessibleBy": "দ্বারা প্রবেশযোগ্য",
|
||||||
"LabelAccountType": "অ্যাকাউন্টের প্রকার",
|
"LabelAccountType": "অ্যাকাউন্টের প্রকার",
|
||||||
"LabelAccountTypeAdmin": "প্রশাসন",
|
"LabelAccountTypeAdmin": "প্রশাসন",
|
||||||
"LabelAccountTypeGuest": "অতিথি",
|
"LabelAccountTypeGuest": "অতিথি",
|
||||||
@@ -196,6 +217,7 @@
|
|||||||
"LabelAddToPlaylist": "প্লেলিস্টে যোগ করুন",
|
"LabelAddToPlaylist": "প্লেলিস্টে যোগ করুন",
|
||||||
"LabelAddToPlaylistBatch": "প্লেলিস্টে {0}টি আইটেম যোগ করুন",
|
"LabelAddToPlaylistBatch": "প্লেলিস্টে {0}টি আইটেম যোগ করুন",
|
||||||
"LabelAddedAt": "এতে যোগ করা হয়েছে",
|
"LabelAddedAt": "এতে যোগ করা হয়েছে",
|
||||||
|
"LabelAddedDate": "যোগ করা হয়েছে {0}",
|
||||||
"LabelAdminUsersOnly": "শুধু অ্যাডমিন ব্যবহারকারী",
|
"LabelAdminUsersOnly": "শুধু অ্যাডমিন ব্যবহারকারী",
|
||||||
"LabelAll": "সব",
|
"LabelAll": "সব",
|
||||||
"LabelAllUsers": "সমস্ত ব্যবহারকারী",
|
"LabelAllUsers": "সমস্ত ব্যবহারকারী",
|
||||||
@@ -218,13 +240,14 @@
|
|||||||
"LabelBackupLocation": "ব্যাকআপ অবস্থান",
|
"LabelBackupLocation": "ব্যাকআপ অবস্থান",
|
||||||
"LabelBackupsEnableAutomaticBackups": "স্বয়ংক্রিয় ব্যাকআপ সক্ষম করুন",
|
"LabelBackupsEnableAutomaticBackups": "স্বয়ংক্রিয় ব্যাকআপ সক্ষম করুন",
|
||||||
"LabelBackupsEnableAutomaticBackupsHelp": "ব্যাকআপগুলি /মেটাডাটা/ব্যাকআপে সংরক্ষিত",
|
"LabelBackupsEnableAutomaticBackupsHelp": "ব্যাকআপগুলি /মেটাডাটা/ব্যাকআপে সংরক্ষিত",
|
||||||
"LabelBackupsMaxBackupSize": "সর্বোচ্চ ব্যাকআপ আকার (GB-তে)",
|
"LabelBackupsMaxBackupSize": "সর্বোচ্চ ব্যাকআপ আকার (GB-তে) (অসীমের জন্য 0)",
|
||||||
"LabelBackupsMaxBackupSizeHelp": "ভুল কনফিগারেশনের বিরুদ্ধে সুরক্ষা হিসেবে ব্যাকআপগুলি ব্যর্থ হবে যদি তারা কনফিগার করা আকার অতিক্রম করে।",
|
"LabelBackupsMaxBackupSizeHelp": "ভুল কনফিগারেশনের বিরুদ্ধে সুরক্ষা হিসেবে ব্যাকআপগুলি ব্যর্থ হবে যদি তারা কনফিগার করা আকার অতিক্রম করে।",
|
||||||
"LabelBackupsNumberToKeep": "ব্যাকআপের সংখ্যা রাখুন",
|
"LabelBackupsNumberToKeep": "ব্যাকআপের সংখ্যা রাখুন",
|
||||||
"LabelBackupsNumberToKeepHelp": "এক সময়ে শুধুমাত্র ১ টি ব্যাকআপ সরানো হবে তাই যদি আপনার কাছে ইতিমধ্যে এর চেয়ে বেশি ব্যাকআপ থাকে তাহলে আপনাকে ম্যানুয়ালি সেগুলি সরিয়ে ফেলতে হবে।",
|
"LabelBackupsNumberToKeepHelp": "এক সময়ে শুধুমাত্র ১ টি ব্যাকআপ সরানো হবে তাই যদি আপনার কাছে ইতিমধ্যে এর চেয়ে বেশি ব্যাকআপ থাকে তাহলে আপনাকে ম্যানুয়ালি সেগুলি সরিয়ে ফেলতে হবে।",
|
||||||
"LabelBitrate": "বিটরেট",
|
"LabelBitrate": "বিটরেট",
|
||||||
"LabelBooks": "বইগুলো",
|
"LabelBooks": "বইগুলো",
|
||||||
"LabelButtonText": "ঘর পাঠ্য",
|
"LabelButtonText": "ঘর পাঠ্য",
|
||||||
|
"LabelByAuthor": "দ্বারা {0}",
|
||||||
"LabelChangePassword": "পাসওয়ার্ড পরিবর্তন করুন",
|
"LabelChangePassword": "পাসওয়ার্ড পরিবর্তন করুন",
|
||||||
"LabelChannels": "চ্যানেল",
|
"LabelChannels": "চ্যানেল",
|
||||||
"LabelChapterTitle": "অধ্যায়ের শিরোনাম",
|
"LabelChapterTitle": "অধ্যায়ের শিরোনাম",
|
||||||
@@ -234,6 +257,7 @@
|
|||||||
"LabelClosePlayer": "প্লেয়ার বন্ধ করুন",
|
"LabelClosePlayer": "প্লেয়ার বন্ধ করুন",
|
||||||
"LabelCodec": "কোডেক",
|
"LabelCodec": "কোডেক",
|
||||||
"LabelCollapseSeries": "সিরিজ সঙ্কুচিত করুন",
|
"LabelCollapseSeries": "সিরিজ সঙ্কুচিত করুন",
|
||||||
|
"LabelCollapseSubSeries": "উপ-সিরিজ সঙ্কুচিত করুন",
|
||||||
"LabelCollection": "সংগ্রহ",
|
"LabelCollection": "সংগ্রহ",
|
||||||
"LabelCollections": "সংগ্রহ",
|
"LabelCollections": "সংগ্রহ",
|
||||||
"LabelComplete": "সম্পূর্ণ",
|
"LabelComplete": "সম্পূর্ণ",
|
||||||
@@ -249,6 +273,7 @@
|
|||||||
"LabelCurrently": "বর্তমানে:",
|
"LabelCurrently": "বর্তমানে:",
|
||||||
"LabelCustomCronExpression": "কাস্টম Cron এক্সপ্রেশন:",
|
"LabelCustomCronExpression": "কাস্টম Cron এক্সপ্রেশন:",
|
||||||
"LabelDatetime": "তারিখ সময়",
|
"LabelDatetime": "তারিখ সময়",
|
||||||
|
"LabelDays": "দিনগুলো",
|
||||||
"LabelDeleteFromFileSystemCheckbox": "ফাইল সিস্টেম থেকে মুছে ফেলুন (শুধু ডাটাবেস থেকে সরাতে টিক চিহ্ন মুক্ত করুন)",
|
"LabelDeleteFromFileSystemCheckbox": "ফাইল সিস্টেম থেকে মুছে ফেলুন (শুধু ডাটাবেস থেকে সরাতে টিক চিহ্ন মুক্ত করুন)",
|
||||||
"LabelDescription": "বিবরণ",
|
"LabelDescription": "বিবরণ",
|
||||||
"LabelDeselectAll": "সমস্ত অনির্বাচিত করুন",
|
"LabelDeselectAll": "সমস্ত অনির্বাচিত করুন",
|
||||||
@@ -262,29 +287,42 @@
|
|||||||
"LabelDownload": "ডাউনলোড করুন",
|
"LabelDownload": "ডাউনলোড করুন",
|
||||||
"LabelDownloadNEpisodes": "{0}টি পর্ব ডাউনলোড করুন",
|
"LabelDownloadNEpisodes": "{0}টি পর্ব ডাউনলোড করুন",
|
||||||
"LabelDuration": "সময়কাল",
|
"LabelDuration": "সময়কাল",
|
||||||
|
"LabelDurationComparisonExactMatch": "(সঠিক মিল)",
|
||||||
|
"LabelDurationComparisonLonger": "({0} দীর্ঘ)",
|
||||||
|
"LabelDurationComparisonShorter": "({0} ছোট)",
|
||||||
"LabelDurationFound": "সময়কাল পাওয়া গেছে:",
|
"LabelDurationFound": "সময়কাল পাওয়া গেছে:",
|
||||||
"LabelEbook": "ই-বই",
|
"LabelEbook": "ই-বই",
|
||||||
"LabelEbooks": "ই-বইগুলো",
|
"LabelEbooks": "ই-বইগুলো",
|
||||||
"LabelEdit": "সম্পাদনা করুন",
|
"LabelEdit": "সম্পাদনা করুন",
|
||||||
"LabelEmail": "ইমেইল",
|
"LabelEmail": "ইমেইল",
|
||||||
"LabelEmailSettingsFromAddress": "ঠিকানা থেকে",
|
"LabelEmailSettingsFromAddress": "ঠিকানা থেকে",
|
||||||
"LabelEmailSettingsRejectUnauthorizedHelp": "Disabling SSL certificate validation may expose your connection to security risks, such as man-in-the-middle attacks. Only disable this option if you understand the implications and trust the mail server you are connecting to।",
|
"LabelEmailSettingsRejectUnauthorized": "অননুমোদিত সার্টিফিকেট প্রত্যাখ্যান করুন",
|
||||||
|
"LabelEmailSettingsRejectUnauthorizedHelp": "SSL প্রমাণপত্রের বৈধতা নিষ্ক্রিয় করা আপনার সংযোগকে নিরাপত্তা ঝুঁকিতে ফেলতে পারে, যেমন ম্যান-ইন-দ্য-মিডল আক্রমণ। শুধুমাত্র এই বিকল্পটি নিষ্ক্রিয় করুন যদি আপনি এর প্রভাবগুলি বুঝতে পারেন এবং আপনি যে মেইল সার্ভারের সাথে সংযোগ করছেন তাকে বিশ্বাস করেন।",
|
||||||
"LabelEmailSettingsSecure": "নিরাপদ",
|
"LabelEmailSettingsSecure": "নিরাপদ",
|
||||||
"LabelEmailSettingsSecureHelp": "যদি সত্য হয় সার্ভারের সাথে সংযোগ করার সময় সংযোগটি TLS ব্যবহার করবে। মিথ্যা হলে TLS ব্যবহার করা হবে যদি সার্ভার STARTTLS এক্সটেনশন সমর্থন করে। বেশিরভাগ ক্ষেত্রে এই মানটিকে সত্য হিসাবে সেট করুন যদি আপনি পোর্ট 465-এর সাথে সংযোগ করছেন। পোর্ট 587 বা পোর্টের জন্য 25 এটি মিথ্যা রাখুন। (nodemailer.com/smtp/#authentication থেকে)",
|
"LabelEmailSettingsSecureHelp": "যদি সত্য হয় সার্ভারের সাথে সংযোগ করার সময় সংযোগটি TLS ব্যবহার করবে। মিথ্যা হলে TLS ব্যবহার করা হবে যদি সার্ভার STARTTLS এক্সটেনশন সমর্থন করে। বেশিরভাগ ক্ষেত্রে এই মানটিকে সত্য হিসাবে সেট করুন যদি আপনি পোর্ট 465-এর সাথে সংযোগ করছেন। পোর্ট 587 বা পোর্টের জন্য 25 এটি মিথ্যা রাখুন। (nodemailer.com/smtp/#authentication থেকে)",
|
||||||
"LabelEmailSettingsTestAddress": "পরীক্ষার ঠিকানা",
|
"LabelEmailSettingsTestAddress": "পরীক্ষার ঠিকানা",
|
||||||
"LabelEmbeddedCover": "এম্বেডেড কভার",
|
"LabelEmbeddedCover": "এম্বেডেড কভার",
|
||||||
"LabelEnable": "সক্ষম করুন",
|
"LabelEnable": "সক্ষম করুন",
|
||||||
"LabelEnd": "সমাপ্ত",
|
"LabelEnd": "সমাপ্ত",
|
||||||
|
"LabelEndOfChapter": "অধ্যায়ের সমাপ্তি",
|
||||||
"LabelEpisode": "পর্ব",
|
"LabelEpisode": "পর্ব",
|
||||||
"LabelEpisodeTitle": "পর্বের শিরোনাম",
|
"LabelEpisodeTitle": "পর্বের শিরোনাম",
|
||||||
"LabelEpisodeType": "পর্বের ধরন",
|
"LabelEpisodeType": "পর্বের ধরন",
|
||||||
|
"LabelEpisodes": "পর্বগুলো",
|
||||||
"LabelExample": "উদাহরণ",
|
"LabelExample": "উদাহরণ",
|
||||||
|
"LabelExpandSeries": "সিরিজ প্রসারিত করুন",
|
||||||
|
"LabelExpandSubSeries": "সাব সিরিজ প্রসারিত করুন",
|
||||||
"LabelExplicit": "বিশদ",
|
"LabelExplicit": "বিশদ",
|
||||||
|
"LabelExplicitChecked": "সুস্পষ্ট (পরীক্ষিত)",
|
||||||
|
"LabelExplicitUnchecked": "অস্পষ্ট (অপরিক্ষীত)",
|
||||||
|
"LabelExportOPML": "OPML এক্সপোর্ট করুন",
|
||||||
"LabelFeedURL": "ফিড ইউআরএল",
|
"LabelFeedURL": "ফিড ইউআরএল",
|
||||||
"LabelFetchingMetadata": "মেটাডেটা আনা হচ্ছে",
|
"LabelFetchingMetadata": "মেটাডেটা আনা হচ্ছে",
|
||||||
"LabelFile": "ফাইল",
|
"LabelFile": "ফাইল",
|
||||||
"LabelFileBirthtime": "ফাইল জন্মের সময়",
|
"LabelFileBirthtime": "ফাইল জন্মের সময়",
|
||||||
|
"LabelFileBornDate": "জন্ম {0}",
|
||||||
"LabelFileModified": "ফাইল পরিবর্তিত",
|
"LabelFileModified": "ফাইল পরিবর্তিত",
|
||||||
|
"LabelFileModifiedDate": "পরিবর্তিত {0}",
|
||||||
"LabelFilename": "ফাইলের নাম",
|
"LabelFilename": "ফাইলের নাম",
|
||||||
"LabelFilterByUser": "ব্যবহারকারী দ্বারা ফিল্টারকৃত",
|
"LabelFilterByUser": "ব্যবহারকারী দ্বারা ফিল্টারকৃত",
|
||||||
"LabelFindEpisodes": "পর্বগুলো খুঁজুন",
|
"LabelFindEpisodes": "পর্বগুলো খুঁজুন",
|
||||||
@@ -292,7 +330,8 @@
|
|||||||
"LabelFolder": "ফোল্ডার",
|
"LabelFolder": "ফোল্ডার",
|
||||||
"LabelFolders": "ফোল্ডারগুলো",
|
"LabelFolders": "ফোল্ডারগুলো",
|
||||||
"LabelFontBold": "বোল্ড",
|
"LabelFontBold": "বোল্ড",
|
||||||
"LabelFontFamily": "ফন্ট পরিবার",
|
"LabelFontBoldness": "হরফ বোল্ডনেস",
|
||||||
|
"LabelFontFamily": "হরফ পরিবার",
|
||||||
"LabelFontItalic": "ইটালিক",
|
"LabelFontItalic": "ইটালিক",
|
||||||
"LabelFontScale": "ফন্ট স্কেল",
|
"LabelFontScale": "ফন্ট স্কেল",
|
||||||
"LabelFontStrikethrough": "অবচ্ছেদন রেখা",
|
"LabelFontStrikethrough": "অবচ্ছেদন রেখা",
|
||||||
@@ -302,9 +341,11 @@
|
|||||||
"LabelHardDeleteFile": "জোরপূর্বক ফাইল মুছে ফেলুন",
|
"LabelHardDeleteFile": "জোরপূর্বক ফাইল মুছে ফেলুন",
|
||||||
"LabelHasEbook": "ই-বই আছে",
|
"LabelHasEbook": "ই-বই আছে",
|
||||||
"LabelHasSupplementaryEbook": "পরিপূরক ই-বই আছে",
|
"LabelHasSupplementaryEbook": "পরিপূরক ই-বই আছে",
|
||||||
|
"LabelHideSubtitles": "সাবটাইটেল লুকান",
|
||||||
"LabelHighestPriority": "সর্বোচ্চ অগ্রাধিকার",
|
"LabelHighestPriority": "সর্বোচ্চ অগ্রাধিকার",
|
||||||
"LabelHost": "নিমন্ত্রণকর্তা",
|
"LabelHost": "নিমন্ত্রণকর্তা",
|
||||||
"LabelHour": "ঘন্টা",
|
"LabelHour": "ঘন্টা",
|
||||||
|
"LabelHours": "ঘন্টা",
|
||||||
"LabelIcon": "আইকন",
|
"LabelIcon": "আইকন",
|
||||||
"LabelImageURLFromTheWeb": "ওয়েব থেকে ছবির ইউআরএল",
|
"LabelImageURLFromTheWeb": "ওয়েব থেকে ছবির ইউআরএল",
|
||||||
"LabelInProgress": "প্রগতিতে আছে",
|
"LabelInProgress": "প্রগতিতে আছে",
|
||||||
@@ -321,8 +362,11 @@
|
|||||||
"LabelIntervalEveryHour": "প্রতি ঘন্টা",
|
"LabelIntervalEveryHour": "প্রতি ঘন্টা",
|
||||||
"LabelInvert": "উল্টানো",
|
"LabelInvert": "উল্টানো",
|
||||||
"LabelItem": "আইটেম",
|
"LabelItem": "আইটেম",
|
||||||
|
"LabelJumpBackwardAmount": "পিছন দিকে ঝাঁপের পরিমাণ",
|
||||||
|
"LabelJumpForwardAmount": "সামনের দিকে ঝাঁপের পরিমাণ",
|
||||||
"LabelLanguage": "ভাষা",
|
"LabelLanguage": "ভাষা",
|
||||||
"LabelLanguageDefaultServer": "সার্ভারের ডিফল্ট ভাষা",
|
"LabelLanguageDefaultServer": "সার্ভারের ডিফল্ট ভাষা",
|
||||||
|
"LabelLanguages": "ভাষাসমূহ",
|
||||||
"LabelLastBookAdded": "শেষ বই যোগ করা হয়েছে",
|
"LabelLastBookAdded": "শেষ বই যোগ করা হয়েছে",
|
||||||
"LabelLastBookUpdated": "শেষ বই আপডেট করা হয়েছে",
|
"LabelLastBookUpdated": "শেষ বই আপডেট করা হয়েছে",
|
||||||
"LabelLastSeen": "শেষ দেখা",
|
"LabelLastSeen": "শেষ দেখা",
|
||||||
@@ -334,6 +378,7 @@
|
|||||||
"LabelLess": "কম",
|
"LabelLess": "কম",
|
||||||
"LabelLibrariesAccessibleToUser": "ব্যবহারকারীর কাছে অ্যাক্সেসযোগ্য লাইব্রেরি",
|
"LabelLibrariesAccessibleToUser": "ব্যবহারকারীর কাছে অ্যাক্সেসযোগ্য লাইব্রেরি",
|
||||||
"LabelLibrary": "লাইব্রেরি",
|
"LabelLibrary": "লাইব্রেরি",
|
||||||
|
"LabelLibraryFilterSublistEmpty": "না {0}",
|
||||||
"LabelLibraryItem": "লাইব্রেরি আইটেম",
|
"LabelLibraryItem": "লাইব্রেরি আইটেম",
|
||||||
"LabelLibraryName": "লাইব্রেরির নাম",
|
"LabelLibraryName": "লাইব্রেরির নাম",
|
||||||
"LabelLimit": "সীমা",
|
"LabelLimit": "সীমা",
|
||||||
@@ -353,6 +398,7 @@
|
|||||||
"LabelMetadataOrderOfPrecedenceDescription": "উচ্চ অগ্রাধিকারের মেটাডেটার উৎসগুলো নিম্ন অগ্রাধিকারের মেটাডেটা উৎসগুলোকে ওভাররাইড করবে",
|
"LabelMetadataOrderOfPrecedenceDescription": "উচ্চ অগ্রাধিকারের মেটাডেটার উৎসগুলো নিম্ন অগ্রাধিকারের মেটাডেটা উৎসগুলোকে ওভাররাইড করবে",
|
||||||
"LabelMetadataProvider": "মেটাডেটা প্রদানকারী",
|
"LabelMetadataProvider": "মেটাডেটা প্রদানকারী",
|
||||||
"LabelMinute": "মিনিট",
|
"LabelMinute": "মিনিট",
|
||||||
|
"LabelMinutes": "মিনিটস",
|
||||||
"LabelMissing": "নিখোঁজ",
|
"LabelMissing": "নিখোঁজ",
|
||||||
"LabelMissingEbook": "কোনও ই-বই নেই",
|
"LabelMissingEbook": "কোনও ই-বই নেই",
|
||||||
"LabelMissingSupplementaryEbook": "কোনও সম্পূরক ই-বই নেই",
|
"LabelMissingSupplementaryEbook": "কোনও সম্পূরক ই-বই নেই",
|
||||||
@@ -369,6 +415,7 @@
|
|||||||
"LabelNewestEpisodes": "নতুনতম পর্ব",
|
"LabelNewestEpisodes": "নতুনতম পর্ব",
|
||||||
"LabelNextBackupDate": "পরবর্তী ব্যাকআপ তারিখ",
|
"LabelNextBackupDate": "পরবর্তী ব্যাকআপ তারিখ",
|
||||||
"LabelNextScheduledRun": "পরবর্তী নির্ধারিত দৌড়",
|
"LabelNextScheduledRun": "পরবর্তী নির্ধারিত দৌড়",
|
||||||
|
"LabelNoCustomMetadataProviders": "কোনো কাস্টম মেটাডেটা প্রদানকারী নেই",
|
||||||
"LabelNoEpisodesSelected": "কোন পর্ব নির্বাচন করা হয়নি",
|
"LabelNoEpisodesSelected": "কোন পর্ব নির্বাচন করা হয়নি",
|
||||||
"LabelNotFinished": "সমাপ্ত হয়নি",
|
"LabelNotFinished": "সমাপ্ত হয়নি",
|
||||||
"LabelNotStarted": "শুরু হয়নি",
|
"LabelNotStarted": "শুরু হয়নি",
|
||||||
@@ -391,6 +438,7 @@
|
|||||||
"LabelOverwrite": "পুনঃলিখিত",
|
"LabelOverwrite": "পুনঃলিখিত",
|
||||||
"LabelPassword": "পাসওয়ার্ড",
|
"LabelPassword": "পাসওয়ার্ড",
|
||||||
"LabelPath": "পথ",
|
"LabelPath": "পথ",
|
||||||
|
"LabelPermanent": "স্থায়ী",
|
||||||
"LabelPermissionsAccessAllLibraries": "সমস্ত লাইব্রেরি অ্যাক্সেস করতে পারবে",
|
"LabelPermissionsAccessAllLibraries": "সমস্ত লাইব্রেরি অ্যাক্সেস করতে পারবে",
|
||||||
"LabelPermissionsAccessAllTags": "সমস্ত ট্যাগ অ্যাক্সেস করতে পারবে",
|
"LabelPermissionsAccessAllTags": "সমস্ত ট্যাগ অ্যাক্সেস করতে পারবে",
|
||||||
"LabelPermissionsAccessExplicitContent": "স্পষ্ট বিষয়বস্তু অ্যাক্সেস করতে পারে",
|
"LabelPermissionsAccessExplicitContent": "স্পষ্ট বিষয়বস্তু অ্যাক্সেস করতে পারে",
|
||||||
@@ -401,6 +449,7 @@
|
|||||||
"LabelPersonalYearReview": "আপনার বছরের পর্যালোচনা ({0})",
|
"LabelPersonalYearReview": "আপনার বছরের পর্যালোচনা ({0})",
|
||||||
"LabelPhotoPathURL": "ছবি পথ/ইউআরএল",
|
"LabelPhotoPathURL": "ছবি পথ/ইউআরএল",
|
||||||
"LabelPlayMethod": "প্লে পদ্ধতি",
|
"LabelPlayMethod": "প্লে পদ্ধতি",
|
||||||
|
"LabelPlayerChapterNumberMarker": "{1} এর মধ্যে {0}",
|
||||||
"LabelPlaylists": "প্লেলিস্ট",
|
"LabelPlaylists": "প্লেলিস্ট",
|
||||||
"LabelPodcast": "পডকাস্ট",
|
"LabelPodcast": "পডকাস্ট",
|
||||||
"LabelPodcastSearchRegion": "পডকাস্ট অনুসন্ধান অঞ্চল",
|
"LabelPodcastSearchRegion": "পডকাস্ট অনুসন্ধান অঞ্চল",
|
||||||
@@ -412,15 +461,20 @@
|
|||||||
"LabelPrimaryEbook": "প্রাথমিক ই-বই",
|
"LabelPrimaryEbook": "প্রাথমিক ই-বই",
|
||||||
"LabelProgress": "প্রগতি",
|
"LabelProgress": "প্রগতি",
|
||||||
"LabelProvider": "প্রদানকারী",
|
"LabelProvider": "প্রদানকারী",
|
||||||
|
"LabelProviderAuthorizationValue": "অনুমোদন শিরোনামের মান",
|
||||||
"LabelPubDate": "প্রকাশের তারিখ",
|
"LabelPubDate": "প্রকাশের তারিখ",
|
||||||
"LabelPublishYear": "প্রকাশের বছর",
|
"LabelPublishYear": "প্রকাশের বছর",
|
||||||
|
"LabelPublishedDate": "প্রকাশিত {0}",
|
||||||
"LabelPublisher": "প্রকাশক",
|
"LabelPublisher": "প্রকাশক",
|
||||||
|
"LabelPublishers": "প্রকাশকরা",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "কাস্টম মালিকের ইমেইল",
|
"LabelRSSFeedCustomOwnerEmail": "কাস্টম মালিকের ইমেইল",
|
||||||
"LabelRSSFeedCustomOwnerName": "কাস্টম মালিকের নাম",
|
"LabelRSSFeedCustomOwnerName": "কাস্টম মালিকের নাম",
|
||||||
"LabelRSSFeedOpen": "আরএসএস ফিড খুলুন",
|
"LabelRSSFeedOpen": "আরএসএস ফিড খুলুন",
|
||||||
"LabelRSSFeedPreventIndexing": "সূচীকরণ প্রতিরোধ করুন",
|
"LabelRSSFeedPreventIndexing": "সূচীকরণ প্রতিরোধ করুন",
|
||||||
"LabelRSSFeedSlug": "আরএসএস ফিড স্লাগ",
|
"LabelRSSFeedSlug": "আরএসএস ফিড স্লাগ",
|
||||||
"LabelRSSFeedURL": "আরএসএস ফিড ইউআরএল",
|
"LabelRSSFeedURL": "আরএসএস ফিড ইউআরএল",
|
||||||
|
"LabelRandomly": "এলোমেলোভাবে",
|
||||||
|
"LabelReAddSeriesToContinueListening": "শোনা চালিয়ে যেতে সিরিজ পুনরায় যোগ করুন",
|
||||||
"LabelRead": "পড়ুন",
|
"LabelRead": "পড়ুন",
|
||||||
"LabelReadAgain": "আবার পড়ুন",
|
"LabelReadAgain": "আবার পড়ুন",
|
||||||
"LabelReadEbookWithoutProgress": "প্রগতি না রেখে ই-বই পড়ুন",
|
"LabelReadEbookWithoutProgress": "প্রগতি না রেখে ই-বই পড়ুন",
|
||||||
@@ -436,6 +490,7 @@
|
|||||||
"LabelSearchTitle": "অনুসন্ধান শিরোনাম",
|
"LabelSearchTitle": "অনুসন্ধান শিরোনাম",
|
||||||
"LabelSearchTitleOrASIN": "অনুসন্ধান শিরোনাম বা ASIN",
|
"LabelSearchTitleOrASIN": "অনুসন্ধান শিরোনাম বা ASIN",
|
||||||
"LabelSeason": "সেশন",
|
"LabelSeason": "সেশন",
|
||||||
|
"LabelSelectAll": "সব নির্বাচন করুন",
|
||||||
"LabelSelectAllEpisodes": "সমস্ত পর্ব নির্বাচন করুন",
|
"LabelSelectAllEpisodes": "সমস্ত পর্ব নির্বাচন করুন",
|
||||||
"LabelSelectEpisodesShowing": "দেখানো {0}টি পর্ব নির্বাচন করুন",
|
"LabelSelectEpisodesShowing": "দেখানো {0}টি পর্ব নির্বাচন করুন",
|
||||||
"LabelSelectUsers": "ব্যবহারকারী নির্বাচন করুন",
|
"LabelSelectUsers": "ব্যবহারকারী নির্বাচন করুন",
|
||||||
@@ -458,7 +513,8 @@
|
|||||||
"LabelSettingsEnableWatcher": "প্রহরী সক্ষম করুন",
|
"LabelSettingsEnableWatcher": "প্রহরী সক্ষম করুন",
|
||||||
"LabelSettingsEnableWatcherForLibrary": "লাইব্রেরির জন্য ফোল্ডার প্রহরী সক্ষম করুন",
|
"LabelSettingsEnableWatcherForLibrary": "লাইব্রেরির জন্য ফোল্ডার প্রহরী সক্ষম করুন",
|
||||||
"LabelSettingsEnableWatcherHelp": "ফাইলের পরিবর্তন শনাক্ত হলে আইটেমগুলির স্বয়ংক্রিয় যোগ/আপডেট সক্ষম করবে। *সার্ভার পুনরায় চালু করতে হবে",
|
"LabelSettingsEnableWatcherHelp": "ফাইলের পরিবর্তন শনাক্ত হলে আইটেমগুলির স্বয়ংক্রিয় যোগ/আপডেট সক্ষম করবে। *সার্ভার পুনরায় চালু করতে হবে",
|
||||||
"LabelSettingsEpubsAllowScriptedContentHelp": "Allow epub files to execute scripts. It is recommended to keep this setting disabled unless you trust the source of the epub files।",
|
"LabelSettingsEpubsAllowScriptedContent": "ইপাবে স্ক্রিপ্ট করা বিষয়বস্তুর অনুমতি দিন",
|
||||||
|
"LabelSettingsEpubsAllowScriptedContentHelp": "ইপাব ফাইলগুলিকে স্ক্রিপ্ট চালানোর অনুমতি দিন। আপনি ইপাব ফাইলগুলির উৎসকে বিশ্বাস না করলে এই সেটিংটি নিষ্ক্রিয় রাখার সুপারিশ করা হলো।",
|
||||||
"LabelSettingsExperimentalFeatures": "পরীক্ষামূলক বৈশিষ্ট্য",
|
"LabelSettingsExperimentalFeatures": "পরীক্ষামূলক বৈশিষ্ট্য",
|
||||||
"LabelSettingsExperimentalFeaturesHelp": "ফিচারের বৈশিষ্ট্য যা আপনার প্রতিক্রিয়া ব্যবহার করতে পারে এবং পরীক্ষায় সহায়তা করতে পারে। গিটহাব আলোচনা খুলতে ক্লিক করুন।",
|
"LabelSettingsExperimentalFeaturesHelp": "ফিচারের বৈশিষ্ট্য যা আপনার প্রতিক্রিয়া ব্যবহার করতে পারে এবং পরীক্ষায় সহায়তা করতে পারে। গিটহাব আলোচনা খুলতে ক্লিক করুন।",
|
||||||
"LabelSettingsFindCovers": "কভার খুঁজুন",
|
"LabelSettingsFindCovers": "কভার খুঁজুন",
|
||||||
@@ -468,7 +524,7 @@
|
|||||||
"LabelSettingsHomePageBookshelfView": "নীড় পেজে বুকশেলফ ভিউ ব্যবহার করুন",
|
"LabelSettingsHomePageBookshelfView": "নীড় পেজে বুকশেলফ ভিউ ব্যবহার করুন",
|
||||||
"LabelSettingsLibraryBookshelfView": "লাইব্রেরি বুকশেলফ ভিউ ব্যবহার করুন",
|
"LabelSettingsLibraryBookshelfView": "লাইব্রেরি বুকশেলফ ভিউ ব্যবহার করুন",
|
||||||
"LabelSettingsOnlyShowLaterBooksInContinueSeries": "কন্টিনিউ সিরিজে আগের বইগুলো এড়িয়ে যান",
|
"LabelSettingsOnlyShowLaterBooksInContinueSeries": "কন্টিনিউ সিরিজে আগের বইগুলো এড়িয়ে যান",
|
||||||
"LabelSettingsOnlyShowLaterBooksInContinueSeriesHelp": "কন্টিনিউ সিরিজের হোম পেজ শেল্ফ প্রথম বইটি দেখায় যেটি সিরিজে শুরু হয়নি যেটিতে অন্তত একটি বই শেষ হয়েছে এবং কোনো বই চলছে না। এই সেটিংটি সক্ষম করা হলে তা শুরু না হওয়া প্রথম বইটির পরিবর্তে সবচেয়ে দূরের সম্পূর্ণ বই থেকে সিরিজ চালিয়ে যাবে।",
|
"LabelSettingsOnlyShowLaterBooksInContinueSeriesHelp": "কন্টিনিউ সিরিজের নীড় পেজ শেল্ফ দেখায় যে সিরিজে শুরু হয়নি এমন প্রথম বই যার অন্তত একটি বই শেষ হয়েছে এবং কোনো বই চলছে না। এই সেটিংটি সক্ষম করলে শুরু না হওয়া প্রথম বইটির পরিবর্তে সবচেয়ে দূরের সম্পূর্ণ বই থেকে সিরিজ চলতে থাকবে।",
|
||||||
"LabelSettingsParseSubtitles": "সাবটাইটেল পার্স করুন",
|
"LabelSettingsParseSubtitles": "সাবটাইটেল পার্স করুন",
|
||||||
"LabelSettingsParseSubtitlesHelp": "অডিওবুক ফোল্ডারের নাম থেকে সাবটাইটেল বের করুন৷<br>সাবটাইটেল অবশ্যই \" - \"<br>অর্থাৎ \"বুকের শিরোনাম - এখানে একটি সাবটাইটেল\" এর সাবটাইটেল আছে \"এখানে একটি সাবটাইটেল\"",
|
"LabelSettingsParseSubtitlesHelp": "অডিওবুক ফোল্ডারের নাম থেকে সাবটাইটেল বের করুন৷<br>সাবটাইটেল অবশ্যই \" - \"<br>অর্থাৎ \"বুকের শিরোনাম - এখানে একটি সাবটাইটেল\" এর সাবটাইটেল আছে \"এখানে একটি সাবটাইটেল\"",
|
||||||
"LabelSettingsPreferMatchedMetadata": "মিলিত মেটাডেটা পছন্দ করুন",
|
"LabelSettingsPreferMatchedMetadata": "মিলিত মেটাডেটা পছন্দ করুন",
|
||||||
@@ -484,12 +540,17 @@
|
|||||||
"LabelSettingsStoreMetadataWithItem": "আইটেমের সাথে মেটাডেটা সংরক্ষণ করুন",
|
"LabelSettingsStoreMetadataWithItem": "আইটেমের সাথে মেটাডেটা সংরক্ষণ করুন",
|
||||||
"LabelSettingsStoreMetadataWithItemHelp": "ডিফল্টরূপে মেটাডেটা ফাইলগুলি /মেটাডাটা/আইটেমগুলি -এ সংরক্ষণ করা হয়, এই সেটিংটি সক্ষম করলে মেটাডেটা ফাইলগুলি আপনার লাইব্রেরি আইটেম ফোল্ডারে সংরক্ষণ করা হবে",
|
"LabelSettingsStoreMetadataWithItemHelp": "ডিফল্টরূপে মেটাডেটা ফাইলগুলি /মেটাডাটা/আইটেমগুলি -এ সংরক্ষণ করা হয়, এই সেটিংটি সক্ষম করলে মেটাডেটা ফাইলগুলি আপনার লাইব্রেরি আইটেম ফোল্ডারে সংরক্ষণ করা হবে",
|
||||||
"LabelSettingsTimeFormat": "সময় বিন্যাস",
|
"LabelSettingsTimeFormat": "সময় বিন্যাস",
|
||||||
|
"LabelShare": "শেয়ার করুন",
|
||||||
|
"LabelShareOpen": "শেয়ার খোলা",
|
||||||
|
"LabelShareURL": "শেয়ার ইউআরএল",
|
||||||
"LabelShowAll": "সব দেখান",
|
"LabelShowAll": "সব দেখান",
|
||||||
|
"LabelShowSeconds": "সেকেন্ড দেখান",
|
||||||
|
"LabelShowSubtitles": "সহ-শিরোনাম দেখান",
|
||||||
"LabelSize": "আকার",
|
"LabelSize": "আকার",
|
||||||
"LabelSleepTimer": "স্লিপ টাইমার",
|
"LabelSleepTimer": "স্লিপ টাইমার",
|
||||||
"LabelSlug": "স্লাগ",
|
"LabelSlug": "স্লাগ",
|
||||||
"LabelStart": "শুরু",
|
"LabelStart": "শুরু",
|
||||||
"LabelStartTime": "শুরু করার সময়",
|
"LabelStartTime": "শুরুর সময়",
|
||||||
"LabelStarted": "শুরু হয়েছে",
|
"LabelStarted": "শুরু হয়েছে",
|
||||||
"LabelStartedAt": "এতে শুরু হয়েছে",
|
"LabelStartedAt": "এতে শুরু হয়েছে",
|
||||||
"LabelStatsAudioTracks": "অডিও ট্র্যাক",
|
"LabelStatsAudioTracks": "অডিও ট্র্যাক",
|
||||||
@@ -522,6 +583,10 @@
|
|||||||
"LabelThemeDark": "অন্ধকার",
|
"LabelThemeDark": "অন্ধকার",
|
||||||
"LabelThemeLight": "আলো",
|
"LabelThemeLight": "আলো",
|
||||||
"LabelTimeBase": "সময় বেস",
|
"LabelTimeBase": "সময় বেস",
|
||||||
|
"LabelTimeDurationXHours": "{0} ঘণ্টা",
|
||||||
|
"LabelTimeDurationXMinutes": "{0} মিনিট",
|
||||||
|
"LabelTimeDurationXSeconds": "{0} সেকেন্ড",
|
||||||
|
"LabelTimeInMinutes": "মিনিটে সময়",
|
||||||
"LabelTimeListened": "সময় শোনা হয়েছে",
|
"LabelTimeListened": "সময় শোনা হয়েছে",
|
||||||
"LabelTimeListenedToday": "আজ শোনার সময়",
|
"LabelTimeListenedToday": "আজ শোনার সময়",
|
||||||
"LabelTimeRemaining": "{0}টি অবশিষ্ট",
|
"LabelTimeRemaining": "{0}টি অবশিষ্ট",
|
||||||
@@ -545,6 +610,7 @@
|
|||||||
"LabelUnabridged": "অসংলগ্ন",
|
"LabelUnabridged": "অসংলগ্ন",
|
||||||
"LabelUndo": "পূর্বাবস্থা",
|
"LabelUndo": "পূর্বাবস্থা",
|
||||||
"LabelUnknown": "অজানা",
|
"LabelUnknown": "অজানা",
|
||||||
|
"LabelUnknownPublishDate": "প্রকাশের তারিখ অজানা",
|
||||||
"LabelUpdateCover": "কভার আপডেট করুন",
|
"LabelUpdateCover": "কভার আপডেট করুন",
|
||||||
"LabelUpdateCoverHelp": "একটি মিল থাকা অবস্থায় নির্বাচিত বইগুলির বিদ্যমান কভারগুলি ওভাররাইট করার অনুমতি দিন",
|
"LabelUpdateCoverHelp": "একটি মিল থাকা অবস্থায় নির্বাচিত বইগুলির বিদ্যমান কভারগুলি ওভাররাইট করার অনুমতি দিন",
|
||||||
"LabelUpdateDetails": "বিশদ আপডেট করুন",
|
"LabelUpdateDetails": "বিশদ আপডেট করুন",
|
||||||
@@ -561,9 +627,12 @@
|
|||||||
"LabelVersion": "সংস্করণ",
|
"LabelVersion": "সংস্করণ",
|
||||||
"LabelViewBookmarks": "বুকমার্ক দেখুন",
|
"LabelViewBookmarks": "বুকমার্ক দেখুন",
|
||||||
"LabelViewChapters": "অধ্যায় দেখুন",
|
"LabelViewChapters": "অধ্যায় দেখুন",
|
||||||
|
"LabelViewPlayerSettings": "প্লেয়ার সেটিংস দেখুন",
|
||||||
"LabelViewQueue": "প্লেয়ার সারি দেখুন",
|
"LabelViewQueue": "প্লেয়ার সারি দেখুন",
|
||||||
"LabelVolume": "ভলিউম",
|
"LabelVolume": "ভলিউম",
|
||||||
"LabelWeekdaysToRun": "চলতে হবে সপ্তাহের দিন",
|
"LabelWeekdaysToRun": "চলতে হবে সপ্তাহের দিন",
|
||||||
|
"LabelXBooks": "{0}টি বই",
|
||||||
|
"LabelXItems": "{0}টি আইটেম",
|
||||||
"LabelYearReviewHide": "পর্যালোচনার বছর লুকান",
|
"LabelYearReviewHide": "পর্যালোচনার বছর লুকান",
|
||||||
"LabelYearReviewShow": "পর্যালোচনার বছর দেখুন",
|
"LabelYearReviewShow": "পর্যালোচনার বছর দেখুন",
|
||||||
"LabelYourAudiobookDuration": "আপনার অডিওবুকের সময়কাল",
|
"LabelYourAudiobookDuration": "আপনার অডিওবুকের সময়কাল",
|
||||||
@@ -571,12 +640,16 @@
|
|||||||
"LabelYourPlaylists": "আপনার প্লেলিস্ট",
|
"LabelYourPlaylists": "আপনার প্লেলিস্ট",
|
||||||
"LabelYourProgress": "আপনার অগ্রগতি",
|
"LabelYourProgress": "আপনার অগ্রগতি",
|
||||||
"MessageAddToPlayerQueue": "প্লেয়ার সারিতে যোগ করুন",
|
"MessageAddToPlayerQueue": "প্লেয়ার সারিতে যোগ করুন",
|
||||||
"MessageAppriseDescription": "এই বৈশিষ্ট্যটি ব্যবহার করার জন্য আপনাকে <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</-এর একটি উদাহরণ থাকতে হবে a> চলমান বা একটি এপিআই যা সেই একই অনুরোধগুলি পরিচালনা করবে৷ <br /> বিজ্ঞপ্তি পাঠানোর জন্য Apprise API Url সম্পূর্ণ URL পাথ হওয়া উচিত, যেমন, যদি আপনার API উদাহরণ <code>http://192.168 এ পরিবেশিত হয়৷ 1.1:8337</code> তারপর আপনি <code>http://192.168.1.1:8337/notify</code> লিখবেন।",
|
"MessageAppriseDescription": "এই বৈশিষ্ট্যটি ব্যবহার করার জন্য আপনাকে <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> চালানোর একটি উদাহরণ বা একটি এপিআই পরিচালনা করতে হবে যে একই অনুরোধ পরিচালনা করবে। <br />অ্যাপ্রাইজ এপিআই ইউআরএলটি বিজ্ঞপ্তি পাঠানোর জন্য সম্পূর্ণ ইউআরএল পথ হওয়া উচিত, যেমন, যদি আপনার API ইনস্ট্যান্স <code>http://192.168.1.1:8337</code> এ পরিবেশিত হয় তাহলে আপনি <code> রাখবেন >http://192.168.1.1:8337/notify</code>।",
|
||||||
"MessageBackupsDescription": "ব্যাকআপের মধ্যে রয়েছে ব্যবহারকারী, ব্যবহারকারীর অগ্রগতি, লাইব্রেরি আইটেমের বিবরণ, সার্ভার সেটিংস এবং <code>/metadata/items</code> & <code>/metadata/authors</code>-এ সংরক্ষিত ছবি। ব্যাকআপগুলি <strong> আপনার লাইব্রেরি ফোল্ডারে সঞ্চিত কোনো ফাইল >অন্তর্ভুক্ত করবেন না</strong>।",
|
"MessageBackupsDescription": "ব্যাকআপের মধ্যে রয়েছে ব্যবহারকারী, ব্যবহারকারীর অগ্রগতি, লাইব্রেরি আইটেমের বিবরণ, সার্ভার সেটিংস এবং <code>/metadata/items</code> & <code>/metadata/authors</code>-এ সংরক্ষিত ছবি। ব্যাকআপগুলি <strong> আপনার লাইব্রেরি ফোল্ডারে সঞ্চিত কোনো ফাইল >অন্তর্ভুক্ত করবেন না</strong>।",
|
||||||
|
"MessageBackupsLocationEditNote": "দ্রষ্টব্য: ব্যাকআপ অবস্থান আপডেট করলে বিদ্যমান ব্যাকআপগুলি সরানো বা সংশোধন করা হবে না",
|
||||||
|
"MessageBackupsLocationNoEditNote": "দ্রষ্টব্য: ব্যাকআপ অবস্থান একটি পরিবেশ পরিবর্তনশীল মাধ্যমে স্থির করা হয়েছে এবং এখানে পরিবর্তন করা যাবে না।",
|
||||||
|
"MessageBackupsLocationPathEmpty": "ব্যাকআপ অবস্থানের পথ খালি থাকতে পারবে না",
|
||||||
"MessageBatchQuickMatchDescription": "কুইক ম্যাচ নির্বাচিত আইটেমগুলির জন্য অনুপস্থিত কভার এবং মেটাডেটা যোগ করার চেষ্টা করবে। বিদ্যমান কভার এবং/অথবা মেটাডেটা ওভাররাইট করার জন্য দ্রুত ম্যাচকে অনুমতি দিতে নীচের বিকল্পগুলি সক্ষম করুন।",
|
"MessageBatchQuickMatchDescription": "কুইক ম্যাচ নির্বাচিত আইটেমগুলির জন্য অনুপস্থিত কভার এবং মেটাডেটা যোগ করার চেষ্টা করবে। বিদ্যমান কভার এবং/অথবা মেটাডেটা ওভাররাইট করার জন্য দ্রুত ম্যাচকে অনুমতি দিতে নীচের বিকল্পগুলি সক্ষম করুন।",
|
||||||
"MessageBookshelfNoCollections": "আপনি এখনও কোনো সংগ্রহ করেননি",
|
"MessageBookshelfNoCollections": "আপনি এখনও কোনো সংগ্রহ করেননি",
|
||||||
"MessageBookshelfNoRSSFeeds": "কোনও RSS ফিড খোলা নেই",
|
"MessageBookshelfNoRSSFeeds": "কোনও RSS ফিড খোলা নেই",
|
||||||
"MessageBookshelfNoResultsForFilter": "ফিল্টার \"{0}: {1}\" এর জন্য কোন ফলাফল নেই",
|
"MessageBookshelfNoResultsForFilter": "ফিল্টার \"{0}: {1}\" এর জন্য কোন ফলাফল নেই",
|
||||||
|
"MessageBookshelfNoResultsForQuery": "প্রশ্নের জন্য কোন ফলাফল নেই",
|
||||||
"MessageBookshelfNoSeries": "আপনার কোনো সিরিজ নেই",
|
"MessageBookshelfNoSeries": "আপনার কোনো সিরিজ নেই",
|
||||||
"MessageChapterEndIsAfter": "অধ্যায়ের সমাপ্তি আপনার অডিওবুকের শেষে",
|
"MessageChapterEndIsAfter": "অধ্যায়ের সমাপ্তি আপনার অডিওবুকের শেষে",
|
||||||
"MessageChapterErrorFirstNotZero": "প্রথম অধ্যায় 0 এ শুরু হতে হবে",
|
"MessageChapterErrorFirstNotZero": "প্রথম অধ্যায় 0 এ শুরু হতে হবে",
|
||||||
@@ -586,16 +659,24 @@
|
|||||||
"MessageCheckingCron": "ক্রন পরীক্ষা করা হচ্ছে...",
|
"MessageCheckingCron": "ক্রন পরীক্ষা করা হচ্ছে...",
|
||||||
"MessageConfirmCloseFeed": "আপনি কি নিশ্চিত যে আপনি এই ফিডটি বন্ধ করতে চান?",
|
"MessageConfirmCloseFeed": "আপনি কি নিশ্চিত যে আপনি এই ফিডটি বন্ধ করতে চান?",
|
||||||
"MessageConfirmDeleteBackup": "আপনি কি নিশ্চিত যে আপনি {0} এর ব্যাকআপ মুছে ফেলতে চান?",
|
"MessageConfirmDeleteBackup": "আপনি কি নিশ্চিত যে আপনি {0} এর ব্যাকআপ মুছে ফেলতে চান?",
|
||||||
|
"MessageConfirmDeleteDevice": "আপনি কি নিশ্চিতভাবে ই-রিডার ডিভাইস \"{0}\" মুছতে চান?",
|
||||||
"MessageConfirmDeleteFile": "এটি আপনার ফাইল সিস্টেম থেকে ফাইলটি মুছে দেবে। আপনি কি নিশ্চিত?",
|
"MessageConfirmDeleteFile": "এটি আপনার ফাইল সিস্টেম থেকে ফাইলটি মুছে দেবে। আপনি কি নিশ্চিত?",
|
||||||
"MessageConfirmDeleteLibrary": "আপনি কি নিশ্চিত যে আপনি স্থায়ীভাবে লাইব্রেরি \"{0}\" মুছে ফেলতে চান?",
|
"MessageConfirmDeleteLibrary": "আপনি কি নিশ্চিত যে আপনি স্থায়ীভাবে লাইব্রেরি \"{0}\" মুছে ফেলতে চান?",
|
||||||
"MessageConfirmDeleteLibraryItem": "এটি ডাটাবেস এবং আপনার ফাইল সিস্টেম থেকে লাইব্রেরি আইটেমটি মুছে ফেলবে। আপনি কি নিশ্চিত?",
|
"MessageConfirmDeleteLibraryItem": "এটি ডাটাবেস এবং আপনার ফাইল সিস্টেম থেকে লাইব্রেরি আইটেমটি মুছে ফেলবে। আপনি কি নিশ্চিত?",
|
||||||
"MessageConfirmDeleteLibraryItems": "এটি ডাটাবেস এবং আপনার ফাইল সিস্টেম থেকে {0}টি লাইব্রেরি আইটেম মুছে ফেলবে। আপনি কি নিশ্চিত?",
|
"MessageConfirmDeleteLibraryItems": "এটি ডাটাবেস এবং আপনার ফাইল সিস্টেম থেকে {0}টি লাইব্রেরি আইটেম মুছে ফেলবে। আপনি কি নিশ্চিত?",
|
||||||
|
"MessageConfirmDeleteMetadataProvider": "আপনি কি নিশ্চিতভাবে কাস্টম মেটাডেটা প্রদানকারী \"{0}\" মুছতে চান?",
|
||||||
|
"MessageConfirmDeleteNotification": "আপনি কি নিশ্চিতভাবে এই বিজ্ঞপ্তিটি মুছতে চান?",
|
||||||
"MessageConfirmDeleteSession": "আপনি কি নিশ্চিত আপনি এই অধিবেশন মুছে দিতে চান?",
|
"MessageConfirmDeleteSession": "আপনি কি নিশ্চিত আপনি এই অধিবেশন মুছে দিতে চান?",
|
||||||
"MessageConfirmForceReScan": "আপনি কি নিশ্চিত যে আপনি জোর করে পুনরায় স্ক্যান করতে চান?",
|
"MessageConfirmForceReScan": "আপনি কি নিশ্চিত যে আপনি জোর করে পুনরায় স্ক্যান করতে চান?",
|
||||||
"MessageConfirmMarkAllEpisodesFinished": "আপনি কি নিশ্চিত যে আপনি সমস্ত পর্ব সমাপ্ত হিসাবে চিহ্নিত করতে চান?",
|
"MessageConfirmMarkAllEpisodesFinished": "আপনি কি নিশ্চিত যে আপনি সমস্ত পর্ব সমাপ্ত হিসাবে চিহ্নিত করতে চান?",
|
||||||
"MessageConfirmMarkAllEpisodesNotFinished": "আপনি কি নিশ্চিত যে আপনি সমস্ত পর্বকে শেষ হয়নি বলে চিহ্নিত করতে চান?",
|
"MessageConfirmMarkAllEpisodesNotFinished": "আপনি কি নিশ্চিত যে আপনি সমস্ত পর্বকে শেষ হয়নি বলে চিহ্নিত করতে চান?",
|
||||||
|
"MessageConfirmMarkItemFinished": "আপনি কি \"{0}\" কে সমাপ্ত হিসাবে চিহ্নিত করার বিষয়ে নিশ্চিত?",
|
||||||
|
"MessageConfirmMarkItemNotFinished": "আপনি কি \"{0}\" শেষ হয়নি বলে চিহ্নিত করার বিষয়ে নিশ্চিত?",
|
||||||
"MessageConfirmMarkSeriesFinished": "আপনি কি নিশ্চিত যে আপনি এই সিরিজের সমস্ত বইকে সমাপ্ত হিসাবে চিহ্নিত করতে চান?",
|
"MessageConfirmMarkSeriesFinished": "আপনি কি নিশ্চিত যে আপনি এই সিরিজের সমস্ত বইকে সমাপ্ত হিসাবে চিহ্নিত করতে চান?",
|
||||||
"MessageConfirmMarkSeriesNotFinished": "আপনি কি নিশ্চিত যে আপনি এই সিরিজের সমস্ত বইকে শেষ হয়নি বলে চিহ্নিত করতে চান?",
|
"MessageConfirmMarkSeriesNotFinished": "আপনি কি নিশ্চিত যে আপনি এই সিরিজের সমস্ত বইকে শেষ হয়নি বলে চিহ্নিত করতে চান?",
|
||||||
|
"MessageConfirmNotificationTestTrigger": "পরীক্ষার তথ্য দিয়ে এই বিজ্ঞপ্তিটি ট্রিগার করবেন?",
|
||||||
|
"MessageConfirmPurgeCache": "ক্যাশে পরিষ্কারক <code>/metadata/cache</code>-এ সম্পূর্ণ ডিরেক্টরি মুছে ফেলবে। <br /><br />আপনি কি নিশ্চিত আপনি ক্যাশে ডিরেক্টরি সরাতে চান?",
|
||||||
|
"MessageConfirmPurgeItemsCache": "আইটেম ক্যাশে পরিষ্কারক <code>/metadata/cache/items</code>-এ সম্পূর্ণ ডিরেক্টরি মুছে ফেলবে।<br />আপনি কি নিশ্চিত?",
|
||||||
"MessageConfirmQuickEmbed": "সতর্কতা! দ্রুত এম্বেড আপনার অডিও ফাইলের ব্যাকআপ করবে না। নিশ্চিত করুন যে আপনার অডিও ফাইলগুলির একটি ব্যাকআপ আছে। <br><br>আপনি কি চালিয়ে যেতে চান?",
|
"MessageConfirmQuickEmbed": "সতর্কতা! দ্রুত এম্বেড আপনার অডিও ফাইলের ব্যাকআপ করবে না। নিশ্চিত করুন যে আপনার অডিও ফাইলগুলির একটি ব্যাকআপ আছে। <br><br>আপনি কি চালিয়ে যেতে চান?",
|
||||||
"MessageConfirmReScanLibraryItems": "আপনি কি নিশ্চিত যে আপনি {0}টি আইটেম পুনরায় স্ক্যান করতে চান?",
|
"MessageConfirmReScanLibraryItems": "আপনি কি নিশ্চিত যে আপনি {0}টি আইটেম পুনরায় স্ক্যান করতে চান?",
|
||||||
"MessageConfirmRemoveAllChapters": "আপনি কি নিশ্চিত যে আপনি সমস্ত অধ্যায় সরাতে চান?",
|
"MessageConfirmRemoveAllChapters": "আপনি কি নিশ্চিত যে আপনি সমস্ত অধ্যায় সরাতে চান?",
|
||||||
@@ -612,14 +693,17 @@
|
|||||||
"MessageConfirmRenameTag": "আপনি কি সব আইটেমের জন্য \"{0}\" ট্যাগের নাম পরিবর্তন করে \"{1}\" করার বিষয়ে নিশ্চিত?",
|
"MessageConfirmRenameTag": "আপনি কি সব আইটেমের জন্য \"{0}\" ট্যাগের নাম পরিবর্তন করে \"{1}\" করার বিষয়ে নিশ্চিত?",
|
||||||
"MessageConfirmRenameTagMergeNote": "দ্রষ্টব্য: এই ট্যাগটি আগে থেকেই বিদ্যমান তাই সেগুলিকে একত্র করা হবে।",
|
"MessageConfirmRenameTagMergeNote": "দ্রষ্টব্য: এই ট্যাগটি আগে থেকেই বিদ্যমান তাই সেগুলিকে একত্র করা হবে।",
|
||||||
"MessageConfirmRenameTagWarning": "সতর্কতা! একটি ভিন্ন কেসিং সহ একটি অনুরূপ ট্যাগ ইতিমধ্যেই বিদ্যমান \"{0}\"।",
|
"MessageConfirmRenameTagWarning": "সতর্কতা! একটি ভিন্ন কেসিং সহ একটি অনুরূপ ট্যাগ ইতিমধ্যেই বিদ্যমান \"{0}\"।",
|
||||||
|
"MessageConfirmResetProgress": "আপনি কি আপনার অগ্রগতি রিসেট করার বিষয়ে নিশ্চিত?",
|
||||||
"MessageConfirmSendEbookToDevice": "আপনি কি নিশ্চিত যে আপনি \"{2}\" ডিভাইসে {0} ইবুক \"{1}\" পাঠাতে চান?",
|
"MessageConfirmSendEbookToDevice": "আপনি কি নিশ্চিত যে আপনি \"{2}\" ডিভাইসে {0} ইবুক \"{1}\" পাঠাতে চান?",
|
||||||
|
"MessageConfirmUnlinkOpenId": "আপনি কি এই ব্যবহারকারীকে ওপেনআইডি থেকে লিঙ্কমুক্ত করার বিষয়ে নিশ্চিত?",
|
||||||
"MessageDownloadingEpisode": "ডাউনলোডিং পর্ব",
|
"MessageDownloadingEpisode": "ডাউনলোডিং পর্ব",
|
||||||
"MessageDragFilesIntoTrackOrder": "সঠিক ট্র্যাক অর্ডারে ফাইল টেনে আনুন",
|
"MessageDragFilesIntoTrackOrder": "সঠিক ট্র্যাক অর্ডারে ফাইল টেনে আনুন",
|
||||||
|
"MessageEmbedFailed": "এম্বেড ব্যর্থ হয়েছে!",
|
||||||
"MessageEmbedFinished": "এম্বেড করা শেষ!",
|
"MessageEmbedFinished": "এম্বেড করা শেষ!",
|
||||||
"MessageEpisodesQueuedForDownload": "{0} পর্ব(গুলি) ডাউনলোডের জন্য সারিবদ্ধ",
|
"MessageEpisodesQueuedForDownload": "{0} পর্ব(গুলি) ডাউনলোডের জন্য সারিবদ্ধ",
|
||||||
"MessageEreaderDevices": "To ensure delivery of ebooks, you may need to add the above email address as a valid sender for each device listed below।",
|
"MessageEreaderDevices": "ই-বুক সরবরাহ নিশ্চিত করতে, আপনাকে নীচে তালিকাভুক্ত প্রতিটি ডিভাইসের জন্য একটি বৈধ প্রেরক হিসাবে উপরের ইমেল ঠিকানাটি যুক্ত করতে হতে পারে।",
|
||||||
"MessageFeedURLWillBe": "ফিড URL হবে {0}",
|
"MessageFeedURLWillBe": "ফিড URL হবে {0}",
|
||||||
"MessageFetching": "আনয় হচ্ছে...",
|
"MessageFetching": "আনয় হচ্ছে.।",
|
||||||
"MessageForceReScanDescription": "সকল ফাইল আবার নতুন স্ক্যানের মত স্ক্যান করবে। অডিও ফাইল ID3 ট্যাগ, OPF ফাইল, এবং টেক্সট ফাইলগুলি নতুন হিসাবে স্ক্যান করা হবে।",
|
"MessageForceReScanDescription": "সকল ফাইল আবার নতুন স্ক্যানের মত স্ক্যান করবে। অডিও ফাইল ID3 ট্যাগ, OPF ফাইল, এবং টেক্সট ফাইলগুলি নতুন হিসাবে স্ক্যান করা হবে।",
|
||||||
"MessageImportantNotice": "গুরুত্বপূর্ণ বিজ্ঞপ্তি!",
|
"MessageImportantNotice": "গুরুত্বপূর্ণ বিজ্ঞপ্তি!",
|
||||||
"MessageInsertChapterBelow": "নীচে অধ্যায় ঢোকান",
|
"MessageInsertChapterBelow": "নীচে অধ্যায় ঢোকান",
|
||||||
@@ -627,9 +711,9 @@
|
|||||||
"MessageItemsUpdated": "{0}টি আইটেম আপডেট করা হয়েছে",
|
"MessageItemsUpdated": "{0}টি আইটেম আপডেট করা হয়েছে",
|
||||||
"MessageJoinUsOn": "আমাদের সাথে যোগ দিন",
|
"MessageJoinUsOn": "আমাদের সাথে যোগ দিন",
|
||||||
"MessageListeningSessionsInTheLastYear": "গত বছরে {0}টি শোনার সেশন",
|
"MessageListeningSessionsInTheLastYear": "গত বছরে {0}টি শোনার সেশন",
|
||||||
"MessageLoading": "লোড হচ্ছে...",
|
"MessageLoading": "লোড হচ্ছে.।",
|
||||||
"MessageLoadingFolders": "ফোল্ডার লোড হচ্ছে...",
|
"MessageLoadingFolders": "ফোল্ডার লোড হচ্ছে...",
|
||||||
"MessageLogsDescription": "Logs are stored in <code>/metadata/logs</code> as JSON files. Crash logs are stored in <code>/metadata/logs/crash_logs.txt</code>।",
|
"MessageLogsDescription": "লগগুলি JSON ফাইল হিসাবে <code>/metadata/logs</code>-এ সংরক্ষণ করা হয়। ক্র্যাশ লগগুলি <code>/metadata/logs/crash_logs.txt</code>-এ সংরক্ষণ করা হয়।",
|
||||||
"MessageM4BFailed": "M4B ব্যর্থ!",
|
"MessageM4BFailed": "M4B ব্যর্থ!",
|
||||||
"MessageM4BFinished": "M4B সমাপ্ত!",
|
"MessageM4BFinished": "M4B সমাপ্ত!",
|
||||||
"MessageMapChapterTitles": "টাইমস্ট্যাম্প সামঞ্জস্য না করে আপনার বিদ্যমান অডিওবুক অধ্যায়গুলিতে অধ্যায়ের শিরোনাম ম্যাপ করুন",
|
"MessageMapChapterTitles": "টাইমস্ট্যাম্প সামঞ্জস্য না করে আপনার বিদ্যমান অডিওবুক অধ্যায়গুলিতে অধ্যায়ের শিরোনাম ম্যাপ করুন",
|
||||||
@@ -646,6 +730,7 @@
|
|||||||
"MessageNoCollections": "কোন সংগ্রহ নেই",
|
"MessageNoCollections": "কোন সংগ্রহ নেই",
|
||||||
"MessageNoCoversFound": "কোন কভার পাওয়া যায়নি",
|
"MessageNoCoversFound": "কোন কভার পাওয়া যায়নি",
|
||||||
"MessageNoDescription": "কোন বর্ণনা নেই",
|
"MessageNoDescription": "কোন বর্ণনা নেই",
|
||||||
|
"MessageNoDevices": "কোনো ডিভাইস নেই",
|
||||||
"MessageNoDownloadsInProgress": "বর্তমানে কোনো ডাউনলোড চলছে না",
|
"MessageNoDownloadsInProgress": "বর্তমানে কোনো ডাউনলোড চলছে না",
|
||||||
"MessageNoDownloadsQueued": "কোনও ডাউনলোড সারি নেই",
|
"MessageNoDownloadsQueued": "কোনও ডাউনলোড সারি নেই",
|
||||||
"MessageNoEpisodeMatchesFound": "কোন পর্বের মিল পাওয়া যায়নি",
|
"MessageNoEpisodeMatchesFound": "কোন পর্বের মিল পাওয়া যায়নি",
|
||||||
@@ -668,10 +753,12 @@
|
|||||||
"MessageNoUpdatesWereNecessary": "কোন আপডেটের প্রয়োজন ছিল না",
|
"MessageNoUpdatesWereNecessary": "কোন আপডেটের প্রয়োজন ছিল না",
|
||||||
"MessageNoUserPlaylists": "আপনার কোনো প্লেলিস্ট নেই",
|
"MessageNoUserPlaylists": "আপনার কোনো প্লেলিস্ট নেই",
|
||||||
"MessageNotYetImplemented": "এখনও বাস্তবায়িত হয়নি",
|
"MessageNotYetImplemented": "এখনও বাস্তবায়িত হয়নি",
|
||||||
|
"MessageOpmlPreviewNote": "দ্রষ্টব্য: এটি পার্স করা OPML ফাইলের একটি পূর্বরূপ। প্রকৃত পডকাস্ট শিরোনাম RSS ফিড থেকে নেওয়া হবে।",
|
||||||
"MessageOr": "বা",
|
"MessageOr": "বা",
|
||||||
"MessagePauseChapter": "পজ অধ্যায় প্লেব্যাক",
|
"MessagePauseChapter": "পজ অধ্যায় প্লেব্যাক",
|
||||||
"MessagePlayChapter": "অধ্যায়ের শুরুতে শুনুন",
|
"MessagePlayChapter": "অধ্যায়ের শুরুতে শুনুন",
|
||||||
"MessagePlaylistCreateFromCollection": "সংগ্রহ থেকে প্লেলিস্ট তৈরি করুন",
|
"MessagePlaylistCreateFromCollection": "সংগ্রহ থেকে প্লেলিস্ট তৈরি করুন",
|
||||||
|
"MessagePleaseWait": "অনুগ্রহ করে অপেক্ষা করুন..।",
|
||||||
"MessagePodcastHasNoRSSFeedForMatching": "পডকাস্টের সাথে মিলের জন্য ব্যবহার করার জন্য কোন RSS ফিড ইউআরএল নেই",
|
"MessagePodcastHasNoRSSFeedForMatching": "পডকাস্টের সাথে মিলের জন্য ব্যবহার করার জন্য কোন RSS ফিড ইউআরএল নেই",
|
||||||
"MessageQuickMatchDescription": "খালি আইটেমের বিশদ বিবরণ এবং '{0}' থেকে প্রথম ম্যাচের ফলাফলের সাথে কভার করুন। সার্ভার সেটিং সক্ষম না থাকলে বিশদ ওভাররাইট করে না।",
|
"MessageQuickMatchDescription": "খালি আইটেমের বিশদ বিবরণ এবং '{0}' থেকে প্রথম ম্যাচের ফলাফলের সাথে কভার করুন। সার্ভার সেটিং সক্ষম না থাকলে বিশদ ওভাররাইট করে না।",
|
||||||
"MessageRemoveChapter": "অধ্যায় সরান",
|
"MessageRemoveChapter": "অধ্যায় সরান",
|
||||||
@@ -686,7 +773,42 @@
|
|||||||
"MessageSelected": "{0}টি নির্বাচিত",
|
"MessageSelected": "{0}টি নির্বাচিত",
|
||||||
"MessageServerCouldNotBeReached": "সার্ভারে পৌঁছানো যায়নি",
|
"MessageServerCouldNotBeReached": "সার্ভারে পৌঁছানো যায়নি",
|
||||||
"MessageSetChaptersFromTracksDescription": "প্রতিটি অডিও ফাইলকে অধ্যায় হিসেবে ব্যবহার করে অধ্যায় সেট করুন এবং অডিও ফাইলের নাম হিসেবে অধ্যায়ের শিরোনাম করুন",
|
"MessageSetChaptersFromTracksDescription": "প্রতিটি অডিও ফাইলকে অধ্যায় হিসেবে ব্যবহার করে অধ্যায় সেট করুন এবং অডিও ফাইলের নাম হিসেবে অধ্যায়ের শিরোনাম করুন",
|
||||||
|
"MessageShareExpirationWillBe": "মেয়াদ শেষ হবে <strong>{0}</strong>",
|
||||||
|
"MessageShareExpiresIn": "মেয়াদ শেষ হবে {0}",
|
||||||
|
"MessageShareURLWillBe": "শেয়ার করা ইউআরএল হবে <strong>{0}</strong>",
|
||||||
"MessageStartPlaybackAtTime": "\"{0}\" এর জন্য {1} এ প্লেব্যাক শুরু করবেন?",
|
"MessageStartPlaybackAtTime": "\"{0}\" এর জন্য {1} এ প্লেব্যাক শুরু করবেন?",
|
||||||
|
"MessageTaskAudioFileNotWritable": "অডিও ফাইল \"{0}\" লেখার যোগ্য নয়",
|
||||||
|
"MessageTaskCanceledByUser": "ব্যবহারকারী দ্বারা টাস্ক বাতিল করা হয়েছে",
|
||||||
|
"MessageTaskDownloadingEpisodeDescription": "\"{0}\" পর্ব ডাউনলোড করা হচ্ছে",
|
||||||
|
"MessageTaskEmbeddingMetadata": "মেটাডেটা এম্বেড করা হচ্ছে",
|
||||||
|
"MessageTaskEmbeddingMetadataDescription": "অডিওবুক \"{0}\" এ মেটাডেটা এম্বেড করা হচ্ছে",
|
||||||
|
"MessageTaskEncodingM4b": "এনকোডিং M4B",
|
||||||
|
"MessageTaskEncodingM4bDescription": "একটি একক m4b ফাইলে অডিওবুক \"{0}\" এনকোড করা হচ্ছে",
|
||||||
|
"MessageTaskFailed": "ব্যর্থ হয়েছে",
|
||||||
|
"MessageTaskFailedToBackupAudioFile": "অডিও ফাইল \"{0}\" ব্যাকআপ করতে ব্যর্থ হয়েছে",
|
||||||
|
"MessageTaskFailedToCreateCacheDirectory": "ক্যাশে ডিরেক্টরি তৈরি করতে ব্যর্থ হয়েছে",
|
||||||
|
"MessageTaskFailedToEmbedMetadataInFile": "\"{0}\" ফাইলে মেটাডেটা এম্বেড করতে ব্যর্থ হয়েছে",
|
||||||
|
"MessageTaskFailedToMergeAudioFiles": "অডিও ফাইল মার্জ করতে ব্যর্থ হয়েছে",
|
||||||
|
"MessageTaskFailedToMoveM4bFile": "m4b ফাইল সরাতে ব্যর্থ হয়েছে",
|
||||||
|
"MessageTaskFailedToWriteMetadataFile": "মেটাডেটা ফাইল লিখতে ব্যর্থ হয়েছে",
|
||||||
|
"MessageTaskMatchingBooksInLibrary": "লাইব্রেরি \"{0}\"-এ বই মিলানো হচ্ছে",
|
||||||
|
"MessageTaskNoFilesToScan": "স্ক্যান করার জন্য কোন ফাইল নেই",
|
||||||
|
"MessageTaskOpmlImport": "OPML আমদানি",
|
||||||
|
"MessageTaskOpmlImportDescription": "{0} RSS ফিড থেকে পডকাস্ট তৈরি করা হচ্ছে",
|
||||||
|
"MessageTaskOpmlImportFeed": "OPML ফিড আমদানি",
|
||||||
|
"MessageTaskOpmlImportFeedDescription": "RSS ফিড \"{0}\" আমদানি করা হচ্ছে",
|
||||||
|
"MessageTaskOpmlImportFeedFailed": "পডকাস্ট ফিড পেতে ব্যর্থ হয়েছে",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastDescription": "পডকাস্ট তৈরি করা হচ্ছে \"{0}\"",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastExists": "পডকাস্ট আগে থেকেই পাথে বিদ্যমান",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastFailed": "পডকাস্ট তৈরি করতে ব্যর্থ",
|
||||||
|
"MessageTaskOpmlImportFinished": "{0}টি পডকাস্ট যোগ করা হয়েছে",
|
||||||
|
"MessageTaskScanItemsAdded": "{0}টি করা হয়েছে",
|
||||||
|
"MessageTaskScanItemsMissing": "{0}টি অনুপস্থিত",
|
||||||
|
"MessageTaskScanItemsUpdated": "{0} টি আপডেট করা হয়েছে",
|
||||||
|
"MessageTaskScanNoChangesNeeded": "কোন পরিবর্তন প্রয়োজন নেই",
|
||||||
|
"MessageTaskScanningFileChanges": "\"{0}\" এ ফাইলের পরিবর্তন স্ক্যান করা হচ্ছে",
|
||||||
|
"MessageTaskScanningLibrary": "\"{0}\" লাইব্রেরি স্ক্যান করা হচ্ছে",
|
||||||
|
"MessageTaskTargetDirectoryNotWritable": "টার্গেট ডিরেক্টরি লেখার যোগ্য নয়",
|
||||||
"MessageThinking": "চিন্তা করছি...",
|
"MessageThinking": "চিন্তা করছি...",
|
||||||
"MessageUploaderItemFailed": "আপলোড করতে ব্যর্থ",
|
"MessageUploaderItemFailed": "আপলোড করতে ব্যর্থ",
|
||||||
"MessageUploaderItemSuccess": "সফলভাবে আপলোড হয়েছে!",
|
"MessageUploaderItemSuccess": "সফলভাবে আপলোড হয়েছে!",
|
||||||
@@ -709,69 +831,162 @@
|
|||||||
"PlaceholderNewPlaylist": "নতুন প্লেলিস্টের নাম",
|
"PlaceholderNewPlaylist": "নতুন প্লেলিস্টের নাম",
|
||||||
"PlaceholderSearch": "অনুসন্ধান..",
|
"PlaceholderSearch": "অনুসন্ধান..",
|
||||||
"PlaceholderSearchEpisode": "অনুসন্ধান পর্ব..",
|
"PlaceholderSearchEpisode": "অনুসন্ধান পর্ব..",
|
||||||
"ToastAccountUpdateFailed": "অ্যাকাউন্ট আপডেট করতে ব্যর্থ",
|
"StatsAuthorsAdded": "লেখক যোগ করা হয়েছে",
|
||||||
|
"StatsBooksAdded": "বই যোগ করা হয়েছে",
|
||||||
|
"StatsBooksAdditional": "কিছু সংযোজনের মধ্যে রয়েছে…",
|
||||||
|
"StatsBooksFinished": "বই সমাপ্ত",
|
||||||
|
"StatsBooksFinishedThisYear": "এ বছর শেষ হওয়া কিছু বই …",
|
||||||
|
"StatsBooksListenedTo": "বই শোনা হয়েছে",
|
||||||
|
"StatsCollectionGrewTo": "আপনার বইয়ের সংগ্রহ বেড়েছে…",
|
||||||
|
"StatsSessions": "অধিবেশনসমূহ",
|
||||||
|
"StatsSpentListening": "শুনে কাটিয়েছেন",
|
||||||
|
"StatsTopAuthor": "শীর্ষস্থানীয় লেখক",
|
||||||
|
"StatsTopAuthors": "শীর্ষস্থানীয় লেখকগণ",
|
||||||
|
"StatsTopGenre": "শীর্ষ ঘরানা",
|
||||||
|
"StatsTopGenres": "শীর্ষ ঘরানাগুলো",
|
||||||
|
"StatsTopMonth": "সেরা মাস",
|
||||||
|
"StatsTopNarrator": "শীর্ষ কথক",
|
||||||
|
"StatsTopNarrators": "শীর্ষ কথকগণ",
|
||||||
|
"StatsTotalDuration": "মোট সময়কাল…",
|
||||||
|
"StatsYearInReview": "বাৎসরিক পর্যালোচনা",
|
||||||
"ToastAccountUpdateSuccess": "অ্যাকাউন্ট আপডেট করা হয়েছে",
|
"ToastAccountUpdateSuccess": "অ্যাকাউন্ট আপডেট করা হয়েছে",
|
||||||
|
"ToastAppriseUrlRequired": "একটি Apprise ইউআরএল লিখতে হবে",
|
||||||
"ToastAuthorImageRemoveSuccess": "লেখকের ছবি সরানো হয়েছে",
|
"ToastAuthorImageRemoveSuccess": "লেখকের ছবি সরানো হয়েছে",
|
||||||
"ToastAuthorUpdateFailed": "লেখক আপডেট করতে ব্যর্থ",
|
"ToastAuthorNotFound": "লেখক \"{0}\" খুঁজে পাওয়া যায়নি",
|
||||||
|
"ToastAuthorRemoveSuccess": "লেখক সরানো হয়েছে",
|
||||||
|
"ToastAuthorSearchNotFound": "লেখক পাওয়া যায়নি",
|
||||||
"ToastAuthorUpdateMerged": "লেখক একত্রিত হয়েছে",
|
"ToastAuthorUpdateMerged": "লেখক একত্রিত হয়েছে",
|
||||||
"ToastAuthorUpdateSuccess": "লেখক আপডেট করেছেন",
|
"ToastAuthorUpdateSuccess": "লেখক আপডেট করেছেন",
|
||||||
"ToastAuthorUpdateSuccessNoImageFound": "লেখক আপডেট করেছেন (কোন ছবি পাওয়া যায়নি)",
|
"ToastAuthorUpdateSuccessNoImageFound": "লেখক আপডেট করেছেন (কোন ছবি পাওয়া যায়নি)",
|
||||||
|
"ToastBackupAppliedSuccess": "ব্যাকআপ প্রয়োগ করা হয়েছে",
|
||||||
"ToastBackupCreateFailed": "ব্যাকআপ তৈরি করতে ব্যর্থ",
|
"ToastBackupCreateFailed": "ব্যাকআপ তৈরি করতে ব্যর্থ",
|
||||||
"ToastBackupCreateSuccess": "ব্যাকআপ তৈরি করা হয়েছে",
|
"ToastBackupCreateSuccess": "ব্যাকআপ তৈরি করা হয়েছে",
|
||||||
"ToastBackupDeleteFailed": "ব্যাকআপ মুছে ফেলতে ব্যর্থ",
|
"ToastBackupDeleteFailed": "ব্যাকআপ মুছে ফেলতে ব্যর্থ",
|
||||||
"ToastBackupDeleteSuccess": "ব্যাকআপ মুছে ফেলা হয়েছে",
|
"ToastBackupDeleteSuccess": "ব্যাকআপ মুছে ফেলা হয়েছে",
|
||||||
|
"ToastBackupInvalidMaxKeep": "রাখার জন্য অকার্যকর ব্যাকআপের সংখ্যা",
|
||||||
|
"ToastBackupInvalidMaxSize": "অকার্যকর সর্বোচ্চ ব্যাকআপ আকার",
|
||||||
"ToastBackupRestoreFailed": "ব্যাকআপ পুনরুদ্ধার করতে ব্যর্থ",
|
"ToastBackupRestoreFailed": "ব্যাকআপ পুনরুদ্ধার করতে ব্যর্থ",
|
||||||
"ToastBackupUploadFailed": "ব্যাকআপ আপলোড করতে ব্যর্থ",
|
"ToastBackupUploadFailed": "ব্যাকআপ আপলোড করতে ব্যর্থ",
|
||||||
"ToastBackupUploadSuccess": "ব্যাকআপ আপলোড হয়েছে",
|
"ToastBackupUploadSuccess": "ব্যাকআপ আপলোড হয়েছে",
|
||||||
|
"ToastBatchDeleteFailed": "ব্যাচ মুছে ফেলতে ব্যর্থ হয়েছে",
|
||||||
|
"ToastBatchDeleteSuccess": "ব্যাচ মুছে ফেলা সফল হয়েছে",
|
||||||
"ToastBatchUpdateFailed": "ব্যাচ আপডেট ব্যর্থ হয়েছে",
|
"ToastBatchUpdateFailed": "ব্যাচ আপডেট ব্যর্থ হয়েছে",
|
||||||
"ToastBatchUpdateSuccess": "ব্যাচ আপডেট সাফল্য",
|
"ToastBatchUpdateSuccess": "ব্যাচ আপডেট সাফল্য",
|
||||||
"ToastBookmarkCreateFailed": "বুকমার্ক তৈরি করতে ব্যর্থ",
|
"ToastBookmarkCreateFailed": "বুকমার্ক তৈরি করতে ব্যর্থ",
|
||||||
"ToastBookmarkCreateSuccess": "বুকমার্ক যোগ করা হয়েছে",
|
"ToastBookmarkCreateSuccess": "বুকমার্ক যোগ করা হয়েছে",
|
||||||
"ToastBookmarkRemoveSuccess": "বুকমার্ক সরানো হয়েছে",
|
"ToastBookmarkRemoveSuccess": "বুকমার্ক সরানো হয়েছে",
|
||||||
"ToastBookmarkUpdateFailed": "বুকমার্ক আপডেট করতে ব্যর্থ",
|
|
||||||
"ToastBookmarkUpdateSuccess": "বুকমার্ক আপডেট করা হয়েছে",
|
"ToastBookmarkUpdateSuccess": "বুকমার্ক আপডেট করা হয়েছে",
|
||||||
|
"ToastCachePurgeFailed": "ক্যাশে পরিষ্কার করতে ব্যর্থ হয়েছে",
|
||||||
|
"ToastCachePurgeSuccess": "ক্যাশে সফলভাবে পরিষ্কার করা হয়েছে",
|
||||||
"ToastChaptersHaveErrors": "অধ্যায়ে ত্রুটি আছে",
|
"ToastChaptersHaveErrors": "অধ্যায়ে ত্রুটি আছে",
|
||||||
"ToastChaptersMustHaveTitles": "অধ্যায়ের শিরোনাম থাকতে হবে",
|
"ToastChaptersMustHaveTitles": "অধ্যায়ের শিরোনাম থাকতে হবে",
|
||||||
|
"ToastChaptersRemoved": "অধ্যায়গুলো মুছে ফেলা হয়েছে",
|
||||||
|
"ToastCollectionItemsAddFailed": "আইটেম(গুলি) সংগ্রহে যোগ করা ব্যর্থ হয়েছে",
|
||||||
|
"ToastCollectionItemsAddSuccess": "আইটেম(গুলি) সংগ্রহে যোগ করা সফল হয়েছে",
|
||||||
"ToastCollectionItemsRemoveSuccess": "আইটেম(গুলি) সংগ্রহ থেকে সরানো হয়েছে",
|
"ToastCollectionItemsRemoveSuccess": "আইটেম(গুলি) সংগ্রহ থেকে সরানো হয়েছে",
|
||||||
"ToastCollectionRemoveSuccess": "সংগ্রহ সরানো হয়েছে",
|
"ToastCollectionRemoveSuccess": "সংগ্রহ সরানো হয়েছে",
|
||||||
"ToastCollectionUpdateFailed": "সংগ্রহ আপডেট করতে ব্যর্থ",
|
|
||||||
"ToastCollectionUpdateSuccess": "সংগ্রহ আপডেট করা হয়েছে",
|
"ToastCollectionUpdateSuccess": "সংগ্রহ আপডেট করা হয়েছে",
|
||||||
"ToastItemCoverUpdateFailed": "আইটেম কভার আপডেট করতে ব্যর্থ হয়েছে",
|
"ToastCoverUpdateFailed": "কভার আপডেট ব্যর্থ হয়েছে",
|
||||||
|
"ToastDeleteFileFailed": "ফাইল মুছে ফেলতে ব্যর্থ হয়েছে",
|
||||||
|
"ToastDeleteFileSuccess": "ফাইল মুছে ফেলা হয়েছে",
|
||||||
|
"ToastDeviceAddFailed": "ডিভাইস যোগ করতে ব্যর্থ হয়েছে",
|
||||||
|
"ToastDeviceNameAlreadyExists": "এই নামের ইরিডার ডিভাইস ইতিমধ্যেই বিদ্যমান",
|
||||||
|
"ToastDeviceTestEmailFailed": "পরীক্ষামূলক ইমেল পাঠাতে ব্যর্থ হয়েছে",
|
||||||
|
"ToastDeviceTestEmailSuccess": "পরীক্ষামূলক ইমেল পাঠানো হয়েছে",
|
||||||
|
"ToastEmailSettingsUpdateSuccess": "ইমেল সেটিংস আপডেট করা হয়েছে",
|
||||||
|
"ToastEncodeCancelFailed": "এনকোড বাতিল করতে ব্যর্থ হয়েছে",
|
||||||
|
"ToastEncodeCancelSucces": "এনকোড বাতিল করা হয়েছে",
|
||||||
|
"ToastEpisodeDownloadQueueClearFailed": "সারি সাফ করতে ব্যর্থ হয়েছে",
|
||||||
|
"ToastEpisodeDownloadQueueClearSuccess": "পর্ব ডাউনলোড সারি পরিষ্কার করা হয়েছে",
|
||||||
|
"ToastErrorCannotShare": "এই ডিভাইসে স্থানীয়ভাবে শেয়ার করা যাবে না",
|
||||||
|
"ToastFailedToLoadData": "ডেটা লোড করা যায়নি",
|
||||||
|
"ToastFailedToShare": "শেয়ার করতে ব্যর্থ",
|
||||||
|
"ToastFailedToUpdate": "আপডেট করতে ব্যর্থ হয়েছে",
|
||||||
|
"ToastInvalidImageUrl": "অকার্যকর ছবির ইউআরএল",
|
||||||
|
"ToastInvalidUrl": "অকার্যকর ইউআরএল",
|
||||||
"ToastItemCoverUpdateSuccess": "আইটেম কভার আপডেট করা হয়েছে",
|
"ToastItemCoverUpdateSuccess": "আইটেম কভার আপডেট করা হয়েছে",
|
||||||
"ToastItemDetailsUpdateFailed": "আইটেমের বিবরণ আপডেট করতে ব্যর্থ",
|
"ToastItemDeletedFailed": "আইটেম মুছে ফেলতে ব্যর্থ",
|
||||||
|
"ToastItemDeletedSuccess": "মুছে ফেলা আইটেম",
|
||||||
"ToastItemDetailsUpdateSuccess": "আইটেমের বিবরণ আপডেট করা হয়েছে",
|
"ToastItemDetailsUpdateSuccess": "আইটেমের বিবরণ আপডেট করা হয়েছে",
|
||||||
"ToastItemMarkedAsFinishedFailed": "সমাপ্ত হিসাবে চিহ্নিত করতে ব্যর্থ",
|
"ToastItemMarkedAsFinishedFailed": "সমাপ্ত হিসাবে চিহ্নিত করতে ব্যর্থ",
|
||||||
"ToastItemMarkedAsFinishedSuccess": "আইটেম সমাপ্ত হিসাবে চিহ্নিত",
|
"ToastItemMarkedAsFinishedSuccess": "আইটেম সমাপ্ত হিসাবে চিহ্নিত",
|
||||||
"ToastItemMarkedAsNotFinishedFailed": "সমাপ্ত হয়নি হিসাবে চিহ্নিত করতে ব্যর্থ",
|
"ToastItemMarkedAsNotFinishedFailed": "সমাপ্ত হয়নি হিসাবে চিহ্নিত করতে ব্যর্থ",
|
||||||
"ToastItemMarkedAsNotFinishedSuccess": "আইটেম সমাপ্ত হয়নি বলে চিহ্নিত",
|
"ToastItemMarkedAsNotFinishedSuccess": "আইটেম সমাপ্ত হয়নি বলে চিহ্নিত",
|
||||||
|
"ToastItemUpdateSuccess": "আইটেম আপডেট করা হয়েছে",
|
||||||
"ToastLibraryCreateFailed": "লাইব্রেরি তৈরি করতে ব্যর্থ",
|
"ToastLibraryCreateFailed": "লাইব্রেরি তৈরি করতে ব্যর্থ",
|
||||||
"ToastLibraryCreateSuccess": "লাইব্রেরি \"{0}\" তৈরি করা হয়েছে",
|
"ToastLibraryCreateSuccess": "লাইব্রেরি \"{0}\" তৈরি করা হয়েছে",
|
||||||
"ToastLibraryDeleteFailed": "লাইব্রেরি মুছে ফেলতে ব্যর্থ",
|
"ToastLibraryDeleteFailed": "লাইব্রেরি মুছে ফেলতে ব্যর্থ",
|
||||||
"ToastLibraryDeleteSuccess": "লাইব্রেরি মুছে ফেলা হয়েছে",
|
"ToastLibraryDeleteSuccess": "লাইব্রেরি মুছে ফেলা হয়েছে",
|
||||||
"ToastLibraryScanFailedToStart": "স্ক্যান শুরু করতে ব্যর্থ",
|
"ToastLibraryScanFailedToStart": "স্ক্যান শুরু করতে ব্যর্থ",
|
||||||
"ToastLibraryScanStarted": "লাইব্রেরি স্ক্যান শুরু হয়েছে",
|
"ToastLibraryScanStarted": "লাইব্রেরি স্ক্যান শুরু হয়েছে",
|
||||||
"ToastLibraryUpdateFailed": "লাইব্রেরি আপডেট করতে ব্যর্থ",
|
|
||||||
"ToastLibraryUpdateSuccess": "লাইব্রেরি \"{0}\" আপডেট করা হয়েছে",
|
"ToastLibraryUpdateSuccess": "লাইব্রেরি \"{0}\" আপডেট করা হয়েছে",
|
||||||
|
"ToastNameEmailRequired": "নাম এবং ইমেইল আবশ্যক",
|
||||||
|
"ToastNameRequired": "নাম আবশ্যক",
|
||||||
|
"ToastNewUserCreatedFailed": "অ্যাকাউন্ট তৈরি করতে ব্যর্থ: \"{0}\"",
|
||||||
|
"ToastNewUserCreatedSuccess": "নতুন একাউন্ট তৈরি হয়েছে",
|
||||||
|
"ToastNewUserLibraryError": "অন্তত একটি লাইব্রেরি নির্বাচন করতে হবে",
|
||||||
|
"ToastNewUserPasswordError": "অন্তত একটি পাসওয়ার্ড থাকতে হবে, শুধুমাত্র রুট ব্যবহারকারীর একটি খালি পাসওয়ার্ড থাকতে পারে",
|
||||||
|
"ToastNewUserTagError": "অন্তত একটি ট্যাগ নির্বাচন করতে হবে",
|
||||||
|
"ToastNewUserUsernameError": "একটি ব্যবহারকারীর নাম লিখুন",
|
||||||
|
"ToastNoUpdatesNecessary": "কোন আপডেটের প্রয়োজন নেই",
|
||||||
|
"ToastNotificationCreateFailed": "বিজ্ঞপ্তি তৈরি করতে ব্যর্থ",
|
||||||
|
"ToastNotificationDeleteFailed": "বিজ্ঞপ্তি মুছে ফেলতে ব্যর্থ",
|
||||||
|
"ToastNotificationFailedMaximum": "সর্বাধিক ব্যর্থ প্রচেষ্টা >= 0 হতে হবে",
|
||||||
|
"ToastNotificationQueueMaximum": "সর্বাধিক বিজ্ঞপ্তি সারি >= 0 হতে হবে",
|
||||||
|
"ToastNotificationSettingsUpdateSuccess": "বিজ্ঞপ্তি সেটিংস আপডেট করা হয়েছে",
|
||||||
|
"ToastNotificationTestTriggerFailed": "পরীক্ষামূলক বিজ্ঞপ্তি ট্রিগার করতে ব্যর্থ হয়েছে",
|
||||||
|
"ToastNotificationTestTriggerSuccess": "পরীক্ষামুলক বিজ্ঞপ্তি ট্রিগার হয়েছে",
|
||||||
|
"ToastNotificationUpdateSuccess": "বিজ্ঞপ্তি আপডেট হয়েছে",
|
||||||
"ToastPlaylistCreateFailed": "প্লেলিস্ট তৈরি করতে ব্যর্থ",
|
"ToastPlaylistCreateFailed": "প্লেলিস্ট তৈরি করতে ব্যর্থ",
|
||||||
"ToastPlaylistCreateSuccess": "প্লেলিস্ট তৈরি করা হয়েছে",
|
"ToastPlaylistCreateSuccess": "প্লেলিস্ট তৈরি করা হয়েছে",
|
||||||
"ToastPlaylistRemoveSuccess": "প্লেলিস্ট সরানো হয়েছে",
|
"ToastPlaylistRemoveSuccess": "প্লেলিস্ট সরানো হয়েছে",
|
||||||
"ToastPlaylistUpdateFailed": "প্লেলিস্ট আপডেট করতে ব্যর্থ",
|
|
||||||
"ToastPlaylistUpdateSuccess": "প্লেলিস্ট আপডেট করা হয়েছে",
|
"ToastPlaylistUpdateSuccess": "প্লেলিস্ট আপডেট করা হয়েছে",
|
||||||
"ToastPodcastCreateFailed": "পডকাস্ট তৈরি করতে ব্যর্থ",
|
"ToastPodcastCreateFailed": "পডকাস্ট তৈরি করতে ব্যর্থ",
|
||||||
"ToastPodcastCreateSuccess": "পডকাস্ট সফলভাবে তৈরি করা হয়েছে",
|
"ToastPodcastCreateSuccess": "পডকাস্ট সফলভাবে তৈরি করা হয়েছে",
|
||||||
|
"ToastPodcastGetFeedFailed": "পডকাস্ট ফিড পেতে ব্যর্থ হয়েছে",
|
||||||
|
"ToastPodcastNoEpisodesInFeed": "আরএসএস ফিডে কোনো পর্ব পাওয়া যায়নি",
|
||||||
|
"ToastPodcastNoRssFeed": "পডকাস্টের কোন আরএসএস ফিড নেই",
|
||||||
|
"ToastProviderCreatedFailed": "প্রদানকারী যোগ করতে ব্যর্থ হয়েছে",
|
||||||
|
"ToastProviderCreatedSuccess": "নতুন প্রদানকারী যোগ করা হয়েছে",
|
||||||
|
"ToastProviderNameAndUrlRequired": "নাম এবং ইউআরএল আবশ্যক",
|
||||||
|
"ToastProviderRemoveSuccess": "প্রদানকারী সরানো হয়েছে",
|
||||||
"ToastRSSFeedCloseFailed": "RSS ফিড বন্ধ করতে ব্যর্থ",
|
"ToastRSSFeedCloseFailed": "RSS ফিড বন্ধ করতে ব্যর্থ",
|
||||||
"ToastRSSFeedCloseSuccess": "RSS ফিড বন্ধ",
|
"ToastRSSFeedCloseSuccess": "RSS ফিড বন্ধ",
|
||||||
|
"ToastRemoveFailed": "মুছে ফেলতে ব্যর্থ হয়েছে",
|
||||||
"ToastRemoveItemFromCollectionFailed": "সংগ্রহ থেকে আইটেম সরাতে ব্যর্থ",
|
"ToastRemoveItemFromCollectionFailed": "সংগ্রহ থেকে আইটেম সরাতে ব্যর্থ",
|
||||||
"ToastRemoveItemFromCollectionSuccess": "সংগ্রহ থেকে আইটেম সরানো হয়েছে",
|
"ToastRemoveItemFromCollectionSuccess": "সংগ্রহ থেকে আইটেম সরানো হয়েছে",
|
||||||
|
"ToastRemoveItemsWithIssuesFailed": "সমস্যাযুক্ত লাইব্রেরি আইটেমগুলি সরাতে ব্যর্থ হয়েছে",
|
||||||
|
"ToastRemoveItemsWithIssuesSuccess": "সমস্যাযুক্ত লাইব্রেরি আইটেম সরানো হয়েছে",
|
||||||
|
"ToastRenameFailed": "পুনঃনামকরণ ব্যর্থ হয়েছে",
|
||||||
|
"ToastRescanFailed": "{0} এর জন্য পুনরায় স্ক্যান করা ব্যর্থ হয়েছে",
|
||||||
|
"ToastRescanRemoved": "পুনরায় স্ক্যান সম্পূর্ণ,আইটেম সরানো হয়েছে",
|
||||||
|
"ToastRescanUpToDate": "পুনরায় স্ক্যান সম্পূর্ণ, আইটেম সাম্প্রতিক ছিল",
|
||||||
|
"ToastRescanUpdated": "পুনরায় স্ক্যান সম্পূর্ণ, আইটেম আপডেট করা হয়েছে",
|
||||||
|
"ToastScanFailed": "লাইব্রেরি আইটেম স্ক্যান করতে ব্যর্থ হয়েছে",
|
||||||
|
"ToastSelectAtLeastOneUser": "অন্তত একজন ব্যবহারকারী নির্বাচন করুন",
|
||||||
"ToastSendEbookToDeviceFailed": "ডিভাইসে ইবুক পাঠাতে ব্যর্থ",
|
"ToastSendEbookToDeviceFailed": "ডিভাইসে ইবুক পাঠাতে ব্যর্থ",
|
||||||
"ToastSendEbookToDeviceSuccess": "ইবুক \"{0}\" ডিভাইসে পাঠানো হয়েছে",
|
"ToastSendEbookToDeviceSuccess": "ইবুক \"{0}\" ডিভাইসে পাঠানো হয়েছে",
|
||||||
"ToastSeriesUpdateFailed": "সিরিজ আপডেট ব্যর্থ হয়েছে",
|
"ToastSeriesUpdateFailed": "সিরিজ আপডেট ব্যর্থ হয়েছে",
|
||||||
"ToastSeriesUpdateSuccess": "সিরিজ আপডেট সাফল্য",
|
"ToastSeriesUpdateSuccess": "সিরিজ আপডেট সাফল্য",
|
||||||
|
"ToastServerSettingsUpdateSuccess": "সার্ভার সেটিংস আপডেট করা হয়েছে",
|
||||||
|
"ToastSessionCloseFailed": "অধিবেশন বন্ধ করতে ব্যর্থ হয়েছে",
|
||||||
"ToastSessionDeleteFailed": "সেশন মুছে ফেলতে ব্যর্থ",
|
"ToastSessionDeleteFailed": "সেশন মুছে ফেলতে ব্যর্থ",
|
||||||
"ToastSessionDeleteSuccess": "সেশন মুছে ফেলা হয়েছে",
|
"ToastSessionDeleteSuccess": "সেশন মুছে ফেলা হয়েছে",
|
||||||
|
"ToastSlugMustChange": "স্লাগে অবৈধ অক্ষর রয়েছে",
|
||||||
|
"ToastSlugRequired": "স্লাগ আবশ্যক",
|
||||||
"ToastSocketConnected": "সকেট সংযুক্ত",
|
"ToastSocketConnected": "সকেট সংযুক্ত",
|
||||||
"ToastSocketDisconnected": "সকেট সংযোগ বিচ্ছিন্ন",
|
"ToastSocketDisconnected": "সকেট সংযোগ বিচ্ছিন্ন",
|
||||||
"ToastSocketFailedToConnect": "সকেট সংযোগ করতে ব্যর্থ হয়েছে",
|
"ToastSocketFailedToConnect": "সকেট সংযোগ করতে ব্যর্থ হয়েছে",
|
||||||
|
"ToastSortingPrefixesEmptyError": "কমপক্ষে ১ টি সাজানোর উপসর্গ থাকতে হবে",
|
||||||
|
"ToastSortingPrefixesUpdateSuccess": "বাছাই করা উপসর্গ আপডেট করা হয়েছে ({0}টি আইটেম)",
|
||||||
|
"ToastTitleRequired": "শিরোনাম আবশ্যক",
|
||||||
|
"ToastUnknownError": "অজানা ত্রুটি",
|
||||||
|
"ToastUnlinkOpenIdFailed": "OpenID থেকে ব্যবহারকারীকে আনলিঙ্ক করতে ব্যর্থ হয়েছে",
|
||||||
|
"ToastUnlinkOpenIdSuccess": "OpenID থেকে ব্যবহারকারীকে লিঙ্কমুক্ত করা হয়েছে",
|
||||||
"ToastUserDeleteFailed": "ব্যবহারকারী মুছতে ব্যর্থ",
|
"ToastUserDeleteFailed": "ব্যবহারকারী মুছতে ব্যর্থ",
|
||||||
"ToastUserDeleteSuccess": "ব্যবহারকারী মুছে ফেলা হয়েছে"
|
"ToastUserDeleteSuccess": "ব্যবহারকারী মুছে ফেলা হয়েছে",
|
||||||
|
"ToastUserPasswordChangeSuccess": "পাসওয়ার্ড সফলভাবে পরিবর্তন করা হয়েছে",
|
||||||
|
"ToastUserPasswordMismatch": "পাসওয়ার্ড মিলছে না",
|
||||||
|
"ToastUserPasswordMustChange": "নতুন পাসওয়ার্ড পুরানো পাসওয়ার্ডের সাথে মিলতে পারবে না",
|
||||||
|
"ToastUserRootRequireName": "একটি রুট ব্যবহারকারীর নাম লিখতে হবে"
|
||||||
}
|
}
|
||||||
|
|||||||
+102
-16
@@ -28,6 +28,7 @@
|
|||||||
"ButtonEdit": "Upravit",
|
"ButtonEdit": "Upravit",
|
||||||
"ButtonEditChapters": "Upravit kapitoly",
|
"ButtonEditChapters": "Upravit kapitoly",
|
||||||
"ButtonEditPodcast": "Upravit podcast",
|
"ButtonEditPodcast": "Upravit podcast",
|
||||||
|
"ButtonEnable": "Povolit",
|
||||||
"ButtonForceReScan": "Vynutit opětovné prohledání",
|
"ButtonForceReScan": "Vynutit opětovné prohledání",
|
||||||
"ButtonFullPath": "Úplná cesta",
|
"ButtonFullPath": "Úplná cesta",
|
||||||
"ButtonHide": "Skrýt",
|
"ButtonHide": "Skrýt",
|
||||||
@@ -44,10 +45,15 @@
|
|||||||
"ButtonMatchAllAuthors": "Spárovat všechny autory",
|
"ButtonMatchAllAuthors": "Spárovat všechny autory",
|
||||||
"ButtonMatchBooks": "Spárovat Knihy",
|
"ButtonMatchBooks": "Spárovat Knihy",
|
||||||
"ButtonNevermind": "Nevadí",
|
"ButtonNevermind": "Nevadí",
|
||||||
|
"ButtonNext": "Další",
|
||||||
"ButtonNextChapter": "Další Kapitola",
|
"ButtonNextChapter": "Další Kapitola",
|
||||||
|
"ButtonNextItemInQueue": "Žádná další položka ve frontě",
|
||||||
|
"ButtonOk": "Ok",
|
||||||
"ButtonOpenFeed": "Otevřít kanál",
|
"ButtonOpenFeed": "Otevřít kanál",
|
||||||
"ButtonOpenManager": "Otevřít správce",
|
"ButtonOpenManager": "Otevřít správce",
|
||||||
|
"ButtonPause": "Pozastavit",
|
||||||
"ButtonPlay": "Přehrát",
|
"ButtonPlay": "Přehrát",
|
||||||
|
"ButtonPlayAll": "Přehrát vše",
|
||||||
"ButtonPlaying": "Hraje",
|
"ButtonPlaying": "Hraje",
|
||||||
"ButtonPlaylists": "Seznamy skladeb",
|
"ButtonPlaylists": "Seznamy skladeb",
|
||||||
"ButtonPrevious": "Předchozí",
|
"ButtonPrevious": "Předchozí",
|
||||||
@@ -88,6 +94,8 @@
|
|||||||
"ButtonStartMetadataEmbed": "Spustit vkládání metadat",
|
"ButtonStartMetadataEmbed": "Spustit vkládání metadat",
|
||||||
"ButtonStats": "Statistiky",
|
"ButtonStats": "Statistiky",
|
||||||
"ButtonSubmit": "Odeslat",
|
"ButtonSubmit": "Odeslat",
|
||||||
|
"ButtonTest": "Test",
|
||||||
|
"ButtonUnlinkOpenId": "Odpojit OpenID",
|
||||||
"ButtonUpload": "Nahrát",
|
"ButtonUpload": "Nahrát",
|
||||||
"ButtonUploadBackup": "Nahrát zálohu",
|
"ButtonUploadBackup": "Nahrát zálohu",
|
||||||
"ButtonUploadCover": "Nahrát obálku",
|
"ButtonUploadCover": "Nahrát obálku",
|
||||||
@@ -100,10 +108,12 @@
|
|||||||
"ErrorUploadFetchMetadataNoResults": "Nepodařilo se načíst metadata - zkuste aktualizovat název a/nebo autora",
|
"ErrorUploadFetchMetadataNoResults": "Nepodařilo se načíst metadata - zkuste aktualizovat název a/nebo autora",
|
||||||
"ErrorUploadLacksTitle": "Musí mít titul",
|
"ErrorUploadLacksTitle": "Musí mít titul",
|
||||||
"HeaderAccount": "Účet",
|
"HeaderAccount": "Účet",
|
||||||
|
"HeaderAddCustomMetadataProvider": "Přidat vlastního poskytovatele metadat",
|
||||||
"HeaderAdvanced": "Pokročilé",
|
"HeaderAdvanced": "Pokročilé",
|
||||||
"HeaderAppriseNotificationSettings": "Nastavení oznámení Apprise",
|
"HeaderAppriseNotificationSettings": "Nastavení oznámení Apprise",
|
||||||
"HeaderAudioTracks": "Zvukové stopy",
|
"HeaderAudioTracks": "Zvukové stopy",
|
||||||
"HeaderAudiobookTools": "Nástroje pro správu souborů audioknih",
|
"HeaderAudiobookTools": "Nástroje pro správu souborů audioknih",
|
||||||
|
"HeaderAuthentication": "Autentizace",
|
||||||
"HeaderBackups": "Zálohy",
|
"HeaderBackups": "Zálohy",
|
||||||
"HeaderChangePassword": "Změnit heslo",
|
"HeaderChangePassword": "Změnit heslo",
|
||||||
"HeaderChapters": "Kapitoly",
|
"HeaderChapters": "Kapitoly",
|
||||||
@@ -144,10 +154,13 @@
|
|||||||
"HeaderMetadataToEmbed": "Metadata k vložení",
|
"HeaderMetadataToEmbed": "Metadata k vložení",
|
||||||
"HeaderNewAccount": "Nový účet",
|
"HeaderNewAccount": "Nový účet",
|
||||||
"HeaderNewLibrary": "Nová knihovna",
|
"HeaderNewLibrary": "Nová knihovna",
|
||||||
|
"HeaderNotificationCreate": "Vytvořit notifikaci",
|
||||||
|
"HeaderNotificationUpdate": "Aktualizovat notifikaci",
|
||||||
"HeaderNotifications": "Oznámení",
|
"HeaderNotifications": "Oznámení",
|
||||||
"HeaderOpenIDConnectAuthentication": "Ověřování pomocí OpenID Connect",
|
"HeaderOpenIDConnectAuthentication": "Ověřování pomocí OpenID Connect",
|
||||||
"HeaderOpenRSSFeed": "Otevřít RSS kanál",
|
"HeaderOpenRSSFeed": "Otevřít RSS kanál",
|
||||||
"HeaderOtherFiles": "Ostatní soubory",
|
"HeaderOtherFiles": "Ostatní soubory",
|
||||||
|
"HeaderPasswordAuthentication": "Autentizace heslem",
|
||||||
"HeaderPermissions": "Oprávnění",
|
"HeaderPermissions": "Oprávnění",
|
||||||
"HeaderPlayerQueue": "Fronta přehrávače",
|
"HeaderPlayerQueue": "Fronta přehrávače",
|
||||||
"HeaderPlayerSettings": "Nastavení přehrávače",
|
"HeaderPlayerSettings": "Nastavení přehrávače",
|
||||||
@@ -200,6 +213,7 @@
|
|||||||
"LabelAddToPlaylist": "Přidat do seznamu přehrávání",
|
"LabelAddToPlaylist": "Přidat do seznamu přehrávání",
|
||||||
"LabelAddToPlaylistBatch": "Přidat {0} položky do seznamu přehrávání",
|
"LabelAddToPlaylistBatch": "Přidat {0} položky do seznamu přehrávání",
|
||||||
"LabelAddedAt": "Přidáno v",
|
"LabelAddedAt": "Přidáno v",
|
||||||
|
"LabelAddedDate": "Přidáno {0}",
|
||||||
"LabelAdminUsersOnly": "Pouze administrátoři",
|
"LabelAdminUsersOnly": "Pouze administrátoři",
|
||||||
"LabelAll": "Vše",
|
"LabelAll": "Vše",
|
||||||
"LabelAllUsers": "Všichni uživatelé",
|
"LabelAllUsers": "Všichni uživatelé",
|
||||||
@@ -229,6 +243,7 @@
|
|||||||
"LabelBitrate": "Datový tok",
|
"LabelBitrate": "Datový tok",
|
||||||
"LabelBooks": "Knihy",
|
"LabelBooks": "Knihy",
|
||||||
"LabelButtonText": "Text tlačítka",
|
"LabelButtonText": "Text tlačítka",
|
||||||
|
"LabelByAuthor": "od {0}",
|
||||||
"LabelChangePassword": "Změnit heslo",
|
"LabelChangePassword": "Změnit heslo",
|
||||||
"LabelChannels": "Kanály",
|
"LabelChannels": "Kanály",
|
||||||
"LabelChapterTitle": "Název kapitoly",
|
"LabelChapterTitle": "Název kapitoly",
|
||||||
@@ -238,6 +253,7 @@
|
|||||||
"LabelClosePlayer": "Zavřít přehrávač",
|
"LabelClosePlayer": "Zavřít přehrávač",
|
||||||
"LabelCodec": "Kodek",
|
"LabelCodec": "Kodek",
|
||||||
"LabelCollapseSeries": "Sbalit sérii",
|
"LabelCollapseSeries": "Sbalit sérii",
|
||||||
|
"LabelCollapseSubSeries": "Sbalit podsérie",
|
||||||
"LabelCollection": "Kolekce",
|
"LabelCollection": "Kolekce",
|
||||||
"LabelCollections": "Kolekce",
|
"LabelCollections": "Kolekce",
|
||||||
"LabelComplete": "Dokončeno",
|
"LabelComplete": "Dokončeno",
|
||||||
@@ -288,16 +304,21 @@
|
|||||||
"LabelEpisode": "Epizoda",
|
"LabelEpisode": "Epizoda",
|
||||||
"LabelEpisodeTitle": "Název epizody",
|
"LabelEpisodeTitle": "Název epizody",
|
||||||
"LabelEpisodeType": "Typ epizody",
|
"LabelEpisodeType": "Typ epizody",
|
||||||
|
"LabelEpisodes": "Epizody",
|
||||||
"LabelExample": "Příklad",
|
"LabelExample": "Příklad",
|
||||||
"LabelExpandSeries": "Rozbalit série",
|
"LabelExpandSeries": "Rozbalit série",
|
||||||
|
"LabelExpandSubSeries": "Rozbalit podsérie",
|
||||||
"LabelExplicit": "Explicitní",
|
"LabelExplicit": "Explicitní",
|
||||||
"LabelExplicitChecked": "Explicitní (zaškrtnuto)",
|
"LabelExplicitChecked": "Explicitní (zaškrtnuto)",
|
||||||
"LabelExplicitUnchecked": "Není explicitní (nezaškrtnuto)",
|
"LabelExplicitUnchecked": "Není explicitní (nezaškrtnuto)",
|
||||||
|
"LabelExportOPML": "Export OPML",
|
||||||
"LabelFeedURL": "URL zdroje",
|
"LabelFeedURL": "URL zdroje",
|
||||||
"LabelFetchingMetadata": "Získávání metadat",
|
"LabelFetchingMetadata": "Získávání metadat",
|
||||||
"LabelFile": "Soubor",
|
"LabelFile": "Soubor",
|
||||||
"LabelFileBirthtime": "Čas vzniku souboru",
|
"LabelFileBirthtime": "Čas vzniku souboru",
|
||||||
|
"LabelFileBornDate": "Vytvořeno {0}",
|
||||||
"LabelFileModified": "Soubor změněn",
|
"LabelFileModified": "Soubor změněn",
|
||||||
|
"LabelFileModifiedDate": "Změněno {0}",
|
||||||
"LabelFilename": "Název souboru",
|
"LabelFilename": "Název souboru",
|
||||||
"LabelFilterByUser": "Filtrovat podle uživatele",
|
"LabelFilterByUser": "Filtrovat podle uživatele",
|
||||||
"LabelFindEpisodes": "Najít epizody",
|
"LabelFindEpisodes": "Najít epizody",
|
||||||
@@ -307,6 +328,7 @@
|
|||||||
"LabelFontBold": "Tučně",
|
"LabelFontBold": "Tučně",
|
||||||
"LabelFontBoldness": "Výraznost písma",
|
"LabelFontBoldness": "Výraznost písma",
|
||||||
"LabelFontFamily": "Rodina písem",
|
"LabelFontFamily": "Rodina písem",
|
||||||
|
"LabelFontItalic": "Kurzíva",
|
||||||
"LabelFontScale": "Měřítko písma",
|
"LabelFontScale": "Měřítko písma",
|
||||||
"LabelFontStrikethrough": "Přeškrtnutí",
|
"LabelFontStrikethrough": "Přeškrtnutí",
|
||||||
"LabelFormat": "Formát",
|
"LabelFormat": "Formát",
|
||||||
@@ -325,6 +347,7 @@
|
|||||||
"LabelInProgress": "Probíhá",
|
"LabelInProgress": "Probíhá",
|
||||||
"LabelIncludeInTracklist": "Zahrnout do seznamu stop",
|
"LabelIncludeInTracklist": "Zahrnout do seznamu stop",
|
||||||
"LabelIncomplete": "Neúplné",
|
"LabelIncomplete": "Neúplné",
|
||||||
|
"LabelInterval": "Interval",
|
||||||
"LabelIntervalCustomDailyWeekly": "Vlastní denně/týdně",
|
"LabelIntervalCustomDailyWeekly": "Vlastní denně/týdně",
|
||||||
"LabelIntervalEvery12Hours": "Každých 12 hodin",
|
"LabelIntervalEvery12Hours": "Každých 12 hodin",
|
||||||
"LabelIntervalEvery15Minutes": "Každých 15 minut",
|
"LabelIntervalEvery15Minutes": "Každých 15 minut",
|
||||||
@@ -421,17 +444,22 @@
|
|||||||
"LabelPersonalYearReview": "Váš přehled roku ({0})",
|
"LabelPersonalYearReview": "Váš přehled roku ({0})",
|
||||||
"LabelPhotoPathURL": "Cesta k fotografii/URL",
|
"LabelPhotoPathURL": "Cesta k fotografii/URL",
|
||||||
"LabelPlayMethod": "Metoda přehrávání",
|
"LabelPlayMethod": "Metoda přehrávání",
|
||||||
|
"LabelPlayerChapterNumberMarker": "{0} z {1}",
|
||||||
"LabelPlaylists": "Seznamy skladeb",
|
"LabelPlaylists": "Seznamy skladeb",
|
||||||
|
"LabelPodcast": "Podcast",
|
||||||
"LabelPodcastSearchRegion": "Oblast vyhledávání podcastu",
|
"LabelPodcastSearchRegion": "Oblast vyhledávání podcastu",
|
||||||
"LabelPodcastType": "Typ podcastu",
|
"LabelPodcastType": "Typ podcastu",
|
||||||
"LabelPodcasts": "Podcasty",
|
"LabelPodcasts": "Podcasty",
|
||||||
|
"LabelPort": "Port",
|
||||||
"LabelPrefixesToIgnore": "Předpony, které se mají ignorovat (nerozlišují se malá a velká písmena)",
|
"LabelPrefixesToIgnore": "Předpony, které se mají ignorovat (nerozlišují se malá a velká písmena)",
|
||||||
"LabelPreventIndexing": "Zabránit indexování vašeho kanálu v adresářích podcastů iTunes a Google",
|
"LabelPreventIndexing": "Zabránit indexování vašeho kanálu v adresářích podcastů iTunes a Google",
|
||||||
"LabelPrimaryEbook": "Hlavní e-kniha",
|
"LabelPrimaryEbook": "Hlavní e-kniha",
|
||||||
"LabelProgress": "Průběh",
|
"LabelProgress": "Průběh",
|
||||||
"LabelProvider": "Poskytovatel",
|
"LabelProvider": "Poskytovatel",
|
||||||
|
"LabelProviderAuthorizationValue": "Hodnota autorizačního headeru",
|
||||||
"LabelPubDate": "Datum vydání",
|
"LabelPubDate": "Datum vydání",
|
||||||
"LabelPublishYear": "Rok vydání",
|
"LabelPublishYear": "Rok vydání",
|
||||||
|
"LabelPublishedDate": "Vydáno {0}",
|
||||||
"LabelPublisher": "Vydavatel",
|
"LabelPublisher": "Vydavatel",
|
||||||
"LabelPublishers": "Vydavatelé",
|
"LabelPublishers": "Vydavatelé",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "Vlastní e-mail vlastníka",
|
"LabelRSSFeedCustomOwnerEmail": "Vlastní e-mail vlastníka",
|
||||||
@@ -441,6 +469,7 @@
|
|||||||
"LabelRSSFeedSlug": "RSS kanál Slug",
|
"LabelRSSFeedSlug": "RSS kanál Slug",
|
||||||
"LabelRSSFeedURL": "URL RSS kanálu",
|
"LabelRSSFeedURL": "URL RSS kanálu",
|
||||||
"LabelRandomly": "Náhodně",
|
"LabelRandomly": "Náhodně",
|
||||||
|
"LabelReAddSeriesToContinueListening": "Znovu přidat sérii k pokračování poslechu",
|
||||||
"LabelRead": "Číst",
|
"LabelRead": "Číst",
|
||||||
"LabelReadAgain": "Číst znovu",
|
"LabelReadAgain": "Číst znovu",
|
||||||
"LabelReadEbookWithoutProgress": "Číst e-knihu bez zachování průběhu",
|
"LabelReadEbookWithoutProgress": "Číst e-knihu bez zachování průběhu",
|
||||||
@@ -448,6 +477,7 @@
|
|||||||
"LabelRecentlyAdded": "Nedávno přidané",
|
"LabelRecentlyAdded": "Nedávno přidané",
|
||||||
"LabelRecommended": "Doporučeno",
|
"LabelRecommended": "Doporučeno",
|
||||||
"LabelRedo": "Přepracovat",
|
"LabelRedo": "Přepracovat",
|
||||||
|
"LabelRegion": "Region",
|
||||||
"LabelReleaseDate": "Datum vydání",
|
"LabelReleaseDate": "Datum vydání",
|
||||||
"LabelRemoveCover": "Odstranit obálku",
|
"LabelRemoveCover": "Odstranit obálku",
|
||||||
"LabelRowsPerPage": "Řádky na stránku",
|
"LabelRowsPerPage": "Řádky na stránku",
|
||||||
@@ -539,6 +569,7 @@
|
|||||||
"LabelTagsNotAccessibleToUser": "Značky nepřístupné uživateli",
|
"LabelTagsNotAccessibleToUser": "Značky nepřístupné uživateli",
|
||||||
"LabelTasks": "Spuštěné Úlohy",
|
"LabelTasks": "Spuštěné Úlohy",
|
||||||
"LabelTextEditorBulletedList": "Seznam s odrážkami",
|
"LabelTextEditorBulletedList": "Seznam s odrážkami",
|
||||||
|
"LabelTextEditorLink": "Odkaz",
|
||||||
"LabelTextEditorNumberedList": "Seznam s čísly",
|
"LabelTextEditorNumberedList": "Seznam s čísly",
|
||||||
"LabelTextEditorUnlink": "Zrušit odkaz",
|
"LabelTextEditorUnlink": "Zrušit odkaz",
|
||||||
"LabelTheme": "Téma",
|
"LabelTheme": "Téma",
|
||||||
@@ -572,6 +603,7 @@
|
|||||||
"LabelUnabridged": "Nezkráceno",
|
"LabelUnabridged": "Nezkráceno",
|
||||||
"LabelUndo": "Zpět",
|
"LabelUndo": "Zpět",
|
||||||
"LabelUnknown": "Neznámý",
|
"LabelUnknown": "Neznámý",
|
||||||
|
"LabelUnknownPublishDate": "Neznámé datum vydání",
|
||||||
"LabelUpdateCover": "Aktualizovat obálku",
|
"LabelUpdateCover": "Aktualizovat obálku",
|
||||||
"LabelUpdateCoverHelp": "Povolit přepsání existujících obálek pro vybrané knihy, pokud je nalezena shoda",
|
"LabelUpdateCoverHelp": "Povolit přepsání existujících obálek pro vybrané knihy, pokud je nalezena shoda",
|
||||||
"LabelUpdateDetails": "Aktualizovat podrobnosti",
|
"LabelUpdateDetails": "Aktualizovat podrobnosti",
|
||||||
@@ -620,14 +652,19 @@
|
|||||||
"MessageCheckingCron": "Kontrola cronu...",
|
"MessageCheckingCron": "Kontrola cronu...",
|
||||||
"MessageConfirmCloseFeed": "Opravdu chcete zavřít tento kanál?",
|
"MessageConfirmCloseFeed": "Opravdu chcete zavřít tento kanál?",
|
||||||
"MessageConfirmDeleteBackup": "Opravdu chcete smazat zálohu pro {0}?",
|
"MessageConfirmDeleteBackup": "Opravdu chcete smazat zálohu pro {0}?",
|
||||||
|
"MessageConfirmDeleteDevice": "Opravdu chcete vymazat zařízení e-reader \"{0}\"?",
|
||||||
"MessageConfirmDeleteFile": "Tento krok smaže soubor ze souborového systému. Jsi si jisti?",
|
"MessageConfirmDeleteFile": "Tento krok smaže soubor ze souborového systému. Jsi si jisti?",
|
||||||
"MessageConfirmDeleteLibrary": "Opravdu chcete trvale smazat knihovnu \"{0}\"?",
|
"MessageConfirmDeleteLibrary": "Opravdu chcete trvale smazat knihovnu \"{0}\"?",
|
||||||
"MessageConfirmDeleteLibraryItem": "Tento krok odstraní položku knihovny z databáze a vašeho souborového systému. Jste si jisti?",
|
"MessageConfirmDeleteLibraryItem": "Tento krok odstraní položku knihovny z databáze a vašeho souborového systému. Jste si jisti?",
|
||||||
"MessageConfirmDeleteLibraryItems": "Tímto smažete {0} položkek knihovny z databáze a vašeho souborového systému. Jsi si jisti?",
|
"MessageConfirmDeleteLibraryItems": "Tímto smažete {0} položkek knihovny z databáze a vašeho souborového systému. Jsi si jisti?",
|
||||||
|
"MessageConfirmDeleteMetadataProvider": "Opravdu chcete vymazat vlastního poskytovatele metadat \"{0}\"?",
|
||||||
|
"MessageConfirmDeleteNotification": "Opravdu chcete vymazat tuto notifikaci?",
|
||||||
"MessageConfirmDeleteSession": "Opravdu chcete smazat tuto relaci?",
|
"MessageConfirmDeleteSession": "Opravdu chcete smazat tuto relaci?",
|
||||||
"MessageConfirmForceReScan": "Opravdu chcete vynutit opětovné prohledání?",
|
"MessageConfirmForceReScan": "Opravdu chcete vynutit opětovné prohledání?",
|
||||||
"MessageConfirmMarkAllEpisodesFinished": "Opravdu chcete označit všechny epizody jako dokončené?",
|
"MessageConfirmMarkAllEpisodesFinished": "Opravdu chcete označit všechny epizody jako dokončené?",
|
||||||
"MessageConfirmMarkAllEpisodesNotFinished": "Opravdu chcete označit všechny epizody jako nedokončené?",
|
"MessageConfirmMarkAllEpisodesNotFinished": "Opravdu chcete označit všechny epizody jako nedokončené?",
|
||||||
|
"MessageConfirmMarkItemFinished": "Opravdu chcete označit \"{0}\" jako dokončené?",
|
||||||
|
"MessageConfirmMarkItemNotFinished": "Opravdu chcete označit \"{0}\" jako nedokončené?",
|
||||||
"MessageConfirmMarkSeriesFinished": "Opravdu chcete označit všechny knihy z této série jako dokončené?",
|
"MessageConfirmMarkSeriesFinished": "Opravdu chcete označit všechny knihy z této série jako dokončené?",
|
||||||
"MessageConfirmMarkSeriesNotFinished": "Opravdu chcete označit všechny knihy z této série jako nedokončené?",
|
"MessageConfirmMarkSeriesNotFinished": "Opravdu chcete označit všechny knihy z této série jako nedokončené?",
|
||||||
"MessageConfirmPurgeCache": "Vyčistit mezipaměť odstraní celý adresář na adrese <code>/metadata/cache</code>. <br /><br />Určitě chcete odstranit adresář mezipaměti?",
|
"MessageConfirmPurgeCache": "Vyčistit mezipaměť odstraní celý adresář na adrese <code>/metadata/cache</code>. <br /><br />Určitě chcete odstranit adresář mezipaměti?",
|
||||||
@@ -648,7 +685,9 @@
|
|||||||
"MessageConfirmRenameTag": "Opravdu chcete přejmenovat tag \"{0}\" na \"{1}\" pro všechny položky?",
|
"MessageConfirmRenameTag": "Opravdu chcete přejmenovat tag \"{0}\" na \"{1}\" pro všechny položky?",
|
||||||
"MessageConfirmRenameTagMergeNote": "Poznámka: Tato značka již existuje, takže budou sloučeny.",
|
"MessageConfirmRenameTagMergeNote": "Poznámka: Tato značka již existuje, takže budou sloučeny.",
|
||||||
"MessageConfirmRenameTagWarning": "Varování! Podobná značka s jinými velkými a malými písmeny již existuje \"{0}\".",
|
"MessageConfirmRenameTagWarning": "Varování! Podobná značka s jinými velkými a malými písmeny již existuje \"{0}\".",
|
||||||
|
"MessageConfirmResetProgress": "Opravdu chcete zahodit svůj pokrok?",
|
||||||
"MessageConfirmSendEbookToDevice": "Opravdu chcete odeslat e-knihu {0} {1}\" do zařízení \"{2}\"?",
|
"MessageConfirmSendEbookToDevice": "Opravdu chcete odeslat e-knihu {0} {1}\" do zařízení \"{2}\"?",
|
||||||
|
"MessageConfirmUnlinkOpenId": "Opravdu chcete odpojit tohoto uživatele z OpenID?",
|
||||||
"MessageDownloadingEpisode": "Stahuji epizodu",
|
"MessageDownloadingEpisode": "Stahuji epizodu",
|
||||||
"MessageDragFilesIntoTrackOrder": "Přetáhněte soubory do správného pořadí stop",
|
"MessageDragFilesIntoTrackOrder": "Přetáhněte soubory do správného pořadí stop",
|
||||||
"MessageEmbedFailed": "Vložení selhalo!",
|
"MessageEmbedFailed": "Vložení selhalo!",
|
||||||
@@ -656,7 +695,7 @@
|
|||||||
"MessageEpisodesQueuedForDownload": "{0} Epizody zařazené do fronty ke stažení",
|
"MessageEpisodesQueuedForDownload": "{0} Epizody zařazené do fronty ke stažení",
|
||||||
"MessageEreaderDevices": "Aby bylo zajištěno doručení elektronických knih, může být nutné přidat výše uvedenou e-mailovou adresu jako platného odesílatele pro každé zařízení uvedené níže.",
|
"MessageEreaderDevices": "Aby bylo zajištěno doručení elektronických knih, může být nutné přidat výše uvedenou e-mailovou adresu jako platného odesílatele pro každé zařízení uvedené níže.",
|
||||||
"MessageFeedURLWillBe": "URL zdroje bude {0}",
|
"MessageFeedURLWillBe": "URL zdroje bude {0}",
|
||||||
"MessageFetching": "Stahování...",
|
"MessageFetching": "Načítání...",
|
||||||
"MessageForceReScanDescription": "znovu prohledá všechny soubory jako při novém skenování. ID3 tagy zvukových souborů OPF soubory a textové soubory budou skenovány jako nové.",
|
"MessageForceReScanDescription": "znovu prohledá všechny soubory jako při novém skenování. ID3 tagy zvukových souborů OPF soubory a textové soubory budou skenovány jako nové.",
|
||||||
"MessageImportantNotice": "Důležité upozornění!",
|
"MessageImportantNotice": "Důležité upozornění!",
|
||||||
"MessageInsertChapterBelow": "Vložit kapitolu níže",
|
"MessageInsertChapterBelow": "Vložit kapitolu níže",
|
||||||
@@ -683,6 +722,7 @@
|
|||||||
"MessageNoCollections": "Žádné kolekce",
|
"MessageNoCollections": "Žádné kolekce",
|
||||||
"MessageNoCoversFound": "Nebyly nalezeny žádné obálky",
|
"MessageNoCoversFound": "Nebyly nalezeny žádné obálky",
|
||||||
"MessageNoDescription": "Bez popisu",
|
"MessageNoDescription": "Bez popisu",
|
||||||
|
"MessageNoDevices": "Žádná zařízení",
|
||||||
"MessageNoDownloadsInProgress": "Momentálně neprobíhá žádné stahování",
|
"MessageNoDownloadsInProgress": "Momentálně neprobíhá žádné stahování",
|
||||||
"MessageNoDownloadsQueued": "Žádné stahování ve frontě",
|
"MessageNoDownloadsQueued": "Žádné stahování ve frontě",
|
||||||
"MessageNoEpisodeMatchesFound": "Nebyly nalezeny žádné odpovídající epizody",
|
"MessageNoEpisodeMatchesFound": "Nebyly nalezeny žádné odpovídající epizody",
|
||||||
@@ -710,6 +750,7 @@
|
|||||||
"MessagePauseChapter": "Pozastavit přehrávání kapitoly",
|
"MessagePauseChapter": "Pozastavit přehrávání kapitoly",
|
||||||
"MessagePlayChapter": "Poslechnout si začátek kapitoly",
|
"MessagePlayChapter": "Poslechnout si začátek kapitoly",
|
||||||
"MessagePlaylistCreateFromCollection": "Vytvořit seznam skladeb z kolekce",
|
"MessagePlaylistCreateFromCollection": "Vytvořit seznam skladeb z kolekce",
|
||||||
|
"MessagePleaseWait": "Čekejte prosím...",
|
||||||
"MessagePodcastHasNoRSSFeedForMatching": "Podcast nemá žádnou adresu URL kanálu RSS, kterou by mohl použít pro porovnávání",
|
"MessagePodcastHasNoRSSFeedForMatching": "Podcast nemá žádnou adresu URL kanálu RSS, kterou by mohl použít pro porovnávání",
|
||||||
"MessageQuickMatchDescription": "Vyplňte prázdné detaily položky a obálku prvním výsledkem shody z '{0}'. Nepřepisuje podrobnosti, pokud není povoleno nastavení serveru \"Preferovat párování metadata\".",
|
"MessageQuickMatchDescription": "Vyplňte prázdné detaily položky a obálku prvním výsledkem shody z '{0}'. Nepřepisuje podrobnosti, pokud není povoleno nastavení serveru \"Preferovat párování metadata\".",
|
||||||
"MessageRemoveChapter": "Odstranit kapitolu",
|
"MessageRemoveChapter": "Odstranit kapitolu",
|
||||||
@@ -728,17 +769,46 @@
|
|||||||
"MessageShareExpiresIn": "Expiruje za {0}",
|
"MessageShareExpiresIn": "Expiruje za {0}",
|
||||||
"MessageShareURLWillBe": "Sdílené URL bude <strong>{0}</strong>",
|
"MessageShareURLWillBe": "Sdílené URL bude <strong>{0}</strong>",
|
||||||
"MessageStartPlaybackAtTime": "Spustit přehrávání pro \"{0}\" v {1}?",
|
"MessageStartPlaybackAtTime": "Spustit přehrávání pro \"{0}\" v {1}?",
|
||||||
|
"MessageTaskAudioFileNotWritable": "Nelze zapisovat do audio souboru \"{0}\"",
|
||||||
|
"MessageTaskCanceledByUser": "Task zrušen uživatelem",
|
||||||
|
"MessageTaskDownloadingEpisodeDescription": "Stahování epizody \"{0}\"",
|
||||||
|
"MessageTaskEmbeddingMetadata": "Vkládání metadat",
|
||||||
|
"MessageTaskEmbeddingMetadataDescription": "Vkládání metadat do audioknihy \"{0}\"",
|
||||||
|
"MessageTaskEncodingM4b": "Kódování M4B",
|
||||||
|
"MessageTaskEncodingM4bDescription": "Kódování audioknihy \"{0}\" do jednoho m4b souboru",
|
||||||
|
"MessageTaskFailed": "Selhalo",
|
||||||
|
"MessageTaskFailedToBackupAudioFile": "Zálohování audio souboru \"{0}\" se selhalo",
|
||||||
|
"MessageTaskFailedToCreateCacheDirectory": "Vytvoření cache adresáře selhalo",
|
||||||
|
"MessageTaskFailedToEmbedMetadataInFile": "Vkládání metadat do souboru \"{0}\" selhalo",
|
||||||
|
"MessageTaskFailedToMergeAudioFiles": "Spojení audio souborů selhalo",
|
||||||
|
"MessageTaskFailedToMoveM4bFile": "Přesunutí m4b souboru selhalo",
|
||||||
|
"MessageTaskFailedToWriteMetadataFile": "Zápis souboru metadat selhal",
|
||||||
|
"MessageTaskNoFilesToScan": "Žádné soubory ke skenování",
|
||||||
|
"MessageTaskOpmlImport": "Import OPML",
|
||||||
|
"MessageTaskOpmlImportDescription": "Vytváření podcastů z {0} RSS feedů",
|
||||||
|
"MessageTaskOpmlImportFeedDescription": "Importování RSS feedu \"{0}\"",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastDescription": "Vytváření podcastu \"{0}\"",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastExists": "Podcast se stejnou cestou již existuje",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastFailed": "Vytváření podcastu selhalo",
|
||||||
|
"MessageTaskOpmlImportFinished": "Přidáno {0} podcastů",
|
||||||
|
"MessageTaskScanItemsAdded": "{0} přidáno",
|
||||||
|
"MessageTaskScanItemsMissing": "{0} chybí",
|
||||||
|
"MessageTaskScanItemsUpdated": "{0} aktualizováno",
|
||||||
|
"MessageTaskScanNoChangesNeeded": "Žádné změny nejsou nutné",
|
||||||
|
"MessageTaskScanningFileChanges": "Skenování změn souborů v \"{0}\"",
|
||||||
|
"MessageTaskScanningLibrary": "Skenování \"{0}\" knihovny",
|
||||||
|
"MessageTaskTargetDirectoryNotWritable": "Do cílové složky nelze zapisovat",
|
||||||
"MessageThinking": "Přemýšlení...",
|
"MessageThinking": "Přemýšlení...",
|
||||||
"MessageUploaderItemFailed": "Nahrávání se nezdařilo",
|
"MessageUploaderItemFailed": "Nahrávání selhalo",
|
||||||
"MessageUploaderItemSuccess": "Nahráno bylo úspěšně!",
|
"MessageUploaderItemSuccess": "Úspěšně nahráno!",
|
||||||
"MessageUploading": "Odesílám...",
|
"MessageUploading": "Nahrávám...",
|
||||||
"MessageValidCronExpression": "Platný výraz cronu",
|
"MessageValidCronExpression": "Platný výraz cronu",
|
||||||
"MessageWatcherIsDisabledGlobally": "Hlídač je globálně zakázán v nastavení serveru",
|
"MessageWatcherIsDisabledGlobally": "Hlídač je globálně zakázán v nastavení serveru",
|
||||||
"MessageXLibraryIsEmpty": "{0} knihovna je prázdná!",
|
"MessageXLibraryIsEmpty": "{0} knihovna je prázdná!",
|
||||||
"MessageYourAudiobookDurationIsLonger": "Doba trvání audioknihy je delší než nalezená délka",
|
"MessageYourAudiobookDurationIsLonger": "Délka audioknihy je delší, než byla nalezena",
|
||||||
"MessageYourAudiobookDurationIsShorter": "Délka audioknihy je kratší, než byla nalezena",
|
"MessageYourAudiobookDurationIsShorter": "Délka audioknihy je kratší, než byla nalezena",
|
||||||
"NoteChangeRootPassword": "Uživatel root je jediný uživatel, který může mít prázdné heslo",
|
"NoteChangeRootPassword": "Uživatel root je jediný uživatel, který může mít prázdné heslo",
|
||||||
"NoteChapterEditorTimes": "Poznámka: Čas začátku první kapitoly musí zůstat v 0:00 a čas začátku poslední kapitoly nesmí překročit tuto dobu trvání audioknihy.",
|
"NoteChapterEditorTimes": "Poznámka: Čas začátku první kapitoly musí zůstat na 0:00 a čas začátku poslední kapitoly nesmí překročit dobu trvání audioknihy.",
|
||||||
"NoteFolderPicker": "Poznámka: složky, které jsou již namapovány, nebudou zobrazeny",
|
"NoteFolderPicker": "Poznámka: složky, které jsou již namapovány, nebudou zobrazeny",
|
||||||
"NoteRSSFeedPodcastAppsHttps": "Upozornění: Většina aplikací pro podcasty bude vyžadovat, aby adresa URL kanálu RSS používala protokol HTTPS",
|
"NoteRSSFeedPodcastAppsHttps": "Upozornění: Většina aplikací pro podcasty bude vyžadovat, aby adresa URL kanálu RSS používala protokol HTTPS",
|
||||||
"NoteRSSFeedPodcastAppsPubDate": "Upozornění: 1 nebo více epizod nemá datum vydání. Některé podcastové aplikace to vyžadují.",
|
"NoteRSSFeedPodcastAppsPubDate": "Upozornění: 1 nebo více epizod nemá datum vydání. Některé podcastové aplikace to vyžadují.",
|
||||||
@@ -752,8 +822,10 @@
|
|||||||
"PlaceholderSearchEpisode": "Hledat epizodu..",
|
"PlaceholderSearchEpisode": "Hledat epizodu..",
|
||||||
"StatsAuthorsAdded": "autoři přidáni",
|
"StatsAuthorsAdded": "autoři přidáni",
|
||||||
"StatsBooksAdded": "knihy přidány",
|
"StatsBooksAdded": "knihy přidány",
|
||||||
|
"StatsBooksAdditional": "Některé další zahrnují…",
|
||||||
"StatsBooksFinished": "dokončené knihy",
|
"StatsBooksFinished": "dokončené knihy",
|
||||||
"StatsBooksFinishedThisYear": "Některé knihy dokončené tento rok…",
|
"StatsBooksFinishedThisYear": "Některé knihy dokončené tento rok…",
|
||||||
|
"StatsCollectionGrewTo": "Vaše kolekce knih se rozrostla na…",
|
||||||
"StatsSessions": "sezení",
|
"StatsSessions": "sezení",
|
||||||
"StatsSpentListening": "stráveno posloucháním",
|
"StatsSpentListening": "stráveno posloucháním",
|
||||||
"StatsTopAuthor": "TOP AUTOR",
|
"StatsTopAuthor": "TOP AUTOR",
|
||||||
@@ -763,59 +835,75 @@
|
|||||||
"StatsTopMonth": "TOP MĚSÍC",
|
"StatsTopMonth": "TOP MĚSÍC",
|
||||||
"StatsTotalDuration": "S celkovou dobou…",
|
"StatsTotalDuration": "S celkovou dobou…",
|
||||||
"StatsYearInReview": "ROK V PŘEHLEDU",
|
"StatsYearInReview": "ROK V PŘEHLEDU",
|
||||||
"ToastAccountUpdateFailed": "Aktualizace účtu se nezdařila",
|
|
||||||
"ToastAccountUpdateSuccess": "Účet aktualizován",
|
"ToastAccountUpdateSuccess": "Účet aktualizován",
|
||||||
|
"ToastAppriseUrlRequired": "Je nutné zadat Apprise URL",
|
||||||
"ToastAuthorImageRemoveSuccess": "Obrázek autora odstraněn",
|
"ToastAuthorImageRemoveSuccess": "Obrázek autora odstraněn",
|
||||||
"ToastAuthorUpdateFailed": "Aktualizace autora se nezdařila",
|
"ToastAuthorNotFound": "Author \"{0}\" nenalezen",
|
||||||
|
"ToastAuthorRemoveSuccess": "Autor odstraněn",
|
||||||
|
"ToastAuthorSearchNotFound": "Autor nenalezen",
|
||||||
"ToastAuthorUpdateMerged": "Autor sloučen",
|
"ToastAuthorUpdateMerged": "Autor sloučen",
|
||||||
"ToastAuthorUpdateSuccess": "Autor aktualizován",
|
"ToastAuthorUpdateSuccess": "Autor aktualizován",
|
||||||
"ToastAuthorUpdateSuccessNoImageFound": "Autor aktualizován (nebyl nalezen žádný obrázek)",
|
"ToastAuthorUpdateSuccessNoImageFound": "Autor aktualizován (nebyl nalezen žádný obrázek)",
|
||||||
|
"ToastBackupAppliedSuccess": "Záloha obnovena",
|
||||||
"ToastBackupCreateFailed": "Vytvoření zálohy se nezdařilo",
|
"ToastBackupCreateFailed": "Vytvoření zálohy se nezdařilo",
|
||||||
"ToastBackupCreateSuccess": "Záloha vytvořena",
|
"ToastBackupCreateSuccess": "Záloha vytvořena",
|
||||||
"ToastBackupDeleteFailed": "Nepodařilo se smazat zálohu",
|
"ToastBackupDeleteFailed": "Nepodařilo se smazat zálohu",
|
||||||
"ToastBackupDeleteSuccess": "Záloha smazána",
|
"ToastBackupDeleteSuccess": "Záloha smazána",
|
||||||
|
"ToastBackupInvalidMaxKeep": "Neplatný počet záloh k zachování",
|
||||||
|
"ToastBackupInvalidMaxSize": "Neplatná maximální velikost zálohy",
|
||||||
"ToastBackupRestoreFailed": "Nepodařilo se obnovit zálohu",
|
"ToastBackupRestoreFailed": "Nepodařilo se obnovit zálohu",
|
||||||
"ToastBackupUploadFailed": "Nepodařilo se nahrát zálohu",
|
"ToastBackupUploadFailed": "Nepodařilo se nahrát zálohu",
|
||||||
"ToastBackupUploadSuccess": "Záloha nahrána",
|
"ToastBackupUploadSuccess": "Záloha nahrána",
|
||||||
|
"ToastBatchDeleteFailed": "Hromadné smazání selhalo",
|
||||||
|
"ToastBatchDeleteSuccess": "Hromadné smazání proběhlo úspěšně",
|
||||||
"ToastBatchUpdateFailed": "Dávková aktualizace se nezdařila",
|
"ToastBatchUpdateFailed": "Dávková aktualizace se nezdařila",
|
||||||
"ToastBatchUpdateSuccess": "Dávková aktualizace proběhla úspěšně",
|
"ToastBatchUpdateSuccess": "Dávková aktualizace proběhla úspěšně",
|
||||||
"ToastBookmarkCreateFailed": "Vytvoření záložky se nezdařilo",
|
"ToastBookmarkCreateFailed": "Vytvoření záložky se nezdařilo",
|
||||||
"ToastBookmarkCreateSuccess": "Přidána záložka",
|
"ToastBookmarkCreateSuccess": "Přidána záložka",
|
||||||
"ToastBookmarkRemoveSuccess": "Záložka odstraněna",
|
"ToastBookmarkRemoveSuccess": "Záložka odstraněna",
|
||||||
"ToastBookmarkUpdateFailed": "Aktualizace záložky se nezdařila",
|
|
||||||
"ToastBookmarkUpdateSuccess": "Záložka aktualizována",
|
"ToastBookmarkUpdateSuccess": "Záložka aktualizována",
|
||||||
"ToastCachePurgeFailed": "Nepodařilo se vyčistit mezipaměť",
|
"ToastCachePurgeFailed": "Nepodařilo se vyčistit mezipaměť",
|
||||||
"ToastCachePurgeSuccess": "Vyrovnávací paměť úspěšně vyčištěna",
|
"ToastCachePurgeSuccess": "Vyrovnávací paměť úspěšně vyčištěna",
|
||||||
"ToastChaptersHaveErrors": "Kapitoly obsahují chyby",
|
"ToastChaptersHaveErrors": "Kapitoly obsahují chyby",
|
||||||
"ToastChaptersMustHaveTitles": "Kapitoly musí mít názvy",
|
"ToastChaptersMustHaveTitles": "Kapitoly musí mít názvy",
|
||||||
|
"ToastChaptersRemoved": "Kapitoly odstraněny",
|
||||||
"ToastCollectionItemsRemoveSuccess": "Položky odstraněny z kolekce",
|
"ToastCollectionItemsRemoveSuccess": "Položky odstraněny z kolekce",
|
||||||
"ToastCollectionRemoveSuccess": "Kolekce odstraněna",
|
"ToastCollectionRemoveSuccess": "Kolekce odstraněna",
|
||||||
"ToastCollectionUpdateFailed": "Aktualizace kolekce se nezdařila",
|
|
||||||
"ToastCollectionUpdateSuccess": "Kolekce aktualizována",
|
"ToastCollectionUpdateSuccess": "Kolekce aktualizována",
|
||||||
|
"ToastCoverUpdateFailed": "Aktualizace obálky selhala",
|
||||||
"ToastDeleteFileFailed": "Nepodařilo se smazat soubor",
|
"ToastDeleteFileFailed": "Nepodařilo se smazat soubor",
|
||||||
"ToastDeleteFileSuccess": "Soubor smazán",
|
"ToastDeleteFileSuccess": "Soubor smazán",
|
||||||
|
"ToastDeviceAddFailed": "Přidání zařízení selhalo",
|
||||||
|
"ToastDeviceNameAlreadyExists": "Zařízení se stejným jménem již existuje",
|
||||||
|
"ToastDeviceTestEmailFailed": "Odeslání testovacího emailu selhalo",
|
||||||
|
"ToastDeviceTestEmailSuccess": "Testovací email byl odeslán",
|
||||||
|
"ToastEmailSettingsUpdateSuccess": "Nastavení emailu aktualizována",
|
||||||
|
"ToastEpisodeDownloadQueueClearFailed": "Vyčištění fronty selhalo",
|
||||||
"ToastErrorCannotShare": "Na tomto zařízení nelze nativně sdílet",
|
"ToastErrorCannotShare": "Na tomto zařízení nelze nativně sdílet",
|
||||||
"ToastFailedToLoadData": "Nepodařilo se načíst data",
|
"ToastFailedToLoadData": "Nepodařilo se načíst data",
|
||||||
"ToastItemCoverUpdateFailed": "Aktualizace obálky se nezdařila",
|
"ToastFailedToShare": "Sdílení selhalo",
|
||||||
|
"ToastFailedToUpdate": "Aktualizace selhala",
|
||||||
|
"ToastInvalidImageUrl": "Neplatná URL obrázku",
|
||||||
|
"ToastInvalidUrl": "Neplatná URL",
|
||||||
"ToastItemCoverUpdateSuccess": "Obálka předmětu byl aktualizována",
|
"ToastItemCoverUpdateSuccess": "Obálka předmětu byl aktualizována",
|
||||||
"ToastItemDetailsUpdateFailed": "Nepodařilo se aktualizovat podrobnosti o položce",
|
"ToastItemDeletedFailed": "Smazání položky selhalo",
|
||||||
|
"ToastItemDeletedSuccess": "Položka smazána",
|
||||||
"ToastItemDetailsUpdateSuccess": "Podrobnosti o položce byly aktualizovány",
|
"ToastItemDetailsUpdateSuccess": "Podrobnosti o položce byly aktualizovány",
|
||||||
"ToastItemMarkedAsFinishedFailed": "Nepodařilo se označit jako dokončené",
|
"ToastItemMarkedAsFinishedFailed": "Nepodařilo se označit jako dokončené",
|
||||||
"ToastItemMarkedAsFinishedSuccess": "Položka označena jako dokončená",
|
"ToastItemMarkedAsFinishedSuccess": "Položka označena jako dokončená",
|
||||||
"ToastItemMarkedAsNotFinishedFailed": "Nepodařilo se označit jako nedokončené",
|
"ToastItemMarkedAsNotFinishedFailed": "Nepodařilo se označit jako nedokončené",
|
||||||
"ToastItemMarkedAsNotFinishedSuccess": "Položka označena jako nedokončená",
|
"ToastItemMarkedAsNotFinishedSuccess": "Položka označena jako nedokončená",
|
||||||
|
"ToastItemUpdateSuccess": "Položka aktualizována",
|
||||||
"ToastLibraryCreateFailed": "Vytvoření knihovny se nezdařilo",
|
"ToastLibraryCreateFailed": "Vytvoření knihovny se nezdařilo",
|
||||||
"ToastLibraryCreateSuccess": "Knihovna \"{0}\" vytvořena",
|
"ToastLibraryCreateSuccess": "Knihovna \"{0}\" vytvořena",
|
||||||
"ToastLibraryDeleteFailed": "Nepodařilo se smazat knihovnu",
|
"ToastLibraryDeleteFailed": "Nepodařilo se smazat knihovnu",
|
||||||
"ToastLibraryDeleteSuccess": "Knihovna smazána",
|
"ToastLibraryDeleteSuccess": "Knihovna smazána",
|
||||||
"ToastLibraryScanFailedToStart": "Nepodařilo se spustit kontrolu",
|
"ToastLibraryScanFailedToStart": "Nepodařilo se spustit kontrolu",
|
||||||
"ToastLibraryScanStarted": "Kontrola knihovny spuštěna",
|
"ToastLibraryScanStarted": "Kontrola knihovny spuštěna",
|
||||||
"ToastLibraryUpdateFailed": "Aktualizace knihovny se nezdařila",
|
|
||||||
"ToastLibraryUpdateSuccess": "Knihovna \"{0}\" aktualizována",
|
"ToastLibraryUpdateSuccess": "Knihovna \"{0}\" aktualizována",
|
||||||
"ToastPlaylistCreateFailed": "Vytvoření seznamu přehrávání se nezdařilo",
|
"ToastPlaylistCreateFailed": "Vytvoření seznamu přehrávání se nezdařilo",
|
||||||
"ToastPlaylistCreateSuccess": "Seznam přehrávání vytvořen",
|
"ToastPlaylistCreateSuccess": "Seznam přehrávání vytvořen",
|
||||||
"ToastPlaylistRemoveSuccess": "Seznam přehrávání odstraněn",
|
"ToastPlaylistRemoveSuccess": "Seznam přehrávání odstraněn",
|
||||||
"ToastPlaylistUpdateFailed": "Aktualizace seznamu přehrávání se nezdařila",
|
|
||||||
"ToastPlaylistUpdateSuccess": "Seznam přehrávání aktualizován",
|
"ToastPlaylistUpdateSuccess": "Seznam přehrávání aktualizován",
|
||||||
"ToastPodcastCreateFailed": "Vytvoření podcastu se nezdařilo",
|
"ToastPodcastCreateFailed": "Vytvoření podcastu se nezdařilo",
|
||||||
"ToastPodcastCreateSuccess": "Podcast byl úspěšně vytvořen",
|
"ToastPodcastCreateSuccess": "Podcast byl úspěšně vytvořen",
|
||||||
@@ -827,7 +915,6 @@
|
|||||||
"ToastSendEbookToDeviceSuccess": "E-kniha odeslána do zařízení \"{0}\"",
|
"ToastSendEbookToDeviceSuccess": "E-kniha odeslána do zařízení \"{0}\"",
|
||||||
"ToastSeriesUpdateFailed": "Aktualizace série se nezdařila",
|
"ToastSeriesUpdateFailed": "Aktualizace série se nezdařila",
|
||||||
"ToastSeriesUpdateSuccess": "Aktualizace série byla úspěšná",
|
"ToastSeriesUpdateSuccess": "Aktualizace série byla úspěšná",
|
||||||
"ToastServerSettingsUpdateFailed": "Nepodařilo se aktualizovat nastavení serveru",
|
|
||||||
"ToastServerSettingsUpdateSuccess": "Nastavení serveru aktualizováno",
|
"ToastServerSettingsUpdateSuccess": "Nastavení serveru aktualizováno",
|
||||||
"ToastSessionDeleteFailed": "Nepodařilo se smazat relaci",
|
"ToastSessionDeleteFailed": "Nepodařilo se smazat relaci",
|
||||||
"ToastSessionDeleteSuccess": "Relace smazána",
|
"ToastSessionDeleteSuccess": "Relace smazána",
|
||||||
@@ -835,7 +922,6 @@
|
|||||||
"ToastSocketDisconnected": "Socket odpojen",
|
"ToastSocketDisconnected": "Socket odpojen",
|
||||||
"ToastSocketFailedToConnect": "Socket se nepodařilo připojit",
|
"ToastSocketFailedToConnect": "Socket se nepodařilo připojit",
|
||||||
"ToastSortingPrefixesEmptyError": "Musí mít alespoň 1 třídicí předponu",
|
"ToastSortingPrefixesEmptyError": "Musí mít alespoň 1 třídicí předponu",
|
||||||
"ToastSortingPrefixesUpdateFailed": "Nepodařilo se aktualizovat třídicí předpony",
|
|
||||||
"ToastSortingPrefixesUpdateSuccess": "Aktualizovány předpony třídění ({0} položek)",
|
"ToastSortingPrefixesUpdateSuccess": "Aktualizovány předpony třídění ({0} položek)",
|
||||||
"ToastUserDeleteFailed": "Nepodařilo se smazat uživatele",
|
"ToastUserDeleteFailed": "Nepodařilo se smazat uživatele",
|
||||||
"ToastUserDeleteSuccess": "Uživatel smazán"
|
"ToastUserDeleteSuccess": "Uživatel smazán"
|
||||||
|
|||||||
+20
-15
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"ButtonAdd": "Tilføj",
|
"ButtonAdd": "Tilføj",
|
||||||
"ButtonAddChapters": "Tilføj kapitler",
|
"ButtonAddChapters": "Tilføj kapitler",
|
||||||
|
"ButtonAddDevice": "Tilføj enhed",
|
||||||
|
"ButtonAddLibrary": "Tilføj Bibliotek",
|
||||||
"ButtonAddPodcasts": "Tilføj podcasts",
|
"ButtonAddPodcasts": "Tilføj podcasts",
|
||||||
|
"ButtonAddUser": "Tilføj bruger",
|
||||||
"ButtonAddYourFirstLibrary": "Tilføj din første bibliotek",
|
"ButtonAddYourFirstLibrary": "Tilføj din første bibliotek",
|
||||||
"ButtonApply": "Anvend",
|
"ButtonApply": "Anvend",
|
||||||
"ButtonApplyChapters": "Anvend kapitler",
|
"ButtonApplyChapters": "Anvend kapitler",
|
||||||
@@ -25,6 +28,7 @@
|
|||||||
"ButtonEdit": "Rediger",
|
"ButtonEdit": "Rediger",
|
||||||
"ButtonEditChapters": "Rediger kapitler",
|
"ButtonEditChapters": "Rediger kapitler",
|
||||||
"ButtonEditPodcast": "Rediger podcast",
|
"ButtonEditPodcast": "Rediger podcast",
|
||||||
|
"ButtonEnable": "Aktiver",
|
||||||
"ButtonForceReScan": "Tvungen genindlæsning",
|
"ButtonForceReScan": "Tvungen genindlæsning",
|
||||||
"ButtonFullPath": "Fuld sti",
|
"ButtonFullPath": "Fuld sti",
|
||||||
"ButtonHide": "Skjul",
|
"ButtonHide": "Skjul",
|
||||||
@@ -42,6 +46,7 @@
|
|||||||
"ButtonOk": "OK",
|
"ButtonOk": "OK",
|
||||||
"ButtonOpenFeed": "Åbn feed",
|
"ButtonOpenFeed": "Åbn feed",
|
||||||
"ButtonOpenManager": "Åbn manager",
|
"ButtonOpenManager": "Åbn manager",
|
||||||
|
"ButtonPause": "Pause",
|
||||||
"ButtonPlay": "Afspil",
|
"ButtonPlay": "Afspil",
|
||||||
"ButtonPlaying": "Afspiller",
|
"ButtonPlaying": "Afspiller",
|
||||||
"ButtonPlaylists": "Afspilningslister",
|
"ButtonPlaylists": "Afspilningslister",
|
||||||
@@ -66,7 +71,7 @@
|
|||||||
"ButtonScanLibrary": "Scan Bibliotek",
|
"ButtonScanLibrary": "Scan Bibliotek",
|
||||||
"ButtonSearch": "Søg",
|
"ButtonSearch": "Søg",
|
||||||
"ButtonSelectFolderPath": "Vælg Mappen Sti",
|
"ButtonSelectFolderPath": "Vælg Mappen Sti",
|
||||||
"ButtonSeries": "Serie",
|
"ButtonSeries": "Serier",
|
||||||
"ButtonSetChaptersFromTracks": "Sæt kapitler fra spor",
|
"ButtonSetChaptersFromTracks": "Sæt kapitler fra spor",
|
||||||
"ButtonShiftTimes": "Skift Tider",
|
"ButtonShiftTimes": "Skift Tider",
|
||||||
"ButtonShow": "Vis",
|
"ButtonShow": "Vis",
|
||||||
@@ -188,14 +193,14 @@
|
|||||||
"LabelChapters": "Kapitler",
|
"LabelChapters": "Kapitler",
|
||||||
"LabelChaptersFound": "fundne kapitler",
|
"LabelChaptersFound": "fundne kapitler",
|
||||||
"LabelClosePlayer": "Luk afspiller",
|
"LabelClosePlayer": "Luk afspiller",
|
||||||
"LabelCollapseSeries": "Fold Serie Sammen",
|
"LabelCollapseSeries": "Fold Serier Sammen",
|
||||||
"LabelCollection": "Samling",
|
"LabelCollection": "Samling",
|
||||||
"LabelCollections": "Samlinger",
|
"LabelCollections": "Samlinger",
|
||||||
"LabelComplete": "Fuldfør",
|
"LabelComplete": "Fuldfør",
|
||||||
"LabelConfirmPassword": "Bekræft Adgangskode",
|
"LabelConfirmPassword": "Bekræft Adgangskode",
|
||||||
"LabelContinueListening": "Fortsæt Lytning",
|
"LabelContinueListening": "Fortsæt med at lytte",
|
||||||
"LabelContinueReading": "Fortsæt Læsning",
|
"LabelContinueReading": "Fortsæt med at læse",
|
||||||
"LabelContinueSeries": "Fortsæt Serie",
|
"LabelContinueSeries": "Fortsæt Serien",
|
||||||
"LabelCover": "Omslag",
|
"LabelCover": "Omslag",
|
||||||
"LabelCoverImageURL": "Omslagsbillede URL",
|
"LabelCoverImageURL": "Omslagsbillede URL",
|
||||||
"LabelCreatedAt": "Oprettet Kl.",
|
"LabelCreatedAt": "Oprettet Kl.",
|
||||||
@@ -212,6 +217,7 @@
|
|||||||
"LabelDiscFromFilename": "Disk fra Filnavn",
|
"LabelDiscFromFilename": "Disk fra Filnavn",
|
||||||
"LabelDiscFromMetadata": "Disk fra Metadata",
|
"LabelDiscFromMetadata": "Disk fra Metadata",
|
||||||
"LabelDiscover": "Opdag",
|
"LabelDiscover": "Opdag",
|
||||||
|
"LabelDownload": "Download",
|
||||||
"LabelDownloadNEpisodes": "Download {0} episoder",
|
"LabelDownloadNEpisodes": "Download {0} episoder",
|
||||||
"LabelDuration": "Varighed",
|
"LabelDuration": "Varighed",
|
||||||
"LabelDurationFound": "Fundet varighed:",
|
"LabelDurationFound": "Fundet varighed:",
|
||||||
@@ -225,12 +231,15 @@
|
|||||||
"LabelEmbeddedCover": "Indlejret Omslag",
|
"LabelEmbeddedCover": "Indlejret Omslag",
|
||||||
"LabelEnable": "Aktivér",
|
"LabelEnable": "Aktivér",
|
||||||
"LabelEnd": "Slut",
|
"LabelEnd": "Slut",
|
||||||
|
"LabelEndOfChapter": "Slutningen af kapitel",
|
||||||
|
"LabelEpisode": "Episode",
|
||||||
"LabelEpisodeTitle": "Episodetitel",
|
"LabelEpisodeTitle": "Episodetitel",
|
||||||
"LabelEpisodeType": "Episodetype",
|
"LabelEpisodeType": "Episodetype",
|
||||||
"LabelExample": "Eksempel",
|
"LabelExample": "Eksempel",
|
||||||
"LabelExplicit": "Eksplisit",
|
"LabelExplicit": "Eksplisit",
|
||||||
|
"LabelFeedURL": "Feed URL",
|
||||||
"LabelFile": "Fil",
|
"LabelFile": "Fil",
|
||||||
"LabelFileBirthtime": "Fødselstidspunkt for fil",
|
"LabelFileBirthtime": "Oprettelsestidspunkt for fil",
|
||||||
"LabelFileModified": "Fil ændret",
|
"LabelFileModified": "Fil ændret",
|
||||||
"LabelFilename": "Filnavn",
|
"LabelFilename": "Filnavn",
|
||||||
"LabelFilterByUser": "Filtrér efter bruger",
|
"LabelFilterByUser": "Filtrér efter bruger",
|
||||||
@@ -238,8 +247,10 @@
|
|||||||
"LabelFinished": "Færdig",
|
"LabelFinished": "Færdig",
|
||||||
"LabelFolder": "Mappe",
|
"LabelFolder": "Mappe",
|
||||||
"LabelFolders": "Mapper",
|
"LabelFolders": "Mapper",
|
||||||
|
"LabelFontBoldness": "Skrift tykkelse",
|
||||||
"LabelFontFamily": "Fontfamilie",
|
"LabelFontFamily": "Fontfamilie",
|
||||||
"LabelFontScale": "Skriftstørrelse",
|
"LabelFontScale": "Skriftstørrelse",
|
||||||
|
"LabelGenre": "Genre",
|
||||||
"LabelGenres": "Genrer",
|
"LabelGenres": "Genrer",
|
||||||
"LabelHardDeleteFile": "Permanent slet fil",
|
"LabelHardDeleteFile": "Permanent slet fil",
|
||||||
"LabelHasEbook": "Har e-bog",
|
"LabelHasEbook": "Har e-bog",
|
||||||
@@ -267,6 +278,7 @@
|
|||||||
"LabelLastSeen": "Sidst set",
|
"LabelLastSeen": "Sidst set",
|
||||||
"LabelLastTime": "Sidste gang",
|
"LabelLastTime": "Sidste gang",
|
||||||
"LabelLastUpdate": "Seneste opdatering",
|
"LabelLastUpdate": "Seneste opdatering",
|
||||||
|
"LabelLayout": "Layout",
|
||||||
"LabelLayoutSinglePage": "Enkeltside",
|
"LabelLayoutSinglePage": "Enkeltside",
|
||||||
"LabelLayoutSplitPage": "Opdelt side",
|
"LabelLayoutSplitPage": "Opdelt side",
|
||||||
"LabelLess": "Mindre",
|
"LabelLess": "Mindre",
|
||||||
@@ -344,10 +356,11 @@
|
|||||||
"LabelRSSFeedPreventIndexing": "Forhindrer indeksering",
|
"LabelRSSFeedPreventIndexing": "Forhindrer indeksering",
|
||||||
"LabelRSSFeedSlug": "RSS-feed-slug",
|
"LabelRSSFeedSlug": "RSS-feed-slug",
|
||||||
"LabelRSSFeedURL": "RSS-feed-URL",
|
"LabelRSSFeedURL": "RSS-feed-URL",
|
||||||
|
"LabelRandomly": "Tilfældigt",
|
||||||
"LabelRead": "Læst",
|
"LabelRead": "Læst",
|
||||||
"LabelReadAgain": "Læs igen",
|
"LabelReadAgain": "Læs igen",
|
||||||
"LabelReadEbookWithoutProgress": "Læs e-bog uden at følge fremskridt",
|
"LabelReadEbookWithoutProgress": "Læs e-bog uden at følge fremskridt",
|
||||||
"LabelRecentSeries": "Seneste serie",
|
"LabelRecentSeries": "Seneste serier",
|
||||||
"LabelRecentlyAdded": "Senest tilføjet",
|
"LabelRecentlyAdded": "Senest tilføjet",
|
||||||
"LabelRecommended": "Anbefalet",
|
"LabelRecommended": "Anbefalet",
|
||||||
"LabelReleaseDate": "Udgivelsesdato",
|
"LabelReleaseDate": "Udgivelsesdato",
|
||||||
@@ -604,10 +617,8 @@
|
|||||||
"PlaceholderNewPlaylist": "Nyt afspilningslistnavn",
|
"PlaceholderNewPlaylist": "Nyt afspilningslistnavn",
|
||||||
"PlaceholderSearch": "Søg..",
|
"PlaceholderSearch": "Søg..",
|
||||||
"PlaceholderSearchEpisode": "Søg efter episode..",
|
"PlaceholderSearchEpisode": "Søg efter episode..",
|
||||||
"ToastAccountUpdateFailed": "Mislykkedes opdatering af konto",
|
|
||||||
"ToastAccountUpdateSuccess": "Konto opdateret",
|
"ToastAccountUpdateSuccess": "Konto opdateret",
|
||||||
"ToastAuthorImageRemoveSuccess": "Forfatterbillede fjernet",
|
"ToastAuthorImageRemoveSuccess": "Forfatterbillede fjernet",
|
||||||
"ToastAuthorUpdateFailed": "Mislykkedes opdatering af forfatter",
|
|
||||||
"ToastAuthorUpdateMerged": "Forfatter fusioneret",
|
"ToastAuthorUpdateMerged": "Forfatter fusioneret",
|
||||||
"ToastAuthorUpdateSuccess": "Forfatter opdateret",
|
"ToastAuthorUpdateSuccess": "Forfatter opdateret",
|
||||||
"ToastAuthorUpdateSuccessNoImageFound": "Forfatter opdateret (ingen billede fundet)",
|
"ToastAuthorUpdateSuccessNoImageFound": "Forfatter opdateret (ingen billede fundet)",
|
||||||
@@ -623,17 +634,13 @@
|
|||||||
"ToastBookmarkCreateFailed": "Mislykkedes oprettelse af bogmærke",
|
"ToastBookmarkCreateFailed": "Mislykkedes oprettelse af bogmærke",
|
||||||
"ToastBookmarkCreateSuccess": "Bogmærke tilføjet",
|
"ToastBookmarkCreateSuccess": "Bogmærke tilføjet",
|
||||||
"ToastBookmarkRemoveSuccess": "Bogmærke fjernet",
|
"ToastBookmarkRemoveSuccess": "Bogmærke fjernet",
|
||||||
"ToastBookmarkUpdateFailed": "Mislykkedes opdatering af bogmærke",
|
|
||||||
"ToastBookmarkUpdateSuccess": "Bogmærke opdateret",
|
"ToastBookmarkUpdateSuccess": "Bogmærke opdateret",
|
||||||
"ToastChaptersHaveErrors": "Kapitler har fejl",
|
"ToastChaptersHaveErrors": "Kapitler har fejl",
|
||||||
"ToastChaptersMustHaveTitles": "Kapitler skal have titler",
|
"ToastChaptersMustHaveTitles": "Kapitler skal have titler",
|
||||||
"ToastCollectionItemsRemoveSuccess": "Element(er) fjernet fra samlingen",
|
"ToastCollectionItemsRemoveSuccess": "Element(er) fjernet fra samlingen",
|
||||||
"ToastCollectionRemoveSuccess": "Samling fjernet",
|
"ToastCollectionRemoveSuccess": "Samling fjernet",
|
||||||
"ToastCollectionUpdateFailed": "Mislykkedes opdatering af samling",
|
|
||||||
"ToastCollectionUpdateSuccess": "Samling opdateret",
|
"ToastCollectionUpdateSuccess": "Samling opdateret",
|
||||||
"ToastItemCoverUpdateFailed": "Mislykkedes opdatering af varens omslag",
|
|
||||||
"ToastItemCoverUpdateSuccess": "Varens omslag opdateret",
|
"ToastItemCoverUpdateSuccess": "Varens omslag opdateret",
|
||||||
"ToastItemDetailsUpdateFailed": "Mislykkedes opdatering af varedetaljer",
|
|
||||||
"ToastItemDetailsUpdateSuccess": "Varedetaljer opdateret",
|
"ToastItemDetailsUpdateSuccess": "Varedetaljer opdateret",
|
||||||
"ToastItemMarkedAsFinishedFailed": "Mislykkedes markering som afsluttet",
|
"ToastItemMarkedAsFinishedFailed": "Mislykkedes markering som afsluttet",
|
||||||
"ToastItemMarkedAsFinishedSuccess": "Vare markeret som afsluttet",
|
"ToastItemMarkedAsFinishedSuccess": "Vare markeret som afsluttet",
|
||||||
@@ -645,12 +652,10 @@
|
|||||||
"ToastLibraryDeleteSuccess": "Bibliotek slettet",
|
"ToastLibraryDeleteSuccess": "Bibliotek slettet",
|
||||||
"ToastLibraryScanFailedToStart": "Mislykkedes start af skanning",
|
"ToastLibraryScanFailedToStart": "Mislykkedes start af skanning",
|
||||||
"ToastLibraryScanStarted": "Biblioteksskanning startet",
|
"ToastLibraryScanStarted": "Biblioteksskanning startet",
|
||||||
"ToastLibraryUpdateFailed": "Mislykkedes opdatering af bibliotek",
|
|
||||||
"ToastLibraryUpdateSuccess": "Bibliotek \"{0}\" opdateret",
|
"ToastLibraryUpdateSuccess": "Bibliotek \"{0}\" opdateret",
|
||||||
"ToastPlaylistCreateFailed": "Mislykkedes oprettelse af afspilningsliste",
|
"ToastPlaylistCreateFailed": "Mislykkedes oprettelse af afspilningsliste",
|
||||||
"ToastPlaylistCreateSuccess": "Afspilningsliste oprettet",
|
"ToastPlaylistCreateSuccess": "Afspilningsliste oprettet",
|
||||||
"ToastPlaylistRemoveSuccess": "Afspilningsliste fjernet",
|
"ToastPlaylistRemoveSuccess": "Afspilningsliste fjernet",
|
||||||
"ToastPlaylistUpdateFailed": "Mislykkedes opdatering af afspilningsliste",
|
|
||||||
"ToastPlaylistUpdateSuccess": "Afspilningsliste opdateret",
|
"ToastPlaylistUpdateSuccess": "Afspilningsliste opdateret",
|
||||||
"ToastPodcastCreateFailed": "Mislykkedes oprettelse af podcast",
|
"ToastPodcastCreateFailed": "Mislykkedes oprettelse af podcast",
|
||||||
"ToastPodcastCreateSuccess": "Podcast oprettet med succes",
|
"ToastPodcastCreateSuccess": "Podcast oprettet med succes",
|
||||||
|
|||||||
+170
-49
@@ -19,7 +19,7 @@
|
|||||||
"ButtonChooseFiles": "Wähle eine Datei",
|
"ButtonChooseFiles": "Wähle eine Datei",
|
||||||
"ButtonClearFilter": "Filter löschen",
|
"ButtonClearFilter": "Filter löschen",
|
||||||
"ButtonCloseFeed": "Feed schließen",
|
"ButtonCloseFeed": "Feed schließen",
|
||||||
"ButtonCloseSession": "Offene Session schließen",
|
"ButtonCloseSession": "Offene Sitzung schließen",
|
||||||
"ButtonCollections": "Sammlungen",
|
"ButtonCollections": "Sammlungen",
|
||||||
"ButtonConfigureScanner": "Scannereinstellungen",
|
"ButtonConfigureScanner": "Scannereinstellungen",
|
||||||
"ButtonCreate": "Erstellen",
|
"ButtonCreate": "Erstellen",
|
||||||
@@ -51,9 +51,12 @@
|
|||||||
"ButtonNext": "Vor",
|
"ButtonNext": "Vor",
|
||||||
"ButtonNextChapter": "Nächstes Kapitel",
|
"ButtonNextChapter": "Nächstes Kapitel",
|
||||||
"ButtonNextItemInQueue": "Das nächste Element in der Warteschlange",
|
"ButtonNextItemInQueue": "Das nächste Element in der Warteschlange",
|
||||||
|
"ButtonOk": "OK",
|
||||||
"ButtonOpenFeed": "Feed öffnen",
|
"ButtonOpenFeed": "Feed öffnen",
|
||||||
"ButtonOpenManager": "Manager öffnen",
|
"ButtonOpenManager": "Manager öffnen",
|
||||||
|
"ButtonPause": "Pausieren",
|
||||||
"ButtonPlay": "Abspielen",
|
"ButtonPlay": "Abspielen",
|
||||||
|
"ButtonPlayAll": "Alles abspielen",
|
||||||
"ButtonPlaying": "Spielt",
|
"ButtonPlaying": "Spielt",
|
||||||
"ButtonPlaylists": "Wiedergabelisten",
|
"ButtonPlaylists": "Wiedergabelisten",
|
||||||
"ButtonPrevious": "Zurück",
|
"ButtonPrevious": "Zurück",
|
||||||
@@ -63,6 +66,7 @@
|
|||||||
"ButtonPurgeItemsCache": "Lösche Medien-Cache",
|
"ButtonPurgeItemsCache": "Lösche Medien-Cache",
|
||||||
"ButtonQueueAddItem": "Zur Warteschlange hinzufügen",
|
"ButtonQueueAddItem": "Zur Warteschlange hinzufügen",
|
||||||
"ButtonQueueRemoveItem": "Aus der Warteschlange entfernen",
|
"ButtonQueueRemoveItem": "Aus der Warteschlange entfernen",
|
||||||
|
"ButtonQuickEmbed": "Schnelles Hinzufügen",
|
||||||
"ButtonQuickEmbedMetadata": "Schnelles Hinzufügen von Metadaten",
|
"ButtonQuickEmbedMetadata": "Schnelles Hinzufügen von Metadaten",
|
||||||
"ButtonQuickMatch": "Schnellabgleich",
|
"ButtonQuickMatch": "Schnellabgleich",
|
||||||
"ButtonReScan": "Neu scannen",
|
"ButtonReScan": "Neu scannen",
|
||||||
@@ -95,7 +99,8 @@
|
|||||||
"ButtonStartMetadataEmbed": "Metadateneinbettung starten",
|
"ButtonStartMetadataEmbed": "Metadateneinbettung starten",
|
||||||
"ButtonStats": "Statistiken",
|
"ButtonStats": "Statistiken",
|
||||||
"ButtonSubmit": "Ok",
|
"ButtonSubmit": "Ok",
|
||||||
"ButtonUnlinkOpedId": "OpenID trennen",
|
"ButtonTest": "Test",
|
||||||
|
"ButtonUnlinkOpenId": "OpenID trennen",
|
||||||
"ButtonUpload": "Hochladen",
|
"ButtonUpload": "Hochladen",
|
||||||
"ButtonUploadBackup": "Sicherung hochladen",
|
"ButtonUploadBackup": "Sicherung hochladen",
|
||||||
"ButtonUploadCover": "Titelbild hochladen",
|
"ButtonUploadCover": "Titelbild hochladen",
|
||||||
@@ -112,7 +117,7 @@
|
|||||||
"HeaderAdvanced": "Erweitert",
|
"HeaderAdvanced": "Erweitert",
|
||||||
"HeaderAppriseNotificationSettings": "Apprise Benachrichtigungseinstellungen",
|
"HeaderAppriseNotificationSettings": "Apprise Benachrichtigungseinstellungen",
|
||||||
"HeaderAudioTracks": "Audiodateien",
|
"HeaderAudioTracks": "Audiodateien",
|
||||||
"HeaderAudiobookTools": "Hörbuch-Dateiverwaltungstools",
|
"HeaderAudiobookTools": "Hörbuch-Dateiverwaltungswerkzeuge",
|
||||||
"HeaderAuthentication": "Authentifizierung",
|
"HeaderAuthentication": "Authentifizierung",
|
||||||
"HeaderBackups": "Sicherungen",
|
"HeaderBackups": "Sicherungen",
|
||||||
"HeaderChangePassword": "Passwort ändern",
|
"HeaderChangePassword": "Passwort ändern",
|
||||||
@@ -122,11 +127,13 @@
|
|||||||
"HeaderCollectionItems": "Sammlungseinträge",
|
"HeaderCollectionItems": "Sammlungseinträge",
|
||||||
"HeaderCover": "Titelbild",
|
"HeaderCover": "Titelbild",
|
||||||
"HeaderCurrentDownloads": "Aktuelle Downloads",
|
"HeaderCurrentDownloads": "Aktuelle Downloads",
|
||||||
"HeaderCustomMessageOnLogin": "Benutzerdefinierte Nachricht für den Login",
|
"HeaderCustomMessageOnLogin": "Benutzerdefinierte Nachricht für die Anmeldung",
|
||||||
"HeaderCustomMetadataProviders": "Benutzerdefinierte Metadata Anbieter",
|
"HeaderCustomMetadataProviders": "Benutzerdefinierte Metadatenanbieter",
|
||||||
|
"HeaderDetails": "Details",
|
||||||
"HeaderDownloadQueue": "Download Warteschlange",
|
"HeaderDownloadQueue": "Download Warteschlange",
|
||||||
"HeaderEbookFiles": "E-Buch-Dateien",
|
"HeaderEbookFiles": "E-Buch-Dateien",
|
||||||
"HeaderEmailSettings": "Email Einstellungen",
|
"HeaderEmail": "E-Mail",
|
||||||
|
"HeaderEmailSettings": "E-Mail-Einstellungen",
|
||||||
"HeaderEpisodes": "Episoden",
|
"HeaderEpisodes": "Episoden",
|
||||||
"HeaderEreaderDevices": "E-Reader Geräte",
|
"HeaderEreaderDevices": "E-Reader Geräte",
|
||||||
"HeaderEreaderSettings": "Einstellungen zum Lesen",
|
"HeaderEreaderSettings": "Einstellungen zum Lesen",
|
||||||
@@ -153,12 +160,12 @@
|
|||||||
"HeaderNewAccount": "Neues Konto",
|
"HeaderNewAccount": "Neues Konto",
|
||||||
"HeaderNewLibrary": "Neue Bibliothek",
|
"HeaderNewLibrary": "Neue Bibliothek",
|
||||||
"HeaderNotificationCreate": "Benachrichtigung erstellen",
|
"HeaderNotificationCreate": "Benachrichtigung erstellen",
|
||||||
"HeaderNotificationUpdate": "Benachrichtigung updaten",
|
"HeaderNotificationUpdate": "Benachrichtigung bearbeiten",
|
||||||
"HeaderNotifications": "Benachrichtigungen",
|
"HeaderNotifications": "Benachrichtigungen",
|
||||||
"HeaderOpenIDConnectAuthentication": "OpenID Connect Authentifizierung",
|
"HeaderOpenIDConnectAuthentication": "OpenID Connect Authentifizierung",
|
||||||
"HeaderOpenRSSFeed": "RSS-Feed öffnen",
|
"HeaderOpenRSSFeed": "RSS-Feed öffnen",
|
||||||
"HeaderOtherFiles": "Sonstige Dateien",
|
"HeaderOtherFiles": "Sonstige Dateien",
|
||||||
"HeaderPasswordAuthentication": "Passwort Authentifizierung",
|
"HeaderPasswordAuthentication": "Passwortauthentifizierung",
|
||||||
"HeaderPermissions": "Berechtigungen",
|
"HeaderPermissions": "Berechtigungen",
|
||||||
"HeaderPlayerQueue": "Player Warteschlange",
|
"HeaderPlayerQueue": "Player Warteschlange",
|
||||||
"HeaderPlayerSettings": "Player Einstellungen",
|
"HeaderPlayerSettings": "Player Einstellungen",
|
||||||
@@ -166,6 +173,7 @@
|
|||||||
"HeaderPlaylistItems": "Einträge in der Wiedergabeliste",
|
"HeaderPlaylistItems": "Einträge in der Wiedergabeliste",
|
||||||
"HeaderPodcastsToAdd": "Podcasts zum Hinzufügen",
|
"HeaderPodcastsToAdd": "Podcasts zum Hinzufügen",
|
||||||
"HeaderPreviewCover": "Vorschau Titelbild",
|
"HeaderPreviewCover": "Vorschau Titelbild",
|
||||||
|
"HeaderRSSFeedGeneral": "RSS Details",
|
||||||
"HeaderRSSFeedIsOpen": "RSS-Feed ist geöffnet",
|
"HeaderRSSFeedIsOpen": "RSS-Feed ist geöffnet",
|
||||||
"HeaderRSSFeeds": "RSS-Feeds",
|
"HeaderRSSFeeds": "RSS-Feeds",
|
||||||
"HeaderRemoveEpisode": "Episode entfernen",
|
"HeaderRemoveEpisode": "Episode entfernen",
|
||||||
@@ -179,6 +187,7 @@
|
|||||||
"HeaderSettingsDisplay": "Anzeige",
|
"HeaderSettingsDisplay": "Anzeige",
|
||||||
"HeaderSettingsExperimental": "Experimentelle Funktionen",
|
"HeaderSettingsExperimental": "Experimentelle Funktionen",
|
||||||
"HeaderSettingsGeneral": "Allgemein",
|
"HeaderSettingsGeneral": "Allgemein",
|
||||||
|
"HeaderSettingsScanner": "Scanner",
|
||||||
"HeaderSleepTimer": "Sleep-Timer",
|
"HeaderSleepTimer": "Sleep-Timer",
|
||||||
"HeaderStatsLargestItems": "Größte Medien",
|
"HeaderStatsLargestItems": "Größte Medien",
|
||||||
"HeaderStatsLongestItems": "Längste Medien (h)",
|
"HeaderStatsLongestItems": "Längste Medien (h)",
|
||||||
@@ -200,6 +209,7 @@
|
|||||||
"LabelAbridgedUnchecked": "Ungekürzt (nicht angehakt)",
|
"LabelAbridgedUnchecked": "Ungekürzt (nicht angehakt)",
|
||||||
"LabelAccessibleBy": "Zugänglich für",
|
"LabelAccessibleBy": "Zugänglich für",
|
||||||
"LabelAccountType": "Kontoart",
|
"LabelAccountType": "Kontoart",
|
||||||
|
"LabelAccountTypeAdmin": "Admin",
|
||||||
"LabelAccountTypeGuest": "Gast",
|
"LabelAccountTypeGuest": "Gast",
|
||||||
"LabelAccountTypeUser": "Benutzer",
|
"LabelAccountTypeUser": "Benutzer",
|
||||||
"LabelActivity": "Aktivitäten",
|
"LabelActivity": "Aktivitäten",
|
||||||
@@ -216,6 +226,9 @@
|
|||||||
"LabelAllUsersIncludingGuests": "Alle Benutzer und Gäste",
|
"LabelAllUsersIncludingGuests": "Alle Benutzer und Gäste",
|
||||||
"LabelAlreadyInYourLibrary": "Bereits in der Bibliothek",
|
"LabelAlreadyInYourLibrary": "Bereits in der Bibliothek",
|
||||||
"LabelAppend": "Anhängen",
|
"LabelAppend": "Anhängen",
|
||||||
|
"LabelAudioBitrate": "Audiobitrate (z. B. 128 kbit/s)",
|
||||||
|
"LabelAudioChannels": "Audiokanäle (1 oder 2)",
|
||||||
|
"LabelAudioCodec": "Audiocodec",
|
||||||
"LabelAuthor": "Autor",
|
"LabelAuthor": "Autor",
|
||||||
"LabelAuthorFirstLast": "Autor (Vorname Nachname)",
|
"LabelAuthorFirstLast": "Autor (Vorname Nachname)",
|
||||||
"LabelAuthorLastFirst": "Autor (Nachname, Vorname)",
|
"LabelAuthorLastFirst": "Autor (Nachname, Vorname)",
|
||||||
@@ -228,6 +241,7 @@
|
|||||||
"LabelAutoRegister": "Automatische Registrierung",
|
"LabelAutoRegister": "Automatische Registrierung",
|
||||||
"LabelAutoRegisterDescription": "Automatische neue Neutzer anlegen nach dem Registrieren",
|
"LabelAutoRegisterDescription": "Automatische neue Neutzer anlegen nach dem Registrieren",
|
||||||
"LabelBackToUser": "Zurück zum Benutzer",
|
"LabelBackToUser": "Zurück zum Benutzer",
|
||||||
|
"LabelBackupAudioFiles": "Audio-Dateien sichern",
|
||||||
"LabelBackupLocation": "Backup-Ort",
|
"LabelBackupLocation": "Backup-Ort",
|
||||||
"LabelBackupsEnableAutomaticBackups": "Automatische Sicherung aktivieren",
|
"LabelBackupsEnableAutomaticBackups": "Automatische Sicherung aktivieren",
|
||||||
"LabelBackupsEnableAutomaticBackupsHelp": "Backups werden in /metadata/backups gespeichert",
|
"LabelBackupsEnableAutomaticBackupsHelp": "Backups werden in /metadata/backups gespeichert",
|
||||||
@@ -235,7 +249,9 @@
|
|||||||
"LabelBackupsMaxBackupSizeHelp": "Zum Schutz vor Fehlkonfigurationen schlagen Sicherungen fehl, wenn sie die konfigurierte Größe überschreiten.",
|
"LabelBackupsMaxBackupSizeHelp": "Zum Schutz vor Fehlkonfigurationen schlagen Sicherungen fehl, wenn sie die konfigurierte Größe überschreiten.",
|
||||||
"LabelBackupsNumberToKeep": "Anzahl der aufzubewahrenden Sicherungen",
|
"LabelBackupsNumberToKeep": "Anzahl der aufzubewahrenden Sicherungen",
|
||||||
"LabelBackupsNumberToKeepHelp": "Es wird immer nur 1 Sicherung auf einmal entfernt. Wenn du bereits mehrere Sicherungen als die definierte max. Anzahl hast, solltest du diese manuell entfernen.",
|
"LabelBackupsNumberToKeepHelp": "Es wird immer nur 1 Sicherung auf einmal entfernt. Wenn du bereits mehrere Sicherungen als die definierte max. Anzahl hast, solltest du diese manuell entfernen.",
|
||||||
|
"LabelBitrate": "Bitrate",
|
||||||
"LabelBooks": "Bücher",
|
"LabelBooks": "Bücher",
|
||||||
|
"LabelButtonText": "Knopftext",
|
||||||
"LabelByAuthor": "von {0}",
|
"LabelByAuthor": "von {0}",
|
||||||
"LabelChangePassword": "Passwort ändern",
|
"LabelChangePassword": "Passwort ändern",
|
||||||
"LabelChannels": "Kanäle",
|
"LabelChannels": "Kanäle",
|
||||||
@@ -244,6 +260,7 @@
|
|||||||
"LabelChaptersFound": "Gefundene Kapitel",
|
"LabelChaptersFound": "Gefundene Kapitel",
|
||||||
"LabelClickForMoreInfo": "Klicken für mehr Informationen",
|
"LabelClickForMoreInfo": "Klicken für mehr Informationen",
|
||||||
"LabelClosePlayer": "Player schließen",
|
"LabelClosePlayer": "Player schließen",
|
||||||
|
"LabelCodec": "Codec",
|
||||||
"LabelCollapseSeries": "Serien einklappen",
|
"LabelCollapseSeries": "Serien einklappen",
|
||||||
"LabelCollapseSubSeries": "Unterserien einklappen",
|
"LabelCollapseSubSeries": "Unterserien einklappen",
|
||||||
"LabelCollection": "Sammlung",
|
"LabelCollection": "Sammlung",
|
||||||
@@ -282,16 +299,26 @@
|
|||||||
"LabelEbook": "E-Buch",
|
"LabelEbook": "E-Buch",
|
||||||
"LabelEbooks": "E-Bücher",
|
"LabelEbooks": "E-Bücher",
|
||||||
"LabelEdit": "Bearbeiten",
|
"LabelEdit": "Bearbeiten",
|
||||||
"LabelEmailSettingsFromAddress": "Von Adresse",
|
"LabelEmail": "E-Mail",
|
||||||
|
"LabelEmailSettingsFromAddress": "Sender",
|
||||||
"LabelEmailSettingsRejectUnauthorized": "Nicht autorisierte Zertifikate ablehnen",
|
"LabelEmailSettingsRejectUnauthorized": "Nicht autorisierte Zertifikate ablehnen",
|
||||||
"LabelEmailSettingsRejectUnauthorizedHelp": "Durch das Deaktivieren der SSL-Zertifikatsüberprüfung kann deine Verbindung Sicherheitsrisiken wie Man-in-the-Middle-Angriffen ausgesetzt sein. Deaktiviere diese Option nur, wenn due die Auswirkungen verstehst und dem Mailserver vertraust, mit dem eine Verbindung hergestellt wird.",
|
"LabelEmailSettingsRejectUnauthorizedHelp": "Durch das Deaktivieren der SSL-Zertifikatsüberprüfung kann deine Verbindung Sicherheitsrisiken wie Man-in-the-Middle-Angriffen ausgesetzt sein. Deaktiviere diese Option nur, wenn due die Auswirkungen verstehst und dem E-Mail-Server vertraust, mit dem eine Verbindung hergestellt wird.",
|
||||||
"LabelEmailSettingsSecure": "Sicher",
|
"LabelEmailSettingsSecure": "Sicher",
|
||||||
"LabelEmailSettingsSecureHelp": "Wenn \"an\", verwendet die Verbindung TLS, wenn du eine Verbindung zum Server herstellst. Bei \"aus\" wird TLS verwendet, wenn der Server die STARTTLS-Erweiterung unterstützt. In den meisten Fällen solltest du diesen Wert auf \"an\" schalten, wenn du eine Verbindung zu Port 465 herstellst. Für Port 587 oder 25 behalte den Wert \"aus\" bei. (von nodemailer.com/smtp/#authentication)",
|
"LabelEmailSettingsSecureHelp": "Wenn an, verwendet die Verbindung TLS, wenn du eine Verbindung zum Server herstellst. Bei „aus“ wird TLS verwendet, wenn der Server die STARTTLS-Erweiterung unterstützt. In den meisten Fällen solltest du diesen Wert auf „an“ schalten, wenn du eine Verbindung zu Port 465 herstellst. Für Port 587 oder 25 behalte den Wert „aus“ bei. (von nodemailer.com/smtp/#authentication)",
|
||||||
"LabelEmailSettingsTestAddress": "Test Adresse",
|
"LabelEmailSettingsTestAddress": "Test-Adresse",
|
||||||
"LabelEmbeddedCover": "Eingebettetes Cover",
|
"LabelEmbeddedCover": "Eingebettetes Cover",
|
||||||
"LabelEnable": "Aktivieren",
|
"LabelEnable": "Aktivieren",
|
||||||
|
"LabelEncodingBackupLocation": "Eine Sicherungskopie der originalen Audiodateien wird gespeichert in:",
|
||||||
|
"LabelEncodingChaptersNotEmbedded": "Kapitel sind in mehrspurigen Hörbüchern nicht eingebettet.",
|
||||||
|
"LabelEncodingClearItemCache": "Stelle sicher, dass der Cache regelmäßig geleert wird.",
|
||||||
|
"LabelEncodingFinishedM4B": "Die fertige M4B-Datei wird im Hörbuch-Ordner unter folgendem Pfad abgelegt:",
|
||||||
|
"LabelEncodingInfoEmbedded": "Metadaten werden in die Audiodateien innerhalb des Audiobook Ordners eingebunden.",
|
||||||
|
"LabelEncodingStartedNavigation": "Sobald die Aufgabe gestartet ist, kann die Seite verlassen werden.",
|
||||||
|
"LabelEncodingTimeWarning": "Kodierung kann bis zu 30 Minuten dauern.",
|
||||||
|
"LabelEncodingWarningAdvancedSettings": "Achtung: Ändere diese Einstellungen nur, wenn du dich mit ffmpeg Kodierung auskennst.",
|
||||||
"LabelEnd": "Ende",
|
"LabelEnd": "Ende",
|
||||||
"LabelEndOfChapter": "Ende des Kapitels",
|
"LabelEndOfChapter": "Ende des Kapitels",
|
||||||
|
"LabelEpisode": "Episode",
|
||||||
"LabelEpisodeTitle": "Episodentitel",
|
"LabelEpisodeTitle": "Episodentitel",
|
||||||
"LabelEpisodeType": "Episodentyp",
|
"LabelEpisodeType": "Episodentyp",
|
||||||
"LabelEpisodes": "Episoden",
|
"LabelEpisodes": "Episoden",
|
||||||
@@ -302,6 +329,7 @@
|
|||||||
"LabelExplicitChecked": "Explicit (Altersbeschränkung) (angehakt)",
|
"LabelExplicitChecked": "Explicit (Altersbeschränkung) (angehakt)",
|
||||||
"LabelExplicitUnchecked": "Not Explicit (Altersbeschränkung) (nicht angehakt)",
|
"LabelExplicitUnchecked": "Not Explicit (Altersbeschränkung) (nicht angehakt)",
|
||||||
"LabelExportOPML": "OPML exportieren",
|
"LabelExportOPML": "OPML exportieren",
|
||||||
|
"LabelFeedURL": "Feed-URL",
|
||||||
"LabelFetchingMetadata": "Abholen der Metadaten",
|
"LabelFetchingMetadata": "Abholen der Metadaten",
|
||||||
"LabelFile": "Datei",
|
"LabelFile": "Datei",
|
||||||
"LabelFileBirthtime": "Datei erstellt",
|
"LabelFileBirthtime": "Datei erstellt",
|
||||||
@@ -320,13 +348,15 @@
|
|||||||
"LabelFontItalic": "Kursiv",
|
"LabelFontItalic": "Kursiv",
|
||||||
"LabelFontScale": "Schriftgröße",
|
"LabelFontScale": "Schriftgröße",
|
||||||
"LabelFontStrikethrough": "Durchgestrichen",
|
"LabelFontStrikethrough": "Durchgestrichen",
|
||||||
|
"LabelFormat": "Format",
|
||||||
"LabelGenre": "Kategorie",
|
"LabelGenre": "Kategorie",
|
||||||
"LabelGenres": "Kategorien",
|
"LabelGenres": "Kategorien",
|
||||||
"LabelHardDeleteFile": "Datei dauerhaft löschen",
|
"LabelHardDeleteFile": "Datei dauerhaft löschen",
|
||||||
"LabelHasEbook": "E-Book verfügbar",
|
"LabelHasEbook": "E-Buch verfügbar",
|
||||||
"LabelHasSupplementaryEbook": "Ergänzendes E-Book verfügbar",
|
"LabelHasSupplementaryEbook": "Ergänzendes E-Buch verfügbar",
|
||||||
"LabelHideSubtitles": "Untertitel ausblenden",
|
"LabelHideSubtitles": "Untertitel ausblenden",
|
||||||
"LabelHighestPriority": "Höchste Priorität",
|
"LabelHighestPriority": "Höchste Priorität",
|
||||||
|
"LabelHost": "Anbieter",
|
||||||
"LabelHour": "Stunde",
|
"LabelHour": "Stunde",
|
||||||
"LabelHours": "Stunden",
|
"LabelHours": "Stunden",
|
||||||
"LabelIcon": "Symbol",
|
"LabelIcon": "Symbol",
|
||||||
@@ -355,12 +385,13 @@
|
|||||||
"LabelLastSeen": "Zuletzt gesehen",
|
"LabelLastSeen": "Zuletzt gesehen",
|
||||||
"LabelLastTime": "Letztes Mal",
|
"LabelLastTime": "Letztes Mal",
|
||||||
"LabelLastUpdate": "Letzte Aktualisierung",
|
"LabelLastUpdate": "Letzte Aktualisierung",
|
||||||
|
"LabelLayout": "Ansicht",
|
||||||
"LabelLayoutSinglePage": "Eine Seite",
|
"LabelLayoutSinglePage": "Eine Seite",
|
||||||
"LabelLayoutSplitPage": "Geteilte Seite",
|
"LabelLayoutSplitPage": "Geteilte Seite",
|
||||||
"LabelLess": "Weniger",
|
"LabelLess": "Weniger",
|
||||||
"LabelLibrariesAccessibleToUser": "Für Benutzer zugängliche Bibliotheken",
|
"LabelLibrariesAccessibleToUser": "Für Benutzer zugängliche Bibliotheken",
|
||||||
"LabelLibrary": "Bibliothek",
|
"LabelLibrary": "Bibliothek",
|
||||||
"LabelLibraryFilterSublistEmpty": "Nr. {0}",
|
"LabelLibraryFilterSublistEmpty": "Keine {0}",
|
||||||
"LabelLibraryItem": "Bibliothekseintrag",
|
"LabelLibraryItem": "Bibliothekseintrag",
|
||||||
"LabelLibraryName": "Bibliotheksname",
|
"LabelLibraryName": "Bibliotheksname",
|
||||||
"LabelLimit": "Begrenzung",
|
"LabelLimit": "Begrenzung",
|
||||||
@@ -376,16 +407,19 @@
|
|||||||
"LabelMediaPlayer": "Mediaplayer",
|
"LabelMediaPlayer": "Mediaplayer",
|
||||||
"LabelMediaType": "Medientyp",
|
"LabelMediaType": "Medientyp",
|
||||||
"LabelMetaTag": "Meta Schlagwort",
|
"LabelMetaTag": "Meta Schlagwort",
|
||||||
|
"LabelMetaTags": "Meta Tags",
|
||||||
"LabelMetadataOrderOfPrecedenceDescription": "Höher priorisierte Quellen für Metadaten überschreiben Metadaten aus Quellen mit niedrigerer Priorität",
|
"LabelMetadataOrderOfPrecedenceDescription": "Höher priorisierte Quellen für Metadaten überschreiben Metadaten aus Quellen mit niedrigerer Priorität",
|
||||||
"LabelMetadataProvider": "Metadatenanbieter",
|
"LabelMetadataProvider": "Metadatenanbieter",
|
||||||
|
"LabelMinute": "Minute",
|
||||||
"LabelMinutes": "Minuten",
|
"LabelMinutes": "Minuten",
|
||||||
"LabelMissing": "Fehlend",
|
"LabelMissing": "Fehlend",
|
||||||
"LabelMissingEbook": "E-Book fehlt",
|
"LabelMissingEbook": "E-Buch fehlt",
|
||||||
"LabelMissingSupplementaryEbook": "Ergänzendes E-Book fehlt",
|
"LabelMissingSupplementaryEbook": "Ergänzendes E-Buch fehlt",
|
||||||
"LabelMobileRedirectURIs": "Erlaubte Weiterleitungs-URIs für die mobile App",
|
"LabelMobileRedirectURIs": "Erlaubte Weiterleitungs-URIs für die mobile App",
|
||||||
"LabelMobileRedirectURIsDescription": "Dies ist eine Whitelist gültiger Umleitungs-URIs für mobile Apps. Der Standardwert ist <code>audiobookshelf://oauth</code>, den du entfernen oder durch zusätzliche URIs für die Integration von Drittanbieter-Apps ergänzen kannst. Die Verwendung eines Sternchens (<code>*</code>) als alleiniger Eintrag erlaubt jede URI.",
|
"LabelMobileRedirectURIsDescription": "Dies ist eine weiße Liste gültiger Umleitungs-URIs für mobile Apps. Der Standardwert ist <code>audiobookshelf://oauth</code>, den du entfernen oder durch zusätzliche URIs für die Integration von Drittanbieter-Apps ergänzen kannst. Die Verwendung eines Sternchens (<code>*</code>) als alleiniger Eintrag erlaubt jede URI.",
|
||||||
"LabelMore": "Mehr",
|
"LabelMore": "Mehr",
|
||||||
"LabelMoreInfo": "Mehr Infos",
|
"LabelMoreInfo": "Mehr Infos",
|
||||||
|
"LabelName": "Name",
|
||||||
"LabelNarrator": "Erzähler",
|
"LabelNarrator": "Erzähler",
|
||||||
"LabelNarrators": "Erzähler",
|
"LabelNarrators": "Erzähler",
|
||||||
"LabelNew": "Neu",
|
"LabelNew": "Neu",
|
||||||
@@ -399,6 +433,7 @@
|
|||||||
"LabelNotFinished": "Nicht beendet",
|
"LabelNotFinished": "Nicht beendet",
|
||||||
"LabelNotStarted": "Nicht begonnen",
|
"LabelNotStarted": "Nicht begonnen",
|
||||||
"LabelNotes": "Notizen",
|
"LabelNotes": "Notizen",
|
||||||
|
"LabelNotificationAppriseURL": "Apprise-URL(s)",
|
||||||
"LabelNotificationAvailableVariables": "Verfügbare Variablen",
|
"LabelNotificationAvailableVariables": "Verfügbare Variablen",
|
||||||
"LabelNotificationBodyTemplate": "Textvorlage",
|
"LabelNotificationBodyTemplate": "Textvorlage",
|
||||||
"LabelNotificationEvent": "Benachrichtigungs Event",
|
"LabelNotificationEvent": "Benachrichtigungs Event",
|
||||||
@@ -429,33 +464,40 @@
|
|||||||
"LabelPlayMethod": "Abspielmethode",
|
"LabelPlayMethod": "Abspielmethode",
|
||||||
"LabelPlayerChapterNumberMarker": "{0} von {1}",
|
"LabelPlayerChapterNumberMarker": "{0} von {1}",
|
||||||
"LabelPlaylists": "Wiedergabelisten",
|
"LabelPlaylists": "Wiedergabelisten",
|
||||||
|
"LabelPodcast": "Podcast",
|
||||||
"LabelPodcastSearchRegion": "Podcast-Suchregion",
|
"LabelPodcastSearchRegion": "Podcast-Suchregion",
|
||||||
"LabelPodcastType": "Podcast Typ",
|
"LabelPodcastType": "Podcast Typ",
|
||||||
|
"LabelPodcasts": "Podcasts",
|
||||||
|
"LabelPort": "Port",
|
||||||
"LabelPrefixesToIgnore": "Zu ignorierende(s) Vorwort(e) (Groß- und Kleinschreibung wird nicht berücksichtigt)",
|
"LabelPrefixesToIgnore": "Zu ignorierende(s) Vorwort(e) (Groß- und Kleinschreibung wird nicht berücksichtigt)",
|
||||||
"LabelPreventIndexing": "Verhindere, dass dein Feed von iTunes- und Google-Podcast-Verzeichnissen indiziert wird",
|
"LabelPreventIndexing": "Verhindere, dass dein Feed von iTunes- und Google-Podcast-Verzeichnissen indiziert wird",
|
||||||
"LabelPrimaryEbook": "Primäres E-Book",
|
"LabelPrimaryEbook": "Primäres E-Buch",
|
||||||
"LabelProgress": "Fortschritt",
|
"LabelProgress": "Fortschritt",
|
||||||
"LabelProvider": "Anbieter",
|
"LabelProvider": "Anbieter",
|
||||||
"LabelProviderAuthorizationValue": "Autorisierungsheader-Wert",
|
"LabelProviderAuthorizationValue": "Autorisierungsheader-Wert",
|
||||||
"LabelPubDate": "Veröffentlichungsdatum",
|
"LabelPubDate": "Veröffentlichungsdatum",
|
||||||
"LabelPublishYear": "Jahr",
|
"LabelPublishYear": "Jahr",
|
||||||
"LabelPublishedDate": "Veröffentlicht {0}",
|
"LabelPublishedDate": "Veröffentlicht {0}",
|
||||||
|
"LabelPublishedDecade": "Jahrzehnt",
|
||||||
|
"LabelPublishedDecades": "Jahrzehnte",
|
||||||
"LabelPublisher": "Herausgeber",
|
"LabelPublisher": "Herausgeber",
|
||||||
"LabelPublishers": "Herausgeber",
|
"LabelPublishers": "Herausgeber",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "Benutzerdefinierte Eigentümer-E-Mail",
|
"LabelRSSFeedCustomOwnerEmail": "Benutzerdefinierte Eigentümer-E-Mail",
|
||||||
"LabelRSSFeedCustomOwnerName": "Benutzerdefinierter Name des Eigentümers",
|
"LabelRSSFeedCustomOwnerName": "Benutzerdefinierter Name des Eigentümers",
|
||||||
"LabelRSSFeedOpen": "RSS Feed Offen",
|
"LabelRSSFeedOpen": "RSS Feed offen",
|
||||||
"LabelRSSFeedPreventIndexing": "Indizierung verhindern",
|
"LabelRSSFeedPreventIndexing": "Indizierung verhindern",
|
||||||
"LabelRSSFeedSlug": "RSS-Feed-Schlagwort",
|
"LabelRSSFeedSlug": "RSS-Feed-Schlagwort",
|
||||||
|
"LabelRSSFeedURL": "RSS-Feed-URL",
|
||||||
"LabelRandomly": "Zufällig",
|
"LabelRandomly": "Zufällig",
|
||||||
"LabelReAddSeriesToContinueListening": "Serien erneut zur Fortsetzungsliste hinzufügen",
|
"LabelReAddSeriesToContinueListening": "Serien erneut zur Fortsetzungsliste hinzufügen",
|
||||||
"LabelRead": "Lesen",
|
"LabelRead": "Lesen",
|
||||||
"LabelReadAgain": "Noch einmal Lesen",
|
"LabelReadAgain": "Noch einmal Lesen",
|
||||||
"LabelReadEbookWithoutProgress": "E-Book lesen und Fortschritt verwerfen",
|
"LabelReadEbookWithoutProgress": "E-Buch lesen und Fortschritt verwerfen",
|
||||||
"LabelRecentSeries": "Aktuelle Serien",
|
"LabelRecentSeries": "Aktuelle Serien",
|
||||||
"LabelRecentlyAdded": "Kürzlich hinzugefügt",
|
"LabelRecentlyAdded": "Kürzlich hinzugefügt",
|
||||||
"LabelRecommended": "Empfohlen",
|
"LabelRecommended": "Empfohlen",
|
||||||
"LabelRedo": "Wiederholen",
|
"LabelRedo": "Wiederholen",
|
||||||
|
"LabelRegion": "Region",
|
||||||
"LabelReleaseDate": "Veröffentlichungsdatum",
|
"LabelReleaseDate": "Veröffentlichungsdatum",
|
||||||
"LabelRemoveCover": "Entferne Titelbild",
|
"LabelRemoveCover": "Entferne Titelbild",
|
||||||
"LabelRowsPerPage": "Zeilen pro Seite",
|
"LabelRowsPerPage": "Zeilen pro Seite",
|
||||||
@@ -467,16 +509,17 @@
|
|||||||
"LabelSelectAllEpisodes": "Alle Episoden auswählen",
|
"LabelSelectAllEpisodes": "Alle Episoden auswählen",
|
||||||
"LabelSelectEpisodesShowing": "{0} ausgewählte Episoden werden angezeigt",
|
"LabelSelectEpisodesShowing": "{0} ausgewählte Episoden werden angezeigt",
|
||||||
"LabelSelectUsers": "Benutzer auswählen",
|
"LabelSelectUsers": "Benutzer auswählen",
|
||||||
"LabelSendEbookToDevice": "E-Book senden an...",
|
"LabelSendEbookToDevice": "E-Buch senden an …",
|
||||||
"LabelSequence": "Reihenfolge",
|
"LabelSequence": "Reihenfolge",
|
||||||
"LabelSeries": "Serien",
|
"LabelSeries": "Serien",
|
||||||
"LabelSeriesName": "Serienname",
|
"LabelSeriesName": "Serienname",
|
||||||
"LabelSeriesProgress": "Serienfortschritt",
|
"LabelSeriesProgress": "Serienfortschritt",
|
||||||
|
"LabelServerLogLevel": "Server Log Level",
|
||||||
"LabelServerYearReview": "Server Jahr in Übersicht ({0})",
|
"LabelServerYearReview": "Server Jahr in Übersicht ({0})",
|
||||||
"LabelSetEbookAsPrimary": "Als Hauptbuch setzen",
|
"LabelSetEbookAsPrimary": "Als Hauptbuch setzen",
|
||||||
"LabelSetEbookAsSupplementary": "Als Ergänzung setzen",
|
"LabelSetEbookAsSupplementary": "Als Ergänzung setzen",
|
||||||
"LabelSettingsAudiobooksOnly": "Nur Hörbücher",
|
"LabelSettingsAudiobooksOnly": "Nur Hörbücher",
|
||||||
"LabelSettingsAudiobooksOnlyHelp": "Wenn du diese Einstellung aktivierst, werden E-Book-Dateien ignoriert, es sei denn, sie befinden sich in einem Hörbuchordner. In diesem Fall werden sie als zusätzliche E-Books festgelegt",
|
"LabelSettingsAudiobooksOnlyHelp": "Wenn du diese Einstellung aktivierst, werden E-Buch-Dateien ignoriert, es sei denn, sie befinden sich in einem Hörbuchordner. In diesem Fall werden sie als zusätzliche E-Bücher festgelegt",
|
||||||
"LabelSettingsBookshelfViewHelp": "Skeumorphes Design mit Holzeinlegeböden",
|
"LabelSettingsBookshelfViewHelp": "Skeumorphes Design mit Holzeinlegeböden",
|
||||||
"LabelSettingsChromecastSupport": "Chromecastunterstützung",
|
"LabelSettingsChromecastSupport": "Chromecastunterstützung",
|
||||||
"LabelSettingsDateFormat": "Datumsformat",
|
"LabelSettingsDateFormat": "Datumsformat",
|
||||||
@@ -522,6 +565,7 @@
|
|||||||
"LabelSize": "Größe",
|
"LabelSize": "Größe",
|
||||||
"LabelSleepTimer": "Schlummerfunktion",
|
"LabelSleepTimer": "Schlummerfunktion",
|
||||||
"LabelSlug": "URL Teil",
|
"LabelSlug": "URL Teil",
|
||||||
|
"LabelStart": "Start",
|
||||||
"LabelStartTime": "Startzeit",
|
"LabelStartTime": "Startzeit",
|
||||||
"LabelStarted": "Gestartet",
|
"LabelStarted": "Gestartet",
|
||||||
"LabelStartedAt": "Gestartet am",
|
"LabelStartedAt": "Gestartet am",
|
||||||
@@ -539,7 +583,7 @@
|
|||||||
"LabelStatsMinutesListening": "Gehörte Minuten",
|
"LabelStatsMinutesListening": "Gehörte Minuten",
|
||||||
"LabelStatsOverallDays": "Gesamte Tage",
|
"LabelStatsOverallDays": "Gesamte Tage",
|
||||||
"LabelStatsOverallHours": "Gesamte Stunden",
|
"LabelStatsOverallHours": "Gesamte Stunden",
|
||||||
"LabelStatsWeekListening": "Gehörte Wochen",
|
"LabelStatsWeekListening": "Wochenhördauer",
|
||||||
"LabelSubtitle": "Untertitel",
|
"LabelSubtitle": "Untertitel",
|
||||||
"LabelSupportedFileTypes": "Unterstützte Dateitypen",
|
"LabelSupportedFileTypes": "Unterstützte Dateitypen",
|
||||||
"LabelTag": "Schlagwort",
|
"LabelTag": "Schlagwort",
|
||||||
@@ -548,6 +592,7 @@
|
|||||||
"LabelTagsNotAccessibleToUser": "Für Benutzer nicht zugängliche Schlagwörter",
|
"LabelTagsNotAccessibleToUser": "Für Benutzer nicht zugängliche Schlagwörter",
|
||||||
"LabelTasks": "Laufende Aufgaben",
|
"LabelTasks": "Laufende Aufgaben",
|
||||||
"LabelTextEditorBulletedList": "Aufzählungsliste",
|
"LabelTextEditorBulletedList": "Aufzählungsliste",
|
||||||
|
"LabelTextEditorLink": "Link",
|
||||||
"LabelTextEditorNumberedList": "nummerierte Liste",
|
"LabelTextEditorNumberedList": "nummerierte Liste",
|
||||||
"LabelTextEditorUnlink": "entkoppeln",
|
"LabelTextEditorUnlink": "entkoppeln",
|
||||||
"LabelTheme": "Farbschema",
|
"LabelTheme": "Farbschema",
|
||||||
@@ -565,9 +610,10 @@
|
|||||||
"LabelTitle": "Titel",
|
"LabelTitle": "Titel",
|
||||||
"LabelToolsEmbedMetadata": "Metadaten einbetten",
|
"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 Audiodatein ein.",
|
||||||
|
"LabelToolsM4bEncoder": "M4B Kodierer",
|
||||||
"LabelToolsMakeM4b": "M4B-Datei erstellen",
|
"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.",
|
"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.",
|
||||||
"LabelToolsSplitM4b": "M4B in MP3's aufteilen",
|
"LabelToolsSplitM4b": "M4B in MP3s aufteilen",
|
||||||
"LabelToolsSplitM4bDescription": "Erstellt aus einer mit Metadaten und nach Kapiteln aufgeteilten M4B-Datei seperate MP3's mit eingebetteten Metadaten, Coverbild und Kapiteln.",
|
"LabelToolsSplitM4bDescription": "Erstellt aus einer mit Metadaten und nach Kapiteln aufgeteilten M4B-Datei seperate MP3's mit eingebetteten Metadaten, Coverbild und Kapiteln.",
|
||||||
"LabelTotalDuration": "Gesamtdauer",
|
"LabelTotalDuration": "Gesamtdauer",
|
||||||
"LabelTotalTimeListened": "Gehörte Gesamtzeit",
|
"LabelTotalTimeListened": "Gehörte Gesamtzeit",
|
||||||
@@ -590,11 +636,13 @@
|
|||||||
"LabelUploaderDragAndDrop": "Ziehen und Ablegen von Dateien oder Ordnern",
|
"LabelUploaderDragAndDrop": "Ziehen und Ablegen von Dateien oder Ordnern",
|
||||||
"LabelUploaderDropFiles": "Dateien löschen",
|
"LabelUploaderDropFiles": "Dateien löschen",
|
||||||
"LabelUploaderItemFetchMetadataHelp": "Automatisches Aktualisieren von Titel, Autor und Serie",
|
"LabelUploaderItemFetchMetadataHelp": "Automatisches Aktualisieren von Titel, Autor und Serie",
|
||||||
|
"LabelUseAdvancedOptions": "Nutze Erweiterte Optionen",
|
||||||
"LabelUseChapterTrack": "Kapiteldatei verwenden",
|
"LabelUseChapterTrack": "Kapiteldatei verwenden",
|
||||||
"LabelUseFullTrack": "Gesamte Datei verwenden",
|
"LabelUseFullTrack": "Gesamte Datei verwenden",
|
||||||
"LabelUser": "Benutzer",
|
"LabelUser": "Benutzer",
|
||||||
"LabelUsername": "Benutzername",
|
"LabelUsername": "Benutzername",
|
||||||
"LabelValue": "Wert",
|
"LabelValue": "Wert",
|
||||||
|
"LabelVersion": "Version",
|
||||||
"LabelViewBookmarks": "Lesezeichen anzeigen",
|
"LabelViewBookmarks": "Lesezeichen anzeigen",
|
||||||
"LabelViewChapters": "Kapitel anzeigen",
|
"LabelViewChapters": "Kapitel anzeigen",
|
||||||
"LabelViewPlayerSettings": "Zeige player Einstellungen",
|
"LabelViewPlayerSettings": "Zeige player Einstellungen",
|
||||||
@@ -629,7 +677,7 @@
|
|||||||
"MessageCheckingCron": "Überprüfe Cron...",
|
"MessageCheckingCron": "Überprüfe Cron...",
|
||||||
"MessageConfirmCloseFeed": "Feed wird geschlossen! Bist du dir sicher?",
|
"MessageConfirmCloseFeed": "Feed wird geschlossen! Bist du dir sicher?",
|
||||||
"MessageConfirmDeleteBackup": "Sicherung für {0} wird gelöscht! Bist du dir sicher?",
|
"MessageConfirmDeleteBackup": "Sicherung für {0} wird gelöscht! Bist du dir sicher?",
|
||||||
"MessageConfirmDeleteDevice": "Möchtest Du das E-Reader-Gerät „{0}“ wirklich löschen?",
|
"MessageConfirmDeleteDevice": "Möchtest du das Lesegerät „{0}“ wirklich löschen?",
|
||||||
"MessageConfirmDeleteFile": "Datei wird vom System gelöscht! Bist du dir sicher?",
|
"MessageConfirmDeleteFile": "Datei wird vom System gelöscht! Bist du dir sicher?",
|
||||||
"MessageConfirmDeleteLibrary": "Bibliothek \"{0}\" wird dauerhaft gelöscht! Bist du dir sicher?",
|
"MessageConfirmDeleteLibrary": "Bibliothek \"{0}\" wird dauerhaft gelöscht! Bist du dir sicher?",
|
||||||
"MessageConfirmDeleteLibraryItem": "Bibliothekselement wird aus der Datenbank + Festplatte gelöscht? Bist du dir sicher?",
|
"MessageConfirmDeleteLibraryItem": "Bibliothekselement wird aus der Datenbank + Festplatte gelöscht? Bist du dir sicher?",
|
||||||
@@ -637,6 +685,7 @@
|
|||||||
"MessageConfirmDeleteMetadataProvider": "Möchtest du den benutzerdefinierten Metadatenanbieter \"{0}\" wirklich löschen?",
|
"MessageConfirmDeleteMetadataProvider": "Möchtest du den benutzerdefinierten Metadatenanbieter \"{0}\" wirklich löschen?",
|
||||||
"MessageConfirmDeleteNotification": "Möchtest du diese Benachrichtigung wirklich löschen?",
|
"MessageConfirmDeleteNotification": "Möchtest du diese Benachrichtigung wirklich löschen?",
|
||||||
"MessageConfirmDeleteSession": "Sitzung wird gelöscht! Bist du dir sicher?",
|
"MessageConfirmDeleteSession": "Sitzung wird gelöscht! Bist du dir sicher?",
|
||||||
|
"MessageConfirmEmbedMetadataInAudioFiles": "Bist du dir sicher, dass die Metadaten in {0} Audiodateien eingebettet werden sollen?",
|
||||||
"MessageConfirmForceReScan": "Scanvorgang erzwingen! Bist du dir sicher?",
|
"MessageConfirmForceReScan": "Scanvorgang erzwingen! Bist du dir sicher?",
|
||||||
"MessageConfirmMarkAllEpisodesFinished": "Alle Episoden werden als abgeschlossen markiert! Bist du dir sicher?",
|
"MessageConfirmMarkAllEpisodesFinished": "Alle Episoden werden als abgeschlossen markiert! Bist du dir sicher?",
|
||||||
"MessageConfirmMarkAllEpisodesNotFinished": "Alle Episoden werden als nicht abgeschlossen markiert! Bist du dir sicher?",
|
"MessageConfirmMarkAllEpisodesNotFinished": "Alle Episoden werden als nicht abgeschlossen markiert! Bist du dir sicher?",
|
||||||
@@ -664,14 +713,14 @@
|
|||||||
"MessageConfirmRenameTagMergeNote": "Hinweis: Tag existiert bereits -> Tags werden zusammengelegt.",
|
"MessageConfirmRenameTagMergeNote": "Hinweis: Tag existiert bereits -> Tags werden zusammengelegt.",
|
||||||
"MessageConfirmRenameTagWarning": "Warnung! Ein ähnlicher Tag mit einem anderen Wortlaut existiert bereits: \"{0}\".",
|
"MessageConfirmRenameTagWarning": "Warnung! Ein ähnlicher Tag mit einem anderen Wortlaut existiert bereits: \"{0}\".",
|
||||||
"MessageConfirmResetProgress": "Möchtest du Ihren Fortschritt wirklich zurücksetzen?",
|
"MessageConfirmResetProgress": "Möchtest du Ihren Fortschritt wirklich zurücksetzen?",
|
||||||
"MessageConfirmSendEbookToDevice": "{0} E-Book \"{1}\" wird auf das Gerät \"{2}\" gesendet! Bist du dir sicher?",
|
"MessageConfirmSendEbookToDevice": "{0} E-Buch „{1}“ wird auf das Gerät „{2}“ gesendet! Bist du dir sicher?",
|
||||||
"MessageConfirmUnlinkOpenId": "Möchtest du die Verknüpfung dieses Benutzers mit OpenID wirklich löschen?",
|
"MessageConfirmUnlinkOpenId": "Möchtest du die Verknüpfung dieses Benutzers mit OpenID wirklich löschen?",
|
||||||
"MessageDownloadingEpisode": "Episode wird heruntergeladen",
|
"MessageDownloadingEpisode": "Episode wird heruntergeladen",
|
||||||
"MessageDragFilesIntoTrackOrder": "Verschiebe die Dateien in die richtige Reihenfolge",
|
"MessageDragFilesIntoTrackOrder": "Verschiebe die Dateien in die richtige Reihenfolge",
|
||||||
"MessageEmbedFailed": "Einbetten fehlgeschlagen!",
|
"MessageEmbedFailed": "Einbetten fehlgeschlagen!",
|
||||||
"MessageEmbedFinished": "Einbettung abgeschlossen!",
|
"MessageEmbedFinished": "Einbettung abgeschlossen!",
|
||||||
"MessageEpisodesQueuedForDownload": "{0} Episode(n) in der Warteschlange zum Herunterladen",
|
"MessageEpisodesQueuedForDownload": "{0} Episode(n) in der Warteschlange zum Herunterladen",
|
||||||
"MessageEreaderDevices": "Um die Zustellung von E-Books sicherzustellen, musst du eventuell die oben genannte E-Mail-Adresse als gültigen Absender für jedes unten aufgeführte Gerät hinzufügen.",
|
"MessageEreaderDevices": "Um die Zustellung von E-Büchern sicherzustellen, musst du eventuell die oben genannte E-Mail-Adresse als gültigen Absender für jedes unten aufgeführte Gerät hinzufügen.",
|
||||||
"MessageFeedURLWillBe": "Feed-URL wird {0} sein",
|
"MessageFeedURLWillBe": "Feed-URL wird {0} sein",
|
||||||
"MessageFetching": "Wird abgerufen …",
|
"MessageFetching": "Wird abgerufen …",
|
||||||
"MessageForceReScanDescription": "Durchsucht alle Dateien erneut, wie bei einem frischen Scan. ID3-Tags von Audiodateien, OPF-Dateien und Textdateien werden neu durchsucht.",
|
"MessageForceReScanDescription": "Durchsucht alle Dateien erneut, wie bei einem frischen Scan. ID3-Tags von Audiodateien, OPF-Dateien und Textdateien werden neu durchsucht.",
|
||||||
@@ -714,6 +763,7 @@
|
|||||||
"MessageNoLogs": "Keine Protokolle",
|
"MessageNoLogs": "Keine Protokolle",
|
||||||
"MessageNoMediaProgress": "Kein Medienfortschritt",
|
"MessageNoMediaProgress": "Kein Medienfortschritt",
|
||||||
"MessageNoNotifications": "Keine Benachrichtigungen",
|
"MessageNoNotifications": "Keine Benachrichtigungen",
|
||||||
|
"MessageNoPodcastFeed": "Ungültiger Podcast: Kein Feed",
|
||||||
"MessageNoPodcastsFound": "Keine Podcasts gefunden",
|
"MessageNoPodcastsFound": "Keine Podcasts gefunden",
|
||||||
"MessageNoResults": "Keine Ergebnisse",
|
"MessageNoResults": "Keine Ergebnisse",
|
||||||
"MessageNoSearchResultsFor": "Keine Suchergebnisse für \"{0}\"",
|
"MessageNoSearchResultsFor": "Keine Suchergebnisse für \"{0}\"",
|
||||||
@@ -747,6 +797,38 @@
|
|||||||
"MessageShareExpiresIn": "Läuft in {0} ab",
|
"MessageShareExpiresIn": "Läuft in {0} ab",
|
||||||
"MessageShareURLWillBe": "Der Freigabe Link wird <strong>{0}</strong> sein.",
|
"MessageShareURLWillBe": "Der Freigabe Link wird <strong>{0}</strong> sein.",
|
||||||
"MessageStartPlaybackAtTime": "Start der Wiedergabe für \"{0}\" bei {1}?",
|
"MessageStartPlaybackAtTime": "Start der Wiedergabe für \"{0}\" bei {1}?",
|
||||||
|
"MessageTaskAudioFileNotWritable": "Die Audiodatei \"{0}\" ist schreibgeschützt",
|
||||||
|
"MessageTaskCanceledByUser": "Aufgabe vom Benutzer abgebrochen",
|
||||||
|
"MessageTaskDownloadingEpisodeDescription": "Folge \"{0}\" wird heruntergeladen",
|
||||||
|
"MessageTaskEmbeddingMetadata": "Metadaten werden eingebettet",
|
||||||
|
"MessageTaskEmbeddingMetadataDescription": "Metadaten werden in Hörbuch \"{0}\" eingebettet",
|
||||||
|
"MessageTaskEncodingM4b": "M4B wird encodiert",
|
||||||
|
"MessageTaskEncodingM4bDescription": "Hörbuch \"{0}\" wird in eine einzelne m4b Datei encodiert",
|
||||||
|
"MessageTaskFailed": "Fehlgeschlagen",
|
||||||
|
"MessageTaskFailedToBackupAudioFile": "Sicherung der Audiodatei \"{0}\" fehlgeschlagen",
|
||||||
|
"MessageTaskFailedToCreateCacheDirectory": "Fehler beim erstellen des Cache-Verzeichnisses",
|
||||||
|
"MessageTaskFailedToEmbedMetadataInFile": "Einbetten der Metadaten in die Datei \"{0}\" fehlgeschlagen",
|
||||||
|
"MessageTaskFailedToMergeAudioFiles": "Fehler beim zusammenführen der Audiodateien",
|
||||||
|
"MessageTaskFailedToMoveM4bFile": "Fehler beim verschieben der m4b Datei",
|
||||||
|
"MessageTaskFailedToWriteMetadataFile": "Fehler beim schreiben der Metadaten-Datei",
|
||||||
|
"MessageTaskMatchingBooksInLibrary": "Vergleiche Bücher in Bibliothek \"{0}\"",
|
||||||
|
"MessageTaskNoFilesToScan": "Keine Dateien zum scannen",
|
||||||
|
"MessageTaskOpmlImport": "OPML-Import",
|
||||||
|
"MessageTaskOpmlImportDescription": "Podcasts von {0} RSS-Feeds werden ersrtellt",
|
||||||
|
"MessageTaskOpmlImportFeed": "OPML-Feed importieren",
|
||||||
|
"MessageTaskOpmlImportFeedDescription": "RSS-Feed \"{0}\" wird importiert",
|
||||||
|
"MessageTaskOpmlImportFeedFailed": "Podcast Feed konnte nicht geladen werden",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastDescription": "Podcast \"{0}\" wird erstellt",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastExists": "Der Podcast ist bereits im Pfad vorhanden",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastFailed": "Erstellen des Podcasts fehlgeschlagen",
|
||||||
|
"MessageTaskOpmlImportFinished": "{0} Podcasts hinzugefügt",
|
||||||
|
"MessageTaskScanItemsAdded": "{0} hinzugefügt",
|
||||||
|
"MessageTaskScanItemsMissing": "{0} fehlend",
|
||||||
|
"MessageTaskScanItemsUpdated": "{0} aktualisiert",
|
||||||
|
"MessageTaskScanNoChangesNeeded": "Keine Änderungen nötig",
|
||||||
|
"MessageTaskScanningFileChanges": "Überprüfe \"{0}\" nach geänderten Dateien",
|
||||||
|
"MessageTaskScanningLibrary": "Bibliothek \"{0}\" wird durchsucht",
|
||||||
|
"MessageTaskTargetDirectoryNotWritable": "Das Zielverzeichnis ist schreibgeschützt",
|
||||||
"MessageThinking": "Nachdenken...",
|
"MessageThinking": "Nachdenken...",
|
||||||
"MessageUploaderItemFailed": "Hochladen fehlgeschlagen",
|
"MessageUploaderItemFailed": "Hochladen fehlgeschlagen",
|
||||||
"MessageUploaderItemSuccess": "Erfolgreich hochgeladen!",
|
"MessageUploaderItemSuccess": "Erfolgreich hochgeladen!",
|
||||||
@@ -780,19 +862,19 @@
|
|||||||
"StatsSpentListening": "zugehört",
|
"StatsSpentListening": "zugehört",
|
||||||
"StatsTopAuthor": "TOP AUTOR",
|
"StatsTopAuthor": "TOP AUTOR",
|
||||||
"StatsTopAuthors": "TOP AUTOREN",
|
"StatsTopAuthors": "TOP AUTOREN",
|
||||||
|
"StatsTopGenre": "TOP GENRE",
|
||||||
|
"StatsTopGenres": "TOP GENRES",
|
||||||
"StatsTopMonth": "TOP MONAT",
|
"StatsTopMonth": "TOP MONAT",
|
||||||
"StatsTopNarrator": "TOP SPRECHER",
|
"StatsTopNarrator": "TOP SPRECHER",
|
||||||
"StatsTopNarrators": "TOP SPRECHER",
|
"StatsTopNarrators": "TOP SPRECHER",
|
||||||
"StatsTotalDuration": "Mit einer totalen Dauer von…",
|
"StatsTotalDuration": "Mit einer totalen Dauer von…",
|
||||||
"StatsYearInReview": "DAS JAHR IM RÜCKBLICK",
|
"StatsYearInReview": "DAS JAHR IM RÜCKBLICK",
|
||||||
"ToastAccountUpdateFailed": "Aktualisierung des Kontos fehlgeschlagen",
|
|
||||||
"ToastAccountUpdateSuccess": "Konto aktualisiert",
|
"ToastAccountUpdateSuccess": "Konto aktualisiert",
|
||||||
"ToastAppriseUrlRequired": "Eine Apprise-URL ist notwendig",
|
"ToastAppriseUrlRequired": "Eine Apprise-URL ist notwendig",
|
||||||
"ToastAuthorImageRemoveSuccess": "Autorenbild entfernt",
|
"ToastAuthorImageRemoveSuccess": "Autorenbild entfernt",
|
||||||
"ToastAuthorNotFound": "Autor \"{0}\" nicht gefunden",
|
"ToastAuthorNotFound": "Autor \"{0}\" nicht gefunden",
|
||||||
"ToastAuthorRemoveSuccess": "Autor entfernt",
|
"ToastAuthorRemoveSuccess": "Autor entfernt",
|
||||||
"ToastAuthorSearchNotFound": "Autor nicht gefunden",
|
"ToastAuthorSearchNotFound": "Autor nicht gefunden",
|
||||||
"ToastAuthorUpdateFailed": "Aktualisierung des Autors fehlgeschlagen",
|
|
||||||
"ToastAuthorUpdateMerged": "Autor zusammengeführt",
|
"ToastAuthorUpdateMerged": "Autor zusammengeführt",
|
||||||
"ToastAuthorUpdateSuccess": "Autor aktualisiert",
|
"ToastAuthorUpdateSuccess": "Autor aktualisiert",
|
||||||
"ToastAuthorUpdateSuccessNoImageFound": "Autor aktualisiert (kein Bild gefunden)",
|
"ToastAuthorUpdateSuccessNoImageFound": "Autor aktualisiert (kein Bild gefunden)",
|
||||||
@@ -803,7 +885,6 @@
|
|||||||
"ToastBackupDeleteSuccess": "Sicherung gelöscht",
|
"ToastBackupDeleteSuccess": "Sicherung gelöscht",
|
||||||
"ToastBackupInvalidMaxKeep": "Ungültige Anzahl aufzubewahrender Backups",
|
"ToastBackupInvalidMaxKeep": "Ungültige Anzahl aufzubewahrender Backups",
|
||||||
"ToastBackupInvalidMaxSize": "Ungültige maximale Backupgröße",
|
"ToastBackupInvalidMaxSize": "Ungültige maximale Backupgröße",
|
||||||
"ToastBackupPathUpdateFailed": "Der Backuppfad konnte nicht aktualisiert werden",
|
|
||||||
"ToastBackupRestoreFailed": "Sicherung konnte nicht wiederhergestellt werden",
|
"ToastBackupRestoreFailed": "Sicherung konnte nicht wiederhergestellt werden",
|
||||||
"ToastBackupUploadFailed": "Sicherung konnte nicht hochgeladen werden",
|
"ToastBackupUploadFailed": "Sicherung konnte nicht hochgeladen werden",
|
||||||
"ToastBackupUploadSuccess": "Sicherung hochgeladen",
|
"ToastBackupUploadSuccess": "Sicherung hochgeladen",
|
||||||
@@ -814,7 +895,6 @@
|
|||||||
"ToastBookmarkCreateFailed": "Lesezeichen konnte nicht erstellt werden",
|
"ToastBookmarkCreateFailed": "Lesezeichen konnte nicht erstellt werden",
|
||||||
"ToastBookmarkCreateSuccess": "Lesezeichen hinzugefügt",
|
"ToastBookmarkCreateSuccess": "Lesezeichen hinzugefügt",
|
||||||
"ToastBookmarkRemoveSuccess": "Lesezeichen entfernt",
|
"ToastBookmarkRemoveSuccess": "Lesezeichen entfernt",
|
||||||
"ToastBookmarkUpdateFailed": "Lesezeichenaktualisierung fehlgeschlagen",
|
|
||||||
"ToastBookmarkUpdateSuccess": "Lesezeichen aktualisiert",
|
"ToastBookmarkUpdateSuccess": "Lesezeichen aktualisiert",
|
||||||
"ToastCachePurgeFailed": "Cache leeren fehlgeschlagen",
|
"ToastCachePurgeFailed": "Cache leeren fehlgeschlagen",
|
||||||
"ToastCachePurgeSuccess": "Cache geleert",
|
"ToastCachePurgeSuccess": "Cache geleert",
|
||||||
@@ -825,7 +905,6 @@
|
|||||||
"ToastCollectionItemsAddSuccess": "Element(e) erfolgreich zur Sammlung hinzugefügt",
|
"ToastCollectionItemsAddSuccess": "Element(e) erfolgreich zur Sammlung hinzugefügt",
|
||||||
"ToastCollectionItemsRemoveSuccess": "Medien aus der Sammlung entfernt",
|
"ToastCollectionItemsRemoveSuccess": "Medien aus der Sammlung entfernt",
|
||||||
"ToastCollectionRemoveSuccess": "Sammlung entfernt",
|
"ToastCollectionRemoveSuccess": "Sammlung entfernt",
|
||||||
"ToastCollectionUpdateFailed": "Sammlung konnte nicht aktualisiert werden",
|
|
||||||
"ToastCollectionUpdateSuccess": "Sammlung aktualisiert",
|
"ToastCollectionUpdateSuccess": "Sammlung aktualisiert",
|
||||||
"ToastCoverUpdateFailed": "Cover-Update fehlgeschlagen",
|
"ToastCoverUpdateFailed": "Cover-Update fehlgeschlagen",
|
||||||
"ToastDeleteFileFailed": "Die Datei konnte nicht gelöscht werden",
|
"ToastDeleteFileFailed": "Die Datei konnte nicht gelöscht werden",
|
||||||
@@ -833,9 +912,7 @@
|
|||||||
"ToastDeviceAddFailed": "Gerät konnte nicht hinzugefügt werden",
|
"ToastDeviceAddFailed": "Gerät konnte nicht hinzugefügt werden",
|
||||||
"ToastDeviceNameAlreadyExists": "E-Reader-Gerät mit diesem Namen existiert bereits",
|
"ToastDeviceNameAlreadyExists": "E-Reader-Gerät mit diesem Namen existiert bereits",
|
||||||
"ToastDeviceTestEmailFailed": "Senden der Test-E-Mail fehlgeschlagen",
|
"ToastDeviceTestEmailFailed": "Senden der Test-E-Mail fehlgeschlagen",
|
||||||
"ToastDeviceTestEmailSuccess": "Test-E-Mail versand",
|
"ToastDeviceTestEmailSuccess": "Test-E-Mail gesendet",
|
||||||
"ToastDeviceUpdateFailed": "Das Gerät konnte nicht aktualisiert werden",
|
|
||||||
"ToastEmailSettingsUpdateFailed": "E-Mail-Einstellungen konnten nicht aktualisiert werden",
|
|
||||||
"ToastEmailSettingsUpdateSuccess": "E-Mail-Einstellungen aktualisiert",
|
"ToastEmailSettingsUpdateSuccess": "E-Mail-Einstellungen aktualisiert",
|
||||||
"ToastEncodeCancelFailed": "Das Encoding konnte nicht abgebrochen werden",
|
"ToastEncodeCancelFailed": "Das Encoding konnte nicht abgebrochen werden",
|
||||||
"ToastEncodeCancelSucces": "Encoding abgebrochen",
|
"ToastEncodeCancelSucces": "Encoding abgebrochen",
|
||||||
@@ -843,50 +920,94 @@
|
|||||||
"ToastEpisodeDownloadQueueClearSuccess": "Warteschlange für Episoden-Downloads gelöscht",
|
"ToastEpisodeDownloadQueueClearSuccess": "Warteschlange für Episoden-Downloads gelöscht",
|
||||||
"ToastErrorCannotShare": "Das kann nicht nativ auf diesem Gerät freigegeben werden",
|
"ToastErrorCannotShare": "Das kann nicht nativ auf diesem Gerät freigegeben werden",
|
||||||
"ToastFailedToLoadData": "Daten laden fehlgeschlagen",
|
"ToastFailedToLoadData": "Daten laden fehlgeschlagen",
|
||||||
"ToastItemCoverUpdateFailed": "Fehler bei der Aktualisierung des Titelbildes",
|
"ToastFailedToShare": "Fehler beim Teilen",
|
||||||
|
"ToastFailedToUpdate": "Aktualisierung ist fehlgeschlagen",
|
||||||
|
"ToastInvalidImageUrl": "Ungültiger Bild URL",
|
||||||
|
"ToastInvalidUrl": "Ungültiger URL",
|
||||||
"ToastItemCoverUpdateSuccess": "Titelbild aktualisiert",
|
"ToastItemCoverUpdateSuccess": "Titelbild aktualisiert",
|
||||||
"ToastItemDetailsUpdateFailed": "Fehler bei der Aktualisierung der Artikeldetails",
|
"ToastItemDeletedFailed": "Fehler beim löschen des Artikels",
|
||||||
|
"ToastItemDeletedSuccess": "Artikel gelöscht",
|
||||||
"ToastItemDetailsUpdateSuccess": "Artikeldetails aktualisiert",
|
"ToastItemDetailsUpdateSuccess": "Artikeldetails aktualisiert",
|
||||||
"ToastItemMarkedAsFinishedFailed": "Fehler bei der Markierung des Mediums als \"Beendet\"",
|
"ToastItemMarkedAsFinishedFailed": "Fehler bei der Markierung des Artikels als \"Beendet\"",
|
||||||
"ToastItemMarkedAsFinishedSuccess": "Medium als \"Beendet\" markiert",
|
"ToastItemMarkedAsFinishedSuccess": "Artikel als \"Beendet\" markiert",
|
||||||
"ToastItemMarkedAsNotFinishedFailed": "Fehler bei der Markierung des Mediums als \"Nicht Beendet\"",
|
"ToastItemMarkedAsNotFinishedFailed": "Fehler bei der Markierung des Artikels als \"Nicht Beendet\"",
|
||||||
"ToastItemMarkedAsNotFinishedSuccess": "Medium als \"Nicht Beendet\" markiert",
|
"ToastItemMarkedAsNotFinishedSuccess": "Artikel als \"Nicht Beendet\" markiert",
|
||||||
|
"ToastItemUpdateSuccess": "Artikel wurde verändert",
|
||||||
"ToastLibraryCreateFailed": "Bibliothek konnte nicht erstellt werden",
|
"ToastLibraryCreateFailed": "Bibliothek konnte nicht erstellt werden",
|
||||||
"ToastLibraryCreateSuccess": "Bibliothek \"{0}\" erstellt",
|
"ToastLibraryCreateSuccess": "Bibliothek \"{0}\" erstellt",
|
||||||
"ToastLibraryDeleteFailed": "Bibliothek konnte nicht gelöscht werden",
|
"ToastLibraryDeleteFailed": "Bibliothek konnte nicht gelöscht werden",
|
||||||
"ToastLibraryDeleteSuccess": "Bibliothek gelöscht",
|
"ToastLibraryDeleteSuccess": "Bibliothek gelöscht",
|
||||||
"ToastLibraryScanFailedToStart": "Scan konnte nicht gestartet werden",
|
"ToastLibraryScanFailedToStart": "Scan konnte nicht gestartet werden",
|
||||||
"ToastLibraryScanStarted": "Bibliotheksscan gestartet",
|
"ToastLibraryScanStarted": "Bibliotheksscan gestartet",
|
||||||
"ToastLibraryUpdateFailed": "Aktualisierung der Bibliothek fehlgeschlagen",
|
|
||||||
"ToastLibraryUpdateSuccess": "Bibliothek \"{0}\" aktualisiert",
|
"ToastLibraryUpdateSuccess": "Bibliothek \"{0}\" aktualisiert",
|
||||||
|
"ToastMatchAllAuthorsFailed": "Nicht alle Autoren konnten zugeordnet werden",
|
||||||
|
"ToastNameEmailRequired": "Name und E-Mail sind erforderlich",
|
||||||
|
"ToastNameRequired": "Name ist erforderlich",
|
||||||
|
"ToastNewUserCreatedFailed": "Fehler beim erstellen des Accounts: \"{ 0}\"",
|
||||||
|
"ToastNewUserCreatedSuccess": "Neuer Account erstellt",
|
||||||
|
"ToastNewUserLibraryError": "Mindestens eine Bibliothek muss ausgewählt werden",
|
||||||
|
"ToastNewUserPasswordError": "Passwort erforderlich, nur der root Benutzer darf ein leeres Passwort haben",
|
||||||
|
"ToastNewUserTagError": "Mindestens ein Tag muss ausgewählt sein",
|
||||||
|
"ToastNewUserUsernameError": "Nutzername eingeben",
|
||||||
|
"ToastNoUpdatesNecessary": "Keine Änderungen nötig",
|
||||||
|
"ToastNotificationCreateFailed": "Fehler beim erstellen der Benachrichtig",
|
||||||
|
"ToastNotificationDeleteFailed": "Fehler beim löschen der Benachrichtigung",
|
||||||
|
"ToastNotificationFailedMaximum": "Maximale Fehlversuche muss >= 0 sein",
|
||||||
|
"ToastNotificationQueueMaximum": "Maximale Benachrichtigungswarteschlange muss >= 0 sein",
|
||||||
|
"ToastNotificationSettingsUpdateSuccess": "Benachrichtigungseinstellungen geändert",
|
||||||
|
"ToastNotificationTestTriggerFailed": "Fehler beim Auslösen der Testbenachrichtigung",
|
||||||
|
"ToastNotificationTestTriggerSuccess": "Testbenachrichtigung ausgelöst",
|
||||||
|
"ToastNotificationUpdateSuccess": "Benachrichtigung geändert",
|
||||||
"ToastPlaylistCreateFailed": "Erstellen der Wiedergabeliste fehlgeschlagen",
|
"ToastPlaylistCreateFailed": "Erstellen der Wiedergabeliste fehlgeschlagen",
|
||||||
"ToastPlaylistCreateSuccess": "Wiedergabeliste erstellt",
|
"ToastPlaylistCreateSuccess": "Wiedergabeliste erstellt",
|
||||||
"ToastPlaylistRemoveSuccess": "Wiedergabeliste gelöscht",
|
"ToastPlaylistRemoveSuccess": "Wiedergabeliste gelöscht",
|
||||||
"ToastPlaylistUpdateFailed": "Aktualisieren der Wiedergabeliste fehlgeschlagen",
|
|
||||||
"ToastPlaylistUpdateSuccess": "Wiedergabeliste aktualisiert",
|
"ToastPlaylistUpdateSuccess": "Wiedergabeliste aktualisiert",
|
||||||
"ToastPodcastCreateFailed": "Podcast konnte nicht erstellt werden",
|
"ToastPodcastCreateFailed": "Podcast konnte nicht erstellt werden",
|
||||||
"ToastPodcastCreateSuccess": "Podcast erstellt",
|
"ToastPodcastCreateSuccess": "Podcast erstellt",
|
||||||
|
"ToastPodcastGetFeedFailed": "Fehler beim abrufen des Podcast Feeds",
|
||||||
|
"ToastPodcastNoEpisodesInFeed": "Keine Episoden in RSS Feed gefunden",
|
||||||
|
"ToastPodcastNoRssFeed": "Podcast enthält keinen RSS Feed",
|
||||||
|
"ToastProviderCreatedFailed": "Fehler beim hinzufügen des Anbieters",
|
||||||
"ToastProviderCreatedSuccess": "Neuer Anbieter hinzugefügt",
|
"ToastProviderCreatedSuccess": "Neuer Anbieter hinzugefügt",
|
||||||
"ToastProviderNameAndUrlRequired": "Name und URL notwendig",
|
"ToastProviderNameAndUrlRequired": "Name und URL notwendig",
|
||||||
"ToastProviderRemoveSuccess": "Anbieter entfernt",
|
"ToastProviderRemoveSuccess": "Anbieter entfernt",
|
||||||
"ToastRSSFeedCloseFailed": "RSS-Feed konnte nicht geschlossen werden",
|
"ToastRSSFeedCloseFailed": "RSS-Feed konnte nicht geschlossen werden",
|
||||||
"ToastRSSFeedCloseSuccess": "RSS-Feed geschlossen",
|
"ToastRSSFeedCloseSuccess": "RSS-Feed geschlossen",
|
||||||
|
"ToastRemoveFailed": "Fehler beim entfernen",
|
||||||
"ToastRemoveItemFromCollectionFailed": "Löschen des Mediums aus der Sammlung fehlgeschlagen",
|
"ToastRemoveItemFromCollectionFailed": "Löschen des Mediums aus der Sammlung fehlgeschlagen",
|
||||||
"ToastRemoveItemFromCollectionSuccess": "Medium aus der Sammlung gelöscht",
|
"ToastRemoveItemFromCollectionSuccess": "Medium aus der Sammlung gelöscht",
|
||||||
"ToastSendEbookToDeviceFailed": "E-Book konnte nicht auf Gerät übertragen werden",
|
"ToastRemoveItemsWithIssuesFailed": "Entfernen von fehlerhaften Bibliotheksartikeln fehlgeschlagenen",
|
||||||
"ToastSendEbookToDeviceSuccess": "E-Book an Gerät \"{0}\" gesendet",
|
"ToastRemoveItemsWithIssuesSuccess": "Fehlerhafte Bibliotheksartikel entfernt",
|
||||||
|
"ToastRenameFailed": "Umbenennen fehlgeschlagen",
|
||||||
|
"ToastRescanFailed": "Erneut scannen fehlgeschlagen für {0}",
|
||||||
|
"ToastRescanRemoved": "Erneut scannen erledigt, Artikel wurde entfernt",
|
||||||
|
"ToastRescanUpToDate": "Erneut scannen erledigt, Artikel wahr auf dem neusten Stand",
|
||||||
|
"ToastRescanUpdated": "Erneut scannen erledigt, Artikel wurde verändert",
|
||||||
|
"ToastScanFailed": "Fehler beim scannen des Artikels der Bibliothek",
|
||||||
|
"ToastSelectAtLeastOneUser": "Wähle mindestens einen Benutzer aus",
|
||||||
|
"ToastSendEbookToDeviceFailed": "E-Buch konnte nicht auf Gerät übertragen werden",
|
||||||
|
"ToastSendEbookToDeviceSuccess": "E-Buch an Gerät „{0}“ gesendet",
|
||||||
"ToastSeriesUpdateFailed": "Aktualisierung der Serien fehlgeschlagen",
|
"ToastSeriesUpdateFailed": "Aktualisierung der Serien fehlgeschlagen",
|
||||||
"ToastSeriesUpdateSuccess": "Serien aktualisiert",
|
"ToastSeriesUpdateSuccess": "Serien aktualisiert",
|
||||||
"ToastServerSettingsUpdateFailed": "Die Server-Einstellungen wurden nicht gespeichert",
|
|
||||||
"ToastServerSettingsUpdateSuccess": "Die Server-Einstellungen wurden geupdated",
|
"ToastServerSettingsUpdateSuccess": "Die Server-Einstellungen wurden geupdated",
|
||||||
|
"ToastSessionCloseFailed": "Fehler beim schließen der Sitzung",
|
||||||
"ToastSessionDeleteFailed": "Sitzung konnte nicht gelöscht werden",
|
"ToastSessionDeleteFailed": "Sitzung konnte nicht gelöscht werden",
|
||||||
"ToastSessionDeleteSuccess": "Sitzung gelöscht",
|
"ToastSessionDeleteSuccess": "Sitzung gelöscht",
|
||||||
|
"ToastSlugMustChange": "URL-Schlüssel enthält ungültige Zeichen",
|
||||||
|
"ToastSlugRequired": "URL-Schlüssel erforderlich",
|
||||||
"ToastSocketConnected": "Verbindung zum WebSocket hergestellt",
|
"ToastSocketConnected": "Verbindung zum WebSocket hergestellt",
|
||||||
"ToastSocketDisconnected": "Verbindung zum WebSocket verloren",
|
"ToastSocketDisconnected": "Verbindung zum WebSocket verloren",
|
||||||
"ToastSocketFailedToConnect": "Verbindung zum WebSocket fehlgeschlagen",
|
"ToastSocketFailedToConnect": "Verbindung zum WebSocket fehlgeschlagen",
|
||||||
"ToastSortingPrefixesEmptyError": "Es muss mindestens ein Sortier-Prefix vorhanden sein",
|
"ToastSortingPrefixesEmptyError": "Es muss mindestens ein Sortier-Prefix vorhanden sein",
|
||||||
"ToastSortingPrefixesUpdateFailed": "Update der Sortier-Prefixe ist fehlgeschlagen",
|
|
||||||
"ToastSortingPrefixesUpdateSuccess": "Die Sortier-Prefixe wirden geupdated ({0} Einträge)",
|
"ToastSortingPrefixesUpdateSuccess": "Die Sortier-Prefixe wirden geupdated ({0} Einträge)",
|
||||||
|
"ToastTitleRequired": "Titel erforderlich",
|
||||||
|
"ToastUnknownError": "Unbekannter Fehler",
|
||||||
|
"ToastUnlinkOpenIdFailed": "Fehler beim entkoppeln des Benutzers von OpenID",
|
||||||
|
"ToastUnlinkOpenIdSuccess": "Benutzer entkoppelt von OpenID",
|
||||||
"ToastUserDeleteFailed": "Benutzer konnte nicht gelöscht werden",
|
"ToastUserDeleteFailed": "Benutzer konnte nicht gelöscht werden",
|
||||||
"ToastUserDeleteSuccess": "Benutzer gelöscht"
|
"ToastUserDeleteSuccess": "Benutzer gelöscht",
|
||||||
|
"ToastUserPasswordChangeSuccess": "Passwort erfolgreich verändert",
|
||||||
|
"ToastUserPasswordMismatch": "Passwörter stimmen nicht überein",
|
||||||
|
"ToastUserPasswordMustChange": "Neues Passwort muss sich von altem Passwort unterscheiden",
|
||||||
|
"ToastUserRootRequireName": "Root Benutzername muss angegeben werden"
|
||||||
}
|
}
|
||||||
|
|||||||
+109
-19
@@ -56,6 +56,7 @@
|
|||||||
"ButtonOpenManager": "Open Manager",
|
"ButtonOpenManager": "Open Manager",
|
||||||
"ButtonPause": "Pause",
|
"ButtonPause": "Pause",
|
||||||
"ButtonPlay": "Play",
|
"ButtonPlay": "Play",
|
||||||
|
"ButtonPlayAll": "Play All",
|
||||||
"ButtonPlaying": "Playing",
|
"ButtonPlaying": "Playing",
|
||||||
"ButtonPlaylists": "Playlists",
|
"ButtonPlaylists": "Playlists",
|
||||||
"ButtonPrevious": "Previous",
|
"ButtonPrevious": "Previous",
|
||||||
@@ -65,6 +66,7 @@
|
|||||||
"ButtonPurgeItemsCache": "Purge Items Cache",
|
"ButtonPurgeItemsCache": "Purge Items Cache",
|
||||||
"ButtonQueueAddItem": "Add to queue",
|
"ButtonQueueAddItem": "Add to queue",
|
||||||
"ButtonQueueRemoveItem": "Remove from queue",
|
"ButtonQueueRemoveItem": "Remove from queue",
|
||||||
|
"ButtonQuickEmbed": "Quick Embed",
|
||||||
"ButtonQuickEmbedMetadata": "Quick Embed Metadata",
|
"ButtonQuickEmbedMetadata": "Quick Embed Metadata",
|
||||||
"ButtonQuickMatch": "Quick Match",
|
"ButtonQuickMatch": "Quick Match",
|
||||||
"ButtonReScan": "Re-Scan",
|
"ButtonReScan": "Re-Scan",
|
||||||
@@ -98,7 +100,7 @@
|
|||||||
"ButtonStats": "Stats",
|
"ButtonStats": "Stats",
|
||||||
"ButtonSubmit": "Submit",
|
"ButtonSubmit": "Submit",
|
||||||
"ButtonTest": "Test",
|
"ButtonTest": "Test",
|
||||||
"ButtonUnlinkOpedId": "Unlink OpenID",
|
"ButtonUnlinkOpenId": "Unlink OpenID",
|
||||||
"ButtonUpload": "Upload",
|
"ButtonUpload": "Upload",
|
||||||
"ButtonUploadBackup": "Upload Backup",
|
"ButtonUploadBackup": "Upload Backup",
|
||||||
"ButtonUploadCover": "Upload Cover",
|
"ButtonUploadCover": "Upload Cover",
|
||||||
@@ -178,6 +180,7 @@
|
|||||||
"HeaderRemoveEpisodes": "Remove {0} Episodes",
|
"HeaderRemoveEpisodes": "Remove {0} Episodes",
|
||||||
"HeaderSavedMediaProgress": "Saved Media Progress",
|
"HeaderSavedMediaProgress": "Saved Media Progress",
|
||||||
"HeaderSchedule": "Schedule",
|
"HeaderSchedule": "Schedule",
|
||||||
|
"HeaderScheduleEpisodeDownloads": "Schedule Automatic Episode Downloads",
|
||||||
"HeaderScheduleLibraryScans": "Schedule Automatic Library Scans",
|
"HeaderScheduleLibraryScans": "Schedule Automatic Library Scans",
|
||||||
"HeaderSession": "Session",
|
"HeaderSession": "Session",
|
||||||
"HeaderSetBackupSchedule": "Set Backup Schedule",
|
"HeaderSetBackupSchedule": "Set Backup Schedule",
|
||||||
@@ -224,6 +227,9 @@
|
|||||||
"LabelAllUsersIncludingGuests": "All users including guests",
|
"LabelAllUsersIncludingGuests": "All users including guests",
|
||||||
"LabelAlreadyInYourLibrary": "Already in your library",
|
"LabelAlreadyInYourLibrary": "Already in your library",
|
||||||
"LabelAppend": "Append",
|
"LabelAppend": "Append",
|
||||||
|
"LabelAudioBitrate": "Audio Bitrate (e.g. 128k)",
|
||||||
|
"LabelAudioChannels": "Audio Channels (1 or 2)",
|
||||||
|
"LabelAudioCodec": "Audio Codec",
|
||||||
"LabelAuthor": "Author",
|
"LabelAuthor": "Author",
|
||||||
"LabelAuthorFirstLast": "Author (First Last)",
|
"LabelAuthorFirstLast": "Author (First Last)",
|
||||||
"LabelAuthorLastFirst": "Author (Last, First)",
|
"LabelAuthorLastFirst": "Author (Last, First)",
|
||||||
@@ -236,6 +242,7 @@
|
|||||||
"LabelAutoRegister": "Auto Register",
|
"LabelAutoRegister": "Auto Register",
|
||||||
"LabelAutoRegisterDescription": "Automatically create new users after logging in",
|
"LabelAutoRegisterDescription": "Automatically create new users after logging in",
|
||||||
"LabelBackToUser": "Back to User",
|
"LabelBackToUser": "Back to User",
|
||||||
|
"LabelBackupAudioFiles": "Backup Audio Files",
|
||||||
"LabelBackupLocation": "Backup Location",
|
"LabelBackupLocation": "Backup Location",
|
||||||
"LabelBackupsEnableAutomaticBackups": "Enable automatic backups",
|
"LabelBackupsEnableAutomaticBackups": "Enable automatic backups",
|
||||||
"LabelBackupsEnableAutomaticBackupsHelp": "Backups saved in /metadata/backups",
|
"LabelBackupsEnableAutomaticBackupsHelp": "Backups saved in /metadata/backups",
|
||||||
@@ -244,15 +251,18 @@
|
|||||||
"LabelBackupsNumberToKeep": "Number of backups to keep",
|
"LabelBackupsNumberToKeep": "Number of backups to keep",
|
||||||
"LabelBackupsNumberToKeepHelp": "Only 1 backup will be removed at a time so if you already have more backups than this you should manually remove them.",
|
"LabelBackupsNumberToKeepHelp": "Only 1 backup will be removed at a time so if you already have more backups than this you should manually remove them.",
|
||||||
"LabelBitrate": "Bitrate",
|
"LabelBitrate": "Bitrate",
|
||||||
|
"LabelBonus": "Bonus",
|
||||||
"LabelBooks": "Books",
|
"LabelBooks": "Books",
|
||||||
"LabelButtonText": "Button Text",
|
"LabelButtonText": "Button Text",
|
||||||
"LabelByAuthor": "by {0}",
|
"LabelByAuthor": "by {0}",
|
||||||
"LabelChangePassword": "Change Password",
|
"LabelChangePassword": "Change Password",
|
||||||
"LabelChannels": "Channels",
|
"LabelChannels": "Channels",
|
||||||
|
"LabelChapterCount": "{0} Chapters",
|
||||||
"LabelChapterTitle": "Chapter Title",
|
"LabelChapterTitle": "Chapter Title",
|
||||||
"LabelChapters": "Chapters",
|
"LabelChapters": "Chapters",
|
||||||
"LabelChaptersFound": "chapters found",
|
"LabelChaptersFound": "chapters found",
|
||||||
"LabelClickForMoreInfo": "Click for more info",
|
"LabelClickForMoreInfo": "Click for more info",
|
||||||
|
"LabelClickToUseCurrentValue": "Click to use current value",
|
||||||
"LabelClosePlayer": "Close player",
|
"LabelClosePlayer": "Close player",
|
||||||
"LabelCodec": "Codec",
|
"LabelCodec": "Codec",
|
||||||
"LabelCollapseSeries": "Collapse Series",
|
"LabelCollapseSeries": "Collapse Series",
|
||||||
@@ -302,12 +312,25 @@
|
|||||||
"LabelEmailSettingsTestAddress": "Test Address",
|
"LabelEmailSettingsTestAddress": "Test Address",
|
||||||
"LabelEmbeddedCover": "Embedded Cover",
|
"LabelEmbeddedCover": "Embedded Cover",
|
||||||
"LabelEnable": "Enable",
|
"LabelEnable": "Enable",
|
||||||
|
"LabelEncodingBackupLocation": "A backup of your original audio files will be stored in:",
|
||||||
|
"LabelEncodingChaptersNotEmbedded": "Chapters are not embedded in multi-track audiobooks.",
|
||||||
|
"LabelEncodingClearItemCache": "Make sure to periodically purge items cache.",
|
||||||
|
"LabelEncodingFinishedM4B": "Finished M4B will be put into your audiobook folder at:",
|
||||||
|
"LabelEncodingInfoEmbedded": "Metadata will be embedded in the audio tracks inside your audiobook folder.",
|
||||||
|
"LabelEncodingStartedNavigation": "Once the task is started you can navigate away from this page.",
|
||||||
|
"LabelEncodingTimeWarning": "Encoding can take up to 30 minutes.",
|
||||||
|
"LabelEncodingWarningAdvancedSettings": "Warning: Do not update these settings unless you are familiar with ffmpeg encoding options.",
|
||||||
|
"LabelEncodingWatcherDisabled": "If you have the watcher disabled you will need to re-scan this audiobook afterwards.",
|
||||||
"LabelEnd": "End",
|
"LabelEnd": "End",
|
||||||
"LabelEndOfChapter": "End of Chapter",
|
"LabelEndOfChapter": "End of Chapter",
|
||||||
"LabelEpisode": "Episode",
|
"LabelEpisode": "Episode",
|
||||||
|
"LabelEpisodeNotLinkedToRssFeed": "Episode not linked to RSS feed",
|
||||||
|
"LabelEpisodeNumber": "Episode #{0}",
|
||||||
"LabelEpisodeTitle": "Episode Title",
|
"LabelEpisodeTitle": "Episode Title",
|
||||||
"LabelEpisodeType": "Episode Type",
|
"LabelEpisodeType": "Episode Type",
|
||||||
|
"LabelEpisodeUrlFromRssFeed": "Episode URL from RSS feed",
|
||||||
"LabelEpisodes": "Episodes",
|
"LabelEpisodes": "Episodes",
|
||||||
|
"LabelEpisodic": "Episodic",
|
||||||
"LabelExample": "Example",
|
"LabelExample": "Example",
|
||||||
"LabelExpandSeries": "Expand Series",
|
"LabelExpandSeries": "Expand Series",
|
||||||
"LabelExpandSubSeries": "Expand Sub Series",
|
"LabelExpandSubSeries": "Expand Sub Series",
|
||||||
@@ -335,6 +358,7 @@
|
|||||||
"LabelFontScale": "Font scale",
|
"LabelFontScale": "Font scale",
|
||||||
"LabelFontStrikethrough": "Strikethrough",
|
"LabelFontStrikethrough": "Strikethrough",
|
||||||
"LabelFormat": "Format",
|
"LabelFormat": "Format",
|
||||||
|
"LabelFull": "Full",
|
||||||
"LabelGenre": "Genre",
|
"LabelGenre": "Genre",
|
||||||
"LabelGenres": "Genres",
|
"LabelGenres": "Genres",
|
||||||
"LabelHardDeleteFile": "Hard delete file",
|
"LabelHardDeleteFile": "Hard delete file",
|
||||||
@@ -390,6 +414,10 @@
|
|||||||
"LabelLowestPriority": "Lowest Priority",
|
"LabelLowestPriority": "Lowest Priority",
|
||||||
"LabelMatchExistingUsersBy": "Match existing users by",
|
"LabelMatchExistingUsersBy": "Match existing users by",
|
||||||
"LabelMatchExistingUsersByDescription": "Used for connecting existing users. Once connected, users will be matched by a unique id from your SSO provider",
|
"LabelMatchExistingUsersByDescription": "Used for connecting existing users. Once connected, users will be matched by a unique id from your SSO provider",
|
||||||
|
"LabelMaxEpisodesToDownload": "Max # of episodes to download. Use 0 for unlimited.",
|
||||||
|
"LabelMaxEpisodesToDownloadPerCheck": "Max # of new episodes to download per check",
|
||||||
|
"LabelMaxEpisodesToKeep": "Max # of episodes to keep",
|
||||||
|
"LabelMaxEpisodesToKeepHelp": "Value of 0 sets no max limit. After a new episode is auto-downloaded this will delete the oldest episode if you have more than X episodes. This will only delete 1 episode per new download.",
|
||||||
"LabelMediaPlayer": "Media Player",
|
"LabelMediaPlayer": "Media Player",
|
||||||
"LabelMediaType": "Media Type",
|
"LabelMediaType": "Media Type",
|
||||||
"LabelMetaTag": "Meta Tag",
|
"LabelMetaTag": "Meta Tag",
|
||||||
@@ -464,6 +492,8 @@
|
|||||||
"LabelPubDate": "Pub Date",
|
"LabelPubDate": "Pub Date",
|
||||||
"LabelPublishYear": "Publish Year",
|
"LabelPublishYear": "Publish Year",
|
||||||
"LabelPublishedDate": "Published {0}",
|
"LabelPublishedDate": "Published {0}",
|
||||||
|
"LabelPublishedDecade": "Published Decade",
|
||||||
|
"LabelPublishedDecades": "Published Decades",
|
||||||
"LabelPublisher": "Publisher",
|
"LabelPublisher": "Publisher",
|
||||||
"LabelPublishers": "Publishers",
|
"LabelPublishers": "Publishers",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "Custom owner Email",
|
"LabelRSSFeedCustomOwnerEmail": "Custom owner Email",
|
||||||
@@ -483,21 +513,28 @@
|
|||||||
"LabelRedo": "Redo",
|
"LabelRedo": "Redo",
|
||||||
"LabelRegion": "Region",
|
"LabelRegion": "Region",
|
||||||
"LabelReleaseDate": "Release Date",
|
"LabelReleaseDate": "Release Date",
|
||||||
|
"LabelRemoveAllMetadataAbs": "Remove all metadata.abs files",
|
||||||
|
"LabelRemoveAllMetadataJson": "Remove all metadata.json files",
|
||||||
"LabelRemoveCover": "Remove cover",
|
"LabelRemoveCover": "Remove cover",
|
||||||
|
"LabelRemoveMetadataFile": "Remove metadata files in library item folders",
|
||||||
|
"LabelRemoveMetadataFileHelp": "Remove all metadata.json and metadata.abs files in your {0} folders.",
|
||||||
"LabelRowsPerPage": "Rows per page",
|
"LabelRowsPerPage": "Rows per page",
|
||||||
"LabelSearchTerm": "Search Term",
|
"LabelSearchTerm": "Search Term",
|
||||||
"LabelSearchTitle": "Search Title",
|
"LabelSearchTitle": "Search Title",
|
||||||
"LabelSearchTitleOrASIN": "Search Title or ASIN",
|
"LabelSearchTitleOrASIN": "Search Title or ASIN",
|
||||||
"LabelSeason": "Season",
|
"LabelSeason": "Season",
|
||||||
|
"LabelSeasonNumber": "Season #{0}",
|
||||||
"LabelSelectAll": "Select all",
|
"LabelSelectAll": "Select all",
|
||||||
"LabelSelectAllEpisodes": "Select all episodes",
|
"LabelSelectAllEpisodes": "Select all episodes",
|
||||||
"LabelSelectEpisodesShowing": "Select {0} episodes showing",
|
"LabelSelectEpisodesShowing": "Select {0} episodes showing",
|
||||||
"LabelSelectUsers": "Select users",
|
"LabelSelectUsers": "Select users",
|
||||||
"LabelSendEbookToDevice": "Send Ebook to...",
|
"LabelSendEbookToDevice": "Send Ebook to...",
|
||||||
"LabelSequence": "Sequence",
|
"LabelSequence": "Sequence",
|
||||||
|
"LabelSerial": "Serial",
|
||||||
"LabelSeries": "Series",
|
"LabelSeries": "Series",
|
||||||
"LabelSeriesName": "Series Name",
|
"LabelSeriesName": "Series Name",
|
||||||
"LabelSeriesProgress": "Series Progress",
|
"LabelSeriesProgress": "Series Progress",
|
||||||
|
"LabelServerLogLevel": "Server Log Level",
|
||||||
"LabelServerYearReview": "Server Year in Review ({0})",
|
"LabelServerYearReview": "Server Year in Review ({0})",
|
||||||
"LabelSetEbookAsPrimary": "Set as primary",
|
"LabelSetEbookAsPrimary": "Set as primary",
|
||||||
"LabelSetEbookAsSupplementary": "Set as supplementary",
|
"LabelSetEbookAsSupplementary": "Set as supplementary",
|
||||||
@@ -586,6 +623,7 @@
|
|||||||
"LabelTimeDurationXMinutes": "{0} minutes",
|
"LabelTimeDurationXMinutes": "{0} minutes",
|
||||||
"LabelTimeDurationXSeconds": "{0} seconds",
|
"LabelTimeDurationXSeconds": "{0} seconds",
|
||||||
"LabelTimeInMinutes": "Time in minutes",
|
"LabelTimeInMinutes": "Time in minutes",
|
||||||
|
"LabelTimeLeft": "{0} left",
|
||||||
"LabelTimeListened": "Time Listened",
|
"LabelTimeListened": "Time Listened",
|
||||||
"LabelTimeListenedToday": "Time Listened Today",
|
"LabelTimeListenedToday": "Time Listened Today",
|
||||||
"LabelTimeRemaining": "{0} remaining",
|
"LabelTimeRemaining": "{0} remaining",
|
||||||
@@ -593,6 +631,7 @@
|
|||||||
"LabelTitle": "Title",
|
"LabelTitle": "Title",
|
||||||
"LabelToolsEmbedMetadata": "Embed Metadata",
|
"LabelToolsEmbedMetadata": "Embed Metadata",
|
||||||
"LabelToolsEmbedMetadataDescription": "Embed metadata into audio files including cover image and chapters.",
|
"LabelToolsEmbedMetadataDescription": "Embed metadata into audio files including cover image and chapters.",
|
||||||
|
"LabelToolsM4bEncoder": "M4B Encoder",
|
||||||
"LabelToolsMakeM4b": "Make M4B Audiobook File",
|
"LabelToolsMakeM4b": "Make M4B Audiobook File",
|
||||||
"LabelToolsMakeM4bDescription": "Generate a .M4B audiobook file with embedded metadata, cover image, and chapters.",
|
"LabelToolsMakeM4bDescription": "Generate a .M4B audiobook file with embedded metadata, cover image, and chapters.",
|
||||||
"LabelToolsSplitM4b": "Split M4B to MP3's",
|
"LabelToolsSplitM4b": "Split M4B to MP3's",
|
||||||
@@ -605,6 +644,7 @@
|
|||||||
"LabelTracksMultiTrack": "Multi-track",
|
"LabelTracksMultiTrack": "Multi-track",
|
||||||
"LabelTracksNone": "No tracks",
|
"LabelTracksNone": "No tracks",
|
||||||
"LabelTracksSingleTrack": "Single-track",
|
"LabelTracksSingleTrack": "Single-track",
|
||||||
|
"LabelTrailer": "Trailer",
|
||||||
"LabelType": "Type",
|
"LabelType": "Type",
|
||||||
"LabelUnabridged": "Unabridged",
|
"LabelUnabridged": "Unabridged",
|
||||||
"LabelUndo": "Undo",
|
"LabelUndo": "Undo",
|
||||||
@@ -618,8 +658,10 @@
|
|||||||
"LabelUploaderDragAndDrop": "Drag & drop files or folders",
|
"LabelUploaderDragAndDrop": "Drag & drop files or folders",
|
||||||
"LabelUploaderDropFiles": "Drop files",
|
"LabelUploaderDropFiles": "Drop files",
|
||||||
"LabelUploaderItemFetchMetadataHelp": "Automatically fetch title, author, and series",
|
"LabelUploaderItemFetchMetadataHelp": "Automatically fetch title, author, and series",
|
||||||
|
"LabelUseAdvancedOptions": "Use Advanced Options",
|
||||||
"LabelUseChapterTrack": "Use chapter track",
|
"LabelUseChapterTrack": "Use chapter track",
|
||||||
"LabelUseFullTrack": "Use full track",
|
"LabelUseFullTrack": "Use full track",
|
||||||
|
"LabelUseZeroForUnlimited": "Use 0 for unlimited",
|
||||||
"LabelUser": "User",
|
"LabelUser": "User",
|
||||||
"LabelUsername": "Username",
|
"LabelUsername": "Username",
|
||||||
"LabelValue": "Value",
|
"LabelValue": "Value",
|
||||||
@@ -666,6 +708,7 @@
|
|||||||
"MessageConfirmDeleteMetadataProvider": "Are you sure you want to delete custom metadata provider \"{0}\"?",
|
"MessageConfirmDeleteMetadataProvider": "Are you sure you want to delete custom metadata provider \"{0}\"?",
|
||||||
"MessageConfirmDeleteNotification": "Are you sure you want to delete this notification?",
|
"MessageConfirmDeleteNotification": "Are you sure you want to delete this notification?",
|
||||||
"MessageConfirmDeleteSession": "Are you sure you want to delete this session?",
|
"MessageConfirmDeleteSession": "Are you sure you want to delete this session?",
|
||||||
|
"MessageConfirmEmbedMetadataInAudioFiles": "Are you sure you want to embed metadata in {0} audio files?",
|
||||||
"MessageConfirmForceReScan": "Are you sure you want to force re-scan?",
|
"MessageConfirmForceReScan": "Are you sure you want to force re-scan?",
|
||||||
"MessageConfirmMarkAllEpisodesFinished": "Are you sure you want to mark all episodes as finished?",
|
"MessageConfirmMarkAllEpisodesFinished": "Are you sure you want to mark all episodes as finished?",
|
||||||
"MessageConfirmMarkAllEpisodesNotFinished": "Are you sure you want to mark all episodes as not finished?",
|
"MessageConfirmMarkAllEpisodesNotFinished": "Are you sure you want to mark all episodes as not finished?",
|
||||||
@@ -677,6 +720,7 @@
|
|||||||
"MessageConfirmPurgeCache": "Purge cache will delete the entire directory at <code>/metadata/cache</code>. <br /><br />Are you sure you want to remove the cache directory?",
|
"MessageConfirmPurgeCache": "Purge cache will delete the entire directory at <code>/metadata/cache</code>. <br /><br />Are you sure you want to remove the cache directory?",
|
||||||
"MessageConfirmPurgeItemsCache": "Purge items cache will delete the entire directory at <code>/metadata/cache/items</code>.<br />Are you sure?",
|
"MessageConfirmPurgeItemsCache": "Purge items cache will delete the entire directory at <code>/metadata/cache/items</code>.<br />Are you sure?",
|
||||||
"MessageConfirmQuickEmbed": "Warning! Quick embed will not backup your audio files. Make sure that you have a backup of your audio files. <br><br>Would you like to continue?",
|
"MessageConfirmQuickEmbed": "Warning! Quick embed will not backup your audio files. Make sure that you have a backup of your audio files. <br><br>Would you like to continue?",
|
||||||
|
"MessageConfirmQuickMatchEpisodes": "Quick matching episodes will overwrite details if a match is found. Only unmatched episodes will be updated. Are you sure?",
|
||||||
"MessageConfirmReScanLibraryItems": "Are you sure you want to re-scan {0} items?",
|
"MessageConfirmReScanLibraryItems": "Are you sure you want to re-scan {0} items?",
|
||||||
"MessageConfirmRemoveAllChapters": "Are you sure you want to remove all chapters?",
|
"MessageConfirmRemoveAllChapters": "Are you sure you want to remove all chapters?",
|
||||||
"MessageConfirmRemoveAuthor": "Are you sure you want to remove author \"{0}\"?",
|
"MessageConfirmRemoveAuthor": "Are you sure you want to remove author \"{0}\"?",
|
||||||
@@ -684,6 +728,7 @@
|
|||||||
"MessageConfirmRemoveEpisode": "Are you sure you want to remove episode \"{0}\"?",
|
"MessageConfirmRemoveEpisode": "Are you sure you want to remove episode \"{0}\"?",
|
||||||
"MessageConfirmRemoveEpisodes": "Are you sure you want to remove {0} episodes?",
|
"MessageConfirmRemoveEpisodes": "Are you sure you want to remove {0} episodes?",
|
||||||
"MessageConfirmRemoveListeningSessions": "Are you sure you want to remove {0} listening sessions?",
|
"MessageConfirmRemoveListeningSessions": "Are you sure you want to remove {0} listening sessions?",
|
||||||
|
"MessageConfirmRemoveMetadataFiles": "Are you sure you want to remove all metadata.{0} files in your library item folders?",
|
||||||
"MessageConfirmRemoveNarrator": "Are you sure you want to remove narrator \"{0}\"?",
|
"MessageConfirmRemoveNarrator": "Are you sure you want to remove narrator \"{0}\"?",
|
||||||
"MessageConfirmRemovePlaylist": "Are you sure you want to remove your playlist \"{0}\"?",
|
"MessageConfirmRemovePlaylist": "Are you sure you want to remove your playlist \"{0}\"?",
|
||||||
"MessageConfirmRenameGenre": "Are you sure you want to rename genre \"{0}\" to \"{1}\" for all items?",
|
"MessageConfirmRenameGenre": "Are you sure you want to rename genre \"{0}\" to \"{1}\" for all items?",
|
||||||
@@ -699,6 +744,7 @@
|
|||||||
"MessageDragFilesIntoTrackOrder": "Drag files into correct track order",
|
"MessageDragFilesIntoTrackOrder": "Drag files into correct track order",
|
||||||
"MessageEmbedFailed": "Embed Failed!",
|
"MessageEmbedFailed": "Embed Failed!",
|
||||||
"MessageEmbedFinished": "Embed Finished!",
|
"MessageEmbedFinished": "Embed Finished!",
|
||||||
|
"MessageEmbedQueue": "Queued for metadata embed ({0} in queue)",
|
||||||
"MessageEpisodesQueuedForDownload": "{0} Episode(s) queued for download",
|
"MessageEpisodesQueuedForDownload": "{0} Episode(s) queued for download",
|
||||||
"MessageEreaderDevices": "To ensure delivery of ebooks, you may need to add the above email address as a valid sender for each device listed below.",
|
"MessageEreaderDevices": "To ensure delivery of ebooks, you may need to add the above email address as a valid sender for each device listed below.",
|
||||||
"MessageFeedURLWillBe": "Feed URL will be {0}",
|
"MessageFeedURLWillBe": "Feed URL will be {0}",
|
||||||
@@ -743,6 +789,7 @@
|
|||||||
"MessageNoLogs": "No Logs",
|
"MessageNoLogs": "No Logs",
|
||||||
"MessageNoMediaProgress": "No Media Progress",
|
"MessageNoMediaProgress": "No Media Progress",
|
||||||
"MessageNoNotifications": "No Notifications",
|
"MessageNoNotifications": "No Notifications",
|
||||||
|
"MessageNoPodcastFeed": "Invalid podcast: No Feed",
|
||||||
"MessageNoPodcastsFound": "No podcasts found",
|
"MessageNoPodcastsFound": "No podcasts found",
|
||||||
"MessageNoResults": "No Results",
|
"MessageNoResults": "No Results",
|
||||||
"MessageNoSearchResultsFor": "No search results for \"{0}\"",
|
"MessageNoSearchResultsFor": "No search results for \"{0}\"",
|
||||||
@@ -759,6 +806,10 @@
|
|||||||
"MessagePlaylistCreateFromCollection": "Create playlist from collection",
|
"MessagePlaylistCreateFromCollection": "Create playlist from collection",
|
||||||
"MessagePleaseWait": "Please wait...",
|
"MessagePleaseWait": "Please wait...",
|
||||||
"MessagePodcastHasNoRSSFeedForMatching": "Podcast has no RSS feed url to use for matching",
|
"MessagePodcastHasNoRSSFeedForMatching": "Podcast has no RSS feed url to use for matching",
|
||||||
|
"MessagePodcastSearchField": "Enter search term or RSS feed URL",
|
||||||
|
"MessageQuickEmbedInProgress": "Quick embed in progress",
|
||||||
|
"MessageQuickEmbedQueue": "Queued for quick embed ({0} in queue)",
|
||||||
|
"MessageQuickMatchAllEpisodes": "Quick Match All Episodes",
|
||||||
"MessageQuickMatchDescription": "Populate empty item details & cover with first match result from '{0}'. Does not overwrite details unless 'Prefer matched metadata' server setting is enabled.",
|
"MessageQuickMatchDescription": "Populate empty item details & cover with first match result from '{0}'. Does not overwrite details unless 'Prefer matched metadata' server setting is enabled.",
|
||||||
"MessageRemoveChapter": "Remove chapter",
|
"MessageRemoveChapter": "Remove chapter",
|
||||||
"MessageRemoveEpisodes": "Remove {0} episode(s)",
|
"MessageRemoveEpisodes": "Remove {0} episode(s)",
|
||||||
@@ -776,6 +827,41 @@
|
|||||||
"MessageShareExpiresIn": "Expires in {0}",
|
"MessageShareExpiresIn": "Expires in {0}",
|
||||||
"MessageShareURLWillBe": "Share URL will be <strong>{0}</strong>",
|
"MessageShareURLWillBe": "Share URL will be <strong>{0}</strong>",
|
||||||
"MessageStartPlaybackAtTime": "Start playback for \"{0}\" at {1}?",
|
"MessageStartPlaybackAtTime": "Start playback for \"{0}\" at {1}?",
|
||||||
|
"MessageTaskAudioFileNotWritable": "Audio file \"{0}\" is not writable",
|
||||||
|
"MessageTaskCanceledByUser": "Task canceled by user",
|
||||||
|
"MessageTaskDownloadingEpisodeDescription": "Downloading episode \"{0}\"",
|
||||||
|
"MessageTaskEmbeddingMetadata": "Embedding metadata",
|
||||||
|
"MessageTaskEmbeddingMetadataDescription": "Embedding metadata in audiobook \"{0}\"",
|
||||||
|
"MessageTaskEncodingM4b": "Encoding M4B",
|
||||||
|
"MessageTaskEncodingM4bDescription": "Encoding audiobook \"{0}\" into a single m4b file",
|
||||||
|
"MessageTaskFailed": "Failed",
|
||||||
|
"MessageTaskFailedToBackupAudioFile": "Failed to backup audio file \"{0}\"",
|
||||||
|
"MessageTaskFailedToCreateCacheDirectory": "Failed to create cache directory",
|
||||||
|
"MessageTaskFailedToEmbedMetadataInFile": "Failed to embed metadata in file \"{0}\"",
|
||||||
|
"MessageTaskFailedToMergeAudioFiles": "Failed to merge audio files",
|
||||||
|
"MessageTaskFailedToMoveM4bFile": "Failed to move m4b file",
|
||||||
|
"MessageTaskFailedToWriteMetadataFile": "Failed to write metadata file",
|
||||||
|
"MessageTaskMatchingBooksInLibrary": "Matching books in library \"{0}\"",
|
||||||
|
"MessageTaskNoFilesToScan": "No files to scan",
|
||||||
|
"MessageTaskOpmlImport": "OPML import",
|
||||||
|
"MessageTaskOpmlImportDescription": "Creating podcasts from {0} RSS feeds",
|
||||||
|
"MessageTaskOpmlImportFeed": "OPML import feed",
|
||||||
|
"MessageTaskOpmlImportFeedDescription": "Importing RSS feed \"{0}\"",
|
||||||
|
"MessageTaskOpmlImportFeedFailed": "Failed to get podcast feed",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastDescription": "Creating podcast \"{0}\"",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastExists": "Podcast already exists at path",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastFailed": "Failed to create podcast",
|
||||||
|
"MessageTaskOpmlImportFinished": "Added {0} podcasts",
|
||||||
|
"MessageTaskOpmlParseFailed": "Failed to parse OPML file",
|
||||||
|
"MessageTaskOpmlParseFastFail": "Invalid OPML file <opml> tag not found OR an <outline> tag was not found",
|
||||||
|
"MessageTaskOpmlParseNoneFound": "No feeds found in OPML file",
|
||||||
|
"MessageTaskScanItemsAdded": "{0} added",
|
||||||
|
"MessageTaskScanItemsMissing": "{0} missing",
|
||||||
|
"MessageTaskScanItemsUpdated": "{0} updated",
|
||||||
|
"MessageTaskScanNoChangesNeeded": "No changes needed",
|
||||||
|
"MessageTaskScanningFileChanges": "Scanning file changes in \"{0}\"",
|
||||||
|
"MessageTaskScanningLibrary": "Scanning \"{0}\" library",
|
||||||
|
"MessageTaskTargetDirectoryNotWritable": "Target directory is not writable",
|
||||||
"MessageThinking": "Thinking...",
|
"MessageThinking": "Thinking...",
|
||||||
"MessageUploaderItemFailed": "Failed to upload",
|
"MessageUploaderItemFailed": "Failed to upload",
|
||||||
"MessageUploaderItemSuccess": "Successfully Uploaded!",
|
"MessageUploaderItemSuccess": "Successfully Uploaded!",
|
||||||
@@ -793,6 +879,10 @@
|
|||||||
"NoteUploaderFoldersWithMediaFiles": "Folders with media files will be handled as separate library items.",
|
"NoteUploaderFoldersWithMediaFiles": "Folders with media files will be handled as separate library items.",
|
||||||
"NoteUploaderOnlyAudioFiles": "If uploading only audio files then each audio file will be handled as a separate audiobook.",
|
"NoteUploaderOnlyAudioFiles": "If uploading only audio files then each audio file will be handled as a separate audiobook.",
|
||||||
"NoteUploaderUnsupportedFiles": "Unsupported files are ignored. When choosing or dropping a folder, other files that are not in an item folder are ignored.",
|
"NoteUploaderUnsupportedFiles": "Unsupported files are ignored. When choosing or dropping a folder, other files that are not in an item folder are ignored.",
|
||||||
|
"NotificationOnBackupCompletedDescription": "Triggered when a backup is completed",
|
||||||
|
"NotificationOnBackupFailedDescription": "Triggered when a backup fails",
|
||||||
|
"NotificationOnEpisodeDownloadedDescription": "Triggered when a podcast episode is auto-downloaded",
|
||||||
|
"NotificationOnTestDescription": "Event for testing the notification system",
|
||||||
"PlaceholderNewCollection": "New collection name",
|
"PlaceholderNewCollection": "New collection name",
|
||||||
"PlaceholderNewFolderPath": "New folder path",
|
"PlaceholderNewFolderPath": "New folder path",
|
||||||
"PlaceholderNewPlaylist": "New playlist name",
|
"PlaceholderNewPlaylist": "New playlist name",
|
||||||
@@ -816,14 +906,13 @@
|
|||||||
"StatsTopNarrators": "TOP NARRATORS",
|
"StatsTopNarrators": "TOP NARRATORS",
|
||||||
"StatsTotalDuration": "With a total duration of…",
|
"StatsTotalDuration": "With a total duration of…",
|
||||||
"StatsYearInReview": "YEAR IN REVIEW",
|
"StatsYearInReview": "YEAR IN REVIEW",
|
||||||
"ToastAccountUpdateFailed": "Failed to update account",
|
|
||||||
"ToastAccountUpdateSuccess": "Account updated",
|
"ToastAccountUpdateSuccess": "Account updated",
|
||||||
"ToastAppriseUrlRequired": "Must enter an Apprise URL",
|
"ToastAppriseUrlRequired": "Must enter an Apprise URL",
|
||||||
|
"ToastAsinRequired": "ASIN is required",
|
||||||
"ToastAuthorImageRemoveSuccess": "Author image removed",
|
"ToastAuthorImageRemoveSuccess": "Author image removed",
|
||||||
"ToastAuthorNotFound": "Author \"{0}\" not found",
|
"ToastAuthorNotFound": "Author \"{0}\" not found",
|
||||||
"ToastAuthorRemoveSuccess": "Author removed",
|
"ToastAuthorRemoveSuccess": "Author removed",
|
||||||
"ToastAuthorSearchNotFound": "Author not found",
|
"ToastAuthorSearchNotFound": "Author not found",
|
||||||
"ToastAuthorUpdateFailed": "Failed to update author",
|
|
||||||
"ToastAuthorUpdateMerged": "Author merged",
|
"ToastAuthorUpdateMerged": "Author merged",
|
||||||
"ToastAuthorUpdateSuccess": "Author updated",
|
"ToastAuthorUpdateSuccess": "Author updated",
|
||||||
"ToastAuthorUpdateSuccessNoImageFound": "Author updated (no image found)",
|
"ToastAuthorUpdateSuccessNoImageFound": "Author updated (no image found)",
|
||||||
@@ -834,29 +923,29 @@
|
|||||||
"ToastBackupDeleteSuccess": "Backup deleted",
|
"ToastBackupDeleteSuccess": "Backup deleted",
|
||||||
"ToastBackupInvalidMaxKeep": "Invalid number of backups to keep",
|
"ToastBackupInvalidMaxKeep": "Invalid number of backups to keep",
|
||||||
"ToastBackupInvalidMaxSize": "Invalid maximum backup size",
|
"ToastBackupInvalidMaxSize": "Invalid maximum backup size",
|
||||||
"ToastBackupPathUpdateFailed": "Failed to update backup path",
|
|
||||||
"ToastBackupRestoreFailed": "Failed to restore backup",
|
"ToastBackupRestoreFailed": "Failed to restore backup",
|
||||||
"ToastBackupUploadFailed": "Failed to upload backup",
|
"ToastBackupUploadFailed": "Failed to upload backup",
|
||||||
"ToastBackupUploadSuccess": "Backup uploaded",
|
"ToastBackupUploadSuccess": "Backup uploaded",
|
||||||
"ToastBatchDeleteFailed": "Batch delete failed",
|
"ToastBatchDeleteFailed": "Batch delete failed",
|
||||||
"ToastBatchDeleteSuccess": "Batch delete success",
|
"ToastBatchDeleteSuccess": "Batch delete success",
|
||||||
|
"ToastBatchQuickMatchFailed": "Batch Quick Match failed!",
|
||||||
|
"ToastBatchQuickMatchStarted": "Batch Quick Match of {0} books started!",
|
||||||
"ToastBatchUpdateFailed": "Batch update failed",
|
"ToastBatchUpdateFailed": "Batch update failed",
|
||||||
"ToastBatchUpdateSuccess": "Batch update success",
|
"ToastBatchUpdateSuccess": "Batch update success",
|
||||||
"ToastBookmarkCreateFailed": "Failed to create bookmark",
|
"ToastBookmarkCreateFailed": "Failed to create bookmark",
|
||||||
"ToastBookmarkCreateSuccess": "Bookmark added",
|
"ToastBookmarkCreateSuccess": "Bookmark added",
|
||||||
"ToastBookmarkRemoveSuccess": "Bookmark removed",
|
"ToastBookmarkRemoveSuccess": "Bookmark removed",
|
||||||
"ToastBookmarkUpdateFailed": "Failed to update bookmark",
|
|
||||||
"ToastBookmarkUpdateSuccess": "Bookmark updated",
|
"ToastBookmarkUpdateSuccess": "Bookmark updated",
|
||||||
"ToastCachePurgeFailed": "Failed to purge cache",
|
"ToastCachePurgeFailed": "Failed to purge cache",
|
||||||
"ToastCachePurgeSuccess": "Cache purged successfully",
|
"ToastCachePurgeSuccess": "Cache purged successfully",
|
||||||
"ToastChaptersHaveErrors": "Chapters have errors",
|
"ToastChaptersHaveErrors": "Chapters have errors",
|
||||||
"ToastChaptersMustHaveTitles": "Chapters must have titles",
|
"ToastChaptersMustHaveTitles": "Chapters must have titles",
|
||||||
"ToastChaptersRemoved": "Chapters removed",
|
"ToastChaptersRemoved": "Chapters removed",
|
||||||
|
"ToastChaptersUpdated": "Chapters updated",
|
||||||
"ToastCollectionItemsAddFailed": "Item(s) added to collection failed",
|
"ToastCollectionItemsAddFailed": "Item(s) added to collection failed",
|
||||||
"ToastCollectionItemsAddSuccess": "Item(s) added to collection success",
|
"ToastCollectionItemsAddSuccess": "Item(s) added to collection success",
|
||||||
"ToastCollectionItemsRemoveSuccess": "Item(s) removed from collection",
|
"ToastCollectionItemsRemoveSuccess": "Item(s) removed from collection",
|
||||||
"ToastCollectionRemoveSuccess": "Collection removed",
|
"ToastCollectionRemoveSuccess": "Collection removed",
|
||||||
"ToastCollectionUpdateFailed": "Failed to update collection",
|
|
||||||
"ToastCollectionUpdateSuccess": "Collection updated",
|
"ToastCollectionUpdateSuccess": "Collection updated",
|
||||||
"ToastCoverUpdateFailed": "Cover update failed",
|
"ToastCoverUpdateFailed": "Cover update failed",
|
||||||
"ToastDeleteFileFailed": "Failed to delete file",
|
"ToastDeleteFileFailed": "Failed to delete file",
|
||||||
@@ -865,31 +954,28 @@
|
|||||||
"ToastDeviceNameAlreadyExists": "Ereader device with that name already exists",
|
"ToastDeviceNameAlreadyExists": "Ereader device with that name already exists",
|
||||||
"ToastDeviceTestEmailFailed": "Failed to send test email",
|
"ToastDeviceTestEmailFailed": "Failed to send test email",
|
||||||
"ToastDeviceTestEmailSuccess": "Test email sent",
|
"ToastDeviceTestEmailSuccess": "Test email sent",
|
||||||
"ToastDeviceUpdateFailed": "Failed to update device",
|
|
||||||
"ToastEmailSettingsUpdateFailed": "Failed to update email settings",
|
|
||||||
"ToastEmailSettingsUpdateSuccess": "Email settings updated",
|
"ToastEmailSettingsUpdateSuccess": "Email settings updated",
|
||||||
"ToastEncodeCancelFailed": "Failed to cancel encode",
|
"ToastEncodeCancelFailed": "Failed to cancel encode",
|
||||||
"ToastEncodeCancelSucces": "Encode canceled",
|
"ToastEncodeCancelSucces": "Encode canceled",
|
||||||
"ToastEpisodeDownloadQueueClearFailed": "Failed to clear queue",
|
"ToastEpisodeDownloadQueueClearFailed": "Failed to clear queue",
|
||||||
"ToastEpisodeDownloadQueueClearSuccess": "Episode download queue cleared",
|
"ToastEpisodeDownloadQueueClearSuccess": "Episode download queue cleared",
|
||||||
|
"ToastEpisodeUpdateSuccess": "{0} episodes updated",
|
||||||
"ToastErrorCannotShare": "Cannot share natively on this device",
|
"ToastErrorCannotShare": "Cannot share natively on this device",
|
||||||
"ToastFailedToLoadData": "Failed to load data",
|
"ToastFailedToLoadData": "Failed to load data",
|
||||||
|
"ToastFailedToMatch": "Failed to match",
|
||||||
"ToastFailedToShare": "Failed to share",
|
"ToastFailedToShare": "Failed to share",
|
||||||
"ToastFailedToUpdateAccount": "Failed to update account",
|
"ToastFailedToUpdate": "Failed to update",
|
||||||
"ToastFailedToUpdateUser": "Failed to update user",
|
|
||||||
"ToastInvalidImageUrl": "Invalid image URL",
|
"ToastInvalidImageUrl": "Invalid image URL",
|
||||||
|
"ToastInvalidMaxEpisodesToDownload": "Invalid max episodes to download",
|
||||||
"ToastInvalidUrl": "Invalid URL",
|
"ToastInvalidUrl": "Invalid URL",
|
||||||
"ToastItemCoverUpdateFailed": "Failed to update item cover",
|
|
||||||
"ToastItemCoverUpdateSuccess": "Item cover updated",
|
"ToastItemCoverUpdateSuccess": "Item cover updated",
|
||||||
"ToastItemDeletedFailed": "Failed to delete item",
|
"ToastItemDeletedFailed": "Failed to delete item",
|
||||||
"ToastItemDeletedSuccess": "Deleted item",
|
"ToastItemDeletedSuccess": "Deleted item",
|
||||||
"ToastItemDetailsUpdateFailed": "Failed to update item details",
|
|
||||||
"ToastItemDetailsUpdateSuccess": "Item details updated",
|
"ToastItemDetailsUpdateSuccess": "Item details updated",
|
||||||
"ToastItemMarkedAsFinishedFailed": "Failed to mark as Finished",
|
"ToastItemMarkedAsFinishedFailed": "Failed to mark as Finished",
|
||||||
"ToastItemMarkedAsFinishedSuccess": "Item marked as Finished",
|
"ToastItemMarkedAsFinishedSuccess": "Item marked as Finished",
|
||||||
"ToastItemMarkedAsNotFinishedFailed": "Failed to mark as Not Finished",
|
"ToastItemMarkedAsNotFinishedFailed": "Failed to mark as Not Finished",
|
||||||
"ToastItemMarkedAsNotFinishedSuccess": "Item marked as Not Finished",
|
"ToastItemMarkedAsNotFinishedSuccess": "Item marked as Not Finished",
|
||||||
"ToastItemUpdateFailed": "Failed to update item",
|
|
||||||
"ToastItemUpdateSuccess": "Item updated",
|
"ToastItemUpdateSuccess": "Item updated",
|
||||||
"ToastLibraryCreateFailed": "Failed to create library",
|
"ToastLibraryCreateFailed": "Failed to create library",
|
||||||
"ToastLibraryCreateSuccess": "Library \"{0}\" created",
|
"ToastLibraryCreateSuccess": "Library \"{0}\" created",
|
||||||
@@ -897,37 +983,42 @@
|
|||||||
"ToastLibraryDeleteSuccess": "Library deleted",
|
"ToastLibraryDeleteSuccess": "Library deleted",
|
||||||
"ToastLibraryScanFailedToStart": "Failed to start scan",
|
"ToastLibraryScanFailedToStart": "Failed to start scan",
|
||||||
"ToastLibraryScanStarted": "Library scan started",
|
"ToastLibraryScanStarted": "Library scan started",
|
||||||
"ToastLibraryUpdateFailed": "Failed to update library",
|
|
||||||
"ToastLibraryUpdateSuccess": "Library \"{0}\" updated",
|
"ToastLibraryUpdateSuccess": "Library \"{0}\" updated",
|
||||||
|
"ToastMatchAllAuthorsFailed": "Failed to match all authors",
|
||||||
|
"ToastMetadataFilesRemovedError": "Error removing metadata.{0} files",
|
||||||
|
"ToastMetadataFilesRemovedNoneFound": "No metadata.{0} files found in library",
|
||||||
|
"ToastMetadataFilesRemovedNoneRemoved": "No metadata.{0} files removed",
|
||||||
|
"ToastMetadataFilesRemovedSuccess": "{0} metadata.{1} files removed",
|
||||||
|
"ToastMustHaveAtLeastOnePath": "Must have at least one path",
|
||||||
"ToastNameEmailRequired": "Name and email are required",
|
"ToastNameEmailRequired": "Name and email are required",
|
||||||
"ToastNameRequired": "Name is required",
|
"ToastNameRequired": "Name is required",
|
||||||
|
"ToastNewEpisodesFound": "{0} new episodes found",
|
||||||
"ToastNewUserCreatedFailed": "Failed to create account: \"{0}\"",
|
"ToastNewUserCreatedFailed": "Failed to create account: \"{0}\"",
|
||||||
"ToastNewUserCreatedSuccess": "New account created",
|
"ToastNewUserCreatedSuccess": "New account created",
|
||||||
"ToastNewUserLibraryError": "Must select at least one library",
|
"ToastNewUserLibraryError": "Must select at least one library",
|
||||||
"ToastNewUserPasswordError": "Must have a password, only root user can have an empty password",
|
"ToastNewUserPasswordError": "Must have a password, only root user can have an empty password",
|
||||||
"ToastNewUserTagError": "Must select at least one tag",
|
"ToastNewUserTagError": "Must select at least one tag",
|
||||||
"ToastNewUserUsernameError": "Enter a username",
|
"ToastNewUserUsernameError": "Enter a username",
|
||||||
|
"ToastNoNewEpisodesFound": "No new episodes found",
|
||||||
"ToastNoUpdatesNecessary": "No updates necessary",
|
"ToastNoUpdatesNecessary": "No updates necessary",
|
||||||
"ToastNotificationCreateFailed": "Failed to create notification",
|
"ToastNotificationCreateFailed": "Failed to create notification",
|
||||||
"ToastNotificationDeleteFailed": "Failed to delete notification",
|
"ToastNotificationDeleteFailed": "Failed to delete notification",
|
||||||
"ToastNotificationFailedMaximum": "Max failed attempts must be >= 0",
|
"ToastNotificationFailedMaximum": "Max failed attempts must be >= 0",
|
||||||
"ToastNotificationQueueMaximum": "Max notification queue must be >= 0",
|
"ToastNotificationQueueMaximum": "Max notification queue must be >= 0",
|
||||||
"ToastNotificationSettingsUpdateFailed": "Failed to update notification settings",
|
|
||||||
"ToastNotificationSettingsUpdateSuccess": "Notification settings updated",
|
"ToastNotificationSettingsUpdateSuccess": "Notification settings updated",
|
||||||
"ToastNotificationTestTriggerFailed": "Failed to trigger test notification",
|
"ToastNotificationTestTriggerFailed": "Failed to trigger test notification",
|
||||||
"ToastNotificationTestTriggerSuccess": "Triggered test notification",
|
"ToastNotificationTestTriggerSuccess": "Triggered test notification",
|
||||||
"ToastNotificationUpdateFailed": "Failed to update notification",
|
|
||||||
"ToastNotificationUpdateSuccess": "Notification updated",
|
"ToastNotificationUpdateSuccess": "Notification updated",
|
||||||
"ToastPlaylistCreateFailed": "Failed to create playlist",
|
"ToastPlaylistCreateFailed": "Failed to create playlist",
|
||||||
"ToastPlaylistCreateSuccess": "Playlist created",
|
"ToastPlaylistCreateSuccess": "Playlist created",
|
||||||
"ToastPlaylistRemoveSuccess": "Playlist removed",
|
"ToastPlaylistRemoveSuccess": "Playlist removed",
|
||||||
"ToastPlaylistUpdateFailed": "Failed to update playlist",
|
|
||||||
"ToastPlaylistUpdateSuccess": "Playlist updated",
|
"ToastPlaylistUpdateSuccess": "Playlist updated",
|
||||||
"ToastPodcastCreateFailed": "Failed to create podcast",
|
"ToastPodcastCreateFailed": "Failed to create podcast",
|
||||||
"ToastPodcastCreateSuccess": "Podcast created successfully",
|
"ToastPodcastCreateSuccess": "Podcast created successfully",
|
||||||
"ToastPodcastGetFeedFailed": "Failed to get podcast feed",
|
"ToastPodcastGetFeedFailed": "Failed to get podcast feed",
|
||||||
"ToastPodcastNoEpisodesInFeed": "No episodes found in RSS feed",
|
"ToastPodcastNoEpisodesInFeed": "No episodes found in RSS feed",
|
||||||
"ToastPodcastNoRssFeed": "Podcast does not have an RSS feed",
|
"ToastPodcastNoRssFeed": "Podcast does not have an RSS feed",
|
||||||
|
"ToastProgressIsNotBeingSynced": "Progress is not being synced, restart playback",
|
||||||
"ToastProviderCreatedFailed": "Failed to add provider",
|
"ToastProviderCreatedFailed": "Failed to add provider",
|
||||||
"ToastProviderCreatedSuccess": "New provider added",
|
"ToastProviderCreatedSuccess": "New provider added",
|
||||||
"ToastProviderNameAndUrlRequired": "Name and Url required",
|
"ToastProviderNameAndUrlRequired": "Name and Url required",
|
||||||
@@ -950,18 +1041,17 @@
|
|||||||
"ToastSendEbookToDeviceSuccess": "Ebook sent to device \"{0}\"",
|
"ToastSendEbookToDeviceSuccess": "Ebook sent to device \"{0}\"",
|
||||||
"ToastSeriesUpdateFailed": "Series update failed",
|
"ToastSeriesUpdateFailed": "Series update failed",
|
||||||
"ToastSeriesUpdateSuccess": "Series update success",
|
"ToastSeriesUpdateSuccess": "Series update success",
|
||||||
"ToastServerSettingsUpdateFailed": "Failed to update server settings",
|
|
||||||
"ToastServerSettingsUpdateSuccess": "Server settings updated",
|
"ToastServerSettingsUpdateSuccess": "Server settings updated",
|
||||||
"ToastSessionCloseFailed": "Failed to close session",
|
"ToastSessionCloseFailed": "Failed to close session",
|
||||||
"ToastSessionDeleteFailed": "Failed to delete session",
|
"ToastSessionDeleteFailed": "Failed to delete session",
|
||||||
"ToastSessionDeleteSuccess": "Session deleted",
|
"ToastSessionDeleteSuccess": "Session deleted",
|
||||||
|
"ToastSleepTimerDone": "Sleep timer done... zZzzZz",
|
||||||
"ToastSlugMustChange": "Slug contains invalid characters",
|
"ToastSlugMustChange": "Slug contains invalid characters",
|
||||||
"ToastSlugRequired": "Slug is required",
|
"ToastSlugRequired": "Slug is required",
|
||||||
"ToastSocketConnected": "Socket connected",
|
"ToastSocketConnected": "Socket connected",
|
||||||
"ToastSocketDisconnected": "Socket disconnected",
|
"ToastSocketDisconnected": "Socket disconnected",
|
||||||
"ToastSocketFailedToConnect": "Socket failed to connect",
|
"ToastSocketFailedToConnect": "Socket failed to connect",
|
||||||
"ToastSortingPrefixesEmptyError": "Must have at least 1 sorting prefix",
|
"ToastSortingPrefixesEmptyError": "Must have at least 1 sorting prefix",
|
||||||
"ToastSortingPrefixesUpdateFailed": "Failed to update sorting prefixes",
|
|
||||||
"ToastSortingPrefixesUpdateSuccess": "Sorting prefixes updated ({0} items)",
|
"ToastSortingPrefixesUpdateSuccess": "Sorting prefixes updated ({0} items)",
|
||||||
"ToastTitleRequired": "Title is required",
|
"ToastTitleRequired": "Title is required",
|
||||||
"ToastUnknownError": "Unknown error",
|
"ToastUnknownError": "Unknown error",
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
+181
-19
@@ -30,6 +30,8 @@
|
|||||||
"ButtonEditChapters": "Editar Capítulo",
|
"ButtonEditChapters": "Editar Capítulo",
|
||||||
"ButtonEditPodcast": "Editar Podcast",
|
"ButtonEditPodcast": "Editar Podcast",
|
||||||
"ButtonEnable": "Permitir",
|
"ButtonEnable": "Permitir",
|
||||||
|
"ButtonFireAndFail": "Ejecutado y fallido",
|
||||||
|
"ButtonFireOnTest": "Activar evento de prueba",
|
||||||
"ButtonForceReScan": "Forzar Re-Escaneo",
|
"ButtonForceReScan": "Forzar Re-Escaneo",
|
||||||
"ButtonFullPath": "Ruta de Acceso Completa",
|
"ButtonFullPath": "Ruta de Acceso Completa",
|
||||||
"ButtonHide": "Esconder",
|
"ButtonHide": "Esconder",
|
||||||
@@ -46,12 +48,15 @@
|
|||||||
"ButtonMatchAllAuthors": "Encontrar Todos los Autores",
|
"ButtonMatchAllAuthors": "Encontrar Todos los Autores",
|
||||||
"ButtonMatchBooks": "Encontrar Libros",
|
"ButtonMatchBooks": "Encontrar Libros",
|
||||||
"ButtonNevermind": "Olvidar",
|
"ButtonNevermind": "Olvidar",
|
||||||
|
"ButtonNext": "Siguiente",
|
||||||
"ButtonNextChapter": "Siguiente Capítulo",
|
"ButtonNextChapter": "Siguiente Capítulo",
|
||||||
"ButtonNextItemInQueue": "El siguiente elemento en cola",
|
"ButtonNextItemInQueue": "El siguiente elemento en cola",
|
||||||
|
"ButtonOk": "De acuerdo",
|
||||||
"ButtonOpenFeed": "Abrir fuente",
|
"ButtonOpenFeed": "Abrir fuente",
|
||||||
"ButtonOpenManager": "Abrir Editor",
|
"ButtonOpenManager": "Abrir Editor",
|
||||||
"ButtonPause": "Pausar",
|
"ButtonPause": "Pausar",
|
||||||
"ButtonPlay": "Reproducir",
|
"ButtonPlay": "Reproducir",
|
||||||
|
"ButtonPlayAll": "Reproducir todo",
|
||||||
"ButtonPlaying": "Reproduciendo",
|
"ButtonPlaying": "Reproduciendo",
|
||||||
"ButtonPlaylists": "Listas de reproducción",
|
"ButtonPlaylists": "Listas de reproducción",
|
||||||
"ButtonPrevious": "Anterior",
|
"ButtonPrevious": "Anterior",
|
||||||
@@ -61,6 +66,7 @@
|
|||||||
"ButtonPurgeItemsCache": "Purgar Elementos de Cache",
|
"ButtonPurgeItemsCache": "Purgar Elementos de Cache",
|
||||||
"ButtonQueueAddItem": "Agregar a la Fila",
|
"ButtonQueueAddItem": "Agregar a la Fila",
|
||||||
"ButtonQueueRemoveItem": "Remover de la Fila",
|
"ButtonQueueRemoveItem": "Remover de la Fila",
|
||||||
|
"ButtonQuickEmbed": "Inserción rápida",
|
||||||
"ButtonQuickEmbedMetadata": "Agregue metadatos rápidamente",
|
"ButtonQuickEmbedMetadata": "Agregue metadatos rápidamente",
|
||||||
"ButtonQuickMatch": "Encontrar Rápido",
|
"ButtonQuickMatch": "Encontrar Rápido",
|
||||||
"ButtonReScan": "Re-Escanear",
|
"ButtonReScan": "Re-Escanear",
|
||||||
@@ -84,6 +90,7 @@
|
|||||||
"ButtonScanLibrary": "Escanear Biblioteca",
|
"ButtonScanLibrary": "Escanear Biblioteca",
|
||||||
"ButtonSearch": "Buscar",
|
"ButtonSearch": "Buscar",
|
||||||
"ButtonSelectFolderPath": "Seleccionar Ruta de Carpeta",
|
"ButtonSelectFolderPath": "Seleccionar Ruta de Carpeta",
|
||||||
|
"ButtonSeries": "Series",
|
||||||
"ButtonSetChaptersFromTracks": "Seleccionar Capítulos Según las Pistas",
|
"ButtonSetChaptersFromTracks": "Seleccionar Capítulos Según las Pistas",
|
||||||
"ButtonShare": "Compartir",
|
"ButtonShare": "Compartir",
|
||||||
"ButtonShiftTimes": "Desplazar Tiempos",
|
"ButtonShiftTimes": "Desplazar Tiempos",
|
||||||
@@ -93,7 +100,7 @@
|
|||||||
"ButtonStats": "Estadísticas",
|
"ButtonStats": "Estadísticas",
|
||||||
"ButtonSubmit": "Enviar",
|
"ButtonSubmit": "Enviar",
|
||||||
"ButtonTest": "Prueba",
|
"ButtonTest": "Prueba",
|
||||||
"ButtonUnlinkOpedId": "Desvincular OpenID",
|
"ButtonUnlinkOpenId": "Desvincular OpenID",
|
||||||
"ButtonUpload": "Subir",
|
"ButtonUpload": "Subir",
|
||||||
"ButtonUploadBackup": "Subir Respaldo",
|
"ButtonUploadBackup": "Subir Respaldo",
|
||||||
"ButtonUploadCover": "Subir Portada",
|
"ButtonUploadCover": "Subir Portada",
|
||||||
@@ -125,6 +132,7 @@
|
|||||||
"HeaderDetails": "Detalles",
|
"HeaderDetails": "Detalles",
|
||||||
"HeaderDownloadQueue": "Lista de Descarga",
|
"HeaderDownloadQueue": "Lista de Descarga",
|
||||||
"HeaderEbookFiles": "Archivos de libros digitales",
|
"HeaderEbookFiles": "Archivos de libros digitales",
|
||||||
|
"HeaderEmail": "Correo electrónico",
|
||||||
"HeaderEmailSettings": "Opciones de Email",
|
"HeaderEmailSettings": "Opciones de Email",
|
||||||
"HeaderEpisodes": "Episodios",
|
"HeaderEpisodes": "Episodios",
|
||||||
"HeaderEreaderDevices": "Dispositivos Ereader",
|
"HeaderEreaderDevices": "Dispositivos Ereader",
|
||||||
@@ -152,6 +160,7 @@
|
|||||||
"HeaderNewAccount": "Nueva Cuenta",
|
"HeaderNewAccount": "Nueva Cuenta",
|
||||||
"HeaderNewLibrary": "Nueva Biblioteca",
|
"HeaderNewLibrary": "Nueva Biblioteca",
|
||||||
"HeaderNotificationCreate": "Crear notificación",
|
"HeaderNotificationCreate": "Crear notificación",
|
||||||
|
"HeaderNotificationUpdate": "Notificación de actualización",
|
||||||
"HeaderNotifications": "Notificaciones",
|
"HeaderNotifications": "Notificaciones",
|
||||||
"HeaderOpenIDConnectAuthentication": "Autenticación OpenID Connect",
|
"HeaderOpenIDConnectAuthentication": "Autenticación OpenID Connect",
|
||||||
"HeaderOpenRSSFeed": "Abrir fuente RSS",
|
"HeaderOpenRSSFeed": "Abrir fuente RSS",
|
||||||
@@ -171,12 +180,14 @@
|
|||||||
"HeaderRemoveEpisodes": "Remover {0} Episodios",
|
"HeaderRemoveEpisodes": "Remover {0} Episodios",
|
||||||
"HeaderSavedMediaProgress": "Guardar Progreso de Multimedia",
|
"HeaderSavedMediaProgress": "Guardar Progreso de Multimedia",
|
||||||
"HeaderSchedule": "Horario",
|
"HeaderSchedule": "Horario",
|
||||||
|
"HeaderScheduleEpisodeDownloads": "Programar descargas automáticas de episodios",
|
||||||
"HeaderScheduleLibraryScans": "Programar Escaneo Automático de Biblioteca",
|
"HeaderScheduleLibraryScans": "Programar Escaneo Automático de Biblioteca",
|
||||||
"HeaderSession": "Sesión",
|
"HeaderSession": "Sesión",
|
||||||
"HeaderSetBackupSchedule": "Programar Respaldo",
|
"HeaderSetBackupSchedule": "Programar Respaldo",
|
||||||
"HeaderSettings": "Configuraciones",
|
"HeaderSettings": "Configuraciones",
|
||||||
"HeaderSettingsDisplay": "Interfaz",
|
"HeaderSettingsDisplay": "Interfaz",
|
||||||
"HeaderSettingsExperimental": "Funciones Experimentales",
|
"HeaderSettingsExperimental": "Funciones Experimentales",
|
||||||
|
"HeaderSettingsGeneral": "General",
|
||||||
"HeaderSettingsScanner": "Escáner",
|
"HeaderSettingsScanner": "Escáner",
|
||||||
"HeaderSleepTimer": "Temporizador de apagado",
|
"HeaderSleepTimer": "Temporizador de apagado",
|
||||||
"HeaderStatsLargestItems": "Artículos mas Grandes",
|
"HeaderStatsLargestItems": "Artículos mas Grandes",
|
||||||
@@ -216,6 +227,9 @@
|
|||||||
"LabelAllUsersIncludingGuests": "Todos los usuarios e invitados",
|
"LabelAllUsersIncludingGuests": "Todos los usuarios e invitados",
|
||||||
"LabelAlreadyInYourLibrary": "Ya existe en la Biblioteca",
|
"LabelAlreadyInYourLibrary": "Ya existe en la Biblioteca",
|
||||||
"LabelAppend": "Adjuntar",
|
"LabelAppend": "Adjuntar",
|
||||||
|
"LabelAudioBitrate": "Tasa de bits del audio (por ejemplo, 128k)",
|
||||||
|
"LabelAudioChannels": "Canales de audio (1 o 2)",
|
||||||
|
"LabelAudioCodec": "Códec de audio",
|
||||||
"LabelAuthor": "Autor",
|
"LabelAuthor": "Autor",
|
||||||
"LabelAuthorFirstLast": "Autor (Nombre Apellido)",
|
"LabelAuthorFirstLast": "Autor (Nombre Apellido)",
|
||||||
"LabelAuthorLastFirst": "Autor (Apellido, Nombre)",
|
"LabelAuthorLastFirst": "Autor (Apellido, Nombre)",
|
||||||
@@ -228,6 +242,7 @@
|
|||||||
"LabelAutoRegister": "Registro automático",
|
"LabelAutoRegister": "Registro automático",
|
||||||
"LabelAutoRegisterDescription": "Crear usuarios automáticamente tras iniciar sesión",
|
"LabelAutoRegisterDescription": "Crear usuarios automáticamente tras iniciar sesión",
|
||||||
"LabelBackToUser": "Regresar a Usuario",
|
"LabelBackToUser": "Regresar a Usuario",
|
||||||
|
"LabelBackupAudioFiles": "Copia de seguridad de archivos de audio",
|
||||||
"LabelBackupLocation": "Ubicación del Respaldo",
|
"LabelBackupLocation": "Ubicación del Respaldo",
|
||||||
"LabelBackupsEnableAutomaticBackups": "Habilitar Respaldo Automático",
|
"LabelBackupsEnableAutomaticBackups": "Habilitar Respaldo Automático",
|
||||||
"LabelBackupsEnableAutomaticBackupsHelp": "Respaldo Guardado en /metadata/backups",
|
"LabelBackupsEnableAutomaticBackupsHelp": "Respaldo Guardado en /metadata/backups",
|
||||||
@@ -235,15 +250,20 @@
|
|||||||
"LabelBackupsMaxBackupSizeHelp": "Como protección contra una configuración errónea, los respaldos fallarán si se excede el tamaño configurado.",
|
"LabelBackupsMaxBackupSizeHelp": "Como protección contra una configuración errónea, los respaldos fallarán si se excede el tamaño configurado.",
|
||||||
"LabelBackupsNumberToKeep": "Numero de respaldos para conservar",
|
"LabelBackupsNumberToKeep": "Numero de respaldos para conservar",
|
||||||
"LabelBackupsNumberToKeepHelp": "Solamente 1 respaldo se removerá a la vez. Si tiene mas respaldos guardados, debe removerlos manualmente.",
|
"LabelBackupsNumberToKeepHelp": "Solamente 1 respaldo se removerá a la vez. Si tiene mas respaldos guardados, debe removerlos manualmente.",
|
||||||
|
"LabelBitrate": "Tasa de bits",
|
||||||
"LabelBooks": "Libros",
|
"LabelBooks": "Libros",
|
||||||
"LabelButtonText": "Texto del botón",
|
"LabelButtonText": "Texto del botón",
|
||||||
|
"LabelByAuthor": "por {0}",
|
||||||
"LabelChangePassword": "Cambiar Contraseña",
|
"LabelChangePassword": "Cambiar Contraseña",
|
||||||
"LabelChannels": "Canales",
|
"LabelChannels": "Canales",
|
||||||
|
"LabelChapterCount": "{0} capítulos",
|
||||||
"LabelChapterTitle": "Titulo del Capítulo",
|
"LabelChapterTitle": "Titulo del Capítulo",
|
||||||
"LabelChapters": "Capítulos",
|
"LabelChapters": "Capítulos",
|
||||||
"LabelChaptersFound": "Capítulo Encontrado",
|
"LabelChaptersFound": "Capítulo Encontrado",
|
||||||
"LabelClickForMoreInfo": "Click para más información",
|
"LabelClickForMoreInfo": "Click para más información",
|
||||||
|
"LabelClickToUseCurrentValue": "Haz clic para utilizar el valor actual",
|
||||||
"LabelClosePlayer": "Cerrar reproductor",
|
"LabelClosePlayer": "Cerrar reproductor",
|
||||||
|
"LabelCodec": "Codec",
|
||||||
"LabelCollapseSeries": "Colapsar serie",
|
"LabelCollapseSeries": "Colapsar serie",
|
||||||
"LabelCollapseSubSeries": "Contraer la subserie",
|
"LabelCollapseSubSeries": "Contraer la subserie",
|
||||||
"LabelCollection": "Colección",
|
"LabelCollection": "Colección",
|
||||||
@@ -282,6 +302,7 @@
|
|||||||
"LabelEbook": "Libro electrónico",
|
"LabelEbook": "Libro electrónico",
|
||||||
"LabelEbooks": "Libros electrónicos",
|
"LabelEbooks": "Libros electrónicos",
|
||||||
"LabelEdit": "Editar",
|
"LabelEdit": "Editar",
|
||||||
|
"LabelEmail": "Correo electrónico",
|
||||||
"LabelEmailSettingsFromAddress": "Remitente",
|
"LabelEmailSettingsFromAddress": "Remitente",
|
||||||
"LabelEmailSettingsRejectUnauthorized": "Rechazar certificados no autorizados",
|
"LabelEmailSettingsRejectUnauthorized": "Rechazar certificados no autorizados",
|
||||||
"LabelEmailSettingsRejectUnauthorizedHelp": "Deshabilitar la validación de certificados SSL puede exponer tu conexión a riesgos de seguridad, como ataques man-in-the-middle. Desactiva esta opción sólo si conoces las implicaciones y confias en el servidor de correo al que te conectas.",
|
"LabelEmailSettingsRejectUnauthorizedHelp": "Deshabilitar la validación de certificados SSL puede exponer tu conexión a riesgos de seguridad, como ataques man-in-the-middle. Desactiva esta opción sólo si conoces las implicaciones y confias en el servidor de correo al que te conectas.",
|
||||||
@@ -290,11 +311,23 @@
|
|||||||
"LabelEmailSettingsTestAddress": "Probar Dirección",
|
"LabelEmailSettingsTestAddress": "Probar Dirección",
|
||||||
"LabelEmbeddedCover": "Portada Integrada",
|
"LabelEmbeddedCover": "Portada Integrada",
|
||||||
"LabelEnable": "Habilitar",
|
"LabelEnable": "Habilitar",
|
||||||
|
"LabelEncodingBackupLocation": "Se guardará una copia de seguridad de tus archivos de audio originales en:",
|
||||||
|
"LabelEncodingChaptersNotEmbedded": "Los capítulos no se incrustan en los audiolibros multipista.",
|
||||||
|
"LabelEncodingClearItemCache": "Asegúrese de purgar periódicamente la caché.",
|
||||||
|
"LabelEncodingFinishedM4B": "El M4B terminado se colocará en su carpeta de audiolibros en:",
|
||||||
|
"LabelEncodingInfoEmbedded": "Los metadatos se integrarán en las pistas de audio dentro de la carpeta de audiolibros.",
|
||||||
|
"LabelEncodingStartedNavigation": "Una vez iniciada la tarea, puedes salir de esta página.",
|
||||||
|
"LabelEncodingTimeWarning": "La codificación puede tardar hasta 30 minutos.",
|
||||||
|
"LabelEncodingWarningAdvancedSettings": "Advertencia: No actualice esta configuración a menos que esté familiarizado con las opciones de codificación de ffmpeg.",
|
||||||
|
"LabelEncodingWatcherDisabled": "Si ha desactivado la supervisión de los archivos, deberá volver a escanear este audiolibro más adelante.",
|
||||||
"LabelEnd": "Fin",
|
"LabelEnd": "Fin",
|
||||||
"LabelEndOfChapter": "Fin del capítulo",
|
"LabelEndOfChapter": "Fin del capítulo",
|
||||||
"LabelEpisode": "Episodio",
|
"LabelEpisode": "Episodio",
|
||||||
|
"LabelEpisodeNotLinkedToRssFeed": "Episodio no enlazado al feed RSS",
|
||||||
|
"LabelEpisodeNumber": "Episodio #{0}",
|
||||||
"LabelEpisodeTitle": "Titulo de Episodio",
|
"LabelEpisodeTitle": "Titulo de Episodio",
|
||||||
"LabelEpisodeType": "Tipo de Episodio",
|
"LabelEpisodeType": "Tipo de Episodio",
|
||||||
|
"LabelEpisodeUrlFromRssFeed": "URL del episodio del feed RSS",
|
||||||
"LabelEpisodes": "Episodios",
|
"LabelEpisodes": "Episodios",
|
||||||
"LabelExample": "Ejemplo",
|
"LabelExample": "Ejemplo",
|
||||||
"LabelExpandSeries": "Ampliar serie",
|
"LabelExpandSeries": "Ampliar serie",
|
||||||
@@ -323,6 +356,7 @@
|
|||||||
"LabelFontScale": "Tamaño de fuente",
|
"LabelFontScale": "Tamaño de fuente",
|
||||||
"LabelFontStrikethrough": "Tachado",
|
"LabelFontStrikethrough": "Tachado",
|
||||||
"LabelFormat": "Formato",
|
"LabelFormat": "Formato",
|
||||||
|
"LabelFull": "Completo",
|
||||||
"LabelGenre": "Genero",
|
"LabelGenre": "Genero",
|
||||||
"LabelGenres": "Géneros",
|
"LabelGenres": "Géneros",
|
||||||
"LabelHardDeleteFile": "Eliminar Definitivamente",
|
"LabelHardDeleteFile": "Eliminar Definitivamente",
|
||||||
@@ -330,6 +364,7 @@
|
|||||||
"LabelHasSupplementaryEbook": "Tiene un libro complementario",
|
"LabelHasSupplementaryEbook": "Tiene un libro complementario",
|
||||||
"LabelHideSubtitles": "Ocultar subtítulos",
|
"LabelHideSubtitles": "Ocultar subtítulos",
|
||||||
"LabelHighestPriority": "Mayor prioridad",
|
"LabelHighestPriority": "Mayor prioridad",
|
||||||
|
"LabelHost": "Host",
|
||||||
"LabelHour": "Hora",
|
"LabelHour": "Hora",
|
||||||
"LabelHours": "Horas",
|
"LabelHours": "Horas",
|
||||||
"LabelIcon": "Icono",
|
"LabelIcon": "Icono",
|
||||||
@@ -359,22 +394,25 @@
|
|||||||
"LabelLastTime": "Última Vez",
|
"LabelLastTime": "Última Vez",
|
||||||
"LabelLastUpdate": "Última Actualización",
|
"LabelLastUpdate": "Última Actualización",
|
||||||
"LabelLayout": "Distribución",
|
"LabelLayout": "Distribución",
|
||||||
"LabelLayoutSinglePage": "Una Página",
|
"LabelLayoutSinglePage": "Página única",
|
||||||
"LabelLayoutSplitPage": "Dos Páginas",
|
"LabelLayoutSplitPage": "Dos Páginas",
|
||||||
"LabelLess": "Menos",
|
"LabelLess": "Menos",
|
||||||
"LabelLibrariesAccessibleToUser": "Bibliotecas Disponibles para el Usuario",
|
"LabelLibrariesAccessibleToUser": "Bibliotecas Disponibles para el Usuario",
|
||||||
"LabelLibrary": "Biblioteca",
|
"LabelLibrary": "Biblioteca",
|
||||||
|
"LabelLibraryFilterSublistEmpty": "Sin {0}",
|
||||||
"LabelLibraryItem": "Elemento de Biblioteca",
|
"LabelLibraryItem": "Elemento de Biblioteca",
|
||||||
"LabelLibraryName": "Nombre de Biblioteca",
|
"LabelLibraryName": "Nombre de Biblioteca",
|
||||||
"LabelLimit": "Limites",
|
"LabelLimit": "Limites",
|
||||||
"LabelLineSpacing": "Interlineado",
|
"LabelLineSpacing": "Interlineado",
|
||||||
"LabelListenAgain": "Volver a escuchar",
|
"LabelListenAgain": "Volver a escuchar",
|
||||||
|
"LabelLogLevelDebug": "Depurar",
|
||||||
"LabelLogLevelInfo": "Información",
|
"LabelLogLevelInfo": "Información",
|
||||||
"LabelLogLevelWarn": "Advertencia",
|
"LabelLogLevelWarn": "Advertencia",
|
||||||
"LabelLookForNewEpisodesAfterDate": "Buscar Nuevos Episodios a partir de esta Fecha",
|
"LabelLookForNewEpisodesAfterDate": "Buscar Nuevos Episodios a partir de esta Fecha",
|
||||||
"LabelLowestPriority": "Menor prioridad",
|
"LabelLowestPriority": "Menor prioridad",
|
||||||
"LabelMatchExistingUsersBy": "Emparejar a los usuarios existentes por",
|
"LabelMatchExistingUsersBy": "Emparejar a los usuarios existentes por",
|
||||||
"LabelMatchExistingUsersByDescription": "Se utiliza para conectar usuarios existentes. Una vez conectados, los usuarios serán emparejados por un identificador único de su proveedor de SSO",
|
"LabelMatchExistingUsersByDescription": "Se utiliza para conectar usuarios existentes. Una vez conectados, los usuarios serán emparejados por un identificador único de su proveedor de SSO",
|
||||||
|
"LabelMaxEpisodesToDownload": "Número máximo # de episodios para descargar. Usa 0 para descargar una cantidad ilimitada.",
|
||||||
"LabelMediaPlayer": "Reproductor de Medios",
|
"LabelMediaPlayer": "Reproductor de Medios",
|
||||||
"LabelMediaType": "Tipo de multimedia",
|
"LabelMediaType": "Tipo de multimedia",
|
||||||
"LabelMetaTag": "Metaetiqueta",
|
"LabelMetaTag": "Metaetiqueta",
|
||||||
@@ -416,7 +454,7 @@
|
|||||||
"LabelNumberOfBooks": "Numero de Libros",
|
"LabelNumberOfBooks": "Numero de Libros",
|
||||||
"LabelNumberOfEpisodes": "# de Episodios",
|
"LabelNumberOfEpisodes": "# de Episodios",
|
||||||
"LabelOpenIDAdvancedPermsClaimDescription": "Nombre de la notificación de OpenID que contiene permisos avanzados para acciones de usuario dentro de la aplicación que se aplicarán a roles que no sean de administrador (<b>si están configurados</b>). Si el reclamo no aparece en la respuesta, se denegará el acceso a ABS. Si falta una sola opción, se tratará como <code>falsa</code>. Asegúrese de que la notificación del proveedor de identidades coincida con la estructura esperada:",
|
"LabelOpenIDAdvancedPermsClaimDescription": "Nombre de la notificación de OpenID que contiene permisos avanzados para acciones de usuario dentro de la aplicación que se aplicarán a roles que no sean de administrador (<b>si están configurados</b>). Si el reclamo no aparece en la respuesta, se denegará el acceso a ABS. Si falta una sola opción, se tratará como <code>falsa</code>. Asegúrese de que la notificación del proveedor de identidades coincida con la estructura esperada:",
|
||||||
"LabelOpenIDClaims": "Deje las siguientes opciones vacías para deshabilitar la asignación avanzada de grupos y permisos, lo que asignaría de manera automática al grupo 'Usuario'",
|
"LabelOpenIDClaims": "Deje las siguientes opciones vacías para deshabilitar la asignación avanzada de grupos y permisos, lo que asignaría de manera automática al grupo 'Usuario'.",
|
||||||
"LabelOpenIDGroupClaimDescription": "Nombre de la declaración OpenID que contiene una lista de grupos del usuario. Comúnmente conocidos como <code>grupos</code>. <b>Si se configura</b>, la aplicación asignará automáticamente roles en función de la pertenencia a grupos del usuario, siempre que estos grupos se denominen \"admin\", \"user\" o \"guest\" en la notificación. La solicitud debe contener una lista, y si un usuario pertenece a varios grupos, la aplicación asignará el rol correspondiente al mayor nivel de acceso. Si ningún grupo coincide, se denegará el acceso.",
|
"LabelOpenIDGroupClaimDescription": "Nombre de la declaración OpenID que contiene una lista de grupos del usuario. Comúnmente conocidos como <code>grupos</code>. <b>Si se configura</b>, la aplicación asignará automáticamente roles en función de la pertenencia a grupos del usuario, siempre que estos grupos se denominen \"admin\", \"user\" o \"guest\" en la notificación. La solicitud debe contener una lista, y si un usuario pertenece a varios grupos, la aplicación asignará el rol correspondiente al mayor nivel de acceso. Si ningún grupo coincide, se denegará el acceso.",
|
||||||
"LabelOpenRSSFeed": "Abrir Fuente RSS",
|
"LabelOpenRSSFeed": "Abrir Fuente RSS",
|
||||||
"LabelOverwrite": "Sobrescribir",
|
"LabelOverwrite": "Sobrescribir",
|
||||||
@@ -433,18 +471,24 @@
|
|||||||
"LabelPersonalYearReview": "Revisión de tu año ({0})",
|
"LabelPersonalYearReview": "Revisión de tu año ({0})",
|
||||||
"LabelPhotoPathURL": "Ruta de Acceso/URL de Foto",
|
"LabelPhotoPathURL": "Ruta de Acceso/URL de Foto",
|
||||||
"LabelPlayMethod": "Método de Reproducción",
|
"LabelPlayMethod": "Método de Reproducción",
|
||||||
|
"LabelPlayerChapterNumberMarker": "{0} de {1}",
|
||||||
"LabelPlaylists": "Lista de Reproducción",
|
"LabelPlaylists": "Lista de Reproducción",
|
||||||
|
"LabelPodcast": "Podcast",
|
||||||
"LabelPodcastSearchRegion": "Región de búsqueda de podcasts",
|
"LabelPodcastSearchRegion": "Región de búsqueda de podcasts",
|
||||||
"LabelPodcastType": "Tipo Podcast",
|
"LabelPodcastType": "Tipo Podcast",
|
||||||
|
"LabelPodcasts": "Podcasts",
|
||||||
"LabelPort": "Puerto",
|
"LabelPort": "Puerto",
|
||||||
"LabelPrefixesToIgnore": "Prefijos para Ignorar (no distingue entre mayúsculas y minúsculas.)",
|
"LabelPrefixesToIgnore": "Prefijos para Ignorar (no distingue entre mayúsculas y minúsculas.)",
|
||||||
"LabelPreventIndexing": "Evite que su fuente sea indexada por los directorios de podcasts de iTunes y Google",
|
"LabelPreventIndexing": "Evite que su fuente sea indexada por los directorios de podcasts de iTunes y Google",
|
||||||
"LabelPrimaryEbook": "Ebook principal",
|
"LabelPrimaryEbook": "Ebook principal",
|
||||||
"LabelProgress": "Progreso",
|
"LabelProgress": "Progreso",
|
||||||
"LabelProvider": "Proveedor",
|
"LabelProvider": "Proveedor",
|
||||||
|
"LabelProviderAuthorizationValue": "Valor del encabezado de autorización",
|
||||||
"LabelPubDate": "Fecha de publicación",
|
"LabelPubDate": "Fecha de publicación",
|
||||||
"LabelPublishYear": "Año de publicación",
|
"LabelPublishYear": "Año de publicación",
|
||||||
"LabelPublishedDate": "Publicado {0}",
|
"LabelPublishedDate": "Publicado {0}",
|
||||||
|
"LabelPublishedDecade": "Década de publicación",
|
||||||
|
"LabelPublishedDecades": "Décadas publicadas",
|
||||||
"LabelPublisher": "Editor",
|
"LabelPublisher": "Editor",
|
||||||
"LabelPublishers": "Editores",
|
"LabelPublishers": "Editores",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "Correo electrónico de dueño personalizado",
|
"LabelRSSFeedCustomOwnerEmail": "Correo electrónico de dueño personalizado",
|
||||||
@@ -476,8 +520,10 @@
|
|||||||
"LabelSelectUsers": "Seleccionar usuarios",
|
"LabelSelectUsers": "Seleccionar usuarios",
|
||||||
"LabelSendEbookToDevice": "Enviar Ebook a...",
|
"LabelSendEbookToDevice": "Enviar Ebook a...",
|
||||||
"LabelSequence": "Secuencia",
|
"LabelSequence": "Secuencia",
|
||||||
|
"LabelSeries": "Series",
|
||||||
"LabelSeriesName": "Nombre de la Serie",
|
"LabelSeriesName": "Nombre de la Serie",
|
||||||
"LabelSeriesProgress": "Progreso de la Serie",
|
"LabelSeriesProgress": "Progreso de la Serie",
|
||||||
|
"LabelServerLogLevel": "Nivel de registro del servidor",
|
||||||
"LabelServerYearReview": "Resumen del año del servidor ({0})",
|
"LabelServerYearReview": "Resumen del año del servidor ({0})",
|
||||||
"LabelSetEbookAsPrimary": "Establecer como primario",
|
"LabelSetEbookAsPrimary": "Establecer como primario",
|
||||||
"LabelSetEbookAsSupplementary": "Establecer como suplementario",
|
"LabelSetEbookAsSupplementary": "Establecer como suplementario",
|
||||||
@@ -527,6 +573,7 @@
|
|||||||
"LabelShowSubtitles": "Mostrar subtítulos",
|
"LabelShowSubtitles": "Mostrar subtítulos",
|
||||||
"LabelSize": "Tamaño",
|
"LabelSize": "Tamaño",
|
||||||
"LabelSleepTimer": "Temporizador de apagado",
|
"LabelSleepTimer": "Temporizador de apagado",
|
||||||
|
"LabelSlug": "Slug",
|
||||||
"LabelStart": "Iniciar",
|
"LabelStart": "Iniciar",
|
||||||
"LabelStartTime": "Tiempo de Inicio",
|
"LabelStartTime": "Tiempo de Inicio",
|
||||||
"LabelStarted": "Iniciado",
|
"LabelStarted": "Iniciado",
|
||||||
@@ -572,6 +619,7 @@
|
|||||||
"LabelTitle": "Título",
|
"LabelTitle": "Título",
|
||||||
"LabelToolsEmbedMetadata": "Incrustar Metadatos",
|
"LabelToolsEmbedMetadata": "Incrustar Metadatos",
|
||||||
"LabelToolsEmbedMetadataDescription": "Incrusta metadatos en los archivos de audio, incluyendo la portada y capítulos.",
|
"LabelToolsEmbedMetadataDescription": "Incrusta metadatos en los archivos de audio, incluyendo la portada y capítulos.",
|
||||||
|
"LabelToolsM4bEncoder": "Codificador M4B",
|
||||||
"LabelToolsMakeM4b": "Hacer Archivo de Audiolibro M4B",
|
"LabelToolsMakeM4b": "Hacer Archivo de Audiolibro M4B",
|
||||||
"LabelToolsMakeM4bDescription": "Generar archivo de audiolibro .M4B con metadatos, imágenes de portada y capítulos incorporados.",
|
"LabelToolsMakeM4bDescription": "Generar archivo de audiolibro .M4B con metadatos, imágenes de portada y capítulos incorporados.",
|
||||||
"LabelToolsSplitM4b": "Dividir M4B en Archivos MP3",
|
"LabelToolsSplitM4b": "Dividir M4B en Archivos MP3",
|
||||||
@@ -597,6 +645,7 @@
|
|||||||
"LabelUploaderDragAndDrop": "Arrastre y suelte archivos o carpetas",
|
"LabelUploaderDragAndDrop": "Arrastre y suelte archivos o carpetas",
|
||||||
"LabelUploaderDropFiles": "Suelte los Archivos",
|
"LabelUploaderDropFiles": "Suelte los Archivos",
|
||||||
"LabelUploaderItemFetchMetadataHelp": "Buscar título, autor y series automáticamente",
|
"LabelUploaderItemFetchMetadataHelp": "Buscar título, autor y series automáticamente",
|
||||||
|
"LabelUseAdvancedOptions": "Usar opciones avanzadas",
|
||||||
"LabelUseChapterTrack": "Usar pista por capitulo",
|
"LabelUseChapterTrack": "Usar pista por capitulo",
|
||||||
"LabelUseFullTrack": "Usar pista completa",
|
"LabelUseFullTrack": "Usar pista completa",
|
||||||
"LabelUser": "Usuario",
|
"LabelUser": "Usuario",
|
||||||
@@ -624,14 +673,14 @@
|
|||||||
"MessageBackupsLocationNoEditNote": "Nota: La ubicación de la copia de seguridad se establece a través de una variable de entorno y no se puede cambiar aquí.",
|
"MessageBackupsLocationNoEditNote": "Nota: La ubicación de la copia de seguridad se establece a través de una variable de entorno y no se puede cambiar aquí.",
|
||||||
"MessageBackupsLocationPathEmpty": "La ruta de la copia de seguridad no puede estar vacía",
|
"MessageBackupsLocationPathEmpty": "La ruta de la copia de seguridad no puede estar vacía",
|
||||||
"MessageBatchQuickMatchDescription": "\"Encontrar Rápido\" tratará de agregar portadas y metadatos faltantes de los elementos seleccionados. Habilite la opción de abajo para que \"Encontrar Rápido\" pueda sobrescribir portadas y/o metadatos existentes.",
|
"MessageBatchQuickMatchDescription": "\"Encontrar Rápido\" tratará de agregar portadas y metadatos faltantes de los elementos seleccionados. Habilite la opción de abajo para que \"Encontrar Rápido\" pueda sobrescribir portadas y/o metadatos existentes.",
|
||||||
"MessageBookshelfNoCollections": "No tienes ninguna colección.",
|
"MessageBookshelfNoCollections": "No tienes ninguna colección",
|
||||||
"MessageBookshelfNoRSSFeeds": "Ninguna Fuente RSS esta abierta",
|
"MessageBookshelfNoRSSFeeds": "Ninguna Fuente RSS esta abierta",
|
||||||
"MessageBookshelfNoResultsForFilter": "Ningún Resultado para el filtro \"{0}: {1}\"",
|
"MessageBookshelfNoResultsForFilter": "Ningún Resultado para el filtro \"{0}: {1}\"",
|
||||||
"MessageBookshelfNoResultsForQuery": "No hay resultados para la consulta",
|
"MessageBookshelfNoResultsForQuery": "No hay resultados para la consulta",
|
||||||
"MessageBookshelfNoSeries": "No tienes ninguna serie",
|
"MessageBookshelfNoSeries": "No tienes ninguna serie",
|
||||||
"MessageChapterEndIsAfter": "El final del capítulo es después del final de tu audiolibro.",
|
"MessageChapterEndIsAfter": "El final del capítulo es después del final de tu audiolibro",
|
||||||
"MessageChapterErrorFirstNotZero": "El primer capitulo debe iniciar en 0",
|
"MessageChapterErrorFirstNotZero": "El primer capitulo debe iniciar en 0",
|
||||||
"MessageChapterErrorStartGteDuration": "El tiempo de inicio no es válido: debe ser inferior a la duración del audiolibro.",
|
"MessageChapterErrorStartGteDuration": "El tiempo de inicio no es válido: debe ser inferior a la duración del audiolibro",
|
||||||
"MessageChapterErrorStartLtPrev": "El tiempo de inicio no es válido: debe ser mayor o igual que el tiempo de inicio del capítulo anterior",
|
"MessageChapterErrorStartLtPrev": "El tiempo de inicio no es válido: debe ser mayor o igual que el tiempo de inicio del capítulo anterior",
|
||||||
"MessageChapterStartIsAfter": "El comienzo del capítulo es después del final de su audiolibro",
|
"MessageChapterStartIsAfter": "El comienzo del capítulo es después del final de su audiolibro",
|
||||||
"MessageCheckingCron": "Revisando cron...",
|
"MessageCheckingCron": "Revisando cron...",
|
||||||
@@ -645,6 +694,7 @@
|
|||||||
"MessageConfirmDeleteMetadataProvider": "¿Estás seguro de que deseas eliminar el proveedor de metadatos personalizado \"{0}\"?",
|
"MessageConfirmDeleteMetadataProvider": "¿Estás seguro de que deseas eliminar el proveedor de metadatos personalizado \"{0}\"?",
|
||||||
"MessageConfirmDeleteNotification": "¿Estás seguro de que deseas eliminar esta notificación?",
|
"MessageConfirmDeleteNotification": "¿Estás seguro de que deseas eliminar esta notificación?",
|
||||||
"MessageConfirmDeleteSession": "¿Está seguro de que desea eliminar esta sesión?",
|
"MessageConfirmDeleteSession": "¿Está seguro de que desea eliminar esta sesión?",
|
||||||
|
"MessageConfirmEmbedMetadataInAudioFiles": "¿Está seguro de que desea incrustar metadatos en {0} archivos de audio?",
|
||||||
"MessageConfirmForceReScan": "¿Está seguro de que desea forzar un re-escaneo?",
|
"MessageConfirmForceReScan": "¿Está seguro de que desea forzar un re-escaneo?",
|
||||||
"MessageConfirmMarkAllEpisodesFinished": "¿Está seguro de que desea marcar todos los episodios como terminados?",
|
"MessageConfirmMarkAllEpisodesFinished": "¿Está seguro de que desea marcar todos los episodios como terminados?",
|
||||||
"MessageConfirmMarkAllEpisodesNotFinished": "¿Está seguro de que desea marcar todos los episodios como no terminados?",
|
"MessageConfirmMarkAllEpisodesNotFinished": "¿Está seguro de que desea marcar todos los episodios como no terminados?",
|
||||||
@@ -673,10 +723,12 @@
|
|||||||
"MessageConfirmRenameTagWarning": "Advertencia! Una etiqueta similar ya existe \"{0}\".",
|
"MessageConfirmRenameTagWarning": "Advertencia! Una etiqueta similar ya existe \"{0}\".",
|
||||||
"MessageConfirmResetProgress": "¿Estás seguro de que quieres reiniciar tu progreso?",
|
"MessageConfirmResetProgress": "¿Estás seguro de que quieres reiniciar tu progreso?",
|
||||||
"MessageConfirmSendEbookToDevice": "¿Está seguro de que enviar {0} ebook(s) \"{1}\" al dispositivo \"{2}\"?",
|
"MessageConfirmSendEbookToDevice": "¿Está seguro de que enviar {0} ebook(s) \"{1}\" al dispositivo \"{2}\"?",
|
||||||
|
"MessageConfirmUnlinkOpenId": "¿Estás seguro de que deseas desvincular este usuario de OpenID?",
|
||||||
"MessageDownloadingEpisode": "Descargando Capitulo",
|
"MessageDownloadingEpisode": "Descargando Capitulo",
|
||||||
"MessageDragFilesIntoTrackOrder": "Arrastra los archivos al orden correcto de las pistas.",
|
"MessageDragFilesIntoTrackOrder": "Arrastra los archivos al orden correcto de las pistas",
|
||||||
"MessageEmbedFailed": "¡Error al insertar!",
|
"MessageEmbedFailed": "¡Error al insertar!",
|
||||||
"MessageEmbedFinished": "Incrustación Terminada!",
|
"MessageEmbedFinished": "Incrustación Terminada!",
|
||||||
|
"MessageEmbedQueue": "En cola para incrustar metadatos ({0} en cola)",
|
||||||
"MessageEpisodesQueuedForDownload": "{0} Episodio(s) en cola para descargar",
|
"MessageEpisodesQueuedForDownload": "{0} Episodio(s) en cola para descargar",
|
||||||
"MessageEreaderDevices": "Para garantizar la entrega de libros electrónicos, es posible que tenga que agregar la dirección de correo electrónico anterior como remitente válido para cada dispositivo enumerado a continuación.",
|
"MessageEreaderDevices": "Para garantizar la entrega de libros electrónicos, es posible que tenga que agregar la dirección de correo electrónico anterior como remitente válido para cada dispositivo enumerado a continuación.",
|
||||||
"MessageFeedURLWillBe": "URL de la fuente será {0}",
|
"MessageFeedURLWillBe": "URL de la fuente será {0}",
|
||||||
@@ -707,6 +759,7 @@
|
|||||||
"MessageNoCollections": "Sin Colecciones",
|
"MessageNoCollections": "Sin Colecciones",
|
||||||
"MessageNoCoversFound": "Ninguna Portada Encontrada",
|
"MessageNoCoversFound": "Ninguna Portada Encontrada",
|
||||||
"MessageNoDescription": "Sin Descripción",
|
"MessageNoDescription": "Sin Descripción",
|
||||||
|
"MessageNoDevices": "Sin dispositivos",
|
||||||
"MessageNoDownloadsInProgress": "No hay descargas actualmente en curso",
|
"MessageNoDownloadsInProgress": "No hay descargas actualmente en curso",
|
||||||
"MessageNoDownloadsQueued": "Sin Lista de Descarga",
|
"MessageNoDownloadsQueued": "Sin Lista de Descarga",
|
||||||
"MessageNoEpisodeMatchesFound": "No se encontraron episodios que coinciden",
|
"MessageNoEpisodeMatchesFound": "No se encontraron episodios que coinciden",
|
||||||
@@ -720,6 +773,7 @@
|
|||||||
"MessageNoLogs": "No hay logs",
|
"MessageNoLogs": "No hay logs",
|
||||||
"MessageNoMediaProgress": "Multimedia sin Progreso",
|
"MessageNoMediaProgress": "Multimedia sin Progreso",
|
||||||
"MessageNoNotifications": "Ninguna Notificación",
|
"MessageNoNotifications": "Ninguna Notificación",
|
||||||
|
"MessageNoPodcastFeed": "Podcast no válido: Sin feed",
|
||||||
"MessageNoPodcastsFound": "Ningún podcast encontrado",
|
"MessageNoPodcastsFound": "Ningún podcast encontrado",
|
||||||
"MessageNoResults": "Sin Resultados",
|
"MessageNoResults": "Sin Resultados",
|
||||||
"MessageNoSearchResultsFor": "No hay resultados para la búsqueda \"{0}\"",
|
"MessageNoSearchResultsFor": "No hay resultados para la búsqueda \"{0}\"",
|
||||||
@@ -734,7 +788,11 @@
|
|||||||
"MessagePauseChapter": "Pausar la reproducción del capítulo",
|
"MessagePauseChapter": "Pausar la reproducción del capítulo",
|
||||||
"MessagePlayChapter": "Escuchar el comienzo del capítulo",
|
"MessagePlayChapter": "Escuchar el comienzo del capítulo",
|
||||||
"MessagePlaylistCreateFromCollection": "Crear una lista de reproducción a partir de una colección",
|
"MessagePlaylistCreateFromCollection": "Crear una lista de reproducción a partir de una colección",
|
||||||
|
"MessagePleaseWait": "Por favor, espera...",
|
||||||
"MessagePodcastHasNoRSSFeedForMatching": "El podcast no tiene una URL de fuente RSS que pueda usar",
|
"MessagePodcastHasNoRSSFeedForMatching": "El podcast no tiene una URL de fuente RSS que pueda usar",
|
||||||
|
"MessagePodcastSearchField": "Introduzca el término de búsqueda o la URL de la fuente RSS",
|
||||||
|
"MessageQuickEmbedInProgress": "Integración rápida en proceso",
|
||||||
|
"MessageQuickEmbedQueue": "En cola para inserción rápida ({0} en cola)",
|
||||||
"MessageQuickMatchDescription": "Rellenar detalles de elementos vacíos y portada con los primeros resultados de '{0}'. No sobrescribe los detalles a menos que la opción \"Preferir Metadatos Encontrados\" del servidor esté habilitada.",
|
"MessageQuickMatchDescription": "Rellenar detalles de elementos vacíos y portada con los primeros resultados de '{0}'. No sobrescribe los detalles a menos que la opción \"Preferir Metadatos Encontrados\" del servidor esté habilitada.",
|
||||||
"MessageRemoveChapter": "Remover capítulos",
|
"MessageRemoveChapter": "Remover capítulos",
|
||||||
"MessageRemoveEpisodes": "Remover {0} episodio(s)",
|
"MessageRemoveEpisodes": "Remover {0} episodio(s)",
|
||||||
@@ -752,6 +810,41 @@
|
|||||||
"MessageShareExpiresIn": "Caduduca en {0}",
|
"MessageShareExpiresIn": "Caduduca en {0}",
|
||||||
"MessageShareURLWillBe": "La URL para compartir será <strong> {0} </strong>",
|
"MessageShareURLWillBe": "La URL para compartir será <strong> {0} </strong>",
|
||||||
"MessageStartPlaybackAtTime": "Iniciar reproducción para \"{0}\" en {1}?",
|
"MessageStartPlaybackAtTime": "Iniciar reproducción para \"{0}\" en {1}?",
|
||||||
|
"MessageTaskAudioFileNotWritable": "El archivo de audio \"{0}\" no se puede grabar",
|
||||||
|
"MessageTaskCanceledByUser": "Tarea cancelada por el usuario",
|
||||||
|
"MessageTaskDownloadingEpisodeDescription": "Descargando el episodio \"{0}\"",
|
||||||
|
"MessageTaskEmbeddingMetadata": "Inserción de metadatos",
|
||||||
|
"MessageTaskEmbeddingMetadataDescription": "Inserción de metadatos en el audiolibro \"{0}\"",
|
||||||
|
"MessageTaskEncodingM4b": "Codificación M4B",
|
||||||
|
"MessageTaskEncodingM4bDescription": "Codificación del audiolibro \"{0}\" en un único archivo m4b",
|
||||||
|
"MessageTaskFailed": "Fallida",
|
||||||
|
"MessageTaskFailedToBackupAudioFile": "Error en la copia de seguridad del archivo de audio \"{0}\"",
|
||||||
|
"MessageTaskFailedToCreateCacheDirectory": "Error al crear el directorio de la caché",
|
||||||
|
"MessageTaskFailedToEmbedMetadataInFile": "Error al incrustar metadatos en el archivo \"{0}\"",
|
||||||
|
"MessageTaskFailedToMergeAudioFiles": "Error al fusionar archivos de audio",
|
||||||
|
"MessageTaskFailedToMoveM4bFile": "Error al mover el archivo m4b",
|
||||||
|
"MessageTaskFailedToWriteMetadataFile": "Error al escribir el archivo de metadatos",
|
||||||
|
"MessageTaskMatchingBooksInLibrary": "Libros coincidentes en la biblioteca \"{0}\"",
|
||||||
|
"MessageTaskNoFilesToScan": "Sin archivos para escanear",
|
||||||
|
"MessageTaskOpmlImport": "Importar OPML",
|
||||||
|
"MessageTaskOpmlImportDescription": "Creando podcasts a partir de {0} fuentes RSS",
|
||||||
|
"MessageTaskOpmlImportFeed": "Feed de importación OPML",
|
||||||
|
"MessageTaskOpmlImportFeedDescription": "Importando el feed RSS \"{0}\"",
|
||||||
|
"MessageTaskOpmlImportFeedFailed": "No se puede obtener el podcast",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastDescription": "Creando podcast \"{0}\"",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastExists": "Podcast ya existe en la ruta",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastFailed": "Error al crear podcast",
|
||||||
|
"MessageTaskOpmlImportFinished": "Añadido {0} podcasts",
|
||||||
|
"MessageTaskOpmlParseFailed": "No se pudo analizar el archivo OPML",
|
||||||
|
"MessageTaskOpmlParseFastFail": "No se encontró la etiqueta <opml> del archivo OPML no válido O no se encontró la etiqueta <outline>",
|
||||||
|
"MessageTaskOpmlParseNoneFound": "No se encontraron fuentes en el archivo OPML",
|
||||||
|
"MessageTaskScanItemsAdded": "{0} añadido",
|
||||||
|
"MessageTaskScanItemsMissing": "Falta {0}",
|
||||||
|
"MessageTaskScanItemsUpdated": "{0} actualizado",
|
||||||
|
"MessageTaskScanNoChangesNeeded": "No se necesitan cambios",
|
||||||
|
"MessageTaskScanningFileChanges": "Escaneando cambios en el archivo en \"{0}\"",
|
||||||
|
"MessageTaskScanningLibrary": "Escaneando la biblioteca \"{0}\"",
|
||||||
|
"MessageTaskTargetDirectoryNotWritable": "El directorio de destino no se puede escribir",
|
||||||
"MessageThinking": "Pensando...",
|
"MessageThinking": "Pensando...",
|
||||||
"MessageUploaderItemFailed": "Error al Subir",
|
"MessageUploaderItemFailed": "Error al Subir",
|
||||||
"MessageUploaderItemSuccess": "¡Éxito al Subir!",
|
"MessageUploaderItemSuccess": "¡Éxito al Subir!",
|
||||||
@@ -769,6 +862,10 @@
|
|||||||
"NoteUploaderFoldersWithMediaFiles": "Las carpetas con archivos multimedia se manejarán como elementos separados en la biblioteca.",
|
"NoteUploaderFoldersWithMediaFiles": "Las carpetas con archivos multimedia se manejarán como elementos separados en la biblioteca.",
|
||||||
"NoteUploaderOnlyAudioFiles": "Si sube solamente archivos de audio, cada archivo se manejará como un audiolibro por separado.",
|
"NoteUploaderOnlyAudioFiles": "Si sube solamente archivos de audio, cada archivo se manejará como un audiolibro por separado.",
|
||||||
"NoteUploaderUnsupportedFiles": "Se ignorarán los archivos no soportados. Al elegir o arrastrar una carpeta, los archivos que no estén dentro de una subcarpeta serán ignorados.",
|
"NoteUploaderUnsupportedFiles": "Se ignorarán los archivos no soportados. Al elegir o arrastrar una carpeta, los archivos que no estén dentro de una subcarpeta serán ignorados.",
|
||||||
|
"NotificationOnBackupCompletedDescription": "Se activa cuando se completa una copia de seguridad",
|
||||||
|
"NotificationOnBackupFailedDescription": "Se activa cuando falla una copia de seguridad",
|
||||||
|
"NotificationOnEpisodeDownloadedDescription": "Se activa cuando se descarga automáticamente un episodio de un podcast",
|
||||||
|
"NotificationOnTestDescription": "Evento para probar el sistema de notificaciones",
|
||||||
"PlaceholderNewCollection": "Nuevo nombre de la colección",
|
"PlaceholderNewCollection": "Nuevo nombre de la colección",
|
||||||
"PlaceholderNewFolderPath": "Nueva ruta de carpeta",
|
"PlaceholderNewFolderPath": "Nueva ruta de carpeta",
|
||||||
"PlaceholderNewPlaylist": "Nuevo nombre de la lista de reproducción",
|
"PlaceholderNewPlaylist": "Nuevo nombre de la lista de reproducción",
|
||||||
@@ -792,80 +889,145 @@
|
|||||||
"StatsTopNarrators": "NARRADORES DESTACADOS",
|
"StatsTopNarrators": "NARRADORES DESTACADOS",
|
||||||
"StatsTotalDuration": "Con una duración total de…",
|
"StatsTotalDuration": "Con una duración total de…",
|
||||||
"StatsYearInReview": "RESEÑA DEL AÑO",
|
"StatsYearInReview": "RESEÑA DEL AÑO",
|
||||||
"ToastAccountUpdateFailed": "Error al actualizar cuenta",
|
|
||||||
"ToastAccountUpdateSuccess": "Cuenta actualizada",
|
"ToastAccountUpdateSuccess": "Cuenta actualizada",
|
||||||
|
"ToastAppriseUrlRequired": "Debes ingresar una URL de Apprise",
|
||||||
"ToastAuthorImageRemoveSuccess": "Se eliminó la imagen del autor",
|
"ToastAuthorImageRemoveSuccess": "Se eliminó la imagen del autor",
|
||||||
"ToastAuthorUpdateFailed": "Error al actualizar el autor",
|
"ToastAuthorNotFound": "No se encontró el autor \"{0}\"",
|
||||||
|
"ToastAuthorRemoveSuccess": "Autor eliminado",
|
||||||
|
"ToastAuthorSearchNotFound": "No se encontró al autor",
|
||||||
"ToastAuthorUpdateMerged": "Autor combinado",
|
"ToastAuthorUpdateMerged": "Autor combinado",
|
||||||
"ToastAuthorUpdateSuccess": "Autor actualizado",
|
"ToastAuthorUpdateSuccess": "Autor actualizado",
|
||||||
"ToastAuthorUpdateSuccessNoImageFound": "Autor actualizado (Imagen no encontrada)",
|
"ToastAuthorUpdateSuccessNoImageFound": "Autor actualizado (Imagen no encontrada)",
|
||||||
|
"ToastBackupAppliedSuccess": "Copia de seguridad aplicada",
|
||||||
"ToastBackupCreateFailed": "Error al crear respaldo",
|
"ToastBackupCreateFailed": "Error al crear respaldo",
|
||||||
"ToastBackupCreateSuccess": "Respaldo creado",
|
"ToastBackupCreateSuccess": "Respaldo creado",
|
||||||
"ToastBackupDeleteFailed": "Error al eliminar respaldo",
|
"ToastBackupDeleteFailed": "Error al eliminar respaldo",
|
||||||
"ToastBackupDeleteSuccess": "Respaldo eliminado",
|
"ToastBackupDeleteSuccess": "Respaldo eliminado",
|
||||||
|
"ToastBackupInvalidMaxKeep": "Número no válido de copias de seguridad a conservar",
|
||||||
|
"ToastBackupInvalidMaxSize": "Tamaño máximo de copia de seguridad no válido",
|
||||||
"ToastBackupRestoreFailed": "Error al restaurar el respaldo",
|
"ToastBackupRestoreFailed": "Error al restaurar el respaldo",
|
||||||
"ToastBackupUploadFailed": "Error al subir el respaldo",
|
"ToastBackupUploadFailed": "Error al subir el respaldo",
|
||||||
"ToastBackupUploadSuccess": "Respaldo cargado",
|
"ToastBackupUploadSuccess": "Respaldo cargado",
|
||||||
|
"ToastBatchDeleteFailed": "Error al eliminar por lotes",
|
||||||
|
"ToastBatchDeleteSuccess": "Borrado por lotes correcto",
|
||||||
"ToastBatchUpdateFailed": "Subida masiva fallida",
|
"ToastBatchUpdateFailed": "Subida masiva fallida",
|
||||||
"ToastBatchUpdateSuccess": "Subida masiva exitosa",
|
"ToastBatchUpdateSuccess": "Subida masiva exitosa",
|
||||||
"ToastBookmarkCreateFailed": "Error al crear marcador",
|
"ToastBookmarkCreateFailed": "Error al crear marcador",
|
||||||
"ToastBookmarkCreateSuccess": "Marcador Agregado",
|
"ToastBookmarkCreateSuccess": "Marcador Agregado",
|
||||||
"ToastBookmarkRemoveSuccess": "Marcador eliminado",
|
"ToastBookmarkRemoveSuccess": "Marcador eliminado",
|
||||||
"ToastBookmarkUpdateFailed": "Error al actualizar el marcador",
|
|
||||||
"ToastBookmarkUpdateSuccess": "Marcador actualizado",
|
"ToastBookmarkUpdateSuccess": "Marcador actualizado",
|
||||||
"ToastCachePurgeFailed": "Error al purgar el caché",
|
"ToastCachePurgeFailed": "Error al purgar el caché",
|
||||||
"ToastCachePurgeSuccess": "Caché purgado de manera exitosa",
|
"ToastCachePurgeSuccess": "Caché purgado de manera exitosa",
|
||||||
"ToastChaptersHaveErrors": "Los capítulos tienen errores",
|
"ToastChaptersHaveErrors": "Los capítulos tienen errores",
|
||||||
"ToastChaptersMustHaveTitles": "Los capítulos tienen que tener un título",
|
"ToastChaptersMustHaveTitles": "Los capítulos tienen que tener un título",
|
||||||
|
"ToastChaptersRemoved": "Capítulos eliminados",
|
||||||
|
"ToastCollectionItemsAddFailed": "Artículo(s) añadido(s) a la colección fallido(s)",
|
||||||
|
"ToastCollectionItemsAddSuccess": "Artículo(s) añadido(s) a la colección correctamente",
|
||||||
"ToastCollectionItemsRemoveSuccess": "Elementos(s) removidos de la colección",
|
"ToastCollectionItemsRemoveSuccess": "Elementos(s) removidos de la colección",
|
||||||
"ToastCollectionRemoveSuccess": "Colección removida",
|
"ToastCollectionRemoveSuccess": "Colección removida",
|
||||||
"ToastCollectionUpdateFailed": "Error al actualizar la colección",
|
|
||||||
"ToastCollectionUpdateSuccess": "Colección actualizada",
|
"ToastCollectionUpdateSuccess": "Colección actualizada",
|
||||||
|
"ToastCoverUpdateFailed": "Error al actualizar la cubierta",
|
||||||
"ToastDeleteFileFailed": "Error el eliminar archivo",
|
"ToastDeleteFileFailed": "Error el eliminar archivo",
|
||||||
"ToastDeleteFileSuccess": "Archivo eliminado",
|
"ToastDeleteFileSuccess": "Archivo eliminado",
|
||||||
|
"ToastDeviceAddFailed": "Error al añadir dispositivo",
|
||||||
|
"ToastDeviceNameAlreadyExists": "Un libro electrónico ya existe con ese nombre",
|
||||||
|
"ToastDeviceTestEmailFailed": "Error al enviar correo de prueba",
|
||||||
|
"ToastDeviceTestEmailSuccess": "Correo electrónico de prueba enviado",
|
||||||
|
"ToastEmailSettingsUpdateSuccess": "Configuración del correo electrónico actualizada",
|
||||||
|
"ToastEncodeCancelFailed": "No se pudo cancelar la codificación",
|
||||||
|
"ToastEncodeCancelSucces": "Codificación cancelada",
|
||||||
|
"ToastEpisodeDownloadQueueClearFailed": "No se pudo borrar la cola",
|
||||||
|
"ToastEpisodeDownloadQueueClearSuccess": "Se borró la cola de descargas de los episodios",
|
||||||
"ToastErrorCannotShare": "No se puede compartir de forma nativa en este dispositivo",
|
"ToastErrorCannotShare": "No se puede compartir de forma nativa en este dispositivo",
|
||||||
"ToastFailedToLoadData": "Error al cargar data",
|
"ToastFailedToLoadData": "Error al cargar data",
|
||||||
"ToastItemCoverUpdateFailed": "Error al actualizar la portada del elemento",
|
"ToastFailedToShare": "Error al compartir",
|
||||||
|
"ToastFailedToUpdate": "Error al actualizar",
|
||||||
|
"ToastInvalidImageUrl": "URL de la imagen no válida",
|
||||||
|
"ToastInvalidUrl": "URL no válida",
|
||||||
"ToastItemCoverUpdateSuccess": "Portada del elemento actualizada",
|
"ToastItemCoverUpdateSuccess": "Portada del elemento actualizada",
|
||||||
"ToastItemDetailsUpdateFailed": "Error al actualizar los detalles del elemento",
|
"ToastItemDeletedFailed": "Error al eliminar el elemento",
|
||||||
|
"ToastItemDeletedSuccess": "Elemento borrado",
|
||||||
"ToastItemDetailsUpdateSuccess": "Detalles del Elemento Actualizados",
|
"ToastItemDetailsUpdateSuccess": "Detalles del Elemento Actualizados",
|
||||||
"ToastItemMarkedAsFinishedFailed": "Error al marcar como terminado",
|
"ToastItemMarkedAsFinishedFailed": "Error al marcar como terminado",
|
||||||
"ToastItemMarkedAsFinishedSuccess": "Elemento marcado como terminado",
|
"ToastItemMarkedAsFinishedSuccess": "Elemento marcado como terminado",
|
||||||
"ToastItemMarkedAsNotFinishedFailed": "No se ha podido marcar como no finalizado",
|
"ToastItemMarkedAsNotFinishedFailed": "No se ha podido marcar como no finalizado",
|
||||||
"ToastItemMarkedAsNotFinishedSuccess": "Elemento marcado como No Terminado",
|
"ToastItemMarkedAsNotFinishedSuccess": "Elemento marcado como No Terminado",
|
||||||
|
"ToastItemUpdateSuccess": "Elemento actualizado",
|
||||||
"ToastLibraryCreateFailed": "Error al crear biblioteca",
|
"ToastLibraryCreateFailed": "Error al crear biblioteca",
|
||||||
"ToastLibraryCreateSuccess": "Biblioteca \"{0}\" creada",
|
"ToastLibraryCreateSuccess": "Biblioteca \"{0}\" creada",
|
||||||
"ToastLibraryDeleteFailed": "Error al eliminar biblioteca",
|
"ToastLibraryDeleteFailed": "Error al eliminar biblioteca",
|
||||||
"ToastLibraryDeleteSuccess": "Biblioteca eliminada",
|
"ToastLibraryDeleteSuccess": "Biblioteca eliminada",
|
||||||
"ToastLibraryScanFailedToStart": "Error al iniciar el escaneo",
|
"ToastLibraryScanFailedToStart": "Error al iniciar el escaneo",
|
||||||
"ToastLibraryScanStarted": "Se inició el escaneo de la biblioteca",
|
"ToastLibraryScanStarted": "Se inició el escaneo de la biblioteca",
|
||||||
"ToastLibraryUpdateFailed": "Error al actualizar la biblioteca",
|
|
||||||
"ToastLibraryUpdateSuccess": "Biblioteca \"{0}\" actualizada",
|
"ToastLibraryUpdateSuccess": "Biblioteca \"{0}\" actualizada",
|
||||||
|
"ToastMatchAllAuthorsFailed": "No coincide con todos los autores",
|
||||||
|
"ToastNameEmailRequired": "Son obligatorios el nombre y el correo electrónico",
|
||||||
|
"ToastNameRequired": "Nombre obligatorio",
|
||||||
|
"ToastNewUserCreatedFailed": "Error al crear la cuenta: \"{0}\"",
|
||||||
|
"ToastNewUserCreatedSuccess": "Nueva cuenta creada",
|
||||||
|
"ToastNewUserLibraryError": "Debes seleccionar al menos una biblioteca",
|
||||||
|
"ToastNewUserPasswordError": "Debes tener una contraseña, solo el usuario root puede estar sin contraseña",
|
||||||
|
"ToastNewUserTagError": "Debes seleccionar al menos una etiqueta",
|
||||||
|
"ToastNewUserUsernameError": "Introduce un nombre de usuario",
|
||||||
|
"ToastNoUpdatesNecessary": "No es necesario actualizar",
|
||||||
|
"ToastNotificationCreateFailed": "Error al crear notificación",
|
||||||
|
"ToastNotificationDeleteFailed": "Error al borrar la notificación",
|
||||||
|
"ToastNotificationFailedMaximum": "El número máximo de intentos fallidos debe ser ≥ 0",
|
||||||
|
"ToastNotificationQueueMaximum": "La cola de notificación máxima debe ser ≥ 0",
|
||||||
|
"ToastNotificationSettingsUpdateSuccess": "Ajustes de la notificación actualizados",
|
||||||
|
"ToastNotificationTestTriggerFailed": "No se ha podido activar la notificación de prueba",
|
||||||
|
"ToastNotificationTestTriggerSuccess": "Notificación de prueba activada",
|
||||||
|
"ToastNotificationUpdateSuccess": "Notificación actualizada",
|
||||||
"ToastPlaylistCreateFailed": "Error al crear la lista de reproducción",
|
"ToastPlaylistCreateFailed": "Error al crear la lista de reproducción",
|
||||||
"ToastPlaylistCreateSuccess": "Lista de reproducción creada",
|
"ToastPlaylistCreateSuccess": "Lista de reproducción creada",
|
||||||
"ToastPlaylistRemoveSuccess": "Lista de reproducción eliminada",
|
"ToastPlaylistRemoveSuccess": "Lista de reproducción eliminada",
|
||||||
"ToastPlaylistUpdateFailed": "Error al actualizar la lista de reproducción.",
|
|
||||||
"ToastPlaylistUpdateSuccess": "Lista de reproducción actualizada",
|
"ToastPlaylistUpdateSuccess": "Lista de reproducción actualizada",
|
||||||
"ToastPodcastCreateFailed": "Error al crear podcast",
|
"ToastPodcastCreateFailed": "Error al crear podcast",
|
||||||
"ToastPodcastCreateSuccess": "Podcast creado",
|
"ToastPodcastCreateSuccess": "Podcast creado",
|
||||||
|
"ToastPodcastGetFeedFailed": "No se puede obtener el podcast",
|
||||||
|
"ToastPodcastNoEpisodesInFeed": "No se han encontrado episodios en el feed del RSS",
|
||||||
|
"ToastPodcastNoRssFeed": "El podcast no tiene feed RSS",
|
||||||
|
"ToastProviderCreatedFailed": "Error al añadir el proveedor",
|
||||||
|
"ToastProviderCreatedSuccess": "Nuevo proveedor añadido",
|
||||||
|
"ToastProviderNameAndUrlRequired": "Nombre y Url obligatorios",
|
||||||
|
"ToastProviderRemoveSuccess": "Proveedor eliminado",
|
||||||
"ToastRSSFeedCloseFailed": "Error al cerrar fuente RSS",
|
"ToastRSSFeedCloseFailed": "Error al cerrar fuente RSS",
|
||||||
"ToastRSSFeedCloseSuccess": "Fuente RSS cerrada",
|
"ToastRSSFeedCloseSuccess": "Fuente RSS cerrada",
|
||||||
|
"ToastRemoveFailed": "Error al eliminar",
|
||||||
"ToastRemoveItemFromCollectionFailed": "Error al eliminar el elemento de la colección",
|
"ToastRemoveItemFromCollectionFailed": "Error al eliminar el elemento de la colección",
|
||||||
"ToastRemoveItemFromCollectionSuccess": "Elemento eliminado de la colección.",
|
"ToastRemoveItemFromCollectionSuccess": "Elemento eliminado de la colección",
|
||||||
|
"ToastRemoveItemsWithIssuesFailed": "Error en la eliminación de artículos de biblioteca incorrectos",
|
||||||
|
"ToastRemoveItemsWithIssuesSuccess": "Se eliminaron artículos de biblioteca incorrectos",
|
||||||
|
"ToastRenameFailed": "Error al cambiar el nombre",
|
||||||
|
"ToastRescanFailed": "Error al volver a escanear para {0}",
|
||||||
|
"ToastRescanRemoved": "Se eliminó el elemento reescaneado",
|
||||||
|
"ToastRescanUpToDate": "Reescaneado del artículo completo, estaba actualizado",
|
||||||
|
"ToastRescanUpdated": "Reescaneado completado, el artículo ha sido actualizado",
|
||||||
|
"ToastScanFailed": "No se pudo escanear el elemento de la biblioteca",
|
||||||
|
"ToastSelectAtLeastOneUser": "Selecciona al menos un usuario",
|
||||||
"ToastSendEbookToDeviceFailed": "Error al enviar el ebook al dispositivo",
|
"ToastSendEbookToDeviceFailed": "Error al enviar el ebook al dispositivo",
|
||||||
"ToastSendEbookToDeviceSuccess": "Ebook enviado al dispositivo \"{0}\"",
|
"ToastSendEbookToDeviceSuccess": "Ebook enviado al dispositivo \"{0}\"",
|
||||||
"ToastSeriesUpdateFailed": "Error al actualizar la serie",
|
"ToastSeriesUpdateFailed": "Error al actualizar la serie",
|
||||||
"ToastSeriesUpdateSuccess": "Serie actualizada",
|
"ToastSeriesUpdateSuccess": "Serie actualizada",
|
||||||
"ToastServerSettingsUpdateFailed": "Error al actualizar configuración del servidor",
|
|
||||||
"ToastServerSettingsUpdateSuccess": "Configuración del servidor actualizada",
|
"ToastServerSettingsUpdateSuccess": "Configuración del servidor actualizada",
|
||||||
|
"ToastSessionCloseFailed": "Error al cerrar la sesión",
|
||||||
"ToastSessionDeleteFailed": "Error al eliminar sesión",
|
"ToastSessionDeleteFailed": "Error al eliminar sesión",
|
||||||
"ToastSessionDeleteSuccess": "Sesión eliminada",
|
"ToastSessionDeleteSuccess": "Sesión eliminada",
|
||||||
|
"ToastSlugMustChange": "El slug contiene caracteres no válidos",
|
||||||
|
"ToastSlugRequired": "Slug obligatorio",
|
||||||
"ToastSocketConnected": "Socket conectado",
|
"ToastSocketConnected": "Socket conectado",
|
||||||
"ToastSocketDisconnected": "Socket desconectado",
|
"ToastSocketDisconnected": "Socket desconectado",
|
||||||
"ToastSocketFailedToConnect": "Error al conectar al Socket",
|
"ToastSocketFailedToConnect": "Error al conectar al Socket",
|
||||||
"ToastSortingPrefixesEmptyError": "Debe tener por lo menos 1 prefijo para ordenar",
|
"ToastSortingPrefixesEmptyError": "Debe tener por lo menos 1 prefijo para ordenar",
|
||||||
"ToastSortingPrefixesUpdateFailed": "Error al actualizar los prefijos de ordenar",
|
|
||||||
"ToastSortingPrefixesUpdateSuccess": "Prefijos de ordenar actualizaron ({0} items)",
|
"ToastSortingPrefixesUpdateSuccess": "Prefijos de ordenar actualizaron ({0} items)",
|
||||||
|
"ToastTitleRequired": "Título obligatorio",
|
||||||
|
"ToastUnknownError": "Error desconocido",
|
||||||
|
"ToastUnlinkOpenIdFailed": "Error al desvincular el usuario de OpenID",
|
||||||
|
"ToastUnlinkOpenIdSuccess": "Usuario desvinculado de OpenID",
|
||||||
"ToastUserDeleteFailed": "Error al eliminar el usuario",
|
"ToastUserDeleteFailed": "Error al eliminar el usuario",
|
||||||
"ToastUserDeleteSuccess": "Usuario eliminado"
|
"ToastUserDeleteSuccess": "Usuario eliminado",
|
||||||
|
"ToastUserPasswordChangeSuccess": "Contraseña modificada correctamente",
|
||||||
|
"ToastUserPasswordMismatch": "No coinciden las contraseñas",
|
||||||
|
"ToastUserPasswordMustChange": "La nueva contraseña no puede ser igual que la anterior",
|
||||||
|
"ToastUserRootRequireName": "Debes introducir un nombre de usuario root"
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-10
@@ -9,6 +9,7 @@
|
|||||||
"ButtonApply": "Rakenda",
|
"ButtonApply": "Rakenda",
|
||||||
"ButtonApplyChapters": "Rakenda peatükid",
|
"ButtonApplyChapters": "Rakenda peatükid",
|
||||||
"ButtonAuthors": "Autorid",
|
"ButtonAuthors": "Autorid",
|
||||||
|
"ButtonBack": "Tagasi",
|
||||||
"ButtonBrowseForFolder": "Sirvi kausta",
|
"ButtonBrowseForFolder": "Sirvi kausta",
|
||||||
"ButtonCancel": "Tühista",
|
"ButtonCancel": "Tühista",
|
||||||
"ButtonCancelEncode": "Tühista kodeerimine",
|
"ButtonCancelEncode": "Tühista kodeerimine",
|
||||||
@@ -18,6 +19,7 @@
|
|||||||
"ButtonChooseFiles": "Vali failid",
|
"ButtonChooseFiles": "Vali failid",
|
||||||
"ButtonClearFilter": "Tühista filter",
|
"ButtonClearFilter": "Tühista filter",
|
||||||
"ButtonCloseFeed": "Sulge voog",
|
"ButtonCloseFeed": "Sulge voog",
|
||||||
|
"ButtonCloseSession": "Sulge avatud sessioon",
|
||||||
"ButtonCollections": "Kogud",
|
"ButtonCollections": "Kogud",
|
||||||
"ButtonConfigureScanner": "Konfigureeri skanner",
|
"ButtonConfigureScanner": "Konfigureeri skanner",
|
||||||
"ButtonCreate": "Loo",
|
"ButtonCreate": "Loo",
|
||||||
@@ -27,6 +29,7 @@
|
|||||||
"ButtonEdit": "Muuda",
|
"ButtonEdit": "Muuda",
|
||||||
"ButtonEditChapters": "Muuda peatükke",
|
"ButtonEditChapters": "Muuda peatükke",
|
||||||
"ButtonEditPodcast": "Muuda podcasti",
|
"ButtonEditPodcast": "Muuda podcasti",
|
||||||
|
"ButtonEnable": "Aktiveeri",
|
||||||
"ButtonForceReScan": "Sunnitud uuestiskaneerimine",
|
"ButtonForceReScan": "Sunnitud uuestiskaneerimine",
|
||||||
"ButtonFullPath": "Täielik asukoht",
|
"ButtonFullPath": "Täielik asukoht",
|
||||||
"ButtonHide": "Peida",
|
"ButtonHide": "Peida",
|
||||||
@@ -43,13 +46,18 @@
|
|||||||
"ButtonMatchAllAuthors": "Sobita kõik autorid",
|
"ButtonMatchAllAuthors": "Sobita kõik autorid",
|
||||||
"ButtonMatchBooks": "Sobita raamatud",
|
"ButtonMatchBooks": "Sobita raamatud",
|
||||||
"ButtonNevermind": "Pole tähtis",
|
"ButtonNevermind": "Pole tähtis",
|
||||||
|
"ButtonNext": "Järgmine",
|
||||||
"ButtonNextChapter": "Järgmine peatükk",
|
"ButtonNextChapter": "Järgmine peatükk",
|
||||||
|
"ButtonNextItemInQueue": "Järgmine kirje järjekorras",
|
||||||
|
"ButtonOk": "Ok",
|
||||||
"ButtonOpenFeed": "Ava voog",
|
"ButtonOpenFeed": "Ava voog",
|
||||||
"ButtonOpenManager": "Ava haldur",
|
"ButtonOpenManager": "Ava haldur",
|
||||||
"ButtonPause": "Peata",
|
"ButtonPause": "Peata",
|
||||||
"ButtonPlay": "Mängi",
|
"ButtonPlay": "Mängi",
|
||||||
|
"ButtonPlayAll": "Mängi kõik",
|
||||||
"ButtonPlaying": "Mängib",
|
"ButtonPlaying": "Mängib",
|
||||||
"ButtonPlaylists": "Esitusloendid",
|
"ButtonPlaylists": "Esitusloendid",
|
||||||
|
"ButtonPrevious": "Eelmine",
|
||||||
"ButtonPreviousChapter": "Eelmine peatükk",
|
"ButtonPreviousChapter": "Eelmine peatükk",
|
||||||
"ButtonPurgeAllCache": "Tühjenda kogu vahemälu",
|
"ButtonPurgeAllCache": "Tühjenda kogu vahemälu",
|
||||||
"ButtonPurgeItemsCache": "Tühjenda esemete vahemälu",
|
"ButtonPurgeItemsCache": "Tühjenda esemete vahemälu",
|
||||||
@@ -58,6 +66,9 @@
|
|||||||
"ButtonQuickMatch": "Kiire sobitamine",
|
"ButtonQuickMatch": "Kiire sobitamine",
|
||||||
"ButtonReScan": "Uuestiskaneeri",
|
"ButtonReScan": "Uuestiskaneeri",
|
||||||
"ButtonRead": "Loe",
|
"ButtonRead": "Loe",
|
||||||
|
"ButtonReadLess": "Loe vähem",
|
||||||
|
"ButtonReadMore": "Loe rohkem",
|
||||||
|
"ButtonRefresh": "Värskenda",
|
||||||
"ButtonRemove": "Eemalda",
|
"ButtonRemove": "Eemalda",
|
||||||
"ButtonRemoveAll": "Eemalda kõik",
|
"ButtonRemoveAll": "Eemalda kõik",
|
||||||
"ButtonRemoveAllLibraryItems": "Eemalda kõik raamatukogu esemed",
|
"ButtonRemoveAllLibraryItems": "Eemalda kõik raamatukogu esemed",
|
||||||
@@ -211,7 +222,7 @@
|
|||||||
"LabelBackupLocation": "Varukoopia asukoht",
|
"LabelBackupLocation": "Varukoopia asukoht",
|
||||||
"LabelBackupsEnableAutomaticBackups": "Luba automaatsed varukoopiad",
|
"LabelBackupsEnableAutomaticBackups": "Luba automaatsed varukoopiad",
|
||||||
"LabelBackupsEnableAutomaticBackupsHelp": "Varukoopiad salvestatakse /metadata/backups kausta",
|
"LabelBackupsEnableAutomaticBackupsHelp": "Varukoopiad salvestatakse /metadata/backups kausta",
|
||||||
"LabelBackupsMaxBackupSize": "Maksimaalne varukoopia suurus (GB-des)",
|
"LabelBackupsMaxBackupSize": "Maksimaalne varukoopia suurus (GB-des) (0 lõpmatu suuruse jaoks)",
|
||||||
"LabelBackupsMaxBackupSizeHelp": "Kaitsena valesti seadistamise vastu ebaõnnestuvad varukoopiad, kui need ületavad seadistatud suuruse.",
|
"LabelBackupsMaxBackupSizeHelp": "Kaitsena valesti seadistamise vastu ebaõnnestuvad varukoopiad, kui need ületavad seadistatud suuruse.",
|
||||||
"LabelBackupsNumberToKeep": "Varukoopiate arv, mida hoida",
|
"LabelBackupsNumberToKeep": "Varukoopiate arv, mida hoida",
|
||||||
"LabelBackupsNumberToKeepHelp": "Ühel ajal eemaldatakse ainult 1 varukoopia, seega kui teil on juba rohkem varukoopiaid kui siin määratud, peaksite need käsitsi eemaldama.",
|
"LabelBackupsNumberToKeepHelp": "Ühel ajal eemaldatakse ainult 1 varukoopia, seega kui teil on juba rohkem varukoopiaid kui siin määratud, peaksite need käsitsi eemaldama.",
|
||||||
@@ -449,7 +460,7 @@
|
|||||||
"LabelSettingsHomePageBookshelfView": "Avaleht kasutage raamatukoguvaadet",
|
"LabelSettingsHomePageBookshelfView": "Avaleht kasutage raamatukoguvaadet",
|
||||||
"LabelSettingsLibraryBookshelfView": "Raamatukogu kasutamiseks kasutage raamatukoguvaadet",
|
"LabelSettingsLibraryBookshelfView": "Raamatukogu kasutamiseks kasutage raamatukoguvaadet",
|
||||||
"LabelSettingsParseSubtitles": "Lugege subtiitreid",
|
"LabelSettingsParseSubtitles": "Lugege subtiitreid",
|
||||||
"LabelSettingsParseSubtitlesHelp": "Eraldage subtiitrid heliraamatu kaustade nimedest.<br>Subtiitrid peavad olema eraldatud \" - \".<br>Näiteks: \"Raamatu pealkiri - Siin on alapealkiri\" alapealkiri on \"Siin on alapealkiri\"",
|
"LabelSettingsParseSubtitlesHelp": "Eraldage subtiitrid heliraamatu kaustade nimedest.<br>Subtiitrid peavad olema eraldatud kasutades \" - \".<br>Näiteks: \"Raamatu pealkiri - Siin on alapealkiri\" alapealkiri on \"Siin on alapealkiri\"",
|
||||||
"LabelSettingsPreferMatchedMetadata": "Eelista sobitatud metaandmeid",
|
"LabelSettingsPreferMatchedMetadata": "Eelista sobitatud metaandmeid",
|
||||||
"LabelSettingsPreferMatchedMetadataHelp": "Sobitatud andmed kirjutavad Kiir Sobitamise kasutamisel üle üksikasjad.",
|
"LabelSettingsPreferMatchedMetadataHelp": "Sobitatud andmed kirjutavad Kiir Sobitamise kasutamisel üle üksikasjad.",
|
||||||
"LabelSettingsSkipMatchingBooksWithASIN": "Jätke ASIN-iga sobituvad raamatud vahele",
|
"LabelSettingsSkipMatchingBooksWithASIN": "Jätke ASIN-iga sobituvad raamatud vahele",
|
||||||
@@ -682,10 +693,8 @@
|
|||||||
"PlaceholderNewPlaylist": "Uue esitusloendi nimi",
|
"PlaceholderNewPlaylist": "Uue esitusloendi nimi",
|
||||||
"PlaceholderSearch": "Otsi...",
|
"PlaceholderSearch": "Otsi...",
|
||||||
"PlaceholderSearchEpisode": "Otsi episoodi...",
|
"PlaceholderSearchEpisode": "Otsi episoodi...",
|
||||||
"ToastAccountUpdateFailed": "Konto värskendamine ebaõnnestus",
|
|
||||||
"ToastAccountUpdateSuccess": "Konto on värskendatud",
|
"ToastAccountUpdateSuccess": "Konto on värskendatud",
|
||||||
"ToastAuthorImageRemoveSuccess": "Autori pilt on eemaldatud",
|
"ToastAuthorImageRemoveSuccess": "Autori pilt on eemaldatud",
|
||||||
"ToastAuthorUpdateFailed": "Autori värskendamine ebaõnnestus",
|
|
||||||
"ToastAuthorUpdateMerged": "Autor liidetud",
|
"ToastAuthorUpdateMerged": "Autor liidetud",
|
||||||
"ToastAuthorUpdateSuccess": "Autor värskendatud",
|
"ToastAuthorUpdateSuccess": "Autor värskendatud",
|
||||||
"ToastAuthorUpdateSuccessNoImageFound": "Autor värskendatud (pilti ei leitud)",
|
"ToastAuthorUpdateSuccessNoImageFound": "Autor värskendatud (pilti ei leitud)",
|
||||||
@@ -701,17 +710,13 @@
|
|||||||
"ToastBookmarkCreateFailed": "Järjehoidja loomine ebaõnnestus",
|
"ToastBookmarkCreateFailed": "Järjehoidja loomine ebaõnnestus",
|
||||||
"ToastBookmarkCreateSuccess": "Järjehoidja lisatud",
|
"ToastBookmarkCreateSuccess": "Järjehoidja lisatud",
|
||||||
"ToastBookmarkRemoveSuccess": "Järjehoidja eemaldatud",
|
"ToastBookmarkRemoveSuccess": "Järjehoidja eemaldatud",
|
||||||
"ToastBookmarkUpdateFailed": "Järjehoidja värskendamine ebaõnnestus",
|
|
||||||
"ToastBookmarkUpdateSuccess": "Järjehoidja värskendatud",
|
"ToastBookmarkUpdateSuccess": "Järjehoidja värskendatud",
|
||||||
"ToastChaptersHaveErrors": "Peatükkidel on vigu",
|
"ToastChaptersHaveErrors": "Peatükkidel on vigu",
|
||||||
"ToastChaptersMustHaveTitles": "Peatükkidel peab olema pealkiri",
|
"ToastChaptersMustHaveTitles": "Peatükkidel peab olema pealkiri",
|
||||||
"ToastCollectionItemsRemoveSuccess": "Üksus(ed) eemaldatud kogumist",
|
"ToastCollectionItemsRemoveSuccess": "Üksus(ed) eemaldatud kogumist",
|
||||||
"ToastCollectionRemoveSuccess": "Kogum eemaldatud",
|
"ToastCollectionRemoveSuccess": "Kogum eemaldatud",
|
||||||
"ToastCollectionUpdateFailed": "Kogumi värskendamine ebaõnnestus",
|
|
||||||
"ToastCollectionUpdateSuccess": "Kogum värskendatud",
|
"ToastCollectionUpdateSuccess": "Kogum värskendatud",
|
||||||
"ToastItemCoverUpdateFailed": "Üksuse kaane värskendamine ebaõnnestus",
|
|
||||||
"ToastItemCoverUpdateSuccess": "Üksuse kaas värskendatud",
|
"ToastItemCoverUpdateSuccess": "Üksuse kaas värskendatud",
|
||||||
"ToastItemDetailsUpdateFailed": "Üksuse üksikasjade värskendamine ebaõnnestus",
|
|
||||||
"ToastItemDetailsUpdateSuccess": "Üksuse üksikasjad värskendatud",
|
"ToastItemDetailsUpdateSuccess": "Üksuse üksikasjad värskendatud",
|
||||||
"ToastItemMarkedAsFinishedFailed": "Märgistamine kui lõpetatud ebaõnnestus",
|
"ToastItemMarkedAsFinishedFailed": "Märgistamine kui lõpetatud ebaõnnestus",
|
||||||
"ToastItemMarkedAsFinishedSuccess": "Üksus märgitud kui lõpetatud",
|
"ToastItemMarkedAsFinishedSuccess": "Üksus märgitud kui lõpetatud",
|
||||||
@@ -723,12 +728,10 @@
|
|||||||
"ToastLibraryDeleteSuccess": "Raamatukogu kustutatud",
|
"ToastLibraryDeleteSuccess": "Raamatukogu kustutatud",
|
||||||
"ToastLibraryScanFailedToStart": "Skanneerimine ei käivitunud",
|
"ToastLibraryScanFailedToStart": "Skanneerimine ei käivitunud",
|
||||||
"ToastLibraryScanStarted": "Raamatukogu skaneerimine alustatud",
|
"ToastLibraryScanStarted": "Raamatukogu skaneerimine alustatud",
|
||||||
"ToastLibraryUpdateFailed": "Raamatukogu värskendamine ebaõnnestus",
|
|
||||||
"ToastLibraryUpdateSuccess": "Raamatukogu \"{0}\" värskendatud",
|
"ToastLibraryUpdateSuccess": "Raamatukogu \"{0}\" värskendatud",
|
||||||
"ToastPlaylistCreateFailed": "Esitusloendi loomine ebaõnnestus",
|
"ToastPlaylistCreateFailed": "Esitusloendi loomine ebaõnnestus",
|
||||||
"ToastPlaylistCreateSuccess": "Esitusloend loodud",
|
"ToastPlaylistCreateSuccess": "Esitusloend loodud",
|
||||||
"ToastPlaylistRemoveSuccess": "Esitusloend eemaldatud",
|
"ToastPlaylistRemoveSuccess": "Esitusloend eemaldatud",
|
||||||
"ToastPlaylistUpdateFailed": "Esitusloendi värskendamine ebaõnnestus",
|
|
||||||
"ToastPlaylistUpdateSuccess": "Esitusloend värskendatud",
|
"ToastPlaylistUpdateSuccess": "Esitusloend värskendatud",
|
||||||
"ToastPodcastCreateFailed": "Podcasti loomine ebaõnnestus",
|
"ToastPodcastCreateFailed": "Podcasti loomine ebaõnnestus",
|
||||||
"ToastPodcastCreateSuccess": "Podcast loodud edukalt",
|
"ToastPodcastCreateSuccess": "Podcast loodud edukalt",
|
||||||
|
|||||||
+166
-2
@@ -19,6 +19,7 @@
|
|||||||
"ButtonChooseFiles": "Valitse tiedostot",
|
"ButtonChooseFiles": "Valitse tiedostot",
|
||||||
"ButtonClearFilter": "Poista suodatus",
|
"ButtonClearFilter": "Poista suodatus",
|
||||||
"ButtonCloseFeed": "Sulje syöte",
|
"ButtonCloseFeed": "Sulje syöte",
|
||||||
|
"ButtonCloseSession": "Sulje Avoin Sessio",
|
||||||
"ButtonCollections": "Kokoelmat",
|
"ButtonCollections": "Kokoelmat",
|
||||||
"ButtonConfigureScanner": "Skannerin asetukset",
|
"ButtonConfigureScanner": "Skannerin asetukset",
|
||||||
"ButtonCreate": "Luo",
|
"ButtonCreate": "Luo",
|
||||||
@@ -28,6 +29,9 @@
|
|||||||
"ButtonEdit": "Muokkaa",
|
"ButtonEdit": "Muokkaa",
|
||||||
"ButtonEditChapters": "Muokkaa lukuja",
|
"ButtonEditChapters": "Muokkaa lukuja",
|
||||||
"ButtonEditPodcast": "Muokkaa podcastia",
|
"ButtonEditPodcast": "Muokkaa podcastia",
|
||||||
|
"ButtonEnable": "Aktivoi",
|
||||||
|
"ButtonFireAndFail": "Laukaise ja epäonnistu",
|
||||||
|
"ButtonFireOnTest": "Laukaise onTest tapahtuma",
|
||||||
"ButtonForceReScan": "Pakota uudelleenskannaus",
|
"ButtonForceReScan": "Pakota uudelleenskannaus",
|
||||||
"ButtonFullPath": "Koko polku",
|
"ButtonFullPath": "Koko polku",
|
||||||
"ButtonHide": "Piilota",
|
"ButtonHide": "Piilota",
|
||||||
@@ -46,10 +50,13 @@
|
|||||||
"ButtonNevermind": "Ei sittenkään",
|
"ButtonNevermind": "Ei sittenkään",
|
||||||
"ButtonNext": "Seuraava",
|
"ButtonNext": "Seuraava",
|
||||||
"ButtonNextChapter": "Seuraava luku",
|
"ButtonNextChapter": "Seuraava luku",
|
||||||
|
"ButtonNextItemInQueue": "Seuraava jonossa",
|
||||||
|
"ButtonOk": "Ok",
|
||||||
"ButtonOpenFeed": "Avaa syöte",
|
"ButtonOpenFeed": "Avaa syöte",
|
||||||
"ButtonOpenManager": "Avaa hallinta",
|
"ButtonOpenManager": "Avaa hallinta",
|
||||||
"ButtonPause": "Pysäytä",
|
"ButtonPause": "Pysäytä",
|
||||||
"ButtonPlay": "Toista",
|
"ButtonPlay": "Toista",
|
||||||
|
"ButtonPlayAll": "Toista kaikki",
|
||||||
"ButtonPlaying": "Toistetaan",
|
"ButtonPlaying": "Toistetaan",
|
||||||
"ButtonPlaylists": "Soittolistat",
|
"ButtonPlaylists": "Soittolistat",
|
||||||
"ButtonPrevious": "Edellinen",
|
"ButtonPrevious": "Edellinen",
|
||||||
@@ -90,6 +97,7 @@
|
|||||||
"ButtonStats": "Tilastot",
|
"ButtonStats": "Tilastot",
|
||||||
"ButtonSubmit": "Lähetä",
|
"ButtonSubmit": "Lähetä",
|
||||||
"ButtonTest": "Testi",
|
"ButtonTest": "Testi",
|
||||||
|
"ButtonUnlinkOpenId": "Poista OpenID linkitys",
|
||||||
"ButtonUpload": "Lähetä palvelimelle",
|
"ButtonUpload": "Lähetä palvelimelle",
|
||||||
"ButtonUploadBackup": "Lähetä varmuuskopio",
|
"ButtonUploadBackup": "Lähetä varmuuskopio",
|
||||||
"ButtonUploadCover": "Lähetä kansikuva",
|
"ButtonUploadCover": "Lähetä kansikuva",
|
||||||
@@ -102,6 +110,7 @@
|
|||||||
"ErrorUploadFetchMetadataNoResults": "Metadatan haku epäonnistui, yritä päivittää Teoksen nimi ja/tai Tekijä",
|
"ErrorUploadFetchMetadataNoResults": "Metadatan haku epäonnistui, yritä päivittää Teoksen nimi ja/tai Tekijä",
|
||||||
"ErrorUploadLacksTitle": "Pitää sisältää Nimi",
|
"ErrorUploadLacksTitle": "Pitää sisältää Nimi",
|
||||||
"HeaderAccount": "Tili",
|
"HeaderAccount": "Tili",
|
||||||
|
"HeaderAddCustomMetadataProvider": "Lisää mukautettu metadata tarjoaja",
|
||||||
"HeaderAdvanced": "Edistynyt",
|
"HeaderAdvanced": "Edistynyt",
|
||||||
"HeaderAppriseNotificationSettings": "Apprise-ilmoitusasetukset",
|
"HeaderAppriseNotificationSettings": "Apprise-ilmoitusasetukset",
|
||||||
"HeaderAudioTracks": "Ääniraidat",
|
"HeaderAudioTracks": "Ääniraidat",
|
||||||
@@ -126,38 +135,60 @@
|
|||||||
"HeaderEreaderDevices": "E-lukijalaitteet",
|
"HeaderEreaderDevices": "E-lukijalaitteet",
|
||||||
"HeaderEreaderSettings": "E-lukijan asetukset",
|
"HeaderEreaderSettings": "E-lukijan asetukset",
|
||||||
"HeaderFiles": "Tiedostot",
|
"HeaderFiles": "Tiedostot",
|
||||||
|
"HeaderFindChapters": "Etsi kappaleet",
|
||||||
"HeaderIgnoredFiles": "Ohitetut tiedostot",
|
"HeaderIgnoredFiles": "Ohitetut tiedostot",
|
||||||
|
"HeaderLastListeningSession": "Edellinen kuuntelukerta",
|
||||||
"HeaderLatestEpisodes": "Viimeisimmät jaksot",
|
"HeaderLatestEpisodes": "Viimeisimmät jaksot",
|
||||||
"HeaderLibraries": "Kirjastot",
|
"HeaderLibraries": "Kirjastot",
|
||||||
"HeaderLibraryFiles": "Kirjaston tiedostot",
|
"HeaderLibraryFiles": "Kirjaston tiedostot",
|
||||||
"HeaderLibraryStats": "Kirjaston tilastot",
|
"HeaderLibraryStats": "Kirjaston tilastot",
|
||||||
|
"HeaderListeningSessions": "Kuuntelukerrat",
|
||||||
"HeaderListeningStats": "Kuuntelutilastot",
|
"HeaderListeningStats": "Kuuntelutilastot",
|
||||||
|
"HeaderLogin": "Kirjaudu",
|
||||||
"HeaderLogs": "Lokit",
|
"HeaderLogs": "Lokit",
|
||||||
|
"HeaderManageGenres": "Hallitse lajityyppejä",
|
||||||
|
"HeaderManageTags": "Hallitse tageja",
|
||||||
|
"HeaderMetadataToEmbed": "Sisällytettävä metadata",
|
||||||
"HeaderNewAccount": "Uusi tili",
|
"HeaderNewAccount": "Uusi tili",
|
||||||
"HeaderNewLibrary": "Uusi kirjasto",
|
"HeaderNewLibrary": "Uusi kirjasto",
|
||||||
|
"HeaderNotificationCreate": "Luo ilmoitus",
|
||||||
|
"HeaderNotificationUpdate": "Päivitä ilmoitus",
|
||||||
"HeaderNotifications": "Ilmoitukset",
|
"HeaderNotifications": "Ilmoitukset",
|
||||||
"HeaderOpenRSSFeed": "Avaa RSS-syöte",
|
"HeaderOpenRSSFeed": "Avaa RSS-syöte",
|
||||||
"HeaderOtherFiles": "Muut tiedostot",
|
"HeaderOtherFiles": "Muut tiedostot",
|
||||||
"HeaderPermissions": "Käyttöoikeudet",
|
"HeaderPermissions": "Käyttöoikeudet",
|
||||||
|
"HeaderPlayerQueue": "Soittimen jono",
|
||||||
|
"HeaderPlayerSettings": "Soittimen asetukset",
|
||||||
"HeaderPlaylist": "Soittolista",
|
"HeaderPlaylist": "Soittolista",
|
||||||
"HeaderPlaylistItems": "Soittolistan kohteet",
|
"HeaderPlaylistItems": "Soittolistan kohteet",
|
||||||
|
"HeaderPodcastsToAdd": "Lisättävät podcastit",
|
||||||
|
"HeaderPreviewCover": "Esikatsele kansikuvaa",
|
||||||
"HeaderRSSFeedGeneral": "RSS yksityiskohdat",
|
"HeaderRSSFeedGeneral": "RSS yksityiskohdat",
|
||||||
"HeaderRSSFeedIsOpen": "RSS syöte on avoinna",
|
"HeaderRSSFeedIsOpen": "RSS syöte on avoinna",
|
||||||
|
"HeaderRSSFeeds": "RSS syötteet",
|
||||||
"HeaderRemoveEpisode": "Poista jakso",
|
"HeaderRemoveEpisode": "Poista jakso",
|
||||||
"HeaderRemoveEpisodes": "Poista {0} jaksoa",
|
"HeaderRemoveEpisodes": "Poista {0} jaksoa",
|
||||||
"HeaderSchedule": "Ajoita",
|
"HeaderSchedule": "Ajoita",
|
||||||
"HeaderScheduleLibraryScans": "Ajoita automaattiset kirjastoskannaukset",
|
"HeaderScheduleLibraryScans": "Ajoita automaattiset kirjastoskannaukset",
|
||||||
|
"HeaderSession": "Istunto",
|
||||||
"HeaderSetBackupSchedule": "Aseta varmuuskopiointiaikataulu",
|
"HeaderSetBackupSchedule": "Aseta varmuuskopiointiaikataulu",
|
||||||
"HeaderSettings": "Asetukset",
|
"HeaderSettings": "Asetukset",
|
||||||
"HeaderSettingsExperimental": "Kokeelliset ominaisuudet",
|
"HeaderSettingsExperimental": "Kokeelliset ominaisuudet",
|
||||||
|
"HeaderSettingsGeneral": "Yleiset",
|
||||||
"HeaderSleepTimer": "Uniajastin",
|
"HeaderSleepTimer": "Uniajastin",
|
||||||
"HeaderStatsMinutesListeningChart": "Kuunteluminuutit (viim. 7 pv)",
|
"HeaderStatsMinutesListeningChart": "Kuunteluminuutit (viim. 7 pv)",
|
||||||
"HeaderStatsRecentSessions": "Viimeaikaiset istunnot",
|
"HeaderStatsRecentSessions": "Viimeaikaiset istunnot",
|
||||||
|
"HeaderStatsTop5Genres": "Top 5 lajityypit",
|
||||||
"HeaderTableOfContents": "Sisällysluettelo",
|
"HeaderTableOfContents": "Sisällysluettelo",
|
||||||
"HeaderTools": "Työkalut",
|
"HeaderTools": "Työkalut",
|
||||||
|
"HeaderUpdateAccount": "Päivitä tili",
|
||||||
|
"HeaderUpdateAuthor": "Päivitä kirjailija",
|
||||||
|
"HeaderUpdateLibrary": "Päivitä kirjasto",
|
||||||
"HeaderUsers": "Käyttäjät",
|
"HeaderUsers": "Käyttäjät",
|
||||||
"HeaderYourStats": "Tilastosi",
|
"HeaderYourStats": "Tilastosi",
|
||||||
|
"LabelAbridged": "Lyhennetty",
|
||||||
"LabelAccountType": "Tilin tyyppi",
|
"LabelAccountType": "Tilin tyyppi",
|
||||||
|
"LabelAccountTypeAdmin": "Järjestelmänvalvoja",
|
||||||
"LabelAccountTypeGuest": "Vieras",
|
"LabelAccountTypeGuest": "Vieras",
|
||||||
"LabelAccountTypeUser": "Käyttäjä",
|
"LabelAccountTypeUser": "Käyttäjä",
|
||||||
"LabelActivity": "Toiminta",
|
"LabelActivity": "Toiminta",
|
||||||
@@ -166,22 +197,29 @@
|
|||||||
"LabelAddToPlaylist": "Lisää soittolistaan",
|
"LabelAddToPlaylist": "Lisää soittolistaan",
|
||||||
"LabelAddToPlaylistBatch": "Lisää {0} kohdetta soittolistaan",
|
"LabelAddToPlaylistBatch": "Lisää {0} kohdetta soittolistaan",
|
||||||
"LabelAddedAt": "Lisätty listalle",
|
"LabelAddedAt": "Lisätty listalle",
|
||||||
|
"LabelAddedDate": "Lisätty {0}",
|
||||||
|
"LabelAdminUsersOnly": "Vain järjestelmänvalvojat",
|
||||||
"LabelAll": "Kaikki",
|
"LabelAll": "Kaikki",
|
||||||
"LabelAllUsers": "Kaikki käyttäjät",
|
"LabelAllUsers": "Kaikki käyttäjät",
|
||||||
"LabelAllUsersExcludingGuests": "Kaikki käyttäjät vieraita lukuun ottamatta",
|
"LabelAllUsersExcludingGuests": "Kaikki käyttäjät vieraita lukuun ottamatta",
|
||||||
"LabelAllUsersIncludingGuests": "Kaikki käyttäjät mukaan lukien vieraat",
|
"LabelAllUsersIncludingGuests": "Kaikki käyttäjät mukaan lukien vieraat",
|
||||||
|
"LabelAlreadyInYourLibrary": "Jo kirjastossasi",
|
||||||
"LabelAuthor": "Tekijä",
|
"LabelAuthor": "Tekijä",
|
||||||
"LabelAuthorFirstLast": "Tekijä (Etunimi Sukunimi)",
|
"LabelAuthorFirstLast": "Tekijä (Etunimi Sukunimi)",
|
||||||
"LabelAuthorLastFirst": "Tekijä (Sukunimi, Etunimi)",
|
"LabelAuthorLastFirst": "Tekijä (Sukunimi, Etunimi)",
|
||||||
"LabelAuthors": "Tekijät",
|
"LabelAuthors": "Tekijät",
|
||||||
"LabelAutoDownloadEpisodes": "Lataa jaksot automaattisesti",
|
"LabelAutoDownloadEpisodes": "Lataa jaksot automaattisesti",
|
||||||
|
"LabelBackToUser": "Takaisin käyttäjään",
|
||||||
|
"LabelBackupLocation": "Varmuuskopiointipaikka",
|
||||||
"LabelBackupsEnableAutomaticBackups": "Ota automaattinen varmuuskopiointi käyttöön",
|
"LabelBackupsEnableAutomaticBackups": "Ota automaattinen varmuuskopiointi käyttöön",
|
||||||
"LabelBackupsEnableAutomaticBackupsHelp": "Varmuuskopiot tallennettu kansioon /metadata/backups",
|
"LabelBackupsEnableAutomaticBackupsHelp": "Varmuuskopiot tallennettu kansioon /metadata/backups",
|
||||||
"LabelBackupsMaxBackupSize": "Varmuuskopion enimmäiskoko (Gt) (0 rajaton)",
|
"LabelBackupsMaxBackupSize": "Varmuuskopion enimmäiskoko (Gt) (0 rajaton)",
|
||||||
"LabelBackupsNumberToKeep": "Säilytettävien varmuuskopioiden määrä",
|
"LabelBackupsNumberToKeep": "Säilytettävien varmuuskopioiden määrä",
|
||||||
|
"LabelBitrate": "Bittinopeus",
|
||||||
"LabelBooks": "Kirjat",
|
"LabelBooks": "Kirjat",
|
||||||
"LabelButtonText": "Painikkeen teksti",
|
"LabelButtonText": "Painikkeen teksti",
|
||||||
"LabelChangePassword": "Vaihda salasana",
|
"LabelChangePassword": "Vaihda salasana",
|
||||||
|
"LabelChannels": "Kanavat",
|
||||||
"LabelChapters": "Luvut",
|
"LabelChapters": "Luvut",
|
||||||
"LabelClickForMoreInfo": "Napsauta saadaksesi lisätietoja",
|
"LabelClickForMoreInfo": "Napsauta saadaksesi lisätietoja",
|
||||||
"LabelClosePlayer": "Sulje soitin",
|
"LabelClosePlayer": "Sulje soitin",
|
||||||
@@ -196,79 +234,205 @@
|
|||||||
"LabelContinueSeries": "Jatka sarjoja",
|
"LabelContinueSeries": "Jatka sarjoja",
|
||||||
"LabelCover": "Kansikuva",
|
"LabelCover": "Kansikuva",
|
||||||
"LabelCoverImageURL": "Kansikuvan URL-osoite",
|
"LabelCoverImageURL": "Kansikuvan URL-osoite",
|
||||||
|
"LabelCreatedAt": "Luotu",
|
||||||
"LabelCurrent": "Nykyinen",
|
"LabelCurrent": "Nykyinen",
|
||||||
|
"LabelDays": "Päivää",
|
||||||
"LabelDescription": "Kuvaus",
|
"LabelDescription": "Kuvaus",
|
||||||
"LabelDevice": "Laite",
|
"LabelDevice": "Laite",
|
||||||
"LabelDeviceInfo": "Laitteen tiedot",
|
"LabelDeviceInfo": "Laitteen tiedot",
|
||||||
|
"LabelDiscover": "Löydä",
|
||||||
"LabelDownload": "Lataa",
|
"LabelDownload": "Lataa",
|
||||||
"LabelDownloadNEpisodes": "Lataa {0} jaksoa",
|
"LabelDownloadNEpisodes": "Lataa {0} jaksoa",
|
||||||
"LabelDuration": "Kesto",
|
"LabelDuration": "Kesto",
|
||||||
|
"LabelDurationComparisonLonger": "({0} pidempi)",
|
||||||
|
"LabelDurationComparisonShorter": "({0} lyhyempi)",
|
||||||
"LabelEbook": "E-kirja",
|
"LabelEbook": "E-kirja",
|
||||||
"LabelEbooks": "E-kirjat",
|
"LabelEbooks": "E-kirjat",
|
||||||
"LabelEdit": "Muokkaa",
|
"LabelEdit": "Muokkaa",
|
||||||
"LabelEmail": "Sähköposti",
|
"LabelEmail": "Sähköposti",
|
||||||
|
"LabelEmailSettingsTestAddress": "Testiosoite",
|
||||||
|
"LabelEmbeddedCover": "Upotettu kansikuva",
|
||||||
"LabelEnable": "Ota käyttöön",
|
"LabelEnable": "Ota käyttöön",
|
||||||
|
"LabelEnd": "Loppu",
|
||||||
"LabelEndOfChapter": "Luvun loppu",
|
"LabelEndOfChapter": "Luvun loppu",
|
||||||
"LabelEpisode": "Jakso",
|
"LabelEpisode": "Jakso",
|
||||||
|
"LabelEpisodes": "Jaksot",
|
||||||
|
"LabelExample": "Esimerkki",
|
||||||
|
"LabelFeedURL": "Syötteen URL",
|
||||||
"LabelFile": "Tiedosto",
|
"LabelFile": "Tiedosto",
|
||||||
"LabelFileBirthtime": "Tiedoston syntymäaika",
|
"LabelFileBirthtime": "Tiedoston syntymäaika",
|
||||||
|
"LabelFileBornDate": "Syntynyt {0}",
|
||||||
"LabelFileModified": "Muutettu tiedosto",
|
"LabelFileModified": "Muutettu tiedosto",
|
||||||
|
"LabelFileModifiedDate": "Muokattu {0}",
|
||||||
"LabelFilename": "Tiedostonimi",
|
"LabelFilename": "Tiedostonimi",
|
||||||
|
"LabelFindEpisodes": "Etsi jaksoja",
|
||||||
|
"LabelFinished": "Valmis",
|
||||||
"LabelFolder": "Kansio",
|
"LabelFolder": "Kansio",
|
||||||
|
"LabelFolders": "Kansiot",
|
||||||
|
"LabelGenre": "Lajityyppi",
|
||||||
|
"LabelGenres": "Lajityypit",
|
||||||
|
"LabelHost": "Isäntä",
|
||||||
|
"LabelHours": "Tunnit",
|
||||||
"LabelInProgress": "Kesken",
|
"LabelInProgress": "Kesken",
|
||||||
"LabelIncomplete": "Keskeneräinen",
|
"LabelIncomplete": "Keskeneräinen",
|
||||||
|
"LabelIntervalEvery12Hours": "12 tunnin välein",
|
||||||
|
"LabelIntervalEvery15Minutes": "15 minuutin välein",
|
||||||
|
"LabelIntervalEvery2Hours": "2 tunnin välein",
|
||||||
|
"LabelIntervalEvery30Minutes": "30 minuutin välein",
|
||||||
|
"LabelIntervalEvery6Hours": "6 tunnin välein",
|
||||||
|
"LabelIntervalEveryDay": "Joka päivä",
|
||||||
|
"LabelIntervalEveryHour": "Joka tunti",
|
||||||
|
"LabelItem": "Kohde",
|
||||||
"LabelLanguage": "Kieli",
|
"LabelLanguage": "Kieli",
|
||||||
|
"LabelLanguageDefaultServer": "Palvelimen oletuskieli",
|
||||||
|
"LabelLanguages": "Kielet",
|
||||||
|
"LabelLastBookAdded": "Viimeisin lisätty kirja",
|
||||||
|
"LabelLibrary": "Kirjasto",
|
||||||
|
"LabelLineSpacing": "Riviväli",
|
||||||
"LabelListenAgain": "Kuuntele uudelleen",
|
"LabelListenAgain": "Kuuntele uudelleen",
|
||||||
"LabelMediaType": "Mediatyyppi",
|
"LabelMediaType": "Mediatyyppi",
|
||||||
|
"LabelMinute": "Minuutti",
|
||||||
|
"LabelMinutes": "Minuutit",
|
||||||
"LabelMore": "Lisää",
|
"LabelMore": "Lisää",
|
||||||
"LabelMoreInfo": "Lisätietoja",
|
"LabelMoreInfo": "Lisätietoja",
|
||||||
"LabelName": "Nimi",
|
"LabelName": "Nimi",
|
||||||
"LabelNarrator": "Lukija",
|
"LabelNarrator": "Lukija",
|
||||||
"LabelNarrators": "Lukijat",
|
"LabelNarrators": "Lukijat",
|
||||||
|
"LabelNew": "Uusi",
|
||||||
|
"LabelNewPassword": "Uusi salasana",
|
||||||
"LabelNewestAuthors": "Uusimmat kirjailijat",
|
"LabelNewestAuthors": "Uusimmat kirjailijat",
|
||||||
"LabelNewestEpisodes": "Uusimmat jaksot",
|
"LabelNewestEpisodes": "Uusimmat jaksot",
|
||||||
|
"LabelNotStarted": "Ei aloitettu",
|
||||||
"LabelPassword": "Salasana",
|
"LabelPassword": "Salasana",
|
||||||
"LabelPath": "Polku",
|
"LabelPath": "Polku",
|
||||||
|
"LabelPermanent": "Pysyvä",
|
||||||
|
"LabelPermissionsAccessAllLibraries": "Käyttöoikeudet kaikkiin kirjastoihin",
|
||||||
|
"LabelPermissionsDelete": "Voi poistaa",
|
||||||
|
"LabelPermissionsDownload": "Voi ladata",
|
||||||
|
"LabelPermissionsUpdate": "Voi päivittää",
|
||||||
|
"LabelPermissionsUpload": "Voi lähettää",
|
||||||
|
"LabelPlaylists": "Soittolistat",
|
||||||
|
"LabelPodcast": "Podcast",
|
||||||
"LabelPodcasts": "Podcastit",
|
"LabelPodcasts": "Podcastit",
|
||||||
|
"LabelPort": "Portti",
|
||||||
"LabelPublishYear": "Julkaisuvuosi",
|
"LabelPublishYear": "Julkaisuvuosi",
|
||||||
|
"LabelPublisher": "Julkaisija",
|
||||||
|
"LabelPublishers": "Julkaisijat",
|
||||||
"LabelRSSFeedPreventIndexing": "Estä indeksointi",
|
"LabelRSSFeedPreventIndexing": "Estä indeksointi",
|
||||||
|
"LabelRandomly": "Satunnaisesti",
|
||||||
"LabelRead": "Lue",
|
"LabelRead": "Lue",
|
||||||
"LabelReadAgain": "Lue uudelleen",
|
"LabelReadAgain": "Lue uudelleen",
|
||||||
"LabelRecentSeries": "Viimeisimmät sarjat",
|
"LabelRecentSeries": "Viimeisimmät sarjat",
|
||||||
"LabelRecentlyAdded": "Viimeeksi lisätyt",
|
"LabelRecentlyAdded": "Viimeeksi lisätyt",
|
||||||
|
"LabelRecommended": "Suositeltu",
|
||||||
|
"LabelRegion": "Alue",
|
||||||
|
"LabelRemoveCover": "Poista kansikuva",
|
||||||
"LabelSeason": "Kausi",
|
"LabelSeason": "Kausi",
|
||||||
|
"LabelSelectAll": "Valitse kaikki",
|
||||||
|
"LabelSelectUsers": "Valitse käyttäjät",
|
||||||
|
"LabelSeries": "Sarja",
|
||||||
|
"LabelSeriesName": "Sarjan nimi",
|
||||||
"LabelSetEbookAsPrimary": "Aseta ensisijaiseksi",
|
"LabelSetEbookAsPrimary": "Aseta ensisijaiseksi",
|
||||||
"LabelSetEbookAsSupplementary": "Aseta täydentäväksi",
|
"LabelSetEbookAsSupplementary": "Aseta täydentäväksi",
|
||||||
|
"LabelSettingsAudiobooksOnly": "Vain äänikirjat",
|
||||||
|
"LabelSettingsChromecastSupport": "Chromecast-tuki",
|
||||||
|
"LabelSettingsExperimentalFeatures": "Kokeelliset ominaisuudet",
|
||||||
|
"LabelSettingsFindCovers": "Etsi kansikuvia",
|
||||||
|
"LabelShare": "Jaa",
|
||||||
"LabelShowAll": "Näytä kaikki",
|
"LabelShowAll": "Näytä kaikki",
|
||||||
|
"LabelShowSeconds": "Näytä sekunnit",
|
||||||
"LabelSize": "Koko",
|
"LabelSize": "Koko",
|
||||||
"LabelSleepTimer": "Uniajastin",
|
"LabelSleepTimer": "Uniajastin",
|
||||||
|
"LabelStart": "Aloita",
|
||||||
|
"LabelStartTime": "Aloitusaika",
|
||||||
|
"LabelStatsAudioTracks": "Ääniraidat",
|
||||||
|
"LabelStatsBestDay": "Paras päivä",
|
||||||
"LabelStatsDailyAverage": "Päivittäinen keskiarvo",
|
"LabelStatsDailyAverage": "Päivittäinen keskiarvo",
|
||||||
|
"LabelStatsDays": "Päivää",
|
||||||
|
"LabelStatsDaysListened": "Päivää kuunneltu",
|
||||||
|
"LabelStatsHours": "Tunnit",
|
||||||
"LabelStatsInARow": "peräjälkeen",
|
"LabelStatsInARow": "peräjälkeen",
|
||||||
"LabelStatsMinutes": "minuuttia",
|
"LabelStatsMinutes": "minuuttia",
|
||||||
|
"LabelStatsMinutesListening": "Minuuttia kuunneltu",
|
||||||
|
"LabelStatsWeekListening": "Viikon aikana kuunneltu",
|
||||||
|
"LabelTag": "Tägi",
|
||||||
|
"LabelTags": "Tägit",
|
||||||
"LabelTheme": "Teema",
|
"LabelTheme": "Teema",
|
||||||
"LabelThemeDark": "Tumma",
|
"LabelThemeDark": "Tumma",
|
||||||
"LabelThemeLight": "Kirkas",
|
"LabelThemeLight": "Kirkas",
|
||||||
"LabelTimeRemaining": "{0} jäljellä",
|
"LabelTimeRemaining": "{0} jäljellä",
|
||||||
|
"LabelTitle": "Nimi",
|
||||||
|
"LabelTotalDuration": "Kokonaiskesto",
|
||||||
|
"LabelTracks": "Raidat",
|
||||||
"LabelType": "Tyyppi",
|
"LabelType": "Tyyppi",
|
||||||
|
"LabelUnknown": "Tuntematon",
|
||||||
|
"LabelUpdateCover": "Päivitä kansikuva",
|
||||||
"LabelUser": "Käyttäjä",
|
"LabelUser": "Käyttäjä",
|
||||||
"LabelUsername": "Käyttäjätunnus",
|
"LabelUsername": "Käyttäjätunnus",
|
||||||
|
"LabelValue": "Arvo",
|
||||||
|
"LabelVersion": "Versio",
|
||||||
"LabelYourBookmarks": "Kirjanmerkkisi",
|
"LabelYourBookmarks": "Kirjanmerkkisi",
|
||||||
"LabelYourProgress": "Edistymisesi",
|
"LabelYourProgress": "Edistymisesi",
|
||||||
"MessageDownloadingEpisode": "Ladataan jaksoa",
|
"MessageDownloadingEpisode": "Ladataan jaksoa",
|
||||||
"MessageEpisodesQueuedForDownload": "{0} jaksoa on latausjonossa",
|
"MessageEpisodesQueuedForDownload": "{0} jaksoa on latausjonossa",
|
||||||
|
"MessageFeedURLWillBe": "Syötteen URL tulee olemaan {0}",
|
||||||
"MessageFetching": "Haetaan...",
|
"MessageFetching": "Haetaan...",
|
||||||
"MessageLoading": "Ladataan...",
|
"MessageLoading": "Ladataan...",
|
||||||
"MessageMarkAsFinished": "Merkitse valmiiksi",
|
"MessageMarkAsFinished": "Merkitse valmiiksi",
|
||||||
"MessageNoBookmarks": "Ei kirjanmerkkejä",
|
"MessageNoBookmarks": "Ei kirjanmerkkejä",
|
||||||
|
"MessageNoChapters": "Ei kappaleita",
|
||||||
|
"MessageNoCoversFound": "Kansikuvia ei löydetty",
|
||||||
|
"MessageNoGenres": "Ei lajityyppejä",
|
||||||
"MessageNoItems": "Ei kohteita",
|
"MessageNoItems": "Ei kohteita",
|
||||||
"MessageNoItemsFound": "Kohteita ei löytynyt",
|
"MessageNoItemsFound": "Kohteita ei löytynyt",
|
||||||
|
"MessageNoListeningSessions": "Ei kuunteluistuntoja",
|
||||||
"MessageNoPodcastsFound": "Podcasteja ei löytynyt",
|
"MessageNoPodcastsFound": "Podcasteja ei löytynyt",
|
||||||
|
"MessageNoUpdatesWereNecessary": "Päivityksiä ei tarvittu",
|
||||||
"MessageNoUserPlaylists": "Sinulla ei ole soittolistoja",
|
"MessageNoUserPlaylists": "Sinulla ei ole soittolistoja",
|
||||||
|
"MessageOr": "tai",
|
||||||
"MessageReportBugsAndContribute": "Ilmoita virheistä, toivo ominaisuuksia ja osallistu",
|
"MessageReportBugsAndContribute": "Ilmoita virheistä, toivo ominaisuuksia ja osallistu",
|
||||||
|
"MessageTaskFailed": "Epäonnistunut",
|
||||||
|
"StatsSessions": "istunnot",
|
||||||
|
"ToastAccountUpdateSuccess": "Tili päivitetty",
|
||||||
"ToastBookmarkCreateFailed": "Kirjanmerkin luominen epäonnistui",
|
"ToastBookmarkCreateFailed": "Kirjanmerkin luominen epäonnistui",
|
||||||
"ToastBookmarkUpdateFailed": "Kirjanmerkin päivittäminen epäonnistui",
|
"ToastCoverUpdateFailed": "Kansikuvan päivitys epäonnistui",
|
||||||
|
"ToastItemCoverUpdateSuccess": "Kohteen kansikuva päivitetty",
|
||||||
"ToastItemMarkedAsFinishedFailed": "Valmiiksi merkitseminen epäonnistui",
|
"ToastItemMarkedAsFinishedFailed": "Valmiiksi merkitseminen epäonnistui",
|
||||||
|
"ToastItemMarkedAsNotFinishedFailed": "Valmiiksi merkitsemisen poisto epäonnistui",
|
||||||
|
"ToastItemUpdateSuccess": "Kohde päivitetty",
|
||||||
|
"ToastLibraryCreateFailed": "Kirjaston luominen epäonnistui",
|
||||||
|
"ToastLibraryCreateSuccess": "Kirjasto \"{0}\" luotu",
|
||||||
|
"ToastLibraryDeleteFailed": "Kirjaston poistaminen epäonnistui",
|
||||||
|
"ToastLibraryDeleteSuccess": "Kirjasto poistettu",
|
||||||
|
"ToastLibraryUpdateSuccess": "Kirjasto \"{0}\" päivitetty",
|
||||||
|
"ToastNewUserCreatedFailed": "Tilin \"{0}\" luominen epäonnistui",
|
||||||
|
"ToastNewUserCreatedSuccess": "Uusi tili luotu",
|
||||||
"ToastPlaylistCreateFailed": "Soittolistan luominen epäonnistui",
|
"ToastPlaylistCreateFailed": "Soittolistan luominen epäonnistui",
|
||||||
|
"ToastPlaylistCreateSuccess": "Soittolista luotu",
|
||||||
|
"ToastPlaylistRemoveSuccess": "Soittolista poistettu",
|
||||||
|
"ToastPlaylistUpdateSuccess": "Soittolista päivitetty",
|
||||||
"ToastPodcastCreateFailed": "Podcastin luominen epäonnistui",
|
"ToastPodcastCreateFailed": "Podcastin luominen epäonnistui",
|
||||||
"ToastPodcastCreateSuccess": "Podcastin luominen onnistui"
|
"ToastPodcastCreateSuccess": "Podcastin luominen onnistui",
|
||||||
|
"ToastRSSFeedCloseFailed": "RSS syötteen sulkeminen epäonnistui",
|
||||||
|
"ToastRSSFeedCloseSuccess": "RSS syöte suljettu",
|
||||||
|
"ToastRemoveFailed": "Poistaminen epäonnistui",
|
||||||
|
"ToastRemoveItemFromCollectionFailed": "Kohteen poistaminen kokoelmasta epäonnistui",
|
||||||
|
"ToastRemoveItemFromCollectionSuccess": "Kohde poistettu kokoelmasta",
|
||||||
|
"ToastRenameFailed": "Uudelleennimeäminen epäonnistui",
|
||||||
|
"ToastSelectAtLeastOneUser": "Valitse ainakin yksi käyttäjä",
|
||||||
|
"ToastServerSettingsUpdateSuccess": "Palvelimen asetukset päivitetty",
|
||||||
|
"ToastSessionCloseFailed": "Istunnon sulkeminen epäonnistui",
|
||||||
|
"ToastSessionDeleteFailed": "Istunnon poistaminen epäonnistui",
|
||||||
|
"ToastSessionDeleteSuccess": "Istunto poistettu",
|
||||||
|
"ToastSocketConnected": "Yhteys saatu",
|
||||||
|
"ToastSocketDisconnected": "Yhteys katkaistu",
|
||||||
|
"ToastSocketFailedToConnect": "Yhteyden muodostus epäonnistui",
|
||||||
|
"ToastTitleRequired": "Otsikko on pakollinen",
|
||||||
|
"ToastUnknownError": "Tuntematon virhe",
|
||||||
|
"ToastUserDeleteFailed": "Käyttäjän poisto epäonnistui",
|
||||||
|
"ToastUserDeleteSuccess": "Käyttäjä poistettu",
|
||||||
|
"ToastUserPasswordChangeSuccess": "Salasana vaihdettu onnistuneesti",
|
||||||
|
"ToastUserPasswordMismatch": "Salasanat eivät täsmää",
|
||||||
|
"ToastUserPasswordMustChange": "Uusi salasana ei voi olla sama kuin vanha salasana",
|
||||||
|
"ToastUserRootRequireName": "Pääkäyttäjän nimi on pakollinen"
|
||||||
}
|
}
|
||||||
|
|||||||
+207
-58
@@ -9,7 +9,7 @@
|
|||||||
"ButtonApply": "Appliquer",
|
"ButtonApply": "Appliquer",
|
||||||
"ButtonApplyChapters": "Appliquer aux chapitres",
|
"ButtonApplyChapters": "Appliquer aux chapitres",
|
||||||
"ButtonAuthors": "Auteurs",
|
"ButtonAuthors": "Auteurs",
|
||||||
"ButtonBack": "Reculer",
|
"ButtonBack": "Retour",
|
||||||
"ButtonBrowseForFolder": "Naviguer vers le répertoire",
|
"ButtonBrowseForFolder": "Naviguer vers le répertoire",
|
||||||
"ButtonCancel": "Annuler",
|
"ButtonCancel": "Annuler",
|
||||||
"ButtonCancelEncode": "Annuler l’encodage",
|
"ButtonCancelEncode": "Annuler l’encodage",
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
"ButtonClearFilter": "Effacer le filtre",
|
"ButtonClearFilter": "Effacer le filtre",
|
||||||
"ButtonCloseFeed": "Fermer le flux",
|
"ButtonCloseFeed": "Fermer le flux",
|
||||||
"ButtonCloseSession": "Fermer la session",
|
"ButtonCloseSession": "Fermer la session",
|
||||||
|
"ButtonCollections": "Collections",
|
||||||
"ButtonConfigureScanner": "Configurer l’analyse",
|
"ButtonConfigureScanner": "Configurer l’analyse",
|
||||||
"ButtonCreate": "Créer",
|
"ButtonCreate": "Créer",
|
||||||
"ButtonCreateBackup": "Créer une sauvegarde",
|
"ButtonCreateBackup": "Créer une sauvegarde",
|
||||||
@@ -49,10 +50,13 @@
|
|||||||
"ButtonNevermind": "Non merci",
|
"ButtonNevermind": "Non merci",
|
||||||
"ButtonNext": "Suivant",
|
"ButtonNext": "Suivant",
|
||||||
"ButtonNextChapter": "Chapitre suivant",
|
"ButtonNextChapter": "Chapitre suivant",
|
||||||
"ButtonNextItemInQueue": "Elément suivant de la file d'attente",
|
"ButtonNextItemInQueue": "Élément suivant dans la file d’attente",
|
||||||
|
"ButtonOk": "D’accord",
|
||||||
"ButtonOpenFeed": "Ouvrir le flux",
|
"ButtonOpenFeed": "Ouvrir le flux",
|
||||||
"ButtonOpenManager": "Ouvrir le gestionnaire",
|
"ButtonOpenManager": "Ouvrir le gestionnaire",
|
||||||
|
"ButtonPause": "Pause",
|
||||||
"ButtonPlay": "Lire",
|
"ButtonPlay": "Lire",
|
||||||
|
"ButtonPlayAll": "Lire tout",
|
||||||
"ButtonPlaying": "En lecture",
|
"ButtonPlaying": "En lecture",
|
||||||
"ButtonPlaylists": "Listes de lecture",
|
"ButtonPlaylists": "Listes de lecture",
|
||||||
"ButtonPrevious": "Précédent",
|
"ButtonPrevious": "Précédent",
|
||||||
@@ -62,6 +66,7 @@
|
|||||||
"ButtonPurgeItemsCache": "Purger le cache des éléments",
|
"ButtonPurgeItemsCache": "Purger le cache des éléments",
|
||||||
"ButtonQueueAddItem": "Ajouter à la liste de lecture",
|
"ButtonQueueAddItem": "Ajouter à la liste de lecture",
|
||||||
"ButtonQueueRemoveItem": "Supprimer de la liste de lecture",
|
"ButtonQueueRemoveItem": "Supprimer de la liste de lecture",
|
||||||
|
"ButtonQuickEmbed": "Intégration rapide",
|
||||||
"ButtonQuickEmbedMetadata": "Ajouter rapidement des métadonnées",
|
"ButtonQuickEmbedMetadata": "Ajouter rapidement des métadonnées",
|
||||||
"ButtonQuickMatch": "Recherche rapide",
|
"ButtonQuickMatch": "Recherche rapide",
|
||||||
"ButtonReScan": "Nouvelle analyse",
|
"ButtonReScan": "Nouvelle analyse",
|
||||||
@@ -94,7 +99,8 @@
|
|||||||
"ButtonStartMetadataEmbed": "Démarrer les Métadonnées intégrées",
|
"ButtonStartMetadataEmbed": "Démarrer les Métadonnées intégrées",
|
||||||
"ButtonStats": "Statistiques",
|
"ButtonStats": "Statistiques",
|
||||||
"ButtonSubmit": "Soumettre",
|
"ButtonSubmit": "Soumettre",
|
||||||
"ButtonUnlinkOpedId": "Dissocier OpenID",
|
"ButtonTest": "Test",
|
||||||
|
"ButtonUnlinkOpenId": "Dissocier OpenID",
|
||||||
"ButtonUpload": "Téléverser",
|
"ButtonUpload": "Téléverser",
|
||||||
"ButtonUploadBackup": "Téléverser une sauvegarde",
|
"ButtonUploadBackup": "Téléverser une sauvegarde",
|
||||||
"ButtonUploadCover": "Téléverser une couverture",
|
"ButtonUploadCover": "Téléverser une couverture",
|
||||||
@@ -112,10 +118,12 @@
|
|||||||
"HeaderAppriseNotificationSettings": "Configuration des notifications Apprise",
|
"HeaderAppriseNotificationSettings": "Configuration des notifications Apprise",
|
||||||
"HeaderAudioTracks": "Pistes audio",
|
"HeaderAudioTracks": "Pistes audio",
|
||||||
"HeaderAudiobookTools": "Outils de gestion de fichiers de livres audio",
|
"HeaderAudiobookTools": "Outils de gestion de fichiers de livres audio",
|
||||||
|
"HeaderAuthentication": "Authentification",
|
||||||
"HeaderBackups": "Sauvegardes",
|
"HeaderBackups": "Sauvegardes",
|
||||||
"HeaderChangePassword": "Modifier le mot de passe",
|
"HeaderChangePassword": "Modifier le mot de passe",
|
||||||
"HeaderChapters": "Chapitres",
|
"HeaderChapters": "Chapitres",
|
||||||
"HeaderChooseAFolder": "Choisir un dossier",
|
"HeaderChooseAFolder": "Choisir un dossier",
|
||||||
|
"HeaderCollection": "Collection",
|
||||||
"HeaderCollectionItems": "Entrées de la collection",
|
"HeaderCollectionItems": "Entrées de la collection",
|
||||||
"HeaderCover": "Couverture",
|
"HeaderCover": "Couverture",
|
||||||
"HeaderCurrentDownloads": "Téléchargements en cours",
|
"HeaderCurrentDownloads": "Téléchargements en cours",
|
||||||
@@ -153,10 +161,12 @@
|
|||||||
"HeaderNewLibrary": "Nouvelle bibliothèque",
|
"HeaderNewLibrary": "Nouvelle bibliothèque",
|
||||||
"HeaderNotificationCreate": "Créer une notification",
|
"HeaderNotificationCreate": "Créer une notification",
|
||||||
"HeaderNotificationUpdate": "Mise à jour de la notification",
|
"HeaderNotificationUpdate": "Mise à jour de la notification",
|
||||||
|
"HeaderNotifications": "Notifications",
|
||||||
"HeaderOpenIDConnectAuthentication": "Authentification via OpenID Connect",
|
"HeaderOpenIDConnectAuthentication": "Authentification via OpenID Connect",
|
||||||
"HeaderOpenRSSFeed": "Ouvrir le flux RSS",
|
"HeaderOpenRSSFeed": "Ouvrir le flux RSS",
|
||||||
"HeaderOtherFiles": "Autres fichiers",
|
"HeaderOtherFiles": "Autres fichiers",
|
||||||
"HeaderPasswordAuthentication": "Authentification par mot de passe",
|
"HeaderPasswordAuthentication": "Authentification par mot de passe",
|
||||||
|
"HeaderPermissions": "Permissions",
|
||||||
"HeaderPlayerQueue": "Liste d’écoute",
|
"HeaderPlayerQueue": "Liste d’écoute",
|
||||||
"HeaderPlayerSettings": "Paramètres du lecteur",
|
"HeaderPlayerSettings": "Paramètres du lecteur",
|
||||||
"HeaderPlaylist": "Liste de lecture",
|
"HeaderPlaylist": "Liste de lecture",
|
||||||
@@ -171,6 +181,7 @@
|
|||||||
"HeaderSavedMediaProgress": "Progression de la sauvegarde des médias",
|
"HeaderSavedMediaProgress": "Progression de la sauvegarde des médias",
|
||||||
"HeaderSchedule": "Programmation",
|
"HeaderSchedule": "Programmation",
|
||||||
"HeaderScheduleLibraryScans": "Analyse automatique de la bibliothèque",
|
"HeaderScheduleLibraryScans": "Analyse automatique de la bibliothèque",
|
||||||
|
"HeaderSession": "Session",
|
||||||
"HeaderSetBackupSchedule": "Activer la sauvegarde automatique",
|
"HeaderSetBackupSchedule": "Activer la sauvegarde automatique",
|
||||||
"HeaderSettings": "Paramètres",
|
"HeaderSettings": "Paramètres",
|
||||||
"HeaderSettingsDisplay": "Affichage",
|
"HeaderSettingsDisplay": "Affichage",
|
||||||
@@ -183,6 +194,7 @@
|
|||||||
"HeaderStatsMinutesListeningChart": "Minutes d’écoute (7 derniers jours)",
|
"HeaderStatsMinutesListeningChart": "Minutes d’écoute (7 derniers jours)",
|
||||||
"HeaderStatsRecentSessions": "Sessions récentes",
|
"HeaderStatsRecentSessions": "Sessions récentes",
|
||||||
"HeaderStatsTop10Authors": "Top 10 Auteurs",
|
"HeaderStatsTop10Authors": "Top 10 Auteurs",
|
||||||
|
"HeaderStatsTop5Genres": "Top 5 Genres",
|
||||||
"HeaderTableOfContents": "Table des matières",
|
"HeaderTableOfContents": "Table des matières",
|
||||||
"HeaderTools": "Outils",
|
"HeaderTools": "Outils",
|
||||||
"HeaderUpdateAccount": "Mettre à jour le compte",
|
"HeaderUpdateAccount": "Mettre à jour le compte",
|
||||||
@@ -197,15 +209,16 @@
|
|||||||
"LabelAbridgedUnchecked": "Intégral (non vérifié)",
|
"LabelAbridgedUnchecked": "Intégral (non vérifié)",
|
||||||
"LabelAccessibleBy": "Accessible par",
|
"LabelAccessibleBy": "Accessible par",
|
||||||
"LabelAccountType": "Type de compte",
|
"LabelAccountType": "Type de compte",
|
||||||
|
"LabelAccountTypeAdmin": "Admin",
|
||||||
"LabelAccountTypeGuest": "Invité",
|
"LabelAccountTypeGuest": "Invité",
|
||||||
"LabelAccountTypeUser": "Utilisateur",
|
"LabelAccountTypeUser": "Utilisateur",
|
||||||
"LabelActivity": "Activité",
|
"LabelActivity": "Activité",
|
||||||
"LabelAddToCollection": "Ajouter à la collection",
|
"LabelAddToCollection": "Ajouter à la collection",
|
||||||
"LabelAddToCollectionBatch": "Ajout de {0} livres à la lollection",
|
"LabelAddToCollectionBatch": "Ajout de {0} livres à la collection",
|
||||||
"LabelAddToPlaylist": "Ajouter à la liste de lecture",
|
"LabelAddToPlaylist": "Ajouter à la liste de lecture",
|
||||||
"LabelAddToPlaylistBatch": "{0} éléments ajoutés à la liste de lecture",
|
"LabelAddToPlaylistBatch": "{0} éléments ajoutés à la liste de lecture",
|
||||||
"LabelAddedAt": "Date d’ajout",
|
"LabelAddedAt": "Date d’ajout",
|
||||||
"LabelAddedDate": "{0} ajoutés",
|
"LabelAddedDate": "Ajouté le {0}",
|
||||||
"LabelAdminUsersOnly": "Administrateurs uniquement",
|
"LabelAdminUsersOnly": "Administrateurs uniquement",
|
||||||
"LabelAll": "Tout",
|
"LabelAll": "Tout",
|
||||||
"LabelAllUsers": "Tous les utilisateurs",
|
"LabelAllUsers": "Tous les utilisateurs",
|
||||||
@@ -213,6 +226,9 @@
|
|||||||
"LabelAllUsersIncludingGuests": "Tous les utilisateurs, y compris les invités",
|
"LabelAllUsersIncludingGuests": "Tous les utilisateurs, y compris les invités",
|
||||||
"LabelAlreadyInYourLibrary": "Déjà dans la bibliothèque",
|
"LabelAlreadyInYourLibrary": "Déjà dans la bibliothèque",
|
||||||
"LabelAppend": "Ajouter",
|
"LabelAppend": "Ajouter",
|
||||||
|
"LabelAudioBitrate": "Débit audio (par exemple 128k)",
|
||||||
|
"LabelAudioChannels": "Canaux audio (1 ou 2)",
|
||||||
|
"LabelAudioCodec": "Codec audio",
|
||||||
"LabelAuthor": "Auteur",
|
"LabelAuthor": "Auteur",
|
||||||
"LabelAuthorFirstLast": "Auteur (Prénom Nom)",
|
"LabelAuthorFirstLast": "Auteur (Prénom Nom)",
|
||||||
"LabelAuthorLastFirst": "Auteur (Nom, Prénom)",
|
"LabelAuthorLastFirst": "Auteur (Nom, Prénom)",
|
||||||
@@ -225,6 +241,7 @@
|
|||||||
"LabelAutoRegister": "Enregistrement automatique",
|
"LabelAutoRegister": "Enregistrement automatique",
|
||||||
"LabelAutoRegisterDescription": "Créer automatiquement de nouveaux utilisateurs après la connexion",
|
"LabelAutoRegisterDescription": "Créer automatiquement de nouveaux utilisateurs après la connexion",
|
||||||
"LabelBackToUser": "Retour à l’utilisateur",
|
"LabelBackToUser": "Retour à l’utilisateur",
|
||||||
|
"LabelBackupAudioFiles": "Sauvegarder les fichiers audio",
|
||||||
"LabelBackupLocation": "Emplacement de la sauvegarde",
|
"LabelBackupLocation": "Emplacement de la sauvegarde",
|
||||||
"LabelBackupsEnableAutomaticBackups": "Activer les sauvegardes automatiques",
|
"LabelBackupsEnableAutomaticBackups": "Activer les sauvegardes automatiques",
|
||||||
"LabelBackupsEnableAutomaticBackupsHelp": "Sauvegardes enregistrées dans /metadata/backups",
|
"LabelBackupsEnableAutomaticBackupsHelp": "Sauvegardes enregistrées dans /metadata/backups",
|
||||||
@@ -232,6 +249,7 @@
|
|||||||
"LabelBackupsMaxBackupSizeHelp": "Afin de prévenir les mauvaises configuration, la sauvegarde échouera si elle excède la taille limite.",
|
"LabelBackupsMaxBackupSizeHelp": "Afin de prévenir les mauvaises configuration, la sauvegarde échouera si elle excède la taille limite.",
|
||||||
"LabelBackupsNumberToKeep": "Nombre de sauvegardes à conserver",
|
"LabelBackupsNumberToKeep": "Nombre de sauvegardes à conserver",
|
||||||
"LabelBackupsNumberToKeepHelp": "Seule une sauvegarde sera supprimée à la fois. Si vous avez déjà plus de sauvegardes à effacer, vous devez les supprimer manuellement.",
|
"LabelBackupsNumberToKeepHelp": "Seule une sauvegarde sera supprimée à la fois. Si vous avez déjà plus de sauvegardes à effacer, vous devez les supprimer manuellement.",
|
||||||
|
"LabelBitrate": "Débit binaire",
|
||||||
"LabelBooks": "Livres",
|
"LabelBooks": "Livres",
|
||||||
"LabelButtonText": "Texte du bouton",
|
"LabelButtonText": "Texte du bouton",
|
||||||
"LabelByAuthor": "par {0}",
|
"LabelByAuthor": "par {0}",
|
||||||
@@ -242,8 +260,11 @@
|
|||||||
"LabelChaptersFound": "chapitres trouvés",
|
"LabelChaptersFound": "chapitres trouvés",
|
||||||
"LabelClickForMoreInfo": "Cliquez ici pour plus d’informations",
|
"LabelClickForMoreInfo": "Cliquez ici pour plus d’informations",
|
||||||
"LabelClosePlayer": "Fermer le lecteur",
|
"LabelClosePlayer": "Fermer le lecteur",
|
||||||
|
"LabelCodec": "Codec",
|
||||||
"LabelCollapseSeries": "Réduire les séries",
|
"LabelCollapseSeries": "Réduire les séries",
|
||||||
"LabelCollapseSubSeries": "Replier les sous-séries",
|
"LabelCollapseSubSeries": "Replier les sous-séries",
|
||||||
|
"LabelCollection": "Collection",
|
||||||
|
"LabelCollections": "Collections",
|
||||||
"LabelComplete": "Complet",
|
"LabelComplete": "Complet",
|
||||||
"LabelConfirmPassword": "Confirmer le mot de passe",
|
"LabelConfirmPassword": "Confirmer le mot de passe",
|
||||||
"LabelContinueListening": "Continuer la lecture",
|
"LabelContinueListening": "Continuer la lecture",
|
||||||
@@ -259,6 +280,7 @@
|
|||||||
"LabelDatetime": "Date",
|
"LabelDatetime": "Date",
|
||||||
"LabelDays": "Jours",
|
"LabelDays": "Jours",
|
||||||
"LabelDeleteFromFileSystemCheckbox": "Supprimer du système de fichiers (décocher pour ne supprimer que de la base de données)",
|
"LabelDeleteFromFileSystemCheckbox": "Supprimer du système de fichiers (décocher pour ne supprimer que de la base de données)",
|
||||||
|
"LabelDescription": "Description",
|
||||||
"LabelDeselectAll": "Tout déselectionner",
|
"LabelDeselectAll": "Tout déselectionner",
|
||||||
"LabelDevice": "Appareil",
|
"LabelDevice": "Appareil",
|
||||||
"LabelDeviceInfo": "Détail de l’appareil",
|
"LabelDeviceInfo": "Détail de l’appareil",
|
||||||
@@ -286,6 +308,15 @@
|
|||||||
"LabelEmailSettingsTestAddress": "Adresse de test",
|
"LabelEmailSettingsTestAddress": "Adresse de test",
|
||||||
"LabelEmbeddedCover": "Couverture du livre intégrée",
|
"LabelEmbeddedCover": "Couverture du livre intégrée",
|
||||||
"LabelEnable": "Activer",
|
"LabelEnable": "Activer",
|
||||||
|
"LabelEncodingBackupLocation": "Une sauvegarde de vos fichiers audio originaux sera stockée dans :",
|
||||||
|
"LabelEncodingChaptersNotEmbedded": "Les chapitres ne sont pas intégrés dans les livres audio multipistes.",
|
||||||
|
"LabelEncodingClearItemCache": "Assurez-vous de purger périodiquement le cache des éléments.",
|
||||||
|
"LabelEncodingFinishedM4B": "Le fichier M4B terminé sera placé dans votre dossier de livre audio à l'adresse suivante :",
|
||||||
|
"LabelEncodingInfoEmbedded": "Les métadonnées seront intégrées dans les pistes audio de votre dossier de livre audio.",
|
||||||
|
"LabelEncodingStartedNavigation": "Une fois la tâche démarrée, vous pouvez quitter cette page.",
|
||||||
|
"LabelEncodingTimeWarning": "L’encodage peut prendre jusqu’à 30 minutes.",
|
||||||
|
"LabelEncodingWarningAdvancedSettings": "Avertissement : ne mettez pas à jour ces paramètres à moins que vous ne soyez familier avec les options d'encodage « ffmpeg ».",
|
||||||
|
"LabelEncodingWatcherDisabled": "Si l'observateur est désactivé, vous devrez ensuite réanalyser ce livre audio.",
|
||||||
"LabelEnd": "Fin",
|
"LabelEnd": "Fin",
|
||||||
"LabelEndOfChapter": "Fin du chapitre",
|
"LabelEndOfChapter": "Fin du chapitre",
|
||||||
"LabelEpisode": "Épisode",
|
"LabelEpisode": "Épisode",
|
||||||
@@ -303,8 +334,9 @@
|
|||||||
"LabelFetchingMetadata": "Récupération des métadonnées",
|
"LabelFetchingMetadata": "Récupération des métadonnées",
|
||||||
"LabelFile": "Fichier",
|
"LabelFile": "Fichier",
|
||||||
"LabelFileBirthtime": "Création du fichier",
|
"LabelFileBirthtime": "Création du fichier",
|
||||||
|
"LabelFileBornDate": "Créé le {0}",
|
||||||
"LabelFileModified": "Modification du fichier",
|
"LabelFileModified": "Modification du fichier",
|
||||||
"LabelFileModifiedDate": "{0} modifiés",
|
"LabelFileModifiedDate": "Modifié le {0}",
|
||||||
"LabelFilename": "Nom de fichier",
|
"LabelFilename": "Nom de fichier",
|
||||||
"LabelFilterByUser": "Filtrer par utilisateur",
|
"LabelFilterByUser": "Filtrer par utilisateur",
|
||||||
"LabelFindEpisodes": "Trouver des épisodes",
|
"LabelFindEpisodes": "Trouver des épisodes",
|
||||||
@@ -317,6 +349,9 @@
|
|||||||
"LabelFontItalic": "Italique",
|
"LabelFontItalic": "Italique",
|
||||||
"LabelFontScale": "Taille de la police de caractère",
|
"LabelFontScale": "Taille de la police de caractère",
|
||||||
"LabelFontStrikethrough": "Barrer",
|
"LabelFontStrikethrough": "Barrer",
|
||||||
|
"LabelFormat": "Format",
|
||||||
|
"LabelGenre": "Genre",
|
||||||
|
"LabelGenres": "Genres",
|
||||||
"LabelHardDeleteFile": "Suppression du fichier",
|
"LabelHardDeleteFile": "Suppression du fichier",
|
||||||
"LabelHasEbook": "A un livre numérique",
|
"LabelHasEbook": "A un livre numérique",
|
||||||
"LabelHasSupplementaryEbook": "A un livre numérique supplémentaire",
|
"LabelHasSupplementaryEbook": "A un livre numérique supplémentaire",
|
||||||
@@ -363,6 +398,9 @@
|
|||||||
"LabelLimit": "Limite",
|
"LabelLimit": "Limite",
|
||||||
"LabelLineSpacing": "Espacement des lignes",
|
"LabelLineSpacing": "Espacement des lignes",
|
||||||
"LabelListenAgain": "Écouter à nouveau",
|
"LabelListenAgain": "Écouter à nouveau",
|
||||||
|
"LabelLogLevelDebug": "Débogage",
|
||||||
|
"LabelLogLevelInfo": "Info",
|
||||||
|
"LabelLogLevelWarn": "Warn",
|
||||||
"LabelLookForNewEpisodesAfterDate": "Rechercher les nouveaux épisodes après cette date",
|
"LabelLookForNewEpisodesAfterDate": "Rechercher les nouveaux épisodes après cette date",
|
||||||
"LabelLowestPriority": "Priorité la plus basse",
|
"LabelLowestPriority": "Priorité la plus basse",
|
||||||
"LabelMatchExistingUsersBy": "Correspondance avec les utilisateurs existants",
|
"LabelMatchExistingUsersBy": "Correspondance avec les utilisateurs existants",
|
||||||
@@ -373,6 +411,8 @@
|
|||||||
"LabelMetaTags": "Balises de métadonnée",
|
"LabelMetaTags": "Balises de métadonnée",
|
||||||
"LabelMetadataOrderOfPrecedenceDescription": "Les sources de métadonnées ayant une priorité plus élevée auront la priorité sur celles ayant une priorité moins élevée",
|
"LabelMetadataOrderOfPrecedenceDescription": "Les sources de métadonnées ayant une priorité plus élevée auront la priorité sur celles ayant une priorité moins élevée",
|
||||||
"LabelMetadataProvider": "Fournisseur de métadonnées",
|
"LabelMetadataProvider": "Fournisseur de métadonnées",
|
||||||
|
"LabelMinute": "Minute",
|
||||||
|
"LabelMinutes": "Minutes",
|
||||||
"LabelMissing": "Manquant",
|
"LabelMissing": "Manquant",
|
||||||
"LabelMissingEbook": "Ne possède aucun livre numérique",
|
"LabelMissingEbook": "Ne possède aucun livre numérique",
|
||||||
"LabelMissingSupplementaryEbook": "Ne possède aucun livre numérique supplémentaire",
|
"LabelMissingSupplementaryEbook": "Ne possède aucun livre numérique supplémentaire",
|
||||||
@@ -393,12 +433,13 @@
|
|||||||
"LabelNoEpisodesSelected": "Aucun épisode sélectionné",
|
"LabelNoEpisodesSelected": "Aucun épisode sélectionné",
|
||||||
"LabelNotFinished": "Non terminé",
|
"LabelNotFinished": "Non terminé",
|
||||||
"LabelNotStarted": "Pas commencé",
|
"LabelNotStarted": "Pas commencé",
|
||||||
|
"LabelNotes": "Notes",
|
||||||
"LabelNotificationAppriseURL": "URL(s) d’Apprise",
|
"LabelNotificationAppriseURL": "URL(s) d’Apprise",
|
||||||
"LabelNotificationAvailableVariables": "Variables disponibles",
|
"LabelNotificationAvailableVariables": "Variables disponibles",
|
||||||
"LabelNotificationBodyTemplate": "Modèle de message",
|
"LabelNotificationBodyTemplate": "Modèle de message",
|
||||||
"LabelNotificationEvent": "Evènement de Notification",
|
"LabelNotificationEvent": "Evènement de Notification",
|
||||||
"LabelNotificationTitleTemplate": "Modèle de titre",
|
"LabelNotificationTitleTemplate": "Modèle de titre",
|
||||||
"LabelNotificationsMaxFailedAttempts": "Nombres de tentatives d’envoi",
|
"LabelNotificationsMaxFailedAttempts": "Nombre maximal de tentatives échouées atteint",
|
||||||
"LabelNotificationsMaxFailedAttemptsHelp": "La notification est abandonnée une fois ce seuil atteint",
|
"LabelNotificationsMaxFailedAttemptsHelp": "La notification est abandonnée une fois ce seuil atteint",
|
||||||
"LabelNotificationsMaxQueueSize": "Nombres de notifications maximum à mettre en attente",
|
"LabelNotificationsMaxQueueSize": "Nombres de notifications maximum à mettre en attente",
|
||||||
"LabelNotificationsMaxQueueSizeHelp": "La limite de notification est de un évènement par seconde. Les notifications seront ignorées si la file d’attente est à son maximum. Cela empêche un flot trop important.",
|
"LabelNotificationsMaxQueueSizeHelp": "La limite de notification est de un évènement par seconde. Les notifications seront ignorées si la file d’attente est à son maximum. Cela empêche un flot trop important.",
|
||||||
@@ -411,6 +452,7 @@
|
|||||||
"LabelOverwrite": "Écraser",
|
"LabelOverwrite": "Écraser",
|
||||||
"LabelPassword": "Mot de passe",
|
"LabelPassword": "Mot de passe",
|
||||||
"LabelPath": "Chemin",
|
"LabelPath": "Chemin",
|
||||||
|
"LabelPermanent": "Permanent",
|
||||||
"LabelPermissionsAccessAllLibraries": "Peut accéder à toutes les bibliothèque",
|
"LabelPermissionsAccessAllLibraries": "Peut accéder à toutes les bibliothèque",
|
||||||
"LabelPermissionsAccessAllTags": "Peut accéder à toutes les étiquettes",
|
"LabelPermissionsAccessAllTags": "Peut accéder à toutes les étiquettes",
|
||||||
"LabelPermissionsAccessExplicitContent": "Peut accéder au contenu restreint",
|
"LabelPermissionsAccessExplicitContent": "Peut accéder au contenu restreint",
|
||||||
@@ -423,8 +465,11 @@
|
|||||||
"LabelPlayMethod": "Méthode d’écoute",
|
"LabelPlayMethod": "Méthode d’écoute",
|
||||||
"LabelPlayerChapterNumberMarker": "{0} sur {1}",
|
"LabelPlayerChapterNumberMarker": "{0} sur {1}",
|
||||||
"LabelPlaylists": "Listes de lecture",
|
"LabelPlaylists": "Listes de lecture",
|
||||||
|
"LabelPodcast": "Podcast",
|
||||||
"LabelPodcastSearchRegion": "Région de recherche de podcasts",
|
"LabelPodcastSearchRegion": "Région de recherche de podcasts",
|
||||||
"LabelPodcastType": "Type de Podcast",
|
"LabelPodcastType": "Type de Podcast",
|
||||||
|
"LabelPodcasts": "Podcasts",
|
||||||
|
"LabelPort": "Port",
|
||||||
"LabelPrefixesToIgnore": "Préfixes à Ignorer (Insensible à la Casse)",
|
"LabelPrefixesToIgnore": "Préfixes à Ignorer (Insensible à la Casse)",
|
||||||
"LabelPreventIndexing": "Empêcher l’indexation de votre flux par les bases de données iTunes et Google podcast",
|
"LabelPreventIndexing": "Empêcher l’indexation de votre flux par les bases de données iTunes et Google podcast",
|
||||||
"LabelPrimaryEbook": "Premier livre numérique",
|
"LabelPrimaryEbook": "Premier livre numérique",
|
||||||
@@ -433,14 +478,16 @@
|
|||||||
"LabelProviderAuthorizationValue": "Valeur de l’en-tête d’autorisation",
|
"LabelProviderAuthorizationValue": "Valeur de l’en-tête d’autorisation",
|
||||||
"LabelPubDate": "Date de publication",
|
"LabelPubDate": "Date de publication",
|
||||||
"LabelPublishYear": "Année de publication",
|
"LabelPublishYear": "Année de publication",
|
||||||
"LabelPublishedDate": "{0} publiés",
|
"LabelPublishedDate": "Publié en {0}",
|
||||||
|
"LabelPublishedDecade": "Décennie de publication",
|
||||||
|
"LabelPublishedDecades": "Décennies de publication",
|
||||||
"LabelPublisher": "Éditeur",
|
"LabelPublisher": "Éditeur",
|
||||||
"LabelPublishers": "Éditeurs",
|
"LabelPublishers": "Éditeurs",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "Courriel personnalisée du propriétaire",
|
"LabelRSSFeedCustomOwnerEmail": "Courriel personnalisée du propriétaire",
|
||||||
"LabelRSSFeedCustomOwnerName": "Nom propriétaire personnalisé",
|
"LabelRSSFeedCustomOwnerName": "Nom propriétaire personnalisé",
|
||||||
"LabelRSSFeedOpen": "Flux RSS ouvert",
|
"LabelRSSFeedOpen": "Flux RSS ouvert",
|
||||||
"LabelRSSFeedPreventIndexing": "Empêcher l’indexation",
|
"LabelRSSFeedPreventIndexing": "Empêcher l’indexation",
|
||||||
"LabelRSSFeedSlug": "Balise URL du flux RSS",
|
"LabelRSSFeedSlug": "Identifiant d’URL du flux RSS",
|
||||||
"LabelRSSFeedURL": "Adresse du flux RSS",
|
"LabelRSSFeedURL": "Adresse du flux RSS",
|
||||||
"LabelRandomly": "Au hasard",
|
"LabelRandomly": "Au hasard",
|
||||||
"LabelReAddSeriesToContinueListening": "Ajouter à nouveau la série pour continuer à l’écouter",
|
"LabelReAddSeriesToContinueListening": "Ajouter à nouveau la série pour continuer à l’écouter",
|
||||||
@@ -461,13 +508,14 @@
|
|||||||
"LabelSeason": "Saison",
|
"LabelSeason": "Saison",
|
||||||
"LabelSelectAll": "Tout sélectionner",
|
"LabelSelectAll": "Tout sélectionner",
|
||||||
"LabelSelectAllEpisodes": "Sélectionner tous les épisodes",
|
"LabelSelectAllEpisodes": "Sélectionner tous les épisodes",
|
||||||
"LabelSelectEpisodesShowing": "Sélectionner {0} episode(s) en cours",
|
"LabelSelectEpisodesShowing": "Sélectionner {0} épisode(s) en cours",
|
||||||
"LabelSelectUsers": "Sélectionner les utilisateurs",
|
"LabelSelectUsers": "Sélectionner les utilisateurs",
|
||||||
"LabelSendEbookToDevice": "Envoyer le livre numérique à…",
|
"LabelSendEbookToDevice": "Envoyer le livre numérique à…",
|
||||||
"LabelSequence": "Séquence",
|
"LabelSequence": "Séquence",
|
||||||
"LabelSeries": "Séries",
|
"LabelSeries": "Séries",
|
||||||
"LabelSeriesName": "Nom de la série",
|
"LabelSeriesName": "Nom de la série",
|
||||||
"LabelSeriesProgress": "Progression de séries",
|
"LabelSeriesProgress": "Progression de séries",
|
||||||
|
"LabelServerLogLevel": "Niveau de journalisation du serveur",
|
||||||
"LabelServerYearReview": "Bilan de l’année du serveur ({0})",
|
"LabelServerYearReview": "Bilan de l’année du serveur ({0})",
|
||||||
"LabelSetEbookAsPrimary": "Définir comme principale",
|
"LabelSetEbookAsPrimary": "Définir comme principale",
|
||||||
"LabelSetEbookAsSupplementary": "Définir comme supplémentaire",
|
"LabelSetEbookAsSupplementary": "Définir comme supplémentaire",
|
||||||
@@ -517,7 +565,7 @@
|
|||||||
"LabelShowSubtitles": "Afficher les sous-titres",
|
"LabelShowSubtitles": "Afficher les sous-titres",
|
||||||
"LabelSize": "Taille",
|
"LabelSize": "Taille",
|
||||||
"LabelSleepTimer": "Minuterie de mise en veille",
|
"LabelSleepTimer": "Minuterie de mise en veille",
|
||||||
"LabelSlug": "Balise",
|
"LabelSlug": "Identifiant d’URL",
|
||||||
"LabelStart": "Démarrer",
|
"LabelStart": "Démarrer",
|
||||||
"LabelStartTime": "Heure de démarrage",
|
"LabelStartTime": "Heure de démarrage",
|
||||||
"LabelStarted": "Démarré",
|
"LabelStarted": "Démarré",
|
||||||
@@ -532,6 +580,7 @@
|
|||||||
"LabelStatsInARow": "d’affilée(s)",
|
"LabelStatsInARow": "d’affilée(s)",
|
||||||
"LabelStatsItemsFinished": "Éléments terminés",
|
"LabelStatsItemsFinished": "Éléments terminés",
|
||||||
"LabelStatsItemsInLibrary": "Éléments dans la bibliothèque",
|
"LabelStatsItemsInLibrary": "Éléments dans la bibliothèque",
|
||||||
|
"LabelStatsMinutes": "minutes",
|
||||||
"LabelStatsMinutesListening": "Minutes d’écoute",
|
"LabelStatsMinutesListening": "Minutes d’écoute",
|
||||||
"LabelStatsOverallDays": "Nombre total de jours",
|
"LabelStatsOverallDays": "Nombre total de jours",
|
||||||
"LabelStatsOverallHours": "Nombre total d’heures",
|
"LabelStatsOverallHours": "Nombre total d’heures",
|
||||||
@@ -552,6 +601,7 @@
|
|||||||
"LabelThemeLight": "Clair",
|
"LabelThemeLight": "Clair",
|
||||||
"LabelTimeBase": "Base de temps",
|
"LabelTimeBase": "Base de temps",
|
||||||
"LabelTimeDurationXHours": "{0} heures",
|
"LabelTimeDurationXHours": "{0} heures",
|
||||||
|
"LabelTimeDurationXMinutes": "{0} minutes",
|
||||||
"LabelTimeDurationXSeconds": "{0} secondes",
|
"LabelTimeDurationXSeconds": "{0} secondes",
|
||||||
"LabelTimeInMinutes": "Temps en minutes",
|
"LabelTimeInMinutes": "Temps en minutes",
|
||||||
"LabelTimeListened": "Temps d’écoute",
|
"LabelTimeListened": "Temps d’écoute",
|
||||||
@@ -561,6 +611,7 @@
|
|||||||
"LabelTitle": "Titre",
|
"LabelTitle": "Titre",
|
||||||
"LabelToolsEmbedMetadata": "Métadonnées intégrées",
|
"LabelToolsEmbedMetadata": "Métadonnées intégrées",
|
||||||
"LabelToolsEmbedMetadataDescription": "Intègre les métadonnées au fichier audio avec la couverture et les chapitres.",
|
"LabelToolsEmbedMetadataDescription": "Intègre les métadonnées au fichier audio avec la couverture et les chapitres.",
|
||||||
|
"LabelToolsM4bEncoder": "Encodeur M4B",
|
||||||
"LabelToolsMakeM4b": "Créer un fichier livre audio M4B",
|
"LabelToolsMakeM4b": "Créer un fichier livre audio M4B",
|
||||||
"LabelToolsMakeM4bDescription": "Générer un fichier de livre audio .M4B avec des métadonnées intégrées, une image de couverture et des chapitres.",
|
"LabelToolsMakeM4bDescription": "Générer un fichier de livre audio .M4B avec des métadonnées intégrées, une image de couverture et des chapitres.",
|
||||||
"LabelToolsSplitM4b": "Scinde le fichier M4B en fichiers MP3",
|
"LabelToolsSplitM4b": "Scinde le fichier M4B en fichiers MP3",
|
||||||
@@ -573,6 +624,7 @@
|
|||||||
"LabelTracksMultiTrack": "Piste multiple",
|
"LabelTracksMultiTrack": "Piste multiple",
|
||||||
"LabelTracksNone": "Aucune piste",
|
"LabelTracksNone": "Aucune piste",
|
||||||
"LabelTracksSingleTrack": "Piste simple",
|
"LabelTracksSingleTrack": "Piste simple",
|
||||||
|
"LabelType": "Type",
|
||||||
"LabelUnabridged": "Version intégrale",
|
"LabelUnabridged": "Version intégrale",
|
||||||
"LabelUndo": "Annuler",
|
"LabelUndo": "Annuler",
|
||||||
"LabelUnknown": "Inconnu",
|
"LabelUnknown": "Inconnu",
|
||||||
@@ -585,15 +637,18 @@
|
|||||||
"LabelUploaderDragAndDrop": "Glisser et déposer des fichiers ou dossiers",
|
"LabelUploaderDragAndDrop": "Glisser et déposer des fichiers ou dossiers",
|
||||||
"LabelUploaderDropFiles": "Déposer des fichiers",
|
"LabelUploaderDropFiles": "Déposer des fichiers",
|
||||||
"LabelUploaderItemFetchMetadataHelp": "Récupérer automatiquement le titre, l’auteur et la série",
|
"LabelUploaderItemFetchMetadataHelp": "Récupérer automatiquement le titre, l’auteur et la série",
|
||||||
|
"LabelUseAdvancedOptions": "Utiliser les options avancées",
|
||||||
"LabelUseChapterTrack": "Utiliser la piste du chapitre",
|
"LabelUseChapterTrack": "Utiliser la piste du chapitre",
|
||||||
"LabelUseFullTrack": "Utiliser la piste complète",
|
"LabelUseFullTrack": "Utiliser la piste complète",
|
||||||
"LabelUser": "Utilisateur",
|
"LabelUser": "Utilisateur",
|
||||||
"LabelUsername": "Nom d’utilisateur",
|
"LabelUsername": "Nom d’utilisateur",
|
||||||
"LabelValue": "Valeur",
|
"LabelValue": "Valeur",
|
||||||
|
"LabelVersion": "Version",
|
||||||
"LabelViewBookmarks": "Afficher les favoris",
|
"LabelViewBookmarks": "Afficher les favoris",
|
||||||
"LabelViewChapters": "Afficher les chapitres",
|
"LabelViewChapters": "Afficher les chapitres",
|
||||||
"LabelViewPlayerSettings": "Afficher les paramètres du lecteur",
|
"LabelViewPlayerSettings": "Afficher les paramètres du lecteur",
|
||||||
"LabelViewQueue": "Afficher la liste de lecture",
|
"LabelViewQueue": "Afficher la liste de lecture",
|
||||||
|
"LabelVolume": "Volume",
|
||||||
"LabelWeekdaysToRun": "Jours de la semaine à exécuter",
|
"LabelWeekdaysToRun": "Jours de la semaine à exécuter",
|
||||||
"LabelXBooks": "{0} livres",
|
"LabelXBooks": "{0} livres",
|
||||||
"LabelXItems": "{0} éléments",
|
"LabelXItems": "{0} éléments",
|
||||||
@@ -621,51 +676,53 @@
|
|||||||
"MessageChapterErrorStartLtPrev": "Horodatage invalide car il doit débuter au moins après le précédent chapitre",
|
"MessageChapterErrorStartLtPrev": "Horodatage invalide car il doit débuter au moins après le précédent chapitre",
|
||||||
"MessageChapterStartIsAfter": "Le premier chapitre est situé au début de votre livre audio",
|
"MessageChapterStartIsAfter": "Le premier chapitre est situé au début de votre livre audio",
|
||||||
"MessageCheckingCron": "Vérification du cron…",
|
"MessageCheckingCron": "Vérification du cron…",
|
||||||
"MessageConfirmCloseFeed": "Êtes-vous sûr de vouloir fermer ce flux ?",
|
"MessageConfirmCloseFeed": "Êtes-vous sûr·e de vouloir fermer ce flux ?",
|
||||||
"MessageConfirmDeleteBackup": "Êtes-vous sûr de vouloir supprimer la sauvegarde de « {0} » ?",
|
"MessageConfirmDeleteBackup": "Êtes-vous sûr·e de vouloir supprimer la sauvegarde de « {0} » ?",
|
||||||
"MessageConfirmDeleteDevice": "Êtes-vous sûr de vouloir supprimer la liseuse « {0} » ?",
|
"MessageConfirmDeleteDevice": "Êtes-vous sûr·e de vouloir supprimer la liseuse « {0} » ?",
|
||||||
"MessageConfirmDeleteFile": "Cela supprimera le fichier de votre système de fichiers. Êtes-vous sûr ?",
|
"MessageConfirmDeleteFile": "Cela supprimera le fichier de votre système de fichiers. Êtes-vous sûr ?",
|
||||||
"MessageConfirmDeleteLibrary": "Êtes-vous sûr de vouloir supprimer définitivement la bibliothèque « {0} » ?",
|
"MessageConfirmDeleteLibrary": "Êtes-vous sûr·e de vouloir supprimer définitivement la bibliothèque « {0} » ?",
|
||||||
"MessageConfirmDeleteLibraryItem": "Cette opération supprimera l’élément de la base de données et de votre système de fichiers. Êtes-vous sûr ?",
|
"MessageConfirmDeleteLibraryItem": "Cette opération supprimera l’élément de la base de données et de votre système de fichiers. Êtes-vous sûr ?",
|
||||||
"MessageConfirmDeleteLibraryItems": "Cette opération supprimera {0} éléments de la base de données et de votre système de fichiers. Êtes-vous sûr ?",
|
"MessageConfirmDeleteLibraryItems": "Cette opération supprimera {0} éléments de la base de données et de votre système de fichiers. Êtes-vous sûr ?",
|
||||||
"MessageConfirmDeleteMetadataProvider": "Êtes-vous sûr de vouloir supprimer le fournisseur de métadonnées personnalisées « {0} » ?",
|
"MessageConfirmDeleteMetadataProvider": "Êtes-vous sûr·e de vouloir supprimer le fournisseur de métadonnées personnalisées « {0} » ?",
|
||||||
"MessageConfirmDeleteNotification": "Êtes-vous sûr de vouloir supprimer cette notification ?",
|
"MessageConfirmDeleteNotification": "Êtes-vous sûr·e de vouloir supprimer cette notification ?",
|
||||||
"MessageConfirmDeleteSession": "Êtes-vous sûr de vouloir supprimer cette session ?",
|
"MessageConfirmDeleteSession": "Êtes-vous sûr·e de vouloir supprimer cette session ?",
|
||||||
"MessageConfirmForceReScan": "Êtes-vous sûr de vouloir lancer une analyse forcée ?",
|
"MessageConfirmEmbedMetadataInAudioFiles": "Souhaitez-vous vraiment intégrer des métadonnées dans {0} fichiers audio ?",
|
||||||
"MessageConfirmMarkAllEpisodesFinished": "Êtes-vous sûr de marquer tous les épisodes comme terminés ?",
|
"MessageConfirmForceReScan": "Êtes-vous sûr·e de vouloir lancer une analyse forcée ?",
|
||||||
"MessageConfirmMarkAllEpisodesNotFinished": "Êtes-vous sûr de vouloir marquer tous les épisodes comme non terminés ?",
|
"MessageConfirmMarkAllEpisodesFinished": "Êtes-vous sûr·e de marquer tous les épisodes comme terminés ?",
|
||||||
"MessageConfirmMarkItemFinished": "Êtes-vous sûr de vouloir marquer \"{0}\" comme terminé ?",
|
"MessageConfirmMarkAllEpisodesNotFinished": "Êtes-vous sûr·e de vouloir marquer tous les épisodes comme non terminés ?",
|
||||||
"MessageConfirmMarkItemNotFinished": "Êtes-vous sûr de vouloir marquer \"{0}\" comme non terminé ?",
|
"MessageConfirmMarkItemFinished": "Êtes-vous sûr·e de vouloir marquer {0} comme terminé ?",
|
||||||
"MessageConfirmMarkSeriesFinished": "Êtes-vous sûr de vouloir marquer tous les livres de cette série comme terminées ?",
|
"MessageConfirmMarkItemNotFinished": "Êtes-vous sûr·e de vouloir marquer {0} comme non terminé ?",
|
||||||
"MessageConfirmMarkSeriesNotFinished": "Êtes-vous sûr de vouloir marquer tous les livres de cette série comme non terminés ?",
|
"MessageConfirmMarkSeriesFinished": "Êtes-vous sûr·e de vouloir marquer tous les livres de cette série comme terminées ?",
|
||||||
|
"MessageConfirmMarkSeriesNotFinished": "Êtes-vous sûr·e de vouloir marquer tous les livres de cette série comme non terminés ?",
|
||||||
"MessageConfirmNotificationTestTrigger": "Déclencher cette notification avec des données de test ?",
|
"MessageConfirmNotificationTestTrigger": "Déclencher cette notification avec des données de test ?",
|
||||||
"MessageConfirmPurgeCache": "La purge du cache supprimera l’intégralité du répertoire à <code>/metadata/cache</code>.<br /><br />Êtes-vous sûr de vouloir supprimer le répertoire de cache ?",
|
"MessageConfirmPurgeCache": "La purge du cache supprimera l’intégralité du répertoire à <code>/metadata/cache</code>.<br /><br />Êtes-vous sûr·e de vouloir supprimer le répertoire de cache ?",
|
||||||
"MessageConfirmPurgeItemsCache": "Purger le cache des éléments supprimera l'ensemble du répertoire <code>/metadata/cache/items</code>.<br />Êtes-vous sûr ?",
|
"MessageConfirmPurgeItemsCache": "Purger le cache des éléments supprimera l'ensemble du répertoire <code>/metadata/cache/items</code>.<br />Êtes-vous sûr ?",
|
||||||
"MessageConfirmQuickEmbed": "Attention ! L'intégration rapide ne permet pas de sauvegarder vos fichiers audio. Assurez-vous d’avoir effectuer une sauvegarde de vos fichiers audio.<br><br>Souhaitez-vous continuer ?",
|
"MessageConfirmQuickEmbed": "Attention ! L'intégration rapide ne permet pas de sauvegarder vos fichiers audio. Assurez-vous d’avoir effectuer une sauvegarde de vos fichiers audio.<br><br>Souhaitez-vous continuer ?",
|
||||||
"MessageConfirmReScanLibraryItems": "Êtes-vous sûr de vouloir re-analyser {0} éléments ?",
|
"MessageConfirmReScanLibraryItems": "Êtes-vous sûr·e de vouloir réanalyser {0} éléments ?",
|
||||||
"MessageConfirmRemoveAllChapters": "Êtes-vous sûr de vouloir supprimer tous les chapitres ?",
|
"MessageConfirmRemoveAllChapters": "Êtes-vous sûr·e de vouloir supprimer tous les chapitres ?",
|
||||||
"MessageConfirmRemoveAuthor": "Êtes-vous sûr de vouloir supprimer l’auteur « {0} » ?",
|
"MessageConfirmRemoveAuthor": "Êtes-vous sûr·e de vouloir supprimer l’auteur « {0} » ?",
|
||||||
"MessageConfirmRemoveCollection": "Êtes-vous sûr de vouloir supprimer la collection « {0} » ?",
|
"MessageConfirmRemoveCollection": "Êtes-vous sûr·e de vouloir supprimer la collection « {0} » ?",
|
||||||
"MessageConfirmRemoveEpisode": "Êtes-vous sûr de vouloir supprimer l’épisode « {0} » ?",
|
"MessageConfirmRemoveEpisode": "Êtes-vous sûr·e de vouloir supprimer l’épisode « {0} » ?",
|
||||||
"MessageConfirmRemoveEpisodes": "Êtes-vous sûr de vouloir supprimer {0} épisodes ?",
|
"MessageConfirmRemoveEpisodes": "Êtes-vous sûr·e de vouloir supprimer {0} épisodes ?",
|
||||||
"MessageConfirmRemoveListeningSessions": "Êtes-vous sûr de vouloir supprimer {0} sessions d’écoute ?",
|
"MessageConfirmRemoveListeningSessions": "Êtes-vous sûr·e de vouloir supprimer {0} sessions d’écoute ?",
|
||||||
"MessageConfirmRemoveNarrator": "Êtes-vous sûr de vouloir supprimer le narrateur « {0} » ?",
|
"MessageConfirmRemoveNarrator": "Êtes-vous sûr·e de vouloir supprimer le narrateur « {0} » ?",
|
||||||
"MessageConfirmRemovePlaylist": "Êtes-vous sûr de vouloir supprimer la liste de lecture « {0} » ?",
|
"MessageConfirmRemovePlaylist": "Êtes-vous sûr·e de vouloir supprimer la liste de lecture « {0} » ?",
|
||||||
"MessageConfirmRenameGenre": "Êtes-vous sûr de vouloir renommer le genre « {0} » en « {1} » pour tous les éléments ?",
|
"MessageConfirmRenameGenre": "Êtes-vous sûr·e de vouloir renommer le genre « {0} » en « {1} » pour tous les éléments ?",
|
||||||
"MessageConfirmRenameGenreMergeNote": "Information : ce genre existe déjà et sera fusionné.",
|
"MessageConfirmRenameGenreMergeNote": "Information : ce genre existe déjà et sera fusionné.",
|
||||||
"MessageConfirmRenameGenreWarning": "Attention ! Un genre similaire avec une casse différente existe déjà « {0} ».",
|
"MessageConfirmRenameGenreWarning": "Attention ! Un genre similaire avec une casse différente existe déjà « {0} ».",
|
||||||
"MessageConfirmRenameTag": "Êtes-vous sûr de vouloir renommer l’étiquette « {0} » en « {1} » pour tous les éléments ?",
|
"MessageConfirmRenameTag": "Êtes-vous sûr·e de vouloir renommer l’étiquette « {0} » en « {1} » pour tous les éléments ?",
|
||||||
"MessageConfirmRenameTagMergeNote": "Information : Cette étiquette existe déjà et sera fusionnée.",
|
"MessageConfirmRenameTagMergeNote": "Information : Cette étiquette existe déjà et sera fusionnée.",
|
||||||
"MessageConfirmRenameTagWarning": "Attention ! Une étiquette similaire avec une casse différente existe déjà « {0} ».",
|
"MessageConfirmRenameTagWarning": "Attention ! Une étiquette similaire avec une casse différente existe déjà « {0} ».",
|
||||||
"MessageConfirmResetProgress": "Êtes-vous sûr de vouloir réinitialiser votre progression ?",
|
"MessageConfirmResetProgress": "Êtes-vous sûr·e de vouloir réinitialiser votre progression ?",
|
||||||
"MessageConfirmSendEbookToDevice": "Êtes-vous sûr de vouloir envoyer {0} livre numérique « {1} » à l'appareil « {2} » ?",
|
"MessageConfirmSendEbookToDevice": "Êtes-vous sûr·e de vouloir envoyer {0} livre numérique « {1} » à l'appareil « {2} » ?",
|
||||||
"MessageConfirmUnlinkOpenId": "Êtes-vous sûr de vouloir dissocier cet utilisateur d’OpenID ?",
|
"MessageConfirmUnlinkOpenId": "Êtes-vous sûr·e de vouloir dissocier cet utilisateur d’OpenID ?",
|
||||||
"MessageDownloadingEpisode": "Téléchargement de l’épisode",
|
"MessageDownloadingEpisode": "Téléchargement de l’épisode",
|
||||||
"MessageDragFilesIntoTrackOrder": "Faites glisser les fichiers dans l’ordre correct des pistes",
|
"MessageDragFilesIntoTrackOrder": "Faites glisser les fichiers dans l’ordre correct des pistes",
|
||||||
"MessageEmbedFailed": "Échec de l’intégration !",
|
"MessageEmbedFailed": "Échec de l’intégration !",
|
||||||
"MessageEmbedFinished": "Intégration terminée !",
|
"MessageEmbedFinished": "Intégration terminée !",
|
||||||
|
"MessageEmbedQueue": "En file d'attente pour l'intégration des métadonnées ({0} dans la file d'attente)",
|
||||||
"MessageEpisodesQueuedForDownload": "{0} épisode(s) mis en file pour téléchargement",
|
"MessageEpisodesQueuedForDownload": "{0} épisode(s) mis en file pour téléchargement",
|
||||||
"MessageEreaderDevices": "Pour garantir la livraison des livres électroniques, vous devrez peut-être ajouter le courriel ci-dessus comme expéditeur valide pour chaque appareil répertorié ci-dessous.",
|
"MessageEreaderDevices": "Pour garantir l’envoi des livres électroniques, vous devrez peut-être ajouter le courriel ci-dessus comme expéditeur valide pour chaque appareil répertorié ci-dessous.",
|
||||||
"MessageFeedURLWillBe": "L’URL du flux sera {0}",
|
"MessageFeedURLWillBe": "L’URL du flux sera {0}",
|
||||||
"MessageFetching": "Récupération…",
|
"MessageFetching": "Récupération…",
|
||||||
"MessageForceReScanDescription": "analysera de nouveau tous les fichiers. Les étiquettes ID3 des fichiers audio, les fichiers OPF et les fichiers texte seront analysés comme s’ils étaient nouveaux.",
|
"MessageForceReScanDescription": "analysera de nouveau tous les fichiers. Les étiquettes ID3 des fichiers audio, les fichiers OPF et les fichiers texte seront analysés comme s’ils étaient nouveaux.",
|
||||||
@@ -678,7 +735,7 @@
|
|||||||
"MessageLoading": "Chargement…",
|
"MessageLoading": "Chargement…",
|
||||||
"MessageLoadingFolders": "Chargement des dossiers…",
|
"MessageLoadingFolders": "Chargement des dossiers…",
|
||||||
"MessageLogsDescription": "Les journaux sont stockés dans <code>/metadata/logs</code> sous forme de fichiers JSON. Les journaux d’incidents sont stockés dans <code>/metadata/logs/crash_logs.txt</code>.",
|
"MessageLogsDescription": "Les journaux sont stockés dans <code>/metadata/logs</code> sous forme de fichiers JSON. Les journaux d’incidents sont stockés dans <code>/metadata/logs/crash_logs.txt</code>.",
|
||||||
"MessageM4BFailed": "M4B a échoué !",
|
"MessageM4BFailed": "Échec de la conversion en M4B !",
|
||||||
"MessageM4BFinished": "M4B terminé !",
|
"MessageM4BFinished": "M4B terminé !",
|
||||||
"MessageMapChapterTitles": "Faire correspondre les titres de chapitres avec ceux de vos livres audio existants sans ajuster les horodatages",
|
"MessageMapChapterTitles": "Faire correspondre les titres de chapitres avec ceux de vos livres audio existants sans ajuster les horodatages",
|
||||||
"MessageMarkAllEpisodesFinished": "Marquer tous les épisodes terminés",
|
"MessageMarkAllEpisodesFinished": "Marquer tous les épisodes terminés",
|
||||||
@@ -708,6 +765,7 @@
|
|||||||
"MessageNoLogs": "Aucun journaux",
|
"MessageNoLogs": "Aucun journaux",
|
||||||
"MessageNoMediaProgress": "Aucun média en cours",
|
"MessageNoMediaProgress": "Aucun média en cours",
|
||||||
"MessageNoNotifications": "Aucune notification",
|
"MessageNoNotifications": "Aucune notification",
|
||||||
|
"MessageNoPodcastFeed": "Podcast invalide : pas de flux",
|
||||||
"MessageNoPodcastsFound": "Aucun podcast trouvé",
|
"MessageNoPodcastsFound": "Aucun podcast trouvé",
|
||||||
"MessageNoResults": "Aucun résultat",
|
"MessageNoResults": "Aucun résultat",
|
||||||
"MessageNoSearchResultsFor": "Aucun résultat pour la recherche « {0} »",
|
"MessageNoSearchResultsFor": "Aucun résultat pour la recherche « {0} »",
|
||||||
@@ -724,14 +782,17 @@
|
|||||||
"MessagePlaylistCreateFromCollection": "Créer une liste de lecture depuis la collection",
|
"MessagePlaylistCreateFromCollection": "Créer une liste de lecture depuis la collection",
|
||||||
"MessagePleaseWait": "Merci de patienter…",
|
"MessagePleaseWait": "Merci de patienter…",
|
||||||
"MessagePodcastHasNoRSSFeedForMatching": "Le Podcast n’a pas d’URL de flux RSS à utiliser pour la correspondance",
|
"MessagePodcastHasNoRSSFeedForMatching": "Le Podcast n’a pas d’URL de flux RSS à utiliser pour la correspondance",
|
||||||
|
"MessagePodcastSearchField": "Saisissez le terme de recherche ou l'URL du flux RSS",
|
||||||
|
"MessageQuickEmbedInProgress": "Intégration rapide en cours",
|
||||||
|
"MessageQuickEmbedQueue": "En file d'attente pour une intégration rapide ({0} dans la file d'attente)",
|
||||||
"MessageQuickMatchDescription": "Renseigne les détails manquants ainsi que la couverture avec la première correspondance de « {0} ». N’écrase pas les données présentes à moins que le paramètre « Préférer les Métadonnées par correspondance » soit activé.",
|
"MessageQuickMatchDescription": "Renseigne les détails manquants ainsi que la couverture avec la première correspondance de « {0} ». N’écrase pas les données présentes à moins que le paramètre « Préférer les Métadonnées par correspondance » soit activé.",
|
||||||
"MessageRemoveChapter": "Supprimer le chapitre",
|
"MessageRemoveChapter": "Supprimer le chapitre",
|
||||||
"MessageRemoveEpisodes": "Suppression de {0} épisode(s)",
|
"MessageRemoveEpisodes": "Suppression de {0} épisode(s)",
|
||||||
"MessageRemoveFromPlayerQueue": "Supprimer de la liste d’écoute",
|
"MessageRemoveFromPlayerQueue": "Supprimer de la liste d’écoute",
|
||||||
"MessageRemoveUserWarning": "Êtes-vous sûr de vouloir supprimer définitivement l’utilisateur « {0} » ?",
|
"MessageRemoveUserWarning": "Êtes-vous sûr·e de vouloir supprimer définitivement l’utilisateur « {0} » ?",
|
||||||
"MessageReportBugsAndContribute": "Signalez des anomalies, demandez des fonctionnalités et contribuez sur",
|
"MessageReportBugsAndContribute": "Signalez des anomalies, demandez des fonctionnalités et contribuez sur",
|
||||||
"MessageResetChaptersConfirm": "Êtes-vous sûr de vouloir réinitialiser les chapitres et annuler les changements effectués ?",
|
"MessageResetChaptersConfirm": "Êtes-vous sûr·e de vouloir réinitialiser les chapitres et annuler les changements effectués ?",
|
||||||
"MessageRestoreBackupConfirm": "Êtes-vous sûr de vouloir restaurer la sauvegarde créée le",
|
"MessageRestoreBackupConfirm": "Êtes-vous sûr·e de vouloir restaurer la sauvegarde créée le",
|
||||||
"MessageRestoreBackupWarning": "Restaurer la sauvegarde écrasera la base de donnée située dans le dossier /config ainsi que les images sur /metadata/items et /metadata/authors.<br><br>Les sauvegardes ne touchent pas aux fichiers de la bibliothèque. Si vous avez activé le paramètre pour sauvegarder les métadonnées et les images de couverture dans le même dossier que les fichiers, ceux-ci ne ni sauvegardés, ni écrasés lors de la restauration.<br><br>Tous les clients utilisant votre serveur seront automatiquement mis à jour.",
|
"MessageRestoreBackupWarning": "Restaurer la sauvegarde écrasera la base de donnée située dans le dossier /config ainsi que les images sur /metadata/items et /metadata/authors.<br><br>Les sauvegardes ne touchent pas aux fichiers de la bibliothèque. Si vous avez activé le paramètre pour sauvegarder les métadonnées et les images de couverture dans le même dossier que les fichiers, ceux-ci ne ni sauvegardés, ni écrasés lors de la restauration.<br><br>Tous les clients utilisant votre serveur seront automatiquement mis à jour.",
|
||||||
"MessageSearchResultsFor": "Résultats de recherche pour",
|
"MessageSearchResultsFor": "Résultats de recherche pour",
|
||||||
"MessageSelected": "{0} sélectionnés",
|
"MessageSelected": "{0} sélectionnés",
|
||||||
@@ -741,6 +802,41 @@
|
|||||||
"MessageShareExpiresIn": "Expire dans {0}",
|
"MessageShareExpiresIn": "Expire dans {0}",
|
||||||
"MessageShareURLWillBe": "L’adresse de partage sera <strong>{0}</strong>",
|
"MessageShareURLWillBe": "L’adresse de partage sera <strong>{0}</strong>",
|
||||||
"MessageStartPlaybackAtTime": "Démarrer la lecture pour « {0} » à {1} ?",
|
"MessageStartPlaybackAtTime": "Démarrer la lecture pour « {0} » à {1} ?",
|
||||||
|
"MessageTaskAudioFileNotWritable": "Le fichier audio « {0} » n’est pas accessible en écriture",
|
||||||
|
"MessageTaskCanceledByUser": "Tâche annulée par l’utilisateur",
|
||||||
|
"MessageTaskDownloadingEpisodeDescription": "Téléchargement de l'épisode « {0} »",
|
||||||
|
"MessageTaskEmbeddingMetadata": "Intégration de métadonnées",
|
||||||
|
"MessageTaskEmbeddingMetadataDescription": "Intégration de métadonnées dans le livre audio « {0} »",
|
||||||
|
"MessageTaskEncodingM4b": "Encodage M4B",
|
||||||
|
"MessageTaskEncodingM4bDescription": "Encodage du livre audio « {0} » dans un seul fichier M4B",
|
||||||
|
"MessageTaskFailed": "Échec",
|
||||||
|
"MessageTaskFailedToBackupAudioFile": "Échec de la sauvegarde du fichier audio « {0} »",
|
||||||
|
"MessageTaskFailedToCreateCacheDirectory": "Échec de la création du répertoire de cache",
|
||||||
|
"MessageTaskFailedToEmbedMetadataInFile": "Échec de l'intégration des métadonnées dans le fichier « {0} »",
|
||||||
|
"MessageTaskFailedToMergeAudioFiles": "Échec de la fusion des fichiers audio",
|
||||||
|
"MessageTaskFailedToMoveM4bFile": "Échec du déplacement du fichier M4B",
|
||||||
|
"MessageTaskFailedToWriteMetadataFile": "Échec de l’écriture du fichier de métadonnées",
|
||||||
|
"MessageTaskMatchingBooksInLibrary": "Livres correspondants dans la bibliothèque « {0} »",
|
||||||
|
"MessageTaskNoFilesToScan": "Aucun fichier à analyser",
|
||||||
|
"MessageTaskOpmlImport": "Importation OPML",
|
||||||
|
"MessageTaskOpmlImportDescription": "Création de podcasts à partir de {0} flux RSS",
|
||||||
|
"MessageTaskOpmlImportFeed": "Flux d’importation OPML",
|
||||||
|
"MessageTaskOpmlImportFeedDescription": "Importation du flux RSS « {0} »",
|
||||||
|
"MessageTaskOpmlImportFeedFailed": "Échec de l’obtention du flux de podcast",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastDescription": "Création du podcast « {0} »",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastExists": "Le podcast existe déjà à cet emplacement",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastFailed": "Échec de la création du podcast",
|
||||||
|
"MessageTaskOpmlImportFinished": "Ajout de {0} podcasts",
|
||||||
|
"MessageTaskOpmlParseFailed": "Échec de l'analyse du fichier OPML",
|
||||||
|
"MessageTaskOpmlParseFastFail": "Balise <opml> de fichier OPML non valide introuvable OU une balise <outline> n’a pas été trouvée",
|
||||||
|
"MessageTaskOpmlParseNoneFound": "Aucun flux trouvé dans le fichier OPML",
|
||||||
|
"MessageTaskScanItemsAdded": "{0} ajouté",
|
||||||
|
"MessageTaskScanItemsMissing": "{0} manquant",
|
||||||
|
"MessageTaskScanItemsUpdated": "{0} mis à jour",
|
||||||
|
"MessageTaskScanNoChangesNeeded": "Aucun changement nécessaire",
|
||||||
|
"MessageTaskScanningFileChanges": "Analyse des modifications du fichier dans « {0} »",
|
||||||
|
"MessageTaskScanningLibrary": "Analyse de la bibliothèque « {0} »",
|
||||||
|
"MessageTaskTargetDirectoryNotWritable": "Le répertoire cible n’est pas accessible en écriture",
|
||||||
"MessageThinking": "Je cherche…",
|
"MessageThinking": "Je cherche…",
|
||||||
"MessageUploaderItemFailed": "Échec du téléversement",
|
"MessageUploaderItemFailed": "Échec du téléversement",
|
||||||
"MessageUploaderItemSuccess": "Téléversement effectué !",
|
"MessageUploaderItemSuccess": "Téléversement effectué !",
|
||||||
@@ -758,6 +854,10 @@
|
|||||||
"NoteUploaderFoldersWithMediaFiles": "Les dossiers contenant des fichiers multimédias seront traités comme des éléments distincts de la bibliothèque.",
|
"NoteUploaderFoldersWithMediaFiles": "Les dossiers contenant des fichiers multimédias seront traités comme des éléments distincts de la bibliothèque.",
|
||||||
"NoteUploaderOnlyAudioFiles": "Si vous téléversez uniquement des fichiers audio, chaque fichier audio sera traité comme un livre audio distinct.",
|
"NoteUploaderOnlyAudioFiles": "Si vous téléversez uniquement des fichiers audio, chaque fichier audio sera traité comme un livre audio distinct.",
|
||||||
"NoteUploaderUnsupportedFiles": "Les fichiers non pris en charge sont ignorés. Lorsque vous choisissez ou déposez un dossier, les autres fichiers qui ne sont pas dans un dossier d’élément sont ignorés.",
|
"NoteUploaderUnsupportedFiles": "Les fichiers non pris en charge sont ignorés. Lorsque vous choisissez ou déposez un dossier, les autres fichiers qui ne sont pas dans un dossier d’élément sont ignorés.",
|
||||||
|
"NotificationOnBackupCompletedDescription": "Déclenché lorsqu’une sauvegarde est terminée",
|
||||||
|
"NotificationOnBackupFailedDescription": "Déclenché lorsqu'une sauvegarde échoue",
|
||||||
|
"NotificationOnEpisodeDownloadedDescription": "Déclenché lorsqu’un épisode de podcast est téléchargé automatiquement",
|
||||||
|
"NotificationOnTestDescription": "Événement pour tester le système de notification",
|
||||||
"PlaceholderNewCollection": "Nom de la nouvelle collection",
|
"PlaceholderNewCollection": "Nom de la nouvelle collection",
|
||||||
"PlaceholderNewFolderPath": "Nouveau chemin de dossier",
|
"PlaceholderNewFolderPath": "Nouveau chemin de dossier",
|
||||||
"PlaceholderNewPlaylist": "Nouveau nom de liste de lecture",
|
"PlaceholderNewPlaylist": "Nouveau nom de liste de lecture",
|
||||||
@@ -770,22 +870,23 @@
|
|||||||
"StatsBooksFinishedThisYear": "Quelques livres terminés cette année…",
|
"StatsBooksFinishedThisYear": "Quelques livres terminés cette année…",
|
||||||
"StatsBooksListenedTo": "livres écoutés",
|
"StatsBooksListenedTo": "livres écoutés",
|
||||||
"StatsCollectionGrewTo": "Votre collection de livres a atteint…",
|
"StatsCollectionGrewTo": "Votre collection de livres a atteint…",
|
||||||
|
"StatsSessions": "sessions",
|
||||||
"StatsSpentListening": "temps passé à écouter",
|
"StatsSpentListening": "temps passé à écouter",
|
||||||
"StatsTopAuthor": "TOP AUTEUR",
|
"StatsTopAuthor": "TOP AUTEUR",
|
||||||
"StatsTopAuthors": "TOP AUTEURS",
|
"StatsTopAuthors": "TOP AUTEURS",
|
||||||
|
"StatsTopGenre": "TOP GENRE",
|
||||||
|
"StatsTopGenres": "TOP GENRES",
|
||||||
"StatsTopMonth": "TOP MOIS",
|
"StatsTopMonth": "TOP MOIS",
|
||||||
"StatsTopNarrator": "TOP NARRATEUR",
|
"StatsTopNarrator": "TOP NARRATEUR",
|
||||||
"StatsTopNarrators": "TOP NARRATEURS",
|
"StatsTopNarrators": "TOP NARRATEURS",
|
||||||
"StatsTotalDuration": "Pour une durée totale de…",
|
"StatsTotalDuration": "Pour une durée totale de…",
|
||||||
"StatsYearInReview": "BILAN DE L’ANNÉE",
|
"StatsYearInReview": "BILAN DE L’ANNÉE",
|
||||||
"ToastAccountUpdateFailed": "Échec de la mise à jour du compte",
|
|
||||||
"ToastAccountUpdateSuccess": "Compte mis à jour",
|
"ToastAccountUpdateSuccess": "Compte mis à jour",
|
||||||
"ToastAppriseUrlRequired": "Vous devez entrer une URL Apprise",
|
"ToastAppriseUrlRequired": "Vous devez entrer une URL Apprise",
|
||||||
"ToastAuthorImageRemoveSuccess": "Image de l’auteur supprimée",
|
"ToastAuthorImageRemoveSuccess": "Image de l’auteur supprimée",
|
||||||
"ToastAuthorNotFound": "Auteur \"{0}\" non trouvé",
|
"ToastAuthorNotFound": "Auteur \"{0}\" non trouvé",
|
||||||
"ToastAuthorRemoveSuccess": "Auteur supprimé",
|
"ToastAuthorRemoveSuccess": "Auteur supprimé",
|
||||||
"ToastAuthorSearchNotFound": "Auteur non trouvé",
|
"ToastAuthorSearchNotFound": "Auteur non trouvé",
|
||||||
"ToastAuthorUpdateFailed": "Échec de la mise à jour de l’auteur",
|
|
||||||
"ToastAuthorUpdateMerged": "Auteur fusionné",
|
"ToastAuthorUpdateMerged": "Auteur fusionné",
|
||||||
"ToastAuthorUpdateSuccess": "Auteur mis à jour",
|
"ToastAuthorUpdateSuccess": "Auteur mis à jour",
|
||||||
"ToastAuthorUpdateSuccessNoImageFound": "Auteur mis à jour (aucune image trouvée)",
|
"ToastAuthorUpdateSuccessNoImageFound": "Auteur mis à jour (aucune image trouvée)",
|
||||||
@@ -796,7 +897,6 @@
|
|||||||
"ToastBackupDeleteSuccess": "Sauvegarde supprimée",
|
"ToastBackupDeleteSuccess": "Sauvegarde supprimée",
|
||||||
"ToastBackupInvalidMaxKeep": "Nombre de sauvegardes à conserver invalide",
|
"ToastBackupInvalidMaxKeep": "Nombre de sauvegardes à conserver invalide",
|
||||||
"ToastBackupInvalidMaxSize": "Taille maximale de sauvegarde invalide",
|
"ToastBackupInvalidMaxSize": "Taille maximale de sauvegarde invalide",
|
||||||
"ToastBackupPathUpdateFailed": "Échec de la mise à jour du chemin de sauvegarde",
|
|
||||||
"ToastBackupRestoreFailed": "Échec de la restauration de sauvegarde",
|
"ToastBackupRestoreFailed": "Échec de la restauration de sauvegarde",
|
||||||
"ToastBackupUploadFailed": "Échec du téléversement de sauvegarde",
|
"ToastBackupUploadFailed": "Échec du téléversement de sauvegarde",
|
||||||
"ToastBackupUploadSuccess": "Sauvegarde téléversée",
|
"ToastBackupUploadSuccess": "Sauvegarde téléversée",
|
||||||
@@ -807,7 +907,6 @@
|
|||||||
"ToastBookmarkCreateFailed": "Échec de la création de signet",
|
"ToastBookmarkCreateFailed": "Échec de la création de signet",
|
||||||
"ToastBookmarkCreateSuccess": "Signet ajouté",
|
"ToastBookmarkCreateSuccess": "Signet ajouté",
|
||||||
"ToastBookmarkRemoveSuccess": "Signet supprimé",
|
"ToastBookmarkRemoveSuccess": "Signet supprimé",
|
||||||
"ToastBookmarkUpdateFailed": "Échec de la mise à jour de signet",
|
|
||||||
"ToastBookmarkUpdateSuccess": "Signet mis à jour",
|
"ToastBookmarkUpdateSuccess": "Signet mis à jour",
|
||||||
"ToastCachePurgeFailed": "Échec de la purge du cache",
|
"ToastCachePurgeFailed": "Échec de la purge du cache",
|
||||||
"ToastCachePurgeSuccess": "Cache purgé avec succès",
|
"ToastCachePurgeSuccess": "Cache purgé avec succès",
|
||||||
@@ -818,7 +917,6 @@
|
|||||||
"ToastCollectionItemsAddSuccess": "Ajout de(s) élément(s) à la collection réussi",
|
"ToastCollectionItemsAddSuccess": "Ajout de(s) élément(s) à la collection réussi",
|
||||||
"ToastCollectionItemsRemoveSuccess": "Élément(s) supprimé(s) de la collection",
|
"ToastCollectionItemsRemoveSuccess": "Élément(s) supprimé(s) de la collection",
|
||||||
"ToastCollectionRemoveSuccess": "Collection supprimée",
|
"ToastCollectionRemoveSuccess": "Collection supprimée",
|
||||||
"ToastCollectionUpdateFailed": "Échec de la mise à jour de la collection",
|
|
||||||
"ToastCollectionUpdateSuccess": "Collection mise à jour",
|
"ToastCollectionUpdateSuccess": "Collection mise à jour",
|
||||||
"ToastCoverUpdateFailed": "Échec de la mise à jour de la couverture",
|
"ToastCoverUpdateFailed": "Échec de la mise à jour de la couverture",
|
||||||
"ToastDeleteFileFailed": "Échec de la suppression du fichier",
|
"ToastDeleteFileFailed": "Échec de la suppression du fichier",
|
||||||
@@ -827,50 +925,101 @@
|
|||||||
"ToastDeviceNameAlreadyExists": "Un appareil de lecture avec ce nom existe déjà",
|
"ToastDeviceNameAlreadyExists": "Un appareil de lecture avec ce nom existe déjà",
|
||||||
"ToastDeviceTestEmailFailed": "Échec de l’envoi du courriel de test",
|
"ToastDeviceTestEmailFailed": "Échec de l’envoi du courriel de test",
|
||||||
"ToastDeviceTestEmailSuccess": "Courriel de test envoyé",
|
"ToastDeviceTestEmailSuccess": "Courriel de test envoyé",
|
||||||
"ToastEmailSettingsUpdateFailed": "Échec de la mise à jour des paramètres de messagerie",
|
"ToastEmailSettingsUpdateSuccess": "Paramètres de messagerie mis à jour",
|
||||||
|
"ToastEncodeCancelFailed": "Échec de l’annulation de l’encodage",
|
||||||
|
"ToastEncodeCancelSucces": "Encodage annulé",
|
||||||
|
"ToastEpisodeDownloadQueueClearFailed": "Échec de la suppression de la file d'attente",
|
||||||
|
"ToastEpisodeDownloadQueueClearSuccess": "File d’attente de téléchargement des épisodes effacée",
|
||||||
"ToastErrorCannotShare": "Impossible de partager nativement sur cet appareil",
|
"ToastErrorCannotShare": "Impossible de partager nativement sur cet appareil",
|
||||||
"ToastFailedToLoadData": "Échec du chargement des données",
|
"ToastFailedToLoadData": "Échec du chargement des données",
|
||||||
"ToastItemCoverUpdateFailed": "Échec de la mise à jour de la couverture de l’élément",
|
"ToastFailedToShare": "Échec du partage",
|
||||||
|
"ToastFailedToUpdate": "Échec de la mise à jour",
|
||||||
|
"ToastInvalidImageUrl": "URL de l'image invalide",
|
||||||
|
"ToastInvalidUrl": "URL invalide",
|
||||||
"ToastItemCoverUpdateSuccess": "Couverture mise à jour",
|
"ToastItemCoverUpdateSuccess": "Couverture mise à jour",
|
||||||
"ToastItemDetailsUpdateFailed": "Échec de la mise à jour des détails de l’élément",
|
"ToastItemDeletedFailed": "La suppression de l'élément à échouée",
|
||||||
|
"ToastItemDeletedSuccess": "Élément supprimé",
|
||||||
"ToastItemDetailsUpdateSuccess": "Détails de l’élément mis à jour",
|
"ToastItemDetailsUpdateSuccess": "Détails de l’élément mis à jour",
|
||||||
"ToastItemMarkedAsFinishedFailed": "Échec de l’annotation terminée",
|
"ToastItemMarkedAsFinishedFailed": "Échec de l’annotation terminée",
|
||||||
"ToastItemMarkedAsFinishedSuccess": "Article marqué comme terminé",
|
"ToastItemMarkedAsFinishedSuccess": "Article marqué comme terminé",
|
||||||
"ToastItemMarkedAsNotFinishedFailed": "Échec de l’annotation non-terminée",
|
"ToastItemMarkedAsNotFinishedFailed": "Échec de l’annotation non-terminée",
|
||||||
"ToastItemMarkedAsNotFinishedSuccess": "Article marqué comme non-terminé",
|
"ToastItemMarkedAsNotFinishedSuccess": "Article marqué comme non-terminé",
|
||||||
|
"ToastItemUpdateSuccess": "Élément mis a jour",
|
||||||
"ToastLibraryCreateFailed": "Échec de la création de bibliothèque",
|
"ToastLibraryCreateFailed": "Échec de la création de bibliothèque",
|
||||||
"ToastLibraryCreateSuccess": "Bibliothèque « {0} » créée",
|
"ToastLibraryCreateSuccess": "Bibliothèque « {0} » créée",
|
||||||
"ToastLibraryDeleteFailed": "Échec de la suppression de la bibliothèque",
|
"ToastLibraryDeleteFailed": "Échec de la suppression de la bibliothèque",
|
||||||
"ToastLibraryDeleteSuccess": "Bibliothèque supprimée",
|
"ToastLibraryDeleteSuccess": "Bibliothèque supprimée",
|
||||||
"ToastLibraryScanFailedToStart": "Échec du démarrage de l’analyse",
|
"ToastLibraryScanFailedToStart": "Échec du démarrage de l’analyse",
|
||||||
"ToastLibraryScanStarted": "Analyse de la bibliothèque démarrée",
|
"ToastLibraryScanStarted": "Analyse de la bibliothèque démarrée",
|
||||||
"ToastLibraryUpdateFailed": "Échec de la mise à jour de la bibliothèque",
|
|
||||||
"ToastLibraryUpdateSuccess": "Bibliothèque « {0} » mise à jour",
|
"ToastLibraryUpdateSuccess": "Bibliothèque « {0} » mise à jour",
|
||||||
|
"ToastMatchAllAuthorsFailed": "Tous les auteurs et autrices n’ont pas pu être classés",
|
||||||
|
"ToastNameEmailRequired": "Le nom et le courriel sont requis",
|
||||||
|
"ToastNameRequired": "Le nom est requis",
|
||||||
|
"ToastNewUserCreatedFailed": "La création du compte à échouée : « {0} »",
|
||||||
|
"ToastNewUserCreatedSuccess": "Nouveau compte créé",
|
||||||
|
"ToastNewUserLibraryError": "Au moins une bibliothèque est requise",
|
||||||
|
"ToastNewUserPasswordError": "Un mot de passe est requis, seul l’utilisateur root peut avoir un mot de passe vide",
|
||||||
|
"ToastNewUserTagError": "Au moins une étiquette est requise",
|
||||||
|
"ToastNewUserUsernameError": "Entrez un nom d’utilisateur",
|
||||||
|
"ToastNoUpdatesNecessary": "Aucune mise à jour nécessaire",
|
||||||
|
"ToastNotificationCreateFailed": "La création de la notification à échouée",
|
||||||
|
"ToastNotificationDeleteFailed": "La suppression de la notification à échouée",
|
||||||
|
"ToastNotificationFailedMaximum": "Le nombre maximum de tentatives échouées doit être >= 0",
|
||||||
|
"ToastNotificationQueueMaximum": "Le nombre de notification maximum doit être >= 0",
|
||||||
|
"ToastNotificationSettingsUpdateSuccess": "Paramètres de notification mis à jour",
|
||||||
|
"ToastNotificationTestTriggerFailed": "L'envoi de la notification de test à échoué",
|
||||||
|
"ToastNotificationTestTriggerSuccess": "Notification de test déclenchée",
|
||||||
|
"ToastNotificationUpdateSuccess": "Notification mise à jour",
|
||||||
"ToastPlaylistCreateFailed": "Échec de la création de la liste de lecture",
|
"ToastPlaylistCreateFailed": "Échec de la création de la liste de lecture",
|
||||||
"ToastPlaylistCreateSuccess": "Liste de lecture créée",
|
"ToastPlaylistCreateSuccess": "Liste de lecture créée",
|
||||||
"ToastPlaylistRemoveSuccess": "Liste de lecture supprimée",
|
"ToastPlaylistRemoveSuccess": "Liste de lecture supprimée",
|
||||||
"ToastPlaylistUpdateFailed": "Échec de la mise à jour de la liste de lecture",
|
|
||||||
"ToastPlaylistUpdateSuccess": "Liste de lecture mise à jour",
|
"ToastPlaylistUpdateSuccess": "Liste de lecture mise à jour",
|
||||||
"ToastPodcastCreateFailed": "Échec de la création du podcast",
|
"ToastPodcastCreateFailed": "Échec de la création du podcast",
|
||||||
"ToastPodcastCreateSuccess": "Podcast créé avec succès",
|
"ToastPodcastCreateSuccess": "Podcast créé avec succès",
|
||||||
|
"ToastPodcastGetFeedFailed": "Échec de la récupération du flux du podcast",
|
||||||
|
"ToastPodcastNoEpisodesInFeed": "Aucun épisode trouvé dans le flux RSS",
|
||||||
|
"ToastPodcastNoRssFeed": "Le podcast n’a pas de flux RSS",
|
||||||
|
"ToastProviderCreatedFailed": "Échec de l’ajout du fournisseur",
|
||||||
|
"ToastProviderCreatedSuccess": "Nouveau fournisseur ajouté",
|
||||||
|
"ToastProviderNameAndUrlRequired": "Nom et URL requis",
|
||||||
|
"ToastProviderRemoveSuccess": "Fournisseur supprimé",
|
||||||
"ToastRSSFeedCloseFailed": "Échec de la fermeture du flux RSS",
|
"ToastRSSFeedCloseFailed": "Échec de la fermeture du flux RSS",
|
||||||
"ToastRSSFeedCloseSuccess": "Flux RSS fermé",
|
"ToastRSSFeedCloseSuccess": "Flux RSS fermé",
|
||||||
|
"ToastRemoveFailed": "Échec de la suppression",
|
||||||
"ToastRemoveItemFromCollectionFailed": "Échec de la suppression d’un élément de la collection",
|
"ToastRemoveItemFromCollectionFailed": "Échec de la suppression d’un élément de la collection",
|
||||||
"ToastRemoveItemFromCollectionSuccess": "Élément supprimé de la collection",
|
"ToastRemoveItemFromCollectionSuccess": "Élément supprimé de la collection",
|
||||||
|
"ToastRemoveItemsWithIssuesFailed": "Échec de la suppression des éléments de bibliothèque présentant des problèmes",
|
||||||
|
"ToastRemoveItemsWithIssuesSuccess": "Éléments de bibliothèque supprimés avec des problèmes",
|
||||||
|
"ToastRenameFailed": "Échec du renommage",
|
||||||
|
"ToastRescanFailed": "Échec de la nouvelle analyse pour {0}",
|
||||||
|
"ToastRescanRemoved": "Nouvelle analyse terminée, l’élément a été supprimé",
|
||||||
|
"ToastRescanUpToDate": "Nouvelle analyse terminée, l’élément était déjà à jour",
|
||||||
|
"ToastRescanUpdated": "Nouvelle analyse terminée, l’élément a été mis à jour",
|
||||||
|
"ToastScanFailed": "Échec de l’analyse de l’élément de la bibliothèque",
|
||||||
|
"ToastSelectAtLeastOneUser": "Sélectionnez au moins un utilisateur",
|
||||||
"ToastSendEbookToDeviceFailed": "Échec de l’envoi du livre numérique à l’appareil",
|
"ToastSendEbookToDeviceFailed": "Échec de l’envoi du livre numérique à l’appareil",
|
||||||
"ToastSendEbookToDeviceSuccess": "Livre numérique envoyé à l’appareil : {0}",
|
"ToastSendEbookToDeviceSuccess": "Livre numérique envoyé à l’appareil : {0}",
|
||||||
"ToastSeriesUpdateFailed": "Échec de la mise à jour de la série",
|
"ToastSeriesUpdateFailed": "Échec de la mise à jour de la série",
|
||||||
"ToastSeriesUpdateSuccess": "Mise à jour de la série réussie",
|
"ToastSeriesUpdateSuccess": "Mise à jour de la série réussie",
|
||||||
"ToastServerSettingsUpdateFailed": "Échec de la mise à jour des paramètres du serveur",
|
|
||||||
"ToastServerSettingsUpdateSuccess": "Mise à jour des paramètres du serveur",
|
"ToastServerSettingsUpdateSuccess": "Mise à jour des paramètres du serveur",
|
||||||
|
"ToastSessionCloseFailed": "Échec de la fermeture de la session",
|
||||||
"ToastSessionDeleteFailed": "Échec de la suppression de session",
|
"ToastSessionDeleteFailed": "Échec de la suppression de session",
|
||||||
"ToastSessionDeleteSuccess": "Session supprimée",
|
"ToastSessionDeleteSuccess": "Session supprimée",
|
||||||
|
"ToastSlugMustChange": "L’identifiant d’URL contient des caractères invalides",
|
||||||
|
"ToastSlugRequired": "L’identifiant d’URL est requis",
|
||||||
"ToastSocketConnected": "WebSocket connecté",
|
"ToastSocketConnected": "WebSocket connecté",
|
||||||
"ToastSocketDisconnected": "WebSocket déconnecté",
|
"ToastSocketDisconnected": "WebSocket déconnecté",
|
||||||
"ToastSocketFailedToConnect": "Échec de la connexion WebSocket",
|
"ToastSocketFailedToConnect": "Échec de la connexion WebSocket",
|
||||||
"ToastSortingPrefixesEmptyError": "Doit avoir au moins 1 préfixe de tri",
|
"ToastSortingPrefixesEmptyError": "Doit avoir au moins 1 préfixe de tri",
|
||||||
"ToastSortingPrefixesUpdateFailed": "Échec de la mise à jour des préfixes de tri",
|
|
||||||
"ToastSortingPrefixesUpdateSuccess": "Mise à jour des préfixes de tri ({0} élément)",
|
"ToastSortingPrefixesUpdateSuccess": "Mise à jour des préfixes de tri ({0} élément)",
|
||||||
|
"ToastTitleRequired": "Le titre est requis",
|
||||||
|
"ToastUnknownError": "Erreur inconnue",
|
||||||
|
"ToastUnlinkOpenIdFailed": "Échec de la dissociation de l’utilisateur l’OpenID",
|
||||||
|
"ToastUnlinkOpenIdSuccess": "Utilisateur dissocié de OpenID",
|
||||||
"ToastUserDeleteFailed": "Échec de la suppression de l’utilisateur",
|
"ToastUserDeleteFailed": "Échec de la suppression de l’utilisateur",
|
||||||
"ToastUserDeleteSuccess": "Utilisateur supprimé"
|
"ToastUserDeleteSuccess": "Utilisateur supprimé",
|
||||||
|
"ToastUserPasswordChangeSuccess": "Mot de passe modifié avec succès",
|
||||||
|
"ToastUserPasswordMismatch": "Les mots de passe ne correspondent pas",
|
||||||
|
"ToastUserPasswordMustChange": "Le nouveau mot de passe ne peut pas être identique à l’ancien",
|
||||||
|
"ToastUserRootRequireName": "Vous devez entrer un nom d’utilisateur root"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
"ButtonCheckAndDownloadNewEpisodes": "નવા એપિસોડ્સ ચેક કરો અને ડાઉનલોડ કરો",
|
"ButtonCheckAndDownloadNewEpisodes": "નવા એપિસોડ્સ ચેક કરો અને ડાઉનલોડ કરો",
|
||||||
"ButtonChooseAFolder": "ફોલ્ડર પસંદ કરો",
|
"ButtonChooseAFolder": "ફોલ્ડર પસંદ કરો",
|
||||||
"ButtonChooseFiles": "ફાઇલો પસંદ કરો",
|
"ButtonChooseFiles": "ફાઇલો પસંદ કરો",
|
||||||
"ButtonClearFilter": "ફિલ્ટર જતુ કરો ",
|
"ButtonClearFilter": "ફિલ્ટર જતુ કરો",
|
||||||
"ButtonCloseFeed": "ફીડ બંધ કરો",
|
"ButtonCloseFeed": "ફીડ બંધ કરો",
|
||||||
"ButtonCollections": "સંગ્રહ",
|
"ButtonCollections": "સંગ્રહ",
|
||||||
"ButtonConfigureScanner": "સ્કેનર સેટિંગ બદલો",
|
"ButtonConfigureScanner": "સ્કેનર સેટિંગ બદલો",
|
||||||
|
|||||||
@@ -701,10 +701,8 @@
|
|||||||
"PlaceholderNewPlaylist": "שם רשימת השמעה חדשה",
|
"PlaceholderNewPlaylist": "שם רשימת השמעה חדשה",
|
||||||
"PlaceholderSearch": "חיפוש..",
|
"PlaceholderSearch": "חיפוש..",
|
||||||
"PlaceholderSearchEpisode": "חיפוש פרק..",
|
"PlaceholderSearchEpisode": "חיפוש פרק..",
|
||||||
"ToastAccountUpdateFailed": "עדכון חשבון נכשל",
|
|
||||||
"ToastAccountUpdateSuccess": "חשבון עודכן בהצלחה",
|
"ToastAccountUpdateSuccess": "חשבון עודכן בהצלחה",
|
||||||
"ToastAuthorImageRemoveSuccess": "תמונת המחבר הוסרה בהצלחה",
|
"ToastAuthorImageRemoveSuccess": "תמונת המחבר הוסרה בהצלחה",
|
||||||
"ToastAuthorUpdateFailed": "עדכון המחבר נכשל",
|
|
||||||
"ToastAuthorUpdateMerged": "המחבר מוזג",
|
"ToastAuthorUpdateMerged": "המחבר מוזג",
|
||||||
"ToastAuthorUpdateSuccess": "המחבר עודכן בהצלחה",
|
"ToastAuthorUpdateSuccess": "המחבר עודכן בהצלחה",
|
||||||
"ToastAuthorUpdateSuccessNoImageFound": "המחבר עודכן (תמונה לא נמצאה)",
|
"ToastAuthorUpdateSuccessNoImageFound": "המחבר עודכן (תמונה לא נמצאה)",
|
||||||
@@ -720,17 +718,13 @@
|
|||||||
"ToastBookmarkCreateFailed": "יצירת סימניה נכשלה",
|
"ToastBookmarkCreateFailed": "יצירת סימניה נכשלה",
|
||||||
"ToastBookmarkCreateSuccess": "הסימניה נוספה בהצלחה",
|
"ToastBookmarkCreateSuccess": "הסימניה נוספה בהצלחה",
|
||||||
"ToastBookmarkRemoveSuccess": "הסימניה הוסרה בהצלחה",
|
"ToastBookmarkRemoveSuccess": "הסימניה הוסרה בהצלחה",
|
||||||
"ToastBookmarkUpdateFailed": "עדכון הסימניה נכשל",
|
|
||||||
"ToastBookmarkUpdateSuccess": "הסימניה עודכנה בהצלחה",
|
"ToastBookmarkUpdateSuccess": "הסימניה עודכנה בהצלחה",
|
||||||
"ToastChaptersHaveErrors": "פרקים מכילים שגיאות",
|
"ToastChaptersHaveErrors": "פרקים מכילים שגיאות",
|
||||||
"ToastChaptersMustHaveTitles": "פרקים חייבים לכלול כותרות",
|
"ToastChaptersMustHaveTitles": "פרקים חייבים לכלול כותרות",
|
||||||
"ToastCollectionItemsRemoveSuccess": "הפריט(ים) הוסרו מהאוסף בהצלחה",
|
"ToastCollectionItemsRemoveSuccess": "הפריט(ים) הוסרו מהאוסף בהצלחה",
|
||||||
"ToastCollectionRemoveSuccess": "האוסף הוסר בהצלחה",
|
"ToastCollectionRemoveSuccess": "האוסף הוסר בהצלחה",
|
||||||
"ToastCollectionUpdateFailed": "עדכון האוסף נכשל",
|
|
||||||
"ToastCollectionUpdateSuccess": "האוסף עודכן בהצלחה",
|
"ToastCollectionUpdateSuccess": "האוסף עודכן בהצלחה",
|
||||||
"ToastItemCoverUpdateFailed": "עדכון כריכת הפריט נכשל",
|
|
||||||
"ToastItemCoverUpdateSuccess": "כריכת הפריט עודכנה בהצלחה",
|
"ToastItemCoverUpdateSuccess": "כריכת הפריט עודכנה בהצלחה",
|
||||||
"ToastItemDetailsUpdateFailed": "עדכון פרטי הפריט נכשל",
|
|
||||||
"ToastItemDetailsUpdateSuccess": "פרטי הפריט עודכנו בהצלחה",
|
"ToastItemDetailsUpdateSuccess": "פרטי הפריט עודכנו בהצלחה",
|
||||||
"ToastItemMarkedAsFinishedFailed": "סימון כפריט כהושלם נכשל",
|
"ToastItemMarkedAsFinishedFailed": "סימון כפריט כהושלם נכשל",
|
||||||
"ToastItemMarkedAsFinishedSuccess": "הפריט סומן כהושלם בהצלחה",
|
"ToastItemMarkedAsFinishedSuccess": "הפריט סומן כהושלם בהצלחה",
|
||||||
@@ -742,12 +736,10 @@
|
|||||||
"ToastLibraryDeleteSuccess": "הספרייה נמחקה בהצלחה",
|
"ToastLibraryDeleteSuccess": "הספרייה נמחקה בהצלחה",
|
||||||
"ToastLibraryScanFailedToStart": "הפעלת הסריקה נכשלה",
|
"ToastLibraryScanFailedToStart": "הפעלת הסריקה נכשלה",
|
||||||
"ToastLibraryScanStarted": "הסריקה של הספרייה החלה",
|
"ToastLibraryScanStarted": "הסריקה של הספרייה החלה",
|
||||||
"ToastLibraryUpdateFailed": "עדכון הספרייה נכשל",
|
|
||||||
"ToastLibraryUpdateSuccess": "הספרייה \"{0}\" עודכנה בהצלחה",
|
"ToastLibraryUpdateSuccess": "הספרייה \"{0}\" עודכנה בהצלחה",
|
||||||
"ToastPlaylistCreateFailed": "יצירת רשימת השמעה נכשלה",
|
"ToastPlaylistCreateFailed": "יצירת רשימת השמעה נכשלה",
|
||||||
"ToastPlaylistCreateSuccess": "רשימת השמעה נוצרה בהצלחה",
|
"ToastPlaylistCreateSuccess": "רשימת השמעה נוצרה בהצלחה",
|
||||||
"ToastPlaylistRemoveSuccess": "רשימת השמעה הוסרה בהצלחה",
|
"ToastPlaylistRemoveSuccess": "רשימת השמעה הוסרה בהצלחה",
|
||||||
"ToastPlaylistUpdateFailed": "עדכון רשימת השמעה נכשל",
|
|
||||||
"ToastPlaylistUpdateSuccess": "רשימת השמעה עודכנה בהצלחה",
|
"ToastPlaylistUpdateSuccess": "רשימת השמעה עודכנה בהצלחה",
|
||||||
"ToastPodcastCreateFailed": "יצירת הפודקאסט נכשלה",
|
"ToastPodcastCreateFailed": "יצירת הפודקאסט נכשלה",
|
||||||
"ToastPodcastCreateSuccess": "הפודקאסט נוצר בהצלחה",
|
"ToastPodcastCreateSuccess": "הפודקאסט נוצר בהצלחה",
|
||||||
@@ -759,7 +751,6 @@
|
|||||||
"ToastSendEbookToDeviceSuccess": "הספר נשלח אל המכשיר \"{0}\"",
|
"ToastSendEbookToDeviceSuccess": "הספר נשלח אל המכשיר \"{0}\"",
|
||||||
"ToastSeriesUpdateFailed": "עדכון הסדרה נכשל",
|
"ToastSeriesUpdateFailed": "עדכון הסדרה נכשל",
|
||||||
"ToastSeriesUpdateSuccess": "הסדרה עודכנה בהצלחה",
|
"ToastSeriesUpdateSuccess": "הסדרה עודכנה בהצלחה",
|
||||||
"ToastServerSettingsUpdateFailed": "כשל בעדכון הגדרות שרת",
|
|
||||||
"ToastServerSettingsUpdateSuccess": "הגדרות שרת עודכנו בהצלחה",
|
"ToastServerSettingsUpdateSuccess": "הגדרות שרת עודכנו בהצלחה",
|
||||||
"ToastSessionDeleteFailed": "מחיקת הפעולה נכשלה",
|
"ToastSessionDeleteFailed": "מחיקת הפעולה נכשלה",
|
||||||
"ToastSessionDeleteSuccess": "הפעולה נמחקה בהצלחה",
|
"ToastSessionDeleteSuccess": "הפעולה נמחקה בהצלחה",
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user