paginated unified messages
unknown
typescript
a month ago
5.0 kB
2
Indexable
Never
import { useState, useEffect, useCallback, useMemo } from "react" import { SubChannel } from "@/convex/tlc/types" import { InboxMessage } from "@/convex/types" import { useWorkspacePaginatedQuery } from "@/hooks/usingWorkspace" import { api } from "@/convex/_generated/api" import { InboxTLCMap } from "@/convex/tlc/clientHandler" type ChannelStatus = | "LoadingFirstPage" | "CanLoadMore" | "LoadingMore" | "Exhausted" type ChannelData = { results: InboxMessage[] isLoading: boolean status: ChannelStatus loadMore: (numItems: number) => void } function useChannelMessages( inboxTLCMap: InboxTLCMap | undefined, type: SubChannel ): ChannelData { const { results, isLoading, status, loadMore } = useWorkspacePaginatedQuery( api.tlc.clientHandler.paginateInboxMessagesByInboxTLCMap, { inboxTLCMap }, { initialNumItems: 5 } ) return { results, isLoading, status, loadMore } } export function useUnifiedMessages(inboxTLCMaps: InboxTLCMap[]) { const emailMessages = useChannelMessages( inboxTLCMaps.find( (tlcMap) => tlcMap.tlcMap.type === SubChannel.EMAIL ), SubChannel.EMAIL ) const smsMessages = useChannelMessages( inboxTLCMaps.find( (tlcMap) => tlcMap.tlcMap.type === SubChannel.SMS ), SubChannel.SMS ) const whatsappMessages = useChannelMessages( inboxTLCMaps.find( (tlcMap) => tlcMap.tlcMap.type === SubChannel.WHATSAPP ), SubChannel.WHATSAPP ) const pmsMessages = useChannelMessages( inboxTLCMaps.find( (tlcMap) => tlcMap.tlcMap.type === SubChannel.PMS ), SubChannel.PMS ) const airbnbMessages = useChannelMessages( inboxTLCMaps.find( (tlcMap) => tlcMap.tlcMap.type === SubChannel.AIRBNB ), SubChannel.AIRBNB ) const channelData = useMemo( () => ({ email: emailMessages, sms: smsMessages, whatsapp: whatsappMessages, pms: pmsMessages, airbnb: airbnbMessages, }), [ emailMessages, smsMessages, whatsappMessages, pmsMessages, airbnbMessages, ] ) const [unifiedMessages, setUnifiedMessages] = useState< InboxMessage[] >([]) const [isLoading, setIsLoading] = useState(true) useEffect(() => { const allMessages = Object.values(channelData).flatMap( (channel) => channel.results ) const sortedMessages = allMessages.sort( (a, b) => a.timestamp - b.timestamp ) setUnifiedMessages(sortedMessages) setIsLoading( Object.values(channelData).some( (channel) => channel.isLoading ) ) console.log("paginated unifiedMessages", unifiedMessages) }, [channelData]) const loadMore = useCallback( (numItems: number = 10) => { const oldestTimestamp = unifiedMessages[0]?.timestamp ?? Infinity const channelToLoad = Object.entries(channelData).reduce( (acc, [key, channel]) => { const oldestChannelMessage = channel.results[0] if ( oldestChannelMessage && oldestChannelMessage.timestamp < acc.timestamp && channel.status === "CanLoadMore" ) { return { key, timestamp: oldestChannelMessage.timestamp, } } return acc }, { key: "", timestamp: Infinity } as { key: string timestamp: number } ) if (channelToLoad.key) { channelData[ channelToLoad.key as keyof typeof channelData ].loadMore(numItems) } }, [unifiedMessages, channelData] ) const overallStatus: ChannelStatus = useMemo(() => { if ( Object.values(channelData).some( (channel) => channel.status === "LoadingFirstPage" ) ) { return "LoadingFirstPage" } if ( Object.values(channelData).some( (channel) => channel.status === "LoadingMore" ) ) { return "LoadingMore" } if ( Object.values(channelData).some( (channel) => channel.status === "CanLoadMore" ) ) { return "CanLoadMore" } return "Exhausted" }, [channelData]) return { messages: unifiedMessages, isLoading, loadMore, status: overallStatus, } }
Leave a Comment