Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/thread loading bug and message update bug #713

Merged
merged 15 commits into from
Jul 13, 2021
Merged
Show file tree
Hide file tree
Changes from 14 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
4 changes: 2 additions & 2 deletions src/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1562,7 +1562,7 @@ export class Channel<
case 'message.deleted':
if (event.message) {
if (event.hard_delete) channelState.removeMessage(event.message);
else channelState.addMessageSorted(event.message);
else channelState.addMessageSorted(event.message, false, false);
if (event.message.pinned) {
channelState.removePinnedMessage(event.message);
}
Expand Down Expand Up @@ -1595,7 +1595,7 @@ export class Channel<
break;
case 'message.updated':
if (event.message) {
channelState.addMessageSorted(event.message);
channelState.addMessageSorted(event.message, false, false);
if (event.message.pinned) {
channelState.addPinnedMessage(event.message);
} else {
Expand Down
70 changes: 59 additions & 11 deletions src/channel_state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ export class ChannelState<
*
* @param {MessageResponse<AttachmentType, ChannelType, CommandType, MessageType, ReactionType, UserType>} newMessage A new message
* @param {boolean} timestampChanged Whether updating a message with changed created_at value.
* @param {boolean} addIfDoesNotExist Add message if it is not in the list, used to prevent out of order updated messages from being added.
*
*/
addMessageSorted(
Expand All @@ -155,8 +156,14 @@ export class ChannelState<
UserType
>,
timestampChanged = false,
addIfDoesNotExist = true,
) {
return this.addMessagesSorted([newMessage], timestampChanged);
return this.addMessagesSorted(
[newMessage],
timestampChanged,
false,
addIfDoesNotExist,
);
}

/**
Expand Down Expand Up @@ -203,6 +210,7 @@ export class ChannelState<
* @param {Array<MessageResponse<AttachmentType, ChannelType, CommandType, MessageType, ReactionType, UserType>>} newMessages A list of messages
* @param {boolean} timestampChanged Whether updating messages with changed created_at value.
* @param {boolean} initializing Whether channel is being initialized.
* @param {boolean} addIfDoesNotExist Add message if it is not in the list, used to prevent out of order updated messages from being added.
*
*/
addMessagesSorted(
Expand All @@ -216,6 +224,7 @@ export class ChannelState<
>[],
timestampChanged = false,
initializing = false,
addIfDoesNotExist = true,
) {
for (let i = 0; i < newMessages.length; i += 1) {
const message = this.formatMessage(newMessages[i]);
Expand Down Expand Up @@ -252,13 +261,33 @@ export class ChannelState<

// add to the main message list
if (!parentID || message.show_in_channel) {
this.messages = this._addToMessageList(this.messages, message, timestampChanged);
this.messages = this._addToMessageList(
this.messages,
message,
timestampChanged,
'created_at',
addIfDoesNotExist,
);
}

// add to the thread if applicable..
if (parentID) {
/**
* Add message to thread if applicable and the message
* was added when querying for replies, or the thread already exits.
* This is to prevent the thread state from getting out of sync if
* a thread message is shown in channel but older than the newest thread
* message. This situation can result in a thread state where a random
* message is "oldest" message, and newer messages are therefore not loaded.
* This can also occur if an old thread message is updated.
*/
if (parentID && !initializing) {
const thread = this.threads[parentID] || [];
const threadMessages = this._addToMessageList(thread, message, timestampChanged);
const threadMessages = this._addToMessageList(
thread,
message,
timestampChanged,
'created_at',
addIfDoesNotExist,
);
this.threads[parentID] = threadMessages;
}
}
Expand Down Expand Up @@ -489,6 +518,7 @@ export class ChannelState<
* @param message
* @param {boolean} timestampChanged Whether updating a message with changed created_at value.
* @param {string} sortBy field name to use to sort the messages by
* @param {boolean} addIfDoesNotExist Add message if it is not in the list, used to prevent out of order updated messages from being added.
*/
_addToMessageList(
messages: Array<
Expand Down Expand Up @@ -517,7 +547,9 @@ export class ChannelState<
>,
timestampChanged = false,
sortBy: 'pinned_at' | 'created_at' = 'created_at',
addIfDoesNotExist = true,
nhannah marked this conversation as resolved.
Show resolved Hide resolved
) {
const addMessageToList = addIfDoesNotExist || timestampChanged;
let messageArr = messages;

// if created_at has changed, message should be filtered and re-inserted in correct order
Expand All @@ -526,19 +558,31 @@ export class ChannelState<
messageArr = messageArr.filter((msg) => !(msg.id && message.id === msg.id));
}

// for empty list just concat and return
if (messageArr.length === 0) return messageArr.concat(message);
// Get array length after filtering
const messageArrayLength = messageArr.length;

// for empty list just concat and return unless it's an update or deletion
if (messageArrayLength === 0 && addMessageToList) {
return messageArr.concat(message);
} else if (messageArrayLength === 0) {
return [...messageArr];
}

const messageTime = (message[sortBy] as Date).getTime();
const messageIsNewest =
(messageArr[messageArrayLength - 1][sortBy] as Date).getTime() < messageTime;

// if message is newer than last item in the list concat and return
if ((messageArr[messageArr.length - 1][sortBy] as Date).getTime() < messageTime)
// if message is newer than last item in the list concat and return unless it's an update or deletion
if (messageIsNewest && addMessageToList) {
return messageArr.concat(message);
} else if (messageIsNewest) {
return [...messageArr];
}

// find the closest index to push the new message
let left = 0;
let middle = 0;
let right = messageArr.length - 1;
let right = messageArrayLength - 1;
while (left <= right) {
middle = Math.floor((right + left) / 2);
if ((messageArr[middle][sortBy] as Date).getTime() <= messageTime)
Expand All @@ -559,7 +603,11 @@ export class ChannelState<
}
}

messageArr.splice(left, 0, message);
// Do not add updated or deleted messages to the list if they do not already exist
// or have a timestamp change.
if (addMessageToList) {
messageArr.splice(left, 0, message);
}
return [...messageArr];
}

Expand Down