Skip to content

Commit

Permalink
Various UX improvements (#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
RheingoldRiver authored Oct 29, 2023
1 parent 6445365 commit 89174bc
Show file tree
Hide file tree
Showing 14 changed files with 200 additions and 106 deletions.
17 changes: 9 additions & 8 deletions src/components/Board/Board.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from "@heroicons/react/24/outline";
import { OrientabilityType, SURFACES } from "../../constants";
import { ChevronDoubleUpIcon } from "@heroicons/react/20/solid";
import { BoardGrid } from "../Grid/BoardGrid";

export const Board = forwardRef(({ gridArea }: { gridArea: string }, ref) => {
const { paintedGrid, surface } = useContext(GameStateContext);
Expand Down Expand Up @@ -59,14 +60,14 @@ export const Board = forwardRef(({ gridArea }: { gridArea: string }, ref) => {
}[surface.orientability.w]
}
</div>
<Grid
paintedGrid={paintedGrid}
gridArea="grid"
borderColor={darkMode ? "#F3F4F6" : "white"}
pentominoSize={appPreferences.pentominoSize}
board={true}
ref={ref}
></Grid>
<BoardGrid paintedGrid={paintedGrid} gridArea="grid" ref={ref}>
<Grid
paintedGrid={paintedGrid}
borderColor={darkMode ? "#F3F4F6" : "white"}
pentominoSize={appPreferences.pentominoSize}
board={true}
/>
</BoardGrid>
</div>
);
});
3 changes: 1 addition & 2 deletions src/components/DarkModeButton/DarkModeButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ export const DarkModeButton = () => {
const ChangeIcon = darkMode === true ? SunIcon : MoonIcon;
return (
<ChangeIcon
className="cursor-pointer"
width={25}
className="cursor-pointer h-10 w-10 text-gray-800 dark:text-gray-300"
onClick={() => {
updateDarkMode(!darkMode);
}}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Game/Game.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const GameContent = () => {
<Wordmark gridArea="wordmark" />
<Header style={{ gridArea: "header" }}></Header>
<div
className="flex flex-row items-start justify-end w-full h-full pr-2 gap-1 max-w-[100vw]"
className="flex flex-row items-start justify-end w-full h-full pr-2 gap-2 max-w-[100vw]"
style={{ gridArea: "settings" }}
>
<Settings></Settings>
Expand Down
62 changes: 40 additions & 22 deletions src/components/GameStateProvider/GameStateProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
orientationReducer,
} from "./currentPentominoReducer";
import { DEFAULT_GAME_PREFERENCES } from "./gameConstants";
import { produce } from "immer";

interface GameState {
grid: PlacedPentomino[][];
Expand All @@ -62,6 +63,8 @@ interface GameState {
setShowInvalidUrlError: Dispatch<SetStateAction<boolean>>;
defaultRandomColors: boolean;
updateDefaultRandomColors: (newDefault: boolean) => void;
defaultAddTerrain: boolean;
updateDefaultAddTerrain: (newDefault: boolean) => void;
}

const DEFAULT_GAME_STATE: GameState = {
Expand All @@ -87,6 +90,8 @@ const DEFAULT_GAME_STATE: GameState = {
setShowInvalidUrlError: () => {},
defaultRandomColors: false,
updateDefaultRandomColors: () => {},
defaultAddTerrain: true,
updateDefaultAddTerrain: () => {},
};

export const GameStateContext = createContext(DEFAULT_GAME_STATE);
Expand All @@ -97,7 +102,12 @@ export default function GameStateProvider({ children }: { children: ReactNode })

const [defaultRandomColors, setDefaultRandomColors] = useState<boolean>(() => {
return (
(window.localStorage.getItem("randc") || DEFAULT_GAME_PREFERENCES.showKeyboardIndicators.toString()) === "true"
(window.localStorage.getItem("randc") ?? DEFAULT_GAME_PREFERENCES.showKeyboardIndicators.toString()) === "true"
);
});
const [defaultAddTerrain, setDefaultAddTerrain] = useState<boolean>(() => {
return (
(window.localStorage.getItem("initterrain") ?? DEFAULT_GAME_PREFERENCES.defaultAddTerrain.toString()) === "true"
);
});

Expand All @@ -108,6 +118,16 @@ export default function GameStateProvider({ children }: { children: ReactNode })
useEffect(() => {
if (!config) {
if (defaultRandomColors) setPentominoColors(randomPentominoColors(PENTOMINO_NAMES.length));
if (defaultAddTerrain) {
setGrid(
produce(grid, (draftGrid) => {
draftGrid[0][0].pentomino = PENTOMINOES.R;
draftGrid[0][7].pentomino = PENTOMINOES.R;
draftGrid[7][0].pentomino = PENTOMINOES.R;
draftGrid[7][7].pentomino = PENTOMINOES.R;
})
);
}
return;
}
try {
Expand Down Expand Up @@ -209,32 +229,23 @@ export default function GameStateProvider({ children }: { children: ReactNode })

function drawPentomino(newX: number, newY: number) {
recordActionHistory(newX, newY);
const newGrid = [...grid];
newGrid[newX][newY] = {
pentomino: currentPentomino,
orientation: { ...currentOrientation },
coordinates: { x: newX, y: newY },
};
setGrid(newGrid);
setGrid(
produce(grid, (draftGrid) => {
draftGrid[newX][newY] = {
pentomino: currentPentomino,
orientation: { ...currentOrientation },
coordinates: { x: newX, y: newY },
};
})
);
}
function erasePentomino(givenX: number, givenY: number) {
recordActionHistory(givenX, givenY);
const newGrid = grid.map((row, x) =>
row.map((c, y) => {
if (x === givenX && y === givenY) {
return {
pentomino: PENTOMINOES.None,
orientation: {
reflection: 0,
rotation: 0,
},
coordinates: { x, y },
};
}
return c;
setGrid(
produce(grid, (draftGrid) => {
draftGrid[givenX][givenY].pentomino = PENTOMINOES.None;
})
);
setGrid(newGrid);
}

function clearGrid(preserveTerrain: boolean) {
Expand Down Expand Up @@ -289,6 +300,11 @@ export default function GameStateProvider({ children }: { children: ReactNode })
setDefaultRandomColors(newDefault);
};

const updateDefaultAddTerrain = (newDefault: boolean) => {
window.localStorage.setItem("initterrain", newDefault.toString());
setDefaultAddTerrain(newDefault);
};

useHotkey("Control", "Z", () => {
const nextActionHistory = [...actionHistory];
const lastAction = nextActionHistory.pop();
Expand Down Expand Up @@ -386,6 +402,8 @@ export default function GameStateProvider({ children }: { children: ReactNode })
setShowInvalidUrlError,
defaultRandomColors,
updateDefaultRandomColors,
defaultAddTerrain,
updateDefaultAddTerrain,
}}
>
{children}
Expand Down
1 change: 1 addition & 0 deletions src/components/GameStateProvider/gameConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export interface GamePreferences {
export const DEFAULT_GAME_PREFERENCES = {
showKeyboardIndicators: false,
defaultRandomColors: false,
defaultAddTerrain: true,
};
36 changes: 36 additions & 0 deletions src/components/Grid/BoardGrid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { PaintedCell, SURFACES } from "../../constants";
import clsx from "clsx";
import { ReactNode, RefObject, forwardRef, memo, useContext } from "react";
import { GameStateContext } from "../GameStateProvider/GameStateProvider";

export const BoardGrid = memo(
forwardRef(
(
{
paintedGrid,
gridArea,
children,
}: {
paintedGrid: PaintedCell[][];
gridArea: string;
children: ReactNode;
},
ref
) => {
const { surface } = useContext(GameStateContext);
return (
<div
className={clsx("grid grid-flow-row w-fit h-fit")}
style={{
gridTemplateRows: `repeat(${paintedGrid.length}, minmax(0, 1fr))`,
gridTemplateColumns: `repeat(${paintedGrid[0].length}, minmax(0, 1fr))`,
gridArea,
}}
ref={surface.name === SURFACES.Rectangle.name ? (ref as RefObject<HTMLDivElement>) : undefined}
>
{children}
</div>
);
}
)
);
81 changes: 30 additions & 51 deletions src/components/Grid/Grid.tsx
Original file line number Diff line number Diff line change
@@ -1,53 +1,32 @@
import { PaintedCell, SURFACES } from "../../constants";
import { PaintedCell } from "../../constants";
import { Cell } from "../Cell/Cell";
import clsx from "clsx";
import { RefObject, forwardRef, memo, useContext } from "react";
import { GameStateContext } from "../GameStateProvider/GameStateProvider";

const GridComponent = forwardRef(
(
{
paintedGrid,
pentominoSize,
gridArea,
borderColor = "white",
board = false,
}: {
paintedGrid: PaintedCell[][];
pentominoSize: number;
gridArea?: string;
borderColor?: string;
board?: boolean;
},
ref
) => {
const { surface } = useContext(GameStateContext);
return (
<div
className={clsx("grid grid-flow-row w-fit h-fit")}
style={{
gridTemplateRows: `repeat(${paintedGrid.length}, minmax(0, 1fr))`,
gridTemplateColumns: `repeat(${paintedGrid[0].length}, minmax(0, 1fr))`,
gridArea,
}}
ref={surface.name === SURFACES.Rectangle.name ? (ref as RefObject<HTMLDivElement>) : undefined}
>
{paintedGrid.map((r, x) =>
r.map((c, y) => (
<Cell
key={`cell-${x}_${y}`}
cell={c}
x={x}
y={y}
pentominoSize={pentominoSize}
borderColor={borderColor}
board={board}
></Cell>
))
)}
</div>
);
}
);

export const Grid = memo(GridComponent);
export const Grid = ({
paintedGrid,
pentominoSize,
borderColor = "white",
board = false,
}: {
paintedGrid: PaintedCell[][];
pentominoSize: number;
borderColor?: string;
board?: boolean;
}) => {
return (
<>
{paintedGrid.map((r, x) =>
r.map((c, y) => (
<Cell
key={`cell-${x}_${y}`}
cell={c}
x={x}
y={y}
pentominoSize={pentominoSize}
borderColor={borderColor}
board={board}
></Cell>
))
)}
</>
);
};
29 changes: 29 additions & 0 deletions src/components/Grid/InfoGrid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { PlacedPentomino } from "../../constants";
import clsx from "clsx";
import { ReactNode, memo, useContext } from "react";
import { GameStateContext } from "../GameStateProvider/GameStateProvider";
import { PENTOMINOES } from "../../pentominoes";

export const InfoGrid = memo(({ grid, children }: { grid: PlacedPentomino[][]; children: ReactNode }) => {
const { setGrid } = useContext(GameStateContext);
return (
<div
className={clsx("grid grid-flow-row w-fit h-fit cursor-pointer")}
style={{
gridTemplateRows: `repeat(${grid.length}, minmax(0, 1fr))`,
gridTemplateColumns: `repeat(${grid[0].length}, minmax(0, 1fr))`,
}}
onClick={() => {
let gridIsEmpty = true;
grid.forEach((row) =>
row.forEach((cell) => {
if (cell.pentomino.name !== PENTOMINOES.None.name) gridIsEmpty = false;
})
);
if (gridIsEmpty || confirm("Reset your board? You won't be able to undo.")) setGrid(grid);
}}
>
{children}
</div>
);
});
Loading

0 comments on commit 89174bc

Please sign in to comment.