diff --git a/apps/meteor/client/navbar/NavBarNavigation.tsx b/apps/meteor/client/navbar/NavBarNavigation.tsx index 836fe7c453877..b90073727884b 100644 --- a/apps/meteor/client/navbar/NavBarNavigation.tsx +++ b/apps/meteor/client/navbar/NavBarNavigation.tsx @@ -1,14 +1,25 @@ import { NavBarGroup, NavBarItem, Box } from '@rocket.chat/fuselage'; import { useLayout, useRouter } from '@rocket.chat/ui-contexts'; import { FocusScope } from 'react-aria'; +import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import NavBarSearch from './NavBarSearch'; const NavbarNavigation = () => { const { t } = useTranslation(); - const { navigate } = useRouter(); + const router = useRouter(); const { isMobile } = useLayout(); + const [, setRouteTick] = useState(0); + + useEffect(() => { + return router.subscribeToRouteChange(() => { + setRouteTick((t) => t + 1); + }); + }, [router]); + + const canGoBack = router.getCanGoBack(); + const canGoForward = router.getCanGoForward(); return ( @@ -18,8 +29,20 @@ const NavbarNavigation = () => { {!isMobile && ( - navigate(-1)} icon='chevron-right' small /> - navigate(1)} icon='chevron-left' small /> + router.navigate(-1)} + icon='chevron-right' + small + disabled={!canGoBack} + /> + router.navigate(1)} + icon='chevron-left' + small + disabled={!canGoForward} + /> )} diff --git a/apps/meteor/client/router/index.tsx b/apps/meteor/client/router/index.tsx index 04083e9f89834..15badce7790cd 100644 --- a/apps/meteor/client/router/index.tsx +++ b/apps/meteor/client/router/index.tsx @@ -43,6 +43,14 @@ export class Router implements RouterContextValue { private readonly page = new Page(); + private historyIndex = 0; + + private historyMaxIndex = 0; + + private pendingHistoryDelta = 0; + + private pendingPush = false; + constructor() { this.registerRoute('*', { id: 'not-found' }); this.updateCallbacks(); @@ -166,6 +174,16 @@ export class Router implements RouterContextValue { } private refresh() { + if (this.pendingHistoryDelta !== 0) { + this.historyIndex += this.pendingHistoryDelta; + this.pendingHistoryDelta = 0; + } + if (this.pendingPush) { + this.historyIndex += 1; + this.historyMaxIndex = this.historyIndex; + this.pendingPush = false; + } + if (!this.current?.route) return; const currentContext = this.current; @@ -273,6 +291,7 @@ export class Router implements RouterContextValue { }, ) => { if (typeof toOrDelta === 'number') { + this.pendingHistoryDelta = toOrDelta; history.go(toOrDelta); return; } @@ -283,6 +302,7 @@ export class Router implements RouterContextValue { if (options?.replace) { history.replaceState(state, '', path); } else { + this.pendingPush = true; history.pushState(state, '', path); } @@ -315,6 +335,10 @@ export class Router implements RouterContextValue { readonly getRoomRoute = (roomType: RoomType, routeData: RoomRouteData) => { return { path: roomCoordinator.getRouteLink(roomType, routeData) || '/' }; }; + + readonly getCanGoBack = (): boolean => this.historyIndex > 0; + + readonly getCanGoForward = (): boolean => this.historyIndex < this.historyMaxIndex; } type RouteOptions = { diff --git a/packages/mock-providers/src/MockedRouterContext.tsx b/packages/mock-providers/src/MockedRouterContext.tsx index ddb7edf840814..b9cd1cbcd4c8b 100644 --- a/packages/mock-providers/src/MockedRouterContext.tsx +++ b/packages/mock-providers/src/MockedRouterContext.tsx @@ -16,6 +16,8 @@ export const MockedRouterContext = ({ children, router }: { children: ReactNode; navigate: () => undefined, defineRoutes: () => () => undefined, getRoomRoute: () => ({ path: '/' }), + getCanGoBack: () => false, + getCanGoForward: () => false, ...router, }} > diff --git a/packages/ui-contexts/src/RouterContext.ts b/packages/ui-contexts/src/RouterContext.ts index d826ca84f679c..d59ad01a63611 100644 --- a/packages/ui-contexts/src/RouterContext.ts +++ b/packages/ui-contexts/src/RouterContext.ts @@ -74,6 +74,8 @@ export type RouterContextValue = { ): { path: LocationPathname; }; + getCanGoBack(): boolean; + getCanGoForward(): boolean; }; export const RouterContext = createContext({ @@ -104,4 +106,6 @@ export const RouterContext = createContext({ getRoomRoute: () => { throw new Error('not implemented'); }, + getCanGoBack: () => false, + getCanGoForward: () => false, });