@@ -13,12 +13,14 @@ import {
1313import { openRawMessagesPanel } from '@/features/workspace/sidebar/topic-list/openRawMessagesPanel' ;
1414import { useIntl } from 'react-intl' ;
1515import { WelcomeScreen } from '@/features/workspace/common/WelcomeScreen' ;
16+ import { LoadingOverlay } from '@/features/workspace/common/LoadingOverlay' ;
1617import { useMessagePipeline } from '@/core/pipeline/useMessagePipeline' ;
1718import type { MessagePipelineState } from '@/core/pipeline/store' ;
1819import { useMessagePipelineStore } from '@/core/pipeline/store' ;
1920import type { SampleDataset } from '@/services/sampleDatasets' ;
2021import type { DatasetHistoryListItem } from '@/shared/utils/datasetHistory' ;
2122import { ResizableHandle , ResizablePanel , ResizablePanelGroup } from '@/shared/ui/resizable' ;
23+ import { Skeleton } from '@/shared/ui/skeleton' ;
2224import type { RosViewExtension } from '@/core/extensions/types' ;
2325import { buildExtensionContext } from '@/core/extensions/buildContext' ;
2426import type { FoxgloveLayoutData } from '@/core/preferences/foxgloveLayout' ;
@@ -49,7 +51,7 @@ interface RosViewContentProps {
4951 onSubmitRemoteUrl : ( url : string ) => void | Promise < void > ;
5052 remoteSubmitLoading ?: boolean ;
5153 onSelectSample : ( sample : SampleDataset ) => void | Promise < void > ;
52- onRequestChangeRemoteUrl ?: ( ) => void ;
54+ onCancelLoading ?: ( ) => void ;
5355 historyItems : DatasetHistoryListItem [ ] ;
5456 onReplayHistory : ( id : string ) => void | Promise < void > ;
5557 onDropRosRecordingFiles : ( files : File [ ] , items ?: DataTransferItemList ) => void | Promise < void > ;
@@ -89,7 +91,7 @@ export const RosViewContent: React.FC<RosViewContentProps> = ({
8991 onSubmitRemoteUrl,
9092 remoteSubmitLoading,
9193 onSelectSample,
92- onRequestChangeRemoteUrl ,
94+ onCancelLoading ,
9395 historyItems,
9496 onReplayHistory,
9597 onDropRosRecordingFiles,
@@ -112,8 +114,8 @@ export const RosViewContent: React.FC<RosViewContentProps> = ({
112114 const { formatMessage } = useIntl ( ) ;
113115 const presence = useMessagePipeline ( ( state : MessagePipelineState ) => state . playerState . presence ) ;
114116 const sortedTopics = useMessagePipeline ( ( state : MessagePipelineState ) => state . sortedTopics ) ;
115- const isLoading = presence === 'initializing' ;
116117 const isReady = presence === 'ready' ;
118+ const showWelcomeFallback = ! isReady && Boolean ( manualOpenHint ) ;
117119 const topicDragDepthRef = useRef ( 0 ) ;
118120 const [ sidebarPanelPercent , setSidebarPanelPercent ] = useState ( ( ) =>
119121 getInitialSidebarPanelPercent ( preferencePersistence ) ,
@@ -251,19 +253,16 @@ export const RosViewContent: React.FC<RosViewContentProps> = ({
251253
252254 return (
253255 < div className = "flex flex-col flex-1 min-h-0 overflow-hidden" >
254- { ! isReady ? (
256+ { showWelcomeFallback ? (
255257 < div className = "relative flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden" >
256258 < WelcomeScreen
257- isLoading = { isLoading }
258- loadingSourceName = { loadingSourceName }
259259 manualOpenHint = { manualOpenHint }
260260 onOpenFile = { onOpenFilePick }
261261 onOpenDirectory = { onOpenDirectory }
262262 onOpenTarPicker = { onOpenTarPick }
263263 onSubmitRemoteUrl = { onSubmitRemoteUrl }
264264 remoteSubmitLoading = { remoteSubmitLoading }
265265 onSelectSample = { onSelectSample }
266- onRequestChangeRemoteUrl = { onRequestChangeRemoteUrl }
267266 historyItems = { historyItems }
268267 onReplayHistory = { onReplayHistory }
269268 />
@@ -334,10 +333,10 @@ export const RosViewContent: React.FC<RosViewContentProps> = ({
334333 className = { `relative flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden bg-background [contain:strict] ${
335334 isTopicDragOver ? 'ring-1 ring-inset ring-primary/40' : ''
336335 } `}
337- onDragEnter = { handleTopicDragEnter }
338- onDragOver = { handleMainDragOver }
339- onDragLeave = { handleTopicDragLeave }
340- onDrop = { handleMainDrop }
336+ onDragEnter = { isReady ? handleTopicDragEnter : undefined }
337+ onDragOver = { isReady ? handleMainDragOver : undefined }
338+ onDragLeave = { isReady ? handleTopicDragLeave : undefined }
339+ onDrop = { isReady ? handleMainDrop : undefined }
341340 >
342341 { isTopicDragOver && (
343342 < div className = "pointer-events-none absolute inset-4 z-10 flex items-center justify-center rounded-lg border border-dashed border-primary/60 bg-primary/5" >
@@ -351,17 +350,30 @@ export const RosViewContent: React.FC<RosViewContentProps> = ({
351350 </ div >
352351 </ div >
353352 ) }
354- < DockviewLayout
355- key = { activeDatasetId ?? 'dataset' }
356- player = { player }
357- preferAutoLayout = { preferAutoLayout }
358- initialLayout = { initialLayout }
359- defaultPanel = { defaultPanel }
360- layoutPersistence = { layoutPersistence }
361- layoutStorageKey = { layoutStorageKey }
362- suppressWelcomePanel = { suppressWelcomePanel }
363- onLayoutReady = { onLayoutReady }
364- />
353+ { isReady ? (
354+ < DockviewLayout
355+ key = { activeDatasetId ?? 'dataset' }
356+ player = { player }
357+ preferAutoLayout = { preferAutoLayout }
358+ initialLayout = { initialLayout }
359+ defaultPanel = { defaultPanel }
360+ layoutPersistence = { layoutPersistence }
361+ layoutStorageKey = { layoutStorageKey }
362+ suppressWelcomePanel = { suppressWelcomePanel }
363+ onLayoutReady = { onLayoutReady }
364+ />
365+ ) : (
366+ < div className = "flex min-h-0 flex-1 flex-col gap-3 p-4" >
367+ < Skeleton className = "h-8 w-40" />
368+ < Skeleton className = "min-h-0 flex-1 rounded-lg" />
369+ </ div >
370+ ) }
371+ { ! isReady ? (
372+ < LoadingOverlay
373+ sourceName = { loadingSourceName }
374+ onCancel = { onCancelLoading }
375+ />
376+ ) : null }
365377 </ main >
366378 </ ResizablePanel >
367379 </ ResizablePanelGroup >
0 commit comments