@scrabble-solver/scrabble-solver 2.13.8 → 2.13.10

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.
Files changed (65) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +6 -6
  3. package/.next/cache/.tsbuildinfo +1 -1
  4. package/.next/cache/eslint/.cache_8dgz12 +1 -1
  5. package/.next/cache/webpack/client-production/0.pack +0 -0
  6. package/.next/cache/webpack/client-production/index.pack +0 -0
  7. package/.next/cache/webpack/edge-server-production/0.pack +0 -0
  8. package/.next/cache/webpack/edge-server-production/index.pack +0 -0
  9. package/.next/cache/webpack/server-production/0.pack +0 -0
  10. package/.next/cache/webpack/server-production/index.pack +0 -0
  11. package/.next/prerender-manifest.js +1 -1
  12. package/.next/prerender-manifest.json +1 -1
  13. package/.next/routes-manifest.json +1 -1
  14. package/.next/server/chunks/807.js +1 -1
  15. package/.next/server/middleware-build-manifest.js +1 -1
  16. package/.next/server/pages/404.html +1 -1
  17. package/.next/server/pages/500.html +1 -1
  18. package/.next/server/pages/_app.js +1 -1
  19. package/.next/server/pages/_error.js +1 -1
  20. package/.next/server/pages/api/solve.js +1 -1
  21. package/.next/server/pages/index.html +1 -1
  22. package/.next/server/pages/index.js +1 -1
  23. package/.next/server/pages/index.json +1 -1
  24. package/.next/static/{7zESQYo9UAqNh9LV0b7Sd → 0kOqO_aASkcT2xjhiptyo}/_buildManifest.js +1 -1
  25. package/.next/static/chunks/pages/{404-63b972b24be99c62.js → 404-b447c5ca188dd7c1.js} +1 -1
  26. package/.next/static/chunks/pages/_app-0bbddaa93fde16ea.js +17 -0
  27. package/.next/static/chunks/pages/index-24b84719cf22731c.js +1 -0
  28. package/.next/static/css/841a5b5f0b2fb131.css +2 -0
  29. package/.next/trace +44 -44
  30. package/LICENSE +1 -1
  31. package/package.json +10 -9
  32. package/src/components/Board/Board.tsx +3 -3
  33. package/src/components/Board/BoardPure.tsx +27 -19
  34. package/src/components/Board/components/Actions/Actions.tsx +8 -12
  35. package/src/components/Board/components/Actions/lib.ts +30 -0
  36. package/src/components/Board/hooks/useBackgroundImage.tsx +3 -24
  37. package/src/components/Radio/Radio.module.scss +2 -1
  38. package/src/components/Results/Results.tsx +5 -1
  39. package/src/components/Tile/Tile.module.scss +0 -2
  40. package/src/components/Tile/Tile.tsx +1 -15
  41. package/src/components/Tooltip/Tooltip.module.scss +1 -0
  42. package/src/hooks/useAppLayout.ts +0 -1
  43. package/src/i18n/languages/english.json +2 -1
  44. package/src/i18n/languages/french.json +2 -1
  45. package/src/i18n/languages/german.json +2 -1
  46. package/src/i18n/languages/persian.json +2 -1
  47. package/src/i18n/languages/polish.json +2 -1
  48. package/src/i18n/languages/romanian.json +2 -1
  49. package/src/i18n/languages/spanish.json +2 -1
  50. package/src/icons/Ban.svg +4 -0
  51. package/src/icons/index.ts +1 -0
  52. package/src/lib/groupResults.ts +7 -13
  53. package/src/lib/index.ts +2 -0
  54. package/src/lib/resultMatchesCellFilter.ts +23 -0
  55. package/src/lib/sortGroupedResults.ts +22 -0
  56. package/src/parameters/index.ts +0 -9
  57. package/src/state/sagas.ts +4 -4
  58. package/src/state/selectors.ts +13 -13
  59. package/src/state/slices/cellFilterInitialState.ts +2 -2
  60. package/src/state/slices/cellFilterSlice.ts +29 -4
  61. package/src/types/index.ts +18 -1
  62. package/.next/static/chunks/pages/_app-a2848b7efa6bb6b0.js +0 -17
  63. package/.next/static/chunks/pages/index-7b73be2915cc7099.js +0 -1
  64. package/.next/static/css/b37850c8d5270d91.css +0 -2
  65. /package/.next/static/{7zESQYo9UAqNh9LV0b7Sd → 0kOqO_aASkcT2xjhiptyo}/_ssgManifest.js +0 -0
@@ -12,7 +12,8 @@ import {
12
12
  getRemainingTiles,
13
13
  getRemainingTilesGroups,
14
14
  groupResults,
15
- sortResults,
15
+ resultMatchesCellFilter,
16
+ sortGroupedResults,
16
17
  unorderedArraysEqual,
17
18
  } from 'lib';
18
19
  import { Point, Translations } from 'types';
@@ -75,8 +76,8 @@ export const selectConfig = createSelector([selectGame, selectLocale], getConfig
75
76
 
76
77
  export const selectFilteredCells = selectCellFilterRoot;
77
78
 
78
- export const selectCellIsFiltered = createSelector([selectFilteredCells, selectPoint], (cellFilter, { x, y }) => {
79
- return cellFilter.some((cell) => cell.x === x && cell.y === y);
79
+ export const selectCellFilter = createSelector([selectFilteredCells, selectPoint], (cellFilter, { x, y }) => {
80
+ return cellFilter.find((cell) => cell.x === x && cell.y === y);
80
81
  });
81
82
 
82
83
  export const selectCellIsValid = createSelector([selectConfig, selectCell], (config, cell) => {
@@ -93,20 +94,23 @@ export const selectResultsQuery = createSelector([selectResultsRoot], (results)
93
94
 
94
95
  export const selectResultsSort = createSelector([selectResultsRoot], (results) => results.sort);
95
96
 
96
- export const selectSortedResults = createSelector([selectResultsRaw, selectResultsSort, selectLocale], sortResults);
97
-
98
97
  export const selectGroupedResults = createSelector(
99
- [selectSortedResults, selectResultsQuery, selectFilteredCells],
98
+ [selectResultsRaw, selectResultsQuery, selectFilteredCells],
100
99
  groupResults,
101
100
  );
102
101
 
103
- export const selectResults = createSelector([selectGroupedResults], (groupedResults) => {
102
+ export const selectGroupedSortedResults = createSelector(
103
+ [selectGroupedResults, selectResultsSort, selectLocale],
104
+ sortGroupedResults,
105
+ );
106
+
107
+ export const selectResults = createSelector([selectGroupedSortedResults], (groupedResults) => {
104
108
  return groupedResults ? [...groupedResults.matching, ...groupedResults.other] : groupedResults;
105
109
  });
106
110
 
107
111
  export const selectIsResultMatching = createSelector(
108
112
  [selectResults, selectResultsQuery, selectFilteredCells, selectResultIndex],
109
- (results, query, filteredCells, index) => {
113
+ (results, query, cellFilter, index) => {
110
114
  if (!results) {
111
115
  return false;
112
116
  }
@@ -118,11 +122,7 @@ export const selectIsResultMatching = createSelector(
118
122
  return false;
119
123
  }
120
124
 
121
- if (filteredCells) {
122
- return filteredCells.every(({ x, y }) => result.cells.some((cell) => cell.x === x && cell.y === y));
123
- }
124
-
125
- return true;
125
+ return resultMatchesCellFilter(result, cellFilter);
126
126
  },
127
127
  );
128
128
 
@@ -1,6 +1,6 @@
1
- import { Point } from 'types';
1
+ import { CellFilterEntry } from 'types';
2
2
 
3
- export type CellFilterState = Point[];
3
+ export type CellFilterState = CellFilterEntry[];
4
4
 
5
5
  const cellFilterInitialState: CellFilterState = [];
6
6
 
@@ -1,6 +1,6 @@
1
1
  import { createSlice, PayloadAction } from '@reduxjs/toolkit';
2
2
 
3
- import { Point } from 'types';
3
+ import { CellFilterType, Point } from 'types';
4
4
 
5
5
  import cellFilterInitialState from './cellFilterInitialState';
6
6
 
@@ -10,17 +10,42 @@ const cellFilterSlice = createSlice({
10
10
  reducers: {
11
11
  toggle: (state, action: PayloadAction<Point>) => {
12
12
  const { x, y } = action.payload;
13
- const has = state.some((point) => point.x === x && point.y === y);
13
+ const currentEntry = state.find((point) => point.x === x && point.y === y);
14
+ const has = Boolean(currentEntry);
15
+ const nextType = currentEntry ? toggleCellFilterState(currentEntry.type) : 'include';
14
16
 
15
- if (has) {
17
+ if (nextType === null) {
16
18
  return state.filter((point) => point.x !== x || point.y !== y);
17
19
  }
18
20
 
19
- return [...state, action.payload];
21
+ if (!has) {
22
+ return [...state, { ...action.payload, type: nextType }];
23
+ }
24
+
25
+ return state.map((entry) => {
26
+ if (entry.x === x && entry.y === y) {
27
+ return { ...entry, type: nextType };
28
+ }
29
+
30
+ return entry;
31
+ });
32
+ },
33
+
34
+ cancel: (state, action: PayloadAction<Point>) => {
35
+ const { x, y } = action.payload;
36
+
37
+ return state.filter((point) => point.x !== x || point.y !== y);
20
38
  },
21
39
 
22
40
  reset: () => cellFilterInitialState,
23
41
  },
24
42
  });
25
43
 
44
+ const toggleCellFilterState = (type: CellFilterType): CellFilterType | null => {
45
+ const chain: (CellFilterType | null)[] = ['include', 'exclude', null];
46
+ const index = chain.indexOf(type);
47
+ const nextIndex = (index + 1) % chain.length;
48
+ return chain[nextIndex];
49
+ };
50
+
26
51
  export default cellFilterSlice;
@@ -1,7 +1,17 @@
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;
4
6
 
7
+ export type CellFilterType = 'include' | 'exclude';
8
+
9
+ export type CellFilterEntry = {
10
+ x: Point['x'];
11
+ y: Point['y'];
12
+ type: CellFilterType;
13
+ };
14
+
5
15
  export type Direction = 'horizontal' | 'vertical';
6
16
 
7
17
  export type InputMode = 'keyboard' | 'touchscreen';
@@ -47,9 +57,16 @@ export enum ResultColumn {
47
57
  Word = 'word',
48
58
  WordsCount = 'words-count',
49
59
  }
60
+
61
+ export interface GroupedResults {
62
+ matching: Result[];
63
+ other: Result[];
64
+ }
65
+
50
66
  export type TranslationKey =
51
67
  | 'cell.enter-word'
52
- | 'cell.filter-cell'
68
+ | 'cell.filter-cell.exclude'
69
+ | 'cell.filter-cell.include'
53
70
  | 'cell.set-blank'
54
71
  | 'cell.set-not-blank'
55
72
  | 'cell.toggle-direction'