Skip to content

Commit 587269b

Browse files
committed
Add sortedInsert utility for message inserts
1 parent 91e8ba4 commit 587269b

3 files changed

Lines changed: 38 additions & 4 deletions

File tree

src/stores/channel.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Channel, Message } from '#models';
2-
import { parseNick } from '#utils';
2+
import { parseNick, sortedInsert } from '#utils';
33
import { defineStore } from 'pinia';
44
import { computed, reactive, readonly, ref, watch } from 'vue';
55
import useIrcStore from './irc';
@@ -161,10 +161,9 @@ const useChannelStore = defineStore('channel', () => {
161161
tags: tags ?? {},
162162
};
163163
// TODO: Cap messages per channel (100)
164-
// TODO: Sort-insert messages based on `time` value
165164
// TODO: Prevent duplicate message insertions with `id` value
166165
log.debug('new message:', newMessage);
167-
channel.messages.push(newMessage);
166+
sortedInsert(channel.messages, newMessage, (a, b) => a.time - b.time);
168167

169168
if (typeof newMessage.tags.batch === 'string') {
170169
// Don't trigger notifications on chat history playback

src/stores/irc.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ const useIrcStore = defineStore('irc', () => {
6767

6868
const ircClient = new Client({
6969
host: import.meta.env.VITE_APP_SERVER_URL!,
70-
port: import.meta.env.VITE_APP_SERVER_PORT!,
70+
port: import.meta.env.VITE_APP_SERVER_PORT,
7171
ssl: import.meta.env.VITE_APP_SSL === 'true',
7272
nick,
7373
username: uid,

src/utils/list.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,38 @@
11
export function random<Item>(list: Item[]): Item {
22
return list[Math.floor(Math.random() * list.length)];
33
}
4+
5+
/**
6+
* @param list Assumed to be already sorted
7+
*/
8+
export function sortedInsert<Item>(
9+
list: Item[],
10+
item: Item,
11+
comparatorFn: (a: Item, b: Item) => number,
12+
): void {
13+
if (list.length === 0 || comparatorFn(item, list.at(-1)!) >= 0) {
14+
// Quickly insert if list is empty or item belongs at the end
15+
list.push(item);
16+
return;
17+
} else if (comparatorFn(item, list.at(0)!) < 0) {
18+
// Quickly insert if item belongs at the start
19+
list.unshift(item);
20+
return;
21+
}
22+
23+
// Find the insertion position if item belongs in the middle
24+
let low = 0;
25+
let high = list.length;
26+
while (low < high) {
27+
const mid = (low + high) >>> 1;
28+
29+
if (comparatorFn(item, list[mid]) < 0) {
30+
high = mid;
31+
} else {
32+
low = mid + 1;
33+
}
34+
}
35+
36+
// Insert item into found position
37+
list.splice(low, 0, item);
38+
}

0 commit comments

Comments
 (0)