diff --git a/package-lock.json b/package-lock.json index 3f328de..e1478be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9042,6 +9042,7 @@ "date-fns": "^4.1.0", "guacamole-common-js": "^1.5.0", "iconv-lite": "^0.6.3", + "mitt": "^3.0.1", "monaco-editor": "^0.52.2", "pinia": "^3.0.2", "pinia-plugin-persistedstate": "^4.2.0", diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 3def40b..046bef1 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -11,6 +11,7 @@ "dependencies": { "@fortawesome/fontawesome-free": "^6.7.2", "@hcaptcha/vue3-hcaptcha": "^1.3.0", + "@simplewebauthn/browser": "^9.0.1", "@tailwindcss/vite": "^4.1.4", "@vscode/iconv-lite-umd": "^0.7.0", "@vueuse/core": "^13.1.0", @@ -21,6 +22,7 @@ "date-fns": "^4.1.0", "guacamole-common-js": "^1.5.0", "iconv-lite": "^0.6.3", + "mitt": "^3.0.1", "monaco-editor": "^0.52.2", "pinia": "^3.0.2", "pinia-plugin-persistedstate": "^4.2.0", @@ -33,8 +35,7 @@ "vue3-recaptcha2": "^1.8.0", "vuedraggable": "^4.1.0", "xterm": "^5.3.0", - "xterm-addon-web-links": "^0.9.0", - "@simplewebauthn/browser": "^9.0.1" + "xterm-addon-web-links": "^0.9.0" }, "devDependencies": { "@types/node": "^20", diff --git a/packages/frontend/src/components/CommandInputBar.vue b/packages/frontend/src/components/CommandInputBar.vue index 9b41397..3e736b9 100644 --- a/packages/frontend/src/components/CommandInputBar.vue +++ b/packages/frontend/src/components/CommandInputBar.vue @@ -8,19 +8,14 @@ import { useSettingsStore } from '../stores/settings.store'; import { useQuickCommandsStore } from '../stores/quickCommands.store'; import { useCommandHistoryStore } from '../stores/commandHistory.store'; import QuickCommandsModal from './QuickCommandsModal.vue'; // +++ Import the modal component +++ +import { useWorkspaceEventEmitter } from '../composables/workspaceEvents'; // +++ 新增导入 +++ // Disable attribute inheritance as this component has multiple root nodes (div + modal) defineOptions({ inheritAttrs: false }); -const emit = defineEmits([ - 'send-command', - 'search', - 'find-next', - 'find-previous', - 'close-search', - 'clear-terminal', - 'toggle-virtual-keyboard' // +++ Add new emit +++ -]); +const emitWorkspaceEvent = useWorkspaceEventEmitter(); // +++ 获取事件发射器 +++ +const emit = defineEmits(['toggle-virtual-keyboard']); + const { t } = useI18n(); const focusSwitcherStore = useFocusSwitcherStore(); const settingsStore = useSettingsStore(); @@ -72,7 +67,7 @@ const currentSessionCommandInput = computed({ const sendCommand = () => { const command = currentSessionCommandInput.value; // 使用计算属性获取值 console.log(`[CommandInputBar] Sending command: ${command || ''} `); - emit('send-command', command); + emitWorkspaceEvent('terminal:sendCommand', { command }); // 清空 store 中的值 if (activeSessionId.value) { updateSessionCommandInput(activeSessionId.value, ''); @@ -83,7 +78,7 @@ const toggleSearch = () => { isSearching.value = !isSearching.value; if (!isSearching.value) { searchTerm.value = ''; // 关闭搜索时清空 - emit('close-search'); // 通知父组件关闭搜索 + emitWorkspaceEvent('search:close'); // 通知父组件关闭搜索 } else { // 可以在这里聚焦搜索输入框 // nextTick(() => searchInputRef.value?.focus()); @@ -91,16 +86,16 @@ const toggleSearch = () => { }; const performSearch = () => { - emit('search', searchTerm.value); + emitWorkspaceEvent('search:start', { term: searchTerm.value }); // 实际的计数更新逻辑应该由父组件通过 props 或事件传递回来 }; const findNext = () => { - emit('find-next'); + emitWorkspaceEvent('search:findNext'); }; const findPrevious = () => { - emit('find-previous'); + emitWorkspaceEvent('search:findPrevious'); }; // 监听搜索词变化,执行搜索 @@ -151,7 +146,7 @@ const handleCommandInputKeydown = (event: KeyboardEvent) => { if (selectedCommand !== undefined) { event.preventDefault(); console.log(`[CommandInputBar] Enter detected with selection. Sending selected command: ${selectedCommand}`); - emit('send-command', selectedCommand); // 发送选中命令 (移除多余的 \n) + emitWorkspaceEvent('terminal:sendCommand', { command: selectedCommand }); // 发送选中命令 if (activeSessionId.value) { updateSessionCommandInput(activeSessionId.value, ''); // 清空输入框 } @@ -190,7 +185,7 @@ const handleCommandInputKeydown = (event: KeyboardEvent) => { // Handle Ctrl+C when input is empty event.preventDefault(); console.log('[CommandInputBar] Ctrl+C detected with empty input. Sending SIGINT.'); - emit('send-command', '\x03'); // Send ETX character (Ctrl+C) + emitWorkspaceEvent('terminal:sendCommand', { command: '\x03' }); // Send ETX character (Ctrl+C) } else if (!event.altKey && event.key === 'Enter') { // Handle regular Enter key press - send current input (empty or not) event.preventDefault(); // Prevent default if needed, e.g., form submission @@ -288,7 +283,7 @@ const closeQuickCommandsModal = () => { // +++ Handler for command execution from the modal +++ const handleQuickCommandExecute = (command: string) => { console.log(`[CommandInputBar] Executing quick command: ${command}`); - emit('send-command', command); // Emit the command to the parent + emitWorkspaceEvent('terminal:sendCommand', { command }); // Emit the command to the parent closeQuickCommandsModal(); // Close the modal after selection }; @@ -298,7 +293,7 @@ const handleQuickCommandExecute = (command: string) => {