dioxus_lazy/
use_lazy_async.rs1use 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}