Browse Source

initial commit

pull/1/head
Sergey Verevkin 4 years ago
parent
commit
057f56d8f7
  1. 8
      .editorconfig
  2. 1
      .env
  3. 52
      .gitignore
  4. 5
      .idea/.gitignore
  5. 8
      .idea/modules.xml
  6. 12
      .idea/ooya.ga.iml
  7. 6
      .idea/vcs.xml
  8. 8
      README.md
  9. 48
      package.json
  10. BIN
      public/favicon.ico
  11. 43
      public/index.html
  12. BIN
      public/logo192.png
  13. BIN
      public/logo512.png
  14. 25
      public/manifest.json
  15. 3
      public/robots.txt
  16. 39
      src/components/App/App.css
  17. 31
      src/components/App/App.tsx
  18. 0
      src/components/GamePage/GamePage.css
  19. 46
      src/components/GamePage/GamePage.tsx
  20. 0
      src/components/IntroPage/IntroPage.css
  21. 19
      src/components/IntroPage/IntroPage.tsx
  22. 13
      src/index.css
  23. 17
      src/index.tsx
  24. 7
      src/model/Game.ts
  25. 7
      src/model/GameDto.ts
  26. 5
      src/model/Witch.ts
  27. 5
      src/model/WitchDto.ts
  28. 13
      src/reportWebVitals.js
  29. 206
      src/resources/witch.svg
  30. 5
      src/setupTests.js
  31. 38
      src/store/apiStore/apiStore.service.ts
  32. 131
      src/store/apiStore/apiStore.ts
  33. 23
      src/store/mapper.ts
  34. 40
      src/store/tool.ts
  35. 26
      tsconfig.json
  36. 8754
      yarn.lock

8
.editorconfig

@ -0,0 +1,8 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
indent_style = space
indent_size = 2

1
.env

@ -0,0 +1 @@
REACT_APP_API_URL=http://127.0.0.1:8000/api

52
.gitignore

@ -1,39 +1,23 @@
# ---> macOS # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails # dependencies
._* /node_modules
/.pnp
.pnp.js
# Files that might appear in the root of a volume # testing
.DocumentRevisions-V100 /coverage
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share # production
.AppleDB /build
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# ---> VisualStudioCode # misc
.vscode/* .DS_Store
!.vscode/settings.json .env.local
!.vscode/tasks.json .env.development.local
!.vscode/launch.json .env.test.local
!.vscode/extensions.json .env.production.local
*.code-workspace
# Local History for Visual Studio Code
.history/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

5
.idea/.gitignore

@ -0,0 +1,5 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/

8
.idea/modules.xml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/ooya.ga.iml" filepath="$PROJECT_DIR$/.idea/ooya.ga.iml" />
</modules>
</component>
</project>

12
.idea/ooya.ga.iml

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/vcs.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

8
README.md

@ -1,2 +1,10 @@
# ooya.ga # ooya.ga
ООП игра Яга для тренировки ПИб-201 и ПИб-202 КузГТУ
Игра работает с локальным сервером, который Вы сами напишете.
Требования к api:
- реализация _./swagger_file_
- CORS должен принимать любые домены
## Удачи!

48
package.json

@ -0,0 +1,48 @@
{
"name": "www",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.4.0",
"@types/lodash": "^4.14.178",
"@types/node": "^17.0.15",
"@types/react": "^17.0.39",
"@types/react-dom": "^17.0.11",
"axios": "^0.25.0",
"lodash": "^4.17.21",
"mobx": "^6.3.13",
"mobx-observer": "^0.1.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "5.0.0",
"typescript": "^4.5.5",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

BIN
public/favicon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

43
public/index.html

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Object oriented yaga"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Object-oriented yaga</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

BIN
public/logo192.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
public/logo512.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

25
public/manifest.json

@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

3
public/robots.txt

@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

39
src/components/App/App.css

@ -0,0 +1,39 @@
.App {
text-align: center;
}
.App-logo {
height: 50vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 10s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
cursor: pointer;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

31
src/components/App/App.tsx

@ -0,0 +1,31 @@
import './App.css';
import IntroPage from '../IntroPage/IntroPage';
import GamePage from '../GamePage/GamePage';
import apiStore, { EGameStage } from '../../store/apiStore/apiStore';
type AppProps = {
onEnterGame?: () => void,
};
const App: React.FC<AppProps> = observer((props) => {
let content = <></>;
switch (apiStore.gameStage) {
case EGameStage.Start: {
content = <IntroPage onEnterGame={() => {
apiStore.startNewGame();
} } />;
break;
}
case EGameStage.Process: {
content = <GamePage onExitGame={() => apiStore.setGameStage(EGameStage.Start) } />;
break;
}
}
return (
<div className="App">
{content}
</div>
);
});
export default App;

0
src/components/GamePage/GamePage.css

46
src/components/GamePage/GamePage.tsx

@ -0,0 +1,46 @@
import _ from 'lodash';
// @ts-ignore
import witch from '../../resources/witch.svg';
import './GamePage.css';
import { Witch } from '../../model/Witch';
import apiStore from '../../store/apiStore/apiStore';
type GameProps = {
onExitGame: () => void,
};
const GamePage: React.FC<GameProps> = (props) => {
const {onExitGame} = props;
const clickAtWitch = (guid: string) => {
apiStore.turn(guid)
.then((result) => console.log('check whether witch is lucky: ' + guid + ' // ' + result));
}
return (
<header className="App-header">
<div className='game'>
<div>Score: {apiStore.currentGame?.score}</div>
<div>Score: {apiStore.currentGame?.score}</div>
<div>
{
_.map(apiStore.currentGame?.witches, (item: Witch, index: number) => {
const left = item.position * 100;
return (
<div key={index} style={{position: 'absolute', left}}>
<img src={witch} alt={`witch-${index}`} onClick={() => clickAtWitch(item.guid)}/>
</div>
)
})
}
</div>
</div>
<h1 onClick={() => onExitGame()}> Стоп игра! </h1>
<div>
<label htmlFor='hasServer'>У меня, кажется, есть свой сервер!</label>
<input type='checkbox' id='hasServer' checked={!apiStore.mockMode}/> </div>
</header>
);
}
export default GamePage;

0
src/components/IntroPage/IntroPage.css

19
src/components/IntroPage/IntroPage.tsx

@ -0,0 +1,19 @@
// @ts-ignore
import witch from '../../resources/witch.svg';
import './IntroPage.css';
type IntroProps = {
onEnterGame: () => void,
};
const IntroPage: React.FC<IntroProps> = (props) => {
const {onEnterGame} = props;
return (
<header className="App-header">
<img src={witch} className="App-logo" alt="logo" />
<h1 onClick={() => onEnterGame()}> Начать играть! </h1>
</header>
);
}
export default IntroPage;

13
src/index.css

@ -0,0 +1,13 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}

17
src/index.tsx

@ -0,0 +1,17 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App/App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

7
src/model/Game.ts

@ -0,0 +1,7 @@
import { Witch } from './Witch';
export type Game = {
guid: string,
score: number,
witches: Witch[],
};

7
src/model/GameDto.ts

@ -0,0 +1,7 @@
import { IWitchDto } from './WitchDto';
export type IGameDto = {
guid: string,
score: number,
witches: IWitchDto[],
};

5
src/model/Witch.ts

@ -0,0 +1,5 @@
export type Witch = {
flagReal: boolean,
guid: string,
position: number,
};

5
src/model/WitchDto.ts

@ -0,0 +1,5 @@
export interface IWitchDto {
guid: string,
flagReal: boolean,
position: number,
};

13
src/reportWebVitals.js

@ -0,0 +1,13 @@
const reportWebVitals = onPerfEntry => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;

206
src/resources/witch.svg

@ -0,0 +1,206 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="1280.000000pt" height="1009.000000pt" viewBox="0 0 1280.000000 1009.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.15, written by Peter Selinger 2001-2017
</metadata>
<g transform="translate(0.000000,1009.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M4710 10076 c0 -9 5 -16 10 -16 6 0 10 4 10 9 0 6 -4 13 -10 16 -5 3
-10 -1 -10 -9z"/>
<path d="M6365 9340 c-3 -6 1 -13 9 -16 9 -3 16 -17 16 -30 0 -14 9 -37 20
-53 20 -26 21 -38 18 -292 -3 -237 -5 -267 -20 -283 -11 -10 -18 -32 -18 -52
0 -20 -6 -42 -14 -49 -7 -8 -17 -39 -20 -69 -4 -31 -12 -58 -17 -61 -5 -4 -9
-22 -9 -41 0 -22 -7 -40 -20 -51 -11 -10 -20 -28 -20 -41 0 -12 -7 -25 -15
-28 -8 -4 -15 -13 -15 -20 0 -8 -7 -17 -15 -20 -8 -4 -15 -12 -15 -20 0 -7
-12 -16 -27 -20 -16 -3 -37 -9 -48 -14 -11 -5 -38 -11 -59 -14 -22 -3 -42 -10
-46 -16 -4 -7 -27 -14 -51 -17 -24 -3 -52 -14 -62 -24 -10 -11 -30 -19 -45
-19 -15 0 -36 -7 -46 -15 -11 -8 -27 -15 -36 -15 -9 0 -35 -18 -59 -40 -24
-23 -56 -47 -72 -56 -16 -8 -29 -19 -29 -24 0 -6 -5 -10 -11 -10 -21 0 -110
-97 -119 -131 -17 -59 -14 -69 25 -69 24 0 35 5 35 14 0 8 21 25 48 38 26 13
51 29 55 35 4 7 18 13 30 13 12 0 28 9 35 20 9 14 23 20 51 20 22 0 44 6 51
15 9 11 33 15 86 15 71 0 75 -1 86 -26 11 -24 10 -29 -10 -42 -12 -8 -22 -22
-22 -31 0 -22 -19 -41 -40 -41 -25 0 -158 -134 -166 -167 -4 -15 -11 -34 -17
-40 -5 -7 -22 -39 -38 -70 -37 -75 -48 -91 -85 -124 -17 -15 -60 -58 -97 -94
-37 -36 -82 -72 -102 -81 -19 -8 -35 -19 -35 -24 0 -15 -27 -12 -61 6 -22 11
-34 12 -43 5 -16 -14 -64 7 -72 32 -4 12 -16 17 -45 17 -21 0 -39 -4 -39 -9 0
-5 18 -28 39 -50 35 -37 44 -41 87 -41 l47 0 -7 -62 c-5 -50 -12 -68 -35 -93
-24 -25 -29 -41 -35 -104 -4 -44 -13 -82 -21 -91 -8 -9 -15 -20 -15 -24 0 -20
-95 -128 -122 -139 -10 -3 -18 -11 -18 -16 0 -5 -13 -23 -30 -39 -30 -30 -38
-56 -21 -66 5 -3 11 1 15 9 3 8 17 15 31 15 14 0 34 9 45 20 11 11 32 20 47
20 47 0 111 32 118 59 3 13 17 32 30 43 13 10 29 34 35 52 6 19 17 37 25 40 8
3 15 10 15 16 0 15 38 50 54 50 24 0 46 12 46 24 0 18 125 40 149 26 11 -5 31
-10 45 -10 32 0 42 -17 22 -39 -9 -10 -16 -26 -16 -37 0 -11 -14 -32 -32 -48
-41 -35 -27 -46 60 -46 49 0 66 -4 82 -20 23 -23 25 -35 8 -56 -35 -41 -65
-64 -86 -64 -12 0 -25 -7 -28 -15 -4 -8 -12 -15 -20 -15 -7 0 -21 -11 -30 -25
-9 -13 -24 -27 -35 -30 -27 -9 -75 -56 -83 -82 -4 -11 -38 -53 -76 -92 -60
-61 -75 -71 -105 -71 -21 0 -41 -7 -52 -19 -20 -21 -86 -51 -112 -51 -9 0 -29
-7 -44 -15 -16 -8 -65 -18 -110 -21 -57 -5 -86 -12 -94 -23 -10 -14 -12 -14
-18 2 -10 23 -31 22 -38 -3 -3 -11 -14 -20 -25 -20 -32 0 -89 -28 -121 -59
-18 -18 -46 -32 -70 -36 -23 -4 -43 -10 -46 -15 -3 -4 -25 -11 -49 -14 -24 -4
-50 -14 -56 -21 -8 -10 -32 -15 -70 -15 -37 0 -62 -5 -69 -14 -26 -31 -98 -48
-183 -43 -97 6 -202 27 -220 45 -7 7 -41 12 -91 12 l-79 0 6 -26 c7 -27 10
-31 64 -90 17 -19 32 -42 32 -50 0 -8 9 -22 20 -31 11 -10 20 -23 20 -29 0 -7
20 -21 45 -33 25 -12 45 -26 45 -31 0 -6 13 -10 29 -10 16 0 36 -7 44 -15 12
-11 57 -16 204 -21 199 -7 214 -11 283 -64 19 -15 49 -34 66 -43 17 -9 47 -32
66 -51 49 -49 135 -76 241 -76 50 0 102 6 127 15 56 20 141 19 205 -2 39 -13
60 -28 89 -66 33 -41 39 -57 43 -110 6 -85 -12 -326 -26 -340 -17 -17 -14
-178 4 -214 9 -19 17 -76 21 -154 4 -68 11 -131 15 -141 5 -9 12 -47 15 -86 5
-56 12 -75 34 -101 16 -17 31 -49 35 -70 8 -47 56 -101 116 -130 26 -12 49
-31 52 -41 3 -13 14 -20 30 -20 14 0 27 -7 31 -15 3 -8 11 -15 17 -15 20 0 59
-45 59 -69 0 -23 -41 -71 -61 -71 -5 0 -12 -7 -15 -15 -4 -10 -20 -15 -48 -15
-29 0 -47 -6 -59 -20 -12 -14 -29 -20 -59 -20 -45 -1 -142 -30 -161 -49 -6 -6
-22 -11 -36 -11 -13 0 -32 -6 -40 -14 -9 -8 -38 -19 -66 -25 -79 -16 -158 -40
-169 -51 -5 -5 -24 -10 -41 -10 -18 0 -42 -9 -55 -20 -13 -11 -37 -20 -56 -20
-18 0 -45 -7 -61 -15 -15 -8 -49 -17 -75 -20 -27 -4 -48 -10 -48 -14 0 -5 -22
-11 -49 -15 -27 -3 -54 -13 -61 -21 -7 -8 -23 -15 -36 -15 -13 0 -48 -13 -78
-29 -30 -17 -71 -33 -93 -37 -21 -3 -42 -10 -48 -14 -12 -10 -130 -50 -147
-50 -7 -1 -31 -9 -53 -20 -22 -11 -54 -19 -72 -20 -17 0 -33 -5 -35 -12 -2 -6
-24 -17 -49 -23 -62 -18 -112 -38 -127 -53 -7 -6 -31 -12 -52 -12 -22 0 -42
-6 -47 -14 -8 -13 -120 -56 -147 -56 -7 0 -19 -7 -26 -15 -7 -8 -28 -15 -48
-15 -19 0 -44 -7 -53 -16 -10 -9 -35 -20 -56 -25 -75 -16 -133 -35 -145 -47
-7 -7 -29 -12 -49 -12 -21 0 -41 -5 -45 -11 -11 -19 -94 -49 -152 -55 -32 -4
-66 -12 -77 -19 -11 -6 -40 -15 -64 -18 -24 -3 -47 -11 -51 -17 -4 -6 -27 -14
-51 -17 -24 -3 -48 -9 -54 -13 -5 -5 -27 -11 -48 -15 -20 -4 -41 -13 -45 -20
-4 -6 -36 -15 -71 -19 -36 -3 -72 -13 -81 -21 -22 -20 -128 -20 -156 -1 -11 8
-38 18 -60 21 -21 4 -45 13 -53 19 -18 14 -209 15 -219 0 -4 -6 -35 -14 -70
-17 -34 -4 -72 -13 -85 -21 -15 -9 -73 -16 -187 -21 -90 -3 -169 -10 -175 -14
-5 -5 -21 -12 -35 -16 -13 -4 -30 -13 -37 -19 -7 -6 -19 -16 -26 -23 -8 -6
-48 -15 -88 -19 -40 -4 -80 -13 -87 -21 -7 -7 -20 -13 -27 -13 -7 0 -21 -7
-30 -16 -8 -9 -34 -18 -57 -21 -22 -4 -64 -21 -92 -40 -28 -18 -58 -33 -67
-33 -9 0 -22 -7 -29 -15 -7 -8 -22 -15 -33 -15 -11 0 -28 -7 -38 -16 -9 -8
-47 -26 -84 -39 -37 -13 -72 -28 -78 -34 -6 -6 -21 -11 -34 -11 -12 0 -27 -9
-33 -20 -6 -11 -16 -20 -21 -20 -6 0 -31 -13 -56 -30 -27 -19 -57 -30 -78 -30
-19 0 -37 -5 -41 -11 -3 -6 -21 -17 -38 -25 -17 -8 -39 -19 -48 -24 -10 -6
-24 -13 -32 -17 -34 -18 -163 -109 -182 -129 -11 -12 -34 -28 -50 -35 -16 -8
-30 -24 -32 -36 -2 -13 -13 -24 -27 -27 -13 -3 -36 -18 -50 -32 -25 -25 -25
-26 -5 -31 14 -4 20 -14 20 -34 0 -15 7 -32 16 -37 15 -8 15 -11 0 -34 -13
-20 -16 -45 -14 -109 3 -76 5 -84 25 -89 37 -9 67 -59 73 -119 5 -52 7 -55 37
-63 17 -4 49 -26 69 -48 21 -22 44 -40 51 -40 19 0 83 -66 83 -85 0 -17 16
-20 25 -5 3 6 34 10 68 10 83 0 137 10 137 25 0 7 12 21 26 31 14 10 35 27 46
37 25 20 32 21 50 4 7 -7 21 -16 30 -20 10 -3 18 -15 18 -26 0 -28 11 -52 21
-45 5 3 9 16 9 29 0 13 7 30 15 39 8 8 15 22 15 30 0 9 9 24 20 33 11 10 20
25 20 34 0 9 9 26 20 39 11 13 20 26 20 29 0 4 18 14 40 24 22 9 63 40 90 67
27 28 59 50 70 50 11 0 23 6 26 14 3 8 14 16 25 19 10 3 19 12 19 19 0 17 29
33 88 48 23 6 42 15 42 20 0 6 6 10 13 10 8 0 22 9 32 20 10 11 31 20 46 20
15 0 30 4 33 9 3 4 27 11 54 15 36 5 56 14 78 37 34 36 101 69 141 69 15 0 40
6 54 14 14 7 56 17 93 20 36 4 66 12 66 16 0 29 134 190 158 190 5 0 12 7 16
15 3 8 23 18 45 21 23 4 46 13 52 20 6 8 23 14 38 14 19 0 32 9 44 29 14 23
27 31 61 36 38 6 45 11 50 36 3 16 12 29 20 29 8 0 18 9 21 20 3 11 10 20 15
20 5 0 11 14 15 30 4 17 10 30 15 30 4 0 11 12 15 27 8 32 44 73 66 73 9 0 26
9 39 20 13 11 37 20 56 20 18 0 39 6 46 13 7 8 40 17 73 21 32 4 62 10 65 15
3 4 26 11 52 15 25 4 52 14 58 21 7 8 23 15 35 15 12 0 38 6 56 14 19 7 55 17
81 20 26 4 50 11 53 16 3 4 24 11 48 15 23 4 49 13 57 20 8 7 31 15 50 19 19
3 62 20 94 36 32 17 73 30 91 30 19 0 35 6 38 14 3 8 23 18 44 21 21 4 47 10
58 15 11 5 35 12 54 16 19 3 41 13 49 20 7 8 31 14 53 14 26 0 42 5 45 15 3 8
22 17 42 21 21 3 51 12 69 20 17 8 35 14 41 14 5 0 15 7 22 15 7 8 28 15 47
15 20 0 46 9 60 20 17 13 41 20 68 20 26 0 48 6 55 15 7 8 23 15 35 15 12 0
28 7 35 15 7 8 28 15 47 15 20 0 46 9 60 20 14 11 36 20 48 20 12 0 39 7 58
15 20 8 49 15 65 15 15 0 37 7 48 15 10 8 29 15 41 15 12 0 29 7 38 16 9 10
33 21 53 25 144 32 177 41 182 48 3 4 24 11 46 14 23 4 54 14 70 22 16 8 43
15 60 15 35 0 150 34 170 51 7 6 37 13 67 16 38 4 54 10 51 18 -3 8 12 14 47
18 29 4 57 11 63 17 5 5 19 10 31 10 11 0 37 9 58 20 20 11 44 20 53 20 8 0
22 7 30 15 18 18 75 20 92 3 7 -7 12 -34 12 -60 0 -43 -3 -50 -26 -58 -14 -6
-42 -24 -62 -40 -20 -17 -42 -30 -48 -30 -6 0 -17 -7 -24 -15 -7 -8 -27 -17
-46 -21 -19 -3 -34 -12 -34 -19 0 -15 -45 -40 -91 -50 -18 -4 -42 -17 -53 -30
-12 -12 -37 -29 -56 -37 -19 -8 -69 -49 -111 -91 -47 -47 -85 -77 -97 -77 -12
0 -26 -9 -32 -20 -6 -11 -21 -20 -33 -20 -13 0 -28 -5 -34 -11 -7 -7 -77 -14
-172 -18 -105 -4 -165 -11 -173 -19 -7 -7 -39 -12 -77 -12 -45 0 -70 -5 -82
-16 -10 -9 -37 -18 -61 -20 -57 -7 -178 -44 -178 -55 0 -5 -7 -9 -15 -9 -9 0
-18 -6 -21 -14 -3 -8 -21 -17 -39 -20 -46 -9 -125 -45 -125 -56 0 -6 -9 -10
-19 -10 -29 0 -51 -11 -51 -25 0 -7 -12 -16 -27 -20 -36 -8 -119 -73 -163
-125 -18 -22 -40 -40 -47 -40 -8 0 -34 -20 -59 -44 -25 -25 -70 -61 -100 -81
-30 -20 -60 -45 -67 -56 -8 -13 -23 -19 -45 -19 -25 0 -35 -5 -39 -20 -4 -15
-11 -18 -28 -14 -33 8 -65 -12 -65 -41 0 -20 5 -25 24 -25 14 0 46 -14 72 -32
41 -28 50 -30 78 -20 17 5 57 13 88 17 31 3 62 13 69 21 7 8 29 14 55 14 23 0
46 5 49 10 4 6 26 20 50 31 38 18 56 20 132 14 218 -15 336 -5 356 31 4 8 12
14 17 14 6 0 19 9 30 20 11 11 33 20 49 20 17 0 32 4 35 9 3 4 59 11 125 14
80 3 131 10 152 21 18 9 53 16 79 16 34 0 52 5 65 20 14 15 31 20 68 20 50 0
135 20 192 45 17 8 54 15 84 18 29 2 57 10 61 17 4 7 34 17 66 21 31 4 60 12
63 17 3 5 36 13 73 16 37 4 70 12 73 17 8 12 478 12 490 0 6 -6 69 -13 140
-17 72 -4 136 -12 144 -18 19 -15 274 -14 292 0 8 6 35 15 62 18 26 4 47 11
47 15 0 5 16 12 35 15 19 4 35 11 35 16 0 5 15 13 33 19 32 11 97 73 97 92 0
5 11 14 25 19 14 5 30 21 35 35 5 14 16 25 25 25 8 0 15 8 15 18 0 26 53 82
78 82 15 0 22 8 27 30 4 17 11 30 15 30 5 0 20 18 32 40 13 22 27 40 32 40 15
0 86 80 86 96 0 7 14 21 32 30 18 9 46 31 64 48 55 55 96 86 120 92 13 3 24 9
24 13 0 8 90 47 133 57 15 3 27 10 27 14 0 5 15 12 33 15 17 4 37 11 42 15 9
8 60 22 185 52 25 6 54 17 65 24 11 8 39 14 64 14 26 0 51 6 61 15 10 9 35 19
56 22 22 3 43 12 47 20 4 7 14 13 21 13 8 0 16 7 20 15 3 10 19 15 46 15 34 0
40 3 40 20 0 25 39 80 57 80 7 0 13 7 13 15 0 8 11 21 24 30 13 8 31 33 41 55
10 22 21 40 25 40 4 0 10 19 13 43 3 23 20 68 36 99 17 32 31 69 31 82 0 14 5
28 11 31 5 4 21 31 35 61 18 41 23 63 18 89 -3 19 -10 35 -14 35 -4 0 -10 14
-13 30 -4 18 -13 30 -22 30 -12 0 -15 13 -15 58 0 32 5 63 12 70 7 7 40 12 78
12 43 0 73 5 86 15 12 9 43 14 85 15 53 0 69 4 84 20 13 14 31 20 61 20 50 0
103 21 159 65 52 40 106 65 142 65 15 0 40 6 54 14 14 7 53 17 85 21 39 5 63
13 71 25 15 21 56 35 126 45 26 3 47 10 47 15 0 4 19 11 43 15 23 4 49 13 57
20 14 12 56 25 150 47 25 6 54 17 65 24 11 8 38 14 61 14 25 0 47 6 54 15 7 8
18 15 24 15 6 0 24 7 39 15 15 8 43 17 62 21 19 3 39 12 46 20 6 8 23 14 37
14 13 0 30 7 36 16 8 10 38 18 86 24 89 10 159 28 181 46 8 8 31 14 49 14 18
0 41 6 49 14 9 7 41 18 71 24 96 19 159 37 172 50 6 6 36 12 65 12 42 0 55 4
65 20 8 12 24 20 40 20 67 0 101 39 96 111 l-3 44 -69 3 c-47 2 -80 -2 -100
-12 -51 -24 -132 -46 -175 -46 -23 0 -46 -7 -56 -17 -9 -9 -39 -18 -68 -21
-29 -2 -59 -11 -68 -19 -10 -8 -42 -17 -73 -20 -31 -3 -61 -12 -67 -19 -6 -8
-28 -14 -49 -14 -21 0 -43 -7 -50 -15 -7 -8 -22 -15 -34 -15 -12 0 -27 -5 -33
-11 -14 -14 -102 -44 -154 -53 -21 -4 -42 -13 -49 -21 -7 -8 -28 -15 -48 -15
-19 0 -40 -6 -46 -14 -6 -7 -31 -19 -56 -25 -25 -7 -63 -17 -85 -23 -22 -6
-47 -17 -56 -24 -8 -8 -36 -14 -60 -14 -32 0 -49 -6 -62 -20 -9 -11 -29 -20
-45 -20 -15 0 -32 -4 -37 -9 -6 -5 -27 -14 -47 -21 -21 -6 -38 -16 -38 -21 0
-5 -19 -9 -43 -9 -23 0 -59 -9 -80 -20 -20 -11 -53 -20 -72 -20 -20 0 -52 -7
-72 -15 -19 -8 -47 -15 -62 -15 -14 0 -38 -6 -52 -13 -14 -8 -44 -17 -68 -21
-24 -3 -50 -13 -58 -21 -21 -22 -265 -22 -287 0 -8 8 -35 18 -61 22 -25 3 -48
10 -51 14 -3 5 -26 18 -51 29 -26 11 -53 29 -60 40 -8 11 -21 20 -30 20 -8 0
-32 14 -53 30 -21 17 -45 30 -54 30 -8 0 -20 9 -26 20 -6 11 -18 20 -26 20 -9
0 -33 14 -54 30 -21 17 -46 30 -57 30 -10 0 -24 9 -31 20 -7 11 -19 20 -28 20
-9 0 -33 13 -53 28 -20 16 -43 33 -52 38 -21 11 -106 82 -134 112 -12 12 -29
22 -36 22 -8 0 -46 34 -86 75 -39 41 -75 75 -81 75 -5 0 -27 23 -48 50 -21 28
-41 50 -45 50 -4 0 -18 17 -30 38 -13 20 -45 59 -71 86 -28 28 -48 57 -48 70
0 14 -19 38 -50 65 -32 28 -50 51 -50 65 0 13 -12 33 -26 47 -14 13 -39 51
-55 84 -27 57 -54 98 -139 211 -22 29 -42 65 -46 80 -7 27 -34 72 -61 102 -7
7 -13 22 -13 33 0 10 -6 19 -14 19 -15 0 -56 58 -56 79 0 7 -7 19 -15 27 -8 9
-15 24 -15 35 0 11 -7 27 -15 35 -9 10 -15 34 -15 63 0 31 5 53 15 61 8 7 15
19 15 28 0 9 10 31 23 49 l22 33 102 0 c72 0 106 -4 115 -13 30 -31 148 -32
148 -2 0 7 8 16 18 20 16 6 16 7 0 16 -10 6 -18 14 -18 19 0 6 -9 19 -20 30
-18 18 -20 33 -20 135 0 102 2 117 20 135 23 23 26 55 6 67 -7 4 -21 25 -30
45 -16 34 -17 38 -1 62 27 40 81 36 128 -9 23 -22 46 -35 63 -35 l27 0 -7 68
c-11 110 -58 202 -103 202 -8 0 -21 16 -29 35 -8 19 -19 35 -24 35 -6 0 -10 6
-10 14 0 8 -9 18 -20 21 -32 10 -28 79 8 110 31 27 86 33 111 11 9 -7 36 -19
61 -25 25 -7 63 -17 85 -23 22 -6 47 -17 56 -24 8 -8 23 -14 31 -14 9 0 35
-16 58 -35 23 -19 52 -35 64 -35 12 0 31 -7 42 -15 27 -20 30 -19 54 20 l22
35 -23 46 c-22 46 -148 184 -168 184 -5 0 -14 6 -18 13 -4 7 -20 18 -35 24
-16 7 -28 17 -28 23 0 5 -7 10 -15 10 -9 0 -18 7 -21 15 -4 8 -16 15 -28 15
-11 0 -31 11 -44 25 -22 23 -77 45 -113 45 -8 0 -24 7 -35 15 -10 8 -27 15
-37 15 -11 0 -31 6 -45 14 -15 8 -35 17 -44 20 -11 3 -18 15 -18 30 0 14 -7
29 -16 34 -17 9 -47 89 -59 157 -4 22 -10 45 -15 50 -4 6 -11 21 -15 35 -4 13
-14 30 -21 38 -8 7 -14 23 -14 34 0 19 -35 86 -51 98 -3 3 -10 16 -14 29 -4
14 -11 29 -16 35 -41 49 -49 61 -54 76 -3 10 -12 21 -20 24 -8 3 -15 12 -15
21 0 8 -4 15 -10 15 -13 0 -90 77 -90 89 0 5 -9 13 -20 16 -11 3 -20 12 -20
19 0 14 -27 44 -60 66 -33 22 -100 89 -100 99 0 10 -24 21 -46 21 -8 0 -37 23
-65 50 -28 28 -59 50 -69 50 -10 0 -21 8 -24 18 -3 10 -26 26 -51 36 -25 11
-50 25 -56 33 -13 15 -115 18 -124 3z m885 -3200 c11 -11 20 -25 20 -31 0 -6
15 -29 34 -52 18 -23 41 -57 50 -74 9 -18 20 -33 25 -33 10 0 91 -105 91 -118
0 -5 9 -17 20 -27 16 -14 20 -29 18 -59 -3 -35 -7 -42 -27 -44 -15 -2 -28 3
-33 12 -5 9 -16 16 -23 16 -8 0 -15 7 -15 15 0 9 -8 19 -17 22 -10 4 -22 12
-26 20 -4 7 -19 13 -32 13 -14 0 -26 7 -30 19 -3 11 -12 22 -20 25 -8 3 -15
12 -15 19 0 8 -15 30 -32 50 -54 60 -58 66 -78 110 -30 64 -25 117 10 117 11
0 22 5 25 10 10 16 33 12 55 -10z m-376 -571 c16 -13 46 -41 68 -61 21 -21 51
-44 66 -52 15 -8 37 -25 49 -38 30 -32 41 -40 93 -67 24 -13 51 -32 58 -42 9
-13 25 -19 50 -19 27 0 46 -9 71 -30 18 -17 44 -30 56 -30 12 0 34 -9 48 -20
14 -11 34 -20 45 -20 12 0 23 -4 26 -9 11 -17 87 -51 115 -51 16 0 40 -9 54
-20 14 -11 33 -20 43 -20 9 0 25 -6 33 -13 9 -7 50 -23 91 -36 41 -12 82 -27
90 -32 8 -5 23 -12 33 -15 9 -4 17 -10 17 -15 0 -5 12 -15 28 -21 70 -29 112
-50 112 -58 0 -4 21 -10 46 -13 26 -2 49 -9 53 -14 5 -7 43 -25 119 -54 12 -5
22 -13 22 -19 0 -5 8 -10 19 -10 10 0 29 -8 42 -18 13 -10 32 -21 42 -25 9 -4
21 -17 27 -31 5 -13 14 -27 19 -31 6 -3 11 -25 11 -48 0 -50 -36 -97 -75 -97
-13 0 -26 -4 -29 -9 -3 -5 -30 -12 -60 -15 -30 -4 -60 -14 -67 -22 -6 -8 -24
-14 -39 -14 -16 0 -30 -7 -34 -15 -4 -11 -22 -15 -74 -15 -50 0 -73 4 -82 15
-8 10 -31 15 -71 15 -38 0 -63 5 -73 15 -8 8 -21 15 -28 15 -25 0 -178 52
-178 61 0 5 -15 9 -32 9 -18 0 -45 6 -59 14 -15 7 -71 17 -125 21 -83 5 -139
17 -209 42 -5 2 -30 14 -54 28 -25 14 -74 30 -110 35 -72 12 -151 38 -151 51
0 4 -14 11 -32 14 -40 9 -138 105 -138 135 0 13 -8 24 -18 27 -24 6 -42 49
-53 130 -5 37 -14 72 -19 77 -6 6 -10 75 -10 157 0 118 3 149 15 159 10 8 15
30 15 61 0 35 5 51 18 59 27 17 94 6 126 -21z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 14 KiB

5
src/setupTests.js

@ -0,0 +1,5 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';

38
src/store/apiStore/apiStore.service.ts

@ -0,0 +1,38 @@
/**
* @file Сервис для источника данных
* @version 2022.01.26
* @author Verevkin S.A.
* @copyright Verevkin S.A.
*/
import tool from '../tool';
import { Game } from '../../model/Game';
import { IGameDto } from '../../model/GameDto';
import { Mapper } from '../mapper';
const service = {
// region Публичные функции
async getGame(): Promise<Game | undefined> {
const resultPromise = tool.get<IGameDto>('/game', {});
return resultPromise.then((response: IGameDto | undefined): (Game | undefined) => {
if (!response) return;
return Mapper.fromGame(response);
});
},
async gameTurn(gameGuid: string, witchGuid: string): Promise<Game | undefined> {
const resultPromise = tool.get<IGameDto>('/turn', {
gameGuid, witchGuid
});
return resultPromise.then((response: IGameDto | undefined): (Game | undefined) => {
if (!response) return;
return Mapper.fromGame(response);
});
},
async getVersion(): Promise<string | undefined> {
return tool.get<string>('/version', {});
}
// endregion
};
export default service;

131
src/store/apiStore/apiStore.ts

@ -0,0 +1,131 @@
/**
* @file Хранилище для источника данных
* @version 2022.01.26
* @author Verevkin S.A.
* @copyright Verevkin S.A.
*/
import { action, makeObservable, observable } from 'mobx';
import { Game } from '../../model/Game';
import service from './apiStore.service';
import { Witch } from '../../model/Witch';
export enum EGameStage {
Start = 0,
Process = 1
}
class ApiStore {
// region observable properties
mockMode: boolean = true;
gameStage: EGameStage = EGameStage.Start;
version: string = "";
currentGame: Game | undefined;
errorState: string = "";
// endregion
// region consts
apiUrl = process.env.REACT_APP_API_URL;
// endregion
constructor() {
makeObservable(this, {
/* observable properties */
currentGame: observable,
mockMode: observable,
version: observable,
errorState: observable,
gameStage: observable,
/* actions */
setCurrentGame: action.bound,
setMockMode: action.bound,
setVersion: action.bound,
setErrorState: action.bound,
setGameStage: action.bound,
});
this.backgroundLoad();
}
// region public methods
async backgroundLoad(): Promise<void> {
if (this.mockMode) {
const ar: Witch[] = [{
guid: '1', position: 0, flagReal: false,
},
{
guid: '2', position: 1, flagReal: true,
},
{
guid: '3', position: 2, flagReal: false,
},
];
this.setCurrentGame({
guid: '1',
witches: ar,
score: 0,
})
return Promise.resolve();
}
service.getVersion()
.then((version) => version && this.setVersion(version));
service.getGame()
.then((game) => game && this.setCurrentGame(game));
}
async turn(witchGuid: string): Promise<boolean> {
if (this.mockMode) return Promise.resolve(false);
if (!this.currentGame?.guid) return Promise.resolve(false);
return service.gameTurn(this.currentGame?.guid, witchGuid)
.then((game) => {
if (!game) return false;
const result = (game?.guid !== this.currentGame?.guid);
this.setCurrentGame(game);
return result;
})
}
// endregion
// region setters
setCurrentGame(game: Game) {
this.currentGame = game;
}
setMockMode(mockMode: boolean) {
if (mockMode !== this.mockMode) this.mockMode = mockMode;
}
setVersion(version: string) {
if (version && version !== this.version) {
this.version = version;
}
}
setErrorState(errorState: string) {
this.errorState = errorState;
if (errorState) {
this.gameStage = EGameStage.Start;
}
}
setGameStage(gameStage: EGameStage) {
if (gameStage === this.gameStage) return;
this.gameStage = gameStage;
}
//endregion
startNewGame() {
if (this.mockMode) {
if (this.currentGame) {
this.currentGame.guid = Date.now().toString(10);
}
this.setGameStage(EGameStage.Process)
} else {
service.getGame()
.then((game) => {
if (game) {
this.setCurrentGame(game);
this.setGameStage(EGameStage.Process)
}
});
}
}
}
export default new ApiStore();

23
src/store/mapper.ts

@ -0,0 +1,23 @@
import _ from 'lodash';
import { Game } from '../model/Game';
import { IGameDto } from '../model/GameDto';
import { IWitchDto } from '../model/WitchDto';
import { Witch } from '../model/Witch';
export const Mapper = {
fromGame(gameDto: IGameDto): Game {
return {
guid: gameDto.guid,
score: gameDto.score,
witches: _.map(gameDto.witches, (witch: IWitchDto) => this.fromWitch(witch)),
}
},
fromWitch(witch: IWitchDto): Witch {
return {
flagReal: witch.flagReal,
position: witch.position,
guid: witch.guid,
}
}
}

40
src/store/tool.ts

@ -0,0 +1,40 @@
/**
* @file Утилиты
* @version 2022.01.26
* @author Verevkin S.A.
* @copyright Verevkin S.A.
*/
import axios from 'axios';
const tool = {
apiUrl: process.env.REACT_APP_API_URL,
// region функции
// метод взаимодействия с REST-сервисом
get<TResult>(
method: string,
args: any,
): Promise<TResult | undefined> {
const url = this.apiUrl + method;
const requestConfig = {
params: Object
};
return axios
.get<TResult>(
`${url}`,
requestConfig,
)
.then((response) => {
const { data } = response;
return data;
})
.catch((err) => {
console.warn(err);
return undefined;
});
},
//endregion
};
export default tool;

26
tsconfig.json

@ -0,0 +1,26 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": [
"src"
]
}

8754
yarn.lock

File diff suppressed because it is too large
Loading…
Cancel
Save