@atlaskit/editor-plugin-media 1.36.5 → 1.37.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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # @atlaskit/editor-plugin-media
2
2
 
3
+ ## 1.37.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#154775](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/154775)
8
+ [`1b353693c3119`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/1b353693c3119) -
9
+ [ED-25348] Refactor Media Group React Class component into Function Component
10
+
11
+ ### Patch Changes
12
+
13
+ - [#154186](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/154186)
14
+ [`5c316170d29dd`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/5c316170d29dd) -
15
+ Bump @atlaskit/adf-schema to 42.3.1
16
+ - Updated dependencies
17
+
3
18
  ## 1.36.5
4
19
 
5
20
  ### Patch Changes
@@ -24,8 +24,10 @@ var _utils = require("@atlaskit/editor-common/utils");
24
24
  var _close = _interopRequireDefault(require("@atlaskit/icon/glyph/editor/close"));
25
25
  var _mediaCommon = require("@atlaskit/media-common");
26
26
  var _mediaFilmstrip = require("@atlaskit/media-filmstrip");
27
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
27
28
  var _useMediaProvider = require("../hooks/useMediaProvider");
28
29
  var _pluginKey = require("../pm-plugins/plugin-key");
30
+ var _mediaGroupNext = require("./mediaGroupNext");
29
31
  var _mediaNodeUpdater = require("./mediaNodeUpdater");
30
32
  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; }
31
33
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
@@ -346,6 +348,23 @@ var MediaGroupNodeView = /*#__PURE__*/function (_ReactNodeView) {
346
348
  if (!mediaProvider) {
347
349
  return null;
348
350
  }
351
+ if ((0, _platformFeatureFlags.fg)('platform_editor_react18_phase2__media_single')) {
352
+ return /*#__PURE__*/_react.default.createElement(_mediaGroupNext.MediaGroupNext, {
353
+ node: _this3.node,
354
+ getPos: getPos,
355
+ view: _this3.view,
356
+ forwardRef: forwardRef,
357
+ disabled: (editorDisabledPlugin || {}).editorDisabled,
358
+ allowLazyLoading: mediaOptions.allowLazyLoading,
359
+ mediaProvider: mediaProvider,
360
+ contextIdentifierProvider: contextIdentifierProvider,
361
+ isCopyPasteEnabled: mediaOptions.isCopyPasteEnabled,
362
+ anchorPos: _this3.view.state.selection.$anchor.pos,
363
+ headPos: _this3.view.state.selection.$head.pos,
364
+ mediaOptions: mediaOptions,
365
+ editorViewMode: (editorViewModePlugin === null || editorViewModePlugin === void 0 ? void 0 : editorViewModePlugin.mode) === 'view'
366
+ });
367
+ }
349
368
  return /*#__PURE__*/_react.default.createElement(IntlMediaGroup, {
350
369
  node: _this3.node,
351
370
  getPos: getPos,
@@ -0,0 +1,295 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.MediaGroupNext = void 0;
9
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
10
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
11
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
12
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
13
+ var _react = _interopRequireWildcard(require("react"));
14
+ var _reactIntlNext = require("react-intl-next");
15
+ var _hooks = require("@atlaskit/editor-common/hooks");
16
+ var _media = require("@atlaskit/editor-common/media");
17
+ var _utils = require("@atlaskit/editor-common/utils");
18
+ var _close = _interopRequireDefault(require("@atlaskit/icon/glyph/editor/close"));
19
+ var _mediaCommon = require("@atlaskit/media-common");
20
+ var _mediaFilmstrip = require("@atlaskit/media-filmstrip");
21
+ var _pluginKey = require("../pm-plugins/plugin-key");
22
+ var _mediaNodeUpdater = require("./mediaNodeUpdater");
23
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
24
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
25
+ 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; }
26
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
27
+ var getIdentifier = function getIdentifier(item) {
28
+ if (item.attrs.type === 'external') {
29
+ return {
30
+ mediaItemType: 'external-image',
31
+ dataURI: item.attrs.url
32
+ };
33
+ }
34
+ return {
35
+ id: item.attrs.id,
36
+ mediaItemType: 'file',
37
+ collectionName: item.attrs.collection
38
+ };
39
+ };
40
+ var isNodeSelected = function isNodeSelected(props) {
41
+ return function (mediaItemPos, mediaGroupPos) {
42
+ var selected = (0, _utils.isNodeSelectedOrInRange)(props.anchorPos, props.headPos, mediaGroupPos, props.nodeSize);
43
+ if (selected === _utils.SelectedState.selectedInRange) {
44
+ return true;
45
+ }
46
+ if (selected === _utils.SelectedState.selectedInside && props.anchorPos === mediaItemPos) {
47
+ return true;
48
+ }
49
+ return false;
50
+ };
51
+ };
52
+ var prepareFilmstripItem = function prepareFilmstripItem(_ref) {
53
+ var allowLazyLoading = _ref.allowLazyLoading,
54
+ enableDownloadButton = _ref.enableDownloadButton,
55
+ handleMediaNodeRemoval = _ref.handleMediaNodeRemoval,
56
+ getPos = _ref.getPos,
57
+ intl = _ref.intl,
58
+ isMediaItemSelected = _ref.isMediaItemSelected,
59
+ setMediaGroupNodeSelection = _ref.setMediaGroupNodeSelection,
60
+ featureFlags = _ref.featureFlags;
61
+ return function (item, idx) {
62
+ // We declared this to get a fresh position every time
63
+ var getNodePos = function getNodePos() {
64
+ var pos = getPos();
65
+ if (typeof pos !== 'number') {
66
+ // That may seems weird, but the previous type wasn't match with the real ProseMirror code. And a lot of Media API was built expecting a number
67
+ // Because the original code would return NaN on runtime
68
+ // We are just make it explict now.
69
+ // We may run a deep investagation on Media code to figure out a better fix. But, for now, we want to keep the current behavior.
70
+ // TODO: ED-13910 prosemirror-bump leftovers
71
+ return NaN;
72
+ }
73
+ return pos + idx + 1;
74
+ };
75
+
76
+ // Media Inline creates a floating toolbar with the same options, excludes these options if enabled
77
+ var mediaInlineOptions = function mediaInlineOptions() {
78
+ var allowMediaInline = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
79
+ if (!allowMediaInline) {
80
+ return {
81
+ shouldEnableDownloadButton: enableDownloadButton,
82
+ actions: [{
83
+ handler: handleMediaNodeRemoval.bind(null, undefined, getNodePos),
84
+ icon: /*#__PURE__*/_react.default.createElement(_close.default, {
85
+ label: intl.formatMessage(_media.nodeViewsMessages.mediaGroupDeleteLabel)
86
+ })
87
+ }]
88
+ };
89
+ }
90
+ };
91
+ var mediaGroupPos = getPos();
92
+ return _objectSpread({
93
+ identifier: getIdentifier(item),
94
+ isLazy: allowLazyLoading,
95
+ selected: isMediaItemSelected(getNodePos(), typeof mediaGroupPos === 'number' ? mediaGroupPos : NaN),
96
+ onClick: function onClick() {
97
+ setMediaGroupNodeSelection(getNodePos());
98
+ }
99
+ }, mediaInlineOptions((0, _mediaCommon.getMediaFeatureFlag)('mediaInline', featureFlags)));
100
+ };
101
+ };
102
+
103
+ /**
104
+ * Keep returning the same ProseMirror Node, unless the node content changed.
105
+ *
106
+ * React uses shallow comparation with `Object.is`,
107
+ * but that can cause multiple re-renders when the same node is given in a different instance.
108
+ *
109
+ * To avoid unnecessary re-renders, this hook uses the `Node.eq` from ProseMirror API to compare
110
+ * previous and new values.
111
+ */
112
+ var useLatestMediaGroupNode = function useLatestMediaGroupNode(nextMediaNode) {
113
+ var previousMediaNode = (0, _hooks.usePreviousState)(nextMediaNode);
114
+ var _React$useState = _react.default.useState(nextMediaNode),
115
+ _React$useState2 = (0, _slicedToArray2.default)(_React$useState, 2),
116
+ mediaNode = _React$useState2[0],
117
+ setMediaNode = _React$useState2[1];
118
+ _react.default.useEffect(function () {
119
+ if (!previousMediaNode) {
120
+ return;
121
+ }
122
+ if (!previousMediaNode.eq(nextMediaNode)) {
123
+ setMediaNode(nextMediaNode);
124
+ }
125
+ }, [previousMediaNode, nextMediaNode]);
126
+ return mediaNode;
127
+ };
128
+ var runMediaNodeUpdate = /*#__PURE__*/function () {
129
+ var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref2) {
130
+ var mediaNodeUpdater, getPos, node, updateAttrs, contextId, hasDifferentContextId;
131
+ return _regenerator.default.wrap(function _callee$(_context) {
132
+ while (1) switch (_context.prev = _context.next) {
133
+ case 0:
134
+ mediaNodeUpdater = _ref2.mediaNodeUpdater, getPos = _ref2.getPos, node = _ref2.node, updateAttrs = _ref2.updateAttrs;
135
+ if (!updateAttrs) {
136
+ _context.next = 4;
137
+ break;
138
+ }
139
+ _context.next = 4;
140
+ return mediaNodeUpdater.updateNodeAttrs(getPos);
141
+ case 4:
142
+ contextId = mediaNodeUpdater.getNodeContextId();
143
+ if (contextId) {
144
+ _context.next = 8;
145
+ break;
146
+ }
147
+ _context.next = 8;
148
+ return mediaNodeUpdater.updateNodeContextId(getPos);
149
+ case 8:
150
+ _context.next = 10;
151
+ return mediaNodeUpdater.hasDifferentContextId();
152
+ case 10:
153
+ hasDifferentContextId = _context.sent;
154
+ if (!hasDifferentContextId) {
155
+ _context.next = 14;
156
+ break;
157
+ }
158
+ _context.next = 14;
159
+ return mediaNodeUpdater.copyNodeFromPos(getPos, {
160
+ traceId: node.attrs.__mediaTraceId
161
+ });
162
+ case 14:
163
+ case "end":
164
+ return _context.stop();
165
+ }
166
+ }, _callee);
167
+ }));
168
+ return function runMediaNodeUpdate(_x) {
169
+ return _ref3.apply(this, arguments);
170
+ };
171
+ }();
172
+ var noop = function noop() {};
173
+ var MediaGroupNext = exports.MediaGroupNext = (0, _reactIntlNext.injectIntl)( /*#__PURE__*/_react.default.memo(function (props) {
174
+ var _props$mediaOptions = props.mediaOptions,
175
+ allowLazyLoading = _props$mediaOptions.allowLazyLoading,
176
+ enableDownloadButton = _props$mediaOptions.enableDownloadButton,
177
+ featureFlags = _props$mediaOptions.featureFlags,
178
+ intl = props.intl,
179
+ _getPos = props.getPos,
180
+ anchorPos = props.anchorPos,
181
+ headPos = props.headPos,
182
+ view = props.view,
183
+ disabled = props.disabled,
184
+ editorViewMode = props.editorViewMode,
185
+ mediaProvider = props.mediaProvider,
186
+ contextIdentifierProvider = props.contextIdentifierProvider,
187
+ isCopyPasteEnabled = props.isCopyPasteEnabled;
188
+ var mediaGroupNode = useLatestMediaGroupNode(props.node);
189
+ var mediaPluginState = (0, _react.useMemo)(function () {
190
+ return _pluginKey.stateKey.getState(view.state);
191
+ }, [view.state]);
192
+ var mediaClientConfig = mediaPluginState === null || mediaPluginState === void 0 ? void 0 : mediaPluginState.mediaClientConfig;
193
+ var handleMediaGroupUpdate = mediaPluginState === null || mediaPluginState === void 0 ? void 0 : mediaPluginState.handleMediaGroupUpdate;
194
+ var _useState = (0, _react.useState)(undefined),
195
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
196
+ viewMediaClientConfig = _useState2[0],
197
+ setViewMediaClientConfig = _useState2[1];
198
+ var nodeSize = mediaGroupNode.nodeSize;
199
+ var mediaNodesWithOffsets = (0, _react.useMemo)(function () {
200
+ var result = [];
201
+ mediaGroupNode.forEach(function (item, childOffset) {
202
+ result.push({
203
+ node: item,
204
+ offset: childOffset
205
+ });
206
+ });
207
+ return result;
208
+ }, [mediaGroupNode]);
209
+ var previousMediaNodesWithOffsets = (0, _hooks.usePreviousState)(mediaNodesWithOffsets);
210
+ var handleMediaNodeRemoval = (0, _react.useMemo)(function () {
211
+ return disabled || !mediaPluginState ? noop : mediaPluginState.handleMediaNodeRemoval;
212
+ }, [disabled, mediaPluginState]);
213
+ var setMediaGroupNodeSelection = (0, _react.useCallback)(function (pos) {
214
+ (0, _utils.setNodeSelection)(view, pos);
215
+ }, [view]);
216
+ var isMediaItemSelected = (0, _react.useMemo)(function () {
217
+ return isNodeSelected({
218
+ anchorPos: anchorPos,
219
+ headPos: headPos,
220
+ nodeSize: nodeSize
221
+ });
222
+ }, [anchorPos, headPos, nodeSize]);
223
+ var filmstripItem = (0, _react.useMemo)(function () {
224
+ return prepareFilmstripItem({
225
+ allowLazyLoading: allowLazyLoading,
226
+ enableDownloadButton: enableDownloadButton,
227
+ handleMediaNodeRemoval: handleMediaNodeRemoval,
228
+ getPos: _getPos,
229
+ intl: intl,
230
+ isMediaItemSelected: isMediaItemSelected,
231
+ setMediaGroupNodeSelection: setMediaGroupNodeSelection,
232
+ featureFlags: featureFlags
233
+ });
234
+ }, [allowLazyLoading, enableDownloadButton, handleMediaNodeRemoval, _getPos, intl, isMediaItemSelected, setMediaGroupNodeSelection, featureFlags]);
235
+ var items = (0, _react.useMemo)(function () {
236
+ return mediaNodesWithOffsets.map(function (_ref4) {
237
+ var node = _ref4.node,
238
+ offset = _ref4.offset;
239
+ return filmstripItem(node, offset);
240
+ });
241
+ }, [mediaNodesWithOffsets, filmstripItem]);
242
+ (0, _react.useEffect)(function () {
243
+ setViewMediaClientConfig(mediaClientConfig);
244
+ }, [mediaClientConfig]);
245
+ (0, _react.useEffect)(function () {
246
+ mediaNodesWithOffsets.forEach(function (_ref5) {
247
+ var node = _ref5.node,
248
+ offset = _ref5.offset;
249
+ var mediaNodeUpdater = (0, _mediaNodeUpdater.createMediaNodeUpdater)({
250
+ view: view,
251
+ mediaProvider: mediaProvider,
252
+ contextIdentifierProvider: contextIdentifierProvider,
253
+ node: node,
254
+ isMediaSingle: false
255
+ });
256
+ var updateAttrs = isCopyPasteEnabled || isCopyPasteEnabled === undefined;
257
+ runMediaNodeUpdate({
258
+ mediaNodeUpdater: mediaNodeUpdater,
259
+ node: node,
260
+ updateAttrs: updateAttrs,
261
+ getPos: function getPos() {
262
+ var pos = _getPos();
263
+ if (typeof pos !== 'number') {
264
+ return undefined;
265
+ }
266
+ return pos + offset + 1;
267
+ }
268
+ });
269
+ });
270
+ }, [view, contextIdentifierProvider, _getPos, mediaProvider, mediaNodesWithOffsets, isCopyPasteEnabled]);
271
+ (0, _react.useEffect)(function () {
272
+ if (!handleMediaGroupUpdate || !previousMediaNodesWithOffsets) {
273
+ return;
274
+ }
275
+ var old = previousMediaNodesWithOffsets.map(function (_ref6) {
276
+ var node = _ref6.node;
277
+ return node;
278
+ });
279
+ var next = mediaNodesWithOffsets.map(function (_ref7) {
280
+ var node = _ref7.node;
281
+ return node;
282
+ });
283
+ handleMediaGroupUpdate(old, next);
284
+ return function () {
285
+ handleMediaGroupUpdate(next, []);
286
+ };
287
+ }, [handleMediaGroupUpdate, mediaNodesWithOffsets, previousMediaNodesWithOffsets]);
288
+ return /*#__PURE__*/_react.default.createElement(_mediaFilmstrip.Filmstrip, {
289
+ items: items,
290
+ mediaClientConfig: viewMediaClientConfig,
291
+ featureFlags: featureFlags,
292
+ shouldOpenMediaViewer: editorViewMode
293
+ });
294
+ }));
295
+ MediaGroupNext.displayName = 'MediaGroup';
@@ -779,8 +779,6 @@ var hasPrivateAttrsChanged = function hasPrivateAttrsChanged(currentAttrs, newAt
779
779
  return currentAttrs.__fileName !== newAttrs.__fileName || currentAttrs.__fileMimeType !== newAttrs.__fileMimeType || currentAttrs.__fileSize !== newAttrs.__fileSize || currentAttrs.__contextId !== newAttrs.__contextId;
780
780
  };
781
781
  var createMediaNodeUpdater = exports.createMediaNodeUpdater = function createMediaNodeUpdater(props) {
782
- var updaterProps = _objectSpread(_objectSpread({}, props), {}, {
783
- isMediaSingle: true
784
- });
782
+ var updaterProps = _objectSpread({}, props);
785
783
  return new MediaNodeUpdater(updaterProps);
786
784
  };
@@ -9,8 +9,10 @@ import { isNodeSelectedOrInRange, SelectedState, setNodeSelection } from '@atlas
9
9
  import EditorCloseIcon from '@atlaskit/icon/glyph/editor/close';
10
10
  import { getMediaFeatureFlag } from '@atlaskit/media-common';
11
11
  import { Filmstrip } from '@atlaskit/media-filmstrip';
12
+ import { fg } from '@atlaskit/platform-feature-flags';
12
13
  import { useMediaProvider } from '../hooks/useMediaProvider';
13
14
  import { stateKey as mediaStateKey } from '../pm-plugins/plugin-key';
15
+ import { MediaGroupNext } from './mediaGroupNext';
14
16
  import { MediaNodeUpdater } from './mediaNodeUpdater';
15
17
  const isMediaGroupSelectedFromProps = props => {
16
18
  /**
@@ -290,6 +292,23 @@ class MediaGroupNodeView extends ReactNodeView {
290
292
  if (!mediaProvider) {
291
293
  return null;
292
294
  }
295
+ if (fg('platform_editor_react18_phase2__media_single')) {
296
+ return /*#__PURE__*/React.createElement(MediaGroupNext, {
297
+ node: this.node,
298
+ getPos: getPos,
299
+ view: this.view,
300
+ forwardRef: forwardRef,
301
+ disabled: (editorDisabledPlugin || {}).editorDisabled,
302
+ allowLazyLoading: mediaOptions.allowLazyLoading,
303
+ mediaProvider: mediaProvider,
304
+ contextIdentifierProvider: contextIdentifierProvider,
305
+ isCopyPasteEnabled: mediaOptions.isCopyPasteEnabled,
306
+ anchorPos: this.view.state.selection.$anchor.pos,
307
+ headPos: this.view.state.selection.$head.pos,
308
+ mediaOptions: mediaOptions,
309
+ editorViewMode: (editorViewModePlugin === null || editorViewModePlugin === void 0 ? void 0 : editorViewModePlugin.mode) === 'view'
310
+ });
311
+ }
293
312
  return /*#__PURE__*/React.createElement(IntlMediaGroup, {
294
313
  node: this.node,
295
314
  getPos: getPos,
@@ -0,0 +1,249 @@
1
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
2
+ import { injectIntl } from 'react-intl-next';
3
+ import { usePreviousState } from '@atlaskit/editor-common/hooks';
4
+ import { nodeViewsMessages as messages } from '@atlaskit/editor-common/media';
5
+ import { isNodeSelectedOrInRange, SelectedState, setNodeSelection } from '@atlaskit/editor-common/utils';
6
+ import EditorCloseIcon from '@atlaskit/icon/glyph/editor/close';
7
+ import { getMediaFeatureFlag } from '@atlaskit/media-common';
8
+ import { Filmstrip } from '@atlaskit/media-filmstrip';
9
+ import { stateKey as mediaStateKey } from '../pm-plugins/plugin-key';
10
+ import { createMediaNodeUpdater } from './mediaNodeUpdater';
11
+ const getIdentifier = item => {
12
+ if (item.attrs.type === 'external') {
13
+ return {
14
+ mediaItemType: 'external-image',
15
+ dataURI: item.attrs.url
16
+ };
17
+ }
18
+ return {
19
+ id: item.attrs.id,
20
+ mediaItemType: 'file',
21
+ collectionName: item.attrs.collection
22
+ };
23
+ };
24
+ const isNodeSelected = props => (mediaItemPos, mediaGroupPos) => {
25
+ const selected = isNodeSelectedOrInRange(props.anchorPos, props.headPos, mediaGroupPos, props.nodeSize);
26
+ if (selected === SelectedState.selectedInRange) {
27
+ return true;
28
+ }
29
+ if (selected === SelectedState.selectedInside && props.anchorPos === mediaItemPos) {
30
+ return true;
31
+ }
32
+ return false;
33
+ };
34
+ const prepareFilmstripItem = ({
35
+ allowLazyLoading,
36
+ enableDownloadButton,
37
+ handleMediaNodeRemoval,
38
+ getPos,
39
+ intl,
40
+ isMediaItemSelected,
41
+ setMediaGroupNodeSelection,
42
+ featureFlags
43
+ }) => (item, idx) => {
44
+ // We declared this to get a fresh position every time
45
+ const getNodePos = () => {
46
+ const pos = getPos();
47
+ if (typeof pos !== 'number') {
48
+ // That may seems weird, but the previous type wasn't match with the real ProseMirror code. And a lot of Media API was built expecting a number
49
+ // Because the original code would return NaN on runtime
50
+ // We are just make it explict now.
51
+ // We may run a deep investagation on Media code to figure out a better fix. But, for now, we want to keep the current behavior.
52
+ // TODO: ED-13910 prosemirror-bump leftovers
53
+ return NaN;
54
+ }
55
+ return pos + idx + 1;
56
+ };
57
+
58
+ // Media Inline creates a floating toolbar with the same options, excludes these options if enabled
59
+ const mediaInlineOptions = (allowMediaInline = false) => {
60
+ if (!allowMediaInline) {
61
+ return {
62
+ shouldEnableDownloadButton: enableDownloadButton,
63
+ actions: [{
64
+ handler: handleMediaNodeRemoval.bind(null, undefined, getNodePos),
65
+ icon: /*#__PURE__*/React.createElement(EditorCloseIcon, {
66
+ label: intl.formatMessage(messages.mediaGroupDeleteLabel)
67
+ })
68
+ }]
69
+ };
70
+ }
71
+ };
72
+ const mediaGroupPos = getPos();
73
+ return {
74
+ identifier: getIdentifier(item),
75
+ isLazy: allowLazyLoading,
76
+ selected: isMediaItemSelected(getNodePos(), typeof mediaGroupPos === 'number' ? mediaGroupPos : NaN),
77
+ onClick: () => {
78
+ setMediaGroupNodeSelection(getNodePos());
79
+ },
80
+ ...mediaInlineOptions(getMediaFeatureFlag('mediaInline', featureFlags))
81
+ };
82
+ };
83
+
84
+ /**
85
+ * Keep returning the same ProseMirror Node, unless the node content changed.
86
+ *
87
+ * React uses shallow comparation with `Object.is`,
88
+ * but that can cause multiple re-renders when the same node is given in a different instance.
89
+ *
90
+ * To avoid unnecessary re-renders, this hook uses the `Node.eq` from ProseMirror API to compare
91
+ * previous and new values.
92
+ */
93
+ const useLatestMediaGroupNode = nextMediaNode => {
94
+ const previousMediaNode = usePreviousState(nextMediaNode);
95
+ const [mediaNode, setMediaNode] = React.useState(nextMediaNode);
96
+ React.useEffect(() => {
97
+ if (!previousMediaNode) {
98
+ return;
99
+ }
100
+ if (!previousMediaNode.eq(nextMediaNode)) {
101
+ setMediaNode(nextMediaNode);
102
+ }
103
+ }, [previousMediaNode, nextMediaNode]);
104
+ return mediaNode;
105
+ };
106
+ const runMediaNodeUpdate = async ({
107
+ mediaNodeUpdater,
108
+ getPos,
109
+ node,
110
+ updateAttrs
111
+ }) => {
112
+ if (updateAttrs) {
113
+ await mediaNodeUpdater.updateNodeAttrs(getPos);
114
+ }
115
+ const contextId = mediaNodeUpdater.getNodeContextId();
116
+ if (!contextId) {
117
+ await mediaNodeUpdater.updateNodeContextId(getPos);
118
+ }
119
+ const hasDifferentContextId = await mediaNodeUpdater.hasDifferentContextId();
120
+ if (hasDifferentContextId) {
121
+ await mediaNodeUpdater.copyNodeFromPos(getPos, {
122
+ traceId: node.attrs.__mediaTraceId
123
+ });
124
+ }
125
+ };
126
+ const noop = () => {};
127
+ export const MediaGroupNext = injectIntl( /*#__PURE__*/React.memo(props => {
128
+ const {
129
+ mediaOptions: {
130
+ allowLazyLoading,
131
+ enableDownloadButton,
132
+ featureFlags
133
+ },
134
+ intl,
135
+ getPos,
136
+ anchorPos,
137
+ headPos,
138
+ view,
139
+ disabled,
140
+ editorViewMode,
141
+ mediaProvider,
142
+ contextIdentifierProvider,
143
+ isCopyPasteEnabled
144
+ } = props;
145
+ const mediaGroupNode = useLatestMediaGroupNode(props.node);
146
+ const mediaPluginState = useMemo(() => {
147
+ return mediaStateKey.getState(view.state);
148
+ }, [view.state]);
149
+ const mediaClientConfig = mediaPluginState === null || mediaPluginState === void 0 ? void 0 : mediaPluginState.mediaClientConfig;
150
+ const handleMediaGroupUpdate = mediaPluginState === null || mediaPluginState === void 0 ? void 0 : mediaPluginState.handleMediaGroupUpdate;
151
+ const [viewMediaClientConfig, setViewMediaClientConfig] = useState(undefined);
152
+ const nodeSize = mediaGroupNode.nodeSize;
153
+ const mediaNodesWithOffsets = useMemo(() => {
154
+ const result = [];
155
+ mediaGroupNode.forEach((item, childOffset) => {
156
+ result.push({
157
+ node: item,
158
+ offset: childOffset
159
+ });
160
+ });
161
+ return result;
162
+ }, [mediaGroupNode]);
163
+ const previousMediaNodesWithOffsets = usePreviousState(mediaNodesWithOffsets);
164
+ const handleMediaNodeRemoval = useMemo(() => {
165
+ return disabled || !mediaPluginState ? noop : mediaPluginState.handleMediaNodeRemoval;
166
+ }, [disabled, mediaPluginState]);
167
+ const setMediaGroupNodeSelection = useCallback(pos => {
168
+ setNodeSelection(view, pos);
169
+ }, [view]);
170
+ const isMediaItemSelected = useMemo(() => {
171
+ return isNodeSelected({
172
+ anchorPos,
173
+ headPos,
174
+ nodeSize
175
+ });
176
+ }, [anchorPos, headPos, nodeSize]);
177
+ const filmstripItem = useMemo(() => {
178
+ return prepareFilmstripItem({
179
+ allowLazyLoading,
180
+ enableDownloadButton,
181
+ handleMediaNodeRemoval,
182
+ getPos,
183
+ intl,
184
+ isMediaItemSelected,
185
+ setMediaGroupNodeSelection,
186
+ featureFlags
187
+ });
188
+ }, [allowLazyLoading, enableDownloadButton, handleMediaNodeRemoval, getPos, intl, isMediaItemSelected, setMediaGroupNodeSelection, featureFlags]);
189
+ const items = useMemo(() => {
190
+ return mediaNodesWithOffsets.map(({
191
+ node,
192
+ offset
193
+ }) => {
194
+ return filmstripItem(node, offset);
195
+ });
196
+ }, [mediaNodesWithOffsets, filmstripItem]);
197
+ useEffect(() => {
198
+ setViewMediaClientConfig(mediaClientConfig);
199
+ }, [mediaClientConfig]);
200
+ useEffect(() => {
201
+ mediaNodesWithOffsets.forEach(({
202
+ node,
203
+ offset
204
+ }) => {
205
+ const mediaNodeUpdater = createMediaNodeUpdater({
206
+ view,
207
+ mediaProvider,
208
+ contextIdentifierProvider,
209
+ node,
210
+ isMediaSingle: false
211
+ });
212
+ const updateAttrs = isCopyPasteEnabled || isCopyPasteEnabled === undefined;
213
+ runMediaNodeUpdate({
214
+ mediaNodeUpdater,
215
+ node,
216
+ updateAttrs,
217
+ getPos: () => {
218
+ const pos = getPos();
219
+ if (typeof pos !== 'number') {
220
+ return undefined;
221
+ }
222
+ return pos + offset + 1;
223
+ }
224
+ });
225
+ });
226
+ }, [view, contextIdentifierProvider, getPos, mediaProvider, mediaNodesWithOffsets, isCopyPasteEnabled]);
227
+ useEffect(() => {
228
+ if (!handleMediaGroupUpdate || !previousMediaNodesWithOffsets) {
229
+ return;
230
+ }
231
+ const old = previousMediaNodesWithOffsets.map(({
232
+ node
233
+ }) => node);
234
+ const next = mediaNodesWithOffsets.map(({
235
+ node
236
+ }) => node);
237
+ handleMediaGroupUpdate(old, next);
238
+ return () => {
239
+ handleMediaGroupUpdate(next, []);
240
+ };
241
+ }, [handleMediaGroupUpdate, mediaNodesWithOffsets, previousMediaNodesWithOffsets]);
242
+ return /*#__PURE__*/React.createElement(Filmstrip, {
243
+ items: items,
244
+ mediaClientConfig: viewMediaClientConfig,
245
+ featureFlags: featureFlags,
246
+ shouldOpenMediaViewer: editorViewMode
247
+ });
248
+ }));
249
+ MediaGroupNext.displayName = 'MediaGroup';
@@ -424,8 +424,7 @@ const hasPrivateAttrsChanged = (currentAttrs, newAttrs) => {
424
424
  };
425
425
  export const createMediaNodeUpdater = props => {
426
426
  const updaterProps = {
427
- ...props,
428
- isMediaSingle: true
427
+ ...props
429
428
  };
430
429
  return new MediaNodeUpdater(updaterProps);
431
430
  };
@@ -21,8 +21,10 @@ import { isNodeSelectedOrInRange, SelectedState, setNodeSelection } from '@atlas
21
21
  import EditorCloseIcon from '@atlaskit/icon/glyph/editor/close';
22
22
  import { getMediaFeatureFlag } from '@atlaskit/media-common';
23
23
  import { Filmstrip } from '@atlaskit/media-filmstrip';
24
+ import { fg } from '@atlaskit/platform-feature-flags';
24
25
  import { useMediaProvider } from '../hooks/useMediaProvider';
25
26
  import { stateKey as mediaStateKey } from '../pm-plugins/plugin-key';
27
+ import { MediaGroupNext } from './mediaGroupNext';
26
28
  import { MediaNodeUpdater } from './mediaNodeUpdater';
27
29
  var isMediaGroupSelectedFromProps = function isMediaGroupSelectedFromProps(props) {
28
30
  /**
@@ -339,6 +341,23 @@ var MediaGroupNodeView = /*#__PURE__*/function (_ReactNodeView) {
339
341
  if (!mediaProvider) {
340
342
  return null;
341
343
  }
344
+ if (fg('platform_editor_react18_phase2__media_single')) {
345
+ return /*#__PURE__*/React.createElement(MediaGroupNext, {
346
+ node: _this3.node,
347
+ getPos: getPos,
348
+ view: _this3.view,
349
+ forwardRef: forwardRef,
350
+ disabled: (editorDisabledPlugin || {}).editorDisabled,
351
+ allowLazyLoading: mediaOptions.allowLazyLoading,
352
+ mediaProvider: mediaProvider,
353
+ contextIdentifierProvider: contextIdentifierProvider,
354
+ isCopyPasteEnabled: mediaOptions.isCopyPasteEnabled,
355
+ anchorPos: _this3.view.state.selection.$anchor.pos,
356
+ headPos: _this3.view.state.selection.$head.pos,
357
+ mediaOptions: mediaOptions,
358
+ editorViewMode: (editorViewModePlugin === null || editorViewModePlugin === void 0 ? void 0 : editorViewModePlugin.mode) === 'view'
359
+ });
360
+ }
342
361
  return /*#__PURE__*/React.createElement(IntlMediaGroup, {
343
362
  node: _this3.node,
344
363
  getPos: getPos,
@@ -0,0 +1,285 @@
1
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
5
+ 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; }
6
+ 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; }
7
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
8
+ import { injectIntl } from 'react-intl-next';
9
+ import { usePreviousState } from '@atlaskit/editor-common/hooks';
10
+ import { nodeViewsMessages as messages } from '@atlaskit/editor-common/media';
11
+ import { isNodeSelectedOrInRange, SelectedState, setNodeSelection } from '@atlaskit/editor-common/utils';
12
+ import EditorCloseIcon from '@atlaskit/icon/glyph/editor/close';
13
+ import { getMediaFeatureFlag } from '@atlaskit/media-common';
14
+ import { Filmstrip } from '@atlaskit/media-filmstrip';
15
+ import { stateKey as mediaStateKey } from '../pm-plugins/plugin-key';
16
+ import { createMediaNodeUpdater } from './mediaNodeUpdater';
17
+ var getIdentifier = function getIdentifier(item) {
18
+ if (item.attrs.type === 'external') {
19
+ return {
20
+ mediaItemType: 'external-image',
21
+ dataURI: item.attrs.url
22
+ };
23
+ }
24
+ return {
25
+ id: item.attrs.id,
26
+ mediaItemType: 'file',
27
+ collectionName: item.attrs.collection
28
+ };
29
+ };
30
+ var isNodeSelected = function isNodeSelected(props) {
31
+ return function (mediaItemPos, mediaGroupPos) {
32
+ var selected = isNodeSelectedOrInRange(props.anchorPos, props.headPos, mediaGroupPos, props.nodeSize);
33
+ if (selected === SelectedState.selectedInRange) {
34
+ return true;
35
+ }
36
+ if (selected === SelectedState.selectedInside && props.anchorPos === mediaItemPos) {
37
+ return true;
38
+ }
39
+ return false;
40
+ };
41
+ };
42
+ var prepareFilmstripItem = function prepareFilmstripItem(_ref) {
43
+ var allowLazyLoading = _ref.allowLazyLoading,
44
+ enableDownloadButton = _ref.enableDownloadButton,
45
+ handleMediaNodeRemoval = _ref.handleMediaNodeRemoval,
46
+ getPos = _ref.getPos,
47
+ intl = _ref.intl,
48
+ isMediaItemSelected = _ref.isMediaItemSelected,
49
+ setMediaGroupNodeSelection = _ref.setMediaGroupNodeSelection,
50
+ featureFlags = _ref.featureFlags;
51
+ return function (item, idx) {
52
+ // We declared this to get a fresh position every time
53
+ var getNodePos = function getNodePos() {
54
+ var pos = getPos();
55
+ if (typeof pos !== 'number') {
56
+ // That may seems weird, but the previous type wasn't match with the real ProseMirror code. And a lot of Media API was built expecting a number
57
+ // Because the original code would return NaN on runtime
58
+ // We are just make it explict now.
59
+ // We may run a deep investagation on Media code to figure out a better fix. But, for now, we want to keep the current behavior.
60
+ // TODO: ED-13910 prosemirror-bump leftovers
61
+ return NaN;
62
+ }
63
+ return pos + idx + 1;
64
+ };
65
+
66
+ // Media Inline creates a floating toolbar with the same options, excludes these options if enabled
67
+ var mediaInlineOptions = function mediaInlineOptions() {
68
+ var allowMediaInline = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
69
+ if (!allowMediaInline) {
70
+ return {
71
+ shouldEnableDownloadButton: enableDownloadButton,
72
+ actions: [{
73
+ handler: handleMediaNodeRemoval.bind(null, undefined, getNodePos),
74
+ icon: /*#__PURE__*/React.createElement(EditorCloseIcon, {
75
+ label: intl.formatMessage(messages.mediaGroupDeleteLabel)
76
+ })
77
+ }]
78
+ };
79
+ }
80
+ };
81
+ var mediaGroupPos = getPos();
82
+ return _objectSpread({
83
+ identifier: getIdentifier(item),
84
+ isLazy: allowLazyLoading,
85
+ selected: isMediaItemSelected(getNodePos(), typeof mediaGroupPos === 'number' ? mediaGroupPos : NaN),
86
+ onClick: function onClick() {
87
+ setMediaGroupNodeSelection(getNodePos());
88
+ }
89
+ }, mediaInlineOptions(getMediaFeatureFlag('mediaInline', featureFlags)));
90
+ };
91
+ };
92
+
93
+ /**
94
+ * Keep returning the same ProseMirror Node, unless the node content changed.
95
+ *
96
+ * React uses shallow comparation with `Object.is`,
97
+ * but that can cause multiple re-renders when the same node is given in a different instance.
98
+ *
99
+ * To avoid unnecessary re-renders, this hook uses the `Node.eq` from ProseMirror API to compare
100
+ * previous and new values.
101
+ */
102
+ var useLatestMediaGroupNode = function useLatestMediaGroupNode(nextMediaNode) {
103
+ var previousMediaNode = usePreviousState(nextMediaNode);
104
+ var _React$useState = React.useState(nextMediaNode),
105
+ _React$useState2 = _slicedToArray(_React$useState, 2),
106
+ mediaNode = _React$useState2[0],
107
+ setMediaNode = _React$useState2[1];
108
+ React.useEffect(function () {
109
+ if (!previousMediaNode) {
110
+ return;
111
+ }
112
+ if (!previousMediaNode.eq(nextMediaNode)) {
113
+ setMediaNode(nextMediaNode);
114
+ }
115
+ }, [previousMediaNode, nextMediaNode]);
116
+ return mediaNode;
117
+ };
118
+ var runMediaNodeUpdate = /*#__PURE__*/function () {
119
+ var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref2) {
120
+ var mediaNodeUpdater, getPos, node, updateAttrs, contextId, hasDifferentContextId;
121
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
122
+ while (1) switch (_context.prev = _context.next) {
123
+ case 0:
124
+ mediaNodeUpdater = _ref2.mediaNodeUpdater, getPos = _ref2.getPos, node = _ref2.node, updateAttrs = _ref2.updateAttrs;
125
+ if (!updateAttrs) {
126
+ _context.next = 4;
127
+ break;
128
+ }
129
+ _context.next = 4;
130
+ return mediaNodeUpdater.updateNodeAttrs(getPos);
131
+ case 4:
132
+ contextId = mediaNodeUpdater.getNodeContextId();
133
+ if (contextId) {
134
+ _context.next = 8;
135
+ break;
136
+ }
137
+ _context.next = 8;
138
+ return mediaNodeUpdater.updateNodeContextId(getPos);
139
+ case 8:
140
+ _context.next = 10;
141
+ return mediaNodeUpdater.hasDifferentContextId();
142
+ case 10:
143
+ hasDifferentContextId = _context.sent;
144
+ if (!hasDifferentContextId) {
145
+ _context.next = 14;
146
+ break;
147
+ }
148
+ _context.next = 14;
149
+ return mediaNodeUpdater.copyNodeFromPos(getPos, {
150
+ traceId: node.attrs.__mediaTraceId
151
+ });
152
+ case 14:
153
+ case "end":
154
+ return _context.stop();
155
+ }
156
+ }, _callee);
157
+ }));
158
+ return function runMediaNodeUpdate(_x) {
159
+ return _ref3.apply(this, arguments);
160
+ };
161
+ }();
162
+ var noop = function noop() {};
163
+ export var MediaGroupNext = injectIntl( /*#__PURE__*/React.memo(function (props) {
164
+ var _props$mediaOptions = props.mediaOptions,
165
+ allowLazyLoading = _props$mediaOptions.allowLazyLoading,
166
+ enableDownloadButton = _props$mediaOptions.enableDownloadButton,
167
+ featureFlags = _props$mediaOptions.featureFlags,
168
+ intl = props.intl,
169
+ _getPos = props.getPos,
170
+ anchorPos = props.anchorPos,
171
+ headPos = props.headPos,
172
+ view = props.view,
173
+ disabled = props.disabled,
174
+ editorViewMode = props.editorViewMode,
175
+ mediaProvider = props.mediaProvider,
176
+ contextIdentifierProvider = props.contextIdentifierProvider,
177
+ isCopyPasteEnabled = props.isCopyPasteEnabled;
178
+ var mediaGroupNode = useLatestMediaGroupNode(props.node);
179
+ var mediaPluginState = useMemo(function () {
180
+ return mediaStateKey.getState(view.state);
181
+ }, [view.state]);
182
+ var mediaClientConfig = mediaPluginState === null || mediaPluginState === void 0 ? void 0 : mediaPluginState.mediaClientConfig;
183
+ var handleMediaGroupUpdate = mediaPluginState === null || mediaPluginState === void 0 ? void 0 : mediaPluginState.handleMediaGroupUpdate;
184
+ var _useState = useState(undefined),
185
+ _useState2 = _slicedToArray(_useState, 2),
186
+ viewMediaClientConfig = _useState2[0],
187
+ setViewMediaClientConfig = _useState2[1];
188
+ var nodeSize = mediaGroupNode.nodeSize;
189
+ var mediaNodesWithOffsets = useMemo(function () {
190
+ var result = [];
191
+ mediaGroupNode.forEach(function (item, childOffset) {
192
+ result.push({
193
+ node: item,
194
+ offset: childOffset
195
+ });
196
+ });
197
+ return result;
198
+ }, [mediaGroupNode]);
199
+ var previousMediaNodesWithOffsets = usePreviousState(mediaNodesWithOffsets);
200
+ var handleMediaNodeRemoval = useMemo(function () {
201
+ return disabled || !mediaPluginState ? noop : mediaPluginState.handleMediaNodeRemoval;
202
+ }, [disabled, mediaPluginState]);
203
+ var setMediaGroupNodeSelection = useCallback(function (pos) {
204
+ setNodeSelection(view, pos);
205
+ }, [view]);
206
+ var isMediaItemSelected = useMemo(function () {
207
+ return isNodeSelected({
208
+ anchorPos: anchorPos,
209
+ headPos: headPos,
210
+ nodeSize: nodeSize
211
+ });
212
+ }, [anchorPos, headPos, nodeSize]);
213
+ var filmstripItem = useMemo(function () {
214
+ return prepareFilmstripItem({
215
+ allowLazyLoading: allowLazyLoading,
216
+ enableDownloadButton: enableDownloadButton,
217
+ handleMediaNodeRemoval: handleMediaNodeRemoval,
218
+ getPos: _getPos,
219
+ intl: intl,
220
+ isMediaItemSelected: isMediaItemSelected,
221
+ setMediaGroupNodeSelection: setMediaGroupNodeSelection,
222
+ featureFlags: featureFlags
223
+ });
224
+ }, [allowLazyLoading, enableDownloadButton, handleMediaNodeRemoval, _getPos, intl, isMediaItemSelected, setMediaGroupNodeSelection, featureFlags]);
225
+ var items = useMemo(function () {
226
+ return mediaNodesWithOffsets.map(function (_ref4) {
227
+ var node = _ref4.node,
228
+ offset = _ref4.offset;
229
+ return filmstripItem(node, offset);
230
+ });
231
+ }, [mediaNodesWithOffsets, filmstripItem]);
232
+ useEffect(function () {
233
+ setViewMediaClientConfig(mediaClientConfig);
234
+ }, [mediaClientConfig]);
235
+ useEffect(function () {
236
+ mediaNodesWithOffsets.forEach(function (_ref5) {
237
+ var node = _ref5.node,
238
+ offset = _ref5.offset;
239
+ var mediaNodeUpdater = createMediaNodeUpdater({
240
+ view: view,
241
+ mediaProvider: mediaProvider,
242
+ contextIdentifierProvider: contextIdentifierProvider,
243
+ node: node,
244
+ isMediaSingle: false
245
+ });
246
+ var updateAttrs = isCopyPasteEnabled || isCopyPasteEnabled === undefined;
247
+ runMediaNodeUpdate({
248
+ mediaNodeUpdater: mediaNodeUpdater,
249
+ node: node,
250
+ updateAttrs: updateAttrs,
251
+ getPos: function getPos() {
252
+ var pos = _getPos();
253
+ if (typeof pos !== 'number') {
254
+ return undefined;
255
+ }
256
+ return pos + offset + 1;
257
+ }
258
+ });
259
+ });
260
+ }, [view, contextIdentifierProvider, _getPos, mediaProvider, mediaNodesWithOffsets, isCopyPasteEnabled]);
261
+ useEffect(function () {
262
+ if (!handleMediaGroupUpdate || !previousMediaNodesWithOffsets) {
263
+ return;
264
+ }
265
+ var old = previousMediaNodesWithOffsets.map(function (_ref6) {
266
+ var node = _ref6.node;
267
+ return node;
268
+ });
269
+ var next = mediaNodesWithOffsets.map(function (_ref7) {
270
+ var node = _ref7.node;
271
+ return node;
272
+ });
273
+ handleMediaGroupUpdate(old, next);
274
+ return function () {
275
+ handleMediaGroupUpdate(next, []);
276
+ };
277
+ }, [handleMediaGroupUpdate, mediaNodesWithOffsets, previousMediaNodesWithOffsets]);
278
+ return /*#__PURE__*/React.createElement(Filmstrip, {
279
+ items: items,
280
+ mediaClientConfig: viewMediaClientConfig,
281
+ featureFlags: featureFlags,
282
+ shouldOpenMediaViewer: editorViewMode
283
+ });
284
+ }));
285
+ MediaGroupNext.displayName = 'MediaGroup';
@@ -772,8 +772,6 @@ var hasPrivateAttrsChanged = function hasPrivateAttrsChanged(currentAttrs, newAt
772
772
  return currentAttrs.__fileName !== newAttrs.__fileName || currentAttrs.__fileMimeType !== newAttrs.__fileMimeType || currentAttrs.__fileSize !== newAttrs.__fileSize || currentAttrs.__contextId !== newAttrs.__contextId;
773
773
  };
774
774
  export var createMediaNodeUpdater = function createMediaNodeUpdater(props) {
775
- var updaterProps = _objectSpread(_objectSpread({}, props), {}, {
776
- isMediaSingle: true
777
- });
775
+ var updaterProps = _objectSpread({}, props);
778
776
  return new MediaNodeUpdater(updaterProps);
779
777
  };
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+ import type { WrappedComponentProps } from 'react-intl-next';
3
+ import type { ContextIdentifierProvider, MediaProvider } from '@atlaskit/editor-common/provider-factory';
4
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
5
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
6
+ import type { MediaOptions } from '../types';
7
+ export declare const MediaGroupNext: React.FC<import("react-intl-next").WithIntlProps<{
8
+ forwardRef?: ((ref: HTMLElement) => void) | undefined;
9
+ node: PMNode;
10
+ view: EditorView;
11
+ getPos: () => number | undefined;
12
+ disabled?: boolean | undefined;
13
+ editorViewMode?: boolean | undefined;
14
+ allowLazyLoading?: boolean | undefined;
15
+ mediaProvider: Promise<MediaProvider>;
16
+ contextIdentifierProvider?: Promise<ContextIdentifierProvider> | undefined;
17
+ isCopyPasteEnabled?: boolean | undefined;
18
+ anchorPos: number;
19
+ headPos: number;
20
+ mediaOptions: MediaOptions;
21
+ } & WrappedComponentProps>> & {
22
+ WrappedComponent: React.ComponentType<{
23
+ forwardRef?: ((ref: HTMLElement) => void) | undefined;
24
+ node: PMNode;
25
+ view: EditorView;
26
+ getPos: () => number | undefined;
27
+ disabled?: boolean | undefined;
28
+ editorViewMode?: boolean | undefined;
29
+ allowLazyLoading?: boolean | undefined;
30
+ mediaProvider: Promise<MediaProvider>;
31
+ contextIdentifierProvider?: Promise<ContextIdentifierProvider> | undefined;
32
+ isCopyPasteEnabled?: boolean | undefined;
33
+ anchorPos: number;
34
+ headPos: number;
35
+ mediaOptions: MediaOptions;
36
+ } & WrappedComponentProps>;
37
+ };
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+ import type { WrappedComponentProps } from 'react-intl-next';
3
+ import type { ContextIdentifierProvider, MediaProvider } from '@atlaskit/editor-common/provider-factory';
4
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
5
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
6
+ import type { MediaOptions } from '../types';
7
+ export declare const MediaGroupNext: React.FC<import("react-intl-next").WithIntlProps<{
8
+ forwardRef?: ((ref: HTMLElement) => void) | undefined;
9
+ node: PMNode;
10
+ view: EditorView;
11
+ getPos: () => number | undefined;
12
+ disabled?: boolean | undefined;
13
+ editorViewMode?: boolean | undefined;
14
+ allowLazyLoading?: boolean | undefined;
15
+ mediaProvider: Promise<MediaProvider>;
16
+ contextIdentifierProvider?: Promise<ContextIdentifierProvider> | undefined;
17
+ isCopyPasteEnabled?: boolean | undefined;
18
+ anchorPos: number;
19
+ headPos: number;
20
+ mediaOptions: MediaOptions;
21
+ } & WrappedComponentProps>> & {
22
+ WrappedComponent: React.ComponentType<{
23
+ forwardRef?: ((ref: HTMLElement) => void) | undefined;
24
+ node: PMNode;
25
+ view: EditorView;
26
+ getPos: () => number | undefined;
27
+ disabled?: boolean | undefined;
28
+ editorViewMode?: boolean | undefined;
29
+ allowLazyLoading?: boolean | undefined;
30
+ mediaProvider: Promise<MediaProvider>;
31
+ contextIdentifierProvider?: Promise<ContextIdentifierProvider> | undefined;
32
+ isCopyPasteEnabled?: boolean | undefined;
33
+ anchorPos: number;
34
+ headPos: number;
35
+ mediaOptions: MediaOptions;
36
+ } & WrappedComponentProps>;
37
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-media",
3
- "version": "1.36.5",
3
+ "version": "1.37.0",
4
4
  "description": "Media plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -32,14 +32,14 @@
32
32
  "./types": "./src/types.ts"
33
33
  },
34
34
  "dependencies": {
35
- "@atlaskit/adf-schema": "^42.0.2",
35
+ "@atlaskit/adf-schema": "^42.3.1",
36
36
  "@atlaskit/analytics-namespaced-context": "^6.12.0",
37
37
  "@atlaskit/analytics-next": "^10.1.0",
38
38
  "@atlaskit/button": "^20.2.0",
39
- "@atlaskit/editor-common": "^93.6.0",
39
+ "@atlaskit/editor-common": "^94.0.0",
40
40
  "@atlaskit/editor-palette": "1.6.1",
41
41
  "@atlaskit/editor-plugin-analytics": "^1.10.0",
42
- "@atlaskit/editor-plugin-annotation": "1.21.1",
42
+ "@atlaskit/editor-plugin-annotation": "1.21.2",
43
43
  "@atlaskit/editor-plugin-decorations": "^1.3.0",
44
44
  "@atlaskit/editor-plugin-editor-disabled": "^1.3.0",
45
45
  "@atlaskit/editor-plugin-editor-viewmode": "^2.1.0",
@@ -53,7 +53,7 @@
53
53
  "@atlaskit/editor-shared-styles": "^3.0.0",
54
54
  "@atlaskit/editor-tables": "^2.8.0",
55
55
  "@atlaskit/form": "^10.5.0",
56
- "@atlaskit/icon": "^22.22.0",
56
+ "@atlaskit/icon": "^22.23.0",
57
57
  "@atlaskit/media-card": "^78.7.0",
58
58
  "@atlaskit/media-client": "^28.0.0",
59
59
  "@atlaskit/media-client-react": "^2.2.0",