92 lines
2.5 KiB
TypeScript
92 lines
2.5 KiB
TypeScript
import type { mastodon } from "masto";
|
|
import {
|
|
For,
|
|
Show,
|
|
createResource,
|
|
createSignal,
|
|
type Component,
|
|
type Ref,
|
|
} from "solid-js";
|
|
import CompactToot from "./CompactToot";
|
|
import { useTimeSource } from "../platform/timesrc";
|
|
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;
|
|
};
|
|
|
|
type ThreadProps = {
|
|
ref?: Ref<HTMLElement>;
|
|
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<ThreadProps> = (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);
|
|
};
|
|
|
|
css`
|
|
.thread {
|
|
user-select: none;
|
|
cursor: pointer;
|
|
}
|
|
`
|
|
return (
|
|
<article ref={props.ref} class="thread">
|
|
<For each={props.toots}>
|
|
{(status, index) => {
|
|
const useThread = props.toots.length > 1;
|
|
const threadPosition = useThread
|
|
? index() === 0
|
|
? "top"
|
|
: index() === props.toots.length - 1
|
|
? "bottom"
|
|
: "middle"
|
|
: undefined;
|
|
return (
|
|
<RegularToot
|
|
data-status-id={status.id}
|
|
data-thread-sort={index()}
|
|
status={status}
|
|
thread={threadPosition}
|
|
class={cardStyle.card}
|
|
evaluated={props.isExpended(status)}
|
|
actionable={props.isExpended(status)}
|
|
onBookmark={(s) => bookmark(s)}
|
|
onRetoot={(s) => boost(s)}
|
|
onReply={reply}
|
|
onClick={[props.onItemClick, status]}
|
|
/>
|
|
);
|
|
}}
|
|
</For>
|
|
</article>
|
|
);
|
|
};
|
|
|
|
export default Thread;
|