diff --git a/src/shared/ui-kit/box/Virtual/hooks/useVirtualActions.ts b/src/shared/ui-kit/box/Virtual/hooks/useVirtualActions.ts index 3da4b9d0..29002ecc 100644 --- a/src/shared/ui-kit/box/Virtual/hooks/useVirtualActions.ts +++ b/src/shared/ui-kit/box/Virtual/hooks/useVirtualActions.ts @@ -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; } @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, diff --git a/src/shared/ui-kit/box/Virtual/hooks/useVirtualItems.ts b/src/shared/ui-kit/box/Virtual/hooks/useVirtualItems.ts index 0ca186a9..da1ab80c 100644 --- a/src/shared/ui-kit/box/Virtual/hooks/useVirtualItems.ts +++ b/src/shared/ui-kit/box/Virtual/hooks/useVirtualItems.ts @@ -35,7 +35,10 @@ export const useVirtualItems = function (props: UseVirtualItemsProps): UseVirtua const previousLength = useRef(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, diff --git a/src/shared/ui-kit/box/Virtual/hooks/useVirtualScroll.ts b/src/shared/ui-kit/box/Virtual/hooks/useVirtualScroll.ts index b40ac20e..ff4981b8 100644 --- a/src/shared/ui-kit/box/Virtual/hooks/useVirtualScroll.ts +++ b/src/shared/ui-kit/box/Virtual/hooks/useVirtualScroll.ts @@ -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'; @@ -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', @@ -84,12 +86,14 @@ 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), }); @@ -97,12 +101,14 @@ export const useVirtualScroll = function (props: UseVirtualScrollProps): UseVirt 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, @@ -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, @@ -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({ @@ -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(); } diff --git a/src/shared/ui-kit/box/Virtual/lib/getPreviousIndex/getPreviousIndex.ts b/src/shared/ui-kit/box/Virtual/lib/getPreviousIndex/getPreviousIndex.ts index f49ece3b..a220a511 100644 --- a/src/shared/ui-kit/box/Virtual/lib/getPreviousIndex/getPreviousIndex.ts +++ b/src/shared/ui-kit/box/Virtual/lib/getPreviousIndex/getPreviousIndex.ts @@ -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); } diff --git a/src/shared/ui-kit/box/Virtual/lib/getScrollDirection/getScrollDirection.ts b/src/shared/ui-kit/box/Virtual/lib/getScrollDirection/getScrollDirection.ts index 59550c6e..08f71264 100644 --- a/src/shared/ui-kit/box/Virtual/lib/getScrollDirection/getScrollDirection.ts +++ b/src/shared/ui-kit/box/Virtual/lib/getScrollDirection/getScrollDirection.ts @@ -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; }; \ No newline at end of file diff --git a/src/shared/ui-kit/box/Virtual/lib/isEndOfScroll/isEndOfScroll.ts b/src/shared/ui-kit/box/Virtual/lib/isEndOfScroll/isEndOfScroll.ts index 607fa31f..32f0f7b8 100644 --- a/src/shared/ui-kit/box/Virtual/lib/isEndOfScroll/isEndOfScroll.ts +++ b/src/shared/ui-kit/box/Virtual/lib/isEndOfScroll/isEndOfScroll.ts @@ -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; }; \ No newline at end of file diff --git a/src/shared/ui-kit/box/Virtual/lib/isStartOfScroll/isStartOfScroll.ts b/src/shared/ui-kit/box/Virtual/lib/isStartOfScroll/isStartOfScroll.ts index 20c83410..8cf1a11d 100644 --- a/src/shared/ui-kit/box/Virtual/lib/isStartOfScroll/isStartOfScroll.ts +++ b/src/shared/ui-kit/box/Virtual/lib/isStartOfScroll/isStartOfScroll.ts @@ -1,3 +1,3 @@ export const isStartOfScroll = function (scrollTop: number): boolean { - return scrollTop === 0; + return Math.abs(scrollTop) <= 1; }; \ No newline at end of file diff --git a/src/shared/ui-kit/box/Virtual/readme.md b/src/shared/ui-kit/box/Virtual/readme.md index 3c9ed948..7898837b 100644 --- a/src/shared/ui-kit/box/Virtual/readme.md +++ b/src/shared/ui-kit/box/Virtual/readme.md @@ -1,5 +1,8 @@ # Virtual scroll +--- +Не работает нормально в chrome (и всех производных). ГГ ВП. + ### TODO: - Добавить loader @@ -13,5 +16,4 @@ ### Buglog - Проблемы с автосроллом -- Если сделать reverse, то надо так же реверсить и first/last - Странное поведение при маленьком количестве элементов и скролле к next \ No newline at end of file diff --git a/src/shared/ui-kit/box/Virtual/ui/Virtual.tsx b/src/shared/ui-kit/box/Virtual/ui/Virtual.tsx index aa12cdbe..9e5ae6ee 100644 --- a/src/shared/ui-kit/box/Virtual/ui/Virtual.tsx +++ b/src/shared/ui-kit/box/Virtual/ui/Virtual.tsx @@ -30,7 +30,6 @@ export type VirtualProps = showAmount?: number; distanceToTrigger?: number; type?: VirtualType; - reverseItems?: boolean; uploadNext?: VirtualUploadMethod; uploadPrevious?: VirtualUploadMethod; hasMoreNext?: boolean; @@ -48,7 +47,6 @@ export const Virtual: FC = memo(function Virtual (props) { showAmount = 40, distanceToTrigger = 200, type = VirtualType.TOP, - reverseItems = false, uploadNext, uploadPrevious, hasMoreNext = true, @@ -93,6 +91,11 @@ export const Virtual: FC = memo(function Virtual (props) { prevHandler : onPrev, }); + console.log('****** VIRTUAL RERENDER ******'); + console.log('Index: ', currentIndex); + console.log('Virtual action: ', actionType.current); + console.log('******************************'); + return (
= memo(function Virtual (props) { ref={ ref } >
{ virtualItems.map(render) }