diff --git a/packages/desktop/src/components/User/basicUserDetailsRow.tsx b/packages/desktop/src/components/User/basicUserDetailsRow.tsx index ee7df02..ffc563a 100644 --- a/packages/desktop/src/components/User/basicUserDetailsRow.tsx +++ b/packages/desktop/src/components/User/basicUserDetailsRow.tsx @@ -1,9 +1,10 @@ +import { Avatar, Tooltip } from "antd"; + import { FaAngleRight } from "react-icons/fa"; import { ReactElement } from "react"; -import { Tooltip } from "antd"; import { User } from "@nirvana/core/models/user.model"; -export default function UserRow({ +export default function BasicUserRow({ user, rightJsx, }: { @@ -13,20 +14,19 @@ export default function UserRow({ return ( - - - - + - {user.name} + {user.name} {user.email} diff --git a/packages/desktop/src/components/header/index.tsx b/packages/desktop/src/components/header/index.tsx index 4d74024..5df5abb 100644 --- a/packages/desktop/src/components/header/index.tsx +++ b/packages/desktop/src/components/header/index.tsx @@ -153,6 +153,7 @@ export default function NirvanaHeader({ {userDetailsRes?.user?.picture && mediaSettings.mode === "audio" && ( - {sourceImages?.map((avatarSrc) => ( - + {sourceImages?.map((avatarSrc, index) => ( + ))} ); diff --git a/packages/desktop/src/components/lines/lineRow.tsx/index.tsx b/packages/desktop/src/components/lines/lineRow.tsx/index.tsx index 2de21a7..39decb9 100644 --- a/packages/desktop/src/components/lines/lineRow.tsx/index.tsx +++ b/packages/desktop/src/components/lines/lineRow.tsx/index.tsx @@ -54,8 +54,13 @@ export default function LineRow({ }} className="shadow-lg" > - {lineDetails.profilePicsLiveBroadcasters.map((avatarSrc) => ( - + {lineDetails.profilePicsLiveBroadcasters.map((avatarSrc, index) => ( + ))} ); diff --git a/packages/desktop/src/pages/nirvanaApp.tsx b/packages/desktop/src/pages/nirvanaApp.tsx index c25283b..86561e2 100644 --- a/packages/desktop/src/pages/nirvanaApp.tsx +++ b/packages/desktop/src/pages/nirvanaApp.tsx @@ -6,11 +6,32 @@ import ProtectedRoute from "../components/ProtectedRoute"; import { ReactQueryDevtools } from "react-query/devtools"; import { RecoilRoot } from "recoil"; import { Toaster } from "react-hot-toast"; +import { configure } from "react-hotkeys"; import io from "socket.io-client"; import testConnection from "@nirvana/core"; testConnection(); +configure({ + // TODO: put back to default from docs: https://github.com/greena13/react-hotkeys#Configuration + + /** + * The HTML tags that React HotKeys should ignore key events from. This only works + * if you are using the default ignoreEventsCondition function. + * @type {String[]} + */ + ignoreTags: [], + + /** + * The function used to determine whether a key event should be ignored by React + * Hotkeys. By default, keyboard events originating elements with a tag name in + * ignoreTags, or a isContentEditable property of true, are ignored. + * + * @type {Function} + */ + // ignoreEventsCondition: function, +}); + // Create a client export const queryClient = new QueryClient(); diff --git a/packages/desktop/src/pages/terminal/index.tsx b/packages/desktop/src/pages/terminal/index.tsx index dde22ba..0646db5 100644 --- a/packages/desktop/src/pages/terminal/index.tsx +++ b/packages/desktop/src/pages/terminal/index.tsx @@ -15,7 +15,7 @@ export default function NirvanaTerminal({ }: { allLines: ILineDetails[]; }) { - const [isModalVisible, setIsModalVisible] = useState(false); + const [isModalVisible, setIsModalVisible] = useState(true); const setSelectedLineId = useSetRecoilState($selectedLineId); const setDesktopMode = useSetRecoilState($desktopMode); diff --git a/packages/desktop/src/pages/terminal/newLine/index.tsx b/packages/desktop/src/pages/terminal/newLine/index.tsx index e84a624..2c0a403 100644 --- a/packages/desktop/src/pages/terminal/newLine/index.tsx +++ b/packages/desktop/src/pages/terminal/newLine/index.tsx @@ -1,7 +1,11 @@ import { Avatar, Modal } from "antd"; +import { HotKeys, KeyMap } from "react-hotkeys"; +import { useCallback, useState } from "react"; -import Search from "antd/lib/input/Search"; -import { useState } from "react"; +import BasicUserRow from "../../../components/User/basicUserDetailsRow"; +import { FiSearch } from "react-icons/fi"; +import { User } from "@nirvana/core/models"; +import { useUserSearch } from "../../../controller/index"; export default function NewLineModal({ open, @@ -10,7 +14,17 @@ export default function NewLineModal({ open: boolean; handleClose: () => void; }) { + const [selectedPeople, setSelectedPeople] = useState([]); + + const [peopleSearchValue, setPeopleSearchValue] = useState(""); + + // the actual state that goes to query...the debounced one so to speak + const [searchQuery, setSearchQuery] = useState(""); + const { refetch, data: searchRes } = useUserSearch(searchQuery); + const handleSubmit = () => { + // ensure that we don't have a one on one chat already with x person if it's one person selected + // upon success, // make sure that the list of lines updates for this client and others so that it shows this new line // select the line so that it shows up in the line details for this client @@ -23,8 +37,43 @@ export default function NewLineModal({ handleClose(); }; - const onSearch = () => { - console.log("searching for people in database"); + const onSearch = useCallback(() => { + if (peopleSearchValue) { + console.log("searching for people in database"); + setSearchQuery(peopleSearchValue); + } + }, [setSearchQuery]); + + const selectUser = useCallback( + (userToAdd: User) => { + setSelectedPeople((prevSelectedUsers) => [ + ...prevSelectedUsers, + userToAdd, + ]); + }, + [setSelectedPeople] + ); + + const unSelectUser = useCallback( + (userIdToRemove: string) => { + setSelectedPeople((prevSelectedUsers) => { + return prevSelectedUsers.filter( + (prevUser) => prevUser._id.toString() !== userIdToRemove + ); + }); + }, + [setSelectedPeople] + ); + + const keyMap: KeyMap = { + HANDLE_SEARCH: { + name: "handle search on enter", + sequence: "enter", + action: "keypress", + }, + }; + const handlers = { + HANDLE_SEARCH: onSearch, }; return ( @@ -49,68 +98,62 @@ export default function NewLineModal({ } - className={"gap-5"} + className={"flex flex-col gap-5"} > -
+ + +

People

- -
+ + - {/* search results */} -
-
- setPeopleSearchValue(e.target.value)} + placeholder="search by name or email" /> -
- Jeremy Leon - - jeremyleon@level.com - -
+ enter to search + - + {/* search results */} +
+ {searchRes?.users?.map((user) => ( + selectUser(user)}>Add} + /> + ))}
{/* selected people */} -
-

People

-
- +

Selected People

-
- Jeremy Leon - - jeremyleon@level.com - -
- - +
+ {selectedPeople.map((selectedUser) => ( + unSelectUser(selectedUser._id.toString())} + > + Remove + + } + /> + ))}
-
+

Line Name (optional)

diff --git a/yarn.lock b/yarn.lock index baa38f7..4a6883a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -79,13 +79,6 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.17.2": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72" - integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg== - dependencies: - regenerator-runtime "^0.13.4" - "@cspotcode/source-map-consumer@0.8.0": version "0.8.0" resolved "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz" @@ -469,13 +462,6 @@ dependencies: cross-spawn "^7.0.1" -"@mui/icons-material@^5.6.2": - version "5.6.2" - resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.6.2.tgz#239c40fc5841dc7c6af7d00e4e988550de170fcd" - integrity sha512-9QdI7axKuBAyaGz4mtdi7Uy1j73/thqFmEuxpJHxNC7O8ADEK1Da3t2veK2tgmsXsUlAHcAG63gg+GvWWeQNqQ== - dependencies: - "@babel/runtime" "^7.17.2" - "@next/env@12.1.4": version "12.1.4" resolved "https://registry.yarnpkg.com/@next/env/-/env-12.1.4.tgz#5af629b43075281ecd7f87938802b7cf5b67e94b"