scrabble-solver 2.13.12 → 2.13.13
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/.eslintrc.js +13 -4
- package/.github/workflows/cypress.yml +24 -0
- package/.github/workflows/eslint.yml +9 -10
- package/.github/workflows/jest.yml +27 -0
- package/.nx/cache/nx_files.nxt +0 -0
- package/.nx/workspace-data/file-map.json +632 -548
- package/.nx/workspace-data/lockfile.hash +1 -1
- package/.nx/workspace-data/parsed-lock-file.json +5765 -5261
- package/.nx/workspace-data/project-graph.json +4745 -3485
- package/README.md +5 -3
- package/cypress/e2e/app.spec.cy.ts +107 -0
- package/cypress/e2e/bugs/112.spec.cy.ts +29 -0
- package/cypress/e2e/bugs/129.spec.cy.ts +13 -0
- package/cypress/e2e/bugs/2.spec.cy.ts +15 -0
- package/cypress/e2e/bugs/3.spec.cy.ts +15 -0
- package/cypress/e2e/bugs/342.spec.cy.ts +37 -0
- package/cypress/e2e/bugs/348.spec.cy.ts +73 -0
- package/cypress/support/commands.ts +4 -0
- package/cypress/support/e2e.ts +1 -0
- package/cypress/support/index.ts +1 -0
- package/cypress/support/lib/actions.ts +57 -0
- package/cypress/support/lib/index.ts +2 -0
- package/cypress/support/lib/selectors.ts +70 -0
- package/cypress/tsconfig.json +9 -0
- package/cypress.config.ts +9 -0
- package/jest.config.js +2 -3
- package/lerna.json +1 -1
- package/package.json +27 -20
- package/packages/configs/package.json +3 -3
- package/packages/constants/package.json +1 -1
- package/packages/dictionaries/package-lock.json +2 -2
- package/packages/dictionaries/package.json +4 -4
- package/packages/logger/package-lock.json +3 -3
- package/packages/logger/package.json +2 -2
- package/packages/scrabble-solver/.next/BUILD_ID +1 -1
- package/packages/scrabble-solver/.next/build-manifest.json +14 -14
- package/packages/scrabble-solver/.next/cache/.tsbuildinfo +1 -1
- package/packages/scrabble-solver/.next/cache/eslint/.cache_8dgz12 +1 -1
- package/packages/scrabble-solver/.next/cache/webpack/client-production/0.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/client-production/index.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/client-production/index.pack.old +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/0.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/index.pack.old +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/server-production/0.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/server-production/index.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/server-production/index.pack.old +0 -0
- package/packages/scrabble-solver/.next/prerender-manifest.js +1 -1
- package/packages/scrabble-solver/.next/prerender-manifest.json +1 -1
- package/packages/scrabble-solver/.next/routes-manifest.json +1 -1
- package/packages/scrabble-solver/.next/server/chunks/807.js +1 -1
- package/packages/scrabble-solver/.next/server/middleware-build-manifest.js +1 -1
- package/packages/scrabble-solver/.next/server/pages/404.html +1 -1
- package/packages/scrabble-solver/.next/server/pages/500.html +1 -1
- package/packages/scrabble-solver/.next/server/pages/api/solve.js +1 -1
- package/packages/scrabble-solver/.next/server/pages/index.html +1 -1
- package/packages/scrabble-solver/.next/server/pages/index.js +1 -1
- package/packages/scrabble-solver/.next/server/pages/index.json +1 -1
- package/packages/scrabble-solver/.next/server/pages-manifest.json +1 -1
- package/packages/scrabble-solver/.next/static/chunks/{main-b5b360c6afb66b05.js → main-8b0b4e610892a916.js} +1 -1
- package/packages/scrabble-solver/.next/static/chunks/pages/{404-0c9f3e0f8b15f487.js → 404-b0c2ccded2455be0.js} +1 -1
- package/packages/scrabble-solver/.next/static/chunks/pages/_app-42ce6b4032e931ff.js +17 -0
- package/packages/scrabble-solver/.next/static/chunks/pages/index-3718075f2ba2220c.js +1 -0
- package/packages/scrabble-solver/.next/static/chunks/webpack-c4acd79e87956a0e.js +1 -0
- package/packages/scrabble-solver/.next/static/css/2adc9736d823979b.css +2 -0
- package/packages/scrabble-solver/.next/static/{N8hSsS6Ppzlj3ebHMSZvI → qwJjm2FeDHHGY92CY5oQQ}/_buildManifest.js +1 -1
- package/packages/scrabble-solver/.next/trace +45 -45
- package/packages/scrabble-solver/package-lock.json +6 -6
- package/packages/scrabble-solver/package.json +12 -12
- package/packages/scrabble-solver/public/service-worker.js +1 -1
- package/packages/scrabble-solver/src/components/Board/Board.module.scss +3 -9
- package/packages/scrabble-solver/src/components/Board/Board.tsx +2 -2
- package/packages/scrabble-solver/src/components/Board/BoardPure.tsx +3 -2
- package/packages/scrabble-solver/src/components/Board/components/ToggleDirectionButton/ToggleDirectionButton.tsx +2 -0
- package/packages/scrabble-solver/src/components/Board/hooks/useBackgroundImage.tsx +2 -6
- package/packages/scrabble-solver/src/components/Board/hooks/useBoardStyle.ts +10 -4
- package/packages/scrabble-solver/src/components/Dictionary/Dictionary.module.scss +10 -7
- package/packages/scrabble-solver/src/components/Dictionary/Dictionary.tsx +38 -36
- package/packages/scrabble-solver/src/components/Loading/Loading.module.scss +1 -0
- package/packages/scrabble-solver/src/components/Loading/Loading.tsx +1 -1
- package/packages/scrabble-solver/src/components/Modal/components/Section/Section.tsx +3 -2
- package/packages/scrabble-solver/src/components/NavButtons/NavButtons.tsx +1 -0
- package/packages/scrabble-solver/src/components/Rack/Rack.tsx +1 -0
- package/packages/scrabble-solver/src/components/Results/Cell.tsx +7 -3
- package/packages/scrabble-solver/src/components/Results/Header.tsx +99 -0
- package/packages/scrabble-solver/src/components/Results/HeaderButton.tsx +18 -13
- package/packages/scrabble-solver/src/components/Results/Result.tsx +23 -16
- package/packages/scrabble-solver/src/components/Results/Results.module.scss +24 -12
- package/packages/scrabble-solver/src/components/Results/Results.tsx +3 -9
- package/packages/scrabble-solver/src/components/Results/types.ts +0 -8
- package/packages/scrabble-solver/src/components/Solver/Solver.tsx +1 -1
- package/packages/scrabble-solver/src/components/Tile/TilePure.tsx +1 -0
- package/packages/scrabble-solver/src/hooks/index.ts +1 -0
- package/packages/scrabble-solver/src/hooks/useAppLayout.ts +12 -1
- package/packages/scrabble-solver/src/hooks/useColumns.ts +47 -0
- package/packages/scrabble-solver/src/icons/GeoAlt.svg +5 -0
- package/packages/scrabble-solver/src/icons/OneTwoThree.svg +4 -0
- package/packages/scrabble-solver/src/icons/SquareA.svg +6 -0
- package/packages/scrabble-solver/src/icons/SquareB.svg +6 -0
- package/packages/scrabble-solver/src/icons/Squares.svg +34 -0
- package/packages/scrabble-solver/src/icons/Words.svg +22 -0
- package/packages/scrabble-solver/src/icons/index.ts +6 -0
- package/packages/scrabble-solver/src/lib/groupResults.ts +1 -1
- package/packages/scrabble-solver/src/lib/index.ts +0 -1
- package/packages/scrabble-solver/src/lib/sortResults.ts +10 -10
- package/packages/scrabble-solver/src/modals/KeyMapModal/KeyMapModal.tsx +8 -9
- package/packages/scrabble-solver/src/modals/RemainingTilesModal/RemainingTilesModal.tsx +1 -0
- package/packages/scrabble-solver/src/modals/SettingsModal/SettingsModal.tsx +5 -5
- package/packages/scrabble-solver/src/modals/WordsModal/WordsModal.tsx +2 -0
- package/packages/scrabble-solver/src/parameters/index.ts +12 -0
- package/packages/scrabble-solver/src/state/selectors.ts +26 -1
- package/packages/scrabble-solver/src/state/slices/resultsInitialState.ts +2 -2
- package/packages/scrabble-solver/src/state/slices/resultsSlice.ts +2 -2
- package/packages/scrabble-solver/src/state/useTranslate.ts +5 -1
- package/packages/scrabble-solver/src/styles/variables.scss +1 -0
- package/packages/scrabble-solver/src/types/index.ts +11 -2
- package/packages/solver/package-lock.json +2 -2
- package/packages/solver/package.json +5 -5
- package/packages/types/package.json +2 -2
- package/packages/word-definitions/build/lib/request.d.ts +0 -1
- package/packages/word-definitions/package-lock.json +2 -2
- package/packages/word-definitions/package.json +2 -2
- package/packages/word-lists/package-lock.json +2 -2
- package/packages/word-lists/package.json +2 -2
- package/tsconfig.jest.json +2 -1
- package/.github/workflows/test.yml +0 -28
- package/packages/scrabble-solver/.next/static/chunks/pages/_app-8246f5b39b6a5e59.js +0 -17
- package/packages/scrabble-solver/.next/static/chunks/pages/index-65bfe83d121535ab.js +0 -1
- package/packages/scrabble-solver/.next/static/chunks/webpack-6ef43a8d4a395f49.js +0 -1
- package/packages/scrabble-solver/.next/static/css/2f727b21d1331ea5.css +0 -2
- package/packages/scrabble-solver/src/components/Results/getCoordinatesColumn.ts +0 -14
- package/packages/scrabble-solver/src/components/Results/getLocaleColumns.ts +0 -58
- package/packages/scrabble-solver/src/components/Results/useColumns.ts +0 -44
- package/packages/scrabble-solver/src/lib/dataUrlToBlob.ts +0 -20
- /package/packages/scrabble-solver/.next/static/{N8hSsS6Ppzlj3ebHMSZvI → qwJjm2FeDHHGY92CY5oQQ}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!-- https://icons.getbootstrap.com/icons/square/ -->
|
|
2
|
+
<!-- https://icons.getbootstrap.com/icons/alphabet-uppercase/ -->
|
|
3
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 16 16">
|
|
4
|
+
<path
|
|
5
|
+
d="m 2.75,4 v 0.75 h 7.75 a 0.75,0.75 0 0 1 0.75,0.75 v 7.75 H 12 V 5.5 A 1.5,1.5 0 0 0 10.5,4 Z"
|
|
6
|
+
stroke-width="0.75" />
|
|
7
|
+
<path
|
|
8
|
+
d="m 12,14 h -0.75 v 0.5 a 0.75,0.75 0 0 1 -0.75,0.75 h -9 A 0.75,0.75 0 0 1 0.75,14.5 v -9 A 0.75,0.75 0 0 1 1.5,4.75 H 2 V 4 H 1.5 A 1.5,1.5 0 0 0 0,5.5 v 9 A 1.5,1.5 0 0 0 1.5,16 h 9 A 1.5,1.5 0 0 0 12,14.5 Z"
|
|
9
|
+
stroke-width="0.75" />
|
|
10
|
+
<path
|
|
11
|
+
d="M 2,4.75 H 2.75 V 4 H 2 Z"
|
|
12
|
+
stroke-width="0.75" />
|
|
13
|
+
<path
|
|
14
|
+
d="M 12,14 V 13.25 H 11.25 V 14 Z"
|
|
15
|
+
stroke-width="0.75" />
|
|
16
|
+
<path
|
|
17
|
+
d="m 4.75,2 v 0.75 h 7.75 a 0.75,0.75 0 0 1 0.75,0.75 v 7.75 H 14 V 3.5 A 1.5,1.5 0 0 0 12.5,2 Z"
|
|
18
|
+
stroke-width="0.75" />
|
|
19
|
+
<path
|
|
20
|
+
d="M 4,2.75 V 2 H 3.5 A 1.5,1.5 0 0 0 2,3.5 V 4 H 2.75 V 3.5 A 0.75,0.75 0 0 1 3.5,2.75 Z"
|
|
21
|
+
stroke-width="0.75" />
|
|
22
|
+
<path
|
|
23
|
+
d="m 14,12 h -0.75 v 0.5 A 0.75,0.75 0 0 1 12.5,13.25 H 12 V 14 h 0.5 A 1.5,1.5 0 0 0 14,12.5 Z"
|
|
24
|
+
stroke-width="0.75" />
|
|
25
|
+
<path
|
|
26
|
+
d="M 4,2.75 H 4.75 V 2 H 4 Z"
|
|
27
|
+
stroke-width="0.75" />
|
|
28
|
+
<path
|
|
29
|
+
d="M 14,12 V 11.25 H 13.25 V 12 Z"
|
|
30
|
+
stroke-width="0.75" />
|
|
31
|
+
<path
|
|
32
|
+
d="M 5.5,0 A 1.5,1.5 0 0 0 4,1.5 V 2 H 4.75 V 1.5 A 0.75,0.75 0 0 1 5.5,0.75 h 9 a 0.75,0.75 0 0 1 0.75,0.75 v 9 A 0.75,0.75 0 0 1 14.5,11.25 H 14 V 12 h 0.5 A 1.5,1.5 0 0 0 16,10.5 v -9 A 1.5,1.5 0 0 0 14.5,0 Z"
|
|
33
|
+
stroke-width="0.75" />
|
|
34
|
+
</svg>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<!-- https://icons.getbootstrap.com/icons/square/ -->
|
|
2
|
+
<!-- https://icons.getbootstrap.com/icons/alphabet-uppercase/ -->
|
|
3
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 16 16">
|
|
4
|
+
<path
|
|
5
|
+
d="M 7.21875,0.51562499 A 0.51562499,0.51562499 0 0 1 7.734375,1.03125 v 6.1875 A 0.51562499,0.51562499 0 0 1 7.21875,7.734375 H 1.03125 A 0.51562499,0.51562499 0 0 1 0.51562499,7.21875 V 1.03125 A 0.51562499,0.51562499 0 0 1 1.03125,0.51562499 Z M 1.03125,0 A 1.03125,1.03125 0 0 0 0,1.03125 v 6.1875 A 1.03125,1.03125 0 0 0 1.03125,8.25 h 6.1875 A 1.03125,1.03125 0 0 0 8.25,7.21875 V 1.03125 A 1.03125,1.03125 0 0 0 7.21875,0 Z"
|
|
6
|
+
stroke-width="0.5" />
|
|
7
|
+
<path
|
|
8
|
+
d="m 14.96875,8.265625 a 0.51562499,0.51562499 0 0 1 0.515625,0.515625 v 6.1875 A 0.51562499,0.51562499 0 0 1 14.96875,15.484375 H 8.7812501 A 0.51562499,0.51562499 0 0 1 8.265625,14.96875 V 8.78125 A 0.51562499,0.51562499 0 0 1 8.7812501,8.265625 Z M 8.7812501,7.75 A 1.03125,1.03125 0 0 0 7.75,8.78125 v 6.1875 A 1.03125,1.03125 0 0 0 8.7812501,16 H 14.96875 A 1.03125,1.03125 0 0 0 16,14.96875 V 8.78125 A 1.03125,1.03125 0 0 0 14.96875,7.75 Z"
|
|
9
|
+
stroke-width="0.5" />
|
|
10
|
+
<path
|
|
11
|
+
d="M 3.7614277,2.5 2.7009247,5.75 H 3.3333995 L 3.5811523,4.9136776 H 4.6366198 L 4.8833654,5.75 H 5.5490753 L 4.493608,2.5 Z m 0.3343657,0.6224265 h 0.0282 L 4.5107288,4.4362133 H 3.7090572 Z"
|
|
12
|
+
stroke-width="0.5" />
|
|
13
|
+
<path
|
|
14
|
+
d="m 2.954049,10.250001 v 3.25 h 1.275448 c 0.621526,0 1.066454,-0.335617 1.066454,-0.916407 0,-0.488403 -0.314632,-0.754324 -0.682648,-0.792732 v -0.0294 c 0.303013,-0.07889 0.525414,-0.316137 0.525414,-0.711635 0,-0.497226 -0.359314,-0.799828 -0.904337,-0.799828 z m 0.60159,0.483546 h 0.537133 c 0.285012,0 0.448262,0.161062 0.448262,0.425765 0,0.282869 -0.17897,0.442997 -0.584987,0.442997 H 3.555639 Z m 0,1.316828 h 0.57522 c 0.356516,0 0.547877,0.187953 0.547877,0.494698 0,0.309859 -0.196385,0.471382 -0.671906,0.471382 H 3.555639 Z"
|
|
15
|
+
stroke-width="0.5" />
|
|
16
|
+
<path
|
|
17
|
+
d="M 7.21875,8.265625 A 0.51562499,0.51562499 0 0 1 7.734375,8.78125 v 6.1875 A 0.51562499,0.51562499 0 0 1 7.21875,15.484375 H 1.03125 A 0.51562499,0.51562499 0 0 1 0.515625,14.96875 V 8.78125 A 0.51562499,0.51562499 0 0 1 1.03125,8.265625 Z M 1.03125,7.75 A 1.03125,1.03125 0 0 0 0,8.78125 v 6.1875 A 1.03125,1.03125 0 0 0 1.03125,16 h 6.1875 A 1.03125,1.03125 0 0 0 8.25,14.96875 V 8.78125 A 1.03125,1.03125 0 0 0 7.21875,7.75 Z"
|
|
18
|
+
stroke-width="0.5" />
|
|
19
|
+
<path
|
|
20
|
+
d="m 11.92041,10.250001 c -0.819499,0 -1.287109,0.548047 -1.287109,1.435547 v 0.389648 c 0,0.887999 0.46311,1.424805 1.287109,1.424805 0.6715,0 1.167289,-0.413243 1.196289,-1.010742 v -0.06055 h -0.585937 c -0.0245,0.320999 -0.253946,0.547851 -0.606446,0.547851 -0.428499,0 -0.672851,-0.323367 -0.672851,-0.901367 v -0.386719 c 0,-0.579999 0.248352,-0.915039 0.672851,-0.915039 0.348,0 0.581446,0.244649 0.606446,0.577149 h 0.585937 v -0.05664 c -0.0265,-0.618999 -0.522789,-1.043945 -1.196289,-1.043945 z"
|
|
21
|
+
stroke-width="0.5" />
|
|
22
|
+
</svg>
|
|
@@ -28,15 +28,21 @@ export { default as FlagGb } from './FlagGb.svg';
|
|
|
28
28
|
export { default as FlagPl } from './FlagPl.svg';
|
|
29
29
|
export { default as FlagRo } from './FlagRo.svg';
|
|
30
30
|
export { default as FlagUs } from './FlagUs.svg';
|
|
31
|
+
export { default as GeoAlt } from './GeoAlt.svg';
|
|
31
32
|
export { default as Github } from './Github.svg';
|
|
32
33
|
export { default as InfoCircleFill } from './InfoCircleFill.svg';
|
|
33
34
|
export { default as Keyboard } from './Keyboard.svg';
|
|
34
35
|
export { default as KeyboardFill } from './KeyboardFill.svg';
|
|
35
36
|
export { default as List } from './List.svg';
|
|
37
|
+
export { default as OneTwoThree } from './OneTwoThree.svg';
|
|
36
38
|
export { default as Sack } from './Sack.svg';
|
|
37
39
|
export { default as Search } from './Search.svg';
|
|
38
40
|
export { default as SortDown } from './SortDown.svg';
|
|
39
41
|
export { default as SortUp } from './SortUp.svg';
|
|
40
42
|
export { default as Square } from './Square.svg';
|
|
43
|
+
export { default as SquareA } from './SquareA.svg';
|
|
44
|
+
export { default as SquareB } from './SquareB.svg';
|
|
41
45
|
export { default as SquareFill } from './SquareFill.svg';
|
|
46
|
+
export { default as Squares } from './Squares.svg';
|
|
42
47
|
export { default as Star } from './Star.svg';
|
|
48
|
+
export { default as Words } from './Words.svg';
|
|
@@ -18,7 +18,7 @@ const groupResults = (
|
|
|
18
18
|
|
|
19
19
|
const { matching, other } = results.reduce<GroupedResults>(
|
|
20
20
|
(groupedResults, result) => {
|
|
21
|
-
const matchesQuery = () =>
|
|
21
|
+
const matchesQuery = () => Boolean(result.word.match(regExp));
|
|
22
22
|
|
|
23
23
|
if (resultMatchesCellFilter(result, cellFilter) && matchesQuery()) {
|
|
24
24
|
groupedResults.matching.push(result);
|
|
@@ -7,7 +7,6 @@ export { default as createKeyboardNavigation } from './createKeyboardNavigation'
|
|
|
7
7
|
export { default as createNullMovingComparator } from './createNullMovingComparator';
|
|
8
8
|
export { default as createRegExp } from './createRegExp';
|
|
9
9
|
export { default as createStringComparator } from './createStringComparator';
|
|
10
|
-
export { default as dataUrlToBlob } from './dataUrlToBlob';
|
|
11
10
|
export { default as detectLocale } from './detectLocale';
|
|
12
11
|
export { default as extractCharacters } from './extractCharacters';
|
|
13
12
|
export { default as extractCharactersByCase } from './extractCharactersByCase';
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
import { Result, ShowCoordinates } from '@scrabble-solver/types';
|
|
2
2
|
|
|
3
|
-
import { Comparator,
|
|
3
|
+
import { Comparator, ResultColumnId, Sort, SortDirection } from 'types';
|
|
4
4
|
|
|
5
5
|
import createKeyComparator from './createKeyComparator';
|
|
6
6
|
import createStringComparator from './createStringComparator';
|
|
7
7
|
import getCoordinates from './getCoordinates';
|
|
8
8
|
import reverseComparator from './reverseComparator';
|
|
9
9
|
|
|
10
|
-
const comparators: Record<
|
|
11
|
-
[
|
|
12
|
-
[
|
|
13
|
-
[
|
|
10
|
+
const comparators: Record<ResultColumnId, (locale: string, showCoordinates: ShowCoordinates) => Comparator<Result>> = {
|
|
11
|
+
[ResultColumnId.BlanksCount]: (locale: string) => createKeyComparator('blanksCount', locale),
|
|
12
|
+
[ResultColumnId.ConsonantsCount]: (locale: string) => createKeyComparator('consonantsCount', locale),
|
|
13
|
+
[ResultColumnId.Coordinates]: (locale: string, showCoordinates: ShowCoordinates) => (a, b) => {
|
|
14
14
|
const stringComparator = createStringComparator(locale);
|
|
15
15
|
const aValue = getCoordinates(a, showCoordinates);
|
|
16
16
|
const bValue = getCoordinates(b, showCoordinates);
|
|
17
17
|
return stringComparator(aValue, bValue);
|
|
18
18
|
},
|
|
19
|
-
[
|
|
20
|
-
[
|
|
21
|
-
[
|
|
22
|
-
[
|
|
23
|
-
[
|
|
19
|
+
[ResultColumnId.Points]: (locale: string) => createKeyComparator('points', locale),
|
|
20
|
+
[ResultColumnId.TilesCount]: (locale: string) => createKeyComparator('tilesCount', locale),
|
|
21
|
+
[ResultColumnId.VowelsCount]: (locale: string) => createKeyComparator('vowelsCount', locale),
|
|
22
|
+
[ResultColumnId.Word]: (locale: string) => createKeyComparator('word', locale),
|
|
23
|
+
[ResultColumnId.WordsCount]: (locale: string) => createKeyComparator('wordsCount', locale),
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
const sortResults = (
|
|
@@ -17,7 +17,7 @@ const KeyMapModal: FunctionComponent<Props> = ({ className, isOpen, onClose }) =
|
|
|
17
17
|
|
|
18
18
|
return (
|
|
19
19
|
<Modal className={className} isOpen={isOpen} title={translate('keyMap')} onClose={onClose}>
|
|
20
|
-
<Modal.Section title={translate('keyMap.board-and-rack')}>
|
|
20
|
+
<Modal.Section label={translate('keyMap.board-and-rack')} title={translate('keyMap.board-and-rack')}>
|
|
21
21
|
<Mapping description={translate('keyMap.board-and-rack.navigate')} mapping={[<Arrows key="arrows" />]} />
|
|
22
22
|
|
|
23
23
|
<Mapping
|
|
@@ -27,11 +27,6 @@ const KeyMapModal: FunctionComponent<Props> = ({ className, isOpen, onClose }) =
|
|
|
27
27
|
|
|
28
28
|
<Mapping description={translate('keyMap.board-and-rack.submit')} mapping={[<Enter key="del" />]} />
|
|
29
29
|
|
|
30
|
-
<Mapping
|
|
31
|
-
description={translate('keyMap.board.toggle-cell-filter')}
|
|
32
|
-
mapping={[[<Ctrl key="ctrl" />, <Key key="g">G</Key>]]}
|
|
33
|
-
/>
|
|
34
|
-
|
|
35
30
|
{config.twoCharacterTiles.length > 0 && (
|
|
36
31
|
<Mapping
|
|
37
32
|
description={translate('keyMap.board-and-rack.insert-two-letter-tile')}
|
|
@@ -49,12 +44,16 @@ const KeyMapModal: FunctionComponent<Props> = ({ className, isOpen, onClose }) =
|
|
|
49
44
|
)}
|
|
50
45
|
</Modal.Section>
|
|
51
46
|
|
|
52
|
-
<Modal.Section title={translate('keyMap.board')}>
|
|
53
|
-
<Mapping description={translate('keyMap.board.toggle-blank')} mapping={[<Space key="space" />]} />
|
|
47
|
+
<Modal.Section label={translate('keyMap.board')} title={translate('keyMap.board')}>
|
|
54
48
|
<Mapping description={translate('keyMap.board.toggle-direction')} mapping={[<Arrows key="arrows" />]} />
|
|
49
|
+
<Mapping description={translate('keyMap.board.toggle-blank')} mapping={[<Space key="space" />]} />
|
|
50
|
+
<Mapping
|
|
51
|
+
description={translate('keyMap.board.toggle-cell-filter')}
|
|
52
|
+
mapping={[[<Ctrl key="ctrl" />, <Key key="g">G</Key>]]}
|
|
53
|
+
/>
|
|
55
54
|
</Modal.Section>
|
|
56
55
|
|
|
57
|
-
<Modal.Section title={translate('keyMap.rack')}>
|
|
56
|
+
<Modal.Section label={translate('keyMap.rack')} title={translate('keyMap.rack')}>
|
|
58
57
|
<Mapping description={translate('keyMap.rack.insert-blank')} mapping={[<Space key="space" />]} />
|
|
59
58
|
</Modal.Section>
|
|
60
59
|
</Modal>
|
|
@@ -24,25 +24,25 @@ const SettingsModal: FunctionComponent<Props> = ({ className, isOpen, onClose })
|
|
|
24
24
|
|
|
25
25
|
return (
|
|
26
26
|
<Modal className={className} isOpen={isOpen} title={translate('settings')} onClose={onClose}>
|
|
27
|
-
<Modal.Section title={translate('settings.game')}>
|
|
27
|
+
<Modal.Section label={translate('settings.game')} title={translate('settings.game')}>
|
|
28
28
|
<ConfigSetting disabled={!isOpen} />
|
|
29
29
|
</Modal.Section>
|
|
30
30
|
|
|
31
|
-
<Modal.Section title={translate('settings.language')}>
|
|
31
|
+
<Modal.Section label={translate('settings.language')} title={translate('settings.language')}>
|
|
32
32
|
<LocaleSetting disabled={!isOpen} />
|
|
33
33
|
</Modal.Section>
|
|
34
34
|
|
|
35
|
-
<Modal.Section title={translate('settings.showCoordinates')}>
|
|
35
|
+
<Modal.Section label={translate('settings.showCoordinates')} title={translate('settings.showCoordinates')}>
|
|
36
36
|
<ShowCoordinatesSetting disabled={!isOpen} />
|
|
37
37
|
</Modal.Section>
|
|
38
38
|
|
|
39
39
|
{!isTouchDevice && (
|
|
40
|
-
<Modal.Section title={translate('settings.inputMode')}>
|
|
40
|
+
<Modal.Section label={translate('settings.inputMode')} title={translate('settings.inputMode')}>
|
|
41
41
|
<InputModeSetting disabled={!isOpen} />
|
|
42
42
|
</Modal.Section>
|
|
43
43
|
)}
|
|
44
44
|
|
|
45
|
-
<Modal.Section title={translate('settings.autoGroupTiles')}>
|
|
45
|
+
<Modal.Section label={translate('settings.autoGroupTiles')} title={translate('settings.autoGroupTiles')}>
|
|
46
46
|
<AutoGroupTilesSetting disabled={!isOpen} />
|
|
47
47
|
</Modal.Section>
|
|
48
48
|
</Modal>
|
|
@@ -21,6 +21,7 @@ const WordsModal: FunctionComponent<Props> = ({ className, isOpen, onClose }) =>
|
|
|
21
21
|
return (
|
|
22
22
|
<Modal className={className} isOpen={isOpen} title={translate('words')} onClose={onClose}>
|
|
23
23
|
<Modal.Section
|
|
24
|
+
label={translate('words.invalid')}
|
|
24
25
|
title={
|
|
25
26
|
<span className={styles.title}>
|
|
26
27
|
<span>{translate('words.invalid')}</span>
|
|
@@ -36,6 +37,7 @@ const WordsModal: FunctionComponent<Props> = ({ className, isOpen, onClose }) =>
|
|
|
36
37
|
</Modal.Section>
|
|
37
38
|
|
|
38
39
|
<Modal.Section
|
|
40
|
+
label={translate('words.valid')}
|
|
39
41
|
title={
|
|
40
42
|
<span className={styles.title}>
|
|
41
43
|
<span>{translate('words.valid')}</span>
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ResultColumnId } from 'types';
|
|
2
|
+
|
|
1
3
|
export const BREAKPOINTS = {
|
|
2
4
|
xs: 480,
|
|
3
5
|
s: 768,
|
|
@@ -120,6 +122,16 @@ export const RACK_TILE_SIZE_MAX = 80;
|
|
|
120
122
|
|
|
121
123
|
export const REMAINING_TILES_TILE_SIZE = 50;
|
|
122
124
|
|
|
125
|
+
export const RESULTS_COLUMN_WIDTH: Record<ResultColumnId, number | undefined> = {
|
|
126
|
+
[ResultColumnId.BlanksCount]: 55,
|
|
127
|
+
[ResultColumnId.ConsonantsCount]: 55,
|
|
128
|
+
[ResultColumnId.Coordinates]: 55,
|
|
129
|
+
[ResultColumnId.Points]: 80,
|
|
130
|
+
[ResultColumnId.TilesCount]: 55,
|
|
131
|
+
[ResultColumnId.VowelsCount]: 55,
|
|
132
|
+
[ResultColumnId.Word]: undefined,
|
|
133
|
+
[ResultColumnId.WordsCount]: 55,
|
|
134
|
+
};
|
|
123
135
|
export const RESULTS_ITEM_HEIGHT = 40;
|
|
124
136
|
|
|
125
137
|
export const RESULTS_HEADER_HEIGHT = RESULTS_ITEM_HEIGHT;
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
sortGroupedResults,
|
|
17
17
|
unorderedArraysEqual,
|
|
18
18
|
} from 'lib';
|
|
19
|
-
import { Point, Translations } from 'types';
|
|
19
|
+
import { Point, ResultColumnId, Translations } from 'types';
|
|
20
20
|
|
|
21
21
|
import { RootState } from './types';
|
|
22
22
|
|
|
@@ -231,3 +231,28 @@ export const selectVerify = selectVerifyRoot;
|
|
|
231
231
|
export const selectHasInvalidWords = createSelector([selectVerify], ({ invalidWords }) => {
|
|
232
232
|
return invalidWords.length > 0;
|
|
233
233
|
});
|
|
234
|
+
|
|
235
|
+
export const selectColumns = createSelector([selectLocale, selectShowCoordinates], (locale, showCoordinates) => {
|
|
236
|
+
const { consonants, vowels } = LOCALE_FEATURES[locale];
|
|
237
|
+
const columns: ResultColumnId[] = [
|
|
238
|
+
ResultColumnId.Word,
|
|
239
|
+
ResultColumnId.TilesCount,
|
|
240
|
+
ResultColumnId.BlanksCount,
|
|
241
|
+
ResultColumnId.WordsCount,
|
|
242
|
+
ResultColumnId.Points,
|
|
243
|
+
];
|
|
244
|
+
|
|
245
|
+
if (showCoordinates !== 'hidden') {
|
|
246
|
+
columns.push(ResultColumnId.Coordinates);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (vowels) {
|
|
250
|
+
columns.push(ResultColumnId.VowelsCount);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (consonants) {
|
|
254
|
+
columns.push(ResultColumnId.ConsonantsCount);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return columns;
|
|
258
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Result } from '@scrabble-solver/types';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { ResultColumnId, Sort, SortDirection } from 'types';
|
|
4
4
|
|
|
5
5
|
export interface ResultsState {
|
|
6
6
|
candidate: Result | null;
|
|
@@ -14,7 +14,7 @@ const resultsInitialState: ResultsState = {
|
|
|
14
14
|
query: '',
|
|
15
15
|
results: undefined,
|
|
16
16
|
sort: {
|
|
17
|
-
column:
|
|
17
|
+
column: ResultColumnId.Points,
|
|
18
18
|
direction: SortDirection.Descending,
|
|
19
19
|
},
|
|
20
20
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
|
2
2
|
import { Result } from '@scrabble-solver/types';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { ResultColumnId, SortDirection } from 'types';
|
|
5
5
|
|
|
6
6
|
import resultsInitialState from './resultsInitialState';
|
|
7
7
|
|
|
@@ -37,7 +37,7 @@ const resultsSlice = createSlice({
|
|
|
37
37
|
};
|
|
38
38
|
},
|
|
39
39
|
|
|
40
|
-
sort: (state, action: PayloadAction<
|
|
40
|
+
sort: (state, action: PayloadAction<ResultColumnId>) => {
|
|
41
41
|
const columndId = action.payload;
|
|
42
42
|
const { column, direction } = state.sort;
|
|
43
43
|
|
|
@@ -9,13 +9,17 @@ const useTranslate = (): Translate => {
|
|
|
9
9
|
const translations = useTypedSelector(selectTranslations);
|
|
10
10
|
const locale = useTypedSelector(selectLocale);
|
|
11
11
|
const translate: Translate = useCallback(
|
|
12
|
-
(id, replacements
|
|
12
|
+
(id, replacements) => {
|
|
13
13
|
const translation = translations[id];
|
|
14
14
|
|
|
15
15
|
if (typeof translation === 'undefined') {
|
|
16
16
|
throw new Error(`Untranslated key "${id}" in locale "${locale}"`);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
if (!replacements) {
|
|
20
|
+
return translation;
|
|
21
|
+
}
|
|
22
|
+
|
|
19
23
|
return Object.entries(replacements).reduce(
|
|
20
24
|
(result, [key, value]) => result.replaceAll(`{{${key}}}`, value),
|
|
21
25
|
translation,
|
|
@@ -106,6 +106,7 @@ $easeOutSine: cubic-bezier(0.61, 1, 0.88, 1);
|
|
|
106
106
|
--modal--width: 370px;
|
|
107
107
|
--nav--height: calc(var(--logo--height) + var(--nav--padding));
|
|
108
108
|
--nav--padding: var(--spacing--l);
|
|
109
|
+
--results--icon--size: 18px;
|
|
109
110
|
--results--item--height: 40px;
|
|
110
111
|
--solver-column--width: 580px;
|
|
111
112
|
--square-button--size: 32px;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Result } from '@scrabble-solver/types';
|
|
2
|
+
import { FunctionComponent, SVGAttributes } from 'react';
|
|
2
3
|
|
|
3
4
|
export type Comparator<T> = (a: T, B: T) => number;
|
|
4
5
|
|
|
@@ -24,7 +25,7 @@ export interface Point {
|
|
|
24
25
|
export type Rack = (string | null)[];
|
|
25
26
|
|
|
26
27
|
export interface Sort {
|
|
27
|
-
column:
|
|
28
|
+
column: ResultColumnId;
|
|
28
29
|
direction: SortDirection;
|
|
29
30
|
}
|
|
30
31
|
|
|
@@ -47,7 +48,7 @@ export interface RemainingTilesGroup {
|
|
|
47
48
|
totalCount: number;
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
export enum
|
|
51
|
+
export enum ResultColumnId {
|
|
51
52
|
BlanksCount = 'blanks-count',
|
|
52
53
|
ConsonantsCount = 'consonants-count',
|
|
53
54
|
Coordinates = 'coordinates',
|
|
@@ -58,6 +59,14 @@ export enum ResultColumn {
|
|
|
58
59
|
WordsCount = 'words-count',
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
export interface ResultColumn {
|
|
63
|
+
className: string;
|
|
64
|
+
Icon?: FunctionComponent<SVGAttributes<SVGElement>>;
|
|
65
|
+
id: ResultColumnId;
|
|
66
|
+
translationKey: TranslationKey;
|
|
67
|
+
width?: number;
|
|
68
|
+
}
|
|
69
|
+
|
|
61
70
|
export interface GroupedResults {
|
|
62
71
|
matching: Result[];
|
|
63
72
|
other: Result[];
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrabble-solver/solver",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.13",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@scrabble-solver/solver",
|
|
9
|
-
"version": "2.13.
|
|
9
|
+
"version": "2.13.13",
|
|
10
10
|
"license": "CC-BY-NC-ND-4.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@kamilmielnik/trie": "^3.0.0"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrabble-solver/solver",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.13",
|
|
4
4
|
"description": "Scrabble Solver 2 - Solver",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@kamilmielnik/trie": "^3.0.0",
|
|
27
|
-
"@scrabble-solver/types": "^2.13.
|
|
27
|
+
"@scrabble-solver/types": "^2.13.13"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@scrabble-solver/configs": "^2.13.
|
|
31
|
-
"@scrabble-solver/constants": "^2.13.
|
|
32
|
-
"@scrabble-solver/dictionaries": "^2.13.
|
|
30
|
+
"@scrabble-solver/configs": "^2.13.13",
|
|
31
|
+
"@scrabble-solver/constants": "^2.13.13",
|
|
32
|
+
"@scrabble-solver/dictionaries": "^2.13.13"
|
|
33
33
|
},
|
|
34
34
|
"gitHead": "1e2d1ad49a288d4a44196d8e3336740da132c637"
|
|
35
35
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrabble-solver/types",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.13",
|
|
4
4
|
"description": "Scrabble Solver 2 - Types",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"clean": "rimraf build/"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@scrabble-solver/constants": "^2.13.
|
|
26
|
+
"@scrabble-solver/constants": "^2.13.13"
|
|
27
27
|
},
|
|
28
28
|
"gitHead": "1e2d1ad49a288d4a44196d8e3336740da132c637"
|
|
29
29
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrabble-solver/word-definitions",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.13",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@scrabble-solver/word-definitions",
|
|
9
|
-
"version": "2.13.
|
|
9
|
+
"version": "2.13.13",
|
|
10
10
|
"license": "CC-BY-NC-ND-4.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"cheerio": "^1.0.0-rc.12",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrabble-solver/word-definitions",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.13",
|
|
4
4
|
"description": "Scrabble Solver 2 - Word definitions",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"clean": "rimraf build/"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@scrabble-solver/types": "^2.13.
|
|
26
|
+
"@scrabble-solver/types": "^2.13.13",
|
|
27
27
|
"cheerio": "^1.0.0-rc.12",
|
|
28
28
|
"follow-redirects": "^1.15.6",
|
|
29
29
|
"striptags": "^3.2.0"
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrabble-solver/word-lists",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.13",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@scrabble-solver/word-lists",
|
|
9
|
-
"version": "2.13.
|
|
9
|
+
"version": "2.13.13",
|
|
10
10
|
"license": "CC-BY-NC-ND-4.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"cheerio": "^1.0.0-rc.12",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrabble-solver/word-lists",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.13",
|
|
4
4
|
"description": "Scrabble Solver 2 - Word lists",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"clean": "rimraf build/"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@scrabble-solver/types": "^2.13.
|
|
26
|
+
"@scrabble-solver/types": "^2.13.13",
|
|
27
27
|
"cheerio": "^1.0.0-rc.12",
|
|
28
28
|
"follow-redirects": "^1.15.6",
|
|
29
29
|
"latinize": "^1.0.0",
|
package/tsconfig.jest.json
CHANGED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
name: Test
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [master]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [master]
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
build:
|
|
11
|
-
|
|
12
|
-
runs-on: ubuntu-latest
|
|
13
|
-
|
|
14
|
-
strategy:
|
|
15
|
-
matrix:
|
|
16
|
-
node-version: [20.x]
|
|
17
|
-
|
|
18
|
-
steps:
|
|
19
|
-
- uses: actions/checkout@v2
|
|
20
|
-
- name: Use Node.js ${{ matrix.node-version }}
|
|
21
|
-
uses: actions/setup-node@v1
|
|
22
|
-
with:
|
|
23
|
-
node-version: ${{ matrix.node-version }}
|
|
24
|
-
- run: npm ci
|
|
25
|
-
- run: npm run build
|
|
26
|
-
- run: npm run test
|
|
27
|
-
env:
|
|
28
|
-
CI: true
|