fcr-core 3.8.1 → 3.9.0-alpha
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/lib/chat-connector/type.d.ts +40 -0
- package/lib/{chat-connection → chat-connector}/type.js +1 -1
- package/lib/engine/index.d.ts +10 -11
- package/lib/engine/index.js +63 -72
- package/lib/engine/type.d.ts +96 -0
- package/lib/engine/type.js +5 -0
- package/lib/imports.d.ts +7 -4
- package/lib/imports.js +30 -4
- package/lib/index.d.ts +3 -2
- package/lib/index.js +21 -2
- package/lib/media-control/desktop.js +12 -12
- package/lib/media-control/mobile.js +4 -0
- package/lib/media-control/type.d.ts +32 -33
- package/lib/monitor-control/index.js +3 -3
- package/lib/peer-session/index.js +14 -14
- package/lib/peer-session/type.d.ts +1 -1
- package/lib/plugins/chat/chatroom.js +417 -0
- package/lib/{chat-connection → plugins/chat}/config.d.ts +1 -0
- package/lib/{room-control/chatroom-control → plugins/chat}/config.js +2 -1
- package/lib/plugins/chat/connector.d.ts +38 -0
- package/lib/{chat-connection/index.js → plugins/chat/connector.js} +181 -61
- package/lib/room-control/ability-control/index.js +5 -4
- package/lib/room-control/ability-control/type.d.ts +5 -1
- package/lib/room-control/ability-control/type.js +4 -0
- package/lib/room-control/chatroom-control/type.d.ts +44 -35
- package/lib/room-control/group-control/index.js +9 -9
- package/lib/room-control/index.js +37 -22
- package/lib/room-control/interpreter-control/index.js +7 -4
- package/lib/room-control/interpreter-control/room.js +3 -3
- package/lib/room-control/interpreter-control/types.d.ts +2 -2
- package/lib/room-control/join-before-host-waitingroom-control/index.js +3 -3
- package/lib/room-control/mainroom-control/index.js +15 -13
- package/lib/room-control/privilege-control/index.js +39 -24
- package/lib/room-control/privilege-control/type.d.ts +15 -15
- package/lib/room-control/room-connector-control/index.js +7 -5
- package/lib/room-control/room-connector-control/type.d.ts +1 -1
- package/lib/room-control/room-control-factory.d.ts +3 -3
- package/lib/room-control/room-control-factory.js +7 -7
- package/lib/room-control/room-session/index.js +17 -15
- package/lib/room-control/room-session/type.d.ts +3 -3
- package/lib/room-control/sharing-control/index.js +13 -7
- package/lib/room-control/stream-control/index.js +18 -16
- package/lib/room-control/stream-control/type.d.ts +5 -5
- package/lib/room-control/stt-control/index.js +38 -31
- package/lib/room-control/type.d.ts +19 -19
- package/lib/room-control/user-control/index.js +20 -22
- package/lib/room-control/user-control/type.d.ts +1 -1
- package/lib/room-control/waitingroom-control/index.js +11 -11
- package/lib/room-control/whiteboard-control-v1/board-window.d.ts +21 -20
- package/lib/room-control/whiteboard-control-v1/board-window.js +27 -8
- package/lib/room-control/whiteboard-control-v1/factory.js +1 -1
- package/lib/room-control/whiteboard-control-v1/index.js +26 -18
- package/lib/room-control/whiteboard-control-v1/type.d.ts +26 -25
- package/lib/room-control/whiteboard-control-v1/type.js +1 -0
- package/lib/room-control/whiteboard-control-v2/annotation-control/control.d.ts +15 -6
- package/lib/room-control/whiteboard-control-v2/annotation-control/control.js +39 -5
- package/lib/room-control/whiteboard-control-v2/annotation-control/factory.d.ts +4 -5
- package/lib/room-control/whiteboard-control-v2/annotation-control/factory.js +6 -5
- package/lib/room-control/whiteboard-control-v2/annotation-control/type.d.ts +7 -1
- package/lib/room-control/whiteboard-control-v2/base/index.d.ts +9 -8
- package/lib/room-control/whiteboard-control-v2/base/index.js +84 -42
- package/lib/room-control/whiteboard-control-v2/base/main-window.d.ts +16 -15
- package/lib/room-control/whiteboard-control-v2/base/main-window.js +23 -4
- package/lib/room-control/whiteboard-control-v2/type.d.ts +17 -17
- package/lib/room-control/whiteboard-control-v2/whiteboard-control/control.d.ts +12 -6
- package/lib/room-control/whiteboard-control-v2/whiteboard-control/control.js +64 -18
- package/lib/room-control/whiteboard-control-v2/whiteboard-control/factory.d.ts +2 -2
- package/lib/room-control/whiteboard-control-v2/whiteboard-control/factory.js +10 -10
- package/lib/room-control/whiteboard-control-v2/whiteboard-control/type.d.ts +1 -1
- package/lib/room-router/index.js +10 -7
- package/lib/room-router/type.d.ts +1 -1
- package/lib/schema.d.ts +24 -46
- package/lib/schema.js +1 -2
- package/lib/service/api.d.ts +5 -3
- package/lib/service/api.js +17 -12
- package/lib/type.d.ts +64 -45
- package/lib/type.js +76 -11
- package/lib/utilities/abortable-retry.d.ts +38 -0
- package/lib/utilities/abortable-retry.js +61 -0
- package/lib/utilities/dual-video-stream-config.d.ts +6 -0
- package/lib/utilities/dual-video-stream-config.js +25 -0
- package/lib/utilities/error-helpers.d.ts +10 -9
- package/lib/utilities/error-helpers.js +12 -11
- package/lib/utilities/error.d.ts +4 -40
- package/lib/utilities/error.js +20 -77
- package/lib/utilities/join-helper.js +2 -2
- package/lib/utilities/logger.d.ts +2 -2
- package/lib/utilities/logger.js +6 -25
- package/lib/utilities/package-info.d.ts +1 -2
- package/lib/utilities/package-info.js +4 -8
- package/lib/utilities/parameters.js +88 -15
- package/lib/utilities/validate-params.js +1 -1
- package/lib/utilities/video-encoder-config.d.ts +9 -0
- package/lib/utilities/video-encoder-config.js +109 -0
- package/lib-es/base-session.js +1 -0
- package/lib-es/chat-connector/type.js +6 -0
- package/lib-es/engine/index.js +412 -0
- package/lib-es/engine/type.js +1 -0
- package/lib-es/imports.js +59 -0
- package/lib-es/index.js +8 -0
- package/lib-es/media-control/desktop.js +172 -0
- package/lib-es/media-control/mobile.js +198 -0
- package/lib-es/media-control/type.js +6 -0
- package/lib-es/monitor-control/index.js +46 -0
- package/lib-es/monitor-control/type.js +1 -0
- package/lib-es/peer-session/index.js +279 -0
- package/lib-es/peer-session/type.js +1 -0
- package/lib-es/plugins/chat/chatroom.js +409 -0
- package/{lib/chat-connection → lib-es/plugins/chat}/config.js +5 -9
- package/lib-es/plugins/chat/connector.js +269 -0
- package/lib-es/plugins/electron-rtc-plugin.js +1 -0
- package/lib-es/plugins/rtm-plugin.js +1 -0
- package/lib-es/plugins/web-rtc-plugin.js +1 -0
- package/lib-es/room-control/ability-control/index.js +58 -0
- package/lib-es/room-control/ability-control/type.js +15 -0
- package/lib-es/room-control/chatroom-control/type.js +12 -0
- package/lib-es/room-control/group-control/index.js +256 -0
- package/lib-es/room-control/helpers/constants.js +92 -0
- package/lib-es/room-control/helpers/index.js +20 -0
- package/lib-es/room-control/helpers/validation-helper.js +46 -0
- package/lib-es/room-control/index.js +623 -0
- package/lib-es/room-control/interpreter-control/index.js +172 -0
- package/lib-es/room-control/interpreter-control/room.js +28 -0
- package/lib-es/room-control/interpreter-control/types.js +26 -0
- package/lib-es/room-control/join-before-host-waitingroom-control/index.js +29 -0
- package/lib-es/room-control/mainroom-control/index.js +248 -0
- package/lib-es/room-control/privilege-control/helper.js +97 -0
- package/lib-es/room-control/privilege-control/index.js +339 -0
- package/lib-es/room-control/privilege-control/type.js +159 -0
- package/lib-es/room-control/room-connector-control/index.js +182 -0
- package/lib-es/room-control/room-connector-control/type.js +28 -0
- package/lib-es/room-control/room-control-factory.js +77 -0
- package/lib-es/room-control/room-session/index.js +292 -0
- package/lib-es/room-control/room-session/type.js +1 -0
- package/lib-es/room-control/shared-cache.js +47 -0
- package/lib-es/room-control/sharing-control/index.js +307 -0
- package/lib-es/room-control/sharing-control/type.js +16 -0
- package/lib-es/room-control/stream-control/index.js +536 -0
- package/lib-es/room-control/stream-control/type.js +1 -0
- package/lib-es/room-control/stt-control/de-compress-gzip.js +33 -0
- package/lib-es/room-control/stt-control/index.js +350 -0
- package/lib-es/room-control/stt-control/type.js +10 -0
- package/lib-es/room-control/type.js +30 -0
- package/lib-es/room-control/user-control/index.js +344 -0
- package/lib-es/room-control/user-control/type.js +21 -0
- package/lib-es/room-control/waitingroom-control/index.js +68 -0
- package/lib-es/room-control/whiteboard-control/enum.js +18 -0
- package/lib-es/room-control/whiteboard-control/type.js +10 -0
- package/lib-es/room-control/whiteboard-control/utils.js +13 -0
- package/lib-es/room-control/whiteboard-control-v1/board-subwindow.js +18 -0
- package/lib-es/room-control/whiteboard-control-v1/board-window.js +573 -0
- package/lib-es/room-control/whiteboard-control-v1/enum.js +157 -0
- package/lib-es/room-control/whiteboard-control-v1/factory.js +12 -0
- package/lib-es/room-control/whiteboard-control-v1/index.js +427 -0
- package/lib-es/room-control/whiteboard-control-v1/mount-manager.js +6 -0
- package/lib-es/room-control/whiteboard-control-v1/type.js +8 -0
- package/lib-es/room-control/whiteboard-control-v1/utils.js +273 -0
- package/lib-es/room-control/whiteboard-control-v2/annotation-control/control.js +76 -0
- package/lib-es/room-control/whiteboard-control-v2/annotation-control/factory.js +37 -0
- package/lib-es/room-control/whiteboard-control-v2/annotation-control/type.js +1 -0
- package/lib-es/room-control/whiteboard-control-v2/base/index.js +347 -0
- package/lib-es/room-control/whiteboard-control-v2/base/main-window.js +269 -0
- package/lib-es/room-control/whiteboard-control-v2/constant.js +9 -0
- package/lib-es/room-control/whiteboard-control-v2/enum.js +28 -0
- package/lib-es/room-control/whiteboard-control-v2/type.js +1 -0
- package/lib-es/room-control/whiteboard-control-v2/utils.js +92 -0
- package/lib-es/room-control/whiteboard-control-v2/whiteboard-control/control.js +204 -0
- package/lib-es/room-control/whiteboard-control-v2/whiteboard-control/factory.js +61 -0
- package/lib-es/room-control/whiteboard-control-v2/whiteboard-control/type.js +1 -0
- package/lib-es/room-router/index.js +263 -0
- package/lib-es/room-router/type.js +5 -0
- package/lib-es/schema.js +231 -0
- package/lib-es/service/api.js +1211 -0
- package/lib-es/service/type.js +1 -0
- package/lib-es/type.js +222 -0
- package/lib-es/utilities/abortable-retry.js +54 -0
- package/lib-es/utilities/cmd.js +1 -0
- package/lib-es/utilities/collection.js +64 -0
- package/lib-es/utilities/dual-video-stream-config.js +19 -0
- package/lib-es/utilities/error-helpers.js +224 -0
- package/lib-es/utilities/error.js +43 -0
- package/lib-es/utilities/join-helper.js +219 -0
- package/lib-es/utilities/logger.js +7 -0
- package/lib-es/utilities/package-info.js +5 -0
- package/lib-es/utilities/parameters.js +106 -0
- package/lib-es/utilities/retry-helpers.js +66 -0
- package/lib-es/utilities/shared-storage.js +31 -0
- package/lib-es/utilities/stream.js +18 -0
- package/lib-es/utilities/user.js +30 -0
- package/lib-es/utilities/validate-params.js +8 -0
- package/lib-es/utilities/video-encoder-config.js +103 -0
- package/package.json +11 -10
- package/lib/chat-connection/index.d.ts +0 -24
- package/lib/chat-connection/type.d.ts +0 -17
- package/lib/plugins/chatroom.js +0 -454
- package/lib/room-control/chatroom-control/config.d.ts +0 -51
- package/lib/utilities/storage.d.ts +0 -8
- package/lib/utilities/storage.js +0 -33
- /package/lib/plugins/{chatroom.d.ts → chat/chatroom.d.ts} +0 -0
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import "core-js/modules/es.array.push.js";
|
|
2
|
+
import "core-js/modules/esnext.function.metadata.js";
|
|
3
|
+
import "core-js/modules/esnext.map.delete-all.js";
|
|
4
|
+
import "core-js/modules/esnext.map.emplace.js";
|
|
5
|
+
import "core-js/modules/esnext.map.every.js";
|
|
6
|
+
import "core-js/modules/esnext.map.filter.js";
|
|
7
|
+
import "core-js/modules/esnext.map.find.js";
|
|
8
|
+
import "core-js/modules/esnext.map.find-key.js";
|
|
9
|
+
import "core-js/modules/esnext.map.includes.js";
|
|
10
|
+
import "core-js/modules/esnext.map.key-of.js";
|
|
11
|
+
import "core-js/modules/esnext.map.map-keys.js";
|
|
12
|
+
import "core-js/modules/esnext.map.map-values.js";
|
|
13
|
+
import "core-js/modules/esnext.map.merge.js";
|
|
14
|
+
import "core-js/modules/esnext.map.reduce.js";
|
|
15
|
+
import "core-js/modules/esnext.map.some.js";
|
|
16
|
+
import "core-js/modules/esnext.map.update.js";
|
|
17
|
+
import "core-js/modules/esnext.symbol.metadata.js";
|
|
18
|
+
let _initProto, _setOperationPrivilegeDecs;
|
|
19
|
+
import "core-js/modules/es.json.stringify.js";
|
|
20
|
+
function _applyDecs(e, t, r, n, o, a) { function i(e, t, r) { return function (n, o) { return r && r(n), e[t].call(n, o); }; } function c(e, t) { for (var r = 0; r < e.length; r++) e[r].call(t); return t; } function s(e, t, r, n) { if ("function" != typeof e && (n || void 0 !== e)) throw new TypeError(t + " must " + (r || "be") + " a function" + (n ? "" : " or undefined")); return e; } function applyDec(e, t, r, n, o, a, c, u, l, f, p, d, h) { function m(e) { if (!h(e)) throw new TypeError("Attempted to access private element on non-instance"); } var y, v = t[0], g = t[3], b = !u; if (!b) { r || Array.isArray(v) || (v = [v]); var w = {}, S = [], A = 3 === o ? "get" : 4 === o || d ? "set" : "value"; f ? (p || d ? w = { get: _setFunctionName(function () { return g(this); }, n, "get"), set: function (e) { t[4](this, e); } } : w[A] = g, p || _setFunctionName(w[A], n, 2 === o ? "" : A)) : p || (w = Object.getOwnPropertyDescriptor(e, n)); } for (var P = e, j = v.length - 1; j >= 0; j -= r ? 2 : 1) { var D = v[j], E = r ? v[j - 1] : void 0, I = {}, O = { kind: ["field", "accessor", "method", "getter", "setter", "class"][o], name: n, metadata: a, addInitializer: function (e, t) { if (e.v) throw Error("attempted to call addInitializer after decoration was finished"); s(t, "An initializer", "be", !0), c.push(t); }.bind(null, I) }; try { if (b) (y = s(D.call(E, P, O), "class decorators", "return")) && (P = y);else { var k, F; O.static = l, O.private = f, f ? 2 === o ? k = function (e) { return m(e), w.value; } : (o < 4 && (k = i(w, "get", m)), 3 !== o && (F = i(w, "set", m))) : (k = function (e) { return e[n]; }, (o < 2 || 4 === o) && (F = function (e, t) { e[n] = t; })); var N = O.access = { has: f ? h.bind() : function (e) { return n in e; } }; if (k && (N.get = k), F && (N.set = F), P = D.call(E, d ? { get: w.get, set: w.set } : w[A], O), d) { if ("object" == typeof P && P) (y = s(P.get, "accessor.get")) && (w.get = y), (y = s(P.set, "accessor.set")) && (w.set = y), (y = s(P.init, "accessor.init")) && S.push(y);else if (void 0 !== P) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0"); } else s(P, (p ? "field" : "method") + " decorators", "return") && (p ? S.push(P) : w[A] = P); } } finally { I.v = !0; } } return (p || d) && u.push(function (e, t) { for (var r = S.length - 1; r >= 0; r--) t = S[r].call(e, t); return t; }), p || b || (f ? d ? u.push(i(w, "get"), i(w, "set")) : u.push(2 === o ? w[A] : i.call.bind(w[A])) : Object.defineProperty(e, n, w)), P; } function u(e, t) { return Object.defineProperty(e, Symbol.metadata || Symbol.for("Symbol.metadata"), { configurable: !0, enumerable: !0, value: t }); } if (arguments.length >= 6) var l = a[Symbol.metadata || Symbol.for("Symbol.metadata")]; var f = Object.create(null == l ? null : l), p = function (e, t, r, n) { var o, a, i = [], s = function (t) { return _checkInRHS(t) === e; }, u = new Map(); function l(e) { e && i.push(c.bind(null, e)); } for (var f = 0; f < t.length; f++) { var p = t[f]; if (Array.isArray(p)) { var d = p[1], h = p[2], m = p.length > 3, y = 16 & d, v = !!(8 & d), g = 0 == (d &= 7), b = h + "/" + v; if (!g && !m) { var w = u.get(b); if (!0 === w || 3 === w && 4 !== d || 4 === w && 3 !== d) throw Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + h); u.set(b, !(d > 2) || d); } applyDec(v ? e : e.prototype, p, y, m ? "#" + h : _toPropertyKey(h), d, n, v ? a = a || [] : o = o || [], i, v, m, g, 1 === d, v && m ? s : r); } } return l(o), l(a), i; }(e, t, o, f); return r.length || u(e, f), { e: p, get c() { var t = []; return r.length && [u(applyDec(e, [r], n, e.name, 5, f, t), f), c.bind(null, t, e)]; } }; }
|
|
21
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
22
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
23
|
+
function _setFunctionName(e, t, n) { "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : ""); try { Object.defineProperty(e, "name", { configurable: !0, value: n ? n + " " + t : t }); } catch (e) {} return e; }
|
|
24
|
+
function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); return e; }
|
|
25
|
+
import { Room } from '@netless/forge-room';
|
|
26
|
+
import { RTMProvider_2_2 } from '@netless/forge-rtm';
|
|
27
|
+
import { WhiteboardApplication } from '@netless/forge-whiteboard';
|
|
28
|
+
import { DetailErrorCode, ErrorModuleCode } from '../../../imports';
|
|
29
|
+
import { AgoraObservable, AgoraScheduler, jsonstring, retryAttempt, to, trace } from '../../../imports';
|
|
30
|
+
import { FcrConnectionState, FcrReturnCode } from '../../../type';
|
|
31
|
+
import { generateFcrCoreClientError, FcrErrorModuleCode, FcrErrorCode } from '../../../utilities/error';
|
|
32
|
+
import { createLogger, generateLogObserver } from '../../../utilities/logger';
|
|
33
|
+
import { INIT_CONFIG_FETCH_INTERVAL, WHITEBOARD_APP_ID } from '../constant';
|
|
34
|
+
import { FcrBoardMainWindowImpl } from './main-window';
|
|
35
|
+
|
|
36
|
+
/** @param isNeedLaunch 是否需要调用白板 luanch 函数 */
|
|
37
|
+
|
|
38
|
+
const WHITEBOARD_ROOM_JOIN_TIMEOUT = 20000;
|
|
39
|
+
export class FcrBaseWhiteboardControlImpl {
|
|
40
|
+
static {
|
|
41
|
+
[_initProto] = _applyDecs(this, [[_setOperationPrivilegeDecs, 2, "setOperationPrivilege"], [trace, 2, "open"], [trace, 2, "close"], [trace, 2, "getConnectionState"], [trace, 2, "getMainWindow"]], []).e;
|
|
42
|
+
}
|
|
43
|
+
[(_setOperationPrivilegeDecs = trace(['hasOperationPrivilege']), "logger")] = (_initProto(this), createLogger({
|
|
44
|
+
prefix: 'FcrBaseWhiteboardControl'
|
|
45
|
+
}));
|
|
46
|
+
observable = new AgoraObservable();
|
|
47
|
+
boardView = null;
|
|
48
|
+
boardRoom = null;
|
|
49
|
+
whiteboard = null;
|
|
50
|
+
connectState = FcrConnectionState.DISCONNECTED;
|
|
51
|
+
forgeInitConfig = null;
|
|
52
|
+
hasOperationPrivilege = false;
|
|
53
|
+
_waitPromise = null;
|
|
54
|
+
_waitPromiseResolve = null;
|
|
55
|
+
_waitPromiseReject = null;
|
|
56
|
+
_openAbortController = null;
|
|
57
|
+
_openState = {
|
|
58
|
+
isOpen: false,
|
|
59
|
+
isNeedLaunch: undefined
|
|
60
|
+
};
|
|
61
|
+
constructor(rtmClient, config, hasOperationPrivilege, forgeInitConfigFetcher) {
|
|
62
|
+
this.rtmClient = rtmClient;
|
|
63
|
+
this.config = config;
|
|
64
|
+
this.hasOperationPrivilege = hasOperationPrivilege;
|
|
65
|
+
this.forgeInitConfigTask = AgoraScheduler.shared.addPollingTask(async () => {
|
|
66
|
+
const forgeInitConfig = await forgeInitConfigFetcher();
|
|
67
|
+
this.forgeInitConfig = forgeInitConfig;
|
|
68
|
+
this.logger.info(`fetch forge init config success, config: ${jsonstring(forgeInitConfig)}`);
|
|
69
|
+
this.forgeInitConfigTask.stop();
|
|
70
|
+
if (this._openState.isOpen) {
|
|
71
|
+
this.connect(this._openState.isNeedLaunch);
|
|
72
|
+
}
|
|
73
|
+
}, INIT_CONFIG_FETCH_INTERVAL);
|
|
74
|
+
this.addLogObserver();
|
|
75
|
+
}
|
|
76
|
+
setOperationPrivilege(hasOperationPrivilege) {
|
|
77
|
+
if (this.hasOperationPrivilege !== hasOperationPrivilege) {
|
|
78
|
+
this.hasOperationPrivilege = hasOperationPrivilege;
|
|
79
|
+
const boardRoom = this.boardRoom;
|
|
80
|
+
const boardView = this.boardView;
|
|
81
|
+
if (boardRoom) {
|
|
82
|
+
if (hasOperationPrivilege) {
|
|
83
|
+
boardRoom.setWritable(true);
|
|
84
|
+
if (boardView) {
|
|
85
|
+
// @ts-expect-error
|
|
86
|
+
boardView._observable.notifyObservers('onWritable', true);
|
|
87
|
+
}
|
|
88
|
+
} else {
|
|
89
|
+
boardRoom.setWritable(false);
|
|
90
|
+
if (boardView) {
|
|
91
|
+
// @ts-expect-error
|
|
92
|
+
boardView._observable.notifyObservers('onWritable', false);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return FcrReturnCode.SUCCESS;
|
|
98
|
+
}
|
|
99
|
+
async open() {
|
|
100
|
+
this.logger.error('subclass must implement open method, not call base class method');
|
|
101
|
+
throw generateFcrCoreClientError(FcrErrorModuleCode.FCR_ROOM_WHITEBOARD, FcrErrorCode.UNDEFINED_ERROR, 'subclass must implement open method, not call base class method', new Error('subclass must implement open method, not call base class method'));
|
|
102
|
+
}
|
|
103
|
+
async close() {
|
|
104
|
+
this._openState = {
|
|
105
|
+
isOpen: false,
|
|
106
|
+
isNeedLaunch: undefined
|
|
107
|
+
};
|
|
108
|
+
if (!this.forgeInitConfigTask.isStopped) {
|
|
109
|
+
this.forgeInitConfigTask.stop();
|
|
110
|
+
}
|
|
111
|
+
if (this._waitPromiseReject) {
|
|
112
|
+
this._waitPromiseReject(new Error('closed before connection established'));
|
|
113
|
+
this._clearWaitPromise();
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
if (this._openAbortController) {
|
|
117
|
+
this._openAbortController.abort();
|
|
118
|
+
this._openAbortController = null;
|
|
119
|
+
}
|
|
120
|
+
const boardRoom = this.boardRoom;
|
|
121
|
+
this.boardRoom = null;
|
|
122
|
+
this.boardView = null;
|
|
123
|
+
this.whiteboard = null;
|
|
124
|
+
if (boardRoom) {
|
|
125
|
+
boardRoom.applicationManager.removeAllListeners();
|
|
126
|
+
await boardRoom.leaveRoom();
|
|
127
|
+
}
|
|
128
|
+
} catch (e) {
|
|
129
|
+
this.logger.error('leave board room failed', e);
|
|
130
|
+
} finally {
|
|
131
|
+
this.updateConnectionState(FcrConnectionState.DISCONNECTED);
|
|
132
|
+
}
|
|
133
|
+
return FcrReturnCode.SUCCESS;
|
|
134
|
+
}
|
|
135
|
+
getConnectionState() {
|
|
136
|
+
return this.connectState;
|
|
137
|
+
}
|
|
138
|
+
getMainWindow() {
|
|
139
|
+
return this.boardView;
|
|
140
|
+
}
|
|
141
|
+
addObserver(observer) {
|
|
142
|
+
this.observable.addObserver(observer);
|
|
143
|
+
}
|
|
144
|
+
removeObserver(observer) {
|
|
145
|
+
this.observable.removeObserver(observer);
|
|
146
|
+
}
|
|
147
|
+
internalOpen(isNeedLaunch) {
|
|
148
|
+
this._openState = {
|
|
149
|
+
isOpen: true,
|
|
150
|
+
isNeedLaunch: isNeedLaunch
|
|
151
|
+
};
|
|
152
|
+
const isReadyToConnect = this._checkForConnect();
|
|
153
|
+
if (isReadyToConnect) {
|
|
154
|
+
return this.connect(isNeedLaunch);
|
|
155
|
+
}
|
|
156
|
+
if (!this._waitPromise) {
|
|
157
|
+
this._waitPromise = new Promise((resolve, reject) => {
|
|
158
|
+
this._waitPromiseResolve = resolve;
|
|
159
|
+
this._waitPromiseReject = reject;
|
|
160
|
+
this.logger.info('waiting for forge config to be ready');
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
return this._waitPromise;
|
|
164
|
+
}
|
|
165
|
+
updateConnectionState(state) {
|
|
166
|
+
if (this.connectState === state) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const oldState = this.connectState;
|
|
170
|
+
this.connectState = state;
|
|
171
|
+
this.logger.info(`Connection state updated: ${FcrConnectionState[oldState]} -> ${FcrConnectionState[state]}`);
|
|
172
|
+
this.observable.notifyObservers('onConnectionStateUpdated', state);
|
|
173
|
+
}
|
|
174
|
+
async connect(isNeedLaunch) {
|
|
175
|
+
if (this.boardView) {
|
|
176
|
+
this.logger.info('board already connected, returning existing board view');
|
|
177
|
+
return this.boardView;
|
|
178
|
+
}
|
|
179
|
+
const abortController = new AbortController();
|
|
180
|
+
this._openAbortController = abortController;
|
|
181
|
+
return new Promise(async (resolve, reject) => {
|
|
182
|
+
// 监听中止信号
|
|
183
|
+
abortController.signal.addEventListener('abort', () => {
|
|
184
|
+
reject(new Error('join board aborted'));
|
|
185
|
+
});
|
|
186
|
+
const {
|
|
187
|
+
userId,
|
|
188
|
+
userName
|
|
189
|
+
} = this.config;
|
|
190
|
+
const {
|
|
191
|
+
boardAppId,
|
|
192
|
+
boardId,
|
|
193
|
+
boardRegion,
|
|
194
|
+
boardToken
|
|
195
|
+
} = this.forgeInitConfig || {};
|
|
196
|
+
if (!boardAppId) {
|
|
197
|
+
throw generateFcrCoreClientError(ErrorModuleCode.FCR_ROOM_WHITEBOARD, DetailErrorCode.UNDEFINED_ERROR, 'boardAppId is required', new Error('boardAppId is required'));
|
|
198
|
+
}
|
|
199
|
+
if (!boardId) {
|
|
200
|
+
throw generateFcrCoreClientError(ErrorModuleCode.FCR_ROOM_WHITEBOARD, DetailErrorCode.UNDEFINED_ERROR, 'boardId is required', new Error('boardId is required'));
|
|
201
|
+
}
|
|
202
|
+
if (!boardToken) {
|
|
203
|
+
throw generateFcrCoreClientError(ErrorModuleCode.FCR_ROOM_WHITEBOARD, DetailErrorCode.UNDEFINED_ERROR, 'boardToken is required', new Error('boardToken is required'));
|
|
204
|
+
}
|
|
205
|
+
const whiteboardOption = this.getWhiteboardOption();
|
|
206
|
+
let width = whiteboardOption.width;
|
|
207
|
+
let height = whiteboardOption.height;
|
|
208
|
+
if (!width) {
|
|
209
|
+
this.logger.warn(`board width is a invalid vlaue: ${width}, using default value 800`);
|
|
210
|
+
whiteboardOption.width = 800;
|
|
211
|
+
}
|
|
212
|
+
if (!height) {
|
|
213
|
+
this.logger.warn(`board height is a invalid value: ${height}, using default value 600`);
|
|
214
|
+
whiteboardOption.height = 600;
|
|
215
|
+
}
|
|
216
|
+
this.logger.info(`open board with boardId: ${boardId}, boardToken: ${boardToken}, region: ${boardRegion}, appIdentifier: ${boardAppId} whiteboardOption: ${jsonstring(whiteboardOption)}`);
|
|
217
|
+
const rtmProvider = new RTMProvider_2_2(this.rtmClient);
|
|
218
|
+
const wbRoom = new Room(boardId, rtmProvider);
|
|
219
|
+
wbRoom.applicationManager.registerApplication(WhiteboardApplication);
|
|
220
|
+
try {
|
|
221
|
+
this.updateConnectionState(FcrConnectionState.CONNECTING);
|
|
222
|
+
let error = null;
|
|
223
|
+
let boardView = null;
|
|
224
|
+
let whiteboard = null;
|
|
225
|
+
let boardRoom = wbRoom;
|
|
226
|
+
const appId = this.getApplicationId();
|
|
227
|
+
let getWhiteboard;
|
|
228
|
+
|
|
229
|
+
// 第一个开启白板的人需要调用 launch 方法, 其他人监听 launch 事件获取白板实例
|
|
230
|
+
if (isNeedLaunch) {
|
|
231
|
+
getWhiteboard = () => {
|
|
232
|
+
return wbRoom.applicationManager.launchApplication(WhiteboardApplication, whiteboardOption, appId);
|
|
233
|
+
};
|
|
234
|
+
} else {
|
|
235
|
+
const launchPromise = new Promise((launchPromseResolve, launchPromseReject) => {
|
|
236
|
+
wbRoom.applicationManager.once('launch', (appId, app) => {
|
|
237
|
+
launchPromseResolve(app);
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
getWhiteboard = () => {
|
|
241
|
+
return launchPromise;
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
[error] = await to(retryAttempt(async () => {
|
|
245
|
+
const joinRoomParams = {
|
|
246
|
+
userId,
|
|
247
|
+
nickName: userName || userId,
|
|
248
|
+
roomToken: boardToken,
|
|
249
|
+
sdkConfig: {
|
|
250
|
+
region: boardRegion,
|
|
251
|
+
appIdentifier: boardAppId
|
|
252
|
+
},
|
|
253
|
+
writable: true
|
|
254
|
+
// verboseLog: true,
|
|
255
|
+
};
|
|
256
|
+
this.logger.info(`join params: ${jsonstring(joinRoomParams)}`);
|
|
257
|
+
|
|
258
|
+
// 20 秒超时
|
|
259
|
+
await wbRoom.joinRoom(joinRoomParams, WHITEBOARD_ROOM_JOIN_TIMEOUT);
|
|
260
|
+
boardRoom = wbRoom;
|
|
261
|
+
whiteboard = await getWhiteboard();
|
|
262
|
+
if (isNeedLaunch) {
|
|
263
|
+
// 在同一个房间内只有第一次调用 launchApplication 时传入的宽高参数会生效, 后续的调用不会生效, 所以需要在这里更新宽高
|
|
264
|
+
// 只有 launch 的用户需要更新宽、高, 白板会自动同步给后加入的用户
|
|
265
|
+
whiteboard.updateViewport(width, height);
|
|
266
|
+
}
|
|
267
|
+
}, [], {
|
|
268
|
+
retriesMax: 0
|
|
269
|
+
}).fail(async ({
|
|
270
|
+
error,
|
|
271
|
+
timeFn,
|
|
272
|
+
currentRetry
|
|
273
|
+
}) => {
|
|
274
|
+
if (abortController.signal.aborted) {
|
|
275
|
+
throw new Error('join board aborted');
|
|
276
|
+
}
|
|
277
|
+
this.logger.error(`failed to join board, error: ${error.message}, current retry: ${currentRetry}`, error);
|
|
278
|
+
await timeFn();
|
|
279
|
+
return true;
|
|
280
|
+
}).exec());
|
|
281
|
+
if (abortController.signal.aborted) {
|
|
282
|
+
throw new Error('join board aborted');
|
|
283
|
+
}
|
|
284
|
+
if (error) {
|
|
285
|
+
this.logger.error(`join board failed, ${error.message}-${JSON.stringify(error)}`);
|
|
286
|
+
throw error;
|
|
287
|
+
}
|
|
288
|
+
whiteboard.enableCameraByMouse = false;
|
|
289
|
+
whiteboard.enableCameraByTouch = false;
|
|
290
|
+
whiteboard.setViewModeToMain();
|
|
291
|
+
boardView = new FcrBoardMainWindowImpl(whiteboard, wbRoom, appId);
|
|
292
|
+
boardView.setBackgroundColor(this.getBackgroundColor());
|
|
293
|
+
this.whiteboard = whiteboard;
|
|
294
|
+
this.boardView = boardView;
|
|
295
|
+
this.boardRoom = boardRoom;
|
|
296
|
+
if (this.hasOperationPrivilege) {
|
|
297
|
+
this.boardRoom.setWritable(true);
|
|
298
|
+
} else {
|
|
299
|
+
this.boardRoom.setWritable(false);
|
|
300
|
+
}
|
|
301
|
+
this.updateConnectionState(FcrConnectionState.CONNECTED);
|
|
302
|
+
resolve(boardView);
|
|
303
|
+
if (this._waitPromiseResolve) {
|
|
304
|
+
this._waitPromiseResolve(boardView);
|
|
305
|
+
this._clearWaitPromise();
|
|
306
|
+
}
|
|
307
|
+
} catch (e) {
|
|
308
|
+
this.logger.error(`join board failed`);
|
|
309
|
+
this.updateConnectionState(FcrConnectionState.DISCONNECTED);
|
|
310
|
+
reject(e);
|
|
311
|
+
if (this._waitPromiseReject) {
|
|
312
|
+
this._waitPromiseReject(e);
|
|
313
|
+
this._clearWaitPromise();
|
|
314
|
+
}
|
|
315
|
+
} finally {
|
|
316
|
+
this._openAbortController = null;
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
getApplicationId() {
|
|
321
|
+
return WHITEBOARD_APP_ID;
|
|
322
|
+
}
|
|
323
|
+
getWhiteboardOption() {
|
|
324
|
+
return {
|
|
325
|
+
width: 800,
|
|
326
|
+
height: 600,
|
|
327
|
+
defaultToolbarStyle: {
|
|
328
|
+
tool: 'laser'
|
|
329
|
+
},
|
|
330
|
+
maxScaleRatio: 1
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
getBackgroundColor() {
|
|
334
|
+
return 'rgba(0, 0, 0, 0)';
|
|
335
|
+
}
|
|
336
|
+
addLogObserver() {
|
|
337
|
+
this.addObserver(generateLogObserver(this.logger, [['onConnectionStateUpdated', ['state']]]));
|
|
338
|
+
}
|
|
339
|
+
_checkForConnect() {
|
|
340
|
+
return !!this.forgeInitConfig;
|
|
341
|
+
}
|
|
342
|
+
_clearWaitPromise() {
|
|
343
|
+
this._waitPromiseResolve = null;
|
|
344
|
+
this._waitPromiseReject = null;
|
|
345
|
+
this._waitPromise = null;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import "core-js/modules/es.array.push.js";
|
|
2
|
+
import "core-js/modules/esnext.function.metadata.js";
|
|
3
|
+
import "core-js/modules/esnext.map.delete-all.js";
|
|
4
|
+
import "core-js/modules/esnext.map.emplace.js";
|
|
5
|
+
import "core-js/modules/esnext.map.every.js";
|
|
6
|
+
import "core-js/modules/esnext.map.filter.js";
|
|
7
|
+
import "core-js/modules/esnext.map.find.js";
|
|
8
|
+
import "core-js/modules/esnext.map.find-key.js";
|
|
9
|
+
import "core-js/modules/esnext.map.includes.js";
|
|
10
|
+
import "core-js/modules/esnext.map.key-of.js";
|
|
11
|
+
import "core-js/modules/esnext.map.map-keys.js";
|
|
12
|
+
import "core-js/modules/esnext.map.map-values.js";
|
|
13
|
+
import "core-js/modules/esnext.map.merge.js";
|
|
14
|
+
import "core-js/modules/esnext.map.reduce.js";
|
|
15
|
+
import "core-js/modules/esnext.map.some.js";
|
|
16
|
+
import "core-js/modules/esnext.map.update.js";
|
|
17
|
+
import "core-js/modules/esnext.symbol.metadata.js";
|
|
18
|
+
let _initProto, _setBackgroundColorDecs, _setToolTypeDecs, _setStrokeWidthDecs, _setStrokeColorDecs, _setTextColorDecs, _setTextSizeDecs, _insertImageDecs, _setContainerSizeRatioDecs, _setBoardTransparentDecs, _updateWindowSizeDecs, _setAutoCancelDrawDecs, _handleApplicationLaunchDecs, _handleApplicationTerminalDecs, _enableAutoCancelDecs;
|
|
19
|
+
import "core-js/modules/esnext.iterator.constructor.js";
|
|
20
|
+
import "core-js/modules/esnext.iterator.some.js";
|
|
21
|
+
function _applyDecs(e, t, r, n, o, a) { function i(e, t, r) { return function (n, o) { return r && r(n), e[t].call(n, o); }; } function c(e, t) { for (var r = 0; r < e.length; r++) e[r].call(t); return t; } function s(e, t, r, n) { if ("function" != typeof e && (n || void 0 !== e)) throw new TypeError(t + " must " + (r || "be") + " a function" + (n ? "" : " or undefined")); return e; } function applyDec(e, t, r, n, o, a, c, u, l, f, p, d, h) { function m(e) { if (!h(e)) throw new TypeError("Attempted to access private element on non-instance"); } var y, v = t[0], g = t[3], b = !u; if (!b) { r || Array.isArray(v) || (v = [v]); var w = {}, S = [], A = 3 === o ? "get" : 4 === o || d ? "set" : "value"; f ? (p || d ? w = { get: _setFunctionName(function () { return g(this); }, n, "get"), set: function (e) { t[4](this, e); } } : w[A] = g, p || _setFunctionName(w[A], n, 2 === o ? "" : A)) : p || (w = Object.getOwnPropertyDescriptor(e, n)); } for (var P = e, j = v.length - 1; j >= 0; j -= r ? 2 : 1) { var D = v[j], E = r ? v[j - 1] : void 0, I = {}, O = { kind: ["field", "accessor", "method", "getter", "setter", "class"][o], name: n, metadata: a, addInitializer: function (e, t) { if (e.v) throw Error("attempted to call addInitializer after decoration was finished"); s(t, "An initializer", "be", !0), c.push(t); }.bind(null, I) }; try { if (b) (y = s(D.call(E, P, O), "class decorators", "return")) && (P = y);else { var k, F; O.static = l, O.private = f, f ? 2 === o ? k = function (e) { return m(e), w.value; } : (o < 4 && (k = i(w, "get", m)), 3 !== o && (F = i(w, "set", m))) : (k = function (e) { return e[n]; }, (o < 2 || 4 === o) && (F = function (e, t) { e[n] = t; })); var N = O.access = { has: f ? h.bind() : function (e) { return n in e; } }; if (k && (N.get = k), F && (N.set = F), P = D.call(E, d ? { get: w.get, set: w.set } : w[A], O), d) { if ("object" == typeof P && P) (y = s(P.get, "accessor.get")) && (w.get = y), (y = s(P.set, "accessor.set")) && (w.set = y), (y = s(P.init, "accessor.init")) && S.push(y);else if (void 0 !== P) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0"); } else s(P, (p ? "field" : "method") + " decorators", "return") && (p ? S.push(P) : w[A] = P); } } finally { I.v = !0; } } return (p || d) && u.push(function (e, t) { for (var r = S.length - 1; r >= 0; r--) t = S[r].call(e, t); return t; }), p || b || (f ? d ? u.push(i(w, "get"), i(w, "set")) : u.push(2 === o ? w[A] : i.call.bind(w[A])) : Object.defineProperty(e, n, w)), P; } function u(e, t) { return Object.defineProperty(e, Symbol.metadata || Symbol.for("Symbol.metadata"), { configurable: !0, enumerable: !0, value: t }); } if (arguments.length >= 6) var l = a[Symbol.metadata || Symbol.for("Symbol.metadata")]; var f = Object.create(null == l ? null : l), p = function (e, t, r, n) { var o, a, i = [], s = function (t) { return _checkInRHS(t) === e; }, u = new Map(); function l(e) { e && i.push(c.bind(null, e)); } for (var f = 0; f < t.length; f++) { var p = t[f]; if (Array.isArray(p)) { var d = p[1], h = p[2], m = p.length > 3, y = 16 & d, v = !!(8 & d), g = 0 == (d &= 7), b = h + "/" + v; if (!g && !m) { var w = u.get(b); if (!0 === w || 3 === w && 4 !== d || 4 === w && 3 !== d) throw Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + h); u.set(b, !(d > 2) || d); } applyDec(v ? e : e.prototype, p, y, m ? "#" + h : _toPropertyKey(h), d, n, v ? a = a || [] : o = o || [], i, v, m, g, 1 === d, v && m ? s : r); } } return l(o), l(a), i; }(e, t, o, f); return r.length || u(e, f), { e: p, get c() { var t = []; return r.length && [u(applyDec(e, [r], n, e.name, 5, f, t), f), c.bind(null, t, e)]; } }; }
|
|
22
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
23
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
24
|
+
function _setFunctionName(e, t, n) { "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : ""); try { Object.defineProperty(e, "name", { configurable: !0, value: n ? n + " " + t : t }); } catch (e) {} return e; }
|
|
25
|
+
function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); return e; }
|
|
26
|
+
import { WhiteboardPermissionFlag } from '@netless/forge-whiteboard';
|
|
27
|
+
import { AgoraObservable } from 'agora-foundation/lib/utilities/observable';
|
|
28
|
+
import { convertToForgeBoardTool } from '../utils';
|
|
29
|
+
import { createLogger, generateLogObserver } from '../../../utilities/logger';
|
|
30
|
+
import { trace } from 'agora-foundation/lib/decorator/log';
|
|
31
|
+
import { stringSchema } from 'agora-foundation/lib/utilities/schema';
|
|
32
|
+
import validateParams from '../../../utilities/validate-params';
|
|
33
|
+
import { booleanSchema, colorSchema, fcrBoardToolTypeSchema, fcrSizeSchema, numberSchema, z } from '../../../schema';
|
|
34
|
+
import { bound } from 'agora-foundation/lib/decorator';
|
|
35
|
+
import { FcrReturnCode } from '../../../type';
|
|
36
|
+
export class FcrBoardMainWindowImpl {
|
|
37
|
+
static {
|
|
38
|
+
[_initProto] = _applyDecs(this, [[trace, 2, "addPage"], [trace, 2, "removePage"], [trace, 2, "undo"], [trace, 2, "redo"], [trace, 2, "clean"], [trace, 2, "getSnapshotImage"], [_setBackgroundColorDecs, 2, "setBackgroundColor"], [trace, 2, "getPageInfo"], [trace, 2, "prevPage"], [trace, 2, "nextPage"], [_setToolTypeDecs, 2, "setToolType"], [_setStrokeWidthDecs, 2, "setStrokeWidth"], [_setStrokeColorDecs, 2, "setStrokeColor"], [_setTextColorDecs, 2, "setTextColor"], [_setTextSizeDecs, 2, "setTextSize"], [_insertImageDecs, 2, "insertImage"], [trace, 2, "getContentView"], [_setContainerSizeRatioDecs, 2, "setContainerSizeRatio"], [_setBoardTransparentDecs, 2, "setBoardTransparent"], [_updateWindowSizeDecs, 2, "updateWindowSize"], [_setAutoCancelDrawDecs, 2, "setAutoCancelDraw"], [trace, 2, "getWritable"], [_handleApplicationLaunchDecs, 2, "_handleApplicationLaunch"], [_handleApplicationTerminalDecs, 2, "_handleApplicationTerminal"], [_enableAutoCancelDecs, 2, "_enableAutoCancel"]], []).e;
|
|
39
|
+
}
|
|
40
|
+
[(_setBackgroundColorDecs = [trace(['color']), validateParams(stringSchema)], _setToolTypeDecs = [trace(['type']), validateParams(fcrBoardToolTypeSchema)], _setStrokeWidthDecs = [trace(['strokeWidth']), validateParams(numberSchema)], _setStrokeColorDecs = [trace(['color']), validateParams(z.union([colorSchema, stringSchema]))], _setTextColorDecs = [trace(['color']), validateParams(colorSchema)], _setTextSizeDecs = [trace(['textSize']), validateParams(numberSchema)], _insertImageDecs = [trace(['resourceUrl', 'x', 'y', 'width', 'height']), validateParams(stringSchema, numberSchema, numberSchema, numberSchema, numberSchema)], _setContainerSizeRatioDecs = [trace(['ratio']), validateParams(numberSchema)], _setBoardTransparentDecs = [trace(['isTransparent']), validateParams(booleanSchema)], _updateWindowSizeDecs = [trace(['size']), validateParams(fcrSizeSchema)], _setAutoCancelDrawDecs = [trace(['enable']), validateParams(booleanSchema)], _handleApplicationLaunchDecs = [bound, trace(['appId', 'app'])], _handleApplicationTerminalDecs = [bound, trace(['appId', 'app'])], _enableAutoCancelDecs = trace(['enable']), "logger")] = (_initProto(this), createLogger({
|
|
41
|
+
prefix: 'FcrBoardMainWindowImpl'
|
|
42
|
+
}));
|
|
43
|
+
_observable = new AgoraObservable();
|
|
44
|
+
_currentPage = 0;
|
|
45
|
+
_background = 'rgba(0, 0, 0, 0)';
|
|
46
|
+
_isAutoCancelEnabled = false;
|
|
47
|
+
constructor(whiteboard, boardRoom, appId) {
|
|
48
|
+
this._addLogObserver();
|
|
49
|
+
this._boardView = document.createElement('div');
|
|
50
|
+
this._boardView.classList.add('fcr-whiteboard-window-view');
|
|
51
|
+
this._boardView.appendChild(whiteboard.view);
|
|
52
|
+
this._boardView.style.height = `100%`;
|
|
53
|
+
this._boardView.style.width = `100%`;
|
|
54
|
+
this._boardView.setAttribute('data-app-id', appId);
|
|
55
|
+
this._whiteboard = whiteboard;
|
|
56
|
+
this._setBoardViewStyle(whiteboard.view);
|
|
57
|
+
this._addWindowManagerEventListeners();
|
|
58
|
+
boardRoom.applicationManager.on('launch', this._handleApplicationLaunch);
|
|
59
|
+
boardRoom.applicationManager.on('terminal', this._handleApplicationTerminal);
|
|
60
|
+
|
|
61
|
+
// @ts-ignore
|
|
62
|
+
this.logger.info(`initialized, room: ${boardRoom.roomId}`);
|
|
63
|
+
}
|
|
64
|
+
async addPage() {
|
|
65
|
+
this._whiteboard.addPage('next');
|
|
66
|
+
return FcrReturnCode.SUCCESS;
|
|
67
|
+
}
|
|
68
|
+
async removePage() {
|
|
69
|
+
this._whiteboard.deletePage('current');
|
|
70
|
+
return FcrReturnCode.SUCCESS;
|
|
71
|
+
}
|
|
72
|
+
async undo() {
|
|
73
|
+
this._whiteboard.undo();
|
|
74
|
+
return FcrReturnCode.SUCCESS;
|
|
75
|
+
}
|
|
76
|
+
async redo() {
|
|
77
|
+
this._whiteboard.redo();
|
|
78
|
+
return FcrReturnCode.SUCCESS;
|
|
79
|
+
}
|
|
80
|
+
async clean() {
|
|
81
|
+
this._whiteboard.clearPage();
|
|
82
|
+
return FcrReturnCode.SUCCESS;
|
|
83
|
+
}
|
|
84
|
+
async getSnapshotImage() {
|
|
85
|
+
if (this._whiteboard) {
|
|
86
|
+
//@ts-ignore
|
|
87
|
+
const base64 = await this._whiteboard.rasterizeElementsBounds(this._whiteboard.view.clientWidth, 2000 // 跟惠东商定的最大高度值
|
|
88
|
+
);
|
|
89
|
+
return new Promise((resolve, reject) => {
|
|
90
|
+
if (base64) {
|
|
91
|
+
const img = new Image();
|
|
92
|
+
img.src = base64;
|
|
93
|
+
img.onload = () => {
|
|
94
|
+
const canvas = document.createElement('canvas');
|
|
95
|
+
canvas.width = img.width;
|
|
96
|
+
canvas.height = img.height;
|
|
97
|
+
const ctx = canvas.getContext('2d');
|
|
98
|
+
ctx.fillStyle = '#ffffff'; // 产品确认使用白色作为导出的背景色
|
|
99
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
100
|
+
ctx.drawImage(img, 0, 0);
|
|
101
|
+
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
102
|
+
resolve(imageData);
|
|
103
|
+
};
|
|
104
|
+
} else {
|
|
105
|
+
reject(new Error('Failed to load image'));
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
} else {
|
|
109
|
+
throw new Error('Whiteboard is not initialized');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async setBackgroundColor(color) {
|
|
113
|
+
this._background = color;
|
|
114
|
+
this.logger.info(`set canvas background color: ${this._background}`);
|
|
115
|
+
this._whiteboard.setCanvasBackgroundColor(color);
|
|
116
|
+
return FcrReturnCode.SUCCESS;
|
|
117
|
+
}
|
|
118
|
+
getPageInfo() {
|
|
119
|
+
return {
|
|
120
|
+
showIndex: this._currentPage,
|
|
121
|
+
count: this._whiteboard.pageList().length || 0
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
async prevPage() {
|
|
125
|
+
this._whiteboard.indexedNavigation.prevPage();
|
|
126
|
+
return FcrReturnCode.SUCCESS;
|
|
127
|
+
}
|
|
128
|
+
async nextPage() {
|
|
129
|
+
this._whiteboard.indexedNavigation.nextPage();
|
|
130
|
+
return FcrReturnCode.SUCCESS;
|
|
131
|
+
}
|
|
132
|
+
async setToolType(type) {
|
|
133
|
+
if (this._whiteboard) {
|
|
134
|
+
const transType = convertToForgeBoardTool(type);
|
|
135
|
+
this._whiteboard.setCurrentTool(transType);
|
|
136
|
+
} else {
|
|
137
|
+
throw new Error('Whiteboard is not initialized');
|
|
138
|
+
}
|
|
139
|
+
return FcrReturnCode.SUCCESS;
|
|
140
|
+
}
|
|
141
|
+
async setStrokeWidth(strokeWidth) {
|
|
142
|
+
if (this._whiteboard) {
|
|
143
|
+
this._whiteboard.strokeWidth = strokeWidth;
|
|
144
|
+
} else {
|
|
145
|
+
throw new Error('Whiteboard is not initialized');
|
|
146
|
+
}
|
|
147
|
+
return FcrReturnCode.SUCCESS;
|
|
148
|
+
}
|
|
149
|
+
async setStrokeColor(color) {
|
|
150
|
+
const c = typeof color === 'string' ? color : `rgb(${color.r},${color.g},${color.b})`;
|
|
151
|
+
if (this._whiteboard) {
|
|
152
|
+
this._whiteboard.strokeColor = c;
|
|
153
|
+
} else {
|
|
154
|
+
throw new Error('Whiteboard is not initialized');
|
|
155
|
+
}
|
|
156
|
+
return FcrReturnCode.SUCCESS;
|
|
157
|
+
}
|
|
158
|
+
async setTextColor(color) {
|
|
159
|
+
const c = typeof color === 'string' ? color : `rgb(${color.r},${color.g},${color.b})`;
|
|
160
|
+
if (this._whiteboard) {
|
|
161
|
+
this._whiteboard.fillColor = c;
|
|
162
|
+
} else {
|
|
163
|
+
throw new Error('Whiteboard is not initialized');
|
|
164
|
+
}
|
|
165
|
+
return FcrReturnCode.SUCCESS;
|
|
166
|
+
}
|
|
167
|
+
async setTextSize(textSize) {
|
|
168
|
+
if (this._whiteboard) {
|
|
169
|
+
this._whiteboard.fontSize = textSize;
|
|
170
|
+
} else {
|
|
171
|
+
throw new Error('Whiteboard is not initialized');
|
|
172
|
+
}
|
|
173
|
+
return FcrReturnCode.SUCCESS;
|
|
174
|
+
}
|
|
175
|
+
async insertImage(resourceUrl, x, y, width, height) {}
|
|
176
|
+
getContentView() {
|
|
177
|
+
return this._boardView;
|
|
178
|
+
}
|
|
179
|
+
async setContainerSizeRatio(ratio) {}
|
|
180
|
+
async setBoardTransparent(isTransparent) {}
|
|
181
|
+
updateWindowSize(size) {
|
|
182
|
+
size && this._whiteboard.updateViewport(size.width, size.height);
|
|
183
|
+
return FcrReturnCode.SUCCESS;
|
|
184
|
+
}
|
|
185
|
+
setAutoCancelDraw(enable) {
|
|
186
|
+
this._isAutoCancelEnabled = enable;
|
|
187
|
+
this._enableAutoCancel(enable);
|
|
188
|
+
return FcrReturnCode.SUCCESS;
|
|
189
|
+
}
|
|
190
|
+
getWritable() {
|
|
191
|
+
return this._whiteboard.permissions.getPermissionFlags().some(flag => {
|
|
192
|
+
return flag === WhiteboardPermissionFlag.all;
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
addObserver(observer) {
|
|
196
|
+
this._observable.addObserver(observer);
|
|
197
|
+
}
|
|
198
|
+
removeObserver(observer) {
|
|
199
|
+
this._observable.removeObserver(observer);
|
|
200
|
+
}
|
|
201
|
+
_addWindowManagerEventListeners() {
|
|
202
|
+
const windowManager = this._whiteboard;
|
|
203
|
+
windowManager.indexedNavigation.on('activePageChange', showIndex => {
|
|
204
|
+
this._currentPage = showIndex;
|
|
205
|
+
const state = {
|
|
206
|
+
showIndex: showIndex,
|
|
207
|
+
count: windowManager.indexedNavigation.pageCount || 0
|
|
208
|
+
};
|
|
209
|
+
this._observable.notifyObservers('onPageInfoUpdated', state);
|
|
210
|
+
});
|
|
211
|
+
windowManager.indexedNavigation.on('pageCountChange', count => {
|
|
212
|
+
const state = {
|
|
213
|
+
showIndex: this._currentPage,
|
|
214
|
+
count
|
|
215
|
+
};
|
|
216
|
+
this._observable.notifyObservers('onPageInfoUpdated', state);
|
|
217
|
+
});
|
|
218
|
+
windowManager.on('undoStackLength', steps => {
|
|
219
|
+
this._observable.notifyObservers('onUndoStateUpdated', steps > 0);
|
|
220
|
+
});
|
|
221
|
+
windowManager.on('redoStackLength', steps => {
|
|
222
|
+
this._observable.notifyObservers('onRedoStateUpdated', steps > 0);
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
_handleApplicationLaunch(appId, app) {
|
|
226
|
+
this._whiteboard = app;
|
|
227
|
+
this._setBoardViewStyle(app.view);
|
|
228
|
+
if (this._background) {
|
|
229
|
+
this.logger.info(`set canvas background color: ${this._background}`);
|
|
230
|
+
this._whiteboard.setCanvasBackgroundColor(this._background);
|
|
231
|
+
}
|
|
232
|
+
this._enableAutoCancel(this._isAutoCancelEnabled);
|
|
233
|
+
if (this._boardView.hasChildNodes()) {
|
|
234
|
+
this.logger.warn('board view is not empty, clear board view before appending new view');
|
|
235
|
+
this._boardView.innerHTML = '';
|
|
236
|
+
}
|
|
237
|
+
this._boardView.setAttribute('data-app-id', appId);
|
|
238
|
+
this._boardView.appendChild(app.view);
|
|
239
|
+
return FcrReturnCode.SUCCESS;
|
|
240
|
+
}
|
|
241
|
+
_handleApplicationTerminal(appId, app) {
|
|
242
|
+
try {
|
|
243
|
+
if (this._boardView.contains(app.view)) {
|
|
244
|
+
this.logger.info(`remove application view: ${appId}`);
|
|
245
|
+
this._boardView.removeChild(app.view);
|
|
246
|
+
} else {
|
|
247
|
+
this.logger.warn(`application view not found in board view: ${appId}`);
|
|
248
|
+
}
|
|
249
|
+
} catch (e) {
|
|
250
|
+
this.logger.error(`failed to handle terminal: ${appId}`, e);
|
|
251
|
+
}
|
|
252
|
+
return FcrReturnCode.SUCCESS;
|
|
253
|
+
}
|
|
254
|
+
_setBoardViewStyle(view) {
|
|
255
|
+
view.style.height = `100%`;
|
|
256
|
+
view.style.width = `100%`;
|
|
257
|
+
view.style.backgroundColor = 'rgba(0, 0, 0, 0)';
|
|
258
|
+
}
|
|
259
|
+
_enableAutoCancel(enable) {
|
|
260
|
+
// @ts-ignore
|
|
261
|
+
this._whiteboard.__setMainCanvasVisible(!enable);
|
|
262
|
+
// @ts-ignore
|
|
263
|
+
this._whiteboard.__delayTranslateOut = enable ? 4000 : -1;
|
|
264
|
+
return FcrReturnCode.SUCCESS;
|
|
265
|
+
}
|
|
266
|
+
_addLogObserver() {
|
|
267
|
+
this.addObserver(generateLogObserver(this.logger, [['onWritable', ['isWritable']], ['onPageInfoUpdated', ['info']], ['onUndoStateUpdated', ['enable']], ['onRedoStateUpdated', ['enable']]]));
|
|
268
|
+
}
|
|
269
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// 此宽高为 HLD 中约定的白板尺寸
|
|
2
|
+
export const BOARD_VIEW_WIDTH = 1920;
|
|
3
|
+
export const BOARD_VIEW_HEIGHT = 1220;
|
|
4
|
+
export const INIT_CONFIG_FETCH_INTERVAL = 3000;
|
|
5
|
+
|
|
6
|
+
// 永久重试
|
|
7
|
+
export const BOARD_RETRY_MAX = 99999;
|
|
8
|
+
export const WHITEBOARD_APP_ID = 'MainWhiteboard';
|
|
9
|
+
export const ANNOTATION_APP_ID = 'Annotation';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export let FcrBoardShape = /*#__PURE__*/function (FcrBoardShape) {
|
|
2
|
+
FcrBoardShape[FcrBoardShape["Curve"] = 1] = "Curve";
|
|
3
|
+
FcrBoardShape[FcrBoardShape["Straight"] = 2] = "Straight";
|
|
4
|
+
FcrBoardShape[FcrBoardShape["Arrow"] = 3] = "Arrow";
|
|
5
|
+
FcrBoardShape[FcrBoardShape["Rectangle"] = 4] = "Rectangle";
|
|
6
|
+
FcrBoardShape[FcrBoardShape["Triangle"] = 5] = "Triangle";
|
|
7
|
+
FcrBoardShape[FcrBoardShape["Rhombus"] = 6] = "Rhombus";
|
|
8
|
+
FcrBoardShape[FcrBoardShape["Pentagram"] = 7] = "Pentagram";
|
|
9
|
+
FcrBoardShape[FcrBoardShape["Ellipse"] = 8] = "Ellipse";
|
|
10
|
+
return FcrBoardShape;
|
|
11
|
+
}({});
|
|
12
|
+
export let FcrBoardToolType = /*#__PURE__*/function (FcrBoardToolType) {
|
|
13
|
+
FcrBoardToolType[FcrBoardToolType["NONE"] = 0] = "NONE";
|
|
14
|
+
FcrBoardToolType[FcrBoardToolType["SELECTOR"] = 1] = "SELECTOR";
|
|
15
|
+
FcrBoardToolType[FcrBoardToolType["LASER_POINTER"] = 2] = "LASER_POINTER";
|
|
16
|
+
FcrBoardToolType[FcrBoardToolType["ERASER"] = 3] = "ERASER";
|
|
17
|
+
FcrBoardToolType[FcrBoardToolType["TEXT"] = 4] = "TEXT";
|
|
18
|
+
FcrBoardToolType[FcrBoardToolType["HAND"] = 5] = "HAND";
|
|
19
|
+
FcrBoardToolType[FcrBoardToolType["CURVE"] = 6] = "CURVE";
|
|
20
|
+
FcrBoardToolType[FcrBoardToolType["STRAIGHT"] = 7] = "STRAIGHT";
|
|
21
|
+
FcrBoardToolType[FcrBoardToolType["ARROW"] = 8] = "ARROW";
|
|
22
|
+
FcrBoardToolType[FcrBoardToolType["RECTANGLE"] = 9] = "RECTANGLE";
|
|
23
|
+
FcrBoardToolType[FcrBoardToolType["TRIANGLE"] = 10] = "TRIANGLE";
|
|
24
|
+
FcrBoardToolType[FcrBoardToolType["RHOMBUS"] = 11] = "RHOMBUS";
|
|
25
|
+
FcrBoardToolType[FcrBoardToolType["PENTAGRAM"] = 12] = "PENTAGRAM";
|
|
26
|
+
FcrBoardToolType[FcrBoardToolType["ELLIPSE"] = 13] = "ELLIPSE";
|
|
27
|
+
return FcrBoardToolType;
|
|
28
|
+
}({});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|