Showing rooms works
This commit is contained in:
parent
b0ebeda23a
commit
f93cabb99d
|
@ -10,6 +10,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@jitsi/react-sdk": "^1.3.0",
|
||||
"just-curry-it": "^5.3.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
|
|
|
@ -1,14 +1,29 @@
|
|||
import "./App.css";
|
||||
import Meeting from "./components/meeting/Meeting";
|
||||
import Sidebar from "./components/sidebar/Sidebar";
|
||||
import useBackendData from "./hooks/useBackendData";
|
||||
import useConferenceData from "./hooks/useConferenceData";
|
||||
import useLocalUser from "./hooks/useLocalUser";
|
||||
|
||||
function App() {
|
||||
const { userInfo, setUserInfo } = useLocalUser();
|
||||
const { roomData, sendMessage } = useBackendData(userInfo);
|
||||
const { conferenceData, setConferenceData } = useConferenceData(
|
||||
sendMessage,
|
||||
setUserInfo
|
||||
);
|
||||
|
||||
console.log(roomData);
|
||||
|
||||
if (roomData && userInfo) {
|
||||
return (
|
||||
<div className="App">
|
||||
<Sidebar />
|
||||
<Meeting />
|
||||
<Sidebar usersData={roomData} />
|
||||
<Meeting setConferenceData={setConferenceData} userInfo={userInfo} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return <h2>🌀 Loading...</h2>;
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
|
|
@ -1,4 +1,14 @@
|
|||
const JITSI_DOMAIN = "thisisnotajitsi.filefighter.de";
|
||||
const WEBSOCKET_URL = "ws" + (window.location.protocol == "https:" ? "s" : "") + "://" + window.location.host + "/ws"
|
||||
const ISPROD = window.location.protocol == "https:";
|
||||
const JITSI_DOMAIN = ISPROD
|
||||
? "thisisnotajitsi.filefighter.de"
|
||||
: "localhost:8443";
|
||||
const WEBSOCKET_URL =
|
||||
"ws" +
|
||||
(ISPROD ? "s" : "") +
|
||||
"://" +
|
||||
(ISPROD ? window.location.host : "localhost:9160") +
|
||||
"/ws";
|
||||
|
||||
export { JITSI_DOMAIN, WEBSOCKET_URL };
|
||||
const USER_COOKIE_NAME = "jitsi-rooms-user";
|
||||
|
||||
export { JITSI_DOMAIN, WEBSOCKET_URL, USER_COOKIE_NAME };
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
function getCookie(cname: string) {
|
||||
let name = cname + "=";
|
||||
let decodedCookie = decodeURIComponent(document.cookie);
|
||||
let ca = decodedCookie.split(";");
|
||||
for (let i = 0; i < ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) == " ") {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) == 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function setCookie(cname: string, cvalue: string, exdays = 30) {
|
||||
const d = new Date();
|
||||
d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000);
|
||||
let expires = "expires=" + d.toUTCString();
|
||||
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
|
||||
}
|
||||
|
||||
export { getCookie, setCookie };
|
|
@ -0,0 +1,16 @@
|
|||
export interface ConferenceData {
|
||||
roomName: string; // the room name of the conference
|
||||
id: string; // the id of the local participant
|
||||
displayName: string; // the display name of the local participant
|
||||
avatarURL: string; // the avatar URL of the local participant
|
||||
breakoutRoom: boolean; // whether the current room is a breakout room
|
||||
}
|
||||
|
||||
function videoConferenceJoinedListener(
|
||||
setConferenceData: (newData: ConferenceData) => void,
|
||||
videoConferenceJoinedEvent: ConferenceData
|
||||
) {
|
||||
setConferenceData(videoConferenceJoinedEvent);
|
||||
}
|
||||
|
||||
export { videoConferenceJoinedListener };
|
|
@ -0,0 +1,16 @@
|
|||
export interface RoomData {
|
||||
roomName: string;
|
||||
participants: Participant[];
|
||||
}
|
||||
|
||||
export interface Participant {
|
||||
avatarURL: string;
|
||||
displayName: string;
|
||||
jid: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
export interface UsersData {
|
||||
roomsData: RoomData[];
|
||||
usersWithOutRoom: string[];
|
||||
}
|
|
@ -1,13 +1,19 @@
|
|||
import { JitsiMeeting } from "@jitsi/react-sdk";
|
||||
import { JITSI_DOMAIN } from "../../background/constants";
|
||||
import { UserInfo } from "./types";
|
||||
import curry from "just-curry-it";
|
||||
import {
|
||||
ConferenceData,
|
||||
videoConferenceJoinedListener,
|
||||
} from "../../background/jitsi/eventListeners";
|
||||
|
||||
interface Props {
|
||||
roomName: string;
|
||||
userInfo: UserInfo;
|
||||
setConferenceData: (newData: ConferenceData) => void;
|
||||
}
|
||||
|
||||
function JitsiEntrypoint({ roomName, userInfo }: Props) {
|
||||
function JitsiEntrypoint({ roomName, userInfo, setConferenceData }: Props) {
|
||||
return (
|
||||
<JitsiMeeting
|
||||
domain={JITSI_DOMAIN}
|
||||
|
@ -24,6 +30,11 @@ function JitsiEntrypoint({ roomName, userInfo }: Props) {
|
|||
onApiReady={(externalApi) => {
|
||||
// here you can attach custom event listeners to the Jitsi Meet External API
|
||||
// you can also store it locally to execute commands
|
||||
|
||||
externalApi.addEventListener(
|
||||
"videoConferenceJoined",
|
||||
curry(videoConferenceJoinedListener)(setConferenceData)
|
||||
);
|
||||
}}
|
||||
getIFrameRef={(iframeRef) => {
|
||||
iframeRef.style.height = "100%";
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
|
||||
interface UserInfo {
|
||||
export interface UserInfo {
|
||||
displayName: string;
|
||||
email: string
|
||||
email: string;
|
||||
}
|
||||
|
||||
export { UserInfo }
|
||||
|
|
|
@ -1,23 +1,32 @@
|
|||
import { useCallback, useState } from "react";
|
||||
import { ConferenceData } from "../../background/jitsi/eventListeners";
|
||||
import { useRoomName } from "../../hooks/useRoomName";
|
||||
import JitsiEntrypoint from "../jitsi/JitsiEntrypoint";
|
||||
import { UserInfo } from "../jitsi/types";
|
||||
import MeetingNameInput from "./MeetingNameInput";
|
||||
|
||||
function Meeting() {
|
||||
interface Props {
|
||||
setConferenceData: (newData: ConferenceData) => void;
|
||||
userInfo: UserInfo;
|
||||
}
|
||||
|
||||
function Meeting({ setConferenceData, userInfo }: Props) {
|
||||
const { roomName, updateRoomName, submitRoomName } = useRoomName();
|
||||
const [meetingStarted, setMeetingStarted] = useState(false);
|
||||
|
||||
const userInfo: UserInfo = { displayName: "unknown traveller", email: "" }
|
||||
|
||||
|
||||
const startMeeting = useCallback(() => {
|
||||
submitRoomName();
|
||||
setMeetingStarted(true);
|
||||
}, [submitRoomName, setMeetingStarted]);
|
||||
|
||||
if (meetingStarted) {
|
||||
return <JitsiEntrypoint roomName={roomName} userInfo={userInfo} />;
|
||||
return (
|
||||
<JitsiEntrypoint
|
||||
roomName={roomName}
|
||||
userInfo={userInfo}
|
||||
setConferenceData={setConferenceData}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,14 +1,37 @@
|
|||
import SidebarHeader from "./SidebarHeader";
|
||||
import useSidebarVisibility from "./useSidebarVisibility";
|
||||
import "./Sidebar.css";
|
||||
import { UsersData } from "../../background/types/roomData";
|
||||
|
||||
function Sidebar() {
|
||||
interface Props {
|
||||
usersData: UsersData;
|
||||
}
|
||||
|
||||
function Sidebar(props: Props) {
|
||||
const { sidebarVisibility, toggleSidebarVisibility, sidebarToggleText } =
|
||||
useSidebarVisibility();
|
||||
|
||||
return (
|
||||
<div className={`sidebar sidebar-${sidebarVisibility}`}>
|
||||
<SidebarHeader sidebarVisibility={sidebarVisibility} />
|
||||
<div>
|
||||
<h3> No room</h3>
|
||||
{props.usersData.usersWithOutRoom.map((username) => (
|
||||
<div>{username}</div>
|
||||
))}
|
||||
</div>
|
||||
<div>
|
||||
{props.usersData.roomsData.map((roomData) => {
|
||||
return (
|
||||
<>
|
||||
<h3> {roomData.roomName} </h3>
|
||||
{roomData.participants.map((participant) => (
|
||||
<div> {participant.displayName} </div>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="sidebar-footer">
|
||||
<button onClick={toggleSidebarVisibility}>{sidebarToggleText}</button>
|
||||
</div>
|
||||
|
|
|
@ -1,20 +1,26 @@
|
|||
import { useEffect } from "react";
|
||||
import { UserInfo } from "../components/jitsi/types";
|
||||
import useRoomData from "./useRoomData";
|
||||
import useWebSocketConnection from "./useWebSocketConnection";
|
||||
|
||||
function useBackendData() {
|
||||
function useBackendData(userInfo: UserInfo) {
|
||||
console.log("[Rooms] useBackendData");
|
||||
const { onMessage, sendMessage } = useWebSocketConnection(userInfo);
|
||||
|
||||
const { onMessage, sendMessage } = useWebSocketConnection();
|
||||
const { roomData, setRoomData } = useRoomData();
|
||||
|
||||
const { roomData, setRoomData } = useRoomData()
|
||||
useEffect(
|
||||
() =>
|
||||
onMessage((messageString) => {
|
||||
console.log("[Rooms] message from ws", messageString);
|
||||
const messageObject = JSON.parse(messageString);
|
||||
|
||||
!!messageObject.roomsData && setRoomData(messageObject);
|
||||
}),
|
||||
[onMessage, setRoomData]
|
||||
);
|
||||
|
||||
onMessage(
|
||||
(messageString) => {
|
||||
const messageObject = JSON.parse(messageString)
|
||||
|
||||
!!messageObject.roomData && setRoomData(messageObject.roomData)
|
||||
|
||||
return { roomData, sendMessage };
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
}
|
||||
export default useBackendData;
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import { useState } from "react";
|
||||
import { ConferenceData } from "../background/jitsi/eventListeners";
|
||||
import { UserInfo } from "../components/jitsi/types";
|
||||
|
||||
function useConferenceData(
|
||||
sendMessage: (message: string) => void,
|
||||
setUserInfo: (newData: UserInfo) => void
|
||||
) {
|
||||
const [conferenceData, setConferenceDataLocal] = useState<ConferenceData>();
|
||||
|
||||
const setConferenceData = (newData: ConferenceData) => {
|
||||
console.log("[Rooms] set conferenceData");
|
||||
sendMessage(JSON.stringify(newData));
|
||||
setConferenceDataLocal(newData);
|
||||
setUserInfo({ displayName: newData.displayName, email: "" });
|
||||
};
|
||||
|
||||
return { conferenceData, setConferenceData };
|
||||
}
|
||||
|
||||
export default useConferenceData;
|
|
@ -0,0 +1,33 @@
|
|||
import { useState } from "react";
|
||||
import { USER_COOKIE_NAME } from "../background/constants";
|
||||
import { getCookie, setCookie } from "../background/cookies";
|
||||
import { UserInfo } from "../components/jitsi/types";
|
||||
|
||||
function useLocalUser() {
|
||||
const [userInfo, setUserInfoLocal] = useState<UserInfo>(() =>
|
||||
getUserInfoFromCookie()
|
||||
);
|
||||
|
||||
const setUserInfo = (newData: UserInfo) => {
|
||||
storeUserInfoInCookie(newData);
|
||||
setUserInfoLocal(newData);
|
||||
};
|
||||
|
||||
return { userInfo, setUserInfo };
|
||||
}
|
||||
|
||||
function getUserInfoFromCookie(): UserInfo {
|
||||
let cookie = getCookie(USER_COOKIE_NAME);
|
||||
console.log("[Rooms] getUserNameFromCookie 1", cookie);
|
||||
if (cookie) return JSON.parse(cookie);
|
||||
return {
|
||||
displayName: "unknown traveller",
|
||||
email: "",
|
||||
};
|
||||
}
|
||||
|
||||
function storeUserInfoInCookie(userInfo: UserInfo) {
|
||||
setCookie(USER_COOKIE_NAME, JSON.stringify(userInfo));
|
||||
}
|
||||
|
||||
export default useLocalUser;
|
|
@ -0,0 +1,10 @@
|
|||
import { useState } from "react";
|
||||
import { UsersData } from "../background/types/roomData";
|
||||
|
||||
function useRoomData() {
|
||||
const [roomData, setRoomData] = useState<UsersData>();
|
||||
|
||||
return { roomData, setRoomData };
|
||||
}
|
||||
|
||||
export default useRoomData;
|
|
@ -1,7 +1,7 @@
|
|||
import { useCallback, useState } from "react";
|
||||
|
||||
function useRoomName() {
|
||||
const [roomName, setRoomName] = useState(getRoomNameFromUrl());
|
||||
const [roomName, setRoomName] = useState(() => getRoomNameFromUrl());
|
||||
|
||||
const updateRoomName = useCallback(
|
||||
(newName: string) => {
|
||||
|
@ -11,13 +11,10 @@ function useRoomName() {
|
|||
[setRoomName]
|
||||
);
|
||||
|
||||
const submitRoomName = useCallback(
|
||||
() => {
|
||||
const submitRoomName = useCallback(() => {
|
||||
setRoomNameInUrl(roomName);
|
||||
setRoomNameInTitle(roomName);
|
||||
},
|
||||
[roomName]
|
||||
);
|
||||
}, [roomName]);
|
||||
|
||||
return { roomName, updateRoomName, submitRoomName };
|
||||
}
|
||||
|
|
|
@ -1,34 +1,46 @@
|
|||
import { useCallback, useState } from "react";
|
||||
import { WEBSOCKET_URL } from "../background/constants";
|
||||
import { UserInfo } from "../components/jitsi/types";
|
||||
|
||||
function useWebSocketConnection() {
|
||||
|
||||
const createWebSocketConnection = () => {
|
||||
const createWebSocketConnection = (userInfo: UserInfo) => {
|
||||
const webSocket = new WebSocket(WEBSOCKET_URL);
|
||||
return webSocket
|
||||
}
|
||||
console.log("[Rooms] createWebSocketConnection");
|
||||
webSocket.addEventListener("open", (_: Event) =>
|
||||
webSocket.send(JSON.stringify(userInfo.displayName))
|
||||
);
|
||||
|
||||
const [webSocketConnection] = useState<WebSocket>(createWebSocketConnection())
|
||||
return webSocket;
|
||||
};
|
||||
|
||||
const sendMessage = useCallback((message: string) => {
|
||||
function useWebSocketConnection(userInfo: UserInfo) {
|
||||
console.log("[Rooms] useWebSocketConnection");
|
||||
|
||||
const [webSocketConnection] = useState<WebSocket>(() =>
|
||||
createWebSocketConnection(userInfo)
|
||||
);
|
||||
|
||||
const sendMessage = useCallback(
|
||||
(message: string) => {
|
||||
//if the socket's open, send a message:
|
||||
if (webSocketConnection.readyState === WebSocket.OPEN) {
|
||||
console.log("[Rooms] sending to ws", message);
|
||||
webSocketConnection.send(message);
|
||||
}
|
||||
},
|
||||
[webSocketConnection]
|
||||
)
|
||||
);
|
||||
|
||||
const onMessage = useCallback(
|
||||
(messageHandler: (messageHandler: string) => void) => {
|
||||
const wsMessageHandler = (ev: MessageEvent<any>) => { messageHandler(ev.data) }
|
||||
webSocketConnection.addEventListener('message', wsMessageHandler)
|
||||
const wsMessageHandler = (ev: MessageEvent<any>) => {
|
||||
messageHandler(ev.data);
|
||||
};
|
||||
webSocketConnection.addEventListener("message", wsMessageHandler);
|
||||
},
|
||||
[webSocketConnection]
|
||||
)
|
||||
);
|
||||
|
||||
return { onMessage, sendMessage }
|
||||
return { onMessage, sendMessage };
|
||||
}
|
||||
|
||||
export default useWebSocketConnection;
|
||||
|
||||
|
|
|
@ -558,6 +558,11 @@ json5@^2.2.2:
|
|||
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
|
||||
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
|
||||
|
||||
just-curry-it@^5.3.0:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/just-curry-it/-/just-curry-it-5.3.0.tgz#1463602e932c5beb431a2a384dddcd48bb3c9c42"
|
||||
integrity sha512-silMIRiFjUWlfaDhkgSzpuAyQ6EX/o09Eu8ZBfmFwQMbax7+LQzeIU2CBrICT6Ne4l86ITCGvUCBpCubWYy0Yw==
|
||||
|
||||
loose-envify@^1.1.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||
|
|
Loading…
Reference in New Issue