-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(WebexMember): split component into space members and meeting par…
…ticipants
- Loading branch information
1 parent
615fdff
commit f1a0714
Showing
18 changed files
with
1,269 additions
and
978 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
89 changes: 89 additions & 0 deletions
89
src/components/WebexMeetingParticipant/WebexMeetingParticipant.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import {DestinationType} from '@webex/component-adapter-interfaces'; | ||
import Spinner from '../generic/Spinner/Spinner'; | ||
import Icon from '../generic/Icon/Icon'; | ||
import { | ||
useMembers, | ||
useMe, | ||
useOrganization, | ||
usePerson, | ||
} from '../hooks'; | ||
import WebexAvatar from '../WebexAvatar/WebexAvatar'; | ||
import webexComponentClasses from '../helpers'; | ||
|
||
/** | ||
* Displays a webex meeting participant. | ||
* | ||
* @param {object} props Data passed to the component | ||
* @param {string} props.className Custom CSS class to apply | ||
* @param {string} props.meetingID ID of the meeting for which to get members | ||
* @param {boolean} props.displayStatus Whether or not to display the user's status | ||
* @param {string} props.personID ID of the member for which to display avatar | ||
* @param {object} props.style Custom style to apply | ||
* @returns {object} JSX of the component | ||
* | ||
*/ | ||
export default function WebexMeetingParticipant({ | ||
className, | ||
meetingID, | ||
displayStatus, | ||
personID, | ||
style, | ||
}) { | ||
const {displayName, orgID, emails} = usePerson(personID); | ||
const me = useMe(); | ||
const members = useMembers(meetingID, DestinationType.MEETING); | ||
const member = members | ||
.find((itemMember) => itemMember.ID === personID); | ||
const organization = useOrganization(orgID); | ||
|
||
const isMuted = member?.muted; | ||
const isSpeaking = member?.speaking; | ||
const isExternal = orgID !== undefined && me.orgID !== undefined && me.orgID !== orgID; | ||
const isSharing = member?.sharing; | ||
const isInMeeting = member?.inMeeting; | ||
const showMe = me.ID === personID; | ||
const isHost = member?.host; | ||
const isGuest = member?.guest; | ||
|
||
const roles = [ | ||
showMe && 'You', | ||
isHost && 'Host', | ||
isSharing && 'Presenter', | ||
].filter((role) => role); | ||
const emailDomain = emails?.[0]?.split('@')[1] || <i>Unknown organization</i>; | ||
|
||
const [cssClasses, sc] = webexComponentClasses('meeting-participant', className); | ||
|
||
return ( | ||
<div className={cssClasses} style={style}> | ||
<WebexAvatar personID={personID} displayStatus={displayStatus} className={sc('avatar')} /> | ||
<div className={sc('details')}> | ||
<div className={sc('name')}> | ||
{(displayName ?? <Spinner size={18} />) || <i>Name not available</i>} | ||
{isGuest && <span className={sc('guest')}> (Guest)</span>} | ||
</div> | ||
{roles.length > 0 && <div className={sc('roles')}>{roles.join(', ')}</div>} | ||
{isExternal && <div className={sc('organization')}>{organization.name || emailDomain}</div>} | ||
</div> | ||
{isInMeeting && isSharing && <Icon name="content-share" size={16} className={sc('sharing')} />} | ||
{isInMeeting && isSpeaking && <Icon name="microphone" size={16} className={sc('speaking')} />} | ||
{isInMeeting && isMuted && <Icon name="microphone-muted" size={16} className={sc('muted')} />} | ||
</div> | ||
); | ||
} | ||
|
||
WebexMeetingParticipant.propTypes = { | ||
className: PropTypes.string, | ||
meetingID: PropTypes.string.isRequired, | ||
displayStatus: PropTypes.bool, | ||
personID: PropTypes.string.isRequired, | ||
style: PropTypes.shape(), | ||
}; | ||
|
||
WebexMeetingParticipant.defaultProps = { | ||
className: '', | ||
displayStatus: false, | ||
style: undefined, | ||
}; |
55 changes: 55 additions & 0 deletions
55
src/components/WebexMeetingParticipant/WebexMeetingParticipant.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
$C: #{$WEBEX_COMPONENTS_CLASS_PREFIX}-meeting-participant; | ||
|
||
.#{$C} { | ||
display: flex; | ||
align-items: center; | ||
color: var(--wxc-text-color); | ||
|
||
.#{$C}__avatar { | ||
height: 2rem; | ||
width: 2rem; | ||
margin-top: 0.5rem; | ||
margin-bottom: 0.5rem; | ||
} | ||
|
||
.#{$C}__details { | ||
flex: 1; | ||
min-width: 0; | ||
margin-left: 0.75rem; | ||
} | ||
|
||
.#{$C}__name { | ||
white-space: nowrap; | ||
overflow: hidden; | ||
text-overflow: ellipsis; | ||
margin-top: 0.063rem; | ||
|
||
.#{$C}__guest { | ||
color: var(--wxc-secondary-text-color); | ||
} | ||
} | ||
|
||
.#{$C}__roles { | ||
font-size: 0.875rem; | ||
line-height: 1rem; | ||
color: var(--wxc-secondary-text-color); | ||
} | ||
|
||
.#{$C}__organization { | ||
font-size: 0.875rem; | ||
line-height: 1rem; | ||
color: var(--wxc-warning-color); | ||
} | ||
|
||
.#{$C}__sharing { | ||
margin-right: 2.5rem; | ||
} | ||
|
||
.#{$C}__speaking { | ||
color: var(--wxc-speaking-color); | ||
} | ||
|
||
.#{$C}__muted { | ||
color: var(--wxc-muted-color); | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
src/components/WebexMeetingParticipant/WebexMeetingParticipant.stories.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import React from 'react'; | ||
import WebexMeetingParticipant from './WebexMeetingParticipant'; | ||
|
||
export default { | ||
title: 'Meetings/Webex Meeting Participant', | ||
component: WebexMeetingParticipant, | ||
decorators: [(Story) => <div style={{width: '20rem'}}><Story /></div>], | ||
}; | ||
|
||
const Template = (args) => <WebexMeetingParticipant {...args} />; | ||
|
||
export const Muted = Template.bind({}); | ||
Muted.args = { | ||
meetingID: 'meeting2', | ||
personID: 'user2', | ||
}; | ||
|
||
export const Host = Template.bind({}); | ||
Host.args = { | ||
meetingID: 'meeting2', | ||
personID: 'user4', | ||
}; | ||
|
||
export const Guest = Template.bind({}); | ||
Guest.args = { | ||
meetingID: 'meeting2', | ||
personID: 'user6', | ||
}; | ||
|
||
export const ScreenSharing = Template.bind({}); | ||
ScreenSharing.args = { | ||
meetingID: 'meeting2', | ||
personID: 'user3', | ||
}; |
Oops, something went wrong.