diff --git a/package.json b/package.json index b594c24..aa8755a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "scrcpy-mask", "private": true, - "version": "0.5.0", + "version": "0.6.0", "type": "module", "scripts": { "dev": "vite", @@ -12,6 +12,7 @@ }, "dependencies": { "@tauri-apps/api": ">=2.0.0-beta.8", + "@tauri-apps/plugin-clipboard-manager": "2.1.0-beta.1", "@tauri-apps/plugin-http": "2.0.0-beta.3", "@tauri-apps/plugin-process": "2.0.0-beta.2", "@tauri-apps/plugin-shell": "2.0.0-beta.3", diff --git a/public/favicon.ico b/public/favicon.ico old mode 100755 new mode 100644 index c8e202a..0114806 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 9433407..d7dfcfb 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "scrcpy-mask" -version = "0.5.0" +version = "0.6.0" description = "A Tauri App" authors = ["AkiChase"] edition = "2021" @@ -21,3 +21,4 @@ tokio = { version = "1.36.0", features = ["rt-multi-thread", "net", "macros", "i tauri-plugin-process = "2.0.0-beta" tauri-plugin-shell = "2.0.0-beta" tauri-plugin-http = "2.0.0-beta" +tauri-plugin-clipboard-manager = "2.1.0-beta.2" diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index 8b1ebe9..70abfb6 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -34,11 +34,16 @@ { "identifier": "http:default", "allow": [ - { "url": "https://api.github.com/repos/AkiChase/scrcpy-mask/*" } + { + "url": "https://api.github.com/repos/AkiChase/scrcpy-mask/*" + } ] }, "http:allow-fetch", "app:default", - "app:allow-version" + "app:allow-version", + "clipboard-manager:default", + "clipboard-manager:allow-read-text", + "clipboard-manager:allow-write-text" ] } diff --git a/src-tauri/icons/128x128.png b/src-tauri/icons/128x128.png index 621020f..be5e982 100644 Binary files a/src-tauri/icons/128x128.png and b/src-tauri/icons/128x128.png differ diff --git a/src-tauri/icons/128x128@2x.png b/src-tauri/icons/128x128@2x.png index 8de7083..026a4be 100644 Binary files a/src-tauri/icons/128x128@2x.png and b/src-tauri/icons/128x128@2x.png differ diff --git a/src-tauri/icons/32x32.png b/src-tauri/icons/32x32.png index f8ac917..f6a6380 100644 Binary files a/src-tauri/icons/32x32.png and b/src-tauri/icons/32x32.png differ diff --git a/src-tauri/icons/icon.icns b/src-tauri/icons/icon.icns index 44ddfa0..7f81fac 100644 Binary files a/src-tauri/icons/icon.icns and b/src-tauri/icons/icon.icns differ diff --git a/src-tauri/icons/icon.ico b/src-tauri/icons/icon.ico index 200207d..0114806 100644 Binary files a/src-tauri/icons/icon.ico and b/src-tauri/icons/icon.ico differ diff --git a/src-tauri/icons/icon.png b/src-tauri/icons/icon.png index 4f93623..36a5a7f 100644 Binary files a/src-tauri/icons/icon.png and b/src-tauri/icons/icon.png differ diff --git a/src-tauri/resource/default-key-config.json b/src-tauri/resource/default-key-config.json index e507135..578385f 100644 --- a/src-tauri/resource/default-key-config.json +++ b/src-tauri/resource/default-key-config.json @@ -1,5 +1,6 @@ [ {"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":[],"type":"key-input-mode"}],"loop":null,"up":null},"note":"聊天","posX":1244,"posY":281,"type":"Macro"}],"relativeSize":{"h":720,"w":1280},"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":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":[],"type":"key-input-mode"}],"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-王者荣耀-四技能-导入默认"}, - {"list":[{"key":"Backquote","note":"准星键","pointerId":0,"posX":640,"posY":361,"scaleX":1,"scaleY":1,"type":"Sight"},{"key":{"down":"KeyS","left":"KeyA","right":"KeyD","up":"KeyW"},"note":"","offset":150,"pointerId":1,"posX":208,"posY":542,"type":"SteeringWheel"},{"key":"KeyC","note":"","pointerId":3,"posX":1085,"posY":668,"time":80,"type":"Tap"},{"key":"KeyZ","note":"","pointerId":3,"posX":1207,"posY":648,"time":80,"type":"Tap"},{"key":"Space","note":"","pointerId":3,"posX":1230,"posY":503,"time":80,"type":"Tap"},{"key":"M3","note":"","pointerId":4,"posX":992,"posY":229,"scale":0.6,"type":"Observation"},{"key":"Digit1","note":"","pointerId":3,"posX":543,"posY":642,"time":80,"type":"Tap"},{"key":"Digit2","note":"","pointerId":3,"posX":729,"posY":644,"time":80,"type":"Tap"},{"key":"ShiftLeft","note":"","pointerId":3,"posX":1075,"posY":194,"time":80,"type":"Tap"},{"key":"KeyF","note":"","pointerId":3,"posX":861,"posY":310,"time":80,"type":"Tap"},{"key":"KeyG","note":"","pointerId":3,"posX":865,"posY":388,"time":80,"type":"Tap"},{"key":"KeyR","note":"","pointerId":3,"posX":976,"posY":674,"time":80,"type":"Tap"},{"key":"KeyE","note":"","pointerId":3,"posX":872,"posY":495,"time":80,"type":"Tap"},{"key":"KeyB","note":"","pointerId":3,"posX":543,"posY":593,"time":80,"type":"Tap"},{"key":"KeyN","note":"","pointerId":3,"posX":721,"posY":589,"time":80,"type":"Tap"},{"drag":false,"note":"","pointerId":2,"posX":1097,"posY":549,"scaleX":0.5,"scaleY":0.5,"type":"Fire"},{"key":"M2","note":"","pointerId":3,"posX":1227,"posY":376,"time":80,"type":"Tap"},{"key":"Tab","macro":{"down":[{"args":["default",5,100,650,80],"type":"touch"}],"loop":null,"up":[{"args":["default",5,1250,40,80],"type":"touch"}]},"note":"背包宏","posX":95,"posY":656,"type":"Macro"},{"key":"M1","note":"地图","pointerId":3,"posX":1244,"posY":43,"time":80,"type":"Tap"},{"key":"KeyV","note":"","pointerId":3,"posX":1156,"posY":300,"time":80,"type":"Tap"},{"key":"M4","note":"","pointerId":3,"posX":862,"posY":180,"time":80,"type":"Tap"},{"key":"KeyT","note":"","pointerId":3,"posX":880,"posY":674,"time":80,"type":"Tap"},{"key":"KeyQ","note":"","pointerId":3,"posX":400,"posY":679,"time":80,"type":"Tap"},{"key":"Digit4","note":"","pointerId":3,"posX":766,"posY":251,"time":80,"type":"Tap"},{"key":"Digit5","note":"","pointerId":3,"posX":770,"posY":320,"time":80,"type":"Tap"},{"key":"Digit3","note":"","pointerId":3,"posX":788,"posY":591,"time":80,"type":"Tap"}],"relativeSize":{"h":720,"w":1280},"title":"AVD-和平精英-导入默认"} + {"list":[{"key":"Backquote","note":"准星键","pointerId":0,"posX":640,"posY":361,"scaleX":1,"scaleY":1,"type":"Sight"},{"key":{"down":"KeyS","left":"KeyA","right":"KeyD","up":"KeyW"},"note":"","offset":150,"pointerId":1,"posX":208,"posY":542,"type":"SteeringWheel"},{"key":"KeyC","note":"","pointerId":3,"posX":1085,"posY":668,"time":80,"type":"Tap"},{"key":"KeyZ","note":"","pointerId":3,"posX":1207,"posY":648,"time":80,"type":"Tap"},{"key":"Space","note":"","pointerId":3,"posX":1230,"posY":503,"time":80,"type":"Tap"},{"key":"M3","note":"","pointerId":4,"posX":992,"posY":229,"scale":0.6,"type":"Observation"},{"key":"Digit1","note":"","pointerId":3,"posX":543,"posY":642,"time":80,"type":"Tap"},{"key":"Digit2","note":"","pointerId":3,"posX":729,"posY":644,"time":80,"type":"Tap"},{"key":"ShiftLeft","note":"","pointerId":3,"posX":1075,"posY":194,"time":80,"type":"Tap"},{"key":"KeyF","note":"","pointerId":3,"posX":861,"posY":310,"time":80,"type":"Tap"},{"key":"KeyG","note":"","pointerId":3,"posX":865,"posY":388,"time":80,"type":"Tap"},{"key":"KeyR","note":"","pointerId":3,"posX":976,"posY":674,"time":80,"type":"Tap"},{"key":"KeyE","note":"","pointerId":3,"posX":872,"posY":495,"time":80,"type":"Tap"},{"key":"KeyB","note":"","pointerId":3,"posX":543,"posY":593,"time":80,"type":"Tap"},{"key":"KeyN","note":"","pointerId":3,"posX":721,"posY":589,"time":80,"type":"Tap"},{"drag":false,"note":"","pointerId":2,"posX":1097,"posY":549,"scaleX":0.5,"scaleY":0.5,"type":"Fire"},{"key":"M2","note":"","pointerId":3,"posX":1227,"posY":376,"time":80,"type":"Tap"},{"key":"Tab","macro":{"down":[{"args":["default",5,100,650,80],"type":"touch"}],"loop":null,"up":[{"args":["default",5,1250,40,80],"type":"touch"}]},"note":"背包宏","posX":95,"posY":656,"type":"Macro"},{"key":"M1","note":"地图","pointerId":3,"posX":1244,"posY":43,"time":80,"type":"Tap"},{"key":"KeyV","note":"","pointerId":3,"posX":1156,"posY":300,"time":80,"type":"Tap"},{"key":"M4","note":"","pointerId":3,"posX":862,"posY":180,"time":80,"type":"Tap"},{"key":"KeyT","note":"","pointerId":3,"posX":880,"posY":674,"time":80,"type":"Tap"},{"key":"KeyQ","note":"","pointerId":3,"posX":400,"posY":679,"time":80,"type":"Tap"},{"key":"Digit4","note":"","pointerId":3,"posX":766,"posY":251,"time":80,"type":"Tap"},{"key":"Digit5","note":"","pointerId":3,"posX":770,"posY":320,"time":80,"type":"Tap"},{"key":"Digit3","note":"","pointerId":3,"posX":788,"posY":591,"time":80,"type":"Tap"}],"relativeSize":{"h":720,"w":1280},"title":"AVD-和平精英-导入默认"}, + {"list":[{"key":{"down":"KeyS","left":"KeyA","right":"KeyD","up":"KeyW"},"note":"","offset":150,"pointerId":1,"posX":204,"posY":531,"type":"SteeringWheel"},{"key":"KeyE","note":"","pointerId":3,"posX":1036,"posY":660,"time":80,"type":"Tap"},{"key":"KeyL","note":"","pointerId":2,"posX":1166,"posY":328,"type":"DirectionlessSkill"},{"key":"KeyI","note":"","pointerId":3,"posX":947,"posY":657,"time":80,"type":"Tap"},{"key":"KeyU","note":"","pointerId":3,"posX":970,"posY":542,"time":80,"type":"Tap"},{"key":"KeyF","note":"","pointerId":3,"posX":1056,"posY":458,"time":80,"type":"Tap"},{"key":"Digit1","note":"","pointerId":3,"posX":560,"posY":666,"time":80,"type":"Tap"},{"key":"Digit2","note":"","pointerId":3,"posX":639,"posY":666,"time":80,"type":"Tap"},{"key":"KeyZ","note":"","pointerId":3,"posX":1163,"posY":433,"time":80,"type":"Tap"},{"key":"Escape","note":"","pointerId":3,"posX":1198,"posY":43,"time":80,"type":"Tap"},{"key":"Enter","macro":{"down":[{"args":[],"type":"key-input-mode"}],"loop":null,"up":null},"note":"","posX":1086,"posY":85,"type":"Macro"},{"key":"KeyK","note":"","pointerId":3,"posX":1188,"posY":528,"time":80,"type":"Tap"},{"key":"Space","note":"","pointerId":3,"posX":732,"posY":653,"time":80,"type":"Tap"},{"key":"Semicolon","note":"","pointerId":3,"posX":1200,"posY":234,"time":80,"type":"Tap"},{"key":"KeyN","note":"","pointerId":3,"posX":1054,"posY":232,"time":80,"type":"Tap"},{"key":"KeyO","note":"","pointerId":3,"posX":1133,"posY":232,"time":80,"type":"Tap"},{"key":"ShiftLeft","note":"","pointerId":2,"posX":991,"posY":233,"type":"DirectionlessSkill"},{"key":"KeyC","note":"","pointerId":2,"posX":1131,"posY":628,"type":"DirectionlessSkill"},{"key":"KeyQ","note":"","pointerId":2,"posX":838,"posY":656,"type":"DirectionlessSkill"},{"key":"KeyJ","note":"","pointerId":3,"posX":1132,"posY":628,"time":80,"type":"Tap"},{"intervalBetweenPos":100,"key":"KeyH","note":"","pointerId":3,"pos":[{"x":1055,"y":357},{"x":1059,"y":430}],"posX":1053,"posY":393,"type":"Swipe"},{"type":"Swipe","key":"BracketLeft","note":"","posX":987,"posY":354,"pointerId":3,"pos":[{"x":1055,"y":356},{"x":942,"y":356}],"intervalBetweenPos":100},{"type":"Swipe","key":"Backslash","note":"","posX":1055,"posY":306,"pointerId":3,"pos":[{"x":1052,"y":356},{"x":1052,"y":288}],"intervalBetweenPos":100},{"type":"Swipe","key":"BracketRight","note":"","posX":1094,"posY":353,"pointerId":3,"pos":[{"x":1050,"y":356},{"x":1117,"y":354}],"intervalBetweenPos":100}],"relativeSize":{"h":720,"w":1280},"title":"AVD-DNF-狂战-导入默认"} ] diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 85eb83b..db44892 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -4,5 +4,5 @@ pub mod client; pub mod control_msg; pub mod resource; pub mod scrcpy_mask_cmd; -pub mod socket; pub mod share; +pub mod socket; diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 5e53b5b..f8abaa6 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -181,6 +181,7 @@ fn set_adb_path(adb_path: String, app: tauri::AppHandle) -> Result<(), String> { #[tokio::main] async fn main() { tauri::Builder::default() + .plugin(tauri_plugin_clipboard_manager::init()) .plugin(tauri_plugin_http::init()) .plugin(tauri_plugin_shell::init()) .plugin(tauri_plugin_process::init()) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index bb7612d..c9f274d 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,6 +1,6 @@ { "productName": "scrcpy-mask", - "version": "0.5.0", + "version": "0.6.0", "identifier": "com.akichase.mask", "build": { "beforeDevCommand": "pnpm dev", diff --git a/src/App.vue b/src/App.vue index 48c9cbb..6f113fc 100644 --- a/src/App.vue +++ b/src/App.vue @@ -58,4 +58,9 @@ onMounted(async () => { width: 100%; height: 100%; } + +.n-message { + user-select: none; + -webkit-user-select: none; +} diff --git a/src/components/Device.vue b/src/components/Device.vue index bcdcd01..b00b6ed 100644 --- a/src/components/Device.vue +++ b/src/components/Device.vue @@ -45,6 +45,7 @@ import { useGlobalStore } from "../store/global"; import { useI18n } from "vue-i18n"; import { closeExternalControl, connectExternalControl } from "../websocket"; import { LogicalSize, getCurrent } from "@tauri-apps/api/window"; +import { writeText } from "@tauri-apps/plugin-clipboard-manager"; const { t } = useI18n(); const dialog = useDialog(); @@ -73,15 +74,8 @@ onMounted(async () => { case "ClipboardChanged": if (payload.clipboard === lastClipboard) break; lastClipboard = payload.clipboard; - navigator.clipboard - .writeText(payload.clipboard) - .then(() => { - message.info(t("pages.Device.clipboard.deviceSync.success")); - }) - .catch((e) => { - console.error(e); - message.error(t("pages.Device.clipboard.deviceSync.failed")); - }); + writeText(payload.clipboard); + console.log(payload); break; case "ClipboardSetAck": break; diff --git a/src/components/Header.vue b/src/components/Header.vue index 087cfd4..104ee65 100644 --- a/src/components/Header.vue +++ b/src/components/Header.vue @@ -50,6 +50,7 @@ async function maximizeOrRestore() { align-items: center; border-radius: 0 10px 0 0; user-select: none; + -webkit-user-select: none; .n-button-group{ flex-shrink: 0; diff --git a/src/components/Mask.vue b/src/components/Mask.vue index 047e6bd..fe81ff5 100644 --- a/src/components/Mask.vue +++ b/src/components/Mask.vue @@ -10,7 +10,7 @@ import { listenToEvent, unlistenToEvent, } from "../hotkey"; -import { KeyMappingConfig, KeySteeringWheel } from "../keyMappingConfig"; +import { KeySteeringWheel } from "../keyMappingConfig"; import ScreenStream from "./ScreenStream.vue"; import { getVersion } from "@tauri-apps/api/app"; import { fetch } from "@tauri-apps/plugin-http"; @@ -19,6 +19,7 @@ import { getCurrent, PhysicalSize } from "@tauri-apps/api/window"; import { Store } from "@tauri-apps/plugin-store"; import { useI18n } from "vue-i18n"; import { checkAdbAvailable } from "../invoke"; +import { loadLocalStorage } from "../storeLoader"; const { t } = useI18n(); const store = useGlobalStore(); @@ -103,79 +104,7 @@ function genClientId() { async function loadLocalStore() { const localStore = new Store("store.bin"); - // loading keyMappingConfigList from local store - let keyMappingConfigList = await localStore.get( - "keyMappingConfigList" - ); - if (keyMappingConfigList === null || keyMappingConfigList.length === 0) { - // add empty key mapping config - // unable to get mask element when app is not ready - // so we use the stored mask area to get relative size - const maskArea = await localStore.get<{ - posX: number; - posY: number; - sizeW: number; - sizeH: number; - }>("maskArea"); - let relativeSize = { w: 800, h: 600 }; - if (maskArea !== null) { - relativeSize = { - w: maskArea.sizeW, - h: maskArea.sizeH, - }; - } - keyMappingConfigList = [ - { - relativeSize, - title: t("pages.Mask.blankConfig"), - list: [], - }, - ]; - await localStore.set("keyMappingConfigList", keyMappingConfigList); - } - store.keyMappingConfigList = keyMappingConfigList; - - // loading curKeyMappingIndex from local store - let curKeyMappingIndex = await localStore.get("curKeyMappingIndex"); - if ( - curKeyMappingIndex === null || - curKeyMappingIndex >= keyMappingConfigList.length - ) { - curKeyMappingIndex = 0; - localStore.set("curKeyMappingIndex", curKeyMappingIndex); - } - store.curKeyMappingIndex = curKeyMappingIndex; - - // loading maskButton from local store - let maskButton = await localStore.get<{ - show: boolean; - transparency: number; - }>("maskButton"); - store.maskButton = maskButton ?? { - show: true, - transparency: 0.5, - }; - - // loading checkUpdateAtStart from local store - const checkUpdateAtStart = await localStore.get( - "checkUpdateAtStart" - ); - store.checkUpdateAtStart = checkUpdateAtStart ?? true; - - // loading rotation from local store - const rotation = await localStore.get<{ - enable: boolean; - verticalLength: number; - horizontalLength: number; - }>("rotation"); - if (rotation) store.rotation = rotation; - - // loading screenStream from local store - const screenStream = await localStore.get<{ - enable: boolean; - address: string; - }>("screenStream"); - if (screenStream) store.screenStream = screenStream; + await loadLocalStorage(localStore, store, t); } async function cleanAfterimage() { diff --git a/src/components/ScreenStream.vue b/src/components/ScreenStream.vue index 38de18f..acdd4ab 100644 --- a/src/components/ScreenStream.vue +++ b/src/components/ScreenStream.vue @@ -66,10 +66,12 @@ onBeforeUnmount(() => { z-index: 0; pointer-events: none; user-select: none; + -webkit-user-select: none; img { pointer-events: none; user-select: none; + -webkit-user-select: none; } } diff --git a/src/components/keyboard/KeyBoard.vue b/src/components/keyboard/KeyBoard.vue index 82ace9a..3180497 100644 --- a/src/components/keyboard/KeyBoard.vue +++ b/src/components/keyboard/KeyBoard.vue @@ -8,6 +8,7 @@ import KeySkill from "./KeySkill.vue"; import KeyObservation from "./KeyObservation.vue"; import KeySight from "./KeySight.vue"; import KeyFire from "./KeyFire.vue"; +import KeySwipe from "./KeySwipe.vue"; import ScreenStream from "../ScreenStream.vue"; import { @@ -17,6 +18,7 @@ import { KeyTap, KeyMacro, KeyMapping, + KeySwipe as KeyMappingKeySwipe, KeySight as KeyMappingKeySight, KeyFire as KeyMappingKeyFire, } from "../../keyMappingConfig"; @@ -43,6 +45,10 @@ const addButtonOptions: DropdownOption[] = [ label: () => t("pages.KeyBoard.addButton.SteeringWheel"), key: "SteeringWheel", }, + { + label: () => t("pages.KeyBoard.addButton.Swipe"), + key: "Swipe", + }, { label: () => t("pages.KeyBoard.addButton.Skill"), key: "DirectionalSkill", @@ -72,6 +78,7 @@ const addButtonOptions: DropdownOption[] = [ function onAddButtonSelect( type: | "Tap" + | "Swipe" | "SteeringWheel" | "DirectionalSkill" | "CancelSkill" @@ -92,6 +99,12 @@ function onAddButtonSelect( if (type === "Tap") { keyMapping.pointerId = 3; (keyMapping as KeyTap).time = 80; + } else if (type === "Swipe") { + keyMapping.pointerId = 3; + (keyMapping as KeyMappingKeySwipe).pos = [ + { x: keyMapping.posX, y: keyMapping.posY }, + ]; + (keyMapping as KeyMappingKeySwipe).intervalBetweenPos = 100; } else if (type === "SteeringWheel") { keyMapping.pointerId = 1; (keyMapping as unknown as KeyMappingSteeringWheel).key = { @@ -139,6 +152,7 @@ function onAddButtonSelect( } else return; keyboardStore.edited = true; store.editKeyMappingList.push(keyMapping as KeyMapping); + keyboardStore.activeButtonIndex = store.editKeyMappingList.length - 1; } function isKeyUnique(curKey: string): boolean { @@ -172,6 +186,7 @@ function setCurButtonKey(curKey: string) { keyboardStore.showButtonSettingFlag || keyboardStore.activeButtonIndex >= store.editKeyMappingList.length || keyboardStore.showButtonSettingFlag || + keyboardStore.editSwipePointsFlag || keyboardStore.showButtonAddFlag ) return; @@ -362,6 +377,10 @@ onBeforeRouteLeave(() => { v-else-if="store.editKeyMappingList[index].type === 'Observation'" :index="index" /> + -import { Settings, CloseCircle } from "@vicons/ionicons5"; +import { Settings, CloseCircle, ReturnUpBack } from "@vicons/ionicons5"; import { NButton, NIcon, @@ -19,6 +19,7 @@ import { loadDefaultKeyconfig } from "../../invoke"; import { KeyMappingConfig } from "../../keyMappingConfig"; import { useKeyboardStore } from "../../store/keyboard"; import { useI18n } from "vue-i18n"; +import { writeText } from "@tauri-apps/plugin-clipboard-manager"; const { t } = useI18n(); const store = useGlobalStore(); @@ -121,14 +122,18 @@ function dragHandler(downEvent: MouseEvent) { localStore.set("keySettingPos", keySettingPos.value); } else { // click up - keyboardStore.activeButtonIndex = -1; - keyboardStore.activeSteeringWheelButtonKeyIndex = -1; - keyboardStore.showSettingFlag = !keyboardStore.showSettingFlag; - if ( - keyboardStore.showSettingFlag && - store.keyMappingConfigList.length === 1 - ) { - message.info(t("pages.KeyBoard.KeySetting.onlyOneConfig")); + if (keyboardStore.editSwipePointsFlag) { + keyboardStore.editSwipePointsFlag = false; + } else { + keyboardStore.activeButtonIndex = -1; + keyboardStore.activeSteeringWheelButtonKeyIndex = -1; + keyboardStore.showSettingFlag = !keyboardStore.showSettingFlag; + if ( + keyboardStore.showSettingFlag && + store.keyMappingConfigList.length === 1 + ) { + message.info(t("pages.KeyBoard.KeySetting.onlyOneConfig")); + } } } }; @@ -251,8 +256,7 @@ function renameKeyMappingConfig() { function exportKeyMappingConfig() { const config = store.keyMappingConfigList[store.curKeyMappingIndex]; const data = JSON.stringify(config, null, 2); - navigator.clipboard - .writeText(data) + writeText(data) .then(() => { message.success(t("pages.KeyBoard.KeySetting.exportSuccess")); }) @@ -374,7 +378,10 @@ function resetKeyMappingConfig() { }" >
+import { computed, ref } from "vue"; +import { useGlobalStore } from "../../store/global"; +import { + NIcon, + NButton, + NFormItem, + NInput, + NH4, + NInputNumber, + useMessage, +} from "naive-ui"; +import { Analytics, CloseCircle, Settings } from "@vicons/ionicons5"; +import { useKeyboardStore } from "../../store/keyboard"; +import { KeySwipe } from "../../keyMappingConfig"; +import { useI18n } from "vue-i18n"; + +const props = defineProps<{ + index: number; +}>(); + +const keyboardStore = useKeyboardStore(); +const message = useMessage(); +const store = useGlobalStore(); +const { t } = useI18n(); + +const elementRef = ref(null); + +const isActive = computed( + () => props.index === keyboardStore.activeButtonIndex +); +const keyMapping = computed( + () => store.editKeyMappingList[props.index] as KeySwipe +); + +const trackPoints = computed(() => { + let s = ""; + if (isActive.value) { + for (const point of keyMapping.value.pos) { + s += `${point.x},${point.y} `; + } + } + return s; +}); + +function dragHandler(downEvent: MouseEvent) { + keyboardStore.activeButtonIndex = props.index; + keyboardStore.showButtonSettingFlag = false; + const oldX = keyMapping.value.posX; + const oldY = keyMapping.value.posY; + const element = elementRef.value; + if (element) { + const keyboardElement = document.getElementById( + "keyboardElement" + ) as HTMLElement; + const maxX = keyboardElement.clientWidth - 30; + const maxY = keyboardElement.clientHeight - 30; + + const x = downEvent.clientX; + const y = downEvent.clientY; + const moveHandler = (moveEvent: MouseEvent) => { + let newX = oldX + moveEvent.clientX - x; + let newY = oldY + moveEvent.clientY - y; + newX = Math.max(30, Math.min(newX, maxX)); + newY = Math.max(30, Math.min(newY, maxY)); + keyMapping.value.posX = newX; + keyMapping.value.posY = newY; + }; + window.addEventListener("mousemove", moveHandler); + const upHandler = () => { + window.removeEventListener("mousemove", moveHandler); + window.removeEventListener("mouseup", upHandler); + if (oldX !== keyMapping.value.posX || oldY !== keyMapping.value.posY) { + keyboardStore.edited = true; + } + }; + window.addEventListener("mouseup", upHandler); + } +} + +function delCurKeyMapping() { + keyboardStore.edited = true; + keyboardStore.activeButtonIndex = -1; + store.editKeyMappingList.splice(props.index, 1); +} + +const settingPosX = ref(0); +const settingPosY = ref(0); +function showSetting() { + const keyboardElement = document.getElementById( + "keyboardElement" + ) as HTMLElement; + const maxWidth = keyboardElement.clientWidth - 150; + const maxHeight = keyboardElement.clientHeight - 380; + + settingPosX.value = Math.min(keyMapping.value.posX + 40, maxWidth); + settingPosY.value = Math.min(keyMapping.value.posY - 40, maxHeight); + keyboardStore.showButtonSettingFlag = true; +} + +function editSwipePoints() { + message.info(t("pages.KeyBoard.Swipe.editTips")); + keyboardStore.showButtonSettingFlag = false; + keyboardStore.editSwipePointsFlag = true; + keyboardStore.edited = true; +} + +function swipePointDragHandlue(downEvent: MouseEvent, index: number) { + if (downEvent.button === 2) { + // del point + keyMapping.value.pos.splice(index, 1); + return; + } + if (downEvent.button !== 0) return; + + const oldX = keyMapping.value.pos[index].x; + const oldY = keyMapping.value.pos[index].y; + const keyboardElement = document.getElementById( + "keyboardElement" + ) as HTMLElement; + const maxX = keyboardElement.clientWidth; + const maxY = keyboardElement.clientHeight; + + const x = downEvent.clientX; + const y = downEvent.clientY; + const moveHandler = (moveEvent: MouseEvent) => { + let newX = oldX + moveEvent.clientX - x; + let newY = oldY + moveEvent.clientY - y; + newX = Math.max(0, Math.min(newX, maxX)); + newY = Math.max(0, Math.min(newY, maxY)); + keyMapping.value.pos[index].x = newX; + keyMapping.value.pos[index].y = newY; + }; + const upHandler = () => { + window.removeEventListener("mousemove", moveHandler); + window.removeEventListener("mouseup", upHandler); + }; + window.addEventListener("mousemove", moveHandler); + window.addEventListener("mouseup", upHandler); +} + +function swipeTrackClickHandler(event: MouseEvent) { + if (event.button !== 0) return; + console.log(event.target, event.currentTarget); + if (event.target !== event.currentTarget) return; + keyMapping.value.pos.push({ x: event.clientX - 70, y: event.clientY - 30 }); +} + + + + + diff --git a/src/components/setting/Basic.vue b/src/components/setting/Basic.vue index 8dcdbe0..3769205 100644 --- a/src/components/setting/Basic.vue +++ b/src/components/setting/Basic.vue @@ -1,23 +1,16 @@ diff --git a/src/components/setting/Data.vue b/src/components/setting/Data.vue new file mode 100644 index 0000000..7f42de2 --- /dev/null +++ b/src/components/setting/Data.vue @@ -0,0 +1,149 @@ + + + + + diff --git a/src/components/setting/Setting.vue b/src/components/setting/Setting.vue index d38b4f2..cbad1a5 100644 --- a/src/components/setting/Setting.vue +++ b/src/components/setting/Setting.vue @@ -1,6 +1,7 @@