Spaces:
Running
Running
| <script lang="ts"> | |
| import { goto } from "$app/navigation"; | |
| import { page } from "$app/stores"; | |
| import Icon from "@iconify/svelte"; | |
| import type { CommunityCard } from "$lib/type"; | |
| import { galleryStore } from "$lib/stores/use-gallery"; | |
| import Loading from "$lib/components/Loading.svelte"; | |
| import Reactions from "./reactions/Reactions.svelte"; | |
| import { error, success } from "$lib/utils/toaster"; | |
| export let card: CommunityCard; | |
| export let form: Record<string, string> | undefined = undefined; | |
| export let displayReactions: boolean = true; | |
| export let displayDelete: boolean = false; | |
| export let displayPublish: boolean = false; | |
| let is_visible = true; | |
| let loading = false; | |
| const handleClick = async () => { | |
| goto(`/gallery/${card?.id}`); | |
| }; | |
| const handleDelete = async (id: string) => { | |
| if (loading) return; | |
| loading = true | |
| const request = await fetch(`/api/community/${id}`, { | |
| method: "DELETE" | |
| }); | |
| const { success } = await request.json(); | |
| if (success) is_visible = false; | |
| loading = false; | |
| } | |
| const handlePublish = async (id: string) => { | |
| if (loading) return; | |
| loading = true | |
| const request = await fetch(`/api/community/${id}/publish`, { | |
| method: "POST" | |
| }); | |
| const { success } = await request.json(); | |
| if (success) card.isPublic = true; | |
| loading = false; | |
| } | |
| </script> | |
| <!-- svelte-ignore a11y-no-static-element-interactions --> | |
| <!-- svelte-ignore a11y-click-events-have-key-events --> | |
| {#if is_visible} | |
| <div | |
| class="cursor-pointer group bg-neutral-700 rounded-xl h-[400px] max-w-[400px] md:h-[350px] md:max-w-[350px] w-full relative flex items-start justify-between flex-col p-5 transition-all duration-200 brightness-90 hover:brightness-100 z-[1] overflow-hidden" | |
| on:click={handleClick} | |
| > | |
| <div class="w-full h-full absolute top-0 left-0 -z-[1] rounded-xl overflow-hidden" class:!brightness-50={loading}> | |
| <img class="w-full h-full bg-center bg-cover transition-all duration-200 group-hover:scale-110 object-cover" src="/api/images/{card.image}" alt="{card.prompt}" /> | |
| <div class="bg-gradient-to-b from-transparent via-black/50 to-black/70 absolute h-[100px] bottom-0 left-0 w-full"></div> | |
| </div> | |
| <div class="group-hover:opacity-100 opacity-0 translate-y-full group-hover:translate-y-0 transition-all duration-200 flex flex-col gap-4 w-full"> | |
| <div class="bg-black/40 backdrop-blur-sm border border-white/30 rounded-lg px-6 py-3 text-white transition-all duration-200 w-full relative"> | |
| <p class="text-white font-semibold text-lg break-all">{card.prompt}</p> | |
| <p class="text-white/75 font-regular text-base break-all">{card.model.id}</p> | |
| <button | |
| class="absolute bottom-3 right-3" | |
| on:click={(e) => { | |
| e.stopPropagation(); | |
| e.preventDefault(); | |
| navigator.clipboard.writeText(card.prompt); | |
| success("Prompt copied to clipboard"); | |
| }} | |
| > | |
| <Icon icon="solar:copy-bold-duotone" class="w-5 h-5 text-white/75 hover:text-white" /> | |
| </button> | |
| </div> | |
| </div> | |
| {#if displayReactions} | |
| <Reactions reactions={card.reactions} gallery_id={card.id} /> | |
| {/if} | |
| {#if displayPublish || displayDelete} | |
| <div class="absolute bottom-0 left-0 w-full p-4 flex items-center justify-end gap-3"> | |
| {#if displayPublish && !card.isPublic} | |
| <button | |
| class="px-4 py-2.5 text-white rounded-full bg-blue-500 backdrop-blur-sm text-sm font-medium transition-all duration-200 hover:bg-blue-700" | |
| on:click={(e) => { | |
| e.stopPropagation(); | |
| e.preventDefault(); | |
| handlePublish(card.id); | |
| success("Published successfully"); | |
| }} | |
| > | |
| Publish | |
| </button> | |
| {/if} | |
| {#if displayDelete} | |
| <button | |
| class="p-2.5 rounded-full bg-red-500 backdrop-blur-sm transition-all duration-200 hover:bg-red-700" | |
| on:click={(e) => { | |
| e.stopPropagation(); | |
| e.preventDefault(); | |
| handleDelete(card.id); | |
| error("Deleted successfully"); | |
| }} | |
| > | |
| <Icon icon="ic:round-delete" class="text-white w-5 h-5" /> | |
| </button> | |
| {/if} | |
| </div> | |
| {/if} | |
| {#if loading} | |
| <Loading /> | |
| {/if} | |
| </div> | |
| {/if} |