enzostvs HF staff commited on
Commit
1c0590e
β€’
1 Parent(s): b1a4d81

fix dockerfile

Browse files
Dockerfile CHANGED
@@ -17,10 +17,10 @@ RUN npm install
17
  COPY --chown=1000 . .
18
 
19
  # Build the Svelte Kit application for production
20
- RUN npm run build
21
 
22
  # Expose the application port (assuming your app runs on port 3000)
23
  EXPOSE 3000
24
 
25
- # Run the application in production mode
26
- CMD ["node", "build"]
 
17
  COPY --chown=1000 . .
18
 
19
  # Build the Svelte Kit application for production
20
+ # RUN npm run build
21
 
22
  # Expose the application port (assuming your app runs on port 3000)
23
  EXPOSE 3000
24
 
25
+ # Start the application
26
+ ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
entrypoint.sh ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ #!/bin/bash
2
+ npm run build && npx prisma generate && npx prisma migrate deploy && npx prisma db push && npm start
package-lock.json CHANGED
@@ -10,6 +10,7 @@
10
  "dependencies": {
11
  "@iconify/svelte": "^3.1.4",
12
  "@prisma/client": "^5.7.1",
 
13
  "@sveltejs/adapter-node": "^1.3.1",
14
  "cookie": "^0.6.0",
15
  "js-cookie": "^3.0.5",
@@ -1281,6 +1282,11 @@
1281
  "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
1282
  "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
1283
  },
 
 
 
 
 
1284
  "node_modules/@sveltejs/adapter-auto": {
1285
  "version": "2.1.1",
1286
  "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-2.1.1.tgz",
 
10
  "dependencies": {
11
  "@iconify/svelte": "^3.1.4",
12
  "@prisma/client": "^5.7.1",
13
+ "@svelte-put/clickoutside": "^3.0.1",
14
  "@sveltejs/adapter-node": "^1.3.1",
15
  "cookie": "^0.6.0",
16
  "js-cookie": "^3.0.5",
 
1282
  "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
1283
  "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
1284
  },
1285
+ "node_modules/@svelte-put/clickoutside": {
1286
+ "version": "3.0.1",
1287
+ "resolved": "https://registry.npmjs.org/@svelte-put/clickoutside/-/clickoutside-3.0.1.tgz",
1288
+ "integrity": "sha512-RhuRmD2RpXF63Mb48DxKkgqIPQ458TnL8M1m6HqtnPh5/g5p+PKIn/L2SPs1s9us2Kn02Y1/txHhOSYbVi6Z2Q=="
1289
+ },
1290
  "node_modules/@sveltejs/adapter-auto": {
1291
  "version": "2.1.1",
1292
  "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-2.1.1.tgz",
package.json CHANGED
@@ -40,6 +40,7 @@
40
  "dependencies": {
41
  "@iconify/svelte": "^3.1.4",
42
  "@prisma/client": "^5.7.1",
 
43
  "@sveltejs/adapter-node": "^1.3.1",
44
  "cookie": "^0.6.0",
45
  "js-cookie": "^3.0.5",
 
40
  "dependencies": {
41
  "@iconify/svelte": "^3.1.4",
42
  "@prisma/client": "^5.7.1",
43
+ "@svelte-put/clickoutside": "^3.0.1",
44
  "@sveltejs/adapter-node": "^1.3.1",
45
  "cookie": "^0.6.0",
46
  "js-cookie": "^3.0.5",
src/lib/components/models/Card.svelte CHANGED
@@ -2,21 +2,16 @@
2
  import type { ModelCard } from "$lib/type";
3
  import Button from "$lib/components/Button.svelte";
4
  import Icon from "@iconify/svelte";
5
- import Loading from "../Loading.svelte";
6
 
7
  export let card: ModelCard;
8
-
9
  </script>
10
  <div
11
  class="w-full cursor-pointer group bg-neutral-900 rounded-xl relative flex items-start justify-between flex-col p-3 border border-neutral-800 transition-all duration-200 brightness-75 hover:brightness-100 z-[1]"
12
  >
13
  <div class="w-full h-[270px] relative z-[1] mb-3 overflow-hidden">
14
- <!-- <div class="w-full h-full bg-center bg-cover rounded-lg bg-neutral-800 relative" style=""> -->
15
- <!-- <Loading /> -->
16
- <!-- </div> -->
17
  <img src="{card.image}" class="w-full h-full bg-center bg-cover rounded-lg object-cover object-center bg-neutral-800" alt="{card?.title}" />
18
  <div class="group-hover:opacity-100 opacity-0 translate-x-full group-hover:translate-x-0 transition-all duration-200 absolute right-3 bottom-3">
19
- <Button theme="light" size="md">
20
  Try it now
21
  </Button>
22
  </div>
 
2
  import type { ModelCard } from "$lib/type";
3
  import Button from "$lib/components/Button.svelte";
4
  import Icon from "@iconify/svelte";
 
5
 
6
  export let card: ModelCard;
 
7
  </script>
8
  <div
9
  class="w-full cursor-pointer group bg-neutral-900 rounded-xl relative flex items-start justify-between flex-col p-3 border border-neutral-800 transition-all duration-200 brightness-75 hover:brightness-100 z-[1]"
10
  >
11
  <div class="w-full h-[270px] relative z-[1] mb-3 overflow-hidden">
 
 
 
12
  <img src="{card.image}" class="w-full h-full bg-center bg-cover rounded-lg object-cover object-center bg-neutral-800" alt="{card?.title}" />
13
  <div class="group-hover:opacity-100 opacity-0 translate-x-full group-hover:translate-x-0 transition-all duration-200 absolute right-3 bottom-3">
14
+ <Button theme="light" size="md" href={`/generate?model=${card.repo}`}>
15
  Try it now
16
  </Button>
17
  </div>
src/lib/components/models/Submit.svelte CHANGED
@@ -1,4 +1,4 @@
1
- <script>
2
  import { get } from 'svelte/store';
3
  import { userStore } from "$lib/stores/use-user";
4
 
@@ -6,10 +6,11 @@
6
  import Button from "$lib/components/Button.svelte";
7
 
8
  let user = get(userStore);
 
9
  let model = {
10
- repo: 'enzostvs/hair-colorrr',
11
- title: 'testt',
12
- image: 'dewdwedd',
13
  }
14
  let error = {
15
  repo: '',
@@ -70,7 +71,7 @@
70
  </p>
71
  <Input
72
  value={model.repo}
73
- placeholder="enzostvs/hair-color"
74
  prefix="huggingface.co/"
75
  onChange={(value) => model.repo = value}
76
  />
@@ -109,7 +110,7 @@
109
  </div>
110
  </main>
111
  <footer class="flex items-center justify-end gap-3">
112
- <Button theme="dark" size="md">Cancel</Button>
113
  <Button theme="blue" size="md" onClick={handleSubmit}>Submit</Button>
114
  </footer>
115
  </div>
 
1
+ <script lang="ts">
2
  import { get } from 'svelte/store';
3
  import { userStore } from "$lib/stores/use-user";
4
 
 
6
  import Button from "$lib/components/Button.svelte";
7
 
8
  let user = get(userStore);
9
+ export let onClose: () => void;
10
  let model = {
11
+ repo: '',
12
+ title: '',
13
+ image: '',
14
  }
15
  let error = {
16
  repo: '',
 
71
  </p>
72
  <Input
73
  value={model.repo}
74
+ placeholder="{`${user.preferred_username}/`}"
75
  prefix="huggingface.co/"
76
  onChange={(value) => model.repo = value}
77
  />
 
110
  </div>
111
  </main>
112
  <footer class="flex items-center justify-end gap-3">
113
+ <Button theme="dark" size="md" onClick={onClose}>Cancel</Button>
114
  <Button theme="blue" size="md" onClick={handleSubmit}>Submit</Button>
115
  </footer>
116
  </div>
src/lib/components/models/autocomplete/Autocomplete.svelte ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script lang="ts">
2
+ import { clickoutside } from '@svelte-put/clickoutside';
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;
9
+ export let value: ModelCard | null = null;
10
+
11
+ console.log(value)
12
+
13
+ let models: ModelCard[] = [];
14
+ let search: string = "";
15
+ let open: boolean = false;
16
+
17
+ const handleSearch = (event: any) => {
18
+ search = event.target.value;
19
+ if (search.length >= 3) {
20
+ open = true;
21
+ onSearch();
22
+ } else {
23
+ models = []
24
+ }
25
+ }
26
+
27
+ const onSearch = async () => {
28
+ const request = await fetch(`/api/models?search=${search}`);
29
+ const response = await request.json();
30
+
31
+ if (response?.cards && response?.cards.length > 0) {
32
+ models = response.cards;
33
+ } else {
34
+ models = [];
35
+ }
36
+ }
37
+
38
+ const handleClickOutside = (event: any) => {
39
+ if (event.target === event.currentTarget) {
40
+ open = false;
41
+ }
42
+ }
43
+
44
+ </script>
45
+
46
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
47
+ <!-- svelte-ignore a11y-no-static-element-interactions -->
48
+ <div
49
+ class="w-full bg-neutral-900 rounded-xl border border-neutral-800 p-4 text-neutral-500 focus-within:border-neutral-700 transition-all duration-200 relative"
50
+ use:clickoutside on:clickoutside={() => open = false}
51
+ on:click={handleClickOutside}
52
+ >
53
+ {#if value}
54
+ <div class="flex items-center justify-between gap-4">
55
+ <div class="flex items-center justify-start gap-3">
56
+ <img src={value.image} alt={value.title} class="w-6 h-6 rounded-lg object-cover" />
57
+ <p class="text-neutral-200 text-base font-medium">{value.title}</p>
58
+ </div>
59
+ <button on:click={() => onChange(null)}>
60
+ <Icon icon="maki:cross" class="w-4 h-4 text-neutral-500 transition-all duration-200 cursor-pointer" />
61
+ </button>
62
+ </div>
63
+ {:else}
64
+ <div class="flex items-center justify-start gap-2 group">
65
+ <Icon icon="lucide:search" class="w-5 h-5 text-neutral-500 group-focus-within:text-neutral-100 transition-all duration-200" />
66
+ <input
67
+ value={search}
68
+ type="text"
69
+ class="w-full bg-transparent text-neutral-200 placeholder:text-neutral-500 outline-none"
70
+ placeholder="Search a model"
71
+ on:focus={() => open = true}
72
+ on:input={handleSearch}
73
+ />
74
+ </div>
75
+ {/if}
76
+ <div
77
+ class="w-full absolute bottom-0 left-0 p-2 bg-neutral-900 rounded-xl translate-y-[calc(100%+12px)] border border-neutral-800 transition-all duration-200 z-10"
78
+ class:opacity-0="{!open}"
79
+ class:pointer-events-none="{!open}"
80
+ >
81
+ {#if search?.length >= 3}
82
+ {#if models?.length > 0}
83
+ {#each models as model}
84
+ <Item model={model} onClick={() => onChange(model)} />
85
+ {/each}
86
+ {:else}
87
+ <div class="flex items-center justify-center flex-col gap-2 p-3">
88
+ <Icon icon="bxs:sad" class="w-12 h-12 text-neutral-500 transition-all duration-200" />
89
+ <p class="text-neutral-500 text-base">No models found</p>
90
+ </div>
91
+ {/if}
92
+ {:else}
93
+ {#each defaultModels as model}
94
+ <Item model={model} onClick={() => onChange(model)} />
95
+ {/each}
96
+ {/if}
97
+ </div>
98
+ </div>
src/lib/components/models/autocomplete/Item.svelte ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script lang="ts">
2
+ import type { ModelCard } from "$lib/type";
3
+
4
+ export let model: ModelCard;
5
+ export let onClick: () => void;
6
+
7
+ </script>
8
+
9
+ <button
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
+ <img src={model.image} alt={model.title} class="w-14 h-14 rounded-lg object-cover" />
14
+ <div>
15
+ <p class="text-neutral-200 text-base font-medium">{model.title}</p>
16
+ <p class="text-neutral-400 text-sm">{model.repo}</p>
17
+ </div>
18
+ </button>
src/lib/components/sidebar/Sidebar.svelte CHANGED
@@ -26,7 +26,7 @@
26
  </script>
27
 
28
  <button class="bg-transparent absolute top-10 right-8 cursor-pointer xl:hidden" on:click="{handleClick}">
29
- <Icon icon="{isOpen ? "mdi:hamburger-remove" : "mdi:hamburger-minus"}" class="w-7 h-7 text-white" />
30
  </button>
31
  <aside class="bg-neutral-950 h-screen border-r border-neutral-800 w-full max-w-[344px] absolute -translate-x-full xl:translate-x-0 transition-all duration-200 xl:relative z-20 xl:z-0 flex flex-col justify-between" class:translate-x-0={isOpen}>
32
  <div class="w-full">
 
26
  </script>
27
 
28
  <button class="bg-transparent absolute top-10 right-8 cursor-pointer xl:hidden" on:click="{handleClick}">
29
+ <Icon icon="{isOpen ? "mdi:hamburger-remove" : "mdi:hamburger-plus"}" class="w-7 h-7 text-white" />
30
  </button>
31
  <aside class="bg-neutral-950 h-screen border-r border-neutral-800 w-full max-w-[344px] absolute -translate-x-full xl:translate-x-0 transition-all duration-200 xl:relative z-20 xl:z-0 flex flex-col justify-between" class:translate-x-0={isOpen}>
32
  <div class="w-full">
src/routes/api/models/+server.ts CHANGED
@@ -11,6 +11,7 @@ export async function GET(request : RequestEvent) {
11
  const page = parseInt(request.url.searchParams.get('page') || '0')
12
  const filter = request.url.searchParams.get('filter') || 'hotest'
13
  const search = request.url.searchParams.get('search') || ''
 
14
 
15
  const cards = await prisma.model.findMany({
16
  where: {
@@ -23,8 +24,8 @@ export async function GET(request : RequestEvent) {
23
  orderBy: {
24
  ...(filter === 'hotest' ? { downloads: 'desc' } : { likes: 'desc' })
25
  },
26
- skip: 20 * page,
27
- take: 20,
28
  })
29
 
30
  const total_reposId = await prisma.model.count({
 
11
  const page = parseInt(request.url.searchParams.get('page') || '0')
12
  const filter = request.url.searchParams.get('filter') || 'hotest'
13
  const search = request.url.searchParams.get('search') || ''
14
+ const limit = parseInt(request.url.searchParams.get('limit') || '20')
15
 
16
  const cards = await prisma.model.findMany({
17
  where: {
 
24
  orderBy: {
25
  ...(filter === 'hotest' ? { downloads: 'desc' } : { likes: 'desc' })
26
  },
27
+ skip: limit * page,
28
+ take: limit,
29
  })
30
 
31
  const total_reposId = await prisma.model.count({
src/routes/api/models/[repo]/+server.ts ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { json, type RequestEvent } from '@sveltejs/kit';
2
+ import prisma from '$lib/prisma';
3
+
4
+ /** @type {import('./$types').RequestHandler} */
5
+
6
+ export async function GET(request : RequestEvent) {
7
+ const repo = request.params.repo?.replace("@", "/")
8
+
9
+ const model = await prisma.model.findFirst({
10
+ where: {
11
+ repo
12
+ }
13
+ })
14
+
15
+ if (!model) {
16
+ return json({
17
+ error: {
18
+ token: "Model params is required"
19
+ }
20
+ }, { status: 401 })
21
+ }
22
+
23
+ return json({
24
+ model
25
+ })
26
+ }
src/routes/generate/+page.svelte CHANGED
@@ -3,6 +3,36 @@
3
  <meta name="description" content="Svelte demo app" />
4
  </svelte:head>
5
 
6
- <h1 class="text-white font-semibold text-2xl">
7
- Generate your Image
8
- </h1>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  <meta name="description" content="Svelte demo app" />
4
  </svelte:head>
5
 
6
+ <script lang="ts">
7
+ import Autocomplete from "$lib/components/models/autocomplete/Autocomplete.svelte";
8
+
9
+ export let data
10
+
11
+ let form = {
12
+ model: data?.model ?? null,
13
+ prompt: ""
14
+ }
15
+ </script>
16
+
17
+ <div class="flex items-start w-full h-full gap-16">
18
+ <div class="w-full">
19
+ <h1 class="text-white font-semibold text-2xl">
20
+ Start generating
21
+ </h1>
22
+ <div class="mt-5 grid grid-cols-1 gap-5">
23
+ <div>
24
+ <p class="text-neutral-300 mb-2.5 text-base">Models</p>
25
+ <Autocomplete
26
+ value={form?.model}
27
+ defaultModels={data?.models?.cards}
28
+ onChange={(model) => form.model = model}
29
+ />
30
+ </div>
31
+ </div>
32
+ </div>
33
+ <div class="w-full bg-neutral-100 rounded-2xl h-full p-8">
34
+ <p class="text-neutral-900 font-semibold text-xl">
35
+ Result of your generation
36
+ </p>
37
+ </div>
38
+ </div>
src/routes/generate/+page.ts ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export async function load({ url, fetch }) {
2
+ let model_parameter = url.searchParams.get("model")
3
+
4
+ let model = null;
5
+
6
+ if (model_parameter) {
7
+ model_parameter = model_parameter?.replace("/", "@")
8
+
9
+ const model_request = await fetch(`/api/models/${model_parameter}`, {
10
+ method: "GET",
11
+ headers: {
12
+ "Content-Type": "application/json"
13
+ }
14
+ })
15
+
16
+ model = await model_request.json()
17
+ }
18
+
19
+
20
+ const models_request = await fetch("/api/models?page=0&filter=likes&limit=5", {
21
+ method: "GET",
22
+ headers: {
23
+ "Content-Type": "application/json"
24
+ }
25
+ })
26
+ const models = await models_request.json()
27
+
28
+ return {
29
+ model: model?.model,
30
+ models
31
+ }
32
+ }
src/routes/models/+page.svelte CHANGED
@@ -50,7 +50,7 @@
50
  </svelte:head>
51
 
52
  <Dialog open={submitModelDialog} onClose={() => submitModelDialog = false}>
53
- <SubmitModel />
54
  </Dialog>
55
  <h1 class="text-white font-semibold text-2xl">
56
  Explore Models ({data.total_items})
 
50
  </svelte:head>
51
 
52
  <Dialog open={submitModelDialog} onClose={() => submitModelDialog = false}>
53
+ <SubmitModel onClose={() => submitModelDialog = false} />
54
  </Dialog>
55
  <h1 class="text-white font-semibold text-2xl">
56
  Explore Models ({data.total_items})