-
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 473bc67
Showing
12 changed files
with
600 additions
and
587 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
90 changes: 90 additions & 0 deletions
90
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,90 @@ | ||
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.memberID 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, | ||
memberID, | ||
style, | ||
}) { | ||
const {displayName, orgID, emails} = usePerson(memberID); | ||
const me = useMe(); | ||
const members = useMembers(meetingID, DestinationType.MEETING); | ||
const member = members | ||
.find((itemMember) => itemMember.ID === memberID); | ||
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 === memberID; | ||
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={memberID} 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, | ||
memberID: 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); | ||
} | ||
} |
56 changes: 56 additions & 0 deletions
56
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,56 @@ | ||
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 Space = Template.bind({}); | ||
// Space.args = { | ||
// destinationType: 'room', | ||
// meetingID: 'room1', | ||
// memberID: 'user1', | ||
// }; | ||
|
||
// export const StatusEnabled = Template.bind({}); | ||
// StatusEnabled.args = { | ||
// destinationType: 'room', | ||
// meetingID: 'room1', | ||
// memberID: 'user1', | ||
// displayStatus: true, | ||
// }; | ||
|
||
export const Muted = Template.bind({}); | ||
Muted.args = { | ||
meetingID: 'meeting2', | ||
memberID: 'user2', | ||
}; | ||
|
||
// export const ExternalOrganization = Template.bind({}); | ||
// ExternalOrganization.args = { | ||
// destinationType: 'room', | ||
// meetingID: 'room2', | ||
// memberID: 'user5', | ||
// }; | ||
|
||
export const Host = Template.bind({}); | ||
Host.args = { | ||
meetingID: 'meeting2', | ||
memberID: 'user4', | ||
}; | ||
|
||
export const Guest = Template.bind({}); | ||
Guest.args = { | ||
meetingID: 'meeting2', | ||
memberID: 'user6', | ||
}; | ||
|
||
export const ScreenSharing = Template.bind({}); | ||
ScreenSharing.args = { | ||
meetingID: 'meeting2', | ||
memberID: 'user3', | ||
}; |
Oops, something went wrong.