feat(core): update slash menu entries with quick search (#7167)
Close BS-351 refactor `Link` and `Linked Doc` entry with `quickSearchService`
This commit is contained in:
@@ -14,11 +14,12 @@ import type {
|
|||||||
import type { PeekViewService } from '@affine/core/modules/peek-view';
|
import type { PeekViewService } from '@affine/core/modules/peek-view';
|
||||||
import type { ActivePeekView } from '@affine/core/modules/peek-view/entities/peek-view';
|
import type { ActivePeekView } from '@affine/core/modules/peek-view/entities/peek-view';
|
||||||
import { DebugLogger } from '@affine/debug';
|
import { DebugLogger } from '@affine/debug';
|
||||||
import type { BlockSpec } from '@blocksuite/block-std';
|
import type { BlockSpec, WidgetElement } from '@blocksuite/block-std';
|
||||||
import type {
|
import {
|
||||||
AffineReference,
|
type AffineReference,
|
||||||
ParagraphBlockService,
|
AffineSlashMenuWidget,
|
||||||
RootService,
|
type ParagraphBlockService,
|
||||||
|
type RootService,
|
||||||
} from '@blocksuite/blocks';
|
} from '@blocksuite/blocks';
|
||||||
import { LitElement, type TemplateResult } from 'lit';
|
import { LitElement, type TemplateResult } from 'lit';
|
||||||
import React, { createElement, type ReactNode } from 'react';
|
import React, { createElement, type ReactNode } from 'react';
|
||||||
@@ -66,7 +67,8 @@ function patchSpecService<Spec extends BlockSpec>(
|
|||||||
service: Spec extends BlockSpec<any, infer BlockService>
|
service: Spec extends BlockSpec<any, infer BlockService>
|
||||||
? BlockService
|
? BlockService
|
||||||
: never
|
: never
|
||||||
) => (() => void) | void
|
) => (() => void) | void,
|
||||||
|
onWidgetConnected?: (component: WidgetElement) => void
|
||||||
) {
|
) {
|
||||||
const oldSetup = spec.setup;
|
const oldSetup = spec.setup;
|
||||||
spec.setup = (slots, disposableGroup) => {
|
spec.setup = (slots, disposableGroup) => {
|
||||||
@@ -79,6 +81,13 @@ function patchSpecService<Spec extends BlockSpec>(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
onWidgetConnected &&
|
||||||
|
disposableGroup.add(
|
||||||
|
slots.widgetConnected.on(({ component }) => {
|
||||||
|
onWidgetConnected(component);
|
||||||
|
})
|
||||||
|
);
|
||||||
};
|
};
|
||||||
return spec;
|
return spec;
|
||||||
}
|
}
|
||||||
@@ -271,45 +280,93 @@ export function patchQuickSearchService(
|
|||||||
return specs;
|
return specs;
|
||||||
}
|
}
|
||||||
|
|
||||||
patchSpecService(rootSpec, pageService => {
|
patchSpecService(
|
||||||
pageService.quickSearchService = {
|
rootSpec,
|
||||||
async searchDoc(options) {
|
pageService => {
|
||||||
let searchResult: SearchCallbackResult | null = null;
|
pageService.quickSearchService = {
|
||||||
if (options.skipSelection) {
|
async searchDoc(options) {
|
||||||
const query = options.userInput;
|
let searchResult: SearchCallbackResult | null = null;
|
||||||
if (!query) {
|
if (options.skipSelection) {
|
||||||
logger.error('No user input provided');
|
const query = options.userInput;
|
||||||
|
if (!query) {
|
||||||
|
logger.error('No user input provided');
|
||||||
|
} else {
|
||||||
|
const searchedDoc = service.quickSearch
|
||||||
|
.getSearchedDocs(query)
|
||||||
|
.at(0);
|
||||||
|
if (searchedDoc) {
|
||||||
|
searchResult = {
|
||||||
|
docId: searchedDoc.doc.id,
|
||||||
|
blockId: searchedDoc.blockId,
|
||||||
|
action: 'insert',
|
||||||
|
query,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const searchedDoc = service.quickSearch
|
searchResult = await service.quickSearch.search(options.userInput);
|
||||||
.getSearchedDocs(query)
|
}
|
||||||
.at(0);
|
|
||||||
if (searchedDoc) {
|
if (searchResult) {
|
||||||
searchResult = {
|
if ('docId' in searchResult) {
|
||||||
docId: searchedDoc.doc.id,
|
return searchResult;
|
||||||
blockId: searchedDoc.blockId,
|
} else {
|
||||||
|
return {
|
||||||
|
userInput: searchResult.query,
|
||||||
action: 'insert',
|
action: 'insert',
|
||||||
query,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
return null;
|
||||||
searchResult = await service.quickSearch.search(options.userInput);
|
},
|
||||||
}
|
};
|
||||||
|
},
|
||||||
|
(component: WidgetElement) => {
|
||||||
|
if (component instanceof AffineSlashMenuWidget) {
|
||||||
|
component.config.items.forEach(item => {
|
||||||
|
if (
|
||||||
|
'action' in item &&
|
||||||
|
(item.name === 'Linked Doc' || item.name === 'Link')
|
||||||
|
) {
|
||||||
|
const oldAction = item.action;
|
||||||
|
item.action = async ({ model, rootElement }) => {
|
||||||
|
const { host, service, std } = rootElement;
|
||||||
|
const { quickSearchService } = service;
|
||||||
|
|
||||||
if (searchResult) {
|
if (!quickSearchService) return oldAction({ model, rootElement });
|
||||||
if ('docId' in searchResult) {
|
|
||||||
return searchResult;
|
const result = await quickSearchService.searchDoc({});
|
||||||
} else {
|
if (result === null) return;
|
||||||
return {
|
|
||||||
userInput: searchResult.query,
|
if ('docId' in result) {
|
||||||
action: 'insert',
|
const linkedDoc = std.collection.getDoc(result.docId);
|
||||||
|
if (!linkedDoc) return;
|
||||||
|
|
||||||
|
host.doc.addSiblingBlocks(model, [
|
||||||
|
{
|
||||||
|
flavour: 'affine:embed-linked-doc',
|
||||||
|
pageId: linkedDoc.id,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
} else if ('userInput' in result) {
|
||||||
|
const embedOptions = service.getEmbedBlockOptions(
|
||||||
|
result.userInput
|
||||||
|
);
|
||||||
|
if (!embedOptions) return;
|
||||||
|
|
||||||
|
host.doc.addSiblingBlocks(model, [
|
||||||
|
{
|
||||||
|
flavour: embedOptions.flavour,
|
||||||
|
url: result.userInput,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
return null;
|
}
|
||||||
},
|
}
|
||||||
};
|
);
|
||||||
});
|
|
||||||
|
|
||||||
return specs;
|
return specs;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user