moodlit-native/Widgets/MoodlitWidget/MediumMoodsView.swift
till 03dca7d84d μ-7.3: Widget (Small/Medium/Large) + Deep-Link-Handling
WidgetSnapshot-Bridge App ↔ Widget via App-Group-UserDefaults
(`group.ev.mana.moodlit`). MoodStore.refreshWidgetSnapshot läuft
nach loadAll + toggleFavorite und pingt WidgetCenter.

Widget-Extension (`ev.mana.moodlit.widget`, iOS-only app-extension):
- Small: Last-Played oder erstes Favorit als Glow-Tile + Name +
  Animation-Slug
- Medium: 2×2-Grid, bis zu 4 Favoriten, jede Kachel hat eigene
  Link-Destination zum App-Player
- Large: 3×3-Grid, bis zu 9 Favoriten + Footer mit Total-Count
- Empty-State, wenn keine Favoriten gesetzt sind

Deep-Links:
- `moodlit://play/<id>` (Custom-Scheme aus Widget-Tap):
  `url.host == "play"`, ID aus pathComponents
- `https://moodlit.mana.how/play/<id>` (Universal-Link via AASA):
  pathComponents == ["/", "play", "<id>"]
Beide öffnen MoodPlayerView als fullScreenCover direkt auf RootView
(unabhängig vom aktiven Tab).

Wegen Widget-Target-Sharing: `Mood.swiftUIColors` aus HexColor.swift
nach Mood+SwiftUI.swift extrahiert (Widget kennt den Mood-Type nicht).

xcodebuild iOS-Sim + macOS beide BUILD SUCCEEDED. Widget-Extension
korrekt eingebettet in `MoodlitNative.app/PlugIns/`. 11 Unit-Tests
weiter grün.

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

67 lines
1.6 KiB
Swift
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.

import SwiftUI
import WidgetKit
/// Medium-Widget 2×2-Grid mit bis zu 4 Favoriten. Tap auf eine
/// Kachel öffnet die App im Player für das jeweilige Mood.
struct MediumMoodsView: View {
let entry: MoodsEntry
private var moods: [WidgetMood] {
Array((entry.snapshot?.favorites ?? []).prefix(4))
}
var body: some View {
if moods.isEmpty {
emptyState
} else {
grid
}
}
private var grid: some View {
LazyVGrid(columns: [GridItem(.flexible(), spacing: 6), GridItem(.flexible(), spacing: 6)], spacing: 6) {
ForEach(moods) { mood in
Link(destination: URL(string: "moodlit://play/\(mood.id)")!) {
tile(mood)
}
}
}
.padding(6)
}
private func tile(_ mood: WidgetMood) -> some View {
ZStack(alignment: .bottomLeading) {
LinearGradient(
colors: mood.colors.map { Color(hex: $0) },
startPoint: .topLeading,
endPoint: .bottomTrailing
)
LinearGradient(
colors: [.black.opacity(0.55), .clear],
startPoint: .bottom,
endPoint: .center
)
Text(mood.name)
.font(.caption.weight(.semibold))
.foregroundStyle(.white)
.shadow(radius: 3)
.padding(6)
}
.clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous))
}
private var emptyState: some View {
VStack(spacing: 8) {
Image(systemName: "heart").font(.title2)
.foregroundStyle(.white.opacity(0.7))
Text("Markiere Moods als Favorit")
.font(.subheadline)
.foregroundStyle(.white.opacity(0.85))
Text("in der Moodlit-App, dann erscheinen sie hier.")
.font(.caption2)
.foregroundStyle(.white.opacity(0.55))
.multilineTextAlignment(.center)
}
.padding(8)
}
}