Welcome screen: add Ready button with loading bar for instant feed access

Progress bar animates during backend readiness check. Once local feed is
loaded from SQLite, button enables with teal highlight. Click switches to
feed tab with cached content — no network wait needed for returning users.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Scott Reimers 2026-04-05 16:41:50 -04:00
parent 9be6a0e40b
commit e354ccc388
2 changed files with 37 additions and 2 deletions

View file

@ -3570,10 +3570,29 @@ async function init() {
} }
}, 2000); }, 2000);
// Ready button — click to go to feed
const readyBtn = document.getElementById('welcome-ready-btn');
const readyBar = document.getElementById('welcome-ready-bar');
if (readyBtn) {
readyBtn.addEventListener('click', () => {
if (readyBtn.disabled) return;
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
document.querySelectorAll('.view').forEach(v => v.classList.remove('active'));
const feedTab = document.querySelector('.tab[data-tab="feed"]');
if (feedTab) feedTab.classList.add('active');
document.getElementById('view-feed').classList.add('active');
currentTab = 'feed';
_lastFeedViewMs = Date.now();
updateTabBadge('feed', 0);
});
}
// Wait for backend in the background, then load node info // Wait for backend in the background, then load node info
(async () => { (async () => {
for (let attempt = 0; attempt < 30; attempt++) { for (let attempt = 0; attempt < 30; attempt++) {
try { try {
// Animate progress bar toward 90% during readiness checks
if (readyBar) readyBar.style.width = Math.min(90, (attempt + 1) * 3) + '%';
await invoke('get_node_info'); await invoke('get_node_info');
break; break;
} catch (e) { } catch (e) {
@ -3586,9 +3605,19 @@ async function init() {
setupOverlay.classList.remove('hidden'); setupOverlay.classList.remove('hidden');
setupName.focus(); setupName.focus();
} }
// Reload feed now that backend is ready // Pre-load feed + messages from local DB (instant — no network needed)
loadFeed(true).catch(() => {}); await loadFeed(true).catch(() => {});
loadMessages(true).catch(() => {}); loadMessages(true).catch(() => {});
// Mark ready button as clickable
if (readyBar) readyBar.style.width = '100%';
if (readyBtn) {
readyBtn.disabled = false;
readyBtn.textContent = 'Ready — Go to Feed';
readyBtn.style.opacity = '1';
readyBtn.style.color = '#7fdbca';
readyBtn.style.borderColor = '#7fdbca';
readyBtn.style.cursor = 'pointer';
}
})(); })();
// Mark notif ready after first welcome fetch succeeds (skip first 2 ticks to avoid spam) // Mark notif ready after first welcome fetch succeeds (skip first 2 ticks to avoid spam)

View file

@ -49,6 +49,12 @@
<div><span id="welcome-reacts" style="font-size:1.4rem;font-weight:700;color:#5b8def;display:block">-</span>Reacts</div> <div><span id="welcome-reacts" style="font-size:1.4rem;font-weight:700;color:#5b8def;display:block">-</span>Reacts</div>
<div><span id="welcome-comments" style="font-size:1.4rem;font-weight:700;color:#5b8def;display:block">-</span>Comments</div> <div><span id="welcome-comments" style="font-size:1.4rem;font-weight:700;color:#5b8def;display:block">-</span>Comments</div>
</div> </div>
<div style="margin-top:2rem;max-width:280px;margin-left:auto;margin-right:auto">
<div style="background:#1a1a2e;border-radius:6px;height:6px;overflow:hidden;margin-bottom:0.75rem">
<div id="welcome-ready-bar" style="height:100%;background:#7fdbca;width:0%;transition:width 0.5s ease;border-radius:6px"></div>
</div>
<button id="welcome-ready-btn" disabled style="width:100%;padding:0.75rem 1.5rem;border:1px solid #333;border-radius:8px;background:#1a1a2e;color:#666;font-size:0.95rem;cursor:not-allowed;opacity:0.5;transition:all 0.3s ease">Loading...</button>
</div>
</div> </div>
</section> </section>