diff --git a/src/masto/timelines.ts b/src/masto/timelines.ts index 917ecf7..ce73490 100644 --- a/src/masto/timelines.ts +++ b/src/masto/timelines.ts @@ -1,5 +1,5 @@ import { type mastodon } from "masto"; -import { Accessor, createEffect, createResource, createSignal } from "solid-js"; +import { Accessor, createEffect, createResource } from "solid-js"; import { createStore } from "solid-js/store"; type TimelineFetchTips = { @@ -8,19 +8,27 @@ type TimelineFetchTips = { type Timeline = { list(params: { - maxId?: string; - minId?: string; + readonly limit?: number; }): mastodon.Paginator; }; -export function useTimeline(timeline: Accessor) { +export function useTimeline( + timeline: Accessor, + cfg?: { + /** + * Use full refresh mode. This mode ignores paging, it will refetch the specified number + * of toots at every refetch(). + */ + fullRefresh?: number; + }, +) { let otl: Timeline | undefined; let npager: mastodon.Paginator | undefined; let opager: mastodon.Paginator | undefined; const [snapshot, { refetch }] = createResource< { records: mastodon.v1.Status[]; - direction: "new" | "old"; + direction: "new" | "old" | "items"; tlChanged: boolean; }, [Timeline], @@ -35,6 +43,20 @@ export function useTimeline(timeline: Accessor) { otl = tl; tlChanged = true; } + const fullRefresh = cfg?.fullRefresh; + if (typeof fullRefresh !== "undefined") { + const records = await tl + .list({ + limit: fullRefresh, + }) + .next(); + return { + direction: "items", + records: records.value ?? [], + end: records.done, + tlChanged, + }; + } const direction = typeof info.refetching !== "boolean" ? (info.refetching?.direction ?? "old") @@ -70,10 +92,12 @@ export function useTimeline(timeline: Accessor) { if (tlChanged) { setStore(() => []); } - if (direction == "new") { + if (direction === "new") { setStore((x) => [...records, ...x]); - } else if (direction == "old") { + } else if (direction === "old") { setStore((x) => [...x, ...records]); + } else if (direction === "items") { + setStore(() => records); } }); diff --git a/src/timelines/Home.tsx b/src/timelines/Home.tsx index d303c72..c09023d 100644 --- a/src/timelines/Home.tsx +++ b/src/timelines/Home.tsx @@ -9,6 +9,8 @@ import { type ParentComponent, children, Suspense, + Match, + Switch as JsSwitch } from "solid-js"; import { useDocumentTitle } from "../utils"; import { type mastodon } from "masto"; @@ -49,6 +51,7 @@ const TimelinePanel: Component<{ client: mastodon.rest.Client; name: "home" | "public" | "trends"; prefetch?: boolean; + fullRefetch?: number; openFullScreenToot: ( toot: mastodon.v1.Status, @@ -60,10 +63,12 @@ const TimelinePanel: Component<{ timeline, snapshot, { refetch: refetchTimeline, mutate: mutateTimeline }, - ] = useTimeline(() => - props.name !== "trends" - ? props.client.v1.timelines[props.name] - : props.client.v1.trends.statuses, + ] = useTimeline( + () => + props.name !== "trends" + ? props.client.v1.timelines[props.name] + : props.client.v1.trends.statuses, + { fullRefresh: props.fullRefetch }, ); const [expandedThreadId, setExpandedThreadId] = createSignal(); @@ -176,15 +181,26 @@ const TimelinePanel: Component<{ "justify-content": "center", }} > - + + + + + + + + ); @@ -403,6 +419,7 @@ const Home: ParentComponent = (props) => { name="trends" prefetch={prefetching()} openFullScreenToot={openFullScreenToot} + fullRefetch={120} />