From fc2a5879bd526e5fd2f76bd499ea4f6c74a913db Mon Sep 17 00:00:00 2001 From: MingLiang Wang Date: Wed, 11 Jan 2023 20:57:56 +0800 Subject: [PATCH] feat: add channel for get new affine list --- .../data-center/src/provider/affine/affine.ts | 71 ++++++++++++++----- .../src/provider/affine/channel.ts | 19 +++-- 2 files changed, 69 insertions(+), 21 deletions(-) diff --git a/packages/data-center/src/provider/affine/affine.ts b/packages/data-center/src/provider/affine/affine.ts index a3142b74ac..c116492099 100644 --- a/packages/data-center/src/provider/affine/affine.ts +++ b/packages/data-center/src/provider/affine/affine.ts @@ -11,12 +11,13 @@ import { storage } from './storage.js'; import assert from 'assert'; import { WebsocketProvider } from './sync.js'; // import { IndexedDBProvider } from '../local/indexeddb'; -import { getApis } from './apis/index.js'; +import { getApis, Workspace } from './apis/index.js'; import type { Apis, WorkspaceDetail, Callback } from './apis'; import { setDefaultAvatar } from '../utils.js'; import { MessageCode } from '../../message'; import { token } from './apis/token.js'; import { WebsocketClient } from './channel'; +import { SyncMode } from '../../workspace-unit'; export interface AffineProviderConstructorParams extends ProviderConstructorParams { @@ -33,21 +34,12 @@ export class AffineProvider extends BaseProvider { private _onTokenRefresh?: Callback = undefined; private _wsMap: Map = new Map(); private _apis: Apis; - private _channel: WebsocketClient; + private _channel?: WebsocketClient; // private _idbMap: Map = new Map(); constructor({ apis, ...params }: AffineProviderConstructorParams) { super(params); this._apis = apis || getApis(); - this._channel = new WebsocketClient( - `${window.location.protocol === 'https:' ? 'wss' : 'ws'}://${ - window.location.host - }/global/sync/`, - this._logger - ); - if (token.isLogin) { - this._connectChannel(); - } } override async init() { @@ -76,14 +68,59 @@ export class AffineProvider extends BaseProvider { } else { storage.setItem('token', this._apis.token.refresh); } + + if (token.isLogin) { + this._connectChannel(); + } } private _connectChannel() { - this._channel.connect(); + if (!this._channel) { + this._channel = new WebsocketClient( + `${window.location.protocol === 'https:' ? 'wss' : 'ws'}://${ + window.location.host + }/api/global/sync/`, + this._logger, + { + params: { + token: this._apis.token.refresh, + }, + } + ); + } + this._channel.on('message', this.handlerAffineListMessage); + } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - this._channel.on('message', (message: any) => { - console.log('message', message); + private handlerAffineListMessage({ + ws_details, + metadata, + }: { + ws_list: Workspace[]; + ws_details: Record; + metadata: Record; + }) { + Object.entries(ws_details).forEach(([id, detail]) => { + const { name, avatar } = metadata[id]; + assert(name); + const workspace = { + name: name, + avatar, + owner: { + name: detail.owner.name, + id: detail.owner.id, + email: detail.owner.email, + avatar: detail.owner.avatar_url, + }, + published: detail.public, + memberCount: detail.member_count, + provider: 'affine', + syncMode: 'core' as SyncMode, + }; + if (this._workspaces.get(id)) { + this._workspaces.update(id, workspace); + } else { + this._workspaces.add({ id, ...workspace }); + } }); } @@ -237,7 +274,7 @@ export class AffineProvider extends BaseProvider { } } const user = await this._apis.signInWithGoogle?.(); - if (!this._channel.connected) { + if (!this._channel?.connected) { this._connectChannel(); } if (!user) { @@ -397,7 +434,7 @@ export class AffineProvider extends BaseProvider { public override async logout(): Promise { token.clear(); - this._channel.disconnect(); + this._channel?.disconnect(); this._wsMap.forEach(ws => ws.disconnect()); storage.removeItem('token'); } diff --git a/packages/data-center/src/provider/affine/channel.ts b/packages/data-center/src/provider/affine/channel.ts index 8d4ae85b09..1503a8b450 100644 --- a/packages/data-center/src/provider/affine/channel.ts +++ b/packages/data-center/src/provider/affine/channel.ts @@ -1,6 +1,7 @@ -import websocket from 'lib0/websocket'; +import * as websocket from 'lib0/websocket'; import { Logger } from 'src/types'; import { token } from './apis/token'; +import * as url from 'lib0/url'; const RECONNECT_INTERVAL_TIME = 5000; const MAX_RECONNECT_TIMES = 50; @@ -10,11 +11,21 @@ export class WebsocketClient extends websocket.WebsocketClient { private _reconnectInterval: number | null = null; private _logger: Logger; constructor( - url: string, + serverUrl: string, logger: Logger, - options?: { binaryType: 'arraybuffer' | 'blob' | null } + options?: ConstructorParameters[1] & { + params: Record; + } ) { - super(url, options); + const params = options?.params || {}; + // ensure that url is always ends with / + while (serverUrl[serverUrl.length - 1] === '/') { + serverUrl = serverUrl.slice(0, serverUrl.length - 1); + } + const encodedParams = url.encodeQueryParams(params); + const newUrl = + serverUrl + '/' + (encodedParams.length === 0 ? '' : '?' + encodedParams); + super(newUrl, options); this._logger = logger; this._setupChannel(); }