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
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ export { default as useSendbirdStateContext } from './hooks/useSendbirdStateCont

// Public enum included in AppProps
export { TypingIndicatorType } from './types';

export { getIsByMe } from "./utils/messages";
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ export const getMessagePartsInfo = ({
currentMessage = null,
currentChannel = null,
replyType = '',
}: GetMessagePartsInfoProps): OutPuts => {
currentUserId
}: GetMessagePartsInfoProps & { currentUserId?: string }): OutPuts => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

currentUserId will be undefined by default anyway right? Any reason to explicitly given it a default of undefined here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah no ur right, I had previously had it as null and refactored it to undefined

const previousMessage = allMessages[currentIndex - 1];
const nextMessage = allMessages[currentIndex + 1];
const [chainTop, chainBottom] = isMessageGroupingEnabled
? compareMessagesForGrouping(previousMessage, currentMessage, nextMessage, currentChannel, (replyType as ReplyType))
? compareMessagesForGrouping(previousMessage, currentMessage, nextMessage, currentChannel, (replyType as ReplyType), currentUserId)
: [false, false];
const previousMessageCreatedAt = previousMessage?.createdAt;
const currentCreatedAt = currentMessage.createdAt;
Expand Down
1 change: 1 addition & 0 deletions src/modules/GroupChannel/components/MessageList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ export const MessageList = ({
currentIndex: idx,
currentMessage: message as CoreMessageType,
currentChannel,
currentUserId: store.config.userId
});
const isOutgoingMessage = isSendableMessage(message) && message.sender.userId === store.config.userId;
return (
Expand Down
6 changes: 3 additions & 3 deletions src/ui/MessageContent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import MessageFeedbackModal from '../MessageFeedbackModal';
import { SbFeedbackStatus } from './types';
import MessageFeedbackFailedModal from '../MessageFeedbackFailedModal';
import { MobileBottomSheetProps } from '../MobileMenu/types';
import { getIsByMe } from '../../utils/messages';

export interface MessageContentProps {
className?: string | Array<string>;
Expand Down Expand Up @@ -162,9 +163,8 @@ export default function MessageContent(props: MessageContentProps): ReactElement

const { stringSet } = useContext(LocalizationContext);

const isByMe = (userId === (message as SendableMessageType)?.sender?.userId)
|| ((message as SendableMessageType)?.sendingStatus === 'pending')
|| ((message as SendableMessageType)?.sendingStatus === 'failed');

const isByMe = getIsByMe(userId, message);
const isByMeClassName = isByMe ? 'outgoing' : 'incoming';
const chainTopClassName = chainTop ? 'chain-top' : '';
const isReactionEnabledInChannel = isReactionEnabled && !channel?.isEphemeral;
Expand Down
51 changes: 37 additions & 14 deletions src/utils/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import format from 'date-fns/format';

import { ReplyType } from '../types';
import type { CoreMessageType } from '.';
import { isReadMessage } from '.';
import { isReadMessage, isSendableMessage } from '.';

/**
* exported, should be backward compatible
Expand All @@ -16,6 +16,7 @@ export const compareMessagesForGrouping = (
nextMessage: CoreMessageType,
currentChannel?: GroupChannel,
replyType?: ReplyType,
currentUserId?: string,
) => {
if (!currentChannel || (currentChannel as GroupChannel).channelType !== 'group') {
return [
Expand All @@ -30,18 +31,43 @@ export const compareMessagesForGrouping = (
const sendingStatus = (currMessage as UserMessage)?.sendingStatus || '';
const isAcceptable = sendingStatus !== 'failed';
return [
isSameGroup(prevMessage, currMessage, currentChannel) && isAcceptable,
isSameGroup(currMessage, nextMessage, currentChannel) && isAcceptable,
isSameGroup(prevMessage, currMessage, currentUserId) && isAcceptable,
isSameGroup(currMessage, nextMessage, currentUserId) && isAcceptable,
];
};

export const getMessageCreatedAt = (message: BaseMessage) => format(message.createdAt, 'p');

// Group current user's messages together. The current user's messages
// may not have their userId on it, and if not, we assume that messages w/ a
// local send status is the current user's as well.
// Given the above is true, group by timestamp
export const areBothFromMyUserAndInSameGroup = (
message: CoreMessageType,
comparingMessage: CoreMessageType,
currentUserId?: string
) => {
if (!currentUserId || !message.createdAt || !comparingMessage.createdAt) return false;

const isFirstMessageByMe = getIsByMe(currentUserId, message);
const isSecondMessageByMe = getIsByMe(currentUserId, comparingMessage);

if (isFirstMessageByMe && isSecondMessageByMe) {
return getMessageCreatedAt(message) === getMessageCreatedAt(comparingMessage);
}

return false;
}

export const isSameGroup = (
message: CoreMessageType,
comparingMessage: CoreMessageType,
currentChannel?: GroupChannel,
currentUserId?: string

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was the group being used for before?

Copy link
Collaborator Author

@awlui awlui May 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was used previously to determine grouping by read status, which we removed cause it was buggy on some clients(jinen's) and we weren't using read status anyways.
https://github.com/sendbird/sendbird-uikit-react/blob/main/src/utils/messages.ts

The usage was removed but the parameter got left in

) => {
if (areBothFromMyUserAndInSameGroup(message, comparingMessage, currentUserId)) {
return true;
}

if (
!(
message
Expand All @@ -61,23 +87,20 @@ export const isSameGroup = (
return false;
}

// group pending messages with any message type other than failed
// Given the above is true, group by timestamp and sender id
if ([message.sendingStatus, comparingMessage.sendingStatus].includes(SendingStatus.PENDING) &&
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this fixed a different bug, but will be obsolete/unnecessary with the new fix.

![message.sendingStatus, comparingMessage.sendingStatus].includes(SendingStatus.FAILED)) {
return (
message?.sender?.userId === comparingMessage?.sender?.userId
&& getMessageCreatedAt(message) === getMessageCreatedAt(comparingMessage)
);
}

return (
message?.sendingStatus === comparingMessage?.sendingStatus
&& message?.sender?.userId === comparingMessage?.sender?.userId
&& getMessageCreatedAt(message) === getMessageCreatedAt(comparingMessage)
);
};

export const getIsByMe = (userId: string, message: BaseMessage) => {
if (!isSendableMessage(message) || !userId) return false;
const messageIsLocalType = [SendingStatus.FAILED, SendingStatus.PENDING].includes(message.sendingStatus);

return userId === message.sender.userId || messageIsLocalType;
}

export default {
compareMessagesForGrouping,
getMessageCreatedAt,
Expand Down