-
-
Top 5 Genres
-
-
-
-
{{ Math.round((100 * genre.count) / totalBooks) }} %
-
-
{{ genre.genre }}
-
-
-
-
+
+
event
+
+
{{ totalDaysListened }}
+
Days Listened
+
-
-
Top 10 Authors
-
-
-
-
{{ index + 1 }}. {{ author.author }}
-
-
-
-
-
+
+
+
watch_later
+
+
{{ totalMinutesListening }}
+
Minutes Listening
+
+
+
+
+
Recent Listening Sessions
+
No Listening Sessions
+
+
+
+
{{ index + 1 }}.
+
+
{{ book.audiobookTitle }}
+
{{ $dateDistanceFromNow(book.lastUpdate) }}
+
+
+
+
{{ $elapsedPretty(book.timeListening) }}
+
+
+
+
+
@@ -58,27 +74,31 @@ export default {
user() {
return this.$store.state.user.user
},
- totalBooks() {
- return this.libraryStats ? this.libraryStats.totalBooks : 0
- },
- genresWithCount() {
- return this.libraryStats ? this.libraryStats.genresWithCount : []
- },
- top5Genres() {
- return this.genresWithCount.slice(0, 5)
- },
- authorsWithCount() {
- return this.libraryStats ? this.libraryStats.authorsWithCount : []
- },
- mostUsedAuthorCount() {
- if (!this.authorsWithCount.length) return 0
- return this.authorsWithCount[0].count
- },
- top10Authors() {
- return this.authorsWithCount.slice(0, 10)
- },
currentLibraryId() {
return this.$store.state.libraries.currentLibraryId
+ },
+ userAudiobooks() {
+ return Object.values(this.user.audiobooks || {})
+ },
+ 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)
+ },
+ mostRecentListeningSessions() {
+ if (!this.listeningStats) return []
+ return this.listeningStats.recentSessions || []
+ },
+ totalMinutesListening() {
+ if (!this.listeningStats) return 0
+ return Math.round(this.listeningStats.totalTime / 60)
+ },
+ totalDaysListened() {
+ if (!this.listeningStats) return 0
+ return Object.values(this.listeningStats.days).length
}
},
methods: {
@@ -88,7 +108,6 @@ export default {
var errorMsg = err.response ? err.response.data || 'Unknown Error' : 'Unknown Error'
this.$toast.error(`Failed to get library stats: ${errorMsg}`)
})
- console.log('lib stats', this.libraryStats)
this.listeningStats = await this.$axios.$get(`/api/me/listening-stats`).catch((err) => {
console.error('Failed to load listening sesions', err)
return []
diff --git a/client/store/libraries.js b/client/store/libraries.js
index c4a51a2e..3ed19240 100644
--- a/client/store/libraries.js
+++ b/client/store/libraries.js
@@ -13,6 +13,11 @@ export const getters = {
getCurrentLibrary: state => {
return state.libraries.find(lib => lib.id === state.currentLibraryId)
},
+ getCurrentLibraryName: (state, getters) => {
+ var currentLibrary = getters.getCurrentLibrary
+ if (!currentLibrary) return ''
+ return currentLibrary.name
+ },
getSortedLibraries: state => () => {
return state.libraries.map(lib => ({ ...lib })).sort((a, b) => a.displayOrder - b.displayOrder)
}
diff --git a/server/ApiController.js b/server/ApiController.js
index 2fe3315d..6a120cb9 100644
--- a/server/ApiController.js
+++ b/server/ApiController.js
@@ -458,14 +458,15 @@ class ApiController {
books: {},
days: {},
dayOfWeek: {},
- today: 0
+ today: 0,
+ recentSessions: listeningSessions.slice(0, 10)
}
listeningSessions.forEach((s) => {
if (s.dayOfWeek) {
if (!listeningStats.dayOfWeek[s.dayOfWeek]) listeningStats.dayOfWeek[s.dayOfWeek] = 0
listeningStats.dayOfWeek[s.dayOfWeek] += s.timeListening
}
- if (s.date) {
+ if (s.date && s.timeListening > 0) {
if (!listeningStats.days[s.date]) listeningStats.days[s.date] = 0
listeningStats.days[s.date] += s.timeListening
@@ -473,8 +474,17 @@ class ApiController {
listeningStats.today += s.timeListening
}
}
- if (!listeningStats.books[s.audiobookId]) listeningStats.books[s.audiobookId] = 0
- listeningStats.books[s.audiobookId] += s.timeListening
+ if (!listeningStats.books[s.audiobookId]) {
+ listeningStats.books[s.audiobookId] = {
+ id: s.audiobookId,
+ timeListening: s.timeListening,
+ title: s.audiobookTitle,
+ author: s.audiobookAuthor,
+ lastUpdate: s.lastUpdate
+ }
+ } else {
+ listeningStats.books[s.audiobookId].timeListening += s.timeListening
+ }
listeningStats.totalTime += s.timeListening
})
diff --git a/server/controllers/LibraryController.js b/server/controllers/LibraryController.js
index ddc89d3a..286704be 100644
--- a/server/controllers/LibraryController.js
+++ b/server/controllers/LibraryController.js
@@ -375,11 +375,14 @@ class LibraryController {
var authorsWithCount = libraryHelpers.getAuthorsWithCount(audiobooksInLibrary)
var genresWithCount = libraryHelpers.getGenresWithCount(audiobooksInLibrary)
+ var abDurationStats = libraryHelpers.getAudiobookDurationStats(audiobooksInLibrary)
var stats = {
totalBooks: audiobooksInLibrary.length,
totalAuthors: Object.keys(authorsWithCount).length,
totalGenres: Object.keys(genresWithCount).length,
- totalDuration: libraryHelpers.getAudiobooksTotalDuration(audiobooksInLibrary),
+ totalDuration: abDurationStats.totalDuration,
+ longestAudiobooks: abDurationStats.longstAudiobooks,
+ numAudioTracks: abDurationStats.numAudioTracks,
totalSize: libraryHelpers.getAudiobooksTotalSize(audiobooksInLibrary),
authorsWithCount,
genresWithCount
diff --git a/server/objects/UserListeningSession.js b/server/objects/UserListeningSession.js
index 35985e67..41e4506f 100644
--- a/server/objects/UserListeningSession.js
+++ b/server/objects/UserListeningSession.js
@@ -10,6 +10,7 @@ class UserListeningSession {
this.audiobookId = null
this.audiobookTitle = null
this.audiobookAuthor = null
+ this.audiobookDuration = 0
this.audiobookGenres = []
this.date = null
@@ -32,6 +33,7 @@ class UserListeningSession {
audiobookId: this.audiobookId,
audiobookTitle: this.audiobookTitle,
audiobookAuthor: this.audiobookAuthor,
+ audiobookDuration: this.audiobookDuration,
audiobookGenres: [...this.audiobookGenres],
date: this.date,
dayOfWeek: this.dayOfWeek,
@@ -48,6 +50,7 @@ class UserListeningSession {
this.audiobookId = session.audiobookId
this.audiobookTitle = session.audiobookTitle
this.audiobookAuthor = session.audiobookAuthor
+ this.audiobookDuration = session.audiobookDuration || 0
this.audiobookGenres = session.audiobookGenres
this.date = session.date
@@ -64,6 +67,7 @@ class UserListeningSession {
this.audiobookId = audiobook.id
this.audiobookTitle = audiobook.title || ''
this.audiobookAuthor = audiobook.authorFL || ''
+ this.audiobookDuration = audiobook.duration || 0
this.audiobookGenres = [...audiobook.genres]
this.timeListening = 0
diff --git a/server/utils/libraryHelpers.js b/server/utils/libraryHelpers.js
index 753169ba..978549b6 100644
--- a/server/utils/libraryHelpers.js
+++ b/server/utils/libraryHelpers.js
@@ -182,12 +182,20 @@ module.exports = {
return Object.values(authorsMap).sort((a, b) => b.count - a.count)
},
- getAudiobooksTotalDuration(audiobooks) {
+ getAudiobookDurationStats(audiobooks) {
+ var sorted = sort(audiobooks).desc(a => a.duration)
+ var top10 = sorted.slice(0, 10).map(ab => ({ title: ab.book.title, duration: ab.duration })).filter(ab => ab.duration > 0)
var totalDuration = 0
+ var numAudioTracks = 0
audiobooks.forEach((ab) => {
totalDuration += ab.duration
+ numAudioTracks += ab.tracks.length
})
- return totalDuration
+ return {
+ totalDuration,
+ numAudioTracks,
+ longstAudiobooks: top10
+ }
},
getAudiobooksTotalSize(audiobooks) {