mirror of
https://github.com/Blah-IM/Weblah.git
synced 2025-08-21 03:22:40 +00:00
feat: [wip] search panel
This commit is contained in:
parent
1a1ac5cd43
commit
3ee0156d19
12 changed files with 179 additions and 43 deletions
|
@ -3,6 +3,7 @@ export type BlahPayloadSignee<P> = {
|
|||
payload: P;
|
||||
timestamp: number;
|
||||
user: string;
|
||||
act_key?: string;
|
||||
};
|
||||
|
||||
export type BlahSignedPayload<P> = {
|
||||
|
|
|
@ -2,7 +2,7 @@ import type { BlahSignedPayload } from '../crypto';
|
|||
import type { BlahMessage } from './message';
|
||||
|
||||
export type BlahRoomInfo = {
|
||||
ruuid: string;
|
||||
rid: string;
|
||||
title: string;
|
||||
last_chat?: BlahSignedPayload<BlahMessage>;
|
||||
};
|
||||
|
|
|
@ -13,8 +13,8 @@ export class ChatListManager {
|
|||
private sortChats(chatList: Chat[]) {
|
||||
chatList.sort(
|
||||
(a, b) =>
|
||||
(b.lastMessage?.date ?? new Date(1970, 0, 1)).getTime() ??
|
||||
-(a.lastMessage?.date ?? new Date(1970, 0, 1)).getTime()
|
||||
(b.lastMessage?.date ?? new Date(0)).getTime() ??
|
||||
-(a.lastMessage?.date ?? new Date(0)).getTime()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ export class ChatListManager {
|
|||
for (const chat of chats) {
|
||||
const newChat = chatFromBlah(chat, serverEndpoint);
|
||||
|
||||
const existing = chatList.find((c) => c.id === chat.ruuid);
|
||||
const existing = chatList.find((c) => c.id === newChat.id);
|
||||
if (existing) {
|
||||
existing.name = newChat.name;
|
||||
existing.lastMessage = newChat.lastMessage ?? existing.lastMessage;
|
||||
|
@ -43,7 +43,7 @@ export class ChatListManager {
|
|||
const chat = chatList.find((c) => c.id === message.signee.payload.room);
|
||||
if (chat) {
|
||||
const newChat = chatFromBlah(
|
||||
{ ruuid: chat.id, title: chat.name, last_chat: message },
|
||||
{ rid: chat.id, title: chat.name, last_chat: message },
|
||||
serverEndpoint
|
||||
);
|
||||
chat.lastMessage = newChat.lastMessage ?? chat.lastMessage;
|
||||
|
|
|
@ -5,6 +5,7 @@ import { BlahKeyPair, type EncodedBlahKeyPair } from './blah/crypto';
|
|||
import { currentKeyPair } from './keystore';
|
||||
import { ChatListManager } from './chatList';
|
||||
import { browser } from '$app/environment';
|
||||
import { GlobalSearchManager } from './globalSearch';
|
||||
|
||||
export const chatServers = persisted<string[]>('weblah-chat-servers', ['https://blah.oxa.li/api']);
|
||||
|
||||
|
@ -12,6 +13,7 @@ class ChatServerConnectionPool {
|
|||
private connections: Map<string, BlahChatServerConnection> = new Map();
|
||||
private keypair: BlahKeyPair | null = null;
|
||||
chatList: ChatListManager = new ChatListManager();
|
||||
searchManager: GlobalSearchManager = new GlobalSearchManager(this.connections);
|
||||
|
||||
constructor() {
|
||||
if (browser) {
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div
|
||||
<label
|
||||
class={tw(
|
||||
'flex items-center gap-1 rounded-md px-2 py-1.5 caret-accent-500 shadow-[inset_0_1px_2px_0_rgb(0_0_0/0.05)] ring-1 ring-ss-secondary',
|
||||
'flex items-center gap-1 rounded-md bg-sb-primary px-2 py-1.5 caret-accent-500 shadow-[inset_0_1px_2px_0_rgb(0_0_0/0.05)] ring-1 ring-ss-secondary transition-shadow duration-200 has-[input,textarea,[contenteditable]]:cursor-text has-[:focus]:ring-ss-primary',
|
||||
className
|
||||
)}
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</label>
|
||||
|
|
56
src/lib/globalSearch.ts
Normal file
56
src/lib/globalSearch.ts
Normal file
|
@ -0,0 +1,56 @@
|
|||
import type { BlahChatServerConnection } from './blah/connection/chatServer';
|
||||
import { chatFromBlah, type Chat } from './types';
|
||||
|
||||
export class GlobalSearchManager {
|
||||
private connections: Map<string, BlahChatServerConnection>;
|
||||
|
||||
constructor(connections: Map<string, BlahChatServerConnection>) {
|
||||
this.connections = connections;
|
||||
}
|
||||
|
||||
public async searchChats(query: string): Promise<{ joined: Chat[]; public: Chat[] }> {
|
||||
let jobs: Promise<['joined' | 'public', Chat[]]>[] = [];
|
||||
|
||||
for (const [endpoint, connection] of this.connections.entries()) {
|
||||
const fetchInJoinedRooms = async (): Promise<['joined' | 'public', Chat[]]> => [
|
||||
'joined',
|
||||
(await connection.fetchJoinedRooms()).map((r) => chatFromBlah(r, endpoint))
|
||||
];
|
||||
const fetchInPublicRooms = async (): Promise<['joined' | 'public', Chat[]]> => [
|
||||
'public',
|
||||
(await connection.discoverRooms()).map((r) => chatFromBlah(r, endpoint))
|
||||
];
|
||||
|
||||
jobs = jobs.concat([fetchInJoinedRooms(), fetchInPublicRooms()]);
|
||||
}
|
||||
|
||||
const results = await Promise.allSettled(jobs);
|
||||
console.log(results);
|
||||
|
||||
const chats: { joined: Chat[]; public: Chat[] } = { joined: [], public: [] };
|
||||
for (const result of results) {
|
||||
console.log(result);
|
||||
|
||||
if (result.status === 'rejected') continue;
|
||||
|
||||
const [type, chatList] = result.value;
|
||||
for (const chat of chatList) {
|
||||
if (!chat.name.includes(query)) continue; // TODO: Actual backend search
|
||||
if (chats[type].find((c) => c.id === chat.id)) continue; // Dedupe in its own type
|
||||
if (type !== 'joined' && chats.joined.find((c) => c.id === chat.id)) continue; // If already in joined, don't add to public
|
||||
|
||||
// Insert in last message date order
|
||||
const date = chat.lastMessage?.date;
|
||||
if (!date) {
|
||||
chats[type].push(chat);
|
||||
continue;
|
||||
}
|
||||
let idx = chats[type].findIndex((c) => (c.lastMessage ? c.lastMessage?.date < date : true));
|
||||
if (idx === -1) idx = 0;
|
||||
chats[type].splice(idx, 0, chat);
|
||||
}
|
||||
}
|
||||
|
||||
return chats;
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ export type Chat = {
|
|||
export function chatFromBlah(room: BlahRoomInfo, serverEndpoint: string): Chat {
|
||||
return {
|
||||
server: serverEndpoint,
|
||||
id: room.ruuid,
|
||||
id: room.rid,
|
||||
name: room.title,
|
||||
type: 'group',
|
||||
lastMessage: room.last_chat ? messageFromBlah(room.last_chat) : undefined
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue