Clean up project structure
This commit is contained in:
55
brittle-ui/src/pdf_viewer.rs
Normal file
55
brittle-ui/src/pdf_viewer.rs
Normal file
@@ -0,0 +1,55 @@
|
||||
//! PDF viewer tab: embeds the Tauri-served PDF viewer in an iframe.
|
||||
//!
|
||||
//! The custom `brittle://` URI scheme serves:
|
||||
//! - `brittle://app/viewer?ref_id=<uuid>` — the viewer HTML page (PDF.js)
|
||||
//! - `brittle://app/pdf?ref_id=<uuid>` — the raw PDF bytes
|
||||
//!
|
||||
//! Using an `<iframe>` keeps the viewer alive when the tab is hidden (via
|
||||
//! `display:none`), so scrolling position and zoom are preserved across
|
||||
//! tab switches.
|
||||
|
||||
use brittle_keymap::actions;
|
||||
use leptos::prelude::*;
|
||||
use wasm_bindgen::JsValue;
|
||||
|
||||
/// Renders the PDF viewer for a single reference.
|
||||
///
|
||||
/// `ref_id` must be the UUID string of a reference that has an attached PDF.
|
||||
/// `is_active` indicates whether this is the currently visible PDF tab; when
|
||||
/// `true`, keymap actions for PDF page navigation are forwarded into the iframe.
|
||||
#[component]
|
||||
pub fn PdfViewer(ref_id: String, is_active: Signal<bool>) -> impl IntoView {
|
||||
let url = format!("brittle://app/viewer?ref_id={ref_id}");
|
||||
|
||||
let iframe_ref = NodeRef::<leptos::html::Iframe>::new();
|
||||
|
||||
let keymap_action = use_context::<crate::KeymapAction>()
|
||||
.expect("KeymapAction context missing")
|
||||
.0;
|
||||
|
||||
Effect::new(move |_| {
|
||||
let Some(ev) = keymap_action.get() else { return };
|
||||
if !is_active.get_untracked() { return }
|
||||
|
||||
let cmd = match ev.name.as_str() {
|
||||
actions::PDF_PAGE_NEXT => actions::PDF_PAGE_NEXT,
|
||||
actions::PDF_PAGE_PREV => actions::PDF_PAGE_PREV,
|
||||
_ => return,
|
||||
};
|
||||
|
||||
let Some(iframe) = iframe_ref.get() else { return };
|
||||
if let Some(win) = iframe.content_window() {
|
||||
let _ = win.post_message(&JsValue::from_str(cmd), "*");
|
||||
}
|
||||
});
|
||||
|
||||
view! {
|
||||
<iframe
|
||||
node_ref=iframe_ref
|
||||
class="pdf-frame"
|
||||
src=url
|
||||
// Intentionally no `sandbox` attribute — the brittle:// protocol
|
||||
// and PDF.js require unrestricted access within the webview.
|
||||
/>
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user