videomail-client 8.3.1 → 8.3.2
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/prototype/js/videomail-client.js +12 -14
- package/prototype/js/videomail-client.min.js +1 -1
- package/prototype/js/videomail-client.min.js.map +1 -1
- package/src/js/client.js +0 -210
- package/src/js/constants.js +0 -11
- package/src/js/events.js +0 -46
- package/src/js/index.js +0 -15
- package/src/js/options.js +0 -180
- package/src/js/resource.js +0 -206
- package/src/js/util/audioRecorder.js +0 -152
- package/src/js/util/browser.js +0 -319
- package/src/js/util/collectLogger.js +0 -72
- package/src/js/util/eventEmitter.js +0 -72
- package/src/js/util/humanize.js +0 -16
- package/src/js/util/mediaEvents.js +0 -148
- package/src/js/util/pretty.js +0 -70
- package/src/js/util/standardize.js +0 -71
- package/src/js/util/videomailError.js +0 -431
- package/src/js/wrappers/buttons.js +0 -670
- package/src/js/wrappers/container.js +0 -797
- package/src/js/wrappers/dimension.js +0 -149
- package/src/js/wrappers/form.js +0 -319
- package/src/js/wrappers/optionsWrapper.js +0 -81
- package/src/js/wrappers/visuals/inside/recorder/countdown.js +0 -83
- package/src/js/wrappers/visuals/inside/recorder/facingMode.js +0 -53
- package/src/js/wrappers/visuals/inside/recorder/pausedNote.js +0 -59
- package/src/js/wrappers/visuals/inside/recorder/recordNote.js +0 -42
- package/src/js/wrappers/visuals/inside/recorder/recordTimer.js +0 -149
- package/src/js/wrappers/visuals/inside/recorderInsides.js +0 -144
- package/src/js/wrappers/visuals/notifier.js +0 -341
- package/src/js/wrappers/visuals/recorder.js +0 -1492
- package/src/js/wrappers/visuals/replay.js +0 -355
- package/src/js/wrappers/visuals/userMedia.js +0 -541
- package/src/js/wrappers/visuals.js +0 -410
- package/src/styles/css/main.min.css.js +0 -1
- package/src/styles/styl/keyframes/blink.styl +0 -16
- package/src/styles/styl/main.styl +0 -126
|
@@ -1,797 +0,0 @@
|
|
|
1
|
-
import Visibility from "document-visibility";
|
|
2
|
-
// needed for IE 11
|
|
3
|
-
import elementClosest from "element-closest";
|
|
4
|
-
import hidden from "hidden";
|
|
5
|
-
import insertCss from "insert-css";
|
|
6
|
-
import inherits from "inherits";
|
|
7
|
-
|
|
8
|
-
import css from "../../styles/css/main.min.css.js";
|
|
9
|
-
import Events from "../events";
|
|
10
|
-
import Resource from "../resource";
|
|
11
|
-
import EventEmitter from "../util/eventEmitter";
|
|
12
|
-
import VideomailError from "../util/videomailError";
|
|
13
|
-
import Buttons from "./buttons";
|
|
14
|
-
import Dimension from "./dimension";
|
|
15
|
-
import Form from "./form";
|
|
16
|
-
import OptionsWrapper from "./optionsWrapper";
|
|
17
|
-
import Visuals from "./visuals";
|
|
18
|
-
|
|
19
|
-
elementClosest(window);
|
|
20
|
-
|
|
21
|
-
const Container = function (options) {
|
|
22
|
-
EventEmitter.call(this, options, "Container");
|
|
23
|
-
|
|
24
|
-
const self = this;
|
|
25
|
-
|
|
26
|
-
const visibility = Visibility();
|
|
27
|
-
const visuals = new Visuals(this, options);
|
|
28
|
-
const buttons = new Buttons(this, options);
|
|
29
|
-
const resource = new Resource(options);
|
|
30
|
-
const htmlElement =
|
|
31
|
-
document && document.querySelector && document.querySelector("html");
|
|
32
|
-
const { debug } = options;
|
|
33
|
-
|
|
34
|
-
let hasError = false;
|
|
35
|
-
let submitted = false;
|
|
36
|
-
let lastValidation = false;
|
|
37
|
-
|
|
38
|
-
let containerElement;
|
|
39
|
-
let built;
|
|
40
|
-
let form;
|
|
41
|
-
|
|
42
|
-
function prependDefaultCss() {
|
|
43
|
-
insertCss(css, { prepend: true });
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// since https://github.com/binarykitchen/videomail-client/issues/87
|
|
47
|
-
function findParentFormElement() {
|
|
48
|
-
return containerElement.closest("form");
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function getFormElement() {
|
|
52
|
-
let formElement;
|
|
53
|
-
|
|
54
|
-
if (containerElement.tagName === "FORM") {
|
|
55
|
-
formElement = containerElement;
|
|
56
|
-
} else if (options.selectors.formId) {
|
|
57
|
-
formElement = document.getElementById(options.selectors.formId);
|
|
58
|
-
} else {
|
|
59
|
-
formElement = findParentFormElement();
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return formElement;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function buildForm() {
|
|
66
|
-
const formElement = getFormElement();
|
|
67
|
-
|
|
68
|
-
if (formElement) {
|
|
69
|
-
debug("Container: buildForm()");
|
|
70
|
-
form = new Form(self, formElement, options);
|
|
71
|
-
|
|
72
|
-
const submitButton = form.findSubmitButton();
|
|
73
|
-
submitButton && buttons.setSubmitButton(submitButton);
|
|
74
|
-
|
|
75
|
-
form.build();
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function buildChildren() {
|
|
80
|
-
debug("Container: buildChildren()");
|
|
81
|
-
|
|
82
|
-
if (!containerElement.classList) {
|
|
83
|
-
self.emit(
|
|
84
|
-
Events.ERROR,
|
|
85
|
-
VideomailError.create("Sorry, your browser is too old!", options),
|
|
86
|
-
);
|
|
87
|
-
} else {
|
|
88
|
-
containerElement.classList.add("videomail");
|
|
89
|
-
|
|
90
|
-
if (!options.playerOnly) {
|
|
91
|
-
buttons.build();
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
visuals.build();
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function processError(err) {
|
|
99
|
-
hasError = true;
|
|
100
|
-
|
|
101
|
-
if (err.stack) {
|
|
102
|
-
options.logger.error(err.stack);
|
|
103
|
-
} else {
|
|
104
|
-
options.logger.error(err);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
if (options.displayErrors) {
|
|
108
|
-
visuals.error(err);
|
|
109
|
-
} else {
|
|
110
|
-
visuals.reset();
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function initEvents() {
|
|
115
|
-
debug("Container: initEvents()");
|
|
116
|
-
|
|
117
|
-
window.addEventListener("beforeunload", (e) => {
|
|
118
|
-
self.unload(e);
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
if (!options.playerOnly) {
|
|
122
|
-
visibility.onChange(function (visible) {
|
|
123
|
-
// built? see https://github.com/binarykitchen/videomail.io/issues/326
|
|
124
|
-
if (built) {
|
|
125
|
-
if (visible) {
|
|
126
|
-
if (options.isAutoPauseEnabled() && self.isCountingDown()) {
|
|
127
|
-
self.resume();
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
self.emit(Events.VISIBLE);
|
|
131
|
-
} else {
|
|
132
|
-
if (
|
|
133
|
-
options.isAutoPauseEnabled() &&
|
|
134
|
-
(self.isCountingDown() || self.isRecording())
|
|
135
|
-
) {
|
|
136
|
-
self.pause("document invisible");
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
self.emit(Events.INVISIBLE);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
if (options.enableSpace) {
|
|
146
|
-
if (!options.playerOnly) {
|
|
147
|
-
window.addEventListener("keypress", function (e) {
|
|
148
|
-
const { tagName } = e.target;
|
|
149
|
-
const isEditable =
|
|
150
|
-
e.target.isContentEditable ||
|
|
151
|
-
e.target.contentEditable === "true" ||
|
|
152
|
-
e.target.contentEditable === true;
|
|
153
|
-
|
|
154
|
-
// beware of rich text editors, hence the isEditable check (wordpress plugin issue)
|
|
155
|
-
if (!isEditable && tagName !== "INPUT" && tagName !== "TEXTAREA") {
|
|
156
|
-
const code = e.keyCode ? e.keyCode : e.which;
|
|
157
|
-
|
|
158
|
-
if (code === 32) {
|
|
159
|
-
e.preventDefault();
|
|
160
|
-
|
|
161
|
-
if (options.enablePause) {
|
|
162
|
-
visuals.pauseOrResume();
|
|
163
|
-
} else {
|
|
164
|
-
visuals.recordOrStop();
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/*
|
|
173
|
-
* better to keep the one and only error listeners
|
|
174
|
-
* at one spot, here, because unload() will do a removeAllListeners()
|
|
175
|
-
*/
|
|
176
|
-
self.on(Events.ERROR, function (err) {
|
|
177
|
-
processError(err);
|
|
178
|
-
unloadChildren(err);
|
|
179
|
-
|
|
180
|
-
if (err.removeDimensions && err.removeDimensions()) {
|
|
181
|
-
removeDimensions();
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
if (!options.playerOnly) {
|
|
186
|
-
self.on(Events.LOADED_META_DATA, function () {
|
|
187
|
-
correctDimensions();
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
function validateOptions() {
|
|
193
|
-
if (options.hasDefinedWidth() && options.video.width % 2 !== 0) {
|
|
194
|
-
throw VideomailError.create("Width must be divisible by two.", options);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
if (options.hasDefinedHeight() && options.video.height % 2 !== 0) {
|
|
198
|
-
throw VideomailError.create("Height must be divisible by two.", options);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/*
|
|
203
|
-
* this will just set the width but not the height because
|
|
204
|
-
* it can be a form with more inputs elements
|
|
205
|
-
*/
|
|
206
|
-
function correctDimensions() {
|
|
207
|
-
if (options.video.stretch) {
|
|
208
|
-
removeDimensions();
|
|
209
|
-
} else {
|
|
210
|
-
const width = visuals.getRecorderWidth(true);
|
|
211
|
-
|
|
212
|
-
if (width < 1) {
|
|
213
|
-
throw VideomailError.create("Recorder width cannot be less than 1!", options);
|
|
214
|
-
} else {
|
|
215
|
-
containerElement.style.width = `${width}px`;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
function removeDimensions() {
|
|
221
|
-
containerElement.style.width = "auto";
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
function unloadChildren(e) {
|
|
225
|
-
visuals.unload(e);
|
|
226
|
-
buttons.unload();
|
|
227
|
-
self.endWaiting();
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
function hideMySelf() {
|
|
231
|
-
hidden(containerElement, true);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
function submitVideomail(formData, method, cb) {
|
|
235
|
-
const videomailFormData = form.transformFormData(formData);
|
|
236
|
-
|
|
237
|
-
// when method is undefined, treat it as a post
|
|
238
|
-
if (isPost(method) || !method) {
|
|
239
|
-
videomailFormData.recordingStats = visuals.getRecordingStats();
|
|
240
|
-
videomailFormData.width = visuals.getRecorderWidth(true);
|
|
241
|
-
videomailFormData.height = visuals.getRecorderHeight(true);
|
|
242
|
-
|
|
243
|
-
if (navigator.connection) {
|
|
244
|
-
videomailFormData.connection = {
|
|
245
|
-
downlink: `${navigator.connection.downlink} Mbit/s`,
|
|
246
|
-
effectiveType: navigator.connection.effectiveType,
|
|
247
|
-
rtt: navigator.connection.rtt,
|
|
248
|
-
type: navigator.connection.type,
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
resource.post(videomailFormData, cb);
|
|
253
|
-
} else if (isPut(method)) {
|
|
254
|
-
resource.put(videomailFormData, cb);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
function submitForm(formData, videomailResponse, url, cb) {
|
|
259
|
-
/*
|
|
260
|
-
* for now, accept POSTs only which have an URL unlike null and
|
|
261
|
-
* treat all other submissions as direct submissions
|
|
262
|
-
*/
|
|
263
|
-
|
|
264
|
-
if (!url || url === "") {
|
|
265
|
-
// figure out URL automatically then
|
|
266
|
-
url = document.baseURI;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
// can be missing when no videomail was recorded and is not required
|
|
270
|
-
if (videomailResponse) {
|
|
271
|
-
formData[options.selectors.aliasInputName] = videomailResponse.videomail.alias;
|
|
272
|
-
|
|
273
|
-
/*
|
|
274
|
-
* this in case if user wants all videomail metadata to be posted
|
|
275
|
-
* altogether with the remaining form
|
|
276
|
-
*/
|
|
277
|
-
if (options.submitWithVideomail) {
|
|
278
|
-
formData.videomail = videomailResponse.videomail;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
resource.form(formData, url, cb);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
function finalizeSubmissions(err, method, videomail, response, formResponse) {
|
|
286
|
-
self.endWaiting();
|
|
287
|
-
|
|
288
|
-
if (err) {
|
|
289
|
-
self.emit(Events.ERROR, err);
|
|
290
|
-
} else {
|
|
291
|
-
submitted = true;
|
|
292
|
-
|
|
293
|
-
// merge two json response bodies to fake as if it were only one request
|
|
294
|
-
if (response && formResponse && formResponse.body) {
|
|
295
|
-
Object.keys(formResponse.body).forEach(function (key) {
|
|
296
|
-
response[key] = formResponse.body[key];
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
self.emit(Events.SUBMITTED, videomail, response || formResponse);
|
|
301
|
-
|
|
302
|
-
if (formResponse && formResponse.type === "text/html" && formResponse.text) {
|
|
303
|
-
// server replied with HTML contents - display these
|
|
304
|
-
document.body.innerHTML = formResponse.text;
|
|
305
|
-
|
|
306
|
-
/*
|
|
307
|
-
* todo: figure out how to fire dom's onload event again
|
|
308
|
-
* todo: or how to run all the scripts over again
|
|
309
|
-
*/
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
this.addPlayerDimensions = function (videomail, element) {
|
|
315
|
-
try {
|
|
316
|
-
videomail.playerHeight = this.calculateHeight(
|
|
317
|
-
{
|
|
318
|
-
responsive: true,
|
|
319
|
-
videoWidth: videomail.width,
|
|
320
|
-
ratio: videomail.height / videomail.width,
|
|
321
|
-
},
|
|
322
|
-
element,
|
|
323
|
-
);
|
|
324
|
-
|
|
325
|
-
videomail.playerWidth = this.calculateWidth({
|
|
326
|
-
responsive: true,
|
|
327
|
-
videoHeight: videomail.playerHeight,
|
|
328
|
-
ratio: videomail.height / videomail.width,
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
return videomail;
|
|
332
|
-
} catch (exc) {
|
|
333
|
-
self.emit(Events.ERROR, exc);
|
|
334
|
-
}
|
|
335
|
-
};
|
|
336
|
-
|
|
337
|
-
this.limitWidth = function (width) {
|
|
338
|
-
return Dimension.limitWidth(containerElement, width, options);
|
|
339
|
-
};
|
|
340
|
-
|
|
341
|
-
this.limitHeight = function (height) {
|
|
342
|
-
return Dimension.limitHeight(height, options);
|
|
343
|
-
};
|
|
344
|
-
|
|
345
|
-
this.calculateWidth = function (fnOptions) {
|
|
346
|
-
return Dimension.calculateWidth(OptionsWrapper.merge(options, fnOptions, true));
|
|
347
|
-
};
|
|
348
|
-
|
|
349
|
-
this.calculateHeight = function (fnOptions, element) {
|
|
350
|
-
if (!element) {
|
|
351
|
-
if (containerElement) {
|
|
352
|
-
element = containerElement;
|
|
353
|
-
} else {
|
|
354
|
-
// better than nothing
|
|
355
|
-
element = document.body;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
return Dimension.calculateHeight(
|
|
360
|
-
element,
|
|
361
|
-
OptionsWrapper.merge(options, fnOptions, true),
|
|
362
|
-
);
|
|
363
|
-
};
|
|
364
|
-
|
|
365
|
-
this.areVisualsHidden = function () {
|
|
366
|
-
return visuals.isHidden();
|
|
367
|
-
};
|
|
368
|
-
|
|
369
|
-
this.hasElement = function () {
|
|
370
|
-
return Boolean(containerElement);
|
|
371
|
-
};
|
|
372
|
-
|
|
373
|
-
this.build = function () {
|
|
374
|
-
try {
|
|
375
|
-
containerElement = document.getElementById(options.selectors.containerId);
|
|
376
|
-
|
|
377
|
-
/*
|
|
378
|
-
* only build when a container element hast been found, otherwise
|
|
379
|
-
* be silent and do nothing
|
|
380
|
-
*/
|
|
381
|
-
if (containerElement) {
|
|
382
|
-
options.insertCss && prependDefaultCss();
|
|
383
|
-
|
|
384
|
-
!built && initEvents();
|
|
385
|
-
validateOptions();
|
|
386
|
-
correctDimensions();
|
|
387
|
-
|
|
388
|
-
if (!options.playerOnly) {
|
|
389
|
-
buildForm();
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
buildChildren();
|
|
393
|
-
|
|
394
|
-
if (!hasError) {
|
|
395
|
-
debug("Container: built.");
|
|
396
|
-
built = true;
|
|
397
|
-
self.emit(Events.BUILT);
|
|
398
|
-
} else {
|
|
399
|
-
debug("Container: building failed due to an error.");
|
|
400
|
-
}
|
|
401
|
-
} else {
|
|
402
|
-
/*
|
|
403
|
-
* commented out since it does too much noise on videomail's view page which is fine
|
|
404
|
-
* debug('Container: no container element with ID ' + options.selectors.containerId + ' found. Do nothing.')
|
|
405
|
-
*/
|
|
406
|
-
}
|
|
407
|
-
} catch (exc) {
|
|
408
|
-
if (visuals.isNotifierBuilt()) {
|
|
409
|
-
self.emit(Events.ERROR, exc);
|
|
410
|
-
} else {
|
|
411
|
-
throw exc;
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
};
|
|
415
|
-
|
|
416
|
-
this.getSubmitButton = function () {
|
|
417
|
-
return buttons.getSubmitButton();
|
|
418
|
-
};
|
|
419
|
-
|
|
420
|
-
this.querySelector = function (selector) {
|
|
421
|
-
return containerElement.querySelector(selector);
|
|
422
|
-
};
|
|
423
|
-
|
|
424
|
-
this.beginWaiting = function () {
|
|
425
|
-
htmlElement.classList && htmlElement.classList.add("wait");
|
|
426
|
-
};
|
|
427
|
-
|
|
428
|
-
this.endWaiting = function () {
|
|
429
|
-
htmlElement.classList && htmlElement.classList.remove("wait");
|
|
430
|
-
};
|
|
431
|
-
|
|
432
|
-
this.appendChild = function (child) {
|
|
433
|
-
containerElement.appendChild(child);
|
|
434
|
-
};
|
|
435
|
-
|
|
436
|
-
this.insertBefore = function (child, reference) {
|
|
437
|
-
containerElement.insertBefore(child, reference);
|
|
438
|
-
};
|
|
439
|
-
|
|
440
|
-
this.unload = function (e) {
|
|
441
|
-
debug("Container: unload()", e);
|
|
442
|
-
|
|
443
|
-
try {
|
|
444
|
-
unloadChildren(e);
|
|
445
|
-
this.removeAllListeners();
|
|
446
|
-
|
|
447
|
-
built = submitted = false;
|
|
448
|
-
} catch (exc) {
|
|
449
|
-
self.emit(Events.ERROR, exc);
|
|
450
|
-
}
|
|
451
|
-
};
|
|
452
|
-
|
|
453
|
-
this.show = function () {
|
|
454
|
-
if (containerElement) {
|
|
455
|
-
hidden(containerElement, false);
|
|
456
|
-
|
|
457
|
-
visuals.show();
|
|
458
|
-
|
|
459
|
-
if (!hasError) {
|
|
460
|
-
const paused = self.isPaused();
|
|
461
|
-
|
|
462
|
-
if (paused) {
|
|
463
|
-
buttons.adjustButtonsForPause();
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
/*
|
|
467
|
-
* since https://github.com/binarykitchen/videomail-client/issues/60
|
|
468
|
-
* we hide areas to make it easier for the user
|
|
469
|
-
*/
|
|
470
|
-
buttons.show();
|
|
471
|
-
|
|
472
|
-
if (self.isReplayShown()) {
|
|
473
|
-
self.emit(Events.PREVIEW);
|
|
474
|
-
} else {
|
|
475
|
-
self.emit(Events.FORM_READY, "paused", paused);
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
};
|
|
480
|
-
|
|
481
|
-
this.hide = function () {
|
|
482
|
-
debug("Container: hide()");
|
|
483
|
-
|
|
484
|
-
hasError = false;
|
|
485
|
-
|
|
486
|
-
this.isRecording() && this.pause();
|
|
487
|
-
|
|
488
|
-
visuals.hide();
|
|
489
|
-
|
|
490
|
-
if (submitted) {
|
|
491
|
-
buttons.hide();
|
|
492
|
-
hideMySelf();
|
|
493
|
-
}
|
|
494
|
-
};
|
|
495
|
-
|
|
496
|
-
this.startOver = function (params) {
|
|
497
|
-
try {
|
|
498
|
-
self.emit(Events.STARTING_OVER);
|
|
499
|
-
|
|
500
|
-
submitted = false;
|
|
501
|
-
form.show();
|
|
502
|
-
visuals.back(params, function () {
|
|
503
|
-
if (params && params.keepHidden) {
|
|
504
|
-
/*
|
|
505
|
-
* just enable form, do nothing else.
|
|
506
|
-
* see example contact_form.html when you submit without videomail
|
|
507
|
-
* and go back
|
|
508
|
-
*/
|
|
509
|
-
self.enableForm();
|
|
510
|
-
} else {
|
|
511
|
-
self.show(params);
|
|
512
|
-
}
|
|
513
|
-
});
|
|
514
|
-
} catch (exc) {
|
|
515
|
-
self.emit(Events.ERROR, exc);
|
|
516
|
-
}
|
|
517
|
-
};
|
|
518
|
-
|
|
519
|
-
this.showReplayOnly = function () {
|
|
520
|
-
hasError = false;
|
|
521
|
-
|
|
522
|
-
this.isRecording() && this.pause();
|
|
523
|
-
|
|
524
|
-
visuals.showReplayOnly();
|
|
525
|
-
|
|
526
|
-
submitted && buttons.hide();
|
|
527
|
-
};
|
|
528
|
-
|
|
529
|
-
this.isNotifying = function () {
|
|
530
|
-
return visuals.isNotifying();
|
|
531
|
-
};
|
|
532
|
-
|
|
533
|
-
this.isPaused = function () {
|
|
534
|
-
return visuals.isPaused();
|
|
535
|
-
};
|
|
536
|
-
|
|
537
|
-
this.pause = function (params) {
|
|
538
|
-
visuals.pause(params);
|
|
539
|
-
};
|
|
540
|
-
|
|
541
|
-
// this code needs a good rewrite :(
|
|
542
|
-
this.validate = function (force) {
|
|
543
|
-
let runValidation = true;
|
|
544
|
-
let valid;
|
|
545
|
-
|
|
546
|
-
if (!options.enableAutoValidation) {
|
|
547
|
-
runValidation = false;
|
|
548
|
-
lastValidation = true; // needed so that it can be submitted anyway, see submit()
|
|
549
|
-
} else if (force) {
|
|
550
|
-
runValidation = force;
|
|
551
|
-
} else if (self.isNotifying()) {
|
|
552
|
-
runValidation = false;
|
|
553
|
-
} else if (visuals.isConnected()) {
|
|
554
|
-
runValidation = visuals.isUserMediaLoaded() || visuals.isReplayShown();
|
|
555
|
-
} else if (visuals.isConnecting()) {
|
|
556
|
-
runValidation = false;
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
if (runValidation) {
|
|
560
|
-
this.emit(Events.VALIDATING);
|
|
561
|
-
|
|
562
|
-
const visualsValid = visuals.validate() && buttons.isRecordAgainButtonEnabled();
|
|
563
|
-
let whyInvalid;
|
|
564
|
-
|
|
565
|
-
if (form) {
|
|
566
|
-
valid = form.validate();
|
|
567
|
-
|
|
568
|
-
if (valid) {
|
|
569
|
-
if (!this.areVisualsHidden() && !visualsValid) {
|
|
570
|
-
if (
|
|
571
|
-
submitted ||
|
|
572
|
-
this.isReady() ||
|
|
573
|
-
this.isRecording() ||
|
|
574
|
-
this.isPaused() ||
|
|
575
|
-
this.isCountingDown()
|
|
576
|
-
) {
|
|
577
|
-
valid = false;
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
if (!valid) {
|
|
581
|
-
whyInvalid = "Video is not recorded";
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
} else {
|
|
585
|
-
const invalidInput = form.getInvalidElement();
|
|
586
|
-
|
|
587
|
-
if (invalidInput) {
|
|
588
|
-
whyInvalid = `Form input named ${
|
|
589
|
-
invalidInput.name
|
|
590
|
-
} is invalid. It has the value: "${invalidInput.value}"`;
|
|
591
|
-
} else {
|
|
592
|
-
whyInvalid = "Form input(s) are invalid";
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
if (valid) {
|
|
597
|
-
/*
|
|
598
|
-
* If CC and/or BCC exist, validate one more time to ensure at least
|
|
599
|
-
* one recipient is given
|
|
600
|
-
*/
|
|
601
|
-
const recipients = form.getRecipients();
|
|
602
|
-
|
|
603
|
-
const toIsConfigured = "to" in recipients;
|
|
604
|
-
const ccIsConfigured = "cc" in recipients;
|
|
605
|
-
const bccIsConfigured = "bcc" in recipients;
|
|
606
|
-
|
|
607
|
-
const hasTo = recipients.to?.length > 0;
|
|
608
|
-
const hasCc = recipients.cc?.length > 0;
|
|
609
|
-
const hasBcc = recipients.bcc?.length > 0;
|
|
610
|
-
|
|
611
|
-
if (toIsConfigured) {
|
|
612
|
-
if (!hasTo) {
|
|
613
|
-
if (ccIsConfigured && bccIsConfigured) {
|
|
614
|
-
if (!hasCc && !hasBcc) {
|
|
615
|
-
valid = false;
|
|
616
|
-
}
|
|
617
|
-
} else if (ccIsConfigured) {
|
|
618
|
-
if (!hasCc) {
|
|
619
|
-
valid = false;
|
|
620
|
-
}
|
|
621
|
-
} else if (bccIsConfigured) {
|
|
622
|
-
if (!hasBcc) {
|
|
623
|
-
valid = false;
|
|
624
|
-
}
|
|
625
|
-
} else {
|
|
626
|
-
whyInvalid = "Please configure the form to have at least one recipient.";
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
} else if (ccIsConfigured) {
|
|
630
|
-
if (!hasCc) {
|
|
631
|
-
if (bccIsConfigured) {
|
|
632
|
-
if (!hasBcc) {
|
|
633
|
-
valid = false;
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
if (!valid) {
|
|
640
|
-
whyInvalid = "Please enter at least one recipient.";
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
} else {
|
|
644
|
-
valid = visualsValid;
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
if (valid) {
|
|
648
|
-
this.emit(Events.VALID);
|
|
649
|
-
} else {
|
|
650
|
-
this.emit(Events.INVALID, whyInvalid);
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
lastValidation = valid;
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
return valid;
|
|
657
|
-
};
|
|
658
|
-
|
|
659
|
-
this.disableForm = function (buttonsToo) {
|
|
660
|
-
form && form.disable(buttonsToo);
|
|
661
|
-
};
|
|
662
|
-
|
|
663
|
-
this.enableForm = function (buttonsToo) {
|
|
664
|
-
form && form.enable(buttonsToo);
|
|
665
|
-
};
|
|
666
|
-
|
|
667
|
-
this.hasForm = function () {
|
|
668
|
-
return Boolean(form);
|
|
669
|
-
};
|
|
670
|
-
|
|
671
|
-
this.isReady = function () {
|
|
672
|
-
return buttons.isRecordButtonEnabled();
|
|
673
|
-
};
|
|
674
|
-
|
|
675
|
-
function isPost(method) {
|
|
676
|
-
return method && method.toUpperCase() === "POST";
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
function isPut(method) {
|
|
680
|
-
return method && method.toUpperCase() === "PUT";
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
this.submitAll = function (formData, method, url) {
|
|
684
|
-
const post = isPost(method);
|
|
685
|
-
const hasVideomailKey = Boolean(formData[options.selectors.keyInputName]);
|
|
686
|
-
|
|
687
|
-
function startSubmission() {
|
|
688
|
-
self.beginWaiting();
|
|
689
|
-
self.disableForm(true);
|
|
690
|
-
self.emit(Events.SUBMITTING);
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
// a closure so that we can access method
|
|
694
|
-
const submitVideomailCallback = function (err1, videomail, videomailResponse) {
|
|
695
|
-
if (err1) {
|
|
696
|
-
finalizeSubmissions(err1, method, videomail, videomailResponse);
|
|
697
|
-
} else if (post) {
|
|
698
|
-
submitForm(formData, videomailResponse, url, function (err2, formResponse) {
|
|
699
|
-
finalizeSubmissions(err2, method, videomail, videomailResponse, formResponse);
|
|
700
|
-
});
|
|
701
|
-
} else {
|
|
702
|
-
// it's a direct submission
|
|
703
|
-
finalizeSubmissions(null, method, videomail, videomailResponse);
|
|
704
|
-
}
|
|
705
|
-
};
|
|
706
|
-
|
|
707
|
-
/*
|
|
708
|
-
* !hasVideomailKey makes it possible to submit form when videomail itself
|
|
709
|
-
* is not optional.
|
|
710
|
-
*/
|
|
711
|
-
if (!hasVideomailKey) {
|
|
712
|
-
if (options.enableAutoSubmission) {
|
|
713
|
-
startSubmission();
|
|
714
|
-
submitForm(formData, null, url, function (err2, formResponse) {
|
|
715
|
-
finalizeSubmissions(err2, method, null, null, formResponse);
|
|
716
|
-
});
|
|
717
|
-
}
|
|
718
|
-
/*
|
|
719
|
-
* ... and when the enableAutoSubmission option is false,
|
|
720
|
-
* then that can mean, leave it to the framework to process with the form
|
|
721
|
-
* validation/handling/submission itself. for example the ninja form
|
|
722
|
-
* will want to highlight which one input are wrong.
|
|
723
|
-
*/
|
|
724
|
-
} else {
|
|
725
|
-
startSubmission();
|
|
726
|
-
submitVideomail(formData, method, submitVideomailCallback);
|
|
727
|
-
}
|
|
728
|
-
};
|
|
729
|
-
|
|
730
|
-
this.isBuilt = function () {
|
|
731
|
-
return built;
|
|
732
|
-
};
|
|
733
|
-
|
|
734
|
-
this.isReplayShown = function () {
|
|
735
|
-
return visuals.isReplayShown();
|
|
736
|
-
};
|
|
737
|
-
|
|
738
|
-
this.isDirty = function () {
|
|
739
|
-
let isDirty = false;
|
|
740
|
-
|
|
741
|
-
if (form) {
|
|
742
|
-
if (visuals.isRecorderUnloaded()) {
|
|
743
|
-
isDirty = false;
|
|
744
|
-
} else if (this.isReplayShown() || this.isPaused()) {
|
|
745
|
-
isDirty = true;
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
return isDirty;
|
|
750
|
-
};
|
|
751
|
-
|
|
752
|
-
this.getReplay = function () {
|
|
753
|
-
return visuals.getReplay();
|
|
754
|
-
};
|
|
755
|
-
|
|
756
|
-
this.isOutsideElementOf = function (element) {
|
|
757
|
-
return element.parentNode !== containerElement && element !== containerElement;
|
|
758
|
-
};
|
|
759
|
-
|
|
760
|
-
this.hideForm = function (params) {
|
|
761
|
-
// form check needed, see https://github.com/binarykitchen/videomail-client/issues/127
|
|
762
|
-
form && form.hide();
|
|
763
|
-
buttons && buttons.hide(params);
|
|
764
|
-
};
|
|
765
|
-
|
|
766
|
-
this.loadForm = function (videomail) {
|
|
767
|
-
if (form) {
|
|
768
|
-
form.loadVideomail(videomail);
|
|
769
|
-
this.validate();
|
|
770
|
-
}
|
|
771
|
-
};
|
|
772
|
-
|
|
773
|
-
this.enableAudio = function () {
|
|
774
|
-
options.setAudioEnabled(true);
|
|
775
|
-
this.emit(Events.ENABLING_AUDIO);
|
|
776
|
-
};
|
|
777
|
-
|
|
778
|
-
this.disableAudio = function () {
|
|
779
|
-
options.setAudioEnabled(false);
|
|
780
|
-
this.emit(Events.DISABLING_AUDIO);
|
|
781
|
-
};
|
|
782
|
-
|
|
783
|
-
this.submit = function () {
|
|
784
|
-
lastValidation && form && form.doTheSubmit();
|
|
785
|
-
};
|
|
786
|
-
|
|
787
|
-
this.isCountingDown = visuals.isCountingDown.bind(visuals);
|
|
788
|
-
this.isRecording = visuals.isRecording.bind(visuals);
|
|
789
|
-
this.record = visuals.record.bind(visuals);
|
|
790
|
-
this.resume = visuals.resume.bind(visuals);
|
|
791
|
-
this.stop = visuals.stop.bind(visuals);
|
|
792
|
-
this.recordAgain = visuals.recordAgain.bind(visuals);
|
|
793
|
-
};
|
|
794
|
-
|
|
795
|
-
inherits(Container, EventEmitter);
|
|
796
|
-
|
|
797
|
-
export default Container;
|