app/Wallpaper.tsx (95 lines of code) (raw):
import React, { useEffect, useState } from "react";
import { makeStyles } from "@material-ui/core/styles";
import { LoadWallpaperManifest } from "./WallpaperService";
import { Fade } from "@material-ui/core";
const useStyles = makeStyles((theme) => ({
wallpaperHolder: {
position: "absolute",
top: "0",
left: "0",
margin: "0",
padding: "0",
width: "100vw",
height: "100vh",
objectFit: "cover",
zIndex: -1,
},
}));
const Wallpaper: React.FC = () => {
const [selectedImageHolder, setSelectedImageHolder] = useState(0);
const [config, setConfig] = useState<WallpaperManifest | undefined>(
undefined
);
const [imageIndex, setImageIndex] = useState(0);
const [loadImmediate, setLoadImmediate] = useState(true);
const classes = useStyles();
const imageHolders = [
React.createRef<HTMLImageElement>(),
React.createRef<HTMLImageElement>(),
];
useEffect(() => {
LoadWallpaperManifest()
.then((maybeContent) => setConfig(maybeContent))
.catch((err) => {
console.log("Could not set up wallpaper");
});
}, []);
const switchOverImageAfterDelay = () => {
const delayMs = loadImmediate ? 10 : (config?.onScreenFor ?? 60) * 1000;
console.log("Image loaded, switching over after ", delayMs, "ms");
window.setTimeout(() => {
const targetImage = selectedImageHolder == 0 ? 1 : 0;
if (imageHolders[targetImage].current) {
// @ts-ignore
imageHolders[targetImage].current.removeEventListener(
"load",
switchOverImageAfterDelay
);
}
setSelectedImageHolder(targetImage);
setImageIndex((prev) =>
config && imageIndex >= config.wallpaperUrls.length - 1 ? 0 : prev + 1
);
setLoadImmediate(false);
}, delayMs);
};
const loadNextImage = () => {
console.log(
`Loading in next image ${imageIndex} ${config?.wallpaperUrls[imageIndex]}`
);
const targetImage = selectedImageHolder == 0 ? 1 : 0;
if (config) {
// @ts-ignore
imageHolders[targetImage].current.src = config.wallpaperUrls[imageIndex];
// @ts-ignore
imageHolders[targetImage].current.addEventListener(
"load",
switchOverImageAfterDelay
);
} else {
console.log("No config was loaded");
}
};
useEffect(() => {
if (config && config.wallpaperUrls) {
loadNextImage();
}
}, [config]);
const timeouts = {
enter: (config?.transitionTime ?? 3) * 1000,
exit: (config?.transitionTime ?? 3) * 1000,
};
return (
<>
<Fade
in={selectedImageHolder == 0 && !!config}
timeout={timeouts}
onExited={loadNextImage}
>
<img ref={imageHolders[0]} className={classes.wallpaperHolder} />
</Fade>
<Fade
in={selectedImageHolder == 1 && !!config}
timeout={timeouts}
onExited={loadNextImage}
>
<img ref={imageHolders[1]} className={classes.wallpaperHolder} />
</Fade>
</>
);
};
export default Wallpaper;