touch operation
This commit is contained in:
@@ -16,6 +16,8 @@ import { Translator } from "./libs/translator";
|
|||||||
import { sendIframeMsg, sendParentMsg } from "./libs/iframe";
|
import { sendIframeMsg, sendParentMsg } from "./libs/iframe";
|
||||||
import { matchRule } from "./libs/rules";
|
import { matchRule } from "./libs/rules";
|
||||||
import Slection from "./views/Selection";
|
import Slection from "./views/Selection";
|
||||||
|
import { touchTapListener } from "./libs/touch";
|
||||||
|
import { debounce } from "./libs/utils";
|
||||||
|
|
||||||
export async function runTranslator(setting) {
|
export async function runTranslator(setting) {
|
||||||
const href = document.location.href;
|
const href = document.location.href;
|
||||||
@@ -120,10 +122,22 @@ export function windowListener(rule) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function showErr(err) {
|
export function showErr(message) {
|
||||||
console.error("[KISS-Translator]", err);
|
|
||||||
const $err = document.createElement("div");
|
const $err = document.createElement("div");
|
||||||
$err.innerText = `KISS-Translator: ${err.message}`;
|
$err.innerText = `KISS-Translator: ${message}`;
|
||||||
$err.style.cssText = "background:red; color:#fff;";
|
$err.style.cssText = "background:red; color:#fff;";
|
||||||
document.body.prepend($err);
|
document.body.prepend($err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function touchOperation(translator) {
|
||||||
|
const { touchTranslate = 2 } = translator.setting;
|
||||||
|
if (touchTranslate === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleTap = debounce(() => {
|
||||||
|
translator.toggle();
|
||||||
|
sendIframeMsg(MSG_TRANS_TOGGLE);
|
||||||
|
});
|
||||||
|
touchTapListener(handleTap, touchTranslate);
|
||||||
|
}
|
||||||
|
|||||||
@@ -647,6 +647,10 @@ export const I18N = {
|
|||||||
zh: `触屏设置`,
|
zh: `触屏设置`,
|
||||||
en: `Touch Setting`,
|
en: `Touch Setting`,
|
||||||
},
|
},
|
||||||
|
touch_translate_shortcut: {
|
||||||
|
zh: `触屏翻译快捷方式`,
|
||||||
|
en: `Touch Translate Shortcut`,
|
||||||
|
},
|
||||||
touch_tap_0: {
|
touch_tap_0: {
|
||||||
zh: `禁用`,
|
zh: `禁用`,
|
||||||
en: `Disable`,
|
en: `Disable`,
|
||||||
|
|||||||
@@ -404,14 +404,6 @@ export const TRANS_MIN_LENGTH = 5; // 最短翻译长度
|
|||||||
export const TRANS_MAX_LENGTH = 5000; // 最长翻译长度
|
export const TRANS_MAX_LENGTH = 5000; // 最长翻译长度
|
||||||
export const TRANS_NEWLINE_LENGTH = 20; // 换行字符数
|
export const TRANS_NEWLINE_LENGTH = 20; // 换行字符数
|
||||||
|
|
||||||
// 触屏操作
|
|
||||||
export const DEFAULT_TOUCH_OPERATION = {
|
|
||||||
[OPT_SHORTCUT_TRANSLATE]: [2, 1, 500],
|
|
||||||
[OPT_SHORTCUT_STYLE]: [3, 1, 500],
|
|
||||||
[OPT_SHORTCUT_POPUP]: [0, 1, 500],
|
|
||||||
[OPT_SHORTCUT_SETTING]: [3, 2, 500],
|
|
||||||
};
|
|
||||||
|
|
||||||
export const DEFAULT_SETTING = {
|
export const DEFAULT_SETTING = {
|
||||||
darkMode: false, // 深色模式
|
darkMode: false, // 深色模式
|
||||||
uiLang: "en", // 界面语言
|
uiLang: "en", // 界面语言
|
||||||
@@ -431,7 +423,7 @@ export const DEFAULT_SETTING = {
|
|||||||
shortcuts: DEFAULT_SHORTCUTS, // 快捷键
|
shortcuts: DEFAULT_SHORTCUTS, // 快捷键
|
||||||
inputRule: DEFAULT_INPUT_RULE, // 输入框设置
|
inputRule: DEFAULT_INPUT_RULE, // 输入框设置
|
||||||
tranboxSetting: DEFAULT_TRANBOX_SETTING, // 划词翻译设置
|
tranboxSetting: DEFAULT_TRANBOX_SETTING, // 划词翻译设置
|
||||||
touchOperations: DEFAULT_TOUCH_OPERATION, // 触屏操作
|
touchTranslate: 2, // 触屏翻译
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DEFAULT_RULES = [GLOBLA_RULE];
|
export const DEFAULT_RULES = [GLOBLA_RULE];
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
showTransbox,
|
showTransbox,
|
||||||
windowListener,
|
windowListener,
|
||||||
showErr,
|
showErr,
|
||||||
|
touchOperation,
|
||||||
} from "./common";
|
} from "./common";
|
||||||
|
|
||||||
function runtimeListener(translator) {
|
function runtimeListener(translator) {
|
||||||
@@ -70,7 +71,11 @@ function runtimeListener(translator) {
|
|||||||
|
|
||||||
// 浮球按钮
|
// 浮球按钮
|
||||||
await showFab(translator);
|
await showFab(translator);
|
||||||
|
|
||||||
|
// 触屏操作
|
||||||
|
touchOperation(translator);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showErr(err);
|
console.error("[KISS-Translator]", err);
|
||||||
|
showErr(err.message);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
import { useCallback } from "react";
|
|
||||||
import { DEFAULT_TOUCH_OPERATION } from "../config";
|
|
||||||
import { useSetting } from "./Setting";
|
|
||||||
|
|
||||||
export function useTouch(action) {
|
|
||||||
const { setting, updateSetting } = useSetting();
|
|
||||||
const touchOperations = setting?.touchOperations || DEFAULT_TOUCH_OPERATION;
|
|
||||||
const touchOperation = touchOperations[action];
|
|
||||||
|
|
||||||
const setTouchOperation = useCallback(
|
|
||||||
async (val, idx) => {
|
|
||||||
touchOperations[action][idx] = val;
|
|
||||||
await updateSetting({ touchOperations: { ...touchOperations } });
|
|
||||||
},
|
|
||||||
[action, touchOperations, updateSetting]
|
|
||||||
);
|
|
||||||
|
|
||||||
return { touchOperation, setTouchOperation };
|
|
||||||
}
|
|
||||||
@@ -1,31 +1,12 @@
|
|||||||
export function touchTapListener(fn, setting) {
|
export function touchTapListener(fn, touchsLength) {
|
||||||
const [touchLength, touchCount, touchTime] = setting;
|
|
||||||
|
|
||||||
let lastTouch = 0;
|
|
||||||
let curCount = 0;
|
|
||||||
const handleTouchend = (e) => {
|
const handleTouchend = (e) => {
|
||||||
if (e.touches.length !== touchLength) {
|
if (e.touches.length === touchsLength) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const timer = setTimeout(() => {
|
|
||||||
clearTimeout(timer);
|
|
||||||
curCount = 0;
|
|
||||||
}, touchTime);
|
|
||||||
|
|
||||||
curCount++;
|
|
||||||
const now = Date.now();
|
|
||||||
if (curCount === touchCount && now - lastTouch <= touchTime) {
|
|
||||||
timer && clearTimeout(timer);
|
|
||||||
curCount = 0;
|
|
||||||
fn();
|
fn();
|
||||||
}
|
}
|
||||||
|
|
||||||
lastTouch = now;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener("touchend", handleTouchend);
|
document.addEventListener("touchstart", handleTouchend);
|
||||||
return () => {
|
return () => {
|
||||||
document.removeEventListener("touchend", handleTouchend);
|
document.removeEventListener("touchstart", handleTouchend);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
showTransbox,
|
showTransbox,
|
||||||
windowListener,
|
windowListener,
|
||||||
showErr,
|
showErr,
|
||||||
|
touchOperation,
|
||||||
} from "./common";
|
} from "./common";
|
||||||
|
|
||||||
function runSettingPage() {
|
function runSettingPage() {
|
||||||
@@ -69,9 +70,13 @@ function runSettingPage() {
|
|||||||
// 浮球按钮
|
// 浮球按钮
|
||||||
await showFab(translator);
|
await showFab(translator);
|
||||||
|
|
||||||
|
// 触屏操作
|
||||||
|
touchOperation(translator);
|
||||||
|
|
||||||
// 同步订阅规则
|
// 同步订阅规则
|
||||||
await trySyncAllSubRules(setting);
|
await trySyncAllSubRules(setting);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showErr(err);
|
console.error("[KISS-Translator]", err);
|
||||||
|
showErr(err.message);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import SendTimeExtensionIcon from "@mui/icons-material/SendTimeExtension";
|
|||||||
import InputIcon from "@mui/icons-material/Input";
|
import InputIcon from "@mui/icons-material/Input";
|
||||||
import SelectAllIcon from "@mui/icons-material/SelectAll";
|
import SelectAllIcon from "@mui/icons-material/SelectAll";
|
||||||
import EventNoteIcon from "@mui/icons-material/EventNote";
|
import EventNoteIcon from "@mui/icons-material/EventNote";
|
||||||
import TouchAppIcon from "@mui/icons-material/TouchApp";
|
|
||||||
|
|
||||||
function LinkItem({ label, url, icon }) {
|
function LinkItem({ label, url, icon }) {
|
||||||
const match = useMatch(url);
|
const match = useMatch(url);
|
||||||
@@ -48,12 +47,6 @@ export default function Navigator(props) {
|
|||||||
url: "/input",
|
url: "/input",
|
||||||
icon: <InputIcon />,
|
icon: <InputIcon />,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: "touch_setting",
|
|
||||||
label: i18n("touch_setting"),
|
|
||||||
url: "/touch",
|
|
||||||
icon: <TouchAppIcon />,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: "selection_translate",
|
id: "selection_translate",
|
||||||
label: i18n("selection_translate"),
|
label: i18n("selection_translate"),
|
||||||
|
|||||||
@@ -60,6 +60,9 @@ export default function Settings() {
|
|||||||
case "newlineLength":
|
case "newlineLength":
|
||||||
value = limitNumber(value, 1, 1000);
|
value = limitNumber(value, 1, 1000);
|
||||||
break;
|
break;
|
||||||
|
case "touchTranslate":
|
||||||
|
value = limitNumber(value, 0, 3);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
updateSetting({
|
updateSetting({
|
||||||
@@ -86,6 +89,7 @@ export default function Settings() {
|
|||||||
newlineLength = TRANS_NEWLINE_LENGTH,
|
newlineLength = TRANS_NEWLINE_LENGTH,
|
||||||
mouseKey = OPT_MOUSEKEY_DISABLE,
|
mouseKey = OPT_MOUSEKEY_DISABLE,
|
||||||
detectRemote = false,
|
detectRemote = false,
|
||||||
|
touchTranslate = 2,
|
||||||
} = setting;
|
} = setting;
|
||||||
const { isHide = false } = fab || {};
|
const { isHide = false } = fab || {};
|
||||||
|
|
||||||
@@ -169,6 +173,22 @@ export default function Settings() {
|
|||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
|
<FormControl size="small">
|
||||||
|
<InputLabel>{i18n("touch_translate_shortcut")}</InputLabel>
|
||||||
|
<Select
|
||||||
|
name="touchTranslate"
|
||||||
|
value={touchTranslate}
|
||||||
|
label={i18n("touch_translate_shortcut")}
|
||||||
|
onChange={handleChange}
|
||||||
|
>
|
||||||
|
{[0, 2, 3].map((item) => (
|
||||||
|
<MenuItem key={item} value={item}>
|
||||||
|
{i18n(`touch_tap_${item}`)}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
<FormControl size="small">
|
<FormControl size="small">
|
||||||
<InputLabel>{i18n("hide_fab_button")}</InputLabel>
|
<InputLabel>{i18n("hide_fab_button")}</InputLabel>
|
||||||
<Select
|
<Select
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import Webfix from "./Webfix";
|
|||||||
import InputSetting from "./InputSetting";
|
import InputSetting from "./InputSetting";
|
||||||
import Tranbox from "./Tranbox";
|
import Tranbox from "./Tranbox";
|
||||||
import FavWords from "./FavWords";
|
import FavWords from "./FavWords";
|
||||||
import TouchSetting from "./touchSetting";
|
|
||||||
|
|
||||||
export default function Options() {
|
export default function Options() {
|
||||||
const [error, setError] = useState("");
|
const [error, setError] = useState("");
|
||||||
@@ -123,7 +122,6 @@ export default function Options() {
|
|||||||
<Route index element={<Setting />} />
|
<Route index element={<Setting />} />
|
||||||
<Route path="rules" element={<Rules />} />
|
<Route path="rules" element={<Rules />} />
|
||||||
<Route path="input" element={<InputSetting />} />
|
<Route path="input" element={<InputSetting />} />
|
||||||
<Route path="touch" element={<TouchSetting />} />
|
|
||||||
<Route path="tranbox" element={<Tranbox />} />
|
<Route path="tranbox" element={<Tranbox />} />
|
||||||
<Route path="apis" element={<Apis />} />
|
<Route path="apis" element={<Apis />} />
|
||||||
<Route path="sync" element={<SyncSetting />} />
|
<Route path="sync" element={<SyncSetting />} />
|
||||||
|
|||||||
@@ -1,103 +0,0 @@
|
|||||||
import Box from "@mui/material/Box";
|
|
||||||
import Stack from "@mui/material/Stack";
|
|
||||||
import TextField from "@mui/material/TextField";
|
|
||||||
import MenuItem from "@mui/material/MenuItem";
|
|
||||||
import { useI18n } from "../../hooks/I18n";
|
|
||||||
import {
|
|
||||||
OPT_SHORTCUT_TRANSLATE,
|
|
||||||
OPT_SHORTCUT_STYLE,
|
|
||||||
OPT_SHORTCUT_POPUP,
|
|
||||||
OPT_SHORTCUT_SETTING,
|
|
||||||
} from "../../config";
|
|
||||||
import Grid from "@mui/material/Grid";
|
|
||||||
import { limitNumber } from "../../libs/utils";
|
|
||||||
import { useTouch } from "../../hooks/Touch";
|
|
||||||
|
|
||||||
function TouchItem({ action, name }) {
|
|
||||||
const i18n = useI18n();
|
|
||||||
const { touchOperation, setTouchOperation } = useTouch(action);
|
|
||||||
const [triggerShortcut, triggerCount, triggerTime] = touchOperation;
|
|
||||||
|
|
||||||
const handleChangeShortcut = (e) => {
|
|
||||||
const value = limitNumber(e.target.value, 0, 3);
|
|
||||||
setTouchOperation(value, 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChangeCount = (e) => {
|
|
||||||
const value = limitNumber(e.target.value, 1, 3);
|
|
||||||
setTouchOperation(value, 2);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChangeTime = (e) => {
|
|
||||||
const value = limitNumber(e.target.value, 100, 1000);
|
|
||||||
setTouchOperation(value, 3);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box>
|
|
||||||
<Grid container spacing={2} columns={12}>
|
|
||||||
<Grid item xs={12} sm={12} md={4} lg={4}>
|
|
||||||
<TextField
|
|
||||||
select
|
|
||||||
fullWidth
|
|
||||||
size="small"
|
|
||||||
name="triggerShortcut"
|
|
||||||
value={triggerShortcut}
|
|
||||||
label={i18n(name)}
|
|
||||||
onChange={handleChangeShortcut}
|
|
||||||
>
|
|
||||||
{[0, 2, 3].map((val) => (
|
|
||||||
<MenuItem key={val} value={val}>
|
|
||||||
{i18n(`touch_tap_${val}`)}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</TextField>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12} sm={12} md={4} lg={4}>
|
|
||||||
<TextField
|
|
||||||
select
|
|
||||||
fullWidth
|
|
||||||
size="small"
|
|
||||||
name="triggerCount"
|
|
||||||
value={triggerCount}
|
|
||||||
label={i18n("shortcut_press_count")}
|
|
||||||
onChange={handleChangeCount}
|
|
||||||
>
|
|
||||||
{[1, 2, 3].map((val) => (
|
|
||||||
<MenuItem key={val} value={val}>
|
|
||||||
{val}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</TextField>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12} sm={12} md={4} lg={4}>
|
|
||||||
<TextField
|
|
||||||
fullWidth
|
|
||||||
size="small"
|
|
||||||
label={i18n("combo_timeout")}
|
|
||||||
type="number"
|
|
||||||
name="triggerTime"
|
|
||||||
defaultValue={triggerTime}
|
|
||||||
onChange={handleChangeTime}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function TouchSetting() {
|
|
||||||
return (
|
|
||||||
<Box>
|
|
||||||
<Stack spacing={3}>
|
|
||||||
<TouchItem
|
|
||||||
action={OPT_SHORTCUT_TRANSLATE}
|
|
||||||
name="toggle_translate_shortcut"
|
|
||||||
/>
|
|
||||||
<TouchItem action={OPT_SHORTCUT_STYLE} name="toggle_style_shortcut" />
|
|
||||||
<TouchItem action={OPT_SHORTCUT_POPUP} name="toggle_popup_shortcut" />
|
|
||||||
<TouchItem action={OPT_SHORTCUT_SETTING} name="open_setting_shortcut" />
|
|
||||||
</Stack>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user