Browse Source

chore: save offset top of nav items

ascarbek 2 years ago
parent
commit
2d8182c503

+ 21 - 0
frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/FolderItem.hooks.ts

@@ -7,6 +7,8 @@ import { AppBackendService } from '../../../stores/effects/folder/app/app_bd_svc
 import { WorkspaceBackendService } from '../../../stores/effects/folder/workspace/workspace_bd_svc';
 import { useError } from '../../error/Error.hooks';
 import { AppObserver } from '../../../stores/effects/folder/app/app_observer';
+import { activePageIdActions } from '../../../stores/reducers/activePageId/slice';
+import { useNavigate } from 'react-router-dom';
 
 const initialFolderHeight = 40;
 const initialPageHeight = 40;
@@ -16,6 +18,8 @@ export const useFolderEvents = (folder: IFolder, pages: IPage[]) => {
   const appDispatch = useAppDispatch();
   const workspace = useAppSelector((state) => state.workspace);
 
+  const navigate = useNavigate();
+
   // Actions
   const [showPages, setShowPages] = useState(false);
   const [showFolderOptions, setShowFolderOptions] = useState(false);
@@ -140,6 +144,10 @@ export const useFolderEvents = (folder: IFolder, pages: IPage[]) => {
           id: newView.id,
         })
       );
+
+      appDispatch(activePageIdActions.setActivePageId(newView.id));
+
+      navigate(`/page/document/${newView.id}`);
     } catch (e: any) {
       error.showError(e?.message);
     }
@@ -161,6 +169,10 @@ export const useFolderEvents = (folder: IFolder, pages: IPage[]) => {
           id: newView.id,
         })
       );
+
+      appDispatch(activePageIdActions.setActivePageId(newView.id));
+
+      navigate(`/page/board/${newView.id}`);
     } catch (e: any) {
       error.showError(e?.message);
     }
@@ -182,11 +194,19 @@ export const useFolderEvents = (folder: IFolder, pages: IPage[]) => {
           id: newView.id,
         })
       );
+
+      appDispatch(activePageIdActions.setActivePageId(newView.id));
+
+      navigate(`/page/grid/${newView.id}`);
     } catch (e: any) {
       error.showError(e?.message);
     }
   };
 
+  const setOffsetTop = (v: number) => {
+    foldersActions.setOffsetTop({ id: folder.id, offset: v });
+  };
+
   return {
     showPages,
     onFolderNameClick,
@@ -209,5 +229,6 @@ export const useFolderEvents = (folder: IFolder, pages: IPage[]) => {
     closePopup,
     folderHeight,
     animationDuration,
+    setOffsetTop,
   };
 };

+ 9 - 3
frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/FolderItem.tsx

@@ -8,7 +8,7 @@ import { IPage } from '../../../stores/reducers/pages/slice';
 import { PageItem } from './PageItem';
 import { Button } from '../../_shared/Button';
 import { RenamePopup } from './RenamePopup';
-import { useEffect, useState } from 'react';
+import { useEffect, useRef, useState } from 'react';
 import { DropDownShowSvg } from '../../_shared/svg/DropDownShowSvg';
 
 let timeoutHandle: any;
@@ -44,6 +44,7 @@ export const FolderItem = ({
     closePopup,
     folderHeight,
     animationDuration,
+    setOffsetTop,
   } = useFolderEvents(folder, pages);
 
   const [hideOverflow, setHideOverflow] = useState(!showPages);
@@ -59,9 +60,14 @@ export const FolderItem = ({
     }
   }, [showPages]);
 
+  const el = useRef<HTMLDivElement>(null);
+
+  useEffect(() => {
+    setOffsetTop(el.current?.offsetTop || 0);
+  }, [el, showPages]);
+
   return (
-    /*transitionTimingFunction:'cubic-bezier(.36,1.55,.65,1.1)'*/
-    <div className={'relative'}>
+    <div className={'relative'} ref={el}>
       <div
         className={`relative my-2 ${hideOverflow ? 'overflow-hidden' : ''} transition-all `}
         style={{ height: folderHeight, transitionDuration: `${animationDuration}ms` }}

+ 5 - 0
frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/PageItem.hooks.ts

@@ -60,6 +60,10 @@ export const usePageEvents = (page: IPage) => {
     setShowRenamePopup(false);
   };
 
+  const setOffsetTop = (v: number) => {
+    pagesActions.setOffsetTop({ id: page.id, offset: v });
+  };
+
   return {
     showPageOptions,
     onPageOptionsClick,
@@ -71,5 +75,6 @@ export const usePageEvents = (page: IPage) => {
     closePopup,
     closeRenamePopup,
     activePageId,
+    setOffsetTop,
   };
 };

+ 9 - 1
frontend/appflowy_tauri/src/appflowy_app/components/layout/NavigationPanel/PageItem.tsx

@@ -8,6 +8,7 @@ import { Button } from '../../_shared/Button';
 import { usePageEvents } from './PageItem.hooks';
 import { RenamePopup } from './RenamePopup';
 import { ViewLayoutTypePB } from '../../../../services/backend';
+import { useEffect, useRef } from 'react';
 
 export const PageItem = ({ page, onPageClick }: { page: IPage; onPageClick: () => void }) => {
   const {
@@ -21,10 +22,17 @@ export const PageItem = ({ page, onPageClick }: { page: IPage; onPageClick: () =
     closePopup,
     closeRenamePopup,
     activePageId,
+    setOffsetTop,
   } = usePageEvents(page);
 
+  const el = useRef<HTMLDivElement>(null);
+
+  useEffect(() => {
+    setOffsetTop(el.current?.offsetTop || 0);
+  }, [el]);
+
   return (
-    <div className={'relative'}>
+    <div className={'relative'} ref={el}>
       <div
         onClick={() => onPageClick()}
         className={`flex cursor-pointer items-center justify-between rounded-lg py-2 pl-8 pr-4 hover:bg-surface-2 ${

+ 5 - 1
frontend/appflowy_tauri/src/appflowy_app/stores/reducers/folders/slice.ts

@@ -3,6 +3,7 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit';
 export interface IFolder {
   id: string;
   title: string;
+  offsetTop?: number;
 }
 
 const initialState: IFolder[] = [];
@@ -15,7 +16,7 @@ export const foldersSlice = createSlice({
       state.push(action.payload);
     },
     renameFolder(state, action: PayloadAction<{ id: string; newTitle: string }>) {
-      return state.map((f) => (f.id === action.payload.id ? { id: f.id, title: action.payload.newTitle } : f));
+      return state.map((f) => (f.id === action.payload.id ? { ...f, title: action.payload.newTitle } : f));
     },
     deleteFolder(state, action: PayloadAction<{ id: string }>) {
       return state.filter((f) => f.id !== action.payload.id);
@@ -23,6 +24,9 @@ export const foldersSlice = createSlice({
     clearFolders() {
       return [];
     },
+    setOffsetTop(state, action: PayloadAction<{ id: string; offset: number }>) {
+      return state.map((f) => (f.id === action.payload.id ? { ...f, offsetTop: action.payload.offset } : f));
+    },
   },
 });
 

+ 5 - 6
frontend/appflowy_tauri/src/appflowy_app/stores/reducers/pages/slice.ts

@@ -6,6 +6,7 @@ export interface IPage {
   title: string;
   pageType: ViewLayoutTypePB;
   folderId: string;
+  offsetTop?: number;
 }
 
 const initialState: IPage[] = [];
@@ -15,12 +16,7 @@ export const pagesSlice = createSlice({
   initialState: initialState,
   reducers: {
     didReceivePages(state, action: PayloadAction<IPage[]>) {
-      action.payload.forEach((updatedPage) => {
-        const index = state.findIndex((page) => page.id === updatedPage.id);
-        if (index !== -1) {
-          state.splice(index, 1, updatedPage);
-        }
-      });
+      return action.payload;
     },
     addPage(state, action: PayloadAction<IPage>) {
       state.push(action.payload);
@@ -36,6 +32,9 @@ export const pagesSlice = createSlice({
     clearPages() {
       return [];
     },
+    setOffsetTop(state, action: PayloadAction<{ id: string; offset: number }>) {
+      return state.map((page) => (page.id === action.payload.id ? { ...page, offsetTop: action.payload.offset } : page));
+    },
   },
 });