@cloudflare/realtimekit-ui 1.2.1-staging.1 → 1.2.1-staging.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1633,8 +1633,7 @@ const RtkMeeting = class {
1633
1633
  if (this.showSetupScreen == null) {
1634
1634
  this.showSetupScreen = data.showSetupScreen;
1635
1635
  }
1636
- if (meeting.connectedMeetings.supportsConnectedMeetings &&
1637
- ((_a = targetStore.state.states.activeBreakoutRoomsManager) === null || _a === void 0 ? void 0 : _a.destinationMeetingId)) {
1636
+ if ((_a = targetStore.state.states.activeBreakoutRoomsManager) === null || _a === void 0 ? void 0 : _a.destinationMeetingId) {
1638
1637
  this.showSetupScreen = false;
1639
1638
  }
1640
1639
  }
@@ -1649,9 +1648,7 @@ const RtkMeeting = class {
1649
1648
  meeting.self.addListener('roomLeft', this.roomLeftListener);
1650
1649
  meeting.self.addListener('mediaPermissionUpdate', this.mediaPermissionUpdateListener);
1651
1650
  meeting.meta.addListener('socketConnectionUpdate', this.socketConnectionUpdateListener);
1652
- if (meeting.connectedMeetings.supportsConnectedMeetings) {
1653
- meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
1654
- }
1651
+ meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
1655
1652
  if (meeting.self.roomJoined) {
1656
1653
  this.updateStates({ meeting: 'joined' });
1657
1654
  }
@@ -300,6 +300,7 @@ const RtkGrid = class {
300
300
  this.pinnedParticipants = this.pinnedParticipants.filter((p) => p.id !== participant.id);
301
301
  }
302
302
  render() {
303
+ var _a, _b, _c, _d;
303
304
  const defaults = {
304
305
  meeting: this.meeting,
305
306
  size: this.size,
@@ -312,7 +313,16 @@ const RtkGrid = class {
312
313
  return (index$1.h(index$1.Host, null, index$1.h("div", { class: "offline-grid" }, index$1.h("rtk-icon", { icon: this.iconPack.join_stage, size: "xl" }), index$1.h("h3", null, this.t('disconnected')), index$1.h("p", null, this.t('disconnected.description')))));
313
314
  }
314
315
  if (this.roomState === 'disconnected') {
315
- return (index$1.h(index$1.Host, null, index$1.h("div", { class: "offline-grid" }, index$1.h("rtk-icon", { icon: this.iconPack.disconnected, size: "xl" }), index$1.h("h3", null, this.t('offline')), index$1.h("p", null, this.t('offline.description')))));
316
+ /**
317
+ * NOTE(ravindra-cloudflare): When disconnected but WebRTC transports are
318
+ * still healthy, skip the offline screen — media is still flowing.
319
+ * The grid stays visible for seamless reconnection.
320
+ */
321
+ const mediaState = (_b = (_a = this.meeting) === null || _a === void 0 ? void 0 : _a.meta) === null || _b === void 0 ? void 0 : _b.mediaState;
322
+ const transportsHealthy = ((_c = mediaState === null || mediaState === void 0 ? void 0 : mediaState.send) === null || _c === void 0 ? void 0 : _c.state) === 'connected' && ((_d = mediaState === null || mediaState === void 0 ? void 0 : mediaState.recv) === null || _d === void 0 ? void 0 : _d.state) === 'connected';
323
+ if (!transportsHealthy) {
324
+ return (index$1.h(index$1.Host, null, index$1.h("div", { class: "offline-grid" }, index$1.h("rtk-icon", { icon: this.iconPack.disconnected, size: "xl" }), index$1.h("h3", null, this.t('offline')), index$1.h("p", null, this.t('offline.description')))));
325
+ }
316
326
  }
317
327
  if (this.roomState === 'failed') {
318
328
  return (index$1.h(index$1.Host, null, index$1.h("div", { class: "offline-grid" }, index$1.h("rtk-icon", { icon: this.iconPack.disconnected, size: "xl" }), index$1.h("h3", null, this.t('failed')), index$1.h("p", null, this.t('failed.description')))));
@@ -21,11 +21,11 @@ class RTKAudio {
21
21
  this.audioTracks = [];
22
22
  }
23
23
  addTrack(id, track) {
24
- if (!this.audioTracks.some((a) => a.id === id)) {
25
- this.audioTracks.push({ id, track });
26
- this.audioStream.addTrack(track);
27
- this.play();
28
- }
24
+ // Remove the track if it already exists, with the same id
25
+ this.removeTrack(id);
26
+ this.audioTracks.push({ id, track });
27
+ this.audioStream.addTrack(track);
28
+ this.play();
29
29
  }
30
30
  removeTrack(id) {
31
31
  const track = this.audioTracks.find((a) => a.id === id);
@@ -182,9 +182,7 @@ const RtkUiProvider = class {
182
182
  meeting.self.addListener('roomLeft', this.roomLeftListener);
183
183
  meeting.self.addListener('mediaPermissionUpdate', this.mediaPermissionUpdateListener);
184
184
  meeting.meta.addListener('socketConnectionUpdate', this.socketConnectionUpdateListener);
185
- if (meeting.connectedMeetings.supportsConnectedMeetings) {
186
- meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
187
- }
185
+ meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
188
186
  if (meeting.self.roomJoined) {
189
187
  this.updateStates({ meeting: 'joined' });
190
188
  }
@@ -296,6 +296,7 @@ export class RtkGrid {
296
296
  this.pinnedParticipants = this.pinnedParticipants.filter((p) => p.id !== participant.id);
297
297
  }
298
298
  render() {
299
+ var _a, _b, _c, _d;
299
300
  const defaults = {
300
301
  meeting: this.meeting,
301
302
  size: this.size,
@@ -308,7 +309,16 @@ export class RtkGrid {
308
309
  return (h(Host, null, h("div", { class: "offline-grid" }, h("rtk-icon", { icon: this.iconPack.join_stage, size: "xl" }), h("h3", null, this.t('disconnected')), h("p", null, this.t('disconnected.description')))));
309
310
  }
310
311
  if (this.roomState === 'disconnected') {
311
- return (h(Host, null, h("div", { class: "offline-grid" }, h("rtk-icon", { icon: this.iconPack.disconnected, size: "xl" }), h("h3", null, this.t('offline')), h("p", null, this.t('offline.description')))));
312
+ /**
313
+ * NOTE(ravindra-cloudflare): When disconnected but WebRTC transports are
314
+ * still healthy, skip the offline screen — media is still flowing.
315
+ * The grid stays visible for seamless reconnection.
316
+ */
317
+ const mediaState = (_b = (_a = this.meeting) === null || _a === void 0 ? void 0 : _a.meta) === null || _b === void 0 ? void 0 : _b.mediaState;
318
+ const transportsHealthy = ((_c = mediaState === null || mediaState === void 0 ? void 0 : mediaState.send) === null || _c === void 0 ? void 0 : _c.state) === 'connected' && ((_d = mediaState === null || mediaState === void 0 ? void 0 : mediaState.recv) === null || _d === void 0 ? void 0 : _d.state) === 'connected';
319
+ if (!transportsHealthy) {
320
+ return (h(Host, null, h("div", { class: "offline-grid" }, h("rtk-icon", { icon: this.iconPack.disconnected, size: "xl" }), h("h3", null, this.t('offline')), h("p", null, this.t('offline.description')))));
321
+ }
312
322
  }
313
323
  if (this.roomState === 'failed') {
314
324
  return (h(Host, null, h("div", { class: "offline-grid" }, h("rtk-icon", { icon: this.iconPack.disconnected, size: "xl" }), h("h3", null, this.t('failed')), h("p", null, this.t('failed.description')))));
@@ -213,8 +213,7 @@ export class RtkMeeting {
213
213
  if (this.showSetupScreen == null) {
214
214
  this.showSetupScreen = data.showSetupScreen;
215
215
  }
216
- if (meeting.connectedMeetings.supportsConnectedMeetings &&
217
- ((_a = targetStore.state.states.activeBreakoutRoomsManager) === null || _a === void 0 ? void 0 : _a.destinationMeetingId)) {
216
+ if ((_a = targetStore.state.states.activeBreakoutRoomsManager) === null || _a === void 0 ? void 0 : _a.destinationMeetingId) {
218
217
  this.showSetupScreen = false;
219
218
  }
220
219
  }
@@ -229,9 +228,7 @@ export class RtkMeeting {
229
228
  meeting.self.addListener('roomLeft', this.roomLeftListener);
230
229
  meeting.self.addListener('mediaPermissionUpdate', this.mediaPermissionUpdateListener);
231
230
  meeting.meta.addListener('socketConnectionUpdate', this.socketConnectionUpdateListener);
232
- if (meeting.connectedMeetings.supportsConnectedMeetings) {
233
- meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
234
- }
231
+ meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
235
232
  if (meeting.self.roomJoined) {
236
233
  this.updateStates({ meeting: 'joined' });
237
234
  }
@@ -173,9 +173,7 @@ export class RtkUiProvider {
173
173
  meeting.self.addListener('roomLeft', this.roomLeftListener);
174
174
  meeting.self.addListener('mediaPermissionUpdate', this.mediaPermissionUpdateListener);
175
175
  meeting.meta.addListener('socketConnectionUpdate', this.socketConnectionUpdateListener);
176
- if (meeting.connectedMeetings.supportsConnectedMeetings) {
177
- meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
178
- }
176
+ meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
179
177
  if (meeting.self.roomJoined) {
180
178
  this.updateStates({ meeting: 'joined' });
181
179
  }
@@ -13,11 +13,11 @@ export default class RTKAudio {
13
13
  this.audioTracks = [];
14
14
  }
15
15
  addTrack(id, track) {
16
- if (!this.audioTracks.some((a) => a.id === id)) {
17
- this.audioTracks.push({ id, track });
18
- this.audioStream.addTrack(track);
19
- this.play();
20
- }
16
+ // Remove the track if it already exists, with the same id
17
+ this.removeTrack(id);
18
+ this.audioTracks.push({ id, track });
19
+ this.audioStream.addTrack(track);
20
+ this.play();
21
21
  }
22
22
  removeTrack(id) {
23
23
  const track = this.audioTracks.find((a) => a.id === id);
@@ -306,6 +306,7 @@ const RtkGrid$1 = /*@__PURE__*/ proxyCustomElement(class RtkGrid extends H {
306
306
  this.pinnedParticipants = this.pinnedParticipants.filter((p) => p.id !== participant.id);
307
307
  }
308
308
  render() {
309
+ var _a, _b, _c, _d;
309
310
  const defaults = {
310
311
  meeting: this.meeting,
311
312
  size: this.size,
@@ -318,7 +319,16 @@ const RtkGrid$1 = /*@__PURE__*/ proxyCustomElement(class RtkGrid extends H {
318
319
  return (h(Host, null, h("div", { class: "offline-grid" }, h("rtk-icon", { icon: this.iconPack.join_stage, size: "xl" }), h("h3", null, this.t('disconnected')), h("p", null, this.t('disconnected.description')))));
319
320
  }
320
321
  if (this.roomState === 'disconnected') {
321
- return (h(Host, null, h("div", { class: "offline-grid" }, h("rtk-icon", { icon: this.iconPack.disconnected, size: "xl" }), h("h3", null, this.t('offline')), h("p", null, this.t('offline.description')))));
322
+ /**
323
+ * NOTE(ravindra-cloudflare): When disconnected but WebRTC transports are
324
+ * still healthy, skip the offline screen — media is still flowing.
325
+ * The grid stays visible for seamless reconnection.
326
+ */
327
+ const mediaState = (_b = (_a = this.meeting) === null || _a === void 0 ? void 0 : _a.meta) === null || _b === void 0 ? void 0 : _b.mediaState;
328
+ const transportsHealthy = ((_c = mediaState === null || mediaState === void 0 ? void 0 : mediaState.send) === null || _c === void 0 ? void 0 : _c.state) === 'connected' && ((_d = mediaState === null || mediaState === void 0 ? void 0 : mediaState.recv) === null || _d === void 0 ? void 0 : _d.state) === 'connected';
329
+ if (!transportsHealthy) {
330
+ return (h(Host, null, h("div", { class: "offline-grid" }, h("rtk-icon", { icon: this.iconPack.disconnected, size: "xl" }), h("h3", null, this.t('offline')), h("p", null, this.t('offline.description')))));
331
+ }
322
332
  }
323
333
  if (this.roomState === 'failed') {
324
334
  return (h(Host, null, h("div", { class: "offline-grid" }, h("rtk-icon", { icon: this.iconPack.disconnected, size: "xl" }), h("h3", null, this.t('failed')), h("p", null, this.t('failed.description')))));
@@ -259,8 +259,7 @@ const RtkMeeting$1 = /*@__PURE__*/ proxyCustomElement(class RtkMeeting extends H
259
259
  if (this.showSetupScreen == null) {
260
260
  this.showSetupScreen = data.showSetupScreen;
261
261
  }
262
- if (meeting.connectedMeetings.supportsConnectedMeetings &&
263
- ((_a = targetStore.state.states.activeBreakoutRoomsManager) === null || _a === void 0 ? void 0 : _a.destinationMeetingId)) {
262
+ if ((_a = targetStore.state.states.activeBreakoutRoomsManager) === null || _a === void 0 ? void 0 : _a.destinationMeetingId) {
264
263
  this.showSetupScreen = false;
265
264
  }
266
265
  }
@@ -275,9 +274,7 @@ const RtkMeeting$1 = /*@__PURE__*/ proxyCustomElement(class RtkMeeting extends H
275
274
  meeting.self.addListener('roomLeft', this.roomLeftListener);
276
275
  meeting.self.addListener('mediaPermissionUpdate', this.mediaPermissionUpdateListener);
277
276
  meeting.meta.addListener('socketConnectionUpdate', this.socketConnectionUpdateListener);
278
- if (meeting.connectedMeetings.supportsConnectedMeetings) {
279
- meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
280
- }
277
+ meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
281
278
  if (meeting.self.roomJoined) {
282
279
  this.updateStates({ meeting: 'joined' });
283
280
  }
@@ -20,11 +20,11 @@ class RTKAudio {
20
20
  this.audioTracks = [];
21
21
  }
22
22
  addTrack(id, track) {
23
- if (!this.audioTracks.some((a) => a.id === id)) {
24
- this.audioTracks.push({ id, track });
25
- this.audioStream.addTrack(track);
26
- this.play();
27
- }
23
+ // Remove the track if it already exists, with the same id
24
+ this.removeTrack(id);
25
+ this.audioTracks.push({ id, track });
26
+ this.audioStream.addTrack(track);
27
+ this.play();
28
28
  }
29
29
  removeTrack(id) {
30
30
  const track = this.audioTracks.find((a) => a.id === id);
@@ -180,9 +180,7 @@ const RtkUiProvider$1 = /*@__PURE__*/ proxyCustomElement(class RtkUiProvider ext
180
180
  meeting.self.addListener('roomLeft', this.roomLeftListener);
181
181
  meeting.self.addListener('mediaPermissionUpdate', this.mediaPermissionUpdateListener);
182
182
  meeting.meta.addListener('socketConnectionUpdate', this.socketConnectionUpdateListener);
183
- if (meeting.connectedMeetings.supportsConnectedMeetings) {
184
- meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
185
- }
183
+ meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
186
184
  if (meeting.self.roomJoined) {
187
185
  this.updateStates({ meeting: 'joined' });
188
186
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2026-06-03T12:47:50",
2
+ "timestamp": "2026-06-05T07:56:56",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
5
  "version": "4.27.2",
@@ -14398,8 +14398,7 @@ const RtkMeeting = class {
14398
14398
  if (this.showSetupScreen == null) {
14399
14399
  this.showSetupScreen = data.showSetupScreen;
14400
14400
  }
14401
- if (meeting.connectedMeetings.supportsConnectedMeetings &&
14402
- ((_a = targetStore.state.states.activeBreakoutRoomsManager) === null || _a === void 0 ? void 0 : _a.destinationMeetingId)) {
14401
+ if ((_a = targetStore.state.states.activeBreakoutRoomsManager) === null || _a === void 0 ? void 0 : _a.destinationMeetingId) {
14403
14402
  this.showSetupScreen = false;
14404
14403
  }
14405
14404
  }
@@ -14414,9 +14413,7 @@ const RtkMeeting = class {
14414
14413
  meeting.self.addListener('roomLeft', this.roomLeftListener);
14415
14414
  meeting.self.addListener('mediaPermissionUpdate', this.mediaPermissionUpdateListener);
14416
14415
  meeting.meta.addListener('socketConnectionUpdate', this.socketConnectionUpdateListener);
14417
- if (meeting.connectedMeetings.supportsConnectedMeetings) {
14418
- meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
14419
- }
14416
+ meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
14420
14417
  if (meeting.self.roomJoined) {
14421
14418
  this.updateStates({ meeting: 'joined' });
14422
14419
  }
@@ -18714,6 +18711,7 @@ const RtkGrid = class {
18714
18711
  this.pinnedParticipants = this.pinnedParticipants.filter((p) => p.id !== participant.id);
18715
18712
  }
18716
18713
  render() {
18714
+ var _a, _b, _c, _d;
18717
18715
  const defaults = {
18718
18716
  meeting: this.meeting,
18719
18717
  size: this.size,
@@ -18726,7 +18724,16 @@ const RtkGrid = class {
18726
18724
  return (h(Host, null, h("div", { class: "offline-grid" }, h("rtk-icon", { icon: this.iconPack.join_stage, size: "xl" }), h("h3", null, this.t('disconnected')), h("p", null, this.t('disconnected.description')))));
18727
18725
  }
18728
18726
  if (this.roomState === 'disconnected') {
18729
- return (h(Host, null, h("div", { class: "offline-grid" }, h("rtk-icon", { icon: this.iconPack.disconnected, size: "xl" }), h("h3", null, this.t('offline')), h("p", null, this.t('offline.description')))));
18727
+ /**
18728
+ * NOTE(ravindra-cloudflare): When disconnected but WebRTC transports are
18729
+ * still healthy, skip the offline screen — media is still flowing.
18730
+ * The grid stays visible for seamless reconnection.
18731
+ */
18732
+ const mediaState = (_b = (_a = this.meeting) === null || _a === void 0 ? void 0 : _a.meta) === null || _b === void 0 ? void 0 : _b.mediaState;
18733
+ const transportsHealthy = ((_c = mediaState === null || mediaState === void 0 ? void 0 : mediaState.send) === null || _c === void 0 ? void 0 : _c.state) === 'connected' && ((_d = mediaState === null || mediaState === void 0 ? void 0 : mediaState.recv) === null || _d === void 0 ? void 0 : _d.state) === 'connected';
18734
+ if (!transportsHealthy) {
18735
+ return (h(Host, null, h("div", { class: "offline-grid" }, h("rtk-icon", { icon: this.iconPack.disconnected, size: "xl" }), h("h3", null, this.t('offline')), h("p", null, this.t('offline.description')))));
18736
+ }
18730
18737
  }
18731
18738
  if (this.roomState === 'failed') {
18732
18739
  return (h(Host, null, h("div", { class: "offline-grid" }, h("rtk-icon", { icon: this.iconPack.disconnected, size: "xl" }), h("h3", null, this.t('failed')), h("p", null, this.t('failed.description')))));
@@ -21316,11 +21323,11 @@ class RTKAudio {
21316
21323
  this.audioTracks = [];
21317
21324
  }
21318
21325
  addTrack(id, track) {
21319
- if (!this.audioTracks.some((a) => a.id === id)) {
21320
- this.audioTracks.push({ id, track });
21321
- this.audioStream.addTrack(track);
21322
- this.play();
21323
- }
21326
+ // Remove the track if it already exists, with the same id
21327
+ this.removeTrack(id);
21328
+ this.audioTracks.push({ id, track });
21329
+ this.audioStream.addTrack(track);
21330
+ this.play();
21324
21331
  }
21325
21332
  removeTrack(id) {
21326
21333
  const track = this.audioTracks.find((a) => a.id === id);
@@ -23797,9 +23804,7 @@ const RtkUiProvider = class {
23797
23804
  meeting.self.addListener('roomLeft', this.roomLeftListener);
23798
23805
  meeting.self.addListener('mediaPermissionUpdate', this.mediaPermissionUpdateListener);
23799
23806
  meeting.meta.addListener('socketConnectionUpdate', this.socketConnectionUpdateListener);
23800
- if (meeting.connectedMeetings.supportsConnectedMeetings) {
23801
- meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
23802
- }
23807
+ meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
23803
23808
  if (meeting.self.roomJoined) {
23804
23809
  this.updateStates({ meeting: 'joined' });
23805
23810
  }
@@ -1629,8 +1629,7 @@ const RtkMeeting = class {
1629
1629
  if (this.showSetupScreen == null) {
1630
1630
  this.showSetupScreen = data.showSetupScreen;
1631
1631
  }
1632
- if (meeting.connectedMeetings.supportsConnectedMeetings &&
1633
- ((_a = targetStore.state.states.activeBreakoutRoomsManager) === null || _a === void 0 ? void 0 : _a.destinationMeetingId)) {
1632
+ if ((_a = targetStore.state.states.activeBreakoutRoomsManager) === null || _a === void 0 ? void 0 : _a.destinationMeetingId) {
1634
1633
  this.showSetupScreen = false;
1635
1634
  }
1636
1635
  }
@@ -1645,9 +1644,7 @@ const RtkMeeting = class {
1645
1644
  meeting.self.addListener('roomLeft', this.roomLeftListener);
1646
1645
  meeting.self.addListener('mediaPermissionUpdate', this.mediaPermissionUpdateListener);
1647
1646
  meeting.meta.addListener('socketConnectionUpdate', this.socketConnectionUpdateListener);
1648
- if (meeting.connectedMeetings.supportsConnectedMeetings) {
1649
- meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
1650
- }
1647
+ meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
1651
1648
  if (meeting.self.roomJoined) {
1652
1649
  this.updateStates({ meeting: 'joined' });
1653
1650
  }
@@ -296,6 +296,7 @@ const RtkGrid = class {
296
296
  this.pinnedParticipants = this.pinnedParticipants.filter((p) => p.id !== participant.id);
297
297
  }
298
298
  render() {
299
+ var _a, _b, _c, _d;
299
300
  const defaults = {
300
301
  meeting: this.meeting,
301
302
  size: this.size,
@@ -308,7 +309,16 @@ const RtkGrid = class {
308
309
  return (h(Host, null, h("div", { class: "offline-grid" }, h("rtk-icon", { icon: this.iconPack.join_stage, size: "xl" }), h("h3", null, this.t('disconnected')), h("p", null, this.t('disconnected.description')))));
309
310
  }
310
311
  if (this.roomState === 'disconnected') {
311
- return (h(Host, null, h("div", { class: "offline-grid" }, h("rtk-icon", { icon: this.iconPack.disconnected, size: "xl" }), h("h3", null, this.t('offline')), h("p", null, this.t('offline.description')))));
312
+ /**
313
+ * NOTE(ravindra-cloudflare): When disconnected but WebRTC transports are
314
+ * still healthy, skip the offline screen — media is still flowing.
315
+ * The grid stays visible for seamless reconnection.
316
+ */
317
+ const mediaState = (_b = (_a = this.meeting) === null || _a === void 0 ? void 0 : _a.meta) === null || _b === void 0 ? void 0 : _b.mediaState;
318
+ const transportsHealthy = ((_c = mediaState === null || mediaState === void 0 ? void 0 : mediaState.send) === null || _c === void 0 ? void 0 : _c.state) === 'connected' && ((_d = mediaState === null || mediaState === void 0 ? void 0 : mediaState.recv) === null || _d === void 0 ? void 0 : _d.state) === 'connected';
319
+ if (!transportsHealthy) {
320
+ return (h(Host, null, h("div", { class: "offline-grid" }, h("rtk-icon", { icon: this.iconPack.disconnected, size: "xl" }), h("h3", null, this.t('offline')), h("p", null, this.t('offline.description')))));
321
+ }
312
322
  }
313
323
  if (this.roomState === 'failed') {
314
324
  return (h(Host, null, h("div", { class: "offline-grid" }, h("rtk-icon", { icon: this.iconPack.disconnected, size: "xl" }), h("h3", null, this.t('failed')), h("p", null, this.t('failed.description')))));
@@ -17,11 +17,11 @@ class RTKAudio {
17
17
  this.audioTracks = [];
18
18
  }
19
19
  addTrack(id, track) {
20
- if (!this.audioTracks.some((a) => a.id === id)) {
21
- this.audioTracks.push({ id, track });
22
- this.audioStream.addTrack(track);
23
- this.play();
24
- }
20
+ // Remove the track if it already exists, with the same id
21
+ this.removeTrack(id);
22
+ this.audioTracks.push({ id, track });
23
+ this.audioStream.addTrack(track);
24
+ this.play();
25
25
  }
26
26
  removeTrack(id) {
27
27
  const track = this.audioTracks.find((a) => a.id === id);
@@ -178,9 +178,7 @@ const RtkUiProvider = class {
178
178
  meeting.self.addListener('roomLeft', this.roomLeftListener);
179
179
  meeting.self.addListener('mediaPermissionUpdate', this.mediaPermissionUpdateListener);
180
180
  meeting.meta.addListener('socketConnectionUpdate', this.socketConnectionUpdateListener);
181
- if (meeting.connectedMeetings.supportsConnectedMeetings) {
182
- meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
183
- }
181
+ meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
184
182
  if (meeting.self.roomJoined) {
185
183
  this.updateStates({ meeting: 'joined' });
186
184
  }