95 lines
2.4 KiB
TypeScript
95 lines
2.4 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 from "./RegularToot";
|
||
|
import cardStyle from "../material/cards.module.css";
|
||
|
import { css } from "solid-styled";
|
||
|
|
||
|
type TootActions = {
|
||
|
onBoost(client: mastodon.rest.Client, status: mastodon.v1.Status): void;
|
||
|
onBookmark(client: mastodon.rest.Client, status: mastodon.v1.Status): void;
|
||
|
onReply(client: mastodon.rest.Client, status: mastodon.v1.Status): 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) => {
|
||
|
props.onReply(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;
|
||
|
}
|
||
|
}
|
||
|
`;
|
||
|
return (
|
||
|
<article
|
||
|
ref={props.ref}
|
||
|
classList={{
|
||
|
"thread-line": props.toots.length > 1,
|
||
|
}}
|
||
|
>
|
||
|
<For each={props.toots}>
|
||
|
{(status, index) => (
|
||
|
<RegularToot
|
||
|
data-status-id={status.id}
|
||
|
data-thread-sort={index()}
|
||
|
status={status}
|
||
|
class={`${cardStyle.card}`}
|
||
|
evaluated={props.isExpended(status)}
|
||
|
actionable={props.isExpended(status)}
|
||
|
onBookmark={(s) => bookmark(s)}
|
||
|
onRetoot={(s) => boost(s)}
|
||
|
onReply={(s) => reply(s)}
|
||
|
onClick={[props.onItemClick, status]}
|
||
|
/>
|
||
|
)}
|
||
|
</For>
|
||
|
</article>
|
||
|
);
|
||
|
};
|
||
|
|
||
|
export default Thread;
|