diff --git a/src/components/ChannelContextMenu.jsx b/src/components/ChannelContextMenu.jsx new file mode 100644 index 0000000..30a9c66 --- /dev/null +++ b/src/components/ChannelContextMenu.jsx @@ -0,0 +1,111 @@ +/* + * + * @flow + */ + +import React, { + useRef, useEffect, useState, useLayoutEffect, +} from 'react'; +import { connect } from 'react-redux'; + +import { + hideContextMenu, +} from '../actions'; +import type { State } from '../reducers'; + +const UserContextMenu = ({ + xPos, + yPos, + cid, + channels, + close, +}) => { + const wrapperRef = useRef(null); + const [channelArray, setChannelArray] = useState([]); + + useEffect(() => { + const handleClickOutside = (event) => { + if (wrapperRef.current && !wrapperRef.current.contains(event.target)) { + close(); + } + }; + document.addEventListener('mousedown', handleClickOutside); + document.addEventListener('touchstart', handleClickOutside); + window.addEventListener('resize', handleClickOutside); + return () => { + document.removeEventListener('mousedown', handleClickOutside); + document.removeEventListener('touchstart', handleClickOutside); + window.removeEventListener('resize', handleClickOutside); + }; + }, [wrapperRef]); + + useLayoutEffect(() => { + for (let i = 0; i < channels.length; i += 1) { + const chan = channels[i]; + /* + * [cid, name, type, lastMessage] + */ + // eslint-disable-next-line eqeqeq + if (chan[0] == cid) { + setChannelArray(chan); + break; + } + } + }, [channels.length]); + + return ( +
+
+ ✔✘ Mute +
+ {(channelArray[2] !== 0) + && ( +
+ Close +
+ )} +
+ ); +}; + +function mapStateToProps(state: State) { + const { + xPos, + yPos, + args, + } = state.contextMenu; + const { + channels, + } = state.chat; + const { + cid, + } = args; + return { + xPos, + yPos, + cid, + channels, + }; +} + +function mapDispatchToProps(dispatch) { + return { + close() { + dispatch(hideContextMenu()); + }, + }; +} + +export default connect(mapStateToProps, mapDispatchToProps)(UserContextMenu); diff --git a/src/components/Chat.jsx b/src/components/Chat.jsx index 72b08e4..607c4dc 100644 --- a/src/components/Chat.jsx +++ b/src/components/Chat.jsx @@ -20,6 +20,7 @@ import { setChatChannel, fetchChatMessages, setChatInputMessage, + showContextMenu, } from '../actions'; import ProtocolClient from '../socket/ProtocolClient'; import { saveSelection, restoreSelection } from '../utils/storeSelection'; @@ -43,6 +44,7 @@ const Chat = ({ fetching, blocked, triggerModal, + openChannelContextMenu, }) => { const listRef = useRef(); const targetRef = useRef(); @@ -111,17 +113,19 @@ const Chat = ({ * for whatever reason (left faction etc.) * set channel to first available one */ - let i = 0; - while (i < channels.length) { - // eslint-disable-next-line eqeqeq - if (channels[i][0] == chatChannel) { - break; + useEffect(() => { + let i = 0; + while (i < channels.length) { + // eslint-disable-next-line eqeqeq + if (channels[i][0] == chatChannel) { + break; + } + i += 1; } - i += 1; - } - if (i && i === channels.length) { - setChannel(channels[0][0]); - } + if (i && i === channels.length) { + setChannel(channels[0][0]); + } + }, [chatChannel, channels]); return (
{ + const { + clientX, + clientY, + } = event; + openChannelContextMenu( + clientX, + clientY, + chatChannel, + ); + }} role="button" tabIndex={-1} >⚙   - {(showExpand) && + {(showExpand) + && ( - } + )}
) ); diff --git a/src/components/UI.jsx b/src/components/UI.jsx index 43c0803..2320d68 100644 --- a/src/components/UI.jsx +++ b/src/components/UI.jsx @@ -15,10 +15,12 @@ import Palette from './Palette'; import HistorySelect from './HistorySelect'; import Mobile3DControls from './Mobile3DControls'; import UserContextMenu from './UserContextMenu'; +import ChannelContextMenu from './ChannelContextMenu'; const CONTEXT_MENUS = { USER: , + CHANNEL: , /* other context menus */ }; diff --git a/src/components/UserContextMenu.jsx b/src/components/UserContextMenu.jsx index 5da6fa7..f89fc7d 100644 --- a/src/components/UserContextMenu.jsx +++ b/src/components/UserContextMenu.jsx @@ -37,9 +37,11 @@ const UserContextMenu = ({ }; document.addEventListener('mousedown', handleClickOutside); document.addEventListener('touchstart', handleClickOutside); + window.addEventListener('resize', handleClickOutside); return () => { document.removeEventListener('mousedown', handleClickOutside); document.removeEventListener('touchstart', handleClickOutside); + window.removeEventListener('resize', handleClickOutside); }; }, [wrapperRef]); @@ -58,6 +60,8 @@ const UserContextMenu = ({ block(uid, name); close(); }} + role="button" + tabIndex={-1} > Block