diff --git a/src/app.jsx b/src/app.jsx index 8dd1c783..1e93235e 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -165,7 +165,7 @@ function App() { if (isLoggedIn) { requestAnimationFrame(() => { - startStream(); + // startStream(); startVisibility(); // Collect instance info @@ -342,20 +342,35 @@ function App() { ); } +let ws; async function startStream() { + if ( + ws && + (ws.readyState === WebSocket.CONNECTING || ws.readyState === WebSocket.OPEN) + ) { + return; + } + const stream = await masto.v1.stream.streamUser(); console.log('STREAM START', { stream }); + ws = stream.ws; + const handleNewStatus = debounce((status) => { console.log('UPDATE', status); const inHomeNew = states.homeNew.find((s) => s.id === status.id); - const inHome = states.home.find((s) => s.id === status.id); + const inHome = status.id === states.homeLast?.id; if (!inHomeNew && !inHome) { - states.homeNew.unshift({ - id: status.id, - reblog: status.reblog?.id, - reply: !!status.inReplyToAccountId, - }); + if (states.settings.boostsCarousel && status.reblog) { + // do nothing + } else { + states.homeNew.unshift({ + id: status.id, + reblog: status.reblog?.id, + reply: !!status.inReplyToAccountId, + }); + console.log('homeNew 1', [...states.homeNew]); + } } saveStatus(status); @@ -377,9 +392,7 @@ async function startStream() { const inNotificationsNew = states.notificationsNew.find( (n) => n.id === notification.id, ); - const inNotifications = states.notifications.find( - (n) => n.id === notification.id, - ); + const inNotifications = notification.id === states.notificationLast?.id; if (!inNotificationsNew && !inNotifications) { states.notificationsNew.unshift(notification); } @@ -389,10 +402,9 @@ async function startStream() { stream.ws.onclose = () => { console.log('STREAM CLOSED!'); - - requestAnimationFrame(() => { + if (document.visibilityState !== 'hidden') { startStream(); - }); + } }; return { @@ -404,8 +416,8 @@ async function startStream() { } function startVisibility() { - const handleVisibilityChange = () => { - if (document.visibilityState === 'hidden') { + const handleVisible = (visible) => { + if (!visible) { const timestamp = Date.now(); store.session.set('lastHidden', timestamp); } else { @@ -415,26 +427,26 @@ function startVisibility() { const diffMins = Math.round(diff / 1000 / 60); if (diffMins > 1) { console.log('visible', { lastHidden, diffMins }); - setTimeout(() => { - // Buffer for WS reconnect - (async () => { - try { - const firstStatusID = states.home[0]?.id; - const firstNotificationID = states.notifications[0]?.id; - const fetchHome = masto.v1.timelines.listHome({ - limit: 1, - ...(firstStatusID && { sinceId: firstStatusID }), - }); - const fetchNotifications = masto.v1.notifications.list({ - limit: 1, - ...(firstNotificationID && { sinceId: firstNotificationID }), - }); + (async () => { + try { + const firstStatusID = states.home[0]?.id; + const firstNotificationID = states.notifications[0]?.id; + const fetchHome = masto.v1.timelines.listHome({ + limit: 1, + ...(firstStatusID && { sinceId: firstStatusID }), + }); + const fetchNotifications = masto.v1.notifications.list({ + limit: 1, + ...(firstNotificationID && { sinceId: firstNotificationID }), + }); - const newStatuses = await fetchHome; - if ( - newStatuses.length && - newStatuses[0].id !== states.home[0].id - ) { + const newStatuses = await fetchHome; + const newStatus = newStatuses?.[0]; + const inHome = newStatus?.id !== states.homeLast?.id; + if (newStatuses.length && !inHome) { + if (states.settings.boostsCarousel && newStatus.reblog) { + // do nothing + } else { states.homeNew = newStatuses.map((status) => { saveStatus(status); return { @@ -443,32 +455,40 @@ function startVisibility() { reply: !!status.inReplyToAccountId, }; }); + console.log('homeNew 2', [...states.homeNew]); } - - const newNotifications = await fetchNotifications; - if (newNotifications.length) { - const notification = newNotifications[0]; - const inNotificationsNew = states.notificationsNew.find( - (n) => n.id === notification.id, - ); - const inNotifications = states.notifications.find( - (n) => n.id === notification.id, - ); - if (!inNotificationsNew && !inNotifications) { - states.notificationsNew.unshift(notification); - } - - saveStatus(notification.status, { override: false }); - } - } catch (e) { - // Silently fail - console.error(e); } - })(); - }, 100); + + const newNotifications = await fetchNotifications; + if (newNotifications.length) { + const notification = newNotifications[0]; + const inNotificationsNew = states.notificationsNew.find( + (n) => n.id === notification.id, + ); + const inNotifications = + notification.id === states.notificationLast?.id; + if (!inNotificationsNew && !inNotifications) { + states.notificationsNew.unshift(notification); + } + + saveStatus(notification.status, { override: false }); + } + } catch (e) { + // Silently fail + console.error(e); + } finally { + startStream(); + } + })(); } } }; + + const handleVisibilityChange = () => { + const hidden = document.visibilityState === 'hidden'; + handleVisible(!hidden); + console.log('VISIBILITY: ' + (hidden ? 'hidden' : 'visible')); + }; document.addEventListener('visibilitychange', handleVisibilityChange); return { stop: () => { diff --git a/src/pages/home.jsx b/src/pages/home.jsx index 5fec0550..71060aa0 100644 --- a/src/pages/home.jsx +++ b/src/pages/home.jsx @@ -22,11 +22,7 @@ function Home({ hidden }) { console.debug('RENDER Home'); - const homeIterator = useRef( - masto.v1.timelines.listHome({ - limit: LIMIT, - }), - ); + const homeIterator = useRef(); async function fetchStatuses(firstLoad) { if (firstLoad) { // Reset iterator @@ -94,12 +90,14 @@ function Home({ hidden }) { specialHome, }); if (firstLoad) { + states.homeLast = specialHome[0]; states.home = specialHome; } else { states.home.push(...specialHome); } } else { if (firstLoad) { + states.homeLast = homeValues[0]; states.home = homeValues; } else { states.home.push(...homeValues); @@ -272,6 +270,13 @@ function Home({ hidden }) { })(); }, []); + // const showUpdatesButton = snapStates.homeNew.length > 0 && reachStart; + const [showUpdatesButton, setShowUpdatesButton] = useState(false); + useEffect(() => { + const isNewAndTop = snapStates.homeNew.length > 0 && reachStart; + setShowUpdatesButton(isNewAndTop); + }, [snapStates.homeNew.length]); + return ( <>