@@ -4,6 +4,7 @@ import * as suspense from '#/components/Suspense'
4
4
import { useEventCallback } from '#/hooks/eventCallbackHooks'
5
5
import * as gtagHooks from '#/hooks/gtagHooks'
6
6
import * as projectHooks from '#/hooks/projectHooks'
7
+ import { useTimeoutCallback } from '#/hooks/timeoutHooks'
7
8
import * as backendProvider from '#/providers/BackendProvider'
8
9
import type { LaunchedProject } from '#/providers/ProjectsProvider'
9
10
import * as textProvider from '#/providers/TextProvider'
@@ -12,7 +13,7 @@ import * as twMerge from '#/utilities/tailwindMerge'
12
13
import { vueComponent } from '#/utilities/vue'
13
14
import * as reactQuery from '@tanstack/react-query'
14
15
import * as React from 'react'
15
- import { useTimeoutCallback } from '../hooks/timeoutHooks '
16
+ import invariant from 'tiny-invariant '
16
17
17
18
const ProjectViewTab = React . lazy ( ( ) =>
18
19
import ( '@/ProjectViewTab.vue' ) . then ( ( { default : vue } ) => vueComponent ( vue ) ) ,
@@ -34,10 +35,11 @@ export interface EditorProps {
34
35
}
35
36
36
37
/** The container that launches the IDE. */
37
- function Editor ( props : EditorProps ) {
38
+ export default function Editor ( props : EditorProps ) {
38
39
const { project, hidden, startProject, isOpeningFailed, openingError } = props
39
40
40
41
const backend = backendProvider . useBackendForProjectType ( project . type )
42
+ const remoteBackend = backendProvider . useRemoteBackend ( )
41
43
42
44
const projectStatusQuery = projectHooks . createGetProjectDetailsQuery ( {
43
45
assetId : project . id ,
@@ -46,6 +48,8 @@ function Editor(props: EditorProps) {
46
48
47
49
const queryClient = reactQuery . useQueryClient ( )
48
50
51
+ const isHybrid = project . hybrid != null
52
+
49
53
const projectQuery = reactQuery . useSuspenseQuery ( {
50
54
...projectStatusQuery ,
51
55
select : ( data ) => {
@@ -58,6 +62,17 @@ function Editor(props: EditorProps) {
58
62
} ,
59
63
} )
60
64
65
+ // If it's a hybrid project, we need to fetch the project details from the remote backend.
66
+ const {
67
+ data : { name } ,
68
+ } = reactQuery . useSuspenseQuery ( {
69
+ ...projectHooks . createGetProjectDetailsQuery ( {
70
+ assetId : isHybrid ? project . hybrid . cloudProjectId : project . id ,
71
+ backend : isHybrid ? remoteBackend : backend ,
72
+ } ) ,
73
+ select : ( projectDetails ) => ( { name : projectDetails . name } ) ,
74
+ } )
75
+
61
76
const { isProjectClosed, isProjectOpening, isProjectOpened, isProjectClosing } = projectQuery . data
62
77
63
78
React . useEffect ( ( ) => {
@@ -121,6 +136,7 @@ function Editor(props: EditorProps) {
121
136
{ ...props }
122
137
openedProject = { projectQuery . data }
123
138
backendType = { project . type }
139
+ projectName = { name }
124
140
/>
125
141
)
126
142
@@ -136,11 +152,12 @@ function Editor(props: EditorProps) {
136
152
interface EditorInternalProps extends Omit < EditorProps , 'project' > {
137
153
readonly openedProject : backendModule . Project
138
154
readonly backendType : backendModule . BackendType
155
+ readonly projectName : string
139
156
}
140
157
141
158
/** An internal editor. */
142
159
function EditorInternal ( props : EditorInternalProps ) {
143
- const { hidden, ydocUrl, renameProject, openedProject, backendType } = props
160
+ const { hidden, ydocUrl, renameProject, openedProject, backendType, projectName } = props
144
161
145
162
const { getText } = textProvider . useText ( )
146
163
const gtagEvent = gtagHooks . useGtagEvent ( )
@@ -158,48 +175,31 @@ function EditorInternal(props: EditorInternalProps) {
158
175
renameProject ( newName , openedProject . projectId )
159
176
} )
160
177
161
- const appProps = React . useMemo < ProjectViewTabProps > ( ( ) => {
162
- const jsonAddress = openedProject . jsonAddress
163
- const binaryAddress = openedProject . binaryAddress
164
- const ydocAddress = openedProject . ydocAddress ?? ydocUrl ?? ''
165
- const projectBackend =
166
- backendType === backendModule . BackendType . remote ? remoteBackend : localBackend
167
-
168
- if ( jsonAddress == null ) {
169
- throw new Error ( getText ( 'noJSONEndpointError' ) )
170
- } else if ( binaryAddress == null ) {
171
- throw new Error ( getText ( 'noBinaryEndpointError' ) )
172
- } else {
173
- return {
174
- hidden,
175
- projectViewProps : {
176
- projectId : openedProject . projectId ,
177
- projectName : openedProject . packageName ,
178
- projectDisplayedName : openedProject . name ,
179
- engine : { rpcUrl : jsonAddress , dataUrl : binaryAddress , ydocUrl : ydocAddress } ,
180
- renameProject : onRenameProject ,
181
- projectBackend,
182
- remoteBackend,
183
- } ,
184
- }
185
- }
186
- } , [
187
- openedProject ,
188
- ydocUrl ,
189
- getText ,
178
+ const jsonAddress = openedProject . jsonAddress
179
+ const binaryAddress = openedProject . binaryAddress
180
+ const ydocAddress = openedProject . ydocAddress ?? ydocUrl ?? ''
181
+ const projectBackend =
182
+ backendType === backendModule . BackendType . remote ? remoteBackend : localBackend
183
+
184
+ invariant ( jsonAddress != null , getText ( 'noJSONEndpointError' ) )
185
+ invariant ( binaryAddress != null , getText ( 'noBinaryEndpointError' ) )
186
+
187
+ const appProps = {
190
188
hidden,
191
- onRenameProject ,
192
- backendType ,
193
- localBackend ,
194
- remoteBackend ,
195
- ] )
196
- // EsLint does not handle types imported from vue files and their dependences.
197
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
189
+ projectViewProps : {
190
+ projectId : openedProject . projectId ,
191
+ projectName : openedProject . packageName ,
192
+ projectDisplayedName : projectName ,
193
+ engine : { rpcUrl : jsonAddress , dataUrl : binaryAddress , ydocUrl : ydocAddress } ,
194
+ renameProject : onRenameProject ,
195
+ projectBackend,
196
+ remoteBackend,
197
+ } ,
198
+ } as const
199
+
198
200
const key : string = appProps . projectViewProps . projectId
199
201
200
202
// Currently the GUI component needs to be fully rerendered whenever the project is changed. Once
201
203
// this is no longer necessary, the `key` could be removed.
202
204
return < ProjectViewTab key = { key } { ...appProps } />
203
205
}
204
-
205
- export default React . memo ( Editor )
0 commit comments