@plaso-infi/whiteboard-sdk 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -1
- package/.eslintrc.cjs +0 -39
- package/postcss.config.cjs +0 -3
- package/rollup.config.mjs +0 -75
- package/src/components/errorBoundary/errorBoundary.tsx +0 -27
- package/src/components/errorBoundary/index.ts +0 -1
- package/src/components/index.ts +0 -1
- package/src/fixtures/index.ts +0 -1
- package/src/fixtures/sdk_status.ts +0 -5
- package/src/index.ts +0 -5
- package/src/instance.ts +0 -105
- package/src/localdemo/demo.tsx +0 -29
- package/src/localdemo/index.html +0 -13
- package/src/localdemo/styles.module.less +0 -5
- package/src/sdk.ts +0 -21
- package/src/types/event.ts +0 -7
- package/src/types/global.d.ts +0 -27
- package/src/types/index.ts +0 -2
- package/src/types/sdk.ts +0 -128
- package/src/upime/index.ts +0 -1
- package/src/upime/upime.tsx +0 -86
- package/src/utils/asyncWork.ts +0 -31
- package/src/utils/avatar.ts +0 -71
- package/src/utils/common.ts +0 -30
- package/src/utils/event.ts +0 -46
- package/src/utils/index.ts +0 -4
- package/tsconfig.json +0 -24
- package/vite.config.ts +0 -40
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plaso-infi/whiteboard-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -64,6 +64,10 @@
|
|
|
64
64
|
"peerDependencies": {
|
|
65
65
|
"ali-oss": "^6.17.1"
|
|
66
66
|
},
|
|
67
|
+
"files": [
|
|
68
|
+
"dist",
|
|
69
|
+
"!dist/**/*.js.map"
|
|
70
|
+
],
|
|
67
71
|
"browserslist": {
|
|
68
72
|
"development": [
|
|
69
73
|
"last 3 chrome version",
|
package/.eslintrc.cjs
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
env: {
|
|
3
|
-
browser: true,
|
|
4
|
-
es2021: true,
|
|
5
|
-
node: true,
|
|
6
|
-
},
|
|
7
|
-
settings: {
|
|
8
|
-
react: {
|
|
9
|
-
pragma: 'React',
|
|
10
|
-
version: 'detect',
|
|
11
|
-
},
|
|
12
|
-
},
|
|
13
|
-
extends: [
|
|
14
|
-
'plugin:@typescript-eslint/recommended',
|
|
15
|
-
'plugin:react/recommended',
|
|
16
|
-
'plugin:prettier/recommended',
|
|
17
|
-
],
|
|
18
|
-
parser: '@typescript-eslint/parser',
|
|
19
|
-
parserOptions: {
|
|
20
|
-
ecmaFeatures: {
|
|
21
|
-
jsx: true,
|
|
22
|
-
},
|
|
23
|
-
ecmaVersion: 13,
|
|
24
|
-
sourceType: 'module',
|
|
25
|
-
},
|
|
26
|
-
plugins: ['react', 'react-hooks', '@typescript-eslint'],
|
|
27
|
-
rules: {
|
|
28
|
-
'@typescript-eslint/no-explicit-any': 0,
|
|
29
|
-
'react-hooks/rules-of-hooks': 'warn',
|
|
30
|
-
'@typescript-eslint/consistent-type-imports': 'error',
|
|
31
|
-
'@typescript-eslint/no-unused-vars': [
|
|
32
|
-
'warn',
|
|
33
|
-
{
|
|
34
|
-
varsIgnorePattern: '^_$',
|
|
35
|
-
},
|
|
36
|
-
],
|
|
37
|
-
},
|
|
38
|
-
ignore: ['dist/'],
|
|
39
|
-
};
|
package/postcss.config.cjs
DELETED
package/rollup.config.mjs
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import commonjs from '@rollup/plugin-commonjs';
|
|
2
|
-
import resolve from '@rollup/plugin-node-resolve';
|
|
3
|
-
import jsonPlugin from '@rollup/plugin-json';
|
|
4
|
-
import clean from 'rollup-plugin-clean';
|
|
5
|
-
import postcss from 'rollup-plugin-postcss';
|
|
6
|
-
import { terser } from 'rollup-plugin-terser';
|
|
7
|
-
import dts from 'rollup-plugin-dts';
|
|
8
|
-
import typescript from 'rollup-plugin-typescript2';
|
|
9
|
-
|
|
10
|
-
const webSdkSetting = {
|
|
11
|
-
input: 'src/index.ts',
|
|
12
|
-
output: [
|
|
13
|
-
{
|
|
14
|
-
dir: 'dist/cjs/',
|
|
15
|
-
format: 'cjs',
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
dir: 'dist/esm/',
|
|
19
|
-
format: 'es',
|
|
20
|
-
},
|
|
21
|
-
],
|
|
22
|
-
plugins: [
|
|
23
|
-
clean(),
|
|
24
|
-
jsonPlugin(),
|
|
25
|
-
commonjs({
|
|
26
|
-
preferBuiltins: false,
|
|
27
|
-
}),
|
|
28
|
-
resolve(),
|
|
29
|
-
typescript({ tsconfig: './tsconfig.json', clean: true }),
|
|
30
|
-
postcss({
|
|
31
|
-
extract: true,
|
|
32
|
-
// postcss plugin has a bug, if modules is object autoModules must set false;
|
|
33
|
-
autoModules: false,
|
|
34
|
-
modules: {
|
|
35
|
-
// generateScopedName: '[local]_[hash:base64:5]',
|
|
36
|
-
generateScopedName: function (name, filename, css) {
|
|
37
|
-
if (filename.includes('upime-sdk')) {
|
|
38
|
-
return name;
|
|
39
|
-
}
|
|
40
|
-
const path = require('path');
|
|
41
|
-
const i = css.indexOf('.' + name);
|
|
42
|
-
const line = css.substr(0, i).split(/[\r\n]/).length;
|
|
43
|
-
const file = path.basename(filename, '.css');
|
|
44
|
-
return '_' + file + '_' + line + '_' + name;
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
}),
|
|
48
|
-
terser({
|
|
49
|
-
compress: {
|
|
50
|
-
pure_funcs: ['console.log', 'console.info'],
|
|
51
|
-
},
|
|
52
|
-
}),
|
|
53
|
-
],
|
|
54
|
-
external: ['ali-oss'],
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
const TypeSetting = {
|
|
58
|
-
input: 'src/index.ts',
|
|
59
|
-
output: [
|
|
60
|
-
{
|
|
61
|
-
file: 'dist/esm/index.d.ts',
|
|
62
|
-
format: 'es',
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
file: 'dist/cjs/index.d.ts',
|
|
66
|
-
format: 'cjs',
|
|
67
|
-
},
|
|
68
|
-
],
|
|
69
|
-
plugins: [typescript({ tsconfig: './tsconfig.json' }), dts()],
|
|
70
|
-
external: ['agora-rtc-sdk-ng', 'react', 'react-dom', 'ali-oss', 'hls.js'],
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
// export default [webSdkSetting];
|
|
74
|
-
|
|
75
|
-
export default [webSdkSetting, TypeSetting];
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { EventManagerT } from '@/types';
|
|
2
|
-
import type { WebsdkEventTypeMap } from '@/types/sdk';
|
|
3
|
-
import React from 'react';
|
|
4
|
-
|
|
5
|
-
type ErrorBoundaryPropT = {
|
|
6
|
-
evtBus: EventManagerT<WebsdkEventTypeMap>;
|
|
7
|
-
children: React.ReactNode;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
class ErrorBoundary extends React.Component<ErrorBoundaryPropT> {
|
|
11
|
-
state: { hasError: boolean } = { hasError: false };
|
|
12
|
-
|
|
13
|
-
componentDidCatch() {
|
|
14
|
-
// TODO: 错误信息收集上报
|
|
15
|
-
this.setState({ hasError: true });
|
|
16
|
-
this.props.evtBus.publish('internal_error', undefined);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
render() {
|
|
20
|
-
if (this.state.hasError) {
|
|
21
|
-
return <div> WebSDK 内部发送错误,请尝试刷新浏览器再使用,如果仍出现问题,请联系我们 </div>;
|
|
22
|
-
}
|
|
23
|
-
return this.props.children;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export { ErrorBoundary };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './errorBoundary';
|
package/src/components/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './errorBoundary';
|
package/src/fixtures/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './sdk_status';
|
package/src/index.ts
DELETED
package/src/instance.ts
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { EventManager, drawNoImageAvatar } from '@/utils';
|
|
2
|
-
import { WebSdkStatus } from './fixtures/sdk_status';
|
|
3
|
-
import type { GetSdkInstanceConfigs, InternalWebSdkInsT, WebsdkEventTypeMap } from '@/types/sdk';
|
|
4
|
-
import { mountUpimeSdk } from './upime';
|
|
5
|
-
import type { BoardSDKRefType } from '@plasosdk/upime-sdk';
|
|
6
|
-
|
|
7
|
-
/** 装饰器,用以检测 BoardSdkRef 是否存在,通常只有白板初始化成功了才会有这个 ref */
|
|
8
|
-
function checkBoardRef(
|
|
9
|
-
_t: InfiWebsdkInstance,
|
|
10
|
-
_k: string,
|
|
11
|
-
descriptor: PropertyDescriptor,
|
|
12
|
-
): PropertyDescriptor {
|
|
13
|
-
const fn = descriptor.value;
|
|
14
|
-
descriptor.value = function (...args: any[]) {
|
|
15
|
-
const _self = this as InfiWebsdkInstance;
|
|
16
|
-
if (_self.sdkRef) {
|
|
17
|
-
return fn.apply(_self, args);
|
|
18
|
-
} else if (_self.status !== WebSdkStatus.CONNECTED) {
|
|
19
|
-
_self.evtBus.publish('not_initialized', undefined);
|
|
20
|
-
return;
|
|
21
|
-
} else {
|
|
22
|
-
_self.evtBus.publish('not_initialized', undefined);
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
return descriptor;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export class InfiWebsdkInstance implements InternalWebSdkInsT {
|
|
30
|
-
status: WebSdkStatus = WebSdkStatus.NOT_CONNECTED;
|
|
31
|
-
|
|
32
|
-
sdkRef: BoardSDKRefType | null = null;
|
|
33
|
-
|
|
34
|
-
_authPassed = false;
|
|
35
|
-
|
|
36
|
-
get authPassed() {
|
|
37
|
-
return this._authPassed;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
constructor(public configs: GetSdkInstanceConfigs) {
|
|
41
|
-
this.init();
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
evtBus = new EventManager<WebsdkEventTypeMap>();
|
|
45
|
-
|
|
46
|
-
async init() {
|
|
47
|
-
if (await this.authCheck()) {
|
|
48
|
-
// TODO: 如果 queryString 校验失败,则需要根据返回类型提示不同的错误消息
|
|
49
|
-
throw new Error('auth check failed ');
|
|
50
|
-
}
|
|
51
|
-
const { loginName, userName, avatarUrl } = this.configs.userInfo;
|
|
52
|
-
if (!avatarUrl) {
|
|
53
|
-
this.configs.userInfo.avatarUrl = await drawNoImageAvatar({
|
|
54
|
-
userId: loginName,
|
|
55
|
-
text: userName,
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
mountUpimeSdk(this.configs, this.evtBus).then(ref => {
|
|
59
|
-
this.sdkRef = ref;
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
private authCheck() {
|
|
64
|
-
// TODO: 在正式使用白板连入之前,可能需要先检验一把 queryString 是否合法,并反馈响应有意义的错误消息
|
|
65
|
-
return Promise.resolve(0);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
enableEdit(couldEdit: boolean) {
|
|
69
|
-
//
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
@checkBoardRef
|
|
73
|
-
async slideToView(position: { x: number; y: number }, scale: number, time: number) {
|
|
74
|
-
//
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
@checkBoardRef
|
|
78
|
-
getCurrentViewData() {
|
|
79
|
-
return {
|
|
80
|
-
left: 0,
|
|
81
|
-
right: 0,
|
|
82
|
-
top: 0,
|
|
83
|
-
bottom: 0,
|
|
84
|
-
scale: 1,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
@checkBoardRef
|
|
89
|
-
async showToast(message: string, duration: number) {
|
|
90
|
-
//
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
on<T extends keyof WebsdkEventTypeMap>(evtName: T, cb: (param: WebsdkEventTypeMap[T]) => void) {
|
|
94
|
-
this.evtBus.subscribe(evtName, cb);
|
|
95
|
-
return () => this.off(evtName, cb);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
off<T extends keyof WebsdkEventTypeMap>(evtName: T, cb: (param: WebsdkEventTypeMap[T]) => void) {
|
|
99
|
-
this.evtBus.unsubscribe(evtName, cb);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
async destroy() {
|
|
103
|
-
//
|
|
104
|
-
}
|
|
105
|
-
}
|
package/src/localdemo/demo.tsx
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { setEnv, env_type } from '@plasosdk/upime-sdk';
|
|
2
|
-
import { getInfiWebsdkQuery, type WebsdkQueryParams } from '@plasosdk/whiteboard-ext-tools';
|
|
3
|
-
|
|
4
|
-
const devQuerySample: WebsdkQueryParams = {
|
|
5
|
-
recordId: 'dev_sample',
|
|
6
|
-
appId: '1866',
|
|
7
|
-
appKey: 'dt47593e1111111b5a185216400f3126',
|
|
8
|
-
loginName: 'user_0',
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
setEnv(env_type.DEV);
|
|
12
|
-
|
|
13
|
-
const getQuery = async () => Promise.resolve(getInfiWebsdkQuery(devQuerySample));
|
|
14
|
-
|
|
15
|
-
const container = document.getElementById('app') as HTMLDivElement;
|
|
16
|
-
|
|
17
|
-
const setup = async () => {
|
|
18
|
-
const ins = await window.InfiWebsdk.getSdkInstance({
|
|
19
|
-
getQueryString: getQuery,
|
|
20
|
-
userInfo: {
|
|
21
|
-
loginName: 'user_0',
|
|
22
|
-
userName: 'User 0',
|
|
23
|
-
},
|
|
24
|
-
containerDom: container,
|
|
25
|
-
getUsersInfo: async () => [],
|
|
26
|
-
});
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
// setup();
|
package/src/localdemo/index.html
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Infi websdk</title>
|
|
7
|
-
|
|
8
|
-
<script type="module" src="./demo.tsx"></script>
|
|
9
|
-
</head>
|
|
10
|
-
<body>
|
|
11
|
-
<div id="app"></div>
|
|
12
|
-
</body>
|
|
13
|
-
</html>
|
package/src/sdk.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { InfiWebSdkType } from '@/types/sdk';
|
|
2
|
-
import pkg from '../package.json';
|
|
3
|
-
import { InfiWebsdkInstance } from './instance';
|
|
4
|
-
|
|
5
|
-
export const InfiWebsdk: InfiWebSdkType = {
|
|
6
|
-
getSdkInstance: async (...params) => {
|
|
7
|
-
try {
|
|
8
|
-
const ins = new InfiWebsdkInstance(...params);
|
|
9
|
-
return {
|
|
10
|
-
code: 0,
|
|
11
|
-
payload: ins,
|
|
12
|
-
};
|
|
13
|
-
} catch {
|
|
14
|
-
return {
|
|
15
|
-
code: 1,
|
|
16
|
-
payload: '初始化错误',
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
version: pkg.version,
|
|
21
|
-
};
|
package/src/types/event.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export type eventHandler<E> = (evt: E) => void;
|
|
2
|
-
|
|
3
|
-
export interface EventManagerT<ET = any> {
|
|
4
|
-
subscribe<T extends keyof ET>(topic: T, cb: eventHandler<ET[T]>): CB;
|
|
5
|
-
once<T extends keyof ET>(topic: T, cb: eventHandler<ET[T]>): CB;
|
|
6
|
-
publish<T extends keyof ET>(topic: T, evt: ET[T]): void;
|
|
7
|
-
}
|
package/src/types/global.d.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
declare module '*.css';
|
|
2
|
-
declare module '*.scss';
|
|
3
|
-
declare module '*.sass';
|
|
4
|
-
declare module '*.svg';
|
|
5
|
-
declare module '*.png';
|
|
6
|
-
declare module '*.jpg';
|
|
7
|
-
declare module '*.jpeg';
|
|
8
|
-
declare module '*.gif';
|
|
9
|
-
|
|
10
|
-
declare module '*.less' {
|
|
11
|
-
const resource: { [key: string]: string };
|
|
12
|
-
export = resource;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
type CB = (...p: any[]) => unknown;
|
|
16
|
-
|
|
17
|
-
interface Window {
|
|
18
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
19
|
-
InfiWebsdk: import('./sdk').InfiWebSdkType;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
declare namespace NodeJS {
|
|
23
|
-
interface Process {
|
|
24
|
-
/** 为解决 node_modules/ali-oss/lib/common/utils/isDingTalk.ts 内错误的类型声明加的 */
|
|
25
|
-
browser: boolean;
|
|
26
|
-
}
|
|
27
|
-
}
|
package/src/types/index.ts
DELETED
package/src/types/sdk.ts
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
type PositionLike = {
|
|
2
|
-
x: number;
|
|
3
|
-
y: number;
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
type Viewbox = {
|
|
7
|
-
left: number;
|
|
8
|
-
top: number;
|
|
9
|
-
right: number;
|
|
10
|
-
bottom: number;
|
|
11
|
-
scale: number;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
/** websdk 实例类型声明接口 */
|
|
15
|
-
export interface InfiWebsdkInstanceType {
|
|
16
|
-
/**
|
|
17
|
-
* 设置是否可以编辑
|
|
18
|
-
* @param couldEdit true: 可编辑; false: 只读
|
|
19
|
-
*/
|
|
20
|
-
enableEdit: (couldEdit: boolean) => void;
|
|
21
|
-
/**
|
|
22
|
-
* 变更白板的画布视野
|
|
23
|
-
* @param position 白板绘制区域左上角的坐标值
|
|
24
|
-
* @param scale 白板当前的画布显示缩放值
|
|
25
|
-
* @param time 显示变更所需时间,如果填入有效值,则画面会平滑过渡到目标视野, 如果填 0 ,则会立即完成视野变更
|
|
26
|
-
* @returns Promise fulfill 表示移动视野动作执行完成
|
|
27
|
-
*/
|
|
28
|
-
slideToView: (position: PositionLike, scale: number, time: number) => Promise<void>;
|
|
29
|
-
/** 获取当前白板的画布视野信息 */
|
|
30
|
-
getCurrentViewData: () => Viewbox;
|
|
31
|
-
/**
|
|
32
|
-
* 于白板内显示 toast 消息
|
|
33
|
-
* @param message 消息
|
|
34
|
-
* @param duration 显示时长,经过该时长后 toast 消息消失
|
|
35
|
-
* @return Promise fulfill 表示消息已经消失
|
|
36
|
-
*/
|
|
37
|
-
showToast: (message: string, duration: number) => Promise<void>;
|
|
38
|
-
/**
|
|
39
|
-
* 注册白板事件监听器
|
|
40
|
-
* TBD: 初期先暴露一些基本事件,比如白板已初始化完毕、白板已销毁完毕等事件
|
|
41
|
-
* @param evtName 事件名
|
|
42
|
-
* @param cb 回调函数
|
|
43
|
-
* @returns 取消注册执行函数
|
|
44
|
-
*/
|
|
45
|
-
on: <T extends keyof WebsdkEventTypeMap>(
|
|
46
|
-
evtName: T,
|
|
47
|
-
cb: (param: WebsdkEventTypeMap[T]) => void,
|
|
48
|
-
) => () => void;
|
|
49
|
-
/**
|
|
50
|
-
* 取消注册白板事件监听器
|
|
51
|
-
* @param evtName 事件名
|
|
52
|
-
* @param cb 回调函数
|
|
53
|
-
*/
|
|
54
|
-
off: <T extends keyof WebsdkEventTypeMap>(
|
|
55
|
-
evtName: T,
|
|
56
|
-
cb: (param: WebsdkEventTypeMap[T]) => void,
|
|
57
|
-
) => void;
|
|
58
|
-
/** 销毁白板 sdk 实例 */
|
|
59
|
-
destroy: () => void;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export interface InternalWebSdkInsT extends InfiWebsdkInstanceType {
|
|
63
|
-
init: () => Promise<void>;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export type WebsdkEventTypeMap = {
|
|
67
|
-
/** 白板未完成初始化 */
|
|
68
|
-
not_initialized: void;
|
|
69
|
-
/** 已连接至白板服务器 */
|
|
70
|
-
connected: void;
|
|
71
|
-
/** 白板服务器连接中 */
|
|
72
|
-
connecting: void;
|
|
73
|
-
/** 白板服务器连接失败 */
|
|
74
|
-
connect_failed: void;
|
|
75
|
-
/** 白板内部错误 */
|
|
76
|
-
internal_error: void;
|
|
77
|
-
/** 因当前白板未处于连接状态,api 调用无效 */
|
|
78
|
-
api_call_rejected: void;
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
/** 当前白板的用户信息 */
|
|
82
|
-
export interface UserInfoT {
|
|
83
|
-
loginName: string;
|
|
84
|
-
userName: string;
|
|
85
|
-
avatarUrl?: string;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/** 获取白板 websdk 实例的配置参数 */
|
|
89
|
-
export interface GetSdkInstanceConfigs {
|
|
90
|
-
/** 白板初始化 & 链接服务器使用的加密字符串, 内涵应用、白板、用户等信息, */
|
|
91
|
-
getQueryString: () => Promise<string>;
|
|
92
|
-
/** 当前白板的用户信息 */
|
|
93
|
-
userInfo: UserInfoT;
|
|
94
|
-
/** 用以挂载白板 DOM 的 HTML DOM 元素, 白板相关元素会自动 appendChild 至这个元素之内 */
|
|
95
|
-
containerDom: HTMLDivElement;
|
|
96
|
-
/** 初始状态下是否默认可编辑, 可基于 InfiWebsdkInstanceType.enableEdit API 进行后续控制 */
|
|
97
|
-
initEditable?: boolean;
|
|
98
|
-
/** 基于 loginName 获取该用户的用户名与头像 url 的方法,由用户提供,方法返回的用户信息用以于白板内作展示 */
|
|
99
|
-
getUsersInfo: (loginNames: string[]) => Promise<UserInfoT[]>;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* 获取白板sdk对象方法的返回值类型,值为对象形式
|
|
104
|
-
* * 对象内 code 值如果为 0, 则表示白板初始化参数验证完毕, payload 为 websdk 的对象实例
|
|
105
|
-
* * 对象内 code 如果不为 0, 则表示白板初始化失败,payload 为错误提示消息
|
|
106
|
-
*/
|
|
107
|
-
type GetSdkInstanceReturnType = Promise<
|
|
108
|
-
| {
|
|
109
|
-
code: 0;
|
|
110
|
-
payload: InfiWebsdkInstanceType;
|
|
111
|
-
}
|
|
112
|
-
| {
|
|
113
|
-
code: 1;
|
|
114
|
-
payload: string;
|
|
115
|
-
}
|
|
116
|
-
>;
|
|
117
|
-
|
|
118
|
-
/** Infi 白板 websdk 全局对象,引入 min.js 后即会挂载至 window 对象上 */
|
|
119
|
-
export interface InfiWebSdkType {
|
|
120
|
-
/**
|
|
121
|
-
* 获取白板sdk对象
|
|
122
|
-
* @param getQueryString 白板初始化 & 链接服务器使用的加密字符串, 内涵应用、白板、用户等信息,
|
|
123
|
-
* 推荐于服务端进行生成,当链接重连但是被白板服务器拒绝后,会自动使用 getQueryString 方法生成新的 queryString 并发起重连
|
|
124
|
-
* @param configs 白板初始化所需要的配置参数
|
|
125
|
-
*/
|
|
126
|
-
getSdkInstance: (configs: GetSdkInstanceConfigs) => GetSdkInstanceReturnType;
|
|
127
|
-
readonly version: string;
|
|
128
|
-
}
|
package/src/upime/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './upime';
|
package/src/upime/upime.tsx
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import type { FC } from 'react';
|
|
2
|
-
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
-
import ReactDOM from 'react-dom';
|
|
4
|
-
import type { BoardSDKRefType } from '@plasosdk/upime-sdk';
|
|
5
|
-
import { BoardSDK, setEnv, env_type } from '@plasosdk/upime-sdk';
|
|
6
|
-
import type { EventManagerT } from '@/types';
|
|
7
|
-
import type { IAsyncWork } from '@/utils/asyncWork';
|
|
8
|
-
import { AsyncWork } from '@/utils/asyncWork';
|
|
9
|
-
import { ErrorBoundary } from '../components';
|
|
10
|
-
import type { GetSdkInstanceConfigs, WebsdkEventTypeMap } from '@/types/sdk';
|
|
11
|
-
import { drawNoImageAvatar } from '@/utils';
|
|
12
|
-
import '@plasosdk/upime-sdk/dist/cjs/index.css';
|
|
13
|
-
|
|
14
|
-
setEnv(env_type.DEV);
|
|
15
|
-
|
|
16
|
-
type BoardPropT = {
|
|
17
|
-
configs: GetSdkInstanceConfigs;
|
|
18
|
-
asyncW: IAsyncWork<BoardSDKRefType>;
|
|
19
|
-
evtBus: EventManagerT<WebsdkEventTypeMap>;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const Board: FC<BoardPropT> = ({ asyncW, configs, evtBus }) => {
|
|
23
|
-
const boardRef = useRef<BoardSDKRefType>(null);
|
|
24
|
-
const [couldEdit, setCouldEdit] = useState(true);
|
|
25
|
-
const { initEditable = true, getUsersInfo } = configs;
|
|
26
|
-
const { getQueryString, userInfo } = configs;
|
|
27
|
-
|
|
28
|
-
useEffect(() => {
|
|
29
|
-
if (boardRef.current) {
|
|
30
|
-
asyncW.done(boardRef.current);
|
|
31
|
-
} else {
|
|
32
|
-
asyncW.fail('sdk init Failed');
|
|
33
|
-
}
|
|
34
|
-
}, []);
|
|
35
|
-
|
|
36
|
-
const getUserInfo = async (loginName: string | string[]) => {
|
|
37
|
-
const loginNames = Array.isArray(loginName) ? loginName : [loginName];
|
|
38
|
-
const users = await getUsersInfo(loginNames);
|
|
39
|
-
const res: Record<string, { userName: string; avatarUrl: string }> = {};
|
|
40
|
-
for (const u of users) {
|
|
41
|
-
const avatarUrl = await drawNoImageAvatar({
|
|
42
|
-
userId: u.loginName,
|
|
43
|
-
text: u.userName,
|
|
44
|
-
imgUrl: u.avatarUrl,
|
|
45
|
-
});
|
|
46
|
-
res[u.loginName] = {
|
|
47
|
-
userName: u.userName,
|
|
48
|
-
avatarUrl,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
return res;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
return (
|
|
55
|
-
<ErrorBoundary evtBus={evtBus}>
|
|
56
|
-
<BoardSDK
|
|
57
|
-
learningCenter={null}
|
|
58
|
-
customizedUploader={null as any}
|
|
59
|
-
loginName={userInfo.loginName}
|
|
60
|
-
userName={userInfo.userName}
|
|
61
|
-
avatarUrl={userInfo.avatarUrl}
|
|
62
|
-
userType={couldEdit ? 'editor' : 'visitor'}
|
|
63
|
-
role={1}
|
|
64
|
-
autoResize={true}
|
|
65
|
-
getBoardQuery={getQueryString}
|
|
66
|
-
getUserInfo={getUserInfo}
|
|
67
|
-
ref={boardRef}
|
|
68
|
-
></BoardSDK>
|
|
69
|
-
</ErrorBoundary>
|
|
70
|
-
);
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
export const mountUpimeSdk = async (
|
|
74
|
-
configs: GetSdkInstanceConfigs,
|
|
75
|
-
evtBus: EventManagerT<WebsdkEventTypeMap>,
|
|
76
|
-
) => {
|
|
77
|
-
const asyncW = new AsyncWork<BoardSDKRefType>();
|
|
78
|
-
|
|
79
|
-
// eslint-disable-next-line react/no-deprecated
|
|
80
|
-
ReactDOM.render(
|
|
81
|
-
<Board evtBus={evtBus} asyncW={asyncW} configs={configs} />,
|
|
82
|
-
configs.containerDom,
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
return asyncW.result;
|
|
86
|
-
};
|
package/src/utils/asyncWork.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
export interface IAsyncWork<T> {
|
|
2
|
-
readonly result: Promise<T>;
|
|
3
|
-
done(result: T): void;
|
|
4
|
-
fail(error: any): void;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export class AsyncWork<T> implements IAsyncWork<T> {
|
|
8
|
-
private _res: ((result: T | PromiseLike<T>) => void) | undefined;
|
|
9
|
-
private _rej: ((reason: any) => void) | undefined;
|
|
10
|
-
private _promise = new Promise<T>((res, rej) => {
|
|
11
|
-
this._res = res;
|
|
12
|
-
this._rej = rej;
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
get result() {
|
|
16
|
-
return this._promise;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
done(result: T) {
|
|
20
|
-
if (this._res) {
|
|
21
|
-
this._res(result);
|
|
22
|
-
this._res = this._rej = undefined;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
fail(error: any) {
|
|
26
|
-
if (this._rej) {
|
|
27
|
-
this._rej(error);
|
|
28
|
-
this._res = this._rej = undefined;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
package/src/utils/avatar.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
export type drawNoImageAvatarParamsT = {
|
|
2
|
-
userId?: string | number;
|
|
3
|
-
text: string;
|
|
4
|
-
imgUrl?: string;
|
|
5
|
-
bgColor?: string;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
const DEFAULT_COVER_COLOR = ['#eea5a5', '#f5cd83', '#9abaee', '#74c5e6', '#54d1c0'];
|
|
9
|
-
export function GetDefaultColor(relyString: string | number) {
|
|
10
|
-
let number;
|
|
11
|
-
if (typeof relyString === 'string') {
|
|
12
|
-
number = relyString.match(/(\d|[a-f]|[A-F])/g)?.join('') || '0';
|
|
13
|
-
} else {
|
|
14
|
-
number = relyString;
|
|
15
|
-
}
|
|
16
|
-
if (number) {
|
|
17
|
-
return DEFAULT_COVER_COLOR[parseInt(number, 16) % DEFAULT_COVER_COLOR.length];
|
|
18
|
-
} else {
|
|
19
|
-
return '#ccc';
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const avatarSize = {
|
|
24
|
-
w: 128,
|
|
25
|
-
h: 128,
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
function drawText(text: string, bgColor: string): string {
|
|
29
|
-
const canvasDOM = document.createElement('canvas');
|
|
30
|
-
canvasDOM.width = avatarSize.w;
|
|
31
|
-
canvasDOM.height = avatarSize.h;
|
|
32
|
-
const ctx = canvasDOM.getContext('2d') as CanvasRenderingContext2D;
|
|
33
|
-
ctx.fillStyle = bgColor;
|
|
34
|
-
ctx.fillRect(0, 0, avatarSize.w, avatarSize.h);
|
|
35
|
-
ctx.font = '64px Arial';
|
|
36
|
-
ctx.textAlign = 'center';
|
|
37
|
-
ctx.fillStyle = '#fff';
|
|
38
|
-
ctx.fillText(text[0], 64, 88);
|
|
39
|
-
return canvasDOM.toDataURL();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* 绘制头像
|
|
44
|
-
* @param param0
|
|
45
|
-
* @returns
|
|
46
|
-
*/
|
|
47
|
-
export function drawNoImageAvatar({
|
|
48
|
-
userId = '',
|
|
49
|
-
text = '',
|
|
50
|
-
imgUrl = '',
|
|
51
|
-
bgColor = '',
|
|
52
|
-
}: drawNoImageAvatarParamsT) {
|
|
53
|
-
return new Promise<string>(resolve => {
|
|
54
|
-
const getDefaultAvatar = () => {
|
|
55
|
-
const curBgColor = bgColor || GetDefaultColor(userId);
|
|
56
|
-
resolve(drawText(text, curBgColor));
|
|
57
|
-
};
|
|
58
|
-
if (!imgUrl) {
|
|
59
|
-
getDefaultAvatar();
|
|
60
|
-
} else {
|
|
61
|
-
const imgDOM = document.createElement('img');
|
|
62
|
-
imgDOM.onload = () => {
|
|
63
|
-
resolve(imgUrl);
|
|
64
|
-
};
|
|
65
|
-
imgDOM.onerror = () => {
|
|
66
|
-
getDefaultAvatar();
|
|
67
|
-
};
|
|
68
|
-
imgDOM.src = imgUrl;
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
}
|
package/src/utils/common.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
export const delay = (t: number) => new Promise(res => setTimeout(res, t));
|
|
2
|
-
|
|
3
|
-
/** 最基本的 debounce 实现 */
|
|
4
|
-
export function debounce<T extends (...args: any[]) => any>(fn: T, time: number) {
|
|
5
|
-
let timer: ReturnType<typeof setTimeout> | null = null;
|
|
6
|
-
return (...args: Parameters<T>): ReturnType<T> => {
|
|
7
|
-
let res: any;
|
|
8
|
-
if (timer) {
|
|
9
|
-
clearTimeout(timer);
|
|
10
|
-
}
|
|
11
|
-
timer = setTimeout(() => {
|
|
12
|
-
res = fn(...args);
|
|
13
|
-
}, time);
|
|
14
|
-
return res;
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/** 最基本的 throttle 实现 */
|
|
19
|
-
export function throttle<T extends (...args: any[]) => any>(fn: T, time: number) {
|
|
20
|
-
let lastTime = 0;
|
|
21
|
-
return (...args: Parameters<T>): ReturnType<T> => {
|
|
22
|
-
const now = Date.now();
|
|
23
|
-
let res: any;
|
|
24
|
-
if (now - lastTime >= time) {
|
|
25
|
-
res = fn(...args);
|
|
26
|
-
lastTime = Date.now();
|
|
27
|
-
}
|
|
28
|
-
return res;
|
|
29
|
-
};
|
|
30
|
-
}
|
package/src/utils/event.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import type { EventManagerT, eventHandler } from '@/types';
|
|
2
|
-
|
|
3
|
-
type Listener<E = any> = {
|
|
4
|
-
cb: eventHandler<E>;
|
|
5
|
-
once: boolean;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export class EventManager<ET = any> implements EventManagerT<ET> {
|
|
9
|
-
private _t: { [p in keyof ET]?: Array<Listener<ET[p]>> } = {};
|
|
10
|
-
|
|
11
|
-
private addListener<T extends keyof ET>(topic: T, cb: eventHandler<ET[T]>, once = false) {
|
|
12
|
-
const topics = this._t;
|
|
13
|
-
let topicList = topics[topic];
|
|
14
|
-
if (!topicList) {
|
|
15
|
-
topics[topic] = topicList = [];
|
|
16
|
-
}
|
|
17
|
-
const one = { cb, once };
|
|
18
|
-
topicList.push(one);
|
|
19
|
-
return function unsub(): void {
|
|
20
|
-
const topicList = topics[topic];
|
|
21
|
-
if (!topicList) return;
|
|
22
|
-
topics[topic] = topicList.filter(o => o !== one);
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
subscribe<T extends keyof ET>(topic: T, cb: eventHandler<ET[T]>) {
|
|
27
|
-
return this.addListener(topic, cb);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
unsubscribe<T extends keyof ET>(topic: T, cb: eventHandler<ET[T]>) {
|
|
31
|
-
const listeners = this._t[topic];
|
|
32
|
-
this._t[topic] = listeners?.filter(l => l.cb === cb);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
once<T extends keyof ET>(topic: T, cb: eventHandler<ET[T]>) {
|
|
36
|
-
return this.addListener(topic, cb, true);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
publish<T extends keyof ET>(topic: T, evt: ET[T]) {
|
|
40
|
-
const topics = this._t;
|
|
41
|
-
const topicList = topics[topic];
|
|
42
|
-
if (!topicList) return;
|
|
43
|
-
topics[topic] = topicList.filter(listener => !listener.once);
|
|
44
|
-
topicList.forEach(listener => listener.cb(evt));
|
|
45
|
-
}
|
|
46
|
-
}
|
package/src/utils/index.ts
DELETED
package/tsconfig.json
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "es5",
|
|
4
|
-
"jsx": "react",
|
|
5
|
-
"experimentalDecorators": true,
|
|
6
|
-
"module": "esnext",
|
|
7
|
-
"moduleResolution": "node",
|
|
8
|
-
"baseUrl": "./",
|
|
9
|
-
"paths": {
|
|
10
|
-
"@/*": ["./src/*"]
|
|
11
|
-
},
|
|
12
|
-
"useUnknownInCatchVariables": false,
|
|
13
|
-
"allowJs": true,
|
|
14
|
-
"sourceMap": true,
|
|
15
|
-
"allowSyntheticDefaultImports": true,
|
|
16
|
-
"esModuleInterop": true,
|
|
17
|
-
"forceConsistentCasingInFileNames": true,
|
|
18
|
-
"resolveJsonModule": true,
|
|
19
|
-
"strict": true,
|
|
20
|
-
"noImplicitAny": false,
|
|
21
|
-
"skipLibCheck": true
|
|
22
|
-
},
|
|
23
|
-
"include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.tsx"]
|
|
24
|
-
}
|
package/vite.config.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vite';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import react from '@vitejs/plugin-react';
|
|
4
|
-
import commonjs from '@rollup/plugin-commonjs';
|
|
5
|
-
|
|
6
|
-
export default defineConfig(({}) => {
|
|
7
|
-
return {
|
|
8
|
-
mode: 'development',
|
|
9
|
-
root: path.resolve(__dirname, 'src/demo'),
|
|
10
|
-
base: '',
|
|
11
|
-
define: {},
|
|
12
|
-
server: {
|
|
13
|
-
host: '0.0.0.0',
|
|
14
|
-
port: 3000,
|
|
15
|
-
proxy: {},
|
|
16
|
-
},
|
|
17
|
-
resolve: {
|
|
18
|
-
alias: [
|
|
19
|
-
{
|
|
20
|
-
find: '@',
|
|
21
|
-
replacement: path.resolve(__dirname, 'src'),
|
|
22
|
-
},
|
|
23
|
-
],
|
|
24
|
-
extensions: ['.js', '.ts', '.jsx', '.tsx', '.json'],
|
|
25
|
-
},
|
|
26
|
-
plugins: [
|
|
27
|
-
react({
|
|
28
|
-
include: '**/*.{jsx,tsx}',
|
|
29
|
-
}),
|
|
30
|
-
commonjs(),
|
|
31
|
-
],
|
|
32
|
-
css: {
|
|
33
|
-
preprocessorOptions: {
|
|
34
|
-
less: {
|
|
35
|
-
javascriptEnabled: true,
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
};
|
|
40
|
-
});
|