v0.4.3: Lock contention overhaul, StoragePool, mobile bottom nav, text scaling

Eliminate all conn_mgr lock holds during network I/O across 14 actor commands
and bi-stream handlers. PostFetch, TcpPunch, PullFromPeer, FetchEngagement,
ResolveAddress, AnchorProbe use brief locks for data gathering only. WormLookup,
ContentSearch, WormQuery use connection snapshots for lock-free cascade fan-out.
RelayIntroduce extracts forwarding data under brief lock, does I/O outside.
BlobRequest, PostFetchRequest, ManifestRefresh use Arc clones instead of conn_mgr
lock. ConnectionActor hoists shared Arcs (storage, blob_store, endpoint) for
lock-free access. ResolveAddress adds 5s per-query timeout (was unbounded).

Initial exchange failure now aborts mesh upgrade (was silently continuing with
broken connection). connect_to_peer/connect_to_anchor use consistent 15s timeout.
Rebalance connects outside the lock via pending_connects pattern.

StoragePool: 8 concurrent SQLite connections in WAL mode replace single
Mutex<Storage>. Reads run fully parallel; writes serialize at SQLite level only.
PRAGMA busy_timeout=5000 for graceful write contention.

Mobile bottom nav bar (<=768px) with icon tabs. Text sizes: XS/S/M/L/XL
(75%/100%/125%/150%/200%), default M. localStorage persistence for instant
restore. Toast repositioned above mobile nav.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Scott Reimers 2026-03-22 21:35:38 -04:00
parent f17535d61d
commit 43adbbdf7d
15 changed files with 1546 additions and 618 deletions

View file

@ -3007,22 +3007,20 @@ $('#circle-profiles-toggle').addEventListener('click', () => {
// --- Notifications popover ---
// Text size toggle
const TEXT_SIZE_SCALES = { small: '100%', normal: '150%', large: '200%' };
// Apply text size immediately (default Normal = 150%)
document.documentElement.style.fontSize = '150%';
(async () => {
const saved = await invoke('get_setting', { key: 'text_size' }).catch(() => null) || 'normal';
document.documentElement.style.fontSize = TEXT_SIZE_SCALES[saved] || '150%';
document.querySelectorAll('.text-size-opt').forEach(b => {
b.classList.toggle('active', b.dataset.size === saved);
});
})();
const TEXT_SIZE_SCALES = { xsmall: '75%', small: '100%', normal: '125%', large: '150%', xlarge: '200%' };
// Apply text size immediately from localStorage cache (no async wait)
const _cachedTextSize = localStorage.getItem('text_size') || 'normal';
document.documentElement.style.fontSize = TEXT_SIZE_SCALES[_cachedTextSize] || '125%';
document.querySelectorAll('.text-size-opt').forEach(b => {
b.classList.toggle('active', b.dataset.size === _cachedTextSize);
});
document.querySelectorAll('.text-size-opt').forEach(btn => {
btn.addEventListener('click', async () => {
const size = btn.dataset.size;
document.documentElement.style.fontSize = TEXT_SIZE_SCALES[size] || '';
document.querySelectorAll('.text-size-opt').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
localStorage.setItem('text_size', size);
await invoke('set_setting', { key: 'text_size', value: size }).catch(() => {});
toast('Text size updated');
});