diff --git a/src/components/file_tree.rs b/src/components/file_tree.rs index 0fbf1f0..92c35e9 100644 --- a/src/components/file_tree.rs +++ b/src/components/file_tree.rs @@ -9,6 +9,16 @@ use std::rc::Rc; use web_sys::HtmlInputElement; use yew::prelude::*; +macro_rules! toggle_bool { + ($bool:expr) => {{ + let boolean = $bool.clone(); + Callback::from(move |event: MouseEvent| { + event.prevent_default(); + boolean.set(!*boolean); + }) + }}; +} + #[derive(PartialEq, Clone, Debug)] struct Context { old_krate: String, @@ -87,8 +97,17 @@ impl SearchFilter { } } +#[derive(Properties, PartialEq, Clone)] +pub struct FileNavigationProps { + pub diff: Rc, + pub path: Utf8PathBuf, +} + #[derive(Properties, PartialEq, Clone)] pub struct FileTreeProps { + search_filter: UseStateHandle, + change_filter: UseStateHandle, + is_expanded: UseStateHandle, pub diff: Rc, pub path: Utf8PathBuf, } @@ -260,22 +279,97 @@ fn SubTree(props: &SubTreeProps) -> Html { } #[function_component] -pub fn FileTree(props: &FileTreeProps) -> Html { - let entries = match props.diff.tree.item.clone() { - Item::File => Default::default(), - Item::Dir(entries) => entries, - }; - +pub fn FileTreeNavigation(props: &FileNavigationProps) -> Html { let change_filter = use_state(|| ChangeFilter::All); + let search_filter = use_state(|| SearchFilter::All); + let expanded = use_state_eq(|| true); + + if *expanded { + html! { + + } + } else { + html! { + + } + } +} + +#[function_component] +pub fn HiddenFileTree(props: &FileTreeProps) -> Html { + html! { +
+ +
+ } +} + +#[derive(Properties, PartialEq, Clone)] +pub struct FileTreeNavigationHeaderProps { + is_expanded: UseStateHandle, + search_filter: UseStateHandle, + change_filter: UseStateHandle, +} + +#[function_component] +pub fn FileTreeNavigationHeader(props: &FileTreeNavigationHeaderProps) -> Html { let change_filter_set = |filter: ChangeFilter| { - let change_filter = change_filter.clone(); + let change_filter = props.change_filter.clone(); move |event: MouseEvent| { change_filter.set(filter); event.prevent_default(); } }; - let search_filter = use_state(|| SearchFilter::All); + if *props.is_expanded { + html! { +
+ + +
+ + +
+
+ } + } else { + html! { +
+ +
+ } + } +} + +#[function_component] +pub fn ExpandedFileTree(props: &FileTreeProps) -> Html { + let entries = match props.diff.tree.item.clone() { + Item::File => Default::default(), + Item::Dir(entries) => entries, + }; + let prefix = Rc::new(Utf8PathBuf::default()); let active = Rc::new(props.path.clone()); @@ -288,28 +382,16 @@ pub fn FileTree(props: &FileTreeProps) -> Html { html! {
-
- -
- - -
-
+ { entries .into_iter() - .filter(|(_, entry)| change_filter.matches(entry.changes)) - .filter(|(_, entry)| search_filter.matches(&entry.name) || entry.item.is_dir()) + .filter(|(_, entry)| props.change_filter.matches(entry.changes)) + .filter(|(_, entry)| props.search_filter.matches(&entry.name) || entry.item.is_dir()) .map(|(key, entry)| html! { Html { prefix={prefix.clone()} active={active.clone()} context={context.clone()} - change_filter={*change_filter} - search_filter={(*search_filter).clone()} + change_filter={*props.change_filter} + search_filter={(*props.search_filter).clone()} /> }) .collect::() diff --git a/src/tailwind.css b/src/tailwind.css index aa62866..bfb70f5 100644 --- a/src/tailwind.css +++ b/src/tailwind.css @@ -31,6 +31,10 @@ @apply flex flex-row items-center gap-2 h-8 mb-2 mt-2; } + .file-tree .header .toggle { + @apply w-4 shrink-0; + } + .file-tree .header .button-group { @apply inline-flex rounded-md shadow-sm; } diff --git a/src/views/diff.rs b/src/views/diff.rs index 97719bc..d9f2905 100644 --- a/src/views/diff.rs +++ b/src/views/diff.rs @@ -293,12 +293,10 @@ pub fn SourceView(props: &SourceViewProps) -> Html { />
-
diff --git a/src/views/repo.rs b/src/views/repo.rs index 2935f49..f2acdfd 100644 --- a/src/views/repo.rs +++ b/src/views/repo.rs @@ -208,12 +208,10 @@ fn RepoSourceFetcherInner(props: &RepoSourceFetcherInnerProps) -> HtmlResult { Ok(html! {
- +