Thread: removed
This commit is contained in:
parent
5afaf21f4b
commit
17e738e21a
3 changed files with 56 additions and 118 deletions
|
@ -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<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);
|
||||
};
|
||||
|
||||
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 (
|
||||
<article ref={props.ref} class="thread" aria-setsize={props.toots.length}>
|
||||
<Index each={props.toots}>
|
||||
{(status, index) => {
|
||||
return (
|
||||
<RegularToot
|
||||
data-status-id={status().id}
|
||||
data-thread-sort={index}
|
||||
status={status()}
|
||||
thread={posThread(index)}
|
||||
class={cardStyle.card}
|
||||
evaluated={props.isExpended(status())}
|
||||
actionable={props.isExpended(status())}
|
||||
onBookmark={(s) => bookmark(s)}
|
||||
onRetoot={(s) => boost(s)}
|
||||
onFavourite={props.onFavourite}
|
||||
onReply={reply}
|
||||
onClick={[props.onItemClick, status()]}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
</Index>
|
||||
</article>
|
||||
);
|
||||
};
|
||||
|
||||
export default Thread;
|
|
@ -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<HTMLDivElement>;
|
||||
|
@ -28,20 +42,20 @@ const TootList: Component<{
|
|||
const [expandedThreadId, setExpandedThreadId] = createSignal<string>();
|
||||
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<{
|
|||
<div ref={props.ref} id={props.id} class="toot-list">
|
||||
<For each={props.threads}>
|
||||
{(itemId) => {
|
||||
const toots = createMemo(() => getPath(itemId));
|
||||
return (
|
||||
<Thread
|
||||
toots={getPath(itemId)}
|
||||
onBoost={toggleBoost}
|
||||
<Index each={toots()}>
|
||||
{(status, index) => (
|
||||
<RegularToot
|
||||
data-status-id={status().id}
|
||||
data-thread-sort={index}
|
||||
status={status()}
|
||||
thread={
|
||||
toots().length > 1
|
||||
? positionTootInThread(index, toots().length)
|
||||
: undefined
|
||||
}
|
||||
class={cardStyle.card}
|
||||
evaluated={checkIsExpended(status())}
|
||||
actionable={checkIsExpended(status())}
|
||||
onBookmark={onBookmark}
|
||||
onReply={onReply}
|
||||
onRetoot={toggleBoost}
|
||||
onFavourite={toggleFavourite}
|
||||
client={session()?.client!}
|
||||
isExpended={checkIsExpended}
|
||||
onItemClick={onItemClick}
|
||||
onReply={(status, event) => {
|
||||
const element = findRootToot(event.currentTarget);
|
||||
openFullScreenToot(status, element, true);
|
||||
}}
|
||||
onClick={[onItemClick, status()]}
|
||||
/>
|
||||
)}
|
||||
</Index>
|
||||
);
|
||||
}}
|
||||
</For>
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue