import { http } from "./http"; import type { Chat, ChatDetail, ChatMember, ChatMemberRole, ChatType, DiscoverChat, Message, MessageReaction, MessageType } from "../chat/types"; import axios from "axios"; export interface ChatNotificationSettings { chat_id: number; user_id: number; muted: boolean; } export async function getChats(query?: string, archived = false): Promise { const { data } = await http.get("/chats", { params: { ...(query?.trim() ? { query: query.trim() } : {}), ...(archived ? { archived: true } : {}) } }); return data; } export async function createPrivateChat(memberId: number): Promise { return createChat("private", null, [memberId]); } export async function createChat(type: ChatType, title: string | null, memberIds: number[] = []): Promise { const { data } = await http.post("/chats", { type, title, is_public: false, member_ids: memberIds }); return data; } export async function createPublicChat(type: "group" | "channel", title: string, handle: string, description?: string): Promise { const { data } = await http.post("/chats", { type, title, handle, description, is_public: true, member_ids: [] }); return data; } export async function getMessages(chatId: number, beforeId?: number): Promise { const { data } = await http.get(`/messages/${chatId}`, { params: { limit: 50, before_id: beforeId } }); return data; } export async function searchMessages(query: string, chatId?: number): Promise { const { data } = await http.get("/messages/search", { params: { query, chat_id: chatId } }); return data; } export async function sendMessage(chatId: number, text: string, type: MessageType = "text"): Promise { const { data } = await http.post("/messages", { chat_id: chatId, text, type }); return data; } export async function sendMessageWithClientId( chatId: number, text: string, type: MessageType, clientMessageId: string, replyToMessageId?: number ): Promise { const { data } = await http.post("/messages", { chat_id: chatId, text, type, client_message_id: clientMessageId, reply_to_message_id: replyToMessageId }); return data; } export interface UploadUrlResponse { upload_url: string; file_url: string; object_key: string; expires_in: number; required_headers: Record; } export async function requestUploadUrl(file: File): Promise { const { data } = await http.post("/media/upload-url", { file_name: file.name, file_type: file.type || "application/octet-stream", file_size: file.size }); return data; } export async function uploadToPresignedUrl( uploadUrl: string, requiredHeaders: Record, file: File, onProgress?: (percent: number) => void, retries = 2 ): Promise { let attempt = 0; while (attempt <= retries) { try { await axios.put(uploadUrl, file, { headers: requiredHeaders, onUploadProgress: (progressEvent) => { if (!onProgress || !progressEvent.total) { return; } onProgress(Math.round((progressEvent.loaded * 100) / progressEvent.total)); } }); return; } catch (error) { const status = axios.isAxiosError(error) ? error.response?.status : undefined; const retryable = status === undefined || status >= 500; if (!retryable || attempt >= retries) { throw error; } attempt += 1; await new Promise((resolve) => window.setTimeout(resolve, 400 * attempt)); } } } export async function attachFile(messageId: number, fileUrl: string, fileType: string, fileSize: number): Promise { await http.post("/media/attachments", { message_id: messageId, file_url: fileUrl, file_type: fileType, file_size: fileSize }); } export async function updateMessageStatus( chatId: number, messageId: number, status: "message_delivered" | "message_read" ): Promise { await http.post("/messages/status", { chat_id: chatId, message_id: messageId, status }); } export async function forwardMessage(messageId: number, targetChatId: number): Promise { const { data } = await http.post(`/messages/${messageId}/forward`, { target_chat_id: targetChatId }); return data; } export async function listMessageReactions(messageId: number): Promise { const { data } = await http.get(`/messages/${messageId}/reactions`); return data; } export async function toggleMessageReaction(messageId: number, emoji: string): Promise { const { data } = await http.post(`/messages/${messageId}/reactions/toggle`, { emoji }); return data; } export async function pinMessage(chatId: number, messageId: number | null): Promise { const { data } = await http.post(`/chats/${chatId}/pin`, { message_id: messageId }); return data; } export async function deleteChat(chatId: number, forAll: boolean): Promise { await http.delete(`/chats/${chatId}`, { params: { for_all: forAll } }); } export async function clearChat(chatId: number): Promise { await http.post(`/chats/${chatId}/clear`); } export async function archiveChat(chatId: number): Promise { const { data } = await http.post(`/chats/${chatId}/archive`); return data; } export async function unarchiveChat(chatId: number): Promise { const { data } = await http.post(`/chats/${chatId}/unarchive`); return data; } export async function pinChat(chatId: number): Promise { const { data } = await http.post(`/chats/${chatId}/pin-chat`); return data; } export async function unpinChat(chatId: number): Promise { const { data } = await http.post(`/chats/${chatId}/unpin-chat`); return data; } export async function deleteMessage(messageId: number, forAll = false): Promise { await http.delete(`/messages/${messageId}`, { params: { for_all: forAll } }); } export async function discoverChats(query?: string): Promise { const { data } = await http.get("/chats/discover", { params: query?.trim() ? { query: query.trim() } : undefined }); return data; } export async function joinChat(chatId: number): Promise { const { data } = await http.post(`/chats/${chatId}/join`); return data; } export async function getSavedMessagesChat(): Promise { const { data } = await http.get("/chats/saved"); return data; } export async function getChatDetail(chatId: number): Promise { const { data } = await http.get(`/chats/${chatId}`); return data; } export async function listChatMembers(chatId: number): Promise { const { data } = await http.get(`/chats/${chatId}/members`); return data; } export async function updateChatTitle(chatId: number, title: string): Promise { const { data } = await http.patch(`/chats/${chatId}/title`, { title }); return data; } export async function addChatMember(chatId: number, userId: number): Promise { const { data } = await http.post(`/chats/${chatId}/members`, { user_id: userId }); return data; } export async function updateChatMemberRole(chatId: number, userId: number, role: ChatMemberRole): Promise { const { data } = await http.patch(`/chats/${chatId}/members/${userId}/role`, { role }); return data; } export async function removeChatMember(chatId: number, userId: number): Promise { await http.delete(`/chats/${chatId}/members/${userId}`); } export async function leaveChat(chatId: number): Promise { await http.post(`/chats/${chatId}/leave`); } export async function getChatNotificationSettings(chatId: number): Promise { const { data } = await http.get(`/chats/${chatId}/notifications`); return data; } export async function updateChatNotificationSettings(chatId: number, muted: boolean): Promise { const { data } = await http.put(`/chats/${chatId}/notifications`, { muted }); return data; }