UNPKG

lrc-maker

Version:

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

243 lines 11.2 kB
import { assignRepo, createRepo, getFils, getRepos, } from "../utils/gistapi.js"; import { appContext } from "./app.context.js"; import { AkariNotFound, AkariOangoLoading } from "./svg.img.js"; import { EditorSVG, GithubSVG, SynchronizerSVG } from "./svg.js"; import { toastPubSub } from "./toast.js"; const { useCallback, useContext, useEffect, useMemo, useState } = React; const newTokenUrl = "https://github.com/settings/tokens/new?scopes=gist&description=https://lrc-maker.github.io"; const disableCheck = { autoCapitalize: "none", autoComplete: "off", autoCorrect: "off", spellCheck: false, }; export const Gist = ({ lrcDispatch, langName }) => { const { lang, trimOptions } = useContext(appContext); const [token, setToken] = useState(() => localStorage.getItem("lrc-maker-oauth-token")); const [gistId, setGistId] = useState(() => localStorage.getItem("lrc-maker-gist-id")); const [gistIdList, setGistIdList] = useState(undefined); const [fileList, setFileList] = useState(() => JSON.parse(localStorage.getItem("lrc-maker-gist-file"))); const ratelimit = useMemo(() => { return JSON.parse(sessionStorage.getItem("x-ratelimit")); }, []); const onSubmitToken = useCallback((ev) => { ev.preventDefault(); const form = ev.target; const tokenInput = form.elements.namedItem("token"); const value = tokenInput.value; localStorage.setItem("lrc-maker-oauth-token", value); setToken(value); }, []); const onCreateNewGist = useCallback(() => { createRepo() .then((json) => { localStorage.setItem("lrc-maker-gist-id", json.id); setGistId(json.id); }) .catch((error) => { toastPubSub.pub({ type: "warning", text: error.message, }); }); }, []); const onSubmitGistId = useCallback((ev) => { ev.preventDefault(); const form = ev.target; const gistIdInput = form.elements.namedItem("gist-id"); const value = gistIdInput.value; localStorage.setItem("lrc-maker-gist-id", value); setGistId(value); assignRepo().catch((error) => { toastPubSub.pub({ type: "warning", text: error.message, }); }); }, []); useEffect(() => { if (gistId !== null || token === null) { return; } if (!("HTMLDataListElement" in window)) { return; } getRepos() .then((result) => { setGistIdList(result .filter((gist) => { return gist.description === "https://lrc-maker.github.io" && ".lrc-maker" in gist.files; }) .map(({ id }) => id)); }) .catch((error) => { toastPubSub.pub({ type: "warning", text: error.message, }); }); }, [token, gistId]); useEffect(() => { if (gistId === null) { return; } getFils() .then((result) => { if (result === null) { return; } const files = Object.values(result.files).filter((file) => file.filename.endsWith(".lrc")); localStorage.setItem("lrc-maker-gist-file", JSON.stringify(files, ["filename", "content", "truncated", "raw_url"])); setFileList(files); }) .catch((error) => { toastPubSub.pub({ type: "warning", text: error.message, }); }); }, [gistId]); const onFileLoad = useCallback((ev) => { const target = ev.target; if (!("key" in target.dataset)) { return; } const key = Number.parseInt(target.dataset.key, 10); const file = fileList === null || fileList === void 0 ? void 0 : fileList[key]; if (!file) { return; } if (file.truncated) { fetch(file.raw_url) .then((res) => res.text()) .then((text) => { lrcDispatch({ type: 0, payload: { text, options: trimOptions }, }); }) .catch((error) => { toastPubSub.pub({ type: "warning", text: error.message, }); }); } else { lrcDispatch({ type: 0, payload: { text: file.content, options: trimOptions }, }); } }, [fileList, lrcDispatch, trimOptions]); const onClear = useCallback(() => { setGistId(null); setToken(null); }, []); const RateLimit = useMemo(() => { if (ratelimit === null) { return false; } const RatelimitReset = new Intl.DateTimeFormat(langName, { year: "numeric", month: "short", day: "numeric", hour: "numeric", minute: "numeric", second: "numeric", hour12: false, }).format(new Date(Number.parseInt(ratelimit["x-ratelimit-reset"], 10) * 1000)); return (React.createElement("section", { className: "ratelimit" }, React.createElement("p", null, "ratelimit-limit: ", ratelimit["x-ratelimit-limit"]), React.createElement("p", null, "ratelimit-remaining: ", ratelimit["x-ratelimit-remaining"]), React.createElement("p", null, "ratelimit-reset: ", RatelimitReset))); }, [ratelimit, langName]); const GistDetails = useCallback(() => { if (gistId !== null && token !== null) { return (React.createElement("details", { className: "gist-details" }, React.createElement("summary", null, lang.gist.info), React.createElement("section", { className: "gist-bar" }, React.createElement("section", { className: "gist-info" }, React.createElement("p", null, "Gist id: ", React.createElement("a", { href: `https://gist.github.com/${gistId}`, target: "_blank", rel: "noopener noreferrer", className: "link" }, gistId)), React.createElement("button", { className: "button", onClick: onClear }, lang.gist.clearTokenAndGist)), RateLimit))); } return null; }, [gistId, token, lang.gist.info, lang.gist.clearTokenAndGist, onClear, RateLimit]); const NewToken = useMemo(() => { if (token === null) { return (React.createElement("section", { className: "new-token" }, React.createElement(GithubSVG, null), React.createElement("p", { className: "new-token-tip-text" }, lang.gist.newTokenTip), React.createElement("a", { className: "new-token-tip button", target: "_blank", rel: "noopener noreferrer", href: newTokenUrl }, lang.gist.newTokenButton), React.createElement("form", { className: "new-token-form", onSubmit: onSubmitToken }, React.createElement("label", { htmlFor: "github-token" }, "Token:"), React.createElement("input", Object.assign({ type: "text", className: "new-token-input", id: "github-token", name: "token", key: "token", minLength: 40, maxLength: 40, required: true }, disableCheck)), React.createElement("input", { className: "new-token-submit button", type: "submit" })))); } }, [token, lang.gist.newTokenTip, lang.gist.newTokenButton, onSubmitToken]); const NewGistID = useMemo(() => { if (gistId === null) { const option = (id) => { return React.createElement("option", { key: id, value: id }); }; const gistIdDataList = gistIdList && (React.createElement("datalist", { id: "gist-list" }, gistIdList.map((id) => option(id)), ";")); return (React.createElement("section", { className: "get-gist-id" }, React.createElement(GithubSVG, null), React.createElement("p", { className: "gist-id-tip-text" }, lang.gist.newGistTip), React.createElement("button", { className: "create-new-gist button", onClick: onCreateNewGist }, lang.gist.newGistRepoButton), React.createElement("form", { className: "gist-id-form", onSubmit: onSubmitGistId }, React.createElement("label", { htmlFor: "gist-id" }, "Gist id:"), React.createElement("input", Object.assign({ type: "text", className: "gist-id-input", id: "gist-id", name: "gist-id", key: "gist-id", list: "gist-list", placeholder: lang.gist.gistIdPlaceholder, required: true }, disableCheck)), React.createElement("input", { className: "button", type: "submit" }), gistIdDataList))); } }, [ gistId, gistIdList, lang.gist.newGistTip, lang.gist.newGistRepoButton, lang.gist.gistIdPlaceholder, onCreateNewGist, onSubmitGistId, ]); const FileCardList = useMemo(() => { if (fileList !== null) { const FileCard = (file, index) => { return (React.createElement("article", { className: "file-item", key: file.raw_url }, React.createElement("section", { className: "file-content" }, file.content), React.createElement("hr", null), React.createElement("section", { className: "file-bar" }, React.createElement("span", { className: "file-title" }, file.filename), React.createElement("span", { className: "file-action" }, React.createElement("a", { className: "file-load", href: "#/editor/", "data-key": index }, React.createElement(EditorSVG, null)), React.createElement("a", { className: "file-load", href: "#/synchronizer/", "data-key": index }, React.createElement(SynchronizerSVG, null)))))); }; if (fileList.length === 0) { return (React.createElement("section", { className: "gist-no-data" }, React.createElement(AkariNotFound, null))); } return (React.createElement("section", { className: "file-list", onClick: onFileLoad }, fileList.map(FileCard))); } }, [fileList, onFileLoad]); return (React.createElement("div", { className: "gist" }, React.createElement(GistDetails, null), NewToken || NewGistID || FileCardList || React.createElement(GistLoading, null))); }; const GistLoading = () => { return (React.createElement("section", { className: "gist-loading" }, React.createElement(AkariOangoLoading, null))); }; //# sourceMappingURL=gist.js.map