add Channel Context Menu

This commit is contained in:
HF 2020-11-25 21:39:43 +01:00
parent 7777fb2bb2
commit f42078853a
5 changed files with 151 additions and 14 deletions

View File

@ -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 (
<div
ref={wrapperRef}
className="contextmenu"
style={{
right: window.innerWidth - xPos,
top: yPos,
}}
>
<div
style={{ borderBottom: 'thin solid' }}
>
Mute
</div>
{(channelArray[2] !== 0)
&& (
<div
role="button"
tabIndex={0}
>
Close
</div>
)}
</div>
);
};
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);

View File

@ -20,6 +20,7 @@ import {
setChatChannel, setChatChannel,
fetchChatMessages, fetchChatMessages,
setChatInputMessage, setChatInputMessage,
showContextMenu,
} from '../actions'; } from '../actions';
import ProtocolClient from '../socket/ProtocolClient'; import ProtocolClient from '../socket/ProtocolClient';
import { saveSelection, restoreSelection } from '../utils/storeSelection'; import { saveSelection, restoreSelection } from '../utils/storeSelection';
@ -43,6 +44,7 @@ const Chat = ({
fetching, fetching,
blocked, blocked,
triggerModal, triggerModal,
openChannelContextMenu,
}) => { }) => {
const listRef = useRef(); const listRef = useRef();
const targetRef = useRef(); const targetRef = useRef();
@ -111,17 +113,19 @@ const Chat = ({
* for whatever reason (left faction etc.) * for whatever reason (left faction etc.)
* set channel to first available one * set channel to first available one
*/ */
let i = 0; useEffect(() => {
while (i < channels.length) { let i = 0;
// eslint-disable-next-line eqeqeq while (i < channels.length) {
if (channels[i][0] == chatChannel) { // eslint-disable-next-line eqeqeq
break; 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 ( return (
<div <div
@ -132,7 +136,6 @@ const Chat = ({
width: '100%', width: '100%',
height: '100%', height: '100%',
flexDirection: 'column', flexDirection: 'column',
height: '100%',
}} }}
> >
<div <div
@ -142,17 +145,29 @@ const Chat = ({
}} }}
> >
<span <span
onClick={(event) => {
const {
clientX,
clientY,
} = event;
openChannelContextMenu(
clientX,
clientY,
chatChannel,
);
}}
role="button" role="button"
tabIndex={-1} tabIndex={-1}
></span> ></span>
&nbsp; &nbsp;
{(showExpand) && {(showExpand)
&& (
<span <span
onClick={triggerModal} onClick={triggerModal}
role="button" role="button"
tabIndex={-1} tabIndex={-1}
></span> ></span>
} )}
</div> </div>
<ul <ul
className="chatarea" className="chatarea"
@ -263,6 +278,11 @@ function mapDispatchToProps(dispatch) {
setInputMessage(message) { setInputMessage(message) {
dispatch(setChatInputMessage(message)); dispatch(setChatInputMessage(message));
}, },
openChannelContextMenu(xPos, yPos, cid) {
dispatch(showContextMenu('CHANNEL', xPos, yPos, {
cid,
}));
},
}; };
} }

View File

@ -40,7 +40,7 @@ function ChatBox({
className={(chatOpen && render) ? 'chatbox show' : 'chatbox'} className={(chatOpen && render) ? 'chatbox show' : 'chatbox'}
onTransitionEnd={onTransitionEnd} onTransitionEnd={onTransitionEnd}
> >
<Chat showExpand={true} /> <Chat showExpand />
</div> </div>
) )
); );

View File

@ -15,10 +15,12 @@ import Palette from './Palette';
import HistorySelect from './HistorySelect'; import HistorySelect from './HistorySelect';
import Mobile3DControls from './Mobile3DControls'; import Mobile3DControls from './Mobile3DControls';
import UserContextMenu from './UserContextMenu'; import UserContextMenu from './UserContextMenu';
import ChannelContextMenu from './ChannelContextMenu';
const CONTEXT_MENUS = { const CONTEXT_MENUS = {
USER: <UserContextMenu />, USER: <UserContextMenu />,
CHANNEL: <ChannelContextMenu />,
/* other context menus */ /* other context menus */
}; };

View File

@ -37,9 +37,11 @@ const UserContextMenu = ({
}; };
document.addEventListener('mousedown', handleClickOutside); document.addEventListener('mousedown', handleClickOutside);
document.addEventListener('touchstart', handleClickOutside); document.addEventListener('touchstart', handleClickOutside);
window.addEventListener('resize', handleClickOutside);
return () => { return () => {
document.removeEventListener('mousedown', handleClickOutside); document.removeEventListener('mousedown', handleClickOutside);
document.removeEventListener('touchstart', handleClickOutside); document.removeEventListener('touchstart', handleClickOutside);
window.removeEventListener('resize', handleClickOutside);
}; };
}, [wrapperRef]); }, [wrapperRef]);
@ -58,6 +60,8 @@ const UserContextMenu = ({
block(uid, name); block(uid, name);
close(); close();
}} }}
role="button"
tabIndex={-1}
> >
Block Block
</div> </div>