Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export const CustomImageNode = (props: CustomImageNodeProps) => {
failedToLoadImage={failedToLoadImage}
getPos={getPos}
loadImageFromFileSystem={setImageFromFileSystem}
maxFileSize={editor.storage.imageComponent.maxFileSize}
maxFileSize={editor.storage.imageComponent?.maxFileSize}
node={node}
setIsUploaded={setIsUploaded}
selected={selected}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const ImageUploadStatus: React.FC<Props> = (props) => {
// subscribe to image upload status
const uploadStatus: number | undefined = useEditorState({
editor,
selector: ({ editor }) => editor.storage.imageComponent.assetsUploadStatus[nodeId],
selector: ({ editor }) => editor.storage.imageComponent?.assetsUploadStatus[nodeId],
});

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ declare module "@tiptap/core" {
imageComponent: {
insertImageComponent: ({ file, pos, event }: InsertImageComponentProps) => ReturnType;
uploadImage: (blockId: string, file: File) => () => Promise<string> | undefined;
updateAssetsUploadStatus: (updatedStatus: TFileHandler["assetsUploadStatus"]) => () => void;
updateAssetsUploadStatus?: (updatedStatus: TFileHandler["assetsUploadStatus"]) => () => void;
getImageSource?: (path: string) => () => Promise<string>;
restoreImage: (src: string) => () => Promise<void>;
};
Expand Down
25 changes: 16 additions & 9 deletions packages/editor/src/core/extensions/extensions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ type TArguments = {
export const CoreEditorExtensions = (args: TArguments): Extensions => {
const { disabledExtensions, enableHistory, fileHandler, mentionHandler, placeholder, tabIndex } = args;

return [
// @ts-expect-error tiptap types are incorrect
const extensions = [
StarterKit.configure({
bulletList: {
HTMLAttributes: {
Expand Down Expand Up @@ -109,12 +108,6 @@ export const CoreEditorExtensions = (args: TArguments): Extensions => {
},
}),
CustomTypographyExtension,
ImageExtension(fileHandler).configure({
HTMLAttributes: {
class: "rounded-md",
},
}),
CustomImageExtension(fileHandler),
TiptapUnderline,
TextStyle,
TaskList.configure({
Expand Down Expand Up @@ -152,7 +145,7 @@ export const CoreEditorExtensions = (args: TArguments): Extensions => {

if (node.type.name === "heading") return `Heading ${node.attrs.level}`;

if (editor.storage.imageComponent.uploadInProgress) return "";
if (editor.storage.imageComponent?.uploadInProgress) return "";

const shouldHidePlaceholder =
editor.isActive("table") ||
Expand All @@ -179,4 +172,18 @@ export const CoreEditorExtensions = (args: TArguments): Extensions => {
disabledExtensions,
}),
];

if (!disabledExtensions.includes("image")) {
extensions.push(
ImageExtension(fileHandler).configure({
HTMLAttributes: {
class: "rounded-md",
},
}),
CustomImageExtension(fileHandler)
);
}

// @ts-expect-error tiptap types are incorrect
return extensions;
};
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const CustomImageComponentWithoutProps = () =>
return {
fileMap: new Map(),
deletedImageSet: new Map<string, boolean>(),
assetsUploadStatus: {},
};
},
});
Expand Down
23 changes: 15 additions & 8 deletions packages/editor/src/core/extensions/read-only-extensions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ type Props = {
export const CoreReadOnlyEditorExtensions = (props: Props): Extensions => {
const { disabledExtensions, fileHandler, mentionHandler } = props;

return [
// @ts-expect-error tiptap types are incorrect
const extensions = [
StarterKit.configure({
bulletList: {
HTMLAttributes: {
Expand Down Expand Up @@ -94,12 +93,6 @@ export const CoreReadOnlyEditorExtensions = (props: Props): Extensions => {
},
}),
CustomTypographyExtension,
ReadOnlyImageExtension(fileHandler).configure({
HTMLAttributes: {
class: "rounded-md",
},
}),
CustomReadOnlyImageExtension(fileHandler),
TiptapUnderline,
TextStyle,
TaskList.configure({
Expand Down Expand Up @@ -136,4 +129,18 @@ export const CoreReadOnlyEditorExtensions = (props: Props): Extensions => {
disabledExtensions,
}),
];

if (!disabledExtensions.includes("image")) {
extensions.push(
ReadOnlyImageExtension(fileHandler).configure({
HTMLAttributes: {
class: "rounded-md",
},
}),
CustomReadOnlyImageExtension(fileHandler)
);
}

// @ts-expect-error tiptap types are incorrect
return extensions;
};
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import { CommandProps, ISlashCommandItem, TSlashCommandSectionKeys } from "@/typ
// plane editor extensions
import { coreEditorAdditionalSlashCommandOptions } from "@/plane-editor/extensions";
// local types
import { TExtensionProps } from "./root";
import { TExtensionProps, TSlashCommandAdditionalOption } from "./root";

export type TSlashCommandSection = {
key: TSlashCommandSectionKeys;
Expand All @@ -54,7 +54,7 @@ export type TSlashCommandSection = {
export const getSlashCommandFilteredSections =
(args: TExtensionProps) =>
({ query }: { query: string }): TSlashCommandSection[] => {
const { additionalOptions, disabledExtensions } = args;
const { additionalOptions: externalAdditionalOptions, disabledExtensions } = args;
const SLASH_COMMAND_SECTIONS: TSlashCommandSection[] = [
{
key: "general",
Expand Down Expand Up @@ -176,15 +176,6 @@ export const getSlashCommandFilteredSections =
icon: <Code2 className="size-3.5" />,
command: ({ editor, range }) => editor.chain().focus().deleteRange(range).toggleCodeBlock().run(),
},
{
commandKey: "image",
key: "image",
title: "Image",
icon: <ImageIcon className="size-3.5" />,
description: "Insert an image",
searchTerms: ["img", "photo", "picture", "media", "upload"],
command: ({ editor, range }: CommandProps) => insertImage({ editor, event: "insert", range }),
},
{
commandKey: "callout",
key: "callout",
Expand Down Expand Up @@ -284,8 +275,24 @@ export const getSlashCommandFilteredSections =
},
];

const internalAdditionalOptions: TSlashCommandAdditionalOption[] = [];
if (!disabledExtensions?.includes("image")) {
internalAdditionalOptions.push({
commandKey: "image",
key: "image",
title: "Image",
icon: <ImageIcon className="size-3.5" />,
description: "Insert an image",
searchTerms: ["img", "photo", "picture", "media", "upload"],
command: ({ editor, range }: CommandProps) => insertImage({ editor, event: "insert", range }),
section: "general",
pushAfter: "code",
});
}

[
...(additionalOptions ?? []),
...internalAdditionalOptions,
...(externalAdditionalOptions ?? []),
...coreEditorAdditionalSlashCommandOptions({
disabledExtensions,
}),
Expand Down
6 changes: 3 additions & 3 deletions packages/editor/src/core/hooks/use-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export const useEditor = (props: CustomEditorProps) => {
// value is null when intentionally passed where syncing is not yet
// supported and value is undefined when the data from swr is not populated
if (value == null) return;
if (editor && !editor.isDestroyed && !editor.storage.imageComponent.uploadInProgress) {
if (editor && !editor.isDestroyed && !editor.storage.imageComponent?.uploadInProgress) {
try {
editor.commands.setContent(value, false, { preserveWhitespace: "full" });
if (editor.state.selection) {
Expand All @@ -129,7 +129,7 @@ export const useEditor = (props: CustomEditorProps) => {
useEffect(() => {
if (!editor) return;
const assetsUploadStatus = fileHandler.assetsUploadStatus;
editor.commands.updateAssetsUploadStatus(assetsUploadStatus);
editor.commands.updateAssetsUploadStatus?.(assetsUploadStatus);
}, [editor, fileHandler.assetsUploadStatus]);

useImperativeHandle(
Expand Down Expand Up @@ -221,7 +221,7 @@ export const useEditor = (props: CustomEditorProps) => {
if (!editor) return;
scrollSummary(editor, marking);
},
isEditorReadyToDiscard: () => editor?.storage.imageComponent.uploadInProgress === false,
isEditorReadyToDiscard: () => editor?.storage.imageComponent?.uploadInProgress === false,
setFocusAtPosition: (position: number) => {
if (!editor || editor.isDestroyed) {
console.error("Editor reference is not available or has been destroyed.");
Expand Down
4 changes: 3 additions & 1 deletion packages/editor/src/core/hooks/use-file-upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ export const useUploader = (args: TUploaderArgs) => {
const uploadFile = useCallback(
async (file: File) => {
const setImageUploadInProgress = (isUploading: boolean) => {
editor.storage.imageComponent.uploadInProgress = isUploading;
if (editor.storage.imageComponent) {
editor.storage.imageComponent.uploadInProgress = isUploading;
}
};
setImageUploadInProgress(true);
setUploading(true);
Expand Down
2 changes: 1 addition & 1 deletion packages/editor/src/core/types/extensions.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export type TExtensions = "ai" | "collaboration-cursor" | "issue-embed" | "slash-commands" | "enter-key";
export type TExtensions = "ai" | "collaboration-cursor" | "issue-embed" | "slash-commands" | "enter-key" | "image";