@bigbinary/neeto-media-recorder 2.4.2 → 2.5.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.
package/index.js CHANGED
@@ -2,7 +2,7 @@ import { shallow } from 'zustand/shallow';
2
2
  import { useState, useEffect, forwardRef, useImperativeHandle, useRef } from 'react';
3
3
  import classNames from 'classnames';
4
4
  import { isNotEmpty, noop } from '@bigbinary/neeto-cist';
5
- import { SCREEN_RECORDER_STATUS, UPLOAD_STATUS, MIME_TYPE as MIME_TYPE$1, ONE_MINUTE_IN_MILLISECONDS as ONE_MINUTE_IN_MILLISECONDS$1, ONE_SECOND_IN_MILLISECONDS as ONE_SECOND_IN_MILLISECONDS$1, IS_EXTENSION as IS_EXTENSION$1, SCREEN_RECORDER_ERROR, IS_SAFARI_EXTENSION, SCREEN_RECORDER_EVENT, UPLOAD_EVENT } from '@bigbinary/neeto-media-recorder/constants';
5
+ import { SCREEN_RECORDER_STATUS, UPLOAD_STATUS as UPLOAD_STATUS$1, MIME_TYPE as MIME_TYPE$1, ONE_MINUTE_IN_MILLISECONDS as ONE_MINUTE_IN_MILLISECONDS$1, ONE_SECOND_IN_MILLISECONDS as ONE_SECOND_IN_MILLISECONDS$1, IS_EXTENSION as IS_EXTENSION$1, SCREEN_RECORDER_ERROR, IS_SAFARI_EXTENSION, SCREEN_RECORDER_EVENT, UPLOAD_EVENT } from '@bigbinary/neeto-media-recorder/constants';
6
6
  import { screenRecorder, multipartS3Uploader } from '@bigbinary/neeto-media-recorder/core';
7
7
  import PageLoader from '@bigbinary/neeto-molecules/PageLoader';
8
8
  import Alert from '@bigbinary/neetoui/Alert';
@@ -25,13 +25,56 @@ import { copyToClipboard } from '@bigbinary/neeto-commons-frontend/utils/general
25
25
  import Close from '@bigbinary/neeto-icons/Close';
26
26
  import Download from '@bigbinary/neeto-icons/Download';
27
27
  import Copy from '@bigbinary/neeto-icons/Copy';
28
+ import Refresh from '@bigbinary/neeto-icons/Refresh';
28
29
  import CopyToClipboardButton from '@bigbinary/neeto-molecules/CopyToClipboardButton';
30
+ import ProgressBar from '@bigbinary/neetoui/ProgressBar';
29
31
 
30
32
  var e=[],t=[];function n(n,r){if(n&&"undefined"!=typeof document){var a,s=!0===r.prepend?"prepend":"append",d=!0===r.singleTag,i="string"==typeof r.container?document.querySelector(r.container):document.getElementsByTagName("head")[0];if(d){var u=e.indexOf(i);-1===u&&(u=e.push(i)-1,t[u]={}),a=t[u]&&t[u][s]?t[u][s]:t[u][s]=c();}else a=c();65279===n.charCodeAt(0)&&(n=n.substring(1)),a.styleSheet?a.styleSheet.cssText+=n:a.appendChild(document.createTextNode(n));}function c(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),r.attributes)for(var t=Object.keys(r.attributes),n=0;n<t.length;n++)e.setAttribute(t[n],r.attributes[t[n]]);var a="prepend"===s?"afterbegin":"beforeend";return i.insertAdjacentElement(a,e),e}}
31
33
 
32
- var css = ".nrec-done-button{background-color:rgb(var(--neeto-ui-error-100));padding:8px 12px}.nrec-done-button:hover{box-shadow:0 0 0 3px rgba(var(--neeto-ui-error-500),15%)}body .neeto-ui-modal__wrapper .neeto-ui-btn--style-danger{background:rgb(var(--neeto-ui-error-500))}.nrec-media-upload-loader{background:#d9d9d9;border-radius:14px;display:inline-block;height:10px;margin:0 auto;max-width:480px;overflow:hidden;position:relative;width:100%}.nrec-media-upload-loader:after{animation:movementLoader 3s linear infinite,barAnimation 1.5s linear infinite;background-color:#fff;background-image:linear-gradient(45deg,#268e6c 25%,#12805c 0,#12805c 50%,#268e6c 0,#268e6c 75%,#12805c 0,#12805c);background-size:1em 1em;border-radius:14px;box-sizing:border-box;content:\"\";height:10px;left:0;position:absolute;top:0;width:230px}@media only screen and (max-width:767px){.nrec-media-upload-loader:after{width:130px}}@keyframes barAnimation{0%{background-position:1em 0}to{background-position:0 0}}@keyframes movementLoader{0%{left:0;transform:translateX(-100%)}to{left:100%;transform:translateX(0)}}";
34
+ var css = ".nrec-done-button{background-color:rgb(var(--neeto-ui-error-100));padding:8px 12px}.nrec-done-button:hover{box-shadow:0 0 0 3px rgba(var(--neeto-ui-error-500),15%)}body .neeto-ui-modal__wrapper .neeto-ui-btn--style-danger{background:rgb(var(--neeto-ui-error-500))}.nrec-media-upload-progress{margin:0 auto;max-width:480px}.nrec-media-upload-error{color:rgb(var(--neeto-ui-error-500))}.nrec-media-upload-loader{background:#d9d9d9;border-radius:14px;display:inline-block;height:10px;margin:0 auto;max-width:480px;overflow:hidden;position:relative;width:100%}.nrec-media-upload-loader:after{animation:movementLoader 3s linear infinite,barAnimation 1.5s linear infinite;background-color:#fff;background-image:linear-gradient(45deg,#268e6c 25%,#12805c 0,#12805c 50%,#268e6c 0,#268e6c 75%,#12805c 0,#12805c);background-size:1em 1em;border-radius:14px;box-sizing:border-box;content:\"\";height:10px;left:0;position:absolute;top:0;width:230px}@media only screen and (max-width:767px){.nrec-media-upload-loader:after{width:130px}}@keyframes barAnimation{0%{background-position:1em 0}to{background-position:0 0}}@keyframes movementLoader{0%{left:0;transform:translateX(-100%)}to{left:100%;transform:translateX(0)}}";
33
35
  n(css,{});
34
36
 
37
+ function _typeof$1(obj) {
38
+ "@babel/helpers - typeof";
39
+
40
+ return _typeof$1 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
41
+ return typeof obj;
42
+ } : function (obj) {
43
+ return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
44
+ }, _typeof$1(obj);
45
+ }
46
+
47
+ function _toPrimitive(input, hint) {
48
+ if (_typeof$1(input) !== "object" || input === null) return input;
49
+ var prim = input[Symbol.toPrimitive];
50
+ if (prim !== undefined) {
51
+ var res = prim.call(input, hint || "default");
52
+ if (_typeof$1(res) !== "object") return res;
53
+ throw new TypeError("@@toPrimitive must return a primitive value.");
54
+ }
55
+ return (hint === "string" ? String : Number)(input);
56
+ }
57
+
58
+ function _toPropertyKey(arg) {
59
+ var key = _toPrimitive(arg, "string");
60
+ return _typeof$1(key) === "symbol" ? key : String(key);
61
+ }
62
+
63
+ function _defineProperty(obj, key, value) {
64
+ key = _toPropertyKey(key);
65
+ if (key in obj) {
66
+ Object.defineProperty(obj, key, {
67
+ value: value,
68
+ enumerable: true,
69
+ configurable: true,
70
+ writable: true
71
+ });
72
+ } else {
73
+ obj[key] = value;
74
+ }
75
+ return obj;
76
+ }
77
+
35
78
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
36
79
  try {
37
80
  var info = gen[key](arg);
@@ -124,9 +167,9 @@ function getDefaultExportFromCjs (x) {
124
167
 
125
168
  var regeneratorRuntime$1 = {exports: {}};
126
169
 
127
- var _typeof$1 = {exports: {}};
170
+ var _typeof = {exports: {}};
128
171
 
129
- _typeof$1.exports;
172
+ _typeof.exports;
130
173
 
131
174
  (function (module) {
132
175
  function _typeof(obj) {
@@ -139,9 +182,9 @@ _typeof$1.exports;
139
182
  }, module.exports.__esModule = true, module.exports["default"] = module.exports), _typeof(obj);
140
183
  }
141
184
  module.exports = _typeof, module.exports.__esModule = true, module.exports["default"] = module.exports;
142
- } (_typeof$1));
185
+ } (_typeof));
143
186
 
144
- var _typeofExports = _typeof$1.exports;
187
+ var _typeofExports = _typeof.exports;
145
188
 
146
189
  regeneratorRuntime$1.exports;
147
190
 
@@ -471,51 +514,17 @@ try {
471
514
 
472
515
  var _regeneratorRuntime = /*@__PURE__*/getDefaultExportFromCjs(regenerator);
473
516
 
474
- function _typeof(obj) {
475
- "@babel/helpers - typeof";
476
-
477
- return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
478
- return typeof obj;
479
- } : function (obj) {
480
- return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
481
- }, _typeof(obj);
482
- }
483
-
484
- function _toPrimitive(input, hint) {
485
- if (_typeof(input) !== "object" || input === null) return input;
486
- var prim = input[Symbol.toPrimitive];
487
- if (prim !== undefined) {
488
- var res = prim.call(input, hint || "default");
489
- if (_typeof(res) !== "object") return res;
490
- throw new TypeError("@@toPrimitive must return a primitive value.");
491
- }
492
- return (hint === "string" ? String : Number)(input);
493
- }
494
-
495
- function _toPropertyKey(arg) {
496
- var key = _toPrimitive(arg, "string");
497
- return _typeof(key) === "symbol" ? key : String(key);
498
- }
499
-
500
- function _defineProperty(obj, key, value) {
501
- key = _toPropertyKey(key);
502
- if (key in obj) {
503
- Object.defineProperty(obj, key, {
504
- value: value,
505
- enumerable: true,
506
- configurable: true,
507
- writable: true
508
- });
509
- } else {
510
- obj[key] = value;
511
- }
512
- return obj;
513
- }
514
-
515
517
  var ONE_SECOND_IN_MILLISECONDS = 1000;
516
518
  var ONE_MINUTE_IN_MILLISECONDS = 60 * ONE_SECOND_IN_MILLISECONDS;
517
519
  var ONE_HOUR_IN_MILLISECONDS = 60 * ONE_MINUTE_IN_MILLISECONDS;
518
- var HAS_CHROME_NAMESPACE = (typeof chrome === "undefined" ? "undefined" : _typeof(chrome)) === "object";
520
+ var UPLOAD_STATUS = {
521
+ uploading: "uploading",
522
+ completed: "completed",
523
+ aborting: "aborting",
524
+ insufficient_data: "insufficient_data",
525
+ error: "error"
526
+ };
527
+ var HAS_CHROME_NAMESPACE = (typeof chrome === "undefined" ? "undefined" : _typeof$1(chrome)) === "object";
519
528
  var IS_EXTENSION = HAS_CHROME_NAMESPACE && isNotNil(chrome.extension);
520
529
  platform.name === "Safari";
521
530
  var MIME_TYPE = {
@@ -590,7 +599,7 @@ var downloadRecordingBlob = function downloadRecordingBlob(blob, name) {
590
599
  var hasRecordingDiscarded = function hasRecordingDiscarded(_ref) {
591
600
  var recorderStatus = _ref.recorderStatus,
592
601
  uploadStatus = _ref.uploadStatus;
593
- return recorderStatus === SCREEN_RECORDER_STATUS.stopped && uploadStatus === UPLOAD_STATUS.aborting;
602
+ return recorderStatus === SCREEN_RECORDER_STATUS.stopped && uploadStatus === UPLOAD_STATUS$1.aborting;
594
603
  };
595
604
  var getRecorderTimeLimitInHumanFormat = function getRecorderTimeLimitInHumanFormat(timeInMs) {
596
605
  var minutes = Math.floor(timeInMs / (1000 * 60));
@@ -1040,7 +1049,10 @@ var generatePublicUrl = function generatePublicUrl(recordingId) {
1040
1049
 
1041
1050
  var UploadingInProgress = function UploadingInProgress(_ref) {
1042
1051
  var recording = _ref.recording,
1043
- onDiscard = _ref.onDiscard;
1052
+ uploadProgress = _ref.uploadProgress,
1053
+ uploadStatus = _ref.uploadStatus,
1054
+ onDiscard = _ref.onDiscard,
1055
+ onRetryUpload = _ref.onRetryUpload;
1044
1056
  var _useState = useState(""),
1045
1057
  _useState2 = _slicedToArray(_useState, 2),
1046
1058
  baseURL = _useState2[0],
@@ -1090,9 +1102,12 @@ var UploadingInProgress = function UploadingInProgress(_ref) {
1090
1102
  weight: "normal",
1091
1103
  children: t("neetoMediaRecorder.record.uploadingRecording")
1092
1104
  }), /*#__PURE__*/jsx("div", {
1093
- className: "pb-3",
1094
- children: /*#__PURE__*/jsx("span", {
1095
- className: "nrec-media-upload-loader"
1105
+ className: "nrec-media-upload-progress pb-3",
1106
+ children: uploadStatus === UPLOAD_STATUS.error ? /*#__PURE__*/jsx("div", {
1107
+ className: "nrec-media-upload-error",
1108
+ children: t("neetoMediaRecorder.common.uploadError")
1109
+ }) : /*#__PURE__*/jsx(ProgressBar, {
1110
+ progressPercentage: uploadProgress
1096
1111
  })
1097
1112
  }), /*#__PURE__*/jsx(Typography, {
1098
1113
  className: "select-none",
@@ -1114,6 +1129,12 @@ var UploadingInProgress = function UploadingInProgress(_ref) {
1114
1129
  style: "tertiary",
1115
1130
  label: isMp4Supported() ? t("neetoMediaRecorder.record.downloadMp4") : t("neetoMediaRecorder.record.downloadWebm"),
1116
1131
  onClick: handleRecordingBlobDownload
1132
+ }), /*#__PURE__*/jsx(Button, {
1133
+ "data-cy": "recorder-retry-upload-button",
1134
+ icon: Refresh,
1135
+ label: "Retry",
1136
+ style: "tertiary",
1137
+ onClick: onRetryUpload
1117
1138
  }), /*#__PURE__*/jsx(Button, {
1118
1139
  "data-cy": "recorder-discard-recording-button",
1119
1140
  icon: Close,
@@ -1267,6 +1288,14 @@ var MediaRecorder$1 = function MediaRecorder(_ref, ref) {
1267
1288
  _useState4 = _slicedToArray(_useState3, 2),
1268
1289
  isRestartAlertOpen = _useState4[0],
1269
1290
  setIsRestartAlertOpen = _useState4[1];
1291
+ var _useState5 = useState(0),
1292
+ _useState6 = _slicedToArray(_useState5, 2),
1293
+ uploadProgress = _useState6[0],
1294
+ setUploadProgress = _useState6[1];
1295
+ var _useState7 = useState(false),
1296
+ _useState8 = _slicedToArray(_useState7, 2),
1297
+ isRetryUpload = _useState8[0],
1298
+ setIsRetryUpload = _useState8[1];
1270
1299
  var _useRecorderStore = useRecorderStore(function (store) {
1271
1300
  return {
1272
1301
  status: store["status"],
@@ -1297,10 +1326,10 @@ var MediaRecorder$1 = function MediaRecorder(_ref, ref) {
1297
1326
  multipartS3Uploader.initialize(recording.id, uploadId);
1298
1327
  var uploadStatus = useMultipartS3UploadStore.getState().status;
1299
1328
  var recorderStatus = useRecorderStore.getState().status;
1300
- if (uploadStatus === UPLOAD_STATUS.uploading) {
1329
+ if (uploadStatus === UPLOAD_STATUS$1.uploading || isRetryUpload) {
1330
+ setIsRetryUpload(false);
1301
1331
  multipartS3Uploader.completeUpload();
1302
- }
1303
- if (hasRecordingDiscarded({
1332
+ } else if (hasRecordingDiscarded({
1304
1333
  recorderStatus: recorderStatus,
1305
1334
  uploadStatus: uploadStatus
1306
1335
  })) {
@@ -1347,7 +1376,7 @@ var MediaRecorder$1 = function MediaRecorder(_ref, ref) {
1347
1376
  return multipartS3Uploader.abortUpload();
1348
1377
  case 2:
1349
1378
  uploadStatus = useMultipartS3UploadStore.getState().status;
1350
- if (!(uploadStatus === UPLOAD_STATUS.aborting)) {
1379
+ if (!(uploadStatus === UPLOAD_STATUS$1.aborting)) {
1351
1380
  _context2.next = 5;
1352
1381
  break;
1353
1382
  }
@@ -1391,6 +1420,35 @@ var MediaRecorder$1 = function MediaRecorder(_ref, ref) {
1391
1420
  restartRecording();
1392
1421
  setIsRestartAlertOpen(false);
1393
1422
  };
1423
+ var handleUploadError = function handleUploadError() {
1424
+ setUploadProgress(0);
1425
+ };
1426
+ var handleUploadProgress = function handleUploadProgress(progress) {
1427
+ setUploadProgress(progress);
1428
+ };
1429
+ var handleReUpload = /*#__PURE__*/function () {
1430
+ var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
1431
+ return _regeneratorRuntime.wrap(function _callee4$(_context4) {
1432
+ while (1) switch (_context4.prev = _context4.next) {
1433
+ case 0:
1434
+ setIsRetryUpload(true);
1435
+ setUploadProgress(0);
1436
+ _context4.next = 4;
1437
+ return multipartS3Uploader.abortUpload();
1438
+ case 4:
1439
+ multipartS3Uploader.resetState();
1440
+ multipartS3Uploader.push(screenRecorder.getWebmMediaBlob());
1441
+ handleCreateRecording();
1442
+ case 7:
1443
+ case "end":
1444
+ return _context4.stop();
1445
+ }
1446
+ }, _callee4);
1447
+ }));
1448
+ return function handleReUpload() {
1449
+ return _ref6.apply(this, arguments);
1450
+ };
1451
+ }();
1394
1452
  useImperativeHandle(ref, function () {
1395
1453
  return {
1396
1454
  handleDiscardRecording: function handleDiscardRecording() {
@@ -1433,17 +1491,22 @@ var MediaRecorder$1 = function MediaRecorder(_ref, ref) {
1433
1491
  return noop;
1434
1492
  }, [recorderStatus, error]);
1435
1493
  useEffect(function () {
1436
- screenRecorder.addCallback(SCREEN_RECORDER_EVENT.onDataAvailable, multipartS3Uploader.push);
1437
- screenRecorder.addCallback(SCREEN_RECORDER_EVENT.onStop, multipartS3Uploader.completeUpload);
1438
- screenRecorder.addCallback(SCREEN_RECORDER_EVENT.onDiscard, handleDiscardRecording);
1439
- screenRecorder.addCallback(SCREEN_RECORDER_EVENT.onRestart, handleRestartRecording);
1440
- multipartS3Uploader.addCallback(UPLOAD_EVENT.onComplete, handleUploadComplete);
1494
+ var _recorderCallbacks, _uploaderCallbacks;
1495
+ var recorderCallbacks = (_recorderCallbacks = {}, _defineProperty(_recorderCallbacks, SCREEN_RECORDER_EVENT.onDataAvailable, multipartS3Uploader.push), _defineProperty(_recorderCallbacks, SCREEN_RECORDER_EVENT.onStop, multipartS3Uploader.completeUpload), _defineProperty(_recorderCallbacks, SCREEN_RECORDER_EVENT.onDiscard, handleDiscardRecording), _defineProperty(_recorderCallbacks, SCREEN_RECORDER_EVENT.onRestart, handleRestartRecording), _recorderCallbacks);
1496
+ var uploaderCallbacks = (_uploaderCallbacks = {}, _defineProperty(_uploaderCallbacks, UPLOAD_EVENT.onComplete, handleUploadComplete), _defineProperty(_uploaderCallbacks, UPLOAD_EVENT.onError, handleUploadError), _defineProperty(_uploaderCallbacks, UPLOAD_EVENT.onProgress, handleUploadProgress), _uploaderCallbacks);
1497
+ Object.keys(recorderCallbacks).forEach(function (key) {
1498
+ screenRecorder.addCallback(key, recorderCallbacks[key]);
1499
+ });
1500
+ Object.keys(uploaderCallbacks).forEach(function (key) {
1501
+ multipartS3Uploader.addCallback(key, uploaderCallbacks[key]);
1502
+ });
1441
1503
  return function () {
1442
- screenRecorder.removeCallback(SCREEN_RECORDER_EVENT.onDataAvailable, multipartS3Uploader.push);
1443
- screenRecorder.removeCallback(SCREEN_RECORDER_EVENT.onStop, multipartS3Uploader.completeUpload);
1444
- screenRecorder.removeCallback(SCREEN_RECORDER_EVENT.onDiscard, handleDiscardRecording);
1445
- screenRecorder.removeCallback(SCREEN_RECORDER_EVENT.onRestart, handleRestartRecording);
1446
- multipartS3Uploader.removeCallback(UPLOAD_EVENT.onComplete, handleUploadComplete);
1504
+ Object.keys(recorderCallbacks).forEach(function (key) {
1505
+ screenRecorder.removeCallback(key, recorderCallbacks[key]);
1506
+ });
1507
+ Object.keys(uploaderCallbacks).forEach(function (key) {
1508
+ multipartS3Uploader.removeCallback(key, uploaderCallbacks[key]);
1509
+ });
1447
1510
  };
1448
1511
  }, [recording.id]);
1449
1512
  useEffect(function () {
@@ -1456,7 +1519,7 @@ var MediaRecorder$1 = function MediaRecorder(_ref, ref) {
1456
1519
  };
1457
1520
  }, []);
1458
1521
  useEffect(function () {
1459
- if (!isUploadStatus(UPLOAD_STATUS.insufficient_data)) return;
1522
+ if (!isUploadStatus(UPLOAD_STATUS$1.insufficient_data)) return;
1460
1523
  handleDiscardRecording();
1461
1524
  }, [uploadStatus]);
1462
1525
  var shouldShowSafariExtensionCalloutToStartRecording = isRecorderStatus(SCREEN_RECORDER_STATUS.idle) && IS_SAFARI_EXTENSION && error === SCREEN_RECORDER_ERROR.None;
@@ -1480,13 +1543,16 @@ var MediaRecorder$1 = function MediaRecorder(_ref, ref) {
1480
1543
  })]
1481
1544
  });
1482
1545
  }
1483
- if (isRecorderStatus(SCREEN_RECORDER_STATUS.stopped) && isUploadStatus(UPLOAD_STATUS.uploading)) {
1546
+ if (isRetryUpload || isRecorderStatus(SCREEN_RECORDER_STATUS.stopped) && isUploadStatus(UPLOAD_STATUS$1.uploading, UPLOAD_STATUS$1.error)) {
1484
1547
  return /*#__PURE__*/jsx(UploadingInProgress, {
1485
1548
  recording: recording,
1486
- onDiscard: handleDiscardRecording
1549
+ uploadProgress: uploadProgress,
1550
+ uploadStatus: uploadStatus,
1551
+ onDiscard: handleDiscardRecording,
1552
+ onRetryUpload: handleReUpload
1487
1553
  });
1488
1554
  }
1489
- if (isRecorderStatus(SCREEN_RECORDER_STATUS.stopped) && isUploadStatus(UPLOAD_STATUS.completed)) {
1555
+ if (isRecorderStatus(SCREEN_RECORDER_STATUS.stopped) && isUploadStatus(UPLOAD_STATUS$1.completed)) {
1490
1556
  return /*#__PURE__*/jsx("div", {
1491
1557
  className: "h-screen w-full",
1492
1558
  children: /*#__PURE__*/jsx(PageLoader, {})