diff --git a/CHANGELOG.md b/CHANGELOG.md index 96a5a9865..33fa291f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,10 @@ --- -#### Version 3.39.1 +#### Version 3.39.2 +- **Fix**: Removed duplicated tip "expected: E-T, E-T, E-T" + +#### Version 3.39.1 (01.04.2025) - **New**: The Hieroglyphs mode now has animation and vibration when toggled #### Version 3.39 (30.03.2025) diff --git a/package.json b/package.json index 134fab931..9b66b8444 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "slowoku" ], "private": true, - "version": "3.39.1", + "version": "3.39.2", "type": "module", "scripts": { "dev": "vite --port 3001", diff --git a/src/api/getWordToGuess.ts b/src/api/getWordToGuess.ts index 51c66b0c9..27fc8485a 100644 --- a/src/api/getWordToGuess.ts +++ b/src/api/getWordToGuess.ts @@ -47,7 +47,7 @@ export const getCatalogInfo = async (gameLanguage: string) => { maxPopularityPosition = 0, }: Catalog = await catalogResponse.json(); - const cataolgResult: Catalog = { + const catalogResult: Catalog = { words, items, easterEggDays, @@ -55,9 +55,9 @@ export const getCatalogInfo = async (gameLanguage: string) => { maxPopularityPosition, }; - cachedCatalogs[gameLanguage] = cataolgResult; + cachedCatalogs[gameLanguage] = catalogResult; - return cataolgResult; + return catalogResult; }; export const getWordToGuess = async ( diff --git a/src/components/Words/WordToSubmitTip.tsx b/src/components/Words/WordToSubmitTip.tsx index 651ae30dc..39780450a 100644 --- a/src/components/Words/WordToSubmitTip.tsx +++ b/src/components/Words/WordToSubmitTip.tsx @@ -159,7 +159,7 @@ const WordToSubmitTip = () => { && ( {', '} - + {t(`game.youCanUseThisWe${capitalize(tipDetailsStatus)}`)} : diff --git a/src/store/utils/getKeyboardState.ts b/src/store/utils/getKeyboardState.ts index 7e7fd873b..4fe7f7a1d 100644 --- a/src/store/utils/getKeyboardState.ts +++ b/src/store/utils/getKeyboardState.ts @@ -1,28 +1,35 @@ -import { AffixStatus, WordStatus, FlatAffixes, UsedLetters } from '@common-types'; +import { + AffixStatus, + WordStatus, + FlatAffixes, + UsedLetters, +} from '@common-types'; import { getHasSpecialCharacters } from '@utils/normilzeWord'; +import { getUniqueArray } from '@utils/array'; import { getLetterOccuranceInWord } from './getLetterOccuranceInWord'; const getIsTextMatchingOrder = (text: string, order: string[]) => { - const { - isMatching, - } = order.reduce((stack, subtext) => { - if (!stack.restString.includes(subtext)) { - return { - restString: '', - isMatching: false, - }; - } + const { isMatching } = order.reduce( + (stack, subtext) => { + if (!stack.restString.includes(subtext)) { + return { + restString: '', + isMatching: false, + }; + } - const [, ...rest] = stack.restString.split(subtext); - stack.restString = rest.join(subtext); + const [, ...rest] = stack.restString.split(subtext); + stack.restString = rest.join(subtext); - return stack; - }, { - restString: text, - isMatching: true, - }); + return stack; + }, + { + restString: text, + isMatching: true, + }, + ); return isMatching; }; @@ -36,15 +43,15 @@ export const getKeyboardState = ({ positionLetters, flatAffixes, }: { - wordToGuess: string, - wordToSubmit: string, - incorrectLetters: UsedLetters, - positionLetters: UsedLetters, - flatAffixes: FlatAffixes, + wordToGuess: string; + wordToSubmit: string; + incorrectLetters: UsedLetters; + positionLetters: UsedLetters; + flatAffixes: FlatAffixes; }): { - status: AffixStatus | WordStatus, - details?: string, - detailsStatus?: 'expected' | 'unexpected', + status: AffixStatus | WordStatus; + details?: string; + detailsStatus?: 'expected' | 'unexpected'; } => { if (!wordToSubmit || !wordToSubmit.replaceAll(' ', '')) { return { @@ -52,9 +59,11 @@ export const getKeyboardState = ({ }; } - const uniqueWordLetters = [...(new Set(wordToSubmit.split('')))].filter(letter => letter !== ' '); + const uniqueWordLetters = [...new Set(wordToSubmit.split(''))].filter( + letter => letter !== ' ', + ); - const incorrectTyppedLetters = uniqueWordLetters.filter((uniqueLetter) => { + const incorrectTypedLetters = uniqueWordLetters.filter((uniqueLetter) => { const isIncorrect = typeof incorrectLetters[uniqueLetter] === 'number'; if (!isIncorrect) { return false; @@ -62,7 +71,10 @@ export const getKeyboardState = ({ const isCorrectSometimes = positionLetters[uniqueLetter] > 0; if (isCorrectSometimes) { - const occurrencesOfLetterInSubmitWord = getLetterOccuranceInWord(uniqueLetter, wordToSubmit); + const occurrencesOfLetterInSubmitWord = getLetterOccuranceInWord( + uniqueLetter, + wordToSubmit, + ); return occurrencesOfLetterInSubmitWord > positionLetters[uniqueLetter]; } @@ -70,11 +82,11 @@ export const getKeyboardState = ({ return true; }); - const hasIncorrectLetterTyped = incorrectTyppedLetters.length > 0; + const hasIncorrectLetterTyped = incorrectTypedLetters.length > 0; if (hasIncorrectLetterTyped) { return { status: AffixStatus.Incorrect, - details: incorrectTyppedLetters.join(', '), + details: incorrectTypedLetters.join(', '), detailsStatus: 'unexpected', }; } @@ -83,7 +95,13 @@ export const getKeyboardState = ({ const hasWordToSubmitSpecialCharacters = wordToSubmit && getHasSpecialCharacters(wordToSubmit); const specialCharacterTypedWhenNotNeeded = !hasWordToGuessSpecialCharacters && hasWordToSubmitSpecialCharacters; if (specialCharacterTypedWhenNotNeeded) { - const uniqueSpecialCharactersTyped = [...new Set(wordToSubmit.split('').filter(letter => getHasSpecialCharacters(letter)))]; + const uniqueSpecialCharactersTyped = [ + ...new Set( + wordToSubmit + .split('') + .filter(letter => getHasSpecialCharacters(letter)), + ), + ]; return { status: AffixStatus.Incorrect, @@ -93,7 +111,9 @@ export const getKeyboardState = ({ } if (flatAffixes) { - const isWrongStart = !wordToSubmit.startsWith(flatAffixes.start.slice(0, wordToSubmit.length)); + const isWrongStart = !wordToSubmit.startsWith( + flatAffixes.start.slice(0, wordToSubmit.length), + ); if (isWrongStart) { return { status: AffixStatus.IncorrectStart, @@ -113,39 +133,51 @@ export const getKeyboardState = ({ const uniqueRequiredLetters = Object.keys(positionLetters); - const { missingRequiredLetters, totalPresent, totalRequired } = uniqueRequiredLetters.reduce(( - stack: { - totalPresent: number, - totalRequired: number, - missingRequiredLetters: { - [letter: string]: number, - } + const { missingRequiredLetters, totalPresent, totalRequired } = uniqueRequiredLetters.reduce( + ( + stack: { + totalPresent: number; + totalRequired: number; + missingRequiredLetters: { + [letter: string]: number; + }; + }, + uniqueLetter, + ) => { + const occurrencesOfLetterInSubmitWord = getLetterOccuranceInWord( + uniqueLetter, + wordToSubmit, + ); + + const missingLettersTotal = positionLetters[uniqueLetter] <= occurrencesOfLetterInSubmitWord + ? 0 + : Math.min( + positionLetters[uniqueLetter], + positionLetters[uniqueLetter] - occurrencesOfLetterInSubmitWord, + ); + + stack.totalPresent + += positionLetters[uniqueLetter] - missingLettersTotal; + stack.totalRequired += positionLetters[uniqueLetter]; + + stack.missingRequiredLetters[uniqueLetter] = missingLettersTotal; + + return stack; }, - uniqueLetter, - ) => { - const occurrencesOfLetterInSubmitWord = getLetterOccuranceInWord(uniqueLetter, wordToSubmit); - - const missingLettersTotal = positionLetters[uniqueLetter] <= occurrencesOfLetterInSubmitWord - ? 0 - : Math.min(positionLetters[uniqueLetter], positionLetters[uniqueLetter] - occurrencesOfLetterInSubmitWord); - - stack.totalPresent += positionLetters[uniqueLetter] - missingLettersTotal; - stack.totalRequired += positionLetters[uniqueLetter]; - - stack.missingRequiredLetters[uniqueLetter] = missingLettersTotal; - - return stack; - }, { missingRequiredLetters: {}, totalPresent: 0, totalRequired: 0 }); + { missingRequiredLetters: {}, totalPresent: 0, totalRequired: 0 }, + ); const areAllRequiredUsed = totalRequired > 0 && totalRequired === totalPresent; const isMissingSomeRequiredLetters = totalRequired > totalPresent; if (isMissingSomeRequiredLetters) { - const hasManyRequiredAndSomeMissing = (totalRequired >= 5 && (totalRequired - totalPresent) <= 2) - || (totalRequired >= 7 && (totalRequired - totalPresent) <= 3); + const hasManyRequiredAndSomeMissing = (totalRequired >= 5 && totalRequired - totalPresent <= 2) + || (totalRequired >= 7 && totalRequired - totalPresent <= 3); if (hasManyRequiredAndSomeMissing) { - const missingLetters = Object.entries(missingRequiredLetters).filter(([, value]) => value > 0).map(([letter]) => letter); + const missingLetters = Object.entries(missingRequiredLetters) + .filter(([, value]) => value > 0) + .map(([letter]) => letter); return { status: WordStatus.IncorrectOccuranceMissing, @@ -167,12 +199,16 @@ export const getKeyboardState = ({ if (flatAffixes.notEnd.includes(wordToSubmit[wordToSubmit.length - 1])) { return { status: AffixStatus.IncorrectEnd, - details: `${PADDING_CHARACTER}${wordToSubmit[wordToSubmit.length - 1]}`, + details: `${PADDING_CHARACTER}${ + wordToSubmit[wordToSubmit.length - 1] + }`, detailsStatus: 'unexpected', }; } - const wrongMiddles = flatAffixes.middle.filter(flatAffix => !wordToSubmit.includes(flatAffix)); + const wrongMiddles = flatAffixes.middle.filter( + flatAffix => !wordToSubmit.includes(flatAffix), + ); const isWrongMiddle = wrongMiddles.length > 0; if (isWrongMiddle) { return { @@ -182,12 +218,16 @@ export const getKeyboardState = ({ } if (flatAffixes.correctOrders.length > 0) { - const wrongOrders = flatAffixes.correctOrders.filter(order => !getIsTextMatchingOrder(wordToSubmit, order)); + const wrongOrders = flatAffixes.correctOrders.filter( + order => !getIsTextMatchingOrder(wordToSubmit, order), + ); const isWrongOrder = wrongOrders.length > 0; if (isWrongOrder) { return { status: AffixStatus.IncorrectOrder, - details: wrongOrders.map(order => order.join(PADDING_CHARACTER)).join(', '), + details: getUniqueArray( + wrongOrders.map(order => order.join(PADDING_CHARACTER)), + ).join(', '), detailsStatus: 'expected', }; } @@ -200,26 +240,32 @@ export const getKeyboardState = ({ if (isWrongOrder) { return { status: AffixStatus.IncorrectOrder, - details: wrongOrders.map(order => order.join(PADDING_CHARACTER)).join(', '), + details: getUniqueArray( + wrongOrders.map(order => order.join(PADDING_CHARACTER)), + ).join(', '), detailsStatus: 'unexpected', }; } } if (flatAffixes.needsALetterBetween.length > 0) { - const wrongPairs = flatAffixes.needsALetterBetween.filter(([first, second]) => { - const regex = new RegExp(`${first}(.*)${second}`); + const wrongPairs = flatAffixes.needsALetterBetween.filter( + ([first, second]) => { + const regex = new RegExp(`${first}(.*)${second}`); - const parts = wordToSubmit.match(regex) ?? []; + const parts = wordToSubmit.match(regex) ?? []; - return parts.length >= 2 && parts[1].length === 0 - }); + return parts.length >= 2 && parts[1].length === 0; + }, + ); const isWrongPair = wrongPairs.length > 0; if (isWrongPair) { return { status: WordStatus.IncorrectPairWithLetterMissing, - details: wrongPairs.map(pair => pair.join('')).join(', '), + details: getUniqueArray( + wrongPairs.map(pair => pair.join('')), + ).join(', '), detailsStatus: 'unexpected', }; } diff --git a/src/utils/array.ts b/src/utils/array.ts new file mode 100644 index 000000000..d6b1e2b58 --- /dev/null +++ b/src/utils/array.ts @@ -0,0 +1 @@ +export const getUniqueArray = (items: T[]): T[] => [...new Set(items)];