Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 5 additions & 5 deletions examples/SampleApp/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3327,7 +3327,7 @@ PODS:
- ReactCommon/turbomodule/core
- SocketRocket
- Yoga
- Teleport (0.5.4):
- Teleport (1.1.2):
- boost
- DoubleConversion
- fast_float
Expand All @@ -3354,9 +3354,9 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- SocketRocket
- Teleport/common (= 0.5.4)
- Teleport/common (= 1.1.2)
- Yoga
- Teleport/common (0.5.4):
- Teleport/common (1.1.2):
- boost
- DoubleConversion
- fast_float
Expand Down Expand Up @@ -3827,7 +3827,7 @@ SPEC CHECKSUMS:
RNGestureHandler: 6bc8f2f56c8a68f3380cd159f3a1ae06defcfabb
RNNotifee: 5e3b271e8ea7456a36eec994085543c9adca9168
RNReactNativeHapticFeedback: 5f1542065f0b24c9252bd8cf3e83bc9c548182e4
RNReanimated: 0e779d4d219b01331bf5ad620d30c5b993d18856
RNReanimated: a1e0ce339c1d8f9164b7499920d8787d6a7f7a23
RNScreens: e902eba58a27d3ad399a495d578e8aba3ea0f490
RNShare: c0f25f3d0ec275239c35cadbc98c94053118bee7
RNSVG: b1cb00d54dbc3066a3e98732e5418c8361335124
Expand All @@ -3836,7 +3836,7 @@ SPEC CHECKSUMS:
SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
stream-chat-react-native: d15df89b47c1a08bc7db90c316d34b8ac4e13900
Teleport: c5c5d9ac843d3024fd5776a7fcba22d37080f86b
Teleport: ed828b19e62ca8b9ec101d991bf0594b1c1c8812
Yoga: ff16d80456ce825ffc9400eeccc645a0dfcccdf5

PODFILE CHECKSUM: 4f662370295f8f9cee909f1a4c59a614999a209d
Expand Down
2 changes: 1 addition & 1 deletion examples/SampleApp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
"react-native-screens": "^4.24.0",
"react-native-share": "^12.0.11",
"react-native-svg": "^15.15.4",
"react-native-teleport": "^0.5.4",
"react-native-teleport": "^1.1.2",
"react-native-video": "^6.16.1",
"react-native-worklets": "^0.8.1",
"stream-chat-react-native": "link:../../package/native-package",
Expand Down
8 changes: 4 additions & 4 deletions examples/SampleApp/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7674,10 +7674,10 @@ react-native-svg@^15.15.4:
css-tree "^1.1.3"
warn-once "0.1.1"

react-native-teleport@^0.5.4:
version "0.5.4"
resolved "https://registry.yarnpkg.com/react-native-teleport/-/react-native-teleport-0.5.4.tgz#6af16e3984ee0fc002e5d6c6dae0ad40f22699c2"
integrity sha512-kiNbB27lJHAO7DdG7LlPi6DaFnYusVQV9rqp0q5WoRpnqKNckIvzXULox6QpZBstaTF/jkO+xmlkU+pnQqKSAQ==
react-native-teleport@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/react-native-teleport/-/react-native-teleport-1.1.2.tgz#23deea2a34f6b1bb378e0305d44deeb93d51d490"
integrity sha512-64dcEkxlVKzxIts2FAVhzI2tDExcD23T13c2yDC/E+1dA1vP9UlDwPYUEkHvnoTOFtMDGrKLH03RJahIWfQC1g==

react-native-url-polyfill@^2.0.0:
version "2.0.0"
Expand Down
3 changes: 3 additions & 0 deletions package/src/components/Channel/Channel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ export type ChannelPropsWithContext = Pick<ChannelContextValue, 'channel'> &
| 'markdownRules'
| 'messageActions'
| 'messageContentOrder'
| 'messageOverlayTargetId'
| 'messageTextNumberOfLines'
| 'messageSwipeToReplyHitSlop'
| 'myMessageTheme'
Expand Down Expand Up @@ -464,6 +465,7 @@ const ChannelWithContext = (props: PropsWithChildren<ChannelPropsWithContext>) =
'text',
'location',
],
messageOverlayTargetId,
messageInputFloating = false,
messageId,
messageSwipeToReplyHitSlop,
Expand Down Expand Up @@ -1665,6 +1667,7 @@ const ChannelWithContext = (props: PropsWithChildren<ChannelPropsWithContext>) =
markdownRules,
messageActions,
messageContentOrder,
messageOverlayTargetId,
messageSwipeToReplyHitSlop,
messageTextNumberOfLines,
myMessageTheme,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const useCreateMessagesContext = ({
markdownRules,
messageActions,
messageContentOrder,
messageOverlayTargetId,
messageSwipeToReplyHitSlop,
messageTextNumberOfLines,
myMessageTheme,
Expand Down Expand Up @@ -100,6 +101,7 @@ export const useCreateMessagesContext = ({
markdownRules,
messageActions,
messageContentOrder,
messageOverlayTargetId,
messageSwipeToReplyHitSlop,
messageTextNumberOfLines,
myMessageTheme,
Expand Down Expand Up @@ -127,6 +129,7 @@ export const useCreateMessagesContext = ({
initialScrollToFirstUnreadMessage,
markdownRulesLength,
messageContentOrderValue,
messageOverlayTargetId,
supportedReactionsLength,
myMessageTheme,
targetedMessage,
Expand Down
186 changes: 109 additions & 77 deletions package/src/components/Message/Message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import { useMessageActions } from './hooks/useMessageActions';
import { useMessageDeliveredData } from './hooks/useMessageDeliveryData';
import { useMessageReadData } from './hooks/useMessageReadData';
import { useProcessReactions } from './hooks/useProcessReactions';
import { DEFAULT_MESSAGE_OVERLAY_TARGET_ID } from './messageOverlayConstants';
import { MessageOverlayWrapper } from './MessageOverlayWrapper';
import { measureInWindow } from './utils/measureInWindow';
import { messageActions as defaultMessageActions } from './utils/messageActions';

Expand All @@ -36,7 +38,11 @@ import {
MessageComposerAPIContextValue,
useMessageComposerAPIContext,
} from '../../contexts/messageComposerContext/MessageComposerAPIContext';
import { MessageContextValue, MessageProvider } from '../../contexts/messageContext/MessageContext';
import {
MessageContextValue,
MessageOverlayRuntimeProvider,
MessageProvider,
} from '../../contexts/messageContext/MessageContext';
import { useMessageListItemContext } from '../../contexts/messageListItemContext/MessageListItemContext';
import {
MessagesContextValue,
Expand Down Expand Up @@ -207,6 +213,7 @@ export type MessagePropsWithContext = Pick<
| 'handleBlockUser'
| 'isAttachmentEqual'
| 'messageActions'
| 'messageOverlayTargetId'
| 'messageContentOrder'
| 'onLongPressMessage'
| 'onPressInMessage'
Expand Down Expand Up @@ -278,6 +285,7 @@ const MessageWithContext = (props: MessagePropsWithContext) => {
members,
message,
messageActions: messageActionsProp = defaultMessageActions,
messageOverlayTargetId = DEFAULT_MESSAGE_OVERLAY_TARGET_ID,
messageContentOrder: messageContentOrderProp,
messagesContext,
onLongPressMessage: onLongPressMessageProp,
Expand Down Expand Up @@ -323,11 +331,28 @@ const MessageWithContext = (props: MessagePropsWithContext) => {
const rectRef = useRef<Rect>(undefined);
const bubbleRect = useRef<Rect>(undefined);
const contextMenuAnchorRef = useRef<View>(null);
const messageOverlayTargetsRef = useRef<Record<string, View | null>>({});
const registerMessageOverlayTarget = useStableCallback(
({ id, view }: { id: string; view: View | null }) => {
messageOverlayTargetsRef.current[id] = view;
},
);
const unregisterMessageOverlayTarget = useStableCallback((id: string) => {
delete messageOverlayTargetsRef.current[id];
});

const showMessageOverlay = useStableCallback(async () => {
dismissKeyboard();
try {
const layout = await measureInWindow(messageWrapperRef, insets);
const activeTargetView = messageOverlayTargetsRef.current[messageOverlayTargetId];

if (!activeTargetView) {
throw new Error(
`No message overlay target is registered for target id "${messageOverlayTargetId}".`,
);
}

const layout = await measureInWindow({ current: activeTargetView }, insets);
const bubbleLayout = await measureInWindow(contextMenuAnchorRef, insets).catch(() => layout);

rectRef.current = layout;
Expand Down Expand Up @@ -655,8 +680,6 @@ const MessageWithContext = (props: MessagePropsWithContext) => {
unpinMessage: handleTogglePinMessage,
};

const messageWrapperRef = useRef<View>(null);

const onLongPress = () => {
setNativeScrollability(false);
if (hasAttachmentActions || isBlockedMessage(message) || !enableLongPress) {
Expand Down Expand Up @@ -771,6 +794,8 @@ const MessageWithContext = (props: MessagePropsWithContext) => {
onThreadSelect,
otherAttachments: attachments.other,
preventPress: overlayActive ? true : preventPress,
registerMessageOverlayTarget,
unregisterMessageOverlayTarget,
reactions,
readBy,
setQuotedMessage,
Expand All @@ -781,6 +806,14 @@ const MessageWithContext = (props: MessagePropsWithContext) => {
threadList,
videos: attachments.videos,
});
const messageOverlayRuntimeContext = useMemo(
() => ({
overlayTargetRectRef: rectRef,
messageOverlayTargetId,
overlayActive,
}),
[messageOverlayTargetId, overlayActive],
);

const prevActive = useRef<boolean>(overlayActive);

Expand Down Expand Up @@ -817,82 +850,74 @@ const MessageWithContext = (props: MessagePropsWithContext) => {

return (
<MessageProvider value={messageContext}>
<View style={[style, styles.wrapper]} testID='message-wrapper'>
{overlayActive && rect ? (
<View
style={{
height: rect.h,
width: rect.w,
}}
/>
) : null}
{/*TODO: V9: Find a way to separate these in a dedicated file*/}
<Portal hostName={overlayActive && rect ? 'top-item' : undefined}>
{overlayActive && rect && overlayItemsAnchorRect ? (
<View
onLayout={(e) => {
const { width: w, height: h } = e.nativeEvent.layout;

setOverlayTopH({
h,
w,
x:
overlayItemAlignment === 'right'
? overlayItemsAnchorRect.x + overlayItemsAnchorRect.w - w
: overlayItemsAnchorRect.x,
y: rect.y - h,
});
}}
>
<MessageReactionPicker
dismissOverlay={dismissOverlay}
handleReaction={ownCapabilities.sendReaction ? handleReaction : undefined}
/>
</View>
) : null}
</Portal>
<Portal
hostName={overlayActive ? 'message-overlay' : undefined}
style={overlayActive && rect ? { width: rect.w } : undefined}
>
<View ref={messageWrapperRef}>
<MessageOverlayRuntimeProvider value={messageOverlayRuntimeContext}>
<View style={[style, styles.wrapper]} testID='message-wrapper'>
{/*TODO: V9: Find a way to separate these in a dedicated file*/}
<Portal hostName={overlayActive && rect ? 'top-item' : undefined}>
{overlayActive && rect && overlayItemsAnchorRect ? (
<View
onLayout={(e) => {
const { width: w, height: h } = e.nativeEvent.layout;

setOverlayTopH({
h,
w,
x:
overlayItemAlignment === 'right'
? overlayItemsAnchorRect.x + overlayItemsAnchorRect.w - w
: overlayItemsAnchorRect.x,
y: rect.y - h,
});
}}
>
<MessageReactionPicker
dismissOverlay={dismissOverlay}
handleReaction={ownCapabilities.sendReaction ? handleReaction : undefined}
/>
</View>
) : null}
</Portal>
<MessageOverlayWrapper targetId={DEFAULT_MESSAGE_OVERLAY_TARGET_ID}>
<MessageItemView />
</View>
</Portal>
{showMessageReactions ? (
<BottomSheetModal
lazy={true}
onClose={() => setShowMessageReactions(false)}
visible={showMessageReactions}
height={424}
>
<MessageUserReactions message={message} selectedReaction={selectedReaction} />
</BottomSheetModal>
) : null}
<Portal hostName={overlayActive && rect ? 'bottom-item' : undefined}>
{overlayActive && rect && overlayItemsAnchorRect ? (
<View
onLayout={(e) => {
const { width: w, height: h } = e.nativeEvent.layout;
setOverlayBottomH({
h,
w,
x:
overlayItemAlignment === 'right'
? overlayItemsAnchorRect.x + overlayItemsAnchorRect.w - w
: overlayItemsAnchorRect.x,
y: rect.y + rect.h,
});
}}
</MessageOverlayWrapper>
{showMessageReactions ? (
<BottomSheetModal
lazy={true}
onClose={() => setShowMessageReactions(false)}
visible={showMessageReactions}
height={424}
>
<MessageActionList dismissOverlay={dismissOverlay} messageActions={messageActions} />
</View>
<MessageUserReactions message={message} selectedReaction={selectedReaction} />
</BottomSheetModal>
) : null}
</Portal>
{isBounceDialogOpen ? (
<MessageBounce setIsBounceDialogOpen={setIsBounceDialogOpen} />
) : null}
</View>
<Portal hostName={overlayActive && rect ? 'bottom-item' : undefined}>
{overlayActive && rect && overlayItemsAnchorRect ? (
<View
onLayout={(e) => {
const { width: w, height: h } = e.nativeEvent.layout;
setOverlayBottomH({
h,
w,
x:
overlayItemAlignment === 'right'
? overlayItemsAnchorRect.x + overlayItemsAnchorRect.w - w
: overlayItemsAnchorRect.x,
y: rect.y + rect.h,
});
}}
>
<MessageActionList
dismissOverlay={dismissOverlay}
messageActions={messageActions}
/>
</View>
) : null}
</Portal>
{isBounceDialogOpen ? (
<MessageBounce setIsBounceDialogOpen={setIsBounceDialogOpen} />
) : null}
</View>
</MessageOverlayRuntimeProvider>
</MessageProvider>
);
};
Expand All @@ -905,6 +930,7 @@ const areEqual = (prevProps: MessagePropsWithContext, nextProps: MessagePropsWit
groupStyles: prevGroupStyles,
isAttachmentEqual,
isTargetedMessage: prevIsTargetedMessage,
messageOverlayTargetId: prevMessageOverlayTargetId,
members: prevMembers,
message: prevMessage,
messagesContext: prevMessagesContext,
Expand All @@ -918,6 +944,7 @@ const areEqual = (prevProps: MessagePropsWithContext, nextProps: MessagePropsWit
goToMessage: nextGoToMessage,
groupStyles: nextGroupStyles,
isTargetedMessage: nextIsTargetedMessage,
messageOverlayTargetId: nextMessageOverlayTargetId,
members: nextMembers,
message: nextMessage,
messagesContext: nextMessagesContext,
Expand Down Expand Up @@ -958,6 +985,11 @@ const areEqual = (prevProps: MessagePropsWithContext, nextProps: MessagePropsWit
return false;
}

const messageOverlayTargetIdEqual = prevMessageOverlayTargetId === nextMessageOverlayTargetId;
if (!messageOverlayTargetIdEqual) {
return false;
}

const messageEqual = checkMessageEquality(prevMessage, nextMessage);

if (!messageEqual) {
Expand Down
Loading
Loading