diff --git a/apps/ui/src/components/Navbar.tsx b/apps/ui/src/components/Navbar.tsx index 642707a..7bf8509 100644 --- a/apps/ui/src/components/Navbar.tsx +++ b/apps/ui/src/components/Navbar.tsx @@ -11,16 +11,39 @@ import clsx from 'clsx' import { useTheme } from '../providers/ThemeProvider' import { useWorkspace } from '../providers/WorkspaceProvider' import AddWorkspace from './AddWorkspace' +import { EventWithPayload, ReadyEvent } from '@manasai/events' +import { useSocket } from '../providers/SocketProvider' const Navbar: React.FC = () => { const { isDarkMode, toggleTheme } = useTheme() - const { workspaces, activeWorkspace, onWorkspaceChange } = useWorkspace() + const { workspaces, activeWorkspace, onWorkspaceChange, setWorkspaces } = + useWorkspace() const [workspaceSelectorOpen, shouldOpenShowWorkspaceSelector] = useState(false) const [showAddWorkspace, shouldShowAddWorkspace] = useState(false) + const { on } = useSocket() const workspaceSelectorRef = useRef(null) + useEffect(() => { + on('READY', (event: EventWithPayload) => { + const { workspaces } = event.payload as ReadyEvent['payload'] + setWorkspaces(workspaces) + + if (workspaces.length === 1) { + onWorkspaceChange(workspaces[0].id) + return + } + + if (workspaces.length === 0) { + shouldShowAddWorkspace(true) + return + } + + shouldOpenShowWorkspaceSelector(true) + }) + }, [on, setWorkspaces, onWorkspaceChange, workspaceSelectorRef]) + useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if ( diff --git a/apps/ui/src/providers/SocketProvider.tsx b/apps/ui/src/providers/SocketProvider.tsx index 56d6c6f..3ebeec5 100644 --- a/apps/ui/src/providers/SocketProvider.tsx +++ b/apps/ui/src/providers/SocketProvider.tsx @@ -8,12 +8,17 @@ import { import { ConnectedEvent, DisconnectedEvent, - EventWithPayload + EventWithPayload, + EventTypes } from '@manasai/events' import ShortUniqueId from 'short-unique-id' interface SocketContextProps { emit: (event: EventWithPayload) => void + on: ( + event: EventTypes, + listener: (event: EventWithPayload) => void + ) => void } interface SocketProviderProps { @@ -26,6 +31,9 @@ const DEVICE_TOKEN_KEY = 'device_token' const SocketContext = createContext({ emit: () => { throw new Error('SocketProvider is not initialized') + }, + on: () => { + throw new Error('SocketProvider is not initialized') } }) @@ -50,6 +58,22 @@ export const SocketProvider: React.FC = ({ [client, deviceToken] ) + const on = useCallback( + ( + event: EventTypes, + listener: (event: EventWithPayload) => void + ) => { + client.addEventListener('message', (e: MessageEvent) => { + const data = JSON.parse(e.data) as EventWithPayload + + if (data.type !== event) return + + listener(data) + }) + }, + [client] + ) + useEffect(() => { if (!deviceToken) { let deviceId = localStorage.getItem(DEVICE_TOKEN_KEY) @@ -95,7 +119,9 @@ export const SocketProvider: React.FC = ({ }, [client, emit, deviceToken]) return ( - {children} + + {children} + ) } diff --git a/apps/ui/src/providers/WorkspaceProvider.tsx b/apps/ui/src/providers/WorkspaceProvider.tsx index cf0bab5..a5e596d 100644 --- a/apps/ui/src/providers/WorkspaceProvider.tsx +++ b/apps/ui/src/providers/WorkspaceProvider.tsx @@ -7,6 +7,7 @@ interface WorkspaceContextProps { addWorkspace: (workspace: Workspace) => void onWorkspaceChange: (id: string) => void isNameTaken: (name: string) => boolean + setWorkspaces: (workspaces: Workspace[]) => void } interface WorkspaceProviderProps { @@ -17,7 +18,8 @@ const WorkspaceContext = createContext({ workspaces: [], addWorkspace: () => null, onWorkspaceChange: () => null, - isNameTaken: () => false + isNameTaken: () => false, + setWorkspaces: () => null }) export const WorkspaceProvider: React.FC = ({ @@ -45,7 +47,8 @@ export const WorkspaceProvider: React.FC = ({ workspaces, addWorkspace, onWorkspaceChange, - isNameTaken + isNameTaken, + setWorkspaces } if (activeWorkspaceId) {