Skip to content

Commit

Permalink
gg wp virtual
Browse files Browse the repository at this point in the history
  • Loading branch information
VanyaMate committed Aug 2, 2024
1 parent d1c1bce commit 36e3e74
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 26 deletions.
13 changes: 11 additions & 2 deletions src/shared/ui-kit/box/Virtual/hooks/useVirtualActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,13 @@ export const useVirtualActions = function (props: UseVirtualActionsProps): UseVi

// Change index
useLayoutEffect(() => {
const itemsLengthChanged: boolean = previous.length.current !== props.items.length;
const itemsLengthNotChanged: boolean = previous.length.current === props.items.length;
if (itemsLengthNotChanged) {
return;
}

if (!itemsLengthChanged) {
const itemsLengthDecreased: boolean = previous.length.current > props.items.length;
if (itemsLengthDecreased) {
return;
}

Expand All @@ -86,6 +90,7 @@ export const useVirtualActions = function (props: UseVirtualActionsProps): UseVi
previousLast : previous.last.current,
items : props.items,
})) {
console.log('Autoscroll', dynamicActionType.current);
props.setIndex(getLastIndex({
type : props.type,
itemsLength: props.items.length,
Expand All @@ -101,6 +106,7 @@ export const useVirtualActions = function (props: UseVirtualActionsProps): UseVi
previousLast : previous.last.current,
items : props.items,
})) {
console.log('Toggle NEXT, Loading NEXT', dynamicActionType.current);
props.setIndex(getNextIndex({
type : props.type,
itemsLength : props.items.length,
Expand All @@ -111,6 +117,7 @@ export const useVirtualActions = function (props: UseVirtualActionsProps): UseVi
break;
case VirtualAction.TOGGLE_PREVIOUS:
case VirtualAction.LOADING_PREVIOUS:
console.log('Toggle PREVIOUS, Loading PREVIOUS', dynamicActionType.current);
if (isPreviousChanges({
type : props.type,
previousFirst: previous.first.current,
Expand Down Expand Up @@ -160,6 +167,7 @@ export const useVirtualActions = function (props: UseVirtualActionsProps): UseVi
processActionType.current = VirtualAction.NONE;
}
} else {
dynamicActionType.current = VirtualAction.NONE;
props.setIndex(
getNextIndex({
type : props.type,
Expand Down Expand Up @@ -200,6 +208,7 @@ export const useVirtualActions = function (props: UseVirtualActionsProps): UseVi
processActionType.current = VirtualAction.NONE;
}
} else {
dynamicActionType.current = VirtualAction.NONE;
props.setIndex(
getPreviousIndex({
type : props.type,
Expand Down
5 changes: 4 additions & 1 deletion src/shared/ui-kit/box/Virtual/hooks/useVirtualItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ export const useVirtualItems = function (props: UseVirtualItemsProps): UseVirtua
const previousLength = useRef<number>(props.items.length);

useLayoutEffect(() => {
if (previousLength.current === props.items.length) {
const itemsLengthNotChanged: boolean = previousLength.current === props.items.length;
const itemsLengthDecreased: boolean = previousLength.current > props.items.length;

if (itemsLengthNotChanged || itemsLengthDecreased) {
const virtualItems = getVirtualItems({
index : refIndex.current,
items : props.items,
Expand Down
53 changes: 39 additions & 14 deletions src/shared/ui-kit/box/Virtual/hooks/useVirtualScroll.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { MutableRefObject, useLayoutEffect, useRef } from 'react';
import {
VirtualType,
} from '@/shared/ui-kit/box/Virtual/ui/Virtual.tsx';
import { VirtualType } from '@/shared/ui-kit/box/Virtual/ui/Virtual.tsx';
import {
getScrollDirection,
} from '@/shared/ui-kit/box/Virtual/lib/getScrollDirection/getScrollDirection.ts';
Expand Down Expand Up @@ -68,14 +66,18 @@ export const useVirtualScroll = function (props: UseVirtualScrollProps): UseVirt

// Update scroll when virtualItems is changed
useLayoutEffect(() => {
console.log('---- Use Scroll', props.virtualAction.current);

switch (props.virtualAction.current) {
case VirtualAction.AUTOSCROLL:
console.log('Autoscroll');
if (isNextChanges({
type : props.type,
previousLast : previous.last.current,
previousFirst: previous.first.current,
items : props.virtualItems,
})) {
console.log('Scrolling...');
containerRef.current.scrollTo({
top : getMaxNextScrollPosition(props.type),
behavior: props.smoothScroll ? 'smooth' : 'instant',
Expand All @@ -84,25 +86,29 @@ export const useVirtualScroll = function (props: UseVirtualScrollProps): UseVirt
break;
case VirtualAction.TOGGLE_NEXT:
case VirtualAction.LOADING_NEXT:
console.log('Next');
if (isNextChanges({
type : props.type,
previousLast : previous.last.current,
previousFirst: previous.first.current,
items : props.virtualItems,
})) {
console.log('Scroll..');
containerRef.current.scrollTo({
top: getMaxNextScrollPosition(props.type),
});
}
break;
case VirtualAction.TOGGLE_PREVIOUS:
case VirtualAction.LOADING_PREVIOUS:
console.log('Previous');
if (isPreviousChanges({
type : props.type,
previousLast : previous.last.current,
previousFirst: previous.first.current,
items : props.virtualItems,
})) {
console.log('Scroll..');
containerRef.current.scrollTo({
top: getMaxPrevScrollPosition({
type : props.type,
Expand All @@ -128,6 +134,11 @@ export const useVirtualScroll = function (props: UseVirtualScrollProps): UseVirt
previousOffsetWidth.current = ref.offsetWidth;

const onScrollHandler = function () {
console.log('On scroll handler with:');
console.log('ScrollDirection:', scrollDirection.current);
console.log('LastHandler:', lastHandler.current);
console.log('ActionType:', props.virtualAction.current);

const {
scrollTop,
scrollHeight,
Expand All @@ -136,45 +147,55 @@ export const useVirtualScroll = function (props: UseVirtualScrollProps): UseVirt
} = ref;

if (previousOffsetWidth.current !== offsetWidth) {
console.log('Offset change', previousOffsetWidth.current, offsetWidth);
previousOffsetWidth.current = offsetWidth;

if (props.virtualAction.current === VirtualAction.AUTOSCROLL) {
ref.scrollTo({
top: getMaxNextScrollPosition(props.type),
});
console.log('Autoscroll, scrolling...');
const scrollPosition: number = getMaxNextScrollPosition(props.type);
previousScrollTop.current = scrollPosition;
ref.scrollTo({ top: scrollPosition });
}
return;
}

if (isStartOfScroll(scrollTop)) {
ref.scrollTo({
top: getMaxNextScrollPosition(props.type),
});
console.log('IsStartOfScroll');
const scrollPosition: number = getMaxNextScrollPosition(props.type);
previousScrollTop.current = scrollPosition;
ref.scrollTo({ top: scrollPosition });
return;
}

if (isEndOfScroll({ scrollHeight, offsetHeight, scrollTop })) {
ref.scrollTo({
top: getMaxPrevScrollPosition({
type: props.type,
scrollTop,
}),
console.log('IsEndOfScroll');
const scrollPosition: number = getMaxPrevScrollPosition({
type: props.type,
scrollTop,
});
previousScrollTop.current = scrollPosition;
ref.scrollTo({ top: scrollPosition });
return;
}

console.log('Previous scroll direction:', scrollDirection.current);

scrollDirection.current = getScrollDirection({
previous: previousScrollTop.current,
current : scrollTop,
});

console.log('Current scroll direction:', scrollDirection.current);

if (isNextScrollTrigger({
scrollDirection : scrollDirection.current,
scrollTop,
distanceToTrigger: props.distanceToTrigger,
})) {
console.log('IsNextScrollTrigger', lastHandler.current);
if (lastHandler.current !== VirtualScrollDirection.NEXT) {
lastHandler.current = VirtualScrollDirection.NEXT;
console.log('!!!!! Execute nextHandler');
props.nextHandler();
}
} else if (isPreviousScrollTrigger({
Expand All @@ -184,12 +205,16 @@ export const useVirtualScroll = function (props: UseVirtualScrollProps): UseVirt
offsetHeight,
scrollHeight,
})) {
console.log('IsPreviousScrollTrigger', lastHandler.current);
if (lastHandler.current !== VirtualScrollDirection.PREVIOUS) {
lastHandler.current = VirtualScrollDirection.PREVIOUS;
console.log('!!!!! Execute prevHandler');
props.prevHandler();
}
} else if (previousScrollTop.current !== Math.abs(scrollTop)) {
console.log('IsOtherTrigger');
lastHandler.current = VirtualScrollDirection.NONE;
console.log('!!!!! Execute otherHandler');
props.otherHandler();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const getPreviousIndex = function (props: GetPreviousIndexProps) {

if (isTop(props.type)) {
const maxIndex: number = props.itemsLength - props.showAmount;
return Math.min(maxIndex, props.currentIndex + offset);
return Math.max(Math.min(maxIndex, props.currentIndex + offset), 0);
} else {
return Math.max(0, props.currentIndex - offset);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,20 @@ export type GetScrollDirectionProps = {


export const getScrollDirection = function (props: GetScrollDirectionProps): VirtualScrollDirection {
return props.previous >= Math.abs(props.current)
? VirtualScrollDirection.NEXT : VirtualScrollDirection.PREVIOUS;
const previous: number = Math.abs(props.previous);
const current: number = Math.abs(props.current);

if (Math.abs(previous - current) > 50) {
return VirtualScrollDirection.NONE;
}

if (previous > current) {
return VirtualScrollDirection.NEXT;
}

if (previous < current) {
return VirtualScrollDirection.PREVIOUS;
}

return VirtualScrollDirection.NONE;
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ export type IsEndOfScrollProps = {
}

export const isEndOfScroll = function (props: IsEndOfScrollProps): boolean {
return props.scrollHeight - props.offsetHeight - Math.abs(props.scrollTop) === 0;
return props.scrollHeight - props.offsetHeight - Math.abs(props.scrollTop) <= 1;
};
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export const isStartOfScroll = function (scrollTop: number): boolean {
return scrollTop === 0;
return Math.abs(scrollTop) <= 1;
};
4 changes: 3 additions & 1 deletion src/shared/ui-kit/box/Virtual/readme.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Virtual scroll

---
Не работает нормально в chrome (и всех производных). ГГ ВП.

### TODO:

- Добавить loader
Expand All @@ -13,5 +16,4 @@
### Buglog

- Проблемы с автосроллом
- Если сделать reverse, то надо так же реверсить и first/last
- Странное поведение при маленьком количестве элементов и скролле к next
9 changes: 6 additions & 3 deletions src/shared/ui-kit/box/Virtual/ui/Virtual.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ export type VirtualProps =
showAmount?: number;
distanceToTrigger?: number;
type?: VirtualType;
reverseItems?: boolean;
uploadNext?: VirtualUploadMethod;
uploadPrevious?: VirtualUploadMethod;
hasMoreNext?: boolean;
Expand All @@ -48,7 +47,6 @@ export const Virtual: FC<VirtualProps> = memo(function Virtual (props) {
showAmount = 40,
distanceToTrigger = 200,
type = VirtualType.TOP,
reverseItems = false,
uploadNext,
uploadPrevious,
hasMoreNext = true,
Expand Down Expand Up @@ -93,14 +91,19 @@ export const Virtual: FC<VirtualProps> = memo(function Virtual (props) {
prevHandler : onPrev,
});

console.log('****** VIRTUAL RERENDER ******');
console.log('Index: ', currentIndex);
console.log('Virtual action: ', actionType.current);
console.log('******************************');

return (
<div
{ ...other }
className={ classNames(css.container, { [css.top]: type === VirtualType.TOP }, [ className ]) }
ref={ ref }
>
<div
className={ classNames(css.content, { [css.reverse]: reverseItems }, [ contentClassName ]) }
className={ classNames(css.content, {}, [ contentClassName ]) }
>
{ virtualItems.map(render) }
</div>
Expand Down

0 comments on commit 36e3e74

Please sign in to comment.