mirror of
https://github.com/anotherhadi/awesome-wallpapers.git
synced 2026-10-05 18:28:25 +02:00
add search, footer, css correction
This commit is contained in:
+187
-167
@@ -10,6 +10,7 @@
|
||||
import { toast } from 'svelte-sonner';
|
||||
import Filters from './filters.svelte';
|
||||
import Loading from './loading.svelte';
|
||||
import Input from '$lib/components/ui/input/input.svelte';
|
||||
|
||||
type Wallpaper = {
|
||||
name: string;
|
||||
@@ -23,12 +24,15 @@
|
||||
sha256: string;
|
||||
};
|
||||
|
||||
const version = 'v0.1.0';
|
||||
const owner = 'anotherhadi';
|
||||
const repo = 'awesome-wallpapers';
|
||||
const path = 'wallpapers';
|
||||
const apiUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${path}`;
|
||||
|
||||
let search: string = $state('');
|
||||
let wallpapers: Wallpaper[] = $state([]);
|
||||
const batchSize = 10;
|
||||
|
||||
let allTags: string[] = $state([]);
|
||||
let selectedTags: string[] = $state([]);
|
||||
@@ -40,61 +44,71 @@
|
||||
.catch(() => toast.error('Failed to copy'));
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
const fetchWallpapers = async () => {
|
||||
try {
|
||||
const response = await axios.get(apiUrl, {
|
||||
headers: { Accept: 'application/vnd.github.v3+json' }
|
||||
});
|
||||
const fetchWallpapers = async () => {
|
||||
try {
|
||||
const response = await axios.get(apiUrl, {
|
||||
headers: { Accept: 'application/vnd.github.v3+json' }
|
||||
});
|
||||
|
||||
if (Array.isArray(response.data)) {
|
||||
const promises = response.data.map(async (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);
|
||||
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);
|
||||
|
||||
tags.forEach((tag: string) => {
|
||||
if (!allTags.includes(tag)) {
|
||||
allTags.push(tag);
|
||||
}
|
||||
});
|
||||
tags.forEach((tag: string) => {
|
||||
if (!allTags.includes(tag)) {
|
||||
allTags.push(tag);
|
||||
}
|
||||
});
|
||||
|
||||
const img = new Image();
|
||||
img.src = `https://raw.githubusercontent.com/${owner}/${repo}/main/${path}/${file.name}`;
|
||||
const img = new Image();
|
||||
img.src = `https://raw.githubusercontent.com/${owner}/${repo}/main/${path}/${file.name}`;
|
||||
|
||||
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 = await Promise.all(promises);
|
||||
} else {
|
||||
console.error('Error');
|
||||
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));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error: ', error);
|
||||
} else {
|
||||
console.error('Error');
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error: ', error);
|
||||
}
|
||||
};
|
||||
|
||||
fetchWallpapers();
|
||||
});
|
||||
onMount(fetchWallpapers);
|
||||
</script>
|
||||
|
||||
<div class="flex min-h-[100vh] flex-col gap-5 bg-background">
|
||||
<div class="relative flex min-h-[100vh] flex-col gap-5 bg-background">
|
||||
<p class="absolute right-0 top-0 m-2 text-muted-foreground">{version}</p>
|
||||
<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
|
||||
@@ -103,151 +117,157 @@
|
||||
<p class="text-muted-foreground">Open-source wallpapers collection from {owner}/{repo}</p>
|
||||
</header>
|
||||
|
||||
<main class="mx-10">
|
||||
<div class="px-2 py-4">
|
||||
<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-2 gap-5">
|
||||
<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) )}
|
||||
<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/20"
|
||||
>
|
||||
<Button
|
||||
href={`https://raw.githubusercontent.com/${owner}/${repo}/main/${path}/${wallpaper.filename}`}
|
||||
target="_blank">Download</Button
|
||||
{#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"
|
||||
>
|
||||
</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>
|
||||
<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 = `
|
||||
<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>
|
||||
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 dark:bg-zinc-900">
|
||||
<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 dark:bg-zinc-900">
|
||||
image = pkgs.fetchurl {
|
||||
url = "https://raw.githubusercontent.com/{owner}/{repo}/refs/heads/main/{path}/{wallpaper.filename}";
|
||||
sha256 = "{wallpaper.sha256}";
|
||||
}</pre>
|
||||
};</pre>
|
||||
</div>
|
||||
</div>
|
||||
<Drawer.Footer>
|
||||
<Drawer.Close>Close</Drawer.Close>
|
||||
</Drawer.Footer>
|
||||
</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"
|
||||
>
|
||||
<Download />
|
||||
</Button>
|
||||
</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"
|
||||
>
|
||||
<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}
|
||||
</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}
|
||||
</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>
|
||||
|
||||
Reference in New Issue
Block a user