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::{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,
|
||||
/// 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 {
|
||||
50
|
||||
20
|
||||
}
|
||||
|
||||
/// Load more data when the table is scrolled to the bottom.
|
||||
|
|
@ -126,6 +126,7 @@ pub struct List<D: ListDelegate> {
|
|||
selected_index: Option<usize>,
|
||||
right_clicked_index: Option<usize>,
|
||||
_search_task: Task<()>,
|
||||
_load_more_task: Task<()>,
|
||||
}
|
||||
|
||||
impl<D> List<D>
|
||||
|
|
@ -160,6 +161,7 @@ where
|
|||
loading: false,
|
||||
size: Size::default(),
|
||||
_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.
|
||||
fn load_more_if_need(&mut self, visible_range: Range<usize>, cx: &mut ViewContext<Self>) {
|
||||
if !self.delegate.can_load_more(cx) {
|
||||
return;
|
||||
}
|
||||
|
||||
let items_count = self.delegate.items_count(cx);
|
||||
fn load_more_if_need(
|
||||
&mut self,
|
||||
items_count: usize,
|
||||
visible_end: usize,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
let threshold = self.delegate.load_more_threshold();
|
||||
if items_count < threshold {
|
||||
return;
|
||||
}
|
||||
|
||||
// Securely handle subtract logic to prevent attempt to subtract with overflow
|
||||
if visible_range.end >= items_count - threshold {
|
||||
cx.spawn(|view, mut cx| async move {
|
||||
cx.update(|cx| {
|
||||
if visible_end >= items_count.saturating_sub(threshold) {
|
||||
if !self.delegate.can_load_more(cx) {
|
||||
return;
|
||||
}
|
||||
|
||||
self._load_more_task = cx.spawn(|view, mut cx| async move {
|
||||
_ = cx.update(|cx| {
|
||||
view.update(cx, |view, cx| {
|
||||
view.delegate.load_more(cx);
|
||||
})
|
||||
})
|
||||
})
|
||||
.detach()
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -525,7 +526,8 @@ where
|
|||
uniform_list(view, "uniform-list", items_count, {
|
||||
move |list, visible_range, cx| {
|
||||
list.load_more_if_need(
|
||||
visible_range.clone(),
|
||||
items_count,
|
||||
visible_range.end,
|
||||
cx,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use gpui::{
|
|||
DragMoveEvent, Edges, Entity, EntityId, EventEmitter, FocusHandle, FocusableView,
|
||||
InteractiveElement, IntoElement, KeyBinding, ListSizingBehavior, MouseButton, MouseDownEvent,
|
||||
ParentElement, Pixels, Point, Render, ScrollHandle, ScrollStrategy, SharedString, Stateful,
|
||||
StatefulInteractiveElement as _, Styled, UniformListScrollHandle, ViewContext,
|
||||
StatefulInteractiveElement as _, Styled, Task, UniformListScrollHandle, ViewContext,
|
||||
VisualContext as _, WindowContext,
|
||||
};
|
||||
|
||||
|
|
@ -176,6 +176,8 @@ pub struct Table<D: TableDelegate> {
|
|||
visible_range: VisibleRangeState,
|
||||
/// The loading state of the table.
|
||||
loading: bool,
|
||||
|
||||
_load_more_task: Task<()>,
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
|
|
@ -297,10 +299,11 @@ pub trait TableDelegate: Sized + 'static {
|
|||
|
||||
/// Returns a threshold value (n rows), of course, when scrolling to the bottom,
|
||||
/// 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 {
|
||||
50
|
||||
20
|
||||
}
|
||||
|
||||
/// Load more data when the table is scrolled to the bottom.
|
||||
|
|
@ -371,6 +374,7 @@ where
|
|||
scrollbar_visible: Edges::all(true),
|
||||
visible_range: VisibleRangeState::default(),
|
||||
loading: false,
|
||||
_load_more_task: Task::ready(()),
|
||||
};
|
||||
|
||||
this.prepare_col_groups(cx);
|
||||
|
|
@ -691,27 +695,26 @@ where
|
|||
}
|
||||
|
||||
/// 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>) {
|
||||
if !self.delegate.can_load_more(cx) {
|
||||
return;
|
||||
}
|
||||
|
||||
let row_count = self.delegate.rows_count(cx);
|
||||
fn load_more_if_need(
|
||||
&mut self,
|
||||
rows_count: usize,
|
||||
visible_end: usize,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
let threshold = self.delegate.load_more_threshold();
|
||||
if row_count < threshold {
|
||||
return;
|
||||
}
|
||||
|
||||
// Securely handle subtract logic to prevent attempt to subtract with overflow
|
||||
if visible_range.end >= row_count - threshold {
|
||||
cx.spawn(|view, mut cx| async move {
|
||||
cx.update(|cx| {
|
||||
if visible_end >= rows_count.saturating_sub(threshold) {
|
||||
if !self.delegate.can_load_more(cx) {
|
||||
return;
|
||||
}
|
||||
|
||||
self._load_more_task = cx.spawn(|view, mut cx| async move {
|
||||
_ = cx.update(|cx| {
|
||||
view.update(cx, |view, cx| {
|
||||
view.delegate.load_more(cx);
|
||||
})
|
||||
})
|
||||
})
|
||||
.detach()
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1345,7 +1348,7 @@ where
|
|||
rows_count + extra_rows_needed,
|
||||
{
|
||||
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(
|
||||
visible_range.clone(),
|
||||
Axis::Vertical,
|
||||
|
|
|
|||
Loading…
Reference in a new issue