This commit is contained in:
Miodec 2026-01-08 19:48:56 +01:00
parent ec0e15efd7
commit a86c2f186a
9 changed files with 121 additions and 108 deletions

View file

@ -0,0 +1,15 @@
import { render } from "solid-js/web";
import { qsr } from "../utils/dom";
import { LiveStats, LiveStatsMini } from "./test/LiveStats";
import { getAcc, getBurst, getWpm } from "../signals/test";
export function mountComponents(): void {
render(
() => <LiveStatsMini wpm={getWpm} acc={getAcc} burst={getBurst} />,
qsr("#liveStatsMini").native,
);
render(
() => <LiveStats wpm={getWpm} acc={getAcc} burst={getBurst} />,
qsr("#liveStatsTextBottom").native,
);
}

View file

@ -0,0 +1,95 @@
import { Accessor, createSignal, JSXElement } from "solid-js";
import {
getLiveAccStyle,
getLiveBurstStyle,
getLiveSpeedStyle,
} from "../../signals/config";
import { isFocused } from "../../test/focus";
import {
useVisibilityAnimation,
VisibilityAnimationOptions,
} from "../../hooks/useVisibilityAnimation";
import { useRefWithUtils } from "../../hooks/useRefWithUtils";
export function Stat(props: {
value: Accessor<string>;
visibilityOptions: Accessor<VisibilityAnimationOptions>;
class?: string;
}): JSXElement {
const [ref, element] = useRefWithUtils<HTMLDivElement>();
useVisibilityAnimation(element, props.visibilityOptions);
return (
<div ref={ref} class={props.class}>
{props.value()}
</div>
);
}
const [miniStatsVisible, setMiniStatsVisible] =
createSignal<VisibilityAnimationOptions>({
visible: false,
animate: true,
});
const getStatsVisible = (): VisibilityAnimationOptions => {
return {
visible: miniStatsVisible().visible && isFocused(),
animate: miniStatsVisible().animate,
};
};
export { setMiniStatsVisible as setStatsVisible };
export function LiveStatsMini(props: {
wpm: Accessor<string>;
acc: Accessor<string>;
burst: Accessor<string>;
}): JSXElement {
return (
<>
<Stat
class="speed"
value={() => (getLiveSpeedStyle() === "mini" ? props.wpm() : "")}
visibilityOptions={getStatsVisible}
/>
<Stat
class="acc"
value={() => (getLiveAccStyle() === "mini" ? props.acc() : "")}
visibilityOptions={getStatsVisible}
/>
<Stat
class="burst"
value={() => (getLiveBurstStyle() === "mini" ? props.burst() : "")}
visibilityOptions={getStatsVisible}
/>
</>
);
}
export function LiveStats(props: {
wpm: Accessor<string>;
acc: Accessor<string>;
burst: Accessor<string>;
}): JSXElement {
return (
<>
<Stat
class="liveSpeed"
value={() => (getLiveSpeedStyle() === "text" ? props.wpm() : "")}
visibilityOptions={getStatsVisible}
/>
<Stat
class="liveAcc"
value={() => (getLiveAccStyle() === "text" ? props.acc() : "")}
visibilityOptions={getStatsVisible}
/>
<Stat
class="liveBurst"
value={() => (getLiveBurstStyle() === "text" ? props.burst() : "")}
visibilityOptions={getStatsVisible}
/>
</>
);
}

View file

@ -1,80 +0,0 @@
import { createSignal } from "solid-js";
import { qsr } from "../../utils/dom";
import { LiveCounter } from "../../test/live-counter";
import { render } from "solid-js/web";
import {
getLiveAccStyle,
getLiveBurstStyle,
getLiveSpeedStyle,
} from "../../signals/config";
import { isFocused } from "../../test/focus";
import { VisibilityAnimationOptions } from "../../hooks/useVisibilityAnimation";
const [getWpm, setLiveStatWpm] = createSignal("0");
const [getAcc, setLiveStatAcc] = createSignal("100%");
const [getBurst, setLiveStatBurst] = createSignal("0");
const [statsVisible, setStatsVisible] =
createSignal<VisibilityAnimationOptions>({
visible: false,
animate: true,
});
const getStatsVisible = (): VisibilityAnimationOptions => {
return {
visible: statsVisible().visible && isFocused(),
animate: statsVisible().animate,
};
};
export { setLiveStatWpm, setLiveStatAcc, setLiveStatBurst, setStatsVisible };
export function mountLiveCounters(): void {
const textWrapper = qsr("#liveStatsTextBottom");
render(
() => (
<>
<LiveCounter
class="liveSpeed"
value={() => (getLiveSpeedStyle() === "text" ? getWpm() : "")}
visibilityOptions={getStatsVisible}
/>
<LiveCounter
class="liveAcc"
value={() => (getLiveAccStyle() === "text" ? getAcc() : "")}
visibilityOptions={getStatsVisible}
/>
<LiveCounter
class="liveBurst"
value={() => (getLiveBurstStyle() === "text" ? getBurst() : "")}
visibilityOptions={getStatsVisible}
/>
</>
),
textWrapper.native,
);
const miniWrapper = qsr("#liveStatsMini");
render(
() => (
<>
<LiveCounter
class="speed"
value={() => (getLiveSpeedStyle() === "mini" ? getWpm() : "")}
visibilityOptions={getStatsVisible}
/>
<LiveCounter
class="acc"
value={() => (getLiveAccStyle() === "mini" ? getAcc() : "")}
visibilityOptions={getStatsVisible}
/>
<LiveCounter
class="burst"
value={() => (getLiveBurstStyle() === "mini" ? getBurst() : "")}
visibilityOptions={getStatsVisible}
/>
</>
),
miniWrapper.native,
);
}

View file

@ -48,6 +48,7 @@ import "./utils/url-handler";
import "./modals/last-signed-out-result";
import { applyEngineSettings } from "./anim";
import { qs, qsa, qsr } from "./utils/dom";
import { mountComponents } from "./components/mount";
// Lock Math.random
Object.defineProperty(Math, "random", {
@ -107,3 +108,5 @@ if (isDevEnvironment()) {
module.appendButton();
});
}
mountComponents();

View file

@ -11,7 +11,6 @@ import { configLoadPromise } from "./config";
import { authPromise } from "./firebase";
import { animate } from "animejs";
import { onDOMReady, qs } from "./utils/dom";
import { mountLiveCounters } from "./components/test/live-stats";
onDOMReady(async () => {
await configLoadPromise;
@ -78,6 +77,4 @@ onDOMReady(async () => {
});
}
}
mountLiveCounters();
});

View file

@ -0,0 +1,5 @@
import { createSignal } from "solid-js";
export const [getWpm, setLiveStatWpm] = createSignal("0");
export const [getAcc, setLiveStatAcc] = createSignal("100%");
export const [getBurst, setLiveStatBurst] = createSignal("0");

View file

@ -1,22 +0,0 @@
import { Accessor, JSXElement } from "solid-js";
import {
useVisibilityAnimation,
VisibilityAnimationOptions,
} from "../hooks/useVisibilityAnimation";
import { useRefWithUtils } from "../hooks/useRefWithUtils";
export function LiveCounter(props: {
value: Accessor<string>;
visibilityOptions?: Accessor<VisibilityAnimationOptions>;
class?: string;
}): JSXElement {
const [ref, element] = useRefWithUtils<HTMLDivElement>();
useVisibilityAnimation(element, props.visibilityOptions);
return (
<div ref={ref} class={props.class}>
{props.value()}
</div>
);
}

View file

@ -21,7 +21,7 @@ import { clearLowFpsMode, setLowFpsMode } from "../anim";
import { createTimer } from "animejs";
import { requestDebouncedAnimationFrame } from "../utils/debounced-animation-frame";
import Format from "../utils/format";
import { setLiveStatWpm } from "../components/test/live-stats";
import { setLiveStatWpm } from "../signals/test";
let lastLoop = 0;
const newTimer = createTimer({

View file

@ -55,12 +55,12 @@ import * as ModesNotice from "../elements/modes-notice";
import * as Last10Average from "../elements/last-10-average";
import * as MemoryFunboxTimer from "./funbox/memory-funbox-timer";
import { qsr } from "../utils/dom";
import { setStatsVisible } from "../components/test/LiveStats";
import {
setLiveStatAcc,
setLiveStatBurst,
setLiveStatWpm,
setStatsVisible,
} from "../components/test/live-stats";
} from "../signals/test";
export const updateHintsPositionDebounced = Misc.debounceUntilResolved(
updateHintsPosition,