diff --git a/components/media-or-link.js b/components/media-or-link.js
index fa36842f..5b42efe8 100644
--- a/components/media-or-link.js
+++ b/components/media-or-link.js
@@ -1,5 +1,5 @@
import styles from './text.module.css'
-import { useState, useEffect, useMemo, useCallback, memo } from 'react'
+import { useState, useEffect, useMemo, useCallback, memo, useRef } from 'react'
import { decodeProxyUrl, IMGPROXY_URL_REGEXP, MEDIA_DOMAIN_REGEXP } from '@/lib/url'
import { useMe } from './me'
import { UNKNOWN_LINK_REL } from '@/lib/constants'
@@ -23,13 +23,31 @@ const Media = memo(function Media ({
src, bestResSrc, srcSet, sizes, width,
height, onClick, onError, style, className, video
}) {
+ const [loaded, setLoaded] = useState(!video)
+ const ref = useRef(null)
+
+ const handleLoadedMedia = () => {
+ setLoaded(true)
+ }
+
+ // events are not fired on elements during hydration
+ // https://github.com/facebook/react/issues/15446
+ useEffect(() => {
+ if (ref.current) {
+ ref.current.src = src
+ }
+ }, [ref.current, src])
+
return (
{video
?
:
}
)
@@ -101,21 +122,28 @@ export const useMediaHelper = ({ src, srcSet: srcSetIntital, topLevel, tab }) =>
useEffect(() => {
// don't load the video at all if user doesn't want these
if (!showMedia || isVideo || isImage) return
- // make sure it's not a false negative by trying to load URL as
- const img = new window.Image()
- img.onload = () => setIsImage(true)
- img.src = src
+
+ // check if it's a video by trying to load it
const video = document.createElement('video')
- video.onloadeddata = () => setIsVideo(true)
+ video.onloadedmetadata = () => {
+ setIsVideo(true)
+ setIsImage(false)
+ }
+ video.onerror = () => {
+ // hack
+ // if it's not a video it will throw an error, so we can assume it's an image
+ const img = new window.Image()
+ img.onload = () => setIsImage(true)
+ img.src = src
+ }
video.src = src
return () => {
- img.onload = null
- img.src = ''
- video.onloadeddata = null
+ video.onloadedmetadata = null
+ video.onerror = null
video.src = ''
}
- }, [src, setIsImage, setIsVideo, showMedia, isVideo])
+ }, [src, setIsImage, setIsVideo, showMedia, isImage])
const srcSet = useMemo(() => {
if (Object.keys(srcSetObj).length === 0) return undefined
diff --git a/components/text.module.css b/components/text.module.css
index ff99b8a9..faa1f1e3 100644
--- a/components/text.module.css
+++ b/components/text.module.css
@@ -184,10 +184,14 @@
.p:has(> .mediaContainer) .mediaContainer
{
display: flex;
- width: min-content;
max-width: 100%;
}
+.p:has(> .mediaContainer) .mediaContainer.loaded
+{
+ width: min-content;
+}
+
.p:has(> .mediaContainer) .mediaContainer img,
.p:has(> .mediaContainer) .mediaContainer video
{