From faf303bbddceed706fb1fa581a970f69a674c7e4 Mon Sep 17 00:00:00 2001 From: danda Date: Tue, 14 May 2024 11:54:42 -0700 Subject: [PATCH] feat: integrate team feedback Changes: + present not-found page for unhandled uri paths, eg /stuff + display the tip-height on front page + add favicon and neptune logo to front page + use ServerDir instead of ServeFile for /image and /css + add help tooltips for fields on front page + use monospace font for digests --- src/html/page/not_found.rs | 6 +++ src/html/page/root.rs | 26 +++++++----- src/http_util.rs | 4 ++ src/main.rs | 23 +++++----- templates/web/css/styles.css | 53 ++++++++++++++++++++++++ templates/web/html/page/block_info.html | 2 +- templates/web/html/page/root.html | 52 ++++++++++++++++------- templates/web/html/page/utxo.html | 9 +++- templates/web/image/neptune-favicon.png | Bin 0 -> 4504 bytes templates/web/image/neptune-logo.png | Bin 0 -> 3889 bytes 10 files changed, 134 insertions(+), 41 deletions(-) create mode 100644 templates/web/image/neptune-favicon.png create mode 100644 templates/web/image/neptune-logo.png diff --git a/src/html/page/not_found.rs b/src/html/page/not_found.rs index 6f61bd6..a1c04ee 100644 --- a/src/html/page/not_found.rs +++ b/src/html/page/not_found.rs @@ -1,7 +1,9 @@ use crate::html::component::header::HeaderHtml; use crate::http_util::not_found_html_err; +use crate::http_util::not_found_html_handler; use crate::model::app_state::AppState; use axum::extract::State; +use axum::http::StatusCode; use axum::response::Html; use axum::response::Response; use html_escaper::Escape; @@ -39,3 +41,7 @@ pub fn not_found_html_response( ) -> Response { not_found_html_err(not_found_page(State(state), error_msg)) } + +pub fn not_found_html_fallback(state: Arc) -> (StatusCode, Html) { + not_found_html_handler(not_found_page(State(state), None)) +} diff --git a/src/html/page/root.rs b/src/html/page/root.rs index 7516c98..dfbb753 100644 --- a/src/html/page/root.rs +++ b/src/html/page/root.rs @@ -1,22 +1,28 @@ +use crate::html::page::not_found::not_found_html_response; use crate::model::app_state::AppState; use axum::extract::State; use axum::response::Html; +use axum::response::Response; use html_escaper::Escape; -use std::ops::Deref; +use neptune_core::models::blockchain::block::block_height::BlockHeight; use std::sync::Arc; +use tarpc::context; #[axum::debug_handler] -pub async fn root(State(state): State>) -> Html { +pub async fn root(State(state): State>) -> Result, Response> { #[derive(boilerplate::Boilerplate)] #[boilerplate(filename = "web/html/page/root.html")] - pub struct RootHtmlPage(Arc); - impl Deref for RootHtmlPage { - type Target = AppState; - fn deref(&self) -> &Self::Target { - &self.0 - } + pub struct RootHtmlPage { + tip_height: BlockHeight, + state: Arc, } - let root_page = RootHtmlPage(state); - Html(root_page.to_string()) + let tip_height = state + .rpc_client + .block_height(context::current()) + .await + .map_err(|e| not_found_html_response(State(state.clone()), Some(e.to_string())))?; + + let root_page = RootHtmlPage { tip_height, state }; + Ok(Html(root_page.to_string())) } diff --git a/src/http_util.rs b/src/http_util.rs index 2a7efc8..9fd9d5b 100644 --- a/src/http_util.rs +++ b/src/http_util.rs @@ -15,6 +15,10 @@ pub fn not_found_html_err(html: Html) -> Response { (StatusCode::NOT_FOUND, html).into_response() } +pub fn not_found_html_handler(html: Html) -> (StatusCode, Html) { + (StatusCode::NOT_FOUND, html) +} + pub fn rpc_err(e: RpcError) -> Response { (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()).into_response() } diff --git a/src/main.rs b/src/main.rs index df2d457..a1e8b11 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use neptune_core::models::blockchain::block::block_selector::BlockSelector; use neptune_core::rpc_server::RPCClient; use neptune_explorer::html::page::block::block_page; use neptune_explorer::html::page::block::block_page_with_value; +use neptune_explorer::html::page::not_found::not_found_html_fallback; use neptune_explorer::html::page::root::root; use neptune_explorer::html::page::utxo::utxo_page; use neptune_explorer::model::app_state::AppState; @@ -21,7 +22,7 @@ use tarpc::client; use tarpc::client::RpcError; use tarpc::context; use tarpc::tokio_serde::formats::Json as RpcJson; -use tower_http::services::ServeFile; +use tower_http::services::ServeDir; #[tokio::main] async fn main() -> Result<(), RpcError> { @@ -58,20 +59,16 @@ async fn main() -> Result<(), RpcError> { .route("/block/:selector/:value", get(block_page_with_value)) .route("/utxo/:value", get(utxo_page)) // -- Static files -- - .route_service( - "/css/pico.min.css", - ServeFile::new(concat!( - env!("CARGO_MANIFEST_DIR"), - "/templates/web/css/pico.min.css" - )), + .nest_service( + "/css", + ServeDir::new(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/web/css")), ) - .route_service( - "/css/styles.css", - ServeFile::new(concat!( - env!("CARGO_MANIFEST_DIR"), - "/templates/web/css/styles.css" - )), + .nest_service( + "/image", + ServeDir::new(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/web/image")), ) + // handle route not-found + .fallback(not_found_html_fallback(shared_state.clone())) // add state .with_state(shared_state); diff --git a/templates/web/css/styles.css b/templates/web/css/styles.css index 230f57f..8cedc95 100644 --- a/templates/web/css/styles.css +++ b/templates/web/css/styles.css @@ -3,6 +3,59 @@ div.indent { left: 20px; } +.mono { + font-family: monospace, monospace; +} + .center-text { text-align: center; } + +/* Tooltip container */ +.tooltip { + position: relative; + display: inline-block; + bottom: 0.1em; + transition: 0s; +} + +/* Tooltip text */ +.tooltip .tooltiptext { + transition-delay: 0.5s; + top: -5px; + left: 115%; + visibility: hidden; + width: 300px; + background-color: white; + color: rgb(0, 118, 118); + text-align: center; + padding: 5px; + border-radius: 6px; + border: solid 1px rgb(1, 220, 220); + + /* Position the tooltip text - see examples below! */ + position: absolute; + z-index: 1; +} + +/* adds a speech-bubble thingy at top-left of tooltip */ +.tooltip .tooltiptext::after { + content: " "; + position: absolute; + top: 20px; + right: 100%; + /* To the left of the tooltip */ + margin-top: -5px; + border-width: 5px; + border-style: solid; + border-color: transparent rgb(1, 220, 220) transparent transparent; +} + +/* Show the tooltip text when you mouse over the tooltip container */ +.tooltip:hover .tooltiptext { + visibility: visible; +} + +.tooltip:hover { + cursor: help; +} diff --git a/templates/web/html/page/block_info.html b/templates/web/html/page/block_info.html index 2ae5dec..8740a5c 100644 --- a/templates/web/html/page/block_info.html +++ b/templates/web/html/page/block_info.html @@ -27,7 +27,7 @@ - + diff --git a/templates/web/html/page/root.html b/templates/web/html/page/root.html index 216b033..f2659d7 100644 --- a/templates/web/html/page/root.html +++ b/templates/web/html/page/root.html @@ -1,8 +1,9 @@ - Neptune Block Explorer: (network: {{self.network}}) + Neptune Block Explorer: (network: {{self.state.network}}) +
Digest{{self.block_info.digest.to_hex()}}{{self.block_info.digest.to_hex()}}
Created