@scrabble-solver/scrabble-solver 2.11.4 → 2.11.6
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 +7 -7
- 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/export-marker.json +1 -1
- 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/131.js +1 -1
- package/.next/server/chunks/277.js +851 -1179
- package/.next/server/chunks/636.js +286 -0
- package/.next/server/chunks/675.js +550 -0
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/pages/404.html +1 -5
- package/.next/server/pages/404.js.nft.json +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/pages/_app.js +73 -9
- package/.next/server/pages/_app.js.nft.json +1 -1
- package/.next/server/pages/_document.js.nft.json +1 -1
- package/.next/server/pages/_error.js +1 -280
- package/.next/server/pages/_error.js.nft.json +1 -1
- package/.next/server/pages/api/solve.js +22 -2
- package/.next/server/pages/index.html +1 -1
- package/.next/server/pages/index.js +381 -314
- 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/Jmk00rVXCbdjFgP77tKXQ/_buildManifest.js +1 -0
- package/.next/static/chunks/pages/{404-448ba28510855455.js → 404-8176f4acd0cfeb42.js} +1 -1
- package/.next/static/chunks/pages/_app-b4fa92112b8f0385.js +28 -0
- package/.next/static/chunks/pages/index-ccd762f8f5028729.js +1 -0
- package/.next/static/css/1cd302e7648d209c.css +2 -0
- package/.next/static/css/34adfcf12a7d9bb6.css +1 -0
- package/.next/trace +50 -53
- package/next.config.js +1 -0
- package/package.json +12 -13
- package/src/@types/svg.d.ts +1 -1
- package/src/components/Board/Board.tsx +48 -44
- package/src/components/Board/components/Actions/Actions.tsx +4 -2
- package/src/components/Board/components/Cell/Cell.module.scss +59 -5
- package/src/components/Board/hooks/useGrid.ts +5 -3
- package/src/components/Button/Button.module.scss +1 -1
- package/src/components/Dictionary/Dictionary.module.scss +0 -1
- package/src/components/EmptyState/EmptyState.module.scss +0 -1
- package/src/components/Key/Key.module.scss +1 -1
- package/src/components/Loading/Loading.module.scss +1 -1
- package/src/components/Loading/Loading.tsx +1 -1
- package/src/components/Logo/Logo.tsx +10 -12
- package/src/components/Logo/LogoBlueprint.tsx +21 -0
- package/src/components/Logo/index.ts +1 -1
- package/src/components/Modal/Modal.module.scss +1 -6
- package/src/components/Modal/Modal.tsx +15 -8
- package/src/components/NavButtons/NavButtons.tsx +2 -2
- package/src/components/PlainTiles/PlainTiles.tsx +0 -10
- package/src/components/PlainTiles/Tile.tsx +1 -4
- package/src/components/Rack/Rack.module.scss +59 -0
- package/src/components/Results/HeaderButton.tsx +6 -6
- package/src/components/Results/Results.module.scss +3 -1
- package/src/components/Results/Results.tsx +7 -7
- package/src/components/Results/useColumns.ts +2 -5
- package/src/components/Solver/Solver.tsx +6 -23
- package/src/components/Tile/Tile.module.scss +2 -1
- package/src/components/Tile/Tile.tsx +8 -4
- package/src/components/index.ts +0 -5
- package/src/hooks/index.ts +6 -0
- package/src/hooks/useAppLayout.ts +62 -12
- package/src/hooks/useDirection.ts +2 -2
- package/src/hooks/useEffectOnce.ts +5 -0
- package/src/hooks/useIsTouchDevice.ts +1 -1
- package/src/hooks/useLanguage.ts +2 -2
- package/src/hooks/useLatest.ts +13 -0
- package/src/hooks/useLocalStorage.ts +51 -0
- package/src/hooks/useMedia.ts +36 -0
- package/src/hooks/useMediaQueries.ts +13 -0
- package/src/hooks/useMediaQuery.ts +2 -1
- package/src/hooks/useOnWindowResize.ts +13 -0
- package/src/hooks/useViewportSize.ts +19 -0
- package/src/i18n/constants.ts +14 -22
- package/src/lib/arrayEquals.ts +5 -0
- package/src/lib/index.ts +1 -0
- package/src/lib/zipCharactersAndTiles.ts +3 -1
- package/src/modals/DictionaryModal/DictionaryModal.tsx +2 -2
- package/src/modals/KeyMapModal/KeyMapModal.tsx +2 -2
- package/src/modals/KeyMapModal/components/Mapping/Mapping.module.scss +0 -1
- package/src/modals/KeyMapModal/keys.tsx +0 -2
- package/src/modals/MenuModal/MenuModal.module.scss +28 -4
- package/src/modals/MenuModal/MenuModal.tsx +4 -4
- package/src/modals/RemainingTilesModal/RemainingTilesModal.tsx +2 -2
- package/src/modals/ResultsModal/ResultsModal.module.scss +1 -5
- package/src/modals/ResultsModal/ResultsModal.tsx +10 -2
- package/src/modals/SettingsModal/SettingsModal.tsx +2 -2
- package/src/modals/SettingsModal/components/AutoGroupTilesSetting/lib.ts +3 -1
- package/src/modals/SettingsModal/components/ConfigSetting/ConfigSetting.module.scss +0 -1
- package/src/modals/SettingsModal/components/LocaleSetting/LocaleSetting.module.scss +1 -6
- package/src/modals/WordsModal/WordsModal.tsx +2 -2
- package/src/pages/index.module.scss +3 -21
- package/src/pages/index.tsx +51 -69
- package/src/parameters/index.ts +29 -2
- package/src/state/localStorage.ts +13 -2
- package/src/state/sagas.ts +16 -8
- package/src/state/slices/boardInitialState.ts +5 -1
- package/src/state/slices/boardSlice.ts +2 -2
- package/src/state/slices/rackInitialState.ts +8 -2
- package/src/state/slices/rackSlice.ts +16 -13
- package/src/state/slices/settingsInitialState.ts +9 -4
- package/src/state/slices/settingsSlice.ts +3 -1
- package/src/styles/animations.scss +0 -20
- package/src/styles/global.scss +4 -15
- package/src/styles/mixins.scss +0 -60
- package/src/styles/variables.scss +14 -5
- package/src/types/index.ts +4 -0
- package/.next/static/MvHZRF4XuJ7g8LLLRkf8U/_buildManifest.js +0 -1
- package/.next/static/chunks/pages/_app-66d80a5594aab8dc.js +0 -28
- package/.next/static/chunks/pages/index-0858deea02b2a417.js +0 -1
- package/.next/static/css/885da289cec275b3.css +0 -1
- package/.next/static/css/ea1c8134fe9a143e.css +0 -2
- package/src/components/LogoSplashScreen/LogoSplashScreen.module.scss +0 -65
- package/src/components/LogoSplashScreen/LogoSplashScreen.tsx +0 -31
- package/src/components/LogoSplashScreen/index.ts +0 -1
- package/src/components/Sizer/Sizer.module.scss +0 -10
- package/src/components/Sizer/Sizer.tsx +0 -10
- package/src/components/Sizer/index.ts +0 -1
- package/src/components/SplashScreen/SplashScreen.module.scss +0 -14
- package/src/components/SplashScreen/SplashScreen.tsx +0 -19
- package/src/components/SplashScreen/index.ts +0 -1
- package/src/components/SvgFontCss/SvgFontCss.tsx +0 -14
- package/src/components/SvgFontCss/createCss.ts +0 -11
- package/src/components/SvgFontCss/createStyle.ts +0 -9
- package/src/components/SvgFontCss/createSvg.ts +0 -10
- package/src/components/SvgFontCss/index.ts +0 -1
- package/src/components/SvgFontFix/SvgFontFix.module.scss +0 -5
- package/src/components/SvgFontFix/SvgFontFix.tsx +0 -21
- package/src/components/SvgFontFix/index.ts +0 -1
- package/src/hooks/useLocalStorage/index.ts +0 -1
- package/src/hooks/useLocalStorage/useLocalStorage.ts +0 -13
- package/src/hooks/useLocalStorage/useLocalStorageBoard.ts +0 -29
- package/src/hooks/useLocalStorage/useLocalStorageConfigId.ts +0 -29
- package/src/hooks/useLocalStorage/useLocalStorageLocale.ts +0 -32
- package/src/hooks/useLocalStorage/useLocalStorageRack.ts +0 -29
- /package/.next/static/{MvHZRF4XuJ7g8LLLRkf8U → Jmk00rVXCbdjFgP77tKXQ}/_ssgManifest.js +0 -0
- /package/{src/components/Logo/Logo.svg → public/logo.svg} +0 -0
package/src/i18n/constants.ts
CHANGED
|
@@ -7,7 +7,6 @@ import styles from './i18n.module.scss';
|
|
|
7
7
|
|
|
8
8
|
interface LocaleFeatures {
|
|
9
9
|
direction: 'ltr' | 'rtl';
|
|
10
|
-
fontFamily: string;
|
|
11
10
|
consonants: boolean;
|
|
12
11
|
vowels: boolean;
|
|
13
12
|
}
|
|
@@ -15,43 +14,36 @@ interface LocaleFeatures {
|
|
|
15
14
|
export const LOCALE_FEATURES: Record<Locale, LocaleFeatures> = {
|
|
16
15
|
[Locale.DE_DE]: {
|
|
17
16
|
direction: 'ltr',
|
|
18
|
-
fontFamily: 'Open Sans',
|
|
19
17
|
consonants: true,
|
|
20
18
|
vowels: true,
|
|
21
19
|
},
|
|
22
20
|
[Locale.EN_GB]: {
|
|
23
21
|
direction: 'ltr',
|
|
24
|
-
fontFamily: 'Open Sans',
|
|
25
22
|
consonants: true,
|
|
26
23
|
vowels: true,
|
|
27
24
|
},
|
|
28
25
|
[Locale.EN_US]: {
|
|
29
26
|
direction: 'ltr',
|
|
30
|
-
fontFamily: 'Open Sans',
|
|
31
27
|
consonants: true,
|
|
32
28
|
vowels: true,
|
|
33
29
|
},
|
|
34
30
|
[Locale.ES_ES]: {
|
|
35
31
|
direction: 'ltr',
|
|
36
|
-
fontFamily: 'Open Sans',
|
|
37
32
|
consonants: true,
|
|
38
33
|
vowels: true,
|
|
39
34
|
},
|
|
40
35
|
[Locale.FA_IR]: {
|
|
41
36
|
direction: 'rtl',
|
|
42
|
-
fontFamily: 'Vazirmatn',
|
|
43
37
|
consonants: false,
|
|
44
38
|
vowels: false,
|
|
45
39
|
},
|
|
46
40
|
[Locale.FR_FR]: {
|
|
47
41
|
direction: 'ltr',
|
|
48
|
-
fontFamily: 'Open Sans',
|
|
49
42
|
consonants: true,
|
|
50
43
|
vowels: true,
|
|
51
44
|
},
|
|
52
45
|
[Locale.PL_PL]: {
|
|
53
46
|
direction: 'ltr',
|
|
54
|
-
fontFamily: 'Open Sans',
|
|
55
47
|
consonants: true,
|
|
56
48
|
vowels: true,
|
|
57
49
|
},
|
|
@@ -66,6 +58,13 @@ interface Flag {
|
|
|
66
58
|
}
|
|
67
59
|
|
|
68
60
|
export const LOCALE_FLAGS: Record<Locale, Flag> = {
|
|
61
|
+
[Locale.DE_DE]: {
|
|
62
|
+
className: styles.de,
|
|
63
|
+
Icon: FlagDe,
|
|
64
|
+
label: 'Deutsch',
|
|
65
|
+
name: 'German',
|
|
66
|
+
value: Locale.DE_DE,
|
|
67
|
+
},
|
|
69
68
|
[Locale.EN_GB]: {
|
|
70
69
|
className: styles.gb,
|
|
71
70
|
Icon: FlagGb,
|
|
@@ -80,6 +79,13 @@ export const LOCALE_FLAGS: Record<Locale, Flag> = {
|
|
|
80
79
|
name: 'English (US)',
|
|
81
80
|
value: Locale.EN_US,
|
|
82
81
|
},
|
|
82
|
+
[Locale.ES_ES]: {
|
|
83
|
+
className: styles.es,
|
|
84
|
+
Icon: FlagEs,
|
|
85
|
+
label: 'Español',
|
|
86
|
+
name: 'Spanish',
|
|
87
|
+
value: Locale.ES_ES,
|
|
88
|
+
},
|
|
83
89
|
[Locale.FA_IR]: {
|
|
84
90
|
className: styles.fa,
|
|
85
91
|
Icon: FlagFa,
|
|
@@ -94,13 +100,6 @@ export const LOCALE_FLAGS: Record<Locale, Flag> = {
|
|
|
94
100
|
name: 'French',
|
|
95
101
|
value: Locale.FR_FR,
|
|
96
102
|
},
|
|
97
|
-
[Locale.DE_DE]: {
|
|
98
|
-
className: styles.de,
|
|
99
|
-
Icon: FlagDe,
|
|
100
|
-
label: 'Deutsch',
|
|
101
|
-
name: 'German',
|
|
102
|
-
value: Locale.DE_DE,
|
|
103
|
-
},
|
|
104
103
|
[Locale.PL_PL]: {
|
|
105
104
|
className: styles.pl,
|
|
106
105
|
Icon: FlagPl,
|
|
@@ -108,11 +107,4 @@ export const LOCALE_FLAGS: Record<Locale, Flag> = {
|
|
|
108
107
|
name: 'Polish',
|
|
109
108
|
value: Locale.PL_PL,
|
|
110
109
|
},
|
|
111
|
-
[Locale.ES_ES]: {
|
|
112
|
-
className: styles.es,
|
|
113
|
-
Icon: FlagEs,
|
|
114
|
-
label: 'Español',
|
|
115
|
-
name: 'Spanish',
|
|
116
|
-
value: Locale.ES_ES,
|
|
117
|
-
},
|
|
118
110
|
};
|
package/src/lib/index.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { BLANK } from '@scrabble-solver/constants';
|
|
2
2
|
import { Tile } from '@scrabble-solver/types';
|
|
3
3
|
|
|
4
|
+
import { Rack } from 'types';
|
|
5
|
+
|
|
4
6
|
interface CharacterTilePair {
|
|
5
7
|
character: string | null;
|
|
6
8
|
tile: Tile | null;
|
|
7
9
|
}
|
|
8
10
|
|
|
9
|
-
const zipCharactersAndTiles = (characters:
|
|
11
|
+
const zipCharactersAndTiles = (characters: Rack, tiles: Tile[]): CharacterTilePair[] => {
|
|
10
12
|
let remainingTiles = [...tiles];
|
|
11
13
|
|
|
12
14
|
return characters.map((character) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FunctionComponent } from 'react';
|
|
1
|
+
import { FunctionComponent, memo } from 'react';
|
|
2
2
|
|
|
3
3
|
import { Dictionary, DictionaryInput, Modal } from 'components';
|
|
4
4
|
import { useTranslate } from 'state';
|
|
@@ -24,4 +24,4 @@ const DictionaryModal: FunctionComponent<Props> = ({ className, isOpen, onClose
|
|
|
24
24
|
);
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
export default DictionaryModal;
|
|
27
|
+
export default memo(DictionaryModal);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FunctionComponent } from 'react';
|
|
1
|
+
import { FunctionComponent, memo } from 'react';
|
|
2
2
|
|
|
3
3
|
import { Modal } from 'components';
|
|
4
4
|
import { useTranslate } from 'state';
|
|
@@ -35,4 +35,4 @@ const KeyMapModal: FunctionComponent<Props> = ({ className, isOpen, onClose }) =
|
|
|
35
35
|
);
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
export default KeyMapModal;
|
|
38
|
+
export default memo(KeyMapModal);
|
|
@@ -23,11 +23,35 @@
|
|
|
23
23
|
justify-content: space-between;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
.
|
|
27
|
-
|
|
26
|
+
.settingsLabel {
|
|
27
|
+
@include ellipsis;
|
|
28
|
+
|
|
29
|
+
--quatar-flag-aspect-ratio: 2.545;
|
|
30
|
+
--highest-flag-aspect-ratio: var(--quatar-flag-aspect-ratio);
|
|
31
|
+
--aspect-ratio: var(--highest-flag-aspect-ratio);
|
|
32
|
+
--padding: calc(var(--spacing--l) + var(--button--icon--size) * var(--aspect-ratio));
|
|
33
|
+
|
|
34
|
+
[dir='ltr'] & {
|
|
35
|
+
padding-right: var(--padding);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
[dir='rtl'] & {
|
|
39
|
+
padding-left: var(--padding);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
28
42
|
|
|
29
|
-
|
|
30
|
-
|
|
43
|
+
.flag {
|
|
44
|
+
position: fixed;
|
|
45
|
+
width: calc(var(--button--icon--size) * var(--aspect-ratio));
|
|
46
|
+
height: var(--button--icon--size);
|
|
31
47
|
border-radius: var(--border--radius);
|
|
32
48
|
box-shadow: 0 0 0 1px var(--box-shadow--color);
|
|
49
|
+
|
|
50
|
+
[dir='ltr'] & {
|
|
51
|
+
right: calc(2 * var(--spacing--l));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
[dir='rtl'] & {
|
|
55
|
+
left: calc(2 * var(--spacing--l));
|
|
56
|
+
}
|
|
33
57
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FunctionComponent } from 'react';
|
|
1
|
+
import { FunctionComponent, memo } from 'react';
|
|
2
2
|
|
|
3
3
|
import { Button, Modal } from 'components';
|
|
4
4
|
import { LOCALE_FLAGS } from 'i18n';
|
|
@@ -18,7 +18,7 @@ interface Props {
|
|
|
18
18
|
onShowWords: () => void;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
const
|
|
21
|
+
const MenuModal: FunctionComponent<Props> = ({
|
|
22
22
|
className,
|
|
23
23
|
isOpen,
|
|
24
24
|
onClose,
|
|
@@ -63,7 +63,7 @@ const Menu: FunctionComponent<Props> = ({
|
|
|
63
63
|
|
|
64
64
|
<Button aria-label={translate('settings')} className={styles.button} Icon={Cog} onClick={onShowSettings}>
|
|
65
65
|
<div className={styles.settings}>
|
|
66
|
-
<
|
|
66
|
+
<div className={styles.settingsLabel}>{translate('settings')}</div>
|
|
67
67
|
<Flag.Icon className={styles.flag} />
|
|
68
68
|
</div>
|
|
69
69
|
</Button>
|
|
@@ -71,4 +71,4 @@ const Menu: FunctionComponent<Props> = ({
|
|
|
71
71
|
);
|
|
72
72
|
};
|
|
73
73
|
|
|
74
|
-
export default
|
|
74
|
+
export default memo(MenuModal);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FunctionComponent } from 'react';
|
|
1
|
+
import { FunctionComponent, memo } from 'react';
|
|
2
2
|
|
|
3
3
|
import { Badge, Modal } from 'components';
|
|
4
4
|
import { LOCALE_FEATURES } from 'i18n';
|
|
@@ -56,4 +56,4 @@ const RemainingTilesModal: FunctionComponent<Props> = ({ className, isOpen, onCl
|
|
|
56
56
|
);
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
-
export default RemainingTilesModal;
|
|
59
|
+
export default memo(RemainingTilesModal);
|
|
@@ -13,12 +13,8 @@
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
.dictionary {
|
|
16
|
-
flex: 0
|
|
16
|
+
flex: 0 0 var(--dictionary--height--mobile);
|
|
17
17
|
background-color: var(--color--background--element);
|
|
18
18
|
border: var(--border);
|
|
19
19
|
border-radius: var(--border--radius);
|
|
20
|
-
|
|
21
|
-
@media (max-height: 600px) {
|
|
22
|
-
display: none;
|
|
23
|
-
}
|
|
24
20
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Result } from '@scrabble-solver/types';
|
|
2
|
-
import { FunctionComponent, useMemo } from 'react';
|
|
2
|
+
import { FunctionComponent, memo, useEffect, useMemo } from 'react';
|
|
3
3
|
import { useDispatch } from 'react-redux';
|
|
4
4
|
|
|
5
5
|
import { Button, Dictionary, Modal, Results } from 'components';
|
|
6
|
+
import { useAppLayout } from 'hooks';
|
|
6
7
|
import { Check, EyeFill } from 'icons';
|
|
7
8
|
import { resultsSlice, selectResultCandidate, selectResults, useTranslate, useTypedSelector } from 'state';
|
|
8
9
|
|
|
@@ -17,6 +18,7 @@ interface Props {
|
|
|
17
18
|
const ResultsModal: FunctionComponent<Props> = ({ className, isOpen, onClose }) => {
|
|
18
19
|
const dispatch = useDispatch();
|
|
19
20
|
const translate = useTranslate();
|
|
21
|
+
const { showResultsInModal } = useAppLayout();
|
|
20
22
|
const results = useTypedSelector(selectResults);
|
|
21
23
|
const resultCandidate = useTypedSelector(selectResultCandidate);
|
|
22
24
|
const index = results ? results.findIndex((result) => result.id === resultCandidate?.id) : -1;
|
|
@@ -49,6 +51,12 @@ const ResultsModal: FunctionComponent<Props> = ({ className, isOpen, onClose })
|
|
|
49
51
|
onClose();
|
|
50
52
|
};
|
|
51
53
|
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
if (isOpen && !showResultsInModal) {
|
|
56
|
+
onClose();
|
|
57
|
+
}
|
|
58
|
+
}, [isOpen, onClose, showResultsInModal]);
|
|
59
|
+
|
|
52
60
|
return (
|
|
53
61
|
<Modal
|
|
54
62
|
className={className}
|
|
@@ -88,4 +96,4 @@ const ResultsModal: FunctionComponent<Props> = ({ className, isOpen, onClose })
|
|
|
88
96
|
);
|
|
89
97
|
};
|
|
90
98
|
|
|
91
|
-
export default ResultsModal;
|
|
99
|
+
export default memo(ResultsModal);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FunctionComponent } from 'react';
|
|
1
|
+
import { FunctionComponent, memo } from 'react';
|
|
2
2
|
|
|
3
3
|
import { Modal } from 'components';
|
|
4
4
|
import { useTranslate } from 'state';
|
|
@@ -31,4 +31,4 @@ const SettingsModal: FunctionComponent<Props> = ({ className, isOpen, onClose })
|
|
|
31
31
|
);
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
-
export default SettingsModal;
|
|
34
|
+
export default memo(SettingsModal);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { AutoGroupTiles } from 'types';
|
|
2
|
+
|
|
1
3
|
import { NULL_VALUE } from './constants';
|
|
2
4
|
|
|
3
|
-
export const parseValue = (value: string):
|
|
5
|
+
export const parseValue = (value: string): AutoGroupTiles => {
|
|
4
6
|
if (value === 'left' || value === 'right') {
|
|
5
7
|
return value;
|
|
6
8
|
}
|
|
@@ -10,17 +10,12 @@
|
|
|
10
10
|
display: flex;
|
|
11
11
|
align-items: center;
|
|
12
12
|
gap: var(--spacing--l);
|
|
13
|
-
font-family: var(--font--family--latin);
|
|
14
|
-
|
|
15
|
-
&.fa {
|
|
16
|
-
font-family: var(--font--family--arabic);
|
|
17
|
-
}
|
|
18
13
|
}
|
|
19
14
|
|
|
20
15
|
.flag {
|
|
21
16
|
--height: 32px;
|
|
22
17
|
|
|
23
|
-
width: calc(var(--height) * var(--aspect
|
|
18
|
+
width: calc(var(--height) * var(--aspect-ratio));
|
|
24
19
|
height: var(--height);
|
|
25
20
|
border-radius: var(--border--radius);
|
|
26
21
|
box-shadow: var(--box-shadow);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import classNames from 'classnames';
|
|
2
|
-
import { FunctionComponent } from 'react';
|
|
2
|
+
import { FunctionComponent, memo } from 'react';
|
|
3
3
|
|
|
4
4
|
import { Badge, Modal } from 'components';
|
|
5
5
|
import { Check, Cross } from 'icons';
|
|
@@ -53,4 +53,4 @@ const WordsModal: FunctionComponent<Props> = ({ className, isOpen, onClose }) =>
|
|
|
53
53
|
);
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
-
export default WordsModal;
|
|
56
|
+
export default memo(WordsModal);
|
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
@import 'styles/mixins';
|
|
2
|
-
|
|
3
|
-
.index {
|
|
4
|
-
display: flex;
|
|
5
|
-
flex-direction: column;
|
|
6
|
-
height: 100%;
|
|
7
|
-
opacity: 0;
|
|
8
|
-
overflow: auto;
|
|
9
|
-
transition: var(--transition--long);
|
|
10
|
-
|
|
11
|
-
&.initialized {
|
|
12
|
-
opacity: 1;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
1
|
.nav {
|
|
17
2
|
position: relative;
|
|
18
3
|
z-index: 1;
|
|
@@ -23,7 +8,7 @@
|
|
|
23
8
|
width: 100%;
|
|
24
9
|
display: flex;
|
|
25
10
|
align-items: flex-start;
|
|
26
|
-
padding: var(--
|
|
11
|
+
padding: var(--nav--padding);
|
|
27
12
|
}
|
|
28
13
|
|
|
29
14
|
.navLogo {
|
|
@@ -36,12 +21,9 @@
|
|
|
36
21
|
}
|
|
37
22
|
|
|
38
23
|
.logo {
|
|
39
|
-
|
|
24
|
+
width: calc(var(--logo--aspect-ratio) * var(--logo--height));
|
|
25
|
+
height: var(--logo--height);
|
|
40
26
|
user-select: none;
|
|
41
|
-
|
|
42
|
-
@include media('<l') {
|
|
43
|
-
height: 48px;
|
|
44
|
-
}
|
|
45
27
|
}
|
|
46
28
|
|
|
47
29
|
.solver {
|
package/src/pages/index.tsx
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import classNames from 'classnames';
|
|
2
1
|
import fs from 'fs';
|
|
3
2
|
import path from 'path';
|
|
4
|
-
import { FunctionComponent,
|
|
3
|
+
import { FunctionComponent, useCallback, useState } from 'react';
|
|
5
4
|
import ReactModal from 'react-modal';
|
|
6
5
|
import { useDispatch } from 'react-redux';
|
|
7
|
-
import { useEffectOnce, useMeasure } from 'react-use';
|
|
8
6
|
|
|
9
|
-
import { Logo,
|
|
10
|
-
import {
|
|
7
|
+
import { Logo, NavButtons, Solver } from 'components';
|
|
8
|
+
import { useDirection, useEffectOnce, useLanguage, useLocalStorage } from 'hooks';
|
|
11
9
|
import { LOCALE_FEATURES } from 'i18n';
|
|
12
10
|
import {
|
|
13
11
|
DictionaryModal,
|
|
@@ -33,7 +31,6 @@ interface Props {
|
|
|
33
31
|
const Index: FunctionComponent<Props> = ({ version }) => {
|
|
34
32
|
const dispatch = useDispatch();
|
|
35
33
|
const locale = useTypedSelector(selectLocale);
|
|
36
|
-
const { showResultsInModal } = useAppLayout();
|
|
37
34
|
const [showDictionary, setShowDictionary] = useState(false);
|
|
38
35
|
const [showKeyMap, setShowKeyMap] = useState(false);
|
|
39
36
|
const [showMenu, setShowMenu] = useState(false);
|
|
@@ -41,38 +38,36 @@ const Index: FunctionComponent<Props> = ({ version }) => {
|
|
|
41
38
|
const [showResults, setShowResults] = useState(false);
|
|
42
39
|
const [showSettings, setShowSettings] = useState(false);
|
|
43
40
|
const [showWords, setShowWords] = useState(false);
|
|
44
|
-
const [isInitialized, setIsInitialized] = useState(false);
|
|
45
|
-
const [indexRef, { height: indexHeight, width: indexWidth }] = useMeasure<HTMLDivElement>();
|
|
46
|
-
const [navRef, { height: navHeight }] = useMeasure<HTMLElement>();
|
|
47
|
-
const solverHeight = indexHeight - navHeight;
|
|
48
|
-
const solverWidth = indexWidth;
|
|
49
41
|
const [isClient, setIsClient] = useState(false);
|
|
50
42
|
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
43
|
+
const handleShowResults = useCallback(() => setShowResults(true), []);
|
|
44
|
+
const handleClear = useCallback(() => dispatch(reset()), [dispatch]);
|
|
45
|
+
const handleHideDictionary = useCallback(() => setShowDictionary(false), []);
|
|
46
|
+
const handleHideKeyMap = useCallback(() => setShowKeyMap(false), []);
|
|
47
|
+
const handleHideMenu = useCallback(() => setShowMenu(false), []);
|
|
48
|
+
const handleHideRemainingTiles = useCallback(() => setShowRemainingTiles(false), []);
|
|
49
|
+
const handleHideResults = useCallback(() => setShowResults(false), []);
|
|
50
|
+
const handleHideSettings = useCallback(() => setShowSettings(false), []);
|
|
51
|
+
const handleHideWords = useCallback(() => setShowWords(false), []);
|
|
52
|
+
const handleShowDictionary = useCallback(() => setShowDictionary(true), []);
|
|
53
|
+
const handleShowKeyMap = useCallback(() => setShowKeyMap(true), []);
|
|
54
|
+
const handleShowMenu = useCallback(() => setShowMenu(true), []);
|
|
55
|
+
const handleShowRemainingTiles = useCallback(() => setShowRemainingTiles(true), []);
|
|
56
|
+
const handleShowSettings = useCallback(() => setShowSettings(true), []);
|
|
57
|
+
const handleShowWords = useCallback(() => setShowWords(true), []);
|
|
54
58
|
|
|
55
59
|
useDirection(LOCALE_FEATURES[locale].direction);
|
|
56
60
|
useLanguage(locale);
|
|
57
61
|
useLocalStorage();
|
|
58
62
|
|
|
59
63
|
useEffectOnce(() => {
|
|
60
|
-
setIsClient(true);
|
|
61
|
-
dispatch(initialize());
|
|
62
|
-
setIsInitialized(true);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
useEffect(() => {
|
|
66
|
-
if (!showResultsInModal) {
|
|
67
|
-
setShowResults(false);
|
|
68
|
-
}
|
|
69
|
-
}, [showResultsInModal]);
|
|
70
|
-
|
|
71
|
-
useEffect(() => {
|
|
72
64
|
if (process.env.NODE_ENV === 'production') {
|
|
73
65
|
registerServiceWorker();
|
|
74
66
|
}
|
|
75
|
-
|
|
67
|
+
|
|
68
|
+
setIsClient(true);
|
|
69
|
+
dispatch(initialize());
|
|
70
|
+
});
|
|
76
71
|
|
|
77
72
|
if (!isClient) {
|
|
78
73
|
return null;
|
|
@@ -80,60 +75,47 @@ const Index: FunctionComponent<Props> = ({ version }) => {
|
|
|
80
75
|
|
|
81
76
|
return (
|
|
82
77
|
<>
|
|
83
|
-
<
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
<a className={styles.logoContainer} href="/" title={version}>
|
|
90
|
-
<Logo className={styles.logo} />
|
|
91
|
-
</a>
|
|
92
|
-
</div>
|
|
93
|
-
|
|
94
|
-
<NavButtons
|
|
95
|
-
onClear={handleClear}
|
|
96
|
-
onShowKeyMap={() => setShowKeyMap(true)}
|
|
97
|
-
onShowMenu={() => setShowMenu(true)}
|
|
98
|
-
onShowRemainingTiles={() => setShowRemainingTiles(true)}
|
|
99
|
-
onShowSettings={() => setShowSettings(true)}
|
|
100
|
-
onShowWords={() => setShowWords(true)}
|
|
101
|
-
/>
|
|
78
|
+
<nav className={styles.nav}>
|
|
79
|
+
<div className={styles.navContent}>
|
|
80
|
+
<div className={styles.navLogo}>
|
|
81
|
+
<a className={styles.logoContainer} href="/" title={version}>
|
|
82
|
+
<Logo className={styles.logo} />
|
|
83
|
+
</a>
|
|
102
84
|
</div>
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
85
|
+
|
|
86
|
+
<NavButtons
|
|
87
|
+
onClear={handleClear}
|
|
88
|
+
onShowKeyMap={handleShowKeyMap}
|
|
89
|
+
onShowMenu={handleShowMenu}
|
|
90
|
+
onShowRemainingTiles={handleShowRemainingTiles}
|
|
91
|
+
onShowSettings={handleShowSettings}
|
|
92
|
+
onShowWords={handleShowWords}
|
|
111
93
|
/>
|
|
112
|
-
|
|
113
|
-
</
|
|
94
|
+
</div>
|
|
95
|
+
</nav>
|
|
96
|
+
|
|
97
|
+
<Solver className={styles.solver} onShowResults={handleShowResults} />
|
|
114
98
|
|
|
115
99
|
<MenuModal
|
|
116
100
|
isOpen={showMenu}
|
|
117
|
-
onClose={
|
|
118
|
-
onShowDictionary={
|
|
119
|
-
onShowRemainingTiles={
|
|
120
|
-
onShowSettings={
|
|
121
|
-
onShowWords={
|
|
101
|
+
onClose={handleHideMenu}
|
|
102
|
+
onShowDictionary={handleShowDictionary}
|
|
103
|
+
onShowRemainingTiles={handleShowRemainingTiles}
|
|
104
|
+
onShowSettings={handleShowSettings}
|
|
105
|
+
onShowWords={handleShowWords}
|
|
122
106
|
/>
|
|
123
107
|
|
|
124
|
-
<SettingsModal isOpen={showSettings} onClose={
|
|
125
|
-
|
|
126
|
-
<KeyMapModal isOpen={showKeyMap} onClose={() => setShowKeyMap(false)} />
|
|
108
|
+
<SettingsModal isOpen={showSettings} onClose={handleHideSettings} />
|
|
127
109
|
|
|
128
|
-
<
|
|
110
|
+
<KeyMapModal isOpen={showKeyMap} onClose={handleHideKeyMap} />
|
|
129
111
|
|
|
130
|
-
<
|
|
112
|
+
<WordsModal isOpen={showWords} onClose={handleHideWords} />
|
|
131
113
|
|
|
132
|
-
<
|
|
114
|
+
<RemainingTilesModal isOpen={showRemainingTiles} onClose={handleHideRemainingTiles} />
|
|
133
115
|
|
|
134
|
-
<
|
|
116
|
+
<ResultsModal isOpen={showResults} onClose={handleHideResults} />
|
|
135
117
|
|
|
136
|
-
<
|
|
118
|
+
<DictionaryModal isOpen={showDictionary} onClose={handleHideDictionary} />
|
|
137
119
|
</>
|
|
138
120
|
);
|
|
139
121
|
};
|
package/src/parameters/index.ts
CHANGED
|
@@ -19,8 +19,14 @@ export const COLOR_GREEN = '#bae3ba';
|
|
|
19
19
|
export const COLOR_RED = '#f7c2aa';
|
|
20
20
|
export const COLOR_YELLOW = '#efe3ae';
|
|
21
21
|
|
|
22
|
-
export const
|
|
23
|
-
export const
|
|
22
|
+
export const SPACING_XS = 2;
|
|
23
|
+
export const SPACING_S = 5;
|
|
24
|
+
export const SPACING_M = 10;
|
|
25
|
+
export const SPACING_L = 20;
|
|
26
|
+
export const SPACING_XL = 40;
|
|
27
|
+
|
|
28
|
+
export const COMPONENTS_SPACING = SPACING_XL;
|
|
29
|
+
export const COMPONENTS_SPACING_SMALL = SPACING_L;
|
|
24
30
|
|
|
25
31
|
export const BOARD_CELL_ACTIONS_OFFSET = 3;
|
|
26
32
|
export const BOARD_CELL_BORDER_WIDTH = 1;
|
|
@@ -36,6 +42,23 @@ export const BOARD_TILE_SIZE_MIN = 20;
|
|
|
36
42
|
|
|
37
43
|
export const BORDER_WIDTH = 1;
|
|
38
44
|
|
|
45
|
+
export const BUTTON_ICON_SIZE = 24;
|
|
46
|
+
export const BUTTON_PADDING_VERTICAL = SPACING_M;
|
|
47
|
+
export const BUTTON_HEIGHT = BUTTON_ICON_SIZE + 2 * BUTTON_PADDING_VERTICAL + 2 * BORDER_WIDTH;
|
|
48
|
+
|
|
49
|
+
export const DICTIONARY_HEIGHT = 260;
|
|
50
|
+
export const DICTIONARY_HEIGHT_MOBILE = 110;
|
|
51
|
+
|
|
52
|
+
export const LOGO_ASPECT_RATIO = 682 / 166;
|
|
53
|
+
export const LOGO_HEIGHT = 60;
|
|
54
|
+
export const LOGO_HEIGHT_SMALL = 48;
|
|
55
|
+
export const LOGO_SRC = '/logo.svg';
|
|
56
|
+
|
|
57
|
+
export const MODAL_WIDTH = 370;
|
|
58
|
+
export const MODAL_HEADER_HEIGHT = 45;
|
|
59
|
+
|
|
60
|
+
export const NAV_PADDING = SPACING_L;
|
|
61
|
+
|
|
39
62
|
export const TILE_SIZE = 80;
|
|
40
63
|
|
|
41
64
|
export const PLAIN_TILES_COLOR_DEFAULT = COLOR_GREEN;
|
|
@@ -67,10 +90,14 @@ export const RACK_TILE_SIZE_MAX = 80;
|
|
|
67
90
|
|
|
68
91
|
export const REMAINING_TILES_TILE_SIZE = 50;
|
|
69
92
|
|
|
93
|
+
export const RESULTS_HEADER_HEIGHT = 35;
|
|
94
|
+
|
|
70
95
|
export const RESULTS_ITEM_HEIGHT = 40;
|
|
71
96
|
|
|
72
97
|
export const SOLVER_COLUMN_WIDTH = 580;
|
|
73
98
|
|
|
99
|
+
export const TEXT_INPUT_HEIGHT = 40;
|
|
100
|
+
|
|
74
101
|
export const TILE_APPEAR_DURATION = 200;
|
|
75
102
|
|
|
76
103
|
export const TILE_APPEAR_KEYFRAMES = [
|