Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
<script lang="ts"> | |
import { clickoutside } from '@svelte-put/clickoutside'; | |
import { goto, invalidate } from "$app/navigation"; | |
import { page } from "$app/stores"; | |
import { get } from "svelte/store"; | |
import Icon from "@iconify/svelte"; | |
import { galleryStore } from "$lib/stores/use-gallery"; | |
import UserIsLogged from '$lib/components/UserIsLogged.svelte'; | |
import Comments from '$lib/components/community/drawer/Comments.svelte'; | |
import Reactions from '$lib/components/community/reactions/Reactions.svelte'; | |
export let form: Record<string, string> | undefined = undefined; | |
let { open, gallery, next, previous } = get(galleryStore); | |
galleryStore.subscribe((value) => { | |
open = value?.open; | |
gallery = value?.gallery; | |
next = value?.next; | |
previous = value?.previous; | |
}); | |
const handleClose = async () => { | |
galleryStore.update((value) => { | |
return { | |
...value, | |
open: false, | |
}; | |
}); | |
await goto(`/gallery`); | |
await invalidate(url => url.pathname.includes("/api/models")); | |
}; | |
const handleClickNext = () => { | |
const element = document.getElementById('gallery_examples'); | |
element?.scrollBy({ | |
left: 300, | |
behavior: 'smooth' | |
}); | |
} | |
const handlePressEscape = (event: KeyboardEvent) => { | |
if (event.key === 'Escape') { | |
handleClose(); | |
} | |
}; | |
const handleClickModel = (id?: string) => { | |
if (!id) return; | |
goto(`/models/${id}`); | |
}; | |
</script> | |
<div | |
class="w-full fixed top-0 left-0 h-full bg-black bg-opacity-50 z-0 backdrop-blur transition-all duration-100" | |
class:opacity-0={!open} | |
class:pointer-events-none={!open} | |
class:!z-40={open} | |
> | |
{#if open} | |
<div | |
class="ml-auto w-full max-w-3xl bg-neutral-950 h-full border-l border-neutral-800 transition-all duration-200 flex flex-col justify-between" | |
use:clickoutside on:clickoutside={handleClose} | |
> | |
{#if gallery?.id} | |
<div class="overflow-auto p-8"> | |
<header class="mb-6 justify-between items-start flex gap-3"> | |
<div class="flex items-center justify-start gap-4"> | |
<img src={gallery?.user?.picture?.startsWith('http') ? gallery?.user?.picture : `https://huggingface.co${gallery?.user?.picture}`} class="w-12 h-12 rounded-full object-cover" alt={gallery?.user?.name} /> | |
<div class="w-full truncate"> | |
<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 cursor-pointer" /> | |
</button> | |
</header> | |
<main class="w-full grid grid-cols-2 gap-5"> | |
<div class="w-full col-span-2"> | |
<Reactions reactions={gallery?.reactions} gallery_id={gallery.id} /> | |
</div> | |
<img src="/api/images/{gallery?.image}" class="max-w-[450px] w-full h-[450px] bg-neutral-800 object-cover rounded-xl col-span-2" alt={gallery?.prompt} /> | |
<div class="col-span-2"> | |
<button | |
class="flex items-center justify-start gap-4 cursor-pointer w-full text-left transition-all duration-200 hover:bg-neutral-900 p-3 group relative rounded-lg" | |
on:click={() => handleClickModel(gallery?.model?.id)} | |
> | |
<img src={gallery?.model?.image} alt={gallery?.model?.id} class="w-14 h-14 rounded-lg object-cover" /> | |
<div> | |
<p class="text-neutral-200 text-base font-medium">{gallery?.model?.id}</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> | |
</main> | |
</div> | |
<footer class="p-8 border-t border-neutral-900 bg-neutral-900/30 flex flex-col justify-between relative max-h-[80%] overflow-auto"> | |
<p class="font-semibold text-neutral-100 text-base lg:text-lg mb-6"> | |
Comment{(gallery?.comments?.length ?? 0) > 1 ? 's' : ''} ({gallery?.comments?.length ?? 0}) | |
</p> | |
{#if gallery?.id} | |
<UserIsLogged> | |
<Comments comments={gallery?.comments} gallery={gallery} /> | |
</UserIsLogged> | |
{/if} | |
</footer> | |
{/if} | |
</div> | |
{/if} | |
</div> | |
<svelte:window on:keydown={handlePressEscape} /> |