@selfcommunity/react-ui 0.7.0-alpha.314 → 0.7.0-alpha.316

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.
@@ -1,250 +1,20 @@
1
- import React, { Suspense, useCallback, useEffect, useRef, useState } from 'react';
2
- import { $getNodeByKey, $getSelection, $isNodeSelection, $setSelection, CLICK_COMMAND, COMMAND_PRIORITY_LOW, DecoratorNode, DRAGSTART_COMMAND, KEY_BACKSPACE_COMMAND, KEY_DELETE_COMMAND, KEY_ENTER_COMMAND, KEY_ESCAPE_COMMAND, SELECTION_CHANGE_COMMAND, TextNode } from 'lexical';
1
+ import React, { Suspense, useCallback, useEffect, useRef } from 'react';
2
+ import { $getNodeByKey, $getSelection, $isNodeSelection, $setSelection, CLICK_COMMAND, COMMAND_PRIORITY_LOW, DecoratorNode, KEY_BACKSPACE_COMMAND, KEY_DELETE_COMMAND, KEY_ENTER_COMMAND, KEY_ESCAPE_COMMAND, SELECTION_CHANGE_COMMAND, TextNode } from 'lexical';
3
3
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
4
4
  import { useLexicalNodeSelection } from '@lexical/react/useLexicalNodeSelection';
5
5
  import { mergeRegister } from '@lexical/utils';
6
- import { styled } from '@mui/material/styles';
7
- import { FormattedMessage } from 'react-intl';
8
- import { Box, Button, InputAdornment, Paper, TextField } from '@mui/material';
9
- const PREFIX = 'SCEditorImagePluginImageEdit';
10
- const classes = {
11
- root: `${PREFIX}-root`
12
- };
13
- const Root = styled(Box, {
14
- name: PREFIX,
15
- slot: 'Root',
16
- overridesResolver: (props, styles) => styles.root
17
- })(({ theme }) => ({
18
- position: 'absolute',
19
- top: 0,
20
- left: 0,
21
- zIndex: 2000,
22
- outline: `2px solid ${theme.palette.primary.main}`,
23
- userSelect: 'none',
24
- display: 'flex',
25
- justifyContent: 'center',
26
- alignItems: 'center',
27
- '& .MuiPaper-root': {
28
- padding: theme.spacing(1),
29
- display: 'flex',
30
- flexDirection: 'column',
31
- justifyContent: 'center',
32
- alignItems: 'center',
33
- width: '50%',
34
- backgroundColor: theme.palette.background.paper,
35
- '& > *': {
36
- margin: theme.spacing(1)
37
- }
38
- }
39
- }));
40
- const ImageEdit = ({ onResize, onDelete, imageRef }) => {
41
- // STATE
42
- const [width, setWidth] = useState(imageRef.current.width);
43
- const [height, setHeight] = useState(imageRef.current.height);
44
- const [openResizePanel, setOpenResizePanel] = useState(false);
45
- // HANDLERS
46
- const handleStopPropagation = (event) => {
47
- event.preventDefault();
48
- event.stopPropagation();
49
- return false;
50
- };
51
- const handleOpenResizePanel = (event) => {
52
- event.preventDefault();
53
- event.stopPropagation();
54
- setOpenResizePanel(true);
55
- return false;
56
- };
57
- const handleChangeWidth = (event) => {
58
- setWidth(event.target.value);
59
- };
60
- const handleChangeHeight = (event) => {
61
- setHeight(event.target.value);
62
- };
63
- const handleResize = (event) => {
64
- onResize(width, height);
65
- setOpenResizePanel(false);
66
- };
67
- // RENDER
68
- return (React.createElement(Root, { className: classes.root, style: { width: imageRef.current.width, height: imageRef.current.height }, contentEditable: false, onClick: handleStopPropagation },
69
- React.createElement(Paper, null, openResizePanel ? (React.createElement(React.Fragment, null,
70
- React.createElement(TextField, { value: width, type: "number", onChange: handleChangeWidth, label: React.createElement(FormattedMessage, { id: "ui.editor.imagePluginEdit.width", defaultMessage: "ui.editor.imagePluginEdit.width" }), InputProps: {
71
- endAdornment: React.createElement(InputAdornment, { position: "start" }, "px")
72
- } }),
73
- React.createElement(TextField, { value: height, type: "number", onChange: handleChangeHeight, label: React.createElement(FormattedMessage, { id: "ui.editor.imagePluginEdit.height", defaultMessage: "ui.editor.imagePluginEdit.height" }), InputProps: {
74
- endAdornment: React.createElement(InputAdornment, { position: "start" }, "px")
75
- } }),
76
- React.createElement(Button, { variant: "contained", color: "primary", disabled: width === imageRef.current.width && height === imageRef.current.height, onClick: handleResize },
77
- React.createElement(FormattedMessage, { id: "ui.editor.imagePluginEdit.resize", defaultMessage: "ui.editor.imagePluginEdit.resize" })))) : (React.createElement(React.Fragment, null,
78
- React.createElement(Button, { variant: "contained", color: "primary", onClick: handleOpenResizePanel },
79
- React.createElement(FormattedMessage, { id: "ui.editor.imagePluginEdit.resize", defaultMessage: "ui.editor.imagePluginEdit.resize" })),
80
- React.createElement(Button, { variant: "contained", color: "secondary", onClick: onDelete },
81
- React.createElement(FormattedMessage, { id: "ui.editor.imagePluginEdit.delete", defaultMessage: "ui.editor.imagePluginEdit.delete" })))))));
82
- };
83
- function clamp(value, min, max) {
84
- return Math.min(Math.max(value, min), Number(max));
85
- }
86
- const Direction = {
87
- east: 1 << 0,
88
- north: 1 << 3,
89
- south: 1 << 1,
90
- west: 1 << 2
91
- };
92
- function ImageResizer({ onResizeStart, onResizeEnd, imageRef, maxWidth, editor }) {
93
- const controlWrapperRef = useRef(null);
94
- const userSelect = useRef({
95
- priority: '',
96
- value: 'default'
97
- });
98
- const positioningRef = useRef({
99
- currentHeight: 0,
100
- currentWidth: 0,
101
- direction: 0,
102
- isResizing: false,
103
- ratio: 0,
104
- startHeight: 0,
105
- startWidth: 0,
106
- startX: 0,
107
- startY: 0
108
- });
109
- const editorRootElement = editor.getRootElement();
110
- // Find max width, accounting for editor padding.
111
- const maxWidthContainer = maxWidth ? maxWidth : editorRootElement !== null ? editorRootElement.getBoundingClientRect().width - 20 : 100;
112
- const maxHeightContainer = editorRootElement !== null ? editorRootElement.getBoundingClientRect().height - 20 : 100;
113
- const minWidth = 100;
114
- const minHeight = 100;
115
- const setStartCursor = (direction) => {
116
- const ew = direction === Direction.east || direction === Direction.west;
117
- const ns = direction === Direction.north || direction === Direction.south;
118
- const nwse = (direction & Direction.north && direction & Direction.west) || (direction & Direction.south && direction & Direction.east);
119
- const cursorDir = ew ? 'ew' : ns ? 'ns' : nwse ? 'nwse' : 'nesw';
120
- if (editorRootElement !== null) {
121
- editorRootElement.style.setProperty('cursor', `${cursorDir}-resize`, 'important');
122
- }
123
- if (document.body !== null) {
124
- document.body.style.setProperty('cursor', `${cursorDir}-resize`, 'important');
125
- userSelect.current.value = document.body.style.getPropertyValue('-webkit-user-select');
126
- userSelect.current.priority = document.body.style.getPropertyPriority('-webkit-user-select');
127
- document.body.style.setProperty('-webkit-user-select', `none`, 'important');
128
- }
129
- };
130
- const setEndCursor = () => {
131
- if (editorRootElement !== null) {
132
- editorRootElement.style.setProperty('cursor', 'text');
133
- }
134
- if (document.body !== null) {
135
- document.body.style.setProperty('cursor', 'default');
136
- document.body.style.setProperty('-webkit-user-select', userSelect.current.value, userSelect.current.priority);
137
- }
138
- };
139
- const handlePointerDown = (event, direction) => {
140
- if (!editor.isEditable()) {
141
- return;
142
- }
143
- const image = imageRef.current;
144
- const controlWrapper = controlWrapperRef.current;
145
- if (image !== null && controlWrapper !== null) {
146
- const { width, height } = image.getBoundingClientRect();
147
- const positioning = positioningRef.current;
148
- positioning.startWidth = width;
149
- positioning.startHeight = height;
150
- positioning.ratio = width / height;
151
- positioning.currentWidth = width;
152
- positioning.currentHeight = height;
153
- positioning.startX = event.clientX;
154
- positioning.startY = event.clientY;
155
- positioning.isResizing = true;
156
- positioning.direction = direction;
157
- setStartCursor(direction);
158
- onResizeStart();
159
- controlWrapper.classList.add('image-control-wrapper--resizing');
160
- image.style.height = `${height}px`;
161
- image.style.width = `${width}px`;
162
- document.addEventListener('pointermove', handlePointerMove);
163
- document.addEventListener('pointerup', handlePointerUp);
164
- }
165
- };
166
- const handlePointerMove = (event) => {
167
- const image = imageRef.current;
168
- const positioning = positioningRef.current;
169
- const isHorizontal = positioning.direction & (Direction.east | Direction.west);
170
- const isVertical = positioning.direction & (Direction.south | Direction.north);
171
- if (image !== null && positioning.isResizing) {
172
- // Corner cursor
173
- if (isHorizontal && isVertical) {
174
- let diff = Math.floor(positioning.startX - event.clientX);
175
- diff = positioning.direction & Direction.east ? -diff : diff;
176
- const width = clamp(positioning.startWidth + diff, minWidth, maxWidthContainer);
177
- const height = width / positioning.ratio;
178
- image.style.width = `${width}px`;
179
- image.style.height = `${height}px`;
180
- positioning.currentHeight = height;
181
- positioning.currentWidth = width;
182
- }
183
- else if (isVertical) {
184
- let diff = Math.floor(positioning.startY - event.clientY);
185
- diff = positioning.direction & Direction.south ? -diff : diff;
186
- const height = clamp(positioning.startHeight + diff, minHeight, maxHeightContainer);
187
- image.style.height = `${height}px`;
188
- positioning.currentHeight = height;
189
- }
190
- else {
191
- let diff = Math.floor(positioning.startX - event.clientX);
192
- diff = positioning.direction & Direction.east ? -diff : diff;
193
- const width = clamp(positioning.startWidth + diff, minWidth, maxWidthContainer);
194
- image.style.width = `${width}px`;
195
- positioning.currentWidth = width;
196
- }
197
- }
198
- };
199
- const handlePointerUp = () => {
200
- const image = imageRef.current;
201
- const positioning = positioningRef.current;
202
- const controlWrapper = controlWrapperRef.current;
203
- if (image !== null && controlWrapper !== null && positioning.isResizing) {
204
- const width = positioning.currentWidth;
205
- const height = positioning.currentHeight;
206
- positioning.startWidth = 0;
207
- positioning.startHeight = 0;
208
- positioning.ratio = 0;
209
- positioning.startX = 0;
210
- positioning.startY = 0;
211
- positioning.currentWidth = 0;
212
- positioning.currentHeight = 0;
213
- positioning.isResizing = false;
214
- controlWrapper.classList.remove('image-control-wrapper--resizing');
215
- setEndCursor();
216
- console.log(width);
217
- console.log(height);
218
- onResizeEnd(width, height);
219
- document.removeEventListener('pointermove', handlePointerMove);
220
- document.removeEventListener('pointerup', handlePointerUp);
221
- }
222
- };
223
- return (React.createElement("div", { ref: controlWrapperRef },
224
- React.createElement("div", { className: "image-resizer image-resizer-n", onPointerDown: (event) => {
225
- handlePointerDown(event, Direction.north);
226
- } }),
227
- React.createElement("div", { className: "image-resizer image-resizer-ne", onPointerDown: (event) => {
228
- handlePointerDown(event, Direction.north | Direction.east);
229
- } }),
230
- React.createElement("div", { className: "image-resizer image-resizer-e", onPointerDown: (event) => {
231
- handlePointerDown(event, Direction.east);
232
- } }),
233
- React.createElement("div", { className: "image-resizer image-resizer-se", onPointerDown: (event) => {
234
- handlePointerDown(event, Direction.south | Direction.east);
235
- } }),
236
- React.createElement("div", { className: "image-resizer image-resizer-s", onPointerDown: (event) => {
237
- handlePointerDown(event, Direction.south);
238
- } }),
239
- React.createElement("div", { className: "image-resizer image-resizer-sw", onPointerDown: (event) => {
240
- handlePointerDown(event, Direction.south | Direction.west);
241
- } }),
242
- React.createElement("div", { className: "image-resizer image-resizer-w", onPointerDown: (event) => {
243
- handlePointerDown(event, Direction.west);
244
- } }),
245
- React.createElement("div", { className: "image-resizer image-resizer-nw", onPointerDown: (event) => {
246
- handlePointerDown(event, Direction.north | Direction.west);
247
- } })));
6
+ /**
7
+ * Limit the width of an image
8
+ * Used to compute the padding-bottom of the div that wrap the img
9
+ */
10
+ const IMAGE_WIDTH_THRESHOLD = 500;
11
+ /**
12
+ * Calc aspect-ratio of image
13
+ * @param width
14
+ * @param height
15
+ */
16
+ function getAspectRatio(width, height) {
17
+ return width / height;
248
18
  }
249
19
  const imageCache = new Set();
250
20
  function useSuspenseImage(src) {
@@ -259,21 +29,21 @@ function useSuspenseImage(src) {
259
29
  });
260
30
  }
261
31
  }
262
- function LazyImage({ altText, className, imageRef, src, width, height, maxWidth }) {
32
+ function LazyImage({ altText, className, imageRef, src, width, height }) {
263
33
  useSuspenseImage(src);
264
- return (React.createElement("img", { className: className, src: src, alt: altText, ref: imageRef, style: {
265
- height: `${height}${height === 'inherit' ? '' : 'px'}`,
266
- maxWidth,
267
- width: `${width}${width === 'inherit' ? '' : 'px'}`
268
- } }));
34
+ const aspectRatio = getAspectRatio(IMAGE_WIDTH_THRESHOLD, height);
35
+ return (React.createElement("div", { draggable: false, className: className, style: { position: 'relative', paddingBottom: `${100 / aspectRatio}%` } },
36
+ React.createElement("img", { src: src, alt: altText, ref: imageRef, style: {
37
+ position: 'absolute',
38
+ height: `100%`,
39
+ width: `100%`
40
+ } })));
269
41
  }
270
- function ImageComponent({ src, altText, nodeKey, width, height, maxWidth, resizable }) {
42
+ function ImageComponent({ src, altText, nodeKey, width, height }) {
271
43
  const imageRef = useRef(null);
272
44
  const buttonRef = useRef(null);
273
45
  const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection(nodeKey);
274
- const [isResizing, setIsResizing] = useState(false);
275
46
  const [editor] = useLexicalComposerContext();
276
- const [selection, setSelection] = useState(null);
277
47
  const activeEditorRef = useRef(null);
278
48
  const onDelete = useCallback((payload) => {
279
49
  if (isSelected && $isNodeSelection($getSelection())) {
@@ -314,19 +84,11 @@ function ImageComponent({ src, altText, nodeKey, width, height, maxWidth, resiza
314
84
  return false;
315
85
  }, [editor, setSelected]);
316
86
  useEffect(() => {
317
- let isMounted = true;
318
- const unregister = mergeRegister(editor.registerUpdateListener(({ editorState }) => {
319
- if (isMounted) {
320
- setSelection(editorState.read(() => $getSelection()));
321
- }
322
- }), editor.registerCommand(SELECTION_CHANGE_COMMAND, (_, activeEditor) => {
87
+ const unregister = mergeRegister(editor.registerCommand(SELECTION_CHANGE_COMMAND, (_, activeEditor) => {
323
88
  activeEditorRef.current = activeEditor;
324
89
  return false;
325
90
  }, COMMAND_PRIORITY_LOW), editor.registerCommand(CLICK_COMMAND, (payload) => {
326
91
  const event = payload;
327
- if (isResizing) {
328
- return true;
329
- }
330
92
  if (event.target === imageRef.current) {
331
93
  if (event.shiftKey) {
332
94
  setSelected(!isSelected);
@@ -338,65 +100,36 @@ function ImageComponent({ src, altText, nodeKey, width, height, maxWidth, resiza
338
100
  return true;
339
101
  }
340
102
  return false;
341
- }, COMMAND_PRIORITY_LOW), editor.registerCommand(DRAGSTART_COMMAND, (event) => {
342
- if (event.target === imageRef.current) {
343
- // TODO This is just a temporary workaround for FF to behave like other browsers.
344
- // Ideally, this handles drag & drop too (and all browsers).
345
- event.preventDefault();
346
- return true;
347
- }
348
- return false;
349
103
  }, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_DELETE_COMMAND, onDelete, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_BACKSPACE_COMMAND, onDelete, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_ENTER_COMMAND, onEnter, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_ESCAPE_COMMAND, onEscape, COMMAND_PRIORITY_LOW));
350
104
  return () => {
351
- isMounted = false;
352
105
  unregister();
353
106
  };
354
- }, [clearSelection, editor, isResizing, isSelected, nodeKey, onDelete, onEnter, onEscape, setSelected]);
355
- const onResizeEnd = (nextWidth, nextHeight) => {
356
- // Delay hiding the resize bars for click case
357
- setTimeout(() => {
358
- setIsResizing(false);
359
- }, 200);
360
- editor.update(() => {
361
- const node = $getNodeByKey(nodeKey);
362
- if ($isImageNode(node)) {
363
- node.setWidthAndHeight(nextWidth, nextHeight);
364
- }
365
- });
366
- };
367
- const onResizeStart = () => {
368
- setIsResizing(true);
369
- };
370
- const draggable = isSelected && $isNodeSelection(selection) && !isResizing;
371
- const isFocused = isSelected || isResizing;
107
+ }, [clearSelection, editor, isSelected, nodeKey, onDelete, onEnter, onEscape, setSelected]);
108
+ const isFocused = isSelected;
372
109
  return (React.createElement(Suspense, { fallback: null },
373
- React.createElement(React.Fragment, null,
374
- React.createElement("div", { draggable: draggable },
375
- React.createElement(LazyImage, { className: isFocused ? `focused ${$isNodeSelection(selection) ? 'draggable' : ''}` : null, src: src, altText: altText, imageRef: imageRef, width: width, height: height, maxWidth: maxWidth })),
376
- resizable && $isNodeSelection(selection) && isFocused && (React.createElement(ImageResizer, { editor: editor, imageRef: imageRef, maxWidth: typeof maxWidth === 'number' ? maxWidth : null, onResizeStart: onResizeStart, onResizeEnd: onResizeEnd })))));
110
+ React.createElement(LazyImage, { className: isFocused ? `focused` : null, src: src, altText: altText, imageRef: imageRef, width: width, height: height })));
377
111
  }
378
112
  function convertImageElement(domNode) {
379
113
  if (domNode instanceof HTMLImageElement) {
380
- const { alt: altText, src, width, height } = domNode;
381
- const node = $createImageNode({ altText, height, src, width, maxWidth: '100%' });
114
+ const { alt: altText, src, dataset: { width, height } } = domNode;
115
+ const node = $createImageNode({ altText, height: Number(height), src, width: Number(width) });
382
116
  return { node };
383
117
  }
384
118
  return null;
385
119
  }
386
120
  export class ImageNode extends DecoratorNode {
387
- constructor(src, altText, maxWidth, width, height, key) {
121
+ constructor(src, altText, width, height, key) {
388
122
  super(key);
389
123
  this.__src = src;
390
124
  this.__altText = altText;
391
- this.__maxWidth = maxWidth;
392
- this.__width = width || 'inherit';
393
- this.__height = height || 'inherit';
125
+ this.__width = width;
126
+ this.__height = height;
394
127
  }
395
128
  static getType() {
396
129
  return 'image';
397
130
  }
398
131
  static clone(node) {
399
- return new ImageNode(node.__src, node.__altText, node.__maxWidth, node.__width, node.__height, node.__key);
132
+ return new ImageNode(node.__src, node.__altText, node.__width, node.__height, node.__key);
400
133
  }
401
134
  setWidthAndHeight(width, height) {
402
135
  const writable = this.getWritable();
@@ -430,24 +163,26 @@ export class ImageNode extends DecoratorNode {
430
163
  }) }, dom);
431
164
  }
432
165
  exportDOM() {
433
- const element = document.createElement('img');
434
- element.setAttribute('src', this.__src);
435
- element.setAttribute('alt', this.__altText);
436
- element.setAttribute('width', `${this.__width}`);
437
- element.setAttribute('height', `${this.__height}`);
438
- element.setAttribute('style', `max-width: ${this.__maxWidth}px;`);
166
+ const aspectRatio = getAspectRatio(this.__width, this.__height);
167
+ const element = document.createElement('div');
168
+ element.setAttribute('style', `position: relative;padding-bottom:${100 / aspectRatio}%`);
169
+ const image = document.createElement('img');
170
+ image.setAttribute('src', this.__src);
171
+ image.setAttribute('alt', this.__altText);
172
+ image.setAttribute('style', `position: absolute;width:100%;height:100%;`);
173
+ image.setAttribute('data-width', `${this.__width}`);
174
+ image.setAttribute('data-height', `${this.__height}`);
175
+ element.appendChild(image);
439
176
  return { element };
440
177
  }
441
178
  decorate() {
442
- console.log(this.__maxWidth);
443
- return (React.createElement(ImageComponent, { src: this.__src, altText: this.__altText, width: this.__width, height: this.__height, maxWidth: this.__maxWidth, nodeKey: this.getKey(), resizable: true }));
179
+ return React.createElement(ImageComponent, { src: this.__src, altText: this.__altText, width: this.__width, height: this.__height, nodeKey: this.getKey() });
444
180
  }
445
181
  static importJSON(serializedNode) {
446
- const { altText, height, width, maxWidth, src } = serializedNode;
182
+ const { altText, height, width, src } = serializedNode;
447
183
  const node = $createImageNode({
448
184
  altText,
449
185
  height,
450
- maxWidth,
451
186
  src,
452
187
  width
453
188
  });
@@ -456,17 +191,16 @@ export class ImageNode extends DecoratorNode {
456
191
  exportJSON() {
457
192
  return {
458
193
  altText: this.getAltText(),
459
- height: this.__height === 'inherit' ? 0 : this.__height,
460
- maxWidth: this.__maxWidth,
194
+ height: this.__height,
461
195
  src: this.getSrc(),
462
196
  type: 'image',
463
197
  version: 1,
464
- width: this.__width === 'inherit' ? 0 : this.__width
198
+ width: this.__width
465
199
  };
466
200
  }
467
201
  }
468
- export function $createImageNode({ src, altText, maxWidth, width = null, height = null }) {
469
- return new ImageNode(src, altText, maxWidth, width, height);
202
+ export function $createImageNode({ src, altText, width, height }) {
203
+ return new ImageNode(src, altText, width, height);
470
204
  }
471
205
  export function $isImageNode(node) {
472
206
  return node.getType() === 'image';
@@ -91,7 +91,7 @@ export default function ImagePlugin() {
91
91
  if ($isRootNode(selection.anchor.getNode())) {
92
92
  selection.insertParagraph();
93
93
  }
94
- const imageNode = $createImageNode({ src: payload.src, altText: payload.altText, maxWidth: '100%', width: payload.width, height: payload.height });
94
+ const imageNode = $createImageNode({ src: payload.src, altText: payload.altText, width: payload.width, height: payload.height });
95
95
  selection.insertNodes([imageNode]);
96
96
  }
97
97
  return true;
@@ -2,7 +2,7 @@
2
2
  import React, { forwardRef, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
3
3
  import { Link, SCCache, SCPreferences, SCPreferencesContext, SCUserContext, useSCFetchFeed, usePreviousValue, useIsComponentMountedRef } from '@selfcommunity/react-core';
4
4
  import { styled, useTheme } from '@mui/material/styles';
5
- import { Box, CardContent, Grid, Hidden, useMediaQuery } from "@mui/material";
5
+ import { Box, CardContent, Grid, Hidden, useMediaQuery } from '@mui/material';
6
6
  import { FormattedMessage } from 'react-intl';
7
7
  import { GenericSkeleton } from '../Skeleton';
8
8
  import CustomAdv from '../CustomAdv';
@@ -25,6 +25,7 @@ const PREFIX = 'SCFeed';
25
25
  const classes = {
26
26
  root: `${PREFIX}-root`,
27
27
  left: `${PREFIX}-left`,
28
+ leftItems: `${PREFIX}-left-items`,
28
29
  start: `${PREFIX}-start`,
29
30
  end: `${PREFIX}-end`,
30
31
  endMessage: `${PREFIX}-end-message`,
@@ -411,14 +412,14 @@ const Feed = (inProps, ref) => {
411
412
  React.createElement(CustomAdv, Object.assign({ position: SCCustomAdvPosition.POSITION_BELOW_TOPBAR }, CustomAdvProps)))) : null,
412
413
  React.createElement(Grid, { item: true, xs: 12, md: 7 },
413
414
  React.createElement("div", { style: { overflow: 'visible' } },
414
- React.createElement(InfiniteScroll, { className: classes.left, dataLength: feedDataLeft.length, next: getNextPage, previous: getPreviousPage, hasMoreNext: Boolean(feedDataObject.next), hasMorePrevious: Boolean(feedDataObject.previous), header: PreviousPageLink, footer: NextPageLink, loaderNext: React.createElement(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), loaderPrevious: React.createElement(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), scrollThreshold: 1, endMessage: React.createElement(Box, { className: classes.end },
415
+ React.createElement(InfiniteScroll, { className: classes.left, dataLength: feedDataLeft.length, next: getNextPage, previous: getPreviousPage, hasMoreNext: Boolean(feedDataObject.next), hasMorePrevious: Boolean(feedDataObject.previous), header: PreviousPageLink, footer: NextPageLink, loaderNext: React.createElement(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), loaderPrevious: React.createElement(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), scrollThreshold: '80%', endMessage: React.createElement(Box, { className: classes.end },
415
416
  React.createElement(Widget, { className: classes.endMessage },
416
417
  React.createElement(CardContent, null, endMessage)),
417
418
  advEnabled && !hideAdvs && enabledCustomAdvPositions.includes(SCCustomAdvPosition.POSITION_ABOVE_FOOTER_BAR) ? (React.createElement(CustomAdv, Object.assign({ position: SCCustomAdvPosition.POSITION_ABOVE_FOOTER_BAR }, CustomAdvProps))) : null,
418
419
  FooterComponent ? React.createElement(FooterComponent, Object.assign({}, FooterComponentProps)) : null), refreshFunction: refresh, pullDownToRefresh: true, pullDownToRefreshThreshold: 1000, pullDownToRefreshContent: null, releaseToRefreshContent: React.createElement(Widget, { variant: "outlined", className: classes.refresh },
419
420
  React.createElement(CardContent, null, refreshMessage)), style: { overflow: 'visible' } },
420
421
  renderHeaderComponent(),
421
- React.createElement(VirtualizedScroller, Object.assign({ items: feedDataLeft, itemComponent: InnerItem, onMount: onScrollerMount, onScrollerStateChange: onScrollerStateChange, getItemId: getScrollItemId, preserveScrollPosition: true, preserveScrollPositionOnPrependItems: true, cacheScrollStateKey: SCCache.getVirtualizedScrollStateCacheKey(id), cacheScrollerPositionKey: SCCache.getFeedSPCacheKey(id), cacheStrategy: cacheStrategy }, VirtualizedScrollerProps))))),
422
+ React.createElement(VirtualizedScroller, Object.assign({ className: classes.leftItems, items: feedDataLeft, itemComponent: InnerItem, onMount: onScrollerMount, onScrollerStateChange: onScrollerStateChange, getItemId: getScrollItemId, preserveScrollPosition: true, preserveScrollPositionOnPrependItems: true, cacheScrollStateKey: SCCache.getVirtualizedScrollStateCacheKey(id), cacheScrollerPositionKey: SCCache.getFeedSPCacheKey(id), cacheStrategy: cacheStrategy }, VirtualizedScrollerProps))))),
422
423
  feedDataRight.length > 0 && !hideAdvs && (React.createElement(Hidden, { smDown: true },
423
424
  React.createElement(Grid, { item: true, xs: 12, md: 5 },
424
425
  React.createElement(StickyBoxComp, Object.assign({ className: classes.right }, FeedSidebarProps),