ui-tweaks
#1
by
victor
HF Staff
- opened
- public/index.html +89 -81
public/index.html
CHANGED
|
@@ -10,7 +10,8 @@
|
|
| 10 |
<div class="flex flex-col md:flex-row" x-data="app()" x-init="init()">
|
| 11 |
<div
|
| 12 |
class="hero md:h-screen bg-stone-100 transition-[width] delay-150 ease-in-out"
|
| 13 |
-
:class="open ? 'w-full md:w-2/6' : 'w-full md:w-6/6'"
|
|
|
|
| 14 |
<div class="hero-content text-center">
|
| 15 |
<div class="flex flex-col w-full md:max-w-xl space-y-3 md:space-y-6">
|
| 16 |
<h1
|
|
@@ -18,12 +19,15 @@
|
|
| 18 |
:class="open
|
| 19 |
? 'text-2xl md:text-3xl lg:text-4xl'
|
| 20 |
: 'text-2xl md:text-3xl lg:text-6xl'"
|
| 21 |
-
>
|
|
|
|
|
|
|
| 22 |
<div
|
| 23 |
class="py-1 md:py-2 space-y-2 md:space-y-4 text-stone-600 transition-all delay-150 ease-in-out"
|
| 24 |
:class="open
|
| 25 |
? 'text-lg md:text-xl lg:text-2xl'
|
| 26 |
-
: 'text-lg md:text-xl lg:text-2xl'"
|
|
|
|
| 27 |
<p>A space to generate web content using WizardCoder.</p>
|
| 28 |
<p>Running on π€ Inference Endpoints.</p>
|
| 29 |
</div>
|
|
@@ -32,10 +36,7 @@
|
|
| 32 |
x-model="promptDraft"
|
| 33 |
rows="10"
|
| 34 |
placeholder="A simple page to compute the BMI (use SI units)"
|
| 35 |
-
class="input input-bordered w-full rounded text-stone-500 bg-stone-300 font-mono
|
| 36 |
-
text-md md:text-lg
|
| 37 |
-
h-24 md:h-48
|
| 38 |
-
"
|
| 39 |
></textarea>
|
| 40 |
<button
|
| 41 |
class="btn disabled:text-stone-400"
|
|
@@ -47,99 +48,106 @@
|
|
| 47 |
<span x-show="promptDraft.length >= minPromptSize && state !== 'stopped'">Stop now</span>
|
| 48 |
<span x-show="promptDraft.length >= minPromptSize && state === 'stopped'">Generate!</span>
|
| 49 |
</button>
|
| 50 |
-
<span class="py-3" x-show="state === 'loading'"
|
|
|
|
|
|
|
| 51 |
<span class="py-3" x-show="state === 'streaming'">
|
| 52 |
-
Streamed <span x-text="humanFileSize(size, true, 2)"></span> so far..<br/>Note: this version generates up
|
|
|
|
|
|
|
| 53 |
</div>
|
| 54 |
</div>
|
| 55 |
</div>
|
| 56 |
<div
|
| 57 |
class="flex transition-[width] delay-150 ease-in-out md:h-screen"
|
| 58 |
-
:class="open ? 'w-full md:w-4/6' : 'w-full md:w-0'"
|
|
|
|
| 59 |
<iframe
|
| 60 |
id="iframe"
|
| 61 |
-
class="border-none w-full md:h-screen"
|
| 62 |
:src="!open
|
| 63 |
? '/placeholder.html'
|
| 64 |
: `/app?prompt=${encodeURIComponent(prompt)}`
|
| 65 |
-
"
|
|
|
|
| 66 |
</div>
|
| 67 |
</div>
|
| 68 |
<script>
|
| 69 |
/**
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
function humanFileSize(bytes, si=false, dp=1) {
|
| 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 |
-
return
|
| 123 |
-
}
|
| 124 |
-
this.size = new Blob([html]).size
|
| 125 |
-
this.state = 'streaming'
|
| 126 |
-
const lastTokenAt = + new Date()
|
| 127 |
-
const elapsed = (lastTokenAt - this.lastTokenAt) / 1000
|
| 128 |
-
this.lastTokenAt = lastTokenAt
|
| 129 |
-
if (elapsed > this.timeoutInSec) {
|
| 130 |
-
console.log(`Something went wrong, it too more than ${this.timeoutInSec} seconds to generate a token.`)
|
| 131 |
-
this.state = 'stopped'
|
| 132 |
-
return
|
| 133 |
-
}
|
| 134 |
-
if (html.includes('</html>')) {
|
| 135 |
-
// console.log('We reached the natural end of the stream, it seems.')
|
| 136 |
-
// this.state === 'stopped'
|
| 137 |
-
return
|
| 138 |
-
}
|
| 139 |
-
}, 100)
|
| 140 |
-
},
|
| 141 |
-
}
|
| 142 |
-
}
|
| 143 |
</script>
|
| 144 |
</body>
|
| 145 |
-
</html>
|
|
|
|
| 10 |
<div class="flex flex-col md:flex-row" x-data="app()" x-init="init()">
|
| 11 |
<div
|
| 12 |
class="hero md:h-screen bg-stone-100 transition-[width] delay-150 ease-in-out"
|
| 13 |
+
:class="open ? 'w-full md:w-2/6' : 'w-full md:w-6/6'"
|
| 14 |
+
>
|
| 15 |
<div class="hero-content text-center">
|
| 16 |
<div class="flex flex-col w-full md:max-w-xl space-y-3 md:space-y-6">
|
| 17 |
<h1
|
|
|
|
| 19 |
:class="open
|
| 20 |
? 'text-2xl md:text-3xl lg:text-4xl'
|
| 21 |
: 'text-2xl md:text-3xl lg:text-6xl'"
|
| 22 |
+
>
|
| 23 |
+
Webapp Factory π
|
| 24 |
+
</h1>
|
| 25 |
<div
|
| 26 |
class="py-1 md:py-2 space-y-2 md:space-y-4 text-stone-600 transition-all delay-150 ease-in-out"
|
| 27 |
:class="open
|
| 28 |
? 'text-lg md:text-xl lg:text-2xl'
|
| 29 |
+
: 'text-lg md:text-xl lg:text-2xl'"
|
| 30 |
+
>
|
| 31 |
<p>A space to generate web content using WizardCoder.</p>
|
| 32 |
<p>Running on π€ Inference Endpoints.</p>
|
| 33 |
</div>
|
|
|
|
| 36 |
x-model="promptDraft"
|
| 37 |
rows="10"
|
| 38 |
placeholder="A simple page to compute the BMI (use SI units)"
|
| 39 |
+
class="input input-bordered w-full rounded text-stone-500 bg-stone-300 font-mono text-md md:text-lg h-24 md:h-48"
|
|
|
|
|
|
|
|
|
|
| 40 |
></textarea>
|
| 41 |
<button
|
| 42 |
class="btn disabled:text-stone-400"
|
|
|
|
| 48 |
<span x-show="promptDraft.length >= minPromptSize && state !== 'stopped'">Stop now</span>
|
| 49 |
<span x-show="promptDraft.length >= minPromptSize && state === 'stopped'">Generate!</span>
|
| 50 |
</button>
|
| 51 |
+
<span class="py-3" x-show="state === 'loading'"
|
| 52 |
+
>Waiting for the stream to begin (might take a few minutes)..</span
|
| 53 |
+
>
|
| 54 |
<span class="py-3" x-show="state === 'streaming'">
|
| 55 |
+
Streamed <span x-text="humanFileSize(size, true, 2)"></span> so far..<br />Note: this version generates up
|
| 56 |
+
to 1024 tokens.</span
|
| 57 |
+
>
|
| 58 |
</div>
|
| 59 |
</div>
|
| 60 |
</div>
|
| 61 |
<div
|
| 62 |
class="flex transition-[width] delay-150 ease-in-out md:h-screen"
|
| 63 |
+
:class="open ? 'w-full md:w-4/6' : 'w-full md:w-0'"
|
| 64 |
+
>
|
| 65 |
<iframe
|
| 66 |
id="iframe"
|
| 67 |
+
class="border-none w-full md:min-h-screen p-4 md:p-8"
|
| 68 |
:src="!open
|
| 69 |
? '/placeholder.html'
|
| 70 |
: `/app?prompt=${encodeURIComponent(prompt)}`
|
| 71 |
+
"
|
| 72 |
+
></iframe>
|
| 73 |
</div>
|
| 74 |
</div>
|
| 75 |
<script>
|
| 76 |
/**
|
| 77 |
+
* Format bytes as human-readable text.
|
| 78 |
+
*
|
| 79 |
+
* @param bytes Number of bytes.
|
| 80 |
+
* @param si True to use metric (SI) units, aka powers of 1000. False to use
|
| 81 |
+
* binary (IEC), aka powers of 1024.
|
| 82 |
+
* @param dp Number of decimal places to display.
|
| 83 |
+
*
|
| 84 |
+
* @return Formatted string.
|
| 85 |
+
*/
|
| 86 |
+
function humanFileSize(bytes, si = false, dp = 1) {
|
| 87 |
+
const thresh = si ? 1000 : 1024;
|
| 88 |
|
| 89 |
+
if (Math.abs(bytes) < thresh) {
|
| 90 |
+
return bytes + " B";
|
| 91 |
+
}
|
| 92 |
|
| 93 |
+
const units = si
|
| 94 |
+
? ["kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]
|
| 95 |
+
: ["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
|
| 96 |
+
let u = -1;
|
| 97 |
+
const r = 10 ** dp;
|
| 98 |
|
| 99 |
+
do {
|
| 100 |
+
bytes /= thresh;
|
| 101 |
+
++u;
|
| 102 |
+
} while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1);
|
| 103 |
|
| 104 |
+
return bytes.toFixed(dp) + " " + units[u];
|
| 105 |
+
}
|
| 106 |
+
function app() {
|
| 107 |
+
return {
|
| 108 |
+
open: false,
|
| 109 |
+
promptDraft:
|
| 110 |
+
new URLSearchParams(window.location.search).get("prompt") ||
|
| 111 |
+
"A simple page to compute the BMI (use SI units)",
|
| 112 |
+
prompt: "",
|
| 113 |
+
size: 0,
|
| 114 |
+
minPromptSize: 16, // if you change this, you will need to also change in src/index.mts
|
| 115 |
+
timeoutInSec: 10, // time before we determine something went wrong
|
| 116 |
+
state: "stopped",
|
| 117 |
+
lastTokenAt: +new Date(),
|
| 118 |
+
init() {
|
| 119 |
+
setInterval(() => {
|
| 120 |
+
if (this.state === "stopped") {
|
| 121 |
+
this.lastTokenAt = +new Date();
|
| 122 |
+
return;
|
| 123 |
+
}
|
| 124 |
+
const html = document?.getElementById("iframe")?.contentWindow?.document?.documentElement?.outerHTML;
|
| 125 |
+
const size = Number(html?.length); // count how many characters we have generated
|
| 126 |
|
| 127 |
+
if (isNaN(size) || !isFinite(size)) {
|
| 128 |
+
this.size = 0;
|
| 129 |
+
this.state = "loading";
|
| 130 |
+
return;
|
| 131 |
+
}
|
| 132 |
+
this.size = new Blob([html]).size;
|
| 133 |
+
this.state = "streaming";
|
| 134 |
+
const lastTokenAt = +new Date();
|
| 135 |
+
const elapsed = (lastTokenAt - this.lastTokenAt) / 1000;
|
| 136 |
+
this.lastTokenAt = lastTokenAt;
|
| 137 |
+
if (elapsed > this.timeoutInSec) {
|
| 138 |
+
console.log(`Something went wrong, it too more than ${this.timeoutInSec} seconds to generate a token.`);
|
| 139 |
+
this.state = "stopped";
|
| 140 |
+
return;
|
| 141 |
+
}
|
| 142 |
+
if (html.includes("</html>")) {
|
| 143 |
+
// console.log('We reached the natural end of the stream, it seems.')
|
| 144 |
+
// this.state === 'stopped'
|
| 145 |
+
return;
|
| 146 |
+
}
|
| 147 |
+
}, 100);
|
| 148 |
+
},
|
| 149 |
+
};
|
| 150 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 151 |
</script>
|
| 152 |
</body>
|
| 153 |
+
</html>
|