paginated unified messages
unknown
typescript
a year ago
5.0 kB
22
Indexable
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,
}
}
Editor is loading...
Leave a Comment