redux
This commit is contained in:
parent
428d3a2c78
commit
c23c65d386
9
client/.babelrc
Normal file
9
client/.babelrc
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
"es2015",
|
||||||
|
"react"
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
["transform-react-jsx", { "pragma":"preact.h" }]
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -1,21 +1,30 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
extends: 'airbnb-base',
|
extends: 'airbnb',
|
||||||
rules: {
|
env: {
|
||||||
// prevents stupid complaints a la
|
"browser": true,
|
||||||
// (req) {
|
"node": true
|
||||||
// req.something = x;
|
},
|
||||||
// }
|
rules: {
|
||||||
'no-param-reassign': [2, {
|
// prevents stupid complaints a la
|
||||||
props: false,
|
// (req) {
|
||||||
}],
|
// req.something = x;
|
||||||
'no-multi-spaces': [0],
|
// }
|
||||||
'max-len': ['error', 120],
|
'no-param-reassign': [2, { props: false }],
|
||||||
'import/no-extraneous-dependencies': [0],
|
'no-multi-spaces': [0],
|
||||||
'prefer-arrow-callback': [0],
|
'max-len': ['error', 120],
|
||||||
'arrow-body-style': [0],
|
'import/no-extraneous-dependencies': [0],
|
||||||
'no-console': [0],
|
'prefer-arrow-callback': [0],
|
||||||
// i like loops
|
'arrow-body-style': [0],
|
||||||
'no-plusplus': [0],
|
'no-console': [0],
|
||||||
'no-await-in-loop': [0],
|
// i like loops
|
||||||
},
|
'no-plusplus': [0],
|
||||||
|
'no-await-in-loop': [0],
|
||||||
|
'indent': ['error', 4],
|
||||||
|
|
||||||
|
// for preact
|
||||||
|
"react/react-in-jsx-scope": [0],
|
||||||
|
"react/jsx-indent": [2, 4],
|
||||||
|
"react/jsx-uses-react": 1,
|
||||||
|
"react/jsx-uses-vars": 1
|
||||||
|
},
|
||||||
};
|
};
|
||||||
@ -1,7 +1,6 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<section class="hero is-info is-large">
|
<section class="hero is-info is-large">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
@ -10,82 +9,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
</body>
|
</body>
|
||||||
|
<script src="./index.js"></script>
|
||||||
<div class="hero-head">
|
|
||||||
<nav class="navbar">
|
|
||||||
<div class="container">
|
|
||||||
<div class="navbar-brand">
|
|
||||||
<span class="navbar-burger burger" data-target="navbarMenuHeroB">
|
|
||||||
<span></span>
|
|
||||||
<span></span>
|
|
||||||
<span></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div id="navbarMenuHeroB" class="navbar-menu">
|
|
||||||
<div class="navbar-end">
|
|
||||||
<a class="navbar-item is-active">
|
|
||||||
Home
|
|
||||||
</a>
|
|
||||||
<a class="navbar-item">
|
|
||||||
Store
|
|
||||||
</a>
|
|
||||||
<a class="navbar-item">
|
|
||||||
FAQ
|
|
||||||
</a>
|
|
||||||
<span class="navbar-item">
|
|
||||||
<a class="button is-info is-inverted">
|
|
||||||
<span class="icon">
|
|
||||||
<i class="fab fa-github"></i>
|
|
||||||
</span>
|
|
||||||
<span>Download</span>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="hero-body">
|
|
||||||
<div class="container has-text-centered">
|
|
||||||
<p class="title">
|
|
||||||
Welcome to Cryps
|
|
||||||
</p>
|
|
||||||
<p class="subtitle">
|
|
||||||
The worlds best pray to win game
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id='fizzytext'></div>
|
|
||||||
|
|
||||||
<div class="hero-foot">
|
|
||||||
<nav class="tabs is-boxed is-fullwidth">
|
|
||||||
<div class="container">
|
|
||||||
<ul>
|
|
||||||
<li class="is-active">
|
|
||||||
<a>Management</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a>Inventory</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a>Missions</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a>Battles</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a>Market</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
|
|
||||||
<script src="./index.js"></script>
|
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|||||||
@ -1,81 +1,2 @@
|
|||||||
const { toast } = require('bulma-toast');
|
// kick it off
|
||||||
const { h, render } = require('preact');
|
require('./src/main');
|
||||||
|
|
||||||
const fizzyText = require('./lib/fizzy-text');
|
|
||||||
|
|
||||||
fizzyText('cryps');
|
|
||||||
|
|
||||||
const cbor = require('borc');
|
|
||||||
const assert = require('assert');
|
|
||||||
// Create WebSocket connection.
|
|
||||||
const ws = new WebSocket('ws://localhost:40000');
|
|
||||||
ws.binaryType = 'arraybuffer';
|
|
||||||
|
|
||||||
// handle account auth within the socket itself
|
|
||||||
// https://www.christian-schneider.net/CrossSiteWebSocketHijacking.html
|
|
||||||
let account = null;
|
|
||||||
|
|
||||||
function error_toast(err) {
|
|
||||||
console.error(err);
|
|
||||||
return toast({
|
|
||||||
message: err,
|
|
||||||
type: "is-warning",
|
|
||||||
duration: 5000,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function account_login(res) {
|
|
||||||
[struct, account] = res;
|
|
||||||
|
|
||||||
account = account;
|
|
||||||
|
|
||||||
console.log(account);
|
|
||||||
return send({ method: 'cryp_spawn', params: { name: 'drake' }});
|
|
||||||
}
|
|
||||||
|
|
||||||
function new_cryp(cryp) {
|
|
||||||
console.log('got a new cryp');
|
|
||||||
}
|
|
||||||
|
|
||||||
const handlers = {
|
|
||||||
'cryp_spawn': new_cryp,
|
|
||||||
'account_login': account_login,
|
|
||||||
'account_create': account_login,
|
|
||||||
};
|
|
||||||
|
|
||||||
function on_message(event) {
|
|
||||||
// decode binary msg from server
|
|
||||||
const blob = new Uint8Array(event.data);
|
|
||||||
const res = cbor.decode(blob);
|
|
||||||
console.log(res);
|
|
||||||
|
|
||||||
// check for error and split into response type and data
|
|
||||||
if (res.err) return error_toast(res.err);
|
|
||||||
const { method, params } = res;
|
|
||||||
return handlers[method](params);
|
|
||||||
}
|
|
||||||
|
|
||||||
function send(msg) {
|
|
||||||
msg.token = account && account.token;
|
|
||||||
ws.send(cbor.encode(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connection opened
|
|
||||||
ws.addEventListener('open', function (event) {
|
|
||||||
// send({ method: 'account_create', params: { name: 'ntr', password: 'grepgrepgrep' }});
|
|
||||||
send({ method: 'account_login', params: { name: 'ntr', password: 'grepgrepgrep' }});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Listen for messages
|
|
||||||
ws.addEventListener('message', on_message);
|
|
||||||
|
|
||||||
ws.addEventListener('error', function (event) {
|
|
||||||
console.error('WebSocket error', event);
|
|
||||||
account = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
ws.addEventListener('close', function (event) {
|
|
||||||
console.error('WebSocket closed', event);
|
|
||||||
account = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|||||||
@ -10,16 +10,21 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "UNLICENSED",
|
"license": "UNLICENSED",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"babel-preset-react": "^6.24.1",
|
||||||
"borc": "^2.0.3",
|
"borc": "^2.0.3",
|
||||||
"bulma-toast": "^1.2.0",
|
"bulma-toast": "^1.2.0",
|
||||||
"docco": "^0.7.0",
|
"docco": "^0.7.0",
|
||||||
"eslint": "^3.18.0",
|
|
||||||
"eslint-config-airbnb-base": "^11.1.1",
|
|
||||||
"eslint-plugin-import": "^2.2.0",
|
|
||||||
"jest": "^18.0.0",
|
"jest": "^18.0.0",
|
||||||
"parcel": "^1.9.7",
|
"parcel": "^1.9.7",
|
||||||
"preact": "^8.3.1",
|
"preact": "^8.3.1",
|
||||||
"preact-redux": "^2.0.3",
|
"preact-redux": "^2.0.3",
|
||||||
"redux": "^4.0.0"
|
"redux": "^4.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "^5.6.0",
|
||||||
|
"eslint-config-airbnb": "^17.1.0",
|
||||||
|
"eslint-plugin-import": "^2.14.0",
|
||||||
|
"eslint-plugin-jsx-a11y": "^6.1.1",
|
||||||
|
"eslint-plugin-react": "^7.11.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
3
client/src/actions.jsx
Normal file
3
client/src/actions.jsx
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export const SET_ACCOUNT = 'SET_ACCOUNT';
|
||||||
|
|
||||||
|
export const setAccount = (value) => ({ type: SET_ACCOUNT, value });
|
||||||
6
client/src/components/status.component.jsx
Normal file
6
client/src/components/status.component.jsx
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
const preact = require('preact');
|
||||||
|
|
||||||
|
module.exports = ({ account }) => {
|
||||||
|
if (account) return <div>{JSON.stringify(account)}</div>;
|
||||||
|
return <div>not logged in</div>;
|
||||||
|
};
|
||||||
13
client/src/components/status.container.js
Normal file
13
client/src/components/status.container.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
const { connect } = require('preact-redux');
|
||||||
|
|
||||||
|
const Status = require('./status.component');
|
||||||
|
|
||||||
|
// Add the incident from state as a property
|
||||||
|
const addState = connect(
|
||||||
|
state => ({ account: state.account }),
|
||||||
|
// dispatch => ({
|
||||||
|
// closeDetails() { dispatch(openIncident()); },
|
||||||
|
// }),
|
||||||
|
);
|
||||||
|
|
||||||
|
module.exports = addState(Status);
|
||||||
36
client/src/main.jsx
Normal file
36
client/src/main.jsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
const preact = require('preact');
|
||||||
|
const { Provider } = require('preact-redux');
|
||||||
|
const { createStore, combineReducers } = require('redux');
|
||||||
|
|
||||||
|
const reducers = require('./reducers');
|
||||||
|
const fizzyText = require('../lib/fizzy-text');
|
||||||
|
const createSocket = require('./socket');
|
||||||
|
|
||||||
|
const StatusContainer = require('./components/status.container');
|
||||||
|
|
||||||
|
const ws = createSocket();
|
||||||
|
|
||||||
|
const store = createStore(
|
||||||
|
combineReducers({
|
||||||
|
account: reducers.accountReducer,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
store.subscribe(() => console.log(store.getState()));
|
||||||
|
|
||||||
|
const Cryps = () => (
|
||||||
|
<section>
|
||||||
|
<div id="fizzytext" />
|
||||||
|
<StatusContainer />
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
|
||||||
|
const Main = () => (
|
||||||
|
<Provider store={store}>
|
||||||
|
<Cryps />
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
|
||||||
|
preact.render(<Main />, document.body);
|
||||||
|
|
||||||
|
fizzyText('cryps');
|
||||||
15
client/src/reducers.jsx
Normal file
15
client/src/reducers.jsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
const { SET_ACCOUNT } = require('./actions');
|
||||||
|
|
||||||
|
const defaultAccount = {};
|
||||||
|
function accountReducer(state = defaultAccount, action) {
|
||||||
|
switch (action.type) {
|
||||||
|
case SET_ACCOUNT:
|
||||||
|
return action.value;
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
accountReducer,
|
||||||
|
};
|
||||||
83
client/src/socket.jsx
Normal file
83
client/src/socket.jsx
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
const { toast } = require('bulma-toast');
|
||||||
|
|
||||||
|
const actions = require('./actions');
|
||||||
|
|
||||||
|
const cbor = require('borc');
|
||||||
|
|
||||||
|
function errorToast(err) {
|
||||||
|
console.error(err);
|
||||||
|
return toast({
|
||||||
|
message: err,
|
||||||
|
type: 'is-warning',
|
||||||
|
duration: 5000,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create WebSocket connection.
|
||||||
|
// requires the redux store in order to push updates
|
||||||
|
// to components
|
||||||
|
function createSocket(store) {
|
||||||
|
const ws = new WebSocket('ws://localhost:40000');
|
||||||
|
ws.binaryType = 'arraybuffer';
|
||||||
|
|
||||||
|
// handle account auth within the socket itself
|
||||||
|
// https://www.christian-schneider.net/CrossSiteWebSocketHijacking.html
|
||||||
|
let account = null;
|
||||||
|
|
||||||
|
function send(msg) {
|
||||||
|
msg.token = account && account.token;
|
||||||
|
ws.send(cbor.encode(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
function accountLogin(res) {
|
||||||
|
const [struct, login] = res;
|
||||||
|
|
||||||
|
account = login;
|
||||||
|
store.dispatch(actions.setAccount(login));
|
||||||
|
console.log(account);
|
||||||
|
return send({ method: 'cryp_spawn', params: { name: 'drake' }});
|
||||||
|
}
|
||||||
|
|
||||||
|
function crypSpawn(cryp) {
|
||||||
|
console.log('got a new cryp', cryp);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlers = {
|
||||||
|
cryp_spawn: crypSpawn,
|
||||||
|
account_login: accountLogin,
|
||||||
|
account_create: accountLogin,
|
||||||
|
};
|
||||||
|
|
||||||
|
function onMessage(event) {
|
||||||
|
// decode binary msg from server
|
||||||
|
const blob = new Uint8Array(event.data);
|
||||||
|
const res = cbor.decode(blob);
|
||||||
|
console.log(res);
|
||||||
|
|
||||||
|
// check for error and split into response type and data
|
||||||
|
if (res.err) return errorToast(res.err);
|
||||||
|
const { method, params } = res;
|
||||||
|
return handlers[method](params);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connection opened
|
||||||
|
ws.addEventListener('open', function wsOpen(event) {
|
||||||
|
// send({ method: 'account_create', params: { name: 'ntr', password: 'grepgrepgrep' }});
|
||||||
|
send({ method: 'account_login', params: { name: 'ntr', password: 'grepgrepgrep' } });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Listen for messages
|
||||||
|
ws.addEventListener('message', onMessage);
|
||||||
|
|
||||||
|
ws.addEventListener('error', function wsError(event) {
|
||||||
|
console.error('WebSocket error', event);
|
||||||
|
account = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
ws.addEventListener('close', function wsClose(event) {
|
||||||
|
console.error('WebSocket closed', event);
|
||||||
|
account = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = createSocket;
|
||||||
Loading…
x
Reference in New Issue
Block a user