mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2026-01-15 11:54:24 +08:00
use signals for focus and isactive state
This commit is contained in:
parent
205a5154df
commit
75a36c9feb
19 changed files with 41 additions and 55 deletions
|
|
@ -79,7 +79,7 @@ export function saveFullConfigToLocalStorage(noDbCheck = false): void {
|
|||
}
|
||||
|
||||
function isConfigChangeBlocked(): boolean {
|
||||
if (TestState.isActive && config.funbox.includes("no_quit")) {
|
||||
if (TestState.isActive() && config.funbox.includes("no_quit")) {
|
||||
Notifications.add("No quit funbox is active. Please finish the test.", 0, {
|
||||
important: true,
|
||||
});
|
||||
|
|
@ -112,7 +112,7 @@ export function setConfig<T extends keyof Config>(
|
|||
|
||||
if (
|
||||
metadata.changeRequiresRestart &&
|
||||
TestState.isActive &&
|
||||
TestState.isActive() &&
|
||||
config.funbox.includes("no_quit")
|
||||
) {
|
||||
Notifications.add("No quit funbox is active. Please finish the test.", 0, {
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ function init(): void {
|
|||
}
|
||||
|
||||
setInterval(() => {
|
||||
if (TestState.isActive) {
|
||||
if (TestState.isActive()) {
|
||||
return;
|
||||
}
|
||||
if (choice === "eg") {
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ export async function navigate(
|
|||
}
|
||||
|
||||
const noQuit = isFunboxActive("no_quit");
|
||||
if (TestState.isActive && noQuit) {
|
||||
if (TestState.isActive() && noQuit) {
|
||||
Notifications.add("No quit funbox is active. Please finish the test.", 0, {
|
||||
important: true,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import * as TestUI from "../../test/test-ui";
|
|||
import { isAwaitingNextWord } from "../state";
|
||||
|
||||
export function onBeforeDelete(event: InputEvent): void {
|
||||
if (!TestState.isActive) {
|
||||
if (!TestState.isActive()) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ export async function onInsertText(options: OnInsertTextParams): Promise<void> {
|
|||
const data = normalizedData ?? options.data;
|
||||
|
||||
// start if needed
|
||||
if (!TestState.isActive) {
|
||||
if (!TestState.isActive()) {
|
||||
TestLogic.startTest(now);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ inputEl.addEventListener("compositionstart", (event) => {
|
|||
CompositionState.setComposing(true);
|
||||
CompositionState.setData("");
|
||||
setLastInsertCompositionTextData("");
|
||||
if (!TestState.isActive) {
|
||||
if (!TestState.isActive()) {
|
||||
TestLogic.startTest(performance.now());
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,5 +2,3 @@ import { createSignal } from "solid-js";
|
|||
export const [getWpm, setWpm] = createSignal("0");
|
||||
export const [getAcc, setAcc] = createSignal("100%");
|
||||
export const [getBurst, setBurst] = createSignal("0");
|
||||
export const [getFocus, setFocus] = createSignal(false);
|
||||
export const [getTestRunning, setTestRunning] = createSignal(false);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ const throttledHandleState = debounce(5000, () => {
|
|||
)?.dispatch("click");
|
||||
}
|
||||
bannerAlreadyClosed = false;
|
||||
} else if (!TestState.isActive) {
|
||||
} else if (!TestState.isActive()) {
|
||||
showOfflineBanner();
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ 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 { setFocus } from "../signals/live-states";
|
||||
import { createSignal } from "solid-js";
|
||||
|
||||
const unfocusPx = 3;
|
||||
let state = false;
|
||||
let [state, setState] = createSignal(false);
|
||||
|
||||
let cacheReady = false;
|
||||
let cache: {
|
||||
|
|
@ -13,6 +13,10 @@ let cache: {
|
|||
cursor?: HTMLElement[];
|
||||
} = {};
|
||||
|
||||
export function isFocused(): boolean {
|
||||
return state();
|
||||
}
|
||||
|
||||
function initializeCache(): void {
|
||||
if (cacheReady) return;
|
||||
|
||||
|
|
@ -43,8 +47,8 @@ export function set(value: boolean, withCursor = false): void {
|
|||
requestDebouncedAnimationFrame("focus.set", () => {
|
||||
initializeCache();
|
||||
|
||||
if (value && !state) {
|
||||
state = true;
|
||||
if (value && !state()) {
|
||||
setState(true);
|
||||
|
||||
// batch DOM operations for better performance
|
||||
if (cache.focus) {
|
||||
|
|
@ -60,8 +64,8 @@ export function set(value: boolean, withCursor = false): void {
|
|||
|
||||
Caret.stopAnimation();
|
||||
TimerProgress.show();
|
||||
} else if (!value && state) {
|
||||
state = false;
|
||||
} else if (!value && state()) {
|
||||
setState(false);
|
||||
|
||||
if (cache.focus) {
|
||||
for (const el of cache.focus) {
|
||||
|
|
@ -77,14 +81,12 @@ export function set(value: boolean, withCursor = false): void {
|
|||
Caret.startAnimation();
|
||||
TimerProgress.hide();
|
||||
}
|
||||
|
||||
setFocus(state);
|
||||
});
|
||||
}
|
||||
|
||||
$(document).on("mousemove", function (event) {
|
||||
if (PageTransition.get()) return;
|
||||
if (!state) return;
|
||||
if (!state()) return;
|
||||
if (
|
||||
event.originalEvent &&
|
||||
// To avoid mouse/desk vibration from creating a flashy effect, we'll unfocus @ >5px instead of >0px
|
||||
|
|
|
|||
|
|
@ -2,20 +2,16 @@ import { createMemo } from "solid-js";
|
|||
import { qsr } from "../utils/dom";
|
||||
import { LiveCounter } from "./live-counter";
|
||||
import { render } from "solid-js/web";
|
||||
import {
|
||||
getAcc,
|
||||
getBurst,
|
||||
getFocus,
|
||||
getTestRunning,
|
||||
getWpm,
|
||||
} from "../signals/live-states";
|
||||
import { getAcc, getBurst, getWpm } from "../signals/live-states";
|
||||
import {
|
||||
getLiveAccStyle,
|
||||
getLiveBurstStyle,
|
||||
getLiveSpeedStyle,
|
||||
} from "../signals/config";
|
||||
import { isActive } from "./test-state";
|
||||
import { isFocused } from "./focus";
|
||||
|
||||
const isTestRunning = createMemo(() => getTestRunning() && getFocus());
|
||||
const isTestRunning = createMemo(() => isActive() && isFocused());
|
||||
|
||||
const liveWpmText = createMemo(() =>
|
||||
isTestRunning() && getLiveSpeedStyle() === "text" ? getWpm() : "",
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ const monkeyEl = document.querySelector("#monkey") as HTMLElement;
|
|||
const monkeyFastEl = document.querySelector("#monkey .fast") as HTMLElement;
|
||||
|
||||
ConfigEvent.subscribe(({ key }) => {
|
||||
if (key === "monkey" && TestState.isActive) {
|
||||
if (key === "monkey" && TestState.isActive()) {
|
||||
if (Config.monkey) {
|
||||
monkeyEl.classList.remove("hidden");
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ export async function update(expectedStepEnd: number): Promise<void> {
|
|||
const currentSettings = settings;
|
||||
if (
|
||||
currentSettings === null ||
|
||||
!TestState.isActive ||
|
||||
!TestState.isActive() ||
|
||||
TestState.resultVisible
|
||||
) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ export function restart(options = {} as RestartOptions): void {
|
|||
const animationTime = options.noAnim ? 0 : Misc.applyReducedMotion(125);
|
||||
|
||||
const noQuit = isFunboxActive("no_quit");
|
||||
if (TestState.isActive && noQuit) {
|
||||
if (TestState.isActive() && noQuit) {
|
||||
Notifications.add("No quit funbox is active. Please finish the test.", 0, {
|
||||
important: true,
|
||||
});
|
||||
|
|
@ -196,7 +196,7 @@ export function restart(options = {} as RestartOptions): void {
|
|||
}
|
||||
}
|
||||
|
||||
if (TestState.isActive) {
|
||||
if (TestState.isActive()) {
|
||||
if (TestState.isRepeated) {
|
||||
options.withSameWordset = true;
|
||||
}
|
||||
|
|
@ -221,7 +221,7 @@ export function restart(options = {} as RestartOptions): void {
|
|||
TestWords.currentQuote !== null &&
|
||||
Config.language.startsWith(TestWords.currentQuote.language) &&
|
||||
Config.repeatQuotes === "typing" &&
|
||||
(TestState.isActive || failReason !== "")
|
||||
(TestState.isActive() || failReason !== "")
|
||||
) {
|
||||
options.withSameWordset = true;
|
||||
}
|
||||
|
|
@ -854,7 +854,7 @@ function buildCompletedEvent(
|
|||
}
|
||||
|
||||
export async function finish(difficultyFailed = false): Promise<void> {
|
||||
if (!TestState.isActive) return;
|
||||
if (!TestState.isActive()) return;
|
||||
TestUI.setResultCalculating(true);
|
||||
const now = performance.now();
|
||||
TestTimer.clear();
|
||||
|
|
@ -1404,7 +1404,7 @@ $(".pageTest").on("click", "#restartTestButton", () => {
|
|||
ManualRestart.set();
|
||||
if (TestUI.resultCalculating) return;
|
||||
if (
|
||||
TestState.isActive &&
|
||||
TestState.isActive() &&
|
||||
Config.repeatQuotes === "typing" &&
|
||||
Config.mode === "quote"
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import { Challenge } from "@monkeytype/schemas/challenges";
|
||||
import { promiseWithResolvers } from "../utils/misc";
|
||||
import { createSignal } from "solid-js";
|
||||
|
||||
export let isRepeated = false;
|
||||
export let isPaceRepeat = false;
|
||||
export let isActive = false;
|
||||
export let [isActive, setActive] = createSignal(false);
|
||||
export let activeChallenge: null | Challenge = null;
|
||||
export let savingEnabled = true;
|
||||
export let bailedOut = false;
|
||||
|
|
@ -23,10 +24,6 @@ export function setPaceRepeat(tf: boolean): void {
|
|||
isPaceRepeat = tf;
|
||||
}
|
||||
|
||||
export function setActive(tf: boolean): void {
|
||||
isActive = tf;
|
||||
}
|
||||
|
||||
export function setActiveChallenge(val: null | Challenge): void {
|
||||
activeChallenge = val;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ export function calculateWpmAndRaw(
|
|||
raw: number;
|
||||
} {
|
||||
const testSeconds = calculateTestSeconds(
|
||||
TestState.isActive ? performance.now() : end,
|
||||
TestState.isActive() ? performance.now() : end,
|
||||
);
|
||||
const chars = countChars(final);
|
||||
const wpm = Numbers.roundTo2(
|
||||
|
|
@ -256,7 +256,7 @@ function getInputWords(): string[] {
|
|||
|
||||
let inputWords = [...TestInput.input.getHistory()];
|
||||
|
||||
if (TestState.isActive) {
|
||||
if (TestState.isActive()) {
|
||||
inputWords.push(TestInput.input.current);
|
||||
}
|
||||
|
||||
|
|
@ -276,7 +276,7 @@ function getTargetWords(): string[] {
|
|||
: TestWords.words.list),
|
||||
];
|
||||
|
||||
if (TestState.isActive) {
|
||||
if (TestState.isActive()) {
|
||||
targetWords.push(
|
||||
Config.mode === "zen"
|
||||
? TestInput.input.current
|
||||
|
|
|
|||
|
|
@ -308,7 +308,7 @@ async function _startOld(): Promise<void> {
|
|||
const drift = Math.abs(interval - delay);
|
||||
checkIfTimerIsSlow(drift);
|
||||
timer = setTimeout(function () {
|
||||
if (!TestState.isActive) {
|
||||
if (!TestState.isActive()) {
|
||||
if (timer !== null) clearTimeout(timer);
|
||||
SlowTimer.clear();
|
||||
slowTimerCount = 0;
|
||||
|
|
|
|||
|
|
@ -55,12 +55,7 @@ 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 {
|
||||
setAcc,
|
||||
setBurst,
|
||||
setTestRunning,
|
||||
setWpm,
|
||||
} from "../signals/live-states";
|
||||
import { setAcc, setBurst, setWpm } from "../signals/live-states";
|
||||
|
||||
export const updateHintsPositionDebounced = Misc.debounceUntilResolved(
|
||||
updateHintsPosition,
|
||||
|
|
@ -88,7 +83,7 @@ export function focusWords(force = false): void {
|
|||
blurInputElement();
|
||||
}
|
||||
focusInputElement(true);
|
||||
if (TestState.isActive) {
|
||||
if (TestState.isActive()) {
|
||||
keepWordsInputInTheCenter(true);
|
||||
} else {
|
||||
const typingTest = document.querySelector<HTMLElement>("#typingTest");
|
||||
|
|
@ -1818,7 +1813,6 @@ export function onTestStart(): void {
|
|||
Focus.set(true);
|
||||
Monkey.show();
|
||||
TimerProgress.show();
|
||||
setTestRunning(true);
|
||||
TimerProgress.update();
|
||||
}
|
||||
|
||||
|
|
@ -1875,7 +1869,6 @@ export function onTestRestart(source: "testPage" | "resultPage"): void {
|
|||
|
||||
export function onTestFinish(): void {
|
||||
Caret.hide();
|
||||
setTestRunning(false);
|
||||
TimerProgress.hide();
|
||||
OutOfFocus.hide();
|
||||
Monkey.hide();
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ const textEl = document.querySelector(
|
|||
const miniEl = document.querySelector("#liveStatsMini .time") as HTMLElement;
|
||||
|
||||
export function show(): void {
|
||||
if (!TestState.isActive) return;
|
||||
if (!TestState.isActive()) return;
|
||||
requestDebouncedAnimationFrame("timer-progress.show", () => {
|
||||
if (Config.mode !== "zen" && Config.timerStyle === "bar") {
|
||||
animate(barOpacityEl, {
|
||||
|
|
@ -255,7 +255,7 @@ export function update(): void {
|
|||
}
|
||||
|
||||
export function updateStyle(): void {
|
||||
if (!TestState.isActive) return;
|
||||
if (!TestState.isActive()) return;
|
||||
hide();
|
||||
update();
|
||||
if (Config.timerStyle === "off") return;
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ window.addEventListener("beforeunload", (event) => {
|
|||
) {
|
||||
//ignore
|
||||
} else {
|
||||
if (TestState.isActive) {
|
||||
if (TestState.isActive()) {
|
||||
event.preventDefault();
|
||||
// Included for legacy support, e.g. Chrome/Edge < 119
|
||||
// oxlint-disable-next-line no-deprecated
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue