mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-04-12 00:17:02 +02:00
fix(editor): add remove button and fix cursor positioning for event embeds
- Add X button on hover to NostrEventPreviewRich (same pattern as BlobAttachmentRich) - Fix cursor positioning after pasting nevent/naddr by tracking node sizes correctly - Import TextSelection from prosemirror-state to properly set cursor position - Change from `tr.insert(from + index, node)` to `tr.insert(insertPos, node)` with cumulative position tracking Previously, cursor would stay behind the event embed node after pasting. Now it correctly positions after the inserted content.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { Extension } from "@tiptap/core";
|
||||
import { Plugin, PluginKey } from "@tiptap/pm/state";
|
||||
import { Plugin, PluginKey, TextSelection } from "@tiptap/pm/state";
|
||||
import { nip19 } from "nostr-tools";
|
||||
import eventStore from "@/services/event-store";
|
||||
import { getProfileContent } from "applesauce-core/helpers";
|
||||
@@ -152,11 +152,16 @@ export const NostrPasteHandler = Extension.create({
|
||||
const { tr } = view.state;
|
||||
const { from } = view.state.selection;
|
||||
|
||||
// Insert content
|
||||
nodes.forEach((node, index) => {
|
||||
tr.insert(from + index, node);
|
||||
// Insert content and track position
|
||||
let insertPos = from;
|
||||
nodes.forEach((node) => {
|
||||
tr.insert(insertPos, node);
|
||||
insertPos += node.nodeSize;
|
||||
});
|
||||
|
||||
// Move cursor to end of inserted content
|
||||
tr.setSelection(TextSelection.near(tr.doc.resolve(insertPos)));
|
||||
|
||||
view.dispatch(tr);
|
||||
return true; // Prevent default paste
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { NodeViewWrapper, type ReactNodeViewProps } from "@tiptap/react";
|
||||
import { X } from "lucide-react";
|
||||
import { useNostrEvent } from "@/hooks/useNostrEvent";
|
||||
import { KindRenderer } from "@/components/nostr/kinds";
|
||||
import type { EventPointer, AddressPointer } from "nostr-tools/nip19";
|
||||
@@ -9,7 +10,10 @@ import { EventCardSkeleton } from "@/components/ui/skeleton";
|
||||
*
|
||||
* Uses the feed KindRenderer to show event content inline
|
||||
*/
|
||||
export function NostrEventPreviewRich({ node }: ReactNodeViewProps) {
|
||||
export function NostrEventPreviewRich({
|
||||
node,
|
||||
deleteNode,
|
||||
}: ReactNodeViewProps) {
|
||||
const { type, data } = node.attrs as {
|
||||
type: "note" | "nevent" | "naddr";
|
||||
data: any;
|
||||
@@ -40,7 +44,7 @@ export function NostrEventPreviewRich({ node }: ReactNodeViewProps) {
|
||||
const event = useNostrEvent(pointer || undefined);
|
||||
|
||||
return (
|
||||
<NodeViewWrapper className="my-2">
|
||||
<NodeViewWrapper className="my-2 relative group">
|
||||
<div className="rounded-lg border border-border bg-muted/30 p-3 pointer-events-none">
|
||||
{!event ? (
|
||||
<EventCardSkeleton className="py-2" />
|
||||
@@ -48,6 +52,15 @@ export function NostrEventPreviewRich({ node }: ReactNodeViewProps) {
|
||||
<KindRenderer event={event} depth={0} />
|
||||
)}
|
||||
</div>
|
||||
{deleteNode && (
|
||||
<button
|
||||
onClick={deleteNode}
|
||||
className="absolute top-2 right-2 p-1.5 rounded-full bg-background/90 hover:bg-background border border-border opacity-0 group-hover:opacity-100 transition-opacity"
|
||||
contentEditable={false}
|
||||
>
|
||||
<X className="size-4" />
|
||||
</button>
|
||||
)}
|
||||
</NodeViewWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user