From e8ca0d0ed4c075f4a3b5e80a1b11ad756fb22736 Mon Sep 17 00:00:00 2001 From: Michael Peters Date: Thu, 30 Dec 2021 21:04:14 -0600 Subject: [PATCH] right click context menu custom effect --- .../lists/components/message-element.scss | 4 +++ .../lists/components/guild-list-element.tsx | 17 +++++------- .../lists/components/message-element.tsx | 18 +++++-------- .../webapp/elements/require/react-helper.tsx | 27 ++++++++++++++++++- 4 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/client/webapp/elements-styles/lists/components/message-element.scss b/src/client/webapp/elements-styles/lists/components/message-element.scss index 8d210f0..20ba54d 100644 --- a/src/client/webapp/elements-styles/lists/components/message-element.scss +++ b/src/client/webapp/elements-styles/lists/components/message-element.scss @@ -5,6 +5,10 @@ padding: 4px 16px; user-select: text; + .context { + user-select: none; + } + &.continued { margin-top: -4px; diff --git a/src/client/webapp/elements/lists/components/guild-list-element.tsx b/src/client/webapp/elements/lists/components/guild-list-element.tsx index 8204787..c8705b1 100644 --- a/src/client/webapp/elements/lists/components/guild-list-element.tsx +++ b/src/client/webapp/elements/lists/components/guild-list-element.tsx @@ -1,11 +1,12 @@ -import React, { FC, MouseEvent, useCallback, useMemo, useRef, useState } from 'react'; +import React, { FC, useCallback, useMemo, useRef } from 'react'; import CombinedGuild from '../../../guild-combined'; import GuildsManager from '../../../guilds-manager'; import ContextMenu from '../../contexts/components/context-menu'; import BasicHover, { BasicHoverSide } from '../../contexts/context-hover-basic'; import BaseElements from '../../require/base-elements'; +import { IAlignment } from '../../require/elements-util'; import GuildSubscriptions from '../../require/guild-subscriptions'; -import ReactHelper from '../../require/react-helper'; +import ReactHelper, { useContextClickContextMenu } from '../../require/react-helper'; export interface GuildListElementProps { guildsManager: GuildsManager; @@ -50,12 +51,10 @@ const GuildListElement: FC = (props: GuildListElementProp await guildsManager.removeGuild(guild); }, [ guildsManager, guild ]) - const [ contextClickPos, setContextClickPos ] = useState<{ x: number, y: number }>({ x: 0, y: 0 }); - const [ contextClickMenu, toggleMenu, closeMenu, openMenu ] = ReactHelper.useContextMenu((close: () => void) => { + const [ contextClickMenu, onContextClick ] = useContextClickContextMenu((alignment: IAlignment, relativeToPos: { x: number, y: number }, close: () => void) => { return (
Leave Guild
@@ -63,10 +62,6 @@ const GuildListElement: FC = (props: GuildListElementProp ) }, [ leaveGuildCallable ]); - const onContextMenu = useCallback((e: MouseEvent) => { - setContextClickPos({ x: e.clientX, y: e.clientY }); - openMenu(); - }, [ openMenu ]); const className = useMemo(() => { return activeGuild && guild.id === activeGuild.id ? 'guild active' : 'guild'; @@ -77,7 +72,7 @@ const GuildListElement: FC = (props: GuildListElementProp
diff --git a/src/client/webapp/elements/lists/components/message-element.tsx b/src/client/webapp/elements/lists/components/message-element.tsx index a986d61..4984ffe 100644 --- a/src/client/webapp/elements/lists/components/message-element.tsx +++ b/src/client/webapp/elements/lists/components/message-element.tsx @@ -1,12 +1,12 @@ import moment from 'moment'; -import React, { Dispatch, FC, MouseEvent, ReactNode, SetStateAction, useCallback, useMemo, useState } from 'react'; +import React, { Dispatch, FC, ReactNode, SetStateAction, useCallback, useMemo } from 'react'; import { Member, Message } from '../../../data-types'; import CombinedGuild from '../../../guild-combined'; import ImageContextMenu from '../../contexts/context-menu-image'; import ImageOverlay from '../../overlays/overlay-image'; -import ElementsUtil from '../../require/elements-util'; +import ElementsUtil, { IAlignment } from '../../require/elements-util'; import GuildSubscriptions from '../../require/guild-subscriptions'; -import ReactHelper from '../../require/react-helper'; +import ReactHelper, { useContextClickContextMenu } from '../../require/react-helper'; interface ResourceElementProps { guild: CombinedGuild; @@ -55,26 +55,20 @@ const PreviewImageElement: FC = (props: PreviewImageEl // TODO: Handle resourceError const [ previewImgSrc, previewResource, previewResourceError ] = GuildSubscriptions.useSoftImageSrcResourceSubscription(guild, resourcePreviewId); - const [ relativeToPos, setRelativeToPos ] = useState<{ x: number, y: number }>({ x: 0, y: 0 }); - const [ contextMenu, toggleContextMenu ] = ReactHelper.useContextMenu((close: () => void) => { + const [ contextMenu, onContextMenu ] = useContextClickContextMenu((alignment: IAlignment, relativeToPos: { x: number, y: number }, close: () => void) => { if (!previewResource) return null; return ( - ) - }, [ previewResource, relativeToPos, resourceName ]); + ); + }, [ previewResource, resourceName ]); const openImageOverlay = useCallback(() => { setOverlay( setOverlay(null)} />); }, [ guild, resourceId, resourceName ]); - const onContextMenu = useCallback((event: MouseEvent) => { - setRelativeToPos({ x: event.clientX, y: event.clientY }); - toggleContextMenu(); - }, [ toggleContextMenu ]); - return (
!!contextMenu && !oldIsOpen); }, [ contextMenu ]); const open = useCallback(() => { - setIsOpen(!!contextMenu); + setIsOpen(true); }, [ contextMenu ]); return [ isOpen ? contextMenu : null, toggle, close, open, isOpen ]; @@ -544,3 +544,28 @@ export default class ReactHelper { return [ dropTarget ]; } } + +export function useContextClickContextMenu( + createContextMenu: (alignment: IAlignment, relativeToPos: { x: number, y: number }, close: () => void) => ReactNode, + createContextMenuDeps: DependencyList +): [ + contextMenu: ReactNode, + onContextMenu: (event: React.MouseEvent) => void +] { + const [ relativeToPos, setRelativeToPos ] = useState<{ x: number, y: number }>({ x: 0, y: 0 }); + + const alignment = useMemo(() => ({ top: 'centerY', left: 'centerX' }), []) + + const createContextMenuWithRelativeToPos = useCallback((close: () => void) => { + return createContextMenu(alignment, relativeToPos, close); + }, [ alignment, relativeToPos ]); + + const [ contextMenu, toggle, close, open ] = ReactHelper.useContextMenu(createContextMenuWithRelativeToPos, createContextMenuDeps); + + const onContextMenu = useCallback((event: React.MouseEvent) => { + setRelativeToPos({ x: event.clientX, y: event.clientY }); + open(); + }, [ open ]); + + return [ contextMenu, onContextMenu ]; +}