mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 02:37:05 +02:00
fix: last and next checking
This commit is contained in:
1 parent
f56c31fb48
commit
8b527f2333
6 files changed
+40
-27
No files matched your search
@@ -2,10 +2,6 @@ import { produce } from "immer";
|
||||
import { merge } from "lodash-es";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
interface ProviderProps<Arguments> {
|
||||
args: Arguments;
|
||||
}
|
||||
|
||||
export class Varuna<Type, Arguments = void> {
|
||||
private listeners = new Set<(state: Type) => void>();
|
||||
|
||||
@@ -53,11 +49,15 @@ export class Varuna<Type, Arguments = void> {
|
||||
}
|
||||
|
||||
on<Slice>(slicer: (state: Type) => Slice, callback: (state: Slice) => void) {
|
||||
const last = slicer(this.state);
|
||||
let last = slicer(this.state);
|
||||
|
||||
function listener(state: Type) {
|
||||
const next = slicer(state);
|
||||
if (next !== last) callback(next);
|
||||
|
||||
if (next !== last) {
|
||||
callback(next);
|
||||
last = next;
|
||||
}
|
||||
}
|
||||
|
||||
this.listeners.add(listener);
|
||||
@@ -94,8 +94,11 @@ export class Varuna<Type, Arguments = void> {
|
||||
use<Slice = Type>(
|
||||
slicer: (state: Type) => Slice = (state) => state as unknown as Slice
|
||||
) {
|
||||
const instance = this;
|
||||
const [slice, setSlice] = useState(slicer(this.state));
|
||||
useEffect(() => this.on(slicer, setSlice), []);
|
||||
|
||||
useEffect(() => instance.on(slicer, setSlice), []);
|
||||
|
||||
return slice;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import { awaitableProvisionDefinitions } from "../../core/awaitables/provisionDe
|
||||
import { tankToDuelMember } from "../../core/blitzkit/tankToDuelMember";
|
||||
import { Var } from "../../core/radix/var";
|
||||
import { Duel } from "../../stores/duel";
|
||||
import { Guess } from "../../stores/guessEphemeral";
|
||||
import { Guess, GuessState } from "../../stores/guessEphemeral";
|
||||
import { TankopediaEphemeral } from "../../stores/tankopediaEphemeral";
|
||||
import "./index.css";
|
||||
|
||||
@@ -39,9 +39,9 @@ export function GuessBackground() {
|
||||
style={{
|
||||
transitionDuration: "2s",
|
||||
backgroundColor: Var(
|
||||
guessState === null
|
||||
guessState === GuessState.NotGuessed
|
||||
? "accent-2"
|
||||
: guessState
|
||||
: guessState === GuessState.Correct
|
||||
? "jade-3"
|
||||
: "tomato-3"
|
||||
),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Guess } from "../stores/guessEphemeral";
|
||||
import { Guess, GuessState } from "../stores/guessEphemeral";
|
||||
import { SmartCanvas } from "./SmartCanvas";
|
||||
import { Controls } from "./Tankopedia/HeroSection/components/TankSandbox/components/Control";
|
||||
import { Lighting } from "./Tankopedia/HeroSection/components/TankSandbox/components/Lighting";
|
||||
@@ -9,7 +9,7 @@ const CONTRAST = 2 ** 2;
|
||||
|
||||
export function GuessRenderer() {
|
||||
const guessState = Guess.use((state) => state.guessState);
|
||||
const isRevealed = guessState !== null;
|
||||
const isRevealed = guessState !== GuessState.NotGuessed;
|
||||
|
||||
return (
|
||||
<SmartCanvas
|
||||
|
||||
@@ -24,7 +24,7 @@ import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { awaitableTankDefinitions } from "../core/awaitables/tankDefinitions";
|
||||
import { awaitableTankNames } from "../core/awaitables/tankNames";
|
||||
import { useLocale } from "../hooks/useLocale";
|
||||
import { Guess } from "../stores/guessEphemeral";
|
||||
import { Guess, GuessState } from "../stores/guessEphemeral";
|
||||
import { classIcons } from "./ClassIcon";
|
||||
import { SearchResults } from "./SearchResults";
|
||||
|
||||
@@ -78,7 +78,7 @@ export function Guesser() {
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (guessState !== null) setSelected(null);
|
||||
if (guessState !== GuessState.NotGuessed) setSelected(null);
|
||||
}, [guessState]);
|
||||
|
||||
return (
|
||||
@@ -148,7 +148,7 @@ export function Guesser() {
|
||||
|
||||
<Flex gap="3">
|
||||
<TextField.Root
|
||||
disabled={guessState !== null}
|
||||
disabled={guessState !== GuessState.NotGuessed}
|
||||
ref={input}
|
||||
onChange={requestSearch}
|
||||
style={{ flex: 1 }}
|
||||
@@ -163,13 +163,19 @@ export function Guesser() {
|
||||
|
||||
<Button
|
||||
size="3"
|
||||
color={guessState === null && selected === null ? "red" : undefined}
|
||||
color={
|
||||
guessState === GuessState.NotGuessed && selected === null
|
||||
? "red"
|
||||
: undefined
|
||||
}
|
||||
onClick={() => {
|
||||
if (guessState === null) {
|
||||
if (guessState === GuessState.NotGuessed) {
|
||||
const correct = selected !== null && selected.id === tank.id;
|
||||
|
||||
Guess.mutate((draft) => {
|
||||
draft.guessState = correct;
|
||||
draft.guessState = correct
|
||||
? GuessState.Correct
|
||||
: GuessState.Incorrect;
|
||||
draft.totalGuesses++;
|
||||
draft.correctGuesses += correct ? 1 : 0;
|
||||
});
|
||||
@@ -181,13 +187,14 @@ export function Guesser() {
|
||||
if (!input.current) return;
|
||||
|
||||
draft.tank = tank;
|
||||
draft.guessState = null;
|
||||
draft.guessState = GuessState.NotGuessed;
|
||||
|
||||
input.current.value = "";
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
{guessState === null ? (
|
||||
{guessState === GuessState.NotGuessed ? (
|
||||
<>
|
||||
{
|
||||
strings.website.tools.guess.search[
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
useLocale,
|
||||
} from "../../../hooks/useLocale";
|
||||
import { Duel } from "../../../stores/duel";
|
||||
import { Guess } from "../../../stores/guessEphemeral";
|
||||
import { Guess, GuessState } from "../../../stores/guessEphemeral";
|
||||
import { TankopediaEphemeral } from "../../../stores/tankopediaEphemeral";
|
||||
|
||||
const [tankDefinitions, modelDefinitions, provisionDefinitions] =
|
||||
@@ -55,7 +55,7 @@ function Content() {
|
||||
const { unwrap } = useLocale();
|
||||
const tank = Guess.use((state) => state.tank);
|
||||
const guessState = Guess.use((state) => state.guessState);
|
||||
const isRevealed = guessState !== null;
|
||||
const isRevealed = guessState !== GuessState.NotGuessed;
|
||||
const name = unwrap(tank.name);
|
||||
const fontSize = `min(48vh, ${55 / name.length}vw)`;
|
||||
const transitionDuration = isRevealed ? "2s" : undefined;
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
import type { TankDefinition } from "@blitzkit/core";
|
||||
import { Varuna } from "varuna";
|
||||
|
||||
export enum GuessState {
|
||||
Correct,
|
||||
Incorrect,
|
||||
NotGuessed,
|
||||
}
|
||||
|
||||
export interface Guess {
|
||||
tank: TankDefinition;
|
||||
/**
|
||||
* true = correct, false = incorrect, null = not guessed
|
||||
*/
|
||||
guessState: boolean | null;
|
||||
guessState: GuessState;
|
||||
totalGuesses: number;
|
||||
correctGuesses: number;
|
||||
}
|
||||
|
||||
export const Guess = new Varuna<Guess, TankDefinition>((tank) => ({
|
||||
tank,
|
||||
guessState: null,
|
||||
guessState: GuessState.NotGuessed,
|
||||
totalGuesses: 0,
|
||||
correctGuesses: 0,
|
||||
}));
|
||||
Reference in new issue
Block a user