From 98361707dac0ceec3f9d52a314d30b31ad7aef06 Mon Sep 17 00:00:00 2001 From: vincent Date: Thu, 10 Feb 2022 15:01:33 +0100 Subject: [PATCH] Test video embed on the text editor --- .../base/text-editor/fab-text-editor.tsx | 4 +- .../components/base/text-editor/iframe.tsx | 76 +++++++++++++++++++ .../components/base/text-editor/menu-bar.tsx | 20 ++++- .../modules/base/fab-text-editor.scss | 9 +++ 4 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 app/frontend/src/javascript/components/base/text-editor/iframe.tsx diff --git a/app/frontend/src/javascript/components/base/text-editor/fab-text-editor.tsx b/app/frontend/src/javascript/components/base/text-editor/fab-text-editor.tsx index 19b293c20..47d173953 100644 --- a/app/frontend/src/javascript/components/base/text-editor/fab-text-editor.tsx +++ b/app/frontend/src/javascript/components/base/text-editor/fab-text-editor.tsx @@ -9,6 +9,7 @@ import Placeholder from '@tiptap/extension-placeholder'; import CharacterCount from '@tiptap/extension-character-count'; import Underline from '@tiptap/extension-underline'; import Link from '@tiptap/extension-link'; +import Iframe from './iframe'; import { MenuBar } from './menu-bar'; import { WarningOctagon } from 'phosphor-react'; @@ -51,7 +52,8 @@ export const FabTextEditor: React.FC = ({ label, paragraphTo }), CharacterCount.configure({ limit - }) + }), + Iframe ], content, onUpdate: ({ editor }) => { diff --git a/app/frontend/src/javascript/components/base/text-editor/iframe.tsx b/app/frontend/src/javascript/components/base/text-editor/iframe.tsx new file mode 100644 index 000000000..0263800f9 --- /dev/null +++ b/app/frontend/src/javascript/components/base/text-editor/iframe.tsx @@ -0,0 +1,76 @@ +import { Node } from '@tiptap/core'; + +export interface IframeOptions { + allowFullscreen: boolean, + HTMLAttributes: { + [key: string]: any + }, +} + +declare module '@tiptap/core' { + interface Commands { + iframe: { + /** + * Add an iframe to embed a video + */ + setIframe: (options: { src: string }) => ReturnType, + } + } +} + +export default Node.create({ + name: 'iframe', + + group: 'block', + + atom: true, + + addOptions () { + return { + allowFullscreen: true, + HTMLAttributes: { + class: 'fab-textEditor-video' + } + }; + }, + + addAttributes () { + return { + src: { + default: null + }, + frameborder: { + default: 0 + }, + allowfullscreen: { + default: this.options.allowFullscreen, + parseHTML: () => this.options.allowFullscreen + } + }; + }, + + parseHTML () { + return [{ + tag: 'iframe' + }]; + }, + + renderHTML ({ HTMLAttributes }) { + return ['div', this.options.HTMLAttributes, ['iframe', HTMLAttributes]]; + }, + + addCommands () { + return { + setIframe: (options: { src: string }) => ({ tr, dispatch }) => { + const { selection } = tr; + const node = this.type.create(options); + + if (dispatch) { + tr.replaceRangeWith(selection.from, selection.to, node); + } + + return true; + } + }; + } +}); diff --git a/app/frontend/src/javascript/components/base/text-editor/menu-bar.tsx b/app/frontend/src/javascript/components/base/text-editor/menu-bar.tsx index 4d19ae195..0448aa3c6 100644 --- a/app/frontend/src/javascript/components/base/text-editor/menu-bar.tsx +++ b/app/frontend/src/javascript/components/base/text-editor/menu-bar.tsx @@ -2,17 +2,18 @@ import React, { useCallback, useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import useOnclickOutside from 'react-cool-onclickoutside'; import { Editor } from '@tiptap/react'; -import { TextAa, TextBolder, TextItalic, TextUnderline, LinkSimpleHorizontal, ListBullets, Quotes, Trash, CheckCircle } from 'phosphor-react'; +import { TextAa, TextBolder, TextItalic, TextUnderline, LinkSimpleHorizontal, ListBullets, Quotes, Trash, CheckCircle, VideoCamera } from 'phosphor-react'; interface MenuBarProps { paragraphTools?: boolean, + extra?: boolean, editor?: Editor, } /** * This component is the menu bar for the WYSIWYG text editor */ -export const MenuBar: React.FC = ({ editor, paragraphTools }) => { +export const MenuBar: React.FC = ({ editor, paragraphTools, extra }) => { const { t } = useTranslation('shared'); const [linkMenu, setLinkMenu] = useState(false); @@ -83,6 +84,11 @@ export const MenuBar: React.FC = ({ editor, paragraphTools }) => { setLinkMenu(false); }; + // Add iFrame + const addIframe = () => { + editor.chain().focus().setIframe({ src: 'https://www.youtube.com/embed/XIMLoLxmTDw' }).run(); + }; + if (!editor) { return null; } @@ -144,6 +150,16 @@ export const MenuBar: React.FC = ({ editor, paragraphTools }) => { > + { extra && + (<> + + ) + }
diff --git a/app/frontend/src/stylesheets/modules/base/fab-text-editor.scss b/app/frontend/src/stylesheets/modules/base/fab-text-editor.scss index cdcbaa7d0..5ec63f5a2 100644 --- a/app/frontend/src/stylesheets/modules/base/fab-text-editor.scss +++ b/app/frontend/src/stylesheets/modules/base/fab-text-editor.scss @@ -144,6 +144,15 @@ } } + &-video { + position: relative; + height: 0; + width: 100%; + max-width: 600px; + padding-bottom: calc(100 / 16 * 9); + overflow: hidden; + } + &-error { position: absolute; top: 4.5rem;