mirror of
https://github.com/anotherhadi/awesome-wallpapers.git
synced 2026-10-05 10:18:26 +02:00
v0.1.1
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
import { readdirSync, readFileSync, statSync, writeFileSync } from 'fs';
|
||||
import { join, extname } from 'path';
|
||||
import { imageSize } from 'image-size';
|
||||
|
||||
const staticDir = './static/wallpapers';
|
||||
const outputFile = './static/files.json';
|
||||
|
||||
function getFiles(dir) {
|
||||
return readdirSync(dir)
|
||||
.filter(file => !file.startsWith('.'))
|
||||
.map(file => {
|
||||
const filePath = join(dir, file);
|
||||
const stats = statSync(filePath);
|
||||
const sizeInMB = (stats.size / (1024 * 1024)).toFixed(2); // Taille en MB
|
||||
|
||||
let dimensions = { width: 0, height: 0 };
|
||||
if (['.jpg', '.png', '.gif'].includes(extname(file).toLowerCase())) {
|
||||
const buffer = readFileSync(filePath);
|
||||
dimensions = imageSize(buffer);
|
||||
}
|
||||
|
||||
return {
|
||||
filename: file,
|
||||
size: sizeInMB,
|
||||
width: dimensions.width || 0,
|
||||
height: dimensions.height || 0
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const files = getFiles(staticDir);
|
||||
writeFileSync(outputFile, JSON.stringify(files, null, 2));
|
||||
|
||||
console.log(`✅ Liste des fichiers générée dans ${outputFile}`);
|
||||
@@ -1,10 +1,49 @@
|
||||
<script lang="ts">
|
||||
import '../app.css';
|
||||
import Badge from '$lib/components/ui/badge/badge.svelte';
|
||||
import Button from '$lib/components/ui/button/button.svelte';
|
||||
import { ChevronRight, Moon, Sun } from '@lucide/svelte';
|
||||
import { toggleMode } from 'mode-watcher';
|
||||
import { ModeWatcher } from 'mode-watcher';
|
||||
import { Toaster } from '$lib/components/ui/sonner/index.js';
|
||||
let { children } = $props();
|
||||
|
||||
const version = 'v0.1.1';
|
||||
const owner = 'anotherhadi';
|
||||
const repo = 'awesome-wallpapers';
|
||||
</script>
|
||||
|
||||
<ModeWatcher />
|
||||
<Toaster />
|
||||
{@render children()}
|
||||
<div class="relative flex min-h-[100vh] flex-col gap-5 bg-background">
|
||||
<p class="absolute right-2 top-2 m-2 text-muted-foreground">{version}</p>
|
||||
<Button onclick={toggleMode} variant="ghost" size="icon" class="absolute left-2 right-2 m-2">
|
||||
<Sun
|
||||
class="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0"
|
||||
/>
|
||||
<Moon
|
||||
class="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100"
|
||||
/>
|
||||
<span class="sr-only">Toggle theme</span>
|
||||
</Button>
|
||||
|
||||
<header class="flex h-96 w-full flex-col items-center justify-center gap-5 bg-primary/20">
|
||||
<Badge class="gap-2" href={'https://github.com/' + owner + '/' + repo} target="_blank"
|
||||
>Check the github repo <ChevronRight size={16} /></Badge
|
||||
>
|
||||
<h1 class="m-0">Awesome Wallpapers</h1>
|
||||
<p class="text-muted-foreground">Open-source wallpapers collection from {owner}/{repo}</p>
|
||||
</header>
|
||||
|
||||
<main class="px-10">
|
||||
{@render children()}
|
||||
</main>
|
||||
|
||||
<div class="mt-32"></div>
|
||||
<div
|
||||
class="absolute bottom-0 flex h-32 w-full flex-col items-center justify-center gap-4 bg-primary/20"
|
||||
>
|
||||
<img src="/favicon.png" alt="logo" class="w-5 rounded-md" />
|
||||
<p class="text-muted-foreground">@anotherhadi</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+212
-242
@@ -1,42 +1,57 @@
|
||||
<script lang="ts">
|
||||
import { AspectRatio } from '$lib/components/ui/aspect-ratio';
|
||||
import * as Drawer from '$lib/components/ui/drawer/index.js';
|
||||
import Badge from '$lib/components/ui/badge/badge.svelte';
|
||||
import Button from '$lib/components/ui/button/button.svelte';
|
||||
import { Copy, Download, Moon, Sun } from '@lucide/svelte';
|
||||
import { Info, ChevronRight, ChevronsUpDown } from '@lucide/svelte';
|
||||
import axios from 'axios';
|
||||
import { onMount } from 'svelte';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import Filters from './filters.svelte';
|
||||
import Loading from './loading.svelte';
|
||||
import Filters from './filters.svelte';
|
||||
import Input from '$lib/components/ui/input/input.svelte';
|
||||
import { toggleMode } from 'mode-watcher';
|
||||
import { AspectRatio } from '$lib/components/ui/aspect-ratio';
|
||||
import Button from '$lib/components/ui/button/button.svelte';
|
||||
import { Copy, Download, Info } from '@lucide/svelte';
|
||||
import * as Drawer from '$lib/components/ui/drawer/index.js';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import Badge from '$lib/components/ui/badge/badge.svelte';
|
||||
|
||||
type Wallpaper = {
|
||||
name: string;
|
||||
filename: string;
|
||||
tags: string[];
|
||||
size: string;
|
||||
width: number;
|
||||
height: number;
|
||||
tags: string[];
|
||||
more: boolean;
|
||||
hovered: boolean;
|
||||
sha256: string;
|
||||
};
|
||||
|
||||
const version = 'v0.1.0';
|
||||
let wallpapers: Wallpaper[] = [];
|
||||
let tags: string[] = [];
|
||||
let selectedTags: string[] = [];
|
||||
let search: string = '';
|
||||
let loading: boolean = false;
|
||||
let isLoadingMore: boolean = false; // Etat pour savoir si de nouveaux wallpapers sont en train de charger
|
||||
let allWallpapers: Wallpaper[] = [];
|
||||
let currentPage: number = 0;
|
||||
const wallpapersPerPage: number = 20;
|
||||
|
||||
const owner = 'anotherhadi';
|
||||
const repo = 'awesome-wallpapers';
|
||||
const path = 'wallpapers';
|
||||
const apiUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${path}`;
|
||||
const path = 'app/static/wallpapers';
|
||||
|
||||
let search: string = $state('');
|
||||
let wallpapers: Wallpaper[] = $state([]);
|
||||
const batchSize = 10;
|
||||
function parseFilename(filename: string) {
|
||||
let [namePart, ...tagsArray] = filename.split('.')[0].split('_');
|
||||
let tagsPart = tagsArray.join('_');
|
||||
let name = namePart.replace(/-/g, ' ').replace(/\b\w/, (l: string) => l.toUpperCase());
|
||||
let fileTags = tagsPart ? tagsPart.split('_') : [];
|
||||
|
||||
let allTags: string[] = $state([]);
|
||||
let selectedTags: string[] = $state([]);
|
||||
fileTags.forEach((tag: string) => {
|
||||
if (!tags.includes(tag)) {
|
||||
tags.push(tag);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
name,
|
||||
filename,
|
||||
tags: fileTags
|
||||
};
|
||||
}
|
||||
|
||||
const copyToClipboard = (text: string) => {
|
||||
navigator.clipboard
|
||||
@@ -45,240 +60,195 @@
|
||||
.catch(() => toast.error('Failed to copy'));
|
||||
};
|
||||
|
||||
const fetchWallpapers = async () => {
|
||||
try {
|
||||
const response = await axios.get(apiUrl, {
|
||||
headers: { Accept: 'application/vnd.github.v3+json' }
|
||||
});
|
||||
async function fetchWallpapers() {
|
||||
const res = await fetch('/files.json');
|
||||
const fileData: { filename: string; size: string; width: number; height: number }[] =
|
||||
await res.json();
|
||||
|
||||
if (Array.isArray(response.data)) {
|
||||
const files = response.data;
|
||||
// Traitement par lots
|
||||
for (let i = 0; i < files.length; i += batchSize) {
|
||||
const batch = files.slice(i, i + batchSize);
|
||||
const batchResults = await Promise.all(
|
||||
batch.map(async (file) => {
|
||||
console.log(file);
|
||||
let [namePart, ...tagsArray] = file.name.split('.')[0].split('_');
|
||||
let tagsPart = tagsArray.join('_');
|
||||
let name = namePart
|
||||
.replace(/-/g, ' ')
|
||||
.replace(/\b\w/, (l: string) => l.toUpperCase());
|
||||
let tags = tagsPart ? tagsPart.split('_') : [];
|
||||
let size = (file.size / 1024 / 1024).toFixed(2);
|
||||
// Map to Wallpaper objects
|
||||
allWallpapers = fileData.map((file) => {
|
||||
let { name, filename, tags: fileTags } = parseFilename(file.filename);
|
||||
|
||||
tags.forEach((tag: string) => {
|
||||
if (!allTags.includes(tag)) {
|
||||
allTags.push(tag);
|
||||
}
|
||||
});
|
||||
return {
|
||||
name,
|
||||
filename,
|
||||
tags: fileTags,
|
||||
size: file.size,
|
||||
width: file.width,
|
||||
height: file.height,
|
||||
hovered: false
|
||||
};
|
||||
});
|
||||
|
||||
const img = new Image();
|
||||
img.src = `https://raw.githubusercontent.com/${owner}/${repo}/main/${path}/${file.name}`;
|
||||
// Initially load the first set of wallpapers
|
||||
loadMoreWallpapers();
|
||||
}
|
||||
|
||||
return new Promise<Wallpaper>((resolve) => {
|
||||
img.onload = () => {
|
||||
resolve({
|
||||
name,
|
||||
filename: file.name,
|
||||
tags,
|
||||
size,
|
||||
width: img.width,
|
||||
height: img.height,
|
||||
more: false,
|
||||
hovered: false,
|
||||
sha256: 'sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='
|
||||
});
|
||||
};
|
||||
});
|
||||
})
|
||||
);
|
||||
wallpapers = [...wallpapers, ...batchResults];
|
||||
// Optionnel : attendre un peu avant de charger le batch suivant
|
||||
await new Promise((r) => setTimeout(r, 100));
|
||||
}
|
||||
} else {
|
||||
console.error('Error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error: ', error);
|
||||
function loadMoreWallpapers() {
|
||||
if (loading || isLoadingMore || currentPage * wallpapersPerPage >= allWallpapers.length) return;
|
||||
isLoadingMore = true;
|
||||
|
||||
// Load next batch of wallpapers
|
||||
const nextWallpapers = allWallpapers.slice(
|
||||
currentPage * wallpapersPerPage,
|
||||
(currentPage + 1) * wallpapersPerPage
|
||||
);
|
||||
wallpapers = [...wallpapers, ...nextWallpapers];
|
||||
currentPage++;
|
||||
isLoadingMore = false;
|
||||
}
|
||||
|
||||
// Handle scroll event
|
||||
function onScroll() {
|
||||
const scrollPosition = window.scrollY + window.innerHeight;
|
||||
const bottomPosition = document.documentElement.scrollHeight;
|
||||
|
||||
if (scrollPosition >= bottomPosition - 100) {
|
||||
// Load more wallpapers when reaching the bottom
|
||||
loadMoreWallpapers();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
onMount(fetchWallpapers);
|
||||
onMount(() => {
|
||||
fetchWallpapers();
|
||||
window.addEventListener('scroll', onScroll);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('scroll', onScroll);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="relative flex min-h-[100vh] flex-col gap-5 bg-background">
|
||||
<p class="absolute right-2 top-2 m-2 text-muted-foreground">{version}</p>
|
||||
<Button onclick={toggleMode} variant="ghost" size="icon" class="absolute left-2 right-2 m-2">
|
||||
<Sun
|
||||
class="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0"
|
||||
/>
|
||||
<Moon
|
||||
class="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100"
|
||||
/>
|
||||
<span class="sr-only">Toggle theme</span>
|
||||
</Button>
|
||||
<div class="flex gap-5 px-2 py-4">
|
||||
<Input class="h-8" placeholder="Search..." bind:value={search} />
|
||||
<Filters title="Tags" options={tags} bind:selectedValues={selectedTags} />
|
||||
</div>
|
||||
|
||||
<header class="flex h-96 w-full flex-col items-center justify-center gap-5 bg-primary/20">
|
||||
<Badge class="gap-2" href={'https://github.com/' + owner + '/' + repo} target="_blank"
|
||||
>Check the github repo <ChevronRight size={16} /></Badge
|
||||
>
|
||||
<h1 class="m-0">Awesome Wallpapers</h1>
|
||||
<p class="text-muted-foreground">Open-source wallpapers collection from {owner}/{repo}</p>
|
||||
</header>
|
||||
|
||||
<main class="px-10">
|
||||
<div class="flex gap-5 px-2 py-4">
|
||||
<Input class="h-8" placeholder="Search..." bind:value={search} />
|
||||
<Filters title="Tags" options={allTags} bind:selectedValues={selectedTags} />
|
||||
</div>
|
||||
{#if wallpapers.length === 0}
|
||||
<Loading />
|
||||
{:else}
|
||||
<div class="grid grid-cols-1 gap-5 md:grid-cols-2 xl:grid-cols-3">
|
||||
{#each wallpapers as wallpaper}
|
||||
{#if selectedTags.length === 0 || selectedTags.some( (tag) => wallpaper.tags.includes(tag) )}
|
||||
{#if wallpaper.name.toLowerCase().includes(search.toLowerCase())}
|
||||
<div class="rounded-t-md bg-muted/5">
|
||||
<div class="relative">
|
||||
<AspectRatio
|
||||
ratio={16 / 9}
|
||||
class="w-full rounded-md bg-muted"
|
||||
onmouseenter={() => (wallpaper.hovered = true)}
|
||||
onmouseleave={() => (wallpaper.hovered = false)}
|
||||
{#if wallpapers.length === 0}
|
||||
<Loading />
|
||||
{:else}
|
||||
<div class="grid grid-cols-1 gap-5 md:grid-cols-2 xl:grid-cols-3">
|
||||
{#each wallpapers as wallpaper}
|
||||
{#if selectedTags.length === 0 || selectedTags.some((tag) => wallpaper.tags.includes(tag))}
|
||||
{#if wallpaper.name.toLowerCase().includes(search.toLowerCase())}
|
||||
<div class="rounded-t-md bg-muted/5">
|
||||
<div class="relative">
|
||||
<AspectRatio
|
||||
ratio={16 / 9}
|
||||
class="w-full rounded-md bg-muted"
|
||||
onmouseenter={() => (wallpaper.hovered = true)}
|
||||
onmouseleave={() => (wallpaper.hovered = false)}
|
||||
>
|
||||
{#if wallpaper.hovered}
|
||||
<div
|
||||
class="absolute bottom-0 left-0 right-0 top-0 z-[10] flex items-center justify-center bg-primary/50"
|
||||
>
|
||||
{#if wallpaper.hovered}
|
||||
<div
|
||||
class="absolute bottom-0 left-0 right-0 top-0 z-[10] flex items-center justify-center bg-primary/50"
|
||||
>
|
||||
<Button
|
||||
href={`https://raw.githubusercontent.com/${owner}/${repo}/main/${path}/${wallpaper.filename}`}
|
||||
target="_blank">Download</Button
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
<img
|
||||
src={`https://raw.githubusercontent.com/${owner}/${repo}/main/${path}/${wallpaper.filename}`}
|
||||
alt={wallpaper.name + ' wallpaper'}
|
||||
class="h-full w-full rounded-md object-cover"
|
||||
/>
|
||||
</AspectRatio>
|
||||
</div>
|
||||
<div class="flex w-full items-center justify-between p-2">
|
||||
{wallpaper.name}
|
||||
<div class="flex gap-2">
|
||||
<Drawer.Root>
|
||||
<Drawer.Trigger>
|
||||
<Button size="icon" variant="ghost" class="h-6 w-6">
|
||||
<Info />
|
||||
</Button>
|
||||
</Drawer.Trigger>
|
||||
<Drawer.Content>
|
||||
<div class="m-auto w-full max-w-3xl select-text">
|
||||
<Drawer.Header>
|
||||
<Drawer.Title>{wallpaper.name}</Drawer.Title>
|
||||
</Drawer.Header>
|
||||
<div class="p-4 pb-0">
|
||||
<p>
|
||||
<span class="text-muted-foreground">Filename:</span>
|
||||
{wallpaper.filename}
|
||||
</p>
|
||||
<p><span class="text-muted-foreground">Name:</span> {wallpaper.name}</p>
|
||||
<p>
|
||||
<span class="text-muted-foreground">Size:</span>
|
||||
{wallpaper.size} Mb
|
||||
</p>
|
||||
<p>
|
||||
<span class="text-muted-foreground">Resolution:</span>
|
||||
{wallpaper.width}x{wallpaper.height}
|
||||
</p>
|
||||
<p>
|
||||
<span class="text-muted-foreground">Tags:</span>
|
||||
{#each wallpaper.tags as tag}
|
||||
<Badge variant="outline">{tag}</Badge>
|
||||
{/each}
|
||||
</p>
|
||||
<p class="mt-2">
|
||||
<span class="text-muted-foreground">Nix fetchurl:</span>
|
||||
</p>
|
||||
|
||||
<div class="relative">
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="absolute right-2 top-2 h-6 w-6"
|
||||
onclick={() => {
|
||||
let content = `
|
||||
image = pkgs.fetchurl {
|
||||
url = "https://raw.githubusercontent.com/${owner}/${repo}/refs/heads/main/${path}/${wallpaper.filename}";
|
||||
sha256 = "${wallpaper.sha256}";
|
||||
};`;
|
||||
copyToClipboard(content);
|
||||
}}
|
||||
>
|
||||
<Copy />
|
||||
</Button>
|
||||
|
||||
<pre
|
||||
id={wallpaper.filename}
|
||||
class="mb-4 mt-2 max-h-[650px] overflow-x-auto rounded-lg border bg-zinc-950 px-2 py-4 text-white dark:bg-zinc-900">
|
||||
image = pkgs.fetchurl {
|
||||
url = "https://raw.githubusercontent.com/{owner}/{repo}/refs/heads/main/{path}/{wallpaper.filename}";
|
||||
sha256 = "{wallpaper.sha256}";
|
||||
};</pre>
|
||||
</div>
|
||||
</div>
|
||||
<Drawer.Footer>
|
||||
<Drawer.Close>Close</Drawer.Close>
|
||||
</Drawer.Footer>
|
||||
</div>
|
||||
</Drawer.Content>
|
||||
</Drawer.Root>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-6 w-6"
|
||||
onclick={() => (wallpaper.more = !wallpaper.more)}
|
||||
>
|
||||
<ChevronsUpDown />
|
||||
</Button>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-6 w-6"
|
||||
href={`https://raw.githubusercontent.com/${owner}/${repo}/main/${path}/${wallpaper.filename}`}
|
||||
target="_blank"
|
||||
target="_blank">Download</Button
|
||||
>
|
||||
<Download />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
{#if wallpaper.more}
|
||||
<div class="px-2 py-1">
|
||||
<p><span class="text-muted-foreground">Name:</span> {wallpaper.name}</p>
|
||||
<p><span class="text-muted-foreground">Size:</span> {wallpaper.size} Mb</p>
|
||||
<p>
|
||||
<span class="text-muted-foreground">Resolution:</span>
|
||||
{wallpaper.width}x{wallpaper.height}
|
||||
</p>
|
||||
<p>
|
||||
<span class="text-muted-foreground">Tags:</span>
|
||||
{#each wallpaper.tags as tag}
|
||||
<Badge variant="outline">{tag}</Badge>
|
||||
{/each}
|
||||
</p>
|
||||
</div>
|
||||
{/if}
|
||||
<img
|
||||
src={`/wallpapers/${wallpaper.filename}`}
|
||||
alt={wallpaper.name + ' wallpaper'}
|
||||
class="h-full w-full rounded-md object-cover"
|
||||
/>
|
||||
</AspectRatio>
|
||||
</div>
|
||||
<div class="flex w-full items-center justify-between p-2">
|
||||
{wallpaper.name}
|
||||
<div class="flex gap-2">
|
||||
<Drawer.Root>
|
||||
<Drawer.Trigger>
|
||||
<Button size="icon" variant="ghost" class="h-6 w-6">
|
||||
<Info />
|
||||
</Button>
|
||||
</Drawer.Trigger>
|
||||
<Drawer.Content>
|
||||
<div class="m-auto w-full max-w-3xl select-text">
|
||||
<Drawer.Header>
|
||||
<Drawer.Title>{wallpaper.name}</Drawer.Title>
|
||||
</Drawer.Header>
|
||||
<div class="p-4 pb-0">
|
||||
<p>
|
||||
<span class="text-muted-foreground">Filename:</span>
|
||||
{wallpaper.filename}
|
||||
</p>
|
||||
<p><span class="text-muted-foreground">Name:</span> {wallpaper.name}</p>
|
||||
<p>
|
||||
<span class="text-muted-foreground">Size:</span>
|
||||
{wallpaper.size} Mb
|
||||
</p>
|
||||
<p>
|
||||
<span class="text-muted-foreground">Resolution:</span>
|
||||
{wallpaper.width}x{wallpaper.height}
|
||||
</p>
|
||||
<p>
|
||||
<span class="text-muted-foreground">Tags:</span>
|
||||
{#if wallpaper.tags.length === 0}
|
||||
<span class="text-muted-foreground">No tags</span>
|
||||
{:else}
|
||||
{#each wallpaper.tags as tag}
|
||||
<Badge variant="outline">{tag}</Badge>
|
||||
{/each}
|
||||
{/if}
|
||||
</p>
|
||||
<p class="mt-2">
|
||||
<span class="text-muted-foreground">Nix fetchurl:</span>
|
||||
</p>
|
||||
|
||||
<div class="relative">
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="absolute right-2 top-2 h-6 w-6"
|
||||
onclick={() => {
|
||||
let content = `
|
||||
image = pkgs.fetchurl {
|
||||
url = "https://raw.githubusercontent.com/${owner}/${repo}/refs/heads/main/${path}/${wallpaper.filename}";
|
||||
sha256 = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
||||
};`;
|
||||
copyToClipboard(content);
|
||||
}}
|
||||
>
|
||||
<Copy />
|
||||
</Button>
|
||||
|
||||
<pre
|
||||
id={wallpaper.filename}
|
||||
class="mb-4 mt-2 max-h-[650px] overflow-x-auto rounded-lg border bg-zinc-950 px-2 py-4 text-white dark:bg-zinc-900">
|
||||
image = pkgs.fetchurl {
|
||||
url = "https://raw.githubusercontent.com/{owner}/{repo}/refs/heads/main/{path}/{wallpaper.filename}";
|
||||
sha256 = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
||||
};</pre>
|
||||
</div>
|
||||
</div>
|
||||
<Drawer.Footer>
|
||||
<Drawer.Close>Close</Drawer.Close>
|
||||
</Drawer.Footer>
|
||||
</div>
|
||||
</Drawer.Content>
|
||||
</Drawer.Root>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
class="h-6 w-6"
|
||||
href={`https://raw.githubusercontent.com/${owner}/${repo}/main/${path}/${wallpaper.filename}`}
|
||||
target="_blank"
|
||||
>
|
||||
<Download />
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
</div>
|
||||
<div class="mt-5 flex h-32 w-full flex-col items-center justify-center gap-4 bg-primary/20">
|
||||
<img src="/favicon.png" alt="logo" class="w-5 rounded-md" />
|
||||
<p class="text-muted-foreground">@anotherhadi</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
{#if isLoadingMore}
|
||||
<div class="mt-4 flex justify-center">
|
||||
<Loading />
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
@@ -0,0 +1,632 @@
|
||||
[
|
||||
{
|
||||
"filename": "a-car-and-a-cloud.png",
|
||||
"size": "1.13",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "a-street-in-the-dark.png",
|
||||
"size": "3.99",
|
||||
"width": 2560,
|
||||
"height": 1440
|
||||
},
|
||||
{
|
||||
"filename": "alone-cloud_dark.png",
|
||||
"size": "1.07",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "another-one.png",
|
||||
"size": "1.94",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "another-sky_light.png",
|
||||
"size": "3.52",
|
||||
"width": 2560,
|
||||
"height": 1600
|
||||
},
|
||||
{
|
||||
"filename": "aurora.png",
|
||||
"size": "37.80",
|
||||
"width": 6016,
|
||||
"height": 3900
|
||||
},
|
||||
{
|
||||
"filename": "barcode_minimalist_dark.png",
|
||||
"size": "0.47",
|
||||
"width": 1512,
|
||||
"height": 982
|
||||
},
|
||||
{
|
||||
"filename": "black-and-white-forest_minimalist_black-and-white.png",
|
||||
"size": "2.95",
|
||||
"width": 3888,
|
||||
"height": 2187
|
||||
},
|
||||
{
|
||||
"filename": "black-oil-2_dark.png",
|
||||
"size": "1.04",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "black-oil-3_dark.png",
|
||||
"size": "2.35",
|
||||
"width": 5760,
|
||||
"height": 3840
|
||||
},
|
||||
{
|
||||
"filename": "black-oil_dark.png",
|
||||
"size": "8.56",
|
||||
"width": 7952,
|
||||
"height": 5304
|
||||
},
|
||||
{
|
||||
"filename": "cat-watching-the-star_pixelart_purple_animated.gif",
|
||||
"size": "0.20",
|
||||
"width": 1916,
|
||||
"height": 1078
|
||||
},
|
||||
{
|
||||
"filename": "cat-watching-the-star_pixelart_purple_static.png",
|
||||
"size": "0.02",
|
||||
"width": 1916,
|
||||
"height": 1078
|
||||
},
|
||||
{
|
||||
"filename": "catstraunaut_blue.png",
|
||||
"size": "2.81",
|
||||
"width": 2205,
|
||||
"height": 1240
|
||||
},
|
||||
{
|
||||
"filename": "cloud-in-the-sky_purple.png",
|
||||
"size": "6.79",
|
||||
"width": 4496,
|
||||
"height": 2529
|
||||
},
|
||||
{
|
||||
"filename": "clouds-dodge-the-moon-2.png",
|
||||
"size": "1.96",
|
||||
"width": 2560,
|
||||
"height": 1600
|
||||
},
|
||||
{
|
||||
"filename": "clouds-in-the-sky-2.png",
|
||||
"size": "6.65",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "clouds-in-the-sky-3.png",
|
||||
"size": "1.53",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "clouds-in-the-sky-4_light.png",
|
||||
"size": "2.11",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "clouds-in-the-sky.png",
|
||||
"size": "1.63",
|
||||
"width": 1620,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "coffee-shop.png",
|
||||
"size": "0.93",
|
||||
"width": 1139,
|
||||
"height": 640
|
||||
},
|
||||
{
|
||||
"filename": "degirled.png",
|
||||
"size": "4.28",
|
||||
"width": 5000,
|
||||
"height": 2186
|
||||
},
|
||||
{
|
||||
"filename": "diner-lonely-road.png",
|
||||
"size": "4.80",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "drawing_art_dark.png",
|
||||
"size": "3.22",
|
||||
"width": 2560,
|
||||
"height": 1440
|
||||
},
|
||||
{
|
||||
"filename": "dry-your-laundry.png",
|
||||
"size": "0.36",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "forest-under-the-clouds.png",
|
||||
"size": "11.64",
|
||||
"width": 4288,
|
||||
"height": 2848
|
||||
},
|
||||
{
|
||||
"filename": "free-astronaut.png",
|
||||
"size": "1.11",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "fuji_dark.png",
|
||||
"size": "3.61",
|
||||
"width": 4096,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "fuji_light.png",
|
||||
"size": "6.87",
|
||||
"width": 4096,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "galaxy-grey_pixelart.png",
|
||||
"size": "5.01",
|
||||
"width": 7680,
|
||||
"height": 4320
|
||||
},
|
||||
{
|
||||
"filename": "galaxy_dark.png",
|
||||
"size": "1.79",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "galaxy_pixelart_purple.png",
|
||||
"size": "0.08",
|
||||
"width": 2275,
|
||||
"height": 1280
|
||||
},
|
||||
{
|
||||
"filename": "girl-watching-the-cloud_blue.png",
|
||||
"size": "6.47",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "glacier-2.png",
|
||||
"size": "0.97",
|
||||
"width": 1920,
|
||||
"height": 1344
|
||||
},
|
||||
{
|
||||
"filename": "glacier-3.png",
|
||||
"size": "0.64",
|
||||
"width": 1920,
|
||||
"height": 1344
|
||||
},
|
||||
{
|
||||
"filename": "glacier.png",
|
||||
"size": "0.82",
|
||||
"width": 1920,
|
||||
"height": 1344
|
||||
},
|
||||
{
|
||||
"filename": "grey-mountains_grey.png",
|
||||
"size": "6.06",
|
||||
"width": 5472,
|
||||
"height": 2976
|
||||
},
|
||||
{
|
||||
"filename": "grey-road_grey.png",
|
||||
"size": "2.07",
|
||||
"width": 2880,
|
||||
"height": 1800
|
||||
},
|
||||
{
|
||||
"filename": "grue_blue.png",
|
||||
"size": "1.61",
|
||||
"width": 3206,
|
||||
"height": 1800
|
||||
},
|
||||
{
|
||||
"filename": "hand-blocking-the-sun_blue.png",
|
||||
"size": "9.16",
|
||||
"width": 7680,
|
||||
"height": 4320
|
||||
},
|
||||
{
|
||||
"filename": "horizon.png",
|
||||
"size": "6.62",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "hue-1_minimalist.png",
|
||||
"size": "1.24",
|
||||
"width": 6000,
|
||||
"height": 4000
|
||||
},
|
||||
{
|
||||
"filename": "hue-2_minimalist.png",
|
||||
"size": "0.58",
|
||||
"width": 4000,
|
||||
"height": 3000
|
||||
},
|
||||
{
|
||||
"filename": "hue-3_minimalist.png",
|
||||
"size": "1.09",
|
||||
"width": 6000,
|
||||
"height": 4000
|
||||
},
|
||||
{
|
||||
"filename": "hue-4_minimalist.png",
|
||||
"size": "1.33",
|
||||
"width": 4001,
|
||||
"height": 2251
|
||||
},
|
||||
{
|
||||
"filename": "hue-5_minimalist.png",
|
||||
"size": "32.70",
|
||||
"width": 6016,
|
||||
"height": 3900
|
||||
},
|
||||
{
|
||||
"filename": "hue-6_minimalist_dark.png",
|
||||
"size": "0.23",
|
||||
"width": 1920,
|
||||
"height": 1200
|
||||
},
|
||||
{
|
||||
"filename": "hue-7_minimalist_dark.png",
|
||||
"size": "0.34",
|
||||
"width": 1920,
|
||||
"height": 1200
|
||||
},
|
||||
{
|
||||
"filename": "it-is-some-waves_dark.png",
|
||||
"size": "5.35",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "it-is-the-ocean.png",
|
||||
"size": "0.25",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "japan-moutains_black-and-white.png",
|
||||
"size": "2.51",
|
||||
"width": 4000,
|
||||
"height": 4000
|
||||
},
|
||||
{
|
||||
"filename": "lavender-cat_purple.png",
|
||||
"size": "0.02",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "leef_dark_purple_minimalist.png",
|
||||
"size": "0.91",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "lights-in-the-dark_dark.png",
|
||||
"size": "0.14",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "lofi-setup_blue_purple.png",
|
||||
"size": "3.34",
|
||||
"width": 2912,
|
||||
"height": 1486
|
||||
},
|
||||
{
|
||||
"filename": "lofi-urban_blue.png",
|
||||
"size": "13.10",
|
||||
"width": 2184,
|
||||
"height": 1224
|
||||
},
|
||||
{
|
||||
"filename": "magma.png",
|
||||
"size": "12.14",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "medusa_art_dark.png",
|
||||
"size": "0.20",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "mosaic_dark.png",
|
||||
"size": "9.52",
|
||||
"width": 6016,
|
||||
"height": 3900
|
||||
},
|
||||
{
|
||||
"filename": "moutains-and-a-lac-night_purple.png",
|
||||
"size": "0.49",
|
||||
"width": 2048,
|
||||
"height": 1152
|
||||
},
|
||||
{
|
||||
"filename": "moutains-and-a-lac_black-and-white.png",
|
||||
"size": "1.58",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "moutains-and-a-lac_blue.png",
|
||||
"size": "1.53",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "moutains-and-stars_black.png",
|
||||
"size": "0.63",
|
||||
"width": 3840,
|
||||
"height": 2400
|
||||
},
|
||||
{
|
||||
"filename": "moutains-on-top-of-clouds.png",
|
||||
"size": "0.19",
|
||||
"width": 736,
|
||||
"height": 414
|
||||
},
|
||||
{
|
||||
"filename": "nasa-japan_dark.png",
|
||||
"size": "0.06",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "night-forest_dark.png",
|
||||
"size": "2.25",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "night-road_purple.png",
|
||||
"size": "1.12",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "nix_minimalist_purple.png",
|
||||
"size": "0.05",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "not-earth_dark.png",
|
||||
"size": "3.54",
|
||||
"width": 5120,
|
||||
"height": 2880
|
||||
},
|
||||
{
|
||||
"filename": "nothin-to-see-here_pink_dark.png",
|
||||
"size": "6.47",
|
||||
"width": 5586,
|
||||
"height": 3724
|
||||
},
|
||||
{
|
||||
"filename": "oneway-street_purple.png",
|
||||
"size": "3.92",
|
||||
"width": 2560,
|
||||
"height": 1440
|
||||
},
|
||||
{
|
||||
"filename": "openbox_dark.png",
|
||||
"size": "0.30",
|
||||
"width": 1080,
|
||||
"height": 785
|
||||
},
|
||||
{
|
||||
"filename": "paint-loop_art.png",
|
||||
"size": "19.75",
|
||||
"width": 6016,
|
||||
"height": 3900
|
||||
},
|
||||
{
|
||||
"filename": "pink-sea.png",
|
||||
"size": "5.92",
|
||||
"width": 2912,
|
||||
"height": 1632
|
||||
},
|
||||
{
|
||||
"filename": "pink-sky-moutains_minimalist.png",
|
||||
"size": "0.69",
|
||||
"width": 4096,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "purple-japan_purple.png",
|
||||
"size": "2.70",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "purple-moon_purple.png",
|
||||
"size": "2.18",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "rains-dark_dark.png",
|
||||
"size": "2.01",
|
||||
"width": 1952,
|
||||
"height": 1120
|
||||
},
|
||||
{
|
||||
"filename": "rocket-launch_light.png",
|
||||
"size": "6.42",
|
||||
"width": 5160,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "rocks-misty_light.png",
|
||||
"size": "1.96",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "rose-sky_rose.png",
|
||||
"size": "10.48",
|
||||
"width": 5120,
|
||||
"height": 2880
|
||||
},
|
||||
{
|
||||
"filename": "sakura_pixelart_light_animated.gif",
|
||||
"size": "0.80",
|
||||
"width": 2240,
|
||||
"height": 1085
|
||||
},
|
||||
{
|
||||
"filename": "sakura_pixelart_light_static.png",
|
||||
"size": "0.52",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "sea_blue.png",
|
||||
"size": "6.54",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "snow-and-a-tree_white.png",
|
||||
"size": "2.41",
|
||||
"width": 5120,
|
||||
"height": 3200
|
||||
},
|
||||
{
|
||||
"filename": "snowy-japan-street.png",
|
||||
"size": "3.18",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "space-2.png",
|
||||
"size": "37.45",
|
||||
"width": 6016,
|
||||
"height": 3900
|
||||
},
|
||||
{
|
||||
"filename": "space_dark.png",
|
||||
"size": "0.50",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "strange-forms_blue_purple.png",
|
||||
"size": "2.18",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "sun-is-shining.png",
|
||||
"size": "1.83",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "sushi-keycap_dark.png",
|
||||
"size": "1.23",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "the-cloud-is-hidding-the-moon_dark.png",
|
||||
"size": "0.72",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "time-to-ski_blue.png",
|
||||
"size": "5.46",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "tokyo-skyscraper_dark.png",
|
||||
"size": "36.61",
|
||||
"width": 6512,
|
||||
"height": 4341
|
||||
},
|
||||
{
|
||||
"filename": "tokyo.png",
|
||||
"size": "1.04",
|
||||
"width": 3840,
|
||||
"height": 2160
|
||||
},
|
||||
{
|
||||
"filename": "topology_dark.png",
|
||||
"size": "3.73",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "train_light.png",
|
||||
"size": "0.89",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "vanilla_pink_purple.png",
|
||||
"size": "0.33",
|
||||
"width": 1280,
|
||||
"height": 640
|
||||
},
|
||||
{
|
||||
"filename": "vector-moutains_blue_dark.png",
|
||||
"size": "0.29",
|
||||
"width": 5120,
|
||||
"height": 2880
|
||||
},
|
||||
{
|
||||
"filename": "velvet-moutains_minimalist_dark.png",
|
||||
"size": "1.31",
|
||||
"width": 5120,
|
||||
"height": 2880
|
||||
},
|
||||
{
|
||||
"filename": "wave-dark_minimalist_black-and-white.png",
|
||||
"size": "0.17",
|
||||
"width": 9893,
|
||||
"height": 5565
|
||||
},
|
||||
{
|
||||
"filename": "white-snow-and-a-tree_light.png",
|
||||
"size": "0.41",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
},
|
||||
{
|
||||
"filename": "white-sphere_black-and-white.png",
|
||||
"size": "0.85",
|
||||
"width": 2560,
|
||||
"height": 1440
|
||||
},
|
||||
{
|
||||
"filename": "windows-by-night_dark.png",
|
||||
"size": "7.00",
|
||||
"width": 4510,
|
||||
"height": 2537
|
||||
},
|
||||
{
|
||||
"filename": "windows-problems_flat_minimalist.png",
|
||||
"size": "0.07",
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user