- 输入栏由体育场形改为圆角矩形,输入区与按钮行分离 - +/发送按钮移至底部行(左下/右下),缩小尺寸、圆角 hover、同心圆角对齐 - 发送按钮去光晕:浅色黑底白三角、深色白底黑三角,仅留浅阴影 - logo 旁思考模式按钮去除扩散光晕,focus 仅留描边环 - 对话区预留高度基准 80→90 适配更高输入栏,欢迎语 padding 同步加大 - /菜单命令名配色:经典 accent 橙、浅/深色保留 state-info 蓝 - /菜单及深色 + 菜单 hover 统一为侧边栏同款 --theme-tab-active(修复深色全黑) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
223 lines
6.8 KiB
TypeScript
223 lines
6.8 KiB
TypeScript
// @ts-nocheck
|
|
import { mapState, mapWritableState } from 'pinia';
|
|
import { useConnectionStore } from '../stores/connection';
|
|
import { useFileStore } from '../stores/file';
|
|
import { useUiStore } from '../stores/ui';
|
|
import { useConversationStore } from '../stores/conversation';
|
|
import { useModelStore } from '../stores/model';
|
|
import { useChatStore } from '../stores/chat';
|
|
import { useInputStore } from '../stores/input';
|
|
import { useToolStore } from '../stores/tool';
|
|
import { useResourceStore } from '../stores/resource';
|
|
import { useFocusStore } from '../stores/focus';
|
|
import { useUploadStore } from '../stores/upload';
|
|
import { useMonitorStore } from '../stores/monitor';
|
|
import { usePolicyStore } from '../stores/policy';
|
|
|
|
export const computed = {
|
|
...mapWritableState(useConnectionStore, [
|
|
'isConnected',
|
|
'socket',
|
|
'stopRequested',
|
|
'projectPath',
|
|
'agentVersion',
|
|
'thinkingMode',
|
|
'runMode'
|
|
]),
|
|
...mapState(useFileStore, ['contextMenu', 'fileTree', 'expandedFolders', 'todoList']),
|
|
...mapWritableState(useUiStore, [
|
|
'sidebarCollapsed',
|
|
'workspaceCollapsed',
|
|
'chatDisplayMode',
|
|
'panelMode',
|
|
'panelMenuOpen',
|
|
'leftWidth',
|
|
'rightWidth',
|
|
'rightCollapsed',
|
|
'isResizing',
|
|
'resizingPanel',
|
|
'minPanelWidth',
|
|
'maxPanelWidth',
|
|
'quotaToast',
|
|
'toastQueue',
|
|
'confirmDialog',
|
|
'easterEgg',
|
|
'isMobileViewport',
|
|
'mobileOverlayMenuOpen',
|
|
'activeMobileOverlay'
|
|
]),
|
|
...mapWritableState(useConversationStore, [
|
|
'conversations',
|
|
'conversationsLoading',
|
|
'hasMoreConversations',
|
|
'loadingMoreConversations',
|
|
'currentConversationId',
|
|
'currentConversationTitle',
|
|
'searchQuery',
|
|
'searchTimer',
|
|
'searchResults',
|
|
'conversationInsertAnimations',
|
|
'conversationListAnimationMode',
|
|
'pendingDeletingConversationIds',
|
|
'searchActive',
|
|
'searchInProgress',
|
|
'searchMoreAvailable',
|
|
'searchOffset',
|
|
'searchTotal',
|
|
'conversationsOffset',
|
|
'conversationsLimit',
|
|
'runningWorkspaceTasks',
|
|
'acknowledgedCompletedTaskIds'
|
|
]),
|
|
...mapWritableState(useModelStore, ['currentModelKey']),
|
|
...mapState(useModelStore, ['models']),
|
|
...mapWritableState(useChatStore, [
|
|
'messages',
|
|
'currentMessageIndex',
|
|
'streamingMessage',
|
|
'expandedBlocks',
|
|
'autoScrollEnabled',
|
|
'userScrolling',
|
|
'thinkingScrollLocks'
|
|
]),
|
|
...mapWritableState(useInputStore, [
|
|
'inputMessage',
|
|
'inputLineCount',
|
|
'inputIsMultiline',
|
|
'inputIsFocused',
|
|
'quickMenuOpen',
|
|
'toolMenuOpen',
|
|
'settingsOpen',
|
|
'imagePickerOpen',
|
|
'videoPickerOpen',
|
|
'selectedImages',
|
|
'selectedVideos',
|
|
'goalModeArmed',
|
|
'goalRunning',
|
|
'goalProgress',
|
|
'goalDialogOpen'
|
|
]),
|
|
resolvedRunMode() {
|
|
const allowed = ['fast', 'thinking', 'deep'];
|
|
if (allowed.includes(this.runMode)) {
|
|
return this.runMode;
|
|
}
|
|
return this.thinkingMode ? 'thinking' : 'fast';
|
|
},
|
|
headerRunModeOptions() {
|
|
return [
|
|
{ value: 'fast', label: '快速模式', desc: '低思考,响应更快' },
|
|
{ value: 'thinking', label: '思考模式', desc: '更长思考,综合回答' },
|
|
{ value: 'deep', label: '深度思考', desc: '持续推理,适合复杂任务' }
|
|
];
|
|
},
|
|
headerRunModeLabel() {
|
|
const current = this.headerRunModeOptions.find((o) => o.value === this.resolvedRunMode);
|
|
return current ? current.label : '快速模式';
|
|
},
|
|
currentModelLabel() {
|
|
const modelStore = useModelStore();
|
|
return modelStore.currentModel?.label || '未选择模型';
|
|
},
|
|
policyUiBlocks() {
|
|
const store = usePolicyStore();
|
|
return store.uiBlocks || {};
|
|
},
|
|
adminDisabledModels() {
|
|
const store = usePolicyStore();
|
|
return store.disabledModelSet;
|
|
},
|
|
modelOptions() {
|
|
const disabledSet = this.adminDisabledModels || new Set();
|
|
const options = this.models || [];
|
|
return options.map((opt) => ({
|
|
...opt,
|
|
disabled: disabledSet.has(opt.key)
|
|
}));
|
|
},
|
|
titleRibbonVisible() {
|
|
return !this.isMobileViewport && this.chatDisplayMode === 'chat';
|
|
},
|
|
chatContainerStyle() {
|
|
const minHeight = 90;
|
|
const raw = Number(this.composerReservedHeight || 0);
|
|
const height = Number.isFinite(raw) ? Math.max(minHeight, Math.round(raw)) : minHeight;
|
|
const growth = Math.max(0, height - minHeight);
|
|
return {
|
|
'--composer-base-height': `calc(${minHeight}px + var(--app-bottom-inset, 0px))`,
|
|
'--composer-reserved-height': `calc(${height}px + var(--app-bottom-inset, 0px))`,
|
|
'--composer-growth-height': `${growth}px`
|
|
};
|
|
},
|
|
...mapWritableState(useToolStore, [
|
|
'preparingTools',
|
|
'activeTools',
|
|
'toolActionIndex',
|
|
'toolStacks',
|
|
'toolSettings',
|
|
'toolSettingsLoading'
|
|
]),
|
|
...mapWritableState(useResourceStore, [
|
|
'tokenPanelCollapsed',
|
|
'currentContextTokens',
|
|
'currentConversationTokens',
|
|
'projectStorage',
|
|
'containerStatus',
|
|
'containerNetRate',
|
|
'usageQuota'
|
|
]),
|
|
...mapWritableState(useFocusStore, ['focusedFiles']),
|
|
...mapWritableState(useUploadStore, ['uploading', 'mediaUploading']),
|
|
...mapState(useMonitorStore, {
|
|
monitorIsLocked: (store) => store.isLocked
|
|
}),
|
|
displayModeSwitchDisabled() {
|
|
return !!this.policyUiBlocks.block_virtual_monitor;
|
|
},
|
|
displayLockEngaged() {
|
|
return !!this.compressionInProgress || !!this.compressing || !!this.currentWorkspaceHasRunningTask;
|
|
},
|
|
currentWorkspaceHasRunningTask() {
|
|
if (!(this.versioningHostMode || this.dockerProjectMode) || !this.currentHostWorkspaceId) {
|
|
return false;
|
|
}
|
|
const tasks = Array.isArray(this.runningWorkspaceTasks) ? this.runningWorkspaceTasks : [];
|
|
return tasks.some((task: any) => {
|
|
const status = String(task?.status || '');
|
|
return (
|
|
task?.workspace_id === this.currentHostWorkspaceId &&
|
|
task?.conversation_id !== this.currentConversationId &&
|
|
['pending', 'running', 'cancel_requested'].includes(status)
|
|
);
|
|
});
|
|
},
|
|
streamingUi() {
|
|
return this.streamingMessage || this.hasPendingToolActions();
|
|
},
|
|
composerBusy() {
|
|
const monitorLock = this.monitorIsLocked && this.chatDisplayMode === 'monitor';
|
|
return (
|
|
this.streamingUi ||
|
|
this.taskInProgress ||
|
|
monitorLock ||
|
|
this.stopRequested ||
|
|
this.compressionInProgress ||
|
|
this.compressing
|
|
);
|
|
},
|
|
composerStreamingForInput() {
|
|
return this.composerBusy && !this.displayLockEngaged;
|
|
},
|
|
composerHeroActive() {
|
|
return (this.blankHeroActive || this.blankHeroExiting) && !this.composerInteractionActive;
|
|
},
|
|
composerInteractionActive() {
|
|
const hasText = !!(this.inputMessage && this.inputMessage.trim().length > 0);
|
|
const hasImages = Array.isArray(this.selectedImages) && this.selectedImages.length > 0;
|
|
return this.quickMenuOpen || hasText || hasImages;
|
|
},
|
|
showScrollToBottomButton() {
|
|
return this.chatDisplayMode === 'chat' && !this.stickIsNearBottom;
|
|
}
|
|
};
|