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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "mywebui",
4
- "version": "1.37.64",
4
+ "version": "1.37.66",
5
5
  "titleLang": {
6
6
  "en": "mywebui",
7
7
  "de": "mywebui",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.mywebui",
3
- "version": "1.37.64",
3
+ "version": "1.37.66",
4
4
  "description": "ioBroker mywebui - Custom edited mywebui by gokturk413",
5
5
  "type": "module",
6
6
  "main": "dist/backend/main.js",
@@ -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.textContent = label;
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 = () => ({ oid: oidInp.value || undefined, condition: condSel.value, value: valInp.value });
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' && oidInp.value) {
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:15px;';
1184
- oidLabel.textContent = 'OID';
1185
- const oidRowDiv = document.createElement('div');
1186
- oidRowDiv.style.cssText = 'display:flex;gap:3px;margin-bottom:4px;padding-left:15px;';
1187
- oidRowDiv.appendChild(oidInp); oidRowDiv.appendChild(oidPickBtn);
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?.oid) return;
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 != null) {
192
- this.cfg[propCapture] = state.val;
193
- // Rebuild tween if currently playing
194
- if (this.tween && !this.tween.paused()) this._play();
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' && cfg.oid) {
364
- _oidId = cfg.oid;
365
- _oidHandler = (id, state) => {
366
- if (checkCond(state?.val, cfg.condition || 'equal', cfg.conditionValue ?? 'true')) applyTween();
367
- };
368
- try { iobrokerHandler.connection.subscribeState(cfg.oid, _oidHandler); } catch (e) {}
369
- iobrokerHandler.connection.getState(cfg.oid).then(state => {
370
- if (state && checkCond(state.val, cfg.condition || 'equal', cfg.conditionValue ?? 'true')) applyTween();
371
- }).catch(() => {});
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 () => {