Skip to content

Commit

Permalink
Merge pull request #173 from dappforce/fix/youtube-fallback
Browse files Browse the repository at this point in the history
Add youtube thumbnail fallbacks
  • Loading branch information
olehmell authored Jan 16, 2024
2 parents 960ac1a + 315641f commit 5ff7926
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 30 deletions.
4 changes: 3 additions & 1 deletion src/components/posts/editor/HtmlEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export interface HTMLEditorProps {
saveBodyDraft?: (body: string) => void
className?: string
showToolbar?: boolean
autoFocus?: boolean
}

export default function HtmlEditor({
Expand All @@ -16,13 +17,14 @@ export default function HtmlEditor({
saveBodyDraft,
className,
showToolbar,
autoFocus,
}: HTMLEditorProps) {
const editor = useCreateEditor(onChange, value, saveBodyDraft)

return (
<>
{showToolbar && <ToolBar editor={editor} />}
<EditorContent tabIndex={0} className={className} editor={editor} />
<EditorContent autoFocus tabIndex={0} className={className} editor={editor} />
</>
)
}
6 changes: 5 additions & 1 deletion src/components/posts/editor/ModalEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,11 @@ export const PostEditorModalBody = ({
<SpaceSelector />
<Form.Item name={fieldName('body')} className='my-3'>
{/* value and onChange are provided by Form.Item */}
<HtmlEditor saveBodyDraft={saveDraft} className={clsx(styles.FastEditor, 'ant-input')} />
<HtmlEditor
autoFocus
saveBodyDraft={saveDraft}
className={clsx(styles.FastEditor, 'ant-input')}
/>
</Form.Item>
{imgUrl && (
<PreviewUploadedImage
Expand Down
83 changes: 67 additions & 16 deletions src/components/posts/embed/Embed.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import clsx from 'clsx'
import { useMemo } from 'react'
import { useEffect, useMemo, useRef, useState } from 'react'
import LiteYouTubeEmbed from 'react-lite-youtube-embed'
import styles from './Embed.module.sass'

Expand Down Expand Up @@ -78,27 +78,78 @@ const Embed = ({ link, className }: EmbedProps) => {
)
}

const thumbnail = ['maxresdefault', 'mqdefault', 'sddefault', 'hqdefault', 'default'] as const
export type ThumbnailRes = (typeof thumbnail)[number]

export function YoutubeThumbnailChecker({
setThumbnailRes,
src,
}: {
src: string
setThumbnailRes: (res: ThumbnailRes) => void
}) {
const currentRetries = useRef(0)
const imgRef = useRef<HTMLImageElement | null>(null)
const youtubeId = useMemo(() => getYoutubeVideoId(src), [src])
const [res, setRes] = useState(0)
useEffect(() => {
setThumbnailRes(thumbnail[res])
}, [res])

useEffect(() => {
function checkImage() {
if (imgRef.current?.complete) {
if (imgRef.current.naturalWidth === 120 && imgRef.current.naturalHeight === 90) {
if (res < thumbnail.length - 1) {
setRes(res + 1)
}
}
} else {
currentRetries.current++
if (currentRetries.current <= 5)
setTimeout(() => {
checkImage()
}, 200)
}
}
checkImage()
}, [res])

return (
<img
ref={imgRef}
style={{ display: 'none' }}
src={`https://i3.ytimg.com/vi/${youtubeId}/${thumbnail[res]}.jpg`}
/>
)
}

function YoutubeEmbed({ src }: { src: string }) {
const youtubeId = useMemo(() => getYoutubeVideoId(src), [src])
const [thumbnailRes, setThumbnailRes] = useState<ThumbnailRes>('maxresdefault')
console.log(thumbnailRes)

if (!youtubeId) return null

return (
<LiteYouTubeEmbed
id={youtubeId}
adNetwork={true}
params=''
playlist={false}
poster='maxresdefault'
title='YouTube Embed'
noCookie={true}
wrapperClass={clsx(styles.YoutubeEmbedWrapper)}
activatedClass='youtube-activated'
playerClass={clsx(styles.YoutubeEmbedPlayer)}
iframeClass={styles.YoutubeEmbedIframe}
aspectHeight={9}
aspectWidth={16}
/>
<>
<YoutubeThumbnailChecker src={src} setThumbnailRes={setThumbnailRes} />
<LiteYouTubeEmbed
id={youtubeId}
adNetwork={true}
params=''
playlist={false}
poster={thumbnailRes}
title='YouTube Embed'
noCookie={true}
wrapperClass={clsx(styles.YoutubeEmbedWrapper)}
activatedClass='youtube-activated'
playerClass={clsx(styles.YoutubeEmbedPlayer)}
iframeClass={styles.YoutubeEmbedIframe}
aspectHeight={9}
aspectWidth={16}
/>
</>
)
}

Expand Down
14 changes: 2 additions & 12 deletions src/components/posts/view-post/PostPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { getPostIdFromSlug } from '@subsocial/utils/slugify'
import clsx from 'clsx'
import { NextPage } from 'next'
import router from 'next/router'
import { FC, useEffect } from 'react'
import { FC } from 'react'
import { CommentSection } from 'src/components/comments/CommentsSection'
import MobileStakerRewardDashboard from 'src/components/creators/MobileStakerRewardDashboard'
import { PageContent } from 'src/components/main/PageWrapper'
Expand All @@ -17,7 +17,7 @@ import { return404 } from 'src/components/utils/next'
import config from 'src/config'
import { resolveIpfsUrl } from 'src/ipfs'
import { getInitialPropsWithRedux, NextContextWithRedux } from 'src/rtk/app'
import { useSelectProfile, useSetChatEntityConfig } from 'src/rtk/app/hooks'
import { useSelectProfile } from 'src/rtk/app/hooks'
import { useAppSelector } from 'src/rtk/app/store'
import { fetchPost, fetchPosts, selectPost } from 'src/rtk/features/posts/postsSlice'
import { useFetchMyReactionsByPostId } from 'src/rtk/features/reactions/myPostReactionsHooks'
Expand Down Expand Up @@ -59,16 +59,6 @@ const InnerPostPage: NextPage<PostDetailsProps> = props => {
const { post, space } = postData
const { struct, content } = post

const setChatConfig = useSetChatEntityConfig()
useEffect(() => {
if (!post) return
setChatConfig({ entity: { data: post, type: 'post' }, withFloatingButton: true })

return () => {
setChatConfig(null)
}
}, [])

const goToCommentsId = 'comments'

const profile = useSelectProfile(postData.post.struct.ownerId)
Expand Down

0 comments on commit 5ff7926

Please sign in to comment.