mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-25 16:09:42 +01:00
@@ -16,6 +16,7 @@
|
||||
"@streetwriters/tinymce-plugins": "^1.5.18",
|
||||
"@tinymce/tinymce-react": "^3.13.0",
|
||||
"@types/rebass": "^4.0.10",
|
||||
"allotment": "^1.12.1",
|
||||
"async-mutex": "^0.3.2",
|
||||
"axios": "^0.21.4",
|
||||
"clipboard-polyfill": "^3.0.3",
|
||||
|
||||
@@ -17,7 +17,7 @@ export default function MobileAppEffects({ sliderId, overlayId, setShow }) {
|
||||
onSliding: (e, { lastSlide, position, lastPosition }) => {
|
||||
if (!isMobile) return;
|
||||
const offset = 70;
|
||||
const width = 180;
|
||||
const width = 300;
|
||||
|
||||
const percent = offset - (position / width) * offset;
|
||||
const overlay = document.getElementById("overlay");
|
||||
@@ -32,6 +32,7 @@ export default function MobileAppEffects({ sliderId, overlayId, setShow }) {
|
||||
onChange: (e, { slide, lastSlide }) => {
|
||||
if (!lastSlide || !isMobile) return;
|
||||
toggleSideMenu(slide?.index === 0 ? true : false);
|
||||
console.log("Setting editor", slide?.index === 2 ? true : false);
|
||||
setIsEditorOpen(slide?.index === 2 ? true : false);
|
||||
},
|
||||
});
|
||||
@@ -43,6 +44,7 @@ export default function MobileAppEffects({ sliderId, overlayId, setShow }) {
|
||||
|
||||
useEffect(() => {
|
||||
if (!isMobile) return;
|
||||
console.log(isEditorOpen);
|
||||
slideToIndex(isEditorOpen ? 2 : 1);
|
||||
}, [isMobile, slideToIndex, isEditorOpen]);
|
||||
|
||||
|
||||
@@ -119,3 +119,28 @@ textarea,
|
||||
background-color: var(--dimPrimary);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.middle-pane {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
}
|
||||
.editor-pane {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.nav-pane {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
}
|
||||
.pane::before {
|
||||
width: 1px !important;
|
||||
}
|
||||
|
||||
:root {
|
||||
--focus-border: var(--primary);
|
||||
--separator-border: var(--border);
|
||||
--sash-size: 10px;
|
||||
--sash-hover-size: 4px;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
import React, { useState, Suspense } from "react";
|
||||
import React, { useState, Suspense, useMemo, useRef, useEffect } from "react";
|
||||
import { Box, Flex } from "rebass";
|
||||
import ThemeProvider from "./components/theme-provider";
|
||||
import { AnimatedFlex } from "./components/animated";
|
||||
import NavigationMenuPlaceholder from "./components/navigationmenu/index.lite";
|
||||
import StatusBarPlaceholder from "./components/statusbar/index.lite";
|
||||
import useMobile from "./utils/use-mobile";
|
||||
import useTablet from "./utils/use-tablet";
|
||||
import { LazyMotion, domAnimation } from "framer-motion";
|
||||
import useDatabase from "./hooks/use-database";
|
||||
import Loader from "./components/loader";
|
||||
import { Allotment } from "allotment";
|
||||
import "allotment/dist/style.css";
|
||||
import Config from "./utils/config";
|
||||
import EditorLoading from "./components/editor/loading";
|
||||
import NavigationMenuPlaceholder from "./components/navigationmenu/index.lite";
|
||||
|
||||
const GlobalMenuWrapper = React.lazy(() =>
|
||||
import("./components/global-menu-wrapper")
|
||||
@@ -22,9 +24,8 @@ const NavigationMenu = React.lazy(() => import("./components/navigation-menu"));
|
||||
const StatusBar = React.lazy(() => import("./components/status-bar"));
|
||||
|
||||
function App() {
|
||||
const [show, setShow] = useState(true);
|
||||
const isMobile = useMobile();
|
||||
const isTablet = useTablet();
|
||||
const [show, setShow] = useState(true);
|
||||
const [isAppLoaded] = useDatabase();
|
||||
|
||||
return (
|
||||
@@ -52,116 +53,15 @@ function App() {
|
||||
height="100%"
|
||||
sx={{ overflow: "hidden" }}
|
||||
>
|
||||
<Flex
|
||||
id="slider"
|
||||
variant="rowFill"
|
||||
overflowX={["auto", "hidden"]}
|
||||
sx={{
|
||||
overflowY: "hidden",
|
||||
scrollSnapType: "x mandatory",
|
||||
scrollBehavior: "smooth",
|
||||
WebkitOverflowScrolling: "touch",
|
||||
scrollSnapStop: "always",
|
||||
overscrollBehavior: "contain",
|
||||
}}
|
||||
>
|
||||
<Flex
|
||||
flexShrink={0}
|
||||
sx={{
|
||||
scrollSnapAlign: "start",
|
||||
scrollSnapStop: "always",
|
||||
}}
|
||||
>
|
||||
<SuspenseLoader
|
||||
condition={isAppLoaded}
|
||||
component={NavigationMenu}
|
||||
props={{
|
||||
toggleNavigationContainer: (state) => {
|
||||
if (!isMobile) setShow(state || !show);
|
||||
},
|
||||
}}
|
||||
fallback={<NavigationMenuPlaceholder />}
|
||||
/>
|
||||
</Flex>
|
||||
<AnimatedFlex
|
||||
className="listMenu"
|
||||
variant="columnFill"
|
||||
initial={{
|
||||
width: isMobile ? "100vw" : isTablet ? "40%" : "25%",
|
||||
opacity: 1,
|
||||
x: 0,
|
||||
}}
|
||||
animate={{
|
||||
width: show
|
||||
? isMobile
|
||||
? "100vw"
|
||||
: isTablet
|
||||
? "40%"
|
||||
: "25%"
|
||||
: "0%",
|
||||
x: show ? 0 : isTablet ? "-40%" : "-25%",
|
||||
opacity: show ? 1 : 0,
|
||||
}}
|
||||
transition={{ duration: 0.2, ease: "easeOut" }}
|
||||
sx={{
|
||||
borderRight: "1px solid",
|
||||
borderColor: "border",
|
||||
borderRightWidth: show ? 1 : 0,
|
||||
position: "relative",
|
||||
scrollSnapAlign: "start",
|
||||
scrollSnapStop: "always",
|
||||
}}
|
||||
flexShrink={0}
|
||||
>
|
||||
<SuspenseLoader
|
||||
condition={isAppLoaded}
|
||||
component={CachedRouter}
|
||||
fallback={
|
||||
<Loader
|
||||
title="Did you know?"
|
||||
text="All your notes are encrypted on your device."
|
||||
/>
|
||||
}
|
||||
/>
|
||||
{isMobile && (
|
||||
<Box
|
||||
id="overlay"
|
||||
sx={{
|
||||
position: "absolute",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: 999,
|
||||
opacity: 0,
|
||||
visibility: "visible",
|
||||
pointerEvents: "none",
|
||||
}}
|
||||
bg="black"
|
||||
/>
|
||||
)}
|
||||
</AnimatedFlex>
|
||||
<Flex
|
||||
width={["100vw", "100%"]}
|
||||
flexShrink={[0, 1]}
|
||||
sx={{
|
||||
scrollSnapAlign: "start",
|
||||
scrollSnapStop: "always",
|
||||
}}
|
||||
flexDirection="column"
|
||||
>
|
||||
<SuspenseLoader
|
||||
fallback={<EditorLoading />}
|
||||
component={HashRouter}
|
||||
condition={isAppLoaded}
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<SuspenseLoader
|
||||
fallback={<StatusBarPlaceholder />}
|
||||
component={StatusBar}
|
||||
condition={isAppLoaded}
|
||||
/>
|
||||
{isMobile ? (
|
||||
<MobileAppContents isAppLoaded={isAppLoaded} />
|
||||
) : (
|
||||
<DesktopAppContents
|
||||
isAppLoaded={isAppLoaded}
|
||||
setShow={setShow}
|
||||
show={show}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
</ThemeProvider>
|
||||
</LazyMotion>
|
||||
@@ -179,3 +79,194 @@ function SuspenseLoader({ condition, props, component: Component, fallback }) {
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
function DesktopAppContents({ isAppLoaded, show, setShow }) {
|
||||
const isTablet = useTablet();
|
||||
const defaultSizes = useMemo(
|
||||
() => [isTablet ? 60 : 180, isTablet ? 240 : 380],
|
||||
[isTablet]
|
||||
);
|
||||
const paneSizes = useMemo(
|
||||
() => Config.get("paneSizes", defaultSizes),
|
||||
[defaultSizes]
|
||||
);
|
||||
const [isNarrow, setIsNarrow] = useState(isTablet);
|
||||
const panesRef = useRef();
|
||||
|
||||
useEffect(() => {
|
||||
panesRef.current.reset();
|
||||
}, [isTablet]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex
|
||||
variant="rowFill"
|
||||
sx={{
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
<Allotment
|
||||
ref={panesRef}
|
||||
proportionalLayout
|
||||
onChange={(sizes) => {
|
||||
Config.set("paneSizes", sizes);
|
||||
setIsNarrow(sizes[0] <= 132);
|
||||
}}
|
||||
>
|
||||
<Allotment.Pane
|
||||
className="pane nav-pane"
|
||||
minSize={50}
|
||||
preferredSize={paneSizes[0]}
|
||||
>
|
||||
<Flex flex={1}>
|
||||
<SuspenseLoader
|
||||
condition={isAppLoaded}
|
||||
component={NavigationMenu}
|
||||
props={{
|
||||
toggleNavigationContainer: (state) => {
|
||||
setShow(state || !show);
|
||||
},
|
||||
isTablet: isTablet || isNarrow,
|
||||
}}
|
||||
fallback={<NavigationMenuPlaceholder />}
|
||||
/>
|
||||
</Flex>
|
||||
</Allotment.Pane>
|
||||
<Allotment.Pane
|
||||
className="pane middle-pane"
|
||||
minSize={5}
|
||||
preferredSize={paneSizes[1]}
|
||||
visible={show}
|
||||
>
|
||||
<Flex className="listMenu" variant="columnFill">
|
||||
<SuspenseLoader
|
||||
condition={isAppLoaded}
|
||||
component={CachedRouter}
|
||||
fallback={
|
||||
<Loader
|
||||
title="Did you know?"
|
||||
text="All your notes are encrypted on your device."
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</Flex>
|
||||
</Allotment.Pane>
|
||||
|
||||
<Allotment.Pane className="pane editor-pane">
|
||||
<Flex
|
||||
sx={{
|
||||
overflow: "hidden",
|
||||
flex: 1,
|
||||
}}
|
||||
flexDirection="column"
|
||||
>
|
||||
<SuspenseLoader
|
||||
fallback={
|
||||
<Loader
|
||||
title="Fun fact"
|
||||
text="Notesnook was released in January 2021 by a team of only 3 people."
|
||||
/>
|
||||
}
|
||||
component={HashRouter}
|
||||
condition={isAppLoaded}
|
||||
/>
|
||||
</Flex>
|
||||
</Allotment.Pane>
|
||||
</Allotment>
|
||||
</Flex>
|
||||
<SuspenseLoader
|
||||
fallback={<StatusBarPlaceholder />}
|
||||
component={StatusBar}
|
||||
condition={isAppLoaded}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function MobileAppContents({ isAppLoaded }) {
|
||||
return (
|
||||
<Flex
|
||||
id="slider"
|
||||
variant="rowFill"
|
||||
overflowX={"auto"}
|
||||
sx={{
|
||||
overflowY: "hidden",
|
||||
scrollSnapType: "x mandatory",
|
||||
scrollBehavior: "smooth",
|
||||
WebkitOverflowScrolling: "touch",
|
||||
scrollSnapStop: "always",
|
||||
overscrollBehavior: "contain",
|
||||
}}
|
||||
>
|
||||
<Flex
|
||||
flexShrink={0}
|
||||
sx={{
|
||||
scrollSnapAlign: "start",
|
||||
scrollSnapStop: "always",
|
||||
width: [300, 60],
|
||||
}}
|
||||
>
|
||||
<SuspenseLoader
|
||||
condition={isAppLoaded}
|
||||
component={NavigationMenu}
|
||||
props={{
|
||||
toggleNavigationContainer: () => {},
|
||||
}}
|
||||
fallback={<NavigationMenuPlaceholder />}
|
||||
/>
|
||||
</Flex>
|
||||
<Flex
|
||||
className="listMenu"
|
||||
variant="columnFill"
|
||||
width={"100vw"}
|
||||
sx={{
|
||||
position: "relative",
|
||||
scrollSnapAlign: "start",
|
||||
scrollSnapStop: "always",
|
||||
}}
|
||||
flexShrink={0}
|
||||
>
|
||||
<SuspenseLoader
|
||||
condition={isAppLoaded}
|
||||
component={CachedRouter}
|
||||
fallback={
|
||||
<Loader
|
||||
title="Did you know?"
|
||||
text="All your notes are encrypted on your device."
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Box
|
||||
id="overlay"
|
||||
sx={{
|
||||
position: "absolute",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: 999,
|
||||
opacity: 0,
|
||||
visibility: "visible",
|
||||
pointerEvents: "none",
|
||||
}}
|
||||
bg="black"
|
||||
/>
|
||||
</Flex>
|
||||
<Flex
|
||||
width={"100vw"}
|
||||
flexShrink={0}
|
||||
sx={{
|
||||
scrollSnapAlign: "start",
|
||||
scrollSnapStop: "always",
|
||||
}}
|
||||
flexDirection="column"
|
||||
>
|
||||
<SuspenseLoader
|
||||
fallback={<EditorLoading />}
|
||||
component={HashRouter}
|
||||
condition={isAppLoaded}
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -227,6 +227,8 @@ function ListContainer(props) {
|
||||
testId={`${props.type}-action-button`}
|
||||
onClick={props.button.onClick}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
display: ["block", "block", "none"],
|
||||
alignSelf: "end",
|
||||
borderRadius: 100,
|
||||
|
||||
@@ -70,7 +70,7 @@ const NAVIGATION_MENU_WIDTH = "10em";
|
||||
const NAVIGATION_MENU_TABLET_WIDTH = "4em";
|
||||
|
||||
function NavigationMenu(props) {
|
||||
const { toggleNavigationContainer } = props;
|
||||
const { toggleNavigationContainer, isTablet } = props;
|
||||
const [location, previousLocation, state] = useLocation();
|
||||
const isFocusMode = useAppStore((store) => store.isFocusMode);
|
||||
const colors = useAppStore((store) => store.colors);
|
||||
@@ -104,7 +104,6 @@ function NavigationMenu(props) {
|
||||
id="navigationmenu"
|
||||
flexDirection="column"
|
||||
justifyContent="space-between"
|
||||
flex={1}
|
||||
initial={{
|
||||
opacity: 1,
|
||||
}}
|
||||
@@ -114,21 +113,10 @@ function NavigationMenu(props) {
|
||||
}}
|
||||
transition={{ duration: 0.3, ease: "easeOut" }}
|
||||
sx={{
|
||||
borderRight: "1px solid",
|
||||
borderRightColor: "border",
|
||||
minWidth: [
|
||||
NAVIGATION_MENU_WIDTH,
|
||||
isFocusMode ? 0 : NAVIGATION_MENU_TABLET_WIDTH,
|
||||
isFocusMode ? 0 : NAVIGATION_MENU_WIDTH,
|
||||
],
|
||||
maxWidth: [
|
||||
NAVIGATION_MENU_WIDTH,
|
||||
isFocusMode ? 0 : NAVIGATION_MENU_TABLET_WIDTH,
|
||||
isFocusMode ? 0 : NAVIGATION_MENU_WIDTH,
|
||||
],
|
||||
zIndex: 1,
|
||||
height: "auto",
|
||||
position: "relative",
|
||||
flex: 1,
|
||||
}}
|
||||
bg={"bgSecondary"}
|
||||
px={0}
|
||||
@@ -137,6 +125,7 @@ function NavigationMenu(props) {
|
||||
<Flex flexDirection="column">
|
||||
{routes.map((item) => (
|
||||
<NavigationItem
|
||||
isTablet={isTablet}
|
||||
key={item.path}
|
||||
title={item.title}
|
||||
icon={item.icon}
|
||||
@@ -155,6 +144,7 @@ function NavigationMenu(props) {
|
||||
))}
|
||||
{colors.map((color) => (
|
||||
<NavigationItem
|
||||
isTablet={isTablet}
|
||||
key={color.id}
|
||||
title={db.colors.alias(color.id)}
|
||||
icon={Circle}
|
||||
@@ -186,6 +176,7 @@ function NavigationMenu(props) {
|
||||
/>
|
||||
{pins.map((pin) => (
|
||||
<NavigationItem
|
||||
isTablet={isTablet}
|
||||
key={pin.id}
|
||||
title={pin.type === "tag" ? db.tags.alias(pin.id) : pin.title}
|
||||
menu={{
|
||||
@@ -224,21 +215,9 @@ function NavigationMenu(props) {
|
||||
</Flex>
|
||||
</FlexScrollContainer>
|
||||
<Flex flexDirection="column">
|
||||
{/* {theme === "light" ? (
|
||||
<NavigationItem
|
||||
title="Dark mode"
|
||||
icon={DarkMode}
|
||||
onClick={toggleNightMode}
|
||||
/>
|
||||
) : (
|
||||
<NavigationItem
|
||||
title="Light mode"
|
||||
icon={LightMode}
|
||||
onClick={toggleNightMode}
|
||||
/>
|
||||
)} */}
|
||||
{!isLoggedIn && (
|
||||
<NavigationItem
|
||||
isTablet={isTablet}
|
||||
title="Login"
|
||||
icon={Login}
|
||||
onClick={() => hardNavigate("/login")}
|
||||
@@ -246,6 +225,7 @@ function NavigationMenu(props) {
|
||||
)}
|
||||
|
||||
<NavigationItem
|
||||
isTablet={isTablet}
|
||||
key={settings.path}
|
||||
title={settings.title}
|
||||
icon={settings.icon}
|
||||
@@ -254,30 +234,32 @@ function NavigationMenu(props) {
|
||||
}}
|
||||
selected={location.startsWith(settings.path)}
|
||||
>
|
||||
<Button
|
||||
variant={"icon"}
|
||||
title="Toggle dark/light mode"
|
||||
sx={{
|
||||
position: "absolute",
|
||||
right: "2px",
|
||||
bg: "transparent",
|
||||
borderRadius: "default",
|
||||
":hover:not(disabled)": {
|
||||
bg: "background",
|
||||
},
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setFollowSystemTheme(false);
|
||||
toggleNightMode();
|
||||
}}
|
||||
>
|
||||
{theme === "dark" ? (
|
||||
<DarkMode size={16} />
|
||||
) : (
|
||||
<LightMode size={16} />
|
||||
)}
|
||||
</Button>
|
||||
{isTablet ? null : (
|
||||
<Button
|
||||
variant={"icon"}
|
||||
title="Toggle dark/light mode"
|
||||
sx={{
|
||||
position: "absolute",
|
||||
right: "2px",
|
||||
bg: "bgSecondary",
|
||||
borderRadius: "default",
|
||||
":hover:not(disabled)": {
|
||||
bg: "background",
|
||||
},
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setFollowSystemTheme(false);
|
||||
toggleNightMode();
|
||||
}}
|
||||
>
|
||||
{theme === "dark" ? (
|
||||
<DarkMode size={16} />
|
||||
) : (
|
||||
<LightMode size={16} />
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
</NavigationItem>
|
||||
</Flex>
|
||||
</AnimatedFlex>
|
||||
|
||||
@@ -1,60 +1,7 @@
|
||||
import { Flex } from "rebass";
|
||||
import { useStore as useThemeStore } from "../../stores/theme-store";
|
||||
import { Button, Text } from "rebass";
|
||||
import useTablet from "../../utils/use-tablet";
|
||||
import {
|
||||
Note,
|
||||
Notebook,
|
||||
StarOutline,
|
||||
Monographs,
|
||||
Tag,
|
||||
Trash,
|
||||
Settings,
|
||||
DarkMode,
|
||||
LightMode,
|
||||
Sync,
|
||||
Login,
|
||||
} from "../icons";
|
||||
import useLocation from "../../hooks/use-location";
|
||||
|
||||
const routes = [
|
||||
{ title: "Notes", path: "/", icon: Note },
|
||||
{
|
||||
title: "Notebooks",
|
||||
path: "/notebooks",
|
||||
icon: Notebook,
|
||||
},
|
||||
{
|
||||
title: "Favorites",
|
||||
path: "/favorites",
|
||||
icon: StarOutline,
|
||||
},
|
||||
{ title: "Tags", path: "/tags", icon: Tag },
|
||||
{
|
||||
title: "Monographs",
|
||||
path: "/monographs",
|
||||
icon: Monographs,
|
||||
},
|
||||
{ title: "Trash", path: "/trash", icon: Trash },
|
||||
];
|
||||
|
||||
const bottomRoutes = [
|
||||
{
|
||||
title: "Settings",
|
||||
path: "/settings",
|
||||
icon: Settings,
|
||||
},
|
||||
];
|
||||
|
||||
const NAVIGATION_MENU_WIDTH = "10em";
|
||||
const NAVIGATION_MENU_TABLET_WIDTH = "4em";
|
||||
import Loader from "../loader";
|
||||
|
||||
function NavigationMenu() {
|
||||
const isLoggedIn = false;
|
||||
const theme = useThemeStore((store) => store.theme);
|
||||
const toggleNightMode = useThemeStore((store) => store.toggleNightMode);
|
||||
const [location] = useLocation();
|
||||
|
||||
return (
|
||||
<Flex
|
||||
id="navigationmenu"
|
||||
@@ -64,127 +11,14 @@ function NavigationMenu() {
|
||||
sx={{
|
||||
borderRight: "1px solid",
|
||||
borderRightColor: "border",
|
||||
minWidth: [
|
||||
NAVIGATION_MENU_WIDTH,
|
||||
NAVIGATION_MENU_TABLET_WIDTH,
|
||||
NAVIGATION_MENU_WIDTH,
|
||||
],
|
||||
maxWidth: [
|
||||
NAVIGATION_MENU_WIDTH,
|
||||
NAVIGATION_MENU_TABLET_WIDTH,
|
||||
NAVIGATION_MENU_WIDTH,
|
||||
],
|
||||
zIndex: 1,
|
||||
height: "auto",
|
||||
position: "relative",
|
||||
}}
|
||||
bg={"bgSecondary"}
|
||||
px={0}
|
||||
>
|
||||
<Flex
|
||||
flexDirection="column"
|
||||
sx={{
|
||||
overflow: "scroll",
|
||||
scrollbarWidth: "none",
|
||||
"::-webkit-scrollbar": { width: 0, height: 0 },
|
||||
msOverflowStyle: "none",
|
||||
}}
|
||||
>
|
||||
{routes.map((item) => (
|
||||
<NavigationItem
|
||||
key={item.path}
|
||||
title={item.title}
|
||||
icon={item.icon}
|
||||
selected={
|
||||
item.path === "/"
|
||||
? location === item.path
|
||||
: location.startsWith(item.path)
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</Flex>
|
||||
<Flex flexDirection="column">
|
||||
{theme === "light" ? (
|
||||
<NavigationItem
|
||||
title="Dark mode"
|
||||
icon={DarkMode}
|
||||
onClick={toggleNightMode}
|
||||
/>
|
||||
) : (
|
||||
<NavigationItem
|
||||
title="Light mode"
|
||||
icon={LightMode}
|
||||
onClick={toggleNightMode}
|
||||
/>
|
||||
)}
|
||||
{isLoggedIn ? (
|
||||
<>
|
||||
<NavigationItem title="Sync" icon={Sync} />
|
||||
</>
|
||||
) : (
|
||||
<NavigationItem title="Login" icon={Login} />
|
||||
)}
|
||||
{bottomRoutes.map((item) => (
|
||||
<NavigationItem
|
||||
key={item.path}
|
||||
title={item.title}
|
||||
icon={item.icon}
|
||||
selected={location.startsWith(item.path)}
|
||||
/>
|
||||
))}
|
||||
</Flex>
|
||||
<Loader />
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
export default NavigationMenu;
|
||||
|
||||
function NavigationItem(props) {
|
||||
const { icon: Icon, color, title, isLoading } = props;
|
||||
const isTablet = useTablet();
|
||||
|
||||
return (
|
||||
<Button
|
||||
data-test-id={`navitem-${title.toLowerCase()}`}
|
||||
variant="icon"
|
||||
bg={props.selected ? "border" : "transparent"}
|
||||
p={2}
|
||||
mx={2}
|
||||
mt={[1, 2, 1]}
|
||||
sx={{
|
||||
borderRadius: "default",
|
||||
position: "relative",
|
||||
":first-of-type": { mt: 2 },
|
||||
":last-of-type": { mb: 2 },
|
||||
}}
|
||||
label={title}
|
||||
title={title}
|
||||
onClick={() => {
|
||||
props.onClick();
|
||||
}}
|
||||
display="flex"
|
||||
justifyContent={["flex-start", "center", "flex-start"]}
|
||||
alignItems="center"
|
||||
>
|
||||
<Icon
|
||||
size={isTablet ? 18 : 15}
|
||||
color={color || (props.selected ? "primary" : "icon")}
|
||||
rotate={isLoading}
|
||||
/>
|
||||
|
||||
<Text
|
||||
display={["block", "none", "block"]}
|
||||
variant="body"
|
||||
fontSize="subtitle"
|
||||
sx={{
|
||||
whiteSpace: "nowrap",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
fontWeight: props.selected ? "bold" : "normal",
|
||||
}}
|
||||
ml={1}
|
||||
>
|
||||
{title}
|
||||
</Text>
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ import { Button, Text } from "rebass";
|
||||
import { useStore as useAppStore } from "../../stores/app-store";
|
||||
import { useMenuTrigger } from "../../hooks/use-menu";
|
||||
import useMobile from "../../utils/use-mobile";
|
||||
import useTablet from "../../utils/use-tablet";
|
||||
import * as Icons from "../icons";
|
||||
|
||||
function NavigationItem(props) {
|
||||
@@ -14,11 +13,11 @@ function NavigationItem(props) {
|
||||
isShortcut,
|
||||
isNew,
|
||||
children,
|
||||
isTablet,
|
||||
} = props;
|
||||
const toggleSideMenu = useAppStore((store) => store.toggleSideMenu);
|
||||
const { openMenu } = useMenuTrigger();
|
||||
const isMobile = useMobile();
|
||||
const isTablet = useTablet();
|
||||
|
||||
return (
|
||||
<Button
|
||||
@@ -27,7 +26,7 @@ function NavigationItem(props) {
|
||||
px={2}
|
||||
py={"9px"}
|
||||
mx={1}
|
||||
mt={[1, 2, "3px"]}
|
||||
mt={isTablet ? 1 : "3px"}
|
||||
sx={{
|
||||
borderRadius: "default",
|
||||
position: "relative",
|
||||
@@ -50,7 +49,7 @@ function NavigationItem(props) {
|
||||
props.onClick();
|
||||
}}
|
||||
display="flex"
|
||||
justifyContent={["flex-start", "center", "flex-start"]}
|
||||
justifyContent={isTablet ? "center" : "flex-start"}
|
||||
alignItems="center"
|
||||
>
|
||||
<Icon
|
||||
@@ -74,7 +73,7 @@ function NavigationItem(props) {
|
||||
)}
|
||||
|
||||
<Text
|
||||
display={["block", "none", "block"]}
|
||||
display={isTablet ? "none" : "block"}
|
||||
variant="body"
|
||||
fontSize="subtitle"
|
||||
sx={{
|
||||
|
||||
@@ -43,8 +43,11 @@ export default function useSlider(sliderId, { onSliding, onChange }) {
|
||||
|
||||
const slideToIndex = useCallback(
|
||||
(index) => {
|
||||
console.log(index, slides, ref.current, slides[index].node);
|
||||
if (!ref.current || index >= slides.length) return;
|
||||
slides[index].node.scrollIntoView({ behavior: "smooth" });
|
||||
setTimeout(() => {
|
||||
slides[index].node.scrollIntoView();
|
||||
}, 100);
|
||||
},
|
||||
[ref, slides]
|
||||
);
|
||||
|
||||
@@ -220,7 +220,6 @@ class EditorStore extends BaseStore {
|
||||
const session = this.get().session;
|
||||
if (session.id) await db.fs.cancel(session.id);
|
||||
|
||||
appStore.setIsEditorOpen(false);
|
||||
this.set((state) => {
|
||||
state.session = {
|
||||
...getDefaultSession(),
|
||||
@@ -231,6 +230,7 @@ class EditorStore extends BaseStore {
|
||||
this.toggleProperties(false);
|
||||
if (shouldNavigate)
|
||||
hashNavigate(`/notes/create`, { replace: true, addNonce: true });
|
||||
appStore.setIsEditorOpen(false);
|
||||
};
|
||||
|
||||
setTitle = (sessionId, title) => {
|
||||
|
||||
Reference in New Issue
Block a user