tangled
alpha
login
or
join now
ajamesphillips.com
/
leaflet
forked from
leaflet.pub/leaflet
a tool for shared writing and social publishing
0
fork
atom
overview
issues
pulls
pipelines
Compare changes
Choose any two refs to compare.
base:
update/wider-page
update/looseleafs
update/delete-leaflets
test/unknown-marks
refactor/shared-home-layout
main
fix/bottom-scroll-margin-on-docs
feature/warn-on-data-loss
feature/tags
feature/reader
feature/publish-leaflets
feature/pub-contributors
feature/profiles
feature/page-blocks
feature/notifications
feature/hard_breaks
feature/follow-via-email
feature/bsky-follows-feed
feature/atp-polls
feature/atp-canvas-blocks
feature/at-mentions
debug/datetime
no tags found
compare:
update/wider-page
update/looseleafs
update/delete-leaflets
test/unknown-marks
refactor/shared-home-layout
main
fix/bottom-scroll-margin-on-docs
feature/warn-on-data-loss
feature/tags
feature/reader
feature/publish-leaflets
feature/pub-contributors
feature/profiles
feature/page-blocks
feature/notifications
feature/hard_breaks
feature/follow-via-email
feature/bsky-follows-feed
feature/atp-polls
feature/atp-canvas-blocks
feature/at-mentions
debug/datetime
no tags found
go
+24
-2
1 changed file
expand all
collapse all
unified
split
app
[leaflet_id]
publish
BskyPostEditorProsemirror.tsx
+24
-2
app/[leaflet_id]/publish/BskyPostEditorProsemirror.tsx
···
1
1
"use client";
2
2
import { AppBskyRichtextFacet, UnicodeString } from "@atproto/api";
3
3
-
import { useState, useCallback, useRef, useLayoutEffect } from "react";
3
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
295
+
const haveContent = (editorState?.doc.textContent.length ?? 0) > 0
296
296
+
297
297
+
// Warn if there's content in the editor on page change, unload or reload.
298
298
+
useWarnOnUnsavedChanges(haveContent);
299
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
305
-
{editorState?.doc.textContent.length === 0 && (
310
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
453
+
454
454
+
455
455
+
function useWarnOnUnsavedChanges(hasUnsavedContent: boolean) {
456
456
+
useEffect(() => {
457
457
+
const handleBeforeUnload = (e: BeforeUnloadEvent) => {
458
458
+
if (hasUnsavedContent) {
459
459
+
e.preventDefault();
460
460
+
// Chrome requires returnValue to be set
461
461
+
e.returnValue = "";
462
462
+
}
463
463
+
};
464
464
+
window.addEventListener("beforeunload", handleBeforeUnload);
465
465
+
return () => {
466
466
+
window.removeEventListener("beforeunload", handleBeforeUnload);
467
467
+
};
468
468
+
}, [hasUnsavedContent]);
469
469
+
}