Skip to content

Commit c169707

Browse files
committed
Merge branch 'preview'
2 parents e699d68 + 8f0c273 commit c169707

File tree

4 files changed

+94
-15
lines changed

4 files changed

+94
-15
lines changed

package-lock.json

Lines changed: 38 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"@uidotdev/usehooks": "^2.4.1",
3434
"@vercel/analytics": "^1.3.1",
3535
"@vercel/speed-insights": "^1.0.12",
36+
"@vidstack/react": "^1.12.9",
3637
"browser-image-compression": "^2.0.2",
3738
"emoji-mart": "^5.6.0",
3839
"jwt-decode": "^4.0.0",

src/components/dataDisplay/postEmbed/PostEmbed.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import {
77
AppBskyEmbedRecordWithMedia,
88
AppBskyGraphDefs,
99
AppBskyFeedDefs,
10+
AppBskyEmbedVideo,
1011
} from "@atproto/api";
1112
import RecordEmbed from "./RecordEmbed";
1213
import ListEmbed from "./ListEmbed";
1314
import FeedEmbed from "./FeedEmbed";
15+
import VideoEmbed from "./VideoEmbed";
1416

1517
interface Props {
1618
content: AppBskyFeedDefs.FeedViewPost["post"]["embed"];
@@ -54,6 +56,15 @@ export default function PostEmbed(props: Props) {
5456
depth={depth}
5557
/>
5658
);
59+
} else if (AppBskyEmbedVideo.isView(content)) {
60+
return (
61+
<VideoEmbed
62+
aspectRatio={`${content.aspectRatio?.width}/${content.aspectRatio?.height}`}
63+
playlist={content.playlist}
64+
thumbnail={content.thumbnail}
65+
alt={content.alt}
66+
/>
67+
);
5768
}
5869
};
5970

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { memo } from "react";
2+
import { MediaPlayer, MediaProvider, Poster } from "@vidstack/react";
3+
import {
4+
defaultLayoutIcons,
5+
DefaultVideoLayout,
6+
} from "@vidstack/react/player/layouts/default";
7+
import "@vidstack/react/player/styles/default/theme.css";
8+
import "@vidstack/react/player/styles/default/layouts/video.css";
9+
10+
interface Props {
11+
aspectRatio: string;
12+
playlist: string;
13+
thumbnail?: string;
14+
alt?: string;
15+
}
16+
17+
const VideoEmbed = memo(function VideoEmbed(props: Props) {
18+
const { aspectRatio, playlist, thumbnail, alt } = props;
19+
20+
return (
21+
<MediaPlayer
22+
crossOrigin
23+
playsInline
24+
viewType="video"
25+
className="mt-2 hover:brightness-90 hover:cursor-pointer"
26+
src={playlist}
27+
poster={thumbnail ?? ""}
28+
onClick={(e) => e.stopPropagation()}
29+
>
30+
<MediaProvider>
31+
{alt && (
32+
<Poster
33+
src={thumbnail}
34+
alt={alt}
35+
className="absolute inset-0 block bg-black opacity-0 transition-opacity data-[visible]:opacity-100 [&>img]:w-full [&>img]:object-contain"
36+
/>
37+
)}
38+
</MediaProvider>
39+
<DefaultVideoLayout thumbnails={thumbnail} icons={defaultLayoutIcons} />
40+
</MediaPlayer>
41+
);
42+
});
43+
44+
export default VideoEmbed;

0 commit comments

Comments
 (0)