fcr-core 3.10.0-rc.1 → 3.10.0

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.
@@ -101,6 +101,12 @@ class FcrCoreEngineImpl {
101
101
  // @internal
102
102
 
103
103
  constructor(config) {
104
+ // 确保config是一个正确的FcrCoreEngineConfig实例,以
105
+ // 便即使调用者传递的是一个普通对象,也能始终应用_prependInternalParameters(rtc/rtm预设参数)。
106
+
107
+ if (!(config instanceof _.FcrCoreEngineConfig)) {
108
+ config = new _.FcrCoreEngineConfig(config);
109
+ }
104
110
  this._config = config;
105
111
  (0, _domainHolder.resetSharedDomainHolder)();
106
112
  const rteLogFileSize = (0, _parameters.getCoreLogFileSize)(config.parameters);
@@ -114,7 +114,7 @@ class FcrBaseRoomControlImpl {
114
114
  // TODO: 确认是否需要限制在主房间
115
115
  this._roomType === _type2.FcrRoomType.Mainroom || this._roomType === _type2.FcrRoomType.Infinityroom)) {
116
116
  this.logger.info('join scene success, start create sharing control');
117
- this.sharingControl = new _sharingControl.FcrSharingControlImpl(this._scene, this._api, this._engine, this._privilegeControl, this._streamControl, this._sharedCache, this._userControl);
117
+ this.sharingControl = new _sharingControl.FcrSharingControlImpl(this._scene, this._api, this._engine, this._config, this._privilegeControl, this._streamControl, this._sharedCache, this._userControl);
118
118
  }
119
119
  this._sttControl = new _sttControl.FcrSttControlImpl(this._scene, this._api, this._sharedCache);
120
120
  this._observable.notifyObservers('onJoinRoomSuccess', sceneId);
@@ -5,13 +5,14 @@ import { FcrScreenSharingState, FcrSharingControl, FcrSharingObserver, FcrWhiteb
5
5
  import { FcrPrivilegeControl } from '../privilege-control/type';
6
6
  import { FcrWhiteboardControl } from '../whiteboard-control-v2/whiteboard-control/type';
7
7
  import { FcrStreamInfo } from '../../type';
8
- import { FcrUserControl } from '../..';
8
+ import { FcrCoreEngineConfig, FcrUserControl } from '../..';
9
9
  import { FcrSharedCache } from '../shared-cache';
10
10
  import { FcrAnnotationControl } from '../whiteboard-control-v2/annotation-control/type';
11
11
  export declare class FcrSharingControlImpl implements FcrSharingControl {
12
12
  private _scene;
13
13
  private _api;
14
14
  private _engine;
15
+ private _config;
15
16
  private _privilegeControl;
16
17
  private _streamControl;
17
18
  private _sharedCache;
@@ -23,12 +24,14 @@ export declare class FcrSharingControlImpl implements FcrSharingControl {
23
24
  private _isActive;
24
25
  private _shareOwnerId;
25
26
  private _shareOwnerStream;
27
+ private _lastScreenSharingState;
28
+ private _lastScreenSharingStreamId;
26
29
  private _streamObserver;
27
30
  private _sceneObserver;
28
31
  private _whiteboardObserver;
29
32
  get ownerId(): string;
30
33
  get ownerStream(): FcrStreamInfo | null;
31
- constructor(_scene: AgoraRteScene, _api: FcrCoreServiceApi, _engine: AgoraRteEngine, _privilegeControl: FcrPrivilegeControl, _streamControl: FcrStreamControl, _sharedCache: FcrSharedCache, _userControl: FcrUserControl);
34
+ constructor(_scene: AgoraRteScene, _api: FcrCoreServiceApi, _engine: AgoraRteEngine, _config: FcrCoreEngineConfig, _privilegeControl: FcrPrivilegeControl, _streamControl: FcrStreamControl, _sharedCache: FcrSharedCache, _userControl: FcrUserControl);
32
35
  startScreenSharing(config: FcrScreenStreamCreateConfig, size?: FcrSize, labels?: Map<string, any>): Promise<string>;
33
36
  startWhiteboard(): Promise<void>;
34
37
  updateScreenSharing(enableAnnotation: boolean): Promise<void>;
@@ -49,5 +52,6 @@ export declare class FcrSharingControlImpl implements FcrSharingControl {
49
52
  private _handleOnWhiteboardActive;
50
53
  private _handleOnWhiteboardInActive;
51
54
  private _getScreenShareStreamByUuid;
55
+ private _notifyScreenSharingUpdated;
52
56
  private _addLogObserver;
53
57
  }
@@ -35,6 +35,8 @@ var _factory2 = require("../whiteboard-control-v2/annotation-control/factory");
35
35
  var _type3 = require("../type");
36
36
  var _type4 = require("../whiteboard-control/type");
37
37
  var _sceneProperties = require("../../utilities/scene-properties");
38
+ var _parameters = require("../../utilities/parameters");
39
+ var _sharedStorage = require("../../utilities/shared-storage");
38
40
  let _initProto, _startScreenSharingDecs, _updateScreenSharingDecs;
39
41
  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)]; } }; }
40
42
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
@@ -52,6 +54,8 @@ class FcrSharingControlImpl {
52
54
  _isActive = false;
53
55
  _shareOwnerId = '';
54
56
  _shareOwnerStream = null;
57
+ _lastScreenSharingState = _type.FcrScreenSharingState.END;
58
+ _lastScreenSharingStreamId = null;
55
59
  _streamObserver = {
56
60
  onStreamsAdded: this._handleOnStreamsAdded.bind(this),
57
61
  onStreamsRemoved: this._handleOnStreamsRemoved.bind(this)
@@ -71,10 +75,11 @@ class FcrSharingControlImpl {
71
75
  get ownerStream() {
72
76
  return this._shareOwnerStream;
73
77
  }
74
- constructor(_scene, _api, _engine, _privilegeControl, _streamControl, _sharedCache, _userControl) {
78
+ constructor(_scene, _api, _engine, _config, _privilegeControl, _streamControl, _sharedCache, _userControl) {
75
79
  this._scene = _scene;
76
80
  this._api = _api;
77
81
  this._engine = _engine;
82
+ this._config = _config;
78
83
  this._privilegeControl = _privilegeControl;
79
84
  this._streamControl = _streamControl;
80
85
  this._sharedCache = _sharedCache;
@@ -86,6 +91,12 @@ class FcrSharingControlImpl {
86
91
  this._streamControl.addObserver(this._streamObserver);
87
92
  this._whiteboardControl.addObserver(this._whiteboardObserver);
88
93
  this._scene.addObserver(this._sceneObserver);
94
+ (0, _sharedStorage.clearBoardIpList)();
95
+ const boardIpList = (0, _parameters.getScribbleForgeIpList)(this._config.parameters);
96
+ if (boardIpList) {
97
+ this.logger.info('set board ip list to storage ', boardIpList);
98
+ (0, _sharedStorage.setBoardIpList)(boardIpList);
99
+ }
89
100
  this.logger.info(`initialized, room id: ${this._scene.sceneId}`);
90
101
  }
91
102
  async startScreenSharing(config, size, labels) {
@@ -157,6 +168,7 @@ class FcrSharingControlImpl {
157
168
  userName,
158
169
  roomId: this._scene.sceneId,
159
170
  boardRatio: 1,
171
+ ipList: (0, _parameters.getScribbleForgeIpList)(this._config.parameters),
160
172
  size: {
161
173
  width: 1280,
162
174
  height: 720
@@ -203,7 +215,8 @@ class FcrSharingControlImpl {
203
215
  userId,
204
216
  userName,
205
217
  roomId: this._scene.sceneId,
206
- boardRatio: 0
218
+ boardRatio: 0,
219
+ ipList: (0, _parameters.getScribbleForgeIpList)(this._config.parameters)
207
220
  };
208
221
  this._whiteboardControl = factory.createForMainProcess(
209
222
  // @ts-ignore
@@ -237,7 +250,7 @@ class FcrSharingControlImpl {
237
250
  if (this._isStreamToHandleScreenSharing(modifiedStream)) {
238
251
  this._shareOwnerId = modifiedStream.owner.userId;
239
252
  this._shareOwnerStream = modifiedStream;
240
- this._observable.notifyObservers('onScreenSharingUpdated', modifiedStream, _type.FcrScreenSharingState.START_ONLY_SCREEN);
253
+ this._notifyScreenSharingUpdated('onScreenSharingUpdated', modifiedStream, this.getScreenSharingState());
241
254
  }
242
255
  });
243
256
  }
@@ -248,7 +261,7 @@ class FcrSharingControlImpl {
248
261
  } = event;
249
262
  const ownerId = modifiedStream.owner.userId;
250
263
  if (this._isStreamToHandleScreenSharing(modifiedStream)) {
251
- this._observable.notifyObservers('onScreenSharingUpdated', modifiedStream, _type.FcrScreenSharingState.END);
264
+ this._notifyScreenSharingUpdated('onScreenSharingUpdated', modifiedStream, _type.FcrScreenSharingState.END);
252
265
  if (this.getScreenSharingState() === _type.FcrScreenSharingState.END) {
253
266
  const isMeSharing = ownerId === this._userControl.getLocalUser().userId;
254
267
  if (isMeSharing) {
@@ -266,43 +279,42 @@ class FcrSharingControlImpl {
266
279
  const causeData = cause?.data;
267
280
  const currentScreenSharingState = this.getScreenSharingState();
268
281
  const causeCmd = cause?.cmd;
282
+ const isWidgetPropertiesUpdated = causeCmd === 10;
283
+ const isAnnotationWidgetUpdated = causeData?.widgetUuid === _type3.FcrWidgetUuid.ANNOTATION;
284
+ const isAnnotationStateUpdated = causeData?.widgetCause?.cmd === _type3.FcrWidgetCauseCmd.ANNOTATION;
285
+ if (!isWidgetPropertiesUpdated || !isAnnotationWidgetUpdated) {
286
+ return;
287
+ }
269
288
  if (currentScreenSharingState === _type.FcrScreenSharingState.END) {
270
- if (causeData && causeCmd === 10 && causeData.widgetUuid === _type3.FcrWidgetUuid.ANNOTATION) {
271
- if (causeData.widgetCause?.cmd === _type3.FcrWidgetCauseCmd.ANNOTATION) {
272
- this._observable.notifyObservers('onScreenSharingUpdated', this.ownerStream, _type.FcrScreenSharingState.END);
273
- const isMeSharing = this.ownerId === this._userControl.getLocalUser().userId;
274
- if (isMeSharing) {
275
- this.logger.info('clean annotation board');
276
- this._annotationControl.getMainWindow()?.clean();
277
- }
289
+ if (causeData.widgetCause?.cmd === _type3.FcrWidgetCauseCmd.ANNOTATION) {
290
+ this._notifyScreenSharingUpdated('onScreenSharingUpdated', this.ownerStream, _type.FcrScreenSharingState.END);
291
+ const isMeSharing = this.ownerId === this._userControl.getLocalUser().userId;
292
+ if (isMeSharing) {
293
+ this.logger.info('clean annotation board');
294
+ this._annotationControl.getMainWindow()?.clean();
278
295
  }
279
296
  }
280
297
  } else {
281
- // 当屏幕共享开启时
282
- if (causeData && causeCmd === 10 && causeData.widgetUuid === _type3.FcrWidgetUuid.ANNOTATION) {
283
- if (causeData.widgetCause?.cmd === _type3.FcrWidgetCauseCmd.ANNOTATION) {
284
- const screenStream = this._getScreenShareStreamByUuid();
285
- this._observable.notifyObservers('onScreenSharingUpdated', screenStream ?? this.ownerStream, _type.FcrScreenSharingState.START_WHIT_ANNOTATION);
286
- // const owner = this._userControl.getUser(this.ownerId);
287
- // const isElectron =
288
- // owner &&
289
- // [FcrPlatform.WEB_DESKTOP, FcrPlatform.MACOS, FcrPlatform.WINDOWS].includes(
290
- // owner.platform,
291
- // );
292
- // const mainWindow = this._annotationControl?.getMainWindow();
293
- // const isAndroid = owner && owner.platform === FcrPlatform.ANDROID;
294
- // if (isElectron && mainWindow) {
295
- // mainWindow.setAutoCancelDraw(false);
296
- // }
297
- // if (isAndroid && mainWindow) {
298
- // const isNotMeSharing = this.ownerId !== this._userControl.getLocalUser().userId;
299
- // mainWindow.setAutoCancelDraw(isNotMeSharing);
300
- // }
301
- } else {
302
- if (causeData.reason === 1) {
303
- this._observable.notifyObservers('onScreenSharingUpdated', this.ownerStream, _type.FcrScreenSharingState.END);
304
- }
305
- }
298
+ if (isAnnotationStateUpdated) {
299
+ const screenStream = this._getScreenShareStreamByUuid();
300
+ this._notifyScreenSharingUpdated('onScreenSharingUpdated', screenStream ?? this.ownerStream, _type.FcrScreenSharingState.START_WHIT_ANNOTATION);
301
+ // const owner = this._userControl.getUser(this.ownerId);
302
+ // const isElectron =
303
+ // owner &&
304
+ // [FcrPlatform.WEB_DESKTOP, FcrPlatform.MACOS, FcrPlatform.WINDOWS].includes(
305
+ // owner.platform,
306
+ // );
307
+ // const mainWindow = this._annotationControl?.getMainWindow();
308
+ // const isAndroid = owner && owner.platform === FcrPlatform.ANDROID;
309
+ // if (isElectron && mainWindow) {
310
+ // mainWindow.setAutoCancelDraw(false);
311
+ // }
312
+ // if (isAndroid && mainWindow) {
313
+ // const isNotMeSharing = this.ownerId !== this._userControl.getLocalUser().userId;
314
+ // mainWindow.setAutoCancelDraw(isNotMeSharing);
315
+ // }
316
+ } else if (causeData.reason === 1) {
317
+ this._notifyScreenSharingUpdated('onScreenSharingUpdated', this.ownerStream, _type.FcrScreenSharingState.END);
306
318
  }
307
319
  }
308
320
  }
@@ -325,6 +337,15 @@ class FcrSharingControlImpl {
325
337
  const stream = this._streamControl.getStreamByStreamId(screenStreamUuid);
326
338
  return typeof stream === 'undefined' ? null : stream;
327
339
  }
340
+ _notifyScreenSharingUpdated(eventName, streamInfo, state) {
341
+ const streamId = streamInfo?.streamId ?? null;
342
+ if (this._lastScreenSharingState === state && this._lastScreenSharingStreamId === streamId) {
343
+ return;
344
+ }
345
+ this._lastScreenSharingState = state;
346
+ this._lastScreenSharingStreamId = state === _type.FcrScreenSharingState.END ? null : streamId;
347
+ this._observable.notifyObservers(eventName, streamInfo, state);
348
+ }
328
349
  _addLogObserver() {
329
350
  this.addObserver((0, _logger.generateLogObserver)(this.logger, [['onScreenSharingUpdated', ['streamInfo', 'state']], ['onWhiteboardStarted', ['ownerId', 'operatorUser']], ['onWhiteboardEnded', ['reason', 'operatorUser']]]));
330
351
  }
@@ -170,14 +170,15 @@ class FcrBaseWhiteboardControlImpl {
170
170
  });
171
171
  const {
172
172
  userId,
173
- userName
173
+ userName,
174
+ ipList
174
175
  } = this.config;
175
176
  const {
176
177
  boardAppId,
177
178
  boardId,
178
179
  boardRegion,
179
- boardToken,
180
- boardPerformance = false
180
+ boardToken
181
+ // boardPerformance = false,
181
182
  } = this.boardRoomConfig || {};
182
183
  if (!boardAppId) {
183
184
  throw (0, _error.generateFcrCoreClientError)(_imports.ErrorModuleCode.FCR_ROOM_WHITEBOARD, _imports.DetailErrorCode.UNDEFINED_ERROR, 'boardAppId is required');
@@ -200,6 +201,15 @@ class FcrBaseWhiteboardControlImpl {
200
201
  whiteboardOption.height = 600;
201
202
  }
202
203
  this.logger.info(`open board with boardId: ${boardId}, boardToken: ${boardToken}, region: ${boardRegion}, appIdentifier: ${boardAppId} whiteboardOption: ${(0, _imports.jsonstring)(whiteboardOption)}`);
204
+ let endpoint = undefined;
205
+ if (ipList !== undefined) {
206
+ if (Array.isArray(ipList) && ipList[0]) {
207
+ this.logger.info(`use ipList from config: ${(0, _imports.jsonstring)(ipList)}`);
208
+ endpoint = ipList[0];
209
+ } else {
210
+ this.logger.error(`ipList in config is empty or invalid: ${(0, _imports.jsonstring)(ipList)}, ignore ipList config`);
211
+ }
212
+ }
203
213
  const rtmProvider = new _forgeRtm.RTMProvider_2_2(this.rtmClient);
204
214
  const wbRoom = new _forgeRoom.Room(boardId, rtmProvider);
205
215
  this.logger.info('ApplicationManager.registerApplication calling');
@@ -237,9 +247,10 @@ class FcrBaseWhiteboardControlImpl {
237
247
  nickName: userName || userId,
238
248
  roomToken: boardToken,
239
249
  sdkConfig: {
240
- region: boardRegion,
250
+ region: endpoint ? 'private' : boardRegion,
241
251
  appIdentifier: boardAppId
242
252
  },
253
+ endpoint,
243
254
  writable: true
244
255
  // verboseLog: true,
245
256
  };
@@ -292,7 +303,8 @@ class FcrBaseWhiteboardControlImpl {
292
303
  // boardView.internalSetWritable(false);
293
304
  // }
294
305
 
295
- boardView.setPerformanceMode(boardPerformance);
306
+ // boardView.setPerformanceMode(boardPerformance);
307
+
296
308
  this.updateConnectionState(_type.FcrConnectionState.CONNECTED);
297
309
  resolve(boardView);
298
310
  if (this._waitPromiseResolve) {
@@ -28,12 +28,6 @@ export declare class FcrBoardMainWindowImpl implements FcrBoardMainWindow {
28
28
  redo(): Promise<FcrReturnCode>;
29
29
  clean(): Promise<FcrReturnCode>;
30
30
  getSnapshotImage(): Promise<ImageData>;
31
- /**
32
- * 设置性能模式状态, enabled 为 true 时开启性能模式, 否则关闭性能模式
33
- * 性能模式下, 白板会降低渲染质量及同步频率以提升性能, 适用于低性能设备或需要大量绘制元素的场景
34
- * @param enable 是否开启性能模式
35
- */
36
- setPerformanceMode(enable: boolean): FcrReturnCode;
37
31
  setBackgroundColor(color: string): Promise<FcrReturnCode>;
38
32
  getPageInfo(): FcrBoardPageInfo;
39
33
  prevPage(): Promise<FcrReturnCode>;
@@ -33,7 +33,7 @@ var _decorator = require("agora-foundation/lib/decorator");
33
33
  var _type = require("../../../type");
34
34
  var _error = require("../../../utilities/error");
35
35
  var _imports = require("../../../imports");
36
- let _initProto, _setPerformanceModeDecs, _setBackgroundColorDecs, _setToolTypeDecs, _setStrokeWidthDecs, _setStrokeColorDecs, _setTextColorDecs, _setTextSizeDecs, _insertImageDecs, _setContainerSizeRatioDecs, _setBoardTransparentDecs, _updateWindowSizeDecs, _setAutoCancelDrawDecs, _handleApplicationLaunchDecs, _handleApplicationTerminalDecs, _enableAutoCancelDecs;
36
+ let _initProto, _setBackgroundColorDecs, _setToolTypeDecs, _setStrokeWidthDecs, _setStrokeColorDecs, _setTextColorDecs, _setTextSizeDecs, _insertImageDecs, _setContainerSizeRatioDecs, _setBoardTransparentDecs, _updateWindowSizeDecs, _setAutoCancelDrawDecs, _handleApplicationLaunchDecs, _handleApplicationTerminalDecs, _enableAutoCancelDecs;
37
37
  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)]; } }; }
38
38
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
39
39
  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); }
@@ -41,9 +41,9 @@ function _setFunctionName(e, t, n) { "symbol" == typeof t && (t = (t = t.descrip
41
41
  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; }
42
42
  class FcrBoardMainWindowImpl {
43
43
  static {
44
- [_initProto] = _applyDecs(this, [[_log.trace, 2, "addPage"], [_log.trace, 2, "removePage"], [_log.trace, 2, "undo"], [_log.trace, 2, "redo"], [_log.trace, 2, "clean"], [_log.trace, 2, "getSnapshotImage"], [_setPerformanceModeDecs, 2, "setPerformanceMode"], [_setBackgroundColorDecs, 2, "setBackgroundColor"], [_log.trace, 2, "getPageInfo"], [_log.trace, 2, "prevPage"], [_log.trace, 2, "nextPage"], [_setToolTypeDecs, 2, "setToolType"], [_setStrokeWidthDecs, 2, "setStrokeWidth"], [_setStrokeColorDecs, 2, "setStrokeColor"], [_setTextColorDecs, 2, "setTextColor"], [_setTextSizeDecs, 2, "setTextSize"], [_insertImageDecs, 2, "insertImage"], [_log.trace, 2, "getContentView"], [_setContainerSizeRatioDecs, 2, "setContainerSizeRatio"], [_setBoardTransparentDecs, 2, "setBoardTransparent"], [_updateWindowSizeDecs, 2, "updateWindowSize"], [_setAutoCancelDrawDecs, 2, "setAutoCancelDraw"], [_log.trace, 2, "getWritable"], [_handleApplicationLaunchDecs, 2, "_handleApplicationLaunch"], [_handleApplicationTerminalDecs, 2, "_handleApplicationTerminal"], [_enableAutoCancelDecs, 2, "_enableAutoCancel"]], []).e;
44
+ [_initProto] = _applyDecs(this, [[_log.trace, 2, "addPage"], [_log.trace, 2, "removePage"], [_log.trace, 2, "undo"], [_log.trace, 2, "redo"], [_log.trace, 2, "clean"], [_log.trace, 2, "getSnapshotImage"], [_setBackgroundColorDecs, 2, "setBackgroundColor"], [_log.trace, 2, "getPageInfo"], [_log.trace, 2, "prevPage"], [_log.trace, 2, "nextPage"], [_setToolTypeDecs, 2, "setToolType"], [_setStrokeWidthDecs, 2, "setStrokeWidth"], [_setStrokeColorDecs, 2, "setStrokeColor"], [_setTextColorDecs, 2, "setTextColor"], [_setTextSizeDecs, 2, "setTextSize"], [_insertImageDecs, 2, "insertImage"], [_log.trace, 2, "getContentView"], [_setContainerSizeRatioDecs, 2, "setContainerSizeRatio"], [_setBoardTransparentDecs, 2, "setBoardTransparent"], [_updateWindowSizeDecs, 2, "updateWindowSize"], [_setAutoCancelDrawDecs, 2, "setAutoCancelDraw"], [_log.trace, 2, "getWritable"], [_handleApplicationLaunchDecs, 2, "_handleApplicationLaunch"], [_handleApplicationTerminalDecs, 2, "_handleApplicationTerminal"], [_enableAutoCancelDecs, 2, "_enableAutoCancel"]], []).e;
45
45
  }
46
- [(_setPerformanceModeDecs = (0, _log.trace)(['enable']), _setBackgroundColorDecs = [(0, _log.trace)(['color']), (0, _validateParams.default)(_schema.stringSchema)], _setToolTypeDecs = [(0, _log.trace)(['type']), (0, _validateParams.default)(_schema2.fcrBoardToolTypeSchema)], _setStrokeWidthDecs = [(0, _log.trace)(['strokeWidth']), (0, _validateParams.default)(_schema2.numberSchema)], _setStrokeColorDecs = [(0, _log.trace)(['color']), (0, _validateParams.default)(_schema2.z.union([_schema2.colorSchema, _schema.stringSchema]))], _setTextColorDecs = [(0, _log.trace)(['color']), (0, _validateParams.default)(_schema2.colorSchema)], _setTextSizeDecs = [(0, _log.trace)(['textSize']), (0, _validateParams.default)(_schema2.numberSchema)], _insertImageDecs = [(0, _log.trace)(['resourceUrl', 'x', 'y', 'width', 'height']), (0, _validateParams.default)(_schema.stringSchema, _schema2.numberSchema, _schema2.numberSchema, _schema2.numberSchema, _schema2.numberSchema)], _setContainerSizeRatioDecs = [(0, _log.trace)(['ratio']), (0, _validateParams.default)(_schema2.numberSchema)], _setBoardTransparentDecs = [(0, _log.trace)(['isTransparent']), (0, _validateParams.default)(_schema2.booleanSchema)], _updateWindowSizeDecs = [(0, _log.trace)(['size']), (0, _validateParams.default)(_schema2.fcrSizeSchema)], _setAutoCancelDrawDecs = [(0, _log.trace)(['enable']), (0, _validateParams.default)(_schema2.booleanSchema)], _handleApplicationLaunchDecs = [_decorator.bound, (0, _log.trace)(['appId', 'app'])], _handleApplicationTerminalDecs = [_decorator.bound, (0, _log.trace)(['appId', 'app'])], _enableAutoCancelDecs = (0, _log.trace)(['enable']), "logger")] = (_initProto(this), (0, _logger.createLogger)({
46
+ [(_setBackgroundColorDecs = [(0, _log.trace)(['color']), (0, _validateParams.default)(_schema.stringSchema)], _setToolTypeDecs = [(0, _log.trace)(['type']), (0, _validateParams.default)(_schema2.fcrBoardToolTypeSchema)], _setStrokeWidthDecs = [(0, _log.trace)(['strokeWidth']), (0, _validateParams.default)(_schema2.numberSchema)], _setStrokeColorDecs = [(0, _log.trace)(['color']), (0, _validateParams.default)(_schema2.z.union([_schema2.colorSchema, _schema.stringSchema]))], _setTextColorDecs = [(0, _log.trace)(['color']), (0, _validateParams.default)(_schema2.colorSchema)], _setTextSizeDecs = [(0, _log.trace)(['textSize']), (0, _validateParams.default)(_schema2.numberSchema)], _insertImageDecs = [(0, _log.trace)(['resourceUrl', 'x', 'y', 'width', 'height']), (0, _validateParams.default)(_schema.stringSchema, _schema2.numberSchema, _schema2.numberSchema, _schema2.numberSchema, _schema2.numberSchema)], _setContainerSizeRatioDecs = [(0, _log.trace)(['ratio']), (0, _validateParams.default)(_schema2.numberSchema)], _setBoardTransparentDecs = [(0, _log.trace)(['isTransparent']), (0, _validateParams.default)(_schema2.booleanSchema)], _updateWindowSizeDecs = [(0, _log.trace)(['size']), (0, _validateParams.default)(_schema2.fcrSizeSchema)], _setAutoCancelDrawDecs = [(0, _log.trace)(['enable']), (0, _validateParams.default)(_schema2.booleanSchema)], _handleApplicationLaunchDecs = [_decorator.bound, (0, _log.trace)(['appId', 'app'])], _handleApplicationTerminalDecs = [_decorator.bound, (0, _log.trace)(['appId', 'app'])], _enableAutoCancelDecs = (0, _log.trace)(['enable']), "logger")] = (_initProto(this), (0, _logger.createLogger)({
47
47
  prefix: 'FcrBoardMainWindowImpl'
48
48
  }));
49
49
  _observable = new _observable.AgoraObservable();
@@ -143,16 +143,6 @@ class FcrBoardMainWindowImpl {
143
143
  throw new Error('Whiteboard is not initialized');
144
144
  }
145
145
  }
146
-
147
- /**
148
- * 设置性能模式状态, enabled 为 true 时开启性能模式, 否则关闭性能模式
149
- * 性能模式下, 白板会降低渲染质量及同步频率以提升性能, 适用于低性能设备或需要大量绘制元素的场景
150
- * @param enable 是否开启性能模式
151
- */
152
- setPerformanceMode(enable) {
153
- this._whiteboard.setPerformanceMode(enable);
154
- return _type.FcrReturnCode.SUCCESS;
155
- }
156
146
  async setBackgroundColor(color) {
157
147
  this._background = color;
158
148
  this.logger.info(`set canvas background color: ${this._background}`);
@@ -110,11 +110,6 @@ export interface FcrBoardMainWindow {
110
110
  * @param textSize
111
111
  */
112
112
  setTextSize(textSize: number): Promise<number>;
113
- /**
114
- * Sets the performance mode of the whiteboard.
115
- * @param enable Whether to enable performance mode.
116
- */
117
- setPerformanceMode(enable: boolean): number;
118
113
  /**
119
114
  * Sets the background color of the whiteboard.
120
115
  * @param color
@@ -155,20 +155,30 @@ class FcrWhiteboardControlImpl extends _base.FcrBaseWhiteboardControlImpl {
155
155
  const operatorUser = (0, _user.convertRteUserToFcrUser)(event.operatorUser, this._roomCache);
156
156
  const getByKeyPath = value => this._scene.getScenePropertiesByKeyPath(value);
157
157
  if (event.cause && event.cause.cmd === 10) {
158
+ const causeData = event.cause.data;
159
+ if (causeData?.widgetUuid && causeData.widgetUuid !== 'netlessBoard') {
160
+ return;
161
+ }
158
162
  const state = getByKeyPath('widgets.netlessBoard.state') ?? _type3.FcrBoardPropertiesState.INACTIVE;
159
163
  const backgroundColor = getByKeyPath('widgets.netlessBoard.extra.backgroundColor');
160
164
  const widgetCauseReason = (0, _imports.get)(event.cause.data, 'widgetCause.data.reason');
161
165
  const widgetCauseCmd = (0, _imports.get)(event.cause.data, 'widgetCause.cmd');
162
166
  if (state === _type3.FcrBoardPropertiesState.ACTIVE) {
163
167
  const ownerUserId = getByKeyPath('widgets.netlessBoard.ownerUserUuid');
168
+ const shouldNotify = !this._isActive || this._ownerId !== ownerUserId;
164
169
  this._ownerId = ownerUserId;
165
170
  this._isActive = true;
166
- this.observable.notifyObservers('onActive', ownerUserId, operatorUser);
171
+ if (shouldNotify) {
172
+ this.observable.notifyObservers('onActive', ownerUserId, operatorUser);
173
+ }
167
174
  }
168
175
  if (state === _type3.FcrBoardPropertiesState.INACTIVE) {
176
+ const shouldNotify = this._isActive || this._ownerId !== null;
169
177
  this._ownerId = null;
170
178
  this._isActive = false;
171
- this.observable.notifyObservers('onInactive', widgetCauseReason, operatorUser);
179
+ if (shouldNotify) {
180
+ this.observable.notifyObservers('onInactive', widgetCauseReason, operatorUser);
181
+ }
172
182
  }
173
183
  if (widgetCauseCmd === _type3.FcrBoardPropertiesState.BACKGROUND_COLOR_UPDATED) {
174
184
  this._backgroundColor = backgroundColor;
@@ -40,6 +40,7 @@ export type FcrBoardConfig = {
40
40
  userName: string;
41
41
  boardRatio: number;
42
42
  roomId: string;
43
+ ipList?: string[];
43
44
  };
44
45
  export type FcrBoardConfigForPrivilege = Pick<FcrBoardConfig, 'userId' | 'userName'>;
45
46
  export interface FcrWhiteboardControlFactory {
@@ -5,6 +5,7 @@ type FcrCoreEngineParameters = {
5
5
  export declare const getCoreIpList: (parameters?: FcrCoreEngineParameters) => string[];
6
6
  export declare const getEasemobChatIpList: (parameters?: FcrCoreEngineParameters) => string[];
7
7
  export declare const getEasemobRestIpList: (parameters?: FcrCoreEngineParameters) => string[];
8
+ export declare const getScribbleForgeIpList: (parameters?: FcrCoreEngineParameters) => string[];
8
9
  export declare const isEndpointRegionDisabled: (parameters?: FcrCoreEngineParameters) => boolean;
9
10
  export declare const getNeedLogUpload: (parameters?: FcrCoreEngineParameters) => boolean;
10
11
  export declare const getCoreLogFileSize: (parameters?: FcrCoreEngineParameters) => number;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.isTrueValue = exports.isEndpointRegionDisabled = exports.getRtcPresetParameters = exports.getNetlessLogFileSize = exports.getNeedLogUpload = exports.getEasemobRestIpList = exports.getEasemobLogFileSize = exports.getEasemobChatIpList = exports.getCoreLogFileSize = exports.getCoreIpList = void 0;
6
+ exports.isTrueValue = exports.isEndpointRegionDisabled = exports.getScribbleForgeIpList = exports.getRtcPresetParameters = exports.getNetlessLogFileSize = exports.getNeedLogUpload = exports.getEasemobRestIpList = exports.getEasemobLogFileSize = exports.getEasemobChatIpList = exports.getCoreLogFileSize = exports.getCoreIpList = void 0;
7
7
  require("core-js/modules/es.json.stringify.js");
8
8
  require("core-js/modules/esnext.set.add-all.js");
9
9
  require("core-js/modules/esnext.set.delete-all.js");
@@ -124,6 +124,10 @@ const getEasemobRestIpList = parameters => {
124
124
  return parameters?.core?.easemobRestIpList;
125
125
  };
126
126
  exports.getEasemobRestIpList = getEasemobRestIpList;
127
+ const getScribbleForgeIpList = parameters => {
128
+ return parameters?.core?.scribbleForgeIpList;
129
+ };
130
+ exports.getScribbleForgeIpList = getScribbleForgeIpList;
127
131
  const isEndpointRegionDisabled = parameters => {
128
132
  return isTrueValue(parameters?.core?.disableEndpointRegion);
129
133
  };
@@ -5,3 +5,6 @@ export declare const clearAnnotationBoardOptions: () => void;
5
5
  export declare const setWhiteboardOptions: (options: FcrBoardRoomConfig) => void;
6
6
  export declare const getWhiteboardOptions: () => FcrBoardRoomConfig | null;
7
7
  export declare const clearWhiteboardOptions: () => void;
8
+ export declare const setBoardIpList: (ipList: string[]) => void;
9
+ export declare const getBoardIpList: () => string[] | undefined;
10
+ export declare const clearBoardIpList: () => void;
@@ -3,12 +3,13 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.setWhiteboardOptions = exports.setAnnotationBoardOptions = exports.getWhiteboardOptions = exports.getAnnotationBoardOptions = exports.clearWhiteboardOptions = exports.clearAnnotationBoardOptions = void 0;
6
+ exports.setWhiteboardOptions = exports.setBoardIpList = exports.setAnnotationBoardOptions = exports.getWhiteboardOptions = exports.getBoardIpList = exports.getAnnotationBoardOptions = exports.clearWhiteboardOptions = exports.clearBoardIpList = exports.clearAnnotationBoardOptions = void 0;
7
7
  require("core-js/modules/es.json.stringify.js");
8
8
  require("core-js/modules/esnext.json.parse.js");
9
9
  var _imports = require("../imports");
10
10
  const STORAGE_KEY_ANNOTATION_BOARD_OPTIONS = 'annotation_board_options';
11
11
  const STORAGE_KEY_WHITEBOARD_OPTIONS = 'whiteboard_options';
12
+ const STORAGE_KEY_BOARD_IP_LIST = 'board_ip_list';
12
13
  const setAnnotationBoardOptions = options => {
13
14
  _imports.localStorage.setItem(STORAGE_KEY_ANNOTATION_BOARD_OPTIONS, JSON.stringify(options));
14
15
  };
@@ -40,4 +41,20 @@ exports.getWhiteboardOptions = getWhiteboardOptions;
40
41
  const clearWhiteboardOptions = () => {
41
42
  _imports.localStorage.removeItem(STORAGE_KEY_WHITEBOARD_OPTIONS);
42
43
  };
43
- exports.clearWhiteboardOptions = clearWhiteboardOptions;
44
+ exports.clearWhiteboardOptions = clearWhiteboardOptions;
45
+ const setBoardIpList = ipList => {
46
+ _imports.localStorage.setItem(STORAGE_KEY_BOARD_IP_LIST, JSON.stringify(ipList));
47
+ };
48
+ exports.setBoardIpList = setBoardIpList;
49
+ const getBoardIpList = () => {
50
+ const ipListStr = _imports.localStorage.getItem(STORAGE_KEY_BOARD_IP_LIST);
51
+ if (ipListStr) {
52
+ return JSON.parse(ipListStr);
53
+ }
54
+ return undefined;
55
+ };
56
+ exports.getBoardIpList = getBoardIpList;
57
+ const clearBoardIpList = () => {
58
+ _imports.localStorage.removeItem(STORAGE_KEY_BOARD_IP_LIST);
59
+ };
60
+ exports.clearBoardIpList = clearBoardIpList;
@@ -36,7 +36,7 @@ import { AgoraRtcRegion } from 'agora-rte-sdk/lib/core/rtc/type';
36
36
  import { AgoraRtmRegion } from 'agora-rte-sdk/lib/core/rtm/type';
37
37
  import { getSharedDomainHolder, resetSharedDomainHolder } from 'agora-rte-sdk/lib/core/services/domain-holder';
38
38
  import to from 'await-to-js';
39
- import { FcrConnectionState } from '..';
39
+ import { FcrConnectionState, FcrCoreEngineConfig } from '..';
40
40
  import { FcrDesktopMediaControlImpl } from '../media-control/desktop';
41
41
  import { FcrMobileMediaControlImpl } from '../media-control/mobile';
42
42
  import { FcrMonitorControlImpl } from '../monitor-control';
@@ -94,6 +94,12 @@ export class FcrCoreEngineImpl {
94
94
  // @internal
95
95
 
96
96
  constructor(config) {
97
+ // 确保config是一个正确的FcrCoreEngineConfig实例,以
98
+ // 便即使调用者传递的是一个普通对象,也能始终应用_prependInternalParameters(rtc/rtm预设参数)。
99
+
100
+ if (!(config instanceof FcrCoreEngineConfig)) {
101
+ config = new FcrCoreEngineConfig(config);
102
+ }
97
103
  this._config = config;
98
104
  resetSharedDomainHolder();
99
105
  const rteLogFileSize = getCoreLogFileSize(config.parameters);
@@ -117,7 +117,7 @@ export class FcrBaseRoomControlImpl {
117
117
  // TODO: 确认是否需要限制在主房间
118
118
  this._roomType === FcrRoomType.Mainroom || this._roomType === FcrRoomType.Infinityroom)) {
119
119
  this.logger.info('join scene success, start create sharing control');
120
- this.sharingControl = new FcrSharingControlImpl(this._scene, this._api, this._engine, this._privilegeControl, this._streamControl, this._sharedCache, this._userControl);
120
+ this.sharingControl = new FcrSharingControlImpl(this._scene, this._api, this._engine, this._config, this._privilegeControl, this._streamControl, this._sharedCache, this._userControl);
121
121
  }
122
122
  this._sttControl = new FcrSttControlImpl(this._scene, this._api, this._sharedCache);
123
123
  this._observable.notifyObservers('onJoinRoomSuccess', sceneId);
@@ -36,6 +36,8 @@ import { FcrAnnotationControlFactoryImpl } from '../whiteboard-control-v2/annota
36
36
  import { FcrWidgetCauseCmd, FcrWidgetUuid } from '../type';
37
37
  import { FcrBoardPropertiesState } from '../whiteboard-control/type';
38
38
  import { getBoardPerformance } from '../../utilities/scene-properties';
39
+ import { getScribbleForgeIpList } from '../../utilities/parameters';
40
+ import { clearBoardIpList, setBoardIpList } from '../../utilities/shared-storage';
39
41
  export class FcrSharingControlImpl {
40
42
  static {
41
43
  [_initProto] = _applyDecs(this, [[_startScreenSharingDecs, 2, "startScreenSharing"], [trace, 2, "startWhiteboard"], [_updateScreenSharingDecs, 2, "updateScreenSharing"], [trace, 2, "stop"], [trace, 2, "getScreenSharingState"]], []).e;
@@ -47,6 +49,8 @@ export class FcrSharingControlImpl {
47
49
  _isActive = false;
48
50
  _shareOwnerId = '';
49
51
  _shareOwnerStream = null;
52
+ _lastScreenSharingState = FcrScreenSharingState.END;
53
+ _lastScreenSharingStreamId = null;
50
54
  _streamObserver = {
51
55
  onStreamsAdded: this._handleOnStreamsAdded.bind(this),
52
56
  onStreamsRemoved: this._handleOnStreamsRemoved.bind(this)
@@ -66,10 +70,11 @@ export class FcrSharingControlImpl {
66
70
  get ownerStream() {
67
71
  return this._shareOwnerStream;
68
72
  }
69
- constructor(_scene, _api, _engine, _privilegeControl, _streamControl, _sharedCache, _userControl) {
73
+ constructor(_scene, _api, _engine, _config, _privilegeControl, _streamControl, _sharedCache, _userControl) {
70
74
  this._scene = _scene;
71
75
  this._api = _api;
72
76
  this._engine = _engine;
77
+ this._config = _config;
73
78
  this._privilegeControl = _privilegeControl;
74
79
  this._streamControl = _streamControl;
75
80
  this._sharedCache = _sharedCache;
@@ -81,6 +86,12 @@ export class FcrSharingControlImpl {
81
86
  this._streamControl.addObserver(this._streamObserver);
82
87
  this._whiteboardControl.addObserver(this._whiteboardObserver);
83
88
  this._scene.addObserver(this._sceneObserver);
89
+ clearBoardIpList();
90
+ const boardIpList = getScribbleForgeIpList(this._config.parameters);
91
+ if (boardIpList) {
92
+ this.logger.info('set board ip list to storage ', boardIpList);
93
+ setBoardIpList(boardIpList);
94
+ }
84
95
  this.logger.info(`initialized, room id: ${this._scene.sceneId}`);
85
96
  }
86
97
  async startScreenSharing(config, size, labels) {
@@ -152,6 +163,7 @@ export class FcrSharingControlImpl {
152
163
  userName,
153
164
  roomId: this._scene.sceneId,
154
165
  boardRatio: 1,
166
+ ipList: getScribbleForgeIpList(this._config.parameters),
155
167
  size: {
156
168
  width: 1280,
157
169
  height: 720
@@ -198,7 +210,8 @@ export class FcrSharingControlImpl {
198
210
  userId,
199
211
  userName,
200
212
  roomId: this._scene.sceneId,
201
- boardRatio: 0
213
+ boardRatio: 0,
214
+ ipList: getScribbleForgeIpList(this._config.parameters)
202
215
  };
203
216
  this._whiteboardControl = factory.createForMainProcess(
204
217
  // @ts-ignore
@@ -232,7 +245,7 @@ export class FcrSharingControlImpl {
232
245
  if (this._isStreamToHandleScreenSharing(modifiedStream)) {
233
246
  this._shareOwnerId = modifiedStream.owner.userId;
234
247
  this._shareOwnerStream = modifiedStream;
235
- this._observable.notifyObservers('onScreenSharingUpdated', modifiedStream, FcrScreenSharingState.START_ONLY_SCREEN);
248
+ this._notifyScreenSharingUpdated('onScreenSharingUpdated', modifiedStream, this.getScreenSharingState());
236
249
  }
237
250
  });
238
251
  }
@@ -243,7 +256,7 @@ export class FcrSharingControlImpl {
243
256
  } = event;
244
257
  const ownerId = modifiedStream.owner.userId;
245
258
  if (this._isStreamToHandleScreenSharing(modifiedStream)) {
246
- this._observable.notifyObservers('onScreenSharingUpdated', modifiedStream, FcrScreenSharingState.END);
259
+ this._notifyScreenSharingUpdated('onScreenSharingUpdated', modifiedStream, FcrScreenSharingState.END);
247
260
  if (this.getScreenSharingState() === FcrScreenSharingState.END) {
248
261
  const isMeSharing = ownerId === this._userControl.getLocalUser().userId;
249
262
  if (isMeSharing) {
@@ -261,43 +274,42 @@ export class FcrSharingControlImpl {
261
274
  const causeData = cause?.data;
262
275
  const currentScreenSharingState = this.getScreenSharingState();
263
276
  const causeCmd = cause?.cmd;
277
+ const isWidgetPropertiesUpdated = causeCmd === 10;
278
+ const isAnnotationWidgetUpdated = causeData?.widgetUuid === FcrWidgetUuid.ANNOTATION;
279
+ const isAnnotationStateUpdated = causeData?.widgetCause?.cmd === FcrWidgetCauseCmd.ANNOTATION;
280
+ if (!isWidgetPropertiesUpdated || !isAnnotationWidgetUpdated) {
281
+ return;
282
+ }
264
283
  if (currentScreenSharingState === FcrScreenSharingState.END) {
265
- if (causeData && causeCmd === 10 && causeData.widgetUuid === FcrWidgetUuid.ANNOTATION) {
266
- if (causeData.widgetCause?.cmd === FcrWidgetCauseCmd.ANNOTATION) {
267
- this._observable.notifyObservers('onScreenSharingUpdated', this.ownerStream, FcrScreenSharingState.END);
268
- const isMeSharing = this.ownerId === this._userControl.getLocalUser().userId;
269
- if (isMeSharing) {
270
- this.logger.info('clean annotation board');
271
- this._annotationControl.getMainWindow()?.clean();
272
- }
284
+ if (causeData.widgetCause?.cmd === FcrWidgetCauseCmd.ANNOTATION) {
285
+ this._notifyScreenSharingUpdated('onScreenSharingUpdated', this.ownerStream, FcrScreenSharingState.END);
286
+ const isMeSharing = this.ownerId === this._userControl.getLocalUser().userId;
287
+ if (isMeSharing) {
288
+ this.logger.info('clean annotation board');
289
+ this._annotationControl.getMainWindow()?.clean();
273
290
  }
274
291
  }
275
292
  } else {
276
- // 当屏幕共享开启时
277
- if (causeData && causeCmd === 10 && causeData.widgetUuid === FcrWidgetUuid.ANNOTATION) {
278
- if (causeData.widgetCause?.cmd === FcrWidgetCauseCmd.ANNOTATION) {
279
- const screenStream = this._getScreenShareStreamByUuid();
280
- this._observable.notifyObservers('onScreenSharingUpdated', screenStream ?? this.ownerStream, FcrScreenSharingState.START_WHIT_ANNOTATION);
281
- // const owner = this._userControl.getUser(this.ownerId);
282
- // const isElectron =
283
- // owner &&
284
- // [FcrPlatform.WEB_DESKTOP, FcrPlatform.MACOS, FcrPlatform.WINDOWS].includes(
285
- // owner.platform,
286
- // );
287
- // const mainWindow = this._annotationControl?.getMainWindow();
288
- // const isAndroid = owner && owner.platform === FcrPlatform.ANDROID;
289
- // if (isElectron && mainWindow) {
290
- // mainWindow.setAutoCancelDraw(false);
291
- // }
292
- // if (isAndroid && mainWindow) {
293
- // const isNotMeSharing = this.ownerId !== this._userControl.getLocalUser().userId;
294
- // mainWindow.setAutoCancelDraw(isNotMeSharing);
295
- // }
296
- } else {
297
- if (causeData.reason === 1) {
298
- this._observable.notifyObservers('onScreenSharingUpdated', this.ownerStream, FcrScreenSharingState.END);
299
- }
300
- }
293
+ if (isAnnotationStateUpdated) {
294
+ const screenStream = this._getScreenShareStreamByUuid();
295
+ this._notifyScreenSharingUpdated('onScreenSharingUpdated', screenStream ?? this.ownerStream, FcrScreenSharingState.START_WHIT_ANNOTATION);
296
+ // const owner = this._userControl.getUser(this.ownerId);
297
+ // const isElectron =
298
+ // owner &&
299
+ // [FcrPlatform.WEB_DESKTOP, FcrPlatform.MACOS, FcrPlatform.WINDOWS].includes(
300
+ // owner.platform,
301
+ // );
302
+ // const mainWindow = this._annotationControl?.getMainWindow();
303
+ // const isAndroid = owner && owner.platform === FcrPlatform.ANDROID;
304
+ // if (isElectron && mainWindow) {
305
+ // mainWindow.setAutoCancelDraw(false);
306
+ // }
307
+ // if (isAndroid && mainWindow) {
308
+ // const isNotMeSharing = this.ownerId !== this._userControl.getLocalUser().userId;
309
+ // mainWindow.setAutoCancelDraw(isNotMeSharing);
310
+ // }
311
+ } else if (causeData.reason === 1) {
312
+ this._notifyScreenSharingUpdated('onScreenSharingUpdated', this.ownerStream, FcrScreenSharingState.END);
301
313
  }
302
314
  }
303
315
  }
@@ -320,6 +332,15 @@ export class FcrSharingControlImpl {
320
332
  const stream = this._streamControl.getStreamByStreamId(screenStreamUuid);
321
333
  return typeof stream === 'undefined' ? null : stream;
322
334
  }
335
+ _notifyScreenSharingUpdated(eventName, streamInfo, state) {
336
+ const streamId = streamInfo?.streamId ?? null;
337
+ if (this._lastScreenSharingState === state && this._lastScreenSharingStreamId === streamId) {
338
+ return;
339
+ }
340
+ this._lastScreenSharingState = state;
341
+ this._lastScreenSharingStreamId = state === FcrScreenSharingState.END ? null : streamId;
342
+ this._observable.notifyObservers(eventName, streamInfo, state);
343
+ }
323
344
  _addLogObserver() {
324
345
  this.addObserver(generateLogObserver(this.logger, [['onScreenSharingUpdated', ['streamInfo', 'state']], ['onWhiteboardStarted', ['ownerId', 'operatorUser']], ['onWhiteboardEnded', ['reason', 'operatorUser']]]));
325
346
  }
@@ -166,14 +166,15 @@ export class FcrBaseWhiteboardControlImpl {
166
166
  });
167
167
  const {
168
168
  userId,
169
- userName
169
+ userName,
170
+ ipList
170
171
  } = this.config;
171
172
  const {
172
173
  boardAppId,
173
174
  boardId,
174
175
  boardRegion,
175
- boardToken,
176
- boardPerformance = false
176
+ boardToken
177
+ // boardPerformance = false,
177
178
  } = this.boardRoomConfig || {};
178
179
  if (!boardAppId) {
179
180
  throw generateFcrCoreClientError(ErrorModuleCode.FCR_ROOM_WHITEBOARD, DetailErrorCode.UNDEFINED_ERROR, 'boardAppId is required');
@@ -196,6 +197,15 @@ export class FcrBaseWhiteboardControlImpl {
196
197
  whiteboardOption.height = 600;
197
198
  }
198
199
  this.logger.info(`open board with boardId: ${boardId}, boardToken: ${boardToken}, region: ${boardRegion}, appIdentifier: ${boardAppId} whiteboardOption: ${jsonstring(whiteboardOption)}`);
200
+ let endpoint = undefined;
201
+ if (ipList !== undefined) {
202
+ if (Array.isArray(ipList) && ipList[0]) {
203
+ this.logger.info(`use ipList from config: ${jsonstring(ipList)}`);
204
+ endpoint = ipList[0];
205
+ } else {
206
+ this.logger.error(`ipList in config is empty or invalid: ${jsonstring(ipList)}, ignore ipList config`);
207
+ }
208
+ }
199
209
  const rtmProvider = new RTMProvider_2_2(this.rtmClient);
200
210
  const wbRoom = new Room(boardId, rtmProvider);
201
211
  this.logger.info('ApplicationManager.registerApplication calling');
@@ -233,9 +243,10 @@ export class FcrBaseWhiteboardControlImpl {
233
243
  nickName: userName || userId,
234
244
  roomToken: boardToken,
235
245
  sdkConfig: {
236
- region: boardRegion,
246
+ region: endpoint ? 'private' : boardRegion,
237
247
  appIdentifier: boardAppId
238
248
  },
249
+ endpoint,
239
250
  writable: true
240
251
  // verboseLog: true,
241
252
  };
@@ -288,7 +299,8 @@ export class FcrBaseWhiteboardControlImpl {
288
299
  // boardView.internalSetWritable(false);
289
300
  // }
290
301
 
291
- boardView.setPerformanceMode(boardPerformance);
302
+ // boardView.setPerformanceMode(boardPerformance);
303
+
292
304
  this.updateConnectionState(FcrConnectionState.CONNECTED);
293
305
  resolve(boardView);
294
306
  if (this._waitPromiseResolve) {
@@ -15,7 +15,7 @@ import "core-js/modules/esnext.map.reduce.js";
15
15
  import "core-js/modules/esnext.map.some.js";
16
16
  import "core-js/modules/esnext.map.update.js";
17
17
  import "core-js/modules/esnext.symbol.metadata.js";
18
- let _initProto, _setPerformanceModeDecs, _setBackgroundColorDecs, _setToolTypeDecs, _setStrokeWidthDecs, _setStrokeColorDecs, _setTextColorDecs, _setTextSizeDecs, _insertImageDecs, _setContainerSizeRatioDecs, _setBoardTransparentDecs, _updateWindowSizeDecs, _setAutoCancelDrawDecs, _handleApplicationLaunchDecs, _handleApplicationTerminalDecs, _enableAutoCancelDecs;
18
+ let _initProto, _setBackgroundColorDecs, _setToolTypeDecs, _setStrokeWidthDecs, _setStrokeColorDecs, _setTextColorDecs, _setTextSizeDecs, _insertImageDecs, _setContainerSizeRatioDecs, _setBoardTransparentDecs, _updateWindowSizeDecs, _setAutoCancelDrawDecs, _handleApplicationLaunchDecs, _handleApplicationTerminalDecs, _enableAutoCancelDecs;
19
19
  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)]; } }; }
20
20
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
21
21
  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); }
@@ -34,9 +34,9 @@ import { handleRequestError } from '../../../utilities/error';
34
34
  import { ErrorModuleCode } from '../../../imports';
35
35
  export class FcrBoardMainWindowImpl {
36
36
  static {
37
- [_initProto] = _applyDecs(this, [[trace, 2, "addPage"], [trace, 2, "removePage"], [trace, 2, "undo"], [trace, 2, "redo"], [trace, 2, "clean"], [trace, 2, "getSnapshotImage"], [_setPerformanceModeDecs, 2, "setPerformanceMode"], [_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;
37
+ [_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;
38
38
  }
39
- [(_setPerformanceModeDecs = trace(['enable']), _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({
39
+ [(_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({
40
40
  prefix: 'FcrBoardMainWindowImpl'
41
41
  }));
42
42
  _observable = new AgoraObservable();
@@ -136,16 +136,6 @@ export class FcrBoardMainWindowImpl {
136
136
  throw new Error('Whiteboard is not initialized');
137
137
  }
138
138
  }
139
-
140
- /**
141
- * 设置性能模式状态, enabled 为 true 时开启性能模式, 否则关闭性能模式
142
- * 性能模式下, 白板会降低渲染质量及同步频率以提升性能, 适用于低性能设备或需要大量绘制元素的场景
143
- * @param enable 是否开启性能模式
144
- */
145
- setPerformanceMode(enable) {
146
- this._whiteboard.setPerformanceMode(enable);
147
- return FcrReturnCode.SUCCESS;
148
- }
149
139
  async setBackgroundColor(color) {
150
140
  this._background = color;
151
141
  this.logger.info(`set canvas background color: ${this._background}`);
@@ -149,20 +149,30 @@ export class FcrWhiteboardControlImpl extends FcrBaseWhiteboardControlImpl {
149
149
  const operatorUser = convertRteUserToFcrUser(event.operatorUser, this._roomCache);
150
150
  const getByKeyPath = value => this._scene.getScenePropertiesByKeyPath(value);
151
151
  if (event.cause && event.cause.cmd === 10) {
152
+ const causeData = event.cause.data;
153
+ if (causeData?.widgetUuid && causeData.widgetUuid !== 'netlessBoard') {
154
+ return;
155
+ }
152
156
  const state = getByKeyPath('widgets.netlessBoard.state') ?? FcrBoardPropertiesState.INACTIVE;
153
157
  const backgroundColor = getByKeyPath('widgets.netlessBoard.extra.backgroundColor');
154
158
  const widgetCauseReason = get(event.cause.data, 'widgetCause.data.reason');
155
159
  const widgetCauseCmd = get(event.cause.data, 'widgetCause.cmd');
156
160
  if (state === FcrBoardPropertiesState.ACTIVE) {
157
161
  const ownerUserId = getByKeyPath('widgets.netlessBoard.ownerUserUuid');
162
+ const shouldNotify = !this._isActive || this._ownerId !== ownerUserId;
158
163
  this._ownerId = ownerUserId;
159
164
  this._isActive = true;
160
- this.observable.notifyObservers('onActive', ownerUserId, operatorUser);
165
+ if (shouldNotify) {
166
+ this.observable.notifyObservers('onActive', ownerUserId, operatorUser);
167
+ }
161
168
  }
162
169
  if (state === FcrBoardPropertiesState.INACTIVE) {
170
+ const shouldNotify = this._isActive || this._ownerId !== null;
163
171
  this._ownerId = null;
164
172
  this._isActive = false;
165
- this.observable.notifyObservers('onInactive', widgetCauseReason, operatorUser);
173
+ if (shouldNotify) {
174
+ this.observable.notifyObservers('onInactive', widgetCauseReason, operatorUser);
175
+ }
166
176
  }
167
177
  if (widgetCauseCmd === FcrBoardPropertiesState.BACKGROUND_COLOR_UPDATED) {
168
178
  this._backgroundColor = backgroundColor;
@@ -114,6 +114,9 @@ export const getEasemobChatIpList = parameters => {
114
114
  export const getEasemobRestIpList = parameters => {
115
115
  return parameters?.core?.easemobRestIpList;
116
116
  };
117
+ export const getScribbleForgeIpList = parameters => {
118
+ return parameters?.core?.scribbleForgeIpList;
119
+ };
117
120
  export const isEndpointRegionDisabled = parameters => {
118
121
  return isTrueValue(parameters?.core?.disableEndpointRegion);
119
122
  };
@@ -3,6 +3,7 @@ import "core-js/modules/esnext.json.parse.js";
3
3
  import { localStorage } from '../imports';
4
4
  const STORAGE_KEY_ANNOTATION_BOARD_OPTIONS = 'annotation_board_options';
5
5
  const STORAGE_KEY_WHITEBOARD_OPTIONS = 'whiteboard_options';
6
+ const STORAGE_KEY_BOARD_IP_LIST = 'board_ip_list';
6
7
  export const setAnnotationBoardOptions = options => {
7
8
  localStorage.setItem(STORAGE_KEY_ANNOTATION_BOARD_OPTIONS, JSON.stringify(options));
8
9
  };
@@ -28,4 +29,17 @@ export const getWhiteboardOptions = () => {
28
29
  };
29
30
  export const clearWhiteboardOptions = () => {
30
31
  localStorage.removeItem(STORAGE_KEY_WHITEBOARD_OPTIONS);
32
+ };
33
+ export const setBoardIpList = ipList => {
34
+ localStorage.setItem(STORAGE_KEY_BOARD_IP_LIST, JSON.stringify(ipList));
35
+ };
36
+ export const getBoardIpList = () => {
37
+ const ipListStr = localStorage.getItem(STORAGE_KEY_BOARD_IP_LIST);
38
+ if (ipListStr) {
39
+ return JSON.parse(ipListStr);
40
+ }
41
+ return undefined;
42
+ };
43
+ export const clearBoardIpList = () => {
44
+ localStorage.removeItem(STORAGE_KEY_BOARD_IP_LIST);
31
45
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "fcr-core",
3
3
  "description": "Core APIs for building online scenes",
4
- "version": "3.10.0-rc.1",
4
+ "version": "3.10.0",
5
5
  "module": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
7
7
  "files": [
@@ -41,7 +41,7 @@
41
41
  "@types/lodash": "^4.14.168",
42
42
  "@types/sinon": "^17.0.2",
43
43
  "@types/uuid": "^8.3.0",
44
- "agora-toolchain": "3.10.0-rc.1",
44
+ "agora-toolchain": "3.10.0",
45
45
  "core-js": "^3.33.3",
46
46
  "decomment": "^0.9.5",
47
47
  "husky": "^9.0.11",
@@ -55,14 +55,14 @@
55
55
  "dependencies": {
56
56
  "@netless/app-slide": "^0.2.81",
57
57
  "@netless/appliance-plugin": "^1.1.21",
58
- "@netless/forge-room": "1.1.1",
59
- "@netless/forge-rtm": "1.1.1",
60
- "@netless/forge-whiteboard": "1.1.1",
58
+ "@netless/forge-room": "1.2.0-alpha.1",
59
+ "@netless/forge-rtm": "1.2.0-alpha.1",
60
+ "@netless/forge-whiteboard": "1.2.0-alpha.1",
61
61
  "@netless/video-js-plugin": "^0.3.8",
62
62
  "@netless/white-snapshot": "^0.4.2",
63
63
  "@netless/window-manager": "^1.0.7-beta.6",
64
- "agora-foundation": "3.10.0-rc.1",
65
- "agora-rte-sdk": "3.10.0-rc.1",
64
+ "agora-foundation": "3.10.0",
65
+ "agora-rte-sdk": "3.10.0",
66
66
  "await-to-js": "^3.0.0",
67
67
  "dayjs": "^1.10.4",
68
68
  "easemob-websdk": "4.13.0",