@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
|
@@ -74,18 +74,20 @@ export function MediaFromURL({
|
|
|
74
74
|
insert: intl.formatMessage(mediaInsertMessages.insert),
|
|
75
75
|
pasteLinkToUpload: intl.formatMessage(mediaInsertMessages.pasteLinkToUpload),
|
|
76
76
|
cancel: intl.formatMessage(mediaInsertMessages.cancel),
|
|
77
|
-
errorMessage: intl.formatMessage(mediaInsertMessages.
|
|
78
|
-
warning: intl.formatMessage(mediaInsertMessages.
|
|
77
|
+
errorMessage: intl.formatMessage(mediaInsertMessages.fromUrlErrorMessage),
|
|
78
|
+
warning: intl.formatMessage(mediaInsertMessages.fromUrlWarning)
|
|
79
79
|
};
|
|
80
80
|
const [inputUrl, setUrl] = React.useState('');
|
|
81
81
|
const [previewState, dispatch] = React.useReducer(previewStateReducer, INITIAL_PREVIEW_STATE);
|
|
82
82
|
const pasteFlag = React.useRef(false);
|
|
83
83
|
const {
|
|
84
|
-
|
|
84
|
+
onUploadButtonClickedAnalytics,
|
|
85
|
+
onUploadCommencedAnalytics,
|
|
85
86
|
onUploadSuccessAnalytics,
|
|
86
87
|
onUploadFailureAnalytics
|
|
87
88
|
} = useAnalyticsEvents(dispatchAnalyticsEvent);
|
|
88
89
|
const uploadExternalMedia = React.useCallback(async url => {
|
|
90
|
+
onUploadButtonClickedAnalytics();
|
|
89
91
|
dispatch({
|
|
90
92
|
type: 'loading'
|
|
91
93
|
});
|
|
@@ -98,13 +100,13 @@ export function MediaFromURL({
|
|
|
98
100
|
}
|
|
99
101
|
const mediaClient = getMediaClient(uploadMediaClientConfig);
|
|
100
102
|
const collection = uploadParams === null || uploadParams === void 0 ? void 0 : uploadParams.collection;
|
|
101
|
-
|
|
103
|
+
onUploadCommencedAnalytics('url');
|
|
102
104
|
try {
|
|
103
105
|
const {
|
|
104
106
|
uploadableFileUpfrontIds,
|
|
105
107
|
dimensions
|
|
106
108
|
} = await mediaClient.file.uploadExternal(url, collection);
|
|
107
|
-
onUploadSuccessAnalytics();
|
|
109
|
+
onUploadSuccessAnalytics('url');
|
|
108
110
|
dispatch({
|
|
109
111
|
type: 'success',
|
|
110
112
|
payload: {
|
|
@@ -120,7 +122,7 @@ export function MediaFromURL({
|
|
|
120
122
|
// TODO: Make sure this gets good unit test coverage with the actual
|
|
121
123
|
// media plugin. This hard coded error message could be changed at any
|
|
122
124
|
// point and we need a unit test to break to stop people changing it.
|
|
123
|
-
onUploadFailureAnalytics(e);
|
|
125
|
+
onUploadFailureAnalytics(e, 'url');
|
|
124
126
|
dispatch({
|
|
125
127
|
type: 'warning',
|
|
126
128
|
warning: e,
|
|
@@ -128,20 +130,20 @@ export function MediaFromURL({
|
|
|
128
130
|
});
|
|
129
131
|
} else if (e instanceof Error) {
|
|
130
132
|
const message = 'Image preview fetch failed';
|
|
131
|
-
onUploadFailureAnalytics(message);
|
|
133
|
+
onUploadFailureAnalytics(message, 'url');
|
|
132
134
|
dispatch({
|
|
133
135
|
type: 'error',
|
|
134
136
|
error: message
|
|
135
137
|
});
|
|
136
138
|
} else {
|
|
137
|
-
onUploadFailureAnalytics('Unknown error');
|
|
139
|
+
onUploadFailureAnalytics('Unknown error', 'url');
|
|
138
140
|
dispatch({
|
|
139
141
|
type: 'error',
|
|
140
142
|
error: 'Unknown error'
|
|
141
143
|
});
|
|
142
144
|
}
|
|
143
145
|
}
|
|
144
|
-
}, [
|
|
146
|
+
}, [onUploadButtonClickedAnalytics, mediaProvider, onUploadCommencedAnalytics, onUploadSuccessAnalytics, onUploadFailureAnalytics, inputUrl]);
|
|
145
147
|
const onURLChange = React.useCallback(e => {
|
|
146
148
|
const url = e.target.value;
|
|
147
149
|
setUrl(url);
|
|
@@ -3,7 +3,8 @@ import { useIntl } from 'react-intl-next';
|
|
|
3
3
|
import { mediaInsertMessages } from '@atlaskit/editor-common/messages';
|
|
4
4
|
import { Box } from '@atlaskit/primitives';
|
|
5
5
|
import Tabs, { Tab, TabList, TabPanel } from '@atlaskit/tabs';
|
|
6
|
-
import {
|
|
6
|
+
import { LocalMedia } from './LocalMedia';
|
|
7
|
+
import { MediaFromURL } from './MediaFromURL';
|
|
7
8
|
export const MediaInsertContent = ({
|
|
8
9
|
mediaProvider,
|
|
9
10
|
dispatchAnalyticsEvent,
|
|
@@ -14,7 +15,12 @@ export const MediaInsertContent = ({
|
|
|
14
15
|
id: "media-insert-tab-navigation"
|
|
15
16
|
}, /*#__PURE__*/React.createElement(Box, {
|
|
16
17
|
paddingBlockEnd: "space.150"
|
|
17
|
-
}, /*#__PURE__*/React.createElement(TabList, null, /*#__PURE__*/React.createElement(Tab, null, intl.formatMessage(mediaInsertMessages.linkTabTitle)))), /*#__PURE__*/React.createElement(TabPanel, null, /*#__PURE__*/React.createElement(
|
|
18
|
+
}, /*#__PURE__*/React.createElement(TabList, null, /*#__PURE__*/React.createElement(Tab, null, intl.formatMessage(mediaInsertMessages.fileTabTitle)), /*#__PURE__*/React.createElement(Tab, null, intl.formatMessage(mediaInsertMessages.linkTabTitle)))), /*#__PURE__*/React.createElement(TabPanel, null, /*#__PURE__*/React.createElement(LocalMedia, {
|
|
19
|
+
mediaProvider: mediaProvider,
|
|
20
|
+
onInsert: () => {},
|
|
21
|
+
onClose: closeMediaInsertPicker,
|
|
22
|
+
dispatchAnalyticsEvent: dispatchAnalyticsEvent
|
|
23
|
+
})), /*#__PURE__*/React.createElement(TabPanel, null, /*#__PURE__*/React.createElement(MediaFromURL, {
|
|
18
24
|
mediaProvider: mediaProvider,
|
|
19
25
|
onExternalInsert: () => {},
|
|
20
26
|
onInsert: () => {},
|
|
@@ -6,6 +6,7 @@ import { mediaInsertMessages } from '@atlaskit/editor-common/messages';
|
|
|
6
6
|
import { Popup, withOuterListeners } from '@atlaskit/editor-common/ui';
|
|
7
7
|
import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
|
|
8
8
|
import { akEditorFloatingDialogZIndex } from '@atlaskit/editor-shared-styles';
|
|
9
|
+
import { useFocusEditor } from '../hooks/use-focus-editor';
|
|
9
10
|
import { MediaInsertContent } from './MediaInsertContent';
|
|
10
11
|
import { MediaInsertWrapper } from './MediaInsertWrapper';
|
|
11
12
|
const PopupWithListeners = withOuterListeners(Popup);
|
|
@@ -46,6 +47,9 @@ export const MediaInsertPicker = ({
|
|
|
46
47
|
const isOpen = (_useSharedPluginState = useSharedPluginState(api, ['mediaInsert'])) === null || _useSharedPluginState === void 0 ? void 0 : (_useSharedPluginState2 = _useSharedPluginState.mediaInsertState) === null || _useSharedPluginState2 === void 0 ? void 0 : _useSharedPluginState2.isOpen;
|
|
47
48
|
const mediaProvider = (_useSharedPluginState3 = useSharedPluginState(api, ['media'])) === null || _useSharedPluginState3 === void 0 ? void 0 : (_useSharedPluginState4 = _useSharedPluginState3.mediaState) === null || _useSharedPluginState4 === void 0 ? void 0 : _useSharedPluginState4.mediaProvider;
|
|
48
49
|
const intl = useIntl();
|
|
50
|
+
const focusEditor = useFocusEditor({
|
|
51
|
+
editorView
|
|
52
|
+
});
|
|
49
53
|
if (!isOpen || !mediaProvider) {
|
|
50
54
|
return null;
|
|
51
55
|
}
|
|
@@ -64,6 +68,7 @@ export const MediaInsertPicker = ({
|
|
|
64
68
|
dispatchAnalyticsEvent(payload);
|
|
65
69
|
}
|
|
66
70
|
closeMediaInsertPicker();
|
|
71
|
+
focusEditor();
|
|
67
72
|
};
|
|
68
73
|
return /*#__PURE__*/React.createElement(PopupWithListeners, {
|
|
69
74
|
ariaLabel: intl.formatMessage(mediaInsertMessages.mediaPickerPopupAriaLabel),
|
|
@@ -82,6 +87,9 @@ export const MediaInsertPicker = ({
|
|
|
82
87
|
}, /*#__PURE__*/React.createElement(MediaInsertWrapper, null, /*#__PURE__*/React.createElement(MediaInsertContent, {
|
|
83
88
|
mediaProvider: mediaProvider,
|
|
84
89
|
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
85
|
-
closeMediaInsertPicker:
|
|
90
|
+
closeMediaInsertPicker: () => {
|
|
91
|
+
closeMediaInsertPicker();
|
|
92
|
+
focusEditor();
|
|
93
|
+
}
|
|
86
94
|
})));
|
|
87
95
|
};
|
|
@@ -1,36 +1,52 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
3
3
|
export function useAnalyticsEvents(dispatchAnalyticsEvent) {
|
|
4
|
-
const
|
|
4
|
+
const onUploadButtonClickedAnalytics = React.useCallback(() => {
|
|
5
5
|
dispatchAnalyticsEvent === null || dispatchAnalyticsEvent === void 0 ? void 0 : dispatchAnalyticsEvent({
|
|
6
6
|
action: ACTION.CLICKED,
|
|
7
7
|
actionSubject: ACTION_SUBJECT.BUTTON,
|
|
8
|
-
actionSubjectId: ACTION_SUBJECT_ID.
|
|
8
|
+
actionSubjectId: ACTION_SUBJECT_ID.UPLOAD_MEDIA,
|
|
9
9
|
eventType: EVENT_TYPE.UI
|
|
10
10
|
});
|
|
11
11
|
}, [dispatchAnalyticsEvent]);
|
|
12
|
-
const
|
|
12
|
+
const onUploadCommencedAnalytics = React.useCallback(mediaUploadSource => {
|
|
13
|
+
dispatchAnalyticsEvent === null || dispatchAnalyticsEvent === void 0 ? void 0 : dispatchAnalyticsEvent({
|
|
14
|
+
action: ACTION.UPLOAD_COMMENCED,
|
|
15
|
+
actionSubject: ACTION_SUBJECT.MEDIA,
|
|
16
|
+
actionSubjectId: ACTION_SUBJECT_ID.UPLOAD_MEDIA,
|
|
17
|
+
eventType: EVENT_TYPE.OPERATIONAL,
|
|
18
|
+
attributes: {
|
|
19
|
+
mediaUploadSource
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}, [dispatchAnalyticsEvent]);
|
|
23
|
+
const onUploadSuccessAnalytics = React.useCallback(mediaUploadSource => {
|
|
13
24
|
dispatchAnalyticsEvent === null || dispatchAnalyticsEvent === void 0 ? void 0 : dispatchAnalyticsEvent({
|
|
14
25
|
action: ACTION.UPLOAD_SUCCEEDED,
|
|
15
26
|
actionSubject: ACTION_SUBJECT.MEDIA,
|
|
16
|
-
actionSubjectId: ACTION_SUBJECT_ID.
|
|
17
|
-
eventType: EVENT_TYPE.OPERATIONAL
|
|
27
|
+
actionSubjectId: ACTION_SUBJECT_ID.UPLOAD_MEDIA,
|
|
28
|
+
eventType: EVENT_TYPE.OPERATIONAL,
|
|
29
|
+
attributes: {
|
|
30
|
+
mediaUploadSource
|
|
31
|
+
}
|
|
18
32
|
});
|
|
19
33
|
}, [dispatchAnalyticsEvent]);
|
|
20
|
-
const onUploadFailureAnalytics = React.useCallback(reason => {
|
|
34
|
+
const onUploadFailureAnalytics = React.useCallback((reason, mediaUploadSource) => {
|
|
21
35
|
dispatchAnalyticsEvent === null || dispatchAnalyticsEvent === void 0 ? void 0 : dispatchAnalyticsEvent({
|
|
22
36
|
action: ACTION.UPLOAD_FAILED,
|
|
23
37
|
actionSubject: ACTION_SUBJECT.MEDIA,
|
|
24
|
-
actionSubjectId: ACTION_SUBJECT_ID.
|
|
38
|
+
actionSubjectId: ACTION_SUBJECT_ID.UPLOAD_MEDIA,
|
|
25
39
|
eventType: EVENT_TYPE.OPERATIONAL,
|
|
26
40
|
attributes: {
|
|
27
|
-
reason
|
|
41
|
+
reason,
|
|
42
|
+
mediaUploadSource
|
|
28
43
|
}
|
|
29
44
|
});
|
|
30
45
|
}, [dispatchAnalyticsEvent]);
|
|
31
46
|
return React.useMemo(() => ({
|
|
32
|
-
|
|
47
|
+
onUploadButtonClickedAnalytics,
|
|
48
|
+
onUploadCommencedAnalytics,
|
|
33
49
|
onUploadSuccessAnalytics,
|
|
34
50
|
onUploadFailureAnalytics
|
|
35
|
-
}), [
|
|
51
|
+
}), [onUploadButtonClickedAnalytics, onUploadCommencedAnalytics, onUploadSuccessAnalytics, onUploadFailureAnalytics]);
|
|
36
52
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
export var useFocusEditor = function useFocusEditor(_ref) {
|
|
3
|
+
var editorView = _ref.editorView;
|
|
4
|
+
var focusEditor = useCallback(function () {
|
|
5
|
+
// use setTimeout to run this async after the call
|
|
6
|
+
setTimeout(function () {
|
|
7
|
+
return editorView.focus();
|
|
8
|
+
}, 0);
|
|
9
|
+
}, [editorView]);
|
|
10
|
+
return focusEditor;
|
|
11
|
+
};
|
package/dist/esm/plugin.js
CHANGED
|
@@ -36,8 +36,6 @@ export var mediaInsertPlugin = function mediaInsertPlugin(_ref) {
|
|
|
36
36
|
popupsMountPoint = _ref3.popupsMountPoint,
|
|
37
37
|
popupsBoundariesElement = _ref3.popupsBoundariesElement,
|
|
38
38
|
popupsScrollableElement = _ref3.popupsScrollableElement;
|
|
39
|
-
var dispatch = editorView.dispatch,
|
|
40
|
-
state = editorView.state;
|
|
41
39
|
return /*#__PURE__*/React.createElement(MediaInsertPicker, {
|
|
42
40
|
api: api,
|
|
43
41
|
editorView: editorView,
|
|
@@ -46,7 +44,7 @@ export var mediaInsertPlugin = function mediaInsertPlugin(_ref) {
|
|
|
46
44
|
popupsBoundariesElement: popupsBoundariesElement,
|
|
47
45
|
popupsScrollableElement: popupsScrollableElement,
|
|
48
46
|
closeMediaInsertPicker: function closeMediaInsertPicker() {
|
|
49
|
-
|
|
47
|
+
editorView.dispatch(_closeMediaInsertPicker(editorView.state.tr));
|
|
50
48
|
}
|
|
51
49
|
});
|
|
52
50
|
},
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
3
|
+
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; }
|
|
4
|
+
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; }
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import { useIntl } from 'react-intl-next';
|
|
7
|
+
import Button from '@atlaskit/button/new';
|
|
8
|
+
import { mediaInsertMessages } from '@atlaskit/editor-common/messages';
|
|
9
|
+
import UploadIcon from '@atlaskit/icon/glyph/upload';
|
|
10
|
+
import { Browser } from '@atlaskit/media-picker';
|
|
11
|
+
import { Stack } from '@atlaskit/primitives';
|
|
12
|
+
import SectionMessage from '@atlaskit/section-message';
|
|
13
|
+
import { useAnalyticsEvents } from './useAnalyticsEvents';
|
|
14
|
+
var INITIAL_UPLOAD_STATE = Object.freeze({
|
|
15
|
+
isOpen: false,
|
|
16
|
+
error: null
|
|
17
|
+
});
|
|
18
|
+
var uploadReducer = function uploadReducer(state, action) {
|
|
19
|
+
switch (action.type) {
|
|
20
|
+
case 'open':
|
|
21
|
+
return _objectSpread(_objectSpread({}, INITIAL_UPLOAD_STATE), {}, {
|
|
22
|
+
isOpen: true
|
|
23
|
+
});
|
|
24
|
+
case 'close':
|
|
25
|
+
// This is the only case where we don't reset state. This is because
|
|
26
|
+
// onClose gets called for cancel _and_ upload, so we don't want to
|
|
27
|
+
// reset any loading or error states that may have occured
|
|
28
|
+
return _objectSpread(_objectSpread({}, state), {}, {
|
|
29
|
+
isOpen: false
|
|
30
|
+
});
|
|
31
|
+
case 'error':
|
|
32
|
+
return _objectSpread(_objectSpread({}, INITIAL_UPLOAD_STATE), {}, {
|
|
33
|
+
error: action.error
|
|
34
|
+
});
|
|
35
|
+
case 'reset':
|
|
36
|
+
return INITIAL_UPLOAD_STATE;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
var isImagePreview = function isImagePreview(preview) {
|
|
40
|
+
return 'dimensions' in preview;
|
|
41
|
+
};
|
|
42
|
+
export var LocalMedia = function LocalMedia(_ref) {
|
|
43
|
+
var mediaProvider = _ref.mediaProvider,
|
|
44
|
+
onInsert = _ref.onInsert,
|
|
45
|
+
dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent;
|
|
46
|
+
var intl = useIntl();
|
|
47
|
+
var strings = {
|
|
48
|
+
upload: intl.formatMessage(mediaInsertMessages.upload),
|
|
49
|
+
networkError: intl.formatMessage(mediaInsertMessages.localFileNetworkErrorMessage),
|
|
50
|
+
genericError: intl.formatMessage(mediaInsertMessages.localFileErrorMessage)
|
|
51
|
+
};
|
|
52
|
+
var _useAnalyticsEvents = useAnalyticsEvents(dispatchAnalyticsEvent),
|
|
53
|
+
onUploadButtonClickedAnalytics = _useAnalyticsEvents.onUploadButtonClickedAnalytics,
|
|
54
|
+
onUploadCommencedAnalytics = _useAnalyticsEvents.onUploadCommencedAnalytics,
|
|
55
|
+
onUploadSuccessAnalytics = _useAnalyticsEvents.onUploadSuccessAnalytics,
|
|
56
|
+
onUploadFailureAnalytics = _useAnalyticsEvents.onUploadFailureAnalytics;
|
|
57
|
+
var _React$useReducer = React.useReducer(uploadReducer, INITIAL_UPLOAD_STATE),
|
|
58
|
+
_React$useReducer2 = _slicedToArray(_React$useReducer, 2),
|
|
59
|
+
uploadState = _React$useReducer2[0],
|
|
60
|
+
dispatch = _React$useReducer2[1];
|
|
61
|
+
var onUpload = function onUpload(_ref2) {
|
|
62
|
+
var _mediaProvider$upload;
|
|
63
|
+
var file = _ref2.file,
|
|
64
|
+
preview = _ref2.preview;
|
|
65
|
+
onUploadSuccessAnalytics('local');
|
|
66
|
+
var insertPayload = {
|
|
67
|
+
id: file.id,
|
|
68
|
+
collection: (_mediaProvider$upload = mediaProvider.uploadParams) === null || _mediaProvider$upload === void 0 ? void 0 : _mediaProvider$upload.collection,
|
|
69
|
+
occurrenceKey: file.occurrenceKey
|
|
70
|
+
};
|
|
71
|
+
if (isImagePreview(preview)) {
|
|
72
|
+
insertPayload.height = preview.dimensions.height;
|
|
73
|
+
insertPayload.width = preview.dimensions.width;
|
|
74
|
+
}
|
|
75
|
+
onInsert(insertPayload);
|
|
76
|
+
|
|
77
|
+
// Probably not needed but I guess it _could_ fail to close for some reason
|
|
78
|
+
dispatch({
|
|
79
|
+
type: 'reset'
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
var uploadParams = mediaProvider.uploadParams,
|
|
83
|
+
uploadMediaClientConfig = mediaProvider.uploadMediaClientConfig;
|
|
84
|
+
return /*#__PURE__*/React.createElement(Stack, {
|
|
85
|
+
grow: "fill",
|
|
86
|
+
space: "space.200"
|
|
87
|
+
}, uploadState.error && /*#__PURE__*/React.createElement(SectionMessage, {
|
|
88
|
+
appearance: "error"
|
|
89
|
+
}, uploadState.error === 'upload_fail' ? strings.networkError : strings.genericError), /*#__PURE__*/React.createElement(Button, {
|
|
90
|
+
iconBefore: UploadIcon,
|
|
91
|
+
shouldFitContainer: true,
|
|
92
|
+
isDisabled: !uploadMediaClientConfig || !uploadParams,
|
|
93
|
+
onClick: function onClick() {
|
|
94
|
+
onUploadButtonClickedAnalytics();
|
|
95
|
+
dispatch({
|
|
96
|
+
type: 'open'
|
|
97
|
+
});
|
|
98
|
+
},
|
|
99
|
+
autoFocus: true
|
|
100
|
+
}, strings.upload), uploadMediaClientConfig && uploadParams && /*#__PURE__*/React.createElement(Browser, {
|
|
101
|
+
isOpen: uploadState.isOpen,
|
|
102
|
+
config: {
|
|
103
|
+
uploadParams: uploadParams
|
|
104
|
+
},
|
|
105
|
+
mediaClientConfig: uploadMediaClientConfig,
|
|
106
|
+
onUploadsStart: function onUploadsStart() {
|
|
107
|
+
onUploadCommencedAnalytics('local');
|
|
108
|
+
},
|
|
109
|
+
onPreviewUpdate: onUpload
|
|
110
|
+
// NOTE: this will fire for some errors like network failures, but not
|
|
111
|
+
// for others like empty files. Those have their own feedback toast
|
|
112
|
+
// owned by media.
|
|
113
|
+
,
|
|
114
|
+
onError: function onError(payload) {
|
|
115
|
+
onUploadFailureAnalytics(payload.error.name, 'local');
|
|
116
|
+
dispatch({
|
|
117
|
+
type: 'error',
|
|
118
|
+
error: payload.error.name
|
|
119
|
+
});
|
|
120
|
+
},
|
|
121
|
+
onClose: function onClose() {
|
|
122
|
+
dispatch({
|
|
123
|
+
type: 'close'
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}));
|
|
127
|
+
};
|
|
@@ -75,8 +75,8 @@ export function MediaFromURL(_ref) {
|
|
|
75
75
|
insert: intl.formatMessage(mediaInsertMessages.insert),
|
|
76
76
|
pasteLinkToUpload: intl.formatMessage(mediaInsertMessages.pasteLinkToUpload),
|
|
77
77
|
cancel: intl.formatMessage(mediaInsertMessages.cancel),
|
|
78
|
-
errorMessage: intl.formatMessage(mediaInsertMessages.
|
|
79
|
-
warning: intl.formatMessage(mediaInsertMessages.
|
|
78
|
+
errorMessage: intl.formatMessage(mediaInsertMessages.fromUrlErrorMessage),
|
|
79
|
+
warning: intl.formatMessage(mediaInsertMessages.fromUrlWarning)
|
|
80
80
|
};
|
|
81
81
|
var _React$useState = React.useState(''),
|
|
82
82
|
_React$useState2 = _slicedToArray(_React$useState, 2),
|
|
@@ -88,7 +88,8 @@ export function MediaFromURL(_ref) {
|
|
|
88
88
|
dispatch = _React$useReducer2[1];
|
|
89
89
|
var pasteFlag = React.useRef(false);
|
|
90
90
|
var _useAnalyticsEvents = useAnalyticsEvents(dispatchAnalyticsEvent),
|
|
91
|
-
|
|
91
|
+
onUploadButtonClickedAnalytics = _useAnalyticsEvents.onUploadButtonClickedAnalytics,
|
|
92
|
+
onUploadCommencedAnalytics = _useAnalyticsEvents.onUploadCommencedAnalytics,
|
|
92
93
|
onUploadSuccessAnalytics = _useAnalyticsEvents.onUploadSuccessAnalytics,
|
|
93
94
|
onUploadFailureAnalytics = _useAnalyticsEvents.onUploadFailureAnalytics;
|
|
94
95
|
var uploadExternalMedia = React.useCallback( /*#__PURE__*/function () {
|
|
@@ -97,27 +98,28 @@ export function MediaFromURL(_ref) {
|
|
|
97
98
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
98
99
|
while (1) switch (_context.prev = _context.next) {
|
|
99
100
|
case 0:
|
|
101
|
+
onUploadButtonClickedAnalytics();
|
|
100
102
|
dispatch({
|
|
101
103
|
type: 'loading'
|
|
102
104
|
});
|
|
103
105
|
uploadMediaClientConfig = mediaProvider.uploadMediaClientConfig, uploadParams = mediaProvider.uploadParams;
|
|
104
106
|
if (uploadMediaClientConfig) {
|
|
105
|
-
_context.next =
|
|
107
|
+
_context.next = 5;
|
|
106
108
|
break;
|
|
107
109
|
}
|
|
108
110
|
return _context.abrupt("return");
|
|
109
|
-
case
|
|
111
|
+
case 5:
|
|
110
112
|
mediaClient = getMediaClient(uploadMediaClientConfig);
|
|
111
113
|
collection = uploadParams === null || uploadParams === void 0 ? void 0 : uploadParams.collection;
|
|
112
|
-
|
|
113
|
-
_context.prev =
|
|
114
|
-
_context.next =
|
|
114
|
+
onUploadCommencedAnalytics('url');
|
|
115
|
+
_context.prev = 8;
|
|
116
|
+
_context.next = 11;
|
|
115
117
|
return mediaClient.file.uploadExternal(url, collection);
|
|
116
|
-
case
|
|
118
|
+
case 11:
|
|
117
119
|
_yield$mediaClient$fi = _context.sent;
|
|
118
120
|
uploadableFileUpfrontIds = _yield$mediaClient$fi.uploadableFileUpfrontIds;
|
|
119
121
|
dimensions = _yield$mediaClient$fi.dimensions;
|
|
120
|
-
onUploadSuccessAnalytics();
|
|
122
|
+
onUploadSuccessAnalytics('url');
|
|
121
123
|
dispatch({
|
|
122
124
|
type: 'success',
|
|
123
125
|
payload: {
|
|
@@ -128,16 +130,16 @@ export function MediaFromURL(_ref) {
|
|
|
128
130
|
occurrenceKey: uploadableFileUpfrontIds.occurrenceKey
|
|
129
131
|
}
|
|
130
132
|
});
|
|
131
|
-
_context.next =
|
|
133
|
+
_context.next = 21;
|
|
132
134
|
break;
|
|
133
|
-
case
|
|
134
|
-
_context.prev =
|
|
135
|
-
_context.t0 = _context["catch"](
|
|
135
|
+
case 18:
|
|
136
|
+
_context.prev = 18;
|
|
137
|
+
_context.t0 = _context["catch"](8);
|
|
136
138
|
if (typeof _context.t0 === 'string' && _context.t0 === 'Could not download remote file') {
|
|
137
139
|
// TODO: Make sure this gets good unit test coverage with the actual
|
|
138
140
|
// media plugin. This hard coded error message could be changed at any
|
|
139
141
|
// point and we need a unit test to break to stop people changing it.
|
|
140
|
-
onUploadFailureAnalytics(_context.t0);
|
|
142
|
+
onUploadFailureAnalytics(_context.t0, 'url');
|
|
141
143
|
dispatch({
|
|
142
144
|
type: 'warning',
|
|
143
145
|
warning: _context.t0,
|
|
@@ -145,28 +147,28 @@ export function MediaFromURL(_ref) {
|
|
|
145
147
|
});
|
|
146
148
|
} else if (_context.t0 instanceof Error) {
|
|
147
149
|
message = 'Image preview fetch failed';
|
|
148
|
-
onUploadFailureAnalytics(message);
|
|
150
|
+
onUploadFailureAnalytics(message, 'url');
|
|
149
151
|
dispatch({
|
|
150
152
|
type: 'error',
|
|
151
153
|
error: message
|
|
152
154
|
});
|
|
153
155
|
} else {
|
|
154
|
-
onUploadFailureAnalytics('Unknown error');
|
|
156
|
+
onUploadFailureAnalytics('Unknown error', 'url');
|
|
155
157
|
dispatch({
|
|
156
158
|
type: 'error',
|
|
157
159
|
error: 'Unknown error'
|
|
158
160
|
});
|
|
159
161
|
}
|
|
160
|
-
case
|
|
162
|
+
case 21:
|
|
161
163
|
case "end":
|
|
162
164
|
return _context.stop();
|
|
163
165
|
}
|
|
164
|
-
}, _callee, null, [[
|
|
166
|
+
}, _callee, null, [[8, 18]]);
|
|
165
167
|
}));
|
|
166
168
|
return function (_x) {
|
|
167
169
|
return _ref2.apply(this, arguments);
|
|
168
170
|
};
|
|
169
|
-
}(), [
|
|
171
|
+
}(), [onUploadButtonClickedAnalytics, mediaProvider, onUploadCommencedAnalytics, onUploadSuccessAnalytics, onUploadFailureAnalytics, inputUrl]);
|
|
170
172
|
var onURLChange = React.useCallback(function (e) {
|
|
171
173
|
var url = e.target.value;
|
|
172
174
|
setUrl(url);
|
|
@@ -3,7 +3,8 @@ import { useIntl } from 'react-intl-next';
|
|
|
3
3
|
import { mediaInsertMessages } from '@atlaskit/editor-common/messages';
|
|
4
4
|
import { Box } from '@atlaskit/primitives';
|
|
5
5
|
import Tabs, { Tab, TabList, TabPanel } from '@atlaskit/tabs';
|
|
6
|
-
import {
|
|
6
|
+
import { LocalMedia } from './LocalMedia';
|
|
7
|
+
import { MediaFromURL } from './MediaFromURL';
|
|
7
8
|
export var MediaInsertContent = function MediaInsertContent(_ref) {
|
|
8
9
|
var mediaProvider = _ref.mediaProvider,
|
|
9
10
|
dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent,
|
|
@@ -13,7 +14,12 @@ export var MediaInsertContent = function MediaInsertContent(_ref) {
|
|
|
13
14
|
id: "media-insert-tab-navigation"
|
|
14
15
|
}, /*#__PURE__*/React.createElement(Box, {
|
|
15
16
|
paddingBlockEnd: "space.150"
|
|
16
|
-
}, /*#__PURE__*/React.createElement(TabList, null, /*#__PURE__*/React.createElement(Tab, null, intl.formatMessage(mediaInsertMessages.linkTabTitle)))), /*#__PURE__*/React.createElement(TabPanel, null, /*#__PURE__*/React.createElement(
|
|
17
|
+
}, /*#__PURE__*/React.createElement(TabList, null, /*#__PURE__*/React.createElement(Tab, null, intl.formatMessage(mediaInsertMessages.fileTabTitle)), /*#__PURE__*/React.createElement(Tab, null, intl.formatMessage(mediaInsertMessages.linkTabTitle)))), /*#__PURE__*/React.createElement(TabPanel, null, /*#__PURE__*/React.createElement(LocalMedia, {
|
|
18
|
+
mediaProvider: mediaProvider,
|
|
19
|
+
onInsert: function onInsert() {},
|
|
20
|
+
onClose: closeMediaInsertPicker,
|
|
21
|
+
dispatchAnalyticsEvent: dispatchAnalyticsEvent
|
|
22
|
+
})), /*#__PURE__*/React.createElement(TabPanel, null, /*#__PURE__*/React.createElement(MediaFromURL, {
|
|
17
23
|
mediaProvider: mediaProvider,
|
|
18
24
|
onExternalInsert: function onExternalInsert() {},
|
|
19
25
|
onInsert: function onInsert() {},
|
|
@@ -6,6 +6,7 @@ import { mediaInsertMessages } from '@atlaskit/editor-common/messages';
|
|
|
6
6
|
import { Popup, withOuterListeners } from '@atlaskit/editor-common/ui';
|
|
7
7
|
import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
|
|
8
8
|
import { akEditorFloatingDialogZIndex } from '@atlaskit/editor-shared-styles';
|
|
9
|
+
import { useFocusEditor } from '../hooks/use-focus-editor';
|
|
9
10
|
import { MediaInsertContent } from './MediaInsertContent';
|
|
10
11
|
import { MediaInsertWrapper } from './MediaInsertWrapper';
|
|
11
12
|
var PopupWithListeners = withOuterListeners(Popup);
|
|
@@ -40,11 +41,14 @@ export var MediaInsertPicker = function MediaInsertPicker(_ref) {
|
|
|
40
41
|
popupsMountPoint = _ref.popupsMountPoint,
|
|
41
42
|
popupsBoundariesElement = _ref.popupsBoundariesElement,
|
|
42
43
|
popupsScrollableElement = _ref.popupsScrollableElement,
|
|
43
|
-
|
|
44
|
+
_closeMediaInsertPicker = _ref.closeMediaInsertPicker;
|
|
44
45
|
var targetRef = getDomRefFromSelection(editorView, dispatchAnalyticsEvent);
|
|
45
46
|
var isOpen = (_useSharedPluginState = useSharedPluginState(api, ['mediaInsert'])) === null || _useSharedPluginState === void 0 || (_useSharedPluginState = _useSharedPluginState.mediaInsertState) === null || _useSharedPluginState === void 0 ? void 0 : _useSharedPluginState.isOpen;
|
|
46
47
|
var mediaProvider = (_useSharedPluginState2 = useSharedPluginState(api, ['media'])) === null || _useSharedPluginState2 === void 0 || (_useSharedPluginState2 = _useSharedPluginState2.mediaState) === null || _useSharedPluginState2 === void 0 ? void 0 : _useSharedPluginState2.mediaProvider;
|
|
47
48
|
var intl = useIntl();
|
|
49
|
+
var focusEditor = useFocusEditor({
|
|
50
|
+
editorView: editorView
|
|
51
|
+
});
|
|
48
52
|
if (!isOpen || !mediaProvider) {
|
|
49
53
|
return null;
|
|
50
54
|
}
|
|
@@ -63,7 +67,8 @@ export var MediaInsertPicker = function MediaInsertPicker(_ref) {
|
|
|
63
67
|
};
|
|
64
68
|
dispatchAnalyticsEvent(payload);
|
|
65
69
|
}
|
|
66
|
-
|
|
70
|
+
_closeMediaInsertPicker();
|
|
71
|
+
focusEditor();
|
|
67
72
|
};
|
|
68
73
|
};
|
|
69
74
|
return /*#__PURE__*/React.createElement(PopupWithListeners, {
|
|
@@ -83,6 +88,9 @@ export var MediaInsertPicker = function MediaInsertPicker(_ref) {
|
|
|
83
88
|
}, /*#__PURE__*/React.createElement(MediaInsertWrapper, null, /*#__PURE__*/React.createElement(MediaInsertContent, {
|
|
84
89
|
mediaProvider: mediaProvider,
|
|
85
90
|
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
86
|
-
closeMediaInsertPicker: closeMediaInsertPicker
|
|
91
|
+
closeMediaInsertPicker: function closeMediaInsertPicker() {
|
|
92
|
+
_closeMediaInsertPicker();
|
|
93
|
+
focusEditor();
|
|
94
|
+
}
|
|
87
95
|
})));
|
|
88
96
|
};
|
|
@@ -1,38 +1,54 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
3
3
|
export function useAnalyticsEvents(dispatchAnalyticsEvent) {
|
|
4
|
-
var
|
|
4
|
+
var onUploadButtonClickedAnalytics = React.useCallback(function () {
|
|
5
5
|
dispatchAnalyticsEvent === null || dispatchAnalyticsEvent === void 0 || dispatchAnalyticsEvent({
|
|
6
6
|
action: ACTION.CLICKED,
|
|
7
7
|
actionSubject: ACTION_SUBJECT.BUTTON,
|
|
8
|
-
actionSubjectId: ACTION_SUBJECT_ID.
|
|
8
|
+
actionSubjectId: ACTION_SUBJECT_ID.UPLOAD_MEDIA,
|
|
9
9
|
eventType: EVENT_TYPE.UI
|
|
10
10
|
});
|
|
11
11
|
}, [dispatchAnalyticsEvent]);
|
|
12
|
-
var
|
|
12
|
+
var onUploadCommencedAnalytics = React.useCallback(function (mediaUploadSource) {
|
|
13
|
+
dispatchAnalyticsEvent === null || dispatchAnalyticsEvent === void 0 || dispatchAnalyticsEvent({
|
|
14
|
+
action: ACTION.UPLOAD_COMMENCED,
|
|
15
|
+
actionSubject: ACTION_SUBJECT.MEDIA,
|
|
16
|
+
actionSubjectId: ACTION_SUBJECT_ID.UPLOAD_MEDIA,
|
|
17
|
+
eventType: EVENT_TYPE.OPERATIONAL,
|
|
18
|
+
attributes: {
|
|
19
|
+
mediaUploadSource: mediaUploadSource
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}, [dispatchAnalyticsEvent]);
|
|
23
|
+
var onUploadSuccessAnalytics = React.useCallback(function (mediaUploadSource) {
|
|
13
24
|
dispatchAnalyticsEvent === null || dispatchAnalyticsEvent === void 0 || dispatchAnalyticsEvent({
|
|
14
25
|
action: ACTION.UPLOAD_SUCCEEDED,
|
|
15
26
|
actionSubject: ACTION_SUBJECT.MEDIA,
|
|
16
|
-
actionSubjectId: ACTION_SUBJECT_ID.
|
|
17
|
-
eventType: EVENT_TYPE.OPERATIONAL
|
|
27
|
+
actionSubjectId: ACTION_SUBJECT_ID.UPLOAD_MEDIA,
|
|
28
|
+
eventType: EVENT_TYPE.OPERATIONAL,
|
|
29
|
+
attributes: {
|
|
30
|
+
mediaUploadSource: mediaUploadSource
|
|
31
|
+
}
|
|
18
32
|
});
|
|
19
33
|
}, [dispatchAnalyticsEvent]);
|
|
20
|
-
var onUploadFailureAnalytics = React.useCallback(function (reason) {
|
|
34
|
+
var onUploadFailureAnalytics = React.useCallback(function (reason, mediaUploadSource) {
|
|
21
35
|
dispatchAnalyticsEvent === null || dispatchAnalyticsEvent === void 0 || dispatchAnalyticsEvent({
|
|
22
36
|
action: ACTION.UPLOAD_FAILED,
|
|
23
37
|
actionSubject: ACTION_SUBJECT.MEDIA,
|
|
24
|
-
actionSubjectId: ACTION_SUBJECT_ID.
|
|
38
|
+
actionSubjectId: ACTION_SUBJECT_ID.UPLOAD_MEDIA,
|
|
25
39
|
eventType: EVENT_TYPE.OPERATIONAL,
|
|
26
40
|
attributes: {
|
|
27
|
-
reason: reason
|
|
41
|
+
reason: reason,
|
|
42
|
+
mediaUploadSource: mediaUploadSource
|
|
28
43
|
}
|
|
29
44
|
});
|
|
30
45
|
}, [dispatchAnalyticsEvent]);
|
|
31
46
|
return React.useMemo(function () {
|
|
32
47
|
return {
|
|
33
|
-
|
|
48
|
+
onUploadButtonClickedAnalytics: onUploadButtonClickedAnalytics,
|
|
49
|
+
onUploadCommencedAnalytics: onUploadCommencedAnalytics,
|
|
34
50
|
onUploadSuccessAnalytics: onUploadSuccessAnalytics,
|
|
35
51
|
onUploadFailureAnalytics: onUploadFailureAnalytics
|
|
36
52
|
};
|
|
37
|
-
}, [
|
|
53
|
+
}, [onUploadButtonClickedAnalytics, onUploadCommencedAnalytics, onUploadSuccessAnalytics, onUploadFailureAnalytics]);
|
|
38
54
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { type DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
|
|
3
|
+
import type { MediaProvider } from '@atlaskit/editor-common/provider-factory';
|
|
4
|
+
import { type OnInsertAttrs } from './types';
|
|
5
|
+
type Props = {
|
|
6
|
+
mediaProvider: MediaProvider;
|
|
7
|
+
onInsert: (attrs: OnInsertAttrs) => void;
|
|
8
|
+
onClose: () => void;
|
|
9
|
+
dispatchAnalyticsEvent?: DispatchAnalyticsEvent;
|
|
10
|
+
};
|
|
11
|
+
export declare const LocalMedia: ({ mediaProvider, onInsert, dispatchAnalyticsEvent }: Props) => JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { MediaProvider } from '@atlaskit/editor-common/provider-factory';
|
|
3
3
|
import { type OnInsertAttrs } from './types';
|
|
4
4
|
type Props = {
|
|
5
|
-
attrs: OnInsertAttrs
|
|
5
|
+
attrs: Required<OnInsertAttrs>;
|
|
6
6
|
mediaProvider: MediaProvider;
|
|
7
7
|
};
|
|
8
8
|
export declare const MediaCard: ({ attrs, mediaProvider }: Props) => JSX.Element;
|