Use StateHandler in Categories

This commit is contained in:
Jeremy Wall 2022-12-28 14:55:15 -06:00
parent 1888e5328f
commit 4b2563509b
4 changed files with 40 additions and 30 deletions

View File

@ -30,7 +30,7 @@ pub struct AppState {
pub extras: BTreeSet<(String, String)>,
pub staples: Option<Recipe>,
pub recipes: BTreeMap<String, Recipe>,
pub category_map: BTreeMap<String, String>,
pub category_map: String,
pub filtered_ingredients: BTreeSet<IngredientKey>,
pub modified_amts: BTreeMap<IngredientKey, String>,
pub auth: Option<UserData>,
@ -43,7 +43,7 @@ impl AppState {
extras: BTreeSet::new(),
staples: None,
recipes: BTreeMap::new(),
category_map: BTreeMap::new(),
category_map: String::new(),
filtered_ingredients: BTreeSet::new(),
modified_amts: BTreeMap::new(),
auth: None,
@ -63,7 +63,8 @@ pub enum Message {
SetRecipe(String, Recipe),
RemoveRecipe(String),
SetStaples(Option<Recipe>),
SetCategoryMap(BTreeMap<String, String>),
SetCategoryMap(String),
UpdateCategories,
InitFilteredIngredient(BTreeSet<IngredientKey>),
AddFilteredIngredient(IngredientKey),
RemoveFilteredIngredient(IngredientKey),
@ -154,14 +155,7 @@ impl StateMachine {
match store.get_categories().await {
Ok(Some(categories_content)) => {
debug!(categories=?categories_content);
match recipes::parse::as_categories(&categories_content) {
Ok(category_map) => {
state.category_map = category_map;
}
Err(err) => {
error!(?err)
}
};
state.category_map = categories_content;
}
Ok(None) => {
warn!("There is no category file");
@ -233,8 +227,29 @@ impl MessageMapper<Message, AppState> for StateMachine {
Message::RemoveRecipe(id) => {
original_copy.recipes.remove(&id);
}
Message::SetCategoryMap(map) => {
original_copy.category_map = map;
Message::SetCategoryMap(category_text) => {
let store = self.0.clone();
original_copy.category_map = category_text.clone();
spawn_local_scoped(cx, async move {
if let Err(e) = store.save_categories(category_text).await {
error!(?e, "Failed to save categories");
}
});
}
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::InitFilteredIngredient(set) => {
original_copy.filtered_ingredients = set;

View File

@ -11,14 +11,16 @@
// 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 crate::{
app_state::{Message, StateHandler},
js_lib::get_element_by_id,
};
use sycamore::{futures::spawn_local_scoped, prelude::*};
use tracing::{debug, error, instrument};
use web_sys::HtmlDialogElement;
use recipes::parse;
use crate::js_lib::get_element_by_id;
fn get_error_dialog() -> HtmlDialogElement {
get_element_by_id::<HtmlDialogElement>("error-dialog")
.expect("error-dialog isn't an html dialog element!")
@ -38,9 +40,9 @@ fn check_category_text_parses(unparsed: &str, error_text: &Signal<String>) -> bo
}
}
#[instrument]
#[instrument(skip_all)]
#[component]
pub fn Categories<G: Html>(cx: Scope) -> View<G> {
pub fn Categories<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View<G> {
let save_signal = create_signal(cx, ());
let error_text = create_signal(cx, String::new());
let category_text: &Signal<String> = create_signal(cx, String::new());
@ -65,18 +67,11 @@ pub fn Categories<G: Html>(cx: Scope) -> View<G> {
return;
}
spawn_local_scoped(cx, {
let store = crate::api::HttpStore::get_from_context(cx);
async move {
// TODO(jwall): Save the categories.
if let Err(e) = store
.save_categories(category_text.get_untracked().as_ref().clone())
.await
{
error!(?e, "Failed to save categories");
error_text.set(format!("{:?}", e));
} else {
dirty.set(false);
}
sh.dispatch(
cx,
Message::SetCategoryMap(category_text.get_untracked().as_ref().clone()),
);
}
});
});

View File

@ -21,6 +21,6 @@ pub fn CategoryPage<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> V
view! {cx,
ManagePage(
selected=Some("Categories".to_owned()),
) { Categories() }
) { Categories(sh) }
}
}

View File

@ -21,8 +21,8 @@ use crate::{api, routing::Handler as RouteHandler};
#[instrument]
#[component]
pub fn UI<G: Html>(cx: Scope) -> View<G> {
api::HttpStore::provide_context(cx, "/api".to_owned());
// 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");
let app_state = crate::app_state::AppState::new();