extensions_ui: Fix scroll to top only on refetch (#29640)

Closes #29604

Release Notes:

- Fixes case where extension page scrolls up to the top when installing
an extension.
This commit is contained in:
Smit Barmase 2025-04-30 09:39:17 +05:30 committed by GitHub
parent 747a029487
commit 8d77efa781
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -280,7 +280,7 @@ impl ExtensionsPage {
window, window,
move |this, _, event, window, cx| match event { move |this, _, event, window, cx| match event {
extension_host::Event::ExtensionsUpdated => { extension_host::Event::ExtensionsUpdated => {
this.fetch_extensions_debounced(cx) this.fetch_extensions_debounced(None, cx)
} }
extension_host::Event::ExtensionInstalled(extension_id) => this extension_host::Event::ExtensionInstalled(extension_id) => this
.on_extension_installed( .on_extension_installed(
@ -319,7 +319,12 @@ impl ExtensionsPage {
upsells: BTreeSet::default(), upsells: BTreeSet::default(),
scrollbar_state: ScrollbarState::new(scroll_handle), scrollbar_state: ScrollbarState::new(scroll_handle),
}; };
this.fetch_extensions(None, Some(BTreeSet::from_iter(this.provides_filter)), cx); this.fetch_extensions(
None,
Some(BTreeSet::from_iter(this.provides_filter)),
None,
cx,
);
this this
}) })
} }
@ -413,6 +418,10 @@ impl ExtensionsPage {
}) })
.map(|(ix, _)| ix), .map(|(ix, _)| ix),
); );
cx.notify();
}
fn scroll_to_top(&mut self, cx: &mut Context<Self>) {
self.list.set_offset(point(px(0.), px(0.))); self.list.set_offset(point(px(0.), px(0.)));
cx.notify(); cx.notify();
} }
@ -421,6 +430,7 @@ impl ExtensionsPage {
&mut self, &mut self,
search: Option<String>, search: Option<String>,
provides_filter: Option<BTreeSet<ExtensionProvides>>, provides_filter: Option<BTreeSet<ExtensionProvides>>,
on_complete: Option<Box<dyn FnOnce(&mut Self, &mut Context<Self>) + Send>>,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) { ) {
self.is_fetching_extensions = true; self.is_fetching_extensions = true;
@ -468,6 +478,9 @@ impl ExtensionsPage {
this.is_fetching_extensions = false; this.is_fetching_extensions = false;
this.remote_extension_entries = fetch_result?; this.remote_extension_entries = fetch_result?;
this.filter_extension_entries(cx); this.filter_extension_entries(cx);
if let Some(callback) = on_complete {
callback(this, cx);
}
anyhow::Ok(()) anyhow::Ok(())
})? })?
}) })
@ -1010,7 +1023,12 @@ impl ExtensionsPage {
} }
fn refresh_search(&mut self, cx: &mut Context<Self>) { fn refresh_search(&mut self, cx: &mut Context<Self>) {
self.fetch_extensions_debounced(cx); self.fetch_extensions_debounced(
Some(Box::new(|this, cx| {
this.scroll_to_top(cx);
})),
cx,
);
self.refresh_feature_upsells(cx); self.refresh_feature_upsells(cx);
} }
@ -1023,7 +1041,11 @@ impl ExtensionsPage {
self.refresh_search(cx); self.refresh_search(cx);
} }
fn fetch_extensions_debounced(&mut self, cx: &mut Context<ExtensionsPage>) { fn fetch_extensions_debounced(
&mut self,
on_complete: Option<Box<dyn FnOnce(&mut Self, &mut Context<Self>) + Send>>,
cx: &mut Context<ExtensionsPage>,
) {
self.extension_fetch_task = Some(cx.spawn(async move |this, cx| { self.extension_fetch_task = Some(cx.spawn(async move |this, cx| {
let search = this let search = this
.update(cx, |this, cx| this.search_query(cx)) .update(cx, |this, cx| this.search_query(cx))
@ -1043,7 +1065,12 @@ impl ExtensionsPage {
}; };
this.update(cx, |this, cx| { this.update(cx, |this, cx| {
this.fetch_extensions(search, Some(BTreeSet::from_iter(this.provides_filter)), cx); this.fetch_extensions(
search,
Some(BTreeSet::from_iter(this.provides_filter)),
on_complete,
cx,
);
}) })
.ok(); .ok();
})); }));
@ -1237,6 +1264,7 @@ impl Render for ExtensionsPage {
.on_click(cx.listener(|this, _event, _, cx| { .on_click(cx.listener(|this, _event, _, cx| {
this.filter = ExtensionFilter::All; this.filter = ExtensionFilter::All;
this.filter_extension_entries(cx); this.filter_extension_entries(cx);
this.scroll_to_top(cx);
})) }))
.tooltip(move |_, cx| { .tooltip(move |_, cx| {
Tooltip::simple("Show all extensions", cx) Tooltip::simple("Show all extensions", cx)
@ -1251,6 +1279,7 @@ impl Render for ExtensionsPage {
.on_click(cx.listener(|this, _event, _, cx| { .on_click(cx.listener(|this, _event, _, cx| {
this.filter = ExtensionFilter::Installed; this.filter = ExtensionFilter::Installed;
this.filter_extension_entries(cx); this.filter_extension_entries(cx);
this.scroll_to_top(cx);
})) }))
.tooltip(move |_, cx| { .tooltip(move |_, cx| {
Tooltip::simple("Show installed extensions", cx) Tooltip::simple("Show installed extensions", cx)
@ -1267,6 +1296,7 @@ impl Render for ExtensionsPage {
.on_click(cx.listener(|this, _event, _, cx| { .on_click(cx.listener(|this, _event, _, cx| {
this.filter = ExtensionFilter::NotInstalled; this.filter = ExtensionFilter::NotInstalled;
this.filter_extension_entries(cx); this.filter_extension_entries(cx);
this.scroll_to_top(cx);
})) }))
.tooltip(move |_, cx| { .tooltip(move |_, cx| {
Tooltip::simple("Show not installed extensions", cx) Tooltip::simple("Show not installed extensions", cx)