add search, footer, css correction

This commit is contained in:
Hadi
2025-03-27 11:08:12 +01:00
parent 6a5f4d4ae2
commit d13bca5004
2 changed files with 188 additions and 167 deletions
+187 -167
View File
@@ -10,6 +10,7 @@
import { toast } from 'svelte-sonner'; import { toast } from 'svelte-sonner';
import Filters from './filters.svelte'; import Filters from './filters.svelte';
import Loading from './loading.svelte'; import Loading from './loading.svelte';
import Input from '$lib/components/ui/input/input.svelte';
type Wallpaper = { type Wallpaper = {
name: string; name: string;
@@ -23,12 +24,15 @@
sha256: string; sha256: string;
}; };
const version = 'v0.1.0';
const owner = 'anotherhadi'; const owner = 'anotherhadi';
const repo = 'awesome-wallpapers'; const repo = 'awesome-wallpapers';
const path = 'wallpapers'; const path = 'wallpapers';
const apiUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${path}`; const apiUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${path}`;
let search: string = $state('');
let wallpapers: Wallpaper[] = $state([]); let wallpapers: Wallpaper[] = $state([]);
const batchSize = 10;
let allTags: string[] = $state([]); let allTags: string[] = $state([]);
let selectedTags: string[] = $state([]); let selectedTags: string[] = $state([]);
@@ -40,61 +44,71 @@
.catch(() => toast.error('Failed to copy')); .catch(() => toast.error('Failed to copy'));
}; };
onMount(() => { const fetchWallpapers = async () => {
const fetchWallpapers = async () => { try {
try { const response = await axios.get(apiUrl, {
const response = await axios.get(apiUrl, { headers: { Accept: 'application/vnd.github.v3+json' }
headers: { Accept: 'application/vnd.github.v3+json' } });
});
if (Array.isArray(response.data)) { if (Array.isArray(response.data)) {
const promises = response.data.map(async (file) => { const files = response.data;
let [namePart, ...tagsArray] = file.name.split('.')[0].split('_'); // Traitement par lots
let tagsPart = tagsArray.join('_'); for (let i = 0; i < files.length; i += batchSize) {
let name = namePart.replace(/-/g, ' ').replace(/\b\w/, (l: string) => l.toUpperCase()); const batch = files.slice(i, i + batchSize);
let tags = tagsPart ? tagsPart.split('_') : []; const batchResults = await Promise.all(
let size = (file.size / 1024 / 1024).toFixed(2); 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) => { tags.forEach((tag: string) => {
if (!allTags.includes(tag)) { if (!allTags.includes(tag)) {
allTags.push(tag); allTags.push(tag);
} }
}); });
const img = new Image(); const img = new Image();
img.src = `https://raw.githubusercontent.com/${owner}/${repo}/main/${path}/${file.name}`; img.src = `https://raw.githubusercontent.com/${owner}/${repo}/main/${path}/${file.name}`;
return new Promise<Wallpaper>((resolve) => { return new Promise<Wallpaper>((resolve) => {
img.onload = () => { img.onload = () => {
resolve({ resolve({
name, name,
filename: file.name, filename: file.name,
tags, tags,
size, size,
width: img.width, width: img.width,
height: img.height, height: img.height,
more: false, more: false,
hovered: false, hovered: false,
sha256: 'sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=' sha256: 'sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='
}); });
}; };
}); });
}); })
);
wallpapers = await Promise.all(promises); wallpapers = [...wallpapers, ...batchResults];
} else { // Optionnel : attendre un peu avant de charger le batch suivant
console.error('Error'); await new Promise((r) => setTimeout(r, 100));
} }
} catch (error) { } else {
console.error('Error: ', error); console.error('Error');
} }
}; } catch (error) {
console.error('Error: ', error);
}
};
fetchWallpapers(); onMount(fetchWallpapers);
});
</script> </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"> <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" <Badge class="gap-2" href={'https://github.com/' + owner + '/' + repo} target="_blank"
>Check the github repo <ChevronRight size={16} /></Badge >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> <p class="text-muted-foreground">Open-source wallpapers collection from {owner}/{repo}</p>
</header> </header>
<main class="mx-10"> <main class="px-10">
<div class="px-2 py-4"> <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} /> <Filters title="Tags" options={allTags} bind:selectedValues={selectedTags} />
</div> </div>
{#if wallpapers.length === 0} {#if wallpapers.length === 0}
<Loading /> <Loading />
{:else} {: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} {#each wallpapers as wallpaper}
{#if selectedTags.length === 0 || selectedTags.some( (tag) => wallpaper.tags.includes(tag) )} {#if selectedTags.length === 0 || selectedTags.some( (tag) => wallpaper.tags.includes(tag) )}
<div class="rounded-t-md bg-muted/5"> {#if wallpaper.name.toLowerCase().includes(search.toLowerCase())}
<div class="relative"> <div class="rounded-t-md bg-muted/5">
<AspectRatio <div class="relative">
ratio={16 / 9} <AspectRatio
class="w-full rounded-md bg-muted" ratio={16 / 9}
onmouseenter={() => (wallpaper.hovered = true)} class="w-full rounded-md bg-muted"
onmouseleave={() => (wallpaper.hovered = false)} onmouseenter={() => (wallpaper.hovered = true)}
> onmouseleave={() => (wallpaper.hovered = false)}
{#if wallpaper.hovered} >
<div {#if wallpaper.hovered}
class="absolute bottom-0 left-0 right-0 top-0 z-[10] flex items-center justify-center bg-primary/20" <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> <Button
{/if} href={`https://raw.githubusercontent.com/${owner}/${repo}/main/${path}/${wallpaper.filename}`}
<img target="_blank">Download</Button
src={`https://raw.githubusercontent.com/${owner}/${repo}/main/${path}/${wallpaper.filename}`} >
alt={wallpaper.name + ' wallpaper'} </div>
class="h-full w-full rounded-md object-cover" {/if}
/> <img
</AspectRatio> src={`https://raw.githubusercontent.com/${owner}/${repo}/main/${path}/${wallpaper.filename}`}
</div> alt={wallpaper.name + ' wallpaper'}
<div class="flex w-full items-center justify-between p-2"> class="h-full w-full rounded-md object-cover"
{wallpaper.name} />
<div class="flex gap-2"> </AspectRatio>
<Drawer.Root> </div>
<Drawer.Trigger> <div class="flex w-full items-center justify-between p-2">
<Button size="icon" variant="ghost" class="h-6 w-6"> {wallpaper.name}
<Info /> <div class="flex gap-2">
</Button> <Drawer.Root>
</Drawer.Trigger> <Drawer.Trigger>
<Drawer.Content> <Button size="icon" variant="ghost" class="h-6 w-6">
<div class="m-auto w-full max-w-3xl select-text"> <Info />
<Drawer.Header> </Button>
<Drawer.Title>{wallpaper.name}</Drawer.Title> </Drawer.Trigger>
</Drawer.Header> <Drawer.Content>
<div class="p-4 pb-0"> <div class="m-auto w-full max-w-3xl select-text">
<p> <Drawer.Header>
<span class="text-muted-foreground">Filename:</span> <Drawer.Title>{wallpaper.name}</Drawer.Title>
{wallpaper.filename} </Drawer.Header>
</p> <div class="p-4 pb-0">
<p><span class="text-muted-foreground">Name:</span> {wallpaper.name}</p> <p>
<p> <span class="text-muted-foreground">Filename:</span>
<span class="text-muted-foreground">Size:</span> {wallpaper.filename}
{wallpaper.size} Mb </p>
</p> <p><span class="text-muted-foreground">Name:</span> {wallpaper.name}</p>
<p> <p>
<span class="text-muted-foreground">Resolution:</span> <span class="text-muted-foreground">Size:</span>
{wallpaper.width}x{wallpaper.height} {wallpaper.size} Mb
</p> </p>
<p> <p>
<span class="text-muted-foreground">Tags:</span> <span class="text-muted-foreground">Resolution:</span>
{#each wallpaper.tags as tag} {wallpaper.width}x{wallpaper.height}
<Badge variant="outline">{tag}</Badge> </p>
{/each} <p>
</p> <span class="text-muted-foreground">Tags:</span>
<p class="mt-2"> {#each wallpaper.tags as tag}
<span class="text-muted-foreground">Nix fetchurl:</span> <Badge variant="outline">{tag}</Badge>
</p> {/each}
</p>
<p class="mt-2">
<span class="text-muted-foreground">Nix fetchurl:</span>
</p>
<div class="relative"> <div class="relative">
<Button <Button
size="icon" size="icon"
variant="ghost" variant="ghost"
class="absolute right-2 top-2 h-6 w-6" class="absolute right-2 top-2 h-6 w-6"
onclick={() => { onclick={() => {
let content = ` let content = `
image = pkgs.fetchurl { image = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/${owner}/${repo}/refs/heads/main/${path}/${wallpaper.filename}"; url = "https://raw.githubusercontent.com/${owner}/${repo}/refs/heads/main/${path}/${wallpaper.filename}";
sha256 = "${wallpaper.sha256}"; sha256 = "${wallpaper.sha256}";
};`; };`;
copyToClipboard(content); copyToClipboard(content);
}} }}
> >
<Copy /> <Copy />
</Button> </Button>
<pre <pre
id={wallpaper.filename} 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"> 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 &lbrace; image = pkgs.fetchurl &lbrace;
url = "https://raw.githubusercontent.com/{owner}/{repo}/refs/heads/main/{path}/{wallpaper.filename}"; url = "https://raw.githubusercontent.com/{owner}/{repo}/refs/heads/main/{path}/{wallpaper.filename}";
sha256 = "{wallpaper.sha256}"; sha256 = "{wallpaper.sha256}";
&rbrace;</pre> &rbrace;;</pre>
</div>
</div> </div>
<Drawer.Footer>
<Drawer.Close>Close</Drawer.Close>
</Drawer.Footer>
</div> </div>
<Drawer.Footer> </Drawer.Content>
<Drawer.Close>Close</Drawer.Close> </Drawer.Root>
</Drawer.Footer> <Button
</div> size="icon"
</Drawer.Content> variant="ghost"
</Drawer.Root> class="h-6 w-6"
<Button onclick={() => (wallpaper.more = !wallpaper.more)}
size="icon" >
variant="ghost" <ChevronsUpDown />
class="h-6 w-6" </Button>
onclick={() => (wallpaper.more = !wallpaper.more)} <Button
> size="icon"
<ChevronsUpDown /> variant="ghost"
</Button> class="h-6 w-6"
<Button href={`https://raw.githubusercontent.com/${owner}/${repo}/main/${path}/${wallpaper.filename}`}
size="icon" target="_blank"
variant="ghost" >
class="h-6 w-6" <Download />
href={`https://raw.githubusercontent.com/${owner}/${repo}/main/${path}/${wallpaper.filename}`} </Button>
target="_blank" </div>
>
<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> </div>
{#if wallpaper.more} {/if}
<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} {/each}
</div> </div>
{/if} {/if}
</main> </main>
</div> </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>
+1
View File
@@ -2,3 +2,4 @@
base = "app" base = "app"
publish = "build" publish = "build"
command = "pnpm build" command = "pnpm build"
ignore = "git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF ."