@ai-matrx/meet 0.11.29 → 0.11.30
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/CHANGELOG.md +2 -2
- package/dist/core.cjs +407 -30
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +186 -5
- package/dist/core.d.ts +186 -5
- package/dist/core.js +407 -30
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +407 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +407 -30
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +498 -30
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +1 -9
- package/dist/react.d.ts +1 -9
- package/dist/react.js +498 -30
- package/dist/react.js.map +1 -1
- package/dist/skins/meet.cjs +250 -22
- package/dist/skins/meet.cjs.map +1 -1
- package/dist/skins/meet.js +250 -22
- package/dist/skins/meet.js.map +1 -1
- package/dist/styles.css +46 -0
- package/package.json +4 -4
package/dist/react.cjs
CHANGED
|
@@ -50,6 +50,7 @@ __export(react_exports, {
|
|
|
50
50
|
GUEST_RECORD_NOT_SHARED: () => GUEST_RECORD_NOT_SHARED,
|
|
51
51
|
GuestRecordAccessControl: () => GuestRecordAccessControl,
|
|
52
52
|
IDLE_MEDIA: () => IDLE_MEDIA,
|
|
53
|
+
IDLE_MEDIA_REGION: () => IDLE_MEDIA_REGION,
|
|
53
54
|
IDLE_PHASES: () => IDLE_PHASES,
|
|
54
55
|
IDLE_TRACK: () => IDLE_TRACK,
|
|
55
56
|
IncomingCallCard: () => IncomingCallCard,
|
|
@@ -129,6 +130,7 @@ __export(react_exports, {
|
|
|
129
130
|
captionSegment: () => captionSegment,
|
|
130
131
|
captureHeldOf: () => captureHeldOf,
|
|
131
132
|
changesPatch: () => changesPatch,
|
|
133
|
+
classifyDeviceFailure: () => classifyDeviceFailure,
|
|
132
134
|
clockPosition: () => clockPosition,
|
|
133
135
|
collabFromState: () => collabFromState,
|
|
134
136
|
computeStage: () => computeStage,
|
|
@@ -140,6 +142,7 @@ __export(react_exports, {
|
|
|
140
142
|
createDeviceManager: () => createDeviceManager,
|
|
141
143
|
createInRoomClient: () => createInRoomClient,
|
|
142
144
|
createLiveKitDriver: () => createLiveKitDriver,
|
|
145
|
+
createMediaSupervisor: () => createMediaSupervisor,
|
|
143
146
|
createMeetAi: () => createMeetAi,
|
|
144
147
|
createMeetApi: () => createMeetApi,
|
|
145
148
|
createMeetRepository: () => createMeetRepository,
|
|
@@ -159,6 +162,12 @@ __export(react_exports, {
|
|
|
159
162
|
createWebResumeStorage: () => createWebResumeStorage,
|
|
160
163
|
createWebRoomTokenStorage: () => createWebRoomTokenStorage,
|
|
161
164
|
defaultCaptionLanguage: () => defaultCaptionLanguage,
|
|
165
|
+
detectBrowser: () => detectBrowser,
|
|
166
|
+
detectOs: () => detectOs,
|
|
167
|
+
deviceChipLabel: () => deviceChipLabel,
|
|
168
|
+
deviceFixSteps: () => deviceFixSteps,
|
|
169
|
+
deviceNoticeCode: () => deviceNoticeCode,
|
|
170
|
+
deviceUnavailableReason: () => deviceUnavailableReason,
|
|
162
171
|
displayNameFor: () => displayNameFor,
|
|
163
172
|
fileDownloadPath: () => fileDownloadPath,
|
|
164
173
|
focusFromRow: () => focusFromRow,
|
|
@@ -315,6 +324,7 @@ __export(react_exports, {
|
|
|
315
324
|
useTrack: () => useTrack,
|
|
316
325
|
userTopic: () => userTopic,
|
|
317
326
|
wasRefused: () => wasRefused,
|
|
327
|
+
webMediaPlatform: () => webMediaPlatform,
|
|
318
328
|
withItem: () => withItem,
|
|
319
329
|
wrapUpStatus: () => wrapUpStatus
|
|
320
330
|
});
|
|
@@ -2489,13 +2499,19 @@ function recordingLabel(state) {
|
|
|
2489
2499
|
}
|
|
2490
2500
|
|
|
2491
2501
|
// src/core/attendance.ts
|
|
2502
|
+
var IDLE_MEDIA_REGION = {
|
|
2503
|
+
permission: { microphone: "unknown", camera: "unknown" },
|
|
2504
|
+
audioOutput: "ok",
|
|
2505
|
+
notice: null,
|
|
2506
|
+
offer: null
|
|
2507
|
+
};
|
|
2492
2508
|
var IDLE_TRACK = { enabled: false, unavailable: null };
|
|
2493
2509
|
var IDLE_MEDIA = {
|
|
2494
2510
|
microphone: IDLE_TRACK,
|
|
2495
2511
|
camera: IDLE_TRACK
|
|
2496
2512
|
};
|
|
2497
|
-
function unavailableFrom(error) {
|
|
2498
|
-
return { code: error.code, message: error.message, remedy: error.remedy };
|
|
2513
|
+
function unavailableFrom(error, reason) {
|
|
2514
|
+
return reason === void 0 ? { code: error.code, message: error.message, remedy: error.remedy } : { code: error.code, message: error.message, remedy: error.remedy, reason };
|
|
2499
2515
|
}
|
|
2500
2516
|
var LISTEN_ONLY_NOTICE = "You're attending without a microphone \u2014 others can't hear you";
|
|
2501
2517
|
function isListenOnly(media) {
|
|
@@ -3943,6 +3959,7 @@ var EMPTY = {
|
|
|
3943
3959
|
wrapUp: null,
|
|
3944
3960
|
noteTakerRefusal: null,
|
|
3945
3961
|
media: IDLE_MEDIA,
|
|
3962
|
+
mediaRegion: IDLE_MEDIA_REGION,
|
|
3946
3963
|
failure: null,
|
|
3947
3964
|
collab: EMPTY_COLLAB,
|
|
3948
3965
|
breakoutRoomId: null
|
|
@@ -4160,7 +4177,7 @@ function createMeetStore(initial = {}) {
|
|
|
4160
4177
|
},
|
|
4161
4178
|
setLocalTrack(kind, next) {
|
|
4162
4179
|
const current = state.media[kind];
|
|
4163
|
-
if (current.enabled === next.enabled && current.unavailable?.code === next.unavailable?.code && current.unavailable?.message === next.unavailable?.message) {
|
|
4180
|
+
if (current.enabled === next.enabled && current.unavailable?.code === next.unavailable?.code && current.unavailable?.reason === next.unavailable?.reason && current.unavailable?.message === next.unavailable?.message) {
|
|
4164
4181
|
return;
|
|
4165
4182
|
}
|
|
4166
4183
|
commit({ ...state, media: { ...state.media, [kind]: next } });
|
|
@@ -4745,6 +4762,342 @@ function createMeetSessionIdentity(options) {
|
|
|
4745
4762
|
});
|
|
4746
4763
|
}
|
|
4747
4764
|
|
|
4765
|
+
// src/core/media-supervisor.ts
|
|
4766
|
+
function classifyDeviceFailure(error, permission) {
|
|
4767
|
+
if (permission === "denied") return "denied";
|
|
4768
|
+
switch (error.code) {
|
|
4769
|
+
case "permission-denied":
|
|
4770
|
+
if (/by system/i.test(error.message) || permission === "granted") return "blocked_os";
|
|
4771
|
+
return "denied";
|
|
4772
|
+
case "device-not-found":
|
|
4773
|
+
return "none";
|
|
4774
|
+
case "device-in-use":
|
|
4775
|
+
return "busy";
|
|
4776
|
+
case "insecure-context":
|
|
4777
|
+
return "blocked_site";
|
|
4778
|
+
default:
|
|
4779
|
+
return "failed";
|
|
4780
|
+
}
|
|
4781
|
+
}
|
|
4782
|
+
function deviceNoticeCode(kind, reason) {
|
|
4783
|
+
if (reason === "denied" || reason === "blocked_site" || reason === "blocked_os") {
|
|
4784
|
+
return kind === "microphone" ? "mic-blocked" : "camera-blocked";
|
|
4785
|
+
}
|
|
4786
|
+
return "device-lost";
|
|
4787
|
+
}
|
|
4788
|
+
function deviceUnavailableReason(track, permission) {
|
|
4789
|
+
if (track.enabled) return null;
|
|
4790
|
+
if (permission === "denied") return "denied";
|
|
4791
|
+
const refused = track.unavailable;
|
|
4792
|
+
if (refused === null) return null;
|
|
4793
|
+
return refused.reason ?? classifyDeviceFailure({ code: refused.code, message: refused.message }, permission);
|
|
4794
|
+
}
|
|
4795
|
+
function deviceChipLabel(kind, reason) {
|
|
4796
|
+
const what = kind === "microphone" ? "Mic" : "Camera";
|
|
4797
|
+
switch (reason) {
|
|
4798
|
+
case "denied":
|
|
4799
|
+
case "blocked_site":
|
|
4800
|
+
case "blocked_os":
|
|
4801
|
+
return `${what} blocked`;
|
|
4802
|
+
case "none":
|
|
4803
|
+
return kind === "microphone" ? "No microphone found" : "No camera found";
|
|
4804
|
+
case "busy":
|
|
4805
|
+
return `${what} in use by another app`;
|
|
4806
|
+
case "revoked":
|
|
4807
|
+
return `${what} access was turned off`;
|
|
4808
|
+
default:
|
|
4809
|
+
return `${what} didn't start`;
|
|
4810
|
+
}
|
|
4811
|
+
}
|
|
4812
|
+
function deviceFixSteps(kind, reason, where) {
|
|
4813
|
+
const device = kind === "microphone" ? "Microphone" : "Camera";
|
|
4814
|
+
const lower = device.toLowerCase();
|
|
4815
|
+
switch (reason) {
|
|
4816
|
+
case "denied":
|
|
4817
|
+
case "revoked":
|
|
4818
|
+
case "blocked_site":
|
|
4819
|
+
switch (where.browser) {
|
|
4820
|
+
case "firefox":
|
|
4821
|
+
return [`Click the crossed-out ${lower} icon in the address bar`, "Clear the Blocked setting", "Press Try again and choose Allow"];
|
|
4822
|
+
case "safari":
|
|
4823
|
+
return where.os === "ios" ? [`Settings \u203A Apps \u203A Safari \u203A ${device}`, "Choose Allow", "Return here and press Try again"] : ["Safari \u203A Settings for This Website", `Set ${device} to Allow`, "Press Try again"];
|
|
4824
|
+
default:
|
|
4825
|
+
return ["Click the icon left of the web address", `Set ${device} to Allow`, "Press Try again"];
|
|
4826
|
+
}
|
|
4827
|
+
case "blocked_os": {
|
|
4828
|
+
const app = where.browser === "chrome" ? "Google Chrome" : where.browser === "edge" ? "Microsoft Edge" : where.browser === "firefox" ? "Firefox" : "your browser";
|
|
4829
|
+
if (where.os === "mac") return [`System Settings \u203A Privacy & Security \u203A ${device}`, `Turn on ${app}`, "Reopen the browser if asked, then Try again"];
|
|
4830
|
+
if (where.os === "windows") return [`Settings \u203A Privacy & security \u203A ${device}`, `Turn on ${device} access for apps`, "Press Try again"];
|
|
4831
|
+
return [`Allow ${lower} access for ${app} in your system settings`, "Press Try again"];
|
|
4832
|
+
}
|
|
4833
|
+
case "busy":
|
|
4834
|
+
return [`Close other apps using the ${lower} (Zoom, Teams, another tab)`, "Press Try again"];
|
|
4835
|
+
case "none":
|
|
4836
|
+
return [`Connect a ${lower}`, "Press Try again"];
|
|
4837
|
+
default:
|
|
4838
|
+
return [`Pick another ${lower} in Settings`, "Press Try again"];
|
|
4839
|
+
}
|
|
4840
|
+
}
|
|
4841
|
+
function detectBrowser(userAgent) {
|
|
4842
|
+
if (/Edg\//.test(userAgent)) return "edge";
|
|
4843
|
+
if (/Firefox\//.test(userAgent)) return "firefox";
|
|
4844
|
+
if (/Chrome\/|Chromium\/|CriOS\//.test(userAgent)) return "chrome";
|
|
4845
|
+
if (/Safari\//.test(userAgent)) return "safari";
|
|
4846
|
+
return "other";
|
|
4847
|
+
}
|
|
4848
|
+
function detectOs(userAgent, maxTouchPoints = 0) {
|
|
4849
|
+
if (/iPhone|iPad|iPod/.test(userAgent)) return "ios";
|
|
4850
|
+
if (/Macintosh/.test(userAgent)) return maxTouchPoints > 1 ? "ios" : "mac";
|
|
4851
|
+
if (/Android/.test(userAgent)) return "android";
|
|
4852
|
+
if (/Windows/.test(userAgent)) return "windows";
|
|
4853
|
+
if (/Linux|CrOS/.test(userAgent)) return "linux";
|
|
4854
|
+
return "other";
|
|
4855
|
+
}
|
|
4856
|
+
function webMediaPlatform() {
|
|
4857
|
+
const scope = globalThis;
|
|
4858
|
+
const nav = scope.navigator;
|
|
4859
|
+
if (nav === void 0) return null;
|
|
4860
|
+
const ua = nav.userAgent ?? "";
|
|
4861
|
+
const reading = (state) => state === "granted" || state === "denied" || state === "prompt" ? state : "unknown";
|
|
4862
|
+
const query = async (kind) => {
|
|
4863
|
+
try {
|
|
4864
|
+
return await nav.permissions?.query({ name: kind }) ?? null;
|
|
4865
|
+
} catch {
|
|
4866
|
+
return null;
|
|
4867
|
+
}
|
|
4868
|
+
};
|
|
4869
|
+
return {
|
|
4870
|
+
browser: detectBrowser(ua),
|
|
4871
|
+
os: detectOs(ua, nav.maxTouchPoints ?? 0),
|
|
4872
|
+
async queryPermission(kind) {
|
|
4873
|
+
return reading((await query(kind))?.state);
|
|
4874
|
+
},
|
|
4875
|
+
watchPermission(kind, onChange) {
|
|
4876
|
+
let status = null;
|
|
4877
|
+
let stopped = false;
|
|
4878
|
+
void query(kind).then((found) => {
|
|
4879
|
+
if (stopped || found === null) return;
|
|
4880
|
+
status = found;
|
|
4881
|
+
found.onchange = () => onChange(reading(found.state));
|
|
4882
|
+
});
|
|
4883
|
+
return () => {
|
|
4884
|
+
stopped = true;
|
|
4885
|
+
if (status !== null) status.onchange = null;
|
|
4886
|
+
};
|
|
4887
|
+
},
|
|
4888
|
+
async listDevices() {
|
|
4889
|
+
try {
|
|
4890
|
+
return await nav.mediaDevices?.enumerateDevices() ?? [];
|
|
4891
|
+
} catch {
|
|
4892
|
+
return [];
|
|
4893
|
+
}
|
|
4894
|
+
},
|
|
4895
|
+
onVisible(callback) {
|
|
4896
|
+
const doc = scope.document;
|
|
4897
|
+
if (doc === void 0) return () => void 0;
|
|
4898
|
+
const handler = () => {
|
|
4899
|
+
if (doc.visibilityState === "visible") callback();
|
|
4900
|
+
};
|
|
4901
|
+
doc.addEventListener("visibilitychange", handler);
|
|
4902
|
+
return () => doc.removeEventListener("visibilitychange", handler);
|
|
4903
|
+
}
|
|
4904
|
+
};
|
|
4905
|
+
}
|
|
4906
|
+
var INPUT_KIND = { microphone: "audioinput", camera: "videoinput" };
|
|
4907
|
+
function isAlias(deviceId2) {
|
|
4908
|
+
return deviceId2 === "default" || deviceId2 === "communications" || deviceId2 === "";
|
|
4909
|
+
}
|
|
4910
|
+
function createMediaSupervisor(options) {
|
|
4911
|
+
const { store, platform } = options;
|
|
4912
|
+
let unsubscribers = [];
|
|
4913
|
+
let started = false;
|
|
4914
|
+
let noticeId = 0;
|
|
4915
|
+
let known = null;
|
|
4916
|
+
let inUse = { audioinput: null, videoinput: null };
|
|
4917
|
+
function region() {
|
|
4918
|
+
return store.snapshot().mediaRegion;
|
|
4919
|
+
}
|
|
4920
|
+
function setRegion(next) {
|
|
4921
|
+
const current = region();
|
|
4922
|
+
const merged = { ...current, ...next };
|
|
4923
|
+
if (merged.audioOutput === current.audioOutput && merged.notice === current.notice && merged.offer === current.offer && merged.permission.microphone === current.permission.microphone && merged.permission.camera === current.permission.camera) {
|
|
4924
|
+
return;
|
|
4925
|
+
}
|
|
4926
|
+
store.patch({ mediaRegion: merged });
|
|
4927
|
+
}
|
|
4928
|
+
function setPermission(kind, reading) {
|
|
4929
|
+
const current = region().permission;
|
|
4930
|
+
if (current[kind] === reading) return;
|
|
4931
|
+
setRegion({ permission: { ...current, [kind]: reading } });
|
|
4932
|
+
const track = store.snapshot().media[kind];
|
|
4933
|
+
if (reading === "granted" && !track.enabled && track.unavailable?.reason === "denied") {
|
|
4934
|
+
store.setLocalTrack(kind, {
|
|
4935
|
+
enabled: false,
|
|
4936
|
+
unavailable: { ...track.unavailable, reason: "failed", remedy: "Access is allowed now. Press Try again." }
|
|
4937
|
+
});
|
|
4938
|
+
}
|
|
4939
|
+
}
|
|
4940
|
+
async function snapshotDevices() {
|
|
4941
|
+
const list = platform === null ? [] : await platform.listDevices();
|
|
4942
|
+
const out = { audioinput: /* @__PURE__ */ new Map(), videoinput: /* @__PURE__ */ new Map() };
|
|
4943
|
+
for (const device of list) {
|
|
4944
|
+
if (device.kind === "audioinput" || device.kind === "videoinput") out[device.kind].set(device.deviceId, device.label);
|
|
4945
|
+
}
|
|
4946
|
+
return out;
|
|
4947
|
+
}
|
|
4948
|
+
function readInUse() {
|
|
4949
|
+
const driver = options.driver();
|
|
4950
|
+
if (driver === null) return;
|
|
4951
|
+
const active = driver.activeDevices();
|
|
4952
|
+
inUse = { audioinput: active.audioinput, videoinput: active.videoinput };
|
|
4953
|
+
}
|
|
4954
|
+
async function handleDevicesChanged() {
|
|
4955
|
+
if (platform === null) return;
|
|
4956
|
+
const before = known;
|
|
4957
|
+
const now = await snapshotDevices();
|
|
4958
|
+
known = now;
|
|
4959
|
+
const driver = options.driver();
|
|
4960
|
+
if (driver === null || before === null) {
|
|
4961
|
+
readInUse();
|
|
4962
|
+
return;
|
|
4963
|
+
}
|
|
4964
|
+
for (const kind of ["microphone", "camera"]) {
|
|
4965
|
+
const deviceKind = INPUT_KIND[kind];
|
|
4966
|
+
const previous = inUse[deviceKind];
|
|
4967
|
+
const track = store.snapshot().media[kind];
|
|
4968
|
+
const gone = previous !== null && !isAlias(previous) && before[deviceKind].has(previous) && !now[deviceKind].has(previous);
|
|
4969
|
+
if (gone) {
|
|
4970
|
+
const from = before[deviceKind].get(previous) ?? "";
|
|
4971
|
+
const remaining = [...now[deviceKind].entries()].filter(([id]) => !isAlias(id));
|
|
4972
|
+
if (remaining.length === 0) {
|
|
4973
|
+
store.setLocalTrack(kind, {
|
|
4974
|
+
enabled: false,
|
|
4975
|
+
unavailable: {
|
|
4976
|
+
code: "device-not-found",
|
|
4977
|
+
message: `meet.${kind}: the ${kind} was disconnected and no other is connected`,
|
|
4978
|
+
remedy: `Connect a ${kind === "microphone" ? "microphone" : "camera"}, then press Try again.`,
|
|
4979
|
+
reason: "none"
|
|
4980
|
+
}
|
|
4981
|
+
});
|
|
4982
|
+
setRegion({ notice: { id: ++noticeId, kind, outcome: "lost", from, to: null } });
|
|
4983
|
+
continue;
|
|
4984
|
+
}
|
|
4985
|
+
if (kind === "camera") {
|
|
4986
|
+
const [nextId, nextLabel] = remaining[0];
|
|
4987
|
+
try {
|
|
4988
|
+
await driver.switchDevice("videoinput", nextId);
|
|
4989
|
+
if (track.enabled || track.unavailable !== null) {
|
|
4990
|
+
await driver.setCameraEnabled(true);
|
|
4991
|
+
store.setLocalTrack("camera", { enabled: true, unavailable: null });
|
|
4992
|
+
}
|
|
4993
|
+
setRegion({ notice: { id: ++noticeId, kind, outcome: "switched", from, to: nextLabel } });
|
|
4994
|
+
} catch (error) {
|
|
4995
|
+
const refused = await unavailable(error, "camera", "meet.camera(fallback)");
|
|
4996
|
+
store.setLocalTrack("camera", { enabled: false, unavailable: refused });
|
|
4997
|
+
setRegion({ notice: { id: ++noticeId, kind, outcome: "lost", from, to: null } });
|
|
4998
|
+
}
|
|
4999
|
+
} else {
|
|
5000
|
+
const active = driver.activeDevices().audioinput;
|
|
5001
|
+
const to = (active !== null ? now.audioinput.get(active) : void 0) ?? now.audioinput.get("default") ?? remaining[0][1];
|
|
5002
|
+
setRegion({ notice: { id: ++noticeId, kind, outcome: "switched", from, to } });
|
|
5003
|
+
}
|
|
5004
|
+
continue;
|
|
5005
|
+
}
|
|
5006
|
+
const added = [...now[deviceKind].entries()].find(([id]) => !isAlias(id) && !before[deviceKind].has(id));
|
|
5007
|
+
if (added !== void 0 && added[0] !== driver.activeDevices()[deviceKind]) {
|
|
5008
|
+
setRegion({ offer: { kind, deviceId: added[0], label: added[1] } });
|
|
5009
|
+
}
|
|
5010
|
+
}
|
|
5011
|
+
readInUse();
|
|
5012
|
+
}
|
|
5013
|
+
async function unavailable(error, kind, operation) {
|
|
5014
|
+
const normalized = normalizeDeviceError(error, operation);
|
|
5015
|
+
const permission = platform === null ? "unknown" : await platform.queryPermission(kind);
|
|
5016
|
+
if (permission !== "unknown") setPermission(kind, permission);
|
|
5017
|
+
return unavailableFrom(normalized, classifyDeviceFailure(normalized, permission));
|
|
5018
|
+
}
|
|
5019
|
+
return {
|
|
5020
|
+
start() {
|
|
5021
|
+
if (started || platform === null) return;
|
|
5022
|
+
started = true;
|
|
5023
|
+
for (const kind of ["microphone", "camera"]) {
|
|
5024
|
+
void platform.queryPermission(kind).then((reading) => setPermission(kind, reading));
|
|
5025
|
+
unsubscribers.push(platform.watchPermission(kind, (reading) => setPermission(kind, reading)));
|
|
5026
|
+
}
|
|
5027
|
+
unsubscribers.push(
|
|
5028
|
+
platform.onVisible(() => {
|
|
5029
|
+
const driver = options.driver();
|
|
5030
|
+
if (driver?.startAudio === void 0 || region().audioOutput !== "blocked") return;
|
|
5031
|
+
driver.startAudio().catch(() => void 0);
|
|
5032
|
+
})
|
|
5033
|
+
);
|
|
5034
|
+
},
|
|
5035
|
+
stop() {
|
|
5036
|
+
for (const off of unsubscribers) off();
|
|
5037
|
+
unsubscribers = [];
|
|
5038
|
+
started = false;
|
|
5039
|
+
},
|
|
5040
|
+
unavailable,
|
|
5041
|
+
onAudioPlayback(canPlay) {
|
|
5042
|
+
setRegion({ audioOutput: canPlay ? "ok" : "blocked" });
|
|
5043
|
+
},
|
|
5044
|
+
onDevicesChanged() {
|
|
5045
|
+
void handleDevicesChanged().catch((error) => {
|
|
5046
|
+
options.report("warn", `meet: device change could not be handled: ${String(error)}`, "Pick the device in Settings.");
|
|
5047
|
+
});
|
|
5048
|
+
},
|
|
5049
|
+
onDeviceError(error, deviceKind) {
|
|
5050
|
+
if (deviceKind === null) return;
|
|
5051
|
+
const kind = deviceKind === "audioinput" ? "microphone" : "camera";
|
|
5052
|
+
void unavailable(error, kind, `meet.${kind}`).then((refused) => {
|
|
5053
|
+
const track = store.snapshot().media[kind];
|
|
5054
|
+
if (track.enabled) return;
|
|
5055
|
+
store.setLocalTrack(kind, { enabled: false, unavailable: refused });
|
|
5056
|
+
});
|
|
5057
|
+
},
|
|
5058
|
+
onConnected() {
|
|
5059
|
+
void snapshotDevices().then((now) => {
|
|
5060
|
+
known = now;
|
|
5061
|
+
readInUse();
|
|
5062
|
+
});
|
|
5063
|
+
},
|
|
5064
|
+
onDisconnected() {
|
|
5065
|
+
known = null;
|
|
5066
|
+
inUse = { audioinput: null, videoinput: null };
|
|
5067
|
+
setRegion({ audioOutput: "ok", notice: null, offer: null });
|
|
5068
|
+
},
|
|
5069
|
+
async enableAudio() {
|
|
5070
|
+
const driver = options.driver();
|
|
5071
|
+
if (driver?.startAudio === void 0) return;
|
|
5072
|
+
try {
|
|
5073
|
+
await driver.startAudio();
|
|
5074
|
+
setRegion({ audioOutput: "ok" });
|
|
5075
|
+
} catch (error) {
|
|
5076
|
+
options.report("warn", `meet: sound could not be enabled: ${String(error)}`, "Click Enable sound again, or check the tab is not muted.");
|
|
5077
|
+
}
|
|
5078
|
+
},
|
|
5079
|
+
async acceptOffer() {
|
|
5080
|
+
const offer = region().offer;
|
|
5081
|
+
const driver = options.driver();
|
|
5082
|
+
setRegion({ offer: null });
|
|
5083
|
+
if (offer === null || driver === null) return;
|
|
5084
|
+
try {
|
|
5085
|
+
await driver.switchDevice(INPUT_KIND[offer.kind], offer.deviceId);
|
|
5086
|
+
readInUse();
|
|
5087
|
+
} catch (error) {
|
|
5088
|
+
const refused = await unavailable(error, offer.kind, "meet.switchDevice");
|
|
5089
|
+
options.report("warn", refused.message, refused.remedy);
|
|
5090
|
+
}
|
|
5091
|
+
},
|
|
5092
|
+
dismissOffer() {
|
|
5093
|
+
setRegion({ offer: null });
|
|
5094
|
+
},
|
|
5095
|
+
dismissNotice() {
|
|
5096
|
+
setRegion({ notice: null });
|
|
5097
|
+
}
|
|
5098
|
+
};
|
|
5099
|
+
}
|
|
5100
|
+
|
|
4748
5101
|
// src/core/room-events.ts
|
|
4749
5102
|
var RECORDING_STATES = [
|
|
4750
5103
|
"idle",
|
|
@@ -5199,9 +5552,9 @@ function createRoomEngine(options) {
|
|
|
5199
5552
|
const departures = /* @__PURE__ */ new Map();
|
|
5200
5553
|
function requestAsNow() {
|
|
5201
5554
|
if (lastRequest === null) return null;
|
|
5202
|
-
const
|
|
5555
|
+
const media2 = store.snapshot().media;
|
|
5203
5556
|
if (store.snapshot().phase !== "in_call") return lastRequest;
|
|
5204
|
-
return { ...lastRequest, mode:
|
|
5557
|
+
return { ...lastRequest, mode: media2.camera.enabled ? "video" : "audio", microphone: media2.microphone.enabled };
|
|
5205
5558
|
}
|
|
5206
5559
|
async function dropRoom() {
|
|
5207
5560
|
const target = driver;
|
|
@@ -5212,6 +5565,7 @@ function createRoomEngine(options) {
|
|
|
5212
5565
|
}
|
|
5213
5566
|
store.setLocalTrack("microphone", IDLE_TRACK);
|
|
5214
5567
|
store.setLocalTrack("camera", IDLE_TRACK);
|
|
5568
|
+
media.onDisconnected();
|
|
5215
5569
|
store.patch({ share: NO_SHARE, connection: "stable" });
|
|
5216
5570
|
clearGhosts();
|
|
5217
5571
|
await target?.disconnect();
|
|
@@ -5277,7 +5631,22 @@ function createRoomEngine(options) {
|
|
|
5277
5631
|
report("error", normalized.message, normalized.remedy);
|
|
5278
5632
|
return normalized;
|
|
5279
5633
|
}
|
|
5634
|
+
const media = createMediaSupervisor({
|
|
5635
|
+
store,
|
|
5636
|
+
platform: options.mediaPlatform === void 0 ? webMediaPlatform() : options.mediaPlatform,
|
|
5637
|
+
driver: () => driver,
|
|
5638
|
+
report
|
|
5639
|
+
});
|
|
5280
5640
|
const handlers = {
|
|
5641
|
+
audioPlayback(canPlay) {
|
|
5642
|
+
media.onAudioPlayback(canPlay);
|
|
5643
|
+
},
|
|
5644
|
+
devicesChanged() {
|
|
5645
|
+
media.onDevicesChanged();
|
|
5646
|
+
},
|
|
5647
|
+
mediaDeviceError(error, kind) {
|
|
5648
|
+
media.onDeviceError(error, kind);
|
|
5649
|
+
},
|
|
5281
5650
|
participants(list) {
|
|
5282
5651
|
const joinedAt = new Date(now()).toISOString();
|
|
5283
5652
|
const before = new Set(store.snapshot().participants.map((p) => p.identity));
|
|
@@ -5543,6 +5912,7 @@ function createRoomEngine(options) {
|
|
|
5543
5912
|
store.dispatch({ type: "connected" });
|
|
5544
5913
|
store.setLocalTrack("microphone", IDLE_TRACK);
|
|
5545
5914
|
store.setLocalTrack("camera", IDLE_TRACK);
|
|
5915
|
+
media.start();
|
|
5546
5916
|
const effects = options.effectsStorage?.load() ?? store.snapshot().effects;
|
|
5547
5917
|
store.patch({ effects });
|
|
5548
5918
|
if (!effects.noiseSuppression || effects.background !== "none") {
|
|
@@ -5567,6 +5937,7 @@ function createRoomEngine(options) {
|
|
|
5567
5937
|
if (request.microphone !== false) {
|
|
5568
5938
|
await enableTrack(created, "microphone", true);
|
|
5569
5939
|
}
|
|
5940
|
+
media.onConnected();
|
|
5570
5941
|
}
|
|
5571
5942
|
async function enableTrack(target, kind, enabled) {
|
|
5572
5943
|
try {
|
|
@@ -5576,10 +5947,10 @@ function createRoomEngine(options) {
|
|
|
5576
5947
|
store.setLocalTrack(kind, state);
|
|
5577
5948
|
return state;
|
|
5578
5949
|
} catch (error) {
|
|
5579
|
-
const
|
|
5580
|
-
const state = { enabled: false, unavailable:
|
|
5950
|
+
const refused = await media.unavailable(error, kind, `meet.${kind}`);
|
|
5951
|
+
const state = { enabled: false, unavailable: refused };
|
|
5581
5952
|
store.setLocalTrack(kind, state);
|
|
5582
|
-
report("warn",
|
|
5953
|
+
report("warn", refused.message, refused.remedy);
|
|
5583
5954
|
return state;
|
|
5584
5955
|
}
|
|
5585
5956
|
}
|
|
@@ -5888,6 +6259,10 @@ function createRoomEngine(options) {
|
|
|
5888
6259
|
if (driver === null) return;
|
|
5889
6260
|
await driver.switchDevice(kind, deviceId2);
|
|
5890
6261
|
},
|
|
6262
|
+
enableAudio: () => media.enableAudio(),
|
|
6263
|
+
acceptDeviceOffer: () => media.acceptOffer(),
|
|
6264
|
+
dismissDeviceOffer: () => media.dismissOffer(),
|
|
6265
|
+
dismissDeviceNotice: () => media.dismissNotice(),
|
|
5891
6266
|
pin(who) {
|
|
5892
6267
|
store.patch({ pinned: who, layout: who === null ? "grid" : "speaker" });
|
|
5893
6268
|
},
|
|
@@ -5902,6 +6277,7 @@ function createRoomEngine(options) {
|
|
|
5902
6277
|
async dispose() {
|
|
5903
6278
|
disposed = true;
|
|
5904
6279
|
supervisor.dispose();
|
|
6280
|
+
media.stop();
|
|
5905
6281
|
clearGhosts();
|
|
5906
6282
|
if (driver !== null) {
|
|
5907
6283
|
const target = driver;
|
|
@@ -6335,6 +6711,12 @@ function createLiveKitDriver(handlers, options = {}) {
|
|
|
6335
6711
|
roster();
|
|
6336
6712
|
}).on(RoomEvent.TrackSubscribed, roster).on(RoomEvent.TrackUnsubscribed, roster).on(RoomEvent.TrackMuted, roster).on(RoomEvent.TrackUnmuted, roster).on(RoomEvent.LocalTrackPublished, roster).on(RoomEvent.LocalTrackUnpublished, roster).on(RoomEvent.ParticipantNameChanged, roster).on(RoomEvent.ParticipantAttributesChanged, roster).on(RoomEvent.ParticipantMetadataChanged, roster).on(RoomEvent.RoomMetadataChanged, (metadata) => {
|
|
6337
6713
|
handlers.roomMetadata?.(metadata ?? "");
|
|
6714
|
+
}).on(RoomEvent.AudioPlaybackStatusChanged, (canPlay) => {
|
|
6715
|
+
handlers.audioPlayback?.(canPlay);
|
|
6716
|
+
}).on(RoomEvent.MediaDevicesChanged, () => {
|
|
6717
|
+
handlers.devicesChanged?.();
|
|
6718
|
+
}).on(RoomEvent.MediaDevicesError, (error, kind) => {
|
|
6719
|
+
handlers.mediaDeviceError?.(error, kind === "audioinput" || kind === "videoinput" ? kind : null);
|
|
6338
6720
|
}).on(RoomEvent.ActiveSpeakersChanged, (speakers) => {
|
|
6339
6721
|
handlers.activeSpeakers(speakers.map((speaker) => speaker.identity));
|
|
6340
6722
|
}).on(RoomEvent.ConnectionQualityChanged, (quality, participant) => {
|
|
@@ -6431,6 +6813,7 @@ function createLiveKitDriver(handlers, options = {}) {
|
|
|
6431
6813
|
}
|
|
6432
6814
|
projectRoster?.();
|
|
6433
6815
|
handlers.roomMetadata?.(target.metadata ?? "");
|
|
6816
|
+
handlers.audioPlayback?.(target.canPlaybackAudio);
|
|
6434
6817
|
},
|
|
6435
6818
|
async disconnect() {
|
|
6436
6819
|
if (room === null) return;
|
|
@@ -6557,6 +6940,11 @@ function createLiveKitDriver(handlers, options = {}) {
|
|
|
6557
6940
|
} catch (error) {
|
|
6558
6941
|
throw normalizeDeviceError(error, "meet.switchDevice");
|
|
6559
6942
|
}
|
|
6943
|
+
},
|
|
6944
|
+
async startAudio() {
|
|
6945
|
+
const target = room;
|
|
6946
|
+
if (target === null) return;
|
|
6947
|
+
await target.startAudio();
|
|
6560
6948
|
}
|
|
6561
6949
|
};
|
|
6562
6950
|
}
|
|
@@ -6964,22 +7352,10 @@ function observedRole(role, standing) {
|
|
|
6964
7352
|
if (role === "host" || role === "cohost") return role;
|
|
6965
7353
|
return isLinkFollower(standing) ? "guest" : "participant";
|
|
6966
7354
|
}
|
|
6967
|
-
function observedDevice(track) {
|
|
7355
|
+
function observedDevice(track, permission = "unknown") {
|
|
6968
7356
|
if (track.enabled) return "on";
|
|
6969
|
-
const
|
|
6970
|
-
|
|
6971
|
-
switch (refused.code) {
|
|
6972
|
-
case "permission-denied":
|
|
6973
|
-
return "unavailable:denied";
|
|
6974
|
-
case "device-not-found":
|
|
6975
|
-
return "unavailable:none";
|
|
6976
|
-
case "device-in-use":
|
|
6977
|
-
return "unavailable:busy";
|
|
6978
|
-
case "insecure-context":
|
|
6979
|
-
return "unavailable:blocked_site";
|
|
6980
|
-
default:
|
|
6981
|
-
return "unavailable:failed";
|
|
6982
|
-
}
|
|
7357
|
+
const reason = deviceUnavailableReason(track, permission);
|
|
7358
|
+
return reason === null ? "muted_by_me" : `unavailable:${reason}`;
|
|
6983
7359
|
}
|
|
6984
7360
|
function endedRecord(snapshot, given) {
|
|
6985
7361
|
const record = snapshot?.meeting ?? given;
|
|
@@ -7012,9 +7388,10 @@ function observe(input) {
|
|
|
7012
7388
|
hostPresent: inCall && snapshot !== null ? snapshot.participants.some((p) => ADMITTER_ROLES.has(p.role)) : snapshot !== null && isWaitingPhase(snapshot.phase) ? snapshot.waiting?.admittersPresent ?? null : null,
|
|
7013
7389
|
lobbyCount: canAdmit && snapshot !== null ? snapshot.lobby.filter((entry) => entry.state === "knocking").length : 0,
|
|
7014
7390
|
recording: snapshot?.recording === "recording" || snapshot?.recording === "stopping",
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
|
|
7391
|
+
// S6c: the autoplay region is known only inside the room (no remote audio exists elsewhere).
|
|
7392
|
+
audioBlocked: inCall && snapshot !== null ? snapshot.mediaRegion.audioOutput === "blocked" : null,
|
|
7393
|
+
camera: deviceInPlay && snapshot !== null ? observedDevice(snapshot.media.camera, snapshot.mediaRegion.permission.camera) : null,
|
|
7394
|
+
microphone: deviceInPlay && snapshot !== null ? observedDevice(snapshot.media.microphone, snapshot.mediaRegion.permission.microphone) : null
|
|
7018
7395
|
};
|
|
7019
7396
|
}
|
|
7020
7397
|
function staticObservation(phase, reason = null) {
|
|
@@ -7079,10 +7456,10 @@ function participantAttributes(p) {
|
|
|
7079
7456
|
if (quality !== null) attrs["data-meet-participant-connection"] = quality;
|
|
7080
7457
|
return attrs;
|
|
7081
7458
|
}
|
|
7082
|
-
function microphoneNoticeCode(track) {
|
|
7083
|
-
const
|
|
7084
|
-
if (
|
|
7085
|
-
return
|
|
7459
|
+
function microphoneNoticeCode(track, permission = "unknown") {
|
|
7460
|
+
const reason = deviceUnavailableReason(track, permission);
|
|
7461
|
+
if (reason === null) return null;
|
|
7462
|
+
return deviceNoticeCode("microphone", reason) === "mic-blocked" ? "mic-blocked" : "device-lost";
|
|
7086
7463
|
}
|
|
7087
7464
|
|
|
7088
7465
|
// src/react/root.tsx
|
|
@@ -8183,6 +8560,26 @@ function useConsentNotice() {
|
|
|
8183
8560
|
if (agent === null) return null;
|
|
8184
8561
|
return `${agent.displayName} is in this meeting: it is transcribing what is said and writing notes everyone here can read.`;
|
|
8185
8562
|
}
|
|
8563
|
+
function useMediaSupervisor() {
|
|
8564
|
+
const host = useMeetHost();
|
|
8565
|
+
const snapshot = useMeetSnapshot();
|
|
8566
|
+
const engine = host?.engine ?? null;
|
|
8567
|
+
return {
|
|
8568
|
+
region: snapshot?.mediaRegion ?? IDLE_MEDIA_REGION,
|
|
8569
|
+
where: (0, import_react4.useMemo)(() => {
|
|
8570
|
+
const platform = webMediaPlatform();
|
|
8571
|
+
return { browser: platform?.browser ?? "other", os: platform?.os ?? "other" };
|
|
8572
|
+
}, []),
|
|
8573
|
+
enableAudio: (0, import_react4.useCallback)(async () => engine?.enableAudio(), [engine]),
|
|
8574
|
+
acceptOffer: (0, import_react4.useCallback)(async () => engine?.acceptDeviceOffer(), [engine]),
|
|
8575
|
+
dismissOffer: (0, import_react4.useCallback)(() => engine?.dismissDeviceOffer(), [engine]),
|
|
8576
|
+
dismissNotice: (0, import_react4.useCallback)(() => engine?.dismissDeviceNotice(), [engine]),
|
|
8577
|
+
retry: (0, import_react4.useCallback)(
|
|
8578
|
+
async (kind) => kind === "microphone" ? engine?.setMicrophoneEnabled(true) : engine?.setCameraEnabled(true),
|
|
8579
|
+
[engine]
|
|
8580
|
+
)
|
|
8581
|
+
};
|
|
8582
|
+
}
|
|
8186
8583
|
function useLocalMedia() {
|
|
8187
8584
|
const snapshot = useMeetSnapshot();
|
|
8188
8585
|
return snapshot?.media ?? IDLE_MEDIA;
|
|
@@ -11031,12 +11428,83 @@ function Toast({ text: text3, failed, onDone }) {
|
|
|
11031
11428
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: onDone, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CloseIcon, { width: 14, height: 14 }) })
|
|
11032
11429
|
] });
|
|
11033
11430
|
}
|
|
11431
|
+
function MediaNotices() {
|
|
11432
|
+
const media = useLocalMedia();
|
|
11433
|
+
const { region, where, enableAudio, acceptOffer, dismissOffer, dismissNotice, retry } = useMediaSupervisor();
|
|
11434
|
+
const [fixing, setFixing] = (0, import_react10.useState)(null);
|
|
11435
|
+
const chips = ["microphone", "camera"].flatMap((kind) => {
|
|
11436
|
+
const reason = deviceUnavailableReason(media[kind], region.permission[kind]);
|
|
11437
|
+
return reason === null ? [] : [{ kind, reason }];
|
|
11438
|
+
});
|
|
11439
|
+
const fixReason = fixing === null ? null : chips.find((chip) => chip.kind === fixing)?.reason ?? null;
|
|
11440
|
+
const notice = region.notice;
|
|
11441
|
+
const offer = region.offer;
|
|
11442
|
+
const name = (kind) => kind === "microphone" ? "Microphone" : "Camera";
|
|
11443
|
+
if (chips.length === 0 && region.audioOutput !== "blocked" && notice === null && offer === null) return null;
|
|
11444
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mx-meet__media-notices", children: [
|
|
11445
|
+
region.audioOutput === "blocked" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mx-meet__media-pill", role: "alert", "data-meet-notice": "audio-blocked", children: [
|
|
11446
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "Sound is paused in this tab" }),
|
|
11447
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mx-meet__primary mx-meet__primary--small", onClick: () => void enableAudio(), children: "Enable sound" })
|
|
11448
|
+
] }) : null,
|
|
11449
|
+
chips.map(({ kind, reason }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mx-meet__media-pill", role: "status", "data-meet-notice": deviceNoticeCode(kind, reason), children: [
|
|
11450
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: deviceChipLabel(kind, reason) }),
|
|
11451
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
11452
|
+
"button",
|
|
11453
|
+
{
|
|
11454
|
+
type: "button",
|
|
11455
|
+
className: "mx-meet__primary mx-meet__primary--small",
|
|
11456
|
+
"aria-label": kind === "microphone" ? "Fix microphone" : "Fix camera",
|
|
11457
|
+
"aria-expanded": fixing === kind,
|
|
11458
|
+
onClick: () => setFixing(fixing === kind ? null : kind),
|
|
11459
|
+
children: "Fix"
|
|
11460
|
+
}
|
|
11461
|
+
)
|
|
11462
|
+
] }, kind)),
|
|
11463
|
+
fixing !== null && fixReason !== null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mx-meet__popover mx-meet__fix-sheet", role: "dialog", "aria-label": `Fix ${name(fixing).toLowerCase()}`, children: [
|
|
11464
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ol", { className: "mx-meet__fix-steps", children: deviceFixSteps(fixing, fixReason, where).map((step) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { children: step }, step)) }),
|
|
11465
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mx-meet__fix-actions", children: [
|
|
11466
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
11467
|
+
"button",
|
|
11468
|
+
{
|
|
11469
|
+
type: "button",
|
|
11470
|
+
className: "mx-meet__primary mx-meet__primary--small",
|
|
11471
|
+
onClick: () => {
|
|
11472
|
+
const kind = fixing;
|
|
11473
|
+
setFixing(null);
|
|
11474
|
+
void retry(kind);
|
|
11475
|
+
},
|
|
11476
|
+
children: "Try again"
|
|
11477
|
+
}
|
|
11478
|
+
),
|
|
11479
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Close", onClick: () => setFixing(null), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CloseIcon, { width: 14, height: 14 }) })
|
|
11480
|
+
] })
|
|
11481
|
+
] }) : null,
|
|
11482
|
+
notice !== null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
11483
|
+
"div",
|
|
11484
|
+
{
|
|
11485
|
+
className: "mx-meet__media-pill",
|
|
11486
|
+
role: "status",
|
|
11487
|
+
...notice.outcome === "lost" ? { "data-meet-notice": "device-lost" } : {},
|
|
11488
|
+
children: [
|
|
11489
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: notice.outcome === "switched" ? `${notice.from || name(notice.kind)} disconnected \xB7 now using ${notice.to || "the default"}` : `${notice.from || name(notice.kind)} disconnected` }),
|
|
11490
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: dismissNotice, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CloseIcon, { width: 14, height: 14 }) })
|
|
11491
|
+
]
|
|
11492
|
+
}
|
|
11493
|
+
) : null,
|
|
11494
|
+
offer !== null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mx-meet__media-pill", role: "status", children: [
|
|
11495
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: `New ${offer.kind}: ${offer.label || name(offer.kind)}` }),
|
|
11496
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mx-meet__primary mx-meet__primary--small", onClick: () => void acceptOffer(), children: "Use it" }),
|
|
11497
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: dismissOffer, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CloseIcon, { width: 14, height: 14 }) })
|
|
11498
|
+
] }) : null
|
|
11499
|
+
] });
|
|
11500
|
+
}
|
|
11034
11501
|
function MeetingOverlays() {
|
|
11035
11502
|
const reactions = useReactions();
|
|
11036
11503
|
const { notice, dismiss } = useModerationNotice();
|
|
11037
11504
|
const room = useRoom();
|
|
11038
11505
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
11039
11506
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ReactionOverlay, { reactions }),
|
|
11507
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MediaNotices, {}),
|
|
11040
11508
|
notice !== null && notice.kind !== "removed" ? (
|
|
11041
11509
|
// A host's request ("the host is asking you to unmute"), not an error:
|
|
11042
11510
|
// an assertive status, so it is announced at once without being filed
|