@scrabble-solver/scrabble-solver 2.13.9 → 2.13.11
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 +6 -6
- package/.next/cache/.tsbuildinfo +1 -1
- package/.next/cache/eslint/.cache_8dgz12 +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/edge-server-production/0.pack +0 -0
- package/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/.next/cache/webpack/server-production/0.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack +0 -0
- package/.next/prerender-manifest.js +1 -1
- package/.next/prerender-manifest.json +1 -1
- package/.next/routes-manifest.json +1 -1
- package/.next/server/chunks/807.js +1 -1
- package/.next/server/chunks/911.js +1 -1
- package/.next/server/chunks/977.js +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/pages/_app.js +1 -1
- package/.next/server/pages/_error.js +1 -1
- package/.next/server/pages/api/dictionary/[locale]/[word].js +1 -1
- package/.next/server/pages/api/solve.js +1 -1
- package/.next/server/pages/api/verify.js +1 -1
- package/.next/server/pages/index.html +1 -1
- package/.next/server/pages/index.js +1 -1
- package/.next/server/pages/index.json +1 -1
- package/.next/static/{eLvYNd4B2hzSgBZ_PuZcQ → 5T-kyZzpLLGYA9Qzg0-Sn}/_buildManifest.js +1 -1
- package/.next/static/chunks/pages/{404-01653a877b233143.js → 404-0c9f3e0f8b15f487.js} +1 -1
- package/.next/static/chunks/pages/_app-264cd7dc7c7b5cc2.js +17 -0
- package/.next/static/chunks/pages/index-65bfe83d121535ab.js +1 -0
- package/.next/static/css/{841a5b5f0b2fb131.css → 2f727b21d1331ea5.css} +2 -2
- package/.next/trace +45 -44
- package/package.json +10 -9
- package/src/api/isBoardValid.ts +1 -1
- package/src/api/isCellValid.ts +2 -2
- package/src/api/isRowValid.ts +1 -1
- package/src/components/Board/components/Actions/Actions.tsx +15 -3
- package/src/components/Board/components/Cell/Cell.tsx +1 -1
- package/src/components/Board/components/ToggleDirectionButton/ToggleDirectionButton.tsx +9 -2
- package/src/components/Board/hooks/useBackgroundImage.tsx +3 -3
- package/src/components/Board/hooks/useBoardStyle.ts +3 -5
- package/src/components/Board/hooks/useGrid.ts +13 -9
- package/src/components/Key/Key.module.scss +3 -2
- package/src/components/Keys/Arrows/Arrows.module.scss +41 -0
- package/src/components/Keys/Arrows/Arrows.tsx +31 -0
- package/src/components/Keys/Arrows/index.ts +1 -0
- package/src/components/Keys/index.ts +1 -0
- package/src/components/Rack/components/InputPrompt/InputPrompt.tsx +1 -1
- package/src/components/Results/HeaderButton.tsx +3 -6
- package/src/components/Results/Results.module.scss +2 -6
- package/src/components/Results/Results.tsx +6 -2
- package/src/components/Results/getCoordinatesColumn.ts +0 -1
- package/src/components/Results/getLocaleColumns.ts +0 -7
- package/src/components/Results/types.ts +0 -1
- package/src/components/index.ts +2 -0
- package/src/components/keys.tsx +26 -0
- package/src/hooks/useAppLayout.ts +8 -8
- package/src/i18n/languages/english.json +4 -2
- package/src/i18n/languages/french.json +4 -2
- package/src/i18n/languages/german.json +4 -2
- package/src/i18n/languages/persian.json +4 -2
- package/src/i18n/languages/polish.json +4 -2
- package/src/i18n/languages/romanian.json +3 -1
- package/src/i18n/languages/spanish.json +4 -2
- package/src/lib/getCellSize.ts +2 -2
- package/src/lib/groupResults.ts +4 -7
- package/src/lib/index.ts +1 -0
- package/src/lib/sortGroupedResults.ts +23 -0
- package/src/lib/sortResults.ts +17 -5
- package/src/modals/KeyMapModal/KeyMapModal.tsx +19 -9
- package/src/modals/SettingsModal/components/ShowCoordinatesSetting/ShowCoordinatesSetting.tsx +1 -1
- package/src/pages/api/dictionary/[locale]/[word].ts +1 -4
- package/src/state/sagas.ts +6 -6
- package/src/state/selectors.ts +8 -5
- package/src/state/slices/boardInitialState.ts +2 -2
- package/src/state/slices/boardSlice.ts +2 -2
- package/src/styles/variables.scss +2 -2
- package/src/types/index.ts +11 -1
- package/.next/static/chunks/pages/_app-735b5863675c1b5d.js +0 -17
- package/.next/static/chunks/pages/index-36c448d585a58425.js +0 -1
- package/src/modals/KeyMapModal/keys.tsx +0 -46
- /package/.next/static/{eLvYNd4B2hzSgBZ_PuZcQ → 5T-kyZzpLLGYA9Qzg0-Sn}/_ssgManifest.js +0 -0
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"cell.set-blank": "Marquer comme vide",
|
|
6
6
|
"cell.set-not-blank": "Marquer comme non vide",
|
|
7
7
|
"cell.tile.location": "Plateau: la case ({{x}}, {{y}})",
|
|
8
|
-
"
|
|
8
|
+
"common.arrows": "Touches fléchées",
|
|
9
9
|
"common.blanks": "Cases vides",
|
|
10
10
|
"common.clear": "Effacer",
|
|
11
11
|
"common.close": "Fermer",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"common.next": "Suivant",
|
|
15
15
|
"common.points": "Points",
|
|
16
16
|
"common.previous": "Précédent",
|
|
17
|
+
"common.space": "Barre d'espace",
|
|
17
18
|
"common.tiles": "Cases",
|
|
18
19
|
"common.two-letter-tiles": "Deux lettres",
|
|
19
20
|
"common.vowels": "Voyelles",
|
|
@@ -34,6 +35,7 @@
|
|
|
34
35
|
"keyMap": "Raccourcis clavier",
|
|
35
36
|
"keyMap.board": "Plateau",
|
|
36
37
|
"keyMap.board.toggle-blank": "Marqué/Démarqué la case en tant que vide",
|
|
38
|
+
"keyMap.board.toggle-cell-filter": "Basculer le filtre de destination",
|
|
37
39
|
"keyMap.board.toggle-direction": "Faire basculer la direction d'écriture",
|
|
38
40
|
"keyMap.board-and-rack": "Plateau & chevalet",
|
|
39
41
|
"keyMap.board-and-rack.insert-two-letter-tile": "Insérer une tuile de deux lettres",
|
|
@@ -41,7 +43,7 @@
|
|
|
41
43
|
"keyMap.board-and-rack.remove-tile": "Supprimer une case",
|
|
42
44
|
"keyMap.board-and-rack.submit": "Commencer la résolution",
|
|
43
45
|
"keyMap.rack": "Chevalet",
|
|
44
|
-
"keyMap.rack.insert-blank": "Inserer une case vide
|
|
46
|
+
"keyMap.rack.insert-blank": "Inserer une case vide",
|
|
45
47
|
"menu": "Menu",
|
|
46
48
|
"rack.placeholder": "Lettres",
|
|
47
49
|
"rack.tile.location": "Chevalet: la case ({{index}})",
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"cell.set-blank": "Als Blanko markieren",
|
|
6
6
|
"cell.set-not-blank": "Nicht als Blanko markieren",
|
|
7
7
|
"cell.tile.location": "Brett: Stein ({{x}}, {{y}})",
|
|
8
|
-
"
|
|
8
|
+
"common.arrows": "Pfeiltasten",
|
|
9
9
|
"common.blanks": "Blankos",
|
|
10
10
|
"common.clear": "Löschen",
|
|
11
11
|
"common.close": "Schließen",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"common.next": "Weiter",
|
|
15
15
|
"common.points": "Punkte",
|
|
16
16
|
"common.previous": "Zurück",
|
|
17
|
+
"common.space": "Leertaste",
|
|
17
18
|
"common.tiles": "Steine",
|
|
18
19
|
"common.two-letter-tiles": "Zwei-Buchstaben",
|
|
19
20
|
"common.vowels": "Vokale",
|
|
@@ -34,6 +35,7 @@
|
|
|
34
35
|
"keyMap": "Tastaturkürzel",
|
|
35
36
|
"keyMap.board": "Brett",
|
|
36
37
|
"keyMap.board.toggle-blank": "Als Blanko markieren / aufheben",
|
|
38
|
+
"keyMap.board.toggle-cell-filter": "Zielfilter umschalten",
|
|
37
39
|
"keyMap.board.toggle-direction": "Schreibrichtung umschalten",
|
|
38
40
|
"keyMap.board-and-rack": "Brett & Ablage",
|
|
39
41
|
"keyMap.board-and-rack.insert-two-letter-tile": "Zwei-Buchstaben Stein hinzufügen",
|
|
@@ -41,7 +43,7 @@
|
|
|
41
43
|
"keyMap.board-and-rack.remove-tile": "Stein entfernen",
|
|
42
44
|
"keyMap.board-and-rack.submit": "Lösen starten",
|
|
43
45
|
"keyMap.rack": "Ablage",
|
|
44
|
-
"keyMap.rack.insert-blank": "Blanko hinzufügen
|
|
46
|
+
"keyMap.rack.insert-blank": "Blanko hinzufügen",
|
|
45
47
|
"menu": "Menü",
|
|
46
48
|
"rack.placeholder": "Steine…",
|
|
47
49
|
"rack.tile.location": "Ablage: Stein ({{index}})",
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"cell.set-blank": "علامت گذاری به عنوان خالی",
|
|
6
6
|
"cell.set-not-blank": "علامت گذاری به عنوان غیر خالی",
|
|
7
7
|
"cell.tile.location": "({{x}}، {{y}}) کاشی: صفحه",
|
|
8
|
-
"
|
|
8
|
+
"common.arrows": "کلیدهای جهت دار",
|
|
9
9
|
"common.blanks": "خالی",
|
|
10
10
|
"common.clear": "پاک کردن",
|
|
11
11
|
"common.close": "بستن",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"common.next": "بعدی",
|
|
15
15
|
"common.points": "امتیازات",
|
|
16
16
|
"common.previous": "قبلی",
|
|
17
|
+
"common.space": "دکمه اسپیس",
|
|
17
18
|
"common.tiles": "کاشی ها",
|
|
18
19
|
"common.two-letter-tiles": "دو حرفی",
|
|
19
20
|
"common.vowels": "حروف مصوت",
|
|
@@ -34,6 +35,7 @@
|
|
|
34
35
|
"keyMap": "میانبر های کیبورد",
|
|
35
36
|
"keyMap.board": "صفحه",
|
|
36
37
|
"keyMap.board.toggle-blank": "علامت/عدم علامت گذاری کاشی به عنوان خالی",
|
|
38
|
+
"keyMap.board.toggle-cell-filter": "فیلتر هدف را تغییر دهید",
|
|
37
39
|
"keyMap.board.toggle-direction": "تغییر جهت تایپ",
|
|
38
40
|
"keyMap.board-and-rack": "صفحه و طاقچه",
|
|
39
41
|
"keyMap.board-and-rack.insert-two-letter-tile": "وارد کردن کاشی دو حرفی",
|
|
@@ -41,7 +43,7 @@
|
|
|
41
43
|
"keyMap.board-and-rack.remove-tile": "حذف کاشی",
|
|
42
44
|
"keyMap.board-and-rack.submit": "حل کردن",
|
|
43
45
|
"keyMap.rack": "طاقچه",
|
|
44
|
-
"keyMap.rack.insert-blank": "وارد کردن کاشی خالی
|
|
46
|
+
"keyMap.rack.insert-blank": "وارد کردن کاشی خالی",
|
|
45
47
|
"menu": "منو",
|
|
46
48
|
"rack.placeholder": "لیستحرف",
|
|
47
49
|
"rack.tile.location": "({{index}}) کاشی: طاقچه",
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"cell.set-blank": "Oznacz jako blank",
|
|
6
6
|
"cell.set-not-blank": "Oznacz jako nie blank",
|
|
7
7
|
"cell.tile.location": "Plansza: płytka ({{x}}, {{y}})",
|
|
8
|
-
"
|
|
8
|
+
"common.arrows": "Klawisze strzałek",
|
|
9
9
|
"common.blanks": "Blanki",
|
|
10
10
|
"common.clear": "Wyczyść",
|
|
11
11
|
"common.close": "Zamknij",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"common.next": "Następne",
|
|
15
15
|
"common.points": "Punkty",
|
|
16
16
|
"common.previous": "Poprzednie",
|
|
17
|
+
"common.space": "Spacja",
|
|
17
18
|
"common.tiles": "Płytki",
|
|
18
19
|
"common.two-letter-tiles": "Dwuliterowe",
|
|
19
20
|
"common.vowels": "Samogłoski",
|
|
@@ -34,6 +35,7 @@
|
|
|
34
35
|
"keyMap": "Skróty klawiszowe",
|
|
35
36
|
"keyMap.board": "Plansza",
|
|
36
37
|
"keyMap.board.toggle-blank": "Oznacz/odznacz płytkę jako blank",
|
|
38
|
+
"keyMap.board.toggle-cell-filter": "Zmień filtr miejsca docelowego",
|
|
37
39
|
"keyMap.board.toggle-direction": "Zmień kierunek wpisywania",
|
|
38
40
|
"keyMap.board-and-rack": "Plansza i stojak",
|
|
39
41
|
"keyMap.board-and-rack.insert-two-letter-tile": "Wstaw dwuliterową płytkę",
|
|
@@ -41,7 +43,7 @@
|
|
|
41
43
|
"keyMap.board-and-rack.remove-tile": "Zdejmij płytkę",
|
|
42
44
|
"keyMap.board-and-rack.submit": "Rozpocznij wyszukiwanie",
|
|
43
45
|
"keyMap.rack": "Stojak",
|
|
44
|
-
"keyMap.rack.insert-blank": "Wstaw blanka
|
|
46
|
+
"keyMap.rack.insert-blank": "Wstaw blanka",
|
|
45
47
|
"menu": "Menu",
|
|
46
48
|
"rack.placeholder": "Literki",
|
|
47
49
|
"rack.tile.location": "Stojak: płytka ({{index}})",
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"cell.set-blank": "Marcare camp liber",
|
|
6
6
|
"cell.set-not-blank": "Marcare camp ocupat ",
|
|
7
7
|
"cell.tile.location": "Tabla: camp ({{x}}, {{y}})",
|
|
8
|
-
"
|
|
8
|
+
"common.arrows": "Sagetile",
|
|
9
9
|
"common.blanks": "Jokeri",
|
|
10
10
|
"common.clear": "Stergere",
|
|
11
11
|
"common.close": "Inchidere",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"common.next": "Pasul urmator",
|
|
15
15
|
"common.points": "Puncte",
|
|
16
16
|
"common.previous": "Pasul anterior",
|
|
17
|
+
"common.space": "Bara de spațiu",
|
|
17
18
|
"common.tiles": "Litere",
|
|
18
19
|
"common.two-letter-tiles": "2 litere",
|
|
19
20
|
"common.vowels": "Vocale",
|
|
@@ -34,6 +35,7 @@
|
|
|
34
35
|
"keyMap": "Comanda rapida la tastatura",
|
|
35
36
|
"keyMap.board": "Tabla joc",
|
|
36
37
|
"keyMap.board.toggle-blank": "Marcheaza/Deselecteaza campul ca liber",
|
|
38
|
+
"keyMap.board.toggle-cell-filter": "Comutați filtrul țintă",
|
|
37
39
|
"keyMap.board.toggle-direction": "Schimbati directia de tastare",
|
|
38
40
|
"keyMap.board-and-rack": "Tabla si literele extrase",
|
|
39
41
|
"keyMap.board-and-rack.insert-two-letter-tile": "Introducere piesa 2 litere",
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"cell.set-blank": "Marcar como en blanco",
|
|
6
6
|
"cell.set-not-blank": "Marcar como no en blanco",
|
|
7
7
|
"cell.tile.location": "Tablero: espacio ({{x}}, {{y}})",
|
|
8
|
-
"
|
|
8
|
+
"common.arrows": "Teclas de flecha",
|
|
9
9
|
"common.blanks": "Blancos",
|
|
10
10
|
"common.clear": "Borrar",
|
|
11
11
|
"common.close": "Cerrar",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"common.next": "Siguiente",
|
|
15
15
|
"common.points": "Puntos",
|
|
16
16
|
"common.previous": "Anterior",
|
|
17
|
+
"common.space": "Barra espaciadora",
|
|
17
18
|
"common.tiles": "Longitud",
|
|
18
19
|
"common.two-letter-tiles": "Dos letras",
|
|
19
20
|
"common.vowels": "Vocales",
|
|
@@ -34,6 +35,7 @@
|
|
|
34
35
|
"keyMap": "Atajos de teclado",
|
|
35
36
|
"keyMap.board": "Tablero",
|
|
36
37
|
"keyMap.board.toggle-blank": "Marcar / desmarcar un espacio en blanco",
|
|
38
|
+
"keyMap.board.toggle-cell-filter": "Alternar filtro de destino",
|
|
37
39
|
"keyMap.board.toggle-direction": "Alternar dirección de escritura",
|
|
38
40
|
"keyMap.board-and-rack": "Tablero y estante",
|
|
39
41
|
"keyMap.board-and-rack.insert-two-letter-tile": "Insertar mosaico de dos letras",
|
|
@@ -41,7 +43,7 @@
|
|
|
41
43
|
"keyMap.board-and-rack.remove-tile": "Quitar Letra",
|
|
42
44
|
"keyMap.board-and-rack.submit": "Empezar a resolver",
|
|
43
45
|
"keyMap.rack": "Estante",
|
|
44
|
-
"keyMap.rack.insert-blank": "Insertar espacio en blanco
|
|
46
|
+
"keyMap.rack.insert-blank": "Insertar espacio en blanco",
|
|
45
47
|
"menu": "Menú",
|
|
46
48
|
"rack.placeholder": "Letras…",
|
|
47
49
|
"rack.tile.location": "Estante: espacio ({{index}})",
|
package/src/lib/getCellSize.ts
CHANGED
|
@@ -3,8 +3,8 @@ import { Config } from '@scrabble-solver/types';
|
|
|
3
3
|
import { BOARD_CELL_BORDER_WIDTH, BOARD_TILE_SIZE_MAX } from 'parameters';
|
|
4
4
|
|
|
5
5
|
const getCellSize = (config: Config, width: number, height: number): number => {
|
|
6
|
-
const maxWidth = (width - BOARD_CELL_BORDER_WIDTH) / config.
|
|
7
|
-
const maxHeight = (height - BOARD_CELL_BORDER_WIDTH) / config.
|
|
6
|
+
const maxWidth = (width - BOARD_CELL_BORDER_WIDTH) / config.boardSize - BOARD_CELL_BORDER_WIDTH;
|
|
7
|
+
const maxHeight = (height - BOARD_CELL_BORDER_WIDTH) / config.boardSize - BOARD_CELL_BORDER_WIDTH;
|
|
8
8
|
const cellSize = Math.min(maxWidth, maxHeight);
|
|
9
9
|
return Math.floor(Math.min(cellSize, BOARD_TILE_SIZE_MAX));
|
|
10
10
|
};
|
package/src/lib/groupResults.ts
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
import { Result } from '@scrabble-solver/types';
|
|
2
2
|
|
|
3
|
-
import { CellFilterEntry } from 'types';
|
|
3
|
+
import { CellFilterEntry, GroupedResults } from 'types';
|
|
4
4
|
|
|
5
5
|
import createRegExp from './createRegExp';
|
|
6
6
|
import resultMatchesCellFilter from './resultMatchesCellFilter';
|
|
7
7
|
|
|
8
|
-
interface GroupedResults {
|
|
9
|
-
matching: Result[];
|
|
10
|
-
other: Result[];
|
|
11
|
-
}
|
|
12
|
-
|
|
13
8
|
const groupResults = (
|
|
14
9
|
results: Result[] | undefined,
|
|
15
10
|
query: string,
|
|
@@ -21,7 +16,7 @@ const groupResults = (
|
|
|
21
16
|
|
|
22
17
|
const regExp = createRegExp(query);
|
|
23
18
|
|
|
24
|
-
|
|
19
|
+
const { matching, other } = results.reduce<GroupedResults>(
|
|
25
20
|
(groupedResults, result) => {
|
|
26
21
|
const matchesQuery = () => regExp.test(result.word);
|
|
27
22
|
|
|
@@ -35,6 +30,8 @@ const groupResults = (
|
|
|
35
30
|
},
|
|
36
31
|
{ matching: [], other: [] },
|
|
37
32
|
);
|
|
33
|
+
|
|
34
|
+
return { matching, other };
|
|
38
35
|
};
|
|
39
36
|
|
|
40
37
|
export default groupResults;
|
package/src/lib/index.ts
CHANGED
|
@@ -34,6 +34,7 @@ export { default as noop } from './noop';
|
|
|
34
34
|
export { default as numberComparator } from './numberComparator';
|
|
35
35
|
export { default as resultMatchesCellFilter } from './resultMatchesCellFilter';
|
|
36
36
|
export { default as reverseComparator } from './reverseComparator';
|
|
37
|
+
export { default as sortGroupedResults } from './sortGroupedResults';
|
|
37
38
|
export { default as sortResults } from './sortResults';
|
|
38
39
|
export { default as unorderedArraysEqual } from './unorderedArraysEqual';
|
|
39
40
|
export { default as zipCharactersAndTiles } from './zipCharactersAndTiles';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Locale, ShowCoordinates } from '@scrabble-solver/types';
|
|
2
|
+
|
|
3
|
+
import { GroupedResults, Sort } from 'types';
|
|
4
|
+
|
|
5
|
+
import sortResults from './sortResults';
|
|
6
|
+
|
|
7
|
+
const sortGroupedResults = (
|
|
8
|
+
results: GroupedResults | undefined,
|
|
9
|
+
sort: Sort,
|
|
10
|
+
locale: Locale,
|
|
11
|
+
showCoordinates: ShowCoordinates,
|
|
12
|
+
): GroupedResults | undefined => {
|
|
13
|
+
if (typeof results === 'undefined') {
|
|
14
|
+
return results;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
matching: sortResults(results.matching, sort, locale, showCoordinates) ?? [],
|
|
19
|
+
other: sortResults(results.other, sort, locale, showCoordinates) ?? [],
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default sortGroupedResults;
|
package/src/lib/sortResults.ts
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
|
-
import { Result } from '@scrabble-solver/types';
|
|
1
|
+
import { Result, ShowCoordinates } from '@scrabble-solver/types';
|
|
2
2
|
|
|
3
3
|
import { Comparator, ResultColumn, Sort, SortDirection } from 'types';
|
|
4
4
|
|
|
5
5
|
import createKeyComparator from './createKeyComparator';
|
|
6
|
+
import createStringComparator from './createStringComparator';
|
|
7
|
+
import getCoordinates from './getCoordinates';
|
|
6
8
|
import reverseComparator from './reverseComparator';
|
|
7
9
|
|
|
8
|
-
const comparators: Record<ResultColumn, (locale: string) => Comparator<Result>> = {
|
|
10
|
+
const comparators: Record<ResultColumn, (locale: string, showCoordinates: ShowCoordinates) => Comparator<Result>> = {
|
|
9
11
|
[ResultColumn.BlanksCount]: (locale: string) => createKeyComparator('blanksCount', locale),
|
|
10
12
|
[ResultColumn.ConsonantsCount]: (locale: string) => createKeyComparator('consonantsCount', locale),
|
|
11
|
-
[ResultColumn.Coordinates]: () => () =>
|
|
13
|
+
[ResultColumn.Coordinates]: (locale: string, showCoordinates: ShowCoordinates) => (a, b) => {
|
|
14
|
+
const stringComparator = createStringComparator(locale);
|
|
15
|
+
const aValue = getCoordinates(a, showCoordinates);
|
|
16
|
+
const bValue = getCoordinates(b, showCoordinates);
|
|
17
|
+
return stringComparator(aValue, bValue);
|
|
18
|
+
},
|
|
12
19
|
[ResultColumn.Points]: (locale: string) => createKeyComparator('points', locale),
|
|
13
20
|
[ResultColumn.TilesCount]: (locale: string) => createKeyComparator('tilesCount', locale),
|
|
14
21
|
[ResultColumn.VowelsCount]: (locale: string) => createKeyComparator('vowelsCount', locale),
|
|
@@ -16,13 +23,18 @@ const comparators: Record<ResultColumn, (locale: string) => Comparator<Result>>
|
|
|
16
23
|
[ResultColumn.WordsCount]: (locale: string) => createKeyComparator('wordsCount', locale),
|
|
17
24
|
};
|
|
18
25
|
|
|
19
|
-
const sortResults = (
|
|
26
|
+
const sortResults = (
|
|
27
|
+
results: Result[] | undefined,
|
|
28
|
+
sort: Sort,
|
|
29
|
+
locale: string,
|
|
30
|
+
showCoordinates: ShowCoordinates,
|
|
31
|
+
): Result[] | undefined => {
|
|
20
32
|
if (typeof results === 'undefined') {
|
|
21
33
|
return results;
|
|
22
34
|
}
|
|
23
35
|
|
|
24
36
|
const createComparator = comparators[sort.column];
|
|
25
|
-
const comparator = createComparator(locale);
|
|
37
|
+
const comparator = createComparator(locale, showCoordinates);
|
|
26
38
|
const finalComparator = sort.direction === SortDirection.Descending ? reverseComparator(comparator) : comparator;
|
|
27
39
|
const sortedResults = [...results].sort(finalComparator);
|
|
28
40
|
return sortedResults;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { FunctionComponent, memo } from 'react';
|
|
2
2
|
|
|
3
|
-
import { Key, Modal } from 'components';
|
|
3
|
+
import { Arrows, Backspace, Ctrl, Del, Enter, Key, Modal, Space } from 'components';
|
|
4
4
|
import { selectConfig, useTranslate, useTypedSelector } from 'state';
|
|
5
5
|
|
|
6
6
|
import { Mapping } from './components';
|
|
7
|
-
import { ARROWS, BACKSPACE, CTRL, DEL, ENTER, SPACE } from './keys';
|
|
8
7
|
|
|
9
8
|
interface Props {
|
|
10
9
|
className?: string;
|
|
@@ -19,15 +18,26 @@ const KeyMapModal: FunctionComponent<Props> = ({ className, isOpen, onClose }) =
|
|
|
19
18
|
return (
|
|
20
19
|
<Modal className={className} isOpen={isOpen} title={translate('keyMap')} onClose={onClose}>
|
|
21
20
|
<Modal.Section title={translate('keyMap.board-and-rack')}>
|
|
22
|
-
<Mapping description={translate('keyMap.board-and-rack.navigate')} mapping={[
|
|
23
|
-
|
|
24
|
-
<Mapping
|
|
21
|
+
<Mapping description={translate('keyMap.board-and-rack.navigate')} mapping={[<Arrows key="arrows" />]} />
|
|
22
|
+
|
|
23
|
+
<Mapping
|
|
24
|
+
description={translate('keyMap.board-and-rack.remove-tile')}
|
|
25
|
+
mapping={[<Del key="del" />, <Backspace key="backspace" />]}
|
|
26
|
+
/>
|
|
27
|
+
|
|
28
|
+
<Mapping description={translate('keyMap.board-and-rack.submit')} mapping={[<Enter key="del" />]} />
|
|
29
|
+
|
|
30
|
+
<Mapping
|
|
31
|
+
description={translate('keyMap.board.toggle-cell-filter')}
|
|
32
|
+
mapping={[[<Ctrl key="ctrl" />, <Key key="g">G</Key>]]}
|
|
33
|
+
/>
|
|
34
|
+
|
|
25
35
|
{config.twoCharacterTiles.length > 0 && (
|
|
26
36
|
<Mapping
|
|
27
37
|
description={translate('keyMap.board-and-rack.insert-two-letter-tile')}
|
|
28
38
|
mapping={[
|
|
29
39
|
[
|
|
30
|
-
|
|
40
|
+
<Ctrl key="ctrl" />,
|
|
31
41
|
<>
|
|
32
42
|
{config.twoCharacterTiles.map(([firstLetter]) => (
|
|
33
43
|
<Key key={firstLetter}>{firstLetter.toUpperCase()}</Key>
|
|
@@ -40,12 +50,12 @@ const KeyMapModal: FunctionComponent<Props> = ({ className, isOpen, onClose }) =
|
|
|
40
50
|
</Modal.Section>
|
|
41
51
|
|
|
42
52
|
<Modal.Section title={translate('keyMap.board')}>
|
|
43
|
-
<Mapping description={translate('keyMap.board.toggle-blank')} mapping={[
|
|
44
|
-
<Mapping description={translate('keyMap.board.toggle-direction')} mapping={[
|
|
53
|
+
<Mapping description={translate('keyMap.board.toggle-blank')} mapping={[<Space key="space" />]} />
|
|
54
|
+
<Mapping description={translate('keyMap.board.toggle-direction')} mapping={[<Arrows key="arrows" />]} />
|
|
45
55
|
</Modal.Section>
|
|
46
56
|
|
|
47
57
|
<Modal.Section title={translate('keyMap.rack')}>
|
|
48
|
-
<Mapping description={translate('keyMap.rack.insert-blank')} mapping={[
|
|
58
|
+
<Mapping description={translate('keyMap.rack.insert-blank')} mapping={[<Space key="space" />]} />
|
|
49
59
|
</Modal.Section>
|
|
50
60
|
</Modal>
|
|
51
61
|
);
|
|
@@ -13,10 +13,7 @@ interface RequestData {
|
|
|
13
13
|
words: string[];
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
const MAXIMUM_COLLISIONS_COUNT = Object.values(games).reduce(
|
|
17
|
-
(result, game) => Math.max(result, game.maximumCharactersCount),
|
|
18
|
-
0,
|
|
19
|
-
);
|
|
16
|
+
const MAXIMUM_COLLISIONS_COUNT = Object.values(games).reduce((result, game) => Math.max(result, game.rackSize), 0);
|
|
20
17
|
const MAXIMUM_WORDS_COUNT = MAXIMUM_COLLISIONS_COUNT + 1;
|
|
21
18
|
|
|
22
19
|
const dictionary = async (request: NextApiRequest, response: NextApiResponse): Promise<void> => {
|
package/src/state/sagas.ts
CHANGED
|
@@ -123,7 +123,7 @@ function* onInitialize(): AnyGenerator {
|
|
|
123
123
|
function* onReset(): AnyGenerator {
|
|
124
124
|
const config = yield select(selectConfig);
|
|
125
125
|
|
|
126
|
-
yield put(boardSlice.actions.init(Board.create(config.
|
|
126
|
+
yield put(boardSlice.actions.init(Board.create(config.boardSize)));
|
|
127
127
|
yield put(cellFilterSlice.actions.reset());
|
|
128
128
|
yield put(dictionarySlice.actions.reset());
|
|
129
129
|
yield put(rackSlice.actions.reset());
|
|
@@ -214,12 +214,12 @@ function* ensureProperTilesCount(): AnyGenerator {
|
|
|
214
214
|
const { config } = yield select(selectConfig);
|
|
215
215
|
const rack = yield select(selectRack);
|
|
216
216
|
|
|
217
|
-
if (config.
|
|
218
|
-
const differenceCount = Math.abs(config.
|
|
217
|
+
if (config.rackSize > rack.length) {
|
|
218
|
+
const differenceCount = Math.abs(config.rackSize - rack.length);
|
|
219
219
|
yield put(rackSlice.actions.init([...rack, ...Array(differenceCount).fill(null)]));
|
|
220
|
-
} else if (config.
|
|
221
|
-
const nonNulls = rack.filter(Boolean).slice(0, config.
|
|
222
|
-
const differenceCount = Math.abs(config.
|
|
220
|
+
} else if (config.rackSize < rack.length) {
|
|
221
|
+
const nonNulls = rack.filter(Boolean).slice(0, config.rackSize);
|
|
222
|
+
const differenceCount = Math.abs(config.rackSize - nonNulls.length);
|
|
223
223
|
const autoGroupTiles = yield select(selectLocaleAutoGroupTiles);
|
|
224
224
|
yield put(rackSlice.actions.init([...nonNulls, ...Array(differenceCount).fill(null)]));
|
|
225
225
|
yield put(rackSlice.actions.groupTiles(autoGroupTiles));
|
package/src/state/selectors.ts
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
getRemainingTilesGroups,
|
|
14
14
|
groupResults,
|
|
15
15
|
resultMatchesCellFilter,
|
|
16
|
-
|
|
16
|
+
sortGroupedResults,
|
|
17
17
|
unorderedArraysEqual,
|
|
18
18
|
} from 'lib';
|
|
19
19
|
import { Point, Translations } from 'types';
|
|
@@ -94,14 +94,17 @@ export const selectResultsQuery = createSelector([selectResultsRoot], (results)
|
|
|
94
94
|
|
|
95
95
|
export const selectResultsSort = createSelector([selectResultsRoot], (results) => results.sort);
|
|
96
96
|
|
|
97
|
-
export const selectSortedResults = createSelector([selectResultsRaw, selectResultsSort, selectLocale], sortResults);
|
|
98
|
-
|
|
99
97
|
export const selectGroupedResults = createSelector(
|
|
100
|
-
[
|
|
98
|
+
[selectResultsRaw, selectResultsQuery, selectFilteredCells],
|
|
101
99
|
groupResults,
|
|
102
100
|
);
|
|
103
101
|
|
|
104
|
-
export const
|
|
102
|
+
export const selectGroupedSortedResults = createSelector(
|
|
103
|
+
[selectGroupedResults, selectResultsSort, selectLocale, selectShowCoordinates],
|
|
104
|
+
sortGroupedResults,
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
export const selectResults = createSelector([selectGroupedSortedResults], (groupedResults) => {
|
|
105
108
|
return groupedResults ? [...groupedResults.matching, ...groupedResults.other] : groupedResults;
|
|
106
109
|
});
|
|
107
110
|
|
|
@@ -8,8 +8,8 @@ import settingsInitialState from './settingsInitialState';
|
|
|
8
8
|
export type BoardState = Board;
|
|
9
9
|
|
|
10
10
|
const { game, locale } = settingsInitialState;
|
|
11
|
-
const {
|
|
12
|
-
export const boardDefaultState = Board.create(
|
|
11
|
+
const { boardSize } = getConfig(game, locale);
|
|
12
|
+
export const boardDefaultState = Board.create(boardSize);
|
|
13
13
|
|
|
14
14
|
const boardInitialState: BoardState = localStorage.getBoard() || boardDefaultState;
|
|
15
15
|
|
|
@@ -65,8 +65,8 @@ const boardSlice = createSlice({
|
|
|
65
65
|
throw new Error(`Cannot find config for game "${game}"`);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
if (state.rows.length !== config.
|
|
69
|
-
return Board.create(config.
|
|
68
|
+
if (state.rows.length !== config.boardSize || state.rows[0].length !== config.boardSize) {
|
|
69
|
+
return Board.create(config.boardSize);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
return state;
|
|
@@ -58,7 +58,7 @@ $easeOutSine: cubic-bezier(0.61, 1, 0.88, 1);
|
|
|
58
58
|
--color--bonus--start: var(--color--violet--light);
|
|
59
59
|
--color--bonus--word-multiplier--2: #fbc997;
|
|
60
60
|
--color--bonus--word-multiplier--3: #f19393;
|
|
61
|
-
--color--tooltip--background: #
|
|
61
|
+
--color--tooltip--background: #444;
|
|
62
62
|
--color--tooltip--foreground: var(--color--white);
|
|
63
63
|
|
|
64
64
|
--font--family: system-ui, sans-serif;
|
|
@@ -110,7 +110,7 @@ $easeOutSine: cubic-bezier(0.61, 1, 0.88, 1);
|
|
|
110
110
|
--solver-column--width: 580px;
|
|
111
111
|
--square-button--size: 32px;
|
|
112
112
|
--text-input--height: 40px;
|
|
113
|
-
--tooltip--max-width:
|
|
113
|
+
--tooltip--max-width: 500px;
|
|
114
114
|
|
|
115
115
|
@include media('<l') {
|
|
116
116
|
--dictionary--height: var(--dictionary--height--mobile);
|
package/src/types/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Result } from '@scrabble-solver/types';
|
|
2
|
+
|
|
1
3
|
export type Comparator<T> = (a: T, B: T) => number;
|
|
2
4
|
|
|
3
5
|
export type AutoGroupTiles = 'left' | 'right' | null;
|
|
@@ -55,14 +57,20 @@ export enum ResultColumn {
|
|
|
55
57
|
Word = 'word',
|
|
56
58
|
WordsCount = 'words-count',
|
|
57
59
|
}
|
|
60
|
+
|
|
61
|
+
export interface GroupedResults {
|
|
62
|
+
matching: Result[];
|
|
63
|
+
other: Result[];
|
|
64
|
+
}
|
|
65
|
+
|
|
58
66
|
export type TranslationKey =
|
|
59
67
|
| 'cell.enter-word'
|
|
60
68
|
| 'cell.filter-cell.exclude'
|
|
61
69
|
| 'cell.filter-cell.include'
|
|
62
70
|
| 'cell.set-blank'
|
|
63
71
|
| 'cell.set-not-blank'
|
|
64
|
-
| 'cell.toggle-direction'
|
|
65
72
|
| 'cell.tile.location'
|
|
73
|
+
| 'common.arrows'
|
|
66
74
|
| 'common.clear'
|
|
67
75
|
| 'common.close'
|
|
68
76
|
| 'common.loading'
|
|
@@ -71,6 +79,7 @@ export type TranslationKey =
|
|
|
71
79
|
| 'common.next'
|
|
72
80
|
| 'common.points'
|
|
73
81
|
| 'common.previous'
|
|
82
|
+
| 'common.space'
|
|
74
83
|
| 'common.tiles'
|
|
75
84
|
| 'common.two-letter-tiles'
|
|
76
85
|
| 'common.vowels'
|
|
@@ -91,6 +100,7 @@ export type TranslationKey =
|
|
|
91
100
|
| 'keyMap'
|
|
92
101
|
| 'keyMap.board'
|
|
93
102
|
| 'keyMap.board.toggle-blank'
|
|
103
|
+
| 'keyMap.board.toggle-cell-filter'
|
|
94
104
|
| 'keyMap.board.toggle-direction'
|
|
95
105
|
| 'keyMap.board-and-rack'
|
|
96
106
|
| 'keyMap.board-and-rack.insert-two-letter-tile'
|