mirror of
https://github.com/docmost/docmost.git
synced 2026-09-11 07:56:54 +08:00
improve slides display
This commit is contained in:
@@ -25,11 +25,14 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
padding: 6vh 5vw 10vh;
|
padding: 6vh 5vw 10vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scrollable {
|
.scrollable {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
align-items: flex-start;
|
||||||
|
zoom: 0.85;
|
||||||
}
|
}
|
||||||
|
|
||||||
.measurementArea {
|
.measurementArea {
|
||||||
|
|||||||
@@ -3,11 +3,12 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|||||||
import { ActionIcon, Box, Modal, Text, Title, Tooltip } from "@mantine/core";
|
import { ActionIcon, Box, Modal, Text, Title, Tooltip } from "@mantine/core";
|
||||||
import { IconChevronLeft, IconChevronRight, IconX } from "@tabler/icons-react";
|
import { IconChevronLeft, IconChevronRight, IconX } from "@tabler/icons-react";
|
||||||
import { useHotkeys } from "@mantine/hooks";
|
import { useHotkeys } from "@mantine/hooks";
|
||||||
import { EditorProvider, isNodeEmpty, type JSONContent } from "@tiptap/react";
|
import { EditorProvider, type JSONContent } from "@tiptap/react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { mainExtensions } from "@/features/editor/extensions/extensions";
|
import { mainExtensions } from "@/features/editor/extensions/extensions";
|
||||||
import { TransclusionLookupProvider } from "@/features/editor/components/transclusion/transclusion-lookup-context";
|
import { TransclusionLookupProvider } from "@/features/editor/components/transclusion/transclusion-lookup-context";
|
||||||
import classes from "./presentation-modal.module.css";
|
import classes from "./presentation-modal.module.css";
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
|
||||||
type PresentationSlide =
|
type PresentationSlide =
|
||||||
| { kind: "title" }
|
| { kind: "title" }
|
||||||
@@ -18,8 +19,6 @@ type MeasuredContentSlide = {
|
|||||||
scrollable: boolean;
|
scrollable: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type MeasuredNode = { node: JSONContent; rect: DOMRect };
|
|
||||||
|
|
||||||
interface PresentationModalProps {
|
interface PresentationModalProps {
|
||||||
title: string;
|
title: string;
|
||||||
content: JSONContent;
|
content: JSONContent;
|
||||||
@@ -41,6 +40,9 @@ const isDivider = (node: JSONContent) => node.type === "horizontalRule";
|
|||||||
const isSectionHeading = (node: JSONContent) =>
|
const isSectionHeading = (node: JSONContent) =>
|
||||||
node.type === "heading" && node.attrs?.level === 1;
|
node.type === "heading" && node.attrs?.level === 1;
|
||||||
|
|
||||||
|
const isEndOfSection = (node: JSONContent) =>
|
||||||
|
node.type === "base" || node.type === "table";
|
||||||
|
|
||||||
function getAvailableHeight(area: HTMLElement): number {
|
function getAvailableHeight(area: HTMLElement): number {
|
||||||
const styles = window.getComputedStyle(area);
|
const styles = window.getComputedStyle(area);
|
||||||
return (
|
return (
|
||||||
@@ -57,10 +59,11 @@ export default function PresentationModal({
|
|||||||
onClose,
|
onClose,
|
||||||
}: PresentationModalProps) {
|
}: PresentationModalProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const { pageSlug } = useParams();
|
||||||
const [slideIndex, setSlideIndex] = useState(0);
|
const [slideIndex, setSlideIndex] = useState(0);
|
||||||
const [contentSlides, setContentSlides] = useState<MeasuredContentSlide[] | null>(
|
const [contentSlides, setContentSlides] = useState<
|
||||||
null
|
MeasuredContentSlide[] | null
|
||||||
);
|
>(null);
|
||||||
const slideAreaRef = useRef<HTMLDivElement>(null);
|
const slideAreaRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const extensions = useMemo(
|
const extensions = useMemo(
|
||||||
@@ -68,6 +71,12 @@ export default function PresentationModal({
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (opened) {
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
}, [pageSlug]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (opened) {
|
if (opened) {
|
||||||
setSlideIndex(0);
|
setSlideIndex(0);
|
||||||
@@ -122,7 +131,9 @@ export default function PresentationModal({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderedNodes = Array.from(editor.view.dom.children) as HTMLElement[];
|
const renderedNodes = Array.from(
|
||||||
|
editor.view.dom.children
|
||||||
|
) as HTMLElement[];
|
||||||
if (!renderedNodes.length) {
|
if (!renderedNodes.length) {
|
||||||
setContentSlides([]);
|
setContentSlides([]);
|
||||||
return;
|
return;
|
||||||
@@ -170,6 +181,10 @@ export default function PresentationModal({
|
|||||||
|
|
||||||
currentSlide.push(node);
|
currentSlide.push(node);
|
||||||
currentSlideBottom = rect.bottom;
|
currentSlideBottom = rect.bottom;
|
||||||
|
|
||||||
|
if (isEndOfSection(node)) {
|
||||||
|
saveCurrentSlide();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
saveCurrentSlide();
|
saveCurrentSlide();
|
||||||
@@ -211,6 +226,7 @@ export default function PresentationModal({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const currentSlide = slides[slideIndex];
|
const currentSlide = slides[slideIndex];
|
||||||
|
const scrollable = currentSlide.kind === "content" && currentSlide.scrollable;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal.Root
|
<Modal.Root
|
||||||
@@ -237,10 +253,9 @@ export default function PresentationModal({
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
|
onClick={goToNext}
|
||||||
className={`${classes.slideArea} ${
|
className={`${classes.slideArea} ${
|
||||||
currentSlide?.kind === "content" && currentSlide.scrollable
|
scrollable ? classes.scrollable : ""
|
||||||
? classes.scrollable
|
|
||||||
: ""
|
|
||||||
}`}
|
}`}
|
||||||
ref={slideAreaRef}
|
ref={slideAreaRef}
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user