feat: 路径收藏添加发送到终端按钮
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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 事件发射器实例
|
||||
|
||||
Reference in New Issue
Block a user