MoodCard-Kontextmenü um Favorit/Aus-Favoriten erweitert (store. toggleFavorite), an beiden Grid-Aufrufstellen verdrahtet. SequenceRow bekommt ein Kontextmenü (Abspielen + Löschen) parallel zum Swipe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
89 lines
2.1 KiB
Swift
89 lines
2.1 KiB
Swift
import SwiftUI
|
|
|
|
/// Karten-Vorschau eines Mood — statische Gradient-Tile in der
|
|
/// Übersichts-Grid (kein TimelineView, damit die Auswahl nicht
|
|
/// flimmert). Klick öffnet `MoodPlayerView` mit der Animation.
|
|
public struct MoodCard: View {
|
|
let mood: Mood
|
|
let isFavorite: Bool
|
|
let onTap: () -> Void
|
|
let onToggleFavorite: (() -> Void)?
|
|
let onDelete: (() -> Void)?
|
|
|
|
public init(
|
|
mood: Mood,
|
|
isFavorite: Bool = false,
|
|
onTap: @escaping () -> Void,
|
|
onToggleFavorite: (() -> Void)? = nil,
|
|
onDelete: (() -> Void)? = nil
|
|
) {
|
|
self.mood = mood
|
|
self.isFavorite = isFavorite
|
|
self.onTap = onTap
|
|
self.onToggleFavorite = onToggleFavorite
|
|
self.onDelete = onDelete
|
|
}
|
|
|
|
public var body: some View {
|
|
Button(action: onTap) {
|
|
ZStack(alignment: .bottomLeading) {
|
|
staticPreview
|
|
.aspectRatio(16.0 / 10.0, contentMode: .fill)
|
|
.frame(maxWidth: .infinity)
|
|
.clipShape(RoundedRectangle(cornerRadius: 16, style: .continuous))
|
|
|
|
LinearGradient(
|
|
colors: [.black.opacity(0.55), .clear],
|
|
startPoint: .bottom,
|
|
endPoint: .center
|
|
)
|
|
.clipShape(RoundedRectangle(cornerRadius: 16, style: .continuous))
|
|
.allowsHitTesting(false)
|
|
|
|
Text(mood.name)
|
|
.font(.headline)
|
|
.foregroundStyle(.white)
|
|
.shadow(radius: 4)
|
|
.padding(12)
|
|
|
|
if isFavorite {
|
|
Image(systemName: "heart.fill")
|
|
.foregroundStyle(.red)
|
|
.shadow(radius: 4)
|
|
.padding(10)
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topTrailing)
|
|
.allowsHitTesting(false)
|
|
}
|
|
}
|
|
}
|
|
.buttonStyle(.plain)
|
|
.contextMenu {
|
|
if let onToggleFavorite {
|
|
Button(action: onToggleFavorite) {
|
|
Label(
|
|
isFavorite ? "Aus Favoriten" : "Favorit",
|
|
systemImage: isFavorite ? "heart.slash" : "heart"
|
|
)
|
|
}
|
|
}
|
|
if let onDelete, !mood.isPreset {
|
|
Button(role: .destructive, action: onDelete) {
|
|
Label("Löschen", systemImage: "trash")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@ViewBuilder
|
|
private var staticPreview: some View {
|
|
if mood.colors.count == 1 {
|
|
Color(hex: mood.colors[0])
|
|
} else {
|
|
LinearGradient(
|
|
colors: mood.swiftUIColors,
|
|
startPoint: .topLeading,
|
|
endPoint: .bottomTrailing
|
|
)
|
|
}
|
|
}
|
|
}
|