Skip to content

Commit

Permalink
useMemo fix on InstructorViewersList
Browse files Browse the repository at this point in the history
  • Loading branch information
roro-lv committed Apr 5, 2022
1 parent 79310f6 commit f6ac6a9
Show file tree
Hide file tree
Showing 2 changed files with 281 additions and 0 deletions.
179 changes: 179 additions & 0 deletions src/frontend/components/ViewersList/InstructorViewersList/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import React, { useMemo } from 'react';
import { Box, Button, List } from 'grommet';
import { AddCircle } from 'grommet-icons';
import { defineMessages, useIntl } from 'react-intl';

import {
useParticipantsStore,
ParticipantType,
} from 'data/stores/useParticipantsStore';
import { Video } from 'types/tracks';
import { ViewersListHeader } from 'components/ViewersList/components/ViewersListHeader';
import { ViewersListItem } from 'components/ViewersList/components/ViewersListItem';
import { converse } from 'utils/window';
import { ViewersListItemContainer } from 'components/ViewersList/components/ViewersListItemContainer';
import { ViewersListTextButton } from 'components/ViewersList/components/ViewersListTextButton';

const messages = defineMessages({
demands: {
defaultMessage: 'Demands',
description:
'Participants asking for going on stage are displayed under this label.',
id: 'components.ViewersList.demands',
},
onStage: {
defaultMessage: 'On stage',
description: 'On-stage participants are displayed under this label.',
id: 'components.ViewersList.onStage',
},
otherViewers: {
defaultMessage: 'Other participants',
description: 'Connected participants are displayed under this label.',
id: 'components.ViewersList.otherViewers',
},
acceptButton: {
defaultMessage: 'Accept',
description:
'The text displayed in the button in charge of accepting on-stage request, in the viewers list.',
id: 'components.ViewersList.acceptButton',
},
endOnStageButton: {
defaultMessage: 'Terminate',
description:
'The text displayed in the button in charge of making students on stage exiting the stage, in the viewers list.',
id: 'components.ViewersList.endOnStageButton',
},
});

interface InstructorViewersListProps {
video: Video;
}

export const InstructorViewersList = ({
video,
}: InstructorViewersListProps) => {
const participants = useParticipantsStore((state) => state.participants);
const participantsOnStage = useMemo(
() =>
participants.filter(
(participant) =>
participant.isInstructor ||
video.participants_in_discussion.some(
(p) => p.name === participant.name,
),
),
[participants, video.participants_in_discussion],
);

const participantsNotOnStageAndNotAsking = useMemo(
() =>
participants.filter(
(participant) =>
!participantsOnStage.includes(participant) &&
!video.participants_asking_to_join.some(
(p) => p.name === participant.name,
),
),
[participants, participantsOnStage, video.participants_asking_to_join],
);
const intl = useIntl();

return (
<Box
fill
gap="30px"
overflow={{
horizontal: 'hidden',
vertical: 'auto',
}}
pad={{ bottom: '20px', top: '30px' }}
>
{video.participants_asking_to_join.length !== 0 && (
<React.Fragment>
<ViewersListHeader
margin={{ left: '20px', bottom: '6px' }}
text={intl.formatMessage(messages.demands)}
/>
<List
border={false}
data={video.participants_asking_to_join.sort(
(participantA, participantB) =>
participantA.name.localeCompare(participantB.name),
)}
pad="none"
>
{(item: ParticipantType, index: number) => (
<ViewersListItemContainer key={index}>
<ViewersListItem
isInstructor={item.isInstructor}
name={item.name}
/>
<Box direction="row" align="center" gap="10px">
<Button
icon={<AddCircle color="red-active" size="20px" />}
onClick={() => converse.rejectParticipantToJoin(item)}
plain
style={{ padding: '0px', transform: 'rotate(45deg)' }}
/>
<ViewersListTextButton
onClick={() =>
converse.acceptParticipantToJoin(item, video)
}
text={intl.formatMessage(messages.acceptButton)}
/>
</Box>
</ViewersListItemContainer>
)}
</List>
</React.Fragment>
)}

{participantsOnStage.length !== 0 && (
<React.Fragment>
<ViewersListHeader
margin={{ left: '20px', bottom: '6px' }}
text={intl.formatMessage(messages.onStage)}
/>
<List border={false} data={participantsOnStage} pad="none">
{(item: ParticipantType, index: number) => (
<ViewersListItemContainer key={index}>
<ViewersListItem
isInstructor={item.isInstructor}
name={item.name}
/>
{!item.isInstructor && (
<ViewersListTextButton
onClick={() => converse.kickParticipant(item)}
text={intl.formatMessage(messages.endOnStageButton)}
/>
)}
</ViewersListItemContainer>
)}
</List>
</React.Fragment>
)}
{participantsNotOnStageAndNotAsking.length !== 0 && (
<React.Fragment>
<ViewersListHeader
margin={{ left: '20px', bottom: '6px' }}
text={intl.formatMessage(messages.otherViewers)}
/>
<List
border={false}
data={participantsNotOnStageAndNotAsking}
pad="none"
>
{(item: ParticipantType, index: number) => (
<ViewersListItemContainer key={index}>
<ViewersListItem
isInstructor={item.isInstructor}
name={item.name}
/>
</ViewersListItemContainer>
)}
</List>
</React.Fragment>
)}
</Box>
);
};
102 changes: 102 additions & 0 deletions src/frontend/components/ViewersList/StudentViewersList/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import React, { useMemo } from 'react';
import { Box, List } from 'grommet';
import { defineMessages, useIntl } from 'react-intl';

import { ViewersListHeader } from 'components/ViewersList/components/ViewersListHeader';
import { ViewersListItem } from 'components/ViewersList/components/ViewersListItem';
import { ViewersListItemContainer } from 'components/ViewersList/components/ViewersListItemContainer';
import {
useParticipantsStore,
ParticipantType,
} from 'data/stores/useParticipantsStore';
import { Video } from 'types/tracks';

const messages = defineMessages({
onStage: {
defaultMessage: 'On stage',
description: 'On-stage participants are displayed under this label.',
id: 'components.ViewersList.onStage',
},
otherViewers: {
defaultMessage: 'Other participants',
description: 'Connected participants are displayed under this label.',
id: 'components.ViewersList.otherViewers',
},
});

interface StudentViewersListProps {
video: Video;
}

export const StudentViewersList = ({ video }: StudentViewersListProps) => {
const participants = useParticipantsStore((state) => state.participants);
const participantsOnStage = useMemo(
() =>
participants.filter(
(participant) =>
participant.isInstructor ||
video.participants_in_discussion.some(
(p) => p.name === participant.name,
),
),
[participants, video.participants_in_discussion],
);

const participantsNotOnStage = useMemo(
() =>
participants.filter(
(participant) => !participantsOnStage.includes(participant),
),
[participants, participantsOnStage],
);
const intl = useIntl();

return (
<Box
fill
gap="30px"
overflow={{
horizontal: 'hidden',
vertical: 'auto',
}}
pad={{ bottom: '20px', top: '30px' }}
>
{participantsOnStage.length !== 0 && (
<React.Fragment>
<ViewersListHeader
margin={{ left: '20px', bottom: '8px' }}
text={intl.formatMessage(messages.onStage)}
/>
<List border={false} data={participantsOnStage} pad="none">
{(item: ParticipantType, index: number) => (
<ViewersListItemContainer key={index}>
<ViewersListItem
isInstructor={item.isInstructor}
name={item.name}
/>
</ViewersListItemContainer>
)}
</List>
</React.Fragment>
)}
{participantsNotOnStage.length !== 0 && (
<React.Fragment>
<ViewersListHeader
margin={{ left: '20px', bottom: '8px' }}
text={intl.formatMessage(messages.otherViewers)}
/>
<List border={false} data={participantsNotOnStage} pad="none">
{(item: ParticipantType, index: number) => (
<ViewersListItemContainer key={index}>
<ViewersListItem
isInstructor={item.isInstructor}
name={item.name}
/>
</ViewersListItemContainer>
)}
</List>
</React.Fragment>
)}
</Box>
);
};

0 comments on commit f6ac6a9

Please sign in to comment.