Switch to double quotes and reformat codebase with Biome
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import React, { useCallback, useMemo, useRef } from 'react'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import React, { useCallback, useMemo, useRef } from "react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Image as RNImage,
|
||||
@@ -10,54 +10,54 @@ import {
|
||||
type LayoutChangeEvent,
|
||||
type NativeScrollEvent,
|
||||
type NativeSyntheticEvent,
|
||||
} from 'react-native'
|
||||
import { StyleSheet, UnistylesRuntime, useUnistyles } from 'react-native-unistyles'
|
||||
import { Fonts } from '@/constants/theme'
|
||||
import { useSessionStore, type ExplorerFile } from '@/stores/session-store'
|
||||
} from "react-native";
|
||||
import { StyleSheet, UnistylesRuntime, useUnistyles } from "react-native-unistyles";
|
||||
import { Fonts } from "@/constants/theme";
|
||||
import { useSessionStore, type ExplorerFile } from "@/stores/session-store";
|
||||
import {
|
||||
WebDesktopScrollbarOverlay,
|
||||
useWebDesktopScrollbarMetrics,
|
||||
} from '@/components/web-desktop-scrollbar'
|
||||
} from "@/components/web-desktop-scrollbar";
|
||||
import {
|
||||
highlightCode,
|
||||
darkHighlightColors,
|
||||
lightHighlightColors,
|
||||
type HighlightToken,
|
||||
type HighlightStyle,
|
||||
} from '@getpaseo/highlight'
|
||||
} from "@getpaseo/highlight";
|
||||
|
||||
interface CodeLineProps {
|
||||
tokens: HighlightToken[]
|
||||
lineNumber: number
|
||||
gutterWidth: number
|
||||
colorMap: Record<HighlightStyle, string>
|
||||
baseColor: string
|
||||
tokens: HighlightToken[];
|
||||
lineNumber: number;
|
||||
gutterWidth: number;
|
||||
colorMap: Record<HighlightStyle, string>;
|
||||
baseColor: string;
|
||||
}
|
||||
|
||||
interface FilePreviewBodyProps {
|
||||
preview: ExplorerFile | null
|
||||
isLoading: boolean
|
||||
showDesktopWebScrollbar: boolean
|
||||
isMobile: boolean
|
||||
filePath: string
|
||||
preview: ExplorerFile | null;
|
||||
isLoading: boolean;
|
||||
showDesktopWebScrollbar: boolean;
|
||||
isMobile: boolean;
|
||||
filePath: string;
|
||||
}
|
||||
|
||||
function trimNonEmpty(value: string | null | undefined): string | null {
|
||||
if (typeof value !== 'string') {
|
||||
return null
|
||||
if (typeof value !== "string") {
|
||||
return null;
|
||||
}
|
||||
const trimmed = value.trim()
|
||||
return trimmed.length > 0 ? trimmed : null
|
||||
const trimmed = value.trim();
|
||||
return trimmed.length > 0 ? trimmed : null;
|
||||
}
|
||||
|
||||
function formatFileSize({ size }: { size: number }): string {
|
||||
if (size < 1024) {
|
||||
return `${size} B`
|
||||
return `${size} B`;
|
||||
}
|
||||
if (size < 1024 * 1024) {
|
||||
return `${(size / 1024).toFixed(1)} KB`
|
||||
return `${(size / 1024).toFixed(1)} KB`;
|
||||
}
|
||||
return `${(size / (1024 * 1024)).toFixed(1)} MB`
|
||||
return `${(size / (1024 * 1024)).toFixed(1)} MB`;
|
||||
}
|
||||
|
||||
const CodeLine = React.memo(function CodeLine({
|
||||
@@ -76,22 +76,22 @@ const CodeLine = React.memo(function CodeLine({
|
||||
{tokens.map((token, index) => (
|
||||
<Text
|
||||
key={index}
|
||||
style={{ color: token.style ? colorMap[token.style] ?? baseColor : baseColor }}
|
||||
style={{ color: token.style ? (colorMap[token.style] ?? baseColor) : baseColor }}
|
||||
>
|
||||
{token.text}
|
||||
</Text>
|
||||
))}
|
||||
</Text>
|
||||
</View>
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
const codeLineStyles = StyleSheet.create((theme) => ({
|
||||
line: {
|
||||
flexDirection: 'row',
|
||||
flexDirection: "row",
|
||||
},
|
||||
gutter: {
|
||||
alignItems: 'flex-end',
|
||||
alignItems: "flex-end",
|
||||
paddingRight: theme.spacing[3],
|
||||
flexShrink: 0,
|
||||
},
|
||||
@@ -107,7 +107,7 @@ const codeLineStyles = StyleSheet.create((theme) => ({
|
||||
lineHeight: theme.fontSize.sm * 1.45,
|
||||
flex: 1,
|
||||
},
|
||||
}))
|
||||
}));
|
||||
|
||||
function FilePreviewBody({
|
||||
preview,
|
||||
@@ -116,46 +116,46 @@ function FilePreviewBody({
|
||||
isMobile,
|
||||
filePath,
|
||||
}: FilePreviewBodyProps) {
|
||||
const { theme } = useUnistyles()
|
||||
const isDark = theme.colors.surface0 === '#18181c'
|
||||
const colorMap = isDark ? darkHighlightColors : lightHighlightColors
|
||||
const baseColor = isDark ? '#c9d1d9' : '#24292f'
|
||||
const { theme } = useUnistyles();
|
||||
const isDark = theme.colors.surface0 === "#18181c";
|
||||
const colorMap = isDark ? darkHighlightColors : lightHighlightColors;
|
||||
const baseColor = isDark ? "#c9d1d9" : "#24292f";
|
||||
|
||||
const enablePreviewDesktopScrollbar = showDesktopWebScrollbar
|
||||
const previewScrollRef = useRef<RNScrollView>(null)
|
||||
const previewScrollbarMetrics = useWebDesktopScrollbarMetrics()
|
||||
const enablePreviewDesktopScrollbar = showDesktopWebScrollbar;
|
||||
const previewScrollRef = useRef<RNScrollView>(null);
|
||||
const previewScrollbarMetrics = useWebDesktopScrollbarMetrics();
|
||||
|
||||
const highlightedLines = useMemo(() => {
|
||||
if (!preview || preview.kind !== 'text') {
|
||||
return null
|
||||
if (!preview || preview.kind !== "text") {
|
||||
return null;
|
||||
}
|
||||
|
||||
return highlightCode(preview.content ?? '', filePath)
|
||||
}, [preview?.kind, preview?.content, filePath])
|
||||
return highlightCode(preview.content ?? "", filePath);
|
||||
}, [preview?.kind, preview?.content, filePath]);
|
||||
|
||||
const gutterWidth = useMemo(() => {
|
||||
if (!highlightedLines) return 0
|
||||
const digits = String(highlightedLines.length).length
|
||||
return Math.max(digits * 8 + 12, 28)
|
||||
}, [highlightedLines])
|
||||
if (!highlightedLines) return 0;
|
||||
const digits = String(highlightedLines.length).length;
|
||||
return Math.max(digits * 8 + 12, 28);
|
||||
}, [highlightedLines]);
|
||||
|
||||
const handlePreviewScroll = useCallback(
|
||||
(event: NativeSyntheticEvent<NativeScrollEvent>) => {
|
||||
if (enablePreviewDesktopScrollbar) {
|
||||
previewScrollbarMetrics.onScroll(event)
|
||||
previewScrollbarMetrics.onScroll(event);
|
||||
}
|
||||
},
|
||||
[enablePreviewDesktopScrollbar, previewScrollbarMetrics]
|
||||
)
|
||||
[enablePreviewDesktopScrollbar, previewScrollbarMetrics],
|
||||
);
|
||||
|
||||
const handlePreviewLayout = useCallback(
|
||||
(event: LayoutChangeEvent) => {
|
||||
if (enablePreviewDesktopScrollbar) {
|
||||
previewScrollbarMetrics.onLayout(event)
|
||||
previewScrollbarMetrics.onLayout(event);
|
||||
}
|
||||
},
|
||||
[enablePreviewDesktopScrollbar, previewScrollbarMetrics]
|
||||
)
|
||||
[enablePreviewDesktopScrollbar, previewScrollbarMetrics],
|
||||
);
|
||||
|
||||
if (isLoading && !preview) {
|
||||
return (
|
||||
@@ -163,7 +163,7 @@ function FilePreviewBody({
|
||||
<ActivityIndicator size="small" />
|
||||
<Text style={styles.loadingText}>Loading file…</Text>
|
||||
</View>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!preview) {
|
||||
@@ -171,11 +171,11 @@ function FilePreviewBody({
|
||||
<View style={styles.centerState}>
|
||||
<Text style={styles.emptyText}>No preview available</Text>
|
||||
</View>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (preview.kind === 'text') {
|
||||
const lines = highlightedLines ?? [[{ text: preview.content ?? '', style: null }]]
|
||||
if (preview.kind === "text") {
|
||||
const lines = highlightedLines ?? [[{ text: preview.content ?? "", style: null }]];
|
||||
const codeLines = (
|
||||
<View>
|
||||
{lines.map((tokens, index) => (
|
||||
@@ -189,7 +189,7 @@ function FilePreviewBody({
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
)
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={styles.previewScrollContainer}>
|
||||
@@ -221,14 +221,14 @@ function FilePreviewBody({
|
||||
enabled={enablePreviewDesktopScrollbar}
|
||||
metrics={previewScrollbarMetrics}
|
||||
onScrollToOffset={(nextOffset) => {
|
||||
previewScrollRef.current?.scrollTo({ y: nextOffset, animated: false })
|
||||
previewScrollRef.current?.scrollTo({ y: nextOffset, animated: false });
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (preview.kind === 'image' && preview.content) {
|
||||
if (preview.kind === "image" && preview.content) {
|
||||
return (
|
||||
<View style={styles.previewScrollContainer}>
|
||||
<RNScrollView
|
||||
@@ -245,7 +245,7 @@ function FilePreviewBody({
|
||||
>
|
||||
<RNImage
|
||||
source={{
|
||||
uri: `data:${preview.mimeType ?? 'image/png'};base64,${preview.content}`,
|
||||
uri: `data:${preview.mimeType ?? "image/png"};base64,${preview.content}`,
|
||||
}}
|
||||
style={styles.previewImage}
|
||||
resizeMode="contain"
|
||||
@@ -255,11 +255,11 @@ function FilePreviewBody({
|
||||
enabled={enablePreviewDesktopScrollbar}
|
||||
metrics={previewScrollbarMetrics}
|
||||
onScrollToOffset={(nextOffset) => {
|
||||
previewScrollRef.current?.scrollTo({ y: nextOffset, animated: false })
|
||||
previewScrollRef.current?.scrollTo({ y: nextOffset, animated: false });
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -267,7 +267,7 @@ function FilePreviewBody({
|
||||
<Text style={styles.emptyText}>Binary preview unavailable</Text>
|
||||
<Text style={styles.binaryMetaText}>{formatFileSize({ size: preview.size })}</Text>
|
||||
</View>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function FilePane({
|
||||
@@ -275,33 +275,33 @@ export function FilePane({
|
||||
workspaceRoot,
|
||||
filePath,
|
||||
}: {
|
||||
serverId: string
|
||||
workspaceRoot: string
|
||||
filePath: string
|
||||
serverId: string;
|
||||
workspaceRoot: string;
|
||||
filePath: string;
|
||||
}) {
|
||||
const isMobile = UnistylesRuntime.breakpoint === 'xs' || UnistylesRuntime.breakpoint === 'sm'
|
||||
const showDesktopWebScrollbar = Platform.OS === 'web' && !isMobile
|
||||
const isMobile = UnistylesRuntime.breakpoint === "xs" || UnistylesRuntime.breakpoint === "sm";
|
||||
const showDesktopWebScrollbar = Platform.OS === "web" && !isMobile;
|
||||
|
||||
const client = useSessionStore((state) => state.sessions[serverId]?.client ?? null)
|
||||
const normalizedWorkspaceRoot = useMemo(() => workspaceRoot.trim(), [workspaceRoot])
|
||||
const normalizedFilePath = useMemo(() => trimNonEmpty(filePath), [filePath])
|
||||
const client = useSessionStore((state) => state.sessions[serverId]?.client ?? null);
|
||||
const normalizedWorkspaceRoot = useMemo(() => workspaceRoot.trim(), [workspaceRoot]);
|
||||
const normalizedFilePath = useMemo(() => trimNonEmpty(filePath), [filePath]);
|
||||
|
||||
const query = useQuery({
|
||||
queryKey: ['workspaceFile', serverId, normalizedWorkspaceRoot, normalizedFilePath],
|
||||
queryKey: ["workspaceFile", serverId, normalizedWorkspaceRoot, normalizedFilePath],
|
||||
enabled: Boolean(client && normalizedWorkspaceRoot && normalizedFilePath),
|
||||
queryFn: async () => {
|
||||
if (!client || !normalizedWorkspaceRoot || !normalizedFilePath) {
|
||||
return { file: null as ExplorerFile | null, error: 'Host is not connected' }
|
||||
return { file: null as ExplorerFile | null, error: "Host is not connected" };
|
||||
}
|
||||
const payload = await client.exploreFileSystem(
|
||||
normalizedWorkspaceRoot,
|
||||
normalizedFilePath,
|
||||
'file'
|
||||
)
|
||||
return { file: payload.file ?? null, error: payload.error ?? null }
|
||||
"file",
|
||||
);
|
||||
return { file: payload.file ?? null, error: payload.error ?? null };
|
||||
},
|
||||
staleTime: 5_000,
|
||||
})
|
||||
});
|
||||
|
||||
return (
|
||||
<View style={styles.container} testID="workspace-file-pane">
|
||||
@@ -319,7 +319,7 @@ export function FilePane({
|
||||
filePath={filePath}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create((theme) => ({
|
||||
@@ -330,8 +330,8 @@ const styles = StyleSheet.create((theme) => ({
|
||||
},
|
||||
centerState: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
padding: theme.spacing[4],
|
||||
},
|
||||
loadingText: {
|
||||
@@ -342,12 +342,12 @@ const styles = StyleSheet.create((theme) => ({
|
||||
errorText: {
|
||||
color: theme.colors.destructive,
|
||||
fontSize: theme.fontSize.sm,
|
||||
textAlign: 'center',
|
||||
textAlign: "center",
|
||||
},
|
||||
emptyText: {
|
||||
color: theme.colors.foregroundMuted,
|
||||
fontSize: theme.fontSize.sm,
|
||||
textAlign: 'center',
|
||||
textAlign: "center",
|
||||
},
|
||||
binaryMetaText: {
|
||||
marginTop: theme.spacing[2],
|
||||
@@ -368,11 +368,11 @@ const styles = StyleSheet.create((theme) => ({
|
||||
previewImageScrollContent: {
|
||||
flexGrow: 1,
|
||||
padding: theme.spacing[4],
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
},
|
||||
previewImage: {
|
||||
width: '100%',
|
||||
width: "100%",
|
||||
height: 420,
|
||||
},
|
||||
}))
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user