add Channel Context Menu
This commit is contained in:
parent
7777fb2bb2
commit
f42078853a
111
src/components/ChannelContextMenu.jsx
Normal file
111
src/components/ChannelContextMenu.jsx
Normal 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);
|
|
@ -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>
|
||||||
|
|
||||||
{(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,
|
||||||
|
}));
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -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 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user