list, table: Refactor to control loading by use delegate. (#562)

- Add `loading` method to `ListDelegate` and `TableDelegate` to control
loading view display.

## Break Changes

- Remove `loading`, `set_loading` method from List and Table, use
`loading` method in delegate instead.
This commit is contained in:
Jason Lee 2025-01-21 20:33:37 +08:00 committed by GitHub
parent 9f2cd84b23
commit 78ce573a52
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 33 additions and 35 deletions

View file

@ -180,6 +180,10 @@ impl ListDelegate for CompanyListDelegate {
None
}
fn loading(&self, _: &AppContext) -> bool {
self.loading
}
fn can_load_more(&self, _: &AppContext) -> bool {
return !self.loading && !self.is_eof;
}
@ -381,10 +385,11 @@ impl Render for ListStory {
.child(
Checkbox::new("loading")
.label("Loading")
.checked(self.company_list.read(cx).loading())
.checked(self.company_list.read(cx).delegate().loading)
.on_click(cx.listener(|this, check: &bool, cx| {
this.company_list.update(cx, |this, cx| {
this.set_loading(*check, cx);
this.delegate_mut().loading = *check;
cx.notify();
})
})),
),

View file

@ -181,6 +181,7 @@ struct StockTableDelegate {
col_sort: bool,
col_selection: bool,
loading: bool,
full_loading: bool,
fixed_cols: bool,
is_eof: bool,
visible_rows: Range<usize>,
@ -253,6 +254,7 @@ impl StockTableDelegate {
col_selection: true,
fixed_cols: false,
loading: false,
full_loading: false,
is_eof: false,
visible_cols: Range::default(),
visible_rows: Range::default(),
@ -263,6 +265,7 @@ impl StockTableDelegate {
self.stocks = random_stocks(size);
self.is_eof = false;
self.loading = false;
self.full_loading = false;
}
fn render_value_cell(&self, val: f64, cx: &mut ViewContext<Table<Self>>) -> AnyElement {
@ -471,6 +474,10 @@ impl TableDelegate for StockTableDelegate {
}
}
fn loading(&self, _: &AppContext) -> bool {
self.full_loading
}
fn can_load_more(&self, _: &AppContext) -> bool {
return !self.loading && !self.is_eof;
}
@ -774,10 +781,11 @@ impl Render for TableStory {
.child(
Checkbox::new("loading")
.label("Loading")
.checked(self.table.read(cx).loading())
.checked(self.table.read(cx).delegate().full_loading)
.on_click(cx.listener(|this, check: &bool, cx| {
this.table.update(cx, |this, cx| {
this.set_loading(*check, cx);
this.delegate_mut().full_loading = *check;
cx.notify();
})
})),
)

View file

@ -75,6 +75,11 @@ pub trait ListDelegate: Sized + 'static {
None
}
/// Returns the loading state to show the loading view.
fn loading(&self, cx: &AppContext) -> bool {
false
}
/// Returns a Element to show when loading, default is built-in Skeleton loading view.
fn render_loading(&self, cx: &mut ViewContext<List<Self>>) -> impl IntoElement {
Loading
@ -122,7 +127,6 @@ pub struct List<D: ListDelegate> {
last_query: Option<String>,
selectable: bool,
querying: bool,
loading: bool,
scrollbar_visible: bool,
vertical_scroll_handle: UniformListScrollHandle,
scrollbar_state: Rc<Cell<ScrollbarState>>,
@ -162,7 +166,6 @@ where
scrollbar_visible: true,
selectable: true,
querying: false,
loading: false,
size: Size::default(),
_search_task: Task::ready(()),
_load_more_task: Task::ready(()),
@ -201,17 +204,6 @@ where
self
}
/// Get the loading state of the list.
pub fn loading(&self) -> bool {
self.loading
}
/// Sets list loading state.
pub fn set_loading(&mut self, loading: bool, cx: &mut ViewContext<Self>) {
self.loading = loading;
cx.notify();
}
pub fn set_query_input(&mut self, query_input: View<TextInput>, cx: &mut ViewContext<Self>) {
cx.subscribe(&query_input, Self::on_query_input_event)
.detach();
@ -483,6 +475,7 @@ where
let view = cx.view().clone();
let vertical_scroll_handle = self.vertical_scroll_handle.clone();
let items_count = self.delegate.items_count(cx);
let loading = self.delegate.loading(cx);
let sizing_behavior = if self.max_height.is_some() {
ListSizingBehavior::Infer
} else {
@ -518,10 +511,10 @@ where
.child(input),
)
})
.when(self.loading, |this| {
.when(loading, |this| {
this.child(self.delegate().render_loading(cx))
})
.when(!self.loading, |this| {
.when(!loading, |this| {
this.on_action(cx.listener(Self::on_action_cancel))
.on_action(cx.listener(Self::on_action_confirm))
.on_action(cx.listener(Self::on_action_select_next))

View file

@ -171,8 +171,6 @@ pub struct Table<D: TableDelegate> {
size: Size,
/// The visible range of the rows and columns.
visible_range: VisibleRangeState,
/// The loading state of the table.
loading: bool,
_load_more_task: Task<()>,
}
@ -280,6 +278,11 @@ pub trait TableDelegate: Sized + 'static {
.into_any_element()
}
/// Return true to show the loading view.
fn loading(&self, cx: &AppContext) -> bool {
false
}
/// Return a Element to show when table is loading, default is built-in Skeleton loading view.
///
/// The size is the size of the Table.
@ -370,7 +373,6 @@ where
size: Size::default(),
scrollbar_visible: Edges::all(true),
visible_range: VisibleRangeState::default(),
loading: false,
_load_more_task: Task::ready(()),
};
@ -424,17 +426,6 @@ where
self
}
/// Get the loading state of the list.
pub fn loading(&self) -> bool {
self.loading
}
/// Sets list loading state.
pub fn set_loading(&mut self, loading: bool, cx: &mut ViewContext<Self>) {
self.loading = loading;
cx.notify();
}
/// When we update columns or rows, we need to refresh the table.
pub fn refresh(&mut self, cx: &mut ViewContext<Self>) {
self.prepare_col_groups(cx);
@ -1291,6 +1282,7 @@ where
let cols_count: usize = self.delegate.cols_count(cx);
let left_cols_count = self.fixed_cols.left;
let rows_count = self.delegate.rows_count(cx);
let loading = self.delegate.loading(cx);
let row_height = self
.vertical_scroll_handle
@ -1400,10 +1392,10 @@ where
this.rounded_md().border_1().border_color(cx.theme().border)
})
.bg(cx.theme().table)
.when(self.loading, |this| {
.when(loading, |this| {
this.child(self.delegate().render_loading(self.size, cx))
})
.when(!self.loading, |this| {
.when(!loading, |this| {
this.child(inner_table)
.child(ScrollableMask::new(
cx.view().entity_id(),