enzostvs's picture
enzostvs HF Staff
gallery viewer
f05d33c
raw
history blame
4.89 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 UserIsLogged from '$lib/components/UserIsLogged.svelte';
import Reactions from '../reactions/Reactions.svelte';
import Button from '$lib/components/Button.svelte';
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}`);
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()}`);
};
</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}
>
<div
class="mx-auto lg:h-2/3 w-full max-w-6xl bg-neutral-900 transition-all duration-200 grid grid-cols-1 lg:grid-cols-2 rounded-xl overflow-hidden"
class:translate-x-full={!open}
use:clickoutside on:clickoutside={handleClose}
>
{#if gallery?.id}
<img src={env.PUBLIC_FILE_UPLOAD_DIR}/{gallery?.image} alt={gallery?.prompt} class="w-full h-full object-cover" />
<div class="flex flex-col justify-between w-full">
<div class="w-full p-8">
<header class="w-full flex items-start justify-between">
<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">
<Reactions reactions={gallery?.reactions} gallery_id={gallery.id} />
<div>
<a
href="/generate?model={gallery?.model?.id}"
class="flex items-center justify-start gap-4 rounded-lg cursor-pointer w-full text-left transition-all duration-200 hover:bg-neutral-950/50 p-3 -mx-3 group relative"
>
<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>
</a>
</div>
<div>
<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>
</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>
</div>