@raydiant/playlist-window-manager 0.16.0 → 0.17.0

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.
@@ -58,6 +58,7 @@ export default class PresentationWindow {
58
58
  private error;
59
59
  private workerState;
60
60
  private workerSubscriptions;
61
+ private runtimeSubscriptions;
61
62
  constructor(options: PresentationWindowOptions);
62
63
  load(): Promise<void>;
63
64
  show(isFocused?: boolean): void;
@@ -102,6 +103,8 @@ export default class PresentationWindow {
102
103
  private disableInteruptLock;
103
104
  private handleEmbeddedMessage;
104
105
  private handleLegacyMessage;
106
+ private handleReady;
107
+ private handleComplete;
105
108
  private handleError;
106
109
  private logDebug;
107
110
  private logInfo;
@@ -91,35 +91,85 @@ var PresentationWindow = /** @class */ (function () {
91
91
  this.error = null;
92
92
  this.workerState = {};
93
93
  this.workerSubscriptions = new Set();
94
+ this.runtimeSubscriptions = new Set();
94
95
  this.handleEmbeddedMessage = function (type, payload) { return __awaiter(_this, void 0, void 0, function () {
95
96
  var windowId, workerState;
96
97
  return __generator(this, function (_a) {
97
98
  windowId = this.options.windowId;
98
- if (type === 'worker-subscribe') {
99
- if (typeof payload === 'string') {
100
- this.logInfo("Received 'worker-subscribe' from window '" + windowId + "'");
101
- // The payload is the worker name.
102
- this.workerSubscriptions.add(payload);
103
- workerState = this.workerState[payload];
104
- if (workerState !== undefined) {
105
- this.sendMessage('worker-state', {
106
- name: payload,
107
- state: workerState
108
- });
99
+ switch (type) {
100
+ case 'ready': {
101
+ this.logInfo("Received 'ready' from window '" + windowId + "'");
102
+ this.handleReady();
103
+ break;
104
+ }
105
+ case 'complete': {
106
+ if (payload === undefined) {
107
+ this.logInfo("Received 'complete' from window '" + windowId + "'");
108
+ this.handleComplete();
109
+ }
110
+ else {
111
+ this.logInfo("Received 'complete' with error from window '" + windowId + ", error=" + payload + "'");
112
+ this.handleError(payload);
109
113
  }
114
+ break;
110
115
  }
111
- else {
112
- this.logWarning("Invalid payload for worker-subscribe message: " + payload);
116
+ case 'runtime-subscribe': {
117
+ if (typeof payload === 'string') {
118
+ this.logInfo("Received 'runtime-subscribe' from window '" + windowId + "'");
119
+ // The payload is the event name (ex. 'play').
120
+ this.runtimeSubscriptions.add(payload);
121
+ // Immediately send play if the app if already playing.
122
+ if (this.isPlaying()) {
123
+ this.sendMessage('play');
124
+ }
125
+ }
126
+ else {
127
+ this.logWarning("Invalid payload for runtime-subscribe message: " + payload);
128
+ }
129
+ break;
113
130
  }
114
- }
115
- else if (type === 'worker-unsubscribe') {
116
- if (typeof payload === 'string') {
117
- this.logInfo("Received 'worker-unsubscribe' from window '" + windowId + "'");
118
- // The payload is the worker name.
119
- this.workerSubscriptions.delete(payload);
131
+ case 'runtime-unsubscribe': {
132
+ if (typeof payload === 'string') {
133
+ this.logInfo("Received 'runtime-unsubscribe' from window '" + windowId + "'");
134
+ // The payload is the event name (ex. 'play').
135
+ this.runtimeSubscriptions.delete(payload);
136
+ }
137
+ else {
138
+ this.logWarning("Invalid payload for runtime-subscribe message: " + payload);
139
+ }
140
+ break;
120
141
  }
121
- else {
122
- this.logWarning("Invalid payload for worker-unsubscribe message: " + payload);
142
+ case 'worker-subscribe': {
143
+ if (typeof payload === 'string') {
144
+ this.logInfo("Received 'worker-subscribe' from window '" + windowId + "'");
145
+ // The payload is the worker name.
146
+ this.workerSubscriptions.add(payload);
147
+ workerState = this.workerState[payload];
148
+ if (workerState !== undefined) {
149
+ this.sendMessage('worker-state', {
150
+ name: payload,
151
+ state: workerState
152
+ });
153
+ }
154
+ }
155
+ else {
156
+ this.logWarning("Invalid payload for worker-subscribe message: " + payload);
157
+ }
158
+ break;
159
+ }
160
+ case 'worker-unsubscribe': {
161
+ if (typeof payload === 'string') {
162
+ this.logInfo("Received 'worker-unsubscribe' from window '" + windowId + "'");
163
+ // The payload is the worker name.
164
+ this.workerSubscriptions.delete(payload);
165
+ }
166
+ else {
167
+ this.logWarning("Invalid payload for worker-unsubscribe message: " + payload);
168
+ }
169
+ break;
170
+ }
171
+ default: {
172
+ this.logWarning("Received unknown embedded message type: " + type);
123
173
  }
124
174
  }
125
175
  return [2 /*return*/];
@@ -135,15 +185,11 @@ var PresentationWindow = /** @class */ (function () {
135
185
  }
136
186
  if (type === 'presentation_ready') {
137
187
  this.logInfo("Received 'presentation_ready' from window '" + windowId + "'");
138
- this.didReceiveReady = true;
139
- this.checkIsReadyCallback();
188
+ this.handleReady();
140
189
  }
141
190
  if (type === 'presentation_complete') {
142
191
  this.logInfo("Received 'presentation_complete' from window '" + windowId + "'");
143
- this.didReceiveComplete = true;
144
- if (this.completeCallback) {
145
- this.completeCallback();
146
- }
192
+ this.handleComplete();
147
193
  }
148
194
  if (type === 'enable_interrupt_lock') {
149
195
  this.logInfo("Received 'enable_interrupt_lock' from window '" + windowId + "'");
@@ -318,13 +364,17 @@ var PresentationWindow = /** @class */ (function () {
318
364
  this.sendMessage('play');
319
365
  // Play any child window managers.
320
366
  Object.values(this.windowManagers).forEach(function (wm) {
321
- // We only want trigger play on child windows the first play of the main window or if
367
+ // We only want to trigger play on child windows the first play of the main window or if
322
368
  // the child window is paused.
323
369
  if (!wm.isPlaying() || wm.isPaused()) {
324
370
  wm.play();
325
371
  }
326
372
  });
327
373
  }
374
+ else if (this.runtimeSubscriptions.has('play')) {
375
+ // If the embedded app has subscribed to the play event, send it a play event.
376
+ this.sendMessage('play');
377
+ }
328
378
  this.lastPlayedAt = new Date();
329
379
  };
330
380
  PresentationWindow.prototype.pause = function () {
@@ -351,6 +401,9 @@ var PresentationWindow = /** @class */ (function () {
351
401
  this.disableInterruptLockCallback = callback;
352
402
  };
353
403
  PresentationWindow.prototype.isReady = function () {
404
+ // TODO: To support the 'ready' event in embedded apps, they will need to tell the
405
+ // runtime that it should wait for ready instead of DOMLoaded. This could be a "wait
406
+ // for ready" option in the Developer Portal.
354
407
  if (this.isEmbeddedApp()) {
355
408
  return this.didEmbeddedAppLoad;
356
409
  }
@@ -774,6 +827,16 @@ var PresentationWindow = /** @class */ (function () {
774
827
  this.disableInterruptLockCallback();
775
828
  }
776
829
  };
830
+ PresentationWindow.prototype.handleReady = function () {
831
+ this.didReceiveReady = true;
832
+ this.checkIsReadyCallback();
833
+ };
834
+ PresentationWindow.prototype.handleComplete = function () {
835
+ this.didReceiveComplete = true;
836
+ if (this.completeCallback) {
837
+ this.completeCallback();
838
+ }
839
+ };
777
840
  PresentationWindow.prototype.logDebug = function (message) {
778
841
  this.options.logger.debug(message, this.getLogContext());
779
842
  };
package/build/preload.js CHANGED
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  var electron_1 = require("electron");
4
4
  var internals = {
5
5
  sendMessage: function (windowId, type, payload) {
6
- electron_1.ipcRenderer.send.apply(electron_1.ipcRenderer, [windowId, type].concat(payload));
6
+ electron_1.ipcRenderer.send(windowId, type, payload);
7
7
  }
8
8
  };
9
9
  // Set __RAYDIANT_INTERNALS on window so it is accessible in to the running application.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raydiant/playlist-window-manager",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "Window manager for playlist playback.",
5
5
  "main": "build/index.js",
6
6
  "scripts": {
@@ -86,6 +86,7 @@ export default class PresentationWindow {
86
86
 
87
87
  private workerState: WorkerState = {};
88
88
  private workerSubscriptions = new Set<string>();
89
+ private runtimeSubscriptions = new Set<string>();
89
90
 
90
91
  constructor(private options: PresentationWindowOptions) {
91
92
  this.builderState = options.builderState;
@@ -218,12 +219,15 @@ export default class PresentationWindow {
218
219
 
219
220
  // Play any child window managers.
220
221
  Object.values(this.windowManagers).forEach(wm => {
221
- // We only want trigger play on child windows the first play of the main window or if
222
+ // We only want to trigger play on child windows the first play of the main window or if
222
223
  // the child window is paused.
223
224
  if (!wm.isPlaying() || wm.isPaused()) {
224
225
  wm.play();
225
226
  }
226
227
  });
228
+ } else if (this.runtimeSubscriptions.has('play')) {
229
+ // If the embedded app has subscribed to the play event, send it a play event.
230
+ this.sendMessage('play');
227
231
  }
228
232
 
229
233
  this.lastPlayedAt = new Date();
@@ -260,6 +264,9 @@ export default class PresentationWindow {
260
264
  }
261
265
 
262
266
  public isReady() {
267
+ // TODO: To support the 'ready' event in embedded apps, they will need to tell the
268
+ // runtime that it should wait for ready instead of DOMLoaded. This could be a "wait
269
+ // for ready" option in the Developer Portal.
263
270
  if (this.isEmbeddedApp()) {
264
271
  return this.didEmbeddedAppLoad;
265
272
  }
@@ -731,37 +738,103 @@ export default class PresentationWindow {
731
738
  private handleEmbeddedMessage = async (type: string, payload?: any) => {
732
739
  const { windowId } = this.options;
733
740
 
734
- if (type === 'worker-subscribe') {
735
- if (typeof payload === 'string') {
736
- this.logInfo(`Received 'worker-subscribe' from window '${windowId}'`);
737
-
738
- // The payload is the worker name.
739
- this.workerSubscriptions.add(payload);
740
-
741
- // Send the current state to the worker if it exists as soon
742
- // as the app subscribes.
743
- const workerState = this.workerState[payload];
744
- if (workerState !== undefined) {
745
- this.sendMessage('worker-state', {
746
- name: payload,
747
- state: workerState
748
- });
741
+ switch (type) {
742
+ case 'ready': {
743
+ this.logInfo(`Received 'ready' from window '${windowId}'`);
744
+ this.handleReady();
745
+ break;
746
+ }
747
+
748
+ case 'complete': {
749
+ if (payload === undefined) {
750
+ this.logInfo(`Received 'complete' from window '${windowId}'`);
751
+ this.handleComplete();
752
+ } else {
753
+ this.logInfo(
754
+ `Received 'complete' with error from window '${windowId}, error=${payload}'`
755
+ );
756
+ this.handleError(payload);
749
757
  }
750
- } else {
751
- this.logWarning(
752
- `Invalid payload for worker-subscribe message: ${payload}`
753
- );
758
+ break;
754
759
  }
755
- } else if (type === 'worker-unsubscribe') {
756
- if (typeof payload === 'string') {
757
- this.logInfo(`Received 'worker-unsubscribe' from window '${windowId}'`);
758
760
 
759
- // The payload is the worker name.
760
- this.workerSubscriptions.delete(payload);
761
- } else {
762
- this.logWarning(
763
- `Invalid payload for worker-unsubscribe message: ${payload}`
764
- );
761
+ case 'runtime-subscribe': {
762
+ if (typeof payload === 'string') {
763
+ this.logInfo(
764
+ `Received 'runtime-subscribe' from window '${windowId}'`
765
+ );
766
+ // The payload is the event name (ex. 'play').
767
+ this.runtimeSubscriptions.add(payload);
768
+
769
+ // Immediately send play if the app if already playing.
770
+ if (this.isPlaying()) {
771
+ this.sendMessage('play');
772
+ }
773
+ } else {
774
+ this.logWarning(
775
+ `Invalid payload for runtime-subscribe message: ${payload}`
776
+ );
777
+ }
778
+ break;
779
+ }
780
+
781
+ case 'runtime-unsubscribe': {
782
+ if (typeof payload === 'string') {
783
+ this.logInfo(
784
+ `Received 'runtime-unsubscribe' from window '${windowId}'`
785
+ );
786
+ // The payload is the event name (ex. 'play').
787
+ this.runtimeSubscriptions.delete(payload);
788
+ } else {
789
+ this.logWarning(
790
+ `Invalid payload for runtime-subscribe message: ${payload}`
791
+ );
792
+ }
793
+ break;
794
+ }
795
+
796
+ case 'worker-subscribe': {
797
+ if (typeof payload === 'string') {
798
+ this.logInfo(`Received 'worker-subscribe' from window '${windowId}'`);
799
+
800
+ // The payload is the worker name.
801
+ this.workerSubscriptions.add(payload);
802
+
803
+ // Send the current state to the worker if it exists as soon
804
+ // as the app subscribes.
805
+ const workerState = this.workerState[payload];
806
+ if (workerState !== undefined) {
807
+ this.sendMessage('worker-state', {
808
+ name: payload,
809
+ state: workerState
810
+ });
811
+ }
812
+ } else {
813
+ this.logWarning(
814
+ `Invalid payload for worker-subscribe message: ${payload}`
815
+ );
816
+ }
817
+ break;
818
+ }
819
+
820
+ case 'worker-unsubscribe': {
821
+ if (typeof payload === 'string') {
822
+ this.logInfo(
823
+ `Received 'worker-unsubscribe' from window '${windowId}'`
824
+ );
825
+
826
+ // The payload is the worker name.
827
+ this.workerSubscriptions.delete(payload);
828
+ } else {
829
+ this.logWarning(
830
+ `Invalid payload for worker-unsubscribe message: ${payload}`
831
+ );
832
+ }
833
+ break;
834
+ }
835
+
836
+ default: {
837
+ this.logWarning(`Received unknown embedded message type: ${type}`);
765
838
  }
766
839
  }
767
840
  };
@@ -776,18 +849,14 @@ export default class PresentationWindow {
776
849
 
777
850
  if (type === 'presentation_ready') {
778
851
  this.logInfo(`Received 'presentation_ready' from window '${windowId}'`);
779
- this.didReceiveReady = true;
780
- this.checkIsReadyCallback();
852
+ this.handleReady();
781
853
  }
782
854
 
783
855
  if (type === 'presentation_complete') {
784
856
  this.logInfo(
785
857
  `Received 'presentation_complete' from window '${windowId}'`
786
858
  );
787
- this.didReceiveComplete = true;
788
- if (this.completeCallback) {
789
- this.completeCallback();
790
- }
859
+ this.handleComplete();
791
860
  }
792
861
 
793
862
  if (type === 'enable_interrupt_lock') {
@@ -871,6 +940,18 @@ export default class PresentationWindow {
871
940
  }
872
941
  };
873
942
 
943
+ private handleReady() {
944
+ this.didReceiveReady = true;
945
+ this.checkIsReadyCallback();
946
+ }
947
+
948
+ private handleComplete() {
949
+ this.didReceiveComplete = true;
950
+ if (this.completeCallback) {
951
+ this.completeCallback();
952
+ }
953
+ }
954
+
874
955
  private handleError = (error: any) => {
875
956
  this.error = error;
876
957
 
package/src/preload.ts CHANGED
@@ -7,7 +7,7 @@ interface RaydiantInternals {
7
7
 
8
8
  const internals: RaydiantInternals = {
9
9
  sendMessage: (windowId: string, type: string, payload?: any) => {
10
- ipcRenderer.send(windowId, type, ...payload);
10
+ ipcRenderer.send(windowId, type, payload);
11
11
  }
12
12
  };
13
13