mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-02-28 21:19:42 +00:00
Merge 1204936bf1 into 1d0b7e383a
This commit is contained in:
commit
972f69f273
3 changed files with 49 additions and 2 deletions
|
|
@ -44,6 +44,14 @@
|
|||
<div class="w-6 h-6 rounded-full bg-black/30 flex items-center justify-center ml-3">
|
||||
<span class="font-mono">{{ $formatNumber(numShowing) }}</span>
|
||||
</div>
|
||||
<div v-if="selectedSeries.totalDuration" class="flex items-center ml-4 text-sm opacity-70 pt-0.5 hidden sm:flex">
|
||||
<template v-if="selectedSeries.progress && selectedSeries.progress.totalDurationListened">
|
||||
<span>{{ $elapsedPretty(selectedSeries.progress.totalDurationListened).replace(' hr', 'h').replace(' min', 'm') }}</span>
|
||||
<span class="mx-1.5">/</span>
|
||||
</template>
|
||||
|
||||
<span>{{ $elapsedPretty(selectedSeries.totalDuration).replace(' hr', 'h').replace(' min', 'm') }}</span>
|
||||
</div>
|
||||
<div class="grow" />
|
||||
|
||||
<!-- RSS feed -->
|
||||
|
|
|
|||
|
|
@ -770,7 +770,7 @@ class LibraryController {
|
|||
*
|
||||
* Optional includes (e.g. `?include=rssfeed,progress`)
|
||||
* rssfeed: adds `rssFeed` to series object if a feed is open
|
||||
* progress: adds `progress` to series object with { libraryItemIds:Array<llid>, libraryItemIdsFinished:Array<llid>, isFinished:boolean }
|
||||
* progress: adds `progress` to series object with { libraryItemIds:Array<llid>, libraryItemIdsFinished:Array<llid>, isFinished:boolean, totalDurationListened: number }
|
||||
*
|
||||
* @param {LibraryControllerRequest} req
|
||||
* @param {Response} res - Series
|
||||
|
|
@ -789,10 +789,15 @@ class LibraryController {
|
|||
const seriesJson = series.toOldJSON()
|
||||
if (include.includes('progress')) {
|
||||
const libraryItemsFinished = libraryItemsInSeries.filter((li) => !!req.user.getMediaProgress(li.media.id)?.isFinished)
|
||||
const totalListened = libraryItemsInSeries.reduce((acc, li) => {
|
||||
const p = req.user.getMediaProgress(li.media.id)
|
||||
return acc + (p?.isFinished ? (li.media.duration || 0) : (p?.currentTime || 0))
|
||||
}, 0)
|
||||
seriesJson.progress = {
|
||||
libraryItemIds: libraryItemsInSeries.map((li) => li.id),
|
||||
libraryItemIdsFinished: libraryItemsFinished.map((li) => li.id),
|
||||
isFinished: libraryItemsFinished.length >= libraryItemsInSeries.length
|
||||
isFinished: libraryItemsFinished.length >= libraryItemsInSeries.length,
|
||||
totalDurationListened: totalListened
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -801,6 +806,9 @@ class LibraryController {
|
|||
seriesJson.rssFeed = feedObj?.toOldJSONMinified() || null
|
||||
}
|
||||
|
||||
// populate total duration (same unit as libraryItem.duration)
|
||||
seriesJson.totalDuration = await Database.seriesModel.getTotalDurationById(series.id)
|
||||
|
||||
res.json(seriesJson)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,6 +65,37 @@ class Series extends Model {
|
|||
series.books = await series.getBooksExpandedWithLibraryItem()
|
||||
return series
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} seriesId
|
||||
* @returns {Promise<number>} total duration (same unit as libraryItem.duration)
|
||||
*/
|
||||
static async getTotalDurationById(seriesId) {
|
||||
const { book: bookModel, libraryItem: libraryItemModel, bookSeries: bookSeriesModel } = this.sequelize.models
|
||||
|
||||
// Sum durations on libraryItems for books that belong to the series.
|
||||
// This relies on Sequelize associations existing between:
|
||||
// libraryItem -> book, book -> bookSeries (or bookSeries as a through model).
|
||||
const total = await libraryItemModel.sum('duration', {
|
||||
where: { mediaType: 'book' },
|
||||
include: [
|
||||
{
|
||||
model: bookModel,
|
||||
attributes: [],
|
||||
include: [
|
||||
{
|
||||
model: bookSeriesModel,
|
||||
attributes: [],
|
||||
where: { seriesId }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
return Number(total) || 0
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue