diff --git a/crates/git_ui/src/git_panel.rs b/crates/git_ui/src/git_panel.rs index 9672b0d244a..b6e5b7e7634 100644 --- a/crates/git_ui/src/git_panel.rs +++ b/crates/git_ui/src/git_panel.rs @@ -67,9 +67,11 @@ use settings::{ update_settings_file, }; use smallvec::SmallVec; +use std::cell::Cell; use std::future::Future; use std::ops::Range; use std::path::Path; +use std::rc::Rc; use std::{sync::Arc, time::Duration, usize}; use strum::{IntoEnumIterator, VariantNames}; use theme_settings::ThemeSettings; @@ -163,7 +165,8 @@ enum TrashCancel { Cancel, } -struct GitMenuState { +#[derive(Clone, Copy)] +struct GitPanelViewOptionsMenuState { sort_by: GitPanelSortBy, group_by: GitPanelGroupBy, tree_view: bool, @@ -208,74 +211,111 @@ fn git_panel_context_menu( fn git_panel_view_options_menu( focus_handle: FocusHandle, - state: GitMenuState, window: &mut Window, cx: &mut App, ) -> Entity { - ContextMenu::build(window, cx, move |context_menu, _, _| { + let view_options_menu_state = Rc::new(Cell::new(GitPanelViewOptionsMenuState { + sort_by: GitPanelSettings::get_global(cx).sort_by, + group_by: GitPanelSettings::get_global(cx).group_by, + tree_view: GitPanelSettings::get_global(cx).tree_view, + })); + + ContextMenu::build_persistent(window, cx, move |context_menu, _, _| { + let state = view_options_menu_state.get(); + context_menu - .context(focus_handle) + .context(focus_handle.clone()) .header("View") - .item( + .item({ + let view_options_menu_state = view_options_menu_state.clone(); ContextMenuEntry::new("List") .toggle(IconPosition::End, !state.tree_view) .handler(move |window, cx| { if state.tree_view { + view_options_menu_state.set(GitPanelViewOptionsMenuState { + tree_view: false, + ..state + }); window.dispatch_action(Box::new(ToggleTreeView), cx); } - }), - ) - .item( + }) + }) + .item({ + let view_options_menu_state = view_options_menu_state.clone(); ContextMenuEntry::new("Tree") .toggle(IconPosition::End, state.tree_view) .handler(move |window, cx| { if !state.tree_view { + view_options_menu_state.set(GitPanelViewOptionsMenuState { + tree_view: true, + ..state + }); window.dispatch_action(Box::new(ToggleTreeView), cx); } - }), - ) + }) + }) .when(!state.tree_view, |this| { this.separator() .header("Sort By") - .item( + .item({ + let view_options_menu_state = view_options_menu_state.clone(); ContextMenuEntry::new("Path") .toggle(IconPosition::End, state.sort_by == GitPanelSortBy::Path) .handler(move |window, cx| { if !state.tree_view { + view_options_menu_state.set(GitPanelViewOptionsMenuState { + sort_by: GitPanelSortBy::Path, + ..state + }); window.dispatch_action(Box::new(SetSortByPath), cx); } - }), - ) - .item( + }) + }) + .item({ + let view_options_menu_state = view_options_menu_state.clone(); ContextMenuEntry::new("Name") .toggle(IconPosition::End, state.sort_by == GitPanelSortBy::Name) .handler(move |window, cx| { if !state.tree_view { + view_options_menu_state.set(GitPanelViewOptionsMenuState { + sort_by: GitPanelSortBy::Name, + ..state + }); window.dispatch_action(Box::new(SetSortByName), cx); } - }), - ) + }) + }) }) .separator() .header("Group By") - .item( + .item({ + let view_options_menu_state = view_options_menu_state.clone(); ContextMenuEntry::new("None") .toggle(IconPosition::End, state.group_by == GitPanelGroupBy::None) .handler(move |window, cx| { if state.group_by != GitPanelGroupBy::None { + view_options_menu_state.set(GitPanelViewOptionsMenuState { + group_by: GitPanelGroupBy::None, + ..state + }); window.dispatch_action(Box::new(SetGroupByNone), cx); } - }), - ) - .item( + }) + }) + .item({ + let view_options_menu_state = view_options_menu_state.clone(); ContextMenuEntry::new("Status") .toggle(IconPosition::End, state.group_by == GitPanelGroupBy::Status) .handler(move |window, cx| { if state.group_by != GitPanelGroupBy::Status { + view_options_menu_state.set(GitPanelViewOptionsMenuState { + group_by: GitPanelGroupBy::Status, + ..state + }); window.dispatch_action(Box::new(SetGroupByStatus), cx); } - }), - ) + }) + }) }) } @@ -4465,11 +4505,6 @@ impl GitPanel { .menu(move |window, cx| { Some(git_panel_view_options_menu( focus_handle.clone(), - GitMenuState { - sort_by: GitPanelSettings::get_global(cx).sort_by, - group_by: GitPanelSettings::get_global(cx).group_by, - tree_view: GitPanelSettings::get_global(cx).tree_view, - }, window, cx, ))