Commit 6f5da362 authored by Thisara Kavinda's avatar Thisara Kavinda

feat: implemented control buttons

parent e6ce68d9
import { Box, Typography } from '@mui/material'
import { useTheme, type Theme } from '@mui/material/styles'
import ControlsButtonGroup from '../ControlsButtonGroup/ControlsButtonGroup'
import type { IMicrophoneAudioTrack, ICameraVideoTrack } from 'agora-rtc-sdk-ng'
import React, { useEffect } from 'react'
interface Props {
setJoined: (x: boolean) => void
localCameraTrack: ICameraVideoTrack | null
localMicrophoneTrack: IMicrophoneAudioTrack | null
}
const ControlCenter = ({ setJoined, localCameraTrack, localMicrophoneTrack }: Props) => {
const theme: Theme = useTheme()
const [currentTime, setCurrentTime] = React.useState(new Date())
const updateTime = () => {
setCurrentTime(new Date())
}
useEffect(() => {
const interval = setInterval(updateTime, 6000)
return () => clearInterval(interval)
}, [])
return (
<Box
sx={{
height: '100%',
width: '100%',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
}}
>
<Box
sx={{
width: '20%',
paddingLeft: '0px',
alignItems: 'center',
justifyContent: 'flex-start',
textAlign: 'left',
}}
>
<Typography
sx={{
fontSize: '18px',
color: theme.palette.common.white,
fontWeight: 600,
textAlign: 'left',
paddingLeft: '50px',
}}
>
{currentTime.toLocaleTimeString('en-US', {
hour: '2-digit',
minute: '2-digit',
hour12: true,
})}
</Typography>
</Box>
<Box
sx={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
}}
>
<ControlsButtonGroup
setJoined={setJoined}
localCameraTrack={localCameraTrack}
localMicrophoneTrack={localMicrophoneTrack}
/>
</Box>
<Box
sx={{
width: '20%',
display: 'flex',
flexDirection: 'row',
justifyContent: 'flex-end',
paddingRight: '50px',
alignItems: 'center',
}}
></Box>
</Box>
)
}
export default ControlCenter
import React, { useState } from 'react'
import type { IMicrophoneAudioTrack, ICameraVideoTrack } from 'agora-rtc-sdk-ng'
import { Box, IconButton } from '@mui/material'
import MicIcon from '@mui/icons-material/Mic'
import VideocamIcon from '@mui/icons-material/Videocam'
import { useTheme, type Theme } from '@mui/material/styles'
import ClosedCaptionIcon from '@mui/icons-material/ClosedCaption'
import PresentToAllIcon from '@mui/icons-material/PresentToAll'
import MicOffIcon from '@mui/icons-material/MicOff'
import CallEndIcon from '@mui/icons-material/CallEnd'
import VideocamOffIcon from '@mui/icons-material/VideocamOff'
interface Props {
setJoined: (x: boolean) => void
localCameraTrack: ICameraVideoTrack | null
localMicrophoneTrack: IMicrophoneAudioTrack | null
}
const ControlsButtonGroup = ({ setJoined, localCameraTrack, localMicrophoneTrack }: Props) => {
const theme: Theme = useTheme()
const [isAudioEnable, setIsAudioEnable] = useState(localMicrophoneTrack?.enabled)
const [isVideoEnabled, setIsVideoEnabled] = useState(localCameraTrack?.enabled)
const toogleAudio = async () => {
if (isAudioEnable) {
await localMicrophoneTrack?.setEnabled(false)
setIsAudioEnable(false)
} else {
await localMicrophoneTrack?.setEnabled(true)
setIsAudioEnable(true)
}
}
const toogleVideo = async () => {
if (isVideoEnabled) {
await localCameraTrack?.setEnabled(false)
setIsVideoEnabled(false)
} else {
await localCameraTrack?.setEnabled(true)
setIsVideoEnabled(true)
}
}
const handleLeaveCall = () => {
localCameraTrack?.close()
localMicrophoneTrack?.close()
setJoined(false)
}
return (
<Box sx={{ height: '100%', width: '100%' }}>
<IconButton
sx={{
borderRadius: '50%',
padding: '15px',
marginX: '15px',
backgroundColor: isAudioEnable ? 'green' : '#363739',
'&:hover': { backgroundColor: isAudioEnable ? 'green' : '#363739' },
}}
onClick={toogleAudio}
>
{isAudioEnable ? (
<MicIcon sx={{ color: theme.palette.common.white }} />
) : (
<MicOffIcon sx={{ color: theme.palette.common.white }} />
)}
</IconButton>
<IconButton
sx={{
borderRadius: '50%',
padding: '15px',
marginX: '15px',
backgroundColor: isVideoEnabled ? 'green' : '#363739',
'&:hover': { backgroundColor: isVideoEnabled ? 'green' : '#363739' },
}}
onClick={toogleVideo}
>
{isVideoEnabled ? (
<VideocamIcon sx={{ color: theme.palette.common.white }} />
) : (
<VideocamOffIcon sx={{ color: theme.palette.common.white }} />
)}
</IconButton>
<IconButton
sx={{
borderRadius: '50%',
padding: '15px',
marginX: '15px',
backgroundColor: '#363739',
'&:hover': { backgroundColor: '#363739' },
}}
>
<ClosedCaptionIcon sx={{ color: theme.palette.common.white }} />
</IconButton>
<IconButton
sx={{
borderRadius: '50%',
padding: '15px',
marginX: '15px',
backgroundColor: '#363739',
'&:hover': { backgroundColor: '#363739' },
}}
>
<PresentToAllIcon sx={{ color: theme.palette.common.white }} />
</IconButton>
<IconButton
sx={{
borderRadius: '40%',
padding: '15px',
paddingX: '25px',
marginX: '15px',
backgroundColor: 'red',
'&:hover': { backgroundColor: 'red' },
}}
onClick={handleLeaveCall}
>
<CallEndIcon sx={{ color: theme.palette.common.white }} />
</IconButton>
</Box>
)
}
export default ControlsButtonGroup
import React, { useEffect, useRef, useState } from 'react'
import { Box } from '@mui/material'
import { useTheme, type Theme } from '@mui/material/styles'
import {
useLocalCameraTrack,
useLocalMicrophoneTrack,
useRemoteUsers,
usePublish,
useRTCClient,
useClientEvent,
} from 'agora-rtc-react'
import { useRemoteUsers, usePublish, useRTCClient, useClientEvent } from 'agora-rtc-react'
import SymmetricGrid from '../SymmetricGrid/SymmetricGrid'
import PinnedGrid from '../PinnedGrid/PinnedGrid'
import type { IAgoraRTCRemoteUser } from 'agora-rtc-sdk-ng'
import type {
IAgoraRTCRemoteUser,
ICameraVideoTrack,
IMicrophoneAudioTrack,
} from 'agora-rtc-sdk-ng'
import ControlCenter from '../ControlCenter/ControlCenter'
const MeetingLayout = () => {
interface Props {
setJoined: (x: boolean) => void
localCameraTrack: ICameraVideoTrack | null
localMicrophoneTrack: IMicrophoneAudioTrack | null
}
const MeetingLayout = ({ setJoined, localCameraTrack, localMicrophoneTrack }: Props) => {
const theme: Theme = useTheme()
const agoraEngine = useRTCClient()
const { localCameraTrack } = useLocalCameraTrack()
const { localMicrophoneTrack } = useLocalMicrophoneTrack()
usePublish([localMicrophoneTrack, localCameraTrack])
const remoteUsers: IAgoraRTCRemoteUser[] = useRemoteUsers()
......@@ -52,11 +54,12 @@ const MeetingLayout = () => {
<Box
sx={{
width: '100%',
height: '80%',
height: '100%',
backgroundColor: theme.palette.background.default,
padding: '30px',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
}}
>
<Box
......@@ -64,7 +67,7 @@ const MeetingLayout = () => {
display: 'flex',
flexDirection: 'row',
width: '100%',
height: '100%',
height: '80%',
}}
ref={gridContainerRef}
>
......@@ -75,6 +78,7 @@ const MeetingLayout = () => {
setIsPinned={setIsPinned}
pinnedUser={pinnedUser}
setPinnedUser={setPinnedUser}
localCameraTrack={localCameraTrack}
/>
) : (
<SymmetricGrid
......@@ -83,9 +87,17 @@ const MeetingLayout = () => {
isPinned={isPinned}
setIsPinned={setIsPinned}
setPinnedUser={setPinnedUser}
localCameraTrack={localCameraTrack}
/>
)}
</Box>
<Box sx={{ height: '10%', width: '100%', display: 'flex', marginBottom: '40px' }}>
<ControlCenter
setJoined={setJoined}
localCameraTrack={localCameraTrack}
localMicrophoneTrack={localMicrophoneTrack}
/>
</Box>
</Box>
)
}
......
import React, { useEffect } from 'react'
import type { IAgoraRTCRemoteUser } from 'agora-rtc-sdk-ng'
import type { IAgoraRTCRemoteUser, ICameraVideoTrack } from 'agora-rtc-sdk-ng'
import { Box, Button, IconButton, Popover, Stack } from '@mui/material'
import useMediaQuery from '@mui/material/useMediaQuery'
import { RemoteUser, useRemoteUsers } from 'agora-rtc-react'
......@@ -13,6 +13,7 @@ interface Props {
setIsPinned: (value: boolean) => void
pinnedUser: IAgoraRTCRemoteUser
setPinnedUser: (value: IAgoraRTCRemoteUser | null) => void
localCameraTrack: ICameraVideoTrack | null
}
const PinnedGrid = ({
......@@ -21,6 +22,7 @@ const PinnedGrid = ({
setIsPinned,
pinnedUser,
setPinnedUser,
localCameraTrack,
}: Props) => {
const theme: Theme = useTheme()
const isSm = useMediaQuery(theme.breakpoints.up('sm'))
......@@ -144,6 +146,7 @@ const PinnedGrid = ({
itemHeight={itemHeight}
setIsPinned={setIsPinned}
setPinnedUser={setPinnedUser}
localCameraTrack={localCameraTrack}
/>
{remoteUsers.length > 1 &&
remoteUsers
......
......@@ -3,7 +3,7 @@ import { Box, Grid } from '@mui/material'
import useMediaQuery from '@mui/material/useMediaQuery'
import { useRemoteUsers } from 'agora-rtc-react'
import { useTheme, type Theme } from '@mui/material/styles'
import type { IAgoraRTCRemoteUser } from 'agora-rtc-sdk-ng'
import type { IAgoraRTCRemoteUser, ICameraVideoTrack } from 'agora-rtc-sdk-ng'
import UserCard from '../UserCard/UserCard'
interface Props {
......@@ -12,6 +12,7 @@ interface Props {
isPinned: boolean
setIsPinned: (value: boolean) => void
setPinnedUser: (value: IAgoraRTCRemoteUser | null) => void
localCameraTrack: ICameraVideoTrack | null
}
const SymmetricGrid = ({
......@@ -20,6 +21,7 @@ const SymmetricGrid = ({
isPinned,
setIsPinned,
setPinnedUser,
localCameraTrack,
}: Props) => {
const theme: Theme = useTheme()
const isSm = useMediaQuery(theme.breakpoints.up('sm'))
......@@ -133,6 +135,7 @@ const SymmetricGrid = ({
itemHeight={itemHeight}
setIsPinned={setIsPinned}
setPinnedUser={setPinnedUser}
localCameraTrack={localCameraTrack}
/>
</Grid>
{remoteUsers.map((remoteUser, index) => (
......
import { Box, Button, IconButton, Popover } from '@mui/material'
import MoreVertIcon from '@mui/icons-material/MoreVert'
import { LocalVideoTrack, RemoteUser, useLocalCameraTrack } from 'agora-rtc-react'
import type { IAgoraRTCRemoteUser } from 'agora-rtc-sdk-ng'
import { LocalVideoTrack, RemoteUser } from 'agora-rtc-react'
import type { IAgoraRTCRemoteUser, ICameraVideoTrack } from 'agora-rtc-sdk-ng'
import { useTheme, type Theme } from '@mui/material/styles'
import React, { useEffect } from 'react'
......@@ -11,11 +11,18 @@ interface Props {
setIsPinned: (value: boolean) => void
setPinnedUser: (value: IAgoraRTCRemoteUser | null) => void
remoteUser?: IAgoraRTCRemoteUser
localCameraTrack?: ICameraVideoTrack | null
}
const UserCard = ({ type, remoteUser, itemHeight, setIsPinned, setPinnedUser }: Props) => {
const UserCard = ({
type,
remoteUser,
itemHeight,
setIsPinned,
setPinnedUser,
localCameraTrack,
}: Props) => {
const theme: Theme = useTheme()
const { localCameraTrack } = useLocalCameraTrack()
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null)
......
......@@ -13,15 +13,11 @@ const VideoCall = () => {
setJoined(true)
}
// const handleLeaveClick = () => {
// setJoined(false)
// }
return (
<Box sx={{ height: '100vh', width: '100vw', overflow: 'hidden' }}>
{joined ? (
<AgoraRTCProvider client={agoraEngine}>
<AgoraManager>
<AgoraManager setJoined={setJoined}>
<div>asas</div>
</AgoraManager>
</AgoraRTCProvider>
......
import { useJoin, useLocalCameraTrack, useLocalMicrophoneTrack } from 'agora-rtc-react'
import React, { createContext, useContext, useEffect } from 'react'
import { useJoin, useLocalCameraTrack, useLocalMicrophoneTrack } from 'agora-rtc-react'
import type { IMicrophoneAudioTrack, ICameraVideoTrack } from 'agora-rtc-sdk-ng'
import { Box } from '@mui/material'
import { useTheme, type Theme } from '@mui/material/styles'
......@@ -31,7 +30,13 @@ export const useAgoraContext = () => {
return context
}
export const AgoraManager = ({ children }: { children: React.ReactNode }) => {
export const AgoraManager = ({
setJoined,
children,
}: {
setJoined: (x: boolean) => void
children: React.ReactNode
}) => {
const theme: Theme = useTheme()
const {
......@@ -73,7 +78,11 @@ export const AgoraManager = ({ children }: { children: React.ReactNode }) => {
localCameraTrack={localCameraTrack}
localMicrophoneTrack={localMicrophoneTrack}
>
<MeetingLayout />
<MeetingLayout
setJoined={setJoined}
localCameraTrack={localCameraTrack}
localMicrophoneTrack={localMicrophoneTrack}
/>
</AgoraProvider>
) : joinError ? (
<MeetingLoading variant='error' />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment