mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-22 22:49:45 +01:00
web: replace allotment with react-resizable-panels
This commit is contained in:
1283
apps/web/package-lock.json
generated
1283
apps/web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -39,7 +39,6 @@
|
|||||||
"@trpc/client": "10.38.3",
|
"@trpc/client": "10.38.3",
|
||||||
"@trpc/react-query": "10.38.3",
|
"@trpc/react-query": "10.38.3",
|
||||||
"@zip.js/zip.js": "^2.7.32",
|
"@zip.js/zip.js": "^2.7.32",
|
||||||
"allotment": "^1.19.3",
|
|
||||||
"async-mutex": "^0.4.0",
|
"async-mutex": "^0.4.0",
|
||||||
"axios": "^1.3.4",
|
"axios": "^1.3.4",
|
||||||
"clipboard-polyfill": "4.0.0",
|
"clipboard-polyfill": "4.0.0",
|
||||||
@@ -77,6 +76,7 @@
|
|||||||
"react-loading-skeleton": "^3.3.1",
|
"react-loading-skeleton": "^3.3.1",
|
||||||
"react-modal": "3.16.1",
|
"react-modal": "3.16.1",
|
||||||
"react-qrcode-logo": "^2.9.0",
|
"react-qrcode-logo": "^2.9.0",
|
||||||
|
"react-resizable-panels": "^2.0.17",
|
||||||
"react-scroll-sync": "^0.11.2",
|
"react-scroll-sync": "^0.11.2",
|
||||||
"react-virtuoso": "^4.6.2",
|
"react-virtuoso": "^4.6.2",
|
||||||
"timeago.js": "4.0.2",
|
"timeago.js": "4.0.2",
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
diff --git a/node_modules/allotment/dist/modern.mjs b/node_modules/allotment/dist/modern.mjs
|
|
||||||
index d5dbdc6..e2d9d2e 100644
|
|
||||||
--- a/node_modules/allotment/dist/modern.mjs
|
|
||||||
+++ b/node_modules/allotment/dist/modern.mjs
|
|
||||||
@@ -1156,11 +1156,11 @@ class Ne extends W {
|
|
||||||
return e < 0 || e >= this.viewItems.length ? -1 : this.viewItems[e].size;
|
|
||||||
}
|
|
||||||
isViewVisible(e) {
|
|
||||||
- if (e < 0 || e >= this.viewItems.length) throw new Error("Index out of bounds");
|
|
||||||
+ if (e < 0 || e >= this.viewItems.length) return false;
|
|
||||||
return this.viewItems[e].visible;
|
|
||||||
}
|
|
||||||
setViewVisible(e, t) {
|
|
||||||
- if (e < 0 || e >= this.viewItems.length) throw new Error("Index out of bounds");
|
|
||||||
+ if (e < 0 || e >= this.viewItems.length) return;
|
|
||||||
this.viewItems[e].setVisible(t), this.distributeEmptySpace(e), this.layoutViews(), this.saveProportions();
|
|
||||||
}
|
|
||||||
distributeViewSizes() {
|
|
||||||
diff --git a/node_modules/allotment/dist/module.js b/node_modules/allotment/dist/module.js
|
|
||||||
index 0de655f..f296aff 100644
|
|
||||||
--- a/node_modules/allotment/dist/module.js
|
|
||||||
+++ b/node_modules/allotment/dist/module.js
|
|
||||||
@@ -1168,11 +1168,11 @@ class Ne extends W {
|
|
||||||
return e < 0 || e >= this.viewItems.length ? -1 : this.viewItems[e].size;
|
|
||||||
}
|
|
||||||
isViewVisible(e) {
|
|
||||||
- if (e < 0 || e >= this.viewItems.length) throw new Error("Index out of bounds");
|
|
||||||
+ if (e < 0 || e >= this.viewItems.length) return false;
|
|
||||||
return this.viewItems[e].visible;
|
|
||||||
}
|
|
||||||
setViewVisible(e, t) {
|
|
||||||
- if (e < 0 || e >= this.viewItems.length) throw new Error("Index out of bounds");
|
|
||||||
+ if (e < 0 || e >= this.viewItems.length) return;
|
|
||||||
this.viewItems[e].setVisible(t), this.distributeEmptySpace(e), this.layoutViews(), this.saveProportions();
|
|
||||||
}
|
|
||||||
distributeViewSizes() {
|
|
||||||
@@ -14,16 +14,31 @@
|
|||||||
-webkit-app-region: no-drag;
|
-webkit-app-region: no-drag;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sash-module_sash__K-9lB.sash-module_hover__80W6I:before,
|
.panel-resize-handle {
|
||||||
.sash-module_sash__K-9lB.sash-module_active__bJspD:before {
|
position: relative;
|
||||||
background: var(--accent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.allotment-module_splitView__L-yRc.allotment-module_separatorBorder__x-rDS
|
.panel-resize-handle::before {
|
||||||
> .allotment-module_splitViewContainer__rQnVa
|
content: " ";
|
||||||
> .allotment-module_splitViewView__MGZ6O:not(:first-child)::before {
|
position: absolute;
|
||||||
background-color: transparent;
|
transition: background-color 300ms ease-out;
|
||||||
|
z-index: 999;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.panel-resize-handle[data-panel-group-direction="horizontal"]::before {
|
||||||
|
width: 5px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-resize-handle[data-panel-group-direction="vertical"]::before {
|
||||||
|
width: 100%;
|
||||||
|
height: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-resize-handle[data-resize-handle-state="hover"]::before {
|
||||||
|
background-color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
/* open-sans-regular - vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic */
|
/* open-sans-regular - vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Open Sans";
|
font-family: "Open Sans";
|
||||||
|
|||||||
@@ -17,13 +17,12 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useState, Suspense, useRef } from "react";
|
import React, { useState, Suspense, useRef, useEffect } from "react";
|
||||||
import { Box, Flex } from "@theme-ui/components";
|
import { Box, Flex } from "@theme-ui/components";
|
||||||
import { ScopedThemeProvider } from "./components/theme-provider";
|
import { ScopedThemeProvider } from "./components/theme-provider";
|
||||||
import useMobile from "./hooks/use-mobile";
|
import useMobile from "./hooks/use-mobile";
|
||||||
import useTablet from "./hooks/use-tablet";
|
import useTablet from "./hooks/use-tablet";
|
||||||
import useDatabase from "./hooks/use-database";
|
import useDatabase from "./hooks/use-database";
|
||||||
import { Allotment, AllotmentHandle, LayoutPriority } from "allotment";
|
|
||||||
import { useStore } from "./stores/app-store";
|
import { useStore } from "./stores/app-store";
|
||||||
import { Toaster } from "react-hot-toast";
|
import { Toaster } from "react-hot-toast";
|
||||||
import { ViewLoader } from "./components/loaders/view-loader";
|
import { ViewLoader } from "./components/loaders/view-loader";
|
||||||
@@ -33,7 +32,12 @@ import { EditorLoader } from "./components/loaders/editor-loader";
|
|||||||
import { FlexScrollContainer } from "./components/scroll-container";
|
import { FlexScrollContainer } from "./components/scroll-container";
|
||||||
import CachedRouter from "./components/cached-router";
|
import CachedRouter from "./components/cached-router";
|
||||||
import { WebExtensionRelay } from "./utils/web-extension-relay";
|
import { WebExtensionRelay } from "./utils/web-extension-relay";
|
||||||
import { usePersistentState } from "./hooks/use-persistent-state";
|
import {
|
||||||
|
PanelGroup,
|
||||||
|
Panel,
|
||||||
|
PanelResizeHandle,
|
||||||
|
ImperativePanelHandle
|
||||||
|
} from "react-resizable-panels";
|
||||||
|
|
||||||
new WebExtensionRelay();
|
new WebExtensionRelay();
|
||||||
|
|
||||||
@@ -128,12 +132,19 @@ function DesktopAppContents({
|
|||||||
}: DesktopAppContentsProps) {
|
}: DesktopAppContentsProps) {
|
||||||
const isFocusMode = useStore((store) => store.isFocusMode);
|
const isFocusMode = useStore((store) => store.isFocusMode);
|
||||||
const isTablet = useTablet();
|
const isTablet = useTablet();
|
||||||
const [paneSizes, setPaneSizes] = usePersistentState("paneSizes", [
|
const [isNarrow, setIsNarrow] = useState(isTablet || false);
|
||||||
isTablet ? 60 : 180,
|
const navPane = useRef<ImperativePanelHandle>(null);
|
||||||
isTablet ? 240 : 380
|
const middlePane = useRef<ImperativePanelHandle>(null);
|
||||||
]);
|
|
||||||
const panesRef = useRef<AllotmentHandle>(null);
|
useEffect(() => {
|
||||||
const [isNarrow, setIsNarrow] = useState(paneSizes[0] <= 55);
|
if (show) middlePane.current?.expand();
|
||||||
|
else middlePane.current?.collapse();
|
||||||
|
}, [show]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isFocusMode) navPane.current?.collapse();
|
||||||
|
else navPane.current?.expand();
|
||||||
|
}, [isFocusMode]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -143,20 +154,14 @@ function DesktopAppContents({
|
|||||||
overflow: "hidden"
|
overflow: "hidden"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Allotment
|
<PanelGroup autoSaveId="global-panel-group" direction="horizontal">
|
||||||
ref={panesRef}
|
<Panel
|
||||||
proportionalLayout={false}
|
ref={navPane}
|
||||||
onDragEnd={(sizes) => {
|
className="nav-pane"
|
||||||
setPaneSizes(sizes);
|
defaultSize={10}
|
||||||
setIsNarrow(sizes[0] <= 55);
|
minSize={3}
|
||||||
}}
|
onResize={(size) => setIsNarrow(size <= 3)}
|
||||||
>
|
collapsible
|
||||||
<Allotment.Pane
|
|
||||||
className="pane nav-pane"
|
|
||||||
minSize={50}
|
|
||||||
preferredSize={isTablet ? 50 : paneSizes[0]}
|
|
||||||
visible={!isFocusMode}
|
|
||||||
priority={LayoutPriority.Low}
|
|
||||||
>
|
>
|
||||||
<NavigationMenu
|
<NavigationMenu
|
||||||
toggleNavigationContainer={(state) => {
|
toggleNavigationContainer={(state) => {
|
||||||
@@ -164,13 +169,13 @@ function DesktopAppContents({
|
|||||||
}}
|
}}
|
||||||
isTablet={isNarrow}
|
isTablet={isNarrow}
|
||||||
/>
|
/>
|
||||||
</Allotment.Pane>
|
</Panel>
|
||||||
<Allotment.Pane
|
<PanelResizeHandle className="panel-resize-handle" />
|
||||||
className="pane middle-pane"
|
<Panel
|
||||||
minSize={2}
|
ref={middlePane}
|
||||||
preferredSize={paneSizes[1]}
|
className="middle-pane"
|
||||||
visible={show}
|
collapsible
|
||||||
priority={LayoutPriority.Normal}
|
defaultSize={20}
|
||||||
>
|
>
|
||||||
<ScopedThemeProvider
|
<ScopedThemeProvider
|
||||||
className="listMenu"
|
className="listMenu"
|
||||||
@@ -185,11 +190,9 @@ function DesktopAppContents({
|
|||||||
>
|
>
|
||||||
{isAppLoaded && <CachedRouter />}
|
{isAppLoaded && <CachedRouter />}
|
||||||
</ScopedThemeProvider>
|
</ScopedThemeProvider>
|
||||||
</Allotment.Pane>
|
</Panel>
|
||||||
<Allotment.Pane
|
<PanelResizeHandle className="panel-resize-handle" />
|
||||||
className="pane editor-pane"
|
<Panel className="editor-pane">
|
||||||
priority={LayoutPriority.High}
|
|
||||||
>
|
|
||||||
<Flex
|
<Flex
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@@ -201,10 +204,9 @@ function DesktopAppContents({
|
|||||||
>
|
>
|
||||||
{isAppLoaded && <HashRouter />}
|
{isAppLoaded && <HashRouter />}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Allotment.Pane>
|
</Panel>
|
||||||
</Allotment>
|
</PanelGroup>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<StatusBar />
|
<StatusBar />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ export async function downloadAttachment<
|
|||||||
type: TType,
|
type: TType,
|
||||||
groupId?: string
|
groupId?: string
|
||||||
): Promise<TOutputType | undefined> {
|
): Promise<TOutputType | undefined> {
|
||||||
|
console.log("DOWNLOADING FILE", hash);
|
||||||
const response = await download(hash, groupId);
|
const response = await download(hash, groupId);
|
||||||
if (!response) return;
|
if (!response) return;
|
||||||
const { attachment, key } = response;
|
const { attachment, key } = response;
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ import Titlebox from "./title-box";
|
|||||||
import Config from "../../utils/config";
|
import Config from "../../utils/config";
|
||||||
import { ScopedThemeProvider } from "../theme-provider";
|
import { ScopedThemeProvider } from "../theme-provider";
|
||||||
import { Lightbox } from "../lightbox";
|
import { Lightbox } from "../lightbox";
|
||||||
import { Allotment } from "allotment";
|
|
||||||
import { showToast } from "../../utils/toast";
|
import { showToast } from "../../utils/toast";
|
||||||
import { Item, MaybeDeletedItem, isDeleted } from "@notesnook/core/dist/types";
|
import { Item, MaybeDeletedItem, isDeleted } from "@notesnook/core/dist/types";
|
||||||
import { debounce, debounceWithId } from "@notesnook/common";
|
import { debounce, debounceWithId } from "@notesnook/common";
|
||||||
@@ -69,6 +68,7 @@ import { scrollIntoViewById } from "@notesnook/editor";
|
|||||||
import { IEditor } from "./types";
|
import { IEditor } from "./types";
|
||||||
import { EditorActionBar } from "./action-bar";
|
import { EditorActionBar } from "./action-bar";
|
||||||
import { logger } from "../../utils/logger";
|
import { logger } from "../../utils/logger";
|
||||||
|
import { PanelGroup, Panel, PanelResizeHandle } from "react-resizable-panels";
|
||||||
|
|
||||||
const PDFPreview = React.lazy(() => import("../pdf-preview"));
|
const PDFPreview = React.lazy(() => import("../pdf-preview"));
|
||||||
|
|
||||||
@@ -120,13 +120,8 @@ export default function TabsView() {
|
|||||||
flexDirection: "column"
|
flexDirection: "column"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Allotment
|
<PanelGroup direction="horizontal" autoSaveId={"editor-panels"}>
|
||||||
proportionalLayout={true}
|
<Panel id="editor-panel" className="editor-pane" order={1}>
|
||||||
onDragEnd={(sizes) => {
|
|
||||||
Config.set("editor:panesize", sizes[1]);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Allotment.Pane className="editor-pane">
|
|
||||||
{sessions.map((session) => (
|
{sessions.map((session) => (
|
||||||
<Freeze
|
<Freeze
|
||||||
key={session.id}
|
key={session.id}
|
||||||
@@ -164,46 +159,55 @@ export default function TabsView() {
|
|||||||
)}
|
)}
|
||||||
</Freeze>
|
</Freeze>
|
||||||
))}
|
))}
|
||||||
</Allotment.Pane>
|
</Panel>
|
||||||
|
|
||||||
{documentPreview && (
|
{documentPreview && (
|
||||||
<Allotment.Pane
|
<>
|
||||||
minSize={450}
|
<PanelResizeHandle className="panel-resize-handle" />
|
||||||
preferredSize={Config.get("editor:panesize", 500)}
|
<Panel
|
||||||
>
|
id="pdf-preview-panel"
|
||||||
<ScopedThemeProvider
|
order={2}
|
||||||
scope="editorSidebar"
|
minSize={35}
|
||||||
id="editorSidebar"
|
defaultSize={35}
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
overflow: "hidden",
|
|
||||||
borderLeft: "1px solid var(--border)",
|
|
||||||
height: "100%",
|
|
||||||
bg: "background"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{documentPreview.url ? (
|
<ScopedThemeProvider
|
||||||
<Suspense
|
scope="editorSidebar"
|
||||||
fallback={
|
id="editorSidebar"
|
||||||
<DownloadAttachmentProgress hash={documentPreview.hash} />
|
sx={{
|
||||||
}
|
display: "flex",
|
||||||
>
|
flexDirection: "column",
|
||||||
<PDFPreview
|
overflow: "hidden",
|
||||||
fileUrl={documentPreview.url}
|
borderLeft: "1px solid var(--border)",
|
||||||
hash={documentPreview.hash}
|
height: "100%",
|
||||||
onClose={() =>
|
bg: "background"
|
||||||
useEditorStore.setState({ documentPreview: undefined })
|
}}
|
||||||
|
>
|
||||||
|
{documentPreview.url ? (
|
||||||
|
<Suspense
|
||||||
|
fallback={
|
||||||
|
<DownloadAttachmentProgress
|
||||||
|
hash={documentPreview.hash}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
/>
|
>
|
||||||
</Suspense>
|
<PDFPreview
|
||||||
) : (
|
fileUrl={documentPreview.url}
|
||||||
<DownloadAttachmentProgress hash={documentPreview.hash} />
|
hash={documentPreview.hash}
|
||||||
)}
|
onClose={() =>
|
||||||
</ScopedThemeProvider>
|
useEditorStore.setState({
|
||||||
</Allotment.Pane>
|
documentPreview: undefined
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Suspense>
|
||||||
|
) : (
|
||||||
|
<DownloadAttachmentProgress hash={documentPreview.hash} />
|
||||||
|
)}
|
||||||
|
</ScopedThemeProvider>
|
||||||
|
</Panel>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</Allotment>
|
</PanelGroup>
|
||||||
<DropZone overlayRef={overlayRef} />
|
<DropZone overlayRef={overlayRef} />
|
||||||
{arePropertiesVisible && activeSessionId && (
|
{arePropertiesVisible && activeSessionId && (
|
||||||
<Properties sessionId={activeSessionId} />
|
<Properties sessionId={activeSessionId} />
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { initializeDatabase } from "../common/db";
|
import { initializeDatabase } from "../common/db";
|
||||||
import { useErrorBoundary } from "react-error-boundary";
|
import { useErrorBoundary } from "react-error-boundary";
|
||||||
import "allotment/dist/style.css";
|
|
||||||
import "../utils/analytics";
|
import "../utils/analytics";
|
||||||
import "../app.css";
|
import "../app.css";
|
||||||
|
|
||||||
|
|||||||
@@ -458,6 +458,7 @@ async function downloadFile(
|
|||||||
requestOptions: RequestOptionsWithSignal
|
requestOptions: RequestOptionsWithSignal
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
console.log("DOWNLOADING FILE", filename);
|
||||||
const { url, headers, chunkSize, signal } = requestOptions;
|
const { url, headers, chunkSize, signal } = requestOptions;
|
||||||
const handle = await streamablefs.readFile(filename);
|
const handle = await streamablefs.readFile(filename);
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ const routes = defineRoutes({
|
|||||||
return defineRoute({
|
return defineRoute({
|
||||||
key: "notebook",
|
key: "notebook",
|
||||||
type: "notes",
|
type: "notes",
|
||||||
|
noCache: true,
|
||||||
component: Notebook,
|
component: Notebook,
|
||||||
props: {
|
props: {
|
||||||
rootId,
|
rootId,
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export type RouteResult = {
|
|||||||
| React.MemoExoticComponent<React.FunctionComponent>;
|
| React.MemoExoticComponent<React.FunctionComponent>;
|
||||||
props?: any;
|
props?: any;
|
||||||
buttons?: RouteContainerButtons;
|
buttons?: RouteContainerButtons;
|
||||||
|
noCache?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function isRouteResult(obj: any): obj is RouteResult {
|
export function isRouteResult(obj: any): obj is RouteResult {
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import {
|
|||||||
ShortcutLink
|
ShortcutLink
|
||||||
} from "../components/icons";
|
} from "../components/icons";
|
||||||
import { pluralize } from "@notesnook/common";
|
import { pluralize } from "@notesnook/common";
|
||||||
import { Allotment, AllotmentHandle } from "allotment";
|
|
||||||
import { Plus } from "../components/icons";
|
import { Plus } from "../components/icons";
|
||||||
import { useStore as useNotesStore } from "../stores/note-store";
|
import { useStore as useNotesStore } from "../stores/note-store";
|
||||||
import { useStore as useNotebookStore } from "../stores/notebook-store";
|
import { useStore as useNotebookStore } from "../stores/notebook-store";
|
||||||
@@ -58,6 +57,12 @@ import { FlexScrollContainer } from "../components/scroll-container";
|
|||||||
import { Menu } from "../hooks/use-menu";
|
import { Menu } from "../hooks/use-menu";
|
||||||
import Config from "../utils/config";
|
import Config from "../utils/config";
|
||||||
import Notes from "./notes";
|
import Notes from "./notes";
|
||||||
|
import {
|
||||||
|
PanelGroup,
|
||||||
|
Panel,
|
||||||
|
PanelResizeHandle,
|
||||||
|
ImperativePanelHandle
|
||||||
|
} from "react-resizable-panels";
|
||||||
|
|
||||||
type NotebookProps = {
|
type NotebookProps = {
|
||||||
rootId: string;
|
rootId: string;
|
||||||
@@ -67,8 +72,7 @@ function Notebook(props: NotebookProps) {
|
|||||||
const { rootId, notebookId } = props;
|
const { rootId, notebookId } = props;
|
||||||
const [isCollapsed, setIsCollapsed] = useState(false);
|
const [isCollapsed, setIsCollapsed] = useState(false);
|
||||||
|
|
||||||
const paneRef = useRef<AllotmentHandle>(null);
|
const subNotebooksPane = useRef<ImperativePanelHandle>(null);
|
||||||
const sizes = useRef<number[]>([]);
|
|
||||||
|
|
||||||
const context = useNotesStore((store) => store.context);
|
const context = useNotesStore((store) => store.context);
|
||||||
const notes = useNotesStore((store) => store.contextNotes);
|
const notes = useNotesStore((store) => store.contextNotes);
|
||||||
@@ -96,68 +100,44 @@ function Notebook(props: NotebookProps) {
|
|||||||
});
|
});
|
||||||
}, [rootId, notebookId]);
|
}, [rootId, notebookId]);
|
||||||
|
|
||||||
const toggleCollapse = useCallback((isCollapsed: boolean) => {
|
|
||||||
if (!paneRef.current || !sizes.current) return;
|
|
||||||
|
|
||||||
if (!isCollapsed) {
|
|
||||||
if (sizes.current[1] < 60) {
|
|
||||||
paneRef.current.reset();
|
|
||||||
} else {
|
|
||||||
paneRef.current.resize(sizes.current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
toggleCollapse(isCollapsed);
|
|
||||||
}, [isCollapsed, toggleCollapse]);
|
|
||||||
|
|
||||||
if (!context || !notes || context.type !== "notebook") return null;
|
if (!context || !notes || context.type !== "notebook") return null;
|
||||||
return (
|
return (
|
||||||
<>
|
<PanelGroup
|
||||||
<Allotment
|
direction="vertical"
|
||||||
ref={paneRef}
|
autoSaveId={`notebook-panel-sizes:${rootId}`}
|
||||||
vertical
|
>
|
||||||
onChange={(paneSizes) => {
|
<Panel>
|
||||||
const [_, topicsPane] = paneSizes;
|
<Notes
|
||||||
if (topicsPane > 30 && !isCollapsed) sizes.current = paneSizes;
|
header={
|
||||||
}}
|
<NotebookHeader
|
||||||
onDragEnd={([_, topicsPane]) => {
|
key={context.id}
|
||||||
if (topicsPane < 35 && !isCollapsed) {
|
rootId={rootId}
|
||||||
setIsCollapsed(true);
|
context={context}
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Allotment.Pane>
|
|
||||||
<Flex variant="columnFill" sx={{ height: "100%" }}>
|
|
||||||
<Notes
|
|
||||||
header={
|
|
||||||
<NotebookHeader
|
|
||||||
key={context.id}
|
|
||||||
rootId={rootId}
|
|
||||||
context={context}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
}
|
||||||
</Allotment.Pane>
|
/>
|
||||||
<Allotment.Pane
|
</Panel>
|
||||||
preferredSize={250}
|
<PanelResizeHandle className="panel-resize-handle" />
|
||||||
visible
|
<Panel
|
||||||
maxSize={isCollapsed ? 30 : Infinity}
|
ref={subNotebooksPane}
|
||||||
>
|
defaultSize={25}
|
||||||
<SubNotebooks
|
collapsedSize={7}
|
||||||
key={rootId}
|
collapsible
|
||||||
notebookId={notebookId}
|
minSize={7}
|
||||||
isCollapsed={isCollapsed}
|
onResize={(size) => setIsCollapsed(size <= 7)}
|
||||||
rootId={rootId}
|
>
|
||||||
onClick={() => {
|
<SubNotebooks
|
||||||
setIsCollapsed((isCollapsed) => !isCollapsed);
|
key={rootId}
|
||||||
}}
|
notebookId={notebookId}
|
||||||
/>
|
isCollapsed={isCollapsed}
|
||||||
</Allotment.Pane>
|
rootId={rootId}
|
||||||
</Allotment>
|
onClick={() => {
|
||||||
</>
|
if (isCollapsed) subNotebooksPane.current?.expand();
|
||||||
|
else subNotebooksPane.current?.collapse();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Panel>
|
||||||
|
</PanelGroup>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
export default Notebook;
|
export default Notebook;
|
||||||
|
|||||||
Reference in New Issue
Block a user