CoolFace
Apppublic

DecliTech/Coding-Projects

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
index.html150 linesDownload Raw Back to root
1<!DOCTYPE html>2<html lang="en">3<head>4    <meta charset="UTF-8">5    <meta name="viewport" content="width=device-width, initial-scale=1.0">6    <title>Screenshot Gallery</title>7    <script src="https://cdn.tailwindcss.com"></script>8    <style>9        /* Ensure html and body take full height */10        html, body {11            height: 100%;12            margin: 0;13            padding: 0;14            background-color: #1a202c; /* Dark background */15        }16        /* Ensure the grid container takes full height */17        #screenshot-grid {18 19        }20        /* Style for individual grid items */21        .grid-item {22            border-radius:12px;23        }24 25        .grid-item:hover {26            filter: brightness(1.2);27        }28        /* Style for images within grid items */29        .grid-item img {30 31        }32    </style>33</head>34<body class="bg-gray-900 text-gray-100">35    <header class="p-4 flex justify-between items-center border-b border-gray-700">36        <h1 class="text-2xl font-bold"><span class="font-normal">Made with</span> DeepSite</h1>37        <p class="max-sm:text-xs max-sm:w-40">⚠️ Do not share personal information. User-submitted apps may contain malicious code.</p>38        <a href="https://huggingface.co/spaces/enzostvs/deepsite" target="_blank" rel="noopener noreferrer" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">39            Open DeepSite40        </a>41    </header>42    <div id="screenshot-grid" class="grid grid-cols-2 sm:grid-cols-3 2xl:grid-cols-4 gap-2 p-4">43        <!-- Screenshots will be loaded here -->44    </div>45 46    <script>47        async function loadScreenshots() {48            try {49                const response = await fetch('screenshots.json');50                if (!response.ok) {51                    throw new Error(`HTTP error! status: ${response.status}`);52                }53                // Read the JSON body ONCE54                const screenshotsData = await response.json();55                // screenshotsData is now an array of objects: [{filename: "...", rating: N}, ...]56 57                const grid = document.getElementById('screenshot-grid');58                grid.innerHTML = ''; // Clear existing content59                const fragment = document.createDocumentFragment(); // Create a fragment60 61                // No need to filter/sort here, assuming screenshots.json is already sorted and correct62                if (!Array.isArray(screenshotsData)) {63                     throw new Error("screenshots.json is not a valid array.");64                }65 66                // Build elements in the fragment67                screenshotsData.forEach(item => {68                    if (!item || typeof item.filename !== 'string' || !item.filename.endsWith('.png')) {69                        console.warn("Skipping invalid item in screenshots.json:", item);70                        return;71                    }72                    // --- Filter by rating ---73                    if (typeof item.rating !== 'number' || item.rating < 50) {74                        // console.log(`Skipping ${item.filename} due to rating: ${item.rating}`);75                        return; // Skip items with rating below 50 or invalid rating76                    }77                    // --- End filter ---78 79                    const filename = item.filename;80                    // const rating = item.rating; // Rating is available if needed for display81 82                    const gridItem = document.createElement('div');83                    gridItem.className = 'grid-item relative'; // Added relative for potential badge positioning84 85                    const img = document.createElement('img');86                    img.src = `screenshots/${filename}`;87                    img.alt = `Screenshot of ${filename.replace(/^space-|-/g, ' ').replace('.png', '')}`; // Improved alt text88                    img.loading = 'lazy'; // Lazy load images89                    img.decoding = 'async'; // Hint for async decoding90                    img.className = 'w-full h-auto object-cover rounded-lg shadow-md'; // Added some styling91 92                    // Create the link element93                    const link = document.createElement('a');94 95                    // Parse filename to create the URL (remove 'space-' prefix and '.png' suffix)96                    try {97                        const namePart = filename.replace(/^space-/, '').replace(/\.png$/, '');98                        // Replace the *first* hyphen only to separate owner/repo99                        const parts = namePart.split(/-(.+)/); // Split on the first hyphen100                        if (parts.length >= 2 && parts[0] && parts[1]) {101                            const username = parts[0];102                            const spacename = parts[1];103                            link.href = `https://huggingface.co/spaces/${username}/${spacename}`;104                            link.target = '_blank'; // Open in new tab105                            link.rel = 'noopener noreferrer'; // Security best practice106                        } else {107                            // Handle cases where the format might be unexpected108                            console.warn(`Could not parse username/spacename from: ${filename}`);109                            // Make it non-clickable by just appending the image110                            gridItem.appendChild(img);111                            fragment.appendChild(gridItem); // Add directly to fragment112                            return; // Skip appending link for this item113                        }114                    } catch (e) {115                         console.error(`Error parsing filename: ${filename}`, e);116                         // Append image directly if parsing fails117                         gridItem.appendChild(img);118                         fragment.appendChild(gridItem); // Add directly to fragment119                         return; // Skip appending link for this item120                    }121 122                    link.appendChild(img); // Place the image inside the link123                    gridItem.appendChild(link); // Place the link (with image) inside the grid item124 125                    // Optional: Display rating badge (Example)126                    // if (typeof rating === 'number') {127                    //     const badge = document.createElement('span');128                    //     badge.className = 'absolute top-2 right-2 bg-blue-500 text-white text-xs font-bold px-2 py-1 rounded-full';129                    //     badge.textContent = rating;130                    //     gridItem.appendChild(badge);131                    // }132 133                    fragment.appendChild(gridItem); // Add the item to the fragment134                });135 136                // Append the fragment to the grid once137                grid.appendChild(fragment);138 139            } catch (error) {140                console.error('Failed to load screenshots:', error);141                const grid = document.getElementById('screenshot-grid');142                grid.innerHTML = '<p class="text-red-500 text-center col-span-3">Failed to load screenshots. Check console for details.</p>';143            }144        }145 146        document.addEventListener('DOMContentLoaded', loadScreenshots);147    </script>148</body>149</html>150