Add the ability to set the shade and group display order #139 and suspend MQTT responses while updating the firmware.

This commit is contained in:
Robert Strouse 2023-09-04 10:33:53 -07:00
parent 92b9b679f9
commit 90b247e7d8
16 changed files with 498 additions and 482 deletions

View file

@ -1 +1 @@
2.1.4
2.1.5

View file

@ -3,11 +3,11 @@
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8">
<link rel="stylesheet" href="main.css?v=2.1.4" type="text/css" />
<link rel="stylesheet" href="widgets.css?v=2.1.4" type="text/css" />
<link rel="stylesheet" href="icons.css?v=2.1.4" type="text/css" />
<link rel="stylesheet" href="main.css?v=2.1.5p" type="text/css" />
<link rel="stylesheet" href="widgets.css?v=2.1.5p" type="text/css" />
<link rel="stylesheet" href="icons.css?v=2.1.5p" type="text/css" />
<link rel="icon" type="image/png" href="favicon.png" />
<script type="text/javascript" src="index.js?v=2.1.4"></script>
<script type="text/javascript" src="index.js?v=2.1.5p"></script>
</head>
<body>
<div id="divContainer" class="container main" data-auth="false">
@ -276,6 +276,7 @@
<div id="divSomfySettings" style="display:none;">
<div class="subtab-container"><span class="selected" data-grpid="divSomfyMotors">Shades</span><span data-grpid="divSomfyGroups">Groups</span></div>
<div id="divSomfyMotors" class="subtab-content" style="padding-top:10px;">
<div style="font-size:.8em;">Drag each item to set the order in which they appear in the list.</div>
<div id="divShadeListContainer">
<div id="divShadeList" class="edit-motorlist"></div>
<div class="button-container">
@ -456,10 +457,11 @@
</div>
</div>
<div id="divSomfyGroups" class="subtab-content" style="display:none;padding-top:10px;">
<div style="font-size:.8em;">Drag each item to set the order in which they appear in the list.</div>
<div id="divGroupListContainer">
<div id="divGroupList" class="edit-grouplist"></div>
<div class="button-container">
<button id="btnAddShade" type="button" onclick="somfy.openEditGroup();">
<button id="btnAddGroup" type="button" onclick="somfy.openEditGroup();">
Add Group
</button>
</div>

View file

@ -1197,7 +1197,7 @@ var security = new Security();
class General {
initialized = false;
appVersion = 'v2.1.4';
appVersion = 'v2.1.5';
reloadApp = false;
init() {
if (this.initialized) return;
@ -1931,12 +1931,16 @@ class Somfy {
}
btnDown = null;
btnTimer = null;
// Sort the array first to allow the user to drag and drop where they want the shade.
setShadesList(shades) {
let divCfg = '';
let divCtl = '';
shades.sort((a, b) => { return a.sortOrder - b.sortOrder });
console.log(shades);
for (let i = 0; i < shades.length; i++) {
let shade = shades[i];
divCfg += `<div class="somfyShade" data-shadeid="${shade.shadeId}" data-remoteaddress="${shade.remoteAddress}" data-tilt="${shade.tiltType}" data-shadetype="${shade.shadeType}">`;
divCfg += `<div class="somfyShade shade-draggable" draggable="true" data-shadeid="${shade.shadeId}" data-remoteaddress="${shade.remoteAddress}" data-tilt="${shade.tiltType}" data-shadetype="${shade.shadeType}">`;
divCfg += `<div class="button-outline" onclick="somfy.openEditShade(${shade.shadeId});"><i class="icss-edit"></i></div>`;
//divCfg += `<i class="shade-icon" data-position="${shade.position || 0}%"></i>`;
divCfg += `<span class="shade-name">${shade.name}</span>`;
@ -2083,14 +2087,87 @@ class Somfy {
}
}, true);
}
this.setListDraggable(document.getElementById('divShadeList'), '.shade-draggable', (list) => {
// Get the shade order
let items = list.querySelectorAll('.shade-draggable');
let order = [];
for (let i = 0; i < items.length; i++) {
order.push(parseInt(items[i].getAttribute('data-shadeid'), 10));
// Reorder the shades on the main page.
}
putJSONSync('/shadeSortOrder', order, (err) => {
for (let i = order.length - 1; i >= 0; i--) {
let el = shadeControls.querySelector(`.somfyShadeCtl[data-shadeid="${order[i]}"`);
if (el) {
shadeControls.prepend(el);
}
}
});
});
}
setListDraggable(list, itemclass, onChanged) {
let items = list.querySelectorAll(itemclass);
let changed = false;
[].forEach.call(items, (item) => {
item.addEventListener('dragstart', function(e) {
console.log({ evt: 'dragStart', e: e, this: this });
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.innerHTML);
e.stopPropagation();
this.style.opacity = '0.4';
this.classList.add('dragging');
});
item.addEventListener('dragenter', function (e) {
this.classList.add('over');
});
item.addEventListener('dragover', function(e) {
e.preventDefault();
e.dataTransfer.dropEffect = 'move';
return false;
});
item.addEventListener('dragleave', function(e) {
this.classList.remove('over');
});
item.addEventListener('drop', function(e) {
// Shift around the items.
console.log({ evt: 'drop', e: e, this: this });
let elDrag = list.querySelector('.dragging');
if (elDrag !== this) {
let curr = 0, end = 0;
for (let i = 0; i < items.length; i++) {
if (this === items[i]) end = i;
if (elDrag === items[i]) curr = i;
}
console.log({ drag: elDrag, curr: curr, end: end, before: curr < end });
if (curr !== end) {
this.before(elDrag);
changed = true;
}
}
});
item.addEventListener('dragend', function (e) {
[].forEach.call(items, (item) => { item.classList.remove('over') });
this.style.opacity = '1';
//overCounter = 0;
this.classList.remove('dragging');
if (changed && typeof onChanged === 'function') {
onChanged(list);
}
//console.log(e);
});
});
}
setGroupsList(groups) {
let divCfg = '';
let divCtl = '';
if (typeof groups !== 'undefined') {
groups.sort((a, b) => { return a.sortOrder - b.sortOrder });
for (let i = 0; i < groups.length; i++) {
let group = groups[i];
divCfg += `<div class="somfyGroup" data-groupid="${group.groupId}" data-remoteaddress="${group.remoteAddress}">`;
divCfg += `<div class="somfyGroup group-draggable" draggable="true" data-groupid="${group.groupId}" data-remoteaddress="${group.remoteAddress}">`;
divCfg += `<div class="button-outline" onclick="somfy.openEditGroup(${group.groupId});"><i class="icss-edit"></i></div>`;
//divCfg += `<i class="Group-icon" data-position="${Group.position || 0}%"></i>`;
divCfg += `<span class="group-name">${group.name}</span>`;
@ -2140,6 +2217,24 @@ class Somfy {
this.sendGroupCommand(groupId, cmd);
}, true);
}
this.setListDraggable(document.getElementById('divGroupList'), '.group-draggable', (list) => {
// Get the shade order
let items = list.querySelectorAll('.group-draggable');
let order = [];
for (let i = 0; i < items.length; i++) {
order.push(parseInt(items[i].getAttribute('data-groupid'), 10));
// Reorder the shades on the main page.
}
putJSONSync('/groupSortOrder', order, (err) => {
for (let i = order.length - 1; i >= 0; i--) {
let el = groupControls.querySelector(`.somfyGroupCtl[data-groupid="${order[i]}"`);
if (el) {
groupControls.prepend(el);
}
}
});
});
}
closeShadePositioners() {
let ctls = document.querySelectorAll('.shade-positioner');

View file

@ -43,6 +43,7 @@ input[type="range"] {
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
cursor:pointer;
}
.button-outline:active {
-webkit-animation: flicker .5s infinite linear;

View file

@ -128,6 +128,7 @@
.shadectl-buttons[data-shadetype="5"] > .button-outline[data-cmd="down"] {
display: none;
}
.shadectl-buttons:not([data-shadetype="5"]) > .button-outline[data-cmd="toggle"],
.shadectl-buttons[data-shadetype="0"] > .button-outline[data-cmd="toggle"],
.shadectl-buttons[data-shadetype="1"] > .button-outline[data-cmd="toggle"],
.shadectl-buttons[data-shadetype="2"] > .button-outline[data-cmd="toggle"],
@ -141,3 +142,19 @@
#somfyShade[data-shadetype="6"] #divStepSettings {
display:none;
}
.group-draggable,
.shade-draggable {
height:32px;
border-top:solid 2px transparent;
cursor:grab;
}
.group-draggable.dragging *,
.group-draggable.over *,
.shade-draggable.dragging *,
.shade-draggable.over * {
pointer-events: none;
}
.group-draggable.over,
.shade-draggable.over {
border-top: solid 2px var(--shade-color, '#00bcd4');
}