diff --git a/wled00/data/index.css b/wled00/data/index.css new file mode 100644 index 000000000..606d69709 --- /dev/null +++ b/wled00/data/index.css @@ -0,0 +1,937 @@ +@font-face { + font-family: "WIcons"; + src: url(data:application/x-font-woff;charset=utf-8;base64,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) format('woff'); +} + +:root { + --c-1: #111; + --c-f: #fff; + --c-2: #222; + --c-3: #333; + --c-4: #444; + --c-5: #555; + --c-6: #666; + --c-8: #888; + --c-b: #bbb; + --c-c: #ccc; + --c-e: #eee; + --c-d: #ddd; + --c-r: #831; + --t-b: 0.5; + --c-o: rgba(34, 34, 34, 0.9); + --c-tb : rgba(34, 34, 34, var(--t-b)); + --c-tba: rgba(102, 102, 102, var(--t-b)); + --c-tbh: rgba(51, 51, 51, var(--t-b)); + /*following are internal*/ + --th: 70px; + --tp: 70px; + --bh: 63px; + --tbp: 14px 14px 10px 14px; + --bbp: 9px 0 7px 0; + --bhd: none; + --bmt: 0px; +} + +html { + touch-action: manipulation; +} + +body { + margin: 0; + background-color: var(--c-1); + font-family: Helvetica, Verdana, sans-serif; + font-size: 17px; + color: var(--c-f); + text-align: center; + -webkit-touch-callout: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-tap-highlight-color: transparent; + scrollbar-width: 6px; + scrollbar-color: var(--c-sb) transparent; +} + +html, +body { + height: 100%; + width: 100%; + position: fixed; + overscroll-behavior: none; +} + +#bg { + height: 100vh; + width: 100vw; + position: fixed; + z-index: -10; + background-position: center; + background-repeat: no-repeat; + background-size: cover; + opacity: 0; + transition: opacity 2s; +} + +p { + margin: 10px 0 2px 0; + color: var(--c-d); +} + +button { + outline: none; + cursor: pointer; +} + +.labels { + margin: 0; + padding: 8px 0 2px 0; +} + +#namelabel { + position: fixed; + bottom: calc(var(--bh) + 5px); + right: 4px; + color: var(--c-6); + writing-mode: vertical-rl; +} + +.bri { + padding: 4px; +} + +.wrapper { + position: fixed; + top: 0; + left: 0; + right: 0; + background: var(--c-tb); + z-index: 1; +} + +.icons { + font-family: 'WIcons'; + font-style: normal; + font-size: 24px; + line-height: 1; + display: inline-block; + margin: -2px 0 4px 0; +} + +.huge { + font-size: 42px; +} + +.infot { + table-layout: fixed; + width: 100%; +} + +.segt { + table-layout: fixed; + width: 76%; +} + +.segtd { + text-align: center; + text-transform: uppercase; + font-size: 14px; +} + +.keytd { + text-align: left; + padding-bottom: 8px; +} + +.valtd { + text-align: right; + padding-bottom: 8px; +} + +.slider-icon +{ + transform: translate(6px,3px); + color: var(--c-d); +} + +.e-icon +{ + transform: translateY(3px); + color: var(--c-d); +} + +.sel-icon { + transform: translateX(3px); + color: var(--c-d); +} + +.flr { + float: right; + cursor: pointer; + margin: 0; + color: var(--c-f); + transform: rotate(0deg); + transition: transform 0.3s; +} + +.exp { + transform: rotate(180deg); +} + +.il { + display: inline-block; + vertical-align: middle; +} + +#liveview { + height: 4px; + display: none; + width: 100%; + border: 0px; +} + +.tab { + background-color: transparent; + color: var(--c-d); +} + +.bot { + position: fixed; + bottom: 0; + left: 0; + width: 100%; + background-color: var(--c-tb); +} + +.tab button { + background-color: transparent; + float: left; + border: none; + transition: color 0.3s, background-color 0.3s; + font-size: 17px; + color: var(--c-c); +} + +.top button { + padding: var(--tbp); +} + +.bot button { + padding: var(--bbp); + width:25%; +} + +.tab button:hover { + background-color: var(--c-tbh); + color: var(--c-e); +} + +.tab button.active { + background-color: var(--c-tba) !important; + color: var(--c-f); +} + +.active { + background-color: var(--c-6) !important; + color: var(--c-f); +} + +.container { + --n: 1; + width: 100%; + width: calc(var(--n)*100%); + height: calc(100% - var(--tp) - var(--bh)); + margin-top: var(--tp); + transform: translate(calc(var(--i, 0)/var(--n)*-100%)); + overscroll-behavior: none; +} + +.tabcontent { + float: left; + position: relative; + width: 100%; + width: calc(100%/var(--n)); + padding: 11px 0; + box-sizing: border-box; + border: 0px; + overflow: auto; + height: 100%; + overscroll-behavior: none; +} + +#Effects { + padding-top: 0; + margin-top: 11px; + height: calc(100% - 11px); + -webkit-overflow-scrolling: touch; +} + +.smooth { transition: transform calc(var(--f, 1)*.5s) ease-out } + +.tab-label { + margin: 0 0 -5px 0; + padding-bottom: 4px; +} + +.overlay { + position: fixed; + height: 100%; + width: 100%; + top: 0; + left: 0; + background-color: var(--c-3); + font-size: 24px; + display: flex; + align-items: center; + justify-content: center; + z-index: 11; + opacity: 0.95; + transition: 0.7s; + pointer-events: none; +} + +.staytop { + display: block; + position: -webkit-sticky; + position: sticky; + background: var(--c-1); + top: -1px; + z-index: 1; + margin-top: 1px; + width: 274px; + margin: auto; + border-radius: 25px; +} + +#staytop1 { + top: 28px; +} + +#staytop2 { + top: 56px; +} + +#fxb0 { + margin-bottom: 2px; + filter: drop-shadow(0 0 1px #000); +} + +.first { + margin-top: 18px !important; +} + +#toast { + opacity: 0; + background-color: var(--c-5); + max-width: 90%; + color: var(--c-f); + text-align: center; + border-radius: 5px; + padding: 16px; + position: fixed; + z-index: 5; + left: 50%; + transform: translateX(-50%); + bottom: calc(var(--bh) + 22px); + font-size: 17px; + pointer-events: none; +} + +#toast.show { + opacity: 1; + animation: fadein 0.5s, fadein 0.5s 2.5s reverse; +} + +#toast.error { + opacity: 1; + background-color: #b21; + animation: fadein 0.5s; +} + +.modal { + position:fixed; + left: 0px; + bottom: 0px; + right: 0px; + top: calc(var(--th) - 1px); + background-color: var(--c-o); + transform: translateY(100%); + transition: transform 0.4s; + padding: 8px; + font-size: 20px; + overflow: auto; +} + +#info { + z-index: 3; +} + +#rover { + z-index: 2; +} + +#roverstar { + position: fixed; + top: calc(var(--th) + 5px); + left: 1px; + display: none; + cursor: pointer; +} + +#connind { + position: fixed; + bottom: calc(var(--bh) + 5px); + left: 4px; + padding: 5px; + border-radius: 5px; + background-color: #a90; + z-index: -2; +} + +#imgw { + width: 200px; + height: 55px; + display: inline-block; +} + +#kv { + max-width: 490px; + display: inline-block; +} + +#lv { + max-width: 600px; + display: inline-block; +} + +#heart { + transition: color 0.9s; + font-size: 16px; + color: #f00; +} + +img { + max-width: 100%; + max-height: 100%; +} + +@keyframes fadein { + from {bottom: 0; opacity: 0;} + to {bottom: calc(var(--bh) + 22px); opacity: 1;} +} + +.sliderdisplay { + content:''; + position: absolute; + top: 13px; bottom: 13px; + left: 10px; right: 10px; + background: var(--c-4); + border-radius: 17px; + pointer-events: none; + z-index: -1; +} + +.sliderbubble { + width: 36px; + line-height: 24px; + background: var(--c-3); + position: absolute; + transform: translateX(-50%); + border-radius: 12px; + margin-left: 12px; + margin-top: 3px; + padding: 0px; + display: inline; +} + +.hidden { + display: none; +} + +input[type=range] { + -webkit-appearance: none; + width: 220px; + padding: 0px; + margin: 0px 10px 0px 10px; + background-color: transparent; + cursor: pointer; +} +input[type=range]:focus { + outline: none; +} +input[type=range]::-webkit-slider-runnable-track { + width: 100%; + height: 30px; + cursor: pointer; + background: transparent; +} +input[type=range]::-webkit-slider-thumb { + height: 16px; + width: 16px; + border-radius: 17px; + background: var(--c-f); + cursor: pointer; + -webkit-appearance: none; + margin-top: 7px; +} +input[type=range]::-moz-range-track { + width: 100%; + height: 30px; + background-color: rgba(0, 0, 0, 0); +} +input[type=range]::-moz-range-thumb { + border: 0px solid rgba(0, 0, 0, 0); + height: 16px; + width: 16px; + border-radius: 17px; + background: var(--c-f); + transform: translateY(7px); +} +input[type=range]:active + .sliderbubble { + display: inline; + transform: translateX(-50%); +} + +#wwrap { + display: none; +} + +.sliderwrap { + height: 30px; + width: 240px; + position: relative; +} + +.sws { + width: 212px; +} + +.sis { + width: 192px !important; +} + +.hd { + display: var(--bhd); +} + +#briwrap { + float: right; + margin-top: var(--bmt); +} + +#picker { + margin: 10px auto; + width: 260px; +} + +#rgbwrap { + display: none; +} + +.btn { + padding: 8px; + margin: 10px; + width: 230px; + font-size: 19px; + background-color: var(--c-3); + color: var(--c-f); + border: 0px solid white; + border-radius: 25px; + transition-duration: 0.5s; + -webkit-backface-visibility: hidden; + -webkit-transform:translate3d(0,0,0); +} + +.btn-s { + padding: 9px; + width: 276px; + background-color: var(--c-2); +} +.btn-i { + padding-bottom: 3px; +} +.btn-icon { + margin: 0px 8px 4px 0; + vertical-align: middle; +} +.btna-icon { + margin: 0px; +} +.btn-p { + width: 216px; +} + +#qcs-w { + margin-top: 10px; +} +.qcs { + padding: 14px; + margin: 2px; + border-radius: 14px; + display: inline-block; +} +.qcsb { + padding: 13px; + border: 1px solid var(--c-f); +} +#hexw { + margin-top: 5px; + display: none; +} + +.cl { + width: 42px; +} + +select { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background: url("data:image/svg+xml;utf8,") no-repeat; + background-size: 12px; + background-position: 206px 16px; + padding-left: 12px !important; + background-repeat: no-repeat; + outline: none; +} +select:-moz-focusring { + transition-duration: 0s; + color: transparent; + text-shadow: 0 0 0 #fff; +} +option { + background-color: var(--c-3); + color: var(--c-f); +} + +input[type=number], input[type=text] { + background: var(--c-3); + color: var(--c-f); + border: 0px solid white; + border-radius: 5px; + padding: 8px; + margin: 6px 6px 6px 0; + font-size: 19px; + transition: background-color 0.2s; + outline: none; + width: 50px; + -webkit-appearance: textfield; + -moz-appearance: textfield; + appearance: textfield; +} + +textarea { + background: var(--c-2); + color: var(--c-f); + width: 236px; + height: 90px; + border-radius: 5px; + border: 2px solid #555; + outline: none; + resize: none; + font-size: 19px; +} + +::selection { + background: var(--c-b); +} + +input[type=text] { + width: 100px; + border-radius: 25px; + text-align: center; +} + +.ptxt { + width: 200px !important; + margin: 26px 0 6px 12px !important; +} + +.stxt { + width: 50px !important; +} + +input[type=number]:focus, input[type=text]:focus { + background: var(--c-6); +} + +input[type=number]::-webkit-inner-spin-button, +input[type=number]::-webkit-outer-spin-button { + -webkit-appearance: none; +} + +.segn { + margin: 3px 0 6px 0 !important; +} + +.segname { + position: absolute; + top: 0px; + left: 50%; + padding: 9px 0; + transform: translateX(-50%); + white-space: nowrap; + cursor: pointer; +} + +.pname { + width: 208px; + padding: 8px 0; + text-align: center; + overflow: hidden; + text-overflow: clip; +} + +.pid { + position: absolute; + top: 0px; + left: 0px; + padding: 11px 0px 0px 11px; + font-size: 16px; + width: 20px; + text-align: center; + color: var(--c-b); +} + +.newseg { + cursor: default; +} + +.ic { + padding: 6px 0 0 0; +} + +.xxs { + width: 40px; + margin: 6px; +} + +.psts { + background-color: var(--c-3); + color: var(--c-f); + cursor: pointer; + padding: 2px 0 0 0; + height: 40px; +} + +.cnf { + color: var(--c-f); + cursor: pointer; + background: var(--c-3); + border-radius: 5px; +} + +.cnf-s { + position: absolute; + top: 66px; + right: 28px; + padding: 43px 6px; +} + +.pwr { + color: var(--c-6); + transform: translate(2px, 3px); + cursor: pointer; +} + +.act { + color: var(--c-f); +} + +.half { + padding: 7.5px; + top: 64px; +} + +.del { + position: absolute; + bottom: 8px; + right: 8px; + color: var(--c-f); + cursor: pointer; +} + +.check { + display: inline-block; + position: relative; + padding-bottom: 32px; + margin-bottom: 14px; + cursor: pointer; + text-align: center; +} + +.schkl { + padding: 2px 22px 0px 35px; + margin: 0 0 0 2px; +} + +.revchkl { + padding: 2px 0px 0px 35px; + margin-bottom: 0px; + margin-top: 8px; +} + +.check input { + position: absolute; + opacity: 0; + cursor: pointer; + height: 0; + width: 0; +} + +.checkmark { + position: absolute; + bottom: 0; + left: 0; + height: 25px; + width: 25px; + background-color: var(--c-3); + border-radius: 10px; +} + +.schk { + top: 0; +} + +.psv { + left: initial; + bottom: initial; + top: 0; + right: 0; +} + +.psvl { + padding: 2px 35px 10px 0px; + margin-top: 10px; + margin-bottom: 0px; +} + + +.check:hover input ~ .checkmark { + background-color: var(--c-4); +} + +.check input:checked ~ .checkmark { + background-color: var(--c-6); +} + +.checkmark:after { + content: ""; + position: absolute; + display: none; +} + +.check input:checked ~ .checkmark:after { + display: block; +} + +.check .checkmark:after { + left: 9px; + top: 5px; + width: 5px; + height: 10px; + border: solid var(--c-f); + border-width: 0 3px 3px 0; + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); +} + +.h { + font-size: 13px; + text-align: center; + color: var(--c-b); +} + +.bp { + margin-bottom: 5px; +} + +.seg { + position: relative; + display: inline-block; + padding: 8px; + margin: 10px; + width: 260px; + font-size: 19px; + background-color: var(--c-2); + color: var(--c-f); + border: 0px solid white; + border-radius: 20px; + text-align: left; + transition: background-color 0.5s; + filter: brightness(1); +} + +.pres { + margin-bottom: 6px; +} + +.segin { + padding: 8px 8px 4px 8px; + display: none; +} + +.expanded { + display: block; +} + +.c { + text-align: center; +} + +.po2 { + display: none; + margin-top: 8px; +} + +.pwarn { + color: red; +} + +::-webkit-scrollbar { + width: 6px; +} +::-webkit-scrollbar-track { + background: transparent; +} +::-webkit-scrollbar-thumb { + background: var(--c-sb); + opacity: 0.2; + border-radius: 5px; +} +::-webkit-scrollbar-thumb:hover { + background: var(--c-sbh); +} + +@media all and (max-width: 335px) { + .sliderbubble { + display: none; + } +} + +@media all and (max-width: 550px) and (min-width: 374px) { + .infobtn { + width: 155px; + } +} + +@media all and (max-width: 685px) { + .top button { + width: 16.6%; + padding: 8px 0 4px 0; + } + .hd { + display: none !important; + } + #briwrap { + margin-top: 0px !important; + float: none; + } +} + +@media all and (max-width: 1249px) { + #buttonPcm { + display: none; + } +} \ No newline at end of file diff --git a/wled00/data/index.htm b/wled00/data/index.htm index 3885d46fa..cbfb5d42d 100644 --- a/wled00/data/index.htm +++ b/wled00/data/index.htm @@ -8,945 +8,7 @@ WLED - + @@ -1130,1436 +192,8 @@ input[type=number]::-webkit-outer-spin-button { For best performance, it is recommended to turn off the streaming source when not in use.
- + + + \ No newline at end of file diff --git a/wled00/data/index.js b/wled00/data/index.js new file mode 100644 index 000000000..fd44ecba7 --- /dev/null +++ b/wled00/data/index.js @@ -0,0 +1,1418 @@ +//page js +var loc = false, locip; +var ps = false, noNewSegs = false; +var isOn = false, nlA = false, isLv = false, isInfo = false, syncSend = false, syncTglRecv = true, isRgbw = false; +var whites = [0,0,0]; +var expanded = [false]; +var powered = [true]; +var nlDur = 60, nlTar = 0; +var nlFade = false; +var selectedFx = 0; +var csel = 0; +var currentPreset = -1; +var lastUpdate = 0; +var segCount = 0, ledCount = 0, lowestUnused = 0, maxSeg = 0, lSeg = 0; +var pcMode = false, pcModeA = false, lastw = 0; +var d = document; +const ranges = RangeTouch.setup('input[type="range"]', {}); +var pJson = {}; +var pO = null, pN = "", pI = 0; +var pmt = 1, pmtLS = 0, pmtLast = 0; +var lastinfo = {}; +var cfg = { + theme:{base:"dark", bg:{url:""}, alpha:{bg:0.6,tab:0.8}, color:{bg:""}}, + comp :{colors:{picker: true, rgb: false, quick: true, hex: false}, labels:true, pcmbot:false, pid:true} +}; + +var cpick = new iro.ColorPicker("#picker", { + width: 260, + wheelLightness: false, + wheelAngle: 90, + layout: [ + { + component: iro.ui.Wheel, + options: {} + }, + { + component: iro.ui.Slider, + options: { + sliderType: 'value' + } + }, + { + component: iro.ui.Slider, + options: { + sliderType: 'kelvin', + minTemperature: 2100, + maxTemperature: 10000 + } + } + ] +}); + +function handleVisibilityChange() { + if (!document.hidden && new Date () - lastUpdate > 3000) { + requestJson(null); + } +} + +function sCol(na, col) { + d.documentElement.style.setProperty(na, col); +} + +function applyCfg() +{ + cTheme(cfg.theme.base === "light"); + var bg = cfg.theme.color.bg; + if (bg) sCol('--c-1', bg); + var ccfg = cfg.comp.colors; + d.getElementById('hexw').style.display = ccfg.hex ? "block":"none"; + d.getElementById('picker').style.display = ccfg.picker ? "block":"none"; + d.getElementById('rgbwrap').style.display = ccfg.rgb ? "block":"none"; + d.getElementById('qcs-w').style.display = ccfg.quick ? "block":"none"; + var l = cfg.comp.labels; + var e = d.querySelectorAll('.tab-label'); + for(var i=0; i 23 && today.getDate() < 28)) img.src = "https://aircoookie.github.io/xmas.png"; + } + img.addEventListener('load', (event) => { + var a = parseFloat(cfg.theme.alpha.bg); + d.getElementById('staytop2').style.background = "transparent"; + if (isNaN(a)) a = 0.6; + bg.style.opacity = a; + bg.style.backgroundImage = `url(${img.src})`; + img = null; + }); +} + +function onLoad() { + if (window.location.protocol == "file:") { + loc = true; + locip = localStorage.getItem('locIp'); + if (!locip) + { + locip = prompt("File Mode. Please enter WLED IP!"); + localStorage.setItem('locIp', locip); + } + } + var sett = localStorage.getItem('wledUiCfg'); + if (sett) cfg = mergeDeep(cfg, JSON.parse(sett)); + + resetPUtil(); + + applyCfg(); + loadBg(cfg.theme.bg.url); + + var cd = d.getElementById('csl').children; + for (i = 0; i < cd.length; i++) { + cd[i].style.backgroundColor = "rgb(0, 0, 0)"; + } + selectSlot(0); + updateTablinks(0); + resetUtil(); + cpick.on("input:end", function() { + setColor(1); + }); + pmtLS = localStorage.getItem('wledPmt'); + setTimeout(function(){requestJson(null, false)}, 25); + d.addEventListener("visibilitychange", handleVisibilityChange, false); + size(); + d.getElementById("cv").style.opacity=0; + if (localStorage.getItem('pcm') == "true") togglePcMode(true); + var sls = d.querySelectorAll('input[type="range"]'); + for (var sl of sls) { + sl.addEventListener('input', updateBubble, true); + sl.addEventListener('touchstart', toggleBubble); + sl.addEventListener('touchend', toggleBubble); + } + +} + +function updateTablinks(tabI) +{ + tablinks = d.getElementsByClassName("tablinks"); + for (i = 0; i < tablinks.length; i++) { + tablinks[i].className = tablinks[i].className.replace(" active", ""); + } + if (pcMode) return; + tablinks[tabI].className += " active"; +} + +function openTab(tabI, force = false) { + if (pcMode && !force) return; + var i, tabcontent, tablinks; + iSlide = tabI; + _C.classList.toggle('smooth', false); + _C.style.setProperty('--i', iSlide); + updateTablinks(tabI); +} + +var timeout; +function showToast(text, error = false) { + if (error) d.getElementById('connind').style.backgroundColor = "#831"; + var x = d.getElementById("toast"); + x.innerHTML = text; + x.className = error ? "error":"show"; + clearTimeout(timeout); + x.style.animation = 'none'; + x.offsetHeight; + x.style.animation = null; + timeout = setTimeout(function(){ x.className = x.className.replace("show", ""); }, 2900); +} + +function showErrorToast() { + showToast('Connection to light failed!', true); +} +function clearErrorToast() { + d.getElementById("toast").className = d.getElementById("toast").className.replace("error", ""); +} + +function getRuntimeStr(rt) +{ + var t = parseInt(rt); + var days = Math.floor(t/86400); + var hrs = Math.floor((t - days*86400)/3600); + var mins = Math.floor((t - days*86400 - hrs*3600)/60); + var str = days ? (days + " " + (days == 1 ? "day" : "days") + ", ") : ""; + str += (hrs || days) ? (hrs + " " + (hrs == 1 ? "hour" : "hours")) : ""; + if (!days && hrs) str += ", "; + if (t > 59 && !days) str += mins + " min"; + if (t < 3600 && t > 59) str += ", "; + if (t < 3600) str += (t - mins*60) + " sec"; + return str; +} + +function inforow(key, val, unit = "") +{ + return `${key}${val}${unit}`; +} + +function getLowestUnusedP() +{ + var l = 1; + for (var key in pJson) + { + if (key == l) l++; + } + if (l > 250) l = 250; + return l; +} + +function checkUsed(i) { + var id = d.getElementById(`p${i}id`).value; + if (pJson[id] && (i == 0 || id != i)) { + d.getElementById(`p${i}warn`).innerHTML = `⚠ Overwriting ${pName(id)}!` + } else { + d.getElementById(`p${i}warn`).innerHTML = ""; + } +} + +function pName(i) { + var n = "Preset " + i; + if (pJson[i].n) n = pJson[i].n; + return n; +} + +function papiVal(i) { + if (!pJson[i]) return ""; + var o = Object.assign({},pJson[i]); + if (o.win) return o.win; + delete o.n; delete o.p; delete o.ql; + return JSON.stringify(o); +} + +function qlName(i) { + if (!pJson[i]) return ""; + if (!pJson[i].ql) return ""; + return pJson[i].ql; +} + +function cpBck() { + var copyText = document.getElementById("bck"); + + copyText.select(); + copyText.setSelectionRange(0, 999999); + + document.execCommand("copy"); + + showToast("Copied to clipboard!") +} + +function presetError(empty) +{ + var hasBackup = false; var bckstr = ""; + try { + bckstr = localStorage.getItem("wledP"); + if (bckstr.length > 10) hasBackup = true; + } catch (e) { + + } + var cn = `
`; + if (empty) + cn += `You have no presets yet!`; + else + cn += `Sorry, there was an issue loading your presets!`; + + if (hasBackup) { + cn += `

`; + if (empty) + cn += `However, there is backup preset data of a previous installation available.
+ (Saving a preset will hide this and overwrite the backup)`; + else + cn += `Here is a backup of the last known good state:`; + cn += `
+ ` + } + cn += `
`; + d.getElementById('pcont').innerHTML = cn; + if (hasBackup) d.getElementById('bck').value = bckstr; +} + +function loadPresets() +{ + var url = '/presets.json'; + if (loc) { + url = `http://${locip}/presets.json`; + } + + fetch + (url, { + method: 'get' + }) + .then(res => { + if (!res.ok) { + showErrorToast(); + } + return res.json(); + }) + .then(json => { + pJson = json; + populatePresets(); + }) + .catch(function (error) { + showToast(error, true); + console.log(error); + presetError(false); + }) +} + +var pQL = []; + +function populateQL() +{ + var cn = ""; + if (pQL.length > 0) { + cn += `

Quick load

`; + + var it = 0; + for (var key in pQL) + { + cn += ``; + it++; + if (it > 4) { + it = 0; + cn += '
'; + } + } + if (it != 0) cn+= '
'; + + cn += `

All presets

`; + } + d.getElementById('pql').innerHTML = cn; +} + +function populatePresets(fromls) +{ + if (fromls) pJson = JSON.parse(localStorage.getItem("wledP")); + delete pJson["0"]; + var cn = ""; + var arr = Object.entries(pJson); + arr.sort(cmpP); + var added = false; + pQL = []; + var is = []; + + for (var key in arr) + { + if (!isObject(arr[key][1])) continue; + var i = parseInt(arr[key][0]); + var qll = arr[key][1]["ql"]; + if (qll) pQL.push([i, qll]); + is.push(i); + + cn += `
`; + if (cfg.comp.pid) cn += `
${i}
`; + cn += `
${pName(i)}
+ +
+

`; + added = true; + } + + d.getElementById('pcont').innerHTML = cn; + if (added) { + if (pmtLS != pmt && pmt != 0) { + localStorage.setItem("wledPmt", pmt); + pJson["0"] = {}; + localStorage.setItem("wledP", JSON.stringify(pJson)); + } + pmtLS = pmt; + for (var a in is) { + var i = is[a]; + if (expanded[i+100]) expand(i+100, true); + } + } else { presetError(true); } + updatePA(); + populateQL(); +} + +function populateInfo(i) +{ + var cn=""; + var heap = i.freeheap/1000; + heap = heap.toFixed(1); + var pwr = i.leds.pwr; + var pwru = "Not calculated"; + if (pwr > 1000) {pwr /= 1000; pwr = pwr.toFixed((pwr > 10) ? 0 : 1); pwru = pwr + " A";} + else if (pwr > 0) {pwr = 50 * Math.round(pwr/50); pwru = pwr + " mA";} + var urows=""; + for (var k in i.u) + { + var val = i.u[k]; + if (val[1]) { + urows += inforow(k,val[0],val[1]); + } else { + urows += inforow(k,val); + } + } + var vcn = "Kuuhaku"; + if (i.ver.startsWith("0.11.")) vcn = "Mirai"; + if (i.cn) vcn = i.cn; + + cn += `v${i.ver} "${vcn}"

+ ${urows} + ${inforow("Build",i.vid)} + ${inforow("Signal strength",i.wifi.signal +"% ("+ i.wifi.rssi, " dBm)")} + ${inforow("Uptime",getRuntimeStr(i.uptime))} + ${inforow("Free heap",heap," kB")} + ${inforow("Estimated current",pwru)} + ${inforow("MAC address",i.mac)} + ${inforow("Filesystem",i.fs.u + "/" + i.fs.t + " kB (" +Math.round(i.fs.u*100/i.fs.t) + "%)")} + ${inforow("Environment",i.arch + " " + i.core + " (" + i.lwip + ")")} +
`; + d.getElementById('kv').innerHTML = cn; +} + +function populateSegments(s) +{ + var cn = ""; + segCount = 0, lowestUnused = 0; lSeg = 0; + + for (y in s.seg) + { + segCount++; + + var inst=s.seg[y]; + var i = parseInt(inst.id); + powered[i] = inst.on; + if (i == lowestUnused) lowestUnused = i+1; + if (i > lSeg) lSeg = i; + + cn += `
+ +
+ Segment ${i} +
+ +
+ + + + + + + + + +
Start LEDStop LED
+ + + + + + + + + +
GroupingSpacing
+
+ +
+ +
+
+ + + + +
+

`; + } + + d.getElementById('segcont').innerHTML = cn; + if (lowestUnused >= maxSeg) { + d.getElementById('segutil').innerHTML = 'Maximum number of segments reached.'; + noNewSegs = true; + } else if (noNewSegs) { + resetUtil(); + noNewSegs = false; + } + for (i = 0; i <= lSeg; i++) { + updateLen(i); + updateTrail(d.getElementById(`seg${i}bri`)); + if (segCount < 2) d.getElementById(`segd${lSeg}`).style.display = "none"; + } + d.getElementById('rsbtn').style.display = (segCount > 1) ? "inline":"none"; +} + +function updateTrail(e, slidercol) +{ + if (e==null) return; + var max = e.hasAttribute('max') ? e.attributes['max'].value : 255; + var progress = e.value * 100 / max; + progress = parseInt(progress); + var scol; + switch (slidercol) { + case 1: scol = "#f00"; break; + case 2: scol = "#0f0"; break; + case 3: scol = "#00f"; break; + default: scol = "var(--c-f)"; + } + var val = `linear-gradient(90deg, ${scol} ${progress}%, var(--c-4) ${progress}%)`; + e.parentNode.getElementsByClassName('sliderdisplay')[0].style.background = val; +} + +function updateBubble(e) +{ + var bubble = e.target.parentNode.getElementsByTagName('output')[0] + var max = e.target.hasAttribute('max') ? e.target.attributes.max.value : 255; + + if (bubble) { + bubble.innerHTML = e.target.value + } +} + +function toggleBubble(e) +{ + e.target.parentNode.querySelector('output').classList.toggle('hidden'); +} + +function updateLen(s) +{ + if (!d.getElementById(`seg${s}s`)) return; + var start = parseInt(d.getElementById(`seg${s}s`).value); + var stop = parseInt(d.getElementById(`seg${s}e`).value); + var len = stop - start; + var out = "(delete)" + if (len > 1) { + out = `${len} LEDs`; + } else if (len == 1) { + out = "1 LED" + } + + if (d.getElementById(`seg${s}grp`) != null) + { + var grp = parseInt(d.getElementById(`seg${s}grp`).value); + var spc = parseInt(d.getElementById(`seg${s}spc`).value); + if (grp == 0) grp = 1; + var virt = Math.ceil(len/(grp + spc)); + if (!isNaN(virt) && (grp > 1 || spc > 0)) out += ` (${virt} virtual)`; + } + + d.getElementById(`seg${s}len`).innerHTML = out; +} + +function updatePA() +{ + var ps = d.getElementsByClassName("seg"); + for (i = 0; i < ps.length; i++) { + ps[i].style.backgroundColor = "var(--c-2)"; + } + ps = d.getElementsByClassName("psts"); + for (i = 0; i < ps.length; i++) { + ps[i].style.backgroundColor = "var(--c-2)"; + } + if (currentPreset > 0) { + var acv = d.getElementById(`p${currentPreset}o`); + if (acv && !expanded[currentPreset+100]) + acv.style.background = "var(--c-6)"; + acv = d.getElementById(`p${currentPreset}qlb`); + if (acv) acv.style.background = "var(--c-6)"; + } +} + +function updateUI() +{ + d.getElementById('buttonPower').className = (isOn) ? "active":""; + d.getElementById('buttonNl').className = (nlA) ? "active":""; + d.getElementById('buttonSync').className = (syncSend) ? "active":""; + + d.getElementById('fxb' + selectedFx).style.backgroundColor = "var(--c-6)"; + updateTrail(d.getElementById('sliderBri')); + updateTrail(d.getElementById('sliderSpeed')); + updateTrail(d.getElementById('sliderIntensity')); + updateTrail(d.getElementById('sliderW')); + if (isRgbw) d.getElementById('wwrap').style.display = "block"; + + spal = d.getElementById("selectPalette"); + spal.style.backgroundColor = (spal.selectedIndex > 0) ? "var(--c-6)":"var(--c-3)"; + updatePA(); + updateHex(); + updateRgb(); +} + +function displayRover(i,s) +{ + d.getElementById('rover').style.transform = (i.live && s.lor == 0) ? "translateY(0px)":"translateY(100%)"; + var sour = i.lip ? i.lip:""; if (sour.length > 2) sour = " from " + sour; + d.getElementById('lv').innerHTML = `WLED is receiving live ${i.lm} data${sour}`; + d.getElementById('roverstar').style.display = (i.live && s.lor) ? "block":"none"; +} + +function compare(a, b) { + if (a.name < b.name) return -1; + return 1; +} +function cmpP(a, b) { + if (!a[1].n) return (a[0] > b[0]); + return a[1].n.localeCompare(b[1].n,undefined, {numeric: true}); +} + +var jsonTimeout; +var reqC = 0; +function requestJson(command, rinfo = true, verbose = true) { + d.getElementById('connind').style.backgroundColor = "#a90"; + lastUpdate = new Date(); + if (!jsonTimeout) jsonTimeout = setTimeout(showErrorToast, 3000); + var req = null; + e1 = d.getElementById('fxlist'); + e2 = d.getElementById('selectPalette'); + + url = rinfo ? '/json/si': (command ? '/json/state':'/json'); + if (loc) { + url = `http://${locip}${url}`; + } + + type = command ? 'post':'get'; + if (command) + { + command.v = verbose; + command.time = Math.floor(Date.now() / 1000); + req = JSON.stringify(command); + //console.log(req); + } + fetch + (url, { + method: type, + headers: { + "Content-type": "application/json; charset=UTF-8" + }, + body: req + }) + .then(res => { + if (!res.ok) { + showErrorToast(); + } + return res.json(); + }) + .then(json => { + clearTimeout(jsonTimeout); + jsonTimeout = null; + clearErrorToast(); + d.getElementById('connind').style.backgroundColor = "#070"; + if (!json) showToast('Empty response', true); + if (json.success) return; + var s = json; + if (!command || rinfo) { + if (!rinfo) { + pmt = json.info.fs.pmt; + if (pmt != pmtLS || pmt == 0) { + setTimeout(loadPresets,99); + } + else populatePresets(true); + pmtLast = pmt; + var x='',y=''; + json.effects.shift(); //remove solid + for (i in json.effects) json.effects[i] = {id: parseInt(i)+1, name:json.effects[i]}; + json.effects.sort(compare); + for (i in json.effects) { + x += `
`; + } + + json.palettes.shift(); //remove default + for (i in json.palettes) json.palettes[i] = {"id": parseInt(i)+1, "name":json.palettes[i]}; + json.palettes.sort(compare); + for (i in json.palettes) { + y += ``; + } + e1.innerHTML=x; e2.innerHTML=y; + } + + var info = json.info; + var name = info.name; + d.getElementById('namelabel').innerHTML = name; + if (name === "Dinnerbone") d.documentElement.style.transform = "rotate(180deg)"; + if (info.live) name = "(Live) " + name; + if (loc) name = "(L) " + name; + d.title = name; + isRgbw = info.leds.wv; + ledCount = info.leds.count; + syncTglRecv = info.str; + maxSeg = info.leds.maxseg; + pmt = info.fs.pmt; + if (!command && pmt != pmtLast) setTimeout(loadPresets,99); + pmtLast = pmt; + lastinfo = info; + if (isInfo) populateInfo(info); + s = json.state; + displayRover(info, s); + } + isOn = s.on; + d.getElementById('sliderBri').value= s.bri; + nlA = s.nl.on; + nlDur = s.nl.dur; + nlTar = s.nl.tbri; + nlFade = s.nl.fade; + syncSend = s.udpn.send; + savedPresets = s.pss; + currentPreset = s.ps; + d.getElementById('cyToggle').checked = (s.pl < 0) ? false : true; + d.getElementById('cycs').value = s.ccnf.min; + d.getElementById('cyce').value = s.ccnf.max; + d.getElementById('cyct').value = s.ccnf.time /10; + d.getElementById('cyctt').value = s.transition /10; + + var selc=0; var ind=0; + populateSegments(s); + for (i in s.seg) + { + if(s.seg[i].sel) {selc = ind; break;} ind++; + } + var i=s.seg[selc]; + if (!i) { + showToast('No Segments!', true); + updateUI(); + return; + } + var cd = d.getElementById('csl').children; + for (e = 2; e >= 0; e--) + { + cd[e].style.backgroundColor = "rgb(" + i.col[e][0] + "," + i.col[e][1] + "," + i.col[e][2] + ")"; + if (isRgbw) whites[e] = parseInt(i.col[e][3]); + selectSlot(csel); + } + d.getElementById('sliderSpeed').value = whites[csel]; + + d.getElementById('sliderSpeed').value = i.sx; + d.getElementById('sliderIntensity').value = i.ix; + + d.getElementById('fxb' + selectedFx).style.backgroundColor = "var(--c-3)"; + selectedFx = i.fx; + e2.value = i.pal; + if (!command) d.getElementById('Effects').scrollTop = d.getElementById('fxb' + selectedFx).offsetTop - d.getElementById('Effects').clientHeight/1.8; + + if (s.error && s.error != 0) { + var errstr = ""; + switch (s.error) { + case 10: errstr = "Could not mount filesystem!"; break; + case 11: errstr = "Not enough space to save preset!"; break; + case 12: errstr = "The requested preset does not exist."; break; + case 19: errstr = "A filesystem error has occured."; break; + } + showToast('Error ' + s.error + ": " + errstr, true); + } + updateUI(); + }) + .catch(function (error) { + showToast(error, true); + console.log(error); + }) +} + +function togglePower() { + isOn = !isOn; + var obj = {"on": isOn}; + obj.transition = parseInt(d.getElementById('cyctt').value*10); + requestJson(obj); +} + +function toggleNl() { + nlA = !nlA; + if (nlA) + { + showToast(`Timer active. Your light will turn ${nlTar > 0 ? "on":"off"} ${nlFade ? "over":"after"} ${nlDur} minutes.`); + } else { + showToast('Timer deactivated.'); + } + var obj = {"nl": {"on": nlA}}; + requestJson(obj); +} + +function toggleSync() { + syncSend = !syncSend; + if (syncSend) + { + showToast('Other lights in the network will now sync to this one.'); + } else { + showToast('This light and other lights in the network will no longer sync.'); + } + var obj = {"udpn": {"send": syncSend}}; + if (syncTglRecv) obj.udpn.recv = syncSend; + requestJson(obj); +} + +function toggleLiveview() { + isLv = !isLv; + d.getElementById('liveview').style.display = (isLv) ? "block":"none"; + var url = loc ? `http://${locip}/liveview`:"/liveview"; + d.getElementById('liveview').src = (isLv) ? url:"about:blank"; + d.getElementById('buttonSr').className = (isLv) ? "active":""; + size(); +} + +function toggleInfo() { + isInfo = !isInfo; + if (isInfo) populateInfo(lastinfo); + d.getElementById('info').style.transform = (isInfo) ? "translateY(0px)":"translateY(100%)"; + d.getElementById('buttonI').className = (isInfo) ? "active":""; +} + +function makeSeg() { + var ns = 0; + if (lowestUnused > 0) { + var pend = d.getElementById(`seg${lowestUnused -1}e`).value; + if (pend < ledCount) ns = pend; + } + var cn = `
+
+ New segment ${lowestUnused} +
+
+
+ + + + + + + + + +
Start LEDStop LED
+
${ledCount - ns} LEDs
+ +
+
`; + d.getElementById('segutil').innerHTML = cn; +} + +function resetUtil() { + var cn = `
`; + d.getElementById('segutil').innerHTML = cn; +} + +function makeP(i) { + return ` +
+
Quick load label:
+
(leave empty for no Quick load button)
+
+
+ API command
+ +
+
+ + +
+
Save to ID 0)?i:getLowestUnusedP()}>
+
+ + ${(i>0)?'': + ''} +
+
+ +
+ ${(i>0)? ('
ID ' +i+ '
'):""}`; +} + +function makePUtil() { + d.getElementById('putil').innerHTML = `
+
+ New preset
+
+ ${makeP(0)}
`; + updateTrail(d.getElementById('p0p')); +} + +function resetPUtil() { + var cn = `
`; + d.getElementById('putil').innerHTML = cn; +} + +function tglCs(i){ + var pss = d.getElementById(`p${i}cstgl`).checked; + d.getElementById(`p${i}o1`).style.display = pss? "block" : "none"; + d.getElementById(`p${i}o2`).style.display = !pss? "block" : "none"; +} + +function selSegEx(s) +{ + var obj = {"seg":[]}; + for(i=0; i<=lSeg; i++){ + obj.seg.push({"sel":(i==s)?true:false}); + } + requestJson(obj); +} + +function selSeg(s){ + var sel = d.getElementById(`seg${s}sel`).checked; + var obj = {"seg": {"id": s, "sel": sel}}; + requestJson(obj, false); +} + +function setSeg(s){ + var start = parseInt(d.getElementById(`seg${s}s`).value); + var stop = parseInt(d.getElementById(`seg${s}e`).value); + if (stop <= start) {delSeg(s); return;}; + var obj = {"seg": {"id": s, "start": start, "stop": stop}}; + if (d.getElementById(`seg${s}grp`)) + { + var grp = parseInt(d.getElementById(`seg${s}grp`).value); + var spc = parseInt(d.getElementById(`seg${s}spc`).value); + obj.seg.grp = grp; + obj.seg.spc = spc; + } + requestJson(obj); +} + +function delSeg(s){ + if (segCount < 2) { + showToast("You need to have multiple segments to delete one!"); + return; + } + expanded[s] = false; + segCount--; + var obj = {"seg": {"id": s, "stop": 0}}; + requestJson(obj, false); +} + +function setRev(s){ + var rev = d.getElementById(`seg${s}rev`).checked; + var obj = {"seg": {"id": s, "rev": rev}}; + requestJson(obj, false); +} + +function setMi(s){ + var mi = d.getElementById(`seg${s}mi`).checked; + var obj = {"seg": {"id": s, "mi": mi}}; + requestJson(obj, false); +} + +function setSegPwr(s){ + var obj = {"seg": {"id": s, "on": !powered[s]}}; + requestJson(obj); +} + +function setSegBri(s){ + var obj = {"seg": {"id": s, "bri": parseInt(d.getElementById(`seg${s}bri`).value)}}; + requestJson(obj); +} + +function setX(ind) { + var obj = {"seg": {"fx": parseInt(ind)}}; + requestJson(obj); +} + +function setPalette() +{ + var obj = {"seg": {"pal": parseInt(d.getElementById('selectPalette').value)}}; + requestJson(obj); +} + +function setBri() { + var obj = {"bri": parseInt(d.getElementById('sliderBri').value)}; + obj.transition = parseInt(d.getElementById('cyctt').value*10); + requestJson(obj); +} + +function setSpeed() { + var obj = {"seg": {"sx": parseInt(d.getElementById('sliderSpeed').value)}}; + requestJson(obj, false); +} + +function setIntensity() { + var obj = {"seg": {"ix": parseInt(d.getElementById('sliderIntensity').value)}}; + requestJson(obj, false); +} + +function setLor(i) { + var obj = {"lor": i}; + requestJson(obj); +} + +function toggleCY() { + var obj = {"pl" : -1}; + if (d.getElementById('cyToggle').checked) + { + obj = {"pl": 0, "ccnf": {"min": parseInt(d.getElementById('cycs').value), "max": parseInt(d.getElementById('cyce').value), "time": parseInt(d.getElementById('cyct').value*10)}}; + obj.transition = parseInt(d.getElementById('cyctt').value*10); + } + + requestJson(obj); +} + +function setPreset(i) { + var obj = {"ps": i} + + showToast("Loading preset " + pName(i) +" (" + i + ")"); + + requestJson(obj); +} + +function saveP(i) { + pI = parseInt(d.getElementById(`p${i}id`).value); + if (!pI || pI < 1) pI = (i>0) ? i : getLowestUnusedP(); + pN = d.getElementById(`p${i}txt`).value; + if (pN == "") pN = "Preset " + pI; + var obj = {}; + if (!d.getElementById(`p${i}cstgl`).checked) { + var raw = d.getElementById(`p${i}api`).value; + try { + obj = JSON.parse(raw); + } catch (e) { + obj["win"] = raw; + if (raw.length < 2) { + d.getElementById(`p${i}warn`).innerHTML = "⚠ Please enter your API command first"; + return; + } else if (raw.indexOf('{') > -1) { + d.getElementById(`p${i}warn`).innerHTML = "⚠ Syntax error in custom JSON API command"; + return; + } else if (raw.indexOf("Please") == 0) { + d.getElementById(`p${i}warn`).innerHTML = "⚠ Please refresh the page before modifying this preset"; + return; + } + } + obj["o"] = true; + } else { + obj["ib"] = d.getElementById(`p${i}ibtgl`).checked; + obj["sb"] = d.getElementById(`p${i}sbtgl`).checked; + } + obj["psave"] = pI; obj["n"] = pN; + var pQN = d.getElementById(`p${i}ql`).value; + if (pQN.length > 0) obj["ql"] = pQN; + + showToast("Saving " + pN +" (" + pI + ")"); + requestJson(obj); + if (obj["o"]) { + pJson[pI] = obj; + delete pJson[pI]["psave"]; + delete pJson[pI]["o"]; + delete pJson[pI]["v"]; + delete pJson[pI]["time"]; + } else { + pJson[pI] = {"n":pN, "win":"Please refresh the page to see this newly saved command."}; + if (obj["win"]) pJson[pI]["win"] = obj["win"]; + if (obj["ql"]) pJson[pI]["ql"] = obj["ql"]; + } + populatePresets(); + resetPUtil(); +} + +function delP(i) { + var obj = {"pdel": i}; + requestJson(obj); + delete pJson[i]; + populatePresets(); +} + +function selectSlot(b) { + csel = b; + var cd = d.getElementById('csl').children; + for (i = 0; i < cd.length; i++) { + cd[i].style.border="2px solid white"; + cd[i].style.margin="5px"; + cd[i].style.width="42px"; + } + cd[csel].style.border="5px solid white"; + cd[csel].style.margin="2px"; + cd[csel].style.width="50px"; + cpick.color.set(cd[csel].style.backgroundColor); + d.getElementById('sliderW').value = whites[csel]; + updateTrail(d.getElementById('sliderW')); + updateHex(); + updateRgb(); +} + +var lasth = 0; +function pC(col) +{ + if (col == "rnd") + { + col = {h: 0, s: 0, v: 100}; + col.s = Math.floor((Math.random() * 50) + 50); + do { + col.h = Math.floor(Math.random() * 360); + } while (Math.abs(col.h - lasth) < 50); + lasth = col.h; + } + cpick.color.set(col); + setColor(0); +} + +function updateRgb() +{ + var col = cpick.color.rgb; + var s = d.getElementById('sliderR'); + s.value = col.r; updateTrail(s,1); + s = d.getElementById('sliderG'); + s.value = col.g; updateTrail(s,2); + s = d.getElementById('sliderB'); + s.value = col.b; updateTrail(s,3); +} + +function updateHex() +{ + var str = cpick.color.hexString; + str = str.substring(1); + var w = whites[csel]; + if (w > 0) str += w.toString(16); + d.getElementById('hexc').value = str; + d.getElementById('hexcnf').style.backgroundColor = "var(--c-3)"; +} + +function hexEnter() { + d.getElementById('hexcnf').style.backgroundColor = "var(--c-6)"; + if(event.keyCode == 13) fromHex(); +} + +function fromHex() +{ + var str = d.getElementById('hexc').value; + whites[csel] = parseInt(str.substring(6), 16); + try { + cpick.color.set("#" + str.substring(0,6)); + } catch (e) { + cpick.color.set("#ffaa00"); + } + if (isNaN(whites[csel])) whites[csel] = 0; + setColor(2); +} + +function fromRgb() +{ + var r = d.getElementById('sliderR').value; + var g = d.getElementById('sliderG').value; + var b = d.getElementById('sliderB').value; + cpick.color.set(`rgb(${r},${g},${b})`); + setColor(0); +} + +function setColor(sr) { + var cd = d.getElementById('csl').children; + if (sr == 1 && cd[csel].style.backgroundColor == 'rgb(0, 0, 0)') cpick.color.setChannel('hsv', 'v', 100); + cd[csel].style.backgroundColor = cpick.color.rgbString; + if (sr != 2) whites[csel] = d.getElementById('sliderW').value; + var col = cpick.color.rgb; + var obj = {"seg": {"col": [[col.r, col.g, col.b, whites[csel]],[],[]]}}; + if (csel == 1) { + obj = {"seg": {"col": [[],[col.r, col.g, col.b, whites[csel]],[]]}}; + } else if (csel == 2) { + obj = {"seg": {"col": [[],[],[col.r, col.g, col.b, whites[csel]]]}}; + } + updateHex(); + updateRgb(); + obj.transition = parseInt(d.getElementById('cyctt').value*10); + requestJson(obj); +} + +var hc = 0; +setInterval(function(){if (!isInfo) return; hc+=18; if (hc>300) hc=0; if (hc>200)hc=306; if (hc==144) hc+=36; if (hc==108) hc+=18; +d.getElementById('heart').style.color = `hsl(${hc}, 100%, 50%)`}, 910); + +function openGH() +{ + window.open("https://github.com/Aircoookie/WLED/wiki"); +} + +var cnfr = false; +function cnfReset() +{ + if (!cnfr) + { + var bt = d.getElementById('resetbtn'); + bt.style.color = "#f00"; + bt.innerHTML = "Confirm Reboot"; + cnfr = true; return; + } + window.location.href = "/reset"; +} + +var cnfrS = false; +function rSegs() +{ + var bt = d.getElementById('rsbtn'); + if (!cnfrS) + { + bt.style.color = "#f00"; + bt.innerHTML = "Confirm reset"; + cnfrS = true; return; + } + cnfrS = false; + bt.style.color = "#fff"; + bt.innerHTML = "Reset segments"; + var obj = {"seg":[{"start":0,"stop":ledCount,"sel":true}]}; + for(i=1; i<=lSeg; i++){ + obj.seg.push({"stop":0}); + } + requestJson(obj); +} + +function expand(i,a) +{ + if (!a) expanded[i] = !expanded[i]; + d.getElementById('seg' +i).style.display = (expanded[i]) ? "block":"none"; + d.getElementById('sege' +i).style.transform = (expanded[i]) ? "rotate(180deg)":"rotate(0deg)" + if (i > 100) { //presets + var p = i-100; + d.getElementById(`p${p}o`).style.background = (expanded[i] || p != currentPreset)?"var(--c-2)":"var(--c-6)"; + if (d.getElementById('seg' +i).innerHTML == "") { + d.getElementById('seg' +i).innerHTML = makeP(p); + var papi = papiVal(p); + d.getElementById(`p${p}api`).value = papi; + if (papi.indexOf("Please") == 0) d.getElementById(`p${p}cstgl`).checked = true; + tglCs(p); + } + } +} + +function unfocusSliders() { + d.getElementById("sliderBri").blur(); + d.getElementById("sliderSpeed").blur(); + d.getElementById("sliderIntensity").blur(); +} + +//sliding UI +const _C = document.querySelector('.container'), N = 4; + +let iSlide = 0, x0 = null, scrollS = 0, locked = false, w; + +function unify(e) { return e.changedTouches ? e.changedTouches[0] : e } + +function hasIroClass(classList) { + for (var i = 0; i < classList.length; i++) { + var element = classList[i]; + if (element.startsWith('Iro')) return true; + } + + return false; +} + + +function lock(e) { + if (pcMode) return; + var l = e.target.classList; + var pl = e.target.parentElement.classList; + + if (l.contains('noslide') || hasIroClass(l) || hasIroClass(pl)) return; + + x0 = unify(e).clientX; + scrollS = d.getElementsByClassName("tabcontent")[iSlide].scrollTop; + + _C.classList.toggle('smooth', !(locked = true)) +} + +function move(e) { + if(!locked || pcMode) return; + var dx = unify(e).clientX - x0, s = Math.sign(dx), + f = +(s*dx/w).toFixed(2); + + if((iSlide > 0 || s < 0) && (iSlide < N - 1 || s > 0) + && f > .12 + && d.getElementsByClassName("tabcontent")[iSlide].scrollTop == scrollS) { + _C.style.setProperty('--i', iSlide -= s); + f = 1 - f; + updateTablinks(iSlide); + } + _C.style.setProperty('--f', f); + _C.classList.toggle('smooth', !(locked = false)); + x0 = null +} + +function size() { + w = window.innerWidth; + var h = d.getElementById('top').clientHeight; + sCol('--th', h + "px"); + sCol('--bh', d.getElementById('bot').clientHeight + "px"); + if (isLv) h -= 4; + sCol('--tp', h + "px"); + togglePcMode(); +} + +function togglePcMode(fromB = false) +{ + if (fromB) { + pcModeA = !pcModeA; + localStorage.setItem('pcm', pcModeA); + pcMode = pcModeA; + } + if (w < 1250 && !pcMode) return; + if (!fromB && ((w < 1250 && lastw < 1250) || (w >= 1250 && lastw >= 1250))) return; + openTab(0, true); + if (w < 1250) {pcMode = false;} + else if (pcModeA && !fromB) pcMode = pcModeA; + updateTablinks(0); + d.getElementById('buttonPcm').className = (pcMode) ? "active":""; + d.getElementById('bot').style.height = (pcMode && !cfg.comp.pcmbot) ? "0":"auto"; + sCol('--bh', d.getElementById('bot').clientHeight + "px"); + _C.style.width = (pcMode)?'100%':'400%'; + lastw = w; +} + +function isObject(item) { + return (item && typeof item === 'object' && !Array.isArray(item)); +} + +function mergeDeep(target, ...sources) { + if (!sources.length) return target; + const source = sources.shift(); + + if (isObject(target) && isObject(source)) { + for (const key in source) { + if (isObject(source[key])) { + if (!target[key]) Object.assign(target, { [key]: {} }); + mergeDeep(target[key], source[key]); + } else { + Object.assign(target, { [key]: source[key] }); + } + } + } + return mergeDeep(target, ...sources); +} + +size(); +_C.style.setProperty('--n', N); + +window.addEventListener('resize', size, false); + +_C.addEventListener('mousedown', lock, false); +_C.addEventListener('touchstart', lock, false); + +_C.addEventListener('mouseout', move, false); +_C.addEventListener('mouseup', move, false); +_C.addEventListener('touchend', move, false); \ No newline at end of file diff --git a/wled00/data/iro.js b/wled00/data/iro.js new file mode 100644 index 000000000..f459e417c --- /dev/null +++ b/wled00/data/iro.js @@ -0,0 +1,7 @@ +/*! + * iro.js v5.3.1 + * 2016-2020 James Daniel + * Licensed under MPL 2.0 + * github.com/jaames/iro.js + */ +!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t=t||self).iro=n()}(this,function(){"use strict";var k,s,n,i,o,m={},M=[],r=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|^--/i;function j(t,n){for(var i in n)t[i]=n[i];return t}function b(t){var n=t.parentNode;n&&n.removeChild(t)}function d(t,n,i){var r,e,u,o,l=arguments;if(n=j({},n),3=r/i?u=n:e=n}return n},function(t,n,i){n&&g(t.prototype,n),i&&g(t,i)}(l,[{key:"hsv",get:function(){var t=this.$;return{h:t.h,s:t.s,v:t.v}},set:function(t){var n=this.$;if(t=p({},n,t),this.onChange){var i={h:!1,v:!1,s:!1,a:!1};for(var r in n)i[r]=t[r]!=n[r];this.$=t,(i.h||i.s||i.v||i.a)&&this.onChange(this,i)}else this.$=t}},{key:"hsva",get:function(){return p({},this.$)},set:function(t){this.hsv=t}},{key:"hue",get:function(){return this.$.h},set:function(t){this.hsv={h:t}}},{key:"saturation",get:function(){return this.$.s},set:function(t){this.hsv={s:t}}},{key:"value",get:function(){return this.$.v},set:function(t){this.hsv={v:t}}},{key:"alpha",get:function(){return this.$.a},set:function(t){this.hsv=p({},this.hsv,{a:t})}},{key:"kelvin",get:function(){return l.rgbToKelvin(this.rgb)},set:function(t){this.rgb=l.kelvinToRgb(t)}},{key:"red",get:function(){return this.rgb.r},set:function(t){this.rgb=p({},this.rgb,{r:t})}},{key:"green",get:function(){return this.rgb.g},set:function(t){this.rgb=p({},this.rgb,{g:t})}},{key:"blue",get:function(){return this.rgb.b},set:function(t){this.rgb=p({},this.rgb,{b:t})}},{key:"rgb",get:function(){var t=l.hsvToRgb(this.$),n=t.r,i=t.g,r=t.b;return{r:U(n),g:U(i),b:U(r)}},set:function(t){this.hsv=p({},l.rgbToHsv(t),{a:void 0===t.a?1:t.a})}},{key:"rgba",get:function(){return p({},this.rgb,{a:this.alpha})},set:function(t){this.rgb=t}},{key:"hsl",get:function(){var t=l.hsvToHsl(this.$),n=t.h,i=t.s,r=t.l;return{h:U(n),s:U(i),l:U(r)}},set:function(t){this.hsv=p({},l.hslToHsv(t),{a:void 0===t.a?1:t.a})}},{key:"hsla",get:function(){return p({},this.hsl,{a:this.alpha})},set:function(t){this.hsl=t}},{key:"rgbString",get:function(){var t=this.rgb;return"rgb("+t.r+", "+t.g+", "+t.b+")"},set:function(t){var n,i,r,e,u=1;if((n=P.exec(t))?(i=K(n[1],255),r=K(n[2],255),e=K(n[3],255)):(n=z.exec(t))&&(i=K(n[1],255),r=K(n[2],255),e=K(n[3],255),u=K(n[4],1)),!n)throw new Error("Invalid rgb string");this.rgb={r:i,g:r,b:e,a:u}}},{key:"rgbaString",get:function(){var t=this.rgba;return"rgba("+t.r+", "+t.g+", "+t.b+", "+t.a+")"},set:function(t){this.rgbString=t}},{key:"hexString",get:function(){var t=this.rgb;return"#"+V(t.r)+V(t.g)+V(t.b)},set:function(t){var n,i,r,e,u=255;if((n=C.exec(t))?(i=17*Q(n[1]),r=17*Q(n[2]),e=17*Q(n[3])):(n=D.exec(t))?(i=17*Q(n[1]),r=17*Q(n[2]),e=17*Q(n[3]),u=17*Q(n[4])):(n=F.exec(t))?(i=Q(n[1]),r=Q(n[2]),e=Q(n[3])):(n=G.exec(t))&&(i=Q(n[1]),r=Q(n[2]),e=Q(n[3]),u=Q(n[4])),!n)throw new Error("Invalid hex string");this.rgb={r:i,g:r,b:e,a:u/255}}},{key:"hex8String",get:function(){var t=this.rgba;return"#"+V(t.r)+V(t.g)+V(t.b)+V(q(255*t.a))},set:function(t){this.hexString=t}},{key:"hslString",get:function(){var t=this.hsl;return"hsl("+t.h+", "+t.s+"%, "+t.l+"%)"},set:function(t){var n,i,r,e,u=1;if((n=H.exec(t))?(i=K(n[1],360),r=K(n[2],100),e=K(n[3],100)):(n=$.exec(t))&&(i=K(n[1],360),r=K(n[2],100),e=K(n[3],100),u=K(n[4],1)),!n)throw new Error("Invalid hsl string");this.hsl={h:i,s:r,l:e,a:u}}},{key:"hslaString",get:function(){var t=this.hsla;return"hsl("+t.h+", "+t.s+"%, "+t.l+"%, "+t.a+")"},set:function(t){this.hslString=t}}]),l}();function Z(t){var n,i=t.width,r=t.sliderSize,e=t.borderWidth,u=t.handleRadius,o=t.padding,l=t.sliderShape,s="horizontal"===t.layoutDirection;return r=null!=(n=r)?n:2*o+2*u+2*e,"circle"===l?{handleStart:t.padding+t.handleRadius,handleRange:i-2*o-2*u-2*e,width:i,height:i,cx:i/2,cy:i/2,radius:i/2-e/2}:{handleStart:r/2,handleRange:i-r,radius:r/2,x:0,y:0,width:s?r:i,height:s?i:r}}function tt(t,n){var i=Z(t),r=i.width,e=i.height,u=i.handleRange,o=i.handleStart,l="horizontal"===t.layoutDirection,s=l?r/2:e/2,c=o+function(t,n){var i=n.hsva,r=n.rgb;switch(t.sliderType){case"red":return r.r/2.55;case"green":return r.g/2.55;case"blue":return r.b/2.55;case"alpha":return 100*i.a;case"kelvin":var e=t.minTemperature,u=t.maxTemperature-e,o=(n.kelvin-e)/u*100;return Math.max(0,Math.min(o,100));case"hue":return i.h/=3.6;case"saturation":return i.s;case"value":default:return i.v}}(t,n)/100*u;return l&&(c=-1*c+u+2*o),{x:l?s:c,y:l?c:s}}function nt(t){var n=t.width/2;return{width:t.width,radius:n-t.borderWidth,cx:n,cy:n}}function it(t,n,i){var r=t.wheelAngle,e=t.wheelDirection;return((n=!i&&"clockwise"===e||i&&"anticlockwise"===e?(i?180:360)-(r-n):r+n)%360+360)%360}function rt(t,n,i){var r=nt(t),e=r.cx,u=r.cy,o=t.width/2-t.padding-t.handleRadius-t.borderWidth;n=e-n,i=u-i;var l=it(t,Math.atan2(-i,-n)*(180/Math.PI)),s=Math.min(Math.sqrt(n*n+i*i),o);return{h:Math.round(l),s:Math.round(100/o*s)}}function et(t){var n=t.width,i=t.boxHeight;return{width:n,height:null!=i?i:n,radius:t.padding+t.handleRadius}}function ut(t,n,i){var r=et(t),e=r.width,u=r.height,o=r.radius,l=(n-o)/(e-2*o)*100,s=(i-o)/(u-2*o)*100;return{s:Math.max(0,Math.min(l,100)),v:Math.max(0,Math.min(100-s,100))}}function ot(t){X=X||document.getElementsByTagName("base");var n=window.navigator.userAgent,i=/^((?!chrome|android).)*safari/i.test(n),r=/iPhone|iPod|iPad/i.test(n),e=window.location;return(i||r)&&0 work on touch devices +// https://github.com/sampotts/rangetouch +// License: The MIT License (MIT) +// ========================================================================== +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define("RangeTouch",t):(e=e||self).RangeTouch=t()}(this,(function(){"use strict";function e(e,t){for(var n=0;nt){var n=function(e){var t="".concat(e).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);return t?Math.max(0,(t[1]?t[1].length:0)-(t[2]?+t[2]:0)):0}(t);return parseFloat(e.toFixed(n))}return Math.round(e/t)*t}return function(){function t(e,n){(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")})(this,t),m(e)?this.element=e:d(e)&&(this.element=document.querySelector(e)),m(this.element)&&p(this.element.rangeTouch)&&(this.config=r({},i,{},n),this.init())}return n=t,c=[{key:"setup",value:function(e){var n=1(n=100/l.width*(i.clientX-l.left))?n=0:100n?n-=(100-2*n)*a:50