@atlaskit/editor-plugin-media 8.6.1 → 8.7.1
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/mediaPlugin.js +76 -43
- package/dist/cjs/pm-plugins/actions.js +3 -1
- package/dist/cjs/pm-plugins/commands.js +23 -1
- package/dist/cjs/pm-plugins/main.js +16 -0
- package/dist/cjs/ui/CaptionPlaceholder/index.js +2 -2
- package/dist/cjs/ui/ImageEditor/ModalWrapper.js +69 -0
- package/dist/cjs/ui/ImageEditor/index.js +62 -0
- package/dist/cjs/ui/toolbar/index.js +24 -11
- package/dist/es2019/mediaPlugin.js +38 -3
- package/dist/es2019/pm-plugins/actions.js +3 -1
- package/dist/es2019/pm-plugins/commands.js +22 -0
- package/dist/es2019/pm-plugins/main.js +14 -0
- package/dist/es2019/ui/CaptionPlaceholder/index.js +2 -2
- package/dist/es2019/ui/ImageEditor/ModalWrapper.js +58 -0
- package/dist/es2019/ui/ImageEditor/index.js +53 -0
- package/dist/es2019/ui/toolbar/index.js +20 -6
- package/dist/esm/mediaPlugin.js +77 -44
- package/dist/esm/pm-plugins/actions.js +3 -1
- package/dist/esm/pm-plugins/commands.js +22 -0
- package/dist/esm/pm-plugins/main.js +16 -0
- package/dist/esm/ui/CaptionPlaceholder/index.js +2 -2
- package/dist/esm/ui/ImageEditor/ModalWrapper.js +60 -0
- package/dist/esm/ui/ImageEditor/index.js +52 -0
- package/dist/esm/ui/toolbar/index.js +23 -10
- package/dist/types/mediaPluginType.d.ts +2 -0
- package/dist/types/pm-plugins/actions.d.ts +2 -0
- package/dist/types/pm-plugins/commands.d.ts +2 -0
- package/dist/types/pm-plugins/main.d.ts +4 -1
- package/dist/types/pm-plugins/types.d.ts +3 -0
- package/dist/types/ui/ImageEditor/ModalWrapper.d.ts +13 -0
- package/dist/types/ui/ImageEditor/index.d.ts +12 -0
- package/dist/types/ui/toolbar/index.d.ts +4 -0
- package/dist/types-ts4.5/mediaPluginType.d.ts +2 -0
- package/dist/types-ts4.5/pm-plugins/actions.d.ts +2 -0
- package/dist/types-ts4.5/pm-plugins/commands.d.ts +2 -0
- package/dist/types-ts4.5/pm-plugins/main.d.ts +4 -1
- package/dist/types-ts4.5/pm-plugins/types.d.ts +3 -0
- package/dist/types-ts4.5/ui/ImageEditor/ModalWrapper.d.ts +13 -0
- package/dist/types-ts4.5/ui/ImageEditor/index.d.ts +12 -0
- package/dist/types-ts4.5/ui/toolbar/index.d.ts +4 -0
- package/package.json +4 -3
|
@@ -30,4 +30,26 @@ export const trackMediaPaste = attrs => ({
|
|
|
30
30
|
identifier
|
|
31
31
|
});
|
|
32
32
|
return tr;
|
|
33
|
+
};
|
|
34
|
+
export const showImageEditor = media => ({
|
|
35
|
+
tr
|
|
36
|
+
}) => {
|
|
37
|
+
tr.setMeta(stateKey, {
|
|
38
|
+
type: ACTIONS.SHOW_IMAGE_EDITOR,
|
|
39
|
+
imageEditorSelectedMedia: media,
|
|
40
|
+
isImageEditorVisible: true
|
|
41
|
+
});
|
|
42
|
+
tr.setMeta('addToHistory', false);
|
|
43
|
+
return tr;
|
|
44
|
+
};
|
|
45
|
+
export const hideImageEditor = ({
|
|
46
|
+
tr
|
|
47
|
+
}) => {
|
|
48
|
+
tr.setMeta(stateKey, {
|
|
49
|
+
type: ACTIONS.HIDE_IMAGE_EDITOR,
|
|
50
|
+
imageEditorSelectedMedia: null,
|
|
51
|
+
isImageEditorVisible: false
|
|
52
|
+
});
|
|
53
|
+
tr.setMeta('addToHistory', false);
|
|
54
|
+
return tr;
|
|
33
55
|
};
|
|
@@ -67,6 +67,7 @@ export class MediaPluginStateImplementation {
|
|
|
67
67
|
_defineProperty(this, "allowInlineImages", false);
|
|
68
68
|
_defineProperty(this, "uploadInProgressSubscriptions", []);
|
|
69
69
|
_defineProperty(this, "uploadInProgressSubscriptionsNotified", false);
|
|
70
|
+
_defineProperty(this, "isImageEditorVisible", false);
|
|
70
71
|
// this is only a temporary variable, which gets cleared after the last inserted node has been selected
|
|
71
72
|
_defineProperty(this, "lastAddedMediaSingleFileIds", []);
|
|
72
73
|
_defineProperty(this, "destroyed", false);
|
|
@@ -568,6 +569,9 @@ export class MediaPluginStateImplementation {
|
|
|
568
569
|
setResizingWidth(width) {
|
|
569
570
|
this.resizingWidth = width;
|
|
570
571
|
}
|
|
572
|
+
setImageEditorVisibility(isVisible) {
|
|
573
|
+
this.isImageEditorVisible = isVisible;
|
|
574
|
+
}
|
|
571
575
|
updateElement() {
|
|
572
576
|
let newElement;
|
|
573
577
|
const selectedContainer = this.selectedMediaContainerNode();
|
|
@@ -771,6 +775,16 @@ export const createPlugin = (_schema, options, getIntl, pluginInjectionApi, node
|
|
|
771
775
|
nextPluginState = pluginState.clone();
|
|
772
776
|
}
|
|
773
777
|
break;
|
|
778
|
+
case ACTIONS.SHOW_IMAGE_EDITOR:
|
|
779
|
+
pluginState.imageEditorSelectedMedia = meta.imageEditorSelectedMedia;
|
|
780
|
+
pluginState.isImageEditorVisible = meta.isImageEditorVisible;
|
|
781
|
+
nextPluginState = nextPluginState.clone();
|
|
782
|
+
break;
|
|
783
|
+
case ACTIONS.HIDE_IMAGE_EDITOR:
|
|
784
|
+
pluginState.imageEditorSelectedMedia = undefined;
|
|
785
|
+
pluginState.isImageEditorVisible = meta.isImageEditorVisible;
|
|
786
|
+
nextPluginState = nextPluginState.clone();
|
|
787
|
+
break;
|
|
774
788
|
}
|
|
775
789
|
|
|
776
790
|
// NOTE: We're not calling passing new state to the Editor, because we depend on the view.state reference
|
|
@@ -52,7 +52,7 @@ export const CaptionPlaceholder = /*#__PURE__*/React.forwardRef(({
|
|
|
52
52
|
// This id is just used for setting styles at the moment, if it's needed for anything more specific
|
|
53
53
|
// It may need to be generated to avoid overlap
|
|
54
54
|
,
|
|
55
|
-
id: expValEquals('cc_editor_ai_content_mode', 'variant', 'test') && fg('platform_editor_content_mode_button_mvp') ? CAPTION_PLACEHOLDER_ID : undefined,
|
|
55
|
+
id: expValEquals('confluence_compact_text_format', 'isEnabled', true) || expValEquals('cc_editor_ai_content_mode', 'variant', 'test') && fg('platform_editor_content_mode_button_mvp') ? CAPTION_PLACEHOLDER_ID : undefined,
|
|
56
56
|
"data-id": CAPTION_PLACEHOLDER_ID,
|
|
57
57
|
"data-testid": "caption-placeholder"
|
|
58
58
|
}, jsx(FormattedMessage
|
|
@@ -81,7 +81,7 @@ export const CaptionPlaceholderButton = /*#__PURE__*/React.forwardRef(({
|
|
|
81
81
|
testId: "caption-placeholder",
|
|
82
82
|
padding: "space.0",
|
|
83
83
|
xcss: placeholderButton
|
|
84
|
-
}, expValEquals('cc_editor_ai_content_mode', 'variant', 'test') && fg('platform_editor_content_mode_button_mvp') ?
|
|
84
|
+
}, expValEquals('confluence_compact_text_format', 'isEnabled', true) || expValEquals('cc_editor_ai_content_mode', 'variant', 'test') && fg('platform_editor_content_mode_button_mvp') ?
|
|
85
85
|
// This id is just used for setting styles at the moment, if it's needed for anything more specific
|
|
86
86
|
// It may need to be generated to avoid overlap
|
|
87
87
|
// eslint-disable-next-line @atlaskit/design-system/use-primitives-text
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { MediaClient } from '@atlaskit/media-client';
|
|
3
|
+
import { isExternalMedia } from '../toolbar/utils';
|
|
4
|
+
import { ImageEditor } from './index';
|
|
5
|
+
export const RenderImageEditor = ({
|
|
6
|
+
mediaClientConfig,
|
|
7
|
+
onClose,
|
|
8
|
+
selectedNodeAttrs,
|
|
9
|
+
errorReporter,
|
|
10
|
+
// TODO: EDITOR-3779 - To implement saving image
|
|
11
|
+
// eslint-disable-next-line
|
|
12
|
+
onSave
|
|
13
|
+
}) => {
|
|
14
|
+
const [imageUrl, setImageUrl] = useState('');
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
const getImageUrl = () => {
|
|
17
|
+
if (isExternalMedia(selectedNodeAttrs)) {
|
|
18
|
+
// External image - use the URL directly
|
|
19
|
+
setImageUrl(selectedNodeAttrs.url || '');
|
|
20
|
+
} else {
|
|
21
|
+
// File media - use MediaClient to get the image URL
|
|
22
|
+
const {
|
|
23
|
+
id,
|
|
24
|
+
collection = ''
|
|
25
|
+
} = selectedNodeAttrs;
|
|
26
|
+
try {
|
|
27
|
+
const mediaClient = new MediaClient(mediaClientConfig);
|
|
28
|
+
|
|
29
|
+
// Subscribe to file state to get file information
|
|
30
|
+
const subscription = mediaClient.file.getFileState(id, {
|
|
31
|
+
collectionName: collection
|
|
32
|
+
}).subscribe(fileState => {
|
|
33
|
+
if (fileState.status === 'processed' || fileState.status === 'processing') {
|
|
34
|
+
// Get the image URL from the processed file
|
|
35
|
+
mediaClient.file.getFileBinaryURL(id, collection).then(url => {
|
|
36
|
+
setImageUrl(url);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Cleanup subscription on unmount
|
|
42
|
+
return () => subscription.unsubscribe();
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (errorReporter) {
|
|
45
|
+
errorReporter.captureException(error instanceof Error ? error : new Error(String(error)));
|
|
46
|
+
}
|
|
47
|
+
setImageUrl('');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
getImageUrl();
|
|
52
|
+
}, [selectedNodeAttrs, mediaClientConfig, errorReporter]);
|
|
53
|
+
return /*#__PURE__*/React.createElement(ImageEditor, {
|
|
54
|
+
isOpen: true,
|
|
55
|
+
onClose: onClose,
|
|
56
|
+
imageUrl: imageUrl
|
|
57
|
+
});
|
|
58
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jsxRuntime classic
|
|
3
|
+
* @jsx jsx
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
|
|
7
|
+
import { css, jsx } from '@emotion/react';
|
|
8
|
+
import { FormattedMessage } from 'react-intl-next';
|
|
9
|
+
import Button from '@atlaskit/button/new';
|
|
10
|
+
import Modal, { ModalBody, ModalFooter, ModalTransition } from '@atlaskit/modal-dialog';
|
|
11
|
+
const imageWrapper = css({
|
|
12
|
+
maxHeight: 'calc(100vh - 250px)',
|
|
13
|
+
width: '100%',
|
|
14
|
+
overflow: 'hidden',
|
|
15
|
+
display: 'flex',
|
|
16
|
+
justifyContent: 'center',
|
|
17
|
+
alignItems: 'center'
|
|
18
|
+
});
|
|
19
|
+
const imageStyle = css({
|
|
20
|
+
maxWidth: '100%',
|
|
21
|
+
maxHeight: 'calc(100vh - 250px)',
|
|
22
|
+
width: 'auto',
|
|
23
|
+
height: 'auto',
|
|
24
|
+
objectFit: 'contain'
|
|
25
|
+
});
|
|
26
|
+
export const ImageEditor = ({
|
|
27
|
+
isOpen,
|
|
28
|
+
onClose,
|
|
29
|
+
imageUrl
|
|
30
|
+
}) => {
|
|
31
|
+
return jsx(ModalTransition, null, isOpen && jsx(Modal, {
|
|
32
|
+
onClose: onClose,
|
|
33
|
+
width: 1800
|
|
34
|
+
}, jsx("br", null), jsx(ModalBody, null, jsx("div", {
|
|
35
|
+
css: imageWrapper
|
|
36
|
+
}, imageUrl && jsx("img", {
|
|
37
|
+
src: imageUrl,
|
|
38
|
+
alt: "Edit preview",
|
|
39
|
+
css: imageStyle
|
|
40
|
+
}))), jsx(ModalFooter, null, jsx(Button, {
|
|
41
|
+
appearance: "subtle",
|
|
42
|
+
onClick: onClose
|
|
43
|
+
}, jsx(FormattedMessage, {
|
|
44
|
+
id: "editor.imageEditor.cancel",
|
|
45
|
+
defaultMessage: "Cancel"
|
|
46
|
+
})), jsx(Button, {
|
|
47
|
+
appearance: "primary",
|
|
48
|
+
onClick: onClose
|
|
49
|
+
}, jsx(FormattedMessage, {
|
|
50
|
+
id: "editor.imageEditor.done",
|
|
51
|
+
defaultMessage: "Done"
|
|
52
|
+
})))));
|
|
53
|
+
};
|
|
@@ -109,6 +109,16 @@ export const handleShowMediaViewer = ({
|
|
|
109
109
|
}
|
|
110
110
|
api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : api.media.commands.showMediaViewer(selectedNodeAttrs));
|
|
111
111
|
};
|
|
112
|
+
export const handleShowImageEditor = ({
|
|
113
|
+
api,
|
|
114
|
+
mediaPluginState
|
|
115
|
+
}) => {
|
|
116
|
+
const selectedNodeAttrs = getSelectedNearestMediaContainerNodeAttrs(mediaPluginState);
|
|
117
|
+
if (!selectedNodeAttrs) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : api.media.commands.showImageEditor(selectedNodeAttrs));
|
|
121
|
+
};
|
|
112
122
|
const generateMediaCardFloatingToolbar = (state, intl, mediaPluginState, hoverDecoration, pluginInjectionApi, editorAnalyticsAPI, forceFocusSelector, isViewOnly) => {
|
|
113
123
|
var _pluginInjectionApi$c, _pluginInjectionApi$c2, _pluginInjectionApi$c3;
|
|
114
124
|
const disableDownloadButton = getIsDownloadDisabledByDataSecurityPolicy(mediaPluginState);
|
|
@@ -563,9 +573,11 @@ const generateMediaSingleFloatingToolbar = (state, intl, options, pluginState, m
|
|
|
563
573
|
icon: ImageCropIcon,
|
|
564
574
|
title: intl.formatMessage(commonMessages.imageEdit),
|
|
565
575
|
onClick: () => {
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
576
|
+
var _handleShowImageEdito;
|
|
577
|
+
return (_handleShowImageEdito = handleShowImageEditor({
|
|
578
|
+
api: pluginInjectionApi,
|
|
579
|
+
mediaPluginState: pluginState
|
|
580
|
+
})) !== null && _handleShowImageEdito !== void 0 ? _handleShowImageEdito : false;
|
|
569
581
|
},
|
|
570
582
|
supportsViewMode: false
|
|
571
583
|
});
|
|
@@ -721,9 +733,11 @@ const generateMediaSingleFloatingToolbar = (state, intl, options, pluginState, m
|
|
|
721
733
|
icon: ImageCropIcon,
|
|
722
734
|
title: intl.formatMessage(commonMessages.imageEdit),
|
|
723
735
|
onClick: () => {
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
736
|
+
var _handleShowImageEdito2;
|
|
737
|
+
return (_handleShowImageEdito2 = handleShowImageEditor({
|
|
738
|
+
api: pluginInjectionApi,
|
|
739
|
+
mediaPluginState: pluginState
|
|
740
|
+
})) !== null && _handleShowImageEdito2 !== void 0 ? _handleShowImageEdito2 : false;
|
|
727
741
|
},
|
|
728
742
|
supportsViewMode: false
|
|
729
743
|
}, {
|
package/dist/esm/mediaPlugin.js
CHANGED
|
@@ -6,6 +6,7 @@ import { areToolbarFlagsEnabled } from '@atlaskit/editor-common/toolbar-flag-che
|
|
|
6
6
|
import { NodeSelection, PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
7
7
|
import { getMediaFeatureFlag } from '@atlaskit/media-common';
|
|
8
8
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
9
|
+
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
9
10
|
import { lazyMediaView } from './nodeviews/lazy-media';
|
|
10
11
|
import { lazyMediaGroupView } from './nodeviews/lazy-media-group';
|
|
11
12
|
import { lazyMediaInlineView } from './nodeviews/lazy-media-inline';
|
|
@@ -16,7 +17,7 @@ import { mediaInlineSpecWithFixedToDOM } from './nodeviews/toDOM-fixes/mediaInli
|
|
|
16
17
|
import { mediaSingleSpecWithFixedToDOM } from './nodeviews/toDOM-fixes/mediaSingle';
|
|
17
18
|
import { createPlugin as createMediaAltTextPlugin } from './pm-plugins/alt-text';
|
|
18
19
|
import keymapMediaAltTextPlugin from './pm-plugins/alt-text/keymap';
|
|
19
|
-
import { hideMediaViewer, showMediaViewer, trackMediaPaste } from './pm-plugins/commands';
|
|
20
|
+
import { hideMediaViewer, showMediaViewer, trackMediaPaste, hideImageEditor, showImageEditor } from './pm-plugins/commands';
|
|
20
21
|
import keymapPlugin from './pm-plugins/keymap';
|
|
21
22
|
import keymapMediaSinglePlugin from './pm-plugins/keymap-media';
|
|
22
23
|
import linkingPlugin from './pm-plugins/linking';
|
|
@@ -26,6 +27,7 @@ import { createPlugin as createMediaPixelResizingPlugin } from './pm-plugins/pix
|
|
|
26
27
|
import { stateKey } from './pm-plugins/plugin-key';
|
|
27
28
|
import { createMediaIdentifierArray, extractMediaNodes } from './pm-plugins/utils/media-common';
|
|
28
29
|
import { insertMediaAsMediaSingle as _insertMediaAsMediaSingle } from './pm-plugins/utils/media-single';
|
|
30
|
+
import { RenderImageEditor } from './ui/ImageEditor/ModalWrapper';
|
|
29
31
|
import { MediaPickerComponents } from './ui/MediaPicker';
|
|
30
32
|
import { RenderMediaViewer } from './ui/MediaViewer/PortalWrapper';
|
|
31
33
|
import { floatingToolbar as _floatingToolbar } from './ui/toolbar';
|
|
@@ -95,10 +97,36 @@ var MediaViewerFunctionalComponent = function MediaViewerFunctionalComponent(_re
|
|
|
95
97
|
items: mediaItems
|
|
96
98
|
});
|
|
97
99
|
};
|
|
98
|
-
|
|
99
|
-
var
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
var imageEditorStateSelector = function imageEditorStateSelector(states) {
|
|
101
|
+
var _states$mediaState6, _states$mediaState7, _states$mediaState8;
|
|
102
|
+
return {
|
|
103
|
+
isImageEditorVisible: (_states$mediaState6 = states.mediaState) === null || _states$mediaState6 === void 0 ? void 0 : _states$mediaState6.isImageEditorVisible,
|
|
104
|
+
imageEditorSelectedMedia: (_states$mediaState7 = states.mediaState) === null || _states$mediaState7 === void 0 ? void 0 : _states$mediaState7.imageEditorSelectedMedia,
|
|
105
|
+
mediaClientConfig: (_states$mediaState8 = states.mediaState) === null || _states$mediaState8 === void 0 ? void 0 : _states$mediaState8.mediaClientConfig
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
var ImageEditorFunctionalComponent = function ImageEditorFunctionalComponent(_ref3) {
|
|
109
|
+
var api = _ref3.api;
|
|
110
|
+
var _useSharedPluginState3 = useSharedPluginStateWithSelector(api, ['media'], imageEditorStateSelector),
|
|
111
|
+
isImageEditorVisible = _useSharedPluginState3.isImageEditorVisible,
|
|
112
|
+
imageEditorSelectedMedia = _useSharedPluginState3.imageEditorSelectedMedia,
|
|
113
|
+
mediaClientConfig = _useSharedPluginState3.mediaClientConfig;
|
|
114
|
+
if (!isImageEditorVisible || !imageEditorSelectedMedia || !mediaClientConfig) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
var handleOnClose = function handleOnClose() {
|
|
118
|
+
api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.media.commands.hideImageEditor);
|
|
119
|
+
};
|
|
120
|
+
return /*#__PURE__*/React.createElement(RenderImageEditor, {
|
|
121
|
+
mediaClientConfig: mediaClientConfig,
|
|
122
|
+
onClose: handleOnClose,
|
|
123
|
+
selectedNodeAttrs: imageEditorSelectedMedia
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
export var mediaPlugin = function mediaPlugin(_ref4) {
|
|
127
|
+
var _ref4$config = _ref4.config,
|
|
128
|
+
options = _ref4$config === void 0 ? {} : _ref4$config,
|
|
129
|
+
api = _ref4.api;
|
|
102
130
|
var previousMediaProvider;
|
|
103
131
|
var mediaErrorLocalIds = new Set();
|
|
104
132
|
return {
|
|
@@ -139,8 +167,8 @@ export var mediaPlugin = function mediaPlugin(_ref3) {
|
|
|
139
167
|
return false;
|
|
140
168
|
}
|
|
141
169
|
previousMediaProvider = provider;
|
|
142
|
-
return (_api$core$actions$exe = api === null || api === void 0 ? void 0 : api.core.actions.execute(function (
|
|
143
|
-
var tr =
|
|
170
|
+
return (_api$core$actions$exe = api === null || api === void 0 ? void 0 : api.core.actions.execute(function (_ref5) {
|
|
171
|
+
var tr = _ref5.tr;
|
|
144
172
|
return tr.setMeta(stateKey, {
|
|
145
173
|
mediaProvider: provider
|
|
146
174
|
});
|
|
@@ -150,19 +178,21 @@ export var mediaPlugin = function mediaPlugin(_ref3) {
|
|
|
150
178
|
commands: {
|
|
151
179
|
showMediaViewer: showMediaViewer,
|
|
152
180
|
hideMediaViewer: hideMediaViewer,
|
|
153
|
-
trackMediaPaste: trackMediaPaste
|
|
181
|
+
trackMediaPaste: trackMediaPaste,
|
|
182
|
+
showImageEditor: showImageEditor,
|
|
183
|
+
hideImageEditor: hideImageEditor
|
|
154
184
|
},
|
|
155
185
|
nodes: function nodes() {
|
|
156
|
-
var
|
|
157
|
-
|
|
158
|
-
allowMediaGroup =
|
|
159
|
-
|
|
160
|
-
allowMediaSingle =
|
|
161
|
-
|
|
162
|
-
allowPixelResizing =
|
|
163
|
-
allowCaptions =
|
|
164
|
-
allowMediaInlineImages =
|
|
165
|
-
mediaFeatureFlags =
|
|
186
|
+
var _ref6 = options || {},
|
|
187
|
+
_ref6$allowMediaGroup = _ref6.allowMediaGroup,
|
|
188
|
+
allowMediaGroup = _ref6$allowMediaGroup === void 0 ? true : _ref6$allowMediaGroup,
|
|
189
|
+
_ref6$allowMediaSingl = _ref6.allowMediaSingle,
|
|
190
|
+
allowMediaSingle = _ref6$allowMediaSingl === void 0 ? false : _ref6$allowMediaSingl,
|
|
191
|
+
_ref6$allowPixelResiz = _ref6.allowPixelResizing,
|
|
192
|
+
allowPixelResizing = _ref6$allowPixelResiz === void 0 ? false : _ref6$allowPixelResiz,
|
|
193
|
+
allowCaptions = _ref6.allowCaptions,
|
|
194
|
+
allowMediaInlineImages = _ref6.allowMediaInlineImages,
|
|
195
|
+
mediaFeatureFlags = _ref6.featureFlags;
|
|
166
196
|
var allowMediaInline = fg('platform_editor_remove_media_inline_feature_flag') ? allowMediaInlineImages : getMediaFeatureFlag('mediaInline', mediaFeatureFlags);
|
|
167
197
|
var mediaSingleOption = {
|
|
168
198
|
withCaption: allowCaptions,
|
|
@@ -196,16 +226,16 @@ export var mediaPlugin = function mediaPlugin(_ref3) {
|
|
|
196
226
|
pmPlugins: function pmPlugins() {
|
|
197
227
|
var pmPlugins = [{
|
|
198
228
|
name: 'media',
|
|
199
|
-
plugin: function plugin(
|
|
200
|
-
var schema =
|
|
201
|
-
dispatch =
|
|
202
|
-
getIntl =
|
|
203
|
-
eventDispatcher =
|
|
204
|
-
providerFactory =
|
|
205
|
-
errorReporter =
|
|
206
|
-
portalProviderAPI =
|
|
207
|
-
dispatchAnalyticsEvent =
|
|
208
|
-
nodeViewPortalProviderAPI =
|
|
229
|
+
plugin: function plugin(_ref7) {
|
|
230
|
+
var schema = _ref7.schema,
|
|
231
|
+
dispatch = _ref7.dispatch,
|
|
232
|
+
getIntl = _ref7.getIntl,
|
|
233
|
+
eventDispatcher = _ref7.eventDispatcher,
|
|
234
|
+
providerFactory = _ref7.providerFactory,
|
|
235
|
+
errorReporter = _ref7.errorReporter,
|
|
236
|
+
portalProviderAPI = _ref7.portalProviderAPI,
|
|
237
|
+
dispatchAnalyticsEvent = _ref7.dispatchAnalyticsEvent,
|
|
238
|
+
nodeViewPortalProviderAPI = _ref7.nodeViewPortalProviderAPI;
|
|
209
239
|
return createPlugin(schema, {
|
|
210
240
|
providerFactory: providerFactory,
|
|
211
241
|
nodeViews: {
|
|
@@ -224,17 +254,17 @@ export var mediaPlugin = function mediaPlugin(_ref3) {
|
|
|
224
254
|
}
|
|
225
255
|
}, {
|
|
226
256
|
name: 'mediaKeymap',
|
|
227
|
-
plugin: function plugin(
|
|
257
|
+
plugin: function plugin(_ref8) {
|
|
228
258
|
var _api$analytics3, _api$selection;
|
|
229
|
-
var getIntl =
|
|
259
|
+
var getIntl = _ref8.getIntl;
|
|
230
260
|
return keymapPlugin(options, api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions, api === null || api === void 0 || (_api$selection = api.selection) === null || _api$selection === void 0 ? void 0 : _api$selection.actions, api === null || api === void 0 ? void 0 : api.width, getIntl);
|
|
231
261
|
}
|
|
232
262
|
}];
|
|
233
263
|
if (options && options.allowMediaSingle) {
|
|
234
264
|
pmPlugins.push({
|
|
235
265
|
name: 'mediaSingleKeymap',
|
|
236
|
-
plugin: function plugin(
|
|
237
|
-
var schema =
|
|
266
|
+
plugin: function plugin(_ref9) {
|
|
267
|
+
var schema = _ref9.schema;
|
|
238
268
|
return keymapMediaSinglePlugin(schema);
|
|
239
269
|
}
|
|
240
270
|
});
|
|
@@ -246,9 +276,9 @@ export var mediaPlugin = function mediaPlugin(_ref3) {
|
|
|
246
276
|
});
|
|
247
277
|
pmPlugins.push({
|
|
248
278
|
name: 'mediaAltTextKeymap',
|
|
249
|
-
plugin: function plugin(
|
|
279
|
+
plugin: function plugin(_ref0) {
|
|
250
280
|
var _api$analytics4;
|
|
251
|
-
var schema =
|
|
281
|
+
var schema = _ref0.schema;
|
|
252
282
|
return keymapMediaAltTextPlugin(schema, api === null || api === void 0 || (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 ? void 0 : _api$analytics4.actions);
|
|
253
283
|
}
|
|
254
284
|
});
|
|
@@ -256,15 +286,15 @@ export var mediaPlugin = function mediaPlugin(_ref3) {
|
|
|
256
286
|
if (options && options.allowLinking) {
|
|
257
287
|
pmPlugins.push({
|
|
258
288
|
name: 'mediaLinking',
|
|
259
|
-
plugin: function plugin(
|
|
260
|
-
var dispatch =
|
|
289
|
+
plugin: function plugin(_ref1) {
|
|
290
|
+
var dispatch = _ref1.dispatch;
|
|
261
291
|
return linkingPlugin(dispatch);
|
|
262
292
|
}
|
|
263
293
|
});
|
|
264
294
|
pmPlugins.push({
|
|
265
295
|
name: 'mediaLinkingKeymap',
|
|
266
|
-
plugin: function plugin(
|
|
267
|
-
var schema =
|
|
296
|
+
plugin: function plugin(_ref10) {
|
|
297
|
+
var schema = _ref10.schema;
|
|
268
298
|
return keymapLinkingPlugin(schema);
|
|
269
299
|
}
|
|
270
300
|
});
|
|
@@ -306,13 +336,16 @@ export var mediaPlugin = function mediaPlugin(_ref3) {
|
|
|
306
336
|
});
|
|
307
337
|
return pmPlugins;
|
|
308
338
|
},
|
|
309
|
-
contentComponent: function contentComponent(
|
|
310
|
-
var editorView =
|
|
311
|
-
appearance =
|
|
339
|
+
contentComponent: function contentComponent(_ref11) {
|
|
340
|
+
var editorView = _ref11.editorView,
|
|
341
|
+
appearance = _ref11.appearance;
|
|
312
342
|
if (!editorView) {
|
|
313
343
|
return null;
|
|
314
344
|
}
|
|
315
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(
|
|
345
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, (options === null || options === void 0 ? void 0 : options.allowImageEditing) && expValEquals('platform_editor_add_image_editing', 'isEnabled', true) && /*#__PURE__*/React.createElement(ImageEditorFunctionalComponent, {
|
|
346
|
+
api: api,
|
|
347
|
+
editorView: editorView
|
|
348
|
+
}), /*#__PURE__*/React.createElement(MediaViewerFunctionalComponent, {
|
|
316
349
|
api: api,
|
|
317
350
|
editorView: editorView
|
|
318
351
|
}), /*#__PURE__*/React.createElement(MediaPickerFunctionalComponent, {
|
|
@@ -321,8 +354,8 @@ export var mediaPlugin = function mediaPlugin(_ref3) {
|
|
|
321
354
|
api: api
|
|
322
355
|
}));
|
|
323
356
|
},
|
|
324
|
-
secondaryToolbarComponent: function secondaryToolbarComponent(
|
|
325
|
-
var disabled =
|
|
357
|
+
secondaryToolbarComponent: function secondaryToolbarComponent(_ref12) {
|
|
358
|
+
var disabled = _ref12.disabled;
|
|
326
359
|
return /*#__PURE__*/React.createElement(ToolbarMedia, {
|
|
327
360
|
isDisabled: disabled,
|
|
328
361
|
isReducedSpacing: true,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export var ACTIONS = {
|
|
2
2
|
SHOW_MEDIA_VIEWER: 'SHOW_MEDIA_VIEWER',
|
|
3
3
|
HIDE_MEDIA_VIEWER: 'HIDE_MEDIA_VIEWER',
|
|
4
|
-
TRACK_MEDIA_PASTE: 'TRACK_MEDIA_PASTE'
|
|
4
|
+
TRACK_MEDIA_PASTE: 'TRACK_MEDIA_PASTE',
|
|
5
|
+
SHOW_IMAGE_EDITOR: 'SHOW_IMAGE_EDITOR',
|
|
6
|
+
HIDE_IMAGE_EDITOR: 'HIDE_IMAGE_EDITOR'
|
|
5
7
|
};
|
|
@@ -31,4 +31,26 @@ export var trackMediaPaste = function trackMediaPaste(attrs) {
|
|
|
31
31
|
});
|
|
32
32
|
return tr;
|
|
33
33
|
};
|
|
34
|
+
};
|
|
35
|
+
export var showImageEditor = function showImageEditor(media) {
|
|
36
|
+
return function (_ref4) {
|
|
37
|
+
var tr = _ref4.tr;
|
|
38
|
+
tr.setMeta(stateKey, {
|
|
39
|
+
type: ACTIONS.SHOW_IMAGE_EDITOR,
|
|
40
|
+
imageEditorSelectedMedia: media,
|
|
41
|
+
isImageEditorVisible: true
|
|
42
|
+
});
|
|
43
|
+
tr.setMeta('addToHistory', false);
|
|
44
|
+
return tr;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
export var hideImageEditor = function hideImageEditor(_ref5) {
|
|
48
|
+
var tr = _ref5.tr;
|
|
49
|
+
tr.setMeta(stateKey, {
|
|
50
|
+
type: ACTIONS.HIDE_IMAGE_EDITOR,
|
|
51
|
+
imageEditorSelectedMedia: null,
|
|
52
|
+
isImageEditorVisible: false
|
|
53
|
+
});
|
|
54
|
+
tr.setMeta('addToHistory', false);
|
|
55
|
+
return tr;
|
|
34
56
|
};
|
|
@@ -82,6 +82,7 @@ export var MediaPluginStateImplementation = /*#__PURE__*/function () {
|
|
|
82
82
|
_defineProperty(this, "allowInlineImages", false);
|
|
83
83
|
_defineProperty(this, "uploadInProgressSubscriptions", []);
|
|
84
84
|
_defineProperty(this, "uploadInProgressSubscriptionsNotified", false);
|
|
85
|
+
_defineProperty(this, "isImageEditorVisible", false);
|
|
85
86
|
// this is only a temporary variable, which gets cleared after the last inserted node has been selected
|
|
86
87
|
_defineProperty(this, "lastAddedMediaSingleFileIds", []);
|
|
87
88
|
_defineProperty(this, "destroyed", false);
|
|
@@ -629,6 +630,11 @@ export var MediaPluginStateImplementation = /*#__PURE__*/function () {
|
|
|
629
630
|
value: function setResizingWidth(width) {
|
|
630
631
|
this.resizingWidth = width;
|
|
631
632
|
}
|
|
633
|
+
}, {
|
|
634
|
+
key: "setImageEditorVisibility",
|
|
635
|
+
value: function setImageEditorVisibility(isVisible) {
|
|
636
|
+
this.isImageEditorVisible = isVisible;
|
|
637
|
+
}
|
|
632
638
|
}, {
|
|
633
639
|
key: "updateElement",
|
|
634
640
|
value: function updateElement() {
|
|
@@ -870,6 +876,16 @@ export var createPlugin = function createPlugin(_schema, options, getIntl, plugi
|
|
|
870
876
|
nextPluginState = pluginState.clone();
|
|
871
877
|
}
|
|
872
878
|
break;
|
|
879
|
+
case ACTIONS.SHOW_IMAGE_EDITOR:
|
|
880
|
+
pluginState.imageEditorSelectedMedia = meta.imageEditorSelectedMedia;
|
|
881
|
+
pluginState.isImageEditorVisible = meta.isImageEditorVisible;
|
|
882
|
+
nextPluginState = nextPluginState.clone();
|
|
883
|
+
break;
|
|
884
|
+
case ACTIONS.HIDE_IMAGE_EDITOR:
|
|
885
|
+
pluginState.imageEditorSelectedMedia = undefined;
|
|
886
|
+
pluginState.isImageEditorVisible = meta.isImageEditorVisible;
|
|
887
|
+
nextPluginState = nextPluginState.clone();
|
|
888
|
+
break;
|
|
873
889
|
}
|
|
874
890
|
|
|
875
891
|
// NOTE: We're not calling passing new state to the Editor, because we depend on the view.state reference
|
|
@@ -47,7 +47,7 @@ export var CaptionPlaceholder = /*#__PURE__*/React.forwardRef(function (_ref, re
|
|
|
47
47
|
// This id is just used for setting styles at the moment, if it's needed for anything more specific
|
|
48
48
|
// It may need to be generated to avoid overlap
|
|
49
49
|
,
|
|
50
|
-
id: expValEquals('cc_editor_ai_content_mode', 'variant', 'test') && fg('platform_editor_content_mode_button_mvp') ? CAPTION_PLACEHOLDER_ID : undefined,
|
|
50
|
+
id: expValEquals('confluence_compact_text_format', 'isEnabled', true) || expValEquals('cc_editor_ai_content_mode', 'variant', 'test') && fg('platform_editor_content_mode_button_mvp') ? CAPTION_PLACEHOLDER_ID : undefined,
|
|
51
51
|
"data-id": CAPTION_PLACEHOLDER_ID,
|
|
52
52
|
"data-testid": "caption-placeholder"
|
|
53
53
|
}, jsx(FormattedMessage
|
|
@@ -75,7 +75,7 @@ export var CaptionPlaceholderButton = /*#__PURE__*/React.forwardRef(function (_r
|
|
|
75
75
|
testId: "caption-placeholder",
|
|
76
76
|
padding: "space.0",
|
|
77
77
|
xcss: placeholderButton
|
|
78
|
-
}, expValEquals('cc_editor_ai_content_mode', 'variant', 'test') && fg('platform_editor_content_mode_button_mvp') ?
|
|
78
|
+
}, expValEquals('confluence_compact_text_format', 'isEnabled', true) || expValEquals('cc_editor_ai_content_mode', 'variant', 'test') && fg('platform_editor_content_mode_button_mvp') ?
|
|
79
79
|
// This id is just used for setting styles at the moment, if it's needed for anything more specific
|
|
80
80
|
// It may need to be generated to avoid overlap
|
|
81
81
|
// eslint-disable-next-line @atlaskit/design-system/use-primitives-text
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
|
+
import React, { useEffect, useState } from 'react';
|
|
3
|
+
import { MediaClient } from '@atlaskit/media-client';
|
|
4
|
+
import { isExternalMedia } from '../toolbar/utils';
|
|
5
|
+
import { ImageEditor } from './index';
|
|
6
|
+
export var RenderImageEditor = function RenderImageEditor(_ref) {
|
|
7
|
+
var mediaClientConfig = _ref.mediaClientConfig,
|
|
8
|
+
onClose = _ref.onClose,
|
|
9
|
+
selectedNodeAttrs = _ref.selectedNodeAttrs,
|
|
10
|
+
errorReporter = _ref.errorReporter,
|
|
11
|
+
onSave = _ref.onSave;
|
|
12
|
+
var _useState = useState(''),
|
|
13
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
14
|
+
imageUrl = _useState2[0],
|
|
15
|
+
setImageUrl = _useState2[1];
|
|
16
|
+
useEffect(function () {
|
|
17
|
+
var getImageUrl = function getImageUrl() {
|
|
18
|
+
if (isExternalMedia(selectedNodeAttrs)) {
|
|
19
|
+
// External image - use the URL directly
|
|
20
|
+
setImageUrl(selectedNodeAttrs.url || '');
|
|
21
|
+
} else {
|
|
22
|
+
// File media - use MediaClient to get the image URL
|
|
23
|
+
var id = selectedNodeAttrs.id,
|
|
24
|
+
_selectedNodeAttrs$co = selectedNodeAttrs.collection,
|
|
25
|
+
collection = _selectedNodeAttrs$co === void 0 ? '' : _selectedNodeAttrs$co;
|
|
26
|
+
try {
|
|
27
|
+
var mediaClient = new MediaClient(mediaClientConfig);
|
|
28
|
+
|
|
29
|
+
// Subscribe to file state to get file information
|
|
30
|
+
var subscription = mediaClient.file.getFileState(id, {
|
|
31
|
+
collectionName: collection
|
|
32
|
+
}).subscribe(function (fileState) {
|
|
33
|
+
if (fileState.status === 'processed' || fileState.status === 'processing') {
|
|
34
|
+
// Get the image URL from the processed file
|
|
35
|
+
mediaClient.file.getFileBinaryURL(id, collection).then(function (url) {
|
|
36
|
+
setImageUrl(url);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Cleanup subscription on unmount
|
|
42
|
+
return function () {
|
|
43
|
+
return subscription.unsubscribe();
|
|
44
|
+
};
|
|
45
|
+
} catch (error) {
|
|
46
|
+
if (errorReporter) {
|
|
47
|
+
errorReporter.captureException(error instanceof Error ? error : new Error(String(error)));
|
|
48
|
+
}
|
|
49
|
+
setImageUrl('');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
getImageUrl();
|
|
54
|
+
}, [selectedNodeAttrs, mediaClientConfig, errorReporter]);
|
|
55
|
+
return /*#__PURE__*/React.createElement(ImageEditor, {
|
|
56
|
+
isOpen: true,
|
|
57
|
+
onClose: onClose,
|
|
58
|
+
imageUrl: imageUrl
|
|
59
|
+
});
|
|
60
|
+
};
|