Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
23 changes: 1 addition & 22 deletions .rnstorybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import React from 'react';
import type { Preview } from '@storybook/react';
import { Provider } from 'react-redux';

import { themes } from '../app/lib/constants/colors';
import MessageContext from '../app/containers/message/Context';
import { selectServerRequest } from '../app/actions/server';
import { mockedStore as store } from '../app/reducers/mockedStore';
import { setUser } from '../app/actions/login';
Expand All @@ -19,26 +17,7 @@ const preview: Preview = {
decorators: [
Story => (
<Provider store={store}>
<MessageContext.Provider
value={{
user: {
id: 'y8bd77ptZswPj3EW8',
username: 'diego.mello',
token: 'abc'
},
baseUrl,
onPress: () => {},
onLongPress: () => {},
reactionInit: () => {},
onErrorPress: () => {},
replyBroadcast: () => {},
onReactionPress: () => {},
onDiscussionPress: () => {},
onReactionLongPress: () => {},
threadBadgeColor: themes.light.badgeBackgroundLevel1
}}>
<Story />
</MessageContext.Provider>
<Story />
</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
139 changes: 110 additions & 29 deletions UBIQUITOUS_LANGUAGE.md → CONTEXT.md

Large diffs are not rendered by default.

43 changes: 26 additions & 17 deletions app/containers/MessageComposer/MessageComposer.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import { selectServerRequest } from '../../actions/server';
import { setUser } from '../../actions/login';
import { mockedStore } from '../../reducers/mockedStore';
import { type IPermissionsState } from '../../reducers/permissions';
import { type IMessage, type IShareAttachment } from '../../definitions';
import { type IMessage, type IShareAttachment, type TMessageActionState } from '../../definitions';
import { colors } from '../../lib/constants/colors';
import { type IRoomContext, RoomContext } from '../../views/RoomView/context';
import { MessageActionProvider } from '../message/stores/MessageActionStore';
import * as EmojiKeyboardHook from './hooks/useEmojiKeyboard';
import { initStore } from '../../lib/store/auxStore';
import { searchRemote } from '../../lib/methods/search';
Expand Down Expand Up @@ -110,24 +111,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,
action,
children
}: {
context?: Partial<IRoomContext>;
action?: TMessageActionState;
children?: ReactElement;
}) => (
<Provider store={mockedStore}>
<RoomContext.Provider value={{ ...initialContext, ...context }}>
<MessageComposerContainer>
<>
<ComposerAttachments />
{children}
</>
</MessageComposerContainer>
</RoomContext.Provider>
<MessageActionProvider initialAction={action}>
<RoomContext.Provider value={{ ...initialContext, ...context }}>
<MessageComposerContainer>
<>
<ComposerAttachments />
{children}
</>
</MessageComposerContainer>
</RoomContext.Provider>
</MessageActionProvider>
</Provider>
);

Expand Down Expand Up @@ -639,7 +648,7 @@ 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 }} action={{ kind: 'edit', messageId: id }} />
);
});
test('init', async () => {
Expand Down Expand Up @@ -671,7 +680,7 @@ 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 }} action={{ kind: 'edit', messageId: 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 @@ -703,14 +712,14 @@ describe('MessageComposer', () => {

describe('Quote', () => {
test('Add quote `abc`', async () => {
render(<Render context={{ action: 'quote', selectedMessages: ['abc'] }} />);
render(<Render action={{ kind: 'quote', messageIds: ['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 action={{ kind: 'quote', messageIds: ['abc', 'def'] }} />);
await screen.findByTestId('composer-quote-abc');
expect(screen.queryByTestId('composer-quote-abc')).toBeOnTheScreen();
expect(screen.queryByTestId('composer-quote-def')).toBeOnTheScreen();
Expand All @@ -719,7 +728,7 @@ describe('MessageComposer', () => {

test('Remove a quote', async () => {
const onRemoveQuoteMessage = jest.fn();
render(<Render context={{ action: 'quote', selectedMessages: ['abc', 'def'], onRemoveQuoteMessage }} />);
render(<Render context={{ onRemoveQuoteMessage }} action={{ kind: 'quote', messageIds: ['abc', 'def'] }} />);
await screen.findByTestId('composer-quote-def');
await user.press(screen.getByTestId('composer-quote-remove-def'));
expect(onRemoveQuoteMessage).toHaveBeenCalledTimes(1);
Expand Down
18 changes: 10 additions & 8 deletions 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 } from '../message/stores/MessageActionStore';
import { Autocomplete } from './components';
import { MIN_HEIGHT } from './constants';
import {
Expand Down Expand Up @@ -54,7 +55,8 @@ 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 alsoSendThreadToChannel = useAlsoSendThreadToChannel();
const { showEmojiKeyboard, showEmojiSearchbar, openEmojiSearchbar, resetKeyboard, keyboardHeight } = useEmojiKeyboard();
const { setAlsoSendThreadToChannel, setAutocompleteParams, clearAttachments } = useMessageComposerApi();
Expand Down Expand Up @@ -108,22 +110,22 @@ export const MessageComposer = ({

const textFromInput = composerInputComponentRef.current.getTextAndClear();

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

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

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

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

if (action === 'quote') {
const quoteMessage = await prepareQuoteMessage(textFromInput, selectedMessages);
if (action?.kind === 'quote') {
const quoteMessage = await prepareQuoteMessage(textFromInput, action.messageIds);
onSendMessage?.(quoteMessage);
return;
}
Expand Down Expand Up @@ -245,7 +247,7 @@ export const MessageComposer = ({
}}>
<MessageComposerContent
recordingAudio={recordingAudio}
action={action}
action={action?.kind ?? null}
showEmojiSearchbar={showEmojiSearchbar}
composerInputComponentRef={composerInputComponentRef}
composerInputRef={composerInputRef}
Expand Down
6 changes: 4 additions & 2 deletions app/containers/MessageComposer/components/CancelEdit.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { BaseButton } from './Buttons';
import { useRoomContext } from '../../../views/RoomView/context';
import { useMessageAction } from '../../message/stores/MessageActionStore';
import { Gap } from './Gap';

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

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

if (action !== 'edit') {
if (action?.kind !== 'edit') {
return null;
}
return (
Expand Down
22 changes: 12 additions & 10 deletions 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 } from '../../message/stores/MessageActionStore';
import { getMessageById } from '../../../lib/database/services/Message';
import { generateTriggerId } from '../../../lib/methods/actions';
import { executeCommandPreview } from '../../../lib/services/restApi';
Expand All @@ -50,7 +51,8 @@ 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 focused = useFocused();
const { setFocused, setMicOrSend, setAutocompleteParams } = useMessageComposerApi();
const autocompleteType = useAutocompleteParams()?.type;
Expand Down Expand Up @@ -92,38 +94,38 @@ export const ComposerInput = memo(
}
};

if (action !== 'edit' && firstRender.current) {
if (action?.kind !== 'edit' && firstRender.current) {
firstRender.current = false;
setDraftMessage();
}
if (sharing) return;
if (usedCannedResponse) setInput(usedCannedResponse);
}, [action, rid, tmid, usedCannedResponse]);
}, [action?.kind, rid, tmid, usedCannedResponse]);

// Edit/quote
useEffect(() => {
const fetchMessageAndSetInput = async () => {
const message = await getMessageById(selectedMessages[0]);
const fetchMessageAndSetInput = async (messageId: string) => {
const message = await getMessageById(messageId);
if (message) {
setInput(message?.msg || (altTextSupported ? '' : message?.attachments?.[0]?.description || ''));
}
};

if (sharing) return;

if (prevAction === 'edit' && action !== 'edit') {
if (prevAction?.kind === 'edit' && action?.kind !== 'edit') {
setInput('');
return;
}
if (action === 'edit' && selectedMessages[0]) {
if (action?.kind === 'edit') {
focus();
fetchMessageAndSetInput();
fetchMessageAndSetInput(action.messageId);
return;
}
if (action === 'quote' && selectedMessages.length) {
if (action?.kind === 'quote' && action.messageIds.length) {
focus();
}
}, [action, selectedMessages]);
}, [action]);

useFocusEffect(
useCallback(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { memo, type ReactElement, type RefObject } from 'react';
import { type LayoutChangeEvent, StyleSheet, View } from 'react-native';

import { type TMessageAction } from '../../../views/RoomView/context';
import { type TMessageAction } from '../../../definitions';
import { type IComposerInput } from '../interfaces';
import { useTheme } from '../../../theme';
import { RecordAudio } from './RecordAudio';
Expand Down
7 changes: 4 additions & 3 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 } from '../../../message/stores/MessageActionStore';

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

const { selectedMessages, action } = useRoomContext();
const action = useMessageAction();
const selectedMessages = action?.kind === 'quote' ? action.messageIds : [];
const nQuotesRef = useRef(0);
const listRef = useRef<FlatList>(null);

Expand All @@ -20,7 +21,7 @@ export const Quotes = (): ReactElement | null => {
nQuotesRef.current = selectedMessages.length;
}, [selectedMessages.length]);

if (action !== 'quote') {
if (action?.kind !== 'quote') {
return null;
}

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

import { saveDraftMessage } from '../../../lib/methods/draftMessage';
import { useRoomContext } from '../../../views/RoomView/context';
import { useMessageAction } from '../../message/stores/MessageActionStore';
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 focused = useFocused();
const oldText = useRef('');
const intervalRef = useRef<number | null>(null);
Expand All @@ -19,11 +21,13 @@ export const useAutoSaveDraft = (text = '') => {
const saveMessageDraft = useCallback(
(m?: string) => {
if (route.name === 'ShareView') return;
if (action === 'edit') return;
if (action?.kind === 'edit') return;

let draftMessage = '';
if (selectedMessages?.length) {
draftMessage = JSON.stringify({ quotes: selectedMessages, msg: text });
if (action?.kind === 'quote') {
draftMessage = JSON.stringify({ quotes: action.messageIds, msg: text });
} else if (action?.kind === 'react') {
draftMessage = JSON.stringify({ quotes: [action.messageId], msg: text });
} else {
draftMessage = m ?? text;
}
Expand All @@ -32,7 +36,7 @@ export const useAutoSaveDraft = (text = '') => {
saveDraftMessage({ rid, tmid, draftMessage });
}
},
[action, rid, tmid, text, selectedMessages, route.name]
[action, rid, tmid, text, route.name]
);

// if focused on composer input, saves every N seconds
Expand Down
Loading
Loading