diff --git a/app/entities/post/detail/PostBody.tsx b/app/entities/post/detail/PostBody.tsx index 53031c4..b2fd342 100644 --- a/app/entities/post/detail/PostBody.tsx +++ b/app/entities/post/detail/PostBody.tsx @@ -35,6 +35,167 @@ const PostBody = ({ content, tags, loading }: Props) => { } } }; + + const renderOpenGraph = (node: any, index?: number, parent?: Element) => { + if (node.type === 'element' && node.tagName === 'p' && node.children) { + const aTag = node.children.find( + (node: any) => node.type === 'element' && node.tagName === 'a' + ); + if (!aTag) return; + + const href = aTag.properties?.href; + if (href && href.startsWith('/')) { + // 부모가 존재하고 children 배열이 있는 경우 + const opengraph = createOpenGraph(href); + if ( + index !== undefined && + parent && + parent.children && + Array.isArray(parent.children) + ) { + // 현재 a 태그 다음 위치에 div 삽입 s + parent.children.splice(index + 1, 0, opengraph); + } else return; + } + } + }; + + const renderYoutubeEmbed = (node: any, index?: number, parent?: Element) => { + if (node.type === 'element' && node.tagName === 'p' && node.children) { + const aTag = node.children.find( + (node: any) => node.type === 'element' && node.tagName === 'a' + ); + if (!aTag) return; + + const href = aTag.properties?.href; + const isYoutubeLink = + href && + (href.startsWith('https://www.youtube.com/watch') || + href.startsWith('https://youtu.be/')); + + if (isYoutubeLink) { + const urlType = href.startsWith('https://www.youtube.com/watch') + ? 'watch' + : 'be'; + + const videoId = + urlType === 'watch' + ? new URL(href).searchParams.get('v') + : href.split('/').pop(); + + if (videoId) { + const youtubeEmbed = createYoutubeIframe(videoId, 736, 414); + // 부모가 존재하고 children 배열이 있는 경우 + if ( + index && + parent && + parent.children && + Array.isArray(parent.children) + ) { + parent.children.splice(index + 1, 0, youtubeEmbed); + } else return; + } + } + } + }; + + const createYoutubeIframe = ( + videoId: string, + width: number, + height: number + ) => { + return { + type: 'element', + tagName: 'iframe', + properties: { + src: `https://www.youtube.com/embed/${videoId}`, + width: width.toString(), + height: height.toString(), + frameBorder: '0', + allowFullScreen: true, + className: 'youtube-embed', + }, + children: [], + }; + }; + + const createOpenGraph = (href: string) => { + return { + type: 'element', + tagName: 'a', + properties: { + className: 'open-graph', + href: href, + }, + children: [ + { + type: 'element', + tagName: 'img', + properties: { + src: `${href}`, + alt: 'Open Graph Image', + className: 'og-image', + }, + children: [], + }, + { + type: 'element', + tagName: 'div', + properties: { + className: 'og-container', + }, + children: [ + { + type: 'element', + tagName: 'h4', + properties: { + className: 'og-title', + }, + children: [ + { + type: 'text', + value: decodeURIComponent(href.split('/').pop()!).replaceAll( + '-', + ' ' + ), + }, + ], + }, + { + type: 'element', + tagName: 'span', + properties: { + className: 'og-content', + }, + children: [ + // { + // type: 'text', + // value: decodeURIComponent(href.split('/').pop()!).replaceAll( + // '-', + // ' ' + // ), + // }, + ], + }, + { + type: 'element', + tagName: 'span', + properties: { + className: 'og-domain', + }, + children: [ + { + type: 'text', + value: '', + }, + ], + }, + ], + }, + ], + }; + }; + return (