Spaces:
Runtime error
Runtime error
Thomas G. Lopes
commited on
Commit
·
a5619c2
1
Parent(s):
2087f3e
add quota modal
Browse files- src/lib/actions/autofocus.ts +5 -1
- src/lib/components/debug-menu.svelte +7 -0
- src/lib/components/inference-playground/conversation.svelte +0 -2
- src/lib/components/prompts.svelte +9 -14
- src/lib/components/quota-modal.svelte +172 -0
- src/lib/components/toaster.svelte.ts +1 -1
- src/routes/+layout.svelte +3 -1
src/lib/actions/autofocus.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
|
|
|
|
|
| 1 |
export function autofocus(node: HTMLElement) {
|
| 2 |
-
|
|
|
|
|
|
|
| 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 |
-
|
|
|
|
| 15 |
|
| 16 |
export function resolvePrompt() {
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
});
|
| 21 |
}
|
| 22 |
|
| 23 |
-
export async function prompt(label: string,
|
| 24 |
return new Promise(res => {
|
| 25 |
-
prompts.
|
| 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 |
-
|
| 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
|
| 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(
|
| 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 />
|