Skip to content

Commit 7908acd

Browse files
refactor(SlidesPanel): performance improvements & refactor
1 parent ca32d3c commit 7908acd

File tree

6 files changed

+47
-45
lines changed

6 files changed

+47
-45
lines changed

src/components/Panels/SlidesPanel/ListWrapper.js

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ const ListWrapper = ({
1616
reportSettings,
1717
...otherProps
1818
}) => {
19-
const outerRef = useRef(null);
19+
const listRef = useRef(null);
2020
const [selectedPageIndex, setSelectedPageIndex] = useState(-1);
21-
const [scrollTracking, setScrollTracking] = useState(true);
2221
const {
2322
reportBackgroundColor,
2423
reportLayoutHeight = 794,
@@ -40,55 +39,69 @@ const ListWrapper = ({
4039

4140
const _onSortEnd = useCallback((sortEvent, nativeEvent) => {
4241
if (onSortEnd) {
43-
onSortEnd(sortEvent, nativeEvent, outerRef.current);
42+
onSortEnd(sortEvent, nativeEvent, listRef.current);
4443
}
4544
}, [onSortEnd]);
4645

47-
useEffect(() => {
48-
if (selectedPageIndex !== -1) {
49-
const instance = outerRef.current.getWrappedInstance();
50-
const list = instance.sortablePageListRef.current;
51-
list.scrollToItem(selectedPageIndex);
46+
const refSetter = useCallback(outerRef => {
47+
if (outerRef) {
48+
const instance = outerRef.getWrappedInstance();
49+
if (instance) {
50+
listRef.current = instance.sortablePageListRef.current;
51+
}
5252
}
53-
}, [selectedPageIndex]);
54-
55-
useEffect(() => { // for page thumbnails actions
56-
if (!scrollTracking) {
57-
scrollToTarget(`pageActions-id-${selectedPageIndex}`, 0, {});
58-
setScrollTracking(true);
59-
}
60-
}, [pageCount]);
53+
}, []);
6154

6255
usePageVisibility(index => {
63-
if (scrollTracking && index !== selectedPageIndex && !Number.isNaN(index)) {
64-
setSelectedPageIndex(index);
65-
} else if (!scrollTracking && index === selectedPageIndex) {
66-
setScrollTracking(true);
56+
if (index && !Number.isNaN(index)) {
57+
listRef.current?.scrollToItem(index, 'center');
58+
59+
const prevSelectedThumbnail = document.querySelector('.thumbnailWrapper.isSelected');
60+
if (prevSelectedThumbnail) {
61+
prevSelectedThumbnail.classList.remove('isSelected');
62+
}
63+
64+
const nextSelectedThumbnail = document
65+
.querySelector(`.thumbnailWrapper[data-order="${index}"]`);
66+
if (nextSelectedThumbnail) {
67+
nextSelectedThumbnail.classList.add('isSelected');
68+
}
6769
}
68-
}, scrollTracking, pageCount, selectedPageIndex);
70+
}, pageCount, selectedPageIndex);
71+
72+
// TODO: could be better than now. scrollend listener is a choice for some cases
73+
const resetSelectedPageIndex = useCallback(() => {
74+
setTimeout(() => {
75+
setSelectedPageIndex(-1);
76+
}, 1000);
77+
}, []);
6978

7079
const onPageClick = useCallback(e => {
7180
const order = e.target.getAttribute('data-order');
72-
setScrollTracking(false);
7381
setSelectedPageIndex(parseInt(order, 10));
7482
if (!e.target.classList.contains('controllerItem')) { // for page thumbnails actions
7583
scrollToTarget(`pageActions-id-${order}`);
7684
}
85+
resetSelectedPageIndex();
7786
}, []);
7887

7988
const handlePageAdd = useCallback(index => {
80-
setScrollTracking(false);
8189
setSelectedPageIndex(index);
8290
onPageAdd(index);
8391
}, [onPageAdd]);
8492

93+
useEffect(() => { // after new page added
94+
scrollToTarget(`pageActions-id-${selectedPageIndex}`, 0, {});
95+
resetSelectedPageIndex();
96+
}, [pageCount]);
97+
8598
return (
8699
<>
87100
<ResponsiveContainer>
88101
<ResponsiveContent>
89102
{(containerWidth, containerHeight) => (
90103
<Component
91-
ref={outerRef}
104+
ref={refSetter}
92105
distance={50}
93106
height={containerHeight}
94107
helperClass="pageThumbnailHelper"
@@ -98,7 +111,6 @@ const ListWrapper = ({
98111
onSortEnd={_onSortEnd}
99112
pageContainerStyle={pageContainerStyles}
100113
pageCount={pageCount}
101-
selectedPageIndex={selectedPageIndex}
102114
width={containerWidth}
103115
{...otherProps}
104116
/>

src/components/Panels/SlidesPanel/SlidesPanel.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,7 @@ const SlidesPanel = ({
4242
return pages[index];
4343
}, [pages]);
4444

45-
const onPageSort = useCallback(({ newIndex, oldIndex }, nativeEvent, ref) => {
46-
const instance = ref.getWrappedInstance();
47-
const list = instance.sortablePageListRef.current;
48-
45+
const onPageSort = useCallback(({ newIndex, oldIndex }, nativeEvent, list) => {
4946
const newPageOrders = arrayMove(pages, oldIndex, newIndex).reduce((acc, page, index) => {
5047
acc[page.id] = { order: index + 1 };
5148
return acc;

src/components/Panels/SlidesPanel/SortablePageItem.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { memo } from 'react';
22
import { SortableElement } from 'react-sortable-hoc';
3-
import classNames from 'classnames';
43
import StaticPage from '../../Preview/StaticPage';
54
import PageThumbnailActions from './PageThumbnailActions';
65

@@ -9,7 +8,6 @@ const SortablePageItem = SortableElement(({
98
additionalPageItems,
109
disableInteraction,
1110
hashCode,
12-
isSelected,
1311
itemAccessor,
1412
onAnEventTrigger,
1513
onPageAdd,
@@ -24,7 +22,7 @@ const SortablePageItem = SortableElement(({
2422
const onKeyDown = f => f;
2523
return (
2624
<div
27-
className={classNames('thumbnailWrapper d-flex a-center j-between', { isSelected })}
25+
className="thumbnailWrapper d-flex a-center j-between"
2826
data-id={page.id}
2927
data-order={order}
3028
onClick={onPageClick}

src/components/Panels/SlidesPanel/SortablePageItemRenderer.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import SortablePageItem from './SortablePageItem';
55

66
const SortablePageItemRenderer = ({ data, index, style }) => {
77
const {
8-
pageContainerStyle, pageGetter, selectedPageIndex, ...otherData
8+
pageContainerStyle, pageGetter, ...otherData
99
} = data;
1010
const page = pageGetter(index);
1111
const pageContainerLastStyle = {
@@ -16,7 +16,6 @@ const SortablePageItemRenderer = ({ data, index, style }) => {
1616
<SortablePageItem
1717
key={`page-${index}-${page.id}`}
1818
index={index}
19-
isSelected={selectedPageIndex === page.order}
2019
order={page.order}
2120
page={page}
2221
pageContainerStyle={pageContainerLastStyle}

src/components/Panels/SlidesPanel/SortablePageList.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ const createItemData = memoize((
1717
onPageRemove,
1818
pageContainerStyle,
1919
pageGetter,
20-
selectedPageIndex,
2120
) => ({
2221
acceptedItems,
2322
additionalPageItems,
@@ -31,7 +30,6 @@ const createItemData = memoize((
3130
onPageRemove,
3231
pageContainerStyle,
3332
pageGetter,
34-
selectedPageIndex,
3533
}));
3634

3735
const SortablePageList = Component => {
@@ -56,7 +54,6 @@ const SortablePageList = Component => {
5654
onPageRemove,
5755
pageContainerStyle,
5856
pageGetter,
59-
selectedPageIndex,
6057
} = this.props;
6158
return createItemData(
6259
acceptedItems,
@@ -71,7 +68,6 @@ const SortablePageList = Component => {
7168
onPageRemove,
7269
pageContainerStyle,
7370
pageGetter,
74-
selectedPageIndex,
7571
);
7672
}
7773

@@ -108,7 +104,6 @@ const SortablePageList = Component => {
108104
pageContainerStyle: PropTypes.shape({}),
109105
pageCount: PropTypes.number,
110106
pageGetter: PropTypes.func,
111-
selectedPageIndex: PropTypes.number,
112107
width: PropTypes.number,
113108
};
114109

@@ -127,7 +122,6 @@ const SortablePageList = Component => {
127122
pageContainerStyle: {},
128123
pageCount: 0,
129124
pageGetter: () => {},
130-
selectedPageIndex: 1,
131125
width: 0,
132126
};
133127

src/utils/hooks.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export const useFitZoom = ({
7878
}, [settings.reportLayout]);
7979
};
8080

81-
export const usePageVisibility = (callback, scrollTracking, pageCount, selectedPageIndex) => {
81+
export const usePageVisibility = (callback, pageCount, selectedPageIndex) => {
8282
const ratio = useRef({});
8383
const pageRefs = useRef([]);
8484
const observer = new window.IntersectionObserver(entries => {
@@ -108,16 +108,18 @@ export const usePageVisibility = (callback, scrollTracking, pageCount, selectedP
108108
}, [pageCount]);
109109

110110
useEffect(() => {
111-
pageRefs.current.forEach(page => {
112-
observer.observe(page);
113-
});
111+
if (selectedPageIndex === -1) {
112+
pageRefs.current.forEach(page => {
113+
observer.observe(page);
114+
});
115+
}
114116

115117
return () => {
116118
pageRefs.current.forEach(page => {
117119
observer.unobserve(page);
118120
});
119121
};
120-
}, [pageRefs.current, scrollTracking, selectedPageIndex]);
122+
}, [selectedPageIndex]);
121123
};
122124

123125
export const useFullscreenChange = (isFullscreen, setIsFullscreen, fitToScreen) => {

0 commit comments

Comments
 (0)