$ show GrapheneOS/PdfViewer
This is an Android PDF viewer application built with Jetpack Compose that uses Mozilla's pdf.js library for rendering. The app displays PDFs in a sandboxed WebView with strict security policies, handles encrypted PDFs, provides navigation controls, outline viewing, document properties, and various UI features like zoom, rotation, and text layer visibility. The architecture follows MVVM with a ViewModel managing state and a Compose UI layer. The app uses content providers to securely load PDF content without granting the WebView access to files or network.
The LLM identified 5 files worth highlighting for reuse:
Manages all UI state including document loading, zoom, rotation, password handling, outline, and document properties. Uses StateFlow for reactive updates and handles async operations like document property retrieval and outline parsing. Well-structured with clear separation of concerns and proper lifecycle management.
Serves as the secure JavaScript-to-Kotlin bridge between the pdf.js WebView and the Android application. Exposes only necessary functionality with input validation (e.g., zoom ratio clamping) and security checks (e.g., preventing multiple calls to setDocumentProperties). Demonstrates careful boundary design for WebView integration.
The main Compose UI screen that integrates the WebView with gesture handling, toolbar controls, and various dialogs. Implements sophisticated WebView lifecycle management, security-conscious resource loading via shouldInterceptRequest, and smooth integration between Compose and Android View systems. Shows excellent handling of complex UI state and edge cases.
A reusable gesture detector that combines scale and gesture detectors to handle pinch-to-zoom and fling navigation. Decoupled from specific UI logic through a listener interface, making it easily extractable for other projects needing touch-based zoom and navigation.
Efficiently parses PDF.js outline JSON into a tree structure using coroutines for non-blocking parsing. Implements a clean visitor pattern with proper state management via IdTracker. Demonstrates good use of Kotlin's coroutines and serialization for CPU-intensive parsing work off the main thread.