fcr-ui-scene 3.7.8-rc.1 → 3.7.8-rc.2
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/creator/index.js +13 -19
- package/lib/electron/bootstrap-sdk.js +19 -2
- package/lib/electron/sdk-helper.js +6 -2
- package/lib/electron/until.js +3 -0
- package/lib/index.js +8 -1
- package/lib/modules/components/leave-meeting/store.base.d.ts +1 -0
- package/lib/modules/components/leave-meeting/store.base.js +46 -5
- package/lib/modules/dialog/dialogs/confirm-leave-meeting/index.d.ts +1 -0
- package/lib/modules/dialog/dialogs/confirm-leave-meeting/index.js +2 -1
- package/lib/modules/dialog/dialogs/share-screen-selection/index.js +0 -12
- package/lib/modules/share-screen/store.base.js +0 -2
- package/lib/modules/share-screen/store.electron.js +54 -31
- package/lib/modules/video-window/popover-watcher.js +4 -1
- package/lib/modules/video-window/store.js +7 -1
- package/lib/modules/video-window/view.js +14 -4
- package/lib/providers/screen-share/strategy/browser.js +1 -1
- package/lib/providers/window/main-window.js +0 -3
- package/lib/providers/window/renderer-window.d.ts +3 -0
- package/lib/providers/window/renderer-window.js +47 -4
- package/lib/providers/window/type.d.ts +1 -0
- package/lib/scenes/main-scene.d.ts +1 -0
- package/lib/scenes/main-scene.js +32 -1
- package/lib/utilities/logger.js +1 -1
- package/package.json +5 -5
- package/public/index.html +2 -149
- package/public/meeting-manager.js +391 -0
- package/installer/icons/favicon.ico +0 -0
- package/installer/icons/favicon.png +0 -0
- package/installer/icons/icon.png +0 -0
- package/installer/mac/entitlements.mac.plist +0 -20
- package/lib/modules/control-bar/reactor.d.ts +0 -2
- package/lib/modules/control-bar/reactor.js +0 -8
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 会议管理器 - 负责处理会议的生命周期管理
|
|
3
|
+
* 包括创建者初始化、会议启动、错误处理等功能
|
|
4
|
+
*/
|
|
5
|
+
class MeetingManager {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.creator = null;
|
|
8
|
+
this.uiScene = null;
|
|
9
|
+
|
|
10
|
+
this.sendExitedEventFlag = true;
|
|
11
|
+
this.lastInitParams = '';
|
|
12
|
+
|
|
13
|
+
this.bindGlobalMethods();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 重新加载创建者
|
|
18
|
+
* @param {string} stringInitParams - 初始化参数字符串
|
|
19
|
+
*/
|
|
20
|
+
reloadCreator(stringInitParams) {
|
|
21
|
+
try {
|
|
22
|
+
const config = JSON.parse(stringInitParams);
|
|
23
|
+
this.creator = new FcrUIScene.FcrUISceneCreator(config);
|
|
24
|
+
this.logInfo('Creator reloaded successfully');
|
|
25
|
+
} catch (error) {
|
|
26
|
+
this.logError('Failed to parse init options:', error);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 创建或初始化创建者
|
|
32
|
+
* @param {Object} config - 配置对象
|
|
33
|
+
*/
|
|
34
|
+
createOrInitCreator(config) {
|
|
35
|
+
try {
|
|
36
|
+
// 如果存在旧的创建者,先释放
|
|
37
|
+
if (this.creator) {
|
|
38
|
+
this.logInfo('Creator exists, releasing previous creator');
|
|
39
|
+
this.releasePreviousScene();
|
|
40
|
+
this.creator.release();
|
|
41
|
+
this.creator = undefined;
|
|
42
|
+
}
|
|
43
|
+
} catch (error) {
|
|
44
|
+
this.logError('Failed to release creator:', error);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 创建新的创建者
|
|
48
|
+
this.lastInitParams = JSON.stringify(config);
|
|
49
|
+
this.logInfo(`Creating new creator with config: ${this.lastInitParams}`);
|
|
50
|
+
this.creator = new FcrUIScene.FcrUISceneCreator(config);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* 释放之前的场景
|
|
55
|
+
*/
|
|
56
|
+
releasePreviousScene() {
|
|
57
|
+
if (this.uiScene) {
|
|
58
|
+
this.sendExitedEventFlag = false;
|
|
59
|
+
this.uiScene.exit();
|
|
60
|
+
this.uiScene = null;
|
|
61
|
+
this.logInfo('Previous UI scene released');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 启动会议
|
|
67
|
+
* @param {Object} launchOptions - 启动选项
|
|
68
|
+
*/
|
|
69
|
+
launchMeeting(launchOptions) {
|
|
70
|
+
const { data, lastInitParams: initParamsFromMainProcess } = launchOptions;
|
|
71
|
+
|
|
72
|
+
this.logInfo(`Launching meeting with params: ${initParamsFromMainProcess}`);
|
|
73
|
+
|
|
74
|
+
// 检查是否需要重新加载创建者
|
|
75
|
+
if (initParamsFromMainProcess !== this.lastInitParams) {
|
|
76
|
+
this.logInfo('Init params changed, reloading creator');
|
|
77
|
+
this.lastInitParams = initParamsFromMainProcess;
|
|
78
|
+
this.reloadCreator(initParamsFromMainProcess);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// 清理之前的场景
|
|
82
|
+
this.cleanupPreviousScene();
|
|
83
|
+
|
|
84
|
+
// 设置UI状态
|
|
85
|
+
this.setFullScreenFailureComp(false);
|
|
86
|
+
this.setLoading(true);
|
|
87
|
+
|
|
88
|
+
// 绑定错误处理事件
|
|
89
|
+
this.bindErrorHandlers();
|
|
90
|
+
|
|
91
|
+
// 注册小部件
|
|
92
|
+
this.registerWidgets(data);
|
|
93
|
+
|
|
94
|
+
// 启动场景
|
|
95
|
+
this.startUIScene(data);
|
|
96
|
+
|
|
97
|
+
// 添加观察者
|
|
98
|
+
this.addSceneObservers();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* 清理之前的场景
|
|
103
|
+
*/
|
|
104
|
+
cleanupPreviousScene() {
|
|
105
|
+
try {
|
|
106
|
+
if (this.uiScene) {
|
|
107
|
+
this.logInfo('Cleaning up previous UI scene');
|
|
108
|
+
this.uiScene.exit();
|
|
109
|
+
this.sendExitedEventFlag = false;
|
|
110
|
+
}
|
|
111
|
+
} catch (error) {
|
|
112
|
+
this.logError('Error during scene cleanup:', error);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* 绑定错误处理事件
|
|
118
|
+
*/
|
|
119
|
+
bindErrorHandlers() {
|
|
120
|
+
const confirmBtn = document.querySelector('#fcr-launch-failure-confirm-btn');
|
|
121
|
+
if (confirmBtn) {
|
|
122
|
+
confirmBtn.removeEventListener('click', this.handleConfirmClick);
|
|
123
|
+
confirmBtn.addEventListener('click', this.handleConfirmClick.bind(this));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* 注册小部件
|
|
129
|
+
* @param {Object} data - 数据对象
|
|
130
|
+
*/
|
|
131
|
+
registerWidgets(data) {
|
|
132
|
+
const { widgets, ...others } = data;
|
|
133
|
+
if (widgets && Array.isArray(widgets)) {
|
|
134
|
+
widgets.forEach(widget => {
|
|
135
|
+
this.creator.registerWidget(widget);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* 启动UI场景
|
|
142
|
+
* @param {Object} data - 数据对象
|
|
143
|
+
*/
|
|
144
|
+
startUIScene(data) {
|
|
145
|
+
const { widgets, ...others } = data;
|
|
146
|
+
|
|
147
|
+
this.uiScene = this.creator.launch(
|
|
148
|
+
others,
|
|
149
|
+
() => {
|
|
150
|
+
this.logInfo('UI scene closed callback');
|
|
151
|
+
window.runtime.getCurrentBrowserWindow().hide();
|
|
152
|
+
},
|
|
153
|
+
() => { }, // 空回调
|
|
154
|
+
() => { }, // 空回调
|
|
155
|
+
document.getElementById('root')
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* 添加场景观察者
|
|
161
|
+
*/
|
|
162
|
+
addSceneObservers() {
|
|
163
|
+
this.uiScene.addObserver({
|
|
164
|
+
onLaunchSuccess: () => this.handleLaunchSuccess(),
|
|
165
|
+
onLaunchFailure: (roomId, error) => this.handleLaunchFailure(roomId, error),
|
|
166
|
+
onExited: (roomId, reason) => this.handleSceneExited(roomId, reason),
|
|
167
|
+
onWidgetClicked: (widgetId) => this.handleWidgetClicked(widgetId),
|
|
168
|
+
onUserTokenWillExpire: () => this.handleUserTokenWillExpire()
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* 处理启动成功
|
|
174
|
+
*/
|
|
175
|
+
handleLaunchSuccess() {
|
|
176
|
+
this.setLoading(false);
|
|
177
|
+
this.sendExitedEventFlag = true;
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
const roomProvider = this.uiScene._objectManager.getObject('roomProvider');
|
|
181
|
+
if (!roomProvider) {
|
|
182
|
+
throw new Error('roomProvider not found in uiScene');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const currentRoomControl = roomProvider.currentRoomControl;
|
|
186
|
+
if (!currentRoomControl) {
|
|
187
|
+
throw new Error('currentRoomControl not found in uiScene');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const roomInfo = currentRoomControl.getRoomInfo();
|
|
191
|
+
if (!roomInfo) {
|
|
192
|
+
throw new Error('roomInfo not found in uiScene');
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const { roomName, roomId } = roomInfo;
|
|
196
|
+
document.querySelector('title').innerText = roomName;
|
|
197
|
+
window.cppSdkHelper.launchSuccess(roomId);
|
|
198
|
+
} catch (error) {
|
|
199
|
+
this.logError('Error in launch success handler:', error);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* 处理启动失败
|
|
205
|
+
* @param {string} roomId - 房间ID
|
|
206
|
+
* @param {Object} error - 错误对象
|
|
207
|
+
*/
|
|
208
|
+
handleLaunchFailure(roomId, error) {
|
|
209
|
+
const errorCode = Number(error.code);
|
|
210
|
+
let errorMessage = this.getErrorMessage(errorCode, error.message);
|
|
211
|
+
|
|
212
|
+
this.setFullScreenFailureComp(true, errorMessage);
|
|
213
|
+
window.cppSdkHelper.launchFailure(roomId, errorCode);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* 获取错误消息
|
|
218
|
+
* @param {number} errorCode - 错误代码
|
|
219
|
+
* @param {string} defaultMessage - 默认错误消息
|
|
220
|
+
* @returns {string} 错误消息
|
|
221
|
+
*/
|
|
222
|
+
getErrorMessage(errorCode, defaultMessage) {
|
|
223
|
+
const errorCodeMap = {
|
|
224
|
+
732403100: 'fmt_lock_error',
|
|
225
|
+
631735290: 'fmt_lock_error',
|
|
226
|
+
732403101: 'fmt_pc_room_not_exist_error',
|
|
227
|
+
732403103: 'fmt_host_leave_error',
|
|
228
|
+
720410100: 'fmt_end_error'
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
const errorKey = errorCodeMap[errorCode];
|
|
232
|
+
if (errorKey) {
|
|
233
|
+
return window._transI18n(errorKey);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return `Error: code=${errorCode}, message=${defaultMessage}`;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* 处理场景退出
|
|
241
|
+
* @param {string} roomId - 房间ID
|
|
242
|
+
* @param {string} reason - 退出原因
|
|
243
|
+
*/
|
|
244
|
+
handleSceneExited(roomId, reason) {
|
|
245
|
+
if (!this.sendExitedEventFlag) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
this.logInfo('UI scene exited');
|
|
250
|
+
window.cppSdkHelper.exitedMeeting(roomId, reason);
|
|
251
|
+
this.uiScene = null;
|
|
252
|
+
|
|
253
|
+
setTimeout(() => {
|
|
254
|
+
this.logInfo('UI scene exited callback');
|
|
255
|
+
window.runtime.getCurrentBrowserWindow().hide();
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* 处理小部件点击
|
|
261
|
+
* @param {string} widgetId - 小部件ID
|
|
262
|
+
*/
|
|
263
|
+
handleWidgetClicked(widgetId) {
|
|
264
|
+
window.cppSdkHelper.onWidgetClicked(widgetId);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* 处理用户令牌即将过期
|
|
269
|
+
*/
|
|
270
|
+
handleUserTokenWillExpire() {
|
|
271
|
+
window.cppSdkHelper.onUserTokenWillExpire();
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* 退出UI场景
|
|
276
|
+
*/
|
|
277
|
+
exitUiScene() {
|
|
278
|
+
try {
|
|
279
|
+
if (!this.uiScene) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
this.uiScene.exit();
|
|
283
|
+
this.lastInitParams = '';
|
|
284
|
+
} catch (error) {
|
|
285
|
+
window.cppSdkHelper.exitedMeeting(roomId, FcrUIExitReason.USER_QUIT);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* 处理确认按钮点击
|
|
291
|
+
*/
|
|
292
|
+
handleConfirmClick() {
|
|
293
|
+
this.setFullScreenFailureComp(false);
|
|
294
|
+
this.logInfo('Error confirmation button clicked');
|
|
295
|
+
window.runtime.getCurrentBrowserWindow().hide();
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* 绑定全局方法
|
|
300
|
+
*/
|
|
301
|
+
bindGlobalMethods() {
|
|
302
|
+
window.cppSdkHelper.onCreatorInit = (config) => {
|
|
303
|
+
window.__AgoraMutex.dispatch(() => {
|
|
304
|
+
this.createOrInitCreator(config);
|
|
305
|
+
});
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
window.cppSdkHelper.onSettingOpen = () => {
|
|
309
|
+
this.creator.openSetting();
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
window.cppSdkHelper.onSettingClose = () => {
|
|
313
|
+
this.creator.closeSetting();
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
window.cppSdkHelper.onSetParameters = (parameters) => {
|
|
317
|
+
this.creator.setParameters(parameters);
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
window.cppSdkHelper.onRenewUserToken = (token) => {
|
|
321
|
+
this.creator.renewUserToken(token);
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
window.cppSdkHelper.exitUiScene = () => {
|
|
325
|
+
window.__AgoraMutex.dispatch(() => {
|
|
326
|
+
this.exitUiScene();
|
|
327
|
+
});
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
window.cppSdkHelper.onLaunchMeeting = (launchOptions) => {
|
|
331
|
+
window.__AgoraMutex.dispatch(() => {
|
|
332
|
+
this.launchMeeting(launchOptions);
|
|
333
|
+
})
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* 设置加载状态
|
|
339
|
+
* @param {boolean} visible - 是否显示加载状态
|
|
340
|
+
*/
|
|
341
|
+
setLoading(visible) {
|
|
342
|
+
const dom = document.querySelector('#launch-loading');
|
|
343
|
+
if (dom) {
|
|
344
|
+
dom.style.display = visible ? 'flex' : 'none';
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* 设置全屏失败组件
|
|
350
|
+
* @param {boolean} visible - 是否显示
|
|
351
|
+
* @param {string} errorMsg - 错误消息
|
|
352
|
+
*/
|
|
353
|
+
setFullScreenFailureComp(visible, errorMsg) {
|
|
354
|
+
this.setLoading(false);
|
|
355
|
+
const dom = document.querySelector('#fcr-launch-failure-comp');
|
|
356
|
+
const btnTextDom = document.querySelector('#fcr-launch-failure-btn-text');
|
|
357
|
+
|
|
358
|
+
if (dom) {
|
|
359
|
+
if (visible) {
|
|
360
|
+
dom.style.display = 'flex';
|
|
361
|
+
btnTextDom.innerText = window.$$agora_language === 'zh' ? '我已知悉' : 'I know';
|
|
362
|
+
if (errorMsg) {
|
|
363
|
+
const msgDom = document.querySelector('#fcr-launch-failure-error-info');
|
|
364
|
+
msgDom.innerText = errorMsg;
|
|
365
|
+
}
|
|
366
|
+
} else {
|
|
367
|
+
dom.style.display = 'none';
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* 记录信息日志
|
|
374
|
+
* @param {string} message - 日志消息
|
|
375
|
+
*/
|
|
376
|
+
logInfo(message) {
|
|
377
|
+
window.__AgoraLogger.info(`MEETING MANAGER: ${message}`);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* 记录错误日志
|
|
382
|
+
* @param {string} message - 错误消息
|
|
383
|
+
* @param {Error} error - 错误对象
|
|
384
|
+
*/
|
|
385
|
+
logError(message, error) {
|
|
386
|
+
window.__AgoraLogger.error(`MEETING MANAGER: ${message}`, error);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// 初始化会议管理器
|
|
391
|
+
const meetingManager = new MeetingManager();
|
|
Binary file
|
|
Binary file
|
package/installer/icons/icon.png
DELETED
|
Binary file
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
-
<plist version="1.0">
|
|
4
|
-
<dict>
|
|
5
|
-
<key>com.apple.security.cs.allow-jit</key>
|
|
6
|
-
<true/>
|
|
7
|
-
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
|
8
|
-
<true/>
|
|
9
|
-
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
|
|
10
|
-
<true/>
|
|
11
|
-
<key>com.apple.security.device.audio-input</key>
|
|
12
|
-
<true/>
|
|
13
|
-
<key>com.apple.security.device.camera</key>
|
|
14
|
-
<true/>
|
|
15
|
-
<key>com.apple.security.network.server</key>
|
|
16
|
-
<true />
|
|
17
|
-
<key>com.apple.security.network.client</key>
|
|
18
|
-
<true />
|
|
19
|
-
</dict>
|
|
20
|
-
</plist>
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
5
|
-
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
6
|
-
var FcrUIMouseEventReactor = /*#__PURE__*/(0, _createClass2["default"])(function FcrUIMouseEventReactor() {
|
|
7
|
-
(0, _classCallCheck2["default"])(this, FcrUIMouseEventReactor);
|
|
8
|
-
});
|