mirror of
https://github.com/AkiChase/scrcpy-mask
synced 2025-02-23 07:22:17 +08:00
commit
d1b0c42b0e
@ -13,8 +13,8 @@ Due to the delay and blurred image quality of the mirror screen. This project fo
|
|||||||
- [x] Visually setting the mapping
|
- [x] Visually setting the mapping
|
||||||
- [x] Key mapping config import and export
|
- [x] Key mapping config import and export
|
||||||
- [x] Update check
|
- [x] Update check
|
||||||
|
- [x] Switch between key mapping and input-text box
|
||||||
- [ ] Internationalization (i18n)
|
- [ ] Internationalization (i18n)
|
||||||
- [ ] Switch between key mapping and raw input
|
|
||||||
- [ ] Gamepad key mapping
|
- [ ] Gamepad key mapping
|
||||||
- [ ] Better macro support
|
- [ ] Better macro support
|
||||||
- [ ] Provide external interface through websocket
|
- [ ] Provide external interface through websocket
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "scrcpy-mask",
|
"name": "scrcpy-mask",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.1.7",
|
"version": "0.1.8",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "scrcpy-mask"
|
name = "scrcpy-mask"
|
||||||
version = "0.1.7"
|
version = "0.1.8"
|
||||||
description = "A Tauri App"
|
description = "A Tauri App"
|
||||||
authors = ["AkiChase"]
|
authors = ["AkiChase"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
[
|
[
|
||||||
{"title":"AVD-王者荣耀-标准三技能-导入默认","list":[{"key":{"down":"KeyS","left":"KeyA","right":"KeyD","up":"KeyW"},"note":"方向轮盘","offset":175,"pointerId":1,"posX":183,"posY":566,"type":"SteeringWheel"},{"key":"KeyQ","note":"技能1","pointerId":2,"posX":951,"posY":636,"range":50,"type":"DirectionalSkill"},{"key":"KeyE","note":"技能2","pointerId":2,"posX":1025,"posY":500,"range":50,"type":"DirectionalSkill"},{"key":"AltLeft","note":"技能3","pointerId":2,"posX":1160,"posY":420,"range":50,"type":"DirectionalSkill"},{"key":"Space","note":"取消技能","pointerId":2,"posX":1160,"posY":140,"type":"CancelSkill"},{"key":"KeyB","note":"回城","pointerId":3,"posX":650,"posY":650,"time":80,"type":"Tap"},{"key":"KeyC","note":"回复","pointerId":3,"posX":740,"posY":650,"time":80,"type":"Tap"},{"key":"KeyF","note":"召唤师技能","pointerId":2,"posX":838,"posY":647,"range":50,"type":"DirectionalSkill"},{"key":"M2","note":"攻击","pointerId":3,"posX":1174,"posY":618,"time":80,"type":"Tap"},{"key":"Digit1","note":"技能1升级","pointerId":3,"posX":880,"posY":560,"time":80,"type":"Tap"},{"key":"Digit2","note":"技能2升级","pointerId":3,"posX":960,"posY":430,"time":80,"type":"Tap"},{"key":"Digit3","note":"技能3升级","pointerId":3,"posX":1090,"posY":350,"time":80,"type":"Tap"},{"key":"Digit5","note":"快速购买1","pointerId":3,"posX":133,"posY":289,"time":80,"type":"Tap"},{"key":"Digit6","note":"快速购买2","pointerId":3,"posX":130,"posY":370,"time":80,"type":"Tap"},{"key":"M3","note":"观察","pointerId":4,"posX":1000,"posY":200,"scale":1,"type":"Observation"},{"key":"Tab","macro":{"down":[{"args":["default",5,1185,40,80],"type":"touch"}],"loop":null,"up":[{"args":["default",5,1220,100,80],"type":"touch"}]},"note":"战绩面板","pointerId":5,"posX":1185,"posY":40,"type":"Macro"},{"key":"ShiftLeft","macro":{"down":[{"args":["default",5,40,300,80],"type":"touch"}],"loop":null,"up":[{"args":["default",5,1200,60,80],"type":"touch"}]},"note":"商店","pointerId":5,"posX":44,"posY":302,"type":"Macro"},{"key":"KeyZ","macro":{"down":[{"args":["default",5,250,230,80],"type":"touch"}],"loop":null,"up":[{"args":["default",5,640,150,80],"type":"touch"}]},"note":"地图","pointerId":5,"posX":250,"posY":230,"type":"Macro"},{"key":"WheelDown","note":"推塔键","pointerId":2,"posX":1228,"posY":513,"time":80,"type":"Tap"},{"key":"Backquote","macro":{"down":[{"args":["default",5,40,300,80],"type":"touch"},{"args":["200"],"type":"sleep"},{"args":["default",5,510,630,80],"type":"touch"},{"args":["default",5,1165,575,80],"type":"touch"},{"args":["default",5,1200,65,80],"type":"touch"},{"args":["300"],"type":"sleep"},{"args":["default",5,125,300,80],"type":"touch"}],"loop":null,"up":null},"note":"换装2","pointerId":5,"posX":236,"posY":66,"type":"Macro"},{"type":"Tap","key":"WheelUp","note":"补兵键","posX":1059,"posY":659,"pointerId":2,"time":80}],"relativeSize":{"h":720,"w":1280}},
|
{"list":[{"key":{"down":"KeyS","left":"KeyA","right":"KeyD","up":"KeyW"},"note":"方向轮盘","offset":175,"pointerId":1,"posX":183,"posY":566,"type":"SteeringWheel"},{"key":"KeyQ","note":"技能1","pointerId":2,"posX":951,"posY":636,"range":30,"type":"DirectionalSkill"},{"key":"KeyE","note":"技能2","pointerId":2,"posX":1025,"posY":500,"range":30,"type":"DirectionalSkill"},{"key":"AltLeft","note":"技能3","pointerId":2,"posX":1160,"posY":420,"range":30,"type":"DirectionalSkill"},{"key":"Space","note":"取消技能","pointerId":2,"posX":1160,"posY":140,"type":"CancelSkill"},{"key":"KeyB","note":"回城","pointerId":3,"posX":650,"posY":650,"time":80,"type":"Tap"},{"key":"KeyC","note":"回复","pointerId":3,"posX":740,"posY":650,"time":80,"type":"Tap"},{"key":"KeyF","note":"召唤师技能","pointerId":2,"posX":838,"posY":647,"range":50,"type":"DirectionalSkill"},{"key":"M2","note":"攻击","pointerId":3,"posX":1174,"posY":618,"time":80,"type":"Tap"},{"key":"Digit1","note":"技能1升级","pointerId":3,"posX":880,"posY":560,"time":80,"type":"Tap"},{"key":"Digit2","note":"技能2升级","pointerId":3,"posX":960,"posY":430,"time":80,"type":"Tap"},{"key":"Digit3","note":"技能3升级","pointerId":3,"posX":1090,"posY":350,"time":80,"type":"Tap"},{"key":"Digit5","note":"快速购买1","pointerId":3,"posX":133,"posY":289,"time":80,"type":"Tap"},{"key":"Digit6","note":"快速购买2","pointerId":3,"posX":130,"posY":370,"time":80,"type":"Tap"},{"key":"M3","note":"观察","pointerId":4,"posX":1000,"posY":200,"scale":1,"type":"Observation"},{"key":"Tab","macro":{"down":[{"args":["default",5,1185,40,80],"type":"touch"}],"loop":null,"up":[{"args":["default",5,1220,100,80],"type":"touch"}]},"note":"战绩面板","posX":1185,"posY":40,"type":"Macro"},{"key":"ShiftLeft","macro":{"down":[{"args":["default",5,40,300,80],"type":"touch"}],"loop":null,"up":[{"args":["default",5,1200,60,80],"type":"touch"}]},"note":"商店","posX":44,"posY":302,"type":"Macro"},{"key":"KeyZ","macro":{"down":[{"args":["default",5,250,230,80],"type":"touch"}],"loop":null,"up":[{"args":["default",5,640,150,80],"type":"touch"}]},"note":"地图","posX":250,"posY":230,"type":"Macro"},{"key":"Backquote","macro":{"down":[{"args":["default",5,40,300,80],"type":"touch"},{"args":[150],"type":"sleep"},{"args":["default",5,510,630,80],"type":"touch"},{"args":[150],"type":"sleep"},{"args":["default",5,1165,575,80],"type":"touch"},{"args":["default",5,1200,65,80],"type":"touch"},{"args":[200],"type":"sleep"},{"args":["default",5,125,300,80],"type":"touch"}],"loop":null,"up":null},"note":"换装2","posX":236,"posY":66,"type":"Macro"},{"directional":false,"key":"ControlLeft","note":"","pointerId":2,"posX":839,"posY":647,"rangeOrTime":80,"type":"TriggerWhenPressedSkill"},{"directional":false,"key":"M4","note":"","pointerId":2,"posX":952,"posY":636,"rangeOrTime":80,"type":"TriggerWhenPressedSkill"},{"directional":false,"key":"WheelDown","note":"","pointerId":2,"posX":1155,"posY":280,"rangeOrTime":80,"type":"TriggerWhenPressedSkill"},{"key":"Enter","macro":{"down":[{"args":["default",5,1245,280,80],"type":"touch"},{"args":[150],"type":"sleep"},{"args":["default",5,1160,560,80],"type":"touch"},{"args":[1],"type":"input-text"}],"loop":null,"up":null},"note":"聊天","posX":1244,"posY":281,"type":"Macro"}],"relativeSize":{"h":720,"w":1280},"title":"AVD-王者荣耀-三技能-导入默认"},
|
||||||
{"title":"AVD-王者荣耀-标准四技能-导入默认","relativeSize":{"h":720,"w":1280},"list":[{"key":{"down":"KeyS","left":"KeyA","right":"KeyD","up":"KeyW"},"note":"方向轮盘","offset":175,"pointerId":1,"posX":183,"posY":566,"type":"SteeringWheel"},{"key":"KeyQ","note":"技能1","pointerId":2,"posX":952,"posY":636,"range":50,"type":"DirectionalSkill"},{"key":"KeyE","note":"技能2","pointerId":2,"posX":979,"posY":526,"range":50,"type":"DirectionalSkill"},{"key":"AltLeft","note":"技能3","pointerId":2,"posX":1074,"posY":438,"range":50,"type":"DirectionalSkill"},{"key":"Space","note":"取消技能","pointerId":2,"posX":1160,"posY":140,"type":"CancelSkill"},{"key":"KeyB","note":"回城","pointerId":3,"posX":644,"posY":650,"time":80,"type":"Tap"},{"key":"KeyC","note":"回复","pointerId":3,"posX":742,"posY":650,"time":80,"type":"Tap"},{"key":"KeyF","note":"召唤师技能","pointerId":2,"posX":838,"posY":647,"range":50,"type":"DirectionalSkill"},{"key":"M2","note":"攻击","pointerId":3,"posX":1179,"posY":621,"time":80,"type":"Tap"},{"key":"Digit1","note":"技能1升级","pointerId":3,"posX":895,"posY":564,"time":80,"type":"Tap"},{"key":"Digit2","note":"技能2升级","pointerId":3,"posX":922,"posY":456,"time":80,"type":"Tap"},{"key":"Digit3","note":"技能3升级","pointerId":3,"posX":1015,"posY":376,"time":80,"type":"Tap"},{"key":"Digit5","note":"快速购买1","pointerId":3,"posX":133,"posY":289,"time":80,"type":"Tap"},{"key":"Digit6","note":"快速购买2","pointerId":3,"posX":130,"posY":370,"time":80,"type":"Tap"},{"key":"M3","note":"观察","pointerId":4,"posX":1000,"posY":200,"scale":1,"type":"Observation"},{"key":"Tab","macro":{"down":[{"args":["default",5,1185,40,80],"type":"touch"}],"loop":null,"up":[{"args":["default",5,1220,100,80],"type":"touch"}]},"note":"战绩面板","pointerId":5,"posX":1185,"posY":40,"type":"Macro"},{"key":"ShiftLeft","macro":{"down":[{"args":["default",5,40,300,80],"type":"touch"}],"loop":null,"up":[{"args":["default",5,1200,60,80],"type":"touch"}]},"note":"商店","pointerId":5,"posX":44,"posY":302,"type":"Macro"},{"key":"KeyZ","macro":{"down":[{"args":["default",5,250,230,80],"type":"touch"}],"loop":null,"up":[{"args":["default",5,640,150,80],"type":"touch"}]},"note":"地图","pointerId":5,"posX":250,"posY":230,"type":"Macro"},{"key":"WheelDown","note":"推塔键","pointerId":2,"posX":1225,"posY":514,"time":80,"type":"Tap"},{"key":"Backquote","macro":{"down":[{"args":["default",5,40,300,80],"type":"touch"},{"args":["200"],"type":"sleep"},{"args":["default",5,510,630,80],"type":"touch"},{"args":["default",5,1165,575,80],"type":"touch"},{"args":["default",5,1200,65,80],"type":"touch"},{"args":["300"],"type":"sleep"},{"args":["default",5,125,300,80],"type":"touch"}],"loop":null,"up":null},"note":"换装2","pointerId":5,"posX":236,"posY":66,"type":"Macro"},{"type":"Tap","key":"WheelUp","note":"补兵键","posX":1058,"posY":655,"pointerId":2,"time":80},{"type":"DirectionalSkill","key":"KeyR","note":"","posX":1189,"posY":422,"pointerId":2,"range":50}]},
|
{"list":[{"key":{"down":"KeyS","left":"KeyA","right":"KeyD","up":"KeyW"},"note":"方向轮盘","offset":175,"pointerId":1,"posX":183,"posY":566,"type":"SteeringWheel"},{"key":"KeyQ","note":"技能1","pointerId":2,"posX":952,"posY":636,"range":50,"type":"DirectionalSkill"},{"key":"AltLeft","note":"技能2","pointerId":2,"posX":979,"posY":526,"range":50,"type":"DirectionalSkill"},{"key":"KeyE","note":"技能3","pointerId":2,"posX":1074,"posY":438,"range":50,"type":"DirectionalSkill"},{"key":"Space","note":"取消技能","pointerId":2,"posX":1160,"posY":140,"type":"CancelSkill"},{"key":"KeyB","note":"回城","pointerId":3,"posX":644,"posY":650,"time":80,"type":"Tap"},{"key":"KeyC","note":"回复","pointerId":3,"posX":742,"posY":650,"time":80,"type":"Tap"},{"key":"KeyF","note":"召唤师技能","pointerId":2,"posX":838,"posY":647,"range":50,"type":"DirectionalSkill"},{"key":"M2","note":"攻击","pointerId":3,"posX":1179,"posY":621,"time":80,"type":"Tap"},{"key":"Digit1","note":"技能1升级","pointerId":3,"posX":895,"posY":564,"time":80,"type":"Tap"},{"key":"Digit2","note":"技能2升级","pointerId":3,"posX":922,"posY":456,"time":80,"type":"Tap"},{"key":"Digit3","note":"技能3升级","pointerId":3,"posX":1015,"posY":376,"time":80,"type":"Tap"},{"key":"Digit5","note":"快速购买1","pointerId":3,"posX":133,"posY":289,"time":80,"type":"Tap"},{"key":"Digit6","note":"快速购买2","pointerId":3,"posX":130,"posY":370,"time":80,"type":"Tap"},{"key":"M3","note":"观察","pointerId":4,"posX":1000,"posY":200,"scale":1,"type":"Observation"},{"key":"Tab","macro":{"down":[{"args":["default",5,1185,40,80],"type":"touch"}],"loop":null,"up":[{"args":["default",5,1220,100,80],"type":"touch"}]},"note":"战绩面板","posX":1185,"posY":40,"type":"Macro"},{"key":"ShiftLeft","macro":{"down":[{"args":["default",5,40,300,80],"type":"touch"}],"loop":null,"up":[{"args":["default",5,1200,60,80],"type":"touch"}]},"note":"商店","posX":44,"posY":302,"type":"Macro"},{"key":"KeyZ","macro":{"down":[{"args":["default",5,250,230,80],"type":"touch"}],"loop":null,"up":[{"args":["default",5,640,150,80],"type":"touch"}]},"note":"地图","posX":250,"posY":230,"type":"Macro"},{"key":"Backquote","macro":{"down":[{"args":["default",5,40,300,80],"type":"touch"},{"args":[150],"type":"sleep"},{"args":["default",5,510,630,80],"type":"touch"},{"args":[150],"type":"sleep"},{"args":["default",5,1165,575,80],"type":"touch"},{"args":["default",5,1200,65,80],"type":"touch"},{"args":[200],"type":"sleep"},{"args":["default",5,125,300,80],"type":"touch"}],"loop":null,"up":null},"note":"换装2","posX":236,"posY":66,"type":"Macro"},{"key":"WheelDown","note":"","pointerId":2,"posX":1189,"posY":422,"range":50,"type":"DirectionalSkill"},{"directional":false,"key":"M4","note":"","pointerId":2,"posX":951,"posY":636,"rangeOrTime":80,"type":"TriggerWhenPressedSkill"},{"type":"Macro","key":"Enter","note":"聊天","posX":1250,"posY":307,"macro":{"down":[{"args":["default",5,1245,280,80],"type":"touch"},{"args":[150],"type":"sleep"},{"args":["default",5,1160,560,80],"type":"touch"},{"args":[1],"type":"input-text"}],"loop":null,"up":null}},{"type":"TriggerWhenPressedSkill","key":"WheelUp","note":"装备技能","posX":1157,"posY":276,"pointerId":2,"directional":false,"rangeOrTime":80}],"relativeSize":{"h":720,"w":1280},"title":"AVD-王者荣耀-四技能-导入默认"}
|
||||||
{"title":"AVD-王者荣耀-暃-导入默认","list":[{"key":{"down":"KeyS","left":"KeyA","right":"KeyD","up":"KeyW"},"note":"方向轮盘","offset":175,"pointerId":1,"posX":183,"posY":566,"type":"SteeringWheel"},{"key":"KeyQ","note":"技能1","pointerId":2,"posX":951,"posY":636,"range":50,"type":"DirectionalSkill"},{"key":"AltLeft","note":"技能2","pointerId":2,"posX":1025,"posY":500,"range":100,"type":"DirectionalSkill"},{"key":"KeyE","note":"技能3","pointerId":2,"posX":1160,"posY":420,"range":0,"type":"DirectionalSkill"},{"directional":false,"key":"WheelUp","note":"无方向装备技能","pointerId":2,"posX":1154,"posY":279,"rangeOrTime":80,"type":"TriggerWhenPressedSkill"},{"key":"Space","note":"取消技能","pointerId":2,"posX":1160,"posY":140,"type":"CancelSkill"},{"key":"KeyB","note":"回城","pointerId":3,"posX":650,"posY":650,"time":80,"type":"Tap"},{"key":"KeyC","note":"回复","pointerId":3,"posX":740,"posY":650,"time":80,"type":"Tap"},{"key":"KeyF","note":"召唤师技能","pointerId":2,"posX":840,"posY":650,"range":50,"type":"DirectionalSkill"},{"directional":false,"key":"ControlLeft","note":"无方向召唤师技能","pointerId":3,"posX":840,"posY":650,"rangeOrTime":80,"type":"TriggerWhenPressedSkill"},{"key":"M2","note":"攻击","pointerId":3,"posX":1165,"posY":616,"time":80,"type":"Tap"},{"key":"Digit1","note":"技能1升级","pointerId":3,"posX":880,"posY":560,"time":80,"type":"Tap"},{"key":"Digit2","note":"技能2升级","pointerId":3,"posX":960,"posY":430,"time":80,"type":"Tap"},{"key":"Digit3","note":"技能3升级","pointerId":3,"posX":1090,"posY":350,"time":80,"type":"Tap"},{"key":"Digit5","note":"快速购买1","pointerId":3,"posX":130,"posY":300,"time":80,"type":"Tap"},{"key":"Digit6","note":"快速购买2","pointerId":3,"posX":130,"posY":370,"time":80,"type":"Tap"},{"key":"M3","note":"观察","pointerId":4,"posX":1000,"posY":200,"scale":1,"type":"Observation"},{"key":"Tab","macro":{"down":[{"args":["default",5,1185,40,80],"type":"touch"}],"loop":null,"up":[{"args":["default",5,1220,100,80],"type":"touch"}]},"note":"战绩面板","pointerId":5,"posX":1185,"posY":40,"type":"Macro"},{"key":"ShiftLeft","macro":{"down":[{"args":["default",5,40,300,80],"type":"touch"}],"loop":null,"up":[{"args":["default",5,1200,60,80],"type":"touch"}]},"note":"商店","pointerId":5,"posX":44,"posY":302,"type":"Macro"},{"key":"KeyZ","macro":{"down":[{"args":["default",5,250,230,80],"type":"touch"}],"loop":null,"up":[{"args":["default",5,640,150,80],"type":"touch"}]},"note":"地图","pointerId":5,"posX":250,"posY":230,"type":"Macro"},{"directional":false,"key":"M4","note":"技能1","pointerId":2,"posX":949,"posY":635,"rangeOrTime":80,"type":"TriggerWhenPressedSkill"},{"key":"WheelDown","note":"推塔键","pointerId":2,"posX":1212,"posY":519,"time":80,"type":"Tap"},{"key":"Backquote","macro":{"down":[{"args":["default",5,40,300,80],"type":"touch"},{"args":["200"],"type":"sleep"},{"args":["default",5,510,630,80],"type":"touch"},{"args":["default",5,1165,575,80],"type":"touch"},{"args":["default",5,1200,65,80],"type":"touch"},{"args":["300"],"type":"sleep"},{"args":["default",5,125,300,80],"type":"touch"}],"loop":null,"up":null},"note":"换装2","pointerId":5,"posX":236,"posY":66,"type":"Macro"}],"relativeSize":{"h":720,"w":1280}}
|
|
||||||
]
|
]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"productName": "scrcpy-mask",
|
"productName": "scrcpy-mask",
|
||||||
"version": "0.1.7",
|
"version": "0.1.8",
|
||||||
"identifier": "com.akichase.mask",
|
"identifier": "com.akichase.mask",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "pnpm dev",
|
"beforeDevCommand": "pnpm dev",
|
||||||
|
@ -123,4 +123,10 @@ onMounted(async () => {
|
|||||||
.n-scrollbar-content {
|
.n-scrollbar-content {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.n-spin-content,
|
||||||
|
.n-spin-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -68,10 +68,10 @@ onMounted(async () => {
|
|||||||
deviceWaitForMetadataTask?.(payload.deviceName);
|
deviceWaitForMetadataTask?.(payload.deviceName);
|
||||||
break;
|
break;
|
||||||
case "ClipboardChanged":
|
case "ClipboardChanged":
|
||||||
console.log("剪切板变动", payload.clipboard);
|
console.log("ClipboardChanged", payload.clipboard);
|
||||||
break;
|
break;
|
||||||
case "ClipboardSetAck":
|
case "ClipboardSetAck":
|
||||||
console.log("剪切板设置成功", payload.sequence);
|
console.log("ClipboardSetAck", payload.sequence);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.log("Unknown reply", payload);
|
console.log("Unknown reply", payload);
|
||||||
|
@ -1,29 +1,48 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onActivated } from "vue";
|
import { h, nextTick, onActivated, onMounted, ref } from "vue";
|
||||||
import { NDialog, useMessage } from "naive-ui";
|
import { NDialog, NInput, useDialog, useMessage } from "naive-ui";
|
||||||
import { useGlobalStore } from "../store/global";
|
import { useGlobalStore } from "../store/global";
|
||||||
import { onBeforeRouteLeave, useRouter } from "vue-router";
|
import { onBeforeRouteLeave, useRouter } from "vue-router";
|
||||||
import {
|
import {
|
||||||
applyShortcuts,
|
applyShortcuts,
|
||||||
clearShortcuts,
|
clearShortcuts,
|
||||||
listenToKeyEvent,
|
listenToEvent,
|
||||||
unlistenToKeyEvent,
|
unlistenToEvent,
|
||||||
updateScreenSizeAndMaskArea,
|
updateScreenSizeAndMaskArea,
|
||||||
} from "../hotkey";
|
} from "../hotkey";
|
||||||
import { KeySteeringWheel } from "../keyMappingConfig";
|
import { KeySteeringWheel } from "../keyMappingConfig";
|
||||||
|
import { getVersion } from "@tauri-apps/api/app";
|
||||||
|
import { fetch } from "@tauri-apps/plugin-http";
|
||||||
|
import { open } from "@tauri-apps/plugin-shell";
|
||||||
|
import {
|
||||||
|
sendInjectKeycode,
|
||||||
|
sendSetClipboard,
|
||||||
|
} from "../frontcommand/controlMsg";
|
||||||
|
import { getCurrent, PhysicalSize } from "@tauri-apps/api/window";
|
||||||
|
import {
|
||||||
|
AndroidKeyEventAction,
|
||||||
|
AndroidKeycode,
|
||||||
|
AndroidMetastate,
|
||||||
|
} from "../frontcommand/android";
|
||||||
|
|
||||||
const store = useGlobalStore();
|
const store = useGlobalStore();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const message = useMessage();
|
const message = useMessage();
|
||||||
|
const dialog = useDialog();
|
||||||
|
|
||||||
|
const showInputBoxRef = ref(false);
|
||||||
|
const inputBoxVal = ref("");
|
||||||
|
const inputInstRef = ref<HTMLInputElement | null>(null);
|
||||||
|
|
||||||
onBeforeRouteLeave(() => {
|
onBeforeRouteLeave(() => {
|
||||||
if (store.controledDevice) {
|
if (store.controledDevice) {
|
||||||
unlistenToKeyEvent();
|
unlistenToEvent();
|
||||||
clearShortcuts();
|
clearShortcuts();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onActivated(async () => {
|
onActivated(async () => {
|
||||||
|
cleanAfterimage();
|
||||||
const maskElement = document.getElementById("maskElement") as HTMLElement;
|
const maskElement = document.getElementById("maskElement") as HTMLElement;
|
||||||
|
|
||||||
if (store.controledDevice) {
|
if (store.controledDevice) {
|
||||||
@ -38,16 +57,137 @@ onActivated(async () => {
|
|||||||
store.keyMappingConfigList[store.curKeyMappingIndex]
|
store.keyMappingConfigList[store.curKeyMappingIndex]
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
listenToKeyEvent();
|
listenToEvent();
|
||||||
} else {
|
} else {
|
||||||
message.error("按键方案异常,请删除此方案");
|
message.error("按键方案异常,请删除此方案");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
store.checkUpdate = checkUpdate;
|
||||||
|
checkUpdate();
|
||||||
|
store.showInputBox = showInputBox;
|
||||||
|
});
|
||||||
|
|
||||||
|
async function cleanAfterimage() {
|
||||||
|
const appWindow = getCurrent();
|
||||||
|
const oldSize = await appWindow.outerSize();
|
||||||
|
const newSize = new PhysicalSize(oldSize.width, oldSize.height + 1);
|
||||||
|
await appWindow.setSize(newSize);
|
||||||
|
await appWindow.setSize(oldSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleInputBoxClick(event: MouseEvent) {
|
||||||
|
if (event.target === document.getElementById("input-box")) {
|
||||||
|
showInputBox(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleInputKeyUp(event: KeyboardEvent) {
|
||||||
|
if (event.key === "Enter") {
|
||||||
|
pasteText();
|
||||||
|
} else if (event.key === "Escape") {
|
||||||
|
showInputBox(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showInputBox(flag: boolean) {
|
||||||
|
if (flag) {
|
||||||
|
unlistenToEvent();
|
||||||
|
inputBoxVal.value = "";
|
||||||
|
showInputBoxRef.value = true;
|
||||||
|
document.addEventListener("keyup", handleInputKeyUp);
|
||||||
|
nextTick(() => {
|
||||||
|
inputInstRef.value?.focus();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
document.removeEventListener("keyup", handleInputKeyUp);
|
||||||
|
inputInstRef.value?.blur();
|
||||||
|
showInputBoxRef.value = false;
|
||||||
|
listenToEvent();
|
||||||
|
nextTick(() => {
|
||||||
|
cleanAfterimage();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sleep(time: number) {
|
||||||
|
return new Promise<void>((resolve) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve();
|
||||||
|
}, time);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function pasteText() {
|
||||||
|
showInputBox(false);
|
||||||
|
if (!inputBoxVal.value) return;
|
||||||
|
sendSetClipboard({
|
||||||
|
sequence: new Date().getTime() % 100000,
|
||||||
|
text: inputBoxVal.value,
|
||||||
|
paste: true,
|
||||||
|
});
|
||||||
|
await sleep(300);
|
||||||
|
// send enter
|
||||||
|
await sendInjectKeycode({
|
||||||
|
action: AndroidKeyEventAction.AKEY_EVENT_ACTION_DOWN,
|
||||||
|
keycode: AndroidKeycode.AKEYCODE_ENTER,
|
||||||
|
repeat: 0,
|
||||||
|
metastate: AndroidMetastate.AMETA_NONE,
|
||||||
|
});
|
||||||
|
await sleep(50);
|
||||||
|
await sendInjectKeycode({
|
||||||
|
action: AndroidKeyEventAction.AKEY_EVENT_ACTION_UP,
|
||||||
|
keycode: AndroidKeycode.AKEYCODE_ENTER,
|
||||||
|
repeat: 0,
|
||||||
|
metastate: AndroidMetastate.AMETA_NONE,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function toStartServer() {
|
function toStartServer() {
|
||||||
router.replace({ name: "device" });
|
router.replace({ name: "device" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderUpdateInfo(content: string) {
|
||||||
|
const pList = content.split("\r\n").map((line: string) => h("p", line));
|
||||||
|
return h("div", { style: "margin: 20px 0" }, pList);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function checkUpdate() {
|
||||||
|
try {
|
||||||
|
const curVersion = await getVersion();
|
||||||
|
const res = await fetch(
|
||||||
|
"https://api.github.com/repos/AkiChase/scrcpy-mask/releases/latest",
|
||||||
|
{
|
||||||
|
connectTimeout: 5000,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.status !== 200) {
|
||||||
|
message.error("检查更新失败");
|
||||||
|
} else {
|
||||||
|
const data = await res.json();
|
||||||
|
const latestVersion = (data.tag_name as string).slice(1);
|
||||||
|
if (latestVersion <= curVersion) {
|
||||||
|
message.success(`最新版本: ${latestVersion},当前已是最新版本`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const body = data.body as string;
|
||||||
|
dialog.info({
|
||||||
|
title: `最新版本:${data.tag_name}`,
|
||||||
|
content: () => renderUpdateInfo(body),
|
||||||
|
positiveText: "前往发布页",
|
||||||
|
negativeText: "取消",
|
||||||
|
onPositiveClick: () => {
|
||||||
|
open(data.html_url);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
message.error("检查更新失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -65,6 +205,19 @@ function toStartServer() {
|
|||||||
</div>
|
</div>
|
||||||
<template v-if="store.keyMappingConfigList.length">
|
<template v-if="store.keyMappingConfigList.length">
|
||||||
<div @contextmenu.prevent class="mask" id="maskElement"></div>
|
<div @contextmenu.prevent class="mask" id="maskElement"></div>
|
||||||
|
<div
|
||||||
|
v-show="showInputBoxRef"
|
||||||
|
class="input-box"
|
||||||
|
id="input-box"
|
||||||
|
@click="handleInputBoxClick"
|
||||||
|
>
|
||||||
|
<NInput
|
||||||
|
ref="inputInstRef"
|
||||||
|
v-model:value="inputBoxVal"
|
||||||
|
type="text"
|
||||||
|
placeholder="Input text and then press enter/esc"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="store.maskButton.show"
|
v-if="store.maskButton.show"
|
||||||
:style="'--transparency: ' + store.maskButton.transparency"
|
:style="'--transparency: ' + store.maskButton.transparency"
|
||||||
@ -125,6 +278,26 @@ function toStartServer() {
|
|||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input-box {
|
||||||
|
z-index: 4;
|
||||||
|
position: absolute;
|
||||||
|
left: 70px;
|
||||||
|
top: 30px;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
|
||||||
|
.n-input {
|
||||||
|
width: 50%;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 15%;
|
||||||
|
margin: auto;
|
||||||
|
background-color: var(--content-bg-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.button-layer {
|
.button-layer {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 70px;
|
left: 70px;
|
||||||
@ -171,7 +344,6 @@ function toStartServer() {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
z-index: 1;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 70px;
|
left: 70px;
|
||||||
top: 30px;
|
top: 30px;
|
||||||
@ -184,3 +356,4 @@ function toStartServer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
h, import { getVersion } from "@tauri-apps/api/app";
|
||||||
|
@ -64,6 +64,15 @@ async function sendKeyCodeToDevice(code: AndroidKeycode) {
|
|||||||
message.error("未连接设备");
|
message.error("未连接设备");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function changeScreenPowerMode() {
|
||||||
|
if (store.controledDevice) {
|
||||||
|
sendSetScreenPowerMode({ mode: nextScreenPowerMode.value });
|
||||||
|
nextScreenPowerMode.value = nextScreenPowerMode.value ? 0 : 2;
|
||||||
|
} else {
|
||||||
|
message.error("未连接设备");
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -96,12 +105,7 @@ async function sendKeyCodeToDevice(code: AndroidKeycode) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="nav">
|
<div class="nav">
|
||||||
<div
|
<div @click="changeScreenPowerMode">
|
||||||
@click="
|
|
||||||
sendSetScreenPowerMode({ mode: nextScreenPowerMode });
|
|
||||||
nextScreenPowerMode = nextScreenPowerMode ? 0 : 2;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<NIcon>
|
<NIcon>
|
||||||
<Bulb v-if="nextScreenPowerMode" />
|
<Bulb v-if="nextScreenPowerMode" />
|
||||||
<BulbOutline v-else />
|
<BulbOutline v-else />
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
KeyObservation as KeyMappingObservation,
|
KeyObservation as KeyMappingObservation,
|
||||||
KeyTap,
|
KeyTap,
|
||||||
KeyMacro,
|
KeyMacro,
|
||||||
|
KeyMapping,
|
||||||
} from "../../keyMappingConfig";
|
} from "../../keyMappingConfig";
|
||||||
import { useGlobalStore } from "../../store/global";
|
import { useGlobalStore } from "../../store/global";
|
||||||
import { DropdownOption, NDropdown, useDialog, useMessage } from "naive-ui";
|
import { DropdownOption, NDropdown, useDialog, useMessage } from "naive-ui";
|
||||||
@ -73,10 +74,10 @@ function onAddButtonSelect(
|
|||||||
(keyMapping as KeyTap).time = 80;
|
(keyMapping as KeyTap).time = 80;
|
||||||
} else if (type === "SteeringWheel") {
|
} else if (type === "SteeringWheel") {
|
||||||
(keyMapping as unknown as KeyMappingSteeringWheel).key = {
|
(keyMapping as unknown as KeyMappingSteeringWheel).key = {
|
||||||
left: "NONE",
|
left: "NONE1",
|
||||||
right: "NONE",
|
right: "NONE2",
|
||||||
up: "NONE",
|
up: "NONE3",
|
||||||
down: "NONE",
|
down: "NONE4",
|
||||||
};
|
};
|
||||||
(keyMapping as unknown as KeyMappingSteeringWheel).offset = 100;
|
(keyMapping as unknown as KeyMappingSteeringWheel).offset = 100;
|
||||||
} else if (type === "DirectionalSkill") {
|
} else if (type === "DirectionalSkill") {
|
||||||
@ -91,9 +92,10 @@ function onAddButtonSelect(
|
|||||||
loop: null,
|
loop: null,
|
||||||
up: null,
|
up: null,
|
||||||
};
|
};
|
||||||
|
delete (keyMapping as any).pointerId;
|
||||||
} else return;
|
} else return;
|
||||||
keyboardStore.edited = true;
|
keyboardStore.edited = true;
|
||||||
store.editKeyMappingList.push(keyMapping);
|
store.editKeyMappingList.push(keyMapping as KeyMapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isKeyUnique(curKey: string): boolean {
|
function isKeyUnique(curKey: string): boolean {
|
||||||
|
@ -14,7 +14,7 @@ import {
|
|||||||
NInputNumber,
|
NInputNumber,
|
||||||
} from "naive-ui";
|
} from "naive-ui";
|
||||||
import { CloseCircle, Settings } from "@vicons/ionicons5";
|
import { CloseCircle, Settings } from "@vicons/ionicons5";
|
||||||
import { KeyMacro, KeyMacroList, KeyTap } from "../../keyMappingConfig";
|
import { KeyCommon, KeyMacro, KeyMacroList } from "../../keyMappingConfig";
|
||||||
import { useKeyboardStore } from "../../store/keyboard";
|
import { useKeyboardStore } from "../../store/keyboard";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
@ -30,7 +30,9 @@ const elementRef = ref<HTMLElement | null>(null);
|
|||||||
const isActive = computed(
|
const isActive = computed(
|
||||||
() => props.index === keyboardStore.activeButtonIndex
|
() => props.index === keyboardStore.activeButtonIndex
|
||||||
);
|
);
|
||||||
const keyMapping = computed(() => store.editKeyMappingList[props.index]);
|
const keyMapping = computed(
|
||||||
|
() => store.editKeyMappingList[props.index] as KeyCommon
|
||||||
|
);
|
||||||
|
|
||||||
const showMacroModal = ref(false);
|
const showMacroModal = ref(false);
|
||||||
const editedMacroRaw = ref({
|
const editedMacroRaw = ref({
|
||||||
@ -216,13 +218,13 @@ function showSetting() {
|
|||||||
</NFormItem>
|
</NFormItem>
|
||||||
<NFormItem v-if="keyMapping.type === 'Tap'" label="触摸时长">
|
<NFormItem v-if="keyMapping.type === 'Tap'" label="触摸时长">
|
||||||
<NInputNumber
|
<NInputNumber
|
||||||
v-model:value="(keyMapping as KeyTap).time"
|
v-model:value="keyMapping.time"
|
||||||
:min="0"
|
:min="0"
|
||||||
placeholder="请输入触摸时长(ms)"
|
placeholder="请输入触摸时长(ms)"
|
||||||
@update:value="keyboardStore.edited = true"
|
@update:value="keyboardStore.edited = true"
|
||||||
/>
|
/>
|
||||||
</NFormItem>
|
</NFormItem>
|
||||||
<NFormItem label="触点ID">
|
<NFormItem v-if="keyMapping.type !== 'Macro'" label="触点ID">
|
||||||
<NInputNumber
|
<NInputNumber
|
||||||
v-model:value="keyMapping.pointerId"
|
v-model:value="keyMapping.pointerId"
|
||||||
:min="0"
|
:min="0"
|
||||||
|
@ -14,7 +14,7 @@ import {
|
|||||||
} from "naive-ui";
|
} from "naive-ui";
|
||||||
import {
|
import {
|
||||||
KeyDirectionalSkill,
|
KeyDirectionalSkill,
|
||||||
KeyTriggerWhenDoublePressedSkill,
|
KeySkill,
|
||||||
KeyTriggerWhenPressedSkill,
|
KeyTriggerWhenPressedSkill,
|
||||||
} from "../../keyMappingConfig";
|
} from "../../keyMappingConfig";
|
||||||
import { useKeyboardStore } from "../../store/keyboard";
|
import { useKeyboardStore } from "../../store/keyboard";
|
||||||
@ -31,7 +31,9 @@ const elementRef = ref<HTMLElement | null>(null);
|
|||||||
const isActive = computed(
|
const isActive = computed(
|
||||||
() => props.index === keyboardStore.activeButtonIndex
|
() => props.index === keyboardStore.activeButtonIndex
|
||||||
);
|
);
|
||||||
const keyMapping = computed(() => store.editKeyMappingList[props.index]);
|
const keyMapping = computed(
|
||||||
|
() => store.editKeyMappingList[props.index] as KeySkill
|
||||||
|
);
|
||||||
|
|
||||||
function dragHandler(downEvent: MouseEvent) {
|
function dragHandler(downEvent: MouseEvent) {
|
||||||
keyboardStore.activeButtonIndex = props.index;
|
keyboardStore.activeButtonIndex = props.index;
|
||||||
@ -97,12 +99,14 @@ function changeSkillType(flag: string) {
|
|||||||
keyboardStore.edited = true;
|
keyboardStore.edited = true;
|
||||||
if (t === "DirectionalSkill") {
|
if (t === "DirectionalSkill") {
|
||||||
// to DirectionlessSkill
|
// to DirectionlessSkill
|
||||||
delete (keyMapping.value as any).range;
|
const k = keyMapping.value as any;
|
||||||
keyMapping.value.type = "DirectionlessSkill";
|
delete k.range;
|
||||||
|
k.type = "DirectionlessSkill";
|
||||||
} else if (t === "DirectionlessSkill") {
|
} else if (t === "DirectionlessSkill") {
|
||||||
// to DirectionalSkill
|
// to DirectionalSkill
|
||||||
(keyMapping.value as any).range = 0;
|
const k = keyMapping.value as any;
|
||||||
keyMapping.value.type = "DirectionalSkill";
|
k.range = 0;
|
||||||
|
k.type = "DirectionalSkill";
|
||||||
} else if (t === "TriggerWhenPressedSkill") {
|
} else if (t === "TriggerWhenPressedSkill") {
|
||||||
// change directional flag
|
// change directional flag
|
||||||
const k = keyMapping.value as KeyTriggerWhenPressedSkill;
|
const k = keyMapping.value as KeyTriggerWhenPressedSkill;
|
||||||
@ -110,8 +114,9 @@ function changeSkillType(flag: string) {
|
|||||||
k.rangeOrTime = k.directional ? 0 : 80;
|
k.rangeOrTime = k.directional ? 0 : 80;
|
||||||
} else if (t === "TriggerWhenDoublePressedSkill") {
|
} else if (t === "TriggerWhenDoublePressedSkill") {
|
||||||
// to DirectionlessSkill
|
// to DirectionlessSkill
|
||||||
delete (keyMapping.value as any).range;
|
const k = keyMapping.value as any;
|
||||||
keyMapping.value.type = "DirectionlessSkill";
|
delete k.range;
|
||||||
|
k.type = "DirectionlessSkill";
|
||||||
}
|
}
|
||||||
} else if (flag === "trigger") {
|
} else if (flag === "trigger") {
|
||||||
keyboardStore.edited = true;
|
keyboardStore.edited = true;
|
||||||
@ -278,7 +283,7 @@ function updateRangeIndicator(element?: HTMLElement) {
|
|||||||
<NFormItem v-if="!isDirectionless" label="范围">
|
<NFormItem v-if="!isDirectionless" label="范围">
|
||||||
<NInputNumber
|
<NInputNumber
|
||||||
v-if="keyMapping.type === 'DirectionalSkill'"
|
v-if="keyMapping.type === 'DirectionalSkill'"
|
||||||
v-model:value="(keyMapping as KeyDirectionalSkill).range"
|
v-model:value="keyMapping.range"
|
||||||
placeholder="range"
|
placeholder="range"
|
||||||
:min="0"
|
:min="0"
|
||||||
:max="100"
|
:max="100"
|
||||||
@ -289,7 +294,7 @@ function updateRangeIndicator(element?: HTMLElement) {
|
|||||||
/>
|
/>
|
||||||
<NInputNumber
|
<NInputNumber
|
||||||
v-else-if="keyMapping.type === 'TriggerWhenPressedSkill'"
|
v-else-if="keyMapping.type === 'TriggerWhenPressedSkill'"
|
||||||
v-model:value="(keyMapping as KeyTriggerWhenPressedSkill).rangeOrTime"
|
v-model:value="keyMapping.rangeOrTime"
|
||||||
placeholder="rangeOrTime"
|
placeholder="rangeOrTime"
|
||||||
:min="0"
|
:min="0"
|
||||||
:max="100"
|
:max="100"
|
||||||
@ -300,7 +305,7 @@ function updateRangeIndicator(element?: HTMLElement) {
|
|||||||
/>
|
/>
|
||||||
<NInputNumber
|
<NInputNumber
|
||||||
v-else-if="keyMapping.type === 'TriggerWhenDoublePressedSkill'"
|
v-else-if="keyMapping.type === 'TriggerWhenDoublePressedSkill'"
|
||||||
v-model:value="(keyMapping as KeyTriggerWhenDoublePressedSkill).range"
|
v-model:value="keyMapping.range"
|
||||||
placeholder="range"
|
placeholder="range"
|
||||||
:min="0"
|
:min="0"
|
||||||
:max="100"
|
:max="100"
|
||||||
@ -315,7 +320,7 @@ function updateRangeIndicator(element?: HTMLElement) {
|
|||||||
label="触摸时长"
|
label="触摸时长"
|
||||||
>
|
>
|
||||||
<NInputNumber
|
<NInputNumber
|
||||||
v-model:value="(keyMapping as KeyTriggerWhenPressedSkill).rangeOrTime"
|
v-model:value="keyMapping.rangeOrTime"
|
||||||
:min="0"
|
:min="0"
|
||||||
placeholder="请输入触摸时长(ms)"
|
placeholder="请输入触摸时长(ms)"
|
||||||
@update:value="keyboardStore.edited = true"
|
@update:value="keyboardStore.edited = true"
|
||||||
|
@ -28,11 +28,8 @@ const offset = computed(() => {
|
|||||||
const clientWidth = keyboardElement.clientWidth;
|
const clientWidth = keyboardElement.clientWidth;
|
||||||
const screenSizeW =
|
const screenSizeW =
|
||||||
store.screenSizeW === 0 ? clientWidth : store.screenSizeW;
|
store.screenSizeW === 0 ? clientWidth : store.screenSizeW;
|
||||||
return (
|
return (keyMapping.value.offset * clientWidth) / screenSizeW;
|
||||||
((keyMapping.value as KeySteeringWheel).offset * clientWidth) /
|
} else return keyMapping.value.offset;
|
||||||
screenSizeW
|
|
||||||
);
|
|
||||||
} else return (keyMapping.value as KeySteeringWheel).offset;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function dragHandler(downEvent: MouseEvent) {
|
function dragHandler(downEvent: MouseEvent) {
|
||||||
|
@ -1,22 +1,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {
|
import { NFlex, NH4, NButton, NIcon, NP } from "naive-ui";
|
||||||
NFlex,
|
|
||||||
NH4,
|
|
||||||
NButton,
|
|
||||||
NIcon,
|
|
||||||
NP,
|
|
||||||
useMessage,
|
|
||||||
useDialog,
|
|
||||||
} from "naive-ui";
|
|
||||||
import { LogoGithub, Planet } from "@vicons/ionicons5";
|
import { LogoGithub, Planet } from "@vicons/ionicons5";
|
||||||
import { open } from "@tauri-apps/plugin-shell";
|
import { open } from "@tauri-apps/plugin-shell";
|
||||||
import { fetch } from "@tauri-apps/plugin-http";
|
|
||||||
import { getVersion } from "@tauri-apps/api/app";
|
import { getVersion } from "@tauri-apps/api/app";
|
||||||
import { h, onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
import { useGlobalStore } from "../../store/global";
|
import { useGlobalStore } from "../../store/global";
|
||||||
|
|
||||||
const message = useMessage();
|
|
||||||
const dialog = useDialog();
|
|
||||||
const store = useGlobalStore();
|
const store = useGlobalStore();
|
||||||
|
|
||||||
const appVersion = ref("");
|
const appVersion = ref("");
|
||||||
@ -28,46 +17,10 @@ function opendWebsite(url: string) {
|
|||||||
open(url);
|
open(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderUpdateInfo(content: string) {
|
|
||||||
const pList = content.split("\r\n").map((line: string) => h("p", line));
|
|
||||||
return h("div", { style: "margin: 20px 0" }, pList);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function checkUpdate() {
|
async function checkUpdate() {
|
||||||
store.showLoading();
|
store.showLoading();
|
||||||
try {
|
await store.checkUpdate();
|
||||||
const res = await fetch(
|
store.hideLoading();
|
||||||
"https://api.github.com/repos/AkiChase/scrcpy-mask/releases/latest",
|
|
||||||
{
|
|
||||||
connectTimeout: 5000,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
store.hideLoading();
|
|
||||||
if (res.status !== 200) {
|
|
||||||
message.error("检查更新失败");
|
|
||||||
} else {
|
|
||||||
const data = await res.json();
|
|
||||||
const latestVersion = (data.tag_name as string).slice(1);
|
|
||||||
if (latestVersion <= appVersion.value) {
|
|
||||||
message.success(`最新版本: ${latestVersion},当前已是最新版本`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const body = data.body as string;
|
|
||||||
dialog.info({
|
|
||||||
title: `最新版本:${data.tag_name}`,
|
|
||||||
content: () => renderUpdateInfo(body),
|
|
||||||
positiveText: "前往发布页",
|
|
||||||
negativeText: "取消",
|
|
||||||
onPositiveClick: () => {
|
|
||||||
opendWebsite(data.html_url);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
store.hideLoading();
|
|
||||||
console.error(e);
|
|
||||||
message.error("检查更新失败");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -3,33 +3,38 @@ import Basic from "./Basic.vue";
|
|||||||
import Script from "./Script.vue";
|
import Script from "./Script.vue";
|
||||||
import Mask from "./Mask.vue";
|
import Mask from "./Mask.vue";
|
||||||
import About from "./About.vue";
|
import About from "./About.vue";
|
||||||
import { NTabs, NTabPane, NScrollbar } from "naive-ui";
|
import { NTabs, NTabPane, NScrollbar, NSpin } from "naive-ui";
|
||||||
|
import { useGlobalStore } from "../../store/global";
|
||||||
|
|
||||||
|
const store = useGlobalStore();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="setting">
|
<div class="setting">
|
||||||
<NTabs type="line" animated placement="left" default-value="basic">
|
<NSpin :show="store.showLoadingRef">
|
||||||
<NTabPane tab="基本设置" name="basic">
|
<NTabs type="line" animated placement="left" default-value="basic">
|
||||||
<NScrollbar>
|
<NTabPane tab="基本设置" name="basic">
|
||||||
<Basic />
|
<NScrollbar>
|
||||||
</NScrollbar>
|
<Basic />
|
||||||
</NTabPane>
|
</NScrollbar>
|
||||||
<NTabPane tab="蒙版设置" name="mask">
|
</NTabPane>
|
||||||
<NScrollbar>
|
<NTabPane tab="蒙版设置" name="mask">
|
||||||
<Mask />
|
<NScrollbar>
|
||||||
</NScrollbar>
|
<Mask />
|
||||||
</NTabPane>
|
</NScrollbar>
|
||||||
<NTabPane tab="脚本设置" name="script">
|
</NTabPane>
|
||||||
<NScrollbar>
|
<NTabPane tab="脚本设置" name="script">
|
||||||
<Script />
|
<NScrollbar>
|
||||||
</NScrollbar>
|
<Script />
|
||||||
</NTabPane>
|
</NScrollbar>
|
||||||
<NTabPane tab="关于" name="about">
|
</NTabPane>
|
||||||
<NScrollbar>
|
<NTabPane tab="关于" name="about">
|
||||||
<About />
|
<NScrollbar>
|
||||||
</NScrollbar>
|
<About />
|
||||||
</NTabPane>
|
</NScrollbar>
|
||||||
</NTabs>
|
</NTabPane>
|
||||||
|
</NTabs>
|
||||||
|
</NSpin>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -41,6 +46,10 @@ import { NTabs, NTabPane, NScrollbar } from "naive-ui";
|
|||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
|
.n-tabs{
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.n-tab-pane {
|
.n-tab-pane {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
KeyTriggerWhenDoublePressedSkill,
|
KeyTriggerWhenDoublePressedSkill,
|
||||||
KeyTriggerWhenPressedSkill,
|
KeyTriggerWhenPressedSkill,
|
||||||
} from "./keyMappingConfig";
|
} from "./keyMappingConfig";
|
||||||
|
import { useGlobalStore } from "./store/global";
|
||||||
|
|
||||||
function clientxToPosx(clientx: number) {
|
function clientxToPosx(clientx: number) {
|
||||||
return clientx < 70
|
return clientx < 70
|
||||||
@ -948,6 +949,12 @@ function addShortcut(
|
|||||||
* 1000,
|
* 1000,
|
||||||
* ],
|
* ],
|
||||||
* },
|
* },
|
||||||
|
* // input-text
|
||||||
|
* {
|
||||||
|
* type: "input-text",
|
||||||
|
* // 1:on, 2:off
|
||||||
|
* args: [1]
|
||||||
|
* }
|
||||||
* ]);
|
* ]);
|
||||||
*/
|
*/
|
||||||
async function execMacro(
|
async function execMacro(
|
||||||
@ -1025,6 +1032,15 @@ async function execMacro(
|
|||||||
intervalBetweenPos: cmd.args[3],
|
intervalBetweenPos: cmd.args[3],
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case "input-text":
|
||||||
|
if (cmd.args[0] === 1) {
|
||||||
|
// on
|
||||||
|
useGlobalStore().showInputBox(true);
|
||||||
|
} else {
|
||||||
|
// off
|
||||||
|
useGlobalStore().showInputBox(false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
console.error("Invalid command: ", cmd);
|
console.error("Invalid command: ", cmd);
|
||||||
return;
|
return;
|
||||||
@ -1163,7 +1179,7 @@ function applyKeyMappingConfigShortcuts(
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.error("Invalid item type: ", item.type);
|
console.error("Invalid item type: ", item);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1175,25 +1191,29 @@ function applyKeyMappingConfigShortcuts(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function listenToKeyEvent() {
|
export function listenToEvent() {
|
||||||
window.addEventListener("keydown", keydownHandler);
|
window.addEventListener("keydown", keydownHandler);
|
||||||
window.addEventListener("keyup", keyupHandler);
|
window.addEventListener("keyup", keyupHandler);
|
||||||
|
window.addEventListener("mousedown", handleMouseDown);
|
||||||
|
window.addEventListener("mousemove", handleMouseMove);
|
||||||
|
window.addEventListener("mouseup", handleMouseUp);
|
||||||
|
window.addEventListener("wheel", handleMouseWheel);
|
||||||
loopFlag = true;
|
loopFlag = true;
|
||||||
execLoopCB();
|
execLoopCB();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function unlistenToKeyEvent() {
|
export function unlistenToEvent() {
|
||||||
window.removeEventListener("keydown", keydownHandler);
|
window.removeEventListener("keydown", keydownHandler);
|
||||||
window.removeEventListener("keyup", keyupHandler);
|
window.removeEventListener("keyup", keyupHandler);
|
||||||
loopFlag = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function clearShortcuts() {
|
|
||||||
window.removeEventListener("mousedown", handleMouseDown);
|
window.removeEventListener("mousedown", handleMouseDown);
|
||||||
window.removeEventListener("mousemove", handleMouseMove);
|
window.removeEventListener("mousemove", handleMouseMove);
|
||||||
window.removeEventListener("mouseup", handleMouseUp);
|
window.removeEventListener("mouseup", handleMouseUp);
|
||||||
window.removeEventListener("wheel", handleMouseWheel);
|
window.removeEventListener("wheel", handleMouseWheel);
|
||||||
|
|
||||||
|
loopFlag = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clearShortcuts() {
|
||||||
downKeyMap.clear();
|
downKeyMap.clear();
|
||||||
downKeyCBMap.clear();
|
downKeyCBMap.clear();
|
||||||
loopDownKeyCBMap.clear();
|
loopDownKeyCBMap.clear();
|
||||||
@ -1216,11 +1236,6 @@ export function applyShortcuts(
|
|||||||
keyMappingConfig: KeyMappingConfig
|
keyMappingConfig: KeyMappingConfig
|
||||||
) {
|
) {
|
||||||
maskElement = element;
|
maskElement = element;
|
||||||
window.addEventListener("mousedown", handleMouseDown);
|
|
||||||
window.addEventListener("mousemove", handleMouseMove);
|
|
||||||
window.addEventListener("mouseup", handleMouseUp);
|
|
||||||
window.addEventListener("wheel", handleMouseWheel);
|
|
||||||
|
|
||||||
addClickShortcuts("M0", 0);
|
addClickShortcuts("M0", 0);
|
||||||
return applyKeyMappingConfigShortcuts(keyMappingConfig);
|
return applyKeyMappingConfigShortcuts(keyMappingConfig);
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,12 @@
|
|||||||
interface Key {
|
interface KeyBase {
|
||||||
type:
|
|
||||||
| "SteeringWheel"
|
|
||||||
| "DirectionalSkill"
|
|
||||||
| "DirectionlessSkill"
|
|
||||||
| "CancelSkill"
|
|
||||||
| "Tap"
|
|
||||||
| "TriggerWhenPressedSkill"
|
|
||||||
| "TriggerWhenDoublePressedSkill"
|
|
||||||
| "Observation"
|
|
||||||
| "Macro";
|
|
||||||
note: string;
|
note: string;
|
||||||
posX: number;
|
posX: number;
|
||||||
posY: number;
|
posY: number;
|
||||||
pointerId: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface KeySteeringWheel extends Key {
|
export interface KeySteeringWheel extends KeyBase {
|
||||||
|
type: "SteeringWheel";
|
||||||
|
pointerId: number;
|
||||||
key: {
|
key: {
|
||||||
left: string;
|
left: string;
|
||||||
right: string;
|
right: string;
|
||||||
@ -25,48 +16,61 @@ interface KeySteeringWheel extends Key {
|
|||||||
offset: number;
|
offset: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface KeyDirectionalSkill extends Key {
|
export interface KeyDirectionalSkill extends KeyBase {
|
||||||
|
type: "DirectionalSkill";
|
||||||
|
pointerId: number;
|
||||||
key: string;
|
key: string;
|
||||||
range: number;
|
range: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface KeyDirectionlessSkill extends Key {
|
export interface KeyDirectionlessSkill extends KeyBase {
|
||||||
|
type: "DirectionlessSkill";
|
||||||
|
pointerId: number;
|
||||||
key: string;
|
key: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface KeyCancelSkill extends Key {
|
export interface KeyCancelSkill extends KeyBase {
|
||||||
|
type: "CancelSkill";
|
||||||
|
pointerId: number;
|
||||||
key: string;
|
key: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface KeyTriggerWhenPressedSkill extends Key {
|
export interface KeyTriggerWhenPressedSkill extends KeyBase {
|
||||||
|
type: "TriggerWhenPressedSkill";
|
||||||
|
pointerId: number;
|
||||||
key: string;
|
key: string;
|
||||||
directional: boolean;
|
directional: boolean;
|
||||||
rangeOrTime: number;
|
rangeOrTime: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface KeyTriggerWhenDoublePressedSkill extends Key {
|
export interface KeyTriggerWhenDoublePressedSkill extends KeyBase {
|
||||||
|
type: "TriggerWhenDoublePressedSkill";
|
||||||
|
pointerId: number;
|
||||||
key: string;
|
key: string;
|
||||||
range: number;
|
range: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface KeyObservation extends Key {
|
export interface KeyObservation extends KeyBase {
|
||||||
|
type: "Observation";
|
||||||
|
pointerId: number;
|
||||||
key: string;
|
key: string;
|
||||||
scale: number;
|
scale: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface KeyTap extends Key {
|
export interface KeyTap extends KeyBase {
|
||||||
|
type: "Tap";
|
||||||
|
pointerId: number;
|
||||||
key: string;
|
key: string;
|
||||||
time: number;
|
time: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeyMacroType = "touch" | "sleep" | "swipe";
|
export type KeyMacroList = Array<{
|
||||||
type KeyMacroArgs = any[];
|
type: "touch" | "sleep" | "swipe" | "input-text";
|
||||||
|
args: any[];
|
||||||
type KeyMacroList = Array<{
|
|
||||||
type: KeyMacroType;
|
|
||||||
args: KeyMacroArgs;
|
|
||||||
}> | null;
|
}> | null;
|
||||||
interface KeyMacro extends Key {
|
|
||||||
|
export interface KeyMacro extends KeyBase {
|
||||||
|
type: "Macro";
|
||||||
key: string;
|
key: string;
|
||||||
macro: {
|
macro: {
|
||||||
down: KeyMacroList;
|
down: KeyMacroList;
|
||||||
@ -75,7 +79,7 @@ interface KeyMacro extends Key {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeyMapping =
|
export type KeyMapping =
|
||||||
| KeySteeringWheel
|
| KeySteeringWheel
|
||||||
| KeyDirectionalSkill
|
| KeyDirectionalSkill
|
||||||
| KeyDirectionlessSkill
|
| KeyDirectionlessSkill
|
||||||
@ -86,23 +90,16 @@ type KeyMapping =
|
|||||||
| KeyCancelSkill
|
| KeyCancelSkill
|
||||||
| KeyTap;
|
| KeyTap;
|
||||||
|
|
||||||
interface KeyMappingConfig {
|
export type KeyCommon = KeyMacro | KeyCancelSkill | KeyTap;
|
||||||
|
|
||||||
|
export type KeySkill =
|
||||||
|
| KeyDirectionalSkill
|
||||||
|
| KeyDirectionlessSkill
|
||||||
|
| KeyTriggerWhenPressedSkill
|
||||||
|
| KeyTriggerWhenDoublePressedSkill;
|
||||||
|
|
||||||
|
export interface KeyMappingConfig {
|
||||||
relativeSize: { w: number; h: number };
|
relativeSize: { w: number; h: number };
|
||||||
title: string;
|
title: string;
|
||||||
list: KeyMapping[];
|
list: KeyMapping[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type {
|
|
||||||
KeyMacroList,
|
|
||||||
KeySteeringWheel,
|
|
||||||
KeyDirectionalSkill,
|
|
||||||
KeyDirectionlessSkill,
|
|
||||||
KeyCancelSkill,
|
|
||||||
KeyTap,
|
|
||||||
KeyTriggerWhenPressedSkill,
|
|
||||||
KeyTriggerWhenDoublePressedSkill,
|
|
||||||
KeyObservation,
|
|
||||||
KeyMacro,
|
|
||||||
KeyMapping,
|
|
||||||
KeyMappingConfig,
|
|
||||||
};
|
|
||||||
|
@ -39,6 +39,10 @@ export const useGlobalStore = defineStore("global", () => {
|
|||||||
show: true,
|
show: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const showInputBox: (_: boolean) => void = (_: boolean) => {};
|
||||||
|
|
||||||
|
let checkUpdate: () => Promise<void> = async () => {};
|
||||||
|
|
||||||
function applyEditKeyMappingList(): boolean {
|
function applyEditKeyMappingList(): boolean {
|
||||||
const set = new Set<string>();
|
const set = new Set<string>();
|
||||||
for (const keyMapping of editKeyMappingList.value) {
|
for (const keyMapping of editKeyMappingList.value) {
|
||||||
@ -88,8 +92,10 @@ export const useGlobalStore = defineStore("global", () => {
|
|||||||
curKeyMappingIndex,
|
curKeyMappingIndex,
|
||||||
editKeyMappingList,
|
editKeyMappingList,
|
||||||
maskButton,
|
maskButton,
|
||||||
|
showInputBox,
|
||||||
applyEditKeyMappingList,
|
applyEditKeyMappingList,
|
||||||
resetEditKeyMappingList,
|
resetEditKeyMappingList,
|
||||||
setKeyMappingIndex,
|
setKeyMappingIndex,
|
||||||
|
checkUpdate,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user