Something went wrong. Try again.
a tool for shared writing and social publishing
Something went wrong. Try again.
2.2 kB · 71 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172import { EditorView } from "prosemirror-view";import { v7 } from "uuid";import { Replicache } from "replicache";import type { ReplicacheMutators } from "src/replicache";import { schema } from "./schema";import { generateKeyBetween } from "fractional-indexing";import { scanIndex } from "src/replicache/utils";
export async function insertFootnote( view: EditorView, blockID: string, rep: Replicache<ReplicacheMutators>, permissionSet: string,) { let footnoteEntityID = v7();
let existingFootnotes = await rep.query(async (tx) => { let scan = scanIndex(tx); return scan.eav(blockID, "block/footnote"); });
// Build a map from footnoteEntityID to its fractional-index position let positionByEntityID: Record<string, string> = {}; for (let f of existingFootnotes) { positionByEntityID[f.data.value] = f.data.position; }
// Find footnotes that appear before and after the insertion point in the text let { from } = view.state.selection; let beforePosition: string | null = null; let afterPosition: string | null = null; let foundInsertionPoint = false;
view.state.doc.descendants((node, pos) => { if (node.type.name === "footnote") { let entityID = node.attrs.footnoteEntityID; let p = positionByEntityID[entityID]; if (p !== undefined) { if (pos < from) { // This footnote is before the insertion point if (beforePosition === null || p > beforePosition) { beforePosition = p; } } else { // This footnote is at or after the insertion point if (!foundInsertionPoint) { afterPosition = p; foundInsertionPoint = true; } else if (afterPosition !== null && p < afterPosition) { afterPosition = p; } } } } });
let position = generateKeyBetween(beforePosition, afterPosition);
await rep.mutate.createFootnote({ footnoteEntityID, blockID, permission_set: permissionSet, position, });
let node = schema.nodes.footnote.create({ footnoteEntityID }); let tr = view.state.tr.insert(from, node); view.dispatch(tr);
return footnoteEntityID;}