fix: inbox

Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
Innei 2024-10-11 18:50:19 +08:00
parent b69c6f97c8
commit df86527072
No known key found for this signature in database
GPG Key ID: 0F62D33977F021F7
6 changed files with 183 additions and 55 deletions

View File

@ -25,8 +25,8 @@ export type TransactionModel = ExtractBizResponse<
export type FeedModel = ExtractBizResponse<typeof apiClient.feeds.$get>["data"]["feed"]
export type ListModelPoplutedFeeds = ExtractBizResponse<typeof apiClient.lists.$get>["data"]["list"]
export type ListModel = Omit<ListModelPoplutedFeeds, "feeds">
export type ListModelPoplutedFeeds = ExtractBizResponse<typeof apiClient.lists.$get>["data"]["list"]
export type InboxModel = ExtractBizResponse<typeof apiClient.inboxes.$get>["data"]

View File

@ -83,7 +83,8 @@ const useInboxesGroupedData = (view: FeedViewType) => {
const groupFolder = {} as Record<string, string[]>
for (const subscription of inboxes) {
groupFolder[subscription.feedId] = [subscription.feedId]
if (!subscription.inboxId) continue
groupFolder[subscription.inboxId] = [subscription.inboxId]
}
return groupFolder

View File

@ -54,7 +54,7 @@ class ListActionStatic {
return ListService.upsert(patchedData as ListModel)
})
}
async addFeedToFeedList(listId: string, feed: FeedModel) {
addFeedToFeedList(listId: string, feed: FeedModel) {
const list = get().lists[listId]
if (!list) return
feedActions.upsertMany([feed])
@ -64,7 +64,7 @@ class ListActionStatic {
})
}
async removeFeedFromFeedList(listId: string, feedId: string) {
removeFeedFromFeedList(listId: string, feedId: string) {
const list = get().lists[listId] as ListModel
if (!list) return
@ -73,7 +73,7 @@ class ListActionStatic {
})
}
async deleteList(listId: string) {
deleteList(listId: string) {
set((state) => {
delete state.lists[listId]
return state
@ -89,7 +89,7 @@ class ListActionStatic {
return res.data
}
async clear() {
clear() {
set((state) => {
state.lists = {}
})

View File

@ -40,3 +40,16 @@ export const useFolderFeedsByFeedId = ({ feedId, view }: { feedId?: string; view
}
return feedIds
})
export const useListSubscriptionCount = () =>
useSubscriptionStore((state) => Object.values(state.data).filter((s) => !!s.listId).length)
export const useInboxSubscriptionCount = () =>
useSubscriptionStore((state) => Object.values(state.data).filter((s) => !!s.inboxId).length)
export const useFeedSubscriptionCount = () =>
useSubscriptionStore(
(state) =>
// FIXME: Backend data compatibility
Object.values(state.data).filter((s) => !!s.feedId && !s.listId && !s.inboxId).length,
)

View File

@ -16,12 +16,13 @@ import { feedActions, getFeedById } from "../feed"
import { inboxActions } from "../inbox"
import { listActions } from "../list"
import { feedUnreadActions } from "../unread"
import { createZustandStore, doMutationAndTransaction } from "../utils/helper"
import { createImmerSetter, createZustandStore, doMutationAndTransaction } from "../utils/helper"
export type SubscriptionFlatModel = Omit<SubscriptionModel, "feeds"> & {
defaultCategory?: string
listId?: string
inboxId?: string
}
interface SubscriptionState {
/**
@ -89,6 +90,7 @@ export const useSubscriptionStore = createZustandStore<SubscriptionState>("subsc
const set = useSubscriptionStore.setState
const get = useSubscriptionStore.getState
const immerSet = createImmerSetter(useSubscriptionStore)
type MarkReadFilter = {
startTime: number
@ -144,59 +146,47 @@ class SubscriptionActions {
runTransactionInScope(() => {
SubscriptionService.upsertMany(subscriptions)
})
set((state) =>
produce(state, (state) => {
subscriptions.forEach((subscription) => {
state.data[subscription.feedId] = omit(subscription, [
"feeds",
"lists",
"inboxes",
]) as SubscriptionFlatModel
state.feedIdByView[subscription.view].push(subscription.feedId)
return state
})
}),
)
immerSet((state) => {
subscriptions.forEach((subscription) => {
state.data[subscription.feedId] = omit(subscription, [
"feeds",
"lists",
"inboxes",
]) as SubscriptionFlatModel
state.feedIdByView[subscription.view].push(subscription.feedId)
})
})
}
updateCategoryOpenState(subscriptions: SubscriptionFlatModel[]) {
set((state) =>
produce(state, (state) => {
subscriptions.forEach((subscription) => {
const folderName = subscription.category || subscription.defaultCategory
state.categoryOpenStateByView[subscription.view][folderName] =
state.categoryOpenStateByView[subscription.view][folderName] || false
return state
})
immerSet((state) =>
subscriptions.forEach((subscription) => {
const folderName = subscription.category || subscription.defaultCategory
state.categoryOpenStateByView[subscription.view][folderName] =
state.categoryOpenStateByView[subscription.view][folderName] || false
return state
}),
)
}
toggleCategoryOpenState(view: FeedViewType, category: string) {
set((state) =>
produce(state, (state) => {
state.categoryOpenStateByView[view][category] =
!state.categoryOpenStateByView[view][category]
}),
immerSet(
(state) =>
(state.categoryOpenStateByView[view][category] =
!state.categoryOpenStateByView[view][category]),
)
}
changeCategoryOpenState(view: FeedViewType, category: string, status: boolean) {
set((state) =>
produce(state, (state) => {
state.categoryOpenStateByView[view][category] = status
}),
)
immerSet((state) => (state.categoryOpenStateByView[view][category] = status))
}
expandCategoryOpenStateByView(view: FeedViewType, isOpen: boolean) {
set((state) =>
produce(state, (state) => {
for (const category in state.categoryOpenStateByView[view]) {
state.categoryOpenStateByView[view][category] = isOpen
}
}),
)
immerSet((state) => {
for (const category in state.categoryOpenStateByView[view]) {
state.categoryOpenStateByView[view][category] = isOpen
}
})
}
async markReadByView(view: FeedViewType, filter?: MarkReadFilter) {

View File

@ -216,6 +216,7 @@ declare const actions: drizzle_orm_pg_core.PgTableWithColumns<{
summary?: boolean;
readability?: boolean;
silence?: boolean;
newEntryNotification?: boolean;
rewriteRules?: {
from: string;
to: string;
@ -261,6 +262,7 @@ declare const actionsItemOpenAPISchema: z.ZodObject<{
summary: z.ZodOptional<z.ZodBoolean>;
readability: z.ZodOptional<z.ZodBoolean>;
silence: z.ZodOptional<z.ZodBoolean>;
newEntryNotification: z.ZodOptional<z.ZodBoolean>;
rewriteRules: z.ZodOptional<z.ZodArray<z.ZodObject<{
from: z.ZodString;
to: z.ZodString;
@ -290,6 +292,7 @@ declare const actionsItemOpenAPISchema: z.ZodObject<{
translation?: "en" | "ja" | "zh-CN" | "zh-TW" | undefined;
readability?: boolean | undefined;
silence?: boolean | undefined;
newEntryNotification?: boolean | undefined;
rewriteRules?: {
from: string;
to: string;
@ -305,6 +308,7 @@ declare const actionsItemOpenAPISchema: z.ZodObject<{
translation?: "en" | "ja" | "zh-CN" | "zh-TW" | undefined;
readability?: boolean | undefined;
silence?: boolean | undefined;
newEntryNotification?: boolean | undefined;
rewriteRules?: {
from: string;
to: string;
@ -323,6 +327,7 @@ declare const actionsItemOpenAPISchema: z.ZodObject<{
translation?: "en" | "ja" | "zh-CN" | "zh-TW" | undefined;
readability?: boolean | undefined;
silence?: boolean | undefined;
newEntryNotification?: boolean | undefined;
rewriteRules?: {
from: string;
to: string;
@ -346,6 +351,7 @@ declare const actionsItemOpenAPISchema: z.ZodObject<{
translation?: "en" | "ja" | "zh-CN" | "zh-TW" | undefined;
readability?: boolean | undefined;
silence?: boolean | undefined;
newEntryNotification?: boolean | undefined;
rewriteRules?: {
from: string;
to: string;
@ -391,6 +397,7 @@ declare const actionsOpenAPISchema: z.ZodObject<z.objectUtil.extendShape<Omit<{
summary: z.ZodOptional<z.ZodBoolean>;
readability: z.ZodOptional<z.ZodBoolean>;
silence: z.ZodOptional<z.ZodBoolean>;
newEntryNotification: z.ZodOptional<z.ZodBoolean>;
rewriteRules: z.ZodOptional<z.ZodArray<z.ZodObject<{
from: z.ZodString;
to: z.ZodString;
@ -420,6 +427,7 @@ declare const actionsOpenAPISchema: z.ZodObject<z.objectUtil.extendShape<Omit<{
translation?: "en" | "ja" | "zh-CN" | "zh-TW" | undefined;
readability?: boolean | undefined;
silence?: boolean | undefined;
newEntryNotification?: boolean | undefined;
rewriteRules?: {
from: string;
to: string;
@ -435,6 +443,7 @@ declare const actionsOpenAPISchema: z.ZodObject<z.objectUtil.extendShape<Omit<{
translation?: "en" | "ja" | "zh-CN" | "zh-TW" | undefined;
readability?: boolean | undefined;
silence?: boolean | undefined;
newEntryNotification?: boolean | undefined;
rewriteRules?: {
from: string;
to: string;
@ -453,6 +462,7 @@ declare const actionsOpenAPISchema: z.ZodObject<z.objectUtil.extendShape<Omit<{
translation?: "en" | "ja" | "zh-CN" | "zh-TW" | undefined;
readability?: boolean | undefined;
silence?: boolean | undefined;
newEntryNotification?: boolean | undefined;
rewriteRules?: {
from: string;
to: string;
@ -476,6 +486,7 @@ declare const actionsOpenAPISchema: z.ZodObject<z.objectUtil.extendShape<Omit<{
translation?: "en" | "ja" | "zh-CN" | "zh-TW" | undefined;
readability?: boolean | undefined;
silence?: boolean | undefined;
newEntryNotification?: boolean | undefined;
rewriteRules?: {
from: string;
to: string;
@ -502,6 +513,7 @@ declare const actionsOpenAPISchema: z.ZodObject<z.objectUtil.extendShape<Omit<{
translation?: "en" | "ja" | "zh-CN" | "zh-TW" | undefined;
readability?: boolean | undefined;
silence?: boolean | undefined;
newEntryNotification?: boolean | undefined;
rewriteRules?: {
from: string;
to: string;
@ -528,6 +540,7 @@ declare const actionsOpenAPISchema: z.ZodObject<z.objectUtil.extendShape<Omit<{
translation?: "en" | "ja" | "zh-CN" | "zh-TW" | undefined;
readability?: boolean | undefined;
silence?: boolean | undefined;
newEntryNotification?: boolean | undefined;
rewriteRules?: {
from: string;
to: string;
@ -3204,6 +3217,91 @@ declare const listsTimelineRelations: drizzle_orm.Relations<"lists_timeline", {
feeds: drizzle_orm.One<"feeds", true>;
}>;
declare const messaging: drizzle_orm_pg_core.PgTableWithColumns<{
name: "messaging";
schema: undefined;
columns: {
userId: drizzle_orm_pg_core.PgColumn<{
name: "user_id";
tableName: "messaging";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: false;
hasDefault: false;
isPrimaryKey: false;
isAutoincrement: false;
hasRuntimeDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
generated: undefined;
}, {}, {}>;
token: drizzle_orm_pg_core.PgColumn<{
name: "token";
tableName: "messaging";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: true;
hasDefault: false;
isPrimaryKey: false;
isAutoincrement: false;
hasRuntimeDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
generated: undefined;
}, {}, {}>;
channel: drizzle_orm_pg_core.PgColumn<{
name: "channel";
tableName: "messaging";
dataType: "string";
columnType: "PgText";
data: string;
driverParam: string;
notNull: true;
hasDefault: false;
isPrimaryKey: false;
isAutoincrement: false;
hasRuntimeDefault: false;
enumValues: [string, ...string[]];
baseColumn: never;
generated: undefined;
}, {}, {}>;
};
dialect: "pg";
}>;
declare const messagingOpenAPISchema: z.ZodObject<z.objectUtil.extendShape<Omit<{
userId: z.ZodNullable<z.ZodString>;
token: z.ZodString;
channel: z.ZodString;
}, "channel">, {
channel: z.ZodEnum<["desktop", "mobile"]>;
}>, "strip", z.ZodTypeAny, {
userId: string | null;
token: string;
channel: "desktop" | "mobile";
}, {
userId: string | null;
token: string;
channel: "desktop" | "mobile";
}>;
declare const messagingRelations: drizzle_orm.Relations<"messaging", {
users: drizzle_orm.One<"user", false>;
}>;
declare enum MessagingType {
NewEntry = "new-entry"
}
type MessagingData = {
type: MessagingType.NewEntry;
feedId: string;
entryId: string;
view: string;
title: string;
description: string;
};
declare const settings: drizzle_orm_pg_core.PgTableWithColumns<{
name: "settings";
schema: undefined;
@ -3751,6 +3849,7 @@ declare const usersRelations: drizzle_orm.Relations<"user", {
wallets: drizzle_orm.One<"wallets", true>;
feeds: drizzle_orm.Many<"feeds">;
inboxes: drizzle_orm.One<"inboxes", true>;
messaging: drizzle_orm.Many<"messaging">;
}>;
declare const wallets: drizzle_orm_pg_core.PgTableWithColumns<{
@ -3869,15 +3968,15 @@ declare const walletsOpenAPISchema: zod.ZodObject<{
}, zod.UnknownKeysParam, zod.ZodTypeAny, {
createdAt: string;
userId: string;
address: string | null;
addressIndex: number;
address: string | null;
dailyPowerToken: string;
cashablePowerToken: string;
}, {
createdAt: string;
userId: string;
address: string | null;
addressIndex: number;
address: string | null;
dailyPowerToken: string;
cashablePowerToken: string;
}>;
@ -4149,6 +4248,32 @@ declare const feedPowerTokensRelations: drizzle_orm.Relations<"feedPowerTokens",
}>;
declare const _routes: hono_hono_base.HonoBase<Env, {
"/messaging": {
$post: {
input: {
json: {
token: string;
channel: "desktop" | "mobile";
};
};
output: {
code: 0;
};
outputFormat: "json" | "text";
status: 200;
};
};
"/messaging/test": {
$get: {
input: {};
output: {
code: 0;
};
outputFormat: "json" | "text";
status: 200;
};
};
} & {
"/inboxes": {
$delete: {
input: {
@ -4770,19 +4895,14 @@ declare const _routes: hono_hono_base.HonoBase<Env, {
};
"/wallets": {
$get: {
input: {
query: {
userId?: string | string[] | undefined;
address?: string | string[] | undefined;
};
};
input: {};
output: {
code: 0;
data: {
createdAt: string;
userId: string;
address: string | null;
addressIndex: number;
address: string | null;
dailyPowerToken: string;
cashablePowerToken: string;
}[];
@ -5454,6 +5574,7 @@ declare const _routes: hono_hono_base.HonoBase<Env, {
translation?: "en" | "ja" | "zh-CN" | "zh-TW" | undefined;
readability?: boolean | undefined;
silence?: boolean | undefined;
newEntryNotification?: boolean | undefined;
rewriteRules?: {
from: string;
to: string;
@ -5687,6 +5808,7 @@ declare const _routes: hono_hono_base.HonoBase<Env, {
translation?: "en" | "ja" | "zh-CN" | "zh-TW" | undefined;
readability?: boolean | undefined;
silence?: boolean | undefined;
newEntryNotification?: boolean | undefined;
rewriteRules?: {
from: string;
to: string;
@ -6181,6 +6303,7 @@ declare const _routes: hono_hono_base.HonoBase<Env, {
translation?: "en" | "ja" | "zh-CN" | "zh-TW" | undefined;
readability?: boolean | undefined;
silence?: boolean | undefined;
newEntryNotification?: boolean | undefined;
rewriteRules?: {
from: string;
to: string;
@ -6213,6 +6336,7 @@ declare const _routes: hono_hono_base.HonoBase<Env, {
translation?: "en" | "ja" | "zh-CN" | "zh-TW" | undefined;
readability?: boolean | undefined;
silence?: boolean | undefined;
newEntryNotification?: boolean | undefined;
rewriteRules?: {
from: string;
to: string;
@ -6304,4 +6428,4 @@ declare const _routes: hono_hono_base.HonoBase<Env, {
}, "/">;
type AppType = typeof _routes;
export { type ActionsModel, type AppType, type AttachmentsModel, CommonEntryFields, type EntriesModel, type EntryReadHistoriesModel, type ExtraModel, type FeedModel, type MediaModel, type SettingsModel, accounts, achievements, achievementsOpenAPISchema, actions, actionsItemOpenAPISchema, actionsOpenAPISchema, actionsRelations, attachmentsZodSchema, collections, collectionsOpenAPISchema, collectionsRelations, entries, entriesOpenAPISchema, entriesRelations, entryReadHistories, entryReadHistoriesOpenAPISchema, entryReadHistoriesRelations, extraZodSchema, feedPowerTokens, feedPowerTokensOpenAPISchema, feedPowerTokensRelations, feeds, feedsOpenAPISchema, feedsRelations, inboxHandleSchema, inboxes, inboxesEntries, inboxesEntriesInsertOpenAPISchema, type inboxesEntriesModel, inboxesEntriesOpenAPISchema, inboxesEntriesRelations, inboxesOpenAPISchema, inboxesRelations, invitations, invitationsOpenAPISchema, invitationsRelations, languageSchema, lists, listsOpenAPISchema, listsRelations, listsSubscriptions, listsSubscriptionsOpenAPISchema, listsSubscriptionsRelations, listsTimeline, listsTimelineOpenAPISchema, listsTimelineRelations, mediaZodSchema, sessions, settings, subscriptions, subscriptionsOpenAPISchema, subscriptionsRelations, timeline, timelineOpenAPISchema, timelineRelations, transactionType, transactions, transactionsOpenAPISchema, transactionsRelations, users, usersOpenApiSchema, usersRelations, verificationTokens, wallets, walletsOpenAPISchema, walletsRelations };
export { type ActionsModel, type AppType, type AttachmentsModel, CommonEntryFields, type EntriesModel, type EntryReadHistoriesModel, type ExtraModel, type FeedModel, type MediaModel, type MessagingData, MessagingType, type SettingsModel, accounts, achievements, achievementsOpenAPISchema, actions, actionsItemOpenAPISchema, actionsOpenAPISchema, actionsRelations, attachmentsZodSchema, collections, collectionsOpenAPISchema, collectionsRelations, entries, entriesOpenAPISchema, entriesRelations, entryReadHistories, entryReadHistoriesOpenAPISchema, entryReadHistoriesRelations, extraZodSchema, feedPowerTokens, feedPowerTokensOpenAPISchema, feedPowerTokensRelations, feeds, feedsOpenAPISchema, feedsRelations, inboxHandleSchema, inboxes, inboxesEntries, inboxesEntriesInsertOpenAPISchema, type inboxesEntriesModel, inboxesEntriesOpenAPISchema, inboxesEntriesRelations, inboxesOpenAPISchema, inboxesRelations, invitations, invitationsOpenAPISchema, invitationsRelations, languageSchema, lists, listsOpenAPISchema, listsRelations, listsSubscriptions, listsSubscriptionsOpenAPISchema, listsSubscriptionsRelations, listsTimeline, listsTimelineOpenAPISchema, listsTimelineRelations, mediaZodSchema, messaging, messagingOpenAPISchema, messagingRelations, sessions, settings, subscriptions, subscriptionsOpenAPISchema, subscriptionsRelations, timeline, timelineOpenAPISchema, timelineRelations, transactionType, transactions, transactionsOpenAPISchema, transactionsRelations, users, usersOpenApiSchema, usersRelations, verificationTokens, wallets, walletsOpenAPISchema, walletsRelations };