@scrabble-solver/scrabble-solver 2.15.10 → 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/812.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/dictionary/[locale]/[word].js.nft.json +1 -1
- package/.next/server/pages/api/dictionary/[locale].js.nft.json +1 -1
- package/.next/server/pages/api/solve.js +1 -1
- package/.next/server/pages/api/solve.js.nft.json +1 -1
- package/.next/server/pages/api/verify.js.nft.json +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/{ylO_ttKeJTuoqDYywao5A → 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 +19 -18
- 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 +12 -12
- 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 +16 -12
- 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 +5 -4
- 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/getCoordinate.test.ts +22 -0
- package/src/lib/getCoordinate.ts +9 -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 +7 -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 +4 -3
- 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 +38 -44
- 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 +9 -4
- package/tsconfig.tsbuildinfo +1 -0
- 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-ac93a74c390f2ab8.js +0 -1
- package/.next/static/chunks/pages/index-e5f1caa581e6d3b8.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 -5
- package/src/lib/getTotalRemainingTilesCount.ts +0 -5
- 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/{ylO_ttKeJTuoqDYywao5A → X6ny8arpUxpRCZ4OMm7Vo}/_ssgManifest.js +0 -0
package/src/state/sagas.ts
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
4
4
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
5
5
|
|
|
6
|
-
import { PayloadAction } from '@reduxjs/toolkit';
|
|
6
|
+
import { type PayloadAction } from '@reduxjs/toolkit';
|
|
7
7
|
import { hasConfig, languages } from '@scrabble-solver/configs';
|
|
8
|
-
import { Board, Locale, Result } from '@scrabble-solver/types';
|
|
8
|
+
import { Board, type Locale, type Result } from '@scrabble-solver/types';
|
|
9
9
|
import { call, delay, put, select, takeEvery, takeLatest } from 'redux-saga/effects';
|
|
10
10
|
|
|
11
11
|
import { LOCALE_FEATURES } from 'i18n';
|
|
@@ -13,27 +13,21 @@ import { memoize } from 'lib';
|
|
|
13
13
|
import { findWordDefinitions, solve, verify, visit } from 'sdk';
|
|
14
14
|
|
|
15
15
|
import { initialize, reset } from './actions';
|
|
16
|
+
import { boardSlice, selectBoard } from './board';
|
|
17
|
+
import { cellFiltersSlice, selectCellFilter } from './cellFilters';
|
|
18
|
+
import { dictionarySlice, selectDictionary } from './dictionary';
|
|
19
|
+
import { rackSlice, selectCharacters, selectRack } from './rack';
|
|
20
|
+
import { resultsSlice } from './results';
|
|
16
21
|
import {
|
|
17
|
-
selectBoard,
|
|
18
|
-
selectCellFilter,
|
|
19
|
-
selectCharacters,
|
|
20
22
|
selectConfig,
|
|
21
|
-
selectDictionary,
|
|
22
23
|
selectGame,
|
|
23
24
|
selectLocale,
|
|
24
25
|
selectLocaleAutoGroupTiles,
|
|
25
|
-
|
|
26
|
-
} from './selectors';
|
|
27
|
-
import {
|
|
28
|
-
boardSlice,
|
|
29
|
-
cellFilterSlice,
|
|
30
|
-
dictionarySlice,
|
|
31
|
-
rackSlice,
|
|
32
|
-
resultsSlice,
|
|
26
|
+
selectRemoveCellFilters,
|
|
33
27
|
settingsSlice,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
} from './
|
|
28
|
+
} from './settings';
|
|
29
|
+
import { solveSlice } from './solve';
|
|
30
|
+
import { verifySlice } from './verify';
|
|
37
31
|
|
|
38
32
|
const SUBMIT_DELAY = 150;
|
|
39
33
|
|
|
@@ -62,7 +56,7 @@ function* onCellValueChange({ payload }: PayloadAction<{ value: string; x: numbe
|
|
|
62
56
|
const filter = yield select((state) => selectCellFilter(state, payload));
|
|
63
57
|
|
|
64
58
|
if (filter) {
|
|
65
|
-
yield put(
|
|
59
|
+
yield put(cellFiltersSlice.actions.cancel(payload));
|
|
66
60
|
}
|
|
67
61
|
|
|
68
62
|
yield put(resultsSlice.actions.changeResultCandidate(null));
|
|
@@ -75,8 +69,13 @@ function* onRackValueChange(): AnyGenerator {
|
|
|
75
69
|
|
|
76
70
|
function* onApplyResult({ payload: result }: PayloadAction<Result>): AnyGenerator {
|
|
77
71
|
const autoGroupTiles = yield select(selectLocaleAutoGroupTiles);
|
|
72
|
+
const removeCellFilters = yield select(selectRemoveCellFilters);
|
|
78
73
|
yield put(boardSlice.actions.applyResult(result));
|
|
79
|
-
|
|
74
|
+
if (removeCellFilters === 'never') {
|
|
75
|
+
yield put(cellFiltersSlice.actions.removeCells(result.cells));
|
|
76
|
+
} else {
|
|
77
|
+
yield put(cellFiltersSlice.actions.reset());
|
|
78
|
+
}
|
|
80
79
|
yield put(rackSlice.actions.removeTiles(result.tiles));
|
|
81
80
|
yield put(rackSlice.actions.groupTiles(autoGroupTiles));
|
|
82
81
|
yield put(verifySlice.actions.submit());
|
|
@@ -92,8 +91,8 @@ function* onGameChange(): AnyGenerator {
|
|
|
92
91
|
}
|
|
93
92
|
|
|
94
93
|
yield put(resultsSlice.actions.reset());
|
|
94
|
+
yield* resetRack();
|
|
95
95
|
yield put(verifySlice.actions.submit());
|
|
96
|
-
yield* ensureProperTilesCount();
|
|
97
96
|
}
|
|
98
97
|
|
|
99
98
|
function* onDictionarySubmit(): AnyGenerator {
|
|
@@ -126,7 +125,7 @@ function* onInitialize(): AnyGenerator {
|
|
|
126
125
|
yield call(visit);
|
|
127
126
|
|
|
128
127
|
if (!board.isEmpty()) {
|
|
129
|
-
yield*
|
|
128
|
+
yield* resetRack();
|
|
130
129
|
yield put(verifySlice.actions.submit());
|
|
131
130
|
}
|
|
132
131
|
}
|
|
@@ -135,7 +134,7 @@ function* onReset(): AnyGenerator {
|
|
|
135
134
|
const config = yield select(selectConfig);
|
|
136
135
|
|
|
137
136
|
yield put(boardSlice.actions.init(Board.create(config.boardWidth, config.boardHeight)));
|
|
138
|
-
yield put(
|
|
137
|
+
yield put(cellFiltersSlice.actions.reset());
|
|
139
138
|
yield put(dictionarySlice.actions.reset());
|
|
140
139
|
yield put(rackSlice.actions.reset());
|
|
141
140
|
yield put(resultsSlice.actions.reset());
|
|
@@ -223,7 +222,7 @@ function* onVerify(): AnyGenerator {
|
|
|
223
222
|
}
|
|
224
223
|
}
|
|
225
224
|
|
|
226
|
-
function*
|
|
225
|
+
function* resetRack(): AnyGenerator {
|
|
227
226
|
const { config } = yield select(selectConfig);
|
|
228
227
|
const rack = yield select(selectRack);
|
|
229
228
|
|
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, 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,
|