diff --git a/apps/renderer/src/modules/entry-column/grid.tsx b/apps/renderer/src/modules/entry-column/grid.tsx index cf1f4a919..557359dd1 100644 --- a/apps/renderer/src/modules/entry-column/grid.tsx +++ b/apps/renderer/src/modules/entry-column/grid.tsx @@ -6,8 +6,16 @@ import { useTypeScriptHappyCallback } from "@follow/hooks" import { LRUCache } from "@follow/utils/lru-cache" import type { Range, VirtualItem, Virtualizer } from "@tanstack/react-virtual" import { useVirtualizer } from "@tanstack/react-virtual" -import type { FC } from "react" -import { Fragment, startTransition, useEffect, useMemo, useState } from "react" +import type { FC, MutableRefObject } from "react" +import { + Fragment, + startTransition, + useEffect, + useLayoutEffect, + useMemo, + useRef, + useState, +} from "react" import { useTranslation } from "react-i18next" import { setUISetting, useUISettingKey } from "~/atoms/settings/ui" @@ -101,16 +109,57 @@ const ratioMap = { // 16:9 [FeedViewType.Videos]: 16 / 9, } -const VirtualGrid: FC = (props) => { - const { entriesIds, feedId, onRangeChange, fetchNextPage, view, Footer, hasNextPage, listRef } = - props - const scrollRef = useScrollViewElement() +const VirtualGrid: FC = (props) => { + const scrollRef = useScrollViewElement() const [containerWidth, setContainerWidth] = useState(0) - const columns = useMemo(() => { - if (!scrollRef) return [0] + useEffect(() => { + if (!scrollRef) return + const handler = () => { + const rem = Number.parseFloat(getComputedStyle(document.documentElement).fontSize) + const width = scrollRef.clientWidth - 2 * rem + setContainerWidth(width) + measureRef.current?.() + } + + const observer = new ResizeObserver(handler) + handler() + observer.observe(scrollRef) + return () => { + observer.disconnect() + } + }, [scrollRef]) + + const measureRef = useRef<() => void>() + + if (!containerWidth) return null + + return +} + +const VirtualGridImpl: FC< + EntryListProps & { + containerWidth: number + measureRef: MutableRefObject<(() => void) | undefined> + } +> = (props) => { + const { + entriesIds, + feedId, + onRangeChange, + fetchNextPage, + view, + Footer, + hasNextPage, + listRef, + measureRef, + containerWidth, + } = props + const scrollRef = useScrollViewElement() + + const columns = useMemo(() => { const width = containerWidth const rem = Number.parseFloat(getComputedStyle(document.documentElement).fontSize) let columnCount = 1 // default (grid-cols-1) @@ -120,7 +169,7 @@ const VirtualGrid: FC = (props) => { if (width >= 80 * rem) columnCount = 5 // @8xl (80rem) return Array.from({ length: columnCount }).fill(width / columnCount) as number[] - }, [containerWidth, scrollRef]) + }, [containerWidth]) // Calculate rows based on entries const rows = useMemo(() => { @@ -190,23 +239,12 @@ const VirtualGrid: FC = (props) => { listRef.current = rowVirtualizer }, [rowVirtualizer, listRef]) - useEffect(() => { - if (!scrollRef) return - const handler = () => { - const rem = Number.parseFloat(getComputedStyle(document.documentElement).fontSize) - const width = scrollRef.clientWidth - 2 * rem - setContainerWidth(width) - + useLayoutEffect(() => { + measureRef.current = () => { rowVirtualizer.measure() columnVirtualizer.measure() } - - const observer = new ResizeObserver(handler) - observer.observe(scrollRef) - return () => { - observer.disconnect() - } - }, [columnVirtualizer, rowVirtualizer, scrollRef]) + }, [columnVirtualizer, measureRef, rowVirtualizer]) const virtualItems = rowVirtualizer.getVirtualItems() useEffect(() => { @@ -233,10 +271,9 @@ const VirtualGrid: FC = (props) => { return (
{rowVirtualizer.getVirtualItems().map((virtualRow) => { diff --git a/packages/shared/src/hono.ts b/packages/shared/src/hono.ts index a8ef01ca3..ffb075789 100644 --- a/packages/shared/src/hono.ts +++ b/packages/shared/src/hono.ts @@ -24,12 +24,7 @@ declare const authPlugins: ({ method: "GET"; }> | undefined)?]>(...ctx: C): Promise; + }] ? Response : any>; path: "/get-providers"; options: { method: "GET"; @@ -58,6 +53,23 @@ declare const authPlugins: ({ headers: Headers; }; }; +} | { + id: "updateUserccc"; + endpoints: { + updateUserccc: { + | undefined)?]>(...ctx: C): Promise; + path: "/update-user-ccc"; + options: { + method: "POST"; + }; + method: better_call.Method | better_call.Method[]; + headers: Headers; + }; + }; })[]; declare const achievements: drizzle_orm_pg_core.PgTableWithColumns<{ @@ -4735,10 +4747,10 @@ declare const user: drizzle_orm_pg_core.PgTableWithColumns<{ emailVerified: drizzle_orm_pg_core.PgColumn<{ name: "emailVerified"; tableName: "user"; - dataType: "date"; - columnType: "PgTimestamp"; - data: Date; - driverParam: string; + dataType: "boolean"; + columnType: "PgBoolean"; + data: boolean; + driverParam: boolean; notNull: false; hasDefault: false; isPrimaryKey: false; @@ -4878,10 +4890,10 @@ declare const users: drizzle_orm_pg_core.PgTableWithColumns<{ emailVerified: drizzle_orm_pg_core.PgColumn<{ name: "emailVerified"; tableName: "user"; - dataType: "date"; - columnType: "PgTimestamp"; - data: Date; - driverParam: string; + dataType: "boolean"; + columnType: "PgBoolean"; + data: boolean; + driverParam: boolean; notNull: false; hasDefault: false; isPrimaryKey: false; @@ -4968,7 +4980,7 @@ declare const usersOpenApiSchema: z.ZodObject; email: z.ZodString; - emailVerified: z.ZodNullable; + emailVerified: z.ZodNullable; image: z.ZodNullable; handle: z.ZodNullable; createdAt: z.ZodDate; @@ -4976,7 +4988,7 @@ declare const usersOpenApiSchema: z.ZodObject, z.UnknownKeysParam, z.ZodTypeAny, { name: string | null; id: string; - emailVerified: string | null; + emailVerified: boolean | null; image: string | null; handle: string | null; createdAt: Date; @@ -4984,7 +4996,7 @@ declare const usersOpenApiSchema: z.ZodObject; + disableRefresh: zod.ZodOptional; }, "strip", zod.ZodTypeAny, { disableCookieCache?: boolean | undefined; + disableRefresh?: boolean | undefined; }, { disableCookieCache?: boolean | undefined; + disableRefresh?: boolean | undefined; }>>; requireHeaders: true; metadata: { @@ -6599,12 +6614,7 @@ declare const auth: { method: "GET"; }> | undefined)?]>(...ctx: C): Promise; + }] ? Response : any>; path: "/get-providers"; options: { method: "GET"; @@ -6628,6 +6638,19 @@ declare const auth: { method: better_call.Method | better_call.Method[]; headers: Headers; }; + updateUserccc: { + | undefined)?]>(...ctx: C): Promise; + path: "/update-user-ccc"; + options: { + method: "POST"; + }; + method: better_call.Method | better_call.Method[]; + headers: Headers; + }; signInSocial: { ]>(...ctx: C): Promise; @@ -7989,20 +8034,20 @@ declare const auth: { ; - image: zod.ZodOptional; - }, zod.UnknownKeysParam, zod.ZodTypeAny, { - name?: string | undefined; - image?: string | undefined; - }, { - name?: string | undefined; - image?: string | undefined; - }> & zod.ZodObject<{ handle: zod.ZodString; }, zod.UnknownKeysParam, zod.ZodTypeAny, { handle: string; }, { handle: string; + }> & zod.ZodObject<{ + name: zod.ZodOptional; + image: zod.ZodOptional; + }, zod.UnknownKeysParam, zod.ZodTypeAny, { + name?: string | undefined; + image?: string | null | undefined; + }, { + name?: string | undefined; + image?: string | null | undefined; }>; use: better_call.Endpoint; - image: zod.ZodOptional; - }, zod.UnknownKeysParam, zod.ZodTypeAny, { - name?: string | undefined; - image?: string | undefined; - }, { - name?: string | undefined; - image?: string | undefined; - }> & zod.ZodObject<{ handle: zod.ZodString; }, zod.UnknownKeysParam, zod.ZodTypeAny, { handle: string; }, { handle: string; + }> & zod.ZodObject<{ + name: zod.ZodOptional; + image: zod.ZodOptional; + }, zod.UnknownKeysParam, zod.ZodTypeAny, { + name?: string | undefined; + image?: string | null | undefined; + }, { + name?: string | undefined; + image?: string | null | undefined; }>; use: better_call.Endpoint; use: better_call.Endpoint & { @@ -8210,19 +8248,15 @@ declare const auth: { }; }; }; - }>]>(...ctx: C): Promise | undefined)?]>(...ctx: C): Promise; + }] ? Response : { + success: boolean; + message: string; + }>; path: "/delete-user"; options: { method: "POST"; - body: zod.ZodObject<{ - password: zod.ZodString; - }, "strip", zod.ZodTypeAny, { - password: string; - }, { - password: string; - }>; use: better_call.Endpoint & { @@ -9071,6 +9105,36 @@ declare const auth: { method: better_call.Method | better_call.Method[]; headers: Headers; }; + deleteUserCallback: { + ; + }>]>(...ctx: C): Promise; + path: "/delete-user/callback"; + options: { + method: "GET"; + query: zod.ZodObject<{ + token: zod.ZodString; + }, "strip", zod.ZodTypeAny, { + token: string; + }, { + token: string; + }>; + }; + method: better_call.Method | better_call.Method[]; + headers: Headers; + }; }; options: { appName: string; @@ -9116,7 +9180,6 @@ declare const auth: { }): Promise; options: better_auth_adapters_drizzle.DrizzleAdapterConfig; }; - baseUrl: string | undefined; basePath: string; trustedOrigins: string[]; user: { @@ -9126,25 +9189,32 @@ declare const auth: { }; }; }; - accounts: { + account: { accountLinking: { - enabled: boolean; - trustedProviders: string[]; + enabled: true; + trustedProviders: ("github" | "apple" | "google")[]; }; }; socialProviders: { google: { clientId: string; clientSecret: string; + redirectURI: string; }; github: { clientId: string; clientSecret: string; + redirectURI: string; }; apple: { + enabled: boolean; clientId: string; clientSecret: string; - } | undefined; + redirectURI: string; + }; + }; + emailAndPassword: { + enabled: true; }; plugins: ({ id: "custom-session"; @@ -9207,12 +9277,7 @@ declare const auth: { method: "GET"; }> | undefined)?]>(...ctx: C): Promise; + }] ? Response : any>; path: "/get-providers"; options: { method: "GET"; @@ -9241,6 +9306,23 @@ declare const auth: { headers: Headers; }; }; + } | { + id: "updateUserccc"; + endpoints: { + updateUserccc: { + | undefined)?]>(...ctx: C): Promise; + path: "/update-user-ccc"; + options: { + method: "POST"; + }; + method: better_call.Method | better_call.Method[]; + headers: Headers; + }; + }; })[]; }; $context: Promise; @@ -9726,7 +9808,7 @@ declare const _routes: hono_hono_base.HonoBase