mirror of
https://github.com/zaphar/kitchen.git
synced 2025-07-22 19:40:14 -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.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::{
|
||||||
|
collections::{BTreeMap, BTreeSet},
|
||||||
|
fmt::Debug,
|
||||||
|
};
|
||||||
|
|
||||||
use client_api::UserData;
|
use client_api::UserData;
|
||||||
use recipes::{parse, IngredientKey, Recipe, RecipeEntry};
|
use recipes::{parse, IngredientKey, Recipe, RecipeEntry};
|
||||||
@ -50,7 +53,6 @@ impl AppState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
ResetRecipeCounts,
|
ResetRecipeCounts,
|
||||||
UpdateRecipeCount(String, usize),
|
UpdateRecipeCount(String, usize),
|
||||||
@ -64,8 +66,46 @@ pub enum Message {
|
|||||||
AddFilteredIngredient(IngredientKey),
|
AddFilteredIngredient(IngredientKey),
|
||||||
UpdateAmt(IngredientKey, String),
|
UpdateAmt(IngredientKey, String),
|
||||||
SetUserData(UserData),
|
SetUserData(UserData),
|
||||||
SaveState,
|
SaveState(Option<Box<dyn FnOnce()>>),
|
||||||
LoadState,
|
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 {
|
pub struct StateMachine {
|
||||||
@ -284,16 +324,17 @@ impl MessageMapper<Message, AppState> for StateMachine {
|
|||||||
Message::SetUserData(user_data) => {
|
Message::SetUserData(user_data) => {
|
||||||
original_copy.auth = Some(user_data);
|
original_copy.auth = Some(user_data);
|
||||||
}
|
}
|
||||||
Message::SaveState => {
|
Message::SaveState(f) => {
|
||||||
let original_copy = original_copy.clone();
|
let original_copy = original_copy.clone();
|
||||||
let store = self.store.clone();
|
let store = self.store.clone();
|
||||||
spawn_local_scoped(cx, async move {
|
spawn_local_scoped(cx, async move {
|
||||||
if let Err(e) = store.save_app_state(original_copy).await {
|
if let Err(e) = store.save_app_state(original_copy).await {
|
||||||
error!(err=?e, "Error saving app state")
|
error!(err=?e, "Error saving app state")
|
||||||
};
|
};
|
||||||
|
f.map(|f| f());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Message::LoadState => {
|
Message::LoadState(f) => {
|
||||||
let store = self.store.clone();
|
let store = self.store.clone();
|
||||||
let local_store = self.local_store.clone();
|
let local_store = self.local_store.clone();
|
||||||
spawn_local_scoped(cx, async move {
|
spawn_local_scoped(cx, async move {
|
||||||
@ -305,6 +346,7 @@ impl MessageMapper<Message, AppState> for StateMachine {
|
|||||||
&original.get().modified_amts,
|
&original.get().modified_amts,
|
||||||
&original.get().extras,
|
&original.get().extras,
|
||||||
));
|
));
|
||||||
|
f.map(|f| f());
|
||||||
});
|
});
|
||||||
return;
|
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 |_| {
|
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 |_| {
|
input(type="button", value="Clear All", on:click=move |_| {
|
||||||
sh.dispatch(cx, Message::ResetRecipeCounts);
|
sh.dispatch(cx, Message::ResetRecipeCounts);
|
||||||
})
|
})
|
||||||
input(type="button", value="Save Plan", on:click=move |_| {
|
input(type="button", value="Save Plan", on:click=move |_| {
|
||||||
// Poor man's click event signaling.
|
// 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 |_| {
|
input(type="button", value="Save", class="no-print", on:click=move |_| {
|
||||||
info!("Registering save request for inventory");
|
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");
|
debug!("authenticating against ui");
|
||||||
if let Some(user_data) = store.authenticate(username, password).await {
|
if let Some(user_data) = store.authenticate(username, password).await {
|
||||||
sh.dispatch(cx, Message::SetUserData(user_data));
|
sh.dispatch(cx, Message::SetUserData(user_data));
|
||||||
sh.dispatch(cx, Message::LoadState);
|
sh.dispatch(cx, Message::LoadState(Some(Box::new(|| sycamore_router::navigate("/ui/planning/plan")))));
|
||||||
sycamore_router::navigate("/ui/planning/plan");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ use crate::{api, routing::Handler as RouteHandler};
|
|||||||
#[instrument]
|
#[instrument]
|
||||||
#[component]
|
#[component]
|
||||||
pub fn UI<G: Html>(cx: Scope) -> View<G> {
|
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());
|
api::HttpStore::provide_context(cx, "/api".to_owned());
|
||||||
let store = api::HttpStore::get_from_context(cx).as_ref().clone();
|
let store = api::HttpStore::get_from_context(cx).as_ref().clone();
|
||||||
info!("Starting UI");
|
info!("Starting UI");
|
||||||
@ -29,8 +28,7 @@ pub fn UI<G: Html>(cx: Scope) -> View<G> {
|
|||||||
let view = create_signal(cx, View::empty());
|
let view = create_signal(cx, View::empty());
|
||||||
spawn_local_scoped(cx, {
|
spawn_local_scoped(cx, {
|
||||||
async move {
|
async move {
|
||||||
sh.dispatch(cx, Message::LoadState);
|
sh.dispatch(cx, Message::LoadState(None));
|
||||||
// TODO(jwall): This needs to be moved into the RouteHandler
|
|
||||||
view.set(view! { cx,
|
view.set(view! { cx,
|
||||||
RouteHandler(sh=sh)
|
RouteHandler(sh=sh)
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user