@@ -262,16 +262,37 @@ export function forceKeyup(now: number): void {
262262 //using mean here because for words mode, the last keypress ends the test.
263263 //if we then force keyup on that last keypress, it will record a duration of 0
264264 //skewing the average and standard deviation
265- const avg = roundTo2 ( mean ( keypressTimings . duration . array ) ) ;
266- const keysOrder = Object . entries ( keyDownData ) ;
267- keysOrder . sort ( ( a , b ) => a [ 1 ] . timestamp - b [ 1 ] . timestamp ) ;
268- for ( const keyOrder of keysOrder ) {
269- recordKeyupTime ( now , keyOrder [ 0 ] ) ;
265+
266+ const indexesToRemove = new Set (
267+ Object . values ( keyDownData ) . map ( ( data ) => data . index )
268+ ) ;
269+
270+ const keypressDurations = keypressTimings . duration . array . filter (
271+ ( _ , index ) => ! indexesToRemove . has ( index )
272+ ) ;
273+ if ( keypressDurations . length === 0 ) {
274+ // this means the test ended while all keys were still held - probably safe to ignore
275+ // since this will result in a "too short" test anyway
276+ return ;
270277 }
271- const last = lastElementFromArray ( keysOrder ) ?. [ 0 ] as string ;
272- const index = keyDownData [ last ] ?. index ;
273- if ( last !== undefined && index !== undefined ) {
278+
279+ const avg = roundTo2 ( mean ( keypressDurations ) ) ;
280+
281+ const orderedKeys = Object . entries ( keyDownData ) . sort (
282+ ( a , b ) => a [ 1 ] . timestamp - b [ 1 ] . timestamp
283+ ) ;
284+
285+ for ( const [ key , { index } ] of orderedKeys ) {
274286 keypressTimings . duration . array [ index ] = avg ;
287+
288+ if ( key === "NoCode" ) {
289+ noCodeIndex -- ;
290+ }
291+
292+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
293+ delete keyDownData [ key ] ;
294+
295+ updateOverlap ( now ) ;
275296 }
276297}
277298
@@ -350,6 +371,21 @@ function updateOverlap(now: number): void {
350371}
351372
352373export function resetKeypressTimings ( ) : void {
374+ //because keydown triggers before input, we need to grab the first keypress data here and carry it over
375+
376+ //take the key with the largest index
377+ const lastKey = Object . keys ( keyDownData ) . reduce ( ( a , b ) => {
378+ const aIndex = keyDownData [ a ] ?. index ;
379+ const bIndex = keyDownData [ b ] ?. index ;
380+ if ( aIndex === undefined ) return b ;
381+ if ( bIndex === undefined ) return a ;
382+ return aIndex > bIndex ? a : b ;
383+ } ) ;
384+
385+ //get the data
386+ const lastKeyData = keyDownData [ lastKey ] ;
387+
388+ //reset
353389 keypressTimings = {
354390 spacing : {
355391 first : - 1 ,
@@ -366,6 +402,26 @@ export function resetKeypressTimings(): void {
366402 } ;
367403 keyDownData = { } ;
368404 noCodeIndex = 0 ;
405+
406+ //carry over
407+ if ( lastKeyData !== undefined ) {
408+ keypressTimings = {
409+ spacing : {
410+ first : lastKeyData . timestamp ,
411+ last : lastKeyData . timestamp ,
412+ array : [ ] ,
413+ } ,
414+ duration : {
415+ array : [ 0 ] ,
416+ } ,
417+ } ;
418+ keyDownData [ lastKey ] = {
419+ timestamp : lastKeyData . timestamp ,
420+ // make sure to set it to the first index
421+ index : 0 ,
422+ } ;
423+ }
424+
369425 console . debug ( "Keypress timings reset" ) ;
370426}
371427
@@ -413,14 +469,4 @@ export function restart(): void {
413469 correct : 0 ,
414470 incorrect : 0 ,
415471 } ;
416- keypressTimings = {
417- spacing : {
418- first : - 1 ,
419- last : - 1 ,
420- array : [ ] ,
421- } ,
422- duration : {
423- array : [ ] ,
424- } ,
425- } ;
426472}
0 commit comments