Skip to content

Commit fc38a07

Browse files
committed
Display status on page
1 parent 52cf660 commit fc38a07

File tree

12 files changed

+154
-26
lines changed

12 files changed

+154
-26
lines changed

daemon/src/index/index.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,22 +101,26 @@ impl DocumentIndex {
101101
}
102102

103103
// Load documents
104+
to_load_unprioritized.retain(|cid, _| !to_load.contains_key(cid));
104105
if !to_load.is_empty() {debug!("{} documents to load ({:.02?}s)", to_load.len(), start.elapsed().as_secs_f32())}
105106
let (to_load_len, to_load_unprioritized_len) = (to_load.len(), to_load_unprioritized.len());
106107
for (i, (cid, (name, parent_cid))) in to_load.drain().chain(to_load_unprioritized.drain()).enumerate() {
107108
let remaining_to_load = to_load_len.saturating_sub(i);
108109
let remaining_unprioritized = std::cmp::min(to_load_unprioritized_len, to_load_len + to_load_unprioritized_len - i);
109110
self.set_status(listed.len(), to_list.len(), loaded.len(), remaining_to_load, remaining_unprioritized).await;
110111

111-
if !loaded.insert(cid.clone()) {continue}
112+
loaded.insert(cid.clone());
112113
let Ok(document) = fetch_document(ipfs_rpc, &cid).await else {continue};
113114
let Some(inspected) = inspect_document(document) else {continue};
114115
self.add_document(&cid, inspected).await;
115116
self.add_ancestor(&cid, name, false, &parent_cid).await;
116117
}
117118

118119
// Update filter
120+
self.set_status(listed.len(), 0, loaded.len(), 0, 0).await;
121+
self.set_status_updating_filter(true).await;
119122
self.update_filter().await;
123+
self.set_status_updating_filter(false).await;
120124
let load = self.get_filter().await.load()*100.0;
121125
if load != previous_load {
122126
previous_load = load;
@@ -165,9 +169,7 @@ impl DocumentIndex {
165169
}
166170

167171
pub async fn update_filter(&self) {
168-
self.set_status_updating_filter(true).await;
169172
self.inner.write().await.update_filter().await;
170-
self.set_status_updating_filter(false).await;
171173
}
172174
}
173175

daemon/src/index/status.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use serde::Serialize;
1+
use serde::{Serialize, Deserialize};
22

3-
#[derive(Default, Debug, Clone, Serialize)]
3+
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
44
pub struct IndexingStatus {
55
pub listed: usize,
66
pub to_list: usize,

webui/src/api.rs

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,13 @@ pub enum ApiError {
1313

1414
impl ApiError {
1515
pub fn to_format_parts(&self) -> (&'static str, Vec<String>, String) {
16-
let (title, recommandations, details) = match self {
16+
let (title, recommandations) = match self {
1717
ApiError::InputJson(e) => (
1818
"Failed to craft request",
1919
vec![
2020
String::from("Open an issue on GitHub"),
2121
String::from("Try again"),
22-
],
23-
format!("InputJson: {e}")
22+
]
2423
),
2524
ApiError::OutputJson(e) => (
2625
"Failed to read results",
@@ -29,8 +28,7 @@ impl ApiError {
2928
String::from("Make sure the daemon address is correct"),
3029
String::from("Open an issue on GitHub"),
3130
String::from("Try again"),
32-
],
33-
format!("OutputJson: {e}")
31+
]
3432
),
3533
ApiError::Fetch(e) => (
3634
"Failed to send query",
@@ -39,17 +37,15 @@ impl ApiError {
3937
String::from("Make sure the daemon address is correct"),
4038
String::from("Make sure CORS is properly configured"),
4139
String::from("Try again"),
42-
],
43-
format!("Fetch: {}", e.clone().dyn_into::<js_sys::Error>().unwrap().message())
40+
]
4441
),
4542
ApiError::NotText(e) => (
4643
"Invalid response",
4744
vec![
4845
String::from("Make sure the daemon address is correct"),
4946
String::from("Open an issue on GitHub"),
5047
String::from("Try again"),
51-
],
52-
format!("NotText: {}", e.clone().dyn_into::<js_sys::Error>().unwrap().message())
48+
]
5349
),
5450
ApiError::BadRequest(e) => (
5551
"Failed to communicate with daemon",
@@ -58,28 +54,39 @@ impl ApiError {
5854
String::from("Make sure the daemon address is correct"),
5955
String::from("Open an issue on GitHub"),
6056
String::from("Try again"),
61-
],
62-
format!("BadRequest: {e}")
57+
]
6358
),
6459
ApiError::Server(e) => (
6560
"Daemon is having issues",
6661
vec![
6762
String::from("Make sure the daemon is up to date"),
6863
String::from("Open an issue on GitHub"),
6964
String::from("Try again"),
70-
],
71-
format!("Server: {e}")
65+
]
7266
),
7367
ApiError::Unknown(e) => (
7468
"Unknown error",
7569
vec![
7670
String::from("Make sure the daemon address is correct"),
7771
String::from("Try again"),
78-
],
79-
format!("Unknown: {e}")
72+
]
8073
),
8174
};
82-
(title, recommandations, details)
75+
(title, recommandations, self.to_string())
76+
}
77+
}
78+
79+
impl std::fmt::Display for ApiError {
80+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
81+
match self {
82+
ApiError::InputJson(e) => write!(f, "InputJson: {}", e),
83+
ApiError::OutputJson(e) => write!(f, "OutputJson: {}", e),
84+
ApiError::Fetch(e) => write!(f, "Fetch: {}", e.clone().dyn_into::<js_sys::Error>().unwrap().message()),
85+
ApiError::NotText(e) => write!(f, "NotText: {}", e.clone().dyn_into::<js_sys::Error>().unwrap().message()),
86+
ApiError::BadRequest(e) => write!(f, "BadRequest: {}", e),
87+
ApiError::Server(e) => write!(f, "Server: {}", e),
88+
ApiError::Unknown(e) => write!(f, "Unknown: {}", e),
89+
}
8390
}
8491
}
8592

@@ -89,7 +96,7 @@ impl From<serde_json::Error> for ApiError {
8996
}
9097
}
9198

92-
async fn get<T: DeserializeOwned>(url: impl AsRef<str>) -> Result<T, ApiError> {
99+
pub async fn get<T: DeserializeOwned>(url: impl AsRef<str>) -> Result<T, ApiError> {
93100
api_custom_method(url, "GET", ()).await
94101
}
95102

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
use crate::prelude::*;
2+
3+
pub async fn get_indexing_status(rpc_addr: &str) -> Result<IndexingStatus, ApiError> {
4+
get(format!("{rpc_addr}/indexing-status")).await
5+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<div id="indexing-status">
2+
<virtual present-if={{exploring}}>
3+
<div id="indexing-status-message">Your daemon is exploring your folders ({{progress_value}} / {{progress_max}}).</div>
4+
<progress id="indexing-status-progress" value={{progress_value}} max={{progress_max}}></progress>
5+
</virtual>
6+
7+
<virtual present-if={{indexing}}>
8+
<div id="indexing-status-message">Your daemon is indexing your files ({{progress_value}} / {{progress_max}}).</div>
9+
<progress id="indexing-status-progress" value={{progress_value}} max={{progress_max}}></progress>
10+
</virtual>
11+
12+
<virtual present-if={{building_filter}}>
13+
<div id="indexing-status-message">Your daemon is compiling its index.</div>
14+
<progress id="indexing-status-progress" max={{progress_max}}></progress>
15+
</virtual>
16+
</div>
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
use crate::prelude::*;
2+
3+
mod ty;
4+
pub use ty::*;
5+
mod api;
6+
pub use api::*;
7+
8+
pub struct IndexingStatusComp {
9+
status: Option<IndexingStatus>,
10+
}
11+
12+
#[derive(PartialEq, Properties)]
13+
pub struct IndexingStatusProps {
14+
pub rpc_addr: String,
15+
}
16+
17+
pub enum IndexingStatusMsg {
18+
SetStatus(IndexingStatus),
19+
}
20+
21+
impl Component for IndexingStatusComp {
22+
type Message = IndexingStatusMsg;
23+
type Properties = IndexingStatusProps;
24+
25+
fn create(ctx: &Context<Self>) -> Self {
26+
let link2 = ctx.link().clone();
27+
let rpc_addr2 = ctx.props().rpc_addr.clone();
28+
spawn_local(async move {
29+
loop {
30+
if link2.get_component().is_none() {
31+
log!("IndexingStatusComp: Component dropped, stopping loop");
32+
break;
33+
}
34+
35+
let status = match get_indexing_status(&rpc_addr2).await {
36+
Ok(status) => status,
37+
Err(e) => {
38+
log!("Failed to get indexing status: {}", e);
39+
sleep(Duration::from_secs(1)).await;
40+
continue;
41+
}
42+
};
43+
44+
let idle = status.to_list == 0 && status.to_load == 0 && status.to_load_unprioritized == 0;
45+
let cooldown = if idle { 30 } else { 1 };
46+
47+
link2.send_message(IndexingStatusMsg::SetStatus(status));
48+
sleep(Duration::from_secs(cooldown)).await;
49+
}
50+
});
51+
52+
Self {
53+
status: None,
54+
}
55+
}
56+
57+
fn update(&mut self, _ctx: &Context<Self>, msg: IndexingStatusMsg) -> bool {
58+
match msg {
59+
IndexingStatusMsg::SetStatus(status) => {
60+
self.status = Some(status);
61+
true
62+
}
63+
}
64+
}
65+
66+
fn view(&self, _ctx: &Context<Self>) -> Html {
67+
let (exploring, indexing, building_filter, progress_value, progress_max) = match &self.status {
68+
Some(status) if status.to_list > 0 => (
69+
true, false, false,
70+
Some(status.listed),
71+
status.listed + status.to_list,
72+
),
73+
Some(status) if status.to_load + status.to_load_unprioritized > 0 => (
74+
false, true, false,
75+
Some(status.loaded),
76+
status.loaded + status.to_load + status.to_load_unprioritized,
77+
),
78+
Some(status) if status.updating_filter => (
79+
false, false, true,
80+
None,
81+
1,
82+
),
83+
_ => return html! {},
84+
};
85+
86+
template_html!(
87+
"components/indexing_status/indexing_status.html",
88+
progress_max = {progress_max.to_string()},
89+
progress_value = {progress_value.unwrap_or(0).to_string()},
90+
...
91+
)
92+
}
93+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../../daemon/src/index/status.rs

webui/src/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ mod search_bar;
1919
mod connection_status;
2020
#[path = "components/result/result.rs"]
2121
mod result_comp;
22+
#[path = "components/indexing_status/indexing_status.rs"]
23+
mod indexing_status;
2224

2325
mod query;
2426

webui/src/pages/search/search.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ <h1>Admarus</h1>
1919
<a href="https://github.com/Mubelotix/admarus/wiki/getting-started">Join the network</a>
2020
<button onclick={{onclick_lucky}}>I'm feeling lucky</button>
2121
</div>
22+
<comp name="IndexingStatusComp" rpc_addr={{rpc_addr}} />
2223
</div>
2324
</section>
2425
</main>

webui/src/pages/search/search.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ impl Component for SearchPage {
3030
let onclick_lucky = ctx.props().app_link.callback(|_| AppMsg::ChangePage(Page::lucky(None)));
3131
let conn_status = Rc::clone(&ctx.props().conn_status);
3232
let onchange_conn_status = ctx.props().onchange_conn_status.clone();
33+
let rpc_addr = conn_status.admarus_addr();
3334

3435
template_html!(
3536
"pages/search/search.html",

0 commit comments

Comments
 (0)