Skip to content

Commit

Permalink
Merge pull request #39 from JollyGrin/feat/flip-enemycard
Browse files Browse the repository at this point in the history
Feat/flip enemycard
  • Loading branch information
JollyGrin authored Sep 29, 2024
2 parents 403fcb0 + 91d942f commit c0862ac
Show file tree
Hide file tree
Showing 9 changed files with 307 additions and 14 deletions.
21 changes: 16 additions & 5 deletions src/components/atoms/mock-cards/atlas.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { CARD_CDN } from "@/components/organisms/GameBoard/constants";
import {
CARD_CDN,
LOCALSTORAGE_KEYS,
} from "@/components/organisms/GameBoard/constants";
import { useLocalStorage } from "@/utils/hooks";
import { Box } from "styled-system/jsx";

export const CardAtlas = ({
Expand All @@ -10,6 +14,14 @@ export const CardAtlas = ({
height?: string;
isMine?: boolean;
}) => {
const { key, ...options } = LOCALSTORAGE_KEYS.SETTINGS.rotateEnemy;
const [rotateEnemy] = useLocalStorage(key, false, options);

const isMe = props.isMine === undefined || !!props.isMine;
function shouldRotate() {
if (rotateEnemy === false) return "rotate(0deg)";
return isMe ? "rotate(0deg)" : "rotate(180deg)";
}
return (
<Box
position="relative"
Expand All @@ -20,12 +32,11 @@ export const CardAtlas = ({
borderRadius="1rem"
isolation="isolate"
overflow="clip"
transition="all 0.25s ease"
style={{
height,
border:
props.isMine === undefined || !!props.isMine
? ""
: "solid 2px tomato",
border: isMe ? "" : "solid 2px tomato",
transform: shouldRotate(),
}}
>
<Box
Expand Down
22 changes: 17 additions & 5 deletions src/components/atoms/mock-cards/card.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { CARD_CDN } from "@/components/organisms/GameBoard/constants";
import {
CARD_CDN,
LOCALSTORAGE_KEYS,
} from "@/components/organisms/GameBoard/constants";
import { useLocalStorage } from "@/utils/hooks";
import { useHover } from "@/utils/hooks/useHover";
import { useKeyPress } from "@/utils/hooks/useKeyPress";
import { useEffect, useRef, useState } from "react";
Expand All @@ -23,6 +27,11 @@ export const CardImage = ({
const hoverRef = useRef(null);
const isHovering = useHover(hoverRef);

const { key, ...options } = LOCALSTORAGE_KEYS.SETTINGS.rotateEnemy;
const [rotateEnemy, setRotateEnemy] = useLocalStorage(key, false, options);

console.log("card", { rotateEnemy });

const isPressed = useKeyPress("Alt");
const [preview, setPreview] = useState(false);
useEffect(() => {
Expand All @@ -32,6 +41,11 @@ export const CardImage = ({
}, [isPressed]);

const show = props.show || (preview && isHovering);
const isMe = props.isMine === undefined || !!props.isMine;
function shouldRotate() {
if (rotateEnemy === false) return "rotate(0deg)";
return isMe ? "rotate(0deg)" : "rotate(180deg)";
}

return (
<Box
Expand All @@ -53,10 +67,8 @@ export const CardImage = ({
onMouseOut={() => setPreview(false)}
style={{
height,
border:
props.isMine === undefined || !!props.isMine
? ""
: "solid 2px tomato",
transform: shouldRotate(),
border: isMe ? "" : "solid 2px tomato",
}}
>
<Box
Expand Down
6 changes: 4 additions & 2 deletions src/components/molecules/CommandModal/Command.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import {
ActDrawDeckTop,
ActionIds,
ActionRollDice,
ActRotateEnemyCards,
ActScryX,
ViewCemetary,
ActViewCemetary,
} from "./Commands";
import { PlayerDataProps } from "@/types/card";

Expand Down Expand Up @@ -36,7 +37,8 @@ export const Command = (props: GameStateActions & PlayerDataProps) => {
if (id === "scry_x") return <ActScryX {...props} deckType="deck" />;
if (id === "scry_x_atlas")
return <ActScryX {...props} deckType="atlas" />;
if (id === "view_cemetary") return <ViewCemetary />;
if (id === "view_cemetary") return <ActViewCemetary />;
if (id === "rotate_enemy") return <ActRotateEnemyCards />;

return <Box>No action setup</Box>;
}}
Expand Down
49 changes: 47 additions & 2 deletions src/components/molecules/CommandModal/Commands.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
getCardImage,
GRIDS,
initGameData,
LOCALSTORAGE_KEYS,
} from "@/components/organisms/GameBoard/constants";
import { Button } from "@/components/ui/button";
import { PlayerDataProps } from "@/types/card";
Expand All @@ -14,9 +15,12 @@ import {
import { useRouter } from "next/router";
import { useState } from "react";
import { css } from "styled-system/css";
import { Box, Flex, HStack, VStack } from "styled-system/jsx";
import { Box, Flex, Grid, HStack, VStack } from "styled-system/jsx";
import { input } from "styled-system/recipes";
import { GiPirateGrave as IconGrave } from "react-icons/gi";
import { useLocalStorage } from "@/utils/hooks";
import { CardImage } from "@/components/atoms/mock-cards/card";
import { CardAtlas } from "@/components/atoms/mock-cards/atlas";

export const actions = [
{
Expand Down Expand Up @@ -47,6 +51,10 @@ export const actions = [
value: "view_cemetary",
label: "View enemy cemetary",
},
{
value: "rotate_enemy",
label: "Rotate enemy cards on grid",
},
] as const;
export type ActionIds = (typeof actions)[number]["value"];

Expand Down Expand Up @@ -176,7 +184,7 @@ export const ActScryX = ({
);
};

export const ViewCemetary = () => {
export const ActViewCemetary = () => {
return (
<Box>
<p>To view an enemy cemetary:</p>
Expand All @@ -188,3 +196,40 @@ export const ViewCemetary = () => {
</Box>
);
};

export const ActRotateEnemyCards = () => {
const { key, ...options } = LOCALSTORAGE_KEYS.SETTINGS.rotateEnemy;
const [rotateEnemy, setRotateEnemy] = useLocalStorage(key, false, options);

return (
<Box>
<p>Rotate the enemy cards on the board.</p>
<Box
className={css({
bg: "rgba(0,100,200,0.1)",
padding: "1rem",
border: "solid 2px",
borderColor: "rgba(0,100,200,0.3)",
borderRadius: "0.25rem",
})}
>
<p>The ordering (top to bottom) remains the same.</p>
<p>Visually each enemy card will be flipped.</p>
<p>Keep this in mind when ordering.</p>
</Box>
<Grid gridTemplateColumns="1fr 1fr" mt="2rem">
<Box>
<p>Rotate enemy: {`${rotateEnemy}`}</p>
<Button onClick={() => setRotateEnemy(!rotateEnemy)}>
Rotate enemy card
</Button>
</Box>

<VStack>
<CardImage img={"autumn_unicorn"} isMine={false} />
<CardAtlas img={"windmill"} isMine={false} />
</VStack>
</Grid>
</Box>
);
};
10 changes: 10 additions & 0 deletions src/components/organisms/GameBoard/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ export enum GRIDS {
GRAVE,
}

export const LOCALSTORAGE_KEYS = {
SETTINGS: {
rotateEnemy: {
key: "SETTINGS:ROTATE_ENEMY",
serializer: (bool: boolean) => `${bool}`,
deserializer: (string: string) => string === "true",
},
},
};

/**
* Length of hand, deck, deck-atlas, and grave (4)
* used to splice playerstate from global state
Expand Down
5 changes: 5 additions & 0 deletions src/utils/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from "./useIsomorphicLayoutEffect";
export * from "./useEventCallback";
export * from "./useEventListener";
export * from "./useLocalStorage";
export * from "./useCopy";
24 changes: 24 additions & 0 deletions src/utils/hooks/useEventCallback.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { useCallback, useRef } from "react";
import { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect";

export function useEventCallback<Args extends unknown[], R>(
fn: (...args: Args) => R,
): (...args: Args) => R;
export function useEventCallback<Args extends unknown[], R>(
fn: ((...args: Args) => R) | undefined,
): ((...args: Args) => R) | undefined;
export function useEventCallback<Args extends unknown[], R>(
fn: ((...args: Args) => R) | undefined,
): ((...args: Args) => R) | undefined {
const ref = useRef<typeof fn>(() => {
throw new Error("Cannot call an event handler while rendering.");
});

useIsomorphicLayoutEffect(() => {
ref.current = fn;
}, [fn]);

return useCallback((...args: Args) => ref.current?.(...args), [ref]) as (
...args: Args
) => R;
}
4 changes: 4 additions & 0 deletions src/utils/hooks/useIsomorphicLayoutEffect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { useEffect, useLayoutEffect } from "react";

export const useIsomorphicLayoutEffect =
typeof window !== "undefined" ? useLayoutEffect : useEffect;
Loading

0 comments on commit c0862ac

Please sign in to comment.