mirror of
https://github.com/zaphar/kitchen.git
synced 2025-07-21 19:29:49 -04:00
Properly delay the navigation until state has loaded
This commit is contained in:
parent
6d21626521
commit
dd9ce0fca2
@ -11,7 +11,10 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::{
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
fmt::Debug,
|
||||
};
|
||||
|
||||
use client_api::UserData;
|
||||
use recipes::{parse, IngredientKey, Recipe, RecipeEntry};
|
||||
@ -50,7 +53,6 @@ impl AppState {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Message {
|
||||
ResetRecipeCounts,
|
||||
UpdateRecipeCount(String, usize),
|
||||
@ -64,8 +66,46 @@ pub enum Message {
|
||||
AddFilteredIngredient(IngredientKey),
|
||||
UpdateAmt(IngredientKey, String),
|
||||
SetUserData(UserData),
|
||||
SaveState,
|
||||
LoadState,
|
||||
SaveState(Option<Box<dyn FnOnce()>>),
|
||||
LoadState(Option<Box<dyn FnOnce()>>),
|
||||
}
|
||||
|
||||
impl Debug for Message {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::ResetRecipeCounts => write!(f, "ResetRecipeCounts"),
|
||||
Self::UpdateRecipeCount(arg0, arg1) => f
|
||||
.debug_tuple("UpdateRecipeCount")
|
||||
.field(arg0)
|
||||
.field(arg1)
|
||||
.finish(),
|
||||
Self::AddExtra(arg0, arg1) => {
|
||||
f.debug_tuple("AddExtra").field(arg0).field(arg1).finish()
|
||||
}
|
||||
Self::RemoveExtra(arg0) => f.debug_tuple("RemoveExtra").field(arg0).finish(),
|
||||
Self::UpdateExtra(arg0, arg1, arg2) => f
|
||||
.debug_tuple("UpdateExtra")
|
||||
.field(arg0)
|
||||
.field(arg1)
|
||||
.field(arg2)
|
||||
.finish(),
|
||||
Self::SaveRecipe(arg0) => f.debug_tuple("SaveRecipe").field(arg0).finish(),
|
||||
Self::SetRecipe(arg0, arg1) => {
|
||||
f.debug_tuple("SetRecipe").field(arg0).field(arg1).finish()
|
||||
}
|
||||
Self::SetCategoryMap(arg0) => f.debug_tuple("SetCategoryMap").field(arg0).finish(),
|
||||
Self::ResetInventory => write!(f, "ResetInventory"),
|
||||
Self::AddFilteredIngredient(arg0) => {
|
||||
f.debug_tuple("AddFilteredIngredient").field(arg0).finish()
|
||||
}
|
||||
Self::UpdateAmt(arg0, arg1) => {
|
||||
f.debug_tuple("UpdateAmt").field(arg0).field(arg1).finish()
|
||||
}
|
||||
Self::SetUserData(arg0) => f.debug_tuple("SetUserData").field(arg0).finish(),
|
||||
Self::SaveState(_) => write!(f, "SaveState"),
|
||||
Self::LoadState(_) => write!(f, "LoadState"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StateMachine {
|
||||
@ -284,16 +324,17 @@ impl MessageMapper<Message, AppState> for StateMachine {
|
||||
Message::SetUserData(user_data) => {
|
||||
original_copy.auth = Some(user_data);
|
||||
}
|
||||
Message::SaveState => {
|
||||
Message::SaveState(f) => {
|
||||
let original_copy = original_copy.clone();
|
||||
let store = self.store.clone();
|
||||
spawn_local_scoped(cx, async move {
|
||||
if let Err(e) = store.save_app_state(original_copy).await {
|
||||
error!(err=?e, "Error saving app state")
|
||||
};
|
||||
f.map(|f| f());
|
||||
});
|
||||
}
|
||||
Message::LoadState => {
|
||||
Message::LoadState(f) => {
|
||||
let store = self.store.clone();
|
||||
let local_store = self.local_store.clone();
|
||||
spawn_local_scoped(cx, async move {
|
||||
@ -305,6 +346,7 @@ impl MessageMapper<Message, AppState> for StateMachine {
|
||||
&original.get().modified_amts,
|
||||
&original.get().extras,
|
||||
));
|
||||
f.map(|f| f());
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -55,14 +55,14 @@ pub fn RecipePlan<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> Vie
|
||||
))
|
||||
}
|
||||
input(type="button", value="Reset", on:click=move |_| {
|
||||
sh.dispatch(cx, Message::LoadState);
|
||||
sh.dispatch(cx, Message::LoadState(None));
|
||||
})
|
||||
input(type="button", value="Clear All", on:click=move |_| {
|
||||
sh.dispatch(cx, Message::ResetRecipeCounts);
|
||||
})
|
||||
input(type="button", value="Save Plan", on:click=move |_| {
|
||||
// Poor man's click event signaling.
|
||||
sh.dispatch(cx, Message::SaveState);
|
||||
sh.dispatch(cx, Message::SaveState(None));
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ pub fn ShoppingList<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> V
|
||||
})
|
||||
input(type="button", value="Save", class="no-print", on:click=move |_| {
|
||||
info!("Registering save request for inventory");
|
||||
sh.dispatch(cx, Message::SaveState);
|
||||
sh.dispatch(cx, Message::SaveState(None));
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -36,8 +36,7 @@ pub fn LoginForm<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View
|
||||
debug!("authenticating against ui");
|
||||
if let Some(user_data) = store.authenticate(username, password).await {
|
||||
sh.dispatch(cx, Message::SetUserData(user_data));
|
||||
sh.dispatch(cx, Message::LoadState);
|
||||
sycamore_router::navigate("/ui/planning/plan");
|
||||
sh.dispatch(cx, Message::LoadState(Some(Box::new(|| sycamore_router::navigate("/ui/planning/plan")))));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ use crate::{api, routing::Handler as RouteHandler};
|
||||
#[instrument]
|
||||
#[component]
|
||||
pub fn UI<G: Html>(cx: Scope) -> View<G> {
|
||||
// FIXME(jwall): We shouldn't need to get the store from a context anymore.
|
||||
api::HttpStore::provide_context(cx, "/api".to_owned());
|
||||
let store = api::HttpStore::get_from_context(cx).as_ref().clone();
|
||||
info!("Starting UI");
|
||||
@ -29,8 +28,7 @@ pub fn UI<G: Html>(cx: Scope) -> View<G> {
|
||||
let view = create_signal(cx, View::empty());
|
||||
spawn_local_scoped(cx, {
|
||||
async move {
|
||||
sh.dispatch(cx, Message::LoadState);
|
||||
// TODO(jwall): This needs to be moved into the RouteHandler
|
||||
sh.dispatch(cx, Message::LoadState(None));
|
||||
view.set(view! { cx,
|
||||
RouteHandler(sh=sh)
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user