Skip to content

Commit

Permalink
Resource popup improvments (#178)
Browse files Browse the repository at this point in the history
  • Loading branch information
danbastin authored Mar 4, 2025
1 parent 6bfc963 commit fc2b28b
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 58 deletions.
2 changes: 1 addition & 1 deletion src/app/GameBoard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ const GameBoard = () => {
</Box>
</Box>

<PopupShell/>
<PopupShell sidebarOpen={sidebarOpen}/>
<PreferencesComponent
sidebarOpen={sidebarOpen}
isPreferenceOpen={isPreferenceOpen}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ const CardActionTray: React.FC = () => {
const playerState = gameState.players[connectedPlayer];

const showTrayButtons = () => {
if ( playerState.promptState.promptType == 'actionWindow' ||
playerState.promptState.promptType == 'resource' ||
playerState.promptState.promptType == 'distributeAmongTargets' ||
playerState.promptState.selectCard == true ) {
if ( playerState.promptState.promptType === 'actionWindow' ||
playerState.promptState.promptType === 'resource' ||
playerState.promptState.promptType === 'distributeAmongTargets' ||
!!playerState.promptState.selectCardMode === true ) {
return true;
}
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,28 @@ const DeckDiscard: React.FC<IDeckDiscardProps> = (
trayPlayer
) => {
const { gameState, connectedPlayer } = useGame();
const { togglePopup } = usePopup();
const { togglePopup, popups } = usePopup();

const handleDiscardToggle = () => {
const playerName = connectedPlayer != trayPlayer.trayPlayer ? 'Your Opponent\'s' : 'Your';
const existingPopup = popups.find(popup => popup.uuid === `${trayPlayer.trayPlayer}-discard`);

if (existingPopup && existingPopup.source === PopupSource.PromptState) {
// TODO: allow game propt to be toggled
// const { type, ...restData } = existingPopup
// togglePopup(type, {
// ...restData
// });
} else {
togglePopup('pile', {
uuid: `${trayPlayer.trayPlayer}-discard`,
title: `${playerName} discard`,
cards: gameState?.players[trayPlayer.trayPlayer]?.cardPiles['discard'],
source: PopupSource.User,
buttons: null
})
}
}

const styles = {
containerStyle: {
Expand Down Expand Up @@ -85,16 +106,7 @@ const DeckDiscard: React.FC<IDeckDiscardProps> = (
<Box sx={styles.containerStyle}>
<Card
sx={styles.discard.discardCardStyle(gameState?.players[trayPlayer.trayPlayer]?.cardPiles['discard'].at(-1))}
onClick={() => {
const playerName = connectedPlayer != trayPlayer.trayPlayer ? 'Your Opponent\'s' : 'Your';

togglePopup('pile', {
uuid: `${trayPlayer.trayPlayer}-discard`,
title: `${playerName} discard`,
cards: gameState?.players[trayPlayer.trayPlayer]?.cardPiles['discard'],
source: PopupSource.User
})
}}
onClick={handleDiscardToggle}
/>
<Card sx={styles.deck.deckCardStyle}>
{deckComponent}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,32 @@ const Resources: React.FC<IResourcesProps> = ({
trayPlayer
}) => {
const { gameState, connectedPlayer } = useGame();
const { togglePopup } = usePopup();
const { togglePopup, popups } = usePopup();

const availableResources = gameState.players[trayPlayer].availableResources;
const totalResources = gameState.players[trayPlayer].cardPiles.resources.length;

const handleResourceToggle = () => {
const playerName = connectedPlayer != trayPlayer ? 'Your Opponent\'s' : 'Your';
const existingPopup = popups.find(popup => popup.uuid === `${trayPlayer}-resources`);

if (existingPopup && existingPopup.source === PopupSource.PromptState) {
// TODO: allow game propt to be toggled
// const { type, ...restData } = existingPopup
// togglePopup(type, {
// ...restData
// });
} else {
togglePopup('pile', {
uuid: `${trayPlayer}-resources`,
title: `${playerName} Resources`,
cards: gameState?.players[trayPlayer]?.cardPiles['resources'],
source: PopupSource.User,
buttons: null
})
}
}

// ------------------------STYLES------------------------//
const styles = {
cardStyle: {
Expand Down Expand Up @@ -86,16 +107,7 @@ const Resources: React.FC<IResourcesProps> = ({
return (
<Card
sx={styles.cardStyle}
onClick={() => {
if (trayPlayer !== connectedPlayer) return;

togglePopup('pile', {
uuid: `${connectedPlayer}-resources`,
title: 'Your Resources',
cards: gameState?.players[connectedPlayer]?.cardPiles['resources'],
source: PopupSource.User
})
}}
onClick={handleResourceToggle}
>
<Box sx={styles.resourceBorderRight} />
<Box sx={styles.resourceBorderLeft} />
Expand Down
13 changes: 12 additions & 1 deletion src/app/_components/_sharedcomponents/Cards/GameCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Grid from '@mui/material/Grid2';
import { IGameCardProps, ICardData, CardStyle } from './CardTypes';
import CardValueAdjuster from './CardValueAdjuster';
import { useGame } from '@/app/_contexts/Game.context';
import { usePopup } from '@/app/_contexts/Popup.context';
import { s3CardImageURL, s3TokenImageURL } from '@/app/_utils/s3Utils';
import { getBorderColor } from './cardUtils';

Expand All @@ -21,6 +22,11 @@ const GameCard: React.FC<IGameCardProps> = ({
disabled = false,
}) => {
const { sendGameMessage, connectedPlayer, getConnectedPlayerPrompt, distributionPromptData } = useGame();
const { clearPopups } = usePopup();

if (!card.selectable) {
disabled = true;
}

const cardInPlayersHand = card.controller?.id === connectedPlayer && card.zone === 'hand';
const cardInOpponentsHand = card.controller?.id !== connectedPlayer && card.zone === 'hand';
Expand Down Expand Up @@ -91,7 +97,12 @@ const GameCard: React.FC<IGameCardProps> = ({
sendGameMessage(['cardClicked', card.uuid]);
}
};
const handleClick = onClick ?? defaultClickFunction;
const handleClick = () => {
if (getConnectedPlayerPrompt()?.selectCardMode !== 'multiple') {
clearPopups();
}
(onClick || defaultClickFunction)();
}

const subcardClick = (subCard: ICardData) => {
if (subCard.selectable) {
Expand Down
4 changes: 4 additions & 0 deletions src/app/_components/_sharedcomponents/Popup/Popup.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ export const headerStyle = (isMinimized: boolean) => ({
position: 'relative',
});

export const subtitleStyle = {
maxWidth: '80%'
}

export const footerStyle = {
display: 'flex',
gap: '1rem',
Expand Down
26 changes: 16 additions & 10 deletions src/app/_components/_sharedcomponents/Popup/Popup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,6 @@ import { useGame } from '@/app/_contexts/Game.context';
import { DropdownPopupModal } from './PopupVariant/DropdownPopup';
import { LeaveGamePopupModule } from '@/app/_components/_sharedcomponents/Popup/PopupVariant/LeaveGamePopup';

const overlayStyle = {
position: 'absolute',
width: '100%',
height: '100%',
pointerEvents: 'none',
display: 'flex',
zIndex: 10,
};

const focusHandlerStyle = (type: PopupType, data: PopupData, index: number, playerName:string, containCards?:boolean): SxProps<Theme> => ({
zIndex: 11 + index,
pointerEvents: 'auto',
Expand Down Expand Up @@ -63,7 +54,13 @@ export const getPopupPosition = (type: PopupType, data: PopupData, index: number
// } as const;
}

const PopupShell: React.FC = () => {
interface IPopupShellProps {
sidebarOpen?: boolean;
}

const PopupShell: React.FC<IPopupShellProps> = ({
sidebarOpen = false
}) => {
const { popups, focusPopup } = usePopup();
const { connectedPlayer }= useGame();
const isPilePopup = (popup: PopupData): popup is PilePopup => popup.type === 'pile';
Expand Down Expand Up @@ -104,6 +101,15 @@ const PopupShell: React.FC = () => {
popups.filter((popup) => popup.type === 'default')
];

const overlayStyle = {
position: 'absolute',
width: sidebarOpen ? 'calc(100% - 250px)' : '100%',
height: '100%',
pointerEvents: 'none',
display: 'flex',
zIndex: 10,
};

return (
<Box sx={overlayStyle}>
{defaultPopups.map((popup, index) => renderPopup(popup, index))}
Expand Down
2 changes: 2 additions & 0 deletions src/app/_components/_sharedcomponents/Popup/Popup.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ export type PilePopup = {
type: 'pile';
uuid: string;
title: string;
subtitle?: string;
cards: ICardData[];
source: PopupSource;
buttons: PopupButton[] | null;
};

export type DropdownPopup = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,6 @@ export const DefaultPopupModal = ({ data }: ButtonProps) => {
>
{button.text}
</GradientBorderButton>
// <Button
// key={`${button.uuid}:${index}`}
// sx={{ ...buttonStyle, backgroundColor: button.selected ? 'white' : '' }}
// variant="contained"
// onClick={() => {
// sendGameMessage([button.command, button.arg, button.uuid]);
// closePopup(data.uuid);
// }}
// >
// {button.text}
// </Button>
))}
</Box>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ import { Box, Button, Grid2, IconButton, Typography } from '@mui/material';
import { useState } from 'react';
import { BiMinus, BiPlus } from 'react-icons/bi';
import GameCard from '../../Cards/GameCard';
import GradientBorderButton from '../../_styledcomponents/GradientBorderButton';
import {
buttonStyle,
containerStyle,
footerStyle,
headerStyle,
minimizeButtonStyle,
titleStyle,
subtitleStyle,
} from '../Popup.styles';
import { PilePopup } from '../Popup.types';
import { PilePopup, PopupButton } from '../Popup.types';
import { useGame } from '@/app/_contexts/Game.context';

interface ButtonProps {
data: PilePopup;
Expand All @@ -25,6 +28,7 @@ export const gridContainerStyle = {

export const PilePopupModal = ({ data }: ButtonProps) => {
const { closePopup } = usePopup();
const { sendGameMessage } = useGame();

const [isMinimized, setIsMinimized] = useState(false);

Expand All @@ -49,9 +53,23 @@ export const PilePopupModal = ({ data }: ButtonProps) => {
{data.cards.length === 0 && <Typography>No cards to display</Typography>}

<Box sx={footerStyle}>
<Button onClick={() => closePopup(data.uuid)} sx={buttonStyle}>
Done
</Button>
{ data.buttons !== null ?
data.buttons.map((button: PopupButton, index: number) => (
<GradientBorderButton
key={`${button.uuid}:${index}`}
fillColor={button.selected ? '#666' : undefined}
onClickHandler={() => {
sendGameMessage([button.command, button.arg, button.uuid]);
}}
>
{button.text}
</GradientBorderButton>
))
:
<Button onClick={() => closePopup(data.uuid)} sx={buttonStyle}>
Close
</Button>
}
</Box>
</>
);
Expand All @@ -74,6 +92,7 @@ export const PilePopupModal = ({ data }: ButtonProps) => {
{isMinimized ? <BiPlus /> : <BiMinus />}
</IconButton>
</Box>
<Typography sx={subtitleStyle} hidden={isMinimized}>{data.subtitle}</Typography>

{renderPopupContent()}
</Box>
Expand Down
14 changes: 13 additions & 1 deletion src/app/_constants/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,16 @@ export const FormatLabels: Record<SwuGameFormat, string> = {
[SwuGameFormat.Premier]: 'Premier',
[SwuGameFormat.NextSetPreview]: 'Next Set Preview',
[SwuGameFormat.Open]: 'Open',
};
};

export enum ZoneName {
Base = 'base',
Capture = 'capture',
Deck = 'deck',
Discard = 'discard',
GroundArena = 'groundArena',
Hand = 'hand',
OutsideTheGame = 'outsideTheGame',
Resource = 'resource',
SpaceArena = 'spaceArena',
}
Loading

0 comments on commit fc2b28b

Please sign in to comment.