mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-08-04 18:24:46 +02:00
Merge branch 'master' into liaocl
This commit is contained in:
commit
2ec52a7a45
119 changed files with 11524 additions and 25894 deletions
|
@ -142,7 +142,7 @@
|
|||
</template>
|
||||
<div class="w-full h-full max-h-full text-sm rounded-lg bg-bg shadow-lg border border-black-300 relative">
|
||||
<div v-if="!chapterData" class="flex p-20">
|
||||
<ui-text-input-with-label v-model="asinInput" label="ASIN" />
|
||||
<ui-text-input-with-label v-model.trim="asinInput" label="ASIN" />
|
||||
<ui-dropdown v-model="regionInput" :label="$strings.LabelRegion" small :items="audibleRegions" class="w-32 mx-1" />
|
||||
<ui-btn small color="primary" class="mt-5" @click="findChapters">{{ $strings.ButtonSearch }}</ui-btn>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,18 @@
|
|||
<template>
|
||||
<div id="authentication-settings">
|
||||
<app-settings-content :header-text="$strings.HeaderAuthentication">
|
||||
<div class="w-full border border-white/10 rounded-xl p-4 my-4 bg-primary/25">
|
||||
<div class="flex items-center">
|
||||
<ui-checkbox v-model="showCustomLoginMessage" checkbox-bg="bg" />
|
||||
<p class="text-lg pl-4">Custom Message on Login</p>
|
||||
</div>
|
||||
<transition name="slide">
|
||||
<div v-if="showCustomLoginMessage" class="w-full pt-4">
|
||||
<ui-rich-text-editor v-model="newAuthSettings.authLoginCustomMessage" />
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
|
||||
<div class="w-full border border-white/10 rounded-xl p-4 my-4 bg-primary/25">
|
||||
<div class="flex items-center">
|
||||
<ui-checkbox v-model="enableLocalAuth" checkbox-bg="bg" />
|
||||
|
@ -103,6 +115,7 @@ export default {
|
|||
return {
|
||||
enableLocalAuth: false,
|
||||
enableOpenIDAuth: false,
|
||||
showCustomLoginMessage: false,
|
||||
savingSettings: false,
|
||||
newAuthSettings: {}
|
||||
}
|
||||
|
@ -221,6 +234,10 @@ export default {
|
|||
return
|
||||
}
|
||||
|
||||
if (!this.showCustomLoginMessage || !this.newAuthSettings.authLoginCustomMessage?.trim()) {
|
||||
this.newAuthSettings.authLoginCustomMessage = null
|
||||
}
|
||||
|
||||
this.newAuthSettings.authActiveAuthMethods = []
|
||||
if (this.enableLocalAuth) this.newAuthSettings.authActiveAuthMethods.push('local')
|
||||
if (this.enableOpenIDAuth) this.newAuthSettings.authActiveAuthMethods.push('openid')
|
||||
|
@ -250,6 +267,7 @@ export default {
|
|||
}
|
||||
this.enableLocalAuth = this.authMethods.includes('local')
|
||||
this.enableOpenIDAuth = this.authMethods.includes('openid')
|
||||
this.showCustomLoginMessage = !!this.authSettings.authLoginCustomMessage
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
|
|
@ -178,9 +178,9 @@
|
|||
</a>
|
||||
<p class="pl-4 pr-2 text-sm text-yellow-400">
|
||||
{{ $strings.MessageJoinUsOn }}
|
||||
<a class="underline" href="https://discord.gg/pJsjuNCKRq" target="_blank">discord</a>
|
||||
<a class="underline" href="https://discord.gg/HQgCbd6E75" 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">
|
||||
<a href="https://discord.gg/HQgCbd6E75" target="_blank" class="text-white hover:text-gray-200 hover:scale-150 hover:rotate-6 transform duration-500">
|
||||
<svg width="31" height="24" viewBox="0 0 71 55" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0)">
|
||||
<path
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
<template>
|
||||
<div class="relative">
|
||||
<app-settings-content :header-text="$strings.HeaderCustomMetadataProviders">
|
||||
<template #header-prefix>
|
||||
<nuxt-link to="/config/item-metadata-utils" class="w-8 h-8 flex items-center justify-center rounded-full cursor-pointer hover:bg-white hover:bg-opacity-10 text-center mr-2">
|
||||
<span class="material-icons text-2xl">arrow_back</span>
|
||||
</nuxt-link>
|
||||
</template>
|
||||
<template #header-items>
|
||||
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
||||
<a href="https://www.audiobookshelf.org/guides/#" target="_blank" class="inline-flex">
|
||||
<span class="material-icons text-xl w-5 text-gray-200">help_outline</span>
|
||||
</a>
|
||||
</ui-tooltip>
|
||||
<div class="flex-grow" />
|
||||
|
||||
<ui-btn color="primary" small @click="setShowAddModal">{{ $strings.ButtonAdd }}</ui-btn>
|
||||
</template>
|
||||
|
||||
<tables-custom-metadata-provider-table :providers="providers" :processing.sync="processing" class="pt-2" @removed="providerRemoved" />
|
||||
<modals-add-custom-metadata-provider-modal ref="addModal" v-model="showAddModal" @added="providerAdded" />
|
||||
</app-settings-content>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
async asyncData({ store, redirect }) {
|
||||
if (!store.getters['user/getIsAdminOrUp']) {
|
||||
redirect('/')
|
||||
return
|
||||
}
|
||||
return {}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showAddModal: false,
|
||||
processing: false,
|
||||
providers: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
providerRemoved(providerId) {
|
||||
this.providers = this.providers.filter((p) => p.id !== providerId)
|
||||
},
|
||||
providerAdded(provider) {
|
||||
this.providers.push(provider)
|
||||
},
|
||||
setShowAddModal() {
|
||||
this.showAddModal = true
|
||||
},
|
||||
loadProviders() {
|
||||
this.processing = true
|
||||
this.$axios
|
||||
.$get('/api/custom-metadata-providers')
|
||||
.then((res) => {
|
||||
this.providers = res.providers
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed', error)
|
||||
this.$toast.error('Failed to load custom metadata providers')
|
||||
})
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.loadProviders()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
|
@ -13,6 +13,12 @@
|
|||
<span class="material-icons">arrow_forward</span>
|
||||
</div>
|
||||
</nuxt-link>
|
||||
<nuxt-link to="/config/item-metadata-utils/custom-metadata-providers" class="block w-full rounded bg-primary/40 hover:bg-primary/60 text-gray-300 hover:text-white p-4 my-2">
|
||||
<div class="flex justify-between">
|
||||
<p>{{ $strings.HeaderCustomMetadataProviders }}</p>
|
||||
<span class="material-icons">arrow_forward</span>
|
||||
</div>
|
||||
</nuxt-link>
|
||||
</app-settings-content>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
</div>
|
||||
|
||||
<div class="relative">
|
||||
<div ref="container" class="relative w-full h-full bg-primary border-bg overflow-x-hidden overflow-y-auto text-red shadow-inner rounded-md" style="max-height: 800px; min-height: 550px">
|
||||
<div ref="container" id="log-container" class="relative w-full h-full bg-primary border-bg overflow-x-hidden overflow-y-auto text-red shadow-inner rounded-md" style="min-height: 550px">
|
||||
<template v-for="(log, index) in logs">
|
||||
<div :key="index" class="flex flex-nowrap px-2 py-1 items-start text-sm bg-opacity-10" :class="`bg-${logColors[log.level]}`">
|
||||
<p class="text-gray-400 w-36 font-mono text-xs">{{ log.timestamp }}</p>
|
||||
|
@ -136,7 +136,15 @@ export default {
|
|||
this.loadedLogs = this.loadedLogs.slice(-5000)
|
||||
}
|
||||
},
|
||||
init(attempts = 0) {
|
||||
async loadLoggerData() {
|
||||
const loggerData = await this.$axios.$get('/api/logger-data').catch((error) => {
|
||||
console.error('Failed to load logger data', error)
|
||||
this.$toast.error('Failed to load logger data')
|
||||
})
|
||||
|
||||
this.loadedLogs = loggerData?.currentDailyLogs || []
|
||||
},
|
||||
async init(attempts = 0) {
|
||||
if (!this.$root.socket) {
|
||||
if (attempts > 10) {
|
||||
return console.error('Failed to setup socket listeners')
|
||||
|
@ -147,14 +155,11 @@ export default {
|
|||
return
|
||||
}
|
||||
|
||||
await this.loadLoggerData()
|
||||
|
||||
this.newServerSettings = this.serverSettings ? { ...this.serverSettings } : {}
|
||||
this.$root.socket.on('daily_logs', this.dailyLogsLoaded)
|
||||
this.$root.socket.on('log', this.logEvtReceived)
|
||||
this.$root.socket.emit('set_log_listener', this.newServerSettings.logLevel)
|
||||
this.$root.socket.emit('fetch_daily_logs')
|
||||
},
|
||||
dailyLogsLoaded(lines) {
|
||||
this.loadedLogs = lines
|
||||
}
|
||||
},
|
||||
updated() {
|
||||
|
@ -166,13 +171,15 @@ export default {
|
|||
beforeDestroy() {
|
||||
if (!this.$root.socket) return
|
||||
this.$root.socket.emit('remove_log_listener')
|
||||
this.$root.socket.off('daily_logs', this.dailyLogsLoaded)
|
||||
this.$root.socket.off('log', this.logEvtReceived)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#log-container {
|
||||
height: calc(100vh - 285px);
|
||||
}
|
||||
.logmessage {
|
||||
width: calc(100% - 208px);
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@
|
|||
<div class="flex items-center my-2">
|
||||
<div class="flex-grow" />
|
||||
<div class="hidden sm:inline-flex items-center">
|
||||
<p class="text-sm">{{ $strings.LabelRowsPerPage }}</p>
|
||||
<p class="text-sm whitespace-nowrap">{{ $strings.LabelRowsPerPage }}</p>
|
||||
<ui-dropdown v-model="itemsPerPage" :items="itemsPerPageOptions" small class="w-24 mx-2" @input="updatedItemsPerPage" />
|
||||
</div>
|
||||
<div class="inline-flex items-center">
|
||||
|
|
|
@ -54,9 +54,16 @@
|
|||
<p class="pl-2 pr-1 text-sm font-semibold">{{ getButtonText(episode) }}</p>
|
||||
</button>
|
||||
|
||||
<button v-if="libraryItemIdStreaming && !isStreamingFromDifferentLibrary" class="h-8 w-8 flex justify-center items-center mx-2" :class="playerQueueEpisodeIdMap[episode.id] ? 'text-success' : ''" @click.stop="queueBtnClick(episode)">
|
||||
<span class="material-icons-outlined text-2xl">{{ playerQueueEpisodeIdMap[episode.id] ? 'playlist_add_check' : 'playlist_add' }}</span>
|
||||
</button>
|
||||
<ui-tooltip v-if="libraryItemIdStreaming && !isStreamingFromDifferentLibrary" :text="playerQueueEpisodeIdMap[episode.id] ? $strings.MessageRemoveFromPlayerQueue : $strings.MessageAddToPlayerQueue" :class="playerQueueEpisodeIdMap[episode.id] ? 'text-success' : ''" direction="top">
|
||||
<ui-icon-btn :icon="playerQueueEpisodeIdMap[episode.id] ? 'playlist_add_check' : 'playlist_play'" borderless @click="queueBtnClick(episode)" />
|
||||
<!-- <button class="h-8 w-8 flex justify-center items-center mx-2" :class="playerQueueEpisodeIdMap[episode.id] ? 'text-success' : ''" @click.stop="queueBtnClick(episode)">
|
||||
<span class="material-icons-outlined text-2xl">{{ playerQueueEpisodeIdMap[episode.id] ? 'playlist_add_check' : 'playlist_add' }}</span>
|
||||
</button> -->
|
||||
</ui-tooltip>
|
||||
|
||||
<ui-tooltip :text="$strings.LabelYourPlaylists" direction="top">
|
||||
<ui-icon-btn icon="playlist_add" borderless @click="clickAddToPlaylist(episode)" />
|
||||
</ui-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -136,6 +143,15 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
clickAddToPlaylist(episode) {
|
||||
// Makeshift libraryItem
|
||||
const libraryItem = {
|
||||
id: episode.libraryItemId,
|
||||
media: episode.podcast
|
||||
}
|
||||
this.$store.commit('globals/setSelectedPlaylistItems', [{ libraryItem: libraryItem, episode }])
|
||||
this.$store.commit('globals/setShowPlaylistsModal', true)
|
||||
},
|
||||
async clickEpisode(episode) {
|
||||
if (this.openingItem) return
|
||||
this.openingItem = true
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
<div class="w-full h-px bg-white bg-opacity-10 my-4" />
|
||||
|
||||
<p v-if="loginCustomMessage" class="py-2 default-style mb-2" v-html="loginCustomMessage"></p>
|
||||
|
||||
<p v-if="error" class="text-error text-center py-2">{{ error }}</p>
|
||||
|
||||
<form v-show="login_local" @submit.prevent="submitForm">
|
||||
|
@ -113,6 +115,9 @@ export default {
|
|||
},
|
||||
openIDButtonText() {
|
||||
return this.authFormData?.authOpenIDButtonText || 'Login with OpenId'
|
||||
},
|
||||
loginCustomMessage() {
|
||||
return this.authFormData?.authLoginCustomMessage || null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue