mascots #6
19
src/main.rs
19
src/main.rs
@ -26,7 +26,7 @@ use client::{canonical_path, proxy};
|
||||
use log::info;
|
||||
use once_cell::sync::Lazy;
|
||||
use server::RequestExt;
|
||||
use utils::{error, redirect, ThemeAssets};
|
||||
use utils::{error, redirect, ThemeAssets, MascotAssets};
|
||||
|
||||
use crate::client::OAUTH_CLIENT;
|
||||
|
||||
@ -111,6 +111,20 @@ async fn style() -> Result<Response<Body>, String> {
|
||||
)
|
||||
}
|
||||
|
||||
/// Serve mascot
|
||||
async fn mascot_image(req: Request<Body>) -> Result<Response<Body>, String> {
|
||||
let res = MascotAssets::get(&req.param("name").unwrap())
|
||||
.unwrap_or(MascotAssets::get("redsunlib.png").unwrap());
|
||||
Ok(
|
||||
Response::builder()
|
||||
.status(200)
|
||||
.header("content-type", "image/png")
|
||||
.header("Cache-Control", "public, max-age=1209600, s-maxage=86400")
|
||||
.body(res.data.into())
|
||||
.unwrap_or_default(),
|
||||
)
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// Load environment variables
|
||||
@ -265,6 +279,9 @@ async fn main() {
|
||||
app.at("/settings/restore").get(|r| settings::restore(r).boxed());
|
||||
app.at("/settings/update").get(|r| settings::update(r).boxed());
|
||||
|
||||
// Mascots
|
||||
app.at("/mascot/:name").get(|r| mascot_image(r).boxed());
|
||||
|
||||
// Subreddit services
|
||||
app
|
||||
.at("/r/:sub")
|
||||
|
@ -19,8 +19,9 @@ struct SettingsTemplate {
|
||||
|
||||
// CONSTANTS
|
||||
|
||||
const PREFS: [&str; 16] = [
|
||||
const PREFS: [&str; 17] = [
|
||||
"theme",
|
||||
"mascot",
|
||||
"front_page",
|
||||
"layout",
|
||||
"wide",
|
||||
|
16
src/utils.rs
16
src/utils.rs
@ -570,7 +570,9 @@ pub struct Params {
|
||||
#[derive(Default)]
|
||||
pub struct Preferences {
|
||||
pub available_themes: Vec<String>,
|
||||
pub available_mascots: Vec<String>,
|
||||
pub theme: String,
|
||||
pub mascot: String,
|
||||
pub front_page: String,
|
||||
pub layout: String,
|
||||
pub wide: String,
|
||||
@ -595,6 +597,11 @@ pub struct Preferences {
|
||||
#[include = "*.css"]
|
||||
pub struct ThemeAssets;
|
||||
|
||||
#[derive(RustEmbed)]
|
||||
#[folder = "static/mascots/"]
|
||||
#[include = "*.png"]
|
||||
pub struct MascotAssets;
|
||||
|
||||
impl Preferences {
|
||||
// Build preferences from cookies
|
||||
pub fn new(req: &Request<Body>) -> Self {
|
||||
@ -605,9 +612,18 @@ impl Preferences {
|
||||
let chunks: Vec<&str> = file.as_ref().split(".css").collect();
|
||||
themes.push(chunks[0].to_owned());
|
||||
}
|
||||
// Read available mascot names from embedded png files.
|
||||
// Always make default "none" option available.
|
||||
let mut mascots = vec!["none".to_string()];
|
||||
for file in MascotAssets::iter() {
|
||||
let chunks: Vec<&str> = file.as_ref().split(".png").collect();
|
||||
mascots.push(chunks[0].to_owned());
|
||||
}
|
||||
Self {
|
||||
available_themes: themes,
|
||||
available_mascots: mascots,
|
||||
theme: setting(req, "theme"),
|
||||
mascot: setting(req, "mascot"),
|
||||
front_page: setting(req, "front_page"),
|
||||
layout: setting(req, "layout"),
|
||||
wide: setting(req, "wide"),
|
||||
|
BIN
static/mascots/BoymoderBlahaj.png
Normal file
BIN
static/mascots/BoymoderBlahaj.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.5 KiB |
BIN
static/mascots/redsunlib.png
Normal file
BIN
static/mascots/redsunlib.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
@ -1774,3 +1774,16 @@ td, th {
|
||||
background-color: var(--accent);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.mascot {
|
||||
position: fixed;
|
||||
right: 1em;
|
||||
bottom: 1em;
|
||||
pointer-events: none;
|
||||
opacity: 0.5;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.mascot > img {
|
||||
max-width: 20em;
|
||||
}
|
@ -60,6 +60,13 @@
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{% if prefs.mascot != "none" && prefs.mascot != "" %}
|
||||
<!-- MASCOT -->
|
||||
<div class="mascot">
|
||||
<img src="/mascot/{{ prefs.mascot }}.png">
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- MAIN CONTENT -->
|
||||
{% block body %}
|
||||
<main>
|
||||
|
@ -19,6 +19,12 @@
|
||||
{% call utils::options(prefs.theme, prefs.available_themes, "system") %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="prefs-group">
|
||||
<label for="mascot">Mascot:</label>
|
||||
<select name="mascot" id="mascot">
|
||||
{% call utils::options(prefs.mascot, prefs.available_mascots, "system") %}
|
||||
</select>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Interface</legend>
|
||||
|
Loading…
Reference in New Issue
Block a user