refactor(editor): remove attachment and image block service (#9909)
This commit is contained in:
@@ -11,7 +11,10 @@ import {
|
|||||||
type AttachmentBlockModel,
|
type AttachmentBlockModel,
|
||||||
AttachmentBlockStyles,
|
AttachmentBlockStyles,
|
||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
import { ThemeProvider } from '@blocksuite/affine-shared/services';
|
import {
|
||||||
|
FileSizeLimitService,
|
||||||
|
ThemeProvider,
|
||||||
|
} from '@blocksuite/affine-shared/services';
|
||||||
import { humanFileSize } from '@blocksuite/affine-shared/utils';
|
import { humanFileSize } from '@blocksuite/affine-shared/utils';
|
||||||
import { BlockSelection, TextSelection } from '@blocksuite/block-std';
|
import { BlockSelection, TextSelection } from '@blocksuite/block-std';
|
||||||
import { Slice } from '@blocksuite/store';
|
import { Slice } from '@blocksuite/store';
|
||||||
@@ -22,17 +25,13 @@ import { classMap } from 'lit/directives/class-map.js';
|
|||||||
import { ref } from 'lit/directives/ref.js';
|
import { ref } from 'lit/directives/ref.js';
|
||||||
import { styleMap } from 'lit/directives/style-map.js';
|
import { styleMap } from 'lit/directives/style-map.js';
|
||||||
|
|
||||||
import type { AttachmentBlockService } from './attachment-service.js';
|
|
||||||
import { AttachmentOptionsTemplate } from './components/options.js';
|
import { AttachmentOptionsTemplate } from './components/options.js';
|
||||||
import { AttachmentEmbedProvider } from './embed.js';
|
import { AttachmentEmbedProvider } from './embed.js';
|
||||||
import { styles } from './styles.js';
|
import { styles } from './styles.js';
|
||||||
import { checkAttachmentBlob, downloadAttachmentBlob } from './utils.js';
|
import { checkAttachmentBlob, downloadAttachmentBlob } from './utils.js';
|
||||||
|
|
||||||
@Peekable()
|
@Peekable()
|
||||||
export class AttachmentBlockComponent extends CaptionedBlockComponent<
|
export class AttachmentBlockComponent extends CaptionedBlockComponent<AttachmentBlockModel> {
|
||||||
AttachmentBlockModel,
|
|
||||||
AttachmentBlockService
|
|
||||||
> {
|
|
||||||
static override styles = styles;
|
static override styles = styles;
|
||||||
|
|
||||||
protected _isDragging = false;
|
protected _isDragging = false;
|
||||||
@@ -86,10 +85,14 @@ export class AttachmentBlockComponent extends CaptionedBlockComponent<
|
|||||||
margin: '18px 0px',
|
margin: '18px 0px',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
private get _maxFileSize() {
|
||||||
|
return this.std.store.get(FileSizeLimitService).maxFileSize;
|
||||||
|
}
|
||||||
|
|
||||||
convertTo = () => {
|
convertTo = () => {
|
||||||
return this.std
|
return this.std
|
||||||
.get(AttachmentEmbedProvider)
|
.get(AttachmentEmbedProvider)
|
||||||
.convertTo(this.model, this.service.maxFileSize);
|
.convertTo(this.model, this._maxFileSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
copy = () => {
|
copy = () => {
|
||||||
@@ -105,7 +108,7 @@ export class AttachmentBlockComponent extends CaptionedBlockComponent<
|
|||||||
embedded = () => {
|
embedded = () => {
|
||||||
return this.std
|
return this.std
|
||||||
.get(AttachmentEmbedProvider)
|
.get(AttachmentEmbedProvider)
|
||||||
.embedded(this.model, this.service.maxFileSize);
|
.embedded(this.model, this._maxFileSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
open = () => {
|
open = () => {
|
||||||
@@ -122,7 +125,7 @@ export class AttachmentBlockComponent extends CaptionedBlockComponent<
|
|||||||
protected get embedView() {
|
protected get embedView() {
|
||||||
return this.std
|
return this.std
|
||||||
.get(AttachmentEmbedProvider)
|
.get(AttachmentEmbedProvider)
|
||||||
.render(this.model, this.blobUrl, this.service.maxFileSize);
|
.render(this.model, this.blobUrl, this._maxFileSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _selectBlock() {
|
private _selectBlock() {
|
||||||
|
|||||||
@@ -1,24 +1,17 @@
|
|||||||
import { FileDropConfigExtension } from '@blocksuite/affine-components/drop-indicator';
|
import { FileDropConfigExtension } from '@blocksuite/affine-components/drop-indicator';
|
||||||
import { AttachmentBlockSchema } from '@blocksuite/affine-model';
|
import { AttachmentBlockSchema } from '@blocksuite/affine-model';
|
||||||
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
import {
|
||||||
|
FileSizeLimitService,
|
||||||
|
TelemetryProvider,
|
||||||
|
} from '@blocksuite/affine-shared/services';
|
||||||
import {
|
import {
|
||||||
isInsideEdgelessEditor,
|
isInsideEdgelessEditor,
|
||||||
matchFlavours,
|
matchFlavours,
|
||||||
} from '@blocksuite/affine-shared/utils';
|
} from '@blocksuite/affine-shared/utils';
|
||||||
import { BlockService } from '@blocksuite/block-std';
|
|
||||||
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
|
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
|
||||||
|
|
||||||
import { addAttachments, addSiblingAttachmentBlocks } from './utils.js';
|
import { addAttachments, addSiblingAttachmentBlocks } from './utils.js';
|
||||||
|
|
||||||
// bytes.parse('2GB')
|
|
||||||
const maxFileSize = 2147483648;
|
|
||||||
|
|
||||||
export class AttachmentBlockService extends BlockService {
|
|
||||||
static override readonly flavour = AttachmentBlockSchema.model.flavour;
|
|
||||||
|
|
||||||
maxFileSize = maxFileSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const AttachmentDropOption = FileDropConfigExtension({
|
export const AttachmentDropOption = FileDropConfigExtension({
|
||||||
flavour: AttachmentBlockSchema.model.flavour,
|
flavour: AttachmentBlockSchema.model.flavour,
|
||||||
onDrop: ({ files, targetModel, placement, point, std }) => {
|
onDrop: ({ files, targetModel, placement, point, std }) => {
|
||||||
@@ -28,11 +21,12 @@ export const AttachmentDropOption = FileDropConfigExtension({
|
|||||||
);
|
);
|
||||||
if (!attachmentFiles.length) return false;
|
if (!attachmentFiles.length) return false;
|
||||||
|
|
||||||
|
const maxFileSize = std.store.get(FileSizeLimitService).maxFileSize;
|
||||||
|
|
||||||
if (targetModel && !matchFlavours(targetModel, ['affine:surface'])) {
|
if (targetModel && !matchFlavours(targetModel, ['affine:surface'])) {
|
||||||
addSiblingAttachmentBlocks(
|
addSiblingAttachmentBlocks(
|
||||||
std.host,
|
std.host,
|
||||||
attachmentFiles,
|
attachmentFiles,
|
||||||
// TODO: use max file size from service
|
|
||||||
maxFileSize,
|
maxFileSize,
|
||||||
targetModel,
|
targetModel,
|
||||||
placement
|
placement
|
||||||
|
|||||||
@@ -3,10 +3,7 @@ import type { ExtensionType } from '@blocksuite/store';
|
|||||||
import { literal } from 'lit/static-html.js';
|
import { literal } from 'lit/static-html.js';
|
||||||
|
|
||||||
import { AttachmentBlockNotionHtmlAdapterExtension } from './adapters/notion-html.js';
|
import { AttachmentBlockNotionHtmlAdapterExtension } from './adapters/notion-html.js';
|
||||||
import {
|
import { AttachmentDropOption } from './attachment-service.js';
|
||||||
AttachmentBlockService,
|
|
||||||
AttachmentDropOption,
|
|
||||||
} from './attachment-service.js';
|
|
||||||
import {
|
import {
|
||||||
AttachmentEmbedConfigExtension,
|
AttachmentEmbedConfigExtension,
|
||||||
AttachmentEmbedService,
|
AttachmentEmbedService,
|
||||||
@@ -14,7 +11,6 @@ import {
|
|||||||
|
|
||||||
export const AttachmentBlockSpec: ExtensionType[] = [
|
export const AttachmentBlockSpec: ExtensionType[] = [
|
||||||
FlavourExtension('affine:attachment'),
|
FlavourExtension('affine:attachment'),
|
||||||
AttachmentBlockService,
|
|
||||||
BlockViewExtension('affine:attachment', model => {
|
BlockViewExtension('affine:attachment', model => {
|
||||||
return model.parent?.flavour === 'affine:surface'
|
return model.parent?.flavour === 'affine:surface'
|
||||||
? literal`affine-edgeless-attachment`
|
? literal`affine-edgeless-attachment`
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { AttachmentBlockComponent } from './attachment-block';
|
import { AttachmentBlockComponent } from './attachment-block';
|
||||||
import { AttachmentEdgelessBlockComponent } from './attachment-edgeless-block';
|
import { AttachmentEdgelessBlockComponent } from './attachment-edgeless-block';
|
||||||
import type { AttachmentBlockService } from './attachment-service';
|
|
||||||
|
|
||||||
export function effects() {
|
export function effects() {
|
||||||
customElements.define(
|
customElements.define(
|
||||||
@@ -9,11 +8,3 @@ export function effects() {
|
|||||||
);
|
);
|
||||||
customElements.define('affine-attachment', AttachmentBlockComponent);
|
customElements.define('affine-attachment', AttachmentBlockComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
|
||||||
namespace BlockSuite {
|
|
||||||
interface BlockServices {
|
|
||||||
'affine:attachment': AttachmentBlockService;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,10 +2,12 @@ import type {
|
|||||||
AttachmentBlockModel,
|
AttachmentBlockModel,
|
||||||
ImageBlockProps,
|
ImageBlockProps,
|
||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
|
import { FileSizeLimitService } from '@blocksuite/affine-shared/services';
|
||||||
import {
|
import {
|
||||||
transformModel,
|
transformModel,
|
||||||
withTempBlobData,
|
withTempBlobData,
|
||||||
} from '@blocksuite/affine-shared/utils';
|
} from '@blocksuite/affine-shared/utils';
|
||||||
|
import { type BlockStdScope, StdIdentifier } from '@blocksuite/block-std';
|
||||||
import type { Container } from '@blocksuite/global/di';
|
import type { Container } from '@blocksuite/global/di';
|
||||||
import { createIdentifier } from '@blocksuite/global/di';
|
import { createIdentifier } from '@blocksuite/global/di';
|
||||||
import type { ExtensionType } from '@blocksuite/store';
|
import type { ExtensionType } from '@blocksuite/store';
|
||||||
@@ -57,8 +59,9 @@ export const AttachmentEmbedProvider = createIdentifier<AttachmentEmbedService>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export class AttachmentEmbedService extends Extension {
|
export class AttachmentEmbedService extends Extension {
|
||||||
// 10MB
|
private get _maxFileSize() {
|
||||||
static MAX_EMBED_SIZE = 10 * 1024 * 1024;
|
return this.std.store.get(FileSizeLimitService).maxFileSize;
|
||||||
|
}
|
||||||
|
|
||||||
get keys() {
|
get keys() {
|
||||||
return this.configs.keys();
|
return this.configs.keys();
|
||||||
@@ -68,7 +71,10 @@ export class AttachmentEmbedService extends Extension {
|
|||||||
return this.configs.values();
|
return this.configs.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(private readonly configs: Map<string, AttachmentEmbedConfig>) {
|
constructor(
|
||||||
|
private readonly std: BlockStdScope,
|
||||||
|
private readonly configs: Map<string, AttachmentEmbedConfig>
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,15 +83,13 @@ export class AttachmentEmbedService extends Extension {
|
|||||||
provider.getAll(AttachmentEmbedConfigIdentifier)
|
provider.getAll(AttachmentEmbedConfigIdentifier)
|
||||||
);
|
);
|
||||||
di.addImpl(AttachmentEmbedProvider, AttachmentEmbedService, [
|
di.addImpl(AttachmentEmbedProvider, AttachmentEmbedService, [
|
||||||
|
StdIdentifier,
|
||||||
AttachmentEmbedConfigMapIdentifier,
|
AttachmentEmbedConfigMapIdentifier,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts to embed view.
|
// Converts to embed view.
|
||||||
convertTo(
|
convertTo(model: AttachmentBlockModel, maxFileSize = this._maxFileSize) {
|
||||||
model: AttachmentBlockModel,
|
|
||||||
maxFileSize = AttachmentEmbedService.MAX_EMBED_SIZE
|
|
||||||
) {
|
|
||||||
const config = this.values.find(config => config.check(model, maxFileSize));
|
const config = this.values.find(config => config.check(model, maxFileSize));
|
||||||
if (!config || !config.action) {
|
if (!config || !config.action) {
|
||||||
model.doc.updateBlock(model, { embed: true });
|
model.doc.updateBlock(model, { embed: true });
|
||||||
@@ -94,17 +98,14 @@ export class AttachmentEmbedService extends Extension {
|
|||||||
config.action(model)?.catch(console.error);
|
config.action(model)?.catch(console.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
embedded(
|
embedded(model: AttachmentBlockModel, maxFileSize = this._maxFileSize) {
|
||||||
model: AttachmentBlockModel,
|
|
||||||
maxFileSize = AttachmentEmbedService.MAX_EMBED_SIZE
|
|
||||||
) {
|
|
||||||
return this.values.some(config => config.check(model, maxFileSize));
|
return this.values.some(config => config.check(model, maxFileSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
render(
|
render(
|
||||||
model: AttachmentBlockModel,
|
model: AttachmentBlockModel,
|
||||||
blobUrl?: string,
|
blobUrl?: string,
|
||||||
maxFileSize = AttachmentEmbedService.MAX_EMBED_SIZE
|
maxFileSize = this._maxFileSize
|
||||||
) {
|
) {
|
||||||
if (!model.embed || !blobUrl) return;
|
if (!model.embed || !blobUrl) return;
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,10 @@ import {
|
|||||||
EMBED_CARD_HEIGHT,
|
EMBED_CARD_HEIGHT,
|
||||||
EMBED_CARD_WIDTH,
|
EMBED_CARD_WIDTH,
|
||||||
} from '@blocksuite/affine-shared/consts';
|
} from '@blocksuite/affine-shared/consts';
|
||||||
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
import {
|
||||||
|
FileSizeLimitService,
|
||||||
|
TelemetryProvider,
|
||||||
|
} from '@blocksuite/affine-shared/services';
|
||||||
import { humanFileSize } from '@blocksuite/affine-shared/utils';
|
import { humanFileSize } from '@blocksuite/affine-shared/utils';
|
||||||
import type { BlockStdScope, EditorHost } from '@blocksuite/block-std';
|
import type { BlockStdScope, EditorHost } from '@blocksuite/block-std';
|
||||||
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
|
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
|
||||||
@@ -272,7 +275,7 @@ export async function addAttachments(
|
|||||||
console.error('Attachment service not found');
|
console.error('Attachment service not found');
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const maxFileSize = attachmentService.maxFileSize;
|
const maxFileSize = std.store.get(FileSizeLimitService).maxFileSize;
|
||||||
const isSizeExceeded = files.some(file => file.size > maxFileSize);
|
const isSizeExceeded = files.some(file => file.size > maxFileSize);
|
||||||
if (isSizeExceeded) {
|
if (isSizeExceeded) {
|
||||||
toast(
|
toast(
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { FileSizeLimitService } from '@blocksuite/affine-shared/services';
|
||||||
import { getImageFilesFromLocal } from '@blocksuite/affine-shared/utils';
|
import { getImageFilesFromLocal } from '@blocksuite/affine-shared/utils';
|
||||||
import type { Command } from '@blocksuite/block-std';
|
import type { Command } from '@blocksuite/block-std';
|
||||||
import type { BlockModel } from '@blocksuite/store';
|
import type { BlockModel } from '@blocksuite/store';
|
||||||
@@ -28,10 +29,7 @@ export const insertImagesCommand: Command<
|
|||||||
? selectedModels[0]
|
? selectedModels[0]
|
||||||
: selectedModels[selectedModels.length - 1];
|
: selectedModels[selectedModels.length - 1];
|
||||||
|
|
||||||
const imageService = std.getService('affine:image');
|
const maxFileSize = std.store.get(FileSizeLimitService).maxFileSize;
|
||||||
if (!imageService) return [];
|
|
||||||
|
|
||||||
const maxFileSize = imageService.maxFileSize;
|
|
||||||
|
|
||||||
const result = addSiblingImageBlock(
|
const result = addSiblingImageBlock(
|
||||||
std.host,
|
std.host,
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { ImageBlockFallbackCard } from './components/image-block-fallback.js';
|
|||||||
import { ImageBlockPageComponent } from './components/page-image-block.js';
|
import { ImageBlockPageComponent } from './components/page-image-block.js';
|
||||||
import { ImageBlockComponent } from './image-block.js';
|
import { ImageBlockComponent } from './image-block.js';
|
||||||
import { ImageEdgelessBlockComponent } from './image-edgeless-block.js';
|
import { ImageEdgelessBlockComponent } from './image-edgeless-block.js';
|
||||||
import type { ImageBlockService } from './image-service.js';
|
|
||||||
|
|
||||||
export function effects() {
|
export function effects() {
|
||||||
customElements.define('affine-image', ImageBlockComponent);
|
customElements.define('affine-image', ImageBlockComponent);
|
||||||
@@ -10,11 +9,3 @@ export function effects() {
|
|||||||
customElements.define('affine-page-image', ImageBlockPageComponent);
|
customElements.define('affine-page-image', ImageBlockPageComponent);
|
||||||
customElements.define('affine-image-fallback-card', ImageBlockFallbackCard);
|
customElements.define('affine-image-fallback-card', ImageBlockFallbackCard);
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
|
||||||
namespace BlockSuite {
|
|
||||||
interface BlockServices {
|
|
||||||
'affine:image': ImageBlockService;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import { when } from 'lit/directives/when.js';
|
|||||||
|
|
||||||
import type { ImageBlockFallbackCard } from './components/image-block-fallback.js';
|
import type { ImageBlockFallbackCard } from './components/image-block-fallback.js';
|
||||||
import type { ImageBlockPageComponent } from './components/page-image-block.js';
|
import type { ImageBlockPageComponent } from './components/page-image-block.js';
|
||||||
import type { ImageBlockService } from './image-service.js';
|
|
||||||
import {
|
import {
|
||||||
copyImageBlob,
|
copyImageBlob,
|
||||||
downloadImageBlob,
|
downloadImageBlob,
|
||||||
@@ -21,10 +20,7 @@ import {
|
|||||||
@Peekable({
|
@Peekable({
|
||||||
enableOn: () => !IS_MOBILE,
|
enableOn: () => !IS_MOBILE,
|
||||||
})
|
})
|
||||||
export class ImageBlockComponent extends CaptionedBlockComponent<
|
export class ImageBlockComponent extends CaptionedBlockComponent<ImageBlockModel> {
|
||||||
ImageBlockModel,
|
|
||||||
ImageBlockService
|
|
||||||
> {
|
|
||||||
convertToCardView = () => {
|
convertToCardView = () => {
|
||||||
turnImageIntoCardView(this).catch(console.error);
|
turnImageIntoCardView(this).catch(console.error);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { styleMap } from 'lit/directives/style-map.js';
|
|||||||
import { when } from 'lit/directives/when.js';
|
import { when } from 'lit/directives/when.js';
|
||||||
|
|
||||||
import type { ImageBlockFallbackCard } from './components/image-block-fallback.js';
|
import type { ImageBlockFallbackCard } from './components/image-block-fallback.js';
|
||||||
import type { ImageBlockService } from './image-service.js';
|
|
||||||
import {
|
import {
|
||||||
copyImageBlob,
|
copyImageBlob,
|
||||||
downloadImageBlob,
|
downloadImageBlob,
|
||||||
@@ -18,10 +17,7 @@ import {
|
|||||||
} from './utils.js';
|
} from './utils.js';
|
||||||
|
|
||||||
@Peekable()
|
@Peekable()
|
||||||
export class ImageEdgelessBlockComponent extends GfxBlockComponent<
|
export class ImageEdgelessBlockComponent extends GfxBlockComponent<ImageBlockModel> {
|
||||||
ImageBlockModel,
|
|
||||||
ImageBlockService
|
|
||||||
> {
|
|
||||||
static override styles = css`
|
static override styles = css`
|
||||||
affine-edgeless-image .resizable-img,
|
affine-edgeless-image .resizable-img,
|
||||||
affine-edgeless-image .resizable-img img {
|
affine-edgeless-image .resizable-img img {
|
||||||
|
|||||||
9
blocksuite/affine/block-image/src/image-proxy-service.ts
Normal file
9
blocksuite/affine/block-image/src/image-proxy-service.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { StoreExtension } from '@blocksuite/store';
|
||||||
|
|
||||||
|
import { setImageProxyMiddlewareURL } from './adapters/middleware';
|
||||||
|
|
||||||
|
export class ImageProxyService extends StoreExtension {
|
||||||
|
static override key = 'image-proxy';
|
||||||
|
|
||||||
|
setImageProxyURL = setImageProxyMiddlewareURL;
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
import { FileDropConfigExtension } from '@blocksuite/affine-components/drop-indicator';
|
import { FileDropConfigExtension } from '@blocksuite/affine-components/drop-indicator';
|
||||||
import { ImageBlockSchema, MAX_IMAGE_WIDTH } from '@blocksuite/affine-model';
|
import { ImageBlockSchema, MAX_IMAGE_WIDTH } from '@blocksuite/affine-model';
|
||||||
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
import {
|
||||||
|
FileSizeLimitService,
|
||||||
|
TelemetryProvider,
|
||||||
|
} from '@blocksuite/affine-shared/services';
|
||||||
import {
|
import {
|
||||||
isInsideEdgelessEditor,
|
isInsideEdgelessEditor,
|
||||||
matchFlavours,
|
matchFlavours,
|
||||||
@@ -8,18 +11,10 @@ import {
|
|||||||
import { BlockService } from '@blocksuite/block-std';
|
import { BlockService } from '@blocksuite/block-std';
|
||||||
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
|
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
|
||||||
|
|
||||||
import { setImageProxyMiddlewareURL } from './adapters/middleware.js';
|
|
||||||
import { addImages, addSiblingImageBlock } from './utils.js';
|
import { addImages, addSiblingImageBlock } from './utils.js';
|
||||||
|
|
||||||
// bytes.parse('2GB')
|
|
||||||
const maxFileSize = 2147483648;
|
|
||||||
|
|
||||||
export class ImageBlockService extends BlockService {
|
export class ImageBlockService extends BlockService {
|
||||||
static override readonly flavour = ImageBlockSchema.model.flavour;
|
static override readonly flavour = ImageBlockSchema.model.flavour;
|
||||||
|
|
||||||
static setImageProxyURL = setImageProxyMiddlewareURL;
|
|
||||||
|
|
||||||
maxFileSize = maxFileSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ImageDropOption = FileDropConfigExtension({
|
export const ImageDropOption = FileDropConfigExtension({
|
||||||
@@ -28,11 +23,12 @@ export const ImageDropOption = FileDropConfigExtension({
|
|||||||
const imageFiles = files.filter(file => file.type.startsWith('image/'));
|
const imageFiles = files.filter(file => file.type.startsWith('image/'));
|
||||||
if (!imageFiles.length) return false;
|
if (!imageFiles.length) return false;
|
||||||
|
|
||||||
|
const maxFileSize = std.store.get(FileSizeLimitService).maxFileSize;
|
||||||
|
|
||||||
if (targetModel && !matchFlavours(targetModel, ['affine:surface'])) {
|
if (targetModel && !matchFlavours(targetModel, ['affine:surface'])) {
|
||||||
addSiblingImageBlock(
|
addSiblingImageBlock(
|
||||||
std.host,
|
std.host,
|
||||||
imageFiles,
|
imageFiles,
|
||||||
// TODO: use max file size from service
|
|
||||||
maxFileSize,
|
maxFileSize,
|
||||||
targetModel,
|
targetModel,
|
||||||
placement
|
placement
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import type { ExtensionType } from '@blocksuite/store';
|
|||||||
import { literal } from 'lit/static-html.js';
|
import { literal } from 'lit/static-html.js';
|
||||||
|
|
||||||
import { ImageBlockAdapterExtensions } from './adapters/extension.js';
|
import { ImageBlockAdapterExtensions } from './adapters/extension.js';
|
||||||
|
import { ImageProxyService } from './image-proxy-service.js';
|
||||||
import { ImageBlockService, ImageDropOption } from './image-service.js';
|
import { ImageBlockService, ImageDropOption } from './image-service.js';
|
||||||
|
|
||||||
export const ImageBlockSpec: ExtensionType[] = [
|
export const ImageBlockSpec: ExtensionType[] = [
|
||||||
@@ -27,3 +28,5 @@ export const ImageBlockSpec: ExtensionType[] = [
|
|||||||
ImageDropOption,
|
ImageDropOption,
|
||||||
ImageBlockAdapterExtensions,
|
ImageBlockAdapterExtensions,
|
||||||
].flat();
|
].flat();
|
||||||
|
|
||||||
|
export const ImageStoreSpec: ExtensionType[] = [ImageProxyService].flat();
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export * from './adapters';
|
|||||||
export * from './commands';
|
export * from './commands';
|
||||||
export * from './image-block';
|
export * from './image-block';
|
||||||
export * from './image-edgeless-block';
|
export * from './image-edgeless-block';
|
||||||
|
export { ImageProxyService } from './image-proxy-service';
|
||||||
export * from './image-service';
|
export * from './image-service';
|
||||||
export * from './image-spec';
|
export * from './image-spec';
|
||||||
export * from './styles';
|
export * from './styles';
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ import type {
|
|||||||
ImageBlockModel,
|
ImageBlockModel,
|
||||||
ImageBlockProps,
|
ImageBlockProps,
|
||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
import { NativeClipboardProvider } from '@blocksuite/affine-shared/services';
|
import {
|
||||||
|
FileSizeLimitService,
|
||||||
|
NativeClipboardProvider,
|
||||||
|
} from '@blocksuite/affine-shared/services';
|
||||||
import {
|
import {
|
||||||
downloadBlob,
|
downloadBlob,
|
||||||
humanFileSize,
|
humanFileSize,
|
||||||
@@ -430,15 +433,9 @@ export async function addImages(
|
|||||||
const imageFiles = [...files].filter(file => file.type.startsWith('image/'));
|
const imageFiles = [...files].filter(file => file.type.startsWith('image/'));
|
||||||
if (!imageFiles.length) return [];
|
if (!imageFiles.length) return [];
|
||||||
|
|
||||||
const imageService = std.getService('affine:image');
|
|
||||||
const gfx = std.get(GfxControllerIdentifier);
|
const gfx = std.get(GfxControllerIdentifier);
|
||||||
|
|
||||||
if (!imageService) {
|
const maxFileSize = std.store.get(FileSizeLimitService).maxFileSize;
|
||||||
console.error('Image service not found');
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const maxFileSize = imageService.maxFileSize;
|
|
||||||
const isSizeExceeded = imageFiles.some(file => file.size > maxFileSize);
|
const isSizeExceeded = imageFiles.some(file => file.size > maxFileSize);
|
||||||
if (isSizeExceeded) {
|
if (isSizeExceeded) {
|
||||||
toast(
|
toast(
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { StoreExtension } from '@blocksuite/store';
|
||||||
|
|
||||||
|
// bytes.parse('2GB')
|
||||||
|
const maxFileSize = 2147483648;
|
||||||
|
|
||||||
|
export class FileSizeLimitService extends StoreExtension {
|
||||||
|
static override key = 'file-size-limit';
|
||||||
|
|
||||||
|
maxFileSize = maxFileSize;
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ export * from './edit-props-store';
|
|||||||
export * from './editor-setting-service';
|
export * from './editor-setting-service';
|
||||||
export * from './embed-option-service';
|
export * from './embed-option-service';
|
||||||
export * from './feature-flag-service';
|
export * from './feature-flag-service';
|
||||||
|
export * from './file-size-limit-service';
|
||||||
export * from './font-loader';
|
export * from './font-loader';
|
||||||
export * from './generate-url-service';
|
export * from './generate-url-service';
|
||||||
export * from './link-previewer-service';
|
export * from './link-previewer-service';
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { DividerBlockSpec } from '@blocksuite/affine-block-divider';
|
|||||||
import { EdgelessTextBlockSpec } from '@blocksuite/affine-block-edgeless-text';
|
import { EdgelessTextBlockSpec } from '@blocksuite/affine-block-edgeless-text';
|
||||||
import { EmbedExtensions } from '@blocksuite/affine-block-embed';
|
import { EmbedExtensions } from '@blocksuite/affine-block-embed';
|
||||||
import { FrameBlockSpec } from '@blocksuite/affine-block-frame';
|
import { FrameBlockSpec } from '@blocksuite/affine-block-frame';
|
||||||
import { ImageBlockSpec } from '@blocksuite/affine-block-image';
|
import { ImageBlockSpec, ImageStoreSpec } from '@blocksuite/affine-block-image';
|
||||||
import { LatexBlockSpec } from '@blocksuite/affine-block-latex';
|
import { LatexBlockSpec } from '@blocksuite/affine-block-latex';
|
||||||
import { ListBlockSpec } from '@blocksuite/affine-block-list';
|
import { ListBlockSpec } from '@blocksuite/affine-block-list';
|
||||||
import {
|
import {
|
||||||
@@ -43,6 +43,7 @@ import {
|
|||||||
DocDisplayMetaService,
|
DocDisplayMetaService,
|
||||||
EditPropsStore,
|
EditPropsStore,
|
||||||
FeatureFlagService,
|
FeatureFlagService,
|
||||||
|
FileSizeLimitService,
|
||||||
FontLoaderService,
|
FontLoaderService,
|
||||||
LinkPreviewerService,
|
LinkPreviewerService,
|
||||||
} from '@blocksuite/affine-shared/services';
|
} from '@blocksuite/affine-shared/services';
|
||||||
@@ -107,4 +108,7 @@ export const StoreExtensions: ExtensionType[] = [
|
|||||||
DatabaseSelectionExtension,
|
DatabaseSelectionExtension,
|
||||||
TableSelectionExtension,
|
TableSelectionExtension,
|
||||||
LinkPreviewerService,
|
LinkPreviewerService,
|
||||||
];
|
FileSizeLimitService,
|
||||||
|
|
||||||
|
ImageStoreSpec,
|
||||||
|
].flat();
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import {
|
|||||||
getTextSelectionCommand,
|
getTextSelectionCommand,
|
||||||
} from '@blocksuite/affine-shared/commands';
|
} from '@blocksuite/affine-shared/commands';
|
||||||
import { REFERENCE_NODE } from '@blocksuite/affine-shared/consts';
|
import { REFERENCE_NODE } from '@blocksuite/affine-shared/consts';
|
||||||
|
import { FileSizeLimitService } from '@blocksuite/affine-shared/services';
|
||||||
import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
|
import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
|
||||||
import {
|
import {
|
||||||
createDefaultDoc,
|
createDefaultDoc,
|
||||||
@@ -436,9 +437,7 @@ const contentMediaToolGroup: KeyboardToolPanelGroup = {
|
|||||||
const file = await openFileOrFiles();
|
const file = await openFileOrFiles();
|
||||||
if (!file) return;
|
if (!file) return;
|
||||||
|
|
||||||
const attachmentService = std.getService('affine:attachment');
|
const maxFileSize = std.store.get(FileSizeLimitService).maxFileSize;
|
||||||
if (!attachmentService) return;
|
|
||||||
const maxFileSize = attachmentService.maxFileSize;
|
|
||||||
|
|
||||||
await addSiblingAttachmentBlocks(std.host, [file], maxFileSize, model);
|
await addSiblingAttachmentBlocks(std.host, [file], maxFileSize, model);
|
||||||
if (model.text?.length === 0) {
|
if (model.text?.length === 0) {
|
||||||
@@ -994,9 +993,7 @@ export const defaultKeyboardToolbarConfig: KeyboardToolbarConfig = {
|
|||||||
const file = await openFileOrFiles();
|
const file = await openFileOrFiles();
|
||||||
if (!file) return;
|
if (!file) return;
|
||||||
|
|
||||||
const attachmentService = std.getService('affine:attachment');
|
const maxFileSize = std.store.get(FileSizeLimitService).maxFileSize;
|
||||||
if (!attachmentService) return;
|
|
||||||
const maxFileSize = attachmentService.maxFileSize;
|
|
||||||
|
|
||||||
await addSiblingAttachmentBlocks(std.host, [file], maxFileSize, model);
|
await addSiblingAttachmentBlocks(std.host, [file], maxFileSize, model);
|
||||||
if (model.text?.length === 0) {
|
if (model.text?.length === 0) {
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ import {
|
|||||||
import { REFERENCE_NODE } from '@blocksuite/affine-shared/consts';
|
import { REFERENCE_NODE } from '@blocksuite/affine-shared/consts';
|
||||||
import {
|
import {
|
||||||
FeatureFlagService,
|
FeatureFlagService,
|
||||||
|
FileSizeLimitService,
|
||||||
TelemetryProvider,
|
TelemetryProvider,
|
||||||
} from '@blocksuite/affine-shared/services';
|
} from '@blocksuite/affine-shared/services';
|
||||||
import {
|
import {
|
||||||
@@ -324,10 +325,8 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
|
|||||||
const file = await openFileOrFiles();
|
const file = await openFileOrFiles();
|
||||||
if (!file) return;
|
if (!file) return;
|
||||||
|
|
||||||
const attachmentService =
|
const maxFileSize =
|
||||||
rootComponent.std.getService('affine:attachment');
|
rootComponent.std.store.get(FileSizeLimitService).maxFileSize;
|
||||||
if (!attachmentService) return;
|
|
||||||
const maxFileSize = attachmentService.maxFileSize;
|
|
||||||
|
|
||||||
await addSiblingAttachmentBlocks(
|
await addSiblingAttachmentBlocks(
|
||||||
rootComponent.host,
|
rootComponent.host,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { ServerService } from '@affine/core/modules/cloud';
|
|||||||
import {
|
import {
|
||||||
customImageProxyMiddleware,
|
customImageProxyMiddleware,
|
||||||
type DocMode,
|
type DocMode,
|
||||||
ImageBlockService,
|
ImageProxyService,
|
||||||
LinkPreviewerService,
|
LinkPreviewerService,
|
||||||
} from '@blocksuite/affine/blocks';
|
} from '@blocksuite/affine/blocks';
|
||||||
import { DisposableGroup } from '@blocksuite/affine/global/utils';
|
import { DisposableGroup } from '@blocksuite/affine/global/utils';
|
||||||
@@ -75,14 +75,14 @@ const BlockSuiteEditorImpl = ({
|
|||||||
BUILD_CONFIG.linkPreviewUrl,
|
BUILD_CONFIG.linkPreviewUrl,
|
||||||
server.baseUrl
|
server.baseUrl
|
||||||
).toString();
|
).toString();
|
||||||
|
|
||||||
editor.host?.std.clipboard.use(
|
editor.host?.std.clipboard.use(
|
||||||
customImageProxyMiddleware(imageProxyUrl)
|
customImageProxyMiddleware(imageProxyUrl)
|
||||||
);
|
);
|
||||||
ImageBlockService.setImageProxyURL(imageProxyUrl);
|
|
||||||
|
|
||||||
editor.host?.doc
|
page.get(LinkPreviewerService).setEndpoint(linkPreviewUrl);
|
||||||
.get(LinkPreviewerService)
|
|
||||||
.setEndpoint(linkPreviewUrl);
|
page.get(ImageProxyService).setImageProxyURL(imageProxyUrl);
|
||||||
|
|
||||||
return editor.host?.updateComplete;
|
return editor.host?.updateComplete;
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import { WorkspaceService } from '@affine/core/modules/workspace';
|
|||||||
import { i18nTime } from '@affine/i18n';
|
import { i18nTime } from '@affine/i18n';
|
||||||
import {
|
import {
|
||||||
customImageProxyMiddleware,
|
customImageProxyMiddleware,
|
||||||
ImageBlockService,
|
ImageProxyService,
|
||||||
LinkPreviewerService,
|
LinkPreviewerService,
|
||||||
RefNodeSlotsProvider,
|
RefNodeSlotsProvider,
|
||||||
} from '@blocksuite/affine/blocks';
|
} from '@blocksuite/affine/blocks';
|
||||||
@@ -162,7 +162,7 @@ const DetailPageImpl = () => {
|
|||||||
).toString();
|
).toString();
|
||||||
|
|
||||||
editorHost?.std.clipboard.use(customImageProxyMiddleware(imageProxyUrl));
|
editorHost?.std.clipboard.use(customImageProxyMiddleware(imageProxyUrl));
|
||||||
ImageBlockService.setImageProxyURL(imageProxyUrl);
|
editorHost?.doc.get(ImageProxyService).setImageProxyURL(imageProxyUrl);
|
||||||
|
|
||||||
// provide link preview endpoint to blocksuite
|
// provide link preview endpoint to blocksuite
|
||||||
editorHost?.doc.get(LinkPreviewerService).setEndpoint(linkPreviewUrl);
|
editorHost?.doc.get(LinkPreviewerService).setEndpoint(linkPreviewUrl);
|
||||||
|
|||||||
Reference in New Issue
Block a user