Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
use last generated image as a thumbnail
Browse files- package-lock.json +6 -0
- package.json +1 -0
- src/lib/components/community/drawer/Drawer.svelte +2 -1
- src/lib/components/generate/Response.svelte +3 -1
- src/lib/components/models/Card.svelte +3 -1
- src/lib/components/models/autocomplete/Autocomplete.svelte +2 -1
- src/lib/components/models/autocomplete/Item.svelte +3 -2
- src/lib/components/models/drawer/Drawer.svelte +2 -1
- src/lib/components/models/image/Image.svelte +29 -0
- src/routes/+layout.svelte +1 -0
- src/routes/api/community/[id]/+server.ts +12 -0
- src/routes/api/models/+server.ts +20 -0
- src/routes/api/models/[id]/+server.ts +12 -0
- src/routes/api/scrap-models/+server.ts +4 -5
package-lock.json
CHANGED
@@ -10,6 +10,7 @@
|
|
10 |
"dependencies": {
|
11 |
"@aws-sdk/client-s3": "^3.490.0",
|
12 |
"@huggingface/hub": "^0.12.3",
|
|
|
13 |
"@iconify/svelte": "^3.1.4",
|
14 |
"@prisma/client": "^5.7.1",
|
15 |
"@svelte-put/clickoutside": "^3.0.1",
|
@@ -1379,6 +1380,11 @@
|
|
1379 |
"node": ">=18"
|
1380 |
}
|
1381 |
},
|
|
|
|
|
|
|
|
|
|
|
1382 |
"node_modules/@humanwhocodes/config-array": {
|
1383 |
"version": "0.11.13",
|
1384 |
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
|
|
|
10 |
"dependencies": {
|
11 |
"@aws-sdk/client-s3": "^3.490.0",
|
12 |
"@huggingface/hub": "^0.12.3",
|
13 |
+
"@huggingface/space-header": "^1.0.1",
|
14 |
"@iconify/svelte": "^3.1.4",
|
15 |
"@prisma/client": "^5.7.1",
|
16 |
"@svelte-put/clickoutside": "^3.0.1",
|
|
|
1380 |
"node": ">=18"
|
1381 |
}
|
1382 |
},
|
1383 |
+
"node_modules/@huggingface/space-header": {
|
1384 |
+
"version": "1.0.1",
|
1385 |
+
"resolved": "https://registry.npmjs.org/@huggingface/space-header/-/space-header-1.0.1.tgz",
|
1386 |
+
"integrity": "sha512-sSHZgWoeCKydlWm/qqIzDwqSHUzr9MqFkS58LZPSnSZNMvhRgU8qQCn9TXHAicFuYyW9W3JkCkc2RpnkfAycyw=="
|
1387 |
+
},
|
1388 |
"node_modules/@humanwhocodes/config-array": {
|
1389 |
"version": "0.11.13",
|
1390 |
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
|
package.json
CHANGED
@@ -43,6 +43,7 @@
|
|
43 |
"dependencies": {
|
44 |
"@aws-sdk/client-s3": "^3.490.0",
|
45 |
"@huggingface/hub": "^0.12.3",
|
|
|
46 |
"@iconify/svelte": "^3.1.4",
|
47 |
"@prisma/client": "^5.7.1",
|
48 |
"@svelte-put/clickoutside": "^3.0.1",
|
|
|
43 |
"dependencies": {
|
44 |
"@aws-sdk/client-s3": "^3.490.0",
|
45 |
"@huggingface/hub": "^0.12.3",
|
46 |
+
"@huggingface/space-header": "^1.0.1",
|
47 |
"@iconify/svelte": "^3.1.4",
|
48 |
"@prisma/client": "^5.7.1",
|
49 |
"@svelte-put/clickoutside": "^3.0.1",
|
src/lib/components/community/drawer/Drawer.svelte
CHANGED
@@ -9,6 +9,7 @@
|
|
9 |
import UserIsLogged from '$lib/components/UserIsLogged.svelte';
|
10 |
import Comments from '$lib/components/community/drawer/Comments.svelte';
|
11 |
import Reactions from '$lib/components/community/reactions/Reactions.svelte';
|
|
|
12 |
|
13 |
export let form: Record<string, string> | undefined = undefined;
|
14 |
let { open, gallery, next, previous } = get(galleryStore);
|
@@ -91,7 +92,7 @@
|
|
91 |
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"
|
92 |
on:click={() => handleClickModel(gallery?.model?.id)}
|
93 |
>
|
94 |
-
<
|
95 |
<div>
|
96 |
<p class="text-neutral-200 text-base font-medium">{gallery?.model?.id}</p>
|
97 |
<p class="text-neutral-400 text-sm">{gallery?.model?.id}</p>
|
|
|
9 |
import UserIsLogged from '$lib/components/UserIsLogged.svelte';
|
10 |
import Comments from '$lib/components/community/drawer/Comments.svelte';
|
11 |
import Reactions from '$lib/components/community/reactions/Reactions.svelte';
|
12 |
+
import Image from '$lib/components/models/image/Image.svelte';
|
13 |
|
14 |
export let form: Record<string, string> | undefined = undefined;
|
15 |
let { open, gallery, next, previous } = get(galleryStore);
|
|
|
92 |
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"
|
93 |
on:click={() => handleClickModel(gallery?.model?.id)}
|
94 |
>
|
95 |
+
<Image src={gallery?.model?.image} generatedImage={gallery?.model?.gallery?.[0]?.image} className="w-14 h-14 rounded-lg object-cover" alt={gallery?.model?.id} />
|
96 |
<div>
|
97 |
<p class="text-neutral-200 text-base font-medium">{gallery?.model?.id}</p>
|
98 |
<p class="text-neutral-400 text-sm">{gallery?.model?.id}</p>
|
src/lib/components/generate/Response.svelte
CHANGED
@@ -4,6 +4,7 @@
|
|
4 |
import { userStore } from "$lib/stores/use-user";
|
5 |
import Icon from "@iconify/svelte";
|
6 |
import { goto } from "$app/navigation";
|
|
|
7 |
|
8 |
export let loading_generation: boolean = false;
|
9 |
|
@@ -114,7 +115,8 @@
|
|
114 |
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"
|
115 |
on:click={() => handleClickModel($generationStore?.form?.model.id)}
|
116 |
>
|
117 |
-
<img src={$generationStore?.form?.model.image} alt={$generationStore?.form?.model.title} class="w-14 h-14 rounded-lg object-cover" />
|
|
|
118 |
<div>
|
119 |
<p class="text-neutral-200 text-base font-medium">{$generationStore?.form?.model.id}</p>
|
120 |
<p class="text-neutral-400 text-sm">{$generationStore?.form?.model.id}</p>
|
|
|
4 |
import { userStore } from "$lib/stores/use-user";
|
5 |
import Icon from "@iconify/svelte";
|
6 |
import { goto } from "$app/navigation";
|
7 |
+
import Image from "../models/image/Image.svelte";
|
8 |
|
9 |
export let loading_generation: boolean = false;
|
10 |
|
|
|
115 |
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"
|
116 |
on:click={() => handleClickModel($generationStore?.form?.model.id)}
|
117 |
>
|
118 |
+
<!-- <img src={$generationStore?.form?.model.image} alt={$generationStore?.form?.model.title} class="w-14 h-14 rounded-lg object-cover" /> -->
|
119 |
+
<Image src={$generationStore?.form?.model?.image} generatedImage={$generationStore?.form?.model?.gallery?.[0]?.image} className="w-14 h-14 rounded-lg object-cover" alt={$generationStore?.form?.model?.id} />
|
120 |
<div>
|
121 |
<p class="text-neutral-200 text-base font-medium">{$generationStore?.form?.model.id}</p>
|
122 |
<p class="text-neutral-400 text-sm">{$generationStore?.form?.model.id}</p>
|
src/lib/components/models/Card.svelte
CHANGED
@@ -6,6 +6,7 @@
|
|
6 |
import Button from "$lib/components/Button.svelte";
|
7 |
import { success } from "$lib/utils/toaster";
|
8 |
import { userStore } from "$lib/stores/use-user";
|
|
|
9 |
|
10 |
export let card: ModelCard;
|
11 |
|
@@ -35,6 +36,7 @@
|
|
35 |
success("Model unpublished successfully!");
|
36 |
}
|
37 |
};
|
|
|
38 |
</script>
|
39 |
|
40 |
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
@@ -44,7 +46,7 @@
|
|
44 |
on:click={handleClick}
|
45 |
>
|
46 |
<div class="w-full h-[350px] relative z-[1] mb-3 overflow-hidden">
|
47 |
-
<
|
48 |
{#if $userStore?.is_admin}
|
49 |
<div
|
50 |
class="absolute flex items-center justify-between bottom-0 left-0 w-full p-5 bg-gradient-to-t from-black to-transparent"
|
|
|
6 |
import Button from "$lib/components/Button.svelte";
|
7 |
import { success } from "$lib/utils/toaster";
|
8 |
import { userStore } from "$lib/stores/use-user";
|
9 |
+
import Image from "./image/Image.svelte";
|
10 |
|
11 |
export let card: ModelCard;
|
12 |
|
|
|
36 |
success("Model unpublished successfully!");
|
37 |
}
|
38 |
};
|
39 |
+
console.log(card)
|
40 |
</script>
|
41 |
|
42 |
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
|
46 |
on:click={handleClick}
|
47 |
>
|
48 |
<div class="w-full h-[350px] relative z-[1] mb-3 overflow-hidden">
|
49 |
+
<Image src={card.image} generatedImage={card?.gallery?.[0]?.image} className="w-full h-full bg-center bg-cover rounded-lg object-cover object-center bg-neutral-800" alt={card?.id} />
|
50 |
{#if $userStore?.is_admin}
|
51 |
<div
|
52 |
class="absolute flex items-center justify-between bottom-0 left-0 w-full p-5 bg-gradient-to-t from-black to-transparent"
|
src/lib/components/models/autocomplete/Autocomplete.svelte
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
import type { ModelCard } from "$lib/type";
|
4 |
import Icon from "@iconify/svelte";
|
5 |
import Item from "./Item.svelte";
|
|
|
6 |
|
7 |
export let defaultModels: ModelCard[] = [];
|
8 |
export let onChange: (model: ModelCard |Β null) => void;
|
@@ -51,7 +52,7 @@
|
|
51 |
{#if value}
|
52 |
<div class="flex items-center justify-between gap-4">
|
53 |
<div class="flex items-center justify-start gap-3">
|
54 |
-
<
|
55 |
<p class="text-neutral-200 text-base font-medium">{value.id}</p>
|
56 |
</div>
|
57 |
<button on:click={() => onChange(null)}>
|
|
|
3 |
import type { ModelCard } from "$lib/type";
|
4 |
import Icon from "@iconify/svelte";
|
5 |
import Item from "./Item.svelte";
|
6 |
+
import Image from '../image/Image.svelte';
|
7 |
|
8 |
export let defaultModels: ModelCard[] = [];
|
9 |
export let onChange: (model: ModelCard |Β null) => void;
|
|
|
52 |
{#if value}
|
53 |
<div class="flex items-center justify-between gap-4">
|
54 |
<div class="flex items-center justify-start gap-3">
|
55 |
+
<Image src={value?.image} generatedImage={value?.gallery?.[0]?.image} className="w-6 h-6 rounded-lg object-cover" alt={value?.id} />
|
56 |
<p class="text-neutral-200 text-base font-medium">{value.id}</p>
|
57 |
</div>
|
58 |
<button on:click={() => onChange(null)}>
|
src/lib/components/models/autocomplete/Item.svelte
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
<script lang="ts">
|
2 |
import type { ModelCard } from "$lib/type";
|
3 |
-
|
|
|
4 |
export let model: ModelCard;
|
5 |
export let onClick: () => void;
|
6 |
|
@@ -10,7 +11,7 @@
|
|
10 |
class="flex items-center justify-start gap-4 px-2 py-2.5 hover:bg-neutral-800/60 transition-all duration-200 rounded-lg cursor-pointer w-full text-left"
|
11 |
on:click={onClick}
|
12 |
>
|
13 |
-
<
|
14 |
<div>
|
15 |
<p class="text-neutral-200 text-base font-medium">{model.id}</p>
|
16 |
<p class="text-neutral-400 text-sm">{model.id}</p>
|
|
|
1 |
<script lang="ts">
|
2 |
import type { ModelCard } from "$lib/type";
|
3 |
+
import Image from "../image/Image.svelte";
|
4 |
+
|
5 |
export let model: ModelCard;
|
6 |
export let onClick: () => void;
|
7 |
|
|
|
11 |
class="flex items-center justify-start gap-4 px-2 py-2.5 hover:bg-neutral-800/60 transition-all duration-200 rounded-lg cursor-pointer w-full text-left"
|
12 |
on:click={onClick}
|
13 |
>
|
14 |
+
<Image src={model?.image} generatedImage={model?.gallery?.[0]?.image} className="w-14 h-14 rounded-lg object-cover" alt={model?.id} />
|
15 |
<div>
|
16 |
<p class="text-neutral-200 text-base font-medium">{model.id}</p>
|
17 |
<p class="text-neutral-400 text-sm">{model.id}</p>
|
src/lib/components/models/drawer/Drawer.svelte
CHANGED
@@ -8,6 +8,7 @@
|
|
8 |
import { modelStore } from "$lib/stores/use-model";
|
9 |
import UserIsLogged from '$lib/components/UserIsLogged.svelte';
|
10 |
import Comments from '$lib/components/models/drawer/comments/Comments.svelte';
|
|
|
11 |
|
12 |
let { open, model } = get(modelStore);
|
13 |
export let onSearch: (search: string) => void;
|
@@ -65,7 +66,7 @@
|
|
65 |
<div class="p-8 overflow-auto">
|
66 |
<header class="flex w-full justify-between items-start mb-6 pr-6 gap-3">
|
67 |
<div class="flex items-center justify-start gap-3 lg:gap-6 w-full">
|
68 |
-
<
|
69 |
<div class="w-full truncate">
|
70 |
<p class="text-neutral-300 font-semibold text-lg lg:text-2xl mb-1 truncate w-full">
|
71 |
<button class="underline text-white" on:click={handleClickAuthor}>{author}</button>/{repo}
|
|
|
8 |
import { modelStore } from "$lib/stores/use-model";
|
9 |
import UserIsLogged from '$lib/components/UserIsLogged.svelte';
|
10 |
import Comments from '$lib/components/models/drawer/comments/Comments.svelte';
|
11 |
+
import Image from '../image/Image.svelte';
|
12 |
|
13 |
let { open, model } = get(modelStore);
|
14 |
export let onSearch: (search: string) => void;
|
|
|
66 |
<div class="p-8 overflow-auto">
|
67 |
<header class="flex w-full justify-between items-start mb-6 pr-6 gap-3">
|
68 |
<div class="flex items-center justify-start gap-3 lg:gap-6 w-full">
|
69 |
+
<Image src={model?.image} generatedImage={model?.gallery?.[0]?.image} className="lg:w-16 lg:h-16 w-12 h-12 rounded-xl bg-neutral-800 object-cover" alt={model?.id} />
|
70 |
<div class="w-full truncate">
|
71 |
<p class="text-neutral-300 font-semibold text-lg lg:text-2xl mb-1 truncate w-full">
|
72 |
<button class="underline text-white" on:click={handleClickAuthor}>{author}</button>/{repo}
|
src/lib/components/models/image/Image.svelte
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<script lang="ts">
|
2 |
+
import Icon from "@iconify/svelte";
|
3 |
+
|
4 |
+
export let src: string |Β undefined;
|
5 |
+
export let className: string;
|
6 |
+
export let generatedImage: stringΒ |Β undefined;
|
7 |
+
export let alt: string | undefined;
|
8 |
+
|
9 |
+
let loaded = 0;
|
10 |
+
</script>
|
11 |
+
|
12 |
+
<!-- svelte-ignore a11y-img-redundant-alt -->
|
13 |
+
{#if loaded === 2}
|
14 |
+
<div class="{className} flex items-center flex-col justify-center text-white/50 text-xs">
|
15 |
+
<Icon icon="mingcute:sad-fill" class="text-lg" />
|
16 |
+
Not found
|
17 |
+
</div>
|
18 |
+
{:else}
|
19 |
+
<img
|
20 |
+
src={
|
21 |
+
loaded === 0 ? src : `/api/images/${generatedImage}`
|
22 |
+
}
|
23 |
+
alt={alt}
|
24 |
+
class="{className}"
|
25 |
+
on:error={() => {
|
26 |
+
loaded += 1;
|
27 |
+
}}
|
28 |
+
/>
|
29 |
+
{/if}
|
src/routes/+layout.svelte
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
import { get } from "svelte/store";
|
3 |
import Icon from "@iconify/svelte";
|
4 |
import { SvelteToast } from '@zerodevx/svelte-toast'
|
|
|
5 |
|
6 |
import Sidebar from "$lib/components/sidebar/Sidebar.svelte";
|
7 |
import "$lib/styles/tailwind.css"
|
|
|
2 |
import { get } from "svelte/store";
|
3 |
import Icon from "@iconify/svelte";
|
4 |
import { SvelteToast } from '@zerodevx/svelte-toast'
|
5 |
+
// import spaceHeader from "@huggingface/space-header"
|
6 |
|
7 |
import Sidebar from "$lib/components/sidebar/Sidebar.svelte";
|
8 |
import "$lib/styles/tailwind.css"
|
src/routes/api/community/[id]/+server.ts
CHANGED
@@ -49,6 +49,18 @@ export async function GET({ params, url } : RequestEvent) {
|
|
49 |
select: {
|
50 |
image: true,
|
51 |
id: true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
}
|
53 |
},
|
54 |
reactions: {
|
|
|
49 |
select: {
|
50 |
image: true,
|
51 |
id: true,
|
52 |
+
gallery: {
|
53 |
+
select: {
|
54 |
+
image: true,
|
55 |
+
},
|
56 |
+
where: {
|
57 |
+
isPublic: true
|
58 |
+
},
|
59 |
+
orderBy: {
|
60 |
+
createdAt: 'desc'
|
61 |
+
},
|
62 |
+
take: 1
|
63 |
+
}
|
64 |
}
|
65 |
},
|
66 |
reactions: {
|
src/routes/api/models/+server.ts
CHANGED
@@ -58,6 +58,26 @@ export async function GET(request : RequestEvent) {
|
|
58 |
{ id: { contains: search } },
|
59 |
]
|
60 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
orderBy: orderBy,
|
62 |
skip: page * limit,
|
63 |
take: limit,
|
|
|
58 |
{ id: { contains: search } },
|
59 |
]
|
60 |
},
|
61 |
+
select: {
|
62 |
+
id: true,
|
63 |
+
likes: true,
|
64 |
+
downloads: true,
|
65 |
+
likes7d: true,
|
66 |
+
image: true,
|
67 |
+
gallery: {
|
68 |
+
select: {
|
69 |
+
id: true,
|
70 |
+
image: true,
|
71 |
+
},
|
72 |
+
where: {
|
73 |
+
isPublic: true
|
74 |
+
},
|
75 |
+
orderBy: {
|
76 |
+
createdAt: 'desc'
|
77 |
+
},
|
78 |
+
take: 1
|
79 |
+
},
|
80 |
+
},
|
81 |
orderBy: orderBy,
|
82 |
skip: page * limit,
|
83 |
take: limit,
|
src/routes/api/models/[id]/+server.ts
CHANGED
@@ -62,6 +62,18 @@ export async function GET({ url, params } : RequestEvent) {
|
|
62 |
image: true,
|
63 |
id: true,
|
64 |
metadata: true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
}
|
66 |
})
|
67 |
|
|
|
62 |
image: true,
|
63 |
id: true,
|
64 |
metadata: true,
|
65 |
+
gallery: {
|
66 |
+
select: {
|
67 |
+
image: true,
|
68 |
+
},
|
69 |
+
where: {
|
70 |
+
isPublic: true
|
71 |
+
},
|
72 |
+
orderBy: {
|
73 |
+
createdAt: 'desc'
|
74 |
+
},
|
75 |
+
take: 1
|
76 |
+
},
|
77 |
}
|
78 |
})
|
79 |
|
src/routes/api/scrap-models/+server.ts
CHANGED
@@ -49,12 +49,11 @@ export async function POST({ request }) {
|
|
49 |
const imageRegex = /!\[.*\]\((.*)\)/
|
50 |
let image = readme.match(imageRegex)?.[1]
|
51 |
|
52 |
-
if (
|
53 |
-
|
|
|
|
|
54 |
}
|
55 |
-
image = image.replace(///g, "/")
|
56 |
-
if (image.startsWith("http")) model.image = image
|
57 |
-
else model.image = `https://huggingface.co/${model.id}/resolve/main/${image.replace("./", "")}`
|
58 |
}
|
59 |
}
|
60 |
|
|
|
49 |
const imageRegex = /!\[.*\]\((.*)\)/
|
50 |
let image = readme.match(imageRegex)?.[1]
|
51 |
|
52 |
+
if (image) {
|
53 |
+
image = image.replace(///g, "/")
|
54 |
+
if (image.startsWith("http")) model.image = image
|
55 |
+
else model.image = `https://huggingface.co/${model.id}/resolve/main/${image.replace("./", "")}`
|
56 |
}
|
|
|
|
|
|
|
57 |
}
|
58 |
}
|
59 |
|