Compare commits

...

21 Commits

Author SHA1 Message Date
4e7fa44301 Add delay for writing files 2021-03-23 18:27:05 -06:00
Elijah Lucian
104d39b4c6 🐛🔨 2021-03-24 00:04:04 -07:00
Elijah Lucian
88e62bdf48 Merge branch 'master' of https://git.tannercollin.com/tanner/3Dshock 2021-03-23 23:40:56 -07:00
Elijah Lucian
b9c8b6c1e6 💎 2021-03-23 23:40:53 -07:00
66f86827ff Allow adjusting LED time and add time info 2021-03-23 17:30:47 -06:00
Elijah Lucian
8ca4d55045 🔧 2021-03-17 10:33:11 -06:00
E
2b495779d3 adding dank transition 2021-03-11 13:11:18 -07:00
Tanner
ce46f006d5 Add random delay to fake download 2021-03-10 22:41:37 -07:00
E
5f8aad7355 Merge branch 'master' of https://git.tannercollin.com/tanner/3Dshock 2021-03-10 22:33:22 -07:00
E
c975432b73 🌫🎲🎰🎇📟🎏 2021-03-10 22:33:06 -07:00
be140b4c22 Add number to fake downloaded photos 2021-03-10 22:24:18 -07:00
E
3c5855ecd3 Merge branch 'master' of https://git.tannercollin.com/tanner/3Dshock 2021-03-10 20:04:21 -07:00
E
1499ee5736 🌠 2021-03-10 20:04:18 -07:00
Tanner
a07d4469c0 Add screenshot of network settings 2021-03-10 20:00:23 -07:00
Tanner
5e565f84c2 Add test for capture 2021-03-10 20:00:08 -07:00
E
b2cc6f4723 Merge branch 'master' of https://git.tannercollin.com/tanner/3Dshock 2021-03-10 19:51:34 -07:00
E
6720816a97 🗯 2021-03-10 19:51:31 -07:00
Tanner
5c15c8fcf5 Freeze requirements 2021-03-10 19:35:13 -07:00
738e688c51 Adjust capture and add logging 2021-03-10 19:22:41 -07:00
19352bf409 Add license 2021-03-10 19:22:41 -07:00
a632034751 Change statuses to ints 2021-03-10 19:22:41 -07:00
35 changed files with 433 additions and 360 deletions

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2021 Tanner and Elijah
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,25 +1,25 @@
{
"files": {
"main.css": "/static/css/main.15b3868d.chunk.css",
"main.js": "/static/js/main.4a4e0606.chunk.js",
"main.js.map": "/static/js/main.4a4e0606.chunk.js.map",
"runtime-main.js": "/static/js/runtime-main.e5089e68.js",
"runtime-main.js.map": "/static/js/runtime-main.e5089e68.js.map",
"main.css": "/static/css/main.895ab0f5.chunk.css",
"main.js": "/static/js/main.4388b0cf.chunk.js",
"main.js.map": "/static/js/main.4388b0cf.chunk.js.map",
"runtime-main.js": "/static/js/runtime-main.8d7962eb.js",
"runtime-main.js.map": "/static/js/runtime-main.8d7962eb.js.map",
"static/css/2.015dc0ab.chunk.css": "/static/css/2.015dc0ab.chunk.css",
"static/js/2.d35ab7cd.chunk.js": "/static/js/2.d35ab7cd.chunk.js",
"static/js/2.d35ab7cd.chunk.js.map": "/static/js/2.d35ab7cd.chunk.js.map",
"static/js/3.fc2e2142.chunk.js": "/static/js/3.fc2e2142.chunk.js",
"static/js/3.fc2e2142.chunk.js.map": "/static/js/3.fc2e2142.chunk.js.map",
"static/js/2.6d12aa16.chunk.js": "/static/js/2.6d12aa16.chunk.js",
"static/js/2.6d12aa16.chunk.js.map": "/static/js/2.6d12aa16.chunk.js.map",
"static/js/3.8e9312c3.chunk.js": "/static/js/3.8e9312c3.chunk.js",
"static/js/3.8e9312c3.chunk.js.map": "/static/js/3.8e9312c3.chunk.js.map",
"index.html": "/index.html",
"static/css/2.015dc0ab.chunk.css.map": "/static/css/2.015dc0ab.chunk.css.map",
"static/css/main.15b3868d.chunk.css.map": "/static/css/main.15b3868d.chunk.css.map",
"static/js/2.d35ab7cd.chunk.js.LICENSE.txt": "/static/js/2.d35ab7cd.chunk.js.LICENSE.txt"
"static/css/main.895ab0f5.chunk.css.map": "/static/css/main.895ab0f5.chunk.css.map",
"static/js/2.6d12aa16.chunk.js.LICENSE.txt": "/static/js/2.6d12aa16.chunk.js.LICENSE.txt"
},
"entrypoints": [
"static/js/runtime-main.e5089e68.js",
"static/js/runtime-main.8d7962eb.js",
"static/css/2.015dc0ab.chunk.css",
"static/js/2.d35ab7cd.chunk.js",
"static/css/main.15b3868d.chunk.css",
"static/js/main.4a4e0606.chunk.js"
"static/js/2.6d12aa16.chunk.js",
"static/css/main.895ab0f5.chunk.css",
"static/js/main.4388b0cf.chunk.js"
]
}

View File

@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="3D Shock by Tanner and Elijah enterprises"/><link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>⚡</text></svg>"><link rel="manifest" href="/manifest.json"/><title>3D Shock!</title><link href="/static/css/2.015dc0ab.chunk.css" rel="stylesheet"><link href="/static/css/main.15b3868d.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function t(t){for(var n,i,a=t[0],c=t[1],l=t[2],s=0,p=[];s<a.length;s++)i=a[s],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&p.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(t);p.length;)p.shift()();return u.push.apply(u,l||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,a=1;a<r.length;a++){var c=r[a];0!==o[c]&&(n=!1)}n&&(u.splice(t--,1),e=i(i.s=r[0]))}return e}var n={},o={1:0},u=[];function i(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.e=function(e){var t=[],r=o[e];if(0!==r)if(r)t.push(r[2]);else{var n=new Promise((function(t,n){r=o[e]=[t,n]}));t.push(r[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"fc2e2142"}[e]+".chunk.js"}(e);var c=new Error;u=function(t){a.onerror=a.onload=null,clearTimeout(l);var r=o[e];if(0!==r){if(r){var n=t&&("load"===t.type?"missing":t.type),u=t&&t.target&&t.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,r[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(t)},i.m=e,i.c=n,i.d=function(e,t,r){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(i.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)i.d(r,n,function(t){return e[t]}.bind(null,n));return r},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="/",i.oe=function(e){throw console.error(e),e};var a=this.webpackJsonpclient=this.webpackJsonpclient||[],c=a.push.bind(a);a.push=t,a=a.slice();for(var l=0;l<a.length;l++)t(a[l]);var f=c;r()}([])</script><script src="/static/js/2.d35ab7cd.chunk.js"></script><script src="/static/js/main.4a4e0606.chunk.js"></script></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="3D Shock by Tanner and Elijah enterprises"/><link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>⚡</text></svg>"><link rel="manifest" href="/manifest.json"/><title>3D Shock!</title><link href="/static/css/2.015dc0ab.chunk.css" rel="stylesheet"><link href="/static/css/main.895ab0f5.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function t(t){for(var n,i,a=t[0],c=t[1],l=t[2],s=0,p=[];s<a.length;s++)i=a[s],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&p.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(t);p.length;)p.shift()();return u.push.apply(u,l||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,a=1;a<r.length;a++){var c=r[a];0!==o[c]&&(n=!1)}n&&(u.splice(t--,1),e=i(i.s=r[0]))}return e}var n={},o={1:0},u=[];function i(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.e=function(e){var t=[],r=o[e];if(0!==r)if(r)t.push(r[2]);else{var n=new Promise((function(t,n){r=o[e]=[t,n]}));t.push(r[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"8e9312c3"}[e]+".chunk.js"}(e);var c=new Error;u=function(t){a.onerror=a.onload=null,clearTimeout(l);var r=o[e];if(0!==r){if(r){var n=t&&("load"===t.type?"missing":t.type),u=t&&t.target&&t.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,r[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(t)},i.m=e,i.c=n,i.d=function(e,t,r){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(i.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)i.d(r,n,function(t){return e[t]}.bind(null,n));return r},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="/",i.oe=function(e){throw console.error(e),e};var a=this.webpackJsonpclient=this.webpackJsonpclient||[],c=a.push.bind(a);a.push=t,a=a.slice();for(var l=0;l<a.length;l++)t(a[l]);var f=c;r()}([])</script><script src="/static/js/2.6d12aa16.chunk.js"></script><script src="/static/js/main.4388b0cf.chunk.js"></script></body></html>

View File

@@ -1,2 +0,0 @@
body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,"Courier New",monospace}form{max-width:500px;-webkit-flex-direction:column;flex-direction:column}form,form label{display:-webkit-flex;display:flex;margin:auto}form label{width:100%;-webkit-flex-direction:row;flex-direction:row;-webkit-justify-content:space-between;justify-content:space-between}.App{text-align:center}.App-logo{height:40vmin;pointer-events:none}@media (prefers-reduced-motion:no-preference){.App-logo{-webkit-animation:App-logo-spin 20s linear infinite;animation:App-logo-spin 20s linear infinite}}.App-header{background-color:#282c34;min-height:100vh;display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;font-size:calc(10px + 2vmin);color:#fff}.App-link{color:#61dafb}@-webkit-keyframes App-logo-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes App-logo-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.error{color:red}.photo-wall{display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap;margin:2rem}.dashboard-form{margin:auto}.ant-card{margin:1rem}.ant-card img{max-width:250px}.loading-bar-container{background:#282c34;width:100%}.loading-bar{background:green}
/*# sourceMappingURL=main.15b3868d.chunk.css.map */

View File

@@ -1 +0,0 @@
{"version":3,"sources":["webpack://src/index.css","webpack://src/App.css"],"names":[],"mappings":"AAAA,KACE,QAAS,CACT,mJAEY,CACZ,kCAAmC,CACnC,iCACF,CAEA,KACE,yEAEF,CAEA,KAEE,eAAgB,CAEhB,6BAAsB,CAAtB,qBACF,CAEA,gBANE,oBAAa,CAAb,YAAa,CAEb,WAUF,CANA,WACE,UAAW,CAEX,0BAAmB,CAAnB,kBAAmB,CACnB,qCAA8B,CAA9B,6BAEF,CC3BA,KACE,iBACF,CAEA,UACE,aAAc,CACd,mBACF,CAEA,8CACE,UACE,mDAA4C,CAA5C,2CACF,CACF,CAEA,YACE,wBAAyB,CACzB,gBAAiB,CACjB,oBAAa,CAAb,YAAa,CACb,6BAAsB,CAAtB,qBAAsB,CACtB,0BAAmB,CAAnB,kBAAmB,CACnB,8BAAuB,CAAvB,sBAAuB,CACvB,4BAA6B,CAC7B,UACF,CAEA,UACE,aACF,CAEA,iCACE,GACE,8BAAuB,CAAvB,sBACF,CACA,GACE,+BAAyB,CAAzB,uBACF,CACF,CAPA,yBACE,GACE,8BAAuB,CAAvB,sBACF,CACA,GACE,+BAAyB,CAAzB,uBACF,CACF,CAEA,OACE,SACF,CAEA,YACE,oBAAa,CAAb,YAAa,CACb,sBAAe,CAAf,cAAe,CACf,WACF,CAEA,gBACE,WACF,CAEA,UACE,WACF,CAEA,cACE,eACF,CAEA,uBACE,kBAAmB,CACnB,UACF,CAEA,aACE,gBACF","file":"main.15b3868d.chunk.css","sourcesContent":["body {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\",\n \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\",\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, \"Courier New\",\n monospace;\n}\n\nform {\n display: flex;\n max-width: 500px;\n margin: auto;\n flex-direction: column;\n}\n\nform label {\n width: 100%; \n display: flex;\n flex-direction: row;\n justify-content: space-between;\n margin: auto;\n}\n\n",".App {\n text-align: center;\n}\n\n.App-logo {\n height: 40vmin;\n pointer-events: none;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .App-logo {\n animation: App-logo-spin infinite 20s linear;\n }\n}\n\n.App-header {\n background-color: #282c34;\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n font-size: calc(10px + 2vmin);\n color: white;\n}\n\n.App-link {\n color: #61dafb;\n}\n\n@keyframes App-logo-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n.error {\n color: red;\n}\n\n.photo-wall {\n display: flex;\n flex-wrap: wrap;\n margin: 2rem;\n}\n\n.dashboard-form {\n margin: auto;\n}\n\n.ant-card {\n margin: 1rem;\n}\n\n.ant-card img {\n max-width: 250px;\n}\n\n.loading-bar-container {\n background: #282c34;\n width: 100%;\n}\n\n.loading-bar {\n background: green;\n}\n"]}

View File

@@ -0,0 +1,2 @@
body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,"Courier New",monospace}form{max-width:500px;-webkit-flex-direction:column;flex-direction:column}form,form label{display:-webkit-flex;display:flex;margin:auto}form label{width:100%;-webkit-flex-direction:row;flex-direction:row;-webkit-justify-content:space-between;justify-content:space-between}:root{--color-primary:#282c34}.App-header{background-color:#282c34;background-color:var(--color-primary);min-height:100vh;display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;font-size:calc(10px + 2vmin);color:#fff}.App-link{color:#61dafb}@-webkit-keyframes App-logo-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes App-logo-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.error{color:red}.photo-wall{display:-webkit-flex;display:flex;-webkit-justify-content:center;justify-content:center;-webkit-flex-wrap:wrap;flex-wrap:wrap;margin:2rem}.dashboard-form{margin:auto}.ant-card{margin:1rem}.ant-card img{max-width:250px}.loading-bar-container{background:#282c34;background:var(--color-primary);width:100%;height:30px;min-height:30px}.loading-bar{transition:all .5s linear;background:#6f6;height:100%}.page-head{background:#282c34;background:var(--color-primary);color:#fff!important;margin-top:0;padding:1rem}.session-toolbar button{margin:0 .5rem;padding:.5rem 1rem;height:100%;font-weight:700;text-transform:uppercase;letter-spacing:.05rem}.ant-modal-content{border-radius:1rem;padding:0!important}.ant-modal-body img{border-radius:.5rem}.ant-modal-close{font-weight:700}.ant-card{border:1px solid #282c34;border:1px solid var(--color-primary);border-radius:.2rem}.ant-card-head{background:#282c34;background:var(--color-primary);color:#fff;font-weight:700;text-transform:uppercase;letter-spacing:.2rem}.session-toolbar{-webkit-justify-content:center;justify-content:center;width:60%;margin:1rem auto}.session-toolbar h3{font-weight:700;color:#fff;margin-right:1rem}.slider{width:400px;margin:auto 1rem}.toolbar{padding:.5rem;background:#282c34;background:var(--color-primary)}.client-info{-webkit-justify-content:center;justify-content:center;width:60%;margin:1rem auto}.client-info span{margin:auto 1rem}
/*# sourceMappingURL=main.895ab0f5.chunk.css.map */

View File

@@ -0,0 +1 @@
{"version":3,"sources":["webpack://src/index.css","webpack://src/App.css"],"names":[],"mappings":"AAAA,KACE,QAAS,CACT,mJAEY,CACZ,kCAAmC,CACnC,iCACF,CAEA,KACE,yEAEF,CAEA,KAEE,eAAgB,CAEhB,6BAAsB,CAAtB,qBACF,CAEA,gBANE,oBAAa,CAAb,YAAa,CAEb,WAUF,CANA,WACE,UAAW,CAEX,0BAAmB,CAAnB,kBAAmB,CACnB,qCAA8B,CAA9B,6BAEF,CC3BA,MACE,uBACF,CAEA,YACE,wBAAsC,CAAtC,qCAAsC,CACtC,gBAAiB,CACjB,oBAAa,CAAb,YAAa,CACb,6BAAsB,CAAtB,qBAAsB,CACtB,0BAAmB,CAAnB,kBAAmB,CACnB,8BAAuB,CAAvB,sBAAuB,CACvB,4BAA6B,CAC7B,UACF,CAEA,UACE,aACF,CAEA,iCACE,GACE,8BAAuB,CAAvB,sBACF,CACA,GACE,+BAAyB,CAAzB,uBACF,CACF,CAPA,yBACE,GACE,8BAAuB,CAAvB,sBACF,CACA,GACE,+BAAyB,CAAzB,uBACF,CACF,CAEA,OACE,SACF,CAEA,YACE,oBAAa,CAAb,YAAa,CACb,8BAAuB,CAAvB,sBAAuB,CACvB,sBAAe,CAAf,cAAe,CACf,WACF,CAEA,gBACE,WACF,CAEA,UACE,WACF,CAEA,cACE,eACF,CAEA,uBACE,kBAAgC,CAAhC,+BAAgC,CAChC,UAAW,CACX,WAAY,CACZ,eACF,CAEA,aACE,yBAA2B,CAC3B,eAAmB,CACnB,WACF,CAEA,WACE,kBAAgC,CAAhC,+BAAgC,CAChC,oBAAuB,CACvB,YAAa,CACb,YACF,CAEA,wBACE,cAAgB,CAChB,kBAAoB,CACpB,WAAY,CACZ,eAAiB,CACjB,wBAAyB,CACzB,qBACF,CAEA,mBACE,kBAAmB,CACnB,mBACF,CAEA,oBACE,mBACF,CAEA,iBACE,eACF,CAEA,UACE,wBAAsC,CAAtC,qCAAsC,CACtC,mBACF,CAEA,eACE,kBAAgC,CAAhC,+BAAgC,CAChC,UAAY,CACZ,eAAiB,CACjB,wBAAyB,CACzB,oBACF,CAEA,iBACE,8BAAuB,CAAvB,sBAAuB,CACvB,SAAU,CACV,gBACF,CAEA,oBACE,eAAiB,CACjB,UAAY,CACZ,iBACF,CAEA,QACE,WAAY,CACZ,gBACF,CAEA,SACE,aAAe,CACf,kBAAgC,CAAhC,+BACF,CAEA,aACE,8BAAuB,CAAvB,sBAAuB,CACvB,SAAU,CACV,gBACF,CAEA,kBACE,gBACF","file":"main.895ab0f5.chunk.css","sourcesContent":["body {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\",\n \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\",\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, \"Courier New\",\n monospace;\n}\n\nform {\n display: flex;\n max-width: 500px;\n margin: auto;\n flex-direction: column;\n}\n\nform label {\n width: 100%; \n display: flex;\n flex-direction: row;\n justify-content: space-between;\n margin: auto;\n}\n\n",":root {\n --color-primary: #282c34;\n}\n\n.App-header {\n background-color: var(--color-primary);\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n font-size: calc(10px + 2vmin);\n color: white;\n}\n\n.App-link {\n color: #61dafb;\n}\n\n@keyframes App-logo-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n.error {\n color: red;\n}\n\n.photo-wall {\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n margin: 2rem;\n}\n\n.dashboard-form {\n margin: auto;\n}\n\n.ant-card {\n margin: 1rem;\n}\n\n.ant-card img {\n max-width: 250px;\n}\n\n.loading-bar-container {\n background: var(--color-primary);\n width: 100%;\n height: 30px;\n min-height: 30px;\n}\n\n.loading-bar {\n transition: all 0.5s linear;\n background: #66ff66;\n height: 100%;\n}\n\n.page-head {\n background: var(--color-primary);\n color: white !important;\n margin-top: 0;\n padding: 1rem;\n}\n\n.session-toolbar button {\n margin: 0 0.5rem;\n padding: 0.5rem 1rem;\n height: 100%;\n font-weight: bold;\n text-transform: uppercase;\n letter-spacing: 0.05rem;\n}\n\n.ant-modal-content {\n border-radius: 1rem;\n padding: 0 !important;\n}\n\n.ant-modal-body img {\n border-radius: 0.5rem;\n}\n\n.ant-modal-close {\n font-weight: bold;\n}\n\n.ant-card {\n border: 1px solid var(--color-primary);\n border-radius: 0.2rem;\n}\n\n.ant-card-head {\n background: var(--color-primary);\n color: white;\n font-weight: bold;\n text-transform: uppercase;\n letter-spacing: 0.2rem;\n}\n\n.session-toolbar {\n justify-content: center;\n width: 60%;\n margin: 1rem auto;\n}\n\n.session-toolbar h3 {\n font-weight: bold;\n color: white;\n margin-right: 1rem;\n}\n\n.slider {\n width: 400px;\n margin: auto 1rem;\n}\n\n.toolbar {\n padding: 0.5rem;\n background: var(--color-primary);\n}\n\n.client-info {\n justify-content: center;\n width: 60%;\n margin: 1rem auto;\n}\n\n.client-info span {\n margin: auto 1rem;\n}\n"]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,2 +1,2 @@
(this.webpackJsonpclient=this.webpackJsonpclient||[]).push([[3],{400:function(t,n,e){"use strict";e.r(n),e.d(n,"getCLS",(function(){return v})),e.d(n,"getFCP",(function(){return y})),e.d(n,"getFID",(function(){return k})),e.d(n,"getLCP",(function(){return C})),e.d(n,"getTTFB",(function(){return P}));var i,a,r,o,c=function(t,n){return{name:t,value:void 0===n?-1:n,delta:0,entries:[],id:"v1-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12)}},u=function(t,n){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var e=new PerformanceObserver((function(t){return t.getEntries().map(n)}));return e.observe({type:t,buffered:!0}),e}}catch(t){}},f=!1,s=function(t,n){f||"undefined"!=typeof InstallTrigger||(addEventListener("beforeunload",(function(){})),f=!0),addEventListener("visibilitychange",(function e(i){"hidden"===document.visibilityState&&(t(i),n&&removeEventListener("visibilitychange",e,!0))}),!0)},d=function(t){addEventListener("pageshow",(function(n){n.persisted&&t(n)}),!0)},m="function"==typeof WeakSet?new WeakSet:new Set,p=function(t,n,e){var i;return function(){n.value>=0&&(e||m.has(n)||"hidden"===document.visibilityState)&&(n.delta=n.value-(i||0),(n.delta||void 0===i)&&(i=n.value,t(n)))}},v=function(t,n){var e,i=c("CLS",0),a=function(t){t.hadRecentInput||(i.value+=t.value,i.entries.push(t),e())},r=u("layout-shift",a);r&&(e=p(t,i,n),s((function(){r.takeRecords().map(a),e()})),d((function(){i=c("CLS",0),e=p(t,i,n)})))},l=-1,h=function(){return"hidden"===document.visibilityState?0:1/0},S=function(){s((function(t){var n=t.timeStamp;l=n}),!0)},g=function(){return l<0&&(l=h(),S(),d((function(){setTimeout((function(){l=h(),S()}),0)}))),{get timeStamp(){return l}}},y=function(t,n){var e,i=g(),a=c("FCP"),r=u("paint",(function(t){"first-contentful-paint"===t.name&&(r&&r.disconnect(),t.startTime<i.timeStamp&&(a.value=t.startTime,a.entries.push(t),m.add(a),e()))}));r&&(e=p(t,a,n),d((function(i){a=c("FCP"),e=p(t,a,n),requestAnimationFrame((function(){requestAnimationFrame((function(){a.value=performance.now()-i.timeStamp,m.add(a),e()}))}))})))},w={passive:!0,capture:!0},E=new Date,L=function(t,n){i||(i=n,a=t,r=new Date,F(removeEventListener),T())},T=function(){if(a>=0&&a<r-E){var t={entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+a};o.forEach((function(n){n(t)})),o=[]}},b=function(t){if(t.cancelable){var n=(t.timeStamp>1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,n){var e=function(){L(t,n),a()},i=function(){a()},a=function(){removeEventListener("pointerup",e,w),removeEventListener("pointercancel",i,w)};addEventListener("pointerup",e,w),addEventListener("pointercancel",i,w)}(n,t):L(n,t)}},F=function(t){["mousedown","keydown","touchstart","pointerdown"].forEach((function(n){return t(n,b,w)}))},k=function(t,n){var e,r=g(),f=c("FID"),v=function(t){t.startTime<r.timeStamp&&(f.value=t.processingStart-t.startTime,f.entries.push(t),m.add(f),e())},l=u("first-input",v);e=p(t,f,n),l&&s((function(){l.takeRecords().map(v),l.disconnect()}),!0),l&&d((function(){var r;f=c("FID"),e=p(t,f,n),o=[],a=-1,i=null,F(addEventListener),r=v,o.push(r),T()}))},C=function(t,n){var e,i=g(),a=c("LCP"),r=function(t){var n=t.startTime;n<i.timeStamp&&(a.value=n,a.entries.push(t)),e()},o=u("largest-contentful-paint",r);if(o){e=p(t,a,n);var f=function(){m.has(a)||(o.takeRecords().map(r),o.disconnect(),m.add(a),e())};["keydown","click"].forEach((function(t){addEventListener(t,f,{once:!0,capture:!0})})),s(f,!0),d((function(i){a=c("LCP"),e=p(t,a,n),requestAnimationFrame((function(){requestAnimationFrame((function(){a.value=performance.now()-i.timeStamp,m.add(a),e()}))}))}))}},P=function(t){var n,e=c("TTFB");n=function(){try{var n=performance.getEntriesByType("navigation")[0]||function(){var t=performance.timing,n={entryType:"navigation",startTime:0};for(var e in t)"navigationStart"!==e&&"toJSON"!==e&&(n[e]=Math.max(t[e]-t.navigationStart,0));return n}();e.value=e.delta=n.responseStart,e.entries=[n],t(e)}catch(t){}},"complete"===document.readyState?setTimeout(n,0):addEventListener("pageshow",n)}}}]);
//# sourceMappingURL=3.fc2e2142.chunk.js.map
(this.webpackJsonpclient=this.webpackJsonpclient||[]).push([[3],{399:function(t,n,e){"use strict";e.r(n),e.d(n,"getCLS",(function(){return v})),e.d(n,"getFCP",(function(){return y})),e.d(n,"getFID",(function(){return k})),e.d(n,"getLCP",(function(){return C})),e.d(n,"getTTFB",(function(){return P}));var i,a,r,o,c=function(t,n){return{name:t,value:void 0===n?-1:n,delta:0,entries:[],id:"v1-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12)}},u=function(t,n){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var e=new PerformanceObserver((function(t){return t.getEntries().map(n)}));return e.observe({type:t,buffered:!0}),e}}catch(t){}},f=!1,s=function(t,n){f||"undefined"!=typeof InstallTrigger||(addEventListener("beforeunload",(function(){})),f=!0),addEventListener("visibilitychange",(function e(i){"hidden"===document.visibilityState&&(t(i),n&&removeEventListener("visibilitychange",e,!0))}),!0)},d=function(t){addEventListener("pageshow",(function(n){n.persisted&&t(n)}),!0)},m="function"==typeof WeakSet?new WeakSet:new Set,p=function(t,n,e){var i;return function(){n.value>=0&&(e||m.has(n)||"hidden"===document.visibilityState)&&(n.delta=n.value-(i||0),(n.delta||void 0===i)&&(i=n.value,t(n)))}},v=function(t,n){var e,i=c("CLS",0),a=function(t){t.hadRecentInput||(i.value+=t.value,i.entries.push(t),e())},r=u("layout-shift",a);r&&(e=p(t,i,n),s((function(){r.takeRecords().map(a),e()})),d((function(){i=c("CLS",0),e=p(t,i,n)})))},l=-1,h=function(){return"hidden"===document.visibilityState?0:1/0},S=function(){s((function(t){var n=t.timeStamp;l=n}),!0)},g=function(){return l<0&&(l=h(),S(),d((function(){setTimeout((function(){l=h(),S()}),0)}))),{get timeStamp(){return l}}},y=function(t,n){var e,i=g(),a=c("FCP"),r=u("paint",(function(t){"first-contentful-paint"===t.name&&(r&&r.disconnect(),t.startTime<i.timeStamp&&(a.value=t.startTime,a.entries.push(t),m.add(a),e()))}));r&&(e=p(t,a,n),d((function(i){a=c("FCP"),e=p(t,a,n),requestAnimationFrame((function(){requestAnimationFrame((function(){a.value=performance.now()-i.timeStamp,m.add(a),e()}))}))})))},w={passive:!0,capture:!0},E=new Date,L=function(t,n){i||(i=n,a=t,r=new Date,F(removeEventListener),T())},T=function(){if(a>=0&&a<r-E){var t={entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+a};o.forEach((function(n){n(t)})),o=[]}},b=function(t){if(t.cancelable){var n=(t.timeStamp>1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,n){var e=function(){L(t,n),a()},i=function(){a()},a=function(){removeEventListener("pointerup",e,w),removeEventListener("pointercancel",i,w)};addEventListener("pointerup",e,w),addEventListener("pointercancel",i,w)}(n,t):L(n,t)}},F=function(t){["mousedown","keydown","touchstart","pointerdown"].forEach((function(n){return t(n,b,w)}))},k=function(t,n){var e,r=g(),f=c("FID"),v=function(t){t.startTime<r.timeStamp&&(f.value=t.processingStart-t.startTime,f.entries.push(t),m.add(f),e())},l=u("first-input",v);e=p(t,f,n),l&&s((function(){l.takeRecords().map(v),l.disconnect()}),!0),l&&d((function(){var r;f=c("FID"),e=p(t,f,n),o=[],a=-1,i=null,F(addEventListener),r=v,o.push(r),T()}))},C=function(t,n){var e,i=g(),a=c("LCP"),r=function(t){var n=t.startTime;n<i.timeStamp&&(a.value=n,a.entries.push(t)),e()},o=u("largest-contentful-paint",r);if(o){e=p(t,a,n);var f=function(){m.has(a)||(o.takeRecords().map(r),o.disconnect(),m.add(a),e())};["keydown","click"].forEach((function(t){addEventListener(t,f,{once:!0,capture:!0})})),s(f,!0),d((function(i){a=c("LCP"),e=p(t,a,n),requestAnimationFrame((function(){requestAnimationFrame((function(){a.value=performance.now()-i.timeStamp,m.add(a),e()}))}))}))}},P=function(t){var n,e=c("TTFB");n=function(){try{var n=performance.getEntriesByType("navigation")[0]||function(){var t=performance.timing,n={entryType:"navigation",startTime:0};for(var e in t)"navigationStart"!==e&&"toJSON"!==e&&(n[e]=Math.max(t[e]-t.navigationStart,0));return n}();e.value=e.delta=n.responseStart,e.entries=[n],t(e)}catch(t){}},"complete"===document.readyState?setTimeout(n,0):addEventListener("pageshow",n)}}}]);
//# sourceMappingURL=3.8e9312c3.chunk.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,2 +1,2 @@
!function(e){function t(t){for(var n,i,a=t[0],c=t[1],l=t[2],s=0,p=[];s<a.length;s++)i=a[s],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&p.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(t);p.length;)p.shift()();return u.push.apply(u,l||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,a=1;a<r.length;a++){var c=r[a];0!==o[c]&&(n=!1)}n&&(u.splice(t--,1),e=i(i.s=r[0]))}return e}var n={},o={1:0},u=[];function i(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.e=function(e){var t=[],r=o[e];if(0!==r)if(r)t.push(r[2]);else{var n=new Promise((function(t,n){r=o[e]=[t,n]}));t.push(r[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"fc2e2142"}[e]+".chunk.js"}(e);var c=new Error;u=function(t){a.onerror=a.onload=null,clearTimeout(l);var r=o[e];if(0!==r){if(r){var n=t&&("load"===t.type?"missing":t.type),u=t&&t.target&&t.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,r[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(t)},i.m=e,i.c=n,i.d=function(e,t,r){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},i.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(i.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)i.d(r,n,function(t){return e[t]}.bind(null,n));return r},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="/",i.oe=function(e){throw console.error(e),e};var a=this.webpackJsonpclient=this.webpackJsonpclient||[],c=a.push.bind(a);a.push=t,a=a.slice();for(var l=0;l<a.length;l++)t(a[l]);var f=c;r()}([]);
//# sourceMappingURL=runtime-main.e5089e68.js.map
!function(e){function t(t){for(var n,i,a=t[0],c=t[1],l=t[2],s=0,p=[];s<a.length;s++)i=a[s],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&p.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(t);p.length;)p.shift()();return u.push.apply(u,l||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,a=1;a<r.length;a++){var c=r[a];0!==o[c]&&(n=!1)}n&&(u.splice(t--,1),e=i(i.s=r[0]))}return e}var n={},o={1:0},u=[];function i(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.e=function(e){var t=[],r=o[e];if(0!==r)if(r)t.push(r[2]);else{var n=new Promise((function(t,n){r=o[e]=[t,n]}));t.push(r[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"8e9312c3"}[e]+".chunk.js"}(e);var c=new Error;u=function(t){a.onerror=a.onload=null,clearTimeout(l);var r=o[e];if(0!==r){if(r){var n=t&&("load"===t.type?"missing":t.type),u=t&&t.target&&t.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,r[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(t)},i.m=e,i.c=n,i.d=function(e,t,r){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},i.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(i.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)i.d(r,n,function(t){return e[t]}.bind(null,n));return r},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="/",i.oe=function(e){throw console.error(e),e};var a=this.webpackJsonpclient=this.webpackJsonpclient||[],c=a.push.bind(a);a.push=t,a=a.slice();for(var l=0;l<a.length;l++)t(a[l]);var f=c;r()}([]);
//# sourceMappingURL=runtime-main.8d7962eb.js.map

176
client/package-lock.json generated
View File

@@ -49,9 +49,6 @@
},
"engines": {
"node": ">=8"
},
"peerDependencies": {
"react": ">=16.0.0"
}
},
"node_modules/@ant-design/icons-svg": {
@@ -1618,7 +1615,6 @@
"jest-resolve": "^26.6.2",
"jest-util": "^26.6.2",
"jest-worker": "^26.6.2",
"node-notifier": "^8.0.0",
"slash": "^3.0.0",
"source-map": "^0.6.0",
"string-length": "^4.0.1",
@@ -3011,14 +3007,6 @@
"rc-util": "^5.8.1",
"scroll-into-view-if-needed": "^2.2.25",
"warning": "^4.0.3"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/ant-design"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/anymatch": {
@@ -5387,18 +5375,8 @@
"integrity": "sha512-X3bf2iTPgCAQp9wvjOQytnf5vO5rESYRXlPIVcgSbtT5OTScPcsf9eZU+B/YIkKAtYr5WeCii58BgATrNitlWg==",
"engines": {
"node": ">=0.11"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/date-fns"
}
},
"node_modules/dayjs": {
"version": "1.10.4",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.4.tgz",
"integrity": "sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw==",
"peer": true
},
"node_modules/debug": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
@@ -9601,7 +9579,6 @@
"@types/node": "*",
"anymatch": "^3.0.3",
"fb-watchman": "^2.0.0",
"fsevents": "^2.1.2",
"graceful-fs": "^4.2.4",
"jest-regex-util": "^26.0.0",
"jest-serializer": "^26.6.2",
@@ -10898,10 +10875,6 @@
"dependencies": {
"hoist-non-react-statics": "^3.3.2",
"shallowequal": "^1.0.2"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/minimalistic-assert": {
@@ -13622,10 +13595,6 @@
"dom-align": "^1.7.0",
"rc-util": "^5.3.0",
"resize-observer-polyfill": "^1.5.1"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-cascader": {
@@ -13638,10 +13607,6 @@
"rc-trigger": "^5.0.4",
"rc-util": "^5.0.1",
"warning": "^4.0.1"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-checkbox": {
@@ -13651,10 +13616,6 @@
"dependencies": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.1"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-collapse": {
@@ -13667,10 +13628,6 @@
"rc-motion": "^2.3.4",
"rc-util": "^5.2.1",
"shallowequal": "^1.1.0"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-dialog": {
@@ -13682,10 +13639,6 @@
"classnames": "^2.2.6",
"rc-motion": "^2.3.0",
"rc-util": "^5.6.1"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-drawer": {
@@ -13696,10 +13649,6 @@
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.6",
"rc-util": "^5.7.0"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-dropdown": {
@@ -13710,10 +13659,6 @@
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.6",
"rc-trigger": "^5.0.4"
},
"peerDependencies": {
"react": "*",
"react-dom": "*"
}
},
"node_modules/rc-field-form": {
@@ -13727,10 +13672,6 @@
},
"engines": {
"node": ">=8.x"
},
"peerDependencies": {
"react": ">= 16.9.0",
"react-dom": ">= 16.9.0"
}
},
"node_modules/rc-image": {
@@ -13742,10 +13683,6 @@
"classnames": "^2.2.6",
"rc-dialog": "~8.5.0",
"rc-util": "^5.0.6"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-input-number": {
@@ -13756,10 +13693,6 @@
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.5",
"rc-util": "^5.0.1"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-mentions": {
@@ -13773,10 +13706,6 @@
"rc-textarea": "^0.3.0",
"rc-trigger": "^5.0.4",
"rc-util": "^5.0.1"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-menu": {
@@ -13792,10 +13721,6 @@
"rc-util": "^5.7.0",
"resize-observer-polyfill": "^1.5.0",
"shallowequal": "^1.1.0"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-motion": {
@@ -13806,10 +13731,6 @@
"@babel/runtime": "^7.11.1",
"classnames": "^2.2.1",
"rc-util": "^5.2.1"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-notification": {
@@ -13824,10 +13745,6 @@
},
"engines": {
"node": ">=8.x"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-overflow": {
@@ -13839,10 +13756,6 @@
"classnames": "^2.2.1",
"rc-resize-observer": "^1.0.0",
"rc-util": "^5.5.1"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-pagination": {
@@ -13852,10 +13765,6 @@
"dependencies": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.1"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-picker": {
@@ -13873,11 +13782,6 @@
},
"engines": {
"node": ">=8.x"
},
"peerDependencies": {
"dayjs": "^1.8.30",
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-progress": {
@@ -13887,10 +13791,6 @@
"dependencies": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.6"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-rate": {
@@ -13904,10 +13804,6 @@
},
"engines": {
"node": ">=8.x"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-resize-observer": {
@@ -13919,10 +13815,6 @@
"classnames": "^2.2.1",
"rc-util": "^5.0.0",
"resize-observer-polyfill": "^1.5.1"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-select": {
@@ -13940,10 +13832,6 @@
},
"engines": {
"node": ">=8.x"
},
"peerDependencies": {
"react": "*",
"react-dom": "*"
}
},
"node_modules/rc-slider": {
@@ -13959,10 +13847,6 @@
},
"engines": {
"node": ">=8.x"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-steps": {
@@ -13976,10 +13860,6 @@
},
"engines": {
"node": ">=8.x"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-switch": {
@@ -13990,10 +13870,6 @@
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.1",
"rc-util": "^5.0.1"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-table": {
@@ -14009,10 +13885,6 @@
},
"engines": {
"node": ">=8.x"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-tabs": {
@@ -14029,10 +13901,6 @@
},
"engines": {
"node": ">=8.x"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-textarea": {
@@ -14044,10 +13912,6 @@
"classnames": "^2.2.1",
"rc-resize-observer": "^1.0.0",
"rc-util": "^5.7.0"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-tooltip": {
@@ -14057,10 +13921,6 @@
"dependencies": {
"@babel/runtime": "^7.11.2",
"rc-trigger": "^5.0.0"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-tree": {
@@ -14076,10 +13936,6 @@
},
"engines": {
"node": ">=8.x"
},
"peerDependencies": {
"react": "*",
"react-dom": "*"
}
},
"node_modules/rc-tree-select": {
@@ -14092,10 +13948,6 @@
"rc-select": "^12.0.0",
"rc-tree": "^4.0.0",
"rc-util": "^5.0.5"
},
"peerDependencies": {
"react": "*",
"react-dom": "*"
}
},
"node_modules/rc-trigger": {
@@ -14111,10 +13963,6 @@
},
"engines": {
"node": ">=8.x"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-upload": {
@@ -14125,10 +13973,6 @@
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.5",
"rc-util": "^5.2.0"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-util": {
@@ -14139,10 +13983,6 @@
"@babel/runtime": "^7.12.5",
"react-is": "^16.12.0",
"shallowequal": "^1.1.0"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/rc-util/node_modules/react-is": {
@@ -14161,10 +14001,6 @@
},
"engines": {
"node": ">=8.x"
},
"peerDependencies": {
"react": "*",
"react-dom": "*"
}
},
"node_modules/react": {
@@ -14485,7 +14321,6 @@
"eslint-webpack-plugin": "^2.5.2",
"file-loader": "6.1.1",
"fs-extra": "^9.0.1",
"fsevents": "^2.1.3",
"html-webpack-plugin": "4.5.0",
"identity-obj-proxy": "3.0.0",
"jest": "26.6.0",
@@ -17652,10 +17487,8 @@
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
"integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==",
"dependencies": {
"chokidar": "^3.4.1",
"graceful-fs": "^4.1.2",
"neo-async": "^2.5.0",
"watchpack-chokidar2": "^2.0.1"
"neo-async": "^2.5.0"
},
"optionalDependencies": {
"chokidar": "^3.4.1",
@@ -18151,7 +17984,6 @@
"anymatch": "^2.0.0",
"async-each": "^1.0.1",
"braces": "^2.3.2",
"fsevents": "^1.2.7",
"glob-parent": "^3.1.0",
"inherits": "^2.0.3",
"is-binary-path": "^1.0.0",
@@ -24165,12 +23997,6 @@
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.19.0.tgz",
"integrity": "sha512-X3bf2iTPgCAQp9wvjOQytnf5vO5rESYRXlPIVcgSbtT5OTScPcsf9eZU+B/YIkKAtYr5WeCii58BgATrNitlWg=="
},
"dayjs": {
"version": "1.10.4",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.4.tgz",
"integrity": "sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw==",
"peer": true
},
"debug": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",

View File

@@ -1,20 +1,9 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
:root {
--color-primary: #282c34;
}
.App-header {
background-color: #282c34;
background-color: var(--color-primary);
min-height: 100vh;
display: flex;
flex-direction: column;
@@ -43,6 +32,7 @@
.photo-wall {
display: flex;
justify-content: center;
flex-wrap: wrap;
margin: 2rem;
}
@@ -60,10 +50,88 @@
}
.loading-bar-container {
background: #282c34;
background: var(--color-primary);
width: 100%;
height: 30px;
min-height: 30px;
}
.loading-bar {
background: green;
transition: all 0.5s linear;
background: #66ff66;
height: 100%;
}
.page-head {
background: var(--color-primary);
color: white !important;
margin-top: 0;
padding: 1rem;
}
.session-toolbar button {
margin: 0 0.5rem;
padding: 0.5rem 1rem;
height: 100%;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 0.05rem;
}
.ant-modal-content {
border-radius: 1rem;
padding: 0 !important;
}
.ant-modal-body img {
border-radius: 0.5rem;
}
.ant-modal-close {
font-weight: bold;
}
.ant-card {
border: 1px solid var(--color-primary);
border-radius: 0.2rem;
}
.ant-card-head {
background: var(--color-primary);
color: white;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 0.2rem;
}
.session-toolbar {
justify-content: center;
width: 60%;
margin: 1rem auto;
}
.session-toolbar h3 {
font-weight: bold;
color: white;
margin-right: 1rem;
}
.slider {
width: 400px;
margin: auto 1rem;
}
.toolbar {
padding: 0.5rem;
background: var(--color-primary);
}
.client-info {
justify-content: center;
width: 60%;
margin: 1rem auto;
}
.client-info span {
margin: auto 1rem;
}

View File

@@ -1,4 +1,4 @@
import { Client } from '../types'
import { Client, Timings } from '../types'
import axios from 'axios'
import { message } from 'antd'
import { Status } from '../components/StatusChip'
@@ -6,7 +6,7 @@ import { Status } from '../components/StatusChip'
const dev = process.env.NODE_ENV === 'development'
if (dev) {
const host = 'http://192.168.1.107:5000'
const host = 'http://192.168.1.114:5000'
axios.defaults.baseURL = host
}
@@ -29,9 +29,9 @@ export const getClient = async (id: string): Promise<Client> => {
const res = await axios.get<Client>(`/api/clients/${id}`)
return res.data
}
export const startSession = async (clientId: string) => {
export const startSession = async (clientId: string, timings: Timings) => {
try {
const res = await axios.post(`/api/clients/${clientId}/session`)
const res = await axios.post(`/api/clients/${clientId}/session`, timings)
return res.data
} catch (err) {
message.error('Something went wrong, check connection with the machine')
@@ -50,9 +50,9 @@ export const killSession = async (clientId: string) => {
await axios.delete(`/api/clients/${clientId}/session`)
}
export const restartSession = async (clientId: string) => {
export const restartSession = async (clientId: string, timings: Timings) => {
await killSession(clientId)
await startSession(clientId)
await startSession(clientId, timings)
}
// TOOD: Get status

View File

@@ -0,0 +1,23 @@
import { Button } from 'antd'
import React from 'react'
export const ScrollToTop = () => {
const handleClick = () => {
window.scrollTo(0, 0)
console.log('')
}
return (
<Button
type="link"
style={{
position: 'fixed',
right: 20,
bottom: 20,
}}
onClick={handleClick}
>
Scroll To Top
</Button>
)
}

View File

@@ -1,6 +1,7 @@
import React, { useEffect, useState } from 'react'
import { Card, message, Modal, PageHeader, Spin } from 'antd'
import { Card, Modal, Row, Select, Typography } from 'antd'
import { getSession } from '../api'
import { ScrollToTop } from './ScrollToTop'
type Props = {
clientId: string
@@ -9,7 +10,9 @@ type Props = {
export const SessionPictures = ({ clientId }: Props) => {
const [urls, setUrls] = useState<string[] | null>(null)
const [activeUrl, setActiveUrl] = useState<string | null>(null)
const [loading, setLoading] = useState(true)
const [focusPhotos, setFocusPhotos] = useState<string[]>(
JSON.parse(window.localStorage.getItem('focusPhotos') || '[]'),
)
useEffect(() => {
const get = async () => {
@@ -33,12 +36,29 @@ export const SessionPictures = ({ clientId }: Props) => {
if (!urls?.length) return null
const photos = urls.sort((a, b) =>
a.split('_')[0].localeCompare(b.split('_')[0]),
)
const u = urls.length / 89
const handleSelect = (v: string[]) => {
console.log('SEelcted', v)
window.localStorage.setItem('focusPhotos', JSON.stringify(v))
setFocusPhotos(v)
}
const filteredPhotos = photos.filter((name) => {
const num = name.split('_')[0]
return focusPhotos.includes(num)
})
return (
<>
<Modal
visible={!!activeUrl}
onOk={closeModal}
cancelText={null}
footer={null}
onCancel={closeModal}
width="50%"
>
@@ -49,31 +69,63 @@ export const SessionPictures = ({ clientId }: Props) => {
alt="large modal"
></img>
</Modal>
<PageHeader
title="Session Pictures"
subTitle={`${urls.length}/${89 * 1} loaded`}
<Row
align="middle"
justify="space-around"
style={{ display: 'flex', width: '100%' }}
>
<div className="loading-bar-container">
<div className="loading-bar"></div>
</div>
</PageHeader>
<div className="photo-wall">
{urls ? (
urls
.sort((a, b) => a.split('_')[0].localeCompare(b.split('_')[0]))
.map((src) => (
<Card key={src} className="photo" title={src.split('_')[0]}>
<img
onClick={() => setActiveUrl(src)}
src={`${host}/output/${clientId}/${src}`}
alt="lol"
/>
</Card>
))
) : (
<Spin />
)}
<Typography.Title style={{ margin: '0.5rem 1rem 0.7rem' }} level={3}>
Session Pictures
</Typography.Title>
<Typography.Text>{urls.length}/ 89 loaded</Typography.Text>
<Typography.Text>Select Featured Photos:</Typography.Text>
<Select
mode="multiple"
allowClear
placeholder="Please select featured"
style={{ width: '35%' }}
defaultValue={focusPhotos}
value={focusPhotos}
onChange={handleSelect}
>
{photos.map((name) => {
const val = name.split('_')[0]
return <Select.Option value={val}>{val}</Select.Option>
})}
</Select>
</Row>
<div className="loading-bar-container">
<div
className="loading-bar"
style={{
width: `${u * 100}%`,
background: `hsl(${Math.floor(u * 120)}, 90%, 70%)`,
}}
></div>
</div>
<div className="featured-photos" style={{ marginTop: '2rem' }}>
{filteredPhotos.map((src) => (
<img
onClick={() => setActiveUrl(src)}
src={`${host}/output/${clientId}/${src}`}
alt="lol"
/>
))}
</div>
<div className="photo-wall">
{photos.map((src) => (
<Card key={src} className="photo" title={src.split('_')[0]}>
<img
onClick={() => setActiveUrl(src)}
src={`${host}/output/${clientId}/${src}`}
alt="lol"
/>
</Card>
))}
</div>
<ScrollToTop />
</>
)
}

View File

@@ -37,7 +37,7 @@ export const StatusChip = ({ poll }: Props) => {
const interval = setInterval(get, 1000 / 4)
return () => clearInterval(interval)
}, [])
}, [poll])
return (
<Tag color={colors[status]} style={{ display: 'flex' }}>

View File

@@ -1,19 +1,27 @@
import { Button, Divider, Form, Input, message, PageHeader, Row } from 'antd'
import React from 'react'
import { Button, Divider, Form, Input, message, Row, Typography } from 'antd'
import FormItem from 'antd/lib/form/FormItem'
import { Store } from 'antd/lib/form/interface'
import { Content } from 'antd/lib/layout/layout'
import React, { FormEvent } from 'react'
import { useState } from 'react'
import { useHistory } from 'react-router-dom'
import { createClient } from '../api'
type FormData = {
name: string
email: string
phone: string
}
export const Dashboard = () => {
const history = useHistory()
const [error, setError] = useState<string | null>(null)
const [form] = Form.useForm<FormData>()
const handleReset = () => {}
const handleReset = () => {
form.resetFields()
}
const handleSubmit = async (values: Store) => {
const handleSubmit = async (values: FormData) => {
if (values.phone.length < 10) {
// helpful message
message.error('Check all fields!')
@@ -32,17 +40,20 @@ export const Dashboard = () => {
return (
<Content>
<PageHeader
title="Dashboard"
subTitle="Enter the name, email and phone number of the subject"
></PageHeader>
<Typography.Title className="page-head" level={3}>
Dashboard
</Typography.Title>
<Divider />
<Form
form={form}
className="dashboard-form"
onFinish={handleSubmit}
labelCol={{ span: 8 }}
wrapperCol={{ span: 16 }}
>
<Typography.Paragraph style={{ textAlign: 'center' }}>
Enter the name, email and phone number of the subject
</Typography.Paragraph>
<FormItem label="name" name="name">
<Input minLength={3} />
</FormItem>

View File

@@ -4,7 +4,15 @@ import { getClient, killSession, restartSession, startSession } from '../api'
import { SessionPictures } from '../components/SessionPictures'
import { StatusChip } from '../components/StatusChip'
import { Button, Divider, message, Popconfirm, Row, Typography } from 'antd'
import {
Button,
Input,
InputNumber,
message,
Popconfirm,
Row,
Typography,
} from 'antd'
import { Content } from 'antd/lib/layout/layout'
import { Client } from '../types'
@@ -15,10 +23,18 @@ export const Session = (props: Props) => {
const { clientId } = props.match.params
const [client, setClient] = useState<Client | null>(null)
const [active, setActive] = useState(false)
const [lightTime, setLightTime] = useState(
parseInt(window.localStorage.getItem('lightTime') || '5000'),
)
const handleTimingUpdate = (n: number) => {
window.localStorage.setItem('lightTime', n.toString())
setLightTime(n)
}
const handleStartSession = async () => {
message.loading('Photo sequence starting! Stand by...')
await startSession(clientId)
await startSession(clientId, { light_time: lightTime })
setActive(true)
}
@@ -27,7 +43,7 @@ export const Session = (props: Props) => {
message.loading(
'Deleting photos & restarting capture sequence! Stand by...',
)
await restartSession(clientId)
await restartSession(clientId, { light_time: lightTime })
setActive(true)
}
@@ -53,62 +69,71 @@ export const Session = (props: Props) => {
return (
<Content>
<Row justify="center">
<Typography.Title>Client: {client?.name}</Typography.Title>
</Row>
<Typography.Title className="page-head" level={3}>
Session View
</Typography.Title>
<Row justify="space-around" style={{ width: '60%', margin: 'auto' }}>
<Row className="client-info">
<Typography.Text>
<strong>email:</strong> {client?.email}
<strong>Name:</strong> {client?.name}
</Typography.Text>
<Typography.Text>
<strong>phone:</strong> {client?.phone}
<strong>Email:</strong> {client?.email}
</Typography.Text>
<Typography.Text>
<strong>Phone:</strong> {client?.phone}
</Typography.Text>
</Row>
<Divider />
<Row justify="center" className="session-header">
<Button
key="startsession"
disabled={active}
type="primary"
onClick={handleStartSession}
>
Capture
</Button>
<Popconfirm
disabled={!active}
key="retry"
title="Re-capture set?"
onConfirm={handleRestartSession}
>
<Button type="default" disabled={!active}>
Retry Capture
<div className="toolbar">
<Row justify="center" className="session-toolbar">
<Button key="finish" onClick={handleExit}>
Back To Dashboard
</Button>
</Popconfirm>
<Popconfirm
key="nuke"
disabled={!active}
title="Delete all photos and return to dashboard?"
onConfirm={handleNuke}
>
<Button danger disabled={!active}>
Abort Session
<Button
key="startsession"
disabled={active}
type="primary"
onClick={handleStartSession}
>
Capture
</Button>
</Popconfirm>
<Button
key="finish"
ghost
type="primary"
disabled={!active}
onClick={handleExit}
>
Finish Session
</Button>
<StatusChip poll={true} />
</Row>
<Popconfirm
disabled={!active}
key="retry"
title="Re-capture set?"
onConfirm={handleRestartSession}
>
<Button type="default" disabled={!active}>
Retry Capture
</Button>
</Popconfirm>
<Popconfirm
key="nuke"
disabled={!active}
title="Delete all photos and return to dashboard?"
onConfirm={handleNuke}
>
<Button danger disabled={!active}>
Abort Session
</Button>
</Popconfirm>
<Divider />
<StatusChip poll={true} />
</Row>
<Row className="session-toolbar">
<h3>Light Duration (ms)</h3>
<InputNumber value={lightTime} onChange={handleTimingUpdate} />
<Input
className="slider"
type="range"
onChange={(e) => handleTimingUpdate(parseInt(e.target.value))}
value={lightTime}
min={500}
max={10000}
step={500}
/>
</Row>
</div>
<Row className="controls">
{active && <SessionPictures clientId={clientId} />}
</Row>

View File

@@ -8,3 +8,7 @@ export type Client = {
export type Session = {
timestamp: number
}
export type Timings = {
light_time: number // 5000
}

View File

@@ -1364,7 +1364,6 @@
"jest-resolve" "^26.6.2"
"jest-util" "^26.6.2"
"jest-worker" "^26.6.2"
"node-notifier" "^8.0.0"
"slash" "^3.0.0"
"source-map" "^0.6.0"
"string-length" "^4.0.1"
@@ -3385,7 +3384,6 @@
"anymatch" "^2.0.0"
"async-each" "^1.0.1"
"braces" "^2.3.2"
"fsevents" "^1.2.7"
"glob-parent" "^3.1.0"
"inherits" "^2.0.3"
"is-binary-path" "^1.0.0"
@@ -4140,11 +4138,6 @@
"resolved" "https://registry.npmjs.org/date-fns/-/date-fns-2.19.0.tgz"
"version" "2.19.0"
"dayjs@^1.8.30":
"integrity" "sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw=="
"resolved" "https://registry.npmjs.org/dayjs/-/dayjs-1.10.4.tgz"
"version" "1.10.4"
"debug@^2.2.0":
"integrity" "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="
"resolved" "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
@@ -6667,7 +6660,6 @@
"@types/node" "*"
"anymatch" "^3.0.3"
"fb-watchman" "^2.0.0"
"fsevents" "^2.1.2"
"graceful-fs" "^4.2.4"
"jest-regex-util" "^26.0.0"
"jest-serializer" "^26.6.2"
@@ -9757,7 +9749,7 @@
"strip-ansi" "6.0.0"
"text-table" "0.2.0"
"react-dom@*", "react-dom@^17.0.1", "react-dom@>= 16.9.0", "react-dom@>=16.9.0":
"react-dom@^17.0.1":
"integrity" "sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug=="
"resolved" "https://registry.npmjs.org/react-dom/-/react-dom-17.0.1.tgz"
"version" "17.0.1"
@@ -9863,7 +9855,6 @@
"eslint-webpack-plugin" "^2.5.2"
"file-loader" "6.1.1"
"fs-extra" "^9.0.1"
"fsevents" "^2.1.3"
"html-webpack-plugin" "4.5.0"
"identity-obj-proxy" "3.0.0"
"jest" "26.6.0"
@@ -9897,7 +9888,7 @@
optionalDependencies:
"fsevents" "^2.1.3"
"react@*", "react@^17.0.1", "react@>= 16.9.0", "react@>=16.0.0", "react@>=16.9.0":
"react@^17.0.1":
"integrity" "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w=="
"resolved" "https://registry.npmjs.org/react/-/react-17.0.1.tgz"
"version" "17.0.1"
@@ -12018,10 +12009,8 @@
"resolved" "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz"
"version" "1.7.5"
dependencies:
"chokidar" "^3.4.1"
"graceful-fs" "^4.1.2"
"neo-async" "^2.5.0"
"watchpack-chokidar2" "^2.0.1"
optionalDependencies:
"chokidar" "^3.4.1"
"watchpack-chokidar2" "^2.0.1"

BIN
network-settings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -28,3 +28,7 @@ def trigger_capture():
sock.sendto(SEND.encode('utf-8'), (MCAST_GRP, MCAST_PORT))
sock.close()
print('Sent.')
if __name__ == '__main__':
print('Triggering test capture...')
trigger_capture()

View File

@@ -5,16 +5,17 @@ import paramiko
import time
paramiko.util.log_to_file('paramiko.log')
def fake_download(dest):
def fake_download(ip, dest):
import requests, random
rnd = str(random.randint(1, 10000))
r = requests.get('https://picsum.photos/400/300?random=' + rnd)
with open(dest / (rnd + '.jpg'), 'wb') as f:
num = ip.split('.')[3]
r = requests.get('https://picsum.photos/400/300?random=' + num)
time.sleep(random.uniform(2, 10))
with open(dest / (num + '_420.jpg'), 'wb') as f:
f.write(r.content)
def download(ip, dest):
if settings.DEBUG:
fake_download(dest)
fake_download(ip, dest)
print('Downloading from', ip)

View File

@@ -1,18 +1,31 @@
import os
import json
import time
from datetime import datetime
from pathlib import Path
from flask import Flask, request, abort, send_from_directory
from flask_cors import CORS
import power, capture, download
import power, capture, download, settings
import logging
log = logging.getLogger('werkzeug')
if not settings.DEBUG:
log.setLevel(logging.ERROR)
build_folder = Path('../client/build')
output_folder = Path('./output')
app = Flask(__name__, static_folder=str(build_folder), static_url_path='')
CORS(app)
status = 'Standby'
STANDBY = 0
WARMUP = 1
CAPTURING_PHOTO = 2
CAPTURING_GRID = 3
WRITING = 4
DOWNLOADING = 5
status = STANDBY
@app.route('/api/status', methods=['GET'])
def status_get():
@@ -21,7 +34,6 @@ def status_get():
@app.route('/api/clients', methods=['POST'])
def clients_post():
content = request.json
print('Recieved:', content)
phone = str(content['phone'])
@@ -32,13 +44,17 @@ def clients_post():
if not path.exists():
break
content['date'] = datetime.now().strftime('%Y-%m-%d')
content['time'] = datetime.now().strftime('%H:%M:%S')
path.mkdir()
info_file = path / 'info.json'
info_file = path / 'info.txt'
info_file.touch()
info_file.write_text(json.dumps(content, indent=4))
client_id = folder
print('POST client:', content, 'cid:', client_id)
return {'client_id': client_id}
@app.route('/api/clients/<cid>', methods=['GET'])
@@ -49,12 +65,13 @@ def clients_get(cid):
if not path.exists():
abort(404)
info_file = path / 'info.json'
info_file = path / 'info.txt'
info_text = info_file.read_text()
res = json.loads(info_text)
photo_glob = path.glob('*.jpg')
res['has_photos'] = bool(list(photo_glob))
print('GET client:', cid, 'res:', res)
return res
@app.route('/api/clients/<cid>/session', methods=['GET'])
@@ -84,12 +101,17 @@ def session_delete(cid):
for p in photo_glob:
p.unlink()
print('DELETE session:', cid)
return ''
@app.route('/api/clients/<cid>/session', methods=['POST'])
def session_post(cid):
content = request.json
light_time = content.get('light_time', 5000)
global status
print('POST session:', cid)
folder = cid
path = output_folder / cid
@@ -97,14 +119,14 @@ def session_post(cid):
abort(404)
# go through the photo taking process
status = 'Warming up'
try:
# warmup
status = WARMUP
power.lights_on()
time.sleep(4)
time.sleep(2)
power.lights_off()
time.sleep(0.5)
time.sleep(1)
except BaseException as e:
print('Problem with lights: {} - {}'.format(e.__class__.__name__, str(e)))
print()
@@ -112,27 +134,23 @@ def session_post(cid):
print()
abort(500)
status = 'Capturing'
# capture
status = CAPTURING_PHOTO
power.lights_on()
time.sleep(0.25)
time.sleep(0.1)
capture.trigger_capture()
time.sleep(1)
power.grid_on()
time.sleep(0.25)
capture.trigger_capture()
time.sleep(1)
power.grid_off()
time.sleep(light_time / 1000)
power.lights_off()
status = 'Writing to files'
status = WRITING
time.sleep(max(5 - light_time / 1000, 1))
status = DOWNLOADING
download.download_all_photos(path)
time.sleep(3)
status = 'Downloading'
download.download_all_photos(path)
status = 'Standby'
status = STANDBY
print('Finished.')
return ''
@app.route('/')

View File

@@ -1,5 +1,36 @@
certifi==2020.12.5
chardet==4.0.0
idna==2.10
requests==2.25.1
urllib3==1.26.3
appdirs==1.4.3
bcrypt==3.2.0
CacheControl==0.12.6
certifi==2019.11.28
cffi==1.14.5
chardet==3.0.4
click==7.1.2
colorama==0.4.3
contextlib2==0.6.0
cryptography==3.4.6
distlib==0.3.0
distro==1.4.0
Flask==1.1.2
Flask-Cors==3.0.10
html5lib==1.0.1
idna==2.8
ipaddr==2.2.0
itsdangerous==1.1.0
Jinja2==2.11.3
lockfile==0.12.2
MarkupSafe==1.1.1
msgpack==0.6.2
packaging==20.3
paramiko==2.7.2
pep517==0.8.2
progress==1.5
pycparser==2.20
PyNaCl==1.4.0
pyparsing==2.4.6
pytoml==0.1.21
requests==2.22.0
retrying==1.3.3
six==1.14.0
urllib3==1.25.8
webencodings==0.5.1
Werkzeug==1.0.1