This commit is contained in:
Philipinho
2026-02-01 02:16:53 +00:00
parent 20a7acfccc
commit 4d322e9157
4 changed files with 57 additions and 51 deletions
@@ -3,3 +3,7 @@ import { atom } from "jotai";
export const historyAtoms = atom<boolean>(false); export const historyAtoms = atom<boolean>(false);
export const activeHistoryIdAtom = atom<string>(""); export const activeHistoryIdAtom = atom<string>("");
export const activeHistoryPrevIdAtom = atom<string>(""); export const activeHistoryPrevIdAtom = atom<string>("");
export const highlightChangesAtom = atom<boolean>(true);
export type DiffCounts = { added: number; deleted: number; total: number };
export const diffCountsAtom = atom<DiffCounts | null>(null);
@@ -9,24 +9,26 @@ import historyClasses from "./history.module.css";
import { recreateTransform } from "@docmost/editor-ext"; import { recreateTransform } from "@docmost/editor-ext";
import { DOMSerializer, Node } from "@tiptap/pm/model"; import { DOMSerializer, Node } from "@tiptap/pm/model";
import { ChangeSet, simplifyChanges } from "prosemirror-changeset"; import { ChangeSet, simplifyChanges } from "prosemirror-changeset";
import { useAtom } from "jotai";
export type DiffCounts = { added: number; deleted: number; total: number }; import {
diffCountsAtom,
highlightChangesAtom,
} from "@/features/page-history/atoms/history-atoms";
export interface HistoryEditorProps { export interface HistoryEditorProps {
title: string; title: string;
content: any; content: any;
previousContent?: any; previousContent?: any;
highlightChanges?: boolean;
onDiffCalculated?: (counts: DiffCounts) => void;
} }
export function HistoryEditor({ export function HistoryEditor({
title, title,
content, content,
previousContent, previousContent,
highlightChanges = true,
onDiffCalculated,
}: HistoryEditorProps) { }: HistoryEditorProps) {
const [highlightChanges] = useAtom(highlightChangesAtom);
const [, setDiffCounts] = useAtom(diffCountsAtom);
const editor = useEditor({ const editor = useEditor({
extensions: mainExtensions, extensions: mainExtensions,
editable: false, editable: false,
@@ -169,7 +171,8 @@ export function HistoryEditor({
} }
const total = addedCount + deletedCount; const total = addedCount + deletedCount;
onDiffCalculated?.({ added: addedCount, deleted: deletedCount, total }); // @ts-ignore
setDiffCounts({ added: addedCount, deleted: deletedCount, total });
editor.setOptions({ editor.setOptions({
editorProps: { editorProps: {
@@ -178,7 +181,14 @@ export function HistoryEditor({
highlightChanges ? decorationSet : DecorationSet.empty, highlightChanges ? decorationSet : DecorationSet.empty,
}, },
}); });
}, [title, content, editor, previousContent, highlightChanges]); }, [
title,
content,
editor,
previousContent,
highlightChanges,
setDiffCounts,
]);
return ( return (
<div> <div>
@@ -7,13 +7,14 @@ import {
Switch, Switch,
Text, Text,
} from "@mantine/core"; } from "@mantine/core";
import { DiffCounts } from "@/features/page-history/components/history-editor";
import HistoryList from "@/features/page-history/components/history-list"; import HistoryList from "@/features/page-history/components/history-list";
import classes from "./history.module.css"; import classes from "./history.module.css";
import { useAtom } from "jotai"; import { useAtom, useSetAtom } from "jotai";
import { import {
activeHistoryIdAtom, activeHistoryIdAtom,
activeHistoryPrevIdAtom, activeHistoryPrevIdAtom,
diffCountsAtom,
highlightChangesAtom,
} from "@/features/page-history/atoms/history-atoms"; } from "@/features/page-history/atoms/history-atoms";
import HistoryView from "@/features/page-history/components/history-view"; import HistoryView from "@/features/page-history/components/history-view";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
@@ -28,14 +29,17 @@ export default function HistoryModalBody({ pageId }: Props) {
const [activeHistoryPrevId, setActiveHistoryPrevId] = useAtom( const [activeHistoryPrevId, setActiveHistoryPrevId] = useAtom(
activeHistoryPrevIdAtom, activeHistoryPrevIdAtom,
); );
const [highlightChanges, setHighlightChanges] = useState(true); const [highlightChanges, setHighlightChanges] = useAtom(highlightChangesAtom);
const [diffCounts, setDiffCounts] = useState<DiffCounts | null>(null); const [diffCounts] = useAtom(diffCountsAtom);
const setDiffCounts = useSetAtom(diffCountsAtom);
const [currentChangeIndex, setCurrentChangeIndex] = useState(0); const [currentChangeIndex, setCurrentChangeIndex] = useState(0);
const scrollViewportRef = useRef<HTMLDivElement>(null); const scrollViewportRef = useRef<HTMLDivElement>(null);
useEffect(() => { useEffect(() => {
setActiveHistoryId(""); setActiveHistoryId("");
setActiveHistoryPrevId(""); setActiveHistoryPrevId("");
setDiffCounts(null);
}, [pageId]); }, [pageId]);
useEffect(() => { useEffect(() => {
@@ -49,7 +53,8 @@ export default function HistoryModalBody({ pageId }: Props) {
if (element instanceof HTMLElement) { if (element instanceof HTMLElement) {
const elementTop = element.offsetTop; const elementTop = element.offsetTop;
const viewportHeight = viewport.clientHeight; const viewportHeight = viewport.clientHeight;
const scrollTarget = elementTop - viewportHeight / 2 + element.offsetHeight / 2; const scrollTarget =
elementTop - viewportHeight / 2 + element.offsetHeight / 2;
viewport.scrollTo({ top: scrollTarget, behavior: "smooth" }); viewport.scrollTo({ top: scrollTarget, behavior: "smooth" });
} }
}; };
@@ -79,16 +84,14 @@ export default function HistoryModalBody({ pageId }: Props) {
</nav> </nav>
<div style={{ position: "relative", flex: 1 }}> <div style={{ position: "relative", flex: 1 }}>
<ScrollArea h={650} w="100%" scrollbarSize={5} viewportRef={scrollViewportRef}> <ScrollArea
h={650}
w="100%"
scrollbarSize={5}
viewportRef={scrollViewportRef}
>
<div className={classes.sidebarRightSection}> <div className={classes.sidebarRightSection}>
{activeHistoryId && ( {activeHistoryId && <HistoryView />}
<HistoryView
historyId={activeHistoryId}
prevHistoryId={activeHistoryPrevId}
highlightChanges={highlightChanges}
onDiffCalculated={setDiffCounts}
/>
)}
</div> </div>
</ScrollArea> </ScrollArea>
@@ -1,24 +1,17 @@
import { usePageHistoryQuery } from "@/features/page-history/queries/page-history-query"; import { usePageHistoryQuery } from "@/features/page-history/queries/page-history-query";
import { import { HistoryEditor } from "@/features/page-history/components/history-editor";
DiffCounts,
HistoryEditor,
} from "@/features/page-history/components/history-editor";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useAtomValue } from "jotai";
import {
activeHistoryIdAtom,
activeHistoryPrevIdAtom,
} from "@/features/page-history/atoms/history-atoms";
interface HistoryProps { function HistoryView() {
historyId: string;
prevHistoryId?: string;
highlightChanges?: boolean;
onDiffCalculated?: (counts: DiffCounts) => void;
}
function HistoryView({
historyId,
prevHistoryId,
highlightChanges,
onDiffCalculated,
}: HistoryProps) {
const { t } = useTranslation(); const { t } = useTranslation();
const historyId = useAtomValue(activeHistoryIdAtom);
const prevHistoryId = useAtomValue(activeHistoryPrevIdAtom);
const { const {
data, data,
isLoading: isLoadingCurrent, isLoading: isLoadingCurrent,
@@ -28,7 +21,7 @@ function HistoryView({
data: prevData, data: prevData,
isLoading: isLoadingPrev, isLoading: isLoadingPrev,
isError: isErrorPrev, isError: isErrorPrev,
} = usePageHistoryQuery(prevHistoryId ?? ""); } = usePageHistoryQuery(prevHistoryId);
if (isLoadingCurrent || isLoadingPrev) { if (isLoadingCurrent || isLoadingPrev) {
return <></>; return <></>;
@@ -39,17 +32,13 @@ function HistoryView({
} }
return ( return (
data && ( <div>
<div> <HistoryEditor
<HistoryEditor content={data.content}
content={data.content} title={data.title}
title={data.title} previousContent={!isErrorPrev ? prevData?.content : undefined}
previousContent={!isErrorPrev ? prevData?.content : undefined} />
highlightChanges={highlightChanges} </div>
onDiffCalculated={onDiffCalculated}
/>
</div>
)
); );
} }