import { Editor } from '@tiptap/react' import { useState } from 'react' import { TwitterTweetEmbed } from 'react-twitter-embed' import { Button } from '../button' import { RichContent } from '../editor' import { Col } from '../layout/col' import { Modal } from '../layout/modal' import { Row } from '../layout/row' import { Spacer } from '../layout/spacer' function isValidIframe(text: string) { return /^$/.test(text) } // A valid tweet URL looks like 'https://twitter.com/username/status/123456789' // Return the tweetId if the URL is valid, otherwise return null. function getTweetId(text: string) { const match = text.match(/^https?:\/\/twitter\.com\/.*\/status\/(\d+)/) return match ? match[1] : null } // Manifold URL: https://manifold.markets/Austin/will-manifold-ever-be-worth-1b function getManifoldSlug(text: string) { const match = text.match(/^https?:\/\/manifold\.markets\/([^\/]+)\/([^\/]+)/) return match ? [match[1], match[2]] : null } // Youtube URL: 'https://www.youtube.com/watch?v=ziq7FUKpCS8' function getYoutubeId(text: string) { const match = text.match(/^https?:\/\/www\.youtube\.com\/watch\?v=([^&]+)/) return match ? match[1] : null } // Metaculus URL: 'https://www.metaculus.com/questions/5320/chinese-annexation-of-half-of-taiwan-by-2050/' function getMetaculusId(text: string) { const match = text.match(/^https?:\/\/www\.metaculus\.com\/questions\/(\d+)/) return match ? match[1] : null } function isValidUrl(text: string) { // Conjured by Codex return /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/.test( text ) } function embedCode(text: string) { if (isValidIframe(text)) { return text } else if (getTweetId(text)) { // Append a leading 't', to prevent tweetId from being interpreted as a number. // If it's a number, there may be numeric precision issues. return `` } else if (getManifoldSlug(text)) { const [username, slug] = getManifoldSlug(text) as [string, string] return `` } else if (getYoutubeId(text)) { return `` } else if (getMetaculusId(text)) { return `` } else if (isValidUrl(text)) { return `` } // Return null if the text is not embeddable. return null } export function EmbedModal(props: { editor: Editor | null open: boolean setOpen: (open: boolean) => void }) { const { editor, open, setOpen } = props const [input, setInput] = useState('') const embed = embedCode(input) return ( setInput(e.target.value)} /> {/* Preview the embed if it's valid */} {embed ? : } ) }