Commit graph

5354 commits

Author SHA1 Message Date
Jack
3aaf8e0e31
refactor: convert focus state to a signal (@miodec) (#7380) 2026-01-16 21:32:18 +01:00
Miodec
a40d1903c7 fix: 404 page not working 2026-01-16 16:59:41 +01:00
Biplav Barua
9896c1816e
refactor: move event handlers from simple-modals to respective files (@biplavbarua) (#7333)
This PR addresses the `TODO` in `simple-modals.ts` by moving event
handlers to their respective page controller files
(`account-settings.ts` and `settings.ts`).

**Key Changes:**
1.  Moved `.pageAccountSettings` handlers to `account-settings.ts`.
2.  Moved `.pageSettings` handlers to `settings.ts`.
3. Extracted `PopupKey`, `list`, and `showPopup` to
`simple-modals-base.ts` to resolve circular dependencies introduced by
importing page controllers in `simple-modals.ts` (which now import
`showPopup` from base).

**Testing:**
- Verified no circular dependencies with `madge`.
- Verified type safety with `tsc`.
- Verified build success.

---------

Co-authored-by: Jack <jack@monkeytype.com>
2026-01-15 16:16:50 +01:00
Francis Eugene Casibu
a6cd53caf0
refactor(modals): remove jquery in ts/modals (@fcasibu) (#7292)
### Description

<!-- Please describe the change(s) made in your PR -->

Refactor `frontend/ts/modals/*` to replace jQuery (some still TODO).
I've also modified `dom.ts` to add `setValue` for
`ElementsWithUtils<ElementWithValue>` instance. Still trying to grep the
whole flow/codebase, so usage of `qsr` or `qs` is uncertain (Probably
use `qsr` always? Can find non-existing elements that way or developer
error). There are a lot of atomic commits in this PR, feel free to
squash.

While doing the refactor, also stumbled upon things that I have
questions for (didn't made any changes to them), which I thought can be
improved:

- `custom-generator.ts:146`: The user is able to write minLength >
maxLength. Is this behavior correct?
- `custom-test-duration.ts:99`: It seems like `parseInput`, always
expects a non nullable string, and we seem to always expect that
`#customTestDurationModal input` to always exist (so I used `qsr`),
which makes the conditions `val !== null`, `!isNaN(val)` seem to be
unnecessary (val is never null or NaN, tbh also isFinite, and val >= 0
is the only valid condition)
- `custom-text.ts:169`: These elements does not seem exist
`.randomWordsCheckbox`, `.replaceNewlineWithSpace`, `.typographyCheck`,
and `.delimiterCheck` (last two is just in a challenge file). Are they
good to remove?
- `edit-preset.ts:146`: Noticed that we're not updaitng the DOM, since
for the most part, in the logic, we mostly use `state.checkboxes`, so no
problem happens, but I think it is also a good idea to update the DOM to
match current state? Either calling `updateUI()` here or just changing
the checked value inline.
- `quote-rate.ts:89`: `getQuoteStats` expects a `quote` but we're not
really passing anything to it, so this essentially does nothing, since
it returns immediately on `!quote`

### Checks

- [x] Adding/modifying Typescript code?
  - [x] I have used `qs`, `qsa` or `qsr` instead of JQuery selectors.
- [x] Check if any open issues are related to this PR; if so, be sure to
tag them below.
- [x] Make sure the PR title follows the Conventional Commits standard.
(https://www.conventionalcommits.org for more info)
- [x] Make sure to include your GitHub username prefixed with @ inside
parentheses at the end of the PR title.

<!-- label(optional scope): pull request title (@your_github_username)
-->

<!-- I know I know they seem boring but please do them, they help us and
you will find out it also helps you.-->

Related #7186

<!-- the issue(s) your PR resolves if any (delete if that is not the
case) -->
<!-- please also reference any issues and or PRs related to your pull
request -->
<!-- Also remove it if you are not following any issues. -->

<!-- pro tip: you can mention an issue, PR, or discussion on GitHub by
referencing its hash number e.g:
[#1234](https://github.com/monkeytypegame/monkeytype/pull/1234) -->

<!-- pro tip: you can press . (dot or period) in the code tab of any
GitHub repo to get access to GitHub's VS Code web editor Enjoy! :) -->

#7186

---------

Co-authored-by: Miodec <jack@monkeytype.com>
2026-01-15 15:58:36 +01:00
Leonabcd123
ea3a545f71
fix(tags): Update tags after deletion (@Leonabcd123) (#7338)
### Description

Fixes the following bug:

- Create tag
- Go to account page
- Add that tag to some result
- Delete the tag
- Go back to account page
- Notice that it still thinks that the test has a tag

---------

Co-authored-by: Jack <jack@monkeytype.com>
2026-01-15 15:15:32 +01:00
Miodec
a856b7659f fix: single list commandline not working on initial show 2026-01-15 10:01:08 +01:00
Miodec
e04d6e88f4 fix: incorrect path 2026-01-14 22:42:34 +01:00
Miodec
d2fd5c0cf8 refactor: restructure the components folder 2026-01-14 22:21:25 +01:00
Christian Fehmer
a795b9dab3
refactor: convert about page to a component (@fehmer, @miodec) (#7350)
Co-authored-by: Miodec <jack@monkeytype.com>
2026-01-14 22:08:54 +01:00
okaybro
c31dd1e05f
fix: correct streak offset validation to allow .5 decrements (@Chaitanya-Keyal) (#7363)
### Description

The current streak hour offset validation fails for values like `-5.5`
because `-5.5 % 1` evaluates to `-0.5`, causing the fractional check to
fail.

This PR simplifies the validation logic by multiplying the value by 2
and checking whether the result is an integer. This correctly allows
only whole-hour and half-hour (`.5`) offsets while handling negative
values properly.

<img width="1667" height="1320" alt="Screenshot 2026-01-14 203300"
src="https://github.com/user-attachments/assets/3c5ccef5-a173-4df7-9ff2-037d4417ae10"
/>


### Checks

- [x] Check if any open issues are related to this PR; if so, be sure to
tag them below.
- [x] Make sure the PR title follows the Conventional Commits standard.
(https://www.conventionalcommits.org for more info)
- [x] Make sure to include your GitHub username prefixed with @ inside
parentheses at the end of the PR title.

<!-- label(optional scope): pull request title (@your_github_username)
-->

<!-- I know I know they seem boring but please do them, they help us and
you will find out it also helps you.-->

Closes #7204, related PRs #7269, #7362

<!-- the issue(s) your PR resolves if any (delete if that is not the
case) -->
<!-- please also reference any issues and or PRs related to your pull
request -->
<!-- Also remove it if you are not following any issues. -->

<!-- pro tip: you can mention an issue, PR, or discussion on GitHub by
referencing its hash number e.g:
[#1234](https://github.com/monkeytypegame/monkeytype/pull/1234) -->

<!-- pro tip: you can press . (dot or period) in the code tab of any
GitHub repo to get access to GitHub's VS Code web editor Enjoy! :) -->
2026-01-14 17:54:11 +01:00
Seif Soliman
e37b44799a
fix(caret): positioning for mixed language directions in zen (@byseif21) (#7281)
Co-authored-by: Jack <jack@monkeytype.com>
2026-01-14 17:39:03 +01:00
Christian Fehmer
ae45d8e1fa
fix: show correct local reset time if streak offset has 30minute offset (@fehmer) (#7362)
closes #7204
2026-01-14 16:25:44 +01:00
Miodec
60c342004f chore: lowercase strings 2026-01-14 16:22:37 +01:00
Christian Fehmer
6c92206ace
refactor: convert footer to a component (@fehmer, @miodec) (#7346)
Co-authored-by: Miodec <jack@monkeytype.com>
2026-01-14 16:19:51 +01:00
Christian Fehmer
3534f8fc31
fix(theme): fix button roundness in dark_note theme (@fehmer) (#7358) 2026-01-14 11:01:53 +01:00
Christian Fehmer
50dfe5f6f4
refactor: rewrite onDOMReady to be closer to jquery ready implementation (@fehmer) (#7356) 2026-01-14 10:28:19 +01:00
Christian Fehmer
3e899b11fc
fix: analytics not loading (@fehmer) (#7354) 2026-01-13 22:09:38 +01:00
Christian Fehmer
9fadc4a493
fix: use onDOMReady for skeleton calls (@fehmer) (#7355)
!nuf
2026-01-13 22:06:22 +01:00
Miodec
c3b5863aa5 fix: move result hashing
!nuf
2026-01-13 20:48:44 +01:00
Miodec
ad5136ef3d fix(result page): long tests showing with graphs from previous tests 2026-01-13 20:03:10 +01:00
Miodec
5ebbc8eec5 chore: clear chart data if result has no data 2026-01-13 19:05:14 +01:00
Miodec
504bad4461 fix: activivity graph sometimes overflowing the container
closes #7157
closes #5942
2026-01-13 18:43:38 +01:00
Miodec
68fe2caf83 chore: dont check github version in dev 2026-01-13 17:24:42 +01:00
Miodec
560768eb38 chore: remove unused code 2026-01-13 14:34:48 +01:00
Leonabcd123
6af2c2dcae
fix(tamil-old): set ligatures to true in tamil old (@Leonabcd123) (#7349)
### Description

Closes #7347
2026-01-13 14:28:35 +01:00
Christian Fehmer
68dfc5c3a1
chore: extract media queries to sass mixin (@fehmer) (#7351) 2026-01-13 14:27:16 +01:00
Miodec
12e0035bfd refactor: replace custom key with semantic kbd element 2026-01-13 09:54:42 +01:00
Miodec
2beb0534b3 chore: upgrade oxc 2026-01-12 13:02:58 +01:00
Christian Fehmer
50a4692033
fix: disable oxlint-overlay on production (@fehmer) (#7348) 2026-01-12 13:02:04 +01:00
Miodec
2829864ae8 fix: component mounting not working in prod 2026-01-11 22:27:48 +01:00
Jack
3163f1e80c
refactor: covert version button and version history modal to a component (@miodec, @fehmer) (#7343)
Also adds a modal component.
Also reworks mounting logic.

---------

Co-authored-by: Christian Fehmer <cfe@sexy-developer.com>
2026-01-11 22:15:54 +01:00
Jack
9799c38698
refactor: convert active page to a signal (@miodec) (#7342) 2026-01-11 15:13:47 +01:00
Leonabcd123
21b0975066
fix(tags): update tag pbs after adding/removing tags from result (@Leonabcd123) (#7337)
### Description

Update tag pbs after adding or removing a tag from some test result.
Fixes the following bug:

- Create a tag
- Click on the tag to mark it as active to apply it automatically for
the following tests
- Complete a test
- Remove the tag from the test
- Complete another test, while being slower than the previous test
- Notice that the tag pb is still the one for the old test, even though
it doesn't have the tag anymore

---------

Co-authored-by: Jack <jack@monkeytype.com>
2026-01-10 22:24:53 +01:00
Martin
ac3435b894
fix(polyglot): use per-word language for lowercasing (@mpodhaisky) (#7335)
### Description

In polyglot mode, some words are generated incorrectly because the
lowercasing of randomWord does not take the actual language of the word
into account.

This change modifies the lowercasing check to base the comparison on the
language provided by PolyglotWordset.

Co-authored-by: Jack <jack@monkeytype.com>
2026-01-10 22:24:36 +01:00
Leonabcd123
405b0ef125
fix(clear-tag-pb): update snapshot after clearing tag pb (@Leonabcd123, @fehmer) (#7332)
Co-authored-by: Jack <jack@monkeytype.com>
2026-01-10 22:23:36 +01:00
Serge
3057d91627
impr(language): update Swiss German language files (@egemasta) (#7329)
## Description

Updated Swiss German language files with improved word selection,
corrections, and Swiss-specific vocabulary enhancements.

## Changes

- Modified `swiss_german.json` (200 words)
- Modified `swiss_german_1k.json` (1000 words)  
- Modified `swiss_german_2k.json` (2000 words)

## Type of Change

- [ ] New feature
- [x] Improvement to existing feature
- [ ] Bug fix
- [ ] Documentation update

## Specific Improvements Made

### Swiss German Vocabulary Additions
- Added authentic Swiss German words like: `Velo` (bicycle), `Spital`
(hospital), `parkieren` (to park)
- Included Swiss-specific food terms: `Znüni`, `Zvieri`, `Rüebli`,
`Glace`
- Added Swiss city names with proper spelling: `Zürich`, `Bern`,
`Basel`, `Luzern`, etc.

### Spelling Corrections (Swiss vs. German Standard)
- Replaced German `ß` with Swiss `ss` throughout all files
- Examples: `groß` → `gross`, `Straße` → `Strasse`, `heißt` → `heisst`
- Ensured consistency with Swiss High German orthography (BCP47: de-CH)

### Word Selection Improvements
- Removed duplicate or non-Swiss vocabulary
- Prioritized commonly used Swiss German words
- Maintained appropriate difficulty progression across 200/1k/2k word
lists

## Regional Dialect Considerations

- All changes follow **Swiss High German** (Schweizer Hochdeutsch)
standards
- BCP47 language code: `de-CH` is correctly set
- Vocabulary reflects Swiss usage, not German or Austrian variants
- Special attention to Swiss-German loanwords and regionalisms

## Testing Performed

- [x] Verified JSON syntax is valid (no trailing commas)
- [x] Confirmed word counts match file names (200/1000/2000)
- [x] Tested that no expletive words are included
- [x] Checked language appears correctly in `_list` and `_groups` files
- [x] Manual typing test performed to verify readability

## Word Count Verification

- `swiss_german.json`: 200 words ✓
- `swiss_german_1k.json`: 1000 words ✓
- `swiss_german_2k.json`: 2000 words ✓

## Source Attribution

Words sourced from:
- https://1000mostcommonwords.com/1000-most-common-swiss-german-words/
- https://de.wiktionary.org (for 2k list)

## Additional Context

These changes improve the authenticity and usability of Swiss German
language support in Monkeytype, making it more accurate for Swiss users
and learners of Swiss High German.

## Screenshots

_N/A - No visual changes to UI_
2026-01-10 22:21:53 +01:00
Umut
f3fa9646d9
docs: Fix double whitespace in privacy-policy.html (@ChopChopp) (#7327)
### Description

I removed the `&nbsp;` as it is explicity requesting a whitespace,
eventhough the formatting is already naturally setting a whitespace.
This lead to a double whitespace:
<img width="673" height="33" alt="image"
src="https://github.com/user-attachments/assets/84b4243f-a867-4cf9-a177-f0dfb5b35016"
/>
<!-- label(docs): Fix double whitespace in privacy-policy.html
(@ChopChopp) -->
2026-01-10 22:21:13 +01:00
Miodec
3e02ae8385 style(scroll to top button): fix icon placement 2026-01-10 22:05:08 +01:00
Christian Fehmer
6dc254dc45
chore: add minimal solidjs integration (@fehmer, @miodec) (#7341)
Co-authored-by: Miodec <jack@monkeytype.com>
2026-01-10 21:35:29 +01:00
Seif Soliman
69cc227c87
fix(event-handlers): commandOverride not working due to incorrect check (@byseif21) (#7330)
it returns null when attribute doesn't exist, not undefined
2026-01-08 17:58:01 +01:00
Miodec
e2d9b79332 fix: skip if annotation has display false 2026-01-07 21:47:05 +01:00
Miodec
5e70e3398c impr(test result): recalculate min max chart values when toggling a dataset 2026-01-07 21:47:05 +01:00
Miodec
c1c6c7dac0 impr(result): add button to quickly toggle chart scale 2026-01-07 21:47:05 +01:00
Murad Bashirov
2e959e592c
impr(quotes): add Azerbaijani quotes (@m-spitfire) (#7315)
### Description

Added Azerbaijani quotes.

### Checks

- [x] Adding quotes?
- [x] Make sure to include translations for the quotes in the
description (or another comment) so we can verify their content.

### Translations

(used chatgpt, I hope it's okay)

1. God must be in the heart of every person… And when He is not there…
everything else is transient
2. There is no such thing as coincidence in life. From the paths that
appear before you, you choose one yourself. Either you think long and
hard about which path to take, or you step forward blindly, trusting
your luck.
3. Trying to explain something to a fool is no different from trying to
pour water into a sieve.
4. Strange—very strange. A photograph taken while a person is alive
carries one appearance, but once they die, it is as if the photograph
itself changes form. If you look closely into their eyes, you can enter
their inner world. The photographs seem to want to ask you something.
They look after you, and keep looking… As if they want to come with you.
They can’t…
5. The dead were at peace. The ones who truly needed resurrection were
the “living.”
6. There is a state women sometimes fall into when, even if no one has
hurt them and no misfortune has occurred, they still feel the need to be
hurt and unhappy. (Original: "У женщины, например, бывает иногда
потребность чувствовать себя несчастною, обиженною, хотя бы не было ни
обид, ни несчастий." from Униженные и оскорбленные, Ф. М. Достоевский)
7. I have now understood one thing: in this meaningful and harmonious
life, only those who live meaningless lives are mere patches. A person
who owns their life, their existence, and true values is not a patch in
this world—they are life itself.
8. The sun has risen in the yard; since you will not see that day, what
use is its light? Outside, the grass has grown and the trees have
blossomed; but what use are those flowers, those meadows, without you?
9. If you educate a man, you educate only one person. If you educate a
woman, you educate an entire family.
10. What is death? At first glance, it is an ordinary, simple question,
yet it contains many peculiarities and complexities. The most ordinary
and well-known notion is that a person should die of old age, without
any particular cause or illness. That is, as a biological being, a human
is born, grows, ages, and dies. Death is the final cessation of all
bodily organs and brain functions as a result of aging… But let us
see—can most people reach death in this natural way? They cannot. To die
like this, one must live their entire life in a natural flow, without
stress or depression, without harm or danger from others, without the
influence of environment or nature… One must live without anger, sorrow,
suffering, pain, or tears…
11. There are people who do not appreciate the good unless they
encounter evil and endure its suffering. Among them are those who, after
seeing the face of evil just once, cling firmly to goodness for the rest
of their lives and worship it with their hearts. But there are also
those who quickly forget both the badness of evil and the goodness of
good, clinging now to one, now to the other, and in doing so ruin both
their own lives and the lives of others.
12. A person understands the sweetness of the moments they have lived
during times of longing, my Sara.
13. I kiss you, my hope. Yours, Mirza.
14. Though the wound in my heart aches silently, its surface has covered
with embers.
15. And those jet-black, long, thick eyelashes—she lifted them in such a
way that it was as if she were opening the heavy page of an ancient
book, and those lashes cast a shadow over half of Tahmina’s face. Once
Zaur had been drinking and said that when you lift your eyelashes, it
feels as though a new page is being opened in the history of humanity…
17. It is impossible to portray a people who waged a sharp and
courageous struggle for freedom against the caliphate for more than
twenty years as a disorderly crowd living a cheerful and carefree life.
17. I have learned that courage is not the absence of fear, but the
triumph over it. The brave person is not one who feels no fear, but one
who conquers it.
18. Every style of writing and every genre that is connected with the
people’s common ideal and sheds light on their life is beneficial.
19. It is possible for colonizers to officially impose a foreign
language on the local population, even when the composition of
native-language speakers is very mixed. This happened, for example, with
the Russian language in the Russian Empire, English in India, French in
Algeria, and Persian in Iran. People are forced to use this imposed
language in meetings and the media, on the pages of books, and in
educational materials. But how can one forcibly impose on a people their
proverbs and sayings, lullabies and laments, ritual and love songs,
fairy tales and legends, an entire epic tradition? These are eternal and
primordial, and no people can forcibly impose the folkloric harmony of
its mother tongue on another people.
20. No matter how complex a person may be, in the end they express
themselves in a very simple way.
21. There’s a saying, boss: better for a man to die than for his name to
be ruined—who would give work to thief Imaş, and who would want to work
with him?
22.
23. People who hear of some extraordinary phenomenon start proposing to
explain it with improbable hypotheses. First consider the simplest
explanation: that it's all nonsense.
24. The bride is my broom. Wherever I put her, that’s where she must
stay.

Signed-off-by: Murad Bashirov <carlsonmu@gmail.com>
Co-authored-by: Jack <jack@monkeytype.com>
2026-01-07 20:03:29 +01:00
Miodec
dc5974103e impr(dom utils): consider padding in slide functions
also adds options to slideup to optionally not hide the element
2026-01-07 19:31:24 +01:00
Jack
2949cd901d
impr(dom utils): add slideUp and slideDown utils (@miodec) (#7323)
!nuf
2026-01-07 13:14:48 +01:00
thanos
33d5605870
refactor(popups): Remove jQuery from popups (@thanoskn) (#7321)
### Description

Replace jQuery with dom utils

### Checks

- [x] Adding/modifying Typescript code?
  - [x] I have used `qs`, `qsa` or `qsr` instead of JQuery selectors.
- [x] Check if any open issues are related to this PR; if so, be sure to
tag them below.
- [x] Make sure the PR title follows the Conventional Commits standard.
(https://www.conventionalcommits.org for more info)
- [x] Make sure to include your GitHub username prefixed with @ inside
parentheses at the end of the PR title.

### Related #7186
2026-01-07 11:54:24 +01:00
Miodec
a7d8bd23d8 fix: remove type annotation from js code 2026-01-06 18:38:13 +01:00
Miodec
b9ee8b7d23 chore: bump oxc 2026-01-06 17:04:02 +01:00
Miodec
1294499d0f fix: themes ui list shows clipped when selected or hovered
closes #7318
2026-01-06 16:56:51 +01:00