@raydiant/playlist-window-manager 0.21.1 → 0.21.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/PresentationWindow.ts +1 -1
- package/tasks/npm-publish.sh +1 -1
- package/build/BrowserViewRenderer.d.ts +0 -19
- package/build/BrowserViewRenderer.js +0 -212
- package/build/BrowserWindowRenderer.d.ts +0 -47
- package/build/BrowserWindowRenderer.js +0 -521
- package/build/IFrameRenderer.d.ts +0 -20
- package/build/IFrameRenderer.js +0 -226
- package/build/PlaylistWindowManager.d.ts +0 -106
- package/build/PlaylistWindowManager.js +0 -1017
- package/build/PlaylistWindowManagerState.d.ts +0 -28
- package/build/PlaylistWindowManagerState.js +0 -60
- package/build/PresentationWindow.d.ts +0 -142
- package/build/PresentationWindow.js +0 -1138
- package/build/PresentationWindow.test.d.ts +0 -1
- package/build/PresentationWindow.test.js +0 -241
- package/build/WindowLoadError.d.ts +0 -3
- package/build/WindowLoadError.js +0 -29
- package/build/WindowTimeoutError.d.ts +0 -3
- package/build/WindowTimeoutError.js +0 -29
- package/build/WindowUnresponsiveError.d.ts +0 -3
- package/build/WindowUnresponsiveError.js +0 -29
- package/build/embeddedApps.d.ts +0 -2
- package/build/embeddedApps.js +0 -59
- package/build/embeddedApps.test.d.ts +0 -1
- package/build/embeddedApps.test.js +0 -123
- package/build/index.d.ts +0 -10
- package/build/index.js +0 -30
- package/build/preload.d.ts +0 -1
- package/build/preload.js +0 -20
- package/build/testUtils.d.ts +0 -43
- package/build/testUtils.js +0 -208
- package/build/types.d.ts +0 -142
- package/build/types.js +0 -2
|
@@ -1,1138 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
-
if (k2 === undefined) k2 = k;
|
|
15
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
-
}
|
|
19
|
-
Object.defineProperty(o, k2, desc);
|
|
20
|
-
}) : (function(o, m, k, k2) {
|
|
21
|
-
if (k2 === undefined) k2 = k;
|
|
22
|
-
o[k2] = m[k];
|
|
23
|
-
}));
|
|
24
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
-
}) : function(o, v) {
|
|
27
|
-
o["default"] = v;
|
|
28
|
-
});
|
|
29
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
30
|
-
if (mod && mod.__esModule) return mod;
|
|
31
|
-
var result = {};
|
|
32
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
33
|
-
__setModuleDefault(result, mod);
|
|
34
|
-
return result;
|
|
35
|
-
};
|
|
36
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
37
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
38
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
39
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
40
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
41
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
42
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
43
|
-
});
|
|
44
|
-
};
|
|
45
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
46
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
47
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
48
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
49
|
-
function step(op) {
|
|
50
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
51
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
52
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
53
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
54
|
-
switch (op[0]) {
|
|
55
|
-
case 0: case 1: t = op; break;
|
|
56
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
57
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
58
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
59
|
-
default:
|
|
60
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
61
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
62
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
63
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
64
|
-
if (t[2]) _.ops.pop();
|
|
65
|
-
_.trys.pop(); continue;
|
|
66
|
-
}
|
|
67
|
-
op = body.call(thisArg, _);
|
|
68
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
69
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
73
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
74
|
-
};
|
|
75
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
76
|
-
var RE = __importStar(require("@raydiant/playlist-rule-engine"));
|
|
77
|
-
var fast_deep_equal_1 = __importDefault(require("fast-deep-equal"));
|
|
78
|
-
var uuid_1 = require("uuid");
|
|
79
|
-
var embeddedApps_1 = __importDefault(require("./embeddedApps"));
|
|
80
|
-
var PlaylistWindowManager_1 = __importDefault(require("./PlaylistWindowManager"));
|
|
81
|
-
var WindowTimeoutError_1 = __importDefault(require("./WindowTimeoutError"));
|
|
82
|
-
var WindowLoadError_1 = __importDefault(require("./WindowLoadError"));
|
|
83
|
-
// TODO: Automatically inject latest version when building in CI.
|
|
84
|
-
var defaultAppRendererUrl = 'https://apps.raydiant.com/3.0.1/index.html';
|
|
85
|
-
var isValidNumber = function (value) {
|
|
86
|
-
return typeof value === 'number' && !isNaN(value);
|
|
87
|
-
};
|
|
88
|
-
var isValidAnalyticsEvent = function (value) {
|
|
89
|
-
return value &&
|
|
90
|
-
typeof value === 'object' &&
|
|
91
|
-
typeof value.type === 'string' &&
|
|
92
|
-
typeof value.source === 'string' &&
|
|
93
|
-
(typeof value.productCategory === 'string' ||
|
|
94
|
-
value.productCategory === undefined ||
|
|
95
|
-
value.productCategory === null);
|
|
96
|
-
};
|
|
97
|
-
var PresentationWindow = /** @class */ (function () {
|
|
98
|
-
function PresentationWindow(options) {
|
|
99
|
-
var _this = this;
|
|
100
|
-
this.options = options;
|
|
101
|
-
this.didReceiveReady = false;
|
|
102
|
-
this.readyCallback = null;
|
|
103
|
-
this.didReceiveComplete = false;
|
|
104
|
-
this.completeCallback = null;
|
|
105
|
-
this.errorCallback = null;
|
|
106
|
-
this.readyTimeout = null;
|
|
107
|
-
this.windowManagers = {};
|
|
108
|
-
this.focusedWindowManager = null;
|
|
109
|
-
this.didEmbeddedAppLoad = false;
|
|
110
|
-
this.lastPlayedAt = null;
|
|
111
|
-
this.configurableDurationTimeout = null;
|
|
112
|
-
this.isWindowLocked = false;
|
|
113
|
-
this.isChildWindowLocked = {};
|
|
114
|
-
this.enableInterruptLockCallback = null;
|
|
115
|
-
this.disableInterruptLockCallback = null;
|
|
116
|
-
this.analyticsEventCallback = null;
|
|
117
|
-
this.forceMute = false;
|
|
118
|
-
this.error = null;
|
|
119
|
-
this.workerState = {};
|
|
120
|
-
this.workerSubscriptions = new Set();
|
|
121
|
-
this.runtimeSubscriptions = new Set();
|
|
122
|
-
this.previewSubscriptions = new Set();
|
|
123
|
-
this.previewState = { inputs: {} };
|
|
124
|
-
this.createObjectURLResolvers = {};
|
|
125
|
-
this.createObjectURLTimeouts = {};
|
|
126
|
-
this.handleEmbeddedMessage = function (type, payload) { return __awaiter(_this, void 0, void 0, function () {
|
|
127
|
-
var windowId, workerState;
|
|
128
|
-
return __generator(this, function (_a) {
|
|
129
|
-
windowId = this.options.windowId;
|
|
130
|
-
switch (type) {
|
|
131
|
-
case 'ready': {
|
|
132
|
-
this.logInfo("Received 'ready' from window '".concat(windowId, "'"));
|
|
133
|
-
this.handleReady();
|
|
134
|
-
break;
|
|
135
|
-
}
|
|
136
|
-
case 'complete': {
|
|
137
|
-
if (payload === undefined) {
|
|
138
|
-
this.logInfo("Received 'complete' from window '".concat(windowId, "'"));
|
|
139
|
-
this.handleComplete();
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
this.logInfo("Received 'complete' with error from window '".concat(windowId, ", error=").concat(payload, "'"));
|
|
143
|
-
this.handleError(payload);
|
|
144
|
-
}
|
|
145
|
-
break;
|
|
146
|
-
}
|
|
147
|
-
case 'runtime-subscribe': {
|
|
148
|
-
if (typeof payload === 'string') {
|
|
149
|
-
this.logInfo("Received 'runtime-subscribe' from window '".concat(windowId, "'"));
|
|
150
|
-
// The payload is the event name (ex. 'play').
|
|
151
|
-
this.runtimeSubscriptions.add(payload);
|
|
152
|
-
// Immediately send play if the app if already playing.
|
|
153
|
-
if (this.isPlaying()) {
|
|
154
|
-
this.sendMessageString('play');
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
this.logWarning("Invalid payload for runtime-subscribe message: ".concat(payload));
|
|
159
|
-
}
|
|
160
|
-
break;
|
|
161
|
-
}
|
|
162
|
-
case 'runtime-unsubscribe': {
|
|
163
|
-
if (typeof payload === 'string') {
|
|
164
|
-
this.logInfo("Received 'runtime-unsubscribe' from window '".concat(windowId, "'"));
|
|
165
|
-
// The payload is the event name (ex. 'play').
|
|
166
|
-
this.runtimeSubscriptions.delete(payload);
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
this.logWarning("Invalid payload for runtime-subscribe message: ".concat(payload));
|
|
170
|
-
}
|
|
171
|
-
break;
|
|
172
|
-
}
|
|
173
|
-
case 'worker-subscribe': {
|
|
174
|
-
if (typeof payload === 'string') {
|
|
175
|
-
this.logInfo("Received 'worker-subscribe' from window '".concat(windowId, "'"));
|
|
176
|
-
// The payload is the worker name.
|
|
177
|
-
this.workerSubscriptions.add(payload);
|
|
178
|
-
workerState = this.workerState[payload];
|
|
179
|
-
if (workerState !== undefined) {
|
|
180
|
-
this.sendMessageString('worker-state', {
|
|
181
|
-
name: payload,
|
|
182
|
-
state: workerState,
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
this.logWarning("Invalid payload for worker-subscribe message: ".concat(payload));
|
|
188
|
-
}
|
|
189
|
-
break;
|
|
190
|
-
}
|
|
191
|
-
case 'worker-unsubscribe': {
|
|
192
|
-
if (typeof payload === 'string') {
|
|
193
|
-
this.logInfo("Received 'worker-unsubscribe' from window '".concat(windowId, "'"));
|
|
194
|
-
// The payload is the worker name.
|
|
195
|
-
this.workerSubscriptions.delete(payload);
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
this.logWarning("Invalid payload for worker-unsubscribe message: ".concat(payload));
|
|
199
|
-
}
|
|
200
|
-
break;
|
|
201
|
-
}
|
|
202
|
-
case 'analytics-event': {
|
|
203
|
-
if (this.analyticsEventCallback && isValidAnalyticsEvent(payload)) {
|
|
204
|
-
this.analyticsEventCallback(payload);
|
|
205
|
-
}
|
|
206
|
-
break;
|
|
207
|
-
}
|
|
208
|
-
case 'create-object-url-result': {
|
|
209
|
-
if (isValidCreateObjectURLResultPayload(payload)) {
|
|
210
|
-
// Resolve promise with the local blob URL.
|
|
211
|
-
if (this.createObjectURLResolvers[payload.requestId]) {
|
|
212
|
-
this.createObjectURLResolvers[payload.requestId](payload.url);
|
|
213
|
-
delete this.createObjectURLResolvers[payload.requestId];
|
|
214
|
-
}
|
|
215
|
-
// Clear the timeout for the request.
|
|
216
|
-
if (this.createObjectURLTimeouts[payload.requestId]) {
|
|
217
|
-
clearTimeout(this.createObjectURLTimeouts[payload.requestId]);
|
|
218
|
-
delete this.createObjectURLTimeouts[payload.requestId];
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
this.logWarning("Invalid payload for create-object-url-result message: ".concat(payload));
|
|
223
|
-
}
|
|
224
|
-
break;
|
|
225
|
-
}
|
|
226
|
-
case 'preview-subscribe': {
|
|
227
|
-
if (typeof payload === 'string') {
|
|
228
|
-
this.logInfo("Received 'preview-subscribe' from window '".concat(windowId, "'"));
|
|
229
|
-
// The payload is the event name (ex. 'inputs').
|
|
230
|
-
this.previewSubscriptions.add(payload);
|
|
231
|
-
}
|
|
232
|
-
else {
|
|
233
|
-
this.logWarning("Invalid payload for preview-subscribe message: ".concat(payload));
|
|
234
|
-
}
|
|
235
|
-
break;
|
|
236
|
-
}
|
|
237
|
-
case 'preview-unsubscribe': {
|
|
238
|
-
if (typeof payload === 'string') {
|
|
239
|
-
this.logInfo("Received 'preview-unsubscribe' from window '".concat(windowId, "'"));
|
|
240
|
-
// The payload is the event name (ex. 'inputs').
|
|
241
|
-
this.previewSubscriptions.delete(payload);
|
|
242
|
-
}
|
|
243
|
-
else {
|
|
244
|
-
this.logWarning("Invalid payload for preview-subscribe message: ".concat(payload));
|
|
245
|
-
}
|
|
246
|
-
break;
|
|
247
|
-
}
|
|
248
|
-
default: {
|
|
249
|
-
this.logWarning("Received unknown embedded message type: ".concat(type));
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
return [2 /*return*/];
|
|
253
|
-
});
|
|
254
|
-
}); };
|
|
255
|
-
this.handleLegacyMessage = function (type, payload) { return __awaiter(_this, void 0, void 0, function () {
|
|
256
|
-
var _a, windowId, onPresentationProperties;
|
|
257
|
-
return __generator(this, function (_b) {
|
|
258
|
-
_a = this.options, windowId = _a.windowId, onPresentationProperties = _a.onPresentationProperties;
|
|
259
|
-
if (type === 'loaded') {
|
|
260
|
-
this.logInfo("Received 'loaded' from window '".concat(windowId, "'"));
|
|
261
|
-
this.sendRenderMessage();
|
|
262
|
-
}
|
|
263
|
-
if (type === 'presentation_ready') {
|
|
264
|
-
this.logInfo("Received 'presentation_ready' from window '".concat(windowId, "'"));
|
|
265
|
-
this.handleReady();
|
|
266
|
-
}
|
|
267
|
-
if (type === 'presentation_complete') {
|
|
268
|
-
this.logInfo("Received 'presentation_complete' from window '".concat(windowId, "'"));
|
|
269
|
-
this.handleComplete();
|
|
270
|
-
}
|
|
271
|
-
if (type === 'enable_interrupt_lock') {
|
|
272
|
-
this.logInfo("Received 'enable_interrupt_lock' from window '".concat(windowId, "'"));
|
|
273
|
-
this.enableInteruptLock();
|
|
274
|
-
}
|
|
275
|
-
if (type === 'disable_interrupt_lock') {
|
|
276
|
-
this.logInfo("Received 'disable_interrupt_lock' from window '".concat(windowId, "'"));
|
|
277
|
-
this.disableInteruptLock();
|
|
278
|
-
}
|
|
279
|
-
if (type === 'open_child_window') {
|
|
280
|
-
this.logInfo("Received 'open_child_window' from window '".concat(windowId, "', windowId=").concat(payload.windowId, " playlistId=").concat(payload.playlistId, " isMuted=").concat(payload.isMuted, " x=").concat(payload.x, " y=").concat(payload.y, " width=").concat(payload.width, " height=").concat(payload.height));
|
|
281
|
-
if (this.isValidOpenChildWindowPayload(payload)) {
|
|
282
|
-
this.openChildWindow(payload.windowId, payload.playlistId, {
|
|
283
|
-
x: Math.round(payload.x),
|
|
284
|
-
y: Math.round(payload.y),
|
|
285
|
-
width: Math.round(payload.width),
|
|
286
|
-
height: Math.round(payload.height),
|
|
287
|
-
}, payload.isMuted, payload.isFocused, payload.theme);
|
|
288
|
-
}
|
|
289
|
-
else {
|
|
290
|
-
this.logWarning("Invalid payload received for 'open_child_window', ignoring");
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
if (type === 'close_child_window') {
|
|
294
|
-
// TODO: Validate close_child_window message payload.
|
|
295
|
-
this.logInfo("Received 'close_child_window', windowId=".concat(payload.windowId));
|
|
296
|
-
this.closeChildWindow(payload.windowId);
|
|
297
|
-
}
|
|
298
|
-
if (type === 'log_error') {
|
|
299
|
-
this.handleError("Received error from window '".concat(windowId, "', error=").concat(JSON.stringify(payload)));
|
|
300
|
-
}
|
|
301
|
-
if (type === 'log_info') {
|
|
302
|
-
this.logInfo("Received info log from window '".concat(windowId, "', message=").concat(JSON.stringify(payload)));
|
|
303
|
-
}
|
|
304
|
-
if (type === 'log_debug') {
|
|
305
|
-
this.logDebug("Received info debug from window '".concat(windowId, "', message=").concat(JSON.stringify(payload)));
|
|
306
|
-
}
|
|
307
|
-
if (type === 'presentation_properties') {
|
|
308
|
-
this.logInfo("Received 'presentation_properties' from window '".concat(windowId, "'"));
|
|
309
|
-
if (onPresentationProperties) {
|
|
310
|
-
onPresentationProperties(payload.properties, payload.strings);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
return [2 /*return*/];
|
|
314
|
-
});
|
|
315
|
-
}); };
|
|
316
|
-
this.handleError = function (error) {
|
|
317
|
-
_this.error = error;
|
|
318
|
-
var message = error instanceof Error ? error.message : error;
|
|
319
|
-
_this.logError(message);
|
|
320
|
-
if (_this.errorCallback) {
|
|
321
|
-
_this.errorCallback(error);
|
|
322
|
-
}
|
|
323
|
-
};
|
|
324
|
-
this.builderState = options.builderState;
|
|
325
|
-
this.presentation = options.presentation;
|
|
326
|
-
this.playlistWindowManagerState = options.playlistWindowManagerState;
|
|
327
|
-
this.ruleEngineState = options.ruleEngineState;
|
|
328
|
-
this.theme = options.theme;
|
|
329
|
-
this.forceMute = options.forceMute || false;
|
|
330
|
-
this.workerState = options.workerState;
|
|
331
|
-
}
|
|
332
|
-
PresentationWindow.prototype.load = function () {
|
|
333
|
-
if (this.isEmbeddedApp()) {
|
|
334
|
-
return this.loadEmbeddedApp();
|
|
335
|
-
}
|
|
336
|
-
return this.loadLegacyApp();
|
|
337
|
-
};
|
|
338
|
-
PresentationWindow.prototype.show = function (isFocused) {
|
|
339
|
-
var _this = this;
|
|
340
|
-
if (isFocused === void 0) { isFocused = true; }
|
|
341
|
-
var _a = this.options, windowId = _a.windowId, renderer = _a.renderer;
|
|
342
|
-
// Show the main window and focus it before any child windows. Showing a child
|
|
343
|
-
// window that requires focus will move focus from the main window to the child.
|
|
344
|
-
renderer.showWindow(windowId, isFocused);
|
|
345
|
-
// Windows are created muted, check if we should unmute the window when showing.
|
|
346
|
-
// This ensures presentations that use audio take precendence over SYB playback on device.
|
|
347
|
-
// This checks the presentation for mute properties when shown but does not handle the case
|
|
348
|
-
// when an app becomes unmuted or muted while running (ie. someone interacting with a video player).
|
|
349
|
-
// A possible better solution would be to have apps fire an event when they need audio.
|
|
350
|
-
var isMuted = this.shouldMute();
|
|
351
|
-
if (!isMuted) {
|
|
352
|
-
renderer.unMuteWindow(windowId);
|
|
353
|
-
}
|
|
354
|
-
// Show child windows after main window, setting focus if necessary.
|
|
355
|
-
var isChildWindowFocused = false;
|
|
356
|
-
Object.values(this.windowManagers).map(function (wm) {
|
|
357
|
-
if (isFocused &&
|
|
358
|
-
_this.focusedWindowManager &&
|
|
359
|
-
_this.focusedWindowManager === wm) {
|
|
360
|
-
isChildWindowFocused = true;
|
|
361
|
-
wm.show(true);
|
|
362
|
-
}
|
|
363
|
-
else {
|
|
364
|
-
wm.show(false);
|
|
365
|
-
}
|
|
366
|
-
});
|
|
367
|
-
this.logInfo("Show window '".concat(windowId, "' isMuted=").concat(isMuted, " isFocused=").concat(isFocused).concat(isChildWindowFocused ? " isChildWindowFocused=true" : ''));
|
|
368
|
-
};
|
|
369
|
-
PresentationWindow.prototype.hide = function () {
|
|
370
|
-
var _a = this.options, windowId = _a.windowId, renderer = _a.renderer;
|
|
371
|
-
// Hide child windows before main window.
|
|
372
|
-
Object.values(this.windowManagers).map(function (wm) { return wm.hide(); });
|
|
373
|
-
renderer.hideWindow(windowId);
|
|
374
|
-
};
|
|
375
|
-
PresentationWindow.prototype.remove = function () {
|
|
376
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
377
|
-
var _a, windowId, renderer, err_1;
|
|
378
|
-
return __generator(this, function (_b) {
|
|
379
|
-
switch (_b.label) {
|
|
380
|
-
case 0:
|
|
381
|
-
_a = this.options, windowId = _a.windowId, renderer = _a.renderer;
|
|
382
|
-
// Clean up callbacks
|
|
383
|
-
this.readyCallback = null;
|
|
384
|
-
this.completeCallback = null;
|
|
385
|
-
this.errorCallback = null;
|
|
386
|
-
this.enableInterruptLockCallback = null;
|
|
387
|
-
this.disableInterruptLockCallback = null;
|
|
388
|
-
// Clean up subscriptions
|
|
389
|
-
this.workerSubscriptions.clear();
|
|
390
|
-
// Clear timers
|
|
391
|
-
if (this.readyTimeout) {
|
|
392
|
-
clearTimeout(this.readyTimeout);
|
|
393
|
-
this.readyTimeout = null;
|
|
394
|
-
}
|
|
395
|
-
if (this.configurableDurationTimeout) {
|
|
396
|
-
clearTimeout(this.configurableDurationTimeout);
|
|
397
|
-
this.configurableDurationTimeout = null;
|
|
398
|
-
}
|
|
399
|
-
// Remove any child window managers.
|
|
400
|
-
Object.values(this.windowManagers).forEach(function (wm) {
|
|
401
|
-
wm.destroy();
|
|
402
|
-
});
|
|
403
|
-
_b.label = 1;
|
|
404
|
-
case 1:
|
|
405
|
-
_b.trys.push([1, 3, , 4]);
|
|
406
|
-
return [4 /*yield*/, renderer.removeWindow(windowId)];
|
|
407
|
-
case 2:
|
|
408
|
-
_b.sent();
|
|
409
|
-
this.logInfo("Removed window '".concat(windowId, "'"));
|
|
410
|
-
return [3 /*break*/, 4];
|
|
411
|
-
case 3:
|
|
412
|
-
err_1 = _b.sent();
|
|
413
|
-
this.logError("Failed to remove window '".concat(windowId, "' with '").concat(err_1.message, "'"));
|
|
414
|
-
return [3 /*break*/, 4];
|
|
415
|
-
case 4: return [2 /*return*/];
|
|
416
|
-
}
|
|
417
|
-
});
|
|
418
|
-
});
|
|
419
|
-
};
|
|
420
|
-
// Method to modify the rule engine state for the inner playlist windows (called from outer playlist window manager)
|
|
421
|
-
PresentationWindow.prototype.reinitializePresentationWindowRuleEngineState = function (newRulesDataStoreObj) {
|
|
422
|
-
Object.values(this.windowManagers).forEach(function (wm) {
|
|
423
|
-
wm.reinitializeRuleEngineState(newRulesDataStoreObj);
|
|
424
|
-
});
|
|
425
|
-
};
|
|
426
|
-
PresentationWindow.prototype.play = function () {
|
|
427
|
-
var _this = this;
|
|
428
|
-
var _a = this.options, applicationVersion = _a.applicationVersion, presentation = _a.presentation;
|
|
429
|
-
if (applicationVersion.configurableDuration) {
|
|
430
|
-
var durationMs = Math.max(presentation.duration * 1000, 5000);
|
|
431
|
-
if (this.configurableDurationTimeout) {
|
|
432
|
-
clearTimeout(this.configurableDurationTimeout);
|
|
433
|
-
}
|
|
434
|
-
this.configurableDurationTimeout = setTimeout(function () {
|
|
435
|
-
if (_this.completeCallback) {
|
|
436
|
-
_this.completeCallback();
|
|
437
|
-
}
|
|
438
|
-
}, durationMs);
|
|
439
|
-
}
|
|
440
|
-
if (!this.isEmbeddedApp()) {
|
|
441
|
-
this.sendMessageString('play');
|
|
442
|
-
// Play any child window managers.
|
|
443
|
-
Object.values(this.windowManagers).forEach(function (wm) {
|
|
444
|
-
// We only want to trigger play on child windows the first play of the main window or if
|
|
445
|
-
// the child window is paused.
|
|
446
|
-
if (!wm.isPlaying() || wm.isPaused()) {
|
|
447
|
-
wm.play();
|
|
448
|
-
}
|
|
449
|
-
});
|
|
450
|
-
}
|
|
451
|
-
else if (this.runtimeSubscriptions.has('play')) {
|
|
452
|
-
// If the embedded app has subscribed to the play event, send it a play event.
|
|
453
|
-
this.sendMessageString('play');
|
|
454
|
-
}
|
|
455
|
-
this.lastPlayedAt = new Date();
|
|
456
|
-
};
|
|
457
|
-
PresentationWindow.prototype.pause = function () {
|
|
458
|
-
// Pause all child window managers.
|
|
459
|
-
Object.values(this.windowManagers).forEach(function (wm) { return wm.pause(); });
|
|
460
|
-
};
|
|
461
|
-
PresentationWindow.prototype.resume = function () {
|
|
462
|
-
// Resume all child window managers.
|
|
463
|
-
Object.values(this.windowManagers).forEach(function (wm) { return wm.resume(); });
|
|
464
|
-
};
|
|
465
|
-
PresentationWindow.prototype.reset = function () {
|
|
466
|
-
this.didReceiveComplete = false;
|
|
467
|
-
};
|
|
468
|
-
PresentationWindow.prototype.onComplete = function (callback) {
|
|
469
|
-
this.completeCallback = callback;
|
|
470
|
-
};
|
|
471
|
-
PresentationWindow.prototype.onError = function (callback) {
|
|
472
|
-
this.errorCallback = callback;
|
|
473
|
-
};
|
|
474
|
-
PresentationWindow.prototype.onEnableInterruptLock = function (callback) {
|
|
475
|
-
this.enableInterruptLockCallback = callback;
|
|
476
|
-
};
|
|
477
|
-
PresentationWindow.prototype.onDisableInterruptLock = function (callback) {
|
|
478
|
-
this.disableInterruptLockCallback = callback;
|
|
479
|
-
};
|
|
480
|
-
PresentationWindow.prototype.onAnalyticsEvent = function (callback) {
|
|
481
|
-
this.analyticsEventCallback = callback;
|
|
482
|
-
};
|
|
483
|
-
PresentationWindow.prototype.isReady = function () {
|
|
484
|
-
// TODO: To support the 'ready' event in embedded apps, they will need to tell the
|
|
485
|
-
// runtime that it should wait for ready instead of DOMLoaded. This could be a "wait
|
|
486
|
-
// for ready" option in the Developer Portal.
|
|
487
|
-
if (this.isEmbeddedApp()) {
|
|
488
|
-
return this.didEmbeddedAppLoad;
|
|
489
|
-
}
|
|
490
|
-
return this.didReceiveReady && this.allChildWindowManagersReady();
|
|
491
|
-
};
|
|
492
|
-
PresentationWindow.prototype.isComplete = function () {
|
|
493
|
-
return this.didReceiveComplete;
|
|
494
|
-
};
|
|
495
|
-
PresentationWindow.prototype.isPlaying = function () {
|
|
496
|
-
return this.lastPlayedAt !== null;
|
|
497
|
-
};
|
|
498
|
-
PresentationWindow.prototype.updateBounds = function (bounds) {
|
|
499
|
-
var _a = this.options, windowId = _a.windowId, renderer = _a.renderer;
|
|
500
|
-
renderer.updateWindowBounds(windowId, bounds);
|
|
501
|
-
};
|
|
502
|
-
PresentationWindow.prototype.didError = function () {
|
|
503
|
-
return !!this.error;
|
|
504
|
-
};
|
|
505
|
-
PresentationWindow.prototype.isLocked = function () {
|
|
506
|
-
return (this.isWindowLocked ||
|
|
507
|
-
Object.values(this.isChildWindowLocked).some(Boolean));
|
|
508
|
-
};
|
|
509
|
-
PresentationWindow.prototype.setPresentation = function (presentation, playlistWindowManagerState, ruleEngineState) {
|
|
510
|
-
this.presentation = presentation;
|
|
511
|
-
this.ruleEngineState = ruleEngineState;
|
|
512
|
-
this.playlistWindowManagerState = playlistWindowManagerState;
|
|
513
|
-
};
|
|
514
|
-
PresentationWindow.prototype.setTheme = function (theme) {
|
|
515
|
-
this.theme = theme;
|
|
516
|
-
};
|
|
517
|
-
PresentationWindow.prototype.setBuilderState = function (builderState) {
|
|
518
|
-
this.builderState = builderState;
|
|
519
|
-
};
|
|
520
|
-
PresentationWindow.prototype.setForceMute = function (forceMute) {
|
|
521
|
-
this.forceMute = forceMute;
|
|
522
|
-
};
|
|
523
|
-
PresentationWindow.prototype.reload = function () {
|
|
524
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
525
|
-
var _a, applicationVersion, windowId, updatedInputs, url;
|
|
526
|
-
return __generator(this, function (_b) {
|
|
527
|
-
switch (_b.label) {
|
|
528
|
-
case 0:
|
|
529
|
-
_a = this.options, applicationVersion = _a.applicationVersion, windowId = _a.windowId;
|
|
530
|
-
if (!this.isEmbeddedApp()) return [3 /*break*/, 4];
|
|
531
|
-
if (!applicationVersion.embeddedUrlFormat) return [3 /*break*/, 3];
|
|
532
|
-
if (!this.previewSubscriptions.has('inputs')) return [3 /*break*/, 1];
|
|
533
|
-
this.logInfo("Reload window '".concat(windowId, "' for embedded app preview state"));
|
|
534
|
-
updatedInputs = transformInputValues(this.presentation.applicationVariables);
|
|
535
|
-
if (!(0, fast_deep_equal_1.default)(updatedInputs, this.previewState.inputs)) {
|
|
536
|
-
this.sendMessageObject('preview-inputs', updatedInputs);
|
|
537
|
-
}
|
|
538
|
-
this.previewState.inputs = updatedInputs;
|
|
539
|
-
return [3 /*break*/, 3];
|
|
540
|
-
case 1:
|
|
541
|
-
url = this.getEmbeddedAppUrl();
|
|
542
|
-
this.logInfo("Reload window '".concat(windowId, "' for embedded app url '").concat(url, "'"));
|
|
543
|
-
return [4 /*yield*/, this.loadWindow(url)];
|
|
544
|
-
case 2:
|
|
545
|
-
_b.sent();
|
|
546
|
-
_b.label = 3;
|
|
547
|
-
case 3: return [3 /*break*/, 5];
|
|
548
|
-
case 4:
|
|
549
|
-
this.logInfo("Reload window '".concat(windowId, "'"));
|
|
550
|
-
this.sendRenderMessage();
|
|
551
|
-
_b.label = 5;
|
|
552
|
-
case 5: return [2 /*return*/];
|
|
553
|
-
}
|
|
554
|
-
});
|
|
555
|
-
});
|
|
556
|
-
};
|
|
557
|
-
PresentationWindow.prototype.runGetProperties = function (builderState) {
|
|
558
|
-
// Do no support conditional properties for embedded apps. We will likely
|
|
559
|
-
// change the way conditional properties work.
|
|
560
|
-
if (!this.isEmbeddedApp()) {
|
|
561
|
-
this.sendMessageString('run_get_properties', builderState);
|
|
562
|
-
}
|
|
563
|
-
};
|
|
564
|
-
PresentationWindow.prototype.createObjectURL = function (blob) {
|
|
565
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
566
|
-
return __generator(this, function (_a) {
|
|
567
|
-
if (this.isEmbeddedApp()) {
|
|
568
|
-
return [2 /*return*/, this.createObjectURLForEmbeddedApp(blob)];
|
|
569
|
-
}
|
|
570
|
-
return [2 /*return*/, URL.createObjectURL(blob)];
|
|
571
|
-
});
|
|
572
|
-
});
|
|
573
|
-
};
|
|
574
|
-
PresentationWindow.prototype.isEmbeddedApp = function () {
|
|
575
|
-
var _a = this.options, applicationVersion = _a.applicationVersion, isPreview = _a.isPreview;
|
|
576
|
-
// If the application has a source url, always use it for rendering the preview.
|
|
577
|
-
// This fixes an issue with Hoopla which is an embedded app but uses a legacy app
|
|
578
|
-
// for it's preview.
|
|
579
|
-
if (isPreview && applicationVersion.sourceUrl) {
|
|
580
|
-
return false;
|
|
581
|
-
}
|
|
582
|
-
return !!applicationVersion.embeddedUrlFormat;
|
|
583
|
-
};
|
|
584
|
-
PresentationWindow.prototype.allChildWindowManagersReady = function () {
|
|
585
|
-
// Return true if the presentation doesn't contain any playlists.
|
|
586
|
-
if (this.presentation.r.presentationsPlaylists.length === 0) {
|
|
587
|
-
return true;
|
|
588
|
-
}
|
|
589
|
-
return Object.values(this.windowManagers).every(function (wm) { return wm.isReady(); });
|
|
590
|
-
};
|
|
591
|
-
PresentationWindow.prototype.checkIsReadyCallback = function () {
|
|
592
|
-
if (this.isReady()) {
|
|
593
|
-
if (this.readyTimeout) {
|
|
594
|
-
clearTimeout(this.readyTimeout);
|
|
595
|
-
}
|
|
596
|
-
if (this.readyCallback) {
|
|
597
|
-
this.readyCallback();
|
|
598
|
-
}
|
|
599
|
-
// Trigger the enable interrupt lock callback if the presentation fired
|
|
600
|
-
// enable_interrupt_lock before presentation_ready.
|
|
601
|
-
if (this.isLocked() && this.enableInterruptLockCallback) {
|
|
602
|
-
this.enableInterruptLockCallback();
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
};
|
|
606
|
-
PresentationWindow.prototype.appendWindowIdToHash = function (urlStr, windowId) {
|
|
607
|
-
var url = new URL(urlStr);
|
|
608
|
-
var hashParams = new URLSearchParams(url.hash.slice(1));
|
|
609
|
-
hashParams.set('__raydiantWindowId', windowId);
|
|
610
|
-
url.hash = hashParams.toString();
|
|
611
|
-
return url.toString();
|
|
612
|
-
};
|
|
613
|
-
PresentationWindow.prototype.loadEmbeddedApp = function () {
|
|
614
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
615
|
-
var _a, windowId, applicationVersion, url;
|
|
616
|
-
return __generator(this, function (_b) {
|
|
617
|
-
switch (_b.label) {
|
|
618
|
-
case 0:
|
|
619
|
-
_a = this.options, windowId = _a.windowId, applicationVersion = _a.applicationVersion;
|
|
620
|
-
if (!applicationVersion.embeddedUrlFormat) {
|
|
621
|
-
throw new Error("Error loading embedded app, missing embeddedUrlFormat for '".concat(applicationVersion.id, "'"));
|
|
622
|
-
}
|
|
623
|
-
url = this.getEmbeddedAppUrl();
|
|
624
|
-
this.logInfo("Create window '".concat(windowId, "' for embedded app url '").concat(url, "'"));
|
|
625
|
-
return [4 /*yield*/, this.createAndLoadWindow(url,
|
|
626
|
-
// Embedded apps should not have a backgroundColor because some sites expect
|
|
627
|
-
// the browser default of white will be applied.
|
|
628
|
-
'#ffffff', this.handleEmbeddedMessage)];
|
|
629
|
-
case 1:
|
|
630
|
-
_b.sent();
|
|
631
|
-
this.didEmbeddedAppLoad = true;
|
|
632
|
-
this.checkIsReadyCallback();
|
|
633
|
-
return [2 /*return*/];
|
|
634
|
-
}
|
|
635
|
-
});
|
|
636
|
-
});
|
|
637
|
-
};
|
|
638
|
-
PresentationWindow.prototype.loadLegacyApp = function () {
|
|
639
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
640
|
-
var _a, windowId, _b, appRendererUrl, backgroundColor;
|
|
641
|
-
return __generator(this, function (_c) {
|
|
642
|
-
switch (_c.label) {
|
|
643
|
-
case 0:
|
|
644
|
-
_a = this.options, windowId = _a.windowId, _b = _a.appRendererUrl, appRendererUrl = _b === void 0 ? defaultAppRendererUrl : _b, backgroundColor = _a.backgroundColor;
|
|
645
|
-
this.logInfo("Create window '".concat(windowId, "'"));
|
|
646
|
-
return [4 /*yield*/, this.createAndLoadWindow(this.appendWindowIdToHash(appRendererUrl, windowId), backgroundColor || '#000000', // Default to black bg for Raydiant apps
|
|
647
|
-
this.handleLegacyMessage)];
|
|
648
|
-
case 1:
|
|
649
|
-
_c.sent();
|
|
650
|
-
return [4 /*yield*/, this.waitForPesentationReady()];
|
|
651
|
-
case 2:
|
|
652
|
-
_c.sent();
|
|
653
|
-
return [2 /*return*/];
|
|
654
|
-
}
|
|
655
|
-
});
|
|
656
|
-
});
|
|
657
|
-
};
|
|
658
|
-
PresentationWindow.prototype.createAndLoadWindow = function (url, backgroundColor, receiveMessageCallback) {
|
|
659
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
660
|
-
var _a, windowId, parentWindowId, renderer, bounds;
|
|
661
|
-
return __generator(this, function (_b) {
|
|
662
|
-
switch (_b.label) {
|
|
663
|
-
case 0:
|
|
664
|
-
_a = this.options, windowId = _a.windowId, parentWindowId = _a.parentWindowId, renderer = _a.renderer, bounds = _a.bounds;
|
|
665
|
-
renderer.createWindow({
|
|
666
|
-
windowId: windowId,
|
|
667
|
-
parentWindowId: parentWindowId,
|
|
668
|
-
bounds: bounds,
|
|
669
|
-
backgroundColor: backgroundColor,
|
|
670
|
-
receiveMessageCallback: receiveMessageCallback,
|
|
671
|
-
errorCallback: this.handleError,
|
|
672
|
-
});
|
|
673
|
-
// Mute new window. This ensures preloaded windows are muted by default and
|
|
674
|
-
// prevents opening an audio channel on the device for SYB playback. When using
|
|
675
|
-
// the BrowserWindowRenderer this will call setAudioMuted(true) but the IFrameRenderer
|
|
676
|
-
// has no API for muting so we rely on apps that use mute presentation props to be
|
|
677
|
-
// initially muted before playing.
|
|
678
|
-
this.logInfo("Mute window ".concat(windowId));
|
|
679
|
-
renderer.muteWindow(windowId);
|
|
680
|
-
return [4 /*yield*/, this.loadWindow(url)];
|
|
681
|
-
case 1:
|
|
682
|
-
_b.sent();
|
|
683
|
-
return [2 /*return*/];
|
|
684
|
-
}
|
|
685
|
-
});
|
|
686
|
-
});
|
|
687
|
-
};
|
|
688
|
-
PresentationWindow.prototype.loadWindow = function (url) {
|
|
689
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
690
|
-
var _a, windowId, renderer, err_2;
|
|
691
|
-
return __generator(this, function (_b) {
|
|
692
|
-
switch (_b.label) {
|
|
693
|
-
case 0:
|
|
694
|
-
_a = this.options, windowId = _a.windowId, renderer = _a.renderer;
|
|
695
|
-
_b.label = 1;
|
|
696
|
-
case 1:
|
|
697
|
-
_b.trys.push([1, 3, , 4]);
|
|
698
|
-
return [4 /*yield*/, renderer.loadWindow(windowId, url)];
|
|
699
|
-
case 2:
|
|
700
|
-
_b.sent();
|
|
701
|
-
this.logInfo("Loaded window '".concat(windowId, "'"));
|
|
702
|
-
return [3 /*break*/, 4];
|
|
703
|
-
case 3:
|
|
704
|
-
err_2 = _b.sent();
|
|
705
|
-
this.handleError(new WindowLoadError_1.default("Failed to load window with '".concat(err_2.message, "'")));
|
|
706
|
-
return [3 /*break*/, 4];
|
|
707
|
-
case 4: return [2 /*return*/];
|
|
708
|
-
}
|
|
709
|
-
});
|
|
710
|
-
});
|
|
711
|
-
};
|
|
712
|
-
// Send a JSON stringified message to the renderer. This is the legacy way of sending
|
|
713
|
-
// messages and should be deprecated in favor of sendMessageObject.
|
|
714
|
-
PresentationWindow.prototype.sendMessageString = function (type, payload) {
|
|
715
|
-
var _a = this.options, windowId = _a.windowId, renderer = _a.renderer;
|
|
716
|
-
var message = JSON.stringify({ type: type, payload: payload, windowId: windowId });
|
|
717
|
-
this.logInfo("Sending '".concat(type, "' to window '").concat(windowId, "'"));
|
|
718
|
-
renderer.sendMessageString(windowId, message);
|
|
719
|
-
};
|
|
720
|
-
// Send a message object to the renderer. This is the preferred way of sending messages
|
|
721
|
-
// going forward since it allows for more complex payloads like ArrayBuffers (for File Inputs).
|
|
722
|
-
PresentationWindow.prototype.sendMessageObject = function (type, payload) {
|
|
723
|
-
var _a = this.options, windowId = _a.windowId, renderer = _a.renderer;
|
|
724
|
-
this.logInfo("Sending '".concat(type, "' to window '").concat(windowId, "'"));
|
|
725
|
-
renderer.sendMessageObject(windowId, type, payload);
|
|
726
|
-
};
|
|
727
|
-
PresentationWindow.prototype.waitForPesentationReady = function () {
|
|
728
|
-
var _this = this;
|
|
729
|
-
var _a = this.options, windowId = _a.windowId, _b = _a.readyTimeoutDurationSeconds, readyTimeoutDurationSeconds = _b === void 0 ? 30 : _b;
|
|
730
|
-
return new Promise(function (resolve) {
|
|
731
|
-
if (_this.didReceiveReady) {
|
|
732
|
-
resolve();
|
|
733
|
-
}
|
|
734
|
-
else {
|
|
735
|
-
_this.readyCallback = function () {
|
|
736
|
-
resolve();
|
|
737
|
-
};
|
|
738
|
-
if (_this.readyTimeout) {
|
|
739
|
-
clearTimeout(_this.readyTimeout);
|
|
740
|
-
}
|
|
741
|
-
_this.readyTimeout = setTimeout(function () {
|
|
742
|
-
_this.handleError(new WindowTimeoutError_1.default("Window ".concat(windowId, " timed out after ").concat(readyTimeoutDurationSeconds, " seconds")));
|
|
743
|
-
// Resolve the promise is the window times out. This ensures windowManager.load() resolves
|
|
744
|
-
// even if the current window times out. Fixes an issue where the boot screen isn't removed
|
|
745
|
-
// if the first presentation times out.
|
|
746
|
-
resolve();
|
|
747
|
-
}, readyTimeoutDurationSeconds * 1000);
|
|
748
|
-
}
|
|
749
|
-
});
|
|
750
|
-
};
|
|
751
|
-
PresentationWindow.prototype.buildTheme = function () {
|
|
752
|
-
if (!this.theme)
|
|
753
|
-
return;
|
|
754
|
-
var nextTheme = __assign({}, this.theme);
|
|
755
|
-
if (nextTheme.headingFontNew && nextTheme.headingFontNew.fileUpload) {
|
|
756
|
-
nextTheme.headingFont =
|
|
757
|
-
nextTheme.headingFontNew.fileUpload.url || nextTheme.headingFont;
|
|
758
|
-
}
|
|
759
|
-
if (nextTheme.heading2FontNew && nextTheme.heading2FontNew.fileUpload) {
|
|
760
|
-
nextTheme.heading2Font =
|
|
761
|
-
nextTheme.heading2FontNew.fileUpload.url || nextTheme.heading2Font;
|
|
762
|
-
}
|
|
763
|
-
if (nextTheme.bodyFontNew && nextTheme.bodyFontNew.fileUpload) {
|
|
764
|
-
nextTheme.bodyFont =
|
|
765
|
-
nextTheme.bodyFontNew.fileUpload.url || nextTheme.bodyFont;
|
|
766
|
-
}
|
|
767
|
-
if (nextTheme.backgroundImageFileUpload) {
|
|
768
|
-
nextTheme.backgroundImage =
|
|
769
|
-
nextTheme.backgroundImageFileUpload.url || nextTheme.backgroundImage;
|
|
770
|
-
}
|
|
771
|
-
return nextTheme;
|
|
772
|
-
};
|
|
773
|
-
PresentationWindow.prototype.sendRenderMessage = function () {
|
|
774
|
-
var _a = this.options, applicationVersion = _a.applicationVersion, isPreview = _a.isPreview, device = _a.device;
|
|
775
|
-
// IFrames do not have a mute/unmute API so we are overriding any mute properties
|
|
776
|
-
// to support muting MZ zones when using the IFrameRenderer (SecondScreen).
|
|
777
|
-
if (this.forceMute) {
|
|
778
|
-
this.sendMessageString('render', {
|
|
779
|
-
builderState: this.builderState,
|
|
780
|
-
presentation: __assign(__assign({}, this.presentation), { applicationVariables: __assign(__assign({}, this.presentation.applicationVariables), {
|
|
781
|
-
// TODO: We need a better way to identify mute properties (ie. PropType.mute())
|
|
782
|
-
// Force mute the presentation, existing apps use either mute or muted.
|
|
783
|
-
mute: true, muted: true }) }),
|
|
784
|
-
theme: this.buildTheme(),
|
|
785
|
-
applicationVersion: applicationVersion,
|
|
786
|
-
device: device,
|
|
787
|
-
isPreview: isPreview,
|
|
788
|
-
});
|
|
789
|
-
}
|
|
790
|
-
else {
|
|
791
|
-
this.sendMessageString('render', {
|
|
792
|
-
builderState: this.builderState,
|
|
793
|
-
presentation: this.presentation,
|
|
794
|
-
theme: this.buildTheme(),
|
|
795
|
-
applicationVersion: applicationVersion,
|
|
796
|
-
device: device,
|
|
797
|
-
isPreview: isPreview,
|
|
798
|
-
});
|
|
799
|
-
}
|
|
800
|
-
};
|
|
801
|
-
PresentationWindow.prototype.openChildWindow = function (windowName, playlistId, bounds, forceMute, isFocused, themeOverride) {
|
|
802
|
-
if (forceMute === void 0) { forceMute = false; }
|
|
803
|
-
if (isFocused === void 0) { isFocused = false; }
|
|
804
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
805
|
-
var _a, windowId, renderer, device, readyTimeoutDurationSeconds, appRendererUrl, logger, isPreview, parentWindowManager, windowManager, prevBounds, prevThemeOverride, prevRuleEngine, prevForceMute, didBoundsChange, didForceMuteChange, didThemeOverrideChange, didPlaylistChange;
|
|
806
|
-
var _this = this;
|
|
807
|
-
return __generator(this, function (_b) {
|
|
808
|
-
switch (_b.label) {
|
|
809
|
-
case 0:
|
|
810
|
-
_a = this.options, windowId = _a.windowId, renderer = _a.renderer, device = _a.device, readyTimeoutDurationSeconds = _a.readyTimeoutDurationSeconds, appRendererUrl = _a.appRendererUrl, logger = _a.logger, isPreview = _a.isPreview;
|
|
811
|
-
parentWindowManager = this.options.windowManager;
|
|
812
|
-
windowManager = this.windowManagers[windowName];
|
|
813
|
-
if (!windowManager) return [3 /*break*/, 1];
|
|
814
|
-
prevBounds = windowManager.getBounds();
|
|
815
|
-
prevThemeOverride = windowManager.getThemeOverride();
|
|
816
|
-
prevRuleEngine = windowManager.getRuleEngine();
|
|
817
|
-
prevForceMute = windowManager.getForceMute();
|
|
818
|
-
didBoundsChange = prevBounds
|
|
819
|
-
? !(0, fast_deep_equal_1.default)(bounds, prevBounds)
|
|
820
|
-
: true;
|
|
821
|
-
if (didBoundsChange) {
|
|
822
|
-
windowManager.updateBounds(bounds);
|
|
823
|
-
}
|
|
824
|
-
didForceMuteChange = forceMute !== prevForceMute;
|
|
825
|
-
didThemeOverrideChange = prevThemeOverride
|
|
826
|
-
? !(0, fast_deep_equal_1.default)(themeOverride, prevThemeOverride)
|
|
827
|
-
: true;
|
|
828
|
-
if (didForceMuteChange || didThemeOverrideChange) {
|
|
829
|
-
windowManager.setThemeOverride(themeOverride);
|
|
830
|
-
windowManager.setForceMute(forceMute);
|
|
831
|
-
windowManager.reload();
|
|
832
|
-
}
|
|
833
|
-
didPlaylistChange = prevRuleEngine
|
|
834
|
-
? playlistId !== prevRuleEngine.playlistId
|
|
835
|
-
: true;
|
|
836
|
-
if (didPlaylistChange) {
|
|
837
|
-
windowManager.reinitialize(this.playlistWindowManagerState, this.createRuleEngine(playlistId), true);
|
|
838
|
-
}
|
|
839
|
-
return [3 /*break*/, 3];
|
|
840
|
-
case 1:
|
|
841
|
-
windowManager = new PlaylistWindowManager_1.default({
|
|
842
|
-
parentWindowId: windowId,
|
|
843
|
-
windowName: windowName,
|
|
844
|
-
ruleEngine: this.createRuleEngine(playlistId),
|
|
845
|
-
state: this.playlistWindowManagerState,
|
|
846
|
-
logger: logger,
|
|
847
|
-
device: device,
|
|
848
|
-
readyTimeoutDurationSeconds: readyTimeoutDurationSeconds,
|
|
849
|
-
appRendererUrl: appRendererUrl,
|
|
850
|
-
bounds: {
|
|
851
|
-
x: bounds.x,
|
|
852
|
-
y: bounds.y,
|
|
853
|
-
width: bounds.width,
|
|
854
|
-
height: bounds.height,
|
|
855
|
-
},
|
|
856
|
-
backgroundColor: 'transparent',
|
|
857
|
-
themeOverride: themeOverride,
|
|
858
|
-
forceMute: forceMute,
|
|
859
|
-
isPreview: isPreview,
|
|
860
|
-
onEnableInterruptLock: function () { return _this.enableInteruptLock(windowName); },
|
|
861
|
-
onDisableInterruptLock: function () { return _this.disableInteruptLock(windowName); },
|
|
862
|
-
});
|
|
863
|
-
// Hook up child window manager events to bubble up to the parent.
|
|
864
|
-
if (parentWindowManager) {
|
|
865
|
-
windowManager.on('window_preload_error', function (metadata) {
|
|
866
|
-
parentWindowManager.emit('window_preload_error', metadata);
|
|
867
|
-
});
|
|
868
|
-
windowManager.on('window_play', function (metadata) {
|
|
869
|
-
parentWindowManager.emit('window_play', metadata);
|
|
870
|
-
});
|
|
871
|
-
windowManager.on('window_end_success', function (metadata) {
|
|
872
|
-
parentWindowManager.emit('window_end_success', metadata);
|
|
873
|
-
});
|
|
874
|
-
windowManager.on('window_end_error', function (metadata) {
|
|
875
|
-
parentWindowManager.emit('window_end_error', metadata);
|
|
876
|
-
});
|
|
877
|
-
windowManager.on('window_analytics_event', function (metadata) {
|
|
878
|
-
parentWindowManager.emit('window_analytics_event', metadata);
|
|
879
|
-
});
|
|
880
|
-
}
|
|
881
|
-
this.windowManagers[windowName] = windowManager;
|
|
882
|
-
windowManager.setRenderer(renderer);
|
|
883
|
-
return [4 /*yield*/, windowManager.load()];
|
|
884
|
-
case 2:
|
|
885
|
-
_b.sent();
|
|
886
|
-
// The child window manager should be focused instead of the main window when focus() is called
|
|
887
|
-
// on the main window. Setting focus currently only happens on window create and can't be updated.
|
|
888
|
-
// This really only exists to support using VR with the remote in MZ. Only one child window can have
|
|
889
|
-
// focus, the last window to send an open window message wins. Handling focus needs more thought now
|
|
890
|
-
// that we have Secondscreen. We need to be extra careful about forcing focus in a touch environment.
|
|
891
|
-
if (isFocused) {
|
|
892
|
-
this.focusedWindowManager = windowManager;
|
|
893
|
-
}
|
|
894
|
-
// If a child window is opened and the presentation is already playing (Kiosk),
|
|
895
|
-
// play the window after opening it. Otherwise we'll will wait until the presentation
|
|
896
|
-
// is ready and has received play before playing it.
|
|
897
|
-
if (this.isPlaying()) {
|
|
898
|
-
windowManager.play();
|
|
899
|
-
}
|
|
900
|
-
else {
|
|
901
|
-
this.checkIsReadyCallback();
|
|
902
|
-
}
|
|
903
|
-
_b.label = 3;
|
|
904
|
-
case 3: return [2 /*return*/];
|
|
905
|
-
}
|
|
906
|
-
});
|
|
907
|
-
});
|
|
908
|
-
};
|
|
909
|
-
PresentationWindow.prototype.closeChildWindow = function (windowName) {
|
|
910
|
-
var windowManager = this.windowManagers[windowName];
|
|
911
|
-
if (windowManager) {
|
|
912
|
-
windowManager.destroy();
|
|
913
|
-
delete this.windowManagers[windowName];
|
|
914
|
-
}
|
|
915
|
-
else {
|
|
916
|
-
this.logWarning("Failed to close child window manager for '".concat(windowName, "'."));
|
|
917
|
-
}
|
|
918
|
-
};
|
|
919
|
-
PresentationWindow.prototype.enableInteruptLock = function (windowName) {
|
|
920
|
-
if (windowName) {
|
|
921
|
-
this.isChildWindowLocked[windowName] = true;
|
|
922
|
-
}
|
|
923
|
-
else {
|
|
924
|
-
this.isWindowLocked = true;
|
|
925
|
-
}
|
|
926
|
-
// If the presentation is ready and locked, trigger the enable interrupt callback.
|
|
927
|
-
if (this.isReady() && this.isLocked() && this.enableInterruptLockCallback) {
|
|
928
|
-
this.enableInterruptLockCallback();
|
|
929
|
-
}
|
|
930
|
-
};
|
|
931
|
-
PresentationWindow.prototype.disableInteruptLock = function (windowName) {
|
|
932
|
-
if (windowName) {
|
|
933
|
-
this.isChildWindowLocked[windowName] = false;
|
|
934
|
-
}
|
|
935
|
-
else {
|
|
936
|
-
this.isWindowLocked = false;
|
|
937
|
-
}
|
|
938
|
-
// If the presentation is ready and unlocked, trigger the disable interrupt callback.
|
|
939
|
-
if (this.isReady() &&
|
|
940
|
-
!this.isLocked() &&
|
|
941
|
-
this.disableInterruptLockCallback) {
|
|
942
|
-
this.disableInterruptLockCallback();
|
|
943
|
-
}
|
|
944
|
-
};
|
|
945
|
-
PresentationWindow.prototype.getEmbeddedAppUrl = function () {
|
|
946
|
-
var windowId = this.options.windowId;
|
|
947
|
-
var metadata = {
|
|
948
|
-
renderMode: this.options.isPreview ? 'preview' : 'live',
|
|
949
|
-
};
|
|
950
|
-
var url = (0, embeddedApps_1.default)(this.presentation, this.options.applicationVersion, metadata);
|
|
951
|
-
return this.appendWindowIdToHash(url, windowId);
|
|
952
|
-
};
|
|
953
|
-
PresentationWindow.prototype.handleReady = function () {
|
|
954
|
-
this.didReceiveReady = true;
|
|
955
|
-
this.checkIsReadyCallback();
|
|
956
|
-
};
|
|
957
|
-
PresentationWindow.prototype.handleComplete = function () {
|
|
958
|
-
this.didReceiveComplete = true;
|
|
959
|
-
if (this.completeCallback) {
|
|
960
|
-
this.completeCallback();
|
|
961
|
-
}
|
|
962
|
-
};
|
|
963
|
-
PresentationWindow.prototype.logDebug = function (message) {
|
|
964
|
-
this.options.logger.debug(message, this.getLogContext());
|
|
965
|
-
};
|
|
966
|
-
PresentationWindow.prototype.logInfo = function (message) {
|
|
967
|
-
this.options.logger.info(message, this.getLogContext());
|
|
968
|
-
};
|
|
969
|
-
PresentationWindow.prototype.logWarning = function (message) {
|
|
970
|
-
this.options.logger.warn(message, this.getLogContext());
|
|
971
|
-
};
|
|
972
|
-
PresentationWindow.prototype.logError = function (message) {
|
|
973
|
-
this.options.logger.error(message, this.getLogContext());
|
|
974
|
-
};
|
|
975
|
-
PresentationWindow.prototype.getLogContext = function () {
|
|
976
|
-
var _a = this.options, windowId = _a.windowId, windowName = _a.windowName, parentWindowId = _a.parentWindowId, presentation = _a.presentation, applicationVersion = _a.applicationVersion, publishedAt = _a.publishedAt, playlistId = _a.playlistId, playlistName = _a.playlistName, rule = _a.rule;
|
|
977
|
-
return {
|
|
978
|
-
windowId: windowId,
|
|
979
|
-
windowName: windowName,
|
|
980
|
-
parentWindowId: parentWindowId,
|
|
981
|
-
presentationId: presentation.id,
|
|
982
|
-
presentationName: presentation.name,
|
|
983
|
-
applicationId: applicationVersion.applicationId,
|
|
984
|
-
applicationVersionName: applicationVersion.name,
|
|
985
|
-
applicationVersionId: applicationVersion.id,
|
|
986
|
-
publishedAt: publishedAt,
|
|
987
|
-
playlistId: playlistId,
|
|
988
|
-
playlistName: playlistName,
|
|
989
|
-
rule: rule,
|
|
990
|
-
};
|
|
991
|
-
};
|
|
992
|
-
PresentationWindow.prototype.metadata = function () {
|
|
993
|
-
return this.getLogContext();
|
|
994
|
-
};
|
|
995
|
-
PresentationWindow.prototype.runWorkerSubscriptions = function (state) {
|
|
996
|
-
// For each worker subscription, compare the previous state to the new state.
|
|
997
|
-
// If the state has changed, send the new state to the subscription.
|
|
998
|
-
for (var _i = 0, _a = Array.from(this.workerSubscriptions); _i < _a.length; _i++) {
|
|
999
|
-
var workerName = _a[_i];
|
|
1000
|
-
var workerState = state[workerName];
|
|
1001
|
-
var previousWorkerState = this.workerState[workerName];
|
|
1002
|
-
if (workerState !== undefined &&
|
|
1003
|
-
!(0, fast_deep_equal_1.default)(workerState, previousWorkerState)) {
|
|
1004
|
-
this.sendMessageString('worker-state', {
|
|
1005
|
-
name: workerName,
|
|
1006
|
-
state: workerState,
|
|
1007
|
-
});
|
|
1008
|
-
}
|
|
1009
|
-
}
|
|
1010
|
-
// Persist the new state so we can compare if the previous values have changed..
|
|
1011
|
-
this.workerState = state;
|
|
1012
|
-
};
|
|
1013
|
-
PresentationWindow.prototype.createRuleEngine = function (playlistId) {
|
|
1014
|
-
var globalRule = this.options.globalRule;
|
|
1015
|
-
return new RE.RuleEngine(playlistId, this.ruleEngineState, globalRule
|
|
1016
|
-
? {
|
|
1017
|
-
// Append to the global rule with an AND to filter out other presentations
|
|
1018
|
-
// that have playlists. Prevents MZ in MZ, Kiosk in Kiosk, MZ in Kiosk, etc...
|
|
1019
|
-
type: 'and',
|
|
1020
|
-
group: [
|
|
1021
|
-
globalRule,
|
|
1022
|
-
{
|
|
1023
|
-
type: 'equals',
|
|
1024
|
-
left: { var: ['target', 'hasPlaylists'] },
|
|
1025
|
-
right: { const: false },
|
|
1026
|
-
},
|
|
1027
|
-
],
|
|
1028
|
-
}
|
|
1029
|
-
: {
|
|
1030
|
-
// A global rule was not provided so we don't need to combine the rule with an AND.
|
|
1031
|
-
type: 'equals',
|
|
1032
|
-
left: { var: ['target', 'hasPlaylists'] },
|
|
1033
|
-
right: { const: false },
|
|
1034
|
-
});
|
|
1035
|
-
};
|
|
1036
|
-
PresentationWindow.prototype.isValidOpenChildWindowPayload = function (payload) {
|
|
1037
|
-
if (!payload)
|
|
1038
|
-
return false;
|
|
1039
|
-
if (typeof payload !== 'object')
|
|
1040
|
-
return false;
|
|
1041
|
-
if (!payload.windowId)
|
|
1042
|
-
return false;
|
|
1043
|
-
if (!payload.playlistId)
|
|
1044
|
-
return false;
|
|
1045
|
-
if (!isValidNumber(payload.x))
|
|
1046
|
-
return false;
|
|
1047
|
-
if (!isValidNumber(payload.y))
|
|
1048
|
-
return false;
|
|
1049
|
-
if (!isValidNumber(payload.width))
|
|
1050
|
-
return false;
|
|
1051
|
-
if (!isValidNumber(payload.height))
|
|
1052
|
-
return false;
|
|
1053
|
-
return true;
|
|
1054
|
-
};
|
|
1055
|
-
PresentationWindow.prototype.shouldMute = function () {
|
|
1056
|
-
if (this.forceMute) {
|
|
1057
|
-
return true;
|
|
1058
|
-
}
|
|
1059
|
-
// Check app vars for muted properties. This is gross because it relies on
|
|
1060
|
-
// presentation properties having specific names. A better solution is needed
|
|
1061
|
-
// long term.
|
|
1062
|
-
var appVars = this.presentation.applicationVariables;
|
|
1063
|
-
var hasMuteProp = appVars.mute === true || appVars.muted === true;
|
|
1064
|
-
if (hasMuteProp) {
|
|
1065
|
-
return true;
|
|
1066
|
-
}
|
|
1067
|
-
var isMutedMultizone = appVars.muteZone1 === true && appVars.muteZone2 === true;
|
|
1068
|
-
return isMutedMultizone;
|
|
1069
|
-
};
|
|
1070
|
-
PresentationWindow.prototype.createObjectURLForEmbeddedApp = function (blob) {
|
|
1071
|
-
var _this = this;
|
|
1072
|
-
return new Promise(function (resolve, reject) {
|
|
1073
|
-
// Handle multiple concurrent createObjectURL calls by creating a request id for each
|
|
1074
|
-
// call. We send the request id along with the message to the running app and the app
|
|
1075
|
-
// sends the request id back with the result so we can resolve the correct promise.
|
|
1076
|
-
var requestId = (0, uuid_1.v4)();
|
|
1077
|
-
_this.createObjectURLResolvers[requestId] = resolve;
|
|
1078
|
-
// Start a timer to reject the promise if the app doesn't respond with the create object
|
|
1079
|
-
// url result within 1 second. This should be more or less instant.
|
|
1080
|
-
_this.createObjectURLTimeouts[requestId] = setTimeout(function () {
|
|
1081
|
-
var error = new Error("Timed out waiting for the create-object-url-result message for request id ".concat(requestId));
|
|
1082
|
-
reject(error);
|
|
1083
|
-
delete _this.createObjectURLResolvers[requestId];
|
|
1084
|
-
delete _this.createObjectURLTimeouts[requestId];
|
|
1085
|
-
}, 1000);
|
|
1086
|
-
// Create a FileReader object to read the file data as an ArrayBuffer.
|
|
1087
|
-
var reader = new FileReader();
|
|
1088
|
-
reader.addEventListener('load', function () {
|
|
1089
|
-
var buffer = reader.result;
|
|
1090
|
-
// Check if buffer is an ArrayBuffer
|
|
1091
|
-
if (buffer instanceof ArrayBuffer) {
|
|
1092
|
-
// Send the ArrayBuffer to the running app to create the local file blob URL.
|
|
1093
|
-
_this.sendMessageObject('create-object-url', { requestId: requestId, buffer: buffer });
|
|
1094
|
-
}
|
|
1095
|
-
}, false);
|
|
1096
|
-
reader.readAsArrayBuffer(blob);
|
|
1097
|
-
return '';
|
|
1098
|
-
});
|
|
1099
|
-
};
|
|
1100
|
-
return PresentationWindow;
|
|
1101
|
-
}());
|
|
1102
|
-
exports.default = PresentationWindow;
|
|
1103
|
-
var isValidCreateObjectURLResultPayload = function (payload) {
|
|
1104
|
-
return (
|
|
1105
|
-
// Ensure payload is an object.
|
|
1106
|
-
typeof payload === 'object' &&
|
|
1107
|
-
payload !== null &&
|
|
1108
|
-
// Ensure requestId is a string.
|
|
1109
|
-
'requestId' in payload &&
|
|
1110
|
-
typeof payload['requestId'] === 'string' &&
|
|
1111
|
-
// Ensure payload.file is an object.
|
|
1112
|
-
'url' in payload &&
|
|
1113
|
-
typeof payload['url'] === 'string');
|
|
1114
|
-
};
|
|
1115
|
-
var transformInputValues = function (inputs) {
|
|
1116
|
-
var transformed = {};
|
|
1117
|
-
// Recursively traverse inputs, transforming any file input values to remove internal
|
|
1118
|
-
// properties like file_upload_id.
|
|
1119
|
-
for (var _i = 0, _a = Object.entries(inputs); _i < _a.length; _i++) {
|
|
1120
|
-
var _b = _a[_i], key = _b[0], value = _b[1];
|
|
1121
|
-
if (typeof value === 'object' && value !== null && 'url' in value) {
|
|
1122
|
-
// Value is a file input, strip out the file_upload_id property.
|
|
1123
|
-
transformed[key] = { url: value.url };
|
|
1124
|
-
}
|
|
1125
|
-
else if (Array.isArray(value)) {
|
|
1126
|
-
// Value is an array input, traverse each item in the array for file input values.
|
|
1127
|
-
transformed[key] = [];
|
|
1128
|
-
for (var _c = 0, value_1 = value; _c < value_1.length; _c++) {
|
|
1129
|
-
var item = value_1[_c];
|
|
1130
|
-
transformed[key].push(transformInputValues(item));
|
|
1131
|
-
}
|
|
1132
|
-
}
|
|
1133
|
-
else {
|
|
1134
|
-
transformed[key] = value;
|
|
1135
|
-
}
|
|
1136
|
-
}
|
|
1137
|
-
return transformed;
|
|
1138
|
-
};
|