Skip to content
Snippets Groups Projects
Commit 3806811b authored by Benjamin Koltes's avatar Benjamin Koltes
Browse files

Merge branch 'refactor/preact' into 'master'

Refactor preact

See merge request hermod/tv_panel!7
parents d7848ed4 eb0a9672
Branches
No related tags found
No related merge requests found
{
"presets": ["es2015"],
"plugins": [["transform-react-jsx", { "pragma": "h" }]]
"presets": ["preact"],
"plugins": ["transform-class-properties"]
}
{
"parser": "babel-eslint",
"extends": "airbnb-base"
"extends": "airbnb",
"rules": {
"react/jsx-filename-extension": "off",
"react/prop-types": "off"
},
"settings": {
"react": {
"pragma": "h"
}
}
}
const toDash = string => string.replace(/([A-Z])/g, char => `-${char.toLowerCase()}`);
const cssStringify = (object) => {
const array = Object.keys(object).map((cssAttribute) => {
if (typeof object[cssAttribute] === 'object') {
return `${toDash(cssAttribute)} {${cssStringify(object[cssAttribute])}}`;
}
return `${toDash(cssAttribute)}: ${object[cssAttribute]};`;
});
return array.join('');
};
export default cssStringify;
const diffNodes = (parentNode, newNodes) => {
const previousChildNumber = parentNode.childElementCount;
const newChildNumber = newNodes.length;
const previousChildren = parentNode.childNodes;
for (let index = 0; index < Math.min(previousChildNumber, newChildNumber); index += 1) {
parentNode.replaceChild(newNodes[index], previousChildren[index]);
}
for (
let index = Math.min(previousChildNumber, newChildNumber);
index < previousChildNumber;
index += 1
) {
parentNode.removeChild(previousChildren[index]);
}
for (
let index = Math.min(previousChildNumber, newChildNumber);
index < newChildNumber;
index += 1
) {
parentNode.appendChild(newNodes[index]);
}
};
export default diffNodes;
import cssStringify from './cssStringify';
const concatTextParts = textParts =>
textParts.map((part) => {
const style = 'style' in part ? cssStringify(part.style) : '';
return (
<span className="text-element" style={style}>
{part.text}
</span>
);
});
const jsonTextToHtml = data => <div className="bloc text-bloc">{concatTextParts(data.text)}</div>;
const jsonImageToHtml = (data) => {
const style =
'heightFactor' in data ? `height: calc(${data.heightFactor} * var(--rowHeight))` : '';
return (
<div className="bloc image-bloc" style={style}>
<img src={data.image} />
</div>
);
};
const jsonImageTextToHtml = data => (
<div className="bloc image-text-bloc">
<img src={data.image} />
<div className="text-section">{concatTextParts(data.text)}</div>
</div>
);
export default (data) => {
const head = <div style="background-color:#F2F2FF; padding:10px" />;
data.rows
.map((row) => {
if (!row) {
return '';
}
switch (row.type) {
case 0:
return jsonTextToHtml(row);
case 1:
return jsonImageTextToHtml(row);
case 2:
return jsonImageToHtml(row);
default:
return '';
}
})
.forEach((row) => {
if (typeof row !== 'string') {
head.appendChild(row);
}
});
const foot = (
<div className="mini">
<p>
Last data: {new Date(Date.now()).toLocaleString()}; TTL: {data.ttl / 1000}s
</p>
<p>Hermod version {data.version}, 2018</p>
</div>
);
return [<hr className="mini" />, head, <hr style="color: #DDDDDD" />, foot];
};
import h from 'hyperscript';
Object.defineProperty(window, 'h', {
value: h,
writable: false,
configurable: false,
});
import { h, Component } from 'preact';
import Row from './Row';
import socketIO from './socket';
class App extends Component {
state = { data: { rows: [], version: null } };
componentDidMount = () => {
socketIO.on('panel_data', this.onReceiveMessage);
};
componentWillUnmount = () => {
socketIO.removeListener('panel_data', this.onReceiveMessage);
};
onReceiveMessage = (data) => {
this.setState({ data });
setTimeout(() => {
socketIO.emit('panel_data');
}, data.ttl);
};
render() {
return (
<div>
<hr className="mini" />
{this.state.data.rows.map(row => <Row row={row} />)}
<hr style={{ color: '#DDDDDD' }} />
<div className="mini">
<p>
Last data: {new Date(Date.now()).toLocaleString()}; TTL: {this.state.data.ttl / 1000}s
</p>
<p>Hermod version {this.state.data.version}, 2018</p>
</div>
</div>
);
}
}
export default App;
import { h } from 'preact';
const TextElement = ({ element: { style, text } }) => (
<span className="text-element" style={style}>
{text}
</span>
);
const PureTextRow = ({ row }) => (
<div className="bloc text-bloc">{row.text.map(element => <TextElement element={element} />)}</div>
);
const PureImageRow = ({ row }) => {
const style =
'heightFactor' in row ? { height: `calc(${row.heightFactor} * var(--rowHeight))` } : {};
return (
<div className="bloc image-bloc" style={style}>
<img src={row.image} alt="" />
</div>
);
};
const TextAndImageRow = ({ row }) => (
<div className="bloc image-text-bloc">
<img src={row.image} alt="" />
<div className="text-section">{row.text.map(element => <TextElement element={element} />)}</div>
</div>
);
const Row = ({ row }) => {
let SubRow;
switch (row.type) {
case 0:
SubRow = PureTextRow;
break;
case 1:
SubRow = TextAndImageRow;
break;
case 2:
SubRow = PureImageRow;
break;
default:
SubRow = null;
break;
}
return (
<div style={{ backgroundColor: '#F2F2FF', padding: '10px' }}>
<SubRow row={row} />
</div>
);
};
export default Row;
File moved
......@@ -18,8 +18,7 @@
<style type="text/css" id="root"></style>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.slim.js"></script>
<script type="text/javascript" src="./setup.js" defer></script>
<script type="text/javascript" src="./socket.js" defer></script>
<script type="text/javascript" src="./index.js" defer></script>
</body>
</html>
\ No newline at end of file
import jsonToHtmlArray from './display';
import diffNodes from './diffNodes';
import { port, host } from './config';
import { h, render } from 'preact';
const socketIO = io.connect(`http://${host || 'localhost'}:${port || 3000}/`);
import App from './App';
import socketIO from './socket';
socketIO.on('connect', () => {
socketIO.emit('date');
setInterval(() => {
socketIO.emit('date');
}, 1000);
socketIO.emit('panel_data');
});
const container = document.getElementById('panel_data');
const existingNode = container.querySelector('*');
render(<App />, container, existingNode);
socketIO.on('config', (data) => {
document.getElementById('root').innerHTML = `html
......@@ -24,17 +18,3 @@ socketIO.on('config', (data) => {
socketIO.on('date', (data) => {
document.getElementById('date').innerHTML = new Date(data.date).toLocaleString();
});
socketIO.on('panel_data', (data) => {
// console.log(data);
// data.ttl = 500000;
setTimeout(() => {
socketIO.emit('panel_data');
}, data.ttl);
const panelData = document.getElementById('panel_data');
diffNodes(panelData, jsonToHtmlArray(data));
});
// socketIO.on('message', (data) => {
// console.log(data);
// });
import { port, host } from './config';
const socketIO = io.connect(`http://${host || 'localhost'}:${port || 3000}/`);
socketIO.on('connect', () => {
socketIO.emit('date');
setInterval(() => {
socketIO.emit('date');
}, 1000);
socketIO.emit('panel_data');
});
export default socketIO;
......@@ -8,7 +8,8 @@
.text-element {
font-size: var(--fontSize);
margin: auto;
margin-top: auto;
margin-bottom: auto;
}
.bloc {
......@@ -16,6 +17,7 @@
}
.text-bloc {
min-height: var(--rowHeight);
border: 1px solid black;
background-color: #e2ffe0;
padding: 10px;
......@@ -29,9 +31,10 @@
}
.image-bloc img {
height: 100px;
height: 100%;
margin-left: auto;
margin-right: auto;
display: block;
}
.image-text-bloc {
......
......@@ -9,27 +9,30 @@
"start": "yarn start:dev",
"start:dev": "nodemon ./server/index.js",
"start:prod": "node ./server/index.js",
"start:front": "parcel serve ./front/ -d build",
"start:front": "parcel serve ./front/src/index.html -d build",
"build:front":
"rm -f build/* && parcel build ./front/ -d build --public-url / --no-cache && mv build/*.html build/index.html",
"rm -f ./front/build/* && parcel build ./front/src/index.html -d ./front/build --public-url / --no-cache",
"sslGenKey": "openssl genrsa 2048 > key.pem",
"sslGenCert": "openssl req -x509 -days 1000 -new -key key.pem -out cert.pem",
"sslGen": "npm run sslGenKey && npm run sslGenCert"
},
"dependencies": {
"hyperscript": "^2.0.2",
"css-in-js-stringify": "^1.0.0",
"jsonwebtoken": "^8.1.1",
"node-fetch": "^2.0.0",
"parcel-bundler": "^1.5.1",
"preact": "^8.2.7",
"socket.io": "^2.0.4"
},
"devDependencies": {
"babel-eslint": "^8.2.1",
"babel-plugin-transform-react-jsx": "^6.24.1",
"babel-preset-es2015": "^6.24.1",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-preset-preact": "^1.1.0",
"eslint": "^4.17.0",
"eslint-config-airbnb-base": "^12.1.0",
"eslint-config-airbnb": "^16.1.0",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-react": "^7.4.0",
"nodemon": "^1.14.12"
}
}
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment