This commit is contained in:
@@ -10,6 +10,32 @@
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.markdown-video-container {
|
||||
width: 100%;
|
||||
margin: 16px 0;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
background: #0a0a1a;
|
||||
border: 1px solid rgba(0, 243, 255, 0.3);
|
||||
box-shadow: 0 0 20px rgba(0, 243, 255, 0.1);
|
||||
|
||||
.markdown-video {
|
||||
width: 100%;
|
||||
height: 225px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.markdown-video-caption {
|
||||
padding: 12px;
|
||||
background: rgba(10, 10, 26, 0.9);
|
||||
color: rgba(0, 243, 255, 0.9);
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.markdown-code-block {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useMemo } from 'react'
|
||||
import { View, RichText } from '@tarojs/components'
|
||||
import { View, RichText, Video } from '@tarojs/components'
|
||||
import { marked, Renderer } from 'marked'
|
||||
import CodeBlock from './CodeBlock'
|
||||
import './index.scss'
|
||||
@@ -51,6 +51,11 @@ const MarkdownReader: React.FC<Props> = ({ content, themeColor = '#00b96b' }) =>
|
||||
// Process tokens
|
||||
tokens.forEach((token, index) => {
|
||||
if (token.type === 'code') {
|
||||
// Skip css blocks that look like the video component styles
|
||||
if ((token.lang === 'css' || !token.lang) && token.text.includes('.simple-tech-video')) {
|
||||
return
|
||||
}
|
||||
|
||||
// Flush accumulated tokens
|
||||
if (currentTokens.length > 0) {
|
||||
// preserve links if any
|
||||
@@ -69,6 +74,57 @@ const MarkdownReader: React.FC<Props> = ({ content, themeColor = '#00b96b' }) =>
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
} else if (token.type === 'html') {
|
||||
// Check for video tag
|
||||
const videoRegex = /<video[^>]*>[\s\S]*?<source[^>]*src=["'](.*?)["'][^>]*>[\s\S]*?<\/video>/i
|
||||
const simpleVideoRegex = /<video[^>]*src=["'](.*?)["'][^>]*>/i
|
||||
|
||||
const match = token.text.match(videoRegex) || token.text.match(simpleVideoRegex)
|
||||
|
||||
if (match) {
|
||||
// Flush accumulated tokens
|
||||
if (currentTokens.length > 0) {
|
||||
(currentTokens as any).links = (tokens as any).links
|
||||
const html = marked.parser(currentTokens as any, { renderer, breaks: true })
|
||||
result.push(<RichText key={`rt-${index}`} nodes={html} className='markdown-text' />)
|
||||
currentTokens = []
|
||||
}
|
||||
|
||||
const src = match[1]
|
||||
// Try to extract caption
|
||||
const captionRegex = /class=["']video-caption["'][^>]*>(.*?)<\/div>/i
|
||||
const captionMatch = token.text.match(captionRegex)
|
||||
const caption = captionMatch ? captionMatch[1] : null
|
||||
|
||||
result.push(
|
||||
<View key={`video-${index}`} className='markdown-video-container'>
|
||||
<Video
|
||||
src={src}
|
||||
className='markdown-video'
|
||||
controls
|
||||
autoplay={false}
|
||||
objectFit='contain'
|
||||
showFullscreenBtn
|
||||
showPlayBtn
|
||||
showCenterPlayBtn
|
||||
enablePlayGesture
|
||||
/>
|
||||
{caption && <View className='markdown-video-caption'>{caption}</View>}
|
||||
</View>
|
||||
)
|
||||
} else {
|
||||
// Filter out style tags for video component if they are parsed as HTML
|
||||
if (token.text.includes('<style>') && token.text.includes('.simple-tech-video')) {
|
||||
// If it's JUST the style tag, ignore it. If it's mixed with other content, we might need to be careful.
|
||||
// But usually marked parses block HTML separately.
|
||||
// Let's verify if we can just skip it.
|
||||
// If the token is ONLY the style block, we skip it.
|
||||
// If it contains other content, we might need to strip the style.
|
||||
// For now, let's assume it's a block HTML token.
|
||||
return
|
||||
}
|
||||
currentTokens.push(token)
|
||||
}
|
||||
} else {
|
||||
currentTokens.push(token)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user