feat: update context menu to use references
This commit is contained in:
		@@ -1,4 +1,4 @@
 | 
				
			|||||||
import { MouseEventHandler, useEffect, useState } from "react";
 | 
					import { createRef, MouseEventHandler, useEffect, useState } from "react";
 | 
				
			||||||
import { useSession } from "./Session";
 | 
					import { useSession } from "./Session";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface ContextMenuItem {
 | 
					interface ContextMenuItem {
 | 
				
			||||||
@@ -13,11 +13,12 @@ export default function Avatar() {
 | 
				
			|||||||
    mouseX: number;
 | 
					    mouseX: number;
 | 
				
			||||||
    mouseY: number;
 | 
					    mouseY: number;
 | 
				
			||||||
  }>({ open: false, mouseX: 0, mouseY: 0 });
 | 
					  }>({ open: false, mouseX: 0, mouseY: 0 });
 | 
				
			||||||
 | 
					  const contextMenuRef = createRef<HTMLUListElement>();
 | 
				
			||||||
 | 
					  const avatarRef = createRef<HTMLDivElement>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const contextMenuItems: ContextMenuItem[] = [
 | 
					  const contextMenuItems: ContextMenuItem[] = [
 | 
				
			||||||
    { label: "View Profile", onClick: () => console.log("View Profile") },
 | 
					    { label: "View Profile", onClick: handleViewProfile },
 | 
				
			||||||
    { label: "Edit Profile", onClick: () => console.log("Edit Profile") },
 | 
					    { label: "Logout", onClick: onLogout },
 | 
				
			||||||
    { label: "Logout", onClick: () => onLogout() },
 | 
					 | 
				
			||||||
  ];
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const handleMenuClick: MouseEventHandler<HTMLDivElement> = (event) => {
 | 
					  const handleMenuClick: MouseEventHandler<HTMLDivElement> = (event) => {
 | 
				
			||||||
@@ -40,29 +41,43 @@ export default function Avatar() {
 | 
				
			|||||||
  const handleMenuClose = () => {
 | 
					  const handleMenuClose = () => {
 | 
				
			||||||
    setContextMenu({ ...contextMenu, open: false });
 | 
					    setContextMenu({ ...contextMenu, open: false });
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  const handleCloseContextMenuOutside: MouseEventHandler<Document> = (
 | 
					  const handleCloseContextMenuOutside: (event: MouseEvent) => void = (ev) => {
 | 
				
			||||||
    event
 | 
					 | 
				
			||||||
  ) => {
 | 
					 | 
				
			||||||
    if (
 | 
					    if (
 | 
				
			||||||
      !event.target ||
 | 
					      !(
 | 
				
			||||||
      (!(event.target as Element).closest(".context-menu") &&
 | 
					        contextMenuRef.current?.contains(ev.target as Node) ||
 | 
				
			||||||
        !(event.target as Element).closest(".avatar"))
 | 
					        avatarRef.current?.contains(ev.target as Node)
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
      handleMenuClose();
 | 
					      handleMenuClose();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const [dialog, setDialog] = useState(<></>);
 | 
				
			||||||
 | 
					  const dialogRef = createRef<HTMLDialogElement>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function handleViewProfile() {
 | 
				
			||||||
 | 
					    handleMenuClose();
 | 
				
			||||||
 | 
					    dialogRef.current?.showModal();
 | 
				
			||||||
 | 
					    setDialog(
 | 
				
			||||||
 | 
					      <ul>
 | 
				
			||||||
 | 
					        <li>username: {user?.username}</li>
 | 
				
			||||||
 | 
					      </ul>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div
 | 
					    <div
 | 
				
			||||||
      className="avatar"
 | 
					      className="avatar"
 | 
				
			||||||
      onContextMenu={handleMenuClick}
 | 
					      onContextMenu={handleMenuClick}
 | 
				
			||||||
      style={{ display: user ? "block" : "none" }}
 | 
					      style={{ display: user ? "block" : "none" }}
 | 
				
			||||||
      onClick={handleMenuClick}
 | 
					      onClick={handleMenuClick}
 | 
				
			||||||
 | 
					      ref={avatarRef}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      {user?.username}
 | 
					      👤 {user?.username}
 | 
				
			||||||
      {contextMenu.open && (
 | 
					      {contextMenu.open && (
 | 
				
			||||||
        <ul
 | 
					        <ul
 | 
				
			||||||
          className="context-menu"
 | 
					          className="context-menu"
 | 
				
			||||||
 | 
					          ref={contextMenuRef}
 | 
				
			||||||
          style={{
 | 
					          style={{
 | 
				
			||||||
            zIndex: 3,
 | 
					            zIndex: 3,
 | 
				
			||||||
            position: "absolute",
 | 
					            position: "absolute",
 | 
				
			||||||
@@ -93,6 +108,15 @@ export default function Avatar() {
 | 
				
			|||||||
          ))}
 | 
					          ))}
 | 
				
			||||||
        </ul>
 | 
					        </ul>
 | 
				
			||||||
      )}
 | 
					      )}
 | 
				
			||||||
 | 
					      <dialog
 | 
				
			||||||
 | 
					        id="AvatarDialog"
 | 
				
			||||||
 | 
					        ref={dialogRef}
 | 
				
			||||||
 | 
					        onClick={(event) => {
 | 
				
			||||||
 | 
					          event.currentTarget.close();
 | 
				
			||||||
 | 
					        }}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        {dialog}
 | 
				
			||||||
 | 
					      </dialog>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user