a demonstration replicated social networking web app built with anproto wiredove.net/
social ed25519 protocols

Refresh timestamps on visibility

+43 -2
+43 -2
render.js
··· 11 11 const EDIT_CACHE_TTL_MS = 5000 12 12 13 13 const editState = new Map() 14 + const timestampRefreshMs = 60000 15 + const visibleTimestamps = new Map() 16 + let timestampObserver = null 14 17 15 18 const getEditState = (hash) => { 16 19 if (!editState.has(hash)) { 17 20 editState.set(hash, { currentIndex: null, userNavigated: false }) 18 21 } 19 22 return editState.get(hash) 23 + } 24 + 25 + const refreshTimestamp = async (element, timestamp) => { 26 + if (!document.body.contains(element)) { 27 + const stored = visibleTimestamps.get(element) 28 + if (stored) { clearInterval(stored.intervalId) } 29 + visibleTimestamps.delete(element) 30 + return 31 + } 32 + element.textContent = await apds.human(timestamp) 33 + } 34 + 35 + const observeTimestamp = (element, timestamp) => { 36 + if (!element) { return } 37 + element.dataset.timestamp = timestamp 38 + if (!timestampObserver) { 39 + timestampObserver = new IntersectionObserver((entries) => { 40 + entries.forEach(entry => { 41 + const target = entry.target 42 + const ts = target.dataset.timestamp 43 + if (!ts) { return } 44 + if (entry.isIntersecting) { 45 + refreshTimestamp(target, ts) 46 + if (!visibleTimestamps.has(target)) { 47 + const intervalId = setInterval(() => { 48 + refreshTimestamp(target, ts) 49 + }, timestampRefreshMs) 50 + visibleTimestamps.set(target, { intervalId }) 51 + } 52 + } else { 53 + const stored = visibleTimestamps.get(target) 54 + if (stored) { clearInterval(stored.intervalId) } 55 + visibleTimestamps.delete(target) 56 + } 57 + }) 58 + }) 59 + } 60 + timestampObserver.observe(element) 20 61 } 21 62 22 63 const renderBody = async (body, replyHash) => { ··· 363 404 syncPrevious(yaml) 364 405 365 406 const ts = h('a', {href: '#' + hash}, [humanTime]) 366 - setInterval(async () => {ts.textContent = await apds.human(timestamp)}, 1000) 407 + observeTimestamp(ts, timestamp) 367 408 368 409 const qrTarget = h('div', {id: 'qr-target' + hash, classList: 'qr-target', style: 'margin: 8px auto 0 auto; text-align: center; max-width: 400px;'}) 369 410 const { raw, rawDiv } = buildRawControls(blob, opened, contentBlob) ··· 399 440 } 400 441 401 442 const ts = h('a', {href: '#' + hash}, [humanTime]) 402 - setInterval(async () => {ts.textContent = await apds.human(timestamp)}, 1000) 443 + observeTimestamp(ts, timestamp) 403 444 404 445 const pubkey = await apds.pubkey() 405 446 const canEdit = pubkey && pubkey === author