.
This commit is contained in:
84
app/components/channel-area.tsx
Normal file
84
app/components/channel-area.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
import { useInfiniteQuery, type QueryFunctionContext } from "@tanstack/react-query"
|
||||
import type { Channel, MessageId } from "~/lib/api/types"
|
||||
import ChatMessage from "./chat-message"
|
||||
import MessageBox from "./message-box"
|
||||
import VisibleTrigger from "./visible-trigger"
|
||||
|
||||
interface ChannelAreaProps {
|
||||
channel: Channel
|
||||
}
|
||||
|
||||
export default function ChannelArea(
|
||||
{ channel }: ChannelAreaProps
|
||||
) {
|
||||
const channelId = channel.id
|
||||
|
||||
const fetchMessages = async ({ pageParam }: QueryFunctionContext) => {
|
||||
return await import("~/lib/api/client/channel").then(m => m.default.paginatedMessages(channelId, 50, pageParam as MessageId | undefined))
|
||||
}
|
||||
|
||||
|
||||
|
||||
const {
|
||||
data,
|
||||
error,
|
||||
fetchNextPage,
|
||||
hasNextPage,
|
||||
isFetching,
|
||||
isFetchingNextPage,
|
||||
isPending,
|
||||
status,
|
||||
} = useInfiniteQuery({
|
||||
queryKey: ["messages", channelId],
|
||||
initialPageParam: undefined,
|
||||
queryFn: fetchMessages,
|
||||
getNextPageParam: (lastPage) => lastPage.length < 50 ? undefined : lastPage[lastPage.length - 1]?.id,
|
||||
staleTime: Infinity,
|
||||
})
|
||||
|
||||
const fetchNextPageVisible = () => {
|
||||
if (!isFetchingNextPage && hasNextPage)
|
||||
fetchNextPage()
|
||||
}
|
||||
|
||||
let messageArea = null
|
||||
|
||||
if (isPending) {
|
||||
messageArea = <div className="flex items-center justify-center size-full">
|
||||
<span>Loading...</span>
|
||||
</div>
|
||||
} else {
|
||||
messageArea = <>
|
||||
<div className="flex-1" />
|
||||
<div className="flex flex-col-reverse overflow-auto gap-2">
|
||||
{
|
||||
status === "success" && data.pages.map((page, i) => (
|
||||
page.map((message) => (
|
||||
<div key={message.id} className="w-full">
|
||||
<ChatMessage message={message} />
|
||||
</div>
|
||||
))
|
||||
)
|
||||
)
|
||||
}
|
||||
<VisibleTrigger triggerOnce={false} onVisible={fetchNextPageVisible} />
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col size-full">
|
||||
<div className="w-full min-h-12 border-b-2 flex items-center justify-center">
|
||||
{channel?.name}
|
||||
</div>
|
||||
<div className="flex-1 overflow-y-auto flex flex-col pl-2 pr-0.5">
|
||||
{messageArea}
|
||||
</div>
|
||||
<div className="w-full max-w-full max-h-1/2">
|
||||
<MessageBox channelId={channelId} />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user