diff --git a/components/embed.js b/components/embed.js index b336fc81e..ecc9b61cd 100644 --- a/components/embed.js +++ b/components/embed.js @@ -1,12 +1,48 @@ -import { memo, useEffect, useRef, useState } from 'react' +import { memo, useEffect, useRef, useState, useCallback } from 'react' import classNames from 'classnames' import useDarkMode from './dark-mode' import styles from './text.module.css' import { Button } from 'react-bootstrap' import { TwitterTweetEmbed } from 'react-twitter-embed' import YouTube from 'react-youtube' +import { useIsClient } from './use-client' +import LoadErrorIcon from '@/svgs/file-warning-line.svg' +import Moon from '@/svgs/moon-fill.svg' +import Link from 'next/link' -function TweetSkeleton ({ className }) { +const Loading = ({ provider, src, className, error }) => { + let host = provider + try { + host = new URL(src).hostname + } catch (e) { + console.error(e) + } + return ( +
+
+ {error ? : } +
{error ? `${provider} embed is not available at the moment.` : `loading ${provider}...`}
+ + view on {host} + +
+
+ ) +} + +const LoaderWrapper = ({ loading, provider, src, children }) => { + console.log('loading', loading) + return ( + <> + {loading && } +
+ {children} +
+ + ) +} + +const TweetSkeleton = ({ className }) => { return (
@@ -21,9 +57,51 @@ function TweetSkeleton ({ className }) { ) } -export const NostrEmbed = memo(function NostrEmbed ({ src, className, topLevel, darkMode, id }) { +const TwitterEmbed = ({ id, className, topLevel, ...props }) => { + const [darkMode] = useDarkMode() + const [overflowing, setOverflowing] = useState(true) const [show, setShow] = useState(false) + + return ( +
+ } + onLoad={() => { props.onLoad(); setOverflowing(true) }} + onError={props.onError} + /> + {overflowing && !show && + } +
+ ) +} + +const YouTubeEmbed = ({ id, className, start, ...props }) => { + return ( +
+ +
+ ) +} + +const NostrEmbed = ({ className, topLevel, id, ...props }) => { const iframeRef = useRef(null) + const [darkMode] = useDarkMode() + const [show, setShow] = useState(false) useEffect(() => { if (!iframeRef.current) return @@ -52,7 +130,7 @@ export const NostrEmbed = memo(function NostrEmbed ({ src, className, topLevel, window?.removeEventListener('message', setHeightFromIframe) iframeRef.current?.removeEventListener('load', handleIframeLoad) } - }, [iframeRef.current, darkMode]) + }, [id, darkMode]) return (
@@ -64,6 +142,7 @@ export const NostrEmbed = memo(function NostrEmbed ({ src, className, topLevel, frameBorder='0' sandbox='allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox' allow='' + {...props} /> {!show && }
) -}) +} -const SpotifyEmbed = function SpotifyEmbed ({ src, className }) { +const SpotifyEmbed = function SpotifyEmbed ({ src, className, ...props }) { const iframeRef = useRef(null) - // https://open.spotify.com/track/1KFxcj3MZrpBGiGA8ZWriv?si=f024c3aa52294aa1 // Remove any additional path segments const url = new URL(src) @@ -84,6 +162,8 @@ const SpotifyEmbed = function SpotifyEmbed ({ src, className }) { useEffect(() => { if (!iframeRef.current) return + console.log('useEffect', iframeRef.current) + console.log('useEffect', url.pathname) const id = url.pathname.split('/').pop() @@ -112,106 +192,102 @@ const SpotifyEmbed = function SpotifyEmbed ({ src, className }) { allow='encrypted-media; clipboard-write;' style={{ borderRadius: '12px' }} sandbox='allow-scripts allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-presentation' + {...props} />
) } -const Embed = memo(function Embed ({ src, provider, id, meta, className, topLevel, onError }) { - const [darkMode] = useDarkMode() - const [overflowing, setOverflowing] = useState(true) - const [show, setShow] = useState(false) - - // This Twitter embed could use similar logic to the video embeds below - if (provider === 'twitter') { - return ( - <> -
- } - onLoad={() => setOverflowing(true)} - /> - {overflowing && !show && - } -
- - ) - } - - if (provider === 'nostr') { - return ( - - ) - } +const WavlakeEmbed = ({ id, className, ...props }) => { + return ( +
+