mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-21 21:22:11 -03:00
refactor(settings): implement macOS Settings style for settings modal
- Reorganize settings into 4 sections: General, Interface, Download, Advanced - Implement section switching instead of scrolling (macOS Settings style) - Remove collapsible/expandable sections and redundant 'SETTINGS' label - Add accent-colored underline for section headers - Update navigation with larger, more prominent active state - Add fade-in animation for section transitions - Update search to auto-switch to matching section - Refactor CSS: 800x600 fixed modal size, remove collapse styles - Refactor JS: simplify navigation logic, remove scroll spy and collapse code Refs: Phase 0 settings modal optimization
This commit is contained in:
@@ -1,176 +1,264 @@
|
||||
# Settings Modal UI/UX Optimization
|
||||
|
||||
## Overview
|
||||
随着Settings功能的不断增加,当前的单列表长页面设计已难以高效浏览和定位设置项。本方案旨在通过专业的UI/UX优化,在保持原有设计语言的前提下,大幅提升用户体验。
|
||||
当前Settings Modal采用单列表长页面设计,随着设置项不断增加,已难以高效浏览和定位。本方案采用 **macOS Settings 模式**(左侧导航 + 右侧单Section独占显示),在保持原有设计语言的前提下,重构信息架构,大幅提升用户体验。
|
||||
|
||||
## Goals
|
||||
1. **提升浏览效率**:用户能够快速定位和修改设置
|
||||
2. **保持设计一致性**:延续现有的颜色、间距、动画系统
|
||||
3. **渐进式增强**:分阶段实施,降低风险
|
||||
4. **向后兼容**:不影响现有功能逻辑
|
||||
3. **简化交互模型**:移除冗余元素(SETTINGS label、折叠功能)
|
||||
4. **清晰的视觉层次**:Section级导航,右侧独占显示
|
||||
5. **向后兼容**:不影响现有功能逻辑
|
||||
|
||||
## Design Principles
|
||||
- **macOS Settings模式**:点击左侧导航,右侧仅显示该Section内容
|
||||
- **贴近原有设计语言**:使用现有CSS变量和样式模式
|
||||
- **最小化风格改动**:在提升UX的同时保持视觉风格稳定
|
||||
- **渐进增强**:优先核心功能,次要功能逐步添加
|
||||
- **简化优于复杂**:移除不必要的折叠/展开交互
|
||||
|
||||
---
|
||||
|
||||
## Optimization Phases
|
||||
## New Design Architecture
|
||||
|
||||
### Phase 0: 左侧导航栏 + 两栏布局 (P0)
|
||||
**Status**: In Progress
|
||||
|
||||
#### Goals
|
||||
- 解决核心痛点:设置项过多导致的浏览困难
|
||||
- 建立清晰的视觉层次和信息架构
|
||||
|
||||
#### Implementation Details
|
||||
|
||||
##### Layout Changes
|
||||
### Layout Structure
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Settings [×] │
|
||||
├──────────────┬──────────────────────────────────────────────┤
|
||||
│ NAVIGATION │ CONTENT │
|
||||
│ │ │
|
||||
│ ▶ General │ ┌─────────────────────────────────────────┐ │
|
||||
│ Interface │ │ Section: General │ │
|
||||
│ Download │ │ ┌─────────────────────────────────────┐ │ │
|
||||
│ Advanced │ │ │ Setting Item 1 │ │ │
|
||||
│ │ │ └─────────────────────────────────────┘ │ │
|
||||
│ │ │ ┌─────────────────────────────────────┐ │ │
|
||||
│ │ │ │ Setting Item 2 │ │ │
|
||||
│ │ │ └─────────────────────────────────────┘ │ │
|
||||
│ General → │ ┌─────────────────────────────────────────┐ │
|
||||
│ Interface │ │ General │ │
|
||||
│ Download │ │ ═══════════════════════════════════════ │ │
|
||||
│ Advanced │ │ │ │
|
||||
│ │ │ ┌─────────────────────────────────────┐ │ │
|
||||
│ │ │ │ Civitai API Key │ │ │
|
||||
│ │ │ │ [ ] [?] │ │ │
|
||||
│ │ │ └─────────────────────────────────────┘ │ │
|
||||
│ │ │ │ │
|
||||
│ │ │ ┌─────────────────────────────────────┐ │ │
|
||||
│ │ │ │ Settings Location │ │ │
|
||||
│ │ │ │ [/path/to/settings] [Browse] │ │ │
|
||||
│ │ │ └─────────────────────────────────────┘ │ │
|
||||
│ │ └─────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ │ ┌─────────────────────────────────────────┐ │
|
||||
│ │ │ Section: Interface │ │
|
||||
│ │ │ ... │ │
|
||||
│ │ └─────────────────────────────────────────┘ │
|
||||
│ │ [Cancel] [Save Changes] │
|
||||
└──────────────┴──────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
##### Technical Specifications
|
||||
- **Modal Width**: 从700px扩展至950px
|
||||
- **Left Sidebar**: 200px固定宽度,独立滚动
|
||||
- **Right Content**: flex: 1,独立滚动
|
||||
- **Height**: 固定80vh,确保内容可见
|
||||
- **Responsive**: 移动端自动切换为单栏布局
|
||||
### Key Design Decisions
|
||||
|
||||
##### Navigation Items
|
||||
基于当前Settings结构,导航项分为4组:
|
||||
#### 1. 移除冗余元素
|
||||
- ❌ 删除 sidebar 中的 "SETTINGS" label
|
||||
- ❌ **取消折叠/展开功能**(增加交互成本,无实际收益)
|
||||
- ❌ 不再在左侧导航显示具体设置项(减少认知负荷)
|
||||
|
||||
1. **通用** (General)
|
||||
- Language
|
||||
- Storage Location
|
||||
#### 2. 导航简化
|
||||
- 左侧仅显示 **4个Section**(General / Interface / Download / Advanced)
|
||||
- 当前选中项用 accent 色 background highlight
|
||||
- 无需滚动监听,点击即切换
|
||||
|
||||
2. **界面** (Interface)
|
||||
- Layout Settings
|
||||
- Video Settings
|
||||
- Content Filtering
|
||||
#### 3. 右侧单Section独占
|
||||
- 点击左侧导航,右侧仅显示该Section的所有设置项
|
||||
- Section标题作为页面标题(大号字体 + accent色下划线)
|
||||
- 所有设置项平铺展示,无需折叠
|
||||
|
||||
3. **下载** (Download)
|
||||
- Download Path Templates
|
||||
- Example Images
|
||||
- Update Flags
|
||||
|
||||
4. **高级** (Advanced)
|
||||
- Priority Tags
|
||||
- Auto-organize
|
||||
- Metadata Archive
|
||||
- Proxy Settings
|
||||
- Misc
|
||||
|
||||
##### Interactive Features
|
||||
- **点击导航**:平滑滚动到对应Section
|
||||
- **当前高亮**:根据滚动位置高亮当前Section
|
||||
- **平滑滚动**:使用scroll-behavior: smooth
|
||||
|
||||
##### CSS Variables Usage
|
||||
延续使用现有变量系统:
|
||||
- `--lora-accent`: 高亮色
|
||||
- `--lora-border`: 边框色
|
||||
- `--card-bg`: 卡片背景
|
||||
- `--text-color`: 文字颜色
|
||||
- `--space-1` to `--space-4`: 间距系统
|
||||
- `--border-radius-xs/sm`: 圆角系统
|
||||
#### 4. 视觉层次
|
||||
```
|
||||
Section Header (20px, bold, accent underline)
|
||||
├── Setting Group (card container, subtle border)
|
||||
│ ├── Setting Label (14px, semibold)
|
||||
│ ├── Setting Description (12px, muted color)
|
||||
│ └── Setting Control (input/select/toggle)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 1: Section折叠/展开 (P1)
|
||||
**Status**: Planned
|
||||
## Optimization Phases
|
||||
|
||||
### Phase 0: macOS Settings模式重构 (P0)
|
||||
**Status**: Ready for Development
|
||||
**Priority**: High
|
||||
|
||||
#### Goals
|
||||
- 进一步减少视觉负担
|
||||
- 允许用户自定义信息密度
|
||||
- 重构为两栏布局(左侧导航 + 右侧内容)
|
||||
- 实现Section级导航切换
|
||||
- 优化视觉层次和间距
|
||||
- 移除冗余元素
|
||||
|
||||
#### Implementation Details
|
||||
- 点击Section标题折叠/展开
|
||||
- 添加chevron图标旋转动画
|
||||
- 记忆用户折叠状态(localStorage)
|
||||
|
||||
##### Layout Specifications
|
||||
| Element | Specification |
|
||||
|---------|--------------|
|
||||
| Modal Width | 800px (比原700px稍宽) |
|
||||
| Modal Height | 600px (固定高度) |
|
||||
| Left Sidebar | 200px 固定宽度 |
|
||||
| Right Content | flex: 1,自动填充 |
|
||||
| Content Padding | --space-3 (24px) |
|
||||
|
||||
##### Navigation Structure
|
||||
```
|
||||
General (通用)
|
||||
├── Language
|
||||
├── Civitai API Key
|
||||
└── Settings Location
|
||||
|
||||
Interface (界面)
|
||||
├── Layout Settings
|
||||
├── Video Settings
|
||||
└── Content Filtering
|
||||
|
||||
Download (下载)
|
||||
├── Folder Settings
|
||||
├── Download Path Templates
|
||||
├── Example Images
|
||||
└── Update Flags
|
||||
|
||||
Advanced (高级)
|
||||
├── Priority Tags
|
||||
├── Auto-organize exclusions
|
||||
├── Metadata refresh skip paths
|
||||
├── Metadata Archive Database
|
||||
├── Proxy Settings
|
||||
└── Misc
|
||||
```
|
||||
|
||||
##### CSS Style Guide
|
||||
|
||||
**Section Header**
|
||||
```css
|
||||
.settings-section-header {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
padding-bottom: var(--space-2);
|
||||
border-bottom: 2px solid var(--lora-accent);
|
||||
margin-bottom: var(--space-3);
|
||||
}
|
||||
```
|
||||
|
||||
**Setting Group (Card)**
|
||||
```css
|
||||
.settings-group {
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--lora-border);
|
||||
border-radius: var(--border-radius-sm);
|
||||
padding: var(--space-3);
|
||||
margin-bottom: var(--space-3);
|
||||
}
|
||||
```
|
||||
|
||||
**Setting Item**
|
||||
```css
|
||||
.setting-item {
|
||||
margin-bottom: var(--space-3);
|
||||
}
|
||||
|
||||
.setting-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.setting-label {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
margin-bottom: var(--space-1);
|
||||
}
|
||||
|
||||
.setting-description {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: var(--space-2);
|
||||
}
|
||||
```
|
||||
|
||||
**Sidebar Navigation**
|
||||
```css
|
||||
.settings-nav-item {
|
||||
padding: var(--space-2) var(--space-3);
|
||||
border-radius: var(--border-radius-xs);
|
||||
cursor: pointer;
|
||||
transition: background 0.2s ease;
|
||||
}
|
||||
|
||||
.settings-nav-item:hover {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.settings-nav-item.active {
|
||||
background: var(--lora-accent);
|
||||
color: white;
|
||||
}
|
||||
```
|
||||
|
||||
#### Files to Modify
|
||||
|
||||
1. **static/css/components/modal/settings-modal.css**
|
||||
- [ ] 新增两栏布局样式
|
||||
- [ ] 新增侧边栏导航样式
|
||||
- [ ] 新增Section标题样式
|
||||
- [ ] 调整设置项卡片样式
|
||||
- [ ] 移除折叠相关的CSS
|
||||
|
||||
2. **templates/components/modals/settings_modal.html**
|
||||
- [ ] 重构为两栏HTML结构
|
||||
- [ ] 添加4个导航项
|
||||
- [ ] 将Section改为独立内容区域
|
||||
- [ ] 移除折叠按钮HTML
|
||||
|
||||
3. **static/js/managers/SettingsManager.js**
|
||||
- [ ] 添加导航点击切换逻辑
|
||||
- [ ] 添加Section显示/隐藏控制
|
||||
- [ ] 移除折叠/展开相关代码
|
||||
- [ ] 默认显示第一个Section
|
||||
|
||||
---
|
||||
|
||||
### Phase 2: 顶部搜索栏 (P1)
|
||||
### Phase 1: 搜索功能 (P1)
|
||||
**Status**: Planned
|
||||
**Priority**: Medium
|
||||
|
||||
#### Goals
|
||||
- 快速定位特定设置项
|
||||
- 支持关键词搜索设置标签和描述
|
||||
|
||||
#### Implementation Details
|
||||
- 实时过滤显示匹配项
|
||||
#### Implementation
|
||||
- 搜索框保持在顶部右侧
|
||||
- 实时过滤:显示匹配的Section和设置项
|
||||
- 高亮匹配的关键词
|
||||
- 使用现有的text-input-wrapper样式
|
||||
- 无结果时显示友好提示
|
||||
|
||||
---
|
||||
|
||||
### Phase 3: 视觉层次优化 (P2)
|
||||
**Status**: Planned
|
||||
|
||||
#### Goals
|
||||
- 提升可读性
|
||||
- 强化Section的视觉区分
|
||||
|
||||
#### Implementation Details
|
||||
- Section标题左侧添加accent色边框
|
||||
- 设置项标签加粗处理
|
||||
- 增大Section间距
|
||||
|
||||
---
|
||||
|
||||
### Phase 4: 快速操作按钮 (P3)
|
||||
### Phase 2: 操作按钮优化 (P2)
|
||||
**Status**: Planned
|
||||
**Priority**: Low
|
||||
|
||||
#### Goals
|
||||
- 增强功能完整性
|
||||
- 提供批量操作能力
|
||||
|
||||
#### Implementation Details
|
||||
- 重置为默认按钮
|
||||
- 导出配置按钮
|
||||
- 导入配置按钮
|
||||
#### Implementation
|
||||
- 底部固定操作栏(position: sticky)
|
||||
- [Cancel] 和 [Save Changes] 按钮
|
||||
- 可选:重置为默认、导出配置、导入配置
|
||||
|
||||
---
|
||||
|
||||
## Files to Modify
|
||||
## Migration Notes
|
||||
|
||||
### Phase 0 Files
|
||||
1. `static/css/components/modal/settings-modal.css`
|
||||
- 新增两栏布局样式
|
||||
- 新增导航栏样式
|
||||
- 调整Modal尺寸
|
||||
### Removed Features
|
||||
| Feature | Reason |
|
||||
|---------|--------|
|
||||
| Section折叠/展开 | 单Section独占显示后不再需要 |
|
||||
| 滚动监听高亮 | 改为点击切换,无需监听滚动 |
|
||||
| 长页面平滑滚动 | 内容不再超长,无需滚动 |
|
||||
| "SETTINGS" label | 冗余信息,移除以简化UI |
|
||||
|
||||
2. `templates/components/modals/settings_modal.html`
|
||||
- 重构HTML结构为两栏布局
|
||||
- 添加导航列表
|
||||
- 为Section添加ID锚点
|
||||
|
||||
3. `static/js/managers/SettingsManager.js`
|
||||
- 添加导航点击处理
|
||||
- 添加滚动监听高亮
|
||||
- 添加平滑滚动行为
|
||||
### Preserved Features
|
||||
- 所有设置项功能和逻辑
|
||||
- 表单验证
|
||||
- 设置项描述和提示
|
||||
- 原有的CSS变量系统
|
||||
|
||||
---
|
||||
|
||||
@@ -178,28 +266,66 @@
|
||||
|
||||
### Phase 0
|
||||
- [ ] Modal显示为两栏布局
|
||||
- [ ] 左侧导航可点击跳转
|
||||
- [ ] 当前Section在导航中高亮
|
||||
- [ ] 滚动时高亮状态同步更新
|
||||
- [ ] 移动端响应式正常
|
||||
- [ ] 所有现有功能正常工作
|
||||
- [ ] 左侧显示4个Section导航
|
||||
- [ ] 点击导航切换右侧显示的Section
|
||||
- [ ] 当前选中导航项高亮显示
|
||||
- [ ] Section标题有accent色下划线
|
||||
- [ ] 设置项以卡片形式分组展示
|
||||
- [ ] 移除所有折叠/展开功能
|
||||
- [ ] 移动端响应式正常(单栏堆叠)
|
||||
- [ ] 所有现有设置功能正常工作
|
||||
- [ ] 设计风格与原有UI一致
|
||||
|
||||
### Phase 1
|
||||
- [ ] 搜索框可输入关键词
|
||||
- [ ] 实时过滤显示匹配项
|
||||
- [ ] 高亮匹配的关键词
|
||||
|
||||
### Phase 2
|
||||
- [ ] 底部有固定操作按钮栏
|
||||
- [ ] Cancel和Save Changes按钮工作正常
|
||||
|
||||
---
|
||||
|
||||
## Timeline
|
||||
|
||||
| Phase | Estimated Time | Status |
|
||||
|-------|---------------|--------|
|
||||
| P0 | 2-3 hours | In Progress |
|
||||
| P1 | 1-2 hours | Planned |
|
||||
| P0 | 3-4 hours | Ready for Development |
|
||||
| P1 | 2-3 hours | Planned |
|
||||
| P2 | 1-2 hours | Planned |
|
||||
| P3 | 1 hour | Planned |
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
- 所有修改优先使用现有CSS变量
|
||||
- 保持向后兼容,不破坏现有功能
|
||||
- 每次Phase完成后进行功能测试
|
||||
- 遵循现有代码风格和命名约定
|
||||
## Reference
|
||||
|
||||
### Design Inspiration
|
||||
- **macOS System Settings**: 左侧导航 + 右侧单Section独占
|
||||
- **VS Code Settings**: 清晰的视觉层次和搜索体验
|
||||
- **Linear**: 简洁的两栏布局设计
|
||||
|
||||
### CSS Variables Reference
|
||||
```css
|
||||
/* Colors */
|
||||
--lora-accent: #007AFF;
|
||||
--lora-border: rgba(255, 255, 255, 0.1);
|
||||
--card-bg: rgba(255, 255, 255, 0.05);
|
||||
--text-color: #ffffff;
|
||||
--text-muted: rgba(255, 255, 255, 0.6);
|
||||
|
||||
/* Spacing */
|
||||
--space-1: 8px;
|
||||
--space-2: 12px;
|
||||
--space-3: 16px;
|
||||
--space-4: 24px;
|
||||
|
||||
/* Border Radius */
|
||||
--border-radius-xs: 4px;
|
||||
--border-radius-sm: 8px;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-02-24
|
||||
**Author**: AI Assistant
|
||||
**Status**: Ready for Implementation
|
||||
|
||||
191
docs/ui-ux-optimization/settings-modal-progress.md
Normal file
191
docs/ui-ux-optimization/settings-modal-progress.md
Normal file
@@ -0,0 +1,191 @@
|
||||
# Settings Modal Optimization Progress
|
||||
|
||||
**Project**: Settings Modal UI/UX Optimization
|
||||
**Status**: Phase 0 - Ready for Development
|
||||
**Last Updated**: 2025-02-24
|
||||
|
||||
---
|
||||
|
||||
## Phase 0: macOS Settings模式重构
|
||||
|
||||
### Overview
|
||||
重构Settings Modal为macOS Settings模式:左侧Section导航 + 右侧单Section独占显示。移除冗余元素,优化视觉层次。
|
||||
|
||||
### Tasks
|
||||
|
||||
#### 1. CSS Updates ✅
|
||||
**File**: `static/css/components/modal/settings-modal.css`
|
||||
|
||||
- [x] **Layout Styles**
|
||||
- [x] Modal固定尺寸 800x600px
|
||||
- [x] 左侧 sidebar 固定宽度 200px
|
||||
- [x] 右侧 content flex: 1 自动填充
|
||||
|
||||
- [x] **Navigation Styles**
|
||||
- [x] `.settings-nav` 容器样式
|
||||
- [x] `.settings-nav-item` 基础样式(更大字体,更醒目的active状态)
|
||||
- [x] `.settings-nav-item.active` 高亮样式(accent背景)
|
||||
- [x] `.settings-nav-item:hover` 悬停效果
|
||||
- [x] 隐藏 "SETTINGS" label
|
||||
- [x] 隐藏 group titles
|
||||
|
||||
- [x] **Content Area Styles**
|
||||
- [x] `.settings-section` 默认隐藏(仅当前显示)
|
||||
- [x] `.settings-section.active` 显示状态
|
||||
- [x] `.settings-section-header` 标题样式(20px + accent下划线)
|
||||
- [x] 添加 fadeIn 动画效果
|
||||
|
||||
- [x] **Cleanup**
|
||||
- [x] 移除折叠相关样式
|
||||
- [x] 移除 `.settings-section-toggle` 按钮样式
|
||||
- [x] 移除展开/折叠动画样式
|
||||
|
||||
**Status**: ✅ Completed
|
||||
|
||||
---
|
||||
|
||||
#### 2. HTML Structure Update ✅
|
||||
**File**: `templates/components/modals/settings_modal.html`
|
||||
|
||||
- [x] **Navigation Items**
|
||||
- [x] General (通用)
|
||||
- [x] Interface (界面)
|
||||
- [x] Download (下载)
|
||||
- [x] Advanced (高级)
|
||||
- [x] 移除 "SETTINGS" label
|
||||
- [x] 移除 group titles
|
||||
|
||||
- [x] **Content Sections**
|
||||
- [x] 重组为4个Section (general/interface/download/advanced)
|
||||
- [x] 每个section添加 `data-section` 属性
|
||||
- [x] 添加Section标题(带accent下划线)
|
||||
- [x] 移除所有折叠按钮(chevron图标)
|
||||
- [x] 平铺显示所有设置项
|
||||
|
||||
**Status**: ✅ Completed
|
||||
|
||||
---
|
||||
|
||||
#### 3. JavaScript Logic Update ✅
|
||||
**File**: `static/js/managers/SettingsManager.js`
|
||||
|
||||
- [x] **Navigation Logic**
|
||||
- [x] `initializeNavigation()` 改为Section切换模式
|
||||
- [x] 点击导航项显示对应Section
|
||||
- [x] 更新导航高亮状态
|
||||
- [x] 默认显示第一个Section
|
||||
|
||||
- [x] **Remove Legacy Code**
|
||||
- [x] 移除 `initializeSectionCollapse()` 方法
|
||||
- [x] 移除滚动监听相关代码
|
||||
- [x] 移除 `localStorage` 折叠状态存储
|
||||
|
||||
- [x] **Search Function**
|
||||
- [x] 更新搜索功能以适配新显示模式
|
||||
- [x] 搜索时自动切换到匹配的Section
|
||||
- [x] 高亮匹配的关键词
|
||||
|
||||
**Status**: ✅ Completed
|
||||
|
||||
---
|
||||
|
||||
### Testing Checklist
|
||||
|
||||
#### Visual Testing
|
||||
- [ ] 两栏布局正确显示
|
||||
- [ ] 左侧导航4个Section正确显示
|
||||
- [ ] 点击导航切换右侧内容
|
||||
- [ ] 当前导航项高亮显示(accent背景)
|
||||
- [ ] Section标题有accent色下划线
|
||||
- [ ] 设置项以卡片形式分组
|
||||
- [ ] 无"SETTINGS" label
|
||||
- [ ] 无折叠/展开按钮
|
||||
|
||||
#### Functional Testing
|
||||
- [ ] 所有设置项可正常编辑
|
||||
- [ ] 设置保存功能正常
|
||||
- [ ] 设置加载功能正常
|
||||
- [ ] 表单验证正常工作
|
||||
- [ ] 帮助提示(tooltip)正常显示
|
||||
|
||||
#### Responsive Testing
|
||||
- [ ] 桌面端(>768px)两栏布局
|
||||
- [ ] 移动端(<768px)单栏堆叠
|
||||
- [ ] 移动端导航可正常切换
|
||||
|
||||
#### Cross-Browser Testing
|
||||
- [ ] Chrome/Edge
|
||||
- [ ] Firefox
|
||||
- [ ] Safari(如适用)
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: 搜索功能
|
||||
|
||||
### Tasks
|
||||
- [ ] 搜索框UI更新
|
||||
- [ ] 搜索逻辑实现
|
||||
- [ ] 实时过滤显示
|
||||
- [ ] 关键词高亮
|
||||
|
||||
**Estimated Time**: 2-3 hours
|
||||
**Status**: 📋 Planned
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: 操作按钮优化
|
||||
|
||||
### Tasks
|
||||
- [ ] 底部操作栏样式
|
||||
- [ ] 固定定位(sticky)
|
||||
- [ ] Cancel/Save按钮功能
|
||||
- [ ] 可选:Reset/Export/Import
|
||||
|
||||
**Estimated Time**: 1-2 hours
|
||||
**Status**: 📋 Planned
|
||||
|
||||
---
|
||||
|
||||
## Progress Summary
|
||||
|
||||
| Phase | Progress | Status |
|
||||
|-------|----------|--------|
|
||||
| Phase 0 | 100% | ✅ Completed |
|
||||
| Phase 1 | 0% | 📋 Planned |
|
||||
| Phase 2 | 0% | 📋 Planned |
|
||||
|
||||
**Overall Progress**: 100% (Phase 0)
|
||||
|
||||
---
|
||||
|
||||
## Development Log
|
||||
|
||||
### 2025-02-24
|
||||
- ✅ 创建优化提案文档(macOS Settings模式)
|
||||
- ✅ 创建进度追踪文档
|
||||
- ✅ Phase 0 开发完成
|
||||
- ✅ CSS重构完成:新增macOS Settings样式,移除折叠相关样式
|
||||
- ✅ HTML重构完成:重组为4个Section,移除所有折叠按钮
|
||||
- ✅ JavaScript重构完成:实现Section切换逻辑,更新搜索功能
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
### Design Decisions
|
||||
- 采用macOS Settings模式而非长页面滚动模式
|
||||
- 左侧仅显示4个Section,不显示具体设置项
|
||||
- 移除折叠/展开功能,简化交互
|
||||
- Section标题使用accent色下划线强调
|
||||
|
||||
### Technical Notes
|
||||
- 优先使用现有CSS变量
|
||||
- 保持向后兼容,不破坏现有设置存储逻辑
|
||||
- 移动端响应式:小屏幕单栏堆叠
|
||||
|
||||
### Blockers
|
||||
None
|
||||
|
||||
---
|
||||
|
||||
**Next Action**: Start Phase 0 - CSS Updates
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Settings styles */
|
||||
/* Settings Modal - macOS Settings Style */
|
||||
.settings-toggle {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
@@ -20,9 +20,10 @@
|
||||
}
|
||||
|
||||
.settings-modal {
|
||||
max-width: 950px;
|
||||
width: 90vw;
|
||||
max-height: 85vh;
|
||||
width: 800px;
|
||||
height: 600px;
|
||||
max-width: 95vw;
|
||||
max-height: 90vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
@@ -49,17 +50,6 @@
|
||||
background: rgba(255, 255, 255, 0.02);
|
||||
}
|
||||
|
||||
.settings-nav-title {
|
||||
font-size: 0.85em;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
color: var(--text-color);
|
||||
opacity: 0.6;
|
||||
margin-bottom: var(--space-2);
|
||||
padding: 0 var(--space-1);
|
||||
}
|
||||
|
||||
.settings-nav-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
@@ -70,28 +60,30 @@
|
||||
margin-bottom: var(--space-2);
|
||||
}
|
||||
|
||||
/* Hide group titles - we use flat navigation */
|
||||
.settings-nav-group-title {
|
||||
font-size: 0.8em;
|
||||
font-weight: 500;
|
||||
color: var(--text-color);
|
||||
opacity: 0.8;
|
||||
padding: var(--space-1) var(--space-1);
|
||||
margin-bottom: var(--space-1);
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Hide settings title */
|
||||
.settings-nav-title {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.settings-nav-item {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 8px 12px;
|
||||
padding: 10px 14px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: var(--text-color);
|
||||
text-align: left;
|
||||
font-size: 0.9em;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
border-radius: var(--border-radius-xs);
|
||||
transition: all 0.2s ease;
|
||||
margin-bottom: 2px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.settings-nav-item:hover {
|
||||
@@ -102,7 +94,7 @@
|
||||
.settings-nav-item.active {
|
||||
background: var(--lora-accent);
|
||||
color: white;
|
||||
font-weight: 500;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Content Area */
|
||||
@@ -560,71 +552,46 @@
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
/* Settings Styles */
|
||||
/* Settings Section - macOS Settings Style */
|
||||
.settings-section {
|
||||
margin-top: var(--space-3);
|
||||
border-top: 1px solid var(--lora-border);
|
||||
padding-top: var(--space-2);
|
||||
display: none;
|
||||
animation: fadeIn 0.2s ease-out;
|
||||
}
|
||||
|
||||
.settings-section.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
.settings-section-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
padding: var(--space-1) 0;
|
||||
margin-bottom: var(--space-2);
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.settings-section-header:hover {
|
||||
opacity: 0.8;
|
||||
padding: 0 0 var(--space-2) 0;
|
||||
margin-bottom: var(--space-3);
|
||||
border-bottom: 2px solid var(--lora-accent);
|
||||
}
|
||||
|
||||
.settings-section-header h3 {
|
||||
font-size: 1.1em;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
color: var(--text-color);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* Remove toggle button styles */
|
||||
.settings-section-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: var(--text-color);
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s ease;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.settings-section-toggle:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.settings-section-toggle .chevron {
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.settings-section.collapsed .settings-section-toggle .chevron {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
.settings-section-content {
|
||||
overflow: hidden;
|
||||
transition: max-height 0.3s ease, opacity 0.3s ease;
|
||||
max-height: 2000px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.settings-section.collapsed .settings-section-content {
|
||||
max-height: 0;
|
||||
opacity: 0;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.setting-item {
|
||||
|
||||
@@ -371,132 +371,39 @@ export class SettingsManager {
|
||||
}
|
||||
|
||||
initializeNavigation() {
|
||||
const settingsContent = document.querySelector('.settings-content');
|
||||
const navItems = document.querySelectorAll('.settings-nav-item');
|
||||
const sections = document.querySelectorAll('.settings-section');
|
||||
|
||||
if (!settingsContent || navItems.length === 0) return;
|
||||
if (navItems.length === 0 || sections.length === 0) return;
|
||||
|
||||
// Handle navigation item clicks
|
||||
// Handle navigation item clicks - macOS Settings style: show section instead of scroll
|
||||
navItems.forEach(item => {
|
||||
item.addEventListener('click', (e) => {
|
||||
const targetId = item.dataset.target;
|
||||
if (!targetId) return;
|
||||
const sectionId = item.dataset.section;
|
||||
if (!sectionId) return;
|
||||
|
||||
const targetSection = document.getElementById(targetId);
|
||||
// Hide all sections
|
||||
sections.forEach(section => {
|
||||
section.classList.remove('active');
|
||||
});
|
||||
|
||||
// Show target section
|
||||
const targetSection = document.getElementById(`section-${sectionId}`);
|
||||
if (targetSection) {
|
||||
targetSection.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
targetSection.classList.add('active');
|
||||
}
|
||||
|
||||
// Update active state
|
||||
// Update active nav state
|
||||
navItems.forEach(nav => nav.classList.remove('active'));
|
||||
item.classList.add('active');
|
||||
});
|
||||
});
|
||||
|
||||
// Setup scroll spy
|
||||
const sections = document.querySelectorAll('.settings-section, .setting-item[id^="section-"]');
|
||||
|
||||
const updateActiveNav = () => {
|
||||
const scrollTop = settingsContent.scrollTop;
|
||||
const contentHeight = settingsContent.clientHeight;
|
||||
|
||||
let currentSection = null;
|
||||
let minDistance = Infinity;
|
||||
|
||||
sections.forEach(section => {
|
||||
const sectionTop = section.offsetTop - settingsContent.offsetTop;
|
||||
const distance = Math.abs(sectionTop - scrollTop);
|
||||
|
||||
if (distance < minDistance) {
|
||||
minDistance = distance;
|
||||
currentSection = section;
|
||||
}
|
||||
});
|
||||
|
||||
if (currentSection) {
|
||||
const sectionId = currentSection.id;
|
||||
navItems.forEach(item => {
|
||||
item.classList.remove('active');
|
||||
if (item.dataset.target === sectionId) {
|
||||
item.classList.add('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Use requestAnimationFrame for performance
|
||||
let ticking = false;
|
||||
settingsContent.addEventListener('scroll', () => {
|
||||
if (!ticking) {
|
||||
window.requestAnimationFrame(() => {
|
||||
updateActiveNav();
|
||||
ticking = false;
|
||||
});
|
||||
ticking = true;
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize section collapse/expand
|
||||
this.initializeSectionCollapse();
|
||||
|
||||
// Initial update
|
||||
updateActiveNav();
|
||||
}
|
||||
|
||||
initializeSectionCollapse() {
|
||||
const sections = document.querySelectorAll('.settings-section, .setting-item[id^="section-"]');
|
||||
const STORAGE_KEY = 'settingsModal_collapsedSections';
|
||||
|
||||
// Load collapsed state from localStorage
|
||||
let collapsedSections = {};
|
||||
try {
|
||||
const stored = localStorage.getItem(STORAGE_KEY);
|
||||
if (stored) {
|
||||
collapsedSections = JSON.parse(stored);
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Failed to load collapsed sections state:', e);
|
||||
// Show first section by default
|
||||
const firstSection = sections[0];
|
||||
if (firstSection) {
|
||||
firstSection.classList.add('active');
|
||||
}
|
||||
|
||||
sections.forEach(section => {
|
||||
const sectionId = section.getAttribute('data-section') || section.id;
|
||||
const header = section.querySelector('.settings-section-header');
|
||||
const toggleBtn = section.querySelector('.settings-section-toggle');
|
||||
|
||||
if (!header || !toggleBtn) return;
|
||||
|
||||
// Apply initial collapsed state
|
||||
if (collapsedSections[sectionId]) {
|
||||
section.classList.add('collapsed');
|
||||
}
|
||||
|
||||
// Handle toggle click
|
||||
const toggleSection = () => {
|
||||
const isCollapsed = section.classList.toggle('collapsed');
|
||||
|
||||
// Save state to localStorage
|
||||
collapsedSections[sectionId] = isCollapsed;
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(collapsedSections));
|
||||
} catch (e) {
|
||||
console.warn('Failed to save collapsed sections state:', e);
|
||||
}
|
||||
};
|
||||
|
||||
// Click on header or toggle button
|
||||
header.addEventListener('click', (e) => {
|
||||
// Don't toggle if clicking on interactive elements within header
|
||||
if (e.target.closest('a, button:not(.settings-section-toggle), input, select')) {
|
||||
return;
|
||||
}
|
||||
toggleSection();
|
||||
});
|
||||
|
||||
toggleBtn.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
toggleSection();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
initializeSearch() {
|
||||
@@ -549,7 +456,8 @@ export class SettingsManager {
|
||||
}
|
||||
|
||||
performSearch(query) {
|
||||
const sections = document.querySelectorAll('.settings-section, .setting-item[id^="section-"]');
|
||||
const sections = document.querySelectorAll('.settings-section');
|
||||
const navItems = document.querySelectorAll('.settings-nav-item');
|
||||
const settingsForm = document.querySelector('.settings-form');
|
||||
|
||||
// Remove existing empty state
|
||||
@@ -559,15 +467,15 @@ export class SettingsManager {
|
||||
}
|
||||
|
||||
if (!query) {
|
||||
// Reset all sections to visible and remove highlights
|
||||
// Reset: remove highlights only, keep current section visible
|
||||
sections.forEach(section => {
|
||||
section.classList.remove('search-hidden', 'search-match');
|
||||
this.removeSearchHighlights(section);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const lowerQuery = query.toLowerCase();
|
||||
let firstMatchSection = null;
|
||||
let matchCount = 0;
|
||||
|
||||
sections.forEach(section => {
|
||||
@@ -575,20 +483,37 @@ export class SettingsManager {
|
||||
const hasMatch = sectionText.includes(lowerQuery);
|
||||
|
||||
if (hasMatch) {
|
||||
section.classList.remove('search-hidden');
|
||||
section.classList.add('search-match');
|
||||
this.highlightSearchMatches(section, lowerQuery);
|
||||
matchCount++;
|
||||
|
||||
// Expand section if it has matches
|
||||
section.classList.remove('collapsed');
|
||||
// Track first match to auto-switch
|
||||
if (!firstMatchSection) {
|
||||
firstMatchSection = section;
|
||||
}
|
||||
} else {
|
||||
section.classList.add('search-hidden');
|
||||
section.classList.remove('search-match');
|
||||
this.removeSearchHighlights(section);
|
||||
}
|
||||
});
|
||||
|
||||
// Auto-switch to first matching section
|
||||
if (firstMatchSection) {
|
||||
const sectionId = firstMatchSection.id.replace('section-', '');
|
||||
|
||||
// Hide all sections
|
||||
sections.forEach(section => section.classList.remove('active'));
|
||||
|
||||
// Show matching section
|
||||
firstMatchSection.classList.add('active');
|
||||
|
||||
// Update nav active state
|
||||
navItems.forEach(item => {
|
||||
item.classList.remove('active');
|
||||
if (item.dataset.section === sectionId) {
|
||||
item.classList.add('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Show empty state if no matches found
|
||||
if (matchCount === 0 && settingsForm) {
|
||||
const emptyState = document.createElement('div');
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user