Widget.js default API URL changed to api.lthn.io. API docs page "Try" links now use configurable API_URL. Base URL display is dynamic. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
104 lines
5 KiB
JavaScript
104 lines
5 KiB
JavaScript
/**
|
|
* Lethean .lthn Name Search Widget
|
|
*
|
|
* Embed on any site:
|
|
* <div id="lthn-search"></div>
|
|
* <script src="https://lthn.io/widget.js"></script>
|
|
*/
|
|
(function() {
|
|
var script = document.currentScript;
|
|
var theme = (script && script.getAttribute('data-theme')) || 'dark';
|
|
var orderUrl = (script && script.getAttribute('data-order-url')) || 'https://order.lthn.ai/order/';
|
|
var apiUrl = (script && script.getAttribute('data-api')) || 'https://api.lthn.io';
|
|
var containerId = (script && script.getAttribute('data-container')) || 'lthn-search';
|
|
|
|
var c = theme === 'light'
|
|
? { bg: '#f8fafc', border: '#e2e8f0', text: '#1e293b', muted: '#64748b', accent: '#818cf8', green: '#22c55e', amber: '#f59e0b', inputBg: '#fff' }
|
|
: { bg: '#111827', border: '#1f2937', text: '#e5e7eb', muted: '#9ca3af', accent: '#818cf8', green: '#34d399', amber: '#fbbf24', inputBg: '#0a0e17' };
|
|
|
|
function el(tag, style, text) {
|
|
var e = document.createElement(tag);
|
|
if (style) Object.assign(e.style, style);
|
|
if (text) e.textContent = text;
|
|
return e;
|
|
}
|
|
|
|
function render() {
|
|
var container = document.getElementById(containerId);
|
|
if (!container) return;
|
|
container.textContent = '';
|
|
|
|
var wrap = el('div', { fontFamily: '-apple-system,BlinkMacSystemFont,sans-serif', background: c.bg, border: '1px solid ' + c.border, borderRadius: '12px', padding: '1.5rem', maxWidth: '480px' });
|
|
|
|
var title = el('div', { textAlign: 'center', marginBottom: '1rem' });
|
|
var t1 = el('span', { fontSize: '1.1rem', fontWeight: '700', color: c.text }, 'Find your ');
|
|
var t2 = el('span', { fontSize: '1.1rem', fontWeight: '700', color: c.accent }, '.lthn');
|
|
var t3 = el('span', { fontSize: '1.1rem', fontWeight: '700', color: c.text }, ' name');
|
|
title.appendChild(t1); title.appendChild(t2); title.appendChild(t3);
|
|
wrap.appendChild(title);
|
|
|
|
var row = el('div', { display: 'flex', gap: '8px' });
|
|
var input = el('input', { flex: '1', padding: '10px 14px', border: '1px solid ' + c.border, borderRadius: '8px', background: c.inputBg, color: c.text, fontSize: '0.95rem', outline: 'none' });
|
|
input.type = 'text'; input.placeholder = 'myname';
|
|
var btn = el('button', { padding: '10px 20px', background: c.accent, color: '#fff', border: 'none', borderRadius: '8px', fontWeight: '600', cursor: 'pointer', fontSize: '0.9rem' }, 'Check');
|
|
row.appendChild(input); row.appendChild(btn);
|
|
wrap.appendChild(row);
|
|
|
|
var result = el('div', { marginTop: '12px', minHeight: '24px' });
|
|
wrap.appendChild(result);
|
|
|
|
var footer = el('div', { textAlign: 'center', marginTop: '10px' });
|
|
var link = el('a', { color: c.muted, fontSize: '0.7rem', textDecoration: 'none' }, 'Powered by .lthn TLD');
|
|
link.href = 'https://lthn.io'; link.target = '_blank';
|
|
footer.appendChild(link);
|
|
wrap.appendChild(footer);
|
|
|
|
container.appendChild(wrap);
|
|
|
|
function check() {
|
|
var name = input.value.trim().toLowerCase().replace(/\.lthn$/, '');
|
|
if (!name) return;
|
|
result.textContent = '';
|
|
var loading = el('span', { color: c.muted, fontSize: '0.85rem' }, 'Checking...');
|
|
result.appendChild(loading);
|
|
btn.disabled = true;
|
|
|
|
fetch(apiUrl + '/v1/names/available/' + encodeURIComponent(name), { headers: { 'Accept': 'application/json' } })
|
|
.then(function(r) { return r.json(); })
|
|
.then(function(data) {
|
|
btn.disabled = false;
|
|
result.textContent = '';
|
|
if (data.available && !data.reserved) {
|
|
var row2 = el('div', { display: 'flex', alignItems: 'center', justifyContent: 'space-between' });
|
|
row2.appendChild(el('span', { color: c.green, fontWeight: '600', fontSize: '0.9rem' }, name + '.lthn is available!'));
|
|
var regLink = el('a', { padding: '6px 16px', background: c.green, color: '#fff', borderRadius: '6px', textDecoration: 'none', fontSize: '0.8rem', fontWeight: '600' }, 'Register');
|
|
regLink.href = orderUrl; regLink.target = '_blank';
|
|
row2.appendChild(regLink);
|
|
result.appendChild(row2);
|
|
} else if (data.reserved) {
|
|
result.appendChild(el('span', { color: c.amber, fontSize: '0.85rem' }, name + '.lthn is reserved during sunrise period.'));
|
|
} else {
|
|
var taken = el('span', { color: c.amber, fontSize: '0.85rem' }, name + '.lthn is already taken. ');
|
|
var detailLink = el('a', { color: c.accent }, 'View details');
|
|
detailLink.href = apiUrl + '/names/' + name; detailLink.target = '_blank';
|
|
taken.appendChild(detailLink);
|
|
result.appendChild(taken);
|
|
}
|
|
})
|
|
.catch(function() {
|
|
btn.disabled = false;
|
|
result.textContent = '';
|
|
result.appendChild(el('span', { color: c.amber, fontSize: '0.85rem' }, 'Could not check availability. Try again.'));
|
|
});
|
|
}
|
|
|
|
btn.addEventListener('click', check);
|
|
input.addEventListener('keypress', function(e) { if (e.key === 'Enter') check(); });
|
|
}
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', render);
|
|
} else {
|
|
render();
|
|
}
|
|
})();
|