feat(mobile): mark as read for list

This commit is contained in:
Stephen Zhou 2025-05-26 23:08:04 +08:00
parent 0a2a099d7b
commit 7c4b8967cb
No known key found for this signature in database
2 changed files with 75 additions and 51 deletions

View File

@ -1,6 +1,7 @@
import { env } from "@follow/shared/src/env.rn"
import { getList } from "@follow/store/src/list/getters"
import { subscriptionSyncService } from "@follow/store/src/subscription/store"
import { unreadSyncService } from "@follow/store/src/unread/store"
import type { FC, PropsWithChildren } from "react"
import { useMemo } from "react"
import { useTranslation } from "react-i18next"
@ -19,47 +20,54 @@ export const SubscriptionListItemContextMenu: FC<
const { t } = useTranslation()
const navigation = useNavigation()
const actions = useMemo(
() => [
{
title: t("operation.edit"),
onSelect: () => {
const list = getList(id)
if (!list) return
navigation.presentControllerView(FollowScreen, {
type: "list",
id: list.id,
})
() =>
[
{
title: t("operation.mark_as_read"),
onSelect: () => {
unreadSyncService.markListAsRead(id)
},
},
},
{
title: t("operation.copy_which", { which: t("operation.copy.link") }),
onSelect: () => {
const list = getList(id)
if (!list) return
toast.success(t("operation.copy_which_success", { which: t("operation.copy.link") }))
Clipboard.setString(`${env.WEB_URL}/share/lists/${list.id}`)
{
title: t("operation.edit"),
onSelect: () => {
const list = getList(id)
if (!list) return
navigation.presentControllerView(FollowScreen, {
type: "list",
id: list.id,
})
},
},
},
{
title: t("operation.unfollow"),
destructive: true,
onSelect: () => {
Alert.alert(t("operation.unfollow"), "Are you sure you want to unsubscribe?", [
{
text: "Cancel",
style: "cancel",
},
{
text: t("operation.unfollow"),
style: "destructive",
onPress: () => {
subscriptionSyncService.unsubscribe(id)
{
title: t("operation.copy_which", { which: t("operation.copy.link") }),
onSelect: () => {
const list = getList(id)
if (!list) return
toast.success(t("operation.copy_which_success", { which: t("operation.copy.link") }))
Clipboard.setString(`${env.WEB_URL}/share/lists/${list.id}`)
},
},
{
title: t("operation.unfollow"),
destructive: true,
onSelect: () => {
Alert.alert(t("operation.unfollow"), "Are you sure you want to unsubscribe?", [
{
text: "Cancel",
style: "cancel",
},
},
])
{
text: t("operation.unfollow"),
style: "destructive",
onPress: () => {
subscriptionSyncService.unsubscribe(id)
},
},
])
},
},
},
],
].filter((i) => !!i),
[id, navigation, t],
)
@ -68,19 +76,17 @@ export const SubscriptionListItemContextMenu: FC<
<ContextMenu.Trigger>{children}</ContextMenu.Trigger>
<ContextMenu.Content>
{actions
.filter((i) => !!i)
.map((action) => {
return (
<ContextMenu.Item
key={action.title}
destructive={action.destructive}
onSelect={action.onSelect}
>
<ContextMenu.ItemTitle>{action.title}</ContextMenu.ItemTitle>
</ContextMenu.Item>
)
})}
{actions.map((action) => {
return (
<ContextMenu.Item
key={action.title}
destructive={action.destructive}
onSelect={action.onSelect}
>
<ContextMenu.ItemTitle>{action.title}</ContextMenu.ItemTitle>
</ContextMenu.Item>
)
})}
</ContextMenu.Content>
</ContextMenu.Root>
)

View File

@ -7,7 +7,7 @@ import { getEntry } from "../entry/getter"
import { entryActions } from "../entry/store"
import type { Hydratable } from "../internal/base"
import { createTransaction, createZustandStore } from "../internal/helper"
import { getListFeedIds } from "../list/getters"
import { getList, getListFeedIds } from "../list/getters"
import { getSubscriptionByView } from "../subscription/getter"
import type { PublishAtTimeRangeFilter, UnreadUpdateOptions } from "./types"
@ -98,6 +98,24 @@ class UnreadSyncService {
this.updateUnreadStatus(feedIds, time)
}
async markListAsRead(listId: string, time?: PublishAtTimeRangeFilter) {
const list = getList(listId)
if (!list) return
await apiClient.reads.all.$post({
json: {
listId,
...time,
},
})
const feedIds = getListFeedIds(listId)
if (feedIds) {
this.updateUnreadStatus(feedIds, time)
}
}
async markEntryAsRead(entryId: string) {
const entry = getEntry(entryId)
if (!entry || entry?.read) return