mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-02-24 12:12:54 +01:00
web: fix list pane not expanding (#7758)
* web: fix list pane not expanding * when a nav item was clicked, list pane was removed entirely which made it difficult to re-open it, now when nav item is clicked we manually collapse, expand, or reset the list pane * open list pane if 'reveal in list' is called * open list pane if navigated to a different nav item Signed-off-by: 01zulfi <85733202+01zulfi@users.noreply.github.com> * web: clicking on nav item should not collapse list pane Signed-off-by: 01zulfi <85733202+01zulfi@users.noreply.github.com> * web: collapse hovered nav pane when notebook/tag item clicked Signed-off-by: 01zulfi <85733202+01zulfi@users.noreply.github.com> --------- Signed-off-by: 01zulfi <85733202+01zulfi@users.noreply.github.com>
This commit is contained in:
@@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { useState, Suspense, useEffect, useRef } from "react";
|
||||
import { Suspense, useEffect, useRef } from "react";
|
||||
import { Box, Flex } from "@theme-ui/components";
|
||||
import { ScopedThemeProvider } from "./components/theme-provider";
|
||||
import useMobile from "./hooks/use-mobile";
|
||||
@@ -50,6 +50,8 @@ import { STATUS_BAR_HEIGHT } from "./common/constants";
|
||||
|
||||
new WebExtensionRelay();
|
||||
|
||||
const LIST_PANE_SNAP_SIZE = 200;
|
||||
|
||||
function App() {
|
||||
const isMobile = useMobile();
|
||||
const isFocusMode = useStore((store) => store.isFocusMode);
|
||||
@@ -131,15 +133,31 @@ export default App;
|
||||
function DesktopAppContents() {
|
||||
const isFocusMode = useStore((store) => store.isFocusMode);
|
||||
const isListPaneVisible = useStore((store) => store.isListPaneVisible);
|
||||
const toggleListPane = useStore((store) => store.toggleListPane);
|
||||
const isTablet = useTablet();
|
||||
// const [isNarrow, setIsNarrow] = useState(isTablet || false);
|
||||
const navPane = useRef<SplitPaneImperativeHandle>(null);
|
||||
const listPaneSize = useRef<null | number>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (isTablet) navPane.current?.collapse(0);
|
||||
else if (navPane.current?.isCollapsed(0)) navPane.current?.expand(0);
|
||||
}, [isTablet]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isListPaneVisible) {
|
||||
navPane.current?.expand(1);
|
||||
return;
|
||||
}
|
||||
if (
|
||||
listPaneSize.current !== null &&
|
||||
listPaneSize.current < LIST_PANE_SNAP_SIZE
|
||||
) {
|
||||
toggleListPane();
|
||||
navPane.current?.reset(1);
|
||||
}
|
||||
}, [isListPaneVisible]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex
|
||||
@@ -155,6 +173,8 @@ function DesktopAppContents() {
|
||||
direction="vertical"
|
||||
onChange={(sizes) => {
|
||||
useStore.setState({ isNavPaneCollapsed: sizes[0] <= 70 });
|
||||
|
||||
listPaneSize.current = sizes[1];
|
||||
}}
|
||||
>
|
||||
{isFocusMode ? null : (
|
||||
@@ -173,12 +193,12 @@ function DesktopAppContents() {
|
||||
<NavigationMenu onExpand={() => navPane.current?.reset(0)} />
|
||||
</Pane>
|
||||
)}
|
||||
{!isFocusMode && isListPaneVisible ? (
|
||||
{!isFocusMode ? (
|
||||
<Pane
|
||||
id="list-pane"
|
||||
initialSize={380}
|
||||
style={{ flex: 1, display: "flex" }}
|
||||
snapSize={200}
|
||||
snapSize={LIST_PANE_SNAP_SIZE}
|
||||
maxSize={500}
|
||||
className="list-pane"
|
||||
>
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
useStore as useSelectionStore,
|
||||
store as selectionStore
|
||||
} from "../../stores/selection-store";
|
||||
import { useStore as useAppStore } from "../../stores/app-store";
|
||||
import GroupHeader from "../group-header";
|
||||
import {
|
||||
ListItemWrapper,
|
||||
@@ -103,6 +104,7 @@ function ListContainer(props: ListContainerProps) {
|
||||
const toggleSelection = useSelectionStore(
|
||||
(store) => store.toggleSelectionMode
|
||||
);
|
||||
const toggleListPane = useAppStore((store) => store.toggleListPane);
|
||||
|
||||
const listRef = useRef<VirtuosoHandle>(null);
|
||||
const listContainerRef = useRef(null);
|
||||
@@ -115,6 +117,7 @@ function ListContainer(props: ListContainerProps) {
|
||||
AppEventManager.subscribe(
|
||||
AppEvents.revealItemInList,
|
||||
async (id?: string) => {
|
||||
toggleListPane();
|
||||
if (!id || !listRef.current) return;
|
||||
|
||||
const ids = await items.ids();
|
||||
|
||||
@@ -197,12 +197,17 @@ function NavigationMenu({ onExpand }: { onExpand?: () => void }) {
|
||||
const isFocusMode = useAppStore((store) => store.isFocusMode);
|
||||
const [currentTab, setCurrentTab] = useState<(typeof tabs)[number]>(tabs[0]);
|
||||
const isNavPaneCollapsed = useAppStore((store) => store.isNavPaneCollapsed);
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
const isCollapsed = isNavPaneCollapsed && !expanded;
|
||||
const isCollapsedNavPaneHovered = useAppStore(
|
||||
(store) => store.isCollapsedNavPaneHovered
|
||||
);
|
||||
const setCollapsedNavPaneHovered = useAppStore(
|
||||
(store) => store.setCollapsedNavPaneHovered
|
||||
);
|
||||
const isCollapsed = isNavPaneCollapsed && !isCollapsedNavPaneHovered;
|
||||
const mouseHoverTimeout = useRef(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (isNavPaneCollapsed) setExpanded(false);
|
||||
if (isNavPaneCollapsed) setCollapsedNavPaneHovered(false);
|
||||
}, [isNavPaneCollapsed]);
|
||||
|
||||
return (
|
||||
@@ -221,7 +226,11 @@ function NavigationMenu({ onExpand }: { onExpand?: () => void }) {
|
||||
borderRight: "1px solid var(--separator)",
|
||||
pt: 1,
|
||||
transition: "width 0.1s ease-in",
|
||||
width: isNavPaneCollapsed ? (expanded ? 250 : 50) : "100%"
|
||||
width: isNavPaneCollapsed
|
||||
? isCollapsedNavPaneHovered
|
||||
? 250
|
||||
: 50
|
||||
: "100%"
|
||||
}}
|
||||
onMouseEnter={() => {
|
||||
clearTimeout(mouseHoverTimeout.current);
|
||||
@@ -231,7 +240,7 @@ function NavigationMenu({ onExpand }: { onExpand?: () => void }) {
|
||||
if (!isNavPaneCollapsed) return;
|
||||
mouseHoverTimeout.current = setTimeout(() => {
|
||||
if (!isNavPaneCollapsed) return;
|
||||
setExpanded(false);
|
||||
setCollapsedNavPaneHovered(false);
|
||||
}, 500) as unknown as number;
|
||||
}}
|
||||
>
|
||||
@@ -239,7 +248,7 @@ function NavigationMenu({ onExpand }: { onExpand?: () => void }) {
|
||||
<Button
|
||||
variant="secondary"
|
||||
sx={{ p: 1, px: "small", bg: "transparent", mx: 1 }}
|
||||
onClick={() => setExpanded(true)}
|
||||
onClick={() => setCollapsedNavPaneHovered(true)}
|
||||
>
|
||||
<HamburgerMenu size={16} color="icon" />
|
||||
</Button>
|
||||
@@ -322,7 +331,7 @@ function NavigationMenu({ onExpand }: { onExpand?: () => void }) {
|
||||
icon={tab.icon}
|
||||
selected={currentTab.id === tab.id}
|
||||
onClick={() => {
|
||||
if (isNavPaneCollapsed) setExpanded(true);
|
||||
if (isNavPaneCollapsed) setCollapsedNavPaneHovered(true);
|
||||
setCurrentTab(tab);
|
||||
}}
|
||||
/>
|
||||
@@ -381,11 +390,11 @@ function NavigationMenu({ onExpand }: { onExpand?: () => void }) {
|
||||
<Flex sx={{ flexDirection: "column", px: 1, gap: [1, 1, "small"] }}>
|
||||
<Routes
|
||||
isCollapsed={isCollapsed}
|
||||
collapse={() => isNavPaneCollapsed && setExpanded(false)}
|
||||
collapse={() => collapseNavPaneHoveredIfNavPaneCollapsed()}
|
||||
/>
|
||||
<Colors
|
||||
isCollapsed={isCollapsed}
|
||||
collapse={() => isNavPaneCollapsed && setExpanded(false)}
|
||||
collapse={() => collapseNavPaneHoveredIfNavPaneCollapsed()}
|
||||
/>
|
||||
<Box
|
||||
bg="separator"
|
||||
@@ -394,7 +403,7 @@ function NavigationMenu({ onExpand }: { onExpand?: () => void }) {
|
||||
/>
|
||||
<Shortcuts
|
||||
isCollapsed={isCollapsed}
|
||||
collapse={() => isNavPaneCollapsed && setExpanded(false)}
|
||||
collapse={() => collapseNavPaneHoveredIfNavPaneCollapsed()}
|
||||
/>
|
||||
</Flex>
|
||||
</FlexScrollContainer>
|
||||
@@ -958,6 +967,13 @@ function navigateToRoute(path: string) {
|
||||
return useSearchStore.getState().resetSearch();
|
||||
return useAppStore.getState().toggleListPane();
|
||||
}
|
||||
useAppStore.getState().toggleListPane();
|
||||
navigate(path);
|
||||
return true;
|
||||
}
|
||||
|
||||
export function collapseNavPaneHoveredIfNavPaneCollapsed() {
|
||||
if (useAppStore.getState().isNavPaneCollapsed) {
|
||||
useAppStore.getState().setCollapsedNavPaneHovered(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import { store as appStore } from "../../stores/app-store";
|
||||
import { Multiselect } from "../../common/multi-select";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { db } from "../../common/db";
|
||||
import { collapseNavPaneHoveredIfNavPaneCollapsed } from "../navigation-menu";
|
||||
|
||||
type NotebookProps = {
|
||||
item: NotebookType;
|
||||
@@ -78,7 +79,10 @@ export function Notebook(props: NotebookProps) {
|
||||
isFocused={isOpened}
|
||||
isCompact
|
||||
item={item}
|
||||
onClick={() => navigate(`/notebooks/${item.id}`)}
|
||||
onClick={() => {
|
||||
navigate(`/notebooks/${item.id}`);
|
||||
collapseNavPaneHoveredIfNavPaneCollapsed();
|
||||
}}
|
||||
onDragEnter={(e) => {
|
||||
if (!isDragEntering(e)) return;
|
||||
e.currentTarget.focus();
|
||||
|
||||
@@ -31,6 +31,7 @@ import { useStore as useSelectionStore } from "../../stores/selection-store";
|
||||
import { useStore as useNoteStore } from "../../stores/note-store";
|
||||
import { Multiselect } from "../../common/multi-select";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { collapseNavPaneHoveredIfNavPaneCollapsed } from "../navigation-menu";
|
||||
|
||||
type TagProps = { item: TagType; totalNotes: number };
|
||||
function Tag(props: TagProps) {
|
||||
@@ -87,6 +88,7 @@ function Tag(props: TagProps) {
|
||||
menuItems={tagMenuItems}
|
||||
onClick={() => {
|
||||
navigate(`/tags/${id}`);
|
||||
collapseNavPaneHoveredIfNavPaneCollapsed();
|
||||
}}
|
||||
onDragEnter={(e) => {
|
||||
e?.currentTarget.focus();
|
||||
|
||||
@@ -67,6 +67,7 @@ class AppStore extends BaseStore<AppStore> {
|
||||
isFocusMode = false;
|
||||
isListPaneVisible = true;
|
||||
isNavPaneCollapsed = false;
|
||||
isCollapsedNavPaneHovered = false;
|
||||
isVaultCreated = false;
|
||||
isAutoSyncEnabled = Config.get("autoSyncEnabled", true);
|
||||
isSyncEnabled = Config.get("syncEnabled", true);
|
||||
@@ -171,6 +172,10 @@ class AppStore extends BaseStore<AppStore> {
|
||||
);
|
||||
};
|
||||
|
||||
setCollapsedNavPaneHovered = (state: boolean) => {
|
||||
this.set({ isCollapsedNavPaneHovered: state });
|
||||
};
|
||||
|
||||
refresh = async () => {
|
||||
logger.measure("refreshing app");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user