2021-02-10 05:57:25 -05:00
|
|
|
import React from 'react'
|
|
|
|
import PropTypes from 'prop-types'
|
|
|
|
import { useTranslation } from 'react-i18next'
|
2024-09-04 03:52:08 -04:00
|
|
|
import { Dropdown as BS3Dropdown, MenuItem } from 'react-bootstrap'
|
|
|
|
import {
|
|
|
|
Dropdown,
|
|
|
|
DropdownHeader,
|
|
|
|
DropdownItem,
|
|
|
|
DropdownMenu,
|
|
|
|
DropdownToggle,
|
|
|
|
} from '@/features/ui/components/bootstrap-5/dropdown-menu'
|
2021-02-10 05:57:25 -05:00
|
|
|
import Icon from '../../../shared/components/icon'
|
2021-05-18 09:43:36 -04:00
|
|
|
import { getHueForUserId } from '../../../shared/utils/colors'
|
2021-06-18 05:29:06 -04:00
|
|
|
import ControlledDropdown from '../../../shared/components/controlled-dropdown'
|
2024-09-04 03:52:08 -04:00
|
|
|
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
|
|
|
|
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
|
|
|
|
import MaterialIcon from '@/shared/components/material-icon'
|
2021-02-10 05:57:25 -05:00
|
|
|
|
|
|
|
function OnlineUsersWidget({ onlineUsers, goToUser }) {
|
|
|
|
const { t } = useTranslation()
|
|
|
|
|
|
|
|
const shouldDisplayDropdown = onlineUsers.length >= 4
|
|
|
|
|
|
|
|
if (shouldDisplayDropdown) {
|
|
|
|
return (
|
2024-09-04 03:52:08 -04:00
|
|
|
<BootstrapVersionSwitcher
|
|
|
|
bs3={
|
|
|
|
<ControlledDropdown
|
|
|
|
id="online-users"
|
|
|
|
className="online-users"
|
|
|
|
pullRight
|
|
|
|
>
|
|
|
|
<DropDownToggleButton
|
|
|
|
bsRole="toggle"
|
|
|
|
onlineUserCount={onlineUsers.length}
|
|
|
|
/>
|
|
|
|
<BS3Dropdown.Menu>
|
|
|
|
<MenuItem header>{t('connected_users')}</MenuItem>
|
|
|
|
{onlineUsers.map((user, index) => (
|
|
|
|
<MenuItem
|
|
|
|
as="button"
|
|
|
|
key={`${user.user_id}_${index}`}
|
|
|
|
eventKey={user}
|
|
|
|
onSelect={goToUser}
|
|
|
|
>
|
|
|
|
<UserIcon user={user} showName />
|
|
|
|
</MenuItem>
|
|
|
|
))}
|
|
|
|
</BS3Dropdown.Menu>
|
|
|
|
</ControlledDropdown>
|
|
|
|
}
|
|
|
|
bs5={
|
|
|
|
<Dropdown id="online-users" className="online-users" align="end">
|
|
|
|
<DropdownToggle
|
|
|
|
as={DropDownToggleButton}
|
|
|
|
onlineUserCount={onlineUsers.length}
|
|
|
|
/>
|
|
|
|
<DropdownMenu>
|
|
|
|
<DropdownHeader aria-hidden="true">
|
|
|
|
{t('connected_users')}
|
|
|
|
</DropdownHeader>
|
|
|
|
{onlineUsers.map((user, index) => (
|
|
|
|
<li role="none" key={`${user.user_id}_${index}`}>
|
|
|
|
<DropdownItem
|
|
|
|
as="button"
|
|
|
|
tabIndex={-1}
|
|
|
|
onClick={() => goToUser(user)}
|
|
|
|
>
|
|
|
|
<UserIcon user={user} showName />
|
|
|
|
</DropdownItem>
|
|
|
|
</li>
|
|
|
|
))}
|
|
|
|
</DropdownMenu>
|
|
|
|
</Dropdown>
|
|
|
|
}
|
|
|
|
/>
|
2021-02-10 05:57:25 -05:00
|
|
|
)
|
|
|
|
} else {
|
|
|
|
return (
|
|
|
|
<div className="online-users">
|
2021-06-30 07:03:13 -04:00
|
|
|
{onlineUsers.map((user, index) => (
|
2024-09-04 03:52:08 -04:00
|
|
|
<OLTooltip
|
2021-06-30 07:03:13 -04:00
|
|
|
key={`${user.user_id}_${index}`}
|
2022-05-18 09:46:10 -04:00
|
|
|
id="online-user"
|
|
|
|
description={user.name}
|
|
|
|
overlayProps={{ placement: 'bottom', trigger: ['hover', 'focus'] }}
|
2021-02-10 05:57:25 -05:00
|
|
|
>
|
|
|
|
<span>
|
|
|
|
{/* OverlayTrigger won't fire unless UserIcon is wrapped in a span */}
|
|
|
|
<UserIcon user={user} onClick={goToUser} />
|
|
|
|
</span>
|
2024-09-04 03:52:08 -04:00
|
|
|
</OLTooltip>
|
2021-02-10 05:57:25 -05:00
|
|
|
))}
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
OnlineUsersWidget.propTypes = {
|
|
|
|
onlineUsers: PropTypes.arrayOf(
|
|
|
|
PropTypes.shape({
|
|
|
|
user_id: PropTypes.string.isRequired,
|
2021-04-27 03:52:58 -04:00
|
|
|
name: PropTypes.string.isRequired,
|
2021-02-10 05:57:25 -05:00
|
|
|
})
|
|
|
|
).isRequired,
|
2021-04-27 03:52:58 -04:00
|
|
|
goToUser: PropTypes.func.isRequired,
|
2021-02-10 05:57:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
function UserIcon({ user, showName, onClick }) {
|
2021-05-18 09:43:36 -04:00
|
|
|
const backgroundColor = `hsl(${getHueForUserId(user.user_id)}, 70%, 50%)`
|
2021-02-10 05:57:25 -05:00
|
|
|
|
|
|
|
function handleOnClick() {
|
2024-09-04 03:52:08 -04:00
|
|
|
onClick?.(user)
|
2021-02-10 05:57:25 -05:00
|
|
|
}
|
|
|
|
|
2023-06-15 05:30:25 -04:00
|
|
|
const [character] = [...user.name]
|
|
|
|
|
2021-02-10 05:57:25 -05:00
|
|
|
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 }}>
|
2023-06-15 05:30:25 -04:00
|
|
|
{character}
|
2021-02-10 05:57:25 -05:00
|
|
|
</span>
|
|
|
|
{showName && user.name}
|
|
|
|
</span>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
UserIcon.propTypes = {
|
|
|
|
user: PropTypes.shape({
|
|
|
|
user_id: PropTypes.string.isRequired,
|
2021-04-27 03:52:58 -04:00
|
|
|
name: PropTypes.string.isRequired,
|
2021-02-10 05:57:25 -05:00
|
|
|
}),
|
|
|
|
showName: PropTypes.bool,
|
2024-09-04 03:52:08 -04:00
|
|
|
onClick: PropTypes.func,
|
2021-02-10 05:57:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
const DropDownToggleButton = React.forwardRef((props, ref) => {
|
|
|
|
const { t } = useTranslation()
|
|
|
|
return (
|
2024-09-04 03:52:08 -04:00
|
|
|
<OLTooltip
|
2022-05-18 09:46:10 -04:00
|
|
|
id="connected-users"
|
|
|
|
description={t('connected_users')}
|
|
|
|
overlayProps={{ placement: 'left' }}
|
2021-02-10 05:57:25 -05:00
|
|
|
>
|
|
|
|
<button
|
2024-09-04 03:52:08 -04:00
|
|
|
type="button"
|
|
|
|
className="online-user online-user-multi"
|
2021-02-10 05:57:25 -05:00
|
|
|
onClick={props.onClick} // required by Bootstrap Dropdown to trigger an opening
|
2024-09-04 03:52:08 -04:00
|
|
|
ref={ref}
|
2021-02-10 05:57:25 -05:00
|
|
|
>
|
2024-09-04 03:52:08 -04:00
|
|
|
<strong>{props.onlineUserCount}</strong>
|
|
|
|
<BootstrapVersionSwitcher
|
|
|
|
bs3={<Icon type="users" fw />}
|
|
|
|
bs5={<MaterialIcon type="groups" />}
|
|
|
|
/>
|
2021-02-10 05:57:25 -05:00
|
|
|
</button>
|
2024-09-04 03:52:08 -04:00
|
|
|
</OLTooltip>
|
2021-02-10 05:57:25 -05:00
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-05-13 06:21:35 -04:00
|
|
|
DropDownToggleButton.displayName = 'DropDownToggleButton'
|
|
|
|
|
2021-02-10 05:57:25 -05:00
|
|
|
DropDownToggleButton.propTypes = {
|
|
|
|
onlineUserCount: PropTypes.number.isRequired,
|
2021-04-27 03:52:58 -04:00
|
|
|
onClick: PropTypes.func,
|
2021-02-10 05:57:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
export default OnlineUsersWidget
|