Skip to content
This repository was archived by the owner on Nov 13, 2024. It is now read-only.

Commit f7a2c3d

Browse files
committed
fix(lib): screen might not be filled with messages on init
feat(lib): add option to render deleted messages instead of filtering them out
1 parent a941257 commit f7a2c3d

5 files changed

Lines changed: 69 additions & 23 deletions

File tree

packages/common/src/message-list/message-list.tsx

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ export interface CommonMessageListProps {
4040
fileRenderer?: (file: FileAttachment) => JSX.Element;
4141
/** This option only works when you use either `messageRenderer` or `bubbleRenderer`. It allows you to apply one of the custom renderers only to the messages selected by the filter. */
4242
filter?: (message: MessageEnvelope) => boolean;
43+
/** Enable this to render deleted messages instead of filtering them out. They can be then customized with one of the renderers. */
44+
renderDeleted?: boolean;
4345
}
4446

4547
/**
@@ -194,16 +196,6 @@ export const useMessageListCore = (props: CommonMessageListProps) => {
194196
}
195197
};
196198

197-
useEffect(() => {
198-
if (!pubnub || !channel) return;
199-
if (channel === prevChannel) return;
200-
if (!initMessagesLoaded[channel]) {
201-
fetchHistory().then(() => {
202-
setInitMessagesLoaded((curr) => ({ ...curr, [channel]: true }));
203-
});
204-
}
205-
}, [channel, fetchHistory, initMessagesLoaded, messages.length, prevChannel, pubnub]);
206-
207199
useEffect(() => {
208200
if (!messages?.length || scrolledBottom) return;
209201
if (messages.length - prevMessages.length !== 1) return;
@@ -237,5 +229,6 @@ export const useMessageListCore = (props: CommonMessageListProps) => {
237229
unreadMessages,
238230
users,
239231
initMessagesLoaded,
232+
setInitMessagesLoaded,
240233
};
241234
};

packages/react-native/src/message-list/message-list.style.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,6 @@ export default (theme: Themes): MessageListStyle => {
7171
messageList: {
7272
backgroundColor: colors.messageListBackground,
7373
},
74-
messageListScroller: {
75-
backgroundColor: colors.messageListBackground,
76-
flexGrow: 1,
77-
},
7874
message: {
7975
flexDirection: "row",
8076
paddingHorizontal: 16,

packages/react-native/src/message-list/message-list.tsx

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,13 @@ export type MessageListProps = CommonMessageListProps & {
5656
export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
5757
const {
5858
addReaction,
59+
channel,
5960
emojiPickerShown,
6061
fetchHistory,
62+
fetchingMessages,
6163
getTime,
6264
getUser,
65+
initMessagesLoaded,
6366
isOwnMessage,
6467
messages,
6568
onError,
@@ -70,6 +73,7 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
7073
removeReaction,
7174
scrolledBottom,
7275
setEmojiPickerShown,
76+
setInitMessagesLoaded,
7377
setReactingToMessage,
7478
setScrolledBottom,
7579
setUnreadMessages,
@@ -88,9 +92,11 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
8892
const [spinnerShown, setSpinnerShown] = useState(false);
8993
const [sheetPosition] = useState(new Animated.Value(0));
9094
const shouldShownSpinner = props.fetchMessages && !paginationEnd;
95+
const currentChannelInitMessagesLoaded = initMessagesLoaded[channel];
9196

9297
const rotate = useRotation(shouldShownSpinner && spinnerShown);
9398
const listRef = useRef<FlatList>(null);
99+
const listHeight = useRef(0);
94100

95101
/**
96102
* Commands
@@ -179,7 +185,7 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
179185
const deleted = !!Object.keys(actions?.deleted || {}).length;
180186
const isOwn = isOwnMessage(uuid);
181187

182-
if (deleted) return;
188+
if (deleted && !props.renderDeleted) return;
183189

184190
return (
185191
<Pressable
@@ -309,7 +315,6 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
309315
<FlatList
310316
testID="message-list"
311317
style={style.messageList}
312-
contentContainerStyle={style.messageListScroller}
313318
data={[
314319
{ timetoken: "children-element", message: { id: "children-element" } },
315320
...reverseMessages,
@@ -318,10 +323,26 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
318323
renderItem={renderItem}
319324
keyExtractor={(envelope) => envelope.timetoken as string}
320325
ref={listRef}
321-
onEndReached={() => fetchHistory()}
326+
onEndReached={() => {
327+
if (!fetchingMessages) fetchHistory();
328+
}}
322329
onScroll={handleScroll}
323330
inverted={true}
324331
onViewableItemsChanged={onViewableItemsChanged}
332+
onContentSizeChange={(_, contentHeight) => {
333+
if (
334+
contentHeight <= listHeight.current &&
335+
!paginationEnd &&
336+
!currentChannelInitMessagesLoaded
337+
) {
338+
if (!fetchingMessages) fetchHistory();
339+
} else {
340+
setInitMessagesLoaded((curr) => ({ ...curr, [channel]: true }));
341+
}
342+
}}
343+
onLayout={(ev) => {
344+
listHeight.current = ev.nativeEvent.layout.height;
345+
}}
325346
/>
326347
{props.reactionsPicker &&
327348
cloneElement(props.reactionsPicker, {

packages/react/src/message-list/message-item.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export type ItemProps = Pick<
3636
| "filter"
3737
| "messageRenderer"
3838
| "reactionsPicker"
39+
| "renderDeleted"
3940
>;
4041
scrollToBottom: () => void;
4142
};
@@ -72,11 +73,12 @@ function Item({
7273
filter,
7374
messageRenderer,
7475
reactionsPicker,
76+
renderDeleted,
7577
} = listProps;
7678

7779
const actions = envelope.actions;
7880
const deleted = !!Object.keys(actions?.deleted || {}).length;
79-
if (deleted) return;
81+
if (deleted && !renderDeleted) return;
8082
const uuid = envelope.uuid || envelope.publisher || "";
8183
const currentUserClass = isOwnMessage(uuid) ? "pn-msg--own" : "";
8284
const message = isFilePayload(envelope.message) ? envelope.message.message : envelope.message;

packages/react/src/message-list/message-list.tsx

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,11 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
6666
unreadMessages,
6767
users,
6868
initMessagesLoaded,
69+
setInitMessagesLoaded,
6970
} = useMessageListCore(props);
7071

72+
const currentChannelInitMessagesLoaded = initMessagesLoaded[channel];
73+
const previousMessagesLength = usePrevious(messages.length);
7174
const lastMessageUniqueReactions = Object.keys(messages.slice(-1)[0]?.actions?.reaction || {});
7275
const prevLastMessageUniqueReactions = usePrevious(lastMessageUniqueReactions);
7376

@@ -137,9 +140,40 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
137140
* Lifecycle
138141
*/
139142
useEffect(() => {
140-
if (!isSpinnerVisible || wasSpinnerVisible || !initMessagesLoaded[channel] || fetchingMessages)
141-
return;
142-
fetchMoreHistory();
143+
const { scrollHeight, clientHeight } = listRef.current;
144+
const hasScroll = scrollHeight > clientHeight;
145+
if (!currentChannelInitMessagesLoaded && (paginationEnd || hasScroll))
146+
setInitMessagesLoaded((curr) => ({ ...curr, [channel]: true }));
147+
if (
148+
pubnub &&
149+
channel &&
150+
!currentChannelInitMessagesLoaded &&
151+
!paginationEnd &&
152+
(channel !== prevChannel || (!hasScroll && messages.length !== previousMessagesLength))
153+
) {
154+
fetchHistory();
155+
}
156+
}, [
157+
channel,
158+
currentChannelInitMessagesLoaded,
159+
fetchHistory,
160+
messages.length,
161+
paginationEnd,
162+
prevChannel,
163+
previousMessagesLength,
164+
pubnub,
165+
setInitMessagesLoaded,
166+
]);
167+
168+
useEffect(() => {
169+
if (
170+
isSpinnerVisible &&
171+
!wasSpinnerVisible &&
172+
currentChannelInitMessagesLoaded &&
173+
!fetchingMessages
174+
) {
175+
fetchMoreHistory();
176+
}
143177

144178
async function fetchMoreHistory() {
145179
const firstMessage = listRef.current?.querySelector(".pn-msg") as HTMLDivElement;
@@ -151,8 +185,7 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
151185
fetchHistory,
152186
isSpinnerVisible,
153187
wasSpinnerVisible,
154-
initMessagesLoaded,
155-
channel,
188+
currentChannelInitMessagesLoaded,
156189
fetchingMessages,
157190
]);
158191

@@ -201,6 +234,7 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
201234
filter: props.filter,
202235
messageRenderer: props.messageRenderer,
203236
reactionsPicker: props.reactionsPicker,
237+
renderDeleted: props.renderDeleted,
204238
},
205239
pubnub,
206240
reactingToMessage,

0 commit comments

Comments
 (0)