Something went wrong. Try again.
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283// The (?) window: a thematic floating panel explaining what the app is, what// the status tiers mean, and a live status readout (connection + counts). Single// instance — opening again just brings it forward.
import { makeDraggable } from './drag.js';
let el = null;let timer = null;
const CONN_LABEL = { connecting: 'connecting…', live: 'connected', down: 'reconnecting…' };
// getStatus() -> { handle, conn, online, idle, offline, total }export function openAbout(getStatus) { if (el) { el.style.zIndex = 3000; return; }
el = document.createElement('div'); el.className = 'imwin about'; el.style.left = `${Math.max(8, (window.innerWidth - 320) / 2)}px`; el.style.top = `${Math.max(8, window.innerHeight / 6)}px`; el.style.zIndex = 3000; el.innerHTML = ` <div class="titlebar im-tb"> <span class="tb-title">❓ About Buddy List</span> <span class="tb-btns"><i class="ab-x">×</i></span> </div> <div class="about-body"> <p>An <b>AIM-style buddy list</b> of your Bluesky mutuals. No login — it reads your public follows & followers, then watches the Bluesky firehose (Jetstream) for what they do, in real time. 👂</p>
<p class="ab-h">Status</p> <ul class="ab-legend"> <li><span class="ab-dot on"></span><b>Online</b> — posted, replied or reposted within the window</li> <li><span class="ab-dot idle"></span><b>Idle</b> — only liked (or followed) — lurking</li> <li><span class="ab-dot off"></span><b>Offline</b> — nothing within the window</li> </ul> <p class="ab-note">Set the window with “active within”. A door chime plays when a buddy flips to Online; click a buddy to open an IM log of their recent activity.</p>
<p class="ab-h">Now</p> <div class="ab-status" id="ab-status">—</div>
<p class="ab-foot">a <a href="https://cee.wtf" target="_blank" rel="noopener">cee.wtf</a> thing</p> </div>`; document.body.appendChild(el);
makeDraggable(el, el.querySelector('.im-tb')); el.addEventListener('mousedown', () => { el.style.zIndex = 3000; }, true); el.querySelector('.ab-x').addEventListener('click', closeAbout);
const paint = () => renderStatus(getStatus()); paint(); timer = setInterval(paint, 3000);}
function renderStatus(s) { const box = el?.querySelector('#ab-status'); if (!box) return; if (!s || !s.handle) { box.innerHTML = `<span class="ab-conn down">not signed on</span>`; return; } box.innerHTML = ` <div>signed on as <b>@${escAttr(s.handle)}</b></div> <div>connection: <span class="ab-conn ${s.conn}">${CONN_LABEL[s.conn] || s.conn}</span></div> <div>${s.online} online · ${s.idle} idle · ${s.offline} offline <span class="ab-dim">(of ${s.total})</span></div>`;}
function escAttr(s) { return String(s).replace(/[&<>"]/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"' }[c]));}
export function closeAbout() { if (timer) { clearInterval(timer); timer = null; } el?.remove(); el = null;}