fix: 堆叠块深色hover不可见 & 底部块高度偏差 & 新增隐藏边线开关

- 深色模式 hover 修复:用 !important 覆盖 _overlays 中的 surface-panel 规则,使用 --hover-bg(6%白) 对齐对话列表 hover
- 底部块高度修正:shellHeight = targetShell + 2 补偿 border-box 下内容区裁剪
- 深色模式运行横条改为白色(var(--text-primary))
- 新增隐藏边线开关:后端 PersonalForm 持久化 stacked_hide_borders,前端条件渲染开关(仅堆叠模式可见)
This commit is contained in:
JOJO 2026-06-10 19:18:29 +08:00
parent 3abbf30422
commit dcb25dfe89
5 changed files with 94 additions and 4 deletions

View File

@ -95,6 +95,7 @@ DEFAULT_PERSONALIZATION_CONFIG: Dict[str, Any] = {
"silent_tool_disable": True, # 禁用工具时不向模型插入提示(默认开启)
"enhanced_tool_display": True, # 增强工具显示
"compact_message_display": "full", # 简略消息显示full-完整原始内容 / brief-一行概要
"stacked_hide_borders": False, # 堆叠块隐藏边线
"show_git_status_bar": True, # 是否显示输入栏上方 Git 状态栏
"versioning_restore_mode": "overwrite", # 版本回溯模式固定为 overwrite
"agents_md_auto_inject": False, # AGENTS.md 自动注入开关
@ -434,6 +435,12 @@ def sanitize_personalization_payload(
else:
base["compact_message_display"] = "full"
# 堆叠块隐藏边线
if "stacked_hide_borders" in data:
base["stacked_hide_borders"] = bool(data.get("stacked_hide_borders"))
else:
base["stacked_hide_borders"] = bool(base.get("stacked_hide_borders", False))
# Git 状态栏显示开关
if "show_git_status_bar" in data:
base["show_git_status_bar"] = bool(data.get("show_git_status_bar"))

View File

@ -1,7 +1,7 @@
<template>
<div
class="stacked-shell"
:class="{ 'stacked-shell--single': isSingle, 'stacked-shell--not-ready': !ready }"
:class="{ 'stacked-shell--single': isSingle, 'stacked-shell--not-ready': !ready, 'stacked-shell--no-borders': hideBorders }"
ref="shell"
:style="{
height: `${shellHeight}px`,
@ -182,6 +182,8 @@ const shouldUseEnhancedDisplay = computed(() => {
return personalizationStore.form.enhanced_tool_display;
});
const hideBorders = computed(() => personalizationStore.form.stacked_hide_borders);
const renderToolResult = (action: any) => {
return renderEnhancedToolResult(
action,
@ -319,8 +321,8 @@ const measureAndCompute = () => {
const fullContent = innerC ? Math.min(Math.ceil(innerC.offsetHeight), COLLAPSE_MAX_HEIGHT) : 0;
nextContentHeights[key] = fullContent;
const expanded = isExpandedById(key);
// .stacked-item 1px border-bottom
const borderH = idx === children.length - 1 ? 0 : 1;
// 线线 0 border-bottom
const borderH = hideBorders.value ? 0 : (idx === children.length - 1 ? 0 : 1);
heights.push(headerH + (expanded ? fullContent : 0) + borderH);
});
@ -334,7 +336,9 @@ const measureAndCompute = () => {
moreHeight.value = moreVisible.value ? moreBaseHeight() : 0;
const targetShell =
moreHeight.value + (showAll.value || !moreVisible.value ? totalHeight : windowHeight);
shellHeight.value = targetShell;
// shellHeight +2 border-box border 1px
// viewport overflow:hidden
shellHeight.value = targetShell + 2;
innerOffset.value = showAll.value || !moreVisible.value ? 0 : -hiddenHeight;
viewportHeight.value = Math.max(0, targetShell - moreHeight.value);
};
@ -417,6 +421,8 @@ watch(
() => (props.expandedBlocks ? props.expandedBlocks.size : 0),
() => scheduleMeasure()
);
watch(hideBorders, () => scheduleMeasure());
</script>
<style scoped>

View File

@ -323,6 +323,30 @@
</ul>
</div>
</div>
<label
v-if="currentBlockDisplayMode === 'stacked'"
class="settings-toggle-row"
>
<span class="settings-row-copy">
<span class="settings-row-title">隐藏块间边线</span>
<span class="settings-row-desc"
>去掉堆叠块之间的分割线更简洁</span
>
</span>
<input
type="checkbox"
:checked="stackedHideBorders"
@change="handleStackedHideBordersChange($event)"
/>
<span class="fancy-check" aria-hidden="true"
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg
></span>
</label>
<div class="settings-select-row">
<span class="settings-row-copy">
<span class="settings-row-title">智能体交流风格</span>
@ -716,6 +740,30 @@
</div>
</div>
</div>
<label
v-if="currentBlockDisplayMode === 'stacked'"
class="settings-toggle-row"
>
<span class="settings-row-copy">
<span class="settings-row-title">隐藏块间边线</span>
<span class="settings-row-desc"
>去掉堆叠块之间的分割线更简洁</span
>
</span>
<input
type="checkbox"
:checked="stackedHideBorders"
@change="handleStackedHideBordersChange($event)"
/>
<span class="fancy-check" aria-hidden="true"
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg
></span>
</label>
<div class="settings-select-row">
<span class="settings-row-copy"
><span class="settings-row-title">简略消息显示</span
@ -1989,6 +2037,8 @@ const conversationContinuityLabel = computed(() => {
const currentBlockDisplayMode = computed(() => experiments.value.blockDisplayMode);
const stackedHideBorders = computed(() => form.value.stacked_hide_borders);
const blockDisplayLabel = computed(() => {
return (
blockDisplayOptions.find((option) => option.value === currentBlockDisplayMode.value)?.label ||
@ -2445,6 +2495,15 @@ const handleBlockDisplayModeChange = (mode: 'traditional' | 'stacked' | 'minimal
personalization.setBlockDisplayMode(mode);
};
const handleStackedHideBordersChange = (event: Event) => {
const target = event.target as HTMLInputElement;
personalization.updateField({
key: 'stacked_hide_borders',
value: target.checked
});
personalization.save();
};
const compactMessageDisplayOptions = [
{
id: 'full',

View File

@ -26,6 +26,7 @@ interface PersonalForm {
enhanced_tool_display: boolean;
compact_message_display: CompactMessageDisplay;
show_git_status_bar: boolean;
stacked_hide_borders: boolean;
enhanced_tool_display_categories: string[];
enabled_skills: string[];
self_identify: string;
@ -123,6 +124,7 @@ const defaultForm = (): PersonalForm => ({
enhanced_tool_display: true,
compact_message_display: 'full',
show_git_status_bar: true,
stacked_hide_borders: false,
enhanced_tool_display_categories: [],
enabled_skills: [],
self_identify: '',
@ -310,6 +312,7 @@ export const usePersonalizationStore = defineStore('personalization', {
enhanced_tool_display: data.enhanced_tool_display !== false,
compact_message_display: data.compact_message_display === 'brief' ? 'brief' : 'full',
show_git_status_bar: data.show_git_status_bar !== false,
stacked_hide_borders: !!data.stacked_hide_borders,
enhanced_tool_display_categories: Array.isArray(data.enhanced_tool_display_categories)
? data.enhanced_tool_display_categories.filter((item: unknown) => typeof item === 'string')
: [],

View File

@ -692,6 +692,11 @@
background: var(--claude-highlight);
}
/* 深色模式下块 hover 对齐对话列表 hover 颜色 */
body[data-theme='dark'] .collapsible-header:hover {
background: var(--hover-bg) !important;
}
.arrow {
width: 16px;
min-width: 16px;
@ -821,6 +826,11 @@
border-bottom: none;
}
/* 隐藏边线模式 */
.stacked-shell--no-borders .stacked-item {
border-bottom: none;
}
.stacked-block {
margin: 0;
border: none;
@ -934,6 +944,11 @@ body[data-theme='dark'] .more-icon {
pointer-events: none;
}
/* 深色模式下 progress-indicator 使用白色 */
body[data-theme='dark'] .progress-indicator {
background: var(--text-primary);
}
.collapsible-block.processing .progress-indicator {
opacity: 1;
}