Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
327 commits
Select commit Hold shift + click to select a range
e84f436
perf: memoize returned closures from useMessagePress/useMessageLongPress
diegolmello Jul 6, 2026
541e85b
perf: de-churn RoomView on incoming messages
diegolmello Jul 6, 2026
a3e2898
fix: re-hide a revealed ignored message when its ignore state changes
diegolmello Jul 6, 2026
cfc0e5a
fix: key Quote reply list by attachment identity, not array index
diegolmello Jul 6, 2026
233b131
fix: derive RepliedThread display in render, fetch on real inputs
diegolmello Jul 6, 2026
9e11259
refactor: drive useMediaAutoDownload status via an event reducer
diegolmello Jul 6, 2026
529e69b
refactor: split MessageRoomProvider and diff-guard the store mirror
diegolmello Jul 6, 2026
061658c
fix: narrow tmid before fetchThreadName in RepliedThread effect
diegolmello Jul 6, 2026
3eec1c1
refactor: model RoomView interaction state as a discriminated union
diegolmello Jul 6, 2026
722f0d4
fix: guard RepliedThread fetch against stale writes
diegolmello Jul 6, 2026
67a6de9
merge: managing-state fixes (NATIVE-22 findings 001-006)
diegolmello Jul 6, 2026
dbac499
refactor: move Attachments unit tests into components/__tests__ (NATI…
diegolmello Jul 6, 2026
ca23750
refactor: move Attachments stories into components/stories and regist…
diegolmello Jul 6, 2026
06e966b
refactor: flatten CollapsibleQuote and OverlayComponent to single-fil…
diegolmello Jul 6, 2026
00027bc
refactor: retire RoomView getCustomEmoji in favor of useCustomEmoji i…
diegolmello Jul 7, 2026
0a3d98f
refactor: dedupe TMessageAction into definitions (NATIVE-22)
diegolmello Jul 7, 2026
ce3d8ee
refactor: rename useIsInfo to useIsInfoMessage returning boolean (NAT…
diegolmello Jul 7, 2026
4c906ea
refactor: pass isHeader into MessageInner instead of re-reading group…
diegolmello Jul 7, 2026
81760b8
fix: remove self-assignment in CollapsibleQuote color override (NATIV…
diegolmello Jul 7, 2026
827dc4d
refactor: use colors from useTheme instead of themes[theme] in Messag…
diegolmello Jul 7, 2026
14e5726
docs: refine CONTEXT.md message glossary (NATIVE-22)
diegolmello Jul 7, 2026
5dd2032
chore: format code and fix lint issues
diegolmello Jul 7, 2026
112cdb9
refactor: guard appendQuote against duplicate ids and rename useArchi…
diegolmello Jul 7, 2026
5dd895a
refactor: make REST string-ts path explicit in computeIsHeader, drop …
diegolmello Jul 7, 2026
c6b44d5
refactor: extract memoized RoomProviders FC, stabilize RoomView RoomC…
diegolmello Jul 7, 2026
d316bda
refactor: wire ShareView to shared RoomProviders FC (NATIVE-22)
diegolmello Jul 7, 2026
7278a62
chore: remove console.count render log (NATIVE-22)
diegolmello Jul 7, 2026
d2b29fc
test: pin autoTranslate boundary for translate hooks (NATIVE-22)
diegolmello Jul 7, 2026
f41a8ba
chore: co-locate message testHelpers (NATIVE-22)
diegolmello Jul 7, 2026
954b18f
refactor: narrow Discussion item subscription (NATIVE-22)
diegolmello Jul 7, 2026
e83d3f3
fix: unify autoTranslate boundary to truthy (NATIVE-22)
diegolmello Jul 7, 2026
b8c9a90
refactor: collapse item/previousItem effects to one (NATIVE-22)
diegolmello Jul 7, 2026
f98690c
refactor: drop bespoke action->interaction mapping in ShareView (NATI…
diegolmello Jul 7, 2026
10521f4
refactor: extract useMessageTouchable pressability hook (NATIVE-22)
diegolmello Jul 7, 2026
da66df3
perf: sync only reactive fields in MessageRoomStoreProvider (NATIVE-22)
diegolmello Jul 7, 2026
f27d8aa
refactor: extract shared BranchAttachmentContent for message branches…
diegolmello Jul 7, 2026
e81c177
refactor: rename Touchable to MessageActionTouchable (NATIVE-22)
diegolmello Jul 7, 2026
4afdf9f
chore: route ModalBlockView's empty-message fixture through unknown (…
diegolmello Jul 7, 2026
3512115
refactor: strip redundant displayName from message components (NATIVE…
diegolmello Jul 7, 2026
0381b55
Merge branch 'develop' into native-22-message-hooks
diegolmello Jul 8, 2026
f0c61cc
chore: refresh time-relative Timestamp story snapshot
diegolmello Jul 8, 2026
b074fee
refactor: rename InteractionStore to MessageActionStore, normalize ac…
diegolmello Jul 8, 2026
01ad242
refactor: collapse message-action hooks into one useMessageAction() (…
diegolmello Jul 8, 2026
b0b3516
refactor: harden no-provider fallback with an inert MessageActionStor…
diegolmello Jul 8, 2026
289d65e
merge: MessageActionStore refactor (NATIVE-22)
diegolmello Jul 8, 2026
5b9bc59
fix: resync room-reactive fields in MessageRoomStore (NATIVE-22)
diegolmello Jul 8, 2026
052ba9b
refactor: move MessageActionStore into containers/message/stores (NAT…
diegolmello Jul 8, 2026
9e1d3f8
fix: restore Jitsi started-a-call line for jitsi_call_started message…
diegolmello Jul 8, 2026
82637b9
test: document useFile's stuck isMessagePersisted contract (NATIVE-22)
diegolmello Jul 8, 2026
cf2b383
test: cover useMessageTouchable/useMessageLongPress/useMessagePress b…
diegolmello Jul 8, 2026
f768034
refactor: narrow IMessage.blocks and e2eMentions off any (NATIVE-22)
diegolmello Jul 8, 2026
49ceb59
test: guard {memo:true} @json invariant (NATIVE-22)
diegolmello Jul 8, 2026
ffb81e9
feat: warn on capture-once store footguns (NATIVE-22)
diegolmello Jul 8, 2026
5827c9c
refactor: drop dead editing/rightButtonsWidth state and close the any…
diegolmello Jul 8, 2026
43494d2
test: close Blocks/RoomProviders/MessageRoomStore coverage gaps (NATI…
diegolmello Jul 8, 2026
d3283db
refactor: remove any from message story fixtures (NATIVE-22)
diegolmello Jul 8, 2026
0a12d2f
refactor: split message components into Message/ (density) + Layout/ …
diegolmello Jul 8, 2026
780456c
refactor: colocate Content orchestrator into Content/index.tsx (NATIV…
diegolmello Jul 8, 2026
5e560b7
chore: annotate Touch.tsx with 'use memo' compiler directive (NATIVE-22)
diegolmello Jul 8, 2026
f2a428f
refactor: rename AttachmentLayout → ContentLayout (NATIVE-22)
diegolmello Jul 9, 2026
b907bc8
refactor: split Message and MessageTouchable into separate files (NAT…
diegolmello Jul 9, 2026
954a30a
Merge branch 'develop' into native-22-message-hooks
diegolmello Jul 9, 2026
387fd4a
fix: correct stale InteractionStore error message in MessageActionSto…
diegolmello Jul 9, 2026
de784df
refactor: use MessageActionProvider in prod, relocate test helper (NA…
diegolmello Jul 9, 2026
149d7e1
chore: remove dead displayName and redundant comment (NATIVE-22)
diegolmello Jul 9, 2026
6459910
chore: remove duplicate roomAttrsUpdate key (NATIVE-1354)
diegolmello Jul 9, 2026
8db26c4
docs: add join-state vocabulary and Positional-state split (NATIVE-1353)
diegolmello Jul 9, 2026
0a95808
refactor: group message touch-surfaces into Touchable/ (NATIVE-22)
diegolmello Jul 9, 2026
555f941
docs: retire 'interaction' from glossary, fold into Message Action St…
diegolmello Jul 9, 2026
e5b0a68
refactor: extract useRoomSubscription hook (NATIVE-1356)
diegolmello Jul 9, 2026
5ec4755
refactor: extract useJumpToMessage hook (NATIVE-1355)
diegolmello Jul 9, 2026
514c18d
refactor: dedup message component helpers (NATIVE-22)
diegolmello Jul 9, 2026
681691d
fix: emit fresh roomUpdate snapshot from useRoomSubscription (NATIVE-…
diegolmello Jul 9, 2026
73004e8
docs: add Message component architecture reference (NATIVE-22)
diegolmello Jul 9, 2026
e09d96c
refactor: extract useHeader hook from RoomView
diegolmello Jul 9, 2026
e796a59
refactor: convert RoomView to a function component
diegolmello Jul 9, 2026
f03920e
refactor: remove frozen-handler dev guard from MessageRoomStore
diegolmello Jul 9, 2026
be9f9eb
fix: never quote edit/react message id in media ShareView (NATIVE-22)
diegolmello Jul 10, 2026
abe0f0c
refactor: move IRoomInfoParam to definitions (NATIVE-22)
diegolmello Jul 10, 2026
bba78b1
fix: defer room init behind interactions and stabilize its trigger (N…
diegolmello Jul 10, 2026
59e8990
refactor: adopt 'use memo' annotation, drop manual memoization
diegolmello Jul 10, 2026
0e6f1c1
fix: rebind ROOM_REMOVED listener when handler identity changes
diegolmello Jul 10, 2026
9a8ccd6
test: cover useRoomSubscription unmount cleanup
diegolmello Jul 10, 2026
901c0af
refactor: dissolve useRoomSubscription into rid-keyed RoomStore
diegolmello Jul 10, 2026
82e5e6f
refactor: replace RoomContext with per-instance composer zustand store
diegolmello Jul 10, 2026
2cbffca
refactor: extract useMessageActions hook from RoomView
diegolmello Jul 10, 2026
a61d2b6
refactor: extract useRoomLifecycle hook from RoomView
diegolmello Jul 10, 2026
d32fd36
refactor: extract useRoomNavigation hook from RoomView
diegolmello Jul 10, 2026
7a32745
refactor: extract useOmnichannelPermissions hook from RoomView
diegolmello Jul 10, 2026
bf47367
refactor: extract MessageRow component from RoomView
diegolmello Jul 10, 2026
8e442c5
refactor: extract RoomFooter + RoomMessageActions components from Roo…
diegolmello Jul 10, 2026
eabf381
refactor: drop room-object param from RoomView navigation route
diegolmello Jul 10, 2026
f44d17c
refactor: shrink useHeader to self-source ambient and store data
diegolmello Jul 11, 2026
855d9b5
refactor: warm RoomStore at navigation time
diegolmello Jul 11, 2026
34e17bf
refactor: annotate RoomView with 'use memo' and drop manual callbacks
diegolmello Jul 11, 2026
0bc4c5c
refactor: drop dead fname field from goRoom warm-up
diegolmello Jul 11, 2026
59f97b0
Merge remote-tracking branch 'origin/native-22-message-hooks' into na…
diegolmello Jul 11, 2026
5dec20a
chore: format code and fix lint issues
diegolmello Jul 11, 2026
d5990e2
fix: subscribe MessageRow and RoomFooter to roomUpdate snapshots
diegolmello Jul 11, 2026
9417a85
docs: drop removed FROZEN_KEYS guard references from message architec…
diegolmello Jul 11, 2026
a3e2801
fix: harden RoomStore init ordering, error logging and rid-less registry
diegolmello Jul 11, 2026
3af0880
refactor: type ComposerStore contract and widen handleSendMessage
diegolmello Jul 11, 2026
fa8b597
test: add direct suites for useRoomLifecycle, useRoomNavigation and C…
diegolmello Jul 11, 2026
72488db
refactor: extract useRoomWithUpdate hook with consumer re-render regr…
diegolmello Jul 11, 2026
2f12a58
test: extend useRoomLifecycle and useRoomNavigation suites to unteste…
diegolmello Jul 11, 2026
482f2c5
fix: keep composer placeholder fresh by threading roomUpdate into the…
diegolmello Jul 11, 2026
8f7bb24
fix: discard superseded omnichannel permission fetches with effect-sc…
diegolmello Jul 12, 2026
bcc5918
fix: derive MessageRow isIgnored and badge color inside store selectors
diegolmello Jul 12, 2026
2b37d2b
test: add React Compiler compilation contract for RoomView
diegolmello Jul 12, 2026
ea36011
refactor: remove exhaustive-deps suppressions so RoomView index compiles
diegolmello Jul 13, 2026
eb14e7d
refactor: move omnichannel permission helpers to module scope so hook…
diegolmello Jul 13, 2026
a29e7c5
refactor: unblock compiler on useRoomNavigation with useDebounce and …
diegolmello Jul 13, 2026
8ee630b
refactor: hoist jumpToMessage impl to module scope so the compiler st…
diegolmello Jul 13, 2026
535cc49
refactor: de-suppress useScroll effects so the compiler stops skippin…
diegolmello Jul 13, 2026
70f090f
refactor: de-suppress useRoomLifecycle so the compiler stops skipping…
diegolmello Jul 13, 2026
56bff8a
Merge remote-tracking branch 'origin/develop' into native-34-roomview…
diegolmello Jul 13, 2026
5da0337
perf(RoomView): render fewer rows in first batch for non-anchored lists
diegolmello Jul 13, 2026
380a9bf
refactor(RoomView): move ComposerState to definitions, type ComposerS…
diegolmello Jul 14, 2026
a7d720a
refactor(RoomView): derive readOnly/E2EE at read-time, remove orchest…
diegolmello Jul 14, 2026
a59c9c9
refactor(RoomView): extract jumpToMessage impl into a service
diegolmello Jul 14, 2026
d80fbb5
refactor(RoomView): dissolve useRoomLifecycle into focused hooks
diegolmello Jul 14, 2026
fa8eb96
refactor(message): add useRoomMessageHandlers for self-sourced messag…
diegolmello Jul 14, 2026
269eaee
refactor(RoomView): extract MessageRow hooks and fix render-phase haptic
diegolmello Jul 14, 2026
ff421d2
refactor(message): self-source leaf handlers via useRoomMessageHandlers
diegolmello Jul 14, 2026
a498ce3
refactor(RoomView): convert RightButtons to function component and sh…
diegolmello Jul 14, 2026
37a16f0
refactor(RoomView): decompose RoomFooter into self-sourcing branch co…
diegolmello Jul 14, 2026
f98c852
refactor(RoomView): make omnichannel permission flags reactive via us…
diegolmello Jul 14, 2026
b4c9067
perf(message): gate per-row a11y ordering wrappers behind accessibili…
diegolmello Jul 14, 2026
8bc6793
test(RoomView): update LoadMore story snapshots after a11y wrapper ga…
diegolmello Jul 15, 2026
d6c9e97
refactor(RoomView): consolidate shared types, drop barrels and test-o…
diegolmello Jul 15, 2026
2312900
fix(RoomView): clear eslint errors across refactored hooks
diegolmello Jul 15, 2026
3fbc2b4
fix(RoomView): pass joinCodeRequired through navigation so protected …
diegolmello Jul 15, 2026
5ebf8c6
fix(RoomView): restore initialNumToRender=20 so non-anchored scroll p…
diegolmello Jul 15, 2026
53e5d21
test(e2e): wait for main room to settle after leaving thread before s…
diegolmello Jul 15, 2026
3457574
fix(RoomView): capture rid/t/tmid once at mount so popTo param wipe c…
diegolmello Jul 15, 2026
198fc39
Merge branch 'develop' into native-34-roomview-hooks
diegolmello Jul 15, 2026
07198fc
fix(RoomView): split RoomStore registry into peek/acquire/release to …
diegolmello Jul 15, 2026
dcc4565
refactor(RoomView): apply Phase 2 comment/test verdicts + relocate ho…
diegolmello Jul 15, 2026
f43feb5
refactor(RoomView): move autocomplete a11y announce into a colocated …
diegolmello Jul 15, 2026
266e3f0
fix(RoomView): harden useRoomStoreByRid fallback and defer unmount re…
diegolmello Jul 15, 2026
05b2db6
refactor(RoomView): make join/resume creator-owned actions, drop stor…
diegolmello Jul 15, 2026
545fce6
refactor(RoomView): produce message handlers in RoomView, inject via …
diegolmello Jul 15, 2026
8ccdb24
refactor(RoomView): adopt usePermissions, split observer hooks, dedup…
diegolmello Jul 15, 2026
f4f33cc
refactor(message): source user/baseUrl from redux, drop MessageRoomSt…
diegolmello Jul 15, 2026
635241e
refactor(RoomView): Phase 8 conventions sweep — theme, navigation, ty…
diegolmello Jul 16, 2026
29bbe91
refactor(RoomView): move root components into components/
diegolmello Jul 16, 2026
b1aceca
Merge remote-tracking branch 'origin/native-34-roomview-hooks' into n…
diegolmello Jul 16, 2026
1615f6d
chore: format code and fix lint issues
diegolmello Jul 16, 2026
afb6a3e
refactor(RoomView): align latest-ref usage with escape-hatches review
diegolmello Jul 16, 2026
ed710d8
Merge branch 'native-34-roomview-hooks' of github.com:RocketChat/Rock…
diegolmello Jul 16, 2026
1fa03be
refactor(RoomView): extract shared pushThreadRoom service
diegolmello Jul 16, 2026
a6e80df
refactor(RoomView): dedup reaction handlers and send path
diegolmello Jul 16, 2026
5bfeaf8
refactor(RoomView): type message-hook params, drop any/Function and t…
diegolmello Jul 16, 2026
8a6d4df
fix(RoomView): recompute livechat on-hold permission on pure onHold t…
diegolmello Jul 16, 2026
fe17027
fix(RoomView): mechanical review nits (log, effect cleanup, named hel…
diegolmello Jul 16, 2026
c54bb03
refactor(RoomView): dedup ComposerStore sync field list via rest state
diegolmello Jul 16, 2026
71d2451
fix(RoomView): warn when acquireRoomStore misses a swept registry entry
diegolmello Jul 16, 2026
9ad61cd
refactor(RoomView): self-source props, drop mapStateToProps + HOCs
diegolmello Jul 16, 2026
6d54182
refactor(RoomView): dedup dual-mode override + roomUpdate-freshness p…
diegolmello Jul 16, 2026
3717594
perf(RoomView): stop per-message header rebuild in useHeader
diegolmello Jul 16, 2026
36f27a5
perf(RoomView): fetch livechat routing config once, derive on-hold se…
diegolmello Jul 16, 2026
74b28bd
refactor(MessageComposer): derive quoted/editing selectors in Message…
diegolmello Jul 16, 2026
cd162f9
refactor(MessageRoomStore): type nav-param, merge overrides, split re…
diegolmello Jul 16, 2026
6bf89cf
refactor(isReadOnly): extract shared branch evaluator
diegolmello Jul 16, 2026
71ffc1d
fix(isReadOnly): short-circuit archived/muted before permission fetch
diegolmello Jul 16, 2026
eaa7412
refactor(RoomView): drop legacy connect/forwardRef/withMasterDetail f…
diegolmello Jul 16, 2026
916cb5f
refactor(RoomView): render MessageRow directly, drop renderRow render…
diegolmello Jul 16, 2026
784d171
refactor(RoomView): batch quick-win cleanups
diegolmello Jul 16, 2026
7c29414
Merge remote-tracking branch 'origin/develop' into native-34-roomview…
diegolmello Aug 3, 2026
ad4187b
cleanup
diegolmello Aug 3, 2026
a137b83
cleanup
diegolmello Aug 3, 2026
9b1dbc7
Merge branch 'native-34-roomview-hooks' of github.com:RocketChat/Rock…
diegolmello Aug 3, 2026
8ac3e8b
Merge branch 'native-34-roomview-hooks' of github.com:RocketChat/Rock…
diegolmello Aug 3, 2026
e33a09f
Merge branch 'native-34-roomview-hooks' of github.com:RocketChat/Rock…
diegolmello Aug 3, 2026
ab7a54d
Merge branch 'develop' into native-34-roomview-hooks
diegolmello Aug 4, 2026
0a46316
Merge branch 'develop' into native-34-roomview-hooks
diegolmello Aug 4, 2026
1067f85
chore: drop 'use memo' directives now that the compiler runs in infer…
diegolmello Aug 4, 2026
0f7cd47
Merge remote-tracking branch 'origin/native-34-roomview-hooks' into n…
diegolmello Aug 4, 2026
036d593
fix: keep RoomView header working after a param wipe
diegolmello Aug 5, 2026
17989a5
fix(RoomView): keep the join-code trigger on the screen, not the shar…
diegolmello Aug 10, 2026
ced8ac4
fix: keep the room footer from flickering when a thread screen mounts
diegolmello Aug 10, 2026
b8c148f
fix: keep the channel unread divider when replying in a thread
diegolmello Aug 10, 2026
40fb713
fix: retry a room that fails to load instead of leaving it empty
diegolmello Aug 10, 2026
36bf5cc
refactor: give init a real result and a per-run cancel token
diegolmello Aug 11, 2026
cf9ed60
refactor: let init own the room reads and writes
diegolmello Aug 11, 2026
ad78362
refactor: give the room screen's own state one home
diegolmello Aug 11, 2026
94488f3
Merge remote-tracking branch 'origin/develop' into native-34-roomview…
diegolmello Sep 1, 2026
b5018fa
refactor(RoomView): encapsulate RoomStore ownership
diegolmello Sep 1, 2026
8c314d6
refactor(RoomStore): collapse duplicate registry acquire paths
diegolmello Sep 1, 2026
810458a
refactor(RoomView): drop unused hook return surface
diegolmello Sep 1, 2026
49654cb
refactor(RoomView): share one context guard per store
diegolmello Sep 1, 2026
a70ca45
refactor(RoomView): read records through the database services
diegolmello Sep 1, 2026
e96efad
refactor(RoomView): drop unused escape hatches and stale state type
diegolmello Sep 1, 2026
3c37975
refactor(RoomView): drop redundant guard and pass-through in message …
diegolmello Sep 1, 2026
3c2fd5e
refactor(message): pass room handlers as one bag from every view
diegolmello Sep 1, 2026
1d20f9c
perf(RoomView): read thread unreads from the observed room store
diegolmello Sep 1, 2026
af548b4
perf(RoomView): fetch the DM counterpart alongside the message load
diegolmello Sep 1, 2026
622ac46
perf(RoomView): fetch the livechat routing config once per screen
diegolmello Sep 1, 2026
76141b2
refactor(RoomView): drop a redundant comment and a tautological test
diegolmello Sep 1, 2026
653e72a
refactor(RoomView): drop the useRightButtons pass-through (#7630)
diegolmello Sep 1, 2026
eb08cc6
refactor(RoomView): pass the message handler bag as a prop (#7629)
diegolmello Sep 1, 2026
ceb7209
refactor(RoomView): rename listRef to listContainerRef and drop resta…
diegolmello Sep 1, 2026
1d5b998
refactor(RoomView): drop the unused consumeJumpParam from useJumpToMe…
diegolmello Sep 1, 2026
7944244
refactor(RoomView): inline the useRoomActions pass-through
diegolmello Sep 1, 2026
97d5f2d
refactor(RoomView): colocate MessageRow's single-caller hooks
diegolmello Sep 1, 2026
543554d
refactor(RoomView): extract getRoomHeaderProps out of useHeader's effect
diegolmello Sep 1, 2026
764c06f
refactor(RoomView): make getRoomHeaderProps module-private
diegolmello Sep 1, 2026
a2af57f
refactor(RoomView): turn useMessageSeparators into a pure function
diegolmello Sep 1, 2026
a649711
refactor(RightButtons): extract navigateToScreen helper
diegolmello Sep 1, 2026
bb97d39
refactor(RoomView): rename isGroupChatValue to roomIsGroupChat
diegolmello Sep 1, 2026
5703498
refactor(RoomView): read Banner colors from useTheme
diegolmello Sep 1, 2026
2e01926
refactor(RoomView): move toggleFollowThread to lib/methods
diegolmello Sep 1, 2026
73674e7
refactor(MessageComposer): select only the action kind
diegolmello Sep 1, 2026
45b964c
chore(MessageComposer): update stale TODO referent
diegolmello Sep 1, 2026
ccae769
refactor(MessageActionStore): group useMessageActionKind with useMess…
diegolmello Sep 1, 2026
c3ecdd2
refactor(RightButtons): narrow navigateToScreen typing
diegolmello Sep 1, 2026
d5ad52a
docs(RoomView): describe the current design, not its history
diegolmello Sep 1, 2026
f7ac989
test(RoomView): keep one copy of the shared onReactionPress cases
diegolmello Sep 1, 2026
984c925
test(RoomStore): drop cases subsumed by siblings
diegolmello Sep 1, 2026
7023456
test(MessageComposer): stub useQuotedMessageIds instead of reimplemen…
diegolmello Sep 1, 2026
9ee278c
test(usePermissions): assert literal expectations instead of hasPermi…
diegolmello Sep 1, 2026
5a2845d
test(message): drop vacuous prop-type assertions and a restated gate-…
diegolmello Sep 1, 2026
ceb9d01
test(RoomView): drop the mount-only case covered by its neighbours
diegolmello Sep 1, 2026
259ce8e
test(RoomProviders): drop the composer value case covered by Composer…
diegolmello Sep 1, 2026
00e4f54
test(useHeader): drop typeof header assertions and a mock echo
diegolmello Sep 1, 2026
3f69371
test(useRoomInit): keep only the distinct rejects case
diegolmello Sep 1, 2026
cdb61db
test(useGoRoomActionsView): drop the case the body cannot observe
diegolmello Sep 1, 2026
0358239
test(useJumpToMessage): name the out-of-window case for what it asserts
diegolmello Sep 1, 2026
4d637f9
docs(RoomView): point the unsourced invariants and init caller at rea…
diegolmello Sep 1, 2026
36827dd
test(RoomProviders): assert rid reaches the composer store
diegolmello Sep 1, 2026
40a12a9
refactor(RoomView): extract indexOfMessage in useScroll
diegolmello Sep 1, 2026
bc57429
refactor(RoomView): rename shouldNavigateToRoom to isTargetOutsideCur…
diegolmello Sep 1, 2026
205c120
refactor(RoomView): drop stale timeout comment in jumpToMessage
diegolmello Sep 1, 2026
c3d187f
refactor(MessageStore): share the auto-translate predicate
diegolmello Sep 1, 2026
8ef0c8a
refactor(ComposerInput): rename result to textBeforeMention
diegolmello Sep 1, 2026
fb2727f
refactor(MessageStore): return the auto-translate language instead of…
diegolmello Sep 1, 2026
0bc1c39
refactor(RoomView): name the thread name result in pushThreadRoom
diegolmello Sep 1, 2026
babf69b
refactor(RoomView): name the re-scroll target index in useScroll
diegolmello Sep 1, 2026
1fdb20b
chore(RoomView): remove docs folder
diegolmello Sep 2, 2026
99f9760
Merge remote-tracking branch 'origin/develop' into native-34-roomview…
diegolmello Sep 2, 2026
be5b0b0
refactor(RoomView): unblock compiler for ReactionPicker (#7633)
diegolmello Sep 2, 2026
e9d971f
refactor(RoomView): observe the followed thread through useSyncExtern…
diegolmello Sep 2, 2026
4dbf414
Merge branch 'develop' into native-34-roomview-hooks
diegolmello Sep 3, 2026
6c1bfb8
chore: format code and fix lint issues
diegolmello Sep 3, 2026
915fd10
refactor(RoomView): first-tier simplifications after the hooks migrat…
diegolmello Sep 3, 2026
8e4d389
refactor(RoomView): make messaging callback wiring explicit (#7639)
diegolmello Sep 3, 2026
bad92c2
refactor(RoomView): tidy room screen components (#7641)
diegolmello Sep 3, 2026
ffddd22
refactor: simplify MessageComposer (#7640)
diegolmello Sep 3, 2026
d4f1b76
refactor(RoomView): narrow hook subscriptions and drop redundant indi…
diegolmello Sep 3, 2026
3c469a3
refactor(RoomView): own room stores per screen (#7642)
diegolmello Sep 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .maestro/tests/room/threads.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,14 @@ tags:
timeout: 60000
- tapOn:
id: 'header-back'
- extendedWaitUntil:
notVisible:
id: 'room-view-title-thread'
timeout: 60000
- extendedWaitUntil:
visible:
id: 'room-view-title-${output.room.name}'
timeout: 60000

# should create thread delete the message and the thread show the correct number of messages
- runFlow:
Expand Down
61 changes: 34 additions & 27 deletions CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@

## Rooms & Conversations

| Term | Definition | Aliases to avoid |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- |
| **Room** | A server-side conversation container with shared state (name, type, settings) | Chat, conversation |
| **Subscription** | A user's personal relationship to a Room, holding per-user state (unread count, favorite, muted, open) — never a **DDP Subscription** | Membership, room entry |
| **Channel** | A public Room (type `'c'`) visible to all Workspace users | Public room |
| **Group** | A private Room (type `'p'`) visible only to invited members | Private room, private channel |
| **Direct Message** | A 1-on-1 private Room (type `'d'`) between two users | DM, PM, private message |
| **Thread** | A branched conversation spawned from a single Message, identified by `tmid` (thread message id) | Reply chain |
| **Discussion** | A separate Room spawned from a parent Room, identified by `prid` (parent room id) — unlike Threads, Discussions are full Rooms | Sub-room, sub-channel |
| **Team** | An organizational container that groups multiple Channels and users under a single entity | Workspace (a different thing) |
| **Broadcast Room** | A Room where only authorized users can send Messages; other users can only Reply Broadcast to existing Messages | Broadcast channel |
| **Reply Broadcast** | The action of replying to a Message in a Broadcast Room when the current user cannot send regular Messages | Broadcast reply |
| Term | Definition | Aliases to avoid |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- |
| **Room** | A server-side conversation container with shared state (name, type, settings) | Chat, conversation |
| **Subscription** | A user's personal relationship to a Room, holding per-user state (unread count, favorite, muted, open), never a **DDP Subscription** | Membership, room entry |
| **Subscribed Room** | A Room the user has joined, backed by a persisted Subscription model. Detected by the presence of a Subscription record. | Joined room |
| **Preview Mode** | Viewing a Room without joining: no Subscription record exists and the Room data comes from navigation params or a REST lookup. Persists until the user joins. Detected by the absence of a Subscription. | — |
| **Invited** | A Room where a Subscription exists but its status is `invited` and not yet accepted. Detected by a Subscription whose status is `invited`. | — |
| **Channel** | A public Room (type `'c'`) visible to all Workspace users | Public room |
| **Group** | A private Room (type `'p'`) visible only to invited members | Private room, private channel |
| **Direct Message** | A 1-on-1 private Room (type `'d'`) between two users | DM, PM, private message |
| **Thread** | A branched conversation spawned from a single Message, identified by `tmid` (thread message id) | Reply chain |
| **Discussion** | A separate Room spawned from a parent Room, identified by `prid` (parent room id) — unlike Threads, Discussions are full Rooms | Sub-room, sub-channel |
| **Team** | An organizational container that groups multiple Channels and users under a single entity | Workspace (a different thing) |
| **Broadcast Room** | A Room where only authorized users can send Messages; other users can only Reply Broadcast to existing Messages | Broadcast channel |
| **Reply Broadcast** | The action of replying to a Message in a Broadcast Room when the current user cannot send regular Messages | Broadcast reply |

## Messages

Expand Down Expand Up @@ -125,10 +128,12 @@ A **Last Open** and a **Last Seen** are not interchangeable — conflating them

Two distinct kinds of transient per-Room state drive how the Room view renders Messages. Keep them apart.

| Term | Definition |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------- |
| **Message Action State** | The active Message Action in the Room (Quote, Edit, or React) and its target Message(s); null when none is active |
| **Positional State** | Which Message is highlighted and the jump or scroll position |
| Term | Definition | Owner | Scope |
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ----------------------------- | ------------------------------------ |
| **Message Action State** | The active Message Action in the Room (Quote, Edit, or React) and its target Message(s); null when none is active | A per-Room MessageActionStore | One Room's Message rows and composer |
| **Positional State** | Umbrella for which Message is highlighted and the jump or scroll position. Splits across two owners (below). | — | — |
| **Jump orchestration** | Deciding to jump to a Message, resolving its anchor, and requesting the jump | RoomView (`useJumpToMessage`) | The Room screen |
| **Scroll and highlight execution** | Performing the scroll onto the target Message and rendering its highlight | The List component | The rendered Message list |

### Message Actions

Expand Down Expand Up @@ -162,17 +167,19 @@ A **Message Action** is the active mode on a Message in the Room view. The three

## Omnichannel / Livechat

| Term | Definition | Aliases to avoid |
| ---------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------- |
| **Omnichannel Room** | A customer-service Room (type `'l'`) connecting a Visitor to an Agent | Livechat room, support chat |
| **Visitor** | An external customer who initiates an Omnichannel conversation, identified by a unique token | Client, customer, end-user |
| **Agent** | A User designated to handle Omnichannel conversations, with `statusLivechat` (available/unavailable) | Support agent, operator, rep |
| **Inquiry** | A queued Omnichannel request waiting to be picked up or routed to an Agent | Queue item, ticket |
| **Department** | An organizational unit that groups Agents for Omnichannel routing | Team (ambiguous), group |
| **Omnichannel Source** | How an Omnichannel conversation was initiated (widget, email, sms, app, api) | Channel origin |
| **Served By** | The Agent currently assigned to handle an Omnichannel Room | Assigned agent, handler |
| **On Hold** | An Omnichannel Room temporarily paused by the Agent | Paused, suspended |
| **Transfer** | Moving an Omnichannel Room to a different Agent or Department | Forward, reassign, handoff |
| Term | Definition | Aliases to avoid |
| ---------------------- | ------------------------------------------------------------------------------------------------------------- | --------------------------------- |
| **Omnichannel Room** | A customer-service Room (type `'l'`) connecting a Visitor to an Agent | Livechat room, support chat |
| **Visitor** | An external customer who initiates an Omnichannel conversation, identified by a unique token | Client, customer, end-user |
| **Agent** | A User designated to handle Omnichannel conversations, with `statusLivechat` (available/unavailable) | Support agent, operator, rep |
| **Inquiry** | A queued Omnichannel request waiting to be picked up or routed to an Agent | Queue item, ticket |
| **Department** | An organizational unit that groups Agents for Omnichannel routing | Team (ambiguous), group |
| **Omnichannel Source** | How an Omnichannel conversation was initiated (widget, email, sms, app, api) | Channel origin |
| **Served By** | The Agent currently assigned to handle an Omnichannel Room | Assigned agent, handler |
| **On Hold** | An Omnichannel Room temporarily paused by the Agent | Paused, suspended |
| **Transfer** | Moving an Omnichannel Room to a different Agent or Department | Forward, reassign, handoff |
| **Routing Config** | Per-server Omnichannel routing settings that say whether Agents may Return to Queue and see the Inquiry queue | Livechat config, routing settings |
| **Return to Queue** | An Agent handing an Omnichannel Room back so it becomes an Inquiry again | Return inquiry, release chat |

## Encryption

Expand Down
1 change: 1 addition & 0 deletions app/actions/actionsTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const INQUIRY = createRequestTypes('INQUIRY', [
'QUEUE_UPDATE',
'QUEUE_REMOVE'
]);
export const ROUTING_CONFIG = createRequestTypes('ROUTING_CONFIG');
export const APP = createRequestTypes('APP', [
'START',
'READY',
Expand Down
9 changes: 5 additions & 4 deletions app/containers/MessageComposer/MessageComposer.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import { mockedStore } from '../../reducers/mockedStore';
import { type IPermissionsState } from '../../reducers/permissions';
import { type IMessage, type IShareAttachment, type TMessageActionState } from '../../definitions';
import { colors } from '../../lib/constants/colors';
import { type IRoomContext, RoomContext } from '../../views/RoomView/context';
import { type ComposerState } from '../../views/RoomView/definitions';
import { ComposerProvider } from '../../views/RoomView/stores/ComposerStore';
import { MessageActionProvider } from '../message/stores/MessageActionStore';
import * as EmojiKeyboardHook from './hooks/useEmojiKeyboard';
import { initStore } from '../../lib/store/auxStore';
Expand Down Expand Up @@ -122,20 +123,20 @@ const Render = ({
action,
children
}: {
context?: Partial<IRoomContext>;
context?: Partial<ComposerState>;
action?: TMessageActionState;
children?: ReactElement;
}) => (
<Provider store={mockedStore}>
<MessageActionProvider initialAction={action}>
<RoomContext.Provider value={{ ...initialContext, ...context }}>
<ComposerProvider {...initialContext} {...context}>
<MessageComposerContainer>
<>
<ComposerAttachments />
{children}
</>
</MessageComposerContainer>
</RoomContext.Provider>
</ComposerProvider>
</MessageActionProvider>
</Provider>
);
Expand Down
40 changes: 27 additions & 13 deletions app/containers/MessageComposer/MessageComposer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ import { useBackHandler } from '@react-native-community/hooks';
import { Q } from '@nozbe/watermelondb';
import Animated, { useAnimatedStyle, useSharedValue } from 'react-native-reanimated';

import { useRoomContext } from '../../views/RoomView/context';
import { useMessageAction } from '../message/stores/MessageActionStore';
import {
useComposerRid,
useComposerSharing,
useComposerStoreApi,
useComposerTmid
} from '../../views/RoomView/stores/ComposerStore';
import { useMessageActionKind, useMessageActionStoreApi } from '../message/stores/MessageActionStore';
import { Autocomplete } from './components';
import { MIN_HEIGHT } from './constants';
import {
Expand Down Expand Up @@ -53,8 +58,12 @@ export const MessageComposer = ({
});
const contentHeight = useSharedValue(MIN_HEIGHT);
useCloseKeyboardWhenOrientationChanges();
const { rid, tmid, sharing, editRequest, onSendMessage, setQuotesAndText } = useRoomContext();
const action = useMessageAction();
const rid = useComposerRid();
const tmid = useComposerTmid();
const sharing = useComposerSharing();
const composerStore = useComposerStoreApi();
const messageActionStore = useMessageActionStoreApi();
const actionKind = useMessageActionKind();
const alsoSendThreadToChannel = useAlsoSendThreadToChannel();
const { showEmojiKeyboard, showEmojiSearchbar, openEmojiSearchbar, resetKeyboard, keyboardHeight } = useEmojiKeyboard();
const { setAlsoSendThreadToChannel, setAutocompleteParams, clearAttachments } = useMessageComposerApi();
Expand All @@ -74,9 +83,9 @@ export const MessageComposer = ({
return false;
});

const closeEmojiKeyboardAndAction = (action?: Function, params?: any) => {
const closeEmojiKeyboardAndAction = (onClosed?: Function, params?: any) => {
resetKeyboard();
action && action(params);
onClosed?.(params);
};

useImperativeHandle(forwardedRef, () => ({
Expand All @@ -94,6 +103,11 @@ export const MessageComposer = ({
const handleSendMessage = async () => {
if (!rid) return;

const { editRequest, onSendMessage, setQuotesAndText } = composerStore.getState();
const { action } = messageActionStore.getState();
const editingMessageId = action?.kind === 'edit' ? action.messageId : undefined;
const quotedMessageIds = action?.kind === 'quote' ? action.messageIds : [];

if (alsoSendThreadToChannel) {
setAlsoSendThreadToChannel(false);
}
Expand All @@ -108,22 +122,22 @@ export const MessageComposer = ({

const textFromInput = composerInputComponentRef.current.getTextAndClear();

if (action?.kind === 'edit') {
if (editingMessageId) {
const updatedAttachments = attachments.length
? attachments.map(({ description, altText, fileId, filename }) =>
altTextSupported ? { description: altText || '', fileId, filename } : { description: description || '' }
)
: undefined;
editRequest?.({ id: action.messageId, msg: textFromInput, rid, attachments: updatedAttachments });
editRequest?.({ id: editingMessageId, msg: textFromInput, rid, attachments: updatedAttachments });
clearAttachments();
return;
}

if (attachments.length) {
let quotedMessage: string | undefined;

if (action?.kind === 'quote') {
quotedMessage = await prepareQuoteMessage(textFromInput, action.messageIds, tmid);
if (quotedMessageIds.length) {
quotedMessage = await prepareQuoteMessage(textFromInput, quotedMessageIds, tmid);
}

try {
Expand All @@ -146,8 +160,8 @@ export const MessageComposer = ({
}
}

if (action?.kind === 'quote') {
const quoteMessage = await prepareQuoteMessage(textFromInput, action.messageIds, tmid);
if (quotedMessageIds.length) {
const quoteMessage = await prepareQuoteMessage(textFromInput, quotedMessageIds, tmid);
onSendMessage?.(quoteMessage);
return;
}
Expand Down Expand Up @@ -245,7 +259,7 @@ export const MessageComposer = ({
}}>
<MessageComposerContent
recordingAudio={recordingAudio}
action={action?.kind ?? null}
action={actionKind}
showEmojiSearchbar={showEmojiSearchbar}
composerInputComponentRef={composerInputComponentRef}
composerInputRef={composerInputRef}
Expand Down
5 changes: 4 additions & 1 deletion app/containers/MessageComposer/MessageComposerContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import { MessageComposerProvider } from './context';
import { type IMessageComposerContainerProps, type IMessageComposerRef } from './interfaces';
import { MessageComposer } from './MessageComposer';
import { EmojiKeyboardProvider } from './hooks/useEmojiKeyboard';
import { ComposerAttachments } from './components/Attachments/ComposerAttachments';

const defaultChildren = <ComposerAttachments />;

export const MessageComposerContainer = forwardRef<IMessageComposerRef, IMessageComposerContainerProps>(
({ children }, ref): ReactElement => {
({ children = defaultChildren }, ref): ReactElement => {
return (
<MessageComposerProvider>
<EmojiKeyboardProvider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9599,7 +9599,7 @@ exports[`MessageComposer Toolbar tap emoji 1`] = `
borderless={true}
collapsable={false}
delayLongPress={600}
handlerTag={11}
handlerTag={-1}
handlerType="NativeViewGestureHandler"
hitSlop={
{
Expand Down
Loading
Loading