diff options
-rw-r--r-- | src/main/js/package.json | 3 | ||||
-rw-r--r-- | src/main/js/src/components/modals/username.js | 40 | ||||
-rw-r--r-- | src/main/js/src/containers/App/actions.js | 5 | ||||
-rw-r--r-- | src/main/js/src/containers/App/constants.js | 1 | ||||
-rw-r--r-- | src/main/js/src/containers/App/index.js | 75 | ||||
-rw-r--r-- | src/main/js/src/containers/App/saga.js | 38 | ||||
-rw-r--r-- | src/main/js/src/containers/GameBrowser/index.js | 11 | ||||
-rw-r--r-- | src/main/js/src/sagas.js | 6 | ||||
-rw-r--r-- | src/main/js/src/utils/createWebSocketConnection.js | 13 | ||||
-rw-r--r-- | src/main/js/src/wsSagas.js | 42 |
10 files changed, 180 insertions, 54 deletions
diff --git a/src/main/js/package.json b/src/main/js/package.json index eff6dc38..0c1bdbb9 100644 --- a/src/main/js/package.json +++ b/src/main/js/package.json @@ -24,5 +24,6 @@ }, "eslintConfig": { "extends": "react-app" - } + }, + "proxy": "ws://localhost:8080" } diff --git a/src/main/js/src/components/modals/username.js b/src/main/js/src/components/modals/username.js new file mode 100644 index 00000000..61b52114 --- /dev/null +++ b/src/main/js/src/components/modals/username.js @@ -0,0 +1,40 @@ +import React from 'react' +import { + Overlay, + Panel, + PanelHeader, + PanelFooter, + Button, + Input, + Close, + Space +} from 'rebass' + +const Modal = ({ modalOpen, toggleModal }) => ( + <Overlay open={modalOpen} onDismiss={toggleModal('usernameModal')}> + <Panel theme="info"> + <PanelHeader> + What's your username ? + <Space auto /> + <Close onClick={toggleModal('usernameModal')} /> + </PanelHeader> + <Input + label="Username" + name="username" + placeholder="Cesar92" + rounded + type="text" + /> + <PanelFooter> + <Space auto /> + <Button + theme="success" + onClick={toggleModal('usernameModal')} + children="Ok" + /> + </PanelFooter> + </Panel> + </Overlay> +) + +export default Modal diff --git a/src/main/js/src/containers/App/actions.js b/src/main/js/src/containers/App/actions.js new file mode 100644 index 00000000..cfb617d5 --- /dev/null +++ b/src/main/js/src/containers/App/actions.js @@ -0,0 +1,5 @@ +import { INITIALIZE_WS } from "./constants" + +export const initializeWs = () => ({ + type: INITIALIZE_WS +}) diff --git a/src/main/js/src/containers/App/constants.js b/src/main/js/src/containers/App/constants.js new file mode 100644 index 00000000..be31f8cc --- /dev/null +++ b/src/main/js/src/containers/App/constants.js @@ -0,0 +1 @@ +export const INITIALIZE_WS = 'app/INITIALIZE_WS' diff --git a/src/main/js/src/containers/App/index.js b/src/main/js/src/containers/App/index.js index b190f960..73b70ec3 100644 --- a/src/main/js/src/containers/App/index.js +++ b/src/main/js/src/containers/App/index.js @@ -1,10 +1,67 @@ -import React from 'react' +import React, { Component } from 'react' import { Link } from 'react-router' -export default () => { - return <div> - <h1>Hello World</h1> - <Link to="/counter">Go to counter +/-</Link> - <br/> - <Link to="/404">Go to 404</Link> - </div> -}
\ No newline at end of file +import { + Banner, + Heading, + Space, + Button, + Text +} from 'rebass' +import { Flex } from 'reflexbox' +import Modal from '../../components/modals/username' +import GameBrowser from '../GameBrowser' + +class App extends Component { + state = { + usernameModal: false + } + + componentDidMount() { + + } + + toggleModal = (key) => { + return (e) => { + const val = !this.state[key] + this.setState({ [key]: val }) + } + } + + render() { + return ( + <div> + <Banner + align="center" + style={{minHeight: '30vh'}} + backgroundImage="https://images.unsplash.com/photo-1431207446535-a9296cf995b1?dpr=1&auto=format&fit=crop&w=1199&h=799&q=80&cs=tinysrgb&crop=" + > + <Heading level={1}>Seven Wonders</Heading> + </Banner> + <Flex align="center" p={1}> + <Button + theme="success" + children="Create Game"/> + <Space auto /> + <Text><b>Username:</b> Cesar92</Text> + <Space x={1} /> + <Button + onClick={this.toggleModal('usernameModal')} + children="Change"/> + </Flex> + <GameBrowser /> + <Modal toggleModal={this.toggleModal} modalOpen={this.state.usernameModal} /> + </div> + ) + } +} + +const mapStateToProps = (state) => ({ + +}) + +import { initializeWs } from "./actions"; +const mapDispatchToProps = { + initializeWs +} + +export default App diff --git a/src/main/js/src/containers/App/saga.js b/src/main/js/src/containers/App/saga.js new file mode 100644 index 00000000..4ccf6019 --- /dev/null +++ b/src/main/js/src/containers/App/saga.js @@ -0,0 +1,38 @@ +import { call, put, take } from 'redux-saga/effects' +import { eventChannel } from 'redux-saga' +import createWebSocketConnection from "../../utils/createWebSocketConnection"; + +function createSocketChannel(socket) { + return eventChannel(emit => { + const errorHandler = event => emit(JSON.parse(event)) + + const userErrors = socket.subscribe('/user/queue/errors', errorHandler) + + const unsubscribe = () => { + userErrors.unsubscribe() + } + + return unsubscribe + }) +} + +export function* watchOnErrors() { + let socketChannel + try { + const { socket } = yield call(createWebSocketConnection) + socketChannel = createSocketChannel(socket) + } catch (error) { + console.error('Error connecting to socket', error) + } + + if (!socketChannel) { + return + } + + while (true) { + const payload = yield take(socketChannel) + yield put({ type: 'USER_ERROR', payload }) + } +} + +export default watchOnErrors
\ No newline at end of file diff --git a/src/main/js/src/containers/GameBrowser/index.js b/src/main/js/src/containers/GameBrowser/index.js new file mode 100644 index 00000000..34a50d53 --- /dev/null +++ b/src/main/js/src/containers/GameBrowser/index.js @@ -0,0 +1,11 @@ +import React, { Component } from 'react' + +class GameBrowser extends Component { + render() { + return ( + <div>Game Browser</div> + ) + } +} + +export default GameBrowser
\ No newline at end of file diff --git a/src/main/js/src/sagas.js b/src/main/js/src/sagas.js index 80222362..46aa278e 100644 --- a/src/main/js/src/sagas.js +++ b/src/main/js/src/sagas.js @@ -1,7 +1,9 @@ import { fork } from 'redux-saga/effects' import counterSaga from './containers/Counter/saga' +import errorSaga from './containers/App/saga' export default function* rootSaga() { - yield fork(counterSaga) -}
\ No newline at end of file + yield fork(counterSaga) + yield fork(errorSaga) +} diff --git a/src/main/js/src/utils/createWebSocketConnection.js b/src/main/js/src/utils/createWebSocketConnection.js new file mode 100644 index 00000000..2f0e5245 --- /dev/null +++ b/src/main/js/src/utils/createWebSocketConnection.js @@ -0,0 +1,13 @@ +import SockJS from 'sockjs-client' +import Stomp from 'webstomp-client' +const wsURL = 'http://localhost:8080/seven-wonders-websocket' + +let socket = null +export default () => { + return new Promise((resolve, reject) => { + socket = Stomp.over(new SockJS(wsURL)) + socket.connect({}, (frame) => { + return resolve({ frame, socket }) + }, reject) + }) +}
\ No newline at end of file diff --git a/src/main/js/src/wsSagas.js b/src/main/js/src/wsSagas.js deleted file mode 100644 index b6dcce95..00000000 --- a/src/main/js/src/wsSagas.js +++ /dev/null @@ -1,42 +0,0 @@ -import { call, put, take } from 'redux-saga/effects' -import SockJS from 'sockjs-client' -import Stomp from 'webstomp-client' -const wsURL = '/seven-wonders-websocket' -let socket = null; - -const openSocket = () => { - socket = Stomp.over(new SockJS(wsURL)) - socket.connect({}, (frame) => { - console.log('Connected') - - socket.subscribe('/user/queue/errors', (msg) => - console.error('/user/queue/errors', msg) - ) - - socket.subscribe('/topic/games', (msg) => { - const game = JSON.parse(msg) - console.error('/topic/games', game) - }) - - socket.subscribe('/user/queue/join-game', (msg) => { - const game = JSON.parse(msg) - console.error('/user/queue/join-game', game) - }) - }) -} - -const disconnect = () => { - if (!socket) { - socket.disconnect() - console.log('Disconnected') - } -} - -export default function* wsSagas() { - const channel = yield call(openSocket) - - while (true) { - const action = yield take(channel) - yield put(action) - } -} |