fix: refine sidebar ui and conversation sorting
This commit is contained in:
parent
9a83f92dd9
commit
b2cfabcd1b
@ -170,6 +170,7 @@ async function bootstrapApp() {
|
||||
loadingMoreConversations: false,
|
||||
currentConversationId: null,
|
||||
currentConversationTitle: '当前对话',
|
||||
personalPageVisible: false,
|
||||
|
||||
// 搜索功能
|
||||
searchQuery: '',
|
||||
@ -629,6 +630,7 @@ async function bootstrapApp() {
|
||||
console.log('对话已切换:', data);
|
||||
this.currentConversationId = data.conversation_id;
|
||||
this.currentConversationTitle = data.title || '';
|
||||
this.promoteConversationToTop(data.conversation_id);
|
||||
|
||||
if (data.cleared) {
|
||||
// 对话被清空
|
||||
@ -655,6 +657,7 @@ async function bootstrapApp() {
|
||||
if (data.title) {
|
||||
this.currentConversationTitle = data.title;
|
||||
}
|
||||
this.promoteConversationToTop(convId);
|
||||
const pathFragment = this.stripConversationPrefix(convId);
|
||||
const currentPath = window.location.pathname.replace(/^\/+/, '');
|
||||
if (data.created) {
|
||||
@ -1544,6 +1547,7 @@ async function bootstrapApp() {
|
||||
// 2. 更新当前对话信息
|
||||
this.currentConversationId = conversationId;
|
||||
this.currentConversationTitle = result.title;
|
||||
this.promoteConversationToTop(conversationId);
|
||||
history.pushState({ conversationId }, '', `/${this.stripConversationPrefix(conversationId)}`);
|
||||
|
||||
// 3. 重置UI状态
|
||||
@ -1570,6 +1574,17 @@ async function bootstrapApp() {
|
||||
alert(`加载对话异常: ${error.message}`);
|
||||
}
|
||||
},
|
||||
|
||||
promoteConversationToTop(conversationId) {
|
||||
if (!Array.isArray(this.conversations) || !conversationId) {
|
||||
return;
|
||||
}
|
||||
const index = this.conversations.findIndex(conv => conv && conv.id === conversationId);
|
||||
if (index > 0) {
|
||||
const [selected] = this.conversations.splice(index, 1);
|
||||
this.conversations.unshift(selected);
|
||||
}
|
||||
},
|
||||
|
||||
// ==========================================
|
||||
// 关键功能:获取并显示历史对话内容
|
||||
@ -2020,6 +2035,14 @@ async function bootstrapApp() {
|
||||
this.sidebarCollapsed = !this.sidebarCollapsed;
|
||||
},
|
||||
|
||||
openPersonalPage() {
|
||||
this.personalPageVisible = true;
|
||||
},
|
||||
|
||||
closePersonalPage() {
|
||||
this.personalPageVisible = false;
|
||||
},
|
||||
|
||||
async toggleThinkingMode() {
|
||||
try {
|
||||
const resp = await fetch('/api/thinking-mode', {
|
||||
|
||||
@ -41,15 +41,48 @@
|
||||
<div class="main-container">
|
||||
<!-- 新增:对话历史侧边栏(最左侧) -->
|
||||
<aside class="conversation-sidebar" :class="{ collapsed: sidebarCollapsed }">
|
||||
<div class="conversation-header">
|
||||
<button @click="createNewConversation" class="new-conversation-btn" v-if="!sidebarCollapsed">
|
||||
<span class="btn-icon">+</span>
|
||||
<span class="btn-text">新建对话</span>
|
||||
</button>
|
||||
<button @click="toggleSidebar" class="toggle-sidebar-btn">
|
||||
<span v-if="sidebarCollapsed">☰</span>
|
||||
<span v-else>←</span>
|
||||
</button>
|
||||
<div class="conversation-header" :class="{ 'collapsed-layout': sidebarCollapsed }">
|
||||
<template v-if="sidebarCollapsed">
|
||||
<div class="collapsed-header-buttons">
|
||||
<button type="button"
|
||||
class="collapsed-control-btn conversation-menu-btn"
|
||||
title="展开对话记录"
|
||||
@click="toggleSidebar">
|
||||
<span class="sr-only">展开对话记录</span>
|
||||
<span class="chat-icon" aria-hidden="true">
|
||||
<svg viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5 6.5c0-1.38 1.12-2.5 2.5-2.5h13c1.38 0 2.5 1.12 2.5 2.5v8.5c0 1.38-1.12 2.5-2.5 2.5h-5.6l-3.4 3.2.6-3.2H7.5c-1.38 0-2.5-1.12-2.5-2.5V6.5z"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.7"
|
||||
stroke-linejoin="round"/>
|
||||
<path d="M9 9.5h10" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/>
|
||||
<path d="M9 13h6" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
<button type="button"
|
||||
class="collapsed-control-btn quick-plus-btn"
|
||||
title="快捷新建对话"
|
||||
@click="createNewConversation">
|
||||
<span class="sr-only">新建对话</span>
|
||||
<span class="pencil-icon" aria-hidden="true">
|
||||
<svg class="edit-svgIcon" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M410.3 231l11.3-11.3-33.9-33.9-62.1-62.1L291.7 89.8l-11.3 11.3-22.6 22.6L58.6 322.9c-10.4 10.4-18 23.3-22.2 37.4L1 480.7c-2.5 8.4-.2 17.5 6.1 23.7s15.3 8.5 23.7 6.1l120.3-35.4c14.1-4.2 27-11.8 37.4-22.2L387.7 253.7 410.3 231zM160 399.4l-9.1 22.7c-4 3.1-8.5 5.4-13.3 6.9L59.4 452l23-78.1c1.4-4.9 3.8-9.4 6.9-13.3l22.7-9.1v32c0 8.8 7.2 16 16 16h32zM362.7 18.7L348.3 33.2 325.7 55.8 314.3 67.1l33.9 33.9 62.1 62.1 33.9 33.9 11.3-11.3 22.6-22.6 14.5-14.5c25-25 25-65.5 0-90.5L453.3 18.7c-25-25-65.5-25-90.5 0zm-47.4 168l-144 144c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6l144-144c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<button @click="createNewConversation" class="new-conversation-btn">
|
||||
<span class="btn-icon">+</span>
|
||||
<span class="btn-text">新建对话</span>
|
||||
</button>
|
||||
<button @click="toggleSidebar" class="toggle-sidebar-btn">
|
||||
<span v-if="sidebarCollapsed">☰</span>
|
||||
<span v-else>←</span>
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<template v-if="!sidebarCollapsed">
|
||||
@ -108,6 +141,24 @@
|
||||
<template v-else>
|
||||
<div class="conversation-collapsed-spacer"></div>
|
||||
</template>
|
||||
<div class="conversation-personal-entry" :class="{ collapsed: sidebarCollapsed }">
|
||||
<button type="button"
|
||||
class="personal-page-btn"
|
||||
:class="{ 'icon-only': sidebarCollapsed }"
|
||||
title="个人页面"
|
||||
@click="openPersonalPage">
|
||||
<span class="sr-only">个人页面</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
aria-hidden="true">
|
||||
<path fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z"></path>
|
||||
</svg>
|
||||
<span class="personal-label" v-if="!sidebarCollapsed">个人页面</span>
|
||||
</button>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 左侧文件树 -->
|
||||
@ -127,94 +178,93 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-header">
|
||||
<div class="panel-menu-wrapper" ref="panelMenuWrapper">
|
||||
<button class="sidebar-view-toggle"
|
||||
@click.stop="togglePanelMenu"
|
||||
title="切换侧边栏">
|
||||
☰
|
||||
</button>
|
||||
<transition name="fade">
|
||||
<div class="panel-menu" v-if="panelMenuOpen">
|
||||
<button type="button"
|
||||
:class="{ active: panelMode === 'files' }"
|
||||
@click.stop="selectPanelMode('files')"
|
||||
title="项目文件">📁</button>
|
||||
<button type="button"
|
||||
:class="{ active: panelMode === 'todo' }"
|
||||
@click.stop="selectPanelMode('todo')"
|
||||
title="待办列表">{{ todoEmoji }}</button>
|
||||
<button type="button"
|
||||
:class="{ active: panelMode === 'subAgents' }"
|
||||
@click.stop="selectPanelMode('subAgents')"
|
||||
title="子智能体">🤖</button>
|
||||
<div class="sidebar-panel-card-wrapper">
|
||||
<div class="sidebar-panel-card">
|
||||
<div class="sidebar-header">
|
||||
<div class="panel-menu-wrapper" ref="panelMenuWrapper">
|
||||
<button class="sidebar-view-toggle"
|
||||
@click.stop="togglePanelMenu"
|
||||
title="切换侧边栏">
|
||||
☰
|
||||
</button>
|
||||
<transition name="fade">
|
||||
<div class="panel-menu" v-if="panelMenuOpen">
|
||||
<button type="button"
|
||||
:class="{ active: panelMode === 'files' }"
|
||||
@click.stop="selectPanelMode('files')"
|
||||
title="项目文件">📁</button>
|
||||
<button type="button"
|
||||
:class="{ active: panelMode === 'todo' }"
|
||||
@click.stop="selectPanelMode('todo')"
|
||||
title="待办列表">{{ todoEmoji }}</button>
|
||||
<button type="button"
|
||||
:class="{ active: panelMode === 'subAgents' }"
|
||||
@click.stop="selectPanelMode('subAgents')"
|
||||
title="子智能体">🤖</button>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</transition>
|
||||
<button class="sidebar-manage-btn"
|
||||
@click="openGuiFileManager"
|
||||
title="打开桌面式文件管理器">
|
||||
管理
|
||||
</button>
|
||||
<h3>
|
||||
<span v-if="panelMode === 'files'">{{ fileEmoji }} 项目文件</span>
|
||||
<span v-else-if="panelMode === 'todo'">{{ todoEmoji }} 待办列表</span>
|
||||
<span v-else>🤖 子智能体</span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="sidebar-panel-content">
|
||||
<div v-if="panelMode === 'todo'" class="todo-panel">
|
||||
<div v-if="!todoList" class="todo-empty">
|
||||
暂无待办列表
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="todo-task"
|
||||
v-for="task in (todoList.tasks || [])"
|
||||
:key="task.index"
|
||||
:class="{ done: task.status === 'done' }">
|
||||
<span class="todo-task-title">task{{ task.index }}:{{ task.title }}</span>
|
||||
<span class="todo-task-status">{{ formatTaskStatus(task) }}</span>
|
||||
</div>
|
||||
<div class="todo-instruction">{{ todoList.instruction }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="panelMode === 'subAgents'" class="sub-agent-panel">
|
||||
<div v-if="!subAgents.length" class="sub-agent-empty">
|
||||
暂无运行中的子智能体
|
||||
</div>
|
||||
<div v-else class="sub-agent-cards">
|
||||
<div class="sub-agent-card"
|
||||
v-for="agent in subAgents"
|
||||
:key="agent.task_id"
|
||||
@click="openSubAgent(agent)">
|
||||
<div class="sub-agent-header">
|
||||
<span class="sub-agent-id">#{{ agent.agent_id }}</span>
|
||||
<span class="sub-agent-status" :class="agent.status">{{ agent.status }}</span>
|
||||
</div>
|
||||
<div class="sub-agent-summary">{{ agent.summary }}</div>
|
||||
<div class="sub-agent-tool" v-if="agent.last_tool">
|
||||
当前:{{ agent.last_tool }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="file-tree" @contextmenu.prevent>
|
||||
<file-node
|
||||
v-for="node in fileTree"
|
||||
:key="node.path"
|
||||
:node="node"
|
||||
:level="0"
|
||||
:expanded-folders="expandedFolders"
|
||||
@toggle-folder="toggleFolder"
|
||||
@context-menu="showContextMenu"
|
||||
></file-node>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="sidebar-manage-btn"
|
||||
@click="openGuiFileManager"
|
||||
title="打开桌面式文件管理器">
|
||||
管理
|
||||
</button>
|
||||
<h3>
|
||||
<span v-if="panelMode === 'files'">{{ fileEmoji }} 项目文件</span>
|
||||
<span v-else-if="panelMode === 'todo'">{{ todoEmoji }} 待办列表</span>
|
||||
<span v-else>🤖 子智能体</span>
|
||||
</h3>
|
||||
</div>
|
||||
<template v-if="panelMode === 'todo'">
|
||||
<div class="todo-panel">
|
||||
<div v-if="!todoList" class="todo-empty">
|
||||
暂无待办列表
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="todo-task"
|
||||
v-for="task in (todoList.tasks || [])"
|
||||
:key="task.index"
|
||||
:class="{ done: task.status === 'done' }">
|
||||
<span class="todo-task-title">task{{ task.index }}:{{ task.title }}</span>
|
||||
<span class="todo-task-status">{{ formatTaskStatus(task) }}</span>
|
||||
</div>
|
||||
<div class="todo-instruction">{{ todoList.instruction }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="panelMode === 'subAgents'">
|
||||
<div class="sub-agent-panel">
|
||||
<div v-if="!subAgents.length" class="sub-agent-empty">
|
||||
暂无运行中的子智能体
|
||||
</div>
|
||||
<div v-else class="sub-agent-cards">
|
||||
<div class="sub-agent-card"
|
||||
v-for="agent in subAgents"
|
||||
:key="agent.task_id"
|
||||
@click="openSubAgent(agent)">
|
||||
<div class="sub-agent-header">
|
||||
<span class="sub-agent-id">#{{
|
||||
agent.agent_id }}</span>
|
||||
<span class="sub-agent-status" :class="agent.status">{{ agent.status }}</span>
|
||||
</div>
|
||||
<div class="sub-agent-summary">{{ agent.summary }}</div>
|
||||
<div class="sub-agent-tool" v-if="agent.last_tool">
|
||||
当前:{{ agent.last_tool }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="file-tree" @contextmenu.prevent>
|
||||
<file-node
|
||||
v-for="node in fileTree"
|
||||
:key="node.path"
|
||||
:node="node"
|
||||
:level="0"
|
||||
:expanded-folders="expandedFolders"
|
||||
@toggle-folder="toggleFolder"
|
||||
@context-menu="showContextMenu"
|
||||
></file-node>
|
||||
</div>
|
||||
</template>
|
||||
</aside>
|
||||
|
||||
<!-- 左侧拖拽手柄 -->
|
||||
@ -645,6 +695,21 @@
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
<transition name="personal-page-fade">
|
||||
<div class="personal-page-overlay"
|
||||
v-if="personalPageVisible"
|
||||
@click.self="closePersonalPage">
|
||||
<div class="personal-page-card">
|
||||
<h2>个人空间</h2>
|
||||
<p>敬请期待,个人页面正在建设中。</p>
|
||||
<button type="button"
|
||||
class="personal-page-close"
|
||||
@click="closePersonalPage">
|
||||
返回工作区
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
<div class="context-menu"
|
||||
v-if="contextMenu.visible"
|
||||
|
||||
312
static/style.css
312
static/style.css
@ -11,6 +11,7 @@
|
||||
--app-bottom-inset: env(safe-area-inset-bottom, 0px);
|
||||
--claude-bg: #eeece2;
|
||||
--claude-panel: rgba(255, 255, 255, 0.82);
|
||||
--claude-left-rail: #f7f3ea;
|
||||
--claude-sidebar: rgba(255, 255, 255, 0.68);
|
||||
--claude-border: rgba(118, 103, 84, 0.25);
|
||||
--claude-text: #3d3929;
|
||||
@ -122,22 +123,30 @@ body {
|
||||
|
||||
.conversation-sidebar {
|
||||
width: 280px;
|
||||
background: var(--claude-sidebar);
|
||||
background-color: var(--claude-left-rail);
|
||||
border-right: none;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
z-index: 50;
|
||||
backdrop-filter: blur(12px);
|
||||
height: var(--app-viewport, 100vh) !important;
|
||||
min-height: var(--app-viewport, 100vh) !important;
|
||||
border-bottom: 1px solid var(--claude-border);
|
||||
}
|
||||
|
||||
.conversation-sidebar,
|
||||
.conversation-sidebar .conversation-header,
|
||||
.conversation-sidebar .conversation-search,
|
||||
.conversation-sidebar .conversation-list,
|
||||
.conversation-sidebar .conversation-personal-entry,
|
||||
.conversation-sidebar .conversation-collapsed-spacer {
|
||||
background-color: var(--claude-left-rail);
|
||||
}
|
||||
|
||||
.conversation-collapsed-spacer {
|
||||
flex: 1 1 auto;
|
||||
background: transparent;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.conversation-sidebar.collapsed {
|
||||
@ -145,14 +154,7 @@ body {
|
||||
overflow: hidden;
|
||||
height: var(--app-viewport, 100vh) !important;
|
||||
min-height: var(--app-viewport, 100vh) !important;
|
||||
}
|
||||
|
||||
.conversation-sidebar.collapsed .conversation-header {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.conversation-sidebar.collapsed .conversation-header .toggle-sidebar-btn {
|
||||
margin-left: 0;
|
||||
background-color: var(--claude-left-rail);
|
||||
}
|
||||
|
||||
.conversation-header {
|
||||
@ -162,7 +164,7 @@ body {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
background: rgba(255, 255, 255, 0.78);
|
||||
background-color: inherit;
|
||||
color: var(--claude-text);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
@ -170,6 +172,92 @@ body {
|
||||
min-height: 68px;
|
||||
}
|
||||
|
||||
.conversation-header.collapsed-layout {
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding: 16px 6px 12px;
|
||||
gap: 14px;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.collapsed-header-buttons {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.collapsed-control-btn {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 28px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: var(--claude-text);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
box-shadow: none;
|
||||
transition: transform 0.2s ease, color 0.2s ease;
|
||||
}
|
||||
|
||||
.collapsed-control-btn:hover {
|
||||
transform: translateY(-1px);
|
||||
color: var(--claude-accent);
|
||||
}
|
||||
|
||||
.conversation-menu-btn {
|
||||
color: #31271d;
|
||||
}
|
||||
|
||||
.conversation-menu-btn:hover {
|
||||
color: var(--claude-accent);
|
||||
}
|
||||
|
||||
.chat-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.conversation-menu-btn svg {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.quick-plus-btn {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 24px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: #2f251b;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: color 0.25s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
.quick-plus-btn:hover,
|
||||
.quick-plus-btn:focus-visible {
|
||||
color: var(--claude-accent);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.pencil-icon svg {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.pencil-icon path {
|
||||
fill: currentColor;
|
||||
fill-opacity: 0.92;
|
||||
}
|
||||
|
||||
.new-conversation-btn {
|
||||
flex: 1;
|
||||
background: linear-gradient(135deg, var(--claude-accent) 0%, var(--claude-accent-strong) 100%);
|
||||
@ -221,9 +309,100 @@ body {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.conversation-personal-entry {
|
||||
margin-top: auto;
|
||||
padding: 8px 16px 12px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.conversation-personal-entry.collapsed {
|
||||
padding: 8px 0 10px;
|
||||
}
|
||||
|
||||
.personal-page-btn {
|
||||
border: none;
|
||||
border-radius: 999px;
|
||||
background: transparent;
|
||||
color: var(--claude-text);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
padding: 10px 18px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
.conversation-personal-entry:not(.collapsed) .personal-page-btn {
|
||||
width: 100%;
|
||||
justify-content: flex-start;
|
||||
padding: 8px 12px;
|
||||
border-radius: 12px;
|
||||
background: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
.personal-page-btn svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.personal-page-btn:hover,
|
||||
.personal-page-btn:focus-visible {
|
||||
color: var(--claude-accent);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.personal-page-btn:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 2px rgba(218, 119, 86, 0.15);
|
||||
}
|
||||
|
||||
.personal-page-btn.icon-only {
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
padding: 0;
|
||||
border-radius: 27px;
|
||||
color: var(--claude-text);
|
||||
}
|
||||
|
||||
.personal-page-btn.icon-only svg {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
}
|
||||
|
||||
.personal-page-btn.icon-only:hover,
|
||||
.personal-page-btn.icon-only:focus-visible {
|
||||
color: var(--claude-accent);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.conversation-personal-entry:not(.collapsed) .personal-page-btn:hover,
|
||||
.conversation-personal-entry:not(.collapsed) .personal-page-btn:focus-visible {
|
||||
background: rgba(218, 119, 86, 0.08);
|
||||
}
|
||||
|
||||
.personal-label {
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.conversation-search {
|
||||
padding: 12px;
|
||||
background: transparent;
|
||||
background-color: inherit;
|
||||
border-bottom: 1px solid var(--claude-border);
|
||||
}
|
||||
|
||||
@ -249,7 +428,7 @@ body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 8px 0;
|
||||
background: transparent;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.loading-conversations,
|
||||
@ -396,7 +575,7 @@ o-conversations {
|
||||
/* 拖拽手柄 */
|
||||
.resize-handle {
|
||||
width: 4px;
|
||||
background: var(--claude-sidebar);
|
||||
background: var(--claude-left-rail);
|
||||
cursor: col-resize;
|
||||
position: relative;
|
||||
transition: background 0.2s;
|
||||
@ -409,12 +588,17 @@ o-conversations {
|
||||
|
||||
/* 侧边栏 */
|
||||
.sidebar {
|
||||
background: rgba(255, 255, 255, 0.75);
|
||||
background: var(--claude-left-rail);
|
||||
overflow-y: auto;
|
||||
flex-shrink: 0;
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.sidebar.left-sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sidebar-status {
|
||||
padding: 18px 18px 8px;
|
||||
}
|
||||
@ -524,6 +708,37 @@ o-conversations {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
}
|
||||
|
||||
.sidebar-panel-card-wrapper {
|
||||
padding: 0 18px 24px;
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.sidebar-panel-card {
|
||||
background: var(--claude-panel);
|
||||
border: 1px solid var(--claude-border);
|
||||
border-radius: 18px;
|
||||
box-shadow: 0 12px 30px rgba(61, 57, 41, 0.12);
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.sidebar-panel-card .sidebar-header {
|
||||
border-radius: 18px 18px 0 0;
|
||||
}
|
||||
|
||||
.sidebar-panel-content {
|
||||
flex: 1 1 auto;
|
||||
background: var(--claude-sidebar);
|
||||
padding: 6px 12px 24px;
|
||||
border-radius: 0 0 18px 18px;
|
||||
border-top: 1px solid rgba(118, 103, 84, 0.12);
|
||||
}
|
||||
|
||||
.panel-menu-wrapper {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
@ -2232,3 +2447,68 @@ o-files {
|
||||
color: var(--claude-text-secondary);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.personal-page-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(33, 24, 14, 0.55);
|
||||
backdrop-filter: blur(12px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 400;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.personal-page-card {
|
||||
width: min(90vw, 420px);
|
||||
background: #fffaf4;
|
||||
border-radius: 26px;
|
||||
border: 1px solid rgba(118, 103, 84, 0.25);
|
||||
box-shadow: 0 28px 60px rgba(38, 28, 18, 0.25);
|
||||
padding: 40px 48px;
|
||||
text-align: center;
|
||||
color: var(--claude-text);
|
||||
}
|
||||
|
||||
.personal-page-card h2 {
|
||||
font-size: 26px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.personal-page-card p {
|
||||
font-size: 15px;
|
||||
color: var(--claude-text-secondary);
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.personal-page-close {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px 22px;
|
||||
border-radius: 999px;
|
||||
border: none;
|
||||
background: linear-gradient(135deg, var(--claude-accent) 0%, var(--claude-accent-strong) 100%);
|
||||
color: #fffdf8;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 14px 28px rgba(189, 93, 58, 0.2);
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.personal-page-close:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 18px 34px rgba(189, 93, 58, 0.3);
|
||||
}
|
||||
|
||||
.personal-page-fade-enter-active,
|
||||
.personal-page-fade-leave-active {
|
||||
transition: opacity 0.25s ease;
|
||||
}
|
||||
|
||||
.personal-page-fade-enter-from,
|
||||
.personal-page-fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user