moodlit-native/STATUS.md
till 206fff422e μ-7.7: Spotlight-Indexing für Moods + Sequenzen
Presets + Custom-Moods + Sequenzen sind über CSSearchable im
Spotlight + Siri-Vorschlägen auffindbar. Tippen routet via
`uniqueIdentifier` (Format `mood:<id>` / `sequence:<id>`) in
RootView zurück → öffnet MoodPlayerView (Moods) oder springt in
Sequenzen-Tab.

Sources/Core/Search/SpotlightIndexer.swift mit zwei Domains
(`ev.mana.moodlit.moods`, `ev.mana.moodlit.sequences`). Domain-
basiertes `deleteSearchableItems` clearen beim Logout — kein
Eintrag des abgemeldeten Kontos bleibt im system-weiten Index.

MoodStore-Integration:
- `refreshSpotlightIndex()` läuft initial im RootView-`task`
  (Presets sofort findbar ohne Login) und nach jedem `loadAll`.
- `clearSpotlightIndex()` beim Auth-Wechsel signedOut.

RootView:
- `onContinueUserActivity(CSSearchableItemActionType)` parsed den
  uniqueIdentifier mit prefix-Check, setzt deepLinkMoodId oder
  selectedTab.
- `authStatusKey()`-Helper für Equatable-onChange auf AuthClient.Status
  (Cases mit assoziierten Werten sind nicht direkt Equatable).

xcodebuild iOS-Sim + macOS BUILD SUCCEEDED; 11/11 Unit-Tests grün.

ShareExt (Photo→Palette→Mood) wäre der natürliche moodlit-Use-
Case, ist aber 2-3h Vision/CoreImage-Arbeit für sich — deferred
auf eigenen Sprint.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 15:39:42 +02:00

162 lines
7.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Moodlit-Native — Status
Letzter Stand: **2026-05-18**
## Phase
**μ-7.7 ✅ Spotlight-Indexing.** Presets + Custom-Moods + Sequenzen
sind in CSSearchable. Tap im Spotlight öffnet Player oder springt
in Sequenzen-Tab. Logout cleared den Index. Build weiter grün
iOS + macOS, 11/11 Unit-Tests grün. **Bereit für TestFlight-Upload
sobald Apple-Dev-Portal-Setup steht (Till manuell).**
## Was steht — μ-7.0
- **Pure-Native Architektur** (kein WebView). SwiftUI Universal
iOS 18 + macOS 15.
- **`ManaCore` + `ManaTokens` + `ManaAuthUI`** via XcodeGen local-path-
Packages. Theme = `ManaTheme.twilight` Forward, Login-Sheets im
Moodlit-Violett-Branding.
- **`MoodlitAPI`** Actor mit allen CRUD-Endpoints (Moods, Sequences,
Preferences) via `AuthenticatedTransport`. JWT-Refresh + 401-Retry
kommen aus ManaCore.
- **24 Presets** als Swift-Konstanten in `DefaultMoods.all` (Port
von `default-moods.ts`, identische Reihenfolge + IDs).
- **21 AnimationTypes** in `AnimatedMoodView` als TimelineView mit
30-fps-Modulation (`brightness`/`opacity`/`hueRotation`/`scale`).
Eigene Implementierungen für `sunrise/sunset/sos`, der Rest ist
`sin/cos`-Formel.
- **`MoodPlayerView`** — Vollbild mit Play/Pause, 1/5/10/15/30/60min-
Timer, Favorite-Toggle, Auto-Hide-Controls nach 3s, **Idle-Timer-
Disabled** (kein Screen-Lock), Status-Bar-Hidden auf iOS.
- **`SequencePlayerView`** — **Net new gegenüber Web!** Crossfade
durch alle Moods nach `durationSec` Sekunden, `transitionSec`
Übergang, Next/Prev/Pause-Controls.
- **Cards-Pattern Auth-Gate** — Presets sichtbar ohne Login, beim
ersten Klick auf "Neues Mood" / "Neue Sequenz" springt der
`ManaAuthGate` mit Login-Sheet auf.
- **App-Group `group.ev.mana.moodlit`** für UserDefaults-Sharing
(Guest-Favoriten lokal, Widget-Daten ab μ-7.6).
## Was steht — μ-7.1
- **Hex-Color-Picker funktioniert**: `Color.toHexString()` via
PlatformColor (UIColor iOS / NSColor macOS sRGB), CreateMoodSheet
hält `[String]` (Hex) als SOT, ColorPicker + TextField binden
beidseitig konvertierend.
- **Random Hex** für „+ Farbe hinzufügen".
## Was steht — μ-7.2 (Tests)
11 Tests in `Tests/UnitTests/DomainCodingTests.swift`, alle grün:
- Mood/MoodSequence/Preferences Decode-Roundtrip gegen API-Wire-Format
- AnimationSpeed slow/normal/fast Enum-Decoding
- DefaultMoods: 24 Einträge, unique IDs, bekannte Slugs, alle
AnimationTypes vorhanden
- HexColor Parsing-Smoke
## Was steht — μ-7.3 (Widget + Deep-Links)
- **`WidgetSnapshot`** Codable-Bridge App↔Widget via App-Group-
UserDefaults (`group.ev.mana.moodlit`). Speichert Favoriten +
Last-Played mit flachen Hex-Colors statt SwiftUI Color
(Widget-Process kann keine App-Bundle-Color dereferenzieren).
- **`MoodStore.refreshWidgetSnapshot`** läuft nach jedem `loadAll`
und `toggleFavorite`, pingt `WidgetCenter.shared.reloadAllTimelines()`.
- **`MoodlitWidgetExtension`** (iOS-only app-extension,
Bundle `ev.mana.moodlit.widget`) mit 3 Größen:
- Small: Last-Played oder erstes Favorit als Glow-Tile
- Medium: 2×2-Grid mit bis zu 4 Favoriten
- Large: 3×3-Grid mit bis zu 9 Favoriten + Footer-Count
- **Deep-Links** `moodlit://play/<id>` (Custom-Scheme aus Widget-
Tap) UND `https://moodlit.mana.how/play/<id>` (Universal-Link
via AASA) öffnen `MoodPlayerView` als fullScreenCover über
RootView — funktioniert egal welcher Tab gerade aktiv ist.
- Widget-Extension korrekt in `MoodlitNative.app/PlugIns/` embedded
(verifiziert per `find /tmp/...-dd`).
## Was steht — μ-7.4 (TestFlight-Blocker behoben)
- `Sources/Resources/Assets.xcassets/AppIcon.appiconset/` mit
1024×1024 Moodlit-Glow-PNG (Python PIL: radialer Verlauf hell-
Lavendel → #7c3aed → dunkel-Violett + 8 verschwommene Strahlen).
- Contents.json mit 3 Einträgen (light/dark/tinted Pattern für
iOS 18).
- Asset-Catalog-Compiler generiert daraus automatisch alle Sizes
inklusive iPhone 120×120 und iPad 152×152, CFBundleIconName
landet im Info.plist.
## Was steht — μ-7.6 (Settings-UI)
- Neuer Settings-Tab in TabView (iOS) + Sidebar (macOS).
- Helligkeit-Slider 20100% → `Preferences.brightness`, debounced
PATCH alle 600ms.
- Animations-Tempo Picker slow/normal/fast → `Preferences.animationSpeed`.
- Standard-Timer-Dauer (Aus/1/5/10/15/30/60 min) in App-Group-
UserDefaults — Player liest beim onAppear.
- Guest-Hinweis: lokale Werte aktiv, persistieren erst nach Login.
- `MoodStore.playerBrightness/playerSpeedMultiplier` als Convenience-
Reader für `MoodPlayerView` (über `.brightness()`-Modifier +
AnimatedMoodView-speedMultiplier-Parameter).
## Was steht — μ-7.7 (Spotlight)
- `Sources/Core/Search/SpotlightIndexer.swift` mit zwei Domains
(`ev.mana.moodlit.moods`, `ev.mana.moodlit.sequences`).
- CSSearchableItem pro Mood (title=name, description=Animation-
Display-Name, keywords=Slug+Display+Stimmung+Mood+Sequence) und
pro Sequence (title=name, description=Anzahl + Dauer/Mood).
- `MoodStore.refreshSpotlightIndex` läuft initial im RootView-`task`
(Presets sofort findbar, auch ohne Login) und nach jedem `loadAll`.
- `clearSpotlightIndex` beim Auth-Wechsel auf signedOut — keine
Einträge eines abgemeldeten Kontos bleiben im system-weiten Index.
- RootView `onContinueUserActivity(CSSearchableItemActionType)`
parsed den uniqueIdentifier (`mood:<id>` / `sequence:<id>`),
routet zu Player oder Sequenzen-Tab.
## Was noch fehlt
- **μ-7.5 Apple-Dev-Portal** — Bundle `ev.mana.moodlit` + Widget-
Bundle `ev.mana.moodlit.widget` + Capabilities (Associated
Domains, App Groups, Keychain Sharing) manuell anlegen (Till).
- **μ-7.6 ASC App-Record** + TestFlight-Upload (nach Apple-Dev-
Portal-Setup).
- **μ-7.8 Visual-Polish**: feinere Animationskurven, evtl. `Canvas`-
basierte Partikel für `sparkle`/`aurora`. Brightness-Slider
hat heute via `.brightness(b - 1.0)` einen einfachen Mapping —
visueller Test auf echter Hardware fehlt.
- **ShareExt (deferred)**: Photo → Palette-Extraktion → vorgefülltes
CreateMoodSheet wäre der natürliche moodlit-Use-Case (Sunset-Foto
→ Sunset-Mood), ist aber 2-3h Vision/CoreImage-Arbeit für sich.
Nicht in μ-7.7 enthalten.
## Build-Verification
```bash
# iOS Simulator
xcodebuild -project MoodlitNative.xcodeproj -scheme MoodlitNative \
-destination 'platform=iOS Simulator,name=iPhone 17' \
-derivedDataPath /tmp/moodlit-native-dd \
CODE_SIGNING_ALLOWED=NO build
# → ** BUILD SUCCEEDED **
# macOS
xcodebuild -project MoodlitNative.xcodeproj -scheme MoodlitNative \
-destination 'platform=macOS' \
-derivedDataPath /tmp/moodlit-native-mac \
CODE_SIGNING_ALLOWED=NO build
# → ** BUILD SUCCEEDED **
```
## Bewusst nicht gemacht
- **Hybrid mit WKWebView** — Pure-Native gewählt wegen Player-
Anforderungen (Idle-Timer-Disable, echtes Vollbild, native Effekte).
- **`autoMoodSwitch`-Random-Mode** — Schema-Feld ist in `Preferences`,
UI dafür kommt mit μ-7.7.
- **Local SwiftData-Caching** — App lebt vom Server (loadAll bei
Mount + scenePhase==.active). Offline-Read kann mit μ-9+ kommen
via mana-sync-Integration (analog Herbatrium).
- **Particle-System für `sparkle`** — Web-Version hat das auch nicht
(war im alten managarten als float-up keyframes, im Lift verworfen).
Brightness-Puls reicht für MVP.