Prevent duplicate ids in editor

This commit is contained in:
Hakan Shehu
2024-12-07 20:34:54 +01:00
parent c93edcf7b4
commit c8a0ac69e2
4 changed files with 21 additions and 44 deletions

View File

@@ -81,7 +81,7 @@ const createWindow = async () => {
if (MAIN_WINDOW_VITE_DEV_SERVER_URL) {
mainWindow.loadURL(MAIN_WINDOW_VITE_DEV_SERVER_URL);
// Open the DevTools.
mainWindow.webContents.openDevTools();
// mainWindow.webContents.openDevTools();
} else {
mainWindow.loadFile(
path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`)

View File

@@ -1,4 +1,4 @@
import { EditorNodeTypes,generateId, getIdTypeFromNode } from '@colanode/core';
import { EditorNodeTypes, generateId, IdType } from '@colanode/core';
import { Extension } from '@tiptap/react';
import { Plugin, PluginKey } from 'prosemirror-state';
@@ -50,16 +50,31 @@ export const IdExtension = Extension.create({
key: new PluginKey('id'),
appendTransaction(_, __, state) {
const { tr } = state;
const ids = new Set<string>();
state.doc.descendants((node, pos) => {
if (node.isText) {
return; // Text nodes don't need IDs
}
if (!node.attrs.id || typeof node.attrs.id !== 'string') {
const id = generateId(IdType.Block);
ids.add(id);
tr.setNodeMarkup(pos, null, {
...node.attrs,
id: generateId(getIdTypeFromNode(node.type.name)),
id,
});
} else {
let id = node.attrs.id;
if (ids.has(id)) {
id = generateId(IdType.Block);
ids.add(id);
tr.setNodeMarkup(pos, null, {
...node.attrs,
id,
});
} else {
ids.add(id);
}
}
});
return tr;

View File

@@ -5,7 +5,7 @@ import {
EditorNodeTypes,
generateId,
generateNodeIndex,
getIdTypeFromNode,
IdType,
} from '@colanode/core';
import { JSONContent } from '@tiptap/core';
@@ -208,7 +208,7 @@ const getIdFromContent = (content: JSONContent): string => {
throw new Error('Invalid content type');
}
return content.attrs?.id ?? generateId(getIdTypeFromNode(content.type));
return content.attrs?.id ?? generateId(IdType.Block);
};
export const editorHasContent = (block?: JSONContent) => {

View File

@@ -1,7 +1,5 @@
import { monotonicFactory } from 'ulid';
import { NodeTypes } from './constants';
const ulid = monotonicFactory();
export enum IdType {
@@ -17,18 +15,6 @@ export enum IdType {
Node = 'nd',
Message = 'ms',
Subscriber = 'sb',
Paragraph = 'pa',
Heading1 = 'h1',
Heading2 = 'h2',
Heading3 = 'h3',
Blockquote = 'bq',
CodeBlock = 'cb',
ListItem = 'li',
OrderedList = 'ol',
BulletList = 'bl',
TaskList = 'tl',
TaskItem = 'ti',
HorizontalRule = 'hr',
Database = 'db',
DatabaseReplica = 'dr',
Record = 'rc',
@@ -49,6 +35,7 @@ export enum IdType {
Transaction = 'tx',
Event = 'ev',
Host = 'ht',
Block = 'bl',
}
export const generateId = (type: IdType): string => {
@@ -62,28 +49,3 @@ export const isIdOfType = (id: string, type: IdType): boolean => {
export const getIdType = (id: string): IdType => {
return id.substring(id.length - 2) as IdType;
};
export const getIdTypeFromNode = (nodeType: string): IdType => {
switch (nodeType) {
case NodeTypes.User:
return IdType.User;
case NodeTypes.Space:
return IdType.Space;
case NodeTypes.Page:
return IdType.Page;
case NodeTypes.Channel:
return IdType.Channel;
case NodeTypes.Message:
return IdType.Message;
case NodeTypes.Database:
return IdType.Database;
case NodeTypes.DatabaseReplica:
return IdType.DatabaseReplica;
case NodeTypes.Record:
return IdType.Record;
case NodeTypes.Folder:
return IdType.Folder;
default:
return IdType.Node;
}
};