@atlaskit/editor-plugin-media-insert 2.1.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/dist/cjs/hooks/use-focus-editor.js +17 -0
- package/dist/cjs/plugin.js +1 -3
- package/dist/cjs/ui/LocalMedia.js +134 -0
- package/dist/cjs/ui/{FromURL.js → MediaFromURL.js} +22 -20
- package/dist/cjs/ui/MediaInsertContent.js +8 -2
- package/dist/cjs/ui/MediaInsertPicker.js +11 -3
- package/dist/cjs/ui/useAnalyticsEvents.js +26 -10
- package/dist/es2019/hooks/use-focus-editor.js +10 -0
- package/dist/es2019/plugin.js +3 -5
- package/dist/es2019/ui/LocalMedia.js +128 -0
- package/dist/es2019/ui/{FromURL.js → MediaFromURL.js} +11 -9
- package/dist/es2019/ui/MediaInsertContent.js +8 -2
- package/dist/es2019/ui/MediaInsertPicker.js +9 -1
- package/dist/es2019/ui/useAnalyticsEvents.js +26 -10
- package/dist/esm/hooks/use-focus-editor.js +11 -0
- package/dist/esm/plugin.js +1 -3
- package/dist/esm/ui/LocalMedia.js +127 -0
- package/dist/esm/ui/{FromURL.js → MediaFromURL.js} +22 -20
- package/dist/esm/ui/MediaInsertContent.js +8 -2
- package/dist/esm/ui/MediaInsertPicker.js +11 -3
- package/dist/esm/ui/useAnalyticsEvents.js +26 -10
- package/dist/types/hooks/use-focus-editor.d.ts +4 -0
- package/dist/types/ui/LocalMedia.d.ts +12 -0
- package/dist/types/ui/MediaCard.d.ts +1 -1
- package/dist/types/ui/types.d.ts +2 -2
- package/dist/types/ui/useAnalyticsEvents.d.ts +6 -3
- package/dist/types-ts4.5/hooks/use-focus-editor.d.ts +4 -0
- package/dist/types-ts4.5/ui/LocalMedia.d.ts +12 -0
- package/dist/types-ts4.5/ui/MediaCard.d.ts +1 -1
- package/dist/types-ts4.5/ui/types.d.ts +2 -2
- package/dist/types-ts4.5/ui/useAnalyticsEvents.d.ts +6 -3
- package/package.json +4 -3
- /package/dist/types/ui/{FromURL.d.ts → MediaFromURL.d.ts} +0 -0
- /package/dist/types-ts4.5/ui/{FromURL.d.ts → MediaFromURL.d.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-media-insert
|
|
2
2
|
|
|
3
|
+
## 2.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#134463](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/134463)
|
|
8
|
+
[`d20ae898369bc`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/d20ae898369bc) -
|
|
9
|
+
[ux] [ED-24326] Add local file upload tab to media insert popup
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
|
|
15
|
+
## 2.1.2
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- [#134104](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/134104)
|
|
20
|
+
[`18a1de35efaf0`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/18a1de35efaf0) -
|
|
21
|
+
[ux] ED-24639 Make sure the editor is properly re-focused when the media insert picker is closed
|
|
22
|
+
- Updated dependencies
|
|
23
|
+
|
|
3
24
|
## 2.1.1
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useFocusEditor = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var useFocusEditor = exports.useFocusEditor = function useFocusEditor(_ref) {
|
|
9
|
+
var editorView = _ref.editorView;
|
|
10
|
+
var focusEditor = (0, _react.useCallback)(function () {
|
|
11
|
+
// use setTimeout to run this async after the call
|
|
12
|
+
setTimeout(function () {
|
|
13
|
+
return editorView.focus();
|
|
14
|
+
}, 0);
|
|
15
|
+
}, [editorView]);
|
|
16
|
+
return focusEditor;
|
|
17
|
+
};
|
package/dist/cjs/plugin.js
CHANGED
|
@@ -43,8 +43,6 @@ var mediaInsertPlugin = exports.mediaInsertPlugin = function mediaInsertPlugin(_
|
|
|
43
43
|
popupsMountPoint = _ref3.popupsMountPoint,
|
|
44
44
|
popupsBoundariesElement = _ref3.popupsBoundariesElement,
|
|
45
45
|
popupsScrollableElement = _ref3.popupsScrollableElement;
|
|
46
|
-
var dispatch = editorView.dispatch,
|
|
47
|
-
state = editorView.state;
|
|
48
46
|
return /*#__PURE__*/_react.default.createElement(_MediaInsertPicker.MediaInsertPicker, {
|
|
49
47
|
api: api,
|
|
50
48
|
editorView: editorView,
|
|
@@ -53,7 +51,7 @@ var mediaInsertPlugin = exports.mediaInsertPlugin = function mediaInsertPlugin(_
|
|
|
53
51
|
popupsBoundariesElement: popupsBoundariesElement,
|
|
54
52
|
popupsScrollableElement: popupsScrollableElement,
|
|
55
53
|
closeMediaInsertPicker: function closeMediaInsertPicker() {
|
|
56
|
-
|
|
54
|
+
editorView.dispatch((0, _actions.closeMediaInsertPicker)(editorView.state.tr));
|
|
57
55
|
}
|
|
58
56
|
});
|
|
59
57
|
},
|
|
@@ -0,0 +1,134 @@
|
|
|
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 _messages = require("@atlaskit/editor-common/messages");
|
|
14
|
+
var _upload = _interopRequireDefault(require("@atlaskit/icon/glyph/upload"));
|
|
15
|
+
var _mediaPicker = require("@atlaskit/media-picker");
|
|
16
|
+
var _primitives = require("@atlaskit/primitives");
|
|
17
|
+
var _sectionMessage = _interopRequireDefault(require("@atlaskit/section-message"));
|
|
18
|
+
var _useAnalyticsEvents2 = require("./useAnalyticsEvents");
|
|
19
|
+
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; }
|
|
20
|
+
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; }
|
|
21
|
+
var INITIAL_UPLOAD_STATE = Object.freeze({
|
|
22
|
+
isOpen: false,
|
|
23
|
+
error: null
|
|
24
|
+
});
|
|
25
|
+
var uploadReducer = function uploadReducer(state, action) {
|
|
26
|
+
switch (action.type) {
|
|
27
|
+
case 'open':
|
|
28
|
+
return _objectSpread(_objectSpread({}, INITIAL_UPLOAD_STATE), {}, {
|
|
29
|
+
isOpen: true
|
|
30
|
+
});
|
|
31
|
+
case 'close':
|
|
32
|
+
// This is the only case where we don't reset state. This is because
|
|
33
|
+
// onClose gets called for cancel _and_ upload, so we don't want to
|
|
34
|
+
// reset any loading or error states that may have occured
|
|
35
|
+
return _objectSpread(_objectSpread({}, state), {}, {
|
|
36
|
+
isOpen: false
|
|
37
|
+
});
|
|
38
|
+
case 'error':
|
|
39
|
+
return _objectSpread(_objectSpread({}, INITIAL_UPLOAD_STATE), {}, {
|
|
40
|
+
error: action.error
|
|
41
|
+
});
|
|
42
|
+
case 'reset':
|
|
43
|
+
return INITIAL_UPLOAD_STATE;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
var isImagePreview = function isImagePreview(preview) {
|
|
47
|
+
return 'dimensions' in preview;
|
|
48
|
+
};
|
|
49
|
+
var LocalMedia = exports.LocalMedia = function LocalMedia(_ref) {
|
|
50
|
+
var mediaProvider = _ref.mediaProvider,
|
|
51
|
+
onInsert = _ref.onInsert,
|
|
52
|
+
dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent;
|
|
53
|
+
var intl = (0, _reactIntlNext.useIntl)();
|
|
54
|
+
var strings = {
|
|
55
|
+
upload: intl.formatMessage(_messages.mediaInsertMessages.upload),
|
|
56
|
+
networkError: intl.formatMessage(_messages.mediaInsertMessages.localFileNetworkErrorMessage),
|
|
57
|
+
genericError: intl.formatMessage(_messages.mediaInsertMessages.localFileErrorMessage)
|
|
58
|
+
};
|
|
59
|
+
var _useAnalyticsEvents = (0, _useAnalyticsEvents2.useAnalyticsEvents)(dispatchAnalyticsEvent),
|
|
60
|
+
onUploadButtonClickedAnalytics = _useAnalyticsEvents.onUploadButtonClickedAnalytics,
|
|
61
|
+
onUploadCommencedAnalytics = _useAnalyticsEvents.onUploadCommencedAnalytics,
|
|
62
|
+
onUploadSuccessAnalytics = _useAnalyticsEvents.onUploadSuccessAnalytics,
|
|
63
|
+
onUploadFailureAnalytics = _useAnalyticsEvents.onUploadFailureAnalytics;
|
|
64
|
+
var _React$useReducer = _react.default.useReducer(uploadReducer, INITIAL_UPLOAD_STATE),
|
|
65
|
+
_React$useReducer2 = (0, _slicedToArray2.default)(_React$useReducer, 2),
|
|
66
|
+
uploadState = _React$useReducer2[0],
|
|
67
|
+
dispatch = _React$useReducer2[1];
|
|
68
|
+
var onUpload = function onUpload(_ref2) {
|
|
69
|
+
var _mediaProvider$upload;
|
|
70
|
+
var file = _ref2.file,
|
|
71
|
+
preview = _ref2.preview;
|
|
72
|
+
onUploadSuccessAnalytics('local');
|
|
73
|
+
var insertPayload = {
|
|
74
|
+
id: file.id,
|
|
75
|
+
collection: (_mediaProvider$upload = mediaProvider.uploadParams) === null || _mediaProvider$upload === void 0 ? void 0 : _mediaProvider$upload.collection,
|
|
76
|
+
occurrenceKey: file.occurrenceKey
|
|
77
|
+
};
|
|
78
|
+
if (isImagePreview(preview)) {
|
|
79
|
+
insertPayload.height = preview.dimensions.height;
|
|
80
|
+
insertPayload.width = preview.dimensions.width;
|
|
81
|
+
}
|
|
82
|
+
onInsert(insertPayload);
|
|
83
|
+
|
|
84
|
+
// Probably not needed but I guess it _could_ fail to close for some reason
|
|
85
|
+
dispatch({
|
|
86
|
+
type: 'reset'
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
var uploadParams = mediaProvider.uploadParams,
|
|
90
|
+
uploadMediaClientConfig = mediaProvider.uploadMediaClientConfig;
|
|
91
|
+
return /*#__PURE__*/_react.default.createElement(_primitives.Stack, {
|
|
92
|
+
grow: "fill",
|
|
93
|
+
space: "space.200"
|
|
94
|
+
}, uploadState.error && /*#__PURE__*/_react.default.createElement(_sectionMessage.default, {
|
|
95
|
+
appearance: "error"
|
|
96
|
+
}, uploadState.error === 'upload_fail' ? strings.networkError : strings.genericError), /*#__PURE__*/_react.default.createElement(_new.default, {
|
|
97
|
+
iconBefore: _upload.default,
|
|
98
|
+
shouldFitContainer: true,
|
|
99
|
+
isDisabled: !uploadMediaClientConfig || !uploadParams,
|
|
100
|
+
onClick: function onClick() {
|
|
101
|
+
onUploadButtonClickedAnalytics();
|
|
102
|
+
dispatch({
|
|
103
|
+
type: 'open'
|
|
104
|
+
});
|
|
105
|
+
},
|
|
106
|
+
autoFocus: true
|
|
107
|
+
}, strings.upload), uploadMediaClientConfig && uploadParams && /*#__PURE__*/_react.default.createElement(_mediaPicker.Browser, {
|
|
108
|
+
isOpen: uploadState.isOpen,
|
|
109
|
+
config: {
|
|
110
|
+
uploadParams: uploadParams
|
|
111
|
+
},
|
|
112
|
+
mediaClientConfig: uploadMediaClientConfig,
|
|
113
|
+
onUploadsStart: function onUploadsStart() {
|
|
114
|
+
onUploadCommencedAnalytics('local');
|
|
115
|
+
},
|
|
116
|
+
onPreviewUpdate: onUpload
|
|
117
|
+
// NOTE: this will fire for some errors like network failures, but not
|
|
118
|
+
// for others like empty files. Those have their own feedback toast
|
|
119
|
+
// owned by media.
|
|
120
|
+
,
|
|
121
|
+
onError: function onError(payload) {
|
|
122
|
+
onUploadFailureAnalytics(payload.error.name, 'local');
|
|
123
|
+
dispatch({
|
|
124
|
+
type: 'error',
|
|
125
|
+
error: payload.error.name
|
|
126
|
+
});
|
|
127
|
+
},
|
|
128
|
+
onClose: function onClose() {
|
|
129
|
+
dispatch({
|
|
130
|
+
type: 'close'
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}));
|
|
134
|
+
};
|
|
@@ -82,8 +82,8 @@ function MediaFromURL(_ref) {
|
|
|
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.
|
|
86
|
-
warning: intl.formatMessage(_messages.mediaInsertMessages.
|
|
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,7 +95,8 @@ 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
|
-
|
|
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 () {
|
|
@@ -104,27 +105,28 @@ function MediaFromURL(_ref) {
|
|
|
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 =
|
|
114
|
+
_context.next = 5;
|
|
113
115
|
break;
|
|
114
116
|
}
|
|
115
117
|
return _context.abrupt("return");
|
|
116
|
-
case
|
|
118
|
+
case 5:
|
|
117
119
|
mediaClient = (0, _mediaClientReact.getMediaClient)(uploadMediaClientConfig);
|
|
118
120
|
collection = uploadParams === null || uploadParams === void 0 ? void 0 : uploadParams.collection;
|
|
119
|
-
|
|
120
|
-
_context.prev =
|
|
121
|
-
_context.next =
|
|
121
|
+
onUploadCommencedAnalytics('url');
|
|
122
|
+
_context.prev = 8;
|
|
123
|
+
_context.next = 11;
|
|
122
124
|
return mediaClient.file.uploadExternal(url, collection);
|
|
123
|
-
case
|
|
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
|
+
onUploadSuccessAnalytics('url');
|
|
128
130
|
dispatch({
|
|
129
131
|
type: 'success',
|
|
130
132
|
payload: {
|
|
@@ -135,16 +137,16 @@ function MediaFromURL(_ref) {
|
|
|
135
137
|
occurrenceKey: uploadableFileUpfrontIds.occurrenceKey
|
|
136
138
|
}
|
|
137
139
|
});
|
|
138
|
-
_context.next =
|
|
140
|
+
_context.next = 21;
|
|
139
141
|
break;
|
|
140
|
-
case
|
|
141
|
-
_context.prev =
|
|
142
|
-
_context.t0 = _context["catch"](
|
|
142
|
+
case 18:
|
|
143
|
+
_context.prev = 18;
|
|
144
|
+
_context.t0 = _context["catch"](8);
|
|
143
145
|
if (typeof _context.t0 === 'string' && _context.t0 === 'Could not download remote file') {
|
|
144
146
|
// TODO: Make sure this gets good unit test coverage with the actual
|
|
145
147
|
// media plugin. This hard coded error message could be changed at any
|
|
146
148
|
// point and we need a unit test to break to stop people changing it.
|
|
147
|
-
onUploadFailureAnalytics(_context.t0);
|
|
149
|
+
onUploadFailureAnalytics(_context.t0, 'url');
|
|
148
150
|
dispatch({
|
|
149
151
|
type: 'warning',
|
|
150
152
|
warning: _context.t0,
|
|
@@ -152,28 +154,28 @@ function MediaFromURL(_ref) {
|
|
|
152
154
|
});
|
|
153
155
|
} else if (_context.t0 instanceof Error) {
|
|
154
156
|
message = 'Image preview fetch failed';
|
|
155
|
-
onUploadFailureAnalytics(message);
|
|
157
|
+
onUploadFailureAnalytics(message, 'url');
|
|
156
158
|
dispatch({
|
|
157
159
|
type: 'error',
|
|
158
160
|
error: message
|
|
159
161
|
});
|
|
160
162
|
} else {
|
|
161
|
-
onUploadFailureAnalytics('Unknown error');
|
|
163
|
+
onUploadFailureAnalytics('Unknown error', 'url');
|
|
162
164
|
dispatch({
|
|
163
165
|
type: 'error',
|
|
164
166
|
error: 'Unknown error'
|
|
165
167
|
});
|
|
166
168
|
}
|
|
167
|
-
case
|
|
169
|
+
case 21:
|
|
168
170
|
case "end":
|
|
169
171
|
return _context.stop();
|
|
170
172
|
}
|
|
171
|
-
}, _callee, null, [[
|
|
173
|
+
}, _callee, null, [[8, 18]]);
|
|
172
174
|
}));
|
|
173
175
|
return function (_x) {
|
|
174
176
|
return _ref2.apply(this, arguments);
|
|
175
177
|
};
|
|
176
|
-
}(), [
|
|
178
|
+
}(), [onUploadButtonClickedAnalytics, mediaProvider, onUploadCommencedAnalytics, onUploadSuccessAnalytics, onUploadFailureAnalytics, inputUrl]);
|
|
177
179
|
var onURLChange = _react.default.useCallback(function (e) {
|
|
178
180
|
var url = e.target.value;
|
|
179
181
|
setUrl(url);
|
|
@@ -11,7 +11,8 @@ 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
|
|
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) {
|
|
@@ -23,7 +24,12 @@ var MediaInsertContent = exports.MediaInsertContent = function MediaInsertConten
|
|
|
23
24
|
id: "media-insert-tab-navigation"
|
|
24
25
|
}, /*#__PURE__*/_react.default.createElement(_primitives.Box, {
|
|
25
26
|
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(
|
|
27
|
+
}, /*#__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, {
|
|
28
|
+
mediaProvider: mediaProvider,
|
|
29
|
+
onInsert: function onInsert() {},
|
|
30
|
+
onClose: closeMediaInsertPicker,
|
|
31
|
+
dispatchAnalyticsEvent: dispatchAnalyticsEvent
|
|
32
|
+
})), /*#__PURE__*/_react.default.createElement(_tabs.TabPanel, null, /*#__PURE__*/_react.default.createElement(_MediaFromURL.MediaFromURL, {
|
|
27
33
|
mediaProvider: mediaProvider,
|
|
28
34
|
onExternalInsert: function onExternalInsert() {},
|
|
29
35
|
onInsert: function onInsert() {},
|
|
@@ -13,6 +13,7 @@ var _messages = require("@atlaskit/editor-common/messages");
|
|
|
13
13
|
var _ui = require("@atlaskit/editor-common/ui");
|
|
14
14
|
var _utils = require("@atlaskit/editor-prosemirror/utils");
|
|
15
15
|
var _editorSharedStyles = require("@atlaskit/editor-shared-styles");
|
|
16
|
+
var _useFocusEditor = require("../hooks/use-focus-editor");
|
|
16
17
|
var _MediaInsertContent = require("./MediaInsertContent");
|
|
17
18
|
var _MediaInsertWrapper = require("./MediaInsertWrapper");
|
|
18
19
|
var PopupWithListeners = (0, _ui.withOuterListeners)(_ui.Popup);
|
|
@@ -47,11 +48,14 @@ var MediaInsertPicker = exports.MediaInsertPicker = function MediaInsertPicker(_
|
|
|
47
48
|
popupsMountPoint = _ref.popupsMountPoint,
|
|
48
49
|
popupsBoundariesElement = _ref.popupsBoundariesElement,
|
|
49
50
|
popupsScrollableElement = _ref.popupsScrollableElement,
|
|
50
|
-
|
|
51
|
+
_closeMediaInsertPicker = _ref.closeMediaInsertPicker;
|
|
51
52
|
var targetRef = getDomRefFromSelection(editorView, dispatchAnalyticsEvent);
|
|
52
53
|
var isOpen = (_useSharedPluginState = (0, _hooks.useSharedPluginState)(api, ['mediaInsert'])) === null || _useSharedPluginState === void 0 || (_useSharedPluginState = _useSharedPluginState.mediaInsertState) === null || _useSharedPluginState === void 0 ? void 0 : _useSharedPluginState.isOpen;
|
|
53
54
|
var mediaProvider = (_useSharedPluginState2 = (0, _hooks.useSharedPluginState)(api, ['media'])) === null || _useSharedPluginState2 === void 0 || (_useSharedPluginState2 = _useSharedPluginState2.mediaState) === null || _useSharedPluginState2 === void 0 ? void 0 : _useSharedPluginState2.mediaProvider;
|
|
54
55
|
var intl = (0, _reactIntlNext.useIntl)();
|
|
56
|
+
var focusEditor = (0, _useFocusEditor.useFocusEditor)({
|
|
57
|
+
editorView: editorView
|
|
58
|
+
});
|
|
55
59
|
if (!isOpen || !mediaProvider) {
|
|
56
60
|
return null;
|
|
57
61
|
}
|
|
@@ -70,7 +74,8 @@ var MediaInsertPicker = exports.MediaInsertPicker = function MediaInsertPicker(_
|
|
|
70
74
|
};
|
|
71
75
|
dispatchAnalyticsEvent(payload);
|
|
72
76
|
}
|
|
73
|
-
|
|
77
|
+
_closeMediaInsertPicker();
|
|
78
|
+
focusEditor();
|
|
74
79
|
};
|
|
75
80
|
};
|
|
76
81
|
return /*#__PURE__*/_react.default.createElement(PopupWithListeners, {
|
|
@@ -90,6 +95,9 @@ var MediaInsertPicker = exports.MediaInsertPicker = function MediaInsertPicker(_
|
|
|
90
95
|
}, /*#__PURE__*/_react.default.createElement(_MediaInsertWrapper.MediaInsertWrapper, null, /*#__PURE__*/_react.default.createElement(_MediaInsertContent.MediaInsertContent, {
|
|
91
96
|
mediaProvider: mediaProvider,
|
|
92
97
|
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
93
|
-
closeMediaInsertPicker: closeMediaInsertPicker
|
|
98
|
+
closeMediaInsertPicker: function closeMediaInsertPicker() {
|
|
99
|
+
_closeMediaInsertPicker();
|
|
100
|
+
focusEditor();
|
|
101
|
+
}
|
|
94
102
|
})));
|
|
95
103
|
};
|
|
@@ -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
|
|
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.
|
|
15
|
+
actionSubjectId: _analytics.ACTION_SUBJECT_ID.UPLOAD_MEDIA,
|
|
16
16
|
eventType: _analytics.EVENT_TYPE.UI
|
|
17
17
|
});
|
|
18
18
|
}, [dispatchAnalyticsEvent]);
|
|
19
|
-
var
|
|
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.
|
|
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.
|
|
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
|
-
|
|
55
|
+
onUploadButtonClickedAnalytics: onUploadButtonClickedAnalytics,
|
|
56
|
+
onUploadCommencedAnalytics: onUploadCommencedAnalytics,
|
|
41
57
|
onUploadSuccessAnalytics: onUploadSuccessAnalytics,
|
|
42
58
|
onUploadFailureAnalytics: onUploadFailureAnalytics
|
|
43
59
|
};
|
|
44
|
-
}, [
|
|
60
|
+
}, [onUploadButtonClickedAnalytics, onUploadCommencedAnalytics, onUploadSuccessAnalytics, onUploadFailureAnalytics]);
|
|
45
61
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
export const useFocusEditor = ({
|
|
3
|
+
editorView
|
|
4
|
+
}) => {
|
|
5
|
+
const focusEditor = useCallback(() => {
|
|
6
|
+
// use setTimeout to run this async after the call
|
|
7
|
+
setTimeout(() => editorView.focus(), 0);
|
|
8
|
+
}, [editorView]);
|
|
9
|
+
return focusEditor;
|
|
10
|
+
};
|
package/dist/es2019/plugin.js
CHANGED
|
@@ -37,10 +37,6 @@ export const mediaInsertPlugin = ({
|
|
|
37
37
|
popupsBoundariesElement,
|
|
38
38
|
popupsScrollableElement
|
|
39
39
|
}) => {
|
|
40
|
-
const {
|
|
41
|
-
dispatch,
|
|
42
|
-
state
|
|
43
|
-
} = editorView;
|
|
44
40
|
return /*#__PURE__*/React.createElement(MediaInsertPicker, {
|
|
45
41
|
api: api,
|
|
46
42
|
editorView: editorView,
|
|
@@ -48,7 +44,9 @@ export const mediaInsertPlugin = ({
|
|
|
48
44
|
popupsMountPoint: popupsMountPoint,
|
|
49
45
|
popupsBoundariesElement: popupsBoundariesElement,
|
|
50
46
|
popupsScrollableElement: popupsScrollableElement,
|
|
51
|
-
closeMediaInsertPicker: () =>
|
|
47
|
+
closeMediaInsertPicker: () => {
|
|
48
|
+
editorView.dispatch(closeMediaInsertPicker(editorView.state.tr));
|
|
49
|
+
}
|
|
52
50
|
});
|
|
53
51
|
},
|
|
54
52
|
pluginsOptions: {
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useIntl } from 'react-intl-next';
|
|
3
|
+
import Button from '@atlaskit/button/new';
|
|
4
|
+
import { mediaInsertMessages } from '@atlaskit/editor-common/messages';
|
|
5
|
+
import UploadIcon from '@atlaskit/icon/glyph/upload';
|
|
6
|
+
import { Browser } from '@atlaskit/media-picker';
|
|
7
|
+
import { Stack } from '@atlaskit/primitives';
|
|
8
|
+
import SectionMessage from '@atlaskit/section-message';
|
|
9
|
+
import { useAnalyticsEvents } from './useAnalyticsEvents';
|
|
10
|
+
const INITIAL_UPLOAD_STATE = Object.freeze({
|
|
11
|
+
isOpen: false,
|
|
12
|
+
error: null
|
|
13
|
+
});
|
|
14
|
+
const uploadReducer = (state, action) => {
|
|
15
|
+
switch (action.type) {
|
|
16
|
+
case 'open':
|
|
17
|
+
return {
|
|
18
|
+
...INITIAL_UPLOAD_STATE,
|
|
19
|
+
isOpen: true
|
|
20
|
+
};
|
|
21
|
+
case 'close':
|
|
22
|
+
// This is the only case where we don't reset state. This is because
|
|
23
|
+
// onClose gets called for cancel _and_ upload, so we don't want to
|
|
24
|
+
// reset any loading or error states that may have occured
|
|
25
|
+
return {
|
|
26
|
+
...state,
|
|
27
|
+
isOpen: false
|
|
28
|
+
};
|
|
29
|
+
case 'error':
|
|
30
|
+
return {
|
|
31
|
+
...INITIAL_UPLOAD_STATE,
|
|
32
|
+
error: action.error
|
|
33
|
+
};
|
|
34
|
+
case 'reset':
|
|
35
|
+
return INITIAL_UPLOAD_STATE;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const isImagePreview = preview => {
|
|
39
|
+
return 'dimensions' in preview;
|
|
40
|
+
};
|
|
41
|
+
export const LocalMedia = ({
|
|
42
|
+
mediaProvider,
|
|
43
|
+
onInsert,
|
|
44
|
+
dispatchAnalyticsEvent
|
|
45
|
+
}) => {
|
|
46
|
+
const intl = useIntl();
|
|
47
|
+
const strings = {
|
|
48
|
+
upload: intl.formatMessage(mediaInsertMessages.upload),
|
|
49
|
+
networkError: intl.formatMessage(mediaInsertMessages.localFileNetworkErrorMessage),
|
|
50
|
+
genericError: intl.formatMessage(mediaInsertMessages.localFileErrorMessage)
|
|
51
|
+
};
|
|
52
|
+
const {
|
|
53
|
+
onUploadButtonClickedAnalytics,
|
|
54
|
+
onUploadCommencedAnalytics,
|
|
55
|
+
onUploadSuccessAnalytics,
|
|
56
|
+
onUploadFailureAnalytics
|
|
57
|
+
} = useAnalyticsEvents(dispatchAnalyticsEvent);
|
|
58
|
+
const [uploadState, dispatch] = React.useReducer(uploadReducer, INITIAL_UPLOAD_STATE);
|
|
59
|
+
const onUpload = ({
|
|
60
|
+
file,
|
|
61
|
+
preview
|
|
62
|
+
}) => {
|
|
63
|
+
var _mediaProvider$upload;
|
|
64
|
+
onUploadSuccessAnalytics('local');
|
|
65
|
+
const insertPayload = {
|
|
66
|
+
id: file.id,
|
|
67
|
+
collection: (_mediaProvider$upload = mediaProvider.uploadParams) === null || _mediaProvider$upload === void 0 ? void 0 : _mediaProvider$upload.collection,
|
|
68
|
+
occurrenceKey: file.occurrenceKey
|
|
69
|
+
};
|
|
70
|
+
if (isImagePreview(preview)) {
|
|
71
|
+
insertPayload.height = preview.dimensions.height;
|
|
72
|
+
insertPayload.width = preview.dimensions.width;
|
|
73
|
+
}
|
|
74
|
+
onInsert(insertPayload);
|
|
75
|
+
|
|
76
|
+
// Probably not needed but I guess it _could_ fail to close for some reason
|
|
77
|
+
dispatch({
|
|
78
|
+
type: 'reset'
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
const {
|
|
82
|
+
uploadParams,
|
|
83
|
+
uploadMediaClientConfig
|
|
84
|
+
} = mediaProvider;
|
|
85
|
+
return /*#__PURE__*/React.createElement(Stack, {
|
|
86
|
+
grow: "fill",
|
|
87
|
+
space: "space.200"
|
|
88
|
+
}, uploadState.error && /*#__PURE__*/React.createElement(SectionMessage, {
|
|
89
|
+
appearance: "error"
|
|
90
|
+
}, uploadState.error === 'upload_fail' ? strings.networkError : strings.genericError), /*#__PURE__*/React.createElement(Button, {
|
|
91
|
+
iconBefore: UploadIcon,
|
|
92
|
+
shouldFitContainer: true,
|
|
93
|
+
isDisabled: !uploadMediaClientConfig || !uploadParams,
|
|
94
|
+
onClick: () => {
|
|
95
|
+
onUploadButtonClickedAnalytics();
|
|
96
|
+
dispatch({
|
|
97
|
+
type: 'open'
|
|
98
|
+
});
|
|
99
|
+
},
|
|
100
|
+
autoFocus: true
|
|
101
|
+
}, strings.upload), uploadMediaClientConfig && uploadParams && /*#__PURE__*/React.createElement(Browser, {
|
|
102
|
+
isOpen: uploadState.isOpen,
|
|
103
|
+
config: {
|
|
104
|
+
uploadParams: uploadParams
|
|
105
|
+
},
|
|
106
|
+
mediaClientConfig: uploadMediaClientConfig,
|
|
107
|
+
onUploadsStart: () => {
|
|
108
|
+
onUploadCommencedAnalytics('local');
|
|
109
|
+
},
|
|
110
|
+
onPreviewUpdate: onUpload
|
|
111
|
+
// NOTE: this will fire for some errors like network failures, but not
|
|
112
|
+
// for others like empty files. Those have their own feedback toast
|
|
113
|
+
// owned by media.
|
|
114
|
+
,
|
|
115
|
+
onError: payload => {
|
|
116
|
+
onUploadFailureAnalytics(payload.error.name, 'local');
|
|
117
|
+
dispatch({
|
|
118
|
+
type: 'error',
|
|
119
|
+
error: payload.error.name
|
|
120
|
+
});
|
|
121
|
+
},
|
|
122
|
+
onClose: () => {
|
|
123
|
+
dispatch({
|
|
124
|
+
type: 'close'
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}));
|
|
128
|
+
};
|