//! Full-page file view (opened files take over the whole content area). //! //! The top bar doubles as the file's header: the file name where the brand //! was, with save/close on the right. Used by both the signed-in shell and //! the public share page. use crate::i18n; use api_types::FileKind; use leptos::prelude::*; use crate::api; use crate::components::icon::icon_svg; use crate::components::toast::{ToastMsg, show}; use crate::icons::{IconName, icon_for}; /// A file that is open in the full-page view. #[derive(Clone)] pub struct FileView { pub root_id: i64, /// Path relative to the root (e.g. "docs/a.txt"). pub path: String, /// Display name (used for the title + language detection). pub name: String, /// Sniffed kind: picks the viewer and the icon. pub kind: FileKind, /// True when the file's folder is read-only. Only the editor acts on it. pub readonly: bool, } /// Top-bar replacement for the brand: file icon + name (with a dirty dot) /// and, for read-only text files, a badge. #[component] pub fn FileViewTitle(view: FileView, dirty: ReadSignal) -> impl IntoView { let icon = icon_for(view.kind, &view.name); let readonly = view.kind == FileKind::Text && view.readonly; let name = view.name; view! {
{icon_svg(icon, "file-title-icon")} {move || { let dot = if dirty.get() { " •" } else { "" }; format!("{name}{dot}") }} {readonly.then(|| view! { {i18n::t(i18n::k::READ_ONLY_BADGE)} })}
} } /// Top-bar actions: Save (only present while an editable file has /// registered its save callback), Download and close. #[component] pub fn FileViewActions( /// The open file — the download button targets it. view: FileView, saving: ReadSignal, dirty: ReadSignal, save_cb: ReadSignal>>, /// The editor registers its close request here (it asks about unsaved /// changes first); other views close directly. close_cb: ReadSignal>>, /// Whether the close button is shown at all: closing means "back to /// the listing", so it is hidden when there is nothing to go back to /// (file shares). show_close: bool, on_close: Callback<()>, toast: ToastMsg, ) -> impl IntoView { // Serves the file from disk (for an open editor: the saved version, // not the working copy). Built once per open file — nothing about it // is reactive. let download_btn = { let dl = view; view! { } }; view! {
{move || save_cb.get().map(|cb| view! { })} {download_btn} {show_close.then(|| view! { })}
} }