first prototype of i18n system
This commit is contained in:
		
							parent
							
								
									70de83a24a
								
							
						
					
					
						commit
						4f8b31ca31
					
				
					 9 changed files with 348 additions and 20 deletions
				
			
		| 
						 | 
				
			
			@ -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 = () => {
 | 
			
		|||
            <IconButton color="inherit" onClick={[navigate, -1]} disableRipple>
 | 
			
		||||
              <CloseIcon />
 | 
			
		||||
            </IconButton>
 | 
			
		||||
            <Title>Settings</Title>
 | 
			
		||||
            <Title>{t("Settings")}</Title>
 | 
			
		||||
          </Toolbar>
 | 
			
		||||
        </AppBar>
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -68,16 +86,16 @@ const Settings: ParentComponent = () => {
 | 
			
		|||
      <List class="setting-list" use:solid-styled>
 | 
			
		||||
        <li>
 | 
			
		||||
          <ul>
 | 
			
		||||
            <ListSubheader>Accounts</ListSubheader>
 | 
			
		||||
            <ListSubheader>{t("Accounts")}</ListSubheader>
 | 
			
		||||
            <ListItem>
 | 
			
		||||
              <ListItemText>All Notifications</ListItemText>
 | 
			
		||||
              <ListItemText>{t("All Notifications")}</ListItemText>
 | 
			
		||||
              <ListItemSecondaryAction>
 | 
			
		||||
                <Switch value={false} />
 | 
			
		||||
              </ListItemSecondaryAction>
 | 
			
		||||
            </ListItem>
 | 
			
		||||
            <Divider />
 | 
			
		||||
            <ListItem>
 | 
			
		||||
              <ListItemText>Sign in...</ListItemText>
 | 
			
		||||
              <ListItemText>{t("Sign in...")}</ListItemText>
 | 
			
		||||
            </ListItem>
 | 
			
		||||
            <Divider />
 | 
			
		||||
          </ul>
 | 
			
		||||
| 
						 | 
				
			
			@ -101,7 +119,7 @@ const Settings: ParentComponent = () => {
 | 
			
		|||
          </For>
 | 
			
		||||
        </li>
 | 
			
		||||
        <li>
 | 
			
		||||
          <ListSubheader>Reading</ListSubheader>
 | 
			
		||||
          <ListSubheader>{t("Reading")}</ListSubheader>
 | 
			
		||||
          <ListItem>
 | 
			
		||||
            <ListItemText secondary="Regular">Fonts</ListItemText>
 | 
			
		||||
          </ListItem>
 | 
			
		||||
| 
						 | 
				
			
			@ -114,8 +132,8 @@ const Settings: ParentComponent = () => {
 | 
			
		|||
              )
 | 
			
		||||
            }
 | 
			
		||||
          >
 | 
			
		||||
            <ListItemText secondary="Tutu will download toots before you scroll to the position.">
 | 
			
		||||
              Prefetch Toots
 | 
			
		||||
            <ListItemText secondary={t("Prefetch Toots.2nd")}>
 | 
			
		||||
              {t("Prefetch Toots")}
 | 
			
		||||
            </ListItemText>
 | 
			
		||||
            <ListItemSecondaryAction>
 | 
			
		||||
              <Switch checked={!settings$().prefetchTootsDisabled} />
 | 
			
		||||
| 
						 | 
				
			
			@ -124,24 +142,93 @@ const Settings: ParentComponent = () => {
 | 
			
		|||
          <Divider />
 | 
			
		||||
        </li>
 | 
			
		||||
        <li>
 | 
			
		||||
          <ListSubheader>This Application</ListSubheader>
 | 
			
		||||
          <ListSubheader>{t("This Application")}</ListSubheader>
 | 
			
		||||
          <ListItem>
 | 
			
		||||
            <ListItemText secondary="Comformtable tooting experience.">
 | 
			
		||||
              About Tutu
 | 
			
		||||
            <ListItemIcon>
 | 
			
		||||
              <TranslateIcon />
 | 
			
		||||
            </ListItemIcon>
 | 
			
		||||
            <ListItemText>{t("Language")}</ListItemText>
 | 
			
		||||
            <ListItemSecondaryAction>
 | 
			
		||||
              <NativeSelect
 | 
			
		||||
                value={settings$().language || "xauto"}
 | 
			
		||||
                onChange={(e) => {
 | 
			
		||||
                  $settings.setKey(
 | 
			
		||||
                    "language",
 | 
			
		||||
                    e.currentTarget.value === "xauto"
 | 
			
		||||
                      ? undefined
 | 
			
		||||
                      : e.currentTarget.value,
 | 
			
		||||
                  );
 | 
			
		||||
                }}
 | 
			
		||||
              >
 | 
			
		||||
                <option value={"xauto"}>
 | 
			
		||||
                  {t("lang.auto", {
 | 
			
		||||
                    detected: t("lang." + autoMatchLangTag()),
 | 
			
		||||
                  })}
 | 
			
		||||
                </option>
 | 
			
		||||
                <For each={SUPPORTED_LANGS}>
 | 
			
		||||
                  {(code) => <option value={code}>{t("lang." + code)}</option>}
 | 
			
		||||
                </For>
 | 
			
		||||
              </NativeSelect>
 | 
			
		||||
            </ListItemSecondaryAction>
 | 
			
		||||
          </ListItem>
 | 
			
		||||
          <Divider />
 | 
			
		||||
          <ListItem>
 | 
			
		||||
            <ListItemIcon>
 | 
			
		||||
              <PublicIcon />
 | 
			
		||||
            </ListItemIcon>
 | 
			
		||||
            <ListItemText>{t("Region")}</ListItemText>
 | 
			
		||||
            <ListItemSecondaryAction>
 | 
			
		||||
              <NativeSelect
 | 
			
		||||
                value={settings$().region}
 | 
			
		||||
                onChange={(e) => {
 | 
			
		||||
                  $settings.setKey(
 | 
			
		||||
                    "region",
 | 
			
		||||
                    e.currentTarget.value === "xauto"
 | 
			
		||||
                      ? undefined
 | 
			
		||||
                      : e.currentTarget.value,
 | 
			
		||||
                  );
 | 
			
		||||
                }}
 | 
			
		||||
              >
 | 
			
		||||
                <option value={"xauto"}>
 | 
			
		||||
                  {t("region.auto", {
 | 
			
		||||
                    detected: t("region." + autoMatchRegion()),
 | 
			
		||||
                  })}
 | 
			
		||||
                </option>
 | 
			
		||||
                <For each={SUPPORTED_REGIONS}>
 | 
			
		||||
                  {(code) => (
 | 
			
		||||
                    <option value={code}>{t("region." + code)}</option>
 | 
			
		||||
                  )}
 | 
			
		||||
                </For>
 | 
			
		||||
              </NativeSelect>
 | 
			
		||||
            </ListItemSecondaryAction>
 | 
			
		||||
          </ListItem>
 | 
			
		||||
          <Divider />
 | 
			
		||||
          <ListItem>
 | 
			
		||||
            <ListItemText secondary={t("About Tutu.2nd")}>
 | 
			
		||||
              {t("About Tutu")}
 | 
			
		||||
            </ListItemText>
 | 
			
		||||
          </ListItem>
 | 
			
		||||
          <Divider />
 | 
			
		||||
          <ListItem>
 | 
			
		||||
            <ListItemText
 | 
			
		||||
              secondary={`Using v${import.meta.env.PACKAGE_VERSION} (built on ${intlFormat(import.meta.env.BUILT_AT)}, ${import.meta.env.MODE})`}
 | 
			
		||||
              secondary={t("version", {
 | 
			
		||||
                packageVersion: import.meta.env.PACKAGE_VERSION,
 | 
			
		||||
                builtAt: format(
 | 
			
		||||
                  import.meta.env.BUILT_AT,
 | 
			
		||||
                  t("datefmt") || "yyyy/MM/dd",
 | 
			
		||||
                  { locale: dateFnLocale() },
 | 
			
		||||
                ),
 | 
			
		||||
                buildMode: import.meta.env.MODE,
 | 
			
		||||
              })}
 | 
			
		||||
            >
 | 
			
		||||
              {needRefresh()
 | 
			
		||||
                ? "An update is ready, restart the Tutu to apply"
 | 
			
		||||
                : "No updates"}
 | 
			
		||||
              {needRefresh() ? t("updates.ready") : t("updates.no")}
 | 
			
		||||
            </ListItemText>
 | 
			
		||||
            <Show when={needRefresh()}>
 | 
			
		||||
              <ListItemSecondaryAction>
 | 
			
		||||
                <IconButton aria-label="Restart Now" onClick={() => window.location.reload()}>
 | 
			
		||||
                <IconButton
 | 
			
		||||
                  aria-label="Restart Now"
 | 
			
		||||
                  onClick={() => window.location.reload()}
 | 
			
		||||
                >
 | 
			
		||||
                  <RefreshIcon />
 | 
			
		||||
                </IconButton>
 | 
			
		||||
              </ListItemSecondaryAction>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										25
									
								
								src/settings/i18n/en.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/settings/i18n/en.json
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								src/settings/i18n/zh-Hans.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/settings/i18n/zh-Hans.json
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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日"
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -3,6 +3,8 @@ import { persistentMap } from "@nanostores/persistent";
 | 
			
		|||
type Settings = {
 | 
			
		||||
  onGoingOAuth2Process?: string;
 | 
			
		||||
  prefetchTootsDisabled?: boolean;
 | 
			
		||||
  language?: string;
 | 
			
		||||
  region?: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const $settings = persistentMap<Settings>(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue