diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 2816a36f4fa5..0652827a898c 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -14,6 +14,6 @@ Describe the fix you have made as succinctly as possible.
I hereby swear that:
- [ ] I opened a hydrogen project and it loaded
-- [ ] I could navigate to various routes in Preview mode
+- [ ] I could navigate to various routes in Play mode
Fixes #[ticket_number] (<< pls delete this line if it's not relevant)
diff --git a/editor/src/components/canvas/stored-layout.ts b/editor/src/components/canvas/stored-layout.ts
index 595716a5efd2..bb2426034158 100644
--- a/editor/src/components/canvas/stored-layout.ts
+++ b/editor/src/components/canvas/stored-layout.ts
@@ -24,12 +24,7 @@ export const GridPanelsNumberOfRows = 12
export type Menu = 'inspector' | 'navigator'
export type Pane = 'code-editor'
-export const allMenusAndPanels: Array
= [
- 'navigator',
- 'code-editor',
- 'inspector',
- // 'preview', // Does this exist?
-]
+export const allMenusAndPanels: Array = ['navigator', 'code-editor', 'inspector']
export interface GridPanelData {
panel: StoredPanel
diff --git a/editor/src/components/common/actions/index.ts b/editor/src/components/common/actions/index.ts
index b58160a0e349..9272ebc26903 100644
--- a/editor/src/components/common/actions/index.ts
+++ b/editor/src/components/common/actions/index.ts
@@ -1,5 +1,3 @@
-export type PreviewPanel = 'preview'
-
export type LeftMenuPanel =
| 'filebrowser'
| 'dependencylist'
@@ -22,10 +20,9 @@ export type EditorPanel =
| CenterPanel
| CodeEditorPanel
| InspectorPanel
- | PreviewPanel
| NavigatorPanel
-export type EditorPane = 'leftmenu' | 'center' | 'inspector' | 'preview' | 'rightmenu'
+export type EditorPane = 'leftmenu' | 'center' | 'inspector' | 'rightmenu'
export function paneForPanel(panel: EditorPanel | null): EditorPane | null {
switch (panel) {
@@ -55,8 +52,6 @@ export function paneForPanel(panel: EditorPanel | null): EditorPane | null {
return 'rightmenu'
case 'codeEditor':
return 'center'
- case 'preview':
- return 'preview'
default:
const _exhaustiveCheck: never = panel
throw new Error(`Unhandled panel ${panel}`)
diff --git a/editor/src/components/editor/action-types.ts b/editor/src/components/editor/action-types.ts
index 94190c524369..757fa6769497 100644
--- a/editor/src/components/editor/action-types.ts
+++ b/editor/src/components/editor/action-types.ts
@@ -602,11 +602,6 @@ export interface SetProjectDescription {
description: string
}
-export interface UpdatePreviewConnected {
- action: 'UPDATE_PREVIEW_CONNECTED'
- connected: boolean
-}
-
export interface AlignSelectedViews {
action: 'ALIGN_SELECTED_VIEWS'
alignment: Alignment
@@ -628,10 +623,6 @@ export interface SetCursorOverlay {
cursor: CSSCursor | null
}
-export interface SendPreviewModel {
- action: 'SEND_PREVIEW_MODEL'
-}
-
export interface UpdateFilePath {
action: 'UPDATE_FILE_PATH'
oldPath: string
@@ -1278,13 +1269,11 @@ export type EditorAction =
| OpenCodeEditor
| SetProjectName
| SetProjectDescription
- | UpdatePreviewConnected
| AlignSelectedViews
| DistributeSelectedViews
| SetCursorOverlay
| DuplicateSpecificElements
| UpdateDuplicationState
- | SendPreviewModel
| UpdateFilePath
| UpdateRemixRoute
| OpenCodeEditorFile
diff --git a/editor/src/components/editor/actions/action-creators.ts b/editor/src/components/editor/actions/action-creators.ts
index fa9ad247a85b..723c48306606 100644
--- a/editor/src/components/editor/actions/action-creators.ts
+++ b/editor/src/components/editor/actions/action-creators.ts
@@ -92,7 +92,6 @@ import type {
SaveImageSwitchMode,
SelectAllSiblings,
SelectComponents,
- SendPreviewModel,
SetAspectRatioLock,
SetCanvasFrames,
SetCodeEditorBuildErrors,
@@ -144,7 +143,6 @@ import type {
UpdateKeysPressed,
UpdateNodeModulesContents,
UpdatePackageJson,
- UpdatePreviewConnected,
UpdatePropertyControlsInfo,
CloseDesignerFile,
SetFocusedElement,
@@ -974,13 +972,6 @@ export function setProjectDescription(projectDescription: string): SetProjectDes
}
}
-export function updatePreviewConnected(connected: boolean): UpdatePreviewConnected {
- return {
- action: 'UPDATE_PREVIEW_CONNECTED',
- connected: connected,
- }
-}
-
export function alignSelectedViews(alignment: Alignment): AlignSelectedViews {
return {
action: 'ALIGN_SELECTED_VIEWS',
@@ -1006,12 +997,6 @@ export function showContextMenu(
}
}
-export function sendPreviewModel(): SendPreviewModel {
- return {
- action: 'SEND_PREVIEW_MODEL',
- }
-}
-
export function updateFilePath(oldPath: string, newPath: string): UpdateFilePath {
return {
action: 'UPDATE_FILE_PATH',
diff --git a/editor/src/components/editor/actions/action-utils.ts b/editor/src/components/editor/actions/action-utils.ts
index 6b4e6b7c33ec..a695b30ad16a 100644
--- a/editor/src/components/editor/actions/action-utils.ts
+++ b/editor/src/components/editor/actions/action-utils.ts
@@ -62,8 +62,6 @@ export function isTransientAction(action: EditorAction): boolean {
case 'SET_PROJECT_ID':
case 'SET_CODE_EDITOR_VISIBILITY':
case 'OPEN_CODE_EDITOR':
- case 'UPDATE_PREVIEW_CONNECTED':
- case 'SEND_PREVIEW_MODEL':
case 'CLOSE_DESIGNER_FILE':
case 'UPDATE_CODE_RESULT_CACHE':
case 'SET_CODE_EDITOR_BUILD_ERRORS':
diff --git a/editor/src/components/editor/actions/actions.tsx b/editor/src/components/editor/actions/actions.tsx
index dc5a7ed77b80..7baaa1b2848c 100644
--- a/editor/src/components/editor/actions/actions.tsx
+++ b/editor/src/components/editor/actions/actions.tsx
@@ -239,7 +239,6 @@ import type {
ScrollToElement,
SelectAllSiblings,
SelectComponents,
- SendPreviewModel,
SetAspectRatioLock,
SetCanvasFrames,
SetCodeEditorBuildErrors,
@@ -304,7 +303,6 @@ import type {
UpdateMouseButtonsPressed,
UpdateNodeModulesContents,
UpdatePackageJson,
- UpdatePreviewConnected,
UpdateProjectContents,
UpdatePropertyControlsInfo,
WrapInElement,
@@ -1000,10 +998,6 @@ export function restoreEditorState(
formulaBarMode: desiredEditor.topmenu.formulaBarMode,
formulaBarFocusCounter: currentEditor.topmenu.formulaBarFocusCounter,
},
- preview: {
- visible: currentEditor.preview.visible,
- connected: currentEditor.preview.connected,
- },
home: {
visible: currentEditor.home.visible,
},
@@ -2966,14 +2960,6 @@ export const UPDATE_FNS = {
visible: action.visible,
},
}
- case 'preview':
- return {
- ...editor,
- preview: {
- ...editor.preview,
- visible: action.visible,
- },
- }
case 'codeEditor':
return {
...editor,
@@ -3069,14 +3055,6 @@ export const UPDATE_FNS = {
visible: !editor.inspector.visible,
},
}
- case 'preview':
- return {
- ...editor,
- preview: {
- ...editor.preview,
- visible: !editor.preview.visible,
- },
- }
case 'projectsettings':
return {
...editor,
@@ -3743,12 +3721,6 @@ export const UPDATE_FNS = {
projectDescription: action.description,
}
},
-
- UPDATE_PREVIEW_CONNECTED: (action: UpdatePreviewConnected, editor: EditorModel): EditorModel => {
- return produce(editor, (editorState) => {
- editorState.preview.connected = action.connected
- })
- },
ALIGN_SELECTED_VIEWS: (action: AlignSelectedViews, editor: EditorModel): EditorModel => {
return alignOrDistributeSelectedViews(editor, action.alignment)
},
@@ -3763,9 +3735,6 @@ export const UPDATE_FNS = {
openMenu(action.menuName, action.event)
return editor
},
- SEND_PREVIEW_MODEL: (action: SendPreviewModel, editor: EditorModel): EditorModel => {
- return editor
- },
UPDATE_FILE_PATH: (
action: UpdateFilePath,
editor: EditorModel,
@@ -6398,10 +6367,6 @@ export async function load(
)
}
-export function isSendPreviewModel(action: any): action is SendPreviewModel {
- return action != null && (action as SendPreviewModel).action === 'SEND_PREVIEW_MODEL'
-}
-
function saveFileInProjectContents(
projectContents: ProjectContentTreeRoot,
filePath: string,
diff --git a/editor/src/components/editor/editor-component.tsx b/editor/src/components/editor/editor-component.tsx
index c87d105ed4d7..e4d1cfacfe0b 100644
--- a/editor/src/components/editor/editor-component.tsx
+++ b/editor/src/components/editor/editor-component.tsx
@@ -39,7 +39,6 @@ import { ConfirmDeleteDialog } from '../filebrowser/confirm-delete-dialog'
import { ConfirmOverwriteDialog } from '../filebrowser/confirm-overwrite-dialog'
import { ConfirmRevertDialog } from '../filebrowser/confirm-revert-dialog'
import { ConfirmRevertAllDialog } from '../filebrowser/confirm-revert-all-dialog'
-import { PreviewColumn } from '../preview/preview-pane'
import * as EditorActions from './actions/action-creators'
import { FatalIndexedDBErrorComponent } from './fatal-indexeddb-error-component'
import { editorIsTarget, handleKeyDown, handleKeyUp } from './global-shortcuts'
@@ -377,12 +376,6 @@ export const EditorComponentInner = React.memo((props: EditorProps) => {
(store) => store.editor.id,
'EditorComponentInner projectId',
)
- const previewVisible = useEditorState(
- Substores.restOfEditor,
- (store) => store.editor.preview.visible,
- 'EditorComponentInner previewVisible',
- )
-
const yDoc = useEditorState(
Substores.restOfStore,
(store) => store.collaborativeEditingSupport.session?.mergeDoc,
@@ -417,11 +410,6 @@ export const EditorComponentInner = React.memo((props: EditorProps) => {
}
}, [projectName, projectId, forking])
- const onClosePreview = React.useCallback(
- () => dispatch([EditorActions.setPanelVisibility('preview', false)]),
- [dispatch],
- )
-
const startDragInsertion = React.useCallback(
(event: React.DragEvent) => {
const draggedTypes = event.nativeEvent?.dataTransfer?.types
@@ -524,37 +512,6 @@ export const EditorComponentInner = React.memo((props: EditorProps) => {
{/* insert more columns here */}
-
- {previewVisible ? (
-
-
- }
- onClose={onClosePreview}
- />
-
-
-
- ) : null}
diff --git a/editor/src/components/editor/preview-report-handler.ts b/editor/src/components/editor/preview-report-handler.ts
deleted file mode 100644
index f7bfd86fa05b..000000000000
--- a/editor/src/components/editor/preview-report-handler.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import type { EditorDispatch } from './action-types'
-import { updatePreviewConnected } from './actions/action-creators'
-
-export const InternalPreviewTimeout = 500
-
-let lastReportFromPreviewTS = 0
-let timeout = 0
-let intervalId: number
-
-export function previewIsAlive(newTimeout: number) {
- timeout = newTimeout
- lastReportFromPreviewTS = Date.now()
-}
-
-export function handlePreviewDisconnected() {
- lastReportFromPreviewTS = 0
-}
-
-export function startPreviewConnectedMonitoring(dispatch: EditorDispatch) {
- let previousPreviewConnected: boolean
-
- window.clearInterval(intervalId)
- intervalId = window.setInterval(() => {
- const stillConnected =
- lastReportFromPreviewTS > 0 && Date.now() - lastReportFromPreviewTS < timeout
- if (stillConnected !== previousPreviewConnected) {
- dispatch([updatePreviewConnected(stillConnected)], 'everyone')
- }
- previousPreviewConnected = stillConnected
- }, 200)
-}
diff --git a/editor/src/components/editor/store/dispatch.tsx b/editor/src/components/editor/store/dispatch.tsx
index b4c4b2153a6d..c0e1a99e29a6 100644
--- a/editor/src/components/editor/store/dispatch.tsx
+++ b/editor/src/components/editor/store/dispatch.tsx
@@ -6,7 +6,6 @@ import { runLocalNavigatorAction } from '../../../templates/editor-navigator'
import { optionalDeepFreeze } from '../../../utils/deep-freeze'
import type { CanvasAction } from '../../canvas/canvas-types'
import type { LocalNavigatorAction } from '../../navigator/actions'
-import { PreviewIframeId, projectContentsUpdateMessage } from '../../preview/preview-pane'
import type { EditorAction, EditorDispatch, UpdateMetadataInEditorState } from '../action-types'
import { isLoggedIn } from '../action-types'
import {
@@ -46,7 +45,7 @@ import { isBrowserEnvironment } from '../../../core/shared/utils'
import type { UiJsxCanvasContextData } from '../../canvas/ui-jsx-canvas'
import type { ProjectContentTreeRoot } from '../../assets'
import { treeToContents } from '../../assets'
-import { isSendPreviewModel, restoreDerivedState, UPDATE_FNS } from '../actions/actions'
+import { restoreDerivedState, UPDATE_FNS } from '../actions/actions'
import { getTransitiveReverseDependencies } from '../../../core/shared/project-contents-dependencies'
import {
reduxDevtoolsSendActions,
@@ -309,26 +308,6 @@ function processActions(
}, working)
}
-export function updateEmbeddedPreview(
- modelId: string | null,
- projectContents: ProjectContentTreeRoot,
-): void {
- const embeddedPreviewElement = document.getElementById(PreviewIframeId)
- if (embeddedPreviewElement != null) {
- const embeddedPreviewIframe = embeddedPreviewElement as any as HTMLIFrameElement
- const contentWindow = embeddedPreviewIframe.contentWindow
- if (contentWindow != null) {
- try {
- contentWindow.postMessage(projectContentsUpdateMessage(projectContents), '*')
- } catch (exception) {
- // Don't nuke the editor if there's an exception posting the message.
- // This can happen if a value can't be cloned when posted.
- console.error('Error updating preview.', exception)
- }
- }
- }
-}
-
function maybeRequestModelUpdate(
projectContents: ProjectContentTreeRoot,
workers: UtopiaTsWorkers,
@@ -525,7 +504,6 @@ export function editorDispatchClosingOut(
})
const anyWorkerUpdates = checkAnyWorkerUpdates(dispatchedActions)
const anyUndoOrRedo = dispatchedActions.some(isUndoOrRedo)
- const anySendPreviewModel = dispatchedActions.some(isSendPreviewModel)
// The FINISH_CHECKPOINT_TIMER action effectively overrides the case where nothing changed,
// as it's likely that action on it's own didn't change anything, but the actions that paired with
@@ -723,13 +701,6 @@ export function editorDispatchClosingOut(
}
}
- const shouldUpdatePreview =
- anySendPreviewModel ||
- frozenEditorState.projectContents !== storedState.unpatchedEditor.projectContents
- if (shouldUpdatePreview) {
- updateEmbeddedPreview(frozenEditorState.id, frozenEditorState.projectContents)
- }
-
if (frozenEditorState.id != null && frozenEditorState.id != storedState.unpatchedEditor.id) {
storedState.workers.initWatchdogWorker(frozenEditorState.id)
}
diff --git a/editor/src/components/editor/store/editor-state.ts b/editor/src/components/editor/store/editor-state.ts
index d6090a49e8bb..633fe15505e7 100644
--- a/editor/src/components/editor/store/editor-state.ts
+++ b/editor/src/components/editor/store/editor-state.ts
@@ -1089,18 +1089,6 @@ export function editorStateTopMenu(
}
}
-export interface EditorStatePreview {
- visible: boolean
- connected: boolean
-}
-
-export function editorStatePreview(visible: boolean, connected: boolean): EditorStatePreview {
- return {
- visible: visible,
- connected: connected,
- }
-}
-
export interface EditorStateHome {
visible: boolean
}
@@ -1446,7 +1434,6 @@ export interface EditorState {
projectSettings: EditorStateProjectSettings
navigator: NavigatorState
topmenu: EditorStateTopMenu
- preview: EditorStatePreview
home: EditorStateHome
lastUsedFont: FontSettings | null
modal: ModalDialog | null
@@ -1530,7 +1517,6 @@ export function editorState(
projectSettings: EditorStateProjectSettings,
editorStateNavigator: NavigatorState,
topmenu: EditorStateTopMenu,
- preview: EditorStatePreview,
home: EditorStateHome,
lastUsedFont: FontSettings | null,
modal: ModalDialog | null,
@@ -1615,7 +1601,6 @@ export function editorState(
projectSettings: projectSettings,
navigator: editorStateNavigator,
topmenu: topmenu,
- preview: preview,
home: home,
lastUsedFont: lastUsedFont,
modal: modal,
@@ -2687,10 +2672,6 @@ export function createEditorState(dispatch: EditorDispatch): EditorState {
formulaBarMode: 'content',
formulaBarFocusCounter: 0,
},
- preview: {
- visible: false,
- connected: false,
- },
home: {
visible: false,
},
@@ -3049,10 +3030,6 @@ export function editorModelFromPersistentModel(
formulaBarMode: 'content',
formulaBarFocusCounter: 0,
},
- preview: {
- visible: false,
- connected: false,
- },
home: {
visible: false,
},
diff --git a/editor/src/components/editor/store/editor-update.spec.tsx b/editor/src/components/editor/store/editor-update.spec.tsx
index 855542efe4d1..fe59fde9219a 100644
--- a/editor/src/components/editor/store/editor-update.spec.tsx
+++ b/editor/src/components/editor/store/editor-update.spec.tsx
@@ -308,38 +308,6 @@ describe('action TOGGLE_PANE', () => {
)
chaiExpect(updatedEditor2.inspector.visible).to.not.equal(updatedEditor.inspector.visible)
})
-
- it('can toggle preview visibility', () => {
- const { editor, derivedState, dispatch } = createEditorStates()
- const action = togglePanel('preview')
- const updatedEditor = runLocalEditorAction(
- editor,
- derivedState,
- defaultUserState,
- workers,
- action,
- History.init(editor, derivedState),
- dispatch,
- emptyUiJsxCanvasContextData(),
- builtInDependencies,
- emptyCollaborativeEditingSupport(),
- emptyProjectServerState(),
- )
- const updatedEditor2 = runLocalEditorAction(
- updatedEditor,
- derivedState,
- defaultUserState,
- workers,
- action,
- History.init(editor, derivedState),
- dispatch,
- emptyUiJsxCanvasContextData(),
- builtInDependencies,
- emptyCollaborativeEditingSupport(),
- emptyProjectServerState(),
- )
- chaiExpect(updatedEditor2.preview.visible).to.not.equal(updatedEditor.preview.visible)
- })
})
describe('action DUPLICATE_SPECIFIC_ELEMENTS', () => {
diff --git a/editor/src/components/editor/store/editor-update.tsx b/editor/src/components/editor/store/editor-update.tsx
index f2b5e82c80d0..e663daa121e8 100644
--- a/editor/src/components/editor/store/editor-update.tsx
+++ b/editor/src/components/editor/store/editor-update.tsx
@@ -262,14 +262,10 @@ export function runSimpleLocalEditorAction(
return UPDATE_FNS.SET_PROJECT_NAME(action, state)
case 'SET_PROJECT_DESCRIPTION':
return UPDATE_FNS.SET_PROJECT_DESCRIPTION(action, state)
- case 'UPDATE_PREVIEW_CONNECTED':
- return UPDATE_FNS.UPDATE_PREVIEW_CONNECTED(action, state)
case 'SHOW_CONTEXT_MENU':
return UPDATE_FNS.SHOW_CONTEXT_MENU(action, state)
case 'DUPLICATE_SPECIFIC_ELEMENTS':
return UPDATE_FNS.DUPLICATE_SPECIFIC_ELEMENTS(action, state, dispatch)
- case 'SEND_PREVIEW_MODEL':
- return UPDATE_FNS.SEND_PREVIEW_MODEL(action, state)
case 'UPDATE_FILE_PATH':
return UPDATE_FNS.UPDATE_FILE_PATH(action, state, userState)
case 'UPDATE_REMIX_ROUTE':
diff --git a/editor/src/components/editor/store/store-deep-equality-instances.ts b/editor/src/components/editor/store/store-deep-equality-instances.ts
index f379de57390f..06e57d5b3d14 100644
--- a/editor/src/components/editor/store/store-deep-equality-instances.ts
+++ b/editor/src/components/editor/store/store-deep-equality-instances.ts
@@ -313,7 +313,6 @@ import type {
EditorStateGoogleFontsResources,
EditorStateProjectSettings,
EditorStateTopMenu,
- EditorStatePreview,
EditorStateHome,
FileDeleteModal,
ModalDialog,
@@ -398,7 +397,6 @@ import {
editorStateGoogleFontsResources,
editorStateProjectSettings,
editorStateTopMenu,
- editorStatePreview,
editorStateHome,
fileDeleteModal,
fileOverwriteModal,
@@ -4397,15 +4395,6 @@ export const EditorStateTopMenuKeepDeepEquality: KeepDeepEqualityCall =
- combine2EqualityCalls(
- (preview) => preview.visible,
- BooleanKeepDeepEquality,
- (preview) => preview.connected,
- BooleanKeepDeepEquality,
- editorStatePreview,
- )
-
export const EditorStateHomeKeepDeepEquality: KeepDeepEqualityCall =
combine1EqualityCall((preview) => preview.visible, BooleanKeepDeepEquality, editorStateHome)
@@ -5241,7 +5230,6 @@ export const EditorStateKeepDeepEquality: KeepDeepEqualityCall = (
)
const navigatorResults = NavigatorStateKeepDeepEquality(oldValue.navigator, newValue.navigator)
const topmenuResults = EditorStateTopMenuKeepDeepEquality(oldValue.topmenu, newValue.topmenu)
- const previewResults = EditorStatePreviewKeepDeepEquality(oldValue.preview, newValue.preview)
const homeResults = EditorStateHomeKeepDeepEquality(oldValue.home, newValue.home)
const lastUsedFontResults = nullableDeepEquality(FontSettingsKeepDeepEquality)(
oldValue.lastUsedFont,
@@ -5436,7 +5424,6 @@ export const EditorStateKeepDeepEquality: KeepDeepEqualityCall = (
projectSettingsResults.areEqual &&
navigatorResults.areEqual &&
topmenuResults.areEqual &&
- previewResults.areEqual &&
homeResults.areEqual &&
lastUsedFontResults.areEqual &&
modalResults.areEqual &&
@@ -5522,7 +5509,6 @@ export const EditorStateKeepDeepEquality: KeepDeepEqualityCall = (
projectSettingsResults.value,
navigatorResults.value,
topmenuResults.value,
- previewResults.value,
homeResults.value,
lastUsedFontResults.value,
modalResults.value,
diff --git a/editor/src/components/editor/store/store-hook-substore-helpers.ts b/editor/src/components/editor/store/store-hook-substore-helpers.ts
index 7e41cf6cc104..bd45ce5dd768 100644
--- a/editor/src/components/editor/store/store-hook-substore-helpers.ts
+++ b/editor/src/components/editor/store/store-hook-substore-helpers.ts
@@ -124,10 +124,6 @@ export const EmptyEditorStateForKeysOnly: EditorState = {
formulaBarMode: 'content',
formulaBarFocusCounter: 0,
},
- preview: {
- visible: false,
- connected: false,
- },
home: {
visible: false,
},
diff --git a/editor/src/components/preview/preview-pane.tsx b/editor/src/components/preview/preview-pane.tsx
deleted file mode 100644
index 18668969db60..000000000000
--- a/editor/src/components/preview/preview-pane.tsx
+++ /dev/null
@@ -1,407 +0,0 @@
-/** @jsxRuntime classic */
-/** @jsx jsx */
-import { jsx } from '@emotion/react'
-import React from 'react'
-import type { DeviceInfo } from '../../common/devices'
-import { deviceInfoList } from '../../common/devices'
-import { BASE_URL, FLOATING_PREVIEW_BASE_URL } from '../../common/env-vars'
-import { Substores, useEditorState } from '../editor/store/store-hook'
-import type { SelectOption } from '../inspector/controls/select-control'
-import type { TextFile } from '../../core/shared/project-file-types'
-import { isTextFile, ProjectContents } from '../../core/shared/project-file-types'
-import { objectKeyParser, parseString } from '../../utils/value-parser-utils'
-import { eitherToMaybe } from '../../core/shared/either'
-import { shareURLForProject } from '../../core/shared/utils'
-import { getMainJSFilename } from '../../core/shared/project-contents-utils'
-import type { ProjectContentTreeRoot } from '../assets'
-import {
- FlexRow,
- Button,
- //TODO: switch to functional component and make use of 'useColorTheme':
- colorTheme,
- FlexColumn,
- UtopiaTheme,
- SquareButton,
- LargerIcons,
- Subdued,
- PopupList,
- Icn,
- UIRow,
-} from '../../uuiui'
-import { setBranchNameFromURL } from '../../utils/branches'
-
-export const PreviewIframeId = 'preview-column-container'
-
-export interface ProjectContentsUpdateMessage {
- type: 'PROJECT_CONTENTS_UPDATE'
- projectContents: ProjectContentTreeRoot
-}
-
-export function projectContentsUpdateMessage(
- projectContents: ProjectContentTreeRoot,
-): ProjectContentsUpdateMessage {
- return {
- type: 'PROJECT_CONTENTS_UPDATE',
- projectContents: projectContents,
- }
-}
-
-export function isProjectContentsUpdateMessage(
- data: unknown,
-): data is ProjectContentsUpdateMessage {
- return (
- data != null &&
- typeof data === 'object' &&
- !Array.isArray(data) &&
- (data as ProjectContentsUpdateMessage).type === 'PROJECT_CONTENTS_UPDATE'
- )
-}
-
-interface IntermediatePreviewColumnProps {
- id: string | null
- projectName: string
- connected: boolean
- packageJSONFile: TextFile | null
-}
-
-export interface PreviewColumnProps {
- id: string | null
- projectName: string
- connected: boolean
- editedFilename: string | null
-}
-
-export interface PreviewColumnState {
- selectedBackgroundOptionIndex: number
- running: boolean
- useDevice: boolean
- scale: number
- selectedScaleOption: number
- deviceInfo: DeviceInfo
- rotated: boolean
- refreshCount: number
- width: number
- height: number
-}
-
-export const PreviewColumn = React.memo(() => {
- const mainJSFilename = useEditorState(
- Substores.projectContents,
- (store) => getMainJSFilename(store.editor.projectContents),
- 'PreviewColumn mainJSFilename',
- )
- const { id, projectName, connected } = useEditorState(
- Substores.restOfEditor,
- (store) => {
- return {
- id: store.editor.id,
- projectName: store.editor.projectName,
- connected: store.editor.preview.connected,
- }
- },
- 'PreviewColumn',
- )
- return (
-
- )
-})
-PreviewColumn.displayName = 'PreviewColumn'
-
-class PreviewColumnContent extends React.Component {
- scaleOptions: number[]
- scaleDropdownOptions: any
- backgroundOptions: any
- constructor(props: PreviewColumnProps) {
- super(props)
-
- this.scaleOptions = [0.25, 0.5, 0.67, 1, 1.25, 1.5, 2, 3, 4]
- this.backgroundOptions = [
- {
- label: 'White',
- value: { backgroundColor: '#ffffff' },
- },
- {
- label: 'Checkerboard (light)',
- value: {
- backgroundImage:
- 'linear-gradient(45deg, #d4d4d4 25%, transparent 25%), linear-gradient(-45deg, #d4d4d4 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #d4d4d4 75%), linear-gradient(-45deg, transparent 75%, #d4d4d4 75%)',
- backgroundSize: '10px 10px',
- backgroundPosition: '0 0, 0 5px, 5px -5px, -5px 0px',
- },
- },
- {
- label: 'Light Grey',
- value: { backgroundColor: '#f4f4f4' },
- },
- {
- label: 'Mid Grey',
- value: { backgroundColor: '#888888' },
- },
- { label: 'Dark Grey', value: { backgroundColor: '#333' } },
- { label: 'Black', value: { backgroundColor: '#000' } },
- ]
-
- this.scaleDropdownOptions = this.scaleOptions.map((s) => ({
- value: s,
- label: `${Math.round(s * 100)}%`,
- }))
-
- this.state = {
- selectedBackgroundOptionIndex: 0,
- running: true,
- useDevice: false,
- scale: 1,
- selectedScaleOption: 4,
- deviceInfo: deviceInfoList.iPhoneXS,
- rotated: false,
- refreshCount: 0,
- width: deviceInfoList.iPhoneXS.width as number,
- height: deviceInfoList.iPhoneXS.height as number,
- }
- }
-
- scaleDown = () => {
- this.setState((prevState) => ({ scale: Math.max(0.25, prevState.scale * 0.5) }))
- }
-
- scaleUp = () => {
- this.setState((prevState) => ({ scale: Math.min(8, prevState.scale * 2) }))
- }
-
- setSelectedValue = (selectedValue: SelectOption) => this.setState({ scale: selectedValue.value })
-
- onRestartClick = () => {
- this.setState((prevState) => ({
- refreshCount: prevState.refreshCount + 1,
- }))
- }
-
- handleKeyPress = (e: React.KeyboardEvent) => {
- if (e.key === 'Enter') {
- e.stopPropagation()
- this.onRestartClick()
- }
- }
-
- toggleRunning = () => {
- this.setState((prevState) => ({ running: !prevState.running }))
- }
-
- render() {
- const ColorButtonGroup = () => (
- *': {
- marginRight: 8,
- },
- }}
- >
- {this.backgroundOptions.map((background: any, i: number) => (
- this.setState(() => ({ selectedBackgroundOptionIndex: i }))}
- >
-
-
- ))}
-
- )
-
- function addInBranchNames(url: string): string {
- if (url === '') {
- return url
- } else {
- const parsedURL = new URL(url)
- setBranchNameFromURL(parsedURL.searchParams)
- return parsedURL.toString()
- }
- }
- let floatingPreviewURL =
- this.props.id == null
- ? ''
- : shareURLForProject(FLOATING_PREVIEW_BASE_URL, this.props.id, this.props.projectName)
- floatingPreviewURL = addInBranchNames(floatingPreviewURL)
- let iframePreviewURL =
- this.props.id == null
- ? ''
- : `${floatingPreviewURL}?embedded=true&refreshCount=${this.state.refreshCount}`
- iframePreviewURL = addInBranchNames(iframePreviewURL)
- let popoutPreviewURL =
- this.props.id == null
- ? ''
- : shareURLForProject(BASE_URL, this.props.id, this.props.projectName)
- popoutPreviewURL = addInBranchNames(popoutPreviewURL)
-
- const iFrame = (
-
- )
-
- return (
-
- *': {
- marginRight: 8,
- },
- }}
- >
-
-
-
-
- {this.props.editedFilename == null ? null : (
- {this.props.editedFilename}
- )}
-
- {this.state.running ? : }
-
-
-
-
-
-
-
-
- *': {
- marginRight: 8,
- },
- }}
- >
-
-
-
-
- = 4}
- onClick={this.scaleUp}
- >
-
-
-
-
-
-
-
- {this.state.running ? (
- iFrame
- ) : (
-
-
-
-
- Start Preview
-
- )}
-
-
- )
- }
-}
diff --git a/editor/src/core/shared/redux-devtools.ts b/editor/src/core/shared/redux-devtools.ts
index 851523157c71..41486b19b947 100644
--- a/editor/src/core/shared/redux-devtools.ts
+++ b/editor/src/core/shared/redux-devtools.ts
@@ -131,9 +131,6 @@ export function reduxDevtoolsSendActions(
const filteredActions = mapDropNulls((action) => {
switch (action.action) {
//Actions to be completely omitted from logging to redux devtools, to avoid noise
- case 'UPDATE_PREVIEW_CONNECTED': {
- return null
- }
// These actions will be logged with all of their payload. Be careful: large payloads choke the Redux Devtool logging
case 'SELECT_COMPONENTS':
case 'CREATE_INTERACTION_SESSION':
diff --git a/editor/src/templates/editor.tsx b/editor/src/templates/editor.tsx
index 0d2aa892c21d..6185db8ee773 100644
--- a/editor/src/templates/editor.tsx
+++ b/editor/src/templates/editor.tsx
@@ -26,11 +26,6 @@ import { actionActionsOptic, isLoggedIn } from '../components/editor/action-type
import * as EditorActions from '../components/editor/actions/action-creators'
import { EditorComponent } from '../components/editor/editor-component'
import * as History from '../components/editor/history'
-import {
- InternalPreviewTimeout,
- previewIsAlive,
- startPreviewConnectedMonitoring,
-} from '../components/editor/preview-report-handler'
import {
getLoginState,
getUserConfiguration,
@@ -83,7 +78,7 @@ import {
} from '../components/canvas/ui-jsx-canvas'
import { foldEither } from '../core/shared/either'
import { getURLImportDetails, reuploadAssets } from '../core/model/project-import'
-import { isSendPreviewModel, load } from '../components/editor/actions/actions'
+import { load } from '../components/editor/actions/actions'
import { UtopiaStyles } from '../uuiui'
import { reduxDevtoolsSendInitialState } from '../core/shared/redux-devtools'
import type { LoginState } from '../common/user'
@@ -216,8 +211,6 @@ export class Editor {
domWalkerMutableState: DomWalkerMutableStateData
constructor() {
- startPreviewConnectedMonitoring(this.boundDispatch)
-
let emptyEditorState = createEditorState(this.boundDispatch)
const derivedState = deriveState(
emptyEditorState,
@@ -232,8 +225,6 @@ export class Editor {
window.addEventListener('blur', this.resetStateOnBlur)
- window.addEventListener('message', this.onMessage)
-
const watchdogWorker = new RealWatchdogWorker()
const renderRootEditor = () =>
@@ -403,14 +394,6 @@ export class Editor {
})
}
- onMessage = (event: MessageEvent): void => {
- const eventData = event.data
- if (isSendPreviewModel(eventData)) {
- previewIsAlive(InternalPreviewTimeout)
- this.boundDispatch([eventData], 'noone')
- }
- }
-
resetStateOnBlur = (): void => {
this.boundDispatch(
[
diff --git a/editor/src/templates/preview/index.html b/editor/src/templates/preview/index.html
deleted file mode 100644
index afc4bfac7977..000000000000
--- a/editor/src/templates/preview/index.html
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
-
-
-
-
- <% if (VITE) { %>
-
- <% } %>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/editor/src/templates/preview/preview.tsx b/editor/src/templates/preview/preview.tsx
deleted file mode 100644
index c2db43f38fb9..000000000000
--- a/editor/src/templates/preview/preview.tsx
+++ /dev/null
@@ -1,338 +0,0 @@
-import '../../vite-shims'
-import fastDeepEquals from 'fast-deep-equal'
-import * as ReactErrorOverlay from 'react-error-overlay'
-import { BASE_URL, getProjectID, getQueryParam, PREVIEW_IS_EMBEDDED } from '../../common/env-vars'
-import { fetchLocalProject } from '../../common/persistence'
-import type { ProjectContentTreeRoot } from '../../components/assets'
-import { getProjectFileByFilePath } from '../../components/assets'
-import { incorporateBuildResult } from '../../components/custom-code/code-file'
-import { sendPreviewModel } from '../../components/editor/actions/action-creators'
-import { dependenciesWithEditorRequirements } from '../../components/editor/npm-dependency/npm-dependency'
-import { projectIsStoredLocally } from '../../components/editor/persistence/persistence-backend'
-import { loadProject } from '../../components/editor/server'
-import { isProjectContentsUpdateMessage } from '../../components/preview/preview-pane'
-import { createBuiltInDependenciesList } from '../../core/es-modules/package-manager/built-in-dependencies-list'
-import { fetchNodeModules } from '../../core/es-modules/package-manager/fetch-packages'
-import {
- getRequireFn,
- ResolvingRemoteDependencyErrorName,
-} from '../../core/es-modules/package-manager/package-manager'
-import { pluck } from '../../core/shared/array-utils'
-import { getMainHTMLFilename, getMainJSFilename } from '../../core/shared/project-contents-utils'
-import type { NodeModules } from '../../core/shared/project-file-types'
-import { isTextFile } from '../../core/shared/project-file-types'
-import { NewBundlerWorker, RealBundlerWorker } from '../../core/workers/bundler-bridge'
-import { createBundle } from '../../core/workers/bundler-promise'
-import Utils from '../../utils/utils'
-
-interface PolledLoadParams {
- projectId: string
- onStartLoad: () => void
- onModelChanged: (model: ProjectContentTreeRoot) => void
- onModelUnchanged: () => void
- onError: (error: Error) => void
-}
-
-export async function startPolledLoad({
- projectId,
- onStartLoad,
- onModelChanged,
- onModelUnchanged,
- onError,
-}: PolledLoadParams) {
- let keepPolling = true
- let isLocal = await projectIsStoredLocally(projectId)
- let pollInterval = isLocal ? 250 : 1000
-
- let lastSavedTS: string | null = null
- let isLoading = false
-
- const loadServerProject = async () => {
- if (!isLoading) {
- isLoading = true
- onStartLoad()
- const project = await loadProject(projectId, lastSavedTS)
- if (project.type === 'ProjectLoaded') {
- // eslint-disable-next-line require-atomic-updates
- lastSavedTS = project.modifiedAt
- onModelChanged(project.content.projectContents)
- } else if (project.type === 'ProjectUnchanged') {
- onModelUnchanged()
- }
- // eslint-disable-next-line require-atomic-updates
- isLoading = false
- }
- }
-
- const loadLocalProject = async () => {
- const project = await fetchLocalProject(projectId)
- const model = Utils.forceNotNull(`Local project ${projectId} could not be found.`, project)
- .model.projectContents
- onModelChanged(model)
- }
-
- let intervalHandle: number | null = null
-
- async function onTimeout() {
- // eslint-disable-next-line require-atomic-updates
- isLocal = isLocal && (await projectIsStoredLocally(projectId))
- pollInterval = isLocal ? 250 : 1000
-
- const polledLoad = isLocal ? loadLocalProject : loadServerProject
- try {
- if (keepPolling) {
- await polledLoad()
- } else if (intervalHandle != null) {
- window.clearInterval(intervalHandle)
- }
- } catch (e: any) {
- onError(e)
- }
- }
- intervalHandle = window.setInterval(onTimeout, pollInterval)
- void onTimeout()
-}
-
-function addOpenInUtopiaButton(): void {
- // Avoid doing this in the embedded preview, as it makes
- // no sense having it in there.
- if (getQueryParam('embedded') != 'true') {
- const projectId = getProjectID()
- if (projectId != null) {
- const openIcon = document.createElement('img')
- openIcon.setAttribute('src', `${BASE_URL}open_in_utopia@2x.png`)
- openIcon.setAttribute('style', 'width: 186px; height: 40px')
- openIcon.setAttribute('alt', 'Open this project in the Utopia editor')
-
- const openInUtopiaButton = document.createElement('div')
- const buttonStyle = [
- 'position: fixed',
- 'right: 20px',
- 'bottom: 20px',
- 'cursor: pointer',
- ].join('; ')
- openInUtopiaButton.setAttribute('style', buttonStyle)
- openInUtopiaButton.setAttribute(
- 'onclick',
- `window.open('${BASE_URL}project/${projectId}/', 'mywindow')`,
- )
-
- openInUtopiaButton.append(openIcon)
-
- document.body.append(openInUtopiaButton)
- }
- }
-}
-
-let lastRenderedModel: ProjectContentTreeRoot | null = null
-let queuedModel: ProjectContentTreeRoot | null = null
-let loadingModel: boolean = false
-let cachedDependencies: NodeModules = {}
-
-const initPreview = () => {
- loadingModel = false
- queuedModel = null
- cachedDependencies = {}
- const bundlerWorker = new NewBundlerWorker(new RealBundlerWorker())
- const builtInDependencies = createBuiltInDependenciesList(null)
-
- const startPollingFromServer = (appID: string | null) => {
- if (appID != null) {
- void startPolledLoad({
- projectId: appID,
- // eslint-disable-next-line @typescript-eslint/no-empty-function
- onStartLoad: () => {},
- onModelChanged: modelUpdated,
- // eslint-disable-next-line @typescript-eslint/no-empty-function
- onModelUnchanged: () => {},
- onError: (error) => {
- console.error('received error', error, error.message)
- },
- })
- }
- }
-
- const modelUpdated = async (model: ProjectContentTreeRoot) => {
- if (loadingModel) {
- queuedModel = model
- } else {
- renderProject(model)
- }
- }
-
- const handleModelUpdateEvent = (event: MessageEvent) => {
- // Received a model from the containing page.
- const eventData = event.data
- if (isProjectContentsUpdateMessage(eventData)) {
- void modelUpdated(eventData.projectContents)
- }
- }
-
- const handlePossiblyQueuedModel = () => {
- if (queuedModel == null) {
- loadingModel = false
- } else {
- renderProject(queuedModel)
- }
- }
-
- const renderProject = (projectContents: ProjectContentTreeRoot): void => {
- loadingModel = true
- queuedModel = null
- void previewRender(projectContents).finally(handlePossiblyQueuedModel)
- }
-
- const rerenderPreview = () => {
- if (lastRenderedModel != null) {
- void previewRender(lastRenderedModel)
- }
- }
-
- const onRemoteModuleDownload = (moduleDownload: Promise) => {
- void moduleDownload.then((downloadedModules: NodeModules) => {
- // MUTATION
- Object.assign(cachedDependencies, downloadedModules)
- rerenderPreview()
- })
- }
-
- const previewRender = async (projectContents: ProjectContentTreeRoot) => {
- const isRerender = projectContents === lastRenderedModel
- let nodeModules: NodeModules = {}
-
- if (isRerender) {
- nodeModules = { ...cachedDependencies }
- } else {
- const lastDependencies =
- lastRenderedModel == null ? [] : dependenciesWithEditorRequirements(lastRenderedModel)
- const npmDependencies = dependenciesWithEditorRequirements(projectContents)
- if (fastDeepEquals(lastDependencies, npmDependencies)) {
- nodeModules = { ...cachedDependencies }
- } else {
- const fetchNodeModulesResult = await fetchNodeModules(
- npmDependencies,
- builtInDependencies,
- true,
- )
-
- if (fetchNodeModulesResult.dependenciesWithError.length > 0) {
- const errorToThrow = Error(
- `Could not load the following npm dependencies: ${JSON.stringify(
- pluck(fetchNodeModulesResult.dependenciesWithError, 'name'),
- )}`,
- )
- ReactErrorOverlay.reportRuntimeError(errorToThrow)
- throw errorToThrow
- }
-
- cachedDependencies = {
- ...cachedDependencies,
- ...fetchNodeModulesResult.nodeModules,
- }
- nodeModules = { ...cachedDependencies }
- }
- }
-
- lastRenderedModel = projectContents
-
- /**
- * please note that we are passing in an empty object instead of the .d.ts files
- * the reason for this is that we only use the bundler as a transpiler here
- * and we don't care about static type errors
- *
- * some libraries, ie Antd have so massive definitions that it took more than 20 seconds
- * for the bundler to process it, basically with no upside
- */
- const emptyTypeDefinitions = {}
- const bundledProjectFiles = (
- await createBundle(bundlerWorker, emptyTypeDefinitions, projectContents)
- ).buildResult
-
- incorporateBuildResult(nodeModules, projectContents, bundledProjectFiles)
-
- const requireFn = getRequireFn(
- onRemoteModuleDownload,
- projectContents,
- nodeModules,
- {},
- builtInDependencies,
- )
-
- // replacing the document body first
- const previewHTMLFileName = getMainHTMLFilename(projectContents)
- const previewHTMLFile = getProjectFileByFilePath(projectContents, `/${previewHTMLFileName}`)
- if (previewHTMLFile != null && isTextFile(previewHTMLFile)) {
- try {
- try {
- ReactErrorOverlay.stopReportingRuntimeErrors()
- } catch (e) {
- // we don't care
- }
- document.open()
- document.write(previewHTMLFile.fileContents.code)
- document.close()
- addOpenInUtopiaButton()
- addWindowListeners()
- ReactErrorOverlay.startReportingRuntimeErrors({})
- } catch (e) {
- console.warn(`no body found in html`, e)
- }
- }
-
- const previewJSFileName = getMainJSFilename(projectContents)
- const previewJSFilePath = `/${previewJSFileName}`
- const previewJSFile = getProjectFileByFilePath(projectContents, previewJSFilePath)
- if (previewJSFile != null && isTextFile(previewJSFile)) {
- if (bundledProjectFiles[previewJSFilePath] == null) {
- throw new Error(
- `Error processing the project files: the build result does not contain the preview file: ${previewJSFilePath}`,
- )
- } else {
- try {
- /**
- * require the js entry point file which will evaluate the module.
- * the React entry point js file traditionally has a top level side effect,
- * calling ReactDOM.render() which starts the Preview app.
- */
- requireFn('/', previewJSFilePath)
- } catch (e: any) {
- if (e?.name === ResolvingRemoteDependencyErrorName && e?.message != null) {
- const loadingMessageDiv = document.createElement('div')
- loadingMessageDiv.innerHTML = e.message
- const loadingMessageStyle = [
- `font-family: -apple-system, BlinkMacSystemFont, Helvetica, 'Segoe UI', Roboto, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'`,
- 'font-size: 11px',
- 'cursor: default',
- ].join('; ')
- loadingMessageDiv.setAttribute('style', loadingMessageStyle)
- document.body.append(loadingMessageDiv)
- } else {
- throw e
- }
- }
- }
- } else {
- throw new Error(
- `Error processing the project files: the preview path (${previewJSFilePath}) did not point to a valid file`,
- )
- }
- }
-
- const addWindowListeners = () => {
- window.addEventListener('message', handleModelUpdateEvent)
- }
-
- const loadPreviewContent = () => {
- const projectId = getProjectID()
- addWindowListeners()
-
- if (PREVIEW_IS_EMBEDDED) {
- // Tell the editor we'd like to be sent the initial model.
- window.parent.postMessage(sendPreviewModel(), '*')
- } else {
- startPollingFromServer(projectId)
- }
- }
- loadPreviewContent()
-}
-initPreview()
diff --git a/editor/webpack.config.js b/editor/webpack.config.js
index 77c9e4cf1c5f..f0c7d9af5995 100644
--- a/editor/webpack.config.js
+++ b/editor/webpack.config.js
@@ -68,9 +68,6 @@ const config = {
editor: hot
? ['react-hot-loader/patch', './src/templates/editor-entry-point.tsx']
: './src/templates/editor-entry-point.tsx',
- preview: hot
- ? ['react-hot-loader/patch', './src/templates/preview/preview.tsx']
- : './src/templates/preview/preview.tsx',
},
output: {
@@ -100,16 +97,6 @@ const config = {
minify: false,
templateParameters: htmlTemplateParameters,
}),
- new HtmlWebpackPlugin({
- // Run it again to generate the preview.html
- chunks: ['preview'],
- inject: 'head', // Add the script tags to the end of the
- scriptLoading: 'defer',
- template: './src/templates/preview/index.html',
- filename: 'preview/index.html',
- minify: false,
- templateParameters: htmlTemplateParameters,
- }),
new HtmlWebpackPlugin({
chunks: [],
inject: 'head', // Add the script tags to the end of the
diff --git a/website-next/components/common/preview-devices.tsx b/website-next/components/common/preview-devices.tsx
deleted file mode 100644
index 07d035cf5ef0..000000000000
--- a/website-next/components/common/preview-devices.tsx
+++ /dev/null
@@ -1,151 +0,0 @@
-import React from 'react'
-import type { ValueType } from 'react-select'
-import { components } from 'react-select'
-import Select from 'react-select'
-import type { DeviceID } from './devices'
-import { deviceInfoList } from './devices'
-
-export const getDeviceReactSelectOption = (deviceID: DeviceID): DeviceReactSelectOption => {
- const device = deviceInfoList[deviceID]
- return {
- value: deviceID,
- label: `${device.prettyName}`,
- }
-}
-
-export type DeviceReactSelectOption = { value: DeviceID; label: string }
-export type DeviceReactSelectList = Array
-export const deviceReactSelectOptionList: DeviceReactSelectList = (
- Object.keys(deviceInfoList) as Array
-).map((value): DeviceReactSelectOption => getDeviceReactSelectOption(value))
-
-interface PreviewReactSelectDeviceSelectorProps {
- value: DeviceReactSelectOption
- onChange: (value: DeviceReactSelectOption) => void
- caratOffset: number
-}
-
-export const PreviewReactSelectDeviceSelector: React.FunctionComponent<
- React.PropsWithChildren
-> = ({ value, onChange, caratOffset }) => {
- const PreviewReactSelectSingleValue = (singleValueProps: any) => {
- return components.SingleValue == null ? null : (
-
-
- {singleValueProps.children}
-
-
-
-
-
- )
- }
-
- const selectOnChange = React.useCallback(
- (newValue: ValueType) => {
- if (newValue != null && !Array.isArray(newValue)) {
- onChange(newValue as DeviceReactSelectOption)
- }
- },
- [onChange],
- )
-
- return (
- {
- return {
- ...base,
- backgroundColor: 'transparent',
- boxShadow: 'none',
- textAlign: 'left',
- cursor: 'default',
- }
- },
- menu: (base: any, state: any) => {
- return {
- ...base,
- width: '200px !important',
- left: -12,
- }
- },
- control: (base: any, state: any) => {
- return {
- display: 'inline-block',
- }
- },
- valueContainer: (base: any, state: any) => {
- return {
- display: 'inline-block',
- }
- },
- singleValue: (base: any, state: any) => {
- return {
- display: 'inline-block',
- height: 18,
- position: 'relative',
- }
- },
- indicatorsContainer: () => {
- return {
- display: 'none',
- }
- },
- }}
- />
- )
-}
-
-type Dimensions = { width: number; height: number }
-
-export const calculatePreviewScale = (
- viewport: Dimensions,
- edgePadding: number,
- sourceWidth: number,
- sourceHeight: number,
-): number => {
- const destinationWidth = viewport.width - 2 * edgePadding
- const destinationHeight = viewport.height - 2 * edgePadding
-
- if (sourceWidth > 0 && sourceHeight > 0) {
- const scale = Math.min(destinationWidth / sourceWidth, destinationHeight / sourceHeight)
- return Math.min(scale, 1)
- } else {
- return 1
- }
-}
diff --git a/website-next/components/preview/preview-page-component.tsx b/website-next/components/preview/preview-page-component.tsx
deleted file mode 100644
index cb002dd4910c..000000000000
--- a/website-next/components/preview/preview-page-component.tsx
+++ /dev/null
@@ -1,335 +0,0 @@
-/** @jsxRuntime classic */
-/** @jsx jsx */
-import React from 'react'
-import { jsx } from '@emotion/react'
-import { Global } from '@emotion/react'
-import type { DeviceReactSelectOption } from '../common/preview-devices'
-import {
- PreviewReactSelectDeviceSelector,
- getDeviceReactSelectOption,
- calculatePreviewScale,
-} from '../common/preview-devices'
-import type { DeviceInfo } from '../common/devices'
-import { deviceInfoList } from '../common/devices'
-
-export type PreviewWindowProps = {
- id: string
-}
-
-export type PreviewWindowState = {
- scale: number
- scaleToFit: boolean
- deviceInfo: DeviceInfo
- width: number
- height: number
- fullscreenViewportOverride: boolean
-}
-
-export class PreviewWindow extends React.Component {
- private previewWrapperRef: React.RefObject
- private iFrameRef: React.RefObject
- private edgePaddingSetting = 20
-
- constructor(props: PreviewWindowProps) {
- super(props)
-
- this.previewWrapperRef = React.createRef()
- this.iFrameRef = React.createRef()
-
- this.state = {
- scale: 1,
- scaleToFit: true,
- deviceInfo: deviceInfoList.iPhoneXS,
- width: deviceInfoList.iPhoneXS.width as number,
- height: deviceInfoList.iPhoneXS.height as number,
- fullscreenViewportOverride: false,
- }
- }
-
- shouldBeFullscreen() {
- // eslint-disable-next-line no-restricted-globals
- const userAgentIsMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)
- const isBelowThreshold = window.innerWidth <= this.state.width
- return userAgentIsMobile || isBelowThreshold
- }
-
- resizePreviewWindow = () => {
- if (this.previewWrapperRef.current != null) {
- const previewWindowDimensions = {
- width: this.previewWrapperRef.current.clientWidth,
- height: this.previewWrapperRef.current.clientHeight,
- }
- if (this.shouldBeFullscreen()) {
- this.setState({
- scale: 1,
- fullscreenViewportOverride: true,
- })
- } else {
- this.setState((previousState) => {
- const scale = calculatePreviewScale(
- previewWindowDimensions,
- this.edgePaddingSetting,
- previousState.width,
- previousState.height,
- )
- return {
- scale,
- fullscreenViewportOverride: false,
- }
- })
- }
- }
- }
-
- componentDidMount() {
- if (this.previewWrapperRef.current != null) {
- this.resizePreviewWindow()
- window.addEventListener('resize', this.resizePreviewWindow)
- }
- }
-
- onRestartClick = () => {
- if (this.iFrameRef.current != null && this.iFrameRef.current.contentWindow != null) {
- this.iFrameRef.current.contentWindow.location.reload()
- }
- }
-
- onDeviceChange = (newValue: DeviceReactSelectOption) => {
- if (this.previewWrapperRef.current != null) {
- const newDevice = deviceInfoList[newValue.value]
- const viewport = {
- width: this.previewWrapperRef.current.clientWidth,
- height: this.previewWrapperRef.current.clientHeight,
- }
-
- this.setState((previousState) => {
- const edgePadding = window.innerWidth > previousState.width ? this.edgePaddingSetting : 0
- return {
- scale: calculatePreviewScale(
- viewport,
- edgePadding,
- previousState.width,
- previousState.height,
- ),
- deviceInfo: newDevice,
- width: newDevice.width,
- height: newDevice.height,
- fullscreenViewportOverride: false,
- }
- })
- }
- }
-
- render() {
- const TopBarHeight = 44
-
- let previewBoxShadow: string
- let previewWrapperAlignItems: string
- let previewBorderRadius: number
-
- if (this.state.fullscreenViewportOverride) {
- previewBoxShadow = ''
- previewWrapperAlignItems = 'flex-start'
- previewBorderRadius = 0
- } else {
- previewBoxShadow = '0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23)'
- previewWrapperAlignItems = 'center'
- previewBorderRadius = 4
- }
-
- const idString = this.props.id !== '' ? ` (${this.props.id})` : null
-
- const displayWidth = this.state.fullscreenViewportOverride ? '100%' : this.state.width
- const displayHeight = this.state.fullscreenViewportOverride ? '100%' : this.state.height
- const scaledDisplayWidth = this.state.fullscreenViewportOverride
- ? '100%'
- : this.state.width * this.state.scale
- const scaledDisplayHeight = this.state.fullscreenViewportOverride
- ? '100%'
- : this.state.height * this.state.scale
-
- return (
-
-
-
-
-
- Untitled{idString}
-
-
- |
-
-
-
-
-
-
- |
-
-
- Scale{' '}
- {this.state.scale != null ? `(${Number((this.state.scale * 100).toFixed(2))}%)` : ''}
-
-
- |
-
-
-
-
-
-
- {!(this.state.scale != null) ? null : (
-
-
-
- )}
-
-
-
- )
- }
-}
-
-export function PreviewPage({ projectId }: { projectId?: string }) {
- if (projectId != null) {
- return
- } else {
- return null
- }
-}
diff --git a/website-next/pages/preview/[id].tsx b/website-next/pages/preview/[id].tsx
deleted file mode 100644
index 8b1514d8847e..000000000000
--- a/website-next/pages/preview/[id].tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import * as React from 'react'
-import { useRouter } from 'next/router'
-import { PreviewPage } from '../../components/preview/preview-page-component'
-
-export default function Preview() {
- const router = useRouter()
- const { id } = router.query
-
- const projectId = Array.isArray(id) ? id[0] : id
-
- return
-}