Files
FeelAloud/FeelAloud/SnapshotView.swift
2026-07-22 22:18:33 +02:00

156 lines
5.4 KiB
Swift

import SwiftData
import SwiftUI
import UIKit
struct SnapshotView: View {
let source: SnapshotSource
@Environment(\.dismiss) private var dismiss
@Environment(\.modelContext) private var modelContext
@State private var savedRating: SnapshotRating?
private let columns = Array(
repeating: GridItem(.flexible(), spacing: 6),
count: SnapshotRating.allCases.count
)
var body: some View {
VStack(spacing: 28) {
Spacer()
VStack(spacing: 8) {
Text("Wie geht es dir gerade?")
.font(.largeTitle.bold())
.multilineTextAlignment(.center)
Text("Ein Tipp genügt.")
.foregroundStyle(.secondary)
}
LazyVGrid(columns: columns, spacing: 10) {
ForEach(SnapshotRating.allCases) { rating in
Button {
save(rating)
} label: {
VStack(spacing: 9) {
Text(rating.emoji)
.font(.system(size: 43))
.scaleEffect(savedRating == rating ? 1.12 : 1)
Text(rating.rawValue)
.font(.caption2.weight(.medium))
.multilineTextAlignment(.center)
.foregroundStyle(.primary)
.lineLimit(2)
.minimumScaleFactor(0.8)
}
.frame(maxWidth: .infinity, minHeight: 100)
.padding(.vertical, 8)
.background(
savedRating == rating
? rating.color.opacity(0.17)
: Color(.secondarySystemGroupedBackground),
in: RoundedRectangle(cornerRadius: 18)
)
}
.buttonStyle(.plain)
.disabled(savedRating != nil)
.accessibilityLabel(rating.rawValue)
}
}
Text("Die Momentaufnahme wird ausschließlich auf diesem iPhone gespeichert.")
.font(.footnote)
.foregroundStyle(.secondary)
.multilineTextAlignment(.center)
Spacer()
}
.padding(20)
.background(Color(.systemGroupedBackground))
.appKeyboardBehavior()
.presentationDragIndicator(.visible)
}
private func save(_ rating: SnapshotRating) {
guard savedRating == nil else { return }
savedRating = rating
modelContext.insert(MoodSnapshot(rating: rating, source: source))
try? modelContext.save()
UINotificationFeedbackGenerator().notificationOccurred(.success)
Task {
try? await Task.sleep(for: .milliseconds(260))
dismiss()
}
}
}
struct SnapshotFollowUpView: View {
@Bindable var snapshot: MoodSnapshot
@Environment(\.appColorProfile) private var colorProfile
@Environment(\.dismiss) private var dismiss
@Environment(\.modelContext) private var modelContext
@State private var note: String
init(snapshot: MoodSnapshot) {
self.snapshot = snapshot
_note = State(initialValue: snapshot.followUpNote)
}
var body: some View {
NavigationStack {
Form {
Section {
HStack(spacing: 14) {
Text(snapshot.rating.emoji)
.font(.system(size: 42))
VStack(alignment: .leading, spacing: 3) {
Text(snapshot.rating.rawValue)
.font(.headline)
Text(snapshot.createdAt.formatted(date: .omitted, time: .shortened))
.font(.subheadline)
.foregroundStyle(.secondary)
}
}
}
Section(snapshot.rating.followUpQuestion) {
TextEditor(text: $note)
.frame(minHeight: 120)
}
Section {
Button {
save()
} label: {
Label("Antwort speichern", systemImage: "checkmark.circle.fill")
.frame(maxWidth: .infinity)
}
.buttonStyle(.borderedProminent)
.tint(colorProfile.accent)
.disabled(note.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty)
.listRowInsets(EdgeInsets())
.listRowBackground(Color.clear)
Button("Heute nicht mehr fragen", role: .cancel) {
snapshot.followUpDismissed = true
try? modelContext.save()
dismiss()
}
.frame(maxWidth: .infinity)
}
}
.navigationTitle("Kurzer Rückblick")
.navigationBarTitleDisplayMode(.inline)
}
.appKeyboardBehavior()
}
private func save() {
snapshot.followUpNote = note.trimmingCharacters(in: .whitespacesAndNewlines)
try? modelContext.save()
dismiss()
}
}