diff --git a/app/src/main/java/com/jocmp/capyreader/common/MD5.kt b/app/src/main/java/com/jocmp/capyreader/common/MD5.kt new file mode 100644 index 00000000..d2fff041 --- /dev/null +++ b/app/src/main/java/com/jocmp/capyreader/common/MD5.kt @@ -0,0 +1,12 @@ +package com.jocmp.capyreader.common + +import java.security.MessageDigest + +@OptIn(ExperimentalStdlibApi::class) +object MD5 { + fun from(value: String): String { + val md = MessageDigest.getInstance("MD5") + val digest = md.digest(value.toByteArray()) + return digest.toHexString() + } +} diff --git a/app/src/main/java/com/jocmp/capyreader/sync/ReadSyncWorker.kt b/app/src/main/java/com/jocmp/capyreader/sync/ReadSyncWorker.kt index 3014a24b..805d0ffd 100644 --- a/app/src/main/java/com/jocmp/capyreader/sync/ReadSyncWorker.kt +++ b/app/src/main/java/com/jocmp/capyreader/sync/ReadSyncWorker.kt @@ -16,13 +16,18 @@ class ReadSyncWorker( private val account by inject() override suspend fun doWork(): Result { - val articleID = inputData.getString(ARTICLE_KEY) ?: return Result.failure() + val articleIDs = inputData + .getStringArray(ARTICLES_KEY)?.toList() ?: return Result.failure() val markRead = inputData.getBoolean(MARK_READ_KEY, false) + if (articleIDs.isEmpty()) { + return Result.failure() + } + val result = if (markRead) { - account.markRead(articleID) + account.markAllRead(articleIDs) } else { - account.markUnread(articleID) + account.markUnread(articleIDs.first()) } return result @@ -39,7 +44,7 @@ class ReadSyncWorker( } companion object { - const val ARTICLE_KEY = "article_id" + const val ARTICLES_KEY = "articles_key" const val MARK_READ_KEY = "mark_read" } } diff --git a/app/src/main/java/com/jocmp/capyreader/sync/Sync.kt b/app/src/main/java/com/jocmp/capyreader/sync/Sync.kt index 5cad8f45..fd1c35a3 100644 --- a/app/src/main/java/com/jocmp/capyreader/sync/Sync.kt +++ b/app/src/main/java/com/jocmp/capyreader/sync/Sync.kt @@ -7,6 +7,7 @@ import androidx.work.ExistingWorkPolicy import androidx.work.NetworkType import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkManager +import com.jocmp.capyreader.common.MD5 fun addStarAsync(articleID: String, context: Context) { val data = Data @@ -28,27 +29,29 @@ fun removeStarAsync(articleID: String, context: Context) { queueStarWorker(articleID, data, context) } -fun markReadAsync(articleID: String, context: Context) { +fun markReadAsync(articleIDs: List, context: Context) { val data = Data .Builder() - .putString(ReadSyncWorker.ARTICLE_KEY, articleID) + .putStringArray(ReadSyncWorker.ARTICLES_KEY, articleIDs.toTypedArray()) .putBoolean(ReadSyncWorker.MARK_READ_KEY, true) .build() - queueReadWorker(articleID, data, context) + queueReadWorker(articleIDs, data, context) } fun markUnreadAsync(articleID: String, context: Context) { + val articleIDs = listOf(articleID) + val data = Data .Builder() - .putString(ReadSyncWorker.ARTICLE_KEY, articleID) + .putStringArray(ReadSyncWorker.ARTICLES_KEY, articleIDs.toTypedArray()) .putBoolean(ReadSyncWorker.MARK_READ_KEY, false) .build() - queueReadWorker(articleID, data, context) + queueReadWorker(articleIDs, data, context) } -private fun queueReadWorker(articleID: String, data: Data, context: Context) { +private fun queueReadWorker(articleIDs: List, data: Data, context: Context) { val workManager = WorkManager.getInstance(context) val request = OneTimeWorkRequestBuilder() @@ -56,8 +59,10 @@ private fun queueReadWorker(articleID: String, data: Data, context: Context) { .setInputData(data) .build() + val key = MD5.from(articleIDs.joinToString(",")) + workManager.enqueueUniqueWork( - "article_read:${articleID}", + "article_read:$key", ExistingWorkPolicy.REPLACE, request ) diff --git a/app/src/main/java/com/jocmp/capyreader/ui/articles/ArticleScreenViewModel.kt b/app/src/main/java/com/jocmp/capyreader/ui/articles/ArticleScreenViewModel.kt index 978fafb6..e2fe4439 100644 --- a/app/src/main/java/com/jocmp/capyreader/ui/articles/ArticleScreenViewModel.kt +++ b/app/src/main/java/com/jocmp/capyreader/ui/articles/ArticleScreenViewModel.kt @@ -108,7 +108,9 @@ class ArticleScreenViewModel( fun markAllRead(range: MarkRead) { viewModelScope.launch(Dispatchers.IO) { - account.markAllRead(filter = filter.value, range = range) + val articleIDs = account.unreadArticleIDs(filter = filter.value, range = range) + + markReadAsync(articleIDs, context) } } @@ -203,7 +205,7 @@ class ArticleScreenViewModel( private suspend fun markRead(articleID: String) { account.markRead(articleID) .onFailure { - markReadAsync(articleID, context) + markReadAsync(listOf(articleID), context) } } diff --git a/capy/src/main/java/com/jocmp/capy/Account.kt b/capy/src/main/java/com/jocmp/capy/Account.kt index 2f67675e..02832932 100644 --- a/capy/src/main/java/com/jocmp/capy/Account.kt +++ b/capy/src/main/java/com/jocmp/capy/Account.kt @@ -100,12 +100,14 @@ data class Account( return delegate.removeStar(listOf(articleID)) } - suspend fun markAllRead(filter: ArticleFilter, range: MarkRead): Result { - val articleIDs = articleRecords.unreadArticleIDs( + fun unreadArticleIDs(filter: ArticleFilter, range: MarkRead): List { + return articleRecords.unreadArticleIDs( filter = filter, range = range ) + } + suspend fun markAllRead(articleIDs: List): Result { articleRecords.markAllRead(articleIDs) return delegate.markRead(articleIDs)