atproto explorer
0
fork

Configure Feed

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

conditionally show video embed

Juliet 71eba81b b60382be

+44 -40
+43 -39
src/components/video-player.tsx
··· 1 1 // courtesy of the best 🐇, my lovely sister mary 2 2 import Hls from "hls.js"; 3 - import { createEffect, createSignal, onCleanup } from "solid-js"; 3 + import { createEffect, createSignal, onCleanup, Show } from "solid-js"; 4 4 5 5 export interface VideoPlayerProps { 6 6 /** Expected to be static */ ··· 10 10 11 11 const VideoPlayer = ({ did, cid }: VideoPlayerProps) => { 12 12 const [playing, setPlaying] = createSignal(false); 13 + const [error, setError] = createSignal(false); 13 14 14 15 const hls = new Hls({ 15 16 capLevelToPlayerSize: true, ··· 27 28 onCleanup(() => hls.destroy()); 28 29 29 30 hls.loadSource(`https://video.cdn.bsky.app/hls/${did}/${cid}/playlist.m3u8`); 31 + hls.on(Hls.Events.ERROR, () => setError(true)); 30 32 31 33 return ( 32 34 <div> 33 - <video 34 - ref={(node) => { 35 - hls.attachMedia(node); 35 + <Show when={!error()}> 36 + <video 37 + ref={(node) => { 38 + hls.attachMedia(node); 36 39 37 - createEffect(() => { 38 - if (!playing()) { 39 - return; 40 - } 40 + createEffect(() => { 41 + if (!playing()) { 42 + return; 43 + } 41 44 42 - const observer = new IntersectionObserver( 43 - (entries) => { 44 - const entry = entries[0]; 45 - if (!entry.isIntersecting) { 46 - node.pause(); 47 - } 48 - }, 49 - { threshold: 0.5 }, 50 - ); 45 + const observer = new IntersectionObserver( 46 + (entries) => { 47 + const entry = entries[0]; 48 + if (!entry.isIntersecting) { 49 + node.pause(); 50 + } 51 + }, 52 + { threshold: 0.5 }, 53 + ); 51 54 52 - onCleanup(() => observer.disconnect()); 55 + onCleanup(() => observer.disconnect()); 53 56 54 - observer.observe(node); 55 - }); 56 - }} 57 - controls 58 - autoplay 59 - muted 60 - playsinline 61 - onPlay={() => setPlaying(true)} 62 - onPause={() => setPlaying(false)} 63 - onLoadedMetadata={(ev) => { 64 - const video = ev.currentTarget; 57 + observer.observe(node); 58 + }); 59 + }} 60 + controls 61 + autoplay 62 + muted 63 + playsinline 64 + onPlay={() => setPlaying(true)} 65 + onPause={() => setPlaying(false)} 66 + onLoadedMetadata={(ev) => { 67 + const video = ev.currentTarget; 65 68 66 - const hasAudio = 67 - // @ts-expect-error: Mozilla-specific 68 - video.mozHasAudio || 69 - // @ts-expect-error: WebKit/Blink-specific 70 - !!video.webkitAudioDecodedByteCount || 71 - // @ts-expect-error: WebKit-specific 72 - !!(video.audioTracks && video.audioTracks.length); 69 + const hasAudio = 70 + // @ts-expect-error: Mozilla-specific 71 + video.mozHasAudio || 72 + // @ts-expect-error: WebKit/Blink-specific 73 + !!video.webkitAudioDecodedByteCount || 74 + // @ts-expect-error: WebKit-specific 75 + !!(video.audioTracks && video.audioTracks.length); 73 76 74 - video.loop = !hasAudio || video.duration <= 6; 75 - }} 76 - /> 77 + video.loop = !hasAudio || video.duration <= 6; 78 + }} 79 + /> 80 + </Show> 77 81 </div> 78 82 ); 79 83 };
+1 -1
src/views/record.tsx
··· 76 76 didDoc: didDocCache[res.data.uri.split("/")[2]], 77 77 }); 78 78 79 - console.warn(errors); 79 + if (errors.length > 0) console.warn(errors); 80 80 setValidRecord(errors.length === 0); 81 81 } catch (err) { 82 82 console.error(err);