Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
<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> |