added composing new toots
This commit is contained in:
parent
143ecf6278
commit
dd6051aea7
3 changed files with 55 additions and 15 deletions
|
@ -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;
|
||||
|
|
|
@ -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()}
|
||||
|
|
|
@ -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;
|
Loading…
Reference in a new issue