nextcloud / nextcloud/unsplash

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

Open
#161 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
JavaScript
Stars
100
Forks
25
PR merge metrics
No merged PRs in 30d

Description

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>

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the login-screen entry point in this Nextcloud app and compare it with the supplied index.php and JavaScript example. Determine how a local image folder could be selected and refreshed without external content, then verify the result on the unauthenticated login screen with images changing at the requested interval.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, php
Domain
frontend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.