feat(home): custom SVG zone icons for body-zone cards #15

Merged
millianlmx merged 1 commits from feat/zone-card-icons into main 2026-07-20 14:31:34 +02:00
Owner

What

Replaces the hand-drawn SwiftUI Path silhouettes on the Home tab body-zone cards with polished vector SVG artwork — one distinct figure per zone (upper / lower / full body).

Why

The previous ZoneHighlightIcon drew a single shared BodySilhouetteShape for all three zones and differentiated them only by masking the upper / lower / full half with a gradient. The result: three near-identical blocky silhouettes that didn't read as distinct body zones. This ships proper artwork for each zone so the cards are immediately recognizable by shape alone.

Changes

New assets — Assets.xcassets/ZoneIcon{Upper,Lower,Full}.imageset/

Three new imagesets, each with a custom SVG (upper.svg, lower.svg, full.svg) and a Contents.json declaring:

  • idiom: universal (single-scale),
  • preserves-vector-representation: true → Xcode keeps the SVG as crisp vector art at any size instead of rasterizing at build time.

The SVGs use a shared design language: two hero colors (#ff004a warm pink, #262bdf deep indigo), with the warm accent positioned to encode the zone (top for upper, bottom for lower, both ends for full).

Rewritten — Views/Components/ZoneHighlightIcon.swift

  • Deletes BodySilhouetteShape (the hand-coded Path geometry) and the inline zone→gradient switch.
  • New body loads the matching SVG via Image(decorative:) + .resizable().scaledToFit() in the existing 56×80 frame.
  • Public API unchangedZoneHighlightIcon(zone: String). ZoneCard in HomeTab.swift was not touched.
struct ZoneHighlightIcon: View {
    let zone: String

    var body: some View {
        Image(decorative: imageName, bundle: .main)
            .resizable()
            .scaledToFit()
            .frame(width: 56, height: 80)
    }

    private var imageName: String {
        switch zone.lowercased() {
        case "upper-body", "upper": return "ZoneIconUpper"
        case "lower-body", "lower": return "ZoneIconLower"
        default:                    return "ZoneIconFull"
        }
    }
}

Files NOT changed

  • project.ymlResources is already a folder reference; files inside Assets.xcassets are picked up automatically on xcodegen generate.
  • HomeTab.swiftZoneCard calls ZoneHighlightIcon(zone:) unchanged.
  • Theme.swift — untouched (the SVGs ship with their own baked-in colors and do not consume Theme.zoneGradient).

How to review

  1. cd tabatago-swift && xcodegen generate
  2. Build the TabataGo scheme (iOS simulator).
  3. Open the Home tab → the three zone cards (Corps complet / Haut du corps / Bas du corps) should each show a distinct figure in its own gradient.

Verification

  • xcodegen generate succeeds
  • xcodebuild buildBUILD SUCCEEDED under Swift 6 strict concurrency (SWIFT_STRICT_CONCURRENCY=complete)
  • Rendered on iPhone 17 Pro simulator (iOS 26.5) — all three icons display correctly

Notes / follow-ups

  • The SVGs have baked-in colors, so they do not inherit Theme.zoneGradient per card. If we later want the icons to auto-recolor to match the card background, ship single-color SVGs, set "template-rendering-intent": "template" in each Contents.json, and add .foregroundStyle(Theme.zoneGradient(zone)) in ZoneHighlightIcon. Out of scope for this PR.
  • Icon aspect ratios differ slightly from the 56×80 (~1:1.4) frame; scaledToFit() preserves each SVG's native proportions, centering it with small side margins. Tunable later if needed.
## What Replaces the hand-drawn SwiftUI `Path` silhouettes on the Home tab body-zone cards with polished vector SVG artwork — one distinct figure per zone (upper / lower / full body). ## Why The previous `ZoneHighlightIcon` drew a single shared `BodySilhouetteShape` for all three zones and differentiated them only by masking the upper / lower / full half with a gradient. The result: three near-identical blocky silhouettes that didn't read as distinct body zones. This ships proper artwork for each zone so the cards are immediately recognizable by shape alone. ## Changes ### New assets — `Assets.xcassets/ZoneIcon{Upper,Lower,Full}.imageset/` Three new imagesets, each with a custom SVG (`upper.svg`, `lower.svg`, `full.svg`) and a `Contents.json` declaring: - `idiom: universal` (single-scale), - `preserves-vector-representation: true` → Xcode keeps the SVG as crisp vector art at any size instead of rasterizing at build time. The SVGs use a shared design language: two hero colors (`#ff004a` warm pink, `#262bdf` deep indigo), with the warm accent positioned to encode the zone (top for upper, bottom for lower, both ends for full). ### Rewritten — `Views/Components/ZoneHighlightIcon.swift` - Deletes `BodySilhouetteShape` (the hand-coded `Path` geometry) and the inline zone→gradient switch. - New body loads the matching SVG via `Image(decorative:)` + `.resizable().scaledToFit()` in the existing 56×80 frame. - **Public API unchanged** — `ZoneHighlightIcon(zone: String)`. `ZoneCard` in `HomeTab.swift` was not touched. ```swift struct ZoneHighlightIcon: View { let zone: String var body: some View { Image(decorative: imageName, bundle: .main) .resizable() .scaledToFit() .frame(width: 56, height: 80) } private var imageName: String { switch zone.lowercased() { case "upper-body", "upper": return "ZoneIconUpper" case "lower-body", "lower": return "ZoneIconLower" default: return "ZoneIconFull" } } } ``` ### Files NOT changed - `project.yml` — `Resources` is already a folder reference; files inside `Assets.xcassets` are picked up automatically on `xcodegen generate`. - `HomeTab.swift` — `ZoneCard` calls `ZoneHighlightIcon(zone:)` unchanged. - `Theme.swift` — untouched (the SVGs ship with their own baked-in colors and do not consume `Theme.zoneGradient`). ## How to review 1. `cd tabatago-swift && xcodegen generate` 2. Build the `TabataGo` scheme (iOS simulator). 3. Open the Home tab → the three zone cards (Corps complet / Haut du corps / Bas du corps) should each show a distinct figure in its own gradient. ## Verification - ✅ `xcodegen generate` succeeds - ✅ `xcodebuild build` — **BUILD SUCCEEDED** under Swift 6 strict concurrency (`SWIFT_STRICT_CONCURRENCY=complete`) - ✅ Rendered on iPhone 17 Pro simulator (iOS 26.5) — all three icons display correctly ## Notes / follow-ups - The SVGs have baked-in colors, so they do **not** inherit `Theme.zoneGradient` per card. If we later want the icons to auto-recolor to match the card background, ship single-color SVGs, set `"template-rendering-intent": "template"` in each `Contents.json`, and add `.foregroundStyle(Theme.zoneGradient(zone))` in `ZoneHighlightIcon`. Out of scope for this PR. - Icon aspect ratios differ slightly from the 56×80 (~1:1.4) frame; `scaledToFit()` preserves each SVG's native proportions, centering it with small side margins. Tunable later if needed.
millianlmx added 1 commit 2026-07-20 14:24:00 +02:00
feat(home): custom SVG zone icons for body-zone cards
All checks were successful
CI / Detect Changes (pull_request) Successful in 4s
CI / YouTube Worker (pull_request) Has been skipped
CI / Deploy (pull_request) Has been skipped
PR → Build → devicectl Deploy → LGTM / Build & Deploy to iPhone (devicectl) (pull_request) Successful in 6m58s
PR → Build → devicectl Deploy → LGTM / Wait for LGTM comment (pull_request) Successful in 31s
a843a2bd20
Replace the hand-drawn Path silhouettes in ZoneHighlightIcon with
polished vector SVG artwork (upper/lower/full body figures).

- Add ZoneIconUpper/Lower/Full.imagesets to Assets.xcassets with
  preserves-vector-representation for crisp rendering at any size
- Rewrite ZoneHighlightIcon to load the SVG assets via Image with
  scaledToFit, preserving the zone: String API so ZoneCard is unchanged

Verified: xcodegen + xcodebuild (Swift 6 strict concurrency) succeeds;
rendered on iPhone 17 Pro simulator.
Author
Owner

📱 Prêt à tester !

L'app est déployée sur l'iPhone (devicectl).

  • Teste les changements
  • Reply LGTM pour merger
  • Reply KO pour bloquer
## 📱 Prêt à tester ! L'app est déployée sur l'iPhone (devicectl). - Teste les changements - Reply **LGTM** pour merger - Reply **KO** pour bloquer
millianlmx merged commit 8f10fe763d into main 2026-07-20 14:31:34 +02:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: millianlmx/tabatago#15