@atlaskit/editor-plugin-media-insert 9.2.0 → 9.2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @atlaskit/editor-plugin-media-insert
2
2
 
3
+ ## 9.2.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [`0a4f34cc9b35c`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/0a4f34cc9b35c) -
8
+ Cleanup platform_editor_media_from_url_remove_form
9
+ - Updated dependencies
10
+
11
+ ## 9.2.1
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies
16
+
3
17
  ## 9.2.0
4
18
 
5
19
  ### Minor Changes
@@ -15,14 +15,12 @@ var _hooks = require("@atlaskit/editor-common/hooks");
15
15
  var _messages = require("@atlaskit/editor-common/messages");
16
16
  var _ui = require("@atlaskit/editor-common/ui");
17
17
  var _editorSharedStyles = require("@atlaskit/editor-shared-styles");
18
- var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
19
18
  var _compiled = require("@atlaskit/primitives/compiled");
20
19
  var _tabs = _interopRequireWildcard(require("@atlaskit/tabs"));
21
20
  var _useFocusEditor = require("./hooks/use-focus-editor");
22
21
  var _useUnholyAutofocus2 = require("./hooks/use-unholy-autofocus");
23
22
  var _LocalMedia = require("./LocalMedia");
24
23
  var _MediaFromURL = require("./MediaFromURL");
25
- var _MediaFromURLWithForm = require("./MediaFromURLWithForm");
26
24
  var _MediaInsertWrapper = require("./MediaInsertWrapper");
27
25
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
28
26
  var PopupWithListeners = (0, _ui.withOuterListeners)(_ui.Popup);
@@ -153,19 +151,7 @@ var MediaInsertPicker = exports.MediaInsertPicker = function MediaInsertPicker(_
153
151
  },
154
152
  dispatchAnalyticsEvent: dispatchAnalyticsEvent,
155
153
  insertFile: insertFile
156
- })), /*#__PURE__*/_react.default.createElement(CustomTabPanel, null, (0, _platformFeatureFlags.fg)('platform_editor_media_from_url_remove_form') ? /*#__PURE__*/_react.default.createElement(_MediaFromURL.MediaFromURL, {
157
- mediaProvider: mediaProvider,
158
- dispatchAnalyticsEvent: dispatchAnalyticsEvent,
159
- closeMediaInsertPicker: function closeMediaInsertPicker() {
160
- _closeMediaInsertPicker();
161
- focusEditor();
162
- },
163
- insertMediaSingle: insertMediaSingle,
164
- insertExternalMediaSingle: insertExternalMediaSingle,
165
- isOnlyExternalLinks: isOnlyExternalLinks,
166
- customizedUrlValidation: customizedUrlValidation,
167
- customizedHelperMessage: customizedHelperMessage
168
- }) : /*#__PURE__*/_react.default.createElement(_MediaFromURLWithForm.MediaFromURLWithForm, {
154
+ })), /*#__PURE__*/_react.default.createElement(CustomTabPanel, null, /*#__PURE__*/_react.default.createElement(_MediaFromURL.MediaFromURL, {
169
155
  mediaProvider: mediaProvider,
170
156
  dispatchAnalyticsEvent: dispatchAnalyticsEvent,
171
157
  closeMediaInsertPicker: function closeMediaInsertPicker() {
@@ -7,14 +7,12 @@ import { sharedPluginStateHookMigratorFactory, useSharedPluginState, useSharedPl
7
7
  import { mediaInsertMessages } from '@atlaskit/editor-common/messages';
8
8
  import { PlainOutsideClickTargetRefContext, Popup, withOuterListeners } from '@atlaskit/editor-common/ui';
9
9
  import { akEditorFloatingDialogZIndex } from '@atlaskit/editor-shared-styles';
10
- import { fg } from '@atlaskit/platform-feature-flags';
11
10
  import { Box } from '@atlaskit/primitives/compiled';
12
11
  import Tabs, { Tab, TabList, useTabPanel } from '@atlaskit/tabs';
13
12
  import { useFocusEditor } from './hooks/use-focus-editor';
14
13
  import { useUnholyAutofocus } from './hooks/use-unholy-autofocus';
15
14
  import { LocalMedia } from './LocalMedia';
16
15
  import { MediaFromURL } from './MediaFromURL';
17
- import { MediaFromURLWithForm } from './MediaFromURLWithForm';
18
16
  import { MediaInsertWrapper } from './MediaInsertWrapper';
19
17
  const PopupWithListeners = withOuterListeners(Popup);
20
18
 
@@ -145,19 +143,7 @@ export const MediaInsertPicker = ({
145
143
  },
146
144
  dispatchAnalyticsEvent: dispatchAnalyticsEvent,
147
145
  insertFile: insertFile
148
- })), /*#__PURE__*/React.createElement(CustomTabPanel, null, fg('platform_editor_media_from_url_remove_form') ? /*#__PURE__*/React.createElement(MediaFromURL, {
149
- mediaProvider: mediaProvider,
150
- dispatchAnalyticsEvent: dispatchAnalyticsEvent,
151
- closeMediaInsertPicker: () => {
152
- closeMediaInsertPicker();
153
- focusEditor();
154
- },
155
- insertMediaSingle: insertMediaSingle,
156
- insertExternalMediaSingle: insertExternalMediaSingle,
157
- isOnlyExternalLinks: isOnlyExternalLinks,
158
- customizedUrlValidation: customizedUrlValidation,
159
- customizedHelperMessage: customizedHelperMessage
160
- }) : /*#__PURE__*/React.createElement(MediaFromURLWithForm, {
146
+ })), /*#__PURE__*/React.createElement(CustomTabPanel, null, /*#__PURE__*/React.createElement(MediaFromURL, {
161
147
  mediaProvider: mediaProvider,
162
148
  dispatchAnalyticsEvent: dispatchAnalyticsEvent,
163
149
  closeMediaInsertPicker: () => {
@@ -7,14 +7,12 @@ import { sharedPluginStateHookMigratorFactory, useSharedPluginState, useSharedPl
7
7
  import { mediaInsertMessages } from '@atlaskit/editor-common/messages';
8
8
  import { PlainOutsideClickTargetRefContext, Popup, withOuterListeners } from '@atlaskit/editor-common/ui';
9
9
  import { akEditorFloatingDialogZIndex } from '@atlaskit/editor-shared-styles';
10
- import { fg } from '@atlaskit/platform-feature-flags';
11
10
  import { Box } from '@atlaskit/primitives/compiled';
12
11
  import Tabs, { Tab, TabList, useTabPanel } from '@atlaskit/tabs';
13
12
  import { useFocusEditor } from './hooks/use-focus-editor';
14
13
  import { useUnholyAutofocus } from './hooks/use-unholy-autofocus';
15
14
  import { LocalMedia } from './LocalMedia';
16
15
  import { MediaFromURL } from './MediaFromURL';
17
- import { MediaFromURLWithForm } from './MediaFromURLWithForm';
18
16
  import { MediaInsertWrapper } from './MediaInsertWrapper';
19
17
  var PopupWithListeners = withOuterListeners(Popup);
20
18
 
@@ -144,19 +142,7 @@ export var MediaInsertPicker = function MediaInsertPicker(_ref2) {
144
142
  },
145
143
  dispatchAnalyticsEvent: dispatchAnalyticsEvent,
146
144
  insertFile: insertFile
147
- })), /*#__PURE__*/React.createElement(CustomTabPanel, null, fg('platform_editor_media_from_url_remove_form') ? /*#__PURE__*/React.createElement(MediaFromURL, {
148
- mediaProvider: mediaProvider,
149
- dispatchAnalyticsEvent: dispatchAnalyticsEvent,
150
- closeMediaInsertPicker: function closeMediaInsertPicker() {
151
- _closeMediaInsertPicker();
152
- focusEditor();
153
- },
154
- insertMediaSingle: insertMediaSingle,
155
- insertExternalMediaSingle: insertExternalMediaSingle,
156
- isOnlyExternalLinks: isOnlyExternalLinks,
157
- customizedUrlValidation: customizedUrlValidation,
158
- customizedHelperMessage: customizedHelperMessage
159
- }) : /*#__PURE__*/React.createElement(MediaFromURLWithForm, {
145
+ })), /*#__PURE__*/React.createElement(CustomTabPanel, null, /*#__PURE__*/React.createElement(MediaFromURL, {
160
146
  mediaProvider: mediaProvider,
161
147
  dispatchAnalyticsEvent: dispatchAnalyticsEvent,
162
148
  closeMediaInsertPicker: function closeMediaInsertPicker() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-media-insert",
3
- "version": "9.2.0",
3
+ "version": "9.2.2",
4
4
  "description": "Media Insert plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -25,12 +25,12 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "@atlaskit/adf-schema": "^50.2.0",
28
- "@atlaskit/button": "^23.3.0",
28
+ "@atlaskit/button": "^23.4.0",
29
29
  "@atlaskit/editor-plugin-analytics": "^3.0.0",
30
30
  "@atlaskit/editor-plugin-media": "^5.2.0",
31
31
  "@atlaskit/editor-prosemirror": "7.0.0",
32
32
  "@atlaskit/editor-shared-styles": "^3.6.0",
33
- "@atlaskit/form": "^12.0.0",
33
+ "@atlaskit/form": "^12.1.0",
34
34
  "@atlaskit/icon": "^27.12.0",
35
35
  "@atlaskit/media-card": "^79.5.0",
36
36
  "@atlaskit/media-client": "^35.3.0",
@@ -41,12 +41,12 @@
41
41
  "@atlaskit/section-message": "^8.5.0",
42
42
  "@atlaskit/tabs": "^18.1.0",
43
43
  "@atlaskit/textfield": "^8.0.0",
44
- "@atlaskit/tmp-editor-statsig": "^9.28.0",
44
+ "@atlaskit/tmp-editor-statsig": "^11.0.0",
45
45
  "@babel/runtime": "^7.0.0",
46
46
  "react-intl-next": "npm:react-intl@^5.18.1"
47
47
  },
48
48
  "peerDependencies": {
49
- "@atlaskit/editor-common": "^107.23.0",
49
+ "@atlaskit/editor-common": "^107.25.0",
50
50
  "@atlaskit/tokens": "^6.0.0",
51
51
  "react": "^18.2.0",
52
52
  "react-dom": "^18.2.0"
@@ -91,10 +91,5 @@
91
91
  "no-unused-dependencies": {
92
92
  "checkDevDependencies": true
93
93
  }
94
- },
95
- "platform-feature-flags": {
96
- "platform_editor_media_from_url_remove_form": {
97
- "type": "boolean"
98
- }
99
94
  }
100
95
  }
@@ -1,387 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- var _typeof = require("@babel/runtime/helpers/typeof");
5
- Object.defineProperty(exports, "__esModule", {
6
- value: true
7
- });
8
- exports.MediaFromURLWithForm = MediaFromURLWithForm;
9
- exports.isValidUrl = void 0;
10
- var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
- var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
12
- var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
13
- var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
14
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
15
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
16
- var _react = _interopRequireWildcard(require("react"));
17
- var _reactIntlNext = require("react-intl-next");
18
- var _adfSchema = require("@atlaskit/adf-schema");
19
- var _buttonGroup = _interopRequireDefault(require("@atlaskit/button/button-group"));
20
- var _new = _interopRequireDefault(require("@atlaskit/button/new"));
21
- var _analytics = require("@atlaskit/editor-common/analytics");
22
- var _messages = require("@atlaskit/editor-common/messages");
23
- var _form = _interopRequireWildcard(require("@atlaskit/form"));
24
- var _growDiagonal = _interopRequireDefault(require("@atlaskit/icon/core/grow-diagonal"));
25
- var _filePreview = _interopRequireDefault(require("@atlaskit/icon/glyph/editor/file-preview"));
26
- var _mediaClientReact = require("@atlaskit/media-client-react");
27
- var _primitives = require("@atlaskit/primitives");
28
- var _sectionMessage = _interopRequireDefault(require("@atlaskit/section-message"));
29
- var _textfield = _interopRequireDefault(require("@atlaskit/textfield"));
30
- var _MediaCard = require("./MediaCard");
31
- var _useAnalyticsEvents2 = require("./useAnalyticsEvents");
32
- var _excluded = ["value", "onChange"];
33
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
34
- 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; }
35
- 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; } // eslint-disable-next-line @atlaskit/design-system/no-emotion-primitives -- to be migrated to @atlaskit/primitives/compiled – go/akcss
36
- var PreviewBoxStyles = (0, _primitives.xcss)({
37
- borderWidth: 'border.width',
38
- borderStyle: 'dashed',
39
- borderColor: 'color.border',
40
- borderRadius: 'border.radius',
41
- height: '200px'
42
- });
43
- var PreviewImageStyles = (0, _primitives.xcss)({
44
- height: '200px'
45
- });
46
- var FormStyles = (0, _primitives.xcss)({
47
- flexGrow: 1
48
- });
49
- var INITIAL_PREVIEW_STATE = Object.freeze({
50
- isLoading: false,
51
- error: null,
52
- warning: null,
53
- previewInfo: null
54
- });
55
- var MAX_URL_LENGTH = 2048;
56
- var isValidInput = function isValidInput(value, customizedUrlValidation) {
57
- if (customizedUrlValidation) {
58
- return customizedUrlValidation(value);
59
- }
60
- return isValidUrl(value);
61
- };
62
- var isValidUrl = exports.isValidUrl = function isValidUrl(value) {
63
- try {
64
- // Check for spaces and length first to avoid the expensive URL parsing
65
- // Ignored via go/ees005
66
- // eslint-disable-next-line require-unicode-regexp
67
- if (/\s/.test(value) || value.length > MAX_URL_LENGTH) {
68
- return false;
69
- }
70
- new URL(value);
71
- } catch (e) {
72
- return false;
73
- }
74
- return (0, _adfSchema.isSafeUrl)(value);
75
- };
76
- var previewStateReducer = function previewStateReducer(state, action) {
77
- switch (action.type) {
78
- case 'loading':
79
- return _objectSpread(_objectSpread({}, INITIAL_PREVIEW_STATE), {}, {
80
- isLoading: true
81
- });
82
- case 'error':
83
- return _objectSpread(_objectSpread({}, INITIAL_PREVIEW_STATE), {}, {
84
- error: action.error
85
- });
86
- case 'warning':
87
- return _objectSpread(_objectSpread({}, INITIAL_PREVIEW_STATE), {}, {
88
- warning: action.warning
89
- });
90
- case 'success':
91
- return _objectSpread(_objectSpread({}, INITIAL_PREVIEW_STATE), {}, {
92
- previewInfo: action.payload
93
- });
94
- case 'reset':
95
- return INITIAL_PREVIEW_STATE;
96
- default:
97
- return state;
98
- }
99
- };
100
- function MediaFromURLWithForm(_ref) {
101
- var mediaProvider = _ref.mediaProvider,
102
- dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent,
103
- closeMediaInsertPicker = _ref.closeMediaInsertPicker,
104
- insertMediaSingle = _ref.insertMediaSingle,
105
- insertExternalMediaSingle = _ref.insertExternalMediaSingle,
106
- isOnlyExternalLinks = _ref.isOnlyExternalLinks,
107
- customizedUrlValidation = _ref.customizedUrlValidation,
108
- customizedHelperMessage = _ref.customizedHelperMessage;
109
- var intl = (0, _reactIntlNext.useIntl)();
110
- var strings = {
111
- loadPreview: intl.formatMessage(_messages.mediaInsertMessages.loadPreview),
112
- insert: intl.formatMessage(_messages.mediaInsertMessages.insert),
113
- pasteLinkToUpload: intl.formatMessage(_messages.mediaInsertMessages.pasteLinkToUpload),
114
- cancel: intl.formatMessage(_messages.mediaInsertMessages.cancel),
115
- errorMessage: intl.formatMessage(_messages.mediaInsertMessages.fromUrlErrorMessage),
116
- warning: intl.formatMessage(_messages.mediaInsertMessages.fromUrlWarning),
117
- invalidUrl: intl.formatMessage(_messages.mediaInsertMessages.invalidUrlErrorMessage)
118
- };
119
- var _React$useReducer = _react.default.useReducer(previewStateReducer, INITIAL_PREVIEW_STATE),
120
- _React$useReducer2 = (0, _slicedToArray2.default)(_React$useReducer, 2),
121
- previewState = _React$useReducer2[0],
122
- dispatch = _React$useReducer2[1];
123
- var _React$useState = _react.default.useState(''),
124
- _React$useState2 = (0, _slicedToArray2.default)(_React$useState, 2),
125
- input = _React$useState2[0],
126
- setInput = _React$useState2[1];
127
- var pasteFlag = _react.default.useRef(false);
128
- var _useAnalyticsEvents = (0, _useAnalyticsEvents2.useAnalyticsEvents)(dispatchAnalyticsEvent),
129
- onUploadButtonClickedAnalytics = _useAnalyticsEvents.onUploadButtonClickedAnalytics,
130
- onUploadCommencedAnalytics = _useAnalyticsEvents.onUploadCommencedAnalytics,
131
- onUploadSuccessAnalytics = _useAnalyticsEvents.onUploadSuccessAnalytics,
132
- onUploadFailureAnalytics = _useAnalyticsEvents.onUploadFailureAnalytics;
133
- var uploadExternalMedia = _react.default.useCallback( /*#__PURE__*/function () {
134
- var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(url) {
135
- var uploadMediaClientConfig, uploadParams, mediaClient, collection, _yield$mediaClient$fi, uploadableFileUpfrontIds, dimensions, mimeType, message;
136
- return _regenerator.default.wrap(function _callee$(_context) {
137
- while (1) switch (_context.prev = _context.next) {
138
- case 0:
139
- onUploadButtonClickedAnalytics();
140
- dispatch({
141
- type: 'loading'
142
- });
143
- uploadMediaClientConfig = mediaProvider.uploadMediaClientConfig, uploadParams = mediaProvider.uploadParams;
144
- if (uploadMediaClientConfig) {
145
- _context.next = 5;
146
- break;
147
- }
148
- return _context.abrupt("return");
149
- case 5:
150
- mediaClient = (0, _mediaClientReact.getMediaClient)(uploadMediaClientConfig);
151
- collection = uploadParams === null || uploadParams === void 0 ? void 0 : uploadParams.collection;
152
- onUploadCommencedAnalytics('url');
153
- _context.prev = 8;
154
- _context.next = 11;
155
- return mediaClient.file.uploadExternal(url, collection);
156
- case 11:
157
- _yield$mediaClient$fi = _context.sent;
158
- uploadableFileUpfrontIds = _yield$mediaClient$fi.uploadableFileUpfrontIds;
159
- dimensions = _yield$mediaClient$fi.dimensions;
160
- mimeType = _yield$mediaClient$fi.mimeType;
161
- onUploadSuccessAnalytics('url');
162
- dispatch({
163
- type: 'success',
164
- payload: {
165
- id: uploadableFileUpfrontIds.id,
166
- collection: collection,
167
- dimensions: dimensions,
168
- occurrenceKey: uploadableFileUpfrontIds.occurrenceKey,
169
- fileMimeType: mimeType
170
- }
171
- });
172
- _context.next = 22;
173
- break;
174
- case 19:
175
- _context.prev = 19;
176
- _context.t0 = _context["catch"](8);
177
- if (typeof _context.t0 === 'string' && _context.t0 === 'Could not download remote file') {
178
- // TODO: ED-26962 - Make sure this gets good unit test coverage with the actual media plugin.
179
- // This hard coded error message could be changed at any
180
- // point and we need a unit test to break to stop people changing it.
181
- onUploadFailureAnalytics(_context.t0, 'url');
182
- dispatch({
183
- type: 'warning',
184
- warning: _context.t0,
185
- url: url
186
- });
187
- } else if (_context.t0 instanceof Error) {
188
- message = 'Image preview fetch failed';
189
- onUploadFailureAnalytics(message, 'url');
190
- dispatch({
191
- type: 'error',
192
- error: message
193
- });
194
- } else {
195
- onUploadFailureAnalytics('Unknown error', 'url');
196
- dispatch({
197
- type: 'error',
198
- error: 'Unknown error'
199
- });
200
- }
201
- case 22:
202
- case "end":
203
- return _context.stop();
204
- }
205
- }, _callee, null, [[8, 19]]);
206
- }));
207
- return function (_x) {
208
- return _ref2.apply(this, arguments);
209
- };
210
- }(), [onUploadButtonClickedAnalytics, mediaProvider, onUploadCommencedAnalytics, onUploadSuccessAnalytics, onUploadFailureAnalytics]);
211
- var onURLChange = _react.default.useCallback(function (e) {
212
- var url = e.currentTarget.value;
213
- dispatch({
214
- type: 'reset'
215
- });
216
- setInput(url);
217
- if (!isValidInput(url, customizedUrlValidation)) {
218
- return;
219
- }
220
- if (pasteFlag.current) {
221
- pasteFlag.current = false;
222
- if (!isOnlyExternalLinks) {
223
- uploadExternalMedia(url);
224
- }
225
- }
226
- }, [uploadExternalMedia, isOnlyExternalLinks, customizedUrlValidation]);
227
- var _onPaste = _react.default.useCallback(function (e, inputUrl) {
228
- // Note: this is a little weird, but the paste event will always be
229
- // fired before the change event when pasting. We don't really want to
230
- // duplicate logic by handling pastes separately to changes, so we're
231
- // just noting paste occurred to then be handled in the onURLChange fn
232
- // above. The one exception to this is where paste inputs exactly what was
233
- // already in the input, in which case we want to ignore it.
234
- if (e.clipboardData.getData('text') !== inputUrl) {
235
- pasteFlag.current = true;
236
- }
237
- }, []);
238
- var onInsert = _react.default.useCallback(function () {
239
- if (previewState.previewInfo) {
240
- insertMediaSingle({
241
- mediaState: previewState.previewInfo,
242
- inputMethod: _analytics.INPUT_METHOD.MEDIA_PICKER
243
- });
244
- }
245
- closeMediaInsertPicker();
246
- }, [closeMediaInsertPicker, insertMediaSingle, previewState.previewInfo]);
247
- var onExternalInsert = _react.default.useCallback(function (url) {
248
- if (previewState.warning || isOnlyExternalLinks) {
249
- insertExternalMediaSingle({
250
- url: url,
251
- alt: '',
252
- inputMethod: _analytics.INPUT_METHOD.MEDIA_PICKER
253
- });
254
- }
255
- closeMediaInsertPicker();
256
- }, [closeMediaInsertPicker, insertExternalMediaSingle, previewState.warning, isOnlyExternalLinks]);
257
- var onInputKeyPress = _react.default.useCallback(function (event) {
258
- if (event && event.key === 'Esc') {
259
- if (dispatchAnalyticsEvent) {
260
- var payload = {
261
- action: _analytics.ACTION.CLOSED,
262
- actionSubject: _analytics.ACTION_SUBJECT.PICKER,
263
- actionSubjectId: _analytics.ACTION_SUBJECT_ID.PICKER_MEDIA,
264
- eventType: _analytics.EVENT_TYPE.UI,
265
- attributes: {
266
- exitMethod: _analytics.INPUT_METHOD.KEYBOARD
267
- }
268
- };
269
- dispatchAnalyticsEvent(payload);
270
- }
271
- closeMediaInsertPicker();
272
- }
273
- }, [dispatchAnalyticsEvent, closeMediaInsertPicker]);
274
- var onCancel = _react.default.useCallback(function () {
275
- if (dispatchAnalyticsEvent) {
276
- var payload = {
277
- action: _analytics.ACTION.CANCELLED,
278
- actionSubject: _analytics.ACTION_SUBJECT.PICKER,
279
- actionSubjectId: _analytics.ACTION_SUBJECT_ID.PICKER_MEDIA,
280
- eventType: _analytics.EVENT_TYPE.UI
281
- };
282
- dispatchAnalyticsEvent(payload);
283
- }
284
- closeMediaInsertPicker();
285
- }, [closeMediaInsertPicker, dispatchAnalyticsEvent]);
286
- return /*#__PURE__*/_react.default.createElement(_form.default, {
287
- onSubmit: function onSubmit(_ref3, form) {
288
- var inputUrl = _ref3.inputUrl;
289
- // This can be triggered from an enter key event on the input even when
290
- // the button is disabled, so we explicitly do nothing when in loading
291
- // state.
292
- if (previewState.isLoading || form.getState().invalid) {
293
- return;
294
- }
295
- if (previewState.previewInfo) {
296
- return onInsert();
297
- }
298
- if (previewState.warning) {
299
- return onExternalInsert(inputUrl);
300
- }
301
- return uploadExternalMedia(inputUrl);
302
- }
303
- }, function (_ref4) {
304
- var formProps = _ref4.formProps;
305
- return (
306
- /*#__PURE__*/
307
- // Ignored via go/ees005
308
- // eslint-disable-next-line react/jsx-props-no-spreading
309
- _react.default.createElement(_primitives.Box, (0, _extends2.default)({
310
- as: "form"
311
- }, formProps, {
312
- xcss: FormStyles
313
- }), /*#__PURE__*/_react.default.createElement(_primitives.Stack, {
314
- space: "space.150",
315
- grow: "fill"
316
- }, /*#__PURE__*/_react.default.createElement(_form.Field, {
317
- "aria-required": true,
318
- isRequired: true,
319
- name: "inputUrl",
320
- validate: function validate(value) {
321
- return value && isValidInput(value, customizedUrlValidation) ? undefined : strings.invalidUrl;
322
- }
323
- }, function (_ref5) {
324
- var _ref5$fieldProps = _ref5.fieldProps,
325
- value = _ref5$fieldProps.value,
326
- _onChange = _ref5$fieldProps.onChange,
327
- rest = (0, _objectWithoutProperties2.default)(_ref5$fieldProps, _excluded),
328
- error = _ref5.error,
329
- meta = _ref5.meta;
330
- return /*#__PURE__*/_react.default.createElement(_primitives.Stack, {
331
- space: "space.150",
332
- grow: "fill"
333
- }, /*#__PURE__*/_react.default.createElement(_primitives.Box, null, /*#__PURE__*/_react.default.createElement(_textfield.default
334
- // Ignored via go/ees005
335
- // eslint-disable-next-line react/jsx-props-no-spreading
336
- , (0, _extends2.default)({}, rest, {
337
- value: value,
338
- placeholder: strings.pasteLinkToUpload,
339
- maxLength: MAX_URL_LENGTH,
340
- onKeyPress: onInputKeyPress,
341
- onPaste: function onPaste(event) {
342
- return _onPaste(event, value);
343
- },
344
- onChange: function onChange(value) {
345
- onURLChange(value);
346
- _onChange(value);
347
- }
348
- })), customizedHelperMessage && /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(_form.HelperMessage, null, customizedHelperMessage)), /*#__PURE__*/_react.default.createElement(_form.MessageWrapper, null, error && /*#__PURE__*/_react.default.createElement(_form.ErrorMessage, null, /*#__PURE__*/_react.default.createElement(_primitives.Box, {
349
- as: "span"
350
- }, error)))), !previewState.previewInfo && !previewState.error && !previewState.warning && !isOnlyExternalLinks && /*#__PURE__*/_react.default.createElement(_primitives.Flex, {
351
- xcss: PreviewBoxStyles,
352
- alignItems: "center",
353
- justifyContent: "center"
354
- }, /*#__PURE__*/_react.default.createElement(_new.default, {
355
- type: "submit",
356
- isLoading: previewState.isLoading,
357
- isDisabled: !!error || !meta.dirty,
358
- iconBefore: function iconBefore() {
359
- return /*#__PURE__*/_react.default.createElement(_growDiagonal.default, {
360
- label: "",
361
- LEGACY_fallbackIcon: _filePreview.default
362
- });
363
- }
364
- }, strings.loadPreview)));
365
- }), previewState.previewInfo && /*#__PURE__*/_react.default.createElement(_primitives.Inline, {
366
- alignInline: "center",
367
- alignBlock: "center",
368
- xcss: PreviewImageStyles,
369
- space: "space.200"
370
- }, /*#__PURE__*/_react.default.createElement(_MediaCard.MediaCard, {
371
- attrs: previewState.previewInfo,
372
- mediaProvider: mediaProvider
373
- })), /*#__PURE__*/_react.default.createElement(_form.MessageWrapper, null, previewState.error && /*#__PURE__*/_react.default.createElement(_sectionMessage.default, {
374
- appearance: "error"
375
- }, strings.errorMessage), previewState.warning && /*#__PURE__*/_react.default.createElement(_sectionMessage.default, {
376
- appearance: "warning"
377
- }, strings.warning)), /*#__PURE__*/_react.default.createElement(_form.FormFooter, null, /*#__PURE__*/_react.default.createElement(_buttonGroup.default, null, /*#__PURE__*/_react.default.createElement(_new.default, {
378
- appearance: "subtle",
379
- onClick: onCancel
380
- }, strings.cancel), /*#__PURE__*/_react.default.createElement(_new.default, {
381
- type: "submit",
382
- appearance: "primary",
383
- isDisabled: isOnlyExternalLinks ? !input || !isValidInput(input, customizedUrlValidation) : !previewState.previewInfo && !previewState.warning
384
- }, strings.insert)))))
385
- );
386
- });
387
- }
@@ -1,344 +0,0 @@
1
- import _extends from "@babel/runtime/helpers/extends";
2
- import React, { Fragment } from 'react';
3
- import { useIntl } from 'react-intl-next';
4
- import { isSafeUrl } from '@atlaskit/adf-schema';
5
- import ButtonGroup from '@atlaskit/button/button-group';
6
- import Button from '@atlaskit/button/new';
7
- import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
8
- import { mediaInsertMessages } from '@atlaskit/editor-common/messages';
9
- import Form, { ErrorMessage, Field, FormFooter, MessageWrapper, HelperMessage } from '@atlaskit/form';
10
- import ExpandIcon from '@atlaskit/icon/core/grow-diagonal';
11
- import { default as EditorFilePreviewIconLegacy } from '@atlaskit/icon/glyph/editor/file-preview';
12
- import { getMediaClient } from '@atlaskit/media-client-react';
13
- // eslint-disable-next-line @atlaskit/design-system/no-emotion-primitives -- to be migrated to @atlaskit/primitives/compiled – go/akcss
14
- import { Box, Flex, Inline, Stack, xcss } from '@atlaskit/primitives';
15
- import SectionMessage from '@atlaskit/section-message';
16
- import TextField from '@atlaskit/textfield';
17
- import { MediaCard } from './MediaCard';
18
- import { useAnalyticsEvents } from './useAnalyticsEvents';
19
- const PreviewBoxStyles = xcss({
20
- borderWidth: 'border.width',
21
- borderStyle: 'dashed',
22
- borderColor: 'color.border',
23
- borderRadius: 'border.radius',
24
- height: '200px'
25
- });
26
- const PreviewImageStyles = xcss({
27
- height: '200px'
28
- });
29
- const FormStyles = xcss({
30
- flexGrow: 1
31
- });
32
- const INITIAL_PREVIEW_STATE = Object.freeze({
33
- isLoading: false,
34
- error: null,
35
- warning: null,
36
- previewInfo: null
37
- });
38
- const MAX_URL_LENGTH = 2048;
39
- const isValidInput = (value, customizedUrlValidation) => {
40
- if (customizedUrlValidation) {
41
- return customizedUrlValidation(value);
42
- }
43
- return isValidUrl(value);
44
- };
45
- export const isValidUrl = value => {
46
- try {
47
- // Check for spaces and length first to avoid the expensive URL parsing
48
- // Ignored via go/ees005
49
- // eslint-disable-next-line require-unicode-regexp
50
- if (/\s/.test(value) || value.length > MAX_URL_LENGTH) {
51
- return false;
52
- }
53
- new URL(value);
54
- } catch (e) {
55
- return false;
56
- }
57
- return isSafeUrl(value);
58
- };
59
- const previewStateReducer = (state, action) => {
60
- switch (action.type) {
61
- case 'loading':
62
- return {
63
- ...INITIAL_PREVIEW_STATE,
64
- isLoading: true
65
- };
66
- case 'error':
67
- return {
68
- ...INITIAL_PREVIEW_STATE,
69
- error: action.error
70
- };
71
- case 'warning':
72
- return {
73
- ...INITIAL_PREVIEW_STATE,
74
- warning: action.warning
75
- };
76
- case 'success':
77
- return {
78
- ...INITIAL_PREVIEW_STATE,
79
- previewInfo: action.payload
80
- };
81
- case 'reset':
82
- return INITIAL_PREVIEW_STATE;
83
- default:
84
- return state;
85
- }
86
- };
87
- export function MediaFromURLWithForm({
88
- mediaProvider,
89
- dispatchAnalyticsEvent,
90
- closeMediaInsertPicker,
91
- insertMediaSingle,
92
- insertExternalMediaSingle,
93
- isOnlyExternalLinks,
94
- customizedUrlValidation,
95
- customizedHelperMessage
96
- }) {
97
- const intl = useIntl();
98
- const strings = {
99
- loadPreview: intl.formatMessage(mediaInsertMessages.loadPreview),
100
- insert: intl.formatMessage(mediaInsertMessages.insert),
101
- pasteLinkToUpload: intl.formatMessage(mediaInsertMessages.pasteLinkToUpload),
102
- cancel: intl.formatMessage(mediaInsertMessages.cancel),
103
- errorMessage: intl.formatMessage(mediaInsertMessages.fromUrlErrorMessage),
104
- warning: intl.formatMessage(mediaInsertMessages.fromUrlWarning),
105
- invalidUrl: intl.formatMessage(mediaInsertMessages.invalidUrlErrorMessage)
106
- };
107
- const [previewState, dispatch] = React.useReducer(previewStateReducer, INITIAL_PREVIEW_STATE);
108
- const [input, setInput] = React.useState('');
109
- const pasteFlag = React.useRef(false);
110
- const {
111
- onUploadButtonClickedAnalytics,
112
- onUploadCommencedAnalytics,
113
- onUploadSuccessAnalytics,
114
- onUploadFailureAnalytics
115
- } = useAnalyticsEvents(dispatchAnalyticsEvent);
116
- const uploadExternalMedia = React.useCallback(async url => {
117
- onUploadButtonClickedAnalytics();
118
- dispatch({
119
- type: 'loading'
120
- });
121
- const {
122
- uploadMediaClientConfig,
123
- uploadParams
124
- } = mediaProvider;
125
- if (!uploadMediaClientConfig) {
126
- return;
127
- }
128
- const mediaClient = getMediaClient(uploadMediaClientConfig);
129
- const collection = uploadParams === null || uploadParams === void 0 ? void 0 : uploadParams.collection;
130
- onUploadCommencedAnalytics('url');
131
- try {
132
- const {
133
- uploadableFileUpfrontIds,
134
- dimensions,
135
- mimeType
136
- } = await mediaClient.file.uploadExternal(url, collection);
137
- onUploadSuccessAnalytics('url');
138
- dispatch({
139
- type: 'success',
140
- payload: {
141
- id: uploadableFileUpfrontIds.id,
142
- collection,
143
- dimensions,
144
- occurrenceKey: uploadableFileUpfrontIds.occurrenceKey,
145
- fileMimeType: mimeType
146
- }
147
- });
148
- } catch (e) {
149
- if (typeof e === 'string' && e === 'Could not download remote file') {
150
- // TODO: ED-26962 - Make sure this gets good unit test coverage with the actual media plugin.
151
- // This hard coded error message could be changed at any
152
- // point and we need a unit test to break to stop people changing it.
153
- onUploadFailureAnalytics(e, 'url');
154
- dispatch({
155
- type: 'warning',
156
- warning: e,
157
- url
158
- });
159
- } else if (e instanceof Error) {
160
- const message = 'Image preview fetch failed';
161
- onUploadFailureAnalytics(message, 'url');
162
- dispatch({
163
- type: 'error',
164
- error: message
165
- });
166
- } else {
167
- onUploadFailureAnalytics('Unknown error', 'url');
168
- dispatch({
169
- type: 'error',
170
- error: 'Unknown error'
171
- });
172
- }
173
- }
174
- }, [onUploadButtonClickedAnalytics, mediaProvider, onUploadCommencedAnalytics, onUploadSuccessAnalytics, onUploadFailureAnalytics]);
175
- const onURLChange = React.useCallback(e => {
176
- const url = e.currentTarget.value;
177
- dispatch({
178
- type: 'reset'
179
- });
180
- setInput(url);
181
- if (!isValidInput(url, customizedUrlValidation)) {
182
- return;
183
- }
184
- if (pasteFlag.current) {
185
- pasteFlag.current = false;
186
- if (!isOnlyExternalLinks) {
187
- uploadExternalMedia(url);
188
- }
189
- }
190
- }, [uploadExternalMedia, isOnlyExternalLinks, customizedUrlValidation]);
191
- const onPaste = React.useCallback((e, inputUrl) => {
192
- // Note: this is a little weird, but the paste event will always be
193
- // fired before the change event when pasting. We don't really want to
194
- // duplicate logic by handling pastes separately to changes, so we're
195
- // just noting paste occurred to then be handled in the onURLChange fn
196
- // above. The one exception to this is where paste inputs exactly what was
197
- // already in the input, in which case we want to ignore it.
198
- if (e.clipboardData.getData('text') !== inputUrl) {
199
- pasteFlag.current = true;
200
- }
201
- }, []);
202
- const onInsert = React.useCallback(() => {
203
- if (previewState.previewInfo) {
204
- insertMediaSingle({
205
- mediaState: previewState.previewInfo,
206
- inputMethod: INPUT_METHOD.MEDIA_PICKER
207
- });
208
- }
209
- closeMediaInsertPicker();
210
- }, [closeMediaInsertPicker, insertMediaSingle, previewState.previewInfo]);
211
- const onExternalInsert = React.useCallback(url => {
212
- if (previewState.warning || isOnlyExternalLinks) {
213
- insertExternalMediaSingle({
214
- url,
215
- alt: '',
216
- inputMethod: INPUT_METHOD.MEDIA_PICKER
217
- });
218
- }
219
- closeMediaInsertPicker();
220
- }, [closeMediaInsertPicker, insertExternalMediaSingle, previewState.warning, isOnlyExternalLinks]);
221
- const onInputKeyPress = React.useCallback(event => {
222
- if (event && event.key === 'Esc') {
223
- if (dispatchAnalyticsEvent) {
224
- const payload = {
225
- action: ACTION.CLOSED,
226
- actionSubject: ACTION_SUBJECT.PICKER,
227
- actionSubjectId: ACTION_SUBJECT_ID.PICKER_MEDIA,
228
- eventType: EVENT_TYPE.UI,
229
- attributes: {
230
- exitMethod: INPUT_METHOD.KEYBOARD
231
- }
232
- };
233
- dispatchAnalyticsEvent(payload);
234
- }
235
- closeMediaInsertPicker();
236
- }
237
- }, [dispatchAnalyticsEvent, closeMediaInsertPicker]);
238
- const onCancel = React.useCallback(() => {
239
- if (dispatchAnalyticsEvent) {
240
- const payload = {
241
- action: ACTION.CANCELLED,
242
- actionSubject: ACTION_SUBJECT.PICKER,
243
- actionSubjectId: ACTION_SUBJECT_ID.PICKER_MEDIA,
244
- eventType: EVENT_TYPE.UI
245
- };
246
- dispatchAnalyticsEvent(payload);
247
- }
248
- closeMediaInsertPicker();
249
- }, [closeMediaInsertPicker, dispatchAnalyticsEvent]);
250
- return /*#__PURE__*/React.createElement(Form, {
251
- onSubmit: ({
252
- inputUrl
253
- }, form) => {
254
- // This can be triggered from an enter key event on the input even when
255
- // the button is disabled, so we explicitly do nothing when in loading
256
- // state.
257
- if (previewState.isLoading || form.getState().invalid) {
258
- return;
259
- }
260
- if (previewState.previewInfo) {
261
- return onInsert();
262
- }
263
- if (previewState.warning) {
264
- return onExternalInsert(inputUrl);
265
- }
266
- return uploadExternalMedia(inputUrl);
267
- }
268
- }, ({
269
- formProps
270
- }) =>
271
- /*#__PURE__*/
272
- // Ignored via go/ees005
273
- // eslint-disable-next-line react/jsx-props-no-spreading
274
- React.createElement(Box, _extends({
275
- as: "form"
276
- }, formProps, {
277
- xcss: FormStyles
278
- }), /*#__PURE__*/React.createElement(Stack, {
279
- space: "space.150",
280
- grow: "fill"
281
- }, /*#__PURE__*/React.createElement(Field, {
282
- "aria-required": true,
283
- isRequired: true,
284
- name: "inputUrl",
285
- validate: value => value && isValidInput(value, customizedUrlValidation) ? undefined : strings.invalidUrl
286
- }, ({
287
- fieldProps: {
288
- value,
289
- onChange,
290
- ...rest
291
- },
292
- error,
293
- meta
294
- }) => /*#__PURE__*/React.createElement(Stack, {
295
- space: "space.150",
296
- grow: "fill"
297
- }, /*#__PURE__*/React.createElement(Box, null, /*#__PURE__*/React.createElement(TextField
298
- // Ignored via go/ees005
299
- // eslint-disable-next-line react/jsx-props-no-spreading
300
- , _extends({}, rest, {
301
- value: value,
302
- placeholder: strings.pasteLinkToUpload,
303
- maxLength: MAX_URL_LENGTH,
304
- onKeyPress: onInputKeyPress,
305
- onPaste: event => onPaste(event, value),
306
- onChange: value => {
307
- onURLChange(value);
308
- onChange(value);
309
- }
310
- })), customizedHelperMessage && /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(HelperMessage, null, customizedHelperMessage)), /*#__PURE__*/React.createElement(MessageWrapper, null, error && /*#__PURE__*/React.createElement(ErrorMessage, null, /*#__PURE__*/React.createElement(Box, {
311
- as: "span"
312
- }, error)))), !previewState.previewInfo && !previewState.error && !previewState.warning && !isOnlyExternalLinks && /*#__PURE__*/React.createElement(Flex, {
313
- xcss: PreviewBoxStyles,
314
- alignItems: "center",
315
- justifyContent: "center"
316
- }, /*#__PURE__*/React.createElement(Button, {
317
- type: "submit",
318
- isLoading: previewState.isLoading,
319
- isDisabled: !!error || !meta.dirty,
320
- iconBefore: () => /*#__PURE__*/React.createElement(ExpandIcon, {
321
- label: "",
322
- LEGACY_fallbackIcon: EditorFilePreviewIconLegacy
323
- })
324
- }, strings.loadPreview)))), previewState.previewInfo && /*#__PURE__*/React.createElement(Inline, {
325
- alignInline: "center",
326
- alignBlock: "center",
327
- xcss: PreviewImageStyles,
328
- space: "space.200"
329
- }, /*#__PURE__*/React.createElement(MediaCard, {
330
- attrs: previewState.previewInfo,
331
- mediaProvider: mediaProvider
332
- })), /*#__PURE__*/React.createElement(MessageWrapper, null, previewState.error && /*#__PURE__*/React.createElement(SectionMessage, {
333
- appearance: "error"
334
- }, strings.errorMessage), previewState.warning && /*#__PURE__*/React.createElement(SectionMessage, {
335
- appearance: "warning"
336
- }, strings.warning)), /*#__PURE__*/React.createElement(FormFooter, null, /*#__PURE__*/React.createElement(ButtonGroup, null, /*#__PURE__*/React.createElement(Button, {
337
- appearance: "subtle",
338
- onClick: onCancel
339
- }, strings.cancel), /*#__PURE__*/React.createElement(Button, {
340
- type: "submit",
341
- appearance: "primary",
342
- isDisabled: isOnlyExternalLinks ? !input || !isValidInput(input, customizedUrlValidation) : !previewState.previewInfo && !previewState.warning
343
- }, strings.insert))))));
344
- }
@@ -1,378 +0,0 @@
1
- import _extends from "@babel/runtime/helpers/extends";
2
- import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
- import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
4
- import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
5
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
6
- var _excluded = ["value", "onChange"];
7
- import _regeneratorRuntime from "@babel/runtime/regenerator";
8
- 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; }
9
- 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) { _defineProperty(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; }
10
- import React, { Fragment } from 'react';
11
- import { useIntl } from 'react-intl-next';
12
- import { isSafeUrl } from '@atlaskit/adf-schema';
13
- import ButtonGroup from '@atlaskit/button/button-group';
14
- import Button from '@atlaskit/button/new';
15
- import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
16
- import { mediaInsertMessages } from '@atlaskit/editor-common/messages';
17
- import Form, { ErrorMessage, Field, FormFooter, MessageWrapper, HelperMessage } from '@atlaskit/form';
18
- import ExpandIcon from '@atlaskit/icon/core/grow-diagonal';
19
- import { default as EditorFilePreviewIconLegacy } from '@atlaskit/icon/glyph/editor/file-preview';
20
- import { getMediaClient } from '@atlaskit/media-client-react';
21
- // eslint-disable-next-line @atlaskit/design-system/no-emotion-primitives -- to be migrated to @atlaskit/primitives/compiled – go/akcss
22
- import { Box, Flex, Inline, Stack, xcss } from '@atlaskit/primitives';
23
- import SectionMessage from '@atlaskit/section-message';
24
- import TextField from '@atlaskit/textfield';
25
- import { MediaCard } from './MediaCard';
26
- import { useAnalyticsEvents } from './useAnalyticsEvents';
27
- var PreviewBoxStyles = xcss({
28
- borderWidth: 'border.width',
29
- borderStyle: 'dashed',
30
- borderColor: 'color.border',
31
- borderRadius: 'border.radius',
32
- height: '200px'
33
- });
34
- var PreviewImageStyles = xcss({
35
- height: '200px'
36
- });
37
- var FormStyles = xcss({
38
- flexGrow: 1
39
- });
40
- var INITIAL_PREVIEW_STATE = Object.freeze({
41
- isLoading: false,
42
- error: null,
43
- warning: null,
44
- previewInfo: null
45
- });
46
- var MAX_URL_LENGTH = 2048;
47
- var isValidInput = function isValidInput(value, customizedUrlValidation) {
48
- if (customizedUrlValidation) {
49
- return customizedUrlValidation(value);
50
- }
51
- return isValidUrl(value);
52
- };
53
- export var isValidUrl = function isValidUrl(value) {
54
- try {
55
- // Check for spaces and length first to avoid the expensive URL parsing
56
- // Ignored via go/ees005
57
- // eslint-disable-next-line require-unicode-regexp
58
- if (/\s/.test(value) || value.length > MAX_URL_LENGTH) {
59
- return false;
60
- }
61
- new URL(value);
62
- } catch (e) {
63
- return false;
64
- }
65
- return isSafeUrl(value);
66
- };
67
- var previewStateReducer = function previewStateReducer(state, action) {
68
- switch (action.type) {
69
- case 'loading':
70
- return _objectSpread(_objectSpread({}, INITIAL_PREVIEW_STATE), {}, {
71
- isLoading: true
72
- });
73
- case 'error':
74
- return _objectSpread(_objectSpread({}, INITIAL_PREVIEW_STATE), {}, {
75
- error: action.error
76
- });
77
- case 'warning':
78
- return _objectSpread(_objectSpread({}, INITIAL_PREVIEW_STATE), {}, {
79
- warning: action.warning
80
- });
81
- case 'success':
82
- return _objectSpread(_objectSpread({}, INITIAL_PREVIEW_STATE), {}, {
83
- previewInfo: action.payload
84
- });
85
- case 'reset':
86
- return INITIAL_PREVIEW_STATE;
87
- default:
88
- return state;
89
- }
90
- };
91
- export function MediaFromURLWithForm(_ref) {
92
- var mediaProvider = _ref.mediaProvider,
93
- dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent,
94
- closeMediaInsertPicker = _ref.closeMediaInsertPicker,
95
- insertMediaSingle = _ref.insertMediaSingle,
96
- insertExternalMediaSingle = _ref.insertExternalMediaSingle,
97
- isOnlyExternalLinks = _ref.isOnlyExternalLinks,
98
- customizedUrlValidation = _ref.customizedUrlValidation,
99
- customizedHelperMessage = _ref.customizedHelperMessage;
100
- var intl = useIntl();
101
- var strings = {
102
- loadPreview: intl.formatMessage(mediaInsertMessages.loadPreview),
103
- insert: intl.formatMessage(mediaInsertMessages.insert),
104
- pasteLinkToUpload: intl.formatMessage(mediaInsertMessages.pasteLinkToUpload),
105
- cancel: intl.formatMessage(mediaInsertMessages.cancel),
106
- errorMessage: intl.formatMessage(mediaInsertMessages.fromUrlErrorMessage),
107
- warning: intl.formatMessage(mediaInsertMessages.fromUrlWarning),
108
- invalidUrl: intl.formatMessage(mediaInsertMessages.invalidUrlErrorMessage)
109
- };
110
- var _React$useReducer = React.useReducer(previewStateReducer, INITIAL_PREVIEW_STATE),
111
- _React$useReducer2 = _slicedToArray(_React$useReducer, 2),
112
- previewState = _React$useReducer2[0],
113
- dispatch = _React$useReducer2[1];
114
- var _React$useState = React.useState(''),
115
- _React$useState2 = _slicedToArray(_React$useState, 2),
116
- input = _React$useState2[0],
117
- setInput = _React$useState2[1];
118
- var pasteFlag = React.useRef(false);
119
- var _useAnalyticsEvents = useAnalyticsEvents(dispatchAnalyticsEvent),
120
- onUploadButtonClickedAnalytics = _useAnalyticsEvents.onUploadButtonClickedAnalytics,
121
- onUploadCommencedAnalytics = _useAnalyticsEvents.onUploadCommencedAnalytics,
122
- onUploadSuccessAnalytics = _useAnalyticsEvents.onUploadSuccessAnalytics,
123
- onUploadFailureAnalytics = _useAnalyticsEvents.onUploadFailureAnalytics;
124
- var uploadExternalMedia = React.useCallback( /*#__PURE__*/function () {
125
- var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(url) {
126
- var uploadMediaClientConfig, uploadParams, mediaClient, collection, _yield$mediaClient$fi, uploadableFileUpfrontIds, dimensions, mimeType, message;
127
- return _regeneratorRuntime.wrap(function _callee$(_context) {
128
- while (1) switch (_context.prev = _context.next) {
129
- case 0:
130
- onUploadButtonClickedAnalytics();
131
- dispatch({
132
- type: 'loading'
133
- });
134
- uploadMediaClientConfig = mediaProvider.uploadMediaClientConfig, uploadParams = mediaProvider.uploadParams;
135
- if (uploadMediaClientConfig) {
136
- _context.next = 5;
137
- break;
138
- }
139
- return _context.abrupt("return");
140
- case 5:
141
- mediaClient = getMediaClient(uploadMediaClientConfig);
142
- collection = uploadParams === null || uploadParams === void 0 ? void 0 : uploadParams.collection;
143
- onUploadCommencedAnalytics('url');
144
- _context.prev = 8;
145
- _context.next = 11;
146
- return mediaClient.file.uploadExternal(url, collection);
147
- case 11:
148
- _yield$mediaClient$fi = _context.sent;
149
- uploadableFileUpfrontIds = _yield$mediaClient$fi.uploadableFileUpfrontIds;
150
- dimensions = _yield$mediaClient$fi.dimensions;
151
- mimeType = _yield$mediaClient$fi.mimeType;
152
- onUploadSuccessAnalytics('url');
153
- dispatch({
154
- type: 'success',
155
- payload: {
156
- id: uploadableFileUpfrontIds.id,
157
- collection: collection,
158
- dimensions: dimensions,
159
- occurrenceKey: uploadableFileUpfrontIds.occurrenceKey,
160
- fileMimeType: mimeType
161
- }
162
- });
163
- _context.next = 22;
164
- break;
165
- case 19:
166
- _context.prev = 19;
167
- _context.t0 = _context["catch"](8);
168
- if (typeof _context.t0 === 'string' && _context.t0 === 'Could not download remote file') {
169
- // TODO: ED-26962 - Make sure this gets good unit test coverage with the actual media plugin.
170
- // This hard coded error message could be changed at any
171
- // point and we need a unit test to break to stop people changing it.
172
- onUploadFailureAnalytics(_context.t0, 'url');
173
- dispatch({
174
- type: 'warning',
175
- warning: _context.t0,
176
- url: url
177
- });
178
- } else if (_context.t0 instanceof Error) {
179
- message = 'Image preview fetch failed';
180
- onUploadFailureAnalytics(message, 'url');
181
- dispatch({
182
- type: 'error',
183
- error: message
184
- });
185
- } else {
186
- onUploadFailureAnalytics('Unknown error', 'url');
187
- dispatch({
188
- type: 'error',
189
- error: 'Unknown error'
190
- });
191
- }
192
- case 22:
193
- case "end":
194
- return _context.stop();
195
- }
196
- }, _callee, null, [[8, 19]]);
197
- }));
198
- return function (_x) {
199
- return _ref2.apply(this, arguments);
200
- };
201
- }(), [onUploadButtonClickedAnalytics, mediaProvider, onUploadCommencedAnalytics, onUploadSuccessAnalytics, onUploadFailureAnalytics]);
202
- var onURLChange = React.useCallback(function (e) {
203
- var url = e.currentTarget.value;
204
- dispatch({
205
- type: 'reset'
206
- });
207
- setInput(url);
208
- if (!isValidInput(url, customizedUrlValidation)) {
209
- return;
210
- }
211
- if (pasteFlag.current) {
212
- pasteFlag.current = false;
213
- if (!isOnlyExternalLinks) {
214
- uploadExternalMedia(url);
215
- }
216
- }
217
- }, [uploadExternalMedia, isOnlyExternalLinks, customizedUrlValidation]);
218
- var _onPaste = React.useCallback(function (e, inputUrl) {
219
- // Note: this is a little weird, but the paste event will always be
220
- // fired before the change event when pasting. We don't really want to
221
- // duplicate logic by handling pastes separately to changes, so we're
222
- // just noting paste occurred to then be handled in the onURLChange fn
223
- // above. The one exception to this is where paste inputs exactly what was
224
- // already in the input, in which case we want to ignore it.
225
- if (e.clipboardData.getData('text') !== inputUrl) {
226
- pasteFlag.current = true;
227
- }
228
- }, []);
229
- var onInsert = React.useCallback(function () {
230
- if (previewState.previewInfo) {
231
- insertMediaSingle({
232
- mediaState: previewState.previewInfo,
233
- inputMethod: INPUT_METHOD.MEDIA_PICKER
234
- });
235
- }
236
- closeMediaInsertPicker();
237
- }, [closeMediaInsertPicker, insertMediaSingle, previewState.previewInfo]);
238
- var onExternalInsert = React.useCallback(function (url) {
239
- if (previewState.warning || isOnlyExternalLinks) {
240
- insertExternalMediaSingle({
241
- url: url,
242
- alt: '',
243
- inputMethod: INPUT_METHOD.MEDIA_PICKER
244
- });
245
- }
246
- closeMediaInsertPicker();
247
- }, [closeMediaInsertPicker, insertExternalMediaSingle, previewState.warning, isOnlyExternalLinks]);
248
- var onInputKeyPress = React.useCallback(function (event) {
249
- if (event && event.key === 'Esc') {
250
- if (dispatchAnalyticsEvent) {
251
- var payload = {
252
- action: ACTION.CLOSED,
253
- actionSubject: ACTION_SUBJECT.PICKER,
254
- actionSubjectId: ACTION_SUBJECT_ID.PICKER_MEDIA,
255
- eventType: EVENT_TYPE.UI,
256
- attributes: {
257
- exitMethod: INPUT_METHOD.KEYBOARD
258
- }
259
- };
260
- dispatchAnalyticsEvent(payload);
261
- }
262
- closeMediaInsertPicker();
263
- }
264
- }, [dispatchAnalyticsEvent, closeMediaInsertPicker]);
265
- var onCancel = React.useCallback(function () {
266
- if (dispatchAnalyticsEvent) {
267
- var payload = {
268
- action: ACTION.CANCELLED,
269
- actionSubject: ACTION_SUBJECT.PICKER,
270
- actionSubjectId: ACTION_SUBJECT_ID.PICKER_MEDIA,
271
- eventType: EVENT_TYPE.UI
272
- };
273
- dispatchAnalyticsEvent(payload);
274
- }
275
- closeMediaInsertPicker();
276
- }, [closeMediaInsertPicker, dispatchAnalyticsEvent]);
277
- return /*#__PURE__*/React.createElement(Form, {
278
- onSubmit: function onSubmit(_ref3, form) {
279
- var inputUrl = _ref3.inputUrl;
280
- // This can be triggered from an enter key event on the input even when
281
- // the button is disabled, so we explicitly do nothing when in loading
282
- // state.
283
- if (previewState.isLoading || form.getState().invalid) {
284
- return;
285
- }
286
- if (previewState.previewInfo) {
287
- return onInsert();
288
- }
289
- if (previewState.warning) {
290
- return onExternalInsert(inputUrl);
291
- }
292
- return uploadExternalMedia(inputUrl);
293
- }
294
- }, function (_ref4) {
295
- var formProps = _ref4.formProps;
296
- return (
297
- /*#__PURE__*/
298
- // Ignored via go/ees005
299
- // eslint-disable-next-line react/jsx-props-no-spreading
300
- React.createElement(Box, _extends({
301
- as: "form"
302
- }, formProps, {
303
- xcss: FormStyles
304
- }), /*#__PURE__*/React.createElement(Stack, {
305
- space: "space.150",
306
- grow: "fill"
307
- }, /*#__PURE__*/React.createElement(Field, {
308
- "aria-required": true,
309
- isRequired: true,
310
- name: "inputUrl",
311
- validate: function validate(value) {
312
- return value && isValidInput(value, customizedUrlValidation) ? undefined : strings.invalidUrl;
313
- }
314
- }, function (_ref5) {
315
- var _ref5$fieldProps = _ref5.fieldProps,
316
- value = _ref5$fieldProps.value,
317
- _onChange = _ref5$fieldProps.onChange,
318
- rest = _objectWithoutProperties(_ref5$fieldProps, _excluded),
319
- error = _ref5.error,
320
- meta = _ref5.meta;
321
- return /*#__PURE__*/React.createElement(Stack, {
322
- space: "space.150",
323
- grow: "fill"
324
- }, /*#__PURE__*/React.createElement(Box, null, /*#__PURE__*/React.createElement(TextField
325
- // Ignored via go/ees005
326
- // eslint-disable-next-line react/jsx-props-no-spreading
327
- , _extends({}, rest, {
328
- value: value,
329
- placeholder: strings.pasteLinkToUpload,
330
- maxLength: MAX_URL_LENGTH,
331
- onKeyPress: onInputKeyPress,
332
- onPaste: function onPaste(event) {
333
- return _onPaste(event, value);
334
- },
335
- onChange: function onChange(value) {
336
- onURLChange(value);
337
- _onChange(value);
338
- }
339
- })), customizedHelperMessage && /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(HelperMessage, null, customizedHelperMessage)), /*#__PURE__*/React.createElement(MessageWrapper, null, error && /*#__PURE__*/React.createElement(ErrorMessage, null, /*#__PURE__*/React.createElement(Box, {
340
- as: "span"
341
- }, error)))), !previewState.previewInfo && !previewState.error && !previewState.warning && !isOnlyExternalLinks && /*#__PURE__*/React.createElement(Flex, {
342
- xcss: PreviewBoxStyles,
343
- alignItems: "center",
344
- justifyContent: "center"
345
- }, /*#__PURE__*/React.createElement(Button, {
346
- type: "submit",
347
- isLoading: previewState.isLoading,
348
- isDisabled: !!error || !meta.dirty,
349
- iconBefore: function iconBefore() {
350
- return /*#__PURE__*/React.createElement(ExpandIcon, {
351
- label: "",
352
- LEGACY_fallbackIcon: EditorFilePreviewIconLegacy
353
- });
354
- }
355
- }, strings.loadPreview)));
356
- }), previewState.previewInfo && /*#__PURE__*/React.createElement(Inline, {
357
- alignInline: "center",
358
- alignBlock: "center",
359
- xcss: PreviewImageStyles,
360
- space: "space.200"
361
- }, /*#__PURE__*/React.createElement(MediaCard, {
362
- attrs: previewState.previewInfo,
363
- mediaProvider: mediaProvider
364
- })), /*#__PURE__*/React.createElement(MessageWrapper, null, previewState.error && /*#__PURE__*/React.createElement(SectionMessage, {
365
- appearance: "error"
366
- }, strings.errorMessage), previewState.warning && /*#__PURE__*/React.createElement(SectionMessage, {
367
- appearance: "warning"
368
- }, strings.warning)), /*#__PURE__*/React.createElement(FormFooter, null, /*#__PURE__*/React.createElement(ButtonGroup, null, /*#__PURE__*/React.createElement(Button, {
369
- appearance: "subtle",
370
- onClick: onCancel
371
- }, strings.cancel), /*#__PURE__*/React.createElement(Button, {
372
- type: "submit",
373
- appearance: "primary",
374
- isDisabled: isOnlyExternalLinks ? !input || !isValidInput(input, customizedUrlValidation) : !previewState.previewInfo && !previewState.warning
375
- }, strings.insert)))))
376
- );
377
- });
378
- }
@@ -1,17 +0,0 @@
1
- import React from 'react';
2
- import { type DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
3
- import type { MediaProvider } from '@atlaskit/editor-common/provider-factory';
4
- import { type CustomizedHelperMessage, type InsertExternalMediaSingle, type InsertMediaSingle } from '../types';
5
- export declare const isValidUrl: (value: string) => boolean;
6
- type Props = {
7
- mediaProvider: MediaProvider;
8
- dispatchAnalyticsEvent?: DispatchAnalyticsEvent;
9
- closeMediaInsertPicker: () => void;
10
- insertMediaSingle: InsertMediaSingle;
11
- insertExternalMediaSingle: InsertExternalMediaSingle;
12
- isOnlyExternalLinks: boolean;
13
- customizedUrlValidation?: (input: string) => boolean;
14
- customizedHelperMessage?: CustomizedHelperMessage;
15
- };
16
- export declare function MediaFromURLWithForm({ mediaProvider, dispatchAnalyticsEvent, closeMediaInsertPicker, insertMediaSingle, insertExternalMediaSingle, isOnlyExternalLinks, customizedUrlValidation, customizedHelperMessage, }: Props): React.JSX.Element;
17
- export {};
@@ -1,17 +0,0 @@
1
- import React from 'react';
2
- import { type DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
3
- import type { MediaProvider } from '@atlaskit/editor-common/provider-factory';
4
- import { type CustomizedHelperMessage, type InsertExternalMediaSingle, type InsertMediaSingle } from '../types';
5
- export declare const isValidUrl: (value: string) => boolean;
6
- type Props = {
7
- mediaProvider: MediaProvider;
8
- dispatchAnalyticsEvent?: DispatchAnalyticsEvent;
9
- closeMediaInsertPicker: () => void;
10
- insertMediaSingle: InsertMediaSingle;
11
- insertExternalMediaSingle: InsertExternalMediaSingle;
12
- isOnlyExternalLinks: boolean;
13
- customizedUrlValidation?: (input: string) => boolean;
14
- customizedHelperMessage?: CustomizedHelperMessage;
15
- };
16
- export declare function MediaFromURLWithForm({ mediaProvider, dispatchAnalyticsEvent, closeMediaInsertPicker, insertMediaSingle, insertExternalMediaSingle, isOnlyExternalLinks, customizedUrlValidation, customizedHelperMessage, }: Props): React.JSX.Element;
17
- export {};