diff --git a/apps/renderer/src/hooks/biz/useEntryActions.tsx b/apps/renderer/src/hooks/biz/useEntryActions.tsx index 74a54fa4e..fe6346232 100644 --- a/apps/renderer/src/hooks/biz/useEntryActions.tsx +++ b/apps/renderer/src/hooks/biz/useEntryActions.tsx @@ -106,12 +106,22 @@ export const useUnCollect = (entry: Nullable) => { export const useRead = () => useMutation({ mutationFn: async (entry: Nullable) => - entry && entryActions.markRead(entry.feeds.id, entry.entries.id, true), + entry && + entryActions.markRead({ + feedId: entry.feeds.id, + entryId: entry.entries.id, + read: true, + }), }) export const useUnread = () => useMutation({ mutationFn: async (entry: Nullable) => - entry && entryActions.markRead(entry.feeds.id, entry.entries.id, false), + entry && + entryActions.markRead({ + feedId: entry.feeds.id, + entryId: entry.entries.id, + read: false, + }), }) export const useEntryActions = ({ diff --git a/apps/renderer/src/modules/entry-column/hooks.ts b/apps/renderer/src/modules/entry-column/hooks.ts index 333894a57..a7ce8c7ea 100644 --- a/apps/renderer/src/modules/entry-column/hooks.ts +++ b/apps/renderer/src/modules/entry-column/hooks.ts @@ -235,7 +235,7 @@ export function batchMarkRead(ids: string[]) { if (batchLikeIds.length > 0) { for (const [feedId, id] of batchLikeIds) { - entryActions.markRead(feedId, id, true) + entryActions.markRead({ feedId, entryId: id, read: true }) } } } diff --git a/apps/renderer/src/modules/entry-column/index.tsx b/apps/renderer/src/modules/entry-column/index.tsx index 5e3f1eb66..a18b787d5 100644 --- a/apps/renderer/src/modules/entry-column/index.tsx +++ b/apps/renderer/src/modules/entry-column/index.tsx @@ -76,7 +76,7 @@ function EntryColumnImpl() { const feedId = activeEntry?.feedId if (!feedId) return - entryActions.markRead(feedId, activeEntryId, true) + entryActions.markRead({ feedId, entryId: activeEntryId, read: true }) }, [activeEntry?.feedId, activeEntryId, isCollection, isPendingEntry]) const isInteracted = useRef(false) diff --git a/apps/renderer/src/modules/entry-column/layouts/EntryItemWrapper.tsx b/apps/renderer/src/modules/entry-column/layouts/EntryItemWrapper.tsx index 3c34b02cc..5bc7bc638 100644 --- a/apps/renderer/src/modules/entry-column/layouts/EntryItemWrapper.tsx +++ b/apps/renderer/src/modules/entry-column/layouts/EntryItemWrapper.tsx @@ -51,7 +51,7 @@ export const EntryItemWrapper: FC< if (!document.hasFocus()) return if (asRead) return - entryActions.markRead(entry.feedId, entry.entries.id, true) + entryActions.markRead({ feedId: entry.feedId, entryId: entry.entries.id, read: true }) }, 233, { diff --git a/apps/renderer/src/modules/entry-column/layouts/EntryListHeader.tsx b/apps/renderer/src/modules/entry-column/layouts/EntryListHeader.tsx index 73a6e77d4..b7b2fd1e8 100644 --- a/apps/renderer/src/modules/entry-column/layouts/EntryListHeader.tsx +++ b/apps/renderer/src/modules/entry-column/layouts/EntryListHeader.tsx @@ -35,7 +35,7 @@ export const EntryListHeader: FC<{ const unreadOnly = useGeneralSettingKey("unreadOnly") - const { feedId, entryId, view } = routerParams + const { feedId, entryId, view, listId } = routerParams const headerTitle = useFeedHeaderTitle() const os = getOS() @@ -58,13 +58,13 @@ export const EntryListHeader: FC<{ ) - const { mutateAsync: refreshFeed, isPending } = useRefreshFeedMutation(routerParams.feedId) + const { mutateAsync: refreshFeed, isPending } = useRefreshFeedMutation(feedId) const user = useWhoami() const isOnline = useIsOnline() - const feed = useFeedById(routerParams.feedId) - const isList = feed?.type === "list" + const feed = useFeedById(feedId) + const isList = !!listId const titleStyleBasedView = ["pl-12", "pl-7", "pl-7", "pl-7", "px-5", "pl-12"] diff --git a/apps/renderer/src/store/entry/helper.ts b/apps/renderer/src/store/entry/helper.ts index 609f3ffc5..a211cfb62 100644 --- a/apps/renderer/src/store/entry/helper.ts +++ b/apps/renderer/src/store/entry/helper.ts @@ -33,8 +33,13 @@ export const getFilteredFeedIds = (feedIds: string[], filter?: EntryFilter) => { } const unread = create({ - fetcher: async (ids: [FeedId, EntryId][]) => { - await apiClient.reads.$post({ json: { entryIds: ids.map((i) => i[1]) } }) + fetcher: async (ids: ([FeedId, EntryId, boolean] | [FeedId, EntryId])[]) => { + await apiClient.reads.$post({ + json: { + entryIds: ids.map((i) => i[1]), + isInbox: ids[0][2], + }, + }) return [] }, diff --git a/apps/renderer/src/store/entry/store.ts b/apps/renderer/src/store/entry/store.ts index 06fb4f74a..10458477f 100644 --- a/apps/renderer/src/store/entry/store.ts +++ b/apps/renderer/src/store/entry/store.ts @@ -345,10 +345,11 @@ class EntryActions { })) } - async markRead(feedId: string, entryId: string, read: boolean) { - const currentIsRead = get().flatMapEntries[entryId]?.read + async markRead({ feedId, entryId, read }: { feedId: string; entryId: string; read: boolean }) { + const entry = get().flatMapEntries[entryId] + const isInbox = entry?.entries && "inboxHandle" in entry.entries - if (read && currentIsRead) { + if (read && entry?.read) { return } @@ -362,11 +363,12 @@ class EntryActions { // Send api request async () => { if (read) { - await internal_batchMarkRead([feedId, entryId]) + await internal_batchMarkRead([feedId, entryId, isInbox]) } else { await apiClient.reads.$delete({ json: { entryId, + isInbox, }, }) } diff --git a/apps/renderer/src/store/inbox/hooks.ts b/apps/renderer/src/store/inbox/hooks.ts index 8120801ee..1cfec8b99 100644 --- a/apps/renderer/src/store/inbox/hooks.ts +++ b/apps/renderer/src/store/inbox/hooks.ts @@ -1,11 +1,6 @@ -import type { FeedViewType } from "~/lib/enum" import type { InboxModel } from "~/models" import { useInboxStore } from "./store" export const useInboxById = (inboxId: Nullable): InboxModel | null => useInboxStore((state) => (inboxId ? state.inboxes[inboxId] : null)) - -export const useInboxByView = (view: FeedViewType) => { - return useInboxStore((state) => (view === 0 ? Object.values(state.inboxes) : [])) -} diff --git a/packages/shared/src/hono.ts b/packages/shared/src/hono.ts index 0dca651ae..5e90ca16a 100644 --- a/packages/shared/src/hono.ts +++ b/packages/shared/src/hono.ts @@ -2213,6 +2213,22 @@ declare const inboxesEntries: drizzle_orm_pg_core.PgTableWithColumns<{ baseColumn: never; generated: undefined; }, {}, {}>; + read: drizzle_orm_pg_core.PgColumn<{ + name: "read"; + tableName: "inboxes_entries"; + dataType: "boolean"; + columnType: "PgBoolean"; + data: boolean; + driverParam: boolean; + notNull: false; + hasDefault: false; + isPrimaryKey: false; + isAutoincrement: false; + hasRuntimeDefault: false; + enumValues: undefined; + baseColumn: never; + generated: undefined; + }, {}, {}>; }; dialect: "pg"; }>; @@ -2245,6 +2261,7 @@ declare const inboxesEntriesOpenAPISchema: z.ZodObject>; inboxHandle: z.ZodString; + read: z.ZodNullable; }, "media" | "attachments" | "extra">, { attachments: z.ZodNullable>; insertedAt: z.ZodString; publishedAt: z.ZodString; + read: z.ZodOptional>; inboxHandle: z.ZodString; }, "id" | "media" | "attachments" | "extra" | "insertedAt" | "publishedAt" | "inboxHandle">, { attachments: z.ZodNullable; declare const inboxesEntriesRelations: drizzle_orm.Relations<"inboxes_entries", { inboxes: drizzle_orm.One<"inboxes", true>; @@ -4219,6 +4241,7 @@ declare const _routes: hono_hono_base.HonoBase