TootBottomSheet: fix the skipped animation

This commit is contained in:
thislight 2024-09-27 18:04:09 +08:00
parent 84dcf9ed86
commit 853ee98525
No known key found for this signature in database
GPG key ID: A50F9451AC56A63E
4 changed files with 64 additions and 31 deletions

View file

@ -44,10 +44,16 @@
&.animated { &.animated {
position: absolute; position: absolute;
transform: none; transform: none;
overflow: hidden;
will-change: width, height, top, left;
&::backdrop { &::backdrop {
opacity: 0; opacity: 0;
} }
& * {
overflow: hidden;
}
} }
&.bottom { &.bottom {

View file

@ -55,7 +55,7 @@ const BottomSheet: ParentComponent<BottomSheetProps> = (props) => {
createEffect(() => { createEffect(() => {
if (props.open) { if (props.open) {
if (!element.open && !pending()) { if (!element.open && !pending()) {
animatedOpen(); requestAnimationFrame(animatedOpen);
setCache(ochildren()); setCache(ochildren());
} }
} else { } else {
@ -66,15 +66,16 @@ const BottomSheet: ParentComponent<BottomSheetProps> = (props) => {
} }
}); });
const onClose = () => {
element.close();
setHero();
};
const animatedClose = () => { const animatedClose = () => {
const endRect = hero(); const endRect = hero();
if (endRect) { if (endRect) {
const startRect = element.getBoundingClientRect(); const startRect = element.getBoundingClientRect();
const animation = animateHero(startRect, endRect, element, true); const animation = animateHero(startRect, endRect, element, true);
const onClose = () => {
element.close();
setHero();
};
animation.addEventListener("finish", onClose); animation.addEventListener("finish", onClose);
animation.addEventListener("cancel", onClose); animation.addEventListener("cancel", onClose);
} else { } else {
@ -126,19 +127,19 @@ const BottomSheet: ParentComponent<BottomSheetProps> = (props) => {
} }
}); });
onMount(() => { const onDialogClick = (
makeEventListener(element, "click", (event) => { event: MouseEvent & { currentTarget: HTMLDialogElement },
const rect = element.getBoundingClientRect(); ) => {
const isInDialog = const rect = event.currentTarget.getBoundingClientRect();
rect.top <= event.clientY && const isInDialog =
event.clientY <= rect.top + rect.height && rect.top <= event.clientY &&
rect.left <= event.clientX && event.clientY <= rect.top + rect.height &&
event.clientX <= rect.left + rect.width; rect.left <= event.clientX &&
if (!isInDialog) { event.clientX <= rect.left + rect.width;
props.onClose?.("backdrop"); if (!isInDialog) {
} props.onClose?.("backdrop");
}); }
}); };
return ( return (
<dialog <dialog
@ -146,6 +147,7 @@ const BottomSheet: ParentComponent<BottomSheetProps> = (props) => {
[styles.bottomSheet]: true, [styles.bottomSheet]: true,
[styles.bottom]: props.bottomUp, [styles.bottom]: props.bottomUp,
}} }}
onClick={onDialogClick}
ref={element!} ref={element!}
> >
{ochildren() ?? cache()} {ochildren() ?? cache()}

View file

@ -22,7 +22,7 @@ import { Title } from "../material/typography";
type ChooseTootLangProps = { type ChooseTootLangProps = {
code: string; code: string;
onCodeChange: (ncode?: string) => void; onCodeChange: (ncode: string) => void;
onClose?: JSX.EventHandlerUnion<HTMLButtonElement, MouseEvent>; onClose?: JSX.EventHandlerUnion<HTMLButtonElement, MouseEvent>;
}; };

View file

@ -1,8 +1,12 @@
import { import {
batch, batch,
createEffect,
createRenderEffect,
createSignal, createSignal,
createUniqueId, createUniqueId,
lazy,
onMount, onMount,
Show,
type Component, type Component,
type Setter, type Setter,
} from "solid-js"; } from "solid-js";
@ -156,6 +160,25 @@ const TootVisibilityPickerDialog: Component<{
); );
}; };
const TootLanguagePickerDialog: Component<{
open?: boolean;
onClose: () => void;
code: string;
onCodeChange: (nval: string) => void;
}> = (props) => {
return (
<BottomSheet open={props.open} onClose={props.onClose}>
<Show when={props.open}>
<ChooseTootLang
code={props.code}
onCodeChange={props.onCodeChange}
onClose={props.onClose}
/>
</Show>
</BottomSheet>
);
};
const ReplyEditor: Component<{ const ReplyEditor: Component<{
profile: Account; profile: Account;
replyToDisplayName: string; replyToDisplayName: string;
@ -163,15 +186,19 @@ const ReplyEditor: Component<{
onTypingChange: (value: boolean) => void; onTypingChange: (value: boolean) => void;
}> = (props) => { }> = (props) => {
let inputRef: HTMLTextAreaElement; let inputRef: HTMLTextAreaElement;
const buttonId = createUniqueId();
const menuId = createUniqueId();
const typing = () => props.isTyping; const typing = () => props.isTyping;
const setTyping = (v: boolean) => props.onTypingChange(v); 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);
const [language, setLanguage] = createSignal(useLanguage()().split("-")[0]); const [language, setLanguage] = createSignal("en");
const [langPickerOpen, setLangPickerOpen] = createSignal(false); const [langPickerOpen, setLangPickerOpen] = createSignal(false);
const appLanguage = useLanguage();
createEffect(() => {
const lang = appLanguage().split("-")[0];
setLanguage(lang);
});
onMount(() => { onMount(() => {
makeEventListener(inputRef, "focus", () => setTyping(true)); makeEventListener(inputRef, "focus", () => setTyping(true));
@ -223,6 +250,8 @@ const ReplyEditor: Component<{
display: "flex", display: "flex",
"justify-content": "flex-end", "justify-content": "flex-end",
"margin-top": "8px", "margin-top": "8px",
gap: "16px",
"flex-flow": "row wrap"
}} }}
> >
<Button onClick={[setLangPickerOpen, true]}> <Button onClick={[setLangPickerOpen, true]}>
@ -230,7 +259,7 @@ const ReplyEditor: Component<{
{iso639_1.getNativeName(language())} {iso639_1.getNativeName(language())}
<ArrowDropDown sx={{ marginTop: "-0.25em" }} /> <ArrowDropDown sx={{ marginTop: "-0.25em" }} />
</Button> </Button>
<Button onClick={[setPermPicker, true]} id={buttonId}> <Button onClick={[setPermPicker, true]}>
<Visibility sx={{ marginTop: "-0.15em", marginRight: "0.25em" }} /> <Visibility sx={{ marginTop: "-0.15em", marginRight: "0.25em" }} />
{visibilityText()} {visibilityText()}
<ArrowDropDown sx={{ marginTop: "-0.25em" }} /> <ArrowDropDown sx={{ marginTop: "-0.25em" }} />
@ -244,16 +273,12 @@ const ReplyEditor: Component<{
onVisibilityChange={setVisibility} onVisibilityChange={setVisibility}
/> />
<BottomSheet <TootLanguagePickerDialog
open={langPickerOpen()} open={langPickerOpen()}
onClose={() => setLangPickerOpen(false)} onClose={() => setLangPickerOpen(false)}
> code={language()}
<ChooseTootLang onCodeChange={setLanguage}
code={language()} />
onCodeChange={setLanguage}
onClose={[setLangPickerOpen, false]}
/>
</BottomSheet>
</div> </div>
); );
}; };