Commit Graph

53 Commits

Author SHA1 Message Date
null 8aea4730cc perf(res): convert all artwork to WebP; unify + blend pack art
Converts every PNG in res to WebP (124 files, 104M -> 28M on disk, -73%).
Each file was encoded both lossless and lossy q95 and the smaller kept, but
lossy only where it measured visually lossless (PSNR >= 40 dB); dimensions and
alpha were verified per file before the PNG was removed, so 25 files that
compressed better losslessly stayed exact. No nine-patches exist to break, and
R.drawable refs are extension-agnostic (the only ".png" in code is a runtime
share-cache filename). Debug APK 141.9 -> 128.8 MB; pack art in the APK
26.4 -> 11.5 MB. The disk saving is larger than the APK saving because AAPT2
already crunched PNGs at build time.

Unifies pack artwork in a new PackArtwork.kt. packArtworkRes was duplicated
verbatim in the library and detail screens — which is exactly how the two
drifted before (one kept a grouped mapping that gave several packs the same
illustration). It now exists once, alongside the two art composables. This is
also where an imported pack's art would resolve.

Pack detail page fixes:
- Removed the second back arrow. The nav scaffold already supplies the
  "Question Pack" bar and its back affordance (AppRoute.kt), so the in-screen
  IconButton was a duplicate; onBack is now unused and gone.
- The description is shown in full. It was capped at maxLines=4 with an
  ellipsis, which truncated most packs mid-sentence — this is the page where
  someone decides whether to open the pack, so it should not be abridged.
- The hero art is blended instead of pasted on: it runs full-bleed (the list no
  longer pads horizontally; items pad themselves) and dissolves into the page.
  The dissolve is an alpha mask (BlendMode.DstIn), not a scrim in the
  background colour — the page behind is a gradient brush, so fading to any
  single colour left a visible pale band in light theme. Fading the image to
  transparent lets the real background through, correct in both themes.
  Library cards get a softer version of the same, into the card surface.

Verified live on both fixtures (dark 5554 / light 5556): single back arrow,
full description, art melting into the page with no hard edges, correct
per-theme art. Unit tests green, 0 FATAL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 20:52:14 -05:00
null 388b927437 feat(packs): add distinct pack artwork 2026-07-14 20:18:56 -05:00
null 6668a3c4b7 refactor(brand): in-app prose -> 'Closer Couples' (launcher + wordmark stay 'Closer')
Extends the store/marketing rename to in-app user-facing PROSE, per owner decision.
Every string where 'Closer' names the app in a sentence now reads 'Closer Couples'
(Android + iOS): settings, pairing, invite share, widget headlines, paywall
subhead/thank-you, age gate, privacy body.

Deliberately KEPT as 'Closer' (judgment calls, documented in docs/NameChange.md):
- launcher label / iOS CFBundleDisplayName (14 chars truncates under the icon)
- wordmark logos (onboarding, auth alt-text, widget header, share-card drawText,
  iOS onboarding) + their asserting tests
- 'Grow Closer' onboarding pun (intimacy, not the app name)
- entity/length-capped lines: privacy rotator 'so Closer cannot read them'
  (hard 64-char cap), iOS 'not even Closer's servers'
- iOS 'Settings > Closer' help path (must match the kept display name)
- 'Closer Premium' tier label (matches the RevenueCat entitlement display name)
- all technical identifiers (app.closer / closer.app / closer_premium / etc.)

TodayWidgetTest exact-match assertions updated. compileDebugKotlin + unit tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 17:07:31 -05:00
null 0195564d25 docs(readme): refresh ready-state home screenshots 2026-07-09 00:30:27 -05:00
null 59e033692b chore(cleanup): purge 55 unused string resources
strings.xml had 127 entries but the app renders copy from hardcoded Compose literals
(only ~4 files use stringResource) — so ~half of strings.xml was a resource catalog that
was pre-created for the pairing/home/partner-home/settings-nav screens and never wired up.

Removed the 55 entries with zero R.string./@string references anywhere (kt/xml/manifest),
including whole dead sections (Settings nav labels, all Pairing subsections, Home screen,
Partner home). Kept everything actually referenced: app_name, today_widget_description,
common actions in use, and the Appearance/Notifications/Account/Privacy sections.
Resources compile clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 00:20:32 -05:00
null f0a05f779b feat(widget): Glance "Today" home-screen widget
Content-free daily-question state + streak, mirrored from HomeViewModel via a
dedicated DataStore (TodayWidgetUpdater -> TodayWidgetState). App-lock drops it
to a generic card so partner-activity state doesn't sit on the protected home
screen; signed-out/unpaired show neutral prompts. Tapping opens the daily
question via MainActivity's app_route extra.

Verified: provider registers, state bridge writes, headline logic unit-tested
(TodayWidgetTest), no crash on launch. On-home-screen render + a Remote Config
kill switch are tracked in Future.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 20:40:28 -05:00
null 55699e17ed feat: security hardening, CI, analytics, invite deep links, solo mode, weekly recap
Roadmap phases 0-3.1 (see plan). Verified: unit tests, functions tests,
firestore rules 119/119, live emulator smokes.

Security + CI:
- Move App Check debug token out of committed build.gradle.kts to
  local.properties (secret() resolver: local.properties -> -P -> env);
  admin service-account key relocated outside the repo.
- Add GitHub Actions (android unit/scan/gitleaks, backend functions +
  rules emulator via emulators:exec) with a CI google-services.json stub
  and a reviewed .gitleaksignore baseline.
- Fix firestore rules tests to the current deployed contract (was 108/118,
  now 119/119).

Analytics + consent:
- FirebaseRetentionAnalytics behind a fail-safe composite sink, single-
  sourced hashing (AnalyticsHashing), Settings -> Privacy opt-out toggle
  gating Firebase + the sink, and the ~11 missing event call sites.
- NoPlaintextInAnalyticsTest guards the content-free rule at build time.

Funnel:
- Invite deep links (https App Link + closer:// fallback), JoinLink parser,
  PendingJoinCodeStore, prefilled/already-paired pairing, richer share text.
- Solo pre-pairing: UnpairedLockedCard on Play, SoloAnswerMigrator + consent
  dialog moving pre-pairing answers into Couple Lore.

Weekly recap:
- WeeklyRecapScreen driven by the existing generator from local answer data,
  Home card rewired, content-free shareable card.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 20:33:38 -05:00
null 31a2652e48 feat(art): add illustration_daily_reveal_ready (light + dark) 2026-07-01 02:55:20 -05:00
null 02c3180ee7 feat(date-memories): add illustration_date_memories_empty (light and dark) 2026-06-30 18:15:03 -05:00
null 097140bc9d feat(date-memories): add glyph_date_replay vector drawable 2026-06-30 18:15:00 -05:00
null 2119792cca Revert "feat(date-memories): add glyph_date_replay + illustration_date_memories_empty assets (batch 7/8)"
This reverts commit 067155c108.
2026-06-30 18:13:00 -05:00
null 067155c108 feat(date-memories): add glyph_date_replay + illustration_date_memories_empty assets (batch 7/8) 2026-06-30 16:52:04 -05:00
null 2a5c40508e feat(notifications): QuietHoursManager + NotificationSettingsScreen rewrite, Cloud Functions (streakReminder, quietHours, reengagement, gameRetention), UserRepository E2EE wiring, SettingsDataStore, firestore rules, wiring-scan 2026-06-30 00:38:06 -05:00
null f6291e1f2e feat(home): HomeScreen rewrite, HomePriorityEngine polish, CoupleRepository E2EE wiring, OutcomeCheckInDialog, YourProgress, MemoryLane, settings/pairing/paywall/play/wheel/question screens cleanup, brand illustrations, QA docs 2026-06-29 16:51:46 -05:00
null 4215563873 brand: update glyph_connection_challenge + add glyph_closer_heart_keyhole 2026-06-28 17:09:02 -05:00
null 2d77786254 brand: refresh dark-variant illustrations (couple_history, couple_onboarding, tonight_partner_prompt) + dark contact sheet 2026-06-28 16:48:37 -05:00
null b9828b60c5 brand: refresh dark-variant illustrations (couple_paywall, partner_activation, together_empty) and dark contact sheet 2026-06-28 16:34:51 -05:00
null f927097d67 brand: update dark-theme illustration and pack-art night assets 2026-06-28 12:45:15 -05:00
null 954aab4cd2 brand: add generated glyph assets + illustration exports, allow generated-art in git 2026-06-28 11:30:12 -05:00
null 9949200f47 feat: wire theme-scan.sh into QA docs, fix script Tier 2, file 9 C-THEME P2 defects 2026-06-28 10:34:55 -05:00
null 4deed13845 feat: theme-scan.sh + improved Pass C scanner methodology (tier 1A-1G, tier 2, tier 3 roadmap) 2026-06-28 10:28:17 -05:00
null fe3ea7715c feat: add automated theme-mismatch scanner to Pass C methodology (Tier 1-3) 2026-06-28 10:20:41 -05:00
null c31eea2549 feat(premium): one-time PremiumUnlockOverlay + theme/art fixes (R13)
- New PremiumUnlockOverlay.kt — one-time 'Premium unlocked' celebration for both partners on couple-shared Premium activation. Driven off CouplePremiumChecker (not the push) so it surfaces for both wherever they are. Gated by persisted premiumUnlockCelebrated flag, auto-reset on lapse.
- New illustration_premium_unlock.png asset for the overlay.
- AppNavigation hosts the overlay at root alongside MessageBubbleOverlay.
- SettingsDataStore: new premiumUnlockCelebrated flag + setter.
- ThisOrThatScreen: theme-token fixes for A/B options, mood chips, versus badge, progress, ChoicePromptBackdrop — all read from MaterialTheme.colorScheme. Bumps dark-mode legibility.
- ConversationScreen: bump PendingMediaChip retry/dismiss IconButtons to 48dp touch targets.
- PlayHubScreen / ActivityScreen / HomeScreen / SubscriptionScreen / OnboardingScreen / PairPromptScreen / PaywallScreen / LocalQuestionContent / OutcomeCheckInDialog / ChatComponents: assorted R13 polish.
- firestore.rules (n/a this batch), SettingsRepository, manual: doc + flag wiring.
- Manual: new C-DARK-UI-001 + C-ART-EDGE-002 landmines, Premium-unlock-modal pattern note.
2026-06-27 21:01:16 -05:00
null 4eed0a8115 feat(premium): couple-shared unlock notification + reveal retry + users update allowlist + brand glyphs
- New Cloud Function: onEntitlementChanged (Firestore onWrite on entitlements/premium) — edge-triggered inactive→active, notifies the OTHER partner so couple-shared unlock isn't silent
- New notification type SUBSCRIPTION_CHANGED → routes to SUBSCRIPTION
- AnswerRevealViewModel: re-issue markRevealed if best-effort failed (offline/transient) so partner_opened_answer push eventually fires
- firestore.rules: harden users/{uid} update allowlist (defense-in-depth; no live hole)
- 18 new brand glyph vector drawables (drawable-nodpi/)
- SettingsScreen / PlayHubScreen / WaitingForPartnerScreen: swap Material icons for new brand glyphs
- ClaudeQA docs + Future.md updated
2026-06-27 16:35:41 -05:00
null fe104b4a41 brand(art): add 12 dark-theme illustration variants for night mode 2026-06-26 11:27:36 -05:00
null 077a408785 brand(art): add 12 generated illustrations to drawable-nodpi; gitignore brand source art
Phase 0 of wiring the generated brand art (full-res per request). Adds A1 pairing,
A2 answer-history, A3 challenges header, A4 memory-lane capsule, A5 date-match
empty+success, A6 bucket-list, A8 messages, A9 quiet-hours, A10 past-games,
A11 privacy-recovery, A12 account-deletion to res/drawable-nodpi. Source working art
(docs/brand/{generated-art,sources,exports}) gitignored — only app copies committed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 09:29:42 -05:00
null 95cad84cb5 brand: loading state, themes, manifest, art preview, pairing screen updates 2026-06-25 15:24:46 -05:00
null fed91dbe46 brand: finalize app icon, brand docs, onboarding visuals, feature graphic 2026-06-25 14:52:21 -05:00
null 520eea2236 brand: update launcher foreground, feature graphic, auth visuals, brand docs 2026-06-25 14:48:57 -05:00
null 334cb079fa brand: update app icon, iOS assets, Android drawables, brand docs (Pass H) 2026-06-25 14:34:27 -05:00
null 06e4d609f2 feat(chat): image picker (gallery + camera), encrypted image rendering, messenger-style avatars on consecutive bubbles
- QuestionDiscussionThread: gallery picker via PickVisualMedia, camera capture via FileProvider, EncryptedChatImage composable decrypts + renders, MessageAvatar with partner photo
- QuestionThreadViewModel: sendImage, loadDecryptedMedia, dailyRevealed skip for already-revealed daily questions, partner photo loading
- QuestionThreadScreen: pass loadDecryptedMedia to discussion thread
- LocalQuestionContent: pass partnerPhotoUrl to discussion thread
- file_paths.xml: cache-path for camera capture
2026-06-24 15:20:18 -05:00
null 06e09da596 docs(readme): add privacy slogan to header 2026-06-23 22:14:36 -05:00
null 17d7489dd8 feat(engagement): streak milestones, celebration overlays, Together screen, avatar in notifications 2026-06-23 18:23:49 -05:00
null 174e56c5a0 feat: local question content, question header, daily question illustration, iOS question/wheel views 2026-06-22 13:57:09 -05:00
null f350c91b55 feat: question pack library screen, pack art assets, iOS question views 2026-06-22 13:45:48 -05:00
null bb119b054b feat: home screen update, pairing views, activation illustrations 2026-06-22 11:25:21 -05:00
null ecc41a77d2 feat: wheel screen, play hub, storage data source, iOS wheel/play views 2026-06-22 10:25:58 -05:00
null e2fd65f070 feat: security screen, theme polish, settings navigation, build config 2026-06-21 17:25:39 -05:00
null b19fc0934c feat: paywall illustrations, subscription polish, recovery store, settings cleanup 2026-06-21 16:27:55 -05:00
null af70280daa feat: E2EE recovery flow, iOS parity updates, onboarding + pairing polish 2026-06-21 11:20:48 -05:00
null dff86eb089 feat: settings polish, privacy strings, home partner state, proguard rules 2026-06-21 09:49:02 -05:00
null e7b45cc84f fix: profile photo temp dir, Firestore rules field-level lockdown (batch v0.2.10)
- Move temp profile photos to filesDir/photos/ subdirectory with mkdirs
- Update file_paths.xml to scope FileProvider to photos/ subdirectory
- Firestore rules: restrict couple doc updates to only mutable fields (streakCount, lastAnsweredAt, wrappedCoupleKey, kdfSalt, kdfParams, encryptionVersion) — prevents client from overwriting currentQuestionId, activePackId, id
2026-06-19 20:33:08 -05:00
null 5caae523e7 feat: app icon redesign, store assets, brand identity docs (batch v0.2.5)
- Redraw adaptive icon layers (background + foreground) with Closer palette colors
- Add monochrome icon layer for Android 13+ themed icons
- Add mipmap-anydpi-v33 adaptive icon configs (round + standard)
- Add store assets: 512px app icon, 1024x500 feature graphic, source SVGs
- Add docs/brand/visual-identity.md with brand mark, color palette, store voice, asset rules
- Update store-assets.md checklist to reflect completed items
2026-06-19 19:10:03 -05:00
null 7256a71bdf feat: dark mode support — ThemeMode setting, dynamic colors, status bar sync (batch v0.2.4)
- Add ThemeMode enum (DEVICE/LIGHT/DARK) with DataStore persistence
- SettingsScreen: appearance section with radio buttons for Device/Light/Dark
- SettingsViewModel: observe and persist theme mode
- MainActivity: read theme setting, apply dark theme, sync status bar icons
- Replace hardcoded Color.White references with MaterialTheme.colorScheme.surface across auth, onboarding, settings, and theme
- Convert AuthVisuals, SettingsVisuals, CloserPalette brushes to @Composable getters using dynamic scheme colors
- Add values-night/themes.xml for dark theme manifest entry
- Add ThemeModeTest unit test for fromStorageValue parsing
2026-06-19 19:00:37 -05:00
null 92a257b3eb feat: add sex field to user profile, Google profile extraction, multi-step onboarding, profile editing 2026-06-17 23:59:46 -05:00
null f7b95fc9ba feat: add Google sign-in icon, update login screen and auth visuals 2026-06-17 23:07:19 -05:00
null d21763ac41 feat: add sexual_preferences seed data (question_v2 schema) 2026-06-17 22:10:50 -05:00
null 95ea9ffed5 security: disable auto backup, rewrite backup rules as allowlist, harden data extraction rules for Android 12+ 2026-06-16 21:58:17 -05:00
null afeb1a1a03 docs: add README, add proguard rules, Firestore entitlement checker, network security config, update build config and onboarding 2026-06-16 20:16:47 -05:00
null 84995641f3 refactor: package rename from com.couplesconnect.app to app.closer, update build config and firebase setup 2026-06-16 20:03:58 -05:00