I'm also facing this problem some time while clicking the pdf its showing blank screen may i know the solution
import React, { useState, useCallback, ReactNode, Component } from "react";
import {
Text,
TouchableOpacity,
View,
Image,
ScrollView,
ActivityIndicator,
Alert,
Dimensions
} from "react-native";
import { WebView } from "react-native-webview";
import { useFocusEffect } from "expo-router";
import * as Linking from "expo-linking"; // 👈 for external browser
import Styles from "./DocumentStyles";
import StorageService from "@/constants/LocalStorage/AsyncStorage";
import { ApiService } from "@/src/Services/ApiServices";
interface DocumentItem {
id: number;
documentName: string;
fileUrl: string;
}
const generateRandomKey = (): number => Math.floor(Math.random() * 100000);
class WebViewErrorBoundary extends Component<
{ children: ReactNode; onReset: () => void },
{ hasError: boolean }
> {
constructor(props: { children: ReactNode; onReset: () => void }) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(): { hasError: boolean } {
return { hasError: true };
}
componentDidCatch(error: Error, info: any) {
console.error("[WebViewErrorBoundary] WebView crashed:", error, info);
this.props.onReset();
}
render() {
if (this.state.hasError) return <></>;
return this.props.children;
}
}
const Documents: React.FC = () => {
const [documents, setDocuments] = useState<DocumentItem[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const [selectedPdf, setSelectedPdf] = useState<DocumentItem | null>(null);
const [webViewKey, setWebViewKey] = useState<number>(generateRandomKey());
const fetchDocuments = async () => {
setLoading(true);
try {
const agentIdStr: string = (await StorageService.getData("agentId")) || "0";
const agentId: number = parseInt(agentIdStr, 10);
const response: DocumentItem[] = await ApiService.getDocuments(agentId);
setDocuments(response);
} catch (error) {
console.error("[Documents] Error fetching documents:", error);
} finally {
setLoading(false);
}
};
useFocusEffect(
useCallback(() => {
fetchDocuments();
}, [])
);
const openPdf = async (documentId: number) => {
try {
const agentIdStr: string = (await StorageService.getData("agentId")) || "0";
const agentId: number = parseInt(agentIdStr, 10);
const latestDocuments: DocumentItem[] = await ApiService.getDocuments(agentId);
const latestDoc = latestDocuments.find((doc) => doc.id === documentId);
if (!latestDoc) return;
setWebViewKey(generateRandomKey());
setSelectedPdf(latestDoc);
} catch (error) {
console.error("[Documents] Failed to open PDF:", error);
}
};
const closePdf = () => setSelectedPdf(null);
if (loading) return <ActivityIndicator size="large" style={{ flex: 1 }} />;
return (
<View style={{ flex: 1 }}>
{/* Document List */}
{!selectedPdf && (
<ScrollView showsVerticalScrollIndicator={false}>
<View style={{ margin: 15, marginBottom: 10 }}>
<View style={Styles.card}>
<Text style={Styles.headerText}>All Documents</Text>
{documents.map((item) => (
<View key={item.id} style={Styles.itemContainer}>
<TouchableOpacity onPress={() => openPdf(item.id)}>
<View style={Styles.itemWrapper}>
<View style={Styles.itemLeft}>
<Image
source={require("../../../assets/images/fileview.png")}
style={Styles.fileIcon}
/>
<Text style={Styles.itemText}>{item.documentName}</Text>
</View>
<Image
source={require("../../../assets/images/forward_icon.png")}
style={Styles.arrowIcon}
/>
</View>
</TouchableOpacity>
<View style={Styles.attachmentsingleline} />
</View>
))}
</View>
</View>
</ScrollView>
)}
{/* PDF Viewer */}
{selectedPdf && (
<WebViewErrorBoundary onReset={() => setWebViewKey(generateRandomKey())}>
<WebView
key={webViewKey}
source={{
uri: `https://docs.google.com/gview?embedded=true&url=${encodeURIComponent(
selectedPdf.fileUrl
)}`,
headers: { "Cache-Control": "no-cache", Pragma: "no-cache" },
}}
cacheEnabled={false}
startInLoadingState={true}
style = {{marginTop: 20, width: Dimensions.get('window').width, height: Dimensions.get('window').height}}
nestedScrollEnabled={true}
javaScriptEnabled={true}
domStorageEnabled={true}
renderLoading={() => <ActivityIndicator size="large" style={{ flex: 1 }} />}
onError={() => {
Alert.alert(
"PDF Error",
"Preview not available. Do you want to open in browser?",
[
{ text: "Cancel", style: "cancel" },
{ text: "Open", onPress: () => Linking.openURL(selectedPdf.fileUrl) },
]
);
}}
onContentProcessDidTerminate={() => {
console.warn("[Documents] WebView content terminated, reloading...");
setWebViewKey(generateRandomKey());
}}
/>
</WebViewErrorBoundary>
)}
</View>
);
};
export default Documents;