fix(sheets-drawing-ui): sheet-drawing memory leak (#4067)

This commit is contained in:
zhangw
2024-11-14 20:31:41 +08:00
committed by GitHub
parent 7550f1cef8
commit 4e64ebbdf7
4 changed files with 50 additions and 28 deletions
@@ -24136,6 +24136,24 @@ export const DEFAULT_WORKBOOK_DATA_DEMO: IWorkbookData = {
'UPBpL-A3RvKoOqPdd8VIq',
],
},
'dv-test': {
data: {
'UPBpL-test': {
unitId: 'workbook-01',
subUnitId: 'dv-test',
drawingId: 'UPBpL-test',
drawingType: 8,
componentKey: 'ImageDemo',
sheetTransform: {
from: { column: 2, columnOffset: 8, row: 9, rowOffset: 9 },
to: { column: 4, columnOffset: 62, row: 23, rowOffset: 0 },
},
transform: { flipY: false, flipX: false, angle: 0, skewX: 0, skewY: 0, left: 200, top: 200, width: 200, height: 200 },
data: { aa: '128' },
},
},
order: ['UPBpL-test'],
},
}),
},
{
@@ -14,6 +14,13 @@
* limitations under the License.
*/
import type { IRange, Nullable, Workbook } from '@univerjs/core';
import type { IImageData, IImageIoServiceParam } from '@univerjs/drawing';
import type { IRenderContext, IRenderModule } from '@univerjs/engine-render';
import type { WorkbookSelections } from '@univerjs/sheets';
import type { ISheetDrawing, ISheetDrawingPosition } from '@univerjs/sheets-drawing';
import type { IInsertDrawingCommandParams, ISetDrawingCommandParams } from '../commands/commands/interfaces';
import type { ISetDrawingArrangeCommandParams } from '../commands/commands/set-drawing-arrange.command';
import { Disposable, FOCUSING_COMMON_DRAWINGS, ICommandService, IContextService, Inject, LocaleService } from '@univerjs/core';
import { MessageType } from '@univerjs/design';
import { DRAWING_IMAGE_ALLOW_IMAGE_LIST, DRAWING_IMAGE_ALLOW_SIZE, DRAWING_IMAGE_COUNT_LIMIT, DRAWING_IMAGE_HEIGHT_LIMIT, DRAWING_IMAGE_WIDTH_LIMIT, DrawingTypeEnum, getImageSize, IDrawingManagerService, IImageIoService, ImageUploadStatusType } from '@univerjs/drawing';
@@ -21,19 +28,12 @@ import { SheetsSelectionsService } from '@univerjs/sheets';
import { ISheetDrawingService } from '@univerjs/sheets-drawing';
import { attachRangeWithCoord, ISheetSelectionRenderService, SheetSkeletonManagerService } from '@univerjs/sheets-ui';
import { ILocalFileService, IMessageService } from '@univerjs/ui';
import type { IRange, Nullable, Workbook } from '@univerjs/core';
import type { IImageData, IImageIoServiceParam } from '@univerjs/drawing';
import type { IRenderContext, IRenderModule } from '@univerjs/engine-render';
import type { WorkbookSelections } from '@univerjs/sheets';
import type { ISheetDrawing, ISheetDrawingPosition } from '@univerjs/sheets-drawing';
import { drawingPositionToTransform, transformToDrawingPosition } from '../basics/transform-position';
import { GroupSheetDrawingCommand } from '../commands/commands/group-sheet-drawing.command';
import { InsertSheetDrawingCommand } from '../commands/commands/insert-sheet-drawing.command';
import { SetDrawingArrangeCommand } from '../commands/commands/set-drawing-arrange.command';
import { SetSheetDrawingCommand } from '../commands/commands/set-sheet-drawing.command';
import { UngroupSheetDrawingCommand } from '../commands/commands/ungroup-sheet-drawing.command';
import type { IInsertDrawingCommandParams, ISetDrawingCommandParams } from '../commands/commands/interfaces';
import type { ISetDrawingArrangeCommandParams } from '../commands/commands/set-drawing-arrange.command';
export class SheetDrawingUpdateController extends Disposable implements IRenderModule {
private readonly _workbookSelections: WorkbookSelections;
@@ -241,7 +241,7 @@ export class SheetDrawingUpdateController extends Disposable implements IRenderM
}
private _updateOrderListener() {
this._drawingManagerService.featurePluginOrderUpdate$.subscribe((params) => {
this.disposeWithMe(this._drawingManagerService.featurePluginOrderUpdate$.subscribe((params) => {
const { unitId, subUnitId, drawingIds, arrangeType } = params;
this._commandService.executeCommand(SetDrawingArrangeCommand.id, {
@@ -250,11 +250,11 @@ export class SheetDrawingUpdateController extends Disposable implements IRenderM
drawingIds,
arrangeType,
} as ISetDrawingArrangeCommandParams);
});
}));
}
private _updateImageListener() {
this._drawingManagerService.featurePluginUpdate$.subscribe((params) => {
this.disposeWithMe(this._drawingManagerService.featurePluginUpdate$.subscribe((params) => {
const drawings: Partial<ISheetDrawing>[] = [];
if (params.length === 0) {
@@ -300,19 +300,19 @@ export class SheetDrawingUpdateController extends Disposable implements IRenderM
drawings,
} as ISetDrawingCommandParams);
}
});
}));
}
private _groupDrawingListener() {
this._drawingManagerService.featurePluginGroupUpdate$.subscribe((params) => {
this.disposeWithMe(this._drawingManagerService.featurePluginGroupUpdate$.subscribe((params) => {
this._commandService.executeCommand(GroupSheetDrawingCommand.id, params);
const { unitId, subUnitId, drawingId } = params[0].parent;
this._drawingManagerService.focusDrawing([{ unitId, subUnitId, drawingId }]);
});
}));
this._drawingManagerService.featurePluginUngroupUpdate$.subscribe((params) => {
this.disposeWithMe(this._drawingManagerService.featurePluginUngroupUpdate$.subscribe((params) => {
this._commandService.executeCommand(UngroupSheetDrawingCommand.id, params);
});
}));
}
private _focusDrawingListener() {
@@ -430,10 +430,6 @@ export class SheetCanvasFloatDomManagerService extends Disposable {
}
private _scrollUpdateListener() {
const workbook = this._univerInstanceService.getCurrentUnitForType<Workbook>(UniverInstanceType.UNIVER_SHEET)!;
if (!workbook) {
return;
}
const updateSheet = (unitId: string, subUnitId: string) => {
const renderObject = this._getSceneAndTransformerByDrawingSearch(unitId);
const map = this._ensureMap(unitId, subUnitId);
@@ -453,21 +449,22 @@ export class SheetCanvasFloatDomManagerService extends Disposable {
};
this.disposeWithMe(
workbook.activeSheet$.pipe(
this._univerInstanceService.getCurrentTypeOfUnit$<Workbook>(UniverInstanceType.UNIVER_SHEET).pipe(
filter((workbook) => !!workbook),
switchMap((workbook) => workbook.activeSheet$),
filter((sheet) => !!sheet),
map((sheet) => {
const render = this._renderManagerService.getRenderById(sheet.getUnitId());
return render ? { render, unitId: workbook.getUnitId(), subUnitId: sheet.getSheetId() } : null;
return render ? { render, unitId: sheet.getUnitId(), subUnitId: sheet.getSheetId() } : null;
}),
filter((render) => !!render),
switchMap((render) =>
fromEventSubject(render.render.scene.getViewport(VIEWPORT_KEY.VIEW_MAIN)!.onScrollAfter$)
.pipe(map(() => ({ unitId: render.unitId, subUnitId: render.subUnitId })))
)
)
.subscribe(({ unitId, subUnitId }) => {
updateSheet(unitId, subUnitId);
})
).subscribe(({ unitId, subUnitId }) => {
updateSheet(unitId, subUnitId);
})
);
this.disposeWithMe(this._commandService.onCommandExecuted((commandInfo) => {
@@ -39,6 +39,8 @@ const FloatDomSingle = memo((props: { layer: IFloatDom; id: string }) => {
const domRef = useRef<HTMLDivElement>(null);
const innerDomRef = useRef<HTMLDivElement>(null);
const transformRef = useRef<string>(`transform: rotate(${position?.rotate}deg) translate(${position?.startX}px, ${position?.startY}px)`);
const topRef = useRef<number>(position?.startY ?? 0);
const leftRef = useRef<number>(position?.startX ?? 0);
const innerStyle = useRef<React.CSSProperties>({
});
@@ -50,9 +52,13 @@ const FloatDomSingle = memo((props: { layer: IFloatDom; id: string }) => {
useEffect(() => {
const subscription = layer.position$.subscribe((position) => {
transformRef.current = `rotate(${position.rotate}deg) translate(${position.startX}px, ${position.startY}px)`;
transformRef.current = `rotate(${position.rotate}deg)`;
topRef.current = position.startY;
leftRef.current = position.startX;
if (domRef.current) {
domRef.current.style.transform = transformRef.current;
domRef.current.style.top = `${topRef.current}px`;
domRef.current.style.left = `${leftRef.current}px`;
}
});
@@ -100,12 +106,13 @@ const FloatDomSingle = memo((props: { layer: IFloatDom; id: string }) => {
className={styles.floatDomWrapper}
style={{
position: 'absolute',
top: 0,
left: 0,
top: topRef.current,
left: leftRef.current,
width: Math.max(position.endX - position.startX - 2, 0),
height: Math.max(position.endY - position.startY - 2, 0),
transform: transformRef.current,
overflow: 'hidden',
transformOrigin: 'center center',
}}
onPointerMove={(e) => {
layer.onPointerMove(e.nativeEvent);