Add basic landing page
This commit is contained in:
@@ -14,9 +14,9 @@ use editor::{
|
||||
};
|
||||
use gpui::{
|
||||
actions, div, white, Action, AnyElement, AnyView, AppContext, Context as _, Div, Element,
|
||||
Entity, EntityId, EventEmitter, FocusableView, InteractiveElement, IntoElement, Model,
|
||||
ModelContext, ParentElement, PromptLevel, Render, SharedString, Styled, Subscription, Task,
|
||||
View, ViewContext, VisualContext, WeakModel, WeakView, WindowContext,
|
||||
Entity, EntityId, EventEmitter, FocusableView, InteractiveElement, IntoElement, KeyContext,
|
||||
Model, ModelContext, ParentElement, PromptLevel, Render, SharedString, Styled, Subscription,
|
||||
Task, View, ViewContext, VisualContext, WeakModel, WeakView, WindowContext,
|
||||
};
|
||||
use menu::Confirm;
|
||||
use project::{
|
||||
@@ -39,7 +39,7 @@ use std::{
|
||||
use theme::ActiveTheme;
|
||||
use ui::{
|
||||
h_stack, v_stack, Button, Clickable, Color, Disableable, Icon, IconButton, IconElement, Label,
|
||||
Selectable,
|
||||
LabelCommon, LabelSize, Selectable,
|
||||
};
|
||||
use util::{paths::PathMatcher, ResultExt as _};
|
||||
use workspace::{
|
||||
@@ -330,10 +330,30 @@ impl Render for ProjectSearchView {
|
||||
.size_full()
|
||||
.child(self.results_editor.clone())
|
||||
} else {
|
||||
div()
|
||||
let has_no_results = self.model.read(cx).no_results.unwrap_or(false);
|
||||
let middle_text = if has_no_results {
|
||||
div()
|
||||
.items_center()
|
||||
.max_w_96()
|
||||
.child(Label::new("No results for a given query"))
|
||||
} else {
|
||||
div()
|
||||
.items_center()
|
||||
.max_w_96()
|
||||
.child(Label::new(self.landing_text_minor()).size(LabelSize::Small))
|
||||
};
|
||||
v_stack().flex_1().size_full().justify_center().child(
|
||||
h_stack()
|
||||
.size_full()
|
||||
.justify_center()
|
||||
.child(h_stack().flex_1())
|
||||
.child(middle_text)
|
||||
.child(h_stack().flex_1()),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// impl Entity for ProjectSearchView {
|
||||
// type Event = ViewEvent;
|
||||
// }
|
||||
@@ -441,49 +461,6 @@ impl Render for ProjectSearchView {
|
||||
// }
|
||||
// };
|
||||
|
||||
// let previous_query_keystrokes =
|
||||
// cx.binding_for_action(&PreviousHistoryQuery {})
|
||||
// .map(|binding| {
|
||||
// binding
|
||||
// .keystrokes()
|
||||
// .iter()
|
||||
// .map(|k| k.to_string())
|
||||
// .collect::<Vec<_>>()
|
||||
// });
|
||||
// let next_query_keystrokes =
|
||||
// cx.binding_for_action(&NextHistoryQuery {}).map(|binding| {
|
||||
// binding
|
||||
// .keystrokes()
|
||||
// .iter()
|
||||
// .map(|k| k.to_string())
|
||||
// .collect::<Vec<_>>()
|
||||
// });
|
||||
// let new_placeholder_text = match (previous_query_keystrokes, next_query_keystrokes) {
|
||||
// (Some(previous_query_keystrokes), Some(next_query_keystrokes)) => {
|
||||
// format!(
|
||||
// "Search ({}/{} for previous/next query)",
|
||||
// previous_query_keystrokes.join(" "),
|
||||
// next_query_keystrokes.join(" ")
|
||||
// )
|
||||
// }
|
||||
// (None, Some(next_query_keystrokes)) => {
|
||||
// format!(
|
||||
// "Search ({} for next query)",
|
||||
// next_query_keystrokes.join(" ")
|
||||
// )
|
||||
// }
|
||||
// (Some(previous_query_keystrokes), None) => {
|
||||
// format!(
|
||||
// "Search ({} for previous query)",
|
||||
// previous_query_keystrokes.join(" ")
|
||||
// )
|
||||
// }
|
||||
// (None, None) => String::new(),
|
||||
// };
|
||||
// self.query_editor.update(cx, |editor, cx| {
|
||||
// editor.set_placeholder_text(new_placeholder_text, cx);
|
||||
// });
|
||||
|
||||
// MouseEventHandler::new::<Status, _>(0, cx, |_, _| {
|
||||
// Flex::column()
|
||||
// .with_child(Flex::column().contained().flex(1., true))
|
||||
@@ -1355,6 +1332,12 @@ impl ProjectSearchView {
|
||||
});
|
||||
}
|
||||
}
|
||||
fn landing_text_minor(&self) -> SharedString {
|
||||
match self.current_mode {
|
||||
SearchMode::Text | SearchMode::Regex => "Include/exclude specific paths with the filter option. Matching exact word and/or casing is available too.".into(),
|
||||
SearchMode::Semantic => ".Simply explain the code you are looking to find. ex. 'prompt user for permissions to index their project'".into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ProjectSearchBar {
|
||||
@@ -1680,6 +1663,47 @@ impl ProjectSearchBar {
|
||||
});
|
||||
}
|
||||
}
|
||||
fn new_placeholder_text(&self, cx: &mut ViewContext<Self>) -> Option<String> {
|
||||
let previous_query_keystrokes = cx
|
||||
.bindings_for_action(&PreviousHistoryQuery {})
|
||||
.into_iter()
|
||||
.next()
|
||||
.map(|binding| {
|
||||
binding
|
||||
.keystrokes()
|
||||
.iter()
|
||||
.map(|k| k.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
let next_query_keystrokes = cx
|
||||
.bindings_for_action(&NextHistoryQuery {})
|
||||
.into_iter()
|
||||
.next()
|
||||
.map(|binding| {
|
||||
binding
|
||||
.keystrokes()
|
||||
.iter()
|
||||
.map(|k| k.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
let new_placeholder_text = match (previous_query_keystrokes, next_query_keystrokes) {
|
||||
(Some(previous_query_keystrokes), Some(next_query_keystrokes)) => Some(format!(
|
||||
"Search ({}/{} for previous/next query)",
|
||||
previous_query_keystrokes.join(" "),
|
||||
next_query_keystrokes.join(" ")
|
||||
)),
|
||||
(None, Some(next_query_keystrokes)) => Some(format!(
|
||||
"Search ({} for next query)",
|
||||
next_query_keystrokes.join(" ")
|
||||
)),
|
||||
(Some(previous_query_keystrokes), None) => Some(format!(
|
||||
"Search ({} for previous query)",
|
||||
previous_query_keystrokes.join(" ")
|
||||
)),
|
||||
(None, None) => None,
|
||||
};
|
||||
new_placeholder_text
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for ProjectSearchBar {
|
||||
@@ -1689,7 +1713,17 @@ impl Render for ProjectSearchBar {
|
||||
let Some(search) = self.active_project_search.clone() else {
|
||||
return div();
|
||||
};
|
||||
let mut key_context = KeyContext::default();
|
||||
key_context.add("ProjectSearchBar");
|
||||
if let Some(placeholder_text) = self.new_placeholder_text(cx) {
|
||||
search.update(cx, |search, cx| {
|
||||
search.query_editor.update(cx, |this, cx| {
|
||||
this.set_placeholder_text(placeholder_text, cx)
|
||||
})
|
||||
});
|
||||
}
|
||||
let search = search.read(cx);
|
||||
|
||||
let query_column = v_stack()
|
||||
.flex_1()
|
||||
.child(
|
||||
@@ -1714,6 +1748,10 @@ impl Render for ProjectSearchBar {
|
||||
.on_action(cx.listener(|this, action: &ActivateRegexMode, cx| {
|
||||
this.activate_search_mode(SearchMode::Regex, cx)
|
||||
}))
|
||||
.on_action(
|
||||
cx.listener(|this, action, cx| this.previous_history_query(action, cx)),
|
||||
)
|
||||
.on_action(cx.listener(|this, action, cx| this.next_history_query(action, cx)))
|
||||
.child(IconElement::new(Icon::MagnifyingGlass))
|
||||
.child(search.query_editor.clone())
|
||||
.child(
|
||||
@@ -1740,34 +1778,54 @@ impl Render for ProjectSearchBar {
|
||||
.when(search.filters_enabled, |this| {
|
||||
this.child(
|
||||
h_stack()
|
||||
.child(search.included_files_editor.clone())
|
||||
.child(search.excluded_files_editor.clone()),
|
||||
.mt_2()
|
||||
.flex_1()
|
||||
.justify_between()
|
||||
.child(
|
||||
h_stack()
|
||||
.flex_1()
|
||||
.border_1()
|
||||
.mr_2()
|
||||
.child(search.included_files_editor.clone()),
|
||||
)
|
||||
.child(
|
||||
h_stack()
|
||||
.flex_1()
|
||||
.border_1()
|
||||
.ml_2()
|
||||
.child(search.excluded_files_editor.clone()),
|
||||
),
|
||||
)
|
||||
});
|
||||
let mode_column = h_stack()
|
||||
.child(
|
||||
h_stack()
|
||||
.child(
|
||||
Button::new("project-search-text-button", "Text")
|
||||
.selected(search.current_mode == SearchMode::Text)
|
||||
.on_click(|_, cx| cx.dispatch_action(ActivateTextMode.boxed_clone())),
|
||||
)
|
||||
.child(
|
||||
Button::new("project-search-regex-button", "Regex")
|
||||
.selected(search.current_mode == SearchMode::Regex)
|
||||
.on_click(|_, cx| cx.dispatch_action(ActivateRegexMode.boxed_clone())),
|
||||
let mode_column = v_stack().items_start().justify_start().child(
|
||||
h_stack()
|
||||
.child(
|
||||
h_stack()
|
||||
.child(
|
||||
Button::new("project-search-text-button", "Text")
|
||||
.selected(search.current_mode == SearchMode::Text)
|
||||
.on_click(|_, cx| {
|
||||
cx.dispatch_action(ActivateTextMode.boxed_clone())
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
Button::new("project-search-regex-button", "Regex")
|
||||
.selected(search.current_mode == SearchMode::Regex)
|
||||
.on_click(|_, cx| {
|
||||
cx.dispatch_action(ActivateRegexMode.boxed_clone())
|
||||
}),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
IconButton::new("project-search-toggle-replace", Icon::Replace).on_click(
|
||||
|_, cx| {
|
||||
cx.dispatch_action(ToggleReplace.boxed_clone());
|
||||
},
|
||||
),
|
||||
)
|
||||
.child(
|
||||
IconButton::new("project-search-toggle-replace", Icon::Replace).on_click(
|
||||
|_, cx| {
|
||||
cx.dispatch_action(ToggleReplace.boxed_clone());
|
||||
},
|
||||
),
|
||||
);
|
||||
);
|
||||
let replace_column = if search.replace_enabled {
|
||||
h_stack()
|
||||
.bg(white())
|
||||
.p_1()
|
||||
.flex_1()
|
||||
.border_2()
|
||||
@@ -1811,6 +1869,7 @@ impl Render for ProjectSearchBar {
|
||||
.on_click(|_, cx| cx.dispatch_action(SelectNextMatch.boxed_clone())),
|
||||
]);
|
||||
h_stack()
|
||||
.key_context(key_context)
|
||||
.size_full()
|
||||
.p_1()
|
||||
.m_2()
|
||||
|
||||
Reference in New Issue
Block a user