feat(api,userbot,frontend): search peers without chats and start tracking them
This commit is contained in:
1 parent
dcf95bd9d4
commit
92fd20137e
21 files changed
+936
-65
No files matched your search
@@ -0,0 +1,41 @@
|
||||
import { getDiscoverItem } from "$lib/api/endpoints";
|
||||
import type { DiscoverItem } from "$lib/api/types";
|
||||
import { accounts } from "$lib/stores/accounts.svelte";
|
||||
|
||||
function createDiscover() {
|
||||
let items = $state<Record<number, DiscoverItem>>({});
|
||||
let account: number | null = null;
|
||||
const pending = new Set<number>();
|
||||
|
||||
function syncAccount() {
|
||||
if (accounts.selectedId !== account) {
|
||||
account = accounts.selectedId;
|
||||
items = {};
|
||||
pending.clear();
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
get(chatId: number): DiscoverItem | undefined {
|
||||
return items[chatId];
|
||||
},
|
||||
set(item: DiscoverItem) {
|
||||
items = { ...items, [item.chat_id]: item };
|
||||
},
|
||||
async ensure(chatId: number) {
|
||||
syncAccount();
|
||||
if (account === null || items[chatId] || pending.has(chatId)) {
|
||||
return;
|
||||
}
|
||||
pending.add(chatId);
|
||||
try {
|
||||
const item = await getDiscoverItem(chatId);
|
||||
items = { ...items, [chatId]: item };
|
||||
} finally {
|
||||
pending.delete(chatId);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const discover = createDiscover();
|
||||
@@ -1,16 +1,18 @@
|
||||
import { searchMessages } from "$lib/api/endpoints";
|
||||
import type { SearchHit } from "$lib/api/types";
|
||||
import { discoverPeers, searchMessages } from "$lib/api/endpoints";
|
||||
import type { DiscoverItem, SearchHit } from "$lib/api/types";
|
||||
import { chats } from "$lib/stores/chats.svelte";
|
||||
|
||||
const DEBOUNCE_MS = 250;
|
||||
const REMOTE_DEBOUNCE_MS = 700;
|
||||
const MIN_LENGTH = 1;
|
||||
|
||||
function createSearch() {
|
||||
let active = $state(false);
|
||||
let query = $state("");
|
||||
let messageHits = $state<SearchHit[]>([]);
|
||||
let peerResults = $state<DiscoverItem[]>([]);
|
||||
let loading = $state(false);
|
||||
let timer: ReturnType<typeof setTimeout> | null = null;
|
||||
let timers: ReturnType<typeof setTimeout>[] = [];
|
||||
let seq = 0;
|
||||
|
||||
const trimmed = $derived(query.trim());
|
||||
@@ -23,9 +25,12 @@ function createSearch() {
|
||||
(chat.title ?? "").toLowerCase().includes(needle)
|
||||
);
|
||||
});
|
||||
const peerHits = $derived.by(() => {
|
||||
const shown = new Set(chatHits.map((chat) => chat.chat_id));
|
||||
return peerResults.filter((item) => !shown.has(item.chat_id));
|
||||
});
|
||||
|
||||
async function run(value: string) {
|
||||
const current = ++seq;
|
||||
async function runMessages(value: string, current: number) {
|
||||
try {
|
||||
const hits = await searchMessages(value);
|
||||
if (current === seq) {
|
||||
@@ -42,21 +47,46 @@ function createSearch() {
|
||||
}
|
||||
}
|
||||
|
||||
function schedule() {
|
||||
if (timer) {
|
||||
async function runPeers(value: string, current: number, remote: boolean) {
|
||||
try {
|
||||
const items = await discoverPeers(value, remote);
|
||||
if (current === seq) {
|
||||
peerResults = items;
|
||||
}
|
||||
} catch {
|
||||
if (current === seq && !remote) {
|
||||
peerResults = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function clearTimers() {
|
||||
for (const timer of timers) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
timers = [];
|
||||
}
|
||||
|
||||
function schedule() {
|
||||
clearTimers();
|
||||
const value = trimmed;
|
||||
const current = ++seq;
|
||||
if (value.length < MIN_LENGTH) {
|
||||
seq++;
|
||||
messageHits = [];
|
||||
peerResults = [];
|
||||
loading = false;
|
||||
return;
|
||||
}
|
||||
loading = true;
|
||||
timer = setTimeout(() => {
|
||||
run(value).catch(() => undefined);
|
||||
}, DEBOUNCE_MS);
|
||||
timers.push(
|
||||
setTimeout(() => {
|
||||
runMessages(value, current).catch(() => undefined);
|
||||
runPeers(value, current, false).catch(() => undefined);
|
||||
}, DEBOUNCE_MS),
|
||||
setTimeout(() => {
|
||||
runPeers(value, current, true).catch(() => undefined);
|
||||
}, REMOTE_DEBOUNCE_MS)
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -78,6 +108,9 @@ function createSearch() {
|
||||
get chatHits() {
|
||||
return chatHits;
|
||||
},
|
||||
get peerHits() {
|
||||
return peerHits;
|
||||
},
|
||||
open() {
|
||||
active = true;
|
||||
},
|
||||
@@ -89,11 +122,10 @@ function createSearch() {
|
||||
active = false;
|
||||
query = "";
|
||||
messageHits = [];
|
||||
peerResults = [];
|
||||
loading = false;
|
||||
seq++;
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
clearTimers();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user