Move the onVisibilityChange API check to app.jsx

Doesn't make sense to make it part of Home. Also add in Notifications check.
This commit is contained in:
Lim Chee Aun 2022-12-24 10:26:05 +08:00
parent 71514312bf
commit 42fa30d8f8
2 changed files with 94 additions and 51 deletions

View file

@ -103,6 +103,99 @@ async function startStream() {
};
}
function startVisibility() {
const handleVisibilityChange = () => {
if (document.hidden) {
const timestamp = Date.now();
store.session.set('lastHidden', timestamp);
} else {
const timestamp = Date.now();
const lastHidden = store.session.get('lastHidden');
const diff = timestamp - lastHidden;
const diffMins = Math.round(diff / 1000 / 60);
if (diffMins > 1) {
console.log('visible', { lastHidden, diffMins });
setTimeout(() => {
// Buffer for WS reconnect
(async () => {
try {
const fetchHome = masto.timelines.fetchHome({
limit: 2,
// Need 2 because "new posts" only appear when there are 2 or more
});
const fetchNotifications = masto.notifications
.iterate({
limit: 1,
})
.next();
const newStatuses = await fetchHome;
if (
newStatuses.value.length &&
newStatuses.value[0].id !== states.home[0].id
) {
states.homeNew = newStatuses.value.map((status) => {
states.statuses.set(status.id, status);
if (status.reblog) {
states.statuses.set(status.reblog.id, status.reblog);
}
return {
id: status.id,
reblog: status.reblog?.id,
reply: !!status.inReplyToAccountId,
};
});
}
const newNotifications = await fetchNotifications;
if (newNotifications.value.length) {
const notification = newNotifications.value[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);
}
if (
notification.status &&
!states.statuses.has(notification.status.id)
) {
states.statuses.set(
notification.status.id,
notification.status,
);
if (
notification.status.reblog &&
!states.statuses.has(notification.status.reblog.id)
) {
states.statuses.set(
notification.status.reblog.id,
notification.status.reblog,
);
}
}
}
} catch (e) {
// Silently fail
console.error(e);
}
})();
}, 100);
}
}
};
document.addEventListener('visibilitychange', handleVisibilityChange);
return {
stop: () => {
document.removeEventListener('visibilitychange', handleVisibilityChange);
},
};
}
export function App() {
const snapStates = useSnapshot(states);
const [isLoggedIn, setIsLoggedIn] = useState(false);
@ -210,6 +303,7 @@ export function App() {
if (isLoggedIn) {
requestAnimationFrame(() => {
startStream();
startVisibility();
// Collect instance info
(async () => {

View file

@ -7,7 +7,6 @@ import Icon from '../components/icon';
import Loader from '../components/loader';
import Status from '../components/status';
import states from '../utils/states';
import store from '../utils/store';
const LIMIT = 20;
@ -70,56 +69,6 @@ function Home({ hidden }) {
loadStatuses(true);
}, []);
useEffect(() => {
const handleVisibilityChange = () => {
if (document.hidden) {
const timestamp = Date.now();
store.session.set('lastHidden', timestamp);
} else {
const timestamp = Date.now();
const lastHidden = store.session.get('lastHidden');
const diff = timestamp - lastHidden;
const diffMins = Math.round(diff / 1000 / 60);
if (diffMins > 1) {
console.log('visible', { lastHidden, diffMins });
setUIState('loading');
setTimeout(() => {
(async () => {
const newStatuses = await masto.timelines.fetchHome({
limit: 2,
// Need 2 because "new posts" only appear when there are 2 or more
});
if (
newStatuses.value.length &&
newStatuses.value[0].id !== states.home[0].id
) {
states.homeNew = newStatuses.value.map((status) => {
states.statuses.set(status.id, status);
if (status.reblog) {
states.statuses.set(status.reblog.id, status.reblog);
}
return {
id: status.id,
reblog: status.reblog?.id,
reply: !!status.inReplyToAccountId,
};
});
}
setUIState('default');
})();
// loadStatuses(true);
// states.homeNew = [];
}, 100);
}
}
};
document.addEventListener('visibilitychange', handleVisibilityChange);
return () => {
document.removeEventListener('visibilitychange', handleVisibilityChange);
setUIState('default');
};
}, []);
const scrollableRef = useRef();
return (