@@ -12,8 +12,10 @@ import { formatFileSize, formatUnixTimestamp } from '@/utils';
1212import type { FileOrFolder } from '@/shared.types' ;
1313import {
1414 useFileContentQuery ,
15- useFileMetadataQuery
15+ useFileMetadataQuery ,
16+ useFileBinaryPreviewQuery
1617} from '@/queries/fileContentQueries' ;
18+ import HexDump from './HexDump' ;
1719import useDarkMode from '@/hooks/useDarkMode' ;
1820
1921type FileViewerProps = {
@@ -84,12 +86,17 @@ export default function FileViewer({ file }: FileViewerProps) {
8486 const isDarkMode = useDarkMode ( ) ;
8587 const [ formatJson , setFormatJson ] = useState < boolean > ( true ) ;
8688
87- // First, fetch metadata to check if file is binary
8889 const metadataQuery = useFileMetadataQuery ( fspName , file . path ) ;
8990
90- // Only fetch content if metadata indicates it's not binary
91- const shouldFetchContent =
92- metadataQuery . isSuccess && ! metadataQuery . data . isBinary ;
91+ const isBinary = metadataQuery . data ?. isBinary === true ;
92+
93+ const binaryPreviewQuery = useFileBinaryPreviewQuery (
94+ fspName ,
95+ file . path ,
96+ isBinary
97+ ) ;
98+
99+ const shouldFetchContent = metadataQuery . isSuccess && ! isBinary ;
93100 const contentQuery = useFileContentQuery (
94101 shouldFetchContent ? fspName : undefined ,
95102 file . path
@@ -99,6 +106,30 @@ export default function FileViewer({ file }: FileViewerProps) {
99106 const isJsonFile = language === 'json' ;
100107
101108 const renderViewer = ( ) => {
109+ // Binary file: show hex preview as soon as the first bytes arrive
110+ if ( isBinary ) {
111+ if ( binaryPreviewQuery . isPending ) {
112+ return (
113+ < Typography className = "p-4 text-foreground" >
114+ Loading binary preview...
115+ </ Typography >
116+ ) ;
117+ }
118+ if ( binaryPreviewQuery . error ) {
119+ return (
120+ < Typography className = "p-4 text-foreground/60" >
121+ Binary file — preview unavailable
122+ </ Typography >
123+ ) ;
124+ }
125+ return (
126+ < HexDump
127+ bytes = { binaryPreviewQuery . data ! }
128+ totalFileSize = { file . size ?? undefined }
129+ />
130+ ) ;
131+ }
132+
102133 if ( metadataQuery . isLoading ) {
103134 return (
104135 < Typography className = "p-4 text-foreground" >
@@ -115,15 +146,6 @@ export default function FileViewer({ file }: FileViewerProps) {
115146 ) ;
116147 }
117148
118- // If file is binary, show a message instead of trying to load content
119- if ( metadataQuery . data ?. isBinary ) {
120- return (
121- < Typography className = "p-4 text-foreground" >
122- Binary file - preview not available
123- </ Typography >
124- ) ;
125- }
126-
127149 if ( contentQuery . isLoading ) {
128150 return (
129151 < Typography className = "p-4 text-foreground" >
@@ -196,8 +218,7 @@ export default function FileViewer({ file }: FileViewerProps) {
196218 } ;
197219
198220 // Determine if we should show JSON format toggle
199- const showJsonToggle =
200- isJsonFile && metadataQuery . isSuccess && ! metadataQuery . data . isBinary ;
221+ const showJsonToggle = isJsonFile && ! isBinary ;
201222
202223 return (
203224 < div className = "flex flex-col h-full w-full overflow-hidden" >
0 commit comments