Skip to content

fix(chat): restyle the archive chips and toast, and route toasts through ToastController - #949

Merged
bmc08gt merged 12 commits into
mainfrom
fix/chat-archive-restyle
Oct 3, 2026
Merged

bmc08gt merged 12 commits into
mainfrom
fix/chat-archive-restyle

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Oct 3, 2026 •

Copy link
Copy Markdown
Collaborator

Follow-up to #948: brings the filter chips and the archive undo toast in line with the chat-archive design shared with Android, and moves toasts onto one app-wide controller.

Filter chips

  • Selected: white at 16% over the background, label in the main text colour. The solid white fill was the brightest thing on the dark chat list.
  • Unselected: no fill, label in the secondary text colour.
  • Both states have a 1pt white 10% outline.

Toasts

Screens no longer draw their own toast overlay and timer. They call toasts.show(_:) on a ToastController held on Container, and HomeTabView hosts the one toast:

  • Above the tab bar when it shows, growing up out of it. When the bar is hidden, as on a pushed screen, the toast sits at the bottom edge and slides up from it.
  • On iOS 18 it clears the legacy pill, which adds nothing to the safe area. Before this, the chats screen's toast landed behind the pill.
  • A new toast replaces the one showing, and each is announced to VoiceOver.
  • A toast with an action takes touches and dismisses on a swipe down. One without lets touches through, so the version-footer countdown on the You tab keeps counting when the toast covers it.

As on Android (code-payments/code-android-app#1669), a covered host doesn't keep a toast under the cover. A router sheet or the bill dismisses the toast showing, and show drops a toast while any sheet or dialog is presented. A sheet a screen presents itself doesn't dismiss a toast already up; that one stays under it until it times out.

show(_:inPlace:) keeps the showing toast's view, so the developer countdown changes its text without replaying the entrance.

Toast design

FloatingToast is the shared pill:

  • The tab bar's surface (capsuleGlassBackground()), no border, so a toast growing out of the bar reads as part of it.
  • As wide as the floating tab bar, or 12pt in from each edge when no bar shows. The developer toast hugs its message instead.
  • An optional 18pt icon and the message at 14pt, both in the main text colour, then an optional action in its own pill filled white at 12%.

The archive toast is "Chat archived" with Undo, for 4s. The developer countdown keeps its 2s.

Swipe actions

Archive and unarchive draw their icons as outlines. Swipe actions fill symbols by default.

A solid white chip was the brightest thing on the dark chat list. Selected
chips now take white at 16% over the background with the main text colour;
unselected chips have no fill and use the secondary text colour, per the
shared chat-archive spec.
The toast is now a full-width frosted pill inset 12pt from each edge, with
a white 10% hairline, an 18pt archive icon, the message at 14pt, and Undo
in its own pill filled white at 12%. A swipe down dismisses it, and the
message is announced to VoiceOver each time a toast appears, including when
a new archive replaces the current one. The 4s lifetime and single-toast
behaviour are unchanged.
A 1pt white 10% hairline, matching the undo toast's border, so unselected
chips read as chips rather than loose labels.
@bmc08gt bmc08gt self-assigned this Oct 3, 2026
The undo toast's pill (frosted fill, white 10% outline, optional icon and
action pill, optional swipe-down dismiss) moves into FlipcashUI as
FloatingToast. ArchiveUndoToast now wraps it, and the You tab's
version-unlock countdown uses it in place of ToastLabel.

The countdown toast is taller than ToastLabel, so it now sits on the
footer's top edge rather than at a fixed offset, keeping the version text
uncovered. It keeps the you-version-toast identifier on the message text,
which the UI tests match as static text.
The archive toast keeps the full-width pill, inset 12pt. The developer
toast on the You tab uses the new .fit width: it hugs its message, caps at
the floating tab bar's width, and passes taps through to the version
footer so the countdown keeps counting.
Swipe actions fill SF Symbols by default; the shared design uses the
outlined archivebox.
HomeTabView publishes the floating tab bar's inset while the bar shows.
FloatingToast caps its width at the bar's, and floatingToastTransition()
swells the toast up from behind the bar, or slides it in from the bottom
edge when no bar is showing.

SwiftUI has no glass morph out of the native UITabBar, and the iOS 26.1
tabViewBottomAccessory cross-fades and wraps its content in a second
glass capsule, so this approximates the morph.
The toast grows out of the floating tab bar, so it takes the bar's
surface: capsuleGlassBackground(), which is Liquid Glass on iOS 26 and
the ultra-thin material below. The white hairline goes too; neither
tab bar has one.
Screens drew their own toast overlays and timers, so each one had to work
out the tab bar's clearance itself; the chats screen missed the iOS 18 pill
until a9b264a. Screens now call `toasts.show(_:)` on a ToastController held
on Container, and HomeTabView hosts the one toast: above the tab bar when it
shows, at the screen's bottom edge when it is hidden. A new toast replaces
the one up, and each is announced to VoiceOver.

A toast with an action takes touches and swipes down to dismiss; one without
lets touches through, which keeps the version-footer countdown counting when
the toast covers it. VersionTapUnlock now returns the line to show instead
of owning a message and timer.
@bmc08gt bmc08gt changed the title fix(chat): restyle the filter chips and archive undo toast fix(chat): restyle the archive chips and toast, and route toasts through ToastController Oct 3, 2026
@bmc08gt
bmc08gt merged commit 322e53b into main Oct 3, 2026
3 checks passed
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