app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit e390825e62d29432ba5efb9b94a559efb97069ac
parent d9ac29fe565e664c3b51edd05eef664503579f0d
Author: triesap <triesap@radroots.dev>
Date:   Mon, 19 Jan 2026 16:44:08 +0000

app: track init state in app context

- create init state signal with default values
- provide init state via leptos context
- mark init stage as storage before backend init
- set init stage to ready or error on completion

Diffstat:
Mapp/src/app.rs | 44++++++++++++++++++++++++++++++++++++++++----
1 file changed, 40 insertions(+), 4 deletions(-)

diff --git a/app/src/app.rs b/app/src/app.rs @@ -1,23 +1,59 @@ use leptos::prelude::*; use leptos::task::spawn_local; -use crate::{app_init_backends, AppBackends, AppInitError}; +use crate::{ + app_init_backends, + app_init_state_default, + AppBackends, + AppInitError, + AppInitStage, +}; #[component] pub fn App() -> impl IntoView { let backends = RwSignal::new_local(None::<AppBackends>); let init_error = RwSignal::new_local(None::<AppInitError>); + let init_state = RwSignal::new_local(app_init_state_default()); provide_context(backends); provide_context(init_error); + provide_context(init_state); Effect::new(move || { spawn_local(async move { + init_state.update(|state| state.stage = AppInitStage::Storage); match app_init_backends().await { - Ok(value) => backends.set(Some(value)), - Err(err) => init_error.set(Some(err)), + Ok(value) => { + backends.set(Some(value)); + init_state.update(|state| state.stage = AppInitStage::Ready); + } + Err(err) => { + init_error.set(Some(err)); + init_state.update(|state| state.stage = AppInitStage::Error); + } } }) }); + let status_color = move || match init_state.get().stage { + AppInitStage::Ready => "green", + AppInitStage::Error => "red", + AppInitStage::Storage => "orange", + AppInitStage::DownloadSql => "orange", + AppInitStage::DownloadGeo => "orange", + AppInitStage::Database => "orange", + AppInitStage::Geocoder => "orange", + AppInitStage::Idle => "gray", + }; view! { - <main>"app"</main> + <main> + <div>"app"</div> + <div style="margin-top: 8px; display: flex; align-items: center; gap: 8px;"> + <span + style=move || format!( + "display:inline-block;width:10px;height:10px;border-radius:50%;background:{};", + status_color() + ) + ></span> + <span>{move || init_state.get().stage.as_str()}</span> + </div> + </main> } }