Skip to content

feat(settings): split monolithic SettingsView into dedicated group pages#288

Merged
connectwithprakash merged 17 commits intomainfrom
feat/285-2-settings-group-pages
Mar 15, 2026
Merged

feat(settings): split monolithic SettingsView into dedicated group pages#288
connectwithprakash merged 17 commits intomainfrom
feat/285-2-settings-group-pages

Conversation

@connectwithprakash
Copy link
Owner

Summary

  • Split monolithic SettingsView into 4 focused page views: General, Notifications, Productivity, Data & About
  • Extract shared utilities (AppearanceMode, formatHour, appVersion, settingsFormWidth) to SettingsHelpers.swift
  • Remove NavigationStack wrapper from AISettingsView (now pushed via route destination)
  • Wire iPad sidebar Settings to ProfileView hub for access to all routes

Test plan

  • Build passes clean
  • SettingsRoute tests (14/14) pass
  • New snapshot tests (16/16) for all 4 page views pass
  • UI tests updated for new navigation paths (General, Notifications, AI Settings)
  • Verify each settings page loads with correct title and sections on device
  • Verify iPad sidebar Settings shows ProfileView hub with all route cards
  • Verify back navigation works from each settings page

Covers all 4 milestone issues:
- #285: Settings reorganization (4 PRs, 16 SP)
- #283: Bidirectional calendar sync (5 PRs, 29 SP)
- #152: On-device knowledge graph + GraphRAG (4 PRs, 26 SP)
- #89: App icon (parallel design work)
Eliminate the intermediate SettingsHomeView page and render all settings
group cards directly on the Me tab for 2-tap depth to any setting.
Matches Apple Settings / Todoist drill-down pattern.

- Replace SettingsHomeView with SettingsRoute enum (updated cases:
  general, notifications, productivity, ai, dataAbout, developer)
- Rewrite ProfileView with inline organize + settings cards, searchable
  filter, empty state, and trimmed query handling
- Remove ProfileDestination.settings; iPad detail goes to SettingsView
- Reset navigation path on deep link and size-class transition
- Add accessibilityIdentifier per card for UI tests and VoiceOver
- Update UI test helpers for flattened layout

Closes #285 (PR 285-1)
Cover SettingsRoute enum (14 unit tests: metadata, identity, search
matching) and Me tab flattened layout (6 UI tests: card visibility,
section headers, navigation, search filtering, empty state).
Replace .searchable() with a custom TextField at the bottom of the
scroll content, matching the iOS Settings app pattern. Update UI
tests to scroll down and use textFields instead of searchFields.
Pin the search field above the tab bar so it's always visible.
Style it to match iOS Settings: dark subtle background, thin
separator border, mic icon, and muted secondary colors.
…tern

Replace VStack-pinned search field with .safeAreaInset(edge: .bottom)
and frosted Capsule(.ultraThinMaterial) to eliminate background color
mismatch between search area and tab bar.
Replace the single SettingsView with focused page views per settings route:
- GeneralSettingsView (appearance, tasks, accessibility)
- BriefingsSettingsView (morning briefing, daily summary, notifications)
- ProductivitySettingsView (calendar sync, focus mode, live activity)
- DataAboutSettingsView (data management, version, privacy/terms)

Extract shared utilities to SettingsHelpers (AppearanceMode, formatHour,
appVersion, settingsFormWidth modifier). Remove NavigationStack wrapper
from AISettingsView since it's now pushed via route destination.

Wire iPad sidebar Settings to ProfileView hub for access to all routes.
Update UI tests to navigate to correct pages after the split.
@netlify
Copy link

netlify bot commented Mar 14, 2026

Deploy Preview for lazyflow canceled.

Name Link
🔨 Latest commit 63b60bb
🔍 Latest deploy log https://app.netlify.com/projects/lazyflow/deploys/69b65b47a15365000970d67a

connectwithprakash and others added 10 commits March 14, 2026 18:39
Inline DataManagementView into DataAboutSettingsView and
NotificationSettingsView into BriefingsSettingsView so all settings
are at most 2 levels deep (Me hub → settings page).

Delete the now-unused child views and re-record snapshot references.
Exclude __Snapshots__ PNGs from test target resources in project.yml
to fix duplicate resource copy conflicts.
Record mode in swift-snapshot-testing always exits non-zero by design.
Remove set -o pipefail and add || true so the workflow proceeds to
commit the re-recorded reference images.
Shell prefix variables may not propagate through xcodebuild to the
simulator test process. Using the step-level env block ensures the
variable is in the process environment tree.
SNAPSHOT_RECORD env var doesn't propagate through xcodebuild to the
simulator test process. Instead, delete existing reference images
before running tests so the default .missing mode re-creates them.
…rs and empty state

Section headers use .textCase(.uppercase) which is visual-only and
doesn't change the accessibility text value. ContentUnavailableView
doesn't reliably expose "No Results" as a staticText. Switch both
tests to use stable accessibilityIdentifiers instead.
… matching

ContentUnavailableView.search doesn't propagate accessibilityIdentifier
to any standard XCTest element type. Wrap in VStack with
.accessibilityElement(children: .combine) and query via
descendants(matching: .any) for reliable cross-version matching.
Search bar on Me tab now matches individual settings items inside
each group page, not just card titles. Tapping a result navigates
to the parent page and scrolls to the matching section.

- Add SettingsSearchItem model with 31 searchable items across all routes
- Update ProfileView to show grouped deep search results
- Add ScrollViewReader + section IDs to all 5 settings views
- Add SettingsRoute.destination(scrollToItemID:) for deep linking
When searching, replace card-level results with individual matching
items for more precise navigation. Removes deduplication that was
hiding deep items when their parent route matched as a card.
@connectwithprakash connectwithprakash merged commit e259462 into main Mar 15, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant