feat: 路径收藏添加发送到终端按钮

This commit is contained in:
Baobhan Sith
2025-05-28 09:18:44 +08:00
parent 2e330d1654
commit 91e8169fa7
3 changed files with 34 additions and 5 deletions
@@ -4,6 +4,7 @@ import { useI18n } from 'vue-i18n';
import { useFavoritePathsStore, type FavoritePathItem } from '../stores/favoritePaths.store';
import { useSessionStore } from '../stores/session.store';
import AddEditFavoritePathForm from './AddEditFavoritePathForm.vue';
import { useWorkspaceEventEmitter } from '../composables/workspaceEvents';
const PADDING = 8; // px
@@ -23,6 +24,7 @@ const emit = defineEmits(['close', 'navigateToPath']);
const { t } = useI18n();
const favoritePathsStore = useFavoritePathsStore();
const sessionStore = useSessionStore();
const emitWorkspaceEvent = useWorkspaceEventEmitter();
const searchTerm = ref('');
const showAddEditModal = ref(false);
@@ -89,6 +91,11 @@ const handleDelete = async (pathItem: FavoritePathItem) => {
}
};
const handleSendToTerminal = (pathItem: FavoritePathItem) => {
emitWorkspaceEvent('favoritePath:sendToActiveTerminal', { path: pathItem.path });
closeModal(); // Optionally close modal after sending
};
const closeModal = () => {
emit('close');
};
@@ -255,6 +262,12 @@ onBeforeUnmount(() => {
</p>
</div>
<div class="flex-shrink-0 flex items-center gap-1 opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity duration-150">
<button
@click.stop="handleSendToTerminal(favPath)"
class="p-1.5 rounded text-text-secondary hover:text-primary hover:bg-black/10 dark:hover:bg-white/10 transition-colors"
:title="t('favoritePaths.sendToTerminal', 'Send to Terminal')">
<i class="fas fa-terminal text-xs"></i>
</button>
<button
@click.stop="openEditModal(favPath)"
class="p-1.5 rounded text-text-secondary hover:text-primary hover:bg-black/10 dark:hover:bg-white/10 transition-colors"
+20 -5
View File
@@ -4,12 +4,13 @@ import { Terminal, ITerminalAddon, IDisposable } from 'xterm';
import { useDeviceDetection } from '../composables/useDeviceDetection';
import { useAppearanceStore } from '../stores/appearance.store';
import { useSettingsStore } from '../stores/settings.store';
import { useSessionStore } from '../stores/session.store';
import { storeToRefs } from 'pinia';
import { FitAddon } from '@xterm/addon-fit';
import { WebLinksAddon } from 'xterm-addon-web-links';
import { SearchAddon, type ISearchOptions } from '@xterm/addon-search';
import 'xterm/css/xterm.css';
import { useWorkspaceEventEmitter } from '../composables/workspaceEvents';
import { useWorkspaceEventEmitter, useWorkspaceEventSubscriber, useWorkspaceEventOff } from '../composables/workspaceEvents'; // +++ Import subscriber and off
// 定义 props 和 emits
@@ -23,6 +24,8 @@ const props = defineProps<{
const emitWorkspaceEvent = useWorkspaceEventEmitter(); // +++ 获取事件发射器 +++
const subscribeToWorkspaceEvent = useWorkspaceEventSubscriber(); // +++ 获取事件订阅器 +++
const unsubscribeFromWorkspaceEvent = useWorkspaceEventOff(); // +++ 获取事件取消订阅器 +++
const terminalRef = ref<HTMLElement | null>(null); // xterm 挂载点的引用 (内部容器)
const terminalOuterWrapperRef = ref<HTMLElement | null>(null); // 最外层容器的引用,用于背景图
@@ -65,6 +68,7 @@ const isTerminalDomReady = ref(false);
// --- Settings Store ---
const settingsStore = useSettingsStore(); // +++ 实例化设置 store +++
const sessionStore = useSessionStore(); // +++ 实例化会话 store +++
const {
autoCopyOnSelectBoolean,
terminalScrollbackLimitNumber,
@@ -569,6 +573,17 @@ onMounted(() => {
terminalRef.value.addEventListener('touchend', handleTouchEnd, { passive: false });
terminalRef.value.addEventListener('touchcancel', handleTouchEnd, { passive: false }); // Also handle cancel
}
// Listen for favorite path to send to terminal
subscribeToWorkspaceEvent('favoritePath:sendToActiveTerminal', ({ path }) => {
if (terminal && props.isActive && sessionStore.activeSessionId === props.sessionId) {
// Ensure path is quoted to handle spaces or special characters
const command = `cd "${path.replace(/"/g, '\\"')}"\n`; // Escape existing quotes in path
emitWorkspaceEvent('terminal:input', { sessionId: props.sessionId, data: command });
terminal.focus(); // Focus terminal after sending command
}
});
}
});
@@ -611,10 +626,10 @@ onBeforeUnmount(() => {
terminalRef.value.removeEventListener('touchend', handleTouchEnd);
terminalRef.value.removeEventListener('touchcancel', handleTouchEnd);
}
// terminalRef 是内部容器,不需要特别处理
// if (terminalRef.value) {
// }
unsubscribeFromWorkspaceEvent('favoritePath:sendToActiveTerminal');
});
// 暴露 write 方法给父组件 (可选)
const write = (data: string | Uint8Array) => {
@@ -51,6 +51,7 @@ export type WorkspaceEventPayloads = {
// Suspended SSH Session Events
'suspendedSession:actionCompleted': void; // Emitted when a resume/remove action is completed
'favoritePath:sendToActiveTerminal': { path: string }; // Event to send a path to the active terminal
};
// 创建 mitt 事件发射器实例