preview.rs
⎇
Raw
1//! File previews: browser-native media (image/PDF/video/audio), full page.
2//! Text files open in the editor instead.
3
4use api_types::FileKind;
5use leptos::prelude::*;
6
7use crate::api;
8
9/// What kind of preview a file gets.
10#[derive(Clone, Copy, PartialEq, Eq)]
11pub enum PreviewKind {
12 Image,
13 Pdf,
14 Video,
15 Audio,
16}
17
18/// Which viewer opens this entry, from the server's sniffed [`FileKind`].
19/// `None` = nothing we can preview here: text goes to the editor, archives
20/// and binaries get the "no preview" view.
21pub fn preview_kind(kind: FileKind) -> Option<PreviewKind> {
22 match kind {
23 FileKind::Image => Some(PreviewKind::Image),
24 FileKind::Pdf => Some(PreviewKind::Pdf),
25 FileKind::Video => Some(PreviewKind::Video),
26 FileKind::Audio => Some(PreviewKind::Audio),
27 FileKind::Dir | FileKind::Archive | FileKind::Binary | FileKind::Text => None,
28 }
29}
30
31/// A file the user wants to preview.
32#[derive(Clone)]
33pub struct PreviewTarget {
34 pub root_id: i64,
35 /// Path relative to the root (e.g. "docs/a.txt").
36 pub path: String,
37 /// Display name (used for the title + language detection).
38 pub name: String,
39}
40
41/// The full-page media preview (closing lives in the top bar).
42#[component]
43pub fn Preview(target: PreviewTarget, kind: PreviewKind) -> impl IntoView {
44 let t = target;
45 let url = api::preview_url(t.root_id, &t.path);
46 view! {
47 <div class="preview-body file-preview">
48 {move || match kind {
49 PreviewKind::Image => {
50 view! { <img class="preview-img" src=url.clone() alt=t.name.clone()/> }
51 .into_view()
52 .into_any()
53 }
54 PreviewKind::Pdf => {
55 view! { <iframe class="preview-pdf" src=url.clone() title=t.name.clone()/> }
56 .into_view()
57 .into_any()
58 }
59 PreviewKind::Video => {
60 view! { <video class="preview-video" src=url.clone() controls=true/> }
61 .into_view()
62 .into_any()
63 }
64 PreviewKind::Audio => {
65 view! {
66 <div class="preview-audio">
67 <audio src=url.clone() controls=true/>
68 </div>
69 }
70 .into_view()
71 .into_any()
72 }
73 }}
74 </div>
75 }
76}
77