From ca929031ee04dce003abc097e2a44968220e52d3 Mon Sep 17 00:00:00 2001 From: "Sergio R. Caprile" Date: Tue, 12 Jul 2022 19:14:21 -0300 Subject: [PATCH] added webUI Preact-based example --- examples/webui-preact/Makefile | 20 +++++ examples/webui-preact/ca.pem | 1 + examples/webui-preact/main.c | 1 + examples/webui-preact/web_root/index.html | 8 ++ examples/webui-preact/web_root/main.js | 86 ++++++++++++++++++++ examples/webui-preact/web_root/preact.min.js | 1 + examples/webui-preact/web_root/style.css | 43 ++++++++++ 7 files changed, 160 insertions(+) create mode 100644 examples/webui-preact/Makefile create mode 120000 examples/webui-preact/ca.pem create mode 120000 examples/webui-preact/main.c create mode 100644 examples/webui-preact/web_root/index.html create mode 100644 examples/webui-preact/web_root/main.js create mode 100644 examples/webui-preact/web_root/preact.min.js create mode 100644 examples/webui-preact/web_root/style.css diff --git a/examples/webui-preact/Makefile b/examples/webui-preact/Makefile new file mode 100644 index 00000000..9addcb99 --- /dev/null +++ b/examples/webui-preact/Makefile @@ -0,0 +1,20 @@ +PROG ?= example +SSL = ? + +ifeq "$(SSL)" "MBEDTLS" +CFLAGS += -DMG_ENABLE_MBEDTLS=1 -lmbedtls -lmbedcrypto -lmbedx509 +endif + +ifeq "$(SSL)" "OPENSSL" +CFLAGS += -DMG_ENABLE_OPENSSL=1 -lssl -lcrypto +endif + +all: $(PROG) + $(DEBUGGER) ./$(PROG) $(ARGS) + + +$(PROG): main.c + $(CC) ../../mongoose.c -I../.. -W -Wall $(CFLAGS) $(EXTRA_CFLAGS) -o $(PROG) main.c + +clean: + rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb diff --git a/examples/webui-preact/ca.pem b/examples/webui-preact/ca.pem new file mode 120000 index 00000000..8addd9e2 --- /dev/null +++ b/examples/webui-preact/ca.pem @@ -0,0 +1 @@ +../../test/data/ca.pem \ No newline at end of file diff --git a/examples/webui-preact/main.c b/examples/webui-preact/main.c new file mode 120000 index 00000000..5f0bdc78 --- /dev/null +++ b/examples/webui-preact/main.c @@ -0,0 +1 @@ +../webui-plain/main.c \ No newline at end of file diff --git a/examples/webui-preact/web_root/index.html b/examples/webui-preact/web_root/index.html new file mode 100644 index 00000000..1ac23a2b --- /dev/null +++ b/examples/webui-preact/web_root/index.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/examples/webui-preact/web_root/main.js b/examples/webui-preact/web_root/main.js new file mode 100644 index 00000000..7ac7d25b --- /dev/null +++ b/examples/webui-preact/web_root/main.js @@ -0,0 +1,86 @@ +'use strict'; +import { h, html, render, useEffect, useState } from './preact.min.js'; + + +const Configuration = function (props) { + const [url, setUrl] = useState(props.config.url || ''); + const [pub, setPub] = useState(props.config.pub || ''); + const [sub, setSub] = useState(props.config.sub || ''); + + useEffect(() => { + setUrl(props.config.url); + setPub(props.config.pub); + setSub(props.config.sub); + }, [props.config]); + + const update = (name, val) => + fetch('/api/config/set', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + [name]: val + }) + }) + .catch(err => { + console.log(err); + enable(false); + }); + + const updateurl = ev => update('url', url); + const updatepub = ev => update('pub', pub); + const updatesub = ev => update('sub', sub); + + return html` +

+ Device Configuration

+
+ MQTT server: + setUrl(ev.target.value)} /> + +
+
+ Subscribe topic: + setSub(ev.target.value)} /> + +
+
+ Publish topic: + setPub(ev.target.value)} /> + +
`; +}; + + +const App = function (props) { + const [config, setConfig] = useState({}); + + const getconfig = () => + fetch('/api/config/get') + .then(r => r.json()) + .then(r => setConfig(r)) + .catch(err => console.log(err)); + + useEffect(() => { + getconfig(); + }, []); + + return html` +

Basic Preact-based UI demo

+
+ ${h(Configuration, { config })} +
+`; +}; + +window.onload = () => render(h(App), document.body); diff --git a/examples/webui-preact/web_root/preact.min.js b/examples/webui-preact/web_root/preact.min.js new file mode 100644 index 00000000..e24f87b9 --- /dev/null +++ b/examples/webui-preact/web_root/preact.min.js @@ -0,0 +1 @@ +var e,n,_,t,o,r,u,l={},i=[],c=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function s(e,n){for(var _ in n)e[_]=n[_];return e}function f(e){var n=e.parentNode;n&&n.removeChild(e)}function a(n,_,t){var o,r,u,l={};for(u in _)"key"==u?o=_[u]:"ref"==u?r=_[u]:l[u]=_[u];if(arguments.length>2&&(l.children=arguments.length>3?e.call(arguments,2):t),"function"==typeof n&&null!=n.defaultProps)for(u in n.defaultProps)void 0===l[u]&&(l[u]=n.defaultProps[u]);return p(n,l,o,r,null)}function p(e,t,o,r,u){var l={type:e,props:t,key:o,ref:r,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==u?++_:u};return null!=n.vnode&&n.vnode(l),l}function h(e){return e.children}function d(e,n){this.props=e,this.context=n}function v(e,n){if(null==n)return e.__?v(e.__,e.__.__k.indexOf(e)+1):null;for(var _;n0?p(m.type,m.props,m.key,null,m.__v):m)){if(m.__=_,m.__b=_.__b+1,null===(y=H[a])||y&&m.key==y.key&&m.type===y.type)H[a]=void 0;else for(d=0;d=t.__.length&&t.__.push({}),t.__[e]}function G(e){return R=1,z(ie,e)}function z(e,n,_){var t=j(L++,2);return t.t=e,t.__c||(t.__=[_?_(n):ie(void 0,n),function(e){var n=t.t(t.__[0],e);t.__[0]!==n&&(t.__=[n,t.__[1]],t.__c.setState({}))}],t.__c=N),t.__}function J(e,_){var t=j(L++,3);!n.__s&&le(t.__H,_)&&(t.__=e,t.__H=_,N.__H.__h.push(t))}function K(e,_){var t=j(L++,4);!n.__s&&le(t.__H,_)&&(t.__=e,t.__H=_,N.__h.push(t))}function Q(e){return R=5,Y(function(){return{current:e}},[])}function X(e,n,_){R=6,K(function(){"function"==typeof e?e(n()):e&&(e.current=n())},null==_?_:_.concat(e))}function Y(e,n){var _=j(L++,7);return le(_.__H,n)&&(_.__=e(),_.__H=n,_.__h=e),_.__}function Z(e,n){return R=8,Y(function(){return e},n)}function ee(e){var n=N.context[e.__c],_=j(L++,9);return _.c=e,n?(null==_.__&&(_.__=!0,n.sub(N)),n.props.value):e.__}function ne(e,_){n.useDebugValue&&n.useDebugValue(_?_(e):e)}function _e(e){var n=j(L++,10),_=G();return n.__=e,N.componentDidCatch||(N.componentDidCatch=function(e){n.__&&n.__(e),_[1](e)}),[_[0],function(){_[1](void 0)}]}function te(){I.forEach(function(e){if(e.__P)try{e.__H.__h.forEach(re),e.__H.__h.forEach(ue),e.__H.__h=[]}catch(_){e.__H.__h=[],n.__e(_,e.__v)}}),I=[]}n.__b=function(e){N=null,O&&O(e)},n.__r=function(e){V&&V(e),L=0;var n=(N=e.__c).__H;n&&(n.__h.forEach(re),n.__h.forEach(ue),n.__h=[])},n.diffed=function(e){q&&q(e);var _=e.__c;_&&_.__H&&_.__H.__h.length&&(1!==I.push(_)&&W===n.requestAnimationFrame||((W=n.requestAnimationFrame)||function(e){var n,_=function(){clearTimeout(t),oe&&cancelAnimationFrame(n),setTimeout(e)},t=setTimeout(_,100);oe&&(n=requestAnimationFrame(_))})(te)),N=void 0},n.__c=function(e,_){_.some(function(e){try{e.__h.forEach(re),e.__h=e.__h.filter(function(e){return!e.__||ue(e)})}catch(t){_.some(function(e){e.__h&&(e.__h=[])}),_=[],n.__e(t,e.__v)}}),B&&B(e,_)},n.unmount=function(e){$&&$(e);var _=e.__c;if(_&&_.__H)try{_.__H.__.forEach(re)}catch(e){n.__e(e,_.__v)}};var oe="function"==typeof requestAnimationFrame;function re(e){var n=N;"function"==typeof e.__c&&e.__c(),N=n}function ue(e){var n=N;e.__c=e.__(),N=n}function le(e,n){return!e||e.length!==n.length||n.some(function(n,_){return n!==e[_]})}function ie(e,n){return"function"==typeof n?n(e):n}var ce=function(e,n,_,t){var o;n[0]=0;for(var r=1;r=5&&((o||!e&&5===t)&&(u.push(t,0,o,_),t=6),e&&(u.push(t,e,0,_),t=6)),o=""},i=0;i"===n?(t=1,o=""):o=n+o[0]:r?n===r?r="":o+=n:'"'===n||"'"===n?r=n:">"===n?(l(),t=1):t&&("="===n?(t=5,_=o,o=""):"/"===n&&(t<5||">"===e[i][c+1])?(l(),3===t&&(u=u[0]),t=u,(u=u[0]).push(2,0,t),t=0):" "===n||"\t"===n||"\n"===n||"\r"===n?(l(),t=2):o+=n),3===t&&"!--"===o&&(t=4,u=u[0])}return l(),u}(e)),n),arguments,[])).length>1?n:n[0]}.bind(a);export{a as h,fe as html,M as render,d as Component,F as createContext,G as useState,z as useReducer,J as useEffect,K as useLayoutEffect,Q as useRef,X as useImperativeHandle,Y as useMemo,Z as useCallback,ee as useContext,ne as useDebugValue,_e as useErrorBoundary}; diff --git a/examples/webui-preact/web_root/style.css b/examples/webui-preact/web_root/style.css new file mode 100644 index 00000000..b483f801 --- /dev/null +++ b/examples/webui-preact/web_root/style.css @@ -0,0 +1,43 @@ +* { box-sizing: border-box; } +html, body { margin: 0; padding: 0; height: 100%; font: 16px sans-serif; } +select, input, label::before, textarea { outline: none; box-shadow:none !important; border: 1px solid #ccc !important; } +code, pre { color: #373; font-family: monospace; font-weight: bolder; font-size: smaller; background: #ddd; padding: 0.1em 0.3em; border-radius: 0.2em; } +textarea, input, .addon { font-size: 15px; border: 1px solid #ccc; padding: 0.5em; } +a, a:visited, a:active { color: #55f; } +.addon { background: #eee; min-width: 9em;} +.btn { + background: #ccc; border-radius: 0.3em; border: 0; color: #fff; cursor: pointer; + display: inline-block; padding: 0.6em 2em; font-weight: bolder; +} +.btn[disabled] { opacity: 0.5; cursor: auto;} +.smooth { transition: all .2s; } +.container { margin: 0 20px; width: auto; } +.d-flex { display: flex; } +.d-none { display: none; } +.border { border: 1px solid #ddd; } +.rounded { border-radius: 0.5em; } +.nowrap { white-space: nowrap; } +.msg { background: #def; border-left: 5px solid #59d; padding: 0.5em; font-size: 90%; margin: 1em 0; } +.section { margin: 0 1em; } +.topic, .data, .qos { padding: 0.2em 0.5em; border-radius: 0.4em; margin-right: 0.5em; } +.qos { background: #efa; } +.topic { background: #fea; } +.data { background: #aef; } + +/* Grid */ +.row { display: flex; flex-wrap: wrap; } +.col { margin: 0; padding: 0; overflow: auto; } +.col-12 { width: 100%; } +.col-11 { width: 91.66%; } +.col-10 { width: 83.33%; } +.col-9 { width: 75%; } +.col-8 { width: 66.66%; } +.col-7 { width: 58.33%; } +.col-6 { width: 50%; } +.col-5 { width: 41.66%; } +.col-4 { width: 33.33%; } +.col-3 { width: 25%; } +.col-2 { width: 16.66%; } +.col-1 { width: 8.33%; } +@media (min-width: 1310px) { .container { margin: auto; width: 1270px; } } +@media (max-width: 920px) { .row .col { width: 100%; } }