156 lines
5.4 KiB
Swift
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()
|
|
}
|
|
}
|