TootBottomSheet: use new cache semantic

This commit is contained in:
thislight 2024-12-26 20:09:03 +08:00
parent 5ab0d4d0a2
commit 6dd6065711
No known key found for this signature in database
GPG key ID: FCFE5192241CCD4E
4 changed files with 22 additions and 50 deletions

View file

@ -115,7 +115,7 @@ export function useDefaultSession() {
* - If the username is not present, any session on the site is returned; or, * - If the username is not present, any session on the site is returned; or,
* - If no available session available for the pattern, an unauthorised session is returned. * - If no available session available for the pattern, an unauthorised session is returned.
* *
* In an unauthorised session, the `.account` is `undefined` and the `client` is an * In an unauthorised session, the `.account` is {@link RemoteServer} and the `client` is an
* unauthorised client for the site. This client may not available for some operations. * unauthorised client for the site. This client may not available for some operations.
*/ */
export function useSessionForAcctStr(acct: Accessor<string>) { export function useSessionForAcctStr(acct: Accessor<string>) {
@ -131,7 +131,7 @@ export function useSessionForAcctStr(acct: Accessor<string>) {
return ( return (
authedSession ?? { authedSession ?? {
client: createUnauthorizedClient(inputSite), client: createUnauthorizedClient(inputSite),
account: undefined, account: { site: inputSite }, // TODO: we need some security checks here?
} }
); );
}); });

View file

@ -1,16 +1,13 @@
import { useLocation, useParams } from "@solidjs/router"; import { useParams } from "@solidjs/router";
import { import {
catchError, catchError,
createEffect,
createRenderEffect,
createResource, createResource,
Show, Show,
type Component, type Component,
} from "solid-js"; } from "solid-js";
import Scaffold from "~material/Scaffold"; import Scaffold from "~material/Scaffold";
import { AppBar, CircularProgress, IconButton, Toolbar } from "@suid/material"; import { CircularProgress } from "@suid/material";
import { Title } from "~material/typography"; import { Title } from "~material/typography";
import { Close as CloseIcon } from "@suid/icons-material";
import { useSessionForAcctStr } from "../masto/clients"; import { useSessionForAcctStr } from "../masto/clients";
import { resolveCustomEmoji } from "../masto/toot"; import { resolveCustomEmoji } from "../masto/toot";
import RegularToot, { import RegularToot, {
@ -33,18 +30,8 @@ import ItemSelectionProvider, {
createSingluarItemSelection, createSingluarItemSelection,
} from "./toots/ItemSelectionProvider"; } from "./toots/ItemSelectionProvider";
import AppTopBar from "~material/AppTopBar"; import AppTopBar from "~material/AppTopBar";
import { fetchStatus } from "../masto/statuses";
let cachedEntry: [string, mastodon.v1.Status] | undefined; import { type Account } from "../accounts/stores";
export function setCache(acct: string, status: mastodon.v1.Status) {
cachedEntry = [acct, status];
}
function getCache(acct: string, id: string) {
if (acct === cachedEntry?.[0] && id === cachedEntry?.[1].id) {
return cachedEntry[1];
}
}
const TootBottomSheet: Component = (props) => { const TootBottomSheet: Component = (props) => {
const params = useParams<{ acct: string; id: string }>(); const params = useParams<{ acct: string; id: string }>();
@ -54,25 +41,15 @@ const TootBottomSheet: Component = (props) => {
const session = useSessionForAcctStr(acctText); const session = useSessionForAcctStr(acctText);
const [, selectionState] = createSingluarItemSelection(); const [, selectionState] = createSingluarItemSelection();
const [remoteToot, { mutate: setRemoteToot }] = createResource( const [remoteToot, { mutate: setRemoteToot }] =
() => [session().client, params.id] as const, fetchStatus.cachedAndRevalidate(
async ([client, id]) => { () => [session().account, params.id] as const,
return await client.v1.statuses.$select(id).fetch(); );
},
);
const toot = () => const toot = () =>
catchError(remoteToot, (error) => { catchError(remoteToot, (error) => {
console.error(error); console.error(error);
}) ?? getCache(acctText(), params.id); });
createEffect((lastTootId?: string) => {
const tootId = toot()?.id;
if (!tootId || lastTootId === tootId) return tootId;
const elementId = `toot-${tootId}`;
document.getElementById(elementId)?.scrollIntoView({ behavior: "smooth" });
return tootId;
});
const [tootContextErrorUncaught, { refetch: refetchContext }] = const [tootContextErrorUncaught, { refetch: refetchContext }] =
createResource( createResource(
@ -94,12 +71,6 @@ const TootBottomSheet: Component = (props) => {
() => tootContext()?.descendants, () => tootContext()?.descendants,
); );
createEffect(() => {
if (ancestors.list.length > 0) {
document.querySelector(`#toot-${toot()!.id}`)?.scrollIntoView();
}
});
useDocumentTitle(() => { useDocumentTitle(() => {
const t = toot()?.reblog ?? toot(); const t = toot()?.reblog ?? toot();
const name = t?.account.displayName ?? "Someone"; const name = t?.account.displayName ?? "Someone";
@ -300,10 +271,10 @@ const TootBottomSheet: Component = (props) => {
</Show> </Show>
</article> </article>
<Show when={session()!.account}> <Show when={(session().account as Account).inf}>
<TootComposer <TootComposer
mentions={defaultMentions()} mentions={defaultMentions()}
profile={session().account!} profile={(session().account! as Account).inf}
replyToDisplayName={toot()?.account?.displayName || ""} replyToDisplayName={toot()?.account?.displayName || ""}
client={session().client} client={session().client}
onSent={() => refetchContext()} onSent={() => refetchContext()}

View file

@ -216,7 +216,7 @@ function cancelEvent(event: Event) {
const TootComposer: Component<{ const TootComposer: Component<{
ref?: Ref<HTMLDivElement>; ref?: Ref<HTMLDivElement>;
style?: JSX.CSSProperties; style?: JSX.CSSProperties;
profile?: Account; profile?: mastodon.v1.Account;
replyToDisplayName?: string; replyToDisplayName?: string;
mentions?: readonly string[]; mentions?: readonly string[];
client?: mastodon.rest.Client; client?: mastodon.rest.Client;
@ -248,15 +248,15 @@ const TootComposer: Component<{
createEffect(() => { createEffect(() => {
if (active()) { if (active()) {
setTimeout(() => inputRef.focus(), 0); setTimeout(() => inputRef!.focus(), 0);
} }
}); });
createEffect(() => { createEffect(() => {
if (inputRef.value !== "") return; if (inputRef!.value !== "") return;
if (props.mentions) { if (props.mentions) {
const prepText = props.mentions.join(" ") + " "; const prepText = props.mentions.join(" ") + " ";
inputRef.value = prepText; inputRef!.value = prepText;
} }
}); });
@ -294,7 +294,7 @@ const TootComposer: Component<{
try { try {
const status = await client.v1.statuses.create( const status = await client.v1.statuses.create(
{ {
status: inputRef.value, status: inputRef!.value,
language: language(), language: language(),
visibility: visibility(), visibility: visibility(),
inReplyToId: props.inReplyToId, inReplyToId: props.inReplyToId,
@ -309,7 +309,7 @@ const TootComposer: Component<{
); );
props.onSent?.(status); props.onSent?.(status);
inputRef.value = ""; inputRef!.value = "";
} finally { } finally {
setSending(false); setSending(false);
} }
@ -363,7 +363,7 @@ const TootComposer: Component<{
<div class="reply-input"> <div class="reply-input">
<Show when={props.profile}> <Show when={props.profile}>
<Avatar <Avatar
src={props.profile!.inf?.avatar} src={props.profile!.avatar}
sx={{ marginLeft: "-0.25em" }} sx={{ marginLeft: "-0.25em" }}
/> />
</Show> </Show>

View file

@ -23,6 +23,7 @@ import type { ThreadNode } from "../masto/timelines";
import { useNavigator } from "~platform/StackedRouter"; import { useNavigator } from "~platform/StackedRouter";
import { ANIM_CURVE_STD } from "~material/theme"; import { ANIM_CURVE_STD } from "~material/theme";
import { useItemSelection } from "./toots/ItemSelectionProvider"; import { useItemSelection } from "./toots/ItemSelectionProvider";
import { fetchStatus } from "../masto/statuses";
function durationOf(rect0: DOMRect, rect1: DOMRect) { function durationOf(rect0: DOMRect, rect1: DOMRect) {
const distancelt = Math.sqrt( const distancelt = Math.sqrt(
@ -130,7 +131,7 @@ const TootList: Component<{
} }
const acct = `${inf.username}@${p.site}`; const acct = `${inf.username}@${p.site}`;
setTootBottomSheetCache(acct, toot); await fetchStatus.setJson([p, toot.id], toot)
push(`/${encodeURIComponent(acct)}/toot/${toot.id}`, { push(`/${encodeURIComponent(acct)}/toot/${toot.id}`, {
animateOpen(element) { animateOpen(element) {