Add player poster
This commit is contained in:
@@ -60,7 +60,7 @@ export default function ContentComponent() {
|
||||
return (
|
||||
<Content className={`${s.root}`} data-columns={chatOpen ? 2 : 1}>
|
||||
<div className={`${s.leftCol}`}>
|
||||
<OwncastPlayer source="https://watch.owncast.online" />
|
||||
<OwncastPlayer source="/hls/stream.m3u8" online={online} />
|
||||
<Statusbar
|
||||
online={online}
|
||||
lastConnectTime={lastConnectTime}
|
||||
|
||||
75
web/components/ui/CrossfadeImage/CrossfadeImage.tsx
Normal file
75
web/components/ui/CrossfadeImage/CrossfadeImage.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
import React, { useMemo, useState } from 'react';
|
||||
|
||||
type ObjectFit = React.CSSProperties['objectFit'];
|
||||
|
||||
interface CrossfadeImageProps {
|
||||
src: string;
|
||||
width: string;
|
||||
height: string;
|
||||
objectFit?: ObjectFit;
|
||||
duration?: string;
|
||||
}
|
||||
|
||||
const imgStyle: React.CSSProperties = {
|
||||
position: 'absolute',
|
||||
width: `100%`,
|
||||
height: `100%`,
|
||||
};
|
||||
|
||||
export default function CrossfadeImage({
|
||||
src = '',
|
||||
width,
|
||||
height,
|
||||
objectFit = 'fill',
|
||||
duration = '1s',
|
||||
}: CrossfadeImageProps) {
|
||||
const spanStyle: React.CSSProperties = useMemo(
|
||||
() => ({
|
||||
display: 'inline-block',
|
||||
position: 'relative',
|
||||
width,
|
||||
height,
|
||||
}),
|
||||
[width, height],
|
||||
);
|
||||
|
||||
const imgStyles = useMemo(
|
||||
() => [
|
||||
{ ...imgStyle, objectFit, opacity: 0, transition: `opacity ${duration}` },
|
||||
{ ...imgStyle, objectFit, opacity: 1, transition: `opacity ${duration}` },
|
||||
{ ...imgStyle, objectFit, opacity: 0 },
|
||||
],
|
||||
[objectFit, duration],
|
||||
);
|
||||
|
||||
const [key, setKey] = useState(0);
|
||||
const [srcs, setSrcs] = useState(['', '']);
|
||||
const nextSrc = src !== srcs[1] ? src : '';
|
||||
|
||||
const onLoadImg = () => {
|
||||
setKey((key + 1) % 3);
|
||||
setSrcs([srcs[1], nextSrc]);
|
||||
};
|
||||
|
||||
return (
|
||||
<span style={spanStyle}>
|
||||
{[...srcs, nextSrc].map(
|
||||
(src, index) =>
|
||||
src !== '' && (
|
||||
<img
|
||||
key={(key + index) % 3}
|
||||
src={src}
|
||||
alt=""
|
||||
style={imgStyles[index]}
|
||||
onLoad={index === 2 ? onLoadImg : undefined}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
CrossfadeImage.defaultProps = {
|
||||
objectFit: 'fill',
|
||||
duration: '3s',
|
||||
};
|
||||
@@ -45,7 +45,7 @@ export default function Statusbar(props: Props) {
|
||||
} else {
|
||||
onlineMessage = 'Offline';
|
||||
if (lastDisconnectTime) {
|
||||
rightSideMessage = `Last live ${formatDistanceToNow(lastDisconnectTime)} ago.`;
|
||||
rightSideMessage = `Last live ${formatDistanceToNow(new Date(lastDisconnectTime))} ago.`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user