@atlaskit/editor-plugin-media-insert 2.1.2 → 2.3.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/cjs/plugin.js +48 -4
  3. package/dist/cjs/ui/LocalMedia.js +143 -0
  4. package/dist/cjs/ui/{FromURL.js → MediaFromURL.js} +50 -27
  5. package/dist/cjs/ui/MediaInsertContent.js +14 -6
  6. package/dist/cjs/ui/MediaInsertPicker.js +6 -2
  7. package/dist/cjs/ui/useAnalyticsEvents.js +26 -10
  8. package/dist/es2019/plugin.js +49 -3
  9. package/dist/es2019/ui/LocalMedia.js +137 -0
  10. package/dist/es2019/ui/{FromURL.js → MediaFromURL.js} +39 -16
  11. package/dist/es2019/ui/MediaInsertContent.js +14 -6
  12. package/dist/es2019/ui/MediaInsertPicker.js +6 -2
  13. package/dist/es2019/ui/useAnalyticsEvents.js +26 -10
  14. package/dist/esm/plugin.js +48 -4
  15. package/dist/esm/ui/LocalMedia.js +136 -0
  16. package/dist/esm/ui/{FromURL.js → MediaFromURL.js} +50 -27
  17. package/dist/esm/ui/MediaInsertContent.js +14 -6
  18. package/dist/esm/ui/MediaInsertPicker.js +6 -2
  19. package/dist/esm/ui/useAnalyticsEvents.js +26 -10
  20. package/dist/types/types.d.ts +13 -0
  21. package/dist/types/ui/LocalMedia.d.ts +12 -0
  22. package/dist/types/ui/MediaCard.d.ts +1 -1
  23. package/dist/types/ui/MediaFromURL.d.ts +13 -0
  24. package/dist/types/ui/MediaInsertContent.d.ts +8 -3
  25. package/dist/types/ui/MediaInsertPicker.d.ts +1 -1
  26. package/dist/types/ui/types.d.ts +3 -2
  27. package/dist/types/ui/useAnalyticsEvents.d.ts +6 -3
  28. package/dist/types-ts4.5/types.d.ts +13 -0
  29. package/dist/types-ts4.5/ui/LocalMedia.d.ts +12 -0
  30. package/dist/types-ts4.5/ui/MediaCard.d.ts +1 -1
  31. package/dist/types-ts4.5/ui/MediaFromURL.d.ts +13 -0
  32. package/dist/types-ts4.5/ui/MediaInsertContent.d.ts +8 -3
  33. package/dist/types-ts4.5/ui/MediaInsertPicker.d.ts +1 -1
  34. package/dist/types-ts4.5/ui/types.d.ts +3 -2
  35. package/dist/types-ts4.5/ui/useAnalyticsEvents.d.ts +6 -3
  36. package/package.json +6 -5
  37. package/dist/types/ui/FromURL.d.ts +0 -13
  38. package/dist/types-ts4.5/ui/FromURL.d.ts +0 -13
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @atlaskit/editor-plugin-media-insert
2
2
 
3
+ ## 2.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#134882](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/134882)
8
+ [`ba204702f8e32`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/ba204702f8e32) -
9
+ [ux] [ED-24567] Insert media into the editor via the media insert picker
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies
14
+
15
+ ## 2.2.0
16
+
17
+ ### Minor Changes
18
+
19
+ - [#134463](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/134463)
20
+ [`d20ae898369bc`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/d20ae898369bc) -
21
+ [ux] [ED-24326] Add local file upload tab to media insert popup
22
+
23
+ ### Patch Changes
24
+
25
+ - Updated dependencies
26
+
3
27
  ## 2.1.2
4
28
 
5
29
  ### Patch Changes
@@ -43,6 +43,48 @@ var mediaInsertPlugin = exports.mediaInsertPlugin = function mediaInsertPlugin(_
43
43
  popupsMountPoint = _ref3.popupsMountPoint,
44
44
  popupsBoundariesElement = _ref3.popupsBoundariesElement,
45
45
  popupsScrollableElement = _ref3.popupsScrollableElement;
46
+ var insertMediaSingle = function insertMediaSingle(_ref4) {
47
+ var _api$media$actions$in;
48
+ var mediaState = _ref4.mediaState,
49
+ inputMethod = _ref4.inputMethod;
50
+ var id = mediaState.id,
51
+ dimensions = mediaState.dimensions,
52
+ contextId = mediaState.contextId,
53
+ _mediaState$scaleFact = mediaState.scaleFactor,
54
+ scaleFactor = _mediaState$scaleFact === void 0 ? 1 : _mediaState$scaleFact,
55
+ fileName = mediaState.fileName,
56
+ collection = mediaState.collection;
57
+ var _ref5 = dimensions || {
58
+ height: undefined,
59
+ width: undefined
60
+ },
61
+ width = _ref5.width,
62
+ height = _ref5.height;
63
+ var scaledWidth = width && Math.round(width / scaleFactor);
64
+ var node = editorView.state.schema.nodes.media.create({
65
+ id: id,
66
+ type: 'file',
67
+ collection: collection,
68
+ contextId: contextId,
69
+ width: scaledWidth,
70
+ height: height && Math.round(height / scaleFactor),
71
+ alt: fileName,
72
+ __fileMimeType: mediaState.fileMimeType
73
+ });
74
+ return (_api$media$actions$in = api === null || api === void 0 ? void 0 : api.media.actions.insertMediaAsMediaSingle(editorView, node, inputMethod)) !== null && _api$media$actions$in !== void 0 ? _api$media$actions$in : false;
75
+ };
76
+ var insertExternalMediaSingle = function insertExternalMediaSingle(_ref6) {
77
+ var _api$media$actions$in2;
78
+ var url = _ref6.url,
79
+ alt = _ref6.alt,
80
+ inputMethod = _ref6.inputMethod;
81
+ var node = editorView.state.schema.nodes.media.create({
82
+ type: 'external',
83
+ url: url,
84
+ alt: alt
85
+ });
86
+ return (_api$media$actions$in2 = api === null || api === void 0 ? void 0 : api.media.actions.insertMediaAsMediaSingle(editorView, node, inputMethod)) !== null && _api$media$actions$in2 !== void 0 ? _api$media$actions$in2 : false;
87
+ };
46
88
  return /*#__PURE__*/_react.default.createElement(_MediaInsertPicker.MediaInsertPicker, {
47
89
  api: api,
48
90
  editorView: editorView,
@@ -51,13 +93,15 @@ var mediaInsertPlugin = exports.mediaInsertPlugin = function mediaInsertPlugin(_
51
93
  popupsBoundariesElement: popupsBoundariesElement,
52
94
  popupsScrollableElement: popupsScrollableElement,
53
95
  closeMediaInsertPicker: function closeMediaInsertPicker() {
54
- editorView.dispatch((0, _actions.closeMediaInsertPicker)(editorView.state.tr));
55
- }
96
+ return editorView.dispatch((0, _actions.closeMediaInsertPicker)(editorView.state.tr));
97
+ },
98
+ insertMediaSingle: insertMediaSingle,
99
+ insertExternalMediaSingle: insertExternalMediaSingle
56
100
  });
57
101
  },
58
102
  pluginsOptions: {
59
- quickInsert: function quickInsert(_ref4) {
60
- var formatMessage = _ref4.formatMessage;
103
+ quickInsert: function quickInsert(_ref7) {
104
+ var formatMessage = _ref7.formatMessage;
61
105
  return [{
62
106
  id: 'media-insert',
63
107
  title: formatMessage(_messages.toolbarInsertBlockMessages.insertMediaFromUrl),
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.LocalMedia = void 0;
8
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
+ var _react = _interopRequireDefault(require("react"));
11
+ var _reactIntlNext = require("react-intl-next");
12
+ var _new = _interopRequireDefault(require("@atlaskit/button/new"));
13
+ var _analytics = require("@atlaskit/editor-common/analytics");
14
+ var _messages = require("@atlaskit/editor-common/messages");
15
+ var _upload = _interopRequireDefault(require("@atlaskit/icon/glyph/upload"));
16
+ var _mediaPicker = require("@atlaskit/media-picker");
17
+ var _primitives = require("@atlaskit/primitives");
18
+ var _sectionMessage = _interopRequireDefault(require("@atlaskit/section-message"));
19
+ var _useAnalyticsEvents2 = require("./useAnalyticsEvents");
20
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
21
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
22
+ var INITIAL_UPLOAD_STATE = Object.freeze({
23
+ isOpen: false,
24
+ error: null
25
+ });
26
+ var uploadReducer = function uploadReducer(state, action) {
27
+ switch (action.type) {
28
+ case 'open':
29
+ return _objectSpread(_objectSpread({}, INITIAL_UPLOAD_STATE), {}, {
30
+ isOpen: true
31
+ });
32
+ case 'close':
33
+ // This is the only case where we don't reset state. This is because
34
+ // onClose gets called for cancel _and_ upload, so we don't want to
35
+ // reset any loading or error states that may have occured
36
+ return _objectSpread(_objectSpread({}, state), {}, {
37
+ isOpen: false
38
+ });
39
+ case 'error':
40
+ return _objectSpread(_objectSpread({}, INITIAL_UPLOAD_STATE), {}, {
41
+ error: action.error
42
+ });
43
+ case 'reset':
44
+ return INITIAL_UPLOAD_STATE;
45
+ }
46
+ };
47
+ var isImagePreview = function isImagePreview(preview) {
48
+ return 'dimensions' in preview;
49
+ };
50
+ var LocalMedia = exports.LocalMedia = function LocalMedia(_ref) {
51
+ var mediaProvider = _ref.mediaProvider,
52
+ onInsert = _ref.onInsert,
53
+ dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent;
54
+ var intl = (0, _reactIntlNext.useIntl)();
55
+ var strings = {
56
+ upload: intl.formatMessage(_messages.mediaInsertMessages.upload),
57
+ networkError: intl.formatMessage(_messages.mediaInsertMessages.localFileNetworkErrorMessage),
58
+ genericError: intl.formatMessage(_messages.mediaInsertMessages.localFileErrorMessage)
59
+ };
60
+ var _useAnalyticsEvents = (0, _useAnalyticsEvents2.useAnalyticsEvents)(dispatchAnalyticsEvent),
61
+ onUploadButtonClickedAnalytics = _useAnalyticsEvents.onUploadButtonClickedAnalytics,
62
+ onUploadCommencedAnalytics = _useAnalyticsEvents.onUploadCommencedAnalytics,
63
+ onUploadSuccessAnalytics = _useAnalyticsEvents.onUploadSuccessAnalytics,
64
+ onUploadFailureAnalytics = _useAnalyticsEvents.onUploadFailureAnalytics;
65
+ var _React$useReducer = _react.default.useReducer(uploadReducer, INITIAL_UPLOAD_STATE),
66
+ _React$useReducer2 = (0, _slicedToArray2.default)(_React$useReducer, 2),
67
+ uploadState = _React$useReducer2[0],
68
+ dispatch = _React$useReducer2[1];
69
+ var onUpload = function onUpload(_ref2) {
70
+ var _mediaProvider$upload;
71
+ var file = _ref2.file,
72
+ preview = _ref2.preview;
73
+ onUploadSuccessAnalytics('local');
74
+ var mediaState = {
75
+ id: file.id,
76
+ collection: (_mediaProvider$upload = mediaProvider.uploadParams) === null || _mediaProvider$upload === void 0 ? void 0 : _mediaProvider$upload.collection,
77
+ fileMimeType: file.type,
78
+ fileSize: file.size,
79
+ fileName: file.name,
80
+ dimensions: undefined
81
+ };
82
+ if (isImagePreview(preview)) {
83
+ mediaState.dimensions = {
84
+ width: preview.dimensions.width,
85
+ height: preview.dimensions.height
86
+ };
87
+ }
88
+ onInsert({
89
+ mediaState: mediaState,
90
+ inputMethod: _analytics.INPUT_METHOD.MEDIA_PICKER
91
+ });
92
+
93
+ // Probably not needed but I guess it _could_ fail to close for some reason
94
+ dispatch({
95
+ type: 'reset'
96
+ });
97
+ };
98
+ var uploadParams = mediaProvider.uploadParams,
99
+ uploadMediaClientConfig = mediaProvider.uploadMediaClientConfig;
100
+ return /*#__PURE__*/_react.default.createElement(_primitives.Stack, {
101
+ grow: "fill",
102
+ space: "space.200"
103
+ }, uploadState.error && /*#__PURE__*/_react.default.createElement(_sectionMessage.default, {
104
+ appearance: "error"
105
+ }, uploadState.error === 'upload_fail' ? strings.networkError : strings.genericError), /*#__PURE__*/_react.default.createElement(_new.default, {
106
+ iconBefore: _upload.default,
107
+ shouldFitContainer: true,
108
+ isDisabled: !uploadMediaClientConfig || !uploadParams,
109
+ onClick: function onClick() {
110
+ onUploadButtonClickedAnalytics();
111
+ dispatch({
112
+ type: 'open'
113
+ });
114
+ },
115
+ autoFocus: true
116
+ }, strings.upload), uploadMediaClientConfig && uploadParams && /*#__PURE__*/_react.default.createElement(_mediaPicker.Browser, {
117
+ isOpen: uploadState.isOpen,
118
+ config: {
119
+ uploadParams: uploadParams
120
+ },
121
+ mediaClientConfig: uploadMediaClientConfig,
122
+ onUploadsStart: function onUploadsStart() {
123
+ onUploadCommencedAnalytics('local');
124
+ },
125
+ onPreviewUpdate: onUpload
126
+ // NOTE: this will fire for some errors like network failures, but not
127
+ // for others like empty files. Those have their own feedback toast
128
+ // owned by media.
129
+ ,
130
+ onError: function onError(payload) {
131
+ onUploadFailureAnalytics(payload.error.name, 'local');
132
+ dispatch({
133
+ type: 'error',
134
+ error: payload.error.name
135
+ });
136
+ },
137
+ onClose: function onClose() {
138
+ dispatch({
139
+ type: 'close'
140
+ });
141
+ }
142
+ }));
143
+ };
@@ -72,18 +72,18 @@ var previewStateReducer = function previewStateReducer(state, action) {
72
72
  };
73
73
  function MediaFromURL(_ref) {
74
74
  var mediaProvider = _ref.mediaProvider,
75
- onInsert = _ref.onInsert,
76
- onExternalInsert = _ref.onExternalInsert,
77
75
  dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent,
78
- closeMediaInsertPicker = _ref.closeMediaInsertPicker;
76
+ closeMediaInsertPicker = _ref.closeMediaInsertPicker,
77
+ insertMediaSingle = _ref.insertMediaSingle,
78
+ insertExternalMediaSingle = _ref.insertExternalMediaSingle;
79
79
  var intl = (0, _reactIntlNext.useIntl)();
80
80
  var strings = {
81
81
  loadPreview: intl.formatMessage(_messages.mediaInsertMessages.loadPreview),
82
82
  insert: intl.formatMessage(_messages.mediaInsertMessages.insert),
83
83
  pasteLinkToUpload: intl.formatMessage(_messages.mediaInsertMessages.pasteLinkToUpload),
84
84
  cancel: intl.formatMessage(_messages.mediaInsertMessages.cancel),
85
- errorMessage: intl.formatMessage(_messages.mediaInsertMessages.errorMessage),
86
- warning: intl.formatMessage(_messages.mediaInsertMessages.warning)
85
+ errorMessage: intl.formatMessage(_messages.mediaInsertMessages.fromUrlErrorMessage),
86
+ warning: intl.formatMessage(_messages.mediaInsertMessages.fromUrlWarning)
87
87
  };
88
88
  var _React$useState = _react.default.useState(''),
89
89
  _React$useState2 = (0, _slicedToArray2.default)(_React$useState, 2),
@@ -95,36 +95,39 @@ function MediaFromURL(_ref) {
95
95
  dispatch = _React$useReducer2[1];
96
96
  var pasteFlag = _react.default.useRef(false);
97
97
  var _useAnalyticsEvents = (0, _useAnalyticsEvents2.useAnalyticsEvents)(dispatchAnalyticsEvent),
98
- onUploadAnalytics = _useAnalyticsEvents.onUploadAnalytics,
98
+ onUploadButtonClickedAnalytics = _useAnalyticsEvents.onUploadButtonClickedAnalytics,
99
+ onUploadCommencedAnalytics = _useAnalyticsEvents.onUploadCommencedAnalytics,
99
100
  onUploadSuccessAnalytics = _useAnalyticsEvents.onUploadSuccessAnalytics,
100
101
  onUploadFailureAnalytics = _useAnalyticsEvents.onUploadFailureAnalytics;
101
102
  var uploadExternalMedia = _react.default.useCallback( /*#__PURE__*/function () {
102
103
  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(url) {
103
- var uploadMediaClientConfig, uploadParams, mediaClient, collection, _yield$mediaClient$fi, uploadableFileUpfrontIds, dimensions, message;
104
+ var uploadMediaClientConfig, uploadParams, mediaClient, collection, _yield$mediaClient$fi, uploadableFileUpfrontIds, dimensions, mimeType, message;
104
105
  return _regenerator.default.wrap(function _callee$(_context) {
105
106
  while (1) switch (_context.prev = _context.next) {
106
107
  case 0:
108
+ onUploadButtonClickedAnalytics();
107
109
  dispatch({
108
110
  type: 'loading'
109
111
  });
110
112
  uploadMediaClientConfig = mediaProvider.uploadMediaClientConfig, uploadParams = mediaProvider.uploadParams;
111
113
  if (uploadMediaClientConfig) {
112
- _context.next = 4;
114
+ _context.next = 5;
113
115
  break;
114
116
  }
115
117
  return _context.abrupt("return");
116
- case 4:
118
+ case 5:
117
119
  mediaClient = (0, _mediaClientReact.getMediaClient)(uploadMediaClientConfig);
118
120
  collection = uploadParams === null || uploadParams === void 0 ? void 0 : uploadParams.collection;
119
- onUploadAnalytics();
120
- _context.prev = 7;
121
- _context.next = 10;
121
+ onUploadCommencedAnalytics('url');
122
+ _context.prev = 8;
123
+ _context.next = 11;
122
124
  return mediaClient.file.uploadExternal(url, collection);
123
- case 10:
125
+ case 11:
124
126
  _yield$mediaClient$fi = _context.sent;
125
127
  uploadableFileUpfrontIds = _yield$mediaClient$fi.uploadableFileUpfrontIds;
126
128
  dimensions = _yield$mediaClient$fi.dimensions;
127
- onUploadSuccessAnalytics();
129
+ mimeType = _yield$mediaClient$fi.mimeType;
130
+ onUploadSuccessAnalytics('url');
128
131
  dispatch({
129
132
  type: 'success',
130
133
  payload: {
@@ -132,19 +135,20 @@ function MediaFromURL(_ref) {
132
135
  collection: collection,
133
136
  height: dimensions.height,
134
137
  width: dimensions.width,
135
- occurrenceKey: uploadableFileUpfrontIds.occurrenceKey
138
+ occurrenceKey: uploadableFileUpfrontIds.occurrenceKey,
139
+ fileMimeType: mimeType
136
140
  }
137
141
  });
138
- _context.next = 20;
142
+ _context.next = 22;
139
143
  break;
140
- case 17:
141
- _context.prev = 17;
142
- _context.t0 = _context["catch"](7);
144
+ case 19:
145
+ _context.prev = 19;
146
+ _context.t0 = _context["catch"](8);
143
147
  if (typeof _context.t0 === 'string' && _context.t0 === 'Could not download remote file') {
144
148
  // TODO: Make sure this gets good unit test coverage with the actual
145
149
  // media plugin. This hard coded error message could be changed at any
146
150
  // point and we need a unit test to break to stop people changing it.
147
- onUploadFailureAnalytics(_context.t0);
151
+ onUploadFailureAnalytics(_context.t0, 'url');
148
152
  dispatch({
149
153
  type: 'warning',
150
154
  warning: _context.t0,
@@ -152,28 +156,28 @@ function MediaFromURL(_ref) {
152
156
  });
153
157
  } else if (_context.t0 instanceof Error) {
154
158
  message = 'Image preview fetch failed';
155
- onUploadFailureAnalytics(message);
159
+ onUploadFailureAnalytics(message, 'url');
156
160
  dispatch({
157
161
  type: 'error',
158
162
  error: message
159
163
  });
160
164
  } else {
161
- onUploadFailureAnalytics('Unknown error');
165
+ onUploadFailureAnalytics('Unknown error', 'url');
162
166
  dispatch({
163
167
  type: 'error',
164
168
  error: 'Unknown error'
165
169
  });
166
170
  }
167
- case 20:
171
+ case 22:
168
172
  case "end":
169
173
  return _context.stop();
170
174
  }
171
- }, _callee, null, [[7, 17]]);
175
+ }, _callee, null, [[8, 19]]);
172
176
  }));
173
177
  return function (_x) {
174
178
  return _ref2.apply(this, arguments);
175
179
  };
176
- }(), [mediaProvider, onUploadAnalytics, onUploadFailureAnalytics, onUploadSuccessAnalytics, inputUrl]);
180
+ }(), [onUploadButtonClickedAnalytics, mediaProvider, onUploadCommencedAnalytics, onUploadSuccessAnalytics, onUploadFailureAnalytics, inputUrl]);
177
181
  var onURLChange = _react.default.useCallback(function (e) {
178
182
  var url = e.target.value;
179
183
  setUrl(url);
@@ -196,14 +200,33 @@ function MediaFromURL(_ref) {
196
200
  pasteFlag.current = true;
197
201
  }
198
202
  }, [inputUrl]);
203
+ var onInsert = _react.default.useCallback(function () {
204
+ if (previewState.previewInfo) {
205
+ insertMediaSingle({
206
+ mediaState: previewState.previewInfo,
207
+ inputMethod: _analytics.INPUT_METHOD.MEDIA_PICKER
208
+ });
209
+ }
210
+ closeMediaInsertPicker();
211
+ }, [closeMediaInsertPicker, insertMediaSingle, previewState.previewInfo]);
212
+ var onExternalInsert = _react.default.useCallback(function (url) {
213
+ if (previewState.warning) {
214
+ insertExternalMediaSingle({
215
+ url: url,
216
+ alt: url,
217
+ inputMethod: _analytics.INPUT_METHOD.MEDIA_PICKER
218
+ });
219
+ }
220
+ closeMediaInsertPicker();
221
+ }, [closeMediaInsertPicker, insertExternalMediaSingle, previewState.warning]);
199
222
  var onInsertClick = _react.default.useCallback(function () {
200
223
  if (previewState.previewInfo) {
201
- return onInsert(previewState.previewInfo);
224
+ return onInsert();
202
225
  }
203
226
  if (previewState.warning) {
204
227
  return onExternalInsert(inputUrl);
205
228
  }
206
- }, [onExternalInsert, onInsert, previewState.previewInfo, previewState.warning, inputUrl]);
229
+ }, [previewState.previewInfo, previewState.warning, onInsert, onExternalInsert, inputUrl]);
207
230
  var onInputKeyPress = _react.default.useCallback(function (event) {
208
231
  if (event && event.key === 'Esc') {
209
232
  if (dispatchAnalyticsEvent) {
@@ -11,23 +11,31 @@ var _reactIntlNext = require("react-intl-next");
11
11
  var _messages = require("@atlaskit/editor-common/messages");
12
12
  var _primitives = require("@atlaskit/primitives");
13
13
  var _tabs = _interopRequireWildcard(require("@atlaskit/tabs"));
14
- var _FromURL = require("./FromURL");
14
+ var _LocalMedia = require("./LocalMedia");
15
+ var _MediaFromURL = require("./MediaFromURL");
15
16
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
16
17
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
17
18
  var MediaInsertContent = exports.MediaInsertContent = function MediaInsertContent(_ref) {
18
19
  var mediaProvider = _ref.mediaProvider,
19
20
  dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent,
20
- closeMediaInsertPicker = _ref.closeMediaInsertPicker;
21
+ closeMediaInsertPicker = _ref.closeMediaInsertPicker,
22
+ insertMediaSingle = _ref.insertMediaSingle,
23
+ insertExternalMediaSingle = _ref.insertExternalMediaSingle;
21
24
  var intl = (0, _reactIntlNext.useIntl)();
22
25
  return /*#__PURE__*/_react.default.createElement(_tabs.default, {
23
26
  id: "media-insert-tab-navigation"
24
27
  }, /*#__PURE__*/_react.default.createElement(_primitives.Box, {
25
28
  paddingBlockEnd: "space.150"
26
- }, /*#__PURE__*/_react.default.createElement(_tabs.TabList, null, /*#__PURE__*/_react.default.createElement(_tabs.Tab, null, intl.formatMessage(_messages.mediaInsertMessages.linkTabTitle)))), /*#__PURE__*/_react.default.createElement(_tabs.TabPanel, null, /*#__PURE__*/_react.default.createElement(_FromURL.MediaFromURL, {
29
+ }, /*#__PURE__*/_react.default.createElement(_tabs.TabList, null, /*#__PURE__*/_react.default.createElement(_tabs.Tab, null, intl.formatMessage(_messages.mediaInsertMessages.fileTabTitle)), /*#__PURE__*/_react.default.createElement(_tabs.Tab, null, intl.formatMessage(_messages.mediaInsertMessages.linkTabTitle)))), /*#__PURE__*/_react.default.createElement(_tabs.TabPanel, null, /*#__PURE__*/_react.default.createElement(_LocalMedia.LocalMedia, {
30
+ mediaProvider: mediaProvider,
31
+ onInsert: insertMediaSingle,
32
+ onClose: closeMediaInsertPicker,
33
+ dispatchAnalyticsEvent: dispatchAnalyticsEvent
34
+ })), /*#__PURE__*/_react.default.createElement(_tabs.TabPanel, null, /*#__PURE__*/_react.default.createElement(_MediaFromURL.MediaFromURL, {
27
35
  mediaProvider: mediaProvider,
28
- onExternalInsert: function onExternalInsert() {},
29
- onInsert: function onInsert() {},
30
36
  dispatchAnalyticsEvent: dispatchAnalyticsEvent,
31
- closeMediaInsertPicker: closeMediaInsertPicker
37
+ closeMediaInsertPicker: closeMediaInsertPicker,
38
+ insertMediaSingle: insertMediaSingle,
39
+ insertExternalMediaSingle: insertExternalMediaSingle
32
40
  })));
33
41
  };
@@ -48,7 +48,9 @@ var MediaInsertPicker = exports.MediaInsertPicker = function MediaInsertPicker(_
48
48
  popupsMountPoint = _ref.popupsMountPoint,
49
49
  popupsBoundariesElement = _ref.popupsBoundariesElement,
50
50
  popupsScrollableElement = _ref.popupsScrollableElement,
51
- _closeMediaInsertPicker = _ref.closeMediaInsertPicker;
51
+ _closeMediaInsertPicker = _ref.closeMediaInsertPicker,
52
+ insertMediaSingle = _ref.insertMediaSingle,
53
+ insertExternalMediaSingle = _ref.insertExternalMediaSingle;
52
54
  var targetRef = getDomRefFromSelection(editorView, dispatchAnalyticsEvent);
53
55
  var isOpen = (_useSharedPluginState = (0, _hooks.useSharedPluginState)(api, ['mediaInsert'])) === null || _useSharedPluginState === void 0 || (_useSharedPluginState = _useSharedPluginState.mediaInsertState) === null || _useSharedPluginState === void 0 ? void 0 : _useSharedPluginState.isOpen;
54
56
  var mediaProvider = (_useSharedPluginState2 = (0, _hooks.useSharedPluginState)(api, ['media'])) === null || _useSharedPluginState2 === void 0 || (_useSharedPluginState2 = _useSharedPluginState2.mediaState) === null || _useSharedPluginState2 === void 0 ? void 0 : _useSharedPluginState2.mediaProvider;
@@ -98,6 +100,8 @@ var MediaInsertPicker = exports.MediaInsertPicker = function MediaInsertPicker(_
98
100
  closeMediaInsertPicker: function closeMediaInsertPicker() {
99
101
  _closeMediaInsertPicker();
100
102
  focusEditor();
101
- }
103
+ },
104
+ insertMediaSingle: insertMediaSingle,
105
+ insertExternalMediaSingle: insertExternalMediaSingle
102
106
  })));
103
107
  };
@@ -8,38 +8,54 @@ exports.useAnalyticsEvents = useAnalyticsEvents;
8
8
  var _react = _interopRequireDefault(require("react"));
9
9
  var _analytics = require("@atlaskit/editor-common/analytics");
10
10
  function useAnalyticsEvents(dispatchAnalyticsEvent) {
11
- var onUploadAnalytics = _react.default.useCallback(function () {
11
+ var onUploadButtonClickedAnalytics = _react.default.useCallback(function () {
12
12
  dispatchAnalyticsEvent === null || dispatchAnalyticsEvent === void 0 || dispatchAnalyticsEvent({
13
13
  action: _analytics.ACTION.CLICKED,
14
14
  actionSubject: _analytics.ACTION_SUBJECT.BUTTON,
15
- actionSubjectId: _analytics.ACTION_SUBJECT_ID.UPLOAD_MEDIA_FROM_URL,
15
+ actionSubjectId: _analytics.ACTION_SUBJECT_ID.UPLOAD_MEDIA,
16
16
  eventType: _analytics.EVENT_TYPE.UI
17
17
  });
18
18
  }, [dispatchAnalyticsEvent]);
19
- var onUploadSuccessAnalytics = _react.default.useCallback(function () {
19
+ var onUploadCommencedAnalytics = _react.default.useCallback(function (mediaUploadSource) {
20
+ dispatchAnalyticsEvent === null || dispatchAnalyticsEvent === void 0 || dispatchAnalyticsEvent({
21
+ action: _analytics.ACTION.UPLOAD_COMMENCED,
22
+ actionSubject: _analytics.ACTION_SUBJECT.MEDIA,
23
+ actionSubjectId: _analytics.ACTION_SUBJECT_ID.UPLOAD_MEDIA,
24
+ eventType: _analytics.EVENT_TYPE.OPERATIONAL,
25
+ attributes: {
26
+ mediaUploadSource: mediaUploadSource
27
+ }
28
+ });
29
+ }, [dispatchAnalyticsEvent]);
30
+ var onUploadSuccessAnalytics = _react.default.useCallback(function (mediaUploadSource) {
20
31
  dispatchAnalyticsEvent === null || dispatchAnalyticsEvent === void 0 || dispatchAnalyticsEvent({
21
32
  action: _analytics.ACTION.UPLOAD_SUCCEEDED,
22
33
  actionSubject: _analytics.ACTION_SUBJECT.MEDIA,
23
- actionSubjectId: _analytics.ACTION_SUBJECT_ID.UPLOAD_MEDIA_FROM_URL,
24
- eventType: _analytics.EVENT_TYPE.OPERATIONAL
34
+ actionSubjectId: _analytics.ACTION_SUBJECT_ID.UPLOAD_MEDIA,
35
+ eventType: _analytics.EVENT_TYPE.OPERATIONAL,
36
+ attributes: {
37
+ mediaUploadSource: mediaUploadSource
38
+ }
25
39
  });
26
40
  }, [dispatchAnalyticsEvent]);
27
- var onUploadFailureAnalytics = _react.default.useCallback(function (reason) {
41
+ var onUploadFailureAnalytics = _react.default.useCallback(function (reason, mediaUploadSource) {
28
42
  dispatchAnalyticsEvent === null || dispatchAnalyticsEvent === void 0 || dispatchAnalyticsEvent({
29
43
  action: _analytics.ACTION.UPLOAD_FAILED,
30
44
  actionSubject: _analytics.ACTION_SUBJECT.MEDIA,
31
- actionSubjectId: _analytics.ACTION_SUBJECT_ID.UPLOAD_MEDIA_FROM_URL,
45
+ actionSubjectId: _analytics.ACTION_SUBJECT_ID.UPLOAD_MEDIA,
32
46
  eventType: _analytics.EVENT_TYPE.OPERATIONAL,
33
47
  attributes: {
34
- reason: reason
48
+ reason: reason,
49
+ mediaUploadSource: mediaUploadSource
35
50
  }
36
51
  });
37
52
  }, [dispatchAnalyticsEvent]);
38
53
  return _react.default.useMemo(function () {
39
54
  return {
40
- onUploadAnalytics: onUploadAnalytics,
55
+ onUploadButtonClickedAnalytics: onUploadButtonClickedAnalytics,
56
+ onUploadCommencedAnalytics: onUploadCommencedAnalytics,
41
57
  onUploadSuccessAnalytics: onUploadSuccessAnalytics,
42
58
  onUploadFailureAnalytics: onUploadFailureAnalytics
43
59
  };
44
- }, [onUploadAnalytics, onUploadSuccessAnalytics, onUploadFailureAnalytics]);
60
+ }, [onUploadButtonClickedAnalytics, onUploadCommencedAnalytics, onUploadSuccessAnalytics, onUploadFailureAnalytics]);
45
61
  }
@@ -37,6 +37,52 @@ export const mediaInsertPlugin = ({
37
37
  popupsBoundariesElement,
38
38
  popupsScrollableElement
39
39
  }) => {
40
+ const insertMediaSingle = ({
41
+ mediaState,
42
+ inputMethod
43
+ }) => {
44
+ var _api$media$actions$in;
45
+ const {
46
+ id,
47
+ dimensions,
48
+ contextId,
49
+ scaleFactor = 1,
50
+ fileName,
51
+ collection
52
+ } = mediaState;
53
+ const {
54
+ width,
55
+ height
56
+ } = dimensions || {
57
+ height: undefined,
58
+ width: undefined
59
+ };
60
+ const scaledWidth = width && Math.round(width / scaleFactor);
61
+ const node = editorView.state.schema.nodes.media.create({
62
+ id,
63
+ type: 'file',
64
+ collection,
65
+ contextId,
66
+ width: scaledWidth,
67
+ height: height && Math.round(height / scaleFactor),
68
+ alt: fileName,
69
+ __fileMimeType: mediaState.fileMimeType
70
+ });
71
+ return (_api$media$actions$in = api === null || api === void 0 ? void 0 : api.media.actions.insertMediaAsMediaSingle(editorView, node, inputMethod)) !== null && _api$media$actions$in !== void 0 ? _api$media$actions$in : false;
72
+ };
73
+ const insertExternalMediaSingle = ({
74
+ url,
75
+ alt,
76
+ inputMethod
77
+ }) => {
78
+ var _api$media$actions$in2;
79
+ const node = editorView.state.schema.nodes.media.create({
80
+ type: 'external',
81
+ url,
82
+ alt
83
+ });
84
+ return (_api$media$actions$in2 = api === null || api === void 0 ? void 0 : api.media.actions.insertMediaAsMediaSingle(editorView, node, inputMethod)) !== null && _api$media$actions$in2 !== void 0 ? _api$media$actions$in2 : false;
85
+ };
40
86
  return /*#__PURE__*/React.createElement(MediaInsertPicker, {
41
87
  api: api,
42
88
  editorView: editorView,
@@ -44,9 +90,9 @@ export const mediaInsertPlugin = ({
44
90
  popupsMountPoint: popupsMountPoint,
45
91
  popupsBoundariesElement: popupsBoundariesElement,
46
92
  popupsScrollableElement: popupsScrollableElement,
47
- closeMediaInsertPicker: () => {
48
- editorView.dispatch(closeMediaInsertPicker(editorView.state.tr));
49
- }
93
+ closeMediaInsertPicker: () => editorView.dispatch(closeMediaInsertPicker(editorView.state.tr)),
94
+ insertMediaSingle: insertMediaSingle,
95
+ insertExternalMediaSingle: insertExternalMediaSingle
50
96
  });
51
97
  },
52
98
  pluginsOptions: {