diff --git a/src/App.tsx b/src/App.tsx
index cd6fe4f..69249b3 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -26,8 +26,6 @@ const TimelineHome = lazy(() => import("./timelines/Home.js"));
const Settings = lazy(() => import("./settings/Settings.js"));
const TootBottomSheet = lazy(() => import("./timelines/TootBottomSheet.js"));
const MotionSettings = lazy(() => import("./settings/Motions.js"));
-const LanguageSettings = lazy(() => import("./settings/Language.js"));
-const RegionSettings = lazy(() => import("./settings/Region.jsx"));
const Routing: Component = () => {
return (
@@ -36,8 +34,6 @@ const Routing: Component = () => {
-
-
diff --git a/src/material/BottomSheet.module.css b/src/material/BottomSheet.module.css
index 410858b..8f716e9 100644
--- a/src/material/BottomSheet.module.css
+++ b/src/material/BottomSheet.module.css
@@ -43,7 +43,7 @@
&.animated {
position: absolute;
- transform: translateY(-50%);
+ transform: none;
overflow: hidden;
will-change: width, height, top, left;
@@ -54,12 +54,6 @@
& * {
overflow: hidden;
}
-
- @media (max-width: 560px) {
- & {
- transform: none;
- }
- }
}
&.bottom {
diff --git a/src/material/BottomSheet.tsx b/src/material/BottomSheet.tsx
index e753e20..92eabc9 100644
--- a/src/material/BottomSheet.tsx
+++ b/src/material/BottomSheet.tsx
@@ -36,7 +36,7 @@ function composeAnimationFrame(
};
}
-const MOVE_SPEED = 1200;
+const MOVE_SPEED = 1400; // 1400px/s, bottom sheet is big and a bit heavier than small papers
const BottomSheet: ParentComponent = (props) => {
let element: HTMLDialogElement;
@@ -62,17 +62,13 @@ const BottomSheet: ParentComponent = (props) => {
});
const onClose = () => {
- const srcElement = hero();
- if (srcElement) {
- srcElement.style.visibility = "unset";
- }
-
+ hero()!.style.visibility = 'unset'
element.close();
setHero();
};
const animatedClose = () => {
- const srcElement = hero();
+ const srcElement = hero()
const endRect = srcElement?.getBoundingClientRect();
if (endRect) {
const startRect = element.getBoundingClientRect();
@@ -80,94 +76,19 @@ const BottomSheet: ParentComponent = (props) => {
animation.addEventListener("finish", onClose);
animation.addEventListener("cancel", onClose);
} else {
- if (window.innerWidth > 560 && !props.bottomUp) {
- onClose();
- return;
- }
- const animation = props.bottomUp
- ? animateSlideInFromBottom(element, true)
- : animateSlideInFromRight(element, true);
- animation.addEventListener("finish", onClose);
- animation.addEventListener("cancel", onClose);
+ element.close();
+ setHero();
}
};
const animatedOpen = () => {
element.showModal();
- const srcElement = hero();
+ const srcElement = hero()
const startRect = srcElement?.getBoundingClientRect();
- if (startRect) {
- srcElement!.style.visibility = "hidden";
- const endRect = element.getBoundingClientRect();
- animateHero(startRect, endRect, element);
- } else if (props.bottomUp) {
- animateSlideInFromBottom(element);
- } else if (window.innerWidth <= 560) {
- animateSlideInFromRight(element);
- }
- };
-
- const animateSlideInFromRight = (element: HTMLElement, reserve?: boolean) => {
- const rect = element.getBoundingClientRect();
- const easing = "cubic-bezier(0.4, 0, 0.2, 1)";
- element.classList.add(styles.animated);
- const oldOverflow = document.body.style.overflow;
- document.body.style.overflow = "hidden";
- const distance = Math.abs(rect.left - window.innerWidth);
- const duration = (distance / MOVE_SPEED) * 1000;
-
- animation = element.animate(
- {
- top: [rect.top, rect.top],
- left: reserve
- ? [`${rect.left}px`, `${window.innerWidth}px`]
- : [`${window.innerWidth}px`, `${rect.left}px`],
- width: [rect.width, rect.width],
- height: [rect.height, rect.height],
- },
- { easing, duration },
- );
- const onAnimationEnd = () => {
- element.classList.remove(styles.animated);
- document.body.style.overflow = oldOverflow;
- animation = undefined;
- };
- animation.addEventListener("cancel", onAnimationEnd);
- animation.addEventListener("finish", onAnimationEnd);
- return animation;
- };
-
- const animateSlideInFromBottom = (
- element: HTMLElement,
- reserve?: boolean,
- ) => {
- const rect = element.getBoundingClientRect();
- const easing = "cubic-bezier(0.4, 0, 0.2, 1)";
- element.classList.add(styles.animated);
- const oldOverflow = document.body.style.overflow;
- document.body.style.overflow = "hidden";
- const distance = Math.abs(rect.top - window.innerHeight);
- const duration = (distance / MOVE_SPEED) * 1000;
-
- animation = element.animate(
- {
- left: [rect.left, rect.left],
- top: reserve
- ? [`${rect.top}px`, `${window.innerHeight}px`]
- : [`${window.innerHeight}px`, `${rect.top}px`],
- width: [rect.width, rect.width],
- height: [rect.height, rect.height],
- },
- { easing, duration },
- );
- const onAnimationEnd = () => {
- element.classList.remove(styles.animated);
- document.body.style.overflow = oldOverflow;
- animation = undefined;
- };
- animation.addEventListener("cancel", onAnimationEnd);
- animation.addEventListener("finish", onAnimationEnd);
- return animation;
+ if (!startRect) return;
+ srcElement!.style.visibility = 'hidden'
+ const endRect = element.getBoundingClientRect();
+ animateHero(startRect, endRect, element);
};
const animateHero = (
diff --git a/src/settings/Language.tsx b/src/settings/ChooseLang.tsx
similarity index 73%
rename from src/settings/Language.tsx
rename to src/settings/ChooseLang.tsx
index f04d4b1..ac03c7b 100644
--- a/src/settings/Language.tsx
+++ b/src/settings/ChooseLang.tsx
@@ -13,7 +13,7 @@ import {
Switch,
Toolbar,
} from "@suid/material";
-import { ArrowBack } from "@suid/icons-material";
+import { Close as CloseIcon } from "@suid/icons-material";
import iso639_1 from "iso-639-1";
import {
autoMatchLangTag,
@@ -22,12 +22,14 @@ import {
} from "../platform/i18n";
import { Title } from "../material/typography";
import type { Template } from "@solid-primitives/i18n";
-import { useStore } from "@nanostores/solid";
-import { $settings } from "./stores";
-import { useNavigate } from "@solidjs/router";
-const ChooseLang: Component = () => {
- const navigate = useNavigate()
+type ChooseLangProps = {
+ code?: string;
+ onCodeChange: (ncode?: string) => void;
+ onClose?: JSX.EventHandlerUnion;
+};
+
+const ChooseLang: Component = (props) => {
const [t] = createTranslator(
() => import("./i18n/lang-names.json"),
(code) =>
@@ -37,9 +39,6 @@ const ChooseLang: Component = () => {
};
}>,
);
- const settings = useStore($settings)
-
- const code = () => settings().language
const unsupportedLangCodes = createMemo(() => {
return iso639_1.getAllCodes().filter((x) => !["zh", "en"].includes(x));
@@ -47,10 +46,6 @@ const ChooseLang: Component = () => {
const matchedLangCode = createMemo(() => autoMatchLangTag());
- const onCodeChange = (code?: string) => {
- $settings.setKey("language", code)
- }
-
return (
{
variant="dense"
sx={{ paddingTop: "var(--safe-area-inset-top, 0px)" }}
>
-
-
+
+
{t("Choose Language")}
@@ -74,7 +69,7 @@ const ChooseLang: Component = () => {
>
{
- onCodeChange(code() ? undefined : matchedLangCode());
+ props.onCodeChange(props.code ? undefined : matchedLangCode());
}}
>
@@ -83,20 +78,20 @@ const ChooseLang: Component = () => {
})}
-
+
{t("Supported")}}>
- {(c) => (
+ {(code) => (
- {t(`lang.${c}`)}
+ {t(`lang.${code}`)}
diff --git a/src/settings/Region.tsx b/src/settings/ChooseRegion.tsx
similarity index 66%
rename from src/settings/Region.tsx
rename to src/settings/ChooseRegion.tsx
index 1ae1a62..77a969e 100644
--- a/src/settings/Region.tsx
+++ b/src/settings/ChooseRegion.tsx
@@ -12,7 +12,8 @@ import {
Switch,
Toolbar,
} from "@suid/material";
-import { ArrowBack } from "@suid/icons-material";
+import { Close as CloseIcon } from "@suid/icons-material";
+import iso639_1 from "iso-639-1";
import {
autoMatchRegion,
createTranslator,
@@ -20,12 +21,14 @@ import {
} from "../platform/i18n";
import { Title } from "../material/typography";
import type { Template } from "@solid-primitives/i18n";
-import { useNavigate } from "@solidjs/router";
-import { $settings } from "./stores";
-import { useStore } from "@nanostores/solid";
-const ChooseRegion: Component = () => {
- const navigate = useNavigate();
+type ChooseRegionProps = {
+ code?: string;
+ onCodeChange: (ncode?: string) => void;
+ onClose?: JSX.EventHandlerUnion;
+};
+
+const ChooseRegion: Component = (props) => {
const [t] = createTranslator(
() => import("./i18n/lang-names.json"),
(code) =>
@@ -36,16 +39,12 @@ const ChooseRegion: Component = () => {
}>,
);
- const settings = useStore($settings);
-
- const region = () => settings().region;
+ const unsupportedLangCodes = createMemo(() => {
+ return iso639_1.getAllCodes().filter((x) => !["zh", "en"].includes(x));
+ });
const matchedRegionCode = createMemo(() => autoMatchRegion());
- const onCodeChange = (code?: string) => {
- $settings.setKey("region", code);
- };
-
return (
{
variant="dense"
sx={{ paddingTop: "var(--safe-area-inset-top, 0px)" }}
>
-
-
+
+
{t("Choose Language")}
@@ -69,17 +68,16 @@ const ChooseRegion: Component = () => {
>
{
- onCodeChange(region() ? undefined : matchedRegionCode());
+ props.onCodeChange(props.code ? undefined : matchedRegionCode());
}}
>
{t("region.auto", {
- detected:
- t(`region.${matchedRegionCode()}`) ?? matchedRegionCode(),
+ detected: t(`region.${matchedRegionCode()}`) ?? matchedRegionCode(),
})}
-
+
@@ -87,16 +85,13 @@ const ChooseRegion: Component = () => {
{(code) => (
{t(`region.${code}`)}
diff --git a/src/settings/Motions.tsx b/src/settings/Motions.tsx
index a90bd44..2f111fd 100644
--- a/src/settings/Motions.tsx
+++ b/src/settings/Motions.tsx
@@ -14,7 +14,7 @@ import {
} from "@suid/material";
import { Title } from "../material/typography";
import { useNavigate } from "@solidjs/router";
-import { ArrowBack } from "@suid/icons-material";
+import { Close as CloseIcon } from "@suid/icons-material";
import { createTranslator } from "../platform/i18n";
import { useStore } from "@nanostores/solid";
import { $settings } from "./stores";
@@ -37,7 +37,7 @@ const Motions: Component = () => {
sx={{ paddingTop: "var(--safe-area-inset-top, 0px)" }}
>
-
+
{t("motions")}
diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx
index 826fea9..e27443a 100644
--- a/src/settings/Settings.tsx
+++ b/src/settings/Settings.tsx
@@ -41,10 +41,15 @@ import {
autoMatchLangTag,
autoMatchRegion,
createTranslator,
+ SUPPORTED_LANGS,
+ SUPPORTED_REGIONS,
useDateFnLocale,
} from "../platform/i18n.jsx";
import { type Template } from "@solid-primitives/i18n";
import BottomSheet from "../material/BottomSheet.jsx";
+import ChooseLang from "./ChooseLang.jsx";
+import ChooseRegion from "./ChooseRegion.jsx";
+import { Portal } from "solid-js/web";
type Strings = {
["lang.auto"]: Template<{ detected: string }>;
@@ -64,6 +69,8 @@ const Settings: ParentComponent = (props) => {
needRefresh: [needRefresh],
} = useRegisterSW();
const dateFnLocale = useDateFnLocale();
+ const [langPickerOpen, setLangPickerOpen] = createSignal(false);
+ const [regionPickerOpen, setRegionPickerOpen] = createSignal(false);
const [profiles] = useSignedInProfiles();
@@ -168,7 +175,7 @@ const Settings: ParentComponent = (props) => {
{t("This Application")}
-
+
@@ -185,8 +192,15 @@ const Settings: ParentComponent = (props) => {
{t("Language")}
+
+ $settings.setKey("language", nval)}
+ onClose={[setLangPickerOpen, false]}
+ />
+
-
+
@@ -203,6 +217,13 @@ const Settings: ParentComponent = (props) => {
{t("Region")}
+
+ $settings.setKey("region", nval)}
+ onClose={[setRegionPickerOpen, false]}
+ />
+