Skip to content

Commit

Permalink
feat: add tape margin
Browse files Browse the repository at this point in the history
  • Loading branch information
Miodec committed Jan 6, 2025
1 parent b490056 commit c9789d6
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 8 deletions.
24 changes: 24 additions & 0 deletions frontend/src/html/pages/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,30 @@
<button data-config-value="word">word</button>
</div>
</div>
<div class="section" data-config-name="tapeMargin">
<div class="groupTitle">
<i class="fas fa-tape"></i>
<span>tape margin</span>
</div>
<div class="text">
When in tape mode, set the carets position from the left edge of the
typing test as a percentage (for example, 50% centers it).
</div>
<div class="inputs">
<div class="inputAndButton">
<input
type="number"
placeholder="tape margin"
class="input"
min="10"
max="90"
/>
<button class="save no-auto-handle">
<i class="fas fa-save fa-fw"></i>
</button>
</div>
</div>
</div>
<div class="section" data-config-name="smoothLineScroll">
<div class="groupTitle">
<i class="fas fa-align-left"></i>
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/styles/test.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1254,6 +1254,8 @@
}
}
#liveStatsMini {
width: 0;
justify-content: start;
height: 0;
margin-left: 0.25em;
display: flex;
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/ts/commandline/lists.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import TimerColorCommands from "./lists/timer-color";
import TimerOpacityCommands from "./lists/timer-opacity";
import HighlightModeCommands from "./lists/highlight-mode";
import TapeModeCommands from "./lists/tape-mode";
import TapeMarginCommands from "./lists/tape-margin";
import BritishEnglishCommands from "./lists/british-english";
import KeymapModeCommands from "./lists/keymap-mode";
import KeymapStyleCommands from "./lists/keymap-style";
Expand Down Expand Up @@ -273,6 +274,7 @@ export const commands: CommandsSubgroup = {
...TimerOpacityCommands,
...HighlightModeCommands,
...TapeModeCommands,
...TapeMarginCommands,
...SmoothLineScrollCommands,
...ShowAllLinesCommands,
...TypingSpeedUnitCommands,
Expand Down
19 changes: 19 additions & 0 deletions frontend/src/ts/commandline/lists/tape-margin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Config, * as UpdateConfig from "../../config";
import { Command } from "../types";

const commands: Command[] = [
{
id: "changeTapeMargin",
display: "Tape margin...",
icon: "fa-tape",
input: true,
defaultValue: (): string => {
return Config.tapeMargin.toString();
},
exec: ({ input }): void => {
if (input === undefined || input === "") return;
UpdateConfig.setTapeMargin(parseFloat(input));
},
},
];
export default commands;
29 changes: 29 additions & 0 deletions frontend/src/ts/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,34 @@ export function setTapeMode(
return true;
}

export function setTapeMargin(
value: ConfigSchemas.TapeMargin,
nosave?: boolean
): boolean {
if (value < 10) {
value = 10;
}
if (value > 90) {
value = 90;
}

if (
!isConfigValueValid("max line width", value, ConfigSchemas.TapeMarginSchema)
) {
return false;
}

config.tapeMargin = value;

saveToLocalStorage("tapeMargin", nosave);
ConfigEvent.dispatch("tapeMargin", config.tapeMargin, nosave);

// trigger a resize event to update the layout - handled in ui.ts:108
$(window).trigger("resize");

return true;
}

export function setHideExtraLetters(val: boolean, nosave?: boolean): boolean {
if (!isConfigValueValidBoolean("hide extra letters", val)) return false;

Expand Down Expand Up @@ -2053,6 +2081,7 @@ export async function apply(
setLazyMode(configObj.lazyMode, true);
setShowAverage(configObj.showAverage, true);
setTapeMode(configObj.tapeMode, true);
setTapeMargin(configObj.tapeMargin, true);

ConfigEvent.dispatch(
"configApplied",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/ts/constants/default-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ const obj = {
lazyMode: false,
showAverage: "off",
tapeMode: "off",
tapeMargin: 10,
maxLineWidth: 0,
} as Config;

Expand Down
45 changes: 45 additions & 0 deletions frontend/src/ts/pages/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,11 @@ async function initGroups(): Promise<void> {
UpdateConfig.setTapeMode,
"button"
) as SettingsGroup<ConfigValue>;
groups["tapeMargin"] = new SettingsGroup(
"tapeMargin",
UpdateConfig.setTapeMargin,
"button"
) as SettingsGroup<ConfigValue>;
groups["timerOpacity"] = new SettingsGroup(
"timerOpacity",
UpdateConfig.setTimerOpacity,
Expand Down Expand Up @@ -694,6 +699,10 @@ async function fillSettingsPage(): Promise<void> {
Config.customLayoutfluid.replace(/#/g, " ")
);

$(".pageSettings .section[data-config-name='tapeMargin'] input").val(
Config.tapeMargin
);

setEventDisabled(true);
if (!groupsInitialized) {
await initGroups();
Expand Down Expand Up @@ -1159,6 +1168,42 @@ $(
}
});

$(
".pageSettings .section[data-config-name='tapeMargin'] .inputAndButton button.save"
).on("click", () => {
const didConfigSave = UpdateConfig.setTapeMargin(
parseFloat(
$(
".pageSettings .section[data-config-name='tapeMargin'] .inputAndButton input"
).val() as string
)
);
if (didConfigSave) {
Notifications.add("Saved", 1, {
duration: 1,
});
}
});

$(
".pageSettings .section[data-config-name='tapeMargin'] .inputAndButton input"
).on("keypress", (e) => {
if (e.key === "Enter") {
const didConfigSave = UpdateConfig.setTapeMargin(
parseFloat(
$(
".pageSettings .section[data-config-name='tapeMargin'] .inputAndButton input"
).val() as string
)
);
if (didConfigSave) {
Notifications.add("Saved", 1, {
duration: 1,
});
}
}
});

$(
".pageSettings .section[data-config-name='maxLineWidth'] .inputAndButton button.save"
).on("click", () => {
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/ts/test/caret.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,10 @@ function getTargetPositionLeft(
} else {
const wordsWrapperWidth =
$(document.querySelector("#wordsWrapper") as HTMLElement).width() ?? 0;
const tapeMargin = wordsWrapperWidth * (Config.tapeMargin / 100);

result =
wordsWrapperWidth / 2 -
tapeMargin -
(fullWidthCaret && isLanguageRightToLeft ? fullWidthCaretWidth : 0);

if (Config.tapeMode === "word" && inputLen > 0) {
Expand Down
31 changes: 24 additions & 7 deletions frontend/src/ts/test/test-ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,14 @@ ConfigEvent.subscribe((eventKey, eventValue, nosave) => {
if (eventKey === "tapeMode" && !nosave) {
if (eventValue === "off") {
$("#words").css("margin-left", "unset");
$("#liveStatsMini").css("display", "").css("justify-content", "");
} else {
scrollTape();
$("#liveStatsMini")
.css("display", "flex")
.css("justify-content", "center");
}
updateLiveStatsMargin();
}

if (eventKey === "tapeMargin" && !nosave) {
updateLiveStatsMargin();
}

if (typeof eventValue !== "boolean") return;
Expand Down Expand Up @@ -474,7 +475,7 @@ export async function updateWordsInputPosition(initial = false): Promise<void> {

if (Config.tapeMode !== "off") {
el.style.top = targetTop + "px";
el.style.left = "50%";
el.style.left = Config.tapeMargin + "%";
return;
}

Expand Down Expand Up @@ -949,7 +950,7 @@ export function scrollTape(): void {
.stop(true, false)
.animate(
{
marginLeft: "50%",
marginLeft: Config.tapeMargin + "%",
},
SlowTimer.get() ? 0 : 125
);
Expand Down Expand Up @@ -1000,7 +1001,9 @@ export function scrollTape(): void {
}
}
}
const newMargin = wordsWrapperWidth / 2 - (fullWordsWidth + currentWordWidth);

const tapeMargin = wordsWrapperWidth * (Config.tapeMargin / 100);
const newMargin = tapeMargin - (fullWordsWidth + currentWordWidth);
if (Config.smoothLineScroll) {
$("#words")
.stop(true, false)
Expand Down Expand Up @@ -1478,6 +1481,20 @@ function updateWordsWidth(): void {
}
}

function updateLiveStatsMargin(): void {
if (Config.tapeMode === "off") {
$("#liveStatsMini").css({
"justify-content": "start",
"margin-left": "unset",
});
} else {
$("#liveStatsMini").css({
"justify-content": "center",
"margin-left": Config.tapeMargin + "%",
});
}
}

function updateLiveStatsOpacity(value: TimerOpacity): void {
$("#barTimerProgress").css("opacity", parseFloat(value as string));
$("#liveStatsTextTop").css("opacity", parseFloat(value as string));
Expand Down
4 changes: 4 additions & 0 deletions packages/contracts/src/schemas/configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ export type HighlightMode = z.infer<typeof HighlightModeSchema>;
export const TapeModeSchema = z.enum(["off", "letter", "word"]);
export type TapeMode = z.infer<typeof TapeModeSchema>;

export const TapeMarginSchema = z.number().min(10).max(90);
export type TapeMargin = z.infer<typeof TapeMarginSchema>;

export const TypingSpeedUnitSchema = z.enum([
"wpm",
"cpm",
Expand Down Expand Up @@ -354,6 +357,7 @@ export const ConfigSchema = z
minWpmCustomSpeed: MinWpmCustomSpeedSchema,
highlightMode: HighlightModeSchema,
tapeMode: TapeModeSchema,
tapeMargin: TapeMarginSchema,
typingSpeedUnit: TypingSpeedUnitSchema,
ads: AdsSchema,
hideExtraLetters: z.boolean(),
Expand Down

0 comments on commit c9789d6

Please sign in to comment.