75 lines
2.9 KiB
TypeScript
75 lines
2.9 KiB
TypeScript
import {Registry} from "tc-shared/events";
|
|
import {HostBannerInfo, HostBannerInfoSet, HostBannerUiEvents} from "tc-shared/ui/frames/HostBannerDefinitions";
|
|
import * as React from "react";
|
|
import {useEffect, useRef, useState} from "react";
|
|
import {useGlobalSetting, useTr} from "tc-shared/ui/react-elements/Helper";
|
|
import {ErrorBoundary} from "tc-shared/ui/react-elements/ErrorBoundary";
|
|
import {Settings} from "tc-shared/settings";
|
|
|
|
const cssStyle = require("./HostBannerRenderer.scss");
|
|
|
|
export const HostBannerRenderer = React.memo((props: { banner: HostBannerInfoSet, clickable: boolean, className?: string }) => {
|
|
const [ revision, setRevision ] = useState(Date.now());
|
|
useEffect(() => {
|
|
if(!props.banner.updateInterval) {
|
|
return;
|
|
}
|
|
|
|
const id = setTimeout(() => setRevision(Date.now()), props.banner.updateInterval * 1000);
|
|
return () => clearTimeout(id);
|
|
});
|
|
|
|
const [ loadingState, setLoadingState ] = useState<"loading" | "error" | "loaded">("loading");
|
|
const refImage = useRef<HTMLImageElement>();
|
|
|
|
useRef(() => {
|
|
if(refImage.current.complete) {
|
|
setLoadingState(refImage.current.naturalWidth === 0 ? "error" : "loaded");
|
|
}
|
|
});
|
|
|
|
let appendix = (props.banner.imageUrl.indexOf("?") === -1 ? "?" : "&") + "_ts=" + revision;
|
|
const withBackground = useGlobalSetting(Settings.KEY_HOSTBANNER_BACKGROUND);
|
|
|
|
return (
|
|
<div
|
|
className={
|
|
cssStyle.containerImage + " " + cssStyle["mode-" + props.banner.mode] + " " + cssStyle["state-" + loadingState] + " " +
|
|
(withBackground ? cssStyle.withBackground : "") + " " + props.className + " "
|
|
+ (props.clickable ? cssStyle.clickable : "")
|
|
}
|
|
onClick={() => {
|
|
if(props.banner.linkUrl && props.clickable) {
|
|
window.open(props.banner.linkUrl, "_blank");
|
|
}
|
|
}}
|
|
>
|
|
<img
|
|
src={props.banner.imageUrl + appendix}
|
|
alt={useTr("Host banner")}
|
|
onError={() => setLoadingState("error")}
|
|
onLoad={() => setLoadingState("loaded")}
|
|
ref={refImage}
|
|
/>
|
|
</div>
|
|
);
|
|
});
|
|
|
|
export const HostBanner = React.memo((props: { events: Registry<HostBannerUiEvents> }) => {
|
|
const [ hostBanner, setHostBanner ] = useState<HostBannerInfo>(() => {
|
|
props.events.fire("query_host_banner");
|
|
return { status: "none" };
|
|
});
|
|
|
|
props.events.reactUse("notify_host_banner", event => {
|
|
setHostBanner(event.banner);
|
|
}, undefined, []);
|
|
|
|
return (
|
|
<div className={cssStyle.container + " " + (hostBanner.status !== "set" ? cssStyle.disabled : "")}>
|
|
<ErrorBoundary>
|
|
{hostBanner.status === "set" ? <HostBannerRenderer key={"banner"} banner={hostBanner} clickable={true} /> : undefined}
|
|
</ErrorBoundary>
|
|
</div>
|
|
);
|
|
}); |