mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 11:29:46 +00:00
Merge branch 'fix-search-profile-pagination' into 'main'
fix: search profiles with offset pagination See merge request soapbox-pub/ditto!564
This commit is contained in:
commit
2b4efd6a03
4 changed files with 32 additions and 10 deletions
|
|
@ -136,7 +136,7 @@ const accountSearchController: AppController = async (c) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const followedPubkeys: Set<string> = viewerPubkey ? await getFollowedPubkeys(viewerPubkey) : new Set();
|
const followedPubkeys: Set<string> = viewerPubkey ? await getFollowedPubkeys(viewerPubkey) : new Set();
|
||||||
const pubkeys = Array.from(await getPubkeysBySearch(kysely, { q: query, limit, followedPubkeys }));
|
const pubkeys = Array.from(await getPubkeysBySearch(kysely, { q: query, limit, offset: 0, followedPubkeys }));
|
||||||
|
|
||||||
let events = event ? [event] : await store.query([{ kinds: [0], authors: pubkeys, limit }], {
|
let events = event ? [event] : await store.query([{ kinds: [0], authors: pubkeys, limit }], {
|
||||||
signal,
|
signal,
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ const searchQuerySchema = z.object({
|
||||||
following: z.boolean().default(false),
|
following: z.boolean().default(false),
|
||||||
account_id: n.id().optional(),
|
account_id: n.id().optional(),
|
||||||
limit: z.coerce.number().catch(20).transform((value) => Math.min(Math.max(value, 0), 40)),
|
limit: z.coerce.number().catch(20).transform((value) => Math.min(Math.max(value, 0), 40)),
|
||||||
|
offset: z.coerce.number().nonnegative().catch(0),
|
||||||
});
|
});
|
||||||
|
|
||||||
type SearchQuery = z.infer<typeof searchQuerySchema>;
|
type SearchQuery = z.infer<typeof searchQuerySchema>;
|
||||||
|
|
@ -77,7 +78,7 @@ const searchController: AppController = async (c) => {
|
||||||
|
|
||||||
/** Get events for the search params. */
|
/** Get events for the search params. */
|
||||||
async function searchEvents(
|
async function searchEvents(
|
||||||
{ q, type, limit, account_id, viewerPubkey }: SearchQuery & { viewerPubkey?: string },
|
{ q, type, limit, offset, account_id, viewerPubkey }: SearchQuery & { viewerPubkey?: string },
|
||||||
signal: AbortSignal,
|
signal: AbortSignal,
|
||||||
): Promise<NostrEvent[]> {
|
): Promise<NostrEvent[]> {
|
||||||
// Hashtag search is not supported.
|
// Hashtag search is not supported.
|
||||||
|
|
@ -98,7 +99,7 @@ async function searchEvents(
|
||||||
const kysely = await Storages.kysely();
|
const kysely = await Storages.kysely();
|
||||||
|
|
||||||
const followedPubkeys = viewerPubkey ? await getFollowedPubkeys(viewerPubkey) : new Set<string>();
|
const followedPubkeys = viewerPubkey ? await getFollowedPubkeys(viewerPubkey) : new Set<string>();
|
||||||
const searchPubkeys = await getPubkeysBySearch(kysely, { q, limit, followedPubkeys });
|
const searchPubkeys = await getPubkeysBySearch(kysely, { q, limit, offset, followedPubkeys });
|
||||||
|
|
||||||
filter.authors = [...searchPubkeys];
|
filter.authors = [...searchPubkeys];
|
||||||
filter.search = undefined;
|
filter.search = undefined;
|
||||||
|
|
|
||||||
|
|
@ -14,17 +14,37 @@ Deno.test('fuzzy search works', async () => {
|
||||||
following_count: 0,
|
following_count: 0,
|
||||||
}).execute();
|
}).execute();
|
||||||
|
|
||||||
assertEquals(await getPubkeysBySearch(db.kysely, { q: 'pat rick', limit: 1, followedPubkeys: new Set() }), new Set());
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
await getPubkeysBySearch(db.kysely, { q: 'patrick dosreis', limit: 1, followedPubkeys: new Set() }),
|
await getPubkeysBySearch(db.kysely, { q: 'pat rick', limit: 1, offset: 0, followedPubkeys: new Set() }),
|
||||||
|
new Set(),
|
||||||
|
);
|
||||||
|
assertEquals(
|
||||||
|
await getPubkeysBySearch(db.kysely, { q: 'patrick dosreis', limit: 1, offset: 0, followedPubkeys: new Set() }),
|
||||||
new Set([
|
new Set([
|
||||||
'47259076c85f9240e852420d7213c95e95102f1de929fb60f33a2c32570c98c4',
|
'47259076c85f9240e852420d7213c95e95102f1de929fb60f33a2c32570c98c4',
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
await getPubkeysBySearch(db.kysely, { q: 'dosreis.com', limit: 1, followedPubkeys: new Set() }),
|
await getPubkeysBySearch(db.kysely, { q: 'dosreis.com', limit: 1, offset: 0, followedPubkeys: new Set() }),
|
||||||
new Set([
|
new Set([
|
||||||
'47259076c85f9240e852420d7213c95e95102f1de929fb60f33a2c32570c98c4',
|
'47259076c85f9240e852420d7213c95e95102f1de929fb60f33a2c32570c98c4',
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.test('fuzzy search works with offset', async () => {
|
||||||
|
await using db = await createTestDB();
|
||||||
|
|
||||||
|
await db.kysely.insertInto('author_stats').values({
|
||||||
|
pubkey: '47259076c85f9240e852420d7213c95e95102f1de929fb60f33a2c32570c98c4',
|
||||||
|
search: 'abdcef patrickReiis patrickdosreis.com',
|
||||||
|
notes_count: 0,
|
||||||
|
followers_count: 0,
|
||||||
|
following_count: 0,
|
||||||
|
}).execute();
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
await getPubkeysBySearch(db.kysely, { q: 'dosreis.com', limit: 1, offset: 1, followedPubkeys: new Set() }),
|
||||||
|
new Set(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@ import { DittoTables } from '@/db/DittoTables.ts';
|
||||||
/** Get pubkeys whose name and NIP-05 is similar to 'q' */
|
/** Get pubkeys whose name and NIP-05 is similar to 'q' */
|
||||||
export async function getPubkeysBySearch(
|
export async function getPubkeysBySearch(
|
||||||
kysely: Kysely<DittoTables>,
|
kysely: Kysely<DittoTables>,
|
||||||
opts: { q: string; limit: number; followedPubkeys: Set<string> },
|
opts: { q: string; limit: number; offset: number; followedPubkeys: Set<string> },
|
||||||
): Promise<Set<string>> {
|
): Promise<Set<string>> {
|
||||||
const { q, limit, followedPubkeys } = opts;
|
const { q, limit, followedPubkeys, offset } = opts;
|
||||||
|
|
||||||
let query = kysely
|
let query = kysely
|
||||||
.selectFrom('author_stats')
|
.selectFrom('author_stats')
|
||||||
|
|
@ -19,7 +19,8 @@ export async function getPubkeysBySearch(
|
||||||
.where(() => sql`${q} <% search`)
|
.where(() => sql`${q} <% search`)
|
||||||
.orderBy(['followers_count desc'])
|
.orderBy(['followers_count desc'])
|
||||||
.orderBy(['sml desc', 'search'])
|
.orderBy(['sml desc', 'search'])
|
||||||
.limit(limit);
|
.limit(limit)
|
||||||
|
.offset(offset);
|
||||||
|
|
||||||
const pubkeys = new Set((await query.execute()).map(({ pubkey }) => pubkey));
|
const pubkeys = new Set((await query.execute()).map(({ pubkey }) => pubkey));
|
||||||
|
|
||||||
|
|
@ -29,5 +30,5 @@ export async function getPubkeysBySearch(
|
||||||
|
|
||||||
const followingPubkeys = new Set((await query.execute()).map(({ pubkey }) => pubkey));
|
const followingPubkeys = new Set((await query.execute()).map(({ pubkey }) => pubkey));
|
||||||
|
|
||||||
return new Set(Array.from(followingPubkeys.union(pubkeys)).slice(0, limit));
|
return new Set(Array.from(followingPubkeys.union(pubkeys)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue