Skip to content

Commit c3a36fe

Browse files
authored
Merge pull request #41 from khairulhaaziq/dev
refactor: make everything more modular with classes fix: fix delete extras when spaced
2 parents 609bf74 + c981bb3 commit c3a36fe

File tree

11 files changed

+182
-197
lines changed

11 files changed

+182
-197
lines changed

pages/index.vue

Lines changed: 75 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
</template>
9494

9595
<script setup lang="ts">
96-
import { WritableComputedRef } from 'vue';
96+
import { ref, computed } from 'vue';
9797
import {
9898
useHomeStore,
9999
KEYOPTIONS,
@@ -126,6 +126,8 @@ import { calculateRawWPM, calculateWPM, focusInput } from '@/utils/input';
126126
import type { Database } from '~/types/database.types';
127127
import formatLocaleTime from '~/utils/format-locale-time';
128128
import { IntervalCounter, BaseCounter } from '~/src/counters';
129+
import { isKeySpace, isQuickRestartShortcut } from '~/src/helpers';
130+
import { WordLog, CharacterLog, IntervalLog } from '~/src/log';
129131
130132
definePageMeta({
131133
middleware: 'auth',
@@ -242,7 +244,7 @@ const currentSelectionData = computed(() => {
242244
}
243245
});
244246
245-
//manage carot
247+
//manage caret
246248
const CARETLEFT = ref(0);
247249
const CARETTOP = ref(0);
248250
@@ -300,46 +302,6 @@ const currentMetadata: globalThis.ComputedRef<InputMetadata> = computed(() => {
300302
};
301303
});
302304
303-
// writable computed ref is used for write only, get is gotten from currentmetadata.
304-
const currentCharacterStatus: WritableComputedRef<CharLogStatus> = computed({
305-
get: (): CharLogStatus => {
306-
return allData.value[currentWordNum.value]?.characters[
307-
currentCharNum.value
308-
].status;
309-
},
310-
set: (newValue: CharLogStatus): void => {
311-
allData.value[currentWordNum.value].characters[
312-
currentCharNum.value
313-
].status = newValue;
314-
},
315-
});
316-
317-
// writable computed ref is used for write only, get is gotten from currentmetadata.
318-
const currentCharacterEndTime: WritableComputedRef<string> = computed({
319-
get: (): string => {
320-
return allData.value[currentWordNum.value]?.characters[
321-
currentCharNum.value
322-
].end_time;
323-
},
324-
set: (newValue: string): void => {
325-
allData.value[currentWordNum.value].characters[
326-
currentCharNum.value
327-
].end_time = newValue;
328-
},
329-
});
330-
const currentCharacterStartTime: WritableComputedRef<string> = computed({
331-
get: (): string => {
332-
return allData.value[currentWordNum.value]?.characters[
333-
currentCharNum.value
334-
].start_time;
335-
},
336-
set: (newValue: string): void => {
337-
allData.value[currentWordNum.value].characters[
338-
currentCharNum.value
339-
].start_time = newValue;
340-
},
341-
});
342-
343305
//
344306
async function fetchWords() {
345307
loading.value = true;
@@ -417,21 +379,9 @@ function handleKeydown(e: KeyboardEvent) {
417379
}
418380
}
419381
420-
function isQuickRestartShortcut(e: KeyboardEvent) {
421-
const key = e.key;
422-
if (key === 'Tab') return true;
423-
return false;
424-
}
425-
426-
function isSpace(e: KeyboardEvent) {
427-
const key = e.key;
428-
if (key === ' ') return true;
429-
return false;
430-
}
431-
432382
function handleSpace() {
433383
const metadata = currentMetadata.value;
434-
metadata.currentWordMetadata.status = getWordStatus()
384+
metadata.currentWordMetadata.status = getWordStatus();
435385
insertWord(metadata.currentWord);
436386
pushWordLogs();
437387
currentWordNum.value += 2;
@@ -445,9 +395,10 @@ function handleQuickRestart() {
445395
}
446396
447397
function isFinalWord(index: number) {
448-
if (selectedMode.value === 'word' && index === selectedWords.value - 1)
449-
return true;
450-
return false;
398+
return (
399+
selectedMode.value === 'word' &&
400+
index === selectedWords.value - 1
401+
);
451402
}
452403
453404
function handleInput(e: KeyboardEvent) {
@@ -461,7 +412,7 @@ function handleInput(e: KeyboardEvent) {
461412
}
462413
if (currentWordType !== 'separator') {
463414
totalCharactersCount.increment();
464-
if (isSpace(e)) {
415+
if (isKeySpace(e)) {
465416
if (!isFinalWord(index)) handleSpace();
466417
return;
467418
}
@@ -475,25 +426,29 @@ function handleInput(e: KeyboardEvent) {
475426
}
476427
477428
function handleCorrectInput() {
478-
deleteExtras();
479429
intervalCharacterCount.increment();
480430
const { currentWordMetadata } = currentMetadata.value;
481431
if (currentWordMetadata && currentWordMetadata.type !== 'separator') {
482432
totalCorrectsCount.increment();
483433
}
484-
485434
const metadata = currentMetadata.value;
486-
const currentCharMetadata = currentMetadata.value.currentCharMetadata;
435+
let currentCharMetadata = currentMetadata.value.currentCharMetadata;
487436
const time = Date.now();
488437
const duration = getCharDuration(time);
489-
const index = metadata.currentCharLocation;
438+
let index = metadata.currentCharLocation;
490439
const wordIndex = metadata.currentWordMetadata.index;
440+
if(currentWordMetadata.type === 'separator'){
441+
currentCharMetadata = allData.value[currentWordNum.value]?.characters[
442+
metadata.currentCorrectCharLocation
443+
];
444+
index = metadata.currentCorrectCharLocation
445+
}
491446
492447
updateCurrentCharacterObject();
493448
if (isEndSession()) {
494449
handleEndSession(time);
495450
return;
496-
} else if (isEndWord()) {
451+
} else if (isEndWord() || currentWordMetadata.type === 'separator') {
497452
handleEndWord();
498453
} else {
499454
incrementChar();
@@ -515,12 +470,6 @@ function handleCorrectInput() {
515470
}
516471
}
517472
518-
watch([CARETTOP], () => {
519-
if (CARETTOP.value > oldTop && oldTop !== 0) {
520-
handleNewLine();
521-
}
522-
oldTop = CARETTOP.value;
523-
});
524473
function getCharDuration(time: number) {
525474
return (time - finalKeydown) / 1000;
526475
}
@@ -640,37 +589,28 @@ function resetPrevCharMetadata() {
640589
const currentWordIndex = currentWordMetadata.index;
641590
let prevCharIndex: number;
642591
let prevCharMetadata: CharacterMetadata;
643-
if (correctCharIndex.value === 0
644-
) {
592+
if (correctCharIndex.value === 0) {
645593
let prevWordMetadata: WordMetadata;
646-
let newWordIndex: number
647-
if(currentWordMetadata.type === 'separator'){
648-
newWordIndex = currentWordNum.value - 1
649-
prevWordMetadata =
650-
allData.value[newWordIndex];
651-
}else{
652-
newWordIndex = currentWordNum.value - 2
653-
prevWordMetadata =
654-
allData.value[newWordIndex];
594+
let newWordIndex: number;
595+
if (currentWordMetadata.type === 'separator') {
596+
newWordIndex = currentWordNum.value - 1;
597+
prevWordMetadata = allData.value[newWordIndex];
598+
} else {
599+
newWordIndex = currentWordNum.value - 2;
600+
prevWordMetadata = allData.value[newWordIndex];
655601
}
656-
for (
657-
let i = 0;
658-
i < prevWordMetadata.characters?.length;
659-
i++
660-
) {
602+
for (let i = 0; i < prevWordMetadata.characters?.length; i++) {
661603
if (
662-
allData.value[newWordIndex]
663-
.characters[i].status === 'pending'
604+
allData.value[newWordIndex].characters[i]
605+
.status === 'pending'
664606
) {
665607
break;
666608
} else {
667609
prevCharIndex = i;
668610
}
669611
}
670612
prevCharMetadata =
671-
allData.value[newWordIndex].characters[
672-
prevCharIndex
673-
];
613+
allData.value[newWordIndex].characters[prevCharIndex];
674614
if (prevCharMetadata.status === 'extra') {
675615
currentMetadata.value.currentWordMetadata.characters.splice(
676616
prevCharIndex,
@@ -851,7 +791,7 @@ function setShowResults() {
851791
852792
function handleEndWord() {
853793
const metadata = currentMetadata.value;
854-
metadata.currentWordMetadata.status = getWordStatus()
794+
metadata.currentWordMetadata.status = getWordStatus();
855795
if (metadata.currentWordMetadata.type === 'word') {
856796
insertWord(metadata.currentWord);
857797
pushWordLogs();
@@ -864,18 +804,22 @@ function pushWordLogs() {
864804
//internal
865805
const wordLength = currentMetadata.value.currentWordLength;
866806
//to push
867-
const index = getWordIndex();
868-
const word = currentMetadata.value.currentWord;
869-
const type = getWordType();
870-
const startTime = getWordStartTime();
871-
const endTime = getWordEndTime();
872807
const duration = getWordDuration();
873-
const status = getWordStatus();
874808
const wpm = getWordWpm();
875-
let session_id: number; // fill at the end
809+
810+
const newWordLog = new WordLog({
811+
index: getWordIndex(),
812+
word: currentMetadata.value.currentWord,
813+
type: getWordType(),
814+
start_time: getWordStartTime(),
815+
end_time: getWordEndTime(),
816+
duration,
817+
status: getWordStatus(),
818+
wpm,
819+
});
876820
877821
if (wpm && duration) {
878-
insertWordLogs();
822+
wordLogs.push(newWordLog.getData());
879823
}
880824
881825
function getWordIndex() {
@@ -911,33 +855,19 @@ function pushWordLogs() {
911855
(wordLength / 5 / (duration / 60)).toFixed(2)
912856
);
913857
}
914-
function insertWordLogs(): void {
915-
const updatedWordObject = {
916-
index,
917-
word,
918-
start_time: startTime,
919-
end_time: endTime,
920-
duration,
921-
status,
922-
type,
923-
wpm,
924-
session_id,
925-
};
926-
wordLogs.push(updatedWordObject);
927-
}
928858
}
929859
930860
function getWordStatus(): WordLogStatus {
931-
const wordLength = currentMetadata.value.currentWordLength
932-
for (let i = 0; i < wordLength; i++) {
933-
if (
934-
currentMetadata.value.currentWordMetadata
935-
.characters[i].status !== 'correct'
936-
)
937-
return 'error';
938-
}
939-
return 'correct';
861+
const wordLength = currentMetadata.value.currentWordLength;
862+
for (let i = 0; i < wordLength; i++) {
863+
if (
864+
currentMetadata.value.currentWordMetadata.characters[i]
865+
.status !== 'correct'
866+
)
867+
return 'error';
940868
}
869+
return 'correct';
870+
}
941871
942872
function insertWord(word: string) {
943873
collectedWords.push(word);
@@ -1159,21 +1089,6 @@ async function insertLogsToDatabase() {
11591089
}
11601090
}
11611091
1162-
// watcher to get fresh data when any mode/settings changed
1163-
watch(
1164-
[
1165-
selectedDifficulty,
1166-
selectedDuration,
1167-
selectedKey,
1168-
selectedMode,
1169-
selectedDataset,
1170-
selectedWords,
1171-
],
1172-
() => {
1173-
fetchFreshWords();
1174-
}
1175-
);
1176-
11771092
// function resetlivetimer live wpm
11781093
function resetLiveInterval() {
11791094
liveTimer.value = 0;
@@ -1307,6 +1222,21 @@ function pushIntervalLogs(
13071222
intervalLogs.push(updatedIntervalLogObject);
13081223
}
13091224
1225+
// watcher to get fresh data when any mode/settings changed
1226+
watch(
1227+
[
1228+
selectedDifficulty,
1229+
selectedDuration,
1230+
selectedKey,
1231+
selectedMode,
1232+
selectedDataset,
1233+
selectedWords,
1234+
],
1235+
() => {
1236+
fetchFreshWords();
1237+
}
1238+
);
1239+
13101240
//watch if input out of focus
13111241
watch(currentActive, () => {
13121242
if (currentActive.value.id !== 'MasterInput') {
@@ -1336,6 +1266,13 @@ onMounted(() => {
13361266
}
13371267
});
13381268
1269+
watch([CARETTOP], () => {
1270+
if (CARETTOP.value > oldTop && oldTop !== 0) {
1271+
handleNewLine();
1272+
}
1273+
oldTop = CARETTOP.value;
1274+
});
1275+
13391276
// get profile data from auth
13401277
watchEffect(async () => {
13411278
if (user.value) {

src/counters/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export { IntervalCounter } from './interval-counter';
2-
export { BaseCounter } from './base-counter';
2+
export { BaseCounter } from './base-counter';
3+
export { RefCounter } from './ref-counter';

src/counters/ref-counter.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { ref } from 'vue';
2+
3+
class RefCounter {
4+
protected count: globalThis.Ref<number>;
5+
6+
constructor() {
7+
this.count = ref(0);
8+
}
9+
10+
increment() {
11+
this.count.value++;
12+
}
13+
14+
decrement() {
15+
this.count.value--;
16+
}
17+
18+
reset() {
19+
this.count.value = 0;
20+
}
21+
22+
setValue(num: number) {
23+
this.count.value = num;
24+
}
25+
26+
getValue() {
27+
return this.count.value;
28+
}
29+
}
30+
31+
export { RefCounter };

0 commit comments

Comments
 (0)