phanpy/src/pages/following.jsx

139 lines
4 KiB
React
Raw Normal View History

2023-02-07 17:31:46 +01:00
import { useEffect, useRef } from 'preact/hooks';
2023-02-03 14:08:08 +01:00
import { useSnapshot } from 'valtio';
import Timeline from '../components/timeline';
import { api } from '../utils/api';
2023-03-21 17:09:36 +01:00
import { filteredItems } from '../utils/filters';
2023-02-05 18:10:49 +01:00
import states from '../utils/states';
2023-02-07 17:31:46 +01:00
import { getStatus, saveStatus } from '../utils/states';
2023-12-14 18:58:29 +01:00
import {
assignFollowedTags,
clearFollowedTagsState,
dedupeBoosts,
} from '../utils/timeline-utils';
2023-02-03 14:08:08 +01:00
import useTitle from '../utils/useTitle';
const LIMIT = 20;
function Following({ title, path, id, ...props }) {
useTitle(title || 'Following', path || '/following');
const { masto, streaming, instance } = api();
2023-02-03 14:08:08 +01:00
const snapStates = useSnapshot(states);
const homeIterator = useRef();
2023-02-07 17:31:46 +01:00
const latestItem = useRef();
console.debug('RENDER Following', title, id);
2023-02-03 14:08:08 +01:00
async function fetchHome(firstLoad) {
if (firstLoad || !homeIterator.current) {
homeIterator.current = masto.v1.timelines.home.list({ limit: LIMIT });
2023-02-03 14:08:08 +01:00
}
const results = await homeIterator.current.next();
2023-03-21 17:09:36 +01:00
let { value } = results;
if (value?.length) {
let latestItemChanged = false;
2023-02-07 17:31:46 +01:00
if (firstLoad) {
if (value[0].id !== latestItem.current) {
latestItemChanged = true;
}
2023-02-07 17:31:46 +01:00
latestItem.current = value[0].id;
2023-03-21 17:09:36 +01:00
console.log('First load', latestItem.current);
2023-02-07 17:31:46 +01:00
}
// value = filteredItems(value, 'home');
value.forEach((item) => {
saveStatus(item, instance);
});
value = dedupeBoosts(value, instance);
if (firstLoad && latestItemChanged) clearFollowedTagsState();
2023-12-14 18:58:29 +01:00
assignFollowedTags(value, instance);
// ENFORCE sort by datetime (Latest first)
value.sort((a, b) => {
const aDate = new Date(a.createdAt);
const bDate = new Date(b.createdAt);
return bDate - aDate;
});
}
2023-05-14 15:13:36 +02:00
return {
...results,
value,
};
2023-02-03 14:08:08 +01:00
}
2023-02-07 17:31:46 +01:00
async function checkForUpdates() {
try {
const results = await masto.v1.timelines.home
.list({
2023-02-07 17:31:46 +01:00
limit: 5,
since_id: latestItem.current,
})
.next();
2023-03-21 17:09:36 +01:00
let { value } = results;
2023-02-09 15:27:49 +01:00
console.log('checkForUpdates', latestItem.current, value);
2024-04-09 17:35:17 +02:00
const valueContainsLatestItem = value[0]?.id === latestItem.current; // since_id might not be supported
if (value?.length && !valueContainsLatestItem) {
2023-03-25 13:18:53 +01:00
latestItem.current = value[0].id;
value = dedupeBoosts(value, instance);
2023-03-25 13:18:53 +01:00
value = filteredItems(value, 'home');
if (value.some((item) => !item.reblog)) {
return true;
}
2023-02-07 17:31:46 +01:00
}
return false;
} catch (e) {
return false;
}
}
useEffect(() => {
let sub;
2023-02-08 12:11:33 +01:00
(async () => {
if (streaming) {
sub = streaming.user.subscribe();
console.log('🎏 Streaming user', sub);
for await (const entry of sub) {
if (!sub) break;
if (entry.event === 'status.update') {
const status = entry.payload;
console.log(`🔄 Status ${status.id} updated`);
saveStatus(status, instance);
} else if (entry.event === 'delete') {
const statusID = entry.payload;
console.log(`❌ Status ${statusID} deleted`);
// delete states.statuses[statusID];
const s = getStatus(statusID, instance);
if (s) s._deleted = true;
}
}
2023-12-12 01:34:06 +01:00
console.log('💥 Streaming user loop STOPPED');
}
2023-02-08 12:11:33 +01:00
})();
2023-02-07 17:31:46 +01:00
return () => {
sub?.unsubscribe?.();
sub = null;
2023-02-07 17:31:46 +01:00
};
}, [streaming]);
2023-02-07 17:31:46 +01:00
2023-02-03 14:08:08 +01:00
return (
<Timeline
2023-02-09 15:27:49 +01:00
title={title || 'Following'}
id={id || 'following'}
2023-02-03 14:08:08 +01:00
emptyText="Nothing to see here."
errorText="Unable to load posts."
2023-02-18 17:05:46 +01:00
instance={instance}
2023-02-03 14:08:08 +01:00
fetchItems={fetchHome}
2023-02-07 17:31:46 +01:00
checkForUpdates={checkForUpdates}
useItemID
2023-02-03 14:08:08 +01:00
boostsCarousel={snapStates.settings.boostsCarousel}
{...props}
// allowFilters
filterContext="home"
2023-12-14 18:58:29 +01:00
showFollowedTags
2024-01-30 07:34:54 +01:00
showReplyParent
2023-02-03 14:08:08 +01:00
/>
);
}
export default Following;