enzostvs HF staff commited on
Commit
2c23da5
β€’
1 Parent(s): c8cc366

add structuration page

Browse files
src/lib/components/community/Card.svelte CHANGED
@@ -19,17 +19,7 @@
19
  let loading = false;
20
 
21
  const handleClick = async () => {
22
- const request = await fetch(`/api/community/${card?.id}?${new URLSearchParams(form)}`);
23
- const { gallery, next, previous } = await request.json();
24
- galleryStore.set({
25
- gallery,
26
- open: true,
27
- next,
28
- previous
29
- });
30
-
31
- $page.url.searchParams.set('gallery', card?.id);
32
- goto(`?${$page.url.searchParams.toString()}`);
33
  };
34
 
35
  const handleDelete = async (id: string) => {
 
19
  let loading = false;
20
 
21
  const handleClick = async () => {
22
+ goto(`/gallery/${card?.id}`);
 
 
 
 
 
 
 
 
 
 
23
  };
24
 
25
  const handleDelete = async (id: string) => {
src/lib/components/community/drawer/Drawer.svelte CHANGED
@@ -28,8 +28,7 @@
28
  };
29
  });
30
 
31
- $page.url.searchParams.delete('model');
32
- await goto(`?${$page.url.searchParams.toString()}`);
33
  await invalidate(url => url.pathname.includes("/api/models"));
34
  };
35
 
@@ -47,9 +46,7 @@
47
  };
48
  const handleClickModel = (id?: string) => {
49
  if (!id) return;
50
- $page.url.searchParams.set('model', id);
51
- $page.url.searchParams.delete('gallery');
52
- goto(`/?${$page.url.searchParams.toString()}`);
53
  };
54
  </script>
55
 
 
28
  };
29
  });
30
 
31
+ await goto(`/gallery`);
 
32
  await invalidate(url => url.pathname.includes("/api/models"));
33
  };
34
 
 
46
  };
47
  const handleClickModel = (id?: string) => {
48
  if (!id) return;
49
+ goto(`/models/${id}`);
 
 
50
  };
51
  </script>
52
 
src/lib/components/models/Card.svelte CHANGED
@@ -8,12 +8,10 @@
8
  import { userStore } from "$lib/stores/use-user";
9
 
10
  export let card: ModelCard;
11
- export let onClick: (modelId: string) => void;
12
 
13
  const handleClick = async () => {
14
  $page.url.searchParams.set('model', card?.id);
15
- goto(`?${$page.url.searchParams.toString()}`);
16
- onClick(card?.id);
17
  };
18
 
19
  const publish = async () => {
 
8
  import { userStore } from "$lib/stores/use-user";
9
 
10
  export let card: ModelCard;
 
11
 
12
  const handleClick = async () => {
13
  $page.url.searchParams.set('model', card?.id);
14
+ goto(`/models/${card?.id}`);
 
15
  };
16
 
17
  const publish = async () => {
src/lib/components/models/drawer/Drawer.svelte CHANGED
@@ -28,8 +28,7 @@
28
  };
29
  });
30
 
31
- $page.url.searchParams.delete('model');
32
- await goto(`?${$page.url.searchParams.toString()}`);
33
  await invalidate(url => url.pathname.includes("/api/models"));
34
  };
35
 
 
28
  };
29
  });
30
 
31
+ await goto(`/models`);
 
32
  await invalidate(url => url.pathname.includes("/api/models"));
33
  };
34
 
src/routes/+page.server.ts ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ import { redirect } from '@sveltejs/kit';
2
+
3
+ /** @type {import('./$types').PageLoad} */
4
+ export async function load() {
5
+ throw redirect(302, "/models")
6
+ }
src/routes/gallery/+layout.svelte ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script lang="ts">
2
+ import { browser } from "$app/environment";
3
+ import InfiniteScroll from "svelte-infinite-scroll";
4
+
5
+ import Button from "$lib/components/Button.svelte";
6
+ import Card from "$lib/components/community/Card.svelte";
7
+ import Input from "$lib/components/fields/Input.svelte";
8
+ import Radio from "$lib/components/fields/Radio.svelte";
9
+ import { COMMUNITY_FILTER_OPTIONS } from "$lib/utils/index.js";
10
+ import GoTop from "$lib/components/GoTop.svelte";
11
+ import GalleryDrawer from "$lib/components/community/drawer/Drawer.svelte";
12
+ import { userStore } from "$lib/stores/use-user";
13
+ import { onMount } from "svelte";
14
+ import type { CommunityCard } from "$lib/type";
15
+
16
+ let data: {
17
+ cards: CommunityCard[],
18
+ total_items: number,
19
+ } = {
20
+ cards: [],
21
+ total_items: 0,
22
+ }
23
+
24
+ let form = {
25
+ filter: "new",
26
+ page: "0",
27
+ search: ""
28
+ }
29
+
30
+ onMount(() => {
31
+ refetch(false);
32
+ });
33
+
34
+ $: elementScroll = browser ? document?.getElementById('app') : undefined;
35
+
36
+ const handleFetchMore = async () => {
37
+ form = {...form, page: (Number(form.page) + 1).toString()};
38
+ refetch(true);
39
+ }
40
+ const handleChangeFilter = async (filter: string) => {
41
+ form = { ...form, filter, page: (0).toString()};
42
+ refetch(false)
43
+ }
44
+ let timeout: any;
45
+ const handleChangeSearch = async (search: string) => {
46
+ clearTimeout(timeout);
47
+ form = { ...form, search, page: (0).toString()};
48
+ timeout = setTimeout(() => refetch(false), 500);
49
+ }
50
+
51
+ const refetch = async (add: boolean) => {
52
+ const request = await fetch(`/api/community?${new URLSearchParams(form)}`);
53
+ const response = await request.json();
54
+ if (add) data = {...data, cards: [...data.cards, ...response.cards ]};
55
+ else data = response;
56
+ }
57
+ </script>
58
+
59
+ <svelte:head>
60
+ <title>Community Gallery</title>
61
+ <meta name="description" content="Svelte demo app" />
62
+ </svelte:head>
63
+
64
+ <main class="px-6 py-10 lg:px-10 lg:py-12">
65
+ <h1 class="text-white font-semibold text-2xl">
66
+ Community Gallery ({data.total_items})
67
+ </h1>
68
+ <div class="flex items-start sm:items-center justify-between mt-5 flex-col sm:flex-row gap-5 sm:justify-between">
69
+ <Radio options={COMMUNITY_FILTER_OPTIONS} value="{form.filter}" onChange={handleChangeFilter} />
70
+ <div class="items-center justify-end gap-5 hidden lg:flex">
71
+ <!-- <UserIsLogged> -->
72
+ <Button icon="ic:round-plus" disabled={true} theme="dark" size="lg">Upload own Image</Button>
73
+ <!-- </UserIsLogged> -->
74
+ <Button icon="fluent:glance-horizontal-sparkles-16-filled" href="/generate" theme="pink" size="lg">Generate</Button>
75
+ </div>
76
+ <div class="items-center justify-end gap-3 flex lg:hidden">
77
+ <!-- <UserIsLogged> -->
78
+ <Button icon="ic:round-plus" disabled={true} theme="dark" size="md">Upload own Image</Button>
79
+ <!-- </UserIsLogged> -->
80
+ <Button icon="fluent:glance-horizontal-sparkles-16-filled" href="/generate" theme="pink" size="md">Generate</Button>
81
+ </div>
82
+ </div>
83
+ <div class="mt-5 max-w-sm">
84
+ <Input value={form.search} placeholder="Search an image" onChange={handleChangeSearch} />
85
+ </div>
86
+ <!-- mx-auto grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-3 xl:grid-cols-4 3xl:grid-cols-5 gap-5 mt-8 lg:mt-10 -->
87
+ <div class="mx-auto flex flex-wrap gap-5 mt-8 lg:mt-10 justify-center md:justify-start">
88
+ {#each data.cards as card}
89
+ <Card card={card} form={form} displayDelete={$userStore?.is_admin} />
90
+ {/each}
91
+ <InfiniteScroll
92
+ elementScroll="{elementScroll ?? undefined}"
93
+ threshold={100}
94
+ hasMore={data.total_items > data.cards.length}
95
+ on:loadMore={handleFetchMore}
96
+ />
97
+ <GoTop />
98
+ </div>
99
+ <GalleryDrawer form={form} />
100
+ <slot />
101
+ </main>
src/routes/gallery/+page.svelte CHANGED
@@ -1,101 +1,3 @@
1
- <script lang="ts">
2
- import { browser } from "$app/environment";
3
- import InfiniteScroll from "svelte-infinite-scroll";
4
-
5
- import Button from "$lib/components/Button.svelte";
6
- import Card from "$lib/components/community/Card.svelte";
7
- import Input from "$lib/components/fields/Input.svelte";
8
- import Radio from "$lib/components/fields/Radio.svelte";
9
- import { COMMUNITY_FILTER_OPTIONS } from "$lib/utils/index.js";
10
- import GoTop from "$lib/components/GoTop.svelte";
11
- import GalleryDrawer from "$lib/components/community/drawer/Drawer.svelte";
12
- import { userStore } from "$lib/stores/use-user";
13
- import { onMount } from "svelte";
14
- import type { CommunityCard } from "$lib/type";
15
-
16
- let data: {
17
- cards: CommunityCard[],
18
- total_items: number,
19
- } = {
20
- cards: [],
21
- total_items: 0,
22
- }
23
-
24
- let form = {
25
- filter: "new",
26
- page: "0",
27
- search: ""
28
- }
29
-
30
- onMount(() => {
31
- refetch(false);
32
- });
33
-
34
- $: elementScroll = browser ? document?.getElementById('app') : undefined;
35
-
36
- const handleFetchMore = async () => {
37
- form = {...form, page: (Number(form.page) + 1).toString()};
38
- refetch(true);
39
- }
40
- const handleChangeFilter = async (filter: string) => {
41
- form = { ...form, filter, page: (0).toString()};
42
- refetch(false)
43
- }
44
- let timeout: any;
45
- const handleChangeSearch = async (search: string) => {
46
- clearTimeout(timeout);
47
- form = { ...form, search, page: (0).toString()};
48
- timeout = setTimeout(() => refetch(false), 500);
49
- }
50
-
51
- const refetch = async (add: boolean) => {
52
- const request = await fetch(`/api/community?${new URLSearchParams(form)}`);
53
- const response = await request.json();
54
- if (add) data = {...data, cards: [...data.cards, ...response.cards ]};
55
- else data = response;
56
- }
57
- </script>
58
-
59
- <svelte:head>
60
- <title>Community Gallery</title>
61
- <meta name="description" content="Svelte demo app" />
62
- </svelte:head>
63
-
64
- <main class="px-6 py-10 lg:px-10 lg:py-12">
65
- <h1 class="text-white font-semibold text-2xl">
66
- Community Gallery ({data.total_items})
67
- </h1>
68
- <div class="flex items-start sm:items-center justify-between mt-5 flex-col sm:flex-row gap-5 sm:justify-between">
69
- <Radio options={COMMUNITY_FILTER_OPTIONS} value="{form.filter}" onChange={handleChangeFilter} />
70
- <div class="items-center justify-end gap-5 hidden lg:flex">
71
- <!-- <UserIsLogged> -->
72
- <Button icon="ic:round-plus" disabled={true} theme="dark" size="lg">Upload own Image</Button>
73
- <!-- </UserIsLogged> -->
74
- <Button icon="fluent:glance-horizontal-sparkles-16-filled" href="/generate" theme="pink" size="lg">Generate</Button>
75
- </div>
76
- <div class="items-center justify-end gap-3 flex lg:hidden">
77
- <!-- <UserIsLogged> -->
78
- <Button icon="ic:round-plus" disabled={true} theme="dark" size="md">Upload own Image</Button>
79
- <!-- </UserIsLogged> -->
80
- <Button icon="fluent:glance-horizontal-sparkles-16-filled" href="/generate" theme="pink" size="md">Generate</Button>
81
- </div>
82
- </div>
83
- <div class="mt-5 max-w-sm">
84
- <Input value={form.search} placeholder="Search an image" onChange={handleChangeSearch} />
85
- </div>
86
- <!-- mx-auto grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-3 xl:grid-cols-4 3xl:grid-cols-5 gap-5 mt-8 lg:mt-10 -->
87
- <div class="mx-auto flex flex-wrap gap-5 mt-8 lg:mt-10 justify-center md:justify-start">
88
- {#each data.cards as card}
89
- <Card card={card} form={form} displayDelete={$userStore?.is_admin} />
90
- {/each}
91
- <InfiniteScroll
92
- elementScroll="{elementScroll ?? undefined}"
93
- threshold={100}
94
- hasMore={data.total_items > data.cards.length}
95
- on:loadMore={handleFetchMore}
96
- />
97
- <GoTop />
98
- </div>
99
- <!-- <GalleryViewer form={form} /> -->
100
- <GalleryDrawer form={form} />
101
- </main>
 
1
+ <div>
2
+ <slot />
3
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/routes/gallery/[id]/+page.svelte ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script lang="ts">
2
+ import { galleryStore } from "$lib/stores/use-gallery.js";
3
+ import { onMount } from "svelte";
4
+ export let data;
5
+
6
+
7
+ onMount(() => {
8
+ console.log(data)
9
+ galleryStore.set({
10
+ gallery: data.gallery,
11
+ open: true,
12
+ next: data.next,
13
+ previous: data.previous
14
+ });
15
+ });
16
+ </script>
src/routes/gallery/[id]/+page.ts ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { error } from '@sveltejs/kit';
2
+
3
+ /** @type {import('./$types').PageLoad} */
4
+ export async function load({ params, fetch }) {
5
+ const { id } = params;
6
+
7
+ // const request = await fetch(`/api/community/${card?.id}?${new URLSearchParams(form)}`);
8
+ // const { gallery, next, previous } = await request.json();
9
+
10
+ const model_request = await fetch(`/api/community/${id}`, {
11
+ method: "GET",
12
+ headers: {
13
+ "Content-Type": "application/json"
14
+ }
15
+ })
16
+ const data = await model_request?.clone().json().catch(() => null);
17
+
18
+ const { gallery, next, previous } = data;
19
+
20
+ if (!gallery) {
21
+ return error(404, 'Not found');
22
+ }
23
+
24
+ return {
25
+ gallery,
26
+ next,
27
+ previous
28
+ }
29
+ }
src/routes/{+page.svelte β†’ models/+layout.svelte} RENAMED
@@ -2,7 +2,6 @@
2
  import { browser } from "$app/environment";
3
  import InfiniteScroll from "svelte-infinite-scroll";
4
  import { page } from "$app/stores";
5
- import { modelStore } from "$lib/stores/use-model";
6
 
7
  import { goto } from "$app/navigation";
8
  import Button from "$lib/components/Button.svelte";
@@ -37,7 +36,7 @@
37
  onMount(() => {
38
  refetch(false);
39
  if ($page.url.searchParams.get('model')) {
40
- getModel($page.url.searchParams.get('model') as string);
41
  }
42
  });
43
 
@@ -76,31 +75,14 @@
76
  data.total_items = response.total_items;
77
  }
78
  }
79
-
80
- const getModel = async (modelId: string) => {
81
- const model_request = await fetch(`/api/models/${modelId?.replace("/", "@")}?full=true`, {
82
- method: "GET",
83
- headers: {
84
- "Content-Type": "application/json"
85
- }
86
- })
87
- const data = await model_request?.clone().json().catch(() => null);
88
- modelStore.set({
89
- model: data?.model ?? null,
90
- open: true
91
- });
92
- }
93
  </script>
94
 
95
  <svelte:head>
96
  <title>Explore Models</title>
97
- <meta name="description" content="Svelte demo app" />
98
  </svelte:head>
99
 
100
  <main class="px-6 py-10 lg:px-10 lg:py-12">
101
- <Dialog open={submitModelDialog} onClose={() => submitModelDialog = false}>
102
- <SubmitModel onClose={() => submitModelDialog = false} />
103
- </Dialog>
104
  <Drawer onSearch={handleChangeSearch} />
105
  <h1 class="text-white font-semibold text-2xl">
106
  Explore Models ({data?.total_items ?? 0})
@@ -135,17 +117,15 @@
135
  </div>
136
  <div class="items-center justify-end gap-3 flex lg:hidden">
137
  <Button href="https://huggingface.co/new/stable-diffusion-lora" target="_blank" icon="ic:round-plus" theme="dark" size="md">Create</Button>
138
- <!-- <UserIsLogged> -->
139
- <Button
140
  icon="octicon:upload-16"
141
  theme="blue"
 
 
142
  size="md"
143
- disabled={true}
144
- onClick={() => submitModelDialog = true}
145
  >
146
- Upload model
147
  </Button>
148
- <!-- </UserIsLogged> -->
149
  </div>
150
  </div>
151
  <div class="mt-5 max-w-sm">
@@ -153,7 +133,7 @@
153
  </div>
154
  <div class="mx-auto grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 2xl:grid-cols-4 gap-5 mt-8 lg:mt-10">
155
  {#each data.models as card}
156
- <Card card={card} onClick={getModel} />
157
  {/each}
158
  {#if data.models.length === 0}
159
  <p class="text-neutral-400 text-left w-full">No models found</p>
@@ -166,4 +146,5 @@
166
  />
167
  <GoTop />
168
  </div>
 
169
  </main>
 
2
  import { browser } from "$app/environment";
3
  import InfiniteScroll from "svelte-infinite-scroll";
4
  import { page } from "$app/stores";
 
5
 
6
  import { goto } from "$app/navigation";
7
  import Button from "$lib/components/Button.svelte";
 
36
  onMount(() => {
37
  refetch(false);
38
  if ($page.url.searchParams.get('model')) {
39
+ // getModel($page.url.searchParams.get('model') as string);
40
  }
41
  });
42
 
 
75
  data.total_items = response.total_items;
76
  }
77
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  </script>
79
 
80
  <svelte:head>
81
  <title>Explore Models</title>
82
+ <meta name="description" content="Explore the LoRa models to find the perfect one!" />
83
  </svelte:head>
84
 
85
  <main class="px-6 py-10 lg:px-10 lg:py-12">
 
 
 
86
  <Drawer onSearch={handleChangeSearch} />
87
  <h1 class="text-white font-semibold text-2xl">
88
  Explore Models ({data?.total_items ?? 0})
 
117
  </div>
118
  <div class="items-center justify-end gap-3 flex lg:hidden">
119
  <Button href="https://huggingface.co/new/stable-diffusion-lora" target="_blank" icon="ic:round-plus" theme="dark" size="md">Create</Button>
120
+ <Button
 
121
  icon="octicon:upload-16"
122
  theme="blue"
123
+ target="_blank"
124
+ href="https://huggingface.co/spaces/multimodalart/civitai-to-hf"
125
  size="md"
 
 
126
  >
127
+ Migrate
128
  </Button>
 
129
  </div>
130
  </div>
131
  <div class="mt-5 max-w-sm">
 
133
  </div>
134
  <div class="mx-auto grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 2xl:grid-cols-4 gap-5 mt-8 lg:mt-10">
135
  {#each data.models as card}
136
+ <Card card={card} />
137
  {/each}
138
  {#if data.models.length === 0}
139
  <p class="text-neutral-400 text-left w-full">No models found</p>
 
146
  />
147
  <GoTop />
148
  </div>
149
+ <slot />
150
  </main>
src/routes/models/+page.svelte ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ <div>
2
+ <slot />
3
+ </div>
src/routes/models/[userId]/+page.svelte ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ <div>
2
+ <slot />
3
+ </div>
src/routes/models/[userId]/[slug]/+page.svelte ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script lang="ts">
2
+ import { modelStore } from "$lib/stores/use-model";
3
+ import { onMount } from "svelte";
4
+ export let data;
5
+
6
+
7
+ onMount(() => {
8
+ modelStore.set({
9
+ model: data ? data.model : null,
10
+ open: true
11
+ });
12
+ });
13
+ </script>
src/routes/models/[userId]/[slug]/+page.ts ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { error } from '@sveltejs/kit';
2
+
3
+ /** @type {import('./$types').PageLoad} */
4
+ export async function load({ params, fetch }) {
5
+ const { userId, slug } = params;
6
+
7
+ const model_request = await fetch(`/api/models/${userId + "@" + slug}?full=true`, {
8
+ method: "GET",
9
+ headers: {
10
+ "Content-Type": "application/json"
11
+ }
12
+ })
13
+ const data = await model_request?.clone().json().catch(() => null);
14
+
15
+ if (!data?.model) {
16
+ return error(404, 'Not found');
17
+ }
18
+
19
+ return data
20
+ }