import { Component, For, onCleanup, createSignal, Show, untrack, Match, Switch as JsSwitch, ErrorBoundary, type Ref, } from "solid-js"; import { type mastodon } from "masto"; import { Button, LinearProgress } from "@suid/material"; import { createTimeline } from "../masto/timelines"; import { vibrate } from "../platform/hardware"; import PullDownToRefresh from "./PullDownToRefresh"; import TootComposer from "./TootComposer"; import Thread from "./Thread.jsx"; import { useDefaultSession } from "../masto/clients"; import { useHeroSignal } from "../platform/anim"; import { HERO as BOTTOM_SHEET_HERO } from "../material/BottomSheet"; import { setCache as setTootBottomSheetCache } from "./TootBottomSheet"; import { useNavigate } from "@solidjs/router"; const TootList: Component<{ ref?: Ref; threads: string[]; onUnknownThread: (id: string) => { value: mastodon.v1.Status }[] | undefined; onChangeToot: (id: string, value: mastodon.v1.Status) => void; }> = (props) => { const session = useDefaultSession(); const [, setHeroSrc] = useHeroSignal(BOTTOM_SHEET_HERO); const [expandedThreadId, setExpandedThreadId] = createSignal(); const navigate = useNavigate(); const onBookmark = async ( 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()); props.onChangeToot(result.id, result); }; const onBoost = async ( client: mastodon.rest.Client, status: mastodon.v1.Status, ) => { vibrate(50); const rootStatus = status.reblog ? status.reblog : status; const reblogged = rootStatus.reblogged; if (status.reblog) { status.reblog = { ...status.reblog, reblogged: !reblogged }; props.onChangeToot(status.id, status); } else { props.onChangeToot( status.id, Object.assign(status, { reblogged: !reblogged, }), ); } const result = reblogged ? await client.v1.statuses.$select(status.id).unreblog() : (await client.v1.statuses.$select(status.id).reblog()).reblog!; props.onChangeToot( status.id, Object.assign(status.reblog ?? status, result.reblog), ); }; const openFullScreenToot = ( toot: mastodon.v1.Status, srcElement?: HTMLElement, reply?: boolean, ) => { const p = session()?.account; if (!p) return; const inf = p.inf; if (!inf) { console.warn("no account info?"); return; } setHeroSrc(srcElement); const acct = `${inf.username}@${p.site}`; setTootBottomSheetCache(acct, toot); navigate(`/${encodeURIComponent(acct)}/toot/${toot.id}`, { state: reply ? { tootReply: true, } : undefined, }); }; return ( { return

Oops: {String(err)}

; }} >
{(itemId, index) => { const path = props.onUnknownThread(itemId)!; const toots = path.reverse().map((x) => x.value); return ( openFullScreenToot(status, element, true) } client={session()?.client!} isExpended={(status) => status.id === expandedThreadId()} onItemClick={(status, event) => { if (status.id !== expandedThreadId()) { setExpandedThreadId((x) => (x ? undefined : status.id)); } else { openFullScreenToot( status, event.currentTarget as HTMLElement, ); } }} /> ); }}
); }; export default TootList;