Skip to content

feat(update): tell users when a newer App Store version is out - #1069

Merged
bmc08gt merged 3 commits into
mainfrom
feat/update-available-toast
Oct 15, 2026
Merged

bmc08gt merged 3 commits into
mainfrom
feat/update-available-toast

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator

The app only knew the forced minimum build, so an optional App Store update went unnoticed. This adds an update check, a one-time "New version available" toast, and an Update action on messages this build can't read. The Android side is code-payments/code-android-app#1770 and code-payments/code-android-app#1771.

Unsupported-message bubble (component 11420:13397)

  • .updateApp now draws a plain received bubble: "This Message Needs a Newer Version of Flipcash" over "Update Flipcash to see messages like this. This one stays hidden." The decrypt-failure hints keep the dashed bubble.
  • A message whose content type this build doesn't know used to be dropped by ConversationMessage.init?. It now maps to .widget(.unrecognized), which already reads back from the store as unsupported, so the schema is unchanged.
  • When a newer version exists, the bubble gets an "Update Flipcash" capsule, with no priority or once-only gate.

Update check

  • UpdateAvailability (on Container) asks the App Store lookup for the newest version when the app becomes active, at most every 6 hours, and caches the result. Builds whose AppTransaction environment isn't production (debug, TestFlight, Xcode) skip it. A failed lookup reads as no update.
  • Priority comes from .well-known/release-manifest.json on main, and applies only when its version matches the lookup's. It is seeded with 2026.10.2 at priority 0.
  • Update opens SKStoreProductViewController for app id 6758636374, falling back to the App Store app if the product fails to load.

Toast
"New version available" shows once per version, when the update is priority 4+ or has been out 7 days:

  • On the Chats or Wallet home, 1s after coming back from a pushed screen or after 3s on the home, for 10s (section 11693:162).
  • In a chat, 1s after it opens with the keyboard down, for 6s, 8pt above the composer and as wide as it (section 11705:162). The keyboard coming up dismisses it.

The version is marked seen only once the toast is on screen, since the controller drops a toast while a sheet or bill covers the app.

Debug builds can force the update state with -UpdateAvailableOverride <version>.

A message this build can't read showed a dashed "This message can't be
displayed" bubble with "Update Flipcash to see it" hanging under it. The
`.updateApp` hint now draws a plain received bubble with no outline: the
title "This Message Needs a Newer Version of Flipcash" over the body
"Update Flipcash to see messages like this. This one stays hidden."
(component 11420:13397), set in the `appTextMedium`, `appTextCaption`
and `appTextSmall` tokens rather than Figma's 15/13/14 sizes. Title and
body are separate labels; as one attributed string with paragraph
spacing, the cell measured short and clipped the body. The
decrypt-failure hints (`.askToResend`, `.resend`) keep the dashed bubble.

`ChatMessageCell.configure` takes an optional `ChatBubbleAction` that adds
an "Update Flipcash" capsule. Nothing passes one yet, so no button shows
until the update check exists.

A message whose content type this build doesn't know was dropped by
`ConversationMessage.init?`. It now maps to `.widget(.unrecognized)`, which
already reads back from the store as unsupported, so the schema is
unchanged. A message with no content entry is still dropped.
The app knew only the forced minimum build, so an optional update went
unnoticed. `UpdateAvailability` (on `Container`) now asks the App Store
lookup for the newest version when the app becomes active, at most every
6 hours, and caches the result. Debug, TestFlight and Xcode builds skip
the check: anything whose `AppTransaction` environment isn't production.
A failed lookup reads as no update.

Priority comes from `.well-known/release-manifest.json`, read from `main`
on GitHub. It applies only when its production version matches the
lookup's, and it is seeded with the current store version, 2026.10.2, at
priority 0.

"New version available" with an Update action shows once per version
when the update is priority (4+) or has been out 7 days:
- On the Chats or Wallet home, 1s after coming back from a pushed screen
  or after 3s on the home, for 10s (section 11693:162).
- In a chat, 1s after it opens with the keyboard down, for 6s, raised
  over the composer and as wide as it (section 11705:162). The keyboard
  coming up dismisses it.
The version is recorded only once the toast is actually on screen, since
the controller drops a toast while a sheet or bill covers the app.

Update opens `SKStoreProductViewController`, falling back to the App
Store app if the product fails to load. The unsupported-message bubble
gets the same action as "Update Flipcash" whenever a newer version
exists, with no priority or once-only gate.

`toastClearance` takes an optional horizontal inset for the chat bar, so
every toast in a chat now sits above the composer at its width.

Debug builds can force the toast with `-UpdateAvailableOverride <version>`.
The chat toast sat 28pt above the composer, not the 8pt section
11705:162 asks for: the clearance counted the bar's 8pt top margin and
its 8pt drop into the safe area on top of the host's 12pt padding.
`toastClearance` takes an `overlap` that lowers the toast back into the
bar's measured height, and the chat passes `BarMetrics.toastOverlap`
(20pt). The profile screens keep the default of 0.
@bmc08gt bmc08gt self-assigned this Oct 15, 2026
@bmc08gt
bmc08gt merged commit 14065ba into main Oct 15, 2026
2 of 3 checks passed
bmc08gt added a commit that referenced this pull request Oct 16, 2026
* origin/main: (23 commits)
  feat(chat): open message links on the linked message (#1055)
  fix(chat): load the link preview for a draft restored on opening a chat
  fix(chat): bring a removed link preview back once its link is edited out of the draft
  fix(chat): animate the composer link card in and out on the chip spring
  fix(chat): draw the composer link preview as a compact card with its remove button on the corner
  fix(chat): enlarge the composer link image and pin its remove button to it
  feat(chat): send a link preview alongside staged photos
  feat(chat): show the link preview's page in the composer before its image uploads
  feat(chat): draw a web card from the sender's preview and drop the receive-side fetch
  feat(chat): build a link preview in the composer and send it with the text
  feat(chat): carry a text message's link preview on the wire and in the store
  feat(chat): add the sender-side link preview checks and their shared vectors
  fix(chat): match Android's update-app bubble border and subtitle
  fix(chat): stand the jump button outside the bar clip so the reply strip no longer leaks (#1074)
  build: update release manifest
  fix(home): draw unselected tab glyphs and labels white on every iOS version (#1073)
  feat(settings): version card for TestFlight builds, kept current by the release manifest (#1072)
  feat(settings): add the update dot and version card (#1070)
  feat(update): tell users when a newer App Store version is out (#1069)
  feat(chat): jump-to-bottom button with unread badge (#1068)
  ...

# Conflicts:
#	Flipcash/Core/Screens/Conversation/LinkCardClassifier.swift
#	Flipcash/Core/Screens/Conversation/LinkCardFeed.swift
#	Flipcash/Core/Screens/Conversation/LinkCardResolver.swift
#	Flipcash/Core/Session/SessionAuthenticator.swift
#	FlipcashCore/Sources/FlipcashCore/Models/Chat/LinkCard.swift
#	FlipcashTests/Chat/LinkCardResolverTests.swift
#	FlipcashUI/Sources/FlipcashUI/Chat/ChatShareProfileCell.swift
#	FlipcashUI/Sources/FlipcashUI/Chat/LinkCardSource.swift
#	FlipcashUI/Sources/FlipcashUI/Chat/LinkCardView.swift
bmc08gt added a commit that referenced this pull request Oct 16, 2026
…t/message-link-share

* origin/feat/message-link-card: (23 commits)
  feat(chat): open message links on the linked message (#1055)
  fix(chat): load the link preview for a draft restored on opening a chat
  fix(chat): bring a removed link preview back once its link is edited out of the draft
  fix(chat): animate the composer link card in and out on the chip spring
  fix(chat): draw the composer link preview as a compact card with its remove button on the corner
  fix(chat): enlarge the composer link image and pin its remove button to it
  feat(chat): send a link preview alongside staged photos
  feat(chat): show the link preview's page in the composer before its image uploads
  feat(chat): draw a web card from the sender's preview and drop the receive-side fetch
  feat(chat): build a link preview in the composer and send it with the text
  feat(chat): carry a text message's link preview on the wire and in the store
  feat(chat): add the sender-side link preview checks and their shared vectors
  fix(chat): match Android's update-app bubble border and subtitle
  fix(chat): stand the jump button outside the bar clip so the reply strip no longer leaks (#1074)
  build: update release manifest
  fix(home): draw unselected tab glyphs and labels white on every iOS version (#1073)
  feat(settings): version card for TestFlight builds, kept current by the release manifest (#1072)
  feat(settings): add the update dot and version card (#1070)
  feat(update): tell users when a newer App Store version is out (#1069)
  feat(chat): jump-to-bottom button with unread badge (#1068)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant