jssz-meeting-component 1.2.2 → 1.2.4
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 +1537 -1532
- 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/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
|
@@ -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;
|
|
@@ -37741,7 +37740,6 @@ const srtc = new Tn({
|
|
|
37741
37740
|
});
|
|
37742
37741
|
srtc.onNotifyChannelEvent = async (evt) => {
|
|
37743
37742
|
var _a25, _b25, _c2, _d, _e, _f2, _g2, _h, _i2, _j, _k, _l2, _m;
|
|
37744
|
-
console.log(evt);
|
|
37745
37743
|
switch (evt.type) {
|
|
37746
37744
|
case on.CONNECTION_QUALITY_CHANGED:
|
|
37747
37745
|
handleConnectionQualityChanged(evt.data);
|
|
@@ -37962,7 +37960,6 @@ async function afterJoin() {
|
|
|
37962
37960
|
item.videoLoadFailed = false;
|
|
37963
37961
|
});
|
|
37964
37962
|
for (const userinfo of Object.values(srtc.getUsersInfo(true))) {
|
|
37965
|
-
console.log("userinfo", userinfo);
|
|
37966
37963
|
await ensurePreferredRemoteVideo(userinfo);
|
|
37967
37964
|
}
|
|
37968
37965
|
scheduleMountTracks(0);
|
|
@@ -38792,23 +38789,27 @@ function handleMeetingEvent(event, data) {
|
|
|
38792
38789
|
emitter.emit("geofenceAlert", data);
|
|
38793
38790
|
break;
|
|
38794
38791
|
case "2021":
|
|
38792
|
+
console.log("所有指令", data);
|
|
38795
38793
|
emitter.emit("commandMessage", data);
|
|
38796
38794
|
break;
|
|
38797
38795
|
case "2016":
|
|
38796
|
+
console.log("围栏更新", data);
|
|
38798
38797
|
emitter.emit("geofenceUpdate", data);
|
|
38799
38798
|
break;
|
|
38800
38799
|
case "2017":
|
|
38800
|
+
console.log("紧急实况", data);
|
|
38801
38801
|
emitter.emit("EmergencyLive", data);
|
|
38802
38802
|
break;
|
|
38803
38803
|
case "2018":
|
|
38804
|
+
console.log("伤员上报", data);
|
|
38804
38805
|
emitter.emit("injuryReport", data);
|
|
38805
38806
|
break;
|
|
38806
38807
|
case "2020":
|
|
38807
|
-
console.log("
|
|
38808
|
+
console.log("已上线的队员", data);
|
|
38808
38809
|
emitter.emit("onlineMember", data);
|
|
38809
38810
|
break;
|
|
38810
38811
|
case "2099":
|
|
38811
|
-
console.log("
|
|
38812
|
+
console.log("事件结束通知", data);
|
|
38812
38813
|
emitter.emit("meetingEnd", data);
|
|
38813
38814
|
break;
|
|
38814
38815
|
}
|
|
@@ -40939,1585 +40940,1621 @@ const _sfc_main$r = /* @__PURE__ */ defineComponent({
|
|
|
40939
40940
|
}
|
|
40940
40941
|
});
|
|
40941
40942
|
const DeviceSelector = /* @__PURE__ */ _export_sfc(_sfc_main$r, [["__scopeId", "data-v-ced67da8"]]);
|
|
40942
|
-
const _hoisted_1$o =
|
|
40943
|
-
|
|
40944
|
-
class: "
|
|
40945
|
-
|
|
40946
|
-
const _hoisted_2$m = { class: "js-call-dialog-container" };
|
|
40947
|
-
const _hoisted_3$l = { class: "status-bar" };
|
|
40948
|
-
const _hoisted_4$j = { class: "status-left" };
|
|
40949
|
-
const _hoisted_5$g = {
|
|
40950
|
-
key: 0,
|
|
40951
|
-
class: "caller-info",
|
|
40952
|
-
title: "来电人"
|
|
40953
|
-
};
|
|
40954
|
-
const _hoisted_6$f = {
|
|
40955
|
-
class: "avatar",
|
|
40956
|
-
style: { "width": "35px", "height": "35px", "font-size": "16px" }
|
|
40943
|
+
const _hoisted_1$o = ["title"];
|
|
40944
|
+
const _hoisted_2$m = {
|
|
40945
|
+
class: "signal-bars",
|
|
40946
|
+
"aria-hidden": "true"
|
|
40957
40947
|
};
|
|
40958
|
-
const
|
|
40959
|
-
const _hoisted_8$d = { class: "caller-name" };
|
|
40960
|
-
const _hoisted_9$b = {
|
|
40948
|
+
const _hoisted_3$l = {
|
|
40961
40949
|
key: 0,
|
|
40962
|
-
class: "
|
|
40950
|
+
class: "signal-text"
|
|
40963
40951
|
};
|
|
40964
|
-
const
|
|
40965
|
-
const
|
|
40966
|
-
const
|
|
40967
|
-
const
|
|
40968
|
-
const
|
|
40969
|
-
const _hoisted_15$6 = { class: "avatar" };
|
|
40970
|
-
const _hoisted_16$6 = { class: "video-loading-overlay" };
|
|
40971
|
-
const _hoisted_17$5 = { class: "video-loading-text" };
|
|
40972
|
-
const _hoisted_18$5 = { class: "video-loading-overlay failed" };
|
|
40973
|
-
const _hoisted_19$5 = ["disabled", "onClick"];
|
|
40974
|
-
const _hoisted_20$5 = { class: "video-meta" };
|
|
40975
|
-
const _hoisted_21$3 = { class: "member-name" };
|
|
40976
|
-
const _hoisted_22$3 = {
|
|
40952
|
+
const _hoisted_4$j = { class: "network-quality-popup-shell" };
|
|
40953
|
+
const _hoisted_5$g = { class: "popup-header" };
|
|
40954
|
+
const _hoisted_6$f = { class: "popup-header-actions" };
|
|
40955
|
+
const _hoisted_7$e = { class: "popup-summary" };
|
|
40956
|
+
const _hoisted_8$d = {
|
|
40977
40957
|
key: 0,
|
|
40978
|
-
class: "
|
|
40979
|
-
};
|
|
40980
|
-
const _hoisted_23$3 = {
|
|
40981
|
-
key: 1,
|
|
40982
|
-
class: "video-empty"
|
|
40958
|
+
class: "popup-reasons"
|
|
40983
40959
|
};
|
|
40984
|
-
const
|
|
40960
|
+
const _hoisted_9$b = { class: "popup-section" };
|
|
40961
|
+
const _hoisted_10$b = { class: "popup-grid" };
|
|
40962
|
+
const _hoisted_11$a = { class: "popup-item-label" };
|
|
40963
|
+
const _hoisted_12$a = { class: "popup-item-value" };
|
|
40964
|
+
const _hoisted_13$8 = { class: "popup-section" };
|
|
40965
|
+
const _hoisted_14$7 = { class: "popup-grid" };
|
|
40966
|
+
const _hoisted_15$6 = { class: "popup-item-label" };
|
|
40967
|
+
const _hoisted_16$6 = { class: "popup-item-value" };
|
|
40968
|
+
const _hoisted_17$5 = { class: "popup-header" };
|
|
40969
|
+
const _hoisted_18$5 = { class: "popup-header-actions" };
|
|
40970
|
+
const _hoisted_19$5 = { class: "popup-section-container" };
|
|
40971
|
+
const _hoisted_20$5 = ["onClick"];
|
|
40972
|
+
const _hoisted_21$3 = { class: "detail-section-main" };
|
|
40973
|
+
const _hoisted_22$3 = { class: "popup-section-title" };
|
|
40974
|
+
const _hoisted_23$3 = { class: "popup-section-count" };
|
|
40975
|
+
const _hoisted_24$3 = { class: "detail-section-icon" };
|
|
40985
40976
|
const _hoisted_25$3 = {
|
|
40986
40977
|
key: 0,
|
|
40987
|
-
class: "
|
|
40978
|
+
class: "metric-card-list"
|
|
40988
40979
|
};
|
|
40989
|
-
const _hoisted_26$3 = {
|
|
40990
|
-
const _hoisted_27$3 = { class: "
|
|
40991
|
-
const _hoisted_28$3 = {
|
|
40980
|
+
const _hoisted_26$3 = { class: "metric-card-header" };
|
|
40981
|
+
const _hoisted_27$3 = { class: "metric-card-title" };
|
|
40982
|
+
const _hoisted_28$3 = { class: "metric-card-subtitle" };
|
|
40983
|
+
const _hoisted_29$2 = { class: "metric-card-grid" };
|
|
40984
|
+
const _hoisted_30$2 = { class: "popup-item-label" };
|
|
40985
|
+
const _hoisted_31$1 = { class: "popup-item-value" };
|
|
40986
|
+
const _hoisted_32$1 = {
|
|
40992
40987
|
key: 1,
|
|
40993
|
-
class: "
|
|
40988
|
+
class: "popup-empty"
|
|
40994
40989
|
};
|
|
40995
|
-
const DEFAULT_SUB_VIDEO_HEIGHT = 110;
|
|
40996
|
-
const DEFAULT_SUB_VIDEO_WIDTH = 190;
|
|
40997
|
-
const SUB_VIDEO_GAP = 12;
|
|
40998
|
-
const CONTROL_BAR_HEIGHT = 90;
|
|
40999
|
-
const STATUS_BAR_HEIGHT = 48;
|
|
41000
40990
|
const _sfc_main$q = /* @__PURE__ */ defineComponent({
|
|
41001
|
-
__name: "
|
|
40991
|
+
__name: "NetworkQualitySignal",
|
|
41002
40992
|
props: {
|
|
41003
40993
|
theme: { default: "dark" },
|
|
41004
|
-
|
|
41005
|
-
|
|
40994
|
+
size: { default: "default" },
|
|
40995
|
+
showText: { type: Boolean, default: false }
|
|
41006
40996
|
},
|
|
41007
40997
|
setup(__props) {
|
|
41008
|
-
const { meState: meState2 } = storeToRefs(useMeetingStore());
|
|
41009
40998
|
const props = __props;
|
|
41010
|
-
const
|
|
40999
|
+
const triggerRef = ref(null);
|
|
41000
|
+
const showPopup = ref(false);
|
|
41001
|
+
const advancedOpen = ref(false);
|
|
41002
|
+
const collapsedSections = ref({});
|
|
41003
|
+
const advancedDetails = ref();
|
|
41004
|
+
let detailTimer = null;
|
|
41011
41005
|
const themeClass = computed(() => `theme-${props.theme}`);
|
|
41012
|
-
|
|
41013
|
-
|
|
41014
|
-
|
|
41015
|
-
|
|
41016
|
-
|
|
41017
|
-
|
|
41018
|
-
|
|
41019
|
-
|
|
41020
|
-
|
|
41021
|
-
|
|
41022
|
-
|
|
41023
|
-
|
|
41024
|
-
|
|
41025
|
-
|
|
41026
|
-
|
|
41027
|
-
|
|
41028
|
-
|
|
41029
|
-
|
|
41006
|
+
function formatValue(value, suffix = "", digits = 0) {
|
|
41007
|
+
if (typeof value !== "number" || Number.isNaN(value)) return "--";
|
|
41008
|
+
return `${value.toFixed(digits)}${suffix}`;
|
|
41009
|
+
}
|
|
41010
|
+
function formatMetricNumber(value, suffix = "", digits = 0) {
|
|
41011
|
+
if (typeof value !== "number" || Number.isNaN(value)) return "--";
|
|
41012
|
+
return `${value.toFixed(digits)}${suffix}`;
|
|
41013
|
+
}
|
|
41014
|
+
function formatBytes(value) {
|
|
41015
|
+
if (typeof value !== "number" || Number.isNaN(value)) return "--";
|
|
41016
|
+
if (value >= 1024 * 1024) return `${(value / (1024 * 1024)).toFixed(2)} MB`;
|
|
41017
|
+
if (value >= 1024) return `${(value / 1024).toFixed(1)} KB`;
|
|
41018
|
+
return `${value.toFixed(0)} B`;
|
|
41019
|
+
}
|
|
41020
|
+
function formatDimension(width, height) {
|
|
41021
|
+
if (!width || !height) return "--";
|
|
41022
|
+
return `${width} x ${height}`;
|
|
41023
|
+
}
|
|
41024
|
+
function formatLossRate(value) {
|
|
41025
|
+
if (typeof value !== "number" || Number.isNaN(value)) return "--";
|
|
41026
|
+
return `${value.toFixed(1)}%`;
|
|
41027
|
+
}
|
|
41028
|
+
function formatMos(value) {
|
|
41029
|
+
if (typeof value !== "number" || value <= 0 || Number.isNaN(value)) return "--";
|
|
41030
|
+
return value.toFixed(1);
|
|
41031
|
+
}
|
|
41032
|
+
function formatUpdatedAt(timestamp) {
|
|
41033
|
+
if (!timestamp) return "--";
|
|
41034
|
+
const date = new Date(timestamp);
|
|
41035
|
+
const hh = String(date.getHours()).padStart(2, "0");
|
|
41036
|
+
const mm = String(date.getMinutes()).padStart(2, "0");
|
|
41037
|
+
const ss = String(date.getSeconds()).padStart(2, "0");
|
|
41038
|
+
return `${hh}:${mm}:${ss}`;
|
|
41039
|
+
}
|
|
41040
|
+
function formatReason(value) {
|
|
41041
|
+
return value || "--";
|
|
41042
|
+
}
|
|
41043
|
+
function getMemberNameById(memberId) {
|
|
41044
|
+
var _a25;
|
|
41045
|
+
if (!memberId) return "";
|
|
41046
|
+
const matched = members.value.find(
|
|
41047
|
+
(member) => {
|
|
41048
|
+
var _a26;
|
|
41049
|
+
return ((_a26 = member == null ? void 0 : member.member) == null ? void 0 : _a26.memberId) === String(memberId);
|
|
41030
41050
|
}
|
|
41031
|
-
},
|
|
41032
|
-
{
|
|
41033
|
-
immediate: true
|
|
41034
|
-
}
|
|
41035
|
-
);
|
|
41036
|
-
const isCalling = computed(() => callStatus.value === "calling");
|
|
41037
|
-
const isReceiving = computed(() => callStatus.value === "receiving");
|
|
41038
|
-
const isConnected = computed(() => callStatus.value === "connected");
|
|
41039
|
-
const isListening = computed(() => callStatus.value === "listening");
|
|
41040
|
-
const isForcibleInsertion = computed(
|
|
41041
|
-
() => callStatus.value === "forcible-insertion"
|
|
41042
|
-
);
|
|
41043
|
-
const visibleMembers = computed(() => {
|
|
41044
|
-
return members.value.filter(
|
|
41045
|
-
(item) => item.roleType !== "4" && item.joinStaus === "1" && (!isListening.value || item.member.memberId !== getUserId())
|
|
41046
41051
|
);
|
|
41047
|
-
|
|
41048
|
-
|
|
41049
|
-
|
|
41050
|
-
|
|
41051
|
-
|
|
41052
|
-
|
|
41053
|
-
|
|
41054
|
-
|
|
41055
|
-
}
|
|
41056
|
-
|
|
41057
|
-
|
|
41058
|
-
|
|
41059
|
-
|
|
41052
|
+
return ((_a25 = matched == null ? void 0 : matched.member) == null ? void 0 : _a25.name) || "";
|
|
41053
|
+
}
|
|
41054
|
+
function startDetailRefresh() {
|
|
41055
|
+
stopDetailRefresh();
|
|
41056
|
+
refreshAdvancedDetails();
|
|
41057
|
+
detailTimer = window.setInterval(() => {
|
|
41058
|
+
refreshAdvancedDetails();
|
|
41059
|
+
}, 2e3);
|
|
41060
|
+
}
|
|
41061
|
+
function stopDetailRefresh() {
|
|
41062
|
+
if (detailTimer !== null) {
|
|
41063
|
+
window.clearInterval(detailTimer);
|
|
41064
|
+
detailTimer = null;
|
|
41060
41065
|
}
|
|
41061
|
-
|
|
41062
|
-
|
|
41066
|
+
}
|
|
41067
|
+
function refreshAdvancedDetails() {
|
|
41068
|
+
advancedDetails.value = readNetworkQualityMetricDetails();
|
|
41069
|
+
}
|
|
41070
|
+
function isSectionCollapsed(key) {
|
|
41071
|
+
return collapsedSections.value[key] ?? false;
|
|
41072
|
+
}
|
|
41073
|
+
function toggleSection(key) {
|
|
41074
|
+
collapsedSections.value[key] = !isSectionCollapsed(key);
|
|
41075
|
+
}
|
|
41076
|
+
function expandAllSections() {
|
|
41077
|
+
collapsedSections.value = Object.fromEntries(
|
|
41078
|
+
detailSections.value.map((section) => [section.key, false])
|
|
41063
41079
|
);
|
|
41064
|
-
|
|
41065
|
-
|
|
41066
|
-
|
|
41067
|
-
|
|
41068
|
-
|
|
41069
|
-
|
|
41070
|
-
|
|
41071
|
-
|
|
41072
|
-
|
|
41073
|
-
|
|
41074
|
-
|
|
41075
|
-
|
|
41076
|
-
|
|
41077
|
-
|
|
41080
|
+
}
|
|
41081
|
+
function collapseAllSections() {
|
|
41082
|
+
collapsedSections.value = Object.fromEntries(
|
|
41083
|
+
detailSections.value.map((section) => [section.key, true])
|
|
41084
|
+
);
|
|
41085
|
+
}
|
|
41086
|
+
function toggleAllSections() {
|
|
41087
|
+
if (allSectionsExpanded.value) {
|
|
41088
|
+
collapseAllSections();
|
|
41089
|
+
return;
|
|
41090
|
+
}
|
|
41091
|
+
expandAllSections();
|
|
41092
|
+
}
|
|
41093
|
+
function syncSectionCollapse(preserveExisting = true) {
|
|
41094
|
+
const nextState = {};
|
|
41095
|
+
for (const section of detailSections.value) {
|
|
41096
|
+
if (preserveExisting && section.key in collapsedSections.value) {
|
|
41097
|
+
nextState[section.key] = collapsedSections.value[section.key];
|
|
41098
|
+
continue;
|
|
41078
41099
|
}
|
|
41079
|
-
|
|
41080
|
-
{ immediate: true, deep: true }
|
|
41081
|
-
);
|
|
41082
|
-
const mainMember = computed(() => {
|
|
41083
|
-
if (!visibleMembers.value.length) return null;
|
|
41084
|
-
if (!mainMemberId.value) {
|
|
41085
|
-
return visibleMembers.value[0];
|
|
41100
|
+
nextState[section.key] = false;
|
|
41086
41101
|
}
|
|
41087
|
-
|
|
41088
|
-
|
|
41089
|
-
|
|
41102
|
+
collapsedSections.value = nextState;
|
|
41103
|
+
}
|
|
41104
|
+
const activeBars = computed(() => {
|
|
41105
|
+
if (networkQualityState.isOffline || networkQualityState.isStale) {
|
|
41106
|
+
return 0;
|
|
41107
|
+
}
|
|
41108
|
+
return getNetworkSignalBars(networkQualityState.level);
|
|
41090
41109
|
});
|
|
41091
|
-
const
|
|
41092
|
-
if (!
|
|
41093
|
-
return
|
|
41094
|
-
(item) => {
|
|
41095
|
-
var _a25;
|
|
41096
|
-
return item.member.memberId !== ((_a25 = mainMember.value) == null ? void 0 : _a25.member.memberId);
|
|
41097
|
-
}
|
|
41098
|
-
);
|
|
41110
|
+
const allSectionsExpanded = computed(() => {
|
|
41111
|
+
if (!detailSections.value.length) return true;
|
|
41112
|
+
return detailSections.value.every((section) => !isSectionCollapsed(section.key));
|
|
41099
41113
|
});
|
|
41100
|
-
const
|
|
41101
|
-
|
|
41102
|
-
|
|
41103
|
-
positions[member.member.memberId] = {
|
|
41104
|
-
position: "absolute",
|
|
41105
|
-
width: `${DEFAULT_SUB_VIDEO_WIDTH}px`,
|
|
41106
|
-
height: `${DEFAULT_SUB_VIDEO_HEIGHT}px`,
|
|
41107
|
-
right: "16px",
|
|
41108
|
-
top: `${STATUS_BAR_HEIGHT + 16 + index * (DEFAULT_SUB_VIDEO_HEIGHT + SUB_VIDEO_GAP)}px`
|
|
41109
|
-
};
|
|
41110
|
-
});
|
|
41111
|
-
return positions;
|
|
41114
|
+
const reasonText = computed(() => {
|
|
41115
|
+
if (!networkQualityState.reasons.length) return "";
|
|
41116
|
+
return `可能原因:${networkQualityState.reasons.join("、")}`;
|
|
41112
41117
|
});
|
|
41113
|
-
const
|
|
41114
|
-
|
|
41115
|
-
|
|
41116
|
-
|
|
41117
|
-
|
|
41118
|
-
|
|
41119
|
-
|
|
41120
|
-
|
|
41121
|
-
|
|
41122
|
-
|
|
41123
|
-
|
|
41124
|
-
|
|
41125
|
-
|
|
41126
|
-
|
|
41127
|
-
|
|
41128
|
-
|
|
41129
|
-
|
|
41130
|
-
|
|
41131
|
-
|
|
41132
|
-
|
|
41133
|
-
|
|
41134
|
-
|
|
41135
|
-
|
|
41136
|
-
|
|
41137
|
-
|
|
41138
|
-
|
|
41139
|
-
|
|
41140
|
-
|
|
41141
|
-
|
|
41142
|
-
|
|
41143
|
-
|
|
41144
|
-
|
|
41145
|
-
|
|
41146
|
-
|
|
41147
|
-
|
|
41148
|
-
|
|
41149
|
-
|
|
41150
|
-
|
|
41151
|
-
|
|
41152
|
-
|
|
41153
|
-
|
|
41154
|
-
|
|
41155
|
-
|
|
41156
|
-
|
|
41157
|
-
|
|
41158
|
-
|
|
41159
|
-
|
|
41160
|
-
|
|
41118
|
+
const qualityItems = computed(() => [
|
|
41119
|
+
{ label: "总体质量", value: networkQualityState.label },
|
|
41120
|
+
{ label: "上行质量", value: networkQualityState.uplink },
|
|
41121
|
+
{ label: "下行质量", value: networkQualityState.downlink },
|
|
41122
|
+
{ label: "MOS", value: formatMos(networkQualityState.mos) },
|
|
41123
|
+
{ label: "最近更新", value: formatUpdatedAt(networkQualityState.updatedAt) },
|
|
41124
|
+
{
|
|
41125
|
+
label: "数据状态",
|
|
41126
|
+
value: networkQualityState.isStale ? "已过期" : "实时"
|
|
41127
|
+
}
|
|
41128
|
+
]);
|
|
41129
|
+
const overviewItems = computed(() => {
|
|
41130
|
+
const stats = networkQualityState.stats;
|
|
41131
|
+
return [
|
|
41132
|
+
{ label: "上行 RTT", value: formatValue(stats == null ? void 0 : stats.rtt_up, " ms") },
|
|
41133
|
+
{ label: "下行 RTT", value: formatValue(stats == null ? void 0 : stats.rtt_down, " ms") },
|
|
41134
|
+
{ label: "上行码率", value: formatValue(stats == null ? void 0 : stats.bitrate_up, " kb/s") },
|
|
41135
|
+
{ label: "下行码率", value: formatValue(stats == null ? void 0 : stats.bitrate_down, " kb/s") },
|
|
41136
|
+
{ label: "上行丢包率", value: formatLossRate(stats == null ? void 0 : stats.lossrate_up) },
|
|
41137
|
+
{ label: "下行丢包率", value: formatLossRate(stats == null ? void 0 : stats.lossrate_down) },
|
|
41138
|
+
{
|
|
41139
|
+
label: "可用上行带宽",
|
|
41140
|
+
value: formatValue(stats == null ? void 0 : stats.available_outgoing_bitrate, " kb/s")
|
|
41141
|
+
},
|
|
41142
|
+
{
|
|
41143
|
+
label: "可用下行带宽",
|
|
41144
|
+
value: formatValue(stats == null ? void 0 : stats.available_incoming_bitrate, " kb/s")
|
|
41145
|
+
}
|
|
41146
|
+
];
|
|
41147
|
+
});
|
|
41148
|
+
function createAudioSendCard(item, index) {
|
|
41149
|
+
const stats = (item == null ? void 0 : item.stats) || {};
|
|
41150
|
+
return {
|
|
41151
|
+
title: `本地音频 ${index + 1}`,
|
|
41152
|
+
subtitle: (item == null ? void 0 : item.desc) || (stats == null ? void 0 : stats.streamId) || "发送轨道",
|
|
41153
|
+
items: [
|
|
41154
|
+
{ label: "实时码率", value: formatMetricNumber(item == null ? void 0 : item.bitrate, " kb/s") },
|
|
41155
|
+
{ label: "音频电平", value: formatMetricNumber(item == null ? void 0 : item.db, " dBFS", 1) },
|
|
41156
|
+
{ label: "已发包数", value: formatMetricNumber(stats == null ? void 0 : stats.packetsSent) },
|
|
41157
|
+
{ label: "已发字节", value: formatBytes(stats == null ? void 0 : stats.bytesSent) },
|
|
41158
|
+
{ label: "远端丢包", value: formatMetricNumber(stats == null ? void 0 : stats.packetsLost) },
|
|
41159
|
+
{ label: "往返时延", value: formatMetricNumber(stats == null ? void 0 : stats.roundTripTime, " ms") },
|
|
41160
|
+
{ label: "远端抖动", value: formatMetricNumber(stats == null ? void 0 : stats.jitter, " ms") },
|
|
41161
|
+
{ label: "采样时间", value: formatUpdatedAt(stats == null ? void 0 : stats.timestamp) }
|
|
41162
|
+
]
|
|
41163
|
+
};
|
|
41164
|
+
}
|
|
41165
|
+
function createVideoSendCard(item, index) {
|
|
41166
|
+
const stats = (item == null ? void 0 : item.stats) || {};
|
|
41167
|
+
return {
|
|
41168
|
+
title: `本地视频 ${index + 1}`,
|
|
41169
|
+
subtitle: (item == null ? void 0 : item.desc) || (stats == null ? void 0 : stats.rid) || (stats == null ? void 0 : stats.streamId) || "发送轨道",
|
|
41170
|
+
items: [
|
|
41171
|
+
{ label: "实时码率", value: formatMetricNumber(item == null ? void 0 : item.bitrate, " kb/s") },
|
|
41172
|
+
{ 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)) },
|
|
41173
|
+
{ label: "帧率", value: formatMetricNumber((item == null ? void 0 : item.fps) || (stats == null ? void 0 : stats.framesPerSecond), " fps") },
|
|
41174
|
+
{ label: "已发帧数", value: formatMetricNumber(stats == null ? void 0 : stats.framesSent) },
|
|
41175
|
+
{ label: "目标码率", value: formatMetricNumber(stats == null ? void 0 : stats.targetBitrate, " bps") },
|
|
41176
|
+
{ 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)}` },
|
|
41177
|
+
{ label: "重传包数", value: formatMetricNumber(stats == null ? void 0 : stats.retransmittedPacketsSent) },
|
|
41178
|
+
{ label: "受限原因", value: formatReason(stats == null ? void 0 : stats.qualityLimitationReason) },
|
|
41179
|
+
{ label: "分辨率变化", value: formatMetricNumber(stats == null ? void 0 : stats.qualityLimitationResolutionChanges) },
|
|
41180
|
+
{ label: "往返时延", value: formatMetricNumber(stats == null ? void 0 : stats.roundTripTime, " ms") },
|
|
41181
|
+
{ label: "采样时间", value: formatUpdatedAt(stats == null ? void 0 : stats.timestamp) }
|
|
41182
|
+
]
|
|
41183
|
+
};
|
|
41184
|
+
}
|
|
41185
|
+
function createAudioRecvCard(item, index) {
|
|
41186
|
+
const stats = (item == null ? void 0 : item.stats) || {};
|
|
41187
|
+
return {
|
|
41188
|
+
title: `远端音频 ${index + 1}`,
|
|
41189
|
+
subtitle: (item == null ? void 0 : item.uid) || (item == null ? void 0 : item.desc) || (stats == null ? void 0 : stats.streamId) || "接收轨道",
|
|
41190
|
+
items: [
|
|
41191
|
+
{ label: "实时码率", value: formatMetricNumber(item == null ? void 0 : item.bitrate, " kb/s") },
|
|
41192
|
+
{ label: "音频电平", value: formatMetricNumber(item == null ? void 0 : item.db, " dBFS", 1) },
|
|
41193
|
+
{ label: "已收包数", value: formatMetricNumber(stats == null ? void 0 : stats.packetsReceived) },
|
|
41194
|
+
{ label: "已收字节", value: formatBytes(stats == null ? void 0 : stats.bytesReceived) },
|
|
41195
|
+
{ label: "丢包数", value: formatMetricNumber(stats == null ? void 0 : stats.packetsLost) },
|
|
41196
|
+
{ label: "网络抖动", value: formatMetricNumber(stats == null ? void 0 : stats.jitter, " ms") },
|
|
41197
|
+
{ label: "缓冲均值", value: formatMetricNumber(stats == null ? void 0 : stats.jitterBufferAvgDelay, " ms") },
|
|
41198
|
+
{ label: "隐藏事件", value: formatMetricNumber(stats == null ? void 0 : stats.concealmentEvents) },
|
|
41199
|
+
{ label: "静音隐藏", value: formatMetricNumber(stats == null ? void 0 : stats.silentConcealmentEvents) },
|
|
41200
|
+
{ label: "采样时间", value: formatUpdatedAt(stats == null ? void 0 : stats.timestamp) }
|
|
41201
|
+
]
|
|
41202
|
+
};
|
|
41203
|
+
}
|
|
41204
|
+
function createVideoRecvCard(item, index) {
|
|
41205
|
+
const stats = (item == null ? void 0 : item.stats) || {};
|
|
41206
|
+
const memberName = getMemberNameById(item == null ? void 0 : item.uid);
|
|
41207
|
+
return {
|
|
41208
|
+
title: `远端视频 ${index + 1}`,
|
|
41209
|
+
subtitle: memberName || (item == null ? void 0 : item.uid) || (item == null ? void 0 : item.desc) || (stats == null ? void 0 : stats.mimeType) || "接收轨道",
|
|
41210
|
+
items: [
|
|
41211
|
+
{ label: "实时码率", value: formatMetricNumber(item == null ? void 0 : item.bitrate, " kb/s") },
|
|
41212
|
+
{ 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)) },
|
|
41213
|
+
{ label: "帧率", value: formatMetricNumber((item == null ? void 0 : item.fps) || (stats == null ? void 0 : stats.framesPerSecond), " fps") },
|
|
41214
|
+
{ label: "已收包数", value: formatMetricNumber(stats == null ? void 0 : stats.packetsReceived) },
|
|
41215
|
+
{ label: "已收字节", value: formatBytes(stats == null ? void 0 : stats.bytesReceived) },
|
|
41216
|
+
{ label: "丢包数", value: formatMetricNumber(stats == null ? void 0 : stats.packetsLost) },
|
|
41217
|
+
{ label: "接收/解码帧", value: `${formatMetricNumber(stats == null ? void 0 : stats.framesReceived)}/${formatMetricNumber(stats == null ? void 0 : stats.framesDecoded)}` },
|
|
41218
|
+
{ label: "丢帧数", value: formatMetricNumber(stats == null ? void 0 : stats.framesDropped) },
|
|
41219
|
+
{ 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)}` },
|
|
41220
|
+
{ label: "缓冲均值", value: formatMetricNumber(stats == null ? void 0 : stats.jitterBufferAvgDelay, " ms") },
|
|
41221
|
+
{ label: "解码器", value: formatReason(stats == null ? void 0 : stats.decoderImplementation) },
|
|
41222
|
+
{ label: "MIME", value: formatReason(stats == null ? void 0 : stats.mimeType) },
|
|
41223
|
+
{ label: "采样时间", value: formatUpdatedAt(stats == null ? void 0 : stats.timestamp) }
|
|
41224
|
+
]
|
|
41225
|
+
};
|
|
41226
|
+
}
|
|
41227
|
+
const detailSections = computed(() => {
|
|
41228
|
+
const details = advancedDetails.value;
|
|
41229
|
+
return [
|
|
41230
|
+
{
|
|
41231
|
+
key: "local-audio",
|
|
41232
|
+
title: "本地音频发送",
|
|
41233
|
+
cards: ((details == null ? void 0 : details.local_audios) || []).map(createAudioSendCard)
|
|
41234
|
+
},
|
|
41235
|
+
{
|
|
41236
|
+
key: "local-video",
|
|
41237
|
+
title: "本地视频发送",
|
|
41238
|
+
cards: ((details == null ? void 0 : details.local_videos) || []).map(createVideoSendCard)
|
|
41239
|
+
},
|
|
41240
|
+
{
|
|
41241
|
+
key: "remote-audio",
|
|
41242
|
+
title: "远端音频接收",
|
|
41243
|
+
cards: ((details == null ? void 0 : details.remote_audios) || []).map(createAudioRecvCard)
|
|
41244
|
+
},
|
|
41245
|
+
{
|
|
41246
|
+
key: "remote-video",
|
|
41247
|
+
title: "远端视频接收",
|
|
41248
|
+
cards: ((details == null ? void 0 : details.remote_videos) || []).map(createVideoRecvCard)
|
|
41249
|
+
}
|
|
41250
|
+
];
|
|
41251
|
+
});
|
|
41252
|
+
watch(showPopup, (visible) => {
|
|
41253
|
+
if (visible) {
|
|
41254
|
+
refreshNetworkQualitySnapshot(false);
|
|
41255
|
+
if (advancedOpen.value) {
|
|
41256
|
+
syncSectionCollapse();
|
|
41257
|
+
startDetailRefresh();
|
|
41258
|
+
}
|
|
41259
|
+
return;
|
|
41260
|
+
}
|
|
41261
|
+
stopDetailRefresh();
|
|
41262
|
+
advancedOpen.value = false;
|
|
41263
|
+
collapsedSections.value = {};
|
|
41264
|
+
advancedDetails.value = void 0;
|
|
41265
|
+
});
|
|
41266
|
+
watch(advancedOpen, (open2) => {
|
|
41267
|
+
if (!showPopup.value) return;
|
|
41268
|
+
if (open2) {
|
|
41269
|
+
syncSectionCollapse(false);
|
|
41270
|
+
startDetailRefresh();
|
|
41271
|
+
} else {
|
|
41272
|
+
stopDetailRefresh();
|
|
41273
|
+
advancedDetails.value = void 0;
|
|
41161
41274
|
}
|
|
41162
41275
|
});
|
|
41163
|
-
const callerInfo = ref({});
|
|
41164
41276
|
watch(
|
|
41165
|
-
|
|
41277
|
+
detailSections,
|
|
41166
41278
|
() => {
|
|
41167
|
-
|
|
41168
|
-
|
|
41169
|
-
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41170
|
-
);
|
|
41171
|
-
callerInfo.value = info || {};
|
|
41172
|
-
} catch {
|
|
41173
|
-
callerInfo.value = {};
|
|
41174
|
-
}
|
|
41279
|
+
if (!advancedOpen.value) return;
|
|
41280
|
+
syncSectionCollapse();
|
|
41175
41281
|
},
|
|
41176
|
-
{
|
|
41282
|
+
{ deep: true }
|
|
41177
41283
|
);
|
|
41178
|
-
const onChange = async (type) => {
|
|
41179
|
-
switch (type) {
|
|
41180
|
-
case RoomModalSelectType.microphoneClick:
|
|
41181
|
-
if (micOperationBusy.value) return;
|
|
41182
|
-
if (isAuthority.value) {
|
|
41183
|
-
showNotification(alertMsg, "warning", 5e3);
|
|
41184
|
-
return;
|
|
41185
|
-
}
|
|
41186
|
-
if (meState2.value.microPhoneState === "1") {
|
|
41187
|
-
await closeMic();
|
|
41188
|
-
} else {
|
|
41189
|
-
await openMic();
|
|
41190
|
-
}
|
|
41191
|
-
break;
|
|
41192
|
-
case RoomModalSelectType.cameraClick:
|
|
41193
|
-
if (cameraOperationBusy.value) return;
|
|
41194
|
-
if (isAuthority.value) {
|
|
41195
|
-
alert(alertMsg);
|
|
41196
|
-
return;
|
|
41197
|
-
}
|
|
41198
|
-
if (meState2.value.cameraState === "1") {
|
|
41199
|
-
await closeCamera();
|
|
41200
|
-
} else {
|
|
41201
|
-
await openCamera();
|
|
41202
|
-
}
|
|
41203
|
-
break;
|
|
41204
|
-
case RoomModalSelectType.acceptClick:
|
|
41205
|
-
acceptCall();
|
|
41206
|
-
break;
|
|
41207
|
-
case RoomModalSelectType.endClick:
|
|
41208
|
-
endCall();
|
|
41209
|
-
break;
|
|
41210
|
-
}
|
|
41211
|
-
};
|
|
41212
|
-
const acceptCall = () => {
|
|
41213
|
-
const meetingInfo = JSON.parse(
|
|
41214
|
-
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41215
|
-
);
|
|
41216
|
-
setCallStatus("connected");
|
|
41217
|
-
stopSosFlash();
|
|
41218
|
-
getAnswerCall({
|
|
41219
|
-
meetingId: meetingInfo.meetingId,
|
|
41220
|
-
memberId: getUserId(),
|
|
41221
|
-
cameraStatus: "0",
|
|
41222
|
-
audioStatus: "0"
|
|
41223
|
-
}).then(() => {
|
|
41224
|
-
return getJoinCall({
|
|
41225
|
-
meetingId: meetingInfo.meetingId,
|
|
41226
|
-
memberId: getUserId(),
|
|
41227
|
-
cameraStatus: "0",
|
|
41228
|
-
audioStatus: "0"
|
|
41229
|
-
});
|
|
41230
|
-
}).then((resp) => {
|
|
41231
|
-
if (resp && resp.code === 200) {
|
|
41232
|
-
sessionStorage.setItem("JS_MEETING_INFO", JSON.stringify(resp.data));
|
|
41233
|
-
console.log("拨打电话", resp.data.meetingToken);
|
|
41234
|
-
setTimeout(() => {
|
|
41235
|
-
joinRoom();
|
|
41236
|
-
}, 100);
|
|
41237
|
-
stopRingtone();
|
|
41238
|
-
recordMeeting("start");
|
|
41239
|
-
}
|
|
41240
|
-
}).catch((err) => {
|
|
41241
|
-
console.error("接听失败", err);
|
|
41242
|
-
setCallStatus("end");
|
|
41243
|
-
});
|
|
41244
|
-
};
|
|
41245
|
-
const endCall = async () => {
|
|
41246
|
-
visible.value = false;
|
|
41247
|
-
stopSosFlash();
|
|
41248
|
-
const meetingInfo = JSON.parse(
|
|
41249
|
-
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41250
|
-
);
|
|
41251
|
-
setCallStatus("end");
|
|
41252
|
-
try {
|
|
41253
|
-
const res = await getHangUpCall({
|
|
41254
|
-
meetingId: meetingInfo.meetingId,
|
|
41255
|
-
memberId: getUserId()
|
|
41256
|
-
});
|
|
41257
|
-
if (res.code === 200) {
|
|
41258
|
-
await logoutRoomAction();
|
|
41259
|
-
clearTimer();
|
|
41260
|
-
recordMeeting("stop");
|
|
41261
|
-
}
|
|
41262
|
-
} catch (err) {
|
|
41263
|
-
console.error("挂断失败", err);
|
|
41264
|
-
await logoutRoomAction();
|
|
41265
|
-
}
|
|
41266
|
-
};
|
|
41267
|
-
const stopMonitoring = async () => {
|
|
41268
|
-
visible.value = false;
|
|
41269
|
-
const meetingInfo = JSON.parse(
|
|
41270
|
-
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41271
|
-
);
|
|
41272
|
-
try {
|
|
41273
|
-
const res = await getMeetingLeave({
|
|
41274
|
-
meetingId: meetingInfo.meetingId,
|
|
41275
|
-
memberId: getUserId()
|
|
41276
|
-
});
|
|
41277
|
-
if (res.code === 200) {
|
|
41278
|
-
await logoutRoomAction();
|
|
41279
|
-
clearTimer();
|
|
41280
|
-
}
|
|
41281
|
-
} catch (err) {
|
|
41282
|
-
console.error("离开失败", err);
|
|
41283
|
-
await logoutRoomAction();
|
|
41284
|
-
}
|
|
41285
|
-
};
|
|
41286
|
-
const clearTimer = () => {
|
|
41287
|
-
if (timer) {
|
|
41288
|
-
clearInterval(timer);
|
|
41289
|
-
timer = null;
|
|
41290
|
-
}
|
|
41291
|
-
};
|
|
41292
|
-
const recordMeeting = (newState) => {
|
|
41293
|
-
const meetingInfo = JSON.parse(
|
|
41294
|
-
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41295
|
-
);
|
|
41296
|
-
let params = {
|
|
41297
|
-
meetingId: meetingInfo.meetingId,
|
|
41298
|
-
memberId: getUserId(),
|
|
41299
|
-
cmd: newState
|
|
41300
|
-
};
|
|
41301
|
-
getMcuCtrl(params).then(() => {
|
|
41302
|
-
}).catch(() => {
|
|
41303
|
-
});
|
|
41304
|
-
};
|
|
41305
|
-
const toggleDeviceSelector = (deviceType) => {
|
|
41306
|
-
currentDeviceType.value = deviceType;
|
|
41307
|
-
showDeviceSelector.value = !showDeviceSelector.value;
|
|
41308
|
-
};
|
|
41309
|
-
watch(
|
|
41310
|
-
() => visible.value,
|
|
41311
|
-
(newValue) => {
|
|
41312
|
-
if (newValue) {
|
|
41313
|
-
showDeviceSelector.value = false;
|
|
41314
|
-
}
|
|
41315
|
-
}
|
|
41316
|
-
);
|
|
41317
|
-
onMounted(() => {
|
|
41318
|
-
});
|
|
41319
41284
|
onUnmounted(() => {
|
|
41320
|
-
|
|
41321
|
-
clearInterval(timer);
|
|
41322
|
-
timer = null;
|
|
41323
|
-
}
|
|
41285
|
+
stopDetailRefresh();
|
|
41324
41286
|
});
|
|
41325
41287
|
return (_ctx, _cache) => {
|
|
41326
|
-
return openBlock(),
|
|
41327
|
-
|
|
41328
|
-
|
|
41329
|
-
|
|
41330
|
-
|
|
41288
|
+
return openBlock(), createElementBlock("div", {
|
|
41289
|
+
class: normalizeClass(["network-quality-signal", [`size-${_ctx.size}`]])
|
|
41290
|
+
}, [
|
|
41291
|
+
createElementVNode("button", {
|
|
41292
|
+
ref_key: "triggerRef",
|
|
41293
|
+
ref: triggerRef,
|
|
41294
|
+
type: "button",
|
|
41295
|
+
class: normalizeClass(["network-quality-trigger", [
|
|
41296
|
+
`is-${unref(networkQualityState).level}`,
|
|
41297
|
+
{
|
|
41298
|
+
"is-alert": unref(networkQualityState).isOffline || unref(networkQualityState).isStale
|
|
41299
|
+
}
|
|
41300
|
+
]]),
|
|
41301
|
+
title: unref(networkQualityState).summary,
|
|
41302
|
+
onClick: _cache[0] || (_cache[0] = ($event) => showPopup.value = !showPopup.value)
|
|
41331
41303
|
}, [
|
|
41332
|
-
createElementVNode("
|
|
41333
|
-
|
|
41334
|
-
createElementVNode("
|
|
41335
|
-
|
|
41336
|
-
|
|
41337
|
-
|
|
41338
|
-
|
|
41339
|
-
|
|
41304
|
+
createElementVNode("span", _hoisted_2$m, [
|
|
41305
|
+
(openBlock(), createElementBlock(Fragment, null, renderList(4, (index) => {
|
|
41306
|
+
return createElementVNode("span", {
|
|
41307
|
+
key: index,
|
|
41308
|
+
class: normalizeClass(["signal-bar", { active: index <= activeBars.value }])
|
|
41309
|
+
}, null, 2);
|
|
41310
|
+
}), 64))
|
|
41311
|
+
]),
|
|
41312
|
+
_ctx.showText ? (openBlock(), createElementBlock("span", _hoisted_3$l, toDisplayString(unref(networkQualityState).label), 1)) : createCommentVNode("", true)
|
|
41313
|
+
], 10, _hoisted_1$o),
|
|
41314
|
+
createVNode(SmartPopup, {
|
|
41315
|
+
visible: showPopup.value,
|
|
41316
|
+
"onUpdate:visible": _cache[3] || (_cache[3] = ($event) => showPopup.value = $event),
|
|
41317
|
+
trigger: triggerRef.value,
|
|
41318
|
+
gap: 12
|
|
41319
|
+
}, {
|
|
41320
|
+
default: withCtx(() => [
|
|
41321
|
+
createElementVNode("div", _hoisted_4$j, [
|
|
41322
|
+
createElementVNode("div", {
|
|
41323
|
+
class: normalizeClass(["network-quality-popup network-quality-main", themeClass.value])
|
|
41324
|
+
}, [
|
|
41325
|
+
createElementVNode("div", _hoisted_5$g, [
|
|
41326
|
+
_cache[4] || (_cache[4] = createElementVNode("div", { class: "popup-title" }, "网络详情", -1)),
|
|
41327
|
+
createElementVNode("div", _hoisted_6$f, [
|
|
41328
|
+
createElementVNode("button", {
|
|
41329
|
+
type: "button",
|
|
41330
|
+
class: "advanced-toggle",
|
|
41331
|
+
onClick: _cache[1] || (_cache[1] = withModifiers(($event) => advancedOpen.value = !advancedOpen.value, ["stop"]))
|
|
41332
|
+
}, toDisplayString(advancedOpen.value ? "关闭高级模式" : "打开高级模式"), 1),
|
|
41333
|
+
createElementVNode("div", {
|
|
41334
|
+
class: normalizeClass(["popup-status", `is-${unref(networkQualityState).level}`])
|
|
41335
|
+
}, toDisplayString(unref(networkQualityState).label), 3)
|
|
41340
41336
|
])
|
|
41341
|
-
])
|
|
41342
|
-
|
|
41343
|
-
|
|
41344
|
-
createElementVNode("
|
|
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
|
-
|
|
41373
|
-
|
|
41374
|
-
|
|
41375
|
-
|
|
41376
|
-
|
|
41377
|
-
|
|
41378
|
-
|
|
41379
|
-
|
|
41380
|
-
|
|
41337
|
+
]),
|
|
41338
|
+
createElementVNode("div", _hoisted_7$e, toDisplayString(unref(networkQualityState).summary), 1),
|
|
41339
|
+
reasonText.value ? (openBlock(), createElementBlock("div", _hoisted_8$d, toDisplayString(reasonText.value), 1)) : createCommentVNode("", true),
|
|
41340
|
+
createElementVNode("div", _hoisted_9$b, [
|
|
41341
|
+
_cache[5] || (_cache[5] = createElementVNode("div", { class: "popup-section-title" }, "质量概览", -1)),
|
|
41342
|
+
createElementVNode("div", _hoisted_10$b, [
|
|
41343
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(qualityItems.value, (item) => {
|
|
41344
|
+
return openBlock(), createElementBlock("div", {
|
|
41345
|
+
key: item.label,
|
|
41346
|
+
class: "popup-item"
|
|
41347
|
+
}, [
|
|
41348
|
+
createElementVNode("div", _hoisted_11$a, toDisplayString(item.label), 1),
|
|
41349
|
+
createElementVNode("div", _hoisted_12$a, toDisplayString(item.value), 1)
|
|
41350
|
+
]);
|
|
41351
|
+
}), 128))
|
|
41352
|
+
])
|
|
41353
|
+
]),
|
|
41354
|
+
createElementVNode("div", _hoisted_13$8, [
|
|
41355
|
+
_cache[6] || (_cache[6] = createElementVNode("div", { class: "popup-section-title" }, "网络指标", -1)),
|
|
41356
|
+
createElementVNode("div", _hoisted_14$7, [
|
|
41357
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(overviewItems.value, (item) => {
|
|
41358
|
+
return openBlock(), createElementBlock("div", {
|
|
41359
|
+
key: item.label,
|
|
41360
|
+
class: "popup-item"
|
|
41361
|
+
}, [
|
|
41362
|
+
createElementVNode("div", _hoisted_15$6, toDisplayString(item.label), 1),
|
|
41363
|
+
createElementVNode("div", _hoisted_16$6, toDisplayString(item.value), 1)
|
|
41364
|
+
]);
|
|
41365
|
+
}), 128))
|
|
41366
|
+
])
|
|
41367
|
+
])
|
|
41368
|
+
], 2),
|
|
41369
|
+
advancedOpen.value ? (openBlock(), createElementBlock("div", {
|
|
41370
|
+
key: 0,
|
|
41371
|
+
class: normalizeClass(["network-quality-popup network-quality-advanced", themeClass.value]),
|
|
41372
|
+
onClick: _cache[2] || (_cache[2] = withModifiers(() => {
|
|
41373
|
+
}, ["stop"]))
|
|
41374
|
+
}, [
|
|
41375
|
+
createElementVNode("div", _hoisted_17$5, [
|
|
41376
|
+
_cache[7] || (_cache[7] = createElementVNode("div", { class: "popup-title" }, "高级模式", -1)),
|
|
41377
|
+
createElementVNode("div", _hoisted_18$5, [
|
|
41378
|
+
createElementVNode("button", {
|
|
41379
|
+
type: "button",
|
|
41380
|
+
class: "advanced-mini-btn",
|
|
41381
|
+
onClick: toggleAllSections
|
|
41382
|
+
}, toDisplayString(allSectionsExpanded.value ? "全部收起" : "全部展开"), 1)
|
|
41383
|
+
])
|
|
41384
|
+
]),
|
|
41385
|
+
createElementVNode("div", _hoisted_19$5, [
|
|
41386
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(detailSections.value, (section) => {
|
|
41387
|
+
return openBlock(), createElementBlock("div", {
|
|
41388
|
+
key: section.key,
|
|
41389
|
+
class: "popup-section"
|
|
41390
|
+
}, [
|
|
41381
41391
|
createElementVNode("button", {
|
|
41382
41392
|
type: "button",
|
|
41383
|
-
class: "
|
|
41384
|
-
|
|
41385
|
-
|
|
41386
|
-
|
|
41387
|
-
|
|
41388
|
-
|
|
41389
|
-
|
|
41390
|
-
|
|
41391
|
-
|
|
41392
|
-
|
|
41393
|
-
|
|
41394
|
-
|
|
41395
|
-
|
|
41396
|
-
|
|
41397
|
-
|
|
41398
|
-
|
|
41399
|
-
|
|
41400
|
-
|
|
41401
|
-
|
|
41402
|
-
|
|
41403
|
-
|
|
41404
|
-
|
|
41405
|
-
|
|
41406
|
-
|
|
41407
|
-
|
|
41408
|
-
|
|
41409
|
-
|
|
41410
|
-
|
|
41411
|
-
|
|
41412
|
-
|
|
41413
|
-
|
|
41414
|
-
|
|
41415
|
-
|
|
41416
|
-
|
|
41417
|
-
|
|
41418
|
-
|
|
41419
|
-
|
|
41420
|
-
createElementVNode("div", {
|
|
41421
|
-
class: normalizeClass(["device-dropdown-trigger", { "is-disabled": unref(micOperationBusy) }]),
|
|
41422
|
-
onClick: _cache[1] || (_cache[1] = ($event) => toggleDeviceSelector("microphone"))
|
|
41423
|
-
}, [
|
|
41424
|
-
createVNode(SvgIcon, {
|
|
41425
|
-
name: "TriangleIcon",
|
|
41426
|
-
size: 9
|
|
41427
|
-
})
|
|
41428
|
-
], 2)
|
|
41429
|
-
], 512)) : createCommentVNode("", true),
|
|
41430
|
-
isReceiving.value ? (openBlock(), createElementBlock("button", {
|
|
41431
|
-
key: 1,
|
|
41432
|
-
class: "accept-call-btn",
|
|
41433
|
-
onClick: acceptCall
|
|
41434
|
-
}, [
|
|
41435
|
-
createVNode(SvgIcon, {
|
|
41436
|
-
name: "PhoneIcon",
|
|
41437
|
-
size: 21
|
|
41438
|
-
}),
|
|
41439
|
-
_cache[10] || (_cache[10] = createElementVNode("span", null, "接听", -1))
|
|
41440
|
-
])) : createCommentVNode("", true),
|
|
41441
|
-
isCalling.value || isReceiving.value || isConnected.value ? (openBlock(), createElementBlock("button", {
|
|
41442
|
-
key: 2,
|
|
41443
|
-
class: "end-call-btn",
|
|
41444
|
-
onClick: endCall
|
|
41445
|
-
}, [
|
|
41446
|
-
createVNode(SvgIcon, {
|
|
41447
|
-
name: "HandUpIcon",
|
|
41448
|
-
size: 21,
|
|
41449
|
-
"color-class": "handUp"
|
|
41450
|
-
}),
|
|
41451
|
-
createElementVNode("span", null, toDisplayString(isReceiving.value ? "拒绝" : "挂断"), 1)
|
|
41452
|
-
])) : createCommentVNode("", true),
|
|
41453
|
-
isListening.value ? (openBlock(), createElementBlock("button", {
|
|
41454
|
-
key: 3,
|
|
41455
|
-
class: "end-call-btn",
|
|
41456
|
-
onClick: stopMonitoring
|
|
41457
|
-
}, [
|
|
41458
|
-
createVNode(SvgIcon, {
|
|
41459
|
-
name: "HandUpIcon",
|
|
41460
|
-
size: 21,
|
|
41461
|
-
"color-class": "handUp"
|
|
41462
|
-
}),
|
|
41463
|
-
_cache[11] || (_cache[11] = createElementVNode("span", null, "结束监听", -1))
|
|
41464
|
-
])) : createCommentVNode("", true),
|
|
41465
|
-
isForcibleInsertion.value ? (openBlock(), createElementBlock("button", {
|
|
41466
|
-
key: 4,
|
|
41467
|
-
class: "end-call-btn",
|
|
41468
|
-
onClick: stopMonitoring
|
|
41469
|
-
}, [
|
|
41470
|
-
createVNode(SvgIcon, {
|
|
41471
|
-
name: "HandUpIcon",
|
|
41472
|
-
size: 20
|
|
41473
|
-
}),
|
|
41474
|
-
_cache[12] || (_cache[12] = createElementVNode("span", null, "退出通话", -1))
|
|
41475
|
-
])) : createCommentVNode("", true),
|
|
41476
|
-
isConnected.value || isForcibleInsertion.value ? (openBlock(), createElementBlock("div", {
|
|
41477
|
-
key: 5,
|
|
41478
|
-
ref_key: "cameraRef",
|
|
41479
|
-
ref: cameraRef
|
|
41480
|
-
}, [
|
|
41481
|
-
createElementVNode("button", {
|
|
41482
|
-
class: normalizeClass(["control-btn", { "is-disabled": unref(cameraOperationBusy) }]),
|
|
41483
|
-
onClick: _cache[2] || (_cache[2] = ($event) => onChange(unref(RoomModalSelectType).cameraClick))
|
|
41484
|
-
}, [
|
|
41485
|
-
createVNode(SvgIcon, {
|
|
41486
|
-
name: unref(meState2).cameraState == "1" ? "CameraIcon" : "CameraSlashIcon",
|
|
41487
|
-
size: 20
|
|
41488
|
-
}, null, 8, ["name"]),
|
|
41489
|
-
_cache[13] || (_cache[13] = createElementVNode("span", null, "摄像头", -1))
|
|
41490
|
-
], 2),
|
|
41491
|
-
createElementVNode("div", {
|
|
41492
|
-
class: normalizeClass(["device-dropdown-trigger", { "is-disabled": unref(cameraOperationBusy) }]),
|
|
41493
|
-
onClick: _cache[3] || (_cache[3] = ($event) => toggleDeviceSelector("camera"))
|
|
41494
|
-
}, [
|
|
41495
|
-
createVNode(SvgIcon, {
|
|
41496
|
-
name: "TriangleIcon",
|
|
41497
|
-
size: 9
|
|
41498
|
-
})
|
|
41499
|
-
], 2)
|
|
41500
|
-
], 512)) : createCommentVNode("", true)
|
|
41501
|
-
]),
|
|
41502
|
-
isConnected.value ? (openBlock(), createElementBlock("div", _hoisted_28$3, [
|
|
41503
|
-
createVNode(SvgIcon, {
|
|
41504
|
-
name: "TranscribeIcon",
|
|
41505
|
-
size: 22
|
|
41506
|
-
}),
|
|
41507
|
-
_cache[14] || (_cache[14] = createElementVNode("span", null, "录制中", -1))
|
|
41508
|
-
])) : createCommentVNode("", true)
|
|
41393
|
+
class: normalizeClass(["detail-section-toggle", { collapsed: isSectionCollapsed(section.key) }]),
|
|
41394
|
+
onClick: ($event) => toggleSection(section.key)
|
|
41395
|
+
}, [
|
|
41396
|
+
createElementVNode("span", _hoisted_21$3, [
|
|
41397
|
+
createElementVNode("span", _hoisted_22$3, toDisplayString(section.title), 1),
|
|
41398
|
+
createElementVNode("span", _hoisted_23$3, "(" + toDisplayString(section.cards.length) + ")", 1)
|
|
41399
|
+
]),
|
|
41400
|
+
createElementVNode("span", _hoisted_24$3, toDisplayString(isSectionCollapsed(section.key) ? "展开" : "收起"), 1)
|
|
41401
|
+
], 10, _hoisted_20$5),
|
|
41402
|
+
!isSectionCollapsed(section.key) && section.cards.length ? (openBlock(), createElementBlock("div", _hoisted_25$3, [
|
|
41403
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(section.cards, (card) => {
|
|
41404
|
+
return openBlock(), createElementBlock("div", {
|
|
41405
|
+
key: card.title,
|
|
41406
|
+
class: "metric-card"
|
|
41407
|
+
}, [
|
|
41408
|
+
createElementVNode("div", _hoisted_26$3, [
|
|
41409
|
+
createElementVNode("div", _hoisted_27$3, toDisplayString(card.title), 1),
|
|
41410
|
+
createElementVNode("div", _hoisted_28$3, toDisplayString(card.subtitle), 1)
|
|
41411
|
+
]),
|
|
41412
|
+
createElementVNode("div", _hoisted_29$2, [
|
|
41413
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(card.items, (item) => {
|
|
41414
|
+
return openBlock(), createElementBlock("div", {
|
|
41415
|
+
key: `${card.title}-${item.label}`,
|
|
41416
|
+
class: "metric-card-item"
|
|
41417
|
+
}, [
|
|
41418
|
+
createElementVNode("div", _hoisted_30$2, toDisplayString(item.label), 1),
|
|
41419
|
+
createElementVNode("div", _hoisted_31$1, toDisplayString(item.value), 1)
|
|
41420
|
+
]);
|
|
41421
|
+
}), 128))
|
|
41422
|
+
])
|
|
41423
|
+
]);
|
|
41424
|
+
}), 128))
|
|
41425
|
+
])) : !isSectionCollapsed(section.key) ? (openBlock(), createElementBlock("div", _hoisted_32$1, "暂无数据")) : createCommentVNode("", true)
|
|
41426
|
+
]);
|
|
41427
|
+
}), 128))
|
|
41428
|
+
])
|
|
41429
|
+
], 2)) : createCommentVNode("", true)
|
|
41509
41430
|
])
|
|
41510
41431
|
]),
|
|
41511
|
-
|
|
41512
|
-
|
|
41513
|
-
|
|
41514
|
-
trigger: currentDeviceType.value == "microphone" ? micRef.value : cameraRef.value,
|
|
41515
|
-
gap: 10
|
|
41516
|
-
}, {
|
|
41517
|
-
default: withCtx(() => [
|
|
41518
|
-
createVNode(DeviceSelector, {
|
|
41519
|
-
"device-type": currentDeviceType.value,
|
|
41520
|
-
theme: _ctx.theme,
|
|
41521
|
-
onClose: _cache[4] || (_cache[4] = ($event) => showDeviceSelector.value = false)
|
|
41522
|
-
}, null, 8, ["device-type", "theme"])
|
|
41523
|
-
]),
|
|
41524
|
-
_: 1
|
|
41525
|
-
}, 8, ["visible", "trigger"])
|
|
41526
|
-
], 2)) : createCommentVNode("", true)
|
|
41527
|
-
]);
|
|
41432
|
+
_: 1
|
|
41433
|
+
}, 8, ["visible", "trigger"])
|
|
41434
|
+
], 2);
|
|
41528
41435
|
};
|
|
41529
41436
|
}
|
|
41530
41437
|
});
|
|
41531
|
-
const
|
|
41532
|
-
const
|
|
41533
|
-
const
|
|
41534
|
-
|
|
41535
|
-
|
|
41536
|
-
|
|
41537
|
-
|
|
41538
|
-
|
|
41539
|
-
const
|
|
41540
|
-
const
|
|
41541
|
-
const
|
|
41542
|
-
|
|
41543
|
-
|
|
41544
|
-
|
|
41545
|
-
|
|
41546
|
-
|
|
41547
|
-
|
|
41548
|
-
|
|
41549
|
-
|
|
41550
|
-
|
|
41551
|
-
|
|
41552
|
-
|
|
41553
|
-
|
|
41554
|
-
|
|
41555
|
-
|
|
41556
|
-
|
|
41557
|
-
|
|
41558
|
-
|
|
41559
|
-
|
|
41560
|
-
|
|
41561
|
-
try {
|
|
41562
|
-
localStorage.setItem(key, value);
|
|
41563
|
-
} catch {
|
|
41564
|
-
}
|
|
41565
|
-
}
|
|
41566
|
-
function safeLocalStorageGetItem(key) {
|
|
41567
|
-
try {
|
|
41568
|
-
return localStorage.getItem(key);
|
|
41569
|
-
} catch {
|
|
41570
|
-
return null;
|
|
41571
|
-
}
|
|
41572
|
-
}
|
|
41573
|
-
function getMeetingMqttHandoffContext() {
|
|
41574
|
-
const sourceTabId = safeSessionStorageGetItem(HANDOFF_SOURCE_TAB_ID_KEY) || "";
|
|
41575
|
-
const targetTabId = safeSessionStorageGetItem(HANDOFF_TARGET_TAB_ID_KEY) || "";
|
|
41576
|
-
const handoffId = safeSessionStorageGetItem(HANDOFF_ID_KEY) || "";
|
|
41577
|
-
if (!sourceTabId || !targetTabId || !handoffId) {
|
|
41578
|
-
return null;
|
|
41579
|
-
}
|
|
41580
|
-
return {
|
|
41581
|
-
sourceTabId,
|
|
41582
|
-
targetTabId,
|
|
41583
|
-
handoffId
|
|
41584
|
-
};
|
|
41585
|
-
}
|
|
41586
|
-
function readTargetHeartbeat() {
|
|
41587
|
-
const raw = safeLocalStorageGetItem(TARGET_HEARTBEAT_KEY);
|
|
41588
|
-
if (!raw) {
|
|
41589
|
-
return null;
|
|
41590
|
-
}
|
|
41591
|
-
try {
|
|
41592
|
-
const parsed = JSON.parse(raw);
|
|
41593
|
-
if (!(parsed == null ? void 0 : parsed.targetTabId) || !(parsed == null ? void 0 : parsed.handoffId) || !(parsed == null ? void 0 : parsed.ts)) {
|
|
41594
|
-
return null;
|
|
41595
|
-
}
|
|
41596
|
-
return {
|
|
41597
|
-
targetTabId: parsed.targetTabId,
|
|
41598
|
-
handoffId: parsed.handoffId,
|
|
41599
|
-
ts: Number(parsed.ts)
|
|
41438
|
+
const NetworkQualitySignal = /* @__PURE__ */ _export_sfc(_sfc_main$q, [["__scopeId", "data-v-3378006f"]]);
|
|
41439
|
+
const _hoisted_1$n = { class: "network-copy" };
|
|
41440
|
+
const _sfc_main$p = /* @__PURE__ */ defineComponent({
|
|
41441
|
+
__name: "netWorkStatus",
|
|
41442
|
+
props: {
|
|
41443
|
+
theme: { default: "dark" }
|
|
41444
|
+
},
|
|
41445
|
+
setup(__props) {
|
|
41446
|
+
const props = __props;
|
|
41447
|
+
const themeClass = computed(() => `theme-${props.theme}`);
|
|
41448
|
+
const displayLabel = computed(() => {
|
|
41449
|
+
if (networkQualityState.isStale) {
|
|
41450
|
+
return "网络检测中";
|
|
41451
|
+
}
|
|
41452
|
+
return networkQualityState.label;
|
|
41453
|
+
});
|
|
41454
|
+
return (_ctx, _cache) => {
|
|
41455
|
+
return openBlock(), createElementBlock("div", {
|
|
41456
|
+
class: normalizeClass(["network-situation", themeClass.value])
|
|
41457
|
+
}, [
|
|
41458
|
+
createVNode(NetworkQualitySignal, {
|
|
41459
|
+
theme: _ctx.theme,
|
|
41460
|
+
size: "compact"
|
|
41461
|
+
}, null, 8, ["theme"]),
|
|
41462
|
+
createElementVNode("div", _hoisted_1$n, [
|
|
41463
|
+
createElementVNode("span", {
|
|
41464
|
+
class: normalizeClass(["network-label", `is-${unref(networkQualityState).level}`])
|
|
41465
|
+
}, toDisplayString(displayLabel.value), 3)
|
|
41466
|
+
])
|
|
41467
|
+
], 2);
|
|
41600
41468
|
};
|
|
41601
|
-
} catch {
|
|
41602
|
-
return null;
|
|
41603
|
-
}
|
|
41604
|
-
}
|
|
41605
|
-
function writeTargetHeartbeat(context) {
|
|
41606
|
-
safeLocalStorageSetItem(
|
|
41607
|
-
TARGET_HEARTBEAT_KEY,
|
|
41608
|
-
JSON.stringify({
|
|
41609
|
-
targetTabId: context.targetTabId,
|
|
41610
|
-
handoffId: context.handoffId,
|
|
41611
|
-
ts: Date.now()
|
|
41612
|
-
})
|
|
41613
|
-
);
|
|
41614
|
-
}
|
|
41615
|
-
function writeTargetTabStatus(status, context) {
|
|
41616
|
-
safeLocalStorageSetItem(
|
|
41617
|
-
TARGET_TAB_STATUS_KEY,
|
|
41618
|
-
JSON.stringify({
|
|
41619
|
-
sourceTabId: context.sourceTabId,
|
|
41620
|
-
targetTabId: context.targetTabId,
|
|
41621
|
-
handoffId: context.handoffId,
|
|
41622
|
-
status,
|
|
41623
|
-
ts: Date.now()
|
|
41624
|
-
})
|
|
41625
|
-
);
|
|
41626
|
-
}
|
|
41627
|
-
function sendReconnectSignal(context) {
|
|
41628
|
-
if (closeSignalSent) {
|
|
41629
|
-
return;
|
|
41630
41469
|
}
|
|
41631
|
-
|
|
41632
|
-
|
|
41633
|
-
|
|
41634
|
-
|
|
41635
|
-
|
|
41636
|
-
|
|
41637
|
-
|
|
41638
|
-
|
|
41639
|
-
|
|
41640
|
-
|
|
41641
|
-
|
|
41642
|
-
|
|
41643
|
-
|
|
41644
|
-
}
|
|
41645
|
-
|
|
41646
|
-
|
|
41647
|
-
|
|
41648
|
-
|
|
41649
|
-
|
|
41650
|
-
}
|
|
41651
|
-
|
|
41652
|
-
|
|
41653
|
-
|
|
41654
|
-
|
|
41655
|
-
|
|
41656
|
-
|
|
41657
|
-
|
|
41658
|
-
|
|
41659
|
-
|
|
41660
|
-
|
|
41661
|
-
|
|
41662
|
-
|
|
41663
|
-
|
|
41664
|
-
|
|
41665
|
-
|
|
41666
|
-
|
|
41667
|
-
|
|
41668
|
-
|
|
41669
|
-
|
|
41670
|
-
|
|
41671
|
-
|
|
41672
|
-
|
|
41673
|
-
|
|
41674
|
-
|
|
41675
|
-
|
|
41676
|
-
|
|
41677
|
-
|
|
41678
|
-
|
|
41679
|
-
|
|
41680
|
-
|
|
41470
|
+
});
|
|
41471
|
+
const NetWorkStatus = /* @__PURE__ */ _export_sfc(_sfc_main$p, [["__scopeId", "data-v-565d8abd"]]);
|
|
41472
|
+
const _hoisted_1$m = {
|
|
41473
|
+
key: 0,
|
|
41474
|
+
class: "sos-flash-overlay"
|
|
41475
|
+
};
|
|
41476
|
+
const _hoisted_2$l = { class: "js-call-dialog-container" };
|
|
41477
|
+
const _hoisted_3$k = { class: "status-bar" };
|
|
41478
|
+
const _hoisted_4$i = { class: "status-left" };
|
|
41479
|
+
const _hoisted_5$f = {
|
|
41480
|
+
key: 0,
|
|
41481
|
+
class: "caller-info",
|
|
41482
|
+
title: "来电人"
|
|
41483
|
+
};
|
|
41484
|
+
const _hoisted_6$e = {
|
|
41485
|
+
class: "avatar",
|
|
41486
|
+
style: { "width": "35px", "height": "35px", "font-size": "16px" }
|
|
41487
|
+
};
|
|
41488
|
+
const _hoisted_7$d = { class: "caller-text" };
|
|
41489
|
+
const _hoisted_8$c = { class: "caller-name" };
|
|
41490
|
+
const _hoisted_9$a = {
|
|
41491
|
+
key: 0,
|
|
41492
|
+
class: "caller-number"
|
|
41493
|
+
};
|
|
41494
|
+
const _hoisted_10$a = { class: "status-right" };
|
|
41495
|
+
const _hoisted_11$9 = ["onClick"];
|
|
41496
|
+
const _hoisted_12$9 = { class: "video-wrapper" };
|
|
41497
|
+
const _hoisted_13$7 = ["id"];
|
|
41498
|
+
const _hoisted_14$6 = { class: "avatar-container" };
|
|
41499
|
+
const _hoisted_15$5 = { class: "avatar" };
|
|
41500
|
+
const _hoisted_16$5 = { class: "video-loading-overlay" };
|
|
41501
|
+
const _hoisted_17$4 = { class: "video-loading-text" };
|
|
41502
|
+
const _hoisted_18$4 = { class: "video-loading-overlay failed" };
|
|
41503
|
+
const _hoisted_19$4 = ["disabled", "onClick"];
|
|
41504
|
+
const _hoisted_20$4 = { class: "video-meta" };
|
|
41505
|
+
const _hoisted_21$2 = { class: "member-name" };
|
|
41506
|
+
const _hoisted_22$2 = {
|
|
41507
|
+
key: 0,
|
|
41508
|
+
class: "role-tag"
|
|
41509
|
+
};
|
|
41510
|
+
const _hoisted_23$2 = {
|
|
41511
|
+
key: 1,
|
|
41512
|
+
class: "video-empty"
|
|
41513
|
+
};
|
|
41514
|
+
const _hoisted_24$2 = { class: "control-bar" };
|
|
41515
|
+
const _hoisted_25$2 = {
|
|
41516
|
+
key: 0,
|
|
41517
|
+
class: "call-duration"
|
|
41518
|
+
};
|
|
41519
|
+
const _hoisted_26$2 = { id: "duration" };
|
|
41520
|
+
const _hoisted_27$2 = { class: "control-buttons" };
|
|
41521
|
+
const _hoisted_28$2 = {
|
|
41522
|
+
key: 1,
|
|
41523
|
+
class: "recording-button"
|
|
41524
|
+
};
|
|
41525
|
+
const DEFAULT_SUB_VIDEO_HEIGHT = 110;
|
|
41526
|
+
const DEFAULT_SUB_VIDEO_WIDTH = 190;
|
|
41527
|
+
const SUB_VIDEO_GAP = 12;
|
|
41528
|
+
const CONTROL_BAR_HEIGHT = 90;
|
|
41529
|
+
const STATUS_BAR_HEIGHT = 48;
|
|
41530
|
+
const _sfc_main$o = /* @__PURE__ */ defineComponent({
|
|
41531
|
+
__name: "call",
|
|
41532
|
+
props: {
|
|
41533
|
+
theme: { default: "dark" },
|
|
41534
|
+
draggable: { type: Boolean, default: false },
|
|
41535
|
+
taskId: {}
|
|
41536
|
+
},
|
|
41537
|
+
setup(__props) {
|
|
41538
|
+
const { meState: meState2 } = storeToRefs(useMeetingStore());
|
|
41539
|
+
const props = __props;
|
|
41540
|
+
const visible = callVisible;
|
|
41541
|
+
const themeClass = computed(() => `theme-${props.theme}`);
|
|
41542
|
+
const showDeviceSelector = ref(false);
|
|
41543
|
+
const currentDeviceType = ref("microphone");
|
|
41544
|
+
const micRef = ref(null);
|
|
41545
|
+
const cameraRef = ref(null);
|
|
41546
|
+
const joinTimeObj = ref("");
|
|
41547
|
+
let timer = null;
|
|
41548
|
+
watch(
|
|
41549
|
+
() => joinTime.value,
|
|
41550
|
+
() => {
|
|
41551
|
+
if (timer) {
|
|
41552
|
+
clearInterval(timer);
|
|
41553
|
+
timer = null;
|
|
41554
|
+
}
|
|
41555
|
+
if (joinTime.value) {
|
|
41556
|
+
timer = setInterval(() => {
|
|
41557
|
+
const now = +/* @__PURE__ */ new Date();
|
|
41558
|
+
joinTimeObj.value = formatDuringObject((now - joinTime.value) / 1e3);
|
|
41559
|
+
}, 1e3);
|
|
41560
|
+
}
|
|
41561
|
+
},
|
|
41562
|
+
{
|
|
41563
|
+
immediate: true
|
|
41564
|
+
}
|
|
41565
|
+
);
|
|
41566
|
+
const isCalling = computed(() => callStatus.value === "calling");
|
|
41567
|
+
const isReceiving = computed(() => callStatus.value === "receiving");
|
|
41568
|
+
const isConnected = computed(() => callStatus.value === "connected");
|
|
41569
|
+
const isListening = computed(() => callStatus.value === "listening");
|
|
41570
|
+
const isForcibleInsertion = computed(
|
|
41571
|
+
() => callStatus.value === "forcible-insertion"
|
|
41572
|
+
);
|
|
41573
|
+
const visibleMembers = computed(() => {
|
|
41574
|
+
return members.value.filter(
|
|
41575
|
+
(item) => item.roleType !== "4" && item.joinStaus === "1" && (!isListening.value || item.member.memberId !== getUserId())
|
|
41576
|
+
);
|
|
41577
|
+
});
|
|
41578
|
+
const hasForceInsertMember = computed(
|
|
41579
|
+
() => visibleMembers.value.some((item) => item.roleType === "1")
|
|
41580
|
+
);
|
|
41581
|
+
const layoutClass = computed(() => {
|
|
41582
|
+
if (visibleMembers.value.length <= 1) return "layout-single";
|
|
41583
|
+
if (hasForceInsertMember.value) return "layout-three";
|
|
41584
|
+
return "layout-two";
|
|
41585
|
+
});
|
|
41586
|
+
const mainMemberId = ref("");
|
|
41587
|
+
const pickDefaultMainMember = (list) => {
|
|
41588
|
+
if (!list.length) {
|
|
41589
|
+
return "";
|
|
41590
|
+
}
|
|
41591
|
+
const remoteMember = list.find(
|
|
41592
|
+
(item) => item.member.memberId !== getUserId()
|
|
41593
|
+
);
|
|
41594
|
+
return (remoteMember || list[0]).member.memberId;
|
|
41595
|
+
};
|
|
41596
|
+
watch(
|
|
41597
|
+
visibleMembers,
|
|
41598
|
+
(list) => {
|
|
41599
|
+
if (!list.length) {
|
|
41600
|
+
mainMemberId.value = "";
|
|
41601
|
+
return;
|
|
41602
|
+
}
|
|
41603
|
+
const exists = list.some(
|
|
41604
|
+
(item) => item.member.memberId === mainMemberId.value
|
|
41605
|
+
);
|
|
41606
|
+
if (!exists) {
|
|
41607
|
+
mainMemberId.value = pickDefaultMainMember(list);
|
|
41608
|
+
}
|
|
41609
|
+
},
|
|
41610
|
+
{ immediate: true, deep: true }
|
|
41611
|
+
);
|
|
41612
|
+
const mainMember = computed(() => {
|
|
41613
|
+
if (!visibleMembers.value.length) return null;
|
|
41614
|
+
if (!mainMemberId.value) {
|
|
41615
|
+
return visibleMembers.value[0];
|
|
41616
|
+
}
|
|
41617
|
+
return visibleMembers.value.find(
|
|
41618
|
+
(item) => item.member.memberId === mainMemberId.value
|
|
41619
|
+
) || visibleMembers.value[0];
|
|
41620
|
+
});
|
|
41621
|
+
const secondaryMembers = computed(() => {
|
|
41622
|
+
if (!mainMember.value) return [];
|
|
41623
|
+
return visibleMembers.value.filter(
|
|
41624
|
+
(item) => {
|
|
41625
|
+
var _a25;
|
|
41626
|
+
return item.member.memberId !== ((_a25 = mainMember.value) == null ? void 0 : _a25.member.memberId);
|
|
41627
|
+
}
|
|
41628
|
+
);
|
|
41629
|
+
});
|
|
41630
|
+
const subVideoPositions = computed(() => {
|
|
41631
|
+
const positions = {};
|
|
41632
|
+
secondaryMembers.value.forEach((member, index) => {
|
|
41633
|
+
positions[member.member.memberId] = {
|
|
41634
|
+
position: "absolute",
|
|
41635
|
+
width: `${DEFAULT_SUB_VIDEO_WIDTH}px`,
|
|
41636
|
+
height: `${DEFAULT_SUB_VIDEO_HEIGHT}px`,
|
|
41637
|
+
right: "16px",
|
|
41638
|
+
top: `${STATUS_BAR_HEIGHT + 16 + index * (DEFAULT_SUB_VIDEO_HEIGHT + SUB_VIDEO_GAP)}px`
|
|
41639
|
+
};
|
|
41640
|
+
});
|
|
41641
|
+
return positions;
|
|
41642
|
+
});
|
|
41643
|
+
const getVideoItemStyle = (memberId) => {
|
|
41644
|
+
var _a25;
|
|
41645
|
+
if (memberId === ((_a25 = mainMember.value) == null ? void 0 : _a25.member.memberId)) {
|
|
41646
|
+
return {
|
|
41647
|
+
position: "absolute",
|
|
41648
|
+
top: `${STATUS_BAR_HEIGHT}px`,
|
|
41649
|
+
right: "0px",
|
|
41650
|
+
left: "0px",
|
|
41651
|
+
bottom: `${CONTROL_BAR_HEIGHT}px`
|
|
41652
|
+
};
|
|
41653
|
+
}
|
|
41654
|
+
return subVideoPositions.value[memberId] || {};
|
|
41655
|
+
};
|
|
41656
|
+
const handleSwitchMain = (memberId) => {
|
|
41657
|
+
if (memberId === mainMemberId.value) return;
|
|
41658
|
+
mainMemberId.value = memberId;
|
|
41659
|
+
};
|
|
41660
|
+
watch(
|
|
41661
|
+
() => {
|
|
41662
|
+
var _a25;
|
|
41663
|
+
return ((_a25 = mainMember.value) == null ? void 0 : _a25.member.memberId) || "";
|
|
41664
|
+
},
|
|
41665
|
+
(memberId) => {
|
|
41666
|
+
const focusUid = memberId && memberId !== getUserId() ? memberId : null;
|
|
41667
|
+
void setPreferredRemoteVideoFocus(focusUid);
|
|
41668
|
+
},
|
|
41669
|
+
{ immediate: true }
|
|
41670
|
+
);
|
|
41671
|
+
const handleRetryVideo = async (user) => {
|
|
41672
|
+
var _a25;
|
|
41673
|
+
const memberId = (_a25 = user == null ? void 0 : user.member) == null ? void 0 : _a25.memberId;
|
|
41674
|
+
if (!memberId || memberId === getUserId() || (user == null ? void 0 : user.videoRetrying)) return;
|
|
41675
|
+
await retryRemoteVideoSubscription(memberId);
|
|
41676
|
+
};
|
|
41677
|
+
const statusText = computed(() => {
|
|
41678
|
+
switch (callStatus.value) {
|
|
41679
|
+
case "calling":
|
|
41680
|
+
return "正在呼叫";
|
|
41681
|
+
case "receiving":
|
|
41682
|
+
return "正在接收呼叫";
|
|
41683
|
+
case "connected":
|
|
41684
|
+
return "通话中";
|
|
41685
|
+
case "listening":
|
|
41686
|
+
return "正在监听";
|
|
41687
|
+
case "end":
|
|
41688
|
+
return "通话结束";
|
|
41689
|
+
default:
|
|
41690
|
+
return "通话中";
|
|
41691
|
+
}
|
|
41692
|
+
});
|
|
41693
|
+
const callerInfo = ref({});
|
|
41694
|
+
watch(
|
|
41695
|
+
() => callStatus.value,
|
|
41696
|
+
() => {
|
|
41697
|
+
try {
|
|
41698
|
+
const info = JSON.parse(
|
|
41699
|
+
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41700
|
+
);
|
|
41701
|
+
callerInfo.value = info || {};
|
|
41702
|
+
} catch {
|
|
41703
|
+
callerInfo.value = {};
|
|
41704
|
+
}
|
|
41705
|
+
},
|
|
41706
|
+
{ immediate: true }
|
|
41707
|
+
);
|
|
41708
|
+
const onChange = async (type) => {
|
|
41709
|
+
switch (type) {
|
|
41710
|
+
case RoomModalSelectType.microphoneClick:
|
|
41711
|
+
if (micOperationBusy.value) return;
|
|
41712
|
+
if (isAuthority.value) {
|
|
41713
|
+
showNotification(alertMsg, "warning", 5e3);
|
|
41714
|
+
return;
|
|
41715
|
+
}
|
|
41716
|
+
if (meState2.value.microPhoneState === "1") {
|
|
41717
|
+
await closeMic();
|
|
41718
|
+
} else {
|
|
41719
|
+
await openMic();
|
|
41720
|
+
}
|
|
41721
|
+
break;
|
|
41722
|
+
case RoomModalSelectType.cameraClick:
|
|
41723
|
+
if (cameraOperationBusy.value) return;
|
|
41724
|
+
if (isAuthority.value) {
|
|
41725
|
+
alert(alertMsg);
|
|
41726
|
+
return;
|
|
41727
|
+
}
|
|
41728
|
+
if (meState2.value.cameraState === "1") {
|
|
41729
|
+
await closeCamera();
|
|
41730
|
+
} else {
|
|
41731
|
+
await openCamera();
|
|
41732
|
+
}
|
|
41733
|
+
break;
|
|
41734
|
+
case RoomModalSelectType.acceptClick:
|
|
41735
|
+
acceptCall();
|
|
41736
|
+
break;
|
|
41737
|
+
case RoomModalSelectType.endClick:
|
|
41738
|
+
endCall();
|
|
41739
|
+
break;
|
|
41740
|
+
}
|
|
41741
|
+
};
|
|
41742
|
+
const acceptCall = () => {
|
|
41743
|
+
const meetingInfo = JSON.parse(
|
|
41744
|
+
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41745
|
+
);
|
|
41746
|
+
setCallStatus("connected");
|
|
41747
|
+
stopSosFlash();
|
|
41748
|
+
getAnswerCall({
|
|
41749
|
+
meetingId: meetingInfo.meetingId,
|
|
41750
|
+
memberId: getUserId(),
|
|
41751
|
+
cameraStatus: "0",
|
|
41752
|
+
audioStatus: "0"
|
|
41753
|
+
}).then(() => {
|
|
41754
|
+
return getJoinCall({
|
|
41755
|
+
meetingId: meetingInfo.meetingId,
|
|
41756
|
+
memberId: getUserId(),
|
|
41757
|
+
cameraStatus: "0",
|
|
41758
|
+
audioStatus: "0"
|
|
41759
|
+
});
|
|
41760
|
+
}).then((resp) => {
|
|
41761
|
+
if (resp && resp.code === 200) {
|
|
41762
|
+
sessionStorage.setItem("JS_MEETING_INFO", JSON.stringify(resp.data));
|
|
41763
|
+
console.log("拨打电话", resp.data.meetingToken);
|
|
41764
|
+
setTimeout(() => {
|
|
41765
|
+
joinRoom();
|
|
41766
|
+
}, 100);
|
|
41767
|
+
stopRingtone();
|
|
41768
|
+
recordMeeting("start");
|
|
41769
|
+
}
|
|
41770
|
+
}).catch((err) => {
|
|
41771
|
+
console.error("接听失败", err);
|
|
41772
|
+
setCallStatus("end");
|
|
41773
|
+
});
|
|
41774
|
+
};
|
|
41775
|
+
const endCall = async () => {
|
|
41776
|
+
visible.value = false;
|
|
41777
|
+
stopSosFlash();
|
|
41778
|
+
const meetingInfo = JSON.parse(
|
|
41779
|
+
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41780
|
+
);
|
|
41781
|
+
setCallStatus("end");
|
|
41782
|
+
try {
|
|
41783
|
+
const res = await getHangUpCall({
|
|
41784
|
+
meetingId: meetingInfo.meetingId,
|
|
41785
|
+
memberId: getUserId()
|
|
41786
|
+
});
|
|
41787
|
+
if (res.code === 200) {
|
|
41788
|
+
await logoutRoomAction();
|
|
41789
|
+
clearTimer();
|
|
41790
|
+
recordMeeting("stop");
|
|
41791
|
+
}
|
|
41792
|
+
} catch (err) {
|
|
41793
|
+
console.error("挂断失败", err);
|
|
41794
|
+
await logoutRoomAction();
|
|
41795
|
+
}
|
|
41796
|
+
};
|
|
41797
|
+
const stopMonitoring = async () => {
|
|
41798
|
+
visible.value = false;
|
|
41799
|
+
const meetingInfo = JSON.parse(
|
|
41800
|
+
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41801
|
+
);
|
|
41802
|
+
try {
|
|
41803
|
+
const res = await getMeetingLeave({
|
|
41804
|
+
meetingId: meetingInfo.meetingId,
|
|
41805
|
+
memberId: getUserId()
|
|
41806
|
+
});
|
|
41807
|
+
if (res.code === 200) {
|
|
41808
|
+
await logoutRoomAction();
|
|
41809
|
+
clearTimer();
|
|
41810
|
+
}
|
|
41811
|
+
} catch (err) {
|
|
41812
|
+
console.error("离开失败", err);
|
|
41813
|
+
await logoutRoomAction();
|
|
41814
|
+
}
|
|
41815
|
+
};
|
|
41816
|
+
const clearTimer = () => {
|
|
41817
|
+
if (timer) {
|
|
41818
|
+
clearInterval(timer);
|
|
41819
|
+
timer = null;
|
|
41820
|
+
}
|
|
41821
|
+
};
|
|
41822
|
+
const recordMeeting = (newState) => {
|
|
41823
|
+
const meetingInfo = JSON.parse(
|
|
41824
|
+
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
41825
|
+
);
|
|
41826
|
+
let params = {
|
|
41827
|
+
meetingId: meetingInfo.meetingId,
|
|
41828
|
+
memberId: getUserId(),
|
|
41829
|
+
cmd: newState
|
|
41830
|
+
};
|
|
41831
|
+
getMcuCtrl(params).then(() => {
|
|
41832
|
+
}).catch(() => {
|
|
41833
|
+
});
|
|
41834
|
+
};
|
|
41835
|
+
const toggleDeviceSelector = (deviceType) => {
|
|
41836
|
+
currentDeviceType.value = deviceType;
|
|
41837
|
+
showDeviceSelector.value = !showDeviceSelector.value;
|
|
41838
|
+
};
|
|
41839
|
+
watch(
|
|
41840
|
+
() => visible.value,
|
|
41841
|
+
(newValue) => {
|
|
41842
|
+
if (newValue) {
|
|
41843
|
+
showDeviceSelector.value = false;
|
|
41844
|
+
}
|
|
41845
|
+
}
|
|
41846
|
+
);
|
|
41847
|
+
onMounted(() => {
|
|
41848
|
+
});
|
|
41849
|
+
onUnmounted(() => {
|
|
41850
|
+
if (timer) {
|
|
41851
|
+
clearInterval(timer);
|
|
41852
|
+
timer = null;
|
|
41853
|
+
}
|
|
41854
|
+
});
|
|
41855
|
+
return (_ctx, _cache) => {
|
|
41856
|
+
return openBlock(), createBlock(Teleport, { to: "body" }, [
|
|
41857
|
+
unref(sosFlashVisible) ? (openBlock(), createElementBlock("div", _hoisted_1$m)) : createCommentVNode("", true),
|
|
41858
|
+
unref(visible) ? (openBlock(), createElementBlock("div", {
|
|
41859
|
+
key: 1,
|
|
41860
|
+
class: normalizeClass(["js-dialog-overlay", themeClass.value])
|
|
41861
|
+
}, [
|
|
41862
|
+
createElementVNode("div", _hoisted_2$l, [
|
|
41863
|
+
createElementVNode("div", _hoisted_3$k, [
|
|
41864
|
+
createElementVNode("div", _hoisted_4$i, [
|
|
41865
|
+
createElementVNode("div", null, [
|
|
41866
|
+
createVNode(NetWorkStatus, { theme: _ctx.theme }, null, 8, ["theme"])
|
|
41867
|
+
]),
|
|
41868
|
+
isReceiving.value && callerInfo.value ? (openBlock(), createElementBlock("div", _hoisted_5$f, [
|
|
41869
|
+
createElementVNode("div", _hoisted_6$e, toDisplayString(unref(getUserAvatar)(callerInfo.value)), 1),
|
|
41870
|
+
createElementVNode("div", _hoisted_7$d, [
|
|
41871
|
+
createElementVNode("div", _hoisted_8$c, toDisplayString(callerInfo.value.memberName || "未知来电"), 1),
|
|
41872
|
+
callerInfo.value.shortNumber ? (openBlock(), createElementBlock("div", _hoisted_9$a, " 分机:" + toDisplayString(callerInfo.value.shortNumber), 1)) : createCommentVNode("", true)
|
|
41873
|
+
])
|
|
41874
|
+
])) : createCommentVNode("", true)
|
|
41875
|
+
]),
|
|
41876
|
+
createElementVNode("div", _hoisted_10$a, [
|
|
41877
|
+
createElementVNode("span", null, toDisplayString(statusText.value), 1)
|
|
41878
|
+
])
|
|
41879
|
+
]),
|
|
41880
|
+
createElementVNode("div", {
|
|
41881
|
+
class: normalizeClass(["video-container", layoutClass.value])
|
|
41882
|
+
}, [
|
|
41883
|
+
visibleMembers.value.length ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(visibleMembers.value, (user) => {
|
|
41884
|
+
var _a25, _b25;
|
|
41885
|
+
return openBlock(), createElementBlock("div", {
|
|
41886
|
+
key: user.member.memberId,
|
|
41887
|
+
class: normalizeClass(["video-item", {
|
|
41888
|
+
"is-main": ((_a25 = mainMember.value) == null ? void 0 : _a25.member.memberId) === user.member.memberId,
|
|
41889
|
+
"is-secondary": ((_b25 = mainMember.value) == null ? void 0 : _b25.member.memberId) !== user.member.memberId
|
|
41890
|
+
}]),
|
|
41891
|
+
style: normalizeStyle(getVideoItemStyle(user.member.memberId)),
|
|
41892
|
+
onClick: ($event) => handleSwitchMain(user.member.memberId)
|
|
41893
|
+
}, [
|
|
41894
|
+
createElementVNode("div", _hoisted_12$9, [
|
|
41895
|
+
withDirectives(createElementVNode("div", {
|
|
41896
|
+
id: unref(getUserId)() === user.member.memberId ? "my-video" : `other-${user.member.memberId}`,
|
|
41897
|
+
class: "video-slot"
|
|
41898
|
+
}, null, 8, _hoisted_13$7), [
|
|
41899
|
+
[vShow, (user == null ? void 0 : user.cameraStatus) === "1"]
|
|
41900
|
+
]),
|
|
41901
|
+
withDirectives(createElementVNode("div", _hoisted_14$6, [
|
|
41902
|
+
createElementVNode("div", _hoisted_15$5, toDisplayString(unref(getUserAvatar)(user)), 1)
|
|
41903
|
+
], 512), [
|
|
41904
|
+
[vShow, (user == null ? void 0 : user.cameraStatus) !== "1"]
|
|
41905
|
+
]),
|
|
41906
|
+
withDirectives(createElementVNode("div", _hoisted_16$5, [
|
|
41907
|
+
_cache[6] || (_cache[6] = createElementVNode("div", { class: "video-loading-spinner" }, null, -1)),
|
|
41908
|
+
createElementVNode("div", _hoisted_17$4, toDisplayString((user == null ? void 0 : user.videoRetrying) ? "重新加载中..." : "加载中..."), 1)
|
|
41909
|
+
], 512), [
|
|
41910
|
+
[vShow, (user == null ? void 0 : user.loading) && (user == null ? void 0 : user.cameraStatus) === "1"]
|
|
41911
|
+
]),
|
|
41912
|
+
withDirectives(createElementVNode("div", _hoisted_18$4, [
|
|
41913
|
+
_cache[7] || (_cache[7] = createElementVNode("div", { class: "video-loading-text" }, "视频加载失败", -1)),
|
|
41914
|
+
createElementVNode("button", {
|
|
41915
|
+
type: "button",
|
|
41916
|
+
class: "video-retry-button",
|
|
41917
|
+
disabled: user == null ? void 0 : user.videoRetrying,
|
|
41918
|
+
onClick: withModifiers(($event) => handleRetryVideo(user), ["stop"])
|
|
41919
|
+
}, toDisplayString((user == null ? void 0 : user.videoRetrying) ? "重新加载中..." : "重新加载"), 9, _hoisted_19$4)
|
|
41920
|
+
], 512), [
|
|
41921
|
+
[vShow, (user == null ? void 0 : user.videoLoadFailed) && (user == null ? void 0 : user.cameraStatus) === "1"]
|
|
41922
|
+
]),
|
|
41923
|
+
createElementVNode("div", _hoisted_20$4, [
|
|
41924
|
+
createElementVNode("span", _hoisted_21$2, toDisplayString(user.member.name || "未知成员"), 1),
|
|
41925
|
+
user.member.memberId === unref(getUserId)() ? (openBlock(), createElementBlock("span", _hoisted_22$2, "(我)")) : createCommentVNode("", true)
|
|
41926
|
+
])
|
|
41927
|
+
])
|
|
41928
|
+
], 14, _hoisted_11$9);
|
|
41929
|
+
}), 128)) : (openBlock(), createElementBlock("div", _hoisted_23$2, [..._cache[8] || (_cache[8] = [
|
|
41930
|
+
createElementVNode("span", null, "等待成员加入...", -1)
|
|
41931
|
+
])]))
|
|
41932
|
+
], 2),
|
|
41933
|
+
createElementVNode("div", _hoisted_24$2, [
|
|
41934
|
+
isConnected.value ? (openBlock(), createElementBlock("div", _hoisted_25$2, [
|
|
41935
|
+
createElementVNode("span", _hoisted_26$2, toDisplayString(joinTimeObj.value), 1)
|
|
41936
|
+
])) : createCommentVNode("", true),
|
|
41937
|
+
createElementVNode("div", _hoisted_27$2, [
|
|
41938
|
+
isConnected.value || isForcibleInsertion.value ? (openBlock(), createElementBlock("div", {
|
|
41939
|
+
key: 0,
|
|
41940
|
+
ref_key: "micRef",
|
|
41941
|
+
ref: micRef
|
|
41942
|
+
}, [
|
|
41943
|
+
createElementVNode("button", {
|
|
41944
|
+
class: normalizeClass(["control-btn", { "is-disabled": unref(micOperationBusy) }]),
|
|
41945
|
+
onClick: _cache[0] || (_cache[0] = ($event) => onChange(unref(RoomModalSelectType).microphoneClick))
|
|
41946
|
+
}, [
|
|
41947
|
+
createVNode(SvgIcon, {
|
|
41948
|
+
name: unref(meState2).microPhoneState == "1" ? "MicrophoneIcon" : "MicrophoneSlashIcon",
|
|
41949
|
+
size: 20
|
|
41950
|
+
}, null, 8, ["name"]),
|
|
41951
|
+
_cache[9] || (_cache[9] = createElementVNode("span", null, "麦克风", -1))
|
|
41952
|
+
], 2),
|
|
41953
|
+
createElementVNode("div", {
|
|
41954
|
+
class: normalizeClass(["device-dropdown-trigger", { "is-disabled": unref(micOperationBusy) }]),
|
|
41955
|
+
onClick: _cache[1] || (_cache[1] = ($event) => toggleDeviceSelector("microphone"))
|
|
41956
|
+
}, [
|
|
41957
|
+
createVNode(SvgIcon, {
|
|
41958
|
+
name: "TriangleIcon",
|
|
41959
|
+
size: 9
|
|
41960
|
+
})
|
|
41961
|
+
], 2)
|
|
41962
|
+
], 512)) : createCommentVNode("", true),
|
|
41963
|
+
isReceiving.value ? (openBlock(), createElementBlock("button", {
|
|
41964
|
+
key: 1,
|
|
41965
|
+
class: "accept-call-btn",
|
|
41966
|
+
onClick: acceptCall
|
|
41967
|
+
}, [
|
|
41968
|
+
createVNode(SvgIcon, {
|
|
41969
|
+
name: "PhoneIcon",
|
|
41970
|
+
size: 21
|
|
41971
|
+
}),
|
|
41972
|
+
_cache[10] || (_cache[10] = createElementVNode("span", null, "接听", -1))
|
|
41973
|
+
])) : createCommentVNode("", true),
|
|
41974
|
+
isCalling.value || isReceiving.value || isConnected.value ? (openBlock(), createElementBlock("button", {
|
|
41975
|
+
key: 2,
|
|
41976
|
+
class: "end-call-btn",
|
|
41977
|
+
onClick: endCall
|
|
41978
|
+
}, [
|
|
41979
|
+
createVNode(SvgIcon, {
|
|
41980
|
+
name: "HandUpIcon",
|
|
41981
|
+
size: 21,
|
|
41982
|
+
"color-class": "handUp"
|
|
41983
|
+
}),
|
|
41984
|
+
createElementVNode("span", null, toDisplayString(isReceiving.value ? "拒绝" : "挂断"), 1)
|
|
41985
|
+
])) : createCommentVNode("", true),
|
|
41986
|
+
isListening.value ? (openBlock(), createElementBlock("button", {
|
|
41987
|
+
key: 3,
|
|
41988
|
+
class: "end-call-btn",
|
|
41989
|
+
onClick: stopMonitoring
|
|
41990
|
+
}, [
|
|
41991
|
+
createVNode(SvgIcon, {
|
|
41992
|
+
name: "HandUpIcon",
|
|
41993
|
+
size: 21,
|
|
41994
|
+
"color-class": "handUp"
|
|
41995
|
+
}),
|
|
41996
|
+
_cache[11] || (_cache[11] = createElementVNode("span", null, "结束监听", -1))
|
|
41997
|
+
])) : createCommentVNode("", true),
|
|
41998
|
+
isForcibleInsertion.value ? (openBlock(), createElementBlock("button", {
|
|
41999
|
+
key: 4,
|
|
42000
|
+
class: "end-call-btn",
|
|
42001
|
+
onClick: stopMonitoring
|
|
42002
|
+
}, [
|
|
42003
|
+
createVNode(SvgIcon, {
|
|
42004
|
+
name: "HandUpIcon",
|
|
42005
|
+
size: 20
|
|
42006
|
+
}),
|
|
42007
|
+
_cache[12] || (_cache[12] = createElementVNode("span", null, "退出通话", -1))
|
|
42008
|
+
])) : createCommentVNode("", true),
|
|
42009
|
+
isConnected.value || isForcibleInsertion.value ? (openBlock(), createElementBlock("div", {
|
|
42010
|
+
key: 5,
|
|
42011
|
+
ref_key: "cameraRef",
|
|
42012
|
+
ref: cameraRef
|
|
42013
|
+
}, [
|
|
42014
|
+
createElementVNode("button", {
|
|
42015
|
+
class: normalizeClass(["control-btn", { "is-disabled": unref(cameraOperationBusy) }]),
|
|
42016
|
+
onClick: _cache[2] || (_cache[2] = ($event) => onChange(unref(RoomModalSelectType).cameraClick))
|
|
42017
|
+
}, [
|
|
42018
|
+
createVNode(SvgIcon, {
|
|
42019
|
+
name: unref(meState2).cameraState == "1" ? "CameraIcon" : "CameraSlashIcon",
|
|
42020
|
+
size: 20
|
|
42021
|
+
}, null, 8, ["name"]),
|
|
42022
|
+
_cache[13] || (_cache[13] = createElementVNode("span", null, "摄像头", -1))
|
|
42023
|
+
], 2),
|
|
42024
|
+
createElementVNode("div", {
|
|
42025
|
+
class: normalizeClass(["device-dropdown-trigger", { "is-disabled": unref(cameraOperationBusy) }]),
|
|
42026
|
+
onClick: _cache[3] || (_cache[3] = ($event) => toggleDeviceSelector("camera"))
|
|
42027
|
+
}, [
|
|
42028
|
+
createVNode(SvgIcon, {
|
|
42029
|
+
name: "TriangleIcon",
|
|
42030
|
+
size: 9
|
|
42031
|
+
})
|
|
42032
|
+
], 2)
|
|
42033
|
+
], 512)) : createCommentVNode("", true)
|
|
42034
|
+
]),
|
|
42035
|
+
isConnected.value ? (openBlock(), createElementBlock("div", _hoisted_28$2, [
|
|
42036
|
+
createVNode(SvgIcon, {
|
|
42037
|
+
name: "TranscribeIcon",
|
|
42038
|
+
size: 22
|
|
42039
|
+
}),
|
|
42040
|
+
_cache[14] || (_cache[14] = createElementVNode("span", null, "录制中", -1))
|
|
42041
|
+
])) : createCommentVNode("", true)
|
|
42042
|
+
])
|
|
42043
|
+
]),
|
|
42044
|
+
createVNode(SmartPopup, {
|
|
42045
|
+
visible: showDeviceSelector.value,
|
|
42046
|
+
"onUpdate:visible": _cache[5] || (_cache[5] = ($event) => showDeviceSelector.value = $event),
|
|
42047
|
+
trigger: currentDeviceType.value == "microphone" ? micRef.value : cameraRef.value,
|
|
42048
|
+
gap: 10
|
|
42049
|
+
}, {
|
|
42050
|
+
default: withCtx(() => [
|
|
42051
|
+
createVNode(DeviceSelector, {
|
|
42052
|
+
"device-type": currentDeviceType.value,
|
|
42053
|
+
theme: _ctx.theme,
|
|
42054
|
+
onClose: _cache[4] || (_cache[4] = ($event) => showDeviceSelector.value = false)
|
|
42055
|
+
}, null, 8, ["device-type", "theme"])
|
|
42056
|
+
]),
|
|
42057
|
+
_: 1
|
|
42058
|
+
}, 8, ["visible", "trigger"])
|
|
42059
|
+
], 2)) : createCommentVNode("", true)
|
|
42060
|
+
]);
|
|
42061
|
+
};
|
|
41681
42062
|
}
|
|
41682
|
-
|
|
41683
|
-
|
|
41684
|
-
|
|
41685
|
-
|
|
41686
|
-
|
|
41687
|
-
|
|
42063
|
+
});
|
|
42064
|
+
const JSCall = /* @__PURE__ */ _export_sfc(_sfc_main$o, [["__scopeId", "data-v-5c880aa1"]]);
|
|
42065
|
+
const HANDOFF_SOURCE_TAB_ID_KEY = "JS_MEETING_MQTT_HANDOFF_SOURCE_TAB_ID";
|
|
42066
|
+
const HANDOFF_TARGET_TAB_ID_KEY = "JS_MEETING_MQTT_HANDOFF_TARGET_TAB_ID";
|
|
42067
|
+
const HANDOFF_ID_KEY = "JS_MEETING_MQTT_HANDOFF_ID";
|
|
42068
|
+
const RECONNECT_SIGNAL_KEY = "JS_MEETING_MQTT_RECONNECT_SIGNAL";
|
|
42069
|
+
const TARGET_HEARTBEAT_KEY = "JS_MEETING_MQTT_HANDOFF_HEARTBEAT";
|
|
42070
|
+
const TARGET_TAB_STATUS_KEY = "JS_MEETING_NEW_TAB_STATUS";
|
|
42071
|
+
const TARGET_HEARTBEAT_INTERVAL_MS = 1e3;
|
|
42072
|
+
const RECONNECT_CHECK_DELAY_MS = 1500;
|
|
42073
|
+
const TARGET_TAB_STATUS_CLOSED = 0;
|
|
42074
|
+
const TARGET_TAB_STATUS_OPEN = 1;
|
|
42075
|
+
let installed = false;
|
|
42076
|
+
let closeSignalSent = false;
|
|
42077
|
+
let heartbeatTimer = null;
|
|
42078
|
+
let lastHandledReconnectSignalTs = 0;
|
|
42079
|
+
let leaveRequestSent = false;
|
|
42080
|
+
function createRandomId() {
|
|
42081
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
42082
|
+
return crypto.randomUUID().replace(/-/g, "").slice(0, 12);
|
|
41688
42083
|
}
|
|
41689
|
-
|
|
41690
|
-
return currentTabId === context.targetTabId;
|
|
42084
|
+
return Math.random().toString(36).slice(2, 14);
|
|
41691
42085
|
}
|
|
41692
|
-
function
|
|
42086
|
+
function safeSessionStorageGetItem(key) {
|
|
41693
42087
|
try {
|
|
41694
|
-
|
|
41695
|
-
const meetingId = String((meetingInfo == null ? void 0 : meetingInfo.meetingId) || "").trim();
|
|
41696
|
-
const memberId = String(getUserId() || "").trim();
|
|
41697
|
-
if (!meetingId || !memberId) {
|
|
41698
|
-
return null;
|
|
41699
|
-
}
|
|
41700
|
-
return { meetingId, memberId, force: true };
|
|
42088
|
+
return sessionStorage.getItem(key);
|
|
41701
42089
|
} catch {
|
|
41702
42090
|
return null;
|
|
41703
42091
|
}
|
|
41704
42092
|
}
|
|
41705
|
-
function
|
|
41706
|
-
if (leaveRequestSent) {
|
|
41707
|
-
return;
|
|
41708
|
-
}
|
|
41709
|
-
const payload = buildMeetingLeavePayload();
|
|
41710
|
-
if (!payload) {
|
|
41711
|
-
return;
|
|
41712
|
-
}
|
|
41713
|
-
leaveRequestSent = true;
|
|
41714
|
-
const body = JSON.stringify(payload);
|
|
41715
|
-
const token = getSdkToken();
|
|
41716
|
-
const authHeader = token ? { Authorization: `Bearer ${token}` } : {};
|
|
41717
|
-
const requestUrl = "/meeting/api/v2/meeting/leave";
|
|
42093
|
+
function safeLocalStorageSetItem(key, value) {
|
|
41718
42094
|
try {
|
|
41719
|
-
|
|
41720
|
-
method: "POST",
|
|
41721
|
-
headers: {
|
|
41722
|
-
"Content-Type": "application/json",
|
|
41723
|
-
Accept: "application/json, text/plain, */*",
|
|
41724
|
-
"X-Requested-With": "XMLHttpRequest",
|
|
41725
|
-
...authHeader
|
|
41726
|
-
},
|
|
41727
|
-
body,
|
|
41728
|
-
keepalive: true,
|
|
41729
|
-
credentials: "same-origin"
|
|
41730
|
-
}).catch(() => {
|
|
41731
|
-
});
|
|
41732
|
-
console.warn("[MQTT_HANDOFF] 页面关闭触发离会请求(keepalive)", payload);
|
|
42095
|
+
localStorage.setItem(key, value);
|
|
41733
42096
|
} catch {
|
|
41734
42097
|
}
|
|
42098
|
+
}
|
|
42099
|
+
function safeLocalStorageGetItem(key) {
|
|
41735
42100
|
try {
|
|
41736
|
-
|
|
41737
|
-
const beaconData = new Blob([body], { type: "application/json" });
|
|
41738
|
-
const sent = navigator.sendBeacon(requestUrl, beaconData);
|
|
41739
|
-
console.warn("[MQTT_HANDOFF] 页面关闭触发离会请求(beacon)", {
|
|
41740
|
-
...payload,
|
|
41741
|
-
sent
|
|
41742
|
-
});
|
|
41743
|
-
}
|
|
42101
|
+
return localStorage.getItem(key);
|
|
41744
42102
|
} catch {
|
|
42103
|
+
return null;
|
|
41745
42104
|
}
|
|
41746
42105
|
}
|
|
41747
|
-
function
|
|
41748
|
-
const
|
|
41749
|
-
|
|
41750
|
-
|
|
41751
|
-
|
|
41752
|
-
|
|
41753
|
-
if (!latestHeartbeat) {
|
|
41754
|
-
return true;
|
|
41755
|
-
}
|
|
41756
|
-
if (latestHeartbeat.targetTabId !== signal.targetTabId) {
|
|
41757
|
-
return true;
|
|
41758
|
-
}
|
|
41759
|
-
if (latestHeartbeat.handoffId !== signal.handoffId) {
|
|
41760
|
-
return true;
|
|
42106
|
+
function getMeetingMqttHandoffContext() {
|
|
42107
|
+
const sourceTabId = safeSessionStorageGetItem(HANDOFF_SOURCE_TAB_ID_KEY) || "";
|
|
42108
|
+
const targetTabId = safeSessionStorageGetItem(HANDOFF_TARGET_TAB_ID_KEY) || "";
|
|
42109
|
+
const handoffId = safeSessionStorageGetItem(HANDOFF_ID_KEY) || "";
|
|
42110
|
+
if (!sourceTabId || !targetTabId || !handoffId) {
|
|
42111
|
+
return null;
|
|
41761
42112
|
}
|
|
41762
|
-
return
|
|
41763
|
-
|
|
41764
|
-
|
|
41765
|
-
|
|
41766
|
-
}
|
|
41767
|
-
function setMeetingMqttHandoffForWindow(targetWindow, context) {
|
|
41768
|
-
targetWindow.sessionStorage.setItem(
|
|
41769
|
-
HANDOFF_SOURCE_TAB_ID_KEY,
|
|
41770
|
-
context.sourceTabId
|
|
41771
|
-
);
|
|
41772
|
-
targetWindow.sessionStorage.setItem(
|
|
41773
|
-
HANDOFF_TARGET_TAB_ID_KEY,
|
|
41774
|
-
context.targetTabId
|
|
41775
|
-
);
|
|
41776
|
-
targetWindow.sessionStorage.setItem(HANDOFF_ID_KEY, context.handoffId);
|
|
42113
|
+
return {
|
|
42114
|
+
sourceTabId,
|
|
42115
|
+
targetTabId,
|
|
42116
|
+
handoffId
|
|
42117
|
+
};
|
|
41777
42118
|
}
|
|
41778
|
-
function
|
|
41779
|
-
|
|
41780
|
-
|
|
42119
|
+
function readTargetHeartbeat() {
|
|
42120
|
+
const raw = safeLocalStorageGetItem(TARGET_HEARTBEAT_KEY);
|
|
42121
|
+
if (!raw) {
|
|
42122
|
+
return null;
|
|
41781
42123
|
}
|
|
41782
|
-
|
|
41783
|
-
|
|
41784
|
-
|
|
41785
|
-
|
|
41786
|
-
return;
|
|
41787
|
-
}
|
|
41788
|
-
let signal = null;
|
|
41789
|
-
try {
|
|
41790
|
-
signal = JSON.parse(event.newValue);
|
|
41791
|
-
} catch {
|
|
41792
|
-
return;
|
|
41793
|
-
}
|
|
41794
|
-
if (!(signal == null ? void 0 : signal.sourceTabId) || !signal.targetTabId || !signal.handoffId) {
|
|
41795
|
-
return;
|
|
41796
|
-
}
|
|
41797
|
-
const signalTs = Number(signal.ts);
|
|
41798
|
-
if (!signalTs || signalTs <= lastHandledReconnectSignalTs) {
|
|
41799
|
-
return;
|
|
41800
|
-
}
|
|
41801
|
-
lastHandledReconnectSignalTs = signalTs;
|
|
41802
|
-
console.warn("[MQTT_HANDOFF] 收到 MQTT 恢复信号,等待确认目标页是否真的关闭", {
|
|
41803
|
-
sourceTabId: signal.sourceTabId,
|
|
41804
|
-
targetTabId: signal.targetTabId,
|
|
41805
|
-
handoffId: signal.handoffId,
|
|
41806
|
-
signalTs
|
|
41807
|
-
});
|
|
41808
|
-
window.setTimeout(() => {
|
|
41809
|
-
if (!shouldReconnectForSignal(signal)) {
|
|
41810
|
-
console.info("[MQTT_HANDOFF] 忽略 MQTT 恢复,本次更像是目标页刷新/重载", {
|
|
41811
|
-
sourceTabId: signal.sourceTabId,
|
|
41812
|
-
targetTabId: signal.targetTabId,
|
|
41813
|
-
handoffId: signal.handoffId
|
|
41814
|
-
});
|
|
41815
|
-
return;
|
|
41816
|
-
}
|
|
41817
|
-
console.warn("[MQTT_HANDOFF] 确认目标页已关闭,准备恢复来源页 MQTT", {
|
|
41818
|
-
sourceTabId: signal.sourceTabId,
|
|
41819
|
-
targetTabId: signal.targetTabId,
|
|
41820
|
-
handoffId: signal.handoffId
|
|
41821
|
-
});
|
|
41822
|
-
void onReconnectRequested();
|
|
41823
|
-
}, RECONNECT_CHECK_DELAY_MS);
|
|
41824
|
-
});
|
|
41825
|
-
window.addEventListener("beforeunload", (event) => {
|
|
41826
|
-
if (!shouldWarnBeforeUnload()) {
|
|
41827
|
-
return;
|
|
41828
|
-
}
|
|
41829
|
-
event.preventDefault();
|
|
41830
|
-
event.returnValue = "";
|
|
41831
|
-
});
|
|
41832
|
-
window.addEventListener("pagehide", (event) => {
|
|
41833
|
-
const context = getMeetingMqttHandoffContext();
|
|
41834
|
-
const shouldHandleTargetTabClose = !!context && getCurrentMeetingTabId() === context.targetTabId;
|
|
41835
|
-
if (shouldHandleTargetTabClose && context) {
|
|
41836
|
-
writeTargetTabStatus(TARGET_TAB_STATUS_CLOSED, context);
|
|
41837
|
-
sendMeetingLeaveOnClose();
|
|
41838
|
-
}
|
|
41839
|
-
stopTargetHeartbeat();
|
|
41840
|
-
if (event.persisted) {
|
|
41841
|
-
return;
|
|
42124
|
+
try {
|
|
42125
|
+
const parsed = JSON.parse(raw);
|
|
42126
|
+
if (!(parsed == null ? void 0 : parsed.targetTabId) || !(parsed == null ? void 0 : parsed.handoffId) || !(parsed == null ? void 0 : parsed.ts)) {
|
|
42127
|
+
return null;
|
|
41842
42128
|
}
|
|
41843
|
-
|
|
42129
|
+
return {
|
|
42130
|
+
targetTabId: parsed.targetTabId,
|
|
42131
|
+
handoffId: parsed.handoffId,
|
|
42132
|
+
ts: Number(parsed.ts)
|
|
42133
|
+
};
|
|
42134
|
+
} catch {
|
|
42135
|
+
return null;
|
|
42136
|
+
}
|
|
42137
|
+
}
|
|
42138
|
+
function writeTargetHeartbeat(context) {
|
|
42139
|
+
safeLocalStorageSetItem(
|
|
42140
|
+
TARGET_HEARTBEAT_KEY,
|
|
42141
|
+
JSON.stringify({
|
|
42142
|
+
targetTabId: context.targetTabId,
|
|
42143
|
+
handoffId: context.handoffId,
|
|
42144
|
+
ts: Date.now()
|
|
42145
|
+
})
|
|
42146
|
+
);
|
|
42147
|
+
}
|
|
42148
|
+
function writeTargetTabStatus(status, context) {
|
|
42149
|
+
safeLocalStorageSetItem(
|
|
42150
|
+
TARGET_TAB_STATUS_KEY,
|
|
42151
|
+
JSON.stringify({
|
|
42152
|
+
sourceTabId: context.sourceTabId,
|
|
42153
|
+
targetTabId: context.targetTabId,
|
|
42154
|
+
handoffId: context.handoffId,
|
|
42155
|
+
status,
|
|
42156
|
+
ts: Date.now()
|
|
42157
|
+
})
|
|
42158
|
+
);
|
|
42159
|
+
}
|
|
42160
|
+
function sendReconnectSignal(context) {
|
|
42161
|
+
if (closeSignalSent) {
|
|
42162
|
+
return;
|
|
42163
|
+
}
|
|
42164
|
+
closeSignalSent = true;
|
|
42165
|
+
console.warn("[MQTT_HANDOFF] 目标页关闭,通知来源页恢复 MQTT", {
|
|
42166
|
+
sourceTabId: context.sourceTabId,
|
|
42167
|
+
targetTabId: context.targetTabId,
|
|
42168
|
+
handoffId: context.handoffId
|
|
41844
42169
|
});
|
|
42170
|
+
safeLocalStorageSetItem(
|
|
42171
|
+
RECONNECT_SIGNAL_KEY,
|
|
42172
|
+
JSON.stringify({
|
|
42173
|
+
...context,
|
|
42174
|
+
ts: Date.now()
|
|
42175
|
+
})
|
|
42176
|
+
);
|
|
41845
42177
|
}
|
|
41846
|
-
|
|
41847
|
-
|
|
41848
|
-
|
|
41849
|
-
|
|
41850
|
-
|
|
41851
|
-
|
|
41852
|
-
|
|
41853
|
-
|
|
41854
|
-
|
|
41855
|
-
|
|
41856
|
-
|
|
41857
|
-
|
|
41858
|
-
|
|
41859
|
-
|
|
41860
|
-
|
|
41861
|
-
|
|
41862
|
-
|
|
41863
|
-
|
|
41864
|
-
|
|
41865
|
-
|
|
41866
|
-
|
|
41867
|
-
|
|
41868
|
-
|
|
41869
|
-
|
|
41870
|
-
|
|
41871
|
-
|
|
41872
|
-
|
|
41873
|
-
|
|
41874
|
-
|
|
41875
|
-
|
|
41876
|
-
|
|
41877
|
-
|
|
41878
|
-
const hasOpenedNewTab = ref(false);
|
|
41879
|
-
const getNewTabFlagFromLocation = () => {
|
|
41880
|
-
if (typeof window === "undefined") return false;
|
|
41881
|
-
const searchParams = new URLSearchParams(window.location.search || "");
|
|
41882
|
-
if (searchParams.get("newTab") === "true") return true;
|
|
41883
|
-
const hash = window.location.hash || "";
|
|
41884
|
-
const hashQueryIndex = hash.indexOf("?");
|
|
41885
|
-
if (hashQueryIndex === -1) return false;
|
|
41886
|
-
const hashQuery = hash.slice(hashQueryIndex + 1);
|
|
41887
|
-
const hashParams = new URLSearchParams(hashQuery);
|
|
41888
|
-
return hashParams.get("newTab") === "true";
|
|
41889
|
-
};
|
|
41890
|
-
const showOpenNewTabButton = computed(() => {
|
|
41891
|
-
if (hasOpenedNewTab.value) return false;
|
|
41892
|
-
return !getNewTabFlagFromLocation();
|
|
41893
|
-
});
|
|
41894
|
-
const createMqttInstanceId = () => {
|
|
41895
|
-
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
41896
|
-
return crypto.randomUUID().replace(/-/g, "").slice(0, 12);
|
|
41897
|
-
}
|
|
41898
|
-
return Math.random().toString(36).slice(2, 14);
|
|
41899
|
-
};
|
|
41900
|
-
const copySessionToNewTab = (targetWindow) => {
|
|
41901
|
-
SESSION_STORAGE_KEYS_TO_CLONE.forEach((key) => {
|
|
41902
|
-
const value = sessionStorage.getItem(key);
|
|
41903
|
-
if (value === null) {
|
|
41904
|
-
targetWindow.sessionStorage.removeItem(key);
|
|
41905
|
-
return;
|
|
41906
|
-
}
|
|
41907
|
-
targetWindow.sessionStorage.setItem(key, value);
|
|
41908
|
-
});
|
|
41909
|
-
};
|
|
41910
|
-
const handleOpenNewTab = async () => {
|
|
41911
|
-
var _a25;
|
|
41912
|
-
hasOpenedNewTab.value = true;
|
|
41913
|
-
const currentMeetingId = (_a25 = meetingInfo.value) == null ? void 0 : _a25.meetingId;
|
|
41914
|
-
const newTab = window.open("", "_blank");
|
|
41915
|
-
if (!newTab) {
|
|
41916
|
-
hasOpenedNewTab.value = false;
|
|
41917
|
-
showNotification("打开新标签页失败,请允许弹窗权限。", "warning", 5e3);
|
|
41918
|
-
return;
|
|
41919
|
-
}
|
|
41920
|
-
try {
|
|
41921
|
-
const sourceTabId = getCurrentMeetingTabId();
|
|
41922
|
-
const nextTabId = createMeetingTabId();
|
|
41923
|
-
const handoffId = createMeetingMqttHandoffId();
|
|
41924
|
-
copySessionToNewTab(newTab);
|
|
41925
|
-
setMeetingMqttHandoffForWindow(newTab, {
|
|
41926
|
-
sourceTabId,
|
|
41927
|
-
targetTabId: nextTabId,
|
|
41928
|
-
handoffId
|
|
41929
|
-
});
|
|
41930
|
-
newTab.sessionStorage.setItem(
|
|
41931
|
-
MQTT_CLIENT_INSTANCE_STORAGE_KEY,
|
|
41932
|
-
createMqttInstanceId()
|
|
41933
|
-
);
|
|
41934
|
-
setMeetingTabIdForWindow(newTab, nextTabId);
|
|
41935
|
-
if (currentMeetingId) {
|
|
41936
|
-
claimActiveMeetingOwnership(currentMeetingId, nextTabId);
|
|
41937
|
-
}
|
|
41938
|
-
let url = window.location.href;
|
|
41939
|
-
if (url.includes("home") || url.includes("surveillance")) {
|
|
41940
|
-
url = url.replace("home", "command");
|
|
41941
|
-
url = url.replace("surveillance", "command");
|
|
41942
|
-
}
|
|
41943
|
-
newTab.location.replace(url + "?newTab=true");
|
|
41944
|
-
resetMeetingMQTT();
|
|
41945
|
-
await logoutRoomAction();
|
|
41946
|
-
closeMeeting();
|
|
41947
|
-
} catch (error) {
|
|
41948
|
-
hasOpenedNewTab.value = false;
|
|
41949
|
-
console.error("Failed to open meeting in a new tab:", error);
|
|
41950
|
-
showNotification("New tab initialized with a fallback page open.", "warning", 5e3);
|
|
41951
|
-
}
|
|
41952
|
-
};
|
|
41953
|
-
const handleCloseClick = async () => {
|
|
41954
|
-
showCloseConfirm.value = !showCloseConfirm.value;
|
|
41955
|
-
};
|
|
41956
|
-
const handleEndMeeting = () => {
|
|
41957
|
-
showCloseConfirm.value = false;
|
|
41958
|
-
emit("onChange", RoomModalSelectType.endClick);
|
|
41959
|
-
};
|
|
41960
|
-
const handleLeaveMeeting = () => {
|
|
41961
|
-
showCloseConfirm.value = false;
|
|
41962
|
-
emit("onChange", RoomModalSelectType.leaveClick);
|
|
41963
|
-
};
|
|
41964
|
-
return (_ctx, _cache) => {
|
|
41965
|
-
return openBlock(), createElementBlock("div", {
|
|
41966
|
-
class: normalizeClass(["js-dialog-header", themeClass.value])
|
|
41967
|
-
}, [
|
|
41968
|
-
createElementVNode("div", _hoisted_1$n, toDisplayString(meetingInfo.value.meetingName), 1),
|
|
41969
|
-
createElementVNode("div", _hoisted_2$l, [
|
|
41970
|
-
showOpenNewTabButton.value ? (openBlock(), createElementBlock("div", {
|
|
41971
|
-
key: 0,
|
|
41972
|
-
title: "新打开标签页",
|
|
41973
|
-
onClick: handleOpenNewTab
|
|
41974
|
-
}, [
|
|
41975
|
-
createVNode(SvgIcon, {
|
|
41976
|
-
name: "OpenNewTabIcon",
|
|
41977
|
-
size: 16
|
|
41978
|
-
})
|
|
41979
|
-
])) : createCommentVNode("", true),
|
|
41980
|
-
createElementVNode("div", {
|
|
41981
|
-
title: "最小化",
|
|
41982
|
-
onClick: _cache[0] || (_cache[0] = ($event) => emit("onChange", unref(RoomModalSelectType).minimizeClick))
|
|
41983
|
-
}, [
|
|
41984
|
-
createVNode(SvgIcon, {
|
|
41985
|
-
name: "MinimizeIcon",
|
|
41986
|
-
size: 16
|
|
41987
|
-
})
|
|
41988
|
-
]),
|
|
41989
|
-
createElementVNode("div", {
|
|
41990
|
-
ref_key: "closeRef",
|
|
41991
|
-
ref: closeRef,
|
|
41992
|
-
title: "关闭",
|
|
41993
|
-
onClick: handleCloseClick
|
|
41994
|
-
}, [
|
|
41995
|
-
createVNode(SvgIcon, {
|
|
41996
|
-
name: "CloseIcon",
|
|
41997
|
-
size: 17
|
|
41998
|
-
})
|
|
41999
|
-
], 512)
|
|
42000
|
-
]),
|
|
42001
|
-
createVNode(SmartPopup, {
|
|
42002
|
-
visible: showCloseConfirm.value,
|
|
42003
|
-
"onUpdate:visible": _cache[2] || (_cache[2] = ($event) => showCloseConfirm.value = $event),
|
|
42004
|
-
trigger: closeRef.value,
|
|
42005
|
-
gap: 10
|
|
42006
|
-
}, {
|
|
42007
|
-
default: withCtx(() => [
|
|
42008
|
-
createElementVNode("div", {
|
|
42009
|
-
class: normalizeClass(["close-confirm-dropdown", themeClass.value])
|
|
42010
|
-
}, [
|
|
42011
|
-
unref(meState2).roleType == "1" ? (openBlock(), createElementBlock("div", {
|
|
42012
|
-
key: 0,
|
|
42013
|
-
class: "close-confirm-option danger",
|
|
42014
|
-
onClick: withModifiers(handleEndMeeting, ["stop"])
|
|
42015
|
-
}, " 结束会议 ")) : createCommentVNode("", true),
|
|
42016
|
-
createElementVNode("div", {
|
|
42017
|
-
class: "close-confirm-option simple",
|
|
42018
|
-
onClick: withModifiers(handleLeaveMeeting, ["stop"])
|
|
42019
|
-
}, " 离开会议 "),
|
|
42020
|
-
createElementVNode("div", {
|
|
42021
|
-
class: "close-confirm-option simple",
|
|
42022
|
-
onClick: _cache[1] || (_cache[1] = ($event) => showCloseConfirm.value = false)
|
|
42023
|
-
}, " 取消 ")
|
|
42024
|
-
], 2)
|
|
42025
|
-
]),
|
|
42026
|
-
_: 1
|
|
42027
|
-
}, 8, ["visible", "trigger"])
|
|
42028
|
-
], 2);
|
|
42029
|
-
};
|
|
42178
|
+
function stopTargetHeartbeat() {
|
|
42179
|
+
if (heartbeatTimer) {
|
|
42180
|
+
clearInterval(heartbeatTimer);
|
|
42181
|
+
heartbeatTimer = null;
|
|
42182
|
+
}
|
|
42183
|
+
}
|
|
42184
|
+
function startTargetHeartbeat() {
|
|
42185
|
+
const context = getMeetingMqttHandoffContext();
|
|
42186
|
+
if (!context) {
|
|
42187
|
+
return;
|
|
42188
|
+
}
|
|
42189
|
+
const currentTabId = getCurrentMeetingTabId();
|
|
42190
|
+
if (currentTabId !== context.targetTabId) {
|
|
42191
|
+
return;
|
|
42192
|
+
}
|
|
42193
|
+
closeSignalSent = false;
|
|
42194
|
+
console.info("[MQTT_HANDOFF] 目标页心跳已启动", {
|
|
42195
|
+
sourceTabId: context.sourceTabId,
|
|
42196
|
+
targetTabId: context.targetTabId,
|
|
42197
|
+
handoffId: context.handoffId
|
|
42198
|
+
});
|
|
42199
|
+
writeTargetTabStatus(TARGET_TAB_STATUS_OPEN, context);
|
|
42200
|
+
writeTargetHeartbeat(context);
|
|
42201
|
+
stopTargetHeartbeat();
|
|
42202
|
+
heartbeatTimer = setInterval(() => {
|
|
42203
|
+
writeTargetHeartbeat(context);
|
|
42204
|
+
}, TARGET_HEARTBEAT_INTERVAL_MS);
|
|
42205
|
+
}
|
|
42206
|
+
function notifySourceTabForReconnect() {
|
|
42207
|
+
const context = getMeetingMqttHandoffContext();
|
|
42208
|
+
if (!context) {
|
|
42209
|
+
return;
|
|
42030
42210
|
}
|
|
42031
|
-
|
|
42032
|
-
|
|
42033
|
-
|
|
42034
|
-
|
|
42035
|
-
|
|
42036
|
-
|
|
42037
|
-
|
|
42038
|
-
const
|
|
42039
|
-
|
|
42040
|
-
|
|
42041
|
-
}
|
|
42042
|
-
const
|
|
42043
|
-
|
|
42044
|
-
|
|
42045
|
-
|
|
42046
|
-
|
|
42047
|
-
|
|
42048
|
-
|
|
42049
|
-
|
|
42050
|
-
|
|
42051
|
-
|
|
42052
|
-
const _hoisted_11$9 = { class: "popup-item-label" };
|
|
42053
|
-
const _hoisted_12$9 = { class: "popup-item-value" };
|
|
42054
|
-
const _hoisted_13$7 = { class: "popup-section" };
|
|
42055
|
-
const _hoisted_14$6 = { class: "popup-grid" };
|
|
42056
|
-
const _hoisted_15$5 = { class: "popup-item-label" };
|
|
42057
|
-
const _hoisted_16$5 = { class: "popup-item-value" };
|
|
42058
|
-
const _hoisted_17$4 = { class: "popup-header" };
|
|
42059
|
-
const _hoisted_18$4 = { class: "popup-header-actions" };
|
|
42060
|
-
const _hoisted_19$4 = { class: "popup-section-container" };
|
|
42061
|
-
const _hoisted_20$4 = ["onClick"];
|
|
42062
|
-
const _hoisted_21$2 = { class: "detail-section-main" };
|
|
42063
|
-
const _hoisted_22$2 = { class: "popup-section-title" };
|
|
42064
|
-
const _hoisted_23$2 = { class: "popup-section-count" };
|
|
42065
|
-
const _hoisted_24$2 = { class: "detail-section-icon" };
|
|
42066
|
-
const _hoisted_25$2 = {
|
|
42067
|
-
key: 0,
|
|
42068
|
-
class: "metric-card-list"
|
|
42069
|
-
};
|
|
42070
|
-
const _hoisted_26$2 = { class: "metric-card-header" };
|
|
42071
|
-
const _hoisted_27$2 = { class: "metric-card-title" };
|
|
42072
|
-
const _hoisted_28$2 = { class: "metric-card-subtitle" };
|
|
42073
|
-
const _hoisted_29$2 = { class: "metric-card-grid" };
|
|
42074
|
-
const _hoisted_30$2 = { class: "popup-item-label" };
|
|
42075
|
-
const _hoisted_31$1 = { class: "popup-item-value" };
|
|
42076
|
-
const _hoisted_32$1 = {
|
|
42077
|
-
key: 1,
|
|
42078
|
-
class: "popup-empty"
|
|
42079
|
-
};
|
|
42080
|
-
const _sfc_main$o = /* @__PURE__ */ defineComponent({
|
|
42081
|
-
__name: "NetworkQualitySignal",
|
|
42082
|
-
props: {
|
|
42083
|
-
theme: { default: "dark" },
|
|
42084
|
-
size: { default: "default" },
|
|
42085
|
-
showText: { type: Boolean, default: false }
|
|
42086
|
-
},
|
|
42087
|
-
setup(__props) {
|
|
42088
|
-
const props = __props;
|
|
42089
|
-
const triggerRef = ref(null);
|
|
42090
|
-
const showPopup = ref(false);
|
|
42091
|
-
const advancedOpen = ref(false);
|
|
42092
|
-
const collapsedSections = ref({});
|
|
42093
|
-
const advancedDetails = ref();
|
|
42094
|
-
let detailTimer = null;
|
|
42095
|
-
const themeClass = computed(() => `theme-${props.theme}`);
|
|
42096
|
-
function formatValue(value, suffix = "", digits = 0) {
|
|
42097
|
-
if (typeof value !== "number" || Number.isNaN(value)) return "--";
|
|
42098
|
-
return `${value.toFixed(digits)}${suffix}`;
|
|
42099
|
-
}
|
|
42100
|
-
function formatMetricNumber(value, suffix = "", digits = 0) {
|
|
42101
|
-
if (typeof value !== "number" || Number.isNaN(value)) return "--";
|
|
42102
|
-
return `${value.toFixed(digits)}${suffix}`;
|
|
42103
|
-
}
|
|
42104
|
-
function formatBytes(value) {
|
|
42105
|
-
if (typeof value !== "number" || Number.isNaN(value)) return "--";
|
|
42106
|
-
if (value >= 1024 * 1024) return `${(value / (1024 * 1024)).toFixed(2)} MB`;
|
|
42107
|
-
if (value >= 1024) return `${(value / 1024).toFixed(1)} KB`;
|
|
42108
|
-
return `${value.toFixed(0)} B`;
|
|
42109
|
-
}
|
|
42110
|
-
function formatDimension(width, height) {
|
|
42111
|
-
if (!width || !height) return "--";
|
|
42112
|
-
return `${width} x ${height}`;
|
|
42113
|
-
}
|
|
42114
|
-
function formatLossRate(value) {
|
|
42115
|
-
if (typeof value !== "number" || Number.isNaN(value)) return "--";
|
|
42116
|
-
return `${value.toFixed(1)}%`;
|
|
42211
|
+
const currentTabId = getCurrentMeetingTabId();
|
|
42212
|
+
if (currentTabId !== context.targetTabId) {
|
|
42213
|
+
return;
|
|
42214
|
+
}
|
|
42215
|
+
sendReconnectSignal(context);
|
|
42216
|
+
}
|
|
42217
|
+
function shouldWarnBeforeUnload() {
|
|
42218
|
+
const context = getMeetingMqttHandoffContext();
|
|
42219
|
+
if (!context) {
|
|
42220
|
+
return false;
|
|
42221
|
+
}
|
|
42222
|
+
const currentTabId = getCurrentMeetingTabId();
|
|
42223
|
+
return currentTabId === context.targetTabId;
|
|
42224
|
+
}
|
|
42225
|
+
function buildMeetingLeavePayload() {
|
|
42226
|
+
try {
|
|
42227
|
+
const meetingInfo = JSON.parse(sessionStorage.getItem("JS_MEETING_INFO") || "{}");
|
|
42228
|
+
const meetingId = String((meetingInfo == null ? void 0 : meetingInfo.meetingId) || "").trim();
|
|
42229
|
+
const memberId = String(getUserId() || "").trim();
|
|
42230
|
+
if (!meetingId || !memberId) {
|
|
42231
|
+
return null;
|
|
42117
42232
|
}
|
|
42118
|
-
|
|
42119
|
-
|
|
42120
|
-
|
|
42233
|
+
return { meetingId, memberId, force: true };
|
|
42234
|
+
} catch {
|
|
42235
|
+
return null;
|
|
42236
|
+
}
|
|
42237
|
+
}
|
|
42238
|
+
function sendMeetingLeaveOnClose() {
|
|
42239
|
+
if (leaveRequestSent) {
|
|
42240
|
+
return;
|
|
42241
|
+
}
|
|
42242
|
+
const payload = buildMeetingLeavePayload();
|
|
42243
|
+
if (!payload) {
|
|
42244
|
+
return;
|
|
42245
|
+
}
|
|
42246
|
+
leaveRequestSent = true;
|
|
42247
|
+
const body = JSON.stringify(payload);
|
|
42248
|
+
const token = getSdkToken();
|
|
42249
|
+
const authHeader = token ? { Authorization: `Bearer ${token}` } : {};
|
|
42250
|
+
const requestUrl = "/meeting/api/v2/meeting/leave";
|
|
42251
|
+
try {
|
|
42252
|
+
fetch(requestUrl, {
|
|
42253
|
+
method: "POST",
|
|
42254
|
+
headers: {
|
|
42255
|
+
"Content-Type": "application/json",
|
|
42256
|
+
Accept: "application/json, text/plain, */*",
|
|
42257
|
+
"X-Requested-With": "XMLHttpRequest",
|
|
42258
|
+
...authHeader
|
|
42259
|
+
},
|
|
42260
|
+
body,
|
|
42261
|
+
keepalive: true,
|
|
42262
|
+
credentials: "same-origin"
|
|
42263
|
+
}).catch(() => {
|
|
42264
|
+
});
|
|
42265
|
+
console.warn("[MQTT_HANDOFF] 页面关闭触发离会请求(keepalive)", payload);
|
|
42266
|
+
} catch {
|
|
42267
|
+
}
|
|
42268
|
+
try {
|
|
42269
|
+
if (typeof navigator !== "undefined" && typeof navigator.sendBeacon === "function") {
|
|
42270
|
+
const beaconData = new Blob([body], { type: "application/json" });
|
|
42271
|
+
const sent = navigator.sendBeacon(requestUrl, beaconData);
|
|
42272
|
+
console.warn("[MQTT_HANDOFF] 页面关闭触发离会请求(beacon)", {
|
|
42273
|
+
...payload,
|
|
42274
|
+
sent
|
|
42275
|
+
});
|
|
42121
42276
|
}
|
|
42122
|
-
|
|
42123
|
-
|
|
42124
|
-
|
|
42125
|
-
|
|
42126
|
-
|
|
42127
|
-
|
|
42128
|
-
|
|
42277
|
+
} catch {
|
|
42278
|
+
}
|
|
42279
|
+
}
|
|
42280
|
+
function shouldReconnectForSignal(signal) {
|
|
42281
|
+
const currentTabId = getCurrentMeetingTabId();
|
|
42282
|
+
if (!signal.sourceTabId || signal.sourceTabId !== currentTabId) {
|
|
42283
|
+
return false;
|
|
42284
|
+
}
|
|
42285
|
+
const latestHeartbeat = readTargetHeartbeat();
|
|
42286
|
+
if (!latestHeartbeat) {
|
|
42287
|
+
return true;
|
|
42288
|
+
}
|
|
42289
|
+
if (latestHeartbeat.targetTabId !== signal.targetTabId) {
|
|
42290
|
+
return true;
|
|
42291
|
+
}
|
|
42292
|
+
if (latestHeartbeat.handoffId !== signal.handoffId) {
|
|
42293
|
+
return true;
|
|
42294
|
+
}
|
|
42295
|
+
return latestHeartbeat.ts <= signal.ts;
|
|
42296
|
+
}
|
|
42297
|
+
function createMeetingMqttHandoffId() {
|
|
42298
|
+
return `mqtt_handoff_${Date.now()}_${createRandomId()}`;
|
|
42299
|
+
}
|
|
42300
|
+
function setMeetingMqttHandoffForWindow(targetWindow, context) {
|
|
42301
|
+
targetWindow.sessionStorage.setItem(
|
|
42302
|
+
HANDOFF_SOURCE_TAB_ID_KEY,
|
|
42303
|
+
context.sourceTabId
|
|
42304
|
+
);
|
|
42305
|
+
targetWindow.sessionStorage.setItem(
|
|
42306
|
+
HANDOFF_TARGET_TAB_ID_KEY,
|
|
42307
|
+
context.targetTabId
|
|
42308
|
+
);
|
|
42309
|
+
targetWindow.sessionStorage.setItem(HANDOFF_ID_KEY, context.handoffId);
|
|
42310
|
+
}
|
|
42311
|
+
function installMeetingMqttHandoffBridge(onReconnectRequested) {
|
|
42312
|
+
if (installed || typeof window === "undefined") {
|
|
42313
|
+
return;
|
|
42314
|
+
}
|
|
42315
|
+
installed = true;
|
|
42316
|
+
startTargetHeartbeat();
|
|
42317
|
+
window.addEventListener("storage", (event) => {
|
|
42318
|
+
if (event.key !== RECONNECT_SIGNAL_KEY || !event.newValue) {
|
|
42319
|
+
return;
|
|
42129
42320
|
}
|
|
42130
|
-
|
|
42131
|
-
|
|
42321
|
+
let signal = null;
|
|
42322
|
+
try {
|
|
42323
|
+
signal = JSON.parse(event.newValue);
|
|
42324
|
+
} catch {
|
|
42325
|
+
return;
|
|
42132
42326
|
}
|
|
42133
|
-
|
|
42134
|
-
|
|
42135
|
-
if (!memberId) return "";
|
|
42136
|
-
const matched = members.value.find(
|
|
42137
|
-
(member) => {
|
|
42138
|
-
var _a26;
|
|
42139
|
-
return ((_a26 = member == null ? void 0 : member.member) == null ? void 0 : _a26.memberId) === String(memberId);
|
|
42140
|
-
}
|
|
42141
|
-
);
|
|
42142
|
-
return ((_a25 = matched == null ? void 0 : matched.member) == null ? void 0 : _a25.name) || "";
|
|
42327
|
+
if (!(signal == null ? void 0 : signal.sourceTabId) || !signal.targetTabId || !signal.handoffId) {
|
|
42328
|
+
return;
|
|
42143
42329
|
}
|
|
42144
|
-
|
|
42145
|
-
|
|
42146
|
-
|
|
42147
|
-
detailTimer = window.setInterval(() => {
|
|
42148
|
-
refreshAdvancedDetails();
|
|
42149
|
-
}, 2e3);
|
|
42330
|
+
const signalTs = Number(signal.ts);
|
|
42331
|
+
if (!signalTs || signalTs <= lastHandledReconnectSignalTs) {
|
|
42332
|
+
return;
|
|
42150
42333
|
}
|
|
42151
|
-
|
|
42152
|
-
|
|
42153
|
-
|
|
42154
|
-
|
|
42334
|
+
lastHandledReconnectSignalTs = signalTs;
|
|
42335
|
+
console.warn("[MQTT_HANDOFF] 收到 MQTT 恢复信号,等待确认目标页是否真的关闭", {
|
|
42336
|
+
sourceTabId: signal.sourceTabId,
|
|
42337
|
+
targetTabId: signal.targetTabId,
|
|
42338
|
+
handoffId: signal.handoffId,
|
|
42339
|
+
signalTs
|
|
42340
|
+
});
|
|
42341
|
+
window.setTimeout(() => {
|
|
42342
|
+
if (!shouldReconnectForSignal(signal)) {
|
|
42343
|
+
console.info("[MQTT_HANDOFF] 忽略 MQTT 恢复,本次更像是目标页刷新/重载", {
|
|
42344
|
+
sourceTabId: signal.sourceTabId,
|
|
42345
|
+
targetTabId: signal.targetTabId,
|
|
42346
|
+
handoffId: signal.handoffId
|
|
42347
|
+
});
|
|
42348
|
+
return;
|
|
42155
42349
|
}
|
|
42350
|
+
console.warn("[MQTT_HANDOFF] 确认目标页已关闭,准备恢复来源页 MQTT", {
|
|
42351
|
+
sourceTabId: signal.sourceTabId,
|
|
42352
|
+
targetTabId: signal.targetTabId,
|
|
42353
|
+
handoffId: signal.handoffId
|
|
42354
|
+
});
|
|
42355
|
+
void onReconnectRequested();
|
|
42356
|
+
}, RECONNECT_CHECK_DELAY_MS);
|
|
42357
|
+
});
|
|
42358
|
+
window.addEventListener("beforeunload", (event) => {
|
|
42359
|
+
if (!shouldWarnBeforeUnload()) {
|
|
42360
|
+
return;
|
|
42156
42361
|
}
|
|
42157
|
-
|
|
42158
|
-
|
|
42159
|
-
|
|
42160
|
-
|
|
42161
|
-
|
|
42162
|
-
|
|
42163
|
-
|
|
42164
|
-
|
|
42165
|
-
|
|
42166
|
-
function expandAllSections() {
|
|
42167
|
-
collapsedSections.value = Object.fromEntries(
|
|
42168
|
-
detailSections.value.map((section) => [section.key, false])
|
|
42169
|
-
);
|
|
42170
|
-
}
|
|
42171
|
-
function collapseAllSections() {
|
|
42172
|
-
collapsedSections.value = Object.fromEntries(
|
|
42173
|
-
detailSections.value.map((section) => [section.key, true])
|
|
42174
|
-
);
|
|
42175
|
-
}
|
|
42176
|
-
function toggleAllSections() {
|
|
42177
|
-
if (allSectionsExpanded.value) {
|
|
42178
|
-
collapseAllSections();
|
|
42179
|
-
return;
|
|
42180
|
-
}
|
|
42181
|
-
expandAllSections();
|
|
42362
|
+
event.preventDefault();
|
|
42363
|
+
event.returnValue = "";
|
|
42364
|
+
});
|
|
42365
|
+
window.addEventListener("pagehide", (event) => {
|
|
42366
|
+
const context = getMeetingMqttHandoffContext();
|
|
42367
|
+
const shouldHandleTargetTabClose = !!context && getCurrentMeetingTabId() === context.targetTabId;
|
|
42368
|
+
if (shouldHandleTargetTabClose && context) {
|
|
42369
|
+
writeTargetTabStatus(TARGET_TAB_STATUS_CLOSED, context);
|
|
42370
|
+
sendMeetingLeaveOnClose();
|
|
42182
42371
|
}
|
|
42183
|
-
|
|
42184
|
-
|
|
42185
|
-
|
|
42186
|
-
if (preserveExisting && section.key in collapsedSections.value) {
|
|
42187
|
-
nextState[section.key] = collapsedSections.value[section.key];
|
|
42188
|
-
continue;
|
|
42189
|
-
}
|
|
42190
|
-
nextState[section.key] = false;
|
|
42191
|
-
}
|
|
42192
|
-
collapsedSections.value = nextState;
|
|
42372
|
+
stopTargetHeartbeat();
|
|
42373
|
+
if (event.persisted) {
|
|
42374
|
+
return;
|
|
42193
42375
|
}
|
|
42194
|
-
|
|
42195
|
-
|
|
42196
|
-
|
|
42197
|
-
|
|
42198
|
-
|
|
42199
|
-
|
|
42200
|
-
|
|
42201
|
-
|
|
42202
|
-
|
|
42376
|
+
notifySourceTabForReconnect();
|
|
42377
|
+
});
|
|
42378
|
+
}
|
|
42379
|
+
const _hoisted_1$l = { class: "js-dialog-header-title" };
|
|
42380
|
+
const _hoisted_2$k = { class: "js-dialog-header-actions" };
|
|
42381
|
+
const MQTT_CLIENT_INSTANCE_STORAGE_KEY = "JS_MQTT_CLIENT_INSTANCE_ID";
|
|
42382
|
+
const _sfc_main$n = /* @__PURE__ */ defineComponent({
|
|
42383
|
+
__name: "meeting-header",
|
|
42384
|
+
props: {
|
|
42385
|
+
theme: {},
|
|
42386
|
+
isMaximized: { type: Boolean }
|
|
42387
|
+
},
|
|
42388
|
+
emits: ["onChange"],
|
|
42389
|
+
setup(__props, { emit: __emit }) {
|
|
42390
|
+
const props = __props;
|
|
42391
|
+
const { meState: meState2 } = storeToRefs(useMeetingStore());
|
|
42392
|
+
const meetingInfo = computed(() => {
|
|
42393
|
+
return JSON.parse(sessionStorage.getItem("JS_MEETING_INFO") || "{}");
|
|
42203
42394
|
});
|
|
42204
|
-
const
|
|
42205
|
-
|
|
42206
|
-
|
|
42395
|
+
const emit = __emit;
|
|
42396
|
+
const closeRef = ref(null);
|
|
42397
|
+
const showCloseConfirm = ref(false);
|
|
42398
|
+
const SESSION_STORAGE_KEYS_TO_CLONE = [
|
|
42399
|
+
"JS_MEETING_INFO",
|
|
42400
|
+
"JS_SDK_TOKEN",
|
|
42401
|
+
"JS_SDK_TOKEN_EXPIRY",
|
|
42402
|
+
"JS_USER_ID",
|
|
42403
|
+
"JS_USER_NAME",
|
|
42404
|
+
"JS_SELF_MEDIA_PREFS",
|
|
42405
|
+
"JS_SERVER_TIMESTAMP",
|
|
42406
|
+
"joinTime",
|
|
42407
|
+
"JS_INCOMING_CALL_INFO",
|
|
42408
|
+
"isSosActive"
|
|
42409
|
+
];
|
|
42410
|
+
const themeClass = computed(() => `theme-${props.theme || "dark"}`);
|
|
42411
|
+
const hasOpenedNewTab = ref(false);
|
|
42412
|
+
const getNewTabFlagFromLocation = () => {
|
|
42413
|
+
if (typeof window === "undefined") return false;
|
|
42414
|
+
const searchParams = new URLSearchParams(window.location.search || "");
|
|
42415
|
+
if (searchParams.get("newTab") === "true") return true;
|
|
42416
|
+
const hash = window.location.hash || "";
|
|
42417
|
+
const hashQueryIndex = hash.indexOf("?");
|
|
42418
|
+
if (hashQueryIndex === -1) return false;
|
|
42419
|
+
const hashQuery = hash.slice(hashQueryIndex + 1);
|
|
42420
|
+
const hashParams = new URLSearchParams(hashQuery);
|
|
42421
|
+
return hashParams.get("newTab") === "true";
|
|
42422
|
+
};
|
|
42423
|
+
const showOpenNewTabButton = computed(() => {
|
|
42424
|
+
if (hasOpenedNewTab.value) return false;
|
|
42425
|
+
return !getNewTabFlagFromLocation();
|
|
42207
42426
|
});
|
|
42208
|
-
const
|
|
42209
|
-
|
|
42210
|
-
|
|
42211
|
-
{ label: "下行质量", value: networkQualityState.downlink },
|
|
42212
|
-
{ label: "MOS", value: formatMos(networkQualityState.mos) },
|
|
42213
|
-
{ label: "最近更新", value: formatUpdatedAt(networkQualityState.updatedAt) },
|
|
42214
|
-
{
|
|
42215
|
-
label: "数据状态",
|
|
42216
|
-
value: networkQualityState.isStale ? "已过期" : "实时"
|
|
42427
|
+
const createMqttInstanceId = () => {
|
|
42428
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
42429
|
+
return crypto.randomUUID().replace(/-/g, "").slice(0, 12);
|
|
42217
42430
|
}
|
|
42218
|
-
|
|
42219
|
-
|
|
42220
|
-
|
|
42221
|
-
|
|
42222
|
-
|
|
42223
|
-
|
|
42224
|
-
|
|
42225
|
-
|
|
42226
|
-
{ label: "上行丢包率", value: formatLossRate(stats == null ? void 0 : stats.lossrate_up) },
|
|
42227
|
-
{ label: "下行丢包率", value: formatLossRate(stats == null ? void 0 : stats.lossrate_down) },
|
|
42228
|
-
{
|
|
42229
|
-
label: "可用上行带宽",
|
|
42230
|
-
value: formatValue(stats == null ? void 0 : stats.available_outgoing_bitrate, " kb/s")
|
|
42231
|
-
},
|
|
42232
|
-
{
|
|
42233
|
-
label: "可用下行带宽",
|
|
42234
|
-
value: formatValue(stats == null ? void 0 : stats.available_incoming_bitrate, " kb/s")
|
|
42431
|
+
return Math.random().toString(36).slice(2, 14);
|
|
42432
|
+
};
|
|
42433
|
+
const copySessionToNewTab = (targetWindow) => {
|
|
42434
|
+
SESSION_STORAGE_KEYS_TO_CLONE.forEach((key) => {
|
|
42435
|
+
const value = sessionStorage.getItem(key);
|
|
42436
|
+
if (value === null) {
|
|
42437
|
+
targetWindow.sessionStorage.removeItem(key);
|
|
42438
|
+
return;
|
|
42235
42439
|
}
|
|
42236
|
-
|
|
42237
|
-
|
|
42238
|
-
|
|
42239
|
-
|
|
42240
|
-
|
|
42241
|
-
|
|
42242
|
-
|
|
42243
|
-
|
|
42244
|
-
|
|
42245
|
-
|
|
42246
|
-
|
|
42247
|
-
|
|
42248
|
-
|
|
42249
|
-
|
|
42250
|
-
|
|
42251
|
-
|
|
42252
|
-
|
|
42253
|
-
|
|
42254
|
-
|
|
42255
|
-
|
|
42256
|
-
|
|
42257
|
-
|
|
42258
|
-
|
|
42259
|
-
|
|
42260
|
-
|
|
42261
|
-
|
|
42262
|
-
|
|
42263
|
-
|
|
42264
|
-
|
|
42265
|
-
|
|
42266
|
-
{ 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)}` },
|
|
42267
|
-
{ label: "重传包数", value: formatMetricNumber(stats == null ? void 0 : stats.retransmittedPacketsSent) },
|
|
42268
|
-
{ label: "受限原因", value: formatReason(stats == null ? void 0 : stats.qualityLimitationReason) },
|
|
42269
|
-
{ label: "分辨率变化", value: formatMetricNumber(stats == null ? void 0 : stats.qualityLimitationResolutionChanges) },
|
|
42270
|
-
{ label: "往返时延", value: formatMetricNumber(stats == null ? void 0 : stats.roundTripTime, " ms") },
|
|
42271
|
-
{ label: "采样时间", value: formatUpdatedAt(stats == null ? void 0 : stats.timestamp) }
|
|
42272
|
-
]
|
|
42273
|
-
};
|
|
42274
|
-
}
|
|
42275
|
-
function createAudioRecvCard(item, index) {
|
|
42276
|
-
const stats = (item == null ? void 0 : item.stats) || {};
|
|
42277
|
-
return {
|
|
42278
|
-
title: `远端音频 ${index + 1}`,
|
|
42279
|
-
subtitle: (item == null ? void 0 : item.uid) || (item == null ? void 0 : item.desc) || (stats == null ? void 0 : stats.streamId) || "接收轨道",
|
|
42280
|
-
items: [
|
|
42281
|
-
{ label: "实时码率", value: formatMetricNumber(item == null ? void 0 : item.bitrate, " kb/s") },
|
|
42282
|
-
{ label: "音频电平", value: formatMetricNumber(item == null ? void 0 : item.db, " dBFS", 1) },
|
|
42283
|
-
{ label: "已收包数", value: formatMetricNumber(stats == null ? void 0 : stats.packetsReceived) },
|
|
42284
|
-
{ label: "已收字节", value: formatBytes(stats == null ? void 0 : stats.bytesReceived) },
|
|
42285
|
-
{ label: "丢包数", value: formatMetricNumber(stats == null ? void 0 : stats.packetsLost) },
|
|
42286
|
-
{ label: "网络抖动", value: formatMetricNumber(stats == null ? void 0 : stats.jitter, " ms") },
|
|
42287
|
-
{ label: "缓冲均值", value: formatMetricNumber(stats == null ? void 0 : stats.jitterBufferAvgDelay, " ms") },
|
|
42288
|
-
{ label: "隐藏事件", value: formatMetricNumber(stats == null ? void 0 : stats.concealmentEvents) },
|
|
42289
|
-
{ label: "静音隐藏", value: formatMetricNumber(stats == null ? void 0 : stats.silentConcealmentEvents) },
|
|
42290
|
-
{ label: "采样时间", value: formatUpdatedAt(stats == null ? void 0 : stats.timestamp) }
|
|
42291
|
-
]
|
|
42292
|
-
};
|
|
42293
|
-
}
|
|
42294
|
-
function createVideoRecvCard(item, index) {
|
|
42295
|
-
const stats = (item == null ? void 0 : item.stats) || {};
|
|
42296
|
-
const memberName = getMemberNameById(item == null ? void 0 : item.uid);
|
|
42297
|
-
return {
|
|
42298
|
-
title: `远端视频 ${index + 1}`,
|
|
42299
|
-
subtitle: memberName || (item == null ? void 0 : item.uid) || (item == null ? void 0 : item.desc) || (stats == null ? void 0 : stats.mimeType) || "接收轨道",
|
|
42300
|
-
items: [
|
|
42301
|
-
{ label: "实时码率", value: formatMetricNumber(item == null ? void 0 : item.bitrate, " kb/s") },
|
|
42302
|
-
{ 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)) },
|
|
42303
|
-
{ label: "帧率", value: formatMetricNumber((item == null ? void 0 : item.fps) || (stats == null ? void 0 : stats.framesPerSecond), " fps") },
|
|
42304
|
-
{ label: "已收包数", value: formatMetricNumber(stats == null ? void 0 : stats.packetsReceived) },
|
|
42305
|
-
{ label: "已收字节", value: formatBytes(stats == null ? void 0 : stats.bytesReceived) },
|
|
42306
|
-
{ label: "丢包数", value: formatMetricNumber(stats == null ? void 0 : stats.packetsLost) },
|
|
42307
|
-
{ label: "接收/解码帧", value: `${formatMetricNumber(stats == null ? void 0 : stats.framesReceived)}/${formatMetricNumber(stats == null ? void 0 : stats.framesDecoded)}` },
|
|
42308
|
-
{ label: "丢帧数", value: formatMetricNumber(stats == null ? void 0 : stats.framesDropped) },
|
|
42309
|
-
{ 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)}` },
|
|
42310
|
-
{ label: "缓冲均值", value: formatMetricNumber(stats == null ? void 0 : stats.jitterBufferAvgDelay, " ms") },
|
|
42311
|
-
{ label: "解码器", value: formatReason(stats == null ? void 0 : stats.decoderImplementation) },
|
|
42312
|
-
{ label: "MIME", value: formatReason(stats == null ? void 0 : stats.mimeType) },
|
|
42313
|
-
{ label: "采样时间", value: formatUpdatedAt(stats == null ? void 0 : stats.timestamp) }
|
|
42314
|
-
]
|
|
42315
|
-
};
|
|
42316
|
-
}
|
|
42317
|
-
const detailSections = computed(() => {
|
|
42318
|
-
const details = advancedDetails.value;
|
|
42319
|
-
return [
|
|
42320
|
-
{
|
|
42321
|
-
key: "local-audio",
|
|
42322
|
-
title: "本地音频发送",
|
|
42323
|
-
cards: ((details == null ? void 0 : details.local_audios) || []).map(createAudioSendCard)
|
|
42324
|
-
},
|
|
42325
|
-
{
|
|
42326
|
-
key: "local-video",
|
|
42327
|
-
title: "本地视频发送",
|
|
42328
|
-
cards: ((details == null ? void 0 : details.local_videos) || []).map(createVideoSendCard)
|
|
42329
|
-
},
|
|
42330
|
-
{
|
|
42331
|
-
key: "remote-audio",
|
|
42332
|
-
title: "远端音频接收",
|
|
42333
|
-
cards: ((details == null ? void 0 : details.remote_audios) || []).map(createAudioRecvCard)
|
|
42334
|
-
},
|
|
42335
|
-
{
|
|
42336
|
-
key: "remote-video",
|
|
42337
|
-
title: "远端视频接收",
|
|
42338
|
-
cards: ((details == null ? void 0 : details.remote_videos) || []).map(createVideoRecvCard)
|
|
42440
|
+
targetWindow.sessionStorage.setItem(key, value);
|
|
42441
|
+
});
|
|
42442
|
+
};
|
|
42443
|
+
const handleOpenNewTab = async () => {
|
|
42444
|
+
var _a25;
|
|
42445
|
+
hasOpenedNewTab.value = true;
|
|
42446
|
+
const currentMeetingId = (_a25 = meetingInfo.value) == null ? void 0 : _a25.meetingId;
|
|
42447
|
+
const newTab = window.open("", "_blank");
|
|
42448
|
+
if (!newTab) {
|
|
42449
|
+
hasOpenedNewTab.value = false;
|
|
42450
|
+
showNotification("打开新标签页失败,请允许弹窗权限。", "warning", 5e3);
|
|
42451
|
+
return;
|
|
42452
|
+
}
|
|
42453
|
+
try {
|
|
42454
|
+
const sourceTabId = getCurrentMeetingTabId();
|
|
42455
|
+
const nextTabId = createMeetingTabId();
|
|
42456
|
+
const handoffId = createMeetingMqttHandoffId();
|
|
42457
|
+
copySessionToNewTab(newTab);
|
|
42458
|
+
setMeetingMqttHandoffForWindow(newTab, {
|
|
42459
|
+
sourceTabId,
|
|
42460
|
+
targetTabId: nextTabId,
|
|
42461
|
+
handoffId
|
|
42462
|
+
});
|
|
42463
|
+
newTab.sessionStorage.setItem(
|
|
42464
|
+
MQTT_CLIENT_INSTANCE_STORAGE_KEY,
|
|
42465
|
+
createMqttInstanceId()
|
|
42466
|
+
);
|
|
42467
|
+
setMeetingTabIdForWindow(newTab, nextTabId);
|
|
42468
|
+
if (currentMeetingId) {
|
|
42469
|
+
claimActiveMeetingOwnership(currentMeetingId, nextTabId);
|
|
42339
42470
|
}
|
|
42340
|
-
|
|
42341
|
-
|
|
42342
|
-
|
|
42343
|
-
|
|
42344
|
-
refreshNetworkQualitySnapshot(false);
|
|
42345
|
-
if (advancedOpen.value) {
|
|
42346
|
-
syncSectionCollapse();
|
|
42347
|
-
startDetailRefresh();
|
|
42471
|
+
let url = window.location.href;
|
|
42472
|
+
if (url.includes("home") || url.includes("surveillance")) {
|
|
42473
|
+
url = url.replace("home", "command");
|
|
42474
|
+
url = url.replace("surveillance", "command");
|
|
42348
42475
|
}
|
|
42349
|
-
|
|
42350
|
-
|
|
42351
|
-
|
|
42352
|
-
|
|
42353
|
-
|
|
42354
|
-
|
|
42355
|
-
|
|
42356
|
-
|
|
42357
|
-
if (!showPopup.value) return;
|
|
42358
|
-
if (open2) {
|
|
42359
|
-
syncSectionCollapse(false);
|
|
42360
|
-
startDetailRefresh();
|
|
42361
|
-
} else {
|
|
42362
|
-
stopDetailRefresh();
|
|
42363
|
-
advancedDetails.value = void 0;
|
|
42476
|
+
newTab.location.replace(url + "?newTab=true");
|
|
42477
|
+
resetMeetingMQTT();
|
|
42478
|
+
await logoutRoomAction();
|
|
42479
|
+
closeMeeting();
|
|
42480
|
+
} catch (error) {
|
|
42481
|
+
hasOpenedNewTab.value = false;
|
|
42482
|
+
console.error("Failed to open meeting in a new tab:", error);
|
|
42483
|
+
showNotification("New tab initialized with a fallback page open.", "warning", 5e3);
|
|
42364
42484
|
}
|
|
42365
|
-
}
|
|
42366
|
-
|
|
42367
|
-
|
|
42368
|
-
|
|
42369
|
-
|
|
42370
|
-
|
|
42371
|
-
|
|
42372
|
-
|
|
42373
|
-
)
|
|
42374
|
-
|
|
42375
|
-
|
|
42376
|
-
}
|
|
42485
|
+
};
|
|
42486
|
+
const handleCloseClick = async () => {
|
|
42487
|
+
showCloseConfirm.value = !showCloseConfirm.value;
|
|
42488
|
+
};
|
|
42489
|
+
const handleEndMeeting = () => {
|
|
42490
|
+
showCloseConfirm.value = false;
|
|
42491
|
+
emit("onChange", RoomModalSelectType.endClick);
|
|
42492
|
+
};
|
|
42493
|
+
const handleLeaveMeeting = () => {
|
|
42494
|
+
showCloseConfirm.value = false;
|
|
42495
|
+
emit("onChange", RoomModalSelectType.leaveClick);
|
|
42496
|
+
};
|
|
42377
42497
|
return (_ctx, _cache) => {
|
|
42378
42498
|
return openBlock(), createElementBlock("div", {
|
|
42379
|
-
class: normalizeClass(["
|
|
42499
|
+
class: normalizeClass(["js-dialog-header", themeClass.value])
|
|
42380
42500
|
}, [
|
|
42381
|
-
createElementVNode("
|
|
42382
|
-
|
|
42383
|
-
|
|
42384
|
-
|
|
42385
|
-
|
|
42386
|
-
|
|
42387
|
-
|
|
42388
|
-
|
|
42389
|
-
|
|
42390
|
-
|
|
42391
|
-
|
|
42392
|
-
|
|
42393
|
-
|
|
42394
|
-
|
|
42395
|
-
(
|
|
42396
|
-
|
|
42397
|
-
|
|
42398
|
-
|
|
42399
|
-
|
|
42400
|
-
})
|
|
42501
|
+
createElementVNode("div", _hoisted_1$l, toDisplayString(meetingInfo.value.meetingName), 1),
|
|
42502
|
+
createElementVNode("div", _hoisted_2$k, [
|
|
42503
|
+
showOpenNewTabButton.value ? (openBlock(), createElementBlock("div", {
|
|
42504
|
+
key: 0,
|
|
42505
|
+
title: "新打开标签页",
|
|
42506
|
+
onClick: handleOpenNewTab
|
|
42507
|
+
}, [
|
|
42508
|
+
createVNode(SvgIcon, {
|
|
42509
|
+
name: "OpenNewTabIcon",
|
|
42510
|
+
size: 16
|
|
42511
|
+
})
|
|
42512
|
+
])) : createCommentVNode("", true),
|
|
42513
|
+
createElementVNode("div", {
|
|
42514
|
+
title: "最小化",
|
|
42515
|
+
onClick: _cache[0] || (_cache[0] = ($event) => emit("onChange", unref(RoomModalSelectType).minimizeClick))
|
|
42516
|
+
}, [
|
|
42517
|
+
createVNode(SvgIcon, {
|
|
42518
|
+
name: "MinimizeIcon",
|
|
42519
|
+
size: 16
|
|
42520
|
+
})
|
|
42401
42521
|
]),
|
|
42402
|
-
|
|
42403
|
-
|
|
42522
|
+
createElementVNode("div", {
|
|
42523
|
+
ref_key: "closeRef",
|
|
42524
|
+
ref: closeRef,
|
|
42525
|
+
title: "关闭",
|
|
42526
|
+
onClick: handleCloseClick
|
|
42527
|
+
}, [
|
|
42528
|
+
createVNode(SvgIcon, {
|
|
42529
|
+
name: "CloseIcon",
|
|
42530
|
+
size: 17
|
|
42531
|
+
})
|
|
42532
|
+
], 512)
|
|
42533
|
+
]),
|
|
42404
42534
|
createVNode(SmartPopup, {
|
|
42405
|
-
visible:
|
|
42406
|
-
"onUpdate:visible": _cache[
|
|
42407
|
-
trigger:
|
|
42408
|
-
gap:
|
|
42535
|
+
visible: showCloseConfirm.value,
|
|
42536
|
+
"onUpdate:visible": _cache[2] || (_cache[2] = ($event) => showCloseConfirm.value = $event),
|
|
42537
|
+
trigger: closeRef.value,
|
|
42538
|
+
gap: 10
|
|
42409
42539
|
}, {
|
|
42410
42540
|
default: withCtx(() => [
|
|
42411
|
-
createElementVNode("div",
|
|
42412
|
-
|
|
42413
|
-
|
|
42414
|
-
|
|
42415
|
-
createElementVNode("div", _hoisted_5$f, [
|
|
42416
|
-
_cache[4] || (_cache[4] = createElementVNode("div", { class: "popup-title" }, "网络详情", -1)),
|
|
42417
|
-
createElementVNode("div", _hoisted_6$e, [
|
|
42418
|
-
createElementVNode("button", {
|
|
42419
|
-
type: "button",
|
|
42420
|
-
class: "advanced-toggle",
|
|
42421
|
-
onClick: _cache[1] || (_cache[1] = withModifiers(($event) => advancedOpen.value = !advancedOpen.value, ["stop"]))
|
|
42422
|
-
}, toDisplayString(advancedOpen.value ? "关闭高级模式" : "打开高级模式"), 1),
|
|
42423
|
-
createElementVNode("div", {
|
|
42424
|
-
class: normalizeClass(["popup-status", `is-${unref(networkQualityState).level}`])
|
|
42425
|
-
}, toDisplayString(unref(networkQualityState).label), 3)
|
|
42426
|
-
])
|
|
42427
|
-
]),
|
|
42428
|
-
createElementVNode("div", _hoisted_7$d, toDisplayString(unref(networkQualityState).summary), 1),
|
|
42429
|
-
reasonText.value ? (openBlock(), createElementBlock("div", _hoisted_8$c, toDisplayString(reasonText.value), 1)) : createCommentVNode("", true),
|
|
42430
|
-
createElementVNode("div", _hoisted_9$a, [
|
|
42431
|
-
_cache[5] || (_cache[5] = createElementVNode("div", { class: "popup-section-title" }, "质量概览", -1)),
|
|
42432
|
-
createElementVNode("div", _hoisted_10$a, [
|
|
42433
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(qualityItems.value, (item) => {
|
|
42434
|
-
return openBlock(), createElementBlock("div", {
|
|
42435
|
-
key: item.label,
|
|
42436
|
-
class: "popup-item"
|
|
42437
|
-
}, [
|
|
42438
|
-
createElementVNode("div", _hoisted_11$9, toDisplayString(item.label), 1),
|
|
42439
|
-
createElementVNode("div", _hoisted_12$9, toDisplayString(item.value), 1)
|
|
42440
|
-
]);
|
|
42441
|
-
}), 128))
|
|
42442
|
-
])
|
|
42443
|
-
]),
|
|
42444
|
-
createElementVNode("div", _hoisted_13$7, [
|
|
42445
|
-
_cache[6] || (_cache[6] = createElementVNode("div", { class: "popup-section-title" }, "网络指标", -1)),
|
|
42446
|
-
createElementVNode("div", _hoisted_14$6, [
|
|
42447
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(overviewItems.value, (item) => {
|
|
42448
|
-
return openBlock(), createElementBlock("div", {
|
|
42449
|
-
key: item.label,
|
|
42450
|
-
class: "popup-item"
|
|
42451
|
-
}, [
|
|
42452
|
-
createElementVNode("div", _hoisted_15$5, toDisplayString(item.label), 1),
|
|
42453
|
-
createElementVNode("div", _hoisted_16$5, toDisplayString(item.value), 1)
|
|
42454
|
-
]);
|
|
42455
|
-
}), 128))
|
|
42456
|
-
])
|
|
42457
|
-
])
|
|
42458
|
-
], 2),
|
|
42459
|
-
advancedOpen.value ? (openBlock(), createElementBlock("div", {
|
|
42541
|
+
createElementVNode("div", {
|
|
42542
|
+
class: normalizeClass(["close-confirm-dropdown", themeClass.value])
|
|
42543
|
+
}, [
|
|
42544
|
+
unref(meState2).roleType == "1" ? (openBlock(), createElementBlock("div", {
|
|
42460
42545
|
key: 0,
|
|
42461
|
-
class:
|
|
42462
|
-
onClick:
|
|
42463
|
-
|
|
42464
|
-
|
|
42465
|
-
|
|
42466
|
-
|
|
42467
|
-
|
|
42468
|
-
|
|
42469
|
-
|
|
42470
|
-
|
|
42471
|
-
|
|
42472
|
-
|
|
42473
|
-
])
|
|
42474
|
-
]),
|
|
42475
|
-
createElementVNode("div", _hoisted_19$4, [
|
|
42476
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(detailSections.value, (section) => {
|
|
42477
|
-
return openBlock(), createElementBlock("div", {
|
|
42478
|
-
key: section.key,
|
|
42479
|
-
class: "popup-section"
|
|
42480
|
-
}, [
|
|
42481
|
-
createElementVNode("button", {
|
|
42482
|
-
type: "button",
|
|
42483
|
-
class: normalizeClass(["detail-section-toggle", { collapsed: isSectionCollapsed(section.key) }]),
|
|
42484
|
-
onClick: ($event) => toggleSection(section.key)
|
|
42485
|
-
}, [
|
|
42486
|
-
createElementVNode("span", _hoisted_21$2, [
|
|
42487
|
-
createElementVNode("span", _hoisted_22$2, toDisplayString(section.title), 1),
|
|
42488
|
-
createElementVNode("span", _hoisted_23$2, "(" + toDisplayString(section.cards.length) + ")", 1)
|
|
42489
|
-
]),
|
|
42490
|
-
createElementVNode("span", _hoisted_24$2, toDisplayString(isSectionCollapsed(section.key) ? "展开" : "收起"), 1)
|
|
42491
|
-
], 10, _hoisted_20$4),
|
|
42492
|
-
!isSectionCollapsed(section.key) && section.cards.length ? (openBlock(), createElementBlock("div", _hoisted_25$2, [
|
|
42493
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(section.cards, (card) => {
|
|
42494
|
-
return openBlock(), createElementBlock("div", {
|
|
42495
|
-
key: card.title,
|
|
42496
|
-
class: "metric-card"
|
|
42497
|
-
}, [
|
|
42498
|
-
createElementVNode("div", _hoisted_26$2, [
|
|
42499
|
-
createElementVNode("div", _hoisted_27$2, toDisplayString(card.title), 1),
|
|
42500
|
-
createElementVNode("div", _hoisted_28$2, toDisplayString(card.subtitle), 1)
|
|
42501
|
-
]),
|
|
42502
|
-
createElementVNode("div", _hoisted_29$2, [
|
|
42503
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(card.items, (item) => {
|
|
42504
|
-
return openBlock(), createElementBlock("div", {
|
|
42505
|
-
key: `${card.title}-${item.label}`,
|
|
42506
|
-
class: "metric-card-item"
|
|
42507
|
-
}, [
|
|
42508
|
-
createElementVNode("div", _hoisted_30$2, toDisplayString(item.label), 1),
|
|
42509
|
-
createElementVNode("div", _hoisted_31$1, toDisplayString(item.value), 1)
|
|
42510
|
-
]);
|
|
42511
|
-
}), 128))
|
|
42512
|
-
])
|
|
42513
|
-
]);
|
|
42514
|
-
}), 128))
|
|
42515
|
-
])) : !isSectionCollapsed(section.key) ? (openBlock(), createElementBlock("div", _hoisted_32$1, "暂无数据")) : createCommentVNode("", true)
|
|
42516
|
-
]);
|
|
42517
|
-
}), 128))
|
|
42518
|
-
])
|
|
42519
|
-
], 2)) : createCommentVNode("", true)
|
|
42520
|
-
])
|
|
42546
|
+
class: "close-confirm-option danger",
|
|
42547
|
+
onClick: withModifiers(handleEndMeeting, ["stop"])
|
|
42548
|
+
}, " 结束会议 ")) : createCommentVNode("", true),
|
|
42549
|
+
createElementVNode("div", {
|
|
42550
|
+
class: "close-confirm-option simple",
|
|
42551
|
+
onClick: withModifiers(handleLeaveMeeting, ["stop"])
|
|
42552
|
+
}, " 离开会议 "),
|
|
42553
|
+
createElementVNode("div", {
|
|
42554
|
+
class: "close-confirm-option simple",
|
|
42555
|
+
onClick: _cache[1] || (_cache[1] = ($event) => showCloseConfirm.value = false)
|
|
42556
|
+
}, " 取消 ")
|
|
42557
|
+
], 2)
|
|
42521
42558
|
]),
|
|
42522
42559
|
_: 1
|
|
42523
42560
|
}, 8, ["visible", "trigger"])
|
|
@@ -42525,40 +42562,7 @@ const _sfc_main$o = /* @__PURE__ */ defineComponent({
|
|
|
42525
42562
|
};
|
|
42526
42563
|
}
|
|
42527
42564
|
});
|
|
42528
|
-
const
|
|
42529
|
-
const _hoisted_1$l = { class: "network-copy" };
|
|
42530
|
-
const _sfc_main$n = /* @__PURE__ */ defineComponent({
|
|
42531
|
-
__name: "netWorkStatus",
|
|
42532
|
-
props: {
|
|
42533
|
-
theme: { default: "dark" }
|
|
42534
|
-
},
|
|
42535
|
-
setup(__props) {
|
|
42536
|
-
const props = __props;
|
|
42537
|
-
const themeClass = computed(() => `theme-${props.theme}`);
|
|
42538
|
-
const displayLabel = computed(() => {
|
|
42539
|
-
if (networkQualityState.isStale) {
|
|
42540
|
-
return "网络检测中";
|
|
42541
|
-
}
|
|
42542
|
-
return networkQualityState.label;
|
|
42543
|
-
});
|
|
42544
|
-
return (_ctx, _cache) => {
|
|
42545
|
-
return openBlock(), createElementBlock("div", {
|
|
42546
|
-
class: normalizeClass(["network-situation", themeClass.value])
|
|
42547
|
-
}, [
|
|
42548
|
-
createVNode(NetworkQualitySignal, {
|
|
42549
|
-
theme: _ctx.theme,
|
|
42550
|
-
size: "compact"
|
|
42551
|
-
}, null, 8, ["theme"]),
|
|
42552
|
-
createElementVNode("div", _hoisted_1$l, [
|
|
42553
|
-
createElementVNode("span", {
|
|
42554
|
-
class: normalizeClass(["network-label", `is-${unref(networkQualityState).level}`])
|
|
42555
|
-
}, toDisplayString(displayLabel.value), 3)
|
|
42556
|
-
])
|
|
42557
|
-
], 2);
|
|
42558
|
-
};
|
|
42559
|
-
}
|
|
42560
|
-
});
|
|
42561
|
-
const NetWorkStatus = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["__scopeId", "data-v-565d8abd"]]);
|
|
42565
|
+
const MeetingHeader = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["__scopeId", "data-v-2299cd2f"]]);
|
|
42562
42566
|
const _hoisted_1$k = { class: "js-dialog-content-inner" };
|
|
42563
42567
|
const _hoisted_2$j = { class: "js-dialog-content-inner-left" };
|
|
42564
42568
|
const _hoisted_3$j = { class: "js-dialog-content-inner-right" };
|
|
@@ -43443,16 +43447,18 @@ const _sfc_main$k = /* @__PURE__ */ defineComponent({
|
|
|
43443
43447
|
], 10, _hoisted_15$4)) : createCommentVNode("", true)
|
|
43444
43448
|
], 8, _hoisted_14$5)) : createCommentVNode("", true)
|
|
43445
43449
|
], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
43446
|
-
|
|
43450
|
+
member.roleType !== "5" ? (openBlock(), createBlock(SvgIcon, {
|
|
43451
|
+
key: 0,
|
|
43447
43452
|
name: (member == null ? void 0 : member.audioStatus) == "1" ? "MicrophoneIcon" : "MicrophoneSlashIcon",
|
|
43448
43453
|
size: 18,
|
|
43449
43454
|
"color-class": "device-icon"
|
|
43450
|
-
}, null, 8, ["name"]),
|
|
43451
|
-
|
|
43455
|
+
}, null, 8, ["name"])) : createCommentVNode("", true),
|
|
43456
|
+
member.roleType !== "5" ? (openBlock(), createBlock(SvgIcon, {
|
|
43457
|
+
key: 1,
|
|
43452
43458
|
name: (member == null ? void 0 : member.cameraStatus) == "1" ? "CameraIcon" : "CameraSlashIcon",
|
|
43453
43459
|
size: 18,
|
|
43454
43460
|
"color-class": "device-icon"
|
|
43455
|
-
}, null, 8, ["name"])
|
|
43461
|
+
}, null, 8, ["name"])) : createCommentVNode("", true)
|
|
43456
43462
|
], 64))
|
|
43457
43463
|
], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
43458
43464
|
unref(meState2).roleType == "1" ? (openBlock(), createElementBlock("button", {
|
|
@@ -43482,7 +43488,7 @@ const _sfc_main$k = /* @__PURE__ */ defineComponent({
|
|
|
43482
43488
|
};
|
|
43483
43489
|
}
|
|
43484
43490
|
});
|
|
43485
|
-
const ManageMembers = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["__scopeId", "data-v-
|
|
43491
|
+
const ManageMembers = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["__scopeId", "data-v-0768f591"]]);
|
|
43486
43492
|
const _hoisted_1$h = { class: "chat-container" };
|
|
43487
43493
|
const _hoisted_2$g = { class: "chat-content" };
|
|
43488
43494
|
const _hoisted_3$g = { class: "chat-meta" };
|
|
@@ -45396,7 +45402,6 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
|
|
|
45396
45402
|
});
|
|
45397
45403
|
};
|
|
45398
45404
|
const leaveMeeting = () => {
|
|
45399
|
-
console.log(111111111111111);
|
|
45400
45405
|
getLoading().show();
|
|
45401
45406
|
const meetingInfo = JSON.parse(
|
|
45402
45407
|
sessionStorage.getItem("JS_MEETING_INFO") || "{}"
|
|
@@ -45540,7 +45545,7 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
|
|
|
45540
45545
|
};
|
|
45541
45546
|
}
|
|
45542
45547
|
});
|
|
45543
|
-
const JSMeeting = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["__scopeId", "data-v-
|
|
45548
|
+
const JSMeeting = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["__scopeId", "data-v-2efb7c64"]]);
|
|
45544
45549
|
const _hoisted_1$8 = { class: "modal" };
|
|
45545
45550
|
const _hoisted_2$8 = { class: "modal-header" };
|
|
45546
45551
|
const _hoisted_3$8 = { class: "tab-header" };
|