Thomas G. Lopes commited on
Commit
a5619c2
·
1 Parent(s): 2087f3e

add quota modal

Browse files
src/lib/actions/autofocus.ts CHANGED
@@ -1,3 +1,7 @@
 
 
1
  export function autofocus(node: HTMLElement) {
2
- node.focus();
 
 
3
  }
 
1
+ import { tick } from "svelte";
2
+
3
  export function autofocus(node: HTMLElement) {
4
+ tick().then(() => {
5
+ node.focus();
6
+ });
7
  }
src/lib/components/debug-menu.svelte CHANGED
@@ -7,6 +7,7 @@
7
  import { compareStr } from "$lib/utils/compare.js";
8
  import type { ToastData } from "./toaster.svelte.js";
9
  import { addToast } from "./toaster.svelte.js";
 
10
 
11
  let innerWidth = $state<number>();
12
  let innerHeight = $state<number>();
@@ -38,6 +39,12 @@
38
  console.log(await prompt("Test prompt"));
39
  },
40
  },
 
 
 
 
 
 
41
  {
42
  label: "Show token modal",
43
  cb: () => {
 
7
  import { compareStr } from "$lib/utils/compare.js";
8
  import type { ToastData } from "./toaster.svelte.js";
9
  import { addToast } from "./toaster.svelte.js";
10
+ import { showQuotaModal } from "./quota-modal.svelte";
11
 
12
  let innerWidth = $state<number>();
13
  let innerHeight = $state<number>();
 
39
  console.log(await prompt("Test prompt"));
40
  },
41
  },
42
+ {
43
+ label: "Show quota modal",
44
+ cb: () => {
45
+ showQuotaModal();
46
+ },
47
+ },
48
  {
49
  label: "Show token modal",
50
  cb: () => {
src/lib/components/inference-playground/conversation.svelte CHANGED
@@ -1,5 +1,3 @@
1
- <!-- @migration-task Error while migrating Svelte code: Can only bind to an Identifier or MemberExpression or a `{get, set}` pair
2
- https://svelte.dev/e/bind_invalid_expression -->
3
  <script lang="ts">
4
  import { run } from "svelte/legacy";
5
 
 
 
 
1
  <script lang="ts">
2
  import { run } from "svelte/legacy";
3
 
src/lib/components/prompts.svelte CHANGED
@@ -1,8 +1,7 @@
1
  <script lang="ts" module>
 
2
  import { clickOutside } from "$lib/actions/click-outside.js";
3
- import { writable } from "svelte/store";
4
  import IconCross from "~icons/carbon/close";
5
- import { autofocus } from "$lib/actions/autofocus.js";
6
 
7
  type Prompt = {
8
  label: string;
@@ -11,30 +10,26 @@
11
  callback: (value: string) => void;
12
  };
13
 
14
- const prompts = writable<Prompt[]>([]);
 
15
 
16
  export function resolvePrompt() {
17
- prompts.update(p => {
18
- p[0]?.callback(p[0]?.value ?? "");
19
- return p.slice(1);
20
- });
21
  }
22
 
23
- export async function prompt(label: string, defaultVAlue?: string): Promise<string> {
24
  return new Promise(res => {
25
- prompts.update(p => [...p, { label, value: defaultVAlue, callback: res }]);
26
  });
27
  }
28
  </script>
29
 
30
  <script lang="ts">
31
- import { run } from "svelte/legacy";
32
-
33
- let current = $derived($prompts?.[0]);
34
-
35
  let dialog: HTMLDialogElement | undefined = $state();
36
 
37
- run(() => {
38
  if (current) {
39
  dialog?.showModal();
40
  } else {
 
1
  <script lang="ts" module>
2
+ import { autofocus } from "$lib/actions/autofocus.js";
3
  import { clickOutside } from "$lib/actions/click-outside.js";
 
4
  import IconCross from "~icons/carbon/close";
 
5
 
6
  type Prompt = {
7
  label: string;
 
10
  callback: (value: string) => void;
11
  };
12
 
13
+ let prompts = $state<Prompt[]>([]);
14
+ const current = $derived(prompts[0]);
15
 
16
  export function resolvePrompt() {
17
+ if (!current) return;
18
+ current.callback(current.value ?? "");
19
+ prompts.splice(0, 1);
 
20
  }
21
 
22
+ export async function prompt(label: string, defaultValue?: string): Promise<string> {
23
  return new Promise(res => {
24
+ prompts.push({ label, value: defaultValue, callback: res });
25
  });
26
  }
27
  </script>
28
 
29
  <script lang="ts">
 
 
 
 
30
  let dialog: HTMLDialogElement | undefined = $state();
31
 
32
+ $effect(() => {
33
  if (current) {
34
  dialog?.showModal();
35
  } else {
src/lib/components/quota-modal.svelte ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script lang="ts" module>
2
+ let open = $state(true);
3
+
4
+ export function showQuotaModal() {
5
+ open = true;
6
+ }
7
+ </script>
8
+
9
+ <script lang="ts">
10
+ import { clickOutside } from "$lib/actions/click-outside.js";
11
+ import IconCross from "~icons/carbon/close";
12
+ import IconCheck from "~icons/carbon/checkmark";
13
+ import IconExternal from "~icons/carbon/arrow-up-right";
14
+ let dialog: HTMLDialogElement | undefined = $state();
15
+
16
+ $effect(() => {
17
+ if (open) {
18
+ dialog?.showModal();
19
+ } else {
20
+ dialog?.close();
21
+ }
22
+ });
23
+ </script>
24
+
25
+ {#snippet pro()}
26
+ <span
27
+ class="inline-block -skew-x-12 rounded-md border border-gray-200 bg-linear-to-br from-pink-300 via-green-200 to-yellow-200 px-1.5 py-0 text-sm font-bold text-black shadow-lg shadow-green-500/10 dark:border-gray-800 dark:from-pink-500 dark:via-green-500 dark:to-yellow-500 dark:text-black dark:shadow-green-500/20"
28
+ >
29
+ PRO
30
+ </span>
31
+ {/snippet}
32
+
33
+ <dialog bind:this={dialog} onclose={() => (open = false)}>
34
+ {#if open}
35
+ <div class="fixed inset-0 z-50 flex items-center justify-center overflow-hidden bg-black/85">
36
+ <div
37
+ class="relative w-3xl rounded-lg bg-white shadow-sm dark:bg-gray-900"
38
+ use:clickOutside={() => (open = false)}
39
+ >
40
+ <div class="flex items-center justify-between rounded-t border-b p-4 md:px-5 md:py-4 dark:border-gray-800">
41
+ <h3 class="flex items-center gap-2.5 text-lg font-semibold text-gray-900 dark:text-white">
42
+ <img
43
+ alt="Hugging Face's logo"
44
+ class="w-7"
45
+ src="https://huggingface.co/front/assets/huggingface_logo-noborder.svg"
46
+ /> Increase your usage limits
47
+ </h3>
48
+ <button
49
+ type="button"
50
+ class="ms-auto inline-flex h-8 w-8 items-center justify-center rounded-lg bg-transparent text-sm text-gray-400 hover:bg-gray-200 hover:text-gray-900 dark:hover:bg-gray-600 dark:hover:text-white"
51
+ onclick={() => (open = false)}
52
+ >
53
+ <div class="text-xl">
54
+ <IconCross />
55
+ </div>
56
+ <span class="sr-only">Close modal</span>
57
+ </button>
58
+ </div>
59
+ <!-- Modal body -->
60
+ <div class="flex flex-col gap-2 p-4 text-white md:p-5">
61
+ <p>
62
+ It seems you have reached your usage limits. If you want to continue using the playground, please consider
63
+ creating a {@render pro()} account!
64
+ </p>
65
+ <p>You'll also gain access to:</p>
66
+ <ul
67
+ class="grid grid-cols-1 flex-col gap-2 text-base text-gray-500 md:col-span-3 md:grid-cols-2 md:flex-row dark:text-gray-400"
68
+ >
69
+ <li class="flex items-start">
70
+ <IconCheck class="text-md shrink-0 pt-2" />
71
+ <p>
72
+ <a
73
+ href="/spaces/enzostvs/zero-gpu-spaces"
74
+ class="font-semibold whitespace-nowrap text-gray-700 underline decoration-gray-400 hover:text-gray-900 hover:decoration-gray-600 dark:text-gray-200 dark:hover:text-gray-200 dark:hover:decoration-gray-300"
75
+ target="_blank">ZeroGPU</a
76
+ >: Get 5x usage quota and highest GPU queue priority
77
+ </p>
78
+ </li>
79
+ <li class="flex items-start">
80
+ <IconCheck class="text-md shrink-0 pt-2" />
81
+ <p>
82
+ <a
83
+ href="/docs/hub/spaces-zerogpu"
84
+ class="font-semibold whitespace-nowrap text-gray-700 underline decoration-gray-400 hover:text-gray-900 hover:decoration-gray-600 dark:text-gray-200 dark:hover:text-gray-200 dark:hover:decoration-gray-300"
85
+ target="_blank">Spaces Hosting</a
86
+ >: Create ZeroGPU Spaces with A100 hardware
87
+ </p>
88
+ </li>
89
+ <li class="flex items-start">
90
+ <IconCheck class="text-md shrink-0 pt-2" />
91
+ <p>
92
+ <a
93
+ href="/docs/hub/spaces-dev-mode"
94
+ class="font-semibold whitespace-nowrap text-gray-700 underline decoration-gray-400 hover:text-gray-900 hover:decoration-gray-600 dark:text-gray-200 dark:hover:text-gray-200 dark:hover:decoration-gray-300"
95
+ target="_blank">Spaces Dev Mode</a
96
+ >: Fast iterations via SSH/VS Code for Spaces
97
+ </p>
98
+ </li>
99
+
100
+ <li class="flex items-start">
101
+ <IconCheck class="text-md shrink-0 pt-2" />
102
+ <p>
103
+ <a
104
+ href="https://huggingface.co/blog/inference-providers"
105
+ class="font-semibold whitespace-nowrap text-gray-700 underline decoration-gray-400 hover:text-gray-900 hover:decoration-gray-600 dark:text-gray-200 dark:hover:text-gray-200 dark:hover:decoration-gray-300"
106
+ target="_blank">Inference Providers</a
107
+ >: Get $2 included credits across all Inference Providers
108
+ </p>
109
+ </li>
110
+ <li class="flex items-start">
111
+ <IconCheck class="text-md shrink-0 pt-2" />
112
+ <p>
113
+ <a
114
+ href="/docs/hub/datasets-viewer"
115
+ class="font-semibold whitespace-nowrap text-gray-700 underline decoration-gray-400 hover:text-gray-900 hover:decoration-gray-600 dark:text-gray-200 dark:hover:text-gray-200 dark:hover:decoration-gray-300"
116
+ target="_blank">Dataset Viewer</a
117
+ >: Activate it on private datasets
118
+ </p>
119
+ </li>
120
+ <li class="flex items-start">
121
+ <IconCheck class="text-md shrink-0 pt-2" />
122
+ <p>
123
+ <a
124
+ href="/blog"
125
+ class="font-semibold whitespace-nowrap text-gray-700 underline decoration-gray-400 hover:text-gray-900 hover:decoration-gray-600 dark:text-gray-200 dark:hover:text-gray-200 dark:hover:decoration-gray-300"
126
+ target="_blank">Blog Articles</a
127
+ >: Publish articles to the Hugging Face blog
128
+ </p>
129
+ </li>
130
+ <li class="flex items-start">
131
+ <IconCheck class="text-md shrink-0 pt-2" />
132
+ <p>
133
+ <a
134
+ href="/posts"
135
+ class="font-semibold whitespace-nowrap text-gray-700 underline decoration-gray-400 hover:text-gray-900 hover:decoration-gray-600 dark:text-gray-200 dark:hover:text-gray-200 dark:hover:decoration-gray-300"
136
+ target="_blank">Social Posts</a
137
+ >: Share short updates with the community
138
+ </p>
139
+ </li>
140
+
141
+ <li class="flex items-start">
142
+ <IconCheck class="text-md shrink-0 pt-2" />
143
+ <p>
144
+ <span class="font-semibold text-gray-700 dark:text-gray-200">Features Preview</span>: Get early access
145
+ to upcoming features
146
+ </p>
147
+ </li>
148
+ <li class="flex items-start">
149
+ <IconCheck class="text-md shrink-0 pt-2" />
150
+ <p>
151
+ {@render pro()}<span class="ml-1.5 font-semibold text-gray-700 dark:text-gray-200">Badge</span>: Show
152
+ your support on your profile
153
+ </p>
154
+ </li>
155
+ </ul>
156
+ </div>
157
+
158
+ <!-- Modal footer -->
159
+ <div class="flex rounded-b border-t border-gray-200 p-4 md:p-5 dark:border-gray-800">
160
+ <a
161
+ class="ml-auto flex items-center gap-1.5 rounded-lg bg-black px-4 py-2.5 pl-3 text-sm font-medium text-white hover:bg-gray-900 focus:ring-4 focus:ring-gray-300 focus:outline-hidden dark:border-gray-700 dark:bg-gray-800 dark:hover:bg-gray-700 dark:focus:ring-gray-700"
162
+ href="https://huggingface.co/settings/billing/subscription#subscribe"
163
+ target="_blank"
164
+ >
165
+ <IconExternal />
166
+ Get Pro ($9/month)
167
+ </a>
168
+ </div>
169
+ </div>
170
+ </div>
171
+ {/if}
172
+ </dialog>
src/lib/components/toaster.svelte.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Toaster, type AddToastProps } from "melt/builders";
2
 
3
  export type ToastData = {
4
  title: string;
 
1
+ import { Toaster } from "melt/builders";
2
 
3
  export type ToastData = {
4
  title: string;
src/routes/+layout.svelte CHANGED
@@ -3,8 +3,9 @@
3
  import DebugMenu from "$lib/components/debug-menu.svelte";
4
  import Prompts from "$lib/components/prompts.svelte";
5
  import Toaster from "$lib/components/toaster.svelte";
 
6
  interface Props {
7
- children?: import('svelte').Snippet;
8
  }
9
 
10
  let { children }: Props = $props();
@@ -14,3 +15,4 @@
14
  <DebugMenu />
15
  <Prompts />
16
  <Toaster />
 
 
3
  import DebugMenu from "$lib/components/debug-menu.svelte";
4
  import Prompts from "$lib/components/prompts.svelte";
5
  import Toaster from "$lib/components/toaster.svelte";
6
+ import QuotaModal from "$lib/components/quota-modal.svelte";
7
  interface Props {
8
+ children?: import("svelte").Snippet;
9
  }
10
 
11
  let { children }: Props = $props();
 
15
  <DebugMenu />
16
  <Prompts />
17
  <Toaster />
18
+ <QuotaModal />