Skip to content

Commit

Permalink
Merge pull request #367 from ant-media/addRaiseYourHand
Browse files Browse the repository at this point in the history
Implement Raise Your Hand Feature
  • Loading branch information
burak-58 authored Jan 7, 2025
2 parents 523acf5 + 00ed391 commit fa471f1
Show file tree
Hide file tree
Showing 12 changed files with 697 additions and 100 deletions.
4 changes: 2 additions & 2 deletions react/.env.production
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# When you create a war file and deploy it to the Ant Media Server, these variables will be set automatically.

# Ant Media Server URL configurations
#REACT_APP_WEBSOCKET_URL="ws://localhost:5080/Conference/websocket"
# REACT_APP_WEBSOCKET_URL="ws://localhost:5080/Conference/websocket"

# Turn Server URL configurations
REACT_APP_TURN_SERVER_URL="stun:stun1.l.google.com:19302"
Expand Down Expand Up @@ -81,4 +81,4 @@ REACT_APP_PLAY_ONLY_ROOM_EMPTY_MESSAGE="There is no active publisher right now."

# URL configurations
REACT_APP_FOOTER_LOGO_ON_CLICK_URL="https://antmedia.io/circle"
REACT_APP_REPORT_PROBLEM_URL="https://github.com/ant-media/conference-call-application/issues"
REACT_APP_REPORT_PROBLEM_URL="https://github.com/ant-media/conference-call-application/issues"
9 changes: 1 addition & 8 deletions react/src/Components/BecomePublisherConfirmationDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ import useMediaQuery from '@mui/material/useMediaQuery';
import {useTheme} from '@mui/material/styles';

export default function BecomePublisherConfirmationDialog(props) {
return (
<div></div>
);

/*
const theme = useTheme();
const fullScreen = useMediaQuery(theme.breakpoints.down('md'));

Expand All @@ -23,7 +18,7 @@ export default function BecomePublisherConfirmationDialog(props) {
const approveBecomePublisher = () => {
props?.setBecomePublisherConfirmationDialogOpen(false);
props?.handleStartBecomePublisher();
}
}

return (
<Dialog
Expand All @@ -47,6 +42,4 @@ export default function BecomePublisherConfirmationDialog(props) {
</DialogActions>
</Dialog>
);
*/
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import Button from '@mui/material/Button';
import { SvgIcon } from '../../SvgIcon';
import { Tooltip } from '@mui/material';
import { styled } from '@mui/material/styles';
import {styled, useTheme} from '@mui/material/styles';
import { useTranslation } from 'react-i18next';
import {CustomizedBtn} from "../../CustomizedBtn";

Expand All @@ -17,14 +17,15 @@ export const roundStyle = {
};

function RequestPublishButton(props) {
const theme = useTheme();
const { rounded, footer, handlePublisherRequest } = props;
const { t } = useTranslation();

return (
<>
<Tooltip title={t('Request becoming publisher')} placement="top">
<CustomizedBtn id="request-publish-button" data-testid="request-publish-button" className={footer ? 'footer-icon-button' : ''} variant="contained" sx={rounded ? roundStyle : {}} color="secondary" onClick={(e) => { handlePublisherRequest(); }}>
<SvgIcon size={32} name={'raise-hand'} color="#fff" />
<SvgIcon size={32} name={'raise-hand'} color={theme.palette?.iconColor?.primary} />
</CustomizedBtn>
</Tooltip>
</>
Expand Down
4 changes: 2 additions & 2 deletions react/src/Components/ParticipantTab.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ function ParticipantTab({
style={{ borderBottomWidth: 1 }}
sx={{ borderColor: "primary.main" }}
>
<Grid item sx={{ pr: 1, maxWidth: "60%" }}>
<Grid item sx={{ pr: 1, maxWidth: "40%" }}>
<ParticipantName
variant="body1"
sx={{
Expand Down Expand Up @@ -178,7 +178,7 @@ function ParticipantTab({
<SvgIcon size={28} name="pin" color={theme.palette?.participantListIcon?.primary}/>
</PinBtn>
)}
<div>
<div style={{display: 'flex'}}>
{process.env.REACT_APP_PARTICIPANT_TAB_ADMIN_MODE_ENABLED === "true" && isAdmin === true ? (
getAdminButtons(streamId, assignedVideoCardId, publishStreamId)
) : null}
Expand Down
11 changes: 8 additions & 3 deletions react/src/Components/PublisherRequestListDrawer.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import Drawer from '@mui/material/Drawer';
import { styled } from '@mui/material/styles';
import {styled, useTheme} from '@mui/material/styles';
import { Grid, Tabs, Tab } from '@mui/material';
import { useTranslation } from 'react-i18next';
import CloseDrawerButton from './DrawerButton';
Expand All @@ -12,7 +12,7 @@ const AntDrawer = styled(Drawer)(({ theme }) => (getAntDrawerStyle(theme)));
const PublisherRequestListGrid = styled(Grid)(({ theme }) => ({
position: 'relative',
padding: 16,
background: theme.palette.themeColor70,
background: theme.palette.themeColor[70],
borderRadius: 10,
}));
const TabGrid = styled(Grid)(({ theme }) => ({
Expand Down Expand Up @@ -75,7 +75,12 @@ const PublisherRequestListDrawer = React.memo(props => {
<Grid item container justifyContent="space-between" alignItems="center" style={{ flex: '1 1 auto', overflowY: 'hidden' }}>
<TabPanel value={value} index={0}>
<TabGrid container>
<PublisherRequestTab />
<PublisherRequestTab
approveBecomeSpeakerRequest={(streamId) => props?.approveBecomeSpeakerRequest(streamId)}
rejectBecomeSpeakerRequest={(streamId) => props?.rejectBecomeSpeakerRequest(streamId)}
requestSpeakerList={props?.requestSpeakerList}
publishStreamId={props?.publishStreamId}
/>
</TabGrid>
</TabPanel>
</Grid>
Expand Down
21 changes: 8 additions & 13 deletions react/src/Components/PublisherRequestTab.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Stack from "@mui/material/Stack";
import Grid from "@mui/material/Grid";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import { styled } from "@mui/material/styles";
import {styled} from "@mui/material/styles";
import { SvgIcon } from "./SvgIcon";

const PublisherRequestName = styled(Typography)(({ theme }) => ({
Expand All @@ -20,35 +20,32 @@ const PinBtn = styled(Button)(({ theme }) => ({
}));

function PublisherRequestTab(props) {
return (
<div></div>
);

/*
const getPublisherRequestItem = (videoId) => {
const getPublisherRequestItem = (streamId) => {
return (
<Grid
key={videoId}
key={streamId}
container
alignItems="center"
justifyContent="space-between"
style={{ borderBottomWidth: 1 }}
sx={{ borderColor: "primary.main" }}
>
<Grid item sx={{ pr: 1 }}>
<PublisherRequestName variant="body1">{videoId}</PublisherRequestName>
<PublisherRequestName variant="body1">{streamId}</PublisherRequestName>
</Grid>
<Grid item>
<PinBtn
data-testid={"approve-become-speaker-"+streamId}
sx={{ minWidth: "unset", pt: 1, pb: 1 }}
onClick={() => {props?.approveBecomeSpeakerRequest(videoId); props?.setRequestSpeakerList(props?.requestSpeakerList.filter((item) => item.streamId !== videoId))}}
onClick={() => {props?.approveBecomeSpeakerRequest(streamId);}}
>
Allow
</PinBtn>

<PinBtn
data-testid={"reject-become-speaker-"+streamId}
sx={{ minWidth: "unset", pt: 1, pb: 1 }}
onClick={() => {props?.rejectSpeakerRequest(videoId); props?.setRequestSpeakerList(props?.requestSpeakerList.filter((item) => item.streamId !== videoId))}}
onClick={() => {props?.rejectBecomeSpeakerRequest(streamId);}}
>
Deny
</PinBtn>
Expand Down Expand Up @@ -80,8 +77,6 @@ function PublisherRequestTab(props) {
</div>
);

*/

}

export default PublisherRequestTab;
90 changes: 90 additions & 0 deletions react/src/__tests__/Components/PublisherRequestTab.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// src/PublisherRequestTab.tet.js

import React from 'react';
import { render } from '@testing-library/react';
import PublisherRequestTab from "../../Components/PublisherRequestTab";
import theme from "../../styles/theme";
import {ThemeList} from "../../styles/themeList";
import {ThemeProvider} from "@mui/material";

// Mock the useContext hook
jest.mock('react', () => ({
...jest.requireActual('react'),
useContext: jest.fn(),
}));


describe('Publisher Request Tab Component', () => {

beforeEach(() => {
// Reset the mock implementation before each test
jest.clearAllMocks();
});


it('renders without crashing', () => {
render(
<ThemeProvider theme={theme(ThemeList.Green)}>
<PublisherRequestTab
approveBecomeSpeakerRequest={jest.fn()}
rejectBecomeSpeakerRequest={jest.fn()}
requestSpeakerList={["test1", "test2"]}
publishStreamId={"test0"}
/>
</ThemeProvider>
);
});

it('renders the publisher request items', () => {
const { getByText } = render(
<ThemeProvider theme={theme(ThemeList.Green)}>
<PublisherRequestTab
approveBecomeSpeakerRequest={jest.fn()}
rejectBecomeSpeakerRequest={jest.fn()}
requestSpeakerList={["test1", "test2"]}
publishStreamId={"test0"}
/>
</ThemeProvider>
);

expect(getByText('test1')).toBeInTheDocument();
expect(getByText('test2')).toBeInTheDocument();
});

it('calls the approveBecomeSpeakerRequest function when the allow button is clicked', () => {
let mockApproveBecomeSpeakerRequest = jest.fn();

const { getByTestId } = render(
<ThemeProvider theme={theme(ThemeList.Green)}>
<PublisherRequestTab
approveBecomeSpeakerRequest={mockApproveBecomeSpeakerRequest}
rejectBecomeSpeakerRequest={jest.fn()}
requestSpeakerList={["test1", "test2"]}
publishStreamId={"test0"}
/>
</ThemeProvider>
);

getByTestId('approve-become-speaker-test1').click();
expect(mockApproveBecomeSpeakerRequest).toHaveBeenCalledWith('test1');
});

it('calls the rejectBecomeSpeakerRequest function when the deny button is clicked', () => {
let mockRejectBecomeSpeakerRequest = jest.fn();

const { getByTestId } = render(
<ThemeProvider theme={theme(ThemeList.Green)}>
<PublisherRequestTab
approveBecomeSpeakerRequest={jest.fn()}
rejectBecomeSpeakerRequest={mockRejectBecomeSpeakerRequest}
requestSpeakerList={["test1", "test2"]}
publishStreamId={"test0"}
/>
</ThemeProvider>
);

getByTestId('reject-become-speaker-test1').click();
expect(mockRejectBecomeSpeakerRequest).toHaveBeenCalledWith('test1');
});

});
Loading

0 comments on commit fa471f1

Please sign in to comment.