Files
Reflect/Shared/FeelsApp.swift
Trey t 920aaee35c Add premium features and reorganize Settings tab
Premium Features:
- Journal notes and photo attachments for mood entries
- Data export (CSV and PDF reports)
- Privacy lock with Face ID/Touch ID
- Apple Health integration for mood correlation
- 4 new personality packs (Motivational Coach, Zen Master, Best Friend, Data Analyst)

Settings Tab Reorganization:
- Combined Customize and Settings into single tab with segmented control
- Added upgrade banner with trial countdown above segment
- "Why Upgrade?" sheet showing all premium benefits
- Subscribe button opens improved StoreKit 2 subscription view

UI Improvements:
- Enhanced subscription store with feature highlights
- Entry detail view for viewing/editing notes and photos
- Removed duplicate subscription banners from tab content

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 12:22:06 -06:00

83 lines
3.0 KiB
Swift

//
// FeelsApp.swift
// Shared
//
// Created by Trey Tartt on 1/5/22.
//
import SwiftUI
import SwiftData
import BackgroundTasks
import WidgetKit
@main
struct FeelsApp: App {
@Environment(\.scenePhase) private var scenePhase
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
let dataController = DataController.shared
@StateObject var iapManager = IAPManager()
@StateObject var authManager = BiometricAuthManager()
@AppStorage(UserDefaultsStore.Keys.firstLaunchDate.rawValue, store: GroupUserDefaults.groupDefaults) private var firstLaunchDate = Date()
@State private var showSubscriptionFromWidget = false
init() {
BGTaskScheduler.shared.cancelAllTaskRequests()
BGTaskScheduler.shared.register(forTaskWithIdentifier: BGTask.updateDBMissingID, using: nil) { (task) in
BGTask.runFillInMissingDatesTask(task: task as! BGProcessingTask)
}
UNUserNotificationCenter.current().setBadgeCount(0)
}
var body: some Scene {
WindowGroup {
ZStack {
MainTabView(dayView: DayView(viewModel: DayViewViewModel(addMonthStartWeekdayPadding: false)),
monthView: MonthView(viewModel: DayViewViewModel(addMonthStartWeekdayPadding: true)),
yearView: YearView(viewModel: YearViewModel()),
insightsView: InsightsView())
.modelContainer(dataController.container)
.environmentObject(iapManager)
.environmentObject(authManager)
.sheet(isPresented: $showSubscriptionFromWidget) {
FeelsSubscriptionStoreView()
.environmentObject(iapManager)
}
.onOpenURL { url in
if url.scheme == "feels" && url.host == "subscribe" {
showSubscriptionFromWidget = true
}
}
// Lock screen overlay
if authManager.isLockEnabled && !authManager.isUnlocked {
LockScreenView(authManager: authManager)
.transition(.opacity)
}
}
}.onChange(of: scenePhase) { _, newPhase in
if newPhase == .background {
//BGTask.scheduleBackgroundProcessing()
WidgetCenter.shared.reloadAllTimelines()
// Lock the app when going to background
authManager.lock()
}
if newPhase == .active {
UNUserNotificationCenter.current().setBadgeCount(0)
// Check subscription status on each app launch
Task {
await iapManager.checkSubscriptionStatus()
}
// Authenticate if locked
if authManager.isLockEnabled && !authManager.isUnlocked {
Task {
await authManager.authenticate()
}
}
}
}
}
}