File size: 7,304 Bytes
5aa7815
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5073220
31cf672
ec86595
5aa7815
 
 
 
 
 
 
 
 
 
 
 
 
66ae080
 
 
 
5aa7815
 
3ba14b7
5aa7815
66ae080
 
 
 
5aa7815
3ba14b7
66ae080
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5aa7815
66ae080
5aa7815
 
 
66ae080
5aa7815
3ba14b7
66ae080
5aa7815
 
 
 
66ae080
5aa7815
66ae080
 
 
 
 
 
5aa7815
 
 
 
 
 
66ae080
5aa7815
66ae080
5aa7815
 
 
 
 
 
66ae080
5aa7815
 
 
 
 
66ae080
 
 
 
 
 
 
 
 
3ba14b7
5aa7815
 
3ba14b7
 
5aa7815
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Screenshot Gallery</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
        /* Ensure html and body take full height */
        html, body {
            height: 100%;
            margin: 0;
            padding: 0;
            background-color: #1a202c; /* Dark background */
        }
        /* Ensure the grid container takes full height */
        #screenshot-grid {

        }
        /* Style for individual grid items */
        .grid-item {
            border-radius:12px;
        }

        .grid-item:hover {
            filter: brightness(1.2);
        }
        /* Style for images within grid items */
        .grid-item img {

        }
    </style>
</head>
<body class="bg-gray-900 text-gray-100">
    <header class="p-4 flex justify-between items-center border-b border-gray-700">
        <h1 class="text-2xl font-bold"><span class="font-normal">Made with</span> DeepSite</h1>
        <p class="max-sm:text-xs max-sm:w-40">⚠️ Do not share personal information. User-submitted apps may contain malicious code.</p>
        <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">
            Open DeepSite
        </a>
    </header>
    <div id="screenshot-grid" class="grid grid-cols-2 sm:grid-cols-3 2xl:grid-cols-4 gap-2 p-4">
        <!-- Screenshots will be loaded here -->
    </div>

    <script>
        async function loadScreenshots() {
            try {
                const response = await fetch('screenshots.json');
                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }
                // Read the JSON body ONCE
                const screenshotsData = await response.json();
                // screenshotsData is now an array of objects: [{filename: "...", rating: N}, ...]

                const grid = document.getElementById('screenshot-grid');
                grid.innerHTML = ''; // Clear existing content
                const fragment = document.createDocumentFragment(); // Create a fragment

                // No need to filter/sort here, assuming screenshots.json is already sorted and correct
                if (!Array.isArray(screenshotsData)) {
                     throw new Error("screenshots.json is not a valid array.");
                }

                // Build elements in the fragment
                screenshotsData.forEach(item => {
                    if (!item || typeof item.filename !== 'string' || !item.filename.endsWith('.png')) {
                        console.warn("Skipping invalid item in screenshots.json:", item);
                        return;
                    }
                    // --- Filter by rating ---
                    if (typeof item.rating !== 'number' || item.rating < 50) {
                        // console.log(`Skipping ${item.filename} due to rating: ${item.rating}`);
                        return; // Skip items with rating below 50 or invalid rating
                    }
                    // --- End filter ---

                    const filename = item.filename;
                    // const rating = item.rating; // Rating is available if needed for display

                    const gridItem = document.createElement('div');
                    gridItem.className = 'grid-item relative'; // Added relative for potential badge positioning

                    const img = document.createElement('img');
                    img.src = `screenshots/${filename}`;
                    img.alt = `Screenshot of ${filename.replace(/^space-|-/g, ' ').replace('.png', '')}`; // Improved alt text
                    img.loading = 'lazy'; // Lazy load images
                    img.decoding = 'async'; // Hint for async decoding
                    img.className = 'w-full h-auto object-cover rounded-lg shadow-md'; // Added some styling

                    // Create the link element
                    const link = document.createElement('a');

                    // Parse filename to create the URL (remove 'space-' prefix and '.png' suffix)
                    try {
                        const namePart = filename.replace(/^space-/, '').replace(/\.png$/, '');
                        // Replace the *first* hyphen only to separate owner/repo
                        const parts = namePart.split(/-(.+)/); // Split on the first hyphen
                        if (parts.length >= 2 && parts[0] && parts[1]) {
                            const username = parts[0];
                            const spacename = parts[1];
                            link.href = `https://huggingface.co/spaces/${username}/${spacename}`;
                            link.target = '_blank'; // Open in new tab
                            link.rel = 'noopener noreferrer'; // Security best practice
                        } else {
                            // Handle cases where the format might be unexpected
                            console.warn(`Could not parse username/spacename from: ${filename}`);
                            // Make it non-clickable by just appending the image
                            gridItem.appendChild(img);
                            fragment.appendChild(gridItem); // Add directly to fragment
                            return; // Skip appending link for this item
                        }
                    } catch (e) {
                         console.error(`Error parsing filename: ${filename}`, e);
                         // Append image directly if parsing fails
                         gridItem.appendChild(img);
                         fragment.appendChild(gridItem); // Add directly to fragment
                         return; // Skip appending link for this item
                    }

                    link.appendChild(img); // Place the image inside the link
                    gridItem.appendChild(link); // Place the link (with image) inside the grid item

                    // Optional: Display rating badge (Example)
                    // if (typeof rating === 'number') {
                    //     const badge = document.createElement('span');
                    //     badge.className = 'absolute top-2 right-2 bg-blue-500 text-white text-xs font-bold px-2 py-1 rounded-full';
                    //     badge.textContent = rating;
                    //     gridItem.appendChild(badge);
                    // }

                    fragment.appendChild(gridItem); // Add the item to the fragment
                });

                // Append the fragment to the grid once
                grid.appendChild(fragment);

            } catch (error) {
                console.error('Failed to load screenshots:', error);
                const grid = document.getElementById('screenshot-grid');
                grid.innerHTML = '<p class="text-red-500 text-center col-span-3">Failed to load screenshots. Check console for details.</p>';
            }
        }

        document.addEventListener('DOMContentLoaded', loadScreenshots);
    </script>
</body>
</html>