Skip to content

Commit 206431a

Browse files
committed
chore: enhance unread message handling in GroupChannelMessageList
1 parent 8277ba3 commit 206431a

File tree

3 files changed

+50
-43
lines changed

3 files changed

+50
-43
lines changed

packages/uikit-react-native/src/domain/groupChannel/component/GroupChannelMessageList.tsx

Lines changed: 39 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { ViewToken } from '@react-native/virtualized-lists';
2-
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
2+
import React, { useCallback, useContext, useEffect, useRef, useState } from 'react';
33

44
import { useToast } from '@sendbird/uikit-react-native-foundation';
55
import { useGroupChannelHandler } from '@sendbird/uikit-tools';
@@ -32,10 +32,19 @@ const GroupChannelMessageList = (props: GroupChannelProps['MessageList']) => {
3232

3333
const isFirstMount = useIsFirstMount();
3434

35-
const { hasSeenNewLineRef, isNewLineInViewportRef, updateHasSeenNewLine, updateIsNewLineInViewport } =
36-
useNewLineTracker({
37-
onNewLineSeenChange: props.onNewLineSeenChange,
38-
});
35+
const hasSeenNewLineRef = useRef(false);
36+
const isNewLineInViewportRef = useRef(false);
37+
const [isVisibleUnreadMessageFloating, setIsVisibleUnreadMessageFloating] = useState(false);
38+
39+
const updateHasSeenNewLine = useCallback(
40+
(hasSeenNewLine: boolean) => {
41+
if (hasSeenNewLineRef.current !== hasSeenNewLine) {
42+
hasSeenNewLineRef.current = hasSeenNewLine;
43+
props.onNewLineSeenChange?.(hasSeenNewLine);
44+
}
45+
},
46+
[props.onNewLineSeenChange],
47+
);
3948

4049
const viewableMessages = useRef<SendbirdMessage[]>();
4150
const hasUserMarkedAsUnreadRef = useRef(false);
@@ -135,11 +144,16 @@ const GroupChannelMessageList = (props: GroupChannelProps['MessageList']) => {
135144
);
136145

137146
if (isNewLineInViewportRef.current !== isNewLineInViewport) {
138-
updateIsNewLineInViewport(isNewLineInViewport);
139-
if (!isNewLineInViewport || hasSeenNewLineRef.current) return;
147+
isNewLineInViewportRef.current = isNewLineInViewport;
148+
updateUnreadMessagesFloatingProps();
149+
if (!isNewLineInViewport || hasSeenNewLineRef.current) {
150+
return;
151+
}
140152

141153
updateHasSeenNewLine(true);
142-
if (hasUserMarkedAsUnreadRef.current) return;
154+
if (hasUserMarkedAsUnreadRef.current) {
155+
return;
156+
}
143157

144158
if (0 < props.newMessages.length) {
145159
props.channel.markAsUnread(props.newMessages[0]);
@@ -170,20 +184,25 @@ const GroupChannelMessageList = (props: GroupChannelProps['MessageList']) => {
170184
[sbOptions.uikit.groupChannel.channel.enableMarkAsUnread, updateHasUserMarkedAsUnread],
171185
);
172186

173-
const unreadMessagesFloatingProps: UnreadMessagesFloatingProps = useMemo(() => {
174-
return {
187+
const unreadMessagesFloatingPropsRef = useRef<UnreadMessagesFloatingProps>();
188+
const updateUnreadMessagesFloatingProps = useFreshCallback(() => {
189+
unreadMessagesFloatingPropsRef.current = {
175190
visible:
176191
sbOptions.uikit.groupChannel.channel.enableMarkAsUnread &&
192+
!!props.isNewLineExistInChannel &&
177193
0 < props.channel.unreadMessageCount &&
178194
!isNewLineInViewportRef.current,
179195
onPressClose: onPressUnreadMessagesFloatingCloseButton,
180196
unreadMessageCount: props.channel.unreadMessageCount,
181197
};
182-
}, [
183-
isNewLineInViewportRef.current,
184-
props.channel.unreadMessageCount,
185-
sbOptions.uikit.groupChannel.channel.enableMarkAsUnread,
186-
]);
198+
if (isVisibleUnreadMessageFloating !== unreadMessagesFloatingPropsRef.current.visible) {
199+
setIsVisibleUnreadMessageFloating(unreadMessagesFloatingPropsRef.current.visible);
200+
}
201+
});
202+
203+
useEffect(() => {
204+
updateUnreadMessagesFloatingProps();
205+
}, [props.isNewLineExistInChannel, sbOptions.uikit.groupChannel.channel.enableMarkAsUnread]);
187206

188207
useGroupChannelHandler(sdk, {
189208
onReactionUpdated(channel, event) {
@@ -231,6 +250,10 @@ const GroupChannelMessageList = (props: GroupChannelProps['MessageList']) => {
231250
scrollToBottom(false);
232251
break;
233252
}
253+
case 'ON_MARKED_AS_READ_BY_CURRENT_USER': {
254+
updateUnreadMessagesFloatingProps();
255+
break;
256+
}
234257
case 'ON_MARKED_AS_UNREAD_BY_CURRENT_USER': {
235258
const foundUnreadFirstMessage = findUnreadFirstMessage(true);
236259
processNewLineVisibility(foundUnreadFirstMessage);
@@ -293,34 +316,9 @@ const GroupChannelMessageList = (props: GroupChannelProps['MessageList']) => {
293316
onPressScrollToBottomButton={scrollToBottom}
294317
onPressMarkAsUnreadMessage={onPressMarkAsUnreadMessage}
295318
unreadFirstMessage={unreadFirstMessage}
296-
unreadMessagesFloatingProps={unreadMessagesFloatingProps}
319+
unreadMessagesFloatingProps={unreadMessagesFloatingPropsRef.current}
297320
/>
298321
);
299322
};
300323

301-
const useNewLineTracker = (params: Pick<GroupChannelProps['MessageList'], 'onNewLineSeenChange'>) => {
302-
const hasSeenNewLineRef = useRef(false);
303-
const isNewLineInViewportRef = useRef(false);
304-
305-
const updateHasSeenNewLine = useCallback(
306-
(hasSeenNewLine: boolean) => {
307-
if (hasSeenNewLineRef.current !== hasSeenNewLine) {
308-
hasSeenNewLineRef.current = hasSeenNewLine;
309-
params.onNewLineSeenChange?.(hasSeenNewLine);
310-
}
311-
},
312-
[params.onNewLineSeenChange],
313-
);
314-
315-
const updateIsNewLineInViewport = useCallback((isNewLineInViewport: boolean) => {
316-
isNewLineInViewportRef.current = isNewLineInViewport;
317-
}, []);
318-
319-
return {
320-
hasSeenNewLineRef,
321-
isNewLineInViewportRef,
322-
updateHasSeenNewLine,
323-
updateIsNewLineInViewport,
324-
};
325-
};
326324
export default React.memo(GroupChannelMessageList);

packages/uikit-react-native/src/domain/groupChannel/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,10 @@ export type GroupChannelPubSubContextPayload =
216216
type: 'TYPING_BUBBLE_RENDERED';
217217
data?: undefined;
218218
}
219+
| {
220+
type: 'ON_MARKED_AS_READ_BY_CURRENT_USER';
221+
data?: undefined;
222+
}
219223
| {
220224
type: 'ON_MARKED_AS_UNREAD_BY_CURRENT_USER';
221225
data?: undefined;

packages/uikit-react-native/src/fragments/createGroupChannelFragment.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ const createGroupChannelFragment = (initModule?: Partial<GroupChannelModule>): G
9999
useEffect(() => {
100100
isNewLineExistInChannelRef.current =
101101
channel.myLastRead < (channel.lastMessage?.createdAt ?? Number.MIN_SAFE_INTEGER);
102-
}, [channel]);
102+
}, [channel.url]);
103103

104104
const onNewLineSeenChange = useFreshCallback((hasSeenNewLine: boolean) => {
105105
hasSeenNewLineRef.current = hasSeenNewLine;
@@ -148,8 +148,13 @@ const createGroupChannelFragment = (initModule?: Partial<GroupChannelModule>): G
148148
groupChannelPubSub.publish({ type: 'MESSAGES_UPDATED', data: { messages } });
149149
},
150150
onChannelUpdated(_, ctx) {
151-
if (ctx?.source === GroupChannelEventSource.EVENT_CHANNEL_UNREAD) {
151+
if (ctx?.source === GroupChannelEventSource.EVENT_CHANNEL_READ) {
152152
if (ctx.userIds.includes(currentUser?.userId ?? '')) {
153+
groupChannelPubSub.publish({ type: 'ON_MARKED_AS_READ_BY_CURRENT_USER' });
154+
}
155+
} else if (ctx?.source === GroupChannelEventSource.EVENT_CHANNEL_UNREAD) {
156+
if (ctx.userIds.includes(currentUser?.userId ?? '')) {
157+
isNewLineExistInChannelRef.current = true;
153158
groupChannelPubSub.publish({ type: 'ON_MARKED_AS_UNREAD_BY_CURRENT_USER' });
154159
}
155160
}

0 commit comments

Comments
 (0)