1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
import { effect, Signal, useSignalEffect } from "@preact/signals"
import { Address } from "$/apps/source";
import { memo, Ref, useRef } from "preact/compat";
const filenameRegex = /.*\/(.*)$/;
export const Video = memo(function Video({ source, title, contentReady, sizingFinished }: Video.Props) {
useSignalEffect(() => {
const filename = decodeURIComponent(source.value.link.pathname.match(filenameRegex)?.[1] ?? source.value.link.toString());
title.value = `${filename} - media player`;
})
const videoRef: Ref<HTMLVideoElement> = useRef(null);
return <video controls src={source.value.link.toString()} ref={video => {
videoRef.current = video
const id = setInterval(() => {
if (video && video.videoWidth) {
clearInterval(id)
contentReady.value = true
const vw = Math.max(document.documentElement.clientWidth, window.innerWidth)
const vh = Math.max(document.documentElement.clientHeight, window.innerHeight)
const maxImageSize = Math.min(vw, vh) * 0.4;
const smallestImageAxis = Math.min(video.videoHeight, video.videoWidth);
const aspectRatio = video.videoWidth / video.videoHeight
if (smallestImageAxis > maxImageSize) {
if (video.videoWidth > video.videoHeight) {
video.style.height = `${maxImageSize / aspectRatio}px`
video.style.width = `${maxImageSize}px`
} else {
video.style.height = `${maxImageSize}px`
video.style.width = `${maxImageSize * aspectRatio}px`
}
effect(() => {
if (sizingFinished.value) {
video!.style.setProperty("height", null)
video!.style.setProperty("width", null)
}
})
}
}
}, 50)
return () => {
clearInterval(id)
videoRef.current = null
}
}}/>
})
namespace Video {
export type Props = {
source: Signal<Address>,
title: Signal<string | undefined>,
contentReady: Signal<boolean>,
sizingFinished: Signal<boolean>
}
}
|