chore: Improve Table, List load more threshold, and avoid duplicate request. (#550)
- Default `threshold` changed to 20.
This commit is contained in:
parent
0312e47554
commit
04d720f3a7
2 changed files with 45 additions and 40 deletions
|
|
@ -1,4 +1,3 @@
|
||||||
use std::ops::Range;
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::{cell::Cell, rc::Rc};
|
use std::{cell::Cell, rc::Rc};
|
||||||
|
|
||||||
|
|
@ -95,10 +94,11 @@ pub trait ListDelegate: Sized + 'static {
|
||||||
|
|
||||||
/// Returns a threshold value (n rows), of course, when scrolling to the bottom,
|
/// Returns a threshold value (n rows), of course, when scrolling to the bottom,
|
||||||
/// the remaining number of rows triggers `load_more`.
|
/// the remaining number of rows triggers `load_more`.
|
||||||
|
/// This should smaller than the total number of first load rows.
|
||||||
///
|
///
|
||||||
/// Default: 50 rows
|
/// Default: 20 rows
|
||||||
fn load_more_threshold(&self) -> usize {
|
fn load_more_threshold(&self) -> usize {
|
||||||
50
|
20
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load more data when the table is scrolled to the bottom.
|
/// Load more data when the table is scrolled to the bottom.
|
||||||
|
|
@ -126,6 +126,7 @@ pub struct List<D: ListDelegate> {
|
||||||
selected_index: Option<usize>,
|
selected_index: Option<usize>,
|
||||||
right_clicked_index: Option<usize>,
|
right_clicked_index: Option<usize>,
|
||||||
_search_task: Task<()>,
|
_search_task: Task<()>,
|
||||||
|
_load_more_task: Task<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D> List<D>
|
impl<D> List<D>
|
||||||
|
|
@ -160,6 +161,7 @@ where
|
||||||
loading: false,
|
loading: false,
|
||||||
size: Size::default(),
|
size: Size::default(),
|
||||||
_search_task: Task::ready(()),
|
_search_task: Task::ready(()),
|
||||||
|
_load_more_task: Task::ready(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -323,27 +325,26 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Dispatch delegate's `load_more` method when the visible range is near the end.
|
/// Dispatch delegate's `load_more` method when the visible range is near the end.
|
||||||
fn load_more_if_need(&mut self, visible_range: Range<usize>, cx: &mut ViewContext<Self>) {
|
fn load_more_if_need(
|
||||||
if !self.delegate.can_load_more(cx) {
|
&mut self,
|
||||||
return;
|
items_count: usize,
|
||||||
}
|
visible_end: usize,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
let items_count = self.delegate.items_count(cx);
|
) {
|
||||||
let threshold = self.delegate.load_more_threshold();
|
let threshold = self.delegate.load_more_threshold();
|
||||||
if items_count < threshold {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Securely handle subtract logic to prevent attempt to subtract with overflow
|
// Securely handle subtract logic to prevent attempt to subtract with overflow
|
||||||
if visible_range.end >= items_count - threshold {
|
if visible_end >= items_count.saturating_sub(threshold) {
|
||||||
cx.spawn(|view, mut cx| async move {
|
if !self.delegate.can_load_more(cx) {
|
||||||
cx.update(|cx| {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self._load_more_task = cx.spawn(|view, mut cx| async move {
|
||||||
|
_ = cx.update(|cx| {
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.delegate.load_more(cx);
|
view.delegate.load_more(cx);
|
||||||
})
|
})
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
.detach()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -525,7 +526,8 @@ where
|
||||||
uniform_list(view, "uniform-list", items_count, {
|
uniform_list(view, "uniform-list", items_count, {
|
||||||
move |list, visible_range, cx| {
|
move |list, visible_range, cx| {
|
||||||
list.load_more_if_need(
|
list.load_more_if_need(
|
||||||
visible_range.clone(),
|
items_count,
|
||||||
|
visible_range.end,
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ use gpui::{
|
||||||
DragMoveEvent, Edges, Entity, EntityId, EventEmitter, FocusHandle, FocusableView,
|
DragMoveEvent, Edges, Entity, EntityId, EventEmitter, FocusHandle, FocusableView,
|
||||||
InteractiveElement, IntoElement, KeyBinding, ListSizingBehavior, MouseButton, MouseDownEvent,
|
InteractiveElement, IntoElement, KeyBinding, ListSizingBehavior, MouseButton, MouseDownEvent,
|
||||||
ParentElement, Pixels, Point, Render, ScrollHandle, ScrollStrategy, SharedString, Stateful,
|
ParentElement, Pixels, Point, Render, ScrollHandle, ScrollStrategy, SharedString, Stateful,
|
||||||
StatefulInteractiveElement as _, Styled, UniformListScrollHandle, ViewContext,
|
StatefulInteractiveElement as _, Styled, Task, UniformListScrollHandle, ViewContext,
|
||||||
VisualContext as _, WindowContext,
|
VisualContext as _, WindowContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -176,6 +176,8 @@ pub struct Table<D: TableDelegate> {
|
||||||
visible_range: VisibleRangeState,
|
visible_range: VisibleRangeState,
|
||||||
/// The loading state of the table.
|
/// The loading state of the table.
|
||||||
loading: bool,
|
loading: bool,
|
||||||
|
|
||||||
|
_load_more_task: Task<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
|
@ -297,10 +299,11 @@ pub trait TableDelegate: Sized + 'static {
|
||||||
|
|
||||||
/// Returns a threshold value (n rows), of course, when scrolling to the bottom,
|
/// Returns a threshold value (n rows), of course, when scrolling to the bottom,
|
||||||
/// the remaining number of rows triggers `load_more`.
|
/// the remaining number of rows triggers `load_more`.
|
||||||
|
/// This should smaller than the total number of first load rows.
|
||||||
///
|
///
|
||||||
/// Default: 50 rows
|
/// Default: 20 rows
|
||||||
fn load_more_threshold(&self) -> usize {
|
fn load_more_threshold(&self) -> usize {
|
||||||
50
|
20
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load more data when the table is scrolled to the bottom.
|
/// Load more data when the table is scrolled to the bottom.
|
||||||
|
|
@ -371,6 +374,7 @@ where
|
||||||
scrollbar_visible: Edges::all(true),
|
scrollbar_visible: Edges::all(true),
|
||||||
visible_range: VisibleRangeState::default(),
|
visible_range: VisibleRangeState::default(),
|
||||||
loading: false,
|
loading: false,
|
||||||
|
_load_more_task: Task::ready(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.prepare_col_groups(cx);
|
this.prepare_col_groups(cx);
|
||||||
|
|
@ -691,27 +695,26 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Dispatch delegate's `load_more` method when the visible range is near the end.
|
/// Dispatch delegate's `load_more` method when the visible range is near the end.
|
||||||
fn load_more_if_need(&mut self, visible_range: Range<usize>, cx: &mut ViewContext<Self>) {
|
fn load_more_if_need(
|
||||||
if !self.delegate.can_load_more(cx) {
|
&mut self,
|
||||||
return;
|
rows_count: usize,
|
||||||
}
|
visible_end: usize,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
let row_count = self.delegate.rows_count(cx);
|
) {
|
||||||
let threshold = self.delegate.load_more_threshold();
|
let threshold = self.delegate.load_more_threshold();
|
||||||
if row_count < threshold {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Securely handle subtract logic to prevent attempt to subtract with overflow
|
// Securely handle subtract logic to prevent attempt to subtract with overflow
|
||||||
if visible_range.end >= row_count - threshold {
|
if visible_end >= rows_count.saturating_sub(threshold) {
|
||||||
cx.spawn(|view, mut cx| async move {
|
if !self.delegate.can_load_more(cx) {
|
||||||
cx.update(|cx| {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self._load_more_task = cx.spawn(|view, mut cx| async move {
|
||||||
|
_ = cx.update(|cx| {
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.delegate.load_more(cx);
|
view.delegate.load_more(cx);
|
||||||
})
|
})
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
.detach()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1345,7 +1348,7 @@ where
|
||||||
rows_count + extra_rows_needed,
|
rows_count + extra_rows_needed,
|
||||||
{
|
{
|
||||||
move |table, visible_range, cx| {
|
move |table, visible_range, cx| {
|
||||||
table.load_more_if_need(visible_range.clone(), cx);
|
table.load_more_if_need(rows_count, visible_range.end, cx);
|
||||||
table.update_visible_range_if_need(
|
table.update_visible_range_if_need(
|
||||||
visible_range.clone(),
|
visible_range.clone(),
|
||||||
Axis::Vertical,
|
Axis::Vertical,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue