import { h, Component, createRef } from '/js/web_modules/preact.js'; import htm from '/js/web_modules/htm.js'; import { textColorForHue } from '../../utils/user-colors.js'; import { URL_BAN_USER, URL_HIDE_MESSAGE } from '../../utils/constants.js'; const html = htm.bind(h); const HIDE_MESSAGE_ICON = `/img/hide-message-grey.svg`; const HIDE_MESSAGE_ICON_HOVER = '/img/hide-message.svg'; const BAN_USER_ICON = '/img/ban-user-grey.svg'; const BAN_USER_ICON_HOVER = '/img/ban-user.svg'; export default class ModeratorActions extends Component { constructor(props) { super(props); this.state = { isMenuOpen: false, }; this.handleOpenMenu = this.handleOpenMenu.bind(this); this.handleCloseMenu = this.handleCloseMenu.bind(this); } handleOpenMenu() { this.setState({ isMenuOpen: true, }); } handleCloseMenu() { this.setState({ isMenuOpen: false, }); } render() { const { isMenuOpen } = this.state; const { message, accessToken } = this.props; const { id } = message; const { user } = message; return html`
${isMenuOpen && html`<${ModeratorMenu} message=${message} onDismiss=${this.handleCloseMenu} accessToken=${accessToken} id=${id} userId=${user.id} />`}
`; } } class ModeratorMenu extends Component { constructor(props) { super(props); this.menuNode = createRef(); this.state = { displayMoreInfo: false, }; this.handleClickOutside = this.handleClickOutside.bind(this); this.handleToggleMoreInfo = this.handleToggleMoreInfo.bind(this); this.handleBanUser = this.handleBanUser.bind(this); this.handleHideMessage = this.handleHideMessage.bind(this); } componentDidMount() { document.addEventListener('mousedown', this.handleClickOutside, false); } componentWillUnmount() { document.removeEventListener('mousedown', this.handleClickOutside, false); } handleClickOutside = (e) => { if ( this.menuNode && !this.menuNode.current.contains(e.target) && this.props.onDismiss ) { this.props.onDismiss(); } }; handleToggleMoreInfo() { this.setState({ displayMoreInfo: !this.state.displayMoreInfo, }); } async handleHideMessage() { if (!confirm('Are you sure you want to remove this message from chat?')) { this.props.onDismiss(); return; } const { accessToken, id } = this.props; const url = new URL(location.origin + URL_HIDE_MESSAGE); url.searchParams.append('accessToken', accessToken); const hideMessageUrl = url.toString(); const options = { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ idArray: [id] }), }; try { await fetch(hideMessageUrl, options); } catch (e) { console.error(e); } this.props.onDismiss(); } async handleBanUser() { if (!confirm('Are you sure you want to remove this user from chat?')) { this.props.onDismiss(); return; } const { accessToken, userId } = this.props; const url = new URL(location.origin + URL_BAN_USER); url.searchParams.append('accessToken', accessToken); const hideMessageUrl = url.toString(); const options = { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ userId: userId }), }; try { await fetch(hideMessageUrl, options); } catch (e) { console.error(e); } this.props.onDismiss(); } render() { const { message } = this.props; const { displayMoreInfo } = this.state; return html` `; } } // 3 dots button function ModeratorMenuItem({ icon, hoverIcon, label, onClick }) { return html` `; } // more details panel that display message, prev usernames, actions function ModeratorMoreInfoContainer({ message, handleHideMessage, handleBanUser, }) { const { user, timestamp, body } = message; const { displayName, createdAt, previousNames, displayColor } = user; const isAuthorModerator = user.scopes && user.scopes.contains('MODERATOR'); const authorTextColor = { color: textColorForHue(displayColor) }; const createDate = new Date(createdAt); const sentDate = new Date(timestamp); return html`

Sent at ${sentDate.toLocaleTimeString()}

Sent by:

${displayName}

First joined: ${createDate.toLocaleString()}

${previousNames.length > 1 && html`

Previously known as: ${' '} ${previousNames.join(', ')}

`}
<${handleHideMessage && ModeratorMenuItem} icon=${HIDE_MESSAGE_ICON} hoverIcon=${HIDE_MESSAGE_ICON_HOVER} label="Hide message" onClick="${handleHideMessage}" /> <${handleBanUser && ModeratorMenuItem} icon=${BAN_USER_ICON} hoverIcon=${BAN_USER_ICON_HOVER} label="Ban user" onClick="${handleBanUser}" />
`; }