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

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,10 @@
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
+ function getAspectRatio(width, height) {
7
+ return width / height;
248
8
  }
249
9
  const imageCache = new Set();
250
10
  function useSuspenseImage(src) {
@@ -259,21 +19,21 @@ function useSuspenseImage(src) {
259
19
  });
260
20
  }
261
21
  }
262
- function LazyImage({ altText, className, imageRef, src, width, height, maxWidth }) {
22
+ function LazyImage({ altText, className, imageRef, src, width, height }) {
263
23
  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
- } }));
24
+ const aspectRatio = getAspectRatio(width, height);
25
+ return (React.createElement("div", { draggable: false, className: className, style: { position: 'relative', paddingBottom: `${100 / aspectRatio}%` } },
26
+ React.createElement("img", { src: src, alt: altText, ref: imageRef, style: {
27
+ position: 'absolute',
28
+ height: `100%`,
29
+ width: `100%`
30
+ } })));
269
31
  }
270
- function ImageComponent({ src, altText, nodeKey, width, height, maxWidth, resizable }) {
32
+ function ImageComponent({ src, altText, nodeKey, width, height }) {
271
33
  const imageRef = useRef(null);
272
34
  const buttonRef = useRef(null);
273
35
  const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection(nodeKey);
274
- const [isResizing, setIsResizing] = useState(false);
275
36
  const [editor] = useLexicalComposerContext();
276
- const [selection, setSelection] = useState(null);
277
37
  const activeEditorRef = useRef(null);
278
38
  const onDelete = useCallback((payload) => {
279
39
  if (isSelected && $isNodeSelection($getSelection())) {
@@ -314,19 +74,11 @@ function ImageComponent({ src, altText, nodeKey, width, height, maxWidth, resiza
314
74
  return false;
315
75
  }, [editor, setSelected]);
316
76
  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) => {
77
+ const unregister = mergeRegister(editor.registerCommand(SELECTION_CHANGE_COMMAND, (_, activeEditor) => {
323
78
  activeEditorRef.current = activeEditor;
324
79
  return false;
325
80
  }, COMMAND_PRIORITY_LOW), editor.registerCommand(CLICK_COMMAND, (payload) => {
326
81
  const event = payload;
327
- if (isResizing) {
328
- return true;
329
- }
330
82
  if (event.target === imageRef.current) {
331
83
  if (event.shiftKey) {
332
84
  setSelected(!isSelected);
@@ -338,65 +90,36 @@ function ImageComponent({ src, altText, nodeKey, width, height, maxWidth, resiza
338
90
  return true;
339
91
  }
340
92
  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
93
  }, 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
94
  return () => {
351
- isMounted = false;
352
95
  unregister();
353
96
  };
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;
97
+ }, [clearSelection, editor, isSelected, nodeKey, onDelete, onEnter, onEscape, setSelected]);
98
+ const isFocused = isSelected;
372
99
  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 })))));
100
+ React.createElement(LazyImage, { className: isFocused ? `focused` : null, src: src, altText: altText, imageRef: imageRef, width: width, height: height })));
377
101
  }
378
102
  function convertImageElement(domNode) {
379
103
  if (domNode instanceof HTMLImageElement) {
380
- const { alt: altText, src, width, height } = domNode;
381
- const node = $createImageNode({ altText, height, src, width, maxWidth: '100%' });
104
+ const { alt: altText, src, dataset: { width, height } } = domNode;
105
+ const node = $createImageNode({ altText, height: Number(height), src, width: Number(width) });
382
106
  return { node };
383
107
  }
384
108
  return null;
385
109
  }
386
110
  export class ImageNode extends DecoratorNode {
387
- constructor(src, altText, maxWidth, width, height, key) {
111
+ constructor(src, altText, width, height, key) {
388
112
  super(key);
389
113
  this.__src = src;
390
114
  this.__altText = altText;
391
- this.__maxWidth = maxWidth;
392
- this.__width = width || 'inherit';
393
- this.__height = height || 'inherit';
115
+ this.__width = width;
116
+ this.__height = height;
394
117
  }
395
118
  static getType() {
396
119
  return 'image';
397
120
  }
398
121
  static clone(node) {
399
- return new ImageNode(node.__src, node.__altText, node.__maxWidth, node.__width, node.__height, node.__key);
122
+ return new ImageNode(node.__src, node.__altText, node.__width, node.__height, node.__key);
400
123
  }
401
124
  setWidthAndHeight(width, height) {
402
125
  const writable = this.getWritable();
@@ -430,24 +153,26 @@ export class ImageNode extends DecoratorNode {
430
153
  }) }, dom);
431
154
  }
432
155
  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;`);
156
+ const aspectRatio = getAspectRatio(this.__width, this.__height);
157
+ const element = document.createElement('div');
158
+ element.setAttribute('style', `position: relative;padding-bottom:${100 / aspectRatio}%`);
159
+ const image = document.createElement('img');
160
+ image.setAttribute('src', this.__src);
161
+ image.setAttribute('alt', this.__altText);
162
+ image.setAttribute('style', `position: absolute;width:100%;height:100%;`);
163
+ image.setAttribute('data-width', `${this.__width}`);
164
+ image.setAttribute('data-height', `${this.__height}`);
165
+ element.appendChild(image);
439
166
  return { element };
440
167
  }
441
168
  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 }));
169
+ return (React.createElement(ImageComponent, { src: this.__src, altText: this.__altText, width: this.__width, height: this.__height, nodeKey: this.getKey() }));
444
170
  }
445
171
  static importJSON(serializedNode) {
446
- const { altText, height, width, maxWidth, src } = serializedNode;
172
+ const { altText, height, width, src } = serializedNode;
447
173
  const node = $createImageNode({
448
174
  altText,
449
175
  height,
450
- maxWidth,
451
176
  src,
452
177
  width
453
178
  });
@@ -456,17 +181,16 @@ export class ImageNode extends DecoratorNode {
456
181
  exportJSON() {
457
182
  return {
458
183
  altText: this.getAltText(),
459
- height: this.__height === 'inherit' ? 0 : this.__height,
460
- maxWidth: this.__maxWidth,
184
+ height: this.__height,
461
185
  src: this.getSrc(),
462
186
  type: 'image',
463
187
  version: 1,
464
- width: this.__width === 'inherit' ? 0 : this.__width
188
+ width: this.__width
465
189
  };
466
190
  }
467
191
  }
468
- export function $createImageNode({ src, altText, maxWidth, width = null, height = null }) {
469
- return new ImageNode(src, altText, maxWidth, width, height);
192
+ export function $createImageNode({ src, altText, width, height }) {
193
+ return new ImageNode(src, altText, width, height);
470
194
  }
471
195
  export function $isImageNode(node) {
472
196
  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),