jssz-meeting-component 1.2.1 → 1.2.3
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/dist/index.esm.js +1888 -1718
- package/dist/index.umd.js +1 -1
- package/dist/src/components/call.vue.d.ts.map +1 -1
- package/dist/src/components/meeting.vue.d.ts.map +1 -1
- package/dist/src/internal/ManageMembers.vue.d.ts.map +1 -1
- package/dist/src/internal/meeting-header.vue.d.ts.map +1 -1
- package/dist/src/utils/eventBus.d.ts +1 -0
- package/dist/src/utils/eventBus.d.ts.map +1 -1
- package/dist/src/utils/meeting-message-handlers.d.ts.map +1 -1
- package/dist/src/utils/srtc.d.ts.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -20339,7 +20339,7 @@ const MEETING_BROADCAST_TOPIC = "/meeting";
|
|
|
20339
20339
|
const MEETING_SERVER_TOPIC = "/meeting/server";
|
|
20340
20340
|
const DEFAULT_MQTT_PATH = "/mqtt";
|
|
20341
20341
|
const DEFAULT_REQUEST_TIMEOUT_MS = 15e3;
|
|
20342
|
-
const MQTT_CLIENT_INSTANCE_STORAGE_KEY = "JS_MQTT_CLIENT_INSTANCE_ID";
|
|
20342
|
+
const MQTT_CLIENT_INSTANCE_STORAGE_KEY$1 = "JS_MQTT_CLIENT_INSTANCE_ID";
|
|
20343
20343
|
let runtimeContext = null;
|
|
20344
20344
|
let offBroadcastMessage = null;
|
|
20345
20345
|
let offResponseMessage = null;
|
|
@@ -20380,7 +20380,6 @@ function normalizeBrokerUrl(baseUrl) {
|
|
|
20380
20380
|
throw new Error("MQTT 初始化失败:mqttUrl 为空");
|
|
20381
20381
|
}
|
|
20382
20382
|
const normalizedScheme = trimmed.startsWith("tcp://") ? `mqtt://${trimmed.slice("tcp://".length)}` : trimmed;
|
|
20383
|
-
console.log("normalizedScheme:", normalizedScheme);
|
|
20384
20383
|
const withoutTrailingSlash = normalizedScheme.replace(/\/+$/g, "");
|
|
20385
20384
|
if (withoutTrailingSlash.endsWith(DEFAULT_MQTT_PATH)) {
|
|
20386
20385
|
return withoutTrailingSlash;
|
|
@@ -20422,12 +20421,12 @@ function buildResponseTopic(currentDevice) {
|
|
|
20422
20421
|
}
|
|
20423
20422
|
function getBrowserMqttInstanceId() {
|
|
20424
20423
|
try {
|
|
20425
|
-
const cached = sessionStorage.getItem(MQTT_CLIENT_INSTANCE_STORAGE_KEY);
|
|
20424
|
+
const cached = sessionStorage.getItem(MQTT_CLIENT_INSTANCE_STORAGE_KEY$1);
|
|
20426
20425
|
if (cached) {
|
|
20427
20426
|
return cached;
|
|
20428
20427
|
}
|
|
20429
20428
|
const nextId = typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" ? crypto.randomUUID().replace(/-/g, "").slice(0, 12) : Math.random().toString(36).slice(2, 14);
|
|
20430
|
-
sessionStorage.setItem(MQTT_CLIENT_INSTANCE_STORAGE_KEY, nextId);
|
|
20429
|
+
sessionStorage.setItem(MQTT_CLIENT_INSTANCE_STORAGE_KEY$1, nextId);
|
|
20431
20430
|
return nextId;
|
|
20432
20431
|
} catch {
|
|
20433
20432
|
return Math.random().toString(36).slice(2, 14);
|
|
@@ -36514,6 +36513,12 @@ function getCurrentMeetingTabId() {
|
|
|
36514
36513
|
}
|
|
36515
36514
|
return tabId;
|
|
36516
36515
|
}
|
|
36516
|
+
function setMeetingTabIdForWindow(targetWindow, tabId) {
|
|
36517
|
+
targetWindow.sessionStorage.setItem(TAB_ID_KEY, tabId);
|
|
36518
|
+
}
|
|
36519
|
+
function createMeetingTabId() {
|
|
36520
|
+
return createTabId();
|
|
36521
|
+
}
|
|
36517
36522
|
function getActiveMeetingOwner() {
|
|
36518
36523
|
try {
|
|
36519
36524
|
const raw = localStorage.getItem(ACTIVE_MEETING_OWNER_KEY);
|
|
@@ -37735,7 +37740,6 @@ const srtc = new Tn({
|
|
|
37735
37740
|
});
|
|
37736
37741
|
srtc.onNotifyChannelEvent = async (evt) => {
|
|
37737
37742
|
var _a25, _b25, _c2, _d, _e, _f2, _g2, _h, _i2, _j, _k, _l2, _m;
|
|
37738
|
-
console.log(evt);
|
|
37739
37743
|
switch (evt.type) {
|
|
37740
37744
|
case on.CONNECTION_QUALITY_CHANGED:
|
|
37741
37745
|
handleConnectionQualityChanged(evt.data);
|
|
@@ -37895,8 +37899,45 @@ async function joinRoom() {
|
|
|
37895
37899
|
const meetingInfo = JSON.parse(
|
|
37896
37900
|
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
37897
37901
|
);
|
|
37898
|
-
|
|
37899
|
-
|
|
37902
|
+
try {
|
|
37903
|
+
await srtc.join(meetingInfo.meetingToken);
|
|
37904
|
+
await afterJoin();
|
|
37905
|
+
} catch (error) {
|
|
37906
|
+
await handleJoinRoomFailure(meetingInfo, error);
|
|
37907
|
+
throw error;
|
|
37908
|
+
}
|
|
37909
|
+
}
|
|
37910
|
+
async function handleJoinRoomFailure(meetingInfo, error) {
|
|
37911
|
+
console.error("加入 SRTC 频道失败", error);
|
|
37912
|
+
stopNetworkQualityMonitor();
|
|
37913
|
+
await cleanupSessionMediaState();
|
|
37914
|
+
if (meetingInfo == null ? void 0 : meetingInfo.meetingId) {
|
|
37915
|
+
try {
|
|
37916
|
+
await getMeetingLeave({
|
|
37917
|
+
meetingId: meetingInfo.meetingId,
|
|
37918
|
+
memberId: getUserId()
|
|
37919
|
+
});
|
|
37920
|
+
} catch (leaveError) {
|
|
37921
|
+
console.error("SDK 入频道失败后的离会补偿失败", leaveError);
|
|
37922
|
+
}
|
|
37923
|
+
}
|
|
37924
|
+
meetingStore$1.clearMembers();
|
|
37925
|
+
try {
|
|
37926
|
+
sessionStorage.removeItem(SELF_MEDIA_PREFS_KEY);
|
|
37927
|
+
} catch (_2) {
|
|
37928
|
+
}
|
|
37929
|
+
clearActiveMeetingOwnership(
|
|
37930
|
+
meetingInfo == null ? void 0 : meetingInfo.meetingId,
|
|
37931
|
+
getCurrentMeetingTabId()
|
|
37932
|
+
);
|
|
37933
|
+
sessionStorage.removeItem("JS_MEETING_INFO");
|
|
37934
|
+
sessionStorage.removeItem("joinTime");
|
|
37935
|
+
joinTime.value = 0;
|
|
37936
|
+
setCallStatus("end");
|
|
37937
|
+
closeMeeting();
|
|
37938
|
+
closeCall();
|
|
37939
|
+
logoutRoomAction();
|
|
37940
|
+
showNotification("加入音视频频道失败,已自动退出,请稍后重试", "error", 6e3);
|
|
37900
37941
|
}
|
|
37901
37942
|
async function afterJoin() {
|
|
37902
37943
|
const _joinTime = sessionStorage.getItem("joinTime");
|
|
@@ -37919,7 +37960,6 @@ async function afterJoin() {
|
|
|
37919
37960
|
item.videoLoadFailed = false;
|
|
37920
37961
|
});
|
|
37921
37962
|
for (const userinfo of Object.values(srtc.getUsersInfo(true))) {
|
|
37922
|
-
console.log("userinfo", userinfo);
|
|
37923
37963
|
await ensurePreferredRemoteVideo(userinfo);
|
|
37924
37964
|
}
|
|
37925
37965
|
scheduleMountTracks(0);
|
|
@@ -38761,8 +38801,13 @@ function handleMeetingEvent(event, data) {
|
|
|
38761
38801
|
emitter.emit("injuryReport", data);
|
|
38762
38802
|
break;
|
|
38763
38803
|
case "2020":
|
|
38804
|
+
console.log("2020", data);
|
|
38764
38805
|
emitter.emit("onlineMember", data);
|
|
38765
38806
|
break;
|
|
38807
|
+
case "2099":
|
|
38808
|
+
console.log("2099", data);
|
|
38809
|
+
emitter.emit("meetingEnd", data);
|
|
38810
|
+
break;
|
|
38766
38811
|
}
|
|
38767
38812
|
}
|
|
38768
38813
|
function installMeetingMessageHandlers() {
|
|
@@ -40891,1484 +40936,1898 @@ const _sfc_main$r = /* @__PURE__ */ defineComponent({
|
|
|
40891
40936
|
}
|
|
40892
40937
|
});
|
|
40893
40938
|
const DeviceSelector = /* @__PURE__ */ _export_sfc(_sfc_main$r, [["__scopeId", "data-v-ced67da8"]]);
|
|
40894
|
-
const _hoisted_1$o =
|
|
40895
|
-
|
|
40896
|
-
class: "
|
|
40897
|
-
|
|
40898
|
-
const _hoisted_2$m = { class: "js-call-dialog-container" };
|
|
40899
|
-
const _hoisted_3$l = { class: "status-bar" };
|
|
40900
|
-
const _hoisted_4$j = { class: "status-left" };
|
|
40901
|
-
const _hoisted_5$g = {
|
|
40902
|
-
key: 0,
|
|
40903
|
-
class: "caller-info",
|
|
40904
|
-
title: "来电人"
|
|
40905
|
-
};
|
|
40906
|
-
const _hoisted_6$f = {
|
|
40907
|
-
class: "avatar",
|
|
40908
|
-
style: { "width": "35px", "height": "35px", "font-size": "16px" }
|
|
40939
|
+
const _hoisted_1$o = ["title"];
|
|
40940
|
+
const _hoisted_2$m = {
|
|
40941
|
+
class: "signal-bars",
|
|
40942
|
+
"aria-hidden": "true"
|
|
40909
40943
|
};
|
|
40910
|
-
const
|
|
40911
|
-
const _hoisted_8$d = { class: "caller-name" };
|
|
40912
|
-
const _hoisted_9$b = {
|
|
40944
|
+
const _hoisted_3$l = {
|
|
40913
40945
|
key: 0,
|
|
40914
|
-
class: "
|
|
40946
|
+
class: "signal-text"
|
|
40915
40947
|
};
|
|
40916
|
-
const
|
|
40917
|
-
const
|
|
40918
|
-
const
|
|
40919
|
-
const
|
|
40920
|
-
const
|
|
40921
|
-
const _hoisted_15$6 = { class: "avatar" };
|
|
40922
|
-
const _hoisted_16$6 = { class: "video-loading-overlay" };
|
|
40923
|
-
const _hoisted_17$5 = { class: "video-loading-text" };
|
|
40924
|
-
const _hoisted_18$5 = { class: "video-loading-overlay failed" };
|
|
40925
|
-
const _hoisted_19$5 = ["disabled", "onClick"];
|
|
40926
|
-
const _hoisted_20$5 = { class: "video-meta" };
|
|
40927
|
-
const _hoisted_21$3 = { class: "member-name" };
|
|
40928
|
-
const _hoisted_22$3 = {
|
|
40948
|
+
const _hoisted_4$j = { class: "network-quality-popup-shell" };
|
|
40949
|
+
const _hoisted_5$g = { class: "popup-header" };
|
|
40950
|
+
const _hoisted_6$f = { class: "popup-header-actions" };
|
|
40951
|
+
const _hoisted_7$e = { class: "popup-summary" };
|
|
40952
|
+
const _hoisted_8$d = {
|
|
40929
40953
|
key: 0,
|
|
40930
|
-
class: "
|
|
40931
|
-
};
|
|
40932
|
-
const _hoisted_23$3 = {
|
|
40933
|
-
key: 1,
|
|
40934
|
-
class: "video-empty"
|
|
40954
|
+
class: "popup-reasons"
|
|
40935
40955
|
};
|
|
40936
|
-
const
|
|
40956
|
+
const _hoisted_9$b = { class: "popup-section" };
|
|
40957
|
+
const _hoisted_10$b = { class: "popup-grid" };
|
|
40958
|
+
const _hoisted_11$a = { class: "popup-item-label" };
|
|
40959
|
+
const _hoisted_12$a = { class: "popup-item-value" };
|
|
40960
|
+
const _hoisted_13$8 = { class: "popup-section" };
|
|
40961
|
+
const _hoisted_14$7 = { class: "popup-grid" };
|
|
40962
|
+
const _hoisted_15$6 = { class: "popup-item-label" };
|
|
40963
|
+
const _hoisted_16$6 = { class: "popup-item-value" };
|
|
40964
|
+
const _hoisted_17$5 = { class: "popup-header" };
|
|
40965
|
+
const _hoisted_18$5 = { class: "popup-header-actions" };
|
|
40966
|
+
const _hoisted_19$5 = { class: "popup-section-container" };
|
|
40967
|
+
const _hoisted_20$5 = ["onClick"];
|
|
40968
|
+
const _hoisted_21$3 = { class: "detail-section-main" };
|
|
40969
|
+
const _hoisted_22$3 = { class: "popup-section-title" };
|
|
40970
|
+
const _hoisted_23$3 = { class: "popup-section-count" };
|
|
40971
|
+
const _hoisted_24$3 = { class: "detail-section-icon" };
|
|
40937
40972
|
const _hoisted_25$3 = {
|
|
40938
40973
|
key: 0,
|
|
40939
|
-
class: "
|
|
40974
|
+
class: "metric-card-list"
|
|
40940
40975
|
};
|
|
40941
|
-
const _hoisted_26$3 = {
|
|
40942
|
-
const _hoisted_27$3 = { class: "
|
|
40943
|
-
const _hoisted_28$3 = {
|
|
40976
|
+
const _hoisted_26$3 = { class: "metric-card-header" };
|
|
40977
|
+
const _hoisted_27$3 = { class: "metric-card-title" };
|
|
40978
|
+
const _hoisted_28$3 = { class: "metric-card-subtitle" };
|
|
40979
|
+
const _hoisted_29$2 = { class: "metric-card-grid" };
|
|
40980
|
+
const _hoisted_30$2 = { class: "popup-item-label" };
|
|
40981
|
+
const _hoisted_31$1 = { class: "popup-item-value" };
|
|
40982
|
+
const _hoisted_32$1 = {
|
|
40944
40983
|
key: 1,
|
|
40945
|
-
class: "
|
|
40984
|
+
class: "popup-empty"
|
|
40946
40985
|
};
|
|
40947
|
-
const DEFAULT_SUB_VIDEO_HEIGHT = 110;
|
|
40948
|
-
const DEFAULT_SUB_VIDEO_WIDTH = 190;
|
|
40949
|
-
const SUB_VIDEO_GAP = 12;
|
|
40950
|
-
const CONTROL_BAR_HEIGHT = 90;
|
|
40951
|
-
const STATUS_BAR_HEIGHT = 48;
|
|
40952
40986
|
const _sfc_main$q = /* @__PURE__ */ defineComponent({
|
|
40953
|
-
__name: "
|
|
40987
|
+
__name: "NetworkQualitySignal",
|
|
40954
40988
|
props: {
|
|
40955
40989
|
theme: { default: "dark" },
|
|
40956
|
-
|
|
40957
|
-
|
|
40990
|
+
size: { default: "default" },
|
|
40991
|
+
showText: { type: Boolean, default: false }
|
|
40958
40992
|
},
|
|
40959
40993
|
setup(__props) {
|
|
40960
|
-
const { meState: meState2 } = storeToRefs(useMeetingStore());
|
|
40961
40994
|
const props = __props;
|
|
40962
|
-
const
|
|
40995
|
+
const triggerRef = ref(null);
|
|
40996
|
+
const showPopup = ref(false);
|
|
40997
|
+
const advancedOpen = ref(false);
|
|
40998
|
+
const collapsedSections = ref({});
|
|
40999
|
+
const advancedDetails = ref();
|
|
41000
|
+
let detailTimer = null;
|
|
40963
41001
|
const themeClass = computed(() => `theme-${props.theme}`);
|
|
40964
|
-
|
|
40965
|
-
|
|
40966
|
-
|
|
40967
|
-
|
|
40968
|
-
|
|
40969
|
-
|
|
40970
|
-
|
|
40971
|
-
|
|
40972
|
-
|
|
40973
|
-
|
|
40974
|
-
|
|
40975
|
-
|
|
40976
|
-
|
|
40977
|
-
|
|
40978
|
-
|
|
40979
|
-
|
|
40980
|
-
|
|
40981
|
-
|
|
41002
|
+
function formatValue(value, suffix = "", digits = 0) {
|
|
41003
|
+
if (typeof value !== "number" || Number.isNaN(value)) return "--";
|
|
41004
|
+
return `${value.toFixed(digits)}${suffix}`;
|
|
41005
|
+
}
|
|
41006
|
+
function formatMetricNumber(value, suffix = "", digits = 0) {
|
|
41007
|
+
if (typeof value !== "number" || Number.isNaN(value)) return "--";
|
|
41008
|
+
return `${value.toFixed(digits)}${suffix}`;
|
|
41009
|
+
}
|
|
41010
|
+
function formatBytes(value) {
|
|
41011
|
+
if (typeof value !== "number" || Number.isNaN(value)) return "--";
|
|
41012
|
+
if (value >= 1024 * 1024) return `${(value / (1024 * 1024)).toFixed(2)} MB`;
|
|
41013
|
+
if (value >= 1024) return `${(value / 1024).toFixed(1)} KB`;
|
|
41014
|
+
return `${value.toFixed(0)} B`;
|
|
41015
|
+
}
|
|
41016
|
+
function formatDimension(width, height) {
|
|
41017
|
+
if (!width || !height) return "--";
|
|
41018
|
+
return `${width} x ${height}`;
|
|
41019
|
+
}
|
|
41020
|
+
function formatLossRate(value) {
|
|
41021
|
+
if (typeof value !== "number" || Number.isNaN(value)) return "--";
|
|
41022
|
+
return `${value.toFixed(1)}%`;
|
|
41023
|
+
}
|
|
41024
|
+
function formatMos(value) {
|
|
41025
|
+
if (typeof value !== "number" || value <= 0 || Number.isNaN(value)) return "--";
|
|
41026
|
+
return value.toFixed(1);
|
|
41027
|
+
}
|
|
41028
|
+
function formatUpdatedAt(timestamp) {
|
|
41029
|
+
if (!timestamp) return "--";
|
|
41030
|
+
const date = new Date(timestamp);
|
|
41031
|
+
const hh = String(date.getHours()).padStart(2, "0");
|
|
41032
|
+
const mm = String(date.getMinutes()).padStart(2, "0");
|
|
41033
|
+
const ss = String(date.getSeconds()).padStart(2, "0");
|
|
41034
|
+
return `${hh}:${mm}:${ss}`;
|
|
41035
|
+
}
|
|
41036
|
+
function formatReason(value) {
|
|
41037
|
+
return value || "--";
|
|
41038
|
+
}
|
|
41039
|
+
function getMemberNameById(memberId) {
|
|
41040
|
+
var _a25;
|
|
41041
|
+
if (!memberId) return "";
|
|
41042
|
+
const matched = members.value.find(
|
|
41043
|
+
(member) => {
|
|
41044
|
+
var _a26;
|
|
41045
|
+
return ((_a26 = member == null ? void 0 : member.member) == null ? void 0 : _a26.memberId) === String(memberId);
|
|
40982
41046
|
}
|
|
40983
|
-
},
|
|
40984
|
-
{
|
|
40985
|
-
immediate: true
|
|
40986
|
-
}
|
|
40987
|
-
);
|
|
40988
|
-
const isCalling = computed(() => callStatus.value === "calling");
|
|
40989
|
-
const isReceiving = computed(() => callStatus.value === "receiving");
|
|
40990
|
-
const isConnected = computed(() => callStatus.value === "connected");
|
|
40991
|
-
const isListening = computed(() => callStatus.value === "listening");
|
|
40992
|
-
const isForcibleInsertion = computed(
|
|
40993
|
-
() => callStatus.value === "forcible-insertion"
|
|
40994
|
-
);
|
|
40995
|
-
const visibleMembers = computed(() => {
|
|
40996
|
-
return members.value.filter(
|
|
40997
|
-
(item) => item.roleType !== "4" && item.joinStaus === "1" && (!isListening.value || item.member.memberId !== getUserId())
|
|
40998
41047
|
);
|
|
40999
|
-
|
|
41000
|
-
|
|
41001
|
-
|
|
41002
|
-
|
|
41003
|
-
|
|
41004
|
-
|
|
41005
|
-
|
|
41006
|
-
|
|
41007
|
-
}
|
|
41008
|
-
|
|
41009
|
-
|
|
41010
|
-
|
|
41011
|
-
|
|
41048
|
+
return ((_a25 = matched == null ? void 0 : matched.member) == null ? void 0 : _a25.name) || "";
|
|
41049
|
+
}
|
|
41050
|
+
function startDetailRefresh() {
|
|
41051
|
+
stopDetailRefresh();
|
|
41052
|
+
refreshAdvancedDetails();
|
|
41053
|
+
detailTimer = window.setInterval(() => {
|
|
41054
|
+
refreshAdvancedDetails();
|
|
41055
|
+
}, 2e3);
|
|
41056
|
+
}
|
|
41057
|
+
function stopDetailRefresh() {
|
|
41058
|
+
if (detailTimer !== null) {
|
|
41059
|
+
window.clearInterval(detailTimer);
|
|
41060
|
+
detailTimer = null;
|
|
41012
41061
|
}
|
|
41013
|
-
|
|
41014
|
-
|
|
41062
|
+
}
|
|
41063
|
+
function refreshAdvancedDetails() {
|
|
41064
|
+
advancedDetails.value = readNetworkQualityMetricDetails();
|
|
41065
|
+
}
|
|
41066
|
+
function isSectionCollapsed(key) {
|
|
41067
|
+
return collapsedSections.value[key] ?? false;
|
|
41068
|
+
}
|
|
41069
|
+
function toggleSection(key) {
|
|
41070
|
+
collapsedSections.value[key] = !isSectionCollapsed(key);
|
|
41071
|
+
}
|
|
41072
|
+
function expandAllSections() {
|
|
41073
|
+
collapsedSections.value = Object.fromEntries(
|
|
41074
|
+
detailSections.value.map((section) => [section.key, false])
|
|
41015
41075
|
);
|
|
41016
|
-
|
|
41017
|
-
|
|
41018
|
-
|
|
41019
|
-
|
|
41020
|
-
|
|
41021
|
-
|
|
41022
|
-
|
|
41023
|
-
|
|
41024
|
-
|
|
41025
|
-
|
|
41026
|
-
|
|
41027
|
-
|
|
41028
|
-
|
|
41029
|
-
|
|
41076
|
+
}
|
|
41077
|
+
function collapseAllSections() {
|
|
41078
|
+
collapsedSections.value = Object.fromEntries(
|
|
41079
|
+
detailSections.value.map((section) => [section.key, true])
|
|
41080
|
+
);
|
|
41081
|
+
}
|
|
41082
|
+
function toggleAllSections() {
|
|
41083
|
+
if (allSectionsExpanded.value) {
|
|
41084
|
+
collapseAllSections();
|
|
41085
|
+
return;
|
|
41086
|
+
}
|
|
41087
|
+
expandAllSections();
|
|
41088
|
+
}
|
|
41089
|
+
function syncSectionCollapse(preserveExisting = true) {
|
|
41090
|
+
const nextState = {};
|
|
41091
|
+
for (const section of detailSections.value) {
|
|
41092
|
+
if (preserveExisting && section.key in collapsedSections.value) {
|
|
41093
|
+
nextState[section.key] = collapsedSections.value[section.key];
|
|
41094
|
+
continue;
|
|
41030
41095
|
}
|
|
41031
|
-
|
|
41032
|
-
{ immediate: true, deep: true }
|
|
41033
|
-
);
|
|
41034
|
-
const mainMember = computed(() => {
|
|
41035
|
-
if (!visibleMembers.value.length) return null;
|
|
41036
|
-
if (!mainMemberId.value) {
|
|
41037
|
-
return visibleMembers.value[0];
|
|
41096
|
+
nextState[section.key] = false;
|
|
41038
41097
|
}
|
|
41039
|
-
|
|
41040
|
-
|
|
41041
|
-
|
|
41098
|
+
collapsedSections.value = nextState;
|
|
41099
|
+
}
|
|
41100
|
+
const activeBars = computed(() => {
|
|
41101
|
+
if (networkQualityState.isOffline || networkQualityState.isStale) {
|
|
41102
|
+
return 0;
|
|
41103
|
+
}
|
|
41104
|
+
return getNetworkSignalBars(networkQualityState.level);
|
|
41042
41105
|
});
|
|
41043
|
-
const
|
|
41044
|
-
if (!
|
|
41045
|
-
return
|
|
41046
|
-
(item) => {
|
|
41047
|
-
var _a25;
|
|
41048
|
-
return item.member.memberId !== ((_a25 = mainMember.value) == null ? void 0 : _a25.member.memberId);
|
|
41049
|
-
}
|
|
41050
|
-
);
|
|
41106
|
+
const allSectionsExpanded = computed(() => {
|
|
41107
|
+
if (!detailSections.value.length) return true;
|
|
41108
|
+
return detailSections.value.every((section) => !isSectionCollapsed(section.key));
|
|
41051
41109
|
});
|
|
41052
|
-
const
|
|
41053
|
-
|
|
41054
|
-
|
|
41055
|
-
positions[member.member.memberId] = {
|
|
41056
|
-
position: "absolute",
|
|
41057
|
-
width: `${DEFAULT_SUB_VIDEO_WIDTH}px`,
|
|
41058
|
-
height: `${DEFAULT_SUB_VIDEO_HEIGHT}px`,
|
|
41059
|
-
right: "16px",
|
|
41060
|
-
top: `${STATUS_BAR_HEIGHT + 16 + index * (DEFAULT_SUB_VIDEO_HEIGHT + SUB_VIDEO_GAP)}px`
|
|
41061
|
-
};
|
|
41062
|
-
});
|
|
41063
|
-
return positions;
|
|
41110
|
+
const reasonText = computed(() => {
|
|
41111
|
+
if (!networkQualityState.reasons.length) return "";
|
|
41112
|
+
return `可能原因:${networkQualityState.reasons.join("、")}`;
|
|
41064
41113
|
});
|
|
41065
|
-
const
|
|
41066
|
-
|
|
41067
|
-
|
|
41068
|
-
|
|
41069
|
-
|
|
41070
|
-
|
|
41071
|
-
|
|
41072
|
-
|
|
41073
|
-
|
|
41074
|
-
};
|
|
41114
|
+
const qualityItems = computed(() => [
|
|
41115
|
+
{ label: "总体质量", value: networkQualityState.label },
|
|
41116
|
+
{ label: "上行质量", value: networkQualityState.uplink },
|
|
41117
|
+
{ label: "下行质量", value: networkQualityState.downlink },
|
|
41118
|
+
{ label: "MOS", value: formatMos(networkQualityState.mos) },
|
|
41119
|
+
{ label: "最近更新", value: formatUpdatedAt(networkQualityState.updatedAt) },
|
|
41120
|
+
{
|
|
41121
|
+
label: "数据状态",
|
|
41122
|
+
value: networkQualityState.isStale ? "已过期" : "实时"
|
|
41075
41123
|
}
|
|
41076
|
-
|
|
41077
|
-
|
|
41078
|
-
|
|
41079
|
-
|
|
41080
|
-
|
|
41081
|
-
|
|
41082
|
-
|
|
41083
|
-
|
|
41084
|
-
|
|
41085
|
-
|
|
41086
|
-
|
|
41087
|
-
|
|
41088
|
-
|
|
41089
|
-
|
|
41090
|
-
|
|
41091
|
-
|
|
41092
|
-
|
|
41093
|
-
|
|
41094
|
-
|
|
41095
|
-
|
|
41096
|
-
|
|
41097
|
-
|
|
41098
|
-
|
|
41099
|
-
|
|
41100
|
-
|
|
41101
|
-
|
|
41102
|
-
|
|
41103
|
-
|
|
41104
|
-
|
|
41105
|
-
|
|
41106
|
-
|
|
41107
|
-
|
|
41108
|
-
|
|
41109
|
-
|
|
41110
|
-
|
|
41111
|
-
|
|
41112
|
-
|
|
41124
|
+
]);
|
|
41125
|
+
const overviewItems = computed(() => {
|
|
41126
|
+
const stats = networkQualityState.stats;
|
|
41127
|
+
return [
|
|
41128
|
+
{ label: "上行 RTT", value: formatValue(stats == null ? void 0 : stats.rtt_up, " ms") },
|
|
41129
|
+
{ label: "下行 RTT", value: formatValue(stats == null ? void 0 : stats.rtt_down, " ms") },
|
|
41130
|
+
{ label: "上行码率", value: formatValue(stats == null ? void 0 : stats.bitrate_up, " kb/s") },
|
|
41131
|
+
{ label: "下行码率", value: formatValue(stats == null ? void 0 : stats.bitrate_down, " kb/s") },
|
|
41132
|
+
{ label: "上行丢包率", value: formatLossRate(stats == null ? void 0 : stats.lossrate_up) },
|
|
41133
|
+
{ label: "下行丢包率", value: formatLossRate(stats == null ? void 0 : stats.lossrate_down) },
|
|
41134
|
+
{
|
|
41135
|
+
label: "可用上行带宽",
|
|
41136
|
+
value: formatValue(stats == null ? void 0 : stats.available_outgoing_bitrate, " kb/s")
|
|
41137
|
+
},
|
|
41138
|
+
{
|
|
41139
|
+
label: "可用下行带宽",
|
|
41140
|
+
value: formatValue(stats == null ? void 0 : stats.available_incoming_bitrate, " kb/s")
|
|
41141
|
+
}
|
|
41142
|
+
];
|
|
41143
|
+
});
|
|
41144
|
+
function createAudioSendCard(item, index) {
|
|
41145
|
+
const stats = (item == null ? void 0 : item.stats) || {};
|
|
41146
|
+
return {
|
|
41147
|
+
title: `本地音频 ${index + 1}`,
|
|
41148
|
+
subtitle: (item == null ? void 0 : item.desc) || (stats == null ? void 0 : stats.streamId) || "发送轨道",
|
|
41149
|
+
items: [
|
|
41150
|
+
{ label: "实时码率", value: formatMetricNumber(item == null ? void 0 : item.bitrate, " kb/s") },
|
|
41151
|
+
{ label: "音频电平", value: formatMetricNumber(item == null ? void 0 : item.db, " dBFS", 1) },
|
|
41152
|
+
{ label: "已发包数", value: formatMetricNumber(stats == null ? void 0 : stats.packetsSent) },
|
|
41153
|
+
{ label: "已发字节", value: formatBytes(stats == null ? void 0 : stats.bytesSent) },
|
|
41154
|
+
{ label: "远端丢包", value: formatMetricNumber(stats == null ? void 0 : stats.packetsLost) },
|
|
41155
|
+
{ label: "往返时延", value: formatMetricNumber(stats == null ? void 0 : stats.roundTripTime, " ms") },
|
|
41156
|
+
{ label: "远端抖动", value: formatMetricNumber(stats == null ? void 0 : stats.jitter, " ms") },
|
|
41157
|
+
{ label: "采样时间", value: formatUpdatedAt(stats == null ? void 0 : stats.timestamp) }
|
|
41158
|
+
]
|
|
41159
|
+
};
|
|
41160
|
+
}
|
|
41161
|
+
function createVideoSendCard(item, index) {
|
|
41162
|
+
const stats = (item == null ? void 0 : item.stats) || {};
|
|
41163
|
+
return {
|
|
41164
|
+
title: `本地视频 ${index + 1}`,
|
|
41165
|
+
subtitle: (item == null ? void 0 : item.desc) || (stats == null ? void 0 : stats.rid) || (stats == null ? void 0 : stats.streamId) || "发送轨道",
|
|
41166
|
+
items: [
|
|
41167
|
+
{ label: "实时码率", value: formatMetricNumber(item == null ? void 0 : item.bitrate, " kb/s") },
|
|
41168
|
+
{ label: "分辨率", value: formatDimension((item == null ? void 0 : item.width) || (stats == null ? void 0 : stats.frameWidth), (item == null ? void 0 : item.height) || (stats == null ? void 0 : stats.frameHeight)) },
|
|
41169
|
+
{ label: "帧率", value: formatMetricNumber((item == null ? void 0 : item.fps) || (stats == null ? void 0 : stats.framesPerSecond), " fps") },
|
|
41170
|
+
{ label: "已发帧数", value: formatMetricNumber(stats == null ? void 0 : stats.framesSent) },
|
|
41171
|
+
{ label: "目标码率", value: formatMetricNumber(stats == null ? void 0 : stats.targetBitrate, " bps") },
|
|
41172
|
+
{ label: "FIR/PLI/NACK", value: `${formatMetricNumber(stats == null ? void 0 : stats.firCount)}/${formatMetricNumber(stats == null ? void 0 : stats.pliCount)}/${formatMetricNumber(stats == null ? void 0 : stats.nackCount)}` },
|
|
41173
|
+
{ label: "重传包数", value: formatMetricNumber(stats == null ? void 0 : stats.retransmittedPacketsSent) },
|
|
41174
|
+
{ label: "受限原因", value: formatReason(stats == null ? void 0 : stats.qualityLimitationReason) },
|
|
41175
|
+
{ label: "分辨率变化", value: formatMetricNumber(stats == null ? void 0 : stats.qualityLimitationResolutionChanges) },
|
|
41176
|
+
{ label: "往返时延", value: formatMetricNumber(stats == null ? void 0 : stats.roundTripTime, " ms") },
|
|
41177
|
+
{ label: "采样时间", value: formatUpdatedAt(stats == null ? void 0 : stats.timestamp) }
|
|
41178
|
+
]
|
|
41179
|
+
};
|
|
41180
|
+
}
|
|
41181
|
+
function createAudioRecvCard(item, index) {
|
|
41182
|
+
const stats = (item == null ? void 0 : item.stats) || {};
|
|
41183
|
+
return {
|
|
41184
|
+
title: `远端音频 ${index + 1}`,
|
|
41185
|
+
subtitle: (item == null ? void 0 : item.uid) || (item == null ? void 0 : item.desc) || (stats == null ? void 0 : stats.streamId) || "接收轨道",
|
|
41186
|
+
items: [
|
|
41187
|
+
{ label: "实时码率", value: formatMetricNumber(item == null ? void 0 : item.bitrate, " kb/s") },
|
|
41188
|
+
{ label: "音频电平", value: formatMetricNumber(item == null ? void 0 : item.db, " dBFS", 1) },
|
|
41189
|
+
{ label: "已收包数", value: formatMetricNumber(stats == null ? void 0 : stats.packetsReceived) },
|
|
41190
|
+
{ label: "已收字节", value: formatBytes(stats == null ? void 0 : stats.bytesReceived) },
|
|
41191
|
+
{ label: "丢包数", value: formatMetricNumber(stats == null ? void 0 : stats.packetsLost) },
|
|
41192
|
+
{ label: "网络抖动", value: formatMetricNumber(stats == null ? void 0 : stats.jitter, " ms") },
|
|
41193
|
+
{ label: "缓冲均值", value: formatMetricNumber(stats == null ? void 0 : stats.jitterBufferAvgDelay, " ms") },
|
|
41194
|
+
{ label: "隐藏事件", value: formatMetricNumber(stats == null ? void 0 : stats.concealmentEvents) },
|
|
41195
|
+
{ label: "静音隐藏", value: formatMetricNumber(stats == null ? void 0 : stats.silentConcealmentEvents) },
|
|
41196
|
+
{ label: "采样时间", value: formatUpdatedAt(stats == null ? void 0 : stats.timestamp) }
|
|
41197
|
+
]
|
|
41198
|
+
};
|
|
41199
|
+
}
|
|
41200
|
+
function createVideoRecvCard(item, index) {
|
|
41201
|
+
const stats = (item == null ? void 0 : item.stats) || {};
|
|
41202
|
+
const memberName = getMemberNameById(item == null ? void 0 : item.uid);
|
|
41203
|
+
return {
|
|
41204
|
+
title: `远端视频 ${index + 1}`,
|
|
41205
|
+
subtitle: memberName || (item == null ? void 0 : item.uid) || (item == null ? void 0 : item.desc) || (stats == null ? void 0 : stats.mimeType) || "接收轨道",
|
|
41206
|
+
items: [
|
|
41207
|
+
{ label: "实时码率", value: formatMetricNumber(item == null ? void 0 : item.bitrate, " kb/s") },
|
|
41208
|
+
{ label: "分辨率", value: formatDimension((item == null ? void 0 : item.width) || (stats == null ? void 0 : stats.frameWidth), (item == null ? void 0 : item.height) || (stats == null ? void 0 : stats.frameHeight)) },
|
|
41209
|
+
{ label: "帧率", value: formatMetricNumber((item == null ? void 0 : item.fps) || (stats == null ? void 0 : stats.framesPerSecond), " fps") },
|
|
41210
|
+
{ label: "已收包数", value: formatMetricNumber(stats == null ? void 0 : stats.packetsReceived) },
|
|
41211
|
+
{ label: "已收字节", value: formatBytes(stats == null ? void 0 : stats.bytesReceived) },
|
|
41212
|
+
{ label: "丢包数", value: formatMetricNumber(stats == null ? void 0 : stats.packetsLost) },
|
|
41213
|
+
{ label: "接收/解码帧", value: `${formatMetricNumber(stats == null ? void 0 : stats.framesReceived)}/${formatMetricNumber(stats == null ? void 0 : stats.framesDecoded)}` },
|
|
41214
|
+
{ label: "丢帧数", value: formatMetricNumber(stats == null ? void 0 : stats.framesDropped) },
|
|
41215
|
+
{ label: "FIR/PLI/NACK", value: `${formatMetricNumber(stats == null ? void 0 : stats.firCount)}/${formatMetricNumber(stats == null ? void 0 : stats.pliCount)}/${formatMetricNumber(stats == null ? void 0 : stats.nackCount)}` },
|
|
41216
|
+
{ label: "缓冲均值", value: formatMetricNumber(stats == null ? void 0 : stats.jitterBufferAvgDelay, " ms") },
|
|
41217
|
+
{ label: "解码器", value: formatReason(stats == null ? void 0 : stats.decoderImplementation) },
|
|
41218
|
+
{ label: "MIME", value: formatReason(stats == null ? void 0 : stats.mimeType) },
|
|
41219
|
+
{ label: "采样时间", value: formatUpdatedAt(stats == null ? void 0 : stats.timestamp) }
|
|
41220
|
+
]
|
|
41221
|
+
};
|
|
41222
|
+
}
|
|
41223
|
+
const detailSections = computed(() => {
|
|
41224
|
+
const details = advancedDetails.value;
|
|
41225
|
+
return [
|
|
41226
|
+
{
|
|
41227
|
+
key: "local-audio",
|
|
41228
|
+
title: "本地音频发送",
|
|
41229
|
+
cards: ((details == null ? void 0 : details.local_audios) || []).map(createAudioSendCard)
|
|
41230
|
+
},
|
|
41231
|
+
{
|
|
41232
|
+
key: "local-video",
|
|
41233
|
+
title: "本地视频发送",
|
|
41234
|
+
cards: ((details == null ? void 0 : details.local_videos) || []).map(createVideoSendCard)
|
|
41235
|
+
},
|
|
41236
|
+
{
|
|
41237
|
+
key: "remote-audio",
|
|
41238
|
+
title: "远端音频接收",
|
|
41239
|
+
cards: ((details == null ? void 0 : details.remote_audios) || []).map(createAudioRecvCard)
|
|
41240
|
+
},
|
|
41241
|
+
{
|
|
41242
|
+
key: "remote-video",
|
|
41243
|
+
title: "远端视频接收",
|
|
41244
|
+
cards: ((details == null ? void 0 : details.remote_videos) || []).map(createVideoRecvCard)
|
|
41245
|
+
}
|
|
41246
|
+
];
|
|
41247
|
+
});
|
|
41248
|
+
watch(showPopup, (visible) => {
|
|
41249
|
+
if (visible) {
|
|
41250
|
+
refreshNetworkQualitySnapshot(false);
|
|
41251
|
+
if (advancedOpen.value) {
|
|
41252
|
+
syncSectionCollapse();
|
|
41253
|
+
startDetailRefresh();
|
|
41254
|
+
}
|
|
41255
|
+
return;
|
|
41256
|
+
}
|
|
41257
|
+
stopDetailRefresh();
|
|
41258
|
+
advancedOpen.value = false;
|
|
41259
|
+
collapsedSections.value = {};
|
|
41260
|
+
advancedDetails.value = void 0;
|
|
41261
|
+
});
|
|
41262
|
+
watch(advancedOpen, (open2) => {
|
|
41263
|
+
if (!showPopup.value) return;
|
|
41264
|
+
if (open2) {
|
|
41265
|
+
syncSectionCollapse(false);
|
|
41266
|
+
startDetailRefresh();
|
|
41267
|
+
} else {
|
|
41268
|
+
stopDetailRefresh();
|
|
41269
|
+
advancedDetails.value = void 0;
|
|
41113
41270
|
}
|
|
41114
41271
|
});
|
|
41115
|
-
const callerInfo = ref({});
|
|
41116
41272
|
watch(
|
|
41117
|
-
|
|
41273
|
+
detailSections,
|
|
41118
41274
|
() => {
|
|
41119
|
-
|
|
41120
|
-
|
|
41121
|
-
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41122
|
-
);
|
|
41123
|
-
callerInfo.value = info || {};
|
|
41124
|
-
} catch {
|
|
41125
|
-
callerInfo.value = {};
|
|
41126
|
-
}
|
|
41275
|
+
if (!advancedOpen.value) return;
|
|
41276
|
+
syncSectionCollapse();
|
|
41127
41277
|
},
|
|
41128
|
-
{
|
|
41278
|
+
{ deep: true }
|
|
41129
41279
|
);
|
|
41130
|
-
const onChange = async (type) => {
|
|
41131
|
-
switch (type) {
|
|
41132
|
-
case RoomModalSelectType.microphoneClick:
|
|
41133
|
-
if (micOperationBusy.value) return;
|
|
41134
|
-
if (isAuthority.value) {
|
|
41135
|
-
showNotification(alertMsg, "warning", 5e3);
|
|
41136
|
-
return;
|
|
41137
|
-
}
|
|
41138
|
-
if (meState2.value.microPhoneState === "1") {
|
|
41139
|
-
await closeMic();
|
|
41140
|
-
} else {
|
|
41141
|
-
await openMic();
|
|
41142
|
-
}
|
|
41143
|
-
break;
|
|
41144
|
-
case RoomModalSelectType.cameraClick:
|
|
41145
|
-
if (cameraOperationBusy.value) return;
|
|
41146
|
-
if (isAuthority.value) {
|
|
41147
|
-
alert(alertMsg);
|
|
41148
|
-
return;
|
|
41149
|
-
}
|
|
41150
|
-
if (meState2.value.cameraState === "1") {
|
|
41151
|
-
await closeCamera();
|
|
41152
|
-
} else {
|
|
41153
|
-
await openCamera();
|
|
41154
|
-
}
|
|
41155
|
-
break;
|
|
41156
|
-
case RoomModalSelectType.acceptClick:
|
|
41157
|
-
acceptCall();
|
|
41158
|
-
break;
|
|
41159
|
-
case RoomModalSelectType.endClick:
|
|
41160
|
-
endCall();
|
|
41161
|
-
break;
|
|
41162
|
-
}
|
|
41163
|
-
};
|
|
41164
|
-
const acceptCall = () => {
|
|
41165
|
-
const meetingInfo = JSON.parse(
|
|
41166
|
-
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41167
|
-
);
|
|
41168
|
-
setCallStatus("connected");
|
|
41169
|
-
stopSosFlash();
|
|
41170
|
-
getAnswerCall({
|
|
41171
|
-
meetingId: meetingInfo.meetingId,
|
|
41172
|
-
memberId: getUserId(),
|
|
41173
|
-
cameraStatus: "0",
|
|
41174
|
-
audioStatus: "0"
|
|
41175
|
-
}).then(() => {
|
|
41176
|
-
return getJoinCall({
|
|
41177
|
-
meetingId: meetingInfo.meetingId,
|
|
41178
|
-
memberId: getUserId(),
|
|
41179
|
-
cameraStatus: "0",
|
|
41180
|
-
audioStatus: "0"
|
|
41181
|
-
});
|
|
41182
|
-
}).then((resp) => {
|
|
41183
|
-
if (resp && resp.code === 200) {
|
|
41184
|
-
sessionStorage.setItem("JS_MEETING_INFO", JSON.stringify(resp.data));
|
|
41185
|
-
console.log("拨打电话", resp.data.meetingToken);
|
|
41186
|
-
setTimeout(() => {
|
|
41187
|
-
joinRoom();
|
|
41188
|
-
}, 100);
|
|
41189
|
-
stopRingtone();
|
|
41190
|
-
recordMeeting("start");
|
|
41191
|
-
}
|
|
41192
|
-
}).catch((err) => {
|
|
41193
|
-
console.error("接听失败", err);
|
|
41194
|
-
setCallStatus("end");
|
|
41195
|
-
});
|
|
41196
|
-
};
|
|
41197
|
-
const endCall = async () => {
|
|
41198
|
-
visible.value = false;
|
|
41199
|
-
stopSosFlash();
|
|
41200
|
-
const meetingInfo = JSON.parse(
|
|
41201
|
-
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41202
|
-
);
|
|
41203
|
-
setCallStatus("end");
|
|
41204
|
-
try {
|
|
41205
|
-
const res = await getHangUpCall({
|
|
41206
|
-
meetingId: meetingInfo.meetingId,
|
|
41207
|
-
memberId: getUserId()
|
|
41208
|
-
});
|
|
41209
|
-
if (res.code === 200) {
|
|
41210
|
-
await logoutRoomAction();
|
|
41211
|
-
clearTimer();
|
|
41212
|
-
recordMeeting("stop");
|
|
41213
|
-
}
|
|
41214
|
-
} catch (err) {
|
|
41215
|
-
console.error("挂断失败", err);
|
|
41216
|
-
await logoutRoomAction();
|
|
41217
|
-
}
|
|
41218
|
-
};
|
|
41219
|
-
const stopMonitoring = async () => {
|
|
41220
|
-
visible.value = false;
|
|
41221
|
-
const meetingInfo = JSON.parse(
|
|
41222
|
-
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41223
|
-
);
|
|
41224
|
-
try {
|
|
41225
|
-
const res = await getMeetingLeave({
|
|
41226
|
-
meetingId: meetingInfo.meetingId,
|
|
41227
|
-
memberId: getUserId()
|
|
41228
|
-
});
|
|
41229
|
-
if (res.code === 200) {
|
|
41230
|
-
await logoutRoomAction();
|
|
41231
|
-
clearTimer();
|
|
41232
|
-
}
|
|
41233
|
-
} catch (err) {
|
|
41234
|
-
console.error("离开失败", err);
|
|
41235
|
-
await logoutRoomAction();
|
|
41236
|
-
}
|
|
41237
|
-
};
|
|
41238
|
-
const clearTimer = () => {
|
|
41239
|
-
if (timer) {
|
|
41240
|
-
clearInterval(timer);
|
|
41241
|
-
timer = null;
|
|
41242
|
-
}
|
|
41243
|
-
};
|
|
41244
|
-
const recordMeeting = (newState) => {
|
|
41245
|
-
const meetingInfo = JSON.parse(
|
|
41246
|
-
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41247
|
-
);
|
|
41248
|
-
let params = {
|
|
41249
|
-
meetingId: meetingInfo.meetingId,
|
|
41250
|
-
memberId: getUserId(),
|
|
41251
|
-
cmd: newState
|
|
41252
|
-
};
|
|
41253
|
-
getMcuCtrl(params).then(() => {
|
|
41254
|
-
}).catch(() => {
|
|
41255
|
-
});
|
|
41256
|
-
};
|
|
41257
|
-
const toggleDeviceSelector = (deviceType) => {
|
|
41258
|
-
currentDeviceType.value = deviceType;
|
|
41259
|
-
showDeviceSelector.value = !showDeviceSelector.value;
|
|
41260
|
-
};
|
|
41261
|
-
watch(
|
|
41262
|
-
() => visible.value,
|
|
41263
|
-
(newValue) => {
|
|
41264
|
-
if (newValue) {
|
|
41265
|
-
showDeviceSelector.value = false;
|
|
41266
|
-
}
|
|
41267
|
-
}
|
|
41268
|
-
);
|
|
41269
|
-
onMounted(() => {
|
|
41270
|
-
});
|
|
41271
41280
|
onUnmounted(() => {
|
|
41272
|
-
|
|
41273
|
-
clearInterval(timer);
|
|
41274
|
-
timer = null;
|
|
41275
|
-
}
|
|
41281
|
+
stopDetailRefresh();
|
|
41276
41282
|
});
|
|
41277
41283
|
return (_ctx, _cache) => {
|
|
41278
|
-
return openBlock(),
|
|
41279
|
-
|
|
41280
|
-
|
|
41281
|
-
|
|
41282
|
-
|
|
41284
|
+
return openBlock(), createElementBlock("div", {
|
|
41285
|
+
class: normalizeClass(["network-quality-signal", [`size-${_ctx.size}`]])
|
|
41286
|
+
}, [
|
|
41287
|
+
createElementVNode("button", {
|
|
41288
|
+
ref_key: "triggerRef",
|
|
41289
|
+
ref: triggerRef,
|
|
41290
|
+
type: "button",
|
|
41291
|
+
class: normalizeClass(["network-quality-trigger", [
|
|
41292
|
+
`is-${unref(networkQualityState).level}`,
|
|
41293
|
+
{
|
|
41294
|
+
"is-alert": unref(networkQualityState).isOffline || unref(networkQualityState).isStale
|
|
41295
|
+
}
|
|
41296
|
+
]]),
|
|
41297
|
+
title: unref(networkQualityState).summary,
|
|
41298
|
+
onClick: _cache[0] || (_cache[0] = ($event) => showPopup.value = !showPopup.value)
|
|
41283
41299
|
}, [
|
|
41284
|
-
createElementVNode("
|
|
41285
|
-
|
|
41286
|
-
createElementVNode("
|
|
41287
|
-
|
|
41288
|
-
|
|
41289
|
-
|
|
41290
|
-
|
|
41291
|
-
|
|
41300
|
+
createElementVNode("span", _hoisted_2$m, [
|
|
41301
|
+
(openBlock(), createElementBlock(Fragment, null, renderList(4, (index) => {
|
|
41302
|
+
return createElementVNode("span", {
|
|
41303
|
+
key: index,
|
|
41304
|
+
class: normalizeClass(["signal-bar", { active: index <= activeBars.value }])
|
|
41305
|
+
}, null, 2);
|
|
41306
|
+
}), 64))
|
|
41307
|
+
]),
|
|
41308
|
+
_ctx.showText ? (openBlock(), createElementBlock("span", _hoisted_3$l, toDisplayString(unref(networkQualityState).label), 1)) : createCommentVNode("", true)
|
|
41309
|
+
], 10, _hoisted_1$o),
|
|
41310
|
+
createVNode(SmartPopup, {
|
|
41311
|
+
visible: showPopup.value,
|
|
41312
|
+
"onUpdate:visible": _cache[3] || (_cache[3] = ($event) => showPopup.value = $event),
|
|
41313
|
+
trigger: triggerRef.value,
|
|
41314
|
+
gap: 12
|
|
41315
|
+
}, {
|
|
41316
|
+
default: withCtx(() => [
|
|
41317
|
+
createElementVNode("div", _hoisted_4$j, [
|
|
41318
|
+
createElementVNode("div", {
|
|
41319
|
+
class: normalizeClass(["network-quality-popup network-quality-main", themeClass.value])
|
|
41320
|
+
}, [
|
|
41321
|
+
createElementVNode("div", _hoisted_5$g, [
|
|
41322
|
+
_cache[4] || (_cache[4] = createElementVNode("div", { class: "popup-title" }, "网络详情", -1)),
|
|
41323
|
+
createElementVNode("div", _hoisted_6$f, [
|
|
41324
|
+
createElementVNode("button", {
|
|
41325
|
+
type: "button",
|
|
41326
|
+
class: "advanced-toggle",
|
|
41327
|
+
onClick: _cache[1] || (_cache[1] = withModifiers(($event) => advancedOpen.value = !advancedOpen.value, ["stop"]))
|
|
41328
|
+
}, toDisplayString(advancedOpen.value ? "关闭高级模式" : "打开高级模式"), 1),
|
|
41329
|
+
createElementVNode("div", {
|
|
41330
|
+
class: normalizeClass(["popup-status", `is-${unref(networkQualityState).level}`])
|
|
41331
|
+
}, toDisplayString(unref(networkQualityState).label), 3)
|
|
41292
41332
|
])
|
|
41293
|
-
])
|
|
41294
|
-
|
|
41295
|
-
|
|
41296
|
-
createElementVNode("
|
|
41297
|
-
|
|
41298
|
-
|
|
41299
|
-
|
|
41300
|
-
|
|
41301
|
-
|
|
41302
|
-
|
|
41303
|
-
|
|
41304
|
-
|
|
41305
|
-
|
|
41306
|
-
|
|
41307
|
-
|
|
41308
|
-
|
|
41309
|
-
|
|
41310
|
-
|
|
41311
|
-
|
|
41312
|
-
|
|
41313
|
-
|
|
41314
|
-
|
|
41315
|
-
|
|
41316
|
-
|
|
41317
|
-
|
|
41318
|
-
|
|
41319
|
-
|
|
41320
|
-
|
|
41321
|
-
|
|
41322
|
-
|
|
41323
|
-
|
|
41324
|
-
|
|
41325
|
-
|
|
41326
|
-
|
|
41327
|
-
|
|
41328
|
-
|
|
41329
|
-
|
|
41330
|
-
|
|
41331
|
-
|
|
41332
|
-
|
|
41333
|
+
]),
|
|
41334
|
+
createElementVNode("div", _hoisted_7$e, toDisplayString(unref(networkQualityState).summary), 1),
|
|
41335
|
+
reasonText.value ? (openBlock(), createElementBlock("div", _hoisted_8$d, toDisplayString(reasonText.value), 1)) : createCommentVNode("", true),
|
|
41336
|
+
createElementVNode("div", _hoisted_9$b, [
|
|
41337
|
+
_cache[5] || (_cache[5] = createElementVNode("div", { class: "popup-section-title" }, "质量概览", -1)),
|
|
41338
|
+
createElementVNode("div", _hoisted_10$b, [
|
|
41339
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(qualityItems.value, (item) => {
|
|
41340
|
+
return openBlock(), createElementBlock("div", {
|
|
41341
|
+
key: item.label,
|
|
41342
|
+
class: "popup-item"
|
|
41343
|
+
}, [
|
|
41344
|
+
createElementVNode("div", _hoisted_11$a, toDisplayString(item.label), 1),
|
|
41345
|
+
createElementVNode("div", _hoisted_12$a, toDisplayString(item.value), 1)
|
|
41346
|
+
]);
|
|
41347
|
+
}), 128))
|
|
41348
|
+
])
|
|
41349
|
+
]),
|
|
41350
|
+
createElementVNode("div", _hoisted_13$8, [
|
|
41351
|
+
_cache[6] || (_cache[6] = createElementVNode("div", { class: "popup-section-title" }, "网络指标", -1)),
|
|
41352
|
+
createElementVNode("div", _hoisted_14$7, [
|
|
41353
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(overviewItems.value, (item) => {
|
|
41354
|
+
return openBlock(), createElementBlock("div", {
|
|
41355
|
+
key: item.label,
|
|
41356
|
+
class: "popup-item"
|
|
41357
|
+
}, [
|
|
41358
|
+
createElementVNode("div", _hoisted_15$6, toDisplayString(item.label), 1),
|
|
41359
|
+
createElementVNode("div", _hoisted_16$6, toDisplayString(item.value), 1)
|
|
41360
|
+
]);
|
|
41361
|
+
}), 128))
|
|
41362
|
+
])
|
|
41363
|
+
])
|
|
41364
|
+
], 2),
|
|
41365
|
+
advancedOpen.value ? (openBlock(), createElementBlock("div", {
|
|
41366
|
+
key: 0,
|
|
41367
|
+
class: normalizeClass(["network-quality-popup network-quality-advanced", themeClass.value]),
|
|
41368
|
+
onClick: _cache[2] || (_cache[2] = withModifiers(() => {
|
|
41369
|
+
}, ["stop"]))
|
|
41370
|
+
}, [
|
|
41371
|
+
createElementVNode("div", _hoisted_17$5, [
|
|
41372
|
+
_cache[7] || (_cache[7] = createElementVNode("div", { class: "popup-title" }, "高级模式", -1)),
|
|
41373
|
+
createElementVNode("div", _hoisted_18$5, [
|
|
41374
|
+
createElementVNode("button", {
|
|
41375
|
+
type: "button",
|
|
41376
|
+
class: "advanced-mini-btn",
|
|
41377
|
+
onClick: toggleAllSections
|
|
41378
|
+
}, toDisplayString(allSectionsExpanded.value ? "全部收起" : "全部展开"), 1)
|
|
41379
|
+
])
|
|
41380
|
+
]),
|
|
41381
|
+
createElementVNode("div", _hoisted_19$5, [
|
|
41382
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(detailSections.value, (section) => {
|
|
41383
|
+
return openBlock(), createElementBlock("div", {
|
|
41384
|
+
key: section.key,
|
|
41385
|
+
class: "popup-section"
|
|
41386
|
+
}, [
|
|
41333
41387
|
createElementVNode("button", {
|
|
41334
41388
|
type: "button",
|
|
41335
|
-
class: "
|
|
41336
|
-
|
|
41337
|
-
|
|
41338
|
-
|
|
41339
|
-
|
|
41340
|
-
|
|
41341
|
-
|
|
41342
|
-
|
|
41343
|
-
|
|
41344
|
-
|
|
41345
|
-
|
|
41346
|
-
|
|
41347
|
-
|
|
41348
|
-
|
|
41349
|
-
|
|
41350
|
-
|
|
41351
|
-
|
|
41352
|
-
|
|
41353
|
-
|
|
41354
|
-
|
|
41355
|
-
|
|
41356
|
-
|
|
41357
|
-
|
|
41358
|
-
|
|
41359
|
-
|
|
41360
|
-
|
|
41361
|
-
|
|
41362
|
-
|
|
41363
|
-
|
|
41364
|
-
|
|
41365
|
-
|
|
41366
|
-
|
|
41367
|
-
|
|
41368
|
-
|
|
41369
|
-
|
|
41370
|
-
|
|
41371
|
-
|
|
41372
|
-
createElementVNode("div", {
|
|
41373
|
-
class: normalizeClass(["device-dropdown-trigger", { "is-disabled": unref(micOperationBusy) }]),
|
|
41374
|
-
onClick: _cache[1] || (_cache[1] = ($event) => toggleDeviceSelector("microphone"))
|
|
41375
|
-
}, [
|
|
41376
|
-
createVNode(SvgIcon, {
|
|
41377
|
-
name: "TriangleIcon",
|
|
41378
|
-
size: 9
|
|
41379
|
-
})
|
|
41380
|
-
], 2)
|
|
41381
|
-
], 512)) : createCommentVNode("", true),
|
|
41382
|
-
isReceiving.value ? (openBlock(), createElementBlock("button", {
|
|
41383
|
-
key: 1,
|
|
41384
|
-
class: "accept-call-btn",
|
|
41385
|
-
onClick: acceptCall
|
|
41386
|
-
}, [
|
|
41387
|
-
createVNode(SvgIcon, {
|
|
41388
|
-
name: "PhoneIcon",
|
|
41389
|
-
size: 21
|
|
41390
|
-
}),
|
|
41391
|
-
_cache[10] || (_cache[10] = createElementVNode("span", null, "接听", -1))
|
|
41392
|
-
])) : createCommentVNode("", true),
|
|
41393
|
-
isCalling.value || isReceiving.value || isConnected.value ? (openBlock(), createElementBlock("button", {
|
|
41394
|
-
key: 2,
|
|
41395
|
-
class: "end-call-btn",
|
|
41396
|
-
onClick: endCall
|
|
41397
|
-
}, [
|
|
41398
|
-
createVNode(SvgIcon, {
|
|
41399
|
-
name: "HandUpIcon",
|
|
41400
|
-
size: 21,
|
|
41401
|
-
"color-class": "handUp"
|
|
41402
|
-
}),
|
|
41403
|
-
createElementVNode("span", null, toDisplayString(isReceiving.value ? "拒绝" : "挂断"), 1)
|
|
41404
|
-
])) : createCommentVNode("", true),
|
|
41405
|
-
isListening.value ? (openBlock(), createElementBlock("button", {
|
|
41406
|
-
key: 3,
|
|
41407
|
-
class: "end-call-btn",
|
|
41408
|
-
onClick: stopMonitoring
|
|
41409
|
-
}, [
|
|
41410
|
-
createVNode(SvgIcon, {
|
|
41411
|
-
name: "HandUpIcon",
|
|
41412
|
-
size: 21,
|
|
41413
|
-
"color-class": "handUp"
|
|
41414
|
-
}),
|
|
41415
|
-
_cache[11] || (_cache[11] = createElementVNode("span", null, "结束监听", -1))
|
|
41416
|
-
])) : createCommentVNode("", true),
|
|
41417
|
-
isForcibleInsertion.value ? (openBlock(), createElementBlock("button", {
|
|
41418
|
-
key: 4,
|
|
41419
|
-
class: "end-call-btn",
|
|
41420
|
-
onClick: stopMonitoring
|
|
41421
|
-
}, [
|
|
41422
|
-
createVNode(SvgIcon, {
|
|
41423
|
-
name: "HandUpIcon",
|
|
41424
|
-
size: 20
|
|
41425
|
-
}),
|
|
41426
|
-
_cache[12] || (_cache[12] = createElementVNode("span", null, "退出通话", -1))
|
|
41427
|
-
])) : createCommentVNode("", true),
|
|
41428
|
-
isConnected.value || isForcibleInsertion.value ? (openBlock(), createElementBlock("div", {
|
|
41429
|
-
key: 5,
|
|
41430
|
-
ref_key: "cameraRef",
|
|
41431
|
-
ref: cameraRef
|
|
41432
|
-
}, [
|
|
41433
|
-
createElementVNode("button", {
|
|
41434
|
-
class: normalizeClass(["control-btn", { "is-disabled": unref(cameraOperationBusy) }]),
|
|
41435
|
-
onClick: _cache[2] || (_cache[2] = ($event) => onChange(unref(RoomModalSelectType).cameraClick))
|
|
41436
|
-
}, [
|
|
41437
|
-
createVNode(SvgIcon, {
|
|
41438
|
-
name: unref(meState2).cameraState == "1" ? "CameraIcon" : "CameraSlashIcon",
|
|
41439
|
-
size: 20
|
|
41440
|
-
}, null, 8, ["name"]),
|
|
41441
|
-
_cache[13] || (_cache[13] = createElementVNode("span", null, "摄像头", -1))
|
|
41442
|
-
], 2),
|
|
41443
|
-
createElementVNode("div", {
|
|
41444
|
-
class: normalizeClass(["device-dropdown-trigger", { "is-disabled": unref(cameraOperationBusy) }]),
|
|
41445
|
-
onClick: _cache[3] || (_cache[3] = ($event) => toggleDeviceSelector("camera"))
|
|
41446
|
-
}, [
|
|
41447
|
-
createVNode(SvgIcon, {
|
|
41448
|
-
name: "TriangleIcon",
|
|
41449
|
-
size: 9
|
|
41450
|
-
})
|
|
41451
|
-
], 2)
|
|
41452
|
-
], 512)) : createCommentVNode("", true)
|
|
41453
|
-
]),
|
|
41454
|
-
isConnected.value ? (openBlock(), createElementBlock("div", _hoisted_28$3, [
|
|
41455
|
-
createVNode(SvgIcon, {
|
|
41456
|
-
name: "TranscribeIcon",
|
|
41457
|
-
size: 22
|
|
41458
|
-
}),
|
|
41459
|
-
_cache[14] || (_cache[14] = createElementVNode("span", null, "录制中", -1))
|
|
41460
|
-
])) : createCommentVNode("", true)
|
|
41389
|
+
class: normalizeClass(["detail-section-toggle", { collapsed: isSectionCollapsed(section.key) }]),
|
|
41390
|
+
onClick: ($event) => toggleSection(section.key)
|
|
41391
|
+
}, [
|
|
41392
|
+
createElementVNode("span", _hoisted_21$3, [
|
|
41393
|
+
createElementVNode("span", _hoisted_22$3, toDisplayString(section.title), 1),
|
|
41394
|
+
createElementVNode("span", _hoisted_23$3, "(" + toDisplayString(section.cards.length) + ")", 1)
|
|
41395
|
+
]),
|
|
41396
|
+
createElementVNode("span", _hoisted_24$3, toDisplayString(isSectionCollapsed(section.key) ? "展开" : "收起"), 1)
|
|
41397
|
+
], 10, _hoisted_20$5),
|
|
41398
|
+
!isSectionCollapsed(section.key) && section.cards.length ? (openBlock(), createElementBlock("div", _hoisted_25$3, [
|
|
41399
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(section.cards, (card) => {
|
|
41400
|
+
return openBlock(), createElementBlock("div", {
|
|
41401
|
+
key: card.title,
|
|
41402
|
+
class: "metric-card"
|
|
41403
|
+
}, [
|
|
41404
|
+
createElementVNode("div", _hoisted_26$3, [
|
|
41405
|
+
createElementVNode("div", _hoisted_27$3, toDisplayString(card.title), 1),
|
|
41406
|
+
createElementVNode("div", _hoisted_28$3, toDisplayString(card.subtitle), 1)
|
|
41407
|
+
]),
|
|
41408
|
+
createElementVNode("div", _hoisted_29$2, [
|
|
41409
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(card.items, (item) => {
|
|
41410
|
+
return openBlock(), createElementBlock("div", {
|
|
41411
|
+
key: `${card.title}-${item.label}`,
|
|
41412
|
+
class: "metric-card-item"
|
|
41413
|
+
}, [
|
|
41414
|
+
createElementVNode("div", _hoisted_30$2, toDisplayString(item.label), 1),
|
|
41415
|
+
createElementVNode("div", _hoisted_31$1, toDisplayString(item.value), 1)
|
|
41416
|
+
]);
|
|
41417
|
+
}), 128))
|
|
41418
|
+
])
|
|
41419
|
+
]);
|
|
41420
|
+
}), 128))
|
|
41421
|
+
])) : !isSectionCollapsed(section.key) ? (openBlock(), createElementBlock("div", _hoisted_32$1, "暂无数据")) : createCommentVNode("", true)
|
|
41422
|
+
]);
|
|
41423
|
+
}), 128))
|
|
41424
|
+
])
|
|
41425
|
+
], 2)) : createCommentVNode("", true)
|
|
41461
41426
|
])
|
|
41462
41427
|
]),
|
|
41463
|
-
|
|
41464
|
-
|
|
41465
|
-
|
|
41466
|
-
trigger: currentDeviceType.value == "microphone" ? micRef.value : cameraRef.value,
|
|
41467
|
-
gap: 10
|
|
41468
|
-
}, {
|
|
41469
|
-
default: withCtx(() => [
|
|
41470
|
-
createVNode(DeviceSelector, {
|
|
41471
|
-
"device-type": currentDeviceType.value,
|
|
41472
|
-
theme: _ctx.theme,
|
|
41473
|
-
onClose: _cache[4] || (_cache[4] = ($event) => showDeviceSelector.value = false)
|
|
41474
|
-
}, null, 8, ["device-type", "theme"])
|
|
41475
|
-
]),
|
|
41476
|
-
_: 1
|
|
41477
|
-
}, 8, ["visible", "trigger"])
|
|
41478
|
-
], 2)) : createCommentVNode("", true)
|
|
41479
|
-
]);
|
|
41428
|
+
_: 1
|
|
41429
|
+
}, 8, ["visible", "trigger"])
|
|
41430
|
+
], 2);
|
|
41480
41431
|
};
|
|
41481
41432
|
}
|
|
41482
41433
|
});
|
|
41483
|
-
const
|
|
41484
|
-
const _hoisted_1$n = { class: "
|
|
41485
|
-
const _hoisted_2$l = { class: "js-dialog-header-actions" };
|
|
41434
|
+
const NetworkQualitySignal = /* @__PURE__ */ _export_sfc(_sfc_main$q, [["__scopeId", "data-v-3378006f"]]);
|
|
41435
|
+
const _hoisted_1$n = { class: "network-copy" };
|
|
41486
41436
|
const _sfc_main$p = /* @__PURE__ */ defineComponent({
|
|
41487
|
-
__name: "
|
|
41437
|
+
__name: "netWorkStatus",
|
|
41488
41438
|
props: {
|
|
41489
|
-
theme: {}
|
|
41490
|
-
isMaximized: { type: Boolean }
|
|
41439
|
+
theme: { default: "dark" }
|
|
41491
41440
|
},
|
|
41492
|
-
|
|
41493
|
-
setup(__props, { emit: __emit }) {
|
|
41441
|
+
setup(__props) {
|
|
41494
41442
|
const props = __props;
|
|
41495
|
-
const
|
|
41496
|
-
const
|
|
41497
|
-
|
|
41443
|
+
const themeClass = computed(() => `theme-${props.theme}`);
|
|
41444
|
+
const displayLabel = computed(() => {
|
|
41445
|
+
if (networkQualityState.isStale) {
|
|
41446
|
+
return "网络检测中";
|
|
41447
|
+
}
|
|
41448
|
+
return networkQualityState.label;
|
|
41498
41449
|
});
|
|
41499
|
-
const emit = __emit;
|
|
41500
|
-
const closeRef = ref(null);
|
|
41501
|
-
const showCloseConfirm = ref(false);
|
|
41502
|
-
const themeClass = computed(() => `theme-${props.theme || "dark"}`);
|
|
41503
|
-
ref(false);
|
|
41504
|
-
const handleCloseClick = async () => {
|
|
41505
|
-
showCloseConfirm.value = !showCloseConfirm.value;
|
|
41506
|
-
};
|
|
41507
|
-
const handleEndMeeting = () => {
|
|
41508
|
-
showCloseConfirm.value = false;
|
|
41509
|
-
emit("onChange", RoomModalSelectType.endClick);
|
|
41510
|
-
};
|
|
41511
|
-
const handleLeaveMeeting = () => {
|
|
41512
|
-
showCloseConfirm.value = false;
|
|
41513
|
-
emit("onChange", RoomModalSelectType.leaveClick);
|
|
41514
|
-
};
|
|
41515
41450
|
return (_ctx, _cache) => {
|
|
41516
41451
|
return openBlock(), createElementBlock("div", {
|
|
41517
|
-
class: normalizeClass(["
|
|
41452
|
+
class: normalizeClass(["network-situation", themeClass.value])
|
|
41518
41453
|
}, [
|
|
41519
|
-
|
|
41520
|
-
|
|
41521
|
-
|
|
41522
|
-
|
|
41523
|
-
|
|
41524
|
-
|
|
41525
|
-
|
|
41526
|
-
|
|
41527
|
-
|
|
41528
|
-
})
|
|
41529
|
-
]),
|
|
41530
|
-
createElementVNode("div", {
|
|
41531
|
-
ref_key: "closeRef",
|
|
41532
|
-
ref: closeRef,
|
|
41533
|
-
title: "关闭",
|
|
41534
|
-
onClick: handleCloseClick
|
|
41535
|
-
}, [
|
|
41536
|
-
createVNode(SvgIcon, {
|
|
41537
|
-
name: "CloseIcon",
|
|
41538
|
-
size: 17
|
|
41539
|
-
})
|
|
41540
|
-
], 512)
|
|
41541
|
-
]),
|
|
41542
|
-
createVNode(SmartPopup, {
|
|
41543
|
-
visible: showCloseConfirm.value,
|
|
41544
|
-
"onUpdate:visible": _cache[2] || (_cache[2] = ($event) => showCloseConfirm.value = $event),
|
|
41545
|
-
trigger: closeRef.value,
|
|
41546
|
-
gap: 10
|
|
41547
|
-
}, {
|
|
41548
|
-
default: withCtx(() => [
|
|
41549
|
-
createElementVNode("div", {
|
|
41550
|
-
class: normalizeClass(["close-confirm-dropdown", themeClass.value])
|
|
41551
|
-
}, [
|
|
41552
|
-
unref(meState2).roleType == "1" ? (openBlock(), createElementBlock("div", {
|
|
41553
|
-
key: 0,
|
|
41554
|
-
class: "close-confirm-option danger",
|
|
41555
|
-
onClick: withModifiers(handleEndMeeting, ["stop"])
|
|
41556
|
-
}, " 结束会议 ")) : createCommentVNode("", true),
|
|
41557
|
-
createElementVNode("div", {
|
|
41558
|
-
class: "close-confirm-option simple",
|
|
41559
|
-
onClick: withModifiers(handleLeaveMeeting, ["stop"])
|
|
41560
|
-
}, " 离开会议 "),
|
|
41561
|
-
createElementVNode("div", {
|
|
41562
|
-
class: "close-confirm-option simple",
|
|
41563
|
-
onClick: _cache[1] || (_cache[1] = ($event) => showCloseConfirm.value = false)
|
|
41564
|
-
}, " 取消 ")
|
|
41565
|
-
], 2)
|
|
41566
|
-
]),
|
|
41567
|
-
_: 1
|
|
41568
|
-
}, 8, ["visible", "trigger"])
|
|
41454
|
+
createVNode(NetworkQualitySignal, {
|
|
41455
|
+
theme: _ctx.theme,
|
|
41456
|
+
size: "compact"
|
|
41457
|
+
}, null, 8, ["theme"]),
|
|
41458
|
+
createElementVNode("div", _hoisted_1$n, [
|
|
41459
|
+
createElementVNode("span", {
|
|
41460
|
+
class: normalizeClass(["network-label", `is-${unref(networkQualityState).level}`])
|
|
41461
|
+
}, toDisplayString(displayLabel.value), 3)
|
|
41462
|
+
])
|
|
41569
41463
|
], 2);
|
|
41570
41464
|
};
|
|
41571
41465
|
}
|
|
41572
41466
|
});
|
|
41573
|
-
const
|
|
41574
|
-
const _hoisted_1$m =
|
|
41575
|
-
|
|
41576
|
-
class: "
|
|
41577
|
-
"aria-hidden": "true"
|
|
41467
|
+
const NetWorkStatus = /* @__PURE__ */ _export_sfc(_sfc_main$p, [["__scopeId", "data-v-565d8abd"]]);
|
|
41468
|
+
const _hoisted_1$m = {
|
|
41469
|
+
key: 0,
|
|
41470
|
+
class: "sos-flash-overlay"
|
|
41578
41471
|
};
|
|
41579
|
-
const
|
|
41472
|
+
const _hoisted_2$l = { class: "js-call-dialog-container" };
|
|
41473
|
+
const _hoisted_3$k = { class: "status-bar" };
|
|
41474
|
+
const _hoisted_4$i = { class: "status-left" };
|
|
41475
|
+
const _hoisted_5$f = {
|
|
41580
41476
|
key: 0,
|
|
41581
|
-
class: "
|
|
41477
|
+
class: "caller-info",
|
|
41478
|
+
title: "来电人"
|
|
41479
|
+
};
|
|
41480
|
+
const _hoisted_6$e = {
|
|
41481
|
+
class: "avatar",
|
|
41482
|
+
style: { "width": "35px", "height": "35px", "font-size": "16px" }
|
|
41582
41483
|
};
|
|
41583
|
-
const
|
|
41584
|
-
const
|
|
41585
|
-
const
|
|
41586
|
-
const _hoisted_7$d = { class: "popup-summary" };
|
|
41587
|
-
const _hoisted_8$c = {
|
|
41484
|
+
const _hoisted_7$d = { class: "caller-text" };
|
|
41485
|
+
const _hoisted_8$c = { class: "caller-name" };
|
|
41486
|
+
const _hoisted_9$a = {
|
|
41588
41487
|
key: 0,
|
|
41589
|
-
class: "
|
|
41488
|
+
class: "caller-number"
|
|
41489
|
+
};
|
|
41490
|
+
const _hoisted_10$a = { class: "status-right" };
|
|
41491
|
+
const _hoisted_11$9 = ["onClick"];
|
|
41492
|
+
const _hoisted_12$9 = { class: "video-wrapper" };
|
|
41493
|
+
const _hoisted_13$7 = ["id"];
|
|
41494
|
+
const _hoisted_14$6 = { class: "avatar-container" };
|
|
41495
|
+
const _hoisted_15$5 = { class: "avatar" };
|
|
41496
|
+
const _hoisted_16$5 = { class: "video-loading-overlay" };
|
|
41497
|
+
const _hoisted_17$4 = { class: "video-loading-text" };
|
|
41498
|
+
const _hoisted_18$4 = { class: "video-loading-overlay failed" };
|
|
41499
|
+
const _hoisted_19$4 = ["disabled", "onClick"];
|
|
41500
|
+
const _hoisted_20$4 = { class: "video-meta" };
|
|
41501
|
+
const _hoisted_21$2 = { class: "member-name" };
|
|
41502
|
+
const _hoisted_22$2 = {
|
|
41503
|
+
key: 0,
|
|
41504
|
+
class: "role-tag"
|
|
41505
|
+
};
|
|
41506
|
+
const _hoisted_23$2 = {
|
|
41507
|
+
key: 1,
|
|
41508
|
+
class: "video-empty"
|
|
41590
41509
|
};
|
|
41591
|
-
const
|
|
41592
|
-
const _hoisted_10$a = { class: "popup-grid" };
|
|
41593
|
-
const _hoisted_11$9 = { class: "popup-item-label" };
|
|
41594
|
-
const _hoisted_12$9 = { class: "popup-item-value" };
|
|
41595
|
-
const _hoisted_13$7 = { class: "popup-section" };
|
|
41596
|
-
const _hoisted_14$6 = { class: "popup-grid" };
|
|
41597
|
-
const _hoisted_15$5 = { class: "popup-item-label" };
|
|
41598
|
-
const _hoisted_16$5 = { class: "popup-item-value" };
|
|
41599
|
-
const _hoisted_17$4 = { class: "popup-header" };
|
|
41600
|
-
const _hoisted_18$4 = { class: "popup-header-actions" };
|
|
41601
|
-
const _hoisted_19$4 = { class: "popup-section-container" };
|
|
41602
|
-
const _hoisted_20$4 = ["onClick"];
|
|
41603
|
-
const _hoisted_21$2 = { class: "detail-section-main" };
|
|
41604
|
-
const _hoisted_22$2 = { class: "popup-section-title" };
|
|
41605
|
-
const _hoisted_23$2 = { class: "popup-section-count" };
|
|
41606
|
-
const _hoisted_24$2 = { class: "detail-section-icon" };
|
|
41510
|
+
const _hoisted_24$2 = { class: "control-bar" };
|
|
41607
41511
|
const _hoisted_25$2 = {
|
|
41608
41512
|
key: 0,
|
|
41609
|
-
class: "
|
|
41513
|
+
class: "call-duration"
|
|
41610
41514
|
};
|
|
41611
|
-
const _hoisted_26$2 = {
|
|
41612
|
-
const _hoisted_27$2 = { class: "
|
|
41613
|
-
const _hoisted_28$2 = {
|
|
41614
|
-
const _hoisted_29$2 = { class: "metric-card-grid" };
|
|
41615
|
-
const _hoisted_30$2 = { class: "popup-item-label" };
|
|
41616
|
-
const _hoisted_31$1 = { class: "popup-item-value" };
|
|
41617
|
-
const _hoisted_32$1 = {
|
|
41515
|
+
const _hoisted_26$2 = { id: "duration" };
|
|
41516
|
+
const _hoisted_27$2 = { class: "control-buttons" };
|
|
41517
|
+
const _hoisted_28$2 = {
|
|
41618
41518
|
key: 1,
|
|
41619
|
-
class: "
|
|
41519
|
+
class: "recording-button"
|
|
41620
41520
|
};
|
|
41621
|
-
const
|
|
41622
|
-
|
|
41623
|
-
|
|
41521
|
+
const DEFAULT_SUB_VIDEO_HEIGHT = 110;
|
|
41522
|
+
const DEFAULT_SUB_VIDEO_WIDTH = 190;
|
|
41523
|
+
const SUB_VIDEO_GAP = 12;
|
|
41524
|
+
const CONTROL_BAR_HEIGHT = 90;
|
|
41525
|
+
const STATUS_BAR_HEIGHT = 48;
|
|
41526
|
+
const _sfc_main$o = /* @__PURE__ */ defineComponent({
|
|
41527
|
+
__name: "call",
|
|
41528
|
+
props: {
|
|
41624
41529
|
theme: { default: "dark" },
|
|
41625
|
-
|
|
41626
|
-
|
|
41530
|
+
draggable: { type: Boolean, default: false },
|
|
41531
|
+
taskId: {}
|
|
41627
41532
|
},
|
|
41628
41533
|
setup(__props) {
|
|
41534
|
+
const { meState: meState2 } = storeToRefs(useMeetingStore());
|
|
41629
41535
|
const props = __props;
|
|
41630
|
-
const
|
|
41631
|
-
const showPopup = ref(false);
|
|
41632
|
-
const advancedOpen = ref(false);
|
|
41633
|
-
const collapsedSections = ref({});
|
|
41634
|
-
const advancedDetails = ref();
|
|
41635
|
-
let detailTimer = null;
|
|
41536
|
+
const visible = callVisible;
|
|
41636
41537
|
const themeClass = computed(() => `theme-${props.theme}`);
|
|
41637
|
-
|
|
41638
|
-
|
|
41639
|
-
|
|
41640
|
-
|
|
41641
|
-
|
|
41642
|
-
|
|
41643
|
-
|
|
41644
|
-
|
|
41645
|
-
|
|
41646
|
-
|
|
41647
|
-
|
|
41648
|
-
|
|
41649
|
-
return `${value.toFixed(0)} B`;
|
|
41650
|
-
}
|
|
41651
|
-
function formatDimension(width, height) {
|
|
41652
|
-
if (!width || !height) return "--";
|
|
41653
|
-
return `${width} x ${height}`;
|
|
41654
|
-
}
|
|
41655
|
-
function formatLossRate(value) {
|
|
41656
|
-
if (typeof value !== "number" || Number.isNaN(value)) return "--";
|
|
41657
|
-
return `${value.toFixed(1)}%`;
|
|
41658
|
-
}
|
|
41659
|
-
function formatMos(value) {
|
|
41660
|
-
if (typeof value !== "number" || value <= 0 || Number.isNaN(value)) return "--";
|
|
41661
|
-
return value.toFixed(1);
|
|
41662
|
-
}
|
|
41663
|
-
function formatUpdatedAt(timestamp) {
|
|
41664
|
-
if (!timestamp) return "--";
|
|
41665
|
-
const date = new Date(timestamp);
|
|
41666
|
-
const hh = String(date.getHours()).padStart(2, "0");
|
|
41667
|
-
const mm = String(date.getMinutes()).padStart(2, "0");
|
|
41668
|
-
const ss = String(date.getSeconds()).padStart(2, "0");
|
|
41669
|
-
return `${hh}:${mm}:${ss}`;
|
|
41670
|
-
}
|
|
41671
|
-
function formatReason(value) {
|
|
41672
|
-
return value || "--";
|
|
41673
|
-
}
|
|
41674
|
-
function getMemberNameById(memberId) {
|
|
41675
|
-
var _a25;
|
|
41676
|
-
if (!memberId) return "";
|
|
41677
|
-
const matched = members.value.find(
|
|
41678
|
-
(member) => {
|
|
41679
|
-
var _a26;
|
|
41680
|
-
return ((_a26 = member == null ? void 0 : member.member) == null ? void 0 : _a26.memberId) === String(memberId);
|
|
41538
|
+
const showDeviceSelector = ref(false);
|
|
41539
|
+
const currentDeviceType = ref("microphone");
|
|
41540
|
+
const micRef = ref(null);
|
|
41541
|
+
const cameraRef = ref(null);
|
|
41542
|
+
const joinTimeObj = ref("");
|
|
41543
|
+
let timer = null;
|
|
41544
|
+
watch(
|
|
41545
|
+
() => joinTime.value,
|
|
41546
|
+
() => {
|
|
41547
|
+
if (timer) {
|
|
41548
|
+
clearInterval(timer);
|
|
41549
|
+
timer = null;
|
|
41681
41550
|
}
|
|
41682
|
-
|
|
41683
|
-
|
|
41684
|
-
|
|
41685
|
-
|
|
41686
|
-
|
|
41687
|
-
|
|
41688
|
-
|
|
41689
|
-
|
|
41690
|
-
|
|
41691
|
-
}
|
|
41692
|
-
function stopDetailRefresh() {
|
|
41693
|
-
if (detailTimer !== null) {
|
|
41694
|
-
window.clearInterval(detailTimer);
|
|
41695
|
-
detailTimer = null;
|
|
41551
|
+
if (joinTime.value) {
|
|
41552
|
+
timer = setInterval(() => {
|
|
41553
|
+
const now = +/* @__PURE__ */ new Date();
|
|
41554
|
+
joinTimeObj.value = formatDuringObject((now - joinTime.value) / 1e3);
|
|
41555
|
+
}, 1e3);
|
|
41556
|
+
}
|
|
41557
|
+
},
|
|
41558
|
+
{
|
|
41559
|
+
immediate: true
|
|
41696
41560
|
}
|
|
41697
|
-
|
|
41698
|
-
|
|
41699
|
-
|
|
41700
|
-
|
|
41701
|
-
|
|
41702
|
-
|
|
41703
|
-
|
|
41704
|
-
|
|
41705
|
-
|
|
41706
|
-
|
|
41707
|
-
|
|
41708
|
-
collapsedSections.value = Object.fromEntries(
|
|
41709
|
-
detailSections.value.map((section) => [section.key, false])
|
|
41710
|
-
);
|
|
41711
|
-
}
|
|
41712
|
-
function collapseAllSections() {
|
|
41713
|
-
collapsedSections.value = Object.fromEntries(
|
|
41714
|
-
detailSections.value.map((section) => [section.key, true])
|
|
41561
|
+
);
|
|
41562
|
+
const isCalling = computed(() => callStatus.value === "calling");
|
|
41563
|
+
const isReceiving = computed(() => callStatus.value === "receiving");
|
|
41564
|
+
const isConnected = computed(() => callStatus.value === "connected");
|
|
41565
|
+
const isListening = computed(() => callStatus.value === "listening");
|
|
41566
|
+
const isForcibleInsertion = computed(
|
|
41567
|
+
() => callStatus.value === "forcible-insertion"
|
|
41568
|
+
);
|
|
41569
|
+
const visibleMembers = computed(() => {
|
|
41570
|
+
return members.value.filter(
|
|
41571
|
+
(item) => item.roleType !== "4" && item.joinStaus === "1" && (!isListening.value || item.member.memberId !== getUserId())
|
|
41715
41572
|
);
|
|
41716
|
-
}
|
|
41717
|
-
|
|
41718
|
-
|
|
41719
|
-
|
|
41720
|
-
|
|
41573
|
+
});
|
|
41574
|
+
const hasForceInsertMember = computed(
|
|
41575
|
+
() => visibleMembers.value.some((item) => item.roleType === "1")
|
|
41576
|
+
);
|
|
41577
|
+
const layoutClass = computed(() => {
|
|
41578
|
+
if (visibleMembers.value.length <= 1) return "layout-single";
|
|
41579
|
+
if (hasForceInsertMember.value) return "layout-three";
|
|
41580
|
+
return "layout-two";
|
|
41581
|
+
});
|
|
41582
|
+
const mainMemberId = ref("");
|
|
41583
|
+
const pickDefaultMainMember = (list) => {
|
|
41584
|
+
if (!list.length) {
|
|
41585
|
+
return "";
|
|
41721
41586
|
}
|
|
41722
|
-
|
|
41723
|
-
|
|
41724
|
-
|
|
41725
|
-
|
|
41726
|
-
|
|
41727
|
-
|
|
41728
|
-
|
|
41729
|
-
|
|
41587
|
+
const remoteMember = list.find(
|
|
41588
|
+
(item) => item.member.memberId !== getUserId()
|
|
41589
|
+
);
|
|
41590
|
+
return (remoteMember || list[0]).member.memberId;
|
|
41591
|
+
};
|
|
41592
|
+
watch(
|
|
41593
|
+
visibleMembers,
|
|
41594
|
+
(list) => {
|
|
41595
|
+
if (!list.length) {
|
|
41596
|
+
mainMemberId.value = "";
|
|
41597
|
+
return;
|
|
41730
41598
|
}
|
|
41731
|
-
|
|
41732
|
-
|
|
41733
|
-
|
|
41734
|
-
|
|
41735
|
-
|
|
41736
|
-
|
|
41737
|
-
|
|
41599
|
+
const exists = list.some(
|
|
41600
|
+
(item) => item.member.memberId === mainMemberId.value
|
|
41601
|
+
);
|
|
41602
|
+
if (!exists) {
|
|
41603
|
+
mainMemberId.value = pickDefaultMainMember(list);
|
|
41604
|
+
}
|
|
41605
|
+
},
|
|
41606
|
+
{ immediate: true, deep: true }
|
|
41607
|
+
);
|
|
41608
|
+
const mainMember = computed(() => {
|
|
41609
|
+
if (!visibleMembers.value.length) return null;
|
|
41610
|
+
if (!mainMemberId.value) {
|
|
41611
|
+
return visibleMembers.value[0];
|
|
41738
41612
|
}
|
|
41739
|
-
return
|
|
41613
|
+
return visibleMembers.value.find(
|
|
41614
|
+
(item) => item.member.memberId === mainMemberId.value
|
|
41615
|
+
) || visibleMembers.value[0];
|
|
41740
41616
|
});
|
|
41741
|
-
const
|
|
41742
|
-
if (!
|
|
41743
|
-
return
|
|
41617
|
+
const secondaryMembers = computed(() => {
|
|
41618
|
+
if (!mainMember.value) return [];
|
|
41619
|
+
return visibleMembers.value.filter(
|
|
41620
|
+
(item) => {
|
|
41621
|
+
var _a25;
|
|
41622
|
+
return item.member.memberId !== ((_a25 = mainMember.value) == null ? void 0 : _a25.member.memberId);
|
|
41623
|
+
}
|
|
41624
|
+
);
|
|
41744
41625
|
});
|
|
41745
|
-
const
|
|
41746
|
-
|
|
41747
|
-
|
|
41626
|
+
const subVideoPositions = computed(() => {
|
|
41627
|
+
const positions = {};
|
|
41628
|
+
secondaryMembers.value.forEach((member, index) => {
|
|
41629
|
+
positions[member.member.memberId] = {
|
|
41630
|
+
position: "absolute",
|
|
41631
|
+
width: `${DEFAULT_SUB_VIDEO_WIDTH}px`,
|
|
41632
|
+
height: `${DEFAULT_SUB_VIDEO_HEIGHT}px`,
|
|
41633
|
+
right: "16px",
|
|
41634
|
+
top: `${STATUS_BAR_HEIGHT + 16 + index * (DEFAULT_SUB_VIDEO_HEIGHT + SUB_VIDEO_GAP)}px`
|
|
41635
|
+
};
|
|
41636
|
+
});
|
|
41637
|
+
return positions;
|
|
41748
41638
|
});
|
|
41749
|
-
const
|
|
41750
|
-
|
|
41751
|
-
|
|
41752
|
-
|
|
41753
|
-
|
|
41754
|
-
|
|
41755
|
-
|
|
41756
|
-
|
|
41757
|
-
|
|
41639
|
+
const getVideoItemStyle = (memberId) => {
|
|
41640
|
+
var _a25;
|
|
41641
|
+
if (memberId === ((_a25 = mainMember.value) == null ? void 0 : _a25.member.memberId)) {
|
|
41642
|
+
return {
|
|
41643
|
+
position: "absolute",
|
|
41644
|
+
top: `${STATUS_BAR_HEIGHT}px`,
|
|
41645
|
+
right: "0px",
|
|
41646
|
+
left: "0px",
|
|
41647
|
+
bottom: `${CONTROL_BAR_HEIGHT}px`
|
|
41648
|
+
};
|
|
41758
41649
|
}
|
|
41759
|
-
|
|
41760
|
-
|
|
41761
|
-
|
|
41762
|
-
return
|
|
41763
|
-
|
|
41764
|
-
|
|
41765
|
-
|
|
41766
|
-
|
|
41767
|
-
|
|
41768
|
-
|
|
41769
|
-
|
|
41770
|
-
|
|
41771
|
-
|
|
41772
|
-
|
|
41773
|
-
|
|
41774
|
-
|
|
41775
|
-
|
|
41776
|
-
|
|
41777
|
-
|
|
41778
|
-
|
|
41779
|
-
|
|
41780
|
-
|
|
41781
|
-
|
|
41782
|
-
|
|
41783
|
-
|
|
41784
|
-
|
|
41785
|
-
|
|
41786
|
-
|
|
41787
|
-
|
|
41788
|
-
|
|
41789
|
-
|
|
41790
|
-
|
|
41791
|
-
|
|
41792
|
-
|
|
41793
|
-
|
|
41794
|
-
|
|
41795
|
-
|
|
41796
|
-
function createVideoSendCard(item, index) {
|
|
41797
|
-
const stats = (item == null ? void 0 : item.stats) || {};
|
|
41798
|
-
return {
|
|
41799
|
-
title: `本地视频 ${index + 1}`,
|
|
41800
|
-
subtitle: (item == null ? void 0 : item.desc) || (stats == null ? void 0 : stats.rid) || (stats == null ? void 0 : stats.streamId) || "发送轨道",
|
|
41801
|
-
items: [
|
|
41802
|
-
{ label: "实时码率", value: formatMetricNumber(item == null ? void 0 : item.bitrate, " kb/s") },
|
|
41803
|
-
{ label: "分辨率", value: formatDimension((item == null ? void 0 : item.width) || (stats == null ? void 0 : stats.frameWidth), (item == null ? void 0 : item.height) || (stats == null ? void 0 : stats.frameHeight)) },
|
|
41804
|
-
{ label: "帧率", value: formatMetricNumber((item == null ? void 0 : item.fps) || (stats == null ? void 0 : stats.framesPerSecond), " fps") },
|
|
41805
|
-
{ label: "已发帧数", value: formatMetricNumber(stats == null ? void 0 : stats.framesSent) },
|
|
41806
|
-
{ label: "目标码率", value: formatMetricNumber(stats == null ? void 0 : stats.targetBitrate, " bps") },
|
|
41807
|
-
{ label: "FIR/PLI/NACK", value: `${formatMetricNumber(stats == null ? void 0 : stats.firCount)}/${formatMetricNumber(stats == null ? void 0 : stats.pliCount)}/${formatMetricNumber(stats == null ? void 0 : stats.nackCount)}` },
|
|
41808
|
-
{ label: "重传包数", value: formatMetricNumber(stats == null ? void 0 : stats.retransmittedPacketsSent) },
|
|
41809
|
-
{ label: "受限原因", value: formatReason(stats == null ? void 0 : stats.qualityLimitationReason) },
|
|
41810
|
-
{ label: "分辨率变化", value: formatMetricNumber(stats == null ? void 0 : stats.qualityLimitationResolutionChanges) },
|
|
41811
|
-
{ label: "往返时延", value: formatMetricNumber(stats == null ? void 0 : stats.roundTripTime, " ms") },
|
|
41812
|
-
{ label: "采样时间", value: formatUpdatedAt(stats == null ? void 0 : stats.timestamp) }
|
|
41813
|
-
]
|
|
41814
|
-
};
|
|
41815
|
-
}
|
|
41816
|
-
function createAudioRecvCard(item, index) {
|
|
41817
|
-
const stats = (item == null ? void 0 : item.stats) || {};
|
|
41818
|
-
return {
|
|
41819
|
-
title: `远端音频 ${index + 1}`,
|
|
41820
|
-
subtitle: (item == null ? void 0 : item.uid) || (item == null ? void 0 : item.desc) || (stats == null ? void 0 : stats.streamId) || "接收轨道",
|
|
41821
|
-
items: [
|
|
41822
|
-
{ label: "实时码率", value: formatMetricNumber(item == null ? void 0 : item.bitrate, " kb/s") },
|
|
41823
|
-
{ label: "音频电平", value: formatMetricNumber(item == null ? void 0 : item.db, " dBFS", 1) },
|
|
41824
|
-
{ label: "已收包数", value: formatMetricNumber(stats == null ? void 0 : stats.packetsReceived) },
|
|
41825
|
-
{ label: "已收字节", value: formatBytes(stats == null ? void 0 : stats.bytesReceived) },
|
|
41826
|
-
{ label: "丢包数", value: formatMetricNumber(stats == null ? void 0 : stats.packetsLost) },
|
|
41827
|
-
{ label: "网络抖动", value: formatMetricNumber(stats == null ? void 0 : stats.jitter, " ms") },
|
|
41828
|
-
{ label: "缓冲均值", value: formatMetricNumber(stats == null ? void 0 : stats.jitterBufferAvgDelay, " ms") },
|
|
41829
|
-
{ label: "隐藏事件", value: formatMetricNumber(stats == null ? void 0 : stats.concealmentEvents) },
|
|
41830
|
-
{ label: "静音隐藏", value: formatMetricNumber(stats == null ? void 0 : stats.silentConcealmentEvents) },
|
|
41831
|
-
{ label: "采样时间", value: formatUpdatedAt(stats == null ? void 0 : stats.timestamp) }
|
|
41832
|
-
]
|
|
41833
|
-
};
|
|
41834
|
-
}
|
|
41835
|
-
function createVideoRecvCard(item, index) {
|
|
41836
|
-
const stats = (item == null ? void 0 : item.stats) || {};
|
|
41837
|
-
const memberName = getMemberNameById(item == null ? void 0 : item.uid);
|
|
41838
|
-
return {
|
|
41839
|
-
title: `远端视频 ${index + 1}`,
|
|
41840
|
-
subtitle: memberName || (item == null ? void 0 : item.uid) || (item == null ? void 0 : item.desc) || (stats == null ? void 0 : stats.mimeType) || "接收轨道",
|
|
41841
|
-
items: [
|
|
41842
|
-
{ label: "实时码率", value: formatMetricNumber(item == null ? void 0 : item.bitrate, " kb/s") },
|
|
41843
|
-
{ label: "分辨率", value: formatDimension((item == null ? void 0 : item.width) || (stats == null ? void 0 : stats.frameWidth), (item == null ? void 0 : item.height) || (stats == null ? void 0 : stats.frameHeight)) },
|
|
41844
|
-
{ label: "帧率", value: formatMetricNumber((item == null ? void 0 : item.fps) || (stats == null ? void 0 : stats.framesPerSecond), " fps") },
|
|
41845
|
-
{ label: "已收包数", value: formatMetricNumber(stats == null ? void 0 : stats.packetsReceived) },
|
|
41846
|
-
{ label: "已收字节", value: formatBytes(stats == null ? void 0 : stats.bytesReceived) },
|
|
41847
|
-
{ label: "丢包数", value: formatMetricNumber(stats == null ? void 0 : stats.packetsLost) },
|
|
41848
|
-
{ label: "接收/解码帧", value: `${formatMetricNumber(stats == null ? void 0 : stats.framesReceived)}/${formatMetricNumber(stats == null ? void 0 : stats.framesDecoded)}` },
|
|
41849
|
-
{ label: "丢帧数", value: formatMetricNumber(stats == null ? void 0 : stats.framesDropped) },
|
|
41850
|
-
{ label: "FIR/PLI/NACK", value: `${formatMetricNumber(stats == null ? void 0 : stats.firCount)}/${formatMetricNumber(stats == null ? void 0 : stats.pliCount)}/${formatMetricNumber(stats == null ? void 0 : stats.nackCount)}` },
|
|
41851
|
-
{ label: "缓冲均值", value: formatMetricNumber(stats == null ? void 0 : stats.jitterBufferAvgDelay, " ms") },
|
|
41852
|
-
{ label: "解码器", value: formatReason(stats == null ? void 0 : stats.decoderImplementation) },
|
|
41853
|
-
{ label: "MIME", value: formatReason(stats == null ? void 0 : stats.mimeType) },
|
|
41854
|
-
{ label: "采样时间", value: formatUpdatedAt(stats == null ? void 0 : stats.timestamp) }
|
|
41855
|
-
]
|
|
41856
|
-
};
|
|
41857
|
-
}
|
|
41858
|
-
const detailSections = computed(() => {
|
|
41859
|
-
const details = advancedDetails.value;
|
|
41860
|
-
return [
|
|
41861
|
-
{
|
|
41862
|
-
key: "local-audio",
|
|
41863
|
-
title: "本地音频发送",
|
|
41864
|
-
cards: ((details == null ? void 0 : details.local_audios) || []).map(createAudioSendCard)
|
|
41865
|
-
},
|
|
41866
|
-
{
|
|
41867
|
-
key: "local-video",
|
|
41868
|
-
title: "本地视频发送",
|
|
41869
|
-
cards: ((details == null ? void 0 : details.local_videos) || []).map(createVideoSendCard)
|
|
41870
|
-
},
|
|
41871
|
-
{
|
|
41872
|
-
key: "remote-audio",
|
|
41873
|
-
title: "远端音频接收",
|
|
41874
|
-
cards: ((details == null ? void 0 : details.remote_audios) || []).map(createAudioRecvCard)
|
|
41875
|
-
},
|
|
41876
|
-
{
|
|
41877
|
-
key: "remote-video",
|
|
41878
|
-
title: "远端视频接收",
|
|
41879
|
-
cards: ((details == null ? void 0 : details.remote_videos) || []).map(createVideoRecvCard)
|
|
41880
|
-
}
|
|
41881
|
-
];
|
|
41882
|
-
});
|
|
41883
|
-
watch(showPopup, (visible) => {
|
|
41884
|
-
if (visible) {
|
|
41885
|
-
refreshNetworkQualitySnapshot(false);
|
|
41886
|
-
if (advancedOpen.value) {
|
|
41887
|
-
syncSectionCollapse();
|
|
41888
|
-
startDetailRefresh();
|
|
41889
|
-
}
|
|
41890
|
-
return;
|
|
41891
|
-
}
|
|
41892
|
-
stopDetailRefresh();
|
|
41893
|
-
advancedOpen.value = false;
|
|
41894
|
-
collapsedSections.value = {};
|
|
41895
|
-
advancedDetails.value = void 0;
|
|
41896
|
-
});
|
|
41897
|
-
watch(advancedOpen, (open2) => {
|
|
41898
|
-
if (!showPopup.value) return;
|
|
41899
|
-
if (open2) {
|
|
41900
|
-
syncSectionCollapse(false);
|
|
41901
|
-
startDetailRefresh();
|
|
41902
|
-
} else {
|
|
41903
|
-
stopDetailRefresh();
|
|
41904
|
-
advancedDetails.value = void 0;
|
|
41650
|
+
return subVideoPositions.value[memberId] || {};
|
|
41651
|
+
};
|
|
41652
|
+
const handleSwitchMain = (memberId) => {
|
|
41653
|
+
if (memberId === mainMemberId.value) return;
|
|
41654
|
+
mainMemberId.value = memberId;
|
|
41655
|
+
};
|
|
41656
|
+
watch(
|
|
41657
|
+
() => {
|
|
41658
|
+
var _a25;
|
|
41659
|
+
return ((_a25 = mainMember.value) == null ? void 0 : _a25.member.memberId) || "";
|
|
41660
|
+
},
|
|
41661
|
+
(memberId) => {
|
|
41662
|
+
const focusUid = memberId && memberId !== getUserId() ? memberId : null;
|
|
41663
|
+
void setPreferredRemoteVideoFocus(focusUid);
|
|
41664
|
+
},
|
|
41665
|
+
{ immediate: true }
|
|
41666
|
+
);
|
|
41667
|
+
const handleRetryVideo = async (user) => {
|
|
41668
|
+
var _a25;
|
|
41669
|
+
const memberId = (_a25 = user == null ? void 0 : user.member) == null ? void 0 : _a25.memberId;
|
|
41670
|
+
if (!memberId || memberId === getUserId() || (user == null ? void 0 : user.videoRetrying)) return;
|
|
41671
|
+
await retryRemoteVideoSubscription(memberId);
|
|
41672
|
+
};
|
|
41673
|
+
const statusText = computed(() => {
|
|
41674
|
+
switch (callStatus.value) {
|
|
41675
|
+
case "calling":
|
|
41676
|
+
return "正在呼叫";
|
|
41677
|
+
case "receiving":
|
|
41678
|
+
return "正在接收呼叫";
|
|
41679
|
+
case "connected":
|
|
41680
|
+
return "通话中";
|
|
41681
|
+
case "listening":
|
|
41682
|
+
return "正在监听";
|
|
41683
|
+
case "end":
|
|
41684
|
+
return "通话结束";
|
|
41685
|
+
default:
|
|
41686
|
+
return "通话中";
|
|
41905
41687
|
}
|
|
41906
41688
|
});
|
|
41689
|
+
const callerInfo = ref({});
|
|
41907
41690
|
watch(
|
|
41908
|
-
|
|
41691
|
+
() => callStatus.value,
|
|
41909
41692
|
() => {
|
|
41910
|
-
|
|
41911
|
-
|
|
41693
|
+
try {
|
|
41694
|
+
const info = JSON.parse(
|
|
41695
|
+
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41696
|
+
);
|
|
41697
|
+
callerInfo.value = info || {};
|
|
41698
|
+
} catch {
|
|
41699
|
+
callerInfo.value = {};
|
|
41700
|
+
}
|
|
41912
41701
|
},
|
|
41913
|
-
{
|
|
41702
|
+
{ immediate: true }
|
|
41914
41703
|
);
|
|
41915
|
-
|
|
41916
|
-
|
|
41917
|
-
|
|
41918
|
-
|
|
41919
|
-
|
|
41920
|
-
|
|
41921
|
-
|
|
41922
|
-
|
|
41923
|
-
|
|
41924
|
-
|
|
41925
|
-
|
|
41926
|
-
|
|
41927
|
-
|
|
41928
|
-
|
|
41929
|
-
|
|
41930
|
-
|
|
41931
|
-
|
|
41932
|
-
|
|
41933
|
-
|
|
41934
|
-
|
|
41935
|
-
|
|
41936
|
-
|
|
41937
|
-
|
|
41938
|
-
|
|
41939
|
-
|
|
41940
|
-
|
|
41941
|
-
|
|
41942
|
-
|
|
41943
|
-
|
|
41944
|
-
|
|
41945
|
-
|
|
41946
|
-
|
|
41947
|
-
"onUpdate:visible": _cache[3] || (_cache[3] = ($event) => showPopup.value = $event),
|
|
41948
|
-
trigger: triggerRef.value,
|
|
41949
|
-
gap: 12
|
|
41950
|
-
}, {
|
|
41951
|
-
default: withCtx(() => [
|
|
41952
|
-
createElementVNode("div", _hoisted_4$i, [
|
|
41953
|
-
createElementVNode("div", {
|
|
41954
|
-
class: normalizeClass(["network-quality-popup network-quality-main", themeClass.value])
|
|
41955
|
-
}, [
|
|
41956
|
-
createElementVNode("div", _hoisted_5$f, [
|
|
41957
|
-
_cache[4] || (_cache[4] = createElementVNode("div", { class: "popup-title" }, "网络详情", -1)),
|
|
41958
|
-
createElementVNode("div", _hoisted_6$e, [
|
|
41959
|
-
createElementVNode("button", {
|
|
41960
|
-
type: "button",
|
|
41961
|
-
class: "advanced-toggle",
|
|
41962
|
-
onClick: _cache[1] || (_cache[1] = withModifiers(($event) => advancedOpen.value = !advancedOpen.value, ["stop"]))
|
|
41963
|
-
}, toDisplayString(advancedOpen.value ? "关闭高级模式" : "打开高级模式"), 1),
|
|
41964
|
-
createElementVNode("div", {
|
|
41965
|
-
class: normalizeClass(["popup-status", `is-${unref(networkQualityState).level}`])
|
|
41966
|
-
}, toDisplayString(unref(networkQualityState).label), 3)
|
|
41967
|
-
])
|
|
41968
|
-
]),
|
|
41969
|
-
createElementVNode("div", _hoisted_7$d, toDisplayString(unref(networkQualityState).summary), 1),
|
|
41970
|
-
reasonText.value ? (openBlock(), createElementBlock("div", _hoisted_8$c, toDisplayString(reasonText.value), 1)) : createCommentVNode("", true),
|
|
41971
|
-
createElementVNode("div", _hoisted_9$a, [
|
|
41972
|
-
_cache[5] || (_cache[5] = createElementVNode("div", { class: "popup-section-title" }, "质量概览", -1)),
|
|
41973
|
-
createElementVNode("div", _hoisted_10$a, [
|
|
41974
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(qualityItems.value, (item) => {
|
|
41975
|
-
return openBlock(), createElementBlock("div", {
|
|
41976
|
-
key: item.label,
|
|
41977
|
-
class: "popup-item"
|
|
41978
|
-
}, [
|
|
41979
|
-
createElementVNode("div", _hoisted_11$9, toDisplayString(item.label), 1),
|
|
41980
|
-
createElementVNode("div", _hoisted_12$9, toDisplayString(item.value), 1)
|
|
41981
|
-
]);
|
|
41982
|
-
}), 128))
|
|
41983
|
-
])
|
|
41984
|
-
]),
|
|
41985
|
-
createElementVNode("div", _hoisted_13$7, [
|
|
41986
|
-
_cache[6] || (_cache[6] = createElementVNode("div", { class: "popup-section-title" }, "网络指标", -1)),
|
|
41987
|
-
createElementVNode("div", _hoisted_14$6, [
|
|
41988
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(overviewItems.value, (item) => {
|
|
41989
|
-
return openBlock(), createElementBlock("div", {
|
|
41990
|
-
key: item.label,
|
|
41991
|
-
class: "popup-item"
|
|
41992
|
-
}, [
|
|
41993
|
-
createElementVNode("div", _hoisted_15$5, toDisplayString(item.label), 1),
|
|
41994
|
-
createElementVNode("div", _hoisted_16$5, toDisplayString(item.value), 1)
|
|
41995
|
-
]);
|
|
41996
|
-
}), 128))
|
|
41997
|
-
])
|
|
41998
|
-
])
|
|
41999
|
-
], 2),
|
|
42000
|
-
advancedOpen.value ? (openBlock(), createElementBlock("div", {
|
|
42001
|
-
key: 0,
|
|
42002
|
-
class: normalizeClass(["network-quality-popup network-quality-advanced", themeClass.value]),
|
|
42003
|
-
onClick: _cache[2] || (_cache[2] = withModifiers(() => {
|
|
42004
|
-
}, ["stop"]))
|
|
42005
|
-
}, [
|
|
42006
|
-
createElementVNode("div", _hoisted_17$4, [
|
|
42007
|
-
_cache[7] || (_cache[7] = createElementVNode("div", { class: "popup-title" }, "高级模式", -1)),
|
|
42008
|
-
createElementVNode("div", _hoisted_18$4, [
|
|
42009
|
-
createElementVNode("button", {
|
|
42010
|
-
type: "button",
|
|
42011
|
-
class: "advanced-mini-btn",
|
|
42012
|
-
onClick: toggleAllSections
|
|
42013
|
-
}, toDisplayString(allSectionsExpanded.value ? "全部收起" : "全部展开"), 1)
|
|
42014
|
-
])
|
|
42015
|
-
]),
|
|
42016
|
-
createElementVNode("div", _hoisted_19$4, [
|
|
42017
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(detailSections.value, (section) => {
|
|
42018
|
-
return openBlock(), createElementBlock("div", {
|
|
42019
|
-
key: section.key,
|
|
42020
|
-
class: "popup-section"
|
|
42021
|
-
}, [
|
|
42022
|
-
createElementVNode("button", {
|
|
42023
|
-
type: "button",
|
|
42024
|
-
class: normalizeClass(["detail-section-toggle", { collapsed: isSectionCollapsed(section.key) }]),
|
|
42025
|
-
onClick: ($event) => toggleSection(section.key)
|
|
42026
|
-
}, [
|
|
42027
|
-
createElementVNode("span", _hoisted_21$2, [
|
|
42028
|
-
createElementVNode("span", _hoisted_22$2, toDisplayString(section.title), 1),
|
|
42029
|
-
createElementVNode("span", _hoisted_23$2, "(" + toDisplayString(section.cards.length) + ")", 1)
|
|
42030
|
-
]),
|
|
42031
|
-
createElementVNode("span", _hoisted_24$2, toDisplayString(isSectionCollapsed(section.key) ? "展开" : "收起"), 1)
|
|
42032
|
-
], 10, _hoisted_20$4),
|
|
42033
|
-
!isSectionCollapsed(section.key) && section.cards.length ? (openBlock(), createElementBlock("div", _hoisted_25$2, [
|
|
42034
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(section.cards, (card) => {
|
|
42035
|
-
return openBlock(), createElementBlock("div", {
|
|
42036
|
-
key: card.title,
|
|
42037
|
-
class: "metric-card"
|
|
42038
|
-
}, [
|
|
42039
|
-
createElementVNode("div", _hoisted_26$2, [
|
|
42040
|
-
createElementVNode("div", _hoisted_27$2, toDisplayString(card.title), 1),
|
|
42041
|
-
createElementVNode("div", _hoisted_28$2, toDisplayString(card.subtitle), 1)
|
|
42042
|
-
]),
|
|
42043
|
-
createElementVNode("div", _hoisted_29$2, [
|
|
42044
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(card.items, (item) => {
|
|
42045
|
-
return openBlock(), createElementBlock("div", {
|
|
42046
|
-
key: `${card.title}-${item.label}`,
|
|
42047
|
-
class: "metric-card-item"
|
|
42048
|
-
}, [
|
|
42049
|
-
createElementVNode("div", _hoisted_30$2, toDisplayString(item.label), 1),
|
|
42050
|
-
createElementVNode("div", _hoisted_31$1, toDisplayString(item.value), 1)
|
|
42051
|
-
]);
|
|
42052
|
-
}), 128))
|
|
42053
|
-
])
|
|
42054
|
-
]);
|
|
42055
|
-
}), 128))
|
|
42056
|
-
])) : !isSectionCollapsed(section.key) ? (openBlock(), createElementBlock("div", _hoisted_32$1, "暂无数据")) : createCommentVNode("", true)
|
|
42057
|
-
]);
|
|
42058
|
-
}), 128))
|
|
42059
|
-
])
|
|
42060
|
-
], 2)) : createCommentVNode("", true)
|
|
42061
|
-
])
|
|
42062
|
-
]),
|
|
42063
|
-
_: 1
|
|
42064
|
-
}, 8, ["visible", "trigger"])
|
|
42065
|
-
], 2);
|
|
42066
|
-
};
|
|
42067
|
-
}
|
|
42068
|
-
});
|
|
42069
|
-
const NetworkQualitySignal = /* @__PURE__ */ _export_sfc(_sfc_main$o, [["__scopeId", "data-v-3378006f"]]);
|
|
42070
|
-
const _hoisted_1$l = { class: "network-copy" };
|
|
42071
|
-
const _sfc_main$n = /* @__PURE__ */ defineComponent({
|
|
42072
|
-
__name: "netWorkStatus",
|
|
42073
|
-
props: {
|
|
42074
|
-
theme: { default: "dark" }
|
|
42075
|
-
},
|
|
42076
|
-
setup(__props) {
|
|
42077
|
-
const props = __props;
|
|
42078
|
-
const themeClass = computed(() => `theme-${props.theme}`);
|
|
42079
|
-
const displayLabel = computed(() => {
|
|
42080
|
-
if (networkQualityState.isStale) {
|
|
42081
|
-
return "网络检测中";
|
|
41704
|
+
const onChange = async (type) => {
|
|
41705
|
+
switch (type) {
|
|
41706
|
+
case RoomModalSelectType.microphoneClick:
|
|
41707
|
+
if (micOperationBusy.value) return;
|
|
41708
|
+
if (isAuthority.value) {
|
|
41709
|
+
showNotification(alertMsg, "warning", 5e3);
|
|
41710
|
+
return;
|
|
41711
|
+
}
|
|
41712
|
+
if (meState2.value.microPhoneState === "1") {
|
|
41713
|
+
await closeMic();
|
|
41714
|
+
} else {
|
|
41715
|
+
await openMic();
|
|
41716
|
+
}
|
|
41717
|
+
break;
|
|
41718
|
+
case RoomModalSelectType.cameraClick:
|
|
41719
|
+
if (cameraOperationBusy.value) return;
|
|
41720
|
+
if (isAuthority.value) {
|
|
41721
|
+
alert(alertMsg);
|
|
41722
|
+
return;
|
|
41723
|
+
}
|
|
41724
|
+
if (meState2.value.cameraState === "1") {
|
|
41725
|
+
await closeCamera();
|
|
41726
|
+
} else {
|
|
41727
|
+
await openCamera();
|
|
41728
|
+
}
|
|
41729
|
+
break;
|
|
41730
|
+
case RoomModalSelectType.acceptClick:
|
|
41731
|
+
acceptCall();
|
|
41732
|
+
break;
|
|
41733
|
+
case RoomModalSelectType.endClick:
|
|
41734
|
+
endCall();
|
|
41735
|
+
break;
|
|
42082
41736
|
}
|
|
42083
|
-
return networkQualityState.label;
|
|
42084
|
-
});
|
|
42085
|
-
return (_ctx, _cache) => {
|
|
42086
|
-
return openBlock(), createElementBlock("div", {
|
|
42087
|
-
class: normalizeClass(["network-situation", themeClass.value])
|
|
42088
|
-
}, [
|
|
42089
|
-
createVNode(NetworkQualitySignal, {
|
|
42090
|
-
theme: _ctx.theme,
|
|
42091
|
-
size: "compact"
|
|
42092
|
-
}, null, 8, ["theme"]),
|
|
42093
|
-
createElementVNode("div", _hoisted_1$l, [
|
|
42094
|
-
createElementVNode("span", {
|
|
42095
|
-
class: normalizeClass(["network-label", `is-${unref(networkQualityState).level}`])
|
|
42096
|
-
}, toDisplayString(displayLabel.value), 3)
|
|
42097
|
-
])
|
|
42098
|
-
], 2);
|
|
42099
41737
|
};
|
|
42100
|
-
|
|
42101
|
-
|
|
42102
|
-
|
|
42103
|
-
|
|
42104
|
-
|
|
42105
|
-
|
|
42106
|
-
|
|
42107
|
-
|
|
42108
|
-
|
|
42109
|
-
|
|
42110
|
-
|
|
42111
|
-
}
|
|
42112
|
-
|
|
42113
|
-
|
|
42114
|
-
|
|
42115
|
-
|
|
42116
|
-
|
|
42117
|
-
|
|
42118
|
-
|
|
42119
|
-
|
|
42120
|
-
|
|
42121
|
-
|
|
42122
|
-
|
|
42123
|
-
|
|
42124
|
-
|
|
42125
|
-
|
|
42126
|
-
|
|
42127
|
-
|
|
42128
|
-
|
|
42129
|
-
|
|
42130
|
-
|
|
42131
|
-
|
|
42132
|
-
const props = __props;
|
|
42133
|
-
const userId = getUserId();
|
|
42134
|
-
const joinTimeObj = ref("");
|
|
42135
|
-
const speakerId = ref(null);
|
|
42136
|
-
const lastGridLayout = ref("grid-9");
|
|
42137
|
-
const getUserName2 = (user) => {
|
|
42138
|
-
var _a25, _b25, _c2;
|
|
42139
|
-
return ((_a25 = user == null ? void 0 : user.member) == null ? void 0 : _a25.memberId) == userId ? `(我)${(_b25 = user == null ? void 0 : user.member) == null ? void 0 : _b25.name}` : ((_c2 = user == null ? void 0 : user.member) == null ? void 0 : _c2.name) || "未知用户";
|
|
41738
|
+
const acceptCall = () => {
|
|
41739
|
+
const meetingInfo = JSON.parse(
|
|
41740
|
+
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41741
|
+
);
|
|
41742
|
+
setCallStatus("connected");
|
|
41743
|
+
stopSosFlash();
|
|
41744
|
+
getAnswerCall({
|
|
41745
|
+
meetingId: meetingInfo.meetingId,
|
|
41746
|
+
memberId: getUserId(),
|
|
41747
|
+
cameraStatus: "0",
|
|
41748
|
+
audioStatus: "0"
|
|
41749
|
+
}).then(() => {
|
|
41750
|
+
return getJoinCall({
|
|
41751
|
+
meetingId: meetingInfo.meetingId,
|
|
41752
|
+
memberId: getUserId(),
|
|
41753
|
+
cameraStatus: "0",
|
|
41754
|
+
audioStatus: "0"
|
|
41755
|
+
});
|
|
41756
|
+
}).then((resp) => {
|
|
41757
|
+
if (resp && resp.code === 200) {
|
|
41758
|
+
sessionStorage.setItem("JS_MEETING_INFO", JSON.stringify(resp.data));
|
|
41759
|
+
console.log("拨打电话", resp.data.meetingToken);
|
|
41760
|
+
setTimeout(() => {
|
|
41761
|
+
joinRoom();
|
|
41762
|
+
}, 100);
|
|
41763
|
+
stopRingtone();
|
|
41764
|
+
recordMeeting("start");
|
|
41765
|
+
}
|
|
41766
|
+
}).catch((err) => {
|
|
41767
|
+
console.error("接听失败", err);
|
|
41768
|
+
setCallStatus("end");
|
|
41769
|
+
});
|
|
42140
41770
|
};
|
|
42141
|
-
const
|
|
42142
|
-
|
|
42143
|
-
|
|
42144
|
-
|
|
42145
|
-
|
|
42146
|
-
|
|
42147
|
-
|
|
42148
|
-
|
|
42149
|
-
|
|
42150
|
-
|
|
41771
|
+
const endCall = async () => {
|
|
41772
|
+
visible.value = false;
|
|
41773
|
+
stopSosFlash();
|
|
41774
|
+
const meetingInfo = JSON.parse(
|
|
41775
|
+
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41776
|
+
);
|
|
41777
|
+
setCallStatus("end");
|
|
41778
|
+
try {
|
|
41779
|
+
const res = await getHangUpCall({
|
|
41780
|
+
meetingId: meetingInfo.meetingId,
|
|
41781
|
+
memberId: getUserId()
|
|
41782
|
+
});
|
|
41783
|
+
if (res.code === 200) {
|
|
41784
|
+
await logoutRoomAction();
|
|
41785
|
+
clearTimer();
|
|
41786
|
+
recordMeeting("stop");
|
|
42151
41787
|
}
|
|
42152
|
-
)
|
|
42153
|
-
|
|
42154
|
-
|
|
42155
|
-
var _a25, _b25;
|
|
42156
|
-
if (props.layout !== "speaker") return null;
|
|
42157
|
-
const focusedUid = (_b25 = (_a25 = speakerUser.value) == null ? void 0 : _a25.member) == null ? void 0 : _b25.memberId;
|
|
42158
|
-
return focusedUid && focusedUid !== userId ? focusedUid : null;
|
|
42159
|
-
});
|
|
42160
|
-
const filteredMembers = computed(() => {
|
|
42161
|
-
return allJoinedMembers.value;
|
|
42162
|
-
});
|
|
42163
|
-
const setSpeaker = (user) => {
|
|
42164
|
-
var _a25;
|
|
42165
|
-
speakerId.value = (_a25 = user == null ? void 0 : user.member) == null ? void 0 : _a25.memberId;
|
|
42166
|
-
if (props.layout !== "speaker") {
|
|
42167
|
-
emit("layout-change", "speaker");
|
|
41788
|
+
} catch (err) {
|
|
41789
|
+
console.error("挂断失败", err);
|
|
41790
|
+
await logoutRoomAction();
|
|
42168
41791
|
}
|
|
42169
41792
|
};
|
|
42170
|
-
const
|
|
42171
|
-
|
|
42172
|
-
|
|
41793
|
+
const stopMonitoring = async () => {
|
|
41794
|
+
visible.value = false;
|
|
41795
|
+
const meetingInfo = JSON.parse(
|
|
41796
|
+
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41797
|
+
);
|
|
41798
|
+
try {
|
|
41799
|
+
const res = await getMeetingLeave({
|
|
41800
|
+
meetingId: meetingInfo.meetingId,
|
|
41801
|
+
memberId: getUserId()
|
|
41802
|
+
});
|
|
41803
|
+
if (res.code === 200) {
|
|
41804
|
+
await logoutRoomAction();
|
|
41805
|
+
clearTimer();
|
|
41806
|
+
}
|
|
41807
|
+
} catch (err) {
|
|
41808
|
+
console.error("离开失败", err);
|
|
41809
|
+
await logoutRoomAction();
|
|
42173
41810
|
}
|
|
42174
41811
|
};
|
|
42175
|
-
const
|
|
42176
|
-
|
|
42177
|
-
|
|
42178
|
-
|
|
42179
|
-
|
|
42180
|
-
};
|
|
42181
|
-
const
|
|
42182
|
-
|
|
41812
|
+
const clearTimer = () => {
|
|
41813
|
+
if (timer) {
|
|
41814
|
+
clearInterval(timer);
|
|
41815
|
+
timer = null;
|
|
41816
|
+
}
|
|
41817
|
+
};
|
|
41818
|
+
const recordMeeting = (newState) => {
|
|
41819
|
+
const meetingInfo = JSON.parse(
|
|
41820
|
+
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41821
|
+
);
|
|
41822
|
+
let params = {
|
|
41823
|
+
meetingId: meetingInfo.meetingId,
|
|
41824
|
+
memberId: getUserId(),
|
|
41825
|
+
cmd: newState
|
|
41826
|
+
};
|
|
41827
|
+
getMcuCtrl(params).then(() => {
|
|
41828
|
+
}).catch(() => {
|
|
41829
|
+
});
|
|
41830
|
+
};
|
|
41831
|
+
const toggleDeviceSelector = (deviceType) => {
|
|
41832
|
+
currentDeviceType.value = deviceType;
|
|
41833
|
+
showDeviceSelector.value = !showDeviceSelector.value;
|
|
42183
41834
|
};
|
|
42184
|
-
const emit = __emit;
|
|
42185
|
-
let timer = null;
|
|
42186
|
-
watch(
|
|
42187
|
-
() => props.layout,
|
|
42188
|
-
(layout) => {
|
|
42189
|
-
if (layout !== "speaker") {
|
|
42190
|
-
lastGridLayout.value = layout;
|
|
42191
|
-
}
|
|
42192
|
-
},
|
|
42193
|
-
{ immediate: true }
|
|
42194
|
-
);
|
|
42195
41835
|
watch(
|
|
42196
|
-
() =>
|
|
42197
|
-
() => {
|
|
42198
|
-
if (
|
|
42199
|
-
|
|
42200
|
-
timer = null;
|
|
42201
|
-
}
|
|
42202
|
-
if (props.joinTime) {
|
|
42203
|
-
timer = setInterval(() => {
|
|
42204
|
-
const now = +/* @__PURE__ */ new Date();
|
|
42205
|
-
joinTimeObj.value = formatDuringObject((now - props.joinTime) / 1e3);
|
|
42206
|
-
}, 1e3);
|
|
41836
|
+
() => visible.value,
|
|
41837
|
+
(newValue) => {
|
|
41838
|
+
if (newValue) {
|
|
41839
|
+
showDeviceSelector.value = false;
|
|
42207
41840
|
}
|
|
42208
|
-
},
|
|
42209
|
-
{
|
|
42210
|
-
immediate: true
|
|
42211
41841
|
}
|
|
42212
41842
|
);
|
|
42213
|
-
onMounted(
|
|
42214
|
-
await nextTick();
|
|
42215
|
-
setTimeout(() => {
|
|
42216
|
-
mountTracks();
|
|
42217
|
-
}, 100);
|
|
41843
|
+
onMounted(() => {
|
|
42218
41844
|
});
|
|
42219
|
-
watch(
|
|
42220
|
-
() => members.value.length,
|
|
42221
|
-
async (len, prevLen) => {
|
|
42222
|
-
if (!len || len === prevLen) return;
|
|
42223
|
-
await nextTick();
|
|
42224
|
-
setTimeout(() => mountTracks(), 0);
|
|
42225
|
-
},
|
|
42226
|
-
{ flush: "post" }
|
|
42227
|
-
);
|
|
42228
|
-
watch(
|
|
42229
|
-
preferredRemoteVideoFocusId,
|
|
42230
|
-
(focusedUid) => {
|
|
42231
|
-
void setPreferredRemoteVideoFocus(focusedUid);
|
|
42232
|
-
},
|
|
42233
|
-
{ immediate: true }
|
|
42234
|
-
);
|
|
42235
41845
|
onUnmounted(() => {
|
|
42236
|
-
void setPreferredRemoteVideoFocus(null);
|
|
42237
41846
|
if (timer) {
|
|
42238
41847
|
clearInterval(timer);
|
|
42239
41848
|
timer = null;
|
|
42240
41849
|
}
|
|
42241
41850
|
});
|
|
42242
41851
|
return (_ctx, _cache) => {
|
|
42243
|
-
return openBlock(),
|
|
42244
|
-
|
|
42245
|
-
|
|
42246
|
-
|
|
42247
|
-
|
|
42248
|
-
]),
|
|
42249
|
-
createElementVNode("div", _hoisted_3$j, [
|
|
42250
|
-
createElementVNode("span", null, toDisplayString(joinTimeObj.value), 1),
|
|
42251
|
-
createVNode(SvgIcon, {
|
|
42252
|
-
name: _ctx.isFullscreen ? "NoFullscreenIcon" : "FullscreenIcon",
|
|
42253
|
-
class: "icon-inactive",
|
|
42254
|
-
onClick: handleFullscreenClick
|
|
42255
|
-
}, null, 8, ["name"])
|
|
42256
|
-
])
|
|
42257
|
-
]),
|
|
42258
|
-
createElementVNode("div", {
|
|
42259
|
-
class: normalizeClass(["js-dialog-content", [layoutClass.value, { "is-fullscreen-layout": _ctx.isFullscreen }]])
|
|
41852
|
+
return openBlock(), createBlock(Teleport, { to: "body" }, [
|
|
41853
|
+
unref(sosFlashVisible) ? (openBlock(), createElementBlock("div", _hoisted_1$m)) : createCommentVNode("", true),
|
|
41854
|
+
unref(visible) ? (openBlock(), createElementBlock("div", {
|
|
41855
|
+
key: 1,
|
|
41856
|
+
class: normalizeClass(["js-dialog-overlay", themeClass.value])
|
|
42260
41857
|
}, [
|
|
42261
|
-
createElementVNode("div",
|
|
42262
|
-
|
|
42263
|
-
|
|
42264
|
-
|
|
42265
|
-
|
|
42266
|
-
|
|
42267
|
-
|
|
42268
|
-
|
|
42269
|
-
|
|
42270
|
-
|
|
42271
|
-
|
|
42272
|
-
|
|
42273
|
-
|
|
42274
|
-
|
|
42275
|
-
|
|
42276
|
-
|
|
42277
|
-
|
|
42278
|
-
|
|
42279
|
-
|
|
42280
|
-
|
|
42281
|
-
|
|
42282
|
-
|
|
42283
|
-
|
|
42284
|
-
|
|
42285
|
-
|
|
41858
|
+
createElementVNode("div", _hoisted_2$l, [
|
|
41859
|
+
createElementVNode("div", _hoisted_3$k, [
|
|
41860
|
+
createElementVNode("div", _hoisted_4$i, [
|
|
41861
|
+
createElementVNode("div", null, [
|
|
41862
|
+
createVNode(NetWorkStatus, { theme: _ctx.theme }, null, 8, ["theme"])
|
|
41863
|
+
]),
|
|
41864
|
+
isReceiving.value && callerInfo.value ? (openBlock(), createElementBlock("div", _hoisted_5$f, [
|
|
41865
|
+
createElementVNode("div", _hoisted_6$e, toDisplayString(unref(getUserAvatar)(callerInfo.value)), 1),
|
|
41866
|
+
createElementVNode("div", _hoisted_7$d, [
|
|
41867
|
+
createElementVNode("div", _hoisted_8$c, toDisplayString(callerInfo.value.memberName || "未知来电"), 1),
|
|
41868
|
+
callerInfo.value.shortNumber ? (openBlock(), createElementBlock("div", _hoisted_9$a, " 分机:" + toDisplayString(callerInfo.value.shortNumber), 1)) : createCommentVNode("", true)
|
|
41869
|
+
])
|
|
41870
|
+
])) : createCommentVNode("", true)
|
|
41871
|
+
]),
|
|
41872
|
+
createElementVNode("div", _hoisted_10$a, [
|
|
41873
|
+
createElementVNode("span", null, toDisplayString(statusText.value), 1)
|
|
41874
|
+
])
|
|
41875
|
+
]),
|
|
41876
|
+
createElementVNode("div", {
|
|
41877
|
+
class: normalizeClass(["video-container", layoutClass.value])
|
|
41878
|
+
}, [
|
|
41879
|
+
visibleMembers.value.length ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(visibleMembers.value, (user) => {
|
|
41880
|
+
var _a25, _b25;
|
|
41881
|
+
return openBlock(), createElementBlock("div", {
|
|
41882
|
+
key: user.member.memberId,
|
|
41883
|
+
class: normalizeClass(["video-item", {
|
|
41884
|
+
"is-main": ((_a25 = mainMember.value) == null ? void 0 : _a25.member.memberId) === user.member.memberId,
|
|
41885
|
+
"is-secondary": ((_b25 = mainMember.value) == null ? void 0 : _b25.member.memberId) !== user.member.memberId
|
|
41886
|
+
}]),
|
|
41887
|
+
style: normalizeStyle(getVideoItemStyle(user.member.memberId)),
|
|
41888
|
+
onClick: ($event) => handleSwitchMain(user.member.memberId)
|
|
42286
41889
|
}, [
|
|
42287
|
-
|
|
42288
|
-
|
|
42289
|
-
|
|
42290
|
-
|
|
42291
|
-
|
|
42292
|
-
|
|
42293
|
-
|
|
42294
|
-
|
|
42295
|
-
(
|
|
42296
|
-
]
|
|
42297
|
-
|
|
42298
|
-
|
|
42299
|
-
createElementVNode("div",
|
|
42300
|
-
|
|
42301
|
-
|
|
42302
|
-
|
|
42303
|
-
|
|
42304
|
-
|
|
42305
|
-
|
|
42306
|
-
|
|
42307
|
-
|
|
42308
|
-
|
|
42309
|
-
|
|
42310
|
-
|
|
42311
|
-
|
|
42312
|
-
|
|
42313
|
-
|
|
42314
|
-
|
|
42315
|
-
|
|
42316
|
-
|
|
42317
|
-
(
|
|
42318
|
-
|
|
42319
|
-
|
|
42320
|
-
|
|
42321
|
-
|
|
42322
|
-
|
|
42323
|
-
|
|
42324
|
-
|
|
42325
|
-
|
|
42326
|
-
|
|
42327
|
-
|
|
42328
|
-
|
|
42329
|
-
|
|
42330
|
-
|
|
42331
|
-
|
|
42332
|
-
|
|
42333
|
-
|
|
42334
|
-
|
|
42335
|
-
|
|
42336
|
-
|
|
42337
|
-
|
|
42338
|
-
|
|
42339
|
-
}])
|
|
41890
|
+
createElementVNode("div", _hoisted_12$9, [
|
|
41891
|
+
withDirectives(createElementVNode("div", {
|
|
41892
|
+
id: unref(getUserId)() === user.member.memberId ? "my-video" : `other-${user.member.memberId}`,
|
|
41893
|
+
class: "video-slot"
|
|
41894
|
+
}, null, 8, _hoisted_13$7), [
|
|
41895
|
+
[vShow, (user == null ? void 0 : user.cameraStatus) === "1"]
|
|
41896
|
+
]),
|
|
41897
|
+
withDirectives(createElementVNode("div", _hoisted_14$6, [
|
|
41898
|
+
createElementVNode("div", _hoisted_15$5, toDisplayString(unref(getUserAvatar)(user)), 1)
|
|
41899
|
+
], 512), [
|
|
41900
|
+
[vShow, (user == null ? void 0 : user.cameraStatus) !== "1"]
|
|
41901
|
+
]),
|
|
41902
|
+
withDirectives(createElementVNode("div", _hoisted_16$5, [
|
|
41903
|
+
_cache[6] || (_cache[6] = createElementVNode("div", { class: "video-loading-spinner" }, null, -1)),
|
|
41904
|
+
createElementVNode("div", _hoisted_17$4, toDisplayString((user == null ? void 0 : user.videoRetrying) ? "重新加载中..." : "加载中..."), 1)
|
|
41905
|
+
], 512), [
|
|
41906
|
+
[vShow, (user == null ? void 0 : user.loading) && (user == null ? void 0 : user.cameraStatus) === "1"]
|
|
41907
|
+
]),
|
|
41908
|
+
withDirectives(createElementVNode("div", _hoisted_18$4, [
|
|
41909
|
+
_cache[7] || (_cache[7] = createElementVNode("div", { class: "video-loading-text" }, "视频加载失败", -1)),
|
|
41910
|
+
createElementVNode("button", {
|
|
41911
|
+
type: "button",
|
|
41912
|
+
class: "video-retry-button",
|
|
41913
|
+
disabled: user == null ? void 0 : user.videoRetrying,
|
|
41914
|
+
onClick: withModifiers(($event) => handleRetryVideo(user), ["stop"])
|
|
41915
|
+
}, toDisplayString((user == null ? void 0 : user.videoRetrying) ? "重新加载中..." : "重新加载"), 9, _hoisted_19$4)
|
|
41916
|
+
], 512), [
|
|
41917
|
+
[vShow, (user == null ? void 0 : user.videoLoadFailed) && (user == null ? void 0 : user.cameraStatus) === "1"]
|
|
41918
|
+
]),
|
|
41919
|
+
createElementVNode("div", _hoisted_20$4, [
|
|
41920
|
+
createElementVNode("span", _hoisted_21$2, toDisplayString(user.member.name || "未知成员"), 1),
|
|
41921
|
+
user.member.memberId === unref(getUserId)() ? (openBlock(), createElementBlock("span", _hoisted_22$2, "(我)")) : createCommentVNode("", true)
|
|
41922
|
+
])
|
|
41923
|
+
])
|
|
41924
|
+
], 14, _hoisted_11$9);
|
|
41925
|
+
}), 128)) : (openBlock(), createElementBlock("div", _hoisted_23$2, [..._cache[8] || (_cache[8] = [
|
|
41926
|
+
createElementVNode("span", null, "等待成员加入...", -1)
|
|
41927
|
+
])]))
|
|
41928
|
+
], 2),
|
|
41929
|
+
createElementVNode("div", _hoisted_24$2, [
|
|
41930
|
+
isConnected.value ? (openBlock(), createElementBlock("div", _hoisted_25$2, [
|
|
41931
|
+
createElementVNode("span", _hoisted_26$2, toDisplayString(joinTimeObj.value), 1)
|
|
41932
|
+
])) : createCommentVNode("", true),
|
|
41933
|
+
createElementVNode("div", _hoisted_27$2, [
|
|
41934
|
+
isConnected.value || isForcibleInsertion.value ? (openBlock(), createElementBlock("div", {
|
|
41935
|
+
key: 0,
|
|
41936
|
+
ref_key: "micRef",
|
|
41937
|
+
ref: micRef
|
|
41938
|
+
}, [
|
|
41939
|
+
createElementVNode("button", {
|
|
41940
|
+
class: normalizeClass(["control-btn", { "is-disabled": unref(micOperationBusy) }]),
|
|
41941
|
+
onClick: _cache[0] || (_cache[0] = ($event) => onChange(unref(RoomModalSelectType).microphoneClick))
|
|
42340
41942
|
}, [
|
|
42341
|
-
|
|
42342
|
-
|
|
42343
|
-
|
|
42344
|
-
|
|
42345
|
-
|
|
42346
|
-
|
|
42347
|
-
}, null, 8, ["name"])
|
|
42348
|
-
], 2),
|
|
42349
|
-
createElementVNode("div", {
|
|
42350
|
-
class: normalizeClass(["indicator cam", (user == null ? void 0 : user.cameraStatus) == "1" ? "on" : "off"])
|
|
42351
|
-
}, [
|
|
42352
|
-
createVNode(SvgIcon, {
|
|
42353
|
-
name: (user == null ? void 0 : user.cameraStatus) == "1" ? "CameraIcon" : "CameraSlashIcon",
|
|
42354
|
-
size: 13
|
|
42355
|
-
}, null, 8, ["name"])
|
|
42356
|
-
], 2)
|
|
42357
|
-
], 2)) : createCommentVNode("", true),
|
|
41943
|
+
createVNode(SvgIcon, {
|
|
41944
|
+
name: unref(meState2).microPhoneState == "1" ? "MicrophoneIcon" : "MicrophoneSlashIcon",
|
|
41945
|
+
size: 20
|
|
41946
|
+
}, null, 8, ["name"]),
|
|
41947
|
+
_cache[9] || (_cache[9] = createElementVNode("span", null, "麦克风", -1))
|
|
41948
|
+
], 2),
|
|
42358
41949
|
createElementVNode("div", {
|
|
42359
|
-
class: normalizeClass(["
|
|
42360
|
-
|
|
42361
|
-
|
|
42362
|
-
|
|
42363
|
-
|
|
42364
|
-
|
|
42365
|
-
|
|
42366
|
-
|
|
42367
|
-
|
|
42368
|
-
|
|
42369
|
-
|
|
42370
|
-
|
|
42371
|
-
|
|
41950
|
+
class: normalizeClass(["device-dropdown-trigger", { "is-disabled": unref(micOperationBusy) }]),
|
|
41951
|
+
onClick: _cache[1] || (_cache[1] = ($event) => toggleDeviceSelector("microphone"))
|
|
41952
|
+
}, [
|
|
41953
|
+
createVNode(SvgIcon, {
|
|
41954
|
+
name: "TriangleIcon",
|
|
41955
|
+
size: 9
|
|
41956
|
+
})
|
|
41957
|
+
], 2)
|
|
41958
|
+
], 512)) : createCommentVNode("", true),
|
|
41959
|
+
isReceiving.value ? (openBlock(), createElementBlock("button", {
|
|
41960
|
+
key: 1,
|
|
41961
|
+
class: "accept-call-btn",
|
|
41962
|
+
onClick: acceptCall
|
|
41963
|
+
}, [
|
|
41964
|
+
createVNode(SvgIcon, {
|
|
41965
|
+
name: "PhoneIcon",
|
|
41966
|
+
size: 21
|
|
41967
|
+
}),
|
|
41968
|
+
_cache[10] || (_cache[10] = createElementVNode("span", null, "接听", -1))
|
|
41969
|
+
])) : createCommentVNode("", true),
|
|
41970
|
+
isCalling.value || isReceiving.value || isConnected.value ? (openBlock(), createElementBlock("button", {
|
|
41971
|
+
key: 2,
|
|
41972
|
+
class: "end-call-btn",
|
|
41973
|
+
onClick: endCall
|
|
41974
|
+
}, [
|
|
41975
|
+
createVNode(SvgIcon, {
|
|
41976
|
+
name: "HandUpIcon",
|
|
41977
|
+
size: 21,
|
|
41978
|
+
"color-class": "handUp"
|
|
41979
|
+
}),
|
|
41980
|
+
createElementVNode("span", null, toDisplayString(isReceiving.value ? "拒绝" : "挂断"), 1)
|
|
41981
|
+
])) : createCommentVNode("", true),
|
|
41982
|
+
isListening.value ? (openBlock(), createElementBlock("button", {
|
|
41983
|
+
key: 3,
|
|
41984
|
+
class: "end-call-btn",
|
|
41985
|
+
onClick: stopMonitoring
|
|
41986
|
+
}, [
|
|
41987
|
+
createVNode(SvgIcon, {
|
|
41988
|
+
name: "HandUpIcon",
|
|
41989
|
+
size: 21,
|
|
41990
|
+
"color-class": "handUp"
|
|
41991
|
+
}),
|
|
41992
|
+
_cache[11] || (_cache[11] = createElementVNode("span", null, "结束监听", -1))
|
|
41993
|
+
])) : createCommentVNode("", true),
|
|
41994
|
+
isForcibleInsertion.value ? (openBlock(), createElementBlock("button", {
|
|
41995
|
+
key: 4,
|
|
41996
|
+
class: "end-call-btn",
|
|
41997
|
+
onClick: stopMonitoring
|
|
41998
|
+
}, [
|
|
41999
|
+
createVNode(SvgIcon, {
|
|
42000
|
+
name: "HandUpIcon",
|
|
42001
|
+
size: 20
|
|
42002
|
+
}),
|
|
42003
|
+
_cache[12] || (_cache[12] = createElementVNode("span", null, "退出通话", -1))
|
|
42004
|
+
])) : createCommentVNode("", true),
|
|
42005
|
+
isConnected.value || isForcibleInsertion.value ? (openBlock(), createElementBlock("div", {
|
|
42006
|
+
key: 5,
|
|
42007
|
+
ref_key: "cameraRef",
|
|
42008
|
+
ref: cameraRef
|
|
42009
|
+
}, [
|
|
42010
|
+
createElementVNode("button", {
|
|
42011
|
+
class: normalizeClass(["control-btn", { "is-disabled": unref(cameraOperationBusy) }]),
|
|
42012
|
+
onClick: _cache[2] || (_cache[2] = ($event) => onChange(unref(RoomModalSelectType).cameraClick))
|
|
42013
|
+
}, [
|
|
42014
|
+
createVNode(SvgIcon, {
|
|
42015
|
+
name: unref(meState2).cameraState == "1" ? "CameraIcon" : "CameraSlashIcon",
|
|
42016
|
+
size: 20
|
|
42017
|
+
}, null, 8, ["name"]),
|
|
42018
|
+
_cache[13] || (_cache[13] = createElementVNode("span", null, "摄像头", -1))
|
|
42019
|
+
], 2),
|
|
42020
|
+
createElementVNode("div", {
|
|
42021
|
+
class: normalizeClass(["device-dropdown-trigger", { "is-disabled": unref(cameraOperationBusy) }]),
|
|
42022
|
+
onClick: _cache[3] || (_cache[3] = ($event) => toggleDeviceSelector("camera"))
|
|
42023
|
+
}, [
|
|
42024
|
+
createVNode(SvgIcon, {
|
|
42025
|
+
name: "TriangleIcon",
|
|
42026
|
+
size: 9
|
|
42027
|
+
})
|
|
42028
|
+
], 2)
|
|
42029
|
+
], 512)) : createCommentVNode("", true)
|
|
42030
|
+
]),
|
|
42031
|
+
isConnected.value ? (openBlock(), createElementBlock("div", _hoisted_28$2, [
|
|
42032
|
+
createVNode(SvgIcon, {
|
|
42033
|
+
name: "TranscribeIcon",
|
|
42034
|
+
size: 22
|
|
42035
|
+
}),
|
|
42036
|
+
_cache[14] || (_cache[14] = createElementVNode("span", null, "录制中", -1))
|
|
42037
|
+
])) : createCommentVNode("", true)
|
|
42038
|
+
])
|
|
42039
|
+
]),
|
|
42040
|
+
createVNode(SmartPopup, {
|
|
42041
|
+
visible: showDeviceSelector.value,
|
|
42042
|
+
"onUpdate:visible": _cache[5] || (_cache[5] = ($event) => showDeviceSelector.value = $event),
|
|
42043
|
+
trigger: currentDeviceType.value == "microphone" ? micRef.value : cameraRef.value,
|
|
42044
|
+
gap: 10
|
|
42045
|
+
}, {
|
|
42046
|
+
default: withCtx(() => [
|
|
42047
|
+
createVNode(DeviceSelector, {
|
|
42048
|
+
"device-type": currentDeviceType.value,
|
|
42049
|
+
theme: _ctx.theme,
|
|
42050
|
+
onClose: _cache[4] || (_cache[4] = ($event) => showDeviceSelector.value = false)
|
|
42051
|
+
}, null, 8, ["device-type", "theme"])
|
|
42052
|
+
]),
|
|
42053
|
+
_: 1
|
|
42054
|
+
}, 8, ["visible", "trigger"])
|
|
42055
|
+
], 2)) : createCommentVNode("", true)
|
|
42056
|
+
]);
|
|
42057
|
+
};
|
|
42058
|
+
}
|
|
42059
|
+
});
|
|
42060
|
+
const JSCall = /* @__PURE__ */ _export_sfc(_sfc_main$o, [["__scopeId", "data-v-5c880aa1"]]);
|
|
42061
|
+
const HANDOFF_SOURCE_TAB_ID_KEY = "JS_MEETING_MQTT_HANDOFF_SOURCE_TAB_ID";
|
|
42062
|
+
const HANDOFF_TARGET_TAB_ID_KEY = "JS_MEETING_MQTT_HANDOFF_TARGET_TAB_ID";
|
|
42063
|
+
const HANDOFF_ID_KEY = "JS_MEETING_MQTT_HANDOFF_ID";
|
|
42064
|
+
const RECONNECT_SIGNAL_KEY = "JS_MEETING_MQTT_RECONNECT_SIGNAL";
|
|
42065
|
+
const TARGET_HEARTBEAT_KEY = "JS_MEETING_MQTT_HANDOFF_HEARTBEAT";
|
|
42066
|
+
const TARGET_TAB_STATUS_KEY = "JS_MEETING_NEW_TAB_STATUS";
|
|
42067
|
+
const TARGET_HEARTBEAT_INTERVAL_MS = 1e3;
|
|
42068
|
+
const RECONNECT_CHECK_DELAY_MS = 1500;
|
|
42069
|
+
const TARGET_TAB_STATUS_CLOSED = 0;
|
|
42070
|
+
const TARGET_TAB_STATUS_OPEN = 1;
|
|
42071
|
+
let installed = false;
|
|
42072
|
+
let closeSignalSent = false;
|
|
42073
|
+
let heartbeatTimer = null;
|
|
42074
|
+
let lastHandledReconnectSignalTs = 0;
|
|
42075
|
+
let leaveRequestSent = false;
|
|
42076
|
+
function createRandomId() {
|
|
42077
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
42078
|
+
return crypto.randomUUID().replace(/-/g, "").slice(0, 12);
|
|
42079
|
+
}
|
|
42080
|
+
return Math.random().toString(36).slice(2, 14);
|
|
42081
|
+
}
|
|
42082
|
+
function safeSessionStorageGetItem(key) {
|
|
42083
|
+
try {
|
|
42084
|
+
return sessionStorage.getItem(key);
|
|
42085
|
+
} catch {
|
|
42086
|
+
return null;
|
|
42087
|
+
}
|
|
42088
|
+
}
|
|
42089
|
+
function safeLocalStorageSetItem(key, value) {
|
|
42090
|
+
try {
|
|
42091
|
+
localStorage.setItem(key, value);
|
|
42092
|
+
} catch {
|
|
42093
|
+
}
|
|
42094
|
+
}
|
|
42095
|
+
function safeLocalStorageGetItem(key) {
|
|
42096
|
+
try {
|
|
42097
|
+
return localStorage.getItem(key);
|
|
42098
|
+
} catch {
|
|
42099
|
+
return null;
|
|
42100
|
+
}
|
|
42101
|
+
}
|
|
42102
|
+
function getMeetingMqttHandoffContext() {
|
|
42103
|
+
const sourceTabId = safeSessionStorageGetItem(HANDOFF_SOURCE_TAB_ID_KEY) || "";
|
|
42104
|
+
const targetTabId = safeSessionStorageGetItem(HANDOFF_TARGET_TAB_ID_KEY) || "";
|
|
42105
|
+
const handoffId = safeSessionStorageGetItem(HANDOFF_ID_KEY) || "";
|
|
42106
|
+
if (!sourceTabId || !targetTabId || !handoffId) {
|
|
42107
|
+
return null;
|
|
42108
|
+
}
|
|
42109
|
+
return {
|
|
42110
|
+
sourceTabId,
|
|
42111
|
+
targetTabId,
|
|
42112
|
+
handoffId
|
|
42113
|
+
};
|
|
42114
|
+
}
|
|
42115
|
+
function readTargetHeartbeat() {
|
|
42116
|
+
const raw = safeLocalStorageGetItem(TARGET_HEARTBEAT_KEY);
|
|
42117
|
+
if (!raw) {
|
|
42118
|
+
return null;
|
|
42119
|
+
}
|
|
42120
|
+
try {
|
|
42121
|
+
const parsed = JSON.parse(raw);
|
|
42122
|
+
if (!(parsed == null ? void 0 : parsed.targetTabId) || !(parsed == null ? void 0 : parsed.handoffId) || !(parsed == null ? void 0 : parsed.ts)) {
|
|
42123
|
+
return null;
|
|
42124
|
+
}
|
|
42125
|
+
return {
|
|
42126
|
+
targetTabId: parsed.targetTabId,
|
|
42127
|
+
handoffId: parsed.handoffId,
|
|
42128
|
+
ts: Number(parsed.ts)
|
|
42129
|
+
};
|
|
42130
|
+
} catch {
|
|
42131
|
+
return null;
|
|
42132
|
+
}
|
|
42133
|
+
}
|
|
42134
|
+
function writeTargetHeartbeat(context) {
|
|
42135
|
+
safeLocalStorageSetItem(
|
|
42136
|
+
TARGET_HEARTBEAT_KEY,
|
|
42137
|
+
JSON.stringify({
|
|
42138
|
+
targetTabId: context.targetTabId,
|
|
42139
|
+
handoffId: context.handoffId,
|
|
42140
|
+
ts: Date.now()
|
|
42141
|
+
})
|
|
42142
|
+
);
|
|
42143
|
+
}
|
|
42144
|
+
function writeTargetTabStatus(status, context) {
|
|
42145
|
+
safeLocalStorageSetItem(
|
|
42146
|
+
TARGET_TAB_STATUS_KEY,
|
|
42147
|
+
JSON.stringify({
|
|
42148
|
+
sourceTabId: context.sourceTabId,
|
|
42149
|
+
targetTabId: context.targetTabId,
|
|
42150
|
+
handoffId: context.handoffId,
|
|
42151
|
+
status,
|
|
42152
|
+
ts: Date.now()
|
|
42153
|
+
})
|
|
42154
|
+
);
|
|
42155
|
+
}
|
|
42156
|
+
function sendReconnectSignal(context) {
|
|
42157
|
+
if (closeSignalSent) {
|
|
42158
|
+
return;
|
|
42159
|
+
}
|
|
42160
|
+
closeSignalSent = true;
|
|
42161
|
+
console.warn("[MQTT_HANDOFF] 目标页关闭,通知来源页恢复 MQTT", {
|
|
42162
|
+
sourceTabId: context.sourceTabId,
|
|
42163
|
+
targetTabId: context.targetTabId,
|
|
42164
|
+
handoffId: context.handoffId
|
|
42165
|
+
});
|
|
42166
|
+
safeLocalStorageSetItem(
|
|
42167
|
+
RECONNECT_SIGNAL_KEY,
|
|
42168
|
+
JSON.stringify({
|
|
42169
|
+
...context,
|
|
42170
|
+
ts: Date.now()
|
|
42171
|
+
})
|
|
42172
|
+
);
|
|
42173
|
+
}
|
|
42174
|
+
function stopTargetHeartbeat() {
|
|
42175
|
+
if (heartbeatTimer) {
|
|
42176
|
+
clearInterval(heartbeatTimer);
|
|
42177
|
+
heartbeatTimer = null;
|
|
42178
|
+
}
|
|
42179
|
+
}
|
|
42180
|
+
function startTargetHeartbeat() {
|
|
42181
|
+
const context = getMeetingMqttHandoffContext();
|
|
42182
|
+
if (!context) {
|
|
42183
|
+
return;
|
|
42184
|
+
}
|
|
42185
|
+
const currentTabId = getCurrentMeetingTabId();
|
|
42186
|
+
if (currentTabId !== context.targetTabId) {
|
|
42187
|
+
return;
|
|
42188
|
+
}
|
|
42189
|
+
closeSignalSent = false;
|
|
42190
|
+
console.info("[MQTT_HANDOFF] 目标页心跳已启动", {
|
|
42191
|
+
sourceTabId: context.sourceTabId,
|
|
42192
|
+
targetTabId: context.targetTabId,
|
|
42193
|
+
handoffId: context.handoffId
|
|
42194
|
+
});
|
|
42195
|
+
writeTargetTabStatus(TARGET_TAB_STATUS_OPEN, context);
|
|
42196
|
+
writeTargetHeartbeat(context);
|
|
42197
|
+
stopTargetHeartbeat();
|
|
42198
|
+
heartbeatTimer = setInterval(() => {
|
|
42199
|
+
writeTargetHeartbeat(context);
|
|
42200
|
+
}, TARGET_HEARTBEAT_INTERVAL_MS);
|
|
42201
|
+
}
|
|
42202
|
+
function notifySourceTabForReconnect() {
|
|
42203
|
+
const context = getMeetingMqttHandoffContext();
|
|
42204
|
+
if (!context) {
|
|
42205
|
+
return;
|
|
42206
|
+
}
|
|
42207
|
+
const currentTabId = getCurrentMeetingTabId();
|
|
42208
|
+
if (currentTabId !== context.targetTabId) {
|
|
42209
|
+
return;
|
|
42210
|
+
}
|
|
42211
|
+
sendReconnectSignal(context);
|
|
42212
|
+
}
|
|
42213
|
+
function shouldWarnBeforeUnload() {
|
|
42214
|
+
const context = getMeetingMqttHandoffContext();
|
|
42215
|
+
if (!context) {
|
|
42216
|
+
return false;
|
|
42217
|
+
}
|
|
42218
|
+
const currentTabId = getCurrentMeetingTabId();
|
|
42219
|
+
return currentTabId === context.targetTabId;
|
|
42220
|
+
}
|
|
42221
|
+
function buildMeetingLeavePayload() {
|
|
42222
|
+
try {
|
|
42223
|
+
const meetingInfo = JSON.parse(sessionStorage.getItem("JS_MEETING_INFO") || "{}");
|
|
42224
|
+
const meetingId = String((meetingInfo == null ? void 0 : meetingInfo.meetingId) || "").trim();
|
|
42225
|
+
const memberId = String(getUserId() || "").trim();
|
|
42226
|
+
if (!meetingId || !memberId) {
|
|
42227
|
+
return null;
|
|
42228
|
+
}
|
|
42229
|
+
return { meetingId, memberId, force: true };
|
|
42230
|
+
} catch {
|
|
42231
|
+
return null;
|
|
42232
|
+
}
|
|
42233
|
+
}
|
|
42234
|
+
function sendMeetingLeaveOnClose() {
|
|
42235
|
+
if (leaveRequestSent) {
|
|
42236
|
+
return;
|
|
42237
|
+
}
|
|
42238
|
+
const payload = buildMeetingLeavePayload();
|
|
42239
|
+
if (!payload) {
|
|
42240
|
+
return;
|
|
42241
|
+
}
|
|
42242
|
+
leaveRequestSent = true;
|
|
42243
|
+
const body = JSON.stringify(payload);
|
|
42244
|
+
const token = getSdkToken();
|
|
42245
|
+
const authHeader = token ? { Authorization: `Bearer ${token}` } : {};
|
|
42246
|
+
const requestUrl = "/meeting/api/v2/meeting/leave";
|
|
42247
|
+
try {
|
|
42248
|
+
fetch(requestUrl, {
|
|
42249
|
+
method: "POST",
|
|
42250
|
+
headers: {
|
|
42251
|
+
"Content-Type": "application/json",
|
|
42252
|
+
Accept: "application/json, text/plain, */*",
|
|
42253
|
+
"X-Requested-With": "XMLHttpRequest",
|
|
42254
|
+
...authHeader
|
|
42255
|
+
},
|
|
42256
|
+
body,
|
|
42257
|
+
keepalive: true,
|
|
42258
|
+
credentials: "same-origin"
|
|
42259
|
+
}).catch(() => {
|
|
42260
|
+
});
|
|
42261
|
+
console.warn("[MQTT_HANDOFF] 页面关闭触发离会请求(keepalive)", payload);
|
|
42262
|
+
} catch {
|
|
42263
|
+
}
|
|
42264
|
+
try {
|
|
42265
|
+
if (typeof navigator !== "undefined" && typeof navigator.sendBeacon === "function") {
|
|
42266
|
+
const beaconData = new Blob([body], { type: "application/json" });
|
|
42267
|
+
const sent = navigator.sendBeacon(requestUrl, beaconData);
|
|
42268
|
+
console.warn("[MQTT_HANDOFF] 页面关闭触发离会请求(beacon)", {
|
|
42269
|
+
...payload,
|
|
42270
|
+
sent
|
|
42271
|
+
});
|
|
42272
|
+
}
|
|
42273
|
+
} catch {
|
|
42274
|
+
}
|
|
42275
|
+
}
|
|
42276
|
+
function shouldReconnectForSignal(signal) {
|
|
42277
|
+
const currentTabId = getCurrentMeetingTabId();
|
|
42278
|
+
if (!signal.sourceTabId || signal.sourceTabId !== currentTabId) {
|
|
42279
|
+
return false;
|
|
42280
|
+
}
|
|
42281
|
+
const latestHeartbeat = readTargetHeartbeat();
|
|
42282
|
+
if (!latestHeartbeat) {
|
|
42283
|
+
return true;
|
|
42284
|
+
}
|
|
42285
|
+
if (latestHeartbeat.targetTabId !== signal.targetTabId) {
|
|
42286
|
+
return true;
|
|
42287
|
+
}
|
|
42288
|
+
if (latestHeartbeat.handoffId !== signal.handoffId) {
|
|
42289
|
+
return true;
|
|
42290
|
+
}
|
|
42291
|
+
return latestHeartbeat.ts <= signal.ts;
|
|
42292
|
+
}
|
|
42293
|
+
function createMeetingMqttHandoffId() {
|
|
42294
|
+
return `mqtt_handoff_${Date.now()}_${createRandomId()}`;
|
|
42295
|
+
}
|
|
42296
|
+
function setMeetingMqttHandoffForWindow(targetWindow, context) {
|
|
42297
|
+
targetWindow.sessionStorage.setItem(
|
|
42298
|
+
HANDOFF_SOURCE_TAB_ID_KEY,
|
|
42299
|
+
context.sourceTabId
|
|
42300
|
+
);
|
|
42301
|
+
targetWindow.sessionStorage.setItem(
|
|
42302
|
+
HANDOFF_TARGET_TAB_ID_KEY,
|
|
42303
|
+
context.targetTabId
|
|
42304
|
+
);
|
|
42305
|
+
targetWindow.sessionStorage.setItem(HANDOFF_ID_KEY, context.handoffId);
|
|
42306
|
+
}
|
|
42307
|
+
function installMeetingMqttHandoffBridge(onReconnectRequested) {
|
|
42308
|
+
if (installed || typeof window === "undefined") {
|
|
42309
|
+
return;
|
|
42310
|
+
}
|
|
42311
|
+
installed = true;
|
|
42312
|
+
startTargetHeartbeat();
|
|
42313
|
+
window.addEventListener("storage", (event) => {
|
|
42314
|
+
if (event.key !== RECONNECT_SIGNAL_KEY || !event.newValue) {
|
|
42315
|
+
return;
|
|
42316
|
+
}
|
|
42317
|
+
let signal = null;
|
|
42318
|
+
try {
|
|
42319
|
+
signal = JSON.parse(event.newValue);
|
|
42320
|
+
} catch {
|
|
42321
|
+
return;
|
|
42322
|
+
}
|
|
42323
|
+
if (!(signal == null ? void 0 : signal.sourceTabId) || !signal.targetTabId || !signal.handoffId) {
|
|
42324
|
+
return;
|
|
42325
|
+
}
|
|
42326
|
+
const signalTs = Number(signal.ts);
|
|
42327
|
+
if (!signalTs || signalTs <= lastHandledReconnectSignalTs) {
|
|
42328
|
+
return;
|
|
42329
|
+
}
|
|
42330
|
+
lastHandledReconnectSignalTs = signalTs;
|
|
42331
|
+
console.warn("[MQTT_HANDOFF] 收到 MQTT 恢复信号,等待确认目标页是否真的关闭", {
|
|
42332
|
+
sourceTabId: signal.sourceTabId,
|
|
42333
|
+
targetTabId: signal.targetTabId,
|
|
42334
|
+
handoffId: signal.handoffId,
|
|
42335
|
+
signalTs
|
|
42336
|
+
});
|
|
42337
|
+
window.setTimeout(() => {
|
|
42338
|
+
if (!shouldReconnectForSignal(signal)) {
|
|
42339
|
+
console.info("[MQTT_HANDOFF] 忽略 MQTT 恢复,本次更像是目标页刷新/重载", {
|
|
42340
|
+
sourceTabId: signal.sourceTabId,
|
|
42341
|
+
targetTabId: signal.targetTabId,
|
|
42342
|
+
handoffId: signal.handoffId
|
|
42343
|
+
});
|
|
42344
|
+
return;
|
|
42345
|
+
}
|
|
42346
|
+
console.warn("[MQTT_HANDOFF] 确认目标页已关闭,准备恢复来源页 MQTT", {
|
|
42347
|
+
sourceTabId: signal.sourceTabId,
|
|
42348
|
+
targetTabId: signal.targetTabId,
|
|
42349
|
+
handoffId: signal.handoffId
|
|
42350
|
+
});
|
|
42351
|
+
void onReconnectRequested();
|
|
42352
|
+
}, RECONNECT_CHECK_DELAY_MS);
|
|
42353
|
+
});
|
|
42354
|
+
window.addEventListener("beforeunload", (event) => {
|
|
42355
|
+
if (!shouldWarnBeforeUnload()) {
|
|
42356
|
+
return;
|
|
42357
|
+
}
|
|
42358
|
+
event.preventDefault();
|
|
42359
|
+
event.returnValue = "";
|
|
42360
|
+
});
|
|
42361
|
+
window.addEventListener("pagehide", (event) => {
|
|
42362
|
+
const context = getMeetingMqttHandoffContext();
|
|
42363
|
+
const shouldHandleTargetTabClose = !!context && getCurrentMeetingTabId() === context.targetTabId;
|
|
42364
|
+
if (shouldHandleTargetTabClose && context) {
|
|
42365
|
+
writeTargetTabStatus(TARGET_TAB_STATUS_CLOSED, context);
|
|
42366
|
+
sendMeetingLeaveOnClose();
|
|
42367
|
+
}
|
|
42368
|
+
stopTargetHeartbeat();
|
|
42369
|
+
if (event.persisted) {
|
|
42370
|
+
return;
|
|
42371
|
+
}
|
|
42372
|
+
notifySourceTabForReconnect();
|
|
42373
|
+
});
|
|
42374
|
+
}
|
|
42375
|
+
const _hoisted_1$l = { class: "js-dialog-header-title" };
|
|
42376
|
+
const _hoisted_2$k = { class: "js-dialog-header-actions" };
|
|
42377
|
+
const MQTT_CLIENT_INSTANCE_STORAGE_KEY = "JS_MQTT_CLIENT_INSTANCE_ID";
|
|
42378
|
+
const _sfc_main$n = /* @__PURE__ */ defineComponent({
|
|
42379
|
+
__name: "meeting-header",
|
|
42380
|
+
props: {
|
|
42381
|
+
theme: {},
|
|
42382
|
+
isMaximized: { type: Boolean }
|
|
42383
|
+
},
|
|
42384
|
+
emits: ["onChange"],
|
|
42385
|
+
setup(__props, { emit: __emit }) {
|
|
42386
|
+
const props = __props;
|
|
42387
|
+
const { meState: meState2 } = storeToRefs(useMeetingStore());
|
|
42388
|
+
const meetingInfo = computed(() => {
|
|
42389
|
+
return JSON.parse(sessionStorage.getItem("JS_MEETING_INFO") || "{}");
|
|
42390
|
+
});
|
|
42391
|
+
const emit = __emit;
|
|
42392
|
+
const closeRef = ref(null);
|
|
42393
|
+
const showCloseConfirm = ref(false);
|
|
42394
|
+
const SESSION_STORAGE_KEYS_TO_CLONE = [
|
|
42395
|
+
"JS_MEETING_INFO",
|
|
42396
|
+
"JS_SDK_TOKEN",
|
|
42397
|
+
"JS_SDK_TOKEN_EXPIRY",
|
|
42398
|
+
"JS_USER_ID",
|
|
42399
|
+
"JS_USER_NAME",
|
|
42400
|
+
"JS_SELF_MEDIA_PREFS",
|
|
42401
|
+
"JS_SERVER_TIMESTAMP",
|
|
42402
|
+
"joinTime",
|
|
42403
|
+
"JS_INCOMING_CALL_INFO",
|
|
42404
|
+
"isSosActive"
|
|
42405
|
+
];
|
|
42406
|
+
const themeClass = computed(() => `theme-${props.theme || "dark"}`);
|
|
42407
|
+
const hasOpenedNewTab = ref(false);
|
|
42408
|
+
const getNewTabFlagFromLocation = () => {
|
|
42409
|
+
if (typeof window === "undefined") return false;
|
|
42410
|
+
const searchParams = new URLSearchParams(window.location.search || "");
|
|
42411
|
+
if (searchParams.get("newTab") === "true") return true;
|
|
42412
|
+
const hash = window.location.hash || "";
|
|
42413
|
+
const hashQueryIndex = hash.indexOf("?");
|
|
42414
|
+
if (hashQueryIndex === -1) return false;
|
|
42415
|
+
const hashQuery = hash.slice(hashQueryIndex + 1);
|
|
42416
|
+
const hashParams = new URLSearchParams(hashQuery);
|
|
42417
|
+
return hashParams.get("newTab") === "true";
|
|
42418
|
+
};
|
|
42419
|
+
const showOpenNewTabButton = computed(() => {
|
|
42420
|
+
if (hasOpenedNewTab.value) return false;
|
|
42421
|
+
return !getNewTabFlagFromLocation();
|
|
42422
|
+
});
|
|
42423
|
+
const createMqttInstanceId = () => {
|
|
42424
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
42425
|
+
return crypto.randomUUID().replace(/-/g, "").slice(0, 12);
|
|
42426
|
+
}
|
|
42427
|
+
return Math.random().toString(36).slice(2, 14);
|
|
42428
|
+
};
|
|
42429
|
+
const copySessionToNewTab = (targetWindow) => {
|
|
42430
|
+
SESSION_STORAGE_KEYS_TO_CLONE.forEach((key) => {
|
|
42431
|
+
const value = sessionStorage.getItem(key);
|
|
42432
|
+
if (value === null) {
|
|
42433
|
+
targetWindow.sessionStorage.removeItem(key);
|
|
42434
|
+
return;
|
|
42435
|
+
}
|
|
42436
|
+
targetWindow.sessionStorage.setItem(key, value);
|
|
42437
|
+
});
|
|
42438
|
+
};
|
|
42439
|
+
const handleOpenNewTab = async () => {
|
|
42440
|
+
var _a25;
|
|
42441
|
+
hasOpenedNewTab.value = true;
|
|
42442
|
+
const currentMeetingId = (_a25 = meetingInfo.value) == null ? void 0 : _a25.meetingId;
|
|
42443
|
+
const newTab = window.open("", "_blank");
|
|
42444
|
+
if (!newTab) {
|
|
42445
|
+
hasOpenedNewTab.value = false;
|
|
42446
|
+
showNotification("打开新标签页失败,请允许弹窗权限。", "warning", 5e3);
|
|
42447
|
+
return;
|
|
42448
|
+
}
|
|
42449
|
+
try {
|
|
42450
|
+
const sourceTabId = getCurrentMeetingTabId();
|
|
42451
|
+
const nextTabId = createMeetingTabId();
|
|
42452
|
+
const handoffId = createMeetingMqttHandoffId();
|
|
42453
|
+
copySessionToNewTab(newTab);
|
|
42454
|
+
setMeetingMqttHandoffForWindow(newTab, {
|
|
42455
|
+
sourceTabId,
|
|
42456
|
+
targetTabId: nextTabId,
|
|
42457
|
+
handoffId
|
|
42458
|
+
});
|
|
42459
|
+
newTab.sessionStorage.setItem(
|
|
42460
|
+
MQTT_CLIENT_INSTANCE_STORAGE_KEY,
|
|
42461
|
+
createMqttInstanceId()
|
|
42462
|
+
);
|
|
42463
|
+
setMeetingTabIdForWindow(newTab, nextTabId);
|
|
42464
|
+
if (currentMeetingId) {
|
|
42465
|
+
claimActiveMeetingOwnership(currentMeetingId, nextTabId);
|
|
42466
|
+
}
|
|
42467
|
+
let url = window.location.href;
|
|
42468
|
+
if (url.includes("home") || url.includes("surveillance")) {
|
|
42469
|
+
url = url.replace("home", "command");
|
|
42470
|
+
url = url.replace("surveillance", "command");
|
|
42471
|
+
}
|
|
42472
|
+
newTab.location.replace(url + "?newTab=true");
|
|
42473
|
+
resetMeetingMQTT();
|
|
42474
|
+
await logoutRoomAction();
|
|
42475
|
+
closeMeeting();
|
|
42476
|
+
} catch (error) {
|
|
42477
|
+
hasOpenedNewTab.value = false;
|
|
42478
|
+
console.error("Failed to open meeting in a new tab:", error);
|
|
42479
|
+
showNotification("New tab initialized with a fallback page open.", "warning", 5e3);
|
|
42480
|
+
}
|
|
42481
|
+
};
|
|
42482
|
+
const handleCloseClick = async () => {
|
|
42483
|
+
showCloseConfirm.value = !showCloseConfirm.value;
|
|
42484
|
+
};
|
|
42485
|
+
const handleEndMeeting = () => {
|
|
42486
|
+
showCloseConfirm.value = false;
|
|
42487
|
+
emit("onChange", RoomModalSelectType.endClick);
|
|
42488
|
+
};
|
|
42489
|
+
const handleLeaveMeeting = () => {
|
|
42490
|
+
showCloseConfirm.value = false;
|
|
42491
|
+
emit("onChange", RoomModalSelectType.leaveClick);
|
|
42492
|
+
};
|
|
42493
|
+
return (_ctx, _cache) => {
|
|
42494
|
+
return openBlock(), createElementBlock("div", {
|
|
42495
|
+
class: normalizeClass(["js-dialog-header", themeClass.value])
|
|
42496
|
+
}, [
|
|
42497
|
+
createElementVNode("div", _hoisted_1$l, toDisplayString(meetingInfo.value.meetingName), 1),
|
|
42498
|
+
createElementVNode("div", _hoisted_2$k, [
|
|
42499
|
+
showOpenNewTabButton.value ? (openBlock(), createElementBlock("div", {
|
|
42500
|
+
key: 0,
|
|
42501
|
+
title: "新打开标签页",
|
|
42502
|
+
onClick: handleOpenNewTab
|
|
42503
|
+
}, [
|
|
42504
|
+
createVNode(SvgIcon, {
|
|
42505
|
+
name: "OpenNewTabIcon",
|
|
42506
|
+
size: 16
|
|
42507
|
+
})
|
|
42508
|
+
])) : createCommentVNode("", true),
|
|
42509
|
+
createElementVNode("div", {
|
|
42510
|
+
title: "最小化",
|
|
42511
|
+
onClick: _cache[0] || (_cache[0] = ($event) => emit("onChange", unref(RoomModalSelectType).minimizeClick))
|
|
42512
|
+
}, [
|
|
42513
|
+
createVNode(SvgIcon, {
|
|
42514
|
+
name: "MinimizeIcon",
|
|
42515
|
+
size: 16
|
|
42516
|
+
})
|
|
42517
|
+
]),
|
|
42518
|
+
createElementVNode("div", {
|
|
42519
|
+
ref_key: "closeRef",
|
|
42520
|
+
ref: closeRef,
|
|
42521
|
+
title: "关闭",
|
|
42522
|
+
onClick: handleCloseClick
|
|
42523
|
+
}, [
|
|
42524
|
+
createVNode(SvgIcon, {
|
|
42525
|
+
name: "CloseIcon",
|
|
42526
|
+
size: 17
|
|
42527
|
+
})
|
|
42528
|
+
], 512)
|
|
42529
|
+
]),
|
|
42530
|
+
createVNode(SmartPopup, {
|
|
42531
|
+
visible: showCloseConfirm.value,
|
|
42532
|
+
"onUpdate:visible": _cache[2] || (_cache[2] = ($event) => showCloseConfirm.value = $event),
|
|
42533
|
+
trigger: closeRef.value,
|
|
42534
|
+
gap: 10
|
|
42535
|
+
}, {
|
|
42536
|
+
default: withCtx(() => [
|
|
42537
|
+
createElementVNode("div", {
|
|
42538
|
+
class: normalizeClass(["close-confirm-dropdown", themeClass.value])
|
|
42539
|
+
}, [
|
|
42540
|
+
unref(meState2).roleType == "1" ? (openBlock(), createElementBlock("div", {
|
|
42541
|
+
key: 0,
|
|
42542
|
+
class: "close-confirm-option danger",
|
|
42543
|
+
onClick: withModifiers(handleEndMeeting, ["stop"])
|
|
42544
|
+
}, " 结束会议 ")) : createCommentVNode("", true),
|
|
42545
|
+
createElementVNode("div", {
|
|
42546
|
+
class: "close-confirm-option simple",
|
|
42547
|
+
onClick: withModifiers(handleLeaveMeeting, ["stop"])
|
|
42548
|
+
}, " 离开会议 "),
|
|
42549
|
+
createElementVNode("div", {
|
|
42550
|
+
class: "close-confirm-option simple",
|
|
42551
|
+
onClick: _cache[1] || (_cache[1] = ($event) => showCloseConfirm.value = false)
|
|
42552
|
+
}, " 取消 ")
|
|
42553
|
+
], 2)
|
|
42554
|
+
]),
|
|
42555
|
+
_: 1
|
|
42556
|
+
}, 8, ["visible", "trigger"])
|
|
42557
|
+
], 2);
|
|
42558
|
+
};
|
|
42559
|
+
}
|
|
42560
|
+
});
|
|
42561
|
+
const MeetingHeader = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["__scopeId", "data-v-2299cd2f"]]);
|
|
42562
|
+
const _hoisted_1$k = { class: "js-dialog-content-inner" };
|
|
42563
|
+
const _hoisted_2$j = { class: "js-dialog-content-inner-left" };
|
|
42564
|
+
const _hoisted_3$j = { class: "js-dialog-content-inner-right" };
|
|
42565
|
+
const _hoisted_4$h = { class: "grid-layout" };
|
|
42566
|
+
const _hoisted_5$e = ["onClick"];
|
|
42567
|
+
const _hoisted_6$d = {
|
|
42568
|
+
key: 0,
|
|
42569
|
+
class: "host-tag"
|
|
42570
|
+
};
|
|
42571
|
+
const _hoisted_7$c = ["id"];
|
|
42572
|
+
const _hoisted_8$b = { class: "avatar-container" };
|
|
42573
|
+
const _hoisted_9$9 = { class: "video-loading-overlay" };
|
|
42574
|
+
const _hoisted_10$9 = { class: "video-loading-text" };
|
|
42575
|
+
const _hoisted_11$8 = { class: "video-loading-overlay failed" };
|
|
42576
|
+
const _hoisted_12$8 = ["disabled", "onClick"];
|
|
42577
|
+
const _sfc_main$m = /* @__PURE__ */ defineComponent({
|
|
42578
|
+
__name: "meeting-content",
|
|
42579
|
+
props: {
|
|
42580
|
+
layout: { default: "grid-9" },
|
|
42581
|
+
isFullscreen: { type: Boolean },
|
|
42582
|
+
joinTime: { default: 0 },
|
|
42583
|
+
theme: { default: "dark" }
|
|
42584
|
+
},
|
|
42585
|
+
emits: ["layout-change", "toggle-fullscreen"],
|
|
42586
|
+
setup(__props, { emit: __emit }) {
|
|
42587
|
+
const speakingUserName = ref("");
|
|
42588
|
+
emitter.on("speakingUserName", (name2) => {
|
|
42589
|
+
speakingUserName.value = name2;
|
|
42590
|
+
});
|
|
42591
|
+
const props = __props;
|
|
42592
|
+
const userId = getUserId();
|
|
42593
|
+
const joinTimeObj = ref("");
|
|
42594
|
+
const speakerId = ref(null);
|
|
42595
|
+
const lastGridLayout = ref("grid-9");
|
|
42596
|
+
const getUserName2 = (user) => {
|
|
42597
|
+
var _a25, _b25, _c2;
|
|
42598
|
+
return ((_a25 = user == null ? void 0 : user.member) == null ? void 0 : _a25.memberId) == userId ? `(我)${(_b25 = user == null ? void 0 : user.member) == null ? void 0 : _b25.name}` : ((_c2 = user == null ? void 0 : user.member) == null ? void 0 : _c2.name) || "未知用户";
|
|
42599
|
+
};
|
|
42600
|
+
const layoutClass = computed(() => `layout-${props.layout}`);
|
|
42601
|
+
const allJoinedMembers = computed(() => {
|
|
42602
|
+
return members.value.filter((user) => (user == null ? void 0 : user.joinStaus) == "1");
|
|
42603
|
+
});
|
|
42604
|
+
const speakerUser = computed(() => {
|
|
42605
|
+
if (!speakerId.value) return allJoinedMembers.value[0];
|
|
42606
|
+
return allJoinedMembers.value.find(
|
|
42607
|
+
(user) => {
|
|
42608
|
+
var _a25;
|
|
42609
|
+
return ((_a25 = user == null ? void 0 : user.member) == null ? void 0 : _a25.memberId) === speakerId.value;
|
|
42610
|
+
}
|
|
42611
|
+
) || allJoinedMembers.value[0];
|
|
42612
|
+
});
|
|
42613
|
+
const preferredRemoteVideoFocusId = computed(() => {
|
|
42614
|
+
var _a25, _b25;
|
|
42615
|
+
if (props.layout !== "speaker") return null;
|
|
42616
|
+
const focusedUid = (_b25 = (_a25 = speakerUser.value) == null ? void 0 : _a25.member) == null ? void 0 : _b25.memberId;
|
|
42617
|
+
return focusedUid && focusedUid !== userId ? focusedUid : null;
|
|
42618
|
+
});
|
|
42619
|
+
const filteredMembers = computed(() => {
|
|
42620
|
+
return allJoinedMembers.value;
|
|
42621
|
+
});
|
|
42622
|
+
const setSpeaker = (user) => {
|
|
42623
|
+
var _a25;
|
|
42624
|
+
speakerId.value = (_a25 = user == null ? void 0 : user.member) == null ? void 0 : _a25.memberId;
|
|
42625
|
+
if (props.layout !== "speaker") {
|
|
42626
|
+
emit("layout-change", "speaker");
|
|
42627
|
+
}
|
|
42628
|
+
};
|
|
42629
|
+
const clearSpeaker = () => {
|
|
42630
|
+
if (props.layout === "speaker") {
|
|
42631
|
+
emit("layout-change", lastGridLayout.value);
|
|
42632
|
+
}
|
|
42633
|
+
};
|
|
42634
|
+
const handleRetryVideo = async (user) => {
|
|
42635
|
+
var _a25;
|
|
42636
|
+
const memberId = (_a25 = user == null ? void 0 : user.member) == null ? void 0 : _a25.memberId;
|
|
42637
|
+
if (!memberId || memberId === userId || (user == null ? void 0 : user.videoRetrying)) return;
|
|
42638
|
+
await retryRemoteVideoSubscription(memberId);
|
|
42639
|
+
};
|
|
42640
|
+
const handleFullscreenClick = () => {
|
|
42641
|
+
emit("toggle-fullscreen");
|
|
42642
|
+
};
|
|
42643
|
+
const emit = __emit;
|
|
42644
|
+
let timer = null;
|
|
42645
|
+
watch(
|
|
42646
|
+
() => props.layout,
|
|
42647
|
+
(layout) => {
|
|
42648
|
+
if (layout !== "speaker") {
|
|
42649
|
+
lastGridLayout.value = layout;
|
|
42650
|
+
}
|
|
42651
|
+
},
|
|
42652
|
+
{ immediate: true }
|
|
42653
|
+
);
|
|
42654
|
+
watch(
|
|
42655
|
+
() => props.joinTime,
|
|
42656
|
+
() => {
|
|
42657
|
+
if (timer) {
|
|
42658
|
+
clearInterval(timer);
|
|
42659
|
+
timer = null;
|
|
42660
|
+
}
|
|
42661
|
+
if (props.joinTime) {
|
|
42662
|
+
timer = setInterval(() => {
|
|
42663
|
+
const now = +/* @__PURE__ */ new Date();
|
|
42664
|
+
joinTimeObj.value = formatDuringObject((now - props.joinTime) / 1e3);
|
|
42665
|
+
}, 1e3);
|
|
42666
|
+
}
|
|
42667
|
+
},
|
|
42668
|
+
{
|
|
42669
|
+
immediate: true
|
|
42670
|
+
}
|
|
42671
|
+
);
|
|
42672
|
+
onMounted(async () => {
|
|
42673
|
+
await nextTick();
|
|
42674
|
+
setTimeout(() => {
|
|
42675
|
+
mountTracks();
|
|
42676
|
+
}, 100);
|
|
42677
|
+
});
|
|
42678
|
+
watch(
|
|
42679
|
+
() => members.value.length,
|
|
42680
|
+
async (len, prevLen) => {
|
|
42681
|
+
if (!len || len === prevLen) return;
|
|
42682
|
+
await nextTick();
|
|
42683
|
+
setTimeout(() => mountTracks(), 0);
|
|
42684
|
+
},
|
|
42685
|
+
{ flush: "post" }
|
|
42686
|
+
);
|
|
42687
|
+
watch(
|
|
42688
|
+
preferredRemoteVideoFocusId,
|
|
42689
|
+
(focusedUid) => {
|
|
42690
|
+
void setPreferredRemoteVideoFocus(focusedUid);
|
|
42691
|
+
},
|
|
42692
|
+
{ immediate: true }
|
|
42693
|
+
);
|
|
42694
|
+
onUnmounted(() => {
|
|
42695
|
+
void setPreferredRemoteVideoFocus(null);
|
|
42696
|
+
if (timer) {
|
|
42697
|
+
clearInterval(timer);
|
|
42698
|
+
timer = null;
|
|
42699
|
+
}
|
|
42700
|
+
});
|
|
42701
|
+
return (_ctx, _cache) => {
|
|
42702
|
+
return openBlock(), createElementBlock(Fragment, null, [
|
|
42703
|
+
createElementVNode("div", _hoisted_1$k, [
|
|
42704
|
+
createElementVNode("div", _hoisted_2$j, [
|
|
42705
|
+
createVNode(NetWorkStatus, { theme: _ctx.theme }, null, 8, ["theme"]),
|
|
42706
|
+
createElementVNode("span", null, "正在讲话:" + toDisplayString(speakingUserName.value || "无"), 1)
|
|
42707
|
+
]),
|
|
42708
|
+
createElementVNode("div", _hoisted_3$j, [
|
|
42709
|
+
createElementVNode("span", null, toDisplayString(joinTimeObj.value), 1),
|
|
42710
|
+
createVNode(SvgIcon, {
|
|
42711
|
+
name: _ctx.isFullscreen ? "NoFullscreenIcon" : "FullscreenIcon",
|
|
42712
|
+
class: "icon-inactive",
|
|
42713
|
+
onClick: handleFullscreenClick
|
|
42714
|
+
}, null, 8, ["name"])
|
|
42715
|
+
])
|
|
42716
|
+
]),
|
|
42717
|
+
createElementVNode("div", {
|
|
42718
|
+
class: normalizeClass(["js-dialog-content", [layoutClass.value, { "is-fullscreen-layout": _ctx.isFullscreen }]])
|
|
42719
|
+
}, [
|
|
42720
|
+
createElementVNode("div", _hoisted_4$h, [
|
|
42721
|
+
!unref(members).length ? (openBlock(), createElementBlock(Fragment, { key: 0 }, renderList(12, (n2) => {
|
|
42722
|
+
return createElementVNode("div", {
|
|
42723
|
+
key: n2,
|
|
42724
|
+
class: "skeleton grid-item"
|
|
42725
|
+
}, [
|
|
42726
|
+
createVNode(Skeleton)
|
|
42727
|
+
]);
|
|
42728
|
+
}), 64)) : (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(filteredMembers.value, (user) => {
|
|
42729
|
+
var _a25, _b25, _c2, _d, _e, _f2, _g2, _h, _i2, _j, _k, _l2, _m, _n, _o, _p, _q, _r2, _s, _t2, _u, _v, _w2, _x2;
|
|
42730
|
+
return openBlock(), createElementBlock("div", {
|
|
42731
|
+
key: user == null ? void 0 : user.member.memberId,
|
|
42732
|
+
class: normalizeClass(["grid-item", {
|
|
42733
|
+
"is-speaker": _ctx.layout === "speaker" && ((_a25 = user == null ? void 0 : user.member) == null ? void 0 : _a25.memberId) === ((_c2 = (_b25 = speakerUser.value) == null ? void 0 : _b25.member) == null ? void 0 : _c2.memberId),
|
|
42734
|
+
"is-hidden": _ctx.layout === "speaker" && ((_d = user == null ? void 0 : user.member) == null ? void 0 : _d.memberId) !== ((_f2 = (_e = speakerUser.value) == null ? void 0 : _e.member) == null ? void 0 : _f2.memberId)
|
|
42735
|
+
}]),
|
|
42736
|
+
onClick: ($event) => {
|
|
42737
|
+
var _a26, _b26, _c3;
|
|
42738
|
+
return _ctx.layout === "speaker" && ((_a26 = user == null ? void 0 : user.member) == null ? void 0 : _a26.memberId) === ((_c3 = (_b26 = speakerUser.value) == null ? void 0 : _b26.member) == null ? void 0 : _c3.memberId) ? clearSpeaker() : setSpeaker(user);
|
|
42739
|
+
}
|
|
42740
|
+
}, [
|
|
42741
|
+
createElementVNode("div", {
|
|
42742
|
+
class: normalizeClass(["video-container", {
|
|
42743
|
+
small: _ctx.layout === "speaker" && ((_g2 = user == null ? void 0 : user.member) == null ? void 0 : _g2.memberId) !== ((_i2 = (_h = speakerUser.value) == null ? void 0 : _h.member) == null ? void 0 : _i2.memberId)
|
|
42744
|
+
}])
|
|
42745
|
+
}, [
|
|
42746
|
+
user.roleType === "1" ? (openBlock(), createElementBlock("div", _hoisted_6$d, "主持人")) : createCommentVNode("", true),
|
|
42747
|
+
withDirectives((openBlock(), createElementBlock("div", {
|
|
42748
|
+
id: unref(userId) === (user == null ? void 0 : user.member.memberId) ? "my-video" : `other-${user == null ? void 0 : user.member.memberId}`,
|
|
42749
|
+
key: unref(userId) === (user == null ? void 0 : user.member.memberId) ? "my-video" : `other-${user == null ? void 0 : user.member.memberId}`,
|
|
42750
|
+
class: "video-element"
|
|
42751
|
+
}, null, 8, _hoisted_7$c)), [
|
|
42752
|
+
[
|
|
42753
|
+
vShow,
|
|
42754
|
+
((user == null ? void 0 : user.cameraStatus) ?? "0") == "1" || ((user == null ? void 0 : user.shareScreenStatus) ?? "0") == "1"
|
|
42755
|
+
]
|
|
42756
|
+
]),
|
|
42757
|
+
withDirectives(createElementVNode("div", _hoisted_8$b, [
|
|
42758
|
+
createElementVNode("div", {
|
|
42759
|
+
class: normalizeClass(["avatar", {
|
|
42760
|
+
large: _ctx.layout === "speaker" && ((_j = user == null ? void 0 : user.member) == null ? void 0 : _j.memberId) === ((_l2 = (_k = speakerUser.value) == null ? void 0 : _k.member) == null ? void 0 : _l2.memberId),
|
|
42761
|
+
small: _ctx.layout === "speaker" && ((_m = user == null ? void 0 : user.member) == null ? void 0 : _m.memberId) !== ((_o = (_n = speakerUser.value) == null ? void 0 : _n.member) == null ? void 0 : _o.memberId)
|
|
42762
|
+
}])
|
|
42763
|
+
}, toDisplayString(unref(getUserAvatar)(user)), 3)
|
|
42764
|
+
], 512), [
|
|
42765
|
+
[
|
|
42766
|
+
vShow,
|
|
42767
|
+
((user == null ? void 0 : user.cameraStatus) ?? "0") == "0" && ((user == null ? void 0 : user.shareScreenStatus) ?? "0") == "0"
|
|
42768
|
+
]
|
|
42769
|
+
]),
|
|
42770
|
+
withDirectives(createElementVNode("div", _hoisted_9$9, [
|
|
42771
|
+
_cache[0] || (_cache[0] = createElementVNode("div", { class: "video-loading-spinner" }, null, -1)),
|
|
42772
|
+
createElementVNode("div", _hoisted_10$9, toDisplayString((user == null ? void 0 : user.videoRetrying) ? "重新加载中..." : "加载中..."), 1)
|
|
42773
|
+
], 512), [
|
|
42774
|
+
[
|
|
42775
|
+
vShow,
|
|
42776
|
+
(user == null ? void 0 : user.loading) && (((user == null ? void 0 : user.cameraStatus) ?? "0") == "1" || ((user == null ? void 0 : user.shareScreenStatus) ?? "0") == "1")
|
|
42777
|
+
]
|
|
42778
|
+
]),
|
|
42779
|
+
withDirectives(createElementVNode("div", _hoisted_11$8, [
|
|
42780
|
+
_cache[1] || (_cache[1] = createElementVNode("div", { class: "video-loading-text" }, "视频加载失败", -1)),
|
|
42781
|
+
createElementVNode("button", {
|
|
42782
|
+
type: "button",
|
|
42783
|
+
class: "video-retry-button",
|
|
42784
|
+
disabled: user == null ? void 0 : user.videoRetrying,
|
|
42785
|
+
onClick: withModifiers(($event) => handleRetryVideo(user), ["stop"])
|
|
42786
|
+
}, toDisplayString((user == null ? void 0 : user.videoRetrying) ? "重新加载中..." : "重新加载"), 9, _hoisted_12$8)
|
|
42787
|
+
], 512), [
|
|
42788
|
+
[
|
|
42789
|
+
vShow,
|
|
42790
|
+
(user == null ? void 0 : user.videoLoadFailed) && (((user == null ? void 0 : user.cameraStatus) ?? "0") == "1" || ((user == null ? void 0 : user.shareScreenStatus) ?? "0") == "1")
|
|
42791
|
+
]
|
|
42792
|
+
]),
|
|
42793
|
+
user.roleType !== "5" ? (openBlock(), createElementBlock("div", {
|
|
42794
|
+
key: 1,
|
|
42795
|
+
class: normalizeClass(["status-indicators", {
|
|
42796
|
+
large: _ctx.layout === "speaker" && ((_p = user == null ? void 0 : user.member) == null ? void 0 : _p.memberId) === ((_r2 = (_q = speakerUser.value) == null ? void 0 : _q.member) == null ? void 0 : _r2.memberId),
|
|
42797
|
+
small: _ctx.layout === "speaker" && ((_s = user == null ? void 0 : user.member) == null ? void 0 : _s.memberId) !== ((_u = (_t2 = speakerUser.value) == null ? void 0 : _t2.member) == null ? void 0 : _u.memberId)
|
|
42798
|
+
}])
|
|
42799
|
+
}, [
|
|
42800
|
+
createElementVNode("div", {
|
|
42801
|
+
class: normalizeClass(["indicator mic", (user == null ? void 0 : user.audioStatus) == "1" ? "on" : "off"])
|
|
42802
|
+
}, [
|
|
42803
|
+
createVNode(SvgIcon, {
|
|
42804
|
+
name: (user == null ? void 0 : user.audioStatus) == "1" ? "MicrophoneIcon" : "MicrophoneSlashIcon",
|
|
42805
|
+
size: 13
|
|
42806
|
+
}, null, 8, ["name"])
|
|
42807
|
+
], 2),
|
|
42808
|
+
createElementVNode("div", {
|
|
42809
|
+
class: normalizeClass(["indicator cam", (user == null ? void 0 : user.cameraStatus) == "1" ? "on" : "off"])
|
|
42810
|
+
}, [
|
|
42811
|
+
createVNode(SvgIcon, {
|
|
42812
|
+
name: (user == null ? void 0 : user.cameraStatus) == "1" ? "CameraIcon" : "CameraSlashIcon",
|
|
42813
|
+
size: 13
|
|
42814
|
+
}, null, 8, ["name"])
|
|
42815
|
+
], 2)
|
|
42816
|
+
], 2)) : createCommentVNode("", true),
|
|
42817
|
+
createElementVNode("div", {
|
|
42818
|
+
class: normalizeClass(["user-name", {
|
|
42819
|
+
small: _ctx.layout === "speaker" && ((_v = user == null ? void 0 : user.member) == null ? void 0 : _v.memberId) !== ((_x2 = (_w2 = speakerUser.value) == null ? void 0 : _w2.member) == null ? void 0 : _x2.memberId)
|
|
42820
|
+
}])
|
|
42821
|
+
}, toDisplayString(getUserName2(user)), 3)
|
|
42822
|
+
], 2)
|
|
42823
|
+
], 10, _hoisted_5$e);
|
|
42824
|
+
}), 128))
|
|
42825
|
+
])
|
|
42826
|
+
], 2)
|
|
42827
|
+
], 64);
|
|
42828
|
+
};
|
|
42829
|
+
}
|
|
42830
|
+
});
|
|
42372
42831
|
const MeetingContent = /* @__PURE__ */ _export_sfc(_sfc_main$m, [["__scopeId", "data-v-2e24401b"]]);
|
|
42373
42832
|
const _hoisted_1$j = { class: "js-dialog-footer" };
|
|
42374
42833
|
const _hoisted_2$i = { class: "js-dialog-footer-group js-dialog-footer-left" };
|
|
@@ -42984,16 +43443,18 @@ const _sfc_main$k = /* @__PURE__ */ defineComponent({
|
|
|
42984
43443
|
], 10, _hoisted_15$4)) : createCommentVNode("", true)
|
|
42985
43444
|
], 8, _hoisted_14$5)) : createCommentVNode("", true)
|
|
42986
43445
|
], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
42987
|
-
|
|
43446
|
+
member.roleType !== "5" ? (openBlock(), createBlock(SvgIcon, {
|
|
43447
|
+
key: 0,
|
|
42988
43448
|
name: (member == null ? void 0 : member.audioStatus) == "1" ? "MicrophoneIcon" : "MicrophoneSlashIcon",
|
|
42989
43449
|
size: 18,
|
|
42990
43450
|
"color-class": "device-icon"
|
|
42991
|
-
}, null, 8, ["name"]),
|
|
42992
|
-
|
|
43451
|
+
}, null, 8, ["name"])) : createCommentVNode("", true),
|
|
43452
|
+
member.roleType !== "5" ? (openBlock(), createBlock(SvgIcon, {
|
|
43453
|
+
key: 1,
|
|
42993
43454
|
name: (member == null ? void 0 : member.cameraStatus) == "1" ? "CameraIcon" : "CameraSlashIcon",
|
|
42994
43455
|
size: 18,
|
|
42995
43456
|
"color-class": "device-icon"
|
|
42996
|
-
}, null, 8, ["name"])
|
|
43457
|
+
}, null, 8, ["name"])) : createCommentVNode("", true)
|
|
42997
43458
|
], 64))
|
|
42998
43459
|
], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
42999
43460
|
unref(meState2).roleType == "1" ? (openBlock(), createElementBlock("button", {
|
|
@@ -43023,7 +43484,7 @@ const _sfc_main$k = /* @__PURE__ */ defineComponent({
|
|
|
43023
43484
|
};
|
|
43024
43485
|
}
|
|
43025
43486
|
});
|
|
43026
|
-
const ManageMembers = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["__scopeId", "data-v-
|
|
43487
|
+
const ManageMembers = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["__scopeId", "data-v-0768f591"]]);
|
|
43027
43488
|
const _hoisted_1$h = { class: "chat-container" };
|
|
43028
43489
|
const _hoisted_2$g = { class: "chat-content" };
|
|
43029
43490
|
const _hoisted_3$g = { class: "chat-meta" };
|
|
@@ -44832,23 +45293,26 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
|
|
|
44832
45293
|
await nextTick();
|
|
44833
45294
|
mountTracks();
|
|
44834
45295
|
};
|
|
44835
|
-
const
|
|
44836
|
-
|
|
44837
|
-
if (
|
|
44838
|
-
|
|
44839
|
-
|
|
44840
|
-
)
|
|
44841
|
-
|
|
44842
|
-
|
|
44843
|
-
|
|
44844
|
-
|
|
44845
|
-
|
|
44846
|
-
|
|
44847
|
-
|
|
44848
|
-
document.exitFullscreen()
|
|
44849
|
-
|
|
44850
|
-
});
|
|
45296
|
+
const fullscreenOperationBusy = ref(false);
|
|
45297
|
+
const handleFullscreen = async () => {
|
|
45298
|
+
if (fullscreenOperationBusy.value) return;
|
|
45299
|
+
fullscreenOperationBusy.value = true;
|
|
45300
|
+
try {
|
|
45301
|
+
if (!document.fullscreenElement) {
|
|
45302
|
+
const fullscreenRoot = document.querySelector(
|
|
45303
|
+
".js-dialog-overlay"
|
|
45304
|
+
);
|
|
45305
|
+
if (!fullscreenRoot) return;
|
|
45306
|
+
await fullscreenRoot.requestFullscreen();
|
|
45307
|
+
isFullscreen.value = true;
|
|
45308
|
+
} else {
|
|
45309
|
+
await document.exitFullscreen();
|
|
45310
|
+
isFullscreen.value = false;
|
|
44851
45311
|
}
|
|
45312
|
+
} catch {
|
|
45313
|
+
isFullscreen.value = !!document.fullscreenElement;
|
|
45314
|
+
} finally {
|
|
45315
|
+
fullscreenOperationBusy.value = false;
|
|
44852
45316
|
}
|
|
44853
45317
|
};
|
|
44854
45318
|
const handleInvite = (arr) => {
|
|
@@ -45077,7 +45541,7 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
|
|
|
45077
45541
|
};
|
|
45078
45542
|
}
|
|
45079
45543
|
});
|
|
45080
|
-
const JSMeeting = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["__scopeId", "data-v-
|
|
45544
|
+
const JSMeeting = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["__scopeId", "data-v-2efb7c64"]]);
|
|
45081
45545
|
const _hoisted_1$8 = { class: "modal" };
|
|
45082
45546
|
const _hoisted_2$8 = { class: "modal-header" };
|
|
45083
45547
|
const _hoisted_3$8 = { class: "tab-header" };
|
|
@@ -46984,333 +47448,39 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
46984
47448
|
style: { "color": "#2f86ff" }
|
|
46985
47449
|
})
|
|
46986
47450
|
]),
|
|
46987
|
-
createElementVNode("div", _hoisted_30, [
|
|
46988
|
-
withDirectives(createElementVNode("input", {
|
|
46989
|
-
"onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => microphoneVolume.value = $event),
|
|
46990
|
-
type: "range",
|
|
46991
|
-
min: "0",
|
|
46992
|
-
max: "100",
|
|
46993
|
-
class: "volume-slider",
|
|
46994
|
-
style: normalizeStyle(`background: linear-gradient(to right, #2f86ff ${microphoneVolume.value}%, rgba(255, 255, 255, 0.08) ${microphoneVolume.value}%)`)
|
|
46995
|
-
}, null, 4), [
|
|
46996
|
-
[vModelText, microphoneVolume.value]
|
|
46997
|
-
])
|
|
46998
|
-
])
|
|
46999
|
-
])
|
|
47000
|
-
])
|
|
47001
|
-
]))
|
|
47002
|
-
])
|
|
47003
|
-
])
|
|
47004
|
-
])), [
|
|
47005
|
-
[_directive_draggable, { handle: ".header" }]
|
|
47006
|
-
])
|
|
47007
|
-
], 2)) : createCommentVNode("", true);
|
|
47008
|
-
};
|
|
47009
|
-
}
|
|
47010
|
-
});
|
|
47011
|
-
const JSSettings = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-27234687"]]);
|
|
47012
|
-
function scheduleJoinRoom() {
|
|
47013
|
-
setTimeout(() => {
|
|
47014
|
-
try {
|
|
47015
|
-
joinRoom();
|
|
47016
|
-
} catch (error) {
|
|
47017
|
-
console.error("恢复后无法加入通话/会议", error);
|
|
47018
|
-
}
|
|
47019
|
-
}, 1e3);
|
|
47020
|
-
}
|
|
47021
|
-
const HANDOFF_SOURCE_TAB_ID_KEY = "JS_MEETING_MQTT_HANDOFF_SOURCE_TAB_ID";
|
|
47022
|
-
const HANDOFF_TARGET_TAB_ID_KEY = "JS_MEETING_MQTT_HANDOFF_TARGET_TAB_ID";
|
|
47023
|
-
const HANDOFF_ID_KEY = "JS_MEETING_MQTT_HANDOFF_ID";
|
|
47024
|
-
const RECONNECT_SIGNAL_KEY = "JS_MEETING_MQTT_RECONNECT_SIGNAL";
|
|
47025
|
-
const TARGET_HEARTBEAT_KEY = "JS_MEETING_MQTT_HANDOFF_HEARTBEAT";
|
|
47026
|
-
const TARGET_TAB_STATUS_KEY = "JS_MEETING_NEW_TAB_STATUS";
|
|
47027
|
-
const TARGET_HEARTBEAT_INTERVAL_MS = 1e3;
|
|
47028
|
-
const RECONNECT_CHECK_DELAY_MS = 1500;
|
|
47029
|
-
const TARGET_TAB_STATUS_CLOSED = 0;
|
|
47030
|
-
const TARGET_TAB_STATUS_OPEN = 1;
|
|
47031
|
-
let installed = false;
|
|
47032
|
-
let closeSignalSent = false;
|
|
47033
|
-
let heartbeatTimer = null;
|
|
47034
|
-
let lastHandledReconnectSignalTs = 0;
|
|
47035
|
-
let leaveRequestSent = false;
|
|
47036
|
-
function safeSessionStorageGetItem(key) {
|
|
47037
|
-
try {
|
|
47038
|
-
return sessionStorage.getItem(key);
|
|
47039
|
-
} catch {
|
|
47040
|
-
return null;
|
|
47041
|
-
}
|
|
47042
|
-
}
|
|
47043
|
-
function safeLocalStorageSetItem(key, value) {
|
|
47044
|
-
try {
|
|
47045
|
-
localStorage.setItem(key, value);
|
|
47046
|
-
} catch {
|
|
47047
|
-
}
|
|
47048
|
-
}
|
|
47049
|
-
function safeLocalStorageGetItem(key) {
|
|
47050
|
-
try {
|
|
47051
|
-
return localStorage.getItem(key);
|
|
47052
|
-
} catch {
|
|
47053
|
-
return null;
|
|
47054
|
-
}
|
|
47055
|
-
}
|
|
47056
|
-
function getMeetingMqttHandoffContext() {
|
|
47057
|
-
const sourceTabId = safeSessionStorageGetItem(HANDOFF_SOURCE_TAB_ID_KEY) || "";
|
|
47058
|
-
const targetTabId = safeSessionStorageGetItem(HANDOFF_TARGET_TAB_ID_KEY) || "";
|
|
47059
|
-
const handoffId = safeSessionStorageGetItem(HANDOFF_ID_KEY) || "";
|
|
47060
|
-
if (!sourceTabId || !targetTabId || !handoffId) {
|
|
47061
|
-
return null;
|
|
47062
|
-
}
|
|
47063
|
-
return {
|
|
47064
|
-
sourceTabId,
|
|
47065
|
-
targetTabId,
|
|
47066
|
-
handoffId
|
|
47067
|
-
};
|
|
47068
|
-
}
|
|
47069
|
-
function readTargetHeartbeat() {
|
|
47070
|
-
const raw = safeLocalStorageGetItem(TARGET_HEARTBEAT_KEY);
|
|
47071
|
-
if (!raw) {
|
|
47072
|
-
return null;
|
|
47073
|
-
}
|
|
47074
|
-
try {
|
|
47075
|
-
const parsed = JSON.parse(raw);
|
|
47076
|
-
if (!(parsed == null ? void 0 : parsed.targetTabId) || !(parsed == null ? void 0 : parsed.handoffId) || !(parsed == null ? void 0 : parsed.ts)) {
|
|
47077
|
-
return null;
|
|
47078
|
-
}
|
|
47079
|
-
return {
|
|
47080
|
-
targetTabId: parsed.targetTabId,
|
|
47081
|
-
handoffId: parsed.handoffId,
|
|
47082
|
-
ts: Number(parsed.ts)
|
|
47451
|
+
createElementVNode("div", _hoisted_30, [
|
|
47452
|
+
withDirectives(createElementVNode("input", {
|
|
47453
|
+
"onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => microphoneVolume.value = $event),
|
|
47454
|
+
type: "range",
|
|
47455
|
+
min: "0",
|
|
47456
|
+
max: "100",
|
|
47457
|
+
class: "volume-slider",
|
|
47458
|
+
style: normalizeStyle(`background: linear-gradient(to right, #2f86ff ${microphoneVolume.value}%, rgba(255, 255, 255, 0.08) ${microphoneVolume.value}%)`)
|
|
47459
|
+
}, null, 4), [
|
|
47460
|
+
[vModelText, microphoneVolume.value]
|
|
47461
|
+
])
|
|
47462
|
+
])
|
|
47463
|
+
])
|
|
47464
|
+
])
|
|
47465
|
+
]))
|
|
47466
|
+
])
|
|
47467
|
+
])
|
|
47468
|
+
])), [
|
|
47469
|
+
[_directive_draggable, { handle: ".header" }]
|
|
47470
|
+
])
|
|
47471
|
+
], 2)) : createCommentVNode("", true);
|
|
47083
47472
|
};
|
|
47084
|
-
} catch {
|
|
47085
|
-
return null;
|
|
47086
|
-
}
|
|
47087
|
-
}
|
|
47088
|
-
function writeTargetHeartbeat(context) {
|
|
47089
|
-
safeLocalStorageSetItem(
|
|
47090
|
-
TARGET_HEARTBEAT_KEY,
|
|
47091
|
-
JSON.stringify({
|
|
47092
|
-
targetTabId: context.targetTabId,
|
|
47093
|
-
handoffId: context.handoffId,
|
|
47094
|
-
ts: Date.now()
|
|
47095
|
-
})
|
|
47096
|
-
);
|
|
47097
|
-
}
|
|
47098
|
-
function writeTargetTabStatus(status, context) {
|
|
47099
|
-
safeLocalStorageSetItem(
|
|
47100
|
-
TARGET_TAB_STATUS_KEY,
|
|
47101
|
-
JSON.stringify({
|
|
47102
|
-
sourceTabId: context.sourceTabId,
|
|
47103
|
-
targetTabId: context.targetTabId,
|
|
47104
|
-
handoffId: context.handoffId,
|
|
47105
|
-
status,
|
|
47106
|
-
ts: Date.now()
|
|
47107
|
-
})
|
|
47108
|
-
);
|
|
47109
|
-
}
|
|
47110
|
-
function sendReconnectSignal(context) {
|
|
47111
|
-
if (closeSignalSent) {
|
|
47112
|
-
return;
|
|
47113
|
-
}
|
|
47114
|
-
closeSignalSent = true;
|
|
47115
|
-
console.warn("[MQTT_HANDOFF] 目标页关闭,通知来源页恢复 MQTT", {
|
|
47116
|
-
sourceTabId: context.sourceTabId,
|
|
47117
|
-
targetTabId: context.targetTabId,
|
|
47118
|
-
handoffId: context.handoffId
|
|
47119
|
-
});
|
|
47120
|
-
safeLocalStorageSetItem(
|
|
47121
|
-
RECONNECT_SIGNAL_KEY,
|
|
47122
|
-
JSON.stringify({
|
|
47123
|
-
...context,
|
|
47124
|
-
ts: Date.now()
|
|
47125
|
-
})
|
|
47126
|
-
);
|
|
47127
|
-
}
|
|
47128
|
-
function stopTargetHeartbeat() {
|
|
47129
|
-
if (heartbeatTimer) {
|
|
47130
|
-
clearInterval(heartbeatTimer);
|
|
47131
|
-
heartbeatTimer = null;
|
|
47132
|
-
}
|
|
47133
|
-
}
|
|
47134
|
-
function startTargetHeartbeat() {
|
|
47135
|
-
const context = getMeetingMqttHandoffContext();
|
|
47136
|
-
if (!context) {
|
|
47137
|
-
return;
|
|
47138
|
-
}
|
|
47139
|
-
const currentTabId = getCurrentMeetingTabId();
|
|
47140
|
-
if (currentTabId !== context.targetTabId) {
|
|
47141
|
-
return;
|
|
47142
|
-
}
|
|
47143
|
-
closeSignalSent = false;
|
|
47144
|
-
console.info("[MQTT_HANDOFF] 目标页心跳已启动", {
|
|
47145
|
-
sourceTabId: context.sourceTabId,
|
|
47146
|
-
targetTabId: context.targetTabId,
|
|
47147
|
-
handoffId: context.handoffId
|
|
47148
|
-
});
|
|
47149
|
-
writeTargetTabStatus(TARGET_TAB_STATUS_OPEN, context);
|
|
47150
|
-
writeTargetHeartbeat(context);
|
|
47151
|
-
stopTargetHeartbeat();
|
|
47152
|
-
heartbeatTimer = setInterval(() => {
|
|
47153
|
-
writeTargetHeartbeat(context);
|
|
47154
|
-
}, TARGET_HEARTBEAT_INTERVAL_MS);
|
|
47155
|
-
}
|
|
47156
|
-
function notifySourceTabForReconnect() {
|
|
47157
|
-
const context = getMeetingMqttHandoffContext();
|
|
47158
|
-
if (!context) {
|
|
47159
|
-
return;
|
|
47160
|
-
}
|
|
47161
|
-
const currentTabId = getCurrentMeetingTabId();
|
|
47162
|
-
if (currentTabId !== context.targetTabId) {
|
|
47163
|
-
return;
|
|
47164
|
-
}
|
|
47165
|
-
sendReconnectSignal(context);
|
|
47166
|
-
}
|
|
47167
|
-
function shouldWarnBeforeUnload() {
|
|
47168
|
-
const context = getMeetingMqttHandoffContext();
|
|
47169
|
-
if (!context) {
|
|
47170
|
-
return false;
|
|
47171
|
-
}
|
|
47172
|
-
const currentTabId = getCurrentMeetingTabId();
|
|
47173
|
-
return currentTabId === context.targetTabId;
|
|
47174
|
-
}
|
|
47175
|
-
function buildMeetingLeavePayload() {
|
|
47176
|
-
try {
|
|
47177
|
-
const meetingInfo = JSON.parse(sessionStorage.getItem("JS_MEETING_INFO") || "{}");
|
|
47178
|
-
const meetingId = String((meetingInfo == null ? void 0 : meetingInfo.meetingId) || "").trim();
|
|
47179
|
-
const memberId = String(getUserId() || "").trim();
|
|
47180
|
-
if (!meetingId || !memberId) {
|
|
47181
|
-
return null;
|
|
47182
|
-
}
|
|
47183
|
-
return { meetingId, memberId, force: true };
|
|
47184
|
-
} catch {
|
|
47185
|
-
return null;
|
|
47186
|
-
}
|
|
47187
|
-
}
|
|
47188
|
-
function sendMeetingLeaveOnClose() {
|
|
47189
|
-
if (leaveRequestSent) {
|
|
47190
|
-
return;
|
|
47191
47473
|
}
|
|
47192
|
-
|
|
47193
|
-
|
|
47194
|
-
|
|
47195
|
-
|
|
47196
|
-
leaveRequestSent = true;
|
|
47197
|
-
const body = JSON.stringify(payload);
|
|
47198
|
-
const token = getSdkToken();
|
|
47199
|
-
const authHeader = token ? { Authorization: `Bearer ${token}` } : {};
|
|
47200
|
-
const requestUrl = "/meeting/api/v2/meeting/leave";
|
|
47201
|
-
try {
|
|
47202
|
-
fetch(requestUrl, {
|
|
47203
|
-
method: "POST",
|
|
47204
|
-
headers: {
|
|
47205
|
-
"Content-Type": "application/json",
|
|
47206
|
-
Accept: "application/json, text/plain, */*",
|
|
47207
|
-
"X-Requested-With": "XMLHttpRequest",
|
|
47208
|
-
...authHeader
|
|
47209
|
-
},
|
|
47210
|
-
body,
|
|
47211
|
-
keepalive: true,
|
|
47212
|
-
credentials: "same-origin"
|
|
47213
|
-
}).catch(() => {
|
|
47214
|
-
});
|
|
47215
|
-
console.warn("[MQTT_HANDOFF] 页面关闭触发离会请求(keepalive)", payload);
|
|
47216
|
-
} catch {
|
|
47217
|
-
}
|
|
47218
|
-
try {
|
|
47219
|
-
if (typeof navigator !== "undefined" && typeof navigator.sendBeacon === "function") {
|
|
47220
|
-
const beaconData = new Blob([body], { type: "application/json" });
|
|
47221
|
-
const sent = navigator.sendBeacon(requestUrl, beaconData);
|
|
47222
|
-
console.warn("[MQTT_HANDOFF] 页面关闭触发离会请求(beacon)", {
|
|
47223
|
-
...payload,
|
|
47224
|
-
sent
|
|
47225
|
-
});
|
|
47226
|
-
}
|
|
47227
|
-
} catch {
|
|
47228
|
-
}
|
|
47229
|
-
}
|
|
47230
|
-
function shouldReconnectForSignal(signal) {
|
|
47231
|
-
const currentTabId = getCurrentMeetingTabId();
|
|
47232
|
-
if (!signal.sourceTabId || signal.sourceTabId !== currentTabId) {
|
|
47233
|
-
return false;
|
|
47234
|
-
}
|
|
47235
|
-
const latestHeartbeat = readTargetHeartbeat();
|
|
47236
|
-
if (!latestHeartbeat) {
|
|
47237
|
-
return true;
|
|
47238
|
-
}
|
|
47239
|
-
if (latestHeartbeat.targetTabId !== signal.targetTabId) {
|
|
47240
|
-
return true;
|
|
47241
|
-
}
|
|
47242
|
-
if (latestHeartbeat.handoffId !== signal.handoffId) {
|
|
47243
|
-
return true;
|
|
47244
|
-
}
|
|
47245
|
-
return latestHeartbeat.ts <= signal.ts;
|
|
47246
|
-
}
|
|
47247
|
-
function installMeetingMqttHandoffBridge(onReconnectRequested) {
|
|
47248
|
-
if (installed || typeof window === "undefined") {
|
|
47249
|
-
return;
|
|
47250
|
-
}
|
|
47251
|
-
installed = true;
|
|
47252
|
-
startTargetHeartbeat();
|
|
47253
|
-
window.addEventListener("storage", (event) => {
|
|
47254
|
-
if (event.key !== RECONNECT_SIGNAL_KEY || !event.newValue) {
|
|
47255
|
-
return;
|
|
47256
|
-
}
|
|
47257
|
-
let signal = null;
|
|
47474
|
+
});
|
|
47475
|
+
const JSSettings = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-27234687"]]);
|
|
47476
|
+
function scheduleJoinRoom() {
|
|
47477
|
+
setTimeout(() => {
|
|
47258
47478
|
try {
|
|
47259
|
-
|
|
47260
|
-
} catch {
|
|
47261
|
-
|
|
47262
|
-
}
|
|
47263
|
-
if (!(signal == null ? void 0 : signal.sourceTabId) || !signal.targetTabId || !signal.handoffId) {
|
|
47264
|
-
return;
|
|
47265
|
-
}
|
|
47266
|
-
const signalTs = Number(signal.ts);
|
|
47267
|
-
if (!signalTs || signalTs <= lastHandledReconnectSignalTs) {
|
|
47268
|
-
return;
|
|
47269
|
-
}
|
|
47270
|
-
lastHandledReconnectSignalTs = signalTs;
|
|
47271
|
-
console.warn("[MQTT_HANDOFF] 收到 MQTT 恢复信号,等待确认目标页是否真的关闭", {
|
|
47272
|
-
sourceTabId: signal.sourceTabId,
|
|
47273
|
-
targetTabId: signal.targetTabId,
|
|
47274
|
-
handoffId: signal.handoffId,
|
|
47275
|
-
signalTs
|
|
47276
|
-
});
|
|
47277
|
-
window.setTimeout(() => {
|
|
47278
|
-
if (!shouldReconnectForSignal(signal)) {
|
|
47279
|
-
console.info("[MQTT_HANDOFF] 忽略 MQTT 恢复,本次更像是目标页刷新/重载", {
|
|
47280
|
-
sourceTabId: signal.sourceTabId,
|
|
47281
|
-
targetTabId: signal.targetTabId,
|
|
47282
|
-
handoffId: signal.handoffId
|
|
47283
|
-
});
|
|
47284
|
-
return;
|
|
47285
|
-
}
|
|
47286
|
-
console.warn("[MQTT_HANDOFF] 确认目标页已关闭,准备恢复来源页 MQTT", {
|
|
47287
|
-
sourceTabId: signal.sourceTabId,
|
|
47288
|
-
targetTabId: signal.targetTabId,
|
|
47289
|
-
handoffId: signal.handoffId
|
|
47290
|
-
});
|
|
47291
|
-
void onReconnectRequested();
|
|
47292
|
-
}, RECONNECT_CHECK_DELAY_MS);
|
|
47293
|
-
});
|
|
47294
|
-
window.addEventListener("beforeunload", (event) => {
|
|
47295
|
-
if (!shouldWarnBeforeUnload()) {
|
|
47296
|
-
return;
|
|
47297
|
-
}
|
|
47298
|
-
event.preventDefault();
|
|
47299
|
-
event.returnValue = "";
|
|
47300
|
-
});
|
|
47301
|
-
window.addEventListener("pagehide", (event) => {
|
|
47302
|
-
const context = getMeetingMqttHandoffContext();
|
|
47303
|
-
const shouldHandleTargetTabClose = !!context && getCurrentMeetingTabId() === context.targetTabId;
|
|
47304
|
-
if (shouldHandleTargetTabClose && context) {
|
|
47305
|
-
writeTargetTabStatus(TARGET_TAB_STATUS_CLOSED, context);
|
|
47306
|
-
sendMeetingLeaveOnClose();
|
|
47307
|
-
}
|
|
47308
|
-
stopTargetHeartbeat();
|
|
47309
|
-
if (event.persisted) {
|
|
47310
|
-
return;
|
|
47479
|
+
joinRoom();
|
|
47480
|
+
} catch (error) {
|
|
47481
|
+
console.error("恢复后无法加入通话/会议", error);
|
|
47311
47482
|
}
|
|
47312
|
-
|
|
47313
|
-
});
|
|
47483
|
+
}, 1e3);
|
|
47314
47484
|
}
|
|
47315
47485
|
let authToken = null;
|
|
47316
47486
|
async function restoreMeetingMqttConnection() {
|