Rebrand entire project from Feels to Reflect
Complete rename across all bundle IDs, App Groups, CloudKit containers, StoreKit product IDs, data store filenames, URL schemes, logger subsystems, Swift identifiers, user-facing strings (7 languages), file names, directory names, Xcode project, schemes, assets, and documentation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// AccessibilityIdentifiers.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Centralized accessibility identifiers for XCUITest targeting.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// Analytics.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Singleton analytics manager wrapping PostHog SDK.
|
||||
// All analytics events flow through this single manager.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// AppDelegate.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 1/10/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// AppShortcuts.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// App Intents and Siri Shortcuts for voice-activated mood logging
|
||||
//
|
||||
@@ -50,7 +50,7 @@ struct MoodEntityQuery: EntityQuery {
|
||||
|
||||
struct LogMoodIntent: AppIntent {
|
||||
static var title: LocalizedStringResource = "Log Mood"
|
||||
static var description = IntentDescription("Record your mood for today in Feels")
|
||||
static var description = IntentDescription("Record your mood for today in Reflect")
|
||||
static var openAppWhenRun: Bool = false
|
||||
|
||||
@Parameter(title: "Mood")
|
||||
@@ -81,7 +81,7 @@ struct LogMoodIntent: AppIntent {
|
||||
|
||||
struct CheckTodaysMoodIntent: AppIntent {
|
||||
static var title: LocalizedStringResource = "Check Today's Mood"
|
||||
static var description = IntentDescription("See what mood you logged today in Feels")
|
||||
static var description = IntentDescription("See what mood you logged today in Reflect")
|
||||
static var openAppWhenRun: Bool = false
|
||||
|
||||
@MainActor
|
||||
@@ -176,7 +176,7 @@ struct MoodLoggedSnippetView: View {
|
||||
|
||||
// MARK: - App Shortcuts Provider
|
||||
|
||||
struct FeelsShortcuts: AppShortcutsProvider {
|
||||
struct ReflectShortcuts: AppShortcutsProvider {
|
||||
static var appShortcuts: [AppShortcut] {
|
||||
AppShortcut(
|
||||
intent: LogMoodIntent(),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "FeelsAppIcon.png",
|
||||
"filename" : "ReflectAppIcon.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
@@ -13,7 +13,7 @@
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"filename" : "FeelsAppIcon 1.png",
|
||||
"filename" : "ReflectAppIcon 1.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
|
||||
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "FeelsAppIcon.png",
|
||||
"filename" : "ReflectAppIcon.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// BGTask.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 1/12/22.
|
||||
//
|
||||
@@ -9,7 +9,7 @@ import Foundation
|
||||
import BackgroundTasks
|
||||
|
||||
class BGTask {
|
||||
static let updateDBMissingID = "com.tt.feels.dbUpdateMissing"
|
||||
static let updateDBMissingID = "com.88oakapps.reflect.dbUpdateMissing"
|
||||
|
||||
@MainActor
|
||||
class func runFillInMissingDatesTask(task: BGProcessingTask) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// Date+Extensions.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/19/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// DemoAnimationManager.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Manages demo animation mode for promotional videos.
|
||||
// Animates filling mood entries from top-left to bottom-right.
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
<key>BUNDLE_ID</key>
|
||||
<string>com.tt.ifeel</string>
|
||||
<key>PROJECT_ID</key>
|
||||
<string>ifeels</string>
|
||||
<string>ireflect</string>
|
||||
<key>STORAGE_BUCKET</key>
|
||||
<string>ifeels.appspot.com</string>
|
||||
<string>ireflect.appspot.com</string>
|
||||
<key>IS_ADS_ENABLED</key>
|
||||
<false/>
|
||||
<key>IS_ANALYTICS_ENABLED</key>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// HealthKitManager.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// HealthKit State of Mind API integration for syncing mood data with Apple Health
|
||||
//
|
||||
@@ -14,7 +14,7 @@ class HealthKitManager: ObservableObject {
|
||||
static let shared = HealthKitManager()
|
||||
|
||||
private let healthStore = HKHealthStore()
|
||||
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.tt.feels", category: "HealthKit")
|
||||
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.88oakapps.reflect", category: "HealthKit")
|
||||
|
||||
@Published var isAuthorized = false
|
||||
@Published var authorizationError: Error?
|
||||
@@ -132,7 +132,7 @@ class HealthKitManager: ObservableObject {
|
||||
throw HealthKitError.notAuthorized
|
||||
}
|
||||
|
||||
// Convert Feels mood to HealthKit valence (-1 to 1 scale)
|
||||
// Convert Reflect mood to HealthKit valence (-1 to 1 scale)
|
||||
let valence = moodToValence(mood)
|
||||
|
||||
// Create State of Mind sample
|
||||
@@ -384,7 +384,7 @@ class HealthKitManager: ObservableObject {
|
||||
|
||||
// MARK: - Conversion Helpers
|
||||
|
||||
/// Convert Feels Mood to HealthKit valence (-1 to 1)
|
||||
/// Convert Reflect Mood to HealthKit valence (-1 to 1)
|
||||
private func moodToValence(_ mood: Mood) -> Double {
|
||||
switch mood {
|
||||
case .horrible: return -1.0
|
||||
@@ -396,7 +396,7 @@ class HealthKitManager: ObservableObject {
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert HealthKit valence to Feels Mood
|
||||
/// Convert HealthKit valence to Reflect Mood
|
||||
func valenceToMood(_ valence: Double) -> Mood {
|
||||
switch valence {
|
||||
case ..<(-0.75): return .horrible
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// IAPManager.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Refactored StoreKit 2 subscription manager with clean state model.
|
||||
//
|
||||
@@ -50,8 +50,8 @@ class IAPManager: ObservableObject {
|
||||
static let subscriptionGroupID = "21914363"
|
||||
|
||||
private let productIdentifiers: Set<String> = [
|
||||
"com.88oakapps.feels.IAP.subscriptions.monthly",
|
||||
"com.88oakapps.feels.IAP.subscriptions.yearly"
|
||||
"com.88oakapps.reflect.IAP.subscriptions.monthly",
|
||||
"com.88oakapps.reflect.IAP.subscriptions.yearly"
|
||||
]
|
||||
|
||||
private let trialDays = 30
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// LocalNotification.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Trey Tartt on 1/8/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// AIInsight.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Claude Code on 12/13/24.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// AppTheme.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Claude Code on 12/26/24.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomWidgetStateViewModel.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Trey Tartt on 3/31/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// DaysFilterClass.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Trey Tartt on 3/31/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// DiamondView.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Trey Tartt on 3/20/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// Mood.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Trey Tartt on 1/5/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// MoodEntryModel.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// SwiftData model replacing Core Data MoodEntry
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// MoodImagable.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/19/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// MoodMetrics.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Trey Tartt on 2/12/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// MoodTintable.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/19/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// OnboardingDataDataManager.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/18/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// NotificationTitles.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/19/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// Shapes.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Trey Tartt on 3/20/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// SharingImageModels.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Trey Tartt on 2/24/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// theme.currentTheme.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/4/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// UserDefaultsStore.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 1/22/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// MoodEntryFunctions.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/19/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// MoodLogger.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Centralized mood logging service that handles all side effects
|
||||
//
|
||||
@@ -15,7 +15,7 @@ import os.log
|
||||
final class MoodLogger {
|
||||
static let shared = MoodLogger()
|
||||
|
||||
private static let logger = Logger(subsystem: "com.tt.feels", category: "MoodLogger")
|
||||
private static let logger = Logger(subsystem: "com.88oakapps.reflect", category: "MoodLogger")
|
||||
|
||||
/// Key for tracking the last date side effects were applied
|
||||
private static let lastSideEffectsDateKey = "lastSideEffectsAppliedDate"
|
||||
@@ -86,8 +86,8 @@ final class MoodLogger {
|
||||
|
||||
// 4. Update tips parameters if requested
|
||||
if updateTips {
|
||||
FeelsTipsManager.shared.onMoodLogged()
|
||||
FeelsTipsManager.shared.updateStreak(streak)
|
||||
ReflectTipsManager.shared.onMoodLogged()
|
||||
ReflectTipsManager.shared.updateStreak(streak)
|
||||
}
|
||||
|
||||
// 5. Request app review at moments of delight
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// MoodStreakActivity.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Live Activity for mood streak tracking on Lock Screen and Dynamic Island
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// OnboardingData.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 1/22/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// OnboardingCustomizeOne.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 4/5/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// OnboardingCustomizeTwo.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 4/5/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// OnboardingDay.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 1/20/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// OnboardingMain.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 1/20/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// OnboardingStyle.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Claude Code on 12/10/24.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// OnboardingSubscription.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Claude Code on 12/10/24.
|
||||
//
|
||||
@@ -143,7 +143,7 @@ struct OnboardingSubscription: View {
|
||||
AnalyticsManager.shared.track(.onboardingCompleted(dayId: nil))
|
||||
completionClosure(onboardingData)
|
||||
}) {
|
||||
FeelsSubscriptionStoreView(source: "onboarding")
|
||||
ReflectSubscriptionStoreView(source: "onboarding")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// OnboardingTime.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 1/20/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// OnboardingTitle.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 1/20/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// OnboardingWelcome.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Claude Code on 12/10/24.
|
||||
//
|
||||
@@ -38,7 +38,7 @@ struct OnboardingWelcome: View {
|
||||
.padding(.bottom, 40)
|
||||
|
||||
// Title
|
||||
Text("Welcome to Feels")
|
||||
Text("Welcome to Reflect")
|
||||
.font(.largeTitle.weight(.bold))
|
||||
.foregroundColor(.white)
|
||||
.padding(.bottom, 12)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// OnboardingWrapup.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 1/21/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// DataController.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// SwiftData controller replacing Core Data PersistenceController.
|
||||
//
|
||||
@@ -11,7 +11,7 @@ import os.log
|
||||
|
||||
@MainActor
|
||||
final class DataController: ObservableObject {
|
||||
private static let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.tt.feels", category: "DataController")
|
||||
private static let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.88oakapps.reflect", category: "DataController")
|
||||
static let shared = DataController()
|
||||
|
||||
private(set) var container: ModelContainer
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// DataControllerADD.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// SwiftData CREATE operations.
|
||||
//
|
||||
@@ -9,7 +9,7 @@ import SwiftData
|
||||
import Foundation
|
||||
import os.log
|
||||
|
||||
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.tt.feels", category: "DataControllerADD")
|
||||
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.88oakapps.reflect", category: "DataControllerADD")
|
||||
|
||||
extension DataController {
|
||||
func add(mood: Mood, forDate date: Date, entryType: EntryType) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// DataControllerDELETE.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// SwiftData DELETE operations.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// DataControllerGET.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// SwiftData READ operations.
|
||||
//
|
||||
@@ -9,7 +9,7 @@ import SwiftData
|
||||
import Foundation
|
||||
import os.log
|
||||
|
||||
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.tt.feels", category: "DataControllerGET")
|
||||
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.88oakapps.reflect", category: "DataControllerGET")
|
||||
|
||||
extension DataController {
|
||||
func getEntry(byDate date: Date) -> MoodEntryModel? {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// DataControllerHelper.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// SwiftData helper and test data operations.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// DataControllerProtocol.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Protocol defining the data access interface for mood entries.
|
||||
// Enables dependency injection and testability.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// DataControllerUPDATE.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// SwiftData UPDATE operations.
|
||||
//
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
//
|
||||
// ExtensionDataProvider.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Unified data provider for Widget and Watch extensions.
|
||||
// - Watch: Uses CloudKit for automatic sync with iPhone
|
||||
// - Widget: Uses local App Group storage (widgets can't use CloudKit)
|
||||
//
|
||||
// Add this file to: FeelsWidgetExtension, Feels Watch App
|
||||
// Add this file to: ReflectWidgetExtension, Reflect Watch App
|
||||
//
|
||||
|
||||
import Foundation
|
||||
@@ -22,7 +22,7 @@ final class ExtensionDataProvider {
|
||||
|
||||
static let shared = ExtensionDataProvider()
|
||||
|
||||
private static let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.tt.feels", category: "ExtensionDataProvider")
|
||||
private static let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.88oakapps.reflect", category: "ExtensionDataProvider")
|
||||
|
||||
private var _container: ModelContainer?
|
||||
|
||||
@@ -47,9 +47,9 @@ final class ExtensionDataProvider {
|
||||
// Watch uses CloudKit for automatic sync with iPhone
|
||||
let cloudKitContainerID: String
|
||||
#if DEBUG
|
||||
cloudKitContainerID = "iCloud.com.88oakapps.feels.debug"
|
||||
cloudKitContainerID = "iCloud.com.88oakapps.reflect.debug"
|
||||
#else
|
||||
cloudKitContainerID = "iCloud.com.88oakapps.feels"
|
||||
cloudKitContainerID = "iCloud.com.88oakapps.reflect"
|
||||
#endif
|
||||
|
||||
let configuration = ModelConfiguration(
|
||||
@@ -89,9 +89,9 @@ final class ExtensionDataProvider {
|
||||
throw NSError(domain: "ExtensionDataProvider", code: 1, userInfo: [NSLocalizedDescriptionKey: "App Group not available"])
|
||||
}
|
||||
#if DEBUG
|
||||
return containerURL.appendingPathComponent("Feels-Debug.store")
|
||||
return containerURL.appendingPathComponent("Reflect-Debug.store")
|
||||
#else
|
||||
return containerURL.appendingPathComponent("Feels.store")
|
||||
return containerURL.appendingPathComponent("Reflect.store")
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// SharedModelContainer.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Factory for creating ModelContainer shared between main app and widget extension.
|
||||
//
|
||||
@@ -25,7 +25,7 @@ enum SharedModelContainerError: LocalizedError {
|
||||
}
|
||||
|
||||
enum SharedModelContainer {
|
||||
private static let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.tt.feels", category: "SharedModelContainer")
|
||||
private static let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.88oakapps.reflect", category: "SharedModelContainer")
|
||||
|
||||
/// Indicates whether the app is running with in-memory storage due to a failed App Group container.
|
||||
/// When `true`, all data will be lost on app restart.
|
||||
@@ -116,18 +116,18 @@ enum SharedModelContainer {
|
||||
/// CloudKit container identifier based on build configuration
|
||||
static var cloudKitContainerID: String {
|
||||
#if DEBUG
|
||||
return "iCloud.com.88oakapps.feels.debug"
|
||||
return "iCloud.com.88oakapps.reflect.debug"
|
||||
#else
|
||||
return "iCloud.com.88oakapps.feels"
|
||||
return "iCloud.com.88oakapps.reflect"
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Store file name based on build configuration
|
||||
static var storeFileName: String {
|
||||
#if DEBUG
|
||||
return "Feels-Debug.store"
|
||||
return "Reflect-Debug.store"
|
||||
#else
|
||||
return "Feels.store"
|
||||
return "Reflect.store"
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// ChartDataBuildable.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Trey Tartt on 1/17/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// ChartViewItemBuildable.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Trey Tartt on 1/17/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// SharingTemplate.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/6/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// Random.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Trey Tartt on 1/9/22.
|
||||
//
|
||||
@@ -10,8 +10,8 @@ import SwiftUI
|
||||
import SwiftData
|
||||
|
||||
struct Constants {
|
||||
static let groupShareId = "group.com.88oakapps.feels"
|
||||
static let groupShareIdDebug = "group.com.88oakapps.feels.debug"
|
||||
static let groupShareId = "group.com.88oakapps.reflect"
|
||||
static let groupShareIdDebug = "group.com.88oakapps.reflect.debug"
|
||||
|
||||
static var currentGroupShareId: String {
|
||||
#if DEBUG
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// FeelsApp.swift
|
||||
// ReflectApp.swift
|
||||
// Shared
|
||||
//
|
||||
// Created by Trey Tartt on 1/5/22.
|
||||
@@ -11,7 +11,7 @@ import BackgroundTasks
|
||||
import WidgetKit
|
||||
|
||||
@main
|
||||
struct FeelsApp: App {
|
||||
struct ReflectApp: App {
|
||||
@Environment(\.scenePhase) private var scenePhase
|
||||
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
|
||||
|
||||
@@ -38,7 +38,7 @@ struct FeelsApp: App {
|
||||
UNUserNotificationCenter.current().setBadgeCount(0)
|
||||
|
||||
// Reset tips session on app launch
|
||||
FeelsTipsManager.shared.resetSession()
|
||||
ReflectTipsManager.shared.resetSession()
|
||||
|
||||
// Initialize Live Activity scheduler
|
||||
LiveActivityScheduler.shared.scheduleBasedOnCurrentTime()
|
||||
@@ -59,7 +59,7 @@ struct FeelsApp: App {
|
||||
.environmentObject(authManager)
|
||||
.environmentObject(healthKitManager)
|
||||
.sheet(isPresented: $showSubscriptionFromWidget) {
|
||||
FeelsSubscriptionStoreView(source: "widget_deeplink")
|
||||
ReflectSubscriptionStoreView(source: "widget_deeplink")
|
||||
.environmentObject(iapManager)
|
||||
}
|
||||
.onOpenURL { url in
|
||||
@@ -147,7 +147,7 @@ struct FeelsApp: App {
|
||||
}
|
||||
|
||||
private func handleDeepLink(_ url: URL) {
|
||||
if url.scheme == "feels" && url.host == "subscribe" {
|
||||
if url.scheme == "reflect" && url.host == "subscribe" {
|
||||
showSubscriptionFromWidget = true
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
//
|
||||
// FeelsTips.swift
|
||||
// Feels
|
||||
// ReflectTips.swift
|
||||
// Reflect
|
||||
//
|
||||
// Custom tips system for feature discovery and onboarding
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
// MARK: - FeelsTip Protocol
|
||||
// MARK: - ReflectTip Protocol
|
||||
|
||||
@MainActor
|
||||
protocol FeelsTip: Identifiable {
|
||||
protocol ReflectTip: Identifiable {
|
||||
var id: String { get }
|
||||
var title: String { get }
|
||||
var message: String { get }
|
||||
@@ -21,7 +21,7 @@ protocol FeelsTip: Identifiable {
|
||||
// MARK: - Tip Definitions
|
||||
|
||||
@MainActor
|
||||
struct CustomizeLayoutTip: FeelsTip {
|
||||
struct CustomizeLayoutTip: ReflectTip {
|
||||
let id = "customizeLayout"
|
||||
let title = "Personalize Your Experience"
|
||||
let message = "Customize mood icons, colors, and layouts to make the app truly yours."
|
||||
@@ -30,51 +30,51 @@ struct CustomizeLayoutTip: FeelsTip {
|
||||
}
|
||||
|
||||
@MainActor
|
||||
struct AIInsightsTip: FeelsTip {
|
||||
struct AIInsightsTip: ReflectTip {
|
||||
let id = "aiInsights"
|
||||
let title = "Discover AI Insights"
|
||||
let message = "Get personalized insights about your mood patterns powered by Apple Intelligence."
|
||||
let icon = "brain.head.profile"
|
||||
var isEligible: Bool {
|
||||
FeelsTipsManager.shared.moodLogCount >= 7
|
||||
ReflectTipsManager.shared.moodLogCount >= 7
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
struct SiriShortcutTip: FeelsTip {
|
||||
struct SiriShortcutTip: ReflectTip {
|
||||
let id = "siriShortcut"
|
||||
let title = "Use Siri to Log Moods"
|
||||
let message = "Say \"Hey Siri, log my mood as great in Feels\" for hands-free logging."
|
||||
let message = "Say \"Hey Siri, log my mood as great in Reflect\" for hands-free logging."
|
||||
let icon = "mic.fill"
|
||||
var isEligible: Bool {
|
||||
FeelsTipsManager.shared.moodLogCount >= 3
|
||||
ReflectTipsManager.shared.moodLogCount >= 3
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
struct HealthKitSyncTip: FeelsTip {
|
||||
struct HealthKitSyncTip: ReflectTip {
|
||||
let id = "healthKitSync"
|
||||
let title = "Sync with Apple Health"
|
||||
let message = "Connect to Apple Health to see your mood data alongside sleep, exercise, and more."
|
||||
let icon = "heart.fill"
|
||||
var isEligible: Bool {
|
||||
FeelsTipsManager.shared.hasSeenSettings
|
||||
ReflectTipsManager.shared.hasSeenSettings
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
struct WidgetVotingTip: FeelsTip {
|
||||
struct WidgetVotingTip: ReflectTip {
|
||||
let id = "widgetVoting"
|
||||
let title = "Vote from Your Home Screen"
|
||||
let message = "Add the Mood Vote widget to quickly log your mood without opening the app."
|
||||
let icon = "square.grid.2x2.fill"
|
||||
var isEligible: Bool {
|
||||
FeelsTipsManager.shared.daysUsingApp >= 2
|
||||
ReflectTipsManager.shared.daysUsingApp >= 2
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
struct TimeViewTip: FeelsTip {
|
||||
struct TimeViewTip: ReflectTip {
|
||||
let id = "timeView"
|
||||
let title = "View Your History"
|
||||
let message = "Switch between Day, Month, and Year views to see your mood patterns over time."
|
||||
@@ -83,20 +83,20 @@ struct TimeViewTip: FeelsTip {
|
||||
}
|
||||
|
||||
@MainActor
|
||||
struct MoodStreakTip: FeelsTip {
|
||||
struct MoodStreakTip: ReflectTip {
|
||||
let id = "moodStreak"
|
||||
let title = "Build Your Streak!"
|
||||
let message = "Log your mood daily to build a streak. Consistency helps you understand your patterns."
|
||||
let icon = "flame.fill"
|
||||
var isEligible: Bool {
|
||||
FeelsTipsManager.shared.currentStreak >= 3
|
||||
ReflectTipsManager.shared.currentStreak >= 3
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - All Tips
|
||||
|
||||
@MainActor
|
||||
enum FeelsTips {
|
||||
enum ReflectTips {
|
||||
static let customizeLayout = CustomizeLayoutTip()
|
||||
static let aiInsights = AIInsightsTip()
|
||||
static let siriShortcut = SiriShortcutTip()
|
||||
@@ -109,21 +109,21 @@ enum FeelsTips {
|
||||
// MARK: - Tips Manager
|
||||
|
||||
@MainActor
|
||||
class FeelsTipsManager: ObservableObject {
|
||||
static let shared = FeelsTipsManager()
|
||||
class ReflectTipsManager: ObservableObject {
|
||||
static let shared = ReflectTipsManager()
|
||||
|
||||
// MARK: - Keys
|
||||
private enum Keys {
|
||||
static let tipsEnabled = "feels.tips.enabled"
|
||||
static let shownTipIDs = "feels.tips.shownIDs"
|
||||
static let moodLogCount = "feels.tips.moodLogCount"
|
||||
static let hasSeenSettings = "feels.tips.hasSeenSettings"
|
||||
static let daysUsingApp = "feels.tips.daysUsingApp"
|
||||
static let currentStreak = "feels.tips.currentStreak"
|
||||
static let tipsEnabled = "reflect.tips.enabled"
|
||||
static let shownTipIDs = "reflect.tips.shownIDs"
|
||||
static let moodLogCount = "reflect.tips.moodLogCount"
|
||||
static let hasSeenSettings = "reflect.tips.hasSeenSettings"
|
||||
static let daysUsingApp = "reflect.tips.daysUsingApp"
|
||||
static let currentStreak = "reflect.tips.currentStreak"
|
||||
}
|
||||
|
||||
// MARK: - Published State
|
||||
@Published var currentTip: (any FeelsTip)?
|
||||
@Published var currentTip: (any ReflectTip)?
|
||||
@Published var showTipModal = false
|
||||
|
||||
// MARK: - Global Toggle (configurable)
|
||||
@@ -178,7 +178,7 @@ class FeelsTipsManager: ObservableObject {
|
||||
// MARK: - Public API
|
||||
|
||||
/// Check if a tip should be shown
|
||||
func shouldShowTip(_ tip: any FeelsTip) -> Bool {
|
||||
func shouldShowTip(_ tip: any ReflectTip) -> Bool {
|
||||
guard tipsEnabled else { return false }
|
||||
guard !hasShownTipThisSession else { return false }
|
||||
guard !shownTipIDs.contains(tip.id) else { return false }
|
||||
@@ -187,14 +187,14 @@ class FeelsTipsManager: ObservableObject {
|
||||
}
|
||||
|
||||
/// Show a tip if eligible
|
||||
func showTipIfEligible(_ tip: any FeelsTip) {
|
||||
func showTipIfEligible(_ tip: any ReflectTip) {
|
||||
guard shouldShowTip(tip) else { return }
|
||||
currentTip = tip
|
||||
showTipModal = true
|
||||
}
|
||||
|
||||
/// Mark a tip as shown (called when dismissed)
|
||||
func markTipAsShown(_ tip: any FeelsTip) {
|
||||
func markTipAsShown(_ tip: any ReflectTip) {
|
||||
shownTipIDs.insert(tip.id)
|
||||
hasShownTipThisSession = true
|
||||
currentTip = nil
|
||||
@@ -237,8 +237,8 @@ class FeelsTipsManager: ObservableObject {
|
||||
|
||||
// MARK: - View Modifier for Easy Integration
|
||||
|
||||
struct FeelsTipModifier: ViewModifier {
|
||||
let tip: any FeelsTip
|
||||
struct ReflectTipModifier: ViewModifier {
|
||||
let tip: any ReflectTip
|
||||
let gradientColors: [Color]
|
||||
|
||||
// Use local state for sheet to avoid interference from other manager state changes
|
||||
@@ -255,7 +255,7 @@ struct FeelsTipModifier: ViewModifier {
|
||||
// Delay tip presentation to ensure view hierarchy is fully established
|
||||
// This prevents "presenting from detached view controller" errors
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
if FeelsTipsManager.shared.shouldShowTip(tip) {
|
||||
if ReflectTipsManager.shared.shouldShowTip(tip) {
|
||||
showSheet = true
|
||||
}
|
||||
}
|
||||
@@ -268,7 +268,7 @@ struct FeelsTipModifier: ViewModifier {
|
||||
gradientColors: gradientColors,
|
||||
onDismiss: {
|
||||
showSheet = false
|
||||
FeelsTipsManager.shared.markTipAsShown(tip)
|
||||
ReflectTipsManager.shared.markTipAsShown(tip)
|
||||
}
|
||||
)
|
||||
.presentationDetents([.height(340)])
|
||||
@@ -280,8 +280,8 @@ struct FeelsTipModifier: ViewModifier {
|
||||
|
||||
extension View {
|
||||
/// Attach a tip that shows as a themed modal when eligible
|
||||
func feelsTip(_ tip: any FeelsTip, gradientColors: [Color]) -> some View {
|
||||
modifier(FeelsTipModifier(tip: tip, gradientColors: gradientColors))
|
||||
func reflectTip(_ tip: any ReflectTip, gradientColors: [Color]) -> some View {
|
||||
modifier(ReflectTipModifier(tip: tip, gradientColors: gradientColors))
|
||||
}
|
||||
|
||||
// MARK: - Convenience Modifiers
|
||||
@@ -292,30 +292,30 @@ extension View {
|
||||
}
|
||||
|
||||
func customizeLayoutTip() -> some View {
|
||||
feelsTip(FeelsTips.customizeLayout, gradientColors: [Color(hex: "667eea"), Color(hex: "764ba2")])
|
||||
reflectTip(ReflectTips.customizeLayout, gradientColors: [Color(hex: "667eea"), Color(hex: "764ba2")])
|
||||
}
|
||||
|
||||
func aiInsightsTip() -> some View {
|
||||
feelsTip(FeelsTips.aiInsights, gradientColors: [.purple, .blue])
|
||||
reflectTip(ReflectTips.aiInsights, gradientColors: [.purple, .blue])
|
||||
}
|
||||
|
||||
func siriShortcutTip() -> some View {
|
||||
feelsTip(FeelsTips.siriShortcut, gradientColors: [Color(hex: "f093fb"), Color(hex: "f5576c")])
|
||||
reflectTip(ReflectTips.siriShortcut, gradientColors: [Color(hex: "f093fb"), Color(hex: "f5576c")])
|
||||
}
|
||||
|
||||
func healthKitSyncTip() -> some View {
|
||||
feelsTip(FeelsTips.healthKitSync, gradientColors: [.red, .pink])
|
||||
reflectTip(ReflectTips.healthKitSync, gradientColors: [.red, .pink])
|
||||
}
|
||||
|
||||
func widgetVotingTip() -> some View {
|
||||
feelsTip(FeelsTips.widgetVoting, gradientColors: [Color(hex: "11998e"), Color(hex: "38ef7d")])
|
||||
reflectTip(ReflectTips.widgetVoting, gradientColors: [Color(hex: "11998e"), Color(hex: "38ef7d")])
|
||||
}
|
||||
|
||||
func timeViewTip() -> some View {
|
||||
feelsTip(FeelsTips.timeView, gradientColors: [.blue, .cyan])
|
||||
reflectTip(ReflectTips.timeView, gradientColors: [.blue, .cyan])
|
||||
}
|
||||
|
||||
func moodStreakTip() -> some View {
|
||||
feelsTip(FeelsTips.moodStreak, gradientColors: [.orange, .red])
|
||||
reflectTip(ReflectTips.moodStreak, gradientColors: [.orange, .red])
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// AppLogger.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Centralized logging using OSLog for production-ready logging.
|
||||
//
|
||||
@@ -29,6 +29,6 @@ enum AppLogger {
|
||||
// MARK: - Private
|
||||
|
||||
private static var subsystem: String {
|
||||
Bundle.main.bundleIdentifier ?? "com.tt.feels"
|
||||
Bundle.main.bundleIdentifier ?? "com.88oakapps.reflect"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// BiometricAuthManager.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Manages Face ID / Touch ID authentication for app privacy lock.
|
||||
//
|
||||
@@ -93,7 +93,7 @@ class BiometricAuthManager: ObservableObject {
|
||||
do {
|
||||
let success = try await context.evaluatePolicy(
|
||||
policy,
|
||||
localizedReason: "Unlock Feels to access your mood data"
|
||||
localizedReason: "Unlock Reflect to access your mood data"
|
||||
)
|
||||
|
||||
isUnlocked = success
|
||||
@@ -120,7 +120,7 @@ class BiometricAuthManager: ObservableObject {
|
||||
do {
|
||||
let success = try await context.evaluatePolicy(
|
||||
.deviceOwnerAuthentication,
|
||||
localizedReason: "Unlock Feels to access your mood data"
|
||||
localizedReason: "Unlock Reflect to access your mood data"
|
||||
)
|
||||
|
||||
isUnlocked = success
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// ExportService.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Handles exporting mood data to CSV and PDF formats with beautiful visualizations.
|
||||
//
|
||||
@@ -76,7 +76,7 @@ class ExportService {
|
||||
func exportCSV(entries: [MoodEntryModel]) -> URL? {
|
||||
let csv = generateCSV(entries: entries)
|
||||
|
||||
let filename = "Feels-Export-\(formattedDate()).csv"
|
||||
let filename = "Reflect-Export-\(formattedDate()).csv"
|
||||
let tempURL = FileManager.default.temporaryDirectory.appendingPathComponent(filename)
|
||||
|
||||
do {
|
||||
@@ -107,7 +107,7 @@ class ExportService {
|
||||
let contentWidth = pageWidth - (margin * 2)
|
||||
|
||||
let pdfMetaData = [
|
||||
kCGPDFContextCreator: "Feels App",
|
||||
kCGPDFContextCreator: "Reflect App",
|
||||
kCGPDFContextTitle: title
|
||||
]
|
||||
|
||||
@@ -167,7 +167,7 @@ class ExportService {
|
||||
return nil
|
||||
}
|
||||
|
||||
let filename = "Feels-Report-\(formattedDate()).pdf"
|
||||
let filename = "Reflect-Report-\(formattedDate()).pdf"
|
||||
let tempURL = FileManager.default.temporaryDirectory.appendingPathComponent(filename)
|
||||
|
||||
do {
|
||||
@@ -624,7 +624,7 @@ class ExportService {
|
||||
.font: footerFont,
|
||||
.foregroundColor: UIColor.lightGray
|
||||
]
|
||||
let footerString = NSAttributedString(string: "Generated by Feels - Your Mood Tracking Companion", attributes: footerAttributes)
|
||||
let footerString = NSAttributedString(string: "Generated by Reflect - Your Mood Tracking Companion", attributes: footerAttributes)
|
||||
let footerSize = footerString.size()
|
||||
footerString.draw(at: CGPoint(x: (pageWidth - footerSize.width) / 2, y: footerY))
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// ExportableInsightsViews.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Exportable insights views with sample AI-generated insights for screenshots.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// ExportableWatchViews.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Exportable watch views that match the real watchOS layouts.
|
||||
// These views accept tint/icon configuration as parameters for batch export.
|
||||
@@ -292,7 +292,7 @@ struct ExportableRectangularComplication: View {
|
||||
.font(.system(size: 24))
|
||||
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text("Feels")
|
||||
Text("Reflect")
|
||||
.font(.system(size: 14, weight: .semibold))
|
||||
Text("Tap to log mood")
|
||||
.font(.system(size: 12))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// ExportableWidgetViews.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Exportable widget views that match the real WidgetKit widgets pixel-for-pixel.
|
||||
// These views accept tint/icon configuration as parameters for batch export.
|
||||
@@ -180,7 +180,7 @@ struct ExportableVotingView: View {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Exportable Voted Stats View (matches VotedStatsView from FeelsVoteWidget.swift)
|
||||
// MARK: - Exportable Voted Stats View (matches VotedStatsView from ReflectVoteWidget.swift)
|
||||
|
||||
struct ExportableVotedStatsView: View {
|
||||
enum Size {
|
||||
@@ -303,7 +303,7 @@ struct ExportableVotedStatsView: View {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Exportable Timeline Small View (matches SmallWidgetView from FeelsTimelineWidget.swift)
|
||||
// MARK: - Exportable Timeline Small View (matches SmallWidgetView from ReflectTimelineWidget.swift)
|
||||
|
||||
struct ExportableTimelineSmallView: View {
|
||||
let config: WidgetExportConfig
|
||||
@@ -359,7 +359,7 @@ struct ExportableTimelineSmallView: View {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Exportable Timeline Medium View (matches MediumWidgetView from FeelsTimelineWidget.swift)
|
||||
// MARK: - Exportable Timeline Medium View (matches MediumWidgetView from ReflectTimelineWidget.swift)
|
||||
|
||||
struct ExportableTimelineMediumView: View {
|
||||
let config: WidgetExportConfig
|
||||
@@ -469,7 +469,7 @@ struct ExportableMediumDayCell: View {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Exportable Timeline Large View (matches LargeWidgetView from FeelsTimelineWidget.swift)
|
||||
// MARK: - Exportable Timeline Large View (matches LargeWidgetView from ReflectTimelineWidget.swift)
|
||||
|
||||
struct ExportableTimelineLargeView: View {
|
||||
let config: WidgetExportConfig
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// FoundationModelsInsightService.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Claude Code on 12/13/24.
|
||||
//
|
||||
@@ -112,7 +112,7 @@ class FoundationModelsInsightService: ObservableObject {
|
||||
|
||||
private var defaultSystemInstructions: String {
|
||||
"""
|
||||
You are a supportive mood analyst for the Feels app. Analyze mood data and provide warm, actionable insights.
|
||||
You are a supportive mood analyst for the Reflect app. Analyze mood data and provide warm, actionable insights.
|
||||
|
||||
Style: Encouraging, empathetic, concise (1-2 sentences per insight). Reference specific data.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// HealthService.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Manages Apple Health integration for mood correlation insights.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// ImageCache.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// In-memory image cache for thumbnail images to improve scrolling performance.
|
||||
//
|
||||
@@ -13,7 +13,7 @@ final class ImageCache {
|
||||
static let shared = ImageCache()
|
||||
|
||||
private let cache = NSCache<NSString, UIImage>()
|
||||
private let queue = DispatchQueue(label: "com.tt.feels.imagecache", qos: .userInitiated)
|
||||
private let queue = DispatchQueue(label: "com.88oakapps.reflect.imagecache", qos: .userInitiated)
|
||||
|
||||
private var memoryWarningToken: NSObjectProtocol?
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// InsightsExporter.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Debug utility to export insights view screenshots with sample AI data.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// MoodDataSummarizer.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Claude Code on 12/13/24.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// PhotoManager.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Manages photo storage for mood entries.
|
||||
// Photos are stored as JPEG files in the app group Documents directory.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// ReviewRequestManager.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Manages in-app review requests using StoreKit.
|
||||
// Follows Apple's guidelines: requests at moments of delight,
|
||||
@@ -28,10 +28,10 @@ final class ReviewRequestManager {
|
||||
// MARK: - UserDefaults Keys
|
||||
|
||||
private enum Keys: String {
|
||||
case lastReviewRequestDate = "feels_lastReviewRequestDate"
|
||||
case totalReviewRequests = "feels_totalReviewRequests"
|
||||
case totalMoodEntriesLogged = "feels_totalMoodEntriesLogged"
|
||||
case lastReviewRequestVersion = "feels_lastReviewRequestVersion"
|
||||
case lastReviewRequestDate = "reflect_lastReviewRequestDate"
|
||||
case totalReviewRequests = "reflect_totalReviewRequests"
|
||||
case totalMoodEntriesLogged = "reflect_totalMoodEntriesLogged"
|
||||
case lastReviewRequestVersion = "reflect_lastReviewRequestVersion"
|
||||
}
|
||||
|
||||
private init() {}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// SharingScreenshotExporter.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Debug utility to export sharing template screenshots.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// WatchConnectivityManager.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Central coordinator for Watch Connectivity.
|
||||
// Used for immediate UI updates (Live Activity, widget refresh).
|
||||
@@ -18,7 +18,7 @@ final class WatchConnectivityManager: NSObject, ObservableObject {
|
||||
|
||||
static let shared = WatchConnectivityManager()
|
||||
|
||||
private static let logger = Logger(subsystem: "com.tt.feels", category: "WatchConnectivity")
|
||||
private static let logger = Logger(subsystem: "com.88oakapps.reflect", category: "WatchConnectivity")
|
||||
|
||||
private var session: WCSession?
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// WatchExporter.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Debug utility to export all watch view previews to PNG files.
|
||||
// Uses the exportable watch views from ExportableWatchViews.swift.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// WidgetExporter.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Debug utility to export all widget previews to PNG files.
|
||||
// Uses the real widget view layouts from ExportableWidgetViews.swift.
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
//
|
||||
// SharedMoodIntent.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Single VoteMoodIntent for all targets.
|
||||
// Main app uses ForegroundContinuableIntent to run widget intents in app process.
|
||||
//
|
||||
// Add this file to ALL targets: Feels (iOS), FeelsWidgetExtension, Feels Watch App
|
||||
// Add this file to ALL targets: Reflect (iOS), ReflectWidgetExtension, Reflect Watch App
|
||||
//
|
||||
|
||||
import AppIntents
|
||||
@@ -72,7 +72,7 @@ extension VoteMoodIntent: ForegroundContinuableIntent {}
|
||||
|
||||
#if WIDGET_EXTENSION
|
||||
enum WidgetMoodSaver {
|
||||
private static let logger = Logger(subsystem: "com.tt.feels.widget", category: "WidgetMoodSaver")
|
||||
private static let logger = Logger(subsystem: "com.88oakapps.reflect.widget", category: "WidgetMoodSaver")
|
||||
private static var cachedContainer: ModelContainer?
|
||||
|
||||
@MainActor
|
||||
@@ -107,9 +107,9 @@ enum WidgetMoodSaver {
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
let storeURL = containerURL.appendingPathComponent("Feels-Debug.store")
|
||||
let storeURL = containerURL.appendingPathComponent("Reflect-Debug.store")
|
||||
#else
|
||||
let storeURL = containerURL.appendingPathComponent("Feels.store")
|
||||
let storeURL = containerURL.appendingPathComponent("Reflect.store")
|
||||
#endif
|
||||
|
||||
let config = ModelConfiguration(schema: schema, url: storeURL, cloudKitDatabase: .none)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// ShowBasedOnVoteLogics.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/17/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// Stats.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Trey Tartt on 1/14/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// UITestMode.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Handles launch arguments for UI testing mode.
|
||||
// When --ui-testing is passed, the app uses deterministic settings.
|
||||
@@ -78,7 +78,7 @@ enum UITestMode {
|
||||
#if DEBUG
|
||||
IAPManager.shared.bypassSubscription = bypassSubscription
|
||||
// Reset subscription state to discard stale cached state from previous test runs.
|
||||
// IAPManager.shared was already initialized (as @StateObject in FeelsApp) before
|
||||
// IAPManager.shared was already initialized (as @StateObject in ReflectApp) before
|
||||
// configureIfNeeded runs, so it may have restored stale subscription data.
|
||||
IAPManager.shared.resetForTesting()
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// AccessibilityHelpers.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Accessibility utilities for supporting VoiceOver, Dynamic Type, and Reduce Motion.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// View+Extensions.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Trey Tartt on 7/7/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// AddMoodHeaderView.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Created by Trey Tartt on 1/5/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// IconView.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 1/20/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CelebrationAnimations.swift
|
||||
// Feels
|
||||
// Reflect
|
||||
//
|
||||
// Full-view celebration animations that play after voting.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CreateIconView.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/13/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// IconView.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/20/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomIcon.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/20/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomIcon.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/13/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// IconView.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/13/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomizeView.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 2/19/22.
|
||||
//
|
||||
@@ -189,7 +189,7 @@ struct CustomizeView: View {
|
||||
AnalyticsManager.shared.trackScreen(.customize)
|
||||
})
|
||||
.sheet(isPresented: $showSubscriptionStore) {
|
||||
FeelsSubscriptionStoreView(source: "customize")
|
||||
ReflectSubscriptionStoreView(source: "customize")
|
||||
}
|
||||
.background(
|
||||
theme.currentTheme.bg
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// AppThemePickerView.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Claude Code on 12/26/24.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// CustomWigetView.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 4/2/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// DayFilterPickerView.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 4/2/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// IconPickerView.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 4/2/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// ImagePackPickerView.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 4/2/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// PersonalityPackPickerView.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 4/2/22.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// ShapePickerView.swift
|
||||
// Feels (iOS)
|
||||
// Reflect (iOS)
|
||||
//
|
||||
// Created by Trey Tartt on 4/2/22.
|
||||
//
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user