@scrabble-solver/scrabble-solver 2.11.1 → 2.11.2
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/next-server.js.nft.json +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/next-server.js.nft.json +1 -1
- package/.next/prerender-manifest.json +1 -1
- package/.next/routes-manifest.json +1 -1
- package/.next/server/chunks/277.js +203 -173
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/pages/404.html +2 -2
- package/.next/server/pages/404.js.nft.json +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/pages/_app.js.nft.json +1 -1
- package/.next/server/pages/_document.js.nft.json +1 -1
- package/.next/server/pages/api/dictionary/[locale]/[word].js +0 -1
- package/.next/server/pages/api/dictionary/[locale].js +0 -1
- package/.next/server/pages/api/solve.js +29 -8
- package/.next/server/pages/api/verify.js +0 -1
- package/.next/server/pages/api/visit.js +0 -1
- package/.next/server/pages/index.html +1 -1
- package/.next/server/pages/index.js +46 -39
- package/.next/server/pages/index.js.nft.json +1 -1
- package/.next/server/pages/index.json +1 -1
- package/.next/static/{esK8DG-6aS5V7QFRtR3YE → Mdvi3FY0PqkILKLbPlVBU}/_buildManifest.js +1 -1
- package/.next/static/chunks/pages/_app-495e6f4ccc278bb2.js +28 -0
- package/.next/static/chunks/pages/index-5ecc51900ca29685.js +1 -0
- package/.next/static/css/17b0a2db8742105f.css +1 -0
- package/.next/static/css/e1ffeb2558330c55.css +2 -0
- package/.next/trace +54 -53
- package/package.json +9 -9
- package/src/components/Board/components/Cell/Cell.module.scss +10 -2
- package/src/components/Board/hooks/useGrid.ts +1 -2
- package/src/components/Board/lib/getPositionInGrid.ts +1 -1
- package/src/components/LogoSplashScreen/LogoSplashScreen.module.scss +4 -1
- package/src/components/Modal/Modal.module.scss +12 -0
- package/src/components/Modal/Modal.tsx +4 -1
- package/src/components/Results/HeaderButton.tsx +5 -12
- package/src/components/Results/Result.tsx +5 -3
- package/src/components/Results/Results.module.scss +13 -1
- package/src/components/Results/Results.tsx +29 -43
- package/src/components/Results/types.ts +1 -1
- package/src/components/Solver/Solver.module.scss +4 -0
- package/src/components/Solver/Solver.tsx +9 -12
- package/src/components/Solver/components/ResultCandidatePicker/ResultCandidatePicker.tsx +5 -6
- package/src/components/Tile/Tile.module.scss +40 -71
- package/src/components/Tile/Tile.tsx +4 -3
- package/src/components/Tile/TilePure.tsx +4 -13
- package/src/hooks/useAppLayout.ts +3 -1
- package/src/i18n/de.json +0 -1
- package/src/i18n/en.json +0 -1
- package/src/i18n/es.json +0 -1
- package/src/i18n/fa.json +0 -1
- package/src/i18n/fr.json +0 -1
- package/src/i18n/pl.json +0 -1
- package/src/lib/createRegExp.ts +13 -0
- package/src/lib/groupResults.ts +38 -0
- package/src/lib/guessLocale.ts +22 -0
- package/src/lib/index.ts +4 -1
- package/src/lib/sortResults.ts +6 -10
- package/src/modals/DictionaryModal/DictionaryModal.module.scss +0 -1
- package/src/modals/MenuModal/MenuModal.module.scss +7 -0
- package/src/modals/ResultsModal/ResultsModal.module.scss +2 -3
- package/src/modals/ResultsModal/ResultsModal.tsx +23 -11
- package/src/pages/api/dictionary/[locale]/[word].ts +0 -1
- package/src/pages/api/dictionary/[locale]/index.ts +0 -1
- package/src/pages/api/solve.ts +0 -1
- package/src/pages/api/verify.ts +0 -1
- package/src/pages/api/visit.ts +0 -1
- package/src/pages/index.tsx +13 -15
- package/src/parameters/index.ts +2 -2
- package/src/state/sagas.ts +1 -0
- package/src/state/selectors.ts +37 -37
- package/src/state/slices/boardInitialState.ts +3 -1
- package/src/state/slices/cellFilterInitialState.ts +3 -3
- package/src/state/slices/cellFilterSlice.ts +3 -1
- package/src/state/slices/dictionaryInitialState.ts +2 -2
- package/src/state/slices/rackInitialState.ts +3 -1
- package/src/state/slices/resultsInitialState.ts +11 -4
- package/src/state/slices/settingsInitialState.ts +10 -21
- package/src/state/slices/solveInitialState.ts +2 -2
- package/src/state/slices/solveSlice.ts +2 -0
- package/src/state/slices/verifyInitialState.ts +13 -4
- package/src/styles/mixins.scss +3 -1
- package/src/styles/variables.scss +1 -0
- package/src/types/index.ts +10 -2
- package/.next/static/chunks/pages/_app-270526803bc274eb.js +0 -28
- package/.next/static/chunks/pages/index-c6e7754ccf3532df.js +0 -1
- package/.next/static/css/ad39b36eab07e613.css +0 -1
- package/.next/static/css/e5803e581e4c0451.css +0 -2
- package/src/components/Board/types/index.ts +0 -4
- /package/.next/static/{esK8DG-6aS5V7QFRtR3YE → Mdvi3FY0PqkILKLbPlVBU}/_ssgManifest.js +0 -0
package/src/state/selectors.ts
CHANGED
|
@@ -1,17 +1,29 @@
|
|
|
1
|
+
/* eslint-disable max-lines */
|
|
2
|
+
|
|
1
3
|
import { createSelector } from '@reduxjs/toolkit';
|
|
2
4
|
import { getLocaleConfig } from '@scrabble-solver/configs';
|
|
3
5
|
import { BLANK } from '@scrabble-solver/constants';
|
|
4
|
-
import { Cell, Config, isError,
|
|
6
|
+
import { Cell, Config, isError, Tile } from '@scrabble-solver/types';
|
|
5
7
|
|
|
6
8
|
import i18n, { LOCALE_FEATURES } from 'i18n';
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
+
import {
|
|
10
|
+
createRegExp,
|
|
11
|
+
findCell,
|
|
12
|
+
getRemainingTiles,
|
|
13
|
+
getRemainingTilesGroups,
|
|
14
|
+
groupResults,
|
|
15
|
+
sortResults,
|
|
16
|
+
unorderedArraysEqual,
|
|
17
|
+
} from 'lib';
|
|
18
|
+
import { Point, Translations } from 'types';
|
|
9
19
|
|
|
10
20
|
import { RootState } from './types';
|
|
11
21
|
|
|
12
22
|
const selectCell = (_: unknown, cell: Cell): Cell => cell;
|
|
13
23
|
|
|
14
|
-
const selectPoint = (_: unknown, point:
|
|
24
|
+
const selectPoint = (_: unknown, point: Point): Point => point;
|
|
25
|
+
|
|
26
|
+
const selectResultIndex = (_: unknown, index: number): number => index;
|
|
15
27
|
|
|
16
28
|
const selectCharacter = (_: unknown, character: string | null): string | null => character;
|
|
17
29
|
|
|
@@ -71,54 +83,42 @@ export const selectCellIsValid = createSelector([selectConfig, selectCell], (con
|
|
|
71
83
|
return config.tiles.some((tile) => tile.character === cell.tile.character);
|
|
72
84
|
});
|
|
73
85
|
|
|
74
|
-
export const
|
|
86
|
+
export const selectResultsRaw = createSelector([selectResultsRoot], (results) => results.results);
|
|
75
87
|
|
|
76
88
|
export const selectResultsQuery = createSelector([selectResultsRoot], (results) => results.query);
|
|
77
89
|
|
|
78
|
-
export const
|
|
90
|
+
export const selectResultsSort = createSelector([selectResultsRoot], (results) => results.sort);
|
|
79
91
|
|
|
80
|
-
export const
|
|
92
|
+
export const selectSortedResults = createSelector([selectResultsRaw, selectResultsSort, selectLocale], sortResults);
|
|
81
93
|
|
|
82
|
-
export const
|
|
83
|
-
[
|
|
84
|
-
|
|
94
|
+
export const selectGroupedResults = createSelector(
|
|
95
|
+
[selectSortedResults, selectResultsQuery, selectCellFilter],
|
|
96
|
+
groupResults,
|
|
85
97
|
);
|
|
86
98
|
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
let regExp: RegExp | undefined;
|
|
93
|
-
|
|
94
|
-
try {
|
|
95
|
-
regExp = new RegExp(query, 'gi');
|
|
96
|
-
} catch {
|
|
97
|
-
return results;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return results.filter((result) => {
|
|
101
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
102
|
-
return regExp!.test(result.word);
|
|
103
|
-
});
|
|
104
|
-
};
|
|
99
|
+
export const selectResults = createSelector([selectGroupedResults], (groupedResults) => {
|
|
100
|
+
return groupedResults ? [...groupedResults.matching, ...groupedResults.other] : groupedResults;
|
|
101
|
+
});
|
|
105
102
|
|
|
106
|
-
export const
|
|
107
|
-
[
|
|
108
|
-
(results, query, cellFilter) => {
|
|
103
|
+
export const selectIsResultMatching = createSelector(
|
|
104
|
+
[selectResults, selectResultsQuery, selectCellFilter, selectResultIndex],
|
|
105
|
+
(results, query, cellFilter, index) => {
|
|
109
106
|
if (!results) {
|
|
110
|
-
return
|
|
107
|
+
return false;
|
|
111
108
|
}
|
|
112
109
|
|
|
113
|
-
const
|
|
110
|
+
const result = results[index];
|
|
111
|
+
const regExp = createRegExp(query);
|
|
114
112
|
|
|
115
|
-
if (!
|
|
116
|
-
return
|
|
113
|
+
if (!regExp.test(result.word)) {
|
|
114
|
+
return false;
|
|
117
115
|
}
|
|
118
116
|
|
|
119
|
-
|
|
117
|
+
if (cellFilter) {
|
|
120
118
|
return cellFilter.every(({ x, y }) => result.cells.some((cell) => cell.x === x && cell.y === y));
|
|
121
|
-
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return true;
|
|
122
122
|
},
|
|
123
123
|
);
|
|
124
124
|
|
|
@@ -3,9 +3,11 @@ import { Board } from '@scrabble-solver/types';
|
|
|
3
3
|
|
|
4
4
|
import settingsInitialState from './settingsInitialState';
|
|
5
5
|
|
|
6
|
+
export type BoardState = Board;
|
|
7
|
+
|
|
6
8
|
const { configId, locale } = settingsInitialState;
|
|
7
9
|
const { boardHeight, boardWidth } = getLocaleConfig(configId, locale);
|
|
8
|
-
const boardInitialState:
|
|
10
|
+
const boardInitialState: BoardState = Board.create(boardWidth, boardHeight);
|
|
9
11
|
|
|
10
12
|
// const createOxyphenbutazone = () => {
|
|
11
13
|
// // Tiles: oypbaze
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Point } from 'types';
|
|
2
2
|
|
|
3
|
-
export type
|
|
3
|
+
export type CellFilterState = Point[];
|
|
4
4
|
|
|
5
|
-
const cellFilterInitialState:
|
|
5
|
+
const cellFilterInitialState: CellFilterState = [];
|
|
6
6
|
|
|
7
7
|
export default cellFilterInitialState;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import { Point } from 'types';
|
|
4
|
+
|
|
5
|
+
import cellFilterInitialState from './cellFilterInitialState';
|
|
4
6
|
|
|
5
7
|
const cellFilterSlice = createSlice({
|
|
6
8
|
initialState: cellFilterInitialState,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { WordDefinition } from '@scrabble-solver/types';
|
|
2
2
|
|
|
3
|
-
interface
|
|
3
|
+
export interface DictionaryState {
|
|
4
4
|
error: unknown | undefined;
|
|
5
5
|
input: string;
|
|
6
6
|
isLoading: boolean;
|
|
7
7
|
results: WordDefinition[];
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
const dictionaryInitialState:
|
|
10
|
+
const dictionaryInitialState: DictionaryState = {
|
|
11
11
|
error: undefined,
|
|
12
12
|
input: '',
|
|
13
13
|
isLoading: false,
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import { Result } from '@scrabble-solver/types';
|
|
2
2
|
|
|
3
|
-
import { ResultColumn, SortDirection } from 'types';
|
|
3
|
+
import { ResultColumn, Sort, SortDirection } from 'types';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
candidate:
|
|
5
|
+
export interface ResultsState {
|
|
6
|
+
candidate: Result | null;
|
|
7
|
+
query: string;
|
|
8
|
+
results: Result[] | undefined;
|
|
9
|
+
sort: Sort;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const resultsInitialState: ResultsState = {
|
|
13
|
+
candidate: null,
|
|
7
14
|
query: '',
|
|
8
|
-
results: undefined
|
|
15
|
+
results: undefined,
|
|
9
16
|
sort: {
|
|
10
17
|
column: ResultColumn.Points,
|
|
11
18
|
direction: SortDirection.Descending,
|
|
@@ -1,29 +1,18 @@
|
|
|
1
|
-
import { scrabble } from '@scrabble-solver/configs';
|
|
1
|
+
import { literaki, scrabble } from '@scrabble-solver/configs';
|
|
2
2
|
import { Locale } from '@scrabble-solver/types';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
if (!globalThis.navigator) {
|
|
6
|
-
return Locale.EN_US;
|
|
7
|
-
}
|
|
4
|
+
import { guessLocale } from 'lib';
|
|
8
5
|
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
export interface SettingsState {
|
|
7
|
+
autoGroupTiles: 'left' | 'right' | null;
|
|
8
|
+
configId: typeof literaki.id | typeof scrabble.id;
|
|
9
|
+
locale: Locale;
|
|
10
|
+
}
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const partialMatch = locales.find((locale) => {
|
|
17
|
-
return globalThis.navigator.language === locale.substring(0, 2);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
return partialMatch || Locale.EN_US;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const settingsInitialState = {
|
|
24
|
-
autoGroupTiles: 'left' as 'left' | 'right' | null,
|
|
12
|
+
const settingsInitialState: SettingsState = {
|
|
13
|
+
autoGroupTiles: 'left',
|
|
25
14
|
configId: scrabble.id,
|
|
26
|
-
locale:
|
|
15
|
+
locale: guessLocale(),
|
|
27
16
|
};
|
|
28
17
|
|
|
29
18
|
export default settingsInitialState;
|
|
@@ -2,7 +2,7 @@ import { Board } from '@scrabble-solver/types';
|
|
|
2
2
|
|
|
3
3
|
import boardInitialState from './boardInitialState';
|
|
4
4
|
|
|
5
|
-
interface
|
|
5
|
+
export interface SolveState {
|
|
6
6
|
error: unknown | undefined;
|
|
7
7
|
isLoading: boolean;
|
|
8
8
|
lastSolvedParameters: {
|
|
@@ -11,7 +11,7 @@ interface SolveInitialState {
|
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
const solveInitialState:
|
|
14
|
+
const solveInitialState: SolveState = {
|
|
15
15
|
error: undefined,
|
|
16
16
|
isLoading: false,
|
|
17
17
|
lastSolvedParameters: {
|
|
@@ -1,12 +1,21 @@
|
|
|
1
|
-
import boardInitialState from './boardInitialState';
|
|
1
|
+
import boardInitialState, { BoardState } from './boardInitialState';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
export interface VerifyState {
|
|
4
|
+
isLoading: boolean;
|
|
5
|
+
lastSolvedParameters: {
|
|
6
|
+
board: BoardState;
|
|
7
|
+
};
|
|
8
|
+
invalidWords: string[];
|
|
9
|
+
validWords: string[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const verifyInitialState: VerifyState = {
|
|
4
13
|
isLoading: false,
|
|
5
14
|
lastSolvedParameters: {
|
|
6
15
|
board: boardInitialState,
|
|
7
16
|
},
|
|
8
|
-
invalidWords: []
|
|
9
|
-
validWords: []
|
|
17
|
+
invalidWords: [],
|
|
18
|
+
validWords: [],
|
|
10
19
|
};
|
|
11
20
|
|
|
12
21
|
export default verifyInitialState;
|
package/src/styles/mixins.scss
CHANGED
|
@@ -43,7 +43,6 @@ $media-expressions: (
|
|
|
43
43
|
position: relative;
|
|
44
44
|
|
|
45
45
|
&::after {
|
|
46
|
-
content: '';
|
|
47
46
|
position: absolute;
|
|
48
47
|
top: 0;
|
|
49
48
|
right: 0;
|
|
@@ -63,6 +62,7 @@ $media-expressions: (
|
|
|
63
62
|
}
|
|
64
63
|
|
|
65
64
|
&::after {
|
|
65
|
+
content: '';
|
|
66
66
|
box-shadow: 0 0 0 var(--focus-effect--size) var(--color--focus);
|
|
67
67
|
}
|
|
68
68
|
}
|
|
@@ -151,6 +151,7 @@ $media-expressions: (
|
|
|
151
151
|
&:nth-child(3) {
|
|
152
152
|
input {
|
|
153
153
|
left: -200%;
|
|
154
|
+
right: 0;
|
|
154
155
|
clip-path: polygon((200% / 3) (100% / 3), 100% (100% / 3), 100% (200% / 3), (200% / 3) (200% / 3));
|
|
155
156
|
}
|
|
156
157
|
}
|
|
@@ -160,6 +161,7 @@ $media-expressions: (
|
|
|
160
161
|
&:nth-last-child(3) {
|
|
161
162
|
input {
|
|
162
163
|
left: 0;
|
|
164
|
+
right: -200%;
|
|
163
165
|
clip-path: polygon(0 (100% / 3), (100% / 3) (100% / 3), (100% / 3) (200% / 3), 0 (200% / 3));
|
|
164
166
|
}
|
|
165
167
|
}
|
|
@@ -41,6 +41,7 @@ $easeOutSine: cubic-bezier(0.61, 1, 0.88, 1);
|
|
|
41
41
|
--color--success: #00a900;
|
|
42
42
|
--color--warning: hsl(35, 90%, 60%);
|
|
43
43
|
--color--primary: var(--color--violet);
|
|
44
|
+
--color--primary--light: var(--color--violet--light);
|
|
44
45
|
--color--primary--opposite: var(--color--white);
|
|
45
46
|
|
|
46
47
|
--color--bonus--character--1: var(--color--yellow--light);
|
package/src/types/index.ts
CHANGED
|
@@ -2,6 +2,16 @@ export type Comparator<T> = (a: T, B: T) => number;
|
|
|
2
2
|
|
|
3
3
|
export type Direction = 'horizontal' | 'vertical';
|
|
4
4
|
|
|
5
|
+
export interface Point {
|
|
6
|
+
x: number;
|
|
7
|
+
y: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface Sort {
|
|
11
|
+
column: ResultColumn;
|
|
12
|
+
direction: SortDirection;
|
|
13
|
+
}
|
|
14
|
+
|
|
5
15
|
export enum SortDirection {
|
|
6
16
|
Ascending = 'ascending',
|
|
7
17
|
Descending = 'descending',
|
|
@@ -30,7 +40,6 @@ export enum ResultColumn {
|
|
|
30
40
|
Word = 'word',
|
|
31
41
|
WordsCount = 'words-count',
|
|
32
42
|
}
|
|
33
|
-
|
|
34
43
|
export type TranslationKey =
|
|
35
44
|
| 'cell.filter-cell'
|
|
36
45
|
| 'cell.set-blank'
|
|
@@ -78,7 +87,6 @@ export type TranslationKey =
|
|
|
78
87
|
| 'rack.tile.location'
|
|
79
88
|
| 'remaining-tiles'
|
|
80
89
|
| 'results'
|
|
81
|
-
| 'results.empty-state.no-filtered-results'
|
|
82
90
|
| 'results.empty-state.no-results'
|
|
83
91
|
| 'results.empty-state.outdated'
|
|
84
92
|
| 'results.empty-state.uninitialized'
|