tutu/src/timelines/TootThread.tsx

95 lines
2.5 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;
onExpandChange?(level: 0 | 1 | 2): void;
2024-07-14 12:28:44 +00:00
};
const TootThread: Component<TootThreadProps> = (props) => {
const status = () => props.status;
const now = useTimeSource();
const expanded = () => props.expanded ?? 0;
2024-07-14 12:28:44 +00:00
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 {
2024-08-05 07:33:00 +00:00
transition:
margin 90ms var(--tutu-anim-curve-sharp),
var(--tutu-transition-shadow);
2024-07-14 12:28:44 +00:00
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);
}
`;
const nextExpandLevel = [1, 2, 2] as const;
2024-07-14 12:28:44 +00:00
return (
2024-08-05 07:33:00 +00:00
<article
classList={{ "thread-line": !!inReplyTo(), expanded: expanded() > 0 }}
onClick={() => props.onExpandChange?.(nextExpandLevel[expanded()])}
2024-08-05 07:33:00 +00:00
>
2024-07-14 12:28:44 +00:00
<Show when={inReplyTo()}>
<CompactToot
status={inReplyTo()!}
now={now()}
class={[cardStyle.card, cardStyle.manualMargin].join(" ")}
/>
</Show>
<RegularToot
status={status()}
class={cardStyle.card}
actionable={expanded() > 0}
2024-07-14 12:28:44 +00:00
onBookmark={(s) => bookmark(s)}
onRetoot={(s) => boost(s)}
/>
</article>
);
};
export default TootThread;