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