dioxus_lazy/
use_lazy_async.rs

1use crate::{lazy::Values, Factory};
2use dioxus::prelude::*;
3use futures::StreamExt;
4use std::{cmp::Ordering, collections::VecDeque, ops::Range};
5
6enum Message {
7    Range(Range<usize>),
8    Refresh,
9}
10
11pub fn use_lazy_async<F>(make_value: F) -> UseLazyAsync<F::Item>
12where
13    F: Factory + 'static,
14{
15    let mut values = use_signal(VecDeque::new);
16
17    let mut last = 0..0;
18    let task = use_coroutine(|mut rx| async move {
19        while let Some(msg) = rx.next().await {
20            match msg {
21                Message::Range(range) => {
22                    match range.start.cmp(&last.start) {
23                        Ordering::Less => {
24                            let mut rows_ref = values.write();
25                            let values = make_value.make(range.start..last.start, true).await;
26                            for value in values.into_iter() {
27                                rows_ref.push_front(value);
28                            }
29                        }
30                        Ordering::Greater => {
31                            let mut rows_ref = values.write();
32                            for _ in 0..range.start - last.start {
33                                rows_ref.pop_front();
34                            }
35                        }
36                        Ordering::Equal => {}
37                    }
38
39                    if range.start != range.end {
40                        match range.end.cmp(&last.end) {
41                            Ordering::Greater => {
42                                let mut rows_ref = values.write();
43                                let values = make_value.make(last.end..range.end, false).await;
44                                for value in values.into_iter() {
45                                    rows_ref.push_back(value);
46                                }
47                            }
48                            Ordering::Less => {
49                                let mut rows_ref = values.write();
50                                for _ in 0..last.end - range.end {
51                                    rows_ref.pop_back();
52                                }
53                            }
54                            Ordering::Equal => {}
55                        }
56                    }
57
58                    last = range;
59                }
60                Message::Refresh => {
61                    let mut rows_ref = values.write();
62                    rows_ref.clear();
63
64                    let values = make_value.make(last.clone(), false).await;
65                    for value in values.into_iter() {
66                        rows_ref.push_back(value);
67                    }
68                }
69            }
70        }
71    });
72
73    UseLazyAsync {
74        task: CopyValue::new(task),
75        values,
76    }
77}
78
79pub struct UseLazyAsync<V: 'static> {
80    pub values: Signal<VecDeque<V>>,
81    task: CopyValue<Coroutine<Message>>,
82}
83
84impl<V> Values for UseLazyAsync<V> {
85    type Value = V;
86
87    fn values(&self) -> Signal<VecDeque<Self::Value>> {
88        self.values
89    }
90
91    fn set(&mut self, range: Range<usize>) {
92        self.task.read().send(Message::Range(range))
93    }
94
95    fn refresh(&mut self) {
96        self.task.read().send(Message::Refresh)
97    }
98}
99
100impl<V> Clone for UseLazyAsync<V> {
101    fn clone(&self) -> Self {
102        *self
103    }
104}
105
106impl<V> Copy for UseLazyAsync<V> {}
107
108impl<V> PartialEq for UseLazyAsync<V> {
109    fn eq(&self, other: &Self) -> bool {
110        self.values == other.values && self.task == other.task
111    }
112}