Skip to main content

ui_grid_core/
infinite_scroll.rs

1use 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}