mirror of
https://github.com/dream-num/univer.git
synced 2026-09-24 15:32:18 +08:00
feat(sheets-drawing-ui): add API to register custom URL image downloader (#6430)
Co-authored-by: weird94 <zhang9748@foxmail.com>
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { IDrawingSearch, Injector } from '@univerjs/core';
|
||||
import type { IDisposable, IDrawingSearch, Injector } from '@univerjs/core';
|
||||
import type { IEventBase } from '@univerjs/core/facade';
|
||||
import type { ISheetFloatDom, ISheetImage } from '@univerjs/sheets-drawing';
|
||||
import type { IDeleteDrawingCommandParams, IInsertDrawingCommandParams, ISetDrawingCommandParams } from '@univerjs/sheets-drawing-ui';
|
||||
@@ -28,7 +28,7 @@ import type {
|
||||
import { CanceledError, DrawingTypeEnum, ICommandService } from '@univerjs/core';
|
||||
import { FUniver } from '@univerjs/core/facade';
|
||||
import { IDrawingManagerService, SetDrawingSelectedOperation } from '@univerjs/drawing';
|
||||
import { InsertSheetDrawingCommand, RemoveSheetDrawingCommand, SetSheetDrawingCommand } from '@univerjs/sheets-drawing-ui';
|
||||
import { IBatchSaveImagesService, InsertSheetDrawingCommand, RemoveSheetDrawingCommand, SetSheetDrawingCommand } from '@univerjs/sheets-drawing-ui';
|
||||
import { FOverGridImage } from './f-over-grid-image';
|
||||
|
||||
interface IBeforeOverGridImageInsertParam extends IEventBase {
|
||||
@@ -476,6 +476,29 @@ export class FUniverDrawingMixin extends FUniver {
|
||||
return this._injector.createInstance(FOverGridImage, drawing);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a custom image downloader for URL images
|
||||
* @param downloader The downloader function that takes a URL and returns a base64 string
|
||||
* @returns A disposable object to unregister the downloader
|
||||
* @example
|
||||
* ```ts
|
||||
* const disposable = univerAPI.registerURLImageDownloader(async (url) => {
|
||||
* const response = await fetch(url);
|
||||
* const blob = await response.blob();
|
||||
* const base64 = await new Promise<string>((resolve) => {
|
||||
* const reader = new FileReader();
|
||||
* reader.onloadend = () => resolve(reader.result as string);
|
||||
* reader.readAsDataURL(blob);
|
||||
* });
|
||||
* return base64;
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
registerURLImageDownloader(downloader: (url: string) => Promise<string>): IDisposable {
|
||||
const batchSaveImagesService = this._injector.get(IBatchSaveImagesService);
|
||||
return batchSaveImagesService.registerURLImageDownloader(downloader);
|
||||
}
|
||||
}
|
||||
|
||||
FUniver.extend(FUniverDrawingMixin);
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { ICellData, IRange, Nullable, Workbook } from '@univerjs/core';
|
||||
import type { ICellData, IDisposable, IRange, Nullable, Workbook } from '@univerjs/core';
|
||||
import type { IImageData } from '@univerjs/drawing';
|
||||
import { createIdentifier, Disposable, IImageIoService, ImageSourceType, Inject, IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
|
||||
import { createIdentifier, Disposable, IImageIoService, ImageSourceType, Inject, IUniverInstanceService, toDisposable, UniverInstanceType } from '@univerjs/core';
|
||||
import { SheetsSelectionsService } from '@univerjs/sheets';
|
||||
|
||||
declare global {
|
||||
@@ -136,10 +136,20 @@ export interface IBatchSaveImagesService {
|
||||
*/
|
||||
getSelectionRowRange(): { startRow: number; endRow: number } | null;
|
||||
|
||||
/**
|
||||
* Get all column indices that are within the current selection
|
||||
*/
|
||||
/**
|
||||
* Get all column indices that are within the current selection
|
||||
*/
|
||||
getSelectionColumnIndices(): Set<number>;
|
||||
|
||||
/**
|
||||
* Register a custom image downloader for URL images
|
||||
* @param downloader The downloader function that takes a URL and returns a base64 string
|
||||
* @returns A disposable object to unregister the downloader
|
||||
*/
|
||||
registerURLImageDownloader(downloader: (url: string) => Promise<string>): IDisposable;
|
||||
}
|
||||
|
||||
export const IBatchSaveImagesService = createIdentifier<IBatchSaveImagesService>('sheets-drawing-ui.batch-save-images.service');
|
||||
@@ -242,6 +252,8 @@ async function imageSourceToBlob(source: string, imageSourceType: ImageSourceTyp
|
||||
}
|
||||
|
||||
export class BatchSaveImagesService extends Disposable implements IBatchSaveImagesService {
|
||||
private _urlImageDownloader: Nullable<(url: string) => Promise<string>> = null;
|
||||
|
||||
constructor(
|
||||
@IUniverInstanceService private readonly _univerInstanceService: IUniverInstanceService,
|
||||
@Inject(SheetsSelectionsService) private readonly _selectionService: SheetsSelectionsService,
|
||||
@@ -250,6 +262,15 @@ export class BatchSaveImagesService extends Disposable implements IBatchSaveImag
|
||||
super();
|
||||
}
|
||||
|
||||
registerURLImageDownloader(downloader: (url: string) => Promise<string>): IDisposable {
|
||||
this._urlImageDownloader = downloader;
|
||||
return toDisposable(() => {
|
||||
if (this._urlImageDownloader === downloader) {
|
||||
this._urlImageDownloader = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getCellImagesInSelection(): ICellImageInfo[] {
|
||||
const workbook = this._univerInstanceService.getCurrentUnitForType<Workbook>(UniverInstanceType.UNIVER_SHEET);
|
||||
if (!workbook) return [];
|
||||
@@ -666,6 +687,17 @@ export class BatchSaveImagesService extends Disposable implements IBatchSaveImag
|
||||
const imageUrl = await this._imageIoService.getImage(imageInfo.source);
|
||||
return imageSourceToBlob(imageUrl, ImageSourceType.URL);
|
||||
}
|
||||
|
||||
if (imageInfo.imageSourceType === ImageSourceType.URL && this._urlImageDownloader) {
|
||||
try {
|
||||
const base64 = await this._urlImageDownloader(imageInfo.source);
|
||||
return imageSourceToBlob(base64, ImageSourceType.BASE64);
|
||||
} catch (error) {
|
||||
console.error(`Custom downloader failed for ${imageInfo.source}, falling back to default fetch:`, error);
|
||||
// Fallback to default fetch if custom downloader fails
|
||||
}
|
||||
}
|
||||
|
||||
return imageSourceToBlob(imageInfo.source, imageInfo.imageSourceType);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user