nextcloud / server

☁️ Nextcloud server, a safe home for all your data
https://nextcloud.com
GNU Affero General Public License v3.0
27.17k stars 4.04k forks source link

random image on login screen (without external app Splash and without external source like Unsplash) #48546

Open devnull4242 opened 2 weeks ago

devnull4242 commented 2 weeks ago

Years ago i used the app Splash with random images from https://unsplash.com . An API key is now required and it is also bad if content is loaded outside of your own Nextcloud. Keyword GDPR. Also, as is currently the case, the latest version is repeatedly not supported

I would like to see Nextcloud's design expanded so that images from a folder could be randomly selected as background images. These could then be replaced at regular intervals (e.g. 4 seconds) on login screen while not logged in.

I have written a programme that uses PHP and JavaScript to randomly read images from a folder (.) and display them as a full screen. Maybe you can build something like this into Nextcloud. I would be very happy about that.

For testing use a webserver outside Nextcloud. Copy the file index.php and some pictures in the folder.

index.php

<?php
function getRandomImage() {
    $images = glob("*.{jpg,JPG,jpeg,JPEG,png,PNG,gif,GIF}", GLOB_BRACE);
    return !empty($images) ? $bilder[array_rand($images)] : null;
}

function getAllImages() {
    return glob("*.{jpg,JPG,jpeg,JPEG,png,PNG,gif,GIF}", GLOB_BRACE);
}

function serveImage($filename) {
    if (file_exists($filename)) {
        $ext = pathinfo($filename, PATHINFO_EXTENSION);
        $mime = [
            'jpg' => 'image/jpeg',
            'jpeg' => 'image/jpeg',
            'png' => 'image/png',
            'gif' => 'image/gif'
        ];

        header("Content-Type: " . ($mime[strtolower($ext)] ?? 'application/octet-stream'));
        header("Cache-Control: public, max-age=31536000"); // Cache für ein Jahr
        readfile($filename);
        exit;
    }
}

if (isset($_GET['img'])) {
    serveImage($_GET['img']);
}

if (isset($_GET['getImages'])) {
    header("Content-Type: application/json");
    header("Cache-Control: public, max-age=3600"); // Cache für eine Stunde
    echo json_encode(getAllImages());
    exit;
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8" />
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
        html, body {
            margin: 0;
            padding: 0;
            height: 100%;
            width: 100%;
            overflow: hidden;
        }
        .image-container {
            position: relative;
            height: 100%;
            width: 100%;
            overflow: hidden;
        }
        img {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            min-width: 100%;
            min-height: 100%;
            width: auto;
            height: auto;
            object-fit: cover;
        }
    </style>
</head>
<body>
    <div class="image-container">
        <img src="no-image.png" id="randomImage" alt="Random Image">
    </div>
    <script>
        let images = [];

        async function fetchImages() {
            try {
                const cachedImages = localStorage.getItem('coffeeImages');
                if (cachedImages) {
                    images = JSON.parse(cachedImages);
                    refreshImage();
                }

                const response = await fetch('index.php?getImages=true');
                const newImages = await response.json();

                if (JSON.stringify(newImages) !== JSON.stringify(images)) {
                    images = newImages;
                    localStorage.setItem('coffeeImages', JSON.stringify(images));
                }

                refreshImage();
            } catch (error) {
                console.error('Fehler beim Laden der Bildnamen:', error);
            }
        }

        function getRandomImage() {
            if (images.length === 0) return 'no-image.png';
            const randomIndex = Math.floor(Math.random() * images.length);
            return images[randomIndex];
        }

        function refreshImage() {
            const img = document.getElementById('randomImage');
            const newSrc = 'index.php?img=' + encodeURIComponent(getRandomImage());
            img.onload = function() {
                const imgRatio = img.naturalWidth / img.naturalHeight;
                const screenRatio = window.innerWidth / window.innerHeight;

                if (imgRatio > screenRatio) {
                    img.style.width = '100%';
                    img.style.height = 'auto';
                } else {
                    img.style.width = 'auto';
                    img.style.height = '100%';
                }
            };
            img.src = newSrc;
        }

        document.addEventListener('DOMContentLoaded', function() {
            fetchImages();
            setInterval(refreshImage, 4000);
        });

        window.addEventListener('resize', refreshImage);
    </script>
</body>
</html>
solracsf commented 2 weeks ago

You can always write an app for this, and make it publicly available trough the AppStore if wished. 😉 I don't think this belong to server itself.

https://docs.nextcloud.com/server/latest/developer_manual/app_development/index.html

joshtrichards commented 2 weeks ago

The existing Unsplash app isn't fundamentally limited to using Splash as a source; it could be adapted to use other providers/sources (either in the app itself or via a fork).

See nextcloud/unsplash#5 See nextcloud/unsplash#94

It would seem to make sense to focus efforts there rather than reinvent the wheel.