import { Component, For, onCleanup, createSignal, Show, untrack, Match, Switch as JsSwitch, ErrorBoundary, } from "solid-js"; import { type mastodon } from "masto"; import { Button, LinearProgress, } from "@suid/material"; import TootThread from "./TootThread.js"; import { useTimeline } from "../masto/timelines"; import { vibrate } from "../platform/hardware"; import PullDownToRefresh from "./PullDownToRefresh"; import TootComposer from "./TootComposer"; const TimelinePanel: Component<{ client: mastodon.rest.Client; name: "home" | "public" | "trends"; prefetch?: boolean; fullRefetch?: number; openFullScreenToot: ( toot: mastodon.v1.Status, srcElement?: HTMLElement, reply?: boolean, ) => void; }> = (props) => { const [scrollLinked, setScrollLinked] = createSignal(); const [ timeline, snapshot, { refetch: refetchTimeline, mutate: mutateTimeline }, ] = useTimeline( () => props.name !== "trends" ? props.client.v1.timelines[props.name] : props.client.v1.trends.statuses, { fullRefresh: props.fullRefetch }, ); const [expandedThreadId, setExpandedThreadId] = createSignal(); const [typing, setTyping] = createSignal(false); const tlEndObserver = new IntersectionObserver(() => { if (untrack(() => props.prefetch) && !snapshot.loading) refetchTimeline({ direction: "old" }); }); onCleanup(() => tlEndObserver.disconnect()); const onBookmark = async ( index: number, client: mastodon.rest.Client, status: mastodon.v1.Status, ) => { const result = await (status.bookmarked ? client.v1.statuses.$select(status.id).unbookmark() : client.v1.statuses.$select(status.id).bookmark()); mutateTimeline((o) => { o[index] = result; return o; }); }; const onBoost = async ( index: number, client: mastodon.rest.Client, status: mastodon.v1.Status, ) => { const reblogged = status.reblog ? status.reblog.reblogged : status.reblogged; vibrate(50); mutateTimeline(index, (x) => { if (x.reblog) { x.reblog = { ...x.reblog, reblogged: !reblogged }; return Object.assign({}, x); } else { return Object.assign({}, x, { reblogged: !reblogged, }); } }); const result = reblogged ? await client.v1.statuses.$select(status.id).unreblog() : (await client.v1.statuses.$select(status.id).reblog()).reblog!; mutateTimeline((o) => { Object.assign(o[index].reblog ?? o[index], { reblogged: result.reblogged, reblogsCount: result.reblogsCount, }); return o; }); }; return ( { return

Oops: {String(err)}

; }} > refetchTimeline({ direction: "new" })} />
setTimeout(() => { setScrollLinked(e.parentElement!); }, 0) } > refetchTimeline({ direction: "new" })} /> {(item, index) => { let element: HTMLElement | undefined; return ( onBoost(index(), ...args)} onBookmark={(...args) => onBookmark(index(), ...args)} onReply={(client, status) => props.openFullScreenToot(status, element, true) } client={props.client} expanded={item.id === expandedThreadId() ? 1 : 0} onExpandChange={(x) => { setTyping(false) if (item.id !== expandedThreadId()) { setExpandedThreadId((x) => (x ? undefined : item.id)); } else if (x === 2) { props.openFullScreenToot(item, element); } }} /> ); }}
tlEndObserver.observe(e)}>
); }; export default TimelinePanel