Skip to content

Commit

Permalink
Merge pull request #1541 from SnowCait/search-users
Browse files Browse the repository at this point in the history
Search users
  • Loading branch information
SnowCait authored Nov 27, 2024
2 parents 4422f8d + 57dd54e commit 3ba40c2
Show file tree
Hide file tree
Showing 8 changed files with 234 additions and 29 deletions.
11 changes: 9 additions & 2 deletions web/src/lib/RxNostrHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ export async function fetchLastEvent(filter: LazyFilter): Promise<Event | undefi
});
}

export async function fetchEvents(filters: LazyFilter[]): Promise<Event[]> {
export async function fetchEvents(
filters: LazyFilter[],
relays: string[] | undefined = undefined
): Promise<Event[]> {
const { promise, resolve } = Promise.withResolvers<Event[]>();
const events: Event[] = [];
const req = createRxBackwardReq();
Expand All @@ -68,7 +71,11 @@ export async function fetchEvents(filters: LazyFilter[]): Promise<Event[]> {
resolve(events);
}
});
req.emit(filters);
if (relays !== undefined && relays.length > 0) {
req.emit(filters, { relays });
} else {
req.emit(filters);
}
req.over();
return await promise;
}
6 changes: 1 addition & 5 deletions web/src/lib/Search.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { nip19, type Filter, Kind } from 'nostr-tools';
import { nip19, type Filter } from 'nostr-tools';
import { get } from 'svelte/store';
import { authorActionReqEmit } from './author/Action';
import { hashtagsRegexp, reverseChronological, searchRelays } from './Constants';
Expand Down Expand Up @@ -60,10 +60,6 @@ export class Search {
}
console.debug('[search matches]', fromPubkeys, toPubkeys, hashtags, kinds, since, until);

if (kinds.length === 0) {
kinds.push(Kind.Text);
}

const $pubkey = get(pubkey);
if (mine && !fromPubkeys.includes($pubkey)) {
fromPubkeys.push($pubkey);
Expand Down
4 changes: 3 additions & 1 deletion web/src/lib/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,9 @@
"search": "Search",
"options": "Search options",
"mine": "My notes",
"proxy": "Include external SNS notes"
"proxy": "Include external SNS notes",
"notes": "Notes",
"users": "Users"
},
"public_chat": {
"create_channel": "Create channel",
Expand Down
4 changes: 3 additions & 1 deletion web/src/lib/i18n/locales/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@
"search": "検索",
"options": "検索オプション",
"mine": "自分の投稿",
"proxy": "外部 SNS の投稿を含める"
"proxy": "外部 SNS の投稿を含める",
"notes": "投稿",
"users": "ユーザー"
},
"public_chat": {
"create_channel": "チャンネルを作成",
Expand Down
95 changes: 95 additions & 0 deletions web/src/lib/timelines/SearchTimeline.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { createRxBackwardReq, uniq, type LazyFilter } from 'rx-nostr';
import { filter, tap } from 'rxjs';
import { get, writable } from 'svelte/store';
import { authorActionReqEmit } from '$lib/author/Action';
import { minTimelineLength, searchRelays } from '$lib/Constants';
import { EventItem } from '$lib/Items';
import { fetchEvents } from '$lib/RxNostrHelper';
import { referencesReqEmit, rxNostr } from './MainTimeline';
import type { Timeline } from './Timeline';
import { oldestCreatedAt } from './TimelineHelper';

export class SearchTimeline implements Timeline {
items = writable<EventItem[]>([]);
#completed = false;

constructor(public readonly filter: LazyFilter) {}

subscribe(): void {
console.debug('[search timeline subscribe]', this.filter);
}

unsubscribe(): void {
console.debug('[search timeline unsubscribe]', this.filter);
this.items.set([]);
}

async load(): Promise<void> {
if (this.#completed) {
return;
}

console.debug('[search timeline load]', this.filter);
const $items = get(this.items);
const firstLength = $items.length;
const filterBase = { ...this.filter };
const { promise, resolve } = Promise.withResolvers<void>();
const req = createRxBackwardReq();
rxNostr
.use(req)
.pipe(
uniq(),
filter(({ event }) => !$items.some((item) => item.event.id === event.id)),
tap(({ event }) => {
referencesReqEmit(event);
authorActionReqEmit(event);
})
)
.subscribe({
next: ({ event }) => {
console.debug('[search next]', event);
const item = new EventItem(event);
const index = $items.findIndex(
(x) => x.event.created_at < item.event.created_at
);
if (index < 0) {
$items.push(item);
} else {
$items.splice(index, 0, item);
}
this.items.set($items);
},
complete: () => {
console.debug('[search complete]', firstLength, $items.length);
resolve();
}
});
const until = oldestCreatedAt($items);
req.emit([{ ...filterBase, until, since: until - 15 * 60 }], { relays: searchRelays });
req.over();
await promise;

const length = $items.length - firstLength;
if (length < minTimelineLength) {
const limit = minTimelineLength - length;
const events = await fetchEvents(
[{ ...filterBase, until: oldestCreatedAt($items), limit }],
searchRelays
);
const _items = events
.filter((event) => !$items.some((item) => item.event.id === event.id))
.splice(0, limit)
.map((event) => new EventItem(event));
if (_items.length === 0) {
this.#completed = true;
}
$items.push(..._items);
this.items.set($items);
}
console.log('[search loaded]', firstLength, $items.length);
}

get completed() {
return this.#completed;
}
}
6 changes: 6 additions & 0 deletions web/src/lib/timelines/TimelineHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ export function insertIntoAscendingTimeline(event: NostrEvent, items: EventItem[
items.splice(index, 0, item);
}
}

export function oldestCreatedAt(items: EventItem[]): number {
return items.length > 0
? items[items.length - 1].event.created_at
: Math.floor(Date.now() / 1000);
}
10 changes: 5 additions & 5 deletions web/src/routes/(app)/channels/[nevent=note]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import PinChannel from './PinChannel.svelte';
import ChannelTitle from '$lib/components/ChannelTitle.svelte';
import MuteButton from '$lib/components/MuteButton.svelte';
import { oldestCreatedAt } from '$lib/timelines/TimelineHelper';
let slug = $page.params.nevent;
let channelId: string;
Expand Down Expand Up @@ -148,9 +149,6 @@
$channelIdStore = undefined;
});
const oldestCreatedAt = (): number =>
items.length > 0 ? items[items.length - 1].event.created_at : Math.floor(Date.now() / 1000);
async function load() {
console.log('[channel page load]', slug, channelId);
if (channelId === undefined) {
Expand Down Expand Up @@ -189,15 +187,17 @@
resolve();
}
});
const until = oldestCreatedAt();
const until = oldestCreatedAt(items);
req.emit([{ ...filterBase, until, since: until - 15 * 60 }]);
req.over();
await promise;
const length = items.length - firstLength;
if (length < minTimelineLength) {
const limit = minTimelineLength - length;
const events = await fetchEvents([{ ...filterBase, until: oldestCreatedAt(), limit }]);
const events = await fetchEvents([
{ ...filterBase, until: oldestCreatedAt(items), limit }
]);
items.push(
...events
.filter((event) => !items.some((item) => item.event.id === event.id))
Expand Down
Loading

0 comments on commit 3ba40c2

Please sign in to comment.