diff --git a/.env b/.env new file mode 100644 index 0000000..55ce932 --- /dev/null +++ b/.env @@ -0,0 +1,8 @@ +#### +# App Config +# Environment files are documented here: +# https://vitejs.dev/guide/env-and-mode.html#env-files +#### + +# The room id for the space to use for listing public group call rooms +# VITE_PUBLIC_SPACE_ROOM_ID=!hjdfshkdskjdsk:myhomeserver.com \ No newline at end of file diff --git a/README.md b/README.md index ef665b5..a9eb707 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,42 @@ Testbed for full mesh video chat. ## Getting Started -You must first run a local Synapse server on port 8008 +`matrix-video-chat` is built against the `robertlong/group-call` branch of both [matrix-js-sdk](https://github.com/matrix-org/matrix-js-sdk/pull/1902) and [matrix-react-sdk](https://github.com/matrix-org/matrix-react-sdk/pull/6848). Because of how these packages are configured and Vite's requirements, you will need to clone them locally and use `yarn link` to stich things together. + +First clone, install, and link `matrix-js-sdk` ``` +git clone https://github.com/matrix-org/matrix-js-sdk.git +cd matrix-js-sdk +git checkout robertlong/group-call +yarn +yarn link +``` + +Then clone, install, link `matrix-js-sdk` into `matrix-react-sdk`, and link `matrix-react-sdk` + +``` +git clone https://github.com/matrix-org/matrix-react-sdk.git +cd matrix-react-sdk +git checkout robertlong/group-call +yarn +yarn link matrix-js-sdk +yarn link +``` + +Next you'll also need [Synapse](https://matrix-org.github.io/synapse/latest/setup/installation.html) installed locally and running on port 8008. + +Finally we can set up this project. + +``` +git clone https://github.com/vector-im/matrix-video-chat.git cd matrix-video-chat yarn +yarn link matrix-js-sdk +yarn link matrix-react-sdk yarn dev ``` + +## Config + +Configuration options are documented in the `.env` file. diff --git a/package.json b/package.json index 79914d8..a96bc72 100644 --- a/package.json +++ b/package.json @@ -6,19 +6,15 @@ "serve": "vite preview" }, "dependencies": { - "@react-spring/web": "^9.2.4", "classnames": "^2.3.1", "color-hash": "^2.0.1", "events": "^3.3.0", - "lodash-move": "^1.1.1", "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#robertlong/group-call", "matrix-react-sdk": "github:matrix-org/matrix-react-sdk#robertlong/group-call", "re-resizable": "^6.9.0", "react": "^17.0.0", "react-dom": "^17.0.0", - "react-router-dom": "^5.2.0", - "react-use-gesture": "^9.1.3", - "react-use-measure": "^2.0.4" + "react-router-dom": "^5.2.0" }, "devDependencies": { "sass": "^1.42.1", diff --git a/src/ConferenceCallManagerHooks.js b/src/ConferenceCallManagerHooks.js index 103ed47..db93e51 100644 --- a/src/ConferenceCallManagerHooks.js +++ b/src/ConferenceCallManagerHooks.js @@ -277,24 +277,56 @@ function sortRooms(client, rooms) { }); } -export function useRooms(client) { +export function useGroupCallRooms(client) { const [rooms, setRooms] = useState([]); useEffect(() => { function updateRooms() { - const visibleRooms = client.getVisibleRooms(); - const sortedRooms = sortRooms(client, visibleRooms); - setRooms(sortedRooms); + const groupCalls = client.groupCallEventHandler.groupCalls.values(); + const rooms = Array.from(groupCalls).map((groupCall) => groupCall.room); + const sortedRooms = sortRooms(client, rooms); + const items = sortedRooms.map((room) => { + const groupCall = client.getGroupCallForRoom(room.roomId); + + return { + room, + groupCall, + participants: [...groupCall.participants], + }; + }); + setRooms(items); } updateRooms(); - client.on("Room", updateRooms); + client.on("GroupCall.incoming", updateRooms); + client.on("GroupCall.participants", updateRooms); return () => { - client.removeListener("Room", updateRooms); + client.removeListener("GroupCall.incoming", updateRooms); + client.removeListener("GroupCall.participants", updateRooms); }; }, []); return rooms; } + +export function usePublicRooms(client, publicSpaceRoomId, maxRooms = 50) { + const [rooms, setRooms] = useState([]); + + useEffect(() => { + if (publicSpaceRoomId) { + client.getRoomHierarchy(publicSpaceRoomId, maxRooms).then(({ rooms }) => { + const filteredRooms = rooms.filter( + (room) => room.room_type !== "m.space" + ); + + setRooms(filteredRooms); + }); + } else { + setRooms([]); + } + }, [publicSpaceRoomId]); + + return rooms; +} diff --git a/src/Facepile.jsx b/src/Facepile.jsx new file mode 100644 index 0000000..77d158f --- /dev/null +++ b/src/Facepile.jsx @@ -0,0 +1,23 @@ +import React from "react"; +import styles from "./Facepile.module.css"; +import ColorHash from "color-hash"; + +const colorHash = new ColorHash({ lightness: 0.3 }); + +export function Facepile({ participants }) { + return ( +