mirror of
https://github.com/zaphar/kitchen.git
synced 2025-07-22 19:40:14 -04:00
Use tracing in our webassembly as well.
This commit is contained in:
parent
cf38056104
commit
bf97f1ed29
13
Cargo.lock
generated
13
Cargo.lock
generated
@ -789,6 +789,8 @@ dependencies = [
|
||||
"reqwasm",
|
||||
"serde_json",
|
||||
"sycamore",
|
||||
"tracing",
|
||||
"tracing-wasm",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
@ -1624,6 +1626,17 @@ dependencies = [
|
||||
"tracing-log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-wasm"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4575c663a174420fa2d78f4108ff68f65bf2fbb7dd89f33749b6e826b3626e07"
|
||||
dependencies = [
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.3"
|
||||
|
@ -18,6 +18,8 @@ reqwasm = "0.5.0"
|
||||
# This makes debugging panics more tractable.
|
||||
console_error_panic_hook = "0.1.7"
|
||||
serde_json = "1.0.79"
|
||||
tracing = "0.1.35"
|
||||
tracing-wasm = "0.2.1"
|
||||
|
||||
[dependencies.wasm-bindgen]
|
||||
# we need wasm-bindgen v0.2.78 exactly
|
||||
|
@ -11,11 +11,12 @@
|
||||
// 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::console_log;
|
||||
use crate::{components::Recipe, service::AppService};
|
||||
|
||||
use sycamore::{context::use_context, prelude::*};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
#[instrument]
|
||||
#[component(RecipeList<G>)]
|
||||
pub fn recipe_list() -> View<G> {
|
||||
let app_service = use_context::<AppService>();
|
||||
@ -26,7 +27,7 @@ pub fn recipe_list() -> View<G> {
|
||||
Indexed(IndexedProps{
|
||||
iterable: menu_list,
|
||||
template: |(idx, _count)| {
|
||||
console_log!("Rendering recipe index: {}", idx);
|
||||
debug!(idx=%idx, "Rendering recipe");
|
||||
let idx = Signal::new(idx);
|
||||
view ! {
|
||||
Recipe(idx.handle())
|
||||
|
@ -11,17 +11,22 @@
|
||||
// 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::console_log;
|
||||
use crate::service::AppService;
|
||||
use std::rc::Rc;
|
||||
|
||||
use sycamore::{context::use_context, prelude::*};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use crate::service::AppService;
|
||||
|
||||
pub struct RecipeCheckBoxProps {
|
||||
pub i: usize,
|
||||
pub title: ReadSignal<String>,
|
||||
}
|
||||
|
||||
#[instrument(skip(props), fields(
|
||||
idx=%props.i,
|
||||
title=%props.title.get()
|
||||
))]
|
||||
#[component(RecipeSelection<G>)]
|
||||
pub fn recipe_selection(props: RecipeCheckBoxProps) -> View<G> {
|
||||
let app_service = use_context::<AppService>();
|
||||
@ -36,7 +41,7 @@ pub fn recipe_selection(props: RecipeCheckBoxProps) -> View<G> {
|
||||
label(for=id_cloned_2) { (props.title.get()) }
|
||||
input(type="number", class="item-count-sel", min="0", bind:value=count.clone(), name=format!("recipe_id:{}", i), value=id_as_str.clone(), on:change=move |_| {
|
||||
let mut app_service = app_service.clone();
|
||||
console_log!("setting recipe id: {} to count: {}", i, *count.get());
|
||||
debug!(idx=%i, count=*count.get(), "setting recipe count");
|
||||
app_service.set_recipe_count_by_index(i, count.get().parse().unwrap());
|
||||
})
|
||||
}
|
||||
|
@ -11,11 +11,12 @@
|
||||
// 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::console_error;
|
||||
use crate::{components::recipe_selection::*, service::AppService};
|
||||
|
||||
use sycamore::{context::use_context, futures::spawn_local_in_scope, prelude::*};
|
||||
use tracing::{error, instrument};
|
||||
|
||||
#[instrument]
|
||||
#[component(RecipeSelector<G>)]
|
||||
pub fn recipe_selector() -> View<G> {
|
||||
let app_service = use_context::<AppService>();
|
||||
@ -32,8 +33,8 @@ pub fn recipe_selector() -> View<G> {
|
||||
spawn_local_in_scope(cloned!((app_service) => {
|
||||
let mut app_service = app_service.clone();
|
||||
async move {
|
||||
if let Err(e) = app_service.refresh().await {
|
||||
console_error!("{}", e);
|
||||
if let Err(err) = app_service.refresh().await {
|
||||
error!(?err);
|
||||
};
|
||||
}
|
||||
}));
|
||||
|
@ -14,9 +14,10 @@
|
||||
use crate::service::AppService;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
use crate::console_debug;
|
||||
use sycamore::{context::use_context, prelude::*};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
#[instrument]
|
||||
#[component(ShoppingList<G>)]
|
||||
pub fn shopping_list() -> View<G> {
|
||||
let app_service = use_context::<AppService>();
|
||||
@ -27,7 +28,7 @@ pub fn shopping_list() -> View<G> {
|
||||
create_effect(cloned!((app_service, ingredients_map) => move || {
|
||||
ingredients_map.set(app_service.get_shopping_list());
|
||||
}));
|
||||
console_debug!("Ingredients map: {:?}", ingredients_map.get_untracked());
|
||||
debug!(ingredients_map=?ingredients_map.get_untracked());
|
||||
let ingredients = create_memo(cloned!((ingredients_map, filtered_keys) => move || {
|
||||
let mut ingredients = Vec::new();
|
||||
// This has the effect of sorting the ingredients by category
|
||||
@ -40,7 +41,7 @@ pub fn shopping_list() -> View<G> {
|
||||
}
|
||||
ingredients
|
||||
}));
|
||||
console_debug!("Ingredients: {:?}", ingredients.get_untracked());
|
||||
debug!(ingredients = ?ingredients.get_untracked());
|
||||
let table_view = Signal::new(View::empty());
|
||||
create_effect(
|
||||
cloned!((table_view, ingredients, filtered_keys, modified_amts, extras) => move || {
|
||||
|
@ -16,19 +16,20 @@ mod components;
|
||||
mod pages;
|
||||
mod router_integration;
|
||||
mod service;
|
||||
mod typings;
|
||||
mod web;
|
||||
|
||||
use sycamore::prelude::*;
|
||||
#[cfg(feature = "web")]
|
||||
use tracing_wasm;
|
||||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
|
||||
use web::UI;
|
||||
|
||||
#[wasm_bindgen(start)]
|
||||
pub fn main() {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
if cfg!(feature = "web") {
|
||||
console_error_panic_hook::set_once();
|
||||
tracing_wasm::set_as_global_default();
|
||||
}
|
||||
sycamore::render(|| view! { UI() });
|
||||
}
|
||||
|
@ -16,16 +16,15 @@ use std::rc::Rc;
|
||||
use std::str::FromStr;
|
||||
|
||||
use sycamore::prelude::*;
|
||||
use tracing::{debug, error, instrument};
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::JsCast;
|
||||
use web_sys::Event;
|
||||
use web_sys::{Element, HtmlAnchorElement};
|
||||
|
||||
use crate::app_state::AppRoutes;
|
||||
use crate::console_debug;
|
||||
use crate::console_error;
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BrowserIntegration(Signal<(String, String, String)>);
|
||||
|
||||
impl BrowserIntegration {
|
||||
@ -38,6 +37,7 @@ impl BrowserIntegration {
|
||||
)))
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
pub fn click_handler(&self) -> Box<dyn Fn(web_sys::Event)> {
|
||||
let route_signal = self.0.clone();
|
||||
Box::new(move |ev| {
|
||||
@ -49,12 +49,12 @@ impl BrowserIntegration {
|
||||
.unwrap_throw()
|
||||
.map(|e| e.unchecked_into::<HtmlAnchorElement>())
|
||||
{
|
||||
console_debug!("handling navigation event.");
|
||||
debug!("handling navigation event.");
|
||||
let location = web_sys::window().unwrap_throw().location();
|
||||
|
||||
if tgt.rel() == "external" {
|
||||
debug!("External Link so ignoring.");
|
||||
return;
|
||||
console_debug!("External Link so ignoring.");
|
||||
}
|
||||
|
||||
let origin = tgt.origin();
|
||||
@ -67,12 +67,12 @@ impl BrowserIntegration {
|
||||
}
|
||||
(true, _, false) // different hash
|
||||
| (true, false, _) /* different path */ => {
|
||||
console_debug!("different path or hash");
|
||||
debug!("different path or hash");
|
||||
ev.prevent_default();
|
||||
// Signal the pathname change
|
||||
let path = format!("{}{}{}", &origin, &tgt_pathname, &hash);
|
||||
console_debug!("new route: ({}, {}, {})", origin, tgt_pathname, hash);
|
||||
console_debug!("new path: ({})", &path);
|
||||
debug!("new route: ({}, {}, {})", origin, tgt_pathname, hash);
|
||||
debug!("new path: ({})", &path);
|
||||
route_signal.set((origin, tgt_pathname, hash));
|
||||
// Update History API.
|
||||
let window = web_sys::window().unwrap_throw();
|
||||
@ -88,6 +88,7 @@ impl BrowserIntegration {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RouterProps<R, F, G>
|
||||
where
|
||||
G: GenericNode,
|
||||
@ -99,13 +100,18 @@ where
|
||||
pub browser_integration: BrowserIntegration,
|
||||
}
|
||||
|
||||
#[instrument(fields(?props.route,
|
||||
origin=props.browser_integration.0.get().0,
|
||||
pathn=props.browser_integration.0.get().1,
|
||||
hash=props.browser_integration.0.get().2),
|
||||
skip(props))]
|
||||
#[component(Router<G>)]
|
||||
pub fn router<R, F>(props: RouterProps<R, F, G>) -> View<G>
|
||||
where
|
||||
R: DeriveRoute + NotFound + Clone + Default + Debug + 'static,
|
||||
F: Fn(ReadSignal<R>) -> View<G> + 'static,
|
||||
{
|
||||
console_debug!("Setting up router");
|
||||
debug!("Setting up router");
|
||||
let integration = Rc::new(props.browser_integration);
|
||||
let route_select = Rc::new(props.route_select);
|
||||
|
||||
@ -113,10 +119,10 @@ where
|
||||
create_effect(
|
||||
cloned!((view_signal, integration, route_select) => move || {
|
||||
let path_signal = integration.0.clone();
|
||||
console_debug!("new path: {:?}", path_signal.get());
|
||||
debug!("new path: {:?}", path_signal.get());
|
||||
let path = path_signal.clone();
|
||||
let route = R::from(path.get().as_ref());
|
||||
console_debug!("new route: {:?}", &route);
|
||||
debug!("new route: {:?}", &route);
|
||||
// TODO(jwall): this is an unnecessary use of signal.
|
||||
let view = route_select.as_ref()(Signal::new(route).handle());
|
||||
register_click_handler(&view, integration.clone());
|
||||
@ -131,22 +137,23 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
fn register_click_handler<G>(view: &View<G>, integration: Rc<BrowserIntegration>)
|
||||
where
|
||||
G: GenericNode<EventType = Event>,
|
||||
{
|
||||
console_debug!("Registring click handler on node(s)");
|
||||
debug!("Registring click handler on node(s)");
|
||||
if let Some(node) = view.as_node() {
|
||||
node.event("click", integration.click_handler());
|
||||
} else if let Some(frag) = view.as_fragment() {
|
||||
console_debug!("Fragment? {:?}", frag);
|
||||
debug!(fragment=?frag);
|
||||
for n in frag {
|
||||
register_click_handler(n, integration.clone());
|
||||
}
|
||||
} else if let Some(dyn_node) = view.as_dyn() {
|
||||
console_debug!("Dynamic node? {:?}", dyn_node);
|
||||
debug!(dynamic_node=?dyn_node);
|
||||
} else {
|
||||
console_debug!("Unknown node? {:?}", view);
|
||||
debug!(node=?view, "Unknown node");
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,8 +172,9 @@ pub trait DeriveRoute {
|
||||
}
|
||||
|
||||
impl DeriveRoute for AppRoutes {
|
||||
#[instrument]
|
||||
fn from(input: &(String, String, String)) -> AppRoutes {
|
||||
console_debug!("routing: {input:?}");
|
||||
debug!("routing: {input:?}");
|
||||
match input.2.as_str() {
|
||||
"" => AppRoutes::default(),
|
||||
"#plan" => AppRoutes::Plan,
|
||||
@ -183,7 +191,7 @@ impl DeriveRoute for AppRoutes {
|
||||
};
|
||||
}
|
||||
}
|
||||
console_error!("Path not found: [{:?}]", input);
|
||||
error!("Path not found: [{:?}]", input);
|
||||
AppRoutes::NotFound
|
||||
}
|
||||
}
|
||||
|
@ -13,10 +13,9 @@
|
||||
// limitations under the License.
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
use crate::{console_debug, console_error, console_log};
|
||||
|
||||
use reqwasm::http;
|
||||
use sycamore::prelude::*;
|
||||
use tracing::{debug, error, info, instrument};
|
||||
use web_sys::{window, Storage};
|
||||
|
||||
use recipes::{parse, Ingredient, IngredientAccumulator, Recipe};
|
||||
@ -46,6 +45,7 @@ impl AppService {
|
||||
.map_err(|e| format!("{:?}", e))
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn fetch_recipes_http() -> Result<String, String> {
|
||||
let resp = match http::Request::get("/api/v1/recipes").send().await {
|
||||
Ok(resp) => resp,
|
||||
@ -54,52 +54,55 @@ impl AppService {
|
||||
if resp.status() != 200 {
|
||||
return Err(format!("Status: {}", resp.status()));
|
||||
} else {
|
||||
console_debug!("We got a valid response back!");
|
||||
debug!("We got a valid response back!");
|
||||
return Ok(resp.text().await.map_err(|e| format!("{}", e))?);
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn fetch_categories_http() -> Result<Option<String>, String> {
|
||||
let resp = match http::Request::get("/api/v1/categories").send().await {
|
||||
Ok(resp) => resp,
|
||||
Err(e) => return Err(format!("Error: {}", e)),
|
||||
};
|
||||
if resp.status() == 404 {
|
||||
console_debug!("Categories returned 404");
|
||||
debug!("Categories returned 404");
|
||||
return Ok(None);
|
||||
} else if resp.status() != 200 {
|
||||
return Err(format!("Status: {}", resp.status()));
|
||||
} else {
|
||||
console_debug!("We got a valid response back!");
|
||||
debug!("We got a valid response back!");
|
||||
return Ok(Some(resp.text().await.map_err(|e| format!("{}", e))?));
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn synchronize() -> Result<(), String> {
|
||||
console_log!("Synchronizing Recipes");
|
||||
info!("Synchronizing Recipes");
|
||||
let storage = Self::get_storage()?.unwrap();
|
||||
let recipes = Self::fetch_recipes_http().await?;
|
||||
storage
|
||||
.set_item("recipes", &recipes)
|
||||
.map_err(|e| format!("{:?}", e))?;
|
||||
console_log!("Synchronizing categories");
|
||||
info!("Synchronizing categories");
|
||||
match Self::fetch_categories_http().await {
|
||||
Ok(Some(categories_content)) => {
|
||||
console_debug!("categories: {}", categories_content);
|
||||
debug!(categories=?categories_content);
|
||||
storage
|
||||
.set_item("categories", &categories_content)
|
||||
.map_err(|e| format!("{:?}", e))?;
|
||||
}
|
||||
Ok(None) => {
|
||||
console_error!("There is no category file");
|
||||
error!("There is no category file");
|
||||
}
|
||||
Err(e) => {
|
||||
console_error!("{}", e);
|
||||
error!("{}", e);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn fetch_categories_from_storage() -> Result<Option<BTreeMap<String, String>>, String> {
|
||||
let storage = Self::get_storage()?.unwrap();
|
||||
match storage
|
||||
@ -111,7 +114,7 @@ impl AppService {
|
||||
match parse::as_categories(&parsed) {
|
||||
Ok(categories) => Ok(Some(categories)),
|
||||
Err(e) => {
|
||||
console_debug!("Error parsing categories {}", e);
|
||||
debug!("Error parsing categories {}", e);
|
||||
Err(format!("Error parsing categories {}", e))
|
||||
}
|
||||
}
|
||||
@ -120,6 +123,7 @@ impl AppService {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn fetch_recipes_from_storage(
|
||||
) -> Result<(Option<Recipe>, Option<Vec<(usize, Recipe)>>), String> {
|
||||
let storage = Self::get_storage()?.unwrap();
|
||||
@ -136,11 +140,10 @@ impl AppService {
|
||||
let recipe = match parse::as_recipe(&r) {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
console_error!("Error parsing recipe {}", e);
|
||||
error!("Error parsing recipe {}", e);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
//console_debug!("We parsed a recipe {}", recipe.title);
|
||||
if recipe.title == "Staples" {
|
||||
staples = Some(recipe);
|
||||
} else {
|
||||
@ -161,14 +164,15 @@ impl AppService {
|
||||
Ok(Self::fetch_categories_from_storage()?)
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
pub async fn refresh(&mut self) -> Result<(), String> {
|
||||
Self::synchronize().await?;
|
||||
console_debug!("refreshing recipes");
|
||||
debug!("refreshing recipes");
|
||||
if let (staples, Some(r)) = Self::fetch_recipes().await? {
|
||||
self.set_recipes(r);
|
||||
self.staples.set(staples);
|
||||
}
|
||||
console_debug!("refreshing categories");
|
||||
debug!("refreshing categories");
|
||||
if let Some(categories) = Self::fetch_categories().await? {
|
||||
self.set_categories(categories);
|
||||
}
|
||||
@ -179,6 +183,7 @@ impl AppService {
|
||||
self.recipes.get().get(idx).map(|(_, r)| r.clone())
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
pub fn get_shopping_list(&self) -> BTreeMap<String, Vec<(Ingredient, BTreeSet<String>)>> {
|
||||
let mut acc = IngredientAccumulator::new();
|
||||
let recipe_counts = self.menu_list.get();
|
||||
@ -205,7 +210,7 @@ impl AppService {
|
||||
.or_insert(vec![])
|
||||
.push((i.clone(), recipes.clone()));
|
||||
}
|
||||
console_debug!("Category map {:?}", self.category_map);
|
||||
debug!(?self.category_map);
|
||||
// FIXM(jwall): Sort by categories and names.
|
||||
groups
|
||||
}
|
||||
|
@ -1,88 +0,0 @@
|
||||
// Copyright 2022 Jeremy Wall
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// 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 wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
// Use `js_namespace` here to bind `console.log(..)` instead of just
|
||||
// `log(..)`
|
||||
#[wasm_bindgen(js_namespace = console)]
|
||||
pub fn log(s: &str);
|
||||
#[wasm_bindgen(js_namespace = console)]
|
||||
pub fn debug(s: &str);
|
||||
#[wasm_bindgen(js_namespace = console)]
|
||||
pub fn warn(s: &str);
|
||||
#[wasm_bindgen(js_namespace = console)]
|
||||
pub fn error(s: &str);
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! console_log {
|
||||
// Note that this is using the `log` function imported above during
|
||||
// `bare_bones`
|
||||
($($t:tt)*) => {
|
||||
if cfg!(feature="web") {
|
||||
use crate::typings::log;
|
||||
log(&format_args!($($t)*).to_string());
|
||||
} else if cfg!(feature="ssr") {
|
||||
println!($($t)*);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! console_debug {
|
||||
// Note that this is using the `log` function imported above during
|
||||
// `bare_bones`
|
||||
($($t:tt)*) => {{
|
||||
if cfg!(feature="web") {
|
||||
use crate::typings::debug;
|
||||
debug(&format_args!($($t)*).to_string());
|
||||
} else if cfg!(feature="ssr") {
|
||||
print!("DEBUG: ");
|
||||
println!($($t)*);
|
||||
}
|
||||
}}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! console_error {
|
||||
// Note that this is using the `error` function imported above during
|
||||
// `bare_bones`
|
||||
($($t:tt)*) => {{
|
||||
if cfg!(feature="web")
|
||||
{
|
||||
use crate::typings::error;
|
||||
error(&format_args!($($t)*).to_string());
|
||||
} else if cfg!(feature="ssr") {
|
||||
print!("ERROR: ");
|
||||
println!($($t)*);
|
||||
};
|
||||
}}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! console_warn {
|
||||
// Note that this is using the `warn` function imported above during
|
||||
// `bare_bones`
|
||||
($($t:tt)*) => {{
|
||||
if cfg!("web") {
|
||||
use crate::typings::warn;
|
||||
(warn(&format_args!($($t)*).to_string()))
|
||||
} else if cfg!(feature="ssr") {
|
||||
print!("WARN: ");
|
||||
(println!($($t)*))
|
||||
}
|
||||
}}
|
||||
}
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
use crate::pages::*;
|
||||
use crate::{app_state::*, components::*, router_integration::*, service::AppService};
|
||||
use crate::{console_error, console_log};
|
||||
use tracing::{error, info, instrument};
|
||||
|
||||
use sycamore::{
|
||||
context::{ContextProvider, ContextProviderProps},
|
||||
@ -51,10 +51,11 @@ fn route_switch<G: Html>(route: ReadSignal<AppRoutes>) -> View<G> {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[component(UI<G>)]
|
||||
pub fn ui() -> View<G> {
|
||||
let app_service = AppService::new();
|
||||
console_log!("Starting UI");
|
||||
info!("Starting UI");
|
||||
view! {
|
||||
// NOTE(jwall): Set the app_service in our toplevel scope. Children will be able
|
||||
// to find the service as long as they are a child of this scope.
|
||||
@ -70,9 +71,9 @@ pub fn ui() -> View<G> {
|
||||
app_service.set_recipes(recipes);
|
||||
}
|
||||
Ok((_, None)) => {
|
||||
console_error!("No recipes to find");
|
||||
error!("No recipes to find");
|
||||
}
|
||||
Err(msg) => console_error!("Failed to get recipes {}", msg),
|
||||
Err(msg) => error!("Failed to get recipes {}", msg),
|
||||
}
|
||||
}
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user