RegularToot: open profile

This commit is contained in:
thislight 2024-10-27 13:43:34 +08:00
parent d4093aaf5c
commit 49e1731cdb
No known key found for this signature in database
GPG key ID: A50F9451AC56A63E
2 changed files with 48 additions and 11 deletions

View file

@ -49,7 +49,8 @@ export type Session = {
client: mastodon.rest.Client; client: mastodon.rest.Client;
}; };
const Context = /* @__PURE__ */ createContext<Accessor<readonly Readonly<Session>[]>>(); const Context =
/* @__PURE__ */ createContext<Accessor<readonly Readonly<Session>[]>>();
export const Provider = Context.Provider; export const Provider = Context.Provider;
@ -77,7 +78,9 @@ function useSessionsRaw() {
return store; return store;
} }
const DefaultSessionContext = /* @__PURE__ */ createContext<Accessor<number>>(() => 0) const DefaultSessionContext = /* @__PURE__ */ createContext<Accessor<number>>(
() => 0,
);
export const DefaultSessionProvider = DefaultSessionContext.Provider; export const DefaultSessionProvider = DefaultSessionContext.Provider;
@ -87,14 +90,14 @@ export const DefaultSessionProvider = DefaultSessionContext.Provider;
* This function may return `undefined`, but it will try to redirect the user to the sign in. * This function may return `undefined`, but it will try to redirect the user to the sign in.
*/ */
export function useDefaultSession() { export function useDefaultSession() {
const sessions = useSessions() const sessions = useSessions();
const sessionIndex = useContext(DefaultSessionContext) const sessionIndex = useContext(DefaultSessionContext);
return () => { return () => {
if (sessions().length > 0) { if (sessions().length > 0) {
return sessions()[sessionIndex()] return sessions()[sessionIndex()];
} }
} };
} }
/** /**
@ -114,7 +117,7 @@ export function useDefaultSession() {
* 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>) {
const allSessions = useSessions() const allSessions = useSessions();
return createMemo(() => { return createMemo(() => {
const [inputUsername, inputSite] = acct().split("@", 2); const [inputUsername, inputSite] = acct().split("@", 2);
@ -132,4 +135,6 @@ export function useSessionForAcctStr(acct: Accessor<string>) {
}); });
} }
export function makeAcctText(session: Session) {
return `${session.account.inf?.username}@${session.account.site}`;
}

View file

@ -39,6 +39,8 @@ import { FastAverageColor } from "fast-average-color";
import Color from "colorjs.io"; import Color from "colorjs.io";
import { useDateFnLocale } from "../platform/i18n"; import { useDateFnLocale } from "../platform/i18n";
import { canShare, share } from "../platform/share"; import { canShare, share } from "../platform/share";
import { makeAcctText, useDefaultSession } from "../masto/clients";
import { useNavigate } from "@solidjs/router";
type TootContentViewProps = { type TootContentViewProps = {
source?: string; source?: string;
@ -209,12 +211,16 @@ function TootActionGroup<T extends mastodon.v1.Status>(
); );
} }
function TootAuthorGroup(props: { status: mastodon.v1.Status; now: Date }) { function TootAuthorGroup(props: {
status: mastodon.v1.Status;
now: Date;
onClick?: JSX.EventHandlerUnion<HTMLDivElement, MouseEvent>;
}) {
const toot = () => props.status; const toot = () => props.status;
const dateFnLocale = useDateFnLocale(); const dateFnLocale = useDateFnLocale();
return ( return (
<div class={tootStyle.tootAuthorGrp}> <div class={tootStyle.tootAuthorGrp} onClick={props.onClick}>
<Img src={toot().account.avatar} class={tootStyle.tootAvatar} /> <Img src={toot().account.avatar} class={tootStyle.tootAvatar} />
<div class={tootStyle.tootAuthorNameGrp}> <div class={tootStyle.tootAuthorNameGrp}>
<Body2 <Body2
@ -309,6 +315,13 @@ export function TootPreviewCard(props: {
); );
} }
/**
* Component for a toot.
*
* If the session involved is not the first session, you must wrap
* this component under a `<DefaultSessionProvier />` with correct
* session.
*/
const RegularToot: Component<TootCardProps> = (props) => { const RegularToot: Component<TootCardProps> = (props) => {
let rootRef: HTMLElement; let rootRef: HTMLElement;
const [managed, managedActionGroup, rest] = splitProps( const [managed, managedActionGroup, rest] = splitProps(
@ -319,6 +332,25 @@ const RegularToot: Component<TootCardProps> = (props) => {
const now = useTimeSource(); const now = useTimeSource();
const status = () => managed.status; const status = () => managed.status;
const toot = () => status().reblog ?? status(); const toot = () => status().reblog ?? status();
const session = useDefaultSession();
const navigate = useNavigate();
const openProfile = (event: MouseEvent) => {
if (!managed.evaluated) return;
event.stopPropagation();
const s = session();
if (!s) {
console.warn("No session is provided");
return;
}
const acct = makeAcctText(s);
navigate(
`/${encodeURIComponent(acct)}/profile/${managed.status.account.id}`,
);
};
css` css`
.reply-sep { .reply-sep {
@ -396,7 +428,7 @@ const RegularToot: Component<TootCardProps> = (props) => {
</span> </span>
</div> </div>
</Show> </Show>
<TootAuthorGroup status={toot()} now={now()} /> <TootAuthorGroup status={toot()} now={now()} onClick={openProfile} />
<TootContentView <TootContentView
source={toot().content} source={toot().content}
emojis={toot().emojis} emojis={toot().emojis}