Selaa lähdekoodia

jump scroll to item

yohei0125 4 vuotta sitten
vanhempi
sitoutus
18d1a9aeac

+ 5 - 2
packages/app/src/client/util/smooth-scroll.ts

@@ -1,13 +1,16 @@
 const WIKI_HEADER_LINK = 120;
 
-export const smoothScrollIntoView = (element: HTMLElement, offsetTop = 0, scrollElement: HTMLElement | Window = window): void => {
+export const smoothScrollIntoView = (element: HTMLElement, offsetTop = 0, scrollElement: HTMLElement | Window = window, useSlimScroll = false): void => {
   const targetElement = element || window.document.body;
 
   // get the distance to the target element top
   const rectTop = targetElement.getBoundingClientRect().top;
 
   const top = window.pageYOffset + rectTop - offsetTop;
-
+  if (useSlimScroll) {
+    (<any>$(scrollElement)).slimScroll({ scrollTo: rectTop });
+    return;
+  }
   scrollElement.scrollTo({
     top,
     behavior: 'smooth',

+ 0 - 8
packages/app/src/components/Sidebar/PageTree/Item.tsx

@@ -34,7 +34,6 @@ interface ItemProps {
   isEnableActions: boolean
   itemNode: ItemNode
   targetPathOrId?: string
-  isScrolled: boolean,
   isOpen?: boolean
   isEnabledAttachTitleHeader?: boolean
   onRenamed?(): void
@@ -360,12 +359,6 @@ const Item: FC<ItemProps> = (props: ItemProps) => {
   };
 
 
-  useEffect(() => {
-    if (!props.isScrolled && page.isTarget) {
-      document.dispatchEvent(new CustomEvent('targetItemRendered'));
-    }
-  }, [props.isScrolled, page.isTarget]);
-
   // didMount
   useEffect(() => {
     if (hasChildren()) setIsOpen(true);
@@ -476,7 +469,6 @@ const Item: FC<ItemProps> = (props: ItemProps) => {
               isEnableActions={isEnableActions}
               itemNode={node}
               isOpen={false}
-              isScrolled={props.isScrolled}
               targetPathOrId={targetPathOrId}
               isEnabledAttachTitleHeader={isEnabledAttachTitleHeader}
               onRenamed={onRenamed}

+ 21 - 12
packages/app/src/components/Sidebar/PageTree/ItemsTree.tsx

@@ -71,7 +71,6 @@ type ItemsTreeProps = {
 const renderByInitialNode = (
     initialNode: ItemNode,
     isEnableActions: boolean,
-    isScrolled: boolean,
     targetPathOrId?: string,
     isEnabledAttachTitleHeader?: boolean,
     onRenamed?: () => void,
@@ -91,7 +90,6 @@ const renderByInitialNode = (
         onRenamed={onRenamed}
         onClickDuplicateMenuItem={onClickDuplicateMenuItem}
         onClickDeleteMenuItem={onClickDeleteMenuItem}
-        isScrolled={isScrolled}
       />
     </ul>
   );
@@ -105,7 +103,8 @@ const scrollTargetItem = () => {
   const scrollElement = document.getElementById('grw-sidebar-contents-scroll-target');
   const target = document.getElementById('grw-pagetree-is-target');
   if (scrollElement != null && target != null) {
-    smoothScrollIntoView(target, SCROLL_OFFSET_TOP, scrollElement);
+    const useSlimScroll = true;
+    smoothScrollIntoView(target, SCROLL_OFFSET_TOP, scrollElement, useSlimScroll);
   }
 };
 // --- end ---
@@ -126,7 +125,6 @@ const ItemsTree: FC<ItemsTreeProps> = (props: ItemsTreeProps) => {
   const { data: isEnabledAttachTitleHeader } = useIsEnabledAttachTitleHeader();
   const { open: openDuplicateModal } = usePageDuplicateModal();
   const { open: openDeleteModal } = usePageDeleteModal();
-  const [isScrolled, setIsScrolled] = useState(false);
 
   const { data: socket } = useGlobalSocket();
   const { data: ptDescCountMap, update: updatePtDescCountMap } = usePageTreeDescCountMap();
@@ -137,17 +135,22 @@ const ItemsTree: FC<ItemsTreeProps> = (props: ItemsTreeProps) => {
   const { advance: advanceFts } = useFullTextSearchTermManager();
   const { advance: advanceDpl } = useDescendantsPageListForCurrentPathTermManager();
 
+  const [isScrolled, setIsScrolled] = useState(false);
+  const [isRenderedCompletely, setIsRenderedCompletely] = useState(false);
+
   const scrollItem = () => {
-    scrollTargetItem();
-    setIsScrolled(true);
+    if (!isScrolled) {
+      scrollTargetItem();
+      setIsScrolled(true);
+    }
   };
 
   useEffect(() => {
-    document.addEventListener('targetItemRendered', scrollItem);
+    document.addEventListener('scrollPageTree', scrollItem);
     return () => {
-      document.removeEventListener('targetItemRendered', scrollItem);
+      document.removeEventListener('scrollPageTree', scrollItem);
     };
-  }, []);
+  });
 
   useEffect(() => {
     if (socket == null) {
@@ -171,6 +174,11 @@ const ItemsTree: FC<ItemsTreeProps> = (props: ItemsTreeProps) => {
     advanceDpl();
   };
 
+  useEffect(() => {
+    if (!isRenderedCompletely) return;
+    document.dispatchEvent(new CustomEvent('resetScroller'));
+  }, [isRenderedCompletely]);
+
   const onClickDuplicateMenuItem = (pageToDuplicate: IPageForPageDuplicateModal) => {
     // eslint-disable-next-line @typescript-eslint/no-unused-vars
     const duplicatedHandler: OnDuplicatedFunction = (fromPath, toPath) => {
@@ -216,11 +224,12 @@ const ItemsTree: FC<ItemsTreeProps> = (props: ItemsTreeProps) => {
   /*
    * Render completely
    */
-  if (ancestorsChildrenData != null && rootPageData != null) {
+  if (ancestorsChildrenData != null && rootPageData != null && !isRenderedCompletely) {
     const initialNode = generateInitialNodeAfterResponse(ancestorsChildrenData.ancestorsChildren, new ItemNode(rootPageData.rootPage));
+    setIsRenderedCompletely(true);
     return renderByInitialNode(
       // eslint-disable-next-line max-len
-      initialNode, isEnableActions, isScrolled, targetPathOrId, isEnabledAttachTitleHeader, onRenamed, onClickDuplicateMenuItem, onClickDeleteMenuItem,
+      initialNode, isEnableActions, targetPathOrId, isEnabledAttachTitleHeader, onRenamed, onClickDuplicateMenuItem, onClickDeleteMenuItem,
     );
   }
 
@@ -231,7 +240,7 @@ const ItemsTree: FC<ItemsTreeProps> = (props: ItemsTreeProps) => {
     const initialNode = generateInitialNodeBeforeResponse(targetAndAncestorsData.targetAndAncestors);
     return renderByInitialNode(
       // eslint-disable-next-line max-len
-      initialNode, isEnableActions, isScrolled, targetPathOrId, isEnabledAttachTitleHeader, onRenamed, onClickDuplicateMenuItem, onClickDeleteMenuItem,
+      initialNode, isEnableActions, targetPathOrId, isEnabledAttachTitleHeader, onRenamed, onClickDuplicateMenuItem, onClickDeleteMenuItem,
     );
   }
 

+ 11 - 6
packages/app/src/components/StickyStretchableScroller.jsx

@@ -63,13 +63,10 @@ const StickyStretchableScroller = (props) => {
    * Reset scrollbar
    */
   const resetScrollbar = useCallback(() => {
-    console.log('------');
     const contentsElem = document.querySelector(contentsElemSelector);
-    console.log('contentsElem', contentsElem);
     if (contentsElem == null) {
       return;
     }
-    console.log('scrollTargetSelector', scrollTargetSelector);
     const viewHeight = calcViewHeightFunc != null
       ? calcViewHeightFunc()
       : 'auto';
@@ -81,9 +78,7 @@ const StickyStretchableScroller = (props) => {
     logger.debug(`[${scrollTargetSelector}] contentsHeight`, contentsHeight);
 
     const isScrollEnabled = viewHeight === 'auto' || (viewHeight < contentsHeight);
-    console.log('viewHeight', viewHeight);
-    console.log('contentsHeight', contentsHeight);
-    console.log('viewHeight < contentsHeight', viewHeight < contentsHeight);
+
     $(scrollTargetSelector).slimScroll({
       color: '#666',
       railColor: '#999',
@@ -94,6 +89,9 @@ const StickyStretchableScroller = (props) => {
       allowPageScroll: true,
     });
 
+    if (isScrollEnabled && scrollTargetSelector === '#grw-sidebar-contents-scroll-target') {
+      document.dispatchEvent(new CustomEvent('scrollPageTree'));
+    }
     // destroy
     if (!isScrollEnabled) {
       $(scrollTargetSelector).slimScroll({ destroy: true });
@@ -104,6 +102,13 @@ const StickyStretchableScroller = (props) => {
   const resetScrollbarDebounced = debounce(100, resetScrollbar);
 
 
+  useEffect(() => {
+    document.addEventListener('resetScroller', resetScrollbarDebounced);
+    return () => {
+      document.removeEventListener('resetScroller', resetScrollbarDebounced);
+    };
+  }, []);
+
   const stickyChangeHandler = useCallback((event) => {
     logger.debug('StickyEvents.CHANGE detected');
     setTimeout(resetScrollbar, 100);