diff --git a/src/timelines/Thread.tsx b/src/timelines/Thread.tsx deleted file mode 100644 index 034c126..0000000 --- a/src/timelines/Thread.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import type { mastodon } from "masto"; -import { Index, type Component, type Ref } from "solid-js"; -import RegularToot, { findRootToot } from "./RegularToot"; -import cardStyle from "../material/cards.module.css"; -import { css } from "solid-styled"; - -type TootActionTarget = { - client: mastodon.rest.Client; - status: mastodon.v1.Status; -}; - -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 = { - ref?: Ref; - client: mastodon.rest.Client; - toots: readonly mastodon.v1.Status[]; - isExpended: (status: mastodon.v1.Status) => boolean; - - onItemClick(status: mastodon.v1.Status, event: MouseEvent): void; -} & TootActions; - -const Thread: Component = (props) => { - const boost = (status: mastodon.v1.Status) => { - props.onBoost(props.client, status); - }; - - const bookmark = (status: mastodon.v1.Status) => { - props.onBookmark(props.client, status); - }; - - const reply = ( - status: mastodon.v1.Status, - event: MouseEvent & { currentTarget: HTMLElement }, - ) => { - const element = findRootToot(event.currentTarget); - 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; - } - `; - return ( -
- - {(status, index) => { - return ( - bookmark(s)} - onRetoot={(s) => boost(s)} - onFavourite={props.onFavourite} - onReply={reply} - onClick={[props.onItemClick, status()]} - /> - ); - }} - -
- ); -}; - -export default Thread; diff --git a/src/timelines/TootList.tsx b/src/timelines/TootList.tsx index 30304d9..667212e 100644 --- a/src/timelines/TootList.tsx +++ b/src/timelines/TootList.tsx @@ -5,16 +5,30 @@ import { ErrorBoundary, type Ref, createSelector, + Index, + createMemo, } from "solid-js"; import { type mastodon } from "masto"; import { vibrate } from "../platform/hardware"; -import Thread from "./Thread.jsx"; import { useDefaultSession } from "../masto/clients"; import { useHeroSource } from "../platform/anim"; import { HERO as BOTTOM_SHEET_HERO } from "../material/BottomSheet"; import { setCache as setTootBottomSheetCache } from "./TootBottomSheet"; import { useNavigate } from "@solidjs/router"; -import { findElementActionable } from "./RegularToot"; +import RegularToot, { + findElementActionable, + findRootToot, +} from "./RegularToot"; +import cardStyle from "../material/cards.module.css"; + +function positionTootInThread(index: number, threadLength: number) { + if (index === 0) { + return "top"; + } else if (index === threadLength - 1) { + return "bottom"; + } + return "middle"; +} const TootList: Component<{ ref?: Ref; @@ -28,20 +42,20 @@ const TootList: Component<{ const [expandedThreadId, setExpandedThreadId] = createSignal(); const navigate = useNavigate(); - const onBookmark = async ( - client: mastodon.rest.Client, - status: mastodon.v1.Status, - ) => { + const onBookmark = async (status: mastodon.v1.Status) => { + const client = session()?.client; + if (!client) return; + 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 toggleBoost = async ( - client: mastodon.rest.Client, - status: mastodon.v1.Status, - ) => { + const toggleBoost = async (status: mastodon.v1.Status) => { + const client = session()?.client; + if (!client) return; + vibrate(50); const rootStatus = status.reblog ? status.reblog : status; const reblogged = rootStatus.reblogged; @@ -110,8 +124,11 @@ const TootList: Component<{ const onItemClick = ( status: mastodon.v1.Status, - event: MouseEvent & { target: HTMLElement; currentTarget: HTMLElement }, + event: MouseEvent & { target: EventTarget; currentTarget: HTMLElement }, ) => { + if (!(event.target instanceof HTMLElement)) { + throw new Error("target is not an element"); + } const actionableElement = findElementActionable( event.target, event.currentTarget, @@ -153,13 +170,6 @@ const TootList: Component<{ const checkIsExpended = (status: mastodon.v1.Status) => checkIsExpendedId(status.id); - const onReply = ( - { status }: { status: mastodon.v1.Status }, - element: HTMLElement, - ) => { - openFullScreenToot(status, element, true); - }; - const getPath = (itemId: string) => { return props .onUnknownThread(itemId)! @@ -176,17 +186,33 @@ const TootList: Component<{
{(itemId) => { + const toots = createMemo(() => getPath(itemId)); return ( - + + {(status, index) => ( + 1 + ? positionTootInThread(index, toots().length) + : undefined + } + class={cardStyle.card} + evaluated={checkIsExpended(status())} + actionable={checkIsExpended(status())} + onBookmark={onBookmark} + onRetoot={toggleBoost} + onFavourite={toggleFavourite} + onReply={(status, event) => { + const element = findRootToot(event.currentTarget); + openFullScreenToot(status, element, true); + }} + onClick={[onItemClick, status()]} + /> + )} + ); }} diff --git a/src/timelines/toot.module.css b/src/timelines/toot.module.css index 365b849..4ee5608 100644 --- a/src/timelines/toot.module.css +++ b/src/timelines/toot.module.css @@ -5,6 +5,8 @@ margin-block: 0; position: relative; contain: content; + user-select: none; + cursor: pointer; &.toot { /* fix composition ordering: I think the css module processor should aware the overriding and behaves, but no */