diff --git a/packages/suite/src/components/suite/Preloader/Preloader.tsx b/packages/suite/src/components/suite/Preloader/Preloader.tsx index 86d61a1a38e..e90009a06ef 100644 --- a/packages/suite/src/components/suite/Preloader/Preloader.tsx +++ b/packages/suite/src/components/suite/Preloader/Preloader.tsx @@ -26,6 +26,7 @@ import { ViewOnlyPromo } from 'src/views/view-only/ViewOnlyPromo'; import { DatabaseUpgradeModal } from './DatabaseUpgradeModal'; import { InitialLoading } from './InitialLoading'; import { RouterAppWithParams } from '../../../constants/suite/routes'; +import { Redirect } from '../../../support/suite/Redirect'; import { PrerequisitesGuide } from '../PrerequisitesGuide/PrerequisitesGuide'; import { DeviceCompromised } from '../SecurityCheck/DeviceCompromised'; import { useReportDeviceCompromised } from '../SecurityCheck/useReportDeviceCompromised'; @@ -40,12 +41,17 @@ const ROUTES_TO_SKIP_FIRMWARE_CHECK: RouterAppWithParams['app'][] = [ 'firmware-custom', ]; -const getFullscreenApp = (route: AppState['router']['route']): FC | undefined => { +const RedirectToDashboard = () => ; + +const getFullscreenApp = ( + route: AppState['router']['route'], + isInitialRun: boolean, +): FC | undefined => { switch (route?.app) { case 'start': - return SuiteStart; + return isInitialRun ? SuiteStart : RedirectToDashboard; case 'onboarding': - return Onboarding; + return isInitialRun ? Onboarding : RedirectToDashboard; default: return undefined; } @@ -118,7 +124,7 @@ export const Preloader = ({ children }: PropsWithChildren) => { // TODO: murder the fullscreen app logic, there must be a better way // i don't like how it's not clear which layout is used // and that the prerequisite screen is handled multiple times - const FullscreenApp = getFullscreenApp(router.route); + const FullscreenApp = getFullscreenApp(router.route, initialRun); if (FullscreenApp !== undefined) { return ; } diff --git a/packages/suite/src/support/suite/Redirect.tsx b/packages/suite/src/support/suite/Redirect.tsx new file mode 100644 index 00000000000..0ee2bdf80f8 --- /dev/null +++ b/packages/suite/src/support/suite/Redirect.tsx @@ -0,0 +1,26 @@ +import { useLayoutEffect } from 'react'; + +import { Route } from '@suite-common/suite-types'; + +import * as routerActions from '../../actions/suite/routerActions'; +import { useDispatch } from '../../hooks/suite'; + +type RedirectProps = { + to: Route['name']; +}; + +/** + * Component that does nothing else but trigger redirection. + * This must be used instead of Redirect from react-router-dom, because we need redux state synced with react-router state! + * @param to destination route name, as named in our route config (not necessarily the actual location.pathname) + */ +export const Redirect = ({ to }: RedirectProps) => { + const dispatch = useDispatch(); + + // useLayoutEffect rather than useEffect to prevent flickering (rendering null while redirect is in progress) + useLayoutEffect(() => { + dispatch(routerActions.goto(to)); + }, [dispatch, to]); + + return null; +};