Skip to content
This repository was archived by the owner on Feb 16, 2025. It is now read-only.

Commit 15dc32f

Browse files
committed
build package
1 parent a9eb80e commit 15dc32f

File tree

11 files changed

+192
-22
lines changed

11 files changed

+192
-22
lines changed

index.html

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@
99
</head>
1010

1111
<body>
12-
<div id="app"></div>
12+
<div id="app">
13+
<span class="prefix">[State]</span>
14+
<span class="state"></span>
15+
<span class="prefix">[Version]</span>
16+
<span class="version"></span>
17+
<span class="prefix">[Listen]</span>
18+
<span class="listen"></span>
19+
<span class="prefix d">[Display]</span>
20+
<span class="display"></span>
21+
</div>
1322
</body>
1423
</html>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "keyboard-monitor",
33
"private": true,
4-
"version": "0.0.0",
4+
"version": "1.0.0-alpha.1",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",

src-tauri/Cargo.lock

Lines changed: 36 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ edition = "2021"
1313
tauri-build = { version = "1.4", features = [] }
1414

1515
[dependencies]
16-
tauri = { version = "1.4", features = ["shell-open"] }
16+
tauri = { version = "1.4", features = [ "system-tray", "shell-open"] }
1717
serde = { version = "1.0", features = ["derive"] }
1818
serde_json = "1.0"
1919
rdev = "0.5.3"

src-tauri/src/main.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
33

44
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
5+
56
use rdev::{listen, Event, EventType, Key};
67
use tauri::Manager;
78
use ws::listen as ws_listen;
89

10+
mod tray;
11+
912
fn get_key_name(key: Key) -> String {
1013
let key_some = Key::from(key);
1114
return match key_some {
@@ -127,13 +130,6 @@ struct Payload {
127130
key: String,
128131
}
129132

130-
#[tauri::command]
131-
fn use_devtools(app_handle: tauri::AppHandle) {
132-
let window = app_handle.get_window("main").unwrap();
133-
window.close_devtools();
134-
window.open_devtools();
135-
}
136-
137133
fn main() {
138134
let context = tauri::generate_context!();
139135

@@ -183,8 +179,9 @@ fn main() {
183179

184180
Ok(())
185181
})
186-
.invoke_handler(tauri::generate_handler![use_devtools])
187182
.device_event_filter(tauri::DeviceEventFilter::Always)
183+
.system_tray(tray::menu()) // ✅ 将 `tauri.conf.json` 上配置的图标添加到系统托盘
184+
.on_system_tray_event(tray::handler) // ✅ 注册系统托盘事件处理程序
188185
.run(context)
189186
.expect("error while running application");
190187
}

src-tauri/src/tray.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use tauri::Manager;
2+
use tauri::{
3+
AppHandle, CustomMenuItem, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem,
4+
};
5+
6+
// 托盘菜单
7+
pub fn menu() -> SystemTray {
8+
let tray_menu = SystemTrayMenu::new()
9+
.add_item(CustomMenuItem::new("hide".to_string(), "隐藏")) // 隐藏应用窗口
10+
.add_item(CustomMenuItem::new("show".to_string(), "显示")) // 显示应用窗口
11+
.add_native_item(SystemTrayMenuItem::Separator) // 分割线
12+
.add_item(CustomMenuItem::new("quit".to_string(), "退出")); // 退出
13+
14+
// 设置在右键单击系统托盘时显示菜单
15+
SystemTray::new().with_menu(tray_menu)
16+
}
17+
18+
// 菜单事件
19+
pub fn handler(app: &AppHandle, event: SystemTrayEvent) {
20+
// 获取应用窗口
21+
let window = app.get_window("main").unwrap();
22+
// 匹配点击事件
23+
match event {
24+
// 根据菜单 id 进行事件匹配
25+
SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
26+
"quit" => {
27+
std::process::exit(0);
28+
}
29+
"show" => {
30+
window.show().unwrap();
31+
}
32+
"hide" => {
33+
window.hide().unwrap();
34+
}
35+
_ => {}
36+
},
37+
_ => {}
38+
}
39+
}

src-tauri/tauri.conf.json

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
},
99
"package": {
1010
"productName": "keyboard-monitor",
11-
"version": "0.0.0"
11+
"version": "1.0.0-alpha.1"
1212
},
1313
"tauri": {
1414
"allowlist": {
@@ -36,11 +36,17 @@
3636
"windows": [
3737
{
3838
"fullscreen": false,
39-
"resizable": true,
40-
"title": "keyboard-monitor",
41-
"width": 400,
42-
"height": 200
39+
"resizable": false,
40+
"title": "Keyboard Monitor",
41+
"width": 300,
42+
"height": 200,
43+
"visible": false,
44+
"alwaysOnTop": true
4345
}
44-
]
46+
],
47+
"systemTray": {
48+
"iconPath": "icons/icon.png",
49+
"iconAsTemplate": true
50+
}
4551
}
4652
}

src/main.ts

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,56 @@
11
import { listen } from "@tauri-apps/api/event"
2-
// import { invoke } from "@tauri-apps/api/tauri"
2+
import { getVersion } from "@tauri-apps/api/app"
33

4-
import { Ws } from "./ws"
5-
import type { Payload } from "./types"
6-
// invoke("use_devtools")
7-
const ws = new Ws("ws://127.0.0.1:3012")
4+
import { Ws } from "./ws.js"
5+
import type { Payload } from "./types.d.js"
86

7+
const WS_URL = "ws://127.0.0.1:3012"
8+
let keyQueue: string[] = []
9+
10+
const app = document.getElementById("app")!
11+
const state = document.querySelector("span.state")!
12+
const version = document.querySelector("span.version")!
13+
const tip = document.querySelector("span.listen")!
14+
const display = document.querySelector("span.display")!
15+
const prefixDisplay = document.querySelector("span.prefix.d")!
16+
17+
function updateState() {
18+
app && (state.innerHTML = `${ws.state}`)
19+
if (!keyQueue.length) {
20+
display.innerHTML = `No key being pressed.`
21+
prefixDisplay.innerHTML = `[Display]`
22+
} else {
23+
display.innerHTML = keyQueue.join("·")
24+
prefixDisplay.innerHTML = `[Display ${keyQueue.length}]`
25+
}
26+
}
27+
28+
const ws = new Ws(WS_URL)
29+
tip.innerHTML = `${WS_URL}`
930
ws.onMessage = (...args) => {
1031
console.log(`Message ${[...args]}`)
1132
}
1233

1334
const unlisten = async () => {
1435
return await listen<Payload>("key", (event) => {
1536
ws.send(JSON.stringify(event.payload))
37+
38+
if (!keyQueue.includes(event.payload.key)) {
39+
keyQueue.push(event.payload.key)
40+
}
41+
42+
if (event.payload.action === "release") {
43+
keyQueue = keyQueue.filter((k) => k !== event.payload.key)
44+
}
45+
46+
updateState()
1647
})
1748
}
1849

50+
document.oncontextmenu = (e: Event) => {
51+
e.preventDefault()
52+
}
53+
getVersion().then((v) => (version.innerHTML = `${v}`))
54+
55+
updateState()
1956
unlisten()

src/styles.css

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,46 @@
33
margin: 0;
44
}
55

6+
html,
7+
body {
8+
font-size: 12px;
9+
font-family: "Consolas";
10+
font-weight: 900;
11+
}
12+
613
#app {
714
min-height: 100vh;
815
width: 100%;
916

1017
display: flex;
18+
flex-direction: column;
1119
flex-wrap: wrap;
1220

1321
justify-content: center;
1422
align-items: center;
23+
24+
user-select: none;
25+
}
26+
27+
span {
28+
display: inline-block;
29+
width: 30ch;
30+
31+
text-align: center;
32+
}
33+
34+
.state,
35+
.version,
36+
.listen,
37+
.display {
38+
margin-bottom: 0.25rem;
39+
word-break: break-all;
40+
41+
text-overflow: ellipsis;
42+
overflow: hidden;
43+
white-space: nowrap;
44+
}
45+
46+
.listen {
47+
user-select: text;
1548
}

src/types.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,10 @@ export interface Payload {
22
action: string
33
key: string
44
}
5+
6+
export enum WsReadyState {
7+
CONNECTING = 0,
8+
OPEN = 1,
9+
CLOSING = 2,
10+
CLOSED = 3,
11+
}

0 commit comments

Comments
 (0)