fcr-core 3.10.6 → 3.11.0-rc.10
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/imports.d.ts +7 -1
- package/lib/imports.js +27 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.js +14 -2
- package/lib/media-control/type.d.ts +8 -1
- package/lib/peer-session/index.js +4 -0
- package/lib/plugins/chat/chatroom.js +9 -5
- package/lib/plugins/chat/connector.d.ts +6 -2
- package/lib/plugins/chat/connector.js +11 -6
- package/lib/plugins/chat/type.d.ts +8 -0
- package/lib/plugins/chat/type.js +5 -0
- package/lib/remote-control/index.js +4 -0
- package/lib/room-control/ability-control/type.d.ts +1 -0
- package/lib/room-control/ability-control/type.js +1 -0
- package/lib/room-control/helpers/constants.d.ts +8 -0
- package/lib/room-control/helpers/constants.js +8 -0
- package/lib/room-control/index.js +145 -1
- package/lib/room-control/infinity-room-control/index.js +3 -4
- package/lib/room-control/mainroom-control/index.js +3 -4
- package/lib/room-control/privilege-control/index.js +22 -3
- package/lib/room-control/privilege-control/type.d.ts +22 -0
- package/lib/room-control/privilege-control/type.js +13 -1
- package/lib/room-control/stt-control/index.js +0 -1
- package/lib/room-control/type.d.ts +44 -0
- package/lib/room-control/user-control/index.js +68 -12
- package/lib/room-control/user-control/type.d.ts +24 -0
- package/lib/room-control/whiteboard-control-v2/base/index.d.ts +7 -0
- package/lib/room-control/whiteboard-control-v2/base/index.js +84 -47
- package/lib/room-control/whiteboard-control-v2/base/main-window.d.ts +6 -0
- package/lib/room-control/whiteboard-control-v2/base/main-window.js +13 -3
- package/lib/room-control/whiteboard-control-v2/type.d.ts +5 -0
- package/lib/service/api.d.ts +15 -1
- package/lib/service/api.js +48 -0
- package/lib/utilities/parameters.js +21 -4
- package/lib-es/imports.js +6 -0
- package/lib-es/index.js +4 -0
- package/lib-es/media-control/desktop.js +1 -0
- package/lib-es/peer-session/index.js +4 -0
- package/lib-es/plugins/chat/chatroom.js +9 -5
- package/lib-es/plugins/chat/connector.js +11 -6
- package/lib-es/plugins/chat/type.js +1 -0
- package/lib-es/remote-control/index.js +4 -0
- package/lib-es/room-control/ability-control/type.js +1 -0
- package/lib-es/room-control/helpers/constants.js +8 -0
- package/lib-es/room-control/index.js +146 -2
- package/lib-es/room-control/infinity-room-control/index.js +3 -4
- package/lib-es/room-control/mainroom-control/index.js +3 -4
- package/lib-es/room-control/privilege-control/index.js +23 -4
- package/lib-es/room-control/privilege-control/type.js +12 -0
- package/lib-es/room-control/stt-control/index.js +0 -1
- package/lib-es/room-control/user-control/index.js +67 -12
- package/lib-es/room-control/whiteboard-control-v2/base/index.js +84 -47
- package/lib-es/room-control/whiteboard-control-v2/base/main-window.js +13 -3
- package/lib-es/service/api.js +48 -0
- package/lib-es/utilities/parameters.js +21 -4
- package/package.json +11 -7
package/lib/imports.d.ts
CHANGED
|
@@ -27,7 +27,13 @@ export { sleep, jsonstring, randomString } from 'agora-foundation/lib/utilities/
|
|
|
27
27
|
export { z, ZodError, anySchema, booleanSchema, numberSchema, stringSchema, fcrRenderViewSchema, unknownSchema, objectSchema, createRecordSchemaWithKey, createUnionSchema, createArraySchema, } from 'agora-foundation/lib/utilities/schema';
|
|
28
28
|
export { validateParams } from 'agora-foundation/lib/decorator/validate';
|
|
29
29
|
export { Mutex } from 'agora-foundation/lib/worker/mutex';
|
|
30
|
-
export type { AgoraRtcNetworkStats, AgoraRtcDeviceInfo, AgoraRtcDisplayInfo, AgoraRtcWindowInfo, AgoraRtePerformanceInfo, AgoraRteScenePropertiesDeletedEvent, AgoraRteStreamEncryptionConfig, AgoraRteStreamJoinConfig, AgoraRteDualVideoStreamConfig, AgoraRteMessage, AgoraRteScenePropertiesUpdatedEvent, AgoraRteRenderView, AgoraRteScene, } from 'agora-rte-sdk';
|
|
30
|
+
export type { AgoraRtcNetworkStats, AgoraRtcDeviceInfo, AgoraRtcDisplayInfo, AgoraRtcWindowInfo, AgoraRtePerformanceInfo, AgoraRteScenePropertiesDeletedEvent, AgoraRteStreamEncryptionConfig, AgoraRteStreamJoinConfig, AgoraRteDualVideoStreamConfig, AgoraRteMessage, AgoraRteScenePropertiesUpdatedEvent, AgoraRteRenderView, AgoraRteScene, AgoraRteClientRecordingConfig, AgoraRteClientRecordingObserver, AgoraRteRecorderInfo, } from 'agora-rte-sdk';
|
|
31
|
+
export { AgoraRteRecorderState, AgoraRteRecorderReasonCode } from 'agora-rte-sdk';
|
|
32
|
+
export type { AgoraRteClientRecordingConfig as FcrClientRecordingConfig } from 'agora-rte-sdk';
|
|
33
|
+
export type { AgoraRteClientRecordingObserver as FcrClientRecordingObserver } from 'agora-rte-sdk';
|
|
34
|
+
export type { AgoraRteRecorderInfo as FcrRecorderInfo } from 'agora-rte-sdk';
|
|
35
|
+
export { AgoraRteRecorderState as FcrRecorderState } from 'agora-rte-sdk';
|
|
36
|
+
export { AgoraRteRecorderReasonCode as FcrRecorderReasonCode } from 'agora-rte-sdk';
|
|
31
37
|
export type { AgoraRtmClient } from 'agora-rte-sdk/lib/core/rtm/client';
|
|
32
38
|
export type { AgoraRteEngineObserver } from 'agora-rte-sdk/lib/core/engine/type';
|
|
33
39
|
export type { AgoraRteNetworkQualityEvent } from 'agora-rte-sdk/lib/core/scene/type';
|
package/lib/imports.js
CHANGED
|
@@ -150,6 +150,18 @@ Object.defineProperty(exports, "AgoraRteMediaStreamType", {
|
|
|
150
150
|
return _type.AgoraRteMediaStreamType;
|
|
151
151
|
}
|
|
152
152
|
});
|
|
153
|
+
Object.defineProperty(exports, "AgoraRteRecorderReasonCode", {
|
|
154
|
+
enumerable: true,
|
|
155
|
+
get: function () {
|
|
156
|
+
return _agoraRteSdk.AgoraRteRecorderReasonCode;
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
Object.defineProperty(exports, "AgoraRteRecorderState", {
|
|
160
|
+
enumerable: true,
|
|
161
|
+
get: function () {
|
|
162
|
+
return _agoraRteSdk.AgoraRteRecorderState;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
153
165
|
Object.defineProperty(exports, "AgoraRteRegion", {
|
|
154
166
|
enumerable: true,
|
|
155
167
|
get: function () {
|
|
@@ -294,6 +306,18 @@ Object.defineProperty(exports, "FcrRTMProvider_2_2", {
|
|
|
294
306
|
return _forgeRtm.RTMProvider_2_2;
|
|
295
307
|
}
|
|
296
308
|
});
|
|
309
|
+
Object.defineProperty(exports, "FcrRecorderReasonCode", {
|
|
310
|
+
enumerable: true,
|
|
311
|
+
get: function () {
|
|
312
|
+
return _agoraRteSdk.AgoraRteRecorderReasonCode;
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
Object.defineProperty(exports, "FcrRecorderState", {
|
|
316
|
+
enumerable: true,
|
|
317
|
+
get: function () {
|
|
318
|
+
return _agoraRteSdk.AgoraRteRecorderState;
|
|
319
|
+
}
|
|
320
|
+
});
|
|
297
321
|
Object.defineProperty(exports, "FcrRoom", {
|
|
298
322
|
enumerable: true,
|
|
299
323
|
get: function () {
|
|
@@ -587,9 +611,9 @@ var _misc = require("agora-foundation/lib/utilities/misc");
|
|
|
587
611
|
var _schema = require("agora-foundation/lib/utilities/schema");
|
|
588
612
|
var _validate = require("agora-foundation/lib/decorator/validate");
|
|
589
613
|
var _mutex = require("agora-foundation/lib/worker/mutex");
|
|
614
|
+
var _agoraRteSdk = require("agora-rte-sdk");
|
|
590
615
|
var _error = require("agora-rte-sdk/lib/core/utilities/error");
|
|
591
616
|
var _agoraError = require("agora-foundation/lib/utilities/error/agora-error");
|
|
592
|
-
var _agoraRteSdk = require("agora-rte-sdk");
|
|
593
617
|
var _type = require("agora-rte-sdk/lib/core/scene/type");
|
|
594
618
|
var _type2 = require("agora-rte-sdk/lib/core/rtc/type");
|
|
595
619
|
var _type3 = require("agora-rte-sdk/lib/type");
|
|
@@ -619,4 +643,6 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
|
|
|
619
643
|
|
|
620
644
|
// Agora RTE exports
|
|
621
645
|
|
|
646
|
+
// Fcr-prefixed re-exports for edu-core layer
|
|
647
|
+
|
|
622
648
|
const localStorage = exports.localStorage = window.localStorage;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export type { FcrDesktopMediaControl, FcrDesktopMediaObserver, FcrMobileMediaControl, FcrMobileMediaObserver, FcrMonitorControl, FcrMonitorObserver, FcrBaseRoomControl, FcrRoomObserver, FcrUserControl, FcrUserObserver, FcrStreamControl, FcrStreamObserver, FcrPrivilegeControl, FcrPermission, FcrBoardMainWindow, FcrBoardMainWindowObserver, FcrColor, FcrBatchResult, FcrStreamUpdateResultDetail, } from './type';
|
|
2
|
+
export type { FcrClientRecordingConfig } from './imports';
|
|
3
|
+
export { FcrRecorderState, FcrRecorderReasonCode } from './imports';
|
|
2
4
|
export { FcrStreamLatencyLevel, FcrPermissionAction, FcrPrivilegeUserRole, FcrUserRole, FcrStreamState, FcrRegion, FcrStreamType, FcrUserUpdatedReason, FcrRoomConnectorType, FcrVideoSourceType, FcrAudioSourceType, FcrMediaSourceState, FcrVideoRenderMode, FcrVideoStreamType, FcrCapability, FcrAiDenoiseLevel, FcrStreamPrivilegeOperation, FcrStreamPrivilegeVideoSourceType, FcrStreamPrivilegeAudioSourceType, FcrConnectionState, registerPlugin, FcrBoardToolType, FcrBoardShape, FcrVideoEncoderConfig, FcrDualVideoStreamConfig, } from './type';
|
|
3
5
|
export { FcrCoreEngineImpl as FcrCoreEngine } from './engine';
|
|
4
6
|
export { FcrCoreEngineConfig } from './struct';
|
package/lib/index.js
CHANGED
|
@@ -87,6 +87,18 @@ Object.defineProperty(exports, "FcrPrivilegeUserRole", {
|
|
|
87
87
|
return _type.FcrPrivilegeUserRole;
|
|
88
88
|
}
|
|
89
89
|
});
|
|
90
|
+
Object.defineProperty(exports, "FcrRecorderReasonCode", {
|
|
91
|
+
enumerable: true,
|
|
92
|
+
get: function () {
|
|
93
|
+
return _imports.FcrRecorderReasonCode;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
Object.defineProperty(exports, "FcrRecorderState", {
|
|
97
|
+
enumerable: true,
|
|
98
|
+
get: function () {
|
|
99
|
+
return _imports.FcrRecorderState;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
90
102
|
Object.defineProperty(exports, "FcrRegion", {
|
|
91
103
|
enumerable: true,
|
|
92
104
|
get: function () {
|
|
@@ -183,8 +195,8 @@ Object.defineProperty(exports, "registerPlugin", {
|
|
|
183
195
|
return _type.registerPlugin;
|
|
184
196
|
}
|
|
185
197
|
});
|
|
198
|
+
var _imports = require("./imports");
|
|
186
199
|
var _type = require("./type");
|
|
187
200
|
var _engine = require("./engine");
|
|
188
201
|
var _struct = require("./struct");
|
|
189
|
-
var _schema = require("./schema");
|
|
190
|
-
var _imports = require("./imports");
|
|
202
|
+
var _schema = require("./schema");
|
|
@@ -163,6 +163,12 @@ export interface FcrAudioEffectEnhancer {
|
|
|
163
163
|
* Disables AGC for the audio track.
|
|
164
164
|
*/
|
|
165
165
|
disableAGC(): void;
|
|
166
|
+
/**
|
|
167
|
+
* Sets the Windows system-level audio preprocessing (hardware 3A) mode.
|
|
168
|
+
* Only effective on Electron Windows.
|
|
169
|
+
* @param mode `0` off (default), `1` on, `2` only enabled under speaker routing.
|
|
170
|
+
*/
|
|
171
|
+
setWindowsSystemAudioPreprocessingMode(mode: number): void;
|
|
166
172
|
}
|
|
167
173
|
export interface FcrVideoEffectEnhancer {
|
|
168
174
|
/**
|
|
@@ -404,8 +410,9 @@ export interface FcrMicrophoneTrack {
|
|
|
404
410
|
/**
|
|
405
411
|
* Starts the microphone test for the specified device.
|
|
406
412
|
* @param interval The interval for the microphone test.
|
|
413
|
+
* @param enablePlayback Whether to enable playback during the test.
|
|
407
414
|
*/
|
|
408
|
-
startTest(interval: number): number;
|
|
415
|
+
startTest(interval: number, enablePlayback?: boolean): number;
|
|
409
416
|
/**
|
|
410
417
|
* Stops the microphone test for the specified device.
|
|
411
418
|
*/
|
|
@@ -326,6 +326,10 @@ class FcrPeerSessionControlImpl {
|
|
|
326
326
|
data,
|
|
327
327
|
cmd
|
|
328
328
|
} = payload;
|
|
329
|
+
if (cmd !== '1001' && cmd !== '1002' || !data || typeof data.sessionKey !== 'string' || typeof data.sessionUuid !== 'string') {
|
|
330
|
+
this.logger.info(`[PeerSession] ignore non peer-session message: cmd=${String(cmd)}, senderId=${senderId}, payload=${JSON.stringify(payload)}`);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
329
333
|
const logContext = `cmd=${cmd}, sessionKey=${data.sessionKey}, sessionId=${data.sessionUuid}, ` + `action=${String(data.action)}, senderId=${senderId}, keepAlive=${!!data.keepAlive}`;
|
|
330
334
|
this.logger.info(`[PeerSession] received peer message: ${logContext}, payload=${JSON.stringify(data.payload ?? {})}`);
|
|
331
335
|
if (cmd === '1001') {
|
|
@@ -77,17 +77,19 @@ class FcrChatRoomControlImpl {
|
|
|
77
77
|
this._observable.notifyObservers('onTextMessageReceived', this._scene.sceneId, message);
|
|
78
78
|
}
|
|
79
79
|
};
|
|
80
|
+
_chatConnectionInternalObserver = {
|
|
81
|
+
onReconnected: () => {
|
|
82
|
+
this.logger.info('chat connector reconnected, try to rejoin chat room');
|
|
83
|
+
this._tryJoinChatRoom(true);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
80
86
|
_chatConnectionObserver = {
|
|
81
87
|
onConnectionStateUpdated: async connectorState => {
|
|
82
|
-
const chatRoomConnectionState = this.getConnectionState();
|
|
83
88
|
if (connectorState === _type.FcrChatConnectionState.DISCONNECTED) {
|
|
84
89
|
this._setConnectionState(_type2.FcrChatRoomConnectionState.Disconnected);
|
|
85
|
-
} else if (connectorState === _type.FcrChatConnectionState.CONNECTED
|
|
90
|
+
} else if (connectorState === _type.FcrChatConnectionState.CONNECTED) {
|
|
86
91
|
this.logger.info('chat connector connected, try to join chat room');
|
|
87
92
|
this._tryJoinChatRoom();
|
|
88
|
-
} else if (connectorState === _type.FcrChatConnectionState.CONNECTED) {
|
|
89
|
-
this.logger.info('chat connector reconnected, try to rejoin chat room');
|
|
90
|
-
this._tryJoinChatRoom(true);
|
|
91
93
|
}
|
|
92
94
|
}
|
|
93
95
|
};
|
|
@@ -202,6 +204,7 @@ class FcrChatRoomControlImpl {
|
|
|
202
204
|
}
|
|
203
205
|
leave() {
|
|
204
206
|
this._chatConnection.removeObserver(this._chatConnectionObserver);
|
|
207
|
+
this._chatConnection.removeInternalObserver(this._chatConnectionInternalObserver);
|
|
205
208
|
if (this._connectionState === _type2.FcrChatRoomConnectionState.Disconnected && !this._abortJoinChatRoom) {
|
|
206
209
|
return;
|
|
207
210
|
}
|
|
@@ -234,6 +237,7 @@ class FcrChatRoomControlImpl {
|
|
|
234
237
|
}
|
|
235
238
|
async join(force = false) {
|
|
236
239
|
this._chatConnection.addObserver(this._chatConnectionObserver);
|
|
240
|
+
this._chatConnection.addInternalObserver(this._chatConnectionInternalObserver);
|
|
237
241
|
const connectorState = this._chatConnection.getConnectionState();
|
|
238
242
|
if (connectorState !== _type.FcrChatConnectionState.CONNECTED) {
|
|
239
243
|
return _type3.FcrReturnCode.SUCCESS;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { EasemobChat } from '../../imports';
|
|
2
2
|
import { FcrCoreServiceApi } from '../../service/api';
|
|
3
|
-
import { FcrChatConnectionObserver, FcrChatConnectionState
|
|
4
|
-
|
|
3
|
+
import { FcrChatConnectionObserver, FcrChatConnectionState } from '../../chat-connector/type';
|
|
4
|
+
import { FcrChatConnectionInternalObserver, FcrChatConnectorInternal } from './type';
|
|
5
|
+
export declare class FcrChatConnectorImpl implements FcrChatConnectorInternal {
|
|
5
6
|
private _userId;
|
|
6
7
|
private _api;
|
|
7
8
|
private _chatIpList?;
|
|
8
9
|
private _restIpList?;
|
|
9
10
|
protected logger: import("agora-foundation/lib/logger/type").Logger;
|
|
10
11
|
private _observable;
|
|
12
|
+
private _internalObservable;
|
|
11
13
|
private _initConfig?;
|
|
12
14
|
private _loginPromise;
|
|
13
15
|
private _logoutPromise;
|
|
@@ -24,6 +26,8 @@ export declare class FcrChatConnectorImpl implements FcrChatConnector {
|
|
|
24
26
|
getConnectionInstance(): EasemobChat.Connection;
|
|
25
27
|
addObserver(observer: FcrChatConnectionObserver): void;
|
|
26
28
|
removeObserver(observer: FcrChatConnectionObserver): void;
|
|
29
|
+
addInternalObserver(observer: FcrChatConnectionInternalObserver): void;
|
|
30
|
+
removeInternalObserver(observer: FcrChatConnectionInternalObserver): void;
|
|
27
31
|
private _performLogin;
|
|
28
32
|
private _addEventListeners;
|
|
29
33
|
private _performLogout;
|
|
@@ -43,6 +43,7 @@ class FcrChatConnectorImpl {
|
|
|
43
43
|
prefix: 'FcrChatConnectorImpl'
|
|
44
44
|
}));
|
|
45
45
|
_observable = new _imports.AgoraObservable();
|
|
46
|
+
_internalObservable = new _imports.AgoraObservable();
|
|
46
47
|
_loginPromise = null;
|
|
47
48
|
_logoutPromise = null;
|
|
48
49
|
_isLogoutRequested = false;
|
|
@@ -98,6 +99,12 @@ class FcrChatConnectorImpl {
|
|
|
98
99
|
removeObserver(observer) {
|
|
99
100
|
this._observable.removeObserver(observer);
|
|
100
101
|
}
|
|
102
|
+
addInternalObserver(observer) {
|
|
103
|
+
this._internalObservable.addObserver(observer);
|
|
104
|
+
}
|
|
105
|
+
removeInternalObserver(observer) {
|
|
106
|
+
this._internalObservable.removeObserver(observer);
|
|
107
|
+
}
|
|
101
108
|
async _performLogin() {
|
|
102
109
|
const privateConfig = this._getPrivateConfig();
|
|
103
110
|
if (privateConfig) {
|
|
@@ -227,7 +234,6 @@ class FcrChatConnectorImpl {
|
|
|
227
234
|
if (this._restIpList?.length) {
|
|
228
235
|
privateConfig.apiUrl = this._restIpList[0];
|
|
229
236
|
}
|
|
230
|
-
privateConfig.url = 'wss://apaas-private-im.agoralab.co:13003/websocket';
|
|
231
237
|
return privateConfig;
|
|
232
238
|
}
|
|
233
239
|
}
|
|
@@ -235,12 +241,11 @@ class FcrChatConnectorImpl {
|
|
|
235
241
|
if (this._isLogoutRequested) {
|
|
236
242
|
return;
|
|
237
243
|
}
|
|
238
|
-
if (this._connectionState
|
|
239
|
-
this.
|
|
240
|
-
|
|
241
|
-
// notify again in case of reconnection
|
|
242
|
-
this._observable.notifyObservers('onConnectionStateUpdated', _type2.FcrChatConnectionState.CONNECTED);
|
|
244
|
+
if (this._connectionState === _type2.FcrChatConnectionState.CONNECTED) {
|
|
245
|
+
this._internalObservable.notifyObservers('onReconnected');
|
|
246
|
+
return;
|
|
243
247
|
}
|
|
248
|
+
this._setConnectionState(_type2.FcrChatConnectionState.CONNECTED);
|
|
244
249
|
}
|
|
245
250
|
_handleDisconnected() {
|
|
246
251
|
if (this._connectionState !== _type2.FcrChatConnectionState.DISCONNECTED) {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FcrChatConnector } from '../../chat-connector/type';
|
|
2
|
+
export interface FcrChatConnectorInternal extends FcrChatConnector {
|
|
3
|
+
addInternalObserver(observer: FcrChatConnectionInternalObserver): void;
|
|
4
|
+
removeInternalObserver(observer: FcrChatConnectionInternalObserver): void;
|
|
5
|
+
}
|
|
6
|
+
export interface FcrChatConnectionInternalObserver {
|
|
7
|
+
onReconnected(): void;
|
|
8
|
+
}
|
|
@@ -78,6 +78,10 @@ class FcrRemoteControlImpl {
|
|
|
78
78
|
data,
|
|
79
79
|
cmd
|
|
80
80
|
} = payload;
|
|
81
|
+
if (cmd !== '1001' && cmd !== '1002' || !data || typeof data.sessionKey !== 'string' || typeof data.sessionUuid !== 'string') {
|
|
82
|
+
this.logger.info(`[RemoteControl] ignore non remote-control message: cmd=${String(cmd)}, senderId=${senderId}, payload=${JSON.stringify(payload)}`);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
81
85
|
const logContext = `cmd=${cmd}, sessionKey=${data.sessionKey}, sessionId=${data.sessionUuid}, ` + `action=${String(data.action)}, senderId=${senderId}, keepAlive=${!!data.keepAlive}`;
|
|
82
86
|
if (data.sessionKey !== this._remoteControlSessionKey) {
|
|
83
87
|
this.logger.info(`[RemoteControl] ignore peer message because sessionKey does not match remote-control: ${logContext}`);
|
|
@@ -8,6 +8,7 @@ export declare enum FcrAbility {
|
|
|
8
8
|
Caption = "caption",
|
|
9
9
|
Transcribe = "transcribe",
|
|
10
10
|
Recording = "recording",
|
|
11
|
+
ClientRecording = "clientRecording",
|
|
11
12
|
Board = "board",
|
|
12
13
|
SettingVirtualBackground = "setting:virtualBackground",
|
|
13
14
|
SettingBeautyMode = "setting:beautyMode",
|
|
@@ -13,6 +13,7 @@ let FcrAbility = exports.FcrAbility = /*#__PURE__*/function (FcrAbility) {
|
|
|
13
13
|
FcrAbility["Caption"] = "caption";
|
|
14
14
|
FcrAbility["Transcribe"] = "transcribe";
|
|
15
15
|
FcrAbility["Recording"] = "recording";
|
|
16
|
+
FcrAbility["ClientRecording"] = "clientRecording";
|
|
16
17
|
FcrAbility["Board"] = "board";
|
|
17
18
|
FcrAbility["SettingVirtualBackground"] = "setting:virtualBackground";
|
|
18
19
|
FcrAbility["SettingBeautyMode"] = "setting:beautyMode";
|
|
@@ -44,6 +44,14 @@ export declare const ROOM_MESSAGE_COMMANDS: {
|
|
|
44
44
|
readonly LIVE_STREAMING_UPDATE: 700;
|
|
45
45
|
/** 用户被踢出命令 */
|
|
46
46
|
readonly USER_KICK_OUT: 5;
|
|
47
|
+
/** 用户widget属性更新命令(widget属性变更的通用cause.cmd) */
|
|
48
|
+
readonly USER_WIDGET_PROPERTIES_UPDATE: 10;
|
|
49
|
+
/** 客户端录制权限变更(角色级, cause.cmd=3260) */
|
|
50
|
+
readonly CLIENT_RECORDING_PERMISSION: 3260;
|
|
51
|
+
/** 客户端录制状态变更 cause.data.widgetCause.cmd=3261 (通过widget属性下发) */
|
|
52
|
+
readonly CLIENT_RECORDING_STATE: 3261;
|
|
53
|
+
/** 用户权限变更(用户级,含客户端录制) */
|
|
54
|
+
readonly USER_PERMISSION_UPDATE: 3121;
|
|
47
55
|
/** 房间会话请求命令 */
|
|
48
56
|
readonly ROOM_SESSION_REQUEST: 1001;
|
|
49
57
|
/** 房间会话接受命令 */
|
|
@@ -53,6 +53,14 @@ const ROOM_MESSAGE_COMMANDS = exports.ROOM_MESSAGE_COMMANDS = {
|
|
|
53
53
|
LIVE_STREAMING_UPDATE: 700,
|
|
54
54
|
/** 用户被踢出命令 */
|
|
55
55
|
USER_KICK_OUT: 5,
|
|
56
|
+
/** 用户widget属性更新命令(widget属性变更的通用cause.cmd) */
|
|
57
|
+
USER_WIDGET_PROPERTIES_UPDATE: 10,
|
|
58
|
+
/** 客户端录制权限变更(角色级, cause.cmd=3260) */
|
|
59
|
+
CLIENT_RECORDING_PERMISSION: 3260,
|
|
60
|
+
/** 客户端录制状态变更 cause.data.widgetCause.cmd=3261 (通过widget属性下发) */
|
|
61
|
+
CLIENT_RECORDING_STATE: 3261,
|
|
62
|
+
/** 用户权限变更(用户级,含客户端录制) */
|
|
63
|
+
USER_PERMISSION_UPDATE: 3121,
|
|
56
64
|
/** 房间会话请求命令 */
|
|
57
65
|
ROOM_SESSION_REQUEST: 1001,
|
|
58
66
|
/** 房间会话接受命令 */
|
|
@@ -24,7 +24,9 @@ require("core-js/modules/es.array.includes.js");
|
|
|
24
24
|
require("core-js/modules/es.array.push.js");
|
|
25
25
|
require("core-js/modules/es.json.stringify.js");
|
|
26
26
|
require("core-js/modules/esnext.iterator.constructor.js");
|
|
27
|
+
require("core-js/modules/esnext.iterator.find.js");
|
|
27
28
|
require("core-js/modules/esnext.iterator.for-each.js");
|
|
29
|
+
require("core-js/modules/esnext.iterator.some.js");
|
|
28
30
|
var _imports = require("../imports");
|
|
29
31
|
var _type = require("../type");
|
|
30
32
|
var _type2 = require("./type");
|
|
@@ -68,7 +70,7 @@ function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side
|
|
|
68
70
|
*/
|
|
69
71
|
class FcrBaseRoomControlImpl {
|
|
70
72
|
static {
|
|
71
|
-
[_initProto] = _applyDecs(this, [[_imports.trace, 2, "getSyncTimestamp"], [_imports.trace, 2, "getRoomInfo"], [_imports.trace, 2, "getRoomSchedule"], [_imports.trace, 2, "getLocalExDataSyncTypeList"], [_joinDecs, 2, "join"], [_imports.trace, 2, "leave"], [_imports.trace, 2, "release"], [_imports.trace, 2, "start"], [_imports.trace, 2, "end"], [_imports.trace, 2, "close"], [_imports.trace, 2, "getRoomState"], [_imports.trace, 2, "getRoomProperties"], [_imports.trace, 2, "getRoomPropertiesByKeyPath"], [_updateRoomPropertiesDecs, 2, "updateRoomProperties"], [_updateIncrementRoomPropertiesDecs, 2, "updateIncrementRoomProperties"], [_deleteRoomPropertiesDecs, 2, "deleteRoomProperties"], [_startCloudRecordingDecs, 2, "startCloudRecording"], [_imports.trace, 2, "pauseCloudRecording"], [_imports.trace, 2, "resumeCloudRecording"], [_imports.trace, 2, "stopCloudRecording"], [_imports.trace, 2, "getLiveStreamingState"], [_imports.trace, 2, "getLiveStreamingConfig"], [_startLiveStreamingDecs, 2, "startLiveStreaming"], [_updateLiveStreamingLayoutDecs, 2, "updateLiveStreamingLayout"], [_imports.trace, 2, "stopLiveStreaming"], [_imports.trace, 2, "getCloudRecordingState"], [_sendRoomMessageDecs, 2, "sendRoomMessage"]], []).e;
|
|
73
|
+
[_initProto] = _applyDecs(this, [[_imports.trace, 2, "getSyncTimestamp"], [_imports.trace, 2, "getRoomInfo"], [_imports.trace, 2, "getRoomSchedule"], [_imports.trace, 2, "getLocalExDataSyncTypeList"], [_joinDecs, 2, "join"], [_imports.trace, 2, "leave"], [_imports.trace, 2, "release"], [_imports.trace, 2, "start"], [_imports.trace, 2, "end"], [_imports.trace, 2, "close"], [_imports.trace, 2, "getRoomState"], [_imports.trace, 2, "getRoomProperties"], [_imports.trace, 2, "getRoomPropertiesByKeyPath"], [_updateRoomPropertiesDecs, 2, "updateRoomProperties"], [_updateIncrementRoomPropertiesDecs, 2, "updateIncrementRoomProperties"], [_deleteRoomPropertiesDecs, 2, "deleteRoomProperties"], [_startCloudRecordingDecs, 2, "startCloudRecording"], [_imports.trace, 2, "pauseCloudRecording"], [_imports.trace, 2, "resumeCloudRecording"], [_imports.trace, 2, "stopCloudRecording"], [_imports.trace, 2, "startClientRecording"], [_imports.trace, 2, "resumeClientRecording"], [_imports.trace, 2, "stopClientRecording"], [_imports.trace, 2, "getLiveStreamingState"], [_imports.trace, 2, "getLiveStreamingConfig"], [_startLiveStreamingDecs, 2, "startLiveStreaming"], [_updateLiveStreamingLayoutDecs, 2, "updateLiveStreamingLayout"], [_imports.trace, 2, "stopLiveStreaming"], [_imports.trace, 2, "hasActiveClientRecording"], [_imports.trace, 2, "getCloudRecordingState"], [_sendRoomMessageDecs, 2, "sendRoomMessage"]], []).e;
|
|
72
74
|
}
|
|
73
75
|
//@internal
|
|
74
76
|
[(_joinDecs = (0, _imports.trace)(['options']), _updateRoomPropertiesDecs = (0, _imports.trace)(['properties', 'cause']), _updateIncrementRoomPropertiesDecs = (0, _imports.trace)(['increments', 'cause']), _deleteRoomPropertiesDecs = (0, _imports.trace)(['properties', 'cause']), _startCloudRecordingDecs = (0, _imports.trace)(['config']), _startLiveStreamingDecs = (0, _imports.trace)(['data']), _updateLiveStreamingLayoutDecs = (0, _imports.trace)(['layoutType']), _sendRoomMessageDecs = (0, _imports.trace)(['payload', 'guaranteedDelivery']), "logger")] = (_initProto(this), (0, _logger.createLogger)({
|
|
@@ -78,6 +80,8 @@ class FcrBaseRoomControlImpl {
|
|
|
78
80
|
_joinRoomSuccess = false;
|
|
79
81
|
_joining = false;
|
|
80
82
|
_joinState = _helpers.ROOM_CONTROL_CONSTANTS.JOIN_STATE.CANCELED;
|
|
83
|
+
_isClientRecordingOwner = false;
|
|
84
|
+
_isStartingClientRecording = false;
|
|
81
85
|
constructor(_engine, _scene, _api, _config, _roomType, _chatConnection, _sharedCache, _chatRoomControl) {
|
|
82
86
|
this._engine = _engine;
|
|
83
87
|
this._scene = _scene;
|
|
@@ -226,8 +230,45 @@ class FcrBaseRoomControlImpl {
|
|
|
226
230
|
this._joinState = _helpers.ROOM_CONTROL_CONSTANTS.JOIN_STATE.CANCELED;
|
|
227
231
|
this._cleanup();
|
|
228
232
|
}
|
|
233
|
+
// Handle user-level local recording permission change (cmd=3121)
|
|
234
|
+
if (event.cause?.cmd === _helpers.ROOM_MESSAGE_COMMANDS.USER_PERMISSION_UPDATE && event.modifiedUser.userId === this._scene.localUser.getLocalUserId()) {
|
|
235
|
+
const causeData = event.cause?.data;
|
|
236
|
+
if (causeData?.removePermissions?.includes('record:startClientRecording')) {
|
|
237
|
+
if (this.isLocalClientRecordingActive()) {
|
|
238
|
+
this.stopClientRecording().catch(e => {
|
|
239
|
+
this.logger.error(`auto-stop client recording failed: ${e.message}`);
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
// 初始化客户端录制观察者
|
|
248
|
+
this._clientRecordingObserver = {
|
|
249
|
+
onRecorderStateChanged: (_channelId, _uid, state, reason) => {
|
|
250
|
+
this.logger.info(`onRecorderStateChanged: state=${state}, reason=${reason}, sceneId=${this._scene.sceneId}`);
|
|
251
|
+
this._observable.notifyObservers('onClientRecordingStateChanged', this._scene.sceneId, state, reason);
|
|
229
252
|
}
|
|
230
253
|
};
|
|
254
|
+
|
|
255
|
+
// 客户端录制观察者由子类(FcrMainRoomControlImpl)注册,基类不注册
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* 注册客户端录制观察者。由主房间子类在构造时调用。
|
|
260
|
+
*/
|
|
261
|
+
_registerClientRecordingObserver() {
|
|
262
|
+
this._engine.getMediaControl().addClientRecordingObserver(this._clientRecordingObserver);
|
|
263
|
+
this._isClientRecordingOwner = true;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* 移除客户端录制观察者。由 _cleanup 调用时需要判断是否已注册。
|
|
268
|
+
*/
|
|
269
|
+
_unregisterClientRecordingObserver() {
|
|
270
|
+
this._engine.getMediaControl().removeClientRecordingObserver(this._clientRecordingObserver);
|
|
271
|
+
this._isClientRecordingOwner = false;
|
|
231
272
|
}
|
|
232
273
|
|
|
233
274
|
/**
|
|
@@ -574,6 +615,89 @@ class FcrBaseRoomControlImpl {
|
|
|
574
615
|
await (0, _error.handleRequestError)(() => this._api.stopCloudRecording(this._scene.sceneId), _imports.ErrorModuleCode.FCR_ROOM, 'stop cloud recording failed');
|
|
575
616
|
return _type.FcrReturnCode.SUCCESS;
|
|
576
617
|
}
|
|
618
|
+
async startClientRecording(config) {
|
|
619
|
+
// 防止并发调用
|
|
620
|
+
if (this._isStartingClientRecording) {
|
|
621
|
+
this.logger.warn('startClientRecording: already starting, ignoring duplicate call');
|
|
622
|
+
return _type.FcrReturnCode.SUCCESS;
|
|
623
|
+
}
|
|
624
|
+
const localUserId = this._scene.localUser.getLocalUserId();
|
|
625
|
+
|
|
626
|
+
// 标记正在启动本地录制,避免在 API 调用后、SDK 录制开始前的时间窗口内触发错误的提示
|
|
627
|
+
this._isStartingClientRecording = true;
|
|
628
|
+
let serverRecordingStarted = false;
|
|
629
|
+
try {
|
|
630
|
+
await (0, _error.handleRequestError)(() => this._api.startClientRecording(this._scene.sceneId, localUserId), _imports.ErrorModuleCode.FCR_ROOM, 'start client recording failed');
|
|
631
|
+
serverRecordingStarted = true;
|
|
632
|
+
|
|
633
|
+
// 使用 mediaControl 来启动本地录制
|
|
634
|
+
const mediaControl = this._engine.getMediaControl();
|
|
635
|
+
const isScreenShareActive = mediaControl.isScreenShareActive();
|
|
636
|
+
const currentScreenShareSourceId = mediaControl.getCurrentScreenShareSourceId();
|
|
637
|
+
|
|
638
|
+
// 获取本地用户的主流 streamId 作为录制 uid(streamId 是数字,userUuid 可能是十六进制字符串)
|
|
639
|
+
const localStreams = this._scene.getStreamsByUserId(localUserId);
|
|
640
|
+
const mainStream = localStreams.find(s => s.videoSourceType === _imports.AgoraRteVideoSourceType.CAMERA) || localStreams[0];
|
|
641
|
+
if (!mainStream) {
|
|
642
|
+
throw new Error(`No stream found for local user: ${localUserId}`);
|
|
643
|
+
}
|
|
644
|
+
const uid = Number(mainStream.streamId);
|
|
645
|
+
await mediaControl.startClientRecording(this._scene.sceneId, uid, config, isScreenShareActive, currentScreenShareSourceId);
|
|
646
|
+
return _type.FcrReturnCode.SUCCESS;
|
|
647
|
+
} catch (e) {
|
|
648
|
+
// API 调用成功但 SDK 启动失败时,回滚服务端状态
|
|
649
|
+
if (serverRecordingStarted) {
|
|
650
|
+
this.logger.error(`startClientRecording SDK failed, rolling back server state: ${e.message}`);
|
|
651
|
+
this._api.stopClientRecording(this._scene.sceneId, localUserId).catch(rollbackErr => {
|
|
652
|
+
this.logger.error(`startClientRecording rollback failed: ${rollbackErr.message}`);
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
throw e;
|
|
656
|
+
} finally {
|
|
657
|
+
this._isStartingClientRecording = false;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
async resumeClientRecording() {
|
|
661
|
+
const localUserId = this._scene.localUser.getLocalUserId();
|
|
662
|
+
await (0, _error.handleRequestError)(() => this._api.resumeClientRecording(this._scene.sceneId, localUserId), _imports.ErrorModuleCode.FCR_ROOM, 'resume client recording failed');
|
|
663
|
+
return _type.FcrReturnCode.SUCCESS;
|
|
664
|
+
}
|
|
665
|
+
async stopClientRecording() {
|
|
666
|
+
const localUserId = this._scene.localUser.getLocalUserId();
|
|
667
|
+
|
|
668
|
+
// Step 1: 使用 mediaControl 的 stopClientRecording(即使失败也继续通知服务端)
|
|
669
|
+
const mediaControl = this._engine.getMediaControl();
|
|
670
|
+
try {
|
|
671
|
+
await mediaControl.stopClientRecording();
|
|
672
|
+
} catch (e) {
|
|
673
|
+
this.logger.error(`mediaControl.stopClientRecording failed: ${e.message}`);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
// Step 2: 无论 SDK 停止是否成功,都通知服务器停止录制
|
|
677
|
+
await (0, _error.handleRequestError)(() => this._api.stopClientRecording(this._scene.sceneId, localUserId), _imports.ErrorModuleCode.FCR_ROOM, 'stop client recording failed');
|
|
678
|
+
return _type.FcrReturnCode.SUCCESS;
|
|
679
|
+
}
|
|
680
|
+
isLocalClientRecordingActive() {
|
|
681
|
+
// 如果正在启动本地录制,也返回 true,避免在启动过程中触发错误的"其他人开启录制"提示
|
|
682
|
+
const mediaControl = this._engine.getMediaControl();
|
|
683
|
+
return this._isStartingClientRecording || mediaControl.isClientRecordingActive();
|
|
684
|
+
}
|
|
685
|
+
isClientRecordingOwnsCapture() {
|
|
686
|
+
const mediaControl = this._engine.getMediaControl();
|
|
687
|
+
return mediaControl.isClientRecordingOwnsCapture();
|
|
688
|
+
}
|
|
689
|
+
async resumeClientRecordingOwnCapture() {
|
|
690
|
+
const mediaControl = this._engine.getMediaControl();
|
|
691
|
+
await mediaControl.resumeClientRecordingOwnCapture();
|
|
692
|
+
}
|
|
693
|
+
async waitForScreenCaptureStopped() {
|
|
694
|
+
const mediaControl = this._engine.getMediaControl();
|
|
695
|
+
await mediaControl.waitForScreenCaptureStopped();
|
|
696
|
+
}
|
|
697
|
+
releaseClientRecordingOwnCapture() {
|
|
698
|
+
const mediaControl = this._engine.getMediaControl();
|
|
699
|
+
mediaControl.releaseClientRecordingOwnCapture();
|
|
700
|
+
}
|
|
577
701
|
getLiveStreamingState() {
|
|
578
702
|
let liveStreamingState = this._scene.getScenePropertiesByKeyPath('live.state');
|
|
579
703
|
if (liveStreamingState === _helpers.LIVE_STREAMING_STATE_VALUES.STARTED) {
|
|
@@ -613,6 +737,11 @@ class FcrBaseRoomControlImpl {
|
|
|
613
737
|
await this._liveStreamingAction(() => this._api.stopLiveStreaming(this._scene.sceneId), 'stop live streaming failed');
|
|
614
738
|
return _type.FcrReturnCode.SUCCESS;
|
|
615
739
|
}
|
|
740
|
+
hasActiveClientRecording() {
|
|
741
|
+
const userControl = this.getUserControl();
|
|
742
|
+
const users = userControl.getUserList();
|
|
743
|
+
return users.some(user => userControl.getUserClientRecordingState(user.userId));
|
|
744
|
+
}
|
|
616
745
|
getCloudRecordingState() {
|
|
617
746
|
const {
|
|
618
747
|
state,
|
|
@@ -641,6 +770,21 @@ class FcrBaseRoomControlImpl {
|
|
|
641
770
|
async _cleanup() {
|
|
642
771
|
this._scene.removeObserver(this._sceneObserver);
|
|
643
772
|
this._engine.removeObserver(this._engineObserver);
|
|
773
|
+
|
|
774
|
+
// 只有注册过录制观察者的 room control 才拥有录制生命周期,
|
|
775
|
+
// 其他房间(如等候室)的 cleanup 不应停止共享 mediaControl 上的录制。
|
|
776
|
+
if (this._isClientRecordingOwner) {
|
|
777
|
+
this._unregisterClientRecordingObserver();
|
|
778
|
+
try {
|
|
779
|
+
const mediaControl = this._engine.getMediaControl();
|
|
780
|
+
if (mediaControl.isClientRecordingActive()) {
|
|
781
|
+
await mediaControl.stopClientRecording();
|
|
782
|
+
this.logger.info('_cleanup: stopped client recording');
|
|
783
|
+
}
|
|
784
|
+
} catch (e) {
|
|
785
|
+
this.logger.error(`_cleanup: failed to stop client recording: ${e.message}`);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
644
788
|
this._sharedCache.getRoomCache(this._scene.sceneId).clear();
|
|
645
789
|
try {
|
|
646
790
|
return await Promise.all([this._chatRoomControl?.leave(), this.sharingControl?.getBoardControl().close(), this.sharingControl?.getAnnotationControl().close(), this._scene.leave()]);
|
|
@@ -60,6 +60,7 @@ class FcrInfinityRoomControlImpl extends _.FcrBaseRoomControlImpl {
|
|
|
60
60
|
this._interpreterControl = new _interpreterControl.FcrInterpreterControlImpl(api, scene, config, engine, chatConnection, sharedCache);
|
|
61
61
|
this._addLogObserver();
|
|
62
62
|
(0, _boardInitInfoHelper.addBoardInitInfoObserver)(this._scene, this._api, this.logger);
|
|
63
|
+
this._registerClientRecordingObserver();
|
|
63
64
|
this.logger.info(`initialized, room id: ${this._scene.sceneId}`);
|
|
64
65
|
}
|
|
65
66
|
getAnnouncement() {
|
|
@@ -114,13 +115,11 @@ class FcrInfinityRoomControlImpl extends _.FcrBaseRoomControlImpl {
|
|
|
114
115
|
_onLocalUserPermissionInfoDeleted(roomId, event) {
|
|
115
116
|
if ((0, _utils.hasBoardWritePermission)(event.permissionInfo)) {
|
|
116
117
|
this.logger.info(`remove board write permission`);
|
|
117
|
-
|
|
118
|
-
// this.getSharingControl().getBoardControl().getMainWindow()?.setWritable(false);
|
|
118
|
+
this.getSharingControl().getBoardControl().getMainWindow()?.setWritable(false);
|
|
119
119
|
}
|
|
120
120
|
if ((0, _utils.hasAnnotationWritePermission)(event.permissionInfo)) {
|
|
121
121
|
this.logger.info(`remove annotation write permission`);
|
|
122
|
-
|
|
123
|
-
// this.getSharingControl().getAnnotationControl().getMainWindow()?.setWritable(false);
|
|
122
|
+
this.getSharingControl().getAnnotationControl().getMainWindow()?.setWritable(false);
|
|
124
123
|
}
|
|
125
124
|
}
|
|
126
125
|
_addLogObserver() {
|
|
@@ -71,6 +71,7 @@ class FcrMainRoomControlImpl extends _.FcrBaseRoomControlImpl {
|
|
|
71
71
|
this._interpreterControl = new _interpreterControl.FcrInterpreterControlImpl(api, scene, config, engine, chatConnection, sharedCache);
|
|
72
72
|
this._addLogObserver();
|
|
73
73
|
(0, _boardInitInfoHelper.addBoardInitInfoObserver)(this._scene, this._api, this.logger);
|
|
74
|
+
this._registerClientRecordingObserver();
|
|
74
75
|
this.logger.info(`initialized, room id: ${this._scene.sceneId}`);
|
|
75
76
|
}
|
|
76
77
|
|
|
@@ -138,13 +139,11 @@ class FcrMainRoomControlImpl extends _.FcrBaseRoomControlImpl {
|
|
|
138
139
|
_onLocalUserPermissionInfoDeleted(roomId, event) {
|
|
139
140
|
if ((0, _utils2.hasBoardWritePermission)(event.permissionInfo)) {
|
|
140
141
|
this.logger.info(`remove board write permission`);
|
|
141
|
-
|
|
142
|
-
// this.getSharingControl().getBoardControl().getMainWindow()?.setWritable(false);
|
|
142
|
+
this.getSharingControl().getBoardControl().getMainWindow()?.setWritable(false);
|
|
143
143
|
}
|
|
144
144
|
if ((0, _utils2.hasAnnotationWritePermission)(event.permissionInfo)) {
|
|
145
145
|
this.logger.info(`remove annotation write permission`);
|
|
146
|
-
|
|
147
|
-
// this.getSharingControl().getAnnotationControl().getMainWindow()?.setWritable(false);
|
|
146
|
+
this.getSharingControl().getAnnotationControl().getMainWindow()?.setWritable(false);
|
|
148
147
|
}
|
|
149
148
|
}
|
|
150
149
|
_checkIfUpdateAnnotationMainWindow() {
|