diff --git a/app/components/Button.tsx b/app/components/Button.tsx index 172a0a4a98..4d7b641c79 100644 --- a/app/components/Button.tsx +++ b/app/components/Button.tsx @@ -9,7 +9,7 @@ import ActionButton, { } from "~/components/ActionButton"; import { undraggableOnDesktop } from "~/styles"; -type RealProps = { +export type RealProps = { $fullwidth?: boolean; $borderOnHover?: boolean; $neutral?: boolean; diff --git a/app/models/Collection.ts b/app/models/Collection.ts index b674e5ddea..fea787d1d7 100644 --- a/app/models/Collection.ts +++ b/app/models/Collection.ts @@ -239,6 +239,25 @@ export default class Collection extends ParanoidModel { } }; + get flatDocuments(): Document[] { + if (!this?.sortedDocuments) { + return []; + } + + const flatten = (docs: Document[]): Document[] => { + const result: Document[] = []; + for (const doc of docs) { + result.push(doc); + if (doc.children && doc.children.length > 0) { + result.push(...flatten(doc.children as Document[])); + } + } + return result; + }; + + return flatten(this.sortedDocuments as Document[]); + } + /** * Updates the document identified by the given id in the collection in memory. * Does not update the document in the database. diff --git a/app/scenes/Document/components/Editor.tsx b/app/scenes/Document/components/Editor.tsx index 31507c9f1f..01963ea71f 100644 --- a/app/scenes/Document/components/Editor.tsx +++ b/app/scenes/Document/components/Editor.tsx @@ -34,6 +34,7 @@ import DocumentMeta from "./DocumentMeta"; import DocumentTitle from "./DocumentTitle"; import first from "lodash/first"; import { getLangFor } from "~/utils/language"; +import NavigationButtons from "./NavigationButtons"; const extensions = withUIExtensions(withComments(richExtensions)); @@ -255,6 +256,9 @@ function DocumentEditor(props: Props, ref: React.RefObject) { {...rest} />
{children}
+ {document.collection?.displayPreferences?.showFooterNavigation && ( + + )} ); } diff --git a/app/scenes/Document/components/NavigationButtons.tsx b/app/scenes/Document/components/NavigationButtons.tsx index 5594635475..a55f3c2e57 100644 --- a/app/scenes/Document/components/NavigationButtons.tsx +++ b/app/scenes/Document/components/NavigationButtons.tsx @@ -3,49 +3,48 @@ import React, { useMemo } from "react"; import { useHistory } from "react-router-dom"; import styled from "styled-components"; import { css } from "styled-components"; -import { RealButton } from "~/components/Button"; +import { RealButton, RealProps } from "~/components/Button"; import useStores from "~/hooks/useStores"; import Document from "~/models/Document"; +import breakpoint from "styled-components-breakpoint"; import { faChevronLeft, faChevronRight, } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { observer } from "mobx-react"; -const NavigationButtons = () => { - const { collections, documents, ui } = useStores(); - const activeCollection = collections.active; - const activeDocument = documents.active; +const NavigationButtons = ({ document }: { document: Document }) => { + const { ui } = useStores(); const history = useHistory(); const docs = useMemo(() => { + const { collection } = document; let navDocs: Record = { prevDoc: null, nextDoc: null, }; - const currentIndex = collections.flatDocuments.findIndex( - (doc) => doc.id === activeDocument?.id - ); + if (collection && collection.flatDocuments) { + const currentIndex = collection.flatDocuments.findIndex( + (doc) => doc.id === document?.id + ); - if ( - currentIndex !== undefined && - currentIndex !== -1 && - activeCollection?.documents - ) { - const nextIdx = currentIndex + 1; - if (nextIdx < collections.flatDocuments.length) { - navDocs.nextDoc = collections.flatDocuments[nextIdx]; - } + if (currentIndex !== undefined && currentIndex !== -1) { + const nextIdx = currentIndex + 1; + if (nextIdx < collection.flatDocuments.length) { + navDocs.nextDoc = collection.flatDocuments[nextIdx]; + } - const prevIdx = currentIndex - 1; - if (prevIdx > -1) { - navDocs.prevDoc = collections.flatDocuments[prevIdx]; + const prevIdx = currentIndex - 1; + if (prevIdx > -1) { + navDocs.prevDoc = collection.flatDocuments[prevIdx]; + } } } return navDocs; - }, [activeDocument]); + }, [document.collection?.sortedDocuments, document.collection]); const handleNavigate = (doc: Document | null) => { if (doc) { @@ -53,10 +52,6 @@ const NavigationButtons = () => { } }; - if (!docs.prevDoc && !docs.nextDoc) { - return null; - } - return ( ` - position: fixed; - bottom: 12px; - margin-left: 20px; + position: sticky; + margin-bottom: 100px; + width: 100%; display: flex; - flex-direction: row; - gap: 20px; - left: 50%; - transform: translateX(-50%); + flex-direction: column; + gap: 10px; - ${(props) => css` - width: ${props.fullwidth ? "35%" : "45%"}; + ${breakpoint("tablet")` + margin: 20px 0; `} - ${(props) => - props.sidebarOpen && - css` - @media (max-width: 1100px) { - left: 55%; - } - - @media (max-width: 900px) { - left: 65%; - } - `} - - @media (max-width: 900px) { - flex-direction: column; - width: 60%; - margin-left: 0; - gap: 10px; - } - - @media (max-width: 735px) { - width: 90%; - left: 50%; - } + ${breakpoint("desktop")` + flex-direction: row; + `} `; const NavButton = styled(RealButton)` @@ -148,22 +121,19 @@ const NavButton = styled(RealButton)` color: ${s("text")}; border-radius: 2px; line-height: 18px; - width: 60%; background: none; - shadow: 0 0 0 0 black; + width: 100%; &:hover { opacity: 1; background: none; } - ${(props) => css` - width: ${props.$fullwidth ? "100%" : "50%"}; + ${breakpoint("desktop")` + ${(props: RealProps) => css` + width: ${props.$fullwidth ? "100%" : "50%"}; + `} `} - - @media (max-width: 900px) { - width: 100%; - } `; const ButtonContent = styled.div` @@ -184,4 +154,4 @@ const ButtonText = styled.div` font-weight: bold; `; -export default NavigationButtons; +export default observer(NavigationButtons); diff --git a/app/scenes/Document/index.tsx b/app/scenes/Document/index.tsx index 90641ce77e..7e1287878d 100644 --- a/app/scenes/Document/index.tsx +++ b/app/scenes/Document/index.tsx @@ -7,7 +7,6 @@ import useStores from "~/hooks/useStores"; import DataLoader from "./components/DataLoader"; import Document from "./components/Document"; import { Footer } from "./components/Footer"; -import NavigationButtons from "./components/NavigationButtons"; type Params = { documentSlug: string; @@ -69,8 +68,6 @@ export default function DocumentScene(props: Props) { > {(rest) => ( - {rest.document.collection?.displayPreferences - ?.showFooterNavigation && }