feat: export old setting
This commit is contained in:
6
.env
6
.env
@@ -11,9 +11,9 @@ REACT_APP_OPTIONSPAGE_DEV=http://localhost:3000/options.html
|
|||||||
|
|
||||||
REACT_APP_LOGOURL=https://fishjar.github.io/kiss-translator/images/logo192.png
|
REACT_APP_LOGOURL=https://fishjar.github.io/kiss-translator/images/logo192.png
|
||||||
|
|
||||||
REACT_APP_RULESURL=https://fishjar.github.io/kiss-rules/kiss-rules.json
|
REACT_APP_RULESURL=https://fishjar.github.io/kiss-rules/kiss-rules_v2.json
|
||||||
REACT_APP_RULESURL_ON=https://fishjar.github.io/kiss-rules/kiss-rules-on.json
|
REACT_APP_RULESURL_ON=https://fishjar.github.io/kiss-rules/kiss-rules-on_v2.json
|
||||||
REACT_APP_RULESURL_OFF=https://fishjar.github.io/kiss-rules/kiss-rules-off.json
|
REACT_APP_RULESURL_OFF=https://fishjar.github.io/kiss-rules/kiss-rules-off_v2.json
|
||||||
|
|
||||||
REACT_APP_USERSCRIPT_DOWNLOADURL=https://fishjar.github.io/kiss-translator/kiss-translator.user.js
|
REACT_APP_USERSCRIPT_DOWNLOADURL=https://fishjar.github.io/kiss-translator/kiss-translator.user.js
|
||||||
REACT_APP_USERSCRIPT_IOS_DOWNLOADURL=https://fishjar.github.io/kiss-translator/kiss-translator-ios-safari.user.js
|
REACT_APP_USERSCRIPT_IOS_DOWNLOADURL=https://fishjar.github.io/kiss-translator/kiss-translator-ios-safari.user.js
|
||||||
|
|||||||
@@ -7,5 +7,7 @@ export const APP_CONSTS = {
|
|||||||
boxID: `${APP_LCNAME}-box`,
|
boxID: `${APP_LCNAME}-box`,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const APP_VERSION = process.env.REACT_APP_VERSION.split(".");
|
||||||
|
|
||||||
export const THEME_LIGHT = "light";
|
export const THEME_LIGHT = "light";
|
||||||
export const THEME_DARK = "dark";
|
export const THEME_DARK = "dark";
|
||||||
|
|||||||
@@ -1402,4 +1402,9 @@ export const I18N = {
|
|||||||
en: `Whether to pre-initialize`,
|
en: `Whether to pre-initialize`,
|
||||||
zh_TW: `是否預初始化`,
|
zh_TW: `是否預初始化`,
|
||||||
},
|
},
|
||||||
|
export_old: {
|
||||||
|
zh: `导出旧版`,
|
||||||
|
en: `Export old version`,
|
||||||
|
zh_TW: `匯出舊版`,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
import { APP_NAME } from "./app";
|
import { APP_NAME, APP_VERSION } from "./app";
|
||||||
|
|
||||||
export const KV_RULES_KEY = "kiss-rules.json";
|
export const KV_RULES_KEY = `kiss-rules_v${APP_VERSION[0]}.json`;
|
||||||
export const KV_WORDS_KEY = "kiss-words.json";
|
export const KV_WORDS_KEY = "kiss-words.json";
|
||||||
export const KV_RULES_SHARE_KEY = "kiss-rules-share.json";
|
export const KV_RULES_SHARE_KEY = `kiss-rules-share_v${APP_VERSION[0]}.json`;
|
||||||
export const KV_SETTING_KEY = "kiss-setting.json";
|
export const KV_SETTING_KEY = `kiss-setting_v${APP_VERSION[0]}.json`;
|
||||||
export const KV_SALT_SYNC = "KISS-Translator-SYNC";
|
export const KV_SALT_SYNC = "KISS-Translator-SYNC";
|
||||||
export const KV_SALT_SHARE = "KISS-Translator-SHARE";
|
export const KV_SALT_SHARE = "KISS-Translator-SHARE";
|
||||||
|
|
||||||
export const STOKEY_MSAUTH = `${APP_NAME}_msauth`;
|
export const STOKEY_MSAUTH = `${APP_NAME}_msauth`;
|
||||||
export const STOKEY_BDAUTH = `${APP_NAME}_bdauth`;
|
export const STOKEY_BDAUTH = `${APP_NAME}_bdauth`;
|
||||||
export const STOKEY_SETTING = `${APP_NAME}_setting`;
|
export const STOKEY_SETTING_OLD = `${APP_NAME}_setting`;
|
||||||
export const STOKEY_RULES = `${APP_NAME}_rules`;
|
export const STOKEY_RULES_OLD = `${APP_NAME}_rules`;
|
||||||
|
export const STOKEY_SETTING = `${APP_NAME}_setting_v${APP_VERSION[0]}`;
|
||||||
|
export const STOKEY_RULES = `${APP_NAME}_rules_v${APP_VERSION[0]}`;
|
||||||
export const STOKEY_WORDS = `${APP_NAME}_words`;
|
export const STOKEY_WORDS = `${APP_NAME}_words`;
|
||||||
export const STOKEY_SYNC = `${APP_NAME}_sync`;
|
export const STOKEY_SYNC = `${APP_NAME}_sync`;
|
||||||
export const STOKEY_FAB = `${APP_NAME}_fab`;
|
export const STOKEY_FAB = `${APP_NAME}_fab`;
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
import { createContext, useContext, useState, forwardRef } from "react";
|
import {
|
||||||
|
createContext,
|
||||||
|
useContext,
|
||||||
|
useState,
|
||||||
|
forwardRef,
|
||||||
|
useCallback,
|
||||||
|
useMemo,
|
||||||
|
} from "react";
|
||||||
import Snackbar from "@mui/material/Snackbar";
|
import Snackbar from "@mui/material/Snackbar";
|
||||||
import MuiAlert from "@mui/material/Alert";
|
import MuiAlert from "@mui/material/Alert";
|
||||||
|
|
||||||
@@ -18,32 +25,37 @@ export function AlertProvider({ children }) {
|
|||||||
const horizontal = "center";
|
const horizontal = "center";
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [severity, setSeverity] = useState("info");
|
const [severity, setSeverity] = useState("info");
|
||||||
const [message, setMessage] = useState("");
|
const [message, setMessage] = useState(null);
|
||||||
|
|
||||||
const showAlert = (msg, type) => {
|
const showAlert = useCallback((msg, type) => {
|
||||||
setOpen(true);
|
setOpen(true);
|
||||||
setMessage(msg);
|
setMessage(msg);
|
||||||
setSeverity(type);
|
setSeverity(type);
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
const handleClose = (_, reason) => {
|
const handleClose = useCallback((_, reason) => {
|
||||||
if (reason === "clickaway") {
|
if (reason === "clickaway") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
const error = (msg) => showAlert(msg, "error");
|
const value = useMemo(
|
||||||
const warning = (msg) => showAlert(msg, "warning");
|
() => ({
|
||||||
const info = (msg) => showAlert(msg, "info");
|
error: (msg) => showAlert(msg, "error"),
|
||||||
const success = (msg) => showAlert(msg, "success");
|
warning: (msg) => showAlert(msg, "warning"),
|
||||||
|
info: (msg) => showAlert(msg, "info"),
|
||||||
|
success: (msg) => showAlert(msg, "success"),
|
||||||
|
}),
|
||||||
|
[showAlert]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AlertContext.Provider value={{ error, warning, info, success }}>
|
<AlertContext.Provider value={value}>
|
||||||
{children}
|
{children}
|
||||||
<Snackbar
|
<Snackbar
|
||||||
open={open}
|
open={open}
|
||||||
autoHideDuration={3000}
|
autoHideDuration={10000}
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
anchorOrigin={{ vertical, horizontal }}
|
anchorOrigin={{ vertical, horizontal }}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
STOKEY_SETTING,
|
STOKEY_SETTING,
|
||||||
|
STOKEY_SETTING_OLD,
|
||||||
STOKEY_RULES,
|
STOKEY_RULES,
|
||||||
|
STOKEY_RULES_OLD,
|
||||||
STOKEY_WORDS,
|
STOKEY_WORDS,
|
||||||
STOKEY_FAB,
|
STOKEY_FAB,
|
||||||
STOKEY_SYNC,
|
STOKEY_SYNC,
|
||||||
@@ -60,7 +62,12 @@ async function trySetObj(key, obj) {
|
|||||||
|
|
||||||
async function getObj(key) {
|
async function getObj(key) {
|
||||||
const val = await get(key);
|
const val = await get(key);
|
||||||
return val && JSON.parse(val);
|
try {
|
||||||
|
return JSON.parse(val);
|
||||||
|
} catch (err) {
|
||||||
|
kissLog("parse json: ", key);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function putObj(key, obj) {
|
async function putObj(key, obj) {
|
||||||
@@ -86,6 +93,7 @@ export const storage = {
|
|||||||
* 设置信息
|
* 设置信息
|
||||||
*/
|
*/
|
||||||
export const getSetting = () => getObj(STOKEY_SETTING);
|
export const getSetting = () => getObj(STOKEY_SETTING);
|
||||||
|
export const getSettingOld = () => getObj(STOKEY_SETTING_OLD);
|
||||||
export const getSettingWithDefault = async () => ({
|
export const getSettingWithDefault = async () => ({
|
||||||
...DEFAULT_SETTING,
|
...DEFAULT_SETTING,
|
||||||
...((await getSetting()) || {}),
|
...((await getSetting()) || {}),
|
||||||
@@ -97,6 +105,7 @@ export const putSetting = (obj) => putObj(STOKEY_SETTING, obj);
|
|||||||
* 规则列表
|
* 规则列表
|
||||||
*/
|
*/
|
||||||
export const getRules = () => getObj(STOKEY_RULES);
|
export const getRules = () => getObj(STOKEY_RULES);
|
||||||
|
export const getRulesOld = () => getObj(STOKEY_RULES_OLD);
|
||||||
export const getRulesWithDefault = async () =>
|
export const getRulesWithDefault = async () =>
|
||||||
(await getRules()) || DEFAULT_RULES;
|
(await getRules()) || DEFAULT_RULES;
|
||||||
export const setRules = (val) => setObj(STOKEY_RULES, val);
|
export const setRules = (val) => setObj(STOKEY_RULES, val);
|
||||||
|
|||||||
@@ -45,7 +45,11 @@ import { loadOrFetchSubRules } from "../../libs/subRules";
|
|||||||
import { useAlert } from "../../hooks/Alert";
|
import { useAlert } from "../../hooks/Alert";
|
||||||
import { syncShareRules } from "../../libs/sync";
|
import { syncShareRules } from "../../libs/sync";
|
||||||
import { debounce } from "../../libs/utils";
|
import { debounce } from "../../libs/utils";
|
||||||
import { delSubRules, getSyncWithDefault } from "../../libs/storage";
|
import {
|
||||||
|
delSubRules,
|
||||||
|
getSyncWithDefault,
|
||||||
|
getRulesOld,
|
||||||
|
} from "../../libs/storage";
|
||||||
import OwSubRule from "./OwSubRule";
|
import OwSubRule from "./OwSubRule";
|
||||||
import ClearAllIcon from "@mui/icons-material/ClearAll";
|
import ClearAllIcon from "@mui/icons-material/ClearAll";
|
||||||
import HelpButton from "./HelpButton";
|
import HelpButton from "./HelpButton";
|
||||||
@@ -901,6 +905,11 @@ function UserRules({ subRules, rules }) {
|
|||||||
text={i18n("export")}
|
text={i18n("export")}
|
||||||
fileName={`kiss-rules_${Date.now()}.json`}
|
fileName={`kiss-rules_${Date.now()}.json`}
|
||||||
/>
|
/>
|
||||||
|
<DownloadButton
|
||||||
|
handleData={async () => JSON.stringify(await getRulesOld(), null, 2)}
|
||||||
|
text={i18n("export_old")}
|
||||||
|
fileName={`kiss-rules_v1_${Date.now()}.json`}
|
||||||
|
/>
|
||||||
|
|
||||||
<ShareButton
|
<ShareButton
|
||||||
rules={rules}
|
rules={rules}
|
||||||
@@ -979,6 +988,7 @@ function SubRulesItem({
|
|||||||
deleteDataCache,
|
deleteDataCache,
|
||||||
}) {
|
}) {
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
const alert = useAlert();
|
||||||
|
|
||||||
const handleDel = async () => {
|
const handleDel = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -1000,6 +1010,12 @@ function SubRulesItem({
|
|||||||
await updateDataCache(url);
|
await updateDataCache(url);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
kissLog("sync sub rules", err);
|
kissLog("sync sub rules", err);
|
||||||
|
alert.error(
|
||||||
|
<>
|
||||||
|
<p>Sync Error:</p>
|
||||||
|
<pre>{err.message}</pre>
|
||||||
|
</>
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import { sendBgMsg } from "../../libs/msg";
|
|||||||
import { kissLog } from "../../libs/log";
|
import { kissLog } from "../../libs/log";
|
||||||
import UploadButton from "./UploadButton";
|
import UploadButton from "./UploadButton";
|
||||||
import DownloadButton from "./DownloadButton";
|
import DownloadButton from "./DownloadButton";
|
||||||
|
import { getSettingOld } from "../../libs/storage";
|
||||||
|
|
||||||
function ShortcutItem({ action, label }) {
|
function ShortcutItem({ action, label }) {
|
||||||
const { shortcut, setShortcut } = useShortcut(action);
|
const { shortcut, setShortcut } = useShortcut(action);
|
||||||
@@ -137,6 +138,13 @@ export default function Settings() {
|
|||||||
text={i18n("export")}
|
text={i18n("export")}
|
||||||
fileName={`kiss-setting_${Date.now()}.json`}
|
fileName={`kiss-setting_${Date.now()}.json`}
|
||||||
/>
|
/>
|
||||||
|
<DownloadButton
|
||||||
|
handleData={async () =>
|
||||||
|
JSON.stringify(await getSettingOld(), null, 2)
|
||||||
|
}
|
||||||
|
text={i18n("export_old")}
|
||||||
|
fileName={`kiss-setting_v1_${Date.now()}.json`}
|
||||||
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<Box>
|
<Box>
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ export default function SyncSetting() {
|
|||||||
</LoadingButton>
|
</LoadingButton>
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
variant="contained"
|
variant="outlined"
|
||||||
onClick={handleGenerateShareString}
|
onClick={handleGenerateShareString}
|
||||||
startIcon={<ContentCopyIcon />}
|
startIcon={<ContentCopyIcon />}
|
||||||
>
|
>
|
||||||
@@ -198,7 +198,7 @@ export default function SyncSetting() {
|
|||||||
<Button
|
<Button
|
||||||
onClick={handleImportFromClipboard}
|
onClick={handleImportFromClipboard}
|
||||||
size="small"
|
size="small"
|
||||||
variant="contained"
|
variant="outlined"
|
||||||
startIcon={<ContentPasteIcon />}
|
startIcon={<ContentPasteIcon />}
|
||||||
>
|
>
|
||||||
{i18n("import", "import")}
|
{i18n("import", "import")}
|
||||||
|
|||||||
Reference in New Issue
Block a user