mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-27 19:52:49 +00:00
The file tab stats the file and mounts its panel without reading it. Every panel, built-in or plugin, gets a PluginFile handle: readText, readBytes, url, version-checked writeText/writeBytes (PluginFileConflictError unless force), and watch. useFileText, useFileBytes and useFileUrl read through it, and Loading joins @getpaseo/plugin/client/ui. Panels own their loading state. The host document pipeline, the explorer preview cache and the preview lifecycle are deleted. The daemon classifies a file version from a bounded sniff and writes base64 content as bytes behind fileByteWrites. A deleted file keeps its panel mounted; a read confirms the deletion first, so a remove-and-rewrite is not reported as one. Native Source decodes with builtins and highlights in idle-time slices, the lines around the opening line first, so a large file no longer blocks the JS thread.
42 lines
1.3 KiB
TypeScript
42 lines
1.3 KiB
TypeScript
import { type PluginFilePanelProps, useFileUrl } from "@getpaseo/plugin/client";
|
|
import { DocumentFrame, Loading } from "@getpaseo/plugin/client/ui";
|
|
import { useMemo } from "react";
|
|
import { Text, View } from "react-native";
|
|
|
|
const messageStyle = {
|
|
flex: 1,
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
padding: 24,
|
|
} as const;
|
|
|
|
export function PdfPanel(props: PluginFilePanelProps) {
|
|
if (props.layout.platform === "android") return <AndroidPdf {...props} />;
|
|
return <InlinePdf {...props} />;
|
|
}
|
|
|
|
function InlinePdf({ file, theme }: PluginFilePanelProps) {
|
|
const url = useFileUrl(file);
|
|
const textStyle = useMemo(() => ({ color: theme.colors.statusDanger }), [theme]);
|
|
if (url.status === "loading") return <Loading />;
|
|
if (url.status === "error") {
|
|
return (
|
|
<View style={messageStyle}>
|
|
<Text style={textStyle}>{url.error.message}</Text>
|
|
</View>
|
|
);
|
|
}
|
|
return <DocumentFrame url={url.url} testID="pdf-panel" />;
|
|
}
|
|
|
|
function AndroidPdf({ file, theme }: PluginFilePanelProps) {
|
|
const textStyle = useMemo(() => ({ color: theme.colors.foregroundMuted }), [theme]);
|
|
return (
|
|
<View style={messageStyle}>
|
|
<Text style={textStyle}>
|
|
{file.name} ({Math.round(file.size / 1024)} KB). Android cannot render PDF inline.
|
|
</Text>
|
|
</View>
|
|
);
|
|
}
|