import type { Editor } from "@tiptap/react" import type { Node as ProseMirrorNode } from "@tiptap/pm/model" import { getDocsBlockTargets } from "@/lib/drive/docs-block-targets" import { clampIndentLevel, nextIndentLevel, } from "@/lib/drive/docs-indent" function applyBlockIndentDelta(editor: Editor, delta: number): boolean { const { state } = editor const targets = getDocsBlockTargets(state.doc, state.selection.from, state.selection.to) if (targets.length === 0) return false let tr = state.tr let changed = false for (const { pos, node } of targets) { const current = clampIndentLevel((node.attrs.indentLevel as number | undefined) ?? 0) const next = nextIndentLevel(current, delta) if (next === current) continue tr = tr.setNodeMarkup(pos, undefined, { ...node.attrs, indentLevel: next }) changed = true } if (!changed) return false editor.view.dispatch(tr.scrollIntoView()) return true } export function increaseDocsIndent(editor: Editor | null): boolean { if (!editor || editor.isDestroyed) return false if (editor.isActive("taskItem")) { return editor.can().sinkListItem("taskItem") ? editor.chain().focus().sinkListItem("taskItem").run() : false } if (editor.isActive("listItem")) { return editor.can().sinkListItem("listItem") ? editor.chain().focus().sinkListItem("listItem").run() : false } return applyBlockIndentDelta(editor, 1) } export function decreaseDocsIndent(editor: Editor | null): boolean { if (!editor || editor.isDestroyed) return false if (editor.isActive("taskItem")) { return editor.can().liftListItem("taskItem") ? editor.chain().focus().liftListItem("taskItem").run() : false } if (editor.isActive("listItem")) { return editor.can().liftListItem("listItem") ? editor.chain().focus().liftListItem("listItem").run() : false } return applyBlockIndentDelta(editor, -1) } export function canIncreaseDocsIndent(editor: Editor | null): boolean { if (!editor || editor.isDestroyed) return false if (editor.isActive("taskItem")) return editor.can().sinkListItem("taskItem") if (editor.isActive("listItem")) return editor.can().sinkListItem("listItem") return getDocsBlockTargets( editor.state.doc, editor.state.selection.from, editor.state.selection.to ).some( ({ node }) => nextIndentLevel((node.attrs.indentLevel as number | undefined) ?? 0, 1) !== clampIndentLevel((node.attrs.indentLevel as number | undefined) ?? 0) ) } export function canDecreaseDocsIndent(editor: Editor | null): boolean { if (!editor || editor.isDestroyed) return false if (editor.isActive("taskItem")) return editor.can().liftListItem("taskItem") if (editor.isActive("listItem")) return editor.can().liftListItem("listItem") return getDocsBlockTargets( editor.state.doc, editor.state.selection.from, editor.state.selection.to ).some(({ node }) => clampIndentLevel((node.attrs.indentLevel as number | undefined) ?? 0) > 0) }