diff --git a/packages/react-icons/assets/BlurPersonHighIcon.svg b/packages/react-icons/assets/BlurPersonHighIcon.svg new file mode 100644 index 0000000000..1bb4b581fb --- /dev/null +++ b/packages/react-icons/assets/BlurPersonHighIcon.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/packages/react-icons/assets/BlurPersonLowIcon.svg b/packages/react-icons/assets/BlurPersonLowIcon.svg new file mode 100644 index 0000000000..15811eea54 --- /dev/null +++ b/packages/react-icons/assets/BlurPersonLowIcon.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/packages/react-icons/assets/SparkleIcon.svg b/packages/react-icons/assets/SparkleIcon.svg new file mode 100644 index 0000000000..9016989109 --- /dev/null +++ b/packages/react-icons/assets/SparkleIcon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/react-icons/src/BlurPersonHighIcon.tsx b/packages/react-icons/src/BlurPersonHighIcon.tsx new file mode 100644 index 0000000000..81a1b11838 --- /dev/null +++ b/packages/react-icons/src/BlurPersonHighIcon.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; +import { SVGProps } from 'react'; +const SvgBlurPersonHighIcon = (props: SVGProps) => ( + + + + +); +export default SvgBlurPersonHighIcon; diff --git a/packages/react-icons/src/BlurPersonLowIcon.tsx b/packages/react-icons/src/BlurPersonLowIcon.tsx new file mode 100644 index 0000000000..cbad4a8a53 --- /dev/null +++ b/packages/react-icons/src/BlurPersonLowIcon.tsx @@ -0,0 +1,21 @@ +import * as React from 'react'; +import { SVGProps } from 'react'; +const SvgBlurPersonLowIcon = (props: SVGProps) => ( + + + + + +); +export default SvgBlurPersonLowIcon; diff --git a/packages/react-icons/src/SparkleIcon.tsx b/packages/react-icons/src/SparkleIcon.tsx new file mode 100644 index 0000000000..909338e0a4 --- /dev/null +++ b/packages/react-icons/src/SparkleIcon.tsx @@ -0,0 +1,14 @@ +import * as React from 'react'; +import { SVGProps } from 'react'; +const SvgSparkleIcon = (props: SVGProps) => ( + + + +); +export default SvgSparkleIcon; diff --git a/packages/react-icons/src/index.ts b/packages/react-icons/src/index.ts index df48d624f9..6642166993 100644 --- a/packages/react-icons/src/index.ts +++ b/packages/react-icons/src/index.ts @@ -30,6 +30,8 @@ export { default as BatteryFullIcon } from './BatteryFullIcon'; export { default as BatteryPowerIcon } from './BatteryPowerIcon'; export { default as BillIcon } from './BillIcon'; export { default as BluetoothIcon } from './BluetoothIcon'; +export { default as BlurPersonHighIcon } from './BlurPersonHighIcon'; +export { default as BlurPersonLowIcon } from './BlurPersonLowIcon'; export { default as BoltIcon } from './BoltIcon'; export { default as BookIcon } from './BookIcon'; export { default as BookmarkIcon } from './BookmarkIcon'; @@ -218,6 +220,7 @@ export { default as ShrinkIcon } from './ShrinkIcon'; export { default as ShuffleIcon } from './ShuffleIcon'; export { default as SlackIcon } from './SlackIcon'; export { default as SolidCheckCircleIcon } from './SolidCheckCircleIcon'; +export { default as SparkleIcon } from './SparkleIcon'; export { default as SpeakerIcon } from './SpeakerIcon'; export { default as SpotlightIcon } from './SpotlightIcon'; export { default as SquareMenuIcon } from './SquareMenuIcon'; diff --git a/packages/roomkit-react/src/Modal/Dialog.tsx b/packages/roomkit-react/src/Modal/Dialog.tsx index fe9c7cb2e0..21cca76a07 100644 --- a/packages/roomkit-react/src/Modal/Dialog.tsx +++ b/packages/roomkit-react/src/Modal/Dialog.tsx @@ -1,28 +1,20 @@ import React, { ReactNode, useRef } from 'react'; import { Root } from '@radix-ui/react-dialog'; import { styled } from '@stitches/react'; -import { CSS } from '../Theme'; import { + CustomDialogContent, + CustomDialogOverlay, DialogClose, DialogDefaultCloseIcon, DialogDescription, DialogTitle, - StyledDialogContent, - StyledDialogOverlay, StyledDialogPortal, StyledDialogTrigger, } from './DialogContent'; import { useDialogContainerSelector } from '../hooks/useDialogContainerSelector'; const StyledDialog = styled(Root, {}); -const CustomDialogContent = ({ children, props = {}, css = {} }: { children: ReactNode; props?: any; css?: CSS }) => ( - - {children} - -); -const CustomDialogOverlay = ({ css = {} }: { css?: CSS }) => ( - -); + const CustomDialogPortal = ({ children, container }: { children: ReactNode; container?: HTMLElement | null }) => { const dialogContainerSelector = useDialogContainerSelector(); const containerRef = useRef(null); diff --git a/packages/roomkit-react/src/Modal/DialogContent.tsx b/packages/roomkit-react/src/Modal/DialogContent.tsx index 91a7dae300..8631bae8a7 100644 --- a/packages/roomkit-react/src/Modal/DialogContent.tsx +++ b/packages/roomkit-react/src/Modal/DialogContent.tsx @@ -17,19 +17,19 @@ export const StyledDialogTrigger = styled(DialogPrimitive.Trigger, { appearance: 'none !important', // Needed for safari it shows white overlay }); -export const StyledDialogOverlay = styled(DialogPrimitive.Overlay, { +export const CustomDialogOverlay = styled(DialogPrimitive.Overlay, { backgroundColor: 'rgba(0, 0, 0, 0.5);', - position: 'fixed', + position: 'absolute', inset: 0, }); export const StyledDialogPortal = styled(DialogPrimitive.Portal, {}); -export const StyledDialogContent = styled(DialogPrimitive.Content, { +export const CustomDialogContent = styled(DialogPrimitive.Content, { color: '$on_surface_medium', backgroundColor: '$surface_default', borderRadius: '8px', - position: 'fixed', + position: 'absolute', top: '50%', left: '50%', border: '$space$px solid $border_bright', diff --git a/packages/roomkit-react/src/Prebuilt/common/constants.js b/packages/roomkit-react/src/Prebuilt/common/constants.js index bb9e4692ba..4aaa2aa6d5 100644 --- a/packages/roomkit-react/src/Prebuilt/common/constants.js +++ b/packages/roomkit-react/src/Prebuilt/common/constants.js @@ -46,6 +46,8 @@ export const APP_DATA = { activeScreensharePeerId: 'activeScreensharePeerId', disableNotifications: 'disableNotifications', pollState: 'pollState', + background: 'background', + backgroundType: 'backgroundType', }; export const UI_SETTINGS = { isAudioOnly: 'isAudioOnly', @@ -61,6 +63,7 @@ export const SIDE_PANE_OPTIONS = { CHAT: 'Chat', STREAMING: 'STREAMING', POLLS: 'POLLS', + VB: 'VB', }; export const POLL_STATE = { diff --git a/packages/roomkit-react/src/Prebuilt/components/AppData/AppData.jsx b/packages/roomkit-react/src/Prebuilt/components/AppData/AppData.jsx index 1039ce6225..4e206005b8 100644 --- a/packages/roomkit-react/src/Prebuilt/components/AppData/AppData.jsx +++ b/packages/roomkit-react/src/Prebuilt/components/AppData/AppData.jsx @@ -4,7 +4,6 @@ import { selectAvailableRoleNames, selectFullAppData, selectHLSState, - selectIsConnectedToRoom, selectLocalPeerRoleName, selectRolesMap, selectRoomState, @@ -15,7 +14,7 @@ import { } from '@100mslive/react-sdk'; import { normalizeAppPolicyConfig } from '../init/initUtils'; import { UserPreferencesKeys, useUserPreferences } from '../hooks/useUserPreferences'; -import { useIsSidepaneTypeOpen, useSidepaneReset, useSidepaneState, useSidepaneToggle } from './useSidepane'; +import { useIsSidepaneTypeOpen, useSidepaneToggle } from './useSidepane'; import { useSetAppDataByKey } from './useUISettings'; import { APP_DATA, @@ -26,6 +25,7 @@ import { UI_MODE_GRID, UI_SETTINGS, } from '../../common/constants'; +import { VB_EFFECT } from '../VirtualBackground/constants'; export const getAppDetails = appDetails => { try { @@ -67,6 +67,8 @@ const initialAppData = { [APP_DATA.minimiseInset]: false, [APP_DATA.activeScreensharePeerId]: '', [APP_DATA.disableNotifications]: false, + [APP_DATA.background]: VB_EFFECT.NONE, + [APP_DATA.backgroundType]: VB_EFFECT.NONE, [APP_DATA.pollState]: { [POLL_STATE.pollInView]: '', [POLL_STATE.view]: '', @@ -75,21 +77,12 @@ const initialAppData = { export const AppData = React.memo(({ appDetails, tokenEndpoint }) => { const hmsActions = useHMSActions(); - const isConnected = useHMSStore(selectIsConnectedToRoom); - const sidePane = useSidepaneState(); - const resetSidePane = useSidepaneReset(); const [preferences = {}] = useUserPreferences(UserPreferencesKeys.UI_SETTINGS); const roleNames = useHMSStore(selectAvailableRoleNames); const rolesMap = useHMSStore(selectRolesMap); const localPeerRole = useHMSStore(selectLocalPeerRoleName); const appData = useHMSStore(selectFullAppData); - useEffect(() => { - if (!isConnected && sidePane && sidePane !== SIDE_PANE_OPTIONS.PARTICIPANTS) { - resetSidePane(); - } - }, [isConnected, sidePane, resetSidePane]); - useEffect(() => { hmsActions.initAppData({ ...initialAppData, diff --git a/packages/roomkit-react/src/Prebuilt/components/AppData/useSidepane.js b/packages/roomkit-react/src/Prebuilt/components/AppData/useSidepane.js index 05a386a47b..d0e99386a1 100644 --- a/packages/roomkit-react/src/Prebuilt/components/AppData/useSidepane.js +++ b/packages/roomkit-react/src/Prebuilt/components/AppData/useSidepane.js @@ -60,7 +60,7 @@ export const usePollViewToggle = () => { }; /** - * reset's the sidepane value + * resets the sidepane value */ export const useSidepaneReset = () => { const hmsActions = useHMSActions(); diff --git a/packages/roomkit-react/src/Prebuilt/components/Footer/Footer.tsx b/packages/roomkit-react/src/Prebuilt/components/Footer/Footer.tsx index 76eb8ffc83..9de5b072c7 100644 --- a/packages/roomkit-react/src/Prebuilt/components/Footer/Footer.tsx +++ b/packages/roomkit-react/src/Prebuilt/components/Footer/Footer.tsx @@ -1,4 +1,4 @@ -import React, { Suspense, useEffect } from 'react'; +import React, { useEffect } from 'react'; import { useMedia } from 'react-use'; import { ConferencingScreen, @@ -21,6 +21,8 @@ import { RaiseHand } from '../RaiseHand'; // @ts-ignore: No implicit Any import { ScreenshareToggle } from '../ScreenShareToggle'; // @ts-ignore: No implicit Any +import { VBToggle } from '../VirtualBackground/VBToggle'; +// @ts-ignore: No implicit Any import { ChatToggle } from './ChatToggle'; // @ts-ignore: No implicit Any import { ParticipantCount } from './ParticipantList'; @@ -31,8 +33,6 @@ import { useIsSidepaneTypeOpen, useSidepaneToggle } from '../AppData/useSidepane import { useShowPolls } from '../AppData/useUISettings'; // @ts-ignore: No implicit Any import { SIDE_PANE_OPTIONS } from '../../common/constants'; -// @ts-ignore: No implicit Any -const VirtualBackground = React.lazy(() => import('../../plugins/VirtualBackground/VirtualBackground')); export const Footer = ({ screenType, @@ -82,11 +82,7 @@ export const Footer = ({ > {isMobile ? : null} - {isMobile ? null : ( - }> - - - )} + {isMobile ? null : } { const peerCount = useHMSStore(selectPeerCount); const toggleSidepane = useSidepaneToggle(SIDE_PANE_OPTIONS.PARTICIPANTS); const isParticipantsOpen = useIsSidepaneTypeOpen(SIDE_PANE_OPTIONS.PARTICIPANTS); - useEffect(() => { - if (isParticipantsOpen && peerCount === 0) { - toggleSidepane(); - } - }, [isParticipantsOpen, peerCount, toggleSidepane]); if (peerCount === 0) { return null; diff --git a/packages/roomkit-react/src/Prebuilt/components/Preview/PreviewJoin.tsx b/packages/roomkit-react/src/Prebuilt/components/Preview/PreviewJoin.tsx index dc9a2ec647..918b453e4b 100644 --- a/packages/roomkit-react/src/Prebuilt/components/Preview/PreviewJoin.tsx +++ b/packages/roomkit-react/src/Prebuilt/components/Preview/PreviewJoin.tsx @@ -1,4 +1,4 @@ -import React, { Fragment, Suspense, useCallback, useEffect, useMemo, useState } from 'react'; +import React, { Fragment, useCallback, useEffect, useMemo, useState } from 'react'; import { useMeasure, useMedia } from 'react-use'; import { HMSRoomState, @@ -18,6 +18,7 @@ import { AudioLevel } from '../../../AudioLevel'; import { useHMSPrebuiltContext } from '../../AppContext'; // @ts-ignore: No implicit Any import IconButton from '../../IconButton'; +import SidePane from '../../layouts/SidePane'; import { useRoomLayout } from '../../provider/roomLayoutProvider'; // @ts-ignore: No implicit Any import { AudioVideoToggle } from '../AudioVideoToggle'; @@ -32,6 +33,8 @@ import { Logo } from '../Header/HeaderComponents'; // @ts-ignore: No implicit Any import SettingsModal from '../Settings/SettingsModal'; // @ts-ignore: No implicit Any +import { VBToggle } from '../VirtualBackground/VBToggle'; +// @ts-ignore: No implicit Any import PreviewForm from './PreviewForm'; // @ts-ignore: No implicit Any import { useAuthToken, useUISettings } from '../AppData/useUISettings'; @@ -42,9 +45,6 @@ import { calculateAvatarAndAttribBoxSize, getFormattedCount } from '../../common // @ts-ignore: No implicit Any import { UI_SETTINGS } from '../../common/constants'; -// @ts-ignore: No implicit Any -const VirtualBackground = React.lazy(() => import('../../plugins/VirtualBackground/VirtualBackground')); - const getParticipantChipContent = (peerCount = 0) => { if (peerCount === 0) { return 'You are the first to join'; @@ -133,60 +133,65 @@ const PreviewJoin = ({ }, [initialName]); return roomState === HMSRoomState.Preview ? ( - - {toggleVideo ? null : } - - - - {previewHeader.title} - - - {previewHeader.sub_title} - - - {isStreamingOn ? ( - } - /> - ) : null} - + + + {toggleVideo ? null : } + + + + {previewHeader.title} + + + {previewHeader.sub_title} + + + {isStreamingOn ? ( + } + /> + ) : null} + + - - {toggleVideo ? ( - - - - ) : null} - - - + {toggleVideo ? ( + + + + ) : null} + + + + + + + - + ) : ( ); @@ -274,7 +279,7 @@ export const PreviewControls = ({ hideSettings }: { hideSettings: boolean }) => > - {!isMobile ? : null} + {!isMobile ? : null} {!hideSettings ? : null} diff --git a/packages/roomkit-react/src/Prebuilt/components/RoleChangeRequest/RequestPrompt.tsx b/packages/roomkit-react/src/Prebuilt/components/RoleChangeRequest/RequestPrompt.tsx index bbbc7f036e..1cbd39ddea 100644 --- a/packages/roomkit-react/src/Prebuilt/components/RoleChangeRequest/RequestPrompt.tsx +++ b/packages/roomkit-react/src/Prebuilt/components/RoleChangeRequest/RequestPrompt.tsx @@ -33,10 +33,9 @@ export const RequestPrompt = ({ } return ( - + - - + e.preventDefault()}> {title} diff --git a/packages/roomkit-react/src/Prebuilt/components/VirtualBackground/VBCollection.tsx b/packages/roomkit-react/src/Prebuilt/components/VirtualBackground/VBCollection.tsx new file mode 100644 index 0000000000..f801722816 --- /dev/null +++ b/packages/roomkit-react/src/Prebuilt/components/VirtualBackground/VBCollection.tsx @@ -0,0 +1,50 @@ +import React from 'react'; +import { Box } from '../../../Layout'; +import { Text } from '../../../Text'; +import { VBOption } from './VBOption'; +import { VB_EFFECT } from './constants'; + +export const VBCollection = ({ + options, + title, + activeBackgroundType = '', + activeBackground = '', +}: { + options: { + title?: string; + icon?: React.JSX.Element; + onClick?: () => Promise; + mediaURL?: string; + type: string; + }[]; + title: string; + activeBackground: HTMLImageElement | string; + activeBackgroundType: string; +}) => { + if (options.length === 0) { + return null; + } + return ( + + + {title} + + + {options.map(option => ( + + {option?.icon} + {option?.title} + + ))} + + + ); +}; diff --git a/packages/roomkit-react/src/Prebuilt/components/VirtualBackground/VBOption.tsx b/packages/roomkit-react/src/Prebuilt/components/VirtualBackground/VBOption.tsx new file mode 100644 index 0000000000..ab0c452ad2 --- /dev/null +++ b/packages/roomkit-react/src/Prebuilt/components/VirtualBackground/VBOption.tsx @@ -0,0 +1,50 @@ +import React from 'react'; +import { Box, Flex } from '../../../Layout'; +import { Text } from '../../../Text'; + +const Root = ({ + onClick, + mediaURL, + isActive, + children, +}: { + onClick?: () => Promise; + mediaURL?: string; + isActive: boolean; + children?: React.JSX.Element[]; +}) => ( + await onClick?.()} + > + {children} + +); + +const Title = ({ children }: { children?: string }) => { + return children ? ( + + {children} + + ) : null; +}; + +const Icon = ({ children }: { children?: React.JSX.Element }) => { + return children ? {children} : null; +}; + +export const VBOption = { + Root, + Title, + Icon, +}; diff --git a/packages/roomkit-react/src/Prebuilt/components/VirtualBackground/VBPicker.jsx b/packages/roomkit-react/src/Prebuilt/components/VirtualBackground/VBPicker.jsx new file mode 100644 index 0000000000..e25242482c --- /dev/null +++ b/packages/roomkit-react/src/Prebuilt/components/VirtualBackground/VBPicker.jsx @@ -0,0 +1,155 @@ +import React, { useEffect, useRef, useState } from 'react'; +import { HMSVBPlugin } from '@100mslive/hms-virtual-background'; +import { + HMSRoomState, + selectIsLocalVideoEnabled, + selectLocalPeer, + selectLocalPeerRole, + selectLocalVideoTrackID, + selectRoomState, + selectVideoTrackByID, + useHMSActions, + useHMSStore, +} from '@100mslive/react-sdk'; +import { BlurPersonHighIcon, CloseIcon, CrossCircleIcon } from '@100mslive/react-icons'; +import { Box, Flex, Video } from '../../../index'; +import { Text } from '../../../Text'; +import { VBCollection } from './VBCollection'; +// @ts-ignore +import { useSidepaneToggle } from '../AppData/useSidepane'; +// @ts-ignore +import { useSetAppDataByKey, useUISettings } from '../AppData/useUISettings'; +// @ts-ignore +import { APP_DATA, SIDE_PANE_OPTIONS, UI_SETTINGS } from '../../common/constants'; +import { defaultMedia, VB_EFFECT } from './constants'; + +const iconDims = { height: '40px', width: '40px' }; + +export const VBPicker = () => { + const toggleVB = useSidepaneToggle(SIDE_PANE_OPTIONS.VB); + const pluginRef = useRef(null); + const hmsActions = useHMSActions(); + const role = useHMSStore(selectLocalPeerRole); + const [isVBSupported, setIsVBSupported] = useState(false); + const localPeerVideoTrackID = useHMSStore(selectLocalVideoTrackID); + const [background, setBackground] = useSetAppDataByKey(APP_DATA.background); + const [backgroundType, setBackgroundType] = useSetAppDataByKey(APP_DATA.backgroundType); + const localPeer = useHMSStore(selectLocalPeer); + const isVideoOn = useHMSStore(selectIsLocalVideoEnabled); + const mirrorLocalVideo = useUISettings(UI_SETTINGS.mirrorLocalVideo); + const trackSelector = selectVideoTrackByID(localPeer?.videoTrack); + const track = useHMSStore(trackSelector); + const roomState = useHMSStore(selectRoomState); + + async function createPlugin() { + if (!pluginRef.current) { + pluginRef.current = new HMSVBPlugin(background, backgroundType); + } + } + + useEffect(() => { + if (!localPeerVideoTrackID) { + return; + } + createPlugin().then(() => { + //check support of plugin + if (pluginRef.current) { + const pluginSupport = hmsActions.validateVideoPluginSupport(pluginRef.current); + setIsVBSupported(pluginSupport.isSupported); + } + }); + }, [hmsActions, localPeerVideoTrackID]); + + async function addPlugin({ mediaURL = '', blurPower = 0 }) { + if (!pluginRef.current) { + return; + } + try { + await createPlugin(); + window.HMS.virtualBackground = pluginRef.current; + if (mediaURL) { + const img = document.createElement('img'); + img.alt = 'VB'; + img.src = mediaURL; + await pluginRef.current.setBackground(img, VB_EFFECT.MEDIA); + } else if (blurPower) { + await pluginRef.current.setBackground(VB_EFFECT.BLUR, VB_EFFECT.BLUR); + } + // Will store blur power here + setBackground(mediaURL || VB_EFFECT.BLUR); + setBackgroundType(mediaURL ? VB_EFFECT.MEDIA : VB_EFFECT.BLUR); + if (role) + await hmsActions.addPluginToVideoTrack(pluginRef.current, Math.floor(role.publishParams.video.frameRate / 2)); + } catch (err) { + console.error('add virtual background plugin failed', err); + } + } + + async function removePlugin() { + if (pluginRef.current) { + await hmsActions.removePluginFromVideoTrack(pluginRef.current); + pluginRef.current = null; + } + } + + if (!isVBSupported) { + return null; + } + + return ( + + + + Virtual Background + + + + + + + {/* Hidden in preview as the effect will be visible in the preview tile. Needed inside the room because the peer might not be on-screen */} + {isVideoOn && roomState !== HMSRoomState.Preview ? ( + + ); +}; diff --git a/packages/roomkit-react/src/Prebuilt/components/VirtualBackground/VBToggle.jsx b/packages/roomkit-react/src/Prebuilt/components/VirtualBackground/VBToggle.jsx new file mode 100644 index 0000000000..a1d52f2ca3 --- /dev/null +++ b/packages/roomkit-react/src/Prebuilt/components/VirtualBackground/VBToggle.jsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { selectIsLocalVideoEnabled, useHMSStore } from '@100mslive/react-sdk'; +import { VirtualBackgroundIcon } from '@100mslive/react-icons'; +import { Tooltip } from '../../../Tooltip'; +import IconButton from '../../IconButton'; +import { useIsSidepaneTypeOpen, useSidepaneToggle } from '../AppData/useSidepane'; +import { SIDE_PANE_OPTIONS } from '../../common/constants'; + +export const VBToggle = () => { + const toggleVB = useSidepaneToggle(SIDE_PANE_OPTIONS.VB); + const isVBOpen = useIsSidepaneTypeOpen(SIDE_PANE_OPTIONS.VB); + const isVideoOn = useHMSStore(selectIsLocalVideoEnabled); + if (!isVideoOn) { + return null; + } + + return ( + + + + + + ); +}; diff --git a/packages/roomkit-react/src/Prebuilt/components/VirtualBackground/constants.ts b/packages/roomkit-react/src/Prebuilt/components/VirtualBackground/constants.ts new file mode 100644 index 0000000000..754d4673b2 --- /dev/null +++ b/packages/roomkit-react/src/Prebuilt/components/VirtualBackground/constants.ts @@ -0,0 +1,19 @@ +// Will support all media, setting to image here to test with current plugin interface +export const VB_EFFECT = { BLUR: 'blur', BEAUTIFY: 'BEAUTIFY', NONE: 'none', MEDIA: 'image' }; + +export const defaultMedia = [ + 'https://d2qi07yyjujoxr.cloudfront.net/webapp/vb/vb-1.jpg', + 'https://d2qi07yyjujoxr.cloudfront.net/webapp/vb/vb-2.jpg', + 'https://d2qi07yyjujoxr.cloudfront.net/webapp/vb/vb-3.png', + 'https://d2qi07yyjujoxr.cloudfront.net/webapp/vb/vb-4.jpg', + 'https://d2qi07yyjujoxr.cloudfront.net/webapp/vb/vb-5.jpg', + 'https://d2qi07yyjujoxr.cloudfront.net/webapp/vb/vb-6.jpg', + 'https://d2qi07yyjujoxr.cloudfront.net/webapp/vb/vb-7.jpg', + 'https://d2qi07yyjujoxr.cloudfront.net/webapp/vb/vb-8.jpg', + 'https://d2qi07yyjujoxr.cloudfront.net/webapp/vb/vb-9.jpg', + 'https://d2qi07yyjujoxr.cloudfront.net/webapp/vb/vb-10.jpg', + 'https://d2qi07yyjujoxr.cloudfront.net/webapp/vb/vb-11.jpg', + 'https://d2qi07yyjujoxr.cloudfront.net/webapp/vb/vb-12.jpg', + // 'https://d2qi07yyjujoxr.cloudfront.net/webapp/vb/vb-13.jpg', + // 'https://d2qi07yyjujoxr.cloudfront.net/webapp/vb/vb-14.jpg', +]; diff --git a/packages/roomkit-react/src/Prebuilt/layouts/SidePane.tsx b/packages/roomkit-react/src/Prebuilt/layouts/SidePane.tsx index 0839ffb976..582e111dcd 100644 --- a/packages/roomkit-react/src/Prebuilt/layouts/SidePane.tsx +++ b/packages/roomkit-react/src/Prebuilt/layouts/SidePane.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { useMedia } from 'react-use'; import { ConferencingScreen } from '@100mslive/types-prebuilt'; import { selectAppData, selectVideoTrackByPeerID, useHMSStore } from '@100mslive/react-sdk'; @@ -7,8 +7,12 @@ import { SidePaneTabs } from '../components/SidePaneTabs'; import { TileCustomisationProps } from '../components/VideoLayouts/GridLayout'; // @ts-ignore: No implicit Any import VideoTile from '../components/VideoTile'; +// @ts-ignore: No implicit Any +import { VBPicker } from '../components/VirtualBackground/VBPicker'; import { Box, Flex } from '../../Layout'; import { config as cssConfig } from '../../Theme'; +// @ts-ignore: No implicit Any +import { useSidepaneReset } from '../components/AppData/useSidepane'; import { useRoomLayoutConferencingScreen } from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen'; import { translateAcross } from '../../utils'; // @ts-ignore: No implicit Any @@ -20,14 +24,15 @@ const SidePane = ({ hideControls = false, }: { screenType: keyof ConferencingScreen; - tileProps: TileCustomisationProps; - hideControls: boolean; + tileProps?: TileCustomisationProps; + hideControls?: boolean; }) => { const isMobile = useMedia(cssConfig.media.md); const sidepane = useHMSStore(selectAppData(APP_DATA.sidePane)); const activeScreensharePeerId = useHMSStore(selectAppData(APP_DATA.activeScreensharePeerId)); const trackId = useHMSStore(selectVideoTrackByPeerID(activeScreensharePeerId))?.id; const { elements } = useRoomLayoutConferencingScreen(); + const resetSidePane = useSidepaneReset(); let ViewComponent; if (sidepane === SIDE_PANE_OPTIONS.POLLS) { ViewComponent = ; @@ -35,6 +40,16 @@ const SidePane = ({ if (sidepane === SIDE_PANE_OPTIONS.PARTICIPANTS || sidepane === SIDE_PANE_OPTIONS.CHAT) { ViewComponent = ; } + if (sidepane === SIDE_PANE_OPTIONS.VB) { + ViewComponent = ; + } + + useEffect(() => { + return () => { + resetSidePane(); + }; + }, [resetSidePane]); + if (!ViewComponent && !trackId) { return null; } @@ -58,6 +73,7 @@ const SidePane = ({ h: '100%', flexShrink: 0, gap: '$4', + position: 'relative', '@md': { position: mwebStreamingChat ? 'absolute' : '', zIndex: 12 }, }} >