Skip to content

Commit

Permalink
feat: support to delete back to the previous incorrect word
Browse files Browse the repository at this point in the history
  • Loading branch information
cuixiaorui committed Mar 1, 2024
1 parent 8164f64 commit f989354
Show file tree
Hide file tree
Showing 3 changed files with 191 additions and 110 deletions.
95 changes: 50 additions & 45 deletions apps/client/components/main/Question.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,32 @@
<div class="text-center pt-2">
<div class="flex relative flex-wrap justify-center gap-2 transition-all">
<template v-for="(w, i) in courseStore.words" :key="i">
<div class="h-[4.8rem] border-solid rounded-[2px] border-b-2 text-[3.2em] transition-all" :class="[
userInputWords[i]['incorrect']
? 'text-red-500 border-b-red-500'
: userInputWords[i]?.['isActive'] && focusing
<div
class="h-[4.8rem] border-solid rounded-[2px] border-b-2 text-[3.2em] transition-all"
:class="[
userInputWords[i]['isActive'] && focusing
? 'text-fuchsia-500 border-b-fuchsia-500'
: 'text-[#20202099] border-b-gray-300 dark:text-gray-300 dark:border-b-gray-400',
isShowWordsWidth() ? '' : 'min-w-28'
]" :style="isShowWordsWidth() ? { width: `${inputWidth(w)}ch` } : {}">
: userInputWords[i]?.['incorrect'] && focusing
? 'text-red-500 border-b-red-500'
: 'text-[#20202099] border-b-gray-300 dark:text-gray-300 dark:border-b-gray-400',
isShowWordsWidth() ? '' : 'min-w-28',
]"
:style="isShowWordsWidth() ? { width: `${inputWidth(w)}ch` } : {}"
>
{{ userInputWords[i]["userInput"] }}
</div>
</template>
<input ref="inputEl" class="absolute h-full w-full opacity-0" type="text" v-model="inputValue" @keyup="handleKeyup"
@keydown="handleKeydown" @focus="handleInputFocus" @blur="handleBlur" autoFocus />
<input
ref="inputEl"
class="absolute h-full w-full top-48"
type="text"
v-model="inputValue"
@keyup="handleKeyup"
@keydown="handleKeydown"
@focus="handleInputFocus"
@blur="handleBlur"
autoFocus
/>
</div>
<div class="mt-12 text-xl dark:text-gray-50">
{{
Expand All @@ -29,24 +42,21 @@ import { useCourseStore } from "~/store/course";
import { useGameMode } from "~/composables/main/game";
import { ref, onMounted, watch } from "vue";
import { useInput } from "~/composables/main/question";
import { useShowWordsWidth } from '~/composables/user/words'
import { useShowWordsWidth } from "~/composables/user/words";
const courseStore = useCourseStore();
const inputEl = ref<HTMLInputElement>();
const { setInputCursorPosition, getInputCursorPosition } = useCursor();
const { focusing, handleInputFocus, handleBlur } = useFocus();
const { showAnswer } = useGameMode();
const { isShowWordsWidth } = useShowWordsWidth()
const { isShowWordsWidth } = useShowWordsWidth();
const {
inputValue,
userInputWords,
preventInput,
submitAnswer,
setInputValue,
fixIncorrectWord,
fixFirstIncorrectWord,
handleKeyboardInput,
} = useInput({
source: () => courseStore.currentStatement?.english!,
setInputCursorPosition,
Expand All @@ -66,10 +76,6 @@ function handleKeyup(e: KeyboardEvent) {
submitAnswer(() => {
showAnswer();
});
} else if (e.code === "Backspace") {
fixFirstIncorrectWord();
} else if (e.code === "Space") {
fixIncorrectWord();
}
}
Expand All @@ -79,71 +85,70 @@ function inputWidth(word: string) {
let width = 0;
// 单词转小写字符数组
word = word.toLocaleLowerCase()
word = word.toLocaleLowerCase();
const wordArr = word.split("");
// 字符宽度1.1的字符数组
const onePointOneLetters = ['u', 'o', 'p', 'q', 'n', 'h', 'g', 'd', 'b'];
const onePointOneLetters = ["u", "o", "p", "q", "n", "h", "g", "d", "b"];
// 字符宽度0.9的字符数组
const zeroPointNineLetters = ['z', 'y', 'x', 'v', 'c'];
const zeroPointNineLetters = ["z", "y", "x", "v", "c"];
for(let letter of wordArr) {
if(letter === 'w' || letter === 'm') {
width += 1.5
for (let letter of wordArr) {
if (letter === "w" || letter === "m") {
width += 1.5;
continue;
}
if(letter === 's') {
width += 0.8
if (letter === "s") {
width += 0.8;
continue;
}
if(letter === 't' || letter === 'r' || letter === 'f') {
width += 0.7
if (letter === "t" || letter === "r" || letter === "f") {
width += 0.7;
continue;
}
if(letter === 'j') {
width += 0.6
if (letter === "j") {
width += 0.6;
continue;
}
if(letter === 'i' || letter === 'l') {
width += 0.5
if (letter === "i" || letter === "l") {
width += 0.5;
continue;
}
// 记录是否已经增加宽度
let increasedWidth = false
let increasedWidth = false;
for(let key of onePointOneLetters) {
if(key === letter) {
for (let key of onePointOneLetters) {
if (key === letter) {
width += 1.1;
increasedWidth = true
increasedWidth = true;
break;
}
}
for(let key of zeroPointNineLetters) {
if(key === letter) {
for (let key of zeroPointNineLetters) {
if (key === letter) {
width += 0.9;
increasedWidth = true
increasedWidth = true;
break;
}
}
// 未增加宽度
if(!increasedWidth) {
width += 1
if (!increasedWidth) {
width += 1;
}
}
// 左右留白
width += 1
width += 1;
return width;
}
function handleKeydown(e: KeyboardEvent) {
preventInput(e);
handleKeyboardInput(e);
}
function useCursor() {
Expand Down
125 changes: 81 additions & 44 deletions apps/client/composables/main/question.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ interface Word {
end: number;
start: number;
position: number;
id: number;
}

interface InputOptions {
Expand Down Expand Up @@ -45,7 +46,7 @@ export function useInput({
updateActiveWord(getInputCursorPosition());
}

function createWord(word: string) {
function createWord(word: string, id: number) {
return reactive({
text: word,
isActive: false,
Expand All @@ -54,7 +55,8 @@ export function useInput({
start: 0,
end: 0,
position: 0,
});
id,
} as Word);
}

function setupUserInputWords() {
Expand Down Expand Up @@ -124,31 +126,44 @@ export function useInput({
word.userInput.toLocaleLowerCase() !== word.text.toLocaleLowerCase()
) {
word.incorrect = true;
} else {
word.incorrect = false;
}
});
}

function focusOnLastWord() {
const position = inputValue.value.length;
updateActiveWord(position);
setInputCursorPosition(position);
}

function lastWordIsActive() {
let len = userInputWords.length;
return userInputWords[len - 1].isActive;
}

function findNextIncorrectWordNew() {
return userInputWords.find((word) => {
return word.incorrect;
})!;
if (!currentEditWord) return;

const wordIndex = userInputWords.findIndex(
(w) => w.id === currentEditWord.id
);

let len = userInputWords.length;
for (let i = wordIndex + 1; i < len; i++) {
const word = userInputWords[i];
if (word.incorrect) {
return word;
}
}
}

function getFirstIncorrectWord() {
return userInputWords.find((w) => w.incorrect);
}

async function clearNextIncorrectWord() {
const word = findNextIncorrectWordNew();
let word = findNextIncorrectWordNew();
if (!word) {
word = getFirstIncorrectWord()!;
}

word.userInput = "";
word.incorrect = false;

currentEditWord = word;

Expand Down Expand Up @@ -184,12 +199,6 @@ export function useInput({

async function fixNextIncorrectWord() {
if (mode === Mode.Fix_Input) {
if (checkWordCorrect()) {
mode = Mode.Input;
focusOnLastWord();
return;
}

await clearNextIncorrectWord();
}
}
Expand All @@ -202,53 +211,81 @@ export function useInput({
}
}

function preventAnyInputWhenFix(e: KeyboardEvent) {
if (mode === Mode.Fix) {
e.preventDefault();
function isEmptyOfCurrentEditWord() {
return currentEditWord.userInput.length <= 0;
}

function findPreviousIncorrectWord() {
if (!currentEditWord) return;

const wordIndex = userInputWords.findIndex(
(w) => w.id === currentEditWord.id
);

for (let i = wordIndex - 1; i >= 0; i--) {
const word = userInputWords[i];
if (word.incorrect) {
return word;
}
}
}

function preventMove(e: KeyboardEvent) {
async function activePreviousIncorrectWord() {
const previousIncorrectWord = findPreviousIncorrectWord();

if (previousIncorrectWord) {
currentEditWord = previousIncorrectWord;

await nextTick();

updateActiveWord(previousIncorrectWord.end);
setInputCursorPosition(previousIncorrectWord.end);
}
}

function handleKeyboardInput(e: KeyboardEvent) {
if (e.code === "ArrowLeft" || e.code === "ArrowRight") {
e.preventDefault();
return;
}
}

function preventSpaceWhenFixInput(e: KeyboardEvent) {
if (e.code === "Space" && mode === Mode.Fix_Input) {
if (e.code !== "Space" && e.code !== "Backspace" && mode === Mode.Fix) {
e.preventDefault();
return;
}
}

function preventInputSpaceOnLastWord(e: KeyboardEvent) {
if (e.code === "Space" && lastWordIsActive()) {
e.preventDefault();
return;
}
}

function preventBackspaceWhenFixInput(e: KeyboardEvent) {
if (e.code === "Backspace" && mode === Mode.Fix_Input) {
if (currentEditWord.userInput.length <= 0) {
e.preventDefault();
}
if (
e.code === "Backspace" &&
mode === Mode.Fix_Input &&
isEmptyOfCurrentEditWord()
) {
e.preventDefault();
activePreviousIncorrectWord();
return;
}
}

function preventInput(e: KeyboardEvent) {
preventAnyInputWhenFix(e);
preventMove(e);
preventSpaceWhenFixInput(e);
preventInputSpaceOnLastWord(e);
preventBackspaceWhenFixInput(e);
if (e.code === "Space" && mode !== Mode.Input) {
e.preventDefault();
fixIncorrectWord();
} else if (e.code === "Backspace" && mode !== Mode.Fix) {
e.preventDefault();
fixFirstIncorrectWord();
}
}

return {
inputValue,
userInputWords,
fixFirstIncorrectWord,
fixIncorrectWord,
preventInput,
submitAnswer,
setInputValue,
activePreviousIncorrectWord,
handleKeyboardInput,
fixIncorrectWord,
fixFirstIncorrectWord,
};
}
Loading

0 comments on commit f989354

Please sign in to comment.