Skip to content

Commit 376bae7

Browse files
authored
add file browser content footer including active file details (#2387)
1 parent e764f46 commit 376bae7

File tree

4 files changed

+107
-22
lines changed

4 files changed

+107
-22
lines changed

components/Package/CodeBrowser/CodeBrowserContent.tsx

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import { useState } from 'react';
1+
import { type SyntheticEvent, useState } from 'react';
22
import { Pressable, View } from 'react-native';
33
import { type Theme } from 'react-shiki';
44
import useSWR from 'swr';
55

66
import { Label, P } from '~/common/styleguide';
77
import { CodeIcon, ImageFileIcon, TempFileIcon } from '~/components/Icons';
8-
import CodeBrowserContentHeader from '~/components/Package/CodeBrowser/CodeBrowserContentHeader';
9-
import DownloadFileButton from '~/components/Package/CodeBrowser/DownloadFileButton';
108
import CopyButton from '~/components/Package/CopyButton';
119
import ThreeDotsLoader from '~/components/Package/ThreeDotsLoader';
1210
import Tooltip from '~/components/Tooltip';
@@ -16,9 +14,13 @@ import { type UnpkgMeta } from '~/types';
1614
import { IMAGE_FILES, PREVIEW_DISABLED_FILES } from '~/util/codeBrowser';
1715
import { TimeRange } from '~/util/datetime';
1816
import { formatBytes } from '~/util/formatBytes';
17+
import { pluralize } from '~/util/strings';
1918
import tw from '~/util/tailwind';
2019

20+
import CodeBrowserContentFooter from './CodeBrowserContentFooter';
21+
import CodeBrowserContentHeader from './CodeBrowserContentHeader';
2122
import CodeBrowserContentHighlighter from './CodeBrowserContentHighlighter';
23+
import DownloadFileButton from './DownloadFileButton';
2224

2325
type Props = {
2426
packageName: string;
@@ -29,6 +31,9 @@ type Props = {
2931
export 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 &quot;<code>{filePath}</code>&quot; file content.
171+
Cannot fetch <code style={tw`text-[90%]`}>&quot;{filePath}&quot;</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 &times;{' '}
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
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { type PropsWithChildren, type ReactNode } from 'react';
2+
import { View } from 'react-native';
3+
import { type Style } from 'twrnc';
4+
5+
import tw from '~/util/tailwind';
6+
7+
type Props = PropsWithChildren<{
8+
style?: Style | Style[];
9+
leftSlot?: ReactNode;
10+
rightSlot?: ReactNode;
11+
}>;
12+
13+
export default function CodeBrowserContentFooter({
14+
style,
15+
leftSlot = <View />,
16+
rightSlot = <View />,
17+
}: Props) {
18+
return (
19+
<View
20+
style={[
21+
tw`relative flex min-h-[26px] flex-row items-center justify-between gap-3 border-t border-palette-gray2 bg-default px-3 pb-px dark:border-default`,
22+
style,
23+
]}>
24+
{leftSlot}
25+
{rightSlot}
26+
</View>
27+
);
28+
}

scenes/PackageCodeScene.tsx

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Label, P, useLayout } from '~/common/styleguide';
66
import ContentContainer from '~/components/ContentContainer';
77
import { FileIcon, Search as SearchIcon } from '~/components/Icons';
88
import CodeBrowserContent from '~/components/Package/CodeBrowser/CodeBrowserContent';
9+
import CodeBrowserContentFooter from '~/components/Package/CodeBrowser/CodeBrowserContentFooter';
910
import CodeBrowserFileTree from '~/components/Package/CodeBrowser/CodeBrowserFileTree';
1011
import DetailsNavigation from '~/components/Package/DetailsNavigation';
1112
import NotFound from '~/components/Package/NotFound';
@@ -77,6 +78,11 @@ export default function PackageCodeScene({ apiData, packageName }: PackageCodePa
7778
[filteredFiles]
7879
);
7980

81+
const activeFileData = useMemo(
82+
() => data?.files.find(file => file.path === `${data.prefix}${activeFile}`),
83+
[data, activeFile]
84+
);
85+
8086
if (!library) {
8187
return <NotFound />;
8288
}
@@ -171,19 +177,20 @@ export default function PackageCodeScene({ apiData, packageName }: PackageCodePa
171177
)}
172178
</ScrollView>
173179
{filteredFiles.length > 0 && (
174-
<View
175-
style={[
176-
tw`relative flex min-h-[26px] flex-row items-center justify-between gap-3 border-r border-t border-palette-gray2 bg-default px-3 pb-px dark:border-default`,
177-
isSmallScreen && tw`border-r-0`,
178-
]}>
179-
<Label style={tw`font-light text-secondary`}>
180-
<span style={tw`font-medium`}>{filteredFiles.length}</span>{' '}
181-
{pluralize('file', filteredFiles.length)}
182-
</Label>
183-
<Label style={tw`font-light text-secondary`}>
184-
<span style={tw`font-medium`}>{formatBytes(totalFilesSize)}</span>
185-
</Label>
186-
</View>
180+
<CodeBrowserContentFooter
181+
style={isSmallScreen ? tw`border-r-0` : tw`border-r`}
182+
leftSlot={
183+
<Label style={tw`font-light text-secondary`}>
184+
<span style={tw`font-medium`}>{filteredFiles.length}</span>{' '}
185+
{pluralize('file', filteredFiles.length)}
186+
</Label>
187+
}
188+
rightSlot={
189+
<Label style={tw`font-light text-secondary`}>
190+
<span style={tw`font-medium`}>{formatBytes(totalFilesSize)}</span>
191+
</Label>
192+
}
193+
/>
187194
)}
188195
</View>
189196
<View
@@ -192,13 +199,11 @@ export default function PackageCodeScene({ apiData, packageName }: PackageCodePa
192199
activeFile ? tw`bg-white dark:bg-[#0d1117]` : tw`items-center justify-center`,
193200
isSmallScreen && tw`min-h-[50vh]`,
194201
]}>
195-
{activeFile ? (
202+
{activeFile && activeFileData ? (
196203
<CodeBrowserContent
197204
packageName={packageName}
198205
filePath={activeFile}
199-
fileData={data?.files.find(
200-
file => file.path === `${data.prefix}${activeFile}`
201-
)}
206+
fileData={activeFileData}
202207
/>
203208
) : (
204209
<View style={tw`flex flex-col items-center gap-1 px-3`}>

util/codeBrowser.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export const FILE_WARNINGS = [
4343
'.all-contributorsrc',
4444
'.babelrc',
4545
'.buckconfig',
46-
'.clang-format-ignore',
46+
'.clang-format*',
4747
'.eslintrc.js',
4848
'.flowconfig',
4949
'.gitattributes',
@@ -52,6 +52,8 @@ export const FILE_WARNINGS = [
5252
'.licence-config.yaml',
5353
'.prettierignore',
5454
'.project',
55+
'.swiftformat',
56+
'.swiftlint.yml',
5557
'.travis.yml',
5658
'.watchmanconfig',
5759
'babel.config.js',
@@ -61,6 +63,7 @@ export const FILE_WARNINGS = [
6163
'gradlew.bat',
6264
'jest*.config.js',
6365
'local.properties',
66+
'manifest-*makeinstall*',
6467
'metro.config.js',
6568
'nitro.json',
6669
'publish.gradle',

0 commit comments

Comments
 (0)