Commit Graph

42 Commits

Author SHA1 Message Date
Trey t
c22d246865 Fix 25 audit issues: memory leaks, concurrency, performance, accessibility
Address findings from comprehensive audit across 5 workstreams:

- Memory: Token-based DataController listeners (prevent closure leaks),
  static DateFormatters, ImageCache observer cleanup, MotionManager
  reference counting, FoundationModels dedup guard
- Concurrency: Replace Task.detached with Task in FeelsApp (preserve
  MainActor isolation), wrap WatchConnectivity handler in MainActor
- Performance: Cache sortedGroupedData in DayViewViewModel, cache demo
  data in MonthView/YearView, remove broken ReduceMotionModifier
- Accessibility: VoiceOver support for LockScreen, DemoHeatmapCell
  labels, MonthCard button labels, InsightsView header traits,
  Smart Invert protection on neon headers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 09:11:48 -06:00
Trey t
277e277750 Add XCUITest suite with 27 test files covering unmapped P1 test cases
- Add 8 new test files: HeaderMoodLogging (TC-002), DayViewGrouping (TC-019),
  AllDayViewStyles (TC-021), MonthViewInteraction (TC-030), PaywallGate
  (TC-032/039/048), AppTheme (TC-070), IconPack (TC-072),
  PremiumCustomization (TC-075)
- Add accessibility IDs for paywall overlays, icon packs, app theme cards,
  and day view section headers
- Add --expire-trial launch argument to UITestMode for paywall gate testing
- Update QA test plan spreadsheet with XCUITest names for 14 test cases
- Include existing test infrastructure: screen objects, helpers, base class,
  and 19 previously written test files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:37:54 -06:00
Trey t
f1cd81c395 Fix 7 data mutation layer risks identified in audit
- save()/saveAndRunDataListeners() now return @discardableResult Bool;
  listeners only fire on successful save
- MoodLogger.updateMood() now recalculates streak, updates Live Activity,
  and notifies watch (was missing these side effects)
- CSV import uses new addBatch()/importMoods() for O(1) side effects
  instead of O(n) per-row widget reloads and streak calcs
- Foreground task ordering: fillInMissingDates() now runs before
  removeDuplicates() so backfill-created duplicates are caught same cycle
- WidgetMoodSaver deletes ALL entries for date (was fetchLimit=1, leaving
  CloudKit sync duplicates behind)
- cleanupPhotoIfNeeded logs warning on failed photo deletion instead of
  silently orphaning files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:09:11 -06:00
Trey t
e0330dbc8d Replace EventLogger with typed AnalyticsManager using PostHog
Complete analytics overhaul: delete EventLogger.swift, create Analytics.swift
with typed event enum (~45 events), screen tracking, super properties
(theme, icon pack, voting layout, etc.), session replay with kill switch,
autocapture, and network telemetry. Replace all 99 call sites across 38 files
with compiler-enforced typed events in object_action naming convention.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 15:12:33 -06:00
Trey t
a08d0d33c0 Add PostHog analytics to replace removed Firebase
Wire PostHog iOS SDK into existing EventLogger pattern so all 60+
call sites flow to self-hosted PostHog instance with zero changes.
Sets subscription person properties for segmentation on foreground.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 13:57:30 -06:00
Trey t
7cb5bdfb40 Update StoreKit config reference and use IAPManager singleton
Re-add Configuration.storekit with updated project reference and
use IAPManager.shared in FeelsApp to avoid creating a duplicate
instance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 09:56:56 -06:00
Trey t
bea2d3bbc9 Update Neon colors and show color circles in theme picker
- Update NeonMoodTint to use synthwave colors matching Neon voting style
  (cyan, lime, yellow, orange, magenta)
- Replace text label with 5 color circles in theme preview Colors row
- Remove unused textColor customization code and picker views
- Add .id(moodTint) to Month/Year views for color refresh
- Clean up various unused color-related code

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 00:08:01 -06:00
Trey t
c59f215535 Replace TipKit with custom themed tips modal system
- Add TipModalView with gradient header, themed styling, and spring animations
- Create FeelsTipsManager with global toggle, session tracking, and persistence
- Define FeelsTip protocol and convert all 7 tips to new system
- Add convenience view modifiers (.customizeLayoutTip(), .aiInsightsTip(), etc.)
- Remove TipKit dependency from all views
- Add Tips Preview debug screen in Settings to test all tip modals
- Update documentation for new custom tips system

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 21:33:36 -06:00
Trey t
f7da61d6ca Consolidate extension data providers and add side effects catch-up
- Create unified ExtensionDataProvider for Widget and Watch targets
- Remove duplicate WatchDataProvider and WatchConnectivityManager from Watch App
- Add side effects catch-up mechanism in MoodLogger for widget votes
- Process pending side effects on app launch and midnight background task
- Reduce ~450 lines of duplicated code across targets

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 22:50:23 -06:00
Trey t
224c00423a Add Apple Watch companion app with complications and WCSession sync
- Add watchOS app target with mood voting UI (5 mood buttons)
- Add WidgetKit complications (circular, corner, inline, rectangular)
- Add WatchConnectivityManager for bidirectional sync between iOS and watch
- iOS app acts as central coordinator - all mood logging flows through MoodLogger
- Watch votes send to iPhone via WCSession, iPhone logs and notifies watch back
- Widget votes use openAppWhenRun=true to run MoodLogger in main app process
- Add #if !os(watchOS) guards to Mood.swift and Random.swift for compatibility
- Update SKStoreReviewController to AppStore.requestReview (iOS 18 deprecation fix)
- Watch reads user's moodImages preference from GroupUserDefaults for emoji style

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 17:19:17 -06:00
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
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
Trey t
f822927e98 Add interactive widget voting and fix warnings/bugs
Widget Features:
- Add inline voting to timeline widget when no entry exists for today
- Show random prompt from notification strings in voting mode
- Update vote widget to use simple icon style for selection
- Make stats bar full width in voted state view
- Add Localizable.strings to widget extension target

Bug Fixes:
- Fix inverted date calculation in InsightsViewModel streak logic
- Replace force unwraps with safe optional handling in widgets
- Replace fatalError calls with graceful error handling
- Fix CSV import safety in SettingsView

Warning Fixes:
- Add @retroactive to Color and Date extension conformances
- Update deprecated onChange(of:perform:) to new syntax
- Replace deprecated applicationIconBadgeNumber with setBadgeCount
- Replace deprecated UIApplication.shared.windows API
- Add @preconcurrency for Swift 6 protocol conformances
- Add missing widget family cases to switch statement
- Remove unused variables and #warning directives

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 16:23:12 -06:00
Trey t
aaaf04f05e Migrate from Core Data to SwiftData
- Replace Core Data with SwiftData for iOS 18+
- Create MoodEntryModel as @Model class replacing MoodEntry entity
- Create SharedModelContainer for App Group container sharing
- Create DataController with CRUD extensions replacing PersistenceController
- Update all views and view models to use MoodEntryModel
- Update widget extension to use SwiftData
- Remove old Core Data files (Persistence*.swift, .xcdatamodeld)
- Add EntryType enum with all entry type cases
- Fix widget label truncation with proper spacing and text scaling

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 15:08:05 -06:00
Trey t
f37b811ab3 Add Insights tab with 60+ randomized analytics
New Insights tab between Year and Customize with:
- 20 insight generators producing 60+ unique insights
- 5 random insights selected per section (month, year, all-time)
- Categories: dominant mood, streaks, trends, positivity score,
  weekend vs weekday, mood swings, milestones, patterns, and more
- Collapsible sections with mood-colored cards
- Subscription paywall support
- English and Spanish localization

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 00:11:07 -06:00
Trey t
f2565678be wip 2025-12-09 23:37:04 -06:00
Trey t
3a10b4b8d6 wip 2025-12-09 23:36:57 -06:00
Trey t
f2c510de50 Refactor StoreKit 2 subscription system and add interactive vote widget
## StoreKit 2 Refactor
- Rewrote IAPManager with clean enum-based state model (SubscriptionState)
- Added native SubscriptionStoreView for iOS 17+ purchase UI
- Subscription status now checked on every app launch
- Synced subscription status to UserDefaults for widget access
- Simplified PurchaseButtonView and IAPWarningView
- Removed unused StatusInfoView

## Interactive Vote Widget
- New FeelsVoteWidget with App Intents for mood voting
- Subscribers can vote directly from widget, shows stats after voting
- Non-subscribers see "Tap to subscribe" which opens subscription store
- Added feels:// URL scheme for deep linking

## Firebase Removal
- Commented out Firebase imports and initialization
- EventLogger now prints to console in DEBUG mode only

## Other Changes
- Added fallback for Core Data when App Group unavailable
- Added new localization strings for subscription UI
- Updated entitlements and Info.plist

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 23:07:16 -06:00
Trey t
2c8772f79a iap work 2022-12-23 11:20:33 -06:00
Trey t
488832b777 WIP 2022-12-23 09:43:48 -06:00
Trey t
49e3812659 iap warning view 2022-12-21 10:19:03 -06:00
Trey t
53334e5fb8 IAP 2022-07-18 20:14:48 -05:00
Trey t
bd238e5743 iap - wip 2022-07-17 10:26:00 -05:00
Trey t
682f62fa4a separate all customize views into their own files
make corner radius a constant
create the views in the main app file and pass through so they dont get re-drawn when changing UI things
2022-04-02 10:53:04 -05:00
Trey t
bdd0b0ce59 filtering days in customize will filter views 2022-03-31 14:45:08 -05:00
Trey t
746337b6a2 update top header graph view when custom color changes
code cleanup
2022-03-02 17:25:06 -06:00
Trey t
065b7bcac1 create home view that is the main tab view 2022-02-18 14:19:37 -06:00
Trey t
675e44bca9 fix issue with two votes on the same date
fix issue with header not showing correct vote date
split logic for Persistence into different files
create class that deals with voting time, existing votes, and what should be shown based on that
2022-02-17 14:46:11 -06:00
Trey t
92514a5e33 closed #79 2022-02-10 10:59:19 -06:00
Trey t
cffce6a773 top view will shrink and fade into another view 2022-01-28 15:18:00 -06:00
Trey t
8c58b37be5 add in cloudkit toggle 2022-01-26 12:08:40 -06:00
Trey t
24be0073ae possibly fix the launch crash
add new package to track cloudkit issues
2022-01-24 10:27:41 -06:00
Trey t
4848106966 add canEdit canDelete to models, default to true
change icloud contatiner
2022-01-23 16:43:35 -06:00
Trey t
fc62413a53 add ability to rate a missing day
made bgview equatable so it doesn't get redrawn each time a sheet is shown

add more string to localization

fill in missing data on launch ... incase they have bgfetch turned off
2022-01-23 11:18:01 -06:00
Trey t
d0842d14d7 closed #34 2022-01-19 11:47:25 -06:00
Trey t
1c7bf1848b closed #4
reset badge number to 0 when app launches
2022-01-16 11:55:44 -06:00
Trey t
cd50230ba0 complete #4 2022-01-16 11:54:49 -06:00
Trey t
64dd1855ac WIP - a lot of uncommitted work 2022-01-15 12:03:31 -06:00
Trey t
19544b528d min ios version to 14 2022-01-10 09:20:26 -06:00
Trey t
00b955b0bc add in bg task to fill in missing days 2022-01-10 09:12:49 -06:00
Trey t
58697bf965 init commit - bring project over from Mood 2022-01-10 09:04:38 -06:00
Trey t
edd65e891d Initial Commit 2022-01-10 08:44:49 -06:00