diff options
| author | MohamedBassem <me@mbassem.com> | 2025-08-03 23:35:06 -0700 |
|---|---|---|
| committer | MohamedBassem <me@mbassem.com> | 2025-08-03 23:59:45 -0700 |
| commit | c68e5099797d5b49ed6441ce04d7c77105327f73 (patch) | |
| tree | 296fe5f473f46d802fcf94fa203ca37672112c30 /apps/web/components/dashboard/preview/content-renderers/TikTokRenderer.tsx | |
| parent | 03aa17200ed80c2978bf496991c6afbb5a04258b (diff) | |
| download | karakeep-c68e5099797d5b49ed6441ce04d7c77105327f73.tar.zst | |
feat(web): Add special cards for specific websites. Fixes #1344
Diffstat (limited to 'apps/web/components/dashboard/preview/content-renderers/TikTokRenderer.tsx')
| -rw-r--r-- | apps/web/components/dashboard/preview/content-renderers/TikTokRenderer.tsx | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/apps/web/components/dashboard/preview/content-renderers/TikTokRenderer.tsx b/apps/web/components/dashboard/preview/content-renderers/TikTokRenderer.tsx new file mode 100644 index 00000000..ecd0c956 --- /dev/null +++ b/apps/web/components/dashboard/preview/content-renderers/TikTokRenderer.tsx @@ -0,0 +1,68 @@ +import { Video } from "lucide-react"; + +import { BookmarkTypes, ZBookmark } from "@karakeep/shared/types/bookmarks"; + +import { ContentRenderer } from "./types"; + +function extractTikTokVideoId(url: string): string | null { + const patterns = [ + /tiktok\.com\/@[^/]+\/video\/(\d+)/, + /tiktok\.com\/t\/([A-Za-z0-9]+)/, + /vm\.tiktok\.com\/([A-Za-z0-9]+)/, + /tiktok\.com\/v\/(\d+)/, + ]; + + for (const pattern of patterns) { + const match = url.match(pattern); + if (match) { + return match[1]; + } + } + return null; +} + +function canRenderTikTok(bookmark: ZBookmark): boolean { + if (bookmark.content.type !== BookmarkTypes.LINK) { + return false; + } + + const url = bookmark.content.url; + return extractTikTokVideoId(url) !== null; +} + +function TikTokRendererComponent({ bookmark }: { bookmark: ZBookmark }) { + if (bookmark.content.type !== BookmarkTypes.LINK) { + return null; + } + + const videoId = extractTikTokVideoId(bookmark.content.url); + if (!videoId) { + return null; + } + + // TikTok embed URL format + const embedUrl = `https://www.tiktok.com/embed/v2/${videoId}`; + + return ( + <div className="relative h-full w-full overflow-hidden"> + <div className="absolute inset-0 h-full w-full"> + <iframe + src={embedUrl} + title="TikTok video" + className="h-full w-full border-0" + allow="encrypted-media" + sandbox="allow-scripts allow-same-origin allow-popups" + /> + </div> + </div> + ); +} + +export const tikTokRenderer: ContentRenderer = { + id: "tiktok", + name: "TikTok", + icon: Video, + canRender: canRenderTikTok, + component: TikTokRendererComponent, + priority: 10, +}; |
