diff --git a/packages/hms-video-store/src/IHMSActions.ts b/packages/hms-video-store/src/IHMSActions.ts index ccdd3635f4..625903f109 100644 --- a/packages/hms-video-store/src/IHMSActions.ts +++ b/packages/hms-video-store/src/IHMSActions.ts @@ -1,3 +1,4 @@ +import { TranscriptionConfig } from './interfaces/transcription-config'; import { HLSConfig, HLSTimedMetadata, @@ -371,6 +372,18 @@ export interface IHMSActions; + /** + * If you want to start transcriptions(Closed Caption). + * @param params.mode This is the mode which represent the type of transcription. Currently we have Caption mode only + */ + startTranscription(params: TranscriptionConfig): Promise; + + /** + * If you want to stop transcriptions(Closed Caption). + * @param params.mode This is the mode which represent the type of transcription you want to stop. Currently we have Caption mode only + */ + stopTranscription(params: TranscriptionConfig): Promise; + /** * @alpha * Used to define date range metadata in a media playlist. diff --git a/packages/hms-video-store/src/interfaces/hms.ts b/packages/hms-video-store/src/interfaces/hms.ts index 22bfe25ebc..14b983ab6c 100644 --- a/packages/hms-video-store/src/interfaces/hms.ts +++ b/packages/hms-video-store/src/interfaces/hms.ts @@ -12,6 +12,7 @@ import { HMSHLS, HMSRecording, HMSRTMP, HMSTranscriptionInfo } from './room'; import { RTMPRecordingConfig } from './rtmp-recording-config'; import { HMSInteractivityCenter, HMSSessionStore } from './session-store'; import { HMSScreenShareConfig } from './track-settings'; +import { TranscriptionConfig } from './transcription-config'; import { HMSAudioListener, HMSConnectionQualityListener, HMSUpdateListener } from './update-listener'; import { HMSAnalyticsLevel } from '../analytics/AnalyticsEventLevel'; import { IAudioOutputManager } from '../device-manager/AudioOutputManager'; @@ -61,6 +62,8 @@ export interface HMSInterface { */ startHLSStreaming(params?: HLSConfig): Promise; stopHLSStreaming(params?: HLSConfig): Promise; + startTranscription(params: TranscriptionConfig): Promise; + stopTranscription(params: TranscriptionConfig): Promise; getRecordingState(): HMSRecording | undefined; getRTMPState(): HMSRTMP | undefined; getHLSState(): HMSHLS | undefined; diff --git a/packages/hms-video-store/src/interfaces/index.ts b/packages/hms-video-store/src/interfaces/index.ts index 8bfb7576e5..f18940854f 100644 --- a/packages/hms-video-store/src/interfaces/index.ts +++ b/packages/hms-video-store/src/interfaces/index.ts @@ -19,3 +19,4 @@ export * from './webrtc-stats'; export * from './framework-info'; export * from './get-token'; export * from './session-store'; +export * from './transcription-config'; diff --git a/packages/hms-video-store/src/interfaces/room.ts b/packages/hms-video-store/src/interfaces/room.ts index 66c06dc19b..db861e0725 100644 --- a/packages/hms-video-store/src/interfaces/room.ts +++ b/packages/hms-video-store/src/interfaces/room.ts @@ -123,6 +123,7 @@ export interface HLSVariant { Transcription related details */ export enum HMSTranscriptionState { + INITIALISED = 'initialised', STARTED = 'started', STOPPED = 'stopped', FAILED = 'failed', @@ -133,4 +134,9 @@ export enum HMSTranscriptionMode { export interface HMSTranscriptionInfo { state?: HMSTranscriptionState; mode?: HMSTranscriptionMode; + initialised_at?: Date; + started_at?: Date; + updated_at?: Date; + stopped_at?: Date; + error?: HMSException; } diff --git a/packages/hms-video-store/src/interfaces/transcription-config.ts b/packages/hms-video-store/src/interfaces/transcription-config.ts new file mode 100644 index 0000000000..9294bfc851 --- /dev/null +++ b/packages/hms-video-store/src/interfaces/transcription-config.ts @@ -0,0 +1,5 @@ +import { HMSTranscriptionMode } from './room'; + +export interface TranscriptionConfig { + mode: HMSTranscriptionMode; +} diff --git a/packages/hms-video-store/src/interfaces/update-listener.ts b/packages/hms-video-store/src/interfaces/update-listener.ts index 9db884a570..315713cb34 100644 --- a/packages/hms-video-store/src/interfaces/update-listener.ts +++ b/packages/hms-video-store/src/interfaces/update-listener.ts @@ -17,6 +17,7 @@ export enum HMSRoomUpdate { SERVER_RECORDING_STATE_UPDATED = 'SERVER_RECORDING_STATE_UPDATED', RTMP_STREAMING_STATE_UPDATED = 'RTMP_STREAMING_STATE_UPDATED', HLS_STREAMING_STATE_UPDATED = 'HLS_STREAMING_STATE_UPDATED', + TRANSCRIPTION_STATE_UPDATED = 'TRANSCRIPTION_STATE_UPDATED', ROOM_PEER_COUNT_UPDATED = 'ROOM_PEER_COUNT_UPDATED', } diff --git a/packages/hms-video-store/src/notification-manager/HMSNotificationMethod.ts b/packages/hms-video-store/src/notification-manager/HMSNotificationMethod.ts index 72c5d06921..28616e29da 100644 --- a/packages/hms-video-store/src/notification-manager/HMSNotificationMethod.ts +++ b/packages/hms-video-store/src/notification-manager/HMSNotificationMethod.ts @@ -28,6 +28,7 @@ export enum HMSNotificationMethod { RTMP_UPDATE = 'on-rtmp-update', RECORDING_UPDATE = 'on-record-update', HLS_UPDATE = 'on-hls-update', + TRANSCRIPTION_UPDATE = 'on-transcription-update', METADATA_CHANGE = 'on-metadata-change', POLL_START = 'on-poll-start', POLL_STOP = 'on-poll-stop', diff --git a/packages/hms-video-store/src/notification-manager/HMSNotifications.ts b/packages/hms-video-store/src/notification-manager/HMSNotifications.ts index 8130e93e2d..34818e72e3 100644 --- a/packages/hms-video-store/src/notification-manager/HMSNotifications.ts +++ b/packages/hms-video-store/src/notification-manager/HMSNotifications.ts @@ -62,6 +62,7 @@ export enum HMSStreamingState { } export enum HMSTranscriptionState { + INITIALISED = 'initialised', STARTED = 'started', STOPPED = 'stopped', FAILED = 'failed', @@ -133,6 +134,12 @@ export interface PeerNotification { export interface TranscriptionNotification { state?: HMSTranscriptionState; mode?: HMSTranscriptionMode; + initialised_at?: number; + started_at?: number; + updated_at?: number; + stopped_at?: number; + peer?: PeerNotificationInfo; + error?: ServerError; } export interface RoomState { diff --git a/packages/hms-video-store/src/notification-manager/managers/RoomUpdateManager.ts b/packages/hms-video-store/src/notification-manager/managers/RoomUpdateManager.ts index 7f4c42b86b..84ec21d0ac 100644 --- a/packages/hms-video-store/src/notification-manager/managers/RoomUpdateManager.ts +++ b/packages/hms-video-store/src/notification-manager/managers/RoomUpdateManager.ts @@ -59,6 +59,9 @@ export class RoomUpdateManager { case HMSNotificationMethod.HLS_UPDATE: this.updateHLSStatus(notification as HLSNotification); break; + case HMSNotificationMethod.TRANSCRIPTION_UPDATE: + this.handleTranscriptionStatus([notification as TranscriptionNotification]); + break; default: break; } @@ -129,6 +132,11 @@ export class RoomUpdateManager { return { state: transcription.state, mode: transcription.mode, + initialised_at: convertDateNumToDate(transcription.initialised_at), + started_at: convertDateNumToDate(transcription.started_at), + stopped_at: convertDateNumToDate(transcription.stopped_at), + updated_at: convertDateNumToDate(transcription.updated_at), + error: this.toSdkError(transcription?.error), }; }); } @@ -200,6 +208,15 @@ export class RoomUpdateManager { this.listener?.onRoomUpdate(HMSRoomUpdate.HLS_STREAMING_STATE_UPDATED, room); } + private handleTranscriptionStatus(notification: TranscriptionNotification[]) { + const room = this.store.getRoom(); + if (!room) { + HMSLogger.w(this.TAG, 'on transcription - room not present'); + return; + } + room.transcriptions = this.addTranscriptionDetail(notification) || []; + this.listener?.onRoomUpdate(HMSRoomUpdate.TRANSCRIPTION_STATE_UPDATED, room); + } private convertHls(hlsNotification?: HLSNotification) { const isInitialised = hlsNotification?.variants && hlsNotification.variants.length > 0 diff --git a/packages/hms-video-store/src/reactive-store/HMSSDKActions.ts b/packages/hms-video-store/src/reactive-store/HMSSDKActions.ts index 57db483bad..2fbff74954 100644 --- a/packages/hms-video-store/src/reactive-store/HMSSDKActions.ts +++ b/packages/hms-video-store/src/reactive-store/HMSSDKActions.ts @@ -701,6 +701,14 @@ export class HMSSDKActions { + await this.sdk.stopTranscription(params); + } + async sendHLSTimedMetadata(metadataList: sdkTypes.HLSTimedMetadata[]): Promise { await this.sdk.sendHLSTimedMetadata(metadataList); } diff --git a/packages/hms-video-store/src/reactive-store/adapter.ts b/packages/hms-video-store/src/reactive-store/adapter.ts index d16e75e830..717b93bb63 100644 --- a/packages/hms-video-store/src/reactive-store/adapter.ts +++ b/packages/hms-video-store/src/reactive-store/adapter.ts @@ -139,10 +139,11 @@ export class SDKToHMS { } static convertRoom(sdkRoom: sdkTypes.HMSRoom, sdkLocalPeerId?: string): Partial { - const { recording, rtmp, hls } = SDKToHMS.convertRecordingStreamingState( - sdkRoom?.recording, - sdkRoom?.rtmp, - sdkRoom?.hls, + const { recording, rtmp, hls, transcriptions } = SDKToHMS.convertRecordingStreamingState( + sdkRoom.recording, + sdkRoom.rtmp, + sdkRoom.hls, + sdkRoom.transcriptions, ); return { id: sdkRoom.id, @@ -151,6 +152,7 @@ export class SDKToHMS { recording, rtmp, hls, + transcriptions, sessionId: sdkRoom.sessionId, startedAt: sdkRoom.startedAt, joinedAt: sdkRoom.joinedAt, diff --git a/packages/hms-video-store/src/sdk/index.ts b/packages/hms-video-store/src/sdk/index.ts index 19d0ef83af..2e4679323f 100644 --- a/packages/hms-video-store/src/sdk/index.ts +++ b/packages/hms-video-store/src/sdk/index.ts @@ -48,7 +48,7 @@ import { HMSPreviewListener } from '../interfaces/preview-listener'; import { RTMPRecordingConfig } from '../interfaces/rtmp-recording-config'; import InitialSettings from '../interfaces/settings'; import { HMSAudioListener, HMSPeerUpdate, HMSTrackUpdate, HMSUpdateListener } from '../interfaces/update-listener'; -import { PlaylistManager } from '../internal'; +import { PlaylistManager, TranscriptionConfig } from '../internal'; import { HMSLocalStream } from '../media/streams/HMSLocalStream'; import { HMSLocalAudioTrack, @@ -70,6 +70,7 @@ import { HLSTimedMetadataParams, HLSVariant, StartRTMPOrRecordingRequestParams, + StartTranscriptionRequestParams, } from '../signal/interfaces'; import HMSTransport from '../transport'; import ITransportObserver from '../transport/ITransportObserver'; @@ -1012,6 +1013,35 @@ export class HMSSdk implements HMSInterface { await this.transport?.signal.stopHLSStreaming(); } + async startTranscription(params: TranscriptionConfig) { + if (!this.localPeer) { + throw ErrorFactory.GenericErrors.NotConnected( + HMSAction.VALIDATION, + 'No local peer present, cannot start transcriptions', + ); + } + const transcriptionParams: StartTranscriptionRequestParams = { + mode: params.mode, + }; + await this.transport?.signal.startTranscription(transcriptionParams); + } + + async stopTranscription(params: TranscriptionConfig) { + if (!this.localPeer) { + throw ErrorFactory.GenericErrors.NotConnected( + HMSAction.VALIDATION, + 'No local peer present, cannot stop transcriptions', + ); + } + if (!params) { + throw ErrorFactory.GenericErrors.Signalling(HMSAction.VALIDATION, 'No mode is passed to stop the transcription'); + } + const transcriptionParams: StartTranscriptionRequestParams = { + mode: params.mode, + }; + await this.transport?.signal.stopTranscription(transcriptionParams); + } + async sendHLSTimedMetadata(metadataList: HLSTimedMetadata[]) { this.validateJoined('sendHLSTimedMetadata'); if (metadataList.length > 0) { diff --git a/packages/hms-video-store/src/signal/interfaces/superpowers.ts b/packages/hms-video-store/src/signal/interfaces/superpowers.ts index b96e5661bb..a72c602f0a 100644 --- a/packages/hms-video-store/src/signal/interfaces/superpowers.ts +++ b/packages/hms-video-store/src/signal/interfaces/superpowers.ts @@ -1,4 +1,4 @@ -import { HMSTrackSource } from '../..'; +import { HMSTrackSource, HMSTranscriptionMode } from '../..'; import { HLSTimedMetadata, RTMPRecordingResolution } from '../../interfaces'; /** @@ -57,6 +57,9 @@ export interface UpdatePeerRequestParams { data?: string; } +export interface StartTranscriptionRequestParams { + mode: HMSTranscriptionMode; +} export interface SetSessionMetadataParams { key?: string; data: any; diff --git a/packages/hms-video-store/src/signal/jsonrpc/index.ts b/packages/hms-video-store/src/signal/jsonrpc/index.ts index 014f725e43..a96909343d 100644 --- a/packages/hms-video-store/src/signal/jsonrpc/index.ts +++ b/packages/hms-video-store/src/signal/jsonrpc/index.ts @@ -60,6 +60,7 @@ import { SetSessionMetadataParams, SetSessionMetadataResponse, StartRTMPOrRecordingRequestParams, + StartTranscriptionRequestParams, Track, TrackUpdateRequestParams, UpdatePeerRequestParams, @@ -364,6 +365,14 @@ export default class JsonRpcSignal { await this.call(HMSSignalMethod.STOP_HLS_STREAMING, { ...params }); } + async startTranscription(params: StartTranscriptionRequestParams) { + await this.call(HMSSignalMethod.START_TRANSCRIPTION, { ...params }); + } + + async stopTranscription(params: StartTranscriptionRequestParams) { + await this.call(HMSSignalMethod.STOP_TRANSCRIPTION, { ...params }); + } + async sendHLSTimedMetadata(params?: HLSTimedMetadataParams): Promise { await this.call(HMSSignalMethod.HLS_TIMED_METADATA, { ...params }); } diff --git a/packages/hms-video-store/src/signal/jsonrpc/models.ts b/packages/hms-video-store/src/signal/jsonrpc/models.ts index 2344ec3e70..51f01d828a 100644 --- a/packages/hms-video-store/src/signal/jsonrpc/models.ts +++ b/packages/hms-video-store/src/signal/jsonrpc/models.ts @@ -39,6 +39,8 @@ export enum HMSSignalMethod { UPDATE_PEER_METADATA = 'peer-update', START_HLS_STREAMING = 'hls-start', STOP_HLS_STREAMING = 'hls-stop', + START_TRANSCRIPTION = 'transcription-start', + STOP_TRANSCRIPTION = 'transcription-stop', HLS_TIMED_METADATA = 'hls-timed-metadata', SET_METADATA = 'set-metadata', GET_METADATA = 'get-metadata', diff --git a/packages/roomkit-react/src/Prebuilt/common/constants.ts b/packages/roomkit-react/src/Prebuilt/common/constants.ts index b79ae78487..ebe8b6dc2f 100644 --- a/packages/roomkit-react/src/Prebuilt/common/constants.ts +++ b/packages/roomkit-react/src/Prebuilt/common/constants.ts @@ -1,6 +1,5 @@ import { parsedUserAgent } from '@100mslive/react-sdk'; -export const DEFAULT_WAITING_VIEWER_ROLE = 'waiting-room'; export const QUERY_PARAM_SKIP_PREVIEW = 'skip_preview'; export const QUERY_PARAM_SKIP_PREVIEW_HEADFUL = 'skip_preview_headful'; export const QUERY_PARAM_NAME = 'name'; @@ -30,7 +29,6 @@ export const APP_DATA = { appConfig: 'appConfig', sidePane: 'sidePane', hlsStats: 'hlsStats', - waitingViewerRole: 'waitingViewerRole', subscribedNotifications: 'subscribedNotifications', logo: 'logo', hlsStarted: 'hlsStarted', diff --git a/packages/roomkit-react/src/Prebuilt/common/hooks.ts b/packages/roomkit-react/src/Prebuilt/common/hooks.ts index 6336042c01..c1ae0b8c31 100644 --- a/packages/roomkit-react/src/Prebuilt/common/hooks.ts +++ b/packages/roomkit-react/src/Prebuilt/common/hooks.ts @@ -1,17 +1,22 @@ -import { useCallback, useEffect, useRef, useState } from 'react'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useMedia } from 'react-use'; import { HMSHLSPlayer } from '@100mslive/hls-player'; import { JoinForm_JoinBtnType } from '@100mslive/types-prebuilt/elements/join_form'; import { + HMSPeer, HMSRecording, parsedUserAgent, selectAvailableRoleNames, + selectIsAllowedToPublish, selectIsConnectedToRoom, + selectLocalPeerRole, selectPeerCount, selectPeerMetadata, selectPeers, + selectPeersByRoles, selectRecordingState, selectRemotePeers, + selectRolesMap, useHMSActions, useHMSStore, useHMSVanillaStore, @@ -218,3 +223,31 @@ export function getResolution( } return resolution; } + +export interface WaitingRoomInfo { + isNotAllowedToPublish: boolean; + isScreenOnlyPublishParams: boolean; + hasSubscribedRolePublishing: boolean; +} +export function useWaitingRoomInfo(): WaitingRoomInfo { + const localPeerRole = useHMSStore(selectLocalPeerRole); + const { video, audio, screen } = useHMSStore(selectIsAllowedToPublish); + const roles = useHMSStore(selectRolesMap); + const peersByRoles = useHMSStore(selectPeersByRoles(localPeerRole?.subscribeParams.subscribeToRoles || [])); + const isNotAllowedToPublish = video && audio && screen; + const isScreenOnlyPublishParams: boolean = screen; + const hasSubscribedRolePublishing: boolean = useMemo(() => { + return peersByRoles.some((peer: HMSPeer) => { + if (peer.roleName && roles[peer.roleName] && !peer.isLocal) { + return !!roles[peer.roleName].publishParams?.allowed.length; + } + return false; + }); + }, [peersByRoles, roles]); + + return { + isNotAllowedToPublish, + isScreenOnlyPublishParams, + hasSubscribedRolePublishing, + }; +} diff --git a/packages/roomkit-react/src/Prebuilt/components/AppData/AppData.tsx b/packages/roomkit-react/src/Prebuilt/components/AppData/AppData.tsx index 5390608332..d781feebc8 100644 --- a/packages/roomkit-react/src/Prebuilt/components/AppData/AppData.tsx +++ b/packages/roomkit-react/src/Prebuilt/components/AppData/AppData.tsx @@ -21,7 +21,6 @@ import { useSetAppDataByKey } from './useUISettings'; import { APP_DATA, CHAT_SELECTOR, - DEFAULT_WAITING_VIEWER_ROLE, POLL_STATE, SIDE_PANE_OPTIONS, UI_MODE_GRID, @@ -56,7 +55,6 @@ const initialAppData = { [APP_DATA.hlsStarted]: false, [APP_DATA.rtmpStarted]: false, [APP_DATA.recordingStarted]: false, - [APP_DATA.waitingViewerRole]: DEFAULT_WAITING_VIEWER_ROLE, [APP_DATA.dropdownList]: [], [APP_DATA.authToken]: '', [APP_DATA.minimiseInset]: false, diff --git a/packages/roomkit-react/src/Prebuilt/components/AppData/useUISettings.js b/packages/roomkit-react/src/Prebuilt/components/AppData/useUISettings.js index 357605413f..61341102eb 100644 --- a/packages/roomkit-react/src/Prebuilt/components/AppData/useUISettings.js +++ b/packages/roomkit-react/src/Prebuilt/components/AppData/useUISettings.js @@ -48,9 +48,6 @@ export const useSetUiSettings = uiSettingKey => { return [value, setValue]; }; -export const useWaitingViewerRole = () => { - return useHMSStore(selectAppData(APP_DATA.waitingViewerRole)); -}; export const useIsHLSStartedFromUI = () => { return useHMSStore(selectAppData(APP_DATA.hlsStarted)); }; diff --git a/packages/roomkit-react/src/Prebuilt/components/Chat/Chat.tsx b/packages/roomkit-react/src/Prebuilt/components/Chat/Chat.tsx index 1ce47c121e..ae455703d7 100644 --- a/packages/roomkit-react/src/Prebuilt/components/Chat/Chat.tsx +++ b/packages/roomkit-react/src/Prebuilt/components/Chat/Chat.tsx @@ -10,17 +10,20 @@ import { Box, Flex } from '../../../Layout'; import { config as cssConfig } from '../../../Theme'; // @ts-ignore: No implicit any import { EmojiReaction } from '../EmojiReaction'; +import { MoreSettings } from '../MoreSettings/MoreSettings'; +import { RaiseHand } from '../RaiseHand'; import { ChatBody } from './ChatBody'; import { ChatFooter } from './ChatFooter'; import { ChatBlocked, ChatPaused } from './ChatStates'; import { PinnedMessage } from './PinnedMessage'; import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen'; import { useSidepaneResetOnLayoutUpdate } from '../AppData/useSidepaneResetOnLayoutUpdate'; +import { useIsPeerBlacklisted } from '../hooks/useChatBlacklist'; import { useLandscapeHLSStream, useMobileHLSStream } from '../../common/hooks'; import { SESSION_STORE_KEY, SIDE_PANE_OPTIONS } from '../../common/constants'; export const Chat = () => { - const { elements } = useRoomLayoutConferencingScreen(); + const { elements, screenType } = useRoomLayoutConferencingScreen(); const listRef = useRef(null); const hmsActions = useHMSActions(); const vanillaStore = useHMSVanillaStore(); @@ -29,6 +32,7 @@ export const Chat = () => { const isMobileHLSStream = useMobileHLSStream(); const isLandscapeStream = useLandscapeHLSStream(); useSidepaneResetOnLayoutUpdate('chat', SIDE_PANE_OPTIONS.CHAT); + const isLocalPeerBlacklisted = useIsPeerBlacklisted({ local: true }); const scrollToBottom = useCallback( (unreadCount = 0) => { @@ -57,20 +61,27 @@ export const Chat = () => { > {isMobile && elements?.chat?.is_overlay && !streaming ? null : } - - - + + + + {streaming && (!isChatEnabled || isLocalPeerBlacklisted) && ( + <> + + + + )} + {isMobile && elements?.chat?.is_overlay && !streaming ? : null} {isChatEnabled ? ( ) : null} - {(isMobileHLSStream || isLandscapeStream) && ( + {streaming && ( { { isMobileHLSStream: true, isChatEnabled: true, + isLocalPeerBlacklisted: false, }, () => ({ bottom: '$17', right: '$8' }), ) @@ -103,6 +115,14 @@ export const Chat = () => { { isLandscapeStream: false, isChatEnabled: true, + isLocalPeerBlacklisted: true, + }, + () => ({ bottom: '$18', right: '$8' }), + ) + .with( + { + isMobileHLSStream: true, + isLocalPeerBlacklisted: true, }, () => ({ bottom: '$20', right: '$8' }), ) diff --git a/packages/roomkit-react/src/Prebuilt/components/Chat/ChatStates.tsx b/packages/roomkit-react/src/Prebuilt/components/Chat/ChatStates.tsx index a55665a013..9c1308be78 100644 --- a/packages/roomkit-react/src/Prebuilt/components/Chat/ChatStates.tsx +++ b/packages/roomkit-react/src/Prebuilt/components/Chat/ChatStates.tsx @@ -30,7 +30,7 @@ export const ChatPaused = () => { diff --git a/packages/roomkit-react/src/Prebuilt/components/VideoLayouts/EqualProminence.tsx b/packages/roomkit-react/src/Prebuilt/components/VideoLayouts/EqualProminence.tsx index d412d7295a..af932b4eca 100644 --- a/packages/roomkit-react/src/Prebuilt/components/VideoLayouts/EqualProminence.tsx +++ b/packages/roomkit-react/src/Prebuilt/components/VideoLayouts/EqualProminence.tsx @@ -1,8 +1,9 @@ -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { useMedia } from 'react-use'; -import { selectLocalPeer, useHMSStore } from '@100mslive/react-sdk'; +import { PeopleAddIcon } from '@100mslive/react-icons'; import { Flex } from '../../../Layout'; import { config as cssConfig } from '../../../Theme'; +import { WaitingView } from '../../layouts/WaitingView'; import { InsetTile } from '../InsetTile'; import { Pagination } from '../Pagination'; import { Grid } from './Grid'; @@ -13,26 +14,14 @@ import { usePagesWithTiles, useTileLayout } from '../hooks/useTileLayout'; import { UI_SETTINGS } from '../../common/constants'; export function EqualProminence({ isInsetEnabled = false, peers, onPageChange, onPageSize, edgeToEdge }: LayoutProps) { - const localPeer = useHMSStore(selectLocalPeer); const isMobile = useMedia(cssConfig.media.md); let maxTileCount = useUISettings(UI_SETTINGS.maxTileCount); maxTileCount = isMobile ? Math.min(maxTileCount, 6) : maxTileCount; - let pageList = usePagesWithTiles({ + const pageList = usePagesWithTiles({ peers, maxTileCount, }); - // useMemo is needed to prevent recursion as new array is created for localPeer - const inputPeers = useMemo(() => { - if (pageList.length === 0) { - return localPeer ? [localPeer] : []; - } - return peers; - }, [pageList.length, peers, localPeer]); - // Pass local peer to main grid if no other peer has tiles - pageList = usePagesWithTiles({ - peers: inputPeers, - maxTileCount, - }); + const { ref, pagesWithTiles } = useTileLayout({ pageList, maxTileCount, @@ -60,7 +49,14 @@ export function EqualProminence({ isInsetEnabled = false, peers, onPageChange, o numPages={pagesWithTiles.length} /> )} - {isInsetEnabled && pageList.length > 0 && pageList[0][0].peer.id !== localPeer?.id && } + {pageList.length === 0 ? ( + } + /> + ) : null} + {isInsetEnabled && } ); } diff --git a/packages/roomkit-react/src/Prebuilt/layouts/HLSView.jsx b/packages/roomkit-react/src/Prebuilt/layouts/HLSView.jsx index c246f2a51c..f24ad67b48 100644 --- a/packages/roomkit-react/src/Prebuilt/layouts/HLSView.jsx +++ b/packages/roomkit-react/src/Prebuilt/layouts/HLSView.jsx @@ -34,6 +34,7 @@ import { Loading } from '../../Loading'; import { Text } from '../../Text'; import { config, theme, useTheme } from '../../Theme'; import { Tooltip } from '../../Tooltip'; +import { WaitingView } from './WaitingView'; import { useSidepaneToggle } from '../components/AppData/useSidepane'; import { useRoomLayoutConferencingScreen } from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen'; import { useIsLandscape, useKeyboardHandler } from '../common/hooks'; @@ -457,17 +458,19 @@ const HLSView = () => { flex: isLandscape ? '2 1 0' : '1 1 0', }} > - - - {streamEnded ? : } - - - {streamEnded ? 'Stream has ended' : 'Stream yet to start'} - - - {streamEnded ? 'Have a nice day!' : 'Sit back and relax'} - - + {streamEnded ? ( + } + title="Stream has ended" + subtitle="Have a nice day!" + /> + ) : ( + } + title="Stream yet to start" + subtitle="Sit back and relax" + /> + )} ); diff --git a/packages/roomkit-react/src/Prebuilt/layouts/NonPublisherView.jsx b/packages/roomkit-react/src/Prebuilt/layouts/NonPublisherView.jsx deleted file mode 100644 index d003f13387..0000000000 --- a/packages/roomkit-react/src/Prebuilt/layouts/NonPublisherView.jsx +++ /dev/null @@ -1,51 +0,0 @@ -import React from 'react'; -import { ShieldAlertIcon } from '@100mslive/react-icons'; -import { Box, Flex } from '../../Layout'; -import { Text } from '../../Text'; - -export const NonPublisherView = React.memo(({ message }) => { - return ( - - - - - - {message} - - - Please go to dashboard and reconfigure role settings or contact the role admin. - - - - - ); -}); diff --git a/packages/roomkit-react/src/Prebuilt/layouts/VideoStreamingSection.tsx b/packages/roomkit-react/src/Prebuilt/layouts/VideoStreamingSection.tsx index aa5a322fc0..b3dc72d378 100644 --- a/packages/roomkit-react/src/Prebuilt/layouts/VideoStreamingSection.tsx +++ b/packages/roomkit-react/src/Prebuilt/layouts/VideoStreamingSection.tsx @@ -5,7 +5,14 @@ import { HLSLiveStreamingScreen_Elements, } from '@100mslive/types-prebuilt'; import { match } from 'ts-pattern'; -import { selectIsConnectedToRoom, selectLocalPeerRoleName, useHMSActions, useHMSStore } from '@100mslive/react-sdk'; +import { + selectIsConnectedToRoom, + selectIsLocalScreenShared, + selectLocalPeerRoleName, + useHMSActions, + useHMSStore, +} from '@100mslive/react-sdk'; +import { PeopleAddIcon, ShareScreenIcon } from '@100mslive/react-icons'; import FullPageProgress from '../components/FullPageProgress'; import { GridLayout } from '../components/VideoLayouts/GridLayout'; import { Box, Flex } from '../../Layout'; @@ -21,11 +28,10 @@ import { CaptionsViewer } from '../plugins/CaptionsViewer'; import { usePDFConfig, useUrlToEmbed, - useWaitingViewerRole, // @ts-ignore: No implicit Any } from '../components/AppData/useUISettings'; import { useCloseScreenshareWhiteboard } from '../components/hooks/useCloseScreenshareWhiteboard'; -import { useLandscapeHLSStream, useMobileHLSStream } from '../common/hooks'; +import { useLandscapeHLSStream, useMobileHLSStream, useWaitingRoomInfo } from '../common/hooks'; import { SESSION_STORE_KEY } from '../common/constants'; // @ts-ignore: No implicit Any const HLSView = React.lazy(() => import('./HLSView')); @@ -39,17 +45,20 @@ export const VideoStreamingSection = ({ elements: DefaultConferencingScreen_Elements | HLSLiveStreamingScreen_Elements; hideControls: boolean; }) => { - const localPeerRole = useHMSStore(selectLocalPeerRoleName); + const localPeerRoleName = useHMSStore(selectLocalPeerRoleName); const isConnected = useHMSStore(selectIsConnectedToRoom); + const isSharingScreen = useHMSStore(selectIsLocalScreenShared); const hmsActions = useHMSActions(); - const waitingViewerRole = useWaitingViewerRole(); const urlToIframe = useUrlToEmbed(); const pdfAnnotatorActive = usePDFConfig(); const isMobileHLSStream = useMobileHLSStream(); const isLandscapeHLSStream = useLandscapeHLSStream(); useCloseScreenshareWhiteboard(); + const { isNotAllowedToPublish, isScreenOnlyPublishParams, hasSubscribedRolePublishing } = useWaitingRoomInfo(); + + console.log('pring ', isNotAllowedToPublish, isScreenOnlyPublishParams, hasSubscribedRolePublishing); useEffect(() => { if (!isConnected) { return; @@ -64,7 +73,7 @@ export const VideoStreamingSection = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [isConnected, hmsActions]); - if (!localPeerRole) { + if (!localPeerRoleName) { // we don't know the role yet to decide how to render UI return null; } @@ -82,7 +91,15 @@ export const VideoStreamingSection = ({ .with({ isMobileHLSStream: true }, () => 'column') .otherwise(() => 'row')} > - {match({ screenType, localPeerRole, pdfAnnotatorActive, urlToIframe }) + {match({ + screenType, + isNotAllowedToPublish, + isScreenOnlyPublishParams, + hasSubscribedRolePublishing, + isSharingScreen, + pdfAnnotatorActive, + urlToIframe, + }) .with( { screenType: 'hls_live_streaming', @@ -90,8 +107,26 @@ export const VideoStreamingSection = ({ () => , ) .when( - ({ localPeerRole }) => localPeerRole === waitingViewerRole, - () => , + ({ isNotAllowedToPublish, hasSubscribedRolePublishing }) => + isNotAllowedToPublish && !hasSubscribedRolePublishing, + () => ( + } + /> + ), + ) + .when( + ({ isScreenOnlyPublishParams, isSharingScreen, hasSubscribedRolePublishing }) => + isScreenOnlyPublishParams && !isSharingScreen && !hasSubscribedRolePublishing, + () => ( + } + /> + ), ) .when( ({ pdfAnnotatorActive }) => !!pdfAnnotatorActive, diff --git a/packages/roomkit-react/src/Prebuilt/layouts/WaitingView.jsx b/packages/roomkit-react/src/Prebuilt/layouts/WaitingView.jsx deleted file mode 100644 index 10f0c26922..0000000000 --- a/packages/roomkit-react/src/Prebuilt/layouts/WaitingView.jsx +++ /dev/null @@ -1,51 +0,0 @@ -import React from 'react'; -import { ColoredTimeIcon } from '@100mslive/react-icons'; -import { Box, Flex } from '../../Layout'; -import { Text } from '../../Text'; - -export const WaitingView = React.memo(() => { - return ( - - - - - - Please wait - - - Sit back and relax till others let you join. - - - - - ); -}); diff --git a/packages/roomkit-react/src/Prebuilt/layouts/WaitingView.tsx b/packages/roomkit-react/src/Prebuilt/layouts/WaitingView.tsx new file mode 100644 index 0000000000..aac75c4895 --- /dev/null +++ b/packages/roomkit-react/src/Prebuilt/layouts/WaitingView.tsx @@ -0,0 +1,52 @@ +import React from 'react'; +import { Box, Flex } from '../../Layout'; +import { Text } from '../../Text'; + +export const WaitingView = React.memo( + ({ icon, title, subtitle }: { icon: React.ReactNode; title: string; subtitle: string }) => { + return ( + + + {icon} + + + + {title} + + + {subtitle} + + + + ); + }, +);