From 49be9ee6bd6e2ae8dfdca8d62676fa4931c5592c Mon Sep 17 00:00:00 2001 From: Sean Parsons Date: Thu, 11 Jul 2024 14:26:03 +0100 Subject: [PATCH] fix(canvas) Better Remix Reset Handling. - Removed handling of reset triggering from `editorDispatchClosingOut`. - Added `useRouteError` wrapper to `createBuiltInDependenciesList`. - `reactRouterErrorTriggeredReset` now returns a `RESET_CANVAS` action as required. - Incoming updates from the code editor can now trigger the canvas reset. --- .../src/components/editor/store/dispatch.tsx | 24 ++++--------------- .../built-in-dependencies-list.ts | 3 ++- .../package-manager/canvas-safe-remix.tsx | 11 ++++++++- .../src/core/shared/runtime-report-logs.tsx | 12 ++++++++++ editor/src/core/vscode/vscode-bridge.ts | 9 ++++--- 5 files changed, 34 insertions(+), 25 deletions(-) diff --git a/editor/src/components/editor/store/dispatch.tsx b/editor/src/components/editor/store/dispatch.tsx index 5082462e3085..c989c2e97b05 100644 --- a/editor/src/components/editor/store/dispatch.tsx +++ b/editor/src/components/editor/store/dispatch.tsx @@ -84,7 +84,10 @@ import { createModuleEvaluator, isComponentDescriptorFile, } from '../../../core/property-controls/property-controls-local' -import { setReactRouterErrorHasBeenLogged } from '../../../core/shared/runtime-report-logs' +import { + hasReactRouterErrorBeenLogged, + setReactRouterErrorHasBeenLogged, +} from '../../../core/shared/runtime-report-logs' import type { PropertyControlsInfo } from '../../custom-code/code-file' import { getFilePathMappings } from '../../../core/model/project-file-utils' @@ -495,18 +498,6 @@ export function editorDispatchActionRunner( return result } -function reactRouterErrorTriggeredReset( - editor: EditorState, - reactRouterErrorPreviouslyLogged: boolean, -): EditorState { - if (reactRouterErrorPreviouslyLogged) { - setReactRouterErrorHasBeenLogged(false) - return UPDATE_FNS.RESET_CANVAS(EditorActions.resetCanvas(), editor) - } else { - return editor - } -} - export function editorDispatchClosingOut( boundDispatch: EditorDispatch, dispatchedActions: readonly EditorAction[], @@ -728,13 +719,6 @@ export function editorDispatchClosingOut( filesModifiedByAnotherUser: updatedFilesModifiedByElsewhere, }, } - - if (filesChanged.length > 0) { - finalStoreV1Final.unpatchedEditor = reactRouterErrorTriggeredReset( - finalStoreV1Final.unpatchedEditor, - reactRouterErrorPreviouslyLogged, - ) - } } const shouldUpdatePreview = diff --git a/editor/src/core/es-modules/package-manager/built-in-dependencies-list.ts b/editor/src/core/es-modules/package-manager/built-in-dependencies-list.ts index 62e45a8c0d1c..48e7cdc0f4d5 100644 --- a/editor/src/core/es-modules/package-manager/built-in-dependencies-list.ts +++ b/editor/src/core/es-modules/package-manager/built-in-dependencies-list.ts @@ -12,7 +12,7 @@ import * as TTYStub from './node-builtin-shims/tty-stub' import * as UUIUI from '../../../uuiui' import * as UUIUIDeps from '../../../uuiui-deps' import * as RemixServerBuild from './built-in-third-party-dependencies/remix-server-build' -import { SafeLink, SafeOutlet } from './canvas-safe-remix' +import { SafeLink, SafeOutlet, useErrorRecordingRouteError } from './canvas-safe-remix' import { UtopiaApiGroup } from './group-component' import utopiaAPIPackageJSON from '../../../../../utopia-api/package.json' @@ -98,6 +98,7 @@ export function createBuiltInDependenciesList( ...RemixRunReact, Link: SafeLink, Outlet: SafeOutlet, + useRouteError: useErrorRecordingRouteError, }, editorPackageJSON.dependencies['@remix-run/react'], ), diff --git a/editor/src/core/es-modules/package-manager/canvas-safe-remix.tsx b/editor/src/core/es-modules/package-manager/canvas-safe-remix.tsx index a02044793f89..f34c3f5dcd16 100644 --- a/editor/src/core/es-modules/package-manager/canvas-safe-remix.tsx +++ b/editor/src/core/es-modules/package-manager/canvas-safe-remix.tsx @@ -1,11 +1,12 @@ import * as React from 'react' -import { Link, Outlet } from '@remix-run/react' +import { Link, Outlet, useRouteError } from '@remix-run/react' import type { LinkProps } from '@remix-run/react' import { useInRouterContext, Router } from 'react-router' import type { Navigator } from 'react-router' import { OutletPathContext } from '../../../components/canvas/remix/remix-utils' import { UTOPIA_PATH_KEY } from '../../model/utopia-constants' import * as EP from '../../shared/element-path' +import { setReactRouterErrorHasBeenLogged } from '../../../core/shared/runtime-report-logs' const dummyNavigator: Navigator = { createHref: () => '', @@ -36,6 +37,14 @@ export const SafeLink: typeof Link = React.forwardRef = [] @@ -89,6 +91,16 @@ export function setReactRouterErrorHasBeenLogged(value: boolean): void { reactRouterErrorLogged = value } +export function reactRouterErrorTriggeredReset(): Array { + const reactRouterErrorPreviouslyLogged = hasReactRouterErrorBeenLogged() + if (reactRouterErrorPreviouslyLogged) { + setReactRouterErrorHasBeenLogged(false) + return [EditorActions.resetCanvas()] + } else { + return [] + } +} + export interface OverlayError { error: FancyError unhandledRejection: boolean diff --git a/editor/src/core/vscode/vscode-bridge.ts b/editor/src/core/vscode/vscode-bridge.ts index 51cacfae677c..b03135cb0fa9 100644 --- a/editor/src/core/vscode/vscode-bridge.ts +++ b/editor/src/core/vscode/vscode-bridge.ts @@ -32,6 +32,7 @@ import { } from 'utopia-vscode-common' import type { ProjectContentTreeRoot } from '../../components/assets' import { walkContentsTree } from '../../components/assets' +import type { EditorAction } from '../../components/editor/action-types' import { EditorDispatch } from '../../components/editor/action-types' import type { EditorState } from '../../components/editor/store/editor-state' import { getHighlightBoundsForElementPath } from '../../components/editor/store/editor-state' @@ -44,7 +45,6 @@ import type { ProjectFile, } from '../shared/project-file-types' import { assertNever, NO_OP } from '../shared/utils' -import type { FromVSCodeAction } from '../../components/editor/actions/actions-from-vscode' import { deleteFileFromVSCode, hideVSCodeLoadingScreen, @@ -56,6 +56,7 @@ import { updateConfigFromVSCode, updateFromCodeEditor, } from '../../components/editor/actions/actions-from-vscode' +import { reactRouterErrorTriggeredReset } from '../shared/runtime-report-logs' export const VSCODE_EDITOR_IFRAME_ID = 'vscode-editor' @@ -97,7 +98,7 @@ let registeredHandlers: (messageEvent: MessageEvent) => void = NO_OP export function initVSCodeBridge( projectContents: ProjectContentTreeRoot, - dispatch: (actions: Array) => void, + dispatch: (actions: Array) => void, openFilePath: string | null, ) { let loadingScreenHidden = false @@ -163,7 +164,9 @@ export function initVSCodeBridge( filePath, fileContent.unsavedContent ?? fileContent.content, ) - dispatch([updateAction, requestLintAction]) + let actionsToDispatch: Array = [updateAction, requestLintAction] + actionsToDispatch.push(...reactRouterErrorTriggeredReset()) + dispatch(actionsToDispatch) } else if (isVSCodeFileDelete(data)) { dispatch([deleteFileFromVSCode(data.filePath)]) } else if (isIndexedDBFailure(data)) {