Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions frontend/src/ts/components/layout/overlays/Banners.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import { setGlobalOffsetTop } from "../../../states/core";
import { getSnapshot } from "../../../states/snapshot";
import { cn } from "../../../utils/cn";
import { isProfilerMode } from "../../../utils/profiler-mode";
import { Fa } from "../../common/Fa";
import { showUpdateNameModal } from "../../modals/account-settings/UpdateNameModal";

Expand Down Expand Up @@ -111,6 +112,14 @@ export function Banners(): JSXElement {

onMount(() => {
window.addEventListener("resize", debouncedMarginUpdate);
if (isProfilerMode()) {
addBanner({
level: "error",
icon: "fas fa-stopwatch",
text: "Profiler mode enabled",
important: true,
});
}
});

onCleanup(() => {
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/ts/components/modals/DevOptionsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { toggleUserFakeChartData } from "../../test/result";
import { disableSlowTimerFail } from "../../test/test-timer";
import { FaSolidIcon } from "../../types/font-awesome";
import { setMediaQueryDebugLevel } from "../../ui";
import { isProfilerMode, setProfilerMode } from "../../utils/profiler-mode";
import { remoteValidation } from "../../utils/remote-validation";
import { AnimatedModal } from "../common/AnimatedModal";
import { Button } from "../common/Button";
Expand Down Expand Up @@ -171,6 +172,15 @@ export function DevOptionsModal(): JSXElement {
label: () => "Event Log Viewer",
onClick: () => showModal("EventLogViewer"),
},
{
icon: "fa-stopwatch",
label: () => `Profiler Mode (${isProfilerMode() ? "ON" : "OFF"})`,
onClick: () => {
setProfilerMode(!isProfilerMode());
showNoticeNotification("Profiler mode toggled, reloading...");
setTimeout(() => location.reload(), 500);
},
},
];

const addDebugInboxItem = (rewardType: "xp" | "badge" | "none"): void => {
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/ts/cookies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { createSignal } from "solid-js";
import { LocalStorageWithSchema } from "./utils/local-storage-with-schema";
import { activateAnalytics } from "./controllers/analytics-controller";
import { activateSentry } from "./sentry";
import { isProfilerMode } from "./utils/profiler-mode";

const AcceptedCookiesSchema = z
.object({
Expand Down Expand Up @@ -39,7 +40,7 @@ export function activateWhatsAccepted(): void {
if (accepted?.analytics) {
activateAnalytics();
}
if (accepted?.sentry) {
if (accepted?.sentry && !isProfilerMode()) {
void activateSentry();
}
}
3 changes: 2 additions & 1 deletion frontend/src/ts/dev/signal-tracker.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { createSignal, DEV } from "solid-js";
import { isProfilerMode } from "../utils/profiler-mode";

export type TrackedSignal = {
name: string;
Expand Down Expand Up @@ -91,7 +92,7 @@ function formatInitialValue(value: unknown): string {
}
}

if (DEV) {
if (DEV && !isProfilerMode()) {
type NodeInfo = {
name: string;
type: "signal" | "store";
Expand Down
64 changes: 41 additions & 23 deletions frontend/src/ts/test/events/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
KeydownEventData,
KeyupEvent,
KeyupEventData,
TestEvent,
TestEventData,
TestEventNoMs,
TestEventType,
Expand All @@ -27,19 +28,25 @@ import { isFunboxActiveWithProperty } from "../funbox/list";
import { getCurrentQuote } from "../../states/test";

export function buildEventLog(): EventLog {
return {
version: EVENT_LOG_VERSION,
events: getAllTestEvents(),
context: {
targetWords: [...TestWords.words.list],
mode: Config.mode,
mode2: getMode2(Config, getCurrentQuote()),
const context = {
targetWords: [...TestWords.words.list],
mode: Config.mode,
mode2: getMode2(Config, getCurrentQuote()),
koreanStatus: koreanStatus,
bailedOut: bailedOut,
...(Config.mode === "custom" && {
customTextLimitMode: CustomText.getLimit().mode,
customTextLimitValue: CustomText.getLimit().value,
}),
...(Config.funbox.length !== 0 && {
isFunboxWithNospacePropertyActive: isFunboxActiveWithProperty("nospace"),
koreanStatus: koreanStatus,
bailedOut: bailedOut,
},
}),
};

return {
version: EVENT_LOG_VERSION,
events: getAllTestEvents(),
context,
};
}

Expand Down Expand Up @@ -272,20 +279,31 @@ export function getAllTestEvents(): TestEventNoMs[] {
const startEventMs =
timerEvents.find((e) => e.data.event === "start")?.ms ?? firstEventMs ?? 0;

// cachedAllEvents = testData300;
// return cachedAllEvents;
cachedAllEvents = [
...keydownEvents,
...keyupEvents,
...timerEvents,
...inputEvents,
...compositionEvents,
]
const total =
keydownEvents.length +
keyupEvents.length +
timerEvents.length +
inputEvents.length +
compositionEvents.length;

const merged = new Array<TestEvent>(total);
let p = 0;
for (const e of keydownEvents) merged[p++] = e;
for (const e of keyupEvents) merged[p++] = e;
for (const e of timerEvents) merged[p++] = e;
for (const e of inputEvents) merged[p++] = e;
for (const e of compositionEvents) merged[p++] = e;

cachedAllEvents = merged
.sort((a, b) => a.ms - b.ms || sortTieRank(a.type) - sortTieRank(b.type))
.map(({ ms, ...rest }) => ({
...rest,
testMs: roundTo2(ms - startEventMs),
}));
.map(
(event) =>
({
type: event.type,
testMs: roundTo2(event.ms - startEventMs),
data: event.data,
}) as TestEventNoMs,
);

return cachedAllEvents;
}
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/ts/test/events/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,10 @@ export type EventLogContext = {
// isTimedTest: boolean;
mode: Config["mode"];
mode2: ReturnType<typeof getMode2>;
customTextLimitMode: CustomTextLimitMode;
customTextLimitValue: number;
customTextLimitMode?: CustomTextLimitMode;
customTextLimitValue?: number;
isFunboxWithNospacePropertyActive?: boolean;
bailedOut: boolean;
isFunboxWithNospacePropertyActive: boolean;
koreanStatus: boolean;
};

Expand Down
17 changes: 13 additions & 4 deletions frontend/src/ts/test/test-ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1277,16 +1277,22 @@ function buildWordLettersHTML(
) {
extraCorrected = "extraCorrected";
}

let displayLetter = inputCharacters[c];
if (displayLetter === " ") {
displayLetter = "_";
}

if (Config.mode === "zen" || wordCharacters[c] !== undefined) {
if (Config.mode === "zen" || inputCharacters[c] === wordCharacters[c]) {
if (
correctedChar === inputCharacters[c] ||
correctedChar === undefined
) {
out += `<letter class="correct ${extraCorrected}">${inputCharacters[c]}</letter>`;
out += `<letter class="correct ${extraCorrected}">${displayLetter}</letter>`;
} else {
out += `<letter class="corrected ${extraCorrected}">${
inputCharacters[c]
displayLetter
}</letter>`;
}
} else {
Expand All @@ -1303,7 +1309,7 @@ function buildWordLettersHTML(
}
}
} else {
out += `<letter class="incorrect extra">${inputCharacters[c]}</letter>`;
out += `<letter class="incorrect extra">${displayLetter}</letter>`;
}
}
return out;
Expand Down Expand Up @@ -1391,7 +1397,10 @@ async function loadWordsHistory(): Promise<boolean> {
);
} catch (e) {
try {
for (const char of word) {
for (let char of word) {
if (char === " ") {
char = "_";
}
const letterEl = document.createElement("letter");
letterEl.textContent = char;
wordEl.appendChild(letterEl);
Expand Down
5 changes: 4 additions & 1 deletion frontend/src/ts/utils/logger.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { z } from "zod";
import { LocalStorageWithSchema } from "./local-storage-with-schema";
import { isDevEnvironment } from "./env";
import { isProfilerMode } from "./profiler-mode";

const nativeLog = console.log;
const nativeWarn = console.warn;
Expand All @@ -14,7 +15,9 @@ const debugLogsLS = new LocalStorageWithSchema({

let debugLogs = debugLogsLS.get();

if (isDevEnvironment()) {
if (isProfilerMode()) {
debugLogs = false;
} else if (isDevEnvironment()) {
debugLogs = true;
debug("Debug logs automatically enabled on localhost");
}
Expand Down
23 changes: 23 additions & 0 deletions frontend/src/ts/utils/profiler-mode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { z } from "zod";
import { LocalStorageWithSchema } from "./local-storage-with-schema";
import { isDevEnvironment } from "./env";

const profilerModeLS = new LocalStorageWithSchema({
key: "profilerMode",
schema: z.boolean(),
fallback: false,
});

// Resolved at module load: profiler mode disables features that initialise
// at load (signal tracker hook, sentry init, logger debug filter), so toggling
// it requires a reload to take effect.
const active = isDevEnvironment() && profilerModeLS.get();

export function isProfilerMode(): boolean {
return active;
}

export function setProfilerMode(value: boolean): void {
if (!isDevEnvironment()) return;
profilerModeLS.set(value);
}
Loading