From bbc894a294e5f99e3f18b6dbf4d275b53bf81fc9 Mon Sep 17 00:00:00 2001 From: amitsh Date: Sat, 3 Oct 2020 16:33:24 +0300 Subject: [PATCH] Nissix "prettier" plugin --- .babelrc | 4 +- README.md | 18 +- dev/app/actions/index.js | 19 +- dev/app/components/App/index.js | 33 +- dev/app/components/GameZone/index.js | 81 +++-- dev/app/components/Loading/index.js | 34 +- dev/app/components/Login/LoginForm.js | 133 ++++---- dev/app/components/Login/RegistrationForm.js | 183 ++++++----- dev/app/components/Login/index.js | 117 ++++--- dev/app/components/Login/style.css | 3 +- dev/app/components/Logo/index.js | 22 +- dev/app/components/Logo/style.css | 4 +- dev/app/components/MainMenu/index.js | 119 ++++--- dev/app/components/MainMenu/style.css | 10 +- dev/app/components/MainPage/index.js | 45 +-- dev/app/components/MainPage/style.css | 8 +- dev/app/components/PlayerCard/index.js | 50 +-- .../components/PlayerHorizontalCard/index.js | 28 +- .../PlayerStats/PlayerStatsViewer.js | 190 ++++++----- dev/app/components/PlayerStats/index.js | 87 ++--- dev/app/components/PrivateRoute/index.js | 37 ++- dev/app/components/Statistics/index.js | 82 ++--- .../game/Board/HittenCheckersAreaViewer.js | 91 +++--- dev/app/components/game/Board/SubBoard.js | 50 +-- dev/app/components/game/Board/index.js | 87 ++--- dev/app/components/game/Board/style.css | 116 ++++--- dev/app/components/game/Chat/index.js | 187 +++++++---- dev/app/components/game/Chat/style.css | 2 +- .../components/game/Checker/CheckerChip.js | 15 +- .../game/Checker/CheckerDndPreview.js | 55 ++-- dev/app/components/game/Checker/index.js | 43 ++- dev/app/components/game/Checker/style.css | 10 +- dev/app/components/game/Dice/index.js | 142 +++++---- dev/app/components/game/Dice/style.css | 12 +- dev/app/components/game/Dicing/index.js | 147 +++++---- dev/app/components/game/Dicing/style.css | 13 +- dev/app/components/game/Game.js | 43 ++- dev/app/components/game/GameInfoViewer.js | 29 +- dev/app/components/game/Point/index.js | 76 +++-- dev/app/components/game/Point/style.css | 19 +- dev/app/components/styles.css | 38 ++- .../utils/AutocompleteInput/index.js | 252 ++++++++------- .../utils/AutocompleteInput/style.css | 23 +- .../components/utils/DynamicLoadTable.Old.js | 136 ++++---- dev/app/components/utils/DynamicLoadTable.js | 57 ++-- dev/app/constants/index.js | 90 ++++-- dev/app/containers/Dicing.js | 27 +- dev/app/containers/GameInfo.js | 40 +-- dev/app/containers/GameZone.js | 26 +- dev/app/containers/HittenCheckersArea.js | 18 +- dev/app/containers/Login.js | 22 +- dev/app/containers/Point.js | 51 +-- dev/app/containers/PrivateRoute.js | 21 +- dev/app/index.js | 88 ++--- dev/app/middlewares/socketio.js | 119 +++---- dev/app/middlewares/spamUserActionFilter.js | 21 +- dev/app/reducers/game.js | 281 +++++++++------- dev/app/reducers/index.js | 12 +- dev/app/reducers/session.js | 27 +- dev/app/rules/index.js | 301 ++++++++++-------- dev/app/socket/index.js | 20 +- dev/app/utils/index.js | 29 +- dev/common/config.js | 4 +- dev/common/constants.js | 42 ++- dev/common/defaultConfig.json | 6 +- dev/content/index.html | 13 +- dev/server/.babelrc | 4 +- dev/server/data/dal.js | 127 +++++--- dev/server/data/db.js | 104 ++++-- dev/server/data/graphql/resolvers.js | 47 +-- dev/server/data/graphql/schema.js | 5 +- dev/server/index.js | 209 ++++++------ dev/server/routes/register.js | 31 +- dev/server/routes/statistics.js | 24 +- dev/server/server.js | 155 ++++----- index2.js | 27 +- package-lock.json | 14 + package.json | 1 + postcss.config.js | 7 +- webpack.config.js | 185 ++++++----- webpack.config.prod.js | 175 +++++----- 81 files changed, 3026 insertions(+), 2297 deletions(-) create mode 100644 package-lock.json diff --git a/.babelrc b/.babelrc index 80d6959..ea4a9f6 100644 --- a/.babelrc +++ b/.babelrc @@ -1,4 +1,4 @@ { - "presets": ["es2015","react","stage-0","stage-2"], - "plugins": ["react-hot-loader/babel"] + "presets": ["es2015", "react", "stage-0", "stage-2"], + "plugins": ["react-hot-loader/babel"] } diff --git a/README.md b/README.md index 09ac0a6..a306643 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,17 @@ ## Development -* npm install -* npm run start-dev -* localhost:4445 +- npm install +- npm run start-dev +- localhost:4445 ## Production -* npm install -* npm run all -* localhost:4445 +- npm install +- npm run all +- localhost:4445 demo users: - - amitush 123 - - deanush 234 - - avivush 345 +- amitush 123 +- deanush 234 +- avivush 345 diff --git a/dev/app/actions/index.js b/dev/app/actions/index.js index 0390125..6196174 100644 --- a/dev/app/actions/index.js +++ b/dev/app/actions/index.js @@ -4,10 +4,10 @@ export const DICING = "DICING"; //export const SET_TURN = "SET_TURN"; //export const INIT_STATE = "INIT_STATE"; -export const switchTurn = () => ({type:SWITCH_TURN}); +export const switchTurn = () => ({ type: SWITCH_TURN }); //export const initState = () => ({type:INIT_STATE}); -export const step = step => ({type:STEP, content: step}); -export const dice = dicesResult => ({type:DICING, content: dicesResult}); +export const step = (step) => ({ type: STEP, content: step }); +export const dice = (dicesResult) => ({ type: DICING, content: dicesResult }); //export const setTurn = isClientTurn => ({type:SET_TURN, content:isClientTurn}); export const LOG_IN = "LOG_IN"; @@ -16,8 +16,11 @@ export const SEARCH_OPPONENT = "SEARCH_OPPONENT"; export const SRART_GAME = "SRART_GAME"; export const OPPONENT_RETIRED = "OPPONENT_RETIRED"; -export const login = user => ({type:LOG_IN, content: user}); -export const logout = () => ({type:LOG_OUT}); -export const searchOpponent = () => ({type:SEARCH_OPPONENT}); -export const startGame = (isClientStart, opponentInfo) => ({type:SRART_GAME, content:{isClientStart, opponentInfo}}); -export const opponentRetirment = () => ({type:OPPONENT_RETIRED}); +export const login = (user) => ({ type: LOG_IN, content: user }); +export const logout = () => ({ type: LOG_OUT }); +export const searchOpponent = () => ({ type: SEARCH_OPPONENT }); +export const startGame = (isClientStart, opponentInfo) => ({ + type: SRART_GAME, + content: { isClientStart, opponentInfo }, +}); +export const opponentRetirment = () => ({ type: OPPONENT_RETIRED }); diff --git a/dev/app/components/App/index.js b/dev/app/components/App/index.js index 1e75832..75525ab 100644 --- a/dev/app/components/App/index.js +++ b/dev/app/components/App/index.js @@ -1,20 +1,21 @@ -import React from 'react' -import MainPage from '../MainPage' -import PrivateRoute from '../../containers/PrivateRoute' -import Login from '../../containers/Login' +import React from "react"; +import MainPage from "../MainPage"; +import PrivateRoute from "../../containers/PrivateRoute"; +import Login from "../../containers/Login"; -import { Link, Redirect } from 'react-router-dom' -import { Router, Switch, Route } from 'react-router' -import createBrowserHistory from 'history/createBrowserHistory' +import { Link, Redirect } from "react-router-dom"; +import { Router, Switch, Route } from "react-router"; +import createBrowserHistory from "history/createBrowserHistory"; -const history = createBrowserHistory() +const history = createBrowserHistory(); -const App = () => - - - - - - +const App = () => ( + + + + + + +); -export default App +export default App; diff --git a/dev/app/components/GameZone/index.js b/dev/app/components/GameZone/index.js index ef53d11..20cce8a 100644 --- a/dev/app/components/GameZone/index.js +++ b/dev/app/components/GameZone/index.js @@ -1,48 +1,59 @@ -import React from 'react'; -import Game from '../game/Game' -import { PLAY_STATUS, IN_GAME_STATUS } from '../../constants' -import { Segment, Header } from 'semantic-ui-react' -import style from './style.css' - -const GameZome = ({inGameStatus, playStatus, play, stopSearch}) => { +import React from "react"; +import Game from "../game/Game"; +import { PLAY_STATUS, IN_GAME_STATUS } from "../../constants"; +import { Segment, Header } from "semantic-ui-react"; +import style from "./style.css"; +const GameZome = ({ inGameStatus, playStatus, play, stopSearch }) => { let message; let onClickAction; let buttonLabel; - switch (playStatus){ - case PLAY_STATUS.PLAY:{ - return - } - case PLAY_STATUS.SEARCH_OPPONENT:{ - message = "Wait for another player" - onClickAction = stopSearch - buttonLabel = "stop search" + switch (playStatus) { + case PLAY_STATUS.PLAY: { + return ; + } + case PLAY_STATUS.SEARCH_OPPONENT: { + message = "Wait for another player"; + onClickAction = stopSearch; + buttonLabel = "stop search"; break; - } - case PLAY_STATUS.OPPONENT_RETIRED:{ - message = "The player retired. For Search a new player:" - onClickAction = play - buttonLabel = "search" + } + case PLAY_STATUS.OPPONENT_RETIRED: { + message = "The player retired. For Search a new player:"; + onClickAction = play; + buttonLabel = "search"; break; - } - case PLAY_STATUS.NOT_PLAY:{ - onClickAction = play - buttonLabel = "play" + } + case PLAY_STATUS.NOT_PLAY: { + onClickAction = play; + buttonLabel = "play"; - if (inGameStatus == IN_GAME_STATUS.WINNER || inGameStatus == IN_GAME_STATUS.LOSER){ - message = `You are the ${inGameStatus} of the game. For play again: ` - }else{ - message = `For search opponent: ` + if ( + inGameStatus == IN_GAME_STATUS.WINNER || + inGameStatus == IN_GAME_STATUS.LOSER + ) { + message = `You are the ${inGameStatus} of the game. For play again: `; + } else { + message = `For search opponent: `; } break; - } - } + } + } - return -
{message}
- -
-} + return ( + +
+ {message} +
+ +
+ ); +}; export default GameZome; diff --git a/dev/app/components/Loading/index.js b/dev/app/components/Loading/index.js index ba11041..75ac768 100644 --- a/dev/app/components/Loading/index.js +++ b/dev/app/components/Loading/index.js @@ -1,24 +1,22 @@ -import React, {Component} from 'react'; +import React, { Component } from "react"; class Loading extends Component { + constructor(props) { + super(props); + this.state = { + loading: true, + }; + } - constructor(props){ - super(props) - this.state = { - loading: true - }; - } + render() { + const { loading } = this.state; - render(){ - const {loading} = this.state; - - return (this.state.loading? -
- {this.props.message} -
- :this.props.children - ) - } + return this.state.loading ? ( +
{this.props.message}
+ ) : ( + this.props.children + ); + } } -export default Loading +export default Loading; diff --git a/dev/app/components/Login/LoginForm.js b/dev/app/components/Login/LoginForm.js index 7609d59..2b25122 100644 --- a/dev/app/components/Login/LoginForm.js +++ b/dev/app/components/Login/LoginForm.js @@ -1,75 +1,96 @@ -import React, { Component } from 'react' -import { Form, Message } from 'semantic-ui-react' -import axios from 'axios' +import React, { Component } from "react"; +import { Form, Message } from "semantic-ui-react"; +import axios from "axios"; class LoginForm extends Component { constructor(props) { - super(props) - this.state = { formData:{playAsGuest:true,username:"amitush",password:"123"}, - isServerChecking:false, - actionFailed:false}; + super(props); + this.state = { + formData: { playAsGuest: true, username: "amitush", password: "123" }, + isServerChecking: false, + actionFailed: false, + }; } - handleChangeField = (e, { name, value }) => this.setState({formData:{ ...this.state.formData, [name]: value }}) + handleChangeField = (e, { name, value }) => + this.setState({ formData: { ...this.state.formData, [name]: value } }); - handleLogin(e){ + handleLogin(e) { e.preventDefault(); - this.setState({isServerChecking:true}); + this.setState({ isServerChecking: true }); - axios.post('/login', this.state.formData) - .then(res => { + axios + .post("/login", this.state.formData) + .then((res) => { this.props.login(res.data.user); - history.push('/'); + history.push("/"); }) - .catch(err => { - this.setState({isServerChecking:false,actionFailed:true,message:err.message}); + .catch((err) => { + this.setState({ + isServerChecking: false, + actionFailed: true, + message: err.message, + }); }); - } - toggle = (name) => () => this.setState({formData:{ ...this.state.formData, [name]: !this.state.formData[name] }}) - + toggle = (name) => () => + this.setState({ + formData: { ...this.state.formData, [name]: !this.state.formData[name] }, + }); render() { + const { username, password, playAsGuest } = this.state.formData; - const {username, password, playAsGuest} = this.state.formData; - - return
- - - - Login - - + return ( +
+ + + + + Login + + + + ); } } -export default LoginForm +export default LoginForm; diff --git a/dev/app/components/Login/RegistrationForm.js b/dev/app/components/Login/RegistrationForm.js index 77a7037..c715c6a 100644 --- a/dev/app/components/Login/RegistrationForm.js +++ b/dev/app/components/Login/RegistrationForm.js @@ -1,119 +1,150 @@ -import React, { Component } from 'react' -import { Icon, Input, Form, Button, Message } from 'semantic-ui-react' -import axios from 'axios' -import {COUNTRIES} from '../../../common/constants' -import style from './style.css' -import Rx from '@rxjs/Rx' +import React, { Component } from "react"; +import { Icon, Input, Form, Button, Message } from "semantic-ui-react"; +import axios from "axios"; +import { COUNTRIES } from "../../../common/constants"; +import style from "./style.css"; +import Rx from "@rxjs/Rx"; class RegistrationForm extends Component { constructor(props) { - super(props) - this.state = { formData:{}, - usernameFieldIcon:null, - usernameChecking:false, - isServerChecking:false, - actionSuccessed:false}; + super(props); + this.state = { + formData: {}, + usernameFieldIcon: null, + usernameChecking: false, + isServerChecking: false, + actionSuccessed: false, + }; this.userNameDebouncer = new Rx.Subject().debounceTime(500); this.userNameDebouncer.subscribe({ - next: (v) => ::this.validateUserName(v) + next: (v) => ::this.validateUserName(v), }); } - handleChangeField(e, { name, value }){ - this.setState({formData:{ ...this.state.formData, [name]: value }}) + handleChangeField(e, { name, value }) { + this.setState({ formData: { ...this.state.formData, [name]: value } }); } - handleRegistration(e){ + handleRegistration(e) { e.preventDefault(); - this.setState({isServerChecking:true}); + this.setState({ isServerChecking: true }); - axios.post('/register', this.state.formData) - .then(res => { - this.setState({isServerChecking:false, actionSuccessed:true}); + axios + .post("/register", this.state.formData) + .then((res) => { + this.setState({ isServerChecking: false, actionSuccessed: true }); }) - .catch(err => { - this.setState({isServerChecking:false, message:err.message}); + .catch((err) => { + this.setState({ isServerChecking: false, message: err.message }); }); } - validateUserName(username){ - axios.post('/register/validation/username', {'username':username}) - .then(res => { - this.setState({usernameChecking:false, - usernameFieldIcon:{name:'checkmark',color:'green',size:'large', style:{width: '1.67142857em'}}}); + validateUserName(username) { + axios + .post("/register/validation/username", { username: username }) + .then((res) => { + this.setState({ + usernameChecking: false, + usernameFieldIcon: { + name: "checkmark", + color: "green", + size: "large", + style: { width: "1.67142857em" }, + }, + }); }) .catch((err) => { - this.setState({usernameChecking:false, - usernameFieldIcon:{name:'remove',color:'red',size:'large', style:{width: '1.67142857em'}}}); + this.setState({ + usernameChecking: false, + usernameFieldIcon: { + name: "remove", + color: "red", + size: "large", + style: { width: "1.67142857em" }, + }, + }); }); } - handleUsernameFieldChange(e, { name, value }){ - + handleUsernameFieldChange(e, { name, value }) { ::this.handleChangeField(e, { name, value }); - if (value === ""){ - this.setState({usernameChecking:false, usernameFieldIcon:'null'}); + if (value === "") { + this.setState({ usernameChecking: false, usernameFieldIcon: "null" }); } else { - this.setState({usernameChecking:true}); + this.setState({ usernameChecking: true }); this.userNameDebouncer.next(value); } } render() { + const { username, password } = this.state.formData; - const {username, password} = this.state.formData; - - return
- - + + - - + required + /> + + - - - + + + + - - + name="country" + label="County" + placeholder="Select your country" + options={COUNTRIES} + onChange={::this.handleChangeField} + /> - Register - - + + Register + + + + ); } } -export default RegistrationForm +export default RegistrationForm; diff --git a/dev/app/components/Login/index.js b/dev/app/components/Login/index.js index 9f68ec4..190dba6 100644 --- a/dev/app/components/Login/index.js +++ b/dev/app/components/Login/index.js @@ -1,68 +1,81 @@ -import React, { Component } from 'react' -import { Redirect } from 'react-router-dom' -import { Segment, Menu, Icon, Grid } from 'semantic-ui-react' -import Logo from '../Logo' -import LoginForm from './LoginForm' -import RegistrationForm from './RegistrationForm' +import React, { Component } from "react"; +import { Redirect } from "react-router-dom"; +import { Segment, Menu, Icon, Grid } from "semantic-ui-react"; +import Logo from "../Logo"; +import LoginForm from "./LoginForm"; +import RegistrationForm from "./RegistrationForm"; class Login extends Component { constructor(props) { - super(props) - this.state = {menuActiveItem:"login"}; + super(props); + this.state = { menuActiveItem: "login" }; } - handleRegister(e, { data }) { - this.setState({username: e.target.value}); + this.setState({ username: e.target.value }); } - handleItemClick (e, { name }) { - this.setState({ menuActiveItem: name }) + handleItemClick(e, { name }) { + this.setState({ menuActiveItem: name }); } render() { + const { from } = this.props.location.state || { + from: { pathname: "/main/game" }, + }; - const {from } = this.props.location.state || { from: { pathname: '/main/game' } } - - return this.props.isLoggedIn ? - : - - - - - - - - - - {(this.state.menuActiveItem === 'login')? - - : - - } - - - - - - - login - - + return this.props.isLoggedIn ? ( + + ) : ( + + + + + + + + + + {this.state.menuActiveItem === "login" ? ( + + ) : ( + + )} + + + + + + + login + + register - - - - - - + + + + + + + ); } } -export default Login +export default Login; diff --git a/dev/app/components/Login/style.css b/dev/app/components/Login/style.css index 106eb1c..ee82ab6 100644 --- a/dev/app/components/Login/style.css +++ b/dev/app/components/Login/style.css @@ -1,6 +1,5 @@ - .field { - width: 50% + width: 50%; } /*.ui.form .field>label{ diff --git a/dev/app/components/Logo/index.js b/dev/app/components/Logo/index.js index e0df11d..45b0003 100644 --- a/dev/app/components/Logo/index.js +++ b/dev/app/components/Logo/index.js @@ -1,13 +1,17 @@ -import React from 'react' -import { Header, Image } from 'semantic-ui-react' -import style from './style.css' -import '../../content/dices.png' +import React from "react"; +import { Header, Image } from "semantic-ui-react"; +import style from "./style.css"; +import "../../content/dices.png"; -const Logo = ({size, textAlign}) => ( +const Logo = ({ size, textAlign }) => (
- -
Shubapp
backgammon
+ +
+ Shubapp +
+ backgammon +
-) +); -export default Logo +export default Logo; diff --git a/dev/app/components/Logo/style.css b/dev/app/components/Logo/style.css index 455e0ed..941d288 100644 --- a/dev/app/components/Logo/style.css +++ b/dev/app/components/Logo/style.css @@ -6,6 +6,6 @@ cursor: default; } -.image{ - margin:0; +.image { + margin: 0; } diff --git a/dev/app/components/MainMenu/index.js b/dev/app/components/MainMenu/index.js index 8475678..4fe41e9 100644 --- a/dev/app/components/MainMenu/index.js +++ b/dev/app/components/MainMenu/index.js @@ -1,70 +1,89 @@ -import React, { Component } from 'react' -import { Redirect, Link } from 'react-router-dom' -import { Segment, Menu, Icon, Dropdown } from 'semantic-ui-react' -import Logo from '../Logo' -import style from './style.css' +import React, { Component } from "react"; +import { Redirect, Link } from "react-router-dom"; +import { Segment, Menu, Icon, Dropdown } from "semantic-ui-react"; +import Logo from "../Logo"; +import style from "./style.css"; class MainMenu extends Component { - constructor(props) { super(props); - this.state = {selectedMenuItem: ::this.clacCurrentTab()}; + this.state = { selectedMenuItem: ::this.clacCurrentTab() }; } - clacCurrentTab(){ + clacCurrentTab() { const currentLocation = this.props.location.pathname; const componentPath = this.props.match.path; - return currentLocation.slice(componentPath.length+1).split('/')[0] + return currentLocation.slice(componentPath.length + 1).split("/")[0]; } handleItemChange(menuItem) { - this.setState({selectedMenuItem: menuItem.name}); + this.setState({ selectedMenuItem: menuItem.name }); this.props.history.push(menuItem.to); } - render(){ - const dropDownTrigger = - - {this.props.userInfo.username} - ; - const dropDown = - - - my profile - - - - logout - - - + render() { + const dropDownTrigger = ( + + + {this.props.userInfo.username} + + ); + const dropDown = ( + + + + my profile + + + + logout + + + + ); - const menuItems = this.props.menuItems - const selectedMenuItem = this.state.selectedMenuItem - const itemsGrid = - - - - {menuItems.map((menuItem, index) => - ::this.handleItemChange(menuItem)}> - {menuItem.name} - )} - - - {dropDown} - - - + const menuItems = this.props.menuItems; + const selectedMenuItem = this.state.selectedMenuItem; + const itemsGrid = ( + + + + + {menuItems.map((menuItem, index) => ( + ::this.handleItemChange(menuItem)} + > + {menuItem.name} + + ))} + + {dropDown} + + + ); - return - {itemsGrid} - - } + return ( + + {itemsGrid} + + ); + } } export default MainMenu; diff --git a/dev/app/components/MainMenu/style.css b/dev/app/components/MainMenu/style.css index b3b7b76..eeba096 100644 --- a/dev/app/components/MainMenu/style.css +++ b/dev/app/components/MainMenu/style.css @@ -7,14 +7,14 @@ } .logo { - padding:0; - padding-right:20px; + padding: 0; + padding-right: 20px; } .dropdownOption { - padding: .2em .4em; + padding: 0.2em 0.4em; } -.dropdownDivider{ - margin: 0.1em 0!important; +.dropdownDivider { + margin: 0.1em 0 !important; } diff --git a/dev/app/components/MainPage/index.js b/dev/app/components/MainPage/index.js index 470d745..eb80540 100644 --- a/dev/app/components/MainPage/index.js +++ b/dev/app/components/MainPage/index.js @@ -1,24 +1,29 @@ -import React from 'react' -import { Route } from 'react-router-dom' -import MainMenu from '../MainMenu' -import Statistics from '../Statistics' +import React from "react"; +import { Route } from "react-router-dom"; +import MainMenu from "../MainMenu"; +import Statistics from "../Statistics"; //import PrivateRoute from '../../containers/PrivateRoute' -import GameZone from '../../containers/GameZone' -import style from './style.css' +import GameZone from "../../containers/GameZone"; +import style from "./style.css"; -const MainPage = props => { - const currentPath = props.match.path - const gamePath = `${currentPath}/game` - const statisticsPath = `${currentPath}/statistics` +const MainPage = (props) => { + const currentPath = props.match.path; + const gamePath = `${currentPath}/game`; + const statisticsPath = `${currentPath}/statistics`; - const menuItems = [{to:gamePath ,name:"game"},{to:statisticsPath ,name:"statistics"}] - return
- -
- - -
-
-} + const menuItems = [ + { to: gamePath, name: "game" }, + { to: statisticsPath, name: "statistics" }, + ]; + return ( +
+ +
+ + +
+
+ ); +}; -export default MainPage +export default MainPage; diff --git a/dev/app/components/MainPage/style.css b/dev/app/components/MainPage/style.css index 130fcd9..a6a1bb3 100644 --- a/dev/app/components/MainPage/style.css +++ b/dev/app/components/MainPage/style.css @@ -1,6 +1,6 @@ .mainContent { - position: absolute; - top: 70px; - width: 100%; - height: calc(100% - 70px); + position: absolute; + top: 70px; + width: 100%; + height: calc(100% - 70px); } diff --git a/dev/app/components/PlayerCard/index.js b/dev/app/components/PlayerCard/index.js index 07df41b..143f58b 100644 --- a/dev/app/components/PlayerCard/index.js +++ b/dev/app/components/PlayerCard/index.js @@ -1,21 +1,33 @@ -import React from 'react'; -import { Icon, Card, Image, Flag, Header } from 'semantic-ui-react' -import '../../content/pp.jpg' +import React from "react"; +import { Icon, Card, Image, Flag, Header } from "semantic-ui-react"; +import "../../content/pp.jpg"; -const PlayerCard = ({playerInfo}) => - {playerInfo.image ? - : } - - - {`${playerInfo.firstName} ${playerInfo.lastName}`} - - - {playerInfo.username} - - - - - - +const PlayerCard = ({ playerInfo }) => ( + + {playerInfo.image ? ( + + ) : ( + + )} + + + {`${playerInfo.firstName} ${playerInfo.lastName}`} + + {playerInfo.username} + + + + + +); -export default PlayerCard +export default PlayerCard; diff --git a/dev/app/components/PlayerHorizontalCard/index.js b/dev/app/components/PlayerHorizontalCard/index.js index 2f30ab8..0b18cb3 100644 --- a/dev/app/components/PlayerHorizontalCard/index.js +++ b/dev/app/components/PlayerHorizontalCard/index.js @@ -1,17 +1,25 @@ -import React from 'react'; -import { Image, Flag, Header , Icon } from 'semantic-ui-react' -import '../../content/pp.jpg' +import React from "react"; +import { Image, Flag, Header, Icon } from "semantic-ui-react"; +import "../../content/pp.jpg"; -const PlayerHorizontalCard = ({playerInfo}) => +const PlayerHorizontalCard = ({ playerInfo }) => (
- {playerInfo.image ? - : } - - {playerInfo.username} + {playerInfo.image ? ( + + ) : ( + + )} + + {playerInfo.username} - +
+); -export default PlayerHorizontalCard +export default PlayerHorizontalCard; diff --git a/dev/app/components/PlayerStats/PlayerStatsViewer.js b/dev/app/components/PlayerStats/PlayerStatsViewer.js index 486ba76..40673ee 100644 --- a/dev/app/components/PlayerStats/PlayerStatsViewer.js +++ b/dev/app/components/PlayerStats/PlayerStatsViewer.js @@ -1,91 +1,110 @@ -import React, {Component} from 'react' -import {Pie as PieChart} from 'react-chartjs-2' -import AutocompleteInput from '../utils/AutocompleteInput' -import PlayerCard from '../PlayerCard' -import DynamicLoadTable from '../utils/DynamicLoadTable' -import axios from 'axios' -import { graphql } from 'react-apollo'; -import gql from 'graphql-tag'; -import style from './style.css' -import moment from 'moment' +import React, { Component } from "react"; +import { Pie as PieChart } from "react-chartjs-2"; +import AutocompleteInput from "../utils/AutocompleteInput"; +import PlayerCard from "../PlayerCard"; +import DynamicLoadTable from "../utils/DynamicLoadTable"; +import axios from "axios"; +import { graphql } from "react-apollo"; +import gql from "graphql-tag"; +import style from "./style.css"; +import moment from "moment"; -const headerRow = ['opponent', 'date', 'result']; +const headerRow = ["opponent", "date", "result"]; -const renderBodyRow = ({id, date, opponent, isWinner}, i) => ({ +const renderBodyRow = ({ id, date, opponent, isWinner }, i) => ({ key: id, - cells:[opponent, moment(date).format("MMM-DD-YYYY HH:mm"), isWinner?"W":"L"] + cells: [ + opponent, + moment(date).format("MMM-DD-YYYY HH:mm"), + isWinner ? "W" : "L", + ], }); const CHART_COLORS = [ - 'rgb(255, 99, 132)', - 'rgb(255, 159, 64)', - 'rgb(255, 205, 86)', - 'rgb(75, 192, 192)', - 'rgb(54, 162, 235)', - 'rgb(153, 102, 255)', - 'rgb(201, 203, 207)'] - + "rgb(255, 99, 132)", + "rgb(255, 159, 64)", + "rgb(255, 205, 86)", + "rgb(75, 192, 192)", + "rgb(54, 162, 235)", + "rgb(153, 102, 255)", + "rgb(201, 203, 207)", +]; class PlayerStatsViewer extends Component { constructor(props) { - super(props); - this.state = {moreItemToLoad:true} - } + super(props); + this.state = { moreItemToLoad: true }; + } // // componentDidUpdate(prevProps, prevState){ // console.log("componentWillReceiveProps"); // } - render(){ - const {userInfo: user, playerStat, playerGames, loadMoreEntries} = this.props; + render() { + const { + userInfo: user, + playerStat, + playerGames, + loadMoreEntries, + } = this.props; let winsLossesChart; - if (playerStat !== undefined){ + if (playerStat !== undefined) { console.log(window.chartColors); - //TODO - const data = { - labels: Object.keys(playerStat.record).filter(key => key != "__typename"), - datasets: [{ - data: Object.values(playerStat.record).filter(value => value != "PlayerRecord"), - backgroundColor: CHART_COLORS, - hoverBackgroundColor: CHART_COLORS - }] - }; + //TODO + const data = { + labels: Object.keys(playerStat.record).filter( + (key) => key != "__typename" + ), + datasets: [ + { + data: Object.values(playerStat.record).filter( + (value) => value != "PlayerRecord" + ), + backgroundColor: CHART_COLORS, + hoverBackgroundColor: CHART_COLORS, + }, + ], + }; - winsLossesChart = + winsLossesChart = ( + + ); } - return
- -
-
- {winsLossesChart} -
-
- {winsLossesChart} -
-
- this.setState({moreItemToLoad:false}))} - headerRow={headerRow} - tableData={playerGames} - moreItemToLoad={this.state.moreItemToLoad} - renderBodyRow={renderBodyRow} - username={user.username} - /> -
+ return ( +
+ +
+
{winsLossesChart}
+
{winsLossesChart}
+
+ + this.setState({ moreItemToLoad: false }) + )} + headerRow={headerRow} + tableData={playerGames} + moreItemToLoad={this.state.moreItemToLoad} + renderBodyRow={renderBodyRow} + username={user.username} + /> +
+ ); } } const playerStatsQuery = gql` - query playerStatsQuery($userId: ID!, $offset: Int, $limit: Int){ + query playerStatsQuery($userId: ID!, $offset: Int, $limit: Int) { playerStat(id: $userId) { record { turkishMarsLoss @@ -97,38 +116,42 @@ const playerStatsQuery = gql` turkishMarsWin } } - playerGames(id: $userId, offset:$offset, limit:$limit) { + playerGames(id: $userId, offset: $offset, limit: $limit) { id opponent score } -} + } `; const gamesQuery = gql` - query playerGamesQuery($userId: ID!, $offset: Int, $limit: Int){ - playerGames(id: $userId, offset:$offset, limit:$limit) { + query playerGamesQuery($userId: ID!, $offset: Int, $limit: Int) { + playerGames(id: $userId, offset: $offset, limit: $limit) { id opponent score } -} + } `; const PlayerStatsViewerWithData = graphql(playerStatsQuery, { - options: ({userInfo}) => ({ + options: ({ userInfo }) => ({ variables: { userId: userInfo.id, offset: 0, - limit: 3} + limit: 3, + }, }), - props: ({ownProps, data: { loading, playerStat, playerGames, fetchMore }}) => ({ + props: ({ + ownProps, + data: { loading, playerStat, playerGames, fetchMore }, + }) => ({ ...ownProps, loading, playerStat, playerGames, loadMoreEntries: (moreItemToLoad) => () => - fetchMore({ + fetchMore({ query: gamesQuery, variables: { userId: ownProps.userInfo.id, @@ -136,16 +159,21 @@ const PlayerStatsViewerWithData = graphql(playerStatsQuery, { limit: 3, }, updateQuery: (previousResult, { fetchMoreResult }) => { - if (!fetchMoreResult || fetchMoreResult.playerGames.length == 0) { moreItemToLoad(); return previousResult; } - return {...previousResult,playerGames: [...previousResult.playerGames, ...fetchMoreResult.playerGames] }; - } - }) - }) + return { + ...previousResult, + playerGames: [ + ...previousResult.playerGames, + ...fetchMoreResult.playerGames, + ], + }; + }, + }), + }), })(PlayerStatsViewer); -export default PlayerStatsViewerWithData +export default PlayerStatsViewerWithData; diff --git a/dev/app/components/PlayerStats/index.js b/dev/app/components/PlayerStats/index.js index 2cc5f67..124484c 100644 --- a/dev/app/components/PlayerStats/index.js +++ b/dev/app/components/PlayerStats/index.js @@ -1,15 +1,15 @@ -import React, { Component } from 'react' -import { Pie as PieChart } from 'react-chartjs-2' -import { gql, withApollo } from 'react-apollo'; -import { Segment } from 'semantic-ui-react' -import AutocompleteInput from '../utils/AutocompleteInput' -import Viewer from './PlayerStatsViewer' -import PlayerHorizontalCard from '../PlayerHorizontalCard' -import style from './style.css' -import moment from 'moment' +import React, { Component } from "react"; +import { Pie as PieChart } from "react-chartjs-2"; +import { gql, withApollo } from "react-apollo"; +import { Segment } from "semantic-ui-react"; +import AutocompleteInput from "../utils/AutocompleteInput"; +import Viewer from "./PlayerStatsViewer"; +import PlayerHorizontalCard from "../PlayerHorizontalCard"; +import style from "./style.css"; +import moment from "moment"; const playersQuery = gql` - query playersQuery($username: String!){ + query playersQuery($username: String!) { players(username: $username) { id username @@ -17,41 +17,56 @@ const playersQuery = gql` lastName country image + } } -} `; class PlayerStats extends Component { constructor(props) { - super(props); - this.state = {selectedUser:null} - } + super(props); + this.state = { selectedUser: null }; + } - render(){ - const searchPromise = value => this.props.client.query({ - query: playersQuery, - variables: { username: value }, - }).then(res => ({data:res.data.players})); + render() { + const searchPromise = (value) => + this.props.client + .query({ + query: playersQuery, + variables: { username: value }, + }) + .then((res) => ({ data: res.data.players })); - const onItemSelect = user => this.setState({selectedUser:user}) - const renderItem = user => - const defaultValue = this.props.match.params.username + const onItemSelect = (user) => this.setState({ selectedUser: user }); + const renderItem = (user) => ; + const defaultValue = this.props.match.params.username; - const searchPanel = - - + const searchPanel = ( + + + + ); - return
- {searchPanel} - {this.state.selectedUser && } -
+ return ( +
+ {searchPanel} + {this.state.selectedUser && ( + + )} +
+ ); } } -export default withApollo(PlayerStats) +export default withApollo(PlayerStats); diff --git a/dev/app/components/PrivateRoute/index.js b/dev/app/components/PrivateRoute/index.js index 1436b2c..f3a2347 100644 --- a/dev/app/components/PrivateRoute/index.js +++ b/dev/app/components/PrivateRoute/index.js @@ -1,17 +1,24 @@ -import React from 'react' -import { Redirect } from 'react-router-dom' -import { Route } from 'react-router' -import PrivateRoute from '../../containers/PrivateRoute' +import React from "react"; +import { Redirect } from "react-router-dom"; +import { Route } from "react-router"; +import PrivateRoute from "../../containers/PrivateRoute"; -const PrivateRouteViewer = ({ component: Component, isLoggedIn, ...rest }) => - isLoggedIn ? - - : - - }/> +const PrivateRouteViewer = ({ component: Component, isLoggedIn, ...rest }) => ( + + isLoggedIn ? ( + + ) : ( + + ) + } + /> +); - -export default PrivateRouteViewer +export default PrivateRouteViewer; diff --git a/dev/app/components/Statistics/index.js b/dev/app/components/Statistics/index.js index e55d19f..acb26c6 100644 --- a/dev/app/components/Statistics/index.js +++ b/dev/app/components/Statistics/index.js @@ -1,51 +1,57 @@ -import React, { Component } from 'react' -import { Route, Redirect } from 'react-router-dom' -import { Menu } from 'semantic-ui-react' -import PlayerStats from '../PlayerStats' -import style from './style.css' +import React, { Component } from "react"; +import { Route, Redirect } from "react-router-dom"; +import { Menu } from "semantic-ui-react"; +import PlayerStats from "../PlayerStats"; +import style from "./style.css"; -const Leaders = () =>
Leaders
-class Statistics extends Component{ - - constructor(props) { +const Leaders = () =>
Leaders
; +class Statistics extends Component { + constructor(props) { super(props); - this.state = {selectedMenuItem: "player"}; + this.state = { selectedMenuItem: "player" }; this.handleItemChange = this.handleItemChange.bind(this); } handleItemChange(menuItem) { - this.setState({selectedMenuItem: menuItem.name}); + this.setState({ selectedMenuItem: menuItem.name }); this.props.history.push(menuItem.to); } - render() { - const { selectedMenuItem } = this.state - const currentPath = this.props.match.path - const playerStatsItem = {to:`${currentPath}/player`, name:"player"} - const leadersItem = {to:`${currentPath}/leaders`, name:"leaders"} + render() { + const { selectedMenuItem } = this.state; + const currentPath = this.props.match.path; + const playerStatsItem = { to: `${currentPath}/player`, name: "player" }; + const leadersItem = { to: `${currentPath}/leaders`, name: "leaders" }; - return
- - this.handleItemChange(playerStatsItem)}> - Player Stats - - this.handleItemChange(leadersItem)}> - Leaders - - - Head2Head - - + return ( +
+ + this.handleItemChange(playerStatsItem)} + > + Player Stats + + this.handleItemChange(leadersItem)} + > + Leaders + + Head2Head + - - - -
- } + + + +
+ ); + } } -export default Statistics +export default Statistics; diff --git a/dev/app/components/game/Board/HittenCheckersAreaViewer.js b/dev/app/components/game/Board/HittenCheckersAreaViewer.js index 3fe357c..8e80164 100644 --- a/dev/app/components/game/Board/HittenCheckersAreaViewer.js +++ b/dev/app/components/game/Board/HittenCheckersAreaViewer.js @@ -1,46 +1,57 @@ -import React, { Component } from 'react'; -import styles from '../Checker/style.css'; +import React, { Component } from "react"; +import styles from "../Checker/style.css"; class HittenCheckersAreaViewer extends Component { - - constructor(props) { - super(props); - - this.flicker = this.flicker.bind(this.flicker); - this.state = {clearInteval: null}; - } - - flicker(element,bool) { - return () => { - - let matches = element.querySelectorAll("." + styles.checkerChipClient.split(' ')[0]); - - matches.forEach(circle => { - if (bool === true) { - circle.style["box-shadow"] = '0px 0px 7px 4px rgb(255, 75, 34)'; - } else { - circle.style["box-shadow"] = '-1px 1px rgba(0,0,0,0.6)'; - }}); - bool = !bool; - } - } - - render() { - return
{this.container = e;}}> - {this.props.children} -
; - } - - componentWillReceiveProps(nextProps){ - if (nextProps.toBlink && this.state.clearInteval == null){ - const clear = setInterval(this.flicker(this.container, true),1000); - this.setState({clearInteval:clear}); - }else if (this.props.toBlink && !nextProps.toBlink && this.state.clearInteval != null){ - clearInterval(this.state.clearInteval); - this.setState({clearInteval:null}); + constructor(props) { + super(props); + + this.flicker = this.flicker.bind(this.flicker); + this.state = { clearInteval: null }; + } + + flicker(element, bool) { + return () => { + let matches = element.querySelectorAll( + "." + styles.checkerChipClient.split(" ")[0] + ); + + matches.forEach((circle) => { + if (bool === true) { + circle.style["box-shadow"] = "0px 0px 7px 4px rgb(255, 75, 34)"; + } else { + circle.style["box-shadow"] = "-1px 1px rgba(0,0,0,0.6)"; } - + }); + bool = !bool; + }; + } + + render() { + return ( +
{ + this.container = e; + }} + > + {this.props.children} +
+ ); + } + + componentWillReceiveProps(nextProps) { + if (nextProps.toBlink && this.state.clearInteval == null) { + const clear = setInterval(this.flicker(this.container, true), 1000); + this.setState({ clearInteval: clear }); + } else if ( + this.props.toBlink && + !nextProps.toBlink && + this.state.clearInteval != null + ) { + clearInterval(this.state.clearInteval); + this.setState({ clearInteval: null }); } + } } -export default HittenCheckersAreaViewer +export default HittenCheckersAreaViewer; diff --git a/dev/app/components/game/Board/SubBoard.js b/dev/app/components/game/Board/SubBoard.js index eeb65c0..a9140e2 100644 --- a/dev/app/components/game/Board/SubBoard.js +++ b/dev/app/components/game/Board/SubBoard.js @@ -1,37 +1,37 @@ -import React, { Component } from 'react'; -import Point from '../../../containers/Point'; -import styles from './style.css'; +import React, { Component } from "react"; +import Point from "../../../containers/Point"; +import styles from "./style.css"; class SubBoard extends Component { - - shouldComponentUpdate(){ + shouldComponentUpdate() { return false; } - render(){ - const {style, pointsIds, isRotated} = this.props; - - var InSubBoard = ({pointsIds}) => ( -
- {pointsIds.map(pointId => + render() { + const { style, pointsIds, isRotated } = this.props; - (
-
- {pointId} -
- + var InSubBoard = ({ pointsIds }) => ( +
+ {pointsIds.map((pointId) => ( +
+
{pointId}
+
- - - + + +
-
) - )} -
); +
+ ))} +
+ ); - return - }; + return ; + } } -export default SubBoard +export default SubBoard; diff --git a/dev/app/components/game/Board/index.js b/dev/app/components/game/Board/index.js index 7135ff0..d6e80ec 100644 --- a/dev/app/components/game/Board/index.js +++ b/dev/app/components/game/Board/index.js @@ -1,19 +1,19 @@ -import React, { Component } from 'react' -import SubBoard from './SubBoard' -import { DragDropContext } from 'react-dnd' -import HTML5Backend from 'react-dnd-html5-backend' -import { default as TouchBackend } from 'react-dnd-touch-backend' -import Dicing from '../../../containers/Dicing' -import HittenCheckersArea from '../../../containers/HittenCheckersArea' -import {POINTS_ON_BOARD} from '../../../constants' -import Point from '../../../containers/Point' -import styles from './style.css' -import Rx from '@rxjs/Rx' +import React, { Component } from "react"; +import SubBoard from "./SubBoard"; +import { DragDropContext } from "react-dnd"; +import HTML5Backend from "react-dnd-html5-backend"; +import { default as TouchBackend } from "react-dnd-touch-backend"; +import Dicing from "../../../containers/Dicing"; +import HittenCheckersArea from "../../../containers/HittenCheckersArea"; +import { POINTS_ON_BOARD } from "../../../constants"; +import Point from "../../../containers/Point"; +import styles from "./style.css"; +import Rx from "@rxjs/Rx"; const addTrianglesReactivity = () => { - let avgContainers = document.querySelectorAll("div[data-key]");; + let avgContainers = document.querySelectorAll("div[data-key]"); - avgContainers.forEach(container => { + avgContainers.forEach((container) => { let svgPapa = container.querySelector("svg"); let poly = svgPapa.querySelector("polygon"); @@ -22,49 +22,54 @@ const addTrianglesReactivity = () => { let w = divBCRect.width; let a = "0," + h; - let b = w/2 + ",0"; - let c = w + "," + h; + let b = w / 2 + ",0"; + let c = w + "," + h; - let pointsStr = [a,b,c].join(" "); + let pointsStr = [a, b, c].join(" "); poly.setAttribute("points", pointsStr); }); }; class Board extends Component { - - componentDidMount(){ + componentDidMount() { addTrianglesReactivity(); - Rx.Observable.fromEvent(window, 'resize'). - debounceTime(100).subscribe(addTrianglesReactivity); + Rx.Observable.fromEvent(window, "resize") + .debounceTime(100) + .subscribe(addTrianglesReactivity); } render() { - const eatenCheckerPlace = -
- - - -
- -
-
; + const eatenCheckerPlace = ( +
+ + + +
+ +
+
+ ); - return ( -
-
+ return ( +
+
{eatenCheckerPlace}
- - - - + + + +
+
+
- -
- ) - + ); } } -export default DragDropContext(TouchBackend({enableMouseEvents: true}))(Board) +export default DragDropContext(TouchBackend({ enableMouseEvents: true }))( + Board +); diff --git a/dev/app/components/game/Board/style.css b/dev/app/components/game/Board/style.css index d1f66e1..4d91dfc 100644 --- a/dev/app/components/game/Board/style.css +++ b/dev/app/components/game/Board/style.css @@ -1,24 +1,24 @@ -@import "../Point/style.css"; +@import "../Point/style.css"; $border-board-color: #613c07; $border-board-size: 7px; .board { - display: flex; - flex-wrap: wrap; - text-align: center; - height: 80%; - box-shadow: -2px 2px 1px 2px #170303; + display: flex; + flex-wrap: wrap; + text-align: center; + height: 80%; + box-shadow: -2px 2px 1px 2px #170303; } .board * { - box-sizing: border-box; - user-select: none; - cursor: default; + box-sizing: border-box; + user-select: none; + cursor: default; } .subBoardsPanel { - height: 100%; + height: 100%; width: 95%; display: flex; flex-wrap: wrap; @@ -27,71 +27,69 @@ $border-board-size: 7px; } .subBoard { - width: 50%; - height: 50%; - display: flex; + width: 50%; + height: 50%; + display: flex; - .subBoardItem { - display: flex; - flex-direction: column; - flex: 1; - /*overflow-y: hidden;*/ - } + .subBoardItem { + display: flex; + flex-direction: column; + flex: 1; + /*overflow-y: hidden;*/ + } } - - .trianglePoint { - width: calc(100% + 4px); - height: calc(100% + 4px); - stroke: black; - stroke-width: 2px; + width: calc(100% + 4px); + height: calc(100% + 4px); + stroke: black; + stroke-width: 2px; } .visualPoint { - transform: rotate(180deg); - height: 80%; - width: 90%; - display: flex; - flex-direction: column; + transform: rotate(180deg); + height: 80%; + width: 90%; + display: flex; + flex-direction: column; } .subBoardRotated { - @extend .subBoard; - flex-direction: row-reverse; + @extend .subBoard; + flex-direction: row-reverse; - .subBoardItem { - flex-direction: column-reverse; + .subBoardItem { + flex-direction: column-reverse; - :global(.pointViewer) { - flex-direction: column-reverse; + :global(.pointViewer) { + flex-direction: column-reverse; - :global(.checkersContainer){ - flex-direction: column-reverse; - } + :global(.checkersContainer) { + flex-direction: column-reverse; + } - .visualPoint { - transform: rotate(0deg); - } - } + .visualPoint { + transform: rotate(0deg); + } } + } } .eatenCheckerPanel { - height: 100%; - width: 5%; - display: flex; - flex-direction: column; - background: #79500f; - border-top: $border-board-size solid $border-board-color; - border-left: $border-board-size solid $border-board-color; - border-bottom: $border-board-size solid $border-board-color; + height: 100%; + width: 5%; + display: flex; + flex-direction: column; + background: #79500f; + border-top: $border-board-size solid $border-board-color; + border-left: $border-board-size solid $border-board-color; + border-bottom: $border-board-size solid $border-board-color; } .eatenCheckerSubPanel { - width: 100%; - flex: 1; - display: flex; + width: 100%; + flex: 1; + display: flex; } .eatenCheckerSubPanelRotated { @@ -100,20 +98,20 @@ $border-board-size: 7px; :global(.pointViewer) { flex-direction: column-reverse; - :global(.checkersContainer){ + :global(.checkersContainer) { flex-direction: column-reverse; } } } -.eatenCheckerSubPanel :global(.pointViewer){ - height: 100%; +.eatenCheckerSubPanel :global(.pointViewer) { + height: 100%; } -.subBoardItem:nth-child(even) :global(.pointViewer) .visualPoint svg{ +.subBoardItem:nth-child(even) :global(.pointViewer) .visualPoint svg { fill: rgba(165, 42, 42, 0.7); } -.subBoardItem:nth-child(odd) :global(.pointViewer) .visualPoint svg{ +.subBoardItem:nth-child(odd) :global(.pointViewer) .visualPoint svg { fill: rgba(122, 175, 132, 0.8); } diff --git a/dev/app/components/game/Chat/index.js b/dev/app/components/game/Chat/index.js index 07bb517..98153f5 100644 --- a/dev/app/components/game/Chat/index.js +++ b/dev/app/components/game/Chat/index.js @@ -1,114 +1,169 @@ -import React, { Component } from 'react' -import { Input, Button, Label, Segment } from 'semantic-ui-react' -import style from './style.css'; -import socket from '../../../socket'; -import {IO_ACTIONS} from '../../../../common/constants'; - -const message = ({textAlign, color, pointing}) => ({key ,content}) => ( - - - ); -const ClientMessage = message({textAlign:"right", pointing:"right", color:"olive"}); -const OppenentMessage = message({textAlign:"left", pointing:"left", color:"yellow"}) +import React, { Component } from "react"; +import { Input, Button, Label, Segment } from "semantic-ui-react"; +import style from "./style.css"; +import socket from "../../../socket"; +import { IO_ACTIONS } from "../../../../common/constants"; + +const message = ({ textAlign, color, pointing }) => ({ key, content }) => ( + + + +); +const ClientMessage = message({ + textAlign: "right", + pointing: "right", + color: "olive", +}); +const OppenentMessage = message({ + textAlign: "left", + pointing: "left", + color: "yellow", +}); class Chat extends Component { constructor(props) { - super(props) + super(props); - socket.on(IO_ACTIONS.CHAT_MESSAGE, data => { + socket.on(IO_ACTIONS.CHAT_MESSAGE, (data) => { const messages = this.state.messages; - const updatedMessages = [...messages, {key:messages.length, isClient:false, content:data}]; - this.setState({messages:updatedMessages, - messageInputValue:"", - messageInputIsFocused:false}); + const updatedMessages = [ + ...messages, + { key: messages.length, isClient: false, content: data }, + ]; + this.setState({ + messages: updatedMessages, + messageInputValue: "", + messageInputIsFocused: false, + }); }); - this.state = {messages:[], messageInputValue:""}; + this.state = { messages: [], messageInputValue: "" }; this.handleOnKeyPress = ::this.handleOnKeyPress; this.handleOnKeyDown = ::this.handleOnKeyDown; - } + } - sendMessage(){ + sendMessage() { socket.emit(IO_ACTIONS.CHAT_MESSAGE, this.state.messageInputValue); const messages = this.state.messages; - const updatedMessages = [...messages, {key: messages.length, isClient:true, content:this.state.messageInputValue}]; - this.setState({messages:updatedMessages,messageInputValue:""}); + const updatedMessages = [ + ...messages, + { + key: messages.length, + isClient: true, + content: this.state.messageInputValue, + }, + ]; + this.setState({ messages: updatedMessages, messageInputValue: "" }); } - handleInputChange(e, {value}){ - if (this.state.messageInputIsFocused){ - this.setState({messageInputValue:value}); + handleInputChange(e, { value }) { + if (this.state.messageInputIsFocused) { + this.setState({ messageInputValue: value }); } } - setMessageInputFocus(isFocus){ - return () => this.setState({messageInputIsFocused:isFocus}); + setMessageInputFocus(isFocus) { + return () => this.setState({ messageInputIsFocused: isFocus }); } - handleOnKeyDown(e){ - const {messageInputValue, messageInputIsFocused} = this.state; - - if (!messageInputIsFocused){ + handleOnKeyDown(e) { + const { messageInputValue, messageInputIsFocused } = this.state; + if (!messageInputIsFocused) { // Back space - delete - if (e.keyCode == 8){ - this.setState({messageInputValue:messageInputValue.substring(0, messageInputValue.length-1)}); + if (e.keyCode == 8) { + this.setState({ + messageInputValue: messageInputValue.substring( + 0, + messageInputValue.length - 1 + ), + }); } } - if (e.keyCode == 13 && messageInputValue != ""){ + if (e.keyCode == 13 && messageInputValue != "") { ::this.sendMessage(); } } - handleOnKeyPress(e){ - const {messageInputValue, messageInputIsFocused} = this.state; + handleOnKeyPress(e) { + const { messageInputValue, messageInputIsFocused } = this.state; - if (!messageInputIsFocused){ + if (!messageInputIsFocused) { e.preventDefault(); - if (e.keyCode != 13){ + if (e.keyCode != 13) { // handle input change - this.setState({messageInputValue:messageInputValue+e.key}); + this.setState({ messageInputValue: messageInputValue + e.key }); } } } - componentDidMount(){ - document.addEventListener("keypress", this.handleOnKeyPress); - document.addEventListener("keydown", this.handleOnKeyDown); + componentDidMount() { + document.addEventListener("keypress", this.handleOnKeyPress); + document.addEventListener("keydown", this.handleOnKeyDown); } - render(){ + render() { const messages = this.state.messages.map((message, index) => - message.isClient? - - : - ); - - return -
{this.messageContainer = e}} style={{flexGrow: '1', overflowY: 'scroll'}}> - {messages} -
- - }/> -
+ message.isClient ? ( + + ) : ( + + ) + ); + + return ( + +
{ + this.messageContainer = e; + }} + style={{ flexGrow: "1", overflowY: "scroll" }} + > + {messages} +
+ + + } + /> +
+ ); } - componentDidUpdate(){ + componentDidUpdate() { this.messageContainer.scrollTop = this.messageContainer.scrollHeight; } - componentWillUnmount(){ + componentWillUnmount() { document.removeEventListener("keydown", this.handleOnKeyDown); document.removeEventListener("keypress", this.handleOnKeyPress); } } -export default Chat +export default Chat; diff --git a/dev/app/components/game/Chat/style.css b/dev/app/components/game/Chat/style.css index 25d8913..be04478 100644 --- a/dev/app/components/game/Chat/style.css +++ b/dev/app/components/game/Chat/style.css @@ -1,5 +1,5 @@ .chat { display: flex; - flex-direction:column; + flex-direction: column; flex-grow: 1; } diff --git a/dev/app/components/game/Checker/CheckerChip.js b/dev/app/components/game/Checker/CheckerChip.js index 4ec92d3..a5fbd03 100644 --- a/dev/app/components/game/Checker/CheckerChip.js +++ b/dev/app/components/game/Checker/CheckerChip.js @@ -1,7 +1,12 @@ -import React from 'react'; -import style from './style.css' +import React from "react"; +import style from "./style.css"; -const CheckerChip = (props) => -
+const CheckerChip = (props) => ( +
+); -export default CheckerChip +export default CheckerChip; diff --git a/dev/app/components/game/Checker/CheckerDndPreview.js b/dev/app/components/game/Checker/CheckerDndPreview.js index 070e22e..0105942 100644 --- a/dev/app/components/game/Checker/CheckerDndPreview.js +++ b/dev/app/components/game/Checker/CheckerDndPreview.js @@ -1,35 +1,40 @@ -import React, { Component, PropTypes } from 'react' -import { DragLayer } from 'react-dnd' -import CheckerChip from './CheckerChip' +import React, { Component, PropTypes } from "react"; +import { DragLayer } from "react-dnd"; +import CheckerChip from "./CheckerChip"; -import style from './style.css'; +import style from "./style.css"; -const previewCollect = monitor => ({ - sourceOffset: monitor.getSourceClientOffset() - }); +const previewCollect = (monitor) => ({ + sourceOffset: monitor.getSourceClientOffset(), +}); class CheckerPreview extends Component { - static propTypes = { - isDragging: PropTypes.bool, - sourceOffset: PropTypes.shape({ - x: PropTypes.number.isRequired, - y: PropTypes.number.isRequired - }) + isDragging: PropTypes.bool, + sourceOffset: PropTypes.shape({ + x: PropTypes.number.isRequired, + y: PropTypes.number.isRequired, + }), }; - render () { - const { isDragging, sourceOffset } = this.props; - if (!isDragging) { return null; } - - const style2 = { - transform: sourceOffset ? `translate(${sourceOffset.x}px, ${sourceOffset.y}px)` : '' - }; - - return
- -
+ render() { + const { isDragging, sourceOffset } = this.props; + if (!isDragging) { + return null; } + + const style2 = { + transform: sourceOffset + ? `translate(${sourceOffset.x}px, ${sourceOffset.y}px)` + : "", + }; + + return ( +
+ +
+ ); + } } -export default DragLayer(previewCollect)(CheckerPreview) +export default DragLayer(previewCollect)(CheckerPreview); diff --git a/dev/app/components/game/Checker/index.js b/dev/app/components/game/Checker/index.js index 286e002..0ee74c4 100644 --- a/dev/app/components/game/Checker/index.js +++ b/dev/app/components/game/Checker/index.js @@ -1,15 +1,14 @@ -import React, { Component, PropTypes } from 'react' -import { DragSource } from 'react-dnd' -import CheckerChip from './CheckerChip' -import CheckerDndPreview from './CheckerDndPreview' +import React, { Component, PropTypes } from "react"; +import { DragSource } from "react-dnd"; +import CheckerChip from "./CheckerChip"; +import CheckerDndPreview from "./CheckerDndPreview"; const checkerSourceMonitor = { - beginDrag(props, monitor, component) { - return {fromPoint:props.pointId, possibleTargets:props.possibleTargets} + return { fromPoint: props.pointId, possibleTargets: props.possibleTargets }; }, - canDrag(props, monitor){ + canDrag(props, monitor) { return props.isClient; }, @@ -17,7 +16,7 @@ const checkerSourceMonitor = { if (!monitor.didDrop()) { return; } - } + }, }; function collect(connect, monitor) { @@ -25,27 +24,39 @@ function collect(connect, monitor) { connectDragSource: connect.dragSource(), connectDragPreview: connect.dragPreview(), isDragging: monitor.isDragging(), - } + }; } - class Checker extends Component { +class Checker extends Component { static propTypes = { connectDragSource: PropTypes.func.isRequired, isDragging: PropTypes.bool.isRequired, connectDragPreview: PropTypes.func.isRequired, pointId: PropTypes.number.isRequired, - possibleTargets: PropTypes.array.isRequired + possibleTargets: PropTypes.array.isRequired, }; render() { const { connectDragSource, isDragging } = this.props; - if (isDragging){ - return connectDragSource(
) - }else{ - return connectDragSource(
) + if (isDragging) { + return connectDragSource( +
+ +
+ ); + } else { + return connectDragSource( +
+ +
+ ); } } } -export default DragSource("CheckerSource", checkerSourceMonitor, collect)(Checker) +export default DragSource( + "CheckerSource", + checkerSourceMonitor, + collect +)(Checker); diff --git a/dev/app/components/game/Checker/style.css b/dev/app/components/game/Checker/style.css index 69dd0f4..7c040fc 100644 --- a/dev/app/components/game/Checker/style.css +++ b/dev/app/components/game/Checker/style.css @@ -3,18 +3,18 @@ width: 20px; height: 20px; border: solid 1px #555; - border-radius:50%; + border-radius: 50%; transition: box-shadow 0.8s cubic-bezier(0, 0, 0.2, 1); } -.checkerChipClient{ - composes:checkerChip; +.checkerChipClient { + composes: checkerChip; box-shadow: -1px 1px white; background-color: white; } -.checkerChipOpponent{ - composes:checkerChip; +.checkerChipOpponent { + composes: checkerChip; box-shadow: -1px 1px black; background-color: black; } diff --git a/dev/app/components/game/Dice/index.js b/dev/app/components/game/Dice/index.js index d6f3604..9b75db8 100644 --- a/dev/app/components/game/Dice/index.js +++ b/dev/app/components/game/Dice/index.js @@ -1,88 +1,100 @@ -import React, { Component, PropTypes } from 'react' -import style from './style.css' +import React, { Component, PropTypes } from "react"; +import style from "./style.css"; const randomize = (maxNumber, minNumber = 0) => { - return Math.floor(Math.random() * (maxNumber - minNumber)) + minNumber + 1 -} + return Math.floor(Math.random() * (maxNumber - minNumber)) + minNumber + 1; +}; class Dice extends Component { - static propTypes = { - }; + static propTypes = {}; - constructor(props) { - super(props); - this.state = ::this.calcDegreeByNumber(this.props.intialNumber) - this.updateDiceNumber = ::this.updateDiceNumber - } + constructor(props) { + super(props); + this.state = ::this.calcDegreeByNumber(this.props.intialNumber); + this.updateDiceNumber = ::this.updateDiceNumber; + } - componentWillMount(){ - this.props.dicingFire[this.props.diceName] = this.updateDiceNumber + componentWillMount() { + this.props.dicingFire[this.props.diceName] = this.updateDiceNumber; } - calcDegreeByNumber(mumber){ - let nextDegX = 0; - let nextDegY = 0; - let nextDegZ = 0; + calcDegreeByNumber(mumber) { + let nextDegX = 0; + let nextDegY = 0; + let nextDegZ = 0; - switch (mumber){ - // case 1: { - // break; - // } - case 2: { - nextDegX = -90; - break; - } - case 3: { - nextDegY = -90; - break; - } - case 4: { - nextDegY = 90; - break; - } - case 5: { - nextDegX = -90; - nextDegZ = 180; - break; - } - case 6: { - nextDegY = 180; - break; - } - default: { - } + switch (mumber) { + // case 1: { + // break; + // } + case 2: { + nextDegX = -90; + break; + } + case 3: { + nextDegY = -90; + break; + } + case 4: { + nextDegY = 90; + break; } + case 5: { + nextDegX = -90; + nextDegZ = 180; + break; + } + case 6: { + nextDegY = 180; + break; + } + default: { + } + } - const currentDegX = this.state?this.state.degX:0; - const currentDegY = this.state?this.state.degY:0; + const currentDegX = this.state ? this.state.degX : 0; + const currentDegY = this.state ? this.state.degY : 0; - const directX = (currentDegX>0)?-1:1; - const directY = (currentDegY>0)?-1:1; - nextDegX += randomize(1,0)*360*directX; - nextDegY += randomize(1,0)*360*directY; - return {degX:nextDegX, degY:nextDegY, degZ:nextDegZ}; + const directX = currentDegX > 0 ? -1 : 1; + const directY = currentDegY > 0 ? -1 : 1; + nextDegX += randomize(1, 0) * 360 * directX; + nextDegY += randomize(1, 0) * 360 * directY; + return { degX: nextDegX, degY: nextDegY, degZ: nextDegZ }; } - updateDiceNumber(nextNumber){ - this.setState(this.calcDegreeByNumber(nextNumber)); + updateDiceNumber(nextNumber) { + this.setState(this.calcDegreeByNumber(nextNumber)); } render() { - return
-
1
-
2
-
3
-
4
-
5
-
6
-
+ return ( +
+
1
+
2
+
3
+
4
+
5
+
6
+
+ ); } - componentWillUnmount(){ + componentWillUnmount() { delete this.props.dicingFire[this.props.diceName]; } - } -export default Dice +export default Dice; diff --git a/dev/app/components/game/Dice/style.css b/dev/app/components/game/Dice/style.css index 9078ae2..f8b63c3 100644 --- a/dev/app/components/game/Dice/style.css +++ b/dev/app/components/game/Dice/style.css @@ -25,26 +25,26 @@ margin: 0px; } -.one { +.one { transform: translateZ(25px); } - .two { +.two { transform: rotateX(90deg) translateZ(25px); } - .three { +.three { transform: rotateY(90deg) translateZ(25px); } - .four { +.four { transform: rotateY(-90deg) translateZ(25px); } - .five { +.five { transform: rotateX(-90deg) rotate(180deg) translateZ(25px); } - .six { +.six { transform: rotateY(180deg) translateZ(25px); } diff --git a/dev/app/components/game/Dicing/index.js b/dev/app/components/game/Dicing/index.js index be659d0..85954a1 100644 --- a/dev/app/components/game/Dicing/index.js +++ b/dev/app/components/game/Dicing/index.js @@ -1,28 +1,27 @@ -import React, { Component, PropTypes } from 'react' -import {INITIAL_GAME_STATE, IN_GAME_STATUS} from '../../../constants' -import Dice from '../Dice' -import style from './style.css' -import { Container } from 'semantic-ui-react' -import classnames from 'classnames' +import React, { Component, PropTypes } from "react"; +import { INITIAL_GAME_STATE, IN_GAME_STATUS } from "../../../constants"; +import Dice from "../Dice"; +import style from "./style.css"; +import { Container } from "semantic-ui-react"; +import classnames from "classnames"; const randomize = (maxNumber) => { - return Math.floor(Math.random() * maxNumber) + 1; - } + return Math.floor(Math.random() * maxNumber) + 1; +}; // Cancel the container and use state? - class DicingViewer extends Component { +class DicingViewer extends Component { static propTypes = { //onDicing: PropTypes.func.isRequired, dice1: PropTypes.number.isRequired, dice2: PropTypes.number.isRequired, status: PropTypes.number.isRequired, clientTurn: PropTypes.bool.isRequired, - doCubeAnimate : PropTypes.bool.isRequired + doCubeAnimate: PropTypes.bool.isRequired, }; - - constructor(props) { - super(props); + constructor(props) { + super(props); this.initialDiceNumber1 = this.props.dice1; this.initialDiceNumber2 = this.props.dice2; this.cubeRef1; @@ -30,27 +29,34 @@ const randomize = (maxNumber) => { this.oneDiceTransformed = false; this.dicingFire = {}; this.message; - this.state = {message:" "}; + this.state = { message: " " }; //this.onDicing = this.onDicing.bind(this); this.calcMessage = this.calcMessage.bind(this); - this.dicesTransitionEndCallback = this.dicesTransitionEndCallback.bind(this); - } - - dicesTransitionEndCallback(){ + this.dicesTransitionEndCallback = this.dicesTransitionEndCallback.bind( + this + ); + } - if (this.props.clientTurn){ - if (this.oneDiceTransformed){ + dicesTransitionEndCallback() { + if (this.props.clientTurn) { + if (this.oneDiceTransformed) { this.calcMessage(this.props); this.oneDiceTransformed = false; - }else{ + } else { this.oneDiceTransformed = true; } } } - componentDidMount(){ - this.cubeRef1.addEventListener("transitionend", this.dicesTransitionEndCallback); - this.cubeRef2.addEventListener("transitionend", this.dicesTransitionEndCallback); + componentDidMount() { + this.cubeRef1.addEventListener( + "transitionend", + this.dicesTransitionEndCallback + ); + this.cubeRef2.addEventListener( + "transitionend", + this.dicesTransitionEndCallback + ); } onDicing() { @@ -62,61 +68,86 @@ const randomize = (maxNumber) => { this.props.sendDicingResult(dice1Number, dice2Number); } - calcMessage(props = this.props){ - + calcMessage(props = this.props) { let nextMessage = " "; - if (props.clientTurn && props.diced && props.status === IN_GAME_STATUS.STUCK){ - nextMessage = "You don't have legal moves. The turn will be switched in a few moments."; - props.switchTurnTimeout(); + if ( + props.clientTurn && + props.diced && + props.status === IN_GAME_STATUS.STUCK + ) { + nextMessage = + "You don't have legal moves. The turn will be switched in a few moments."; + props.switchTurnTimeout(); } - this.setState({message:nextMessage}); + this.setState({ message: nextMessage }); } render() { - let message = this.state.message; - let turnMessage = this.props.clientTurn?"Your Turn ":"Not your turn " + let turnMessage = this.props.clientTurn ? "Your Turn " : "Not your turn "; - return ( + return (
- this.cubeRef1 = el}/> - this.cubeRef2 = el}/> - - - - {turnMessage}
- {message} -
-
- ) + (this.cubeRef1 = el)} + /> + (this.cubeRef2 = el)} + /> + + + + {turnMessage} +
+ {message} +
+
+ ); } - componentWillReceiveProps(nextProps){ + componentWillReceiveProps(nextProps) { // If it is the point the opponent diced - if (!nextProps.clientTurn && nextProps.diced && - !(!this.props.clientTurn && this.props.diced)){ - //this.setState({dice1:nextProps.dice1, dice2:nextProps.dice2}); - this.dicingFire.dice1(nextProps.dice1); - this.dicingFire.dice2(nextProps.dice2); + if ( + !nextProps.clientTurn && + nextProps.diced && + !(!this.props.clientTurn && this.props.diced) + ) { + //this.setState({dice1:nextProps.dice1, dice2:nextProps.dice2}); + this.dicingFire.dice1(nextProps.dice1); + this.dicingFire.dice2(nextProps.dice2); } - if (!nextProps.clientTurn || !this.props.diced){ - this.setState({message:" "}); - }else{ + if (!nextProps.clientTurn || !this.props.diced) { + this.setState({ message: " " }); + } else { this.calcMessage(nextProps); } } // componentWillUpdate(nextProps, nextState){ // } - componentWillUnmount(){ - // this.cubeRef1.removeEventListener("transitionend", this.dicesTransitionEndCallback); - // this.cubeRef2.removeEventListener("transitionend", this.dicesTransitionEndCallback); + componentWillUnmount() { + // this.cubeRef1.removeEventListener("transitionend", this.dicesTransitionEndCallback); + // this.cubeRef2.removeEventListener("transitionend", this.dicesTransitionEndCallback); } - } -export default DicingViewer +export default DicingViewer; diff --git a/dev/app/components/game/Dicing/style.css b/dev/app/components/game/Dicing/style.css index fc01af6..5617603 100644 --- a/dev/app/components/game/Dicing/style.css +++ b/dev/app/components/game/Dicing/style.css @@ -1,17 +1,16 @@ - @import "../../styles"; .dicing { - height: 20%; - display: flex; - align-items: flex-start; - align-content: flex-start; + height: 20%; + display: flex; + align-items: flex-start; + align-content: flex-start; } .dicing * { - margin: 15px; + margin: 15px; } .messagingContainer * { - margin: 2px; + margin: 2px; } diff --git a/dev/app/components/game/Game.js b/dev/app/components/game/Game.js index 4972d15..e4f3a82 100644 --- a/dev/app/components/game/Game.js +++ b/dev/app/components/game/Game.js @@ -1,15 +1,32 @@ -import React from 'react' -import Board from './Board' -import Chat from './Chat' -import GameInfo from '../../containers/GameInfo' -import { Segment } from 'semantic-ui-react' +import React from "react"; +import Board from "./Board"; +import Chat from "./Chat"; +import GameInfo from "../../containers/GameInfo"; +import { Segment } from "semantic-ui-react"; -const Game = () => -
- - -
- -
+const Game = () => ( + +
+ + +
+ +
+); -export default Game +export default Game; diff --git a/dev/app/components/game/GameInfoViewer.js b/dev/app/components/game/GameInfoViewer.js index 5e59e06..8adc510 100644 --- a/dev/app/components/game/GameInfoViewer.js +++ b/dev/app/components/game/GameInfoViewer.js @@ -1,16 +1,17 @@ -import React from 'react'; -import { Container } from 'semantic-ui-react' -import PlayerCard from '../PlayerHorizontalCard' +import React from "react"; +import { Container } from "semantic-ui-react"; +import PlayerCard from "../PlayerHorizontalCard"; -const GameInfoViewerComponent = ({opponentInfo, leftSteps}) => - - Your opponent: - -

- {`Your remaining steps: ${leftSteps.client}`} -
- {`${opponentInfo.username} remaining steps: ${leftSteps.opponent}`} -

-
+const GameInfoViewerComponent = ({ opponentInfo, leftSteps }) => ( + + Your opponent: + +

+ {`Your remaining steps: ${leftSteps.client}`} +
+ {`${opponentInfo.username} remaining steps: ${leftSteps.opponent}`} +

+
+); -export default GameInfoViewerComponent; +export default GameInfoViewerComponent; diff --git a/dev/app/components/game/Point/index.js b/dev/app/components/game/Point/index.js index dea0a70..cc276f7 100644 --- a/dev/app/components/game/Point/index.js +++ b/dev/app/components/game/Point/index.js @@ -1,32 +1,32 @@ -import React, { Component, PropTypes } from 'react'; -import { DropTarget } from 'react-dnd'; -import Checker from '../Checker'; -import styles from './style.css'; +import React, { Component, PropTypes } from "react"; +import { DropTarget } from "react-dnd"; +import Checker from "../Checker"; +import styles from "./style.css"; const pointTarget = { drop(props, monitor, component) { // It has to be the client. - component.props.receiveChecker(monitor.getItem().fromPoint) - }, - hover(props, monitor, component){ + component.props.receiveChecker(monitor.getItem().fromPoint); }, + hover(props, monitor, component) {}, - canDrop(props, monitor){ + canDrop(props, monitor) { if (!props.isEnabledByState) { return false; } - const numberOfSteps = monitor.getItem().possibleTargets.indexOf(props.pointId) > -1; + const numberOfSteps = + monitor.getItem().possibleTargets.indexOf(props.pointId) > -1; - return (numberOfSteps); - } + return numberOfSteps; + }, }; function collect(connect, monitor) { return { connectDropTarget: connect.dropTarget(), isOver: monitor.isOver(), - canDrop: monitor.canDrop() + canDrop: monitor.canDrop(), }; } @@ -35,33 +35,53 @@ class PointViewer extends Component { isOver: PropTypes.bool.isRequired, canDrop: PropTypes.bool.isRequired, amount: PropTypes.number.isRequired, - isClient:PropTypes.bool.isRequired, - pointId: PropTypes.number.isRequired + isClient: PropTypes.bool.isRequired, + pointId: PropTypes.number.isRequired, }; - constructor(props) { + constructor(props) { super(props); } renderOverlay(color) { - return
+ return ( +
+ ); } render() { - const {connectDropTarget, isOver, canDrop, pointId, amount, isClient, possibleTargets } = this.props; + const { + connectDropTarget, + isOver, + canDrop, + pointId, + amount, + isClient, + possibleTargets, + } = this.props; - const checkers = Array.apply(null, {length: amount}).map((obj, index) => - ()); + const checkers = Array.apply(null, { length: amount }).map((obj, index) => ( + + )); - return connectDropTarget(
- {this.props.children} -
- {checkers} -
- {isOver && !canDrop && ::this.renderOverlay('red')} - {!isOver && canDrop && ::this.renderOverlay('yellow')} - {isOver && canDrop && ::this.renderOverlay('blue')} -
) + return connectDropTarget( +
+ {this.props.children} +
{checkers}
+ {isOver && !canDrop && ::this.renderOverlay("red")} + {!isOver && canDrop && ::this.renderOverlay("yellow")} + {isOver && canDrop && ::this.renderOverlay("blue")} +
+ ); } } diff --git a/dev/app/components/game/Point/style.css b/dev/app/components/game/Point/style.css index 72ff064..678b530 100644 --- a/dev/app/components/game/Point/style.css +++ b/dev/app/components/game/Point/style.css @@ -1,6 +1,5 @@ - :global { -.checkersContainer { + .checkersContainer { position: absolute; width: 100%; height: 90%; @@ -11,9 +10,9 @@ flex-wrap: wrap; align-content: center; align-items: center; -} + } -.pointViewer { + .pointViewer { position: relative; display: flex; flex-direction: column; @@ -21,15 +20,15 @@ flex: 1; overflow-y: auto; overflow-x: hidden; -} + } } .pointViewerOverlay { - position: absolute; - height: 100%; - width: 100%; - opacity: 0.3; - overflow: hidden; + position: absolute; + height: 100%; + width: 100%; + opacity: 0.3; + overflow: hidden; } /*.pointViewerOverlay:after { diff --git a/dev/app/components/styles.css b/dev/app/components/styles.css index b066bd9..7bb4b60 100644 --- a/dev/app/components/styles.css +++ b/dev/app/components/styles.css @@ -1,25 +1,37 @@ $main-menu-height: 70px; .actionButtom { - border-top: 1px solid #000000; - background: -webkit-linear-gradient(top, rgb(110, 185, 27) 0%,rgb(91, 111, 40) 100%); - padding: 13px 13px; - border-radius: 15px; - box-shadow: rgba(0,0,0,1) 0 1px 0; - text-shadow: rgba(0,0,0,.4) 0 1px 0; - color: #ffffff; - text-decoration: none; - font-size: 1.5rem; + border-top: 1px solid #000000; + background: -webkit-linear-gradient( + top, + rgb(110, 185, 27) 0%, + rgb(91, 111, 40) 100% + ); + padding: 13px 13px; + border-radius: 15px; + box-shadow: rgba(0, 0, 0, 1) 0 1px 0; + text-shadow: rgba(0, 0, 0, 0.4) 0 1px 0; + color: #ffffff; + text-decoration: none; + font-size: 1.5rem; } .actionButtom:active { - background: -webkit-linear-gradient(top, rgb(110, 185, 27) 0%,rgb(91, 111, 40) 100%); + background: -webkit-linear-gradient( + top, + rgb(110, 185, 27) 0%, + rgb(91, 111, 40) 100% + ); } .actionButtom:disabled { - color: white; - background: -webkit-linear-gradient(top, rgba(110, 185, 27, 0.5) 0%,rgba(102,142,0,1) 100%); + color: white; + background: -webkit-linear-gradient( + top, + rgba(110, 185, 27, 0.5) 0%, + rgba(102, 142, 0, 1) 100% + ); } .actionButtom:focus { - outline: -webkit-focus-ring-color auto 0px; + outline: -webkit-focus-ring-color auto 0px; } diff --git a/dev/app/components/utils/AutocompleteInput/index.js b/dev/app/components/utils/AutocompleteInput/index.js index 7effc2b..1964b8a 100644 --- a/dev/app/components/utils/AutocompleteInput/index.js +++ b/dev/app/components/utils/AutocompleteInput/index.js @@ -1,149 +1,185 @@ -import React, { Component } from 'react' -import { Input } from 'semantic-ui-react' -import classNames from 'classnames' -import style from './style.css' -import {debounce} from '../../../utils' - -const SearchItem = ({itemData, onItemSelect, renderItem, addedClassName, onMouseEnter}) => -
- {renderItem(itemData)} -
+import React, { Component } from "react"; +import { Input } from "semantic-ui-react"; +import classNames from "classnames"; +import style from "./style.css"; +import { debounce } from "../../../utils"; + +const SearchItem = ({ + itemData, + onItemSelect, + renderItem, + addedClassName, + onMouseEnter, +}) => ( +
+ {renderItem(itemData)} +
+); class AutocompleteInput extends Component { - constructor(props){ - super(props); - this.state = { isLoading: false, - searchResults:[], - serachValue:"", - focusedItem:-1, - showResults:true} + constructor(props) { + super(props); + this.state = { + isLoading: false, + searchResults: [], + serachValue: "", + focusedItem: -1, + showResults: true, + }; this.handleOnKeyDown = ::this.handleOnKeyDown; this.debouncedFecthing = debounce(::this.fetchData, 200); - } - - componentDidMount(){ + } - const { searchableKey, defaultValue, autoFocus } = this.props + componentDidMount() { + const { searchableKey, defaultValue, autoFocus } = this.props; - if (autoFocus){ + if (autoFocus) { document.addEventListener("keydown", this.handleOnKeyDown); - }else{ + } else { this.elementRef.addEventListener("keydown", this.handleOnKeyDown); } - if (defaultValue){ - this.props.searchPromise(defaultValue) - .then(res => { - if (res.data.length == 1 && res.data[0].username==defaultValue){ - ::this.onItemSelect(res.data[0])() - } - }) - .catch(err => { - console.log(err); - }); - - this.setState({serachValue:defaultValue}) + if (defaultValue) { + this.props + .searchPromise(defaultValue) + .then((res) => { + if (res.data.length == 1 && res.data[0].username == defaultValue) { + ::this.onItemSelect(res.data[0])(); + } + }) + .catch((err) => { + console.log(err); + }); + + this.setState({ serachValue: defaultValue }); } } onItemSelect(item) { return () => { - this.setState({searchResults:[], serachValue:item[this.props.searchableKey]}) - this.props.onItemSelect(item) - } + this.setState({ + searchResults: [], + serachValue: item[this.props.searchableKey], + }); + this.props.onItemSelect(item); + }; } - onInputFocus(){ - this.setState({showResults:true}); + onInputFocus() { + this.setState({ showResults: true }); } - handleSearchChange(e, {value}) { - - if (value.length < 2){ - this.setState({ isLoading: false, searchResults:[], serachValue: value }); - }else{ - this.setState({ isLoading: true, serachValue: value }); + handleSearchChange(e, { value }) { + if (value.length < 2) { + this.setState({ + isLoading: false, + searchResults: [], + serachValue: value, + }); + } else { + this.setState({ isLoading: true, serachValue: value }); this.debouncedFecthing(value); } - } + } - fetchData(value){ - this.props.searchPromise(value) - .then(res => { - this.setState({ isLoading: false, searchResults:res.data}); + fetchData(value) { + this.props + .searchPromise(value) + .then((res) => { + this.setState({ isLoading: false, searchResults: res.data }); }) - .catch(err => { + .catch((err) => { console.log(err); }); } - handleOnKeyDown(e){ - const {serachValue, focusedItem, searchResults} = this.state; - if (this.inputElementRef !== document.activeElement){ - this.inputElementRef.focus(); - } + handleOnKeyDown(e) { + const { serachValue, focusedItem, searchResults } = this.state; + if (this.inputElementRef !== document.activeElement) { + this.inputElementRef.focus(); + } - if (e.keyCode == 13){ - if (focusedItem >= 0){ - this.onItemSelect(searchResults[focusedItem])(); - } - } else { - // down - if (e.keyCode == 40){ - // For include -1 in the cirlce - const nextFocused = (focusedItem + 2) % (searchResults.length+1) - 1; - this.setState({focusedItem:nextFocused}); - } - // up - if (e.keyCode == 38){ - const nextFocused = (focusedItem>=0)?(focusedItem - 1):(searchResults.length-1); - this.setState({focusedItem:nextFocused}); - } + if (e.keyCode == 13) { + if (focusedItem >= 0) { + this.onItemSelect(searchResults[focusedItem])(); } + } else { + // down + if (e.keyCode == 40) { + // For include -1 in the cirlce + const nextFocused = + ((focusedItem + 2) % (searchResults.length + 1)) - 1; + this.setState({ focusedItem: nextFocused }); + } + // up + if (e.keyCode == 38) { + const nextFocused = + focusedItem >= 0 ? focusedItem - 1 : searchResults.length - 1; + this.setState({ focusedItem: nextFocused }); + } + } } render() { - - const { renderItem } = this.props - const { serachValue, searchResults, isLoading, focusedItem, showResults } = this.state; - - return
this.elementRef = e} - style={{display: 'inline-block'}} - onMouseLeave={() => this.setState({focusedItem:-1})} - onBlur={() => { - setTimeout(() => this.setState({showResults:true}), 500); - }}> - this.inputElementRef = e} - placeholder='Search...' - style={{marginBottom:'2px'}} - onChange={::this.handleSearchChange} - value={serachValue} - results={searchResults} - loading={isLoading} - onFocus={::this.onInputFocus} - icon="search"/> - {showResults && searchResults.map((item, index) => - this.setState({focusedItem:index})} - onItemSelect={::this.onItemSelect(item)}/>)} -
+ const { renderItem } = this.props; + const { + serachValue, + searchResults, + isLoading, + focusedItem, + showResults, + } = this.state; + + return ( +
(this.elementRef = e)} + style={{ display: "inline-block" }} + onMouseLeave={() => this.setState({ focusedItem: -1 })} + onBlur={() => { + setTimeout(() => this.setState({ showResults: true }), 500); + }} + > + (this.inputElementRef = e)} + placeholder="Search..." + style={{ marginBottom: "2px" }} + onChange={::this.handleSearchChange} + value={serachValue} + results={searchResults} + loading={isLoading} + onFocus={::this.onInputFocus} + icon="search" + /> + {showResults && + searchResults.map((item, index) => ( + this.setState({ focusedItem: index })} + onItemSelect={::this.onItemSelect(item)} + /> + ))} +
+ ); } - componentWillUnmount(){ - if (this.props.autoFocus){ + componentWillUnmount() { + if (this.props.autoFocus) { document.removeEventListener("keydown", this.handleOnKeyDown); - }else{ + } else { this.elementRef.removeEventListener("keydown", this.handleOnKeyDown); } } } -export default AutocompleteInput +export default AutocompleteInput; diff --git a/dev/app/components/utils/AutocompleteInput/style.css b/dev/app/components/utils/AutocompleteInput/style.css index 0fbded1..d375cd3 100644 --- a/dev/app/components/utils/AutocompleteInput/style.css +++ b/dev/app/components/utils/AutocompleteInput/style.css @@ -1,14 +1,17 @@ -.focusedSearchItem, .searchItem { +.focusedSearchItem, +.searchItem { position: relative; text-align: left; } .searchItem:after { - content: '\A'; + content: "\A"; position: absolute; - width: 100%; height:100%; - top:0; left:0; - background:rgb(0,0,0); + width: 100%; + height: 100%; + top: 0; + left: 0; + background: rgb(0, 0, 0); opacity: 0; transition: all 0.5s; -webkit-transition: all 0.5s; @@ -19,11 +22,13 @@ }*/ .focusedSearchItem:after { - content: '\A'; + content: "\A"; position: absolute; - width: 100%; height:100%; - top:0; left:0; - background:rgb(0,0,0); + width: 100%; + height: 100%; + top: 0; + left: 0; + background: rgb(0, 0, 0); opacity: 0.15; transition: all 0.5s; -webkit-transition: all 0.5s; diff --git a/dev/app/components/utils/DynamicLoadTable.Old.js b/dev/app/components/utils/DynamicLoadTable.Old.js index 2696cc8..6a8a8e6 100644 --- a/dev/app/components/utils/DynamicLoadTable.Old.js +++ b/dev/app/components/utils/DynamicLoadTable.Old.js @@ -1,79 +1,105 @@ -import React, { Component } from 'react' -import { Table, Loader } from 'semantic-ui-react' -import {debounce} from '../../utils' +import React, { Component } from "react"; +import { Table, Loader } from "semantic-ui-react"; +import { debounce } from "../../utils"; -const INITIAL_STATE = {offsetItemsPaging:0, pageSize:3, moreItemToLoad:false, isLoadingItems:false, items:[]}; +const INITIAL_STATE = { + offsetItemsPaging: 0, + pageSize: 3, + moreItemToLoad: false, + isLoadingItems: false, + items: [], +}; class DynamicLoadTable extends Component { constructor(props) { - super(props); - this.state = INITIAL_STATE; + super(props); + this.state = INITIAL_STATE; - this.debouncedHandleScroll = debounce(::this.handleScroll, 300); - } - - componentDidMount(){ - ::this.fetchData(); - } + this.debouncedHandleScroll = debounce(::this.handleScroll, 300); + } - fetchData(){ - this.setState({isLoadingItems:true}); - const { offsetItemsPaging, pageSize } = this.state; + componentDidMount() { + ::this.fetchData(); + } - this.props.fetchingMedthod(this.props.username, pageSize, offsetItemsPaging) - .then(res => { + fetchData() { + this.setState({ isLoadingItems: true }); + const { offsetItemsPaging, pageSize } = this.state; - const numberOfNewItems = res.data.length; - const updatedItems = [...this.state.items, ...res.data]; - const newOffsetItemsPaging = this.state.offsetItemsPaging + numberOfNewItems; + this.props + .fetchingMedthod(this.props.username, pageSize, offsetItemsPaging) + .then((res) => { + const numberOfNewItems = res.data.length; + const updatedItems = [...this.state.items, ...res.data]; + const newOffsetItemsPaging = + this.state.offsetItemsPaging + numberOfNewItems; - let moreItemToLoad = true; - if (res.data.length < pageSize){ - moreItemToLoad = false; - } + let moreItemToLoad = true; + if (res.data.length < pageSize) { + moreItemToLoad = false; + } - this.setState({items:updatedItems, - offsetItemsPaging:newOffsetItemsPaging, - moreItemToLoad:moreItemToLoad, - isLoadingItems:false}); - }) - .catch(err => { - console.log(err); - }); - } + this.setState({ + items: updatedItems, + offsetItemsPaging: newOffsetItemsPaging, + moreItemToLoad: moreItemToLoad, + isLoadingItems: false, + }); + }) + .catch((err) => { + console.log(err); + }); + } handleScroll(target) { - if (this.state.moreItemToLoad ){ - if (target.scrollTop + target.clientHeight >= target.scrollHeight ) { + if (this.state.moreItemToLoad) { + if (target.scrollTop + target.clientHeight >= target.scrollHeight) { this.fetchData.call(this); } } } - render(){ - const { className, headerRow, renderBodyRow } = this.props - return
this.debouncedHandleScroll(e.target)}> - + render() { + const { className, headerRow, renderBodyRow } = this.props; + return ( +
this.debouncedHandleScroll(e.target)} + > +
- - - } + + + ); + } - componentWillReceiveProps(nextProps, nextState){ - if (this.props.username != nextProps.username){ + componentWillReceiveProps(nextProps, nextState) { + if (this.props.username != nextProps.username) { this.setState(INITIAL_STATE); } - } + } - componentDidUpdate(prevProps, prevState){ - if (this.props.username != prevProps.username){ - ::this.fetchData(); - } - } + componentDidUpdate(prevProps, prevState) { + if (this.props.username != prevProps.username) { + ::this.fetchData(); + } + } } -export default DynamicLoadTable +export default DynamicLoadTable; diff --git a/dev/app/components/utils/DynamicLoadTable.js b/dev/app/components/utils/DynamicLoadTable.js index c6478e5..0bc926a 100644 --- a/dev/app/components/utils/DynamicLoadTable.js +++ b/dev/app/components/utils/DynamicLoadTable.js @@ -1,32 +1,49 @@ -import React, { Component } from 'react' -import { Table, Loader } from 'semantic-ui-react' -import {debounce} from '../../utils' +import React, { Component } from "react"; +import { Table, Loader } from "semantic-ui-react"; +import { debounce } from "../../utils"; class DynamicLoadTable extends Component { constructor(props) { - super(props); - this.debouncedHandleScroll = debounce(::this.handleScroll, 300); - } + super(props); + this.debouncedHandleScroll = debounce(::this.handleScroll, 300); + } handleScroll(target) { - if (this.props.moreItemToLoad ){ - if (target.scrollTop + target.clientHeight >= target.scrollHeight ) { + if (this.props.moreItemToLoad) { + if (target.scrollTop + target.clientHeight >= target.scrollHeight) { this.props.fetchingMedthod(); } } } - render(){ - const { className, headerRow, renderBodyRow, tableData } = this.props - return
this.debouncedHandleScroll(e.target)}> -
- - - } + render() { + const { className, headerRow, renderBodyRow, tableData } = this.props; + return ( +
this.debouncedHandleScroll(e.target)} + > +
+ + + ); + } } -export default DynamicLoadTable +export default DynamicLoadTable; diff --git a/dev/app/constants/index.js b/dev/app/constants/index.js index 847a7a1..8a1667b 100644 --- a/dev/app/constants/index.js +++ b/dev/app/constants/index.js @@ -1,41 +1,73 @@ -export const PLAY_STATUS = { NOT_PLAY:0, SEARCH_OPPONENT:1, PLAY:2, OPPONENT_RETIRED:3 }; -export const IN_GAME_STATUS = {ONGOING:0, EATEN:1, DROPOUT:2, LOSER:"loser", WINNER:"winner", STUCK:5}; +export const PLAY_STATUS = { + NOT_PLAY: 0, + SEARCH_OPPONENT: 1, + PLAY: 2, + OPPONENT_RETIRED: 3, +}; +export const IN_GAME_STATUS = { + ONGOING: 0, + EATEN: 1, + DROPOUT: 2, + LOSER: "loser", + WINNER: "winner", + STUCK: 5, +}; +export const getInitialGameState = () => ({ + playStatus: PLAY_STATUS.NOT_PLAY, + clientTurn: false, + diced: false, + dicesResult: { dice1: 0, dice2: 0 }, + steps: [], + clientStatus: IN_GAME_STATUS.ONGOING, + checkersState: [ + { amount: 0, isClient: true, pointId: 0 }, -export const getInitialGameState = () => - ({playStatus:PLAY_STATUS.NOT_PLAY, clientTurn:false, diced:false, dicesResult:{dice1:0, dice2:0}, steps:[], - clientStatus:IN_GAME_STATUS.ONGOING, checkersState: [ - {amount:0, isClient:true, pointId:0}, + { amount: 2, isClient: true, pointId: 1 }, + { amount: 0, isClient: true, pointId: 2 }, + { amount: 0, isClient: true, pointId: 3 }, + { amount: 0, isClient: true, pointId: 4 }, + { amount: 0, isClient: true, pointId: 5 }, + { amount: 5, isClient: false, pointId: 6 }, - {amount:2, isClient:true, pointId:1}, {amount:0, isClient:true, pointId:2}, - {amount:0, isClient:true, pointId:3}, {amount:0, isClient:true, pointId:4}, - {amount:0, isClient:true, pointId:5}, {amount:5, isClient:false, pointId:6}, + { amount: 0, isClient: true, pointId: 7 }, + { amount: 3, isClient: false, pointId: 8 }, + { amount: 0, isClient: true, pointId: 9 }, + { amount: 0, isClient: true, pointId: 10 }, + { amount: 0, isClient: true, pointId: 11 }, + { amount: 5, isClient: true, pointId: 12 }, - {amount:0, isClient:true, pointId:7}, {amount:3, isClient:false, pointId:8}, - {amount:0, isClient:true, pointId:9}, {amount:0, isClient:true, pointId:10}, - {amount:0, isClient:true, pointId:11}, {amount:5, isClient:true, pointId:12}, + { amount: 5, isClient: false, pointId: 13 }, + { amount: 0, isClient: true, pointId: 14 }, + { amount: 0, isClient: true, pointId: 15 }, + { amount: 0, isClient: true, pointId: 16 }, + { amount: 3, isClient: true, pointId: 17 }, + { amount: 0, isClient: false, pointId: 18 }, - {amount:5, isClient:false, pointId:13}, {amount:0, isClient:true, pointId:14}, - {amount:0, isClient:true, pointId:15}, {amount:0, isClient:true, pointId:16}, - {amount:3, isClient:true, pointId:17}, {amount:0, isClient:false, pointId:18}, + { amount: 5, isClient: true, pointId: 19 }, + { amount: 0, isClient: true, pointId: 20 }, + { amount: 0, isClient: true, pointId: 21 }, + { amount: 0, isClient: true, pointId: 22 }, + { amount: 0, isClient: true, pointId: 23 }, + { amount: 2, isClient: false, pointId: 24 }, - {amount:5, isClient:true, pointId:19}, {amount:0, isClient:true, pointId:20}, - {amount:0, isClient:true, pointId:21}, {amount:0, isClient:true, pointId:22}, - {amount:0, isClient:true, pointId:23}, {amount:2, isClient:false, pointId:24}, + { amount: 0, isClient: false, pointId: 25 }, + ], +}); - {amount:0, isClient:false, pointId:25} - - ]}); - -export const getInitialSessionState = () => ({isLoggedIn:false, status: PLAY_STATUS.NOT_PLAY, user:{username:"amitush"}}); +export const getInitialSessionState = () => ({ + isLoggedIn: false, + status: PLAY_STATUS.NOT_PLAY, + user: { username: "amitush" }, +}); //export const INITIAL_STATE = {game:INITIAL_GAME_STATE, session:INITIAL_SESSION_STATE}; - - - - -export const POINTS_ON_BOARD = { pointsI:[1,2,3,4,5,6], pointsII:[7,8,9,10,11,12], - pointsIII:[13,14,15,16,17,18], pointsIV:[19,20,21,22,23,24]}; +export const POINTS_ON_BOARD = { + pointsI: [1, 2, 3, 4, 5, 6], + pointsII: [7, 8, 9, 10, 11, 12], + pointsIII: [13, 14, 15, 16, 17, 18], + pointsIV: [19, 20, 21, 22, 23, 24], +}; /////////////////////// // | // diff --git a/dev/app/containers/Dicing.js b/dev/app/containers/Dicing.js index 19f3c95..6b2e37f 100644 --- a/dev/app/containers/Dicing.js +++ b/dev/app/containers/Dicing.js @@ -1,6 +1,6 @@ -import { connect } from 'react-redux' -import { dice, switchTurn } from '../actions' -import DicingViewer from '../components/game/Dicing' +import { connect } from "react-redux"; +import { dice, switchTurn } from "../actions"; +import DicingViewer from "../components/game/Dicing"; const mapStateToProps = (state, ownProps) => ({ //isEnabled: (state.clientTurn && !state.diced), @@ -9,25 +9,22 @@ const mapStateToProps = (state, ownProps) => ({ status: state.app.game.clientStatus, clientTurn: state.app.game.clientTurn, diced: state.app.game.diced, - doCubeAnimate: !ownProps.diced && state.app.game.diced -}) + doCubeAnimate: !ownProps.diced && state.app.game.diced, +}); const randomize = () => { - return Math.floor(Math.random() * 6) + 1; - } + return Math.floor(Math.random() * 6) + 1; +}; const mapDispatchToProps = (dispatch, ownProps) => ({ sendDicingResult: (resultDice1, resultDice2) => { - dispatch(dice({dice1:resultDice1, dice2:resultDice2})) + dispatch(dice({ dice1: resultDice1, dice2: resultDice2 })); }, switchTurnTimeout: () => { setTimeout(() => dispatch(switchTurn()), 4000); - } -}) + }, +}); -const Dicing = connect( - mapStateToProps, - mapDispatchToProps -)(DicingViewer) +const Dicing = connect(mapStateToProps, mapDispatchToProps)(DicingViewer); -export default Dicing +export default Dicing; diff --git a/dev/app/containers/GameInfo.js b/dev/app/containers/GameInfo.js index ebc38ac..413238d 100644 --- a/dev/app/containers/GameInfo.js +++ b/dev/app/containers/GameInfo.js @@ -1,25 +1,27 @@ -import { connect } from 'react-redux' -import GameInfoViewer from '../components/game/GameInfoViewer' +import { connect } from "react-redux"; +import GameInfoViewer from "../components/game/GameInfoViewer"; const mapStateToProps = (state, ownProps) => { + // Calc how many steps left for each player. + const totalLeftSteps = state.app.game.checkersState.reduce( + (leftSteps, point) => { + if (point.isClient) { + const sum = leftSteps.client + point.amount * (25 - point.pointId); + return { ...leftSteps, client: sum }; + } else { + const sum = leftSteps.opponent + point.amount * point.pointId; + return { ...leftSteps, opponent: sum }; + } + }, + { client: 0, opponent: 0 } + ); - // Calc how many steps left for each player. - const totalLeftSteps = state.app.game.checkersState.reduce((leftSteps, point) => { - if (point.isClient){ - const sum = leftSteps.client+point.amount*(25-point.pointId); - return {...leftSteps,client:sum}; - } else{ - const sum = leftSteps.opponent+point.amount*point.pointId; - return {...leftSteps,opponent:sum}; - } - }, {client:0, opponent:0}); - - return { opponentInfo:state.app.game.opponentInfo, leftSteps:totalLeftSteps } + return { + opponentInfo: state.app.game.opponentInfo, + leftSteps: totalLeftSteps, + }; }; +const GameInfo = connect(mapStateToProps)(GameInfoViewer); -const GameInfo = connect( - mapStateToProps -)(GameInfoViewer) - -export default GameInfo +export default GameInfo; diff --git a/dev/app/containers/GameZone.js b/dev/app/containers/GameZone.js index 95045a8..17a612f 100644 --- a/dev/app/containers/GameZone.js +++ b/dev/app/containers/GameZone.js @@ -1,23 +1,19 @@ -import React from 'react'; -import { connect } from 'react-redux'; -import GameZoneViewer from '../components/GameZone'; -import { searchOpponent } from '../actions'; - +import React from "react"; +import { connect } from "react-redux"; +import GameZoneViewer from "../components/GameZone"; +import { searchOpponent } from "../actions"; const mapStateToProps = (state, ownProps) => ({ - playStatus:state.app.game.playStatus, - inGameStatus:state.app.game.clientStatus -}) + playStatus: state.app.game.playStatus, + inGameStatus: state.app.game.clientStatus, +}); const mapDispatchToProps = (dispatch, ownProps) => ({ play: () => { dispatch(searchOpponent()); - } -}) + }, +}); -const GameZone = connect( - mapStateToProps, - mapDispatchToProps -)(GameZoneViewer) +const GameZone = connect(mapStateToProps, mapDispatchToProps)(GameZoneViewer); -export default GameZone +export default GameZone; diff --git a/dev/app/containers/HittenCheckersArea.js b/dev/app/containers/HittenCheckersArea.js index 637ab47..808ed65 100644 --- a/dev/app/containers/HittenCheckersArea.js +++ b/dev/app/containers/HittenCheckersArea.js @@ -1,13 +1,13 @@ -import { connect } from 'react-redux' -import HittenCheckersAreaViewer from '../components/game/Board/HittenCheckersAreaViewer' +import { connect } from "react-redux"; +import HittenCheckersAreaViewer from "../components/game/Board/HittenCheckersAreaViewer"; const mapStateToProps = (state, ownProps) => ({ - toBlink:state.app.game.checkersState.find(point => (point.pointId == ownProps.pointId)).amount > 0 && - state.app.game.clientTurn -}) + toBlink: + state.app.game.checkersState.find( + (point) => point.pointId == ownProps.pointId + ).amount > 0 && state.app.game.clientTurn, +}); -const HittenCheckersArea = connect( - mapStateToProps -)(HittenCheckersAreaViewer) +const HittenCheckersArea = connect(mapStateToProps)(HittenCheckersAreaViewer); -export default HittenCheckersArea +export default HittenCheckersArea; diff --git a/dev/app/containers/Login.js b/dev/app/containers/Login.js index ccbed31..1095736 100644 --- a/dev/app/containers/Login.js +++ b/dev/app/containers/Login.js @@ -1,21 +1,17 @@ -import { connect } from 'react-redux' -import LoginViewer from '../components/Login' -import { login } from '../actions' - +import { connect } from "react-redux"; +import LoginViewer from "../components/Login"; +import { login } from "../actions"; const mapStateToProps = (state, ownProps) => ({ - isLoggedIn:state.app.session.isLoggedIn -}) + isLoggedIn: state.app.session.isLoggedIn, +}); const mapDispatchToProps = (dispatch, ownProps) => ({ login: (user) => { dispatch(login(user)); - } -}) + }, +}); -const Login = connect( - mapStateToProps, - mapDispatchToProps -)(LoginViewer) +const Login = connect(mapStateToProps, mapDispatchToProps)(LoginViewer); -export default Login +export default Login; diff --git a/dev/app/containers/Point.js b/dev/app/containers/Point.js index 1b092b6..0751476 100644 --- a/dev/app/containers/Point.js +++ b/dev/app/containers/Point.js @@ -1,26 +1,34 @@ -import { connect } from 'react-redux' -import { step } from '../actions' -import PointViewer from '../components/game/Point' -import {canBeDraggedTo, isPointCanDragTarget} from '../rules' +import { connect } from "react-redux"; +import { step } from "../actions"; +import PointViewer from "../components/game/Point"; +import { canBeDraggedTo, isPointCanDragTarget } from "../rules"; const mapStateToProps = (state, ownProps) => { - - const { clientStatus, checkersState, steps } = state.app.game; - const {amount, isClient, pointId} = checkersState.find(point => point.pointId == ownProps.pointId); - - const isEnabledByState = isPointCanDragTarget(pointId, clientStatus); - const possibleTargets = canBeDraggedTo(pointId, checkersState, steps, clientStatus); - - return {amount, isClient, pointId, possibleTargets, isEnabledByState} -} + const { clientStatus, checkersState, steps } = state.app.game; + const { amount, isClient, pointId } = checkersState.find( + (point) => point.pointId == ownProps.pointId + ); + + const isEnabledByState = isPointCanDragTarget(pointId, clientStatus); + const possibleTargets = canBeDraggedTo( + pointId, + checkersState, + steps, + clientStatus + ); + + return { amount, isClient, pointId, possibleTargets, isEnabledByState }; +}; const mapDispatchToProps = (dispatch, ownProps) => ({ receiveChecker: (fromPoint) => { - //if (ownProps.isEnabled){ - dispatch(step({fromPoint:fromPoint, toPoint:ownProps.pointId, isClient: true})) - //} - } -}) + //if (ownProps.isEnabled){ + dispatch( + step({ fromPoint: fromPoint, toPoint: ownProps.pointId, isClient: true }) + ); + //} + }, +}); // function mergeProps(stateProps, dispatchProps, ownProps) { // return { @@ -30,9 +38,6 @@ const mapDispatchToProps = (dispatch, ownProps) => ({ // }; // } -const Point = connect( - mapStateToProps, - mapDispatchToProps -)(PointViewer) +const Point = connect(mapStateToProps, mapDispatchToProps)(PointViewer); -export default Point +export default Point; diff --git a/dev/app/containers/PrivateRoute.js b/dev/app/containers/PrivateRoute.js index 75c9e43..efeb99c 100644 --- a/dev/app/containers/PrivateRoute.js +++ b/dev/app/containers/PrivateRoute.js @@ -1,22 +1,21 @@ -import { connect } from 'react-redux' -import PrivateRouteViewer from '../components/PrivateRoute' -import { logout } from '../actions'; - +import { connect } from "react-redux"; +import PrivateRouteViewer from "../components/PrivateRoute"; +import { logout } from "../actions"; const mapStateToProps = (state, ownProps) => ({ - isLoggedIn:state.app.session.isLoggedIn, - userInfo:state.app.session.user -}) + isLoggedIn: state.app.session.isLoggedIn, + userInfo: state.app.session.user, +}); const mapDispatchToProps = (dispatch, ownProps) => ({ logout: () => { dispatch(logout()); - } -}) + }, +}); const PrivateRoute = connect( mapStateToProps, mapDispatchToProps -)(PrivateRouteViewer) +)(PrivateRouteViewer); -export default PrivateRoute +export default PrivateRoute; diff --git a/dev/app/index.js b/dev/app/index.js index be0a80b..705102f 100644 --- a/dev/app/index.js +++ b/dev/app/index.js @@ -1,55 +1,61 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import { createStore, applyMiddleware, combineReducers } from 'redux'; -import { Provider } from 'react-redux'; -import reducer from './reducers/index'; - -import socketIoMiddleware from './middlewares/socketio'; -import spamUserActionFilter from './middlewares/spamUserActionFilter'; -import logger from 'redux-logger'; - -import { ApolloClient, ApolloProvider, createNetworkInterface} from 'react-apollo'; - - -import App from './components/App'; -import {getInitialGameState, getInitialSessionState} from './constants'; -import { login } from './actions'; -import 'semantic-ui-css/semantic.min.css'; -import { AppContainer } from 'react-hot-loader' - +import React from "react"; +import ReactDOM from "react-dom"; +import { createStore, applyMiddleware, combineReducers } from "redux"; +import { Provider } from "react-redux"; +import reducer from "./reducers/index"; + +import socketIoMiddleware from "./middlewares/socketio"; +import spamUserActionFilter from "./middlewares/spamUserActionFilter"; +import logger from "redux-logger"; + +import { + ApolloClient, + ApolloProvider, + createNetworkInterface, +} from "react-apollo"; + +import App from "./components/App"; +import { getInitialGameState, getInitialSessionState } from "./constants"; +import { login } from "./actions"; +import "semantic-ui-css/semantic.min.css"; +import { AppContainer } from "react-hot-loader"; const apolloClient = new ApolloClient({ - networkInterface: createNetworkInterface({uri: '/graphql'}) + networkInterface: createNetworkInterface({ uri: "/graphql" }), }); -let middlewares = [apolloClient.middleware(), spamUserActionFilter, socketIoMiddleware]; +let middlewares = [ + apolloClient.middleware(), + spamUserActionFilter, + socketIoMiddleware, +]; -if (process.env.NODE_ENV != 'production'){ - middlewares.unshift(logger); +if (process.env.NODE_ENV != "production") { + middlewares.unshift(logger); } -const store = createStore(combineReducers({app:reducer, - apollo: apolloClient.reducer()}), - {app:{game:getInitialGameState(), session:getInitialSessionState()}}, - applyMiddleware(...middlewares)); - +const store = createStore( + combineReducers({ app: reducer, apollo: apolloClient.reducer() }), + { app: { game: getInitialGameState(), session: getInitialSessionState() } }, + applyMiddleware(...middlewares) +); -const render = Component => { +const render = (Component) => { ReactDOM.render( - - {Component} - , - document.getElementById('app') - ) -} + {Component}, + document.getElementById("app") + ); +}; -render( - - ); +render( + + + +); if (module.hot) { - module.hot.accept() + module.hot.accept(); // module.hot.accept('./containers/App', () => { render( - // - // ) }) + // + // ) }) } diff --git a/dev/app/middlewares/socketio.js b/dev/app/middlewares/socketio.js index 633032a..61b9a60 100644 --- a/dev/app/middlewares/socketio.js +++ b/dev/app/middlewares/socketio.js @@ -1,78 +1,89 @@ - -import * as actions from '../actions'; -import {IO_ACTIONS} from '../../common/constants'; -import config from '../../common/config'; -import socket from '../socket'; -import {IN_GAME_STATUS} from '../constants'; +import * as actions from "../actions"; +import { IO_ACTIONS } from "../../common/constants"; +import config from "../../common/config"; +import socket from "../socket"; +import { IN_GAME_STATUS } from "../constants"; const initSocket = (store, username) => { - - const isGuest = store.getState().app.session.user.playAsGuest - socket.init(document.location.host, { query: `username=${username}&isGuest=${isGuest}`}); - - socket.on('disconnect', () => { - console.warn('Server disconnected'); + const isGuest = store.getState().app.session.user.playAsGuest; + socket.init(document.location.host, { + query: `username=${username}&isGuest=${isGuest}`, }); - socket.on(IO_ACTIONS.START_GAME, data => { + socket.on("disconnect", () => { + console.warn("Server disconnected"); + }); - store.dispatch(actions.startGame(data.start, data.opponentInfo)); - //store.dispatch(setTurn(data.start)); + socket.on(IO_ACTIONS.START_GAME, (data) => { + store.dispatch(actions.startGame(data.start, data.opponentInfo)); + //store.dispatch(setTurn(data.start)); }); - socket.on(IO_ACTIONS.GAME_ACTION, data => { - store.dispatch({type:data.type, fromServer:true, content:data.content}); + socket.on(IO_ACTIONS.GAME_ACTION, (data) => { + store.dispatch({ + type: data.type, + fromServer: true, + content: data.content, + }); }); socket.on(IO_ACTIONS.OPPONENT_RETIREMENT, () => { - store.dispatch(actions.opponentRetirment()); + store.dispatch(actions.opponentRetirment()); }); }; +const socketIoMiddleware = (store) => (next) => (action) => { + if (action) { + if (action.type == actions.LOG_OUT) { + socket.close(); + } -const socketIoMiddleware = store => next => action => { - - - if (action){ - if (action.type == actions.LOG_OUT){ - socket.close(); - } - - if (action.type == actions.SEARCH_OPPONENT){ - socket.emit(IO_ACTIONS.SEARCH_NEW_OPPONENT); - } - - if (((action.type == actions.STEP) || (action.type == actions.SWITCH_TURN) || (action.type == actions.DICING)) - && !action.fromServer){ - socket.emit(IO_ACTIONS.GAME_ACTION, convertActionToOpponent(action)); - + if (action.type == actions.SEARCH_OPPONENT) { + socket.emit(IO_ACTIONS.SEARCH_NEW_OPPONENT); + } - } + if ( + (action.type == actions.STEP || + action.type == actions.SWITCH_TURN || + action.type == actions.DICING) && + !action.fromServer + ) { + socket.emit(IO_ACTIONS.GAME_ACTION, convertActionToOpponent(action)); } - const ret = next(action); + } + const ret = next(action); - // TODO do it better. - if (action){ - if (action.type == actions.LOG_IN){ - initSocket(store, action.content.username); - } + // TODO do it better. + if (action) { + if (action.type == actions.LOG_IN) { + initSocket(store, action.content.username); + } - if ((action.type == actions.STEP) && (store.getState().app.game.clientStatus == IN_GAME_STATUS.WINNER)){ - socket.emit(IO_ACTIONS.GAME_OVER); - } + if ( + action.type == actions.STEP && + store.getState().app.game.clientStatus == IN_GAME_STATUS.WINNER + ) { + socket.emit(IO_ACTIONS.GAME_OVER); + } } - return ret; + return ret; }; -const convertActionToOpponent = action => { - switch (action.type){ - case actions.STEP:{ - const {isClient, fromPoint, toPoint} = action.content; - return Object.assign({}, action, {content:{ isClient:!isClient, toPoint: 25-toPoint, fromPoint: 25-fromPoint }}) - } - default: - return action +const convertActionToOpponent = (action) => { + switch (action.type) { + case actions.STEP: { + const { isClient, fromPoint, toPoint } = action.content; + return Object.assign({}, action, { + content: { + isClient: !isClient, + toPoint: 25 - toPoint, + fromPoint: 25 - fromPoint, + }, + }); + } + default: + return action; } -} +}; export default socketIoMiddleware; diff --git a/dev/app/middlewares/spamUserActionFilter.js b/dev/app/middlewares/spamUserActionFilter.js index 5e5c7f9..0e3a459 100644 --- a/dev/app/middlewares/spamUserActionFilter.js +++ b/dev/app/middlewares/spamUserActionFilter.js @@ -1,12 +1,15 @@ -import { STEP } from '../actions' +import { STEP } from "../actions"; -const spamUserActionFilter = store => next => action => { - - if (action.type !== STEP || action.fromServer || store.getState().app.game.clientTurn){ - return next(action); - }else{ - return action; - } +const spamUserActionFilter = (store) => (next) => (action) => { + if ( + action.type !== STEP || + action.fromServer || + store.getState().app.game.clientTurn + ) { + return next(action); + } else { + return action; + } }; -export default spamUserActionFilter +export default spamUserActionFilter; diff --git a/dev/app/reducers/game.js b/dev/app/reducers/game.js index 64436f7..867dd4c 100644 --- a/dev/app/reducers/game.js +++ b/dev/app/reducers/game.js @@ -1,121 +1,186 @@ -import { STEP, DICING, SWITCH_TURN, SRART_GAME, SEARCH_OPPONENT, OPPONENT_RETIRED, LOG_IN } from '../actions' -import {getInitialGameState, IN_GAME_STATUS, PLAY_STATUS, CHECKERS_ORDER} from '../constants' -import {getStateByBoard} from '../rules' +import { + STEP, + DICING, + SWITCH_TURN, + SRART_GAME, + SEARCH_OPPONENT, + OPPONENT_RETIRED, + LOG_IN, +} from "../actions"; +import { + getInitialGameState, + IN_GAME_STATUS, + PLAY_STATUS, + CHECKERS_ORDER, +} from "../constants"; +import { getStateByBoard } from "../rules"; const updateSteps = (fromPoint, toPoint, currentStep) => { - let stepLength = Math.abs(toPoint-fromPoint); + let stepLength = Math.abs(toPoint - fromPoint); - const stepIndex = currentStep.indexOf(stepLength); - let updatedSteps; + const stepIndex = currentStep.indexOf(stepLength); + let updatedSteps; - if (stepIndex > -1){ - updatedSteps = [...currentStep.slice(0, stepIndex), ...currentStep.slice(stepIndex+1)] + if (stepIndex > -1) { + updatedSteps = [ + ...currentStep.slice(0, stepIndex), + ...currentStep.slice(stepIndex + 1), + ]; - // continious step or - // drop out max case then (remove the max which is the first) - }else{ - updatedSteps = [...currentStep]; + // continious step or + // drop out max case then (remove the max which is the first) + } else { + updatedSteps = [...currentStep]; - while (stepLength > 0){ - stepLength -= updatedSteps[0]; - updatedSteps = updatedSteps.slice(1); - } - } + while (stepLength > 0) { + stepLength -= updatedSteps[0]; + updatedSteps = updatedSteps.slice(1); + } + } - return updatedSteps; -} + return updatedSteps; +}; const moveChecker = (fromPoint, toPoint, isClientTurn, checkersState) => { - let newCheckersState = checkersState.slice(0); - const sroucePoint = newCheckersState.find(point => point.pointId == fromPoint); - const tragetPoint = newCheckersState.find(point => point.pointId == toPoint); - - sroucePoint.amount--; - - // if eating rival checker - if (isClientTurn && !tragetPoint.isClient && tragetPoint.amount==1 && - tragetPoint.pointId != 25){ //ignore eating in dropout - tragetPoint.isClient = sroucePoint.isClient; - newCheckersState.find(point => (point.pointId == 25)).amount++; - - // if the rival ate the client - } else if (!isClientTurn && tragetPoint.isClient && tragetPoint.amount==1&& - tragetPoint.pointId != 0){ //ignore eating in dropout - tragetPoint.isClient = sroucePoint.isClient; - newCheckersState.find(point => (point.pointId == 0)).amount++; - - // In case any player drop out the checker we don't update the target. - } else if (!(isClientTurn && tragetPoint.pointId == 25) && - !(!isClientTurn && tragetPoint.pointId == 0)){ - tragetPoint.amount++; - tragetPoint.isClient = isClientTurn; - } - - return newCheckersState; -} + let newCheckersState = checkersState.slice(0); + const sroucePoint = newCheckersState.find( + (point) => point.pointId == fromPoint + ); + const tragetPoint = newCheckersState.find( + (point) => point.pointId == toPoint + ); + + sroucePoint.amount--; + + // if eating rival checker + if ( + isClientTurn && + !tragetPoint.isClient && + tragetPoint.amount == 1 && + tragetPoint.pointId != 25 + ) { + //ignore eating in dropout + tragetPoint.isClient = sroucePoint.isClient; + newCheckersState.find((point) => point.pointId == 25).amount++; + + // if the rival ate the client + } else if ( + !isClientTurn && + tragetPoint.isClient && + tragetPoint.amount == 1 && + tragetPoint.pointId != 0 + ) { + //ignore eating in dropout + tragetPoint.isClient = sroucePoint.isClient; + newCheckersState.find((point) => point.pointId == 0).amount++; + + // In case any player drop out the checker we don't update the target. + } else if ( + !(isClientTurn && tragetPoint.pointId == 25) && + !(!isClientTurn && tragetPoint.pointId == 0) + ) { + tragetPoint.amount++; + tragetPoint.isClient = isClientTurn; + } + + return newCheckersState; +}; const reducer = (state = getInitialGameState(), action) => { - - switch (action.type){ - case DICING:{ - const dicesResult = action.content; - let newSteps; - if (dicesResult.dice1 == dicesResult.dice2){ - newSteps = Array(4).fill(dicesResult.dice1); - }else{ - // sort because calculate 'farestPoint' in rules.js - newSteps = [dicesResult.dice1, dicesResult.dice2].sort(); - } - - // update the status only if it's client turn. - const clientStatus = state.clientTurn?getStateByBoard(state.checkersState, newSteps):IN_GAME_STATUS.ONGOING; - - - - return {...state, clientStatus:clientStatus, diced:true, dicesResult:dicesResult, steps:newSteps}; - } - - case STEP:{ - const {fromPoint, toPoint, isClient} = action.content; - - const updatedSteps = updateSteps(fromPoint, toPoint,state.steps); - const newCheckersState = moveChecker(fromPoint, toPoint, isClient, state.checkersState); - const clientStatus = getStateByBoard(state.checkersState, updatedSteps); - - const playStatus = (clientStatus == IN_GAME_STATUS.WINNER || clientStatus == IN_GAME_STATUS.LOSER)? - PLAY_STATUS.NOT_PLAY:state.playStatus; - - // No steps then finish the turn - if (updatedSteps.length==0){ - return {...state, checkersState:newCheckersState, clientStatus:clientStatus, - diced:false, clientTurn: !state.clientTurn, steps:updatedSteps, playStatus:playStatus} - }else{ - return {...state, checkersState:newCheckersState, clientStatus:clientStatus, - clientTurn: state.clientTurn, steps:updatedSteps, playStatus:playStatus} - - } - } - - case SWITCH_TURN:{ - return {...state, clientTurn:!state.clientTurn, diced:false, steps:[]} - } - case SRART_GAME:{ - - return {...getInitialGameState(), clientTurn:action.content.isClientStart, - playStatus: PLAY_STATUS.PLAY, opponentInfo:action.content.opponentInfo } - } - case SEARCH_OPPONENT:{ - return { ...state, playStatus: PLAY_STATUS.SEARCH_OPPONENT }; - } - case OPPONENT_RETIRED:{ - return { ...state, playStatus: PLAY_STATUS.OPPONENT_RETIRED }; - } - case LOG_IN:{ - return getInitialGameState(); - } - default: - return state - } -} + switch (action.type) { + case DICING: { + const dicesResult = action.content; + let newSteps; + if (dicesResult.dice1 == dicesResult.dice2) { + newSteps = Array(4).fill(dicesResult.dice1); + } else { + // sort because calculate 'farestPoint' in rules.js + newSteps = [dicesResult.dice1, dicesResult.dice2].sort(); + } + + // update the status only if it's client turn. + const clientStatus = state.clientTurn + ? getStateByBoard(state.checkersState, newSteps) + : IN_GAME_STATUS.ONGOING; + + return { + ...state, + clientStatus: clientStatus, + diced: true, + dicesResult: dicesResult, + steps: newSteps, + }; + } + + case STEP: { + const { fromPoint, toPoint, isClient } = action.content; + + const updatedSteps = updateSteps(fromPoint, toPoint, state.steps); + const newCheckersState = moveChecker( + fromPoint, + toPoint, + isClient, + state.checkersState + ); + const clientStatus = getStateByBoard(state.checkersState, updatedSteps); + + const playStatus = + clientStatus == IN_GAME_STATUS.WINNER || + clientStatus == IN_GAME_STATUS.LOSER + ? PLAY_STATUS.NOT_PLAY + : state.playStatus; + + // No steps then finish the turn + if (updatedSteps.length == 0) { + return { + ...state, + checkersState: newCheckersState, + clientStatus: clientStatus, + diced: false, + clientTurn: !state.clientTurn, + steps: updatedSteps, + playStatus: playStatus, + }; + } else { + return { + ...state, + checkersState: newCheckersState, + clientStatus: clientStatus, + clientTurn: state.clientTurn, + steps: updatedSteps, + playStatus: playStatus, + }; + } + } + + case SWITCH_TURN: { + return { + ...state, + clientTurn: !state.clientTurn, + diced: false, + steps: [], + }; + } + case SRART_GAME: { + return { + ...getInitialGameState(), + clientTurn: action.content.isClientStart, + playStatus: PLAY_STATUS.PLAY, + opponentInfo: action.content.opponentInfo, + }; + } + case SEARCH_OPPONENT: { + return { ...state, playStatus: PLAY_STATUS.SEARCH_OPPONENT }; + } + case OPPONENT_RETIRED: { + return { ...state, playStatus: PLAY_STATUS.OPPONENT_RETIRED }; + } + case LOG_IN: { + return getInitialGameState(); + } + default: + return state; + } +}; export default reducer; diff --git a/dev/app/reducers/index.js b/dev/app/reducers/index.js index d077a81..29bb820 100644 --- a/dev/app/reducers/index.js +++ b/dev/app/reducers/index.js @@ -1,10 +1,10 @@ -import { combineReducers } from 'redux' -import game from './game' -import session from './session' +import { combineReducers } from "redux"; +import game from "./game"; +import session from "./session"; const rootReducer = combineReducers({ game, - session -}) + session, +}); -export default rootReducer \ No newline at end of file +export default rootReducer; diff --git a/dev/app/reducers/session.js b/dev/app/reducers/session.js index eb61a81..8c2d192 100644 --- a/dev/app/reducers/session.js +++ b/dev/app/reducers/session.js @@ -1,20 +1,19 @@ -import { LOG_IN, LOG_OUT } from '../actions'; -import { getInitialSessionState } from '../constants'; +import { LOG_IN, LOG_OUT } from "../actions"; +import { getInitialSessionState } from "../constants"; const reducer = (state = getInitialSessionState(), action) => { + switch (action.type) { + case LOG_IN: { + return { isLoggedIn: true, user: action.content }; + } - switch (action.type){ - case LOG_IN:{ - return {isLoggedIn:true, user:action.content}; - } + case LOG_OUT: { + return { isLoggedIn: false }; + } - case LOG_OUT:{ - return { isLoggedIn:false }; - } - - default: - return state - } -} + default: + return state; + } +}; export default reducer; diff --git a/dev/app/rules/index.js b/dev/app/rules/index.js index e88009a..563c6ce 100644 --- a/dev/app/rules/index.js +++ b/dev/app/rules/index.js @@ -1,154 +1,173 @@ -import { IN_GAME_STATUS} from '../constants' - -const getPoint = (board, pointId) => (board.find(point => (point.pointId == pointId))); - -const isPointFree = (point) => (point.isClient || point.amount<=1 || point.pointId == 25); - -const numberOfCheckersInBoard = (board, isClient, minPoint = 0 , maxPoint = 25) => - (board.reduce((sumChecker, point) => { - if (point.isClient == isClient && point.pointId>=minPoint && point.pointId<=maxPoint){ - return sumChecker + point.amount - }else{ - return sumChecker; - } - },0)) +import { IN_GAME_STATUS } from "../constants"; + +const getPoint = (board, pointId) => + board.find((point) => point.pointId == pointId); + +const isPointFree = (point) => + point.isClient || point.amount <= 1 || point.pointId == 25; + +const numberOfCheckersInBoard = ( + board, + isClient, + minPoint = 0, + maxPoint = 25 +) => + board.reduce((sumChecker, point) => { + if ( + point.isClient == isClient && + point.pointId >= minPoint && + point.pointId <= maxPoint + ) { + return sumChecker + point.amount; + } else { + return sumChecker; + } + }, 0); // Only for client const isStuckInPoint = (pointId, board, steps, clientState) => { - const possibleTargetPointsIds = canBeDraggedTo(pointId, board, steps, clientState); - return board.findIndex(p => (possibleTargetPointsIds.indexOf(p.pointId) > -1 && - isPointFree(p))) == -1; -} - - -const possibleClientContiniousSteps = (pointId, board, singleSteps) =>{ - - let continiousSteps = []; - // In case of double - if (singleSteps.length > 2){ - - let currStep = singleSteps[0]; - let i = 0; - while (i < singleSteps.length){ - let point = getPoint(board, Math.min(pointId+currStep, 25)); - - if (isPointFree(point)){ - continiousSteps.push(currStep); - }else{ - break; - } - currStep += singleSteps[0]; - i++; - } - - }else if (singleSteps.length > 0){ - - - const firstStep = singleSteps[0]; - const firstPoint = getPoint(board, Math.min(pointId+firstStep, 25)); - - const isFirstStepFree = isPointFree(firstPoint); - if (isFirstStepFree){ - continiousSteps.push(firstStep); - } - - const secondStep = singleSteps[1]; - const secondPoint = getPoint(board, Math.min(pointId+secondStep, 25)); - - - if (typeof secondStep !== 'undefined') { - - const isSecondStepFree = isPointFree(secondPoint); - if (isSecondStepFree){ - continiousSteps.push(secondStep); - } - - if (isFirstStepFree || isSecondStepFree){ - const combinedPoint = getPoint(board, Math.min(pointId+firstStep+secondStep, 25)); - - if (isPointFree(combinedPoint)){ - continiousSteps.push(firstStep+secondStep); - } - } - } - } - return continiousSteps; -} + const possibleTargetPointsIds = canBeDraggedTo( + pointId, + board, + steps, + clientState + ); + return ( + board.findIndex( + (p) => possibleTargetPointsIds.indexOf(p.pointId) > -1 && isPointFree(p) + ) == -1 + ); +}; + +const possibleClientContiniousSteps = (pointId, board, singleSteps) => { + let continiousSteps = []; + // In case of double + if (singleSteps.length > 2) { + let currStep = singleSteps[0]; + let i = 0; + while (i < singleSteps.length) { + let point = getPoint(board, Math.min(pointId + currStep, 25)); + + if (isPointFree(point)) { + continiousSteps.push(currStep); + } else { + break; + } + currStep += singleSteps[0]; + i++; + } + } else if (singleSteps.length > 0) { + const firstStep = singleSteps[0]; + const firstPoint = getPoint(board, Math.min(pointId + firstStep, 25)); + + const isFirstStepFree = isPointFree(firstPoint); + if (isFirstStepFree) { + continiousSteps.push(firstStep); + } + + const secondStep = singleSteps[1]; + const secondPoint = getPoint(board, Math.min(pointId + secondStep, 25)); + + if (typeof secondStep !== "undefined") { + const isSecondStepFree = isPointFree(secondPoint); + if (isSecondStepFree) { + continiousSteps.push(secondStep); + } + + if (isFirstStepFree || isSecondStepFree) { + const combinedPoint = getPoint( + board, + Math.min(pointId + firstStep + secondStep, 25) + ); + + if (isPointFree(combinedPoint)) { + continiousSteps.push(firstStep + secondStep); + } + } + } + } + return continiousSteps; +}; const isStuckInBoard = (board, steps, clientState) => - (board.filter(p => (p.isClient && p.amount > 0)). - every(p => (isStuckInPoint(p.pointId, board, steps, clientState)))); + board + .filter((p) => p.isClient && p.amount > 0) + .every((p) => isStuckInPoint(p.pointId, board, steps, clientState)); const getStateByBoard = (board, steps) => { - - // check if the user losed. - if (numberOfCheckersInBoard(board, false) == 0){ - return IN_GAME_STATUS.LOSER; - - // check if there are checkers in point of the eaten. - } else if (board.find(point => (point.pointId == 0)).amount > 0){ - if (isStuckInPoint(0, board, steps)){ - return IN_GAME_STATUS.STUCK; - }else{ - return IN_GAME_STATUS.EATEN; - } - // check if sum the number of checkers that not in the six points home. - } else if (numberOfCheckersInBoard(board, true, 0, 18) == 0){ - - // check sum the number of checkers that not in the six points home. - if (numberOfCheckersInBoard(board, true, 19) == 0){ - return IN_GAME_STATUS.WINNER; - }else if(isStuckInBoard(board, steps, IN_GAME_STATUS.DROPOUT)){ - return IN_GAME_STATUS.STUCK; - } else { - return IN_GAME_STATUS.DROPOUT; - } - } else if(isStuckInBoard(board, steps)){ - return IN_GAME_STATUS.STUCK; - } - - return IN_GAME_STATUS.ONGOING; -} + // check if the user losed. + if (numberOfCheckersInBoard(board, false) == 0) { + return IN_GAME_STATUS.LOSER; + + // check if there are checkers in point of the eaten. + } else if (board.find((point) => point.pointId == 0).amount > 0) { + if (isStuckInPoint(0, board, steps)) { + return IN_GAME_STATUS.STUCK; + } else { + return IN_GAME_STATUS.EATEN; + } + // check if sum the number of checkers that not in the six points home. + } else if (numberOfCheckersInBoard(board, true, 0, 18) == 0) { + // check sum the number of checkers that not in the six points home. + if (numberOfCheckersInBoard(board, true, 19) == 0) { + return IN_GAME_STATUS.WINNER; + } else if (isStuckInBoard(board, steps, IN_GAME_STATUS.DROPOUT)) { + return IN_GAME_STATUS.STUCK; + } else { + return IN_GAME_STATUS.DROPOUT; + } + } else if (isStuckInBoard(board, steps)) { + return IN_GAME_STATUS.STUCK; + } + + return IN_GAME_STATUS.ONGOING; +}; const isPointCanDragTarget = (pointId, clientStatus) => { + // if the client was eaten he can only insert + if ( + clientStatus == IN_GAME_STATUS.STUCK || + (clientStatus == IN_GAME_STATUS.EATEN && pointId > 6) + ) { + return false; + } - // if the client was eaten he can only insert - if ((clientStatus == IN_GAME_STATUS.STUCK) || ((clientStatus == IN_GAME_STATUS.EATEN) && (pointId > 6))){ - return false; - } - - return true; -} + return true; +}; // consider replace canBeDragTargetFrom. const canBeDraggedTo = (pointId, board, singleSteps, clientState) => { - - if (clientState == IN_GAME_STATUS.EATEN){ - if (pointId == 0){ - return singleSteps.map(step => pointId+step).filter(pointId => isPointFree(getPoint(board, pointId))) - }else - return []; - } - - const continiousSteps = possibleClientContiniousSteps(pointId, board, singleSteps); - - let possibleTargetPointsIds = continiousSteps.map(step => (pointId+step)); - - if (clientState == IN_GAME_STATUS.DROPOUT){ - if (Math.min(...singleSteps)>(25-pointId)){ - - const farestPoint = board.filter(point => (point.isClient && point.amount>0)).sort()[0]; - - if (farestPoint.pointId == pointId){ - possibleTargetPointsIds.push(25); - } - } - - return possibleTargetPointsIds.filter(id => id <= 25) - } - - return possibleTargetPointsIds.filter(id => id < 25); -} - - -export {getStateByBoard, isPointCanDragTarget, canBeDraggedTo} + if (clientState == IN_GAME_STATUS.EATEN) { + if (pointId == 0) { + return singleSteps + .map((step) => pointId + step) + .filter((pointId) => isPointFree(getPoint(board, pointId))); + } else return []; + } + + const continiousSteps = possibleClientContiniousSteps( + pointId, + board, + singleSteps + ); + + let possibleTargetPointsIds = continiousSteps.map((step) => pointId + step); + + if (clientState == IN_GAME_STATUS.DROPOUT) { + if (Math.min(...singleSteps) > 25 - pointId) { + const farestPoint = board + .filter((point) => point.isClient && point.amount > 0) + .sort()[0]; + + if (farestPoint.pointId == pointId) { + possibleTargetPointsIds.push(25); + } + } + + return possibleTargetPointsIds.filter((id) => id <= 25); + } + + return possibleTargetPointsIds.filter((id) => id < 25); +}; + +export { getStateByBoard, isPointCanDragTarget, canBeDraggedTo }; diff --git a/dev/app/socket/index.js b/dev/app/socket/index.js index b60d79f..b1fbf12 100644 --- a/dev/app/socket/index.js +++ b/dev/app/socket/index.js @@ -1,11 +1,21 @@ -import io from 'socket.io-client'; +import io from "socket.io-client"; let socket; let wrapper = { - init: (address, options) => {if (!socket) {socket = io(address, options)}}, - close: () => {socket.close();}, - on: (actionName, callback) => {socket.on(actionName, callback);}, - emit: (actionName, data) => {socket.emit(actionName, data);} + init: (address, options) => { + if (!socket) { + socket = io(address, options); + } + }, + close: () => { + socket.close(); + }, + on: (actionName, callback) => { + socket.on(actionName, callback); + }, + emit: (actionName, data) => { + socket.emit(actionName, data); + }, }; export default wrapper; diff --git a/dev/app/utils/index.js b/dev/app/utils/index.js index 4bf67ed..eb1e02d 100644 --- a/dev/app/utils/index.js +++ b/dev/app/utils/index.js @@ -1,17 +1,16 @@ - - export function debounce(func, wait, immediate) { - var timeout; - return function() { - var context = this, args = arguments; + var timeout; + return function () { + var context = this, + args = arguments; - var later = function() { - timeout = null; - if (!immediate) func.apply(context, args); - }; - var callNow = immediate && !timeout; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - if (callNow) func.apply(context, args); - }; - }; + var later = function () { + timeout = null; + if (!immediate) func.apply(context, args); + }; + var callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if (callNow) func.apply(context, args); + }; +} diff --git a/dev/common/config.js b/dev/common/config.js index 940c1d4..d63ed95 100644 --- a/dev/common/config.js +++ b/dev/common/config.js @@ -1,6 +1,6 @@ -import defaultConfig from './defaultConfig.json'; +import defaultConfig from "./defaultConfig.json"; // TODO check why process.env[name] undifined in client in prod const getParameter = (name) => process.env[name] || defaultConfig[name]; -export default {getParameter} \ No newline at end of file +export default { getParameter }; diff --git a/dev/common/constants.js b/dev/common/constants.js index 8d71cd7..90b5610 100644 --- a/dev/common/constants.js +++ b/dev/common/constants.js @@ -1,20 +1,28 @@ // const IO_ACTIONS = {startGame: "START_GAME", gameAction:"GAME_ACTION", opponentRetirement:"OPPONENT_RETIREMENT", // searchNewOpponent:"SEARCH_NEW_OPPONENT", rematch:"REMATCH"}; -const IO_ACTIONS = { SEARCH_NEW_OPPONENT: 0, START_GAME:1, GAME_ACTION:2, OPPONENT_RETIREMENT:3, GAME_OVER:4, - CHAT_MESSAGE:5}; -const COUNTRIES = [{ key: 'af', value: 'af', flag: 'af', text: 'Afghanistan' }, -{ key: 'be', value: 'be', flag: 'be', text: 'Belgium' }, -{ key: 'br', value: 'br', flag: 'br', text: 'Brazil' }, -{ key: 'cl', value: 'cl', flag: 'cl', text: 'Chile' }, -{ key: 'fr', value: 'fr', flag: 'fr', text: 'France' }, -{ key: 'de', value: 'de', flag: 'de', text: 'Germany' }, -{ key: 'il', value: 'il', flag: 'il', text: 'Israel' }, -{ key: 'it', value: 'it', flag: 'it', text: 'Italy' }, -{ key: 'lt', value: 'lt', flag: 'lt', text: 'Lithuania' }, -{ key: 'nl', value: 'nl', flag: 'nl', text: 'Netherlands' }, -{ key: 'ru', value: 'ru', flag: 'ru', text: 'Russia' }, -{ key: 'gb', value: 'gb', flag: 'gb', text: 'United Kingdom' }, -{ key: 'us', value: 'us', flag: 'us', text: 'United States' }]; -export {IO_ACTIONS}; -export {COUNTRIES}; +const IO_ACTIONS = { + SEARCH_NEW_OPPONENT: 0, + START_GAME: 1, + GAME_ACTION: 2, + OPPONENT_RETIREMENT: 3, + GAME_OVER: 4, + CHAT_MESSAGE: 5, +}; +const COUNTRIES = [ + { key: "af", value: "af", flag: "af", text: "Afghanistan" }, + { key: "be", value: "be", flag: "be", text: "Belgium" }, + { key: "br", value: "br", flag: "br", text: "Brazil" }, + { key: "cl", value: "cl", flag: "cl", text: "Chile" }, + { key: "fr", value: "fr", flag: "fr", text: "France" }, + { key: "de", value: "de", flag: "de", text: "Germany" }, + { key: "il", value: "il", flag: "il", text: "Israel" }, + { key: "it", value: "it", flag: "it", text: "Italy" }, + { key: "lt", value: "lt", flag: "lt", text: "Lithuania" }, + { key: "nl", value: "nl", flag: "nl", text: "Netherlands" }, + { key: "ru", value: "ru", flag: "ru", text: "Russia" }, + { key: "gb", value: "gb", flag: "gb", text: "United Kingdom" }, + { key: "us", value: "us", flag: "us", text: "United States" }, +]; +export { IO_ACTIONS }; +export { COUNTRIES }; diff --git a/dev/common/defaultConfig.json b/dev/common/defaultConfig.json index 7f5fa5f..50d870f 100644 --- a/dev/common/defaultConfig.json +++ b/dev/common/defaultConfig.json @@ -1,4 +1,4 @@ { - "HOSTNAME":"localhost", - "PORT":4444 -} \ No newline at end of file + "HOSTNAME": "localhost", + "PORT": 4444 +} diff --git a/dev/content/index.html b/dev/content/index.html index f0c1521..59f2297 100644 --- a/dev/content/index.html +++ b/dev/content/index.html @@ -1,25 +1,24 @@ - + backgammon - + - -
+ +
diff --git a/dev/server/.babelrc b/dev/server/.babelrc index 0f44dfc..43c8d1f 100644 --- a/dev/server/.babelrc +++ b/dev/server/.babelrc @@ -1,4 +1,4 @@ { - "presets": ["es2015","stage-0","stage-2","react"], - "plugins": ["react-hot-loader/babel"] + "presets": ["es2015", "stage-0", "stage-2", "react"], + "plugins": ["react-hot-loader/babel"] } diff --git a/dev/server/data/dal.js b/dev/server/data/dal.js index bf2e5f2..81e8601 100644 --- a/dev/server/data/dal.js +++ b/dev/server/data/dal.js @@ -1,63 +1,102 @@ -import db from './db' -import moment from 'moment' +import db from "./db"; +import moment from "moment"; const scoreDecoder = { -"-3":"turkishMarsLoss", -"-2":"marsLoss", -"-1":"loss", -"0":"draw", -"1":"win", -"2":"marsWin", -"3":"turkishMarsWin"} + "-3": "turkishMarsLoss", + "-2": "marsLoss", + "-1": "loss", + 0: "draw", + 1: "win", + 2: "marsWin", + 3: "turkishMarsWin", +}; // TODO: extend to all types of result -const insertGame = (host , guest, isHostWinner) => { - const maxId = Math.max.apply(Math, db.models.games.map(game => game.id)); - db.models.games.push({id:maxId+1, host, guest, score:isHostWinner?1:-1, date:moment()}); +const insertGame = (host, guest, isHostWinner) => { + const maxId = Math.max.apply( + Math, + db.models.games.map((game) => game.id) + ); + db.models.games.push({ + id: maxId + 1, + host, + guest, + score: isHostWinner ? 1 : -1, + date: moment(), + }); }; -const getUserByUsername = username => { - const user = db.models.users.find(user => (user.username == username)); - return {...user, password:undefined} +const getUserByUsername = (username) => { + const user = db.models.users.find((user) => user.username == username); + return { ...user, password: undefined }; }; -const getUserByPassword = (username, password) => db.models.users - .find(user => (user.username == username && user.password == password)) +const getUserByPassword = (username, password) => + db.models.users.find( + (user) => user.username == username && user.password == password + ); -const getUser = userId => db.models.users - .find(user => (user.id == userId)); +const getUser = (userId) => db.models.users.find((user) => user.id == userId); -const addUser = user => { +const addUser = (user) => { db.models.users.push(user); }; -const gePlayerRecord = userId => db.models.games.reduce((res, game) => { - const decode = scoreDecoder[game.score]; - if (game.host == userId){ - res[decode] = res[decode]+1; - }else if (game.guest == userId){ - res[scoreDecoder[game.score*(-1)]] = res[scoreDecoder[game.score*(-1)]]+1; - } - return res; -},{"turkishMarsLoss":0,"marsLoss":0,"loss":0,"draw":0,"win":0,"marsWin":0,"turkishMarsWin":0}); +const gePlayerRecord = (userId) => + db.models.games.reduce( + (res, game) => { + const decode = scoreDecoder[game.score]; + if (game.host == userId) { + res[decode] = res[decode] + 1; + } else if (game.guest == userId) { + res[scoreDecoder[game.score * -1]] = + res[scoreDecoder[game.score * -1]] + 1; + } + return res; + }, + { + turkishMarsLoss: 0, + marsLoss: 0, + loss: 0, + draw: 0, + win: 0, + marsWin: 0, + turkishMarsWin: 0, + } + ); -const getWinsLossesRecord = userId => { - const {turkishMarsLoss, marsLoss, loss, draw, - win, marsWin, turkishMarsWin} = gePlayerRecord(userId); +const getWinsLossesRecord = (userId) => { + const { + turkishMarsLoss, + marsLoss, + loss, + draw, + win, + marsWin, + turkishMarsWin, + } = gePlayerRecord(userId); - return {win:win+marsWin+turkishMarsWin, draw, loss:turkishMarsLoss+marsLoss+loss} -} + return { + win: win + marsWin + turkishMarsWin, + draw, + loss: turkishMarsLoss + marsLoss + loss, + }; +}; -const getGamesOfUser = (userId, offest, count) => db.models.games - .filter(game => (game.host == userId || game.guest == userId)) - .slice(offest, count + offest) - .map(({id, date, host, guest, score}) => ((host == userId)? - {id, date, opponent:guest, score:scoreDecoder[score]} - : - {id, date, opponent:host, score:scoreDecoder[(score*-1)]})); +const getGamesOfUser = (userId, offest, count) => + db.models.games + .filter((game) => game.host == userId || game.guest == userId) + .slice(offest, count + offest) + .map(({ id, date, host, guest, score }) => + host == userId + ? { id, date, opponent: guest, score: scoreDecoder[score] } + : { id, date, opponent: host, score: scoreDecoder[score * -1] } + ); -const filterUsersByUsername = regExp => db.models.users. - filter(user => regExp.test(user.username)).map(user => ({...user, password:undefined})); +const filterUsersByUsername = (regExp) => + db.models.users + .filter((user) => regExp.test(user.username)) + .map((user) => ({ ...user, password: undefined })); const dal = { insertGame, @@ -68,7 +107,7 @@ const dal = { gePlayerRecord, getWinsLossesRecord, getGamesOfUser, - filterUsersByUsername + filterUsersByUsername, }; export default dal; diff --git a/dev/server/data/db.js b/dev/server/data/db.js index 185b7e2..6c6c158 100644 --- a/dev/server/data/db.js +++ b/dev/server/data/db.js @@ -1,45 +1,81 @@ -import moment from 'moment' +import moment from "moment"; const db = { - models:{ - users:[ + models: { + users: [ { - id:1, - username:"amitush", - firstName:"Amit", - lastName:"Shalev", - password:"123", - country:"us", - image:'/images/pp.jpg' + id: 1, + username: "amitush", + firstName: "Amit", + lastName: "Shalev", + password: "123", + country: "us", + image: "/images/pp.jpg", }, { - id:2, - username:"deanush", - firstName:"Dean", - lastName:"Shub", - password:"234", - country:"il" + id: 2, + username: "deanush", + firstName: "Dean", + lastName: "Shub", + password: "234", + country: "il", }, { - id:3, - username:"avivush", - firstName:"Aviv", - lastName:"Aviv", - password:"345", - country:"ch" + id: 3, + username: "avivush", + firstName: "Aviv", + lastName: "Aviv", + password: "345", + country: "ch", }, ], - games:[ - {id:1, host:1, guest:2, score: 1, date:moment()}, - {id:2, host:1, guest:3, score: 2, date:moment().subtract('days', 2)}, - {id:3, host:2, guest:3, score: 1, date:moment().subtract('days', 18)}, - {id:4, host:1, guest:3, score: 1, date:moment().subtract('days', 6)}, - {id:5, host:2, guest:1, score: -1, date:moment()}, - {id:6, host:1, guest:3, score: -1, date:moment().subtract('days', 46)}, - {id:7, host:2, guest:3, score: 1, date:moment().subtract('days', 11)}, - {id:8, host:3, guest:2, score: -2, date:moment().subtract('days', 6)}, - ] - } -} + games: [ + { id: 1, host: 1, guest: 2, score: 1, date: moment() }, + { + id: 2, + host: 1, + guest: 3, + score: 2, + date: moment().subtract("days", 2), + }, + { + id: 3, + host: 2, + guest: 3, + score: 1, + date: moment().subtract("days", 18), + }, + { + id: 4, + host: 1, + guest: 3, + score: 1, + date: moment().subtract("days", 6), + }, + { id: 5, host: 2, guest: 1, score: -1, date: moment() }, + { + id: 6, + host: 1, + guest: 3, + score: -1, + date: moment().subtract("days", 46), + }, + { + id: 7, + host: 2, + guest: 3, + score: 1, + date: moment().subtract("days", 11), + }, + { + id: 8, + host: 3, + guest: 2, + score: -2, + date: moment().subtract("days", 6), + }, + ], + }, +}; export default db; diff --git a/dev/server/data/graphql/resolvers.js b/dev/server/data/graphql/resolvers.js index 031b524..acf7278 100644 --- a/dev/server/data/graphql/resolvers.js +++ b/dev/server/data/graphql/resolvers.js @@ -1,37 +1,46 @@ -import dal from '../dal' +import dal from "../dal"; -const getPlayerInfo = userId => { +const getPlayerInfo = (userId) => { const user = dal.getUser(userId); const basicRecord = dal.getWinsLossesRecord(userId); - const playerInfo = {id: user.id, username: user.username, image:user.image, basicRecord}; + const playerInfo = { + id: user.id, + username: user.username, + image: user.image, + basicRecord, + }; return playerInfo; -} +}; const resolvers = { Query: { - players: (root, {username}) => { + players: (root, { username }) => { const string = `.*${username}.*`; const regExp = new RegExp(string); return dal.filterUsersByUsername(regExp); }, - playerInfo: (root, {id}) => { + playerInfo: (root, { id }) => { return getPlayerInfo(id); }, - playerStat: (root, {id:userId, skip}) => { - //const user = dal.getUser(userId); - const record = dal.gePlayerRecord(userId); - // const games = dal.getGamesOfUser(userId, 0, skip) - // .map(game => ({...game, opponent:dal.getUser(game.opponent).username})); - const playerStat = {id: userId, record}; + playerStat: (root, { id: userId, skip }) => { + //const user = dal.getUser(userId); + const record = dal.gePlayerRecord(userId); + // const games = dal.getGamesOfUser(userId, 0, skip) + // .map(game => ({...game, opponent:dal.getUser(game.opponent).username})); + const playerStat = { id: userId, record }; - return playerStat; + return playerStat; }, - playerGames: (root, {id, offset, limit}) => { - return dal.getGamesOfUser(id, offset, limit) - .map(game => ({...game, opponent:dal.getUser(game.opponent).username})); - } - } + playerGames: (root, { id, offset, limit }) => { + return dal + .getGamesOfUser(id, offset, limit) + .map((game) => ({ + ...game, + opponent: dal.getUser(game.opponent).username, + })); + }, + }, }; -export default resolvers +export default resolvers; diff --git a/dev/server/data/graphql/schema.js b/dev/server/data/graphql/schema.js index b7b056b..d9ad9f8 100644 --- a/dev/server/data/graphql/schema.js +++ b/dev/server/data/graphql/schema.js @@ -1,6 +1,6 @@ -import { makeExecutableSchema } from 'graphql-tools' +import { makeExecutableSchema } from "graphql-tools"; -import resolvers from './resolvers'; +import resolvers from "./resolvers"; const typeDefs = ` @@ -58,6 +58,5 @@ type Query { } `; - const schema = makeExecutableSchema({ typeDefs, resolvers }); export default schema; diff --git a/dev/server/index.js b/dev/server/index.js index 75ab0e9..1fd091d 100644 --- a/dev/server/index.js +++ b/dev/server/index.js @@ -1,56 +1,63 @@ - - -import express from 'express' -import path from 'path' -import passport from 'passport' -import {Strategy} from 'passport-local' -import cookieParser from 'cookie-parser' -import bodyParser from 'body-parser' -import expressSession from 'express-session' -import webpack from 'webpack' -import {create} from './server' -import db from './data/db' -import dal from './data/dal' -import http from 'http' -import register from './routes/register' -import statistics from './routes/statistics' -import {graphqlExpress, graphiqlExpress} from 'apollo-server-express' -import schema from './data/graphql/schema' - -let STATIC_FILES_DIRECTORY = (process.env.NODE_ENV === 'production')? - path.resolve(__dirname, '..'):path.resolve(__dirname, '../content') - +import express from "express"; +import path from "path"; +import passport from "passport"; +import { Strategy } from "passport-local"; +import cookieParser from "cookie-parser"; +import bodyParser from "body-parser"; +import expressSession from "express-session"; +import webpack from "webpack"; +import { create } from "./server"; +import db from "./data/db"; +import dal from "./data/dal"; +import http from "http"; +import register from "./routes/register"; +import statistics from "./routes/statistics"; +import { graphqlExpress, graphiqlExpress } from "apollo-server-express"; +import schema from "./data/graphql/schema"; + +let STATIC_FILES_DIRECTORY = + process.env.NODE_ENV === "production" + ? path.resolve(__dirname, "..") + : path.resolve(__dirname, "../content"); const port = process.env.PORT || 4445; const app = express(); - -app.use(cookieParser()) -app.use(bodyParser.json()) -app.use(bodyParser.urlencoded({ extended: true })) -app.use(expressSession({ - secret: 'amit sha3', - resave: true, - saveUninitialized: true, - // cookie: {secure:true}, -})) -app.use(passport.initialize()) -app.use(passport.session()) - -if (process.env.NODE_ENV === 'production'){ +app.use(cookieParser()); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: true })); +app.use( + expressSession({ + secret: "amit sha3", + resave: true, + saveUninitialized: true, + // cookie: {secure:true}, + }) +); +app.use(passport.initialize()); +app.use(passport.session()); + +if (process.env.NODE_ENV === "production") { console.log("production env"); -}else{ - - var webpackConfig = require(process.env.WEBPACK_CONFIG || '../../webpack.config'); - var compiler = webpack(webpackConfig); - - app.use(require("webpack-dev-middleware")(compiler, { - noInfo: true, publicPath: webpackConfig.output.publicPath - })); - - app.use(require("webpack-hot-middleware")(compiler, { - log: console.log, path: '/__webpack_hmr', heartbeat: 10 * 1000 - })); +} else { + var webpackConfig = require(process.env.WEBPACK_CONFIG || + "../../webpack.config"); + var compiler = webpack(webpackConfig); + + app.use( + require("webpack-dev-middleware")(compiler, { + noInfo: true, + publicPath: webpackConfig.output.publicPath, + }) + ); + + app.use( + require("webpack-hot-middleware")(compiler, { + log: console.log, + path: "/__webpack_hmr", + heartbeat: 10 * 1000, + }) + ); } passport.serializeUser((user, cb) => { @@ -62,67 +69,75 @@ passport.deserializeUser((username, cb) => { return cb(null, user); }); -passport.use(new Strategy( - (username, password, cb) => { - const user = dal.getUserByPassword(username, password); - return cb(null, {...user, password:undefined}); - })); - - - -app.post('/login', (req, res, next) => { - if (req.body.playAsGuest){ - res.json({user:{username:req.body.username, playAsGuest:true}}) - }else{ - passport.authenticate('local', (err, user, info) => { - if (err) { return next(err) } - if (!user) { return res.status(403).json({error:'Username or password are Incorrect.'}) } +passport.use( + new Strategy((username, password, cb) => { + const user = dal.getUserByPassword(username, password); + return cb(null, { ...user, password: undefined }); + }) +); + +app.post("/login", (req, res, next) => { + if (req.body.playAsGuest) { + res.json({ user: { username: req.body.username, playAsGuest: true } }); + } else { + passport.authenticate("local", (err, user, info) => { + if (err) { + return next(err); + } + if (!user) { + return res + .status(403) + .json({ error: "Username or password are Incorrect." }); + } req.logIn(user, (err) => { - if (err) { return next(err) } - res.json({user:user}) - }) - })(req, res, next) + if (err) { + return next(err); + } + res.json({ user: user }); + }); + })(req, res, next); } -}) - +}); -app.post('/isAuthenticated', (req, res)=>{ - if (req.isAuthenticated()){ - res.json(req.user) - }else{ - res.json({}) +app.post("/isAuthenticated", (req, res) => { + if (req.isAuthenticated()) { + res.json(req.user); + } else { + res.json({}); } -}) +}); function isAuthenticated(req, res, next) { - if (req.isAuthenticated()){ - return next() + if (req.isAuthenticated()) { + return next(); } - res.redirect('/login') + res.redirect("/login"); } -app.get('/login', (req, res)=>{ - res.sendFile(path.join(STATIC_FILES_DIRECTORY, 'index.html')) -}) - -app.get('/main*', isAuthenticated, (req, res)=>{ - res.sendFile(path.join(STATIC_FILES_DIRECTORY, 'index.html')) -}) - +app.get("/login", (req, res) => { + res.sendFile(path.join(STATIC_FILES_DIRECTORY, "index.html")); +}); -app.get('/logout', (req, res)=>{ - req.logout() - res.redirect('/login') -}) +app.get("/main*", isAuthenticated, (req, res) => { + res.sendFile(path.join(STATIC_FILES_DIRECTORY, "index.html")); +}); -app.use('/', express.static(STATIC_FILES_DIRECTORY)); -app.use('/register', register) -app.use('/statistics', statistics) +app.get("/logout", (req, res) => { + req.logout(); + res.redirect("/login"); +}); -app.use('/graphql', bodyParser.json(), graphqlExpress({schema})) -app.use('/graphiql', graphiqlExpress({ - endpointURL: '/graphql', -})); +app.use("/", express.static(STATIC_FILES_DIRECTORY)); +app.use("/register", register); +app.use("/statistics", statistics); + +app.use("/graphql", bodyParser.json(), graphqlExpress({ schema })); +app.use( + "/graphiql", + graphiqlExpress({ + endpointURL: "/graphql", + }) +); const httpServer = new http.Server(app); diff --git a/dev/server/routes/register.js b/dev/server/routes/register.js index f61a5ef..d15e670 100644 --- a/dev/server/routes/register.js +++ b/dev/server/routes/register.js @@ -1,23 +1,22 @@ -import express from 'express' -import { addUser, getUserByUsername } from '../data/dal' +import express from "express"; +import { addUser, getUserByUsername } from "../data/dal"; -const router = express.Router() +const router = express.Router(); -const checkIsExisted = username => getUserByUsername(username) !== undefined +const checkIsExisted = (username) => getUserByUsername(username) !== undefined; -router.post('/', (req, res) => { - const user = req.body +router.post("/", (req, res) => { + const user = req.body; addUser(user); - res.sendStatus(200) -}) + res.sendStatus(200); +}); -router.post('/validation/username', function (req, res) { - if (!checkIsExisted(req.body.username)){ - res.sendStatus(200) - }else{ - res.status(403).send({message:'Invalid username'}) +router.post("/validation/username", function (req, res) { + if (!checkIsExisted(req.body.username)) { + res.sendStatus(200); + } else { + res.status(403).send({ message: "Invalid username" }); } +}); -}) - -export default router +export default router; diff --git a/dev/server/routes/statistics.js b/dev/server/routes/statistics.js index fe0b4af..4b6611f 100644 --- a/dev/server/routes/statistics.js +++ b/dev/server/routes/statistics.js @@ -1,25 +1,29 @@ -import express from 'express' -import { getGamesOfUser, winsLossesRecord, filterUsersByUsername } from '../data/dal' +import express from "express"; +import { + getGamesOfUser, + winsLossesRecord, + filterUsersByUsername, +} from "../data/dal"; -const router = express.Router() +const router = express.Router(); -router.get('/record/:username', (req, res) => { - const username = req.params.username +router.get("/record/:username", (req, res) => { + const username = req.params.username; res.json(winsLossesRecord(username)); -}) +}); -router.get('/games/:username', (req, res) => { +router.get("/games/:username", (req, res) => { const { username } = req.params; const { offest, count } = req.query; //console.log("count + offest" , count + offest); res.json(getGamesOfUser(username, parseInt(offest), parseInt(count))); -}) +}); -router.get('/serach', (req, res) => { +router.get("/serach", (req, res) => { const { username } = req.query; const string = `.*${username}.*`; const regExp = new RegExp(string); res.json(filterUsersByUsername(regExp)); }); -export default router +export default router; diff --git a/dev/server/server.js b/dev/server/server.js index a42981a..66b17c6 100644 --- a/dev/server/server.js +++ b/dev/server/server.js @@ -1,99 +1,104 @@ -import socketIo from 'socket.io' -import {IO_ACTIONS} from '../common/constants' -import dal from './data/dal' - -export const create = httpServer => { +import socketIo from "socket.io"; +import { IO_ACTIONS } from "../common/constants"; +import dal from "./data/dal"; +export const create = (httpServer) => { const io = socketIo(httpServer); let players = {}; let socketToUser = {}; let waitingPlayers = []; let playsAgainst = {}; -io.use((socket, next) => { + io.use((socket, next) => { const username = socket.handshake.query.username; const isGuest = socket.handshake.query.isGuest; - socketToUser[socket.id] = {username, isGuest: (isGuest == 'true')}; + socketToUser[socket.id] = { username, isGuest: isGuest == "true" }; next(); -}); - - const getPlayerInfo = socketId => { - const user = socketToUser[socketId]; - const username = user.username; - - if (user.isGuest){ - return user; - } - - const userInfo = dal.getUserByUsername(username); - - const rate = dal.getWinsLossesRecord(username); - - return {...userInfo, rate} - }; - - const searchOppenent = socketId => { - - if (waitingPlayers.length == 0){ - waitingPlayers.push(socketId); - }else{ - let secondPlayerId = waitingPlayers.shift(); - - playsAgainst[socketId] = secondPlayerId; - playsAgainst[secondPlayerId] = socketId; - - io.sockets.to(socketId).emit(IO_ACTIONS.START_GAME, {start:true, opponentInfo:getPlayerInfo(secondPlayerId)}); - io.sockets.to(secondPlayerId).emit(IO_ACTIONS.START_GAME, {start:false, opponentInfo:getPlayerInfo(socketId)}); - } - }; - - const deleteGameOfSocket = socketId => { - const opponentId = playsAgainst[socketId]; - - delete playsAgainst[socketId]; - delete playsAgainst[opponentId]; - }; - - - io.on('connection', socket => { - - socket.on('disconnect', () => { - - const opponentId = playsAgainst[socket.id]; - // check if currently plays. - if (opponentId !== undefined){ - io.sockets.to(opponentId).emit(IO_ACTIONS.OPPONENT_RETIREMENT); - deleteGameOfSocket(socket.id); - } else { + }); - // Check if in waiting list. - const index = waitingPlayers.indexOf(socket.id); - if (index > -1){ - waitingPlayers = waitingPlayers.splice(index, 1) - } + const getPlayerInfo = (socketId) => { + const user = socketToUser[socketId]; + const username = user.username; + + if (user.isGuest) { + return user; + } + + const userInfo = dal.getUserByUsername(username); + + const rate = dal.getWinsLossesRecord(username); + + return { ...userInfo, rate }; + }; + + const searchOppenent = (socketId) => { + if (waitingPlayers.length == 0) { + waitingPlayers.push(socketId); + } else { + let secondPlayerId = waitingPlayers.shift(); + + playsAgainst[socketId] = secondPlayerId; + playsAgainst[secondPlayerId] = socketId; + + io.sockets + .to(socketId) + .emit(IO_ACTIONS.START_GAME, { + start: true, + opponentInfo: getPlayerInfo(secondPlayerId), + }); + io.sockets + .to(secondPlayerId) + .emit(IO_ACTIONS.START_GAME, { + start: false, + opponentInfo: getPlayerInfo(socketId), + }); + } + }; + + const deleteGameOfSocket = (socketId) => { + const opponentId = playsAgainst[socketId]; + + delete playsAgainst[socketId]; + delete playsAgainst[opponentId]; + }; + + io.on("connection", (socket) => { + socket.on("disconnect", () => { + const opponentId = playsAgainst[socket.id]; + // check if currently plays. + if (opponentId !== undefined) { + io.sockets.to(opponentId).emit(IO_ACTIONS.OPPONENT_RETIREMENT); + deleteGameOfSocket(socket.id); + } else { + // Check if in waiting list. + const index = waitingPlayers.indexOf(socket.id); + if (index > -1) { + waitingPlayers = waitingPlayers.splice(index, 1); } + } - delete socketToUser[socket.id] - }); - - socket.on(IO_ACTIONS.GAME_ACTION, data => { - //console.log("server GAME_ACTION" , playsAgainst); - io.sockets.to(playsAgainst[socket.id]).emit(IO_ACTIONS.GAME_ACTION, data); + delete socketToUser[socket.id]; }); - socket.on(IO_ACTIONS.CHAT_MESSAGE, data => { - //console.log("server GAME_ACTION" , playsAgainst); - io.sockets.to(playsAgainst[socket.id]).emit(IO_ACTIONS.CHAT_MESSAGE, data); + socket.on(IO_ACTIONS.GAME_ACTION, (data) => { + //console.log("server GAME_ACTION" , playsAgainst); + io.sockets.to(playsAgainst[socket.id]).emit(IO_ACTIONS.GAME_ACTION, data); }); - socket.on(IO_ACTIONS.SEARCH_NEW_OPPONENT, data => { - searchOppenent(socket.id); + socket.on(IO_ACTIONS.CHAT_MESSAGE, (data) => { + //console.log("server GAME_ACTION" , playsAgainst); + io.sockets + .to(playsAgainst[socket.id]) + .emit(IO_ACTIONS.CHAT_MESSAGE, data); }); - socket.on(IO_ACTIONS.GAME_OVER, data => { + socket.on(IO_ACTIONS.SEARCH_NEW_OPPONENT, (data) => { + searchOppenent(socket.id); + }); + socket.on(IO_ACTIONS.GAME_OVER, (data) => { // The winner send this event. const name = socketToUser[socket.id]; const user = dal.getUserByUsername(name); @@ -108,4 +113,4 @@ io.use((socket, next) => { deleteGameOfSocket(socket.id); }); }); -} +}; diff --git a/index2.js b/index2.js index 3e34cb7..39d8f80 100644 --- a/index2.js +++ b/index2.js @@ -1,24 +1,27 @@ -import path from 'path'; -import http from 'http'; -import express from 'express'; -import webpack from 'webpack'; +import path from "path"; +import http from "http"; +import express from "express"; +import webpack from "webpack"; //import webpackConfig from process.env.WEBPACK_CONFIG || './webpack.config'; -import {create} from './server'; +import { create } from "./server"; -var webpackConfig = require(process.env.WEBPACK_CONFIG || './webpack.config'); +var webpackConfig = require(process.env.WEBPACK_CONFIG || "./webpack.config"); var compiler = webpack(webpackConfig); const port = process.env.PORT || 4445; const app = express(); -if (process.env.NODE_ENV==='development'){ - app.use(require("webpack-hot-middleware")(compiler)); - app.use(require("webpack-dev-middleware")(compiler, { - noInfo: true, publicPath: webpackConfig.output.publicPath - })); +if (process.env.NODE_ENV === "development") { + app.use(require("webpack-hot-middleware")(compiler)); + app.use( + require("webpack-dev-middleware")(compiler, { + noInfo: true, + publicPath: webpackConfig.output.publicPath, + }) + ); } -app.use('/', express.static(path.resolve(__dirname, '..'))); +app.use("/", express.static(path.resolve(__dirname, ".."))); const httpServer = new http.Server(app); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..b1a7fda --- /dev/null +++ b/package-lock.json @@ -0,0 +1,14 @@ +{ + "name": "backgammon", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "prettier": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz", + "integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==", + "dev": true + } + } +} diff --git a/package.json b/package.json index f49dc3c..a5c46ea 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "css-loader": "^0.28.4", "postcss-loader": "^2.0.6", "precss": "^2.0.0", + "prettier": "^2.1.2", "react-hot-loader": "^3.0.0-beta.7", "style-loader": "^0.18.2", "url-loader": "^0.5.9", diff --git a/postcss.config.js b/postcss.config.js index 23ac9df..2e0905c 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,6 +1,3 @@ module.exports = { - plugins: [ - require('precss'), - require('autoprefixer') - ] -} + plugins: [require("precss"), require("autoprefixer")], +}; diff --git a/webpack.config.js b/webpack.config.js index 4e01d68..de05340 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -7,28 +7,28 @@ var OUTPUT = path.resolve(__dirname, "output"); var config = { entry: { - app:[ - 'webpack-hot-middleware/client', - 'react-hot-loader/patch', - DEV + "/app/index.js" + app: [ + "webpack-hot-middleware/client", + "react-hot-loader/patch", + DEV + "/app/index.js", ], - html: DEV + "/content/index.html", + html: DEV + "/content/index.html", vendor: [ - 'webpack-hot-middleware/client', - 'react-hot-loader/patch', - 'react', - 'react-dom', - 'react-router' - ] + "webpack-hot-middleware/client", + "react-hot-loader/patch", + "react", + "react-dom", + "react-router", + ], }, output: { path: OUTPUT, publicPath: "/", - filename: '[name].js', + filename: "[name].js", }, devServer: { - inline: true, - port:4445, + inline: true, + port: 4445, hot: true, // contentBase: OUTPUT, // historyApiFallback: { @@ -36,79 +36,90 @@ var config = { // }, // historyApiFallback: true }, - module:{ - rules: [ - { - test: /\.html$/, - loader: ['react-hot-loader/webpack', 'file-loader?name=[name].[ext]'], - }, - { - test: /\.(js|jsx)$/, - exclude: /node_modules/, - loader: 'babel-loader?cacheDirectory=true' - }, - { - test: /\.css$/, - exclude: path.join(__dirname, 'dev'), - use: [{ - loader:'style-loader', - },{ - loader:'css-loader', - }], - }, - { - test: /\.css$/, - include: path.join(__dirname, 'dev'), - use: [ - 'style-loader', - 'css-loader?modules&sourceMap&importLoaders=1&localIdentName=[local]___[hash:base64:5]', - 'postcss-loader', - ], - }, - { - test: /\.svg(\?.*)?$/, - loader: 'url-loader?limit=10000&mimetype=image/svg+xml&name=images/[name].[ext]', - // include: path.join(__dirname, 'client', 'assets'), - }, { - test: /\.png$/, - loader: 'url-loader?limit=8192&mimetype=image/png&name=images/[name].[ext]', - // include: path.join(__dirname, 'client', 'assets'), - }, { - test: /\.gif$/, - loader: 'url-loader?limit=8192&mimetype=image/gif&name=images/[name].[ext]', - // include: path.join(__dirname, 'client', 'assets'), - }, { - test: /\.jpg$/, - loader: 'url-loader?limit=8192&mimetype=image/jpg&name=images/[name].[ext]', - // include: path.join(__dirname, 'client', 'assets'), - }, - { - test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, - loader: 'url-loader?limit=10000&mimetype=application/font-woff', - }, - { - test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, - loader: 'file-loader', - }, - ] -}, -resolve: { - extensions: ['.json','.js', '.jsx'] -}, -plugins: [ - // new HtmlWebpackPlugin({ - // filename: 'index.html', - // template: 'dev/content/index-prod.html', - // inject: true - // }), - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)}), - // // 'process.env.HOSTNAME': JSON.stringify('localhost'), - // 'process.env.PORT': 4445 - // }), - new webpack.HotModuleReplacementPlugin(), - new webpack.NoEmitOnErrorsPlugin() - ] + module: { + rules: [ + { + test: /\.html$/, + loader: ["react-hot-loader/webpack", "file-loader?name=[name].[ext]"], + }, + { + test: /\.(js|jsx)$/, + exclude: /node_modules/, + loader: "babel-loader?cacheDirectory=true", + }, + { + test: /\.css$/, + exclude: path.join(__dirname, "dev"), + use: [ + { + loader: "style-loader", + }, + { + loader: "css-loader", + }, + ], + }, + { + test: /\.css$/, + include: path.join(__dirname, "dev"), + use: [ + "style-loader", + "css-loader?modules&sourceMap&importLoaders=1&localIdentName=[local]___[hash:base64:5]", + "postcss-loader", + ], + }, + { + test: /\.svg(\?.*)?$/, + loader: + "url-loader?limit=10000&mimetype=image/svg+xml&name=images/[name].[ext]", + // include: path.join(__dirname, 'client', 'assets'), + }, + { + test: /\.png$/, + loader: + "url-loader?limit=8192&mimetype=image/png&name=images/[name].[ext]", + // include: path.join(__dirname, 'client', 'assets'), + }, + { + test: /\.gif$/, + loader: + "url-loader?limit=8192&mimetype=image/gif&name=images/[name].[ext]", + // include: path.join(__dirname, 'client', 'assets'), + }, + { + test: /\.jpg$/, + loader: + "url-loader?limit=8192&mimetype=image/jpg&name=images/[name].[ext]", + // include: path.join(__dirname, 'client', 'assets'), + }, + { + test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, + loader: "url-loader?limit=10000&mimetype=application/font-woff", + }, + { + test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, + loader: "file-loader", + }, + ], + }, + resolve: { + extensions: [".json", ".js", ".jsx"], + }, + plugins: [ + // new HtmlWebpackPlugin({ + // filename: 'index.html', + // template: 'dev/content/index-prod.html', + // inject: true + // }), + new webpack.DefinePlugin({ + "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV), + }), + // // 'process.env.HOSTNAME': JSON.stringify('localhost'), + // 'process.env.PORT': 4445 + // }), + new webpack.HotModuleReplacementPlugin(), + new webpack.NoEmitOnErrorsPlugin(), + ], }; //process.traceDeprecation = true; module.exports = config; diff --git a/webpack.config.prod.js b/webpack.config.prod.js index a5dcfaa..c0aea0e 100644 --- a/webpack.config.prod.js +++ b/webpack.config.prod.js @@ -6,24 +6,18 @@ var OUTPUT = path.resolve(__dirname, "output"); var config = { entry: { - app:[ - DEV + "/app/index.js" - ], - html: DEV + "/content/index.html", - vendor: [ - 'react', - 'react-dom', - 'react-router' - ] + app: [DEV + "/app/index.js"], + html: DEV + "/content/index.html", + vendor: ["react", "react-dom", "react-router"], }, output: { path: OUTPUT, publicPath: "/", - filename: '[name].js', + filename: "[name].js", }, devServer: { - inline: true, - port:4445, + inline: true, + port: 4445, hot: true, // contentBase: OUTPUT, // historyApiFallback: { @@ -31,79 +25,90 @@ var config = { // }, // historyApiFallback: true }, - module:{ - rules: [ - { - test: /\.html$/, - loader: ['file-loader?name=[name].[ext]'], - }, - { - test: /\.(js|jsx)$/, - exclude: /node_modules/, - loader: 'babel-loader?cacheDirectory=true' - }, - { - test: /\.css$/, - exclude: path.join(__dirname, 'dev'), - use: [{ - loader:'style-loader', - },{ - loader:'css-loader', - }], - }, - { - test: /\.css$/, - include: path.join(__dirname, 'dev'), - use: [ - 'style-loader', - 'css-loader?modules&sourceMap&importLoaders=1&localIdentName=[local]___[hash:base64:5]', - 'postcss-loader', - ], - }, - { - test: /\.svg(\?.*)?$/, - loader: 'url-loader?limit=10000&mimetype=image/svg+xml&name=images/[name].[ext]', - // include: path.join(__dirname, 'client', 'assets'), - }, { - test: /\.png$/, - loader: 'url-loader?limit=8192&mimetype=image/png&name=images/[name].[ext]', - // include: path.join(__dirname, 'client', 'assets'), - }, { - test: /\.gif$/, - loader: 'url-loader?limit=8192&mimetype=image/gif&name=images/[name].[ext]', - // include: path.join(__dirname, 'client', 'assets'), - }, { - test: /\.jpg$/, - loader: 'url-loader?limit=8192&mimetype=image/jpg&name=images/[name].[ext]', - // include: path.join(__dirname, 'client', 'assets'), - }, - { - test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, - loader: 'url-loader?limit=10000&mimetype=application/font-woff', - }, - { - test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, - loader: 'file-loader', - }, - ] -}, -resolve: { - extensions: ['.json','.js', '.jsx'] -}, -plugins: [ - // new HtmlWebpackPlugin({ - // filename: 'index.html', - // template: 'dev/content/index-prod.html', - // inject: true - // }), - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)}), - // // 'process.env.HOSTNAME': JSON.stringify('localhost'), - // 'process.env.PORT': 4445 - // }), - new webpack.HotModuleReplacementPlugin(), - new webpack.NoEmitOnErrorsPlugin() - ] + module: { + rules: [ + { + test: /\.html$/, + loader: ["file-loader?name=[name].[ext]"], + }, + { + test: /\.(js|jsx)$/, + exclude: /node_modules/, + loader: "babel-loader?cacheDirectory=true", + }, + { + test: /\.css$/, + exclude: path.join(__dirname, "dev"), + use: [ + { + loader: "style-loader", + }, + { + loader: "css-loader", + }, + ], + }, + { + test: /\.css$/, + include: path.join(__dirname, "dev"), + use: [ + "style-loader", + "css-loader?modules&sourceMap&importLoaders=1&localIdentName=[local]___[hash:base64:5]", + "postcss-loader", + ], + }, + { + test: /\.svg(\?.*)?$/, + loader: + "url-loader?limit=10000&mimetype=image/svg+xml&name=images/[name].[ext]", + // include: path.join(__dirname, 'client', 'assets'), + }, + { + test: /\.png$/, + loader: + "url-loader?limit=8192&mimetype=image/png&name=images/[name].[ext]", + // include: path.join(__dirname, 'client', 'assets'), + }, + { + test: /\.gif$/, + loader: + "url-loader?limit=8192&mimetype=image/gif&name=images/[name].[ext]", + // include: path.join(__dirname, 'client', 'assets'), + }, + { + test: /\.jpg$/, + loader: + "url-loader?limit=8192&mimetype=image/jpg&name=images/[name].[ext]", + // include: path.join(__dirname, 'client', 'assets'), + }, + { + test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, + loader: "url-loader?limit=10000&mimetype=application/font-woff", + }, + { + test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, + loader: "file-loader", + }, + ], + }, + resolve: { + extensions: [".json", ".js", ".jsx"], + }, + plugins: [ + // new HtmlWebpackPlugin({ + // filename: 'index.html', + // template: 'dev/content/index-prod.html', + // inject: true + // }), + new webpack.DefinePlugin({ + "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV), + }), + // // 'process.env.HOSTNAME': JSON.stringify('localhost'), + // 'process.env.PORT': 4445 + // }), + new webpack.HotModuleReplacementPlugin(), + new webpack.NoEmitOnErrorsPlugin(), + ], }; //process.traceDeprecation = true; module.exports = config;