Skip to content

Commit

Permalink
Merge pull request #88 from daithihearn/auto-action
Browse files Browse the repository at this point in the history
Auto action
  • Loading branch information
daithihearn authored Jan 18, 2023
2 parents 655aefa + 044de60 commit 2372a94
Show file tree
Hide file tree
Showing 11 changed files with 53 additions and 32 deletions.
6 changes: 3 additions & 3 deletions src/caches/GameSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ export const getHasGame = createSelector(
getGameStatus,
status => status === GameStatus.ACTIVE || status === GameStatus.NONE,
)
export const isGameActive = createSelector(
export const getIsGameActive = createSelector(
getGameStatus,
status => status === GameStatus.ACTIVE,
)

export const isGameFinished = createSelector(
export const getIsGameFinished = createSelector(
getGameStatus,
status => status === GameStatus.FINISHED,
)
Expand All @@ -73,7 +73,7 @@ export const getIsRoundPlaying = createSelector(
status => status === RoundStatus.PLAYING,
)

export const isDoublesGame = createSelector(
export const getIsDoublesGame = createSelector(
getGamePlayers,
players => players.length === 6,
)
Expand Down
8 changes: 5 additions & 3 deletions src/caches/MyCardsSlice.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit"
import { createSelector, createSlice, PayloadAction } from "@reduxjs/toolkit"
import { BLANK_CARD, SelectableCard } from "../model/Cards"
import { processOrderedCardsAfterGameUpdate } from "../utils/GameUtils"
import { RootState } from "./caches"
Expand Down Expand Up @@ -56,5 +56,7 @@ export const {
} = myCardsSlice.actions

export const getMyCards = (state: RootState) => state.myCards.cards
export const getMyCardsWithoutBlanks = (state: RootState) =>
state.myCards.cards.filter(c => c.name !== BLANK_CARD.name)

export const getMyCardsWithoutBlanks = createSelector(getMyCards, cards =>
cards.filter(c => c.name !== BLANK_CARD.name),
)
8 changes: 6 additions & 2 deletions src/caches/MyProfileSlice.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit"
import { createSelector, createSlice, PayloadAction } from "@reduxjs/toolkit"
import { MyProfile } from "../model/Player"
import { RootState } from "./caches"

Expand All @@ -24,4 +24,8 @@ export const myProfileSlice = createSlice({
export const { updateMyProfile } = myProfileSlice.actions

export const getMyProfile = (state: RootState) => state.myProfile
export const getAccessToken = (state: RootState) => state.myProfile.accessToken

export const getAccessToken = createSelector(
getMyProfile,
myProfile => myProfile.accessToken,
)
2 changes: 0 additions & 2 deletions src/components/Game/GameWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import PlayersAndCards from "./PlayersAndCards"
import Calling from "./Calling"
import Buying from "./Buying"
import SelectSuit from "./SelectSuit"
import AutoActionManager from "./AutoActionManager"
import WebsocketManager from "./WebsocketManager"

import { useAppSelector } from "../../caches/hooks"
Expand All @@ -17,7 +16,6 @@ const GameWrapper = () => {
return (
<CardGroup>
<WebsocketManager />
<AutoActionManager />

<Card className="p-6" inverse>
<PlayersAndCards />
Expand Down
2 changes: 1 addition & 1 deletion src/components/Game/MyCards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ const MyCards: React.FC = () => {
<Droppable droppableId="characters" direction="horizontal">
{provided => (
<div
className="characters"
className="characters myCards"
style={{ display: "inline-flex" }}
{...provided.droppableProps}
ref={provided.innerRef}>
Expand Down
16 changes: 14 additions & 2 deletions src/components/Game/WebsocketManager.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useState } from "react"
import React, { useCallback, useEffect, useState } from "react"

import { StompSessionProvider, useSubscription } from "react-stomp-hooks"
import { useAppDispatch, useAppSelector } from "../../caches/hooks"
Expand All @@ -15,6 +15,7 @@ import shuffleAudioFile from "../../assets/sounds/shuffle.ogg"
import playCardAudioFile from "../../assets/sounds/play_card.ogg"
import callAudioFile from "../../assets/sounds/call.ogg"
import passAudioFile from "../../assets/sounds/pass.ogg"
import AutoActionManager from "./AutoActionManager"

const shuffleAudio = new Audio(shuffleAudioFile)
const playCardAudio = new Audio(playCardAudioFile)
Expand Down Expand Up @@ -49,11 +50,19 @@ interface ActionEvent {
const WebsocketHandler = () => {
const dispatch = useAppDispatch()

const [autoActionEnabled, setAutoActionEnabled] = useState(false)
const playerProfiles = useAppSelector(getPlayerProfiles)
const { enqueueSnackbar } = useSnackbar()

const [previousAction, updatePreviousAction] = useState<Actions>()

// Enable the auto action manager after a delay if it isn't already active
useEffect(() => {
setTimeout(() => {
if (!autoActionEnabled) setAutoActionEnabled(true)
}, 4000)
}, [autoActionEnabled])

const handleWebsocketMessage = useCallback(
(message: string) => {
if (previousAction === "LAST_CARD_PLAYED") {
Expand All @@ -79,6 +88,9 @@ const WebsocketHandler = () => {
const gameState = actionEvent.content as GameState
dispatch(updateGame(gameState))
}

// Only enable the auto action manager when we have successfully processed a message
if (!autoActionEnabled) setAutoActionEnabled(true)
}

const reloadCards = (payload: unknown) => {
Expand Down Expand Up @@ -142,7 +154,7 @@ const WebsocketHandler = () => {
handleWebsocketMessage(message.body),
)

return null
return <>{autoActionEnabled && <AutoActionManager />}</>
}

const WebsocketManager = () => {
Expand Down
8 changes: 4 additions & 4 deletions src/components/Header/NavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import ProfilePictureEditor from "../Avatar/ProfilePictureEditor"
import GameHeader from "../Game/GameHeader"
import { Col, Container, Row } from "reactstrap"
import LeaderboardModal from "../Leaderboard/LeaderboardModal"
import { isGameActive } from "../../caches/GameSlice"
import { getIsGameActive } from "../../caches/GameSlice"

const NavBar = () => {
const { logout } = useAuth0()

const gameActive = useAppSelector(isGameActive)
const isGameActive = useAppSelector(getIsGameActive)
const [showEditAvatar, setShowEditAvatar] = useState(false)

const myProfile = useAppSelector(getMyProfile)
Expand All @@ -40,10 +40,10 @@ const NavBar = () => {
</Link>
</Col>
<Col className="nav-col">
{gameActive && <LeaderboardModal />}
{isGameActive && <LeaderboardModal />}
</Col>
<Col className="nav-col">
{gameActive && <GameHeader />}
{isGameActive && <GameHeader />}
</Col>
<Col className="nav-col">
<div>
Expand Down
16 changes: 7 additions & 9 deletions src/components/Leaderboard/DoublesLeaderboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ import DataTable, { TableColumn } from "react-data-table-component"
import TrophyImage from "../../assets/icons/trophy.png"
import { useAppSelector } from "../../caches/hooks"
import {
getGame,
getGamePlayers,
getRound,
isGameFinished,
getIsGameFinished,
} from "../../caches/GameSlice"
import { getPlayerProfiles } from "../../caches/PlayerProfilesSlice"
import { GameStatus } from "../../model/Game"
import { compareScore, compareTeamIds } from "../../utils/PlayerUtils"
import { Player } from "../../model/Player"
import { customStyles } from "../Tables/CustomStyles"
Expand All @@ -34,7 +32,7 @@ const DoublesLeaderboard = () => {
const round = useAppSelector(getRound)
const players = useAppSelector(getGamePlayers)
const playerProfiles = useAppSelector(getPlayerProfiles)
const gameOver = useAppSelector(isGameFinished)
const isGameFinished = useAppSelector(getIsGameFinished)

const previousHand = useMemo(() => {
if (round) return round.completedHands[round.completedHands.length - 1]
Expand Down Expand Up @@ -111,7 +109,7 @@ const DoublesLeaderboard = () => {
className="avatar"
/>

{!gameOver && !!row.player1.previousCard ? (
{!isGameFinished && !!row.player1.previousCard ? (
<div>
{previousHand ? (
<img
Expand All @@ -127,7 +125,7 @@ const DoublesLeaderboard = () => {
</div>
) : null}

{!gameOver ? (
{!isGameFinished ? (
<div>
{!!row.player1.cardsBought
? `Bought: ${row.player1.cardsBought}`
Expand All @@ -148,7 +146,7 @@ const DoublesLeaderboard = () => {
className="avatar"
/>

{!gameOver && previousHand ? (
{!isGameFinished && previousHand ? (
<div>
{previousHand ? (
<img
Expand All @@ -164,7 +162,7 @@ const DoublesLeaderboard = () => {
</div>
) : null}

{!gameOver ? (
{!isGameFinished ? (
<div>
{!!row.player2.cardsBought
? `Bought: ${row.player2.cardsBought}`
Expand Down Expand Up @@ -195,7 +193,7 @@ const DoublesLeaderboard = () => {
</div>
),
center: true,
omit: !gameOver,
omit: !isGameFinished,
},
]

Expand Down
6 changes: 3 additions & 3 deletions src/components/Leaderboard/Leaderboard.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import SinglesLeaderboard from "./SinglesLeaderboard"
import DoublesLeaderboard from "./DoublesLeaderboard"
import { useAppSelector } from "../../caches/hooks"
import { isDoublesGame } from "../../caches/GameSlice"
import { getIsDoublesGame } from "../../caches/GameSlice"

const Leaderboard = () => {
const isDoubles = useAppSelector(isDoublesGame)
const isDoublesGame = useAppSelector(getIsDoublesGame)

if (isDoubles) return <DoublesLeaderboard />
if (isDoublesGame) return <DoublesLeaderboard />

return <SinglesLeaderboard />
}
Expand Down
6 changes: 3 additions & 3 deletions src/pages/Game/Game.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useParams } from "react-router-dom"

import { useAppDispatch, useAppSelector } from "../../caches/hooks"
import { useSnackbar } from "notistack"
import { getHasGame, resetGame } from "../../caches/GameSlice"
import { getIsGameActive, resetGame } from "../../caches/GameSlice"
import { clearAutoPlay } from "../../caches/AutoPlaySlice"
import { clearMyCards } from "../../caches/MyCardsSlice"
import RefreshingData from "../../components/icons/RefreshingData"
Expand All @@ -19,7 +19,7 @@ const Game = () => {
const dispatch = useAppDispatch()
let { id } = useParams<string>()
const { enqueueSnackbar } = useSnackbar()
const hasGame = useAppSelector(getHasGame)
const isGameActive = useAppSelector(getIsGameActive)

const fetchData = async () => {
if (id)
Expand Down Expand Up @@ -50,7 +50,7 @@ const Game = () => {
<div className="app carpet">
<div className="game_wrap">
<div className="game_container">
{hasGame ? <GameWrapper /> : <GameOver />}
{isGameActive ? <GameWrapper /> : <GameOver />}
</div>
</div>
</div>
Expand Down
7 changes: 7 additions & 0 deletions src/pages/Game/_game.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@
filter: drop-shadow(16px 16px 20px red);
}

.myCards {
border-style: solid;
border-width: 5px;
border-radius: 10px;
padding: 2px;
}

// .carpet {
// background-image: url("/assets/img/carpet2.jpg");
// }
Expand Down

0 comments on commit 2372a94

Please sign in to comment.