117 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			117 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| 
								 | 
							
								import { createMemo, For, type Component, type JSX } from "solid-js";
							 | 
						||
| 
								 | 
							
								import Scaffold from "../material/Scaffold";
							 | 
						||
| 
								 | 
							
								import {
							 | 
						||
| 
								 | 
							
								  AppBar,
							 | 
						||
| 
								 | 
							
								  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<HTMLButtonElement, MouseEvent>;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const ChooseLang: Component<ChooseLangProps> = (props) => {
							 | 
						||
| 
								 | 
							
								  const [t] = createTranslator(
							 | 
						||
| 
								 | 
							
								    () => import("./i18n/lang-names.json"),
							 | 
						||
| 
								 | 
							
								    (code) =>
							 | 
						||
| 
								 | 
							
								      import(`./i18n/${code}.json`) as Promise<{
							 | 
						||
| 
								 | 
							
								        default: Record<string, string | undefined> & {
							 | 
						||
| 
								 | 
							
								          ["lang.auto"]: Template<{ detected: string }>;
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								      }>,
							 | 
						||
| 
								 | 
							
								  );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const unsupportedLangCodes = createMemo(() => {
							 | 
						||
| 
								 | 
							
								    return iso639_1.getAllCodes().filter((x) => !["zh", "en"].includes(x));
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const matchedLangCode = createMemo(() => autoMatchLangTag());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return (
							 | 
						||
| 
								 | 
							
								    <Scaffold
							 | 
						||
| 
								 | 
							
								      topbar={
							 | 
						||
| 
								 | 
							
								        <AppBar position="static">
							 | 
						||
| 
								 | 
							
								          <Toolbar
							 | 
						||
| 
								 | 
							
								            variant="dense"
							 | 
						||
| 
								 | 
							
								            sx={{ paddingTop: "var(--safe-area-inset-top, 0px)" }}
							 | 
						||
| 
								 | 
							
								          >
							 | 
						||
| 
								 | 
							
								            <IconButton color="inherit" onClick={props.onClose} disableRipple>
							 | 
						||
| 
								 | 
							
								              <CloseIcon />
							 | 
						||
| 
								 | 
							
								            </IconButton>
							 | 
						||
| 
								 | 
							
								            <Title>{t("Choose Language")}</Title>
							 | 
						||
| 
								 | 
							
								          </Toolbar>
							 | 
						||
| 
								 | 
							
								        </AppBar>
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    >
							 | 
						||
| 
								 | 
							
								      <List
							 | 
						||
| 
								 | 
							
								        sx={{
							 | 
						||
| 
								 | 
							
								          paddingBottom: "var(--safe-area-inset-bottom, 0)",
							 | 
						||
| 
								 | 
							
								        }}
							 | 
						||
| 
								 | 
							
								      >
							 | 
						||
| 
								 | 
							
								        <ListItemButton
							 | 
						||
| 
								 | 
							
								          onClick={() => {
							 | 
						||
| 
								 | 
							
								            props.onCodeChange(props.code ? undefined : matchedLangCode());
							 | 
						||
| 
								 | 
							
								          }}
							 | 
						||
| 
								 | 
							
								        >
							 | 
						||
| 
								 | 
							
								          <ListItemText>
							 | 
						||
| 
								 | 
							
								            {t("lang.auto", {
							 | 
						||
| 
								 | 
							
								              detected: t(`lang.${matchedLangCode()}`) ?? matchedLangCode(),
							 | 
						||
| 
								 | 
							
								            })}
							 | 
						||
| 
								 | 
							
								          </ListItemText>
							 | 
						||
| 
								 | 
							
								          <ListItemSecondaryAction>
							 | 
						||
| 
								 | 
							
								            <Switch checked={typeof props.code === "undefined"} />
							 | 
						||
| 
								 | 
							
								          </ListItemSecondaryAction>
							 | 
						||
| 
								 | 
							
								        </ListItemButton>
							 | 
						||
| 
								 | 
							
								        <List subheader={<ListSubheader>{t("Supported")}</ListSubheader>}>
							 | 
						||
| 
								 | 
							
								          <For each={SUPPORTED_LANGS}>
							 | 
						||
| 
								 | 
							
								            {(code) => (
							 | 
						||
| 
								 | 
							
								              <ListItemButton
							 | 
						||
| 
								 | 
							
								                disabled={typeof props.code === "undefined"}
							 | 
						||
| 
								 | 
							
								                onClick={[props.onCodeChange, code]}
							 | 
						||
| 
								 | 
							
								              >
							 | 
						||
| 
								 | 
							
								                <ListItemText>{t(`lang.${code}`)}</ListItemText>
							 | 
						||
| 
								 | 
							
								                <ListItemSecondaryAction>
							 | 
						||
| 
								 | 
							
								                  <Radio
							 | 
						||
| 
								 | 
							
								                    checked={props.code === code || (props.code === undefined && matchedLangCode() == code)}
							 | 
						||
| 
								 | 
							
								                  />
							 | 
						||
| 
								 | 
							
								                </ListItemSecondaryAction>
							 | 
						||
| 
								 | 
							
								              </ListItemButton>
							 | 
						||
| 
								 | 
							
								            )}
							 | 
						||
| 
								 | 
							
								          </For>
							 | 
						||
| 
								 | 
							
								        </List>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        <List subheader={<ListSubheader>{t("Unsupported")}</ListSubheader>}>
							 | 
						||
| 
								 | 
							
								          <For each={unsupportedLangCodes()}>
							 | 
						||
| 
								 | 
							
								            {(code) => (
							 | 
						||
| 
								 | 
							
								              <ListItem>
							 | 
						||
| 
								 | 
							
								                <ListItemText>{iso639_1.getNativeName(code)}</ListItemText>
							 | 
						||
| 
								 | 
							
								              </ListItem>
							 | 
						||
| 
								 | 
							
								            )}
							 | 
						||
| 
								 | 
							
								          </For>
							 | 
						||
| 
								 | 
							
								        </List>
							 | 
						||
| 
								 | 
							
								      </List>
							 | 
						||
| 
								 | 
							
								    </Scaffold>
							 | 
						||
| 
								 | 
							
								  );
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export default ChooseLang;
							 |