mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-07-10 11:21:36 +00:00
Rename methods and fix save bug
This commit is contained in:
parent
00bfb5ced4
commit
9ff5f2fc37
7 changed files with 69 additions and 69 deletions
|
|
@ -85,15 +85,15 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div v-if="incomingFeeds.length" class="block max-w-full">
|
<div v-if="feedSubscriptions.length" class="block max-w-full">
|
||||||
<div class="flex -mx-1 items-center mb-3">
|
<div class="flex -mx-1 items-center mb-3">
|
||||||
<div class="w-3/4 px-1">
|
<div class="w-3/4 px-1">
|
||||||
<form @submit.prevent="incomingFeedsSubmit" class="flex flex-grow">
|
<form @submit.prevent="feedSubscriptionsSubmit" class="flex flex-grow">
|
||||||
<ui-text-input v-model="incomingFeedsSearch" @input="incomingFeedsInputUpdate" type="search" :placeholder="$strings.PlaceholderSearchTitle" class="flex-grow text-sm md:text-base" />
|
<ui-text-input v-model="feedSubscriptionsSearch" @input="feedSubscriptionsInputUpdate" type="search" :placeholder="$strings.PlaceholderSearchTitle" class="flex-grow text-sm md:text-base" />
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-grow px-1">
|
<div class="flex-grow px-1">
|
||||||
<ui-checkbox v-model="incomingFeedShowOnlyUnhealthy" :label="$strings.LabelFeedShowOnlyUnhealthy" checkbox-bg="primary" border-color="gray-600" label-class="pl-2 text-base font-semibold" />
|
<ui-checkbox v-model="feedSubscriptionsShowOnlyUnhealthy" :label="$strings.LabelFeedShowOnlyUnhealthy" checkbox-bg="primary" border-color="gray-600" label-class="pl-2 text-base font-semibold" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -109,43 +109,43 @@
|
||||||
<th class="w-16 text-center"></th>
|
<th class="w-16 text-center"></th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr v-for="incomingFeed in incomingFeedsList" :key="incomingFeed.id" class="cursor-pointer h-12">
|
<tr v-for="feedSubscription in feedSubscriptionsList" :key="feedSubscription.id" class="cursor-pointer h-12">
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<td>
|
<td>
|
||||||
<covers-preview-cover v-if="incomingFeed?.metadata?.imageUrl" :width="50"
|
<covers-preview-cover v-if="feedSubscription?.metadata?.imageUrl" :width="50"
|
||||||
:src="incomingFeed.metadata.imageUrl"
|
:src="feedSubscription.metadata.imageUrl"
|
||||||
:book-cover-aspect-ratio="bookCoverAspectRatio" :show-resolution="false"/>
|
:book-cover-aspect-ratio="bookCoverAspectRatio" :show-resolution="false"/>
|
||||||
<img v-else :src="noCoverUrl" class="h-full w-full"/>
|
<img v-else :src="noCoverUrl" class="h-full w-full"/>
|
||||||
</td>
|
</td>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<td class="w-48 max-w-64 min-w-24 text-left truncate">
|
<td class="w-48 max-w-64 min-w-24 text-left truncate">
|
||||||
<p class="truncate">{{ incomingFeed.metadata.title }}</p>
|
<p class="truncate">{{ feedSubscription.metadata.title }}</p>
|
||||||
<p class="truncate text-xs text-gray-300">{{ incomingFeed.metadata.feedUrl }}</p>
|
<p class="truncate text-xs text-gray-300">{{ feedSubscription.metadata.feedUrl }}</p>
|
||||||
</td>
|
</td>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<td class="text-left">
|
<td class="text-left">
|
||||||
<ui-tooltip v-if="incomingFeed.lastEpisodeCheck" direction="top"
|
<ui-tooltip v-if="feedSubscription.lastEpisodeCheck" direction="top"
|
||||||
:text="$formatDatetime(incomingFeed.lastEpisodeCheck, dateFormat, timeFormat)">
|
:text="$formatDatetime(feedSubscription.lastEpisodeCheck, dateFormat, timeFormat)">
|
||||||
<p class="text-gray-200">{{ $dateDistanceFromNow(incomingFeed.lastEpisodeCheck) }}</p>
|
<p class="text-gray-200">{{ $dateDistanceFromNow(feedSubscription.lastEpisodeCheck) }}</p>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
</td>
|
</td>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<td class="text-left">
|
<td class="text-left">
|
||||||
<ui-tooltip v-if="incomingFeed.metadata.lastSuccessfulFetchAt" direction="top"
|
<ui-tooltip v-if="feedSubscription.metadata.lastSuccessfulFetchAt" direction="top"
|
||||||
:text="$formatDatetime(incomingFeed.metadata.lastSuccessfulFetchAt, dateFormat, timeFormat)">
|
:text="$formatDatetime(feedSubscription.metadata.lastSuccessfulFetchAt, dateFormat, timeFormat)">
|
||||||
<p class="text-gray-200">{{
|
<p class="text-gray-200">{{
|
||||||
$dateDistanceFromNow(incomingFeed.metadata.lastSuccessfulFetchAt)
|
$dateDistanceFromNow(feedSubscription.metadata.lastSuccessfulFetchAt)
|
||||||
}}</p>
|
}}</p>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
<p class="text-gray-200" v-else>{{ $strings.MessageNoAvailable }}</p>
|
<p class="text-gray-200" v-else>{{ $strings.MessageNoAvailable }}</p>
|
||||||
</td>
|
</td>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<td class="text-center leading-none lg:table-cell">
|
<td class="text-center leading-none lg:table-cell">
|
||||||
<widgets-feed-healthy-indicator :value="!!incomingFeed.metadata.feedHealthy" />
|
<widgets-feed-healthy-indicator :value="!!feedSubscription.metadata.feedHealthy" />
|
||||||
</td>
|
</td>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<td class="text-center leading-none lg:table-cell">
|
<td class="text-center leading-none lg:table-cell">
|
||||||
<ui-tooltip v-if="incomingFeed.autoDownloadEpisodes" direction="top"
|
<ui-tooltip v-if="feedSubscription.autoDownloadEpisodes" direction="top"
|
||||||
:text="$strings.LabelEnabled">
|
:text="$strings.LabelEnabled">
|
||||||
<span class="material-icons text-2xl">check</span>
|
<span class="material-icons text-2xl">check</span>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|
@ -156,10 +156,10 @@
|
||||||
</td>
|
</td>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<td class="text-left">
|
<td class="text-left">
|
||||||
<ui-tooltip v-if="incomingFeed.autoDownloadEpisodes" direction="top"
|
<ui-tooltip v-if="feedSubscription.autoDownloadEpisodes" direction="top"
|
||||||
:text="`${$strings.LabelCronExpression}: ${incomingFeed.autoDownloadSchedule}`">
|
:text="`${$strings.LabelCronExpression}: ${feedSubscription.autoDownloadSchedule}`">
|
||||||
<p class="text-gray-200">
|
<p class="text-gray-200">
|
||||||
{{ nextRun(incomingFeed.autoDownloadSchedule) }}
|
{{ nextRun(feedSubscription.autoDownloadSchedule) }}
|
||||||
</p>
|
</p>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
</td>
|
</td>
|
||||||
|
|
@ -169,14 +169,14 @@
|
||||||
<ui-tooltip direction="top"
|
<ui-tooltip direction="top"
|
||||||
:text="$strings.ButtonCopyFeedURL">
|
:text="$strings.ButtonCopyFeedURL">
|
||||||
<button class="inline-flex material-icons text-xl mx-1 mt-1 text-white/70 hover:text-white/100"
|
<button class="inline-flex material-icons text-xl mx-1 mt-1 text-white/70 hover:text-white/100"
|
||||||
@click.stop="copyToClipboard(incomingFeed.metadata.feedUrl)">content_copy
|
@click.stop="copyToClipboard(feedSubscription.metadata.feedUrl)">content_copy
|
||||||
</button>
|
</button>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
<ui-tooltip direction="top" :text="$strings.ButtonForceReCheckFeed">
|
<ui-tooltip direction="top" :text="$strings.ButtonForceReCheckFeed">
|
||||||
<button class="inline-flex material-icons text-xl mx-1 mt-1 text-white/70 hover:text-white/100"
|
<button class="inline-flex material-icons text-xl mx-1 mt-1 text-white/70 hover:text-white/100"
|
||||||
@click.stop="forceRecheckFeed(incomingFeed)"
|
@click.stop="forceRecheckFeed(feedSubscription)"
|
||||||
:disabled="incomingFeed.isLoading">
|
:disabled="feedSubscription.isLoading">
|
||||||
<span v-if="incomingFeed.isLoading" class="material-icons">hourglass_empty</span>
|
<span v-if="feedSubscription.isLoading" class="material-icons">hourglass_empty</span>
|
||||||
<span v-else class="material-icons">autorenew</span>
|
<span v-else class="material-icons">autorenew</span>
|
||||||
</button>
|
</button>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|
@ -201,14 +201,14 @@ export default {
|
||||||
showFeedModal: false,
|
showFeedModal: false,
|
||||||
selectedFeed: null,
|
selectedFeed: null,
|
||||||
feeds: [],
|
feeds: [],
|
||||||
incomingFeeds: [],
|
feedSubscriptions: [],
|
||||||
feedsSearch: null,
|
feedsSearch: null,
|
||||||
feedsSearchTimeout: null,
|
feedsSearchTimeout: null,
|
||||||
feedsSearchText: null,
|
feedsSearchText: null,
|
||||||
incomingFeedsSearch: null,
|
feedSubscriptionsSearch: null,
|
||||||
incomingFeedsSearchTimeout: null,
|
feedSubscriptionsSearchTimeout: null,
|
||||||
incomingFeedsSearchText: null,
|
feedSubscriptionsSearchText: null,
|
||||||
incomingFeedShowOnlyUnhealthy: false,
|
feedSubscriptionsShowOnlyUnhealthy: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -230,17 +230,17 @@ export default {
|
||||||
return feed?.meta?.title?.toLowerCase().includes(this.feedsSearchText) || feed?.slug?.toLowerCase().includes(this.feedsSearchText)
|
return feed?.meta?.title?.toLowerCase().includes(this.feedsSearchText) || feed?.slug?.toLowerCase().includes(this.feedsSearchText)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
incomingFeedsSorted() {
|
feedSubscriptionsSorted() {
|
||||||
return this.incomingFeedShowOnlyUnhealthy
|
return this.feedSubscriptionsShowOnlyUnhealthy
|
||||||
? this.incomingFeeds.filter(incomingFeed => !incomingFeed.metadata.feedHealthy)
|
? this.feedSubscriptions.filter(feedSubscription => !feedSubscription.metadata.feedHealthy)
|
||||||
: this.incomingFeeds;
|
: this.feedSubscriptions;
|
||||||
},
|
},
|
||||||
incomingFeedsList() {
|
feedSubscriptionsList() {
|
||||||
return this.incomingFeedsSorted.filter((incomingFeed) => {
|
return this.feedSubscriptionsSorted.filter((feedSubscription) => {
|
||||||
if (!this.incomingFeedsSearchText) return true
|
if (!this.feedSubscriptionsSearchText) return true
|
||||||
if (this.incomingFeedShowOnlyUnhealthy && incomingFeed?.metadata?.feedHealthy) return false
|
if (this.feedSubscriptionsShowOnlyUnhealthy && feedSubscription?.metadata?.feedHealthy) return false
|
||||||
return incomingFeed?.metadata?.title?.toLowerCase().includes(this.incomingFeedsSearchText) ||
|
return feedSubscription?.metadata?.title?.toLowerCase().includes(this.feedSubscriptionsSearchText) ||
|
||||||
incomingFeed?.metadata?.feedUrl?.toLowerCase().includes(this.incomingFeedsSearchText)
|
feedSubscription?.metadata?.feedUrl?.toLowerCase().includes(this.feedSubscriptionsSearchText)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -256,15 +256,15 @@ export default {
|
||||||
this.feedsSearchText = this.feedsSearch.toLowerCase().trim()
|
this.feedsSearchText = this.feedsSearch.toLowerCase().trim()
|
||||||
}, 500)
|
}, 500)
|
||||||
},
|
},
|
||||||
incomingFeedsSubmit() {},
|
feedSubscriptionsSubmit() {},
|
||||||
incomingFeedsInputUpdate() {
|
feedSubscriptionsInputUpdate() {
|
||||||
clearTimeout(this.incomingFeedsSearchTimeout)
|
clearTimeout(this.feedSubscriptionsSearchTimeout)
|
||||||
this.incomingFeedsSearchTimeout = setTimeout(() => {
|
this.feedSubscriptionsSearchTimeout = setTimeout(() => {
|
||||||
if (!this.incomingFeedsSearch || !this.incomingFeedsSearch.trim()) {
|
if (!this.feedSubscriptionsSearch || !this.feedSubscriptionsSearch.trim()) {
|
||||||
this.incomingFeedsSearchText = ''
|
this.feedSubscriptionsSearchText = ''
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.incomingFeedsSearchText = this.incomingFeedsSearch.toLowerCase().trim()
|
this.feedSubscriptionsSearchText = this.feedSubscriptionsSearch.toLowerCase().trim()
|
||||||
}, 500)
|
}, 500)
|
||||||
},
|
},
|
||||||
showFeed(feed) {
|
showFeed(feed) {
|
||||||
|
|
@ -355,21 +355,21 @@ export default {
|
||||||
}
|
}
|
||||||
this.feeds = data.feeds
|
this.feeds = data.feeds
|
||||||
},
|
},
|
||||||
async loadIncomingFeeds() {
|
async loadPodcastsWithExternalFeedSubscriptions() {
|
||||||
const data = await this.$axios.$get(`/api/podcasts/incomingFeeds`).catch((err) => {
|
const data = await this.$axios.$get(`/api/podcasts/external-podcast-feeds-status`).catch((err) => {
|
||||||
console.error('Failed to load incoming RSS feeds', err)
|
console.error('Failed to load podcasts with external feed subscriptions', err)
|
||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
if (!data) {
|
if (!data) {
|
||||||
this.$toast.error('Failed to load incoming RSS feeds')
|
this.$toast.error('Failed to load podcasts with external feed subscriptions')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.incomingFeeds = data.podcasts.map(podcast => ({...podcast, isLoading: false}));
|
this.feedSubscriptions = data.podcasts.map(podcast => ({...podcast, isLoading: false}));
|
||||||
},
|
},
|
||||||
init() {
|
init() {
|
||||||
this.loadFeeds()
|
this.loadFeeds()
|
||||||
this.loadIncomingFeeds()
|
this.loadPodcastsWithExternalFeedSubscriptions()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@
|
||||||
"HeaderEpisodes": "Episodes",
|
"HeaderEpisodes": "Episodes",
|
||||||
"HeaderEreaderDevices": "Ereader Devices",
|
"HeaderEreaderDevices": "Ereader Devices",
|
||||||
"HeaderEreaderSettings": "Ereader Settings",
|
"HeaderEreaderSettings": "Ereader Settings",
|
||||||
"HeaderExternalFeedURLHealthChecker": "External Feed URL Health Checker",
|
"HeaderExternalFeedURLHealthChecker": "External Podcast Feeds Subscription Health Checker",
|
||||||
"HeaderFiles": "Files",
|
"HeaderFiles": "Files",
|
||||||
"HeaderFindChapters": "Find Chapters",
|
"HeaderFindChapters": "Find Chapters",
|
||||||
"HeaderIgnoredFiles": "Ignored Files",
|
"HeaderIgnoredFiles": "Ignored Files",
|
||||||
|
|
|
||||||
|
|
@ -130,8 +130,8 @@ class PodcastController {
|
||||||
res.json({ podcast })
|
res.json({ podcast })
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPodcastsWithIncomingFeeds(req, res) {
|
async getPodcastsWithExternalFeedsSubscriptions(req, res) {
|
||||||
const podcasts = await Database.podcastModel.getAllIncomingFeeds()
|
const podcasts = await Database.podcastModel.getAllIWithFeedSubscriptions()
|
||||||
res.json({
|
res.json({
|
||||||
podcasts
|
podcasts
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -335,7 +335,7 @@ class PodcastManager {
|
||||||
}
|
}
|
||||||
podcast.lastEpisodeCheck = Date.now()
|
podcast.lastEpisodeCheck = Date.now()
|
||||||
podcast.updatedAt = Date.now()
|
podcast.updatedAt = Date.now()
|
||||||
await Database.podcastModel.update(podcast, {where: { id: podcastId }})
|
await podcast.save()
|
||||||
|
|
||||||
return {lastEpisodeCheck: podcast.lastEpisodeCheck, lastSuccessfulFetchAt: podcast.lastSuccessfulFetchAt, feedHealthy: podcast.feedHealthy}
|
return {lastEpisodeCheck: podcast.lastEpisodeCheck, lastSuccessfulFetchAt: podcast.lastSuccessfulFetchAt, feedHealthy: podcast.feedHealthy}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ class Podcast extends Model {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getAllIncomingFeeds() {
|
static async getAllIWithFeedSubscriptions() {
|
||||||
const podcasts = await this.findAll()
|
const podcasts = await this.findAll()
|
||||||
const podcastsFiltered = podcasts.filter(p => p.dataValues.feedURL !== null);
|
const podcastsFiltered = podcasts.filter(p => p.dataValues.feedURL !== null);
|
||||||
return podcastsFiltered.map(p => this.getOldPodcast({media: p.dataValues}))
|
return podcastsFiltered.map(p => this.getOldPodcast({media: p.dataValues}))
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ class ApiRouter {
|
||||||
//
|
//
|
||||||
this.router.post('/podcasts', PodcastController.create.bind(this))
|
this.router.post('/podcasts', PodcastController.create.bind(this))
|
||||||
this.router.post('/podcasts/feed', PodcastController.getPodcastFeed.bind(this))
|
this.router.post('/podcasts/feed', PodcastController.getPodcastFeed.bind(this))
|
||||||
this.router.get('/podcasts/incomingFeeds', PodcastController.getPodcastsWithIncomingFeeds.bind(this))
|
this.router.get('/podcasts/external-podcast-feeds-status', PodcastController.getPodcastsWithExternalFeedsSubscriptions.bind(this))
|
||||||
this.router.get('/podcasts/:id/feed', PodcastController.middleware.bind(this), PodcastController.checkPodcastFeed.bind(this))
|
this.router.get('/podcasts/:id/feed', PodcastController.middleware.bind(this), PodcastController.checkPodcastFeed.bind(this))
|
||||||
this.router.get('/podcasts/:id/check-feed-url', PodcastController.checkPodcastFeedUrl.bind(this))
|
this.router.get('/podcasts/:id/check-feed-url', PodcastController.checkPodcastFeedUrl.bind(this))
|
||||||
this.router.post('/podcasts/opml', PodcastController.getFeedsFromOPMLText.bind(this))
|
this.router.post('/podcasts/opml', PodcastController.getFeedsFromOPMLText.bind(this))
|
||||||
|
|
|
||||||
|
|
@ -512,7 +512,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get longest podcasts in library
|
* Get the longest podcasts in library
|
||||||
* @param {string} libraryId
|
* @param {string} libraryId
|
||||||
* @param {number} limit
|
* @param {number} limit
|
||||||
* @returns {Promise<{ id:string, title:string, duration:number }[]>}
|
* @returns {Promise<{ id:string, title:string, duration:number }[]>}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue