Skip to content
Open
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
16 changes: 16 additions & 0 deletions frontend/src/html/pages/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,22 @@
<button data-config-value="next_three_words">next three words</button>
</div>
</div>
<div class="section" data-config-name="typedWords">
<div class="groupTitle">
<i class="fas fa-eye"></i>
<span>typed words</span>
<button class="text" tabindex="-1">
<i class="fas fa-fw fa-link"></i>
</button>
</div>
<div class="text">Change how typed words are shown.</div>
<div class="buttons">
<button data-config-value="show">show</button>
<button data-config-value="hide">hide</button>
<button data-config-value="fade">fade</button>
<button data-config-value="dots">dots</button>
</div>
</div>
<div class="section" data-config-name="tapeMode">
<div class="groupTitle">
<i class="fas fa-tape"></i>
Expand Down
43 changes: 43 additions & 0 deletions frontend/src/styles/animations.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@
}
}

@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}

@keyframes caretFlashSmooth {
0%,
100% {
Expand Down Expand Up @@ -130,3 +139,37 @@
background-position: 0% 50%;
}
}

@keyframes typedWordsFadeIn {
0% {
opacity: 0;
}
75% {
opacity: 0.4;
}
100% {
opacity: 1;
}
}

@keyframes typedWordsToDust {
0% {
transform: scale(1);
color: var(--current-color);
}
10% {
/* transform: scale(1); */
}
15% {
transform: scale(1);
color: var(--c-dot);
}
80% {
/* transform: scale(0.5); */
color: var(--c-dot);
}
100% {
transform: scale(0.4);
color: transparent;
}
}
61 changes: 61 additions & 0 deletions frontend/src/styles/test.scss
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,8 @@
--untyped-letter-color: var(--sub-color);
--incorrect-letter-color: var(--colorful-error-color);
--extra-letter-color: var(--colorful-error-extra-color);
--c-dot: var(--main-color);
--c-dot--error: var(--colorful-error-color);
&.blind .word.error {
border-bottom: 2px solid transparent;
}
Expand Down Expand Up @@ -518,6 +520,62 @@
}
}
}

&.typed-words-hide {
.word.typed {
opacity: 0;
}
}

&.typed-words-fade {
.word.typed {
animation: fadeOut 250ms ease-in 1 forwards;
}
}

&.typed-words-dots:not(.withLigatures) {
/* transform already typed letters into appropriately colored dots */

.word letter {
position: relative;
&::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 1em;
aspect-ratio: 1;
border-radius: 50%;
opacity: 0;
}
}
.typed letter {
color: var(--bg-color);
animation: typedWordsToDust 200ms ease-out 0ms 1 forwards !important;
&::after {
animation: typedWordsFadeIn 100ms ease-in 100ms 1 forwards;
background: var(--c-dot);
}
}
&:not(.blind) {
.word letter.incorrect::after {
background: var(--c-dot--error);
}
}

@media (prefers-reduced-motion) {
.typed letter {
animation: none !important;
transform: scale(0.4);
color: transparent;
&::after {
animation: none !important;
opacity: 1;
}
}
}
}
}

.word {
Expand Down Expand Up @@ -1416,6 +1474,9 @@
rgba(0, 0, 0, 0) 99%
);
}

--c-dot: var(--text-color);
--c-dot--error: var(--error-color);
}
#memoryTimer,
#layoutfluidTimer {
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/ts/commandline/commandline-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,11 @@ export const commandlineConfigMetadata: CommandlineConfigMetadataObject = {
options: "fromSchema",
},
},
typedWords: {
subgroup: {
options: "fromSchema",
},
},
tapeMode: {
subgroup: {
options: "fromSchema",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/ts/commandline/lists.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ export const commands: CommandsSubgroup = {
"timerColor",
"timerOpacity",
"highlightMode",
"typedWords",

"tapeMode",
"tapeMargin",
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/ts/config-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,12 @@ export const configMetadata: ConfigMetadataObject = {
changeRequiresRestart: false,
group: "appearance",
},
typedWords: {
icon: "fa-eye",
displayString: "typed words",
changeRequiresRestart: false,
group: "appearance",
},
tapeMode: {
icon: "fa-tape",
triggerResize: true,
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 @@ -77,6 +77,7 @@ const obj: Config = {
minWpm: "off",
minWpmCustomSpeed: 100,
highlightMode: "letter",
typedWords: "show",
typingSpeedUnit: "wpm",
ads: "result",
hideExtraLetters: false,
Expand Down
1 change: 1 addition & 0 deletions frontend/src/ts/pages/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ async function initGroups(): Promise<void> {
groups["liveAccStyle"] = new SettingsGroup("liveAccStyle", "button");
groups["liveBurstStyle"] = new SettingsGroup("liveBurstStyle", "button");
groups["highlightMode"] = new SettingsGroup("highlightMode", "button");
groups["typedWords"] = new SettingsGroup("typedWords", "button");
groups["tapeMode"] = new SettingsGroup("tapeMode", "button");
groups["tapeMargin"] = new SettingsGroup("tapeMargin", "input", {
validation: { schema: true, inputValueConvert: Number },
Expand Down
10 changes: 9 additions & 1 deletion frontend/src/ts/test/test-ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -450,10 +450,17 @@ function updateWordWrapperClasses(): void {
const existing =
wordsEl?.className
.split(/\s+/)
.filter((className) => !className.startsWith("highlight-")) ?? [];
.filter(
(className) =>
!className.startsWith("highlight-") &&
!className.startsWith("typed-words-"),
) ?? [];
if (Config.highlightMode !== null) {
existing.push("highlight-" + Config.highlightMode.replaceAll("_", "-"));
}
if (Config.typedWords !== null) {
existing.push("typed-words-" + Config.typedWords.replaceAll("_", "-"));
}
wordsEl.className = existing.join(" ");

updateWordsWidth();
Expand Down Expand Up @@ -2033,6 +2040,7 @@ ConfigEvent.subscribe(({ key, newValue }) => {
if (
[
"highlightMode",
"typedWords",
"blindMode",
"indicateTypos",
"tapeMode",
Expand Down
100 changes: 0 additions & 100 deletions frontend/static/themes/dark_note.css
Original file line number Diff line number Diff line change
Expand Up @@ -88,103 +88,3 @@ body::before {
text-decoration-color: var(--error-color);
text-decoration-thickness: 2px;
}

/* transform already typed letters into appropriately colored dots */

/* setting variables to the appropriate colors */
#wordsWrapper {
--c-dot: var(--text-color);
--c-dot--error: var(--error-color);
}

.colorfulMode {
--c-dot: var(--main-color);
--c-dot--error: var(--colorful-error-color);
}

#words .typed letter {
animation: darkNoteToDust 200ms ease-out 0ms 1 forwards !important;
}
#words .typed letter::after {
animation: darkNoteFadeIn 100ms ease-in 100ms 1 forwards;
}

.word letter {
position: relative;
}

#words:not(.withLigatures) .word letter::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 1em;
height: 1em;
border-radius: 50%;
opacity: 0;
}

#wordsWrapper .typed letter::after {
background: var(--c-dot);
}

#wordsWrapper #words:not(.blind) .word letter.incorrect::after {
background: var(--c-dot--error);
}

/* hide hint during dot transformation */
hint {
transition: 300ms ease opacity;
opacity: 1;
}

#wordsWrapper .word:not(.active) letter.incorrect hint {
opacity: 0;
}

@media (prefers-reduced-motion) {
#words .typed letter {
animation: none !important;
transform: scale(0.4);
color: transparent;
}
#words .typed letter::after {
animation: none !important;
opacity: 1;
}
}

@keyframes darkNoteFadeIn {
0% {
opacity: 0;
}
75% {
opacity: 0.4;
}
100% {
opacity: 1;
}
}

@keyframes darkNoteToDust {
0% {
transform: scale(1);
color: var(--current-color);
}
10% {
/* transform: scale(1); */
}
15% {
transform: scale(1);
color: var(--c-dot);
}
80% {
/* transform: scale(0.5); */
color: var(--c-dot);
}
100% {
transform: scale(0.4);
color: transparent;
}
}
4 changes: 4 additions & 0 deletions packages/schemas/src/configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@ export const HighlightModeSchema = z.enum([
]);
export type HighlightMode = z.infer<typeof HighlightModeSchema>;

export const TypedWordsSchema = z.enum(["show", "hide", "fade", "dots"]);
export type TypedWords = z.infer<typeof TypedWordsSchema>;

export const TapeModeSchema = z.enum(["off", "letter", "word"]);
export type TapeMode = z.infer<typeof TapeModeSchema>;

Expand Down Expand Up @@ -441,6 +444,7 @@ export const ConfigSchema = z
timerColor: TimerColorSchema,
timerOpacity: TimerOpacitySchema,
highlightMode: HighlightModeSchema,
typedWords: TypedWordsSchema,
tapeMode: TapeModeSchema,
tapeMargin: TapeMarginSchema,
smoothLineScroll: z.boolean(),
Expand Down