diff --git a/ui/src/app/messages.tsx b/ui/src/app/messages.tsx index 8c1e5e4..100d57a 100644 --- a/ui/src/app/messages.tsx +++ b/ui/src/app/messages.tsx @@ -24,6 +24,7 @@ export default function MessagesSection({ }: Props) { const { client, isReady } = useWAClient(); const [message, setMessage] = useState(""); + const [isPending, setPending] = useState(false); const { data: contacts } = useQuery({ queryKey: ["contacts"], @@ -32,7 +33,7 @@ export default function MessagesSection({ }); const chatId = getId(chat.id); - const { data: messages } = useQuery({ + const { data: messages, refetch } = useQuery({ queryKey: ["messages", chatId], queryFn: () => client.getMessages({ chatId, count: 50 }).then((res) => @@ -60,10 +61,33 @@ export default function MessagesSection({ ?.reverse(); }, [messages, contacts]); - function sendMessage() { + async function sendMessage() { const text = message.trim(); if (!text) return; - setMessage(""); + + try { + setPending(true); + await client.sendText({ chatId, text, options: { waitForAck: true } }); + setTimeout(refetch, 100); + setMessage(""); + } catch (err) { + alert((err as Error).message); + } finally { + setPending(false); + } + } + + async function fetchMedia(msgId: string) { + const data = await client.getMedia(msgId); + // decode from base64 + const blob = await fetch(data).then((res) => res.blob()); + // download + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = "media"; + a.click(); + URL.revokeObjectURL(url); } return ( @@ -156,11 +180,13 @@ export default function MessagesSection({ ) : null} {item.type === "image" && ( - + fetchMedia(item.id)}> + + )} {item.type === "chat" || item.caption ? ( @@ -227,7 +253,7 @@ export default function MessagesSection({ aria-label="Send message" onClick={sendMessage} className="grid size-10 shrink-0 place-items-center rounded-full bg-primary text-primary-foreground shadow-sm transition hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-50" - disabled={!message.trim()} + disabled={!message.trim() || isPending} > diff --git a/ui/src/app/page.tsx b/ui/src/app/page.tsx index 8685822..47ba6eb 100644 --- a/ui/src/app/page.tsx +++ b/ui/src/app/page.tsx @@ -12,96 +12,6 @@ import { useQuery } from "@tanstack/react-query"; import { cn, getId, getInitial } from "@/lib/utils"; import MessagesSection from "./messages"; -// type Chat = { -// id: number; -// name: string; -// initials: string; -// color: string; -// preview: string; -// time: string; -// unread?: number; -// online?: boolean; -// messages: { text: string; time: string; fromMe?: boolean; read?: boolean }[]; -// }; - -// const chats: Chat[] = [ -// { -// id: 1, -// name: "Maya Chen", -// initials: "MC", -// color: "bg-rose-200 text-rose-800", -// preview: "That sounds perfect. See you then!", -// time: "10:42 AM", -// online: true, -// messages: [ -// { text: "Hey! Are we still on for coffee tomorrow?", time: "10:38 AM" }, -// { -// text: "Absolutely. I found a new spot near the park.", -// time: "10:40 AM", -// fromMe: true, -// read: true, -// }, -// { text: "That sounds perfect. See you then!", time: "10:42 AM" }, -// ], -// }, -// { -// id: 2, -// name: "Design team", -// initials: "DT", -// color: "bg-violet-200 text-violet-800", -// preview: "Jon: The new explorations are ready", -// time: "9:16 AM", -// unread: 3, -// messages: [ -// { text: "Jon: The new explorations are ready", time: "9:16 AM" }, -// ], -// }, -// { -// id: 3, -// name: "Alex Morgan", -// initials: "AM", -// color: "bg-amber-200 text-amber-800", -// preview: "You: Thanks for sending that over", -// time: "Yesterday", -// messages: [ -// { -// text: "Thanks for sending that over", -// time: "Yesterday", -// fromMe: true, -// read: true, -// }, -// ], -// }, -// { -// id: 4, -// name: "Weekend plans", -// initials: "WP", -// color: "bg-emerald-200 text-emerald-800", -// preview: "Priya: I can bring the snacks", -// time: "Yesterday", -// unread: 8, -// messages: [{ text: "Priya: I can bring the snacks", time: "Yesterday" }], -// }, -// { -// id: 5, -// name: "Noah Williams", -// initials: "NW", -// color: "bg-sky-200 text-sky-800", -// preview: "Voice message", -// time: "Tuesday", -// messages: [{ text: "Voice message", time: "Tuesday" }], -// }, -// { -// id: 6, -// name: "Sofia Patel", -// initials: "SP", -// color: "bg-orange-200 text-orange-800", -// preview: "See you at the studio!", -// time: "Monday", -// messages: [{ text: "See you at the studio!", time: "Monday" }], -// }, -// ]; - export default function Page() { const [selectedId, setSelectedId] = useState(); const [query, setQuery] = useState(""); @@ -234,7 +144,9 @@ export default function Page() {

- {chat.lastMessage?.body?.substring(0, 50)} + {chat.previewMessage?.type === "chat" + ? chat.previewMessage?.body?.substring(0, 50) + : null}

{/* {chat.unread && ( diff --git a/ui/src/lib/context.tsx b/ui/src/lib/context.tsx index d9df84c..1beedfd 100644 --- a/ui/src/lib/context.tsx +++ b/ui/src/lib/context.tsx @@ -15,13 +15,7 @@ export function useWAClient() { return ctx; } -export function WAProvider({ - children, - url, -}: { - children: React.ReactNode; - url?: string; -}) { +export function WAProvider({ children }: { children: React.ReactNode }) { const isInitialized = useRef(false); const [isConnected, setConnected] = useState(false); @@ -38,9 +32,7 @@ export function WAProvider({ isInitialized.current = true; wa.on("status", setConnected); - }, [url]); - - console.log("status", status); + }, []); return ( - +