mirror of
https://github.com/docmost/docmost.git
synced 2026-05-08 23:33:09 +08:00
nodes
This commit is contained in:
@@ -32,3 +32,19 @@
|
||||
border-radius: rem(2px);
|
||||
padding: 0 rem(2px);
|
||||
}
|
||||
|
||||
:global(.history-diff-node-added) {
|
||||
outline: rem(2px) solid light-dark(var(--mantine-color-green-5), var(--mantine-color-green-7));
|
||||
outline-offset: rem(2px);
|
||||
border-radius: rem(4px);
|
||||
}
|
||||
|
||||
:global(.history-diff-node-deleted) {
|
||||
display: inline-block;
|
||||
background: light-dark(var(--mantine-color-red-0), rgba(255, 0, 0, 0.1));
|
||||
border: rem(1px) dashed light-dark(var(--mantine-color-red-4), var(--mantine-color-red-6));
|
||||
border-radius: rem(4px);
|
||||
padding: rem(4px) rem(8px);
|
||||
color: light-dark(var(--mantine-color-red-7), var(--mantine-color-red-4));
|
||||
font-size: rem(12px);
|
||||
}
|
||||
|
||||
@@ -64,27 +64,82 @@ export function HistoryEditor({
|
||||
|
||||
editor.commands.setContent(content);
|
||||
|
||||
const specialNodeTypes = new Set([
|
||||
"image",
|
||||
"attachment",
|
||||
"video",
|
||||
"excalidraw",
|
||||
"drawio",
|
||||
"mermaid",
|
||||
"mathBlock",
|
||||
"mathInline",
|
||||
"table",
|
||||
"details",
|
||||
"callout",
|
||||
]);
|
||||
|
||||
const decorations: Decoration[] = [];
|
||||
for (const change of changes) {
|
||||
if (change.toB > change.fromB) {
|
||||
decorations.push(
|
||||
Decoration.inline(change.fromB, change.toB, {
|
||||
class: "history-diff-added",
|
||||
}),
|
||||
);
|
||||
let foundSpecialNode: { node: Node; pos: number } | null = null;
|
||||
docNew.nodesBetween(change.fromB, change.toB, (node, pos) => {
|
||||
if (specialNodeTypes.has(node.type.name)) {
|
||||
foundSpecialNode = { node, pos };
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if (foundSpecialNode) {
|
||||
const nodeEnd =
|
||||
foundSpecialNode.pos + foundSpecialNode.node.nodeSize;
|
||||
decorations.push(
|
||||
Decoration.node(foundSpecialNode.pos, nodeEnd, {
|
||||
class: "history-diff-node-added",
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
decorations.push(
|
||||
Decoration.inline(change.fromB, change.toB, {
|
||||
class: "history-diff-added",
|
||||
}),
|
||||
);
|
||||
}
|
||||
addedCount += 1;
|
||||
}
|
||||
if (change.toA > change.fromA) {
|
||||
const deletedText = docOld.textBetween(change.fromA, change.toA, "");
|
||||
if (deletedText) {
|
||||
let foundDeletedNode: { node: Node; pos: number } | null = null;
|
||||
docOld.nodesBetween(change.fromA, change.toA, (node, pos) => {
|
||||
if (specialNodeTypes.has(node.type.name)) {
|
||||
foundDeletedNode = { node, pos };
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if (foundDeletedNode) {
|
||||
decorations.push(
|
||||
Decoration.widget(change.fromB, () => {
|
||||
const span = document.createElement("span");
|
||||
span.className = "history-diff-deleted";
|
||||
span.textContent = deletedText;
|
||||
span.className = "history-diff-node-deleted";
|
||||
span.textContent = `[${foundDeletedNode!.node.type.name} removed]`;
|
||||
return span;
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
const deletedText = docOld.textBetween(
|
||||
change.fromA,
|
||||
change.toA,
|
||||
"",
|
||||
);
|
||||
if (deletedText) {
|
||||
decorations.push(
|
||||
Decoration.widget(change.fromB, () => {
|
||||
const span = document.createElement("span");
|
||||
span.className = "history-diff-deleted";
|
||||
span.textContent = deletedText;
|
||||
return span;
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
deletedCount += 1;
|
||||
}
|
||||
@@ -104,7 +159,8 @@ export function HistoryEditor({
|
||||
editor.setOptions({
|
||||
editorProps: {
|
||||
...editor.options.editorProps,
|
||||
decorations: () => (highlightChanges ? decorationSet : DecorationSet.empty),
|
||||
decorations: () =>
|
||||
highlightChanges ? decorationSet : DecorationSet.empty,
|
||||
},
|
||||
});
|
||||
}, [title, content, editor, previousContent, highlightChanges]);
|
||||
|
||||
@@ -3,6 +3,7 @@ import { OnEvent } from '@nestjs/event-emitter';
|
||||
import { PageHistoryRepo } from '@docmost/db/repos/page/page-history.repo';
|
||||
import { Page } from '@docmost/db/types/entity.types';
|
||||
import { isDeepStrictEqual } from 'node:util';
|
||||
import { EnvironmentService } from '../../integrations/environment/environment.service';
|
||||
|
||||
export class UpdatedPageEvent {
|
||||
page: Page;
|
||||
@@ -12,7 +13,10 @@ export class UpdatedPageEvent {
|
||||
export class HistoryListener {
|
||||
private readonly logger = new Logger(HistoryListener.name);
|
||||
|
||||
constructor(private readonly pageHistoryRepo: PageHistoryRepo) {}
|
||||
constructor(
|
||||
private readonly pageHistoryRepo: PageHistoryRepo,
|
||||
private readonly environmentService: EnvironmentService,
|
||||
) {}
|
||||
|
||||
@OnEvent('collab.page.updated')
|
||||
async handleCreatePageHistory(event: UpdatedPageEvent) {
|
||||
@@ -20,7 +24,9 @@ export class HistoryListener {
|
||||
|
||||
const pageCreationTime = new Date(page.createdAt).getTime();
|
||||
const currentTime = Date.now();
|
||||
const FIVE_MINUTES = 5 * 60 * 1000;
|
||||
const FIVE_MINUTES = this.environmentService.isDevelopment()
|
||||
? 30 * 1000
|
||||
: 5 * 60 * 1000;
|
||||
|
||||
if (currentTime - pageCreationTime < FIVE_MINUTES) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user