Skip to content

Commit

Permalink
Adjust insertion index API
Browse files Browse the repository at this point in the history
  • Loading branch information
arnautov-anton committed Aug 6, 2024
1 parent ee136fd commit 18f7bd3
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 23 deletions.
2 changes: 1 addition & 1 deletion src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
tags: ['connection', 'client'],
});

return Promise.resolve();
return;
}

this.clientID = `${this.userID}--${randomId()}`;
Expand Down
19 changes: 14 additions & 5 deletions src/thread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ import type {
MessagePaginationOptions,
AscDesc,
} from './types';
import { addToMessageList, findInsertionIndex, formatMessage, transformReadArrayToDictionary, throttle } from './utils';
import {
addToMessageList,
findIndexInSortedArray,
formatMessage,
transformReadArrayToDictionary,
throttle,
} from './utils';
import { Handler, SimpleStateStore } from './store/SimpleStateStore';

type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };
Expand Down Expand Up @@ -381,9 +387,12 @@ export class Thread<Scg extends ExtendableGenerics = DefaultGenerics> {
public deleteReplyLocally = ({ message }: { message: MessageResponse<Scg> }) => {
const { latestReplies } = this.state.getLatestValue();

const index = findInsertionIndex({
message: formatMessage(message),
messages: latestReplies,
const index = findIndexInSortedArray({
needle: formatMessage(message),
sortedArray: latestReplies,
// TODO: make following two configurable (sortDirection and created_at)
sortDirection: 'ascending',
selectValueToCompare: (m) => m['created_at'].getTime(),
});

const actualIndex =
Expand Down Expand Up @@ -796,7 +805,7 @@ export class ThreadManager<Scg extends ExtendableGenerics = DefaultGenerics> {
// TODO: loading states
console.error(error);
} finally {
console.log('...');
// ...
}
};

Expand Down
71 changes: 54 additions & 17 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,28 +305,60 @@ export function formatMessage<StreamChatGenerics extends ExtendableGenerics = De
};
}

// TODO: does not respect message lists ordered [newest -> oldest] only [oldest -> newest]
export const findInsertionIndex = <T extends FormatMessageResponse>({
message,
messages,
sortBy = 'created_at',
export const findIndexInSortedArray = <T, L>({
needle,
sortedArray,
selectValueToCompare = (e) => e,
sortDirection = 'ascending',
}: {
message: T;
messages: Array<T>;
sortBy?: 'pinned_at' | 'created_at';
needle: T;
sortedArray: readonly T[];
/**
* In array of objects (like messages), pick a specific
* property to compare needle value to.
*
* @example
* ```ts
* selectValueToCompare: (message) => message.created_at.getTime()
* ```
*/
selectValueToCompare?: (arrayElement: T) => L | T;
/**
* @default ascending
* @description
* ```md
* ascending - [1,2,3,4,5...]
* descending - [...5,4,3,2,1]
* ```
*/
sortDirection?: 'ascending' | 'descending';
}) => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const messageTime = message[sortBy]!.getTime();
if (!sortedArray.length) return 0;

let left = 0;
let right = sortedArray.length - 1;
let middle = 0;
let right = messages.length - 1;

const recalculateMiddle = () => {
middle = Math.round((left + right) / 2);
};

const actualNeedle = selectValueToCompare(needle);
recalculateMiddle();

while (left <= right) {
middle = Math.floor((right + left) / 2);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
if (messages[middle][sortBy]!.getTime() <= messageTime) left = middle + 1;
else right = middle - 1;
// if (actualNeedle === selectValueToCompare(sortedArray[middle])) return middle;

if (
(sortDirection === 'ascending' && actualNeedle < selectValueToCompare(sortedArray[middle])) ||
(sortDirection === 'descending' && actualNeedle > selectValueToCompare(sortedArray[middle]))
) {
right = middle - 1;
} else {
left = middle + 1;
}

recalculateMiddle();
}

return left;
Expand Down Expand Up @@ -364,9 +396,14 @@ export function addToMessageList<T extends FormatMessageResponse>(
}

// find the closest index to push the new message
const insertionIndex = findInsertionIndex({ message: newMessage, messages: newMessages, sortBy });
const insertionIndex = findIndexInSortedArray({
needle: newMessage,
sortedArray: messages,
sortDirection: 'ascending',
selectValueToCompare: (m) => m[sortBy]!.getTime(),
});

// message already exists and not filtered due to timestampChanged, update and return
// message already exists and not filtered with timestampChanged, update and return
if (!timestampChanged && newMessage.id) {
if (newMessages[insertionIndex] && newMessage.id === newMessages[insertionIndex].id) {
newMessages[insertionIndex] = newMessage;
Expand Down

0 comments on commit 18f7bd3

Please sign in to comment.