From 5fbba6cb98d59f5c96c1c6d3de0baa34855ae7cf Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 8 Apr 2023 15:58:11 +0200 Subject: [PATCH] jotai & allchat --- frontend/dev-with-remote-backend.sh | 0 frontend/package.json | 1 + frontend/src/App.tsx | 12 +---- frontend/src/background/types/roomData.ts | 8 ++- frontend/src/components/chat/Chat.css | 20 +++++++ frontend/src/components/chat/Chat.tsx | 53 +++++++++++++++++++ frontend/src/components/meeting/Meeting.tsx | 14 ++--- .../components/meeting/MeetingNameInput.tsx | 23 +++++--- frontend/src/components/sidebar/Sidebar.css | 6 ++- frontend/src/components/sidebar/Sidebar.tsx | 19 ++++--- frontend/src/hooks/useAllChat.tsx | 27 ++++++++++ frontend/src/hooks/useBackendData.ts | 4 ++ frontend/src/hooks/useMeetingStarted.ts | 7 +++ frontend/src/hooks/useRoomName.ts | 5 +- frontend/src/main.tsx | 5 +- frontend/yarn.lock | 5 ++ 16 files changed, 172 insertions(+), 37 deletions(-) mode change 100644 => 100755 frontend/dev-with-remote-backend.sh create mode 100644 frontend/src/components/chat/Chat.css create mode 100644 frontend/src/components/chat/Chat.tsx create mode 100644 frontend/src/hooks/useAllChat.tsx create mode 100644 frontend/src/hooks/useMeetingStarted.ts diff --git a/frontend/dev-with-remote-backend.sh b/frontend/dev-with-remote-backend.sh old mode 100644 new mode 100755 diff --git a/frontend/package.json b/frontend/package.json index 19a0215..5b9bf01 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@jitsi/react-sdk": "^1.3.0", + "jotai": "^2.0.3", "just-curry-it": "^5.3.0", "react": "^18.2.0", "react-dom": "^18.2.0" diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 5901c6c..92bf62a 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,3 +1,4 @@ +import { Provider } from "jotai"; import { useState } from "react"; import "./App.css"; import Meeting from "./components/meeting/Meeting"; @@ -9,7 +10,6 @@ import { useRoomName } from "./hooks/useRoomName"; function App() { const { userInfo, setUserInfo } = useLocalUser(); - const { roomName, updateRoomName, updateAndSubmitRoomName, submitRoomName } = useRoomName(); const { roomData, sendMessage } = useBackendData(userInfo); const { conferenceData, setConferenceData } = useConferenceData( sendMessage, @@ -23,20 +23,12 @@ function App() { return (
{ - updateAndSubmitRoomName(roomName) - setMeetingStarted(true) - }} + sendMessage={sendMessage} />
); diff --git a/frontend/src/background/types/roomData.ts b/frontend/src/background/types/roomData.ts index 02ae94d..55579cd 100644 --- a/frontend/src/background/types/roomData.ts +++ b/frontend/src/background/types/roomData.ts @@ -10,7 +10,13 @@ export interface Participant { email: string; } +export interface User { + uuid: string, + name: string + +} + export interface UsersData { roomsData: RoomData[]; - usersWithOutRoom: string[]; + usersWithOutRoom: User[]; } diff --git a/frontend/src/components/chat/Chat.css b/frontend/src/components/chat/Chat.css new file mode 100644 index 0000000..2b530f8 --- /dev/null +++ b/frontend/src/components/chat/Chat.css @@ -0,0 +1,20 @@ +.chat-input{ +max-width: 50%; +} + + +.chat-bubble{ + background-color: #3d3d5c; + overflow-wrap: break-word; + margin-bottom: 7px; + + white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* css-3 */ + word-wrap: break-word; /* Internet Explorer 5.5+ */ + white-space: -webkit-pre-wrap; /* Newer versions of Chrome/Safari*/ + word-break: break-all; + white-space: normal; +} + diff --git a/frontend/src/components/chat/Chat.tsx b/frontend/src/components/chat/Chat.tsx new file mode 100644 index 0000000..cc8484b --- /dev/null +++ b/frontend/src/components/chat/Chat.tsx @@ -0,0 +1,53 @@ +import { useState } from "react"; +import { FormEventHandler } from "react"; +import useAllChat from "../../hooks/useAllChat"; +import "./Chat.css" + +interface Props { + sendMessage: Function +} + + + +function Chat({ sendMessage }: Props) { + + const [chatInput, setChatInput] = useState("") + + const { chatMesages } = useAllChat() + + const onInput: React.ChangeEventHandler = (event) => { + setChatInput(event.target.value); + event.preventDefault(); + }; + + const onSubmit: FormEventHandler = (event) => { + event.preventDefault(); + sendMessage(JSON.stringify({ content: chatInput })); + setChatInput("") + } + + return ( +
+ {chatMesages.map(message => ( +
{message.sender.name}: {message.content}
+ )) + + } +
+ + +
+
+ ); + + +} + + +export default Chat diff --git a/frontend/src/components/meeting/Meeting.tsx b/frontend/src/components/meeting/Meeting.tsx index f767894..23c2f9a 100644 --- a/frontend/src/components/meeting/Meeting.tsx +++ b/frontend/src/components/meeting/Meeting.tsx @@ -1,5 +1,6 @@ import { useCallback, useState } from "react"; import { ConferenceData } from "../../background/jitsi/eventListeners"; +import useMeetingStarted from "../../hooks/useMeetingStarted"; import { useRoomName } from "../../hooks/useRoomName"; import JitsiEntrypoint from "../jitsi/JitsiEntrypoint"; import { UserInfo } from "../jitsi/types"; @@ -9,17 +10,12 @@ interface Props { conferenceData: ConferenceData | undefined; setConferenceData: (newData: ConferenceData) => void; userInfo: UserInfo; - //@ts-ignore - roomName, updateRoomName, submitRoomName - meetingStarted: Boolean, setMeetingStarted: Function } -function Meeting({ conferenceData, setConferenceData, userInfo, roomName, updateRoomName, submitRoomName, meetingStarted, setMeetingStarted }: Props) { +function Meeting({ conferenceData, setConferenceData, userInfo }: Props) { - const startMeeting = useCallback(() => { - submitRoomName(); - setMeetingStarted(true); - }, [submitRoomName, setMeetingStarted]); + const [meetingStarted, setMeetingStarted] = useMeetingStarted() + const { roomName } = useRoomName() if (meetingStarted) { return ( @@ -35,8 +31,6 @@ function Meeting({ conferenceData, setConferenceData, userInfo, roomName, update return ( ); diff --git a/frontend/src/components/meeting/MeetingNameInput.tsx b/frontend/src/components/meeting/MeetingNameInput.tsx index b8aa7dd..38a3531 100644 --- a/frontend/src/components/meeting/MeetingNameInput.tsx +++ b/frontend/src/components/meeting/MeetingNameInput.tsx @@ -1,26 +1,35 @@ import { FormEventHandler } from "react"; +import useMeetingStarted from "../../hooks/useMeetingStarted"; +import { useRoomName } from "../../hooks/useRoomName"; import "./MeetingNameInput.css"; function MeetingNameInput(props: { - roomName: string; - setName: (name: string) => void; - submit: FormEventHandler; - currentUser: string; + roomName: string; currentUser: string; }) { + + const { roomName, updateRoomName, updateAndSubmitRoomName, submitRoomName } = useRoomName() + const [_, setMeetingStarted] = useMeetingStarted() + const onInput: React.ChangeEventHandler = (event) => { - props.setName(event.target.value); + updateRoomName(event.target.value); event.preventDefault(); }; + const onSubmit: FormEventHandler = (event) => { + submitRoomName() + setMeetingStarted(true) + event.preventDefault(); + } + console.log("[Rooms] MeetingName input comp"); return (

Greetings {props.currentUser}

-
+ diff --git a/frontend/src/components/sidebar/Sidebar.css b/frontend/src/components/sidebar/Sidebar.css index 964b43e..435e1f0 100644 --- a/frontend/src/components/sidebar/Sidebar.css +++ b/frontend/src/components/sidebar/Sidebar.css @@ -25,7 +25,11 @@ max-width: 220px; } -.sidebar-hidden > .sidebar-footer { +.sidebar-hidden { + width: 0; +} + +.sidebar-hidden > .sidebar-footer > .sidebar-toggle { position: absolute; bottom: 0; } diff --git a/frontend/src/components/sidebar/Sidebar.tsx b/frontend/src/components/sidebar/Sidebar.tsx index 17d5414..251ad88 100644 --- a/frontend/src/components/sidebar/Sidebar.tsx +++ b/frontend/src/components/sidebar/Sidebar.tsx @@ -2,15 +2,20 @@ import SidebarHeader from "./SidebarHeader"; import useSidebarVisibility from "./useSidebarVisibility"; import "./Sidebar.css"; import { UsersData } from "../../background/types/roomData"; +import useMeetingStarted from "../../hooks/useMeetingStarted"; +import { useRoomName } from "../../hooks/useRoomName"; +import Chat from "../chat/Chat"; interface Props { usersData: UsersData; - updateAndSubmitRoomName: Function + sendMessage: Function } function Sidebar(props: Props) { const { sidebarVisibility, toggleSidebarVisibility, sidebarToggleText } = useSidebarVisibility(); + const [_, setMeetingStarted] = useMeetingStarted() + const { updateAndSubmitRoomName: updateAndSubmitRoomName } = useRoomName(); return (
@@ -21,13 +26,14 @@ function Sidebar(props: Props) { <>

{ - props.updateAndSubmitRoomName(roomData.roomName) + updateAndSubmitRoomName(roomData.roomName) + setMeetingStarted(true) }}> {roomData.roomName}

{roomData.participants.map((participant) => ( -
{participant.displayName}
+
{participant.displayName}
))} ); @@ -35,12 +41,13 @@ function Sidebar(props: Props) {

No room

- {props.usersData.usersWithOutRoom.map((username) => ( -
{username}
+ {props.usersData.usersWithOutRoom.map((user) => ( +
{user.name}
))}
- + +
); diff --git a/frontend/src/hooks/useAllChat.tsx b/frontend/src/hooks/useAllChat.tsx new file mode 100644 index 0000000..d75d202 --- /dev/null +++ b/frontend/src/hooks/useAllChat.tsx @@ -0,0 +1,27 @@ +import { atom, useAtom } from "jotai"; +import { atomWithReducer, useReducerAtom } from 'jotai/utils' +import { User } from "../background/types/roomData"; + +interface ChatMessage { + content: string + sender: User + +} + +export const allChatMessagesAtom = atomWithReducer([], (list: ChatMessage[], item: ChatMessage) => list.concat(item)) + + +const useAllChat = () => { + const [chatMessages, addChatMessage] = useAtom(allChatMessagesAtom) + + + return { chatMesages: chatMessages, addChatMessage } + + + +} + + +export default useAllChat + + diff --git a/frontend/src/hooks/useBackendData.ts b/frontend/src/hooks/useBackendData.ts index 4befc80..3231f4b 100644 --- a/frontend/src/hooks/useBackendData.ts +++ b/frontend/src/hooks/useBackendData.ts @@ -1,5 +1,6 @@ import { useEffect } from "react"; import { UserInfo } from "../components/jitsi/types"; +import useAllChat from "./useAllChat"; import useRoomData from "./useRoomData"; import useWebSocketConnection from "./useWebSocketConnection"; @@ -10,12 +11,15 @@ function useBackendData(userInfo: UserInfo) { const { roomData, setRoomData } = useRoomData(); + const { chatMesages, addChatMessage } = useAllChat() + useEffect(() => { onMessage((messageString) => { console.log("[Rooms] message from ws", messageString); const messageObject = JSON.parse(messageString); !!messageObject.roomsData && setRoomData(messageObject); + !!messageObject.content && addChatMessage(messageObject); return disconnect; }); }, [onMessage, setRoomData, disconnect]); diff --git a/frontend/src/hooks/useMeetingStarted.ts b/frontend/src/hooks/useMeetingStarted.ts new file mode 100644 index 0000000..2187ec7 --- /dev/null +++ b/frontend/src/hooks/useMeetingStarted.ts @@ -0,0 +1,7 @@ +import { atom, useAtom } from "jotai"; + +const meetingStarted = atom(false) + +const useMeetingStarted = () => useAtom(meetingStarted); + +export default useMeetingStarted diff --git a/frontend/src/hooks/useRoomName.ts b/frontend/src/hooks/useRoomName.ts index 1639237..dfdc685 100644 --- a/frontend/src/hooks/useRoomName.ts +++ b/frontend/src/hooks/useRoomName.ts @@ -1,7 +1,10 @@ +import { atom, useAtom } from "jotai"; import { useCallback, useState } from "react"; +const roomNameAtom = atom(getRoomNameFromUrl()) + function useRoomName() { - const [roomName, setRoomName] = useState(() => getRoomNameFromUrl()); + const [roomName, setRoomName] = useAtom(roomNameAtom) const updateRoomName = useCallback( (newName: string) => { diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index 791f139..2ed612a 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -1,3 +1,4 @@ +import { Provider } from 'jotai' import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' @@ -5,6 +6,8 @@ import './index.css' ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( - + + + , ) diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 08008e3..b3b1a74 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -543,6 +543,11 @@ is-core-module@^2.9.0: dependencies: has "^1.0.3" +jotai@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/jotai/-/jotai-2.0.3.tgz#3b67cda9f6d5feb70a14db0b842a9873aacda8b5" + integrity sha512-MMjhSPAL3RoeZD9WbObufRT2quThEAEknHHridf2ma8Ml7ZVQmUiHk0ssdbR3F0h3kcwhYqSGJ59OjhPge7RRg== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"