diff --git a/src/App.tsx b/src/App.tsx index 7b72a12..29fa918 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -15,6 +15,7 @@ import PrivateRoute from '@educt/components/PrivateRoute'; import PublicRoute from '@educt/components/PublicRoute'; import { useSocketEvent } from './hooks/useSocketEvent'; import { SocketContext } from './contexts'; +import { UserOnlineListType, UserSeesionType } from './types'; const App = () => { const { @@ -26,16 +27,16 @@ const App = () => { useSocketEvent('connect', () => console.info('[WebSocket]: Connected.')); useSocketEvent('disconnect', () => console.info('[WebSocket]: Disconnected.')); useSocketEvent('connect_error', err => console.error(err)); - useSocketEvent('user:session', data => { + useSocketEvent('user:session', data => { if (socket) { - const { sessionId, userId } = data; - socket.auth = { sessionId }; - window.localStorage.setItem('sessionId', sessionId); - // TODO fix types - socket.userId = userId; + const { sessionId } = data; + if (sessionId) { + socket.auth = { sessionId }; + window.localStorage.setItem('sessionId', sessionId); + } } }); - useSocketEvent('user:online', online => onlineStore.loadOnline(online)); + useSocketEvent('user:online', online => onlineStore.loadOnline(online)); return ( diff --git a/src/components/Chat/Sidebar/Users/Users.tsx b/src/components/Chat/Sidebar/Users/Users.tsx index 55449ca..6f7e9f6 100644 --- a/src/components/Chat/Sidebar/Users/Users.tsx +++ b/src/components/Chat/Sidebar/Users/Users.tsx @@ -17,10 +17,13 @@ const Wrapper: React.FC = ({ children }) => { const Users: React.FC = observer(() => { const { data: users } = useFetchUsers(); - const { onlineStore } = useRootStore(); + const { + userStore: { me }, + onlineStore, + } = useRootStore(); const { search } = useChatContext(); - if (users === null) + if (users === null || me === null) return ( @@ -28,20 +31,31 @@ const Users: React.FC = observer(() => { ); - const filtered = (!search ? users : users.filter(u => u.fullname.toLocaleLowerCase().includes(search))).sort(user => - !onlineStore.isOnline(user.id) ? 1 : -1 - ); + const filtered = (!search ? users : users.filter(u => u.fullname.toLocaleLowerCase().includes(search))) + .concat() + .sort(u => (onlineStore.isOnline(u.id) ? -1 : 1)); + const isEmpty = filtered.length === 0; return ( + {/* Favorites */} + + + + + + {/* User list */} {!isEmpty ? ( - filtered.map(user => ( - - - - - )) + filtered.map( + user => + user.id !== me.id && ( + + + + + ) + ) ) : ( diff --git a/src/components/Chat/Window/Window.tsx b/src/components/Chat/Window/Window.tsx index 0ab74f4..319041d 100644 --- a/src/components/Chat/Window/Window.tsx +++ b/src/components/Chat/Window/Window.tsx @@ -17,7 +17,7 @@ import { import { MdOutlineChat, MdSend } from 'react-icons/md'; import { MessageList } from './Message'; import { SocketContext } from '@educt/contexts'; -import { MessageType } from '@educt/types'; +import { HistoryMessageType, MessageType } from '@educt/types'; import { UserServiceInstance } from '@educt/services'; import { IUser } from '@educt/interfaces'; import LoadingList from '@educt/components/LoadingList'; @@ -120,11 +120,10 @@ const Window: React.FC = props => { } }, [chatId]); - // TODO add types for this event /** * Event on accept new messages */ - useSocketEvent('chat:message', data => { + useSocketEvent('chat:message', data => { const user = onlineStore.getUser(data.from); if (user) { @@ -134,6 +133,18 @@ const Window: React.FC = props => { */ if (data.to === data.from) return; + /** + * Notify user about new message + */ + // toast({ + // title: `${user.userName}`, + // description: data.content, + // variant: 'left-accent', + // position: 'bottom-right', + // status: 'info', + // duration: 5000, + // }); + const message: MessageType = { content: data.content, userName: user.userName, diff --git a/src/contexts/index.ts b/src/contexts/index.ts index 3b545c7..c158cf3 100644 --- a/src/contexts/index.ts +++ b/src/contexts/index.ts @@ -2,10 +2,11 @@ import { createContext } from 'react'; import { ChangeEmailPageContextType, CoursesPageContextType, UsersPageContextType } from '@educt/types'; import RootStore from '../stores/RootStore'; import { Socket } from 'socket.io-client'; +import { ClientToServerEvents, ServerToClientEvents } from '@educt/interfaces'; export const StoreContext = createContext(undefined); -export const SocketContext = createContext<{ socket: Socket | null }>({ +export const SocketContext = createContext<{ socket: Socket | null }>({ socket: null, }); diff --git a/src/hooks/useSocketEvent.ts b/src/hooks/useSocketEvent.ts index 0a81121..a14a276 100644 --- a/src/hooks/useSocketEvent.ts +++ b/src/hooks/useSocketEvent.ts @@ -1,7 +1,7 @@ import { useContext, useEffect } from 'react'; import { SocketContext } from '@educt/contexts'; -export const useSocketEvent = (event: string, callback: (...args: unknown[]) => void) => { +export const useSocketEvent = (event: string, callback: (data: T) => void) => { const { socket } = useContext(SocketContext); useEffect(() => { diff --git a/src/types/index.d.ts b/src/types/index.d.ts index d4a4bd4..a741313 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -76,6 +76,13 @@ export type HistoryMessageType = { time: string; }; +export type UserSeesionType = { + sessionId: string | undefined; + userId: string | undefined; +}; + +export type UserOnlineListType = [string, { userId: string; userName: string }][]; + /** * Change email page context */