added composing new toots

This commit is contained in:
thislight 2024-09-28 15:15:06 +08:00
parent 143ecf6278
commit dd6051aea7
No known key found for this signature in database
GPG key ID: A50F9451AC56A63E
3 changed files with 55 additions and 15 deletions

View file

@ -11,7 +11,7 @@ import {
Suspense,
Match,
Switch as JsSwitch,
ErrorBoundary
ErrorBoundary,
} from "solid-js";
import { useDocumentTitle } from "../utils";
import { type mastodon } from "masto";
@ -47,6 +47,7 @@ import { HeroSourceProvider, type HeroSource } from "../platform/anim";
import { useNavigate } from "@solidjs/router";
import { useSignedInProfiles } from "../masto/acct";
import { setCache as setTootBottomSheetCache } from "./TootBottomSheet";
import TootComposer from "./TootComposer";
const TimelinePanel: Component<{
client: mastodon.rest.Client;
@ -72,6 +73,7 @@ const TimelinePanel: Component<{
{ fullRefresh: props.fullRefetch },
);
const [expandedThreadId, setExpandedThreadId] = createSignal<string>();
const [typing, setTyping] = createSignal(false);
const tlEndObserver = new IntersectionObserver(() => {
if (untrack(() => props.prefetch) && !snapshot.loading)
@ -126,9 +128,11 @@ const TimelinePanel: Component<{
};
return (
<ErrorBoundary fallback={(err, reset) => {
return <p>Oops: {String(err)}</p>
}}>
<ErrorBoundary
fallback={(err, reset) => {
return <p>Oops: {String(err)}</p>;
}}
>
<PullDownToRefresh
linkedElement={scrollLinked()}
loading={snapshot.loading}
@ -141,6 +145,17 @@ const TimelinePanel: Component<{
}, 0)
}
>
<Show when={props.name === "home"}>
<TootComposer
style={{
"--scaffold-topbar-height": "0px",
}}
isTyping={typing()}
onTypingChange={setTyping}
client={props.client}
onSent={() => refetchTimeline({direction: "new"})}
/>
</Show>
<For each={timeline}>
{(item, index) => {
let element: HTMLElement | undefined;

View file

@ -23,7 +23,7 @@ import cards from "../material/cards.module.css";
import { css } from "solid-styled";
import { vibrate } from "../platform/hardware";
import { createTimeSource, TimeSourceProvider } from "../platform/timesrc";
import ReplyEditor from "./ReplyEditor";
import TootComposer from "./TootComposer";
let cachedEntry: [string, mastodon.v1.Status] | undefined;
@ -250,7 +250,7 @@ const TootBottomSheet: Component = (props) => {
</article>
<Show when={session()!.account}>
<ReplyEditor
<TootComposer
isTyping={isInTyping()}
onTypingChange={setInTyping}
mentions={defaultMentions()}

View file

@ -5,6 +5,8 @@ import {
onMount,
Show,
type Component,
type JSX,
type Ref,
} from "solid-js";
import Scaffold from "../material/Scaffold";
import {
@ -177,15 +179,26 @@ const TootLanguagePickerDialog: Component<{
);
};
const ReplyEditor: Component<{
profile: Account;
replyToDisplayName: string;
function randomChoose<T extends any[]>(
rn: number,
K: T,
): T extends Array<infer E> ? E : never {
const idx = Math.round(rn * K.length);
return K[idx];
}
const TootComposer: Component<{
ref?: Ref<HTMLDivElement>;
style?: JSX.CSSProperties;
profile?: Account;
replyToDisplayName?: string;
mentions?: readonly string[];
isTyping?: boolean;
onTypingChange: (value: boolean) => void;
client?: mastodon.rest.Client;
inReplyToId?: string;
onSent?: (status: mastodon.v1.Status) => void;
inputProps?: JSX.TextareaHTMLAttributes<HTMLTextAreaElement>;
}> = (props) => {
let inputRef: HTMLTextAreaElement;
let sendKey: string | undefined;
@ -223,6 +236,7 @@ const ReplyEditor: Component<{
top: "var(--scaffold-topbar-height, 0)",
bottom: "var(--safe-area-inset-bottom, 0)",
"z-index": 2,
...props.style,
}
: undefined;
@ -274,20 +288,31 @@ const ReplyEditor: Component<{
return (
<div
ref={props.ref}
class={tootComposers.composer}
style={containerStyle()}
onClick={(e) => inputRef.focus()}
>
<div class={tootComposers.replyInput}>
<Avatar
src={props.profile.inf?.avatar}
sx={{ marginLeft: "-0.25em" }}
/>
<Show when={props.profile}>
<Avatar
src={props.profile!.inf?.avatar}
sx={{ marginLeft: "-0.25em" }}
/>
</Show>
<textarea
ref={inputRef!}
placeholder={`Reply to ${props.replyToDisplayName}...`}
placeholder={
props.replyToDisplayName
? `Reply to ${props.replyToDisplayName}...`
: randomChoose(Math.random(), [
"What's happening?",
"What do your think?",
])
}
style={{ width: "100%", border: "none" }}
disabled={sending()}
{...props.inputProps}
></textarea>
<Show when={props.client}>
<Show
@ -351,4 +376,4 @@ const ReplyEditor: Component<{
);
};
export default ReplyEditor;
export default TootComposer;