@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.
Files changed (42) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/cjs/mediaPlugin.js +76 -43
  3. package/dist/cjs/pm-plugins/actions.js +3 -1
  4. package/dist/cjs/pm-plugins/commands.js +23 -1
  5. package/dist/cjs/pm-plugins/main.js +16 -0
  6. package/dist/cjs/ui/CaptionPlaceholder/index.js +2 -2
  7. package/dist/cjs/ui/ImageEditor/ModalWrapper.js +69 -0
  8. package/dist/cjs/ui/ImageEditor/index.js +62 -0
  9. package/dist/cjs/ui/toolbar/index.js +24 -11
  10. package/dist/es2019/mediaPlugin.js +38 -3
  11. package/dist/es2019/pm-plugins/actions.js +3 -1
  12. package/dist/es2019/pm-plugins/commands.js +22 -0
  13. package/dist/es2019/pm-plugins/main.js +14 -0
  14. package/dist/es2019/ui/CaptionPlaceholder/index.js +2 -2
  15. package/dist/es2019/ui/ImageEditor/ModalWrapper.js +58 -0
  16. package/dist/es2019/ui/ImageEditor/index.js +53 -0
  17. package/dist/es2019/ui/toolbar/index.js +20 -6
  18. package/dist/esm/mediaPlugin.js +77 -44
  19. package/dist/esm/pm-plugins/actions.js +3 -1
  20. package/dist/esm/pm-plugins/commands.js +22 -0
  21. package/dist/esm/pm-plugins/main.js +16 -0
  22. package/dist/esm/ui/CaptionPlaceholder/index.js +2 -2
  23. package/dist/esm/ui/ImageEditor/ModalWrapper.js +60 -0
  24. package/dist/esm/ui/ImageEditor/index.js +52 -0
  25. package/dist/esm/ui/toolbar/index.js +23 -10
  26. package/dist/types/mediaPluginType.d.ts +2 -0
  27. package/dist/types/pm-plugins/actions.d.ts +2 -0
  28. package/dist/types/pm-plugins/commands.d.ts +2 -0
  29. package/dist/types/pm-plugins/main.d.ts +4 -1
  30. package/dist/types/pm-plugins/types.d.ts +3 -0
  31. package/dist/types/ui/ImageEditor/ModalWrapper.d.ts +13 -0
  32. package/dist/types/ui/ImageEditor/index.d.ts +12 -0
  33. package/dist/types/ui/toolbar/index.d.ts +4 -0
  34. package/dist/types-ts4.5/mediaPluginType.d.ts +2 -0
  35. package/dist/types-ts4.5/pm-plugins/actions.d.ts +2 -0
  36. package/dist/types-ts4.5/pm-plugins/commands.d.ts +2 -0
  37. package/dist/types-ts4.5/pm-plugins/main.d.ts +4 -1
  38. package/dist/types-ts4.5/pm-plugins/types.d.ts +3 -0
  39. package/dist/types-ts4.5/ui/ImageEditor/ModalWrapper.d.ts +13 -0
  40. package/dist/types-ts4.5/ui/ImageEditor/index.d.ts +12 -0
  41. package/dist/types-ts4.5/ui/toolbar/index.d.ts +4 -0
  42. 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
- // TODO: EDITOR-3716 - Implement image editing logic
567
- // console.log('Image editing clicked');
568
- return true;
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
- // TODO: EDITOR-3716 - Implement image editing logic
725
- // console.log('Image editing clicked');
726
- return true;
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
  }, {
@@ -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
- export var mediaPlugin = function mediaPlugin(_ref3) {
99
- var _ref3$config = _ref3.config,
100
- options = _ref3$config === void 0 ? {} : _ref3$config,
101
- api = _ref3.api;
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 (_ref4) {
143
- var tr = _ref4.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 _ref5 = options || {},
157
- _ref5$allowMediaGroup = _ref5.allowMediaGroup,
158
- allowMediaGroup = _ref5$allowMediaGroup === void 0 ? true : _ref5$allowMediaGroup,
159
- _ref5$allowMediaSingl = _ref5.allowMediaSingle,
160
- allowMediaSingle = _ref5$allowMediaSingl === void 0 ? false : _ref5$allowMediaSingl,
161
- _ref5$allowPixelResiz = _ref5.allowPixelResizing,
162
- allowPixelResizing = _ref5$allowPixelResiz === void 0 ? false : _ref5$allowPixelResiz,
163
- allowCaptions = _ref5.allowCaptions,
164
- allowMediaInlineImages = _ref5.allowMediaInlineImages,
165
- mediaFeatureFlags = _ref5.featureFlags;
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(_ref6) {
200
- var schema = _ref6.schema,
201
- dispatch = _ref6.dispatch,
202
- getIntl = _ref6.getIntl,
203
- eventDispatcher = _ref6.eventDispatcher,
204
- providerFactory = _ref6.providerFactory,
205
- errorReporter = _ref6.errorReporter,
206
- portalProviderAPI = _ref6.portalProviderAPI,
207
- dispatchAnalyticsEvent = _ref6.dispatchAnalyticsEvent,
208
- nodeViewPortalProviderAPI = _ref6.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(_ref7) {
257
+ plugin: function plugin(_ref8) {
228
258
  var _api$analytics3, _api$selection;
229
- var getIntl = _ref7.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(_ref8) {
237
- var schema = _ref8.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(_ref9) {
279
+ plugin: function plugin(_ref0) {
250
280
  var _api$analytics4;
251
- var schema = _ref9.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(_ref0) {
260
- var dispatch = _ref0.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(_ref1) {
267
- var schema = _ref1.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(_ref10) {
310
- var editorView = _ref10.editorView,
311
- appearance = _ref10.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(MediaViewerFunctionalComponent, {
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(_ref11) {
325
- var disabled = _ref11.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
+ };