mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-12-18 01:39:38 +00:00
Add:Audiobooks only library settings, supplementary ebooks #1664
This commit is contained in:
parent
4b4fb33d8f
commit
014fc45c15
39 changed files with 624 additions and 122 deletions
|
|
@ -921,7 +921,7 @@ export default {
|
|||
return null
|
||||
})
|
||||
if (!libraryItem) return
|
||||
this.store.commit('showEReader', libraryItem)
|
||||
this.store.commit('showEReader', { libraryItem, keepProgress: true })
|
||||
},
|
||||
selectBtnClick(evt) {
|
||||
if (this.processingBatch) return
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="w-full h-full px-1 md:px-4 py-1 mb-4">
|
||||
<div class="flex items-center py-2">
|
||||
<div class="flex items-center py-3">
|
||||
<ui-toggle-switch v-model="useSquareBookCovers" @input="formUpdated" />
|
||||
<ui-tooltip :text="$strings.LabelSettingsSquareBookCoversHelp">
|
||||
<p class="pl-4 text-base">
|
||||
|
|
@ -17,13 +17,22 @@
|
|||
</div>
|
||||
<p v-if="globalWatcherDisabled" class="text-xs text-warning">*{{ $strings.MessageWatcherIsDisabledGlobally }}</p>
|
||||
</div>
|
||||
<div v-if="mediaType == 'book'" class="py-3">
|
||||
<div v-if="isBookLibrary" class="flex items-center py-3">
|
||||
<ui-toggle-switch v-model="audiobooksOnly" @input="formUpdated" />
|
||||
<ui-tooltip :text="$strings.LabelSettingsAudiobooksOnlyHelp">
|
||||
<p class="pl-4 text-base">
|
||||
{{ $strings.LabelSettingsAudiobooksOnly }}
|
||||
<span class="material-icons icon-text text-sm">info_outlined</span>
|
||||
</p>
|
||||
</ui-tooltip>
|
||||
</div>
|
||||
<div v-if="isBookLibrary" class="py-3">
|
||||
<div class="flex items-center">
|
||||
<ui-toggle-switch v-model="skipMatchingMediaWithAsin" @input="formUpdated" />
|
||||
<p class="pl-4 text-base">{{ $strings.LabelSettingsSkipMatchingBooksWithASIN }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="mediaType == 'book'" class="py-3">
|
||||
<div v-if="isBookLibrary" class="py-3">
|
||||
<div class="flex items-center">
|
||||
<ui-toggle-switch v-model="skipMatchingMediaWithIsbn" @input="formUpdated" />
|
||||
<p class="pl-4 text-base">{{ $strings.LabelSettingsSkipMatchingBooksWithISBN }}</p>
|
||||
|
|
@ -47,7 +56,8 @@ export default {
|
|||
useSquareBookCovers: false,
|
||||
disableWatcher: false,
|
||||
skipMatchingMediaWithAsin: false,
|
||||
skipMatchingMediaWithIsbn: false
|
||||
skipMatchingMediaWithIsbn: false,
|
||||
audiobooksOnly: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -60,6 +70,9 @@ export default {
|
|||
mediaType() {
|
||||
return this.library.mediaType
|
||||
},
|
||||
isBookLibrary() {
|
||||
return this.mediaType === 'book'
|
||||
},
|
||||
providers() {
|
||||
if (this.mediaType === 'podcast') return this.$store.state.scanners.podcastProviders
|
||||
return this.$store.state.scanners.providers
|
||||
|
|
@ -72,7 +85,8 @@ export default {
|
|||
coverAspectRatio: this.useSquareBookCovers ? this.$constants.BookCoverAspectRatio.SQUARE : this.$constants.BookCoverAspectRatio.STANDARD,
|
||||
disableWatcher: !!this.disableWatcher,
|
||||
skipMatchingMediaWithAsin: !!this.skipMatchingMediaWithAsin,
|
||||
skipMatchingMediaWithIsbn: !!this.skipMatchingMediaWithIsbn
|
||||
skipMatchingMediaWithIsbn: !!this.skipMatchingMediaWithIsbn,
|
||||
audiobooksOnly: !!this.audiobooksOnly
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -84,6 +98,7 @@ export default {
|
|||
this.disableWatcher = !!this.librarySettings.disableWatcher
|
||||
this.skipMatchingMediaWithAsin = !!this.librarySettings.skipMatchingMediaWithAsin
|
||||
this.skipMatchingMediaWithIsbn = !!this.librarySettings.skipMatchingMediaWithIsbn
|
||||
this.audiobooksOnly = !!this.librarySettings.audiobooksOnly
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
|
|
|||
|
|
@ -64,7 +64,9 @@ export default {
|
|||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
playerOpen: Boolean
|
||||
playerOpen: Boolean,
|
||||
keepProgress: Boolean,
|
||||
fileId: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -98,6 +100,9 @@ export default {
|
|||
return this.libraryItem?.id
|
||||
},
|
||||
ebookUrl() {
|
||||
if (this.fileId) {
|
||||
return `/api/items/${this.libraryItemId}/ebook/${this.fileId}`
|
||||
}
|
||||
return `/api/items/${this.libraryItemId}/ebook`
|
||||
},
|
||||
comicMetadataKeys() {
|
||||
|
|
@ -114,6 +119,8 @@ export default {
|
|||
return this.$store.getters['user/getUserMediaProgress'](this.libraryItemId)
|
||||
},
|
||||
savedPage() {
|
||||
if (!this.keepProgress) return 0
|
||||
|
||||
// Validate ebookLocation is a number
|
||||
if (!this.userMediaProgress?.ebookLocation || isNaN(this.userMediaProgress.ebookLocation)) return 0
|
||||
return Number(this.userMediaProgress.ebookLocation)
|
||||
|
|
@ -141,6 +148,8 @@ export default {
|
|||
this.showInfoMenu = !this.showInfoMenu
|
||||
},
|
||||
updateProgress() {
|
||||
if (!this.keepProgress) return
|
||||
|
||||
if (!this.numPages) {
|
||||
console.error('Num pages not loaded')
|
||||
return
|
||||
|
|
|
|||
|
|
@ -28,7 +28,9 @@ export default {
|
|||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
playerOpen: Boolean
|
||||
playerOpen: Boolean,
|
||||
keepProgress: Boolean,
|
||||
fileId: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -68,6 +70,7 @@ export default {
|
|||
return this.$store.getters['user/getUserMediaProgress'](this.libraryItemId)
|
||||
},
|
||||
savedEbookLocation() {
|
||||
if (!this.keepProgress) return null
|
||||
if (!this.userMediaProgress?.ebookLocation) return null
|
||||
// Validate ebookLocation is an epubcfi
|
||||
if (!String(this.userMediaProgress.ebookLocation).startsWith('epubcfi')) return null
|
||||
|
|
@ -84,7 +87,10 @@ export default {
|
|||
if (this.windowHeight < 400 || !this.playerOpen) return this.windowHeight
|
||||
return this.windowHeight - 164
|
||||
},
|
||||
epubUrl() {
|
||||
ebookUrl() {
|
||||
if (this.fileId) {
|
||||
return `/api/items/${this.libraryItemId}/ebook/${this.fileId}`
|
||||
}
|
||||
return `/api/items/${this.libraryItemId}/ebook`
|
||||
}
|
||||
},
|
||||
|
|
@ -112,6 +118,7 @@ export default {
|
|||
* @param {string} payload.ebookProgress - eBook Progress Percentage
|
||||
*/
|
||||
updateProgress(payload) {
|
||||
if (!this.keepProgress) return
|
||||
this.$axios.$patch(`/api/me/progress/${this.libraryItemId}`, payload).catch((error) => {
|
||||
console.error('EpubReader.updateProgress failed:', error)
|
||||
})
|
||||
|
|
@ -223,7 +230,7 @@ export default {
|
|||
const reader = this
|
||||
|
||||
/** @type {ePub.Book} */
|
||||
reader.book = new ePub(reader.epubUrl, {
|
||||
reader.book = new ePub(reader.ebookUrl, {
|
||||
width: this.readerWidth,
|
||||
height: this.readerHeight - 50,
|
||||
openAs: 'epub',
|
||||
|
|
@ -242,7 +249,7 @@ export default {
|
|||
reader.rendition.display(this.savedEbookLocation || reader.book.locations.start)
|
||||
|
||||
// load style
|
||||
reader.rendition.themes.default({ '*': { color: '#fff!important', 'background-color': 'rgb(35 35 35)!important' } })
|
||||
reader.rendition.themes.default({ '*': { color: '#fff!important', 'background-color': 'rgb(35 35 35)!important' }, a: { color: '#fff!important' } })
|
||||
|
||||
reader.book.ready.then(() => {
|
||||
// set up event listeners
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ export default {
|
|||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
playerOpen: Boolean
|
||||
playerOpen: Boolean,
|
||||
fileId: String
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
|
|
@ -32,6 +33,9 @@ export default {
|
|||
return this.libraryItem?.id
|
||||
},
|
||||
ebookUrl() {
|
||||
if (this.fileId) {
|
||||
return `/api/items/${this.libraryItemId}/ebook/${this.fileId}`
|
||||
}
|
||||
return `/api/items/${this.libraryItemId}/ebook`
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -45,7 +45,9 @@ export default {
|
|||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
playerOpen: Boolean
|
||||
playerOpen: Boolean,
|
||||
keepProgress: Boolean,
|
||||
fileId: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -95,13 +97,21 @@ export default {
|
|||
return this.$store.getters['user/getUserMediaProgress'](this.libraryItemId)
|
||||
},
|
||||
savedPage() {
|
||||
if (!this.keepProgress) return 0
|
||||
|
||||
// Validate ebookLocation is a number
|
||||
if (!this.userMediaProgress?.ebookLocation || isNaN(this.userMediaProgress.ebookLocation)) return 0
|
||||
return Number(this.userMediaProgress.ebookLocation)
|
||||
},
|
||||
ebookUrl() {
|
||||
if (this.fileId) {
|
||||
return `/api/items/${this.libraryItemId}/ebook/${this.fileId}`
|
||||
}
|
||||
return `/api/items/${this.libraryItemId}/ebook`
|
||||
},
|
||||
pdfDocInitParams() {
|
||||
return {
|
||||
url: `/api/items/${this.libraryItemId}/ebook`,
|
||||
url: this.ebookUrl,
|
||||
httpHeaders: {
|
||||
Authorization: `Bearer ${this.userToken}`
|
||||
}
|
||||
|
|
@ -116,6 +126,7 @@ export default {
|
|||
this.scale -= 0.1
|
||||
},
|
||||
updateProgress() {
|
||||
if (!this.keepProgress) return
|
||||
if (!this.numPages) {
|
||||
console.error('Num pages not loaded')
|
||||
return
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
<span class="material-icons cursor-pointer text-2xl" @click="close">close</span>
|
||||
</div>
|
||||
|
||||
<component v-if="componentName" ref="readerComponent" :is="componentName" :library-item="selectedLibraryItem" :player-open="!!streamLibraryItem" />
|
||||
<component v-if="componentName" ref="readerComponent" :is="componentName" :library-item="selectedLibraryItem" :player-open="!!streamLibraryItem" :keep-progress="keepProgress" :file-id="ebookFileId" />
|
||||
|
||||
<!-- TOC side nav -->
|
||||
<div v-if="tocOpen" class="w-full h-full fixed inset-0 bg-black/20 z-20" @click.stop.prevent="toggleToC"></div>
|
||||
|
|
@ -103,10 +103,18 @@ export default {
|
|||
return this.selectedLibraryItem.folderId
|
||||
},
|
||||
ebookFile() {
|
||||
// ebook file id is passed when reading a supplementary ebook
|
||||
if (this.ebookFileId) {
|
||||
return this.selectedLibraryItem.libraryFiles.find((lf) => lf.ino === this.ebookFileId)
|
||||
}
|
||||
return this.media.ebookFile
|
||||
},
|
||||
ebookFormat() {
|
||||
if (!this.ebookFile) return null
|
||||
// Use file extension for supplementary ebook
|
||||
if (!this.ebookFile.ebookFormat) {
|
||||
return this.ebookFile.metadata.ext.toLowerCase().slice(1)
|
||||
}
|
||||
return this.ebookFile.ebookFormat
|
||||
},
|
||||
ebookType() {
|
||||
|
|
@ -130,6 +138,12 @@ export default {
|
|||
},
|
||||
userToken() {
|
||||
return this.$store.getters['user/getToken']
|
||||
},
|
||||
keepProgress() {
|
||||
return this.$store.state.ereaderKeepProgress
|
||||
},
|
||||
ebookFileId() {
|
||||
return this.$store.state.ereaderFileId
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ export default {
|
|||
},
|
||||
deleteLibraryFile() {
|
||||
const payload = {
|
||||
message: 'This will delete the file from your file system. Are you sure?',
|
||||
message: this.$strings.MessageConfirmDeleteFile,
|
||||
callback: (confirmed) => {
|
||||
if (confirmed) {
|
||||
this.$axios
|
||||
|
|
|
|||
87
client/components/tables/EbookFilesTable.vue
Normal file
87
client/components/tables/EbookFilesTable.vue
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
<template>
|
||||
<div class="w-full my-2">
|
||||
<div class="w-full bg-primary px-4 md:px-6 py-2 flex items-center cursor-pointer" @click.stop="clickBar">
|
||||
<p class="pr-2 md:pr-4">{{ $strings.HeaderEbookFiles }}</p>
|
||||
<div class="h-5 md:h-7 w-5 md:w-7 rounded-full bg-white bg-opacity-10 flex items-center justify-center">
|
||||
<span class="text-sm font-mono">{{ ebookFiles.length }}</span>
|
||||
</div>
|
||||
<div class="flex-grow" />
|
||||
<ui-btn v-if="userIsAdmin" small :color="showFullPath ? 'gray-600' : 'primary'" class="mr-2 hidden md:block" @click.stop="showFullPath = !showFullPath">{{ $strings.ButtonFullPath }}</ui-btn>
|
||||
<div class="cursor-pointer h-10 w-10 rounded-full hover:bg-black-400 flex justify-center items-center duration-500" :class="showFiles ? 'transform rotate-180' : ''">
|
||||
<span class="material-icons text-4xl">expand_more</span>
|
||||
</div>
|
||||
</div>
|
||||
<transition name="slide">
|
||||
<div class="w-full" v-show="showFiles">
|
||||
<table class="text-sm tracksTable">
|
||||
<tr>
|
||||
<th class="text-left px-4">{{ $strings.LabelPath }}</th>
|
||||
<th class="text-left w-24 min-w-24">{{ $strings.LabelSize }}</th>
|
||||
<th class="text-left px-4 w-24">
|
||||
{{ $strings.LabelRead }} <ui-tooltip :text="$strings.LabelReadEbookWithoutProgress" direction="top" class="inline-block"><span class="material-icons-outlined text-sm align-middle">info</span></ui-tooltip>
|
||||
</th>
|
||||
<th v-if="userCanDelete || userCanDownload || userIsAdmin" class="text-center w-16"></th>
|
||||
</tr>
|
||||
<template v-for="file in ebookFiles">
|
||||
<tables-ebook-files-table-row :key="file.path" :libraryItemId="libraryItemId" :showFullPath="showFullPath" :file="file" @read="readEbook" />
|
||||
</template>
|
||||
</table>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
libraryItem: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showFiles: false,
|
||||
showFullPath: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
libraryItemId() {
|
||||
return this.libraryItem.id
|
||||
},
|
||||
userToken() {
|
||||
return this.$store.getters['user/getToken']
|
||||
},
|
||||
userCanDownload() {
|
||||
return this.$store.getters['user/getUserCanDownload']
|
||||
},
|
||||
userCanDelete() {
|
||||
return this.$store.getters['user/getUserCanDelete']
|
||||
},
|
||||
userIsAdmin() {
|
||||
return this.$store.getters['user/getIsAdminOrUp']
|
||||
},
|
||||
ebookFiles() {
|
||||
return (this.libraryItem.libraryFiles || []).filter((lf) => lf.fileType === 'ebook')
|
||||
},
|
||||
ebookFileIno() {
|
||||
return this.libraryItem.media.ebookFile?.ino
|
||||
},
|
||||
audioFiles() {
|
||||
if (this.libraryItem.mediaType === 'podcast') {
|
||||
return this.libraryItem.media?.episodes.map((ep) => ep.audioFile) || []
|
||||
}
|
||||
return this.libraryItem.media?.audioFiles || []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
readEbook(fileIno) {
|
||||
this.$store.commit('showEReader', { libraryItem: this.libraryItem, keepProgress: false, fileId: fileIno })
|
||||
},
|
||||
clickBar() {
|
||||
this.showFiles = !this.showFiles
|
||||
}
|
||||
},
|
||||
mounted() {}
|
||||
}
|
||||
</script>
|
||||
139
client/components/tables/EbookFilesTableRow.vue
Normal file
139
client/components/tables/EbookFilesTableRow.vue
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
<template>
|
||||
<tr>
|
||||
<td class="px-4">
|
||||
{{ showFullPath ? file.metadata.path : file.metadata.relPath }} <ui-tooltip :text="$strings.LabelPrimaryEbook" class="inline-block"><span v-if="isPrimary" class="material-icons-outlined text-success align-text-bottom">check_circle</span></ui-tooltip>
|
||||
</td>
|
||||
<td>
|
||||
{{ $bytesPretty(file.metadata.size) }}
|
||||
</td>
|
||||
<td class="text-xs">
|
||||
<ui-icon-btn icon="auto_stories" outlined borderless icon-font-size="1.125rem" :size="8" @click="readEbook" />
|
||||
</td>
|
||||
<td v-if="contextMenuItems.length" class="text-center">
|
||||
<ui-context-menu-dropdown :items="contextMenuItems" :menu-width="130" :processing="processing" @action="contextMenuAction" />
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
libraryItemId: String,
|
||||
showFullPath: Boolean,
|
||||
file: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
processing: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
userToken() {
|
||||
return this.$store.getters['user/getToken']
|
||||
},
|
||||
userCanDownload() {
|
||||
return this.$store.getters['user/getUserCanDownload']
|
||||
},
|
||||
userCanDelete() {
|
||||
return this.$store.getters['user/getUserCanDelete']
|
||||
},
|
||||
userCanUpdate() {
|
||||
return this.$store.getters['user/getUserCanUpdate']
|
||||
},
|
||||
userIsAdmin() {
|
||||
return this.$store.getters['user/getIsAdminOrUp']
|
||||
},
|
||||
downloadUrl() {
|
||||
return `${process.env.serverUrl}/api/items/${this.libraryItemId}/file/${this.file.ino}/download?token=${this.userToken}`
|
||||
},
|
||||
isPrimary() {
|
||||
return !this.file.isSupplementary
|
||||
},
|
||||
libraryIsAudiobooksOnly() {
|
||||
return this.$store.getters['libraries/getLibraryIsAudiobooksOnly']
|
||||
},
|
||||
contextMenuItems() {
|
||||
const items = []
|
||||
if (this.userCanUpdate && !this.libraryIsAudiobooksOnly) {
|
||||
items.push({
|
||||
text: this.isPrimary ? this.$strings.LabelSetEbookAsSupplementary : this.$strings.LabelSetEbookAsPrimary,
|
||||
action: 'updateStatus'
|
||||
})
|
||||
}
|
||||
if (this.userCanDownload) {
|
||||
items.push({
|
||||
text: this.$strings.LabelDownload,
|
||||
action: 'download'
|
||||
})
|
||||
}
|
||||
if (this.userCanDelete) {
|
||||
items.push({
|
||||
text: this.$strings.ButtonDelete,
|
||||
action: 'delete'
|
||||
})
|
||||
}
|
||||
return items
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
readEbook() {
|
||||
this.$emit('read', this.file.ino)
|
||||
},
|
||||
contextMenuAction({ action }) {
|
||||
if (action === 'delete') {
|
||||
this.deleteLibraryFile()
|
||||
} else if (action === 'download') {
|
||||
this.downloadLibraryFile()
|
||||
} else if (action === 'updateStatus') {
|
||||
this.updateEbookStatus()
|
||||
}
|
||||
},
|
||||
updateEbookStatus() {
|
||||
this.processing = true
|
||||
this.$axios
|
||||
.$patch(`/api/items/${this.libraryItemId}/ebook/${this.file.ino}/status`)
|
||||
.then(() => {
|
||||
this.$toast.success('Ebook updated')
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to update ebook', error)
|
||||
this.$toast.error('Failed to update ebook')
|
||||
})
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
})
|
||||
},
|
||||
deleteLibraryFile() {
|
||||
const payload = {
|
||||
message: this.$strings.MessageConfirmDeleteFile,
|
||||
callback: (confirmed) => {
|
||||
if (confirmed) {
|
||||
this.processing = true
|
||||
this.$axios
|
||||
.$delete(`/api/items/${this.libraryItemId}/file/${this.file.ino}`)
|
||||
.then(() => {
|
||||
this.$toast.success('File deleted')
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to delete file', error)
|
||||
this.$toast.error('Failed to delete file')
|
||||
})
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
})
|
||||
}
|
||||
},
|
||||
type: 'yesNo'
|
||||
}
|
||||
this.$store.commit('globals/setConfirmPrompt', payload)
|
||||
},
|
||||
downloadLibraryFile() {
|
||||
this.$downloadFile(this.downloadUrl, this.file.metadata.filename)
|
||||
}
|
||||
},
|
||||
mounted() {}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -38,7 +38,6 @@ export default {
|
|||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
isMissing: Boolean,
|
||||
expanded: Boolean, // start expanded
|
||||
inModal: Boolean
|
||||
},
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ export default {
|
|||
},
|
||||
deleteLibraryFile() {
|
||||
const payload = {
|
||||
message: 'This will delete the file from your file system. Are you sure?',
|
||||
message: this.$strings.MessageConfirmDeleteFile,
|
||||
callback: (confirmed) => {
|
||||
if (confirmed) {
|
||||
this.$axios
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
<template>
|
||||
<div class="relative h-9 w-9" v-click-outside="clickOutsideObj">
|
||||
<slot :disabled="disabled" :showMenu="showMenu" :clickShowMenu="clickShowMenu">
|
||||
<button type="button" :disabled="disabled" class="relative h-full w-full flex items-center justify-center shadow-sm pl-3 pr-3 text-left focus:outline-none cursor-pointer text-gray-100 hover:text-gray-200 rounded-full hover:bg-white/5" aria-haspopup="listbox" :aria-expanded="showMenu" @click.stop.prevent="clickShowMenu">
|
||||
<slot :disabled="disabled" :showMenu="showMenu" :clickShowMenu="clickShowMenu" :processing="processing">
|
||||
<button v-if="!processing" type="button" :disabled="disabled" class="relative h-full w-full flex items-center justify-center shadow-sm pl-3 pr-3 text-left focus:outline-none cursor-pointer text-gray-100 hover:text-gray-200 rounded-full hover:bg-white/5" aria-haspopup="listbox" :aria-expanded="showMenu" @click.stop.prevent="clickShowMenu">
|
||||
<span class="material-icons" :class="iconClass">more_vert</span>
|
||||
</button>
|
||||
<div v-else class="h-full w-full flex items-center justify-center">
|
||||
<widgets-loading-spinner />
|
||||
</div>
|
||||
</slot>
|
||||
|
||||
<transition name="menu">
|
||||
|
|
@ -28,7 +31,7 @@
|
|||
</div>
|
||||
</template>
|
||||
<div v-else :key="index" class="flex items-center px-2 py-1.5 hover:bg-white hover:bg-opacity-5 text-white text-xs cursor-pointer" @click.stop="clickAction(item.action)">
|
||||
<p>{{ item.text }}</p>
|
||||
<p class="text-left">{{ item.text }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
|
@ -51,7 +54,8 @@ export default {
|
|||
menuWidth: {
|
||||
type: Number,
|
||||
default: 192
|
||||
}
|
||||
},
|
||||
processing: Boolean
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -147,7 +147,9 @@
|
|||
|
||||
<tables-chapters-table v-if="chapters.length" :library-item="libraryItem" class="mt-6" />
|
||||
|
||||
<tables-library-files-table v-if="libraryFiles.length" :is-missing="isMissing" :library-item="libraryItem" class="mt-6" />
|
||||
<tables-ebook-files-table v-if="ebookFiles.length" :library-item="libraryItem" class="mt-6" />
|
||||
|
||||
<tables-library-files-table v-if="libraryFiles.length" :library-item="libraryItem" class="mt-6" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -320,6 +322,9 @@ export default {
|
|||
libraryFiles() {
|
||||
return this.libraryItem.libraryFiles || []
|
||||
},
|
||||
ebookFiles() {
|
||||
return this.libraryFiles.filter((lf) => lf.fileType === 'ebook')
|
||||
},
|
||||
ebookFile() {
|
||||
return this.media.ebookFile
|
||||
},
|
||||
|
|
@ -519,7 +524,7 @@ export default {
|
|||
this.$store.commit('showEditModalOnTab', { libraryItem: this.libraryItem, tab: 'cover' })
|
||||
},
|
||||
openEbook() {
|
||||
this.$store.commit('showEReader', this.libraryItem)
|
||||
this.$store.commit('showEReader', { libraryItem: this.libraryItem, keepProgress: true })
|
||||
},
|
||||
toggleFinished(confirmed = false) {
|
||||
if (!this.userIsFinished && this.progressPercent > 0 && !confirmed) {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ export const state = () => ({
|
|||
editPodcastModalTab: 'details',
|
||||
showEditModal: false,
|
||||
showEReader: false,
|
||||
ereaderKeepProgress: false,
|
||||
ereaderFileId: null,
|
||||
selectedLibraryItem: null,
|
||||
developerMode: false,
|
||||
processingBatch: false,
|
||||
|
|
@ -210,8 +212,10 @@ export const mutations = {
|
|||
setEditPodcastModalTab(state, tab) {
|
||||
state.editPodcastModalTab = tab
|
||||
},
|
||||
showEReader(state, libraryItem) {
|
||||
showEReader(state, { libraryItem, keepProgress, fileId }) {
|
||||
state.selectedLibraryItem = libraryItem
|
||||
state.ereaderKeepProgress = keepProgress
|
||||
state.ereaderFileId = fileId
|
||||
|
||||
state.showEReader = true
|
||||
},
|
||||
|
|
|
|||
|
|
@ -57,6 +57,9 @@ export const getters = {
|
|||
if (!getters.getCurrentLibrarySettings || isNaN(getters.getCurrentLibrarySettings.coverAspectRatio)) return 1
|
||||
return getters.getCurrentLibrarySettings.coverAspectRatio === Constants.BookCoverAspectRatio.STANDARD ? 1.6 : 1
|
||||
},
|
||||
getLibraryIsAudiobooksOnly: (state, getters) => {
|
||||
return !!getters.getCurrentLibrarySettings?.audiobooksOnly
|
||||
},
|
||||
getCollection: state => id => {
|
||||
return state.collections.find(c => c.id === id)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@
|
|||
"HeaderCurrentDownloads": "Aktuelle Downloads",
|
||||
"HeaderDetails": "Details",
|
||||
"HeaderDownloadQueue": "Download Warteschlange",
|
||||
"HeaderEbookFiles": "Ebook Files",
|
||||
"HeaderEmail": "Email",
|
||||
"HeaderEmailSettings": "Email Settings",
|
||||
"HeaderEpisodes": "Episoden",
|
||||
|
|
@ -339,12 +340,15 @@
|
|||
"LabelPort": "Port",
|
||||
"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",
|
||||
"LabelPrimaryEbook": "Primary ebook",
|
||||
"LabelProgress": "Fortschritt",
|
||||
"LabelProvider": "Anbieter",
|
||||
"LabelPubDate": "Veröffentlichungsdatum",
|
||||
"LabelPublisher": "Herausgeber",
|
||||
"LabelPublishYear": "Jahr",
|
||||
"LabelRead": "Read",
|
||||
"LabelReadAgain": "Read Again",
|
||||
"LabelReadEbookWithoutProgress": "Read ebook without keeping progress",
|
||||
"LabelRecentlyAdded": "Kürzlich hinzugefügt",
|
||||
"LabelRecentSeries": "Aktuelle Serien",
|
||||
"LabelRecommended": "Empfohlen",
|
||||
|
|
@ -366,6 +370,10 @@
|
|||
"LabelSeries": "Serien",
|
||||
"LabelSeriesName": "Serienname",
|
||||
"LabelSeriesProgress": "Serienfortschritt",
|
||||
"LabelSetEbookAsPrimary": "Set as primary",
|
||||
"LabelSetEbookAsSupplementary": "Set as supplementary",
|
||||
"LabelSettingsAudiobooksOnly": "Audiobooks only",
|
||||
"LabelSettingsAudiobooksOnlyHelp": "Enabling this setting will ignore ebook files unless they are inside an audiobook folder in which case they will be set as supplementary ebooks",
|
||||
"LabelSettingsBookshelfViewHelp": "Skeumorphes Design mit Holzeinlegeböden",
|
||||
"LabelSettingsChromecastSupport": "Chromecastunterstützung",
|
||||
"LabelSettingsDateFormat": "Datumsformat",
|
||||
|
|
@ -489,6 +497,7 @@
|
|||
"MessageChapterStartIsAfter": "Ungültige Kapitelstartzeit: Kapitelanfang > Mediumende (Kapitelanfang liegt nach dem Ende des Mediums)",
|
||||
"MessageCheckingCron": "Überprüfe Cron...",
|
||||
"MessageConfirmDeleteBackup": "Sind Sie sicher, dass Sie die Sicherung für {0} löschen wollen?",
|
||||
"MessageConfirmDeleteFile": "This will delete the file from your file system. Are you sure?",
|
||||
"MessageConfirmDeleteLibrary": "Sind Sie sicher, dass Sie die Bibliothek \"{0}\" dauerhaft löschen wollen?",
|
||||
"MessageConfirmDeleteSession": "Sind Sie sicher, dass Sie diese Sitzung löschen möchten?",
|
||||
"MessageConfirmForceReScan": "Sind Sie sicher, dass Sie einen erneuten Scanvorgang erzwingen wollen?",
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@
|
|||
"HeaderCurrentDownloads": "Current Downloads",
|
||||
"HeaderDetails": "Details",
|
||||
"HeaderDownloadQueue": "Download Queue",
|
||||
"HeaderEbookFiles": "Ebook Files",
|
||||
"HeaderEmail": "Email",
|
||||
"HeaderEmailSettings": "Email Settings",
|
||||
"HeaderEpisodes": "Episodes",
|
||||
|
|
@ -339,12 +340,15 @@
|
|||
"LabelPort": "Port",
|
||||
"LabelPrefixesToIgnore": "Prefixes to Ignore (case insensitive)",
|
||||
"LabelPreventIndexing": "Prevent your feed from being indexed by iTunes and Google podcast directories",
|
||||
"LabelPrimaryEbook": "Primary ebook",
|
||||
"LabelProgress": "Progress",
|
||||
"LabelProvider": "Provider",
|
||||
"LabelPubDate": "Pub Date",
|
||||
"LabelPublisher": "Publisher",
|
||||
"LabelPublishYear": "Publish Year",
|
||||
"LabelRead": "Read",
|
||||
"LabelReadAgain": "Read Again",
|
||||
"LabelReadEbookWithoutProgress": "Read ebook without keeping progress",
|
||||
"LabelRecentlyAdded": "Recently Added",
|
||||
"LabelRecentSeries": "Recent Series",
|
||||
"LabelRecommended": "Recommended",
|
||||
|
|
@ -366,6 +370,10 @@
|
|||
"LabelSeries": "Series",
|
||||
"LabelSeriesName": "Series Name",
|
||||
"LabelSeriesProgress": "Series Progress",
|
||||
"LabelSetEbookAsPrimary": "Set as primary",
|
||||
"LabelSetEbookAsSupplementary": "Set as supplementary",
|
||||
"LabelSettingsAudiobooksOnly": "Audiobooks only",
|
||||
"LabelSettingsAudiobooksOnlyHelp": "Enabling this setting will ignore ebook files unless they are inside an audiobook folder in which case they will be set as supplementary ebooks",
|
||||
"LabelSettingsBookshelfViewHelp": "Skeumorphic design with wooden shelves",
|
||||
"LabelSettingsChromecastSupport": "Chromecast support",
|
||||
"LabelSettingsDateFormat": "Date Format",
|
||||
|
|
@ -489,6 +497,7 @@
|
|||
"MessageChapterStartIsAfter": "Chapter start is after the end of your audiobook",
|
||||
"MessageCheckingCron": "Checking cron...",
|
||||
"MessageConfirmDeleteBackup": "Are you sure you want to delete backup for {0}?",
|
||||
"MessageConfirmDeleteFile": "This will delete the file from your file system. Are you sure?",
|
||||
"MessageConfirmDeleteLibrary": "Are you sure you want to permanently delete library \"{0}\"?",
|
||||
"MessageConfirmDeleteSession": "Are you sure you want to delete this session?",
|
||||
"MessageConfirmForceReScan": "Are you sure you want to force re-scan?",
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@
|
|||
"HeaderCurrentDownloads": "Descargando Actualmente",
|
||||
"HeaderDetails": "Detalles",
|
||||
"HeaderDownloadQueue": "Lista de Descarga",
|
||||
"HeaderEbookFiles": "Ebook Files",
|
||||
"HeaderEmail": "Email",
|
||||
"HeaderEmailSettings": "Email Settings",
|
||||
"HeaderEpisodes": "Episodios",
|
||||
|
|
@ -339,12 +340,15 @@
|
|||
"LabelPort": "Port",
|
||||
"LabelPrefixesToIgnore": "Prefijos para Ignorar (no distingue entre mayúsculas y minúsculas.)",
|
||||
"LabelPreventIndexing": "Evite que su fuente sea indexado por iTunes y Google podcast directories",
|
||||
"LabelPrimaryEbook": "Primary ebook",
|
||||
"LabelProgress": "Progreso",
|
||||
"LabelProvider": "Proveedor",
|
||||
"LabelPubDate": "Fecha de Publicación",
|
||||
"LabelPublisher": "Editor",
|
||||
"LabelPublishYear": "Año de Publicación",
|
||||
"LabelRead": "Read",
|
||||
"LabelReadAgain": "Read Again",
|
||||
"LabelReadEbookWithoutProgress": "Read ebook without keeping progress",
|
||||
"LabelRecentlyAdded": "Agregado Reciente",
|
||||
"LabelRecentSeries": "Series Recientes",
|
||||
"LabelRecommended": "Recomendados",
|
||||
|
|
@ -366,6 +370,10 @@
|
|||
"LabelSeries": "Series",
|
||||
"LabelSeriesName": "Nombre de la Serie",
|
||||
"LabelSeriesProgress": "Progreso de la Serie",
|
||||
"LabelSetEbookAsPrimary": "Set as primary",
|
||||
"LabelSetEbookAsSupplementary": "Set as supplementary",
|
||||
"LabelSettingsAudiobooksOnly": "Audiobooks only",
|
||||
"LabelSettingsAudiobooksOnlyHelp": "Enabling this setting will ignore ebook files unless they are inside an audiobook folder in which case they will be set as supplementary ebooks",
|
||||
"LabelSettingsBookshelfViewHelp": "Diseño Skeumorphic con Estantes de Madera",
|
||||
"LabelSettingsChromecastSupport": "Soporte para Chromecast",
|
||||
"LabelSettingsDateFormat": "Formato de Fecha",
|
||||
|
|
@ -489,6 +497,7 @@
|
|||
"MessageChapterStartIsAfter": "El comienzo del capítulo es después del final de su audiolibro",
|
||||
"MessageCheckingCron": "Checking cron...",
|
||||
"MessageConfirmDeleteBackup": "Esta seguro que desea eliminar el respaldo {0}?",
|
||||
"MessageConfirmDeleteFile": "This will delete the file from your file system. Are you sure?",
|
||||
"MessageConfirmDeleteLibrary": "Esta seguro que desea eliminar permanentemente la biblioteca \"{0}\"?",
|
||||
"MessageConfirmDeleteSession": "Esta seguro que desea eliminar esta session?",
|
||||
"MessageConfirmForceReScan": "Esta seguro que desea forzar re-escanear?",
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@
|
|||
"HeaderCurrentDownloads": "Téléchargements en cours",
|
||||
"HeaderDetails": "Détails",
|
||||
"HeaderDownloadQueue": "File d'attente de téléchargements",
|
||||
"HeaderEbookFiles": "Ebook Files",
|
||||
"HeaderEmail": "E-mails",
|
||||
"HeaderEmailSettings": "Configuration des e-mails",
|
||||
"HeaderEpisodes": "Épisodes",
|
||||
|
|
@ -339,12 +340,15 @@
|
|||
"LabelPort": "Port",
|
||||
"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",
|
||||
"LabelPrimaryEbook": "Primary ebook",
|
||||
"LabelProgress": "Progression",
|
||||
"LabelProvider": "Fournisseur",
|
||||
"LabelPubDate": "Date de publication",
|
||||
"LabelPublisher": "Éditeur",
|
||||
"LabelPublishYear": "Année d’édition",
|
||||
"LabelRead": "Read",
|
||||
"LabelReadAgain": "Read Again",
|
||||
"LabelReadEbookWithoutProgress": "Read ebook without keeping progress",
|
||||
"LabelRecentlyAdded": "Derniers ajouts",
|
||||
"LabelRecentSeries": "Séries récentes",
|
||||
"LabelRecommended": "Recommandé",
|
||||
|
|
@ -366,6 +370,10 @@
|
|||
"LabelSeries": "Séries",
|
||||
"LabelSeriesName": "Nom de la série",
|
||||
"LabelSeriesProgress": "Progression de séries",
|
||||
"LabelSetEbookAsPrimary": "Set as primary",
|
||||
"LabelSetEbookAsSupplementary": "Set as supplementary",
|
||||
"LabelSettingsAudiobooksOnly": "Audiobooks only",
|
||||
"LabelSettingsAudiobooksOnlyHelp": "Enabling this setting will ignore ebook files unless they are inside an audiobook folder in which case they will be set as supplementary ebooks",
|
||||
"LabelSettingsBookshelfViewHelp": "Interface skeuomorphique avec une étagère en bois",
|
||||
"LabelSettingsChromecastSupport": "Support du Chromecast",
|
||||
"LabelSettingsDateFormat": "Format de date",
|
||||
|
|
@ -489,6 +497,7 @@
|
|||
"MessageChapterStartIsAfter": "Le Chapitre Début est situé au début de votre Livre Audio",
|
||||
"MessageCheckingCron": "Vérification du cron…",
|
||||
"MessageConfirmDeleteBackup": "Êtes-vous sûr de vouloir supprimer la Sauvegarde de {0} ?",
|
||||
"MessageConfirmDeleteFile": "This will delete the file from your file system. Are you sure?",
|
||||
"MessageConfirmDeleteLibrary": "Êtes-vous sûr de vouloir supprimer définitivement la bibliothèque « {0} » ?",
|
||||
"MessageConfirmDeleteSession": "Êtes-vous sûr de vouloir supprimer cette session ?",
|
||||
"MessageConfirmForceReScan": "Êtes-vous sûr de vouloir lancer une Analyse Forcée ?",
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@
|
|||
"HeaderCurrentDownloads": "Current Downloads",
|
||||
"HeaderDetails": "Details",
|
||||
"HeaderDownloadQueue": "Download Queue",
|
||||
"HeaderEbookFiles": "Ebook Files",
|
||||
"HeaderEmail": "Email",
|
||||
"HeaderEmailSettings": "Email Settings",
|
||||
"HeaderEpisodes": "Episodes",
|
||||
|
|
@ -339,12 +340,15 @@
|
|||
"LabelPort": "Port",
|
||||
"LabelPrefixesToIgnore": "Prefixes to Ignore (case insensitive)",
|
||||
"LabelPreventIndexing": "Prevent your feed from being indexed by iTunes and Google podcast directories",
|
||||
"LabelPrimaryEbook": "Primary ebook",
|
||||
"LabelProgress": "Progress",
|
||||
"LabelProvider": "Provider",
|
||||
"LabelPubDate": "Pub Date",
|
||||
"LabelPublisher": "Publisher",
|
||||
"LabelPublishYear": "Publish Year",
|
||||
"LabelRead": "Read",
|
||||
"LabelReadAgain": "Read Again",
|
||||
"LabelReadEbookWithoutProgress": "Read ebook without keeping progress",
|
||||
"LabelRecentlyAdded": "Recently Added",
|
||||
"LabelRecentSeries": "Recent Series",
|
||||
"LabelRecommended": "Recommended",
|
||||
|
|
@ -366,6 +370,10 @@
|
|||
"LabelSeries": "Series",
|
||||
"LabelSeriesName": "Series Name",
|
||||
"LabelSeriesProgress": "Series Progress",
|
||||
"LabelSetEbookAsPrimary": "Set as primary",
|
||||
"LabelSetEbookAsSupplementary": "Set as supplementary",
|
||||
"LabelSettingsAudiobooksOnly": "Audiobooks only",
|
||||
"LabelSettingsAudiobooksOnlyHelp": "Enabling this setting will ignore ebook files unless they are inside an audiobook folder in which case they will be set as supplementary ebooks",
|
||||
"LabelSettingsBookshelfViewHelp": "Skeumorphic design with wooden shelves",
|
||||
"LabelSettingsChromecastSupport": "Chromecast support",
|
||||
"LabelSettingsDateFormat": "Date Format",
|
||||
|
|
@ -489,6 +497,7 @@
|
|||
"MessageChapterStartIsAfter": "Chapter start is after the end of your audiobook",
|
||||
"MessageCheckingCron": "Checking cron...",
|
||||
"MessageConfirmDeleteBackup": "Are you sure you want to delete backup for {0}?",
|
||||
"MessageConfirmDeleteFile": "This will delete the file from your file system. Are you sure?",
|
||||
"MessageConfirmDeleteLibrary": "Are you sure you want to permanently delete library \"{0}\"?",
|
||||
"MessageConfirmDeleteSession": "Are you sure you want to delete this session?",
|
||||
"MessageConfirmForceReScan": "Are you sure you want to force re-scan?",
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@
|
|||
"HeaderCurrentDownloads": "Current Downloads",
|
||||
"HeaderDetails": "Details",
|
||||
"HeaderDownloadQueue": "Download Queue",
|
||||
"HeaderEbookFiles": "Ebook Files",
|
||||
"HeaderEmail": "Email",
|
||||
"HeaderEmailSettings": "Email Settings",
|
||||
"HeaderEpisodes": "Episodes",
|
||||
|
|
@ -339,12 +340,15 @@
|
|||
"LabelPort": "Port",
|
||||
"LabelPrefixesToIgnore": "Prefixes to Ignore (case insensitive)",
|
||||
"LabelPreventIndexing": "Prevent your feed from being indexed by iTunes and Google podcast directories",
|
||||
"LabelPrimaryEbook": "Primary ebook",
|
||||
"LabelProgress": "Progress",
|
||||
"LabelProvider": "Provider",
|
||||
"LabelPubDate": "Pub Date",
|
||||
"LabelPublisher": "Publisher",
|
||||
"LabelPublishYear": "Publish Year",
|
||||
"LabelRead": "Read",
|
||||
"LabelReadAgain": "Read Again",
|
||||
"LabelReadEbookWithoutProgress": "Read ebook without keeping progress",
|
||||
"LabelRecentlyAdded": "Recently Added",
|
||||
"LabelRecentSeries": "Recent Series",
|
||||
"LabelRecommended": "Recommended",
|
||||
|
|
@ -366,6 +370,10 @@
|
|||
"LabelSeries": "Series",
|
||||
"LabelSeriesName": "Series Name",
|
||||
"LabelSeriesProgress": "Series Progress",
|
||||
"LabelSetEbookAsPrimary": "Set as primary",
|
||||
"LabelSetEbookAsSupplementary": "Set as supplementary",
|
||||
"LabelSettingsAudiobooksOnly": "Audiobooks only",
|
||||
"LabelSettingsAudiobooksOnlyHelp": "Enabling this setting will ignore ebook files unless they are inside an audiobook folder in which case they will be set as supplementary ebooks",
|
||||
"LabelSettingsBookshelfViewHelp": "Skeumorphic design with wooden shelves",
|
||||
"LabelSettingsChromecastSupport": "Chromecast support",
|
||||
"LabelSettingsDateFormat": "Date Format",
|
||||
|
|
@ -489,6 +497,7 @@
|
|||
"MessageChapterStartIsAfter": "Chapter start is after the end of your audiobook",
|
||||
"MessageCheckingCron": "Checking cron...",
|
||||
"MessageConfirmDeleteBackup": "Are you sure you want to delete backup for {0}?",
|
||||
"MessageConfirmDeleteFile": "This will delete the file from your file system. Are you sure?",
|
||||
"MessageConfirmDeleteLibrary": "Are you sure you want to permanently delete library \"{0}\"?",
|
||||
"MessageConfirmDeleteSession": "Are you sure you want to delete this session?",
|
||||
"MessageConfirmForceReScan": "Are you sure you want to force re-scan?",
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@
|
|||
"HeaderCurrentDownloads": "Current Downloads",
|
||||
"HeaderDetails": "Detalji",
|
||||
"HeaderDownloadQueue": "Download Queue",
|
||||
"HeaderEbookFiles": "Ebook Files",
|
||||
"HeaderEmail": "Email",
|
||||
"HeaderEmailSettings": "Email Settings",
|
||||
"HeaderEpisodes": "Epizode",
|
||||
|
|
@ -339,12 +340,15 @@
|
|||
"LabelPort": "Port",
|
||||
"LabelPrefixesToIgnore": "Prefiksi za ignorirati (mala i velika slova nisu bitna)",
|
||||
"LabelPreventIndexing": "Prevent your feed from being indexed by iTunes and Google podcast directories",
|
||||
"LabelPrimaryEbook": "Primary ebook",
|
||||
"LabelProgress": "Napredak",
|
||||
"LabelProvider": "Dobavljač",
|
||||
"LabelPubDate": "Datam izdavanja",
|
||||
"LabelPublisher": "Izdavač",
|
||||
"LabelPublishYear": "Godina izdavanja",
|
||||
"LabelRead": "Read",
|
||||
"LabelReadAgain": "Read Again",
|
||||
"LabelReadEbookWithoutProgress": "Read ebook without keeping progress",
|
||||
"LabelRecentlyAdded": "Nedavno dodano",
|
||||
"LabelRecentSeries": "Nedavne serije",
|
||||
"LabelRecommended": "Recommended",
|
||||
|
|
@ -366,6 +370,10 @@
|
|||
"LabelSeries": "Serije",
|
||||
"LabelSeriesName": "Ime serije",
|
||||
"LabelSeriesProgress": "Series Progress",
|
||||
"LabelSetEbookAsPrimary": "Set as primary",
|
||||
"LabelSetEbookAsSupplementary": "Set as supplementary",
|
||||
"LabelSettingsAudiobooksOnly": "Audiobooks only",
|
||||
"LabelSettingsAudiobooksOnlyHelp": "Enabling this setting will ignore ebook files unless they are inside an audiobook folder in which case they will be set as supplementary ebooks",
|
||||
"LabelSettingsBookshelfViewHelp": "Skeumorfski (što god to bilo) dizajn sa drvenim policama",
|
||||
"LabelSettingsChromecastSupport": "Chromecast podrška",
|
||||
"LabelSettingsDateFormat": "Format datuma",
|
||||
|
|
@ -489,6 +497,7 @@
|
|||
"MessageChapterStartIsAfter": "Početak poglavlja je nakon kraja audioknjige.",
|
||||
"MessageCheckingCron": "Provjeravam cron...",
|
||||
"MessageConfirmDeleteBackup": "Jeste li sigurni da želite obrisati backup za {0}?",
|
||||
"MessageConfirmDeleteFile": "This will delete the file from your file system. Are you sure?",
|
||||
"MessageConfirmDeleteLibrary": "Jeste li sigurni da želite trajno obrisati biblioteku \"{0}\"?",
|
||||
"MessageConfirmDeleteSession": "Jeste li sigurni da želite obrisati ovu sesiju?",
|
||||
"MessageConfirmForceReScan": "Jeste li sigurni da želite ponovno skenirati?",
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@
|
|||
"HeaderCurrentDownloads": "Current Downloads",
|
||||
"HeaderDetails": "Dettagli",
|
||||
"HeaderDownloadQueue": "Download Queue",
|
||||
"HeaderEbookFiles": "Ebook Files",
|
||||
"HeaderEmail": "Email",
|
||||
"HeaderEmailSettings": "Email Settings",
|
||||
"HeaderEpisodes": "Episodi",
|
||||
|
|
@ -339,12 +340,15 @@
|
|||
"LabelPort": "Port",
|
||||
"LabelPrefixesToIgnore": "Suffissi da ignorare (specificando maiuscole e minuscole)",
|
||||
"LabelPreventIndexing": "Impedisci che il tuo feed venga indicizzato da iTunes e dalle directory dei podcast di Google",
|
||||
"LabelPrimaryEbook": "Primary ebook",
|
||||
"LabelProgress": "Cominciati",
|
||||
"LabelProvider": "Provider",
|
||||
"LabelPubDate": "Data Pubblicazione",
|
||||
"LabelPublisher": "Editore",
|
||||
"LabelPublishYear": "Anno Pubblicazione",
|
||||
"LabelRead": "Read",
|
||||
"LabelReadAgain": "Read Again",
|
||||
"LabelReadEbookWithoutProgress": "Read ebook without keeping progress",
|
||||
"LabelRecentlyAdded": "Aggiunti Recentemente",
|
||||
"LabelRecentSeries": "Serie Recenti",
|
||||
"LabelRecommended": "Raccomandati",
|
||||
|
|
@ -366,6 +370,10 @@
|
|||
"LabelSeries": "Serie",
|
||||
"LabelSeriesName": "Nome Serie",
|
||||
"LabelSeriesProgress": "Cominciato",
|
||||
"LabelSetEbookAsPrimary": "Set as primary",
|
||||
"LabelSetEbookAsSupplementary": "Set as supplementary",
|
||||
"LabelSettingsAudiobooksOnly": "Audiobooks only",
|
||||
"LabelSettingsAudiobooksOnlyHelp": "Enabling this setting will ignore ebook files unless they are inside an audiobook folder in which case they will be set as supplementary ebooks",
|
||||
"LabelSettingsBookshelfViewHelp": "Design con scaffali in legno",
|
||||
"LabelSettingsChromecastSupport": "Supporto a Chromecast",
|
||||
"LabelSettingsDateFormat": "Formato Data",
|
||||
|
|
@ -489,6 +497,7 @@
|
|||
"MessageChapterStartIsAfter": "L'inizio del capitolo è dopo la fine del tuo audiolibro",
|
||||
"MessageCheckingCron": "Controllo cron...",
|
||||
"MessageConfirmDeleteBackup": "Sei sicuro di voler eliminare il backup {0}?",
|
||||
"MessageConfirmDeleteFile": "This will delete the file from your file system. Are you sure?",
|
||||
"MessageConfirmDeleteLibrary": "Sei sicuro di voler eliminare definitivamente la libreria \"{0}\"?",
|
||||
"MessageConfirmDeleteSession": "Sei sicuro di voler eliminare questa sessione?",
|
||||
"MessageConfirmForceReScan": "Sei sicuro di voler forzare una nuova scansione?",
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@
|
|||
"HeaderCurrentDownloads": "Huidige downloads",
|
||||
"HeaderDetails": "Details",
|
||||
"HeaderDownloadQueue": "Download-wachtrij",
|
||||
"HeaderEbookFiles": "Ebook Files",
|
||||
"HeaderEmail": "Email",
|
||||
"HeaderEmailSettings": "Email Settings",
|
||||
"HeaderEpisodes": "Afleveringen",
|
||||
|
|
@ -339,12 +340,15 @@
|
|||
"LabelPort": "Port",
|
||||
"LabelPrefixesToIgnore": "Te negeren voorzetsels (ongeacht hoofdlettergebruik)",
|
||||
"LabelPreventIndexing": "Voorkom indexering van je feed door iTunes- en Google podcastmappen",
|
||||
"LabelPrimaryEbook": "Primary ebook",
|
||||
"LabelProgress": "Voortgang",
|
||||
"LabelProvider": "Bron",
|
||||
"LabelPubDate": "Publicatiedatum",
|
||||
"LabelPublisher": "Uitgever",
|
||||
"LabelPublishYear": "Jaar van uitgave",
|
||||
"LabelRead": "Read",
|
||||
"LabelReadAgain": "Read Again",
|
||||
"LabelReadEbookWithoutProgress": "Read ebook without keeping progress",
|
||||
"LabelRecentlyAdded": "Recent toegevoegd",
|
||||
"LabelRecentSeries": "Recente series",
|
||||
"LabelRecommended": "Aangeraden",
|
||||
|
|
@ -366,6 +370,10 @@
|
|||
"LabelSeries": "Serie",
|
||||
"LabelSeriesName": "Naam serie",
|
||||
"LabelSeriesProgress": "Voortgang serie",
|
||||
"LabelSetEbookAsPrimary": "Set as primary",
|
||||
"LabelSetEbookAsSupplementary": "Set as supplementary",
|
||||
"LabelSettingsAudiobooksOnly": "Audiobooks only",
|
||||
"LabelSettingsAudiobooksOnlyHelp": "Enabling this setting will ignore ebook files unless they are inside an audiobook folder in which case they will be set as supplementary ebooks",
|
||||
"LabelSettingsBookshelfViewHelp": "Skeumorphisch design met houten planken",
|
||||
"LabelSettingsChromecastSupport": "Chromecast support",
|
||||
"LabelSettingsDateFormat": "Datum format",
|
||||
|
|
@ -489,6 +497,7 @@
|
|||
"MessageChapterStartIsAfter": "Start van hoofdstuk is na het einde van je audioboek",
|
||||
"MessageCheckingCron": "Cron aan het checken...",
|
||||
"MessageConfirmDeleteBackup": "Weet je zeker dat je de backup voor {0} wil verwijderen?",
|
||||
"MessageConfirmDeleteFile": "This will delete the file from your file system. Are you sure?",
|
||||
"MessageConfirmDeleteLibrary": "Weet je zeker dat je de bibliotheek \"{0}\" permanent wil verwijderen?",
|
||||
"MessageConfirmDeleteSession": "Weet je zeker dat je deze sessie wil verwijderen?",
|
||||
"MessageConfirmForceReScan": "Weet je zeker dat je geforceerd opnieuw wil scannen?",
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@
|
|||
"HeaderCurrentDownloads": "Current Downloads",
|
||||
"HeaderDetails": "Szczegóły",
|
||||
"HeaderDownloadQueue": "Download Queue",
|
||||
"HeaderEbookFiles": "Ebook Files",
|
||||
"HeaderEmail": "Email",
|
||||
"HeaderEmailSettings": "Email Settings",
|
||||
"HeaderEpisodes": "Rozdziały",
|
||||
|
|
@ -339,12 +340,15 @@
|
|||
"LabelPort": "Port",
|
||||
"LabelPrefixesToIgnore": "Ignorowane prefiksy (wielkość liter nie ma znaczenia)",
|
||||
"LabelPreventIndexing": "Prevent your feed from being indexed by iTunes and Google podcast directories",
|
||||
"LabelPrimaryEbook": "Primary ebook",
|
||||
"LabelProgress": "Postęp",
|
||||
"LabelProvider": "Dostawca",
|
||||
"LabelPubDate": "Data publikacji",
|
||||
"LabelPublisher": "Wydawca",
|
||||
"LabelPublishYear": "Rok publikacji",
|
||||
"LabelRead": "Read",
|
||||
"LabelReadAgain": "Read Again",
|
||||
"LabelReadEbookWithoutProgress": "Read ebook without keeping progress",
|
||||
"LabelRecentlyAdded": "Niedawno dodany",
|
||||
"LabelRecentSeries": "Ostatnie serie",
|
||||
"LabelRecommended": "Recommended",
|
||||
|
|
@ -366,6 +370,10 @@
|
|||
"LabelSeries": "Serie",
|
||||
"LabelSeriesName": "Nazwy serii",
|
||||
"LabelSeriesProgress": "Postęp w serii",
|
||||
"LabelSetEbookAsPrimary": "Set as primary",
|
||||
"LabelSetEbookAsSupplementary": "Set as supplementary",
|
||||
"LabelSettingsAudiobooksOnly": "Audiobooks only",
|
||||
"LabelSettingsAudiobooksOnlyHelp": "Enabling this setting will ignore ebook files unless they are inside an audiobook folder in which case they will be set as supplementary ebooks",
|
||||
"LabelSettingsBookshelfViewHelp": "Widok półki z ksiązkami",
|
||||
"LabelSettingsChromecastSupport": "Wsparcie Chromecast",
|
||||
"LabelSettingsDateFormat": "Format daty",
|
||||
|
|
@ -489,6 +497,7 @@
|
|||
"MessageChapterStartIsAfter": "Początek rozdziału następuje po zakończeniu audiobooka",
|
||||
"MessageCheckingCron": "Sprawdzanie cron...",
|
||||
"MessageConfirmDeleteBackup": "Czy na pewno chcesz usunąć kopię zapasową dla {0}?",
|
||||
"MessageConfirmDeleteFile": "This will delete the file from your file system. Are you sure?",
|
||||
"MessageConfirmDeleteLibrary": "Czy na pewno chcesz trwale usunąć bibliotekę \"{0}\"?",
|
||||
"MessageConfirmDeleteSession": "Czy na pewno chcesz usunąć tę sesję?",
|
||||
"MessageConfirmForceReScan": "Czy na pewno chcesz wymusić ponowne skanowanie?",
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@
|
|||
"HeaderCurrentDownloads": "Текущие закачки",
|
||||
"HeaderDetails": "Подробности",
|
||||
"HeaderDownloadQueue": "Очередь скачивания",
|
||||
"HeaderEbookFiles": "Ebook Files",
|
||||
"HeaderEmail": "Email",
|
||||
"HeaderEmailSettings": "Email Settings",
|
||||
"HeaderEpisodes": "Эпизоды",
|
||||
|
|
@ -339,12 +340,15 @@
|
|||
"LabelPort": "Port",
|
||||
"LabelPrefixesToIgnore": "Игнорируемые префиксы (без учета регистра)",
|
||||
"LabelPreventIndexing": "Запретить индексацию фида каталогами подкастов iTunes и Google",
|
||||
"LabelPrimaryEbook": "Primary ebook",
|
||||
"LabelProgress": "Прогресс",
|
||||
"LabelProvider": "Провайдер",
|
||||
"LabelPubDate": "Дата публикации",
|
||||
"LabelPublisher": "Издатель",
|
||||
"LabelPublishYear": "Год публикации",
|
||||
"LabelRead": "Read",
|
||||
"LabelReadAgain": "Read Again",
|
||||
"LabelReadEbookWithoutProgress": "Read ebook without keeping progress",
|
||||
"LabelRecentlyAdded": "Недавно добавленные",
|
||||
"LabelRecentSeries": "Последние серии",
|
||||
"LabelRecommended": "Рекомендованное",
|
||||
|
|
@ -366,6 +370,10 @@
|
|||
"LabelSeries": "Серия",
|
||||
"LabelSeriesName": "Имя серии",
|
||||
"LabelSeriesProgress": "Прогресс серии",
|
||||
"LabelSetEbookAsPrimary": "Set as primary",
|
||||
"LabelSetEbookAsSupplementary": "Set as supplementary",
|
||||
"LabelSettingsAudiobooksOnly": "Audiobooks only",
|
||||
"LabelSettingsAudiobooksOnlyHelp": "Enabling this setting will ignore ebook files unless they are inside an audiobook folder in which case they will be set as supplementary ebooks",
|
||||
"LabelSettingsBookshelfViewHelp": "Конструкция с деревянными полками",
|
||||
"LabelSettingsChromecastSupport": "Поддержка Chromecast",
|
||||
"LabelSettingsDateFormat": "Формат даты",
|
||||
|
|
@ -489,6 +497,7 @@
|
|||
"MessageChapterStartIsAfter": "Глава начинается после окончания аудиокниги",
|
||||
"MessageCheckingCron": "Проверка cron...",
|
||||
"MessageConfirmDeleteBackup": "Вы уверены, что хотите удалить бэкап для {0}?",
|
||||
"MessageConfirmDeleteFile": "This will delete the file from your file system. Are you sure?",
|
||||
"MessageConfirmDeleteLibrary": "Вы уверены, что хотите навсегда удалить библиотеку \"{0}\"?",
|
||||
"MessageConfirmDeleteSession": "Вы уверены, что хотите удалить этот сеанс?",
|
||||
"MessageConfirmForceReScan": "Вы уверены, что хотите принудительно выполнить повторное сканирование?",
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@
|
|||
"HeaderCurrentDownloads": "当前下载",
|
||||
"HeaderDetails": "详情",
|
||||
"HeaderDownloadQueue": "下载队列",
|
||||
"HeaderEbookFiles": "Ebook Files",
|
||||
"HeaderEmail": "Email",
|
||||
"HeaderEmailSettings": "Email Settings",
|
||||
"HeaderEpisodes": "剧集",
|
||||
|
|
@ -339,12 +340,15 @@
|
|||
"LabelPort": "Port",
|
||||
"LabelPrefixesToIgnore": "忽略的前缀 (不区分大小写)",
|
||||
"LabelPreventIndexing": "防止 iTunes 和 Google 播客目录对你的源进行索引",
|
||||
"LabelPrimaryEbook": "Primary ebook",
|
||||
"LabelProgress": "进度",
|
||||
"LabelProvider": "供应商",
|
||||
"LabelPubDate": "出版日期",
|
||||
"LabelPublisher": "出版商",
|
||||
"LabelPublishYear": "发布年份",
|
||||
"LabelRead": "Read",
|
||||
"LabelReadAgain": "Read Again",
|
||||
"LabelReadEbookWithoutProgress": "Read ebook without keeping progress",
|
||||
"LabelRecentlyAdded": "最近添加",
|
||||
"LabelRecentSeries": "最近添加系列",
|
||||
"LabelRecommended": "推荐内容",
|
||||
|
|
@ -366,6 +370,10 @@
|
|||
"LabelSeries": "系列",
|
||||
"LabelSeriesName": "系列名称",
|
||||
"LabelSeriesProgress": "系列进度",
|
||||
"LabelSetEbookAsPrimary": "Set as primary",
|
||||
"LabelSetEbookAsSupplementary": "Set as supplementary",
|
||||
"LabelSettingsAudiobooksOnly": "Audiobooks only",
|
||||
"LabelSettingsAudiobooksOnlyHelp": "Enabling this setting will ignore ebook files unless they are inside an audiobook folder in which case they will be set as supplementary ebooks",
|
||||
"LabelSettingsBookshelfViewHelp": "带有木架子的拟物化设计",
|
||||
"LabelSettingsChromecastSupport": "Chromecast 支持",
|
||||
"LabelSettingsDateFormat": "日期格式",
|
||||
|
|
@ -489,6 +497,7 @@
|
|||
"MessageChapterStartIsAfter": "章节开始是在有声读物结束之后",
|
||||
"MessageCheckingCron": "检查计划任务...",
|
||||
"MessageConfirmDeleteBackup": "你确定要删除备份 {0}?",
|
||||
"MessageConfirmDeleteFile": "This will delete the file from your file system. Are you sure?",
|
||||
"MessageConfirmDeleteLibrary": "你确定要永久删除媒体库 \"{0}\"?",
|
||||
"MessageConfirmDeleteSession": "你确定要删除此会话吗?",
|
||||
"MessageConfirmForceReScan": "你确定要强制重新扫描吗?",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue