diff --git a/frontend/src/html/pages/settings.html b/frontend/src/html/pages/settings.html
index b8557e36f..a2c2d6646 100644
--- a/frontend/src/html/pages/settings.html
+++ b/frontend/src/html/pages/settings.html
@@ -856,13 +856,16 @@
- Change the style of the timer/word count during a test.
+ Change the style of the timer/word count during a test. "Flash" styles
+ will briefly show the timer in timed modes every 15 seconds.
diff --git a/frontend/src/styles/settings.scss b/frontend/src/styles/settings.scss
index 4c7c2d3c0..f37ed4b68 100644
--- a/frontend/src/styles/settings.scss
+++ b/frontend/src/styles/settings.scss
@@ -339,6 +339,12 @@
}
}
+ &[data-config-name="timerStyle"] {
+ .buttons {
+ grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+ }
+ }
+
&.tags {
.tagsListAndButton {
grid-area: buttons;
diff --git a/frontend/src/ts/test/timer-progress.ts b/frontend/src/ts/test/timer-progress.ts
index 12f337545..cbf5b2103 100644
--- a/frontend/src/ts/test/timer-progress.ts
+++ b/frontend/src/ts/test/timer-progress.ts
@@ -36,6 +36,22 @@ export function show(): void {
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],
@@ -124,6 +140,30 @@ export function update(): void {
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) {
@@ -163,6 +203,18 @@ export function update(): void {
} 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}`;
@@ -173,6 +225,10 @@ export function update(): void {
} 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}`;
}
diff --git a/packages/schemas/src/configs.ts b/packages/schemas/src/configs.ts
index 9eaf3b8b5..e5a2f698f 100644
--- a/packages/schemas/src/configs.ts
+++ b/packages/schemas/src/configs.ts
@@ -54,7 +54,14 @@ export type ConfidenceMode = z.infer
;
export const IndicateTyposSchema = z.enum(["off", "below", "replace", "both"]);
export type IndicateTypos = z.infer;
-export const TimerStyleSchema = z.enum(["off", "bar", "text", "mini"]);
+export const TimerStyleSchema = z.enum([
+ "off",
+ "bar",
+ "text",
+ "mini",
+ "flash text",
+ "flash mini",
+]);
export type TimerStyle = z.infer;
export const LiveSpeedAccBurstStyleSchema = z.enum(["off", "text", "mini"]);