mirror of
https://github.com/zaphar/kitchen.git
synced 2025-07-22 19:40:14 -04:00
Remove the old State
This commit is contained in:
parent
a1fa17da68
commit
f3f27a0350
@ -23,10 +23,7 @@ use client_api::*;
|
|||||||
use recipes::{parse, IngredientKey, Recipe, RecipeEntry};
|
use recipes::{parse, IngredientKey, Recipe, RecipeEntry};
|
||||||
use wasm_bindgen::JsValue;
|
use wasm_bindgen::JsValue;
|
||||||
|
|
||||||
use crate::{
|
use crate::{app_state::AppState, js_lib};
|
||||||
app_state::{self, AppState},
|
|
||||||
js_lib,
|
|
||||||
};
|
|
||||||
|
|
||||||
// FIXME(jwall): We should be able to delete this now.
|
// FIXME(jwall): We should be able to delete this now.
|
||||||
#[instrument]
|
#[instrument]
|
||||||
@ -360,29 +357,6 @@ impl HttpStore {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument]
|
|
||||||
pub async fn save_state(&self, state: std::rc::Rc<app_state::State>) -> Result<(), Error> {
|
|
||||||
let mut plan = Vec::new();
|
|
||||||
for (key, count) in state.recipe_counts.get_untracked().iter() {
|
|
||||||
plan.push((key.clone(), *count.get_untracked() as i32));
|
|
||||||
}
|
|
||||||
debug!("Saving plan data");
|
|
||||||
self.save_plan(plan).await?;
|
|
||||||
debug!("Saving inventory data");
|
|
||||||
self.save_inventory_data(
|
|
||||||
state.filtered_ingredients.get_untracked().as_ref().clone(),
|
|
||||||
state.get_current_modified_amts(),
|
|
||||||
state
|
|
||||||
.extras
|
|
||||||
.get()
|
|
||||||
.as_ref()
|
|
||||||
.iter()
|
|
||||||
.map(|t| (t.1 .0.get().as_ref().clone(), t.1 .1.get().as_ref().clone()))
|
|
||||||
.collect(),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn save_plan(&self, plan: Vec<(String, i32)>) -> Result<(), Error> {
|
pub async fn save_plan(&self, plan: Vec<(String, i32)>) -> Result<(), Error> {
|
||||||
let mut path = self.v1_path();
|
let mut path = self.v1_path();
|
||||||
path.push_str("/plan");
|
path.push_str("/plan");
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
|
|
||||||
use client_api::UserData;
|
use client_api::UserData;
|
||||||
use recipes::{parse, Ingredient, IngredientAccumulator, IngredientKey, Recipe, RecipeEntry};
|
use recipes::{parse, IngredientKey, Recipe, RecipeEntry};
|
||||||
use serde_json::from_str;
|
use serde_json::from_str;
|
||||||
use sycamore::futures::spawn_local_scoped;
|
use sycamore::futures::spawn_local_scoped;
|
||||||
use sycamore::prelude::*;
|
use sycamore::prelude::*;
|
||||||
@ -55,23 +55,23 @@ impl AppState {
|
|||||||
pub enum Message {
|
pub enum Message {
|
||||||
ResetRecipeCounts,
|
ResetRecipeCounts,
|
||||||
UpdateRecipeCount(String, usize),
|
UpdateRecipeCount(String, usize),
|
||||||
InitExtras(BTreeSet<(String, String)>),
|
|
||||||
AddExtra(String, String),
|
AddExtra(String, String),
|
||||||
RemoveExtra(String, String),
|
RemoveExtra(String, String),
|
||||||
InitRecipes(BTreeMap<String, Recipe>),
|
|
||||||
SaveRecipe(RecipeEntry),
|
SaveRecipe(RecipeEntry),
|
||||||
SetRecipe(String, Recipe),
|
SetRecipe(String, Recipe),
|
||||||
|
// TODO(jwall): Remove this annotation when safe to do so.
|
||||||
|
#[allow(dead_code)]
|
||||||
RemoveRecipe(String),
|
RemoveRecipe(String),
|
||||||
|
// TODO(jwall): Remove this annotation when safe to do so.
|
||||||
|
#[allow(dead_code)]
|
||||||
SetStaples(Option<Recipe>),
|
SetStaples(Option<Recipe>),
|
||||||
SetCategoryMap(String),
|
SetCategoryMap(String),
|
||||||
ResetInventory,
|
ResetInventory,
|
||||||
UpdateCategories,
|
|
||||||
InitFilteredIngredient(BTreeSet<IngredientKey>),
|
|
||||||
AddFilteredIngredient(IngredientKey),
|
AddFilteredIngredient(IngredientKey),
|
||||||
RemoveFilteredIngredient(IngredientKey),
|
|
||||||
InitAmts(BTreeMap<IngredientKey, String>),
|
|
||||||
UpdateAmt(IngredientKey, String),
|
UpdateAmt(IngredientKey, String),
|
||||||
SetUserData(UserData),
|
SetUserData(UserData),
|
||||||
|
// TODO(jwall): Remove this annotation when safe to do so.
|
||||||
|
#[allow(dead_code)]
|
||||||
UnsetUserData,
|
UnsetUserData,
|
||||||
SaveState,
|
SaveState,
|
||||||
LoadState,
|
LoadState,
|
||||||
@ -196,9 +196,6 @@ impl MessageMapper<Message, AppState> for StateMachine {
|
|||||||
Message::UpdateRecipeCount(id, count) => {
|
Message::UpdateRecipeCount(id, count) => {
|
||||||
original_copy.recipe_counts.insert(id, count);
|
original_copy.recipe_counts.insert(id, count);
|
||||||
}
|
}
|
||||||
Message::InitExtras(set) => {
|
|
||||||
original_copy.extras = set;
|
|
||||||
}
|
|
||||||
Message::AddExtra(amt, name) => {
|
Message::AddExtra(amt, name) => {
|
||||||
original_copy.extras.insert((amt, name));
|
original_copy.extras.insert((amt, name));
|
||||||
}
|
}
|
||||||
@ -208,9 +205,6 @@ impl MessageMapper<Message, AppState> for StateMachine {
|
|||||||
Message::SetStaples(staples) => {
|
Message::SetStaples(staples) => {
|
||||||
original_copy.staples = staples;
|
original_copy.staples = staples;
|
||||||
}
|
}
|
||||||
Message::InitRecipes(recipes) => {
|
|
||||||
original_copy.recipes = recipes;
|
|
||||||
}
|
|
||||||
Message::SetRecipe(id, recipe) => {
|
Message::SetRecipe(id, recipe) => {
|
||||||
original_copy.recipes.insert(id, recipe);
|
original_copy.recipes.insert(id, recipe);
|
||||||
}
|
}
|
||||||
@ -242,38 +236,14 @@ impl MessageMapper<Message, AppState> for StateMachine {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Message::UpdateCategories => {
|
|
||||||
let store = self.0.clone();
|
|
||||||
let mut original_copy = original_copy.clone();
|
|
||||||
spawn_local_scoped(cx, async move {
|
|
||||||
if let Some(categories) = match store.get_categories().await {
|
|
||||||
Ok(js) => js,
|
|
||||||
Err(e) => {
|
|
||||||
error!(err=?e, "Failed to get categories.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} {
|
|
||||||
original_copy.category_map = categories;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Message::ResetInventory => {
|
Message::ResetInventory => {
|
||||||
original_copy.filtered_ingredients = BTreeSet::new();
|
original_copy.filtered_ingredients = BTreeSet::new();
|
||||||
original_copy.modified_amts = BTreeMap::new();
|
original_copy.modified_amts = BTreeMap::new();
|
||||||
original_copy.extras = BTreeSet::new();
|
original_copy.extras = BTreeSet::new();
|
||||||
}
|
}
|
||||||
Message::InitFilteredIngredient(set) => {
|
|
||||||
original_copy.filtered_ingredients = set;
|
|
||||||
}
|
|
||||||
Message::AddFilteredIngredient(key) => {
|
Message::AddFilteredIngredient(key) => {
|
||||||
original_copy.filtered_ingredients.insert(key);
|
original_copy.filtered_ingredients.insert(key);
|
||||||
}
|
}
|
||||||
Message::RemoveFilteredIngredient(key) => {
|
|
||||||
original_copy.filtered_ingredients.remove(&key);
|
|
||||||
}
|
|
||||||
Message::InitAmts(map) => {
|
|
||||||
original_copy.modified_amts = map;
|
|
||||||
}
|
|
||||||
Message::UpdateAmt(key, amt) => {
|
Message::UpdateAmt(key, amt) => {
|
||||||
original_copy.modified_amts.insert(key, amt);
|
original_copy.modified_amts.insert(key, amt);
|
||||||
}
|
}
|
||||||
@ -313,115 +283,3 @@ pub fn get_state_handler<'ctx>(
|
|||||||
) -> StateHandler<'ctx> {
|
) -> StateHandler<'ctx> {
|
||||||
Handler::new(cx, initial, StateMachine(store))
|
Handler::new(cx, initial, StateMachine(store))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct State {
|
|
||||||
pub recipe_counts: RcSignal<BTreeMap<String, RcSignal<usize>>>,
|
|
||||||
pub extras: RcSignal<Vec<(usize, (RcSignal<String>, RcSignal<String>))>>,
|
|
||||||
pub staples: RcSignal<Option<Recipe>>,
|
|
||||||
pub recipes: RcSignal<BTreeMap<String, Recipe>>,
|
|
||||||
pub category_map: RcSignal<BTreeMap<String, String>>,
|
|
||||||
pub filtered_ingredients: RcSignal<BTreeSet<IngredientKey>>,
|
|
||||||
pub modified_amts: RcSignal<BTreeMap<IngredientKey, RcSignal<String>>>,
|
|
||||||
pub auth: RcSignal<Option<UserData>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl State {
|
|
||||||
pub fn get_from_context(cx: Scope) -> std::rc::Rc<Self> {
|
|
||||||
use_context::<std::rc::Rc<Self>>(cx).clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_menu_list(&self) -> Vec<(String, RcSignal<usize>)> {
|
|
||||||
self.recipe_counts
|
|
||||||
.get()
|
|
||||||
.iter()
|
|
||||||
.map(|(k, v)| (k.clone(), v.clone()))
|
|
||||||
.filter(|(_, v)| *(v.get_untracked()) != 0)
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip(self))]
|
|
||||||
pub fn get_shopping_list(
|
|
||||||
&self,
|
|
||||||
show_staples: bool,
|
|
||||||
) -> BTreeMap<String, Vec<(Ingredient, BTreeSet<String>)>> {
|
|
||||||
let mut acc = IngredientAccumulator::new();
|
|
||||||
let recipe_counts = self.get_menu_list();
|
|
||||||
for (idx, count) in recipe_counts.iter() {
|
|
||||||
for _ in 0..*count.get_untracked() {
|
|
||||||
acc.accumulate_from(
|
|
||||||
self.recipes
|
|
||||||
.get()
|
|
||||||
.get(idx)
|
|
||||||
.expect(&format!("No such recipe id exists: {}", idx)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if show_staples {
|
|
||||||
if let Some(staples) = self.staples.get().as_ref() {
|
|
||||||
acc.accumulate_from(staples);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let mut ingredients = acc.ingredients();
|
|
||||||
let mut groups = BTreeMap::new();
|
|
||||||
let cat_map = self.category_map.get().clone();
|
|
||||||
for (_, (i, recipes)) in ingredients.iter_mut() {
|
|
||||||
let category = if let Some(cat) = cat_map.get(&i.name) {
|
|
||||||
cat.clone()
|
|
||||||
} else {
|
|
||||||
"other".to_owned()
|
|
||||||
};
|
|
||||||
i.category = category.clone();
|
|
||||||
groups
|
|
||||||
.entry(category)
|
|
||||||
.or_insert(vec![])
|
|
||||||
.push((i.clone(), recipes.clone()));
|
|
||||||
}
|
|
||||||
debug!(?self.category_map);
|
|
||||||
// FIXME(jwall): Sort by categories and names.
|
|
||||||
groups
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves the count for a recipe without triggering subscribers to the entire
|
|
||||||
/// recipe count set.
|
|
||||||
pub fn get_recipe_count_by_index(&self, key: &String) -> Option<RcSignal<usize>> {
|
|
||||||
self.recipe_counts.get_untracked().get(key).cloned()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reset_recipe_counts(&self) {
|
|
||||||
for (_, count) in self.recipe_counts.get_untracked().iter() {
|
|
||||||
count.set(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the recipe_count by index. Does not trigger subscribers to the entire set of recipe_counts.
|
|
||||||
/// This does trigger subscribers of the specific recipe you are updating though.
|
|
||||||
pub fn set_recipe_count_by_index(&self, key: &String, count: usize) -> RcSignal<usize> {
|
|
||||||
let mut counts = self.recipe_counts.get_untracked().as_ref().clone();
|
|
||||||
counts
|
|
||||||
.entry(key.clone())
|
|
||||||
.and_modify(|e| e.set(count))
|
|
||||||
.or_insert_with(|| create_rc_signal(count));
|
|
||||||
self.recipe_counts.set(counts);
|
|
||||||
self.recipe_counts.get_untracked().get(key).unwrap().clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_current_modified_amts(&self) -> BTreeMap<IngredientKey, String> {
|
|
||||||
let mut modified_amts = BTreeMap::new();
|
|
||||||
for (key, amt) in self.modified_amts.get_untracked().iter() {
|
|
||||||
modified_amts.insert(key.clone(), amt.get_untracked().as_ref().clone());
|
|
||||||
}
|
|
||||||
modified_amts
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reset_modified_amts(&self, modified_amts: BTreeMap<IngredientKey, String>) {
|
|
||||||
let mut modified_amts_copy = self.modified_amts.get().as_ref().clone();
|
|
||||||
for (key, amt) in modified_amts {
|
|
||||||
modified_amts_copy
|
|
||||||
.entry(key)
|
|
||||||
.and_modify(|amt_signal| amt_signal.set(amt.clone()))
|
|
||||||
.or_insert_with(|| create_rc_signal(amt));
|
|
||||||
}
|
|
||||||
self.modified_amts.set(modified_amts_copy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -16,7 +16,7 @@ use std::rc::Rc;
|
|||||||
use sycamore::prelude::*;
|
use sycamore::prelude::*;
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
|
|
||||||
use crate::app_state::{self, Message, StateHandler};
|
use crate::app_state::{Message, StateHandler};
|
||||||
|
|
||||||
#[derive(Props)]
|
#[derive(Props)]
|
||||||
pub struct RecipeCheckBoxProps<'ctx> {
|
pub struct RecipeCheckBoxProps<'ctx> {
|
||||||
@ -46,7 +46,6 @@ pub fn RecipeSelection<'ctx, G: Html>(
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
let id_clone = id.clone();
|
|
||||||
let title = title.get().clone();
|
let title = title.get().clone();
|
||||||
let for_id = id.clone();
|
let for_id = id.clone();
|
||||||
let href = format!("/ui/recipe/view/{}", id);
|
let href = format!("/ui/recipe/view/{}", id);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user