Skip to content

fix: replace corrupted youtube asset - #17

Merged
bmc08gt merged 1 commit into
developfrom
chore/fix-corrupted-youtube-asset
Dec 20, 2023
Merged

bmc08gt merged 1 commit into
developfrom
chore/fix-corrupted-youtube-asset

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Dec 20, 2023

Copy link
Copy Markdown
Collaborator

github's web IDE corrupted the asset

github's web IDE corrupted the asset

Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
@bmc08gt
bmc08gt requested a review from jeffyanta December 20, 2023 22:24
@bmc08gt bmc08gt self-assigned this Dec 20, 2023
@bmc08gt
bmc08gt merged commit ecb81b0 into develop Dec 20, 2023
@bmc08gt
bmc08gt deleted the chore/fix-corrupted-youtube-asset branch December 20, 2023 22:24
bmc08gt added a commit that referenced this pull request Sep 26, 2026
* test: sync chat-reactions fixtures from flipcash-client-orchestrator#17

* refactor(chat): name the reaction version field version, as the proto does

* feat(chat): add the reaction reducer, pill order, strip, recents and catalog

* feat(chat): page reactors and batch-fetch reaction summaries by id

getReactors now returns the server paging token and hasMore, threaded
through the controller/repo/service/api with a pageSize param, so the
reactors sheet can page past the first 100. Adds
getReactionSummariesByIds, chunked at 100 ids per request via the
MessageIdBatch oneof, for the reaction refresh-on-paging flow.

* feat(chat): merge reactions by version on message upsert

* feat(chat): add reactions-only DAO writes and a JSON-level merge

* feat(chat): route stream reaction updates through the reducer and persist them

* feat(chat): add ReactionOperations — toggle, refresh, and page reactors

* test(chat): cover ReactionsDelegate toggle, rollback, coalescing, and refresh

* fix(chat): tombstone reactions a Room merge omits, require strictly newer version

mergeReactionsJson previously kept a stored emoji as-is when an incoming
payload (a server-fetched message copy) omitted it, leaving a stale pill
once the server side had removed it. Now it tombstones the omitted emoji
(count 0, self/sample reactors cleared, version kept) and only lets an
incoming entry win on a strictly greater version, matching
ReactionState.accept's tie-breaking.

* fix(chat): seed ReactionsDelegate.snapshot from Room, not just the overlay

After relaunch, a confirmed self-reaction lives only in Room's
reactions_json — ChatStateHolder's in-memory overlay starts empty. A
freshly-created ReactionState picked up no prior confirmed state, so the
first tap on an emoji already reacted to computed an ADD instead of a
REMOVE. snapshot now seeds a new state from ChatMessageDataSource before
folding in the overlay.

* fix(chat): add MessageReactions.from for messages outside live overlays

observeChatReactions only ever covered messages with a pending tap or a
confirmed overlay from the event stream/refreshReactions; a message whose
reactions live only in a paged Room read had no way to become pills. Document
that contract on the method and give the ViewModel a pure fallback -
MessageReactions.from(summary) runs a ChatMessage's persisted reactions
through ReactionState.applySummary so tombstone filtering and pill order
match the live path exactly.

* feat(chat): add canReact predicate for reaction eligibility

* feat(chat-ui): add ReactionPillRow with N-more collapse layout

* feat(chat): add ReactionRefreshPlanner for paging-driven reaction refresh

* feat(chat): add ReactionPicker/Reactors ChatStep and RecentReactionsStore.stats

* feat(chat-ui): add reactionPills and canReact to ContentBubble

* feat(chat): add ReactionPicker/Reactors nav stubs and ToggleReaction actions

* feat(chat): wire reaction pills into mappedMessages and ToggleReaction/picker/reactors events

* test(chat): cover ToggleReaction's selection-clearing reducer branch

* feat(chat): wire reaction pills, quick strip, and picker/reactors navigation into ChatViewModel

- Attach per-message reaction pills and canReact to ContentBubble in
  mappedMessages, sourced from the live reaction overlay with Room fallback
  via MessageReactions.from.
- Add ToggleReaction/OpenReactionPicker/OpenReactors events, wired through
  ChatCoordinator.toggleReaction and the screen's navigation to the
  ChatStep.ReactionPicker/Reactors stubs.
- Surface reactionErrors as a snackbar via BottomBarManager.showError.
- Compose the quick strip's entries from RecentReactionsStore + EmojiCatalog
  + EmojiDrawability whenever the selected, reactable message changes; record
  a used emoji on add (not on remove).
- Render ReactionPillRow under each bubble and QuickReactionStrip above a
  selected, reactable bubble in MessageRow/MessageList.

* feat(chat): wire reaction refresh hooks into the transcript's paging lifecycle

- Add ChatAction.RefreshReactionIds and ChatViewModel.Event.RefreshReactionIds,
  forwarding batches to ChatCoordinator.refreshReactions.
- In MessageList, refresh the newest 60 loaded ids on open and on every
  screen-lifecycle resume (repeatOnLifecycle(RESUMED), mirroring
  ChatViewModel's own repeatOnLifecycle(STARTED) pattern), and refresh
  Room-sourced pages in ~40-id chunks as they page in, skipping pages the
  RemoteMediator just fetched (loadState.mediator?.append is Loading).

* fix(chat): record reaction recents once, at tap time

The ViewModel recorded on tap using only the live overlay, and ReactionsDelegate
recorded again on a successful add, so each add counted twice and a take-back of
a reaction stored only in Room counted as a use. Record in the delegate when the
tap is made, against the Room-seeded state, as iOS ConversationReactions.toggle does.

* fix(chat): show reaction errors as one-line toasts with the iOS copy

iOS shows "Couldn't add reaction" and "This message has the maximum number of
reactions" as a single-line toast. Drop the bottom-bar error and its invented
second lines.

* feat(emojis): add EmojiPickerModel search/section grouping

Mirrors iOS's EmojiPickerModel: Frequently Used row (deduped, order preserved)
then one section per catalog category, or a single search-results section when
the query is non-empty. Undrawable entries are filtered from every section.

* feat(chat): default getReactorsPage to a 50-row page

REACTORS_PAGE_SIZE matches the reactors sheet's own page size (decision 4)
rather than QueryOptions' general-purpose default of 100.

* feat(chat): merge reactors sheet pages into one row per person

* feat(chat): add reactor name resolution and reactors/picker sheet detents

ReactorNameResolver is a pure precedence function over self, the cached
UserProfile, the chat's member roster, and a requested sender-profile
fetch, mirroring the sources ChatViewModel.memberParticipant already
reads. ChatStep.ReactionPicker/Reactors now also implement HalfSheet,
matching iOS's .medium/.large detents for both sheets.

* feat(chat): add ReactorsPrefetchCache for OpenReactors-triggered loading

One ReactorsListModel per messageId, started on OpenReactors (a pill long-press) rather than the sheet's own composition, so the fetch is already in flight by the time the sheet reads rows/loading for that id.

* feat(chat): start reactors fetch on OpenReactors, resolve reactor names

ChatViewModel now owns a ReactorsPrefetchCache keyed by messageId and starts it in the OpenReactors handler, one step before the navigator pushes the sheet. reactorName()/reactorParticipant() combine the cached-profile store, chat members, and sender profiles per decision 4's precedence, requesting a server fetch when none of them has an answer.

* feat(chat): resolve reactor avatar alongside name

reactorDisplay() replaces reactorName() with a small ReactorDisplay(name, profile) pair, so the reactors sheet's row can draw an avatar from the same resolved source rather than a second lookup. Self resolves to the viewer's own profilePicture under the 'You' label.

* fix(chat): key ReactorsPrefetchCache flows so subscribers survive a race

A composition reading rows()/loading() before OpenReactors calls start() was capturing a placeholder StateFlow that start() could never update. Back both by one shared map-keyed StateFlow instead, so a subscription taken before start() still sees the fetch land.

* feat(chat): build the reactors sheet UI

* feat(chat): build the reaction picker sheet UI

* feat(chat): wire the picker and reactors sheets into ChatFlowScreen

* test(messenger): pass userProfileDataSource mock to ChatViewModel in analytics tests

* test(emojis): run the drawability vectors on a device

Robolectric's Paint has no emoji font, so the unit test could only check that
EmojiDrawability ran. The instrumented test asserts each #17 drawability vector
against the device font, with a verbatim copy of reactions.json in androidTest assets.

* fix(emojis): run the Hilt processor so the app sees ReactionsModule

* fix(emojis): keep reaction recents per account

* fix(persistence): read reaction rows stored under the old sequence key

* fix(chat): fade overflowing reactor emoji and open profiles from the person only

* feat(messenger): match reaction picker sheet to iOS

Rework ReactionPickerSheet to mirror iOS's EmojiPickerSheet (node
9768:1402): drop the reused reactors-sheet title, replace the search
row with a black-.26 capsule (magnifier + Search + clear), let the
7-column grid fill the sheet as it expands, and add a floating Haze
glass category bar over the bottom of the grid with a scroll-synced
selection indicator. Show a spinner while the catalog loads and the
existing no-results copy when a search comes back empty.

Departure from iOS: no drag-across-the-bar gesture on the category
bar, tap-only.

* test(chat): cover ReactionPillRow and QuickReactionStrip

Tap/long-press/plus wiring, the previewer's read-only contract,
narrow-width N-more collapse, selection semantics, and the quick
strip's scroll-to-overflow all lacked coverage.

ReactionPillRow's pill tap called onToggle even when canReact was
false, so a previewer's tap silently registered a reaction attempt
instead of doing nothing. Gate it on canReact. Also tag pills/more/plus
chips for lookup and expose selfReacted/highlighted as semantics
selected, since neither existed to assert against.

* fix(chat): draw no pill row until a message has a reaction, and size "+" to 28dp

iOS hides the row and its "+" while a message has no reactions; Android drew a
"+" under every message. PlusChip also ignored its size, so the chip shrank to
the glyph.

* fix(chat): place the quick reaction strip beside the bubble, sized as on iOS

The strip drew inside the bubble's box shifted up 12dp, so it covered the
bubble and ran to the screen edge with "+" scrolled out of view. It now sits in
a popup 16dp above the bubble (below it when the selection bar is in the way),
hugging the sender's side and 16dp inside the window, at iOS's 55dp height and
313dp max width, with "+" pinned outside the scrolling emoji.

* fix(chat): leave selection when the strip's + opens the picker

The strip stayed on screen over the picker because the message stayed
selected. iOS dismisses its context menu before presenting the picker; this
does the same.

* fix(chat): size reaction pills and their + as on iOS

Pills and the "N more" pill never applied their 28dp height, so they shrank
to the text and sat shorter than "+", and their text took Material's dark
content color, leaving the count unreadable on the dark fill. They now match
iOS: 28dp tall, a 15sp emoji and a 13sp medium count in textMain, 4dp apart.
"+" uses the strip's add-reaction icon on a white-18% circle, and both "+"
buttons are labelled "Add reaction" for TalkBack.

* fix(messenger): slide the picker's category indicator and let it drag, as on iOS

* fix(messenger): keep the picker's category bar on screen once the sheet can expand

* fix(messenger): move the picker's category bar in step with the sheet

The bar's lift came from onGloballyPositioned, which only sees the
sheet's new position after layout, so the bar trailed the sheet by a
frame and jumped while it was dragged. The sheet host now exposes
LocalSheetOverhang, read from the sheet state's drag offset, and the bar
reads it at placement so both move in the same frame.

* fix(chat): grow the quick reaction strip in as iOS does

The strip popped in at full size in its own popup window, a beat out of step
with the bubble's raise. It now enters as the iOS strip does: the capsule widens
out of the side it hugs with "+" on its growing edge, and the emoji scale in one
after another, settling in about 200ms. Everything animates in the draw phase,
so the popup never resizes.

* fix(chat): keep pills under the backdrop and enter the strip with the lift

Selecting a message hid every row's pill row, so the pills vanished from
the whole transcript while one bubble was raised. They now stay, blurred
and dimmed with their row, and ignore touches like the rest of it.

The strip was built only after the selection landed: a glyph check over
the first catalog category and a DataStore read, then a second state
update. The popup therefore trailed the lift. Those inputs are now kept
ready from init and refreshed after each toggle, and the strip is built
as the message is selected and carried in on the same event.

* fix(chat): place the reaction strip below the measured top bar

* test(reactions): read reactions.json from test-vectors instead of three copies

* fix(chat): line the reaction strip up with the bubble, not its row

* fix(messenger): lift only the bubble, leaving its reaction pills behind the backdrop

The lift scaled the whole row, so a selected message's pills rose with its
bubble. iOS lifts only the bubble view; the pills stay in the cell under
the backdrop. Move the scale onto the bubble and give the selected row's
pills the same dim and blur as the rest of the transcript.

* fix(chat): seed the stream's reaction state from Room before writing it back

A reaction arriving over the event stream built its message's state from
nothing, then merged it into Room as a full summary. Every stored emoji the
stream hadn't mentioned this session was tombstoned at its stored version,
and GetReactionSummaries at that same version can't replace it. A message
with 16 emoji showed 10 after one live reaction.

* fix(chat): animate reaction pills in and out, clip their ripple, and duck the picker's category bar

Pills scale and fade in and out, the row's height springs as pills come and go, and
each chip is clipped before its click handling so the ripple stays in the capsule.
The picker's category bar stops lifting at the top of the grid, so collapsing the
sheet takes the bar down with it instead of lifting it over the search field.
ChatAnimations moves to chat-ui so the pill row can share the reaction springs.
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