mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-11 20:08:37 +00:00
refactor(editor): extract attachment block (#9308)
This commit is contained in:
44
blocksuite/affine/block-attachment/package.json
Normal file
44
blocksuite/affine/block-attachment/package.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "@blocksuite/affine-block-attachment",
|
||||
"description": "Attachment block for BlockSuite.",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"test:unit": "nx vite:test --run --passWithNoTests",
|
||||
"test:unit:coverage": "nx vite:test --run --coverage",
|
||||
"test:e2e": "playwright test"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"keywords": [],
|
||||
"author": "toeverything",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@blocksuite/affine-block-embed": "workspace:*",
|
||||
"@blocksuite/affine-components": "workspace:*",
|
||||
"@blocksuite/affine-model": "workspace:*",
|
||||
"@blocksuite/affine-shared": "workspace:*",
|
||||
"@blocksuite/block-std": "workspace:*",
|
||||
"@blocksuite/global": "workspace:*",
|
||||
"@blocksuite/icons": "^2.1.75",
|
||||
"@blocksuite/inline": "workspace:*",
|
||||
"@blocksuite/store": "workspace:*",
|
||||
"@floating-ui/dom": "^1.6.10",
|
||||
"@lit/context": "^1.1.2",
|
||||
"@preact/signals-core": "^1.8.0",
|
||||
"@toeverything/theme": "^1.1.1",
|
||||
"file-type": "^19.5.0",
|
||||
"lit": "^3.2.0",
|
||||
"minimatch": "^10.0.1",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./effects": "./src/effects.ts"
|
||||
},
|
||||
"files": [
|
||||
"src",
|
||||
"dist",
|
||||
"!src/__tests__",
|
||||
"!dist/__tests__"
|
||||
]
|
||||
}
|
||||
@@ -4,10 +4,10 @@ import {
|
||||
EMBED_CARD_HEIGHT,
|
||||
EMBED_CARD_WIDTH,
|
||||
} from '@blocksuite/affine-shared/consts';
|
||||
import { toGfxBlockComponent } from '@blocksuite/block-std';
|
||||
import { type BlockService, toGfxBlockComponent } from '@blocksuite/block-std';
|
||||
import type { Slot } from '@blocksuite/store';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
|
||||
import type { EdgelessRootService } from '../root-block/index.js';
|
||||
import { AttachmentBlockComponent } from './attachment-block.js';
|
||||
|
||||
export class AttachmentEdgelessBlockComponent extends toGfxBlockComponent(
|
||||
@@ -17,15 +17,20 @@ export class AttachmentEdgelessBlockComponent extends toGfxBlockComponent(
|
||||
|
||||
override blockDraggable = false;
|
||||
|
||||
get rootService() {
|
||||
return this.std.getService('affine:page') as EdgelessRootService;
|
||||
get rootService(): null | (BlockService & { slots: Record<string, Slot> }) {
|
||||
return this.std.getService('affine:page');
|
||||
}
|
||||
|
||||
override connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
|
||||
const rootService = this.rootService;
|
||||
if (!rootService) {
|
||||
console.warn('rootService is not found');
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: move root service slots to extension
|
||||
this._disposables.add(
|
||||
rootService.slots.elementResizeStart.on(() => {
|
||||
this._isResizing = true;
|
||||
@@ -33,6 +38,7 @@ export class AttachmentEdgelessBlockComponent extends toGfxBlockComponent(
|
||||
})
|
||||
);
|
||||
|
||||
// TODO: move root service slots to extension
|
||||
this._disposables.add(
|
||||
rootService.slots.elementResizeEnd.on(() => {
|
||||
this._isResizing = false;
|
||||
@@ -8,8 +8,7 @@ import {
|
||||
import { BlockService } from '@blocksuite/block-std';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
|
||||
|
||||
import { addAttachments } from '../root-block/edgeless/utils/common.js';
|
||||
import { addSiblingAttachmentBlocks } from './utils.js';
|
||||
import { addAttachments, addSiblingAttachmentBlocks } from './utils.js';
|
||||
|
||||
// bytes.parse('2GB')
|
||||
const maxFileSize = 2147483648;
|
||||
@@ -30,7 +29,10 @@ export const AttachmentDropOption = FileDropConfigExtension({
|
||||
|
||||
if (!attachmentFiles.length) return false;
|
||||
|
||||
if (targetModel && !matchFlavours(targetModel, ['affine:surface'])) {
|
||||
if (
|
||||
targetModel &&
|
||||
!matchFlavours(targetModel, ['affine:surface' as BlockSuite.Flavour])
|
||||
) {
|
||||
addSiblingAttachmentBlocks(
|
||||
std.host,
|
||||
attachmentFiles,
|
||||
19
blocksuite/affine/block-attachment/src/effects.ts
Normal file
19
blocksuite/affine/block-attachment/src/effects.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { AttachmentBlockComponent } from './attachment-block';
|
||||
import { AttachmentEdgelessBlockComponent } from './attachment-edgeless-block';
|
||||
import type { AttachmentBlockService } from './attachment-service';
|
||||
|
||||
export function effects() {
|
||||
customElements.define(
|
||||
'affine-edgeless-attachment',
|
||||
AttachmentEdgelessBlockComponent
|
||||
);
|
||||
customElements.define('affine-attachment', AttachmentBlockComponent);
|
||||
}
|
||||
|
||||
declare global {
|
||||
namespace BlockSuite {
|
||||
interface BlockServices {
|
||||
'affine:attachment': AttachmentBlockService;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
blocksuite/affine/block-attachment/src/index.ts
Normal file
11
blocksuite/affine/block-attachment/src/index.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export * from './adapters/notion-html';
|
||||
export * from './attachment-block';
|
||||
export * from './attachment-service';
|
||||
export * from './attachment-spec';
|
||||
export { attachmentViewToggleMenu } from './components/options';
|
||||
export {
|
||||
type AttachmentEmbedConfig,
|
||||
AttachmentEmbedConfigIdentifier,
|
||||
AttachmentEmbedProvider,
|
||||
} from './embed';
|
||||
export { addAttachments, addSiblingAttachmentBlocks } from './utils';
|
||||
@@ -4,9 +4,15 @@ import type {
|
||||
AttachmentBlockProps,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { defaultAttachmentProps } from '@blocksuite/affine-model';
|
||||
import {
|
||||
EMBED_CARD_HEIGHT,
|
||||
EMBED_CARD_WIDTH,
|
||||
} from '@blocksuite/affine-shared/consts';
|
||||
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
||||
import { humanFileSize } from '@blocksuite/affine-shared/utils';
|
||||
import type { EditorHost } from '@blocksuite/block-std';
|
||||
import type { BlockStdScope, EditorHost } from '@blocksuite/block-std';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
|
||||
import { Bound, type IVec, Point, Vec } from '@blocksuite/global/utils';
|
||||
import type { BlockModel } from '@blocksuite/store';
|
||||
|
||||
import type { AttachmentBlockComponent } from './attachment-block.js';
|
||||
@@ -251,3 +257,80 @@ export async function addSiblingAttachmentBlocks(
|
||||
|
||||
return blockIds;
|
||||
}
|
||||
|
||||
export async function addAttachments(
|
||||
std: BlockStdScope,
|
||||
files: File[],
|
||||
point?: IVec
|
||||
): Promise<string[]> {
|
||||
if (!files.length) return [];
|
||||
|
||||
const attachmentService = std.getService('affine:attachment');
|
||||
const gfx = std.get(GfxControllerIdentifier);
|
||||
|
||||
if (!attachmentService) {
|
||||
console.error('Attachment service not found');
|
||||
return [];
|
||||
}
|
||||
const maxFileSize = attachmentService.maxFileSize;
|
||||
const isSizeExceeded = files.some(file => file.size > maxFileSize);
|
||||
if (isSizeExceeded) {
|
||||
toast(
|
||||
std.host,
|
||||
`You can only upload files less than ${humanFileSize(
|
||||
maxFileSize,
|
||||
true,
|
||||
0
|
||||
)}`
|
||||
);
|
||||
return [];
|
||||
}
|
||||
|
||||
let { x, y } = gfx.viewport.center;
|
||||
if (point) [x, y] = gfx.viewport.toModelCoord(...point);
|
||||
|
||||
const CARD_STACK_GAP = 32;
|
||||
|
||||
const dropInfos: { blockId: string; file: File }[] = files.map(
|
||||
(file, index) => {
|
||||
const point = new Point(
|
||||
x + index * CARD_STACK_GAP,
|
||||
y + index * CARD_STACK_GAP
|
||||
);
|
||||
const center = Vec.toVec(point);
|
||||
const bound = Bound.fromCenter(
|
||||
center,
|
||||
EMBED_CARD_WIDTH.cubeThick,
|
||||
EMBED_CARD_HEIGHT.cubeThick
|
||||
);
|
||||
const blockId = std.doc.addBlock(
|
||||
'affine:attachment',
|
||||
{
|
||||
name: file.name,
|
||||
size: file.size,
|
||||
type: file.type,
|
||||
style: 'cubeThick',
|
||||
xywh: bound.serialize(),
|
||||
} satisfies Partial<AttachmentBlockProps>,
|
||||
gfx.surface
|
||||
);
|
||||
|
||||
return { blockId, file };
|
||||
}
|
||||
);
|
||||
|
||||
// upload file and update the attachment model
|
||||
const uploadPromises = dropInfos.map(async ({ blockId, file }) => {
|
||||
const filetype = await getFileType(file);
|
||||
await uploadAttachmentBlob(std.host, blockId, file, filetype, true);
|
||||
return blockId;
|
||||
});
|
||||
const blockIds = await Promise.all(uploadPromises);
|
||||
|
||||
gfx.selection.set({
|
||||
elements: blockIds,
|
||||
editing: false,
|
||||
});
|
||||
|
||||
return blockIds;
|
||||
}
|
||||
35
blocksuite/affine/block-attachment/tsconfig.json
Normal file
35
blocksuite/affine/block-attachment/tsconfig.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src/",
|
||||
"outDir": "./dist/",
|
||||
"noEmit": false
|
||||
},
|
||||
"include": ["./src"],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../framework/global"
|
||||
},
|
||||
{
|
||||
"path": "../../framework/store"
|
||||
},
|
||||
{
|
||||
"path": "../../framework/block-std"
|
||||
},
|
||||
{
|
||||
"path": "../../framework/inline"
|
||||
},
|
||||
{
|
||||
"path": "../model"
|
||||
},
|
||||
{
|
||||
"path": "../components"
|
||||
},
|
||||
{
|
||||
"path": "../shared"
|
||||
},
|
||||
{
|
||||
"path": "../block-embed"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
"author": "toeverything",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@blocksuite/affine-block-attachment": "workspace:*",
|
||||
"@blocksuite/affine-block-bookmark": "workspace:*",
|
||||
"@blocksuite/affine-block-embed": "workspace:*",
|
||||
"@blocksuite/affine-block-list": "workspace:*",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { attachmentBlockNotionHtmlAdapterMatcher } from '@blocksuite/affine-block-attachment';
|
||||
import { bookmarkBlockNotionHtmlAdapterMatcher } from '@blocksuite/affine-block-bookmark';
|
||||
import {
|
||||
embedFigmaBlockNotionHtmlAdapterMatcher,
|
||||
@@ -9,7 +10,6 @@ import { listBlockNotionHtmlAdapterMatcher } from '@blocksuite/affine-block-list
|
||||
import { paragraphBlockNotionHtmlAdapterMatcher } from '@blocksuite/affine-block-paragraph';
|
||||
import type { BlockNotionHtmlAdapterMatcher } from '@blocksuite/affine-shared/adapters';
|
||||
|
||||
import { attachmentBlockNotionHtmlAdapterMatcher } from '../../../attachment-block/adapters/notion-html.js';
|
||||
import { codeBlockNotionHtmlAdapterMatcher } from '../../../code-block/adapters/notion-html.js';
|
||||
import { databaseBlockNotionHtmlAdapterMatcher } from '../../../database-block/adapters/notion-html.js';
|
||||
import { dividerBlockNotionHtmlAdapterMatcher } from '../../../divider-block/adapters/notion-html.js';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { AttachmentBlockSpec } from '@blocksuite/affine-block-attachment';
|
||||
import { BookmarkBlockSpec } from '@blocksuite/affine-block-bookmark';
|
||||
import { EmbedExtensions } from '@blocksuite/affine-block-embed';
|
||||
import { ListBlockSpec } from '@blocksuite/affine-block-list';
|
||||
@@ -7,7 +8,6 @@ import { EditPropsStore } from '@blocksuite/affine-shared/services';
|
||||
import type { ExtensionType } from '@blocksuite/block-std';
|
||||
|
||||
import { AdapterFactoryExtensions } from '../_common/adapters/extension.js';
|
||||
import { AttachmentBlockSpec } from '../attachment-block/attachment-spec.js';
|
||||
import { CodeBlockSpec } from '../code-block/code-block-spec.js';
|
||||
import { DataViewBlockSpec } from '../data-view-block/data-view-spec.js';
|
||||
import { DatabaseBlockSpec } from '../database-block/database-spec.js';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { AttachmentBlockSpec } from '@blocksuite/affine-block-attachment';
|
||||
import { BookmarkBlockSpec } from '@blocksuite/affine-block-bookmark';
|
||||
import {
|
||||
EmbedFigmaBlockSpec,
|
||||
@@ -11,7 +12,6 @@ import {
|
||||
import { ListBlockSpec } from '@blocksuite/affine-block-list';
|
||||
import { ParagraphBlockSpec } from '@blocksuite/affine-block-paragraph';
|
||||
|
||||
import { AttachmentBlockSpec } from '../../attachment-block/attachment-spec.js';
|
||||
import { CodeBlockSpec } from '../../code-block/code-block-spec.js';
|
||||
import { DataViewBlockSpec } from '../../data-view-block/data-view-spec.js';
|
||||
import { DatabaseBlockSpec } from '../../database-block/database-spec.js';
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
export * from './attachment-block.js';
|
||||
export * from './attachment-service.js';
|
||||
export { attachmentViewToggleMenu } from './components/options.js';
|
||||
export {
|
||||
type AttachmentEmbedConfig,
|
||||
AttachmentEmbedConfigIdentifier,
|
||||
AttachmentEmbedProvider,
|
||||
} from './embed.js';
|
||||
@@ -1,3 +1,4 @@
|
||||
import { effects as blockAttachmentEffects } from '@blocksuite/affine-block-attachment/effects';
|
||||
import { effects as blockBookmarkEffects } from '@blocksuite/affine-block-bookmark/effects';
|
||||
import { effects as blockEmbedEffects } from '@blocksuite/affine-block-embed/effects';
|
||||
import { effects as blockListEffects } from '@blocksuite/affine-block-list/effects';
|
||||
@@ -29,11 +30,6 @@ import { EmbedCardEditCaptionEditModal } from './_common/components/embed-card/m
|
||||
import { EmbedCardCreateModal } from './_common/components/embed-card/modal/embed-card-create-modal.js';
|
||||
import { EmbedCardEditModal } from './_common/components/embed-card/modal/embed-card-edit-modal.js';
|
||||
import { registerSpecs } from './_specs/register-specs.js';
|
||||
import { AttachmentEdgelessBlockComponent } from './attachment-block/attachment-edgeless-block.js';
|
||||
import {
|
||||
AttachmentBlockComponent,
|
||||
type AttachmentBlockService,
|
||||
} from './attachment-block/index.js';
|
||||
import { AffineCodeUnit } from './code-block/highlight/affine-code-unit.js';
|
||||
import {
|
||||
CodeBlockComponent,
|
||||
@@ -275,6 +271,7 @@ export function effects() {
|
||||
stdEffects();
|
||||
inlineEffects();
|
||||
|
||||
blockAttachmentEffects();
|
||||
blockBookmarkEffects();
|
||||
blockListEffects();
|
||||
blockParagraphEffects();
|
||||
@@ -322,13 +319,8 @@ export function effects() {
|
||||
);
|
||||
customElements.define('affine-edgeless-text', EdgelessTextBlockComponent);
|
||||
customElements.define('center-peek', CenterPeek);
|
||||
customElements.define(
|
||||
'affine-edgeless-attachment',
|
||||
AttachmentEdgelessBlockComponent
|
||||
);
|
||||
customElements.define('database-datasource-note-renderer', NoteRenderer);
|
||||
customElements.define('database-datasource-block-renderer', BlockRenderer);
|
||||
customElements.define('affine-attachment', AttachmentBlockComponent);
|
||||
customElements.define('affine-latex', LatexBlockComponent);
|
||||
customElements.define('affine-page-root', PageRootBlockComponent);
|
||||
customElements.define('edgeless-note-mask', EdgelessNoteMask);
|
||||
@@ -594,7 +586,6 @@ declare global {
|
||||
interface BlockServices {
|
||||
'affine:note': NoteBlockService;
|
||||
'affine:page': RootService;
|
||||
'affine:attachment': AttachmentBlockService;
|
||||
'affine:database': DatabaseBlockService;
|
||||
'affine:image': ImageBlockService;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ export * from './_common/test-utils/test-utils.js';
|
||||
export * from './_common/transformers/index.js';
|
||||
export { type AbstractEditor } from './_common/types.js';
|
||||
export * from './_specs/index.js';
|
||||
export * from './attachment-block/index.js';
|
||||
export * from './code-block/index.js';
|
||||
export * from './data-view-block/index.js';
|
||||
export * from './database-block/index.js';
|
||||
@@ -49,6 +48,7 @@ export {
|
||||
MiniMindmapPreview,
|
||||
} from './surface-block/mini-mindmap/index.js';
|
||||
export * from './surface-ref-block/index.js';
|
||||
export * from '@blocksuite/affine-block-attachment';
|
||||
export * from '@blocksuite/affine-block-bookmark';
|
||||
export * from '@blocksuite/affine-block-embed';
|
||||
export * from '@blocksuite/affine-block-list';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { addAttachments } from '@blocksuite/affine-block-attachment';
|
||||
import {
|
||||
CanvasElementType,
|
||||
SurfaceGroupLikeModel,
|
||||
@@ -75,7 +76,7 @@ import {
|
||||
getSortedCloneElements,
|
||||
serializeElement,
|
||||
} from '../utils/clone-utils.js';
|
||||
import { addAttachments, addImages } from '../utils/common.js';
|
||||
import { addImages } from '../utils/common.js';
|
||||
import { deleteElements } from '../utils/crud.js';
|
||||
import {
|
||||
isAttachmentBlock,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { addAttachments } from '@blocksuite/affine-block-attachment';
|
||||
import { AttachmentIcon, LinkIcon } from '@blocksuite/affine-components/icons';
|
||||
import { MAX_IMAGE_WIDTH } from '@blocksuite/affine-model';
|
||||
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
||||
@@ -14,7 +15,7 @@ import {
|
||||
} from '../../../../../_common/utils/index.js';
|
||||
import { ImageIcon } from '../../../../../image-block/styles.js';
|
||||
import type { NoteToolOption } from '../../../gfx-tool/note-tool.js';
|
||||
import { addAttachments, addImages } from '../../../utils/common.js';
|
||||
import { addImages } from '../../../utils/common.js';
|
||||
import { getTooltipWithShortcut } from '../../utils.js';
|
||||
import { EdgelessToolbarToolMixin } from '../mixins/tool.mixin.js';
|
||||
import { NOTE_MENU_ITEMS } from './note-menu-config.js';
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { focusTextModel } from '@blocksuite/affine-components/rich-text';
|
||||
import { toast } from '@blocksuite/affine-components/toast';
|
||||
import {
|
||||
type AttachmentBlockProps,
|
||||
DEFAULT_NOTE_HEIGHT,
|
||||
DEFAULT_NOTE_WIDTH,
|
||||
type ImageBlockProps,
|
||||
@@ -9,10 +8,6 @@ import {
|
||||
type NoteBlockModel,
|
||||
NoteDisplayMode,
|
||||
} from '@blocksuite/affine-model';
|
||||
import {
|
||||
EMBED_CARD_HEIGHT,
|
||||
EMBED_CARD_WIDTH,
|
||||
} from '@blocksuite/affine-shared/consts';
|
||||
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
||||
import type { NoteChildrenFlavour } from '@blocksuite/affine-shared/types';
|
||||
import {
|
||||
@@ -22,7 +17,6 @@ import {
|
||||
import type { BlockStdScope } from '@blocksuite/block-std';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
|
||||
import {
|
||||
Bound,
|
||||
type IPoint,
|
||||
type IVec,
|
||||
Point,
|
||||
@@ -30,91 +24,10 @@ import {
|
||||
Vec,
|
||||
} from '@blocksuite/global/utils';
|
||||
|
||||
import {
|
||||
getFileType,
|
||||
uploadAttachmentBlob,
|
||||
} from '../../../attachment-block/utils.js';
|
||||
import { calcBoundByOrigin, readImageSize } from '../components/utils.js';
|
||||
import { DEFAULT_NOTE_OFFSET_X, DEFAULT_NOTE_OFFSET_Y } from './consts.js';
|
||||
import { addBlock } from './crud.js';
|
||||
|
||||
export async function addAttachments(
|
||||
std: BlockStdScope,
|
||||
files: File[],
|
||||
point?: IVec
|
||||
): Promise<string[]> {
|
||||
if (!files.length) return [];
|
||||
|
||||
const attachmentService = std.getService('affine:attachment');
|
||||
const gfx = std.get(GfxControllerIdentifier);
|
||||
|
||||
if (!attachmentService) {
|
||||
console.error('Attachment service not found');
|
||||
return [];
|
||||
}
|
||||
const maxFileSize = attachmentService.maxFileSize;
|
||||
const isSizeExceeded = files.some(file => file.size > maxFileSize);
|
||||
if (isSizeExceeded) {
|
||||
toast(
|
||||
std.host,
|
||||
`You can only upload files less than ${humanFileSize(
|
||||
maxFileSize,
|
||||
true,
|
||||
0
|
||||
)}`
|
||||
);
|
||||
return [];
|
||||
}
|
||||
|
||||
let { x, y } = gfx.viewport.center;
|
||||
if (point) [x, y] = gfx.viewport.toModelCoord(...point);
|
||||
|
||||
const CARD_STACK_GAP = 32;
|
||||
|
||||
const dropInfos: { blockId: string; file: File }[] = files.map(
|
||||
(file, index) => {
|
||||
const point = new Point(
|
||||
x + index * CARD_STACK_GAP,
|
||||
y + index * CARD_STACK_GAP
|
||||
);
|
||||
const center = Vec.toVec(point);
|
||||
const bound = Bound.fromCenter(
|
||||
center,
|
||||
EMBED_CARD_WIDTH.cubeThick,
|
||||
EMBED_CARD_HEIGHT.cubeThick
|
||||
);
|
||||
const blockId = std.doc.addBlock(
|
||||
'affine:attachment',
|
||||
{
|
||||
name: file.name,
|
||||
size: file.size,
|
||||
type: file.type,
|
||||
style: 'cubeThick',
|
||||
xywh: bound.serialize(),
|
||||
} satisfies Partial<AttachmentBlockProps>,
|
||||
gfx.surface
|
||||
);
|
||||
|
||||
return { blockId, file };
|
||||
}
|
||||
);
|
||||
|
||||
// upload file and update the attachment model
|
||||
const uploadPromises = dropInfos.map(async ({ blockId, file }) => {
|
||||
const filetype = await getFileType(file);
|
||||
await uploadAttachmentBlob(std.host, blockId, file, filetype, true);
|
||||
return blockId;
|
||||
});
|
||||
const blockIds = await Promise.all(uploadPromises);
|
||||
|
||||
gfx.selection.set({
|
||||
elements: blockIds,
|
||||
editing: false,
|
||||
});
|
||||
|
||||
return blockIds;
|
||||
}
|
||||
|
||||
export async function addImages(
|
||||
std: BlockStdScope,
|
||||
files: File[],
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import {
|
||||
type AttachmentBlockComponent,
|
||||
attachmentViewToggleMenu,
|
||||
} from '@blocksuite/affine-block-attachment';
|
||||
import { getEmbedCardIcons } from '@blocksuite/affine-block-embed';
|
||||
import {
|
||||
CaptionIcon,
|
||||
@@ -18,8 +22,6 @@ import { property } from 'lit/decorators.js';
|
||||
import { join } from 'lit/directives/join.js';
|
||||
|
||||
import type { EmbedCardStyle } from '../../../_common/types.js';
|
||||
import type { AttachmentBlockComponent } from '../../../attachment-block/index.js';
|
||||
import { attachmentViewToggleMenu } from '../../../attachment-block/index.js';
|
||||
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
|
||||
|
||||
export class EdgelessChangeAttachmentButton extends WithDisposable(LitElement) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { AttachmentBlockComponent } from '@blocksuite/affine-block-attachment';
|
||||
import type { BookmarkBlockComponent } from '@blocksuite/affine-block-bookmark';
|
||||
import type {
|
||||
EmbedFigmaBlockComponent,
|
||||
@@ -31,7 +32,6 @@ import {
|
||||
notifyDocCreated,
|
||||
promptDocTitle,
|
||||
} from '../../../../_common/utils/render-linked-doc.js';
|
||||
import type { AttachmentBlockComponent } from '../../../../attachment-block/attachment-block.js';
|
||||
import type { ImageBlockComponent } from '../../../../image-block/image-block.js';
|
||||
import { duplicate } from '../../../edgeless/utils/clipboard-utils.js';
|
||||
import { getSortedCloneElements } from '../../../edgeless/utils/clone-utils.js';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { addSiblingAttachmentBlocks } from '@blocksuite/affine-block-attachment';
|
||||
import {
|
||||
getInlineEditorByModel,
|
||||
insertContent,
|
||||
@@ -60,7 +61,6 @@ import { cssVarV2 } from '@toeverything/theme/v2';
|
||||
import type { TemplateResult } from 'lit';
|
||||
|
||||
import { toggleEmbedCardCreateModal } from '../../../_common/components/embed-card/modal/embed-card-create-modal.js';
|
||||
import { addSiblingAttachmentBlocks } from '../../../attachment-block/utils.js';
|
||||
import { getSurfaceBlock } from '../../../surface-ref-block/utils.js';
|
||||
import type { PageRootBlockComponent } from '../../page/page-root-block.js';
|
||||
import { formatDate, formatTime } from '../../utils/misc.js';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { addSiblingAttachmentBlocks } from '@blocksuite/affine-block-attachment';
|
||||
import {
|
||||
FigmaIcon,
|
||||
GithubIcon,
|
||||
@@ -49,7 +50,6 @@ import type { TemplateResult } from 'lit';
|
||||
|
||||
import { toggleEmbedCardCreateModal } from '../../../_common/components/embed-card/modal/embed-card-create-modal.js';
|
||||
import { textConversionConfigs } from '../../../_common/configs/text-conversion.js';
|
||||
import { addSiblingAttachmentBlocks } from '../../../attachment-block/utils.js';
|
||||
import type { DataViewBlockComponent } from '../../../data-view-block/index.js';
|
||||
import { getSurfaceBlock } from '../../../surface-ref-block/utils.js';
|
||||
import type { RootBlockComponent } from '../../types.js';
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
{
|
||||
"path": "../affine/block-bookmark"
|
||||
},
|
||||
{
|
||||
"path": "../affine/block-attachment"
|
||||
},
|
||||
{
|
||||
"path": "../affine/data-view"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user