mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-31 21:59:10 +08:00
chore: bump blocksuite (#8230)
## 0.17.11 ### Patch Changes - [3c61be5](https://github.com/toeverything/blocksuite/commit/3c61be5dedcc1fc37d6f09ed2541b391584c0ded): - 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:
@@ -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>,
|
||||
];
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user