mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-01-04 18:19:37 +00:00
Update:More localization strings #1103
This commit is contained in:
parent
eb463a2958
commit
faac6f677a
46 changed files with 772 additions and 527 deletions
|
|
@ -2,15 +2,16 @@
|
|||
<div class="w-full h-full">
|
||||
<div class="bg-bg rounded-md shadow-lg border border-white border-opacity-5 p-4 mb-8">
|
||||
<div class="flex items-center mb-2">
|
||||
<h1 class="text-xl">Backups</h1>
|
||||
<h1 class="text-xl">{{ $strings.HeaderBackups }}</h1>
|
||||
</div>
|
||||
|
||||
<p class="text-base mb-4 text-gray-300">Backups include users, user progress, library item details, server settings, and images stored in <span class="font-mono text-gray-100">/metadata/items</span> & <span class="font-mono text-gray-100">/metadata/authors</span>. <br />Backups <strong>do not</strong> include any files stored in your library folders.</p>
|
||||
<p class="text-base mb-2 text-gray-300">{{ $strings.MessageBackupsDescription }} <span class="font-mono text-gray-100">/metadata/items</span> & <span class="font-mono text-gray-100">/metadata/authors</span>.</p>
|
||||
<p class="text-base mb-4 text-gray-300">{{ $strings.MessageBackupsNote }}</p>
|
||||
|
||||
<div class="flex items-center py-2">
|
||||
<ui-toggle-switch v-model="enableBackups" small :disabled="updatingServerSettings" @input="updateBackupsSettings" />
|
||||
<ui-tooltip :text="backupsTooltip">
|
||||
<p class="pl-4 text-lg">Enable automatic backups <span class="material-icons icon-text">info_outlined</span></p>
|
||||
<ui-tooltip :text="$strings.LabelBackupsEnableAutomaticBackupsHelp">
|
||||
<p class="pl-4 text-lg">{{ $strings.LabelBackupsEnableAutomaticBackups }} <span class="material-icons icon-text">info_outlined</span></p>
|
||||
</ui-tooltip>
|
||||
</div>
|
||||
|
||||
|
|
@ -25,16 +26,16 @@
|
|||
<div class="flex items-center py-2">
|
||||
<ui-text-input type="number" v-model="backupsToKeep" no-spinner :disabled="updatingServerSettings" :padding-x="1" text-center class="w-10" @change="updateBackupsSettings" />
|
||||
|
||||
<ui-tooltip :text="numBackupsToKeepTooltip">
|
||||
<p class="pl-4 text-lg">Number of backups to keep <span class="material-icons icon-text">info_outlined</span></p>
|
||||
<ui-tooltip :text="$strings.LabelBackupsNumberToKeepHelp">
|
||||
<p class="pl-4 text-lg">{{ $strings.LabelBackupsNumberToKeep }} <span class="material-icons icon-text">info_outlined</span></p>
|
||||
</ui-tooltip>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center py-2">
|
||||
<ui-text-input type="number" v-model="maxBackupSize" no-spinner :disabled="updatingServerSettings" :padding-x="1" text-center class="w-10" @change="updateBackupsSettings" />
|
||||
|
||||
<ui-tooltip :text="maxBackupSizeTooltip">
|
||||
<p class="pl-4 text-lg">Maximum backup size (in GB) <span class="material-icons icon-text">info_outlined</span></p>
|
||||
<ui-tooltip :text="$strings.LabelBackupsMaxBackupSizeHelp">
|
||||
<p class="pl-4 text-lg">{{ $strings.LabelBackupsMaxBackupSize }} <span class="material-icons icon-text">info_outlined</span></p>
|
||||
</ui-tooltip>
|
||||
</div>
|
||||
|
||||
|
|
@ -55,10 +56,7 @@ export default {
|
|||
maxBackupSize: 1,
|
||||
cronExpression: '',
|
||||
newServerSettings: {},
|
||||
showCronBuilder: false,
|
||||
backupsTooltip: 'Backups saved in /metadata/backups',
|
||||
numBackupsToKeepTooltip: 'Only 1 backup will be removed at a time so if you already have more backups than this you should manually remove them.',
|
||||
maxBackupSizeTooltip: 'As a safeguard against misconfiguration, backups will fail if they exceed the configured size.'
|
||||
showCronBuilder: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
|
|
|||
|
|
@ -109,9 +109,9 @@
|
|||
|
||||
<div class="flex items-center py-2">
|
||||
<ui-toggle-switch v-model="newServerSettings.scannerPreferOverdriveMediaMarker" :disabled="updatingServerSettings" @input="(val) => updateSettingsKey('scannerPreferOverdriveMediaMarker', val)" />
|
||||
<ui-tooltip :text="tooltips.scannerPreferOverdriveMediaMarker">
|
||||
<ui-tooltip :text="$strings.LabelSettingsOverdriveMediaMarkersHelp">
|
||||
<p class="pl-4">
|
||||
Use Overdrive Media Markers for chapters
|
||||
{{ $strings.LabelSettingsOverdriveMediaMarkers }}
|
||||
<span class="material-icons icon-text text-sm">info_outlined</span>
|
||||
</p>
|
||||
</ui-tooltip>
|
||||
|
|
@ -119,9 +119,9 @@
|
|||
|
||||
<div class="flex items-center py-2">
|
||||
<ui-toggle-switch v-model="newServerSettings.scannerPreferAudioMetadata" :disabled="updatingServerSettings" @input="(val) => updateSettingsKey('scannerPreferAudioMetadata', val)" />
|
||||
<ui-tooltip :text="tooltips.scannerPreferAudioMetadata">
|
||||
<ui-tooltip :text="$strings.LabelSettingsPreferAudioMetadataHelp">
|
||||
<p class="pl-4">
|
||||
Prefer audio metadata
|
||||
{{ $strings.LabelSettingsPreferAudioMetadata }}
|
||||
<span class="material-icons icon-text text-sm">info_outlined</span>
|
||||
</p>
|
||||
</ui-tooltip>
|
||||
|
|
@ -129,9 +129,9 @@
|
|||
|
||||
<div class="flex items-center py-2">
|
||||
<ui-toggle-switch v-model="newServerSettings.scannerPreferOpfMetadata" :disabled="updatingServerSettings" @input="(val) => updateSettingsKey('scannerPreferOpfMetadata', val)" />
|
||||
<ui-tooltip :text="tooltips.scannerPreferOpfMetadata">
|
||||
<ui-tooltip :text="$strings.LabelSettingsPreferOPFMetadataHelp">
|
||||
<p class="pl-4">
|
||||
Prefer OPF metadata
|
||||
{{ $strings.LabelSettingsPreferOPFMetadata }}
|
||||
<span class="material-icons icon-text text-sm">info_outlined</span>
|
||||
</p>
|
||||
</ui-tooltip>
|
||||
|
|
@ -139,9 +139,9 @@
|
|||
|
||||
<div class="flex items-center py-2">
|
||||
<ui-toggle-switch v-model="newServerSettings.scannerPreferMatchedMetadata" :disabled="updatingServerSettings" @input="(val) => updateSettingsKey('scannerPreferMatchedMetadata', val)" />
|
||||
<ui-tooltip :text="tooltips.scannerPreferMatchedMetadata">
|
||||
<ui-tooltip :text="$strings.LabelSettingsPreferMatchedMetadataHelp">
|
||||
<p class="pl-4">
|
||||
Prefer matched metadata
|
||||
{{ $strings.LabelSettingsPreferMatchedMetadata }}
|
||||
<span class="material-icons icon-text text-sm">info_outlined</span>
|
||||
</p>
|
||||
</ui-tooltip>
|
||||
|
|
@ -149,33 +149,23 @@
|
|||
|
||||
<div class="flex items-center py-2">
|
||||
<ui-toggle-switch v-model="newServerSettings.scannerDisableWatcher" :disabled="updatingServerSettings" @input="(val) => updateSettingsKey('scannerDisableWatcher', val)" />
|
||||
<ui-tooltip :text="tooltips.scannerDisableWatcher">
|
||||
<ui-tooltip :text="$strings.LabelSettingsDisableWatcherHelp">
|
||||
<p class="pl-4">
|
||||
Disable Watcher
|
||||
{{ $strings.LabelSettingsDisableWatcher }}
|
||||
<span class="material-icons icon-text text-sm">info_outlined</span>
|
||||
</p>
|
||||
</ui-tooltip>
|
||||
</div>
|
||||
|
||||
<!-- <div class="flex items-center py-2">
|
||||
<ui-text-input type="number" v-model="newServerSettings.scannerMaxThreads" no-spinner :disabled="updatingServerSettings" :padding-x="1" text-center class="w-10" @change="updateScannerMaxThreads" />
|
||||
<ui-tooltip :text="tooltips.scannerMaxThreads">
|
||||
<p class="pl-4">
|
||||
Max # of threads to use
|
||||
<span class="material-icons icon-text text-sm">info_outlined</span>
|
||||
</p>
|
||||
</ui-tooltip>
|
||||
</div> -->
|
||||
|
||||
<div class="pt-4">
|
||||
<h2 class="font-semibold">{{ $strings.HeaderSettingsExperimental }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center py-2">
|
||||
<ui-toggle-switch v-model="showExperimentalFeatures" />
|
||||
<ui-tooltip :text="tooltips.experimentalFeatures">
|
||||
<ui-tooltip :text="$strings.LabelSettingsExperimentalFeaturesHelp">
|
||||
<p class="pl-4">
|
||||
Experimental features
|
||||
{{ $strings.LabelSettingsExperimentalFeatures }}
|
||||
<a href="https://github.com/advplyr/audiobookshelf/discussions/75" target="_blank">
|
||||
<span class="material-icons icon-text text-sm">info_outlined</span>
|
||||
</a>
|
||||
|
|
@ -185,9 +175,9 @@
|
|||
|
||||
<div class="flex items-center py-2">
|
||||
<ui-toggle-switch v-model="newServerSettings.enableEReader" :disabled="updatingServerSettings" @input="(val) => updateSettingsKey('enableEReader', val)" />
|
||||
<ui-tooltip :text="tooltips.enableEReader">
|
||||
<ui-tooltip :text="$strings.LabelSettingsEnableEReaderHelp">
|
||||
<p class="pl-4">
|
||||
Enable e-reader for all users
|
||||
{{ $strings.LabelSettingsEnableEReader }}
|
||||
<span class="material-icons icon-text text-sm">info_outlined</span>
|
||||
</p>
|
||||
</ui-tooltip>
|
||||
|
|
@ -228,7 +218,7 @@
|
|||
</svg>
|
||||
</a>
|
||||
<p class="pl-4 pr-2 text-sm font-book text-yellow-400">
|
||||
Join us on
|
||||
{{ $strings.MessageJoinUsOn }}
|
||||
<a class="underline" href="https://discord.gg/pJsjuNCKRq" target="_blank">discord</a>
|
||||
</p>
|
||||
<a href="https://discord.gg/pJsjuNCKRq" target="_blank" class="text-white hover:text-gray-200 hover:scale-150 hover:rotate-6 transform duration-500">
|
||||
|
|
@ -276,17 +266,6 @@ export default {
|
|||
useBookshelfView: false,
|
||||
isPurgingCache: false,
|
||||
newServerSettings: {},
|
||||
tooltips: {
|
||||
experimentalFeatures: 'Features in development that could use your feedback and help testing. Click to open github discussion.',
|
||||
scannerDisableWatcher: 'Disables the automatic adding/updating of items when file changes are detected. *Requires server restart',
|
||||
scannerPreferOpfMetadata: 'OPF file metadata will be used for book details over folder names',
|
||||
scannerPreferMatchedMetadata: 'Matched data will overide book details when using Quick Match',
|
||||
scannerPreferAudioMetadata: 'Audio file ID3 meta tags will be used for book details over folder names',
|
||||
enableEReader: 'E-reader is still a work in progress, but use this setting to open it up to all your users (or use the "Experimental Features" toggle just for use by you)',
|
||||
scannerPreferOverdriveMediaMarker: 'MP3 files from Overdrive come with chapter timings embedded as custom metadata. Enabling this will use these tags for chapter timings automatically',
|
||||
scannerUseSingleThreadedProber: 'The old scanner used a single thread. Leaving it in to use as a comparison for now.',
|
||||
scannerMaxThreads: 'Number of concurrent media files to scan at a time. Value of 1 will be a slower scan but less CPU usage. <br><br>Value of 0 defaults to # of CPU cores for this server times 2 (i.e. 4-core CPU will be 8)'
|
||||
},
|
||||
showConfirmPurgeCache: false
|
||||
}
|
||||
},
|
||||
|
|
@ -317,26 +296,6 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
updateScannerMaxThreads(val) {
|
||||
if (!val || isNaN(val)) {
|
||||
this.$toast.error('Invalid max threads must be a number')
|
||||
this.newServerSettings.scannerMaxThreads = 0
|
||||
return
|
||||
}
|
||||
if (Number(val) < 0) {
|
||||
this.$toast.error('Max threads must be >= 0')
|
||||
this.newServerSettings.scannerMaxThreads = 0
|
||||
return
|
||||
}
|
||||
if (Math.round(Number(val)) !== Number(val)) {
|
||||
this.$toast.error('Max threads must be an integer')
|
||||
this.newServerSettings.scannerMaxThreads = 0
|
||||
return
|
||||
}
|
||||
this.updateServerSettings({
|
||||
scannerMaxThreads: Number(val)
|
||||
})
|
||||
},
|
||||
updateSortingPrefixes(val) {
|
||||
if (!val || !val.length) {
|
||||
this.$toast.error('Must have at least 1 prefix')
|
||||
|
|
@ -390,7 +349,7 @@ export default {
|
|||
this.useBookshelfView = this.newServerSettings.bookshelfView != this.$constants.BookshelfView.DETAIL
|
||||
},
|
||||
resetLibraryItems() {
|
||||
if (confirm('WARNING! This action will remove all library items from the database including any updates or matches you have made. This does not do anything to your actual files. Shall we continue?')) {
|
||||
if (confirm(this.$strings.MessageRemoveAllItemsWarning)) {
|
||||
this.isResettingLibraryItems = true
|
||||
this.$axios
|
||||
.$delete('/api/items/all')
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
<template>
|
||||
<div class="bg-bg rounded-md shadow-lg border border-white border-opacity-5 p-4 mb-8">
|
||||
<h1 class="text-xl">Stats for library {{ currentLibraryName }}</h1>
|
||||
<h1 class="text-xl">{{ $strings.HeaderLibraryStats }}: {{ currentLibraryName }}</h1>
|
||||
<stats-preview-icons v-if="totalItems" :library-stats="libraryStats" />
|
||||
|
||||
<div class="flex lg:flex-row flex-wrap justify-between flex-col mt-8">
|
||||
<div class="w-80 my-6 mx-auto">
|
||||
<h1 class="text-2xl mb-4 font-book">Top 5 Genres</h1>
|
||||
<p v-if="!top5Genres.length">No Genres</p>
|
||||
<h1 class="text-2xl mb-4 font-book">{{ $strings.HeaderStatsTop5Genres }}</h1>
|
||||
<p v-if="!top5Genres.length">{{ $strings.MessageNoGenres }}</p>
|
||||
<template v-for="genre in top5Genres">
|
||||
<div :key="genre.genre" class="w-full py-2">
|
||||
<div class="flex items-end mb-1">
|
||||
|
|
@ -23,8 +23,8 @@
|
|||
</template>
|
||||
</div>
|
||||
<div class="w-80 my-6 mx-auto">
|
||||
<h1 class="text-2xl mb-4 font-book">Top 10 Authors</h1>
|
||||
<p v-if="!top10Authors.length">No Authors</p>
|
||||
<h1 class="text-2xl mb-4 font-book">{{ $strings.HeaderStatsTop10Authors }}</h1>
|
||||
<p v-if="!top10Authors.length">{{ $strings.MessageNoAuthors }}</p>
|
||||
<template v-for="(author, index) in top10Authors">
|
||||
<div :key="author.id" class="w-full py-2">
|
||||
<div class="flex items-center mb-1">
|
||||
|
|
@ -42,8 +42,8 @@
|
|||
</template>
|
||||
</div>
|
||||
<div class="w-80 my-6 mx-auto">
|
||||
<h1 class="text-2xl mb-4 font-book">Longest Items (hrs)</h1>
|
||||
<p v-if="!top10LongestItems.length">No Items</p>
|
||||
<h1 class="text-2xl mb-4 font-book">{{ $strings.HeaderStatsLongestItems }}</h1>
|
||||
<p v-if="!top10LongestItems.length">{{ $strings.MessageNoItems }}</p>
|
||||
<template v-for="(ab, index) in top10LongestItems">
|
||||
<div :key="index" class="w-full py-2">
|
||||
<div class="flex items-center mb-1">
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<div class="w-full h-full">
|
||||
<div class="bg-bg rounded-md shadow-lg border border-white border-opacity-5 p-4 mb-8">
|
||||
<div class="flex items-center mb-2">
|
||||
<h1 class="text-xl">Logs</h1>
|
||||
<h1 class="text-xl">{{ $strings.HeaderLogs }}</h1>
|
||||
</div>
|
||||
<div class="flex justify-between mb-2 place-items-end">
|
||||
<ui-text-input ref="input" v-model="search" placeholder="Search filter.." @input="inputUpdate" clearable class="w-full sm:w-40 h-8 text-sm sm:mb-0" />
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
</div>
|
||||
|
||||
<div v-if="!logs.length" class="absolute top-0 left-0 w-full h-full flex flex-col items-center justify-center text-center">
|
||||
<p class="text-xl text-gray-200 mb-2">No Logs</p>
|
||||
<p class="text-xl text-gray-200 mb-2">{{ $strings.MessageNoLogs }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="bg-bg rounded-md shadow-lg border border-white border-opacity-5 p-3 md:p-8 mb-2 max-w-3xl mx-auto">
|
||||
<h2 class="text-xl font-semibold mb-4">Apprise Notification Settings</h2>
|
||||
<h2 class="text-xl font-semibold mb-4">{{ $strings.HeaderAppriseNotificationSettings }}</h2>
|
||||
<p class="mb-6 text-gray-200">
|
||||
In order to use this feature you will need to have an instance of <a href="https://github.com/caronc/apprise-api" target="_blank" class="hover:underline text-blue-400 hover:text-blue-300">Apprise API</a> running or an api that will handle those same requests. <br />The Apprise API Url should be the full URL path to send the notification, e.g., if your API instance is served at
|
||||
<span class="rounded-md bg-neutral-600 text-sm text-white py-0.5 px-1 font-mono">http://192.168.1.1:8337</span> then you would put <span class="rounded-md bg-neutral-600 text-sm text-white py-0.5 px-1 font-mono">http://192.168.1.1:8337/notify</span>.
|
||||
|
|
@ -13,33 +13,33 @@
|
|||
<div class="flex items-center py-2">
|
||||
<ui-text-input ref="maxNotificationQueueInput" type="number" v-model="maxNotificationQueue" no-spinner :disabled="savingSettings" :padding-x="1" text-center class="w-10" />
|
||||
|
||||
<ui-tooltip text="Events are limited to firing 1 per second. Events will be ignored if the queue is at max size. This prevents notification spamming." direction="right">
|
||||
<p class="pl-2 md:pl-4 text-base md:text-lg">Max queue size for notification events<span class="material-icons icon-text ml-1">info_outlined</span></p>
|
||||
<ui-tooltip :text="$strings.LabelNotificationsMaxQueueSizeHelp" direction="right">
|
||||
<p class="pl-2 md:pl-4 text-base md:text-lg">{{ $strings.LabelNotificationsMaxQueueSize }}<span class="material-icons icon-text ml-1">info_outlined</span></p>
|
||||
</ui-tooltip>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center py-2">
|
||||
<ui-text-input ref="maxFailedAttemptsInput" type="number" v-model="maxFailedAttempts" no-spinner :disabled="savingSettings" :padding-x="1" text-center class="w-10" />
|
||||
|
||||
<ui-tooltip text="Notifications are disabled once they fail to send this many times." direction="right">
|
||||
<p class="pl-2 md:pl-4 text-base md:text-lg">Max failed attempts<span class="material-icons icon-text ml-1">info_outlined</span></p>
|
||||
<ui-tooltip :text="$strings.LabelNotificationsMaxFailedAttemptsHelp" direction="right">
|
||||
<p class="pl-2 md:pl-4 text-base md:text-lg">{{ $strings.LabelNotificationsMaxFailedAttempts }}<span class="material-icons icon-text ml-1">info_outlined</span></p>
|
||||
</ui-tooltip>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-end pt-4">
|
||||
<ui-btn :loading="savingSettings" type="submit">Save</ui-btn>
|
||||
<ui-btn :loading="savingSettings" type="submit">{{ $strings.ButtonSave }}</ui-btn>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="w-full h-px bg-white bg-opacity-10 my-6" />
|
||||
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h2 class="text-xl font-semibold">Notifications</h2>
|
||||
<ui-btn small color="success" class="flex items-center" @click="clickCreate">Create <span class="material-icons text-lg pl-2">add</span></ui-btn>
|
||||
<h2 class="text-xl font-semibold">{{ $strings.HeaderNotifications }}</h2>
|
||||
<ui-btn small color="success" class="flex items-center" @click="clickCreate">{{ $strings.ButtonCreate }} <span class="material-icons text-lg pl-2">add</span></ui-btn>
|
||||
</div>
|
||||
|
||||
<div v-if="!notifications.length" class="flex justify-center text-center">
|
||||
<p class="text-lg text-gray-200">No notifications</p>
|
||||
<p class="text-lg text-gray-200">{{ $strings.MessageNoNotifications }}</p>
|
||||
</div>
|
||||
<template v-for="notification in notifications">
|
||||
<cards-notification-card :key="notification.id" :notification="notification" @update="updateSettings" @edit="editNotification" />
|
||||
|
|
|
|||
|
|
@ -2,23 +2,23 @@
|
|||
<div class="w-full h-full">
|
||||
<div class="bg-bg rounded-md shadow-lg border border-white border-opacity-5 p-4 mb-8">
|
||||
<div class="flex items-center mb-2">
|
||||
<h1 class="text-xl">Listening Sessions</h1>
|
||||
<h1 class="text-xl">{{ $strings.HeaderListeningSessions }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end mb-2">
|
||||
<ui-dropdown v-model="selectedUser" :items="userItems" label="Filter by User" small class="max-w-48" @input="updateUserFilter" />
|
||||
<ui-dropdown v-model="selectedUser" :items="userItems" :label="$strings.LabelFilterByUser" small class="max-w-48" @input="updateUserFilter" />
|
||||
</div>
|
||||
|
||||
<div v-if="listeningSessions.length" class="block max-w-full">
|
||||
<table class="userSessionsTable">
|
||||
<tr class="bg-primary bg-opacity-40">
|
||||
<th class="w-48 min-w-48 text-left">Item</th>
|
||||
<th class="w-20 min-w-20 text-left hidden md:table-cell">User</th>
|
||||
<th class="w-32 min-w-32 text-left hidden md:table-cell">Play Method</th>
|
||||
<th class="w-32 min-w-32 text-left hidden sm:table-cell">Device Info</th>
|
||||
<th class="w-32 min-w-32">Listened</th>
|
||||
<th class="w-16 min-w-16">Last Time</th>
|
||||
<th class="flex-grow hidden sm:table-cell">Last Update</th>
|
||||
<th class="w-48 min-w-48 text-left">{{ $strings.LabelItem }}</th>
|
||||
<th class="w-20 min-w-20 text-left hidden md:table-cell">{{ $strings.LabelUser }}</th>
|
||||
<th class="w-32 min-w-32 text-left hidden md:table-cell">{{ $strings.LabelPlayMethod }}</th>
|
||||
<th class="w-32 min-w-32 text-left hidden sm:table-cell">{{ $strings.LabelDeviceInfo }}</th>
|
||||
<th class="w-32 min-w-32">{{ $strings.LabelTimeListened }}</th>
|
||||
<th class="w-16 min-w-16">{{ $strings.LabelLastTime }}</th>
|
||||
<th class="flex-grow hidden sm:table-cell">{{ $strings.LabelLastUpdate }}</th>
|
||||
</tr>
|
||||
|
||||
<tr v-for="session in listeningSessions" :key="session.id" class="cursor-pointer" @click="showSession(session)">
|
||||
|
|
@ -55,7 +55,7 @@
|
|||
<ui-icon-btn icon="arrow_forward_ios" :size="7" icon-font-size="1rem" class="mx-1" :disabled="currentPage >= numPages - 1" @click="nextPage" />
|
||||
</div>
|
||||
</div>
|
||||
<p v-else class="text-white text-opacity-50">No sessions yet...</p>
|
||||
<p v-else class="text-white text-opacity-50">{{ $strings.MessageNoListeningSessions }}</p>
|
||||
</div>
|
||||
|
||||
<modals-listening-session-modal v-model="showSessionModal" :session="selectedSession" @removedSession="removedSession" />
|
||||
|
|
@ -134,7 +134,7 @@ export default {
|
|||
}
|
||||
|
||||
const payload = {
|
||||
message: `Start playback for "${session.displayTitle}" at ${this.$secondsToTimestamp(session.currentTime)}?`,
|
||||
message: this.$getString('MessageStartPlaybackAtTime', [session.displayTitle, this.$secondsToTimestamp(session.currentTime)]),
|
||||
callback: (confirmed) => {
|
||||
if (confirmed) {
|
||||
this.$eventBus.$emit('play-item', {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="bg-bg rounded-md shadow-lg border border-white border-opacity-5 p-4 mb-8">
|
||||
<h1 class="text-xl">Stats for {{ username }}</h1>
|
||||
<h1 class="text-xl">{{ $strings.HeaderYourStats }}</h1>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex p-2">
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
</svg>
|
||||
<div class="px-3">
|
||||
<p class="text-4xl md:text-5xl font-bold">{{ userItemsFinished.length }}</p>
|
||||
<p class="font-book text-xs md:text-sm text-white text-opacity-80">Items Finished</p>
|
||||
<p class="font-book text-xs md:text-sm text-white text-opacity-80">{{ $strings.LabelStatsItemsFinished }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
</div>
|
||||
<div class="px-1">
|
||||
<p class="text-4xl md:text-5xl font-bold">{{ totalDaysListened }}</p>
|
||||
<p class="font-book text-xs md:text-sm text-white text-opacity-80">Days Listened</p>
|
||||
<p class="font-book text-xs md:text-sm text-white text-opacity-80">{{ $strings.LabelStatsDaysListened }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
</div>
|
||||
<div class="px-1">
|
||||
<p class="text-4xl md:text-5xl font-bold">{{ totalMinutesListening }}</p>
|
||||
<p class="font-book text-xs md:text-sm text-white text-opacity-80">Minutes Listening</p>
|
||||
<p class="font-book text-xs md:text-sm text-white text-opacity-80">{{ $strings.LabelStatsMinutesListening }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -40,11 +40,11 @@
|
|||
<stats-daily-listening-chart :listening-stats="listeningStats" class="origin-top-left transform scale-75 lg:scale-100" />
|
||||
<div class="w-80 my-6 mx-auto">
|
||||
<div class="flex mb-4 items-center">
|
||||
<h1 class="text-2xl font-book">Recent Sessions</h1>
|
||||
<h1 class="text-2xl font-book">{{ $strings.HeaderStatsRecentSessions }}</h1>
|
||||
<div class="flex-grow" />
|
||||
<ui-btn :to="`/config/users/${user.id}/sessions`" class="text-xs" :padding-x="1.5" :padding-y="1">View All</ui-btn>
|
||||
<ui-btn :to="`/config/users/${user.id}/sessions`" class="text-xs" :padding-x="1.5" :padding-y="1">{{ $strings.ButtonViewAll }}</ui-btn>
|
||||
</div>
|
||||
<p v-if="!mostRecentListeningSessions.length">No Listening Sessions</p>
|
||||
<p v-if="!mostRecentListeningSessions.length">{{ $strings.MessageNoListeningSessions }}</p>
|
||||
<template v-for="(item, index) in mostRecentListeningSessions">
|
||||
<div :key="item.id" class="w-full py-0.5">
|
||||
<div class="flex items-center mb-1">
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<div class="h-10 w-10 flex items-center justify-center">
|
||||
<span class="material-icons text-2xl">arrow_back</span>
|
||||
</div>
|
||||
<p class="pl-1">All Users</p>
|
||||
<p class="pl-1">{{ $strings.LabelAllUsers }}</p>
|
||||
</div>
|
||||
</nuxt-link>
|
||||
<div class="flex items-center mb-2 mt-4 px-2 sm:px-0">
|
||||
|
|
@ -22,22 +22,22 @@
|
|||
</div>
|
||||
<div class="w-full h-px bg-white bg-opacity-10 my-2" />
|
||||
<div class="py-2">
|
||||
<h1 class="text-lg mb-2 text-white text-opacity-90 px-2 sm:px-0">Listening Stats</h1>
|
||||
<h1 class="text-lg mb-2 text-white text-opacity-90 px-2 sm:px-0">{{ $strings.HeaderListeningStats }}</h1>
|
||||
<div class="flex items-center">
|
||||
<p class="text-sm text-gray-300">{{ listeningSessions.length }} Listening Sessions</p>
|
||||
<ui-btn :to="`/config/users/${user.id}/sessions`" class="text-xs mx-2" :padding-x="1.5" :padding-y="1">View All</ui-btn>
|
||||
<p class="text-sm text-gray-300">{{ listeningSessions.length }} {{ $strings.HeaderListeningSessions }}</p>
|
||||
<ui-btn :to="`/config/users/${user.id}/sessions`" class="text-xs mx-2" :padding-x="1.5" :padding-y="1">{{ $strings.ButtonViewAll }}</ui-btn>
|
||||
</div>
|
||||
<p class="text-sm text-gray-300">
|
||||
Total Time Listened:
|
||||
{{ $strings.LabelTotalTimeListened }}:
|
||||
<span class="font-mono text-base">{{ listeningTimePretty }}</span>
|
||||
</p>
|
||||
<p v-if="timeListenedToday" class="text-sm text-gray-300">
|
||||
Time Listened Today:
|
||||
{{ $strings.LabelTimeListenedToday }}:
|
||||
<span class="font-mono text-base">{{ $elapsedPrettyExtended(timeListenedToday) }}</span>
|
||||
</p>
|
||||
|
||||
<div v-if="latestSession" class="mt-4">
|
||||
<h1 class="text-lg mb-2 text-white text-opacity-90 px-2 sm:px-0">Last Listening Session</h1>
|
||||
<h1 class="text-lg mb-2 text-white text-opacity-90 px-2 sm:px-0">{{ $strings.HeaderLastListeningSession }}</h1>
|
||||
<p class="text-sm text-gray-300">
|
||||
<strong>{{ latestSession.displayTitle }}</strong> {{ $dateDistanceFromNow(latestSession.updatedAt) }} for <span class="font-mono text-base">{{ $elapsedPrettyExtended(this.latestSession.timeListening) }}</span>
|
||||
</p>
|
||||
|
|
@ -45,21 +45,21 @@
|
|||
</div>
|
||||
<div class="w-full h-px bg-white bg-opacity-10 my-2" />
|
||||
<div class="py-2">
|
||||
<h1 class="text-lg mb-2 text-white text-opacity-90 px-2 sm:px-0">Saved Media Progress</h1>
|
||||
<h1 class="text-lg mb-2 text-white text-opacity-90 px-2 sm:px-0">{{ $strings.HeaderSavedMediaProgress }}</h1>
|
||||
|
||||
<div v-if="mediaProgressWithoutMedia.length" class="flex items-center py-2 mb-2">
|
||||
<p class="text-error">User has media progress for {{ mediaProgressWithoutMedia.length }} items that no longer exist.</p>
|
||||
<div class="flex-grow" />
|
||||
<ui-btn small :loading="purgingMediaProgress" @click.stop="purgeMediaProgress">Purge Media Progress</ui-btn>
|
||||
<ui-btn small :loading="purgingMediaProgress" @click.stop="purgeMediaProgress">{{ $strings.ButtonPurgeMediaProgress }}</ui-btn>
|
||||
</div>
|
||||
|
||||
<table v-if="mediaProgressWithMedia.length" class="userAudiobooksTable">
|
||||
<tr class="bg-primary bg-opacity-40">
|
||||
<th class="w-16 text-left">Item</th>
|
||||
<th class="w-16 text-left">{{ $strings.LabelItem }}</th>
|
||||
<th class="text-left"></th>
|
||||
<th class="w-32">Progress</th>
|
||||
<th class="w-40 hidden sm:table-cell">Started At</th>
|
||||
<th class="w-40 hidden sm:table-cell">Last Update</th>
|
||||
<th class="w-32">{{ $strings.LabelProgress }}</th>
|
||||
<th class="w-40 hidden sm:table-cell">{{ $strings.LabelStartedAt }}</th>
|
||||
<th class="w-40 hidden sm:table-cell">{{ $strings.LabelLastUpdate }}</th>
|
||||
</tr>
|
||||
<tr v-for="item in mediaProgressWithMedia" :key="item.id" :class="!item.isFinished ? '' : 'isFinished'">
|
||||
<td>
|
||||
|
|
@ -90,7 +90,7 @@
|
|||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p v-else class="text-white text-opacity-50">Nothing listened to yet...</p>
|
||||
<p v-else class="text-white text-opacity-50">{{ $strings.MessageNoMediaProgress }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<div class="h-10 w-10 flex items-center justify-center">
|
||||
<span class="material-icons text-2xl">arrow_back</span>
|
||||
</div>
|
||||
<p class="pl-1">Back to User</p>
|
||||
<p class="pl-1">{{ $strings.LabelBackToUser }}</p>
|
||||
</div>
|
||||
</nuxt-link>
|
||||
<div class="flex items-center mb-2 mt-4 px-2 sm:px-0">
|
||||
|
|
@ -17,16 +17,16 @@
|
|||
<div class="w-full h-px bg-white bg-opacity-10 my-2" />
|
||||
|
||||
<div class="py-2">
|
||||
<h1 class="text-lg mb-2 text-white text-opacity-90 px-2 sm:px-0">Listening Sessions</h1>
|
||||
<h1 class="text-lg mb-2 text-white text-opacity-90 px-2 sm:px-0">{{ $strings.HeaderListeningSessions }}</h1>
|
||||
<div v-if="listeningSessions.length">
|
||||
<table class="userSessionsTable">
|
||||
<tr class="bg-primary bg-opacity-40">
|
||||
<th class="w-48 min-w-48 text-left">Item</th>
|
||||
<th class="w-32 min-w-32 text-left hidden md:table-cell">Play Method</th>
|
||||
<th class="w-32 min-w-32 text-left hidden sm:table-cell">Device Info</th>
|
||||
<th class="w-32 min-w-32">Listened</th>
|
||||
<th class="w-16 min-w-16">Last Time</th>
|
||||
<th class="flex-grow hidden sm:table-cell">Last Update</th>
|
||||
<th class="w-48 min-w-48 text-left">{{ $strings.LabelItem }}</th>
|
||||
<th class="w-32 min-w-32 text-left hidden md:table-cell">{{ $strings.LabelPlayMethod }}</th>
|
||||
<th class="w-32 min-w-32 text-left hidden sm:table-cell">{{ $strings.LabelDeviceInfo }}</th>
|
||||
<th class="w-32 min-w-32">{{ $strings.LabelTimeListened }}</th>
|
||||
<th class="w-16 min-w-16">{{ $strings.LabelLastTime }}</th>
|
||||
<th class="flex-grow hidden sm:table-cell">{{ $strings.LabelLastUpdate }}</th>
|
||||
</tr>
|
||||
<tr v-for="session in listeningSessions" :key="session.id" class="cursor-pointer" @click="showSession(session)">
|
||||
<td class="py-1 max-w-48">
|
||||
|
|
@ -121,7 +121,7 @@ export default {
|
|||
}
|
||||
|
||||
const payload = {
|
||||
message: `Start playback for "${session.displayTitle}" at ${this.$secondsToTimestamp(session.currentTime)}?`,
|
||||
message: this.$getString('MessageStartPlaybackAtTime', [session.displayTitle, this.$secondsToTimestamp(session.currentTime)]),
|
||||
callback: (confirmed) => {
|
||||
if (confirmed) {
|
||||
this.$eventBus.$emit('play-item', {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue