diff --git a/src/Components/Buttons/CommanderDamage.tsx b/src/Components/Buttons/CommanderDamage.tsx index 156a2d2..e72aa23 100644 --- a/src/Components/Buttons/CommanderDamage.tsx +++ b/src/Components/Buttons/CommanderDamage.tsx @@ -17,6 +17,8 @@ export type RotationButtonProps = TwcComponentProps<'button'> & { $rotation?: number; }; +export const MAX_TAP_MOVE_DISTANCE = 20; + const CommanderDamageContainer = twc.div((props) => [ 'flex flex-grow', props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side @@ -38,7 +40,7 @@ const CommanderDamageTextContainer = twc.div((props) => [ : '', ]); -const PartnerDamageSeperator = twc.div((props) => [ +const PartnerDamageSeparator = twc.div((props) => [ 'bg-black', props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side ? 'w-full h-px' @@ -54,6 +56,7 @@ type CommanderDamageButtonComponentProps = { type InputProps = { opponentIndex: number; isPartner: boolean; + event: React.PointerEvent; }; export const CommanderDamage = ({ @@ -65,6 +68,7 @@ export const CommanderDamage = ({ const timeoutRef = useRef(undefined); const [timeoutFinished, setTimeoutFinished] = useState(false); const [hasPressedDown, setHasPressedDown] = useState(false); + const downPositionRef = useRef({ x: 0, y: 0 }); const handleCommanderDamageChange = ( index: number, @@ -103,7 +107,8 @@ export const CommanderDamage = ({ handleLifeChange(player.lifeTotal - increment); }; - const handleDownInput = ({ opponentIndex, isPartner }: InputProps) => { + const handleDownInput = ({ opponentIndex, isPartner, event }: InputProps) => { + downPositionRef.current = { x: event.clientX, y: event.clientY }; setTimeoutFinished(false); setHasPressedDown(true); timeoutRef.current = setTimeout(() => { @@ -112,11 +117,23 @@ export const CommanderDamage = ({ }, decrementTimeoutMs); }; - const handleUpInput = ({ opponentIndex, isPartner }: InputProps) => { + const handleUpInput = ({ opponentIndex, isPartner, event }: InputProps) => { if (!(hasPressedDown && !timeoutFinished)) { return; } - clearTimeout(timeoutRef.current); + + const upPosition = { x: event.clientX, y: event.clientY }; + + const hasMoved = + Math.abs(upPosition.x - downPositionRef.current.x) > + MAX_TAP_MOVE_DISTANCE || + Math.abs(upPosition.y - downPositionRef.current.y) > + MAX_TAP_MOVE_DISTANCE; + + if (hasMoved) { + return; + } + handleCommanderDamageChange(opponentIndex, 1, isPartner); setHasPressedDown(false); }; @@ -141,10 +158,12 @@ export const CommanderDamage = ({ - handleDownInput({ opponentIndex, isPartner: false }) + onPointerDown={(e) => + handleDownInput({ opponentIndex, isPartner: false, event: e }) + } + onPointerUp={(e) => + handleUpInput({ opponentIndex, isPartner: false, event: e }) } - onPointerUp={() => handleUpInput({ opponentIndex, isPartner: false })} onPointerLeave={handleLeaveInput} onContextMenu={(e: React.MouseEvent) => { e.preventDefault(); @@ -167,15 +186,15 @@ export const CommanderDamage = ({ {opponent.settings.usePartner && ( <> - + - handleDownInput({ opponentIndex, isPartner: true }) + onPointerDown={(e) => + handleDownInput({ opponentIndex, isPartner: true, event: e }) } - onPointerUp={() => - handleUpInput({ opponentIndex, isPartner: true }) + onPointerUp={(e) => + handleUpInput({ opponentIndex, isPartner: true, event: e }) } onPointerLeave={handleLeaveInput} onContextMenu={( diff --git a/src/Components/Buttons/ExtraCounter.tsx b/src/Components/Buttons/ExtraCounter.tsx index 18bb804..ccc9f9c 100644 --- a/src/Components/Buttons/ExtraCounter.tsx +++ b/src/Components/Buttons/ExtraCounter.tsx @@ -3,7 +3,7 @@ import { twc } from 'react-twc'; import { decrementTimeoutMs } from '../../Data/constants'; import { CounterType, Rotation } from '../../Types/Player'; import { OutlinedText } from '../Misc/OutlinedText'; -import { RotationDivProps } from './CommanderDamage'; +import { MAX_TAP_MOVE_DISTANCE, RotationDivProps } from './CommanderDamage'; const ExtraCounterContainer = twc.div` flex @@ -63,6 +63,7 @@ const ExtraCounter = ({ const timeoutRef = useRef(undefined); const [timeoutFinished, setTimeoutFinished] = useState(false); const [hasPressedDown, setHasPressedDown] = useState(false); + const downPositionRef = useRef({ x: 0, y: 0 }); const handleCountChange = (increment: number) => { if (!counterTotal) { @@ -72,7 +73,8 @@ const ExtraCounter = ({ setCounterTotal(counterTotal + increment, type); }; - const handleDownInput = () => { + const handleDownInput = (event: React.PointerEvent) => { + downPositionRef.current = { x: event.clientX, y: event.clientY }; setTimeoutFinished(false); setHasPressedDown(true); timeoutRef.current = setTimeout(() => { @@ -81,10 +83,23 @@ const ExtraCounter = ({ }, decrementTimeoutMs); }; - const handleUpInput = () => { + const handleUpInput = (event: React.PointerEvent) => { if (!(hasPressedDown && !timeoutFinished)) { return; } + + const upPosition = { x: event.clientX, y: event.clientY }; + + const hasMoved = + Math.abs(upPosition.x - downPositionRef.current.x) > + MAX_TAP_MOVE_DISTANCE || + Math.abs(upPosition.y - downPositionRef.current.y) > + MAX_TAP_MOVE_DISTANCE; + + if (hasMoved) { + return; + } + clearTimeout(timeoutRef.current); handleCountChange(1); setHasPressedDown(false); diff --git a/src/Components/Buttons/LifeCounterButton.tsx b/src/Components/Buttons/LifeCounterButton.tsx index c642dc4..007da84 100644 --- a/src/Components/Buttons/LifeCounterButton.tsx +++ b/src/Components/Buttons/LifeCounterButton.tsx @@ -2,6 +2,7 @@ import { useRef, useState } from 'react'; import { TwcComponentProps, twc } from 'react-twc'; import { lifeLongPressMultiplier } from '../../Data/constants'; import { Rotation } from '../../Types/Player'; +import { MAX_TAP_MOVE_DISTANCE } from './CommanderDamage'; type RotationButtonProps = TwcComponentProps<'div'> & { $align?: string; @@ -56,12 +57,14 @@ const LifeCounterButton = ({ const timeoutRef = useRef(undefined); const [timeoutFinished, setTimeoutFinished] = useState(false); const [hasPressedDown, setHasPressedDown] = useState(false); + const downPositionRef = useRef({ x: 0, y: 0 }); const handleLifeChange = (increment: number) => { setLifeTotal(lifeTotal + increment); }; - const handleDownInput = () => { + const handleDownInput = (event: React.PointerEvent) => { + downPositionRef.current = { x: event.clientX, y: event.clientY }; setTimeoutFinished(false); setHasPressedDown(true); timeoutRef.current = setTimeout(() => { @@ -70,10 +73,23 @@ const LifeCounterButton = ({ }, 500); }; - const handleUpInput = () => { + const handleUpInput = (event: React.PointerEvent) => { if (!(hasPressedDown && !timeoutFinished)) { return; } + + const upPosition = { x: event.clientX, y: event.clientY }; + + const hasMoved = + Math.abs(upPosition.x - downPositionRef.current.x) > + MAX_TAP_MOVE_DISTANCE || + Math.abs(upPosition.y - downPositionRef.current.y) > + MAX_TAP_MOVE_DISTANCE; + + if (hasMoved) { + return; + } + clearTimeout(timeoutRef.current); handleLifeChange(operation === 'add' ? 1 : -1); setHasPressedDown(false); diff --git a/src/Components/Buttons/SettingsButton.tsx b/src/Components/Buttons/SettingsButton.tsx deleted file mode 100644 index 2177a74..0000000 --- a/src/Components/Buttons/SettingsButton.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { twc } from 'react-twc'; -import { Cog } from '../../Icons/generated'; -import { Rotation } from '../../Types/Player'; -import { RotationButtonProps } from './CommanderDamage'; - -const SettingsButtonTwc = twc.button((props) => [ - 'absolute flex-grow border-none outline-none cursor-pointer bg-transparent z-[1] select-none webkit-user-select-none', - props.$rotation === Rotation.Side || props.$rotation === Rotation.SideFlipped - ? `right-auto top-[1vmax] left-[27%]` - : 'top-1/4 right-[1vmax]', -]); - -type SettingsButtonProps = { - onClick: () => void; - rotation: Rotation; -}; - -const SettingsButton = ({ onClick, rotation }: SettingsButtonProps) => { - return ( - - - - ); -}; - -export default SettingsButton; diff --git a/src/Components/LifeCounter/LifeCounter.tsx b/src/Components/LifeCounter/LifeCounter.tsx index 38c5286..35623e9 100644 --- a/src/Components/LifeCounter/LifeCounter.tsx +++ b/src/Components/LifeCounter/LifeCounter.tsx @@ -64,6 +64,8 @@ type LifeCounterProps = { opponents: Player[]; }; +const RECENT_DIFFERENCE_TTL = 3_000; + const LifeCounter = ({ player, opponents }: LifeCounterProps) => { const { updatePlayer, updateLifeTotal } = usePlayers(); const { settings } = useGlobalSettings(); @@ -81,24 +83,26 @@ const LifeCounter = ({ player, opponents }: LifeCounterProps) => { const handlers = useSwipeable({ trackMouse: true, - onSwipedDown: () => { + onSwipedDown: (e) => { + e.event.stopPropagation(); console.log(`User DOWN Swiped on player ${player.index}`); setShowPlayerMenu(true); }, - onSwipedUp: () => { + onSwipedUp: (e) => { + e.event.stopPropagation(); console.log(`User UP Swiped on player ${player.index}`); setShowPlayerMenu(false); }, swipeDuration: 500, - onSwiping: (eventData) => console.log(eventData), + onSwiping: (e) => e.event.stopPropagation(), rotationAngle, }); useEffect(() => { const timer = setTimeout(() => { setRecentDifference(0); - }, 3_000); + }, RECENT_DIFFERENCE_TTL); const resizeObserver = new ResizeObserver(() => { if (document.body.clientWidth > document.body.clientHeight) diff --git a/src/Components/Player/PlayerMenu.tsx b/src/Components/Player/PlayerMenu.tsx index 4ae11be..efbf039 100644 --- a/src/Components/Player/PlayerMenu.tsx +++ b/src/Components/Player/PlayerMenu.tsx @@ -40,16 +40,19 @@ const BetterRowContainer = twc.div` flex-grow w-full h-full - justify-end + justify-between items-stretch `; const TogglesSection = twc.div` flex - relative flex-row + flex-wrap + relative gap-2 + h-full justify-evenly + items-center `; const ButtonsSections = twc.div` @@ -59,14 +62,14 @@ const ButtonsSections = twc.div` justify-between p-[3%] items-center + flex-wrap `; const ColorPicker = twc.input` - absolute - top-[5%] - left-[5%] h-[8vmax] w-[8vmax] + max-h-12 + max-w-11 border-none outline-none cursor-pointer @@ -156,15 +159,15 @@ const PlayerMenu = ({ }} ref={settingsContainerRef} > - + {player.settings.useCommanderDamage && ( -
+

Reset Game?