Feature/99 fix progress sync (#115)

This commit is contained in:
Max Grakov
2025-02-01 18:51:18 +01:00
committed by GitHub
parent 4916f37016
commit 3d7af47e5f
7 changed files with 48 additions and 9 deletions

View File

@@ -29,8 +29,8 @@ android {
applicationId = "org.grakovne.lissen"
minSdk = 28
targetSdk = 35
versionCode = 67
versionName = "1.2.6"
versionCode = 68
versionName = "1.2.7"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {

View File

@@ -56,14 +56,16 @@ abstract class AudiobookshelfChannel(
.map { libraryResponseConverter.apply(it) }
override suspend fun fetchRecentListenedBooks(libraryId: String): ApiResult<List<RecentBook>> {
val progress: Map<String, Double> = dataRepository
val progress: Map<String, Pair<Long, Double>> = dataRepository
.fetchUserInfoResponse()
.fold(
onSuccess = {
it
.user
.mediaProgress
?.associate { item -> item.libraryItemId to item.progress }
?.groupBy { item -> item.libraryItemId }
?.map { (item, value) -> item to value.maxBy { progress -> progress.lastUpdate } }
?.associate { (item, progress) -> item to (progress.lastUpdate to progress.progress) }
?: emptyMap()
},
onFailure = { emptyMap() },

View File

@@ -10,7 +10,7 @@ class RecentListeningResponseConverter @Inject constructor() {
fun apply(
response: List<PersonalizedFeedResponse>,
progress: Map<String, Double>,
progress: Map<String, Pair<Long, Double>>,
): List<RecentBook> = response
.find { it.labelStringKey == LABEL_CONTINUE_LISTENING }
?.entities
@@ -20,7 +20,8 @@ class RecentListeningResponseConverter @Inject constructor() {
id = it.id,
title = it.media.metadata.title,
author = it.media.metadata.authorName,
listenedPercentage = progress[it.id]?.let { it * 100 }?.toInt(),
listenedPercentage = progress[it.id]?.second?.let { it * 100 }?.toInt(),
listenedLastUpdate = progress[it.id]?.first ,
)
} ?: emptyList()

View File

@@ -151,7 +151,9 @@ class LissenMediaProvider @Inject constructor(
return when (sharedPreferences.isForceCache()) {
true -> localCacheRepository.fetchRecentListenedBooks()
false -> providePreferredChannel().fetchRecentListenedBooks(libraryId)
false -> providePreferredChannel()
.fetchRecentListenedBooks(libraryId)
.map { items -> syncFromLocalProgress(items) }
}
}
@@ -182,6 +184,37 @@ class LissenMediaProvider @Inject constructor(
return provideAuthService().authorize(host, username, password)
}
private suspend fun syncFromLocalProgress(
detailedItems: List<RecentBook>,
): List<RecentBook> {
val localRecentlyBooks = localCacheRepository
.fetchRecentListenedBooks()
.fold(
onSuccess = { it },
onFailure = { return@fold detailedItems },
)
val syncedRecentlyBooks = detailedItems
.mapNotNull { item -> localRecentlyBooks.find { it.id == item.id }?.let { item to it } }
.map { (remote, local) ->
val localTimestamp = local.listenedLastUpdate ?: return@map remote
val remoteTimestamp = remote.listenedLastUpdate ?: return@map remote
when (remoteTimestamp > localTimestamp) {
true -> remote
false -> local
}
}
return detailedItems
.map { item ->
syncedRecentlyBooks
.find { item.id == it.id }
?.let { local -> item.copy(listenedPercentage = local.listenedPercentage) }
?: item
}
}
private suspend fun syncFromLocalProgress(detailedItem: DetailedItem): DetailedItem {
val cachedBook = localCacheRepository.fetchBook(detailedItem.id) ?: return detailedItem

View File

@@ -78,7 +78,7 @@ class CachedBookRepository @Inject constructor(
val progress = recentBooks
.map { it.id }
.mapNotNull { bookDao.fetchMediaProgress(it) }
.associate { it.bookId to it.currentTime }
.associate { it.bookId to (it.lastUpdate to it.currentTime) }
return recentBooks
.map { cachedBookEntityRecentConverter.apply(it, progress[it.id]) }

View File

@@ -8,11 +8,13 @@ import javax.inject.Singleton
@Singleton
class CachedBookEntityRecentConverter @Inject constructor() {
fun apply(entity: BookEntity, currentTime: Double?): RecentBook = RecentBook(
fun apply(entity: BookEntity, currentTime: Pair<Long, Double>?): RecentBook = RecentBook(
id = entity.id,
title = entity.title,
author = entity.author,
listenedLastUpdate = currentTime?.first ?: 0,
listenedPercentage = currentTime
?.second
?.let { it / entity.duration }
?.let { it * 100 }
?.toInt(),

View File

@@ -5,4 +5,5 @@ data class RecentBook(
val title: String,
val author: String?,
val listenedPercentage: Int?,
val listenedLastUpdate: Long?,
)