2026-01-11 18:27:51 +08:00
|
|
|
|
// main.js
|
2026-01-11 17:50:27 +08:00
|
|
|
|
import { createPanel } from './scripts/panel.js';
|
|
|
|
|
|
import { handleCommand, COMMANDS } from './scripts/commands.js';
|
|
|
|
|
|
import { initVoice } from './scripts/voice.js';
|
|
|
|
|
|
import { translateToCommand } from './scripts/ai.js';
|
2026-01-02 21:06:54 +08:00
|
|
|
|
|
2026-01-11 12:22:49 +08:00
|
|
|
|
const init = async () => {
|
|
|
|
|
|
const ui = createPanel();
|
2026-01-11 18:27:51 +08:00
|
|
|
|
let spaceTimer = null;
|
|
|
|
|
|
let isRecording = false;
|
2026-01-02 21:06:54 +08:00
|
|
|
|
|
2026-01-11 12:22:49 +08:00
|
|
|
|
async function startProcess(text) {
|
2026-01-11 18:27:51 +08:00
|
|
|
|
if (!text) return;
|
2026-01-11 12:22:49 +08:00
|
|
|
|
ui.setLoading(true);
|
|
|
|
|
|
try {
|
2026-01-11 18:27:51 +08:00
|
|
|
|
const localMatch = COMMANDS.find(c => text.includes(c.key));
|
|
|
|
|
|
if (localMatch) {
|
|
|
|
|
|
handleCommand(localMatch.key);
|
2026-01-11 12:22:49 +08:00
|
|
|
|
} else {
|
2026-01-11 18:27:51 +08:00
|
|
|
|
const aiResult = await translateToCommand(text);
|
|
|
|
|
|
if (aiResult) handleCommand(aiResult);
|
2026-01-11 12:22:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
ui.setLoading(false);
|
2026-01-02 21:06:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-11 18:27:51 +08:00
|
|
|
|
const voiceCtrl = initVoice(document.getElementById("automation-ai-panel"), (text) => {
|
|
|
|
|
|
ui.input.value = text;
|
|
|
|
|
|
startProcess(text);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// --- 逻辑 A: 保留原有按钮点击录音 ---
|
|
|
|
|
|
ui.btn.onclick = () => {
|
|
|
|
|
|
if (!isRecording) {
|
|
|
|
|
|
voiceCtrl.start();
|
|
|
|
|
|
ui.setRecording(true);
|
|
|
|
|
|
isRecording = true;
|
|
|
|
|
|
// 按钮模式下 3秒后自动停止,或靠 recognition 自动结束
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
if (isRecording) {
|
|
|
|
|
|
voiceCtrl.stop();
|
|
|
|
|
|
ui.setRecording(false);
|
|
|
|
|
|
isRecording = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}, 3000);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// --- 逻辑 B: 空格长按 0.5s 触发 ---
|
|
|
|
|
|
window.addEventListener("keydown", (e) => {
|
|
|
|
|
|
if (e.code === "Space" && e.target.tagName !== "INPUT" && e.target.tagName !== "TEXTAREA") {
|
|
|
|
|
|
if (spaceTimer || isRecording) return;
|
|
|
|
|
|
|
|
|
|
|
|
spaceTimer = setTimeout(() => {
|
|
|
|
|
|
if (voiceCtrl.supportSpeech) {
|
|
|
|
|
|
voiceCtrl.start();
|
|
|
|
|
|
ui.setRecording(true);
|
|
|
|
|
|
isRecording = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}, 500);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
window.addEventListener("keyup", (e) => {
|
|
|
|
|
|
if (e.code === "Space") {
|
|
|
|
|
|
if (spaceTimer) {
|
|
|
|
|
|
clearTimeout(spaceTimer);
|
|
|
|
|
|
spaceTimer = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (isRecording) {
|
|
|
|
|
|
// 松开空格,延迟一小会儿停止,确保最后几个字能录进去
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
voiceCtrl.stop();
|
|
|
|
|
|
ui.setRecording(false);
|
|
|
|
|
|
isRecording = false;
|
|
|
|
|
|
}, 200);
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
ui.input.onkeydown = (e) => {
|
2026-01-11 12:22:49 +08:00
|
|
|
|
if (e.key === "Enter") {
|
|
|
|
|
|
const val = ui.input.value;
|
|
|
|
|
|
ui.input.value = "";
|
|
|
|
|
|
startProcess(val);
|
|
|
|
|
|
}
|
2026-01-11 18:27:51 +08:00
|
|
|
|
};
|
2026-01-11 12:22:49 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2026-01-11 18:27:51 +08:00
|
|
|
|
if (document.readyState === "complete") init();
|
|
|
|
|
|
else window.addEventListener("load", init);
|