feat: add TikTok embed support
This commit is contained in:
@@ -23,8 +23,9 @@ import {
|
||||
ThumbnailContent,
|
||||
UnsupportedContent,
|
||||
VideoContent,
|
||||
VideoFrameThumbnail,
|
||||
} from './message';
|
||||
import { UrlPreviewCard, UrlPreviewHolder, YouTubeEmbed, isYouTubeUrl } from './url-preview';
|
||||
import { UrlPreviewCard, UrlPreviewHolder, YouTubeEmbed, isYouTubeUrl, TikTokEmbed, isTikTokUrl } from './url-preview';
|
||||
import { Image, MediaControl, Video } from './media';
|
||||
import { ImageViewer } from './image-viewer';
|
||||
import { PdfViewer } from './Pdf-viewer';
|
||||
@@ -66,16 +67,21 @@ export function RenderMessageContent({
|
||||
filteredUrls = filterDisabledUrls(filteredUrls, disabledEmbedPatterns ?? []);
|
||||
if (filteredUrls.length === 0) return undefined;
|
||||
|
||||
// Separate YouTube URLs from other URLs
|
||||
// Separate special URLs from generic ones
|
||||
const youtubeUrls = filteredUrls.filter(isYouTubeUrl);
|
||||
const otherUrls = filteredUrls.filter((url) => !isYouTubeUrl(url));
|
||||
const tiktokUrls = filteredUrls.filter(isTikTokUrl);
|
||||
const otherUrls = filteredUrls.filter((url) => !isYouTubeUrl(url) && !isTikTokUrl(url));
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Render YouTube embeds (ad-free via Piped) */}
|
||||
{/* Render YouTube embeds (ad-free via yt-dlp) */}
|
||||
{youtubeUrls.map((url) => (
|
||||
<YouTubeEmbed key={url} url={url} />
|
||||
))}
|
||||
{/* Render TikTok embeds */}
|
||||
{tiktokUrls.map((url) => (
|
||||
<TikTokEmbed key={url} url={url} />
|
||||
))}
|
||||
{/* Render standard URL previews for other links */}
|
||||
{otherUrls.length > 0 && (
|
||||
<UrlPreviewHolder>
|
||||
@@ -227,26 +233,47 @@ export function RenderMessageContent({
|
||||
<MVideo
|
||||
content={getContent()}
|
||||
renderAsFile={renderFile}
|
||||
renderVideoContent={({ body, info, ...props }) => (
|
||||
<VideoContent
|
||||
body={body}
|
||||
info={info}
|
||||
{...props}
|
||||
renderThumbnail={
|
||||
mediaAutoLoad
|
||||
? () => (
|
||||
<ThumbnailContent
|
||||
info={info}
|
||||
renderImage={(src) => (
|
||||
<Image alt={body} title={body} src={src} loading="lazy" />
|
||||
)}
|
||||
/>
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
renderVideo={(p) => <Video {...p} />}
|
||||
/>
|
||||
)}
|
||||
renderVideoContent={({ body, info, mimeType, url, encInfo, ...props }) => {
|
||||
// Check if there's valid thumbnail metadata
|
||||
const hasValidThumbnail =
|
||||
(typeof info.thumbnail_file?.url === 'string' || typeof info.thumbnail_url === 'string') &&
|
||||
typeof info.thumbnail_info?.mimetype === 'string';
|
||||
|
||||
return (
|
||||
<VideoContent
|
||||
body={body}
|
||||
info={info}
|
||||
mimeType={mimeType}
|
||||
url={url}
|
||||
encInfo={encInfo}
|
||||
{...props}
|
||||
renderThumbnail={
|
||||
mediaAutoLoad
|
||||
? () => hasValidThumbnail ? (
|
||||
// Try to load the provided thumbnail first
|
||||
<ThumbnailContent
|
||||
info={info}
|
||||
renderImage={(src) => (
|
||||
<Image alt={body} title={body} src={src} loading="lazy" />
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
// Fallback: Extract first frame from the video itself
|
||||
<VideoFrameThumbnail
|
||||
mimeType={mimeType}
|
||||
url={url}
|
||||
encInfo={encInfo}
|
||||
renderImage={(src) => (
|
||||
<Image alt={body} title={body} src={src} loading="lazy" />
|
||||
)}
|
||||
/>
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
renderVideo={(p) => <Video {...p} />}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
outlined={outlineAttachment}
|
||||
/>
|
||||
{renderCaption()}
|
||||
|
||||
Reference in New Issue
Block a user