UNPKG

lrc-maker

Version:

歌词滚动姬|可能是你所能见到的最好用的歌词制作工具

230 lines 13.6 kB
import { info, themeColor } from "../hooks/usePref.js"; import { convertTimeToTag, formatText } from "../lrc-parser.js"; import { unregister } from "../utils/sw.unregister.js"; import { appContext } from "./app.context.js"; import { AkariHideWall } from "./svg.img.js"; const { useCallback, useContext, useEffect, useMemo, useRef } = React; const numberInputProps = { type: "number", step: 1 }; const useNumberInput = (defaultValue, onChange) => { const ref = useRef(null); useEffect(() => { const target = ref.current; if (target) { const onChange = () => { target.value = defaultValue.toString(); }; target.addEventListener("change", onChange); return () => target.removeEventListener("change", onChange); } }, [defaultValue]); const $onChange = useCallback((ev) => { if (ev.target.validity.valid) { onChange(ev); } }, [onChange]); return Object.assign(Object.assign({}, numberInputProps), { ref, onChange: $onChange, defaultValue }); }; export const Preferences = () => { const { prefState, prefDispatch, lang } = useContext(appContext, 1 || 4); const onColorPick = useCallback((ev) => { prefDispatch({ type: "themeColor", payload: ev.target.value, }); }, [prefDispatch]); const userColorInputText = useRef(null); const onUserInput = useCallback((input) => { let value = input.value; if (!input.validity.valid) { input.value = input.defaultValue; return; } if (value.length === 3) { value = [].map.call(value, (v) => v + v).join(""); } if (value.length < 6) { value = value.padEnd(6, "0"); } prefDispatch({ type: "themeColor", payload: "#" + value, }); }, [prefDispatch]); const onUserColorInputBlur = useCallback((ev) => onUserInput(ev.target), [onUserInput]); const onColorSubmit = useCallback((ev) => { ev.preventDefault(); const form = ev.target; const input = form.elements.namedItem("user-color-input-text"); return onUserInput(input); }, [onUserInput]); useEffect(() => { userColorInputText.current.value = prefState.themeColor.slice(1); }, [prefState.themeColor]); const onSpaceChange = useCallback((ev) => { prefDispatch({ type: ev.target.name, payload: ev.target.value, }); }, [prefDispatch]); const onCacheClear = useCallback(() => { unregister(); }, []); const updateTime = useMemo(() => { const date = new Date("2022-10-22T10:52:25+08:00"); const options = { year: "numeric", month: "short", day: "numeric", hour: "numeric", minute: "numeric", second: "numeric", timeZoneName: "short", hour12: false, }; return new Intl.DateTimeFormat(prefState.lang, options).format(date); }, [prefState.lang]); const onLangChanged = useCallback((ev) => { prefDispatch({ type: "lang", payload: ev.target.value, }); }, [prefDispatch]); const onBuiltInAudioToggle = useCallback(() => prefDispatch({ type: "builtInAudio", payload: (prefState) => !prefState.builtInAudio, }), [prefDispatch]); const onScreenButtonToggle = useCallback(() => prefDispatch({ type: "screenButton", payload: (prefState) => !prefState.screenButton, }), [prefDispatch]); const onThemeModeChange = useCallback((ev) => { prefDispatch({ type: "themeMode", payload: Number.parseInt(ev.target.value, 10), }); }, [prefDispatch]); const onFixedChanged = useCallback((ev) => { prefDispatch({ type: "fixed", payload: Number.parseInt(ev.target.value, 10), }); }, [prefDispatch]); const LangOptionList = useMemo(() => { return Object.entries(info.languages).map(([langCode, langName]) => { return (React.createElement("option", { key: langCode, value: langCode }, langName)); }); }, []); const ColorPickerWall = useMemo(() => { return Object.values(themeColor).map((color) => { const checked = color === prefState.themeColor; const classNames = ["color-picker", "ripple"]; if (checked) { classNames.push("checked"); } return (React.createElement("label", { className: classNames.join(" "), key: color, style: { backgroundColor: color } }, React.createElement("input", { hidden: true, type: "radio", name: "theme-color", value: color, checked: checked, onChange: onColorPick }))); }); }, [onColorPick, prefState.themeColor]); const currentThemeColorStyle = useMemo(() => { return { backgroundColor: prefState.themeColor, }; }, [prefState.themeColor]); const formatedText = useMemo(() => { return formatText(" hello 世界~ ", prefState.spaceStart, prefState.spaceEnd); }, [prefState.spaceStart, prefState.spaceEnd]); const userColorLabel = useRef(null); const userColorInput = useRef(null); useEffect(() => { if (userColorInput.current.type === "color") { userColorLabel.current.removeAttribute("for"); } }, []); return (React.createElement("div", { className: "preferences" }, React.createElement("ul", null, React.createElement("li", null, React.createElement("section", { className: "list-item" }, React.createElement("span", null, lang.preferences.version), React.createElement("span", { className: "select-all" }, "5.6.6"))), React.createElement("li", null, React.createElement("section", { className: "list-item" }, React.createElement("span", null, lang.preferences.commitHash), React.createElement("span", { className: "select-all" }, "26783c9"))), React.createElement("li", null, React.createElement("section", { className: "list-item" }, React.createElement("span", null, lang.preferences.updateTime), React.createElement("span", null, updateTime))), React.createElement("li", null, React.createElement("section", { className: "list-item" }, React.createElement("span", null, lang.preferences.repo), React.createElement("a", { className: "link", href: "https://github.com/magic-akari/lrc-maker", target: "_blank", rel: "noopener noreferrer" }, "Github"))), React.createElement("li", null, React.createElement("section", { className: "list-item" }, React.createElement("span", null, lang.preferences.help), React.createElement("a", { className: "link", href: "https://github.com/magic-akari/lrc-maker/wiki", target: "_blank", rel: "noopener noreferrer" }, "Github Wiki"))), React.createElement("li", null, React.createElement("section", { className: "list-item" }, React.createElement("span", null, lang.preferences.language), React.createElement("div", { className: "option-select" }, React.createElement("select", { value: prefState.lang, onChange: onLangChanged, "aria-label": lang.preferences.language }, LangOptionList)))), React.createElement("li", null, React.createElement("label", { className: "list-item" }, React.createElement("span", null, lang.preferences.builtInAudio), React.createElement("label", { className: "toggle-switch" }, React.createElement("input", { type: "checkbox", checked: prefState.builtInAudio, onChange: onBuiltInAudioToggle, "aria-label": lang.preferences.builtInAudio }), React.createElement("span", { className: "toggle-switch-label" })))), React.createElement("li", null, React.createElement("label", { className: "list-item" }, React.createElement("span", null, lang.preferences.spaceButton), React.createElement("label", { className: "toggle-switch" }, React.createElement("input", { type: "checkbox", checked: prefState.screenButton, onChange: onScreenButtonToggle, "aria-label": lang.preferences.spaceButton }), React.createElement("span", { className: "toggle-switch-label" })))), React.createElement("li", null, React.createElement("section", { className: "list-item" }, React.createElement("span", null, lang.preferences.themeMode.label), React.createElement("div", { className: "option-select" }, React.createElement("select", { name: "theme-mode", value: prefState.themeMode, onChange: onThemeModeChange, "aria-label": lang.preferences.themeMode.label }, React.createElement("option", { value: 0 }, lang.preferences.themeMode.auto), React.createElement("option", { value: 1 }, lang.preferences.themeMode.light), React.createElement("option", { value: 2 }, lang.preferences.themeMode.dark))))), React.createElement("li", null, React.createElement("section", { className: "list-item" }, React.createElement("span", null, lang.preferences.themeColor), React.createElement("details", { className: "dropdown" }, React.createElement("summary", null, React.createElement("span", { className: "color-picker ripple hash", style: currentThemeColorStyle }, "#"), React.createElement("span", { className: "current-theme-color" }, prefState.themeColor.slice(1))), React.createElement("form", { className: "dropdown-body color-wall", onSubmit: onColorSubmit }, ColorPickerWall, React.createElement("label", { className: "color-picker ripple user-color-label hash", htmlFor: "user-color-input-text", style: currentThemeColorStyle, ref: userColorLabel }, "#", React.createElement("input", { type: "color", className: "color-picker pseudo-hidden", value: prefState.themeColor, onChange: onColorPick, ref: userColorInput })), React.createElement("input", { ref: userColorInputText, id: "user-color-input-text", name: "user-color-input-text", className: "user-color-input-text", type: "text", pattern: "[\\da-f]{3,6}", required: true, autoCapitalize: "none", autoComplete: "off", autoCorrect: "off", spellCheck: false, defaultValue: prefState.themeColor.slice(1), onBlur: onUserColorInputBlur }))))), React.createElement("li", null, React.createElement("section", { className: "list-item" }, React.createElement("span", null, lang.preferences.lrcFormat), React.createElement("span", null, React.createElement("time", { className: "format-example-time" }, convertTimeToTag(83.456, prefState.fixed)), React.createElement("span", { className: "format-example-text" }, formatedText)))), React.createElement("li", null, React.createElement("section", { className: "list-item" }, React.createElement("span", null, lang.preferences.fixed), React.createElement("div", { className: "option-select" }, React.createElement("select", { name: "fixed", value: prefState.fixed, onChange: onFixedChanged, "aria-label": lang.preferences.lrcFormat }, React.createElement("option", { value: 0 }, "0"), React.createElement("option", { value: 1 }, "1"), React.createElement("option", { value: 2 }, "2"), React.createElement("option", { value: 3 }, "3"))))), React.createElement("li", null, React.createElement("label", { className: "list-item" }, React.createElement("label", { htmlFor: "space-start" }, lang.preferences.leftSpace), React.createElement("input", Object.assign({ name: "spaceStart", id: "space-start", required: true, min: -1 }, useNumberInput(prefState.spaceStart, onSpaceChange))))), React.createElement("li", null, React.createElement("label", { className: "list-item" }, React.createElement("label", { htmlFor: "space-end" }, lang.preferences.rightSpace), React.createElement("input", Object.assign({ name: "spaceEnd", id: "space-end", required: true, min: -1 }, useNumberInput(prefState.spaceEnd, onSpaceChange))))), React.createElement("li", { className: "ripple", onTransitionEnd: onCacheClear }, React.createElement("section", { className: "list-item" }, lang.preferences.clearCache))), React.createElement(AkariHideWall, null))); }; //# sourceMappingURL=preferences.js.map