web: optimize ui for mobile & tablet form factor

This commit is contained in:
Abdullah Atta
2024-07-04 22:50:02 +05:00
committed by Abdullah Atta
parent f7de4c9084
commit 5ef7e39e17
10 changed files with 148 additions and 70 deletions

View File

@@ -58,9 +58,8 @@ export default function MobileAppEffects({
overlay.style.pointerEvents = "none";
}
},
onChange: (e, { slide, lastSlide }) => {
if (!lastSlide || !isMobile) return;
toggleSideMenu(slide?.index === 1 ? true : false);
onChange: (e, { slide }) => {
toggleSideMenu(slide?.index === 0 ? true : false);
setIsEditorOpen(slide?.index === 3 ? true : false);
}
});

View File

@@ -125,19 +125,23 @@ function DesktopAppContents({ show, setShow }: DesktopAppContentsProps) {
const middlePane = useRef<ImperativePanelHandle>(null);
useEffect(() => {
if (show) middlePane.current?.expand();
else middlePane.current?.collapse();
}, [show]);
setIsNarrow(isTablet);
}, [isTablet]);
useEffect(() => {
if (isFocusMode) {
const middlePaneSize = middlePane.current?.getSize() || 20;
navPane.current?.collapse();
// the middle pane has to be resized because collapsing the nav
// pane increases the middle pane's size every time.
middlePane.current?.resize(middlePaneSize);
} else navPane.current?.expand();
}, [isFocusMode]);
// useEffect(() => {
// if (show) middlePane.current?.expand();
// else middlePane.current?.collapse();
// }, [show]);
// useEffect(() => {
// if (isFocusMode) {
// const middlePaneSize = middlePane.current?.getSize() || 20;
// navPane.current?.collapse();
// // the middle pane has to be resized because collapsing the nav
// // pane increases the middle pane's size every time.
// middlePane.current?.resize(middlePaneSize);
// } else navPane.current?.expand();
// }, [isFocusMode]);
return (
<>
@@ -148,45 +152,67 @@ function DesktopAppContents({ show, setShow }: DesktopAppContentsProps) {
}}
>
<PanelGroup autoSaveId="global-panel-group" direction="horizontal">
<Panel
ref={navPane}
className="nav-pane"
defaultSize={10}
minSize={3.5}
onResize={(size) => setIsNarrow(size <= 5)}
collapsible
collapsedSize={3.5}
>
<NavigationMenu
toggleNavigationContainer={(state) => {
setShow(state || !show);
}}
isTablet={isNarrow}
/>
</Panel>
<PanelResizeHandle className="panel-resize-handle" />
<Panel
ref={middlePane}
className="middle-pane"
collapsible
defaultSize={20}
>
<ScopedThemeProvider
className="listMenu"
scope="list"
sx={{
display: "flex",
flexDirection: "column",
flex: 1,
bg: "background",
borderRight: "1px solid var(--separator)"
}}
>
<CachedRouter />
</ScopedThemeProvider>
</Panel>
<PanelResizeHandle className="panel-resize-handle" />
<Panel className="editor-pane" defaultSize={70}>
{!isFocusMode && isTablet ? (
<Flex sx={{ width: 50 }}>
<NavigationMenu
toggleNavigationContainer={(state) => {
setShow(state || !show);
}}
isTablet={isNarrow}
/>
</Flex>
) : (
!isFocusMode && (
<>
<Panel
ref={navPane}
order={1}
className="nav-pane"
defaultSize={10}
minSize={3.5}
// maxSize={isNarrow ? 5 : undefined}
onResize={(size) => setIsNarrow(size <= 5)}
collapsible
collapsedSize={3.5}
>
<NavigationMenu
toggleNavigationContainer={(state) => {
setShow(state || !show);
}}
isTablet={isNarrow}
/>
</Panel>
<PanelResizeHandle className="panel-resize-handle" />
</>
)
)}
{!isFocusMode && show && (
<>
<Panel
ref={middlePane}
className="middle-pane"
order={2}
collapsible
defaultSize={20}
>
<ScopedThemeProvider
className="listMenu"
scope="list"
sx={{
display: "flex",
flexDirection: "column",
flex: 1,
bg: "background",
borderRight: "1px solid var(--separator)"
}}
>
<CachedRouter />
</ScopedThemeProvider>
</Panel>
<PanelResizeHandle className="panel-resize-handle" />
</>
)}
<Panel className="editor-pane" order={3} defaultSize={70}>
<Flex
sx={{
display: "flex",

View File

@@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { Button, Flex, Text } from "@theme-ui/components";
import { useState } from "react";
import {
ArrowLeft,
Cross,
EditorFullWidth,
EditorNormalWidth,
@@ -74,6 +75,7 @@ import { useStore as useUserStore } from "../../stores/user-store";
import { db } from "../../common/db";
import { showPublishView } from "../publish-view";
import { restrictToHorizontalAxis } from "@dnd-kit/modifiers";
import useMobile from "../../hooks/use-mobile";
export function EditorActionBar() {
const editorMargins = useEditorStore((store) => store.editorMargins);
@@ -89,6 +91,8 @@ export function EditorActionBar() {
const monographs = useMonographStore((store) => store.monographs);
const isNotePublished =
activeSession && db.monographs.isPublished(activeSession.id);
const isMobile = useMobile();
const setIsEditorOpen = useAppStore((store) => store.setIsEditorOpen);
const tools = [
{
@@ -107,6 +111,7 @@ export function EditorActionBar() {
title: isNotePublished ? "Published" : "Publish",
icon: isNotePublished ? Published : Publish,
hidden: !isLoggedIn,
hideOnMobile: true,
enabled:
activeSession &&
(activeSession.type === "default" || activeSession.type === "readonly"),
@@ -120,6 +125,7 @@ export function EditorActionBar() {
title: editorMargins ? "Disable editor margins" : "Enable editor margins",
icon: editorMargins ? EditorNormalWidth : EditorFullWidth,
enabled: true,
hideOnMobile: true,
onClick: () => useEditorStore.getState().toggleEditorMargins()
},
{
@@ -187,7 +193,24 @@ export function EditorActionBar() {
return (
<>
<TabStrip />
{isMobile ? (
<Flex sx={{ flex: 1 }}>
<Button
variant={"secondary"}
sx={{
height: "100%",
bg: "transparent",
borderRadius: 0,
flexShrink: 0
}}
onClick={() => setIsEditorOpen(false)}
>
<ArrowLeft size={18} />
</Button>
</Flex>
) : (
<TabStrip />
)}
{tools.map((tool) => (
<Button
data-test-id={tool.title}

View File

@@ -630,8 +630,8 @@ function EditorChrome(props: PropsWithChildren<EditorProps>) {
maxWidth: editorMargins ? "min(100%, 850px)" : "auto",
width: "100%"
}}
pl={6}
pr={6}
pl={[2, 2, 6]}
pr={[2, 2, 6]}
onClick={onRequestFocus}
>
{children}

View File

@@ -59,6 +59,8 @@ import { writeToClipboard } from "../../utils/clipboard";
import { useEditorStore } from "../../stores/editor-store";
import { parseInternalLink } from "@notesnook/core";
import Skeleton from "react-loading-skeleton";
import useMobile from "../../hooks/use-mobile";
import useTablet from "../../hooks/use-tablet";
export type OnChangeHandler = (
content: () => string,
@@ -89,6 +91,7 @@ type TipTapProps = {
readonly?: boolean;
nonce?: number;
isMobile?: boolean;
isTablet?: boolean;
downloadOptions?: DownloadOptions;
fontSize: number;
fontFamily: string;
@@ -127,6 +130,7 @@ function TipTap(props: TipTapProps) {
readonly,
nonce,
isMobile,
isTablet,
downloadOptions,
fontSize,
fontFamily
@@ -361,7 +365,12 @@ function TipTap(props: TipTapProps) {
>
<Toolbar
editor={editor}
location={isMobile ? "bottom" : "top"}
location={"top"}
sx={
isTablet || isMobile
? { overflowX: "scroll", flexWrap: "nowrap" }
: {}
}
tools={toolbarConfig}
defaultFontFamily={fontFamily}
defaultFontSize={fontSize}
@@ -385,6 +394,8 @@ function TiptapWrapper(
const containerRef = useRef<HTMLDivElement>(null);
const editorContainerRef = useRef<HTMLDivElement>();
const { editorConfig } = useEditorConfig();
const isMobile = useMobile();
const isTablet = useTablet();
useLayoutEffect(() => {
if (
@@ -425,6 +436,8 @@ function TiptapWrapper(
>
<TipTap
{...props}
isMobile={isMobile}
isTablet={isTablet}
onLoad={(editor) => {
if (!isHydrating) {
onLoad?.(editor);

View File

@@ -256,7 +256,7 @@ function ListContainer(props: ListContainerProps) {
height: 45
}}
>
<Plus color="static" />
<Plus color="accentForeground" />
</Button>
)}
</Flex>

View File

@@ -40,8 +40,8 @@ function Notice() {
cursor: "pointer",
borderRadius: "default",
":hover": { bg: "hover" },
alignItems: "center",
minWidth: 250
alignItems: "center"
// minWidth: 250
}}
p={1}
onClick={() => NoticeData.action()}
@@ -53,11 +53,30 @@ function Notice() {
color="accent"
sx={{ bg: "shade", mr: 2, p: 2, borderRadius: 80 }}
/>
<Flex variant="columnCenter" sx={{ alignItems: "flex-start" }}>
<Text variant="body" sx={{ fontSize: "body" }}>
<Flex
variant="columnCenter"
sx={{ alignItems: "flex-start", overflow: "hidden" }}
>
<Text
variant="body"
sx={{
fontSize: "body",
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis"
}}
>
{NoticeData.title}
</Text>
<Text variant="subBody" sx={{ display: "block" }}>
<Text
variant="subBody"
sx={{
display: "block",
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis"
}}
>
{NoticeData.subtitle}
</Text>
</Flex>

View File

@@ -91,7 +91,6 @@ export default function useSlider(
const slideToIndex = useCallback(
(index: number) => {
if (!slides || !ref.current || index >= slides.length) return;
console.log(slides[index].offset, slides[index].width);
const slider = ref.current;
setTimeout(() => {
slider.scrollTo({

View File

@@ -198,10 +198,9 @@ class AppStore extends BaseStore<AppStore> {
};
toggleSideMenu = (toggleState: boolean) => {
console.log("toggling side menu");
this.set(
(state) =>
(state.isSideMenuOpen =
toggleState != null ? toggleState : !state.isSideMenuOpen)
(state) => (state.isSideMenuOpen = toggleState ?? !state.isSideMenuOpen)
);
};

View File

@@ -92,11 +92,11 @@ export function Toolbar(props: ToolbarProps) {
<Flex
className={["editor-toolbar", className].join(" ")}
sx={{
...sx,
flexWrap: isMobile ? "nowrap" : "wrap",
overflowX: isMobile ? "auto" : "hidden",
bg: "background",
borderRadius: isMobile ? "0px" : "default"
borderRadius: isMobile ? "0px" : "default",
...sx
}}
{...flexProps}
>