Updating pxmagic and WLED UI

This commit is contained in:
Alerson Jorge 2023-07-20 13:20:13 -03:00
parent e010e67717
commit aec0bc5029
7 changed files with 2781 additions and 2634 deletions

View File

@ -271,6 +271,20 @@ button {
transform: translate(-50%,-50%); transform: translate(-50%,-50%);
} }
#pxm {
display: none;
width: 100%;
height: 100%;
border: 0;
position: absolute;
}
#ipxm {
width: 100%;
height: 100%;
position: relative;
}
.tab { .tab {
background-color: transparent; background-color: transparent;
color: var(--c-d); color: var(--c-d);

View File

@ -65,6 +65,7 @@
<button id="buttonNl" onclick="toggleNl()"><i class="icons">&#xe2a2;</i><p class="tab-label">Timer</p></button> <button id="buttonNl" onclick="toggleNl()"><i class="icons">&#xe2a2;</i><p class="tab-label">Timer</p></button>
<button id="buttonSync" onclick="toggleSync()"><i class="icons">&#xe116;</i><p class="tab-label">Sync</p></button> <button id="buttonSync" onclick="toggleSync()"><i class="icons">&#xe116;</i><p class="tab-label">Sync</p></button>
<button id="buttonSr" onclick="toggleLiveview()"><i class="icons">&#xe410;</i><p class="tab-label">Peek</p></button> <button id="buttonSr" onclick="toggleLiveview()"><i class="icons">&#xe410;</i><p class="tab-label">Peek</p></button>
<button id="buttonPixelMagicTool" onclick="togglePixelMagicTool()"><i class="icons">&#xe2b3;</i><p class="tab-label">Pixel Magic</p></button>
<button id="buttonI" onclick="toggleInfo()"><i class="icons">&#xe066;</i><p class="tab-label">Info</p></button> <button id="buttonI" onclick="toggleInfo()"><i class="icons">&#xe066;</i><p class="tab-label">Info</p></button>
<button id="buttonNodes" onclick="toggleNodes()"><i class="icons">&#xe22d;</i><p class="tab-label">Nodes</p></button> <button id="buttonNodes" onclick="toggleNodes()"><i class="icons">&#xe22d;</i><p class="tab-label">Nodes</p></button>
<button onclick="window.location.href=getURL('/settings');"><i class="icons">&#xe0a2;</i><p class="tab-label">Config</p></button> <button onclick="window.location.href=getURL('/settings');"><i class="icons">&#xe0a2;</i><p class="tab-label">Config</p></button>
@ -392,6 +393,12 @@
<button class="btn" onclick="setLor(2)">Override until reboot</button><br> <button class="btn" onclick="setLor(2)">Override until reboot</button><br>
<span class="h">For best performance, it is recommended to turn off the streaming source when not in use.</span> <span class="h">For best performance, it is recommended to turn off the streaming source when not in use.</span>
</div> </div>
<div id="mpxm" class="modal">
<button class="btn btn-xs close" onclick="togglePixelMagicTool()"><i class="icons rot45">&#xe18a;</i></button>
<div id="ipxm">Loading...</div>
</div>
<i id="roverstar" class="icons huge" onclick="setLor(0)">&#xe410;</i><br> <i id="roverstar" class="icons huge" onclick="setLor(0)">&#xe410;</i><br>
<script src="index.js"></script> <script src="index.js"></script>
</body> </body>

View File

@ -1,6 +1,6 @@
//page js //page js
var loc = false, locip, locproto = "http:"; var loc = false, locip, locproto = "http:";
var isOn = false, nlA = false, isLv = false, isInfo = false, isNodes = false, syncSend = false, syncTglRecv = true; var isOn = false, nlA = false, isLv = false, isInfo = false, isNodes = false, syncSend = false, syncTglRecv = true, isPXM = false;
var hasWhite = false, hasRGB = false, hasCCT = false; var hasWhite = false, hasRGB = false, hasCCT = false;
var nlDur = 60, nlTar = 0; var nlDur = 60, nlTar = 0;
var nlMode = false; var nlMode = false;
@ -26,7 +26,7 @@ var ws, cpick, ranges;
var cfg = { var cfg = {
theme:{base:"dark", bg:{url:""}, alpha:{bg:0.6,tab:0.8}, color:{bg:""}}, theme:{base:"dark", bg:{url:""}, alpha:{bg:0.6,tab:0.8}, color:{bg:""}},
comp :{colors:{picker: true, rgb: false, quick: true, hex: false}, comp :{colors:{picker: true, rgb: false, quick: true, hex: false},
labels:true, pcmbot:false, pid:true, seglen:false, segpwr:false, segexp:false, css:true, hdays:false} labels:true, pcmbot:false, pid:true, seglen:false, segpwr:false, segexp:false, css:true, hdays:false, pxm: false}
}; };
var hol = [ var hol = [
[0,11,24,4,"https://aircoookie.github.io/xmas.png"], // christmas [0,11,24,4,"https://aircoookie.github.io/xmas.png"], // christmas
@ -38,6 +38,9 @@ var hol = [
[0,0,1,1,"https://initiate.alphacoders.com/download/wallpaper/1198800/images/jpg/2522807481585600"] // new year [0,0,1,1,"https://initiate.alphacoders.com/download/wallpaper/1198800/images/jpg/2522807481585600"] // new year
]; ];
// Buttons
var btnPXM = gId('buttonPixelMagicTool');
function handleVisibilityChange() {if (!d.hidden && new Date () - lastUpdate > 3000) requestJson();} function handleVisibilityChange() {if (!d.hidden && new Date () - lastUpdate > 3000) requestJson();}
function sCol(na, col) {d.documentElement.style.setProperty(na, col);} function sCol(na, col) {d.documentElement.style.setProperty(na, col);}
function gId(c) {return d.getElementById(c);} function gId(c) {return d.getElementById(c);}
@ -283,6 +286,8 @@ function onLoad()
sl.addEventListener('touchstart', toggleBubble); sl.addEventListener('touchstart', toggleBubble);
sl.addEventListener('touchend', toggleBubble); sl.addEventListener('touchend', toggleBubble);
} }
btnPXM.style.display = cfg.comp.pxm ? "block" : "none";
} }
function updateTablinks(tabI) function updateTablinks(tabI)
@ -1685,6 +1690,7 @@ function toggleLiveview()
//WLEDSR adding liveview2D support //WLEDSR adding liveview2D support
if (isInfo && isM) toggleInfo(); if (isInfo && isM) toggleInfo();
if (isNodes && isM) toggleNodes(); if (isNodes && isM) toggleNodes();
if (isPXM && isM) togglePixelMagicTool();
isLv = !isLv; isLv = !isLv;
var lvID = "liveview"; var lvID = "liveview";
@ -1709,6 +1715,7 @@ function toggleLiveview()
function toggleInfo() function toggleInfo()
{ {
if (isNodes) toggleNodes(); if (isNodes) toggleNodes();
if (isPXM) togglePixelMagicTool();
if (isLv && isM) toggleLiveview(); if (isLv && isM) toggleLiveview();
isInfo = !isInfo; isInfo = !isInfo;
if (isInfo) requestJson(); if (isInfo) requestJson();
@ -1719,6 +1726,7 @@ function toggleInfo()
function toggleNodes() function toggleNodes()
{ {
if (isInfo) toggleInfo(); if (isInfo) toggleInfo();
if (isPXM) togglePixelMagicTool();
if (isLv && isM) toggleLiveview(); if (isLv && isM) toggleLiveview();
isNodes = !isNodes; isNodes = !isNodes;
if (isNodes) loadNodes(); if (isNodes) loadNodes();
@ -1726,6 +1734,40 @@ function toggleNodes()
gId('buttonNodes').className = (isNodes) ? "active":""; gId('buttonNodes').className = (isNodes) ? "active":"";
} }
function togglePixelMagicTool()
{
if (isInfo) toggleInfo();
if (isNodes) toggleNodes();
if (isLv && isM) toggleLiveview();
isPXM = !isPXM;
var id = "pxm";
if (isPXM) gId('ipxm').innerHTML = `<iframe id="${id}" src="about:blank"></iframe>`;
gId('mpxm').style.transform = (isPXM) ? "translateY(0px)":"translateY(100%)";
var iframe = gId(id);
iframe.style.display = (isPXM) ? "block":"none";
iframe.src = (isPXM) ? getURL("/pxmagic.htm"):"about:blank";
iframe.onload = function () {
if(isPXM){
var iframeContent = this.contentDocument;
iframeContent.body.style.backgroundColor = "transparent";
var header = iframeContent.querySelector('.header');
header.style.display = "none";
}
}
btnPXM.className = (isPXM) ? "active":"";
size();
}
function updateNameResize(){
btnPXM.querySelector('p').textContent = (wW < 1024) ? "PXM" : "Pixel Magic";
}
function makeSeg() function makeSeg()
{ {
var ns = 0, ct = 0; var ns = 0, ct = 0;
@ -2853,9 +2895,22 @@ function size()
if (isLv) h -= 4; if (isLv) h -= 4;
sCol('--tp', h + "px"); sCol('--tp', h + "px");
togglePcMode(); togglePcMode();
updateNameResize();
lastw = wW; lastw = wW;
} }
function listenMessage(e){
const { origin, data } = e;
if (origin === window.location.origin) {
switch(data){
case 'loadPresets':
setTimeout(()=>{pmtLast=0; loadPresets();}, 250);
break;
}
}
}
function togglePcMode(fromB = false) function togglePcMode(fromB = false)
{ {
if (fromB) { if (fromB) {
@ -2895,6 +2950,7 @@ size();
_C.style.setProperty('--n', N); _C.style.setProperty('--n', N);
window.addEventListener('resize', size, true); window.addEventListener('resize', size, true);
window.addEventListener('message', listenMessage, true);
_C.addEventListener('mousedown', lock, false); _C.addEventListener('mousedown', lock, false);
_C.addEventListener('touchstart', lock, false); _C.addEventListener('touchstart', lock, false);

View File

@ -7,13 +7,10 @@
<title>Pixel Magic Tool</title> <title>Pixel Magic Tool</title>
<!-- <link
rel="shortcut icon"
href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAK9JREFUeNqUUssNwyAMJZWVUw4dhRHakZA6RqWMFEbwKDnk1FNBekEWxOBYQggL/D68yXXq+M7PtHkcefn89vrOw/UrP96w/NUFGiDLRz71GyY0QJa1Yn+nFa0ShqUNYCAF0QvoceOB4naEZif6UTNRapYaTyauRi4DEspr4Hbs5YKsbmtMyeJ0LxeESV4gB+hlSy4oO2txWysyus0a0+lO6vBjxcTMlG4mt2H6F2AAhU5NWu4dorQAAAAASUVORK5CYII=
" /> -->
<style> <style>
:root { :root {
--s-thumb: #0006;
--s-background: #0003;
--overlay: rgba(0, 0, 0, 0.5); --overlay: rgba(0, 0, 0, 0.5);
--background: #111; --background: #111;
--text: #bbb; --text: #bbb;
@ -34,6 +31,24 @@
--warning-light: #f48c06; --warning-light: #f48c06;
} }
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: var(--s-thumb);
opacity: 0.2;
border-radius: 5px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--s-background);
}
::selection { ::selection {
background: var(--blue-light); background: var(--blue-light);
} }
@ -65,7 +80,7 @@
display: block; display: block;
font-weight: 400; font-weight: 400;
margin: 2px 0 5px; margin: 2px 0 5px;
color: var(--text); color: var(--gray-light);
font-size: 12px; font-size: 12px;
} }
@ -83,7 +98,7 @@
font-weight: 600; font-weight: 600;
} }
:is(a:hover, a:focus, a:active) { a:is(:hover, :focus, :active) {
color: var(--blue-medium); color: var(--blue-medium);
} }
@ -108,8 +123,7 @@
} }
.content { .content {
width: calc(100% - 40px); width: min(768px, calc(100% - 40px));
max-width: 768px;
margin: 20px; margin: 20px;
} }
@ -117,19 +131,19 @@
display: flex; display: flex;
flex-wrap: nowrap; flex-wrap: nowrap;
justify-content: space-between; justify-content: space-between;
margin: 20px 0 0; margin-top: 20px;
} }
.column { .column {
flex-basis: calc(50% - 10px); flex-basis: calc(50% - 10px);
position: relative; position: relative;
padding: 0 5px; padding-inline: 5px;
} }
.column-full { .column-full {
flex-basis: 100%; flex-basis: 100%;
position: relative; position: relative;
padding: 0 5px; padding-inline: 5px;
} }
label { label {
@ -157,7 +171,7 @@
width: 32px; width: 32px;
height: 32px; height: 32px;
cursor: pointer; cursor: pointer;
padding: 0px 1px; padding-inline: 1px;
outline: none; outline: none;
} }
@ -172,18 +186,19 @@
} }
.input-group .input-description { .input-group .input-description {
width: 38px; width: 100%;
max-width: 38px;
height: 38px; height: 38px;
padding: 10px 0; display: flex;
justify-content: center;
align-items: center;
color: var(--gray-dark); color: var(--gray-dark);
background: var(--gray-light); background: var(--gray-light);
border-radius: 0px 5px 5px 0; border-radius: 0px 8px 8px 0;
border: 1px solid var(--gray-light); border: 1px solid var(--gray-light);
border-left: 0; border-left: 0;
text-align: center;
font-size: 14px; font-size: 14px;
line-height: 16px; line-height: 16px;
font-weight: 600;
} }
.input-group .square { .input-group .square {
@ -191,10 +206,19 @@
margin-left: 10px; margin-left: 10px;
} }
.input-group .square input {
text-align: center;
background: none;
padding: 0;
border: 0;
color: var(--gray-dark);
}
textarea { textarea {
resize: vertical; resize: none;
min-height: 200px; min-height: 200px;
border-radius: 8px; border-radius: 8px;
overflow-x: hidden;
} }
.custom-select { .custom-select {
@ -231,7 +255,7 @@
text-align: center; text-align: center;
padding: 40px 10px; padding: 40px 10px;
border-radius: 8px; border-radius: 8px;
margin: 20px 0 0; margin-top: 20px;
transition: all 0.5s ease-in-out; transition: all 0.5s ease-in-out;
} }
@ -253,7 +277,7 @@
width: 100%; width: 100%;
border-radius: 10px; border-radius: 10px;
outline: none; outline: none;
margin: 16px 0; margin-block: 15px;
} }
.range-slider::-webkit-slider-thumb { .range-slider::-webkit-slider-thumb {
@ -326,7 +350,7 @@
align-items: center; align-items: center;
width: auto; width: auto;
padding: 6px 12px; padding: 6px 12px;
margin: 10px 0 0; margin-top: 10px;
border-radius: 8px; border-radius: 8px;
transform: translateY(30px); transform: translateY(30px);
opacity: 0; opacity: 0;
@ -334,7 +358,7 @@
} }
.toast .toast-body { .toast .toast-body {
padding: 8px 0; padding-block: 8px;
font-weight: 600; font-weight: 600;
color: var(--text); color: var(--text);
letter-spacing: 0.5px; letter-spacing: 0.5px;
@ -360,7 +384,7 @@
height: 3px; height: 3px;
transform: scaleX(0); transform: scaleX(0);
transform-origin: left; transform-origin: left;
border-radius: inherit; border-radius: 8px;
} }
.toast.success .toast-progress { .toast.success .toast-progress {
@ -391,7 +415,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
padding: 0 0 20px; padding-bottom: 20px;
} }
.header .brand { .header .brand {
@ -410,18 +434,6 @@
cursor: pointer; cursor: pointer;
} }
.carousel img {
display: block;
width: 100%;
height: 100%;
margin-right: 20px;
border: 0;
}
.carousel img:last-child {
margin-right: 0;
}
.button { .button {
width: 100%; width: 100%;
border: 0; border: 0;
@ -429,7 +441,7 @@
border-radius: 50px; border-radius: 50px;
color: var(--text); color: var(--text);
cursor: pointer; cursor: pointer;
margin: 0 0 10px; margin-bottom: 10px;
background: var(--gray-medium); background: var(--gray-medium);
border: 1px solid var(--gray-dark); border: 1px solid var(--gray-dark);
transition: all 0.5s ease-in-out; transition: all 0.5s ease-in-out;
@ -477,7 +489,7 @@
} }
#recreatedImage { #recreatedImage {
margin: 20px 0; margin-block: 20px;
} }
.invalid { .invalid {
@ -487,7 +499,7 @@
.error-message { .error-message {
display: block; display: block;
color: var(--error-dark); color: var(--error-dark);
padding: 4px 0; padding-block: 4px;
font-weight: 600; font-weight: 600;
font-size: 12px; font-size: 12px;
} }
@ -506,7 +518,7 @@
.column, .column,
.column-full { .column-full {
flex-basis: 100%; flex-basis: 100%;
margin: 20px 0 0; margin-top: 20px;
padding: 0; padding: 0;
} }
} }
@ -686,19 +698,25 @@
max="255" max="255"
value="128" value="128"
class="range-slider" /> class="range-slider" />
<div class="input-description square">
<input <input
type="text" type="text"
name="brightnessValue"
id="brightnessValue" id="brightnessValue"
class="input-description square"
value="128" /> value="128" />
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="row"> <div class="row">
<div class="column" validate> <div class="column" validate>
<label for="animation">Animation</label> <label for="animation">Animation</label>
<label class="switch"> <label class="switch">
<input type="checkbox" name="animation" id="animation" /> <input
type="checkbox"
name="animation"
id="animation"
data-parent="animation" />
<span class="switch-slider"></span> <span class="switch-slider"></span>
</label> </label>
</div> </div>
@ -708,14 +726,20 @@
<input <input
type="checkbox" type="checkbox"
name="transparentImage" name="transparentImage"
id="transparentImage" /> id="transparentImage"
data-parent="transparentImage" />
<span class="switch-slider"></span> <span class="switch-slider"></span>
</label> </label>
</div> </div>
<div class="column" validate> <div class="column" validate>
<label for="resizeImage">Resize Image</label> <label for="resizeImage">Resize Image</label>
<label class="switch"> <label class="switch">
<input type="checkbox" name="resizeImage" id="resizeImage" /> <input
type="checkbox"
name="resizeImage"
id="resizeImage"
data-parent="resizeImage"
checked />
<span class="switch-slider"></span> <span class="switch-slider"></span>
</label> </label>
</div> </div>
@ -747,7 +771,9 @@
min="0" min="0"
step="0.1" step="0.1"
inputmode="numeric" /> inputmode="numeric" />
<div class="input-description">sec</div> <div class="input-description">
<span>sec</span>
</div>
</div> </div>
</div> </div>
<div class="column" validate> <div class="column" validate>
@ -762,7 +788,9 @@
min="0" min="0"
step="0.1" step="0.1"
inputmode="numeric" /> inputmode="numeric" />
<div class="input-description">sec</div> <div class="input-description">
<span>sec</span>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -853,7 +881,7 @@
<div id="overlay"></div> <div id="overlay"></div>
</body> </body>
<script> <script>
const d = document; const doc = document;
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
const host = params.get("hn") const host = params.get("hn")
? params.get("hn") ? params.get("hn")
@ -884,11 +912,12 @@
await segments(); await segments();
await images(); await images();
checked();
hostnameLabel(); hostnameLabel();
})(); })();
function element(id) { function element(id) {
return d.getElementById(id); return doc.getElementById(id);
} }
function hostnameLabel() { function hostnameLabel() {
@ -896,6 +925,18 @@
link.href = link.href.replace("[wled-ip]", hostname.value); link.href = link.href.replace("[wled-ip]", hostname.value);
} }
function checked() {
const checkbox = doc.querySelectorAll('input[type="checkbox"]');
checkbox.forEach((cb) => {
let parentName = cb.dataset.parent;
let parent = doc.getElementsByClassName(parentName)[0];
let { checked } = cb;
parent.style.display = checked ? "flex" : "none";
});
}
async function playlist() { async function playlist() {
const { value: duration } = element("duration"); const { value: duration } = element("duration");
const { value: transition } = element("transition"); const { value: transition } = element("transition");
@ -999,6 +1040,7 @@
if (success) { if (success) {
toast(`Preset "${item.n}" save successfully`); toast(`Preset "${item.n}" save successfully`);
window.parent.postMessage("loadPresets", WLED_URL);
} }
} catch (error) { } catch (error) {
toast(`Error saving preset: ${error}`, "error"); toast(`Error saving preset: ${error}`, "error");
@ -1216,7 +1258,7 @@
toast("Text copied to clipboard"); toast("Text copied to clipboard");
} catch (error) { } catch (error) {
try { try {
await d.execCommand("copy"); await doc.execCommand("copy");
toast("Text copied to clipboard"); toast("Text copied to clipboard");
} catch (error) { } catch (error) {
toast(error, "error"); toast(error, "error");
@ -1245,7 +1287,7 @@
}); });
element("output").addEventListener("change", (e) => { element("output").addEventListener("change", (e) => {
const output = d.getElementsByClassName("output"); const output = doc.getElementsByClassName("output");
const { value } = e.target.selectedOptions[0]; const { value } = e.target.selectedOptions[0];
Array.from(output).forEach(function (element) { Array.from(output).forEach(function (element) {
@ -1293,43 +1335,37 @@
}); });
element("transparentImage").addEventListener("change", (e) => { element("transparentImage").addEventListener("change", (e) => {
const transparentImage = d.getElementsByClassName("transparentImage"); const transparentImage = doc.getElementsByClassName("transparentImage")[0];
const { checked } = e.target; const { checked } = e.target;
Array.from(transparentImage).forEach(function (element) {
if (checked) { if (checked) {
element.style.display = "flex"; transparentImage.style.display = "flex";
} else { } else {
element.style.display = "none"; transparentImage.style.display = "none";
} }
}); });
});
element("resizeImage").addEventListener("change", (e) => { element("resizeImage").addEventListener("change", (e) => {
const resizeImage = d.getElementsByClassName("resizeImage"); const resizeImage = doc.getElementsByClassName("resizeImage")[0];
const pattern = element("pattern"); const pattern = element("pattern");
const { checked } = e.target; const { checked } = e.target;
Array.from(resizeImage).forEach(function (element) {
if (checked) { if (checked) {
pattern.value = 3; pattern.value = 3;
element.style.display = "flex"; resizeImage.style.display = "flex";
} else { } else {
pattern.value = 1; pattern.value = 1;
element.style.display = "none"; resizeImage.style.display = "none";
} }
}); });
});
element("animation").addEventListener("change", (e) => { element("animation").addEventListener("change", (e) => {
const animation = d.getElementsByClassName("animation"); const animation = doc.getElementsByClassName("animation")[0];
const pattern = element("pattern"); const pattern = element("pattern");
const source = element("source"); const source = element("source");
const { checked } = e.target; const { checked } = e.target;
Array.from(animation).forEach(function (element) {
if (checked) { if (checked) {
toast( toast(
'If you want all frames in the image, set it to "0"', 'If you want all frames in the image, set it to "0"',
@ -1338,18 +1374,17 @@
); );
source.setAttribute("accept", "image/gif"); source.setAttribute("accept", "image/gif");
element.style.display = "flex"; animation.style.display = "flex";
pattern.value = 3; pattern.value = 3;
} else { } else {
source.setAttribute( source.setAttribute(
"accept", "accept",
"image/jpg,image/jpeg,image/png,image/gif" "image/jpg,image/jpeg,image/png,image/gif"
); );
element.style.display = "none"; animation.style.display = "none";
pattern.value = 1; pattern.value = 1;
} }
}); });
});
element("btnGenerate").addEventListener("click", async (event) => { element("btnGenerate").addEventListener("click", async (event) => {
const { checked } = element("animation"); const { checked } = element("animation");
@ -1719,7 +1754,7 @@
} }
function createCanvas(width, height) { function createCanvas(width, height) {
const canvas = d.createElement("canvas"); const canvas = doc.createElement("canvas");
canvas.width = width; canvas.width = width;
canvas.height = height; canvas.height = height;
@ -1763,7 +1798,7 @@
const blob = new Blob([text], { type: mimeType }); const blob = new Blob([text], { type: mimeType });
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob);
const anchorElement = d.createElement("a"); const anchorElement = doc.createElement("a");
anchorElement.href = url; anchorElement.href = url;
anchorElement.download = `${filename}.${fileExtension}`; anchorElement.download = `${filename}.${fileExtension}`;
@ -1784,8 +1819,8 @@
[device]: { [device]: {
friendly_name, friendly_name,
unique_id, unique_id,
command_on: `curl -X POST "http://${hostname}/json/state" -d '${jsonData}' -H "Content-Type: application/json"`, command_on: `curl -X POST "http://${hostname}/json/state" -doc '${jsonData}' -H "Content-Type: application/json"`,
command_off: `curl -X POST "http://${hostname}/json/state" -d '{"on":false}' -H "Content-Type: application/json"`, command_off: `curl -X POST "http://${hostname}/json/state" -doc '{"on":false}' -H "Content-Type: application/json"`,
}, },
}, },
}; };
@ -1796,7 +1831,7 @@
function curl(jsonData) { function curl(jsonData) {
const { value: hostname } = element("hostname"); const { value: hostname } = element("hostname");
return `curl -X POST "http://${hostname}/json/state" -d '${jsonData}' -H "Content-Type: application/json"`; return `curl -X POST "http://${hostname}/json/state" -doc '${jsonData}' -H "Content-Type: application/json"`;
} }
function convertToYaml(obj) { function convertToYaml(obj) {
@ -1834,7 +1869,7 @@
hideElement = "preview" hideElement = "preview"
) { ) {
const hide = element(hideElement); const hide = element(hideElement);
const toast = d.createElement("div"); const toast = doc.createElement("div");
const wait = 100; const wait = 100;
toast.style.animation = "fadeIn"; toast.style.animation = "fadeIn";
@ -1843,14 +1878,14 @@
toast.classList.add("toast", type); toast.classList.add("toast", type);
const body = d.createElement("span"); const body = doc.createElement("span");
body.classList.add("toast-body"); body.classList.add("toast-body");
body.textContent = message; body.textContent = message;
toast.appendChild(body); toast.appendChild(body);
const progress = d.createElement("div"); const progress = doc.createElement("div");
progress.classList.add("toast-progress"); progress.classList.add("toast-progress");
progress.style.animation = "progress"; progress.style.animation = "progress";
@ -1875,7 +1910,7 @@
function carousel(id, images, delay = 3000) { function carousel(id, images, delay = 3000) {
let index = 0; let index = 0;
const carousel = d.createElement("div"); const carousel = doc.createElement("div");
carousel.classList.add("carousel"); carousel.classList.add("carousel");
images.forEach((canvas, i) => { images.forEach((canvas, i) => {
@ -1940,7 +1975,7 @@
overlay.style.display = "block"; overlay.style.display = "block";
overlay.style.cursor = "not-allowed"; overlay.style.cursor = "not-allowed";
d.body.style.overflow = "hidden"; doc.body.style.overflow = "hidden";
} }
function hide() { function hide() {
@ -1949,7 +1984,7 @@
overlay.style.display = "none"; overlay.style.display = "none";
overlay.style.cursor = "default"; overlay.style.cursor = "default";
d.body.style.overflow = "auto"; doc.body.style.overflow = "auto";
} }
function validate(event) { function validate(event) {
@ -1976,7 +2011,7 @@
let isVisible = true; let isVisible = true;
let tempParent = parent; let tempParent = parent;
while (tempParent !== d.body) { while (tempParent !== doc.body) {
const parentStyles = window.getComputedStyle(tempParent); const parentStyles = window.getComputedStyle(tempParent);
if ( if (
parentStyles.display === "none" || parentStyles.display === "none" ||
@ -2003,7 +2038,7 @@
let errorElement = parent.querySelector(".error-message"); let errorElement = parent.querySelector(".error-message");
if (!errorElement) { if (!errorElement) {
errorElement = d.createElement("div"); errorElement = doc.createElement("div");
errorElement.classList.add("error-message"); errorElement.classList.add("error-message");
parent.appendChild(errorElement); parent.appendChild(errorElement);
} }

View File

@ -26,7 +26,8 @@
"segpwr": "Hide segment power &amp; brightness", "segpwr": "Hide segment power &amp; brightness",
"segexp" : "Always expand first segment", "segexp" : "Always expand first segment",
"css": "Enable custom CSS", "css": "Enable custom CSS",
"hdays": "Enable custom Holidays list" "hdays": "Enable custom Holidays list",
"hdays": "Enable Pixel Magic Tool",
}, },
"theme":{ "theme":{
"alpha": { "alpha": {
@ -289,6 +290,7 @@
<div id="skin">Custom CSS: <input type="file" name="data" accept=".css"> <input type="button" value="Upload" onclick="uploadFile(d.Sf.data,'/skin.css');"><br></div> <div id="skin">Custom CSS: <input type="file" name="data" accept=".css"> <input type="button" value="Upload" onclick="uploadFile(d.Sf.data,'/skin.css');"><br></div>
<span class="l"></span>: <input type="checkbox" id="comp_hdays" class="agi cb"><br> <span class="l"></span>: <input type="checkbox" id="comp_hdays" class="agi cb"><br>
<div id="holidays">Holidays: <input type="file" name="data2" accept=".json"> <input type="button" value="Upload" onclick="uploadFile(d.Sf.data2,'/holidays.json');"><br></div> <div id="holidays">Holidays: <input type="file" name="data2" accept=".json"> <input type="button" value="Upload" onclick="uploadFile(d.Sf.data2,'/holidays.json');"><br></div>
<span class="l"></span>: <input type="checkbox" id="comp_pxm" class="agi cb"><br>
<div id="toast"></div> <div id="toast"></div>
<hr><button type="button" onclick="cLS()">Clear local storage</button> <hr><button type="button" onclick="cLS()">Clear local storage</button>
<hr><button type="button" onclick="B()">Back</button><button type="button" onclick="Save()">Save</button> <hr><button type="button" onclick="B()">Back</button><button type="button" onclick="Save()">Save</button>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff