diff --git a/src/masto/timelines.ts b/src/masto/timelines.ts index 556bc83..6e5eb9b 100644 --- a/src/masto/timelines.ts +++ b/src/masto/timelines.ts @@ -18,30 +18,6 @@ type Timeline = { type TimelineParamsOf = T extends Timeline ? P : never; -function createControlsForLookup( - lookup: ReactiveMap>, -) { - return { - get(id: string) { - return lookup.get(id); - }, - getPath(id: string) { - const node = lookup.get(id); - if (!node) return; - const path = collectPath(node); - for (const sym of path) { - lookup.get(sym.value.id); // Track every node on the path - } - return path; - }, - set(id: string, value: mastodon.v1.Status) { - const node = untrack(() => lookup.get(id)); - if (!node) return; - lookup.set(id, {...node, value}); - }, - }; -} - export function createTimelineControlsForArray( status: () => mastodon.v1.Status[] | undefined, ): TimelineControls { @@ -92,7 +68,20 @@ export function createTimelineControlsForArray( return { list: threads, - ...createControlsForLookup(lookup), + get(id: string) { + return lookup.get(id); + }, + getPath(id: string) { + const node = lookup.get(id); + if (!node) return; + return collectPath(node); + }, + set(id: string, value: mastodon.v1.Status) { + const node = untrack(() => lookup.get(id)); + if (!node) return; + node.value = value; + lookup.set(id, node); + }, }; } @@ -318,7 +307,20 @@ export function createTimeline< return [ { list: threads, - ...createControlsForLookup(lookup), + get(id: string) { + return lookup.get(id); + }, + getPath(id: string) { + const node = lookup.get(id); + if (!node) return; + return collectPath(node); + }, + set(id: string, value: mastodon.v1.Status) { + const node = untrack(() => lookup.get(id)); + if (!node) return; + node.value = value; + lookup.set(id, node); + }, }, chunk, { refetch }, diff --git a/src/timelines/Thread.tsx b/src/timelines/Thread.tsx index 034c126..f8d4932 100644 --- a/src/timelines/Thread.tsx +++ b/src/timelines/Thread.tsx @@ -1,5 +1,9 @@ import type { mastodon } from "masto"; -import { Index, type Component, type Ref } from "solid-js"; +import { + For, + type Component, + type Ref, +} from "solid-js"; import RegularToot, { findRootToot } from "./RegularToot"; import cardStyle from "../material/cards.module.css"; import { css } from "solid-styled"; @@ -13,7 +17,6 @@ type TootActions = { onBoost(client: mastodon.rest.Client, status: mastodon.v1.Status): void; onBookmark(client: mastodon.rest.Client, status: mastodon.v1.Status): void; onReply(target: TootActionTarget, element: HTMLElement): void; - onFavourite(status: mastodon.v1.Status): void }; type ThreadProps = { @@ -42,47 +45,41 @@ const Thread: Component = (props) => { props.onReply({ client: props.client, status }, element); }; - const threading = () => props.toots.length > 1; - - const posThread = (index: number) => { - if (!threading()) return; - - if (index === 0) { - return "top"; - } else if (index === props.toots.length - 1) { - return "bottom"; - } - return "middle"; - }; - css` - .thread { - user-select: none; - cursor: pointer; - } - `; + .thread { + user-select: none; + cursor: pointer; + } + ` return (
- + {(status, index) => { + const useThread = props.toots.length > 1; + const threadPosition = useThread + ? index() === 0 + ? "top" + : index() === props.toots.length - 1 + ? "bottom" + : "middle" + : undefined; return ( bookmark(s)} onRetoot={(s) => boost(s)} - onFavourite={props.onFavourite} onReply={reply} - onClick={[props.onItemClick, status()]} + onClick={[props.onItemClick, status]} /> ); }} - +
); }; diff --git a/src/timelines/TootList.tsx b/src/timelines/TootList.tsx index 30304d9..da3f065 100644 --- a/src/timelines/TootList.tsx +++ b/src/timelines/TootList.tsx @@ -38,7 +38,7 @@ const TootList: Component<{ props.onChangeToot(result.id, result); }; - const toggleBoost = async ( + const onBoost = async ( client: mastodon.rest.Client, status: mastodon.v1.Status, ) => { @@ -46,39 +46,23 @@ const TootList: Component<{ const rootStatus = status.reblog ? status.reblog : status; const reblogged = rootStatus.reblogged; if (status.reblog) { - props.onChangeToot(status.id, { - ...status, - reblog: { ...status.reblog, reblogged: !reblogged }, - }); + status.reblog = { ...status.reblog, reblogged: !reblogged }; + props.onChangeToot(status.id, status); } else { - props.onChangeToot(status.id, { - ...status, - reblogged: !reblogged, - }); + 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!; - - if (status.reblog) { - props.onChangeToot(status.id, { - ...status, - reblog: result, - }); - } else { - props.onChangeToot(status.id, result); - } - }; - - const toggleFavourite = async (status: mastodon.v1.Status) => { - const client = session()?.client; - if (!client) return; - const ovalue = status.favourited; - const result = ovalue - ? await client.v1.statuses.$select(status.id).unfavourite() - : await client.v1.statuses.$select(status.id).favourite(); - props.onChangeToot(status.id, result); + props.onChangeToot( + status.id, + Object.assign(status.reblog ?? status, result.reblog), + ); }; const openFullScreenToot = ( @@ -160,13 +144,6 @@ const TootList: Component<{ openFullScreenToot(status, element, true); }; - const getPath = (itemId: string) => { - return props - .onUnknownThread(itemId)! - .reverse() - .map((x) => x.value); - }; - return ( { @@ -175,14 +152,16 @@ const TootList: Component<{ >
- {(itemId) => { + {(itemId, index) => { + const path = props.onUnknownThread(itemId)!; + const toots = path.reverse().map((x) => x.value); + return (