fix: cloud workspace search prefer & highlights
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { toDocSearchParams } from '@affine/core/modules/navigation';
|
import { toDocSearchParams } from '@affine/core/modules/navigation';
|
||||||
import type { IndexerSyncState } from '@affine/nbstore';
|
import type { IndexerPreferOptions, IndexerSyncState } from '@affine/nbstore';
|
||||||
import type { ReferenceParams } from '@blocksuite/affine/model';
|
import type { ReferenceParams } from '@blocksuite/affine/model';
|
||||||
import { fromPromise, LiveData, Service } from '@toeverything/infra';
|
import { fromPromise, LiveData, Service } from '@toeverything/infra';
|
||||||
import { isEmpty, omit } from 'lodash-es';
|
import { isEmpty, omit } from 'lodash-es';
|
||||||
@@ -26,6 +26,24 @@ export class DocsSearchService extends Service {
|
|||||||
errorMessage: null,
|
errorMessage: null,
|
||||||
} as IndexerSyncState);
|
} as IndexerSyncState);
|
||||||
|
|
||||||
|
private normalizeHighlight(value?: string | null) {
|
||||||
|
if (!value) {
|
||||||
|
return value ?? '';
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(value);
|
||||||
|
if (Array.isArray(parsed)) {
|
||||||
|
return parsed.join(' ');
|
||||||
|
}
|
||||||
|
if (typeof parsed === 'string') {
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// ignore parse errors, return raw value
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
searchTitle$(query: string) {
|
searchTitle$(query: string) {
|
||||||
return this.indexer
|
return this.indexer
|
||||||
.search$(
|
.search$(
|
||||||
@@ -49,7 +67,10 @@ export class DocsSearchService extends Service {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
search$(query: string): Observable<
|
search$(
|
||||||
|
query: string,
|
||||||
|
prefer: IndexerPreferOptions = 'remote'
|
||||||
|
): Observable<
|
||||||
{
|
{
|
||||||
docId: string;
|
docId: string;
|
||||||
title: string;
|
title: string;
|
||||||
@@ -112,7 +133,7 @@ export class DocsSearchService extends Service {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
prefer: 'remote',
|
prefer,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.pipe(
|
.pipe(
|
||||||
@@ -123,10 +144,14 @@ export class DocsSearchService extends Service {
|
|||||||
const firstMatchFlavour = bucket.hits.nodes[0]?.fields.flavour;
|
const firstMatchFlavour = bucket.hits.nodes[0]?.fields.flavour;
|
||||||
if (firstMatchFlavour === 'affine:page') {
|
if (firstMatchFlavour === 'affine:page') {
|
||||||
// is title match
|
// is title match
|
||||||
const blockContent = bucket.hits.nodes[1]?.highlights.content[0]; // try to get block content
|
const blockContent = this.normalizeHighlight(
|
||||||
|
bucket.hits.nodes[1]?.highlights.content[0]
|
||||||
|
); // try to get block content
|
||||||
result.push({
|
result.push({
|
||||||
docId: bucket.key,
|
docId: bucket.key,
|
||||||
title: bucket.hits.nodes[0].highlights.content[0],
|
title: this.normalizeHighlight(
|
||||||
|
bucket.hits.nodes[0].highlights.content[0]
|
||||||
|
),
|
||||||
score: bucket.score,
|
score: bucket.score,
|
||||||
blockContent,
|
blockContent,
|
||||||
});
|
});
|
||||||
@@ -144,7 +169,9 @@ export class DocsSearchService extends Service {
|
|||||||
? matchedBlockId
|
? matchedBlockId
|
||||||
: matchedBlockId[0],
|
: matchedBlockId[0],
|
||||||
score: bucket.score,
|
score: bucket.score,
|
||||||
blockContent: bucket.hits.nodes[0]?.highlights.content[0],
|
blockContent: this.normalizeHighlight(
|
||||||
|
bucket.hits.nodes[0]?.highlights.content[0]
|
||||||
|
),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,8 +107,43 @@ export class DocsQuickSearchSession
|
|||||||
if (!query) {
|
if (!query) {
|
||||||
out = of([] as QuickSearchItem<'docs', DocsPayload>[]);
|
out = of([] as QuickSearchItem<'docs', DocsPayload>[]);
|
||||||
} else {
|
} else {
|
||||||
out = this.docsSearchService.search$(query).pipe(
|
const preferRemote =
|
||||||
map(docs =>
|
!this.searchLocally && this.isSupportServerIndexer();
|
||||||
|
const preferMode =
|
||||||
|
this.searchLocally || !this.isSupportServerIndexer()
|
||||||
|
? 'local'
|
||||||
|
: 'remote';
|
||||||
|
const search$ = preferRemote
|
||||||
|
? this.docsSearchService.search$(query, 'remote').pipe(
|
||||||
|
switchMap(docs => {
|
||||||
|
if (docs.length > 0) {
|
||||||
|
return of({ docs, useLocalLabel: false });
|
||||||
|
}
|
||||||
|
return this.docsSearchService.search$(query, 'local').pipe(
|
||||||
|
map(localDocs => ({
|
||||||
|
docs: localDocs,
|
||||||
|
useLocalLabel: true,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
catchError(() =>
|
||||||
|
this.docsSearchService.search$(query, 'local').pipe(
|
||||||
|
map(localDocs => ({
|
||||||
|
docs: localDocs,
|
||||||
|
useLocalLabel: true,
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
: this.docsSearchService.search$(query, preferMode).pipe(
|
||||||
|
map(docs => ({
|
||||||
|
docs,
|
||||||
|
useLocalLabel: preferMode === 'local',
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
out = search$.pipe(
|
||||||
|
map(({ docs, useLocalLabel }) =>
|
||||||
docs
|
docs
|
||||||
.map(doc => {
|
.map(doc => {
|
||||||
const docRecord = this.docsService.list.doc$(doc.docId).value;
|
const docRecord = this.docsService.list.doc$(doc.docId).value;
|
||||||
@@ -126,7 +161,7 @@ export class DocsQuickSearchSession
|
|||||||
group: {
|
group: {
|
||||||
id: 'docs',
|
id: 'docs',
|
||||||
label: {
|
label: {
|
||||||
i18nKey: this.searchLocally
|
i18nKey: useLocalLabel
|
||||||
? 'com.affine.quicksearch.group.searchfor-locally'
|
? 'com.affine.quicksearch.group.searchfor-locally'
|
||||||
: 'com.affine.quicksearch.group.searchfor',
|
: 'com.affine.quicksearch.group.searchfor',
|
||||||
options: { query: truncate(query) },
|
options: { query: truncate(query) },
|
||||||
|
|||||||
Reference in New Issue
Block a user