import { For, Show, type Component } from "solid-js"; import Scaffold from "~material/Scaffold.js"; import { AppBar, Divider, IconButton, List, ListItem, ListItemButton, ListItemIcon, ListItemSecondaryAction, ListItemText, ListSubheader, NativeSelect, Switch, Toolbar, } from "@suid/material"; import { Animation as AnimationIcon, Close as CloseIcon, Logout, Public as PublicIcon, Refresh as RefreshIcon, Translate as TranslateIcon, } from "@suid/icons-material"; import A from "~platform/A.js"; import { Title } from "~material/typography.js"; import { css } from "solid-styled"; import { signOut, type Account } from "../accounts/stores.js"; import { format } from "date-fns"; import { useStore } from "@nanostores/solid"; import { $settings } from "./stores.js"; import { autoMatchLangTag, autoMatchRegion, createTranslator, useDateFnLocale, } from "~platform/i18n.jsx"; import { type Template } from "@solid-primitives/i18n"; import { useServiceWorker } from "~platform/host.js"; import { useSessions } from "../masto/clients.js"; import { useNavigator } from "~platform/StackedRouter.jsx"; type Inset = { top?: number; right?: number; bottom?: number; left?: number; }; type SafeAreaInsets = { landscape: Inset; protrait: Inset; }; const safeAreaInsets: Record = { iphone15: { protrait: { top: 59, bottom: 34, }, landscape: { bottom: 21, left: 59, right: 59, }, }, iphone12: { protrait: { top: 47, bottom: 34, }, landscape: { bottom: 21, left: 47, right: 47, }, }, iphone13mini: { protrait: { top: 50, bottom: 34, }, landscape: { bottom: 21, left: 50, right: 50, }, }, }; let screenOrientationCallback: (() => void) | undefined; function removeSafeAreaEmulation(root: HTMLElement) { for (const name of ["top", "right", "bottom", "left"]) { root.style.removeProperty(`--safe-area-inset-${name}`); } } function applySafeAreaEmulation(root: HTMLElement, insets: Inset) { removeSafeAreaEmulation(root); for (const key of Object.keys(insets) as (keyof Inset)[]) { const value = insets[key]; if (!value || value === 0) continue; root.style.setProperty(`--safe-area-inset-${key}`, `${value}px`); } } function setupSafeAreaEmulation(name: string) { const insets = safeAreaInsets[name]; const root = document.querySelector(":root")! as HTMLElement; if (screenOrientationCallback) { window.screen.orientation.removeEventListener( "change", screenOrientationCallback, ); screenOrientationCallback = undefined; } removeSafeAreaEmulation(root); if (insets) { screenOrientationCallback = () => { console.debug( `safe area emulation target: ${window.screen.orientation.type}`, ); if (window.screen.orientation.type === "portrait-primary") { console.debug("safe area emulation: protrait"); applySafeAreaEmulation(root, insets.protrait); } else if (window.screen.orientation.type === "landscape-primary") { console.debug("safe area emulation: landscape"); applySafeAreaEmulation(root, insets.landscape); } }; window.screen.orientation.addEventListener( "change", screenOrientationCallback, ); screenOrientationCallback(); } } if (import.meta.hot) { import.meta.hot.accept((mod) => { if (!mod) return; if (screenOrientationCallback) { mod["screenOrientationCallback"] = screenOrientationCallback; setTimeout(screenOrientationCallback, 0); } }); } type Strings = { ["lang.auto"]: Template<{ detected: string }>; } & Record; const Settings: Component = () => { const [t] = createTranslator( (code) => import(`./i18n/${code}.json`) as Promise<{ default: Strings; }>, () => import(`./i18n/generic.json`), ); const { pop } = useNavigator(); const settings$ = useStore($settings); const { needRefresh } = useServiceWorker(); const dateFnLocale = useDateFnLocale(); const profiles = useSessions(); const doSignOut = (acct: Account) => { signOut((a) => a.site === acct.site && a.accessToken === acct.accessToken); }; css` ul { padding: 0; } .setting-list { padding-bottom: calc(var(--safe-area-inset-bottom, 0px) + 16px); overflow: hidden auto; height: calc(100vh - var(--scaffold-topbar-height, 0)); height: calc(100dvh - var(--scaffold-topbar-height, 0)); } `; return ( {t("Settings")} } >
    • {t("Accounts")} {t("All Notifications")} {t("Sign in...")}
    {({ account: acct }) => (
      {`@${acct.inf?.username ?? "..."}@${new URL(acct.site).host}`} {t("Notifications")} {t("Sign out")}
    )}
  • {t("timelines")} $settings.setKey( "prefetchTootsDisabled", !settings$().prefetchTootsDisabled, ) } > {t("Prefetch Toots")} {t("motions")}
  • {t("This Application")} {t("Language")} {t("Region")} {t("About Tutu")} {needRefresh() ? t("updates.ready") : t("updates.no")} window.location.reload()} > {import.meta.env.VITE_CODE_VERSION ? ( <> {t("version.code")} ) : ( <> )}
  • {import.meta.env.DEV ? (
  • Developer Tools { const k = event.currentTarget.value; setupSafeAreaEmulation(k); }} > ) : undefined } > Safe Area Insets
  • ) : ( <> )}
    ); }; export default Settings;