Skip to content

Commit

Permalink
Merge pull request #268 from waku-org/fix/web-chat-msg-order
Browse files Browse the repository at this point in the history
  • Loading branch information
fryorcraken committed Sep 15, 2023
2 parents 0b494e4 + 47b57bb commit b11300c
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 11 deletions.
4 changes: 2 additions & 2 deletions examples/web-chat/src/ChatList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Message } from "./Message";
import type { ChatListProps } from "./types";

export default function ChatList(props: ChatListProps) {
const renderedMessages = props.messages.map((message) => (
const renderedMessages = props.messages.array.map((message) => (
<div
key={
message.nick +
Expand All @@ -24,7 +24,7 @@ export default function ChatList(props: ChatListProps) {
return (
<div className="overflow-y-auto h-full">
{renderedMessages}
<AlwaysScrollToBottom messages={props.messages} />
<AlwaysScrollToBottom messages={props.messages.array} />
</div>
);
}
Expand Down
12 changes: 12 additions & 0 deletions examples/web-chat/src/Message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ export class Message {
this.sentTimestamp = sentTimestamp;
}

static cmp(left: Message, right: Message): boolean {
return left.timestamp.getTime() < right.timestamp.getTime();
}

static isEqual(left: Message, right: Message): boolean {
return (
left.timestamp.valueOf() === right.timestamp.valueOf() &&
left.chatMessage.nick === right.chatMessage.nick &&
left.chatMessage.payloadAsUtf8 === right.chatMessage.payloadAsUtf8
);
}

static fromWakuMessage(wakuMsg: IDecodedMessage): Message | undefined {
if (wakuMsg.payload) {
try {
Expand Down
20 changes: 14 additions & 6 deletions examples/web-chat/src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
UsePeersParams,
UsePeersResults,
} from "./types";
import { OrderedSet } from "./ordered_array";

export const usePersistentNick = (): [
string,
Expand Down Expand Up @@ -40,15 +41,22 @@ export const useMessages = (params: UseMessagesParams): UseMessagesResult => {
setLocalMessages((prev) => [...prev, ...msgs]);
};

const allMessages = React.useMemo((): Message[] => {
return [...storedMessages, ...newMessages]
const allMessages = React.useMemo((): OrderedSet<Message> => {
const allMessages = new OrderedSet(Message.cmp, Message.isEqual);

const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);

const _msgs = [...storedMessages, ...newMessages]
.map(Message.fromWakuMessage)
.concat(localMessages)
.filter((v): v is Message => !!v)
.filter((v) => v.payloadAsUtf8 !== "")
.sort(
(left, right) => left.timestamp.getTime() - right.timestamp.getTime()
);
// Filter out messages that are "sent" tomorrow are they are likely to be flukes
.filter((m) => m.timestamp.valueOf() < tomorrow.valueOf());
allMessages.push(..._msgs);
allMessages.push(...localMessages);

return allMessages;
}, [storedMessages, newMessages, localMessages]);

return [allMessages, pushMessages];
Expand Down
32 changes: 32 additions & 0 deletions examples/web-chat/src/ordered_array.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export class OrderedSet<T> {
array: Array<T>;

constructor(
public orderCmp: (a: T, b: T) => boolean,
public isEqual: (a: T, b: T) => boolean
) {
this.array = [];
}

push(...items: T[]): void {
for (const item of items) {
this.insertInOrder(this.array, item);
}
}

insertInOrder(array: T[], item: T): T[] {
let i = 0;
while (i < array.length) {
if (this.isEqual(item, array[i])) {
continue;
}
if (this.orderCmp(item, array[i])) {
break;
}
i++;
}

array.splice(i, 0, item);
return array;
}
}
7 changes: 4 additions & 3 deletions examples/web-chat/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { PeerId } from "@libp2p/interface-peer-id";
import type { LightNode, StoreQueryOptions, Waku } from "@waku/interfaces";
import type { Decoder } from "@waku/sdk";
import type { Message } from "./Message";
import { OrderedSet } from "./ordered_array";

export type UsePeersParams = {
node: undefined | Waku;
Expand All @@ -20,10 +21,10 @@ export type UseMessagesParams = {
options: StoreQueryOptions;
};

export type UseMessagesResult = [Message[], (v: Message[]) => void];
export type UseMessagesResult = [OrderedSet<Message>, (v: Message[]) => void];

export interface ChatListProps {
messages: Message[];
messages: OrderedSet<Message>;
}

export interface MessageInputProps {
Expand All @@ -32,7 +33,7 @@ export interface MessageInputProps {
}

export interface RoomProps {
messages: Message[];
messages: OrderedSet<Message>;
commandHandler: (cmd: string) => void;
nick: string;
}

0 comments on commit b11300c

Please sign in to comment.