@ai-matrx/meet 0.11.49 → 0.11.51
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 +12 -0
- package/dist/core.cjs +77 -12
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +14 -0
- package/dist/core.d.ts +14 -0
- package/dist/core.js +77 -12
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +77 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +77 -12
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +140 -48
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -0
- package/dist/react.d.ts +2 -0
- package/dist/react.js +140 -48
- package/dist/react.js.map +1 -1
- package/dist/skins/meet.cjs +63 -36
- package/dist/skins/meet.cjs.map +1 -1
- package/dist/skins/meet.js +63 -36
- package/dist/skins/meet.js.map +1 -1
- package/package.json +5 -5
package/dist/react.cjs
CHANGED
|
@@ -491,7 +491,8 @@ var DEFAULT_CONNECTION_POLICY = {
|
|
|
491
491
|
autoRejoin: true,
|
|
492
492
|
autoRejoinMaxAttempts: 5,
|
|
493
493
|
reconnectGraceSeconds: 30,
|
|
494
|
-
videoAutoOffAfterPoorSeconds: 20
|
|
494
|
+
videoAutoOffAfterPoorSeconds: 20,
|
|
495
|
+
captionsStartTimeoutSeconds: 20
|
|
495
496
|
};
|
|
496
497
|
function clampInt(value, min, max, fallback) {
|
|
497
498
|
if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
|
|
@@ -506,7 +507,8 @@ function connectionPolicyFrom(raw) {
|
|
|
506
507
|
autoRejoin: typeof row["auto_rejoin"] === "boolean" ? row["auto_rejoin"] : d.autoRejoin,
|
|
507
508
|
autoRejoinMaxAttempts: clampInt(row["auto_rejoin_max_attempts"], 0, 20, d.autoRejoinMaxAttempts),
|
|
508
509
|
reconnectGraceSeconds: clampInt(row["reconnect_grace_seconds"], 0, 600, d.reconnectGraceSeconds),
|
|
509
|
-
videoAutoOffAfterPoorSeconds: clampInt(row["video_auto_off_after_poor_seconds"], 0, 600, d.videoAutoOffAfterPoorSeconds)
|
|
510
|
+
videoAutoOffAfterPoorSeconds: clampInt(row["video_auto_off_after_poor_seconds"], 0, 600, d.videoAutoOffAfterPoorSeconds),
|
|
511
|
+
captionsStartTimeoutSeconds: clampInt(row["captions_start_timeout_seconds"], 1, 600, d.captionsStartTimeoutSeconds)
|
|
510
512
|
};
|
|
511
513
|
}
|
|
512
514
|
var LIVEKIT_BASE_DELAYS_MS = [0, 300, 1200, 2700, 4800, 7e3];
|
|
@@ -4357,6 +4359,7 @@ var EMPTY = {
|
|
|
4357
4359
|
noteTakerRefusal: null,
|
|
4358
4360
|
captionsOn: false,
|
|
4359
4361
|
captionsRefusal: null,
|
|
4362
|
+
captionsStartTimeoutSeconds: 20,
|
|
4360
4363
|
media: IDLE_MEDIA,
|
|
4361
4364
|
mediaRegion: IDLE_MEDIA_REGION,
|
|
4362
4365
|
failure: null,
|
|
@@ -4778,7 +4781,10 @@ function createMeetingSession(options) {
|
|
|
4778
4781
|
const meeting = store.snapshot().meeting;
|
|
4779
4782
|
const pass = options.resolvePass?.() ?? null;
|
|
4780
4783
|
if (meeting === null || pass === null) return;
|
|
4781
|
-
if (policyReading)
|
|
4784
|
+
if (policyReading) {
|
|
4785
|
+
await (policyInFlight ?? void 0);
|
|
4786
|
+
return readLivePolicy();
|
|
4787
|
+
}
|
|
4782
4788
|
policyReading = true;
|
|
4783
4789
|
let done = () => void 0;
|
|
4784
4790
|
policyInFlight = new Promise((resolve) => done = resolve);
|
|
@@ -4799,6 +4805,9 @@ function createMeetingSession(options) {
|
|
|
4799
4805
|
if (!samePolicy(snapshot.livePolicy, next) || startedAt !== snapshot.sessionStartedAt) {
|
|
4800
4806
|
store.patch({ livePolicy: next, sessionStartedAt: startedAt });
|
|
4801
4807
|
}
|
|
4808
|
+
if (read.consent_given === true && !store.snapshot().recordingConsentGiven) {
|
|
4809
|
+
store.patch({ recordingConsentGiven: true });
|
|
4810
|
+
}
|
|
4802
4811
|
} catch {
|
|
4803
4812
|
} finally {
|
|
4804
4813
|
policyReading = false;
|
|
@@ -5103,6 +5112,21 @@ function createMeetingSession(options) {
|
|
|
5103
5112
|
stopWaiting,
|
|
5104
5113
|
readState: readState2,
|
|
5105
5114
|
readLivePolicy,
|
|
5115
|
+
async acknowledgeConsent() {
|
|
5116
|
+
const meeting = requireMeeting("meet.consent");
|
|
5117
|
+
const pass = options.resolvePass?.() ?? null;
|
|
5118
|
+
const response = await options.api.request({
|
|
5119
|
+
path: MEET_ROUTES.consent,
|
|
5120
|
+
method: "POST",
|
|
5121
|
+
requireAuth: false,
|
|
5122
|
+
operation: "meet.consent",
|
|
5123
|
+
body: { meeting_id: meeting.id },
|
|
5124
|
+
...pass !== null ? { headers: { [MEETING_PASS_HEADER]: pass } } : {}
|
|
5125
|
+
});
|
|
5126
|
+
if (!response.ok) {
|
|
5127
|
+
throw new MeetError("transport", `meet.consent: the server answered ${response.status}`, "Your agreement was not saved. Try again.");
|
|
5128
|
+
}
|
|
5129
|
+
},
|
|
5106
5130
|
async readExit(connection, held) {
|
|
5107
5131
|
const meeting = store.snapshot().meeting;
|
|
5108
5132
|
const pass = held ?? options.resolvePass?.() ?? null;
|
|
@@ -5498,7 +5522,9 @@ function createMediaSupervisor(options) {
|
|
|
5498
5522
|
const deviceKind = INPUT_KIND[kind];
|
|
5499
5523
|
const previous = inUse[deviceKind];
|
|
5500
5524
|
const track = store.snapshot().media[kind];
|
|
5501
|
-
const
|
|
5525
|
+
const aliasLabel = previous !== null && isAlias(previous) ? before[deviceKind].get(previous) : void 0;
|
|
5526
|
+
const aliasGone = previous !== null && aliasLabel !== void 0 && aliasLabel !== "" && (!now[deviceKind].has(previous) || now[deviceKind].get(previous) !== aliasLabel);
|
|
5527
|
+
const gone = aliasGone || previous !== null && !isAlias(previous) && before[deviceKind].has(previous) && !now[deviceKind].has(previous);
|
|
5502
5528
|
if (gone) {
|
|
5503
5529
|
const from = before[deviceKind].get(previous) ?? "";
|
|
5504
5530
|
const remaining = [...now[deviceKind].entries()].filter(([id]) => !isAlias(id));
|
|
@@ -5523,7 +5549,7 @@ function createMediaSupervisor(options) {
|
|
|
5523
5549
|
await driver.setCameraEnabled(true);
|
|
5524
5550
|
store.setLocalTrack("camera", { enabled: true, unavailable: null });
|
|
5525
5551
|
}
|
|
5526
|
-
setRegion({ notice: { id: ++noticeId, kind, outcome: "switched", from, to: nextLabel } });
|
|
5552
|
+
setRegion({ notice: { id: ++noticeId, kind, outcome: "switched", from, fromId: previous, to: nextLabel } });
|
|
5527
5553
|
} catch (error) {
|
|
5528
5554
|
const refused = await unavailable(error, "camera", "meet.camera(fallback)");
|
|
5529
5555
|
store.setLocalTrack("camera", { enabled: false, unavailable: refused });
|
|
@@ -5531,8 +5557,24 @@ function createMediaSupervisor(options) {
|
|
|
5531
5557
|
}
|
|
5532
5558
|
} else {
|
|
5533
5559
|
const active = driver.activeDevices().audioinput;
|
|
5534
|
-
|
|
5535
|
-
|
|
5560
|
+
let to = (active !== null && !aliasGone ? now.audioinput.get(active) : void 0) ?? now.audioinput.get("default");
|
|
5561
|
+
if (to === void 0 || aliasGone) {
|
|
5562
|
+
const [nextId, nextLabel] = remaining[0];
|
|
5563
|
+
try {
|
|
5564
|
+
await driver.switchDevice("audioinput", nextId);
|
|
5565
|
+
if (track.enabled || track.unavailable !== null) {
|
|
5566
|
+
await driver.setMicrophoneEnabled(true);
|
|
5567
|
+
store.setLocalTrack("microphone", { enabled: true, unavailable: null });
|
|
5568
|
+
}
|
|
5569
|
+
to = nextLabel;
|
|
5570
|
+
} catch (error) {
|
|
5571
|
+
const refused = await unavailable(error, "microphone", "meet.microphone(fallback)");
|
|
5572
|
+
store.setLocalTrack("microphone", { enabled: false, unavailable: refused });
|
|
5573
|
+
setRegion({ notice: { id: ++noticeId, kind, outcome: "lost", from, to: null } });
|
|
5574
|
+
continue;
|
|
5575
|
+
}
|
|
5576
|
+
}
|
|
5577
|
+
setRegion({ notice: { id: ++noticeId, kind, outcome: "switched", from, fromId: previous, to } });
|
|
5536
5578
|
}
|
|
5537
5579
|
continue;
|
|
5538
5580
|
}
|
|
@@ -5637,6 +5679,21 @@ function createMediaSupervisor(options) {
|
|
|
5637
5679
|
},
|
|
5638
5680
|
dismissNotice() {
|
|
5639
5681
|
setRegion({ notice: null });
|
|
5682
|
+
},
|
|
5683
|
+
async undoNotice() {
|
|
5684
|
+
const notice = region().notice;
|
|
5685
|
+
setRegion({ notice: null });
|
|
5686
|
+
const driver = options.driver();
|
|
5687
|
+
if (notice === null || notice.outcome !== "switched" || notice.fromId === void 0 || driver === null) return;
|
|
5688
|
+
const list = await snapshotDevices();
|
|
5689
|
+
if (!list[INPUT_KIND[notice.kind]].has(notice.fromId)) return;
|
|
5690
|
+
try {
|
|
5691
|
+
await driver.switchDevice(INPUT_KIND[notice.kind], notice.fromId);
|
|
5692
|
+
readInUse();
|
|
5693
|
+
} catch (error) {
|
|
5694
|
+
const refused = await unavailable(error, notice.kind, "meet.undoDeviceSwitch");
|
|
5695
|
+
store.setLocalTrack(notice.kind, { enabled: false, unavailable: refused });
|
|
5696
|
+
}
|
|
5640
5697
|
}
|
|
5641
5698
|
};
|
|
5642
5699
|
return api;
|
|
@@ -5859,11 +5916,10 @@ function moderationText(kind, payload) {
|
|
|
5859
5916
|
switch (kind) {
|
|
5860
5917
|
case "muted": {
|
|
5861
5918
|
const source = text2(payload["source"]) ?? "microphone";
|
|
5862
|
-
|
|
5863
|
-
return source === "microphone" ? `You've been muted by ${who}.` : source === "camera" ? `Your camera was turned off by ${who}.` : `Your screen share was stopped by ${who}.`;
|
|
5919
|
+
return source === "microphone" ? `${by} muted you.` : source === "camera" ? `${by} turned off your camera.` : `${by} stopped your screen share.`;
|
|
5864
5920
|
}
|
|
5865
5921
|
case "ask-unmute":
|
|
5866
|
-
return `${by
|
|
5922
|
+
return `${by} is asking you to unmute.`;
|
|
5867
5923
|
case "removed":
|
|
5868
5924
|
return `${by} removed you from this meeting.`;
|
|
5869
5925
|
default:
|
|
@@ -5889,7 +5945,7 @@ function applyModeration(store, payload, now) {
|
|
|
5889
5945
|
grants: { ...snapshot.grants, role },
|
|
5890
5946
|
moderationNotice: {
|
|
5891
5947
|
kind: "role",
|
|
5892
|
-
text: role === "host" ? "You are now the host." : role === "cohost" ? "You
|
|
5948
|
+
text: role === "host" ? "You are now the host." : role === "cohost" ? "You are now a co-host." : role === "presenter" ? "You are now a presenter." : snapshot.grants.role === "presenter" ? "You are now a participant: you can no longer present." : "You are no longer a co-host.",
|
|
5893
5949
|
at: now()
|
|
5894
5950
|
}
|
|
5895
5951
|
});
|
|
@@ -6391,7 +6447,14 @@ function createRoomEngine(options) {
|
|
|
6391
6447
|
const latest = store.snapshot().meeting;
|
|
6392
6448
|
if (latest === null) return;
|
|
6393
6449
|
store.patch({ meeting: { ...latest, endedAt: verified.endedAt } });
|
|
6394
|
-
|
|
6450
|
+
const connection = current?.connectionIdentity ?? current?.identity ?? store.snapshot().localIdentity ?? null;
|
|
6451
|
+
let why;
|
|
6452
|
+
try {
|
|
6453
|
+
why = options.readExit !== void 0 && connection !== null ? await options.readExit(connection, current?.meetingPass ?? null) : void 0;
|
|
6454
|
+
} catch {
|
|
6455
|
+
why = null;
|
|
6456
|
+
}
|
|
6457
|
+
store.dispatch({ type: "ended" }, { reason: why?.exitReason === "time_limit" ? "time_limit" : "ended" });
|
|
6395
6458
|
await dropRoom();
|
|
6396
6459
|
options.onLeft?.("ended");
|
|
6397
6460
|
} catch (error) {
|
|
@@ -6719,6 +6782,7 @@ function createRoomEngine(options) {
|
|
|
6719
6782
|
current = token;
|
|
6720
6783
|
lastServerUrl = token.serverUrl;
|
|
6721
6784
|
connectionPolicy = token.connectionPolicy ?? DEFAULT_CONNECTION_POLICY;
|
|
6785
|
+
store.patch({ captionsStartTimeoutSeconds: connectionPolicy.captionsStartTimeoutSeconds });
|
|
6722
6786
|
if (token.leavePolicy !== void 0) store.patch({ leavePolicy: token.leavePolicy });
|
|
6723
6787
|
store.patch({ canReclaim: token.canReclaim === true });
|
|
6724
6788
|
store.patch({
|
|
@@ -7163,6 +7227,7 @@ function createRoomEngine(options) {
|
|
|
7163
7227
|
acceptDeviceOffer: () => media.acceptOffer(),
|
|
7164
7228
|
dismissDeviceOffer: () => media.dismissOffer(),
|
|
7165
7229
|
dismissDeviceNotice: () => media.dismissNotice(),
|
|
7230
|
+
undoDeviceNotice: () => media.undoNotice(),
|
|
7166
7231
|
pin(who) {
|
|
7167
7232
|
store.patch({ pinned: who, layout: who === null ? "grid" : "speaker" });
|
|
7168
7233
|
},
|
|
@@ -9165,6 +9230,22 @@ function createMeetingRecordCache(options = {}) {
|
|
|
9165
9230
|
};
|
|
9166
9231
|
}
|
|
9167
9232
|
|
|
9233
|
+
// src/core/captions-state.ts
|
|
9234
|
+
var CAPTIONS_TIMEOUT_REASON = "Captions are unavailable right now.";
|
|
9235
|
+
function resolveCaptionsState(i) {
|
|
9236
|
+
if (!i.on) return { state: "off", reason: null, remedy: null };
|
|
9237
|
+
if (i.takerState === "transcribing" && i.takerPresent) return { state: "live", reason: null, remedy: null };
|
|
9238
|
+
if (i.takerState === "joining" && !i.timedOut) return { state: "starting", reason: null, remedy: null };
|
|
9239
|
+
if (i.refusal !== null && i.refusal.reason.length > 0) {
|
|
9240
|
+
return { state: "unavailable", reason: i.refusal.reason, remedy: i.refusal.remedy.length > 0 ? i.refusal.remedy : null };
|
|
9241
|
+
}
|
|
9242
|
+
if (i.takerState === "ended" || i.takerState === "handoff_pending") {
|
|
9243
|
+
return { state: "unavailable", reason: i.takerLabel, remedy: null };
|
|
9244
|
+
}
|
|
9245
|
+
if (i.timedOut) return { state: "unavailable", reason: CAPTIONS_TIMEOUT_REASON, remedy: null };
|
|
9246
|
+
return { state: "starting", reason: null, remedy: null };
|
|
9247
|
+
}
|
|
9248
|
+
|
|
9168
9249
|
// src/core/layout.ts
|
|
9169
9250
|
var DEFAULT_PAGE_SIZE = 12;
|
|
9170
9251
|
function orderParticipants(participants, activeSpeakers) {
|
|
@@ -9255,7 +9336,8 @@ function useRoom() {
|
|
|
9255
9336
|
local,
|
|
9256
9337
|
// An observer (role `viewer`) publishes nothing: no Share screen to press and be refused (MD-16).
|
|
9257
9338
|
sharingAllowed: snapshot === null || canShareUnder(snapshot.livePolicy, effectiveRole(snapshot), effectiveStanding(snapshot)),
|
|
9258
|
-
canShareScreen: (engine?.supportsScreenShare() ?? true) && !isObserverRole(snapshot?.grants.role ?? null) &&
|
|
9339
|
+
canShareScreen: (engine?.supportsScreenShare() ?? true) && !isObserverRole(snapshot?.grants.role ?? null) && // The server's word that sharing was taken away arrives before the rules refresh does: the control goes at once.
|
|
9340
|
+
!(snapshot?.share.state === "ended" && snapshot.share.reason === "not_allowed") && (snapshot === null || canShareUnder(snapshot.livePolicy, effectiveRole(snapshot), effectiveStanding(snapshot))),
|
|
9259
9341
|
otherPresenter: otherPresenterOf(snapshot),
|
|
9260
9342
|
join: (0, import_react4.useCallback)(
|
|
9261
9343
|
async (request) => requireEngine(engine, "join").join(request),
|
|
@@ -9652,32 +9734,37 @@ function useCaptions() {
|
|
|
9652
9734
|
if (host === null || meeting === null) return;
|
|
9653
9735
|
void host.ai.requestCaptions({ meetingId: meeting.id });
|
|
9654
9736
|
}, [host, meeting]);
|
|
9737
|
+
const [timedOut, setTimedOut] = (0, import_react4.useState)(false);
|
|
9738
|
+
const timeoutSeconds = snapshot?.captionsStartTimeoutSeconds ?? 20;
|
|
9739
|
+
const live = taker.state === "transcribing" && taker.present;
|
|
9740
|
+
const [attempt, setAttempt] = (0, import_react4.useState)(0);
|
|
9741
|
+
(0, import_react4.useEffect)(() => {
|
|
9742
|
+
setTimedOut(false);
|
|
9743
|
+
if (!on || live) return void 0;
|
|
9744
|
+
const id = setTimeout(() => setTimedOut(true), timeoutSeconds * 1e3);
|
|
9745
|
+
return () => clearTimeout(id);
|
|
9746
|
+
}, [on, live, timeoutSeconds, attempt]);
|
|
9655
9747
|
const toggle = (0, import_react4.useCallback)(() => {
|
|
9656
9748
|
if (host === null) return;
|
|
9657
9749
|
const next = !on;
|
|
9658
9750
|
host.store.patch({ captionsOn: next, captionsRefusal: null });
|
|
9659
9751
|
if (next && taker.state !== "joining" && taker.state !== "transcribing") request();
|
|
9660
9752
|
}, [host, on, taker.state, request]);
|
|
9661
|
-
|
|
9662
|
-
|
|
9663
|
-
|
|
9664
|
-
|
|
9665
|
-
|
|
9666
|
-
|
|
9667
|
-
|
|
9668
|
-
|
|
9669
|
-
|
|
9670
|
-
|
|
9671
|
-
|
|
9672
|
-
|
|
9673
|
-
|
|
9674
|
-
|
|
9675
|
-
|
|
9676
|
-
} else {
|
|
9677
|
-
state = "starting";
|
|
9678
|
-
}
|
|
9679
|
-
}
|
|
9680
|
-
return { on, state, reason, remedy, toggle };
|
|
9753
|
+
const retry = (0, import_react4.useCallback)(() => {
|
|
9754
|
+
if (host === null) return;
|
|
9755
|
+
host.store.patch({ captionsOn: true, captionsRefusal: null });
|
|
9756
|
+
setAttempt((n) => n + 1);
|
|
9757
|
+
request();
|
|
9758
|
+
}, [host, request]);
|
|
9759
|
+
const view = resolveCaptionsState({
|
|
9760
|
+
on,
|
|
9761
|
+
takerState: taker.state,
|
|
9762
|
+
takerPresent: taker.present,
|
|
9763
|
+
refusal: refusal2,
|
|
9764
|
+
takerLabel: on ? noteTakerLabel(taker) : "",
|
|
9765
|
+
timedOut
|
|
9766
|
+
});
|
|
9767
|
+
return { on, state: view.state, reason: view.reason, remedy: view.remedy, toggle, retry };
|
|
9681
9768
|
}
|
|
9682
9769
|
function useEndMeeting() {
|
|
9683
9770
|
const host = useMeetHost();
|
|
@@ -9735,6 +9822,7 @@ function useMediaSupervisor() {
|
|
|
9735
9822
|
acceptOffer: (0, import_react4.useCallback)(async () => engine?.acceptDeviceOffer(), [engine]),
|
|
9736
9823
|
dismissOffer: (0, import_react4.useCallback)(() => engine?.dismissDeviceOffer(), [engine]),
|
|
9737
9824
|
dismissNotice: (0, import_react4.useCallback)(() => engine?.dismissDeviceNotice(), [engine]),
|
|
9825
|
+
undoNotice: (0, import_react4.useCallback)(async () => engine?.undoDeviceNotice(), [engine]),
|
|
9738
9826
|
retry: (0, import_react4.useCallback)(
|
|
9739
9827
|
async (kind) => kind === "microphone" ? engine?.setMicrophoneEnabled(true) : engine?.setCameraEnabled(true),
|
|
9740
9828
|
[engine]
|
|
@@ -10204,19 +10292,19 @@ function useLivePolicy() {
|
|
|
10204
10292
|
const host = useMeetHost();
|
|
10205
10293
|
const pending = consentPending(policy, role, snapshot?.recording === "recording", snapshot?.recordingConsentGiven === true);
|
|
10206
10294
|
const viewOnly = pending && policy.recordingConsent === "view_only_until_agree";
|
|
10207
|
-
const idle = snapshot !== null && snapshot.recording !== "recording" && snapshot.recording !== "starting" && snapshot.recording !== "stopping";
|
|
10208
|
-
const given = snapshot?.recordingConsentGiven === true;
|
|
10209
10295
|
const store = host?.store ?? null;
|
|
10210
|
-
(0, import_react4.useEffect)(() => {
|
|
10211
|
-
if (idle && given) store?.patch({ recordingConsentGiven: false });
|
|
10212
|
-
}, [idle, given, store]);
|
|
10213
10296
|
return {
|
|
10214
10297
|
canChat: canChat(policy, role),
|
|
10215
10298
|
chatMode: policy.chatMode,
|
|
10216
10299
|
micLocked: isLockedFor(policy, role, "microphone") || viewOnly,
|
|
10217
10300
|
cameraLocked: isLockedFor(policy, role, "camera") || viewOnly,
|
|
10218
10301
|
consent: pending ? policy.recordingConsent === "ok_or_leave" ? "ok_or_leave" : "view_only_until_agree" : null,
|
|
10219
|
-
|
|
10302
|
+
// The person's agreement is recorded by the SERVER (per run); the screen follows at once and
|
|
10303
|
+
// takes it back if the server did not save it.
|
|
10304
|
+
agree: () => {
|
|
10305
|
+
store?.patch({ recordingConsentGiven: true });
|
|
10306
|
+
void host?.meetings.acknowledgeConsent().catch(() => store?.patch({ recordingConsentGiven: false }));
|
|
10307
|
+
},
|
|
10220
10308
|
minutesLeft: left,
|
|
10221
10309
|
timeWarning: left !== null && left <= policy.timeLimitWarningMinutes
|
|
10222
10310
|
};
|
|
@@ -13015,7 +13103,7 @@ function SpeakingWhileMutedNudge() {
|
|
|
13015
13103
|
}
|
|
13016
13104
|
function MediaNotices() {
|
|
13017
13105
|
const media = useLocalMedia();
|
|
13018
|
-
const { region, where, enableAudio, acceptOffer, dismissOffer, dismissNotice, retry } = useMediaSupervisor();
|
|
13106
|
+
const { region, where, enableAudio, acceptOffer, dismissOffer, dismissNotice, undoNotice, retry } = useMediaSupervisor();
|
|
13019
13107
|
const [fixing, setFixing] = (0, import_react10.useState)(null);
|
|
13020
13108
|
const chips = ["microphone", "camera"].flatMap((kind) => {
|
|
13021
13109
|
const reason = deviceUnavailableReason(media[kind], region.permission[kind]);
|
|
@@ -13080,9 +13168,10 @@ function MediaNotices() {
|
|
|
13080
13168
|
{
|
|
13081
13169
|
className: "mx-meet__media-pill",
|
|
13082
13170
|
role: "status",
|
|
13083
|
-
|
|
13171
|
+
"data-meet-notice": notice.outcome === "lost" ? "device-lost" : "device-switched",
|
|
13084
13172
|
children: [
|
|
13085
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: notice.outcome === "switched" ? `${notice.from || name(notice.kind)} disconnected \xB7
|
|
13173
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: notice.outcome === "switched" ? `${notice.from || name(notice.kind)} disconnected \xB7 switched to ${notice.to || "the default"}` : `${notice.from || name(notice.kind)} disconnected` }),
|
|
13174
|
+
notice.outcome === "switched" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => void undoNotice(), children: "Undo" }) : null,
|
|
13086
13175
|
/* @__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 }) })
|
|
13087
13176
|
]
|
|
13088
13177
|
}
|
|
@@ -13135,7 +13224,7 @@ function MeetingOverlays() {
|
|
|
13135
13224
|
live.minutesLeft,
|
|
13136
13225
|
" ",
|
|
13137
13226
|
live.minutesLeft === 1 ? "minute" : "minutes",
|
|
13138
|
-
"
|
|
13227
|
+
"."
|
|
13139
13228
|
] }) : null,
|
|
13140
13229
|
notice !== null && notice.kind !== "removed" ? (
|
|
13141
13230
|
// A host's request ("the host is asking you to unmute"), not an error:
|
|
@@ -14194,11 +14283,14 @@ function Captions({ lines = 3 }) {
|
|
|
14194
14283
|
const captions = useCaptions();
|
|
14195
14284
|
if (!captions.on) return null;
|
|
14196
14285
|
if (captions.state === "unavailable") {
|
|
14197
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.
|
|
14198
|
-
|
|
14199
|
-
|
|
14200
|
-
|
|
14201
|
-
|
|
14286
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mx-meet__captions", role: "status", "data-meet-notice": "captions-unavailable", children: [
|
|
14287
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "mx-meet__caption", children: [
|
|
14288
|
+
(captions.reason ?? "").startsWith("Captions are unavailable") ? "" : "Captions are unavailable. ",
|
|
14289
|
+
captions.reason,
|
|
14290
|
+
captions.remedy !== null ? ` ${captions.remedy}` : ""
|
|
14291
|
+
] }),
|
|
14292
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mx-meet__caption-retry", onClick: captions.retry, children: "Try again" })
|
|
14293
|
+
] });
|
|
14202
14294
|
}
|
|
14203
14295
|
if (visible.length === 0) {
|
|
14204
14296
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", "data-meet-caption": captions.state, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mx-meet__caption mx-meet__caption--interim", children: captions.state === "starting" ? "Starting captions. They appear as people speak." : "Captions are on. They appear as people speak." }) });
|