Skip to content

Instantly share code, notes, and snippets.

@ephys
Created June 15, 2020 20:53
Show Gist options
  • Save ephys/4789d904b121b92514629df4773f03a1 to your computer and use it in GitHub Desktop.
Save ephys/4789d904b121b92514629df4773f03a1 to your computer and use it in GitHub Desktop.
export function useConversationsPaged(filters?: GetConversationFilters, swrOptions?: SwrOptions): [
// the useSWRPage response
PagedSwrRes<PaginatedResponse<Conversation>>,
// the nodes that can be displayed (merge of paged swr response & update polls)
Conversation[],
] {
// Keys used for individual SWRs
const [updatedNodes, setUpdatedNodes] = React.useState({});
const lastUpdate = React.useRef(new Date());
React.useEffect(() => {
const interval = setInterval(async () => {
const newLastUpdate = new Date();
// poll the endpoint to retrieve the list of conversations that have changed since lastUpdate
const data = await getConversations({ ...filters, updatedAfter: lastUpdate.current });
lastUpdate.current = newLastUpdate;
if (!data.nodes.length) {
return;
}
setUpdatedNodes(oldUpdates => {
const newUpdates = { ...oldUpdates };
for (const node: Conversation of data.nodes) {
newUpdates[node.id] = node;
}
return newUpdates;
});
}, 10000);
return () => clearInterval(interval);
}, [filters]);
const pagedSwr = usePagedQuery({
// eslint-disable-next-line react-hooks/rules-of-hooks
fetchPageHook: offset => useConversations({ ...filters, after: offset }, swrOptions),
key: `conversations`,
});
const pages = pagedSwr.pageSWRs;
const mergedNodes = React.useMemo(() => {
// liveUpdates is the list of elements that have changed since swr first loaded the data
const allConversations = { ...updatedNodes };
for (const page of pages) {
if (!page.data) {
continue;
}
for (const node of page.data.nodes) {
const updatedNode = allConversations[node.id];
// if a newer version of this conversation exist, don't add this one
if (updatedNode && Date.parse(updatedNode.lastMessage) >= Date.parse(node.lastMessage)) {
continue;
}
allConversations[node.id] = node;
}
}
return Object.values(allConversations).sort((a, b) => {
return Date.parse(a.lastMessage) - Date.parse(b.lastMessage);
});
}, [pages, updatedNodes]);
return [pagedSwr, mergedNodes];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment