@scrabble-solver/scrabble-solver 2.15.11 → 2.15.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +15 -15
- package/.next/cache/.rscinfo +1 -1
- package/.next/cache/.tsbuildinfo +1 -1
- package/.next/cache/webpack/client-production/0.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack.old +0 -0
- package/.next/cache/webpack/edge-server-production/0.pack +0 -0
- package/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/.next/cache/webpack/edge-server-production/index.pack.old +0 -0
- package/.next/cache/webpack/server-production/0.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack.old +0 -0
- package/.next/diagnostics/framework.json +1 -1
- package/.next/next-minimal-server.js.nft.json +1 -1
- package/.next/next-server.js.nft.json +1 -1
- package/.next/prerender-manifest.json +4 -4
- package/.next/required-server-files.json +7 -6
- package/.next/routes-manifest.json +1 -1
- package/.next/server/chunks/30.js +3 -3
- package/.next/server/chunks/318.js +1 -0
- package/.next/server/chunks/60.js +1 -1
- package/.next/server/chunks/974.js +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/404.js.nft.json +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/pages/_app.js +1 -1
- package/.next/server/pages/_app.js.nft.json +1 -1
- package/.next/server/pages/_error.js +1 -1
- package/.next/server/pages/_error.js.nft.json +1 -1
- package/.next/server/pages/api/solve.js +1 -1
- package/.next/server/pages/index.html +1 -1
- package/.next/server/pages/index.js +1 -1
- package/.next/server/pages/index.js.nft.json +1 -1
- package/.next/server/pages/index.json +1 -1
- package/.next/server/pages-manifest.json +1 -1
- package/.next/static/{47JHul8F9NSWCNSEuahuL → X6ny8arpUxpRCZ4OMm7Vo}/_buildManifest.js +1 -1
- package/.next/static/chunks/framework-57125a0cc6749ff9.js +1 -0
- package/.next/static/chunks/main-03618e8bd3cd04dd.js +1 -0
- package/.next/static/chunks/pages/{404-590e2a3839c1d9e0.js → 404-18b9f6f5faa91442.js} +1 -1
- package/.next/static/chunks/pages/_app-2378fe90e1762e8c.js +1 -0
- package/.next/static/chunks/pages/index-bfc599d9351773ae.js +1 -0
- package/.next/static/css/{6682db14f926d4c7.css → 04a3767982ec10e8.css} +1 -1
- package/.next/static/css/{d875648f38121a28.css → 1fae874a25934f54.css} +1 -1
- package/.next/trace +23 -23
- package/coverage/clover.xml +6 -0
- package/coverage/coverage-final.json +1 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +101 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov.info +0 -0
- package/package.json +17 -17
- package/src/api/getServerLoggingData.ts +1 -1
- package/src/api/isBoardValid.ts +1 -1
- package/src/api/isCellValid.ts +1 -1
- package/src/api/isRowValid.ts +1 -1
- package/src/components/Alert/Alert.tsx +1 -1
- package/src/components/Badge/Badge.tsx +1 -1
- package/src/components/Board/Board.tsx +8 -8
- package/src/components/Board/BoardPure.tsx +11 -11
- package/src/components/Board/components/Actions/Actions.tsx +3 -3
- package/src/components/Board/components/Actions/lib.ts +3 -3
- package/src/components/Board/components/Cell/Cell.tsx +7 -7
- package/src/components/Board/components/InputPrompt/InputPrompt.tsx +2 -2
- package/src/components/Board/components/ToggleDirectionButton/ToggleDirectionButton.tsx +2 -2
- package/src/components/Board/hooks/useBackgroundImage.tsx +1 -1
- package/src/components/Board/hooks/useBoardStyle.ts +1 -1
- package/src/components/Board/hooks/useGrid.ts +13 -13
- package/src/components/Board/lib.ts +37 -0
- package/src/components/Board/selectors.ts +8 -0
- package/src/components/Button/Button.tsx +1 -1
- package/src/components/Button/Link.tsx +1 -1
- package/src/components/Dictionary/Dictionary.tsx +10 -3
- package/src/components/DictionaryInput/DictionaryInput.tsx +1 -1
- package/src/components/EmptyState/EmptyState.tsx +3 -3
- package/src/components/IconButton/IconButton.tsx +1 -1
- package/src/components/IconButton/Link.tsx +1 -1
- package/src/components/Key/Key.tsx +1 -1
- package/src/components/Keys/Arrows/Arrows.tsx +1 -1
- package/src/components/Keys/index.tsx +1 -1
- package/src/components/Loading/Loading.tsx +6 -8
- package/src/components/Logo/LogoBlueprint.tsx +1 -1
- package/src/components/Modal/Modal.tsx +4 -2
- package/src/components/Modal/components/Section/Section.tsx +1 -1
- package/src/components/NavButtons/NavButtons.tsx +4 -3
- package/src/components/NavButtons/selectors.ts +11 -0
- package/src/components/NotFound/NotFound.tsx +1 -1
- package/src/components/PlainTiles/PlainTiles.tsx +1 -1
- package/src/components/PlainTiles/Tile.tsx +1 -1
- package/src/components/PlainTiles/lib.ts +90 -0
- package/src/components/Progress/Progress.tsx +1 -1
- package/src/components/Rack/Rack.tsx +10 -26
- package/src/components/Rack/components/InputPrompt/InputPrompt.tsx +5 -8
- package/src/components/Rack/components/InputPrompt/lib.test.ts +27 -0
- package/src/components/Rack/components/InputPrompt/lib.ts +19 -0
- package/src/components/Rack/components/RackTile/RackTile.tsx +9 -9
- package/src/components/Rack/selectors.ts +9 -0
- package/src/components/Radio/Radio.tsx +1 -1
- package/src/components/Results/Cell.tsx +2 -2
- package/src/components/Results/Header.tsx +1 -1
- package/src/components/Results/HeaderButton.tsx +2 -2
- package/src/components/Results/Result.tsx +5 -6
- package/src/components/Results/Results.tsx +6 -6
- package/src/components/Results/SolveButton.tsx +3 -3
- package/src/components/Results/types.ts +2 -2
- package/src/components/ResultsInput/ResultsInput.tsx +1 -1
- package/src/components/SeoMessage/SeoMessage.tsx +1 -1
- package/src/components/Solver/Solver.tsx +4 -4
- package/src/components/Solver/components/InsertButton/InsertButton.tsx +1 -1
- package/src/components/Solver/components/ResultCandidatePicker/ResultCandidatePicker.tsx +5 -5
- package/src/components/Spinner/Spinner.tsx +1 -1
- package/src/components/Tile/Tile.tsx +7 -7
- package/src/components/Tile/TilePure.tsx +8 -8
- package/src/components/Tooltip/Tooltip.tsx +1 -1
- package/src/components/Tooltip/TooltipContent.tsx +1 -1
- package/src/components/Tooltip/TooltipTrigger.tsx +1 -1
- package/src/components/Tooltip/context.ts +1 -1
- package/src/components/Tooltip/useTooltip.ts +1 -1
- package/src/hooks/useAppLayout.ts +1 -1
- package/src/hooks/useColumns.ts +28 -1
- package/src/hooks/useEffectOnce.ts +1 -1
- package/src/hooks/useLocalStorage.ts +8 -0
- package/src/i18n/constants.ts +1 -1
- package/src/i18n/i18n.ts +1 -1
- package/src/i18n/languages/english.json +3 -0
- package/src/i18n/languages/french.json +3 -0
- package/src/i18n/languages/german.json +3 -0
- package/src/i18n/languages/persian.json +3 -0
- package/src/i18n/languages/polish.json +3 -0
- package/src/i18n/languages/romanian.json +3 -0
- package/src/i18n/languages/spanish.json +3 -0
- package/src/i18n/languages/turkish.json +3 -0
- package/src/lib/createComparator.ts +1 -1
- package/src/lib/createKeyComparator.ts +1 -1
- package/src/lib/createKeyboardNavigation.ts +1 -1
- package/src/lib/createStringComparator.ts +1 -1
- package/src/lib/extractCharacters.test.ts +42 -15
- package/src/lib/extractCharacters.ts +27 -25
- package/src/lib/findCell.ts +1 -1
- package/src/lib/index.ts +2 -17
- package/src/lib/isCtrl.ts +1 -1
- package/src/lib/localeTransliterate.test.ts +14 -0
- package/src/lib/localeTransliterate.ts +18 -0
- package/src/lib/numberComparator.ts +1 -1
- package/src/lib/reverseComparator.ts +1 -1
- package/src/lib/zipCharactersAndTiles.ts +2 -2
- package/src/modals/DictionaryModal/DictionaryModal.tsx +1 -1
- package/src/modals/KeyMapModal/KeyMapModal.tsx +1 -1
- package/src/modals/KeyMapModal/components/Mapping/Mapping.tsx +1 -1
- package/src/modals/MenuModal/MenuModal.tsx +1 -1
- package/src/modals/RemainingTilesModal/RemainingTilesModal.tsx +3 -2
- package/src/modals/RemainingTilesModal/components/Character/Character.tsx +2 -2
- package/src/{lib/getRemainingTilesGroups.ts → modals/RemainingTilesModal/lib.ts} +26 -9
- package/src/modals/RemainingTilesModal/selectors.ts +7 -0
- package/src/modals/ResultsModal/ResultsModal.tsx +4 -4
- package/src/modals/SettingsModal/SettingsModal.tsx +6 -1
- package/src/modals/SettingsModal/components/AutoGroupTilesSetting/AutoGroupTilesSetting.tsx +1 -1
- package/src/modals/SettingsModal/components/AutoGroupTilesSetting/lib.ts +1 -1
- package/src/modals/SettingsModal/components/ConfigSetting/ConfigSetting.tsx +1 -1
- package/src/modals/SettingsModal/components/ConfigSetting/lib.ts +1 -1
- package/src/modals/SettingsModal/components/InputModeSetting/InputModeSetting.tsx +1 -1
- package/src/modals/SettingsModal/components/InputModeSetting/lib.ts +1 -1
- package/src/modals/SettingsModal/components/LocaleSetting/LocaleSetting.tsx +2 -2
- package/src/modals/SettingsModal/components/RemoveCellFiltersSetting/RemoveCellFiltersSetting.module.scss +12 -0
- package/src/modals/SettingsModal/components/RemoveCellFiltersSetting/RemoveCellFiltersSetting.tsx +53 -0
- package/src/modals/SettingsModal/components/RemoveCellFiltersSetting/index.ts +1 -0
- package/src/modals/SettingsModal/components/RemoveCellFiltersSetting/lib.ts +13 -0
- package/src/modals/SettingsModal/components/ShowCoordinatesSetting/ShowCoordinatesSetting.tsx +2 -2
- package/src/modals/SettingsModal/components/index.ts +1 -0
- package/src/modals/WordsModal/WordsModal.tsx +4 -3
- package/src/pages/_app.tsx +2 -2
- package/src/pages/_document.tsx +1 -1
- package/src/pages/api/dictionary/[locale]/[word].ts +2 -2
- package/src/pages/api/dictionary/[locale]/index.ts +2 -2
- package/src/pages/api/solve.ts +11 -2
- package/src/pages/api/verify.ts +2 -2
- package/src/pages/api/visit.ts +1 -1
- package/src/pages/index.tsx +34 -43
- package/src/parameters/index.ts +1 -0
- package/src/sdk/findWordDefinitions.ts +1 -1
- package/src/sdk/getDictionary.ts +1 -1
- package/src/sdk/solve.ts +1 -1
- package/src/sdk/verify.ts +1 -1
- package/src/service-worker/dictionaries/getDictionary.ts +1 -1
- package/src/service-worker/dictionaries/getDictionaryUrl.ts +1 -1
- package/src/service-worker/dictionaries/revalidateDictionary.ts +1 -1
- package/src/service-worker/getTrie.ts +1 -1
- package/src/service-worker/routeSolveRequests.ts +2 -2
- package/src/service-worker/routeVerifyRequests.ts +1 -1
- package/src/state/board/index.ts +4 -0
- package/src/state/{slices/boardInitialState.ts → board/initialState.ts} +3 -6
- package/src/state/board/selectors.ts +3 -0
- package/src/state/{slices/boardSlice.ts → board/slice.ts} +5 -4
- package/src/state/board/types.ts +3 -0
- package/src/state/cellFilters/index.ts +4 -0
- package/src/state/cellFilters/initialState.ts +3 -0
- package/src/state/cellFilters/lib.ts +8 -0
- package/src/state/cellFilters/selectors.ts +13 -0
- package/src/state/{slices/cellFilterSlice.ts → cellFilters/slice.ts} +15 -14
- package/src/state/cellFilters/types.ts +3 -0
- package/src/state/dictionary/index.ts +4 -0
- package/src/state/dictionary/initialState.ts +8 -0
- package/src/state/dictionary/selectors.ts +16 -0
- package/src/state/{slices/dictionarySlice.ts → dictionary/slice.ts} +3 -3
- package/src/state/dictionary/types.ts +8 -0
- package/src/state/index.ts +12 -5
- package/src/{lib/getRemainingTiles.ts → state/lib.ts} +3 -4
- package/src/state/localStorage.ts +11 -2
- package/src/state/rack/index.ts +4 -0
- package/src/state/rack/initialState.ts +12 -0
- package/src/state/rack/selectors.ts +7 -0
- package/src/state/{slices/rackSlice.ts → rack/slice.ts} +4 -4
- package/src/state/rack/types.ts +3 -0
- package/src/state/results/index.ts +4 -0
- package/src/state/results/initialState.ts +13 -0
- package/src/state/results/lib.ts +96 -0
- package/src/state/results/selectors.ts +75 -0
- package/src/state/{slices/resultsSlice.ts → results/slice.ts} +4 -4
- package/src/state/results/types.ts +10 -0
- package/src/state/sagas.ts +22 -23
- package/src/state/selectors.ts +15 -235
- package/src/state/settings/index.ts +4 -0
- package/src/state/{slices/settingsInitialState.ts → settings/initialState.ts} +4 -11
- package/src/state/settings/lib.ts +42 -0
- package/src/state/settings/selectors.ts +69 -0
- package/src/state/{slices/settingsSlice.ts → settings/slice.ts} +9 -4
- package/src/state/settings/types.ts +12 -0
- package/src/state/solve/index.ts +4 -0
- package/src/state/solve/initialState.ts +12 -0
- package/src/state/solve/selectors.ts +14 -0
- package/src/state/{slices/solveSlice.ts → solve/slice.ts} +3 -3
- package/src/state/solve/types.ts +10 -0
- package/src/state/store.ts +9 -11
- package/src/state/types.ts +16 -18
- package/src/state/useTranslate.ts +2 -2
- package/src/state/useTypedSelector.ts +2 -2
- package/src/state/verify/index.ts +4 -0
- package/src/state/verify/initialState.ts +12 -0
- package/src/state/verify/selectors.ts +9 -0
- package/src/state/{slices/verifySlice.ts → verify/slice.ts} +3 -3
- package/src/state/verify/types.ts +10 -0
- package/src/styles/global.scss +5 -0
- package/src/types/api.ts +1 -1
- package/src/types/index.ts +8 -3
- package/tsconfig.tsbuildinfo +1 -1
- package/.eslintrc.js +0 -10
- package/.next/server/chunks/968.js +0 -1
- package/.next/static/chunks/framework-288d1abd95de88d9.js +0 -1
- package/.next/static/chunks/main-016492249b3393e2.js +0 -1
- package/.next/static/chunks/pages/_app-0e951de0aebb6505.js +0 -1
- package/.next/static/chunks/pages/index-c1d5a66d0f4794a6.js +0 -1
- package/src/components/Board/lib/getBonusColor.ts +0 -16
- package/src/components/Board/lib/getPositionInGrid.ts +0 -13
- package/src/components/Board/lib/index.ts +0 -2
- package/src/components/PlainTiles/lib/createPlainTile.ts +0 -41
- package/src/components/PlainTiles/lib/createPlainTiles.ts +0 -25
- package/src/components/PlainTiles/lib/getViewbox.ts +0 -17
- package/src/components/PlainTiles/lib/getX.ts +0 -5
- package/src/components/PlainTiles/lib/getY.ts +0 -5
- package/src/components/PlainTiles/lib/index.ts +0 -6
- package/src/components/PlainTiles/lib/randomize.ts +0 -1
- package/src/lib/createArray.ts +0 -1
- package/src/lib/createGridOf.ts +0 -9
- package/src/lib/detectLocale.ts +0 -27
- package/src/lib/extractCharactersByCase.test.ts +0 -29
- package/src/lib/extractCharactersByCase.ts +0 -29
- package/src/lib/getCellSize.ts +0 -10
- package/src/lib/getCoordinates.ts +0 -16
- package/src/lib/getRemainingTilesCount.ts +0 -11
- package/src/lib/getTotalRemainingTilesCount.ts +0 -11
- package/src/lib/groupResults.ts +0 -35
- package/src/lib/guessLocale.ts +0 -20
- package/src/lib/isUpperCase.ts +0 -5
- package/src/lib/resultMatchesCellFilter.ts +0 -21
- package/src/lib/sortGroupedResults.ts +0 -21
- package/src/lib/sortResults.ts +0 -41
- package/src/state/slices/cellFilterInitialState.ts +0 -5
- package/src/state/slices/dictionaryInitialState.ts +0 -15
- package/src/state/slices/index.ts +0 -16
- package/src/state/slices/rackInitialState.ts +0 -9
- package/src/state/slices/resultsInitialState.ts +0 -20
- package/src/state/slices/solveInitialState.ts +0 -21
- package/src/state/slices/verifyInitialState.ts +0 -19
- /package/.next/static/{47JHul8F9NSWCNSEuahuL → X6ny8arpUxpRCZ4OMm7Vo}/_ssgManifest.js +0 -0
package/src/state/selectors.ts
CHANGED
|
@@ -1,255 +1,35 @@
|
|
|
1
|
-
/* eslint-disable max-lines */
|
|
2
|
-
|
|
3
1
|
import { createSelector } from '@reduxjs/toolkit';
|
|
4
|
-
import { getConfig } from '@scrabble-solver/configs';
|
|
5
|
-
import { BLANK } from '@scrabble-solver/constants';
|
|
6
|
-
import { Cell, Config, isError, Tile } from '@scrabble-solver/types';
|
|
7
|
-
|
|
8
|
-
import { i18n, LOCALE_FEATURES } from 'i18n';
|
|
9
|
-
import {
|
|
10
|
-
createRegExp,
|
|
11
|
-
findCell,
|
|
12
|
-
getRemainingTiles,
|
|
13
|
-
getRemainingTilesGroups,
|
|
14
|
-
groupResults,
|
|
15
|
-
resultMatchesCellFilter,
|
|
16
|
-
sortGroupedResults,
|
|
17
|
-
unorderedArraysEqual,
|
|
18
|
-
} from 'lib';
|
|
19
|
-
import { Point, ResultColumnId, Translations } from 'types';
|
|
20
|
-
|
|
21
|
-
import { RootState } from './types';
|
|
22
|
-
|
|
23
|
-
const selectCell = (_: unknown, cell: Cell): Cell => cell;
|
|
24
|
-
|
|
25
|
-
const selectPoint = (_: unknown, point: Point): Point => point;
|
|
26
|
-
|
|
27
|
-
const selectResultIndex = (_: unknown, index: number): number => index;
|
|
28
|
-
|
|
29
|
-
const selectCharacter = (_: unknown, character: string | null): string | null => character;
|
|
30
|
-
|
|
31
|
-
const selectTile = (_: unknown, tile: Tile | null): Tile | null => tile;
|
|
32
|
-
|
|
33
|
-
const selectBoardRoot = (state: RootState): RootState['board'] => state.board;
|
|
34
|
-
|
|
35
|
-
const selectDictionaryRoot = (state: RootState): RootState['dictionary'] => state.dictionary;
|
|
36
|
-
|
|
37
|
-
const selectCellFilterRoot = (state: RootState): RootState['cellFilter'] => state.cellFilter;
|
|
38
|
-
|
|
39
|
-
const selectRackRoot = (state: RootState): RootState['rack'] => state.rack;
|
|
40
|
-
|
|
41
|
-
const selectResultsRoot = (state: RootState): RootState['results'] => state.results;
|
|
42
|
-
|
|
43
|
-
const selectSettingsRoot = (state: RootState): RootState['settings'] => state.settings;
|
|
44
|
-
|
|
45
|
-
const selectSolveRoot = (state: RootState): RootState['solve'] => state.solve;
|
|
46
|
-
|
|
47
|
-
const selectVerifyRoot = (state: RootState): RootState['verify'] => state.verify;
|
|
48
|
-
|
|
49
|
-
export const selectDictionary = selectDictionaryRoot;
|
|
50
|
-
|
|
51
|
-
export const selectDictionaryError = createSelector([selectDictionaryRoot], (dictionary) => {
|
|
52
|
-
return isError(dictionary.error) ? dictionary.error : undefined;
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
export const selectLocale = createSelector([selectSettingsRoot], (settings) => settings.locale);
|
|
56
|
-
|
|
57
|
-
export const selectAutoGroupTiles = createSelector([selectSettingsRoot], (settings) => settings.autoGroupTiles);
|
|
58
|
-
|
|
59
|
-
export const selectLocaleAutoGroupTiles = createSelector([selectLocale, selectSettingsRoot], (locale, settings) => {
|
|
60
|
-
if (LOCALE_FEATURES[locale].direction === 'ltr' || settings.autoGroupTiles === null) {
|
|
61
|
-
return settings.autoGroupTiles;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return settings.autoGroupTiles === 'left' ? 'right' : 'left';
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
export const selectBoard = selectBoardRoot;
|
|
68
|
-
|
|
69
|
-
export const selectInputMode = createSelector([selectSettingsRoot], (settings) => settings.inputMode);
|
|
70
|
-
|
|
71
|
-
export const selectShowCoordinates = createSelector([selectSettingsRoot], (settings) => settings.showCoordinates);
|
|
72
|
-
|
|
73
|
-
export const selectGame = createSelector([selectSettingsRoot], (settings) => settings.game);
|
|
74
|
-
|
|
75
|
-
export const selectConfig = createSelector([selectGame, selectLocale], getConfig);
|
|
76
|
-
|
|
77
|
-
export const selectFilteredCells = selectCellFilterRoot;
|
|
78
|
-
|
|
79
|
-
export const selectCellFilter = createSelector([selectFilteredCells, selectPoint], (cellFilter, { x, y }) => {
|
|
80
|
-
return cellFilter.find((cell) => cell.x === x && cell.y === y);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
export const selectCellIsValid = createSelector([selectConfig, selectCell], (config, cell) => {
|
|
84
|
-
if (!cell.hasTile()) {
|
|
85
|
-
return true;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return config.tiles.some((tile) => tile.character === cell.tile.character);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
export const selectResultsRaw = createSelector([selectResultsRoot], (results) => results.results);
|
|
92
|
-
|
|
93
|
-
export const selectResultsQuery = createSelector([selectResultsRoot], (results) => results.query);
|
|
94
|
-
|
|
95
|
-
export const selectResultsSort = createSelector([selectResultsRoot], (results) => results.sort);
|
|
96
|
-
|
|
97
|
-
export const selectGroupedResults = createSelector(
|
|
98
|
-
[selectResultsRaw, selectResultsQuery, selectFilteredCells],
|
|
99
|
-
groupResults,
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
export const selectGroupedSortedResults = createSelector(
|
|
103
|
-
[selectGroupedResults, selectResultsSort, selectLocale, selectShowCoordinates],
|
|
104
|
-
sortGroupedResults,
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
export const selectResults = createSelector([selectGroupedSortedResults], (groupedResults) => {
|
|
108
|
-
return groupedResults ? [...groupedResults.matching, ...groupedResults.other] : groupedResults;
|
|
109
|
-
});
|
|
110
2
|
|
|
111
|
-
|
|
112
|
-
[selectResults, selectResultsQuery, selectFilteredCells, selectResultIndex],
|
|
113
|
-
(results, query, cellFilter, index) => {
|
|
114
|
-
if (!results) {
|
|
115
|
-
return false;
|
|
116
|
-
}
|
|
3
|
+
import { unorderedArraysEqual } from 'lib';
|
|
117
4
|
|
|
118
|
-
|
|
119
|
-
|
|
5
|
+
import { selectBoard } from './board';
|
|
6
|
+
import { getRemainingTiles } from './lib';
|
|
7
|
+
import { selectCharacters } from './rack';
|
|
8
|
+
import { selectConfig, selectLocale } from './settings';
|
|
9
|
+
import { selectLastSolvedParameters } from './solve';
|
|
120
10
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return resultMatchesCellFilter(result, cellFilter);
|
|
126
|
-
},
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
export const selectResultCandidate = createSelector([selectResultsRoot], (results) => results.candidate);
|
|
130
|
-
|
|
131
|
-
export const selectResultCandidateCells = createSelector(
|
|
132
|
-
[selectResultCandidate],
|
|
133
|
-
(resultCandidate): Cell[] => resultCandidate?.cells || [],
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
export const selectResultCandidateTiles = createSelector(
|
|
137
|
-
[selectResultCandidate],
|
|
138
|
-
(resultCandidate): Tile[] => resultCandidate?.tiles || [],
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
export const selectRowsWithCandidate = createSelector([selectBoardRoot, selectResultCandidateCells], (board, cells) => {
|
|
142
|
-
return board.rows.map((row: Cell[], y: number) => row.map((cell: Cell, x: number) => findCell(cells, x, y) || cell));
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
export const selectCellBonus = createSelector([selectConfig, selectCell], (config: Config, cell: Cell) => {
|
|
146
|
-
return config.getCellBonus(cell);
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
export const selectCharacterPoints = createSelector(
|
|
150
|
-
[selectConfig, selectCharacter],
|
|
151
|
-
(config: Config, character: string | null) => {
|
|
152
|
-
return config.getCharacterPoints(character);
|
|
153
|
-
},
|
|
154
|
-
);
|
|
155
|
-
|
|
156
|
-
export const selectCharacterIsValid = createSelector(
|
|
157
|
-
[selectConfig, selectCharacter],
|
|
158
|
-
(config: Config, character: string | null) => {
|
|
159
|
-
if (character === null || character === BLANK) {
|
|
160
|
-
return true;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return config.tiles.some((tile) => tile.character === character);
|
|
11
|
+
const selectHasBoardChanged = createSelector(
|
|
12
|
+
[selectLastSolvedParameters, selectBoard],
|
|
13
|
+
(lastSolvedParameters, board) => {
|
|
14
|
+
return !lastSolvedParameters.board.equals(board);
|
|
164
15
|
},
|
|
165
16
|
);
|
|
166
17
|
|
|
167
|
-
|
|
168
|
-
return config.getTilePoints(tile);
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
export const selectTranslations = createSelector([selectLocale], (locale) => i18n[locale]);
|
|
172
|
-
|
|
173
|
-
export const selectTranslation = createSelector(
|
|
174
|
-
[selectTranslations, selectLocale, (_: unknown, id: keyof Translations) => id],
|
|
175
|
-
(translations, locale, id): string => {
|
|
176
|
-
const translation = translations[id];
|
|
177
|
-
|
|
178
|
-
if (typeof translation === 'undefined') {
|
|
179
|
-
throw new Error(`Untranslated key "${id}" in locale "${locale}"`);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return translation;
|
|
183
|
-
},
|
|
184
|
-
);
|
|
185
|
-
|
|
186
|
-
export const selectRack = selectRackRoot;
|
|
187
|
-
|
|
188
|
-
export const selectCharacters = createSelector(selectRackRoot, (rack) => rack.filter((tile) => tile !== null));
|
|
189
|
-
|
|
190
|
-
export const selectLastSolvedParameters = createSelector([selectSolveRoot], (solve) => solve.lastSolvedParameters);
|
|
191
|
-
|
|
192
|
-
export const selectIsLoading = createSelector([selectSolveRoot], (solve) => solve.isLoading);
|
|
193
|
-
|
|
194
|
-
export const selectSolveError = createSelector([selectSolveRoot], (solve) => {
|
|
195
|
-
return isError(solve.error) ? solve.error : undefined;
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
export const selectHaveCharactersChanged = createSelector(
|
|
18
|
+
const selectHaveCharactersChanged = createSelector(
|
|
199
19
|
[selectLastSolvedParameters, selectCharacters, selectLocale],
|
|
200
20
|
(lastSolvedParameters, characters, locale) => {
|
|
201
21
|
return !unorderedArraysEqual(lastSolvedParameters.characters, characters, locale);
|
|
202
22
|
},
|
|
203
23
|
);
|
|
204
24
|
|
|
205
|
-
export const selectHasBoardChanged = createSelector(
|
|
206
|
-
[selectLastSolvedParameters, selectBoardRoot],
|
|
207
|
-
(lastSolvedParameters, board) => !lastSolvedParameters.board.equals(board),
|
|
208
|
-
);
|
|
209
|
-
|
|
210
25
|
export const selectAreResultsOutdated = createSelector(
|
|
211
26
|
[selectHasBoardChanged, selectHaveCharactersChanged],
|
|
212
|
-
(hasBoardChanged, haveCharactersChanged) =>
|
|
27
|
+
(hasBoardChanged, haveCharactersChanged) => {
|
|
28
|
+
return hasBoardChanged || haveCharactersChanged;
|
|
29
|
+
},
|
|
213
30
|
);
|
|
214
31
|
|
|
215
32
|
export const selectRemainingTiles = createSelector(
|
|
216
|
-
[selectConfig,
|
|
33
|
+
[selectConfig, selectBoard, selectCharacters, selectLocale],
|
|
217
34
|
getRemainingTiles,
|
|
218
35
|
);
|
|
219
|
-
|
|
220
|
-
export const selectHasOverusedTiles = createSelector([selectRemainingTiles], (remainingTiles) => {
|
|
221
|
-
return remainingTiles.some(({ count = 0, usedCount }) => usedCount > count);
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
export const selectRemainingTilesGroups = createSelector([selectRemainingTiles], getRemainingTilesGroups);
|
|
225
|
-
|
|
226
|
-
export const selectVerify = selectVerifyRoot;
|
|
227
|
-
|
|
228
|
-
export const selectHasInvalidWords = createSelector([selectVerify], ({ invalidWords }) => {
|
|
229
|
-
return invalidWords.length > 0;
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
export const selectColumns = createSelector([selectLocale, selectShowCoordinates], (locale, showCoordinates) => {
|
|
233
|
-
const { consonants, vowels } = LOCALE_FEATURES[locale];
|
|
234
|
-
const columns: ResultColumnId[] = [
|
|
235
|
-
ResultColumnId.Word,
|
|
236
|
-
ResultColumnId.TilesCount,
|
|
237
|
-
ResultColumnId.BlanksCount,
|
|
238
|
-
ResultColumnId.WordsCount,
|
|
239
|
-
ResultColumnId.Points,
|
|
240
|
-
];
|
|
241
|
-
|
|
242
|
-
if (showCoordinates !== 'hidden') {
|
|
243
|
-
columns.push(ResultColumnId.Coordinates);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
if (vowels) {
|
|
247
|
-
columns.push(ResultColumnId.VowelsCount);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
if (consonants) {
|
|
251
|
-
columns.push(ResultColumnId.ConsonantsCount);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
return columns;
|
|
255
|
-
});
|
|
@@ -1,17 +1,9 @@
|
|
|
1
|
-
import { Game
|
|
2
|
-
|
|
3
|
-
import { guessLocale } from 'lib';
|
|
4
|
-
import { AutoGroupTiles, InputMode } from 'types';
|
|
1
|
+
import { Game } from '@scrabble-solver/types';
|
|
5
2
|
|
|
6
3
|
import { localStorage } from '../localStorage';
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
game: Game;
|
|
11
|
-
inputMode: InputMode;
|
|
12
|
-
locale: Locale;
|
|
13
|
-
showCoordinates: ShowCoordinates;
|
|
14
|
-
}
|
|
5
|
+
import { guessLocale } from './lib';
|
|
6
|
+
import type { SettingsState } from './types';
|
|
15
7
|
|
|
16
8
|
const localStorageAutoGroupTiles = localStorage.getAutoGroupTiles();
|
|
17
9
|
const isTouchScreen = typeof globalThis.matchMedia !== 'undefined' && globalThis.matchMedia('(hover: none)').matches;
|
|
@@ -22,4 +14,5 @@ export const settingsInitialState: SettingsState = {
|
|
|
22
14
|
inputMode: localStorage.getInputMode() ?? (isTouchScreen ? 'touchscreen' : 'keyboard'),
|
|
23
15
|
locale: localStorage.getLocale() ?? guessLocale(),
|
|
24
16
|
showCoordinates: localStorage.getShowCoordinates() ?? 'hidden',
|
|
17
|
+
removeCellFilters: localStorage.getRemoveCellFilters() ?? 'always',
|
|
25
18
|
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Locale } from '@scrabble-solver/types';
|
|
2
|
+
|
|
3
|
+
export const guessLocale = (): Locale => {
|
|
4
|
+
if (!globalThis.navigator) {
|
|
5
|
+
return Locale.EN_US;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const languages = globalThis.navigator.languages;
|
|
9
|
+
|
|
10
|
+
if (languages.includes('pl') || languages.includes('pl-PL')) {
|
|
11
|
+
return Locale.PL_PL;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (languages.includes('en-GB')) {
|
|
15
|
+
return Locale.EN_GB;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (languages.includes('fa') || languages.includes('fa-IR')) {
|
|
19
|
+
return Locale.FA_IR;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (languages.includes('fr-FR')) {
|
|
23
|
+
return Locale.FR_FR;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (languages.includes('ro') || languages.includes('ro-RO')) {
|
|
27
|
+
return Locale.RO_RO;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const locales = Object.values(Locale);
|
|
31
|
+
const exactMatch = locales.find((locale) => globalThis.navigator.language === String(locale));
|
|
32
|
+
|
|
33
|
+
if (exactMatch) {
|
|
34
|
+
return exactMatch;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const partialMatch = locales.find((locale) => {
|
|
38
|
+
return globalThis.navigator.language === locale.substring(0, 2);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
return partialMatch ?? Locale.EN_US;
|
|
42
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { createSelector } from '@reduxjs/toolkit';
|
|
2
|
+
import { getConfig } from '@scrabble-solver/configs';
|
|
3
|
+
import { BLANK } from '@scrabble-solver/constants';
|
|
4
|
+
import { type Cell, type Tile } from '@scrabble-solver/types';
|
|
5
|
+
|
|
6
|
+
import { i18n, LOCALE_FEATURES } from 'i18n';
|
|
7
|
+
|
|
8
|
+
import type { RootState } from '../types';
|
|
9
|
+
|
|
10
|
+
const selectCell = (_: unknown, cell: Cell): Cell => cell;
|
|
11
|
+
|
|
12
|
+
const selectCharacter = (_: unknown, character: string | null): string | null => character;
|
|
13
|
+
|
|
14
|
+
const selectTile = (_: unknown, tile: Tile | null): Tile | null => tile;
|
|
15
|
+
|
|
16
|
+
export const selectSettings = (state: RootState) => state.settings;
|
|
17
|
+
|
|
18
|
+
export const selectAutoGroupTiles = createSelector([selectSettings], (settings) => settings.autoGroupTiles);
|
|
19
|
+
|
|
20
|
+
export const selectGame = createSelector([selectSettings], (settings) => settings.game);
|
|
21
|
+
|
|
22
|
+
export const selectInputMode = createSelector([selectSettings], (settings) => settings.inputMode);
|
|
23
|
+
|
|
24
|
+
export const selectLocale = createSelector([selectSettings], (settings) => settings.locale);
|
|
25
|
+
|
|
26
|
+
export const selectLocaleAutoGroupTiles = createSelector([selectLocale, selectSettings], (locale, settings) => {
|
|
27
|
+
if (LOCALE_FEATURES[locale].direction === 'ltr' || settings.autoGroupTiles === null) {
|
|
28
|
+
return settings.autoGroupTiles;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return settings.autoGroupTiles === 'left' ? 'right' : 'left';
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export const selectShowCoordinates = createSelector([selectSettings], (settings) => settings.showCoordinates);
|
|
35
|
+
|
|
36
|
+
export const selectConfig = createSelector([selectGame, selectLocale], getConfig);
|
|
37
|
+
|
|
38
|
+
export const selectCharacterPoints = createSelector([selectConfig, selectCharacter], (config, character) => {
|
|
39
|
+
return config.getCharacterPoints(character);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
export const selectCharacterIsValid = createSelector([selectConfig, selectCharacter], (config, character) => {
|
|
43
|
+
if (character === null || character === BLANK) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return config.tiles.some((tile) => tile.character === character);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export const selectCellBonus = createSelector([selectConfig, selectCell], (config, cell) => {
|
|
51
|
+
return config.getCellBonus(cell);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
export const selectTilePoints = createSelector([selectConfig, selectTile], (config, tile) => {
|
|
55
|
+
return config.getTilePoints(tile);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export const selectCellIsValid = createSelector([selectConfig, selectCell], (config, cell) => {
|
|
59
|
+
if (!cell.hasTile()) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return config.tiles.some((tile) => tile.character === cell.tile.character);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
export const selectTranslations = createSelector([selectLocale], (locale) => i18n[locale]);
|
|
67
|
+
|
|
68
|
+
export const selectRemoveCellFilters = createSelector([selectSettings], (settings) => settings.removeCellFilters);
|
|
69
|
+
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
|
2
|
-
import { Game, Locale, ShowCoordinates } from '@scrabble-solver/types';
|
|
1
|
+
import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
|
|
2
|
+
import { type Game, type Locale, type ShowCoordinates } from '@scrabble-solver/types';
|
|
3
3
|
|
|
4
|
-
import { AutoGroupTiles, InputMode } from 'types';
|
|
4
|
+
import type { AutoGroupTiles, InputMode, RemoveCellFilters } from 'types';
|
|
5
5
|
|
|
6
|
-
import { settingsInitialState } from './
|
|
6
|
+
import { settingsInitialState } from './initialState';
|
|
7
7
|
|
|
8
8
|
export const settingsSlice = createSlice({
|
|
9
9
|
initialState: settingsInitialState,
|
|
@@ -34,6 +34,11 @@ export const settingsSlice = createSlice({
|
|
|
34
34
|
return { ...state, showCoordinates };
|
|
35
35
|
},
|
|
36
36
|
|
|
37
|
+
changeRemoveCellFilters: (state, action: PayloadAction<RemoveCellFilters>) => {
|
|
38
|
+
const removeCellFilters = action.payload;
|
|
39
|
+
return { ...state, removeCellFilters };
|
|
40
|
+
},
|
|
41
|
+
|
|
37
42
|
init: (state, action: PayloadAction<Partial<Pick<typeof settingsInitialState, 'game' | 'locale'>>>) => {
|
|
38
43
|
return { ...state, ...action.payload };
|
|
39
44
|
},
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Game, type Locale, type ShowCoordinates } from '@scrabble-solver/types';
|
|
2
|
+
|
|
3
|
+
import type { AutoGroupTiles, InputMode, RemoveCellFilters } from 'types';
|
|
4
|
+
|
|
5
|
+
export interface SettingsState {
|
|
6
|
+
autoGroupTiles: AutoGroupTiles;
|
|
7
|
+
game: Game;
|
|
8
|
+
inputMode: InputMode;
|
|
9
|
+
locale: Locale;
|
|
10
|
+
showCoordinates: ShowCoordinates;
|
|
11
|
+
removeCellFilters: RemoveCellFilters;
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { boardInitialState } from '../board';
|
|
2
|
+
|
|
3
|
+
import type { SolveState } from './types';
|
|
4
|
+
|
|
5
|
+
export const solveInitialState: SolveState = {
|
|
6
|
+
error: undefined,
|
|
7
|
+
isLoading: false,
|
|
8
|
+
lastSolvedParameters: {
|
|
9
|
+
board: boardInitialState,
|
|
10
|
+
characters: [],
|
|
11
|
+
},
|
|
12
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createSelector } from '@reduxjs/toolkit';
|
|
2
|
+
import { isError } from '@scrabble-solver/types';
|
|
3
|
+
|
|
4
|
+
import type { RootState } from '../types';
|
|
5
|
+
|
|
6
|
+
export const selectSolve = (state: RootState) => state.solve;
|
|
7
|
+
|
|
8
|
+
export const selectSolveError = createSelector([selectSolve], (solve) => {
|
|
9
|
+
return isError(solve.error) ? solve.error : undefined;
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export const selectSolveIsLoading = createSelector([selectSolve], (solve) => solve.isLoading);
|
|
13
|
+
|
|
14
|
+
export const selectLastSolvedParameters = createSelector([selectSolve], (solve) => solve.lastSolvedParameters);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
|
2
|
-
import { Board } from '@scrabble-solver/types';
|
|
1
|
+
import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
|
|
2
|
+
import { type Board } from '@scrabble-solver/types';
|
|
3
3
|
|
|
4
|
-
import { solveInitialState } from './
|
|
4
|
+
import { solveInitialState } from './initialState';
|
|
5
5
|
|
|
6
6
|
interface SolveParameters {
|
|
7
7
|
board: Board;
|
package/src/state/store.ts
CHANGED
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
import { configureStore } from '@reduxjs/toolkit';
|
|
2
2
|
import reduxSaga from 'redux-saga';
|
|
3
3
|
|
|
4
|
+
import { boardSlice } from './board';
|
|
5
|
+
import { cellFiltersSlice } from './cellFilters';
|
|
6
|
+
import { dictionarySlice } from './dictionary';
|
|
7
|
+
import { rackSlice } from './rack';
|
|
8
|
+
import { resultsSlice } from './results';
|
|
4
9
|
import { rootSaga } from './sagas';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
dictionarySlice,
|
|
9
|
-
rackSlice,
|
|
10
|
-
resultsSlice,
|
|
11
|
-
settingsSlice,
|
|
12
|
-
solveSlice,
|
|
13
|
-
verifySlice,
|
|
14
|
-
} from './slices';
|
|
10
|
+
import { settingsSlice } from './settings';
|
|
11
|
+
import { solveSlice } from './solve';
|
|
12
|
+
import { verifySlice } from './verify';
|
|
15
13
|
|
|
16
14
|
const sagaMiddleware = reduxSaga();
|
|
17
15
|
|
|
18
16
|
export const store = configureStore({
|
|
19
17
|
reducer: {
|
|
20
18
|
board: boardSlice.reducer,
|
|
21
|
-
|
|
19
|
+
cellFilters: cellFiltersSlice.reducer,
|
|
22
20
|
dictionary: dictionarySlice.reducer,
|
|
23
21
|
rack: rackSlice.reducer,
|
|
24
22
|
results: resultsSlice.reducer,
|
package/src/state/types.ts
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
verifySlice,
|
|
10
|
-
} from './slices';
|
|
1
|
+
import type { BoardState } from './board';
|
|
2
|
+
import type { CellFiltersState } from './cellFilters';
|
|
3
|
+
import type { DictionaryState } from './dictionary';
|
|
4
|
+
import type { RackState } from './rack';
|
|
5
|
+
import type { ResultsState } from './results';
|
|
6
|
+
import type { SettingsState } from './settings';
|
|
7
|
+
import type { SolveState } from './solve';
|
|
8
|
+
import type { VerifyState } from './verify';
|
|
11
9
|
|
|
12
10
|
export type RootState = {
|
|
13
|
-
board:
|
|
14
|
-
|
|
15
|
-
dictionary:
|
|
16
|
-
rack:
|
|
17
|
-
results:
|
|
18
|
-
settings:
|
|
19
|
-
solve:
|
|
20
|
-
verify:
|
|
11
|
+
board: BoardState;
|
|
12
|
+
cellFilters: CellFiltersState;
|
|
13
|
+
dictionary: DictionaryState;
|
|
14
|
+
rack: RackState;
|
|
15
|
+
results: ResultsState;
|
|
16
|
+
settings: SettingsState;
|
|
17
|
+
solve: SolveState;
|
|
18
|
+
verify: VerifyState;
|
|
21
19
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useCallback } from 'react';
|
|
2
2
|
|
|
3
|
-
import { Translate } from 'types';
|
|
3
|
+
import type { Translate } from 'types';
|
|
4
4
|
|
|
5
|
-
import { selectLocale, selectTranslations } from './
|
|
5
|
+
import { selectLocale, selectTranslations } from './settings';
|
|
6
6
|
import { useTypedSelector } from './useTypedSelector';
|
|
7
7
|
|
|
8
8
|
export const useTranslate = (): Translate => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { TypedUseSelectorHook, useSelector } from 'react-redux';
|
|
1
|
+
import { type TypedUseSelectorHook, useSelector } from 'react-redux';
|
|
2
2
|
|
|
3
|
-
import { RootState } from './types';
|
|
3
|
+
import type { RootState } from './types';
|
|
4
4
|
|
|
5
5
|
export const useTypedSelector: TypedUseSelectorHook<RootState> = useSelector;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { boardInitialState } from '../board';
|
|
2
|
+
|
|
3
|
+
import type { VerifyState } from './types';
|
|
4
|
+
|
|
5
|
+
export const verifyInitialState: VerifyState = {
|
|
6
|
+
isLoading: false,
|
|
7
|
+
lastSolvedParameters: {
|
|
8
|
+
board: boardInitialState,
|
|
9
|
+
},
|
|
10
|
+
invalidWords: [],
|
|
11
|
+
validWords: [],
|
|
12
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createSelector } from '@reduxjs/toolkit';
|
|
2
|
+
|
|
3
|
+
import type { RootState } from '../types';
|
|
4
|
+
|
|
5
|
+
export const selectVerify = (state: RootState) => state.verify;
|
|
6
|
+
|
|
7
|
+
export const selectInvalidWords = createSelector([selectVerify], (verify) => verify.invalidWords);
|
|
8
|
+
|
|
9
|
+
export const selectValidWords = createSelector([selectVerify], (verify) => verify.validWords);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
|
2
|
-
import { Board } from '@scrabble-solver/types';
|
|
1
|
+
import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
|
|
2
|
+
import { type Board } from '@scrabble-solver/types';
|
|
3
3
|
|
|
4
|
-
import { verifyInitialState } from './
|
|
4
|
+
import { verifyInitialState } from './initialState';
|
|
5
5
|
|
|
6
6
|
interface VerifyParameters {
|
|
7
7
|
board: Board;
|