From 377e5b41bccd8ca874738f106455e1acbb7c5918 Mon Sep 17 00:00:00 2001 From: Amar Bathwal <110378139+amar-1995@users.noreply.github.com> Date: Tue, 21 May 2024 15:50:13 +0530 Subject: [PATCH] feat: empty screen for viewers --- .../src/Prebuilt/common/constants.ts | 2 - .../src/Prebuilt/common/hooks.ts | 35 +++++++++++- .../Prebuilt/components/AppData/AppData.tsx | 2 - .../components/AppData/useUISettings.js | 3 -- .../VideoLayouts/EqualProminence.tsx | 30 +++++------ .../src/Prebuilt/layouts/HLSView.jsx | 25 +++++---- .../src/Prebuilt/layouts/NonPublisherView.jsx | 51 ------------------ .../layouts/VideoStreamingSection.tsx | 53 +++++++++++++++---- .../src/Prebuilt/layouts/WaitingView.jsx | 51 ------------------ .../src/Prebuilt/layouts/WaitingView.tsx | 52 ++++++++++++++++++ 10 files changed, 157 insertions(+), 147 deletions(-) delete mode 100644 packages/roomkit-react/src/Prebuilt/layouts/NonPublisherView.jsx delete mode 100644 packages/roomkit-react/src/Prebuilt/layouts/WaitingView.jsx create mode 100644 packages/roomkit-react/src/Prebuilt/layouts/WaitingView.tsx 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/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} + + + + ); + }, +);