diff --git a/src/app/atoms/context-menu/ContextMenu.jsx b/src/app/atoms/context-menu/ContextMenu.jsx index 50894b5d..b525e22e 100644 --- a/src/app/atoms/context-menu/ContextMenu.jsx +++ b/src/app/atoms/context-menu/ContextMenu.jsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import './ContextMenu.scss'; @@ -10,12 +10,16 @@ import Button from '../button/Button'; import ScrollView from '../scroll/ScrollView'; function ContextMenu({ - content, placement, maxWidth, render, + content, placement, maxWidth, render, afterToggle, }) { const [isVisible, setVisibility] = useState(false); const showMenu = () => setVisibility(true); const hideMenu = () => setVisibility(false); + useEffect(() => { + if (afterToggle !== null) afterToggle(isVisible); + }, [isVisible]); + return ( }
- - )} - render={(toggleMenu) => } + { + openEmojiBoard({ + x: e.detail ? e.clientX + 40 : '10%', + y: e.detail ? e.clientY - 240 : 300, + isReverse: !e.detail, + detail: e.detail, + }, addEmoji); + }} + tooltip="Emoji" + src={EmojiIC} />
diff --git a/src/app/organisms/emoji-board/EmojiBoardOpener.jsx b/src/app/organisms/emoji-board/EmojiBoardOpener.jsx new file mode 100644 index 00000000..c9b81e94 --- /dev/null +++ b/src/app/organisms/emoji-board/EmojiBoardOpener.jsx @@ -0,0 +1,79 @@ +import React, { useEffect, useRef } from 'react'; + +import cons from '../../../client/state/cons'; +import navigation from '../../../client/state/navigation'; + +import ContextMenu from '../../atoms/context-menu/ContextMenu'; +import EmojiBoard from './EmojiBoard'; + +let requestCallback = null; +function EmojiBoardOpener() { + const openerRef = useRef(null); + + function openEmojiBoard(cords, requestEmojiCallback) { + console.log(requestCallback); + if (requestCallback !== null) { + requestCallback = null; + if (cords.detail === 0) openerRef.current.click(); + return; + } + + const x = typeof cords.x === 'string' ? cords.x : `${cords.x}px`; + const y = typeof cords.y === 'string' ? cords.y : `${cords.y}px`; + + openerRef.current.style.left = cords.isReverse ? 'unset' : x; + openerRef.current.style.top = cords.isReverse ? 'unset' : y; + openerRef.current.style.right = cords.isReverse ? x : 'unset'; + openerRef.current.style.bottom = cords.isReverse ? y : 'unset'; + requestCallback = requestEmojiCallback; + openerRef.current.click(); + } + + function afterEmojiBoardToggle(isVisible) { + console.log(isVisible); + if (!isVisible) { + setTimeout(() => { + requestCallback = null; + }, 500); + } + } + + function addEmoji(emoji) { + requestCallback(emoji); + } + + useEffect(() => { + navigation.on(cons.events.navigation.EMOJIBOARD_OPENED, openEmojiBoard); + return () => { + navigation.removeListener(cons.events.navigation.EMOJIBOARD_OPENED, openEmojiBoard); + }; + }, []); + + return ( + + )} + afterToggle={afterEmojiBoardToggle} + render={(toggleMenu, isVisible) => ( + + )} + /> + ); +} + +export default EmojiBoardOpener; diff --git a/src/app/templates/client/Client.jsx b/src/app/templates/client/Client.jsx index 9c840319..9705c4a5 100644 --- a/src/app/templates/client/Client.jsx +++ b/src/app/templates/client/Client.jsx @@ -6,6 +6,7 @@ import Spinner from '../../atoms/spinner/Spinner'; import Navigation from '../../organisms/navigation/Navigation'; import Channel from '../../organisms/channel/Channel'; import Windows from '../../organisms/pw/Windows'; +import EmojiBoardOpener from '../../organisms/emoji-board/EmojiBoardOpener'; import initMatrix from '../../../client/initMatrix'; @@ -40,6 +41,7 @@ function Client() { + ); } diff --git a/src/client/action/navigation.js b/src/client/action/navigation.js index 79bde0a0..a9032f23 100644 --- a/src/client/action/navigation.js +++ b/src/client/action/navigation.js @@ -54,6 +54,14 @@ function openSettings() { }); } +function openEmojiBoard(cords, requestEmojiCallback) { + appDispatcher.dispatch({ + type: cons.actions.navigation.OPEN_EMOJIBOARD, + cords, + requestEmojiCallback, + }); +} + export { handleTabChange, selectRoom, @@ -63,4 +71,5 @@ export { openCreateChannel, openInviteUser, openSettings, + openEmojiBoard, }; diff --git a/src/client/state/cons.js b/src/client/state/cons.js index 9b30031f..d762e07c 100644 --- a/src/client/state/cons.js +++ b/src/client/state/cons.js @@ -16,6 +16,7 @@ const cons = { OPEN_CREATE_CHANNEL: 'OPEN_CREATE_CHANNEL', OPEN_INVITE_USER: 'OPEN_INVITE_USER', OPEN_SETTINGS: 'OPEN_SETTINGS', + OPEN_EMOJIBOARD: 'OPEN_EMOJIBOARD', }, room: { JOIN: 'JOIN', @@ -39,6 +40,7 @@ const cons = { CREATE_CHANNEL_OPENED: 'CREATE_CHANNEL_OPENED', INVITE_USER_OPENED: 'INVITE_USER_OPENED', SETTINGS_OPENED: 'SETTINGS_OPENED', + EMOJIBOARD_OPENED: 'EMOJIBOARD_OPENED', }, roomList: { ROOMLIST_UPDATED: 'ROOMLIST_UPDATED', diff --git a/src/client/state/navigation.js b/src/client/state/navigation.js index af89cd9f..c7984020 100644 --- a/src/client/state/navigation.js +++ b/src/client/state/navigation.js @@ -48,6 +48,12 @@ class Navigation extends EventEmitter { [cons.actions.navigation.OPEN_SETTINGS]: () => { this.emit(cons.events.navigation.SETTINGS_OPENED); }, + [cons.actions.navigation.OPEN_EMOJIBOARD]: () => { + this.emit( + cons.events.navigation.EMOJIBOARD_OPENED, + action.cords, action.requestEmojiCallback, + ); + }, }; actions[action.type]?.(); }