ReplyEditor: promote the blur condition up
This commit is contained in:
parent
6c98f1e78d
commit
a1a587a77f
2 changed files with 23 additions and 21 deletions
|
@ -1,4 +1,5 @@
|
||||||
import {
|
import {
|
||||||
|
batch,
|
||||||
createSignal,
|
createSignal,
|
||||||
createUniqueId,
|
createUniqueId,
|
||||||
onMount,
|
onMount,
|
||||||
|
@ -57,14 +58,12 @@ const TootVisibilityPickerDialog: Component<{
|
||||||
|
|
||||||
const discoverable = () => {
|
const discoverable = () => {
|
||||||
return props.visibility === "public";
|
return props.visibility === "public";
|
||||||
}
|
|
||||||
|
|
||||||
const setDiscoverable = (setter: (v: boolean) => boolean) => {
|
|
||||||
const nval = setter(discoverable())
|
|
||||||
props.onVisibilityChange(nval ? "public" : "unlisted"); // trigger change
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const setDiscoverable = (setter: (v: boolean) => boolean) => {
|
||||||
|
const nval = setter(discoverable());
|
||||||
|
props.onVisibilityChange(nval ? "public" : "unlisted"); // trigger change
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BottomSheet open={props.open} onClose={props.onClose} bottomUp>
|
<BottomSheet open={props.open} onClose={props.onClose} bottomUp>
|
||||||
|
@ -83,7 +82,7 @@ const TootVisibilityPickerDialog: Component<{
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<List>
|
<List dense>
|
||||||
<ListItemButton onClick={[setKind, "public"]}>
|
<ListItemButton onClick={[setKind, "public"]}>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<PublicIcon />
|
<PublicIcon />
|
||||||
|
@ -155,27 +154,29 @@ const TootVisibilityPickerDialog: Component<{
|
||||||
const ReplyEditor: Component<{
|
const ReplyEditor: Component<{
|
||||||
profile: Account;
|
profile: Account;
|
||||||
replyToDisplayName: string;
|
replyToDisplayName: string;
|
||||||
|
isTyping?: boolean
|
||||||
|
onTypingChange: (value: boolean) => void
|
||||||
}> = (props) => {
|
}> = (props) => {
|
||||||
let inputRef: HTMLTextAreaElement;
|
let inputRef: HTMLTextAreaElement;
|
||||||
const buttonId = createUniqueId();
|
const buttonId = createUniqueId();
|
||||||
const menuId = createUniqueId();
|
const menuId = createUniqueId();
|
||||||
|
|
||||||
const [typing, setTyping] = createSignal(false);
|
const typing = () => props.isTyping
|
||||||
|
const setTyping = (v: boolean) => props.onTypingChange(v)
|
||||||
const [visibility, setVisibility] = createSignal<TootVisibility>("public");
|
const [visibility, setVisibility] = createSignal<TootVisibility>("public");
|
||||||
const [permPicker, setPermPicker] = createSignal(false);
|
const [permPicker, setPermPicker] = createSignal(false);
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
makeEventListener(inputRef, "focus", () => setTyping(true));
|
makeEventListener(inputRef, "focus", () => setTyping(true));
|
||||||
makeEventListener(inputRef, "blur", () => setTyping(false));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const containerStyle = () =>
|
const containerStyle = () =>
|
||||||
typing()
|
typing() || permPicker()
|
||||||
? {
|
? {
|
||||||
position: "sticky" as const,
|
position: "sticky" as const,
|
||||||
top: "var(--scaffold-topbar-height, 0)",
|
top: "var(--scaffold-topbar-height, 0)",
|
||||||
bottom: "var(--safe-area-inset-bottom, 0)",
|
bottom: "var(--safe-area-inset-bottom, 0)",
|
||||||
"z-index": 1,
|
"z-index": 2,
|
||||||
}
|
}
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
|
@ -196,7 +197,7 @@ const ReplyEditor: Component<{
|
||||||
<div
|
<div
|
||||||
class={tootComposers.composer}
|
class={tootComposers.composer}
|
||||||
style={containerStyle()}
|
style={containerStyle()}
|
||||||
onClick={() => setTyping(true)}
|
onClick={(e) => inputRef.focus()}
|
||||||
>
|
>
|
||||||
<div class={tootComposers.replyInput}>
|
<div class={tootComposers.replyInput}>
|
||||||
<Avatar src={props.profile.inf?.avatar} />
|
<Avatar src={props.profile.inf?.avatar} />
|
||||||
|
@ -219,7 +220,7 @@ const ReplyEditor: Component<{
|
||||||
>
|
>
|
||||||
<Button onClick={[setPermPicker, true]} id={buttonId}>
|
<Button onClick={[setPermPicker, true]} id={buttonId}>
|
||||||
{visibilityText()}
|
{visibilityText()}
|
||||||
<ArrowDropDown />
|
<ArrowDropDown sx={{ marginTop: "-0.25em" }} />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -3,17 +3,13 @@ import {
|
||||||
createEffect,
|
createEffect,
|
||||||
createRenderEffect,
|
createRenderEffect,
|
||||||
createResource,
|
createResource,
|
||||||
|
createSignal,
|
||||||
For,
|
For,
|
||||||
Show,
|
Show,
|
||||||
type Component,
|
type Component,
|
||||||
} from "solid-js";
|
} from "solid-js";
|
||||||
import Scaffold from "../material/Scaffold";
|
import Scaffold from "../material/Scaffold";
|
||||||
import {
|
import { AppBar, CircularProgress, IconButton, Toolbar } from "@suid/material";
|
||||||
AppBar,
|
|
||||||
CircularProgress,
|
|
||||||
IconButton,
|
|
||||||
Toolbar,
|
|
||||||
} from "@suid/material";
|
|
||||||
import { Title } from "../material/typography";
|
import { Title } from "../material/typography";
|
||||||
import {
|
import {
|
||||||
ArrowBack as BackIcon,
|
ArrowBack as BackIcon,
|
||||||
|
@ -41,14 +37,13 @@ function getCache(acct: string, id: string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const TootBottomSheet: Component = (props) => {
|
const TootBottomSheet: Component = (props) => {
|
||||||
const params = useParams<{ acct: string; id: string }>();
|
const params = useParams<{ acct: string; id: string }>();
|
||||||
const location = useLocation<{ tootBottomSheetPushedCount?: number }>();
|
const location = useLocation<{ tootBottomSheetPushedCount?: number }>();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const allSession = useSessions();
|
const allSession = useSessions();
|
||||||
const time = createTimeSource();
|
const time = createTimeSource();
|
||||||
|
const [isInTyping, setInTyping] = createSignal(false);
|
||||||
const acctText = () => decodeURIComponent(params.acct);
|
const acctText = () => decodeURIComponent(params.acct);
|
||||||
const session = () => {
|
const session = () => {
|
||||||
const [inputUsername, inputSite] = acctText().split("@", 2);
|
const [inputUsername, inputSite] = acctText().split("@", 2);
|
||||||
|
@ -164,6 +159,10 @@ const TootBottomSheet: Component = (props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const switchContext = (status: mastodon.v1.Status) => {
|
const switchContext = (status: mastodon.v1.Status) => {
|
||||||
|
if (isInTyping()) {
|
||||||
|
setInTyping(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
setCache(params.acct, status);
|
setCache(params.acct, status);
|
||||||
navigate(`/${params.acct}/${status.id}`, {
|
navigate(`/${params.acct}/${status.id}`, {
|
||||||
state: {
|
state: {
|
||||||
|
@ -240,6 +239,8 @@ const TootBottomSheet: Component = (props) => {
|
||||||
|
|
||||||
<Show when={profile()}>
|
<Show when={profile()}>
|
||||||
<ReplyEditor
|
<ReplyEditor
|
||||||
|
isTyping={isInTyping()}
|
||||||
|
onTypingChange={setInTyping}
|
||||||
profile={profile()!}
|
profile={profile()!}
|
||||||
replyToDisplayName={toot()?.account?.displayName || ""}
|
replyToDisplayName={toot()?.account?.displayName || ""}
|
||||||
/>
|
/>
|
||||||
|
|
Loading…
Reference in a new issue