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

Deleted messages behaviors #137

Merged
merged 3 commits into from
May 16, 2024
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
9 changes: 8 additions & 1 deletion .pubnub.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
---
name: pubnub-react-chat-components
version: v0.33.0
version: v0.34.0
scm: github.com/pubnub/react-chat-components
schema: 1
files:
- lib/dist/index.js
- lib/dist/index.es.js
changelog:
- date: 2024-05-16
version: v0.34.0
changes:
- type: feature
text: "Add option to render deleted messages instead of filtering them out."
- type: bug
text: "Screen might not be filled with messages on init."
- date: 2023-12-11
version: v0.33.0
changes:
Expand Down
2 changes: 1 addition & 1 deletion packages/common/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pubnub/common-chat-components",
"version": "0.33.0",
"version": "0.34.0",
"main": "src/index.ts",
"license": "MIT",
"scripts": {
Expand Down
13 changes: 3 additions & 10 deletions packages/common/src/message-list/message-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ export interface CommonMessageListProps {
fileRenderer?: (file: FileAttachment) => JSX.Element;
/** 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. */
filter?: (message: MessageEnvelope) => boolean;
/** Enable this to render deleted messages instead of filtering them out. They can be then customized with one of the renderers. */
renderDeleted?: boolean;
}

/**
Expand Down Expand Up @@ -194,16 +196,6 @@ export const useMessageListCore = (props: CommonMessageListProps) => {
}
};

useEffect(() => {
if (!pubnub || !channel) return;
if (channel === prevChannel) return;
if (!initMessagesLoaded[channel]) {
fetchHistory().then(() => {
setInitMessagesLoaded((curr) => ({ ...curr, [channel]: true }));
});
}
}, [channel, fetchHistory, initMessagesLoaded, messages.length, prevChannel, pubnub]);

useEffect(() => {
if (!messages?.length || scrolledBottom) return;
if (messages.length - prevMessages.length !== 1) return;
Expand Down Expand Up @@ -237,5 +229,6 @@ export const useMessageListCore = (props: CommonMessageListProps) => {
unreadMessages,
users,
initMessagesLoaded,
setInitMessagesLoaded,
};
};
2 changes: 1 addition & 1 deletion packages/react-native/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pubnub/react-native-chat-components",
"version": "0.33.0",
"version": "0.34.0",
"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.",
"author": "PubNub <[email protected]>",
"main": "dist/commonjs/index",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,6 @@ export default (theme: Themes): MessageListStyle => {
messageList: {
backgroundColor: colors.messageListBackground,
},
messageListScroller: {
backgroundColor: colors.messageListBackground,
flexGrow: 1,
},
message: {
flexDirection: "row",
paddingHorizontal: 16,
Expand Down
43 changes: 40 additions & 3 deletions packages/react-native/src/message-list/message-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,25 @@ export type MessageListProps = CommonMessageListProps & {
export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
const {
addReaction,
channel,
emojiPickerShown,
fetchHistory,
fetchingMessages,
getTime,
getUser,
initMessagesLoaded,
isOwnMessage,
messages,
onError,
paginationEnd,
prevChannel,
prevMessages,
pubnub,
reactingToMessage,
removeReaction,
scrolledBottom,
setEmojiPickerShown,
setInitMessagesLoaded,
setReactingToMessage,
setScrolledBottom,
setUnreadMessages,
Expand All @@ -88,9 +93,11 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
const [spinnerShown, setSpinnerShown] = useState(false);
const [sheetPosition] = useState(new Animated.Value(0));
const shouldShownSpinner = props.fetchMessages && !paginationEnd;
const currentChannelInitMessagesLoaded = initMessagesLoaded[channel];

const rotate = useRotation(shouldShownSpinner && spinnerShown);
const listRef = useRef<FlatList>(null);
const listHeight = useRef(0);

/**
* Commands
Expand Down Expand Up @@ -145,6 +152,21 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
/**
* Lifecycle
*/
useEffect(() => {
if (!currentChannelInitMessagesLoaded && channel !== prevChannel) {
fetchHistory();
}
}, [
channel,
currentChannelInitMessagesLoaded,
fetchHistory,
messages.length,
paginationEnd,
pubnub,
prevChannel,
setInitMessagesLoaded,
]);

useEffect(() => {
if (!scrolledBottom) return;
if (prevMessages.length !== messages.length) scrollToBottom();
Expand Down Expand Up @@ -179,7 +201,7 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
const deleted = !!Object.keys(actions?.deleted || {}).length;
const isOwn = isOwnMessage(uuid);

if (deleted) return;
if (deleted && !props.renderDeleted) return;

return (
<Pressable
Expand Down Expand Up @@ -309,7 +331,6 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
<FlatList
testID="message-list"
style={style.messageList}
contentContainerStyle={style.messageListScroller}
data={[
{ timetoken: "children-element", message: { id: "children-element" } },
...reverseMessages,
Expand All @@ -318,10 +339,26 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
renderItem={renderItem}
keyExtractor={(envelope) => envelope.timetoken as string}
ref={listRef}
onEndReached={() => fetchHistory()}
onEndReached={() => {
if (!fetchingMessages) fetchHistory();
}}
onScroll={handleScroll}
inverted={true}
onViewableItemsChanged={onViewableItemsChanged}
onContentSizeChange={(_, contentHeight) => {
if (
contentHeight <= listHeight.current &&
!paginationEnd &&
!currentChannelInitMessagesLoaded
) {
if (!fetchingMessages) fetchHistory();
} else {
setInitMessagesLoaded((curr) => ({ ...curr, [channel]: true }));
}
}}
onLayout={(ev) => {
listHeight.current = ev.nativeEvent.layout.height;
}}
/>
{props.reactionsPicker &&
cloneElement(props.reactionsPicker, {
Expand Down
2 changes: 1 addition & 1 deletion packages/react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pubnub/react-chat-components",
"version": "0.33.0",
"version": "0.34.0",
"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.",
"author": "PubNub <[email protected]>",
"main": "dist/index.js",
Expand Down
4 changes: 3 additions & 1 deletion packages/react/src/message-list/message-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export type ItemProps = Pick<
| "filter"
| "messageRenderer"
| "reactionsPicker"
| "renderDeleted"
>;
scrollToBottom: () => void;
};
Expand Down Expand Up @@ -72,11 +73,12 @@ function Item({
filter,
messageRenderer,
reactionsPicker,
renderDeleted,
} = listProps;

const actions = envelope.actions;
const deleted = !!Object.keys(actions?.deleted || {}).length;
if (deleted) return;
if (deleted && !renderDeleted) return;
const uuid = envelope.uuid || envelope.publisher || "";
const currentUserClass = isOwnMessage(uuid) ? "pn-msg--own" : "";
const message = isFilePayload(envelope.message) ? envelope.message.message : envelope.message;
Expand Down
44 changes: 39 additions & 5 deletions packages/react/src/message-list/message-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,11 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
unreadMessages,
users,
initMessagesLoaded,
setInitMessagesLoaded,
} = useMessageListCore(props);

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

Expand Down Expand Up @@ -137,9 +140,40 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
* Lifecycle
*/
useEffect(() => {
if (!isSpinnerVisible || wasSpinnerVisible || !initMessagesLoaded[channel] || fetchingMessages)
return;
fetchMoreHistory();
const { scrollHeight, clientHeight } = listRef.current;
const hasScroll = scrollHeight > clientHeight;
if (!currentChannelInitMessagesLoaded && (paginationEnd || hasScroll))
setInitMessagesLoaded((curr) => ({ ...curr, [channel]: true }));
if (
pubnub &&
channel &&
!currentChannelInitMessagesLoaded &&
!paginationEnd &&
(channel !== prevChannel || (!hasScroll && messages.length !== previousMessagesLength))
) {
fetchHistory();
}
}, [
channel,
currentChannelInitMessagesLoaded,
fetchHistory,
messages.length,
paginationEnd,
prevChannel,
previousMessagesLength,
pubnub,
setInitMessagesLoaded,
]);

useEffect(() => {
if (
isSpinnerVisible &&
!wasSpinnerVisible &&
currentChannelInitMessagesLoaded &&
!fetchingMessages
) {
fetchMoreHistory();
}

async function fetchMoreHistory() {
const firstMessage = listRef.current?.querySelector(".pn-msg") as HTMLDivElement;
Expand All @@ -151,8 +185,7 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
fetchHistory,
isSpinnerVisible,
wasSpinnerVisible,
initMessagesLoaded,
channel,
currentChannelInitMessagesLoaded,
fetchingMessages,
]);

Expand Down Expand Up @@ -201,6 +234,7 @@ export const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
filter: props.filter,
messageRenderer: props.messageRenderer,
reactionsPicker: props.reactionsPicker,
renderDeleted: props.renderDeleted,
},
pubnub,
reactingToMessage,
Expand Down
Loading