From b4fa751345311ffe53072db2f4c5103b37d5f880 Mon Sep 17 00:00:00 2001 From: thislight Date: Thu, 26 Sep 2024 17:23:40 +0800 Subject: [PATCH 1/5] first prototype of i18n system --- bun.lockb | Bin 238907 -> 239741 bytes package.json | 2 + src/App.tsx | 21 +++- src/platform/i18n.tsx | 170 +++++++++++++++++++++++++++++++++ src/settings/Settings.tsx | 119 +++++++++++++++++++---- src/settings/i18n/en.json | 25 +++++ src/settings/i18n/zh-Hans.json | 25 +++++ src/settings/stores.ts | 2 + src/timelines/RegularToot.tsx | 4 +- 9 files changed, 348 insertions(+), 20 deletions(-) create mode 100644 src/platform/i18n.tsx create mode 100644 src/settings/i18n/en.json create mode 100644 src/settings/i18n/zh-Hans.json diff --git a/bun.lockb b/bun.lockb index 024e9977b43bda1ed14ddda5e184503ea59508b0..8230f5ff44fe878835dc364611480f661f380f35 100755 GIT binary patch delta 42224 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ℑfQCml7XzvXdP2z-ASf`V85jS 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 VF+RM#)!a8@#KZ%6&*bIX{vVlK`(Xe8 delta 41999 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 rSuL_HFNm?{ import("./accounts/SignIn.js")); const AccountMastodonOAuth2Callback = lazy( @@ -47,6 +49,7 @@ const App: Component = () => { const theme = useRootTheme(); const accts = useStore($accounts); const clientStore = createSignal([]); + const lang = useLanguage(); createRenderEffect(() => { const [, setClients] = clientStore; @@ -55,6 +58,16 @@ const App: Component = () => { ); }); + createRenderEffect(() => { + const root = document.querySelector(":root")!; + root.setAttribute("lang", lang()); + }); + + onCleanup(() => { + const root = document.querySelector(":root")!; + root.removeAttribute("lang"); + }); + const UnexpectedError = lazy(() => import("./UnexpectedError.js")); return ( @@ -65,9 +78,11 @@ const App: Component = () => { }} > - - - + + + + + ); diff --git a/src/platform/i18n.tsx b/src/platform/i18n.tsx new file mode 100644 index 0000000..7627ea1 --- /dev/null +++ b/src/platform/i18n.tsx @@ -0,0 +1,170 @@ +import { + ParentComponent, + createContext, + createMemo, + createRenderEffect, + createResource, + useContext, +} from "solid-js"; +import { match } from "@formatjs/intl-localematcher"; +import { Accessor, createEffect, createSignal } from "solid-js"; +import { $settings } from "../settings/stores"; +import { enGB } from "date-fns/locale/en-GB"; +import { useStore } from "@nanostores/solid"; +import type { Locale } from "date-fns"; +import type { Template } from "@solid-primitives/i18n"; + +async function synchronised( + name: string, + callback: () => Promise | void, +): Promise { + await navigator.locks.request(name, callback); +} + +export const SUPPORTED_LANGS = ["en", "zh-Hans"]; + +export const SUPPORTED_REGIONS = ["en_US", "en_GB", "zh_CN"]; + +const DEFAULT_LANG = "en"; + +/** + * Decide the using language for the user. + * @returns the selected language tag + */ +export function autoMatchLangTag() { + return match(Array.from(navigator.languages), SUPPORTED_LANGS, DEFAULT_LANG); +} + +const DateFnLocaleCx = createContext>(() => enGB); + +const cachedDateFnLocale: Record = { + enGB, +}; + +export function autoMatchRegion() { + const regions = navigator.languages + .map((x) => { + const parts = x.split("_"); + if (parts.length > 1) { + return parts[1]; + } + return undefined; + }) + .filter((x): x is string => !!x); + for (const r of regions) { + for (const available of SUPPORTED_REGIONS) { + if (available.toLowerCase().endsWith(r.toLowerCase())) { + return available; + } + } + } + return "en_GB"; +} + +export function useRegion() { + const appSettings = useStore($settings); + + return createMemo(() => { + const settings = appSettings(); + if (typeof settings.region !== "undefined") { + return settings.region; + } else { + return autoMatchRegion(); + } + }); +} + +async function importDateFnLocale(tag: string): Promise { + switch (tag.toLowerCase()) { + case "en_us": + return (await import("date-fns/locale/en-US")).enUS; + case "en_gb": + return (await import("date-fns/locale/en-GB")).enGB; + case "zh_cn": + return (await import("date-fns/locale/zh-CN")).zhCN; + default: + throw new TypeError(`unsupported tag "${tag}"`); + } +} + +/** + * Provides runtime values and fetch dependencies for date-fns locale + */ +export const DateFnScope: ParentComponent = (props) => { + const [dateFnLocale, setDateFnLocale] = createSignal(enGB); + const region = useRegion(); + + createEffect(() => { + const dateFnLocaleName = region(); + + if (cachedDateFnLocale[dateFnLocaleName]) { + setDateFnLocale(cachedDateFnLocale[dateFnLocaleName]); + } else { + synchronised("i18n-wrapper-load-date-fns-locale", async () => { + if (cachedDateFnLocale[dateFnLocaleName]) { + setDateFnLocale(cachedDateFnLocale[dateFnLocaleName]); + return; + } + const target = `date-fns/locale/${dateFnLocaleName}`; + try { + const mod = await importDateFnLocale(dateFnLocaleName); + cachedDateFnLocale[dateFnLocaleName] = mod; + setDateFnLocale(mod); + } catch (reason) { + console.error( + { + act: "load-date-fns-locale", + stat: "failed", + reason, + target, + }, + "failed to load date-fns locale", + ); + } + }); + } + }); + + return ( + + {props.children} + + ); +}; + +/** + * Get the {@link Locale} object for date-fns. + * + * This function must be using in {@link DateFnScope} + * + * @returns Accessor for Locale + */ +export function useDateFnLocale(): Accessor { + const cx = useContext(DateFnLocaleCx); + return cx; +} + +export function useLanguage() { + const settings = useStore($settings); + return () => settings().language || autoMatchLangTag(); +} + +export function createStringResource< + M extends Record>, +>(importFn: (code: string) => Promise<{ default: M }>) { + const language = useLanguage(); + const cache: Record = {}; + + return createResource( + () => [language()] as const, + async ([nlang]) => { + if (cache[nlang]) { + return cache[nlang]; + } + + const { default: dict } = await importFn(`${nlang}`); + + return dict; + }, + ); +} diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx index 9eebcac..65d94b9 100644 --- a/src/settings/Settings.tsx +++ b/src/settings/Settings.tsx @@ -7,32 +7,50 @@ import { List, ListItem, ListItemButton, + ListItemIcon, ListItemSecondaryAction, ListItemText, ListSubheader, + NativeSelect, Switch, Toolbar, } from "@suid/material"; import { Close as CloseIcon, + Public as PublicIcon, Refresh as RefreshIcon, + Translate as TranslateIcon, } from "@suid/icons-material"; import { useNavigate } from "@solidjs/router"; import { Title } from "../material/typography.jsx"; import { css } from "solid-styled"; import { useSignedInProfiles } from "../masto/acct.js"; import { signOut, type Account } from "../accounts/stores.js"; -import { intlFormat } from "date-fns"; +import { format, intlFormat } from "date-fns"; import { useStore } from "@nanostores/solid"; import { $settings } from "./stores.js"; import { useRegisterSW } from "virtual:pwa-register/solid"; +import { + autoMatchLangTag, + autoMatchRegion, + createStringResource, + SUPPORTED_LANGS, + SUPPORTED_REGIONS, + useDateFnLocale, +} from "../platform/i18n.jsx"; +import { resolveTemplate, translator } from "@solid-primitives/i18n"; const Settings: ParentComponent = () => { + const [strings] = createStringResource( + (code) => import(`./i18n/${code}.json`), + ); + const t = translator(strings, resolveTemplate); const navigate = useNavigate(); const settings$ = useStore($settings); const { needRefresh: [needRefresh], } = useRegisterSW(); + const dateFnLocale = useDateFnLocale(); const [profiles] = useSignedInProfiles(); @@ -60,7 +78,7 @@ const Settings: ParentComponent = () => { - Settings + {t("Settings")} } @@ -68,16 +86,16 @@ const Settings: ParentComponent = () => {
    • - Accounts + {t("Accounts")} - All Notifications + {t("All Notifications")} - Sign in... + {t("Sign in...")}
    @@ -101,7 +119,7 @@ const Settings: ParentComponent = () => {
  • - Reading + {t("Reading")} Fonts @@ -114,8 +132,8 @@ const Settings: ParentComponent = () => { ) } > - - Prefetch Toots + + {t("Prefetch Toots")} @@ -124,24 +142,93 @@ const Settings: ParentComponent = () => {
  • - This Application + {t("This Application")} - - About Tutu + + + + {t("Language")} + + { + $settings.setKey( + "language", + e.currentTarget.value === "xauto" + ? undefined + : e.currentTarget.value, + ); + }} + > + + + {(code) => } + + + + + + + + + + {t("Region")} + + { + $settings.setKey( + "region", + e.currentTarget.value === "xauto" + ? undefined + : e.currentTarget.value, + ); + }} + > + + + {(code) => ( + + )} + + + + + + + + {t("About Tutu")} - {needRefresh() - ? "An update is ready, restart the Tutu to apply" - : "No updates"} + {needRefresh() ? t("updates.ready") : t("updates.no")} - window.location.reload()}> + window.location.reload()} + > diff --git a/src/settings/i18n/en.json b/src/settings/i18n/en.json new file mode 100644 index 0000000..07fb85d --- /dev/null +++ b/src/settings/i18n/en.json @@ -0,0 +1,25 @@ +{ + "Settings": "Settings", + "Accounts": "Accounts", + "All Notifications": "All Notifications", + "Sign in...": "Sign in...", + "Reading": "Reading", + "Prefetch Toots": "Prefetch Toots", + "Prefetch Toots.2nd": "Tutu will download the toots before you need.", + "This Application": "This Application", + "About Tutu": "About Tutu", + "About Tutu.2nd": "Comfortable tooting experience.", + "updates.ready": "An update is ready, restart the Tutu to apply", + "updates.no": "No updates", + "version": "Using v{{packageVersion}} (built on {{builtAt}}, {{buildMode}})", + "Language": "Language", + "Region": "Region", + "lang.auto": "Auto({{detected}})", + "lang.zh-Hans": "中文(简体)", + "lang.en": "English", + "region.auto": "Auto({{detected}})", + "region.en_GB": "Great Britan (English)", + "region.en_US": "United States (English)", + "region.zh_CN": "China Mainland (Chinese)", + "datefmt": "yyyy/MM/dd" +} \ No newline at end of file diff --git a/src/settings/i18n/zh-Hans.json b/src/settings/i18n/zh-Hans.json new file mode 100644 index 0000000..df9941e --- /dev/null +++ b/src/settings/i18n/zh-Hans.json @@ -0,0 +1,25 @@ +{ + "Settings": "设置", + "Accounts": "所有账号", + "All Notifications": "所有通知", + "Sign in...": "登录新账户...", + "Reading": "阅读", + "Prefetch Toots": "提前下载嘟文", + "Prefetch Toots.2nd": "图图会在你可能需要的时候提前下载嘟文。", + "This Application": "本应用", + "About Tutu": "关于图图", + "About Tutu.2nd": "舒服地刷嘟。", + "updates.ready": "更新已准备好,下次开启会启动新版本", + "updates.no": "已是最新版本", + "version": "正在使用 v{{packageVersion}} ({{builtAt}}构建, {{buildMode}})", + "Language": "语言", + "Region": "区域", + "lang.auto": "自动({{detected}})", + "lang.zh-Hans": "中文(简体)", + "lang.en": "English", + "region.auto": "自动({{detected}})", + "region.en_GB": "英国和苏格兰(英语)", + "region.en_US": "美国(英语)", + "region.zh_CN": "中国大陆(中文)", + "datefmt": "yyyy年MM月dd日" +} \ No newline at end of file diff --git a/src/settings/stores.ts b/src/settings/stores.ts index 25f6484..151f449 100644 --- a/src/settings/stores.ts +++ b/src/settings/stores.ts @@ -3,6 +3,8 @@ import { persistentMap } from "@nanostores/persistent"; type Settings = { onGoingOAuth2Process?: string; prefetchTootsDisabled?: boolean; + language?: string; + region?: string; }; export const $settings = persistentMap( diff --git a/src/timelines/RegularToot.tsx b/src/timelines/RegularToot.tsx index 97178c3..30376de 100644 --- a/src/timelines/RegularToot.tsx +++ b/src/timelines/RegularToot.tsx @@ -36,6 +36,7 @@ import Button from "../material/Button.js"; import MediaAttachmentGrid from "./MediaAttachmentGrid.js"; import { FastAverageColor } from "fast-average-color"; import Color from "colorjs.io"; +import { useDateFnLocale } from "../platform/i18n"; type TootContentViewProps = { source?: string; @@ -170,6 +171,7 @@ function TootActionGroup( function TootAuthorGroup(props: { status: mastodon.v1.Status; now: Date }) { const toot = () => props.status; + const dateFnLocale = useDateFnLocale() return (
    @@ -187,7 +189,7 @@ function TootAuthorGroup(props: { status: mastodon.v1.Status; now: Date }) { }} /> @{toot().account.username}@{new URL(toot().account.url).hostname} -- 2.45.2 From c49ae6fe0a1ab6039c35d4192a143fac65f65f01 Mon Sep 17 00:00:00 2001 From: thislight Date: Thu, 26 Sep 2024 19:36:46 +0800 Subject: [PATCH 2/5] createStringsResource: support merged imports --- src/platform/i18n.tsx | 25 ++++++++++++---- src/settings/Settings.tsx | 48 ++++++++++++++++++------------- src/settings/i18n/en.json | 6 ++-- src/settings/i18n/lang-names.json | 4 +++ src/settings/i18n/zh-Hans.json | 6 ++-- tsconfig.json | 1 + 6 files changed, 58 insertions(+), 32 deletions(-) create mode 100644 src/settings/i18n/lang-names.json diff --git a/src/platform/i18n.tsx b/src/platform/i18n.tsx index 7627ea1..d291677 100644 --- a/src/platform/i18n.tsx +++ b/src/platform/i18n.tsx @@ -35,7 +35,7 @@ export function autoMatchLangTag() { return match(Array.from(navigator.languages), SUPPORTED_LANGS, DEFAULT_LANG); } -const DateFnLocaleCx = createContext>(() => enGB); +const DateFnLocaleCx = /* __@PURE__ */createContext>(() => enGB); const cachedDateFnLocale: Record = { enGB, @@ -149,11 +149,20 @@ export function useLanguage() { return () => settings().language || autoMatchLangTag(); } +type ImportFn = (name: string) => Promise<{default: T}> + +type ImportedModule = F extends ImportFn ? T: never + +type MergedImportedModule = + T extends [] ? {} : + T extends [infer I] ? ImportedModule : + T extends [infer I, ...infer J] ? ImportedModule & MergedImportedModule : never + export function createStringResource< - M extends Record>, ->(importFn: (code: string) => Promise<{ default: M }>) { + T extends ImportFn | undefined>>[], +>(...importFns: T) { const language = useLanguage(); - const cache: Record = {}; + const cache: Record> = {}; return createResource( () => [language()] as const, @@ -162,9 +171,13 @@ export function createStringResource< return cache[nlang]; } - const { default: dict } = await importFn(`${nlang}`); + const results = await Promise.all(importFns.map(x => x(nlang).then(v => v.default))) - return dict; + const merged: MergedImportedModule = Object.assign({}, ...results) + + cache[nlang] = merged; + + return merged; }, ); } diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx index 65d94b9..1b9605c 100644 --- a/src/settings/Settings.tsx +++ b/src/settings/Settings.tsx @@ -17,6 +17,7 @@ import { } from "@suid/material"; import { Close as CloseIcon, + Logout, Public as PublicIcon, Refresh as RefreshIcon, Translate as TranslateIcon, @@ -38,11 +39,19 @@ import { SUPPORTED_REGIONS, useDateFnLocale, } from "../platform/i18n.jsx"; -import { resolveTemplate, translator } from "@solid-primitives/i18n"; +import { resolveTemplate, translator, type Template } from "@solid-primitives/i18n"; + +type Strings = { + ["lang.auto"]: Template<{detected: string}> +} & Record const Settings: ParentComponent = () => { const [strings] = createStringResource( - (code) => import(`./i18n/${code}.json`), + (code) => + import(`./i18n/${code}.json`) as Promise<{ + default: Strings; + }>, + () => import(`./i18n/lang-names.json`) ); const t = translator(strings, resolveTemplate); const navigate = useNavigate(); @@ -87,31 +96,34 @@ const Settings: ParentComponent = () => {
    • {t("Accounts")} - + {t("All Notifications")} - + - + - + {t("Sign in...")} - +
    {({ account: acct, inf }) => (
      {`@${inf?.username ?? "..."}@${new URL(acct.site).host}`} - - Notifications + + {t("Notifications")} - + - + - Sign out + + + + {t("Sign out")}
    @@ -120,11 +132,7 @@ const Settings: ParentComponent = () => {
  • {t("Reading")} - - Fonts - - - $settings.setKey( "prefetchTootsDisabled", @@ -138,7 +146,7 @@ const Settings: ParentComponent = () => { - +
  • @@ -162,7 +170,7 @@ const Settings: ParentComponent = () => { > @@ -191,7 +199,7 @@ const Settings: ParentComponent = () => { > diff --git a/src/settings/i18n/en.json b/src/settings/i18n/en.json index 07fb85d..1149933 100644 --- a/src/settings/i18n/en.json +++ b/src/settings/i18n/en.json @@ -15,11 +15,11 @@ "Language": "Language", "Region": "Region", "lang.auto": "Auto({{detected}})", - "lang.zh-Hans": "中文(简体)", - "lang.en": "English", "region.auto": "Auto({{detected}})", "region.en_GB": "Great Britan (English)", "region.en_US": "United States (English)", "region.zh_CN": "China Mainland (Chinese)", - "datefmt": "yyyy/MM/dd" + "datefmt": "yyyy/MM/dd", + "Sign out": "Sign out", + "Notifications": "Notifications" } \ No newline at end of file diff --git a/src/settings/i18n/lang-names.json b/src/settings/i18n/lang-names.json new file mode 100644 index 0000000..6d250bd --- /dev/null +++ b/src/settings/i18n/lang-names.json @@ -0,0 +1,4 @@ +{ + "lang.zh-Hans": "中文(简体)", + "lang.en": "English" +} \ No newline at end of file diff --git a/src/settings/i18n/zh-Hans.json b/src/settings/i18n/zh-Hans.json index df9941e..4d046df 100644 --- a/src/settings/i18n/zh-Hans.json +++ b/src/settings/i18n/zh-Hans.json @@ -15,11 +15,11 @@ "Language": "语言", "Region": "区域", "lang.auto": "自动({{detected}})", - "lang.zh-Hans": "中文(简体)", - "lang.en": "English", "region.auto": "自动({{detected}})", "region.en_GB": "英国和苏格兰(英语)", "region.en_US": "美国(英语)", "region.zh_CN": "中国大陆(中文)", - "datefmt": "yyyy年MM月dd日" + "datefmt": "yyyy年MM月dd日", + "Sign out": "登出此账户", + "Notifications": "通知" } \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index ccd018b..6cc68b0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,5 +11,6 @@ "types": ["vite/client", "vite-plugin-pwa/solid"], "noEmit": true, "isolatedModules": true, + "resolveJsonModule": true, } } -- 2.45.2 From 55705b0a6db045712d34ff8e1231d4bf59f393cf Mon Sep 17 00:00:00 2001 From: thislight Date: Thu, 26 Sep 2024 19:42:44 +0800 Subject: [PATCH 3/5] i18n: add createTranslator --- src/platform/i18n.tsx | 9 +++++++-- src/settings/Settings.tsx | 9 ++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/platform/i18n.tsx b/src/platform/i18n.tsx index d291677..a43a574 100644 --- a/src/platform/i18n.tsx +++ b/src/platform/i18n.tsx @@ -2,7 +2,6 @@ import { ParentComponent, createContext, createMemo, - createRenderEffect, createResource, useContext, } from "solid-js"; @@ -12,7 +11,7 @@ import { $settings } from "../settings/stores"; import { enGB } from "date-fns/locale/en-GB"; import { useStore } from "@nanostores/solid"; import type { Locale } from "date-fns"; -import type { Template } from "@solid-primitives/i18n"; +import { resolveTemplate, translator, type Template } from "@solid-primitives/i18n"; async function synchronised( name: string, @@ -181,3 +180,9 @@ export function createStringResource< }, ); } + +export function createTranslator | undefined>>[],>(...importFns: T) { + const res = createStringResource(...importFns) + + return [translator(res[0], resolveTemplate), res] as const +} diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx index 1b9605c..bc35b7d 100644 --- a/src/settings/Settings.tsx +++ b/src/settings/Settings.tsx @@ -27,33 +27,32 @@ import { Title } from "../material/typography.jsx"; import { css } from "solid-styled"; import { useSignedInProfiles } from "../masto/acct.js"; import { signOut, type Account } from "../accounts/stores.js"; -import { format, intlFormat } from "date-fns"; +import { format } from "date-fns"; import { useStore } from "@nanostores/solid"; import { $settings } from "./stores.js"; import { useRegisterSW } from "virtual:pwa-register/solid"; import { autoMatchLangTag, autoMatchRegion, - createStringResource, + createTranslator, SUPPORTED_LANGS, SUPPORTED_REGIONS, useDateFnLocale, } from "../platform/i18n.jsx"; -import { resolveTemplate, translator, type Template } from "@solid-primitives/i18n"; +import { type Template } from "@solid-primitives/i18n"; type Strings = { ["lang.auto"]: Template<{detected: string}> } & Record const Settings: ParentComponent = () => { - const [strings] = createStringResource( + const [t] = createTranslator( (code) => import(`./i18n/${code}.json`) as Promise<{ default: Strings; }>, () => import(`./i18n/lang-names.json`) ); - const t = translator(strings, resolveTemplate); const navigate = useNavigate(); const settings$ = useStore($settings); const { -- 2.45.2 From e56dc4bf7bd8a65f3130c2f75d0d1b69d41563e5 Mon Sep 17 00:00:00 2001 From: thislight Date: Fri, 27 Sep 2024 14:15:34 +0800 Subject: [PATCH 4/5] Settings: added lang and region picker dialog --- bun.lockb | Bin 239741 -> 240104 bytes package.json | 1 + src/masto/acct.ts | 13 ++-- src/platform/i18n.tsx | 4 +- src/settings/ChooseLang.tsx | 117 +++++++++++++++++++++++++++++++++ src/settings/ChooseRegion.tsx | 110 +++++++++++++++++++++++++++++++ src/settings/Settings.tsx | 113 +++++++++++++++---------------- src/settings/i18n/en.json | 11 +++- src/settings/i18n/zh-Hans.json | 13 ++-- src/timelines/Home.tsx | 9 ++- 10 files changed, 316 insertions(+), 75 deletions(-) create mode 100644 src/settings/ChooseLang.tsx create mode 100644 src/settings/ChooseRegion.tsx diff --git a/bun.lockb b/bun.lockb index 8230f5ff44fe878835dc364611480f661f380f35..25e9097232174094867a4c68f2617eb664c3fb9d 100755 GIT binary patch delta 41211 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 { - const value = accessor(); - if (!value) { - return sessions().map((x) => ({ ...x, inf: x.account.inf })); + try { + const value = accessor(); + if (value) { + return value; + } + } catch (reason) { + console.error("useSignedInProfiles: update acct info failed", reason); } - return value; + + return sessions().map((x) => ({ ...x, inf: x.account.inf })); }, tools, ] as const; diff --git a/src/platform/i18n.tsx b/src/platform/i18n.tsx index a43a574..b31d888 100644 --- a/src/platform/i18n.tsx +++ b/src/platform/i18n.tsx @@ -20,9 +20,9 @@ async function synchronised( await navigator.locks.request(name, callback); } -export const SUPPORTED_LANGS = ["en", "zh-Hans"]; +export const SUPPORTED_LANGS = ["en", "zh-Hans"] as const; -export const SUPPORTED_REGIONS = ["en_US", "en_GB", "zh_CN"]; +export const SUPPORTED_REGIONS = ["en_US", "en_GB", "zh_CN"] as const; const DEFAULT_LANG = "en"; diff --git a/src/settings/ChooseLang.tsx b/src/settings/ChooseLang.tsx new file mode 100644 index 0000000..96a8db9 --- /dev/null +++ b/src/settings/ChooseLang.tsx @@ -0,0 +1,117 @@ +import { createMemo, For, type Component, type JSX } from "solid-js"; +import Scaffold from "../material/Scaffold"; +import { + AppBar, + Checkbox, + IconButton, + List, + ListItem, + ListItemButton, + ListItemSecondaryAction, + ListItemText, + ListSubheader, + Radio, + Switch, + Toolbar, +} from "@suid/material"; +import { Close as CloseIcon } from "@suid/icons-material"; +import iso639_1 from "iso-639-1"; +import { + autoMatchLangTag, + createTranslator, + SUPPORTED_LANGS, +} from "../platform/i18n"; +import { Title } from "../material/typography"; +import type { Template } from "@solid-primitives/i18n"; + +type ChooseLangProps = { + code?: string; + onCodeChange: (ncode?: string) => void; + onClose?: JSX.EventHandlerUnion; +}; + +const ChooseLang: Component = (props) => { + const [t] = createTranslator( + () => import("./i18n/lang-names.json"), + (code) => + import(`./i18n/${code}.json`) as Promise<{ + default: Record & { + ["lang.auto"]: Template<{ detected: string }>; + }; + }>, + ); + + const unsupportedLangCodes = createMemo(() => { + return iso639_1.getAllCodes().filter((x) => !["zh", "en"].includes(x)); + }); + + const matchedLangCode = createMemo(() => autoMatchLangTag()); + + return ( + + + + + + {t("Choose Language")} + + + } + > + + { + props.onCodeChange(props.code ? undefined : matchedLangCode()); + }} + > + + {t("lang.auto", { + detected: t(`lang.${matchedLangCode()}`) ?? matchedLangCode(), + })} + + + + + + {t("Supported")}}> + + {(code) => ( + + {t(`lang.${code}`)} + + + + + )} + + + + {t("Unsupported")}}> + + {(code) => ( + + {iso639_1.getNativeName(code)} + + )} + + + + + ); +}; + +export default ChooseLang; diff --git a/src/settings/ChooseRegion.tsx b/src/settings/ChooseRegion.tsx new file mode 100644 index 0000000..53302d8 --- /dev/null +++ b/src/settings/ChooseRegion.tsx @@ -0,0 +1,110 @@ +import { createMemo, For, type Component, type JSX } from "solid-js"; +import Scaffold from "../material/Scaffold"; +import { + AppBar, + Checkbox, + IconButton, + List, + ListItem, + ListItemButton, + ListItemSecondaryAction, + ListItemText, + ListSubheader, + Radio, + Switch, + Toolbar, +} from "@suid/material"; +import { Close as CloseIcon } from "@suid/icons-material"; +import iso639_1 from "iso-639-1"; +import { + autoMatchLangTag, + autoMatchRegion, + createTranslator, + SUPPORTED_LANGS, + SUPPORTED_REGIONS, +} from "../platform/i18n"; +import { Title } from "../material/typography"; +import type { Template } from "@solid-primitives/i18n"; + +type ChooseRegionProps = { + code?: string; + onCodeChange: (ncode?: string) => void; + onClose?: JSX.EventHandlerUnion; +}; + +const ChooseRegion: Component = (props) => { + const [t] = createTranslator( + () => import("./i18n/lang-names.json"), + (code) => + import(`./i18n/${code}.json`) as Promise<{ + default: Record & { + ["lang.auto"]: Template<{ detected: string }>; + }; + }>, + ); + + const unsupportedLangCodes = createMemo(() => { + return iso639_1.getAllCodes().filter((x) => !["zh", "en"].includes(x)); + }); + + const matchedRegionCode = createMemo(() => autoMatchRegion()); + + return ( + + + + + + {t("Choose Language")} + + + } + > + + { + props.onCodeChange(props.code ? undefined : matchedRegionCode()); + }} + > + + {t("region.auto", { + detected: t(`region.${matchedRegionCode()}`) ?? matchedRegionCode(), + })} + + + + + + + {t("Supported")}}> + + {(code) => ( + + {t(`region.${code}`)} + + + + + )} + + + + + ); +}; + +export default ChooseRegion; diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx index bc35b7d..ad9f66b 100644 --- a/src/settings/Settings.tsx +++ b/src/settings/Settings.tsx @@ -1,4 +1,4 @@ -import { For, Show, type ParentComponent } from "solid-js"; +import { createSignal, For, Show, type ParentComponent } from "solid-js"; import Scaffold from "../material/Scaffold.js"; import { AppBar, @@ -40,10 +40,13 @@ import { 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"; type Strings = { - ["lang.auto"]: Template<{detected: string}> -} & Record + ["lang.auto"]: Template<{ detected: string }>; +} & Record; const Settings: ParentComponent = () => { const [t] = createTranslator( @@ -51,7 +54,7 @@ const Settings: ParentComponent = () => { import(`./i18n/${code}.json`) as Promise<{ default: Strings; }>, - () => import(`./i18n/lang-names.json`) + () => import(`./i18n/lang-names.json`), ); const navigate = useNavigate(); const settings$ = useStore($settings); @@ -59,6 +62,8 @@ const Settings: ParentComponent = () => { needRefresh: [needRefresh], } = useRegisterSW(); const dateFnLocale = useDateFnLocale(); + const [langPickerOpen, setLangPickerOpen] = createSignal(false); + const [regionPickerOpen, setRegionPickerOpen] = createSignal(false); const [profiles] = useSignedInProfiles(); @@ -98,7 +103,7 @@ const Settings: ParentComponent = () => { {t("All Notifications")} - + @@ -114,13 +119,13 @@ const Settings: ParentComponent = () => { {t("Notifications")} - + - + {t("Sign out")} @@ -150,65 +155,55 @@ const Settings: ParentComponent = () => {
  • {t("This Application")} - + - {t("Language")} - - { - $settings.setKey( - "language", - e.currentTarget.value === "xauto" - ? undefined - : e.currentTarget.value, - ); - }} - > - - - {(code) => } - - - - + + {t("Language")} + + + + $settings.setKey("language", nval)} + onClose={[setLangPickerOpen, false]} + /> + - + - {t("Region")} - - { - $settings.setKey( - "region", - e.currentTarget.value === "xauto" - ? undefined - : e.currentTarget.value, - ); - }} - > - - - {(code) => ( - - )} - - - - + + {t("Region")} + + + + $settings.setKey("region", nval)} + onClose={[setRegionPickerOpen, false]} + /> + diff --git a/src/settings/i18n/en.json b/src/settings/i18n/en.json index 1149933..095bc04 100644 --- a/src/settings/i18n/en.json +++ b/src/settings/i18n/en.json @@ -14,12 +14,17 @@ "version": "Using v{{packageVersion}} (built on {{builtAt}}, {{buildMode}})", "Language": "Language", "Region": "Region", - "lang.auto": "Auto({{detected}})", - "region.auto": "Auto({{detected}})", + "lang.auto": "(Auto) {{detected}}", + "region.auto": "(Auto) {{detected}}", "region.en_GB": "Great Britan (English)", "region.en_US": "United States (English)", "region.zh_CN": "China Mainland (Chinese)", "datefmt": "yyyy/MM/dd", "Sign out": "Sign out", - "Notifications": "Notifications" + "Notifications": "Notifications", + + "Choose Language": "Choose Language", + "Supported": "Supported", + "Unsupported": "Unsupported", + "Choose Region": "Choose Region" } \ No newline at end of file diff --git a/src/settings/i18n/zh-Hans.json b/src/settings/i18n/zh-Hans.json index 4d046df..8fd70d1 100644 --- a/src/settings/i18n/zh-Hans.json +++ b/src/settings/i18n/zh-Hans.json @@ -1,6 +1,6 @@ { "Settings": "设置", - "Accounts": "所有账号", + "Accounts": "所有账户", "All Notifications": "所有通知", "Sign in...": "登录新账户...", "Reading": "阅读", @@ -14,12 +14,17 @@ "version": "正在使用 v{{packageVersion}} ({{builtAt}}构建, {{buildMode}})", "Language": "语言", "Region": "区域", - "lang.auto": "自动({{detected}})", - "region.auto": "自动({{detected}})", + "lang.auto": "(自动){{detected}}", + "region.auto": "(自动){{detected}}", "region.en_GB": "英国和苏格兰(英语)", "region.en_US": "美国(英语)", "region.zh_CN": "中国大陆(中文)", "datefmt": "yyyy年MM月dd日", "Sign out": "登出此账户", - "Notifications": "通知" + "Notifications": "通知", + + "Choose Language": "选择语言", + "Supported": "已支持", + "Unsupported": "尚未支持", + "Choose Region": "选择区域" } \ No newline at end of file diff --git a/src/timelines/Home.tsx b/src/timelines/Home.tsx index c09023d..b83de4d 100644 --- a/src/timelines/Home.tsx +++ b/src/timelines/Home.tsx @@ -10,7 +10,8 @@ import { children, Suspense, Match, - Switch as JsSwitch + Switch as JsSwitch, + ErrorBoundary } from "solid-js"; import { useDocumentTitle } from "../utils"; import { type mastodon } from "masto"; @@ -125,7 +126,9 @@ const TimelinePanel: Component<{ }; return ( - <> + { + return

    Oops: {String(err)}

    + }}> - +
    ); }; -- 2.45.2 From e6a14a8a2603abee7628d442c8564705a8e8ef73 Mon Sep 17 00:00:00 2001 From: thislight Date: Fri, 27 Sep 2024 14:18:21 +0800 Subject: [PATCH 5/5] clean up unused imports --- src/settings/ChooseLang.tsx | 1 - src/settings/ChooseRegion.tsx | 4 ---- 2 files changed, 5 deletions(-) diff --git a/src/settings/ChooseLang.tsx b/src/settings/ChooseLang.tsx index 96a8db9..ac03c7b 100644 --- a/src/settings/ChooseLang.tsx +++ b/src/settings/ChooseLang.tsx @@ -2,7 +2,6 @@ import { createMemo, For, type Component, type JSX } from "solid-js"; import Scaffold from "../material/Scaffold"; import { AppBar, - Checkbox, IconButton, List, ListItem, diff --git a/src/settings/ChooseRegion.tsx b/src/settings/ChooseRegion.tsx index 53302d8..77a969e 100644 --- a/src/settings/ChooseRegion.tsx +++ b/src/settings/ChooseRegion.tsx @@ -2,10 +2,8 @@ import { createMemo, For, type Component, type JSX } from "solid-js"; import Scaffold from "../material/Scaffold"; import { AppBar, - Checkbox, IconButton, List, - ListItem, ListItemButton, ListItemSecondaryAction, ListItemText, @@ -17,10 +15,8 @@ import { import { Close as CloseIcon } from "@suid/icons-material"; import iso639_1 from "iso-639-1"; import { - autoMatchLangTag, autoMatchRegion, createTranslator, - SUPPORTED_LANGS, SUPPORTED_REGIONS, } from "../platform/i18n"; import { Title } from "../material/typography"; -- 2.45.2