a tool for shared writing and social publishing

Compare changes

Choose any two refs to compare.

Changed files
+24 -2
app
[leaflet_id]
+24 -2
app/[leaflet_id]/publish/BskyPostEditorProsemirror.tsx
··· 1 1 "use client"; 2 2 import { AppBskyRichtextFacet, UnicodeString } from "@atproto/api"; 3 - import { useState, useCallback, useRef, useLayoutEffect } from "react"; 3 + import { useEffect, useState, useCallback, useRef, useLayoutEffect } from "react"; 4 4 import { EditorState } from "prosemirror-state"; 5 5 import { EditorView } from "prosemirror-view"; 6 6 import { Schema, MarkSpec, Mark } from "prosemirror-model"; ··· 292 292 }; 293 293 }, [openMentionAutocomplete]); 294 294 295 + const haveContent = (editorState?.doc.textContent.length ?? 0) > 0 296 + 297 + // Warn if there's content in the editor on page change, unload or reload. 298 + useWarnOnUnsavedChanges(haveContent); 299 + 295 300 return ( 296 301 <div className="relative w-full h-full group"> 297 302 <MentionAutocomplete ··· 302 307 coords={mentionCoords} 303 308 placeholder="Search people..." 304 309 /> 305 - {editorState?.doc.textContent.length === 0 && ( 310 + {!haveContent && ( 306 311 <div className="italic text-tertiary absolute top-0 left-0 pointer-events-none"> 307 312 Write a post to share your writing! 308 313 </div> ··· 445 450 view.dispatch(tr); 446 451 view.focus(); 447 452 }; 453 + 454 + 455 + function useWarnOnUnsavedChanges(hasUnsavedContent: boolean) { 456 + useEffect(() => { 457 + const handleBeforeUnload = (e: BeforeUnloadEvent) => { 458 + if (hasUnsavedContent) { 459 + e.preventDefault(); 460 + // Chrome requires returnValue to be set 461 + e.returnValue = ""; 462 + } 463 + }; 464 + window.addEventListener("beforeunload", handleBeforeUnload); 465 + return () => { 466 + window.removeEventListener("beforeunload", handleBeforeUnload); 467 + }; 468 + }, [hasUnsavedContent]); 469 + }