import React, { createContext, useContext, useEffect, useState, useCallback } from "react"; import sdk from "matrix-js-sdk"; const MatrixContext = createContext(null); export function useMatrix() { return useContext(MatrixContext); } export function MatrixProvider({ children }) { const [client, setClient] = useState(null); const [rooms, setRooms] = useState([]); const [messages, setMessages] = useState([]); const [user, setUser] = useState(null); const [currentRoomId, setCurrentRoomId] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); // Login to Matrix const login = useCallback(async (username, password, homeserver = "https://matrix.org") => { setLoading(true); setError(null); try { const matrixClient = sdk.createClient({ baseUrl: homeserver }); const resp = await matrixClient.loginWithPassword(username, password); matrixClient.startClient({ initialSyncLimit: 10 }); setClient(matrixClient); setUser({ userId: resp.user_id, accessToken: resp.access_token }); setLoading(false); // Listen for sync and events matrixClient.on("sync", (state) => { if (state === "PREPARED") { setRooms(matrixClient.getRooms()); } }); matrixClient.on("Room.timeline", (event, room) => { if (room.roomId === currentRoomId && event.getType() === "m.room.message") { setMessages((msgs) => [...msgs, event.event]); } }); } catch (e) { setError(e.message); setLoading(false); } }, [currentRoomId]); // Join a room and fetch messages const joinRoom = useCallback(async (roomId) => { if (!client) return; setCurrentRoomId(roomId); const room = client.getRoom(roomId); if (room) { setMessages(room.timeline.filter(e => e.getType() === "m.room.message").map(e => e.event)); } }, [client]); // Send a message const sendMessage = useCallback(async (roomId, text) => { if (!client) return; await client.sendTextMessage(roomId, text); }, [client]); return ( {children} ); }