diff --git a/assets/icons.woff2 b/assets/icons.woff2 new file mode 100644 index 0000000..34311ea Binary files /dev/null and b/assets/icons.woff2 differ diff --git a/assets/platforms/n64.svg b/assets/platforms/n64.svg index ec90d8b..9bb01c5 100644 --- a/assets/platforms/n64.svg +++ b/assets/platforms/n64.svg @@ -1,6 +1,3 @@ - - - - - + + diff --git a/crates/images/src/lib.rs b/crates/images/src/lib.rs index 1d7c8d2..75befb8 100644 --- a/crates/images/src/lib.rs +++ b/crates/images/src/lib.rs @@ -5,7 +5,6 @@ pub mod treemap; use std::str::FromStr; use axum::{ - extract::Path, http::{StatusCode, header}, response::{IntoResponse, Response}, }; @@ -17,33 +16,6 @@ pub fn image_mime_from_ext(ext: &str) -> Option { .map(|format| Mime::from_str(format.to_mime_type()).unwrap()) } -pub async fn get_asset(Path(filename): Path) -> Result { - let path = join_normalized("assets", &filename); - let Some(ext) = path.extension() else { - return Err(AppError::Status(StatusCode::NOT_FOUND)); - }; - let content_type = if let Some(format) = image::ImageFormat::from_extension(ext) { - format.to_mime_type() - } else { - match ext.to_str() { - Some("svg") => mime::IMAGE_SVG.as_ref(), - _ => return Err(AppError::Status(StatusCode::NOT_FOUND)), - } - }; - let output = tokio::fs::read(path).await?; - Ok(( - [ - (header::CONTENT_TYPE, content_type), - #[cfg(not(debug_assertions))] - (header::CACHE_CONTROL, "public, max-age=3600"), - #[cfg(debug_assertions)] - (header::CACHE_CONTROL, "no-cache"), - ], - output, - ) - .into_response()) -} - pub async fn get_og() -> Result { let path = join_normalized("assets", "og.svg"); let svg_src = tokio::fs::read_to_string(&path) diff --git a/crates/web/src/handlers/auth.rs b/crates/web/src/handlers/auth.rs index b548ca0..af2ea04 100644 --- a/crates/web/src/handlers/auth.rs +++ b/crates/web/src/handlers/auth.rs @@ -44,8 +44,8 @@ pub async fn login( } Ok(html! { (DOCTYPE) - html { - head lang="en" { + html lang="en" { + head { meta charset="utf-8"; title { "Logging in... • decomp.dev" } meta http-equiv="refresh" content=(format!("0;URL={redirect_url}")); diff --git a/crates/web/src/handlers/common.rs b/crates/web/src/handlers/common.rs index da9f37b..1f5a855 100644 --- a/crates/web/src/handlers/common.rs +++ b/crates/web/src/handlers/common.rs @@ -133,11 +133,7 @@ pub fn nav_links() -> Markup { a href="https://wiki.decomp.dev" { "Wiki" } } li { - a #theme-toggle href="#" title="Toggle theme" { - (PreEscaped(r#" - -"#)) - } + a #theme-toggle .icon-theme-light-dark href="#" title="Toggle theme" {} } } } diff --git a/crates/web/src/handlers/manage.rs b/crates/web/src/handlers/manage.rs index dfa0683..499c717 100644 --- a/crates/web/src/handlers/manage.rs +++ b/crates/web/src/handlers/manage.rs @@ -39,8 +39,8 @@ pub async fn manage( Ok(html! { (DOCTYPE) - html { - head lang="en" { + html lang="en" { + head { meta charset="utf-8"; title { "Manage • decomp.dev" } (header()) @@ -138,8 +138,8 @@ async fn render_new( Ok(html! { (DOCTYPE) - html { - head lang="en" { + html lang="en" { + head { meta charset="utf-8"; title { "New Project • decomp.dev" } (header()) @@ -351,8 +351,8 @@ async fn render_manage_project( html! { (DOCTYPE) - html { - head lang="en" { + html lang="en" { + head { meta charset="utf-8"; title { (project_short_name) " • Manage" } (header()) diff --git a/crates/web/src/handlers/mod.rs b/crates/web/src/handlers/mod.rs index 4f4b597..db04177 100644 --- a/crates/web/src/handlers/mod.rs +++ b/crates/web/src/handlers/mod.rs @@ -32,7 +32,6 @@ pub fn build_router() -> Router { .route("/manage/{owner}/{repo}", get(manage::manage_project)) .route("/manage/{owner}/{repo}", post(manage::manage_project_save)) .route("/manage/{owner}/{repo}/refresh", post(manage::manage_project_refresh)) - .route("/assets/{*filename}", get(decomp_dev_images::get_asset)) .route("/og.png", get(decomp_dev_images::get_og)) .route("/", get(project::get_projects)) .route("/{owner}/{repo}", get(report::get_report)) diff --git a/crates/web/src/handlers/project.rs b/crates/web/src/handlers/project.rs index a1a37ae..3abda6c 100644 --- a/crates/web/src/handlers/project.rs +++ b/crates/web/src/handlers/project.rs @@ -157,8 +157,8 @@ pub async fn get_projects( let rendered = html! { (DOCTYPE) - html { - head lang="en" { + html lang="en" { + head { meta charset="utf-8"; title { "Projects • decomp.dev" } (header()) @@ -251,8 +251,7 @@ fn project_fragment( } @if let Some(platform) = &info.project.platform { @let platform_name = Platform::from_str(platform).map(|p| p.name()).unwrap_or(platform); - img class="platform-icon" src=(format!("/assets/platforms/{}.svg", platform)) - alt=(platform_name) title=(platform_name) width="24" height="24"; + span class=(format!("platform-icon icon-{platform}")) title=(platform_name) {} } } h6 { diff --git a/crates/web/src/handlers/report.rs b/crates/web/src/handlers/report.rs index 7f795b5..ef03e22 100644 --- a/crates/web/src/handlers/report.rs +++ b/crates/web/src/handlers/report.rs @@ -664,8 +664,8 @@ async fn render_report( Ok(html! { (DOCTYPE) - html { - head lang="en" { + html lang="en" { + head { meta charset="utf-8"; title { (project_short_name) " • Progress Report" } (header()) @@ -710,9 +710,19 @@ async fn render_report( details class="dropdown" { summary {} ul dir="rtl" { - li { a href=(project_history_path) { "History" } } + li { + a href=(project_history_path) { + "History " + span .icon-chart-line { " " } + } + } @if can_manage { - li { a href=(project_manage_path) { "Manage" } } + li { + a href=(project_manage_path) { + "Manage " + span .icon-cog { " " } + } + } } } } @@ -764,20 +774,24 @@ async fn render_report( div role="group" { @if let Some(prev_commit_path) = prev_commit_path { a role="button" class="outline secondary" href=(prev_commit_path) { - "Previous" + span .icon-left-open {} + " Previous" } } @else { button disabled class="outline secondary" { - "Previous" + span .icon-left-open {} + " Previous" } } @if let Some(next_commit_path) = next_commit_path { a role="button" class="outline secondary" href=(next_commit_path) { - "Next" + "Next " + span .icon-right-open {} } } @else { button disabled class="outline secondary" { - "Next" + "Next " + span .icon-right-open {} } } @if let Some(latest_commit_path) = latest_commit_path { @@ -899,8 +913,8 @@ async fn render_history( Ok(html! { (DOCTYPE) - html { - head lang="en" { + html lang="en" { + head { meta charset="utf-8"; title { (project_short_name) " • Progress History" } (header()) diff --git a/css/main.scss b/css/main.scss index cf180e4..3e77a47 100644 --- a/css/main.scss +++ b/css/main.scss @@ -109,10 +109,6 @@ $breakpoints: ( --pico-code-kbd-background-color: #333; --progress-background-color: #{$slate-800}; --progress-stripe-color: rgba(255, 255, 255, 0.15); - - .platform-icon { - filter: invert(1); - } } [data-theme=dark] { @@ -125,6 +121,50 @@ $breakpoints: ( } } +@font-face { + font-family: 'icons'; + src: url('../assets/icons.woff2') format('woff2'); + font-weight: normal; + font-style: normal; + font-display: block; +} + +[class^="icon-"], [class*=" icon-"] { + font-size: 0.9em; + line-height: 1em; + + &:before { + display: inline-block; + width: 1em; + font-family: "icons"; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-decoration: inherit; + text-align: center; + text-transform: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } +} + +.icon-history:before { content: '\e800'; } +.icon-cog:before { content: '\e801'; } +.icon-theme-light-dark:before { content: '\e802'; } +.icon-chart-line:before { content: '\e803'; } +.icon-github-circled:before { content: '\e804'; } +.icon-left-open:before { content: '\e805'; } +.icon-right-open:before { content: '\e806'; } + +.icon-gc:before { content: '\ea00'; } +.icon-wii:before { content: '\ea01'; } +.icon-n64:before { content: '\ea02'; } +.icon-gba:before { content: '\ea03'; } +.icon-nds:before { content: '\ea04'; } +.icon-switch:before { content: '\ea05'; } +.icon-ps:before { content: '\ea06'; } +.icon-ps2:before { content: '\ea07'; } + // Override the tooltip component [data-tooltip]:not(a, button, input) { border-bottom: none; @@ -157,6 +197,12 @@ nav { } } +#theme-toggle { + font-size: 1.33rem; + vertical-align: middle; + text-decoration: none; +} + @keyframes progress-stripes { 0% { background-position: 0 0 @@ -273,8 +319,7 @@ $unit-size: 0.75rem; } .platform-icon { - width: 1.5rem; - height: 1.5rem; + font-size: 1.5rem; } }