Skip to content

Commit

Permalink
feat: added message search fragment
Browse files Browse the repository at this point in the history
  • Loading branch information
bang9 committed Apr 28, 2023
1 parent 43ee963 commit a6342c0
Show file tree
Hide file tree
Showing 37 changed files with 795 additions and 194 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { useChannelMessagesReducer } from '../useChannelMessagesReducer';
const createMessageCollection = (channel: SendbirdGroupChannel, options?: UseGroupChannelMessagesOptions) => {
if (options?.collectionCreator) return options?.collectionCreator({ startingPoint: options?.startingPoint });
const filter = new MessageFilter();
return channel.createMessageCollection({ filter, limit: 20, startingPoint: options?.startingPoint });
return channel.createMessageCollection({ filter, limit: 30, startingPoint: options?.startingPoint });
};

function isNotEmpty(arr?: unknown[]): arr is unknown[] {
Expand All @@ -28,6 +28,8 @@ function isNotEmpty(arr?: unknown[]): arr is unknown[] {
}

export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (sdk, channel, userId, options) => {
const initialStartingPoint = options?.startingPoint ?? Number.MAX_SAFE_INTEGER;

const forceUpdate = useForceUpdate();
const collectionRef = useRef<SendbirdMessageCollection>();
const handlerId = useUniqHandlerId('useGroupChannelMessagesWithCollection');
Expand Down Expand Up @@ -66,107 +68,109 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
if (isNotEmpty(failedMessages)) updateMessages(failedMessages, false, sdk.currentUser.userId);
};

const init = useFreshCallback(async (uid?: string, callback?: () => void) => {
const init = useFreshCallback(async (startingPoint: number, callback?: () => void) => {
if (collectionRef.current) collectionRef.current?.dispose();

if (uid) {
channelMarkAsRead();
updateNewMessages([], true, sdk.currentUser.userId);

collectionRef.current = createMessageCollection(channel, options);
collectionRef.current?.setMessageCollectionHandler({
onMessagesAdded: (_, __, messages) => {
channelMarkAsRead(_.source);

const incomingMessages = messages.filter((it) => {
switch (_.source) {
case MessageEventSource.EVENT_MESSAGE_SENT_PENDING:
case MessageEventSource.EVENT_MESSAGE_SENT_SUCCESS:
case MessageEventSource.EVENT_MESSAGE_SENT_FAILED:
return !isMyMessage(it, sdk.currentUser.userId);
default:
return true;
}
});
channelMarkAsRead();
updateNewMessages([], true, sdk.currentUser.userId);

if (incomingMessages.length > 0) {
updateMessages(incomingMessages, false, sdk.currentUser.userId);
collectionRef.current = createMessageCollection(channel, {
collectionCreator: options?.collectionCreator,
startingPoint,
});

collectionRef.current?.setMessageCollectionHandler({
onMessagesAdded: (_, __, messages) => {
channelMarkAsRead(_.source);

const incomingMessages = messages.filter((it) => {
switch (_.source) {
case MessageEventSource.EVENT_MESSAGE_SENT_PENDING:
case MessageEventSource.EVENT_MESSAGE_SENT_SUCCESS:
case MessageEventSource.EVENT_MESSAGE_SENT_FAILED:
return !isMyMessage(it, sdk.currentUser.userId);
default:
return true;
}
});

if (options?.shouldCountNewMessages?.()) {
updateNewMessages(incomingMessages, false, sdk.currentUser.userId);
}
if (incomingMessages.length > 0) {
updateMessages(incomingMessages, false, sdk.currentUser.userId);

switch (_.source) {
case MessageEventSource.EVENT_MESSAGE_RECEIVED:
case MessageEventSource.SYNC_MESSAGE_FILL: {
options?.onMessagesReceived?.(incomingMessages);
}
}
if (options?.shouldCountNewMessages?.()) {
updateNewMessages(incomingMessages, false, sdk.currentUser.userId);
}
},
onMessagesUpdated: (_, __, messages) => {
channelMarkAsRead(_.source);

const incomingMessages = messages.filter((it) => {
switch (_.source) {
case MessageEventSource.EVENT_MESSAGE_UPDATED:
return !isMyMessage(it, sdk.currentUser.userId);
default:
return true;
}
});

if (incomingMessages.length > 0) {
// NOTE: admin message is not added via onMessagesAdded handler, not checked yet is this a bug.
updateMessages(messages, false, sdk.currentUser.userId);

if (options?.shouldCountNewMessages?.()) {
if (_.source === MessageEventSource.EVENT_MESSAGE_RECEIVED) {
updateNewMessages(messages, false, sdk.currentUser.userId);
}
switch (_.source) {
case MessageEventSource.EVENT_MESSAGE_RECEIVED:
case MessageEventSource.SYNC_MESSAGE_FILL: {
options?.onMessagesReceived?.(incomingMessages);
}
}
},
onMessagesDeleted: (_, __, messageIds) => {
deleteMessages(messageIds, []);
deleteNewMessages(messageIds, []);
},
onChannelDeleted: () => {
options?.onChannelDeleted?.();
},
onChannelUpdated: (_, eventChannel) => {
if (eventChannel.isGroupChannel() && !isDifferentChannel(eventChannel, channel)) {
forceUpdate();
}
},
onMessagesUpdated: (_, __, messages) => {
channelMarkAsRead(_.source);

const incomingMessages = messages.filter((it) => {
switch (_.source) {
case MessageEventSource.EVENT_MESSAGE_UPDATED:
return !isMyMessage(it, sdk.currentUser.userId);
default:
return true;
}
},
onHugeGapDetected: () => {
init(uid);
},
});
});

collectionRef.current
.initialize(MessageCollectionInitPolicy.CACHE_AND_REPLACE_BY_API)
.onCacheResult((err, messages) => {
if (err) sdk.isCacheEnabled && Logger.error('[useGroupChannelMessagesWithCollection/onCacheResult]', err);
else {
Logger.debug('[useGroupChannelMessagesWithCollection/onCacheResult]', 'message length:', messages.length);
if (incomingMessages.length > 0) {
// NOTE: admin message is not added via onMessagesAdded handler, not checked yet is this a bug.
updateMessages(messages, false, sdk.currentUser.userId);

updateMessages(messages, true, sdk.currentUser.userId);
updateUnsendMessages();
}
callback?.();
})
.onApiResult((err, messages) => {
if (err) Logger.warn('[useGroupChannelMessagesWithCollection/onApiResult]', err);
else {
Logger.debug('[useGroupChannelMessagesWithCollection/onApiResult]', 'message length:', messages.length);

updateMessages(messages, true, sdk.currentUser.userId);
if (sdk.isCacheEnabled) updateUnsendMessages();
if (options?.shouldCountNewMessages?.()) {
if (_.source === MessageEventSource.EVENT_MESSAGE_RECEIVED) {
updateNewMessages(messages, false, sdk.currentUser.userId);
}
}
callback?.();
});
}
}
},
onMessagesDeleted: (_, __, messageIds) => {
deleteMessages(messageIds, []);
deleteNewMessages(messageIds, []);
},
onChannelDeleted: () => {
options?.onChannelDeleted?.();
},
onChannelUpdated: (_, eventChannel) => {
if (eventChannel.isGroupChannel() && !isDifferentChannel(eventChannel, channel)) {
forceUpdate();
}
},
onHugeGapDetected: () => {
init(Number.MAX_SAFE_INTEGER);
},
});

collectionRef.current
.initialize(MessageCollectionInitPolicy.CACHE_AND_REPLACE_BY_API)
.onCacheResult((err, messages) => {
if (err) sdk.isCacheEnabled && Logger.error('[useGroupChannelMessagesWithCollection/onCacheResult]', err);
else {
Logger.debug('[useGroupChannelMessagesWithCollection/onCacheResult]', 'message length:', messages.length);

updateMessages(messages, true, sdk.currentUser.userId);
updateUnsendMessages();
}
callback?.();
})
.onApiResult((err, messages) => {
if (err) Logger.warn('[useGroupChannelMessagesWithCollection/onApiResult]', err);
else {
Logger.debug('[useGroupChannelMessagesWithCollection/onApiResult]', 'message length:', messages.length);

updateMessages(messages, true, sdk.currentUser.userId);
if (sdk.isCacheEnabled) updateUnsendMessages();
}
callback?.();
});
});

useChannelHandler(sdk, handlerId, {
Expand All @@ -185,7 +189,7 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
// NOTE: Cache read is heavy task, and it prevents smooth ui transition
setTimeout(async () => {
updateLoading(true);
init(userId, () => updateLoading(false));
init(initialStartingPoint, () => updateLoading(false));
}, 0);
}, [channel.url, userId]);

Expand All @@ -197,7 +201,7 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s

const refresh: ReturnType<UseGroupChannelMessages>['refresh'] = useFreshCallback(async () => {
updateRefreshing(true);
init(userId, () => updateRefreshing(false));
init(Number.MAX_SAFE_INTEGER, () => updateRefreshing(false));
});

const prev: ReturnType<UseGroupChannelMessages>['prev'] = useFreshCallback(async () => {
Expand Down Expand Up @@ -314,6 +318,16 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
const resetNewMessages: ReturnType<UseGroupChannelMessages>['resetNewMessages'] = useFreshCallback(() => {
updateNewMessages([], true, sdk.currentUser.userId);
});
const resetWithStartingPoint: ReturnType<UseGroupChannelMessages>['resetWithStartingPoint'] = useFreshCallback(
(startingPoint, callback) => {
updateLoading(true);
updateMessages([], true, sdk.currentUser.userId);
init(startingPoint, () => {
updateLoading(false);
callback?.();
});
},
);

return {
loading,
Expand All @@ -332,6 +346,7 @@ export const useGroupChannelMessagesWithCollection: UseGroupChannelMessages = (s
updateFileMessage,
resendMessage,
deleteMessage,
resetWithStartingPoint,
nextMessages: newMessages,
newMessagesFromMembers: newMessages,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,9 @@ export const useGroupChannelMessagesWithQuery: UseGroupChannelMessages = (sdk, c
updateFileMessage,
resendMessage,
deleteMessage,
resetWithStartingPoint() {
Logger.warn('resetWithStartingPoint is not supported in Query, please use Collection instead.');
},

nextMessages: newMessages,
newMessagesFromMembers: newMessages,
Expand Down
5 changes: 5 additions & 0 deletions packages/uikit-chat-hooks/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ export interface UseGroupChannelMessages {
* */
newMessages: SendbirdMessage[];

/**
* reset message list with starting point
* */
resetWithStartingPoint: (startingPoint: number, callback?: () => void) => void;

/**
* Reset new messages
* */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ const ChannelMessageList = <T extends SendbirdGroupChannel | SendbirdOpenChannel
{renderNewMessagesButton && (
<View style={[styles.newMsgButton, safeAreaLayout]}>
{renderNewMessagesButton({
visible: !hasNext() && scrolledAwayFromBottom,
visible: newMessages.length > 0 && (hasNext() || scrolledAwayFromBottom),
onPress: () => onPressNewMessagesButton(),
newMessages,
})}
Expand All @@ -174,7 +174,7 @@ const ChannelMessageList = <T extends SendbirdGroupChannel | SendbirdOpenChannel
{renderScrollToBottomButton && (
<View pointerEvents={scrolledAwayFromBottom ? 'auto' : 'none'} style={[styles.scrollButton, safeAreaLayout]}>
{renderScrollToBottomButton({
visible: !hasNext() && scrolledAwayFromBottom,
visible: hasNext() || scrolledAwayFromBottom,
onPress: () => onPressScrollToBottomButton(),
})}
</View>
Expand Down
Loading

0 comments on commit a6342c0

Please sign in to comment.