From 375b5197da6867c3ef22daf9167aa02b92cc7e71 Mon Sep 17 00:00:00 2001 From: MingLiang Wang Date: Sun, 8 Jan 2023 18:42:35 +0800 Subject: [PATCH] feat: add default head img --- packages/data-center/src/datacenter.ts | 6 +++ .../data-center/src/provider/affine/affine.ts | 12 +++++- packages/data-center/src/provider/base.ts | 19 +++++++++- .../data-center/src/provider/local/local.ts | 27 ++++++++++++- packages/data-center/src/utils/index.ts | 38 +++++++++++++++++++ 5 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 packages/data-center/src/utils/index.ts diff --git a/packages/data-center/src/datacenter.ts b/packages/data-center/src/datacenter.ts index d88762b436..bec4794df4 100644 --- a/packages/data-center/src/datacenter.ts +++ b/packages/data-center/src/datacenter.ts @@ -173,6 +173,12 @@ export class DataCenter { w.doc.meta.setAvatar(avatar); update.avatar = avatar; } + // may run for change workspace meta + const workspaceInfo = this.workspaces.getWorkspace(w.room); + assert(workspaceInfo, 'Workspace not found'); + const provider = this.providerMap.get(workspaceInfo.provider); + provider?.updateWorkspaceMeta(w.room, update); + // update workspace list directly this.workspaces.updateWorkspaceInfo(w.room, update); } diff --git a/packages/data-center/src/provider/affine/affine.ts b/packages/data-center/src/provider/affine/affine.ts index c2bea657db..ae986cdb7c 100644 --- a/packages/data-center/src/provider/affine/affine.ts +++ b/packages/data-center/src/provider/affine/affine.ts @@ -21,6 +21,7 @@ import assert from 'assert'; import { getAuthorizer } from './apis/token'; import { WebsocketProvider } from './sync'; import { IndexedDBProvider } from '../indexeddb'; +import { getDefaultHeadImgBlob } from 'src/utils'; export class AffineProvider extends BaseProvider { public id = 'affine'; @@ -229,6 +230,7 @@ export class AffineProvider extends BaseProvider { idb = new IndexedDBProvider(workspace.room, workspace.doc); this._idbMap.set(workspace.room, idb); await idb.whenSynced; + this._logger('Local data loaded'); return idb; } @@ -236,13 +238,19 @@ export class AffineProvider extends BaseProvider { meta: WorkspaceMeta ): Promise { assert(meta.name, 'Workspace name is required'); - meta.avatar ?? (meta.avatar = ''); + if (!meta.avatar) { + // set default avatar + const blob = await getDefaultHeadImgBlob(meta.name); + meta.avatar = (await this.setBlob(blob)) || ''; + } const { id } = await createWorkspace(meta as Required); + this._logger('Creating affine workspace'); const nw = new Workspace({ room: id, }).register(BlockSchema); + nw.meta.setName(meta.name); + nw.meta.setAvatar(meta.avatar); this._initWorkspaceDb(nw); - this._logger('Local data loaded'); return nw; } diff --git a/packages/data-center/src/provider/base.ts b/packages/data-center/src/provider/base.ts index 904b04d067..77cd9fdd3f 100644 --- a/packages/data-center/src/provider/base.ts +++ b/packages/data-center/src/provider/base.ts @@ -65,11 +65,11 @@ export class BaseProvider { } async getBlob(id: string): Promise { - return this._blobs.get(id); + return await this._blobs.get(id); } async setBlob(blob: Blob): Promise { - return this._blobs.set(blob); + return await this._blobs.set(blob); } /** @@ -131,6 +131,21 @@ export class BaseProvider { return; } + /** + * change workspace meta by workspace id , work for cached list in different provider + * @param id + * @param meta + * @returns + */ + public async updateWorkspaceMeta( + id: string, + meta: Partial + ): Promise { + id; + meta; + return; + } + public async createWorkspace( meta: WorkspaceMeta ): Promise { diff --git a/packages/data-center/src/provider/local/local.ts b/packages/data-center/src/provider/local/local.ts index 20ed420ba1..1acc6db7dd 100644 --- a/packages/data-center/src/provider/local/local.ts +++ b/packages/data-center/src/provider/local/local.ts @@ -4,6 +4,7 @@ import { Workspace as WS, WorkspaceMeta } from 'src/types'; import { Workspace } from '@blocksuite/store'; import { IndexedDBProvider } from '../indexeddb'; import assert from 'assert'; +import { getDefaultHeadImgBlob } from 'src/utils'; const WORKSPACE_KEY = 'workspaces'; @@ -27,6 +28,7 @@ export class LocalProvider extends BaseProvider { idb?.destroy(); idb = new IndexedDBProvider(workspace.room, workspace.doc); this._idbMap.set(workspace.room, idb); + this._logger('Local data loaded'); return idb; } @@ -62,14 +64,35 @@ export class LocalProvider extends BaseProvider { } } + public override async updateWorkspaceMeta( + id: string, + meta: Partial + ) { + const index = this._workspacesList.findIndex(ws => ws.id === id); + if (index !== -1) { + const workspace = this._workspacesList[index]; + meta.name && (workspace.name = meta.name); + meta.avatar && (workspace.avatar = meta.avatar); + this._storeWorkspaces(this._workspacesList); + } else { + this._logger(`Failed to update workspace ${id}`); + } + } + public override async createWorkspace( meta: WorkspaceMeta ): Promise { assert(meta.name, 'Workspace name is required'); - meta.avatar ?? (meta.avatar = ''); + if (!meta.avatar) { + // set default avatar + const blob = await getDefaultHeadImgBlob(meta.name); + meta.avatar = (await this.setBlob(blob)) || ''; + } const workspaceInfos = this._workspaces.addLocalWorkspace(meta.name); + this._logger('Creating affine workspace'); const workspace = new Workspace({ room: workspaceInfos.id }); - // TODO: add avatar + workspace.meta.setName(meta.name); + workspace.meta.setAvatar(meta.avatar); this._storeWorkspaces([...this._workspacesList, workspaceInfos]); this._initWorkspaceDb(workspace); return workspace; diff --git a/packages/data-center/src/utils/index.ts b/packages/data-center/src/utils/index.ts new file mode 100644 index 0000000000..d1040b0246 --- /dev/null +++ b/packages/data-center/src/utils/index.ts @@ -0,0 +1,38 @@ +const DefaultHeadImgColors = [ + ['#C6F2F3', '#0C6066'], + ['#FFF5AB', '#896406'], + ['#FFCCA7', '#8F4500'], + ['#FFCECE', '#AF1212'], + ['#E3DEFF', '#511AAB'], +]; + +export async function getDefaultHeadImgBlob( + workspaceName: string +): Promise { + const canvas = document.createElement('canvas'); + canvas.height = 100; + canvas.width = 100; + const ctx = canvas.getContext('2d'); + return new Promise((resolve, reject) => { + if (ctx) { + const randomNumber = Math.floor(Math.random() * 5); + const randomColor = DefaultHeadImgColors[randomNumber]; + ctx.fillStyle = randomColor[0]; + ctx.fillRect(0, 0, 100, 100); + ctx.font = "600 50px 'PingFang SC', 'Microsoft Yahei'"; + ctx.fillStyle = randomColor[1]; + ctx.textAlign = 'center'; + ctx.textBaseline = 'middle'; + ctx.fillText(workspaceName[0], 50, 50); + canvas.toBlob(blob => { + if (blob) { + resolve(blob); + } else { + reject(); + } + }, 'image/png'); + } else { + reject(); + } + }); +}