AeThex-Connect/astro-site/src/components/matrix/MatrixProvider.jsx

68 lines
2.3 KiB
JavaScript

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 (
<MatrixContext.Provider value={{ client, rooms, messages, user, login, joinRoom, sendMessage, currentRoomId, loading, error }}>
{children}
</MatrixContext.Provider>
);
}