@flexem/fc-gui 3.0.0-alpha.11 → 3.0.0-alpha.111

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 (131) hide show
  1. package/CHANGELOG.md +445 -0
  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/bundles/@flexem/fc-gui.umd.js +19414 -17248
  7. package/bundles/@flexem/fc-gui.umd.js.map +1 -1
  8. package/bundles/@flexem/fc-gui.umd.min.js +5 -5
  9. package/bundles/@flexem/fc-gui.umd.min.js.map +1 -1
  10. package/communication/variable/variable-communicator.d.ts +1 -0
  11. package/config/alarm/alarm.store.d.ts +6 -0
  12. package/config/alarm/alarm.store.js +0 -0
  13. package/config/alarm/alarm.store.metadata.json +1 -0
  14. package/config/alarm/get-alarms-args.d.ts +9 -0
  15. package/config/alarm/get-alarms-args.js +9 -0
  16. package/config/alarm/get-alarms-args.metadata.json +1 -0
  17. package/config/alarm/index.d.ts +2 -0
  18. package/config/alarm/index.js +1 -0
  19. package/config/alarm/index.metadata.json +1 -0
  20. package/config/config-store.d.ts +2 -0
  21. package/config/index.d.ts +1 -0
  22. package/config/index.js +1 -0
  23. package/config/index.metadata.json +1 -1
  24. package/elements/air-quality/air-quality-element.d.ts +31 -0
  25. package/elements/air-quality/air-quality-element.js +194 -0
  26. package/elements/air-quality/air-quality-element.metadata.json +1 -0
  27. package/elements/alarm/alarm-element.d.ts +44 -0
  28. package/elements/alarm/alarm-element.js +386 -0
  29. package/elements/alarm/alarm-element.metadata.json +1 -0
  30. package/elements/bar-graph-element.d.ts +10 -2
  31. package/elements/bar-graph-element.js +135 -5
  32. package/elements/bar-graph-element.metadata.json +1 -1
  33. package/elements/base/readable-element.d.ts +6 -1
  34. package/elements/base/readable-element.js +31 -2
  35. package/elements/base/readable-element.metadata.json +1 -1
  36. package/elements/datetime-display/datetime-display-element.d.ts +1 -0
  37. package/elements/datetime-display/datetime-display-element.js +10 -2
  38. package/elements/datetime-display/datetime-display-element.metadata.json +1 -1
  39. package/elements/datetime-display/time-zone-select-json.d.ts +8 -0
  40. package/elements/datetime-display/time-zone-select-json.js +558 -0
  41. package/elements/historical-curve/historical-curve.element.d.ts +8 -0
  42. package/elements/historical-curve/historical-curve.element.js +224 -19
  43. package/elements/historical-curve/historical-curve.element.metadata.json +1 -1
  44. package/elements/main-element.js +25 -4
  45. package/elements/main-element.metadata.json +1 -1
  46. package/elements/meter-element.d.ts +7 -1
  47. package/elements/meter-element.js +76 -7
  48. package/elements/meter-element.metadata.json +1 -1
  49. package/elements/numerical-display/numerical-display-element.d.ts +8 -2
  50. package/elements/numerical-display/numerical-display-element.js +55 -11
  51. package/elements/numerical-display/numerical-display-element.metadata.json +1 -1
  52. package/elements/per-view-variable-communicator.d.ts +2 -0
  53. package/elements/per-view-variable-communicator.js +8 -0
  54. package/elements/per-view-variable-communicator.metadata.json +1 -1
  55. package/elements/ring-graph/ring-graph-element.d.ts +13 -1
  56. package/elements/ring-graph/ring-graph-element.js +164 -3
  57. package/elements/ring-graph/ring-graph-element.metadata.json +1 -1
  58. package/elements/shared/graph/graph-state-element.js +0 -3
  59. package/elements/shared/text/text-element.js +13 -2
  60. package/elements/shared/text/text-state-element.js +1 -1
  61. package/elements/switch-indicator-light/bit-switch-operator.d.ts +1 -0
  62. package/elements/switch-indicator-light/bit-switch-operator.js +19 -0
  63. package/elements/switch-indicator-light/bit-switch-operator.metadata.json +1 -1
  64. package/elements/switch-indicator-light/switch-indicator-light-element.d.ts +8 -0
  65. package/elements/switch-indicator-light/switch-indicator-light-element.js +93 -23
  66. package/elements/switch-indicator-light/switch-indicator-light-element.metadata.json +1 -1
  67. package/elements/switch-indicator-light/switch-operator.d.ts +1 -0
  68. package/elements/switch-indicator-light/word-switch-operator.d.ts +1 -0
  69. package/elements/switch-indicator-light/word-switch-operator.js +6 -0
  70. package/elements/switch-indicator-light/word-switch-operator.metadata.json +1 -1
  71. package/elements/video/video-element.d.ts +4 -0
  72. package/elements/video/video-element.js +74 -20
  73. package/elements/video/video-element.metadata.json +1 -1
  74. package/elements/view-operation/view-operation.element.js +8 -0
  75. package/elements/weather/weater-element.js +0 -1
  76. package/gui/gui-context.d.ts +2 -1
  77. package/gui/gui-host.d.ts +1 -1
  78. package/gui/gui.component.d.ts +3 -0
  79. package/gui/gui.component.js +15 -2
  80. package/gui/gui.component.metadata.json +1 -1
  81. package/localization/localization.service.d.ts +7 -0
  82. package/localization/localization.service.js +10 -3
  83. package/localization/localization.service.metadata.json +1 -1
  84. package/localization/localization.service.zh_CN.js +8 -1
  85. package/localization/localization.service.zh_CN.metadata.json +1 -1
  86. package/modal/write-value/write-value-modal-args.d.ts +3 -1
  87. package/modal/write-value/write-value-modal-args.js +2 -1
  88. package/modal/write-value/write-value-modal-args.metadata.json +1 -1
  89. package/modal/write-value/write-value-modal.component.d.ts +8 -7
  90. package/modal/write-value/write-value-modal.component.html +9 -4
  91. package/modal/write-value/write-value-modal.component.js +42 -15
  92. package/modal/write-value/write-value-modal.component.metadata.json +1 -1
  93. package/model/air-quality/air-quality-info.d.ts +23 -0
  94. package/model/air-quality/air-quality-info.js +4 -0
  95. package/model/air-quality/air-quality-info.metadata.json +1 -0
  96. package/model/air-quality/air-quality.model.d.ts +7 -0
  97. package/model/air-quality/air-quality.model.js +0 -0
  98. package/model/air-quality/air-quality.model.metadata.json +1 -0
  99. package/model/alarm/alarm.model.d.ts +13 -0
  100. package/model/alarm/alarm.model.js +0 -0
  101. package/model/alarm/alarm.model.metadata.json +1 -0
  102. package/model/bar-graph/bar-graph.d.ts +4 -0
  103. package/model/base/readable-model.d.ts +4 -0
  104. package/model/datetime-display/datetime-display.d.ts +1 -0
  105. package/model/historical-curve/historical-curve-axis-settings.d.ts +11 -0
  106. package/model/historical-curve/historical-curve-axis-settings.js +5 -0
  107. package/model/historical-curve/historical-curve-axis-settings.metadata.json +1 -1
  108. package/model/historical-curve/historical-curve-chanel.model.d.ts +8 -0
  109. package/model/meter/meter.d.ts +4 -0
  110. package/model/ring-graph/ring-graph.model.d.ts +8 -0
  111. package/model/switch-indicator-light/bit-switch-operation.d.ts +2 -1
  112. package/model/switch-indicator-light/bit-switch-operation.js +1 -0
  113. package/model/switch-indicator-light/bit-switch-operation.metadata.json +1 -1
  114. package/package.json +1 -1
  115. package/remote/communication/variable/remote-variable-communicator.d.ts +4 -0
  116. package/remote/communication/variable/remote-variable-communicator.js +23 -1
  117. package/remote/communication/variable/remote-variable-communicator.metadata.json +1 -1
  118. package/remote/communication/variable/remote-variable-protocol.d.ts +3 -0
  119. package/service/index.d.ts +1 -0
  120. package/service/index.metadata.json +1 -1
  121. package/service/released-variable/index.d.ts +1 -0
  122. package/service/released-variable/index.js +0 -0
  123. package/service/released-variable/index.metadata.json +1 -0
  124. package/service/released-variable/released-variable.service.d.ts +4 -0
  125. package/service/released-variable/released-variable.service.js +0 -0
  126. package/service/released-variable/released-variable.service.metadata.json +1 -0
  127. package/service/weather.service.d.ts +1 -0
  128. package/shared/gui-consts.d.ts +2 -0
  129. package/shared/gui-consts.js +2 -0
  130. package/shared/gui-consts.metadata.json +1 -1
  131. package/utils/data-type/fbox-data-type.service.js +40 -0
@@ -1,7 +1,7 @@
1
1
  import { LOGGER_SERVICE_TOKEN } from '../../logger';
2
2
  import * as d3 from 'd3-selection';
3
3
  import { isUndefined } from 'lodash';
4
- import { IndicatorLightType, SwitchType, State } from '../../model';
4
+ import { IndicatorLightType, SwitchType, State, BitSwitchOperation } from '../../model';
5
5
  import { VariableState } from '../../communication';
6
6
  import { ConditionalEnableElement } from '../base/conditional-enable-element';
7
7
  import { GraphStateElement } from '../shared/graph/graph-state-element';
@@ -23,13 +23,17 @@ export class SwitchIndicatorLightElement extends ConditionalEnableElement {
23
23
  this.graphStore = graphStore;
24
24
  this.operationRecordService = operationRecordService;
25
25
  this.securityChecker = securityChecker;
26
+ this.isBitRestoration = false; // 是否是 位设定且执行设置是复位
27
+ this.isVerifiedForRestoration = false; // 位设定且执行设置是复位情况下,是否已经完成了验证
28
+ this.isWriteRestorationDownValue = false;
26
29
  this.logger = injector.get(LOGGER_SERVICE_TOKEN);
27
30
  this.isMobileMode = DisplayMode.Mobile === injector.get(GlobalSettings).displayMode;
28
31
  this.checkState();
29
32
  if (this.model.useSwitch) {
30
33
  this.initSwitchOperator();
31
34
  this.rootElement.style('cursor', 'hand');
32
- this.rootElement.on('mousedown', () => {
35
+ 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);
36
+ this.rootElement.on(this.isMobileMode && isMobile ? 'touchstart' : 'mousedown', () => {
33
37
  if (!this.isInitialized) {
34
38
  return;
35
39
  }
@@ -43,31 +47,39 @@ export class SwitchIndicatorLightElement extends ConditionalEnableElement {
43
47
  return;
44
48
  }
45
49
  if (this.switchOperator.canExecute()) {
46
- if (this.model.useSecurity) {
47
- const modalRef = this.modalService.show(ConfirmOperationModalComponent, { backdrop: 'static', class: 'gui-modal-dialog-position', animated: false });
48
- const onClosedSub = modalRef.content.onClosed.subscribe(result => {
49
- modalRef.hide();
50
- onClosedSub.unsubscribe();
51
- if (result) {
52
- this.checkElementPassword();
50
+ if (!this.isBitRestoration || !this.isVerifiedForRestoration) {
51
+ if (this.model.useSecurity) {
52
+ const modalRef = this.modalService.show(ConfirmOperationModalComponent, { backdrop: 'static', class: 'gui-modal-dialog-position', animated: false });
53
+ const onClosedSub = modalRef.content.onClosed.subscribe(result => {
54
+ modalRef.hide();
55
+ onClosedSub.unsubscribe();
56
+ if (result) {
57
+ this.checkElementPassword(true);
58
+ }
59
+ });
60
+ }
61
+ else {
62
+ this.checkElementPassword(false);
63
+ if (!this.model.useIndicatorLight && !this.isMobileMode) {
64
+ this.switchToState(1);
53
65
  }
54
- });
66
+ }
55
67
  }
56
68
  else {
57
- this.checkElementPassword();
58
- if (!this.model.useIndicatorLight && !this.isMobileMode) {
59
- this.switchToState(1);
60
- }
69
+ document.addEventListener(this.isMobileMode ? 'touchend' : 'mouseup', this.onDocMouseUp);
70
+ this.restorationTimer = setTimeout(() => {
71
+ this.writeValue(1);
72
+ this.isWriteRestorationDownValue = true;
73
+ }, 1000);
61
74
  }
62
75
  d3.event.preventDefault();
63
76
  }
64
77
  });
65
- if (!this.model.useIndicatorLight && !this.isMobileMode) {
66
- this.rootElement.on('mouseup', () => {
67
- this.switchToState(0);
68
- d3.event.preventDefault();
69
- });
70
- }
78
+ this.rootElement.on(this.isMobileMode && isMobile ? 'touchend' : 'mouseup', () => {
79
+ this.handleMouseUp();
80
+ d3.event.stopPropagation();
81
+ });
82
+ this.initOnDocMouseUpEvent();
71
83
  }
72
84
  this.initGraphAndText();
73
85
  if (this.model.useIndicatorLight) {
@@ -77,19 +89,62 @@ export class SwitchIndicatorLightElement extends ConditionalEnableElement {
77
89
  this.switchToState(0);
78
90
  }
79
91
  }
80
- checkElementPassword() {
92
+ handleMouseUp() {
93
+ if (this.restorationTimer) {
94
+ clearTimeout(this.restorationTimer);
95
+ this.restorationTimer = undefined;
96
+ }
97
+ if (this.isBitRestoration && this.isWriteRestorationDownValue) {
98
+ this.writeValue(0);
99
+ }
100
+ document.removeEventListener(this.isMobileMode ? 'touchend' : 'mouseup', this.onDocMouseUp);
101
+ this.isVerifiedForRestoration = false;
102
+ this.isWriteRestorationDownValue = false;
103
+ if (!this.model.useIndicatorLight && !this.isMobileMode) {
104
+ this.switchToState(0);
105
+ if (d3.event) {
106
+ d3.event.preventDefault();
107
+ }
108
+ }
109
+ }
110
+ initOnDocMouseUpEvent() {
111
+ this.onDocMouseUp = () => {
112
+ this.handleMouseUp();
113
+ };
114
+ }
115
+ checkElementPassword(afterConfirm) {
81
116
  if (this.model.enablePassword) {
82
117
  const modalRef = this.modalService.show(VerifyPasswordModalComponent, { initialState: { securityChecker: this.securityChecker }, backdrop: 'static', class: 'gui-modal-dialog-position', animated: false });
83
118
  const onClosedSub = modalRef.content.onClosed.subscribe(result => {
84
119
  modalRef.hide();
85
120
  onClosedSub.unsubscribe();
86
121
  if (result) {
87
- this.doSwitchOperator();
122
+ if (!this.isBitRestoration) {
123
+ this.doSwitchOperator();
124
+ }
125
+ else {
126
+ this.isVerifiedForRestoration = true;
127
+ }
88
128
  }
89
129
  });
90
130
  }
91
131
  else {
92
- this.doSwitchOperator();
132
+ if (!this.isBitRestoration) {
133
+ this.doSwitchOperator();
134
+ }
135
+ else {
136
+ if (afterConfirm) {
137
+ this.isVerifiedForRestoration = true;
138
+ }
139
+ else {
140
+ this.isVerifiedForRestoration = true;
141
+ document.addEventListener(this.isMobileMode ? 'touchend' : 'mouseup', this.onDocMouseUp);
142
+ this.restorationTimer = setTimeout(() => {
143
+ this.writeValue(1);
144
+ this.isWriteRestorationDownValue = true;
145
+ }, 1000);
146
+ }
147
+ }
93
148
  }
94
149
  }
95
150
  doSwitchOperator() {
@@ -106,12 +161,27 @@ export class SwitchIndicatorLightElement extends ConditionalEnableElement {
106
161
  throw new Error('Failure of the operation record:switchOperator');
107
162
  });
108
163
  }
164
+ writeValue(value) {
165
+ this.switchOperator.writeValue(value).then(args => {
166
+ if (this.model.isRecordOperation || this.model.isRecordOperation === undefined) {
167
+ if (args.newValue !== undefined || args.originValue !== undefined) {
168
+ this.operationRecordService.record({
169
+ variableOptionModel: args,
170
+ operationDescription: this.model.operationDescription
171
+ });
172
+ }
173
+ }
174
+ }).catch(() => {
175
+ throw new Error('Failure of the operation record:switchOperator');
176
+ });
177
+ }
109
178
  initSwitchOperator() {
110
179
  const settings = this.model.switchSettings;
111
180
  switch (settings.type) {
112
181
  case SwitchType.Bit:
113
182
  this.switchOperator =
114
183
  new BitSwitchOperator(settings.settings, this.variableCommunicator, this.variableStore, this.signalRAppId);
184
+ this.isBitRestoration = settings.settings.operation === BitSwitchOperation.Restoration;
115
185
  break;
116
186
  case SwitchType.Word:
117
187
  this.switchOperator =
@@ -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":44,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":45,"character":18},{"__symbolic":"reference","module":"ngx-bootstrap/modal","name":"BsModalService","line":46,"character":39},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":47,"character":30},{"__symbolic":"reference","module":"../../config","name":"GraphStore","line":48,"character":37},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":49,"character":27},{"__symbolic":"reference","module":"../../service","name":"OperationRecordService","line":50,"character":49},{"__symbolic":"reference","module":"../../security","name":"SecurityChecker","line":51,"character":42},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":52,"character":23},{"__symbolic":"reference","module":"../../localization","name":"Localization","line":53,"character":22},{"__symbolic":"reference","name":"string"}]}],"checkElementPassword":[{"__symbolic":"method"}],"doSwitchOperator":[{"__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":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"}]}}}}]
@@ -2,4 +2,5 @@ import { VariableOptionModel } from '../../service';
2
2
  export interface SwitchOperator {
3
3
  canExecute(): boolean;
4
4
  execute(): Promise<VariableOptionModel>;
5
+ writeValue(value: number): Promise<VariableOptionModel>;
5
6
  }
@@ -14,4 +14,5 @@ export declare class WordSwitchOperator implements SwitchOperator {
14
14
  constructor(settings: WordSwitchSettings, variableCommunicator: VariableCommunicator, variableStore: VariableStore, signalRAppId: string);
15
15
  canExecute(): boolean;
16
16
  execute(): Promise<VariableOptionModel>;
17
+ writeValue(value: any): Promise<VariableOptionModel>;
17
18
  }
@@ -66,4 +66,10 @@ export class WordSwitchOperator {
66
66
  newValue: newValue
67
67
  });
68
68
  }
69
+ // 此方法为 位设定添加的,字设定目前不会用到,为了解决接口error,添加一个空实现
70
+ writeValue(value) {
71
+ return Promise.resolve({
72
+ newValue: value
73
+ });
74
+ }
69
75
  }
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"WordSwitchOperator":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"../../model","name":"WordSwitchSettings","line":20,"character":43},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":20,"character":102},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":21,"character":40},{"__symbolic":"reference","name":"string"}]}],"canExecute":[{"__symbolic":"method"}],"execute":[{"__symbolic":"method"}]}}}}]
1
+ [{"__symbolic":"module","version":4,"metadata":{"WordSwitchOperator":{"__symbolic":"class","members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"../../model","name":"WordSwitchSettings","line":20,"character":43},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":20,"character":102},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":21,"character":40},{"__symbolic":"reference","name":"string"}]}],"canExecute":[{"__symbolic":"method"}],"execute":[{"__symbolic":"method"}],"writeValue":[{"__symbolic":"method"}]}}}}]
@@ -16,6 +16,9 @@ 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;
19
22
  constructor(element: HTMLElement, injector: Injector, permissionChecker: PermissionChecker, variableCommunicator: VariableCommunicator, variableStore: VariableStore, videoService: VideoService, guiSize: Size, svgRootClass: string, signalRAppId: string);
20
23
  dispose(): void;
21
24
  hide(): void;
@@ -24,4 +27,5 @@ export declare class VideoElement extends ConditionalDisplayElement {
24
27
  private initVideo;
25
28
  private addVideoAddressToolTip;
26
29
  private setAndroidVideo;
30
+ private setIosVideo;
27
31
  }
@@ -11,6 +11,7 @@ export class VideoElement extends ConditionalDisplayElement {
11
11
  this.guiSize = guiSize;
12
12
  this.svgRootClass = svgRootClass;
13
13
  this.videoId = '';
14
+ this.isFullscreen = false;
14
15
  this.isMobileMode = DisplayMode.Mobile === injector.get(GlobalSettings).displayMode;
15
16
  this.localization = injector.get(LOCALIZATION);
16
17
  this.init();
@@ -50,12 +51,13 @@ export class VideoElement extends ConditionalDisplayElement {
50
51
  .attr('width', this.model.size.width)
51
52
  .attr('height', this.model.size.height);
52
53
  this.videoService.getVideoUrl(this.model.videoTag).then(result => {
53
- this.initVideo(result.url, result.isMobileType, this.videoId);
54
+ this.videoUrl = result.url;
55
+ this.initVideo(result.url, this.videoId);
54
56
  }).catch(() => {
55
57
  throw new Error('Failure of the videoService');
56
58
  });
57
59
  }
58
- initVideo(videoUrl, isMobileType, videoId) {
60
+ initVideo(videoUrl, videoId) {
59
61
  const patt = /https:.+.m3u8/;
60
62
  if (videoUrl.indexOf('http:') !== -1) {
61
63
  videoUrl = videoUrl.replace('http:', 'https:');
@@ -68,6 +70,8 @@ export class VideoElement extends ConditionalDisplayElement {
68
70
  this.addVideoAddressToolTip(videoToolTip);
69
71
  return;
70
72
  }
73
+ const isAndroid = !!navigator.userAgent.match(/(Android)/i);
74
+ const isIos = !!navigator.userAgent.match(/(Mac)/i);
71
75
  const currentRect = this.$element.find('rect#rect' + videoId).first();
72
76
  if (!currentRect.length) {
73
77
  return;
@@ -77,16 +81,18 @@ export class VideoElement extends ConditionalDisplayElement {
77
81
  const chartHeight = clientRect.height;
78
82
  const left = this.model.location.x / this.guiSize.width * $('.' + this.svgRootClass).find('.svg-content').width();
79
83
  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);
84
+ const scareX = this.model.location.x / this.guiSize.width;
85
+ const scareY = this.model.location.y / this.guiSize.height;
86
+ if (isIos) {
87
+ videoUrl = videoUrl + '#t=1';
88
+ }
89
+ const preload = isIos ? ' preload=\'metadata\'' : '';
90
+ let videoHtml = `<video scareX="${scareX}"
91
+ scareY="${scareY}" id="${videoId}" ${preload} src="${videoUrl}" width="${chartWidth}" height="${chartHeight}"
92
+ style="position: absolute;top:${top}px;left:${left}px;object-fit:fill;z-index:0;"
93
+ playsInline webkit-playsinline `;
85
94
  if (this.isMobileMode) {
86
95
  if (isAndroid) {
87
- if (isMobileType) {
88
- videoHtml += ' controls ';
89
- }
90
96
  videoHtml += ' autoplay muted></video>';
91
97
  }
92
98
  else {
@@ -100,10 +106,25 @@ export class VideoElement extends ConditionalDisplayElement {
100
106
  if (this.isShow === false) {
101
107
  $('#' + this.videoId).hide();
102
108
  }
103
- this.videoPlayer = new EZUIPlayer(videoId);
104
- if (isAndroid && !isMobileType) {
105
- this.setAndroidVideo(videoId);
106
- }
109
+ setTimeout(() => {
110
+ if (isAndroid) {
111
+ this.setAndroidVideo(videoId);
112
+ }
113
+ else if (isIos) {
114
+ this.setIosVideo(this.videoUrl, videoId);
115
+ }
116
+ try {
117
+ this.videoPlayer = new EZUIPlayer(videoId);
118
+ }
119
+ catch (err) {
120
+ console.log(err);
121
+ }
122
+ }, 1000);
123
+ const style = document.createElement('style');
124
+ style.innerHTML = `#${videoId}::-webkit-media-controls-enclosure {
125
+ display: none;
126
+ }`;
127
+ document.head.append();
107
128
  }
108
129
  addVideoAddressToolTip(videoToolTip) {
109
130
  const size = this.model.size;
@@ -126,35 +147,68 @@ export class VideoElement extends ConditionalDisplayElement {
126
147
  this.$element.append(textElement.Element);
127
148
  }
128
149
  setAndroidVideo(videoId) {
129
- let isFullscreen = false;
130
150
  const videoElement = $('#' + videoId);
131
151
  let preHeight = videoElement.height();
132
152
  let preWidth = videoElement.width();
133
153
  let preTop = videoElement.css('top');
134
154
  let preLeft = videoElement.css('left');
155
+ const { StatusBar } = window;
135
156
  videoElement.on('click', () => {
136
- if (!isFullscreen) {
157
+ if (!this.isFullscreen) {
158
+ if (StatusBar) {
159
+ StatusBar.hide();
160
+ }
137
161
  preHeight = videoElement.height();
138
162
  preWidth = videoElement.width();
139
163
  preTop = videoElement.css('top');
140
164
  preLeft = videoElement.css('left');
141
- const width = document.body.clientWidth;
142
- const height = width * 9 / 16;
165
+ const width = document.documentElement.clientWidth;
166
+ const height = document.documentElement.clientHeight;
167
+ videoElement.css('object-fit', 'contain');
168
+ videoElement.css('background', '#000000');
143
169
  videoElement.css('width', width + 'px');
144
170
  videoElement.css('height', height + 'px');
145
171
  videoElement.css('left', '0px');
146
172
  videoElement.css('top', '0px');
147
173
  videoElement.css('z-index', '99');
148
- isFullscreen = true;
174
+ videoElement.css('position', 'fixed');
175
+ this.isFullscreen = true;
176
+ try {
177
+ screen.orientation.lock(screen.orientation.type);
178
+ }
179
+ catch (error) {
180
+ console.error(error);
181
+ }
149
182
  }
150
183
  else {
184
+ videoElement.css('object-fit', 'fill');
151
185
  videoElement.css('width', preWidth + 'px');
152
186
  videoElement.css('height', preHeight + 'px');
153
187
  videoElement.css('left', preLeft);
154
188
  videoElement.css('top', preTop);
155
189
  videoElement.css('z-index', '0');
156
- isFullscreen = false;
190
+ videoElement.css('position', 'absolute');
191
+ this.isFullscreen = false;
192
+ try {
193
+ if (screen.orientation.type.includes('portrait')) {
194
+ StatusBar.show();
195
+ }
196
+ }
197
+ catch (error) {
198
+ console.error(error);
199
+ }
157
200
  }
158
201
  });
159
202
  }
203
+ setIosVideo(videoUrl, videoId) {
204
+ const video = $('#' + this.videoId);
205
+ video.on('webkitendfullscreen', () => {
206
+ video.remove();
207
+ clearTimeout(this.refreshTimer);
208
+ this.refreshTimer = null;
209
+ this.refreshTimer = setTimeout(() => {
210
+ this.initVideo(videoUrl, videoId);
211
+ }, 500);
212
+ });
213
+ }
160
214
  }
@@ -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":27,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":28,"character":18},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":29,"character":27},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":30,"character":30},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":31,"character":23},{"__symbolic":"reference","module":"../../service","name":"VideoService","line":32,"character":39},{"__symbolic":"reference","module":"../../model","name":"Size","line":33,"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"}],"setIosVideo":[{"__symbolic":"method"}]}}}}]
@@ -170,6 +170,9 @@ export class ViewOperationElement extends ConditionalEnableElement {
170
170
  const viewIndex = this.model.viewIndex;
171
171
  if (null != viewIndex) {
172
172
  this.popupViewService.popView(viewIndex, this.hostContainerId, this.el).subscribe(() => this.recordViewOperation(), error => this.logger.error(`ToggleView(${viewIndex}) failed. ${error}`));
173
+ $(`#${this.hostContainerId} video`)
174
+ .addClass('video-hidden')
175
+ .css('visibility', 'hidden');
173
176
  }
174
177
  else {
175
178
  this.logger.error('[GUI]Toggle View:invalid view index');
@@ -177,6 +180,11 @@ export class ViewOperationElement extends ConditionalEnableElement {
177
180
  }
178
181
  closeView() {
179
182
  this.popupViewService.closeView();
183
+ if ($(`#${this.hostContainerId} > svg > svg`).length === 0) {
184
+ $(`#${this.hostContainerId} .video-hidden`)
185
+ .removeClass('video-hidden')
186
+ .css('visibility', 'visible');
187
+ }
180
188
  this.recordViewOperation();
181
189
  }
182
190
  moveView(movementX, movementY) {
@@ -45,7 +45,6 @@ export class WeatherElement extends ConditionalDisplayElement {
45
45
  }
46
46
  handleGettingAddress() {
47
47
  this.handleUnusualCommon(this.localization.weatherNotAvailable);
48
- setTimeout(() => this.initWeatherInfo(), 1000 * 60);
49
48
  }
50
49
  handleNoAddress() {
51
50
  this.handleUnusualCommon(this.localization.weatherNotAddress);
@@ -1,12 +1,13 @@
1
1
  import { ConfigStore } from '../config';
2
2
  import { VariableCommunicator } from '../communication';
3
3
  import { SecurityChecker } from '../security';
4
- import { VideoService, WeatherService, PermissionChecker, OperationRecordService } from '../service';
4
+ import { VideoService, WeatherService, PermissionChecker, OperationRecordService, ReleasedVariableService } from '../service';
5
5
  export interface GuiContext {
6
6
  readonly configStore: ConfigStore;
7
7
  readonly variableCommunicator: VariableCommunicator;
8
8
  readonly permissionChecker: PermissionChecker;
9
9
  readonly operationRecordService: OperationRecordService;
10
+ readonly releasedVariableService: ReleasedVariableService;
10
11
  readonly securityChecker: SecurityChecker;
11
12
  readonly videoService: VideoService;
12
13
  readonly weatherService: WeatherService;
package/gui/gui-host.d.ts CHANGED
@@ -13,7 +13,7 @@ export declare class GuiHost implements Disposable {
13
13
  readonly el: ElementRef;
14
14
  private isLoaded;
15
15
  private currentView;
16
- private currentViewIndex;
16
+ currentViewIndex: number;
17
17
  private containerEl;
18
18
  private currentViewSize;
19
19
  private currentViewReiszeMode;
@@ -24,10 +24,12 @@ export declare class GuiComponent implements OnChanges, OnDestroy {
24
24
  initHeight: number;
25
25
  lastScale: number;
26
26
  isMobileMode: boolean;
27
+ hostContainerId: string;
27
28
  private $svg;
28
29
  private host;
29
30
  private get viewResizeMode();
30
31
  private readonly globalSettings;
32
+ private readonly viewService;
31
33
  constructor(el: ElementRef, localization: Localization, injector: Injector, bsModalService: BsModalService);
32
34
  ngOnChanges(changes: {
33
35
  [propKey: string]: SimpleChange;
@@ -39,4 +41,5 @@ export declare class GuiComponent implements OnChanges, OnDestroy {
39
41
  private onSizeChanged;
40
42
  private onResizeModeChanged;
41
43
  private onDisplayModeChanged;
44
+ refreshCurrentPage(): boolean;
42
45
  }
@@ -18,6 +18,7 @@ import { Size } from '../model';
18
18
  import { DisplayMode, GlobalSettings, ViewResizeMode } from '../settings';
19
19
  import { GuiHost } from './gui-host';
20
20
  import { Guid } from '../utils/guid';
21
+ import { ViewService } from '../view/view.service';
21
22
  let GuiComponent = class GuiComponent {
22
23
  constructor(el, localization, injector, bsModalService) {
23
24
  this.el = el;
@@ -29,6 +30,7 @@ let GuiComponent = class GuiComponent {
29
30
  this.lastScale = 1;
30
31
  this.isMobileMode = false;
31
32
  this.globalSettings = this.injector.get(GlobalSettings);
33
+ this.viewService = injector.get(ViewService);
32
34
  }
33
35
  get viewResizeMode() {
34
36
  switch (this.resizeMode) {
@@ -131,11 +133,11 @@ let GuiComponent = class GuiComponent {
131
133
  this.$svg = $(this.el.nativeElement).find('div.svgView').first();
132
134
  this.$svg.empty();
133
135
  const svgRootClass = 'S' + Guid.newGuid().toString('n');
134
- const hostContainerId = 'H' + Guid.newGuid().toString('n');
136
+ this.hostContainerId = 'H' + Guid.newGuid().toString('n');
135
137
  this.$svg.addClass(svgRootClass);
136
138
  const guiOptions = {
137
139
  svgRootClass: svgRootClass,
138
- hostContainerId: hostContainerId,
140
+ hostContainerId: this.hostContainerId,
139
141
  el: this.el
140
142
  };
141
143
  const host = new GuiHost(this.injector, this.bsModalService, newValue, guiOptions, this.el);
@@ -190,6 +192,17 @@ let GuiComponent = class GuiComponent {
190
192
  this.isMobileMode = this.displayMode === 'Mobile';
191
193
  this.globalSettings.displayMode = this.isMobileMode ? DisplayMode.Mobile : DisplayMode.Web;
192
194
  }
195
+ refreshCurrentPage() {
196
+ if (this.host.currentViewIndex === undefined) {
197
+ return false;
198
+ }
199
+ const toggleView = this.viewService.toggleViews.get(this.el);
200
+ if (!toggleView) {
201
+ return false;
202
+ }
203
+ toggleView(this.host.currentViewIndex, this.hostContainerId, this.el).subscribe();
204
+ return true;
205
+ }
193
206
  };
194
207
  __decorate([
195
208
  Input(),
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"GuiComponent":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Component","line":11,"character":1},"arguments":[{"selector":"fc-gui","template":"<div> <div class='svgView' style=\"position: relative;display: flex;justify-content: center;align-items: center;\"></div> </div> "}]}],"members":{"context":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":17,"character":5}}]}],"size":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":18,"character":5}}]}],"resizeMode":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":19,"character":5}}]}],"displayMode":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":20,"character":5}}]}],"loadFailed":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Output","line":21,"character":5}}]}],"loaded":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Output","line":22,"character":5}}]}],"__ctor__":[{"__symbolic":"constructor","parameterDecorators":[null,[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Inject","line":46,"character":9},"arguments":[{"__symbolic":"reference","module":"../localization","name":"LOCALIZATION","line":46,"character":16}]}],null,null],"parameters":[{"__symbolic":"reference","module":"@angular/core","name":"ElementRef","line":45,"character":37},{"__symbolic":"reference","module":"../localization","name":"Localization","line":46,"character":61},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":47,"character":35},{"__symbolic":"reference","module":"ngx-bootstrap/modal","name":"BsModalService","line":48,"character":41}]}],"ngOnChanges":[{"__symbolic":"method"}],"doubleFingerZooming":[{"__symbolic":"method"}],"getDistance":[{"__symbolic":"method"}],"ngOnDestroy":[{"__symbolic":"method"}],"onProviderChanged":[{"__symbolic":"method"}],"onSizeChanged":[{"__symbolic":"method"}],"onResizeModeChanged":[{"__symbolic":"method"}],"onDisplayModeChanged":[{"__symbolic":"method"}]}}}}]
1
+ [{"__symbolic":"module","version":4,"metadata":{"GuiComponent":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Component","line":12,"character":1},"arguments":[{"selector":"fc-gui","template":"<div> <div class='svgView' style=\"position: relative;display: flex;justify-content: center;align-items: center;\"></div> </div> "}]}],"members":{"context":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":18,"character":5}}]}],"size":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":19,"character":5}}]}],"resizeMode":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":20,"character":5}}]}],"displayMode":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":21,"character":5}}]}],"loadFailed":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Output","line":22,"character":5}}]}],"loaded":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Output","line":23,"character":5}}]}],"__ctor__":[{"__symbolic":"constructor","parameterDecorators":[null,[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Inject","line":50,"character":9},"arguments":[{"__symbolic":"reference","module":"../localization","name":"LOCALIZATION","line":50,"character":16}]}],null,null],"parameters":[{"__symbolic":"reference","module":"@angular/core","name":"ElementRef","line":49,"character":37},{"__symbolic":"reference","module":"../localization","name":"Localization","line":50,"character":61},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":51,"character":35},{"__symbolic":"reference","module":"ngx-bootstrap/modal","name":"BsModalService","line":52,"character":41}]}],"ngOnChanges":[{"__symbolic":"method"}],"doubleFingerZooming":[{"__symbolic":"method"}],"getDistance":[{"__symbolic":"method"}],"ngOnDestroy":[{"__symbolic":"method"}],"onProviderChanged":[{"__symbolic":"method"}],"onSizeChanged":[{"__symbolic":"method"}],"onResizeModeChanged":[{"__symbolic":"method"}],"onDisplayModeChanged":[{"__symbolic":"method"}],"refreshCurrentPage":[{"__symbolic":"method"}]}}}}]
@@ -4,8 +4,10 @@ export interface Localization {
4
4
  loadFailed: any;
5
5
  setting: any;
6
6
  submit: any;
7
+ submitting: any;
7
8
  numericalValueRequired: any;
8
9
  invalidNumericalValue: any;
10
+ writeValueTimeout: any;
9
11
  binaryType: any;
10
12
  decimalType: any;
11
13
  hexadecimalType: any;
@@ -30,7 +32,9 @@ export interface Localization {
30
32
  permissiontip: any;
31
33
  conditionIsNotMetTip: any;
32
34
  chartNoData: any;
35
+ lastThirtyMinutes: any;
33
36
  lastOneHour: any;
37
+ lastEightHour: any;
34
38
  lastTwentyFourHours: any;
35
39
  lastSevenDays: any;
36
40
  lastThirtyDays: any;
@@ -47,5 +51,8 @@ export interface Localization {
47
51
  weatherNotSupport: any;
48
52
  weatherNotAddress: any;
49
53
  weatherNotAvailable: any;
54
+ airQualityNotSupport: any;
55
+ airQualityNotAddress: any;
56
+ airQualityNotAvailable: any;
50
57
  }
51
58
  export declare const DefaultLocalization: Localization;