Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat: long-press to reorder & hide cards on Today & Vitals - #64

Merged
saksham2001 merged 6 commits into
saksham2001:mainfrom
rgvxsthi:feat/card-reorder
Jul 9, 2026
Merged

saksham2001 merged 6 commits into
saksham2001:mainfrom
rgvxsthi:feat/card-reorder

Conversation

@rgvxsthi

@rgvxsthi rgvxsthi commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

What

Long-press any Today tile or Vitals card to enter an edit mode where cards wiggle and can be dragged to reorder (home-screen style); a Done pill exits. Cards can also be hidden (a "–" badge) and restored (a "Hidden" tray). Card order + visibility persist per screen.

Data safety

Order + hidden state are pure display preferences — lists of MetricKey raw values saved as JSON in UserDefaults (MetricPrefsStore, alongside the existing hidden-metric + resolution prefs). They never touch the SwiftData health samples, the ring/BLE, or any backend. Tolerant decode → a corrupt/missing value falls back to the default order; no data-loss path.

Changes

  • MetricPrefs: todayOrder/vitalsOrder ([String], tolerant-decoded, empty = screen default) + resolvedOrder() merging saved order with currently-visible metrics.
  • Today (LazyVGrid) and Vitals (VStack) render data-driven via ReorderableForEach over the resolved order, filtered by live prefs.isHidden so hide/restore reflect immediately.
  • ReorderableForEach (DesignSystem/CardReorder.swift): wiggle + live onDrag/onDrop reorder; inner card disabled while editing so taps can't navigate; long-press via simultaneousGesture (fires alongside each card's own button); "–" remove badge; VoiceOver move/hide actions; HiddenMetricsTray restore tray.

UX pass — done ✅

The items flagged as "needs UX before merge" are now implemented:

  • Discoverability — kept the instant long-press → jiggle entry (home-screen feel).
  • AccessibilityReduce Motion kills the wiggle (reorder still works via drag); VoiceOver exposes per-card Move up / Move down / Move to top / Hide actions + position, and the Hidden tray exposes Show (drag/badges are invisible to VO).
  • Feel — spring shuffle on reorder; lift-on-pickup (scale + shadow, dimmed in-place copy); exit on tap-outside / Done.
  • Hide / restore — home-screen "–" badge hides a card; a "Hidden" tray ("+") restores it — the full loop lives in edit mode, no Settings changes.
  • Drop targeting — full-cell contentShape drop targets fix the LazyVGrid imprecision.

Fixes from device testing

  • Hide now filters the grid by live prefs.isHidden (not the store's cached visibleMetrics snapshot), so a hidden card drops from the grid immediately.
  • Removed a scroll-to-exit behavior that was both blocking scrolling and dismissing edit mode — you can now scroll through all cards in edit mode.
  • Moved the "–" badge above the drag layer so its tap isn't swallowed by the cell's .onDrag.

Rebased onto current main (includes the AI-coach rehaul). Tested on-device (physical ring).

Long-press any Today tile or Vitals card to enter an edit mode where the cards
wiggle and can be dragged to reorder; a Done pill exits. Order persists per
scope in MetricPrefsStore (UserDefaults) as MetricKey rawValues — a pure display
preference that never touches health data, the ring, or any backend.

- MetricPrefs gains todayOrder/vitalsOrder ([String], tolerant-decoded, empty =
  screen default). resolvedOrder() merges saved order with visible metrics so new
  or never-reordered cards slot into their default position.
- Today (LazyVGrid) and Vitals (VStack) refactored from hardcoded card sequences
  to a data-driven ReorderableForEach over the saved order.
- ReorderableForEach (DesignSystem/CardReorder.swift): wiggle + live onDrag/onDrop
  reorder; inner card disabled while editing so taps can't navigate; long-press
  attached via simultaneousGesture so it fires alongside each card's own button.

NOTE: initial cut — needs further UX before merge (see PR description).
@rgvxsthi
rgvxsthi requested a review from saksham2001 as a code owner July 8, 2026 15:25
saksham2001 and others added 3 commits July 9, 2026 02:57
…l, hide/restore

Builds on the long-press card reorder:
- Keep instant long-press -> jiggle entry (no context menu).
- Reduce Motion: no wiggle; reorder still works via drag + VoiceOver.
- VoiceOver: per-card Move up / Move down / Move to top + Hide actions.
- Feel: spring shuffle, lift-on-pickup (scale + shadow, dimmed in-place copy), exit on tap-outside/scroll.
- Home-screen '-' remove badge to hide a card; a 'Hidden' tray (with '+') in edit mode restores it (full hide/restore loop, no Settings changes).
- LazyVGrid drop-target tuning (full-cell drop).
Limited to CardReorder.swift / TodayView.swift / VitalsView.swift; Settings untouched.
…e minus

- Hide now filters the grid by live prefs.isHidden (not the store's cached
  visibleMetrics snapshot), so the '-' badge / Hidden-tray '+' drop or restore
  a card immediately.
- Removed the scroll-to-exit behavior so you can scroll through all cards in
  edit mode without it dismissing edit mode.
- Moved the '-' remove badge to an overlay above the drag layer so its tap
  isn't swallowed by the cell's .onDrag.
@rgvxsthi rgvxsthi changed the title feat: long-press to reorder cards on Today & Vitals (WIP — needs UX work) feat: long-press to reorder & hide cards on Today & Vitals Jul 9, 2026
@saksham2001
saksham2001 merged commit 338226a into saksham2001:main Jul 9, 2026
2 checks passed
@rgvxsthi
rgvxsthi deleted the feat/card-reorder branch July 16, 2026 04:21
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.

2 participants