Skip to content

Commit

Permalink
Merge pull request #149 from daithihearn/daithihearn-styling2
Browse files Browse the repository at this point in the history
Re ordering components on game page
  • Loading branch information
daithihearn authored Feb 28, 2023
2 parents eef92cc + 4ec56d4 commit db2048c
Show file tree
Hide file tree
Showing 12 changed files with 430 additions and 389 deletions.
2 changes: 2 additions & 0 deletions src/caches/GameSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,10 @@ export const getIsDoublesGame = createSelector(
players => players.length === 6,
)

export const getMaxCall = createSelector(getGame, game => game.maxCall || 0)
export const getIsMyGo = createSelector(getGame, game => game.isMyGo)
export const getIamGoer = createSelector(getGame, game => game.iamGoer)
export const getIamDealer = createSelector(getGame, game => game.iamDealer)
export const getIHavePlayed = createSelector(getGame, game => {
const myPosition = game.players.findIndex(p => p.id === game.me?.id)
const currentPlayerPosition = game.players.findIndex(
Expand Down
32 changes: 32 additions & 0 deletions src/components/Game/Actions/ActionsWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { ButtonGroup, CardBody } from "reactstrap"
import {
getIsRoundBuying,
getIsRoundCalled,
getIsRoundCalling,
getIsRoundPlaying,
} from "../../../caches/GameSlice"
import { useAppSelector } from "../../../caches/hooks"
import Buying from "./Buying"
import Calling from "./Calling"
import PlayCard from "./PlayCard"
import SelectSuit from "./SelectSuit"

const ActionsWrapper = () => {
const isBuying = useAppSelector(getIsRoundBuying)
const isCalling = useAppSelector(getIsRoundCalling)
const isPlaying = useAppSelector(getIsRoundPlaying)
const isCalled = useAppSelector(getIsRoundCalled)

return (
<CardBody className="buttonArea">
<ButtonGroup size="lg">
{isCalling && <Calling />}
{isBuying && <Buying />}
{isCalled && <SelectSuit />}
{isPlaying && <PlayCard />}
</ButtonGroup>
</CardBody>
)
}

export default ActionsWrapper
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
import { Button, ButtonGroup, CardBody } from "reactstrap"
import { Button } from "reactstrap"

import { useCallback, useEffect, useState } from "react"

import GameService from "../../services/GameService"
import { useAppDispatch, useAppSelector } from "../../caches/hooks"
import GameService from "../../..//services/GameService"
import { useAppDispatch, useAppSelector } from "../../..//caches/hooks"
import { useSnackbar } from "notistack"
import {
getMyCardsWithoutBlanks,
getSelectedCards,
selectAll,
} from "../../caches/MyCardsSlice"
} from "../../..//caches/MyCardsSlice"
import {
getGameId,
getIamGoer,
getIHavePlayed,
getIsMyGo,
getSuit,
} from "../../caches/GameSlice"
import { riskOfMistakeBuyingCards } from "../../utils/GameUtils"
} from "../../..//caches/GameSlice"
import { riskOfMistakeBuyingCards } from "../../../utils/GameUtils"
import ThrowCardsWarningModal from "./ThrowCardsWarningModal"
import { SelectableCard } from "../../model/Cards"
import parseError from "../../utils/ErrorUtils"
import { SelectableCard } from "../../../model/Cards"
import parseError from "../../../utils/ErrorUtils"

const WaitingForRoundToStart = () => (
<Button disabled type="button" color="info">
<b>Waiting for round to start...</b>
</Button>
)

const Buying = () => {
const dispatch = useAppDispatch()
Expand Down Expand Up @@ -69,32 +75,27 @@ const Buying = () => {
}
}, [gameId, suit, selectedCards, myCards, isMyGo, readyToBuy])

if (iHavePlayed) return <WaitingForRoundToStart />
return (
<div>
<CardBody className="buttonArea">
<ButtonGroup size="lg">
{!iHavePlayed ? (
<Button
type="button"
onClick={toggleReadyToBuy}
color={isMyGo || !readyToBuy ? "primary" : "info"}>
<b>
{isMyGo || !readyToBuy
? "Keep Cards"
: "Waiting to buy cards..."}
</b>
</Button>
) : null}
</ButtonGroup>
<>
<Button
type="button"
onClick={toggleReadyToBuy}
color={isMyGo || !readyToBuy ? "primary" : "info"}>
<b>
{isMyGo || !readyToBuy
? "Keep Cards"
: "Waiting to buy cards..."}
</b>
</Button>

<ThrowCardsWarningModal
modalVisible={deleteCardsDialog}
cancelCallback={hideCancelDeleteCardsDialog}
continueCallback={buyCards}
suit={suit!}
/>
</CardBody>
</div>
<ThrowCardsWarningModal
modalVisible={deleteCardsDialog}
cancelCallback={hideCancelDeleteCardsDialog}
continueCallback={buyCards}
suit={suit!}
/>
</>
)
}

Expand Down
125 changes: 125 additions & 0 deletions src/components/Game/Actions/Calling.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { Button } from "reactstrap"

import GameService from "../../../services/GameService"
import { useAppDispatch, useAppSelector } from "../../../caches/hooks"
import {
getCards,
getGameId,
getGamePlayers,
getIamDealer,
getIsMyGo,
getMaxCall,
getRound,
} from "../../../caches/GameSlice"
import { useCallback, useMemo } from "react"
import { useSnackbar } from "notistack"
import parseError from "../../../utils/ErrorUtils"

const Calling = () => {
const dispatch = useAppDispatch()
const { enqueueSnackbar } = useSnackbar()
const gameId = useAppSelector(getGameId)
const cards = useAppSelector(getCards)
const round = useAppSelector(getRound)
const players = useAppSelector(getGamePlayers)
const isMyGo = useAppSelector(getIsMyGo)
const iamDealer = useAppSelector(getIamDealer)
const maxCall = useAppSelector(getMaxCall)

const call = useCallback(
(callAmount: number) => {
if (gameId)
dispatch(GameService.call(gameId, callAmount)).catch(
(e: Error) =>
enqueueSnackbar(parseError(e), { variant: "error" }),
)
},
[gameId],
)

const buttonsEnabled = useMemo(
() => round && round.currentHand && cards.length > 0 && isMyGo,
[round, cards, isMyGo],
)

const canCall10 = useMemo(
() =>
players.length === 6 &&
((iamDealer && maxCall <= 10) || maxCall < 10),
[players, iamDealer, maxCall],
)

const canCall15 = useMemo(
() => (iamDealer && maxCall <= 15) || maxCall < 15,
[iamDealer, maxCall],
)

const canCall20 = useMemo(
() => (iamDealer && maxCall <= 20) || maxCall < 20,
[iamDealer, maxCall],
)

const canCall25 = useMemo(
() => (iamDealer && maxCall <= 25) || maxCall < 25,
[iamDealer, maxCall],
)

const canCallJink = useMemo(() => players.length > 2, [players])

return (
<>
<Button
disabled={!buttonsEnabled}
type="button"
color="secondary"
onClick={() => call(0)}>
Pass
</Button>
{canCall10 ? (
<Button
disabled={!buttonsEnabled}
type="button"
color="primary"
onClick={() => call(10)}>
10
</Button>
) : null}
{canCall15 ? (
<Button
disabled={!buttonsEnabled}
type="button"
color="warning"
onClick={() => call(15)}>
15
</Button>
) : null}
{canCall20 ? (
<Button
disabled={!buttonsEnabled}
type="button"
color="warning"
onClick={() => call(20)}>
20
</Button>
) : null}
{canCall25 ? (
<Button
disabled={!buttonsEnabled}
type="button"
color="warning"
onClick={() => call(25)}>
25
</Button>
) : null}
<Button
disabled={!buttonsEnabled}
type="button"
color="danger"
onClick={() => call(30)}>
{canCallJink ? "Jink" : "30"}
</Button>
</>
)
}

export default Calling
68 changes: 68 additions & 0 deletions src/components/Game/Actions/PlayCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { Button } from "reactstrap"

import { useCallback, useMemo } from "react"

import GameService from "../../../services/GameService"
import { useAppDispatch, useAppSelector } from "../../../caches/hooks"
import { useSnackbar } from "notistack"
import {
getMyCardsWithoutBlanks,
getSelectedCards,
} from "../../../caches/MyCardsSlice"
import { getGameId, getIsMyGo, getRound } from "../../../caches/GameSlice"
import { BLANK_CARD } from "../../../model/Cards"
import parseError from "../../../utils/ErrorUtils"
import { RoundStatus } from "../../../model/Round"

const WaitingForYourGo = () => (
<Button disabled type="button" color="info">
<b>Waiting for your go...</b>
</Button>
)

const PlayCard = () => {
const dispatch = useAppDispatch()
const round = useAppSelector(getRound)
const { enqueueSnackbar } = useSnackbar()
const gameId = useAppSelector(getGameId)
const myCards = useAppSelector(getMyCardsWithoutBlanks)
const isMyGo = useAppSelector(getIsMyGo)
const selectedCards = useAppSelector(getSelectedCards)

const playButtonEnabled = useMemo(
() =>
isMyGo &&
round &&
round.status === RoundStatus.PLAYING &&
round.completedHands.length +
myCards.filter(c => c.name !== BLANK_CARD.name).length ===
5,

[isMyGo, round, myCards],
)

const playCard = useCallback(() => {
if (selectedCards.length !== 1) {
enqueueSnackbar("Please select exactly one card to play", {
variant: "warning",
})
} else {
dispatch(
GameService.playCard(gameId!, selectedCards[0].name),
).catch(e => enqueueSnackbar(parseError(e), { variant: "error" }))
}
}, [gameId, selectedCards])

if (!playButtonEnabled) return <WaitingForYourGo />
return (
<Button
id="playCardButton"
type="button"
onClick={playCard}
color="primary">
<b>Play Card</b>
</Button>
)
}

export default PlayCard
Loading

0 comments on commit db2048c

Please sign in to comment.