Files
Reflect/Shared/Views/CustomizeView/SubViews/PersonalityPackPickerView.swift
Trey t 440b04159e Add Apple platform features and UX improvements
- Add HealthKit State of Mind sync for mood entries
- Add Live Activity with streak display and rating time window
- Add App Shortcuts/Siri integration for voice mood logging
- Add TipKit hints for feature discovery
- Add centralized MoodLogger for consistent side effects
- Add reminder time setting in Settings with time picker
- Fix duplicate notifications when changing reminder time
- Fix Live Activity streak showing 0 when not yet rated today
- Fix slow tap response in entry detail mood selection
- Update widget timeline to refresh at rating time
- Sync widgets when reminder time changes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 17:21:55 -06:00

84 lines
4.1 KiB
Swift

//
// PersonalityPackPickerView.swift
// Feels (iOS)
//
// Created by Trey Tartt on 4/2/22.
//
import SwiftUI
struct PersonalityPackPickerView: View {
@AppStorage(UserDefaultsStore.Keys.theme.rawValue, store: GroupUserDefaults.groupDefaults) private var theme: Theme = .system
@AppStorage(UserDefaultsStore.Keys.personalityPack.rawValue, store: GroupUserDefaults.groupDefaults) private var personalityPack: PersonalityPack = .Default
@State private var showOver18Alert = false
@AppStorage(UserDefaultsStore.Keys.showNSFW.rawValue, store: GroupUserDefaults.groupDefaults) private var showNSFW: Bool = false
@AppStorage(UserDefaultsStore.Keys.textColor.rawValue, store: GroupUserDefaults.groupDefaults) private var textColor: Color = DefaultTextColor.textColor
var body: some View {
ZStack {
theme.currentTheme.secondaryBGColor
VStack {
ForEach(PersonalityPack.allCases, id: \.self) { aPack in
VStack(spacing: 10) {
Text(String(aPack.title()))
.font(.body)
.foregroundColor(textColor)
Text(aPack.randomPushNotificationStrings().title)
.font(.body)
.foregroundColor(Color(UIColor.systemGray))
Text(aPack.randomPushNotificationStrings().body)
.font(.body)
.foregroundColor(Color(UIColor.systemGray))
}
.frame(minWidth: 0, maxWidth: .infinity)
.padding()
.contentShape(Rectangle())
.background(
RoundedRectangle(cornerRadius: 10, style: .continuous)
.fill(personalityPack == aPack ? theme.currentTheme.bgColor : .clear)
.padding(5)
)
.onTapGesture {
// if aPack.rawValue == PersonalityPack.Rude.rawValue && !showNSFW {
// showOver18Alert = true
// EventLogger.log(event: "show_over_18_alert")
// } else {
let impactMed = UIImpactFeedbackGenerator(style: .heavy)
impactMed.impactOccurred()
personalityPack = aPack
EventLogger.log(event: "change_personality_pack", withData: ["pack_title": aPack.title()])
LocalNotification.rescheduleNotifiations()
// }
}
// .blur(radius: aPack.rawValue == PersonalityPack.Rude.rawValue && !showNSFW ? 5 : 0)
.alert(isPresented: $showOver18Alert) {
let primaryButton = Alert.Button.default(Text(String(localized: "customize_view_over18alert_ok"))) {
showNSFW = true
}
let secondaryButton = Alert.Button.cancel(Text(String(localized: "customize_view_over18alert_no"))) {
showNSFW = false
}
return Alert(title: Text(String(localized: "customize_view_over18alert_title")),
message: Text(String(localized: "customize_view_over18alert_body")),
primaryButton: primaryButton,
secondaryButton: secondaryButton)
}
if aPack.rawValue != (PersonalityPack.allCases.sorted(by: { $0.rawValue > $1.rawValue }).first?.rawValue) ?? 0 {
Divider()
}
}
}
}
.fixedSize(horizontal: false, vertical: true)
.cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
}
}
struct PersonalityPackPickerView_Previews: PreviewProvider {
static var previews: some View {
PersonalityPackPickerView()
}
}