Skip to content

Commit

Permalink
refactor current guess ID to game state
Browse files Browse the repository at this point in the history
  • Loading branch information
Artemis21 committed Feb 11, 2024
1 parent 23eb19b commit 8095bc5
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 41 deletions.
1 change: 1 addition & 0 deletions src/game/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ async fn new_game(
}
track::pick::daily(&mut tx).await?
} else if let Some(genre_id) = body.genre_id {
// FIXME: avoid picking tracks the user has already played
track::pick::genre(&mut tx, genre_id).await?
} else {
track::pick::any(&mut tx).await?
Expand Down
9 changes: 7 additions & 2 deletions web/components/Game.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@ import { GameOver } from "./GameOver";
import { useNavigate, useParams } from "react-router-dom";
import { useState } from "react";

export type GuessQuery = {
query: string;
id: number | null;
}

export function Game() {
const { gameId } = useParams();
const { data, error } = useGame(Number(gameId));
const navigate = useNavigate();
// the text the user has entered in the guess input
const [guessQuery, setGuessQuery] = useState("");
const [guess, setGuess] = useState<GuessQuery>({ query: "", id: null });
if (error) return <Error error={error} />;
if (data === undefined) return <Loading />;
if (data === null) {
Expand All @@ -21,7 +26,7 @@ export function Game() {
let game;
if (data.won === null) {
game = (
<Guesses game={data} guessQuery={guessQuery} setGuessQuery={setGuessQuery} />
<Guesses game={data} guessQuery={guess} setGuessQuery={setGuess} />
);
} else {
game = <GameOver game={data} />;
Expand Down
13 changes: 7 additions & 6 deletions web/components/Guess.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Card } from "./Card";
import { TrackCard } from "./TrackCard";
import { useTimer } from "../utils";
import { useCallback, useEffect } from "react";
import { GuessQuery } from "./Game";

export function WrongGuess({ track }: { track: Track }) {
return <TrackCard track={track} bad />;
Expand All @@ -25,13 +26,13 @@ export function EmptyGuess() {
export function NewGuess({
gameId,
timedGuess,
guessQuery,
setGuessQuery,
guess,
setGuess,
}: {
gameId: number;
timedGuess: GuessTiming | null;
guessQuery: string;
setGuessQuery: (q: string) => void;
guess: GuessQuery;
setGuess: (q: GuessQuery) => void;
}) {
const time = useTimer(20);
// We have to `useCallback` because otherwise `invalidateGame` is a new
Expand All @@ -58,8 +59,8 @@ export function NewGuess({
<SongSearch
gameId={gameId}
inputId="new_guess"
query={guessQuery}
setQuery={setGuessQuery}
guess={guess}
setGuess={setGuess}
/>
);
return (
Expand Down
9 changes: 5 additions & 4 deletions web/components/Guesses.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Game } from "../api";
import { GuessQuery } from "./Game";
import { WrongGuess, SkippedGuess, EmptyGuess, NewGuess } from "./Guess";
import { Scrollable } from "./Scrollable";

Expand All @@ -8,8 +9,8 @@ export function Guesses({
setGuessQuery,
}: {
game: Game;
guessQuery: string;
setGuessQuery: (q: string) => void;
guessQuery: GuessQuery;
setGuessQuery: (q: GuessQuery) => void;
}) {
const guessEls = [];
for (let n = 0; n < constants.maxGuesses; n++) {
Expand All @@ -26,8 +27,8 @@ export function Guesses({
key={n}
gameId={id}
timedGuess={timedGuess}
guessQuery={guessQuery}
setGuessQuery={setGuessQuery}
guess={guessQuery}
setGuess={setGuessQuery}
/>,
);
} else {
Expand Down
57 changes: 28 additions & 29 deletions web/components/SongSearch.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
import { useEffect, useState } from "react";
import { Track, searchTracks, useNewGuess } from "../api";
import { useThrottled, classModifiers } from "../utils";
import { GuessQuery } from "./Game";

export function SongSearch({
gameId,
inputId,
query,
setQuery,
guess,
setGuess,
}: {
gameId: number;
inputId: string;
query: string;
setQuery: (q: string) => void;
guess: GuessQuery;
setGuess: (q: GuessQuery) => void;
}) {
const debouncedQ = useThrottled(query, 500);
const [id, setId] = useState<number | null>(null);
const debouncedQ = useThrottled(guess.query, 500);
const [active, setActive] = useState(false);
const [tracks, setTracks] = useState<Track[] | undefined>(undefined);
const [error, setError] = useState<object | null>(null);
useEffect(() => {
if (id === null && debouncedQ !== "") {
if (guess.id === null && debouncedQ !== "") {
let cancelled = false;
searchTracks(debouncedQ)
.then(data => cancelled || setTracks(data.tracks))
Expand All @@ -28,27 +28,29 @@ export function SongSearch({
cancelled = true;
};
}
}, [debouncedQ, id]);
}, [debouncedQ, guess]);
let results;
if (!active || query === "" || id !== null) {
if (!active || guess.query === "" || guess.id !== null) {
results = null;
} else if (error) {
results = <SearchResultsPlaceholder message={error.toString()} />;
} else if (tracks === undefined || (tracks.length === 0 && query !== debouncedQ)) {
} else if (
tracks === undefined ||
(tracks.length === 0 && guess.query !== debouncedQ)
) {
results = <SearchResultsPlaceholder message="Loading..." />;
} else if (tracks.length === 0) {
results = <SearchResultsPlaceholder message="No results found." />;
} else {
results = <SearchResults tracks={tracks} setQ={setQuery} setId={setId} />;
results = <SearchResults tracks={tracks} setGuess={setGuess} />;
}
let button;
if (id === null) {
button = (
<GuessButton gameId={gameId} guess={null} afterSubmit={() => setQuery("")} />
);
const resetGuess = () => setGuess({ query: "", id: null });
if (guess.id === null) {
button = <GuessButton gameId={gameId} guess={null} afterSubmit={resetGuess} />;
} else {
button = (
<GuessButton gameId={gameId} guess={id} afterSubmit={() => setQuery("")} />
<GuessButton gameId={gameId} guess={guess.id} afterSubmit={resetGuess} />
);
}
return (
Expand All @@ -58,13 +60,15 @@ export function SongSearch({
className="input"
type="search"
placeholder="Title or artist..."
onChange={e => {
setId(null);
setQuery(e.target.value);
}}
onChange={e =>
setGuess({
query: e.target.value,
id: null,
})
}
onFocus={() => setActive(true)}
onBlur={() => setActive(false)}
value={query}
value={guess.query}
id={inputId}
/>
{results}
Expand All @@ -76,21 +80,16 @@ export function SongSearch({

function SearchResults({
tracks,
setQ,
setId,
setGuess,
}: {
tracks: Track[];
setQ: (q: string) => void;
setId: (id: number) => void;
setGuess: (q: GuessQuery) => void;
}) {
return (
<div className="search__results">
{tracks.map(track => {
const displayName = `${track.title} - ${track.artistName}`;
const click = () => {
setId(track.id);
setQ(displayName);
};
const click = () => setGuess({ query: displayName, id: track.id });
return (
<button
className="search__results__result"
Expand Down
1 change: 1 addition & 0 deletions web/sass/card.sass
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@
bottom: 0
left: 0
border-radius: 1rem
pointer-events: none
background: #0002

.card__icon
Expand Down

0 comments on commit 8095bc5

Please sign in to comment.