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