Skip to content

Commit

Permalink
Display status on page
Browse files Browse the repository at this point in the history
  • Loading branch information
Mubelotix committed Jun 16, 2024
1 parent 52cf660 commit fc38a07
Show file tree
Hide file tree
Showing 12 changed files with 154 additions and 26 deletions.
8 changes: 5 additions & 3 deletions daemon/src/index/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,22 +101,26 @@ impl DocumentIndex {
}

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

if !loaded.insert(cid.clone()) {continue}
loaded.insert(cid.clone());
let Ok(document) = fetch_document(ipfs_rpc, &cid).await else {continue};
let Some(inspected) = inspect_document(document) else {continue};
self.add_document(&cid, inspected).await;
self.add_ancestor(&cid, name, false, &parent_cid).await;
}

// Update filter
self.set_status(listed.len(), 0, loaded.len(), 0, 0).await;
self.set_status_updating_filter(true).await;
self.update_filter().await;
self.set_status_updating_filter(false).await;
let load = self.get_filter().await.load()*100.0;
if load != previous_load {
previous_load = load;
Expand Down Expand Up @@ -165,9 +169,7 @@ impl DocumentIndex {
}

pub async fn update_filter(&self) {
self.set_status_updating_filter(true).await;
self.inner.write().await.update_filter().await;
self.set_status_updating_filter(false).await;
}
}

Expand Down
4 changes: 2 additions & 2 deletions daemon/src/index/status.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use serde::Serialize;
use serde::{Serialize, Deserialize};

#[derive(Default, Debug, Clone, Serialize)]
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub struct IndexingStatus {
pub listed: usize,
pub to_list: usize,
Expand Down
41 changes: 24 additions & 17 deletions webui/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@ pub enum ApiError {

impl ApiError {
pub fn to_format_parts(&self) -> (&'static str, Vec<String>, String) {
let (title, recommandations, details) = match self {
let (title, recommandations) = match self {
ApiError::InputJson(e) => (
"Failed to craft request",
vec![
String::from("Open an issue on GitHub"),
String::from("Try again"),
],
format!("InputJson: {e}")
]
),
ApiError::OutputJson(e) => (
"Failed to read results",
Expand All @@ -29,8 +28,7 @@ impl ApiError {
String::from("Make sure the daemon address is correct"),
String::from("Open an issue on GitHub"),
String::from("Try again"),
],
format!("OutputJson: {e}")
]
),
ApiError::Fetch(e) => (
"Failed to send query",
Expand All @@ -39,17 +37,15 @@ impl ApiError {
String::from("Make sure the daemon address is correct"),
String::from("Make sure CORS is properly configured"),
String::from("Try again"),
],
format!("Fetch: {}", e.clone().dyn_into::<js_sys::Error>().unwrap().message())
]
),
ApiError::NotText(e) => (
"Invalid response",
vec![
String::from("Make sure the daemon address is correct"),
String::from("Open an issue on GitHub"),
String::from("Try again"),
],
format!("NotText: {}", e.clone().dyn_into::<js_sys::Error>().unwrap().message())
]
),
ApiError::BadRequest(e) => (
"Failed to communicate with daemon",
Expand All @@ -58,28 +54,39 @@ impl ApiError {
String::from("Make sure the daemon address is correct"),
String::from("Open an issue on GitHub"),
String::from("Try again"),
],
format!("BadRequest: {e}")
]
),
ApiError::Server(e) => (
"Daemon is having issues",
vec![
String::from("Make sure the daemon is up to date"),
String::from("Open an issue on GitHub"),
String::from("Try again"),
],
format!("Server: {e}")
]
),
ApiError::Unknown(e) => (
"Unknown error",
vec![
String::from("Make sure the daemon address is correct"),
String::from("Try again"),
],
format!("Unknown: {e}")
]
),
};
(title, recommandations, details)
(title, recommandations, self.to_string())
}
}

impl std::fmt::Display for ApiError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
ApiError::InputJson(e) => write!(f, "InputJson: {}", e),
ApiError::OutputJson(e) => write!(f, "OutputJson: {}", e),
ApiError::Fetch(e) => write!(f, "Fetch: {}", e.clone().dyn_into::<js_sys::Error>().unwrap().message()),
ApiError::NotText(e) => write!(f, "NotText: {}", e.clone().dyn_into::<js_sys::Error>().unwrap().message()),
ApiError::BadRequest(e) => write!(f, "BadRequest: {}", e),
ApiError::Server(e) => write!(f, "Server: {}", e),
ApiError::Unknown(e) => write!(f, "Unknown: {}", e),
}
}
}

Expand All @@ -89,7 +96,7 @@ impl From<serde_json::Error> for ApiError {
}
}

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

Expand Down
5 changes: 5 additions & 0 deletions webui/src/components/indexing_status/api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use crate::prelude::*;

pub async fn get_indexing_status(rpc_addr: &str) -> Result<IndexingStatus, ApiError> {
get(format!("{rpc_addr}/indexing-status")).await
}
16 changes: 16 additions & 0 deletions webui/src/components/indexing_status/indexing_status.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<div id="indexing-status">
<virtual present-if={{exploring}}>
<div id="indexing-status-message">Your daemon is exploring your folders ({{progress_value}} / {{progress_max}}).</div>
<progress id="indexing-status-progress" value={{progress_value}} max={{progress_max}}></progress>
</virtual>

<virtual present-if={{indexing}}>
<div id="indexing-status-message">Your daemon is indexing your files ({{progress_value}} / {{progress_max}}).</div>
<progress id="indexing-status-progress" value={{progress_value}} max={{progress_max}}></progress>
</virtual>

<virtual present-if={{building_filter}}>
<div id="indexing-status-message">Your daemon is compiling its index.</div>
<progress id="indexing-status-progress" max={{progress_max}}></progress>
</virtual>
</div>
93 changes: 93 additions & 0 deletions webui/src/components/indexing_status/indexing_status.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
use crate::prelude::*;

mod ty;
pub use ty::*;
mod api;
pub use api::*;

pub struct IndexingStatusComp {
status: Option<IndexingStatus>,
}

#[derive(PartialEq, Properties)]
pub struct IndexingStatusProps {
pub rpc_addr: String,
}

pub enum IndexingStatusMsg {
SetStatus(IndexingStatus),
}

impl Component for IndexingStatusComp {
type Message = IndexingStatusMsg;
type Properties = IndexingStatusProps;

fn create(ctx: &Context<Self>) -> Self {
let link2 = ctx.link().clone();
let rpc_addr2 = ctx.props().rpc_addr.clone();
spawn_local(async move {
loop {
if link2.get_component().is_none() {
log!("IndexingStatusComp: Component dropped, stopping loop");
break;
}

let status = match get_indexing_status(&rpc_addr2).await {
Ok(status) => status,
Err(e) => {
log!("Failed to get indexing status: {}", e);
sleep(Duration::from_secs(1)).await;
continue;
}
};

let idle = status.to_list == 0 && status.to_load == 0 && status.to_load_unprioritized == 0;
let cooldown = if idle { 30 } else { 1 };

link2.send_message(IndexingStatusMsg::SetStatus(status));
sleep(Duration::from_secs(cooldown)).await;
}
});

Self {
status: None,
}
}

fn update(&mut self, _ctx: &Context<Self>, msg: IndexingStatusMsg) -> bool {
match msg {
IndexingStatusMsg::SetStatus(status) => {
self.status = Some(status);
true
}
}
}

fn view(&self, _ctx: &Context<Self>) -> Html {
let (exploring, indexing, building_filter, progress_value, progress_max) = match &self.status {
Some(status) if status.to_list > 0 => (
true, false, false,
Some(status.listed),
status.listed + status.to_list,
),
Some(status) if status.to_load + status.to_load_unprioritized > 0 => (
false, true, false,
Some(status.loaded),
status.loaded + status.to_load + status.to_load_unprioritized,
),
Some(status) if status.updating_filter => (
false, false, true,
None,
1,
),
_ => return html! {},
};

template_html!(
"components/indexing_status/indexing_status.html",
progress_max = {progress_max.to_string()},
progress_value = {progress_value.unwrap_or(0).to_string()},
...
)
}
}
1 change: 1 addition & 0 deletions webui/src/components/indexing_status/ty.rs
2 changes: 2 additions & 0 deletions webui/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ mod search_bar;
mod connection_status;
#[path = "components/result/result.rs"]
mod result_comp;
#[path = "components/indexing_status/indexing_status.rs"]
mod indexing_status;

mod query;

Expand Down
1 change: 1 addition & 0 deletions webui/src/pages/search/search.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ <h1>Admarus</h1>
<a href="https://github.com/Mubelotix/admarus/wiki/getting-started">Join the network</a>
<button onclick={{onclick_lucky}}>I'm feeling lucky</button>
</div>
<comp name="IndexingStatusComp" rpc_addr={{rpc_addr}} />
</div>
</section>
</main>
1 change: 1 addition & 0 deletions webui/src/pages/search/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ impl Component for SearchPage {
let onclick_lucky = ctx.props().app_link.callback(|_| AppMsg::ChangePage(Page::lucky(None)));
let conn_status = Rc::clone(&ctx.props().conn_status);
let onchange_conn_status = ctx.props().onchange_conn_status.clone();
let rpc_addr = conn_status.admarus_addr();

template_html!(
"pages/search/search.html",
Expand Down
4 changes: 2 additions & 2 deletions webui/src/prelude.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
pub use crate::{
app::*, search::*, settings::*, util::*, results::*, result::*, api_bodies::*, api::*, lang::*,
search_bar::*, lucky::*, query::*, connection_status::*, result_comp::*, *
search_bar::*, lucky::*, query::*, connection_status::*, indexing_status::*, result_comp::*, *
};
pub use js_sys::{Array, Function, Promise, Reflect::*};
pub use js_sys::{Array, Function, Promise, Reflect};
pub use std::{time::Duration, rc::Rc, cmp::Ordering, collections::{HashMap, HashSet}, ops::Deref};
pub use wasm_bindgen::{prelude::Closure, JsCast, JsValue};
pub use wasm_bindgen_futures::{spawn_local, JsFuture};
Expand Down
4 changes: 2 additions & 2 deletions webui/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl<COMP: Component> HackTraitAnimation<COMP> for Scope<COMP> {
let document = unsafe {
web_sys::window().unwrap_unchecked().document().unwrap_unchecked()
};
let start_view_transition = get(&document, &"startViewTransition".into()).unwrap();
let start_view_transition = Reflect::get(&document, &"startViewTransition".into()).unwrap();
let start_view_transition = match start_view_transition.dyn_ref::<Function>() {
Some(f) => f.clone(),
None => {
Expand All @@ -47,7 +47,7 @@ impl<COMP: Component> HackTraitAnimation<COMP> for Scope<COMP> {
}) as Box<dyn FnMut(_)>);
let args = Array::new_with_length(1);
args.set(0, callback.as_ref().clone());
apply(&start_view_transition, &document, &args).unwrap();
Reflect::apply(&start_view_transition, &document, &args).unwrap();

if !LEAK_MEMORY {
spawn_local(async move {
Expand Down

0 comments on commit fc38a07

Please sign in to comment.