ui_grid_core/
infinite_scroll.rs1use serde::{Deserialize, Serialize};
2
3use crate::models::GridInfiniteScrollState;
4
5#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6#[serde(rename_all = "camelCase")]
7pub struct MaybeRequestInfiniteScrollDataContext {
8 pub state: GridInfiniteScrollState,
9 pub start_index: usize,
10 pub visible_rows: usize,
11 pub viewport_rows: usize,
12 pub threshold: usize,
13}
14
15#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
16#[serde(rename_all = "lowercase")]
17pub enum InfiniteScrollRequest {
18 Top,
19 Bottom,
20}
21
22#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
23#[serde(rename_all = "camelCase")]
24pub struct MaybeRequestInfiniteScrollDataResult {
25 #[serde(default)]
26 pub request: Option<InfiniteScrollRequest>,
27 pub next_state: GridInfiniteScrollState,
28}
29
30pub fn maybe_request_infinite_scroll_data(
31 context: &MaybeRequestInfiniteScrollDataContext,
32) -> MaybeRequestInfiniteScrollDataResult {
33 if context.state.data_loading {
34 return MaybeRequestInfiniteScrollDataResult {
35 request: None,
36 next_state: context.state.clone(),
37 };
38 }
39
40 if context.state.scroll_up && context.start_index <= context.threshold {
41 return MaybeRequestInfiniteScrollDataResult {
42 request: Some(InfiniteScrollRequest::Top),
43 next_state: GridInfiniteScrollState {
44 scroll_up: context.state.scroll_up,
45 scroll_down: context.state.scroll_down,
46 data_loading: true,
47 previous_visible_rows: context.visible_rows,
48 },
49 };
50 }
51
52 if context.state.scroll_down
53 && context.start_index + context.viewport_rows
54 >= std::cmp::max(context.visible_rows.saturating_sub(context.threshold), 0)
55 {
56 return MaybeRequestInfiniteScrollDataResult {
57 request: Some(InfiniteScrollRequest::Bottom),
58 next_state: GridInfiniteScrollState {
59 scroll_up: context.state.scroll_up,
60 scroll_down: context.state.scroll_down,
61 data_loading: true,
62 previous_visible_rows: context.visible_rows,
63 },
64 };
65 }
66
67 MaybeRequestInfiniteScrollDataResult {
68 request: None,
69 next_state: context.state.clone(),
70 }
71}
72
73pub fn complete_infinite_scroll_data_load(
74 state: &GridInfiniteScrollState,
75 scroll_up: bool,
76 scroll_down: bool,
77) -> GridInfiniteScrollState {
78 GridInfiniteScrollState {
79 scroll_up,
80 scroll_down,
81 data_loading: false,
82 previous_visible_rows: state.previous_visible_rows,
83 }
84}
85
86pub fn reset_infinite_scroll_state(scroll_up: bool, scroll_down: bool) -> GridInfiniteScrollState {
87 GridInfiniteScrollState {
88 scroll_up,
89 scroll_down,
90 data_loading: false,
91 previous_visible_rows: 0,
92 }
93}
94
95pub fn save_infinite_scroll_percentage(
96 state: &GridInfiniteScrollState,
97 visible_rows: usize,
98) -> GridInfiniteScrollState {
99 GridInfiniteScrollState {
100 scroll_up: state.scroll_up,
101 scroll_down: state.scroll_down,
102 data_loading: state.data_loading,
103 previous_visible_rows: visible_rows,
104 }
105}
106
107pub fn set_infinite_scroll_directions_state(
108 state: &GridInfiniteScrollState,
109 scroll_up: bool,
110 scroll_down: bool,
111) -> GridInfiniteScrollState {
112 GridInfiniteScrollState {
113 scroll_up,
114 scroll_down,
115 data_loading: state.data_loading,
116 previous_visible_rows: state.previous_visible_rows,
117 }
118}