Compare commits

...

1 Commits

Author SHA1 Message Date
Tom Moor 50b0c4b357 fix: Cannot leave overlapping comments 2024-12-12 13:29:47 -05:00
3 changed files with 28 additions and 8 deletions
+5 -1
View File
@@ -241,7 +241,11 @@ export default function formattingMenuItems(
shortcut: `${metaDisplay}+⌥+M`,
icon: <CommentIcon />,
label: isCodeBlock ? dictionary.comment : undefined,
active: isMarkActive(schema.marks.comment, { resolved: false }),
active: isMarkActive(
schema.marks.comment,
{ resolved: false },
{ exact: true }
),
visible: !isMobile || !isEmpty,
},
{
+9 -3
View File
@@ -16,6 +16,8 @@ export default class Comment extends Mark {
get schema(): MarkSpec {
return {
// Allow multiple comments to overlap
excludes: "",
attrs: {
id: {},
userId: {},
@@ -97,9 +99,13 @@ export default class Comment extends Mark {
return this.options.onCreateCommentMark
? (): Command => (state, dispatch) => {
if (
isMarkActive(state.schema.marks.comment, {
resolved: false,
})(state)
isMarkActive(
state.schema.marks.comment,
{
resolved: false,
},
{ exact: true }
)(state)
) {
return false;
}
+14 -4
View File
@@ -3,15 +3,21 @@ import { EditorState } from "prosemirror-state";
import { Primitive } from "utility-types";
import { getMarksBetween } from "./getMarksBetween";
type Options = {
/** Only return match if the range and attrs is exact */
exact?: boolean;
};
/**
* Checks if a mark is active in the current selection or not.
*
* @param type The mark type to check.
* @param attrs The attributes to check.
* @param options The options to use.
* @returns A function that checks if a mark is active in the current selection or not.
*/
export const isMarkActive =
(type: MarkType, attrs?: Record<string, Primitive>) =>
(type: MarkType, attrs?: Record<string, Primitive>, options?: Options) =>
(state: EditorState): boolean => {
if (!type) {
return false;
@@ -25,12 +31,16 @@ export const isMarkActive =
if (!hasMark) {
return false;
}
if (attrs) {
if (attrs || options) {
const results = getMarksBetween(from, to, state);
return results.some(
({ mark }) =>
({ mark, start, end }) =>
mark.type === type &&
Object.keys(attrs).every((key) => mark.attrs[key] === attrs[key])
(!attrs ||
Object.keys(attrs).every(
(key) => mark.attrs[key] === attrs[key]
)) &&
(!options?.exact || (start === from && end === to))
);
}