iobroker.mywebui 1.37.64 → 1.37.66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/io-package.json
CHANGED
package/package.json
CHANGED
|
@@ -767,7 +767,7 @@ export class IobrokerWebuiAppShell extends BaseCustomWebComponentConstructorAppe
|
|
|
767
767
|
const collectAnimCfg = () => {
|
|
768
768
|
const e = effectSel.value;
|
|
769
769
|
const c = {};
|
|
770
|
-
const addCtrl = (key, row) => { const v = row._getCtrl(); if (v.oid) c[key] = v; };
|
|
770
|
+
const addCtrl = (key, row) => { const v = row._getCtrl(); if (v.oid || v.oid_bind) c[key] = v; };
|
|
771
771
|
addCtrl('play', playCtrl); addCtrl('pause', pauseCtrl);
|
|
772
772
|
addCtrl('resume', resumeCtrl); addCtrl('stop', stopCtrl);
|
|
773
773
|
addCtrl('reverse', reverseCtrl);
|
|
@@ -868,25 +868,12 @@ export class IobrokerWebuiAppShell extends BaseCustomWebComponentConstructorAppe
|
|
|
868
868
|
const wrap = document.createElement('div');
|
|
869
869
|
wrap.style.cssText = 'border:1px solid #eee;border-radius:3px;padding:6px;margin-bottom:6px;background:#fafafa;';
|
|
870
870
|
const head = document.createElement('div');
|
|
871
|
-
head.style.cssText = 'font-size:11px;font-weight:600;color:#444;margin-bottom:5px;';
|
|
872
|
-
head.
|
|
871
|
+
head.style.cssText = 'display:flex;align-items:center;gap:4px;font-size:11px;font-weight:600;color:#444;margin-bottom:5px;';
|
|
872
|
+
head.appendChild(this._makeBindSquare('oid', ctrlCfg, designItem, 'data-animation', saveAndRefresh));
|
|
873
|
+
const headText = document.createElement('span');
|
|
874
|
+
headText.textContent = label;
|
|
875
|
+
head.appendChild(headText);
|
|
873
876
|
wrap.appendChild(head);
|
|
874
|
-
const oidInp = document.createElement('input');
|
|
875
|
-
oidInp.type = 'text'; oidInp.value = ctrlCfg.oid || '';
|
|
876
|
-
oidInp.placeholder = 'OID…';
|
|
877
|
-
oidInp.style.cssText = 'width:100%;box-sizing:border-box;padding:3px 5px;font-size:11px;border:1px solid #ccc;border-radius:3px;margin-bottom:3px;';
|
|
878
|
-
oidInp.onchange = save;
|
|
879
|
-
const pickBtn = document.createElement('button');
|
|
880
|
-
pickBtn.textContent = '…';
|
|
881
|
-
pickBtn.style.cssText = 'padding:2px 6px;font-size:11px;cursor:pointer;border:1px solid #aaa;border-radius:3px;margin-left:3px;';
|
|
882
|
-
pickBtn.onclick = async () => {
|
|
883
|
-
const picked = await openSelectIdDialog(document.body, { id: oidInp.value });
|
|
884
|
-
if (picked) { oidInp.value = picked; save(); }
|
|
885
|
-
};
|
|
886
|
-
const oidRow2 = document.createElement('div');
|
|
887
|
-
oidRow2.style.cssText = 'display:flex;margin-bottom:3px;';
|
|
888
|
-
oidRow2.appendChild(oidInp); oidRow2.appendChild(pickBtn);
|
|
889
|
-
wrap.appendChild(oidRow2);
|
|
890
877
|
const condSel = sel([
|
|
891
878
|
['equal','='],['not_equal','≠'],['less_than','<'],['less_equal','≤'],
|
|
892
879
|
['greater_than','>'],['greater_equal','≥'],['exists','exists']
|
|
@@ -900,7 +887,11 @@ export class IobrokerWebuiAppShell extends BaseCustomWebComponentConstructorAppe
|
|
|
900
887
|
condRow.style.cssText = 'display:flex;gap:3px;';
|
|
901
888
|
condRow.appendChild(condSel); condRow.appendChild(valInp);
|
|
902
889
|
wrap.appendChild(condRow);
|
|
903
|
-
wrap._getCtrl = () =>
|
|
890
|
+
wrap._getCtrl = () => {
|
|
891
|
+
const v = { condition: condSel.value, value: valInp.value };
|
|
892
|
+
if (ctrlCfg.oid_bind) v.oid_bind = ctrlCfg.oid_bind;
|
|
893
|
+
return v;
|
|
894
|
+
};
|
|
904
895
|
return wrap;
|
|
905
896
|
};
|
|
906
897
|
|
|
@@ -1064,8 +1055,7 @@ export class IobrokerWebuiAppShell extends BaseCustomWebComponentConstructorAppe
|
|
|
1064
1055
|
if (parseFloat(delayInp.value)) out.delay = parseFloat(delayInp.value);
|
|
1065
1056
|
if (parseInt(repeatInp.value)) out.repeat = parseInt(repeatInp.value);
|
|
1066
1057
|
out.ease = easeSel.value || 'power2.out';
|
|
1067
|
-
if (triggerSel.value === 'oid'
|
|
1068
|
-
out.oid = oidInp.value;
|
|
1058
|
+
if (triggerSel.value === 'oid') {
|
|
1069
1059
|
out.condition = condSel.value;
|
|
1070
1060
|
out.conditionValue = condValInp.value;
|
|
1071
1061
|
}
|
|
@@ -1146,21 +1136,12 @@ export class IobrokerWebuiAppShell extends BaseCustomWebComponentConstructorAppe
|
|
|
1146
1136
|
['elastic.out(1,0.3)','elastic.out'],['back.inOut(1.7)','back.inOut'],['none','none']
|
|
1147
1137
|
], cfg.ease || 'power2.out');
|
|
1148
1138
|
|
|
1149
|
-
const oidInp = inp(cfg.oid || '');
|
|
1150
1139
|
const condSel = sel([['equal','='],['not_equal','≠'],['less_than','<'],['greater_than','>'],['exists','exists']], cfg.condition || 'equal');
|
|
1151
1140
|
const condValInp = inp(cfg.conditionValue ?? 'true');
|
|
1152
1141
|
const glowColorInp = inp(cfg.glowColor || 'yellow', 'color');
|
|
1153
1142
|
const glowSizeInp = inp(cfg.glowSize || 10, 'number');
|
|
1154
1143
|
const blurInp = inp(cfg.blurAmount || 5, 'number');
|
|
1155
1144
|
|
|
1156
|
-
const oidPickBtn = document.createElement('button');
|
|
1157
|
-
oidPickBtn.textContent = '…';
|
|
1158
|
-
oidPickBtn.style.cssText = 'padding:2px 6px;font-size:11px;cursor:pointer;border:1px solid #aaa;border-radius:3px;flex-shrink:0;';
|
|
1159
|
-
oidPickBtn.onclick = async () => {
|
|
1160
|
-
const picked = await openSelectIdDialog(document.body, { id: oidInp.value });
|
|
1161
|
-
if (picked) { oidInp.value = picked; save(); }
|
|
1162
|
-
};
|
|
1163
|
-
|
|
1164
1145
|
// ── Build UI ──────────────────────────────────────────────────────────
|
|
1165
1146
|
content.innerHTML = '';
|
|
1166
1147
|
|
|
@@ -1180,16 +1161,15 @@ export class IobrokerWebuiAppShell extends BaseCustomWebComponentConstructorAppe
|
|
|
1180
1161
|
const oidSection = document.createElement('div');
|
|
1181
1162
|
oidSection.style.display = cfg.trigger === 'oid' ? '' : 'none';
|
|
1182
1163
|
const oidLabel = document.createElement('div');
|
|
1183
|
-
oidLabel.style.cssText = 'font-size:11px;font-weight:600;color:#555;margin-bottom:3px;padding-left:
|
|
1184
|
-
oidLabel.
|
|
1185
|
-
const
|
|
1186
|
-
|
|
1187
|
-
|
|
1164
|
+
oidLabel.style.cssText = 'display:flex;align-items:center;gap:4px;font-size:11px;font-weight:600;color:#555;margin-bottom:3px;padding-left:4px;';
|
|
1165
|
+
oidLabel.appendChild(this._makeBindSquare('oid', cfg, designItem, 'data-effects', saveAndRefresh));
|
|
1166
|
+
const oidLabelText = document.createElement('span');
|
|
1167
|
+
oidLabelText.textContent = 'OID';
|
|
1168
|
+
oidLabel.appendChild(oidLabelText);
|
|
1188
1169
|
const condRowDiv = document.createElement('div');
|
|
1189
1170
|
condRowDiv.style.cssText = 'display:flex;gap:3px;margin-bottom:6px;padding-left:15px;';
|
|
1190
1171
|
condRowDiv.appendChild(condSel); condRowDiv.appendChild(condValInp);
|
|
1191
1172
|
oidSection.appendChild(oidLabel);
|
|
1192
|
-
oidSection.appendChild(oidRowDiv);
|
|
1193
1173
|
oidSection.appendChild(condRowDiv);
|
|
1194
1174
|
content.appendChild(oidSection);
|
|
1195
1175
|
triggerSel.addEventListener('change', () => { oidSection.style.display = triggerSel.value === 'oid' ? '' : 'none'; });
|
|
@@ -156,9 +156,26 @@ class AnimationInstance {
|
|
|
156
156
|
if (!window.gsap) return;
|
|
157
157
|
const controls = this.cfg.controls || {};
|
|
158
158
|
|
|
159
|
-
const bindControl = (key, action) => {
|
|
159
|
+
const bindControl = async (key, action) => {
|
|
160
160
|
const ctrl = controls[key];
|
|
161
|
-
if (!ctrl
|
|
161
|
+
if (!ctrl) return;
|
|
162
|
+
|
|
163
|
+
// If OID itself is bound via binding square, resolve it first
|
|
164
|
+
if (ctrl.oid_bind?.signal) {
|
|
165
|
+
try {
|
|
166
|
+
const s = await iobrokerHandler.connection.getState(ctrl.oid_bind.signal);
|
|
167
|
+
if (s?.val != null) ctrl.oid = String(s.val);
|
|
168
|
+
} catch (e) {}
|
|
169
|
+
const oidBindHandler = (id, state) => {
|
|
170
|
+
if (state?.val != null) ctrl.oid = String(state.val);
|
|
171
|
+
};
|
|
172
|
+
try {
|
|
173
|
+
iobrokerHandler.connection.subscribeState(ctrl.oid_bind.signal, oidBindHandler);
|
|
174
|
+
this._subs.push({ oid: ctrl.oid_bind.signal, handler: oidBindHandler });
|
|
175
|
+
} catch (e) {}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (!ctrl.oid) return;
|
|
162
179
|
const handler = (id, state) => {
|
|
163
180
|
if (checkCond(state?.val, ctrl.condition || 'equal', ctrl.value ?? 'true')) action();
|
|
164
181
|
};
|
|
@@ -171,11 +188,11 @@ class AnimationInstance {
|
|
|
171
188
|
}).catch(() => {});
|
|
172
189
|
};
|
|
173
190
|
|
|
174
|
-
bindControl('play', () => this._play());
|
|
175
|
-
bindControl('pause', () => this.tween?.pause());
|
|
176
|
-
bindControl('resume', () => this.tween?.play());
|
|
177
|
-
bindControl('stop', () => this.tween?.pause(0));
|
|
178
|
-
bindControl('reverse', () => this.tween?.reverse());
|
|
191
|
+
await bindControl('play', () => this._play());
|
|
192
|
+
await bindControl('pause', () => this.tween?.pause());
|
|
193
|
+
await bindControl('resume', () => this.tween?.play());
|
|
194
|
+
await bindControl('stop', () => this.tween?.pause(0));
|
|
195
|
+
await bindControl('reverse', () => this.tween?.reverse());
|
|
179
196
|
|
|
180
197
|
// Dynamic property bindings — each prop can have a propKey_bind: {signal, expression}
|
|
181
198
|
const dynamicProps = [
|
|
@@ -183,16 +200,27 @@ class AnimationInstance {
|
|
|
183
200
|
'fillColorFrom', 'fillColorTo', 'transformOriginX', 'transformOriginY',
|
|
184
201
|
'svgAttr', 'pathId', 'alignToPath', 'orientToPath'
|
|
185
202
|
];
|
|
203
|
+
let _restartTimer = null;
|
|
186
204
|
for (const prop of dynamicProps) {
|
|
187
205
|
const bindCfg = this.cfg[prop + '_bind'];
|
|
188
206
|
if (!bindCfg?.signal) continue;
|
|
189
207
|
const propCapture = prop;
|
|
190
208
|
const handler = (id, state) => {
|
|
191
|
-
if (state?.val
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
209
|
+
if (state?.val == null) return;
|
|
210
|
+
this.cfg[propCapture] = state.val;
|
|
211
|
+
if (!this.tween) return;
|
|
212
|
+
// Duration: adjust timeScale without restarting (smooth for repeat:-1)
|
|
213
|
+
if (propCapture === 'duration' && this.tween.vars) {
|
|
214
|
+
const origDur = parseFloat(this.tween.vars.duration) || 1;
|
|
215
|
+
const newDur = parseFloat(state.val) || 1;
|
|
216
|
+
this.tween.timeScale(origDur / newDur);
|
|
217
|
+
return;
|
|
195
218
|
}
|
|
219
|
+
// Other props: debounced restart so rapid changes don't freeze
|
|
220
|
+
clearTimeout(_restartTimer);
|
|
221
|
+
_restartTimer = setTimeout(() => {
|
|
222
|
+
if (this.tween && !this.tween.paused()) this._play();
|
|
223
|
+
}, 60);
|
|
196
224
|
};
|
|
197
225
|
try {
|
|
198
226
|
iobrokerHandler.connection.subscribeState(bindCfg.signal, handler);
|
|
@@ -360,15 +388,28 @@ async function _applyEffect(el, cfg) {
|
|
|
360
388
|
} else if (cfg.trigger === 'click') {
|
|
361
389
|
_clickFn = applyTween;
|
|
362
390
|
el.addEventListener('click', _clickFn);
|
|
363
|
-
} else if (cfg.trigger === 'oid'
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
391
|
+
} else if (cfg.trigger === 'oid') {
|
|
392
|
+
// Resolve OID — may come from a binding square binding
|
|
393
|
+
if (cfg.oid_bind?.signal) {
|
|
394
|
+
try {
|
|
395
|
+
const s = await iobrokerHandler.connection.getState(cfg.oid_bind.signal);
|
|
396
|
+
if (s?.val != null) cfg.oid = String(s.val);
|
|
397
|
+
} catch (e) {}
|
|
398
|
+
const oidBindHandler = (id, state) => { if (state?.val != null) cfg.oid = String(state.val); };
|
|
399
|
+
try { iobrokerHandler.connection.subscribeState(cfg.oid_bind.signal, oidBindHandler); } catch (e) {}
|
|
400
|
+
_oidId = cfg.oid_bind.signal;
|
|
401
|
+
_oidHandler = oidBindHandler;
|
|
402
|
+
}
|
|
403
|
+
if (cfg.oid) {
|
|
404
|
+
_oidId = cfg.oid;
|
|
405
|
+
_oidHandler = (id, state) => {
|
|
406
|
+
if (checkCond(state?.val, cfg.condition || 'equal', cfg.conditionValue ?? 'true')) applyTween();
|
|
407
|
+
};
|
|
408
|
+
try { iobrokerHandler.connection.subscribeState(cfg.oid, _oidHandler); } catch (e) {}
|
|
409
|
+
iobrokerHandler.connection.getState(cfg.oid).then(state => {
|
|
410
|
+
if (state && checkCond(state.val, cfg.condition || 'equal', cfg.conditionValue ?? 'true')) applyTween();
|
|
411
|
+
}).catch(() => {});
|
|
412
|
+
}
|
|
372
413
|
}
|
|
373
414
|
|
|
374
415
|
return () => {
|