This repository has no description
0

Configure Feed

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

feat: bluesky video embed player

+78 -3
+27
package-lock.json
··· 12968 12968 } 12969 12969 } 12970 12970 }, 12971 + "node_modules/@vidstack/react": { 12972 + "version": "1.12.13", 12973 + "resolved": "https://registry.npmjs.org/@vidstack/react/-/react-1.12.13.tgz", 12974 + "integrity": "sha512-zyNydy1+HtoK6cJ8EmqFNkPPGHIFMrr2KH+ef3654EqXx4IcJ8A5LCNMXBuALQE8IMxtk040JMoR9OKyeXjBOQ==", 12975 + "license": "MIT", 12976 + "dependencies": { 12977 + "@floating-ui/dom": "^1.6.10", 12978 + "media-captions": "^1.0.4" 12979 + }, 12980 + "engines": { 12981 + "node": ">=18" 12982 + }, 12983 + "peerDependencies": { 12984 + "@types/react": "^18.0.0 || ^19.0.0", 12985 + "react": "^18.0.0 || ^19.0.0" 12986 + } 12987 + }, 12971 12988 "node_modules/@vitest/browser": { 12972 12989 "version": "4.1.5", 12973 12990 "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-4.1.5.tgz", ··· 22932 22949 "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", 22933 22950 "devOptional": true 22934 22951 }, 22952 + "node_modules/media-captions": { 22953 + "version": "1.0.4", 22954 + "resolved": "https://registry.npmjs.org/media-captions/-/media-captions-1.0.4.tgz", 22955 + "integrity": "sha512-cyDNmuZvvO4H27rcBq2Eudxo9IZRDCOX/I7VEyqbxsEiD2Ei7UYUhG/Sc5fvMZjmathgz3fEK7iAKqvpY+Ux1w==", 22956 + "license": "MIT", 22957 + "engines": { 22958 + "node": ">=16" 22959 + } 22960 + }, 22935 22961 "node_modules/media-typer": { 22936 22962 "version": "1.1.0", 22937 22963 "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", ··· 32160 32186 "@tanstack/react-query": "^5.85.5", 32161 32187 "@types/mdx": "^2.0.13", 32162 32188 "@vercel/analytics": "^1.5.0", 32189 + "@vidstack/react": "^1.12.13", 32163 32190 "capnweb": "^0.6.1", 32164 32191 "date-fns": "^4.1.0", 32165 32192 "dayjs": "^1.11.13",
+50 -3
src/webapp/features/platforms/bluesky/components/videoEmbed/VideoEmbed.tsx
··· 1 + 'use client'; 2 + 1 3 import { AppBskyEmbedVideo } from '@atproto/api'; 2 - import { AspectRatio, Image } from '@mantine/core'; 4 + import { AspectRatio } from '@mantine/core'; 5 + import { 6 + MediaPlayer, 7 + MediaProvider, 8 + MuteButton, 9 + MuteButtonInstance, 10 + PlayButton, 11 + VolumeSlider, 12 + VolumeSliderInstance, 13 + } from '@vidstack/react'; 14 + import { 15 + defaultLayoutIcons, 16 + DefaultVideoLayout, 17 + } from '@vidstack/react/player/layouts/default'; 18 + import '@vidstack/react/player/styles/default/theme.css'; 19 + import '@vidstack/react/player/styles/default/layouts/video.css'; 3 20 4 21 interface Props { 5 22 embed: AppBskyEmbedVideo.View; 6 23 } 7 24 8 25 export default function VideoEmbed(props: Props) { 26 + const ratio = props.embed.aspectRatio 27 + ? props.embed.aspectRatio.width / props.embed.aspectRatio.height 28 + : 16 / 9; 29 + 9 30 return ( 10 - <AspectRatio ratio={16 / 9}> 11 - <Image src={props.embed.thumbnail} alt={props.embed.alt} radius={'sm'} /> 31 + <AspectRatio ratio={ratio}> 32 + <MediaPlayer 33 + crossOrigin 34 + playsInline 35 + viewType="video" 36 + src={props.embed.playlist} 37 + poster={props.embed.thumbnail ?? ''} 38 + onClick={(e) => e.stopPropagation()} 39 + style={{ 40 + width: '100%', 41 + height: '100%', 42 + borderRadius: 'var(--mantine-radius-md)', 43 + overflow: 'hidden', 44 + '--video-border': '0px', 45 + }} 46 + > 47 + <MediaProvider /> 48 + <DefaultVideoLayout 49 + thumbnails={props.embed.thumbnail} 50 + icons={defaultLayoutIcons} 51 + slots={{ 52 + settingsMenu: null, 53 + captionButton: null, 54 + airPlayButton: null, 55 + googleCastButton: null, 56 + }} 57 + /> 58 + </MediaPlayer> 12 59 </AspectRatio> 13 60 ); 14 61 }
+1
src/webapp/package.json
··· 44 44 "@tanstack/react-query": "^5.85.5", 45 45 "@types/mdx": "^2.0.13", 46 46 "@vercel/analytics": "^1.5.0", 47 + "@vidstack/react": "^1.12.13", 47 48 "capnweb": "^0.6.1", 48 49 "date-fns": "^4.1.0", 49 50 "dayjs": "^1.11.13",