@naviedu/room-platform-react 0.0.9 → 0.0.11

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/README.md CHANGED
@@ -85,13 +85,18 @@ layout that allows the room to occupy the viewport.
85
85
  | `extensions` | No | Host-provided top-bar, workspace, sidebar, monitor, and participant extensions. |
86
86
  | `integrations` | No | Chat and whiteboard configuration. |
87
87
  | `isPracticeMode` | No | Enables practice-room presentation behavior. |
88
- | `showLocalPreview` | No | Shows the local preview in the sidebar. Defaults to `true`. |
89
- | `primaryCameraSelector` | No | Selects the primary camera track when the default selection is not suitable. |
90
88
  | `onError` | No | Receives connection, media, and action errors. |
91
89
  | `onLifecycleEvent` | No | Receives exchange, renewal, and reconnect lifecycle events. |
92
90
  | `onExit` | No | Called when the user chooses to leave the room. |
93
91
  | `children` | No | Replaces the default workspace while keeping the provider and room runtime. |
94
92
 
93
+ The default teaching stage selects the available participant camera carrying
94
+ the canonical `room:moderate` capability. Screen share remains primary and the
95
+ moderator camera becomes its overlay. If no moderator camera is available, the
96
+ stage keeps its waiting state and never promotes a student camera. The local
97
+ sidebar preview is hidden only when that selected moderator camera is local;
98
+ its existing desktop breakpoint remains unchanged.
99
+
95
100
  ### Error and lifecycle callbacks
96
101
 
97
102
  ```tsx
package/index.d.ts CHANGED
@@ -393,7 +393,6 @@ export declare type RoomPlatformExtensions = {
393
393
  topBarTrailing?: ComponentType<RoomPlatformExtensionProps>;
394
394
  monitor?: {
395
395
  roster: readonly RoomParticipantRosterEntry[];
396
- roomEligible: boolean;
397
396
  };
398
397
  mainWorkspace?: {
399
398
  placement: 'overlay' | 'alongside-stage';
@@ -617,7 +616,7 @@ export declare type RoomPlatformProviderProps = PropsWithChildren<{
617
616
  }>;
618
617
  }>;
619
618
 
620
- export declare function RoomPlatformRoom({ children, extensions, integrations, isPracticeMode, onExit, primaryCameraSelector, showLocalPreview, sizing, ...providerProps }: RoomPlatformRoomProps): JSX.Element;
619
+ export declare function RoomPlatformRoom({ children, extensions, integrations, isPracticeMode, onExit, sizing, ...providerProps }: RoomPlatformRoomProps): JSX.Element;
621
620
 
622
621
  export declare type RoomPlatformRoomProps = {
623
622
  apiBaseUrl: string;
@@ -626,8 +625,6 @@ export declare type RoomPlatformRoomProps = {
626
625
  launchToken: string;
627
626
  isPracticeMode?: boolean;
628
627
  sizing?: RoomPlatformSizing;
629
- primaryCameraSelector?: (cameraTracks: readonly TrackReference[], activeSpeakerParticipantIdentity?: string) => TrackReference | null;
630
- showLocalPreview?: boolean;
631
628
  onError?: (event: RoomPlatformErrorEvent) => void;
632
629
  onLifecycleEvent?: (event: RoomPlatformLifecycleEvent) => void;
633
630
  onExit?: () => void;
@@ -663,14 +660,13 @@ export declare type RoomPlatformShellProps = {
663
660
 
664
661
  export declare type RoomPlatformSizing = 'viewport' | 'container';
665
662
 
666
- export declare function RoomPlatformSpeakQueue({ activeSpeakerParticipantIdentity, activeSpeakerSlot, canApproveSpeak, canClearActiveSpeaker, canRejectSpeak, isClearingActiveSpeaker, isPracticeMode, onApproveSpeakRequest, onClearActiveSpeaker, onRejectSpeakRequest, participants, raisedHandParticipantIdentities, }: {
663
+ export declare function RoomPlatformSpeakQueue({ activeSpeakerParticipantIdentity, activeSpeakerSlot, canApproveSpeak, canClearActiveSpeaker, canRejectSpeak, isClearingActiveSpeaker, onApproveSpeakRequest, onClearActiveSpeaker, onRejectSpeakRequest, participants, raisedHandParticipantIdentities, }: {
667
664
  activeSpeakerParticipantIdentity?: string;
668
665
  activeSpeakerSlot?: ReactNode;
669
666
  canApproveSpeak?: boolean;
670
667
  canClearActiveSpeaker?: boolean;
671
668
  canRejectSpeak?: boolean;
672
669
  isClearingActiveSpeaker?: boolean;
673
- isPracticeMode?: boolean;
674
670
  onApproveSpeakRequest?: (participantIdentity: string) => Promise<void> | void;
675
671
  onClearActiveSpeaker?: () => void;
676
672
  onRejectSpeakRequest?: (participantIdentity: string) => Promise<void> | void;
package/index.esm.js CHANGED
@@ -173,7 +173,13 @@ var getParticipantTabTitle = function(participantTab) {
173
173
  };
174
174
 
175
175
  var RoomPlatformCapability = {
176
+ ROOM_JOIN: 'room:join',
177
+ CHAT_SEND: 'chat:send',
178
+ MEDIA_SUBSCRIBE: 'media:subscribe',
179
+ MEDIA_PUBLISH_AUDIO: 'media:publish_audio',
180
+ MEDIA_PUBLISH_VIDEO: 'media:publish_video',
176
181
  MEDIA_SHARE_SCREEN: 'media:share_screen',
182
+ DATA_PUBLISH: 'data:publish',
177
183
  ROOM_SPEAK_REQUEST: 'room:speak_request',
178
184
  ROOM_MODERATE: 'room:moderate',
179
185
  MONITOR_MANAGE: 'monitor:manage',
@@ -182,6 +188,10 @@ var RoomPlatformCapability = {
182
188
  PRIVATE_ROOM_CLOSE: 'private_room:close',
183
189
  WHITEBOARD_CLEAR: 'whiteboard:clear'
184
190
  };
191
+ var roomPlatformCapabilities = Object.values(RoomPlatformCapability);
192
+ var isRoomPlatformCapability = function(value) {
193
+ return roomPlatformCapabilities.includes(value);
194
+ };
185
195
 
186
196
  function _define_property$y(obj, key, value) {
187
197
  if (key in obj) {
@@ -9680,7 +9690,7 @@ function RoomPlatformVideoTile(param) {
9680
9690
  return /*#__PURE__*/ jsxs("div", {
9681
9691
  "aria-label": resolvedLabel,
9682
9692
  className: [
9683
- 'relative overflow-hidden rounded-lg bg-slate-900 text-white ring-1 ring-white/10',
9693
+ 'relative overflow-hidden rounded-lg bg-slate-900 text-white',
9684
9694
  className
9685
9695
  ].filter(Boolean).join(' '),
9686
9696
  "data-kind": kind,
@@ -19560,19 +19570,28 @@ function getNearestMarkerExpiry(objects) {
19560
19570
  return expiries.length ? (_Math = Math).min.apply(_Math, _to_consumable_array$5(expiries)) : undefined;
19561
19571
  }
19562
19572
  function getNormalizedPoint(event, frameRect) {
19563
- if (!Number.isFinite(frameRect.left) || !Number.isFinite(frameRect.top)) return undefined;
19564
- if (!Number.isFinite(frameRect.width) || !Number.isFinite(frameRect.height)) return undefined;
19565
- if (frameRect.width <= 0 || frameRect.height <= 0) return undefined;
19573
+ var currentFrameRect = getPointerFrameRect(event, frameRect);
19574
+ if (!currentFrameRect) return undefined;
19566
19575
  var clientX = getEventCoordinate(event, 'clientX');
19567
19576
  var clientY = getEventCoordinate(event, 'clientY');
19568
19577
  if (!Number.isFinite(clientX) || !Number.isFinite(clientY)) return undefined;
19569
- var x = (clientX - frameRect.left) / frameRect.width;
19570
- var y = (clientY - frameRect.top) / frameRect.height;
19578
+ var x = (clientX - currentFrameRect.left) / currentFrameRect.width;
19579
+ var y = (clientY - currentFrameRect.top) / currentFrameRect.height;
19571
19580
  return {
19572
19581
  x: clamp01(x),
19573
19582
  y: clamp01(y)
19574
19583
  };
19575
19584
  }
19585
+ function getPointerFrameRect(event, fallback) {
19586
+ var rect = event.currentTarget.getBoundingClientRect();
19587
+ if (Number.isFinite(rect.left) && Number.isFinite(rect.top) && Number.isFinite(rect.width) && Number.isFinite(rect.height) && rect.width > 0 && rect.height > 0) {
19588
+ return rect;
19589
+ }
19590
+ if (!Number.isFinite(fallback.left) || !Number.isFinite(fallback.top) || !Number.isFinite(fallback.width) || !Number.isFinite(fallback.height) || fallback.width <= 0 || fallback.height <= 0) {
19591
+ return undefined;
19592
+ }
19593
+ return fallback;
19594
+ }
19576
19595
  function getEventCoordinate(event, key) {
19577
19596
  var _event_nativeEvent;
19578
19597
  if (Number.isFinite(event[key])) return event[key];
@@ -26672,7 +26691,7 @@ function _ts_generator$1(thisArg, body) {
26672
26691
  }
26673
26692
  }
26674
26693
  function RoomPlatformSpeakQueue(param) {
26675
- var activeSpeakerParticipantIdentity = param.activeSpeakerParticipantIdentity, activeSpeakerSlot = param.activeSpeakerSlot, canApproveSpeak = param.canApproveSpeak, canClearActiveSpeaker = param.canClearActiveSpeaker, canRejectSpeak = param.canRejectSpeak, isClearingActiveSpeaker = param.isClearingActiveSpeaker, _param_isPracticeMode = param.isPracticeMode, isPracticeMode = _param_isPracticeMode === void 0 ? false : _param_isPracticeMode, onApproveSpeakRequest = param.onApproveSpeakRequest, onClearActiveSpeaker = param.onClearActiveSpeaker, onRejectSpeakRequest = param.onRejectSpeakRequest, participants = param.participants, raisedHandParticipantIdentities = param.raisedHandParticipantIdentities;
26694
+ var activeSpeakerParticipantIdentity = param.activeSpeakerParticipantIdentity, activeSpeakerSlot = param.activeSpeakerSlot, canApproveSpeak = param.canApproveSpeak, canClearActiveSpeaker = param.canClearActiveSpeaker, canRejectSpeak = param.canRejectSpeak, isClearingActiveSpeaker = param.isClearingActiveSpeaker, onApproveSpeakRequest = param.onApproveSpeakRequest, onClearActiveSpeaker = param.onClearActiveSpeaker, onRejectSpeakRequest = param.onRejectSpeakRequest, participants = param.participants, raisedHandParticipantIdentities = param.raisedHandParticipantIdentities;
26676
26695
  var participantsByIdentity = new Map(participants.map(function(participant) {
26677
26696
  return [
26678
26697
  participant.participantIdentity,
@@ -26751,11 +26770,11 @@ function RoomPlatformSpeakQueue(param) {
26751
26770
  "Bục giảng"
26752
26771
  ]
26753
26772
  }),
26754
- !isPracticeMode ? /*#__PURE__*/ jsx(Badge, {
26773
+ /*#__PURE__*/ jsx(Badge, {
26755
26774
  variant: "outline",
26756
26775
  className: "border-liveclass-orange/30 text-liveclass-orange",
26757
26776
  children: raisedHandParticipantIdentities.length
26758
- }) : null
26777
+ })
26759
26778
  ]
26760
26779
  }),
26761
26780
  hasActiveSpeaker ? /*#__PURE__*/ jsxs("div", {
@@ -26856,7 +26875,7 @@ function RoomPlatformSpeakQueue(param) {
26856
26875
  }, participantIdentity);
26857
26876
  }) : /*#__PURE__*/ jsx("p", {
26858
26877
  className: "text-sm text-muted-foreground",
26859
- children: isPracticeMode ? 'Danh sách chờ phát biểu sẽ được đồng bộ theo trạng thái phòng.' : 'Không có học sinh chờ phát biểu.'
26878
+ children: "Kh\xf4ng c\xf3 học sinh chờ ph\xe1t biểu."
26860
26879
  })
26861
26880
  ]
26862
26881
  });
@@ -26937,6 +26956,24 @@ function _unsupported_iterable_to_array$1(o, minLen) {
26937
26956
  if (n === "Map" || n === "Set") return Array.from(n);
26938
26957
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$1(o, minLen);
26939
26958
  }
26959
+ var cameraOverlayClassName = 'absolute left-4 top-4 z-30 aspect-video w-48 max-w-[40%]';
26960
+ function RoomPlatformCameraOverlay(param) {
26961
+ var trackRef = param.trackRef, status = param.status, testId = param.testId;
26962
+ return /*#__PURE__*/ jsx("div", {
26963
+ "data-identity": trackRef === null || trackRef === void 0 ? void 0 : trackRef.participant.identity,
26964
+ "data-status": status,
26965
+ "data-testid": testId,
26966
+ className: cameraOverlayClassName,
26967
+ style: {
26968
+ aspectRatio: getTrackAspectRatio(trackRef)
26969
+ },
26970
+ children: trackRef ? /*#__PURE__*/ jsx(RoomPlatformVideoTile, {
26971
+ kind: "overlay",
26972
+ mediaClassName: "h-full w-full overflow-hidden",
26973
+ trackRef: trackRef
26974
+ }) : 'Đang chờ tín hiệu lớp học'
26975
+ });
26976
+ }
26940
26977
  function getTrackAspectRatio(trackRef) {
26941
26978
  var _ref, _ref1;
26942
26979
  var _publication_track, _publication_track_mediaStreamTrack_getSettings, _publication_track_mediaStreamTrack, _publication_track1;
@@ -26974,17 +27011,10 @@ function RoomPlatformStage(param) {
26974
27011
  var resolvedOverlayTrack = overlayTrack !== null && overlayTrack !== void 0 ? overlayTrack : isScreenShare ? model.cameraOverlay : undefined;
26975
27012
  var frameClassName = model.primary ? 'relative flex h-full min-h-0 w-full items-center justify-center overflow-hidden rounded-lg text-white ring-1 ring-white/10' : 'relative flex h-full min-h-0 w-full items-center justify-center overflow-hidden rounded-lg bg-slate-950 p-4 text-sm text-slate-300 ring-1 ring-white/10';
26976
27013
  if (layout === 'camera-overlay') {
26977
- return /*#__PURE__*/ jsx("div", {
26978
- className: "absolute left-4 top-4 z-10 aspect-video w-48 max-w-[40%] overflow-hidden rounded-lg bg-slate-950 text-white ring-1 ring-white/20",
26979
- "data-status": status,
26980
- "data-testid": "room-platform-stage",
26981
- style: frameStyle,
26982
- children: cameraOverlayTrack ? /*#__PURE__*/ jsx(RoomPlatformVideoTile, {
26983
- className: "h-full w-full",
26984
- kind: "overlay",
26985
- mediaClassName: "h-full w-full overflow-hidden",
26986
- trackRef: cameraOverlayTrack
26987
- }) : 'Đang chờ tín hiệu lớp học'
27014
+ return /*#__PURE__*/ jsx(RoomPlatformCameraOverlay, {
27015
+ status: status,
27016
+ testId: "room-platform-stage",
27017
+ trackRef: cameraOverlayTrack
26988
27018
  });
26989
27019
  }
26990
27020
  return /*#__PURE__*/ jsxs("div", {
@@ -27021,15 +27051,9 @@ function RoomPlatformStage(param) {
27021
27051
  }) : 'Đang chờ tín hiệu lớp học'
27022
27052
  })
27023
27053
  }),
27024
- resolvedOverlayTrack ? /*#__PURE__*/ jsx("div", {
27025
- "data-identity": resolvedOverlayTrack.participant.identity,
27026
- "data-testid": "room-platform-camera-overlay",
27027
- className: "absolute left-4 top-4 z-30 aspect-video w-48 max-w-[40%] ring-1 ring-white/20",
27028
- children: /*#__PURE__*/ jsx(RoomPlatformVideoTile, {
27029
- kind: "overlay",
27030
- mediaClassName: "h-full w-full overflow-hidden",
27031
- trackRef: resolvedOverlayTrack
27032
- })
27054
+ resolvedOverlayTrack ? /*#__PURE__*/ jsx(RoomPlatformCameraOverlay, {
27055
+ testId: "room-platform-camera-overlay",
27056
+ trackRef: resolvedOverlayTrack
27033
27057
  }) : null
27034
27058
  ]
27035
27059
  });
@@ -27066,22 +27090,29 @@ function RoomPlatformTopBar(param) {
27066
27090
  });
27067
27091
  }
27068
27092
 
27069
- var isSpeakingRemote = function(param) {
27070
- var participant = param.participant;
27071
- return !participant.isLocal && participant.isSpeaking;
27072
- };
27073
- var isRemote = function(param) {
27074
- var participant = param.participant;
27075
- return !participant.isLocal;
27076
- };
27077
27093
  var hasAvailableTrackMedia = function(param) {
27078
27094
  var publication = param.publication;
27079
27095
  var state = publication;
27080
27096
  return !state.isMuted && state.isSubscribed !== false && state.track !== null;
27081
27097
  };
27098
+ var capabilitiesFromMetadata = function(metadata) {
27099
+ if (!metadata) return [];
27100
+ try {
27101
+ var capabilities = JSON.parse(metadata).capabilities;
27102
+ return Array.isArray(capabilities) && capabilities.every(function(value) {
27103
+ return typeof value === 'string' && isRoomPlatformCapability(value);
27104
+ }) ? capabilities : [];
27105
+ } catch (unused) {
27106
+ return [];
27107
+ }
27108
+ };
27109
+ var isModeratorCamera = function(param, localCapabilities) {
27110
+ var participant = param.participant;
27111
+ return (participant.isLocal ? localCapabilities : capabilitiesFromMetadata(participant.metadata)).includes(RoomPlatformCapability.ROOM_MODERATE);
27112
+ };
27082
27113
  function selectRoomPlatformStage(tracks) {
27083
- var _ref = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}, activeSpeakerParticipantIdentity = _ref.activeSpeakerParticipantIdentity, primaryCameraSelector = _ref.primaryCameraSelector;
27084
- var _ref1, _cameras_find, _cameras_find1, _ref2, _shares_;
27114
+ var _ref = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}, activeSpeakerParticipantIdentity = _ref.activeSpeakerParticipantIdentity, localCapabilities = _ref.localCapabilities;
27115
+ var _ref1, _shares_;
27085
27116
  var availableTracks = tracks.filter(hasAvailableTrackMedia);
27086
27117
  var shares = availableTracks.filter(function(param) {
27087
27118
  var source = param.source;
@@ -27091,13 +27122,10 @@ function selectRoomPlatformStage(tracks) {
27091
27122
  var source = param.source;
27092
27123
  return source === Track.Source.Camera;
27093
27124
  });
27094
- var genericPrimaryCamera = (_ref1 = (_cameras_find = cameras.find(isSpeakingRemote)) !== null && _cameras_find !== void 0 ? _cameras_find : cameras.find(isRemote)) !== null && _ref1 !== void 0 ? _ref1 : cameras[0];
27095
- var selectedPrimaryCamera = primaryCameraSelector ? primaryCameraSelector(cameras, activeSpeakerParticipantIdentity) : shares[0] ? (_cameras_find1 = cameras.find(function(param) {
27096
- var participant = param.participant;
27097
- var _shares_;
27098
- return participant.identity === ((_shares_ = shares[0]) === null || _shares_ === void 0 ? void 0 : _shares_.participant.identity);
27099
- })) !== null && _cameras_find1 !== void 0 ? _cameras_find1 : genericPrimaryCamera : genericPrimaryCamera;
27100
- var primary = (_ref2 = (_shares_ = shares[0]) !== null && _shares_ !== void 0 ? _shares_ : selectedPrimaryCamera) !== null && _ref2 !== void 0 ? _ref2 : undefined;
27125
+ var selectedPrimaryCamera = cameras.find(function(camera) {
27126
+ return isModeratorCamera(camera, localCapabilities !== null && localCapabilities !== void 0 ? localCapabilities : []);
27127
+ });
27128
+ var primary = (_ref1 = (_shares_ = shares[0]) !== null && _shares_ !== void 0 ? _shares_ : selectedPrimaryCamera) !== null && _ref1 !== void 0 ? _ref1 : undefined;
27101
27129
  var cameraOverlay = shares[0] ? selectedPrimaryCamera !== null && selectedPrimaryCamera !== void 0 ? selectedPrimaryCamera : undefined : undefined;
27102
27130
  var localPreview = cameras.find(function(param) {
27103
27131
  var participant = param.participant;
@@ -27125,8 +27153,9 @@ function selectRoomPlatformStage(tracks) {
27125
27153
  };
27126
27154
  }
27127
27155
 
27128
- function useRoomPlatformStage(primaryCameraSelector) {
27129
- var controlState = useRoomPlatform().controlState;
27156
+ function useRoomPlatformStage() {
27157
+ var _ref;
27158
+ var _useRoomPlatform = useRoomPlatform(), access = _useRoomPlatform.access, controlState = _useRoomPlatform.controlState;
27130
27159
  return selectRoomPlatformStage(useTracks([
27131
27160
  Track.Source.Camera,
27132
27161
  Track.Source.ScreenShare
@@ -27134,7 +27163,7 @@ function useRoomPlatformStage(primaryCameraSelector) {
27134
27163
  onlySubscribed: true
27135
27164
  }), {
27136
27165
  activeSpeakerParticipantIdentity: controlState === null || controlState === void 0 ? void 0 : controlState.activeSpeakerParticipantIdentity,
27137
- primaryCameraSelector: primaryCameraSelector
27166
+ localCapabilities: (_ref = access === null || access === void 0 ? void 0 : access.capabilities) !== null && _ref !== void 0 ? _ref : []
27138
27167
  });
27139
27168
  }
27140
27169
 
@@ -27411,6 +27440,32 @@ var emptyStageModel = {
27411
27440
  },
27412
27441
  primary: undefined
27413
27442
  };
27443
+ function RoomPlatformPracticeModeMediaPolicy(param) {
27444
+ var isPracticeMode = param.isPracticeMode;
27445
+ var _useRoomPlatform = useRoomPlatform(), localMedia = _useRoomPlatform.localMedia, setLocalMediaEnabled = _useRoomPlatform.setLocalMediaEnabled;
27446
+ var previousIsPracticeModeRef = useRef(isPracticeMode);
27447
+ var shouldStopScreenShareRef = useRef(false);
27448
+ useEffect(function() {
27449
+ if (!previousIsPracticeModeRef.current && isPracticeMode) {
27450
+ shouldStopScreenShareRef.current = true;
27451
+ }
27452
+ previousIsPracticeModeRef.current = isPracticeMode;
27453
+ if (!isPracticeMode) {
27454
+ shouldStopScreenShareRef.current = false;
27455
+ return;
27456
+ }
27457
+ if (!shouldStopScreenShareRef.current || !localMedia.screenShare) return;
27458
+ shouldStopScreenShareRef.current = false;
27459
+ void setLocalMediaEnabled('screenShare', false).catch(function() {
27460
+ return undefined;
27461
+ });
27462
+ }, [
27463
+ isPracticeMode,
27464
+ localMedia.screenShare,
27465
+ setLocalMediaEnabled
27466
+ ]);
27467
+ return null;
27468
+ }
27414
27469
  function getShareSessionKey(trackSid) {
27415
27470
  return trackSid ? "livekit:".concat(trackSid) : undefined;
27416
27471
  }
@@ -27447,13 +27502,14 @@ function RoomPlatformWhiteboardShareLifecycle(param) {
27447
27502
  return null;
27448
27503
  }
27449
27504
  var RoomPlatformWorkspaceContent = function(param) {
27450
- var cameraBackground = param.cameraBackground, integrations = param.integrations, extensions = param.extensions, isPracticeMode = param.isPracticeMode, onExit = param.onExit; param.primaryCameraSelector; var showLocalPreview = param.showLocalPreview, sizing = param.sizing, stageModel = param.stageModel;
27451
- var _ref, _ref1;
27452
- var _resolvedStageModel_primary, _extensions_sidebarTabs;
27505
+ var cameraBackground = param.cameraBackground, integrations = param.integrations, extensions = param.extensions; param.isPracticeMode; var onExit = param.onExit, sizing = param.sizing, stageModel = param.stageModel;
27506
+ var _resolvedStageModel_cameraOverlay, _ref, _ref1;
27507
+ var _resolvedStageModel_primary, _resolvedStageModel_primary1, _extensions_sidebarTabs;
27453
27508
  var _useRoomPlatform = useRoomPlatform(), access = _useRoomPlatform.access, controlState = _useRoomPlatform.controlState, error = _useRoomPlatform.error, hasCapability = _useRoomPlatform.hasCapability, isActionPending = _useRoomPlatform.isActionPending, localPreviewTrack = _useRoomPlatform.localPreviewTrack, performAction = _useRoomPlatform.performAction, status = _useRoomPlatform.status;
27454
27509
  var _useRoomPlatformPrivateRoom = useRoomPlatformPrivateRoom(), cancelPrivateRoom = _useRoomPlatformPrivateRoom.cancelPrivateRoom, currentPrivateRoomOperation = _useRoomPlatformPrivateRoom.currentPrivateRoomOperation;
27455
27510
  var resolvedStageModel = stageModel !== null && stageModel !== void 0 ? stageModel : emptyStageModel;
27456
- var shareSessionKey = ((_resolvedStageModel_primary = resolvedStageModel.primary) === null || _resolvedStageModel_primary === void 0 ? void 0 : _resolvedStageModel_primary.source) === Track.Source.ScreenShare ? getShareSessionKey(resolvedStageModel.primary.publication.trackSid) : undefined;
27511
+ var selectedHostCamera = (_resolvedStageModel_cameraOverlay = resolvedStageModel.cameraOverlay) !== null && _resolvedStageModel_cameraOverlay !== void 0 ? _resolvedStageModel_cameraOverlay : ((_resolvedStageModel_primary = resolvedStageModel.primary) === null || _resolvedStageModel_primary === void 0 ? void 0 : _resolvedStageModel_primary.source) === Track.Source.Camera ? resolvedStageModel.primary : undefined;
27512
+ var shareSessionKey = ((_resolvedStageModel_primary1 = resolvedStageModel.primary) === null || _resolvedStageModel_primary1 === void 0 ? void 0 : _resolvedStageModel_primary1.source) === Track.Source.ScreenShare ? getShareSessionKey(resolvedStageModel.primary.publication.trackSid) : undefined;
27457
27513
  var participants = useRoomPresence();
27458
27514
  var currentParticipantPresence = participants.find(function(participant) {
27459
27515
  return participant.isLocal;
@@ -27497,7 +27553,7 @@ var RoomPlatformWorkspaceContent = function(param) {
27497
27553
  };
27498
27554
  var participantTab = extensions === null || extensions === void 0 ? void 0 : extensions.participantTab;
27499
27555
  var monitor = extensions === null || extensions === void 0 ? void 0 : extensions.monitor;
27500
- var canUseMonitor = Boolean((monitor === null || monitor === void 0 ? void 0 : monitor.roomEligible) && hasCapability('monitor:manage'));
27556
+ var canUseMonitor = hasCapability('monitor:manage');
27501
27557
  var handleMonitorStartError = useCallback(function() {
27502
27558
  setStageView('teaching');
27503
27559
  toast.error('Không thể bật Monitor. Vui lòng thử lại.');
@@ -27602,10 +27658,10 @@ var RoomPlatformWorkspaceContent = function(param) {
27602
27658
  var activeSpeakerSlot = resolvedStageModel.activeSpeaker && !isSelfActiveSpeaker ? /*#__PURE__*/ jsx(RoomPlatformActiveSpeaker, {
27603
27659
  trackRef: resolvedStageModel.activeSpeaker
27604
27660
  }) : undefined;
27605
- var localMediaSlot = showLocalPreview ? /*#__PURE__*/ jsx(RoomPlatformLocalPreview, {
27661
+ var localMediaSlot = (selectedHostCamera === null || selectedHostCamera === void 0 ? void 0 : selectedHostCamera.participant.isLocal) ? undefined : /*#__PURE__*/ jsx(RoomPlatformLocalPreview, {
27606
27662
  localPreviewTrack: localPreviewTrack,
27607
27663
  trackRef: resolvedStageModel.localPreview
27608
- }) : undefined;
27664
+ });
27609
27665
  var activeSpeakerMediaSlot = hasActiveSpeaker && !canModerate ? activeSpeakerSlot : undefined;
27610
27666
  var isClearingActiveSpeaker = isActionPending(RoomPlatformAction.SPEAKER_CLEAR);
27611
27667
  var clearActiveSpeaker = function() {
@@ -27648,7 +27704,6 @@ var RoomPlatformWorkspaceContent = function(param) {
27648
27704
  canClearActiveSpeaker: true,
27649
27705
  canRejectSpeak: true,
27650
27706
  isClearingActiveSpeaker: isClearingActiveSpeaker,
27651
- isPracticeMode: isPracticeMode,
27652
27707
  onApproveSpeakRequest: approveSpeakRequest,
27653
27708
  onClearActiveSpeaker: clearActiveSpeaker,
27654
27709
  onRejectSpeakRequest: rejectSpeakRequest,
@@ -27828,7 +27883,7 @@ var RoomPlatformWorkspaceContent = function(param) {
27828
27883
  });
27829
27884
  };
27830
27885
  var RoomPlatformConnectedWorkspace = function(props) {
27831
- var stageModel = useRoomPlatformStage(props.primaryCameraSelector);
27886
+ var stageModel = useRoomPlatformStage();
27832
27887
  return /*#__PURE__*/ jsx(RoomPlatformWorkspaceContent, _object_spread_props(_object_spread({}, props), {
27833
27888
  stageModel: stageModel
27834
27889
  }));
@@ -28000,31 +28055,32 @@ function RoomPlatformPrivateRoomRuntime(param) {
28000
28055
  });
28001
28056
  }
28002
28057
  function RoomPlatformRoom(_0) {
28003
- var children = _0.children, extensions = _0.extensions, integrations = _0.integrations, isPracticeMode = _0.isPracticeMode, onExit = _0.onExit, primaryCameraSelector = _0.primaryCameraSelector, _0_showLocalPreview = _0.showLocalPreview, showLocalPreview = _0_showLocalPreview === void 0 ? true : _0_showLocalPreview, _0_sizing = _0.sizing, sizing = _0_sizing === void 0 ? 'viewport' : _0_sizing, providerProps = _object_without_properties(_0, [
28058
+ var children = _0.children, extensions = _0.extensions, integrations = _0.integrations, isPracticeMode = _0.isPracticeMode, onExit = _0.onExit, _0_sizing = _0.sizing, sizing = _0_sizing === void 0 ? 'viewport' : _0_sizing, providerProps = _object_without_properties(_0, [
28004
28059
  "children",
28005
28060
  "extensions",
28006
28061
  "integrations",
28007
28062
  "isPracticeMode",
28008
28063
  "onExit",
28009
- "primaryCameraSelector",
28010
- "showLocalPreview",
28011
28064
  "sizing"
28012
28065
  ]);
28013
- return /*#__PURE__*/ jsx(RoomPlatformProvider, _object_spread_props(_object_spread({}, providerProps), {
28014
- children: /*#__PURE__*/ jsx(RoomPlatformMediaRuntime, {
28015
- children: /*#__PURE__*/ jsx(RoomPlatformPrivateRoomRuntime, {
28016
- integrations: integrations,
28017
- children: children !== null && children !== void 0 ? children : /*#__PURE__*/ jsx(RoomPlatformWorkspace, {
28018
- extensions: extensions,
28066
+ return /*#__PURE__*/ jsxs(RoomPlatformProvider, _object_spread_props(_object_spread({}, providerProps), {
28067
+ children: [
28068
+ /*#__PURE__*/ jsx(RoomPlatformPracticeModeMediaPolicy, {
28069
+ isPracticeMode: isPracticeMode
28070
+ }),
28071
+ /*#__PURE__*/ jsx(RoomPlatformMediaRuntime, {
28072
+ children: /*#__PURE__*/ jsx(RoomPlatformPrivateRoomRuntime, {
28019
28073
  integrations: integrations,
28020
- isPracticeMode: isPracticeMode,
28021
- onExit: onExit,
28022
- primaryCameraSelector: primaryCameraSelector,
28023
- showLocalPreview: showLocalPreview,
28024
- sizing: sizing
28074
+ children: children !== null && children !== void 0 ? children : /*#__PURE__*/ jsx(RoomPlatformWorkspace, {
28075
+ extensions: extensions,
28076
+ integrations: integrations,
28077
+ isPracticeMode: isPracticeMode,
28078
+ onExit: onExit,
28079
+ sizing: sizing
28080
+ })
28025
28081
  })
28026
28082
  })
28027
- })
28083
+ ]
28028
28084
  }));
28029
28085
  }
28030
28086
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naviedu/room-platform-react",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "type": "module",
5
5
  "main": "./index.esm.js",
6
6
  "module": "./index.esm.js",
package/styles.css CHANGED
@@ -1144,6 +1144,10 @@
1144
1144
  --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
1145
1145
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
1146
1146
  }
1147
+ .room-platform-room .ring {
1148
+ --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
1149
+ box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
1150
+ }
1147
1151
  .room-platform-room .ring-1 {
1148
1152
  --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
1149
1153
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
@@ -1170,12 +1174,6 @@
1170
1174
  --tw-ring-color: color-mix(in oklab, var(--color-white) 10%, transparent);
1171
1175
  }
1172
1176
  }
1173
- .room-platform-room .ring-white\/20 {
1174
- --tw-ring-color: color-mix(in srgb, #fff 20%, transparent);
1175
- @supports (color: color-mix(in lab, red, red)) {
1176
- --tw-ring-color: color-mix(in oklab, var(--color-white) 20%, transparent);
1177
- }
1178
- }
1179
1177
  .room-platform-room .outline-hidden {
1180
1178
  --tw-outline-style: none;
1181
1179
  outline-style: none;