This commit is contained in:
ntr 2018-09-18 20:13:22 +10:00
parent 428d3a2c78
commit c23c65d386
11 changed files with 204 additions and 180 deletions

9
client/.babelrc Normal file
View File

@ -0,0 +1,9 @@
{
"presets": [
"es2015",
"react"
],
"plugins": [
["transform-react-jsx", { "pragma":"preact.h" }]
]
}

View File

@ -1,21 +1,30 @@
module.exports = {
extends: 'airbnb-base',
rules: {
// prevents stupid complaints a la
// (req) {
// req.something = x;
// }
'no-param-reassign': [2, {
props: false,
}],
'no-multi-spaces': [0],
'max-len': ['error', 120],
'import/no-extraneous-dependencies': [0],
'prefer-arrow-callback': [0],
'arrow-body-style': [0],
'no-console': [0],
// i like loops
'no-plusplus': [0],
'no-await-in-loop': [0],
},
extends: 'airbnb',
env: {
"browser": true,
"node": true
},
rules: {
// prevents stupid complaints a la
// (req) {
// req.something = x;
// }
'no-param-reassign': [2, { props: false }],
'no-multi-spaces': [0],
'max-len': ['error', 120],
'import/no-extraneous-dependencies': [0],
'prefer-arrow-callback': [0],
'arrow-body-style': [0],
'no-console': [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
},
};

View File

@ -1,7 +1,6 @@
<!DOCTYPE html>
<html>
<section class="hero is-info is-large">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
@ -10,82 +9,7 @@
</head>
<body>
</body>
<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>
<script src="./index.js"></script>
</html>
<!--

View File

@ -1,81 +1,2 @@
const { toast } = require('bulma-toast');
const { h, render } = require('preact');
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;
});
// kick it off
require('./src/main');

View File

@ -10,16 +10,21 @@
"author": "",
"license": "UNLICENSED",
"dependencies": {
"babel-preset-react": "^6.24.1",
"borc": "^2.0.3",
"bulma-toast": "^1.2.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",
"parcel": "^1.9.7",
"preact": "^8.3.1",
"preact-redux": "^2.0.3",
"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
View File

@ -0,0 +1,3 @@
export const SET_ACCOUNT = 'SET_ACCOUNT';
export const setAccount = (value) => ({ type: SET_ACCOUNT, value });

View 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>;
};

View 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
View 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
View 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
View 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;