use leptos::*; use leptos_router::*; use crate::prelude::*; #[component] pub fn DebugPage() -> impl IntoView { let query_params = use_query_map(); let auth = use_context::().expect("missing auth context"); let (cached, set_cached) = create_signal(false); let (error, set_error) = create_signal(false); let (plain, set_plain) = create_signal(false); let (text, set_text) = create_signal("".to_string()); let navigate = use_navigate(); let cached_query = move || ( query_params.with(|params| params.get("q").cloned().unwrap_or_default()), cached.get(), ); let object = create_local_resource( cached_query, move |(query, cached)| async move { set_text.set(query.clone()); set_error.set(false); if query.is_empty() { return serde_json::Value::Null }; if cached { match CACHE.get(&query) { Some(x) => (*x).clone(), None => { set_error.set(true); serde_json::Value::Null }, } } else { debug_fetch(&format!("{URL_BASE}/proxy?id={query}"), auth, set_error).await } } ); let loading = object.loading(); view! {
config :: devtools
				{move || match object.get() {
					None => view! { 

}.into_view(), Some(o) => if plain.get() { serde_json::to_string_pretty(&o).unwrap_or_else(|e| e.to_string()).into_view() } else { view! { }.into_view() }, }}

" raw :: " obj " :: " usr " :: " ext " :: " copy

} } // this is a rather weird way to fetch but i want to see the bare error text if it fails! async fn debug_fetch(url: &str, token: Auth, error: WriteSignal) -> serde_json::Value { match Http::request::<()>(reqwest::Method::GET, url, None, token).await { Ok(res) => { if res.error_for_status_ref().is_err() { error.set(true); // this is an error but body could still be useful json } match res.text().await { Ok(x) => match serde_json::from_str(&x) { Ok(v) => v, Err(_) => { error.set(true); serde_json::Value::String(x) }, }, Err(e) => { error.set(true); serde_json::Value::String(format!("[!] invalid response body: {e}")) }, } }, Err(e) => { error.set(true); serde_json::Value::String(format!("[!] failed sending request: {e}")) }, } } #[component] fn DocumentNode(obj: serde_json::Value, #[prop(optional)] depth: usize) -> impl IntoView { let prefix = " ".repeat(depth); let newline_replace = format!("\n{prefix} "); match obj { serde_json::Value::Null => view! { null }.into_view(), serde_json::Value::Bool(x) => view! { {x} }.into_view(), serde_json::Value::Number(n) => view! { {n.to_string()} }.into_view(), serde_json::Value::String(s) => { if s.starts_with("https://") || s.starts_with("http://") { view! { {s} }.into_view() } else { view! { "\""{s.replace("
", "
\n").replace('\n', &newline_replace)}
"\"" }.into_view() } }, serde_json::Value::Array(arr) => if arr.is_empty() { view! { "[]" }.into_view() } else { view! { "[\n" {arr.into_iter().map(|x| view! { {prefix.clone()}" ""\n" }).collect_view()} {prefix.clone()}"]" }.into_view() }, serde_json::Value::Object(map) => if map.is_empty() { view! { "{}" }.into_view() } else { view! { "{\n" { map.into_iter() .map(|(k, v)| view! { {prefix.clone()}" "{k}": ""\n" }) .collect_view() } {prefix.clone()}"}" }.into_view() }, } }