diff --git a/docs/ui-ux-optimization/settings-modal-optimization-proposal.md b/docs/ui-ux-optimization/settings-modal-optimization-proposal.md index 3d005bc2..53b71a40 100644 --- a/docs/ui-ux-optimization/settings-modal-optimization-proposal.md +++ b/docs/ui-ux-optimization/settings-modal-optimization-proposal.md @@ -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 diff --git a/docs/ui-ux-optimization/settings-modal-progress.md b/docs/ui-ux-optimization/settings-modal-progress.md new file mode 100644 index 00000000..520dd131 --- /dev/null +++ b/docs/ui-ux-optimization/settings-modal-progress.md @@ -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 diff --git a/static/css/components/modal/settings-modal.css b/static/css/components/modal/settings-modal.css index efae43bb..65b2922d 100644 --- a/static/css/components/modal/settings-modal.css +++ b/static/css/components/modal/settings-modal.css @@ -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 { diff --git a/static/js/managers/SettingsManager.js b/static/js/managers/SettingsManager.js index 2ab3335d..cf1a939a 100644 --- a/static/js/managers/SettingsManager.js +++ b/static/js/managers/SettingsManager.js @@ -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'); diff --git a/templates/components/modals/settings_modal.html b/templates/components/modals/settings_modal.html index b709a4f8..edf6d0b1 100644 --- a/templates/components/modals/settings_modal.html +++ b/templates/components/modals/settings_modal.html @@ -31,34 +31,12 @@