Fix: Resolve button click and icon rendering race condition

This commit is contained in:
2025-09-26 15:32:19 -07:00
parent 23a11456ed
commit b103f99bad

View File

@@ -18,6 +18,7 @@
.btn:disabled{opacity:.6;cursor:not-allowed;box-shadow:none}
.btn:hover{transform:translateY(-1px)}
.btn.phantom{background:transparent;box-shadow:none}
.btn>*{pointer-events:none}
.hero{display:grid;gap:18px;justify-items:center;text-align:center;padding:40px 0}
.h1{font-size:clamp(28px,6vw,44px);letter-spacing:-.02em;line-height:1.08;margin:0}
.sub{max-width:680px;color:var(--muted)}
@@ -164,13 +165,13 @@ init(){document.documentElement.setAttribute('data-theme',this.t);this.freshIcon
setTheme(v){this.t=v;localStorage.setItem('theme',v);document.documentElement.setAttribute('data-theme',v);this.freshIcons()},
toggleTheme(){this.setTheme(this.t==='light'?'dark':'light')},
val(u){try{new URL(u);return 1}catch(e){return 0}},
async shorten(){if(this.busy||!this.val(this.url))return this.toast('Enter a valid URL');this.busy=1;try{const r=await fetch(this.base,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({url:this.url.trim()})});if(!r.ok)throw'';const d=await r.json();this.short=d.shortUrl;this.links.unshift({slug:d.slug,target:d.target,created:Date.now()});this.links.splice(20);localStorage.setItem('4ev.links',JSON.stringify(this.links));this.url='';this.toast('Link created')}catch(e){this.toast('Failed to shorten link')}finally{this.busy=0;this.freshIcons()}},
async shorten(){if(this.busy||!this.val(this.url))return this.toast('Enter a valid URL');this.busy=1;this.freshIcons();try{const r=await fetch(this.base,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({url:this.url.trim()})});if(!r.ok)throw'';const d=await r.json();this.short=d.shortUrl;this.links.unshift({slug:d.slug,target:d.target,created:Date.now()});this.links.splice(20);localStorage.setItem('4ev.links',JSON.stringify(this.links));this.url='';this.toast('Link created')}catch(e){this.toast('Failed to shorten link')}finally{this.busy=0;this.freshIcons()}},
copy(txt){navigator.clipboard?.writeText(txt).then(()=>this.toast('Copied')).catch(()=>{let t=document.createElement('textarea');t.value=txt;document.body.appendChild(t);t.select();document.execCommand('copy');t.remove();this.toast('Copied')})},
toast(m){this.msg=m;this.freshIcons();clearTimeout(this._to);this._to=setTimeout(()=>this.msg='',2000)},
del(i){this.links.splice(i,1);localStorage.setItem('4ev.links',JSON.stringify(this.links));this.freshIcons()},
freshIcons(){try{lucide&&lucide.createIcons()}catch(e){}}
freshIcons(){this.$nextTick(()=>(lucide?.createIcons()))}
});
document.addEventListener('DOMContentLoaded',()=>{try{lucide.createIcons()}catch(e){}});
document.addEventListener('DOMContentLoaded',()=>{lucide.createIcons()});
</script>
<style>@keyframes spin{to{transform:rotate(360deg)}}</style>
<div x-data="{m:''}" x-init="$watch('$root.__x.$data.msg',v=>{m=v})">