@flexem/fc-gui 3.0.0-alpha.17 → 3.0.0-alpha.171

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.
Files changed (193) hide show
  1. package/CHANGELOG.md +424 -1
  2. package/assets/img/black_first_page.png +0 -0
  3. package/assets/img/black_last_page.png +0 -0
  4. package/assets/img/black_next_page.png +0 -0
  5. package/assets/img/black_previous_page.png +0 -0
  6. package/assets/img/exclamation-outline-circle.png +0 -0
  7. package/bundles/@flexem/fc-gui.umd.js +39304 -34437
  8. package/bundles/@flexem/fc-gui.umd.js.map +1 -1
  9. package/bundles/@flexem/fc-gui.umd.min.js +5 -5
  10. package/bundles/@flexem/fc-gui.umd.min.js.map +1 -1
  11. package/communication/variable/variable-communicator.d.ts +5 -0
  12. package/communication/variable/variable-state-enum.d.ts +1 -0
  13. package/communication/variable/variable-state-enum.js +1 -0
  14. package/communication/variable/variable-state-enum.metadata.json +1 -1
  15. package/communication/variable/variable-value.d.ts +4 -1
  16. package/communication/variable/variable-value.js +4 -1
  17. package/communication/variable/variable-value.metadata.json +1 -1
  18. package/config/alarm/alarm.store.d.ts +6 -0
  19. package/config/alarm/alarm.store.js +0 -0
  20. package/config/alarm/alarm.store.metadata.json +1 -0
  21. package/config/alarm/get-alarms-args.d.ts +12 -0
  22. package/config/alarm/get-alarms-args.js +13 -0
  23. package/config/alarm/get-alarms-args.metadata.json +1 -0
  24. package/config/alarm/index.d.ts +2 -0
  25. package/config/alarm/index.js +1 -0
  26. package/config/alarm/index.metadata.json +1 -0
  27. package/config/config-store.d.ts +2 -0
  28. package/config/gui-feature-config.d.ts +3 -0
  29. package/config/gui-feature-config.js +3 -0
  30. package/config/gui-feature-config.metadata.json +1 -0
  31. package/config/index.d.ts +2 -0
  32. package/config/index.js +2 -0
  33. package/config/index.metadata.json +1 -1
  34. package/config/variable/variable-store.d.ts +1 -0
  35. package/elements/air-quality/air-quality-element.d.ts +31 -0
  36. package/elements/air-quality/air-quality-element.js +194 -0
  37. package/elements/air-quality/air-quality-element.metadata.json +1 -0
  38. package/elements/alarm/alarm-element.d.ts +69 -0
  39. package/elements/alarm/alarm-element.js +497 -0
  40. package/elements/alarm/alarm-element.metadata.json +1 -0
  41. package/elements/bar-graph-element.d.ts +10 -2
  42. package/elements/bar-graph-element.js +135 -5
  43. package/elements/bar-graph-element.metadata.json +1 -1
  44. package/elements/base/readable-element.d.ts +6 -1
  45. package/elements/base/readable-element.js +66 -2
  46. package/elements/base/readable-element.metadata.json +1 -1
  47. package/elements/base/state-control-element.d.ts +3 -1
  48. package/elements/base/state-control-element.js +21 -5
  49. package/elements/character-display/character-display-element.js +3 -2
  50. package/elements/character-display/character-display-element.metadata.json +1 -1
  51. package/elements/datetime-display/datetime-display-element.d.ts +1 -0
  52. package/elements/datetime-display/datetime-display-element.js +10 -2
  53. package/elements/datetime-display/datetime-display-element.metadata.json +1 -1
  54. package/elements/datetime-display/time-zone-select-json.d.ts +8 -0
  55. package/elements/datetime-display/time-zone-select-json.js +558 -0
  56. package/elements/historical-curve/historical-curve.element.d.ts +41 -3
  57. package/elements/historical-curve/historical-curve.element.js +662 -32
  58. package/elements/historical-curve/historical-curve.element.metadata.json +1 -1
  59. package/elements/main-element.d.ts +1 -0
  60. package/elements/main-element.js +75 -9
  61. package/elements/main-element.metadata.json +1 -1
  62. package/elements/meter-element.d.ts +7 -1
  63. package/elements/meter-element.js +76 -7
  64. package/elements/meter-element.metadata.json +1 -1
  65. package/elements/numerical-display/numerical-display-element.d.ts +22 -3
  66. package/elements/numerical-display/numerical-display-element.js +145 -12
  67. package/elements/numerical-display/numerical-display-element.metadata.json +1 -1
  68. package/elements/per-view-variable-communicator.d.ts +4 -0
  69. package/elements/per-view-variable-communicator.js +21 -1
  70. package/elements/per-view-variable-communicator.metadata.json +1 -1
  71. package/elements/ring-graph/ring-graph-element.d.ts +13 -1
  72. package/elements/ring-graph/ring-graph-element.js +164 -3
  73. package/elements/ring-graph/ring-graph-element.metadata.json +1 -1
  74. package/elements/scroll-alarm/scroll-alarm-element.d.ts +78 -0
  75. package/elements/scroll-alarm/scroll-alarm-element.js +843 -0
  76. package/elements/scroll-alarm/scroll-alarm-element.metadata.json +1 -0
  77. package/elements/shared/graph/graph-state-element.d.ts +1 -0
  78. package/elements/shared/graph/graph-state-element.js +30 -1
  79. package/elements/shared/graph/graph-state-element.metadata.json +1 -1
  80. package/elements/shared/text/text-element.d.ts +14 -0
  81. package/elements/shared/text/text-element.js +42 -4
  82. package/elements/shared/text/text-element.metadata.json +1 -1
  83. package/elements/shared/text/text-state-element.d.ts +39 -2
  84. package/elements/shared/text/text-state-element.js +242 -67
  85. package/elements/shared/text/text-state-element.metadata.json +1 -1
  86. package/elements/static-elements/hyperlink-element.d.ts +28 -2
  87. package/elements/static-elements/hyperlink-element.js +153 -4
  88. package/elements/static-elements/hyperlink-element.metadata.json +1 -1
  89. package/elements/static-elements/text-element.d.ts +28 -2
  90. package/elements/static-elements/text-element.js +162 -12
  91. package/elements/static-elements/text-element.metadata.json +1 -1
  92. package/elements/switch-indicator-light/bit-indicator-light-operator.d.ts +1 -0
  93. package/elements/switch-indicator-light/bit-indicator-light-operator.js +10 -3
  94. package/elements/switch-indicator-light/bit-indicator-light-operator.metadata.json +1 -1
  95. package/elements/switch-indicator-light/switch-indicator-light-element.d.ts +11 -2
  96. package/elements/switch-indicator-light/switch-indicator-light-element.js +70 -12
  97. package/elements/switch-indicator-light/switch-indicator-light-element.metadata.json +1 -1
  98. package/elements/switch-indicator-light/word-indicator-light-operator.d.ts +1 -0
  99. package/elements/switch-indicator-light/word-indicator-light-operator.js +10 -3
  100. package/elements/switch-indicator-light/word-indicator-light-operator.metadata.json +1 -1
  101. package/elements/video/video-element.d.ts +10 -0
  102. package/elements/video/video-element.js +119 -21
  103. package/elements/video/video-element.metadata.json +1 -1
  104. package/elements/view-operation/view-operation.element.d.ts +28 -2
  105. package/elements/view-operation/view-operation.element.js +163 -4
  106. package/elements/view-operation/view-operation.element.metadata.json +1 -1
  107. package/elements/weather/weater-element.js +0 -1
  108. package/gui/gui-context.d.ts +25 -2
  109. package/gui/gui-host.d.ts +1 -1
  110. package/gui/gui-view.d.ts +4 -1
  111. package/gui/gui-view.js +69 -8
  112. package/gui/gui-view.metadata.json +1 -1
  113. package/gui/gui.component.d.ts +3 -0
  114. package/gui/gui.component.js +15 -2
  115. package/gui/gui.component.metadata.json +1 -1
  116. package/localization/localization.service.d.ts +12 -0
  117. package/localization/localization.service.js +16 -4
  118. package/localization/localization.service.metadata.json +1 -1
  119. package/localization/localization.service.zh_CN.js +14 -2
  120. package/localization/localization.service.zh_CN.metadata.json +1 -1
  121. package/modal/write-character/write-character-modal.component.html +4 -4
  122. package/modal/write-character/write-character-modal.component.js +2 -2
  123. package/modal/write-character/write-character-modal.component.less +15 -0
  124. package/modal/write-character/write-character-modal.component.metadata.json +1 -1
  125. package/modal/write-value/write-value-modal-args.d.ts +5 -1
  126. package/modal/write-value/write-value-modal-args.js +3 -1
  127. package/modal/write-value/write-value-modal-args.metadata.json +1 -1
  128. package/modal/write-value/write-value-modal.component.d.ts +13 -7
  129. package/modal/write-value/write-value-modal.component.html +10 -5
  130. package/modal/write-value/write-value-modal.component.js +95 -20
  131. package/modal/write-value/write-value-modal.component.less +16 -1
  132. package/modal/write-value/write-value-modal.component.metadata.json +1 -1
  133. package/model/air-quality/air-quality-info.d.ts +23 -0
  134. package/model/air-quality/air-quality-info.js +4 -0
  135. package/model/air-quality/air-quality-info.metadata.json +1 -0
  136. package/model/air-quality/air-quality.model.d.ts +7 -0
  137. package/model/air-quality/air-quality.model.js +0 -0
  138. package/model/air-quality/air-quality.model.metadata.json +1 -0
  139. package/model/alarm/alarm.model.d.ts +13 -0
  140. package/model/alarm/alarm.model.js +0 -0
  141. package/model/alarm/alarm.model.metadata.json +1 -0
  142. package/model/bar-graph/bar-graph.d.ts +4 -0
  143. package/model/base/font-setting-model.d.ts +22 -1
  144. package/model/base/font-setting-model.metadata.json +1 -1
  145. package/model/base/readable-model.d.ts +4 -0
  146. package/model/datetime-display/datetime-display.d.ts +1 -0
  147. package/model/historical-curve/historical-curve-axis-settings.d.ts +11 -0
  148. package/model/historical-curve/historical-curve-axis-settings.js +5 -0
  149. package/model/historical-curve/historical-curve-axis-settings.metadata.json +1 -1
  150. package/model/historical-curve/historical-curve-chanel.model.d.ts +8 -0
  151. package/model/meter/meter.d.ts +4 -0
  152. package/model/numerical-display/numerical-operation.d.ts +10 -2
  153. package/model/ring-graph/ring-graph.model.d.ts +8 -0
  154. package/model/scroll-alarm/scroll-alarm.model.d.ts +21 -0
  155. package/model/scroll-alarm/scroll-alarm.model.js +0 -0
  156. package/model/scroll-alarm/scroll-alarm.model.metadata.json +1 -0
  157. package/model/shared/state/state.d.ts +1 -0
  158. package/model/shared/state/state.js +1 -0
  159. package/model/shared/state/state.metadata.json +1 -1
  160. package/model/shared/text/font.d.ts +1 -1
  161. package/model/shared/text/text.d.ts +3 -0
  162. package/model/switch-indicator-light/switch-indicator-light.d.ts +2 -0
  163. package/model/view-operation/view-operation-element.model.d.ts +7 -1
  164. package/package.json +1 -1
  165. package/public_api.js +1 -0
  166. package/remote/communication/variable/remote-variable-communicator.d.ts +30 -0
  167. package/remote/communication/variable/remote-variable-communicator.js +193 -3
  168. package/remote/communication/variable/remote-variable-communicator.metadata.json +1 -1
  169. package/remote/communication/variable/remote-variable-protocol.d.ts +8 -0
  170. package/service/index.d.ts +4 -0
  171. package/service/index.js +1 -0
  172. package/service/index.metadata.json +1 -1
  173. package/service/language.service.d.ts +37 -0
  174. package/service/language.service.js +0 -0
  175. package/service/language.service.metadata.json +1 -0
  176. package/service/released-variable/index.d.ts +1 -0
  177. package/service/released-variable/index.js +0 -0
  178. package/service/released-variable/index.metadata.json +1 -0
  179. package/service/released-variable/released-variable.service.d.ts +4 -0
  180. package/service/released-variable/released-variable.service.js +0 -0
  181. package/service/released-variable/released-variable.service.metadata.json +1 -0
  182. package/service/system-text-library.service.d.ts +77 -0
  183. package/service/system-text-library.service.js +29 -0
  184. package/service/system-text-library.service.metadata.json +1 -0
  185. package/service/text-library.service.d.ts +49 -0
  186. package/service/text-library.service.js +0 -0
  187. package/service/text-library.service.metadata.json +1 -0
  188. package/service/weather.service.d.ts +1 -0
  189. package/shared/gui-consts.d.ts +3 -0
  190. package/shared/gui-consts.js +3 -0
  191. package/shared/gui-consts.metadata.json +1 -1
  192. package/utils/data-type/fbox-data-type.service.js +40 -0
  193. package/utils/numerical-operation.service.js +28 -4
@@ -2,7 +2,7 @@ import { LOGGER_SERVICE_TOKEN } from '../../logger';
2
2
  import * as d3 from 'd3-selection';
3
3
  import { isUndefined } from 'lodash';
4
4
  import { IndicatorLightType, SwitchType, State, BitSwitchOperation } from '../../model';
5
- import { VariableState } from '../../communication';
5
+ import { VariableState, VariableStateEnum } from '../../communication';
6
6
  import { ConditionalEnableElement } from '../base/conditional-enable-element';
7
7
  import { GraphStateElement } from '../shared/graph/graph-state-element';
8
8
  import { TextStateElement } from '../shared/text/text-state-element';
@@ -17,12 +17,15 @@ import { DisplayMode, GlobalSettings } from '../../settings';
17
17
  import { VariableUtil } from '../../utils/variable-util';
18
18
  import { VariableDefinition } from '../../communication/variable/variable-definition';
19
19
  export class SwitchIndicatorLightElement extends ConditionalEnableElement {
20
- constructor(element, injector, modalService, variableCommunicator, graphStore, permissionChecker, operationRecordService, securityChecker, variableStore, localization, signalRAppId) {
20
+ constructor(element, injector, modalService, variableCommunicator, graphStore, permissionChecker, operationRecordService, securityChecker, variableStore, localization, signalRAppId, textLibraryService, languageService, guiContext) {
21
21
  super(element, permissionChecker, variableCommunicator, variableStore, localization, signalRAppId);
22
22
  this.modalService = modalService;
23
23
  this.graphStore = graphStore;
24
24
  this.operationRecordService = operationRecordService;
25
25
  this.securityChecker = securityChecker;
26
+ this.textLibraryService = textLibraryService;
27
+ this.languageService = languageService;
28
+ this.guiContext = guiContext;
26
29
  this.isBitRestoration = false; // 是否是 位设定且执行设置是复位
27
30
  this.isVerifiedForRestoration = false; // 位设定且执行设置是复位情况下,是否已经完成了验证
28
31
  this.isWriteRestorationDownValue = false;
@@ -32,7 +35,8 @@ export class SwitchIndicatorLightElement extends ConditionalEnableElement {
32
35
  if (this.model.useSwitch) {
33
36
  this.initSwitchOperator();
34
37
  this.rootElement.style('cursor', 'hand');
35
- this.rootElement.on(this.isMobileMode ? 'touchstart' : 'mousedown', () => {
38
+ const isMobile = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i);
39
+ this.rootElement.on(this.isMobileMode && isMobile ? 'touchstart' : 'mousedown', () => {
36
40
  if (!this.isInitialized) {
37
41
  return;
38
42
  }
@@ -59,7 +63,7 @@ export class SwitchIndicatorLightElement extends ConditionalEnableElement {
59
63
  }
60
64
  else {
61
65
  this.checkElementPassword(false);
62
- if (!this.model.useIndicatorLight && !this.isMobileMode) {
66
+ if (!this.model.useIndicatorLight) {
63
67
  this.switchToState(1);
64
68
  }
65
69
  }
@@ -74,7 +78,7 @@ export class SwitchIndicatorLightElement extends ConditionalEnableElement {
74
78
  d3.event.preventDefault();
75
79
  }
76
80
  });
77
- this.rootElement.on(this.isMobileMode ? 'touchend' : 'mouseup', () => {
81
+ this.rootElement.on(this.isMobileMode && isMobile ? 'touchend' : 'mouseup', () => {
78
82
  this.handleMouseUp();
79
83
  d3.event.stopPropagation();
80
84
  });
@@ -99,7 +103,7 @@ export class SwitchIndicatorLightElement extends ConditionalEnableElement {
99
103
  document.removeEventListener(this.isMobileMode ? 'touchend' : 'mouseup', this.onDocMouseUp);
100
104
  this.isVerifiedForRestoration = false;
101
105
  this.isWriteRestorationDownValue = false;
102
- if (!this.model.useIndicatorLight && !this.isMobileMode) {
106
+ if (!this.model.useIndicatorLight) {
103
107
  this.switchToState(0);
104
108
  if (d3.event) {
105
109
  d3.event.preventDefault();
@@ -191,11 +195,21 @@ export class SwitchIndicatorLightElement extends ConditionalEnableElement {
191
195
  }
192
196
  }
193
197
  initIndictorLightOperator() {
198
+ var _a, _b, _c, _d, _e, _f;
194
199
  const settings = this.model.indicatorLightSettings;
195
200
  if (settings.settings.variableName) {
196
201
  const variable = new VariableDefinition(settings.settings.variableName, settings.settings.variableGroupName, settings.settings.dataSourceCode, settings.settings.variableVersion);
197
- this.addElementState(new VariableState(VariableUtil.getConvertedVariableName(this.variableStore, variable), undefined));
202
+ const convertedName = VariableUtil.getConvertedVariableName(this.variableStore, variable);
203
+ this.addElementState(new VariableState(convertedName, undefined));
198
204
  this.initState();
205
+ // 模拟模式下优先用后端 GetVariablesForDesigner 查出的有效变量(绑定了 manager);
206
+ // 运行模式不填充 validVariableNames,回退到 variableStore.getAllVariableNames()
207
+ const validNames = (_b = (_a = this.guiContext) === null || _a === void 0 ? void 0 : _a.validVariableNames) !== null && _b !== void 0 ? _b : (_f = (_e = (_d = (_c = this.guiContext) === null || _c === void 0 ? void 0 : _c.configStore) === null || _d === void 0 ? void 0 : _d.variableStore) === null || _e === void 0 ? void 0 : _e.getAllVariableNames) === null || _f === void 0 ? void 0 : _f.call(_e);
208
+ if (validNames && !validNames.includes(convertedName)) {
209
+ this.updateElementStates([new VariableState(convertedName, VariableStateEnum.InvalidMonitor)]);
210
+ this.switchToState(0);
211
+ return;
212
+ }
199
213
  }
200
214
  switch (settings.type) {
201
215
  case IndicatorLightType.Bit:
@@ -207,17 +221,26 @@ export class SwitchIndicatorLightElement extends ConditionalEnableElement {
207
221
  default:
208
222
  throw new Error(`Unknown switchType:${settings.type}`);
209
223
  }
210
- this.indicatorLightOperator.currentStateIdChanged.subscribe(statusIdValue => {
224
+ this.indicatorLightSubscription = this.indicatorLightOperator.currentStateIdChanged.subscribe(statusIdValue => {
211
225
  this.currentStateIdChange(statusIdValue);
212
226
  });
213
227
  this.indicatorLightOperator.requestData(this.signalRAppId);
214
228
  }
215
229
  currentStateIdChange(statusIdValue) {
216
- if (!isUndefined(statusIdValue.value)) {
217
- this.switchToState(statusIdValue.value);
218
- }
219
230
  this.updateElementStates([statusIdValue.state]);
220
231
  if (this.state === State.Unbind || this.state === State.Offline) {
232
+ if (!isUndefined(statusIdValue.value)) {
233
+ this.switchToState(statusIdValue.value);
234
+ }
235
+ else {
236
+ this.switchToState(0);
237
+ }
238
+ }
239
+ else if (!isUndefined(statusIdValue.value)) {
240
+ this.switchToState(statusIdValue.value);
241
+ }
242
+ else {
243
+ // 变量值为 null/undefined(含无效变量)时,显示第一个状态样式
221
244
  this.switchToState(0);
222
245
  }
223
246
  }
@@ -237,9 +260,44 @@ export class SwitchIndicatorLightElement extends ConditionalEnableElement {
237
260
  this.graphStateElement = new GraphStateElement(this.model.graphSetting, width, height, this.graphStore, this.logger, this.model.version, this.model.states);
238
261
  this.$element.append(this.graphStateElement.Element);
239
262
  }
240
- this.textStateElement = new TextStateElement(this.model.states, width, height, this.logger, this.model.version, this.model.states);
263
+ this.textStateElement = new TextStateElement(this.model.states, width, height, this.logger, this.model.version, this.model.states, this.model.textLibrary, this.textLibraryService, this.languageService, this.guiContext, true, this.model.fontStyleCultures);
241
264
  this.$element.append(this.textStateElement.Element);
242
265
  }
266
+ /**
267
+ * 释放资源
268
+ */
269
+ dispose() {
270
+ // 释放文本元素资源(取消语种变化订阅等)
271
+ if (this.textStateElement) {
272
+ this.textStateElement.dispose();
273
+ }
274
+ // 释放指示灯操作器资源
275
+ if (this.indicatorLightOperator) {
276
+ // indicatorLightOperator 可能有自己的dispose方法
277
+ }
278
+ // 清除定时器
279
+ if (this.restorationTimer) {
280
+ clearTimeout(this.restorationTimer);
281
+ this.restorationTimer = undefined;
282
+ }
283
+ // 移除事件监听
284
+ if (this.onDocMouseUp) {
285
+ document.removeEventListener(this.isMobileMode ? 'touchend' : 'mouseup', this.onDocMouseUp);
286
+ }
287
+ // 清理 indicatorLightOperator 订阅
288
+ if (this.indicatorLightSubscription) {
289
+ this.indicatorLightSubscription.unsubscribe();
290
+ }
291
+ // 清理图形元素(释放 SVG 内存)
292
+ if (this.graphStateElement) {
293
+ this.graphStateElement.dispose();
294
+ }
295
+ // 清理文本元素
296
+ if (this.textStateElement) {
297
+ // TextStateElement 可能也需要 dispose,暂时先清理引用
298
+ this.textStateElement = null;
299
+ }
300
+ }
243
301
  checkState() {
244
302
  if (!this.model.states) {
245
303
  throw new Error('The switch indicator light\'s states is undefined.');
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"SwitchIndicatorLightElement":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"../base/conditional-enable-element","name":"ConditionalEnableElement","line":32,"character":49},"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"error","message":"Could not resolve type","line":50,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":51,"character":18},{"__symbolic":"reference","module":"ngx-bootstrap/modal","name":"BsModalService","line":52,"character":39},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":53,"character":30},{"__symbolic":"reference","module":"../../config","name":"GraphStore","line":54,"character":37},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":55,"character":27},{"__symbolic":"reference","module":"../../service","name":"OperationRecordService","line":56,"character":49},{"__symbolic":"reference","module":"../../security","name":"SecurityChecker","line":57,"character":42},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":58,"character":23},{"__symbolic":"reference","module":"../../localization","name":"Localization","line":59,"character":22},{"__symbolic":"reference","name":"string"}]}],"handleMouseUp":[{"__symbolic":"method"}],"initOnDocMouseUpEvent":[{"__symbolic":"method"}],"checkElementPassword":[{"__symbolic":"method"}],"doSwitchOperator":[{"__symbolic":"method"}],"writeValue":[{"__symbolic":"method"}],"initSwitchOperator":[{"__symbolic":"method"}],"initIndictorLightOperator":[{"__symbolic":"method"}],"currentStateIdChange":[{"__symbolic":"method"}],"switchToState":[{"__symbolic":"method"}],"initGraphAndText":[{"__symbolic":"method"}],"checkState":[{"__symbolic":"method"}]}}}}]
1
+ [{"__symbolic":"module","version":4,"metadata":{"SwitchIndicatorLightElement":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"../base/conditional-enable-element","name":"ConditionalEnableElement","line":33,"character":49},"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"error","message":"Could not resolve type","line":52,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":53,"character":18},{"__symbolic":"reference","module":"ngx-bootstrap/modal","name":"BsModalService","line":54,"character":39},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":55,"character":30},{"__symbolic":"reference","module":"../../config","name":"GraphStore","line":56,"character":37},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":57,"character":27},{"__symbolic":"reference","module":"../../service","name":"OperationRecordService","line":58,"character":49},{"__symbolic":"reference","module":"../../security","name":"SecurityChecker","line":59,"character":42},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":60,"character":23},{"__symbolic":"reference","module":"../../localization","name":"Localization","line":61,"character":22},{"__symbolic":"reference","name":"string"},{"__symbolic":"reference","module":"../../service","name":"TextLibraryService","line":63,"character":46},{"__symbolic":"reference","module":"../../service","name":"LanguageService","line":64,"character":43},{"__symbolic":"reference","module":"../../gui/gui-context","name":"GuiContext","line":65,"character":38}]}],"handleMouseUp":[{"__symbolic":"method"}],"initOnDocMouseUpEvent":[{"__symbolic":"method"}],"checkElementPassword":[{"__symbolic":"method"}],"doSwitchOperator":[{"__symbolic":"method"}],"writeValue":[{"__symbolic":"method"}],"initSwitchOperator":[{"__symbolic":"method"}],"initIndictorLightOperator":[{"__symbolic":"method"}],"currentStateIdChange":[{"__symbolic":"method"}],"switchToState":[{"__symbolic":"method"}],"initGraphAndText":[{"__symbolic":"method"}],"dispose":[{"__symbolic":"method"}],"checkState":[{"__symbolic":"method"}]}}}}]
@@ -10,6 +10,7 @@ export declare class WordIndicatorLightOperator implements IndicatorLightOperato
10
10
  private readonly variableStore;
11
11
  currentStateId?: number;
12
12
  currentStateIdChanged: EventEmitter<CurrentStateIdValue>;
13
+ private valueSubscription;
13
14
  private sortedStates;
14
15
  get variableName(): string;
15
16
  constructor(settings: WordIndicatorLightSettings, states: SwitchIndicatorState[], variableCommunicator: VariableCommunicator, variableStore: VariableStore);
@@ -5,6 +5,7 @@ import { VariableStateEnum, VariableState } from '../../communication';
5
5
  import { CurrentStateIdValue } from './current-stateId-value';
6
6
  import { VariableUtil } from '../../utils/variable-util';
7
7
  import { VariableDefinition } from '../../communication/variable/variable-definition';
8
+ import { GuiFeatureConfig } from '../../config';
8
9
  export class WordIndicatorLightOperator {
9
10
  constructor(settings, states, variableCommunicator, variableStore) {
10
11
  this.settings = settings;
@@ -26,8 +27,11 @@ export class WordIndicatorLightOperator {
26
27
  if (variableValue.state === VariableStateEnum.Normal) {
27
28
  this.requestCurrentSateIdValue(this.variableCommunicator, appId);
28
29
  }
30
+ else if (GuiFeatureConfig.isOfflineDisplayEnabled && variableValue.state === VariableStateEnum.Offline && !this.valueSubscription) {
31
+ this.requestCurrentSateIdValue(this.variableCommunicator, appId);
32
+ }
29
33
  else {
30
- this.currentStateIdChanged.emit(new CurrentStateIdValue(new VariableState(this.variableName, variableValue.state)));
34
+ this.currentStateIdChanged.emit(new CurrentStateIdValue(new VariableState(this.variableName, variableValue.state), this.currentStateId));
31
35
  }
32
36
  });
33
37
  }
@@ -36,9 +40,12 @@ export class WordIndicatorLightOperator {
36
40
  }
37
41
  }
38
42
  requestCurrentSateIdValue(variableCommunicator, appId = '') {
43
+ if (this.valueSubscription) {
44
+ return;
45
+ }
39
46
  // TODO 检查状态id是从0-n连续编号的。
40
- variableCommunicator.openVariable(this.variableName, appId).subscribe(value => {
41
- if (value.state === VariableStateEnum.DataNormal) {
47
+ this.valueSubscription = variableCommunicator.openVariable(this.variableName, appId).subscribe(value => {
48
+ if (value.state === VariableStateEnum.DataNormal || (GuiFeatureConfig.isOfflineDisplayEnabled && value.state === VariableStateEnum.Offline)) {
42
49
  let stateId = 0;
43
50
  for (let index = 0; index < this.sortedStates.length - 1; index++) {
44
51
  const element = this.sortedStates[index];
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"WordIndicatorLightOperator":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"../../model","name":"WordIndicatorLightSettings","line":23,"character":43},{"__symbolic":"reference","name":"Array","arguments":[{"__symbolic":"reference","module":"../../model","name":"SwitchIndicatorState","line":24,"character":16}]},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":25,"character":47},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":26,"character":40}]}],"requestData":[{"__symbolic":"method"}],"requestCurrentSateIdValue":[{"__symbolic":"method"}]}}}}]
1
+ [{"__symbolic":"module","version":4,"metadata":{"WordIndicatorLightOperator":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"../../model","name":"WordIndicatorLightSettings","line":25,"character":43},{"__symbolic":"reference","name":"Array","arguments":[{"__symbolic":"reference","module":"../../model","name":"SwitchIndicatorState","line":26,"character":16}]},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":27,"character":47},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":28,"character":40}]}],"requestData":[{"__symbolic":"method"}],"requestCurrentSateIdValue":[{"__symbolic":"method"}]}}}}]
@@ -16,6 +16,12 @@ export declare class VideoElement extends ConditionalDisplayElement {
16
16
  private videoId;
17
17
  private isShow;
18
18
  private videoPlayer;
19
+ private refreshTimer;
20
+ private isFullscreen;
21
+ private videoUrl;
22
+ private visibilityChangeHandler;
23
+ private timeUpdateWatchdog;
24
+ private lastTimeUpdate;
19
25
  constructor(element: HTMLElement, injector: Injector, permissionChecker: PermissionChecker, variableCommunicator: VariableCommunicator, variableStore: VariableStore, videoService: VideoService, guiSize: Size, svgRootClass: string, signalRAppId: string);
20
26
  dispose(): void;
21
27
  hide(): void;
@@ -24,4 +30,8 @@ export declare class VideoElement extends ConditionalDisplayElement {
24
30
  private initVideo;
25
31
  private addVideoAddressToolTip;
26
32
  private setAndroidVideo;
33
+ private initVisibilityHandler;
34
+ private startTimeUpdateWatchdog;
35
+ private clearTimeUpdateWatchdog;
36
+ private setIosVideo;
27
37
  }
@@ -11,8 +11,11 @@ export class VideoElement extends ConditionalDisplayElement {
11
11
  this.guiSize = guiSize;
12
12
  this.svgRootClass = svgRootClass;
13
13
  this.videoId = '';
14
+ this.isFullscreen = false;
15
+ this.lastTimeUpdate = 0;
14
16
  this.isMobileMode = DisplayMode.Mobile === injector.get(GlobalSettings).displayMode;
15
17
  this.localization = injector.get(LOCALIZATION);
18
+ this.initVisibilityHandler();
16
19
  this.init();
17
20
  }
18
21
  dispose() {
@@ -22,6 +25,10 @@ export class VideoElement extends ConditionalDisplayElement {
22
25
  $('div.' + this.svgRootClass + ' video').each(function () {
23
26
  $(this).remove();
24
27
  });
28
+ if (this.visibilityChangeHandler) {
29
+ document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
30
+ }
31
+ this.clearTimeUpdateWatchdog();
25
32
  }
26
33
  hide() {
27
34
  super.hide();
@@ -50,12 +57,13 @@ export class VideoElement extends ConditionalDisplayElement {
50
57
  .attr('width', this.model.size.width)
51
58
  .attr('height', this.model.size.height);
52
59
  this.videoService.getVideoUrl(this.model.videoTag).then(result => {
53
- this.initVideo(result.url, result.isMobileType, this.videoId);
60
+ this.videoUrl = result.url;
61
+ this.initVideo(result.url, this.videoId);
54
62
  }).catch(() => {
55
63
  throw new Error('Failure of the videoService');
56
64
  });
57
65
  }
58
- initVideo(videoUrl, isMobileType, videoId) {
66
+ initVideo(videoUrl, videoId) {
59
67
  const patt = /https:.+.m3u8/;
60
68
  if (videoUrl.indexOf('http:') !== -1) {
61
69
  videoUrl = videoUrl.replace('http:', 'https:');
@@ -68,6 +76,8 @@ export class VideoElement extends ConditionalDisplayElement {
68
76
  this.addVideoAddressToolTip(videoToolTip);
69
77
  return;
70
78
  }
79
+ const isAndroid = !!navigator.userAgent.match(/(Android)/i);
80
+ const isIos = !!navigator.userAgent.match(/(Mac)/i);
71
81
  const currentRect = this.$element.find('rect#rect' + videoId).first();
72
82
  if (!currentRect.length) {
73
83
  return;
@@ -77,17 +87,19 @@ export class VideoElement extends ConditionalDisplayElement {
77
87
  const chartHeight = clientRect.height;
78
88
  const left = this.model.location.x / this.guiSize.width * $('.' + this.svgRootClass).find('.svg-content').width();
79
89
  const top = this.model.location.y / this.guiSize.height * $('.' + this.svgRootClass).find('.svg-content').height();
80
- let videoHtml = `<video scareX="${this.model.location.x / this.guiSize.width}"
81
- scareY="${this.model.location.y / this.guiSize.height}" id="${videoId}" src="${videoUrl}" style="
82
- position: absolute;top:${top}px;left:${left}px;width:${chartWidth}px;height:${chartHeight}px;object-fit:fill;z-index:0"
83
- playsInline webkit-playsinline `;
84
- const isAndroid = !!navigator.userAgent.match(/(Android)/i);
90
+ const scareX = this.model.location.x / this.guiSize.width;
91
+ const scareY = this.model.location.y / this.guiSize.height;
92
+ if (isIos) {
93
+ videoUrl = videoUrl + '#t=1';
94
+ }
95
+ const preload = isIos ? ' preload=\'metadata\'' : '';
96
+ let videoHtml = `<video scareX="${scareX}"
97
+ scareY="${scareY}" id="${videoId}" ${preload} src="${videoUrl}" width="${chartWidth}" height="${chartHeight}"
98
+ style="position: absolute;top:${top}px;left:${left}px;object-fit:fill;z-index:0;"
99
+ playsInline webkit-playsinline `;
85
100
  if (this.isMobileMode) {
86
101
  if (isAndroid) {
87
- if (isMobileType) {
88
- videoHtml += ' controls ';
89
- }
90
- videoHtml += ' autoplay muted></video>';
102
+ videoHtml += ' muted></video>';
91
103
  }
92
104
  else {
93
105
  videoHtml += ' controls muted></video>';
@@ -100,10 +112,32 @@ export class VideoElement extends ConditionalDisplayElement {
100
112
  if (this.isShow === false) {
101
113
  $('#' + this.videoId).hide();
102
114
  }
103
- this.videoPlayer = new EZUIPlayer(videoId);
104
- if (isAndroid && !isMobileType) {
105
- this.setAndroidVideo(videoId);
106
- }
115
+ setTimeout(() => {
116
+ if (isAndroid) {
117
+ this.setAndroidVideo(videoId);
118
+ }
119
+ else if (isIos) {
120
+ this.setIosVideo(this.videoUrl, videoId);
121
+ }
122
+ try {
123
+ this.videoPlayer = new EZUIPlayer(videoId);
124
+ if (isAndroid) {
125
+ // 确保在 EZUIPlayer 初始化后才调用 play 方法
126
+ this.videoPlayer.on('canplay', () => {
127
+ this.videoPlayer.play();
128
+ });
129
+ }
130
+ this.startTimeUpdateWatchdog(videoId);
131
+ }
132
+ catch (err) {
133
+ console.log(err);
134
+ }
135
+ }, 1000);
136
+ const style = document.createElement('style');
137
+ style.innerHTML = `#${videoId}::-webkit-media-controls-enclosure {
138
+ display: none;
139
+ }`;
140
+ document.head.append();
107
141
  }
108
142
  addVideoAddressToolTip(videoToolTip) {
109
143
  const size = this.model.size;
@@ -126,35 +160,99 @@ export class VideoElement extends ConditionalDisplayElement {
126
160
  this.$element.append(textElement.Element);
127
161
  }
128
162
  setAndroidVideo(videoId) {
129
- let isFullscreen = false;
130
163
  const videoElement = $('#' + videoId);
131
164
  let preHeight = videoElement.height();
132
165
  let preWidth = videoElement.width();
133
166
  let preTop = videoElement.css('top');
134
167
  let preLeft = videoElement.css('left');
168
+ const { StatusBar } = window;
135
169
  videoElement.on('click', () => {
136
- if (!isFullscreen) {
170
+ if (!this.isFullscreen) {
171
+ if (StatusBar) {
172
+ StatusBar.hide();
173
+ }
137
174
  preHeight = videoElement.height();
138
175
  preWidth = videoElement.width();
139
176
  preTop = videoElement.css('top');
140
177
  preLeft = videoElement.css('left');
141
- const width = document.body.clientWidth;
142
- const height = width * 9 / 16;
178
+ const width = document.documentElement.clientWidth;
179
+ const height = document.documentElement.clientHeight;
180
+ videoElement.css('object-fit', 'contain');
181
+ videoElement.css('background', '#000000');
143
182
  videoElement.css('width', width + 'px');
144
183
  videoElement.css('height', height + 'px');
145
184
  videoElement.css('left', '0px');
146
185
  videoElement.css('top', '0px');
147
186
  videoElement.css('z-index', '99');
148
- isFullscreen = true;
187
+ videoElement.css('position', 'fixed');
188
+ this.isFullscreen = true;
189
+ try {
190
+ screen.orientation.lock(screen.orientation.type);
191
+ }
192
+ catch (error) {
193
+ console.error(error);
194
+ }
149
195
  }
150
196
  else {
197
+ videoElement.css('object-fit', 'fill');
151
198
  videoElement.css('width', preWidth + 'px');
152
199
  videoElement.css('height', preHeight + 'px');
153
200
  videoElement.css('left', preLeft);
154
201
  videoElement.css('top', preTop);
155
202
  videoElement.css('z-index', '0');
156
- isFullscreen = false;
203
+ videoElement.css('position', 'absolute');
204
+ this.isFullscreen = false;
205
+ try {
206
+ if (screen.orientation.type.includes('portrait')) {
207
+ StatusBar.show();
208
+ }
209
+ }
210
+ catch (error) {
211
+ console.error(error);
212
+ }
213
+ }
214
+ });
215
+ }
216
+ initVisibilityHandler() {
217
+ this.visibilityChangeHandler = () => {
218
+ if (!document.hidden && this.videoUrl && this.videoId) {
219
+ this.initVideo(this.videoUrl, this.videoId);
157
220
  }
221
+ };
222
+ document.addEventListener('visibilitychange', this.visibilityChangeHandler);
223
+ }
224
+ startTimeUpdateWatchdog(videoId) {
225
+ this.clearTimeUpdateWatchdog();
226
+ this.lastTimeUpdate = Date.now();
227
+ const videoEl = document.getElementById(videoId);
228
+ if (videoEl && videoEl.tagName === 'VIDEO') {
229
+ videoEl.addEventListener('timeupdate', () => {
230
+ this.lastTimeUpdate = Date.now();
231
+ });
232
+ }
233
+ this.timeUpdateWatchdog = setInterval(() => {
234
+ if (document.hidden)
235
+ return;
236
+ if (Date.now() - this.lastTimeUpdate > 30000) {
237
+ this.initVideo(this.videoUrl, this.videoId);
238
+ }
239
+ }, 30000);
240
+ }
241
+ clearTimeUpdateWatchdog() {
242
+ if (this.timeUpdateWatchdog) {
243
+ clearInterval(this.timeUpdateWatchdog);
244
+ this.timeUpdateWatchdog = null;
245
+ }
246
+ }
247
+ setIosVideo(videoUrl, videoId) {
248
+ const video = $('#' + this.videoId);
249
+ video.on('webkitendfullscreen', () => {
250
+ video.remove();
251
+ clearTimeout(this.refreshTimer);
252
+ this.refreshTimer = null;
253
+ this.refreshTimer = setTimeout(() => {
254
+ this.initVideo(videoUrl, videoId);
255
+ }, 500);
158
256
  });
159
257
  }
160
258
  }
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"VideoElement":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"../base/conditional-display-element","name":"ConditionalDisplayElement","line":15,"character":34},"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"error","message":"Could not resolve type","line":23,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":24,"character":18},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":25,"character":27},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":26,"character":30},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":27,"character":23},{"__symbolic":"reference","module":"../../service","name":"VideoService","line":28,"character":39},{"__symbolic":"reference","module":"../../model","name":"Size","line":29,"character":34},{"__symbolic":"reference","name":"string"},{"__symbolic":"reference","name":"string"}]}],"dispose":[{"__symbolic":"method"}],"hide":[{"__symbolic":"method"}],"show":[{"__symbolic":"method"}],"init":[{"__symbolic":"method"}],"initVideo":[{"__symbolic":"method"}],"addVideoAddressToolTip":[{"__symbolic":"method"}],"setAndroidVideo":[{"__symbolic":"method"}]}}}}]
1
+ [{"__symbolic":"module","version":4,"metadata":{"VideoElement":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"../base/conditional-display-element","name":"ConditionalDisplayElement","line":15,"character":34},"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"error","message":"Could not resolve type","line":30,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":31,"character":18},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":32,"character":27},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":33,"character":30},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":34,"character":23},{"__symbolic":"reference","module":"../../service","name":"VideoService","line":35,"character":39},{"__symbolic":"reference","module":"../../model","name":"Size","line":36,"character":34},{"__symbolic":"reference","name":"string"},{"__symbolic":"reference","name":"string"}]}],"dispose":[{"__symbolic":"method"}],"hide":[{"__symbolic":"method"}],"show":[{"__symbolic":"method"}],"init":[{"__symbolic":"method"}],"initVideo":[{"__symbolic":"method"}],"addVideoAddressToolTip":[{"__symbolic":"method"}],"setAndroidVideo":[{"__symbolic":"method"}],"initVisibilityHandler":[{"__symbolic":"method"}],"startTimeUpdateWatchdog":[{"__symbolic":"method"}],"clearTimeUpdateWatchdog":[{"__symbolic":"method"}],"setIosVideo":[{"__symbolic":"method"}]}}}}]
@@ -3,11 +3,12 @@ import { BsModalService } from 'ngx-bootstrap/modal';
3
3
  import { Localization } from '../../localization';
4
4
  import { GraphStore, VariableStore } from '../../config';
5
5
  import { ViewOperationElementModel } from '../../model';
6
- import { PermissionChecker, OperationRecordService } from '../../service';
6
+ import { PermissionChecker, OperationRecordService, TextLibraryService, LanguageService } from '../../service';
7
7
  import { VariableCommunicator } from '../../communication';
8
8
  import { ConditionalEnableElement } from '../base/conditional-enable-element';
9
9
  import { PopupViewService } from '../../view/popup-view.service';
10
10
  import { SecurityChecker } from '../../security';
11
+ import { GuiContext } from '../../gui/gui-context';
11
12
  export declare class ViewOperationElement extends ConditionalEnableElement {
12
13
  private readonly modalService;
13
14
  private readonly graphStore;
@@ -16,13 +17,18 @@ export declare class ViewOperationElement extends ConditionalEnableElement {
16
17
  private readonly popupViewService;
17
18
  private readonly hostContainerId;
18
19
  private readonly el;
20
+ private readonly textLibraryService?;
21
+ private readonly languageService?;
22
+ private readonly guiContext?;
19
23
  protected model: ViewOperationElementModel;
20
24
  private readonly logger;
21
25
  private readonly viewService;
22
26
  private graphStateElement?;
27
+ private textElementModal?;
28
+ private languageChangeSubscription?;
23
29
  private touchedScreenX;
24
30
  private touchedScreenY;
25
- constructor(element: HTMLElement, injector: Injector, modalService: BsModalService, variableCommunicator: VariableCommunicator, variableStore: VariableStore, graphStore: GraphStore, permissionChecker: PermissionChecker, operationRecordService: OperationRecordService, securityChecker: SecurityChecker, localization: Localization, popupViewService: PopupViewService, hostContainerId: string, el: ElementRef, signalRAppId: string);
31
+ constructor(element: HTMLElement, injector: Injector, modalService: BsModalService, variableCommunicator: VariableCommunicator, variableStore: VariableStore, graphStore: GraphStore, permissionChecker: PermissionChecker, operationRecordService: OperationRecordService, securityChecker: SecurityChecker, localization: Localization, popupViewService: PopupViewService, hostContainerId: string, el: ElementRef, signalRAppId: string, textLibraryService?: TextLibraryService, languageService?: LanguageService, guiContext?: GuiContext);
26
32
  private initElement;
27
33
  private switchToState;
28
34
  private initGraph;
@@ -33,4 +39,24 @@ export declare class ViewOperationElement extends ConditionalEnableElement {
33
39
  private closeView;
34
40
  private moveView;
35
41
  private recordViewOperation;
42
+ /**
43
+ * 订阅语种变化事件
44
+ */
45
+ private subscribeLanguageChange;
46
+ /**
47
+ * 获取当前语种的字体样式
48
+ */
49
+ private getFontStyle;
50
+ /**
51
+ * 更新文本内容(支持文本库和语种切换)
52
+ */
53
+ private updateTextContent;
54
+ /**
55
+ * 获取显示文本
56
+ */
57
+ private getDisplayText;
58
+ /**
59
+ * 释放资源
60
+ */
61
+ dispose(): void;
36
62
  }