Implement main app navigation

This commit is contained in:
2026-05-08 14:03:26 +02:00
parent f7e866a08d
commit 794e27c554
90 changed files with 11725 additions and 187 deletions

View File

@@ -0,0 +1,169 @@
---
phase: 02.1-app-shell-navigation-search-foundation
plan: 03
subsystem: ui
tags: [kotlin, compose-multiplatform, glass, liquid, haze, composition-local, multiplatform-settings]
requires:
- phase: 02.1-01
provides: Liquid, Haze, and multiplatform-settings dependencies
- phase: 02.1-02
provides: RecipeTheme color tokens used by GlassSurface defaults
provides:
- GlassSurface public chrome primitive with Liquid, Haze, and flat backends
- GlassBackdropSource shared source wrapper for Liquid/Haze sampling
- debug-gated resolveGlassBackend helper and platform isDebugBuild actuals
- resolver tests for V-02 and V-03 validation anchors
affects: [app-shell, dock, search, ui-chrome, phase-10-polish]
tech-stack:
added: []
patterns: [CompositionLocal backend dispatch, Recipe-owned glass wrapper, local test fake for Settings]
key-files:
created:
- composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/ui/components/glass/GlassBackend.kt
- composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/ui/components/glass/GlassBackdrop.kt
- composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/ui/components/glass/GlassSurface.kt
- composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/ui/components/glass/LiquidGlassSurface.kt
- composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/ui/components/glass/HazeGlassSurface.kt
- composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/ui/components/glass/FlatGlassSurface.kt
- composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/ui/components/glass/IsDebugBuild.kt
- composeApp/src/iosMain/kotlin/dev/ulfrx/recipe/ui/components/glass/IsDebugBuild.ios.kt
- composeApp/src/androidMain/kotlin/dev/ulfrx/recipe/ui/components/glass/IsDebugBuild.android.kt
modified:
- composeApp/src/commonTest/kotlin/dev/ulfrx/recipe/ui/components/glass/GlassBackendTest.kt
- composeApp/src/commonTest/kotlin/dev/ulfrx/recipe/ui/components/glass/GlassBackendOverrideTest.kt
key-decisions:
- "Android debug detection uses the runtime ApplicationInfo.FLAG_DEBUGGABLE fallback because BuildConfig is not available on this module's Kotlin compile classpath."
- "Haze 1.6.10 uses Modifier.hazeEffect(state, style) instead of the deprecated hazeChild API, with hazeSource(state) on the backdrop."
- "multiplatform-settings-test was not added because this wave owns only glass files; the tests use a local Settings fake named MapSettings."
patterns-established:
- "GlassSurface dispatches by LocalGlassBackend while preserving one tint/radius/border call-site API."
- "GlassBackdropSource hides Liquid/Haze source wiring behind Recipe-owned state."
requirements-completed: [UI-04]
duration: 7min
completed: 2026-05-08
---
# Phase 02.1 Plan 03: Glass Backend Summary
**Layered glass chrome primitive with debug-gated backend resolution, shared Liquid/Haze backdrop sampling, and resolver tests for default and override behavior.**
## Performance
- **Duration:** 7 min
- **Started:** 2026-05-08T12:43:07Z
- **Completed:** 2026-05-08T12:50:27Z
- **Tasks:** 3
- **Files modified:** 12
## Accomplishments
- Added `GlassSurface(...)` as the single public chrome primitive dispatching to Liquid, Haze, or flat via `LocalGlassBackend`.
- Added `GlassBackdropSource` / `LocalGlassBackdropState` so future AppShell body content can feed the same Liquid/Haze sampling state consumed by dock/search chrome.
- Replaced ignored glass validation stubs with 8 resolver assertions covering defaults, invalid settings, debug overrides, case-insensitive parsing, and production short-circuiting.
## Task Commits
Each task was committed atomically:
1. **Task 1: Backend resolver and debug gates** - `3043dad` (feat)
2. **Task 2: Glass backdrop and backend surfaces** - `c13a0ab` (feat)
3. **Task 3: Glass resolver tests** - `ee465a1` (test)
**Plan metadata:** this docs commit
## Files Created/Modified
- `composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/ui/components/glass/GlassBackend.kt` - Backend enum, CompositionLocal, debug key, and pure resolver.
- `composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/ui/components/glass/GlassBackdrop.kt` - Shared Recipe-owned backdrop/source wrapper.
- `composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/ui/components/glass/GlassSurface.kt` - Public dispatcher with shared tint/radius/border API.
- `composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/ui/components/glass/LiquidGlassSurface.kt` - Liquid backend using `Modifier.liquid(state)` and `Modifier.liquefiable(state)`.
- `composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/ui/components/glass/HazeGlassSurface.kt` - Haze backend using `Modifier.hazeEffect(state, style)` and `Modifier.hazeSource(state)`.
- `composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/ui/components/glass/FlatGlassSurface.kt` - Flat translucent fallback.
- `composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/ui/components/glass/IsDebugBuild.kt` - Common debug-build gate declaration.
- `composeApp/src/iosMain/kotlin/dev/ulfrx/recipe/ui/components/glass/IsDebugBuild.ios.kt` - Kotlin/Native `Platform.isDebugBinary` actual.
- `composeApp/src/androidMain/kotlin/dev/ulfrx/recipe/ui/components/glass/IsDebugBuild.android.kt` - Android debuggable-flag actual.
- `composeApp/src/commonTest/kotlin/dev/ulfrx/recipe/ui/components/glass/GlassBackendTest.kt` - V-02 resolver tests plus local `MapSettings` fake.
- `composeApp/src/commonTest/kotlin/dev/ulfrx/recipe/ui/components/glass/GlassBackendOverrideTest.kt` - V-03 override tests.
## Decisions Made
- Confirmed Liquid 1.1.1 API locally: `Modifier.liquid(state) { ... }`, `Modifier.liquefiable(state)`, and `rememberLiquidState()`.
- Confirmed Haze 1.6.10 API divergence from the plan: `hazeChild` is deprecated and fails under `-Werror`, so the backend uses `Modifier.hazeEffect(state, style)` with `Modifier.hazeSource(state)` for the source layer.
- Did not add `multiplatform-settings-test`; ownership was limited to glass files, so the tests carry a minimal local `MapSettings` implementation of `Settings`.
## Deviations from Plan
### Auto-fixed Issues
**1. [Rule 3 - Blocking] Android BuildConfig.DEBUG was unavailable**
- **Found during:** Task 1
- **Issue:** `dev.ulfrx.recipe.BuildConfig.DEBUG` did not resolve on the Kotlin compile classpath.
- **Fix:** Switched Android `isDebugBuild` to read the current application's `ApplicationInfo.FLAG_DEBUGGABLE` flag.
- **Files modified:** `composeApp/src/androidMain/kotlin/dev/ulfrx/recipe/ui/components/glass/IsDebugBuild.android.kt`
- **Verification:** `./gradlew :composeApp:compileDebugKotlinAndroid -q` passed.
- **Committed in:** `3043dad`
**2. [Rule 3 - Blocking] Haze child API was deprecated under -Werror**
- **Found during:** Task 2
- **Issue:** `Modifier.hazeChild(...)` exists in Haze 1.6.10 but is deprecated; warnings are errors in this repo.
- **Fix:** Used the current `Modifier.hazeEffect(state, style)` API and retained shared source wiring through `Modifier.hazeSource(state)`.
- **Files modified:** `composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/ui/components/glass/HazeGlassSurface.kt`
- **Verification:** iOS and Android compile targets passed.
- **Committed in:** `c13a0ab`
**3. [Rule 3 - Blocking] MapSettings test artifact was not on the test classpath**
- **Found during:** Task 3
- **Issue:** `com.russhwolf.settings.MapSettings` was unresolved, and the wave ownership excluded Gradle dependency edits.
- **Fix:** Added a minimal package-local `MapSettings` fake in the owned glass test file that implements `Settings`.
- **Files modified:** `composeApp/src/commonTest/kotlin/dev/ulfrx/recipe/ui/components/glass/GlassBackendTest.kt`
- **Verification:** `./gradlew :composeApp:compileTestKotlinIosSimulatorArm64 -q` and `./gradlew :composeApp:iosSimulatorArm64Test -q` passed.
- **Committed in:** `ee465a1`
---
**Total deviations:** 3 auto-fixed (all Rule 3 blocking issues).
**Impact on plan:** Behavior and public contracts are intact. The only API divergence is using Haze's non-deprecated 1.6.10 modifier name.
## Issues Encountered
- `:composeApp:commonTest` is not a registered Gradle task, consistent with prior Phase 02.1 summaries. Used `:composeApp:compileTestKotlinIosSimulatorArm64` and `:composeApp:iosSimulatorArm64Test` as the executable common-source validation path.
- `:composeApp:iosSimulatorArm64Test` emitted external debug-info warnings from cached cryptography artifacts but exited 0.
## Known Stubs
None.
## Verification
- `./gradlew :composeApp:compileKotlinIosSimulatorArm64 -q` - PASS
- `./gradlew :composeApp:compileDebugKotlinAndroid -q` - PASS
- `./gradlew :composeApp:compileTestKotlinIosSimulatorArm64 -q` - PASS
- `./gradlew :composeApp:iosSimulatorArm64Test -q` - PASS
- `./gradlew :composeApp:commonTest --tests "dev.ulfrx.recipe.ui.components.glass.*" -q` - NOT AVAILABLE, task does not exist
- Material 3 boundary preserved: every file under `ui/components/glass/` returned `0` for `androidx.compose.material3`.
- Liquid/Haze imports are confined to `LiquidGlassSurface.kt` and `HazeGlassSurface.kt`; dispatcher/gate/flat files returned `0` matches.
## User Setup Required
None - no external service configuration required.
## Next Phase Readiness
Plans 02.1-05 and 02.1-06 can consume `GlassSurface` and wrap screen content with `GlassBackdropSource` without importing Liquid or Haze directly.
## Self-Check: PASSED
- All created/modified files listed in this summary exist on disk.
- Task commits `3043dad`, `c13a0ab`, and `ee465a1` exist in git history.
- `.planning/STATE.md` and `.planning/ROADMAP.md` were not modified by this executor.
---
*Phase: 02.1-app-shell-navigation-search-foundation*
*Completed: 2026-05-08*