Add zooming in/out to PDF

This commit is contained in:
2026-03-25 10:54:14 +01:00
parent 75dcacf011
commit 0b354462e0
14 changed files with 386 additions and 95 deletions

View File

@@ -19,6 +19,12 @@ use crate::state::AppState;
// ── Embedded assets ───────────────────────────────────────────────────────────
static VIEWER_HTML: &[u8] = include_bytes!("pdf_viewer.html");
static PDFJS_MIN_JS: &[u8] = include_bytes!(
"../pdfjs/node_modules/pdfjs-dist/build/pdf.min.js"
);
static PDFJS_WORKER_JS: &[u8] = include_bytes!(
"../pdfjs/node_modules/pdfjs-dist/build/pdf.worker.min.js"
);
// ── Public API ────────────────────────────────────────────────────────────────
@@ -35,7 +41,7 @@ pub fn handle<R: Runtime>(app: &AppHandle<R>, req: &Request<Vec<u8>>) -> Respons
if rel_path.contains("..") {
return response_403();
}
serve_pdfjs_file(&pdfjs_root(app), &rel_path)
serve_pdfjs_file(&rel_path)
}
routing::Route::Pdf { ref_id } => serve_pdf(app, &ref_id),
routing::Route::NotFound => response_404(),
@@ -51,20 +57,18 @@ fn serve_viewer(ref_id: &str) -> Response<Vec<u8>> {
response_ok(html.into_bytes(), "text/html; charset=utf-8")
}
fn serve_pdfjs_file(pdfjs_root: &std::path::Path, rel_path: &str) -> Response<Vec<u8>> {
let full_path = pdfjs_root.join(rel_path);
match std::fs::read(&full_path) {
Ok(bytes) => {
let mime = routing::mime_for_path(&full_path);
let mut resp = response_ok(bytes, mime);
resp.headers_mut().insert(
header::CACHE_CONTROL,
"public, max-age=3600".parse().unwrap(),
);
resp
}
Err(_) => response_404(),
}
fn serve_pdfjs_file(rel_path: &str) -> Response<Vec<u8>> {
let bytes: &[u8] = match rel_path {
"build/pdf.min.js" => PDFJS_MIN_JS,
"build/pdf.worker.min.js" => PDFJS_WORKER_JS,
_ => return response_404(),
};
let mut resp = response_ok(bytes.to_vec(), "application/javascript; charset=utf-8");
resp.headers_mut().insert(
header::CACHE_CONTROL,
"public, max-age=3600".parse().unwrap(),
);
resp
}
fn serve_pdf<R: Runtime>(app: &AppHandle<R>, ref_id: &str) -> Response<Vec<u8>> {
@@ -95,22 +99,6 @@ fn serve_pdf<R: Runtime>(app: &AppHandle<R>, ref_id: &str) -> Response<Vec<u8>>
}
}
// ── Path resolution ───────────────────────────────────────────────────────────
fn pdfjs_root<R: Runtime>(app: &AppHandle<R>) -> PathBuf {
if cfg!(debug_assertions) {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("pdfjs")
.join("node_modules")
.join("pdfjs-dist")
} else {
app.path()
.resource_dir()
.unwrap_or_default()
.join("pdfjs-dist")
}
}
// ── Response builders ─────────────────────────────────────────────────────────
fn response_ok(body: Vec<u8>, content_type: &str) -> Response<Vec<u8>> {