Add in-content video embed and image replace/delete controls
- KinescopeVideo TipTap node: insert video anywhere in lesson content via toolbar button; editor shows ID preview, student view renders KinescopePlayer - ImageWithControls NodeView: hover over any image in editor to reveal Replace and Delete buttons Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,16 +1,56 @@
|
||||
"use client";
|
||||
|
||||
import { useEditor, EditorContent } from "@tiptap/react";
|
||||
import { useEditor, EditorContent, NodeViewWrapper, ReactNodeViewRenderer } from "@tiptap/react";
|
||||
import { Node, mergeAttributes } from "@tiptap/core";
|
||||
import StarterKit from "@tiptap/starter-kit";
|
||||
import Image from "@tiptap/extension-image";
|
||||
import Link from "@tiptap/extension-link";
|
||||
import Underline from "@tiptap/extension-underline";
|
||||
import { KinescopePlayer } from "@/components/player/kinescope-player";
|
||||
|
||||
function KinescopeVideoStudentView({ node }: { node: { attrs: Record<string, unknown> } }) {
|
||||
const videoId = node.attrs.videoId as string;
|
||||
if (!videoId) return null;
|
||||
return (
|
||||
<NodeViewWrapper>
|
||||
<div className="my-6">
|
||||
<KinescopePlayer videoId={videoId} />
|
||||
</div>
|
||||
</NodeViewWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
const KinescopeVideoExtension = Node.create({
|
||||
name: "kinescopeVideo",
|
||||
group: "block",
|
||||
atom: true,
|
||||
|
||||
addAttributes() {
|
||||
return { videoId: { default: "" } };
|
||||
},
|
||||
|
||||
parseHTML() {
|
||||
return [{ tag: "div[data-kinescope-video]" }];
|
||||
},
|
||||
|
||||
renderHTML({ HTMLAttributes }) {
|
||||
return ["div", mergeAttributes({ "data-kinescope-video": "" }, HTMLAttributes)];
|
||||
},
|
||||
|
||||
addNodeView() {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return ReactNodeViewRenderer(KinescopeVideoStudentView as any);
|
||||
},
|
||||
});
|
||||
|
||||
export function LessonContent({ content }: { content: object }) {
|
||||
const editor = useEditor({
|
||||
extensions: [
|
||||
StarterKit,
|
||||
Underline,
|
||||
Image.configure({ inline: false }),
|
||||
Link.configure({ openOnClick: true }),
|
||||
KinescopeVideoExtension,
|
||||
],
|
||||
content,
|
||||
editable: false,
|
||||
|
||||
Reference in New Issue
Block a user