(config);
-export { getLiveSpeedStyle, getLiveAccStyle, getLiveBurstStyle };
+export { getConfigSignal };
-ConfigEvent.subscribe(({ key, newValue }) => {
- if (key === "liveSpeedStyle") {
- setLiveSpeedStyle(newValue);
- } else if (key === "liveAccStyle") {
- setLiveAccStyle(newValue);
- } else if (key === "liveBurstStyle") {
- setLiveBurstStyle(newValue);
- }
+ConfigEvent.subscribe(() => {
+ setConfigSignal(structuredClone(config));
});
diff --git a/frontend/src/ts/signals/test.ts b/frontend/src/ts/signals/test.ts
index 133f9a4e3..c3487ba86 100644
--- a/frontend/src/ts/signals/test.ts
+++ b/frontend/src/ts/signals/test.ts
@@ -1,6 +1,15 @@
import { createSignal } from "solid-js";
import { VisibilityAnimationOptions } from "../hooks/useVisibilityAnimation";
+import * as Time from "../states/time";
+import Config from "../config";
+import * as CustomText from "../test/custom-text";
+import * as DateTime from "../utils/date-and-time";
+import * as TestWords from "../test/test-words";
+import * as TestInput from "../test/test-input";
+import * as TestState from "../test/test-state";
+export const [getTestTime, setTestTime] = createSignal(0);
+export const [getProgress, setLiveProgress] = createSignal("");
export const [getWpm, setLiveStatWpm] = createSignal("0");
export const [getAcc, setLiveStatAcc] = createSignal("100%");
export const [getBurst, setLiveStatBurst] = createSignal("0");
@@ -10,3 +19,102 @@ export const [statsVisible, setStatsVisible] =
visible: false,
animate: true,
});
+
+function getCurrentCount(): number {
+ if (Config.mode === "custom" && CustomText.getLimitMode() === "section") {
+ return (
+ (TestWords.words.sectionIndexList[TestState.activeWordIndex] as number) -
+ 1
+ );
+ } else {
+ return TestInput.input.getHistory().length;
+ }
+}
+
+export function updateProgressSignal(): void {
+ const time = Time.get();
+ if (
+ Config.mode === "time" ||
+ (Config.mode === "custom" && CustomText.getLimitMode() === "time")
+ ) {
+ let maxtime = Config.time;
+ if (Config.mode === "custom" && CustomText.getLimitMode() === "time") {
+ maxtime = CustomText.getLimitValue();
+ }
+ if (Config.timerStyle === "text") {
+ let displayTime = DateTime.secondsToString(maxtime - time);
+ if (maxtime === 0) {
+ displayTime = DateTime.secondsToString(time);
+ }
+ setLiveProgress(displayTime);
+ } else if (Config.timerStyle === "flash_mini") {
+ let displayTime = DateTime.secondsToString(maxtime - time);
+ if (maxtime === 0) {
+ displayTime = DateTime.secondsToString(time);
+ }
+ setLiveProgress(displayTime);
+ } else if (Config.timerStyle === "flash_text") {
+ let displayTime = DateTime.secondsToString(maxtime - time);
+ if (maxtime === 0) {
+ displayTime = DateTime.secondsToString(time);
+ }
+ setLiveProgress(displayTime);
+ } else if (Config.timerStyle === "mini") {
+ let displayTime = DateTime.secondsToString(maxtime - time);
+ if (maxtime === 0) {
+ displayTime = DateTime.secondsToString(time);
+ }
+ setLiveProgress(displayTime);
+ }
+ } else if (
+ Config.mode === "words" ||
+ Config.mode === "custom" ||
+ Config.mode === "quote"
+ ) {
+ let outof = TestWords.words.length;
+ if (Config.mode === "words") {
+ outof = Config.words;
+ }
+ if (Config.mode === "custom") {
+ outof = CustomText.getLimitValue();
+ }
+ if (Config.mode === "quote") {
+ outof = TestWords.currentQuote?.textSplit.length ?? 1;
+ }
+ if (Config.timerStyle === "text") {
+ if (outof === 0) {
+ setLiveProgress(`${TestInput.input.getHistory().length}`);
+ } else {
+ setLiveProgress(`${getCurrentCount()}/${outof}`);
+ }
+ } else if (Config.timerStyle === "flash_mini") {
+ if (outof === 0) {
+ setLiveProgress(`${TestInput.input.getHistory().length}`);
+ } else {
+ setLiveProgress(`${getCurrentCount()}/${outof}`);
+ }
+ } else if (Config.timerStyle === "flash_text") {
+ if (outof === 0) {
+ setLiveProgress(`${TestInput.input.getHistory().length}`);
+ } else {
+ setLiveProgress(`${getCurrentCount()}/${outof}`);
+ }
+ } else if (Config.timerStyle === "mini") {
+ if (outof === 0) {
+ setLiveProgress(`${TestInput.input.getHistory().length}`);
+ } else {
+ setLiveProgress(`${getCurrentCount()}/${outof}`);
+ }
+ }
+ } else if (Config.mode === "zen") {
+ if (Config.timerStyle === "text") {
+ setLiveProgress(`${TestInput.input.getHistory().length}`);
+ } else if (Config.timerStyle === "flash_mini") {
+ setLiveProgress(`${TestInput.input.getHistory().length}`);
+ } else if (Config.timerStyle === "flash_text") {
+ setLiveProgress(`${TestInput.input.getHistory().length}`);
+ } else {
+ setLiveProgress(`${TestInput.input.getHistory().length}`);
+ }
+ }
+}
diff --git a/frontend/src/ts/states/time.ts b/frontend/src/ts/states/time.ts
index c18761a1a..35e3496de 100644
--- a/frontend/src/ts/states/time.ts
+++ b/frontend/src/ts/states/time.ts
@@ -1,3 +1,5 @@
+import { setTestTime } from "../signals/test";
+
let time = 0;
export function get(): number {
@@ -6,8 +8,10 @@ export function get(): number {
export function set(number: number): void {
time = number;
+ setTestTime(time);
}
export function increment(): void {
time++;
+ setTestTime(time);
}
diff --git a/frontend/src/ts/test/focus.ts b/frontend/src/ts/test/focus.ts
index 4ce820e55..8cbd42023 100644
--- a/frontend/src/ts/test/focus.ts
+++ b/frontend/src/ts/test/focus.ts
@@ -1,5 +1,4 @@
import * as Caret from "./caret";
-import * as TimerProgress from "./timer-progress";
import * as PageTransition from "../states/page-transition";
import { requestDebouncedAnimationFrame } from "../utils/debounced-animation-frame";
import { createSignal } from "solid-js";
@@ -63,7 +62,6 @@ export function set(value: boolean, withCursor = false): void {
}
Caret.stopAnimation();
- TimerProgress.show();
} else if (!value && state()) {
setState(false);
@@ -79,7 +77,6 @@ export function set(value: boolean, withCursor = false): void {
}
Caret.startAnimation();
- TimerProgress.hide();
}
});
}
diff --git a/frontend/src/ts/test/test-timer.ts b/frontend/src/ts/test/test-timer.ts
index 19ef7c74a..093a3511d 100644
--- a/frontend/src/ts/test/test-timer.ts
+++ b/frontend/src/ts/test/test-timer.ts
@@ -3,7 +3,6 @@
import Config, { setConfig } from "../config";
import * as CustomText from "./custom-text";
-import * as TimerProgress from "./timer-progress";
import * as TestStats from "./test-stats";
import * as TestInput from "./test-input";
import * as Monkey from "./monkey";
@@ -21,7 +20,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 "../signals/test";
+import { setLiveStatWpm, updateProgressSignal } from "../signals/test";
let lastLoop = 0;
const newTimer = createTimer({
@@ -235,7 +234,7 @@ function timerStep(): void {
});
// already using raf
- TimerProgress.update();
+ updateProgressSignal();
setLiveStatWpm(
Format.typingSpeed(Config.blindMode ? wpmAndRaw.raw : wpmAndRaw.wpm, {
showDecimalPlaces: false,
diff --git a/frontend/src/ts/test/test-ui.ts b/frontend/src/ts/test/test-ui.ts
index f3d8f3cdd..f5850d322 100644
--- a/frontend/src/ts/test/test-ui.ts
+++ b/frontend/src/ts/test/test-ui.ts
@@ -16,7 +16,6 @@ import * as Hangul from "hangul-js";
import * as ResultWordHighlight from "../elements/result-word-highlight";
import * as ActivePage from "../states/active-page";
import Format from "../utils/format";
-import { TimerColor, TimerOpacity } from "@monkeytype/schemas/configs";
import { convertRemToPixels } from "../utils/numbers";
import {
findSingleActiveFunboxWithFunction,
@@ -33,7 +32,6 @@ import * as Numbers from "@monkeytype/util/numbers";
import * as TestStats from "./test-stats";
import * as KeymapEvent from "../observables/keymap-event";
import * as Focus from "../test/focus";
-import * as TimerProgress from "../test/timer-progress";
import * as Monkey from "./monkey";
import { animate } from "animejs";
import {
@@ -56,10 +54,12 @@ import * as Last10Average from "../elements/last-10-average";
import * as MemoryFunboxTimer from "./funbox/memory-funbox-timer";
import { qsr } from "../utils/dom";
import {
+ setLiveProgress,
setLiveStatAcc,
setLiveStatBurst,
setLiveStatWpm,
setStatsVisible,
+ updateProgressSignal,
} from "../signals/test";
export const updateHintsPositionDebounced = Misc.debounceUntilResolved(
@@ -1586,48 +1586,6 @@ function updateLiveStatsMargin(): void {
}
}
-function updateLiveStatsOpacity(value: TimerOpacity): void {
- $("#barTimerProgress").css("opacity", parseFloat(value as string));
- $("#liveStatsTextTop").css("opacity", parseFloat(value as string));
- $("#liveStatsTextBottom").css("opacity", parseFloat(value as string));
- $("#liveStatsMini").css("opacity", parseFloat(value as string));
-}
-
-function updateLiveStatsColor(value: TimerColor): void {
- $("#barTimerProgress").removeClass("timerSub");
- $("#barTimerProgress").removeClass("timerText");
- $("#barTimerProgress").removeClass("timerMain");
-
- $("#liveStatsTextTop").removeClass("timerSub");
- $("#liveStatsTextTop").removeClass("timerText");
- $("#liveStatsTextTop").removeClass("timerMain");
-
- $("#liveStatsTextBottom").removeClass("timerSub");
- $("#liveStatsTextBottom").removeClass("timerText");
- $("#liveStatsTextBottom").removeClass("timerMain");
-
- $("#liveStatsMini").removeClass("timerSub");
- $("#liveStatsMini").removeClass("timerText");
- $("#liveStatsMini").removeClass("timerMain");
-
- if (value === "main") {
- $("#barTimerProgress").addClass("timerMain");
- $("#liveStatsTextTop").addClass("timerMain");
- $("#liveStatsTextBottom").addClass("timerMain");
- $("#liveStatsMini").addClass("timerMain");
- } else if (value === "sub") {
- $("#barTimerProgress").addClass("timerSub");
- $("#liveStatsTextTop").addClass("timerSub");
- $("#liveStatsTextBottom").addClass("timerSub");
- $("#liveStatsMini").addClass("timerSub");
- } else if (value === "text") {
- $("#barTimerProgress").addClass("timerText");
- $("#liveStatsTextTop").addClass("timerText");
- $("#liveStatsTextBottom").addClass("timerText");
- $("#liveStatsMini").addClass("timerText");
- }
-}
-
function showHideTestRestartButton(showHide: boolean): void {
if (showHide) {
$(".pageTest #restartTestButton").removeClass("hidden");
@@ -1688,7 +1646,8 @@ function afterAnyTestInput(
}
if (Config.mode !== "time") {
- TimerProgress.update();
+ // TimerProgress.update();
+ updateProgressSignal();
}
if (Config.keymapMode === "next") {
@@ -1819,8 +1778,7 @@ export async function afterTestWordChange(
export function onTestStart(): void {
Focus.set(true);
Monkey.show();
- TimerProgress.show();
- TimerProgress.update();
+ updateProgressSignal();
setStatsVisible({
visible: true,
animate: true,
@@ -1837,11 +1795,10 @@ export function onTestRestart(source: "testPage" | "resultPage"): void {
visible: false,
animate: false,
});
+ setLiveProgress("0");
setLiveStatWpm("0");
setLiveStatBurst("0");
setLiveStatAcc("100%");
- TimerProgress.instantHide();
- TimerProgress.reset();
Monkey.instantHide();
LayoutfluidFunboxTimer.instantHide();
updatePremid();
@@ -1884,12 +1841,15 @@ export function onTestRestart(source: "testPage" | "resultPage"): void {
export function onTestFinish(): void {
Caret.hide();
- TimerProgress.hide();
OutOfFocus.hide();
Monkey.hide();
if (Config.playSoundOnClick === "16") {
void SoundController.playFartReverb();
}
+ setStatsVisible({
+ visible: false,
+ animate: true,
+ });
}
$(".pageTest #copyWordsListButton").on("click", async () => {
@@ -2000,12 +1960,6 @@ ConfigEvent.subscribe(({ key, newValue }) => {
if (key === "quickRestart") {
showHideTestRestartButton(newValue === "off");
}
- if (key === "timerOpacity") {
- updateLiveStatsOpacity(newValue);
- }
- if (key === "timerColor") {
- updateLiveStatsColor(newValue);
- }
if (key === "showOutOfFocusWarning" && !newValue) {
OutOfFocus.hide();
}
diff --git a/frontend/src/ts/test/timer-progress.ts b/frontend/src/ts/test/timer-progress.ts
deleted file mode 100644
index 8b3967d60..000000000
--- a/frontend/src/ts/test/timer-progress.ts
+++ /dev/null
@@ -1,269 +0,0 @@
-import Config from "../config";
-import * as CustomText from "./custom-text";
-import * as DateTime from "../utils/date-and-time";
-import * as TestWords from "./test-words";
-import * as TestInput from "./test-input";
-import * as Time from "../states/time";
-import * as TestState from "./test-state";
-import * as ConfigEvent from "../observables/config-event";
-import { applyReducedMotion } from "../utils/misc";
-import { requestDebouncedAnimationFrame } from "../utils/debounced-animation-frame";
-import { animate } from "animejs";
-
-const barEl = document.querySelector("#barTimerProgress .bar") as HTMLElement;
-const barOpacityEl = document.querySelector(
- "#barTimerProgress .opacityWrapper",
-) as HTMLElement;
-const textEl = document.querySelector(
- "#liveStatsTextTop .timerProgress",
-) as HTMLElement;
-const miniEl = document.querySelector("#liveStatsMini .time") as HTMLElement;
-
-export function show(): void {
- if (!TestState.isActive()) return;
- requestDebouncedAnimationFrame("timer-progress.show", () => {
- if (Config.mode !== "zen" && Config.timerStyle === "bar") {
- animate(barOpacityEl, {
- opacity: [0, 1],
- duration: applyReducedMotion(125),
- onBegin: () => {
- barOpacityEl.classList.remove("hidden");
- },
- });
- } else if (Config.timerStyle === "text") {
- animate(textEl, {
- opacity: [0, 1],
- duration: applyReducedMotion(125),
- onBegin: () => {
- textEl.classList.remove("hidden");
- },
- });
- } else if (Config.timerStyle === "flash_mini") {
- animate(miniEl, {
- opacity: [0, 1],
- duration: applyReducedMotion(125),
- onBegin: () => {
- miniEl.classList.remove("hidden");
- },
- });
- } else if (Config.timerStyle === "flash_text") {
- animate(textEl, {
- opacity: [0, 1],
- duration: applyReducedMotion(125),
- onBegin: () => {
- textEl.classList.remove("hidden");
- },
- });
- } else if (Config.mode === "zen" || Config.timerStyle === "mini") {
- animate(miniEl, {
- opacity: [0, 1],
- duration: applyReducedMotion(125),
- onBegin: () => {
- miniEl.classList.remove("hidden");
- },
- });
- }
- });
-}
-
-export function reset(): void {
- requestDebouncedAnimationFrame("timer-progress.reset", () => {
- let width = "0vw";
- if (
- Config.mode === "time" ||
- (Config.mode === "custom" && CustomText.getLimitMode() === "time")
- ) {
- width = "100vw";
- }
-
- animate(barEl, {
- width,
- duration: 0,
- });
- miniEl.textContent = "0";
- textEl.textContent = "0";
- });
-}
-
-export function hide(): void {
- requestDebouncedAnimationFrame("timer-progress.hide", () => {
- animate(barOpacityEl, {
- opacity: 0,
- duration: applyReducedMotion(125),
- });
-
- animate(miniEl, {
- opacity: 0,
- duration: applyReducedMotion(125),
- onComplete: () => {
- miniEl.classList.add("hidden");
- },
- });
-
- animate(textEl, {
- opacity: 0,
- duration: applyReducedMotion(125),
- onComplete: () => {
- textEl.classList.add("hidden");
- },
- });
- });
-}
-
-export function instantHide(): void {
- barOpacityEl.style.opacity = "0";
-
- miniEl.classList.add("hidden");
- miniEl.style.opacity = "0";
-
- textEl.classList.add("hidden");
- textEl.style.opacity = "0";
-}
-
-function getCurrentCount(): number {
- if (Config.mode === "custom" && CustomText.getLimitMode() === "section") {
- return (
- (TestWords.words.sectionIndexList[TestState.activeWordIndex] as number) -
- 1
- );
- } else {
- return TestInput.input.getHistory().length;
- }
-}
-
-export function update(): void {
- requestDebouncedAnimationFrame("timer-progress.update", () => {
- const time = Time.get();
- if (
- Config.mode === "time" ||
- (Config.mode === "custom" && CustomText.getLimitMode() === "time")
- ) {
- let maxtime = Config.time;
- if (Config.mode === "custom" && CustomText.getLimitMode() === "time") {
- maxtime = CustomText.getLimitValue();
- }
- if (Config.timerStyle === "bar") {
- const percent = 100 - ((time + 1) / maxtime) * 100;
-
- animate(barEl, {
- width: percent + "vw",
- duration: 1000,
- ease: "linear",
- });
- } else if (Config.timerStyle === "text") {
- let displayTime = DateTime.secondsToString(maxtime - time);
- if (maxtime === 0) {
- displayTime = DateTime.secondsToString(time);
- }
- if (textEl !== null) {
- textEl.innerHTML = "" + displayTime + "
";
- }
- } else if (Config.timerStyle === "flash_mini") {
- let displayTime = DateTime.secondsToString(maxtime - time);
- if (maxtime === 0) {
- displayTime = DateTime.secondsToString(time);
- }
- if (miniEl !== null) {
- if ((maxtime - time) % 15 !== 0) {
- miniEl.style.opacity = "0";
- } else {
- miniEl.style.opacity = "1";
- }
- miniEl.innerHTML = "" + displayTime + "
";
- }
- } else if (Config.timerStyle === "flash_text") {
- let displayTime = DateTime.secondsToString(maxtime - time);
- if (maxtime === 0) {
- displayTime = DateTime.secondsToString(time);
- }
- if (textEl !== null) {
- textEl.innerHTML =
- "" +
- `${(maxtime - time) % 15 !== 0 ? "" : displayTime}` +
- "
";
- }
- } else if (Config.timerStyle === "mini") {
- let displayTime = DateTime.secondsToString(maxtime - time);
- if (maxtime === 0) {
- displayTime = DateTime.secondsToString(time);
- }
- if (miniEl !== null) {
- miniEl.innerHTML = displayTime;
- }
- }
- } else if (
- Config.mode === "words" ||
- Config.mode === "custom" ||
- Config.mode === "quote"
- ) {
- let outof = TestWords.words.length;
- if (Config.mode === "words") {
- outof = Config.words;
- }
- if (Config.mode === "custom") {
- outof = CustomText.getLimitValue();
- }
- if (Config.mode === "quote") {
- outof = TestWords.currentQuote?.textSplit.length ?? 1;
- }
- if (Config.timerStyle === "bar") {
- const percent = Math.floor(
- ((TestState.activeWordIndex + 1) / outof) * 100,
- );
-
- animate(barEl, {
- width: percent + "vw",
- duration: 250,
- });
- } else if (Config.timerStyle === "text") {
- if (outof === 0) {
- textEl.innerHTML = `${TestInput.input.getHistory().length}
`;
- } else {
- textEl.innerHTML = `${getCurrentCount()}/${outof}
`;
- }
- } else if (Config.timerStyle === "flash_mini") {
- if (outof === 0) {
- miniEl.innerHTML = `${TestInput.input.getHistory().length}`;
- } else {
- miniEl.innerHTML = `${getCurrentCount()}/${outof}`;
- }
- } else if (Config.timerStyle === "flash_text") {
- if (outof === 0) {
- textEl.innerHTML = `${TestInput.input.getHistory().length}
`;
- } else {
- textEl.innerHTML = `${getCurrentCount()}/${outof}
`;
- }
- } else if (Config.timerStyle === "mini") {
- if (outof === 0) {
- miniEl.innerHTML = `${TestInput.input.getHistory().length}`;
- } else {
- miniEl.innerHTML = `${getCurrentCount()}/${outof}`;
- }
- }
- } else if (Config.mode === "zen") {
- if (Config.timerStyle === "text") {
- textEl.innerHTML = `${TestInput.input.getHistory().length}
`;
- } else if (Config.timerStyle === "flash_mini") {
- miniEl.innerHTML = `${TestInput.input.getHistory().length}`;
- } else if (Config.timerStyle === "flash_text") {
- textEl.innerHTML = `${TestInput.input.getHistory().length}
`;
- } else {
- miniEl.innerHTML = `${TestInput.input.getHistory().length}`;
- }
- }
- });
-}
-
-export function updateStyle(): void {
- if (!TestState.isActive()) return;
- hide();
- update();
- if (Config.timerStyle === "off") return;
- setTimeout(() => {
- show();
- }, 125);
-}
-
-ConfigEvent.subscribe(({ key }) => {
- if (key === "timerStyle") updateStyle();
-});