feat: allow search for doc without showing modal (#7138)

depends on https://github.com/toeverything/blocksuite/pull/7199#pullrequestreview-2095567573

fix TOV-858, fix AFF-1132
This commit is contained in:
pengx17 2024-06-06 06:29:41 +00:00
parent 1439d00b61
commit 5bd9c7a2a3
No known key found for this signature in database
GPG Key ID: 23F23D9E8B3971ED
3 changed files with 99 additions and 9 deletions

View File

@ -208,9 +208,36 @@ export const BlocksuiteEdgelessEditor = forwardRef<
BlocksuiteEditorProps
>(function BlocksuiteEdgelessEditor({ page }, ref) {
const [specs, portals] = usePatchSpecs(page, EdgelessModeSpecs);
const editorRef = useRef<EdgelessEditor | null>(null);
const onDocRef = useCallback(
(el: EdgelessEditor) => {
editorRef.current = el;
if (ref) {
if (typeof ref === 'function') {
ref(el);
} else {
ref.current = el;
}
}
},
[ref]
);
useEffect(() => {
if (editorRef.current) {
editorRef.current.updateComplete
.then(() => {
// make sure editor can get keyboard events on showing up
editorRef.current?.querySelector('affine-edgeless-root')?.click();
})
.catch(console.error);
}
}, []);
return (
<>
<adapted.EdgelessEditor ref={ref} doc={page} specs={specs} />
<adapted.EdgelessEditor ref={onDocRef} doc={page} specs={specs} />
{portals}
</>
);

View File

@ -7,7 +7,10 @@ import {
type useConfirmModal,
type usePromptModal,
} from '@affine/component';
import type { QuickSearchService } from '@affine/core/modules/cmdk';
import type {
QuickSearchService,
SearchCallbackResult,
} from '@affine/core/modules/cmdk';
import type { PeekViewService } from '@affine/core/modules/peek-view';
import type { ActivePeekView } from '@affine/core/modules/peek-view/entities/peek-view';
import { DebugLogger } from '@affine/debug';
@ -254,13 +257,34 @@ export function patchQuickSearchService(
patchSpecService(rootSpec, pageService => {
pageService.quickSearchService = {
async searchDoc(options) {
const result = await service.quickSearch.search(options.userInput);
if (result) {
if ('docId' in result) {
return result;
let searchResult: SearchCallbackResult | null = null;
if (options.skipSelection) {
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 {
searchResult = await service.quickSearch.search(options.userInput);
}
if (searchResult) {
if ('docId' in searchResult) {
return searchResult;
} else {
return {
userInput: result.query,
userInput: searchResult.query,
action: 'insert',
};
}

View File

@ -1,4 +1,5 @@
import { test } from '@affine-test/kit/playwright';
import { clickEdgelessModeButton } from '@affine-test/kit/utils/editor';
import { withCtrlOrMeta } from '@affine-test/kit/utils/keyboard';
import { openHomePage } from '@affine-test/kit/utils/load-page';
import {
@ -467,7 +468,7 @@ test('disable quick search when the link-popup is visitable', async ({
await openQuickSearchByShortcut(page);
const quickSearch = page.locator('[data-testid=cmdk-quick-search]');
await expect(quickSearch).toBeVisible();
await withCtrlOrMeta(page, () => page.keyboard.press('k', { delay: 50 }));
await withCtrlOrMeta(page, () => page.keyboard.press('k'));
await getBlockSuiteEditorTitle(page).click();
await getBlockSuiteEditorTitle(page).fill(specialTitle);
@ -475,9 +476,47 @@ test('disable quick search when the link-popup is visitable', async ({
await page.keyboard.insertText('1234567890');
await page.getByText('1234567890').dblclick();
await withCtrlOrMeta(page, () => page.keyboard.press('k', { delay: 50 }));
await withCtrlOrMeta(page, () => page.keyboard.press('k'));
const linkPopup = page.locator('.affine-link-popover');
await expect(linkPopup).toBeVisible();
const currentQuickSearch = page.locator('[data-testid=cmdk-quick-search]');
await expect(currentQuickSearch).not.toBeVisible();
});
test('can use @ to open quick search to search for doc and insert into canvas', async ({
page,
}) => {
await openHomePage(page);
await waitForEditorLoad(page);
const url = page.url();
await clickNewPageButton(page);
await clickEdgelessModeButton(page);
await page.locator('affine-edgeless-root').press('@');
const quickSearch = page.locator('[data-testid=cmdk-quick-search]');
await expect(quickSearch).toBeVisible();
// search by using url
await insertInputText(page, url);
// expect the default page to be selected
await expect(page.locator('[cmdk-group-items] [cmdk-item]')).toHaveCount(1);
// press enter to insert the page to canvas
await page.keyboard.press('Enter');
await expect(page.locator('affine-embed-synced-doc-block')).toBeVisible();
await page.locator('affine-embed-synced-doc-block').click();
// change to linked card
await page.locator('edgeless-tool-icon-button.card').click();
await expect(
page.locator('.affine-embed-linked-doc-content-title')
).toContainText('Write, Draw, Plan all at Once');
// double clock to show peek view
await page.locator('affine-embed-linked-doc-block').dblclick();
await expect(page.getByTestId('peek-view-modal')).toBeVisible();
});