1- import { useState } from 'react' ;
1+ import { type SyntheticEvent , useState } from 'react' ;
22import { Pressable , View } from 'react-native' ;
33import { type Theme } from 'react-shiki' ;
44import useSWR from 'swr' ;
55
66import { Label , P } from '~/common/styleguide' ;
77import { CodeIcon , ImageFileIcon , TempFileIcon } from '~/components/Icons' ;
8- import CodeBrowserContentHeader from '~/components/Package/CodeBrowser/CodeBrowserContentHeader' ;
9- import DownloadFileButton from '~/components/Package/CodeBrowser/DownloadFileButton' ;
108import CopyButton from '~/components/Package/CopyButton' ;
119import ThreeDotsLoader from '~/components/Package/ThreeDotsLoader' ;
1210import Tooltip from '~/components/Tooltip' ;
@@ -16,9 +14,13 @@ import { type UnpkgMeta } from '~/types';
1614import { IMAGE_FILES , PREVIEW_DISABLED_FILES } from '~/util/codeBrowser' ;
1715import { TimeRange } from '~/util/datetime' ;
1816import { formatBytes } from '~/util/formatBytes' ;
17+ import { pluralize } from '~/util/strings' ;
1918import tw from '~/util/tailwind' ;
2019
20+ import CodeBrowserContentFooter from './CodeBrowserContentFooter' ;
21+ import CodeBrowserContentHeader from './CodeBrowserContentHeader' ;
2122import CodeBrowserContentHighlighter from './CodeBrowserContentHighlighter' ;
23+ import DownloadFileButton from './DownloadFileButton' ;
2224
2325type Props = {
2426 packageName : string ;
@@ -29,6 +31,9 @@ type Props = {
2931export default function CodeBrowserContent ( { packageName, filePath, fileData } : Props ) {
3032 const fileExtension = filePath . split ( '.' ) . at ( - 1 ) ?? 'text' ;
3133 const [ rawPreview , setRawPreview ] = useState ( false ) ;
34+ const [ imageData , setImageData ] = useState <
35+ SyntheticEvent < HTMLImageElement > [ 'currentTarget' ] | null
36+ > ( null ) ;
3237
3338 const isTooBig = Boolean ( fileData ?. size && fileData . size > 1024 * 1024 * 4 ) ;
3439 const isPreviewDisabled = PREVIEW_DISABLED_FILES . includes ( fileExtension ) || isTooBig ;
@@ -59,6 +64,15 @@ export default function CodeBrowserContent({ packageName, filePath, fileData }:
5964 < View style = { tw `flex flex-1 items-center justify-center` } >
6065 < ThreeDotsLoader />
6166 </ View >
67+ < CodeBrowserContentFooter
68+ rightSlot = {
69+ fileData && (
70+ < Label style = { tw `font-light text-secondary` } >
71+ < span style = { tw `font-medium` } > { formatBytes ( fileData . size ) } </ span >
72+ </ Label >
73+ )
74+ }
75+ />
6276 </ >
6377 ) ;
6478 }
@@ -92,6 +106,21 @@ export default function CodeBrowserContent({ packageName, filePath, fileData }:
92106 lang = { filePath . split ( '.' ) . at ( - 1 ) ?? 'text' }
93107 theme = { ( tw . prefixMatch ( 'dark' ) ? rndDark : rndLight ) as Theme }
94108 />
109+ < CodeBrowserContentFooter
110+ leftSlot = {
111+ < Label style = { tw `font-light text-secondary` } >
112+ < span style = { tw `font-medium` } > { data . split ( '\n' ) . length } </ span > { ' ' }
113+ { pluralize ( 'line' , data . split ( '\n' ) . length ) }
114+ </ Label >
115+ }
116+ rightSlot = {
117+ fileData && (
118+ < Label style = { tw `font-light text-secondary` } >
119+ < span style = { tw `font-medium` } > { formatBytes ( fileData . size ) } </ span >
120+ </ Label >
121+ )
122+ }
123+ />
95124 </ >
96125 ) ;
97126 }
@@ -121,6 +150,9 @@ export default function CodeBrowserContent({ packageName, filePath, fileData }:
121150 src = { `https://unpkg.com/${ packageName } /${ filePath } ` }
122151 alt = ""
123152 style = { tw `max-h-full max-w-full` }
153+ onLoad = { ( event : SyntheticEvent < HTMLImageElement > ) => {
154+ setImageData ( event . currentTarget ) ;
155+ } }
124156 />
125157 ) }
126158 { ! isImageFile && isPreviewDisabled && (
@@ -136,10 +168,27 @@ export default function CodeBrowserContent({ packageName, filePath, fileData }:
136168 ) }
137169 { ! isPreviewDisabled && ! isImageFile && (
138170 < P >
139- Cannot fetch " < code > { filePath } </ code > " file content.
171+ Cannot fetch < code style = { tw `text-[90%]` } > " { filePath } " </ code > file content.
140172 </ P >
141173 ) }
142174 </ View >
175+ < CodeBrowserContentFooter
176+ leftSlot = {
177+ isImageFile && imageData ? (
178+ < Label style = { tw `font-light text-secondary` } >
179+ < span style = { tw `font-medium` } > { imageData . naturalWidth } </ span > px ×{ ' ' }
180+ < span style = { tw `font-medium` } > { imageData . naturalHeight } </ span > px
181+ </ Label >
182+ ) : undefined
183+ }
184+ rightSlot = {
185+ fileData && (
186+ < Label style = { tw `font-light text-secondary` } >
187+ < span style = { tw `font-medium` } > { formatBytes ( fileData . size ) } </ span >
188+ </ Label >
189+ )
190+ }
191+ />
143192 </ >
144193 ) ;
145194}
0 commit comments