This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

feat: spotify embed

+95
+5
src/webapp/features/cards/components/urlCardContent/UrlCardContent.tsx
··· 7 7 import { ErrorBoundary } from 'react-error-boundary'; 8 8 import BlueskyPostSkeleton from '@/features/platforms/bluesky/components/blueskyPost/Skeleton.BlueskyPost'; 9 9 import YoutubeVideo from '@/features/platforms/youtube/components/YoutubeVideo/YoutubeVideo'; 10 + import SpotifyEmbed from '@/features/platforms/spotify/components/SpotifyEmbed/SpotifyEmbed'; 10 11 11 12 interface Props { 12 13 url: string; ··· 42 43 43 44 if (platform.type === SupportedPlatform.YOUTUBE_VIDEO) { 44 45 return <YoutubeVideo url={platform.url} cardContent={props.cardContent} />; 46 + } 47 + 48 + if (platform.type === SupportedPlatform.SPOTIFY) { 49 + return <SpotifyEmbed url={platform.url} cardContent={props.cardContent} />; 45 50 } 46 51 47 52 return <LinkCardContent cardContent={props.cardContent} />;
+57
src/webapp/features/platforms/spotify/components/SpotifyEmbed/SpotifyEmbed.tsx
··· 1 + import { getDomain } from '@/lib/utils/link'; 2 + import { Anchor, AspectRatio, Card, Stack, Tooltip } from '@mantine/core'; 3 + import { UrlCard } from '@semble/types'; 4 + import Link from 'next/link'; 5 + import { Fragment } from 'react'; 6 + 7 + interface Props { 8 + url: string; 9 + cardContent: UrlCard['cardContent']; 10 + } 11 + 12 + export default function SpotifyEmbed(props: Props) { 13 + const domain = getDomain(props.url); 14 + 15 + return ( 16 + <Fragment> 17 + <Stack gap={0} flex={1}> 18 + <Tooltip label={props.cardContent.url}> 19 + <Anchor 20 + onClick={(e) => e.stopPropagation()} 21 + component={Link} 22 + href={props.cardContent.url} 23 + target="_blank" 24 + c={'gray'} 25 + lineClamp={1} 26 + w={'fit-content'} 27 + > 28 + {domain} 29 + </Anchor> 30 + </Tooltip> 31 + {props.cardContent.title && ( 32 + <Anchor 33 + onClick={(e) => e.stopPropagation()} 34 + component={Link} 35 + href={props.cardContent.url} 36 + target="_blank" 37 + c={'bright'} 38 + lineClamp={2} 39 + fw={500} 40 + w={'fit-content'} 41 + > 42 + {props.cardContent.title} 43 + </Anchor> 44 + )} 45 + </Stack> 46 + 47 + <Card p={0}> 48 + <iframe 49 + src={props.url} 50 + height={200} 51 + allowFullScreen 52 + style={{ border: 0 }} 53 + /> 54 + </Card> 55 + </Fragment> 56 + ); 57 + }
+33
src/webapp/lib/utils/link.ts
··· 30 30 BLUESKY_POST = 'bluesky post', 31 31 BLACKSKY_POST = 'blacksky post', 32 32 SEMBLE_COLLECTION = 'semble collection', 33 + SPOTIFY = 'spotify', 33 34 YOUTUBE_VIDEO = 'youtube video', 35 + 34 36 DEFAULT = 'default', 35 37 } 36 38 ··· 62 64 return { type: SupportedPlatform.BLACKSKY_POST, url }; 63 65 } 64 66 67 + // youtube 65 68 if (parsedUrl.hostname === 'youtu.be') { 66 69 const videoId = parsedUrl.pathname.split('/')[1]; 67 70 const t = parsedUrl.searchParams.get('t') ?? '0'; ··· 96 99 type: SupportedPlatform.YOUTUBE_VIDEO, 97 100 url: `https://www.youtube.com/embed/${videoId}?start=${seek}`, 98 101 }; 102 + } 103 + 104 + // spotify 105 + if (parsedUrl.hostname === 'open.spotify.com') { 106 + const [__, typeOrLocale, idOrType, id] = parsedUrl.pathname.split('/'); 107 + 108 + if (typeOrLocale === 'album' || idOrType === 'album') { 109 + return { 110 + type: SupportedPlatform.SPOTIFY, 111 + url: `https://open.spotify.com/embed/album/${id ?? idOrType}`, 112 + }; 113 + } 114 + if (typeOrLocale === 'track' || idOrType === 'track') { 115 + return { 116 + type: SupportedPlatform.SPOTIFY, 117 + url: `https://open.spotify.com/embed/track/${id ?? idOrType}`, 118 + }; 119 + } 120 + if (typeOrLocale === 'episode' || idOrType === 'episode') { 121 + return { 122 + type: SupportedPlatform.SPOTIFY, 123 + url: `https://open.spotify.com/embed/episode/${id ?? idOrType}`, 124 + }; 125 + } 126 + if (typeOrLocale === 'show' || idOrType === 'show') { 127 + return { 128 + type: SupportedPlatform.SPOTIFY, 129 + url: `https://open.spotify.com/embed/show/${id ?? idOrType}`, 130 + }; 131 + } 99 132 } 100 133 101 134 return { type: SupportedPlatform.DEFAULT, url }; // no supported service detected