Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167import { createCard } from './components/Card.js';import { renderProgressMap as renderProgressMapEl } from './components/ProgressMap.js';import { attachTypeahead } from './components/HandleTypeahead.js';import { createElement, RefreshCw, UserPlus, UserMinus, Sprout, ArrowRight } from 'lucide';
const ARROW_RIGHT_HTML = createElement(ArrowRight, { width: 16, height: 16, 'stroke-width': 2, class: 'inline align-text-bottom ml-1' }).outerHTML;
const ICON_MAP = { follow: UserPlus, unfollow: UserMinus, seed: Sprout, refresh: RefreshCw };export function iconHtml(type, size = 14) { const node = ICON_MAP[type]; if (!node) return ''; return createElement(node, { width: size, height: size, 'stroke-width': 2, class: 'inline align-text-bottom' }).outerHTML;}
export const KEYS = ['a', 's', 'd', 'f'];
export const secretBtns = `<span class="hidden sm:inline">— </span><br class="sm:hidden" /><span id="refresh-btn" class="cursor-pointer">[r] refresh</span><span id="back-btn" class="cursor-pointer"> / [b] back</span><span id="forward-btn" class="cursor-pointer"> / [n] next</span>`;
export function showLoading(msg) { document.getElementById('login-screen').style.display = 'none'; document.getElementById('discover-screen').style.display = 'none'; const ls = document.getElementById('loading-screen'); ls.style.display = 'block'; ls.textContent = msg || 'loading…';}
export function showDiscover() { document.getElementById('login-screen').style.display = 'none'; document.getElementById('loading-screen').style.display = 'none'; document.getElementById('discover-screen').style.display = 'block';}
export function setStatus(msg) { document.getElementById('status').innerHTML = msg; }
export function updateFollowCounter(count) { const el = document.getElementById('follow-counter'); if (el) el.textContent = `${count.toLocaleString()} following`;}
export function setUndoVisible(visible) { const hint = document.getElementById('z-hint'); if (hint) hint.style.display = visible ? 'block' : 'none';}
export function setSmallOnlyChecked(checked) { const el = document.getElementById('small-only-toggle'); if (el) el.checked = checked;}
export function setBackVisible(visible) { const btn = document.getElementById('back-btn'); if (btn) btn.style.display = visible ? '' : 'none';}
export function setForwardVisible(visible) { const btn = document.getElementById('forward-btn'); if (btn) btn.style.display = visible ? '' : 'none';}
export function showLoginError(msg) { document.getElementById('login-error').textContent = msg || ''; }
export function showError(msg) { document.getElementById('error').textContent = msg || '';}
export function setRefreshSpinnerVisible(visible) { const el = document.getElementById('refresh-spinner'); if (el) el.style.display = visible ? 'flex' : 'none';}
export function setGridDimmed(dimmed) { const classList = document.getElementById('grid').classList; if (dimmed) { classList.add('opacity-40', 'pointer-events-none'); } else { classList.remove('opacity-40', 'pointer-events-none'); }}
export function highlightCard(index) { const card = document.getElementById('grid').children[index]; if (!card) return () => {}; card.classList.add('outline', 'outline-4', 'outline-offset-4', 'outline-black', 'dark:outline-gray-600'); return () => card.classList.remove('outline', 'outline-4', 'outline-offset-4', 'outline-black', 'dark:outline-gray-600');}
export function renderGrid(candidates, onSelect, followingSet) { const grid = document.getElementById('grid'); grid.innerHTML = ''; candidates.forEach((p, i) => { const followed = followingSet?.has(p.did) ?? false; const card = createCard(p, KEYS[i], followed ? null : () => onSelect(i), followed); grid.appendChild(card); });}
export function renderProgressMap(timelineEvents, myAvatar, cursor) { renderProgressMapEl(document.getElementById('progress-map'), timelineEvents, myAvatar, cursor);}
export function setLoginLoading(isLoading) { const btn = document.getElementById('login-btn'); btn.disabled = isLoading; btn.innerHTML = isLoading ? 'redirecting…' : `enter tunnel${ARROW_RIGHT_HTML}`; if (isLoading) showLoginError('');}
export function bindEvents({ onLogin, onLogout, onKeySelect, onRefresh, onBack, onForward, onUndo, onSmallOnlyToggle }) { const smallToggle = document.getElementById('small-only-toggle'); if (smallToggle && onSmallOnlyToggle) { smallToggle.addEventListener('change', () => { onSmallOnlyToggle(smallToggle.checked); smallToggle.blur(); }); } setLoginLoading(false); const handleInput = document.getElementById('handle'); document.getElementById('login-btn').addEventListener('click', () => { onLogin(handleInput.value.trim()); });
attachTypeahead(handleInput, document.getElementById('handle-typeahead'), { onSubmit: v => onLogin(v), });
document.getElementById('logout-btn').addEventListener('click', onLogout);
document.addEventListener('click', e => { if (e.target.id === 'refresh-btn' && onRefresh) onRefresh(); if (e.target.id === 'back-btn' && onBack) onBack(); if (e.target.id === 'forward-btn' && onForward) onForward(); if (e.target.id === 'new-seed-btn' && onForward) onForward(); if (e.target.id === 'undo-btn' && onUndo) onUndo(); if (e.target.id === 'undo-btn-bottom' && onUndo) onUndo(); });
document.addEventListener('keydown', e => { if (e.target.tagName === 'INPUT') return; if (e.key === 'r') { if (onRefresh) onRefresh(); return; } if (e.key === 'b') { if (onBack) onBack(); return; } if (e.key === 'n') { if (onForward) onForward(); return; } if (e.key === 'z') { if (onUndo) onUndo(); return; } const i = KEYS.indexOf(e.key); if (i !== -1) { onKeySelect(i); } });}