mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-11 20:08:37 +00:00
chore: bump blocksuite (#8230)
## 0.17.11
### Patch Changes
- [3c61be5](3c61be5ded): - Refactor drag handle widget
- Split embed blocks to `@blocksuite/affine-block-embed`
- Fix latex selected state in edgeless mode
- Fix unclear naming
- Fix prototype pollution
- Fix portal interaction in affine modal
- Fix paste linked block on edgeless
- Add scroll anchoring widget
- Add highlight selection
This commit is contained in:
@@ -28,7 +28,7 @@
|
||||
"@affine/core": "workspace:*",
|
||||
"@affine/i18n": "workspace:*",
|
||||
"@affine/native": "workspace:*",
|
||||
"@blocksuite/global": "0.17.10",
|
||||
"@blocksuite/global": "0.17.11",
|
||||
"@electron-forge/cli": "^7.3.0",
|
||||
"@electron-forge/core": "^7.3.0",
|
||||
"@electron-forge/core-utils": "^7.3.0",
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"@affine/component": "workspace:*",
|
||||
"@affine/core": "workspace:*",
|
||||
"@affine/i18n": "workspace:*",
|
||||
"@blocksuite/blocks": "0.17.10",
|
||||
"@blocksuite/blocks": "0.17.11",
|
||||
"@blocksuite/icons": "^2.1.67",
|
||||
"@sentry/react": "^8.0.0",
|
||||
"react": "^18.2.0",
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
"zod": "^3.22.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@blocksuite/global": "0.17.10",
|
||||
"@blocksuite/global": "0.17.11",
|
||||
"@blocksuite/icons": "2.1.67",
|
||||
"@chromatic-com/storybook": "^2.0.0",
|
||||
"@storybook/addon-essentials": "^8.2.9",
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
"@affine/i18n": "workspace:*",
|
||||
"@affine/templates": "workspace:*",
|
||||
"@affine/track": "workspace:*",
|
||||
"@blocksuite/block-std": "0.17.10",
|
||||
"@blocksuite/blocks": "0.17.10",
|
||||
"@blocksuite/global": "0.17.10",
|
||||
"@blocksuite/block-std": "0.17.11",
|
||||
"@blocksuite/blocks": "0.17.11",
|
||||
"@blocksuite/global": "0.17.11",
|
||||
"@blocksuite/icons": "2.1.67",
|
||||
"@blocksuite/inline": "0.17.10",
|
||||
"@blocksuite/presets": "0.17.10",
|
||||
"@blocksuite/store": "0.17.10",
|
||||
"@blocksuite/inline": "0.17.11",
|
||||
"@blocksuite/presets": "0.17.11",
|
||||
"@blocksuite/store": "0.17.11",
|
||||
"@dnd-kit/core": "^6.1.0",
|
||||
"@dnd-kit/modifiers": "^7.0.0",
|
||||
"@dnd-kit/sortable": "^8.0.0",
|
||||
|
||||
@@ -34,7 +34,6 @@ import type {
|
||||
DocMode,
|
||||
DocModeProvider,
|
||||
QuickSearchResult,
|
||||
ReferenceParams,
|
||||
RootService,
|
||||
} from '@blocksuite/blocks';
|
||||
import {
|
||||
@@ -42,12 +41,10 @@ import {
|
||||
DocModeExtension,
|
||||
EdgelessRootBlockComponent,
|
||||
EmbedLinkedDocBlockComponent,
|
||||
EmbedOptionProvider,
|
||||
NotificationExtension,
|
||||
ParseDocUrlExtension,
|
||||
PeekViewExtension,
|
||||
QuickSearchExtension,
|
||||
QuickSearchProvider,
|
||||
ReferenceNodeConfigExtension,
|
||||
} from '@blocksuite/blocks';
|
||||
import { AIChatBlockSchema } from '@blocksuite/presets';
|
||||
@@ -62,6 +59,7 @@ import {
|
||||
import { type TemplateResult } from 'lit';
|
||||
import { customElement } from 'lit/decorators.js';
|
||||
import { literal } from 'lit/static-html.js';
|
||||
import { pick } from 'lodash-es';
|
||||
|
||||
export type ReferenceReactRenderer = (
|
||||
reference: AffineReference
|
||||
@@ -318,14 +316,13 @@ export function patchQuickSearchService(framework: FrameworkProvider) {
|
||||
}
|
||||
|
||||
if (result.source === 'link') {
|
||||
const { docId, blockIds, elementIds, mode } = result.payload;
|
||||
resolve({
|
||||
docId,
|
||||
params: {
|
||||
blockIds,
|
||||
elementIds,
|
||||
mode,
|
||||
},
|
||||
docId: result.payload.docId,
|
||||
params: pick(result.payload, [
|
||||
'mode',
|
||||
'blockIds',
|
||||
'elementIds',
|
||||
]),
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -349,13 +346,8 @@ export function patchQuickSearchService(framework: FrameworkProvider) {
|
||||
primaryMode: mode,
|
||||
docProps,
|
||||
});
|
||||
track.doc.editor.quickSearch.createDoc({
|
||||
mode,
|
||||
});
|
||||
|
||||
resolve({
|
||||
docId: newDoc.id,
|
||||
});
|
||||
resolve({ docId: newDoc.id });
|
||||
return;
|
||||
}
|
||||
},
|
||||
@@ -373,6 +365,7 @@ export function patchQuickSearchService(framework: FrameworkProvider) {
|
||||
return searchResult;
|
||||
},
|
||||
});
|
||||
|
||||
const SlashMenuQuickSearchExtension = patchSpecService<RootService>(
|
||||
'affine:page',
|
||||
() => {},
|
||||
@@ -383,51 +376,38 @@ export function patchQuickSearchService(framework: FrameworkProvider) {
|
||||
'action' in item &&
|
||||
(item.name === 'Linked Doc' || item.name === 'Link')
|
||||
) {
|
||||
const oldAction = item.action;
|
||||
item.action = async ({ model, rootComponent }) => {
|
||||
const { host, std } = rootComponent;
|
||||
const quickSearchService =
|
||||
component.std.getOptional(QuickSearchProvider);
|
||||
item.action = async ({ rootComponent }) => {
|
||||
// TODO(@Mirone): fix the type
|
||||
// @ts-expect-error fixme
|
||||
const { success, insertedLinkType } =
|
||||
// @ts-expect-error fixme
|
||||
rootComponent.std.command.exec('insertLinkByQuickSearch');
|
||||
|
||||
if (!quickSearchService)
|
||||
return oldAction({ model, rootComponent });
|
||||
if (!success) return;
|
||||
|
||||
const result = await quickSearchService.openQuickSearch();
|
||||
if (result === null) return;
|
||||
// TODO(@Mirone): fix the type
|
||||
insertedLinkType
|
||||
?.then(
|
||||
(type: {
|
||||
flavour?: 'affine:embed-linked-doc' | 'affine:bookmark';
|
||||
}) => {
|
||||
const flavour = type?.flavour;
|
||||
if (!flavour) return;
|
||||
|
||||
if ('docId' in result) {
|
||||
const linkedDoc = std.collection.getDoc(result.docId);
|
||||
if (!linkedDoc) return;
|
||||
if (flavour === 'affine:embed-linked-doc') {
|
||||
track.doc.editor.slashMenu.linkDoc({
|
||||
control: 'linkDoc',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const props: {
|
||||
flavour: string;
|
||||
pageId: string;
|
||||
params?: ReferenceParams;
|
||||
} = {
|
||||
flavour: 'affine:embed-linked-doc',
|
||||
pageId: linkedDoc.id,
|
||||
};
|
||||
|
||||
if (result.params) {
|
||||
props.params = result.params;
|
||||
}
|
||||
|
||||
host.doc.addSiblingBlocks(model, [props]);
|
||||
|
||||
track.doc.editor.slashMenu.linkDoc({ control: 'linkDoc' });
|
||||
} else if (result.externalUrl) {
|
||||
const embedOptions = std
|
||||
.get(EmbedOptionProvider)
|
||||
.getEmbedBlockOptions(result.externalUrl);
|
||||
if (!embedOptions) return;
|
||||
|
||||
host.doc.addSiblingBlocks(model, [
|
||||
{
|
||||
flavour: embedOptions.flavour,
|
||||
url: result.externalUrl,
|
||||
},
|
||||
]);
|
||||
}
|
||||
if (flavour === 'affine:bookmark') {
|
||||
track.doc.editor.slashMenu.bookmark();
|
||||
return;
|
||||
}
|
||||
}
|
||||
)
|
||||
.catch(console.error);
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -16,7 +16,10 @@ import {
|
||||
WorkspaceService,
|
||||
} from '@toeverything/infra';
|
||||
|
||||
export function createLinkedWidgetConfig(framework: FrameworkProvider) {
|
||||
// TODO: fix the type
|
||||
export function createLinkedWidgetConfig(
|
||||
framework: FrameworkProvider
|
||||
): Partial<Record<string, unknown>> {
|
||||
return {
|
||||
getMenus: (
|
||||
query: string,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { notify } from '@affine/component';
|
||||
import { getAffineCloudBaseUrl } from '@affine/core/modules/cloud/services/fetch';
|
||||
import { toURLSearchParams } from '@affine/core/utils';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { track } from '@affine/track';
|
||||
import { type EditorHost } from '@blocksuite/block-std';
|
||||
@@ -34,20 +35,14 @@ export const generateUrl = ({
|
||||
if (!baseUrl) return null;
|
||||
|
||||
try {
|
||||
const url = new URL(`${baseUrl}/workspace/${workspaceId}/${pageId}`);
|
||||
const search = url.searchParams;
|
||||
if (shareMode) {
|
||||
search.append('mode', shareMode);
|
||||
}
|
||||
if (blockIds && blockIds.length > 0) {
|
||||
search.append('blockIds', blockIds.join(','));
|
||||
}
|
||||
if (elementIds && elementIds.length > 0) {
|
||||
search.append('elementIds', elementIds.join(','));
|
||||
}
|
||||
if (xywh) {
|
||||
search.append('xywh', xywh);
|
||||
}
|
||||
const url = new URL(`/workspace/${workspaceId}/${pageId}`, baseUrl);
|
||||
const search = toURLSearchParams({
|
||||
mode: shareMode,
|
||||
blockIds,
|
||||
elementIds,
|
||||
xywh,
|
||||
});
|
||||
if (search) url.search = search.toString();
|
||||
return url.toString();
|
||||
} catch {
|
||||
return null;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useAutoFocus } from '@affine/component';
|
||||
import { getSvgPath } from '@blocksuite/global/utils';
|
||||
import { getFigmaSquircleSvgPath } from '@blocksuite/global/utils';
|
||||
import { SearchIcon } from '@blocksuite/icons/rc';
|
||||
import clsx from 'clsx';
|
||||
import { debounce } from 'lodash-es';
|
||||
@@ -49,7 +49,13 @@ export const SearchInput = forwardRef<HTMLInputElement, SearchInputProps>(
|
||||
const [inputValue, setInputValue] = useState(value);
|
||||
|
||||
const clipPath = useMemo(
|
||||
() => getSvgPath({ width, height, cornerRadius, cornerSmoothing }),
|
||||
() =>
|
||||
getFigmaSquircleSvgPath({
|
||||
width,
|
||||
height,
|
||||
cornerRadius,
|
||||
cornerSmoothing,
|
||||
}),
|
||||
[cornerRadius, cornerSmoothing, height, width]
|
||||
);
|
||||
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
import type { DocMode, EdgelessRootService } from '@blocksuite/blocks';
|
||||
import type {
|
||||
DocMode,
|
||||
EdgelessRootService,
|
||||
ReferenceParams,
|
||||
} from '@blocksuite/blocks';
|
||||
import type { InlineEditor } from '@blocksuite/inline';
|
||||
import type { AffineEditorContainer, DocTitle } from '@blocksuite/presets';
|
||||
import type { DocService, WorkspaceService } from '@toeverything/infra';
|
||||
import { Entity, LiveData } from '@toeverything/infra';
|
||||
import { isEqual } from 'lodash-es';
|
||||
|
||||
import { paramsParseOptions, preprocessParams } from '../../navigation/utils';
|
||||
import type { WorkbenchView } from '../../workbench';
|
||||
import { EditorScope } from '../scopes/editor';
|
||||
import type { EditorSelector } from '../types';
|
||||
@@ -58,22 +63,11 @@ export class Editor extends Entity {
|
||||
*/
|
||||
bindWorkbenchView(view: WorkbenchView) {
|
||||
// eslint-disable-next-line rxjs/finnish
|
||||
const viewParams$ = view.queryString$<{
|
||||
mode?: DocMode;
|
||||
blockIds?: string[];
|
||||
elementIds?: string[];
|
||||
refreshKey?: string;
|
||||
}>({
|
||||
// Cannot handle single id situation correctly: `blockIds=xxx`
|
||||
arrayFormat: 'none',
|
||||
types: {
|
||||
mode: value =>
|
||||
value === 'page' || value === 'edgeless' ? value : undefined,
|
||||
blockIds: value => (value.length ? value.split(',') : []),
|
||||
elementIds: value => (value.length ? value.split(',') : []),
|
||||
refreshKey: 'string',
|
||||
},
|
||||
});
|
||||
const viewParams$ = view
|
||||
.queryString$<
|
||||
ReferenceParams & { refreshKey?: string }
|
||||
>(paramsParseOptions)
|
||||
.map(preprocessParams);
|
||||
|
||||
const stablePrimaryMode = this.doc.getPrimaryMode();
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import type {
|
||||
EdgelessRootService,
|
||||
PageRootService,
|
||||
} from '@blocksuite/blocks';
|
||||
import { ZOOM_MAX } from '@blocksuite/blocks';
|
||||
import { Bound, deserializeXYWH } from '@blocksuite/global/utils';
|
||||
|
||||
function scrollAnchoringInEdgelessMode(
|
||||
@@ -47,8 +46,7 @@ function scrollAnchoringInEdgelessMode(
|
||||
|
||||
const { zoom, centerX, centerY } = service.getFitToScreenData(
|
||||
[20, 20, 100, 20],
|
||||
[bounds],
|
||||
ZOOM_MAX
|
||||
[bounds]
|
||||
);
|
||||
|
||||
service.viewport.setCenter(centerX, centerY);
|
||||
|
||||
@@ -53,13 +53,37 @@ const testCases: [string, ReturnType<typeof resolveLinkToDoc>][] = [
|
||||
},
|
||||
],
|
||||
[
|
||||
'http//localhost:8000/workspace/48__RTCSwASvWZxyAk3Jw/-Uge-K6SYcAbcNYfQ5U-j?blockIds=xxxx',
|
||||
'http//localhost:8000/workspace/48__RTCSwASvWZxyAk3Jw/-Uge-K6SYcAbcNYfQ5U-j?mode=page&blockIds=xxxx',
|
||||
{
|
||||
workspaceId: '48__RTCSwASvWZxyAk3Jw',
|
||||
docId: '-Uge-K6SYcAbcNYfQ5U-j',
|
||||
mode: 'page',
|
||||
blockIds: ['xxxx'],
|
||||
},
|
||||
],
|
||||
[
|
||||
'http//localhost:8000/workspace/48__RTCSwASvWZxyAk3Jw/-Uge-K6SYcAbcNYfQ5U-j?mode=&blockIds=',
|
||||
{
|
||||
workspaceId: '48__RTCSwASvWZxyAk3Jw',
|
||||
docId: '-Uge-K6SYcAbcNYfQ5U-j',
|
||||
},
|
||||
],
|
||||
[
|
||||
'http//localhost:8000/workspace/48__RTCSwASvWZxyAk3Jw/-Uge-K6SYcAbcNYfQ5U-j?mode=edgeless&elementIds=yyyy',
|
||||
{
|
||||
workspaceId: '48__RTCSwASvWZxyAk3Jw',
|
||||
docId: '-Uge-K6SYcAbcNYfQ5U-j',
|
||||
mode: 'edgeless',
|
||||
elementIds: ['yyyy'],
|
||||
},
|
||||
],
|
||||
[
|
||||
'http//localhost:8000/workspace/48__RTCSwASvWZxyAk3Jw/-Uge-K6SYcAbcNYfQ5U-j?mode=edgeles&elementId=yyyy',
|
||||
{
|
||||
workspaceId: '48__RTCSwASvWZxyAk3Jw',
|
||||
docId: '-Uge-K6SYcAbcNYfQ5U-j',
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
for (const [input, expected] of testCases) {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import type { DocMode } from '@blocksuite/blocks';
|
||||
import type { ReferenceParams } from '@blocksuite/blocks';
|
||||
import { isNil, pick, pickBy } from 'lodash-es';
|
||||
import type { ParsedQuery, ParseOptions } from 'query-string';
|
||||
import queryString from 'query-string';
|
||||
|
||||
function maybeAffineOrigin(origin: string) {
|
||||
@@ -61,6 +63,23 @@ export const resolveRouteLinkMeta = (href: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const isLink = (href: string) => {
|
||||
try {
|
||||
const hasScheme = href.match(/^https?:\/\//);
|
||||
|
||||
if (!hasScheme) {
|
||||
const dotIdx = href.indexOf('.');
|
||||
if (dotIdx > 0 && dotIdx < href.length - 1) {
|
||||
href = `https://${href}`;
|
||||
}
|
||||
}
|
||||
|
||||
return Boolean(URL.canParse?.(href) ?? new URL(href));
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @see /packages/frontend/core/src/router.tsx
|
||||
*/
|
||||
@@ -76,22 +95,49 @@ export const resolveLinkToDoc = (href: string) => {
|
||||
const meta = resolveRouteLinkMeta(href);
|
||||
if (!meta || meta.moduleName !== 'doc') return null;
|
||||
|
||||
const params: {
|
||||
mode?: DocMode;
|
||||
blockIds?: string[];
|
||||
elementIds?: string[];
|
||||
} = queryString.parse(meta.location.search, {
|
||||
arrayFormat: 'none',
|
||||
types: {
|
||||
mode: value => (value === 'edgeless' ? 'edgeless' : 'page') as DocMode,
|
||||
blockIds: value => value.split(','),
|
||||
elementIds: value => value.split(','),
|
||||
},
|
||||
});
|
||||
const params = preprocessParams(
|
||||
queryString.parse(meta.location.search, paramsParseOptions)
|
||||
);
|
||||
|
||||
return {
|
||||
workspaceId: meta.workspaceId,
|
||||
docId: meta.docId,
|
||||
...pick(meta, ['workspaceId', 'docId']),
|
||||
...params,
|
||||
};
|
||||
};
|
||||
|
||||
export const preprocessParams = (
|
||||
params: ParsedQuery<string>
|
||||
): ReferenceParams & { refreshKey?: string } => {
|
||||
const result: ReferenceParams & { refreshKey?: string } = pickBy(
|
||||
params,
|
||||
value => {
|
||||
if (isNil(value)) return false;
|
||||
if (typeof value === 'string' && value.length === 0) return false;
|
||||
if (Array.isArray(value) && value.length === 0) return false;
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
if (result.blockIds?.length) {
|
||||
result.blockIds = result.blockIds.filter(v => v.length);
|
||||
}
|
||||
if (result.elementIds?.length) {
|
||||
result.elementIds = result.elementIds.filter(v => v.length);
|
||||
}
|
||||
|
||||
return pick(result, ['mode', 'blockIds', 'elementIds', 'refreshKey']);
|
||||
};
|
||||
|
||||
export const paramsParseOptions: ParseOptions = {
|
||||
// Cannot handle single id situation correctly: `blockIds=xxx`
|
||||
arrayFormat: 'none',
|
||||
types: {
|
||||
mode: value =>
|
||||
value === 'page' || value === 'edgeless' ? value : undefined,
|
||||
blockIds: value =>
|
||||
value.length ? value.split(',').filter(v => v.length) : [],
|
||||
elementIds: value =>
|
||||
value.length ? value.split(',').filter(v => v.length) : [],
|
||||
refreshKey: 'string',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { WorkspaceService } from '@toeverything/infra';
|
||||
import { Entity, LiveData } from '@toeverything/infra';
|
||||
|
||||
import { resolveLinkToDoc } from '../../navigation';
|
||||
import { isLink } from '../../navigation/utils';
|
||||
import type { QuickSearchSession } from '../providers/quick-search-provider';
|
||||
import type { QuickSearchItem } from '../types/item';
|
||||
|
||||
@@ -21,11 +22,10 @@ export class ExternalLinksQuickSearchSession
|
||||
query$ = new LiveData('');
|
||||
|
||||
items$ = LiveData.computed(get => {
|
||||
const query = get(this.query$);
|
||||
const query = get(this.query$).trim();
|
||||
if (!query) return [];
|
||||
|
||||
const isLink = query.startsWith('http://') || query.startsWith('https://');
|
||||
if (!isLink) return [];
|
||||
if (!isLink(query)) return [];
|
||||
|
||||
const resolvedDoc = resolveLinkToDoc(query);
|
||||
if (
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
import type { DocMode } from '@blocksuite/blocks';
|
||||
import type { ReferenceParams } from '@blocksuite/blocks';
|
||||
import { BlockLinkIcon, EdgelessIcon, PageIcon } from '@blocksuite/icons/rc';
|
||||
import type { DocsService, WorkspaceService } from '@toeverything/infra';
|
||||
import { Entity, LiveData } from '@toeverything/infra';
|
||||
import { truncate } from 'lodash-es';
|
||||
import { omit, truncate } from 'lodash-es';
|
||||
|
||||
import { resolveLinkToDoc } from '../../navigation';
|
||||
import { isLink } from '../../navigation/utils';
|
||||
import type { QuickSearchSession } from '../providers/quick-search-provider';
|
||||
import type { DocDisplayMetaService } from '../services/doc-display-meta';
|
||||
import type { QuickSearchItem } from '../types/item';
|
||||
|
||||
type LinkPayload = {
|
||||
docId: string;
|
||||
blockIds?: string[];
|
||||
elementIds?: string[];
|
||||
mode?: DocMode;
|
||||
};
|
||||
type LinkPayload = { docId: string } & ReferenceParams;
|
||||
|
||||
export class LinksQuickSearchSession
|
||||
extends Entity
|
||||
@@ -31,11 +27,10 @@ export class LinksQuickSearchSession
|
||||
query$ = new LiveData('');
|
||||
|
||||
items$ = LiveData.computed(get => {
|
||||
const query = get(this.query$);
|
||||
const query = get(this.query$).trim();
|
||||
if (!query) return [];
|
||||
|
||||
const isLink = query.startsWith('http://') || query.startsWith('https://');
|
||||
if (!isLink) return [];
|
||||
if (!isLink(query)) return [];
|
||||
|
||||
const resolvedDoc = resolveLinkToDoc(query);
|
||||
if (
|
||||
@@ -53,6 +48,13 @@ export class LinksQuickSearchSession
|
||||
this.docDisplayMetaService.getDocDisplayMeta(doc);
|
||||
const linkToNode = resolvedDoc.blockIds || resolvedDoc.elementIds;
|
||||
const score = 100;
|
||||
const payload = omit(resolvedDoc, ['workspaceId']);
|
||||
const icons = {
|
||||
page: PageIcon,
|
||||
edgeless: EdgelessIcon,
|
||||
node: BlockLinkIcon,
|
||||
other: icon,
|
||||
};
|
||||
|
||||
return [
|
||||
{
|
||||
@@ -67,23 +69,12 @@ export class LinksQuickSearchSession
|
||||
score: 5,
|
||||
},
|
||||
label: {
|
||||
title: title,
|
||||
title,
|
||||
},
|
||||
score,
|
||||
icon: linkToNode
|
||||
? BlockLinkIcon
|
||||
: resolvedDoc.mode === 'page'
|
||||
? PageIcon
|
||||
: resolvedDoc.mode === 'edgeless'
|
||||
? EdgelessIcon
|
||||
: icon,
|
||||
icon: icons[linkToNode ? 'node' : (resolvedDoc.mode ?? 'other')],
|
||||
timestamp: updatedDate,
|
||||
payload: {
|
||||
docId,
|
||||
blockIds: resolvedDoc.blockIds,
|
||||
elementIds: resolvedDoc.elementIds,
|
||||
mode: resolvedDoc.mode,
|
||||
},
|
||||
payload,
|
||||
} as QuickSearchItem<'link', LinkPayload>,
|
||||
];
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { appInfo } from '@affine/electron-api';
|
||||
import { isNil } from 'lodash-es';
|
||||
|
||||
interface AppUrlOptions {
|
||||
desktop?: boolean | string;
|
||||
@@ -32,12 +33,24 @@ export function buildAppUrl(path: string, opts: AppUrlOptions = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
export function toURLSearchParams(params?: Record<string, string | string[]>) {
|
||||
export function toURLSearchParams(
|
||||
params?: Partial<Record<string, string | string[]>>
|
||||
) {
|
||||
if (!params) return;
|
||||
|
||||
const items = Object.entries(params)
|
||||
.filter(([_, v]) => !isNil(v))
|
||||
.filter(([_, v]) => {
|
||||
if (typeof v === 'string') {
|
||||
return v.length > 0;
|
||||
}
|
||||
if (Array.isArray(v)) {
|
||||
return v.length > 0;
|
||||
}
|
||||
return false;
|
||||
}) as [string, string | string[]][];
|
||||
|
||||
return new URLSearchParams(
|
||||
Object.entries(params).map(([k, v]) => [
|
||||
k,
|
||||
Array.isArray(v) ? v.join(',') : v,
|
||||
])
|
||||
items.map(([k, v]) => [k, Array.isArray(v) ? v.join(',') : v])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,8 @@ type DocEvents =
|
||||
| 'switchPageMode'
|
||||
| 'openDocOptionsMenu'
|
||||
| 'openDocInfo'
|
||||
| 'copyBlockToLink';
|
||||
| 'copyBlockToLink'
|
||||
| 'bookmark';
|
||||
type EditorEvents = 'bold' | 'italic' | 'underline' | 'strikeThrough';
|
||||
// END SECTION
|
||||
|
||||
@@ -262,7 +263,7 @@ const PageEvents = {
|
||||
},
|
||||
doc: {
|
||||
editor: {
|
||||
slashMenu: ['linkDoc', 'createDoc'],
|
||||
slashMenu: ['linkDoc', 'createDoc', 'bookmark'],
|
||||
atMenu: ['linkDoc'],
|
||||
quickSearch: ['createDoc'],
|
||||
formatToolbar: ['bold'],
|
||||
|
||||
Reference in New Issue
Block a user