enzostvs's picture
enzostvs HF staff
drawer gallery view + WIP: redo the response check, user is able to post multiple time the same img
0d4cbee
raw
history blame
5.67 kB
<script lang="ts">
import { clickoutside } from '@svelte-put/clickoutside';
import { goto } from "$app/navigation";
import { page } from "$app/stores";
import { get } from "svelte/store";
import { env } from "$env/dynamic/public";
import Icon from "@iconify/svelte";
import { galleryStore } from "$lib/stores/use-gallery";
import Reactions from '../reactions/Reactions.svelte';
import Button from '$lib/components/Button.svelte';
export let form: Record<string, string>;
let { open, gallery, previous, next } = get(galleryStore);
let loading = false;
galleryStore.subscribe((value) => {
open = value?.open;
gallery = value?.gallery;
previous = value?.previous;
next = value?.next;
});
const handleClose = () => {
galleryStore.update((value) => {
return {
...value,
open: false,
};
});
$page.url.searchParams.delete('model');
goto(`?${$page.url.searchParams.toString()}`);
};
const handlePagination = async (id?: string) => {
if (!id) return;
loading = true;
const request = await fetch(`/api/community/${id}?${new URLSearchParams(form)}`);
const { gallery, next, previous } = await request.json();
galleryStore.set({
gallery,
open: true,
next,
previous
});
loading = false;
$page.url.searchParams.set('gallery', id);
goto(`?${$page.url.searchParams.toString()}`);
};
// to url search params
const handleClickModel = (id?: string) => {
if (!id) return;
$page.url.searchParams.set('model', id);
$page.url.searchParams.delete('gallery');
goto(`/?${$page.url.searchParams.toString()}`);
};
</script>
<div
class="w-full fixed top-0 left-0 h-full bg-black bg-opacity-50 z-40 backdrop-blur transition-all duration-100 p-6 lg:p-10 flex items-center justify-center"
class:opacity-0={!open}
class:pointer-events-none={!open}
>
{#if open}
<div
class="mx-auto w-full max-w-6xl bg-neutral-900 transition-all duration-200 lg:grid lg:grid-cols-2 rounded-xl overflow-hidden"
use:clickoutside on:clickoutside={handleClose}
>
{#if gallery?.id}
<img src={env.PUBLIC_FILE_UPLOAD_DIR}/{gallery?.image} alt={gallery?.prompt} class="w-full object-cover h-[200px] lg:h-auto" />
<div class="flex flex-col justify-between w-full overflow-auto flex-1">
<div class="w-full p-6">
<header class="w-full flex items-start justify-between px-2 pt-2">
<div class="flex items-center justify-start gap-4">
<img src={gallery?.user?.picture} class="w-12 h-12 rounded-full object-cover" alt={gallery?.user?.name} />
<div>
<p class="text-neutral-100 font-bold text-lg">
{gallery?.user?.name}
</p>
<p class="text-neutral-400 text-sm">
@{gallery?.user?.preferred_username}
</p>
</div>
</div>
<button on:click={handleClose}>
<Icon icon="carbon:close" class="w-6 h-6 text-white" />
</button>
</header>
<div class="mt-8 grid grid-cols-1 gap-5 overflow-auto">
<div class="w-full px-2">
<Reactions reactions={gallery?.reactions} gallery_id={gallery.id} />
</div>
<div>
<button
class="flex items-center justify-start gap-4 cursor-pointer w-full text-left transition-all duration-200 hover:bg-neutral-950/50 p-3 group relative rounded-lg"
on:click={() => handleClickModel(gallery?.model?.id)}
>
<img src={gallery?.model?.image} alt={gallery?.model?.title} class="w-14 h-14 rounded-lg object-cover" />
<div>
<p class="text-neutral-200 text-base font-medium">{gallery?.model?.title}</p>
<p class="text-neutral-400 text-sm">{gallery?.model?.id}</p>
</div>
<div class="rounded-full absolute top-1/2 -translate-y-1/2 text-neutral-100 w-8 h-8 right-4 bg-pink-500 flex items-center justify-center transition-all duration-200 group-hover:opacity-100 opacity-0">
<Icon icon="tabler:arrow-up" class="w-5 h-5 transform rotate-45 font-bold" />
</div>
</button>
</div>
<div class="px-2">
<p class="text-neutral-400 font-semibold text-xs uppercase">
Prompt
</p>
<p class="text-neutral-200 text-base font-medium mt-2">"{gallery?.prompt}"</p>
</div>
<div class="px-2">
<p class="text-neutral-400 font-semibold text-xs uppercase">
Dimension
</p>
<p class="text-neutral-200 text-base font-medium mt-2">1024x1024</p>
</div>
</div>
</div>
<footer class="border-t border-neutral-800 px-8 py-6 flex items-center justify-between">
<Button
size="lg"
theme="dark"
disabled={!previous}
loading={loading}
onClick={() => handlePagination(previous)}
>
Previous
</Button>
<Button
size="lg"
theme="light"
loading={loading}
disabled={!next}
onClick={() => handlePagination(next)}
>
Next
</Button>
</footer>
</div>
{/if}
</div>
{/if}
</div>