Files
LifeTrinket/my-app/src/Components/Buttons/CommanderDamageBar.tsx
2023-07-06 23:50:03 +02:00

220 lines
6.1 KiB
TypeScript

import { useRef, useState } from 'react';
import { Player } from '../../Types/Player';
import styled from 'styled-components';
const CommanderDamageGrid = styled.div`
display: flex;
flex-direction: row;
flex-grow: 1;
width: 100%;
`;
const CommanderDamageContainer = styled.div`
display: flex;
flex-direction: row;
flex-grow: 1;
width: 100%;
`;
const CommanderDamageButton = styled.button<{ backgroundColor?: string }>`
display: flex;
flex-grow: 1;
border: none;
height: 10vmin;
outline: none;
cursor: pointer;
background-color: ${(props) => props.backgroundColor || 'antiquewhite'};
margin: 0;
user-select: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: transparent;
-moz-user-select: -moz-none;
-webkit-user-select: none;
-ms-user-select: none;
`;
const CommanderDamageButtonText = styled.p`
position: relative;
margin: auto;
font-size: 1.5rem;
text-align: center;
text-size-adjust: auto;
font-variant-numeric: tabular-nums;
pointer-events: none;
width: 2rem;
text-shadow: -1px -1px 0 #ffffff, 1px -1px 0 #ffffff, -1px 1px 0 #ffffff,
1px 1px 0 #ffffff;
color: #000000;
user-select: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: transparent;
-moz-user-select: -moz-none;
-webkit-user-select: none;
-ms-user-select: none;
`;
const VerticalSeperator = styled.div`
width: 1px;
background-color: rgba(0, 0, 0, 1);
`;
type CommanderDamageBarProps = {
lifeTotal: number;
opponents: Player[];
player: Player;
onPlayerChange: (updatedPlayer: Player) => void;
setLifeTotal: (lifeTotal: number) => void;
};
const CommanderDamageBar = ({
opponents,
lifeTotal,
player,
onPlayerChange,
setLifeTotal,
}: CommanderDamageBarProps) => {
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
const [timeoutFinished, setTimeoutFinished] = useState(false);
const [hasPressedDown, setHasPressedDown] = useState(false);
const handleCommanderDamageChange = (
index: number,
increment: number,
isPartner: boolean
) => {
const currentCommanderDamage = player.commanderDamage[index];
if (isPartner) {
if (currentCommanderDamage.partnerDamageTotal === 0 && increment === -1) {
return;
}
const updatedCommanderDamage = [...player.commanderDamage];
updatedCommanderDamage[index].partnerDamageTotal += increment;
const updatedPlayer = {
...player,
commanderDamage: updatedCommanderDamage,
};
onPlayerChange(updatedPlayer);
setLifeTotal(lifeTotal - increment);
return;
}
if (currentCommanderDamage.damageTotal === 0 && increment === -1) {
return;
}
const updatedCommanderDamage = [...player.commanderDamage];
updatedCommanderDamage[index].damageTotal += increment;
const updatedPlayer = {
...player,
commanderDamage: updatedCommanderDamage,
};
onPlayerChange(updatedPlayer);
setLifeTotal(lifeTotal - increment);
};
const handleDownInput = (index: number) => {
setTimeoutFinished(false);
setHasPressedDown(true);
timeoutRef.current = setTimeout(() => {
setTimeoutFinished(true);
handleCommanderDamageChange(index, -1, false);
}, 500);
};
const handleUpInput = (index: number) => {
if (!(hasPressedDown && !timeoutFinished)) {
return;
}
clearTimeout(timeoutRef.current);
handleCommanderDamageChange(index, 1, false);
setHasPressedDown(false);
};
const handleLeaveInput = () => {
setTimeoutFinished(true);
clearTimeout(timeoutRef.current);
setHasPressedDown(false);
};
const handlePartnerDownInput = (index: number) => {
setTimeoutFinished(false);
setHasPressedDown(true);
timeoutRef.current = setTimeout(() => {
setTimeoutFinished(true);
handleCommanderDamageChange(index, -1, true);
}, 500);
};
const handlePartnerUpInput = (index: number) => {
if (!(hasPressedDown && !timeoutFinished)) {
return;
}
clearTimeout(timeoutRef.current);
handleCommanderDamageChange(index, 1, true);
setHasPressedDown(false);
};
const handlePartnerLeaveInput = () => {
setTimeoutFinished(true);
clearTimeout(timeoutRef.current);
setHasPressedDown(false);
};
return (
<CommanderDamageGrid>
{opponents.map((opponent, index) => {
return (
<CommanderDamageContainer>
<CommanderDamageButton
key={index}
onPointerDown={() => handleDownInput(index)}
onPointerUp={() => handleUpInput(index)}
onPointerLeave={handleLeaveInput}
onContextMenu={(
e: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
e.preventDefault();
}}
backgroundColor={opponent.color}
>
<CommanderDamageButtonText>
{player.commanderDamage[index].damageTotal > 0
? player.commanderDamage[index].damageTotal
: ''}
</CommanderDamageButtonText>
</CommanderDamageButton>
{opponent.settings.usePartner && (
<>
<VerticalSeperator />
<CommanderDamageButton
key={index}
onPointerDown={() => handlePartnerDownInput(index)}
onPointerUp={() => handlePartnerUpInput(index)}
onPointerLeave={handlePartnerLeaveInput}
onContextMenu={(
e: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
e.preventDefault();
}}
backgroundColor={opponent.color}
>
<CommanderDamageButtonText>
{player.commanderDamage[index].partnerDamageTotal > 0
? player.commanderDamage[index].partnerDamageTotal
: ''}
</CommanderDamageButtonText>
</CommanderDamageButton>
</>
)}
</CommanderDamageContainer>
);
})}
</CommanderDamageGrid>
);
};
export default CommanderDamageBar;