deletable messages
This commit is contained in:
+93
-12
@@ -493,7 +493,7 @@ export default function ChatPage() {
|
|||||||
<Tabs.Tab value="fact-triggers">Fact Triggers</Tabs.Tab>
|
<Tabs.Tab value="fact-triggers">Fact Triggers</Tabs.Tab>
|
||||||
</Tabs.List>
|
</Tabs.List>
|
||||||
<Tabs.Panel value="message">
|
<Tabs.Panel value="message">
|
||||||
<Messages messages={messages || []} />
|
<Messages />
|
||||||
<Textarea
|
<Textarea
|
||||||
resize="vertical"
|
resize="vertical"
|
||||||
placeholder="Type your message here..."
|
placeholder="Type your message here..."
|
||||||
@@ -670,12 +670,92 @@ export default function ChatPage() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Messages({
|
function Messages() {
|
||||||
messages,
|
|
||||||
}: {
|
|
||||||
messages: Array<DraftMessage | CommittedMessage>;
|
|
||||||
}) {
|
|
||||||
const theme = useMantineTheme();
|
const theme = useMantineTheme();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const trpc = useTRPC();
|
||||||
|
const pageContext = usePageContext();
|
||||||
|
const conversationId = pageContext.routeParams.id;
|
||||||
|
|
||||||
|
const messagesResult = useQuery(
|
||||||
|
trpc.chat.messages.fetchByConversationId.queryOptions({
|
||||||
|
conversationId,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
const messages: Array<DraftMessage | CommittedMessage> | undefined =
|
||||||
|
messagesResult.data?.map((m) => ({
|
||||||
|
...m,
|
||||||
|
parts: m.parts.filter((p) => p.type === "text"),
|
||||||
|
})) || [];
|
||||||
|
|
||||||
|
const deleteMessage = useMutation(
|
||||||
|
trpc.chat.messages.deleteOne.mutationOptions({
|
||||||
|
onMutate: async ({ id: messageIdToDelete }) => {
|
||||||
|
/** Cancel affected queries that may be in-flight: */
|
||||||
|
await queryClient.cancelQueries({
|
||||||
|
queryKey: trpc.chat.messages.fetchByConversationId.queryKey({
|
||||||
|
conversationId,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
/** Optimistically update the affected queries in react-query's cache: */
|
||||||
|
const previousMessages = await queryClient.getQueryData(
|
||||||
|
trpc.chat.messages.fetchByConversationId.queryKey({
|
||||||
|
conversationId,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
if (!previousMessages) {
|
||||||
|
return {
|
||||||
|
previousMessages: [],
|
||||||
|
newMessages: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const newMessages = previousMessages.filter(
|
||||||
|
(m: CommittedMessage) => m.id !== messageIdToDelete
|
||||||
|
);
|
||||||
|
queryClient.setQueryData(
|
||||||
|
trpc.chat.messages.fetchByConversationId.queryKey({
|
||||||
|
conversationId,
|
||||||
|
}),
|
||||||
|
newMessages
|
||||||
|
);
|
||||||
|
|
||||||
|
return { previousMessages, newMessages };
|
||||||
|
},
|
||||||
|
onSettled: async (data, variables, context) => {
|
||||||
|
await queryClient.invalidateQueries({
|
||||||
|
queryKey: trpc.chat.messages.fetchByConversationId.queryKey({
|
||||||
|
conversationId,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onError: async (error, variables, context) => {
|
||||||
|
console.error(error);
|
||||||
|
if (!context) return;
|
||||||
|
queryClient.setQueryData(
|
||||||
|
trpc.chat.messages.fetchByConversationId.queryKey({
|
||||||
|
conversationId,
|
||||||
|
}),
|
||||||
|
context.previousMessages
|
||||||
|
);
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
async function handleDeleteMessage(message: DraftMessage | CommittedMessage) {
|
||||||
|
// If the message does not have an id, do nothing
|
||||||
|
if (!("id" in message) || !message.id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the message from the server using the mutation
|
||||||
|
try {
|
||||||
|
await deleteMessage.mutateAsync({ id: message.id });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to delete message:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack gap="md" justify="flex-start">
|
<Stack gap="md" justify="flex-start">
|
||||||
{messages.map((message, index) => (
|
{messages.map((message, index) => (
|
||||||
@@ -708,16 +788,17 @@ function Messages({
|
|||||||
</HoverCard.Target>
|
</HoverCard.Target>
|
||||||
<HoverCard.Dropdown>
|
<HoverCard.Dropdown>
|
||||||
<ActionIcon.Group>
|
<ActionIcon.Group>
|
||||||
<ActionIcon size="lg" variant="filled" color="red">
|
<ActionIcon
|
||||||
<IconTrash
|
size="lg"
|
||||||
size={16}
|
variant="filled"
|
||||||
stroke={1.5}
|
color="red"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// handleDeleteMessage(message.id);
|
handleDeleteMessage(message);
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
|
<IconTrash size={16} stroke={1.5} />
|
||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
</ActionIcon.Group>
|
</ActionIcon.Group>
|
||||||
</HoverCard.Dropdown>
|
</HoverCard.Dropdown>
|
||||||
|
|||||||
@@ -54,6 +54,12 @@ export const messages = router({
|
|||||||
.query(async ({ input: { conversationId } }) => {
|
.query(async ({ input: { conversationId } }) => {
|
||||||
return await db.messages.findByConversationId(conversationId);
|
return await db.messages.findByConversationId(conversationId);
|
||||||
}),
|
}),
|
||||||
|
deleteOne: publicProcedure
|
||||||
|
.input((x) => x as { id: string })
|
||||||
|
.mutation(async ({ input: { id } }) => {
|
||||||
|
await db.messages.delete(id);
|
||||||
|
return { success: true };
|
||||||
|
}),
|
||||||
generateRunningSummary: publicProcedure
|
generateRunningSummary: publicProcedure
|
||||||
.input(
|
.input(
|
||||||
(x) =>
|
(x) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user