@bigbinary/neeto-media-recorder 1.0.8 → 1.0.10

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
@@ -1,18 +1,19 @@
1
1
  import { shallow } from 'zustand/shallow';
2
2
  import React, { useState, useEffect, forwardRef, useImperativeHandle } from 'react';
3
3
  import classNames from 'classnames';
4
+ import { isNotEmpty, noop } from '@bigbinary/neeto-cist';
5
+ import { SCREEN_RECORDER_STATUS, SCREEN_RECORDER_ERROR, IS_SAFARI_EXTENSION, UPLOAD_STATUS, ONE_MINUTE_IN_MILLISECONDS, ONE_SECOND_IN_MILLISECONDS, IS_EXTENSION, SCREEN_RECORDER_EVENT, UPLOAD_EVENT } from '@bigbinary/neeto-media-recorder/constants';
6
+ import { screenRecorder, multipartS3Uploader } from '@bigbinary/neeto-media-recorder/core';
4
7
  import { Typography, Spinner, Button, Callout, Alert } from '@bigbinary/neetoui';
5
- import { isEmpty } from 'ramda';
6
8
  import { useTranslation } from 'react-i18next';
7
9
  import { useMutation } from 'react-query';
8
10
  import axios from 'axios';
9
- import { screenRecorder, multipartS3Uploader } from '@bigbinary/neeto-media-recorder/core';
10
- import { SCREEN_RECORDER_STATUS, SCREEN_RECORDER_ERROR, IS_SAFARI_EXTENSION, ONE_MINUTE_IN_MILLISECONDS, ONE_SECOND_IN_MILLISECONDS, IS_EXTENSION, SCREEN_RECORDER_EVENT, UPLOAD_EVENT, UPLOAD_STATUS } from '@bigbinary/neeto-media-recorder/constants';
11
11
  import withT from '@bigbinary/neeto-commons-frontend/react-utils/withT';
12
- import { isNotEmpty, noop } from '@bigbinary/neeto-cist';
13
12
  import { Pause, Delete, Copy, Download } from '@bigbinary/neeto-icons';
14
- import CopyToClipboardButton from '@bigbinary/neeto-molecules/CopyToClipboardButton';
13
+ import { copyToClipboard } from '@bigbinary/neeto-commons-frontend/utils/general';
15
14
  import { generatePublicUrl } from '@bigbinary/neeto-media-recorder/utils';
15
+ import CopyToClipboardButton from '@bigbinary/neeto-molecules/CopyToClipboardButton';
16
+ import { isEmpty } from 'ramda';
16
17
 
17
18
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
18
19
  try {
@@ -454,8 +455,8 @@ try {
454
455
  var _regeneratorRuntime = /*@__PURE__*/getDefaultExportFromCjs(regenerator);
455
456
 
456
457
  var baseUrl = "/api/v1/recordings";
457
- var create = function create(payload) {
458
- return axios.post(baseUrl, payload);
458
+ var create = function create() {
459
+ return axios.post(baseUrl);
459
460
  };
460
461
  var update = function update(_ref) {
461
462
  var id = _ref.id,
@@ -691,16 +692,16 @@ var Controls = function Controls(_ref) {
691
692
  className: "flex-shrink-0",
692
693
  size: "large",
693
694
  style: "text",
694
- tooltipProps: {
695
- content: t("neetoMediaRecorder.record.pause"),
696
- position: "top"
697
- },
698
695
  icon: function icon() {
699
696
  return /*#__PURE__*/React.createElement(Pause, {
700
697
  className: "nr-control-button__icon--neeto",
701
698
  size: 24
702
699
  });
703
700
  },
701
+ tooltipProps: {
702
+ content: t("neetoMediaRecorder.record.pause"),
703
+ position: "top"
704
+ },
704
705
  onClick: pauseRecording
705
706
  }), isStatus(SCREEN_RECORDER_STATUS.paused) && /*#__PURE__*/React.createElement(Button, {
706
707
  className: "flex-shrink-0",
@@ -738,16 +739,16 @@ var Controls = function Controls(_ref) {
738
739
  className: "flex-shrink-0",
739
740
  size: "large",
740
741
  style: "text",
741
- tooltipProps: {
742
- content: t("neetoMediaRecorder.record.discard"),
743
- position: "top"
744
- },
745
742
  icon: function icon() {
746
743
  return /*#__PURE__*/React.createElement(Delete, {
747
744
  className: "nr-control-button__icon--neeto",
748
745
  size: 24
749
746
  });
750
747
  },
748
+ tooltipProps: {
749
+ content: t("neetoMediaRecorder.record.discard"),
750
+ position: "top"
751
+ },
751
752
  onClick: function onClick() {
752
753
  return setIsDiscardAlertOpen(true);
753
754
  }
@@ -814,6 +815,11 @@ var downloadRecordingBlob = function downloadRecordingBlob(blob, name) {
814
815
  document.body.removeChild(linkElement);
815
816
  URL.revokeObjectURL(blobUrl);
816
817
  };
818
+ var hasRecordingDiscarded = function hasRecordingDiscarded(_ref) {
819
+ var recorderStatus = _ref.recorderStatus,
820
+ uploadStatus = _ref.uploadStatus;
821
+ return recorderStatus === SCREEN_RECORDER_STATUS.stopped && uploadStatus === UPLOAD_STATUS.aborting;
822
+ };
817
823
 
818
824
  var Timer = function Timer() {
819
825
  var _useTranslation = useTranslation(),
@@ -849,24 +855,34 @@ var UnSupportedBrowser = withT(function (_ref) {
849
855
  });
850
856
 
851
857
  var UploadingInProgress = function UploadingInProgress(_ref) {
852
- var recordingId = _ref.recordingId,
853
- recordingTitle = _ref.recordingTitle;
854
- var _useState = useState(window.location.origin),
858
+ var recording = _ref.recording;
859
+ var _useState = useState(""),
855
860
  _useState2 = _slicedToArray(_useState, 2),
856
861
  baseURL = _useState2[0],
857
862
  setBaseURL = _useState2[1];
858
863
  var _useTranslation = useTranslation(),
859
864
  t = _useTranslation.t;
860
865
  var handleRecordingBlobDownload = function handleRecordingBlobDownload() {
861
- downloadRecordingBlob(screenRecorder.getWebmMediaBlob(), recordingTitle);
866
+ downloadRecordingBlob(screenRecorder.getWebmMediaBlob(), recording.title);
862
867
  };
863
868
  useEffect(function () {
864
- if (!IS_EXTENSION) return;
869
+ if (!IS_EXTENSION) {
870
+ setBaseURL(window.location.origin);
871
+ return;
872
+ }
865
873
  chrome.storage.local.get("baseURL").then(function (_ref2) {
866
874
  var baseURL = _ref2.baseURL;
867
875
  setBaseURL(baseURL);
868
876
  });
869
877
  }, []);
878
+ useEffect(function () {
879
+ if (!window.document.hasFocus() || !recording.id || isEmpty(baseURL)) {
880
+ return;
881
+ }
882
+ copyToClipboard(generatePublicUrl(recording.id, baseURL), {
883
+ message: t("neetoMediaRecorder.record.copyToClipboardToastrMessage")
884
+ });
885
+ }, [recording.id, baseURL]);
870
886
  return /*#__PURE__*/React.createElement("div", {
871
887
  className: "flex h-screen w-full flex-col items-center justify-center"
872
888
  }, /*#__PURE__*/React.createElement("div", {
@@ -879,7 +895,7 @@ var UploadingInProgress = function UploadingInProgress(_ref) {
879
895
  icon: Copy,
880
896
  label: t("neetoMediaRecorder.record.copyToClipboard"),
881
897
  style: "primary",
882
- value: generatePublicUrl(recordingId, baseURL)
898
+ value: generatePublicUrl(recording.id, baseURL)
883
899
  }), /*#__PURE__*/React.createElement(Button, {
884
900
  icon: Download,
885
901
  style: "secondary",
@@ -894,6 +910,7 @@ var UploadingInProgress = function UploadingInProgress(_ref) {
894
910
  var useRecorderStore = screenRecorder.useRecorderStore,
895
911
  restartRecording = screenRecorder.restartRecording,
896
912
  discardRecording = screenRecorder.discardRecording;
913
+ var useMultipartS3UploadStore = multipartS3Uploader.useMultipartS3UploadStore;
897
914
  var MediaRecorder = function MediaRecorder(_ref, ref) {
898
915
  var _ref$onUploadComplete = _ref.onUploadComplete,
899
916
  onUploadComplete = _ref$onUploadComplete === void 0 ? noop : _ref$onUploadComplete,
@@ -901,26 +918,14 @@ var MediaRecorder = function MediaRecorder(_ref, ref) {
901
918
  onDiscard = _ref$onDiscard === void 0 ? noop : _ref$onDiscard;
902
919
  var _useTranslation = useTranslation(),
903
920
  t = _useTranslation.t;
904
- var _useState = useState(""),
921
+ var _useState = useState(false),
905
922
  _useState2 = _slicedToArray(_useState, 2),
906
- recordingId = _useState2[0],
907
- setRecordingId = _useState2[1];
908
- var _useState3 = useState(""),
923
+ isDiscardAlertOpen = _useState2[0],
924
+ setIsDiscardAlertOpen = _useState2[1];
925
+ var _useState3 = useState(false),
909
926
  _useState4 = _slicedToArray(_useState3, 2),
910
- uploadId = _useState4[0],
911
- setUploadId = _useState4[1];
912
- var _useState5 = useState(""),
913
- _useState6 = _slicedToArray(_useState5, 2),
914
- defaultRecordingTitle = _useState6[0],
915
- setDefaultRecordingTitle = _useState6[1];
916
- var _useState7 = useState(false),
917
- _useState8 = _slicedToArray(_useState7, 2),
918
- isDiscardAlertOpen = _useState8[0],
919
- setIsDiscardAlertOpen = _useState8[1];
920
- var _useState9 = useState(false),
921
- _useState10 = _slicedToArray(_useState9, 2),
922
- isRestartAlertOpen = _useState10[0],
923
- setIsRestartAlertOpen = _useState10[1];
927
+ isRestartAlertOpen = _useState4[0],
928
+ setIsRestartAlertOpen = _useState4[1];
924
929
  var _useRecorderStore = useRecorderStore(function (store) {
925
930
  return {
926
931
  status: store["status"],
@@ -931,48 +936,77 @@ var MediaRecorder = function MediaRecorder(_ref, ref) {
931
936
  recorderStatus = _useRecorderStore.status,
932
937
  error = _useRecorderStore.error,
933
938
  countdownTimeLeft = _useRecorderStore.countdownTimeLeft;
939
+ var _useMultipartS3Upload = useMultipartS3UploadStore(function (store) {
940
+ return {
941
+ status: store["status"]
942
+ };
943
+ }, shallow),
944
+ uploadStatus = _useMultipartS3Upload.status;
934
945
  var _useRecorderStatus = useRecorderStatus(),
935
946
  isRecorderStatus = _useRecorderStatus.isStatus;
936
- var _useMultipartS3Upload = useMultipartS3UploadStatus(),
937
- isUploadStatus = _useMultipartS3Upload.isStatus;
947
+ var _useMultipartS3Upload2 = useMultipartS3UploadStatus(),
948
+ isUploadStatus = _useMultipartS3Upload2.isStatus;
938
949
  var _useCreateRecording = useCreateRecording({
939
- onSuccess: function onSuccess(data) {
940
- setDefaultRecordingTitle(data === null || data === void 0 ? void 0 : data.recording.title);
941
- setRecordingId(data === null || data === void 0 ? void 0 : data.recording.id);
942
- setUploadId(data === null || data === void 0 ? void 0 : data.uploadId);
950
+ onSuccess: function onSuccess(_ref2) {
951
+ var recording = _ref2.recording,
952
+ uploadId = _ref2.uploadId;
953
+ multipartS3Uploader.initialize(recording.id, uploadId);
954
+ var uploadStatus = useMultipartS3UploadStore.getState().status;
955
+ var recorderStatus = useRecorderStore.getState().status;
956
+ if (uploadStatus === UPLOAD_STATUS.uploading) {
957
+ multipartS3Uploader.completeUpload();
958
+ }
959
+ if (hasRecordingDiscarded({
960
+ recorderStatus: recorderStatus,
961
+ uploadStatus: uploadStatus
962
+ })) {
963
+ handleDiscardRecording();
964
+ }
943
965
  }
944
966
  }),
945
- createRecording = _useCreateRecording.mutate;
967
+ createRecording = _useCreateRecording.mutate,
968
+ _useCreateRecording$d = _useCreateRecording.data,
969
+ _useCreateRecording$d2 = _useCreateRecording$d === void 0 ? {} : _useCreateRecording$d,
970
+ _useCreateRecording$d3 = _useCreateRecording$d2.recording,
971
+ recording = _useCreateRecording$d3 === void 0 ? {} : _useCreateRecording$d3;
946
972
  var _useRecordingUploadSu = useRecordingUploadSuccess(),
947
973
  markRecordingAsUploaded = _useRecordingUploadSu.mutate;
948
974
  var handleUploadComplete = function handleUploadComplete() {
949
- return markRecordingAsUploaded(recordingId, {
975
+ return markRecordingAsUploaded(recording.id, {
950
976
  onSuccess: function onSuccess() {
951
- return onUploadComplete(recordingId);
977
+ return onUploadComplete(recording.id);
952
978
  }
953
979
  });
954
980
  };
955
981
  var handleDiscardRecording = /*#__PURE__*/function () {
956
- var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
982
+ var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
983
+ var uploadStatus;
957
984
  return _regeneratorRuntime.wrap(function _callee$(_context) {
958
985
  while (1) switch (_context.prev = _context.next) {
959
986
  case 0:
960
987
  _context.next = 2;
961
988
  return multipartS3Uploader.abortUpload();
962
989
  case 2:
990
+ uploadStatus = useMultipartS3UploadStore.getState().status;
991
+ if (!(uploadStatus === UPLOAD_STATUS.aborting)) {
992
+ _context.next = 5;
993
+ break;
994
+ }
995
+ return _context.abrupt("return");
996
+ case 5:
963
997
  onDiscard();
964
- case 3:
998
+ case 6:
965
999
  case "end":
966
1000
  return _context.stop();
967
1001
  }
968
1002
  }, _callee);
969
1003
  }));
970
1004
  return function handleDiscardRecording() {
971
- return _ref2.apply(this, arguments);
1005
+ return _ref3.apply(this, arguments);
972
1006
  };
973
1007
  }();
974
1008
  var handleRestartRecording = /*#__PURE__*/function () {
975
- var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
1009
+ var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
976
1010
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
977
1011
  while (1) switch (_context2.prev = _context2.next) {
978
1012
  case 0:
@@ -987,7 +1021,7 @@ var MediaRecorder = function MediaRecorder(_ref, ref) {
987
1021
  }, _callee2);
988
1022
  }));
989
1023
  return function handleRestartRecording() {
990
- return _ref3.apply(this, arguments);
1024
+ return _ref4.apply(this, arguments);
991
1025
  };
992
1026
  }();
993
1027
  var handleDiscardAlertClose = function handleDiscardAlertClose() {
@@ -1015,8 +1049,6 @@ var MediaRecorder = function MediaRecorder(_ref, ref) {
1015
1049
  screenRecorder.startRecording();
1016
1050
  }, [recorderStatus, error]);
1017
1051
  useEffect(function () {
1018
- if (isEmpty(uploadId)) return undefined;
1019
- multipartS3Uploader.initialize(recordingId, uploadId);
1020
1052
  screenRecorder.addCallback(SCREEN_RECORDER_EVENT.onDataAvailable, multipartS3Uploader.push);
1021
1053
  screenRecorder.addCallback(SCREEN_RECORDER_EVENT.onStop, multipartS3Uploader.completeUpload);
1022
1054
  screenRecorder.addCallback(SCREEN_RECORDER_EVENT.onDiscard, handleDiscardRecording);
@@ -1029,7 +1061,7 @@ var MediaRecorder = function MediaRecorder(_ref, ref) {
1029
1061
  screenRecorder.removeCallback(SCREEN_RECORDER_EVENT.onRestart, handleRestartRecording);
1030
1062
  multipartS3Uploader.removeCallback(UPLOAD_EVENT.onComplete, handleUploadComplete);
1031
1063
  };
1032
- }, [uploadId, recordingId]);
1064
+ }, [recording]);
1033
1065
  useEffect(function () {
1034
1066
  screenRecorder.addCallback(SCREEN_RECORDER_EVENT.onStart, createRecording);
1035
1067
  screenRecorder.addCallback(SCREEN_RECORDER_EVENT.onDiscardDuringCountdown, onDiscard);
@@ -1039,15 +1071,19 @@ var MediaRecorder = function MediaRecorder(_ref, ref) {
1039
1071
  screenRecorder.resetState();
1040
1072
  };
1041
1073
  }, []);
1042
- var shouldShowSafariExtensionCalloutToStartRecording = isRecorderStatus(SCREEN_RECORDER_STATUS.idle) && IS_SAFARI_EXTENSION && error == SCREEN_RECORDER_ERROR.None;
1043
- if (error === SCREEN_RECORDER_ERROR.UnSupportedBrowser) return /*#__PURE__*/React.createElement(UnSupportedBrowser, null);
1074
+ var shouldShowSafariExtensionCalloutToStartRecording = isRecorderStatus(SCREEN_RECORDER_STATUS.idle) && IS_SAFARI_EXTENSION && error === SCREEN_RECORDER_ERROR.None;
1075
+ if (error === SCREEN_RECORDER_ERROR.UnSupportedBrowser) {
1076
+ return /*#__PURE__*/React.createElement(UnSupportedBrowser, null);
1077
+ }
1044
1078
  if (isRecorderStatus(SCREEN_RECORDER_STATUS.stopped) && isUploadStatus(UPLOAD_STATUS.uploading)) {
1045
1079
  return /*#__PURE__*/React.createElement(UploadingInProgress, {
1046
- recordingId: recordingId,
1047
- recordingTitle: defaultRecordingTitle
1080
+ recording: recording
1048
1081
  });
1049
1082
  }
1050
- if (isRecorderStatus(SCREEN_RECORDER_STATUS.stopped) && isUploadStatus(UPLOAD_STATUS.aborting)) {
1083
+ if (hasRecordingDiscarded({
1084
+ recorderStatus: recorderStatus,
1085
+ uploadStatus: uploadStatus
1086
+ })) {
1051
1087
  return /*#__PURE__*/React.createElement(AbortUpload, null);
1052
1088
  }
1053
1089
  return /*#__PURE__*/React.createElement("div", {
@@ -1069,9 +1105,9 @@ var MediaRecorder = function MediaRecorder(_ref, ref) {
1069
1105
  className: "neeto-ui-bg-primary-100 neeto-ui-rounded-full flex h-32 w-32 items-center justify-center",
1070
1106
  style: "h1"
1071
1107
  }, countdownTimeLeft), /*#__PURE__*/React.createElement(Typography, null, t("neetoMediaRecorder.record.startsIn"))), isRecorderStatus(SCREEN_RECORDER_STATUS.recording, SCREEN_RECORDER_STATUS.paused) && /*#__PURE__*/React.createElement(Timer, null)), /*#__PURE__*/React.createElement(Controls, {
1072
- className: "mt-5",
1073
1108
  setIsDiscardAlertOpen: setIsDiscardAlertOpen,
1074
- setIsRestartAlertOpen: setIsRestartAlertOpen
1109
+ setIsRestartAlertOpen: setIsRestartAlertOpen,
1110
+ className: "mt-5"
1075
1111
  }), /*#__PURE__*/React.createElement(Alert, {
1076
1112
  isOpen: isDiscardAlertOpen,
1077
1113
  message: t("neetoMediaRecorder.record.discardConfirmation.message"),