Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
151 commits
Select commit Hold shift + click to select a range
a03dc92
docs: rename ubiquitous language glossary to CONTEXT and add message …
diegolmello Jun 26, 2026
6a8682c
perf: memoize @json model fields
diegolmello Jun 26, 2026
e78bf01
merge: PR #7450 docs rename UBIQUITOUS_LANGUAGE.md -> CONTEXT.md
diegolmello Jun 29, 2026
da76a6a
merge: PR #7451 perf memoize @json model fields
diegolmello Jun 29, 2026
b2709f2
feat: add reactive useMessage snapshot hook (NATIVE-1347)
diegolmello Jun 29, 2026
0db07c7
feat: migrate Message row container to function component (NATIVE-1348)
diegolmello Jun 29, 2026
1209090
perf: move Message interaction state to a per-Room store (NATIVE-1349)
diegolmello Jun 29, 2026
45ea86d
refactor: narrow Message component props contract (NATIVE-1350)
diegolmello Jun 29, 2026
c33f71d
refactor: annotate message presentational layers for React Compiler (…
diegolmello Jun 29, 2026
7738cc3
refactor: remove dead RoomView message state (NATIVE-1352)
diegolmello Jun 29, 2026
d8c1881
fix: prevent quote attachment loss under concurrent decryption
diegolmello Jun 30, 2026
9387cbc
refactor: remove unused useInteractionApi export
diegolmello Jun 30, 2026
50e3a44
fix: harden message row reactivity and correct memo/link/translation …
diegolmello Jun 30, 2026
ad71bdd
refactor: drop redundant React.memo from compiled message subtree
diegolmello Jun 30, 2026
425a635
refactor: replace useMessage snapshot hook with per-message store
diegolmello Jul 1, 2026
abaf4c5
refactor: make message header grouping reactive via previous-record s…
diegolmello Jul 1, 2026
6f3682d
test: refresh time-drifted Timestamp story snapshot
diegolmello Jul 1, 2026
1f045e6
feat: add per-instance MessageRoomStore and provider (NATIVE-1376)
diegolmello Jul 1, 2026
39167bd
feat: add per-message data selectors for translate/id/replies (NATIVE…
diegolmello Jul 1, 2026
854e457
test: shared message render helper wiring MessageRoomProvider (NATIVE…
diegolmello Jul 1, 2026
263729b
refactor: read fetchThreadName via room-store selector in RepliedThre…
diegolmello Jul 1, 2026
1bc61ac
refactor: read grouping/thread/translate config via room store in Mes…
diegolmello Jul 1, 2026
8e7ce17
refactor: read stable message fields via room-store selectors in leaf…
diegolmello Jul 1, 2026
2e91b79
refactor: read stable fields via room/message selectors in attachment…
diegolmello Jul 1, 2026
c49a81b
fix: wrap forwarded-message preview in MessageRoomProvider (NATIVE-1376)
diegolmello Jul 1, 2026
dac3e90
refactor: read blockAction and reply fields via selectors (NATIVE-1376)
diegolmello Jul 1, 2026
6010df4
refactor: add room-store fields for message row action handlers (NATI…
diegolmello Jul 1, 2026
6dedc8c
refactor: add per-message store fields and composite press hooks (NAT…
diegolmello Jul 1, 2026
542d982
refactor: migrate message row-action consumers to store selectors (NA…
diegolmello Jul 1, 2026
3118d50
refactor: collapse MessageContainerInner and migrate press handlers t…
diegolmello Jul 1, 2026
66964e0
refactor: drop dead theme prop from the message container (NATIVE-1376)
diegolmello Jul 1, 2026
4059a49
refactor: delete MessageContext and its inert provider (NATIVE-1376)
diegolmello Jul 1, 2026
f9ab6a6
refactor: drop dead handler props from the message container interfac…
diegolmello Jul 1, 2026
4ddd704
refactor: remove unused message room theme slice (NATIVE-1376)
diegolmello Jul 1, 2026
a3fe56f
refactor: default getCustomEmoji consistently in message components (…
diegolmello Jul 1, 2026
be3b34a
fix: provide message context to UIKit modal image blocks (NATIVE-1376)
diegolmello Jul 1, 2026
4708c13
fix: seed rid in message providers for the files and search views (NA…
diegolmello Jul 2, 2026
304b241
refactor: read rid from the room store in the blocks leaf (NATIVE-1385)
diegolmello Jul 2, 2026
d3c448d
refactor: read broadcast from the room store in the broadcast leaf (N…
diegolmello Jul 2, 2026
dda147c
refactor: read archived from the room store in the message touchable …
diegolmello Jul 2, 2026
80bda4e
refactor: read isThreadRoom from the room store in content and thread…
diegolmello Jul 2, 2026
6110f85
refactor: read autoTranslateLanguage from the room store where needed…
diegolmello Jul 2, 2026
c8cfc84
refactor: read the display-name setting directly in message leaves (N…
diegolmello Jul 2, 2026
96c8d7c
test: drop vestigial autoTranslateLanguage args from accessibility-la…
diegolmello Jul 2, 2026
8330912
refactor: add timeFormat to the message room store (NATIVE-1385)
diegolmello Jul 2, 2026
7f5bffd
refactor: seed timeFormat in the message room providers (NATIVE-1385)
diegolmello Jul 2, 2026
4ca8a76
refactor: read timeFormat from the room store in the message leaves (…
diegolmello Jul 2, 2026
a7a8bc7
refactor: read attachments from the store in the quote and attachment…
diegolmello Jul 2, 2026
941c090
refactor: drop dead argument interfaces from the urls and reactions l…
diegolmello Jul 2, 2026
85cdf40
refactor: read tmid from the thread store in the content leaf (NATIVE…
diegolmello Jul 2, 2026
5e76409
refactor: add isReadReceiptEnabled to the message room store (NATIVE-…
diegolmello Jul 3, 2026
4de1b09
refactor: read isReadReceiptEnabled from the room store in the messag…
diegolmello Jul 3, 2026
5ae9832
refactor: lift the ignored flag into the message store (NATIVE-1385)
diegolmello Jul 3, 2026
9c4386e
refactor: drop stale reusable-button todos from message components (N…
diegolmello Jul 3, 2026
e404870
refactor: drop manual memo and tighten ts-ignore notes in the message…
diegolmello Jul 3, 2026
47fdf5f
refactor: make Quote and Attachments pure prop-driven
diegolmello Jul 3, 2026
0607227
fix: default ignoredSeed in the message store factory
diegolmello Jul 3, 2026
f05a225
fix: restore message-link jump in SearchMessagesView
diegolmello Jul 3, 2026
430d920
refactor: remove dead isBeingEdited and small props from Message
diegolmello Jul 3, 2026
2f00bd2
refactor: correct MessageRoomStore mirroring comment
diegolmello Jul 3, 2026
5ce3f4b
test: cover ignored-message reveal, interaction fallback, room-store …
diegolmello Jul 3, 2026
273326b
refactor: reorganize the message module into components, stores, test…
diegolmello Jul 3, 2026
b503abd
refactor: remove reducible props from message leaves (NATIVE-1394)
diegolmello Jul 3, 2026
5d687aa
refactor: carry the ignored seed in message context (NATIVE-1395)
diegolmello Jul 3, 2026
ff9f162
test: add snapshot-oracle stories for message leaves (NATIVE-1396)
diegolmello Jul 3, 2026
715c48a
test: add unit tests for logic-bearing message units (NATIVE-1397)
diegolmello Jul 3, 2026
7a058b1
refactor: tighten message module TypeScript types
diegolmello Jul 3, 2026
00e9bbe
refactor: replace useMessagePress hand-rolled debounce with useDebounce
diegolmello Jul 3, 2026
2a82113
refactor: mechanical convention cleanup in message module
diegolmello Jul 3, 2026
ec77896
refactor: decompose message Content into per-branch leaves
diegolmello Jul 3, 2026
3aa1092
refactor: decompose message Message.tsx into per-branch renderers
diegolmello Jul 3, 2026
dbef733
feat: add useCustomEmoji hook and migrate Preview to it
diegolmello Jul 3, 2026
cfad92a
refactor: break Message/MessageInner import cycle and narrow author r…
diegolmello Jul 3, 2026
6be3190
refactor: retire ROOM_STATE_KEYS and pickMessageRoomState test picker
diegolmello Jul 3, 2026
a01f1f5
refactor: retire getCustomEmoji room-store field for useCustomEmoji hook
diegolmello Jul 3, 2026
4af3c80
refactor: remove dead getCustomEmoji methods from message list views
diegolmello Jul 3, 2026
49ecae7
refactor: add explicit deps to MessageStore mirror effect, document M…
diegolmello Jul 3, 2026
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
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
514c18d
refactor: dedup message component helpers (NATIVE-22)
diegolmello Jul 9, 2026
73004e8
docs: add Message component architecture reference (NATIVE-22)
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
7a1f61b
refactor: source author inside Attachments, drop CollapsibleQuote fra…
diegolmello Jul 13, 2026
cd5ea75
refactor: drop unnecessary user cast in RoomView MessageRoomProvider …
diegolmello Jul 13, 2026
f440691
Merge branch 'develop' into native-22-message-hooks
diegolmello Jul 13, 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: 7 additions & 1 deletion .rnstorybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,13 @@ const preview: Preview = {
onReactionPress: () => {},
onDiscussionPress: () => {},
onReactionLongPress: () => {},
threadBadgeColor: themes.light.badgeBackgroundLevel1
threadBadgeColor: themes.light.badgeBackgroundLevel1,
getCustomEmoji: () => null,
navToRoomInfo: () => {},
showAttachment: undefined,
blockAction: undefined,
handleEnterCall: undefined,
fetchThreadName: undefined
}}>
<Story />
</MessageContext.Provider>
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Rocket.Chat React Native mobile client. Single-package React Native app (not a m
- React 19.1, React Native 0.81, Expo 54
- TypeScript with strict mode, baseUrl set to `app/` (imports resolve from there)
- Node: engines `>=18`, volta pins 24.13.1
- Read UBIQUITOUS_LANGUAGE.md
- Read CONTEXT.md

## Commands

Expand Down
9 changes: 9 additions & 0 deletions UBIQUITOUS_LANGUAGE.md → CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@
| **Room History** | Older Messages of a Room fetched on demand from the server (distinct from **Server History**) | Message history |
| **Jump to Message** | Re-position the Room view onto a target Message that may be far from the Live Tail or not yet synced — fetches a surrounding Chunk | Scroll to message |

## Message Interaction & Position State

Two distinct kinds of transient per-Room state drive how the Room view renders Messages. They have different owners and are migrated independently, so keep them apart.

| Term | Definition | Owner | Scope |
| --------------------- | --------------------------------------------------------------------------------------- | ------------------------------ | -------------------------------------------------------------------- |
| **Interaction state** | Which Message is selected and the current Message action — reply, quote, edit, or react | A per-Room interaction store | Migrated to the per-Room store as part of the Message row work |
| **Positional state** | Which Message is highlighted and the jump or scroll position | The Room view scroll machinery | Stays with the Room view scroll machinery and is migrated separately |

## Users & Roles

| Term | Definition | Aliases to avoid |
Expand Down
50 changes: 33 additions & 17 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 } from '../../definitions';
import { colors } from '../../lib/constants/colors';
import { type IRoomContext, RoomContext } from '../../views/RoomView/context';
import { type IRoomContext, RoomContext, type TMessageAction } from '../../views/RoomView/context';
import { InteractionProvider } from '../../views/RoomView/InteractionStore';
import * as EmojiKeyboardHook from './hooks/useEmojiKeyboard';
import { initStore } from '../../lib/store/auxStore';
import { search } from '../../lib/methods/search';
Expand Down Expand Up @@ -109,24 +110,32 @@ const initialContext = {
federated: false
},
sharing: false,
action: null,
selectedMessages: [],
editCancel: jest.fn(),
editRequest: jest.fn(),
onSendMessage: jest.fn(),
onRemoveQuoteMessage: jest.fn()
};

const Render = ({ context, children }: { context?: Partial<IRoomContext>; children?: ReactElement }) => (
const Render = ({
context,
interactionState,
children
}: {
context?: Partial<IRoomContext>;
interactionState?: { action?: TMessageAction; selectedMessages?: string[] };
children?: ReactElement;
}) => (
<Provider store={mockedStore}>
<RoomContext.Provider value={{ ...initialContext, ...context }}>
<MessageComposerContainer>
<>
<ComposerAttachments />
{children}
</>
</MessageComposerContainer>
</RoomContext.Provider>
<InteractionProvider initialState={interactionState}>
<RoomContext.Provider value={{ ...initialContext, ...context }}>
<MessageComposerContainer>
<>
<ComposerAttachments />
{children}
</>
</MessageComposerContainer>
</RoomContext.Provider>
</InteractionProvider>
</Provider>
);

Expand Down Expand Up @@ -638,7 +647,10 @@ describe('MessageComposer', () => {
const id = 'messageId';
beforeEach(() => {
return renderAndFlush(
<Render context={{ rid: 'rid', selectedMessages: [id], action: 'edit', onSendMessage, editCancel, editRequest }} />
<Render
context={{ rid: 'rid', onSendMessage, editCancel, editRequest }}
interactionState={{ action: 'edit', selectedMessages: [id] }}
/>
);
});
test('init', async () => {
Expand Down Expand Up @@ -670,7 +682,9 @@ describe('MessageComposer', () => {
const editRequest = jest.fn();
const id = 'image';
test('edit image', async () => {
await renderAndFlush(<Render context={{ rid: 'rid', selectedMessages: [id], action: 'edit', editRequest }} />);
await renderAndFlush(
<Render context={{ rid: 'rid', editRequest }} interactionState={{ action: 'edit', selectedMessages: [id] }} />
);
await screen.findByTestId('message-composer');
await user.press(screen.getByTestId('message-composer-send'));
expect(editRequest).toHaveBeenCalledWith({ id, msg: `Attachment description for ${id}`, rid: 'rid' });
Expand Down Expand Up @@ -702,14 +716,14 @@ describe('MessageComposer', () => {

describe('Quote', () => {
test('Add quote `abc`', async () => {
render(<Render context={{ action: 'quote', selectedMessages: ['abc'] }} />);
render(<Render interactionState={{ action: 'quote', selectedMessages: ['abc'] }} />);
await screen.findByTestId('composer-quote-abc');
expect(screen.queryByTestId('composer-quote-abc')).toBeOnTheScreen();
expect(screen.toJSON()).toMatchSnapshot();
});

test('Add quote `def`', async () => {
render(<Render context={{ action: 'quote', selectedMessages: ['abc', 'def'] }} />);
render(<Render interactionState={{ action: 'quote', selectedMessages: ['abc', 'def'] }} />);
await screen.findByTestId('composer-quote-abc');
expect(screen.queryByTestId('composer-quote-abc')).toBeOnTheScreen();
expect(screen.queryByTestId('composer-quote-def')).toBeOnTheScreen();
Expand All @@ -718,7 +732,9 @@ describe('MessageComposer', () => {

test('Remove a quote', async () => {
const onRemoveQuoteMessage = jest.fn();
render(<Render context={{ action: 'quote', selectedMessages: ['abc', 'def'], onRemoveQuoteMessage }} />);
render(
<Render context={{ onRemoveQuoteMessage }} interactionState={{ action: 'quote', selectedMessages: ['abc', 'def'] }} />
);
await screen.findByTestId('composer-quote-def');
await user.press(screen.getByTestId('composer-quote-remove-def'));
expect(onRemoveQuoteMessage).toHaveBeenCalledTimes(1);
Expand Down
5 changes: 4 additions & 1 deletion app/containers/MessageComposer/MessageComposer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Q } from '@nozbe/watermelondb';
import Animated, { useAnimatedStyle, useSharedValue } from 'react-native-reanimated';

import { useRoomContext } from '../../views/RoomView/context';
import { useMessageAction, useSelectedMessages } from '../../views/RoomView/InteractionStore';
import { Autocomplete } from './components';
import { MIN_HEIGHT } from './constants';
import {
Expand Down Expand Up @@ -54,7 +55,9 @@ export const MessageComposer = ({
});
const contentHeight = useSharedValue(MIN_HEIGHT);
useCloseKeyboardWhenOrientationChanges();
const { rid, tmid, action, selectedMessages, sharing, editRequest, onSendMessage, setQuotesAndText } = useRoomContext();
const { rid, tmid, sharing, editRequest, onSendMessage, setQuotesAndText } = useRoomContext();
const action = useMessageAction();
const selectedMessages = useSelectedMessages();
const alsoSendThreadToChannel = useAlsoSendThreadToChannel();
const { showEmojiKeyboard, showEmojiSearchbar, openEmojiSearchbar, resetKeyboard, keyboardHeight } = useEmojiKeyboard();
const { setAlsoSendThreadToChannel, setAutocompleteParams, clearAttachments } = useMessageComposerApi();
Expand Down
4 changes: 3 additions & 1 deletion app/containers/MessageComposer/components/CancelEdit.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { BaseButton } from './Buttons';
import { useRoomContext } from '../../../views/RoomView/context';
import { useMessageAction } from '../../../views/RoomView/InteractionStore';
import { Gap } from './Gap';

export const CancelEdit = () => {
'use memo';

const { action, editCancel } = useRoomContext();
const { editCancel } = useRoomContext();
const action = useMessageAction();

if (action !== 'edit') {
return null;
Expand Down
5 changes: 4 additions & 1 deletion app/containers/MessageComposer/components/ComposerInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import database from '../../../lib/database';
import Navigation from '../../../lib/navigation/appNavigation';
import { emitter } from '../../../lib/methods/helpers/emitter';
import { useRoomContext } from '../../../views/RoomView/context';
import { useMessageAction, useSelectedMessages } from '../../../views/RoomView/InteractionStore';
import { getMessageById } from '../../../lib/database/services/Message';
import { generateTriggerId } from '../../../lib/methods/actions';
import { executeCommandPreview } from '../../../lib/services/restApi';
Expand All @@ -50,7 +51,9 @@ const defaultSelection: IInputSelection = { start: 0, end: 0 };
export const ComposerInput = memo(
forwardRef<IComposerInput, IComposerInputProps>(({ inputRef }, ref) => {
const { colors, theme } = useTheme();
const { rid, tmid, sharing, action, selectedMessages, setQuotesAndText, room } = useRoomContext();
const { rid, tmid, sharing, setQuotesAndText, room } = useRoomContext();
const action = useMessageAction();
const selectedMessages = useSelectedMessages();
const focused = useFocused();
const { setFocused, setMicOrSend, setAutocompleteParams } = useMessageComposerApi();
const autocompleteType = useAutocompleteParams()?.type;
Expand Down
5 changes: 3 additions & 2 deletions app/containers/MessageComposer/components/Quotes/Quotes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import { useEffect, useRef, type ReactElement } from 'react';
import { FlatList } from 'react-native';

import { Quote } from './Quote';
import { useRoomContext } from '../../../../views/RoomView/context';
import { useMessageAction, useSelectedMessages } from '../../../../views/RoomView/InteractionStore';

export const Quotes = (): ReactElement | null => {
'use memo';

const { selectedMessages, action } = useRoomContext();
const selectedMessages = useSelectedMessages();
const action = useMessageAction();
const nQuotesRef = useRef(0);
const listRef = useRef<FlatList>(null);

Expand Down
5 changes: 4 additions & 1 deletion app/containers/MessageComposer/hooks/useAutoSaveDraft.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ import { useCallback, useEffect, useRef } from 'react';

import { saveDraftMessage } from '../../../lib/methods/draftMessage';
import { useRoomContext } from '../../../views/RoomView/context';
import { useMessageAction, useSelectedMessages } from '../../../views/RoomView/InteractionStore';
import { useFocused } from '../context';

export const useAutoSaveDraft = (text = '') => {
'use memo';

const route = useRoute();
const { rid, tmid, action, selectedMessages } = useRoomContext();
const { rid, tmid } = useRoomContext();
const action = useMessageAction();
const selectedMessages = useSelectedMessages();
const focused = useFocused();
const oldText = useRef('');
const intervalRef = useRef<number | null>(null);
Expand Down
11 changes: 9 additions & 2 deletions app/containers/MessageComposer/hooks/useChooseMedia.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ jest.mock('../../../views/RoomView/context', () => ({
useRoomContext: jest.fn()
}));

jest.mock('../../../views/RoomView/InteractionStore', () => ({
useMessageAction: jest.fn(),
useSelectedMessages: jest.fn()
}));

jest.mock('../../../lib/hooks/useAltTextSupported', () => ({
useAltTextSupported: jest.fn()
}));
Expand Down Expand Up @@ -46,6 +51,8 @@ const mockGetDocumentAsync = require('expo-document-picker').getDocumentAsync as
const mockUseAppSelector = require('../../../lib/hooks/useAppSelector').useAppSelector as jest.Mock;
const mockUseMessageComposerApi = require('../context').useMessageComposerApi as jest.Mock;
const mockUseRoomContext = require('../../../views/RoomView/context').useRoomContext as jest.Mock;
const mockUseMessageAction = require('../../../views/RoomView/InteractionStore').useMessageAction as jest.Mock;
const mockUseSelectedMessages = require('../../../views/RoomView/InteractionStore').useSelectedMessages as jest.Mock;
const mockUseAltTextSupported = require('../../../lib/hooks/useAltTextSupported').useAltTextSupported as jest.Mock;
const mockGetSubscriptionByRoomId = require('../../../lib/database/services/Subscription').getSubscriptionByRoomId as jest.Mock;
const mockGetThreadById = require('../../../lib/database/services/Thread').getThreadById as jest.Mock;
Expand All @@ -67,11 +74,11 @@ describe('useChooseMedia', () => {
);
mockUseMessageComposerApi.mockReturnValue({ addAttachments });
mockUseRoomContext.mockReturnValue({
action: null,
setQuotesAndText: jest.fn(),
selectedMessages: [],
getText: jest.fn(() => 'draft')
});
mockUseMessageAction.mockReturnValue(null);
mockUseSelectedMessages.mockReturnValue([]);
mockGetSubscriptionByRoomId.mockResolvedValue({ rid: 'room-id', t: 'c' });
mockGetThreadById.mockResolvedValue({ id: 'thread-id' });
});
Expand Down
5 changes: 4 additions & 1 deletion app/containers/MessageComposer/hooks/useChooseMedia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { getThreadById } from '../../../lib/database/services/Thread';
import Navigation from '../../../lib/navigation/appNavigation';
import { useAppSelector } from '../../../lib/hooks/useAppSelector';
import { useRoomContext } from '../../../views/RoomView/context';
import { useMessageAction, useSelectedMessages } from '../../../views/RoomView/InteractionStore';
import { type IShareAttachment } from '../../../definitions';
import ImagePicker, { type ImageOrVideo } from '../../../lib/methods/helpers/ImagePicker/ImagePicker';
import { useMessageComposerApi } from '../context';
Expand All @@ -31,7 +32,9 @@ export const useChooseMedia = ({

const { FileUpload_MediaTypeWhiteList, FileUpload_MaxFileSize } = useAppSelector(state => state.settings);
const { addAttachments } = useMessageComposerApi();
const { action, setQuotesAndText, selectedMessages, getText } = useRoomContext();
const { setQuotesAndText, getText } = useRoomContext();
const action = useMessageAction();
const selectedMessages = useSelectedMessages();
const altTextSupported = useAltTextSupported();
const allowList = FileUpload_MediaTypeWhiteList as string;
const maxFileSize = FileUpload_MaxFileSize as number;
Expand Down
2 changes: 1 addition & 1 deletion app/containers/ReactionsList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const useRoutes = (reactions: IReaction[] | undefined) => {
};
}

const sortedReactions = reactions?.sort((reaction1, reaction2) => reaction2.usernames.length - reaction1.usernames.length);
const sortedReactions = [...reactions].sort((reaction1, reaction2) => reaction2.usernames.length - reaction1.usernames.length);
const routes: IRoute[] = sortedReactions.map(reaction => ({
key: reaction.emoji,
title: reaction.emoji,
Expand Down
7 changes: 5 additions & 2 deletions app/containers/message/Blocks.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { createElement } from 'react';
import { createElement, useContext } from 'react';

import { messageBlockWithContext } from '../UIKit/MessageBlock';
import { type IMessageBlocks } from './interfaces';
import MessageContext from './Context';

const Blocks = ({ blocks, id: mid, rid, blockAction }: IMessageBlocks) => {
const Blocks = ({ blocks, id: mid, rid }: IMessageBlocks) => {
'use memo';

const { blockAction } = useContext(MessageContext);

if (blocks && blocks.length > 0) {
const appId = blocks[0]?.appId || '';
return createElement(
Expand Down
2 changes: 1 addition & 1 deletion app/containers/message/Broadcast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const Broadcast = memo(({ author, broadcast }: IMessageBroadcast) => {

const { user, replyBroadcast } = useContext(MessageContext);
const { theme } = useTheme();
const isOwn = author?._id === user.id;
const isOwn = author?._id === user?.id;

if (broadcast && !isOwn) {
return (
Expand Down
8 changes: 4 additions & 4 deletions app/containers/message/CallButton.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { memo } from 'react';
import { memo, useContext } from 'react';
import { Text, View } from 'react-native';

import Touchable from './Touchable';
Expand All @@ -7,13 +7,13 @@ import styles from './styles';
import I18n from '../../i18n';
import { CustomIcon } from '../CustomIcon';
import { themes } from '../../lib/constants/colors';
import { type IMessageCallButton } from './interfaces';
import { useTheme } from '../../theme';
import MessageContext from './Context';

// TODO: Create a reusable button component for message
const CallButton = memo(({ handleEnterCall }: IMessageCallButton) => {
const CallButton = memo(() => {
'use memo';

const { handleEnterCall } = useContext(MessageContext);
const { theme } = useTheme();
return (
<View style={styles.buttonContainer}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const AttachedActions = ({ attachment, getCustomEmoji }: { attachment: IAttachme
const attachedButtons = attachment.actions.map((element: TElement) => {
const onPress = () => {
if (element.msg) {
onAnswerButtonPress(element.msg);
onAnswerButtonPress?.(element.msg);
}

if (element.url) {
Expand Down
Loading
Loading