New data model play media entity, PlaybackSessionManager

This commit is contained in:
advplyr 2022-03-17 19:10:47 -05:00
parent 1cf9e85272
commit 099ae7c776
54 changed files with 841 additions and 902 deletions

View file

@ -95,7 +95,7 @@ export default {
if (!store.getters['user/getUserCanUpdate']) {
return redirect('/?error=unauthorized')
}
var payload = await app.$axios.$get(`/api/audiobooks/${params.id}/item?expanded=1`).catch((error) => {
var payload = await app.$axios.$get(`/api/entities/${params.id}/item?expanded=1`).catch((error) => {
console.error('Failed', error)
return false
})
@ -103,7 +103,7 @@ export default {
console.error('Not found...', params.id)
return redirect('/')
}
const audiobook = payload.audiobook
const audiobook = payload.mediaEntity
return {
audiobook,
libraryItem: payload.libraryItem,
@ -218,7 +218,7 @@ export default {
this.saving = true
this.$axios
.$patch(`/api/audiobooks/${this.audiobook.id}/tracks`, { orderedFileData })
.$patch(`/api/entities/${this.audiobook.id}/tracks`, { orderedFileData })
.then((data) => {
console.log('Finished patching files', data)
this.saving = false

View file

@ -9,8 +9,8 @@
/>
</svg>
<div class="px-3">
<p class="text-4xl md:text-5xl font-bold">{{ userAudiobooksRead.length }}</p>
<p class="font-book text-xs md:text-sm text-white text-opacity-80">Books Read</p>
<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>
</div>
</div>
@ -35,17 +35,17 @@
<div class="w-80 my-6 mx-auto">
<h1 class="text-2xl mb-4 font-book">Recent Listening Sessions</h1>
<p v-if="!mostRecentListeningSessions.length">No Listening Sessions</p>
<template v-for="(book, index) in mostRecentListeningSessions">
<div :key="book.id" class="w-full py-0.5">
<template v-for="(item, index) in mostRecentListeningSessions">
<div :key="item.id" class="w-full py-0.5">
<div class="flex items-center mb-1">
<p class="text-sm font-book text-white text-opacity-70 w-6 truncate">{{ index + 1 }}.&nbsp;</p>
<div class="w-56">
<p class="text-sm font-book text-white text-opacity-80 truncate">{{ book.audiobookTitle }}</p>
<p class="text-xs text-white text-opacity-50">{{ $dateDistanceFromNow(book.lastUpdate) }}</p>
<p class="text-sm font-book text-white text-opacity-80 truncate">{{ item.mediaMetadata.title }}</p>
<p class="text-xs text-white text-opacity-50">{{ $dateDistanceFromNow(item.lastUpdate) }}</p>
</div>
<div class="flex-grow" />
<div class="w-18 text-right">
<p class="text-sm font-bold">{{ $elapsedPretty(book.timeListening) }}</p>
<p class="text-sm font-bold">{{ $elapsedPretty(item.timeListening) }}</p>
</div>
</div>
</div>
@ -76,16 +76,11 @@ export default {
currentLibraryId() {
return this.$store.state.libraries.currentLibraryId
},
userAudiobooks() {
return Object.values(this.user.audiobooks || {})
userItemProgress() {
return this.user.libraryItemProgress || []
},
userAudiobooksRead() {
return this.userAudiobooks.filter((ab) => !!ab.isRead)
},
mostRecentBooksListened() {
if (!this.listeningStats) return []
var sorted = Object.values(this.listeningStats.books || {}).sort((a, b) => b.lastUpdate - a.lastUpdate)
return sorted.slice(0, 10)
userItemsFinished() {
return this.userItemProgress.filter((lip) => !!lip.isFinished)
},
mostRecentListeningSessions() {
if (!this.listeningStats) return []

View file

@ -14,7 +14,10 @@
<h1 class="text-xl pl-2">{{ username }}</h1>
</div>
<div class="cursor-pointer text-gray-400 hover:text-white" @click="copyToClipboard(userToken)">
<p class="py-2 text-xs"><strong class="text-white">API Token: </strong><br /><span class="text-white">{{ userToken }}</span><span class="material-icons pl-2 text-base">content_copy</span></p>
<p class="py-2 text-xs">
<strong class="text-white">API Token: </strong><br /><span class="text-white">{{ userToken }}</span
><span class="material-icons pl-2 text-base">content_copy</span>
</p>
</div>
<div v-if="showExperimentalFeatures" class="w-full h-px bg-white bg-opacity-10 my-2" />
<div v-if="showExperimentalFeatures" class="py-2">
@ -35,32 +38,32 @@
</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">Reading Progress</h1>
<table v-if="userAudiobooks.length" class="userAudiobooksTable">
<h1 class="text-lg mb-2 text-white text-opacity-90 px-2 sm:px-0">Item Progress</h1>
<table v-if="libraryItemProgress.length" class="userAudiobooksTable">
<tr class="bg-primary bg-opacity-40">
<th class="w-16 text-left">Book</th>
<th class="w-16 text-left">Item</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>
</tr>
<tr v-for="ab in userAudiobooks" :key="ab.audiobookId" :class="!ab.isRead ? '' : 'isRead'">
<tr v-for="item in libraryItemProgress" :key="item.id" :class="!item.isFinished ? '' : 'isFinished'">
<td>
<covers-book-cover :width="50" :library-item="ab" :book-cover-aspect-ratio="bookCoverAspectRatio" />
<covers-book-cover :width="50" :library-item="item" :book-cover-aspect-ratio="bookCoverAspectRatio" />
</td>
<td class="font-book">
<p>{{ ab.media && ab.media.metadata ? ab.media.metadata.title : ab.audiobookTitle || 'Unknown' }}</p>
<p v-if="ab.media && ab.media.metadata && ab.media.metadata.authorName" class="text-white text-opacity-50 text-sm font-sans">by {{ ab.media.metadata.authorName }}</p>
<p>{{ item.media && item.media.metadata ? item.media.metadata.title : 'Unknown' }}</p>
<p v-if="item.media && item.media.metadata && item.media.metadata.authorName" class="text-white text-opacity-50 text-sm font-sans">by {{ item.media.metadata.authorName }}</p>
</td>
<td class="text-center">{{ Math.floor(ab.progress * 100) }}%</td>
<td class="text-center">{{ Math.floor(item.progress * 100) }}%</td>
<td class="text-center hidden sm:table-cell">
<ui-tooltip v-if="ab.startedAt" direction="top" :text="$formatDate(ab.startedAt, 'MMMM do, yyyy HH:mm')">
<p class="text-sm">{{ $dateDistanceFromNow(ab.startedAt) }}</p>
<ui-tooltip v-if="item.startedAt" direction="top" :text="$formatDate(item.startedAt, 'MMMM do, yyyy HH:mm')">
<p class="text-sm">{{ $dateDistanceFromNow(item.startedAt) }}</p>
</ui-tooltip>
</td>
<td class="text-center hidden sm:table-cell">
<ui-tooltip v-if="ab.lastUpdate" direction="top" :text="$formatDate(ab.lastUpdate, 'MMMM do, yyyy HH:mm')">
<p class="text-sm">{{ $dateDistanceFromNow(ab.lastUpdate) }}</p>
<ui-tooltip v-if="item.lastUpdate" direction="top" :text="$formatDate(item.lastUpdate, 'MMMM do, yyyy HH:mm')">
<p class="text-sm">{{ $dateDistanceFromNow(item.lastUpdate) }}</p>
</ui-tooltip>
</td>
</tr>
@ -108,15 +111,8 @@ export default {
userOnline() {
return this.$store.getters['users/getIsUserOnline'](this.user.id)
},
userAudiobooks() {
return Object.values(this.user.audiobooks || {})
.map((uab) => {
return {
id: uab.audiobookId,
...uab
}
})
.sort((a, b) => b.lastUpdate - a.lastUpdate)
libraryItemProgress() {
return this.user.libraryItemProgress.sort((a, b) => b.lastUpdate - a.lastUpdate)
},
totalListeningTime() {
return this.listeningStats.totalTime || 0
@ -169,7 +165,7 @@ export default {
.userAudiobooksTable tr:hover:not(:first-child) {
background-color: #474747;
}
.userAudiobooksTable tr.isRead {
.userAudiobooksTable tr.isFinished {
background-color: rgba(76, 175, 80, 0.1);
}
.userAudiobooksTable td {