Skip to content

Commit

Permalink
feat(tiptap): Loom embed extension (#8612)
Browse files Browse the repository at this point in the history
* feat(tiptap): Loom embed extension

* Use read-only approach

* Increase margins + refactor HTML a bit

* Fix/improve regexp
  • Loading branch information
jmtaber129 authored Aug 21, 2023
1 parent 9b92924 commit e1e6958
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {Link} from '@mui/icons-material'
import {Editor as EditorState} from '@tiptap/core'
import {BubbleMenu, EditorContent, JSONContent, PureEditorContent, useEditor} from '@tiptap/react'
import areEqual from 'fbjs/lib/areEqual'
import React, {useCallback, useEffect, useRef, useState} from 'react'
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'
import {PALETTE} from '~/styles/paletteV3'
import {Radius} from '~/types/constEnums'
import BaseButton from '../BaseButton'
Expand All @@ -12,6 +12,7 @@ import EditorLinkViewerTipTap from '../EditorLinkViewer/EditorLinkViewerTipTap'
import EmojiMenuTipTap from './EmojiMenuTipTap'
import MentionsTipTap from './MentionsTipTap'
import {createEditorExtensions, getLinkProps, LinkMenuProps, LinkPreviewProps} from './tiptapConfig'
import {unfurlLoomLinks} from './loomExtension'

const LinkIcon = styled(Link)({
height: 18,
Expand Down Expand Up @@ -134,7 +135,7 @@ interface Props {
const PromptResponseEditor = (props: Props) => {
const {
autoFocus: autoFocusProp,
content,
content: rawContent,
handleSubmit,
readOnly,
placeholder,
Expand All @@ -144,6 +145,11 @@ const PromptResponseEditor = (props: Props) => {
const [isEditing, setIsEditing] = useState(false)
const [autoFocus, setAutoFocus] = useState(autoFocusProp)

const content = useMemo(
() => (rawContent && readOnly ? unfurlLoomLinks(rawContent) : rawContent),
[rawContent, readOnly]
)

const [linkOverlayProps, setLinkOverlayProps] = useState<
| {
linkMenuProps: LinkMenuProps
Expand Down
89 changes: 89 additions & 0 deletions packages/client/components/promptResponse/loomExtension.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import {Node} from '@tiptap/core'
import {JSONContent, mergeAttributes} from '@tiptap/react'

const LOOM_REGEX = /^(?:https?:\/\/)?(?:www\.)?loom\.com\/share\/[a-zA-Z0-9]+/g

export const unfurlLoomLinks = (rawContent: JSONContent): JSONContent => {
if (!rawContent.content) {
return rawContent
}

const newContent: JSONContent[] = []
rawContent.content.forEach((content) => {
if (content.type === 'paragraph') {
newContent.push(content, ...getLoomNodesForParagraph(content))
} else {
newContent.push(unfurlLoomLinks(content))
}
})

return {
type: rawContent.type,
content: newContent
}
}

const getLoomNodesForParagraph = (content: JSONContent) => {
const distinctLoomLinks: Record<string, string> = {}
content.content?.forEach((subContent) => {
if (subContent.type === 'text') {
const link = subContent.marks?.find((mark) => mark.type === 'link')
if (!link) {
return
}

if (link.attrs?.href.match(LOOM_REGEX)) {
const linkKey = link.attrs.href.split('?')[0]
if (!distinctLoomLinks[linkKey]) {
distinctLoomLinks[linkKey] = link.attrs.href
}
}
}
})

return Object.values(distinctLoomLinks).map((link) => {
return {
type: 'loom',
attrs: {
src: link
}
}
})
}

export const LoomExtension = Node.create({
name: 'loom',

group: 'block',
inline: false,

addAttributes() {
return {
src: {
default: null
}
}
},

renderHTML(props) {
const {HTMLAttributes} = props
const components = HTMLAttributes.src.split('/')
return [
'div',
mergeAttributes(HTMLAttributes, {
style: 'position: relative; padding-bottom: 75%; height: 0; margin: 8px 0px;'
}),
[
'iframe',
{
src: `https://www.loom.com/embed/${components[components.length - 1]}`,
style: 'position: absolute; top: 0; left: 0; width: 100%; height: 100%;',
frameborder: '0',
webkitallowfullscreen: true,
mozallowfullscreen: true,
allowfullscreen: true
}
]
]
}
})
2 changes: 2 additions & 0 deletions packages/client/components/promptResponse/tiptapConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Mention from '@tiptap/extension-mention'
import Placeholder from '@tiptap/extension-placeholder'
import StarterKit from '@tiptap/starter-kit'
import {BBox} from '~/types/animations'
import {LoomExtension} from './loomExtension'

export interface LinkMenuProps {
text: string
Expand Down Expand Up @@ -71,6 +72,7 @@ export const createEditorExtensions = (
placeholder?: string
) => [
StarterKit,
LoomExtension,
Link.extend({
inclusive: false,
addKeyboardShortcuts() {
Expand Down

0 comments on commit e1e6958

Please sign in to comment.