From 9e486fa3902a3ce8ddc3e3cfc69e4816990c8232 Mon Sep 17 00:00:00 2001 From: Cx330 <1487537121@qq.com> Date: Sun, 11 Jan 2026 18:27:51 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E8=BE=93=E5=85=A5=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- content.js | 2 +- main.js | 107 ++++++++++++++++++++++++++++++----------------- scripts/panel.js | 57 +++++++++++++++---------- scripts/voice.js | 52 ++++++++++------------- 4 files changed, 127 insertions(+), 91 deletions(-) diff --git a/content.js b/content.js index e1c1a43..833a27e 100644 --- a/content.js +++ b/content.js @@ -3,7 +3,7 @@ script.type = 'module'; script.src = chrome.runtime.getURL('main.js'); document.head.appendChild(script); -// 2. 监听来自网页(main.js)的请求 +// 监听来自网页(main.js)的请求 window.addEventListener("DO_AI_REQUEST", async (event) => { const { userInput, systemPrompt } = event.detail; diff --git a/main.js b/main.js index 5952e2f..d8a12f7 100644 --- a/main.js +++ b/main.js @@ -1,64 +1,93 @@ +// main.js 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'; -// 等待页面加载完成 const init = async () => { - console.log("🚀 插件主程序启动..."); const ui = createPanel(); + let spaceTimer = null; + let isRecording = false; async function startProcess(text) { - const rawText = text.trim(); - if (!rawText) return; - - console.log("📩 接收到输入:", rawText); - - // 1. 本地匹配逻辑 - const localMatch = COMMANDS.find(c => rawText.includes(c.key)); - if (localMatch) { - console.log("🎯 本地关键词匹配成功:", localMatch.key); - handleCommand(localMatch.key); - return; - } - - // 2. AI 翻译逻辑 + if (!text) return; ui.setLoading(true); try { - const aiResult = await translateToCommand(rawText); - if (aiResult) { - handleCommand(aiResult); + const localMatch = COMMANDS.find(c => text.includes(c.key)); + if (localMatch) { + handleCommand(localMatch.key); } else { - console.warn("❌ AI 无法理解该指令"); + const aiResult = await translateToCommand(text); + if (aiResult) handleCommand(aiResult); } - } catch (err) { - console.error("AI 流程出错:", err); } finally { ui.setLoading(false); } } - // 输入框回车事件监听 - ui.input.addEventListener("keydown", (e) => { + 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) => { if (e.key === "Enter") { - e.preventDefault(); // 防止某些页面表单提交刷新 const val = ui.input.value; ui.input.value = ""; startProcess(val); } - }); - - // 语音识别初始化 - // 修正:确保 voice.js 里的 handleCommand 回调指向我们的 startProcess - initVoice(document.getElementById("automation-ai-panel"), (spokenText) => { - ui.input.value = spokenText; - startProcess(spokenText); - }); + }; }; -// 确保在 DOM 完成后运行 -if (document.readyState === "complete" || document.readyState === "interactive") { - init(); -} else { - window.addEventListener("DOMContentLoaded", init); -} \ No newline at end of file +if (document.readyState === "complete") init(); +else window.addEventListener("load", init); \ No newline at end of file diff --git a/scripts/panel.js b/scripts/panel.js index 99af3d7..b924575 100644 --- a/scripts/panel.js +++ b/scripts/panel.js @@ -1,6 +1,6 @@ +// scripts/panel.js export function createPanel() { const panelId = "automation-ai-panel"; - // 防止重复创建 let panel = document.getElementById(panelId); if (panel) return getUIRefs(panel); @@ -10,21 +10,30 @@ export function createPanel() { position: fixed; bottom: 24px; right: 24px; z-index: 2147483647; background: white; border-radius: 10px; box-shadow: 0 4px 12px rgba(0,0,0,.2); padding: 12px; width: 260px; - font-size: 14px; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + font-size: 14px; font-family: sans-serif; `; panel.innerHTML = ` +