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

Commit 51cb463

Browse files
authored
Merge pull request #137 from pubnub/deleted-messages-behaviors
Deleted messages behaviors
2 parents a941257 + 61f37ee commit 51cb463

File tree

9 files changed

+96
-27
lines changed

9 files changed

+96
-27
lines changed

.pubnub.yml

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
---
22
name: pubnub-react-chat-components
3-
version: v0.33.0
3+
version: v0.34.0
44
scm: github.com/pubnub/react-chat-components
55
schema: 1
66
files:
77
- lib/dist/index.js
88
- lib/dist/index.es.js
99
changelog:
10+
- date: 2024-05-16
11+
version: v0.34.0
12+
changes:
13+
- type: feature
14+
text: "Add option to render deleted messages instead of filtering them out."
15+
- type: bug
16+
text: "Screen might not be filled with messages on init."
1017
- date: 2023-12-11
1118
version: v0.33.0
1219
changes:

packages/common/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pubnub/common-chat-components",
3-
"version": "0.33.0",
3+
"version": "0.34.0",
44
"main": "src/index.ts",
55
"license": "MIT",
66
"scripts": {

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

+3-10
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/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pubnub/react-native-chat-components",
3-
"version": "0.33.0",
3+
"version": "0.34.0",
44
"description": "PubNub Chat Components is a development kit of React Native components that aims to help you to easily build Chat applications using PubNub infrastructure. It removes the complexicity of picking an adequate Chat engine, learning its APIs and dealing with its low-level internals. As the same time it allows you to create apps of various use cases, with different functionalities and customizable looks.",
55
"author": "PubNub <[email protected]>",
66
"main": "dist/commonjs/index",

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

-4
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

+40-3
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,25 @@ 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,
6669
paginationEnd,
70+
prevChannel,
6771
prevMessages,
6872
pubnub,
6973
reactingToMessage,
7074
removeReaction,
7175
scrolledBottom,
7276
setEmojiPickerShown,
77+
setInitMessagesLoaded,
7378
setReactingToMessage,
7479
setScrolledBottom,
7580
setUnreadMessages,
@@ -88,9 +93,11 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
8893
const [spinnerShown, setSpinnerShown] = useState(false);
8994
const [sheetPosition] = useState(new Animated.Value(0));
9095
const shouldShownSpinner = props.fetchMessages && !paginationEnd;
96+
const currentChannelInitMessagesLoaded = initMessagesLoaded[channel];
9197

9298
const rotate = useRotation(shouldShownSpinner && spinnerShown);
9399
const listRef = useRef<FlatList>(null);
100+
const listHeight = useRef(0);
94101

95102
/**
96103
* Commands
@@ -145,6 +152,21 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
145152
/**
146153
* Lifecycle
147154
*/
155+
useEffect(() => {
156+
if (!currentChannelInitMessagesLoaded && channel !== prevChannel) {
157+
fetchHistory();
158+
}
159+
}, [
160+
channel,
161+
currentChannelInitMessagesLoaded,
162+
fetchHistory,
163+
messages.length,
164+
paginationEnd,
165+
pubnub,
166+
prevChannel,
167+
setInitMessagesLoaded,
168+
]);
169+
148170
useEffect(() => {
149171
if (!scrolledBottom) return;
150172
if (prevMessages.length !== messages.length) scrollToBottom();
@@ -179,7 +201,7 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
179201
const deleted = !!Object.keys(actions?.deleted || {}).length;
180202
const isOwn = isOwnMessage(uuid);
181203

182-
if (deleted) return;
204+
if (deleted && !props.renderDeleted) return;
183205

184206
return (
185207
<Pressable
@@ -309,7 +331,6 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
309331
<FlatList
310332
testID="message-list"
311333
style={style.messageList}
312-
contentContainerStyle={style.messageListScroller}
313334
data={[
314335
{ timetoken: "children-element", message: { id: "children-element" } },
315336
...reverseMessages,
@@ -318,10 +339,26 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
318339
renderItem={renderItem}
319340
keyExtractor={(envelope) => envelope.timetoken as string}
320341
ref={listRef}
321-
onEndReached={() => fetchHistory()}
342+
onEndReached={() => {
343+
if (!fetchingMessages) fetchHistory();
344+
}}
322345
onScroll={handleScroll}
323346
inverted={true}
324347
onViewableItemsChanged={onViewableItemsChanged}
348+
onContentSizeChange={(_, contentHeight) => {
349+
if (
350+
contentHeight <= listHeight.current &&
351+
!paginationEnd &&
352+
!currentChannelInitMessagesLoaded
353+
) {
354+
if (!fetchingMessages) fetchHistory();
355+
} else {
356+
setInitMessagesLoaded((curr) => ({ ...curr, [channel]: true }));
357+
}
358+
}}
359+
onLayout={(ev) => {
360+
listHeight.current = ev.nativeEvent.layout.height;
361+
}}
325362
/>
326363
{props.reactionsPicker &&
327364
cloneElement(props.reactionsPicker, {

packages/react/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pubnub/react-chat-components",
3-
"version": "0.33.0",
3+
"version": "0.34.0",
44
"description": "PubNub Chat Components is a development kit of React components that aims to help you to easily build Chat applications using PubNub infrastructure. It removes the complexicity of picking an adequate Chat engine, learning its APIs and dealing with its low-level internals. As the same time it allows you to create apps of various use cases, with different functionalities and customizable looks.",
55
"author": "PubNub <[email protected]>",
66
"main": "dist/index.js",

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

+3-1
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

+39-5
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)