Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
341 commits
Select commit Hold shift + click to select a range
2391bc5
fix(test config): punctuation and numbers disappearing when selected …
Miodec Apr 16, 2025
4abcc8c
impr: split keymap layouts into seperate files (@fehmer) (#6452)
fehmer Apr 16, 2025
e1c8e4a
impr(settings): use dropdown for custom layoutfluid (@fehmer) (#6445)
fehmer Apr 16, 2025
92d97c1
impr: optimize getFirstDayOfWeek (@fehmer) (#6457)
fehmer Apr 16, 2025
cac8835
chore: add oxlint (@miodec) (#6455)
Miodec Apr 16, 2025
33857d4
impr(frontend): reduce json minification logs on build
Miodec Apr 16, 2025
3207a20
refactor: reduce indentation by extracting code to a function
Miodec Apr 16, 2025
1582266
refactor: enable eqeqeq rule
Miodec Apr 16, 2025
0b05b3c
refactor: enable ban-ts-comment rule
Miodec Apr 16, 2025
bf0ce66
fix: lint issues
Miodec Apr 16, 2025
2d33e1d
chore: throw error when response in fetchJson() is not json (@NadAlab…
nadalaba Apr 16, 2025
8bec7da
chore: bump vite and vite plugins versions
Miodec Apr 16, 2025
55e7de7
docs: add layouts (@fehmer) (#6461)
fehmer Apr 17, 2025
312813c
fix(settings): Update layoutfluid on config change (@fehmer) (#6462)
fehmer Apr 17, 2025
fd75dd8
impr(quotes): add urdu quotes (@aitchz) (#6441)
HazHazardous Apr 17, 2025
644c59c
fix(theme): inconsistent/unreadable styling on settings page when usi…
fehmer Apr 17, 2025
6acaeb4
feat(theme): add Vesper theme (@SameerJS6) (#6443)
SameerJS6 Apr 17, 2025
bf002c0
feat(funbox): add layout mirror (@megalodon2710) (#6463)
megalodon2710 Apr 17, 2025
a8ce609
feat(language): add xhosa_3k (@aitchz) (#6464)
HazHazardous Apr 17, 2025
da67133
feat(funbox): add polyglot (@fehmer) (#6454)
fehmer Apr 18, 2025
2a4fe18
chore: release v25.16.1
Miodec Apr 18, 2025
4d570d3
fix: fix content-type check in fetchJson (@fehmer) (#6465)
fehmer Apr 18, 2025
2835a02
impr: add type safety to the config event observable
Miodec Apr 18, 2025
0bd49db
impr(funbox): notify user if polyglot languages are not valid
Miodec Apr 18, 2025
a910dda
chore: move word gen error definition to utils to fix circular depend…
Miodec Apr 18, 2025
c5d0f98
impr: use rainbow effect on rgb badges for reduced-motion (@fehmer) (…
fehmer Apr 18, 2025
a9c2f52
docs: order oxlint badge correctly (@fehmer) (#6470)
fehmer Apr 19, 2025
e0d1ee4
fix(settings): fix dropdown not rendered correctly (@fehmer) (#6468)
fehmer Apr 19, 2025
ff10bac
feat(theme): add sunset theme (@catdogdonkey) (#6467)
catdogdonkey Apr 19, 2025
74d54ac
fix: compatibility check for funboxes when switching test modes (@feh…
fehmer Apr 19, 2025
d651f28
feat(layout): add OPY (@robi-wan) (#6453)
robi-wan Apr 23, 2025
0c4352e
refactor: improve funbox-validation, add tests (@fehmer) (#6478)
fehmer Apr 23, 2025
d3f3a83
refactor: remove unnecessary json parse
Miodec Apr 23, 2025
ac1d6f0
feat(funbox): add ASL (@fehmer) (#6485)
fehmer Apr 23, 2025
a424f96
chore: upgrade oxlint
Miodec Apr 23, 2025
d863e8d
fix(keymap): dynamic legends not working correctly
Miodec Apr 24, 2025
86383cf
refactor(backend): improve redis and json.parse type safety with zod …
byseif21 Apr 24, 2025
f60dd0a
chore: remove false positive
Miodec Apr 24, 2025
a59f99a
refactor: protect against null, remove nullish coalescing
Miodec Apr 26, 2025
e06f7f4
refactor: add trycatch util (@miodec) (#6492)
Miodec Apr 26, 2025
ab9cef0
chore: swap monkeyerror for error to not expose actual error message …
Miodec Apr 26, 2025
b36bc9f
refactor: move layout names to contracts (@fehmer) (#6495)
fehmer Apr 28, 2025
212b8d3
refactor: make funbox settings an array (@fehmer) (#6487)
fehmer Apr 29, 2025
c253d2f
refactor: make customLayoutfluid an array (@fehmer) (#6494)
fehmer Apr 29, 2025
ae653be
chore: release v25.18.0
Miodec Apr 29, 2025
f0f27f0
chore: upgrade octokit/rest
Miodec Apr 29, 2025
e8c0fc0
chore: temporairly allow null discordIds
Miodec Apr 29, 2025
c666d13
impr: parse response from discord api with zod
Miodec Apr 29, 2025
511d8d1
chore: add sentry
Miodec Apr 29, 2025
b0ad7f7
chore: bump konami version
Miodec Apr 29, 2025
0db87ad
chore: move sentry to its own file, call set user
Miodec Apr 29, 2025
fee0b74
fix: remove double error message on failed release notes fetch
Miodec Apr 29, 2025
be794ac
chore: catch errors thrown when fetching release from github
Miodec Apr 29, 2025
5d22a92
chore: pass client version into sentry plugin
Miodec Apr 29, 2025
cbb7264
chore: pass client version into sentry plugin
Miodec Apr 29, 2025
2fc4d42
chore: ignore third party errors in sentry
Miodec Apr 29, 2025
93bcd3c
chore: missing optional chain
Miodec Apr 29, 2025
bbd5cf2
chore: remove analytics logging
Miodec Apr 29, 2025
c2f6ec8
fix: very slow generation of tests in large languages (@fehmer, @miod…
fehmer Apr 30, 2025
c2f2029
chore: unmask notifications in sentry
Miodec Apr 30, 2025
c6620ab
chore: register service worker manually, also catch errors
Miodec Apr 30, 2025
c8e964d
refactor: add hotfix mode to release package
Miodec Apr 30, 2025
53ca12f
fix(arabic egypt): remove offensive word
Miodec Apr 30, 2025
5d4f449
chore: dont use turbo cache in release script
Miodec Apr 30, 2025
bdaa3b1
chore: catch failed fetch requests to instatus api
Miodec Apr 30, 2025
faffc78
chore: only add sentry plugin when building from release package
Miodec Apr 30, 2025
055b7f0
chore: add a function to manually capture exceptions and send to sentry
Miodec Apr 30, 2025
ee378f3
fix: key elements being too close to surrounding text
Miodec Apr 30, 2025
9287e88
chore: temporairly try a different filtering behavior
Miodec Apr 30, 2025
255c4b9
fix: unable to link discord if user has no avatar
Miodec Apr 30, 2025
c51acf3
chore: dont sample random sessions without errors
Miodec Apr 30, 2025
827637c
chore: set commits on sentry release
Miodec May 1, 2025
f4b9066
chore: missing repo field
Miodec May 1, 2025
0f211b2
chore: fix repo name
Miodec May 1, 2025
7685967
chore: remove console.error from notifications
Miodec May 2, 2025
a99408a
chore: remove error logging to analytics
Miodec May 2, 2025
33a9022
chore: remove duplicate console.error on rejection
Miodec May 2, 2025
e5d8bd3
chore: always init sentry, dont send in dev mode, add debug logs to s…
Miodec May 2, 2025
4cca580
fix: client version potentially being different during build
Miodec May 2, 2025
be2d830
fix: failed to fetch commandline when a version/hotfix is deployed (@…
fehmer May 2, 2025
2a95c2b
chore: drop third party frames
Miodec May 2, 2025
fb529ae
chore: remove duplicated onerror listener
Miodec May 2, 2025
141a84c
refactor: remove pointless rethrows causing loss of original error
Miodec May 2, 2025
79aa3a5
build(deps-dev): bump vite from 6.3.0 to 6.3.4 in /frontend (#6510)
dependabot[bot] May 2, 2025
07f2d86
chore: try to use auto commit detection again
Miodec May 2, 2025
949b618
chore: check if caches exists
Miodec May 3, 2025
16f3da0
fix: unhandled exception when cancelling google sign in
Miodec May 3, 2025
fc2b051
refactor: handle cases when grecaptcha failed to load
Miodec May 3, 2025
b257a52
impr: add fallback and migrate to parsejsonwithschema (@miodec) (#6518)
Miodec May 3, 2025
b806179
fix: errors during word generation when custom text was empty
Miodec May 3, 2025
3953d64
chore: add basic log when initializing test
Miodec May 3, 2025
57ccfbb
chore: optional chaining to avoid throwing errors
Miodec May 3, 2025
ac33789
fix: catch errors when google sign up failed
Miodec May 3, 2025
2506b4f
impr(settings): settings group performance (@fehmer, @miodec) (#6509)
fehmer May 3, 2025
2c161e5
chore: use vanilla js to try to fix weird stack size error
Miodec May 3, 2025
d4d621e
style: fix too big of a gap between tab buttons and theme buttons
Miodec May 3, 2025
5ba39c6
refactor: rework theme picker button and tab approach
Miodec May 3, 2025
d02f41e
fix(quote search): uncaught errors when closing modal right after sea…
Miodec May 3, 2025
2b292b0
chore: only save 50% of the error replays
Miodec May 3, 2025
8ec109d
chore: dont set page transition when restartin the test
Miodec May 4, 2025
17c8f6d
impr: show loading bar when fetching language/quotes to indicate back…
Miodec May 4, 2025
c7ac9ad
chore: stop update if element was not found
Miodec May 4, 2025
024e86e
fix: stop broken background images from displaying (@mattlau1) (#6526)
mattlau1 May 5, 2025
72016ea
fix: compatibility banner blocked by ublock (@fehmer) (#6502)
fehmer May 5, 2025
ca33892
ci: run layouts tests on pr-check-other-json (@fehmer) (#6520)
fehmer May 5, 2025
499754a
ci: fix missing dependencies when running pr-check-other-json (@fehme…
fehmer May 5, 2025
dc6d451
chore: block typing when test is not initialised correctly, show message
Miodec May 5, 2025
5ab7bfb
refactor: move themes list to typescript (@fehmer) (#6489)
fehmer May 5, 2025
752d273
chore: release v25.19.0
Miodec May 5, 2025
a8bec90
fix(theme-picker): don't use .toSorted (@fehmer) (#6531)
fehmer May 5, 2025
7952acc
chore: show compatibility headers when shift clicking version
Miodec May 5, 2025
baf7844
chore: capture config setting errors in sentry
Miodec May 7, 2025
b4dcb2c
fix(settings): fix error when setting keymap layout (@fehmer) (#6537)
fehmer May 7, 2025
75dd791
chore: fix alignment
Miodec May 7, 2025
ed24f7f
fix: slow commandline when searching
Miodec May 7, 2025
eb092ce
refactor: move languages to contracts (@fehmer) (#6497)
fehmer May 7, 2025
7bcad31
impr(quotes): 50 new quotes for polish language from books (@sobczakt…
sobczaktm May 7, 2025
69d9b38
feat(language): add Thai 1K, 5K, 10K, 50K, and 60K (@jnx03) (#6498)
JNX03 May 7, 2025
98ca811
feat(font): add Kanit and Sarabun (@jnx03) (#6500)
JNX03 May 7, 2025
c29bc57
impr(quotes): add Kazakh quotes (@w0ikid) (#6512)
w0ikid May 7, 2025
6e4dd9d
impr(quotes): add Indonesian quotes (@siily-g) (#6522)
siily-g May 7, 2025
be62681
docs: update pull request template (@fehmer) (#6538)
fehmer May 7, 2025
44a67db
feat(commandline): add download screenshot command (@torturado) (#6532)
torturado May 7, 2025
71fc96d
fix(settings): handle boolean values for indicateTypos (@fehmer) (#6554)
fehmer May 11, 2025
00525a0
fix: burst heatmap not being useful in words 10 mode
Miodec May 12, 2025
98f2b9c
fix: typo in malagasy
Miodec May 12, 2025
8370de1
impr: add function to clearstreakhouroffset
Miodec May 12, 2025
f1f4d17
impr(profile): validate inputs for twitter, github and website (@fehm…
fehmer May 12, 2025
48ed096
impr(settings): prevent customLayoutFluid and customPolyglot to be em…
fehmer May 12, 2025
b402c3a
fix: remove some misspellings in english_450k (@byseif21) (#6546)
byseif21 May 12, 2025
3aaf2f6
fix(wordsInput): adjust #wordsInput position to be on the active word…
nadalaba May 12, 2025
d47272b
chore: add eslint compat plugin (@fehmer) (#6542)
fehmer May 12, 2025
e42e90b
impr(quotes): add english quotes (@jay-tau) (#6515)
jay-tau May 12, 2025
98f1273
impr(commandline): improve performance (@fehmer) (#6559)
fehmer May 13, 2025
90b3d73
chore: update privacy policy to mention sentry (@miodec) (#6558)
Miodec May 13, 2025
b34c179
fix: smooth transition for theme palette icon in chaos_theory theme (…
byseif21 May 13, 2025
bfb06a2
impr(config): handle invalid config values (@fehmer) (#6555)
fehmer May 13, 2025
485eb22
impr(account graph): round accuracy to nearest multiple of 5 instead …
Miodec May 12, 2025
d3fa7c9
fix(commandline): cannot use mouse to select first element (@fehmer) …
fehmer May 15, 2025
cde852c
chore: merch banner, anniversary
Miodec May 16, 2025
ea90e0a
refactor: dont allow nullable numbers (@miodec) (#6564)
Miodec May 16, 2025
53bf826
chore: ls with schema debug logs
Miodec May 17, 2025
fc2d85a
chore: disable rule
Miodec May 17, 2025
8f6e961
chore: remove anniversary elements
Miodec May 22, 2025
e28aa97
feat(language): add viossa (@nginearing) (#6571)
Nginearing May 26, 2025
16eda17
fix(language): incorrect and non-standard words in kazakh_1K wordlist…
byseif21 May 26, 2025
ea14499
fix(language): update Ukrainian Latin to national standard (@paiv) (#…
paiv May 26, 2025
a9fb72d
perf(test): optimize test-timer checkIfTimeIsUp (@fehmer) (#6588)
fehmer May 26, 2025
4fe11ac
fix(theme): dark note and reduced-motion not replacing letters with c…
fehmer May 26, 2025
1826948
feat(layout): add Tarmak layouts (@siily-g) (#6574)
siily-g May 26, 2025
07c581f
feat(profile): add Open Graph meta tags for social sharing (@TryOmar)…
TryOmar May 26, 2025
19930a9
docs: update PR template (@fehmer) (#6600)
fehmer May 26, 2025
1cada77
fix: sanitize result filters before storing in LS (@fehmer) (#6583)
fehmer May 26, 2025
47de0c8
refactor: cleanup schema and types for CustomText (@fehmer) (#6605)
fehmer May 27, 2025
093a17b
chore: remove log (@fehmer) (#6601)
fehmer May 27, 2025
d6ae7cf
fix: compatability check header shown if client is using cached respo…
fehmer May 27, 2025
b26e1d2
chore: correct text in difficulty settings descriptions (@byseif21) (…
byseif21 May 27, 2025
3b0cf16
perf: use cache in local-storage-with-schema (@fehmer) (#6596)
fehmer May 27, 2025
5695245
chore: release v25.22.0
Miodec May 27, 2025
2d878b8
fix(commandline): improve caching to fix stale checkmark and UI state…
byseif21 May 27, 2025
0bf76e8
impr: add quick theme favorite indicator to the commandline & footer …
byseif21 May 29, 2025
04fbd81
chore: bump oxlint version
Miodec May 29, 2025
0600b25
fix(settings page): ui not updating on favorite themes change via com…
byseif21 May 29, 2025
af86a2d
style: align ad content to the center
Miodec May 29, 2025
4bb431b
perf: fix account page getting slower with every load (@miodec) (#6606)
Miodec May 29, 2025
502f1c5
impr: add words to Odin, remove non-existing complex_* (@dayllenger) …
dayllenger Jun 4, 2025
ec6e76b
chore: fix typo in issue template (@byseif21) (#6613)
byseif21 Jun 4, 2025
238a2c7
fix(wordsInput): prevent #wordsInput from overflowing the #wordsWrapp…
nadalaba Jun 4, 2025
9d28a42
chore: remove non word
Miodec Jun 12, 2025
8843c50
impr(account): add restarts per test and highest wpm to activity graph
Miodec Jun 12, 2025
2d00846
chore: catch firebase internal errors when trying to auth
Miodec Jun 14, 2025
4c05dd8
chore: bump oxlint version
Miodec Jun 14, 2025
63b63ff
chore: update plugins overrides
Miodec Jun 14, 2025
9891dac
chore(release script): remove validate-json step if only running in t…
Miodec Jun 16, 2025
dabaa14
chore: add insane badge
Miodec Jun 16, 2025
bf4f1e0
impr(quotes): Add English quotes from Andor S1 (@j5155) (#6585)
j5155 Jun 16, 2025
26a39eb
fix(commandline): prevent unwanted scrolling on initial mouse entry (…
byseif21 Jun 16, 2025
e8cbe3b
impr(quotes): ad 60 Chinese Simplified Quotes (@derekyuan1000) (#6620)
derekyuan1000 Jun 16, 2025
ebfa8be
fix(quotes): gladiator quote (@acdpsn) (#6626)
acdpsn Jun 16, 2025
85543ff
fix(docker): fix deeplinks and update documentation (@fehmer) (#6640)
fehmer Jun 17, 2025
5ca47e1
impr(tape mode): support RTL languages (@NadAlaba) (#5748)
nadalaba Jun 18, 2025
ced4b6e
impr(lazy mode): support replacing 2 characters with one
Miodec Jun 22, 2025
33a6bc0
refactor(caret): move active word element offset to test-state and re…
nadalaba Jun 23, 2025
79cc330
fix(account): fix not all results shown if result has a funbox unknow…
fehmer Jun 23, 2025
9cd312d
fix(theme): wrong theme application during preview (@byseif21) (#6617)
byseif21 Jun 23, 2025
61766d3
fix(commandline): skip input recall on up arrow when it's opened with…
byseif21 Jun 23, 2025
7be7fbe
impr(nav): avoid duplicate browser history entries when re-clicking s…
byseif21 Jun 24, 2025
fe71e0b
fix(language): Common Lisp Function Typo (@hikettei) (#6653)
hikettei Jun 25, 2025
c851b00
fix(input-controller): prevent default behavior for Arrow keys and ct…
raaid3 Jun 25, 2025
896c065
impr(quotes): add Russian quotes (@WormholeDragon) (#6632)
WormholeDragon Jun 25, 2025
217981e
fix(wordsInput): clamp #wordsInput from the left to #wordsWrapper (@N…
nadalaba Jun 25, 2025
10aa894
fix(caret): prevent misalignment on initial load and resize (@byseif2…
byseif21 Jun 25, 2025
b0e7e2e
impr(quotes): add English quote (@AlexiusOL) (#6643)
AlexiusOL Jun 26, 2025
0bc380f
fix(word generation): test sometimes stopping in a repeated practice …
Miodec Jun 24, 2025
a327882
fix(focus mode): remove cursor when in hovering over links and button…
jaydent4 Jun 26, 2025
4a4a6ab
feat(language): add viossa njutro (@khautshi) (#6659)
Khautshi Jun 26, 2025
cfff712
fix(xp-bar): don't show attribute if it's 0 (@jackrosenberg) (#6664)
jackrosenberg Jun 26, 2025
836345c
fix(inbox): size indicator not updating on item deletion (@byseif21) …
byseif21 Jun 26, 2025
e4a102a
impr(results): allow PBs with stop on letter if accuracy is 100% (@by…
byseif21 Jun 26, 2025
6133bd2
impr: block Math.random from simple reassignments at runtime
Miodec Jun 27, 2025
677c328
chore(language): remove word from english_450k (@fehmer) (#6672)
fehmer Jun 27, 2025
36dcfe2
refactor: add url parameter handling to Page class (@fehmer) (#6668)
fehmer Jun 27, 2025
83a34c6
fix: cursor disappearing when hovering over buttons
Miodec Jun 27, 2025
fdead53
fix(theme-constroller): fix theme flashing behavior when switching cu…
raaid3 Jun 27, 2025
ebaf49d
chore: release v25.27.0
Miodec Jun 28, 2025
4fffc64
fix(quotes): replace long dash with short one in some quotes (@Wormho…
WormholeDragon Jul 1, 2025
64322a2
fix(commandline): prevent duplicate entries in Polyglot and Layoutflu…
byseif21 Jul 1, 2025
afbff1b
fix(docker): Allow to self-host without firebase config (@fehmer) (#6…
fehmer Jul 1, 2025
3724389
impr(test-screenshot): Show download screenshot button when holding s…
raaid3 Jul 1, 2025
1ace28d
feat(font): add iosevka (@leana8959) (#6674)
leana8959 Jul 1, 2025
0f4d311
fix(input-controller): update keymap UI on backspace in layout emulat…
47th Jul 1, 2025
3135197
fix(theme-picker): ensure color input is updated correctly in updateC…
raaid3 Jul 1, 2025
b9bb113
impr(quotes): add Indonesian quotes (@RKPYI) (#6680)
RKPYI Jul 1, 2025
084dc0d
refactor(page): Move urlParams to beforeShow (@fehmer) (#6687)
fehmer Jul 1, 2025
de447c2
impr(account): add url params / deep links to account settings (@fehm…
fehmer Jul 1, 2025
ce737e3
fix(caret): misalignment issue when switching between carets (@byseif…
byseif21 Jul 1, 2025
ee6a929
fix(funbox): remove difficulty xp bonus from instant messaging funbox
Miodec Jul 1, 2025
e50d5e9
feat(settings): add deep links to specific sections (@fehmer) (#6661)
fehmer Jul 1, 2025
14d5a72
impr(quotes): add 3 spanish quotes (@AntikoreDev) (#6676)
AntikoreDev Jul 3, 2025
9b26793
chore: update express to 5.1.0 (@fehmer) (#6691)
fehmer Jul 3, 2025
4319830
refactor: split key labels in layout files (@fehmer) (#6527)
fehmer Jul 3, 2025
2437222
refactor(commandline): rework some parts of the code
Miodec Jul 3, 2025
9e7740a
refactor(config): remove special handling for font size 15 (@fehmer) …
fehmer Jul 4, 2025
8d15d6b
fix(indicate typos): input sometimes being blocked in the middle of a…
Miodec Jul 3, 2025
de25417
chore: upgrade throttle debounce type
Miodec Jul 4, 2025
06ca8c2
impr(ligatures): always enable in Zen and Custom modes for always cor…
byseif21 Jul 9, 2025
6b1bbfb
fix: pin implementation (@fehmer) (#6699)
fehmer Jul 9, 2025
07a04d1
fix(test): funbox does not remember settings (@fehmer) (#6701)
fehmer Jul 9, 2025
7b283b9
docs: Fix missing colons and comma in THEMES.md (@NeoNyaa) (#6707)
NeoNyaa Jul 9, 2025
f130947
impr(layout): adjust the Romak layout according to the latest changes…
rafaelromao Jul 9, 2025
0c1e1f2
fix(settings): remove highlight if not set (@fehmer) (#6711)
fehmer Jul 9, 2025
8be3a3c
fix(leaderboard): use minTimeTyping from configuration (@fehmer) (#6710)
fehmer Jul 9, 2025
2d430c1
chore: fix syntax in example.env (@byseif21) (#6712)
byseif21 Jul 9, 2025
178033c
impr: add perfection badge
Miodec Jul 9, 2025
a12999d
chore: change insane badge colors per request
Miodec Jul 9, 2025
b9cff9e
impr(commandline): allow validation for text inputs (@fehmer) (#6692)
fehmer Jul 9, 2025
83cc759
impr(commandline): validate input for polyglot and layoutfluid (@fehm…
fehmer Jul 9, 2025
5243d14
refactor(hints): improve readability of hints functions (@NadAlaba) (…
nadalaba Jul 9, 2025
ed47e2f
fix(account settings): ape keys table not displaying correctly
Miodec Jul 9, 2025
9a6fe31
fix(test): line not jumping when word overflows to the next line
Miodec Jul 9, 2025
477dc48
fix(settings): fix highlight not visible with reduced-motion (@fehmer…
fehmer Jul 10, 2025
0c5cb1b
impr(quotes): Add 4 english quotes from Better Call Saul (@Soufi-ane)…
Soufi-ane Jul 11, 2025
14cf7b0
refactor(hints): allow joinOverlappingHints to run on joined hints (@…
nadalaba Jul 11, 2025
ee02bee
fix(wordsInput): prevent automatic scrolling when focusing #wordsInpu…
nadalaba Jul 11, 2025
2908331
fix(zen): remove input length check to prevent jump to hidden line (@…
byseif21 Jul 11, 2025
02fcad4
fix(caret): incorrect vertical position if word wrapped to the next line
Miodec Jul 11, 2025
0b8ee9c
impr(quotes): 15 polish movie quotes for polish language (@sobczaktm)…
sobczaktm Jul 12, 2025
c6dcfa1
fix(profile): remove previous error message on page load (@fehmer) (#…
fehmer Jul 12, 2025
5aec2c9
fix(docker): use frontend url for firebase admin (@fehmer) (#6730)
fehmer Jul 14, 2025
a4de8df
impr(leaderboard): daily mode/language buttons based on backend confi…
fehmer Jul 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ body:
value: |
# Issue details
```
Please provide a detailed decription of what's happening, and most importantly - solid steps to reproduce the issue. This will help us find it quicker.
Please provide a detailed description of what's happening, and most importantly - solid steps to reproduce the issue. This will help us find it quicker.
```

- type: textarea
Expand Down
19 changes: 15 additions & 4 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,21 @@

- [ ] Adding quotes?
- [ ] Make sure to include translations for the quotes in the description (or another comment) so we can verify their content.
- [ ] Adding a language or a theme?
- [ ] If is a language, did you edit `_list.json`, `_groups.json` and add `languages.json`?
- [ ] If is a theme, did you add the theme.css?
- Also please add a screenshot of the theme, it would be extra awesome if you do so!
- [ ] Adding a language?
- Make sure to follow the [languages documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/LANGUAGES.md)
- [ ] Add language to `packages/contracts/src/schemas/languages.ts`
- [ ] Add language to exactly one group in `frontend/src/ts/constants/languages.ts`
- [ ] Add language json file to `frontend/static/languages`
- [ ] Adding a theme?
- Make sure to follow the [themes documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/THEMES.md)
- [ ] Add theme to `packages/contracts/src/schemas/themes.ts`
- [ ] Add theme to `frontend/src/ts/constants/themes.ts`
- [ ] Add theme css file to `frontend/static/themes`
- Also please add a screenshot of the theme, it would be extra awesome if you do so!
- [ ] Adding a layout?
- [ ] Make sure to follow the [layouts documentation](https://github.com/monkeytypegame/monkeytype/blob/master/docs/LAYOUTS.md)
- [ ] Add layout to `packages/contracts/src/schemas/layouts.ts`
- [ ] Add layout json file to `frontend/static/layouts`
- [ ] Check if any open issues are related to this PR; if so, be sure to tag them below.
- [ ] Make sure the PR title follows the Conventional Commits standard. (https://www.conventionalcommits.org for more info)
- [ ] Make sure to include your GitHub username prefixed with @ inside parentheses at the end of the PR title.
Expand Down
16 changes: 11 additions & 5 deletions .github/workflows/ci-failure-comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,14 @@ jobs:
if: ${{ github.event.workflow_run.conclusion == 'failure' }}
steps:
- name: Download workflow artifact
uses: dawidd6/action-download-artifact@v6
uses: actions/download-artifact@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: peek_icons.yml
run_id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}

- name: Read the pr_num file
id: pr_num_reader
uses: juliangruber/read-file-action@v1.0.0
uses: juliangruber/read-file-action@v1
with:
path: ./pr_num/pr_num.txt

Expand All @@ -31,3 +30,10 @@ jobs:
issue-number: ${{ steps.pr_num_reader.outputs.content }}
body: |
Continuous integration check(s) failed. Please review the [failing check\'s logs](${{ github.event.workflow_run.html_url }}) and make the necessary changes.

- name: Apply label changes
uses: PauMAVA/add-remove-label-action@v1.0.3
with:
issue_number: ${{ steps.pr_num_reader.outputs.content }}
add: "waiting for update"
remove: "waiting for review"
2 changes: 1 addition & 1 deletion .github/workflows/monkey-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ jobs:
run: echo $PR_NUM > pr_num.txt

- name: Upload the PR number
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: pr_num
path: ./pr_num.txt
4 changes: 2 additions & 2 deletions .github/workflows/pretty-fix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name}}
ref: ${{ github.event.pull_request.head.sha }}

- name: Set up Node.js
uses: actions/setup-node@v4
Expand Down Expand Up @@ -62,7 +63,6 @@ jobs:
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "prettier fix"
branch: ${{ github.event.pull_request.head.ref }}

- name: Remove label
uses: actions-ecosystem/action-remove-labels@v1
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-docker-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
tags: ${{ env.BE_REPO }}:latest,${{ steps.bemeta.outputs.tags }}
labels: ${{ steps.bemeta.outputs.labels }}
build-args: |
server_version: {{version}}
server_version: ${{ github.event.release.tag_name }}

- name: Backend publish description
uses: peter-evans/dockerhub-description@e98e4d1628a5f3be2be7c231e50981aee98723ae
Expand Down
13 changes: 4 additions & 9 deletions .github/workflows/semantic-pr-title.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,7 @@ jobs:
Title "{title}"
didn't match the configured pattern. Please ensure that the title
contains your name so that you can be credited in our changelog.
A correct version would look something like:

feat: add new feature (@github-username)
impr(quotes): add english quotes (@github-username)
fix: resolve bug (@github-username)


- uses: marocchino/sticky-pull-request-comment@v2
# When the previous steps fails, the workflow would stop. By adding this
# condition you can continue the execution with the populated error message.
Expand All @@ -66,9 +61,9 @@ jobs:
```
A correct version would look something like:

feat: add new feature (@github-username)
impr(quotes): add english quotes (@github-username)
fix: resolve bug (@github-username)
feat: add new feature (@github_username)
impr(quotes): add english quotes (@username)
fix(leaderboard): show user rank correctly (@user1, @user2, @user3)

# Delete a previous comment when the issue has been resolved
- if: ${{ steps.lint_pr_title.outputs.error_message == null }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/write-labels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:

- name: Read json file
id: json_reader
uses: juliangruber/read-file-action@v1.1.7
uses: juliangruber/read-file-action@v1
with:
path: ./labels/write-labels.json

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,4 @@ frontend/src/webfonts-generated
frontend/static/webfonts-preview

.turbo
frontend/.env.sentry-build-plugin
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
![HTML5](https://img.shields.io/badge/html5-%23E34F26.svg?style=for-the-badge&logo=html5&logoColor=white)
![JQuery](https://img.shields.io/badge/jQuery-0769AD?style=for-the-badge&logo=jquery&logoColor=white)
![MongoDB](https://img.shields.io/badge/-MongoDB-13aa52?style=for-the-badge&logo=mongodb&logoColor=white)
![OXLint](https://img.shields.io/badge/%E2%9A%93%20oxlint-2b3c5a?style=for-the-badge&logoColor=white)
![PNPM](https://img.shields.io/badge/pnpm-F69220?style=for-the-badge&logo=pnpm&logoColor=white)
![Redis](https://img.shields.io/badge/Redis-DC382D?style=for-the-badge&logo=redis&logoColor=white)
![SASS](https://img.shields.io/badge/SASS-hotpink.svg?style=for-the-badge&logo=SASS&logoColor=white)
Expand Down
26 changes: 26 additions & 0 deletions backend/.oxlintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"extends": [
"../packages/oxlint-config/index.json"
// "@monkeytype/oxlint-config"
],
"overrides": [
{
"files": ["__tests__/**"],
"plugins": [
"typescript",
"unicorn",
"oxc",
"import",
"node",
"promise",
"jest",
"vitest"
],
"rules": {
"no-explicit-any": "allow",
"explicit-function-return-type": "off",
"ban-ts-comment": "off"
}
}
]
}
89 changes: 89 additions & 0 deletions backend/__tests__/api/controllers/admin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,95 @@ describe("AdminController", () => {
).toBeRateLimited({ max: 1, windowMs: 5000 });
});
});

describe("clear streak hour offset", () => {
const clearStreakHourOffset = vi.spyOn(UserDal, "clearStreakHourOffset");

beforeEach(() => {
[clearStreakHourOffset].forEach((it) => it.mockReset());
});

it("should clear streak hour offset for user", async () => {
//GIVEN
const victimUid = new ObjectId().toHexString();

//WHEN
const { body } = await mockApp
.post("/admin/clearStreakHourOffset")
.send({ uid: victimUid })
.set("Authorization", `Bearer ${uid}`)
.expect(200);

//THEN
expect(body).toEqual({
message: "Streak hour offset cleared",
data: null,
});
expect(clearStreakHourOffset).toHaveBeenCalledWith(victimUid);
});
it("should fail without mandatory properties", async () => {
//GIVEN

//WHEN
const { body } = await mockApp
.post("/admin/clearStreakHourOffset")
.send({})
.set("Authorization", `Bearer ${uid}`)
.expect(422);

//THEN
expect(body).toEqual({
message: "Invalid request data schema",
validationErrors: ['"uid" Required'],
});
});
it("should fail with unknown properties", async () => {
//GIVEN

//WHEN
const { body } = await mockApp
.post("/admin/clearStreakHourOffset")
.send({ uid: new ObjectId().toHexString(), extra: "value" })
.set("Authorization", `Bearer ${uid}`)
.expect(422);

//THEN
expect(body).toEqual({
message: "Invalid request data schema",
validationErrors: ["Unrecognized key(s) in object: 'extra'"],
});
});
it("should fail if user is no admin", async () => {
await expectFailForNonAdmin(
mockApp
.post("/admin/clearStreakHourOffset")
.send({ uid: new ObjectId().toHexString() })
.set("Authorization", `Bearer ${uid}`)
);
});
it("should fail if admin endpoints are disabled", async () => {
//GIVEN
await expectFailForDisabledEndpoint(
mockApp
.post("/admin/clearStreakHourOffset")
.send({ uid: new ObjectId().toHexString() })
.set("Authorization", `Bearer ${uid}`)
);
});
it("should be rate limited", async () => {
//GIVEN
const victimUid = new ObjectId().toHexString();

//WHEN
await expect(
mockApp
.post("/admin/clearStreakHourOffset")
.send({ uid: victimUid })
.set("Authorization", `Bearer ${uid}`)
).toBeRateLimited({ max: 1, windowMs: 5000 });
});
});

describe("accept reports", () => {
const getReportsMock = vi.spyOn(ReportDal, "getReports");
const deleteReportsMock = vi.spyOn(ReportDal, "deleteReports");
Expand Down
49 changes: 25 additions & 24 deletions backend/__tests__/api/controllers/leaderboard.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,28 +139,29 @@ describe("Loaderboard Controller", () => {
);
});

it("should get for mode", async () => {
getLeaderboardMock.mockResolvedValue([]);
for (const mode of ["time", "words", "quote", "zen", "custom"]) {
const response = await mockApp
.get("/leaderboards")
.query({ language: "english", mode, mode2: "custom" });
expect(response.status, "for mode " + mode).toEqual(200);
}
});

it("should get for mode2", async () => {
getLeaderboardMock.mockResolvedValue([]);
for (const mode2 of allModes) {
const response = await mockApp.get("/leaderboards").query({
language: "english",
mode: "words",
mode2,
});
describe("should get for modes", async () => {
beforeEach(() => {
getLeaderboardMock.mockResolvedValue([]);
});

expect(response.status, "for mode2 " + mode2).toEqual(200);
}
const testCases = [
{ mode: "time", mode2: "15", language: "english", expectStatus: 200 },
{ mode: "time", mode2: "60", language: "english", expectStatus: 200 },
{ mode: "time", mode2: "30", language: "english", expectStatus: 404 },
{ mode: "words", mode2: "15", language: "english", expectStatus: 404 },
{ mode: "time", mode2: "15", language: "spanish", expectStatus: 404 },
];
it.for(testCases)(
`expect $expectStatus for mode $mode, mode2 $mode2, lang $language`,
async ({ mode, mode2, language, expectStatus }) => {
await mockApp
.get("/leaderboards")
.query({ language, mode, mode2 })
.expect(expectStatus);
}
);
});

it("fails for missing query", async () => {
const { body } = await mockApp.get("/leaderboards").expect(422);

Expand Down Expand Up @@ -188,7 +189,7 @@ describe("Loaderboard Controller", () => {
expect(body).toEqual({
message: "Invalid query schema",
validationErrors: [
'"language" Can only contain letters [a-zA-Z0-9_+]',
'"language" Invalid enum value. Must be a supported language',
`"mode" Invalid enum value. Expected 'time' | 'words' | 'quote' | 'custom' | 'zen', received 'unknownMode'`,
'"mode2" Needs to be a number or a number represented as a string e.g. "10".',
'"page" Number must be greater than or equal to 0',
Expand Down Expand Up @@ -344,7 +345,7 @@ describe("Loaderboard Controller", () => {
expect(body).toEqual({
message: "Invalid query schema",
validationErrors: [
'"language" Can only contain letters [a-zA-Z0-9_+]',
'"language" Invalid enum value. Must be a supported language',
`"mode" Invalid enum value. Expected 'time' | 'words' | 'quote' | 'custom' | 'zen', received 'unknownMode'`,
'"mode2" Needs to be a number or a number represented as a string e.g. "10".',
],
Expand Down Expand Up @@ -652,7 +653,7 @@ describe("Loaderboard Controller", () => {
expect(body).toEqual({
message: "Invalid query schema",
validationErrors: [
'"language" Can only contain letters [a-zA-Z0-9_+]',
'"language" Invalid enum value. Must be a supported language',
`"mode" Invalid enum value. Expected 'time' | 'words' | 'quote' | 'custom' | 'zen', received 'unknownMode'`,
'"mode2" Needs to be a number or a number represented as a string e.g. "10".',
],
Expand Down Expand Up @@ -830,7 +831,7 @@ describe("Loaderboard Controller", () => {
expect(body).toEqual({
message: "Invalid query schema",
validationErrors: [
'"language" Can only contain letters [a-zA-Z0-9_+]',
'"language" Invalid enum value. Must be a supported language',
`"mode" Invalid enum value. Expected 'time' | 'words' | 'quote' | 'custom' | 'zen', received 'unknownMode'`,
'"mode2" Needs to be a number or a number represented as a string e.g. "10".',
],
Expand Down
2 changes: 1 addition & 1 deletion backend/__tests__/api/controllers/public.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ describe("PublicController", () => {
expect(body).toEqual({
message: "Invalid query schema",
validationErrors: [
'"language" Can only contain letters [a-zA-Z0-9_+]',
'"language" Invalid enum value. Must be a supported language',
`"mode" Invalid enum value. Expected 'time' | 'words' | 'quote' | 'custom' | 'zen', received 'unknownMode'`,
'"mode2" Needs to be a number or a number represented as a string e.g. "10".',
],
Expand Down
Loading
Loading