overleaf/services/web/frontend/js/features/editor-navigation-toolbar/components/online-users-widget.js
Alf Eaton 1be43911b4 Merge pull request #3942 from overleaf/prettier-trailing-comma
Set Prettier's "trailingComma" setting to "es5"

GitOrigin-RevId: 9f14150511929a855b27467ad17be6ab262fe5d5
2021-04-28 02:10:01 +00:00

120 lines
3.3 KiB
JavaScript

import React from 'react'
import PropTypes from 'prop-types'
import { useTranslation } from 'react-i18next'
import { Dropdown, MenuItem, OverlayTrigger, Tooltip } from 'react-bootstrap'
import Icon from '../../../shared/components/icon'
import ColorManager from '../../../ide/colors/ColorManager'
function OnlineUsersWidget({ onlineUsers, goToUser }) {
const { t } = useTranslation()
const shouldDisplayDropdown = onlineUsers.length >= 4
if (shouldDisplayDropdown) {
return (
<Dropdown id="online-users" className="online-users" pullRight>
<DropDownToggleButton
bsRole="toggle"
onlineUserCount={onlineUsers.length}
/>
<Dropdown.Menu>
<MenuItem header>{t('connected_users')}</MenuItem>
{onlineUsers.map(user => (
<MenuItem
as="button"
key={user.user_id}
eventKey={user}
onSelect={goToUser}
>
<UserIcon user={user} onClick={goToUser} showName />
</MenuItem>
))}
</Dropdown.Menu>
</Dropdown>
)
} else {
return (
<div className="online-users">
{onlineUsers.map(user => (
<OverlayTrigger
key={user.user_id}
placement="bottom"
trigger={['hover', 'focus']}
overlay={<Tooltip id="tooltip-online-user">{user.name}</Tooltip>}
>
<span>
{/* OverlayTrigger won't fire unless UserIcon is wrapped in a span */}
<UserIcon user={user} onClick={goToUser} />
</span>
</OverlayTrigger>
))}
</div>
)
}
}
OnlineUsersWidget.propTypes = {
onlineUsers: PropTypes.arrayOf(
PropTypes.shape({
user_id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
})
).isRequired,
goToUser: PropTypes.func.isRequired,
}
function UserIcon({ user, showName, onClick }) {
const backgroundColor = `hsl(${ColorManager.getHueForUserId(
user.user_id
)}, 70%, 50%)`
function handleOnClick() {
onClick(user)
}
return (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
<span onClick={handleOnClick}>
<span className="online-user" style={{ backgroundColor }}>
{user.name.slice(0, 1)}
</span>
{showName && user.name}
</span>
)
}
UserIcon.propTypes = {
user: PropTypes.shape({
user_id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
}),
showName: PropTypes.bool,
onClick: PropTypes.func.isRequired,
}
const DropDownToggleButton = React.forwardRef((props, ref) => {
const { t } = useTranslation()
return (
<OverlayTrigger
placement="left"
overlay={
<Tooltip id="tooltip-connected-users">{t('connected_users')}</Tooltip>
}
>
<button
className="btn online-user online-user-multi"
onClick={props.onClick} // required by Bootstrap Dropdown to trigger an opening
>
<strong>{props.onlineUserCount}</strong>
<Icon type="users" modifier="fw" />
</button>
</OverlayTrigger>
)
})
DropDownToggleButton.propTypes = {
onlineUserCount: PropTypes.number.isRequired,
onClick: PropTypes.func,
}
export default OnlineUsersWidget