Skip to content

feat(chat): settle reaction pills on a beat - #1607

Merged
bmc08gt merged 1 commit into
code/cashfrom
feat/reaction-pill-settling
Sep 28, 2026
Merged

bmc08gt merged 1 commit into
code/cashfrom
feat/reaction-pill-settling

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Sep 28, 2026

Copy link
Copy Markdown
Collaborator

The pill row re-sorted on every reaction update, so under a burst of
reactions pills moved and changed width while a thumb was on its way
down, and the tap landed on a different pill.

ReactionSettler, in :shared:chat, sits between ReactionOrdering and the
row. It is gen_reactions.py's Settler, and the 16 settle cases in
reactions.json replay against it with a fake clock:

  • Counts and boosts update live; order changes on a 1 s beat, at most
    3 adjacent swaps per beat, nearest the top first. Any boost lead or a
    count lead of 1 passes; ties never move. A pair that swapped can't
    swap back for 3 s.
  • A touch on the row holds the beat 1.5 s, extended by further touches
    and capped 4 s from the first.
  • Emptied pills leave on the beat; new emoji join at the end.
  • Each pill reserves room for its count (at least 2 digits) and boost
    as of the last beat. A value that fits shows at once; one that needs
    more room, such as 99 to 100, waits for the next beat.

ReactionPillRow runs the beat, sizes the count to the reserved digits
in tabular figures, and for 450 ms after a beat changes the layout
routes a tap to whatever was under it before. That window is
ReactionSettler.HIT_GRACE_MS, the one place to change it once it's
measured on phones.

reactions.json is re-synced from the orchestrator's canonical copy.

Spec: code-payments/flipcash-client-orchestrator#28 (Settling section, settle vectors).

The pill row re-sorted on every reaction update, so under a burst of
reactions pills moved and changed width while a thumb was on its way
down, and the tap landed on a different pill.

ReactionSettler, in :shared:chat, sits between ReactionOrdering and the
row. It is gen_reactions.py's Settler, and the 16 `settle` cases in
reactions.json replay against it with a fake clock:

- Counts and boosts update live; order changes on a 1 s beat, at most
  3 adjacent swaps per beat, nearest the top first. Any boost lead or a
  count lead of 1 passes; ties never move. A pair that swapped can't
  swap back for 3 s.
- A touch on the row holds the beat 1.5 s, extended by further touches
  and capped 4 s from the first.
- Emptied pills leave on the beat; new emoji join at the end.
- Each pill reserves room for its count (at least 2 digits) and boost
  as of the last beat. A value that fits shows at once; one that needs
  more room, such as 99 to 100, waits for the next beat.

ReactionPillRow runs the beat, sizes the count to the reserved digits
in tabular figures, and for 450 ms after a beat changes the layout
routes a tap to whatever was under it before. That window is
ReactionSettler.HIT_GRACE_MS, the one place to change it once it's
measured on phones.

reactions.json is re-synced from the orchestrator's canonical copy.
@bmc08gt bmc08gt self-assigned this Sep 28, 2026
@github-actions github-actions Bot added the type: feature New functionality label Sep 28, 2026
@bmc08gt
bmc08gt merged commit 9382ce1 into code/cash Sep 28, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: feature New functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant