added better syncing of "Saved" state of editor and Image uploads

This commit is contained in:
Palanikannan1437 2023-08-18 18:01:24 +05:30
parent aa1812b9e3
commit aa5c118616
8 changed files with 16 additions and 17 deletions

View File

@ -75,6 +75,8 @@ export const IssueDescriptionForm: FC<IssueDetailsProps> = ({
setTimeout(async () => { setTimeout(async () => {
setIsSubmitting("saved"); setIsSubmitting("saved");
}, 2000); }, 2000);
} else if (isSubmitting === "submitting") {
setShowAlert(true);
} }
}, [isSubmitting, setShowAlert]); }, [isSubmitting, setShowAlert]);

View File

@ -23,7 +23,7 @@ import isValidHttpUrl from "../bubble-menu/utils/link-validator";
lowlight.registerLanguage("ts", ts); lowlight.registerLanguage("ts", ts);
export const TiptapExtensions = (workspaceSlug: string) => [ export const TiptapExtensions = (workspaceSlug: string, setIsSubmitting?: (isSubmitting: "submitting" | "submitted" | "saved") => void) => [
StarterKit.configure({ StarterKit.configure({
bulletList: { bulletList: {
HTMLAttributes: { HTMLAttributes: {
@ -112,7 +112,7 @@ export const TiptapExtensions = (workspaceSlug: string) => [
UniqueID.configure({ UniqueID.configure({
types: ["image"], types: ["image"],
}), }),
SlashCommand(workspaceSlug), SlashCommand(workspaceSlug, setIsSubmitting),
TiptapUnderline, TiptapUnderline,
TextStyle, TextStyle,
Color, Color,

View File

@ -39,8 +39,8 @@ const Tiptap = (props: ITiptapRichTextEditor) => {
const editor = useEditor({ const editor = useEditor({
editable: editable ?? true, editable: editable ?? true,
editorProps: TiptapEditorProps(workspaceSlug), editorProps: TiptapEditorProps(workspaceSlug, setIsSubmitting),
extensions: TiptapExtensions(workspaceSlug), extensions: TiptapExtensions(workspaceSlug, setIsSubmitting),
content: value, content: value,
onUpdate: async ({ editor }) => { onUpdate: async ({ editor }) => {
// for instant feedback loop // for instant feedback loop

View File

@ -14,7 +14,6 @@ const TrackImageDeletionPlugin = () =>
const removedImages: ProseMirrorNode[] = []; const removedImages: ProseMirrorNode[] = [];
oldState.doc.descendants((oldNode, oldPos) => { oldState.doc.descendants((oldNode, oldPos) => {
console.log(oldNode.type.name)
if (oldNode.type.name !== 'image') return; if (oldNode.type.name !== 'image') return;
if (!newState.doc.resolve(oldPos).parent) return; if (!newState.doc.resolve(oldPos).parent) return;

View File

@ -57,7 +57,7 @@ function findPlaceholder(state: EditorState, id: {}) {
return found.length ? found[0].from : null; return found.length ? found[0].from : null;
} }
export async function startImageUpload(file: File, view: EditorView, pos: number, workspaceSlug: string) { export async function startImageUpload(file: File, view: EditorView, pos: number, workspaceSlug: string, setIsSubmitting?: (isSubmitting: "submitting" | "submitted" | "saved") => void) {
if (!file.type.includes("image/")) { if (!file.type.includes("image/")) {
return; return;
} else if (file.size / 1024 / 1024 > 20) { } else if (file.size / 1024 / 1024 > 20) {
@ -85,6 +85,7 @@ export async function startImageUpload(file: File, view: EditorView, pos: number
if (!workspaceSlug) { if (!workspaceSlug) {
return; return;
} }
setIsSubmitting?.("submitting")
const src = await UploadImageHandler(file, workspaceSlug); const src = await UploadImageHandler(file, workspaceSlug);
const { schema } = view.state; const { schema } = view.state;
pos = findPlaceholder(view.state, id); pos = findPlaceholder(view.state, id);
@ -104,7 +105,6 @@ const UploadImageHandler = (file: File, workspaceSlug: string): Promise<string>
return Promise.reject("Workspace slug is missing"); return Promise.reject("Workspace slug is missing");
} }
try { try {
console.log("in here",workspaceSlug)
const formData = new FormData(); const formData = new FormData();
formData.append("asset", file); formData.append("asset", file);
formData.append("attributes", JSON.stringify({})); formData.append("attributes", JSON.stringify({}));
@ -116,7 +116,6 @@ const UploadImageHandler = (file: File, workspaceSlug: string): Promise<string>
const image = new Image(); const image = new Image();
image.src = imageUrl; image.src = imageUrl;
console.log("image uploaded", imageUrl)
image.onload = () => { image.onload = () => {
resolve(imageUrl); resolve(imageUrl);
}; };

View File

@ -1,7 +1,7 @@
import { EditorProps } from "@tiptap/pm/view"; import { EditorProps } from "@tiptap/pm/view";
import { startImageUpload } from "./plugins/upload-image"; import { startImageUpload } from "./plugins/upload-image";
export function TiptapEditorProps(workspaceSlug: string): EditorProps { export function TiptapEditorProps(workspaceSlug: string, setIsSubmitting?: (isSubmitting: "submitting" | "submitted" | "saved") => void): EditorProps {
return { return {
attributes: { attributes: {
class: `prose prose-brand max-w-full prose-headings:font-display font-default focus:outline-none`, class: `prose prose-brand max-w-full prose-headings:font-display font-default focus:outline-none`,
@ -26,8 +26,7 @@ export function TiptapEditorProps(workspaceSlug: string): EditorProps {
event.preventDefault(); event.preventDefault();
const file = event.clipboardData.files[0]; const file = event.clipboardData.files[0];
const pos = view.state.selection.from; const pos = view.state.selection.from;
startImageUpload(file, view, pos, workspaceSlug, setIsSubmitting);
startImageUpload(file, view, pos, workspaceSlug);
return true; return true;
} }
return false; return false;
@ -47,7 +46,7 @@ export function TiptapEditorProps(workspaceSlug: string): EditorProps {
}); });
// here we deduct 1 from the pos or else the image will create an extra node // here we deduct 1 from the pos or else the image will create an extra node
if (coordinates) { if (coordinates) {
startImageUpload(file, view, coordinates.pos - 1, workspaceSlug); startImageUpload(file, view, coordinates.pos - 1, workspaceSlug, setIsSubmitting);
} }
return true; return true;
} }

View File

@ -52,7 +52,7 @@ const Command = Extension.create({
}, },
}); });
const getSuggestionItems = (workspaceSlug: string) => ({ query }: { query: string }) => const getSuggestionItems = (workspaceSlug: string, setIsSubmitting?: (isSubmitting: "submitting" | "submitted" | "saved") => void) => ({ query }: { query: string }) =>
[ [
{ {
title: "Text", title: "Text",
@ -163,7 +163,7 @@ const getSuggestionItems = (workspaceSlug: string) => ({ query }: { query: strin
if (input.files?.length) { if (input.files?.length) {
const file = input.files[0]; const file = input.files[0];
const pos = editor.view.state.selection.from; const pos = editor.view.state.selection.from;
startImageUpload(file, editor.view, pos, workspaceSlug); startImageUpload(file, editor.view, pos, workspaceSlug, setIsSubmitting);
} }
}; };
input.click(); input.click();
@ -328,10 +328,10 @@ const renderItems = () => {
}; };
}; };
export const SlashCommand = (workspaceSlug: string) => export const SlashCommand = (workspaceSlug: string, setIsSubmitting?: (isSubmitting: "submitting" | "submitted" | "saved") => void) =>
Command.configure({ Command.configure({
suggestion: { suggestion: {
items: getSuggestionItems(workspaceSlug), items: getSuggestionItems(workspaceSlug, setIsSubmitting),
render: renderItems, render: renderItems,
}, },
}); });

View File

@ -135,7 +135,7 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p {
box-sizing: border-box; box-sizing: border-box;
position: absolute; position: absolute;
top: 50%; top: 50%;
left: 50%; left: 45%;
width: 20px; width: 20px;
height: 20px; height: 20px;
border-radius: 50%; border-radius: 50%;