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>
This commit is contained in:
@@ -17,6 +17,7 @@ struct FeelsApp: App {
|
||||
|
||||
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
|
||||
|
||||
@@ -30,26 +31,36 @@ struct FeelsApp: App {
|
||||
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
MainTabView(dayView: DayView(viewModel: DayViewViewModel(addMonthStartWeekdayPadding: false)),
|
||||
monthView: MonthView(viewModel: DayViewViewModel(addMonthStartWeekdayPadding: true)),
|
||||
yearView: YearView(viewModel: YearViewModel()),
|
||||
insightsView: InsightsView(),
|
||||
customizeView: CustomizeView())
|
||||
.modelContainer(dataController.container)
|
||||
.environmentObject(iapManager)
|
||||
.sheet(isPresented: $showSubscriptionFromWidget) {
|
||||
FeelsSubscriptionStoreView()
|
||||
.environmentObject(iapManager)
|
||||
}
|
||||
.onOpenURL { url in
|
||||
if url.scheme == "feels" && url.host == "subscribe" {
|
||||
showSubscriptionFromWidget = true
|
||||
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 {
|
||||
@@ -58,6 +69,12 @@ struct FeelsApp: App {
|
||||
Task {
|
||||
await iapManager.checkSubscriptionStatus()
|
||||
}
|
||||
// Authenticate if locked
|
||||
if authManager.isLockEnabled && !authManager.isUnlocked {
|
||||
Task {
|
||||
await authManager.authenticate()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user