From 05807809aa23ea2fa566f19f081cdfe2c2b5da69 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Tue, 23 Jul 2024 10:19:11 +0530 Subject: [PATCH] refactor: click & confirmation logic --- src/components/atoms/canvas.tsx | 155 +++++++++++++++++++------------- 1 file changed, 92 insertions(+), 63 deletions(-) diff --git a/src/components/atoms/canvas.tsx b/src/components/atoms/canvas.tsx index ff438669..c9a9ca5a 100644 --- a/src/components/atoms/canvas.tsx +++ b/src/components/atoms/canvas.tsx @@ -1,7 +1,9 @@ -import React, { useCallback, useEffect, useRef } from 'react'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; import { useSocketStore } from '../../context/socket'; import { getMappedCoordinates } from "../../helpers/inputHelpers"; import { useGlobalInfoStore } from "../../context/globalInfo"; +import { GenericModal } from '../atoms/GenericModal'; +import { Box, Button, Typography } from '@mui/material'; interface CreateRefCallback { (ref: React.RefObject): void; @@ -11,61 +13,54 @@ interface CanvasProps { width: number; height: number; onCreateRef: CreateRefCallback; - isClickConfirmed: boolean; - resetClickConfirmation: () => void; + highlighterData: { rect: DOMRect, selector: string } | null; } -/** - * Interface for mouse's x,y coordinates - */ export interface Coordinates { x: number; y: number; +} + +const ConfirmationBox = ({ selector, onYes, onNo }: { selector: string; onYes: () => void; onNo: () => void }) => { + return ( + + + Confirmation + + + Do you want to interact with the element: {selector}? + + + + + + + ); }; -const Canvas = ({ width, height, onCreateRef, isClickConfirmed, resetClickConfirmation }: CanvasProps) => { - +const Canvas = ({ width, height, onCreateRef, highlighterData }: CanvasProps) => { const canvasRef = useRef(null); const { socket } = useSocketStore(); - const { setLastAction, lastAction } = useGlobalInfoStore(); - - const notifyLastAction = (action: string) => { - if (lastAction !== action) { - setLastAction(action); - } - }; + const { setLastAction } = useGlobalInfoStore(); + const [showConfirmation, setShowConfirmation] = useState(false); + const [pendingClick, setPendingClick] = useState(null); const lastMousePosition = useRef({ x: 0, y: 0 }); - //const lastWheelPosition = useRef({ deltaX: 0, deltaY: 0 }); const onMouseEvent = useCallback((event: MouseEvent) => { if (socket) { - const coordinates = { - x: event.clientX, - y: event.clientY, - } + const coordinates = getMappedCoordinates(event, canvasRef.current, width, height); switch (event.type) { - case 'mousedown': - const clickCoordinates = getMappedCoordinates(event, canvasRef.current, width, height); - if (isClickConfirmed) { - socket.emit('input:mousedown', clickCoordinates); - notifyLastAction('click'); - resetClickConfirmation(); - } - break; case 'mousemove': - const coordinates = getMappedCoordinates(event, canvasRef.current, width, height); if (lastMousePosition.current.x !== coordinates.x || lastMousePosition.current.y !== coordinates.y) { - lastMousePosition.current = { - x: coordinates.x, - y: coordinates.y, - }; - socket.emit('input:mousemove', { - x: coordinates.x, - y: coordinates.y, - }); - notifyLastAction('move'); + lastMousePosition.current = coordinates; + socket.emit('input:mousemove', coordinates); + setLastAction('move'); } break; case 'wheel': @@ -75,37 +70,64 @@ const Canvas = ({ width, height, onCreateRef, isClickConfirmed, resetClickConfir deltaY: Math.round(wheelEvent.deltaY), }; socket.emit('input:wheel', deltas); - notifyLastAction('scroll'); + setLastAction('scroll'); break; - default: - console.log('Default mouseEvent registered'); - return; } } - }, [socket]); + }, [socket, width, height, setLastAction]); const onKeyboardEvent = useCallback((event: KeyboardEvent) => { if (socket) { switch (event.type) { case 'keydown': socket.emit('input:keydown', { key: event.key, coordinates: lastMousePosition.current }); - notifyLastAction(`${event.key} pressed`); + setLastAction(`${event.key} pressed`); break; case 'keyup': socket.emit('input:keyup', event.key); break; - default: - console.log('Default keyEvent registered'); - return; } } - }, [socket]); + }, [socket, setLastAction]); + const handleCanvasClick = useCallback((event: MouseEvent) => { + if (canvasRef.current && highlighterData) { + const canvasRect = canvasRef.current.getBoundingClientRect(); + const clickX = event.clientX - canvasRect.left; + const clickY = event.clientY - canvasRect.top; + + const highlightRect = highlighterData.rect; + if ( + clickX >= highlightRect.left && + clickX <= highlightRect.right && + clickY >= highlightRect.top && + clickY <= highlightRect.bottom + ) { + setPendingClick({ x: clickX, y: clickY }); + setShowConfirmation(true); + } + } + }, [highlighterData]); + + const handleConfirmation = (confirmed: boolean) => { + if (confirmed && pendingClick && socket && canvasRef.current) { + const mappedCoordinates = getMappedCoordinates( + { clientX: pendingClick.x, clientY: pendingClick.y } as MouseEvent, + canvasRef.current, + width, + height + ); + socket.emit('input:mousedown', mappedCoordinates); + setLastAction('click'); + } + setShowConfirmation(false); + setPendingClick(null); + }; useEffect(() => { if (canvasRef.current) { onCreateRef(canvasRef); - canvasRef.current.addEventListener('mousedown', onMouseEvent); + canvasRef.current.addEventListener('click', handleCanvasClick); canvasRef.current.addEventListener('mousemove', onMouseEvent); canvasRef.current.addEventListener('wheel', onMouseEvent, { passive: true }); canvasRef.current.addEventListener('keydown', onKeyboardEvent); @@ -113,30 +135,37 @@ const Canvas = ({ width, height, onCreateRef, isClickConfirmed, resetClickConfir return () => { if (canvasRef.current) { - canvasRef.current.removeEventListener('mousedown', onMouseEvent); + canvasRef.current.removeEventListener('click', handleCanvasClick); canvasRef.current.removeEventListener('mousemove', onMouseEvent); canvasRef.current.removeEventListener('wheel', onMouseEvent); canvasRef.current.removeEventListener('keydown', onKeyboardEvent); canvasRef.current.removeEventListener('keyup', onKeyboardEvent); } - }; - } else { - console.log('Canvas not initialized'); } - - }, [onMouseEvent]); + }, [onMouseEvent, onKeyboardEvent, handleCanvasClick, onCreateRef]); return ( - + <> + setShowConfirmation(false)} + canBeClosed={false} + > + handleConfirmation(true)} + onNo={() => handleConfirmation(false)} + /> + + + ); - }; - export default Canvas; \ No newline at end of file