Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 0 additions & 29 deletions app/api/agents/route.ts

This file was deleted.

18 changes: 6 additions & 12 deletions components/Sidebar/Modals/DeleteConfirmationModal.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
import { useState, useEffect } from "react";
import Modal from "@/components/Modal";
import type { Conversation } from "@/types/Chat";
import type { ArtistAgent } from "@/lib/supabase/getArtistAgents";
import { useDeleteChat } from "@/hooks/useDeleteChat";

interface DeleteConfirmationModalProps {
isOpen: boolean;
onClose: () => void;
chatRoom: Conversation | ArtistAgent | null;
chatRooms?: Array<Conversation | ArtistAgent>;
chatRoom: Conversation | null;
chatRooms?: Conversation[];
onDelete: () => void;
}

// Helper functions for type handling and data extraction
const isChatRoom = (item: Conversation | ArtistAgent): item is Conversation => 'id' in item;
const getChatName = (item: Conversation | ArtistAgent): string => isChatRoom(item) ? item.topic : item.type;
const getChatId = (item: Conversation | ArtistAgent): string => isChatRoom(item) ? item.id : item.agentId;

const DeleteConfirmationModal = ({ isOpen, onClose, chatRoom, chatRooms, onDelete }: DeleteConfirmationModalProps) => {
const [error, setError] = useState("");
const [deletingProgress, setDeletingProgress] = useState<{ current: number; total: number } | null>(null);
Expand All @@ -41,7 +35,7 @@ const DeleteConfirmationModal = ({ isOpen, onClose, chatRoom, chatRooms, onDelet

const chatCount = chatsToDelete.length;
const isSingleDelete = chatCount === 1;
const chatName = isSingleDelete ? getChatName(chatsToDelete[0]) : `${chatCount} chats`;
const chatName = isSingleDelete ? (chatsToDelete[0].topic || "Chat") : `${chatCount} chats`;
const buttonText = isDeleting
? (deletingProgress ? `Deleting ${deletingProgress.current}/${deletingProgress.total}...` : 'Deleting...')
: 'Delete';
Expand All @@ -58,10 +52,10 @@ const DeleteConfirmationModal = ({ isOpen, onClose, chatRoom, chatRooms, onDelet
setDeletingProgress({ current: i + 1, total: chatCount });

try {
await deleteChat(getChatId(chat));
await deleteChat(chat.id);
} catch (chatError) {
console.error(`Error deleting chat ${getChatName(chat)}:`, chatError);
failedChats.push(getChatName(chat));
console.error(`Error deleting chat ${chat.topic || "Chat"}:`, chatError);
failedChats.push(chat.topic || "Chat");
}
}

Expand Down
3 changes: 1 addition & 2 deletions components/Sidebar/Modals/RenameModal.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import Modal from "@/components/Modal";
import type { Conversation } from "@/types/Chat";
import type { ArtistAgent } from "@/lib/supabase/getArtistAgents";
import { useRenameModal } from "@/hooks/useRenameModal";

interface RenameModalProps {
isOpen: boolean;
onClose: () => void;
chatRoom: Conversation | ArtistAgent | null;
chatRoom: Conversation | null;
}

const RenameModal = ({
Expand Down
8 changes: 3 additions & 5 deletions components/Sidebar/RecentChats/ChatItem.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { useState, useEffect, type RefObject, type MouseEvent } from "react";
import { MoreHorizontal, Pencil, Trash2, Check } from "lucide-react";
import type { Conversation } from "@/types/Chat";
import type { ArtistAgent } from "@/lib/supabase/getArtistAgents";
import { cn } from "@/lib/utils";
import useCreateChat from "@/hooks/useCreateChat";
import { getChatDisplayInfo } from "@/lib/chat/getChatDisplayInfo";

type ChatItemProps = {
chatRoom: Conversation | ArtistAgent;
chatRoom: Conversation;
isMobile: boolean;
isHovered: boolean;
isMenuOpen: boolean;
Expand Down Expand Up @@ -54,9 +53,8 @@ const ChatItem = ({

const showOptions = isMobile || isHovered || isActive;
const isOptimisticChatItem =
"id" in chatRoom &&
Array.isArray((chatRoom as Conversation).memories) &&
(chatRoom as Conversation).memories.some((memory) => {
Array.isArray(chatRoom.memories) &&
chatRoom.memories.some((memory) => {
const content = memory?.content as unknown;
if (!content || typeof content !== "object") {
return false;
Expand Down
10 changes: 3 additions & 7 deletions components/Sidebar/RecentChats/RecentChatList.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { AnimatePresence, motion } from "framer-motion";
import type { Conversation } from "@/types/Chat";
import type { ArtistAgent } from "@/lib/supabase/getArtistAgents";
import ChatItem from "./ChatItem";
import type { MutableRefObject } from "react";
import { getChatRoomId } from "@/lib/chat/getChatRoomId";

interface RecentChatListProps {
conversations: Array<Conversation | ArtistAgent>;
conversations: Conversation[];
isMobile: boolean;
hoveredChatId: string | null;
openMenuId: string | null;
Expand All @@ -17,13 +16,10 @@ interface RecentChatListProps {
menuRef: MutableRefObject<HTMLDivElement | null>;
buttonRefs: MutableRefObject<Record<string, HTMLButtonElement | null>>;
setHoveredChatId: (chatId: string | null) => void;
handleChatClick: (chatRoom: Conversation | ArtistAgent) => void;
handleChatClick: (chatRoom: Conversation) => void;
handleChatSelection: (chatId: string, isShiftKey: boolean) => void;
toggleMenu: (roomId: string) => void;
openModal: (
type: "rename" | "delete",
chatRoom: Conversation | ArtistAgent
) => void;
openModal: (type: "rename" | "delete", chatRoom: Conversation) => void;
}

const RecentChatList = ({
Expand Down
19 changes: 6 additions & 13 deletions components/Sidebar/RecentChats/useRecentChats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { useConversationsProvider } from "@/providers/ConversationsProvider";
import { useMobileDetection } from "@/hooks/useMobileDetection";
import { useOutsideClick } from "@/hooks/useOutsideClick";
import type { Conversation } from "@/types/Chat";
import type { ArtistAgent } from "@/lib/supabase/getArtistAgents";
import { getChatRoomId } from "@/lib/chat/getChatRoomId";

interface UseRecentChatsParams {
Expand All @@ -22,11 +21,7 @@ export const useRecentChats = ({ toggleModal }: UseRecentChatsParams) => {
const [hoveredChatId, setHoveredChatId] = useState<string | null>(null);
const [openMenuId, setOpenMenuId] = useState<string | null>(null);
const [activeChatId, setActiveChatId] = useState<string | null>(
typeof params?.roomId === "string"
? params.roomId
: typeof params?.agentId === "string"
? params.agentId
: null
typeof params?.roomId === "string" ? params.roomId : null
);

useEffect(() => {
Expand All @@ -39,18 +34,16 @@ export const useRecentChats = ({ toggleModal }: UseRecentChatsParams) => {
}

const roomId = typeof params?.roomId === "string" ? params.roomId : null;
const agentId =
typeof params?.agentId === "string" ? params.agentId : null;
setActiveChatId(roomId || agentId || null);
setActiveChatId(roomId || null);
};

updateActiveChatId();
}, [params, conversations]);

const [modalState, setModalState] = useState<{
type: "rename" | "delete" | null;
chatRoom: Conversation | ArtistAgent | null;
chatRooms?: Array<Conversation | ArtistAgent>;
chatRoom: Conversation | null;
chatRooms?: Conversation[];
}>({ type: null, chatRoom: null });

const [selectedChatIds, setSelectedChatIds] = useState<Set<string>>(
Expand Down Expand Up @@ -93,7 +86,7 @@ export const useRecentChats = ({ toggleModal }: UseRecentChatsParams) => {

const openModal = (
type: "rename" | "delete",
chatRoom: Conversation | ArtistAgent
chatRoom: Conversation
) => {
setModalState({ type, chatRoom });
setOpenMenuId(null);
Expand Down Expand Up @@ -164,7 +157,7 @@ export const useRecentChats = ({ toggleModal }: UseRecentChatsParams) => {

const clearSelection = () => setSelectedChatIds(new Set());

const handleChatClick = (chatRoom: Conversation | ArtistAgent) => {
const handleChatClick = (chatRoom: Conversation) => {
handleClick(chatRoom, toggleModal);
};

Expand Down
31 changes: 0 additions & 31 deletions hooks/useArtistAgents.ts

This file was deleted.

23 changes: 6 additions & 17 deletions hooks/useConversations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@ import { useUserProvider } from "@/providers/UserProvder";
import { useArtistProvider } from "@/providers/ArtistProvider";
import getConversations from "@/lib/getConversations";
import { Conversation } from "@/types/Chat";
import useArtistAgents from "./useArtistAgents";
import { ArtistAgent } from "@/lib/supabase/getArtistAgents";
import { usePrivy } from "@privy-io/react-auth";

const useConversations = () => {
const { userData } = useUserProvider();
const { selectedArtist, artists } = useArtistProvider();
const { agents } = useArtistAgents();
const queryClient = useQueryClient();
const { getAccessToken, authenticated } = usePrivy();

Expand All @@ -38,32 +35,24 @@ const useConversations = () => {
initialData: [],
});

const combinedConversations = useMemo<
Array<Conversation | ArtistAgent>
>(() => {
return [...fetchedConversations, ...agents];
}, [fetchedConversations, agents]);

const conversations = useMemo(() => {
// If artist selected, filter to only that artist's conversations
if (selectedArtist) {
return combinedConversations.filter(
(item: Conversation | ArtistAgent) =>
"artist_id" in item && item.artist_id === selectedArtist.account_id,
return fetchedConversations.filter(
(item) => item.artist_id === selectedArtist.account_id,
);
}

// No artist selected - filter to artists in the current org view
if (orgArtistIds.size > 0) {
return combinedConversations.filter(
(item: Conversation | ArtistAgent) =>
"artist_id" in item && orgArtistIds.has(item.artist_id),
return fetchedConversations.filter((item) =>
orgArtistIds.has(item.artist_id),
);
}

// Fallback: no artists in org (shouldn't happen normally)
return combinedConversations;
}, [selectedArtist, combinedConversations, orgArtistIds]);
return fetchedConversations;
}, [selectedArtist, fetchedConversations, orgArtistIds]);

// Optimistic update helpers for creating a new chat room
const addOptimisticConversation = (
Expand Down
7 changes: 3 additions & 4 deletions hooks/useCreateChat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
CreateChatRequest,
CreateChatResponse,
} from "@/types/Chat";
import type { ArtistAgent } from "@/lib/supabase/getArtistAgents";
import { useArtistProvider } from "@/providers/ArtistProvider";
import { useConversationsProvider } from "@/providers/ConversationsProvider";
import { usePrivy } from "@privy-io/react-auth";
Expand All @@ -16,7 +15,7 @@ const useCreateChat = ({
setDisplayName,
}: {
isOptimisticChatItem: boolean;
chatRoom: Conversation | ArtistAgent;
chatRoom: Conversation;
setDisplayName: (displayName: string) => void;
}) => {
const { selectedArtist } = useArtistProvider();
Expand All @@ -32,7 +31,7 @@ const useCreateChat = ({
if (!accessToken) return;

// Extract first message from optimistic memories
const firstMessage = (chatRoom as Conversation).memories?.find(
const firstMessage = chatRoom.memories?.find(
(memory) => {
const content = memory?.content as {
optimistic?: boolean;
Expand Down Expand Up @@ -65,7 +64,7 @@ const useCreateChat = ({

const requestBody: CreateChatRequest = {
artistId: selectedArtist?.account_id,
chatId: (chatRoom as Conversation).id,
chatId: chatRoom.id,
firstMessage: messageText,
};

Expand Down
15 changes: 3 additions & 12 deletions hooks/useRenameModal.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
import { useState, useEffect, useCallback } from "react";
import type { Conversation } from "@/types/Chat";
import type { ArtistAgent } from "@/lib/supabase/getArtistAgents";
import { usePrivy } from "@privy-io/react-auth";
import { updateChat } from "@/lib/chats/updateChat";
import { useConversationsProvider } from "@/providers/ConversationsProvider";

type ChatItem = Conversation | ArtistAgent;

const isChatRoom = (item: ChatItem): item is Conversation => "id" in item;
const getChatName = (item: ChatItem): string =>
isChatRoom(item) ? item.topic : item.type;
const getChatId = (item: ChatItem): string =>
isChatRoom(item) ? item.id : item.agentId;

const validateName = (value: string): string => {
const trimmed = value.trim();

Expand All @@ -26,7 +17,7 @@ const validateName = (value: string): string => {

type UseRenameModalParams = {
isOpen: boolean;
chatRoom: ChatItem | null;
chatRoom: Conversation | null;
onClose: () => void;
};

Expand All @@ -46,7 +37,7 @@ export function useRenameModal({
// Reset form when modal opens
useEffect(() => {
if (isOpen && chatRoom) {
setName(getChatName(chatRoom));
setName(chatRoom.topic);
setError("");
setTouched(false);
setIsSubmitting(false);
Expand Down Expand Up @@ -99,7 +90,7 @@ export function useRenameModal({
setIsSubmitting(true);

try {
const chatId = getChatId(chatRoom);
const chatId = chatRoom.id;
await updateChat({
accessToken,
chatId,
Expand Down
15 changes: 3 additions & 12 deletions lib/chat/getChatDisplayInfo.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
import type { Conversation } from "@/types/Chat";
import type { ArtistAgent } from "@/lib/supabase/getArtistAgents";
import capitalize from "@/lib/capitalize";

export const getChatDisplayInfo = (item: Conversation | ArtistAgent) => {
const isChatRoom = "id" in item;
const displayName = isChatRoom ? item.topic : capitalize(item.type);

return {
displayName:
displayName || `${capitalize(isChatRoom ? "Chat" : item.type)} Analysis`,
isChatRoom,
};
};
export const getChatDisplayInfo = (item: Conversation) => ({
displayName: item.topic || "Chat Analysis",
});
Loading
Loading