Files
orca/mobile/src/files/MobileFileMarkdownPreview.tsx
T

87 lines
3.0 KiB
TypeScript

import { useState } from 'react'
import { Pressable, ScrollView, View } from 'react-native'
import { Code, Pencil } from 'lucide-react-native'
import { MobileMarkdown } from '../components/MobileMarkdown'
import { colors } from '../theme/mobile-theme'
import {
MobileFilePreviewSourceText,
MobileFilePreviewTruncatedNote
} from './MobileFilePreviewSourceText'
import { filePreviewStyles as styles } from './mobile-file-preview-styles'
type Props = {
relativePath: string
content: string
truncated: boolean
byteLength: number
initialLine?: number
}
export function MobileFileMarkdownPreview({
relativePath,
content,
truncated,
byteLength,
initialLine
}: Props) {
const [mode, setMode] = useState<'preview' | 'source'>(() => (initialLine ? 'source' : 'preview'))
const [previousRelativePath, setPreviousRelativePath] = useState(relativePath)
const [previousInitialLine, setPreviousInitialLine] = useState(initialLine)
// Why: opening a different file or line target must switch modes before paint,
// never briefly retain the prior file's manually selected mode.
if (relativePath !== previousRelativePath || initialLine !== previousInitialLine) {
setPreviousRelativePath(relativePath)
setPreviousInitialLine(initialLine)
setMode(initialLine ? 'source' : 'preview')
}
const previewSelected = mode === 'preview'
const sourceSelected = mode === 'source'
return (
<View style={styles.modeContainer}>
<View style={styles.modeToolbar}>
<Pressable
style={[styles.modeToggle, sourceSelected && styles.modeToggleActive]}
onPress={() => setMode('source')}
accessibilityRole="button"
accessibilityState={{ selected: sourceSelected }}
accessibilityLabel="View Markdown source"
>
<Code
size={15}
color={sourceSelected ? colors.textPrimary : colors.textSecondary}
strokeWidth={2.2}
/>
</Pressable>
<Pressable
style={[styles.modeToggle, previewSelected && styles.modeToggleActive]}
onPress={() => setMode('preview')}
accessibilityRole="button"
accessibilityState={{ selected: previewSelected }}
accessibilityLabel="View rendered Markdown preview"
>
<Pencil
size={15}
color={previewSelected ? colors.textPrimary : colors.textSecondary}
strokeWidth={2.2}
/>
</Pressable>
</View>
{mode === 'preview' ? (
<ScrollView style={styles.scroll} contentContainerStyle={styles.markdownContent}>
{truncated ? <MobileFilePreviewTruncatedNote byteLength={byteLength} /> : null}
<MobileMarkdown content={content} />
</ScrollView>
) : (
<MobileFilePreviewSourceText
relativePath={relativePath}
content={content}
truncated={truncated}
byteLength={byteLength}
initialLine={initialLine}
/>
)}
</View>
)
}