File size: 4,755 Bytes
f144646
fbef5e8
4b8b411
fbef5e8
c3571d4
 
da972f7
936176c
 
f144646
 
d4fcb0f
0bcf467
f144646
c3571d4
f144646
 
 
c3571d4
 
 
 
60216ec
f144646
 
c3571d4
 
 
 
 
 
 
 
 
 
 
 
 
f144646
 
c3571d4
f144646
c3571d4
 
 
 
f144646
c3571d4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64cfbce
c3571d4
 
 
 
f144646
 
c3571d4
 
 
f144646
c3571d4
 
 
 
 
 
 
f144646
c3571d4
 
 
 
 
 
 
 
f144646
c3571d4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<script lang="ts">
	import { clickOutside } from "$lib/attachments/click-outside.js";

	import { autofocus } from "$lib/attachments/autofocus.js";
	import { token } from "$lib/state/token.svelte";
	import IconCross from "~icons/carbon/close";

	let backdropEl = $state<HTMLDivElement>();
	let modalEl = $state<HTMLDivElement>();

	function handleKeydown(event: KeyboardEvent) {
		const { key } = event;
		if (key === "Escape") {
			event.preventDefault();
			token.showModal = false;
		}
	}

	$effect(() => {
		if (token.showModal) {
			document.getElementById("app")?.setAttribute("inert", "true");
		} else {
			document.getElementById("app")?.removeAttribute("inert");
		}
	});

	function handleTokenSubmit(e: Event) {
		e.preventDefault();
		const form = e.target as HTMLFormElement;
		const formData = new FormData(form);
		const submittedHfToken = (formData.get("hf-token") as string).trim() ?? "";
		const RE_HF_TOKEN = /\bhf_[a-zA-Z0-9]{34}\b/;
		if (RE_HF_TOKEN.test(submittedHfToken)) {
			token.value = submittedHfToken;
		} else {
			alert("Please provide a valid HF token.");
		}
	}
</script>

{#if token.showModal}
	<div
		id="default-modal"
		aria-hidden="true"
		class="fixed inset-0 z-50 flex items-center justify-center overflow-hidden bg-black/85"
		bind:this={backdropEl}
	>
		<div
			role="dialog"
			tabindex="-1"
			class="relative max-h-full w-full max-w-xl p-4 outline-hidden"
			bind:this={modalEl}
			onkeydown={handleKeydown}
			{@attach clickOutside(() => (token.showModal = false))}
		>
			<form onsubmit={handleTokenSubmit} class="relative rounded-lg bg-white shadow-sm dark:bg-gray-900">
				<div class="flex items-center justify-between rounded-t border-b p-4 md:px-5 md:py-4 dark:border-gray-800">
					<h3 class="flex items-center gap-2.5 text-lg font-semibold text-gray-900 dark:text-white">
						<img
							alt="Hugging Face's logo"
							class="w-7"
							src="https://huggingface.co/front/assets/huggingface_logo-noborder.svg"
						/> Add a Hugging Face Token
					</h3>
					<button
						type="button"
						onclick={() => (token.showModal = false)}
						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"
					>
						<div class="text-xl">
							<IconCross />
						</div>
						<span class="sr-only">Close modal</span>
					</button>
				</div>
				<!-- Modal body -->
				<div class="p-4 md:p-5">
					<p class="mb-5 text-base leading-relaxed text-gray-800 2xl:text-balance dark:text-gray-300">
						You need a free Hugging Face token to use this application. <strong class="font-semibold"
							>Make sure you create a token with Inference API permission.</strong
						><br /> Your token is kept safe by only being used from your browser.
					</p>
					<div>
						<label for="hf-token" class="mb-2 block text-sm font-medium text-gray-900 dark:text-white">
							Hugging Face Token
						</label>
						<input
							required
							placeholder="Enter HF Token"
							type="text"
							id="hf-token"
							name="hf-token"
							class="block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
							{@attach autofocus()}
						/>
					</div>
					<label class="mt-4 flex items-center gap-x-1.5 text-gray-900 dark:text-gray-200">
						<input type="checkbox" bind:checked={token.writeToLocalStorage} />
						<p class="text-sm leading-none">Save to local storage for future use</p></label
					>
				</div>

				<!-- Modal footer -->
				<div
					class="flex items-center justify-between rounded-b border-t border-gray-200 p-4 md:p-5 dark:border-gray-800"
				>
					<a
						href="https://huggingface.co/settings/tokens/new?ownUserPermissions=inference.serverless.write&tokenType=fineGrained"
						tabindex="-1"
						target="_blank"
						class="rounded-lg border border-gray-200 bg-white px-5 py-2.5 text-sm font-medium text-gray-900 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 focus:outline-hidden dark:border-gray-600 dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white dark:focus:ring-gray-700"
						>Create new token</a
					>

					<button
						type="submit"
						class="rounded-lg bg-black px-5 py-2.5 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"
						>Submit</button
					>
				</div>
			</form>
		</div>
	</div>
{/if}