iobroker.mywebui 1.37.66 → 1.37.68

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.66",
4
+ "version": "1.37.68",
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.66",
3
+ "version": "1.37.68",
4
4
  "description": "ioBroker mywebui - Custom edited mywebui by gokturk413",
5
5
  "type": "module",
6
6
  "main": "dist/backend/main.js",
@@ -878,18 +878,27 @@ export class IobrokerWebuiAppShell extends BaseCustomWebComponentConstructorAppe
878
878
  ['equal','='],['not_equal','≠'],['less_than','<'],['less_equal','≤'],
879
879
  ['greater_than','>'],['greater_equal','≥'],['exists','exists']
880
880
  ], ctrlCfg.condition || 'equal');
881
- condSel.style.cssText += 'width:70px;flex:none;margin-right:4px;';
881
+ condSel.style.cssText += 'flex:1;';
882
+ condSel.onchange = save;
883
+ const condRow = document.createElement('div');
884
+ condRow.style.cssText = 'display:flex;align-items:center;gap:4px;margin-bottom:4px;';
885
+ condRow.appendChild(this._makeBindSquare('condition', ctrlCfg, designItem, 'data-animation', saveAndRefresh));
886
+ condRow.appendChild(condSel);
887
+ wrap.appendChild(condRow);
882
888
  const valInp = document.createElement('input');
883
889
  valInp.type = 'text'; valInp.value = ctrlCfg.value ?? 'true';
884
890
  valInp.style.cssText = 'flex:1;padding:3px 5px;font-size:11px;border:1px solid #ccc;border-radius:3px;';
885
- condSel.onchange = save; valInp.onchange = save;
886
- const condRow = document.createElement('div');
887
- condRow.style.cssText = 'display:flex;gap:3px;';
888
- condRow.appendChild(condSel); condRow.appendChild(valInp);
889
- wrap.appendChild(condRow);
891
+ valInp.onchange = save;
892
+ const valRow = document.createElement('div');
893
+ valRow.style.cssText = 'display:flex;align-items:center;gap:4px;';
894
+ valRow.appendChild(this._makeBindSquare('value', ctrlCfg, designItem, 'data-animation', saveAndRefresh));
895
+ valRow.appendChild(valInp);
896
+ wrap.appendChild(valRow);
890
897
  wrap._getCtrl = () => {
891
898
  const v = { condition: condSel.value, value: valInp.value };
892
899
  if (ctrlCfg.oid_bind) v.oid_bind = ctrlCfg.oid_bind;
900
+ if (ctrlCfg.condition_bind) v.condition_bind = ctrlCfg.condition_bind;
901
+ if (ctrlCfg.value_bind) v.value_bind = ctrlCfg.value_bind;
893
902
  return v;
894
903
  };
895
904
  return wrap;
@@ -897,7 +906,8 @@ export class IobrokerWebuiAppShell extends BaseCustomWebComponentConstructorAppe
897
906
 
898
907
  const effectSel = sel([
899
908
  ['','— none —'],['opacity','Opacity'],['rotation','Rotation'],['scale','Scale'],
900
- ['translate','Translate XY'],['translateX','Translate X'],['translateY','Translate Y'],
909
+ ['translateX','Move X (relative)'],['translateY','Move Y (relative)'],['translate','Move XY (relative)'],
910
+ ['left','Move Left (absolute)'],['top','Move Top (absolute)'],
901
911
  ['skew','Skew'],['fill','Fill Color'],['transform','Transform (CSS)'],
902
912
  ['svg','SVG Attribute'],['morphSVG','MorphSVG'],['motionPath','Motion Path']
903
913
  ], cfg.effect || '');
@@ -1167,10 +1177,16 @@ export class IobrokerWebuiAppShell extends BaseCustomWebComponentConstructorAppe
1167
1177
  oidLabelText.textContent = 'OID';
1168
1178
  oidLabel.appendChild(oidLabelText);
1169
1179
  const condRowDiv = document.createElement('div');
1170
- condRowDiv.style.cssText = 'display:flex;gap:3px;margin-bottom:6px;padding-left:15px;';
1171
- condRowDiv.appendChild(condSel); condRowDiv.appendChild(condValInp);
1180
+ condRowDiv.style.cssText = 'display:flex;align-items:center;gap:4px;margin-bottom:4px;padding-left:4px;';
1181
+ condRowDiv.appendChild(this._makeBindSquare('condition', cfg, designItem, 'data-effects', saveAndRefresh));
1182
+ condRowDiv.appendChild(condSel);
1183
+ const condValRowDiv = document.createElement('div');
1184
+ condValRowDiv.style.cssText = 'display:flex;align-items:center;gap:4px;margin-bottom:6px;padding-left:4px;';
1185
+ condValRowDiv.appendChild(this._makeBindSquare('conditionValue', cfg, designItem, 'data-effects', saveAndRefresh));
1186
+ condValRowDiv.appendChild(condValInp);
1172
1187
  oidSection.appendChild(oidLabel);
1173
1188
  oidSection.appendChild(condRowDiv);
1189
+ oidSection.appendChild(condValRowDiv);
1174
1190
  content.appendChild(oidSection);
1175
1191
  triggerSel.addEventListener('change', () => { oidSection.style.display = triggerSel.value === 'oid' ? '' : 'none'; });
1176
1192
 
@@ -95,17 +95,39 @@ function buildTweenConfig(cfg, value) {
95
95
  case 'translateX':
96
96
  config.x = cfg.valueTo != null ? parseFloat(cfg.valueTo)
97
97
  : (typeof normalVal === 'boolean' ? (normalVal ? 100 : 0) : numVal);
98
+ if (cfg.valueFrom != null) config.startAt = { x: parseFloat(cfg.valueFrom) };
98
99
  break;
99
100
  case 'translateY':
100
101
  config.y = cfg.valueTo != null ? parseFloat(cfg.valueTo)
101
102
  : (typeof normalVal === 'boolean' ? (normalVal ? 100 : 0) : numVal);
103
+ if (cfg.valueFrom != null) config.startAt = { y: parseFloat(cfg.valueFrom) };
102
104
  break;
103
105
  case 'translate': {
104
- const tv = cfg.valueTo != null ? parseFloat(cfg.valueTo)
105
- : (typeof normalVal === 'boolean' ? (normalVal ? 100 : 0) : numVal);
106
- config.x = tv; config.y = tv;
106
+ // valueTo / valueFrom: "x,y" or single number (used for x, y=0)
107
+ const parseXY = (v, defVal) => {
108
+ if (v == null) return { x: defVal, y: 0 };
109
+ const s = String(v);
110
+ const parts = s.split(',');
111
+ return { x: parseFloat(parts[0]) || 0, y: parts.length > 1 ? parseFloat(parts[1]) || 0 : 0 };
112
+ };
113
+ const to = parseXY(cfg.valueTo, typeof normalVal === 'boolean' ? (normalVal ? 100 : 0) : numVal);
114
+ config.x = to.x; config.y = to.y;
115
+ if (cfg.valueFrom != null) {
116
+ const from = parseXY(cfg.valueFrom, 0);
117
+ config.startAt = { x: from.x, y: from.y };
118
+ }
107
119
  break;
108
120
  }
121
+ case 'left':
122
+ config.left = cfg.valueTo != null ? cfg.valueTo
123
+ : (typeof normalVal === 'boolean' ? (normalVal ? '100px' : '0px') : (numVal + 'px'));
124
+ if (cfg.valueFrom != null) config.startAt = { left: isNaN(cfg.valueFrom) ? cfg.valueFrom : cfg.valueFrom + 'px' };
125
+ break;
126
+ case 'top':
127
+ config.top = cfg.valueTo != null ? cfg.valueTo
128
+ : (typeof normalVal === 'boolean' ? (normalVal ? '100px' : '0px') : (numVal + 'px'));
129
+ if (cfg.valueFrom != null) config.startAt = { top: isNaN(cfg.valueFrom) ? cfg.valueFrom : cfg.valueFrom + 'px' };
130
+ break;
109
131
  case 'skew': {
110
132
  const sv = cfg.valueTo != null ? parseFloat(cfg.valueTo)
111
133
  : (typeof normalVal === 'boolean' ? (normalVal ? 45 : 0) : numVal);
@@ -160,30 +182,37 @@ class AnimationInstance {
160
182
  const ctrl = controls[key];
161
183
  if (!ctrl) return;
162
184
 
163
- // If OID itself is bound via binding square, resolve it first
164
- if (ctrl.oid_bind?.signal) {
185
+ // condition_bind: dynamically update which condition operator to use
186
+ if (ctrl.condition_bind?.signal) {
165
187
  try {
166
- const s = await iobrokerHandler.connection.getState(ctrl.oid_bind.signal);
167
- if (s?.val != null) ctrl.oid = String(s.val);
188
+ const s = await iobrokerHandler.connection.getState(ctrl.condition_bind.signal);
189
+ if (s?.val != null) ctrl.condition = String(s.val);
168
190
  } catch (e) {}
169
- const oidBindHandler = (id, state) => {
170
- if (state?.val != null) ctrl.oid = String(state.val);
171
- };
191
+ const h = (id, state) => { if (state?.val != null) ctrl.condition = String(state.val); };
192
+ try { iobrokerHandler.connection.subscribeState(ctrl.condition_bind.signal, h); this._subs.push({ oid: ctrl.condition_bind.signal, handler: h }); } catch (e) {}
193
+ }
194
+
195
+ // value_bind: dynamically update the trigger value
196
+ if (ctrl.value_bind?.signal) {
172
197
  try {
173
- iobrokerHandler.connection.subscribeState(ctrl.oid_bind.signal, oidBindHandler);
174
- this._subs.push({ oid: ctrl.oid_bind.signal, handler: oidBindHandler });
198
+ const s = await iobrokerHandler.connection.getState(ctrl.value_bind.signal);
199
+ if (s?.val != null) ctrl.value = String(s.val);
175
200
  } catch (e) {}
201
+ const h = (id, state) => { if (state?.val != null) ctrl.value = String(state.val); };
202
+ try { iobrokerHandler.connection.subscribeState(ctrl.value_bind.signal, h); this._subs.push({ oid: ctrl.value_bind.signal, handler: h }); } catch (e) {}
176
203
  }
177
204
 
178
- if (!ctrl.oid) return;
205
+ // oid_bind.signal IS the OID to watch (binding square directly holds the target OID)
206
+ const oid = ctrl.oid || ctrl.oid_bind?.signal;
207
+ if (!oid) return;
179
208
  const handler = (id, state) => {
180
209
  if (checkCond(state?.val, ctrl.condition || 'equal', ctrl.value ?? 'true')) action();
181
210
  };
182
211
  try {
183
- iobrokerHandler.connection.subscribeState(ctrl.oid, handler);
184
- this._subs.push({ oid: ctrl.oid, handler });
212
+ iobrokerHandler.connection.subscribeState(oid, handler);
213
+ this._subs.push({ oid, handler });
185
214
  } catch (e) {}
186
- iobrokerHandler.connection.getState(ctrl.oid).then(state => {
215
+ iobrokerHandler.connection.getState(oid).then(state => {
187
216
  if (state && checkCond(state.val, ctrl.condition || 'equal', ctrl.value ?? 'true')) action();
188
217
  }).catch(() => {});
189
218
  };
@@ -389,24 +418,26 @@ async function _applyEffect(el, cfg) {
389
418
  _clickFn = applyTween;
390
419
  el.addEventListener('click', _clickFn);
391
420
  } 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;
421
+ // condition_bind and conditionValue_bind
422
+ if (cfg.condition_bind?.signal) {
423
+ try { const s = await iobrokerHandler.connection.getState(cfg.condition_bind.signal); if (s?.val != null) cfg.condition = String(s.val); } catch (e) {}
424
+ const h = (id, state) => { if (state?.val != null) cfg.condition = String(state.val); };
425
+ try { iobrokerHandler.connection.subscribeState(cfg.condition_bind.signal, h); } catch (e) {}
426
+ }
427
+ if (cfg.conditionValue_bind?.signal) {
428
+ try { const s = await iobrokerHandler.connection.getState(cfg.conditionValue_bind.signal); if (s?.val != null) cfg.conditionValue = String(s.val); } catch (e) {}
429
+ const h = (id, state) => { if (state?.val != null) cfg.conditionValue = String(state.val); };
430
+ try { iobrokerHandler.connection.subscribeState(cfg.conditionValue_bind.signal, h); } catch (e) {}
402
431
  }
403
- if (cfg.oid) {
404
- _oidId = cfg.oid;
432
+ // oid_bind.signal IS the OID to watch (same as for animation controls)
433
+ const oid = cfg.oid || cfg.oid_bind?.signal;
434
+ if (oid) {
435
+ _oidId = oid;
405
436
  _oidHandler = (id, state) => {
406
437
  if (checkCond(state?.val, cfg.condition || 'equal', cfg.conditionValue ?? 'true')) applyTween();
407
438
  };
408
- try { iobrokerHandler.connection.subscribeState(cfg.oid, _oidHandler); } catch (e) {}
409
- iobrokerHandler.connection.getState(cfg.oid).then(state => {
439
+ try { iobrokerHandler.connection.subscribeState(oid, _oidHandler); } catch (e) {}
440
+ iobrokerHandler.connection.getState(oid).then(state => {
410
441
  if (state && checkCond(state.val, cfg.condition || 'equal', cfg.conditionValue ?? 'true')) applyTween();
411
442
  }).catch(() => {});
412
443
  }