mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-03-14 23:28:32 +01:00
Translation strings added (#3304)
* Update: `pages/items/_id` toast messages * Update: account modal strings * Update: audio file data modal strings * Update: sleep timer set string * Update: loading indicator string * Update: lazy book card strings * Reorder keys * Fix: syntax error in LazyBookCard * Fix: json ordering * Fix: fix double message definition * Update: login form toast strings * Update: batch delete toast * Update: collection add toast messages * Replace: toasts in BookShelfToolbar * Update: playlist edit toasts * Update: Details tab * Add: title required string * Update: ereader toasts * Update: author toasts, title and name required toasts * Clean up "no updates" strings * Change: slug strings * Update: cover modal toasts * Change: cancel encode toasts * Change: failed to share toasts * Simplify: "renameFail" and "removeFail" toasts * Fix: ordering * Change: chapters remove toast * Update: notification strings * Revert: loading indicator (error in browser) * Update: collectionBooksTable toast * Update: "failed to get" strings * Update: backup strings * Update: custom provider strings * Update: sessions strings * Update: email strings * Update sort display translation strings, update podcast episode queue strings to use translation * Fix loading indicator please wait translation * Consolidate translations and reduce number of toasts --------- Co-authored-by: advplyr <advplyr@protonmail.com>
This commit is contained in:
parent
acc4bdbc5e
commit
f0e70ed27b
@ -332,13 +332,13 @@ export default {
|
||||
libraryItemIds: this.selectedMediaItems.map((i) => i.id)
|
||||
})
|
||||
.then(() => {
|
||||
this.$toast.success('Batch delete success')
|
||||
this.$toast.success(this.$strings.ToastBatchDeleteSuccess)
|
||||
this.$store.commit('globals/resetSelectedMediaItems', [])
|
||||
this.$eventBus.$emit('bookshelf_clear_selection')
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Batch delete failed', error)
|
||||
this.$toast.error('Batch delete failed')
|
||||
this.$toast.error(this.$strings.ToastBatchDeleteFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.$store.commit('setProcessingBatch', false)
|
||||
|
@ -473,11 +473,11 @@ export default {
|
||||
this.$axios
|
||||
.$get(`/api/me/series/${this.seriesId}/readd-to-continue-listening`)
|
||||
.then(() => {
|
||||
this.$toast.success('Series re-added to continue listening')
|
||||
this.$toast.success(this.$strings.ToastItemUpdateSuccess)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to re-add series to continue listening', error)
|
||||
this.$toast.error('Failed to re-add series to continue listening')
|
||||
this.$toast.error(this.$strings.ToastItemUpdateFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.processingSeries = false
|
||||
@ -504,7 +504,7 @@ export default {
|
||||
})
|
||||
if (!response) {
|
||||
console.error(`Author ${author.name} not found`)
|
||||
this.$toast.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)`)
|
||||
@ -522,13 +522,13 @@ export default {
|
||||
this.$axios
|
||||
.$delete(`/api/libraries/${this.currentLibraryId}/issues`)
|
||||
.then(() => {
|
||||
this.$toast.success('Removed library items with issues')
|
||||
this.$toast.success(this.$strings.ToastRemoveItemsWithIssuesSuccess)
|
||||
this.$router.push(`/library/${this.currentLibraryId}/bookshelf`)
|
||||
this.$store.dispatch('libraries/fetch', this.currentLibraryId)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to remove library items with issues', error)
|
||||
this.$toast.error('Failed to remove library items with issues')
|
||||
this.$toast.error(this.$strings.ToastRemoveItemsWithIssuesFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.processingIssues = false
|
||||
|
@ -346,14 +346,14 @@ export default {
|
||||
},
|
||||
displaySortLine() {
|
||||
if (this.collapsedSeries) return null
|
||||
if (this.orderBy === 'mtimeMs') return 'Modified ' + this.$formatDate(this._libraryItem.mtimeMs, this.dateFormat)
|
||||
if (this.orderBy === 'birthtimeMs') return 'Born ' + this.$formatDate(this._libraryItem.birthtimeMs, this.dateFormat)
|
||||
if (this.orderBy === 'addedAt') return 'Added ' + this.$formatDate(this._libraryItem.addedAt, this.dateFormat)
|
||||
if (this.orderBy === 'media.duration') return 'Duration: ' + this.$elapsedPrettyExtended(this.media.duration, false)
|
||||
if (this.orderBy === 'size') return 'Size: ' + this.$bytesPretty(this._libraryItem.size)
|
||||
if (this.orderBy === 'media.numTracks') return `${this.numEpisodes} Episodes`
|
||||
if (this.orderBy === 'mtimeMs') return this.$getString('LabelFileModifiedDate', [this.$formatDate(this._libraryItem.mtimeMs, this.dateFormat)])
|
||||
if (this.orderBy === 'birthtimeMs') return this.$getString('LabelFileBornDate', [this.$formatDate(this._libraryItem.birthtimeMs, this.dateFormat)])
|
||||
if (this.orderBy === 'addedAt') return this.$getString('LabelAddedDate', [this.$formatDate(this._libraryItem.addedAt, this.dateFormat)])
|
||||
if (this.orderBy === 'media.duration') return this.$strings.LabelDuration + ': ' + this.$elapsedPrettyExtended(this.media.duration, false)
|
||||
if (this.orderBy === 'size') return this.$strings.LabelSize + ': ' + this.$bytesPretty(this._libraryItem.size)
|
||||
if (this.orderBy === 'media.numTracks') return `${this.numEpisodes} ` + this.$strings.LabelEpisodes
|
||||
if (this.orderBy === 'media.metadata.publishedYear') {
|
||||
if (this.mediaMetadata.publishedYear) return 'Published ' + this.mediaMetadata.publishedYear
|
||||
if (this.mediaMetadata.publishedYear) return this.$getString('LabelPublishedDate', [this.mediaMetadata.publishedYear])
|
||||
return '\u00A0'
|
||||
}
|
||||
return null
|
||||
@ -710,7 +710,7 @@ export default {
|
||||
toggleFinished(confirmed = false) {
|
||||
if (!this.itemIsFinished && this.userProgressPercent > 0 && !confirmed) {
|
||||
const payload = {
|
||||
message: `Are you sure you want to mark "${this.displayTitle}" as finished?`,
|
||||
message: this.$getString('MessageConfirmMarkItemFinished', [this.displayTitle]),
|
||||
callback: (confirmed) => {
|
||||
if (confirmed) {
|
||||
this.toggleFinished(true)
|
||||
@ -755,18 +755,18 @@ export default {
|
||||
.then((data) => {
|
||||
var result = data.result
|
||||
if (!result) {
|
||||
this.$toast.error(`Re-Scan Failed for "${this.title}"`)
|
||||
this.$toast.error(this.$getString('ToastRescanFailed', [this.displayTitle]))
|
||||
} else if (result === 'UPDATED') {
|
||||
this.$toast.success(`Re-Scan complete item was updated`)
|
||||
this.$toast.success(this.$strings.ToastRescanUpdated)
|
||||
} else if (result === 'UPTODATE') {
|
||||
this.$toast.success(`Re-Scan complete item was up to date`)
|
||||
this.$toast.success(this.$strings.ToastRescanUpToDate)
|
||||
} else if (result === 'REMOVED') {
|
||||
this.$toast.error(`Re-Scan complete item was removed`)
|
||||
this.$toast.error(this.$strings.ToastRescanRemoved)
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to scan library item', error)
|
||||
this.$toast.error('Failed to scan library item')
|
||||
this.$toast.error(this.$strings.ToastScanFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
@ -823,7 +823,7 @@ export default {
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to remove series from home', error)
|
||||
this.$toast.error('Failed to update user')
|
||||
this.$toast.error(this.$strings.ToastFailedToUpdateUser)
|
||||
})
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
@ -841,7 +841,7 @@ export default {
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to hide item from home', error)
|
||||
this.$toast.error('Failed to update user')
|
||||
this.$toast.error(this.$strings.ToastFailedToUpdateUser)
|
||||
})
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
@ -856,7 +856,7 @@ export default {
|
||||
episodeId: this.recentEpisode.id,
|
||||
title: this.recentEpisode.title,
|
||||
subtitle: this.mediaMetadata.title,
|
||||
caption: this.recentEpisode.publishedAt ? `Published ${this.$formatDate(this.recentEpisode.publishedAt, this.dateFormat)}` : 'Unknown publish date',
|
||||
caption: this.recentEpisode.publishedAt ? this.$getString('LabelPublishedDate', [this.$formatDate(this.recentEpisode.publishedAt, this.dateFormat)]) : this.$strings.LabelUnknownPublishDate,
|
||||
duration: this.recentEpisode.audioFile.duration || null,
|
||||
coverPath: this.media.coverPath || null
|
||||
}
|
||||
@ -906,11 +906,11 @@ export default {
|
||||
axios
|
||||
.$delete(`/api/items/${this.libraryItemId}?hard=${hardDelete ? 1 : 0}`)
|
||||
.then(() => {
|
||||
this.$toast.success('Item deleted')
|
||||
this.$toast.success(this.$strings.ToastItemDeletedSuccess)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to delete item', error)
|
||||
this.$toast.error('Failed to delete item')
|
||||
this.$toast.error(this.$strings.ToastItemDeletedFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
@ -1016,7 +1016,7 @@ export default {
|
||||
episodeId: episode.id,
|
||||
title: episode.title,
|
||||
subtitle: this.mediaMetadata.title,
|
||||
caption: episode.publishedAt ? `Published ${this.$formatDate(episode.publishedAt, this.dateFormat)}` : 'Unknown publish date',
|
||||
caption: episode.publishedAt ? this.$getString('LabelPublishedDate', [this.$formatDate(episode.publishedAt, this.dateFormat)]) : this.$strings.LabelUnknownPublishDate,
|
||||
duration: episode.audioFile.duration || null,
|
||||
coverPath: this.media.coverPath || null
|
||||
})
|
||||
|
@ -96,7 +96,7 @@ export default {
|
||||
displaySortLine() {
|
||||
switch (this.orderBy) {
|
||||
case 'addedAt':
|
||||
return `${this.$strings.LabelAdded} ${this.$formatDate(this.addedAt, this.dateFormat)}`
|
||||
return this.$getString('LabelAddedDate', [this.$formatDate(this.addedAt, this.dateFormat)])
|
||||
case 'totalDuration':
|
||||
return `${this.$strings.LabelDuration} ${this.$elapsedPrettyExtended(this.totalDuration, false)}`
|
||||
case 'lastBookUpdated':
|
||||
|
@ -4,11 +4,11 @@
|
||||
<p class="text-base md:text-lg font-semibold pr-4">{{ eventName }}</p>
|
||||
<div class="flex-grow" />
|
||||
|
||||
<ui-btn v-if="eventName === 'onTest' && notification.enabled" :loading="testing" small class="mr-2" @click.stop="fireTestEventAndSucceed">Fire onTest Event</ui-btn>
|
||||
<ui-btn v-if="eventName === 'onTest' && notification.enabled" :loading="testing" small class="mr-2" color="red-600" @click.stop="fireTestEventAndFail">Fire & Fail</ui-btn>
|
||||
<ui-btn v-if="eventName === 'onTest' && notification.enabled" :loading="testing" small class="mr-2" @click.stop="fireTestEventAndSucceed">{{ this.$strings.ButtonFireOnTest }}</ui-btn>
|
||||
<ui-btn v-if="eventName === 'onTest' && notification.enabled" :loading="testing" small class="mr-2" color="red-600" @click.stop="fireTestEventAndFail">{{ this.$strings.ButtonFireAndFail }}</ui-btn>
|
||||
<!-- <ui-btn v-if="eventName === 'onTest' && notification.enabled" :loading="testing" small class="mr-2" @click.stop="rapidFireTestEvents">Rapid Fire</ui-btn> -->
|
||||
<ui-btn v-else-if="notification.enabled" :loading="sendingTest" small class="mr-2" @click.stop="sendTestClick">Test</ui-btn>
|
||||
<ui-btn v-else :loading="enabling" small color="success" class="mr-2" @click="enableNotification">Enable</ui-btn>
|
||||
<ui-btn v-else-if="notification.enabled" :loading="sendingTest" small class="mr-2" @click.stop="sendTestClick">{{ this.$strings.ButtonTest }}</ui-btn>
|
||||
<ui-btn v-else :loading="enabling" small color="success" class="mr-2" @click="enableNotification">{{ this.$strings.ButtonEnable }}</ui-btn>
|
||||
|
||||
<ui-icon-btn :size="7" icon-font-size="1.1rem" icon="edit" class="mr-2" @click="editNotification" />
|
||||
<ui-icon-btn bg-color="error" :size="7" icon-font-size="1.2rem" icon="delete" @click="deleteNotificationClick" />
|
||||
@ -65,12 +65,12 @@ export default {
|
||||
this.$axios
|
||||
.$get(`/api/notifications/test?fail=${intentionallyFail ? 1 : 0}`)
|
||||
.then(() => {
|
||||
this.$toast.success('Triggered onTest Event')
|
||||
this.$toast.success(this.$strings.ToastNotificationTestTriggerSuccess)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed', error)
|
||||
const errorMsg = error.response ? error.response.data : null
|
||||
this.$toast.error(`Failed: ${errorMsg}` || 'Failed to trigger onTest event')
|
||||
this.$toast.error(`Failed: ${errorMsg}` || this.$strings.ToastNotificationTestTriggerFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.testing = false
|
||||
@ -91,7 +91,7 @@ export default {
|
||||
// End testing functions
|
||||
sendTestClick() {
|
||||
const payload = {
|
||||
message: `Trigger this notification with test data?`,
|
||||
message: this.$strings.MessageConfirmNotificationTestTrigger,
|
||||
callback: (confirmed) => {
|
||||
if (confirmed) {
|
||||
this.sendTest()
|
||||
@ -106,12 +106,12 @@ export default {
|
||||
this.$axios
|
||||
.$get(`/api/notifications/${this.notification.id}/test`)
|
||||
.then(() => {
|
||||
this.$toast.success('Triggered test notification')
|
||||
this.$toast.success(this.$strings.ToastNotificationTestTriggerSuccess)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed', error)
|
||||
const errorMsg = error.response ? error.response.data : null
|
||||
this.$toast.error(`Failed: ${errorMsg}` || 'Failed to trigger test notification')
|
||||
this.$toast.error(`Failed: ${errorMsg}` || this.$strings.ToastNotificationTestTriggerFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.sendingTest = false
|
||||
@ -127,11 +127,10 @@ export default {
|
||||
.$patch(`/api/notifications/${this.notification.id}`, payload)
|
||||
.then((updatedSettings) => {
|
||||
this.$emit('update', updatedSettings)
|
||||
this.$toast.success('Notification enabled')
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to update notification', error)
|
||||
this.$toast.error('Failed to update notification')
|
||||
this.$toast.error(this.$strings.ToastNotificationUpdateFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.enabling = false
|
||||
@ -139,7 +138,7 @@ export default {
|
||||
},
|
||||
deleteNotificationClick() {
|
||||
const payload = {
|
||||
message: `Are you sure you want to delete this notification?`,
|
||||
message: this.$strings.MessageConfirmDeleteNotification,
|
||||
callback: (confirmed) => {
|
||||
if (confirmed) {
|
||||
this.deleteNotification()
|
||||
@ -155,11 +154,10 @@ export default {
|
||||
.$delete(`/api/notifications/${this.notification.id}`)
|
||||
.then((updatedSettings) => {
|
||||
this.$emit('update', updatedSettings)
|
||||
this.$toast.success('Deleted notification')
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed', error)
|
||||
this.$toast.error('Failed to delete notification')
|
||||
this.$toast.error(this.$strings.ToastNotificationDeleteFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.deleting = false
|
||||
@ -171,4 +169,4 @@ export default {
|
||||
},
|
||||
mounted() {}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
@ -111,7 +111,7 @@
|
||||
</div>
|
||||
|
||||
<div class="flex pt-4 px-2">
|
||||
<ui-btn v-if="hasOpenIDLink" small :loading="unlinkingFromOpenID" color="primary" type="button" class="mr-2" @click.stop="unlinkOpenID">Unlink OpenID</ui-btn>
|
||||
<ui-btn v-if="hasOpenIDLink" small :loading="unlinkingFromOpenID" color="primary" type="button" class="mr-2" @click.stop="unlinkOpenID">{{ $strings.ButtonUnlinkOpenId }}</ui-btn>
|
||||
<ui-btn v-if="isEditingRoot" small class="flex items-center" to="/account">{{ $strings.ButtonChangeRootPassword }}</ui-btn>
|
||||
<div class="flex-grow" />
|
||||
<ui-btn color="success" type="submit">{{ $strings.ButtonSubmit }}</ui-btn>
|
||||
@ -212,19 +212,19 @@ export default {
|
||||
},
|
||||
unlinkOpenID() {
|
||||
const payload = {
|
||||
message: 'Are you sure you want to unlink this user from OpenID?',
|
||||
message: this.$strings.MessageConfirmUnlinkOpenId,
|
||||
callback: (confirmed) => {
|
||||
if (confirmed) {
|
||||
this.unlinkingFromOpenID = true
|
||||
this.$axios
|
||||
.$patch(`/api/users/${this.account.id}/openid-unlink`)
|
||||
.then(() => {
|
||||
this.$toast.success('User unlinked from OpenID')
|
||||
this.$toast.success(this.$strings.ToastUnlinkOpenIdSuccess)
|
||||
this.show = false
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to unlink user from OpenID', error)
|
||||
this.$toast.error('Failed to unlink user from OpenID')
|
||||
this.$toast.error(this.$strings.ToastUnlinkOpenIdFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.unlinkingFromOpenID = false
|
||||
@ -265,15 +265,15 @@ export default {
|
||||
},
|
||||
submitForm() {
|
||||
if (!this.newUser.username) {
|
||||
this.$toast.error('Enter a username')
|
||||
this.$toast.error(this.$strings.ToastNewUserUsernameError)
|
||||
return
|
||||
}
|
||||
if (!this.newUser.permissions.accessAllLibraries && !this.newUser.librariesAccessible.length) {
|
||||
this.$toast.error('Must select at least one library')
|
||||
this.$toast.error(this.$strings.ToastNewUserLibraryError)
|
||||
return
|
||||
}
|
||||
if (!this.newUser.permissions.accessAllTags && !this.newUser.itemTagsSelected.length) {
|
||||
this.$toast.error('Must select at least one tag')
|
||||
this.$toast.error(this.$strings.ToastNewUserTagError)
|
||||
return
|
||||
}
|
||||
|
||||
@ -313,12 +313,12 @@ export default {
|
||||
this.processing = false
|
||||
console.error('Failed to update account', error)
|
||||
var errMsg = error.response ? error.response.data || '' : ''
|
||||
this.$toast.error(errMsg || 'Failed to update account')
|
||||
this.$toast.error(errMsg || this.$strings.ToastFailedToUpdateAccount)
|
||||
})
|
||||
},
|
||||
submitCreateAccount() {
|
||||
if (!this.newUser.password) {
|
||||
this.$toast.error('Must have a password, only root user can have an empty password')
|
||||
this.$toast.error(this.$strings.ToastNewUserPasswordError)
|
||||
return
|
||||
}
|
||||
|
||||
@ -329,9 +329,9 @@ export default {
|
||||
.then((data) => {
|
||||
this.processing = false
|
||||
if (data.error) {
|
||||
this.$toast.error(`Failed to create account: ${data.error}`)
|
||||
this.$toast.error(this.$strings.ToastNewUserCreatedFailed + ': ' + data.error)
|
||||
} else {
|
||||
this.$toast.success('New account created')
|
||||
this.$toast.success(this.$strings.ToastNewUserCreatedSuccess)
|
||||
this.show = false
|
||||
}
|
||||
})
|
||||
|
@ -2,7 +2,7 @@
|
||||
<modals-modal ref="modal" v-model="show" name="custom-metadata-provider" :width="600" :height="'unset'" :processing="processing">
|
||||
<template #outer>
|
||||
<div class="absolute top-0 left-0 p-5 w-2/3 overflow-hidden">
|
||||
<p class="text-3xl text-white truncate">Add custom metadata provider</p>
|
||||
<p class="text-3xl text-white truncate">{{ $strings.HeaderAddCustomMetadataProvider }}</p>
|
||||
</div>
|
||||
</template>
|
||||
<form @submit.prevent="submitForm">
|
||||
@ -20,7 +20,7 @@
|
||||
<ui-text-input-with-label v-model="newUrl" label="URL" />
|
||||
</div>
|
||||
<div class="w-full mb-2 p-1">
|
||||
<ui-text-input-with-label v-model="newAuthHeaderValue" :label="'Authorization Header Value'" type="password" />
|
||||
<ui-text-input-with-label v-model="newAuthHeaderValue" :label="$strings.LabelProviderAuthorizationValue" type="password" />
|
||||
</div>
|
||||
<div class="flex px-1 pt-4">
|
||||
<div class="flex-grow" />
|
||||
@ -67,7 +67,7 @@ export default {
|
||||
methods: {
|
||||
submitForm() {
|
||||
if (!this.newName || !this.newUrl) {
|
||||
this.$toast.error('Must add name and url')
|
||||
this.$toast.error(this.$strings.ToastProviderNameAndUrlRequired)
|
||||
return
|
||||
}
|
||||
|
||||
@ -81,13 +81,13 @@ export default {
|
||||
})
|
||||
.then((data) => {
|
||||
this.$emit('added', data.provider)
|
||||
this.$toast.success('New provider added')
|
||||
this.$toast.success(this.$strings.ToastProviderCreatedSuccess)
|
||||
this.show = false
|
||||
})
|
||||
.catch((error) => {
|
||||
const errorMsg = error.response?.data || 'Unknown error'
|
||||
console.error('Failed to add provider', error)
|
||||
this.$toast.error('Failed to add provider: ' + errorMsg)
|
||||
this.$toast.error(this.$strings.ToastProviderCreatedFailed + ': ' + errorMsg)
|
||||
})
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
|
@ -4,7 +4,7 @@
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="text-base text-gray-200 truncate">{{ metadata.filename }}</p>
|
||||
<ui-btn v-if="ffprobeData" small class="ml-2" @click="ffprobeData = null">{{ $strings.ButtonReset }}</ui-btn>
|
||||
<ui-btn v-else-if="userIsAdminOrUp" small :loading="probingFile" class="ml-2" @click="getFFProbeData">Probe Audio File</ui-btn>
|
||||
<ui-btn v-else-if="userIsAdminOrUp" small :loading="probingFile" class="ml-2" @click="getFFProbeData">{{ $strings.ButtonProbeAudioFile }}</ui-btn>
|
||||
</div>
|
||||
|
||||
<div class="w-full h-px bg-white bg-opacity-10 my-4" />
|
||||
@ -159,7 +159,7 @@ export default {
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to get ffprobe data', error)
|
||||
this.$toast.error('FFProbe failed')
|
||||
this.$toast.error(this.$strings.ToastFailedToLoadData)
|
||||
})
|
||||
.finally(() => {
|
||||
this.probingFile = false
|
||||
|
@ -9,7 +9,7 @@
|
||||
<widgets-cron-expression-builder ref="expressionBuilder" v-model="newCronExpression" @input="expressionUpdated" />
|
||||
|
||||
<div class="flex items-center justify-end">
|
||||
<ui-btn :disabled="!isUpdated" @click="submit">{{ isUpdated ? $strings.ButtonSave : $strings.MessageNoUpdateNecessary }}</ui-btn>
|
||||
<ui-btn :disabled="!isUpdated" @click="submit">{{ isUpdated ? $strings.ButtonSave : $strings.MessageNoUpdatesWereNecessary }}</ui-btn>
|
||||
</div>
|
||||
</div>
|
||||
</modals-modal>
|
||||
|
@ -94,7 +94,7 @@ export default {
|
||||
this.$toast.success(this.$strings.ToastBookmarkRemoveSuccess)
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$toast.error(this.$strings.ToastBookmarkRemoveFailed)
|
||||
this.$toast.error(this.$strings.ToastRemoveFailed)
|
||||
console.error(error)
|
||||
})
|
||||
this.show = false
|
||||
|
@ -100,7 +100,7 @@
|
||||
|
||||
<div class="flex items-center">
|
||||
<ui-btn v-if="!isOpenSession && !isMediaItemShareSession" small color="error" @click.stop="deleteSessionClick">{{ $strings.ButtonDelete }}</ui-btn>
|
||||
<ui-btn v-else-if="!isMediaItemShareSession" small color="error" @click.stop="closeSessionClick">Close Open Session</ui-btn>
|
||||
<ui-btn v-else-if="!isMediaItemShareSession" small color="error" @click.stop="closeSessionClick">{{ $strings.ButtonCloseSession }}</ui-btn>
|
||||
</div>
|
||||
</div>
|
||||
</modals-modal>
|
||||
@ -206,14 +206,13 @@ export default {
|
||||
this.$axios
|
||||
.$post(`/api/session/${this._session.id}/close`)
|
||||
.then(() => {
|
||||
this.$toast.success('Session closed')
|
||||
this.show = false
|
||||
this.$emit('closedSession')
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to close session', error)
|
||||
const errMsg = error.response?.data || ''
|
||||
this.$toast.error(errMsg || 'Failed to close open session')
|
||||
this.$toast.error(errMsg || this.$strings.ToastSessionCloseFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
|
@ -165,7 +165,7 @@ export default {
|
||||
},
|
||||
openShare() {
|
||||
if (!this.newShareSlug) {
|
||||
this.$toast.error('Slug is required')
|
||||
this.$toast.error(this.$strings.ToastSlugRequired)
|
||||
return
|
||||
}
|
||||
const payload = {
|
||||
|
@ -15,7 +15,7 @@
|
||||
</template>
|
||||
<form class="flex items-center justify-center px-6 py-3" @submit.prevent="submitCustomTime">
|
||||
<ui-text-input v-model="customTime" type="number" step="any" min="0.1" :placeholder="$strings.LabelTimeInMinutes" class="w-48" />
|
||||
<ui-btn color="success" type="submit" :padding-x="0" class="h-9 w-12 flex items-center justify-center ml-1">Set</ui-btn>
|
||||
<ui-btn color="success" type="submit" :padding-x="0" class="h-9 w-18 flex items-center justify-center ml-1">{{ $strings.ButtonSubmit }}</ui-btn>
|
||||
</form>
|
||||
</div>
|
||||
<div v-if="timerSet" class="w-full p-4">
|
||||
|
@ -78,14 +78,13 @@ export default {
|
||||
if (data.error) {
|
||||
this.$toast.error(data.error)
|
||||
} else {
|
||||
this.$toast.success('Cover Uploaded')
|
||||
this.resetCoverPreview()
|
||||
}
|
||||
this.processingUpload = false
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed', error)
|
||||
var errorMsg = error.response && error.response.data ? error.response.data : 'Unknown Error'
|
||||
var errorMsg = error.response && error.response.data ? error.response.data : this.$strings.ToastUnknownError
|
||||
this.$toast.error(errorMsg)
|
||||
this.processingUpload = false
|
||||
})
|
||||
@ -95,7 +94,7 @@ export default {
|
||||
|
||||
var success = await this.$axios.$post(`/api/${this.entity}/${this.entityId}/cover`, { url: this.imageUrl }).catch((error) => {
|
||||
console.error('Failed to download cover from url', error)
|
||||
var errorMsg = error.response && error.response.data ? error.response.data : 'Unknown Error'
|
||||
var errorMsg = error.response && error.response.data ? error.response.data : this.$strings.ToastUnknownError
|
||||
this.$toast.error(errorMsg)
|
||||
return false
|
||||
})
|
||||
@ -104,4 +103,4 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
@ -116,12 +116,12 @@ export default {
|
||||
this.$axios
|
||||
.$delete(`/api/authors/${this.authorId}`)
|
||||
.then(() => {
|
||||
this.$toast.success('Author removed')
|
||||
this.$toast.success(this.$strings.ToastAuthorRemoveSuccess)
|
||||
this.show = false
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to remove author', error)
|
||||
this.$toast.error('Failed to remove author')
|
||||
this.$toast.error(this.$strings.ToastRemoveFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
@ -141,7 +141,7 @@ export default {
|
||||
}
|
||||
})
|
||||
if (!Object.keys(updatePayload).length) {
|
||||
this.$toast.info(this.$strings.MessageNoUpdateNecessary)
|
||||
this.$toast.info(this.$strings.ToastNoUpdatesNecessary)
|
||||
return
|
||||
}
|
||||
this.processing = true
|
||||
@ -158,7 +158,7 @@ export default {
|
||||
} else if (result.merged) {
|
||||
this.$toast.success(this.$strings.ToastAuthorUpdateMerged)
|
||||
this.show = false
|
||||
} else this.$toast.info(this.$strings.MessageNoUpdatesWereNecessary)
|
||||
} else this.$toast.info(this.$strings.ToastNoUpdatesNecessary)
|
||||
}
|
||||
this.processing = false
|
||||
},
|
||||
@ -174,7 +174,7 @@ export default {
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed', error)
|
||||
this.$toast.error(this.$strings.ToastAuthorImageRemoveFailed)
|
||||
this.$toast.error(this.$strings.ToastRemoveFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
@ -182,7 +182,7 @@ export default {
|
||||
},
|
||||
submitUploadCover() {
|
||||
if (!this.imageUrl?.startsWith('http:') && !this.imageUrl?.startsWith('https:')) {
|
||||
this.$toast.error('Invalid image url')
|
||||
this.$toast.error(this.$strings.ToastInvalidImageUrl)
|
||||
return
|
||||
}
|
||||
|
||||
@ -194,14 +194,14 @@ export default {
|
||||
.$post(`/api/authors/${this.authorId}/image`, updatePayload)
|
||||
.then((data) => {
|
||||
this.imageUrl = ''
|
||||
this.$toast.success('Author image updated')
|
||||
this.$toast.success(this.$strings.ToastAuthorUpdateSuccess)
|
||||
|
||||
this.authorCopy.updatedAt = data.author.updatedAt
|
||||
this.authorCopy.imagePath = data.author.imagePath
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed', error)
|
||||
this.$toast.error(error.response.data || 'Failed to remove author image')
|
||||
this.$toast.error(error.response.data || this.$strings.ToastRemoveFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
@ -209,7 +209,7 @@ export default {
|
||||
},
|
||||
async searchAuthor() {
|
||||
if (!this.authorCopy.name && !this.authorCopy.asin) {
|
||||
this.$toast.error('Must enter an author name')
|
||||
this.$toast.error(this.$strings.ToastNameRequired)
|
||||
return
|
||||
}
|
||||
this.processing = true
|
||||
@ -228,17 +228,19 @@ export default {
|
||||
return null
|
||||
})
|
||||
if (!response) {
|
||||
this.$toast.error('Author not found')
|
||||
this.$toast.error(this.$strings.ToastAuthorSearchNotFound)
|
||||
} else if (response.updated) {
|
||||
if (response.author.imagePath) {
|
||||
this.$toast.success(this.$strings.ToastAuthorUpdateSuccess)
|
||||
} else this.$toast.success(this.$strings.ToastAuthorUpdateSuccessNoImageFound)
|
||||
} else {
|
||||
this.$toast.success(this.$strings.ToastAuthorUpdateSuccessNoImageFound)
|
||||
}
|
||||
|
||||
this.authorCopy = {
|
||||
...response.author
|
||||
}
|
||||
} else {
|
||||
this.$toast.info('No updates were made for Author')
|
||||
this.$toast.info(this.$strings.ToastNoUpdatesNecessary)
|
||||
}
|
||||
this.processing = false
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ export default {
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to remove books from collection', error)
|
||||
this.$toast.error(this.$strings.ToastCollectionItemsRemoveFailed)
|
||||
this.$toast.error(this.$strings.ToastRemoveFailed)
|
||||
this.processing = false
|
||||
})
|
||||
} else {
|
||||
@ -157,7 +157,7 @@ export default {
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to remove book from collection', error)
|
||||
this.$toast.error(this.$strings.ToastCollectionItemsRemoveFailed)
|
||||
this.$toast.error(this.$strings.ToastRemoveFailed)
|
||||
this.processing = false
|
||||
})
|
||||
}
|
||||
@ -172,12 +172,12 @@ export default {
|
||||
.$post(`/api/collections/${collection.id}/batch/add`, { books: this.selectedBookIds })
|
||||
.then((updatedCollection) => {
|
||||
console.log(`Books added to collection`, updatedCollection)
|
||||
this.$toast.success('Books added to collection')
|
||||
this.$toast.success(this.$strings.ToastCollectionItemsAddSuccess)
|
||||
this.processing = false
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to add books to collection', error)
|
||||
this.$toast.error('Failed to add books to collection')
|
||||
this.$toast.error(this.$strings.ToastCollectionItemsAddFailed)
|
||||
this.processing = false
|
||||
})
|
||||
} else {
|
||||
@ -187,12 +187,12 @@ export default {
|
||||
.$post(`/api/collections/${collection.id}/book`, { id: this.selectedLibraryItemId })
|
||||
.then((updatedCollection) => {
|
||||
console.log(`Book added to collection`, updatedCollection)
|
||||
this.$toast.success('Book added to collection')
|
||||
this.$toast.success(this.$strings.ToastCollectionItemsAddSuccess)
|
||||
this.processing = false
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to add book to collection', error)
|
||||
this.$toast.error('Failed to add book to collection')
|
||||
this.$toast.error(this.$strings.ToastCollectionItemsAddFailed)
|
||||
this.processing = false
|
||||
})
|
||||
}
|
||||
@ -221,7 +221,7 @@ export default {
|
||||
.catch((error) => {
|
||||
console.error('Failed to create collection', error)
|
||||
var errMsg = error.response ? error.response.data || '' : ''
|
||||
this.$toast.error(`Failed to create collection: ${errMsg}`)
|
||||
this.$toast.error(this.$strings.ToastCollectionCreateFailed + ': ' + errMsg)
|
||||
this.processing = false
|
||||
})
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ export default {
|
||||
.catch((error) => {
|
||||
console.error('Failed to remove collection', error)
|
||||
this.processing = false
|
||||
this.$toast.error(this.$strings.ToastCollectionRemoveFailed)
|
||||
this.$toast.error(this.$strings.ToastRemoveFailed)
|
||||
})
|
||||
}
|
||||
},
|
||||
@ -115,7 +115,7 @@ export default {
|
||||
return
|
||||
}
|
||||
if (!this.newCollectionName) {
|
||||
return this.$toast.error('Collection must have a name')
|
||||
return this.$toast.error(this.$strings.ToastNameRequired)
|
||||
}
|
||||
|
||||
this.processing = true
|
||||
|
@ -125,12 +125,12 @@ export default {
|
||||
this.$refs.ereaderEmailInput.blur()
|
||||
|
||||
if (!this.newDevice.name?.trim() || !this.newDevice.email?.trim()) {
|
||||
this.$toast.error('Name and email required')
|
||||
this.$toast.error(this.$strings.ToastNameEmailRequired)
|
||||
return
|
||||
}
|
||||
|
||||
if (this.newDevice.availabilityOption === 'specificUsers' && !this.newDevice.users.length) {
|
||||
this.$toast.error('Must select at least one user')
|
||||
this.$toast.error(this.$strings.ToastSelectAtLeastOneUser)
|
||||
return
|
||||
}
|
||||
if (this.newDevice.availabilityOption !== 'specificUsers') {
|
||||
@ -142,14 +142,14 @@ export default {
|
||||
|
||||
if (!this.ereaderDevice) {
|
||||
if (this.existingDevices.some((d) => d.name === this.newDevice.name)) {
|
||||
this.$toast.error('Ereader device with that name already exists')
|
||||
this.$toast.error(this.$strings.ToastDeviceNameAlreadyExists)
|
||||
return
|
||||
}
|
||||
|
||||
this.submitCreate()
|
||||
} else {
|
||||
if (this.ereaderDevice.name !== this.newDevice.name && this.existingDevices.some((d) => d.name === this.newDevice.name)) {
|
||||
this.$toast.error('Ereader device with that name already exists')
|
||||
this.$toast.error(this.$strings.ToastDeviceNameAlreadyExists)
|
||||
return
|
||||
}
|
||||
|
||||
@ -174,12 +174,11 @@ export default {
|
||||
.$post(`/api/emails/ereader-devices`, payload)
|
||||
.then((data) => {
|
||||
this.$emit('update', data.ereaderDevices)
|
||||
this.$toast.success('Device updated')
|
||||
this.show = false
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to update device', error)
|
||||
this.$toast.error('Failed to update device')
|
||||
this.$toast.error(this.$strings.ToastDeviceUpdateFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
@ -201,12 +200,11 @@ export default {
|
||||
.$post('/api/emails/ereader-devices', payload)
|
||||
.then((data) => {
|
||||
this.$emit('update', data.ereaderDevices || [])
|
||||
this.$toast.success('Device added')
|
||||
this.show = false
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to add device', error)
|
||||
this.$toast.error('Failed to add device')
|
||||
this.$toast.error(this.$strings.ToastDeviceAddFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
|
@ -194,7 +194,6 @@ export default {
|
||||
if (data.error) {
|
||||
this.$toast.error(data.error)
|
||||
} else {
|
||||
this.$toast.success('Cover Uploaded')
|
||||
this.resetCoverPreview()
|
||||
}
|
||||
this.processingUpload = false
|
||||
@ -204,7 +203,7 @@ export default {
|
||||
if (error.response && error.response.data) {
|
||||
this.$toast.error(error.response.data)
|
||||
} else {
|
||||
this.$toast.error('Oops, something went wrong...')
|
||||
this.$toast.error(this.$strings.ToastUnknownError)
|
||||
}
|
||||
this.processingUpload = false
|
||||
})
|
||||
@ -255,7 +254,7 @@ export default {
|
||||
},
|
||||
async updateCover(cover) {
|
||||
if (!cover.startsWith('http:') && !cover.startsWith('https:')) {
|
||||
this.$toast.error('Invalid URL')
|
||||
this.$toast.error(this.$strings.ToastInvalidUrl)
|
||||
return
|
||||
}
|
||||
|
||||
@ -264,11 +263,10 @@ export default {
|
||||
.$post(`/api/items/${this.libraryItemId}/cover`, { url: cover })
|
||||
.then(() => {
|
||||
this.imageUrl = ''
|
||||
this.$toast.success('Update Successful')
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to update cover', error)
|
||||
this.$toast.error(error.response?.data || 'Failed to update cover')
|
||||
this.$toast.error(error.response?.data || this.$strings.ToastCoverUpdateFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.isProcessing = false
|
||||
@ -308,12 +306,9 @@ export default {
|
||||
this.isProcessing = true
|
||||
this.$axios
|
||||
.$patch(`/api/items/${this.libraryItemId}/cover`, { cover: coverFile.metadata.path })
|
||||
.then(() => {
|
||||
this.$toast.success('Update Successful')
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to set local cover', error)
|
||||
this.$toast.error(error.response?.data || 'Failed to set cover')
|
||||
this.$toast.error(error.response?.data || this.$strings.ToastCoverUpdateFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.isProcessing = false
|
||||
@ -321,4 +316,4 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
@ -92,7 +92,7 @@ export default {
|
||||
|
||||
var { title, author } = this.$refs.itemDetailsEdit.getTitleAndAuthorName()
|
||||
if (!title) {
|
||||
this.$toast.error('Must have a title for quick match')
|
||||
this.$toast.error(this.$strings.ToastTitleRequired)
|
||||
return
|
||||
}
|
||||
this.quickMatching = true
|
||||
@ -108,9 +108,9 @@ export default {
|
||||
if (res.warning) {
|
||||
this.$toast.warning(res.warning)
|
||||
} else if (res.updated) {
|
||||
this.$toast.success('Item details updated')
|
||||
this.$toast.success(this.$strings.ToastNoUpdatesNecessary)
|
||||
} else {
|
||||
this.$toast.info('No updates were made')
|
||||
this.$toast.info(this.$strings.ToastItemDetailsUpdateUnneeded)
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
@ -128,18 +128,18 @@ export default {
|
||||
this.rescanning = false
|
||||
var result = data.result
|
||||
if (!result) {
|
||||
this.$toast.error(`Re-Scan Failed for "${this.title}"`)
|
||||
this.$toast.error(this.$getString('ToastRescanFailed', [this.title]))
|
||||
} else if (result === 'UPDATED') {
|
||||
this.$toast.success(`Re-Scan complete item was updated`)
|
||||
this.$toast.success(this.$strings.ToastRescanUpdated)
|
||||
} else if (result === 'UPTODATE') {
|
||||
this.$toast.success(`Re-Scan complete item was up to date`)
|
||||
this.$toast.success(this.$strings.ToastRescanUpToDate)
|
||||
} else if (result === 'REMOVED') {
|
||||
this.$toast.error(`Re-Scan complete item was removed`)
|
||||
this.$toast.error(this.$strings.ToastRescanRemoved)
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to scan library item', error)
|
||||
this.$toast.error('Failed to scan library item')
|
||||
this.$toast.error(this.$strings.ToastScanFailed)
|
||||
this.rescanning = false
|
||||
})
|
||||
},
|
||||
@ -156,7 +156,7 @@ export default {
|
||||
}
|
||||
var updatedDetails = this.$refs.itemDetailsEdit.getDetails()
|
||||
if (!updatedDetails.hasChanges) {
|
||||
this.$toast.info('No changes were made')
|
||||
this.$toast.info(this.$strings.MessageNoUpdatesWereNecessary)
|
||||
return false
|
||||
}
|
||||
return this.updateDetails(updatedDetails)
|
||||
@ -170,7 +170,7 @@ export default {
|
||||
this.isProcessing = false
|
||||
if (updateResult) {
|
||||
if (updateResult.updated) {
|
||||
this.$toast.success('Item details updated')
|
||||
this.$toast.success(this.$strings.MessageItemDetailsUpdated)
|
||||
return true
|
||||
} else {
|
||||
this.$toast.info(this.$strings.MessageNoUpdatesWereNecessary)
|
||||
@ -217,4 +217,4 @@ export default {
|
||||
height: calc(100% - 80px);
|
||||
max-height: calc(100% - 80px);
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -397,7 +397,7 @@ export default {
|
||||
},
|
||||
submitSearch() {
|
||||
if (!this.searchTitle) {
|
||||
this.$toast.warning('Search title is required')
|
||||
this.$toast.warning(this.$strings.ToastTitleRequired)
|
||||
return
|
||||
}
|
||||
this.persistProvider()
|
||||
@ -618,7 +618,7 @@ export default {
|
||||
if (updateResult.updated) {
|
||||
this.$toast.success(this.$strings.ToastItemDetailsUpdateSuccess)
|
||||
} else {
|
||||
this.$toast.info(this.$strings.ToastItemDetailsUpdateUnneeded)
|
||||
this.$toast.info(this.$strings.ToastNoUpdatesNecessary)
|
||||
}
|
||||
this.clearSelectedMatch()
|
||||
this.$emit('selectTab', 'details')
|
||||
|
@ -163,7 +163,7 @@ export default {
|
||||
this.isProcessing = false
|
||||
if (updateResult) {
|
||||
if (updateResult.updated) {
|
||||
this.$toast.success('Item details updated')
|
||||
this.$toast.success(this.$strings.ToastItemDetailsUpdateSuccess)
|
||||
return true
|
||||
} else {
|
||||
this.$toast.info(this.$strings.MessageNoUpdatesWereNecessary)
|
||||
|
@ -156,7 +156,7 @@ export default {
|
||||
},
|
||||
validate() {
|
||||
if (!this.libraryCopy.name) {
|
||||
this.$toast.error('Library must have a name')
|
||||
this.$toast.error(this.$strings.ToastNameRequired)
|
||||
return false
|
||||
}
|
||||
if (!this.libraryCopy.folders.length) {
|
||||
@ -205,7 +205,7 @@ export default {
|
||||
submitUpdateLibrary() {
|
||||
var newLibraryPayload = this.getLibraryUpdatePayload()
|
||||
if (!Object.keys(newLibraryPayload).length) {
|
||||
this.$toast.info('No updates are necessary')
|
||||
this.$toast.info(this.$strings.ToastNoUpdatesNecessary)
|
||||
return
|
||||
}
|
||||
|
||||
@ -264,4 +264,4 @@ export default {
|
||||
.tab.tab-selected {
|
||||
height: 41px;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -162,7 +162,7 @@ export default {
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to get filesystem paths', error)
|
||||
this.$toast.error('Failed to get filesystem paths')
|
||||
this.$toast.error(this.$strings.ToastFailedToLoadData)
|
||||
return []
|
||||
})
|
||||
.finally(() => {
|
||||
|
@ -78,4 +78,4 @@ export default {
|
||||
},
|
||||
mounted() {}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
@ -86,7 +86,7 @@ export default {
|
||||
return this.selectedEventData && this.selectedEventData.requiresLibrary
|
||||
},
|
||||
title() {
|
||||
return this.isNew ? 'Create Notification' : 'Update Notification'
|
||||
return this.isNew ? this.$strings.HeaderNotificationCreate : this.$strings.HeaderNotificationUpdate
|
||||
},
|
||||
availableVariables() {
|
||||
return this.selectedEventData ? this.selectedEventData.variables || null : null
|
||||
@ -104,9 +104,9 @@ export default {
|
||||
},
|
||||
submitForm() {
|
||||
this.$refs.urlsInput?.forceBlur()
|
||||
|
||||
|
||||
if (!this.newNotification.urls.length) {
|
||||
this.$toast.error('Must enter an Apprise URL')
|
||||
this.$toast.error(this.$strings.ToastAppriseUrlRequired)
|
||||
return
|
||||
}
|
||||
|
||||
@ -127,12 +127,12 @@ export default {
|
||||
.$patch(`/api/notifications/${payload.id}`, payload)
|
||||
.then((updatedSettings) => {
|
||||
this.$emit('update', updatedSettings)
|
||||
this.$toast.success('Notification updated')
|
||||
this.$toast.success(this.$strings.ToastNotificationUpdateSuccess)
|
||||
this.show = false
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to update notification', error)
|
||||
this.$toast.error('Failed to update notification')
|
||||
this.$toast.error(this.$strings.ToastNotificationUpdateFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
@ -149,12 +149,11 @@ export default {
|
||||
.$post('/api/notifications', payload)
|
||||
.then((updatedSettings) => {
|
||||
this.$emit('update', updatedSettings)
|
||||
this.$toast.success('Notification created')
|
||||
this.show = false
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to create notification', error)
|
||||
this.$toast.error('Failed to create notification')
|
||||
this.$toast.error(this.$strings.ToastNotificationCreateFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
|
@ -130,12 +130,12 @@ export default {
|
||||
.$post(`/api/playlists/${playlist.id}/batch/remove`, { items: itemObjects })
|
||||
.then((updatedPlaylist) => {
|
||||
console.log(`Items removed from playlist`, updatedPlaylist)
|
||||
this.$toast.success('Playlist item(s) removed')
|
||||
this.$toast.success(this.$strings.ToastPlaylistUpdateSuccess)
|
||||
this.processing = false
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to remove items from playlist', error)
|
||||
this.$toast.error('Failed to remove playlist item(s)')
|
||||
this.$toast.error(this.$strings.ToastPlaylistUpdateFailed)
|
||||
this.processing = false
|
||||
})
|
||||
},
|
||||
@ -148,12 +148,12 @@ export default {
|
||||
.$post(`/api/playlists/${playlist.id}/batch/add`, { items: itemObjects })
|
||||
.then((updatedPlaylist) => {
|
||||
console.log(`Items added to playlist`, updatedPlaylist)
|
||||
this.$toast.success('Items added to playlist')
|
||||
this.$toast.success(this.$strings.ToastPlaylistUpdateSuccess)
|
||||
this.processing = false
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to add items to playlist', error)
|
||||
this.$toast.error('Failed to add items to playlist')
|
||||
this.$toast.error(this.$strings.ToastPlaylistUpdateFailed)
|
||||
this.processing = false
|
||||
})
|
||||
},
|
||||
@ -174,14 +174,14 @@ export default {
|
||||
.$post('/api/playlists', newPlaylist)
|
||||
.then((data) => {
|
||||
console.log('New playlist created', data)
|
||||
this.$toast.success(`Playlist "${data.name}" created`)
|
||||
this.$toast.success(this.$strings.ToastPlaylistCreateSuccess + ': ' + data.name)
|
||||
this.processing = false
|
||||
this.newPlaylistName = ''
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to create playlist', error)
|
||||
var errMsg = error.response ? error.response.data || '' : ''
|
||||
this.$toast.error(`Failed to create playlist: ${errMsg}`)
|
||||
this.$toast.error(this.$strings.ToastPlaylistCreateFailed + ': ' + errMsg)
|
||||
this.processing = false
|
||||
})
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ export default {
|
||||
.catch((error) => {
|
||||
console.error('Failed to remove playlist', error)
|
||||
this.processing = false
|
||||
this.$toast.error(this.$strings.ToastPlaylistRemoveFailed)
|
||||
this.$toast.error(this.$strings.ToastRemoveFailed)
|
||||
})
|
||||
}
|
||||
},
|
||||
@ -95,7 +95,7 @@ export default {
|
||||
return
|
||||
}
|
||||
if (!this.newPlaylistName) {
|
||||
return this.$toast.error('Playlist must have a name')
|
||||
return this.$toast.error(this.$strings.ToastNameRequired)
|
||||
}
|
||||
|
||||
this.processing = true
|
||||
|
@ -142,7 +142,7 @@ export default {
|
||||
|
||||
const updatedDetails = this.getUpdatePayload()
|
||||
if (!Object.keys(updatedDetails).length) {
|
||||
this.$toast.info('No changes were made')
|
||||
this.$toast.info(this.$strings.ToastNoUpdatesNecessary)
|
||||
return false
|
||||
}
|
||||
return this.updateDetails(updatedDetails)
|
||||
|
@ -105,7 +105,7 @@ export default {
|
||||
}
|
||||
const updatePayload = this.getUpdatePayload(episodeData)
|
||||
if (!Object.keys(updatePayload).length) {
|
||||
return this.$toast.info('No updates are necessary')
|
||||
return this.$toast.info(this.$strings.ToastNoUpdatesNecessary)
|
||||
}
|
||||
console.log('Episode update payload', updatePayload)
|
||||
|
||||
@ -126,7 +126,7 @@ export default {
|
||||
},
|
||||
submitForm() {
|
||||
if (!this.episodeTitle || !this.episodeTitle.length) {
|
||||
this.$toast.error('Must enter an episode title')
|
||||
this.$toast.error(this.$strings.ToastTitleRequired)
|
||||
return
|
||||
}
|
||||
this.searchedTitle = this.episodeTitle
|
||||
|
@ -121,14 +121,14 @@ export default {
|
||||
methods: {
|
||||
openFeed() {
|
||||
if (!this.newFeedSlug) {
|
||||
this.$toast.error('Must set a feed slug')
|
||||
this.$toast.error(this.$strings.ToastSlugRequired)
|
||||
return
|
||||
}
|
||||
|
||||
const sanitized = this.$sanitizeSlug(this.newFeedSlug)
|
||||
if (this.newFeedSlug !== sanitized) {
|
||||
this.newFeedSlug = sanitized
|
||||
this.$toast.warning('Slug had to be modified - Run again')
|
||||
this.$toast.warning(this.$strings.ToastSlugMustChange)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -261,7 +261,7 @@ export default {
|
||||
.catch((error) => {
|
||||
console.error('Failed to share', error)
|
||||
if (error.name !== 'AbortError') {
|
||||
this.$toast.error('Failed to share: ' + error.message)
|
||||
this.$toast.error(this.$strings.ToastFailedToShare + ': ' + error.message)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
|
@ -237,7 +237,7 @@ export default {
|
||||
.catch((error) => {
|
||||
console.error('Failed to share', error)
|
||||
if (error.name !== 'AbortError') {
|
||||
this.$toast.error('Failed to share: ' + error.message)
|
||||
this.$toast.error(this.$strings.ToastFailedToShare + ': ' + error.message)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
|
@ -167,7 +167,7 @@ export default {
|
||||
.catch((error) => {
|
||||
console.error('Failed to share', error)
|
||||
if (error.name !== 'AbortError') {
|
||||
this.$toast.error('Failed to share: ' + error.message)
|
||||
this.$toast.error(this.$strings.ToastFailedToShare + ': ' + error.message)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
|
@ -186,7 +186,7 @@ export default {
|
||||
mounted() {
|
||||
this.loadBackups()
|
||||
if (this.$route.query.backup) {
|
||||
this.$toast.success('Backup applied successfully')
|
||||
this.$toast.success(this.$strings.ToastBackupAppliedSuccess)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ export default {
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to update collection', error)
|
||||
this.$toast.error('Failed to save collection books order')
|
||||
this.$toast.error(this.$strings.ToastCollectionUpdateFailed)
|
||||
})
|
||||
},
|
||||
editBook(book) {
|
||||
@ -110,4 +110,4 @@ export default {
|
||||
.collection-book-leave-active {
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -45,7 +45,7 @@ export default {
|
||||
methods: {
|
||||
removeProvider(provider) {
|
||||
const payload = {
|
||||
message: `Are you sure you want remove custom metadata provider "${provider.name}"?`,
|
||||
message: this.$getString('MessageConfirmDeleteMetadataProvider', [provider.name]),
|
||||
callback: (confirmed) => {
|
||||
if (confirmed) {
|
||||
this.$emit('update:processing', true)
|
||||
@ -53,12 +53,12 @@ export default {
|
||||
this.$axios
|
||||
.$delete(`/api/custom-metadata-providers/${provider.id}`)
|
||||
.then(() => {
|
||||
this.$toast.success('Provider removed')
|
||||
this.$toast.success(this.$strings.ToastProviderRemoveSuccess)
|
||||
this.$emit('removed', provider.id)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to remove provider', error)
|
||||
this.$toast.error('Failed to remove provider')
|
||||
this.$toast.error(this.$strings.ToastRemoveFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.$emit('update:processing', false)
|
||||
|
@ -92,7 +92,7 @@ export default {
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to update playlist', error)
|
||||
this.$toast.error('Failed to save playlist items order')
|
||||
this.$toast.error(this.$strings.ToastPlaylistUpdateFailed)
|
||||
})
|
||||
},
|
||||
init() {
|
||||
@ -119,4 +119,4 @@ export default {
|
||||
.playlist-item-leave-active {
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -218,12 +218,12 @@ export default {
|
||||
this.$toast.success(this.$strings.ToastPlaylistRemoveSuccess)
|
||||
} else {
|
||||
console.log(`Item removed from playlist`, updatedPlaylist)
|
||||
this.$toast.success('Item removed from playlist')
|
||||
this.$toast.success(this.$strings.ToastPlaylistUpdateSuccess)
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to remove item from playlist', error)
|
||||
this.$toast.error('Failed to remove item from playlist')
|
||||
this.$toast.error(this.$strings.ToastPlaylistUpdateFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.processingRemove = false
|
||||
|
@ -270,7 +270,7 @@ export default {
|
||||
if (data.numEpisodesUpdated) {
|
||||
this.$toast.success(`${data.numEpisodesUpdated} episodes updated`)
|
||||
} else {
|
||||
this.$toast.info('No changes were made')
|
||||
this.$toast.info(this.$strings.ToastNoUpdatesNecessary)
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
@ -295,7 +295,7 @@ export default {
|
||||
episodeId: episode.id,
|
||||
title: episode.title,
|
||||
subtitle: this.mediaMetadata.title,
|
||||
caption: episode.publishedAt ? `Published ${this.$formatDate(episode.publishedAt, this.dateFormat)}` : 'Unknown publish date',
|
||||
caption: episode.publishedAt ? this.$getString('LabelPublishedDate', [this.$formatDate(episode.publishedAt, this.dateFormat)]) : this.$strings.LabelUnknownPublishDate,
|
||||
duration: episode.audioFile.duration || null,
|
||||
coverPath: this.media.coverPath || null
|
||||
}
|
||||
@ -372,7 +372,7 @@ export default {
|
||||
episodeId: episode.id,
|
||||
title: episode.title,
|
||||
subtitle: this.mediaMetadata.title,
|
||||
caption: episode.publishedAt ? `Published ${this.$formatDate(episode.publishedAt, this.dateFormat)}` : 'Unknown publish date',
|
||||
caption: episode.publishedAt ? this.$getString('LabelPublishedDate', [this.$formatDate(episode.publishedAt, this.dateFormat)]) : this.$strings.LabelUnknownPublishDate,
|
||||
duration: episode.audioFile.duration || null,
|
||||
coverPath: this.media.coverPath || null
|
||||
})
|
||||
|
@ -7,7 +7,7 @@
|
||||
<div class="absolute top-0 mt-1 w-3 h-3 rounded-full bg-green-500"></div>
|
||||
<div class="absolute top-0 mt-1 w-3 h-3 rounded-full bg-green-500"></div>
|
||||
</div>
|
||||
<div class="text-gray-200 text-xs font-light mt-2 text-center">{{ text }}</div>
|
||||
<div class="text-gray-200 text-xs font-light mt-2 text-center">{{ message }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -17,7 +17,12 @@ export default {
|
||||
props: {
|
||||
text: {
|
||||
type: String,
|
||||
default: 'Please Wait...'
|
||||
default: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
message() {
|
||||
return this.text || this.$strings.MessagePleaseWait
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -67,4 +72,4 @@ export default {
|
||||
transform: translate(24px, 0);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -117,10 +117,10 @@ export default {
|
||||
},
|
||||
submitChangePassword() {
|
||||
if (this.newPassword !== this.confirmPassword) {
|
||||
return this.$toast.error('New password and confirm password do not match')
|
||||
return this.$toast.error(this.$strings.ToastUserPasswordMismatch)
|
||||
}
|
||||
if (this.password === this.newPassword) {
|
||||
return this.$toast.error('Password and New Password cannot be the same')
|
||||
return this.$toast.error(this.$strings.ToastUserPasswordMustChange)
|
||||
}
|
||||
this.changingPassword = true
|
||||
this.$axios
|
||||
@ -130,16 +130,16 @@ export default {
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
this.$toast.success('Password Changed Successfully')
|
||||
this.$toast.success(this.$strings.ToastUserPasswordChangeSuccess)
|
||||
this.resetForm()
|
||||
} else {
|
||||
this.$toast.error(res.error || 'Unknown Error')
|
||||
this.$toast.error(res.error || this.$strings.ToastUnknownError)
|
||||
}
|
||||
this.changingPassword = false
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error)
|
||||
this.$toast.error('Api call failed')
|
||||
this.$toast.error(this.$strings.ToastUnknownError)
|
||||
this.changingPassword = false
|
||||
})
|
||||
}
|
||||
@ -148,4 +148,4 @@ export default {
|
||||
this.selectedLanguage = this.$languageCodes.current
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
@ -560,7 +560,7 @@ export default {
|
||||
.catch((error) => {
|
||||
this.findingChapters = false
|
||||
console.error('Failed to get chapter data', error)
|
||||
this.$toast.error('Failed to find chapters')
|
||||
this.$toast.error(this.$strings.ToastFailedToLoadData)
|
||||
this.showFindChaptersModal = false
|
||||
})
|
||||
},
|
||||
@ -611,7 +611,7 @@ export default {
|
||||
.$post(`/api/items/${this.libraryItem.id}/chapters`, payload)
|
||||
.then((data) => {
|
||||
if (data.updated) {
|
||||
this.$toast.success('Chapters removed')
|
||||
this.$toast.success(this.$strings.ToastChaptersRemoved)
|
||||
if (this.previousRoute) {
|
||||
this.$router.push(this.previousRoute)
|
||||
} else {
|
||||
@ -623,7 +623,7 @@ export default {
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to remove chapters', error)
|
||||
this.$toast.error('Failed to remove chapters')
|
||||
this.$toast.error(this.$strings.ToastRemoveFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.saving = false
|
||||
|
@ -331,11 +331,11 @@ export default {
|
||||
this.$axios
|
||||
.$delete(`/api/tools/item/${this.libraryItemId}/encode-m4b`)
|
||||
.then(() => {
|
||||
this.$toast.success('Encode canceled')
|
||||
this.$toast.success(this.$strings.ToastEncodeCancelSucces)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to cancel encode', error)
|
||||
this.$toast.error('Failed to cancel encode')
|
||||
this.$toast.error(this.$strings.ToastEncodeCancelFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.isCancelingEncode = false
|
||||
|
@ -366,7 +366,7 @@ export default {
|
||||
}
|
||||
}
|
||||
if (!updates.length) {
|
||||
return this.$toast.warning('No updates were made')
|
||||
return this.$toast.warning(this.$strings.ToastNoUpdatesNecessary)
|
||||
}
|
||||
|
||||
console.log('Pushing updates', updates)
|
||||
@ -406,4 +406,4 @@ export default {
|
||||
transform: translateY(-100%);
|
||||
transition: all 150ms ease-in 0s;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -162,7 +162,7 @@ export default {
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to save backup path', error)
|
||||
const errorMsg = error.response?.data || 'Failed to save backup path'
|
||||
const errorMsg = error.response?.data || this.$strings.ToastBackupPathUpdateFailed
|
||||
this.$toast.error(errorMsg)
|
||||
})
|
||||
.finally(() => {
|
||||
@ -171,11 +171,11 @@ export default {
|
||||
},
|
||||
updateBackupsSettings() {
|
||||
if (isNaN(this.maxBackupSize) || this.maxBackupSize < 0) {
|
||||
this.$toast.error('Invalid maximum backup size')
|
||||
this.$toast.error(this.$strings.ToastBackupInvalidMaxSize)
|
||||
return
|
||||
}
|
||||
if (isNaN(this.backupsToKeep) || this.backupsToKeep <= 0 || this.backupsToKeep > 99) {
|
||||
this.$toast.error('Invalid number of backups to keep')
|
||||
this.$toast.error(this.$strings.ToastBackupInvalidMaxKeep)
|
||||
return
|
||||
}
|
||||
const updatePayload = {
|
||||
|
@ -109,7 +109,7 @@
|
||||
</tr>
|
||||
</table>
|
||||
<div v-else-if="!loading" class="text-center py-4">
|
||||
<p class="text-lg text-gray-100">No Devices</p>
|
||||
<p class="text-lg text-gray-100">{{ $strings.MessageNoDevices }}</p>
|
||||
</div>
|
||||
</app-settings-content>
|
||||
|
||||
@ -199,7 +199,7 @@ export default {
|
||||
},
|
||||
deleteDeviceClick(device) {
|
||||
const payload = {
|
||||
message: `Are you sure you want to delete e-reader device "${device.name}"?`,
|
||||
message: this.$getString('MessageConfirmDeleteDevice', [device.name]),
|
||||
callback: (confirmed) => {
|
||||
if (confirmed) {
|
||||
this.deleteDevice(device)
|
||||
@ -218,11 +218,10 @@ export default {
|
||||
.$post(`/api/emails/ereader-devices`, payload)
|
||||
.then((data) => {
|
||||
this.ereaderDevicesUpdated(data.ereaderDevices)
|
||||
this.$toast.success('Device deleted')
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to delete device', error)
|
||||
this.$toast.error('Failed to delete device')
|
||||
this.$toast.error(this.$strings.ToastRemoveFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.deletingDeviceName = null
|
||||
@ -246,11 +245,11 @@ export default {
|
||||
this.$axios
|
||||
.$post('/api/emails/test')
|
||||
.then(() => {
|
||||
this.$toast.success('Test Email Sent')
|
||||
this.$toast.success(this.$strings.ToastDeviceTestEmailSuccess)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to send test email', error)
|
||||
const errorMsg = error.response.data || 'Failed to send test email'
|
||||
const errorMsg = error.response.data || this.$strings.ToastDeviceTestEmailFailed
|
||||
this.$toast.error(errorMsg)
|
||||
})
|
||||
.finally(() => {
|
||||
@ -289,11 +288,11 @@ export default {
|
||||
this.newSettings = {
|
||||
...data.settings
|
||||
}
|
||||
this.$toast.success('Email settings updated')
|
||||
this.$toast.success(this.$strings.ToastEmailSettingsUpdateSuccess)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to update email settings', error)
|
||||
this.$toast.error('Failed to update email settings')
|
||||
this.$toast.error(this.$strings.ToastEmailSettingsUpdateFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.savingSettings = false
|
||||
|
@ -130,7 +130,7 @@ export default {
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to rename genre', error)
|
||||
this.$toast.error('Failed to rename genre')
|
||||
this.$toast.error(this.$strings.ToastRenameFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
@ -147,7 +147,7 @@ export default {
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to remove genre', error)
|
||||
this.$toast.error('Failed to remove genre')
|
||||
this.$toast.error(this.$strings.ToastRemoveFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
|
@ -126,7 +126,7 @@ export default {
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to rename tag', error)
|
||||
this.$toast.error('Failed to rename tag')
|
||||
this.$toast.error(this.$strings.ToastRenameFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
@ -143,7 +143,7 @@ export default {
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to remove tag', error)
|
||||
this.$toast.error('Failed to remove tag')
|
||||
this.$toast.error(this.$strings.ToastRemoveFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
|
@ -105,12 +105,12 @@ export default {
|
||||
}
|
||||
|
||||
if (isNaN(this.maxNotificationQueue) || this.maxNotificationQueue <= 0) {
|
||||
this.$toast.error('Max notification queue must be >= 0')
|
||||
this.$toast.error(this.$strings.ToastNotificationQueueMaximum)
|
||||
return false
|
||||
}
|
||||
|
||||
if (isNaN(this.maxFailedAttempts) || this.maxFailedAttempts <= 0) {
|
||||
this.$toast.error('Max failed attempts must be >= 0')
|
||||
this.$toast.error(this.$strings.ToastNotificationFailedMaximum)
|
||||
return false
|
||||
}
|
||||
|
||||
@ -128,11 +128,11 @@ export default {
|
||||
this.$axios
|
||||
.$patch('/api/notifications', updatePayload)
|
||||
.then(() => {
|
||||
this.$toast.success('Notification settings updated')
|
||||
this.$toast.success(this.$strings.ToastNotificationSettingsUpdateSuccess)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to update notification settings', error)
|
||||
this.$toast.error('Failed to update notification settings')
|
||||
this.$toast.error(this.$strings.ToastNotificationSettingsUpdateFailed)
|
||||
})
|
||||
.finally(() => {
|
||||
this.savingSettings = false
|
||||
|
@ -290,7 +290,6 @@ export default {
|
||||
this.$axios
|
||||
.$post(`/api/sessions/batch/delete`, payload)
|
||||
.then(() => {
|
||||
this.$toast.success('Sessions removed')
|
||||
if (isAllSessions) {
|
||||
// If all sessions were removed from the current page then go to the previous page
|
||||
if (this.currentPage > 0) {
|
||||
@ -303,7 +302,7 @@ export default {
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
const errorMsg = error.response?.data || 'Failed to remove sessions'
|
||||
const errorMsg = error.response?.data || this.$strings.ToastRemoveFailed
|
||||
this.$toast.error(errorMsg)
|
||||
})
|
||||
.finally(() => {
|
||||
@ -358,12 +357,13 @@ export default {
|
||||
})
|
||||
|
||||
if (!libraryItem) {
|
||||
this.$toast.error('Failed to get library item')
|
||||
this.$toast.error(this.$strings.ToastFailedToLoadData)
|
||||
this.processingGoToTimestamp = false
|
||||
return
|
||||
}
|
||||
if (session.episodeId && !libraryItem.media.episodes.some((ep) => ep.id === session.episodeId)) {
|
||||
this.$toast.error('Failed to get podcast episode')
|
||||
console.error('Episode not found in library item', session.episodeId, libraryItem.media.episodes)
|
||||
this.$toast.error(this.$strings.ToastFailedToLoadData)
|
||||
this.processingGoToTimestamp = false
|
||||
return
|
||||
}
|
||||
@ -377,7 +377,7 @@ export default {
|
||||
episodeId: episode.id,
|
||||
title: episode.title,
|
||||
subtitle: libraryItem.media.metadata.title,
|
||||
caption: episode.publishedAt ? `Published ${this.$formatDate(episode.publishedAt, this.dateFormat)}` : 'Unknown publish date',
|
||||
caption: episode.publishedAt ? this.$getString('LabelPublishedDate', [this.$formatDate(episode.publishedAt, this.dateFormat)]) : this.$strings.LabelUnknownPublishDate,
|
||||
duration: episode.audioFile.duration || null,
|
||||
coverPath: libraryItem.media.coverPath || null
|
||||
}
|
||||
|
@ -127,12 +127,13 @@ export default {
|
||||
})
|
||||
|
||||
if (!libraryItem) {
|
||||
this.$toast.error('Failed to get library item')
|
||||
this.$toast.error(this.$strings.ToastFailedToLoadData)
|
||||
this.processingGoToTimestamp = false
|
||||
return
|
||||
}
|
||||
if (session.episodeId && !libraryItem.media.episodes.some((ep) => ep.id === session.episodeId)) {
|
||||
this.$toast.error('Failed to get podcast episode')
|
||||
console.error('Episode not found in library item', session.episodeId, libraryItem.media.episodes)
|
||||
this.$toast.error(this.$strings.ToastFailedToLoadData)
|
||||
this.processingGoToTimestamp = false
|
||||
return
|
||||
}
|
||||
@ -146,7 +147,7 @@ export default {
|
||||
episodeId: episode.id,
|
||||
title: episode.title,
|
||||
subtitle: libraryItem.media.metadata.title,
|
||||
caption: episode.publishedAt ? `Published ${this.$formatDate(episode.publishedAt, this.dateFormat)}` : 'Unknown publish date',
|
||||
caption: episode.publishedAt ? this.$getString('LabelPublishedDate', [this.$formatDate(episode.publishedAt, this.dateFormat)]) : this.$strings.LabelUnknownPublishDate,
|
||||
duration: episode.audioFile.duration || null,
|
||||
coverPath: libraryItem.media.coverPath || null
|
||||
}
|
||||
|
@ -484,23 +484,23 @@ export default {
|
||||
this.$axios
|
||||
.$get(`/api/podcasts/${this.libraryItemId}/clear-queue`)
|
||||
.then(() => {
|
||||
this.$toast.success('Episode download queue cleared')
|
||||
this.$toast.success(this.$strings.ToastEpisodeDownloadQueueClearSuccess)
|
||||
this.episodeDownloadQueued = []
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to clear queue', error)
|
||||
this.$toast.error('Failed to clear queue')
|
||||
this.$toast.error(this.$strings.ToastEpisodeDownloadQueueClearFailed)
|
||||
})
|
||||
}
|
||||
},
|
||||
async findEpisodesClick() {
|
||||
if (!this.mediaMetadata.feedUrl) {
|
||||
return this.$toast.error('Podcast does not have an RSS Feed')
|
||||
return this.$toast.error(this.$strings.ToastNoRSSFeed)
|
||||
}
|
||||
this.fetchingRSSFeed = true
|
||||
var payload = await this.$axios.$post(`/api/podcasts/feed`, { rssFeed: this.mediaMetadata.feedUrl }).catch((error) => {
|
||||
console.error('Failed to get feed', error)
|
||||
this.$toast.error('Failed to get podcast feed')
|
||||
this.$toast.error(this.$strings.ToastPodcastGetFeedFailed)
|
||||
return null
|
||||
})
|
||||
this.fetchingRSSFeed = false
|
||||
@ -509,7 +509,7 @@ export default {
|
||||
console.log('Podcast feed', payload)
|
||||
const podcastfeed = payload.podcast
|
||||
if (!podcastfeed.episodes || !podcastfeed.episodes.length) {
|
||||
this.$toast.info('No episodes found in RSS feed')
|
||||
this.$toast.info(this.$strings.ToastPodcastNoEpisodesInFeed)
|
||||
return
|
||||
}
|
||||
|
||||
@ -578,7 +578,7 @@ export default {
|
||||
episodeId: episode.id,
|
||||
title: episode.title,
|
||||
subtitle: this.title,
|
||||
caption: episode.publishedAt ? `Published ${this.$formatDate(episode.publishedAt, this.dateFormat)}` : 'Unknown publish date',
|
||||
caption: episode.publishedAt ? this.$getString('LabelPublishedDate', [this.$formatDate(episode.publishedAt, this.dateFormat)]) : this.$strings.LabelUnknownPublishDate,
|
||||
duration: episode.audioFile.duration || null,
|
||||
coverPath: this.libraryItem.media.coverPath || null
|
||||
})
|
||||
@ -622,13 +622,12 @@ export default {
|
||||
},
|
||||
clearProgressClick() {
|
||||
if (!this.userMediaProgress) return
|
||||
if (confirm(`Are you sure you want to reset your progress?`)) {
|
||||
if (confirm(this.$strings.MessageConfirmResetProgress)) {
|
||||
this.resettingProgress = true
|
||||
this.$axios
|
||||
.$delete(`/api/me/progress/${this.userMediaProgress.id}`)
|
||||
.then(() => {
|
||||
console.log('Progress reset complete')
|
||||
this.$toast.success(`Your progress was reset`)
|
||||
this.resettingProgress = false
|
||||
})
|
||||
.catch((error) => {
|
||||
@ -722,12 +721,12 @@ export default {
|
||||
this.$axios
|
||||
.$delete(`/api/items/${this.libraryItemId}?hard=${hardDelete ? 1 : 0}`)
|
||||
.then(() => {
|
||||
this.$toast.success('Item deleted')
|
||||
this.$toast.success(this.$strings.ToastItemDeletedSuccess)
|
||||
this.$router.replace(`/library/${this.libraryId}`)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to delete item', error)
|
||||
this.$toast.error('Failed to delete item')
|
||||
this.$toast.error(this.$strings.ToastItemDeleteFailed)
|
||||
})
|
||||
}
|
||||
},
|
||||
|
@ -138,7 +138,7 @@ export default {
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to remove narrator', error)
|
||||
this.$toast.error('Failed to remove narrator')
|
||||
this.$toast.error(this.$strings.ToastRemoveFailed)
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
@ -158,4 +158,4 @@ export default {
|
||||
},
|
||||
beforeDestroy() {}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
@ -111,7 +111,7 @@ export default {
|
||||
this.processing = true
|
||||
const queuePayload = await this.$axios.$get(`/api/libraries/${this.libraryId}/episode-downloads`).catch((error) => {
|
||||
console.error('Failed to get download queue', error)
|
||||
this.$toast.error('Failed to get download queue')
|
||||
this.$toast.error(this.$strings.ToastFailedToLoadData)
|
||||
return null
|
||||
})
|
||||
this.processing = false
|
||||
|
@ -234,7 +234,7 @@ export default {
|
||||
episodeId: episode.id,
|
||||
title: episode.title,
|
||||
subtitle: episode.podcast.metadata.title,
|
||||
caption: episode.publishedAt ? `Published ${this.$formatDate(episode.publishedAt, this.dateFormat)}` : 'Unknown publish date',
|
||||
caption: episode.publishedAt ? this.$getString('LabelPublishedDate', [this.$formatDate(episode.publishedAt, this.dateFormat)]) : this.$strings.LabelUnknownPublishDate,
|
||||
duration: episode.duration || null,
|
||||
coverPath: episode.podcast.coverPath || null
|
||||
})
|
||||
@ -251,7 +251,7 @@ export default {
|
||||
this.processing = true
|
||||
const episodePayload = await this.$axios.$get(`/api/libraries/${this.libraryId}/recent-episodes?limit=25&page=${page}`).catch((error) => {
|
||||
console.error('Failed to get recent episodes', error)
|
||||
this.$toast.error('Failed to get recent episodes')
|
||||
this.$toast.error(this.$strings.ToastFailedToLoadData)
|
||||
return null
|
||||
})
|
||||
this.processing = false
|
||||
@ -271,7 +271,7 @@ export default {
|
||||
episodeId: episode.id,
|
||||
title: episode.title,
|
||||
subtitle: episode.podcast.metadata.title,
|
||||
caption: episode.publishedAt ? `Published ${this.$formatDate(episode.publishedAt, this.dateFormat)}` : 'Unknown publish date',
|
||||
caption: episode.publishedAt ? this.$getString('LabelPublishedDate', [this.$formatDate(episode.publishedAt, this.dateFormat)]) : this.$strings.LabelUnknownPublishDate,
|
||||
duration: episode.duration || null,
|
||||
coverPath: episode.podcast.coverPath || null
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ export default {
|
||||
this.processing = true
|
||||
var payload = await this.$axios.$post(`/api/podcasts/feed`, { rssFeed }).catch((error) => {
|
||||
console.error('Failed to get feed', error)
|
||||
this.$toast.error('Failed to get podcast feed')
|
||||
this.$toast.error(this.$strings.ToastPodcastGetFeedFailed)
|
||||
return null
|
||||
})
|
||||
this.processing = false
|
||||
@ -197,7 +197,7 @@ export default {
|
||||
this.processing = true
|
||||
const payload = await this.$axios.$post(`/api/podcasts/feed`, { rssFeed: podcast.feedUrl }).catch((error) => {
|
||||
console.error('Failed to get feed', error)
|
||||
this.$toast.error('Failed to get podcast feed')
|
||||
this.$toast.error(this.$strings.ToastPodcastGetFeedFailed)
|
||||
return null
|
||||
})
|
||||
this.processing = false
|
||||
|
@ -132,11 +132,11 @@ export default {
|
||||
methods: {
|
||||
async submitServerSetup() {
|
||||
if (!this.newRoot.username || !this.newRoot.username.trim()) {
|
||||
this.$toast.error('Must enter a root username')
|
||||
this.$toast.error(this.$strings.ToastUserRootRequireName)
|
||||
return
|
||||
}
|
||||
if (this.newRoot.password !== this.confirmPassword) {
|
||||
this.$toast.error('Password mismatch')
|
||||
this.$toast.error(this.$strings.ToastUserPasswordMismatch)
|
||||
return
|
||||
}
|
||||
if (!this.newRoot.password) {
|
||||
|
@ -19,6 +19,7 @@
|
||||
"ButtonChooseFiles": "Choose files",
|
||||
"ButtonClearFilter": "Clear Filter",
|
||||
"ButtonCloseFeed": "Close Feed",
|
||||
"ButtonCloseSession": "Close Open Session",
|
||||
"ButtonCollections": "Collections",
|
||||
"ButtonConfigureScanner": "Configure Scanner",
|
||||
"ButtonCreate": "Create",
|
||||
@ -28,6 +29,9 @@
|
||||
"ButtonEdit": "Edit",
|
||||
"ButtonEditChapters": "Edit Chapters",
|
||||
"ButtonEditPodcast": "Edit Podcast",
|
||||
"ButtonEnable": "Enable",
|
||||
"ButtonFireAndFail": "Fire and Fail",
|
||||
"ButtonFireOnTest": "Fire onTest event",
|
||||
"ButtonForceReScan": "Force Re-Scan",
|
||||
"ButtonFullPath": "Full Path",
|
||||
"ButtonHide": "Hide",
|
||||
@ -56,6 +60,7 @@
|
||||
"ButtonPlaylists": "Playlists",
|
||||
"ButtonPrevious": "Previous",
|
||||
"ButtonPreviousChapter": "Previous Chapter",
|
||||
"ButtonProbeAudioFile": "Probe Audio File",
|
||||
"ButtonPurgeAllCache": "Purge All Cache",
|
||||
"ButtonPurgeItemsCache": "Purge Items Cache",
|
||||
"ButtonQueueAddItem": "Add to queue",
|
||||
@ -93,6 +98,7 @@
|
||||
"ButtonStats": "Stats",
|
||||
"ButtonSubmit": "Submit",
|
||||
"ButtonTest": "Test",
|
||||
"ButtonUnlinkOpedId": "Unlink OpenID",
|
||||
"ButtonUpload": "Upload",
|
||||
"ButtonUploadBackup": "Upload Backup",
|
||||
"ButtonUploadCover": "Upload Cover",
|
||||
@ -105,6 +111,7 @@
|
||||
"ErrorUploadFetchMetadataNoResults": "Could not fetch metadata - try updating title and/or author",
|
||||
"ErrorUploadLacksTitle": "Must have a title",
|
||||
"HeaderAccount": "Account",
|
||||
"HeaderAddCustomMetadataProvider": "Add Custom Metadata Provider",
|
||||
"HeaderAdvanced": "Advanced",
|
||||
"HeaderAppriseNotificationSettings": "Apprise Notification Settings",
|
||||
"HeaderAudioTracks": "Audio Tracks",
|
||||
@ -150,6 +157,8 @@
|
||||
"HeaderMetadataToEmbed": "Metadata to embed",
|
||||
"HeaderNewAccount": "New Account",
|
||||
"HeaderNewLibrary": "New Library",
|
||||
"HeaderNotificationCreate": "Create Notification",
|
||||
"HeaderNotificationUpdate": "Update Notification",
|
||||
"HeaderNotifications": "Notifications",
|
||||
"HeaderOpenIDConnectAuthentication": "OpenID Connect Authentication",
|
||||
"HeaderOpenRSSFeed": "Open RSS Feed",
|
||||
@ -206,8 +215,8 @@
|
||||
"LabelAddToCollectionBatch": "Add {0} Books to Collection",
|
||||
"LabelAddToPlaylist": "Add to Playlist",
|
||||
"LabelAddToPlaylistBatch": "Add {0} Items to Playlist",
|
||||
"LabelAdded": "Added",
|
||||
"LabelAddedAt": "Added At",
|
||||
"LabelAddedDate": "Added {0}",
|
||||
"LabelAdminUsersOnly": "Admin users only",
|
||||
"LabelAll": "All",
|
||||
"LabelAllUsers": "All Users",
|
||||
@ -298,6 +307,7 @@
|
||||
"LabelEpisode": "Episode",
|
||||
"LabelEpisodeTitle": "Episode Title",
|
||||
"LabelEpisodeType": "Episode Type",
|
||||
"LabelEpisodes": "Episodes",
|
||||
"LabelExample": "Example",
|
||||
"LabelExpandSeries": "Expand Series",
|
||||
"LabelExpandSubSeries": "Expand Sub Series",
|
||||
@ -309,7 +319,9 @@
|
||||
"LabelFetchingMetadata": "Fetching Metadata",
|
||||
"LabelFile": "File",
|
||||
"LabelFileBirthtime": "File Birthtime",
|
||||
"LabelFileBornDate": "Born {0}",
|
||||
"LabelFileModified": "File Modified",
|
||||
"LabelFileModifiedDate": "Modified {0}",
|
||||
"LabelFilename": "Filename",
|
||||
"LabelFilterByUser": "Filter by User",
|
||||
"LabelFindEpisodes": "Find Episodes",
|
||||
@ -448,8 +460,10 @@
|
||||
"LabelPrimaryEbook": "Primary ebook",
|
||||
"LabelProgress": "Progress",
|
||||
"LabelProvider": "Provider",
|
||||
"LabelProviderAuthorizationValue": "Authorization Header Value",
|
||||
"LabelPubDate": "Pub Date",
|
||||
"LabelPublishYear": "Publish Year",
|
||||
"LabelPublishedDate": "Published {0}",
|
||||
"LabelPublisher": "Publisher",
|
||||
"LabelPublishers": "Publishers",
|
||||
"LabelRSSFeedCustomOwnerEmail": "Custom owner Email",
|
||||
@ -595,6 +609,7 @@
|
||||
"LabelUnabridged": "Unabridged",
|
||||
"LabelUndo": "Undo",
|
||||
"LabelUnknown": "Unknown",
|
||||
"LabelUnknownPublishDate": "Unknown publish date",
|
||||
"LabelUpdateCover": "Update Cover",
|
||||
"LabelUpdateCoverHelp": "Allow overwriting of existing covers for the selected books when a match is located",
|
||||
"LabelUpdateDetails": "Update Details",
|
||||
@ -643,16 +658,22 @@
|
||||
"MessageCheckingCron": "Checking cron...",
|
||||
"MessageConfirmCloseFeed": "Are you sure you want to close this feed?",
|
||||
"MessageConfirmDeleteBackup": "Are you sure you want to delete backup for {0}?",
|
||||
"MessageConfirmDeleteDevice": "Are you sure you want to delete e-reader device \"{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}\"?",
|
||||
"MessageConfirmDeleteLibraryItem": "This will delete the library item from the database and your file system. Are you sure?",
|
||||
"MessageConfirmDeleteLibraryItems": "This will delete {0} library items from the database and your file system. Are you sure?",
|
||||
"MessageConfirmDeleteMetadataProvider": "Are you sure you want to delete custom metadata provider \"{0}\"?",
|
||||
"MessageConfirmDeleteNotification": "Are you sure you want to delete this notification?",
|
||||
"MessageConfirmDeleteSession": "Are you sure you want to delete this session?",
|
||||
"MessageConfirmForceReScan": "Are you sure you want to force re-scan?",
|
||||
"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?",
|
||||
"MessageConfirmMarkItemFinished": "Are you sure you want to mark \"{0}\" as finished?",
|
||||
"MessageConfirmMarkItemNotFinished": "Are you sure you want to mark \"{0}\" as not finished?",
|
||||
"MessageConfirmMarkSeriesFinished": "Are you sure you want to mark all books in this series as finished?",
|
||||
"MessageConfirmMarkSeriesNotFinished": "Are you sure you want to mark all books in this series as not finished?",
|
||||
"MessageConfirmNotificationTestTrigger": "Trigger this notification with test data?",
|
||||
"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?",
|
||||
"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?",
|
||||
@ -671,7 +692,9 @@
|
||||
"MessageConfirmRenameTag": "Are you sure you want to rename tag \"{0}\" to \"{1}\" for all items?",
|
||||
"MessageConfirmRenameTagMergeNote": "Note: This tag already exists so they will be merged.",
|
||||
"MessageConfirmRenameTagWarning": "Warning! A similar tag with a different casing already exists \"{0}\".",
|
||||
"MessageConfirmResetProgress": "Are you sure you want to reset your progress?",
|
||||
"MessageConfirmSendEbookToDevice": "Are you sure you want to send {0} ebook \"{1}\" to device \"{2}\"?",
|
||||
"MessageConfirmUnlinkOpenId": "Are you sure you want to unlink this user from OpenID?",
|
||||
"MessageDownloadingEpisode": "Downloading episode",
|
||||
"MessageDragFilesIntoTrackOrder": "Drag files into correct track order",
|
||||
"MessageEmbedFailed": "Embed Failed!",
|
||||
@ -706,6 +729,7 @@
|
||||
"MessageNoCollections": "No Collections",
|
||||
"MessageNoCoversFound": "No Covers Found",
|
||||
"MessageNoDescription": "No description",
|
||||
"MessageNoDevices": "No devices",
|
||||
"MessageNoDownloadsInProgress": "No downloads currently in progress",
|
||||
"MessageNoDownloadsQueued": "No downloads queued",
|
||||
"MessageNoEpisodeMatchesFound": "No episode matches found",
|
||||
@ -725,7 +749,6 @@
|
||||
"MessageNoSeries": "No Series",
|
||||
"MessageNoTags": "No Tags",
|
||||
"MessageNoTasksRunning": "No Tasks Running",
|
||||
"MessageNoUpdateNecessary": "No update necessary",
|
||||
"MessageNoUpdatesWereNecessary": "No updates were necessary",
|
||||
"MessageNoUserPlaylists": "You have no playlists",
|
||||
"MessageNotYetImplemented": "Not yet implemented",
|
||||
@ -734,6 +757,7 @@
|
||||
"MessagePauseChapter": "Pause chapter playback",
|
||||
"MessagePlayChapter": "Listen to beginning of chapter",
|
||||
"MessagePlaylistCreateFromCollection": "Create playlist from collection",
|
||||
"MessagePleaseWait": "Please wait...",
|
||||
"MessagePodcastHasNoRSSFeedForMatching": "Podcast has no RSS feed url to use for matching",
|
||||
"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",
|
||||
@ -794,24 +818,32 @@
|
||||
"StatsYearInReview": "YEAR IN REVIEW",
|
||||
"ToastAccountUpdateFailed": "Failed to update account",
|
||||
"ToastAccountUpdateSuccess": "Account updated",
|
||||
"ToastAuthorImageRemoveFailed": "Failed to remove image",
|
||||
"ToastAppriseUrlRequired": "Must enter an Apprise URL",
|
||||
"ToastAuthorImageRemoveSuccess": "Author image removed",
|
||||
"ToastAuthorNotFound": "Author \"{0}\" not found",
|
||||
"ToastAuthorRemoveSuccess": "Author removed",
|
||||
"ToastAuthorSearchNotFound": "Author not found",
|
||||
"ToastAuthorUpdateFailed": "Failed to update author",
|
||||
"ToastAuthorUpdateMerged": "Author merged",
|
||||
"ToastAuthorUpdateSuccess": "Author updated",
|
||||
"ToastAuthorUpdateSuccessNoImageFound": "Author updated (no image found)",
|
||||
"ToastBackupAppliedSuccess": "Backup applied",
|
||||
"ToastBackupCreateFailed": "Failed to create backup",
|
||||
"ToastBackupCreateSuccess": "Backup created",
|
||||
"ToastBackupDeleteFailed": "Failed to delete backup",
|
||||
"ToastBackupDeleteSuccess": "Backup deleted",
|
||||
"ToastBackupInvalidMaxKeep": "Invalid number of backups to keep",
|
||||
"ToastBackupInvalidMaxSize": "Invalid maximum backup size",
|
||||
"ToastBackupPathUpdateFailed": "Failed to update backup path",
|
||||
"ToastBackupRestoreFailed": "Failed to restore backup",
|
||||
"ToastBackupUploadFailed": "Failed to upload backup",
|
||||
"ToastBackupUploadSuccess": "Backup uploaded",
|
||||
"ToastBatchDeleteFailed": "Batch delete failed",
|
||||
"ToastBatchDeleteSuccess": "Batch delete success",
|
||||
"ToastBatchUpdateFailed": "Batch update failed",
|
||||
"ToastBatchUpdateSuccess": "Batch update success",
|
||||
"ToastBookmarkCreateFailed": "Failed to create bookmark",
|
||||
"ToastBookmarkCreateSuccess": "Bookmark added",
|
||||
"ToastBookmarkRemoveFailed": "Failed to remove bookmark",
|
||||
"ToastBookmarkRemoveSuccess": "Bookmark removed",
|
||||
"ToastBookmarkUpdateFailed": "Failed to update bookmark",
|
||||
"ToastBookmarkUpdateSuccess": "Bookmark updated",
|
||||
@ -819,25 +851,46 @@
|
||||
"ToastCachePurgeSuccess": "Cache purged successfully",
|
||||
"ToastChaptersHaveErrors": "Chapters have errors",
|
||||
"ToastChaptersMustHaveTitles": "Chapters must have titles",
|
||||
"ToastCollectionItemsRemoveFailed": "Failed to remove item(s) from collection",
|
||||
"ToastChaptersRemoved": "Chapters removed",
|
||||
"ToastCollectionItemsAddFailed": "Item(s) added to collection failed",
|
||||
"ToastCollectionItemsAddSuccess": "Item(s) added to collection success",
|
||||
"ToastCollectionItemsRemoveSuccess": "Item(s) removed from collection",
|
||||
"ToastCollectionRemoveFailed": "Failed to remove collection",
|
||||
"ToastCollectionRemoveSuccess": "Collection removed",
|
||||
"ToastCollectionUpdateFailed": "Failed to update collection",
|
||||
"ToastCollectionUpdateSuccess": "Collection updated",
|
||||
"ToastCoverUpdateFailed": "Cover update failed",
|
||||
"ToastDeleteFileFailed": "Failed to delete file",
|
||||
"ToastDeleteFileSuccess": "File deleted",
|
||||
"ToastDeviceAddFailed": "Failed to add device",
|
||||
"ToastDeviceNameAlreadyExists": "Ereader device with that name already exists",
|
||||
"ToastDeviceTestEmailFailed": "Failed to send test email",
|
||||
"ToastDeviceTestEmailSuccess": "Test email sent",
|
||||
"ToastDeviceUpdateFailed": "Failed to update device",
|
||||
"ToastEmailSettingsUpdateFailed": "Failed to update email settings",
|
||||
"ToastEmailSettingsUpdateSuccess": "Email settings updated",
|
||||
"ToastEncodeCancelFailed": "Failed to cancel encode",
|
||||
"ToastEncodeCancelSucces": "Encode canceled",
|
||||
"ToastEpisodeDownloadQueueClearFailed": "Failed to clear queue",
|
||||
"ToastEpisodeDownloadQueueClearSuccess": "Episode download queue cleared",
|
||||
"ToastErrorCannotShare": "Cannot share natively on this device",
|
||||
"ToastFailedToLoadData": "Failed to load data",
|
||||
"ToastFailedToShare": "Failed to share",
|
||||
"ToastFailedToUpdateAccount": "Failed to update account",
|
||||
"ToastFailedToUpdateUser": "Failed to update user",
|
||||
"ToastInvalidImageUrl": "Invalid image URL",
|
||||
"ToastInvalidUrl": "Invalid URL",
|
||||
"ToastItemCoverUpdateFailed": "Failed to update item cover",
|
||||
"ToastItemCoverUpdateSuccess": "Item cover updated",
|
||||
"ToastItemDeletedFailed": "Failed to delete item",
|
||||
"ToastItemDeletedSuccess": "Deleted item",
|
||||
"ToastItemDetailsUpdateFailed": "Failed to update item details",
|
||||
"ToastItemDetailsUpdateSuccess": "Item details updated",
|
||||
"ToastItemDetailsUpdateUnneeded": "No updates needed for item details",
|
||||
"ToastItemMarkedAsFinishedFailed": "Failed to mark as Finished",
|
||||
"ToastItemMarkedAsFinishedSuccess": "Item marked as Finished",
|
||||
"ToastItemMarkedAsNotFinishedFailed": "Failed to mark as Not Finished",
|
||||
"ToastItemMarkedAsNotFinishedSuccess": "Item marked as Not Finished",
|
||||
"ToastItemUpdateFailed": "Failed to update item",
|
||||
"ToastItemUpdateSuccess": "Item updated",
|
||||
"ToastLibraryCreateFailed": "Failed to create library",
|
||||
"ToastLibraryCreateSuccess": "Library \"{0}\" created",
|
||||
"ToastLibraryDeleteFailed": "Failed to delete library",
|
||||
@ -846,32 +899,78 @@
|
||||
"ToastLibraryScanStarted": "Library scan started",
|
||||
"ToastLibraryUpdateFailed": "Failed to update library",
|
||||
"ToastLibraryUpdateSuccess": "Library \"{0}\" updated",
|
||||
"ToastNameEmailRequired": "Name and email are required",
|
||||
"ToastNameRequired": "Name is required",
|
||||
"ToastNewUserCreatedFailed": "Failed to create account: \"{0}\"",
|
||||
"ToastNewUserCreatedSuccess": "New account created",
|
||||
"ToastNewUserLibraryError": "Must select at least one library",
|
||||
"ToastNewUserPasswordError": "Must have a password, only root user can have an empty password",
|
||||
"ToastNewUserTagError": "Must select at least one tag",
|
||||
"ToastNewUserUsernameError": "Enter a username",
|
||||
"ToastNoUpdatesNecessary": "No updates necessary",
|
||||
"ToastNotificationCreateFailed": "Failed to create notification",
|
||||
"ToastNotificationDeleteFailed": "Failed to delete notification",
|
||||
"ToastNotificationFailedMaximum": "Max failed attempts must be >= 0",
|
||||
"ToastNotificationQueueMaximum": "Max notification queue must be >= 0",
|
||||
"ToastNotificationSettingsUpdateFailed": "Failed to update notification settings",
|
||||
"ToastNotificationSettingsUpdateSuccess": "Notification settings updated",
|
||||
"ToastNotificationTestTriggerFailed": "Failed to trigger test notification",
|
||||
"ToastNotificationTestTriggerSuccess": "Triggered test notification",
|
||||
"ToastNotificationUpdateFailed": "Failed to update notification",
|
||||
"ToastNotificationUpdateSuccess": "Notification updated",
|
||||
"ToastPlaylistCreateFailed": "Failed to create playlist",
|
||||
"ToastPlaylistCreateSuccess": "Playlist created",
|
||||
"ToastPlaylistRemoveFailed": "Failed to remove playlist",
|
||||
"ToastPlaylistRemoveSuccess": "Playlist removed",
|
||||
"ToastPlaylistUpdateFailed": "Failed to update playlist",
|
||||
"ToastPlaylistUpdateSuccess": "Playlist updated",
|
||||
"ToastPodcastCreateFailed": "Failed to create podcast",
|
||||
"ToastPodcastCreateSuccess": "Podcast created successfully",
|
||||
"ToastPodcastGetFeedFailed": "Failed to get podcast feed",
|
||||
"ToastPodcastNoEpisodesInFeed": "No episodes found in RSS feed",
|
||||
"ToastPodcastNoRssFeed": "Podcast does not have an RSS feed",
|
||||
"ToastProviderCreatedFailed": "Failed to add provider",
|
||||
"ToastProviderCreatedSuccess": "New provider added",
|
||||
"ToastProviderNameAndUrlRequired": "Name and Url required",
|
||||
"ToastProviderRemoveSuccess": "Provider removed",
|
||||
"ToastRSSFeedCloseFailed": "Failed to close RSS feed",
|
||||
"ToastRSSFeedCloseSuccess": "RSS feed closed",
|
||||
"ToastRemoveFailed": "Failed to remove",
|
||||
"ToastRemoveItemFromCollectionFailed": "Failed to remove item from collection",
|
||||
"ToastRemoveItemFromCollectionSuccess": "Item removed from collection",
|
||||
"ToastRemoveItemsWithIssuesFailed": "Failed to remove library items with issues",
|
||||
"ToastRemoveItemsWithIssuesSuccess": "Removed library items with issues",
|
||||
"ToastRenameFailed": "Failed to rename",
|
||||
"ToastRescanFailed": "Re-Scan Failed for {0}",
|
||||
"ToastRescanRemoved": "Re-Scan complete item was removed",
|
||||
"ToastRescanUpToDate": "Re-Scan complete item was up to date",
|
||||
"ToastRescanUpdated": "Re-Scan complete item was updated",
|
||||
"ToastScanFailed": "Failed to scan library item",
|
||||
"ToastSelectAtLeastOneUser": "Select at least one user",
|
||||
"ToastSendEbookToDeviceFailed": "Failed to send ebook to device",
|
||||
"ToastSendEbookToDeviceSuccess": "Ebook sent to device \"{0}\"",
|
||||
"ToastSeriesUpdateFailed": "Series update failed",
|
||||
"ToastSeriesUpdateSuccess": "Series update success",
|
||||
"ToastServerSettingsUpdateFailed": "Failed to update server settings",
|
||||
"ToastServerSettingsUpdateSuccess": "Server settings updated",
|
||||
"ToastSessionCloseFailed": "Failed to close session",
|
||||
"ToastSessionDeleteFailed": "Failed to delete session",
|
||||
"ToastSessionDeleteSuccess": "Session deleted",
|
||||
"ToastSlugMustChange": "Slug contains invalid characters",
|
||||
"ToastSlugRequired": "Slug is required",
|
||||
"ToastSocketConnected": "Socket connected",
|
||||
"ToastSocketDisconnected": "Socket disconnected",
|
||||
"ToastSocketFailedToConnect": "Socket failed to connect",
|
||||
"ToastSortingPrefixesEmptyError": "Must have at least 1 sorting prefix",
|
||||
"ToastSortingPrefixesUpdateFailed": "Failed to update sorting prefixes",
|
||||
"ToastSortingPrefixesUpdateSuccess": "Sorting prefixes updated ({0} items)",
|
||||
"ToastTitleRequired": "Title is required",
|
||||
"ToastUnknownError": "Unknown error",
|
||||
"ToastUnlinkOpenIdFailed": "Failed to unlink user from OpenID",
|
||||
"ToastUnlinkOpenIdSuccess": "User unlinked from OpenID",
|
||||
"ToastUserDeleteFailed": "Failed to delete user",
|
||||
"ToastUserDeleteSuccess": "User deleted"
|
||||
"ToastUserDeleteSuccess": "User deleted",
|
||||
"ToastUserPasswordChangeSuccess": "Password changed successfully",
|
||||
"ToastUserPasswordMismatch": "Passwords do not match",
|
||||
"ToastUserPasswordMustChange": "New password cannot match old password",
|
||||
"ToastUserRootRequireName": "Must enter a root username"
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user