moodlit-native/CLAUDE.md
till bbfdff7e3c μ-7.0: Initial moodlit-native Skelett (Pure-Native iOS+macOS)
Pure-Native SwiftUI-App für Moodlit. Pendant zur SvelteKit-Web-App
auf moodlit.mana.how; konsumiert ManaCore + ManaTokens + ManaAuthUI
aus den Schwester-Repos.

Stack:
- SwiftUI Universal (iOS 18 / macOS 15), Swift 6 strict concurrency
- mana-swift-core + mana-swift-ui (lokale SPM-Pakete via XcodeGen)
- Bundle ev.mana.moodlit, Team QP3GLU8PH3, App-Group group.ev.mana.moodlit

Features:
- 24 Mood-Presets als Swift-Konstanten (Port von default-moods.ts)
- Custom-Moods + Sequenzen via MoodlitAPI (Actor mit JWT-Bearer-Calls
  über AuthenticatedTransport, automatischer 401-Retry)
- MoodPlayerView mit Idle-Timer-Off, Status-Bar-Hidden, Timer-Auto-
  Close, Favorite-Toggle, Play/Pause, Auto-Hide-Controls
- SequencePlayerView mit Crossfade-Rotation durch alle Sequence-Moods
  (Net new ggü. Web — dort ist Sequence-Playback nicht verkabelt)
- AnimatedMoodView rendert alle 21 AnimationTypes als 30-fps Timeline-
  View mit sin/cos-modulierten Filter-Effekten
- Cards-Pattern Auth-Gate: Presets ohne Login sichtbar, Custom-
  Creation triggert ManaAuthGate.require → Login-Sheet
- Theme: ManaTheme.twilight Forward (Violett #7c3aed)

Build verified:
- xcodebuild iOS Simulator (iPhone 17) → BUILD SUCCEEDED
- xcodebuild macOS → BUILD SUCCEEDED

Offen (μ-7.1+): Apple-Dev-Portal-Setup (Bundle, Capabilities), TestFlight,
Widget, Settings-UI (Brightness/Speed), Hex-Color-Picker mit Text-Input,
Visual-Polish der per-Animation Effekte.

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

6 KiB

CLAUDE.md — Moodlit-Native

Guidance für Claude Code in diesem Repo.

Wenn du gerade neu bist: lies zuerst STATUS.md. Web-Counterpart: ../moodlit/, Wire-Format-SOT.

Was dieses Repo ist

Moodlit Native — iOS + macOS Universal-App für Ambient-Lighting und Mood-Sequenzen. Pendant zur SvelteKit-Web-App in ../moodlit/, konsumiert ManaCore / ManaAuthUI aus dem mana-swift-core + mana-swift-ui SwiftPM-Workspace, redet mit moodlit-api.mana.how.

Pure-Native (kein WebView) — der Use-Case "Vollbild auf'm Nachttisch" verlangt:

  • UIApplication.isIdleTimerDisabled = true im Player (Bildschirm schaltet nicht in den Lock)
  • statusBarHidden + persistentSystemOverlays(.hidden) für echtes Vollbild
  • Native SwiftUI-Animationen statt CSS-keyframes

Architektonische Invarianten

Beschlossen. Nicht ohne explizite Diskussion antasten.

  1. SwiftUI Universal, Single-Repo. iOS 18 + macOS 15 aus demselben Code. Plattform-Spezifika via #if os(iOS)/#if os(macOS).
  2. mana-auth via ManaAuthUI. Kein eigener Login-Flow. ManaAuthGate wrapt das RootView (Cards-Pattern).
  3. Server-authoritative. Kein lokales Caching im MVP. App ist thin Client zu moodlit-api. Presets bleiben statisch im Bundle (DefaultMoods.all).
  4. Pure-Native, kein WebView. Anders als seepuls/zitare. Begründet durch Player-Use-Case (Status-Bar-Hide + Idle-Timer + native Animationen).
  5. Sequence-Playback ist Native-Plus. Web-App hat das nicht — nur Erstellen/Löschen. Der Sequence-Player ist der Killer- Use-Case der Native-App.
  6. DSGVO via mana-auth/me/data. Profile-Tab leitet via ManaAuthUI zur Vereins-Plattform-DSGVO durch.

Stack

  • SwiftUI Universal (iOS 18 / macOS 15)
  • Swift 6, SWIFT_STRICT_CONCURRENCY=complete
  • mana-swift-core (ManaCore + ManaTokens) + mana-swift-ui (ManaAuthUI)
  • XcodeGen für Projekt-Datei
  • Bundle ev.mana.moodlit, Team QP3GLU8PH3
  • App-Group group.ev.mana.moodlit

Repo-Struktur

moodlit-native/
├── Sources/
│   ├── App/
│   │   ├── MoodlitNativeApp.swift     @main + State-Boot
│   │   └── RootView.swift             TabView/Sidebar + AuthGate
│   ├── Core/
│   │   ├── AppConfig.swift            URLs + Identifiers
│   │   ├── API/
│   │   │   └── MoodlitAPI.swift       Actor, CRUD via AuthenticatedTransport
│   │   ├── Domain/
│   │   │   ├── Mood.swift             Wire-Types (Mood, MoodSequence, Preferences)
│   │   │   ├── AnimationType.swift    21 Animations-Stile
│   │   │   ├── DefaultMoods.swift     24 Presets (Port von default-moods.ts)
│   │   │   └── HexColor.swift         "#rrggbb" → SwiftUI Color
│   │   └── Theme/
│   │       ├── MoodlitTheme.swift     ManaTheme.twilight Forward
│   │       └── MoodlitBrand.swift     ManaBrandConfig für AuthUI
│   ├── Features/
│   │   ├── Moods/
│   │   │   ├── MoodStore.swift        @Observable Store, Cache + Mutations
│   │   │   ├── MoodListView.swift     Grid mit Presets + Custom
│   │   │   ├── MoodCard.swift         Animated Tile mit Context-Menu
│   │   │   └── CreateMoodSheet.swift  Form (Name + Animation + Farben)
│   │   ├── Player/
│   │   │   ├── AnimatedMoodView.swift TimelineView-Renderer (21 Effekte)
│   │   │   └── MoodPlayerView.swift   Vollbild, Idle-Timer-Off, Timer-Auto-Close
│   │   ├── Sequences/
│   │   │   ├── SequenceListView.swift Liste + Play-Button
│   │   │   ├── SequencePlayerView.swift Crossfade-Rotation (Native-Plus!)
│   │   │   └── CreateSequenceSheet.swift Mood-Multipicker
│   │   └── Settings/
│   │       └── ProfileView.swift      Login-Status + Logout
│   └── Resources/
│       ├── Info.plist
│       └── MoodlitNative.entitlements
├── Tests/UnitTests/                   (TODO μ-7.2)
├── project.yml                        XcodeGen-Definition
├── README.md
├── STATUS.md
└── CLAUDE.md (diese Datei)

Animations-Layer

AnimatedMoodView rendert per TimelineView mit 30 fps und dispatched über einen MoodEffectModifier auf die 21 AnimationTypes. Effekte sind bewusst kompakt (≤ 5 Zeilen pro Branch) — keine Magie, nur sin/cos-modulierte brightness/scale/opacity/hueRotation.

Detaillierte Effekte ggü. dem Web-Stand:

  • sunrise/sunset — eigene Brightness/Saturate-Crescendos (parity)
  • sparkle — Brightness-Puls (nicht Particles; Web hat dasselbe)
  • disco/ravehueRotation continuous
  • sos — explizites Morse-Pattern via Array
  • Rest — sin/cos-Modulation

Per-Animation feintuning kommt mit μ-7.1 (Lost-Pixel-artige Vergleichs- Snapshots gegen Web sind nicht geplant — visual judgment).

Wichtige Cross-Repo-Doks

  • ../moodlit/STATUS.md — Web-App-Stand (heute live auf moodlit.mana.how)
  • ../moodlit/apps/api/src/routes/ — Wire-Format-SOT
  • ../mana/docs/MANA_SWIFT.md — Native-Plattform-SOT
  • ../mana-swift-core/CLAUDE.md — Core-Package
  • ../mana-swift-ui/CLAUDE.md — UI-Package

Lokal entwickeln

xcodegen                                    # → MoodlitNative.xcodeproj
xcodebuild -project MoodlitNative.xcodeproj \
  -scheme MoodlitNative \
  -destination 'platform=iOS Simulator,name=iPhone 17' \
  -derivedDataPath /tmp/moodlit-native-dd \
  CODE_SIGNING_ALLOWED=NO build
open MoodlitNative.xcodeproj
# Cmd+R in Xcode

Voraussetzungen:

  • Xcode 16+
  • mana-swift-core + mana-swift-ui als Schwester-Repos
  • Apple-Developer-Account mit Team QP3GLU8PH3-Mitgliedschaft

Apple-Dev-Portal (offen)

Vor erstem TestFlight-Upload muss Till manuell anlegen:

  1. Bundle ev.mana.moodlit (App ID)
  2. Capabilities: Associated Domains (applinks:moodlit.mana.how), App Groups (group.ev.mana.moodlit), Keychain Sharing
  3. Provisioning Profile via Auto-Manage in Xcode