Skip to content

Commit 83375c8

Browse files
committed
Attempt to make loading indicator
1 parent 170c8ea commit 83375c8

5 files changed

Lines changed: 254 additions & 122 deletions

File tree

api/_public/main.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const highlighter = await createHighlighter({
88
langs: ['shellsession', 'shell'],
99
})
1010

11+
document.getElementById('hl-loading')?.remove()
1112
console.log('highlighter', highlighter)
1213

1314

@@ -16,14 +17,29 @@ document.addEventListener('alpine:init', () => {
1617
curl: '',
1718
httpie: '',
1819
errors: [],
20+
loading: false,
21+
highlighting: false,
22+
highlightedHtml: '',
1923
async onSubmit() {
24+
this.loading = true
2025
const { httpie, errors } = await ky.post('/api/', { json: { curl: this.curl } }).json()
2126
this.httpie = '$ ' + httpie
2227
this.errors = errors
28+
this.loading = false
29+
this.highlighting = true
30+
setTimeout(() => {
31+
this.highlightedHtml = highlighter.codeToHtml(this.httpie, { lang: 'shellsession', theme: 'andromeeda' })
32+
this.highlighting = false
33+
}, 0)
2334
},
2435
colorizeHttpie() {
2536
if (!this.httpie) return ''
2637
return highlighter.codeToHtml(this.httpie, { lang: 'shellsession', theme: 'andromeeda' })
38+
},
39+
copyHttpie() {
40+
const cmd = (this.httpie || '').replace(/^\$ /, '')
41+
if (!cmd) return
42+
navigator.clipboard?.writeText(cmd)
2743
}
2844
}))
2945
})

api/_public/uno.css

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
.mx-auto{margin-left:auto;margin-right:auto;}
2424
.mb-8{margin-bottom:2rem;}
2525
.mt-4{margin-top:1rem;}
26+
.inline-block{display:inline-block;}
2627
.h-4{height:1rem;}
2728
.h-48{height:12rem;}
2829
.h-5{height:1.25rem;}
@@ -36,32 +37,46 @@
3637
.flex{display:flex;}
3738
.grow{flex-grow:1;}
3839
.flex-col{flex-direction:column;}
40+
@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
41+
.animate-spin{animation:spin 1s linear infinite;}
3942
.cursor-pointer{cursor:pointer;}
4043
.select-none{-webkit-user-select:none;user-select:none;}
4144
.resize-y{resize:vertical;}
4245
.items-center{align-items:center;}
4346
.justify-between{justify-content:space-between;}
4447
.gap-1{gap:0.25rem;}
48+
.gap-2{gap:0.5rem;}
4549
.space-y-4>:not([hidden])~:not([hidden]){--un-space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--un-space-y-reverse)));margin-bottom:calc(1rem * var(--un-space-y-reverse));}
4650
.overflow-hidden{overflow:hidden;}
51+
.border-2{border-width:2px;}
52+
.border-white{--un-border-opacity:1;border-color:rgb(255 255 255 / var(--un-border-opacity));}
53+
.border-t-purple-500{--un-border-opacity:1;--un-border-top-opacity:var(--un-border-opacity);border-top-color:rgb(168 85 247 / var(--un-border-top-opacity));}
54+
.rounded{border-radius:0.25rem;}
55+
.rounded-full{border-radius:9999px;}
4756
.rounded-t{border-top-left-radius:0.25rem;border-top-right-radius:0.25rem;}
48-
.bg-gray-900{--un-bg-opacity:1;background-color:rgb(17 24 39 / var(--un-bg-opacity));}
57+
.bg-gray-700{--un-bg-opacity:1;background-color:rgb(55 65 81 / var(--un-bg-opacity)) /* #374151 */;}
58+
.bg-gray-900{--un-bg-opacity:1;background-color:rgb(17 24 39 / var(--un-bg-opacity)) /* #111827 */;}
59+
.hover\:bg-gray-600:hover{--un-bg-opacity:1;background-color:rgb(75 85 99 / var(--un-bg-opacity)) /* #4b5563 */;}
4960
.from-gray-700{--un-gradient-from-position:0%;--un-gradient-from:rgb(55 65 81 / var(--un-from-opacity, 1)) var(--un-gradient-from-position);--un-gradient-to-position:100%;--un-gradient-to:rgb(55 65 81 / 0) var(--un-gradient-to-position);--un-gradient-stops:var(--un-gradient-from), var(--un-gradient-to);}
5061
.to-gray-800{--un-gradient-to-position:100%;--un-gradient-to:rgb(31 41 55 / var(--un-to-opacity, 1)) var(--un-gradient-to-position);}
51-
.bg-gradient-to-b{--un-gradient-shape:to bottom;--un-gradient:var(--un-gradient-shape), var(--un-gradient-stops);background-image:linear-gradient(var(--un-gradient));}
62+
.bg-gradient-to-b{--un-gradient-shape:to bottom in oklch;--un-gradient:var(--un-gradient-shape), var(--un-gradient-stops);background-image:linear-gradient(var(--un-gradient));}
5263
.p-1{padding:0.25rem;}
5364
.p-2{padding:0.5rem;}
5465
.px-2{padding-left:0.5rem;padding-right:0.5rem;}
66+
.py-1{padding-top:0.25rem;padding-bottom:0.25rem;}
67+
.py-2{padding-top:0.5rem;padding-bottom:0.5rem;}
5568
.pb-2{padding-bottom:0.5rem;}
5669
.text-center{text-align:center;}
5770
.text-sm{font-size:0.875rem;line-height:1.25rem;}
58-
.text-gray-300{--un-text-opacity:1;color:rgb(209 213 219 / var(--un-text-opacity));}
59-
.text-purple-600{--un-text-opacity:1;color:rgb(147 51 234 / var(--un-text-opacity));}
60-
.text-red-400{--un-text-opacity:1;color:rgb(248 113 113 / var(--un-text-opacity));}
61-
.hover\:text-red-400:hover{--un-text-opacity:1;color:rgb(248 113 113 / var(--un-text-opacity));}
71+
.text-xs{font-size:0.75rem;line-height:1rem;}
72+
.text-gray-300{--un-text-opacity:1;color:rgb(209 213 219 / var(--un-text-opacity)) /* #d1d5db */;}
73+
.text-purple-600{--un-text-opacity:1;color:rgb(147 51 234 / var(--un-text-opacity)) /* #9333ea */;}
74+
.text-red-400{--un-text-opacity:1;color:rgb(248 113 113 / var(--un-text-opacity)) /* #f87171 */;}
75+
.hover\:text-red-400:hover{--un-text-opacity:1;color:rgb(248 113 113 / var(--un-text-opacity)) /* #f87171 */;}
6276
.font-bold{font-weight:700;}
6377
.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;}
6478
.shadow-lg{--un-shadow:var(--un-shadow-inset) 0 10px 15px -3px var(--un-shadow-color, rgb(0 0 0 / 0.1)),var(--un-shadow-inset) 0 4px 6px -4px var(--un-shadow-color, rgb(0 0 0 / 0.1));box-shadow:var(--un-ring-offset-shadow), var(--un-ring-shadow), var(--un-shadow);}
79+
.drop-shadow{--un-drop-shadow:drop-shadow(0 1px 2px var(--un-drop-shadow-color, rgb(0 0 0 / 0.1))) drop-shadow(0 1px 1px var(--un-drop-shadow-color, rgb(0 0 0 / 0.06)));filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia);}
6580
@media (min-width: 640px){
6681
.sm\:flex-row{flex-direction:row;}
6782
.sm\:resize-none{resize:none;}

api/templates/index.jinja

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,24 @@
4141
<svg class='w-5 h-5 cursor-pointer' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'><path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z'></path></svg>
4242
<span class='font-bold select-none'>Terminal</span>
4343
</div>
44-
<div class='flex items-center gap-1'>
44+
<div class='flex items-center gap-2'>
45+
<div id='hl-loading' class='flex items-center'>
46+
<span class='inline-block w-4 h-4 border-2 border-white border-t-purple-500 rounded-full animate-spin drop-shadow'></span>
47+
</div>
48+
<div class='flex items-center' x-show='loading'>
49+
<span class='inline-block w-4 h-4 border-2 border-white border-t-purple-500 rounded-full animate-spin drop-shadow'></span>
50+
</div>
51+
<button class='text-xs px-2 py-1 rounded bg-gray-700 hover:bg-gray-600' x-on:click='copyHttpie()'>Copy</button>
4552
<svg class='w-4 h-4 cursor-pointer hover:text-red-400' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'><path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 9l-7 7-7-7'></path></svg>
4653
<svg class='w-4 h-4 cursor-pointer hover:text-red-400' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'><path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 15l7-7 7 7'></path></svg>
4754
<svg class='w-4 h-4 cursor-pointer hover:text-red-400' fill='currentColor' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'><path fill-rule='evenodd' d='M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z' clip-rule='evenodd'></path></svg>
4855
</div>
4956
</div>
50-
<div class='p-1 bg-gray-900 font-mono min-h-24' x-html='colorizeHttpie()'>
57+
<div class='p-1 bg-gray-900 font-mono min-h-24'>
58+
<div x-show='highlighting' class='py-2'>
59+
<span class='inline-block w-4 h-4 border-2 border-white border-t-purple-500 rounded-full animate-spin drop-shadow'></span>
60+
</div>
61+
<div x-show='!highlighting' x-html='highlightedHtml'></div>
5162
</div>
5263
</div>
5364

pyproject.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ dependencies = [
1313
"orjson>=3.10.15",
1414
"first>=2.0.2",
1515
"http-constants>=0.5.0",
16-
"logbook>=1.8.0",
16+
"logbook>=1.9.2",
1717
"kiss-headers>=2.5.0",
18-
"pydantic>=2.10.6",
19-
"typed-argument-parser>=1.10.1",
20-
"pydantic-settings>=2.7.1",
18+
"pydantic>=2.12.5",
19+
"typed-argument-parser>=1.11.0",
20+
"pydantic-settings>=2.12.0",
2121
]
2222
classifiers = [
2323
"Intended Audience :: Developers",
@@ -40,7 +40,7 @@ dev = [
4040
"jinja2>=3.1.5",
4141
]
4242
lint = [
43-
"ruff>=0.9.5",
43+
"ruff>=0.14.10",
4444
]
4545
test = [
4646
"mypy>=1.15.0",

0 commit comments

Comments
 (0)