Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
@@ -33,6 +33,8 @@ export default function Action({ translator, fab }) {
|
||||
});
|
||||
const [moved, setMoved] = useState(false);
|
||||
|
||||
const { fabClickAction = 0 } = fab || {};
|
||||
|
||||
const handleWindowResize = useMemo(
|
||||
() =>
|
||||
debounce(() => {
|
||||
@@ -215,7 +217,14 @@ export default function Action({ translator, fab }) {
|
||||
color="primary"
|
||||
onClick={(e) => {
|
||||
if (!moved) {
|
||||
setShowPopup((pre) => !pre);
|
||||
if (fabClickAction === 1) {
|
||||
translator.toggle();
|
||||
sendIframeMsg(MSG_TRANS_TOGGLE);
|
||||
setShowPopup(false);
|
||||
}
|
||||
else {
|
||||
setShowPopup((pre) => !pre);
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -122,7 +122,7 @@ export default function Settings() {
|
||||
transInterval = 200,
|
||||
langDetector = OPT_TRANS_MICROSOFT,
|
||||
} = setting;
|
||||
const { isHide = false } = fab || {};
|
||||
const { isHide = false, fabClickAction = 0 } = fab || {};
|
||||
|
||||
return (
|
||||
<Box>
|
||||
@@ -232,6 +232,19 @@ export default function Settings() {
|
||||
</Select>
|
||||
</FormControl>
|
||||
|
||||
<FormControl size="small">
|
||||
<InputLabel>{i18n("fab_click_action")}</InputLabel>
|
||||
<Select
|
||||
name="fabClickAction"
|
||||
value={fabClickAction}
|
||||
label={i18n("fab_click_action")}
|
||||
onChange= {(e) => updateFab({ fabClickAction: e.target.value })}
|
||||
>
|
||||
<MenuItem value={0}>{i18n("fab_click_menu")}</MenuItem>
|
||||
<MenuItem value={1}>{i18n("fab_click_translate")}</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
|
||||
<FormControl size="small">
|
||||
<InputLabel>{i18n("context_menus")}</InputLabel>
|
||||
<Select
|
||||
|
||||
@@ -7,18 +7,22 @@ import Alert from "@mui/material/Alert";
|
||||
import Link from "@mui/material/Link";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
import Button from "@mui/material/Button";
|
||||
import {
|
||||
URL_KISS_WORKER,
|
||||
OPT_SYNCTYPE_ALL,
|
||||
OPT_SYNCTYPE_WORKER,
|
||||
OPT_SYNCTYPE_WEBDAV,
|
||||
OPT_SYNCTOKEN_PERFIX,
|
||||
} from "../../config";
|
||||
import { useState } from "react";
|
||||
import { syncSettingAndRules } from "../../libs/sync";
|
||||
import { useAlert } from "../../hooks/Alert";
|
||||
import SyncIcon from "@mui/icons-material/Sync";
|
||||
import { useSetting } from "../../hooks/Setting";
|
||||
import { kissLog } from "../../libs/log";
|
||||
import SyncIcon from "@mui/icons-material/Sync";
|
||||
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
||||
import ContentPasteIcon from '@mui/icons-material/ContentPaste';
|
||||
|
||||
export default function SyncSetting() {
|
||||
const i18n = useI18n();
|
||||
@@ -50,6 +54,57 @@ export default function SyncSetting() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleGenerateShareString = async () => {
|
||||
try {
|
||||
const base64Config = btoa(JSON.stringify({
|
||||
syncType: syncType,
|
||||
syncUrl: syncUrl,
|
||||
syncUser: syncUser,
|
||||
syncKey: syncKey,
|
||||
}));
|
||||
const shareString = `${OPT_SYNCTOKEN_PERFIX}${base64Config}`;
|
||||
await navigator.clipboard.writeText(shareString);
|
||||
console.debug("Share string copied to clipboard", shareString);
|
||||
} catch (error) {
|
||||
console.error("Failed to copy share string to clipboard", error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleImportFromClipboard = async () => {
|
||||
try {
|
||||
const text = await navigator.clipboard.readText();
|
||||
console.debug('read_clipboard', text)
|
||||
if (text.startsWith(OPT_SYNCTOKEN_PERFIX)) {
|
||||
const base64Config = text.slice(OPT_SYNCTOKEN_PERFIX.length);
|
||||
const jsonString = atob(base64Config);
|
||||
const updatedConfig = JSON.parse(jsonString);
|
||||
|
||||
if (!OPT_SYNCTYPE_ALL.includes(updatedConfig.syncType)) {
|
||||
console.error('error syncType', updatedConfig.syncType)
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
updatedConfig.syncUrl
|
||||
) {
|
||||
updateSync({
|
||||
syncType: updatedConfig.syncType,
|
||||
syncUrl: updatedConfig.syncUrl,
|
||||
syncUser: updatedConfig.syncUser,
|
||||
syncKey: updatedConfig.syncKey,
|
||||
});
|
||||
} else {
|
||||
console.error("Invalid config structure");
|
||||
}
|
||||
} else {
|
||||
console.error("Invalid share string", text);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to read from clipboard or parse JSON", error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if (!sync) {
|
||||
return;
|
||||
}
|
||||
@@ -133,6 +188,22 @@ export default function SyncSetting() {
|
||||
>
|
||||
{i18n("sync_now")}
|
||||
</LoadingButton>
|
||||
<Button
|
||||
size="small"
|
||||
variant="contained"
|
||||
onClick={handleGenerateShareString}
|
||||
startIcon={<ContentCopyIcon />}
|
||||
>
|
||||
{i18n("copy", "copy")}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleImportFromClipboard}
|
||||
size="small"
|
||||
variant="contained"
|
||||
startIcon={<ContentPasteIcon />}
|
||||
>
|
||||
{i18n("import", "import")}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Box>
|
||||
|
||||
Reference in New Issue
Block a user