Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(docs): pictures support writing to the clipboard #4086

Merged
merged 6 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import type { DocumentDataModel, ICommandInfo, IDocDrawingPosition, Nullable } from '@univerjs/core';
import type { IDocDrawing } from '@univerjs/docs-drawing';
import type { IImageIoServiceParam } from '@univerjs/drawing';
import type { IDrawingParam, IImageIoServiceParam } from '@univerjs/drawing';
import type { Documents, Image, IRenderContext, IRenderModule } from '@univerjs/engine-render';
import type { IInsertDrawingCommandParams } from '../../commands/commands/interfaces';
import { BooleanNumber, Disposable, FOCUSING_COMMON_DRAWINGS, ICommandService, IContextService, Inject, LocaleService, ObjectRelativeFromH, ObjectRelativeFromV, PositionedObjectLayoutType, WrapTextType } from '@univerjs/core';
Expand All @@ -28,6 +28,7 @@ import { DRAWING_IMAGE_ALLOW_IMAGE_LIST, DRAWING_IMAGE_ALLOW_SIZE, DRAWING_IMAGE
import { DocumentEditArea, IRenderManagerService } from '@univerjs/engine-render';

import { ILocalFileService, IMessageService } from '@univerjs/ui';
import { debounceTime } from 'rxjs';
import { GroupDocDrawingCommand } from '../../commands/commands/group-doc-drawing.command';
import { InsertDocDrawingCommand } from '../../commands/commands/insert-doc-drawing.command';
import { type ISetDrawingArrangeCommandParams, SetDocDrawingArrangeCommand } from '../../commands/commands/set-drawing-arrange.command';
Expand Down Expand Up @@ -55,7 +56,7 @@ export class DocDrawingUpdateRenderController extends Disposable implements IRen
this._updateOrderListener();
this._groupDrawingListener();
this._focusDrawingListener();

this._transformDrawingListener();
this._editAreaChangeListener();
}

Expand Down Expand Up @@ -250,6 +251,17 @@ export class DocDrawingUpdateRenderController extends Disposable implements IRen
return { scene, transformer, docsLeft, docsTop };
}

private _transformDrawingListener() {
const res = this._getCurrentSceneAndTransformer();
if (res && res.transformer) {
this.disposeWithMe(res.transformer.changeEnd$.pipe(debounceTime(30)).subscribe((params) => {
this._docSelectionManagerService.refreshSelection();
}));
} else {
throw new Error('transformer is not init');
}
}

private _focusDrawingListener() {
this.disposeWithMe(
this._drawingManagerService.focus$.subscribe((params) => {
Expand All @@ -267,12 +279,7 @@ export class DocDrawingUpdateRenderController extends Disposable implements IRen
} else {
this._contextService.setContextValue(FOCUSING_COMMON_DRAWINGS, true);
this._docDrawingService.focusDrawing(params);
// Need to remove text selections when focus drawings.
const activeTextRange = this._docSelectionManagerService.getActiveTextRange();
if (activeTextRange) {
this._docSelectionManagerService.replaceTextRanges([]);
}

this._setDrawingSelections(params);
const prevSegmentId = this._docSelectionRenderService.getSegment();
const segmentId = this._findSegmentIdByDrawingId(params[0].drawingId);

Expand Down Expand Up @@ -396,4 +403,18 @@ export class DocDrawingUpdateRenderController extends Disposable implements IRen
})
);
}

private _setDrawingSelections(params: IDrawingParam[]) {
const { unit } = this._context;
const customBlocks = unit.getSnapshot().body?.customBlocks ?? [];
const ranges = params.map((item) => {
const id = item.drawingId;
const block = customBlocks.find((b) => b.blockId === id);
if (block) {
return block.startIndex;
}
return null;
}).filter((e) => e !== null).map((offset) => ({ startOffset: offset, endOffset: offset + 1 }));
this._docSelectionManagerService.replaceDocRanges(ranges);
}
}
2 changes: 1 addition & 1 deletion packages/docs-drawing/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
*/

export { UniverDocsDrawingPlugin } from './plugin';
export { DocDrawingService, type IDocDrawing, IDocDrawingService } from './services/doc-drawing.service';
export { DocDrawingService, type IDocDrawing, IDocDrawingService, type IDocImage } from './services/doc-drawing.service';

export { DOCS_DRAWING_PLUGIN, type IDocDrawingModel } from './controllers/doc-drawing.controller';
2 changes: 2 additions & 0 deletions packages/docs-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@
"@univerjs/core": "workspace:*",
"@univerjs/design": "workspace:*",
"@univerjs/docs": "workspace:*",
"@univerjs/docs-drawing": "workspace:*",
"@univerjs/drawing": "workspace:*",
"@univerjs/engine-formula": "workspace:*",
"@univerjs/engine-render": "workspace:*",
"@univerjs/icons": "^0.2.7",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ import {
Inject,
RxDisposable,
} from '@univerjs/core';
import {
FILE__BMP_CLIPBOARD_MIME_TYPE,
FILE__JPEG_CLIPBOARD_MIME_TYPE,
FILE__WEBP_CLIPBOARD_MIME_TYPE,
FILE_PNG_CLIPBOARD_MIME_TYPE,
HTML_CLIPBOARD_MIME_TYPE,
PLAIN_TEXT_CLIPBOARD_MIME_TYPE,
} from '@univerjs/ui';
import { takeUntil } from 'rxjs';
import { whenDocOrEditor } from '../../commands/commands/clipboard.command';
import { IDocClipboardService } from '../../services/clipboard/clipboard.service';
Expand All @@ -37,6 +45,7 @@ export class DocClipboardController extends RxDisposable implements IRenderModul
@Inject(DocSelectionRenderService) private readonly _docSelectionRenderService: DocSelectionRenderService,
@IContextService private readonly _contextService: IContextService,
@IEditorService private readonly _editorService: IEditorService

) {
super();

Expand All @@ -55,8 +64,20 @@ export class DocClipboardController extends RxDisposable implements IRenderModul

config!.event.preventDefault();
const clipboardEvent = config!.event as ClipboardEvent;
let htmlContent = clipboardEvent.clipboardData?.getData('text/html');
const textContent = clipboardEvent.clipboardData?.getData('text/plain');
let htmlContent = clipboardEvent.clipboardData?.getData(HTML_CLIPBOARD_MIME_TYPE);
const textContent = clipboardEvent.clipboardData?.getData(PLAIN_TEXT_CLIPBOARD_MIME_TYPE);

const imageTypes = [
FILE__BMP_CLIPBOARD_MIME_TYPE,
FILE__JPEG_CLIPBOARD_MIME_TYPE,
FILE__WEBP_CLIPBOARD_MIME_TYPE,
FILE_PNG_CLIPBOARD_MIME_TYPE,
];

const files = [...(clipboardEvent.clipboardData?.items || [])]
.filter((item) => imageTypes.includes(item.type))
.map((item) => item.getAsFile()!)
.filter((e) => !!e);

// TODO: @JOCS, work around to fix https://github.com/dream-num/univer-pro/issues/2006. and then when you paste it,
// you need to distinguish between different editors,
Expand All @@ -67,7 +88,7 @@ export class DocClipboardController extends RxDisposable implements IRenderModul
htmlContent = '';
}

this._docClipboardService.legacyPaste(htmlContent, textContent);
this._docClipboardService.legacyPaste({ html: htmlContent, text: textContent, files });
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ describe('test case in html and udm convert', () => {
describe('test cases in udm-to-html', () => {
it('should paste the case when convert udm to html', async () => {
const convertor = new UDMToHtmlService();
const html = await convertor.convert([body!]);
const html = await convertor.convert([{ body: body!, id: '', documentStyle: {} }]);

expect(html).toBe('<p class="UniverNormal" ><strong>hello</strong><strong><i>world</i></strong></p>');
});
Expand Down
Loading
Loading