Files
buzz/mobile/test/shared/custom_emoji
Tom Brow 9fc2b33320 perf(mobile): read only changed custom emoji sets on reconnect (#9446)
Once anything has read the custom emoji palette (opening any channel
does), every reconnect refetches every member's kind 30030 emoji set. On
Block's Builderlab that is 123 sets, about 1 MB, on every resume, though
the sets rarely change. The provider also watched the whole session
state, not just its status.

The palette now keeps the sets it has read per author and, on a
reconnect, asks only for sets written since shortly before the previous
read (`since` reaching back `relayCrossDeviceSkewSeconds`, the window
the unread catch-up already uses for events other devices write). A
newer set replaces the known one for its author, with the relay's order
for a same-second tie (the lower event id wins); the palette is the
union as before, recomputed only when a set changes, so a reconnect that
brings nothing new republishes the identical list and rebuilds nothing.
A community or account switch (a new relay client) starts over with a
full read.

Two side benefits: the loaded palette stays visible while disconnected
(before, it was empty until the full read finished, so `:shortcode:`s in
visible messages briefly showed as text on resume), and the palette no
longer refetches on every reconnect attempt during backoff, only on
status changes.

### Validation

Added test: the first read has no `since`; a reconnect with nothing new
sends a `since` and keeps the palette as the identical list; a new
member's set and a replaced set both arrive in the window and update it;
a same-second replacement wins with a lower id and is ignored with a
higher one. It fails without this change. Existing emoji picker tests
pass; full mobile test suite and `flutter analyze` pass.

On an iPhone 12 mini signed in to Block's Builderlab (instrumented
profile build): after opening a channel, a resume after 60 s in the
background downloaded the 1 MB of sets again (kind 30030, 123 events).
With this change the same resume sent the read with a `since` and got no
events back, so the 1 MB was not downloaded again; the first read when
opening the channel is unchanged (123 sets, 1 MB).

### Regressions

A set removed with a NIP-09 deletion (rather than replaced) stays in the
palette until the app restarts, since a deletion isn't a newer set. Buzz
clients edit a set by replacing it (desktop removes a shortcode by
republishing the set), so that only affects other clients, and desktop's
emoji directory keeps deleted sets the same way. A set written by a
device whose clock is more than 30 minutes behind is missed until
restart, the same bound the unread catch-up accepts.

---------

Signed-off-by: Tom Brow <tomb@squareup.com>
Co-authored-by: Tom Brow <tomb@squareup.com>
Co-authored-by: studio <dc2fc481343672df31a689840c09299972e704dac592e0da6f18486646a7ee3e@localhost>
2026-11-13 13:40:32 -08:00
..