Persist settings nav across every settings sub-page
Each ely://settings/* route used to render its content alone, with no nav column — so clicking a sidebar item replaced the entire page and read to users as a brand-new tab opening. Move the nav column into a shared render_settings_shell wrapper and route every settings/* URL through it. ely://sync/status reuses the sync route highlight. Also stop in-place navigation from stealing focus to the omnibar so the destination page keeps focus for scroll and interaction.
This commit is contained in:
@@ -22,7 +22,7 @@ pub(crate) use brand_glyph::{accent_color_for_host, render_glyph_for};
|
|||||||
pub(crate) use command_overlay::render_command_overlay;
|
pub(crate) use command_overlay::render_command_overlay;
|
||||||
pub(crate) use home::render_home_page;
|
pub(crate) use home::render_home_page;
|
||||||
pub(crate) use plugin_detail_view::render_plugin_detail_view;
|
pub(crate) use plugin_detail_view::render_plugin_detail_view;
|
||||||
pub(crate) use settings_layout::render_settings_landing;
|
pub(crate) use settings_layout::render_settings_shell;
|
||||||
pub(crate) use sidebar::{panel_bg, panel_shadow};
|
pub(crate) use sidebar::{panel_bg, panel_shadow};
|
||||||
pub(crate) use sidebar_header::{
|
pub(crate) use sidebar_header::{
|
||||||
render_sidebar_header, render_workspace_disclosure, render_workspace_disclosure_backdrop,
|
render_sidebar_header, render_workspace_disclosure, render_workspace_disclosure_backdrop,
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ use gpui::{
|
|||||||
use gpui_component::{IconName, scroll::ScrollableElement};
|
use gpui_component::{IconName, scroll::ScrollableElement};
|
||||||
|
|
||||||
use crate::shell::ElyShell;
|
use crate::shell::ElyShell;
|
||||||
use crate::shell::chrome::render_appearance_form;
|
|
||||||
|
|
||||||
struct NavGroup {
|
struct NavGroup {
|
||||||
label: &'static str,
|
label: &'static str,
|
||||||
@@ -111,10 +110,15 @@ const NAV_GROUPS: &[NavGroup] = &[
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
pub(crate) fn render_settings_landing(
|
/// Wrap a settings sub-page so the persistent left nav column sits next
|
||||||
shell: &mut ElyShell,
|
/// to the page-specific content. Every `ely://settings/*` route renders
|
||||||
|
/// through here, so navigating sub-pages reads as "the panel on the
|
||||||
|
/// right swapped" instead of "the layout disappeared and a new tab
|
||||||
|
/// opened" — the prior behavior that misread to users as a tab spawn.
|
||||||
|
pub(crate) fn render_settings_shell(
|
||||||
snapshot: &BrowserSnapshot,
|
snapshot: &BrowserSnapshot,
|
||||||
active_route: &str,
|
active_route: &str,
|
||||||
|
content: AnyElement,
|
||||||
cx: &mut Context<ElyShell>,
|
cx: &mut Context<ElyShell>,
|
||||||
) -> AnyElement {
|
) -> AnyElement {
|
||||||
div()
|
div()
|
||||||
@@ -122,7 +126,7 @@ pub(crate) fn render_settings_landing(
|
|||||||
.h_full()
|
.h_full()
|
||||||
.flex()
|
.flex()
|
||||||
.child(render_nav_column(snapshot, active_route, cx))
|
.child(render_nav_column(snapshot, active_route, cx))
|
||||||
.child(render_appearance_form(shell, snapshot, cx))
|
.child(content)
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ use gpui_component::{IconName, StyledExt, scroll::ScrollableElement};
|
|||||||
|
|
||||||
use super::ElyShell;
|
use super::ElyShell;
|
||||||
use super::archive_labels::archive_detail_label;
|
use super::archive_labels::archive_detail_label;
|
||||||
|
use super::chrome::render_settings_shell;
|
||||||
|
|
||||||
impl ElyShell {
|
impl ElyShell {
|
||||||
pub(super) fn render_web_canvas(
|
pub(super) fn render_web_canvas(
|
||||||
@@ -83,23 +84,66 @@ impl ElyShell {
|
|||||||
}
|
}
|
||||||
"ely://about" => self.render_about_page(snapshot),
|
"ely://about" => self.render_about_page(snapshot),
|
||||||
"ely://settings" => self.render_settings_page(snapshot, cx),
|
"ely://settings" => self.render_settings_page(snapshot, cx),
|
||||||
"ely://settings/advanced" => self.render_advanced_page(snapshot),
|
url @ "ely://settings/advanced" => {
|
||||||
"ely://settings/appearance" => self.render_appearance_page(snapshot, cx),
|
let content = self.render_advanced_page(snapshot);
|
||||||
"ely://settings/general" => self.render_general_page(snapshot, cx),
|
render_settings_shell(snapshot, url, content, cx)
|
||||||
"ely://settings/sidebar-tabs" => self.render_sidebar_tabs_page(snapshot, cx),
|
}
|
||||||
"ely://settings/search" => self.render_search_page(snapshot, cx),
|
url @ "ely://settings/appearance" => {
|
||||||
"ely://settings/privacy-security" => self.render_privacy_security_page(snapshot, cx),
|
let content = self.render_appearance_page(snapshot, cx);
|
||||||
"ely://settings/downloads" => self.render_download_settings_page(snapshot, cx),
|
render_settings_shell(snapshot, url, content, cx)
|
||||||
"ely://settings/spaces" => self.render_spaces_page(snapshot, cx),
|
}
|
||||||
"ely://settings/site-permissions" => {
|
url @ "ely://settings/general" => {
|
||||||
self.render_site_permissions_settings_page(snapshot, cx)
|
let content = self.render_general_page(snapshot, cx);
|
||||||
|
render_settings_shell(snapshot, url, content, cx)
|
||||||
|
}
|
||||||
|
url @ "ely://settings/sidebar-tabs" => {
|
||||||
|
let content = self.render_sidebar_tabs_page(snapshot, cx);
|
||||||
|
render_settings_shell(snapshot, url, content, cx)
|
||||||
|
}
|
||||||
|
url @ "ely://settings/search" => {
|
||||||
|
let content = self.render_search_page(snapshot, cx);
|
||||||
|
render_settings_shell(snapshot, url, content, cx)
|
||||||
|
}
|
||||||
|
url @ "ely://settings/privacy-security" => {
|
||||||
|
let content = self.render_privacy_security_page(snapshot, cx);
|
||||||
|
render_settings_shell(snapshot, url, content, cx)
|
||||||
|
}
|
||||||
|
url @ "ely://settings/downloads" => {
|
||||||
|
let content = self.render_download_settings_page(snapshot, cx);
|
||||||
|
render_settings_shell(snapshot, url, content, cx)
|
||||||
|
}
|
||||||
|
url @ "ely://settings/spaces" => {
|
||||||
|
let content = self.render_spaces_page(snapshot, cx);
|
||||||
|
render_settings_shell(snapshot, url, content, cx)
|
||||||
|
}
|
||||||
|
url @ "ely://settings/site-permissions" => {
|
||||||
|
let content = self.render_site_permissions_settings_page(snapshot, cx);
|
||||||
|
render_settings_shell(snapshot, url, content, cx)
|
||||||
|
}
|
||||||
|
url @ "ely://settings/shortcuts" => {
|
||||||
|
let content = self.render_shortcuts_page(snapshot, cx);
|
||||||
|
render_settings_shell(snapshot, url, content, cx)
|
||||||
|
}
|
||||||
|
url @ "ely://settings/plugins" => {
|
||||||
|
let content = self.render_plugins_page(snapshot, cx);
|
||||||
|
render_settings_shell(snapshot, url, content, cx)
|
||||||
|
}
|
||||||
|
url @ "ely://settings/profiles" => {
|
||||||
|
let content = self.render_profiles_page(snapshot, cx);
|
||||||
|
render_settings_shell(snapshot, url, content, cx)
|
||||||
|
}
|
||||||
|
url @ "ely://settings/sync" => {
|
||||||
|
let content = self.render_sync_page(snapshot, cx);
|
||||||
|
render_settings_shell(snapshot, url, content, cx)
|
||||||
|
}
|
||||||
|
url @ "ely://settings/updates" => {
|
||||||
|
let content = self.render_updates_page(snapshot, cx);
|
||||||
|
render_settings_shell(snapshot, url, content, cx)
|
||||||
|
}
|
||||||
|
"ely://sync/status" => {
|
||||||
|
let content = self.render_sync_page(snapshot, cx);
|
||||||
|
render_settings_shell(snapshot, "ely://settings/sync", content, cx)
|
||||||
}
|
}
|
||||||
"ely://settings/shortcuts" => self.render_shortcuts_page(snapshot, cx),
|
|
||||||
"ely://settings/plugins" => self.render_plugins_page(snapshot, cx),
|
|
||||||
"ely://settings/profiles" => self.render_profiles_page(snapshot, cx),
|
|
||||||
"ely://settings/sync" => self.render_sync_page(snapshot, cx),
|
|
||||||
"ely://settings/updates" => self.render_updates_page(snapshot, cx),
|
|
||||||
"ely://sync/status" => self.render_sync_page(snapshot, cx),
|
|
||||||
url if super::web_surface::is_external_web_url(url) => {
|
url if super::web_surface::is_external_web_url(url) => {
|
||||||
self.render_external_web_canvas(tab, snapshot, cx)
|
self.render_external_web_canvas(tab, snapshot, cx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use ely_browser_core::BrowserSnapshot;
|
|||||||
use gpui::{AnyElement, Context};
|
use gpui::{AnyElement, Context};
|
||||||
|
|
||||||
use super::ElyShell;
|
use super::ElyShell;
|
||||||
use crate::shell::chrome::render_settings_landing;
|
use crate::shell::chrome::{render_appearance_form, render_settings_shell};
|
||||||
|
|
||||||
impl ElyShell {
|
impl ElyShell {
|
||||||
pub(super) fn render_settings_page(
|
pub(super) fn render_settings_page(
|
||||||
@@ -10,6 +10,7 @@ impl ElyShell {
|
|||||||
snapshot: &BrowserSnapshot,
|
snapshot: &BrowserSnapshot,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) -> AnyElement {
|
) -> AnyElement {
|
||||||
render_settings_landing(self, snapshot, "ely://settings/appearance", cx)
|
let content = render_appearance_form(self, snapshot, cx);
|
||||||
|
render_settings_shell(snapshot, "ely://settings/appearance", content, cx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,11 @@ impl ElyShell {
|
|||||||
/// Navigate the active tab to `url` without creating a new tab.
|
/// Navigate the active tab to `url` without creating a new tab.
|
||||||
/// Falls back to opening a new tab only if there's no active tab
|
/// Falls back to opening a new tab only if there's no active tab
|
||||||
/// to navigate (the BrowserCore returns `TabNotFound`).
|
/// to navigate (the BrowserCore returns `TabNotFound`).
|
||||||
|
///
|
||||||
|
/// Note: in-place navigation does NOT steal focus to the omnibar.
|
||||||
|
/// Settings nav clicks, home pills, and disclosure rows expect
|
||||||
|
/// focus to stay on the page so the user can immediately scroll
|
||||||
|
/// or interact with the destination.
|
||||||
pub(crate) fn navigate_active_tab(
|
pub(crate) fn navigate_active_tab(
|
||||||
&mut self,
|
&mut self,
|
||||||
url: UrlText,
|
url: UrlText,
|
||||||
@@ -69,7 +74,6 @@ impl ElyShell {
|
|||||||
core.open_tab(url);
|
core.open_tab(url);
|
||||||
}
|
}
|
||||||
self.sync_address_input(window, cx);
|
self.sync_address_input(window, cx);
|
||||||
self.focus_address_bar(window, cx);
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user