Skip to content

Commit

Permalink
summonerd: tweaks to web interface
Browse files Browse the repository at this point in the history
  • Loading branch information
hdevalence committed Nov 4, 2023
1 parent 4f47927 commit 953550a
Show file tree
Hide file tree
Showing 6 changed files with 406 additions and 207 deletions.
141 changes: 106 additions & 35 deletions tools/summonerd/src/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,48 @@ pub struct WebAppState {
storage: Storage,
}

async fn serve_summoning_jpg() -> impl IntoResponse {
let jpg = include_bytes!("../templates/static/summoning.jpg").as_slice();
Response::builder()
.status(StatusCode::OK)
.header("Content-Type", "image/jpeg")
.header("Cache-Control", "public, max-age=3600") // Cache for 1 hour
.body(axum::body::Full::from(jpg))
.unwrap()
}

async fn serve_css() -> impl IntoResponse {
let css = include_bytes!("../templates/static/index.css").as_slice();
Response::builder()
.status(StatusCode::OK)
.header("Content-Type", "text/css")
.header("Cache-Control", "public, max-age=3600") // Cache for 1 hour
.body(axum::body::Full::from(css))
.unwrap()
}

async fn serve_woff2(filename: &str) -> impl IntoResponse {
let data = match filename {
"Iosevka-Term" => include_bytes!("../templates/static/Iosevka-Term.woff2").as_slice(),
"PublicSans-Bold" => include_bytes!("../templates/static/PublicSans-Bold.woff2").as_slice(),
"PublicSans-Regular" => {
include_bytes!("../templates/static/PublicSans-Regular.woff2").as_slice()
}
_ => {
return Response::builder()
.status(StatusCode::NOT_FOUND)
.body("Not Found".into())
.unwrap()
}
};
Response::builder()
.status(StatusCode::OK)
.header("Content-Type", "font/woff2")
.header("Cache-Control", "public, max-age=3600") // Cache for 1 hour
.body(axum::body::Full::from(data))
.unwrap()
}

pub fn web_app(
address: Address,
config: Config,
Expand All @@ -43,38 +85,69 @@ pub fn web_app(
.route("/", get(main_page).with_state(shared_state.clone()))
.route("/phase/1", get(phase_1).with_state(shared_state.clone()))
.route("/phase/2", get(phase_2).with_state(shared_state))
.route(
"/static/index.css",
get(|| async { include_bytes!("../templates/static/index.css") }),
)
.route("/static/index.css", get(serve_css))
.route(
"/static/Iosevka-Term.woff2",
get(|| async { include_bytes!("../templates/static/Iosevka-Term.woff2") }),
get(|| serve_woff2("Iosevka-Term")),
)
.route(
"/static/PublicSans-Bold.woff2",
get(|| async { include_bytes!("../templates/static/PublicSans-Bold.woff2") }),
get(|| serve_woff2("PublicSans-Bold")),
)
.route(
"/static/PublicSans-Regular.woff2",
get(|| async { include_bytes!("../templates/static/PublicSans-Regular.woff2") }),
get(|| serve_woff2("PublicSans-Regular")),
)
.route("/static/summoning.jpg", get(|| serve_summoning_jpg()))
}

pub async fn main_page(State(state): State<Arc<WebAppState>>) -> impl IntoResponse {
let phase_number = match state.phase {
PhaseMarker::P1 => 1,
PhaseMarker::P2 => 2,
};
let participants_top_median = snapshot_participants_top_median(state.clone()).await;

let (phase_number, phase_1_participants_top_median, phase_2_participants_top_median) =
match state.phase {
PhaseMarker::P1 => (1, Some(participants_top_median), None),
PhaseMarker::P2 => (2, None, Some(participants_top_median)),
};

let phase_1_completed = state
.storage
.current_slot(PhaseMarker::P1)
.await
.unwrap_or(0);
let phase_2_completed = state
.storage
.current_slot(PhaseMarker::P2)
.await
.unwrap_or(0);

let template = MainTemplate {
address: state.address.to_string(),
min_bid: format!("{}penumbra", state.config.min_bid_u64),
phase_number,
phase_1_completed,
phase_2_completed,
phase_1_participants_top_median,
phase_2_participants_top_median,
};
HtmlTemplate(template)
}

pub async fn snapshot_participants_top_median(state: Arc<WebAppState>) -> (u64, String, String) {
let snapshot = state.queue.snapshot().await;
(
snapshot.connected_participants,
format!(
"{}penumbra",
snapshot.top_bid.unwrap_or(0u64.into()) / 1_000_000u128.into()
),
format!(
"{}penumbra",
snapshot.median_bid.unwrap_or(0u64.into()) / 1_000_000u128.into()
),
)
}

pub async fn phase_1(State(state): State<Arc<WebAppState>>) -> impl IntoResponse {
let contributions_by_slot_hash_time_shortaddr = state
.storage
Expand All @@ -83,23 +156,19 @@ pub async fn phase_1(State(state): State<Arc<WebAppState>>) -> impl IntoResponse
.expect("Can get top N contributors");

let snapshot_participants_top_median = if state.phase == PhaseMarker::P1 {
let snapshot = state.queue.snapshot().await;
Some((
snapshot.connected_participants,
format!(
"{}penumbra",
snapshot.top_bid.unwrap_or(0u64.into()) / 1_000_000u128.into()
),
format!(
"{}penumbra",
snapshot.median_bid.unwrap_or(0u64.into()) / 1_000_000u128.into()
),
))
Some(snapshot_participants_top_median(state.clone()).await)
} else {
None
};

// extract the contribution number from the contribution data
let completed = contributions_by_slot_hash_time_shortaddr
.first()
.map(|(n, _, _, _)| *n)
.unwrap_or(0);

let template = Phase1Template {
completed,
snapshot_participants_top_median,
contributions_by_slot_hash_time_shortaddr,
};
Expand All @@ -114,23 +183,19 @@ pub async fn phase_2(State(state): State<Arc<WebAppState>>) -> impl IntoResponse
.expect("Can get top N contributors");

let snapshot_participants_top_median = if state.phase == PhaseMarker::P2 {
let snapshot = state.queue.snapshot().await;
Some((
snapshot.connected_participants,
format!(
"{}penumbra",
snapshot.top_bid.unwrap_or(0u64.into()) / 1_000_000u128.into()
),
format!(
"{}penumbra",
snapshot.median_bid.unwrap_or(0u64.into()) / 1_000_000u128.into()
),
))
Some(snapshot_participants_top_median(state.clone()).await)
} else {
None
};

// extract the contribution number from the contribution data
let completed = contributions_by_slot_hash_time_shortaddr
.first()
.map(|(n, _, _, _)| *n)
.unwrap_or(0);

let template = Phase2Template {
completed,
snapshot_participants_top_median,
contributions_by_slot_hash_time_shortaddr,
};
Expand All @@ -143,18 +208,24 @@ struct MainTemplate {
address: String,
min_bid: String,
phase_number: u64,
phase_1_completed: u64,
phase_1_participants_top_median: Option<(u64, String, String)>,
phase_2_completed: u64,
phase_2_participants_top_median: Option<(u64, String, String)>,
}

#[derive(Template)]
#[template(path = "phase1.html")]
struct Phase1Template {
completed: u64,
snapshot_participants_top_median: Option<(u64, String, String)>,
contributions_by_slot_hash_time_shortaddr: Vec<(u64, String, String, String)>,
}

#[derive(Template)]
#[template(path = "phase2.html")]
struct Phase2Template {
completed: u64,
snapshot_participants_top_median: Option<(u64, String, String)>,
contributions_by_slot_hash_time_shortaddr: Vec<(u64, String, String, String)>,
}
Expand Down
Loading

0 comments on commit 953550a

Please sign in to comment.