composing toots #21
4 changed files with 64 additions and 31 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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,9 +127,10 @@ const BottomSheet: ParentComponent<BottomSheetProps> = (props) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onMount(() => {
|
const onDialogClick = (
|
||||||
makeEventListener(element, "click", (event) => {
|
event: MouseEvent & { currentTarget: HTMLDialogElement },
|
||||||
const rect = element.getBoundingClientRect();
|
) => {
|
||||||
|
const rect = event.currentTarget.getBoundingClientRect();
|
||||||
const isInDialog =
|
const isInDialog =
|
||||||
rect.top <= event.clientY &&
|
rect.top <= event.clientY &&
|
||||||
event.clientY <= rect.top + rect.height &&
|
event.clientY <= rect.top + rect.height &&
|
||||||
|
@ -137,8 +139,7 @@ const BottomSheet: ParentComponent<BottomSheetProps> = (props) => {
|
||||||
if (!isInDialog) {
|
if (!isInDialog) {
|
||||||
props.onClose?.("backdrop");
|
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()}
|
||||||
|
|
|
@ -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>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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)}
|
||||||
>
|
|
||||||
<ChooseTootLang
|
|
||||||
code={language()}
|
code={language()}
|
||||||
onCodeChange={setLanguage}
|
onCodeChange={setLanguage}
|
||||||
onClose={[setLangPickerOpen, false]}
|
|
||||||
/>
|
/>
|
||||||
</BottomSheet>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue