tutu/src/timelines/TootThread.tsx

87 lines
2.3 KiB
TypeScript
Raw Normal View History

2024-07-14 12:28:44 +00:00
import type { mastodon } from "masto";
import { Show, createResource, createSignal, type Component } from "solid-js";
import CompactToot from "./CompactToot";
import { useTimeSource } from "../platform/timesrc";
import RegularToot from "./RegularToot";
import cardStyle from "../material/cards.module.css";
import { css } from "solid-styled";
type TootThreadProps = {
status: mastodon.v1.Status;
client: mastodon.rest.Client;
expanded?: 0 | 1 | 2;
onBoost?(client: mastodon.rest.Client, status: mastodon.v1.Status): void;
onBookmark?(client: mastodon.rest.Client, status: mastodon.v1.Status): void;
};
const TootThread: Component<TootThreadProps> = (props) => {
const status = () => props.status;
const now = useTimeSource();
const [expanded, setExpanded] = createSignal(false);
const [inReplyTo] = createResource(
() => [props.client, status().inReplyToId || null] as const,
async ([client, replyToId]) => {
if (!(client && replyToId)) return null;
return await client.v1.statuses.$select(replyToId).fetch();
},
);
const boost = (status: mastodon.v1.Status) => {
props.onBoost?.(props.client, status);
};
const bookmark = (status: mastodon.v1.Status) => {
props.onBookmark?.(props.client, status);
};
css`
article {
transition: margin 90ms var(--tutu-anim-curve-sharp), var(--tutu-transition-shadow);
user-select: none;
cursor: pointer;
}
.thread-line {
position: relative;
&::before {
content: "";
position: absolute;
left: 36px;
top: 16px;
bottom: 0;
background-color: var(--tutu-color-secondary);
width: 2px;
display: block;
}
}
.expanded {
margin-block: 20px;
box-shadow: var(--tutu-shadow-e9);
}
`;
return (
<article classList={{ "thread-line": !!inReplyTo(), "expanded": expanded() }} onClick={() => setExpanded((x) => !x)}>
<Show when={inReplyTo()}>
<CompactToot
status={inReplyTo()!}
now={now()}
class={[cardStyle.card, cardStyle.manualMargin].join(" ")}
/>
</Show>
<RegularToot
status={status()}
class={cardStyle.card}
actionable={expanded()}
onBookmark={(s) => bookmark(s)}
onRetoot={(s) => boost(s)}
/>
</article>
);
};
export default TootThread;