From a9b227924b9cc0b145b7ec1e105eac3d26966f27 Mon Sep 17 00:00:00 2001 From: Ash Date: Thu, 18 Jan 2024 21:28:11 +0800 Subject: [PATCH] feat(greader): support mark as read or starred --- .../model/general/MarkAsReadConditions.kt | 2 +- .../domain/service/GoogleReaderRssService.kt | 53 +++++++++---------- .../rss/provider/greader/GoogleReaderAPI.kt | 43 +++++++++++---- .../ash/reader/ui/page/home/flow/FlowPage.kt | 2 +- 4 files changed, 61 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/me/ash/reader/domain/model/general/MarkAsReadConditions.kt b/app/src/main/java/me/ash/reader/domain/model/general/MarkAsReadConditions.kt index 256ddc0a8..397d559e9 100644 --- a/app/src/main/java/me/ash/reader/domain/model/general/MarkAsReadConditions.kt +++ b/app/src/main/java/me/ash/reader/domain/model/general/MarkAsReadConditions.kt @@ -20,7 +20,7 @@ enum class MarkAsReadConditions { ; fun toDate(): Date? = when (this) { - All -> Date() + All -> null else -> Calendar.getInstance().apply { time = Date() add(Calendar.DAY_OF_MONTH, when (this@MarkAsReadConditions) { diff --git a/app/src/main/java/me/ash/reader/domain/service/GoogleReaderRssService.kt b/app/src/main/java/me/ash/reader/domain/service/GoogleReaderRssService.kt index d87716c0c..10b050efe 100644 --- a/app/src/main/java/me/ash/reader/domain/service/GoogleReaderRssService.kt +++ b/app/src/main/java/me/ash/reader/domain/service/GoogleReaderRssService.kt @@ -28,7 +28,9 @@ import me.ash.reader.infrastructure.di.IODispatcher import me.ash.reader.infrastructure.di.MainDispatcher import me.ash.reader.infrastructure.rss.RssHelper import me.ash.reader.infrastructure.rss.provider.greader.GoogleReaderAPI +import me.ash.reader.infrastructure.rss.provider.greader.GoogleReaderAPI.Companion.ofCategoryIdToStreamId import me.ash.reader.infrastructure.rss.provider.greader.GoogleReaderAPI.Companion.ofCategoryStreamIdToId +import me.ash.reader.infrastructure.rss.provider.greader.GoogleReaderAPI.Companion.ofFeedIdToStreamId import me.ash.reader.infrastructure.rss.provider.greader.GoogleReaderAPI.Companion.ofFeedStreamIdToId import me.ash.reader.infrastructure.rss.provider.greader.GoogleReaderAPI.Companion.ofItemStreamIdToId import me.ash.reader.ui.ext.currentAccountId @@ -346,49 +348,46 @@ class GoogleReaderRssService @Inject constructor( ) { super.markAsRead(groupId, feedId, articleId, before, isUnread) val googleReaderAPI = getGoogleReaderAPI() - val beforeUnixTimestamp = (before?.time ?: Date(Long.MAX_VALUE).time) / 1000 + val sinceTime = before?.time when { groupId != null -> { - // googleReaderAPI.markGroup( - // status = if (isUnread) FeverDTO.StatusEnum.Unread else FeverDTO.StatusEnum.Read, - // id = groupId.dollarLast().toLong(), - // before = beforeUnixTimestamp - // ) + googleReaderAPI.markAllAsRead( + streamId = groupId.dollarLast().ofCategoryIdToStreamId(), + sinceTimestamp = sinceTime + ) } feedId != null -> { - // googleReaderAPI.markFeed( - // status = if (isUnread) FeverDTO.StatusEnum.Unread else FeverDTO.StatusEnum.Read, - // id = feedId.dollarLast().toLong(), - // before = beforeUnixTimestamp - // ) + // TODO: Nothing happened??? + googleReaderAPI.markAllAsRead( + streamId = feedId.dollarLast().ofFeedIdToStreamId(), + sinceTimestamp = sinceTime + ) } articleId != null -> { - // googleReaderAPI.markItem( - // status = if (isUnread) FeverDTO.StatusEnum.Unread else FeverDTO.StatusEnum.Read, - // id = articleId.dollarLast(), - // ) + googleReaderAPI.editTag( + itemIds = listOf(articleId.dollarLast()), + mark = if (!isUnread) GoogleReaderAPI.Label.READ else null, + unmark = if (isUnread) GoogleReaderAPI.Label.READ else null, + ) } else -> { - feedDao.queryAll(context.currentAccountId).forEach { - // googleReaderAPI.markFeed( - // status = if (isUnread) FeverDTO.StatusEnum.Unread else FeverDTO.StatusEnum.Read, - // id = it.id.dollarLast().toLong(), - // before = beforeUnixTimestamp - // ) - } + googleReaderAPI.markAllAsRead( + streamId = GoogleReaderAPI.Label.ALL_ITEMS, + sinceTimestamp = sinceTime + ) } } } override suspend fun markAsStarred(articleId: String, isStarred: Boolean) { super.markAsStarred(articleId, isStarred) - val googleReaderAPI = getGoogleReaderAPI() - // googleReaderAPI.markItem( - // status = if (isStarred) FeverDTO.StatusEnum.Saved else FeverDTO.StatusEnum.Unsaved, - // id = articleId.dollarLast() - // ) + getGoogleReaderAPI().editTag( + itemIds = listOf(articleId.dollarLast()), + mark = if (isStarred) GoogleReaderAPI.Label.STARRED else null, + unmark = if (!isStarred) GoogleReaderAPI.Label.STARRED else null, + ) } } diff --git a/app/src/main/java/me/ash/reader/infrastructure/rss/provider/greader/GoogleReaderAPI.kt b/app/src/main/java/me/ash/reader/infrastructure/rss/provider/greader/GoogleReaderAPI.kt index f50650583..f75bb7e18 100644 --- a/app/src/main/java/me/ash/reader/infrastructure/rss/provider/greader/GoogleReaderAPI.kt +++ b/app/src/main/java/me/ash/reader/infrastructure/rss/provider/greader/GoogleReaderAPI.kt @@ -182,7 +182,7 @@ class GoogleReaderAPI private constructor( retryableGetRequest( query = "reader/api/0/stream/items/ids", params = listOf( - Pair("s", "user/-/state/com.google/read"), + Pair("s", Label.READ), Pair("ot", since.toString()), Pair("n", MAXIMUM_ITEMS_LIMIT), )) @@ -191,8 +191,8 @@ class GoogleReaderAPI private constructor( retryableGetRequest( query = "reader/api/0/stream/items/ids", params = listOf( - Pair("s", "user/-/state/com.google/reading-list"), - Pair("xt", "user/-/state/com.google/read"), + Pair("s", Label.ALL_ITEMS), + Pair("xt", Label.READ), Pair("n", MAXIMUM_ITEMS_LIMIT), )) @@ -200,7 +200,7 @@ class GoogleReaderAPI private constructor( retryableGetRequest( query = "reader/api/0/stream/items/ids", params = listOf( - Pair("s", "user/-/state/com.google/starred"), + Pair("s", Label.STARRED), Pair("n", MAXIMUM_ITEMS_LIMIT), )) @@ -221,10 +221,23 @@ class GoogleReaderAPI private constructor( enum class subscriptionOperationType - suspend fun editTag(categoryName: String): String = + object Label { + + const val ALL_ITEMS = "user/-/state/com.google/reading-list" + const val READ = "user/-/state/com.google/read" + const val STARRED = "user/-/state/com.google/starred" + const val LIKE = "user/-/state/com.google/like" + const val BROADCAST = "user/-/state/com.google/broadcast" + } + + suspend fun editTag(itemIds: List, mark: String? = null, unmark: String? = null): String = retryablePostRequest( query = "reader/api/0/edit-tag", - form = listOf(Pair("a", categoryName.ofCategoryIdToStreamId())) + form = mutableListOf>().apply { + itemIds.forEach { add(Pair("i", it.ofItemIdToStreamId())) } + mark?.let { add(Pair("a", mark)) } + unmark?.let { add(Pair("r", unmark)) } + } ) suspend fun disableTag(categoryId: String): String = @@ -248,13 +261,23 @@ class GoogleReaderAPI private constructor( ): String = retryablePostRequest( query = "reader/api/0/subscription/edit", form = mutableListOf(Pair("ac", action)).apply { - if (destFeedId != null) add(Pair("s", destFeedId.ofFeedIdToStreamId())) - if (destCategoryId != null) add(Pair("a", destCategoryId.ofCategoryIdToStreamId())) - if (originCategoryId != null) add(Pair("r", originCategoryId.ofCategoryIdToStreamId())) - if (destFeedName?.isNotBlank() == true) add(Pair("t", destFeedName)) + destFeedId?.let { add(Pair("s", it.ofFeedIdToStreamId())) } + destCategoryId?.let { add(Pair("a", it.ofCategoryIdToStreamId())) } + originCategoryId?.let { add(Pair("r", it.ofCategoryIdToStreamId())) } + destFeedName?.takeIf { it.isNotBlank() }?.let { add(Pair("t", destFeedName)) } } ) + suspend fun markAllAsRead(streamId: String, sinceTimestamp: Long? = null): String = + retryablePostRequest( + query = "reader/api/0/mark-all-as-read", + form = mutableListOf( + Pair("s", streamId), + ).apply { + sinceTimestamp?.let { add(Pair("ts", it.toString())) } + } + ) + companion object { const val MAXIMUM_ITEMS_LIMIT = "10000" diff --git a/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowPage.kt b/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowPage.kt index 243eecd56..9c37b13d1 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowPage.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowPage.kt @@ -250,7 +250,7 @@ fun FlowPage( feedId = null, articleId = it.article.id, MarkAsReadConditions.All - ) + ) } item { Spacer(modifier = Modifier.height(128.dp))