feat: React UI! WorldTime as Component

This commit is contained in:
cha0s 2019-04-12 11:04:59 -05:00
parent 67ef5ff17a
commit 49e229a74a
8 changed files with 187 additions and 26 deletions

View File

@ -7,6 +7,7 @@ module.exports = function (api) {
];
const plugins = [
'@babel/plugin-proposal-object-rest-spread',
'react-hot-loader/babel',
];
return {

View File

@ -31,18 +31,6 @@
.app .avocado-stage {
margin: auto;
}
.ui .time {
background-color: rgba(0, 0, 0, .3);
border: 0.5px solid gray;
border-radius: 50px;
color: white;
position: absolute;
top: 5px;
right: 5px;
line-height: 1em;
padding: 0.5em;
font-family: monospace;
}
</style>
</head>
<body>

View File

@ -1,3 +1,6 @@
// 3rd party.
import React from 'react';
import ReactDOM from 'react-dom';
// 2nd party.
import {create as createClient} from '@avocado/client/socket';
import {EntityList} from '@avocado/entity';
@ -11,6 +14,7 @@ import {clearAnimation, setAnimation, Ticker} from '@avocado/timing';
// 1st party.
import {InputPacket, KeysPacket, StatePacket} from '../common/packet';
import {WorldTime} from '../common/world-time';
import Ui from './ui';
// DOM.
const appNode = document.querySelector('.app');
// Lol Apple
@ -32,10 +36,13 @@ stage.element.addEventListener('focus', () => {
isFocused = true;
});
stage.addToDom(appNode);
// Time display.
const timeUi = document.createElement('div');
timeUi.className = 'time unselectable';
stage.ui.appendChild(timeUi);
// World time ticker.
const worldTimeTicker = new Ticker(1 / 10);
// UI.
const UiComponent = <Ui
worldTimeTicker={worldTimeTicker}
/>;
ReactDOM.render(UiComponent, stage.ui);
// Handle "own" entity.
let selfEntity;
function hasSelfEntity() {
@ -48,7 +55,9 @@ const roomView = new RoomView(room, stage.renderer);
stage.addChild(roomView);
// Time.
const worldTime = new WorldTime();
let lastWorldTime = worldTime.humanReadable();
worldTimeTicker.on('tick', () => {
worldTimeTicker.emit('updateTime', worldTime.hour)
});
// Synchronize state.
let state = undefined;
const synchronizer = new Synchronizer({
@ -188,6 +197,8 @@ const predictionHandle = setInterval(() => {
state = synchronizer.state;
// Render timing.
renderTicker.tick(elapsed);
// World time ticker.
worldTimeTicker.tick(elapsed);
// Apply environmental lighting.
let intensity = 0;
if (worldTime.hour >= 21 || worldTime.hour < 4) {
@ -241,10 +252,6 @@ function render() {
return false;
}
mayRender = false;
if (worldTime.humanReadable() !== lastWorldTime) {
timeUi.textContent = worldTime.humanReadable();
lastWorldTime = worldTime.humanReadable();
}
stage.render();
dirty = false;
}

11
client/ui/index.js Normal file
View File

@ -0,0 +1,11 @@
// 3rd party.
import React from 'react';
import {hot} from 'react-hot-loader/root';
// 1st party.
import WorldTime from './world-time';
const Ui = ({worldTimeTicker}) => {
return <WorldTime ticker={worldTimeTicker} />;
};
export default hot(Ui);

40
client/ui/world-time.js Normal file
View File

@ -0,0 +1,40 @@
// 3rd party.
import React, {useEffect, useState} from 'react';
// 2nd party.
import {compose} from '@avocado/core';
import contempo from 'contempo';
// 1st party.
import {WorldTime} from '../../common/world-time';
const decorate = compose(
contempo(`
.time {
background-color: rgba(0, 0, 0, .3);
border: 0.5px solid gray;
border-radius: 50px;
color: white;
position: absolute;
top: 5px;
right: 5px;
line-height: 1em;
padding: 0.5em;
font-family: monospace;
}
`),
);
const WorldTimeComponent = ({ticker}) => {
const [time, setTime] = useState('--:-- --');
useEffect(() => {
const updater = (hour) => {
setTime(WorldTime.format(hour));
};
ticker.on('updateTime', updater);
return () => {
ticker.off('updateTime', updater);
};
}, []);
return <div className="time unselectable">{time}</div>;
}
export default decorate(WorldTimeComponent);

View File

@ -18,7 +18,7 @@
"webpack-node-externals": "1.7.2"
},
"scripts": {
"client": "webpack-dev-server --config webpack.client.config.js",
"client": "webpack-dev-server --hot --config webpack.client.config.js",
"server": "webpack --config webpack.server.config.js",
"start": "webpack --config webpack.server.config.js && webpack-dev-server --config webpack.client.config.js"
},
@ -36,9 +36,13 @@
"@avocado/state": "1.x",
"@avocado/timing": "1.x",
"@avocado/topdown": "1.x",
"contempo": "1.x",
"glob": "^7.1.3",
"immutablediff": "0.4.4",
"is-plain-object": "2.0.4",
"react": "16.8.6",
"react-dom": "16.8.6",
"react-hot-loader": "4.8.3",
"source-map-support": "^0.5.11"
}
}

View File

@ -10,7 +10,7 @@ const config = {
{
test: /\.js$/,
exclude: [
/(node_modules\/(?!@avocado))/,
/(node_modules\/(?!@avocado|contempo))/,
],
use: {
loader: 'babel-loader',

116
yarn.lock
View File

@ -1441,6 +1441,13 @@ constants-browserify@^1.0.0:
version "1.0.0"
resolved "https://npm.i12e.cha0s.io/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
contempo@1.x:
version "1.0.1"
resolved "https://npm.i12e.cha0s.io/contempo/-/contempo-1.0.1.tgz#f084b53ede757e92ff32bac7df9d278426f1c64a"
dependencies:
css "^2.2.4"
react "^16.5.0"
content-disposition@0.5.2:
version "0.5.2"
resolved "https://npm.i12e.cha0s.io/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4"
@ -1553,6 +1560,15 @@ css-what@2.1:
version "2.1.3"
resolved "https://npm.i12e.cha0s.io/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2"
css@^2.2.4:
version "2.2.4"
resolved "https://npm.i12e.cha0s.io/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929"
dependencies:
inherits "^2.0.3"
source-map "^0.6.1"
source-map-resolve "^0.5.2"
urix "^0.1.0"
cyclist@~0.2.2:
version "0.2.2"
resolved "https://npm.i12e.cha0s.io/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
@ -1723,6 +1739,10 @@ dom-serializer@0:
domelementtype "^1.3.0"
entities "^1.1.1"
dom-walk@^0.1.0:
version "0.1.1"
resolved "https://npm.i12e.cha0s.io/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
domain-browser@^1.1.1:
version "1.2.0"
resolved "https://npm.i12e.cha0s.io/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
@ -2033,6 +2053,10 @@ fast-json-stable-stringify@^2.0.0:
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
fast-levenshtein@^2.0.6:
version "2.0.6"
resolved "https://npm.i12e.cha0s.io/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
faye-websocket@^0.10.0:
version "0.10.0"
resolved "https://npm.i12e.cha0s.io/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4"
@ -2224,6 +2248,13 @@ global-prefix@^1.0.1:
is-windows "^1.0.1"
which "^1.2.14"
global@^4.3.0:
version "4.3.2"
resolved "https://npm.i12e.cha0s.io/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f"
dependencies:
min-document "^2.19.0"
process "~0.5.1"
globals@^11.1.0:
version "11.11.0"
resolved "https://npm.i12e.cha0s.io/globals/-/globals-11.11.0.tgz#dcf93757fa2de5486fbeed7118538adf789e9c2e"
@ -2327,6 +2358,12 @@ hmac-drbg@^1.0.0:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"
hoist-non-react-statics@^3.3.0:
version "3.3.0"
resolved "https://npm.i12e.cha0s.io/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz#b09178f0122184fb95acf525daaecb4d8f45958b"
dependencies:
react-is "^16.7.0"
homedir-polyfill@^1.0.1:
version "1.0.3"
resolved "https://npm.i12e.cha0s.io/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8"
@ -2824,7 +2861,7 @@ loglevel@^1.4.1:
version "1.6.1"
resolved "https://npm.i12e.cha0s.io/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa"
loose-envify@^1.0.0:
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://npm.i12e.cha0s.io/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
dependencies:
@ -2953,6 +2990,12 @@ mimic-fn@^2.0.0:
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/mimic-fn/-/mimic-fn-2.0.0.tgz#0913ff0b121db44ef5848242c38bbb35d44cabde"
min-document@^2.19.0:
version "2.19.0"
resolved "https://npm.i12e.cha0s.io/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
dependencies:
dom-walk "^0.1.0"
mini-signals@^1.1.1:
version "1.2.0"
resolved "https://npm.i12e.cha0s.io/mini-signals/-/mini-signals-1.2.0.tgz#45b08013c5fae51a24aa1a935cd317c9ed721d74"
@ -3211,7 +3254,7 @@ number-is-nan@^1.0.0:
version "1.0.1"
resolved "https://npm.i12e.cha0s.io/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
object-assign@^4.0.1, object-assign@^4.1.0:
object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
resolved "https://npm.i12e.cha0s.io/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
@ -3516,10 +3559,22 @@ process@^0.11.10:
version "0.11.10"
resolved "https://npm.i12e.cha0s.io/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
process@~0.5.1:
version "0.5.2"
resolved "https://npm.i12e.cha0s.io/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf"
promise-inflight@^1.0.1:
version "1.0.1"
resolved "https://npm.i12e.cha0s.io/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
prop-types@^15.6.1, prop-types@^15.6.2:
version "15.7.2"
resolved "https://npm.i12e.cha0s.io/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
dependencies:
loose-envify "^1.4.0"
object-assign "^4.1.1"
react-is "^16.8.1"
proxy-addr@~2.0.4:
version "2.0.4"
resolved "https://npm.i12e.cha0s.io/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93"
@ -3627,6 +3682,46 @@ rc@^1.2.7:
minimist "^1.2.0"
strip-json-comments "~2.0.1"
react-dom@16.8.6:
version "16.8.6"
resolved "https://npm.i12e.cha0s.io/react-dom/-/react-dom-16.8.6.tgz#71d6303f631e8b0097f56165ef608f051ff6e10f"
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.2"
scheduler "^0.13.6"
react-hot-loader@4.8.3:
version "4.8.3"
resolved "https://npm.i12e.cha0s.io/react-hot-loader/-/react-hot-loader-4.8.3.tgz#14f018777a60ea9cfa60496c7341c2f967311253"
dependencies:
fast-levenshtein "^2.0.6"
global "^4.3.0"
hoist-non-react-statics "^3.3.0"
loader-utils "^1.1.0"
lodash "^4.17.11"
prop-types "^15.6.1"
react-lifecycles-compat "^3.0.4"
shallowequal "^1.0.2"
source-map "^0.7.3"
react-is@^16.7.0, react-is@^16.8.1:
version "16.8.6"
resolved "https://npm.i12e.cha0s.io/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16"
react-lifecycles-compat@^3.0.4:
version "3.0.4"
resolved "https://npm.i12e.cha0s.io/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
react@16.8.6, react@^16.5.0:
version "16.8.6"
resolved "https://npm.i12e.cha0s.io/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe"
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.2"
scheduler "^0.13.6"
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6:
version "2.3.6"
resolved "https://npm.i12e.cha0s.io/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
@ -3824,6 +3919,13 @@ sax@^1.2.4:
version "1.2.4"
resolved "https://npm.i12e.cha0s.io/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
scheduler@^0.13.6:
version "0.13.6"
resolved "https://npm.i12e.cha0s.io/scheduler/-/scheduler-0.13.6.tgz#466a4ec332467b31a91b9bf74e5347072e4cd889"
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
schema-utils@^1.0.0:
version "1.0.0"
resolved "https://npm.i12e.cha0s.io/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770"
@ -3930,6 +4032,10 @@ sha.js@^2.4.0, sha.js@^2.4.8:
inherits "^2.0.1"
safe-buffer "^5.0.1"
shallowequal@^1.0.2:
version "1.1.0"
resolved "https://npm.i12e.cha0s.io/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
shebang-command@^1.2.0:
version "1.2.0"
resolved "https://npm.i12e.cha0s.io/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
@ -4035,7 +4141,7 @@ source-list-map@^2.0.0:
version "2.0.1"
resolved "https://npm.i12e.cha0s.io/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
source-map-resolve@^0.5.0:
source-map-resolve@^0.5.0, source-map-resolve@^0.5.2:
version "0.5.2"
resolved "https://npm.i12e.cha0s.io/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259"
dependencies:
@ -4064,6 +4170,10 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
version "0.6.1"
resolved "https://npm.i12e.cha0s.io/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
source-map@^0.7.3:
version "0.7.3"
resolved "https://npm.i12e.cha0s.io/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
spdy-transport@^3.0.0:
version "3.0.0"
resolved "https://npm.i12e.cha0s.io/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31"