Compare commits

...

2 Commits

Author SHA1 Message Date
4c6a71171b add boymoder 2024-06-17 22:29:58 +12:00
846377b586 implement mascots 2024-06-17 22:29:52 +12:00
8 changed files with 63 additions and 2 deletions

View File

@ -26,7 +26,7 @@ use client::{canonical_path, proxy};
use log::info; use log::info;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use server::RequestExt; use server::RequestExt;
use utils::{error, redirect, ThemeAssets}; use utils::{error, redirect, ThemeAssets, MascotAssets};
use crate::client::OAUTH_CLIENT; 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] #[tokio::main]
async fn main() { async fn main() {
// Load environment variables // Load environment variables
@ -265,6 +279,9 @@ async fn main() {
app.at("/settings/restore").get(|r| settings::restore(r).boxed()); app.at("/settings/restore").get(|r| settings::restore(r).boxed());
app.at("/settings/update").get(|r| settings::update(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 // Subreddit services
app app
.at("/r/:sub") .at("/r/:sub")

View File

@ -19,8 +19,9 @@ struct SettingsTemplate {
// CONSTANTS // CONSTANTS
const PREFS: [&str; 16] = [ const PREFS: [&str; 17] = [
"theme", "theme",
"mascot",
"front_page", "front_page",
"layout", "layout",
"wide", "wide",

View File

@ -570,7 +570,9 @@ pub struct Params {
#[derive(Default)] #[derive(Default)]
pub struct Preferences { pub struct Preferences {
pub available_themes: Vec<String>, pub available_themes: Vec<String>,
pub available_mascots: Vec<String>,
pub theme: String, pub theme: String,
pub mascot: String,
pub front_page: String, pub front_page: String,
pub layout: String, pub layout: String,
pub wide: String, pub wide: String,
@ -595,6 +597,11 @@ pub struct Preferences {
#[include = "*.css"] #[include = "*.css"]
pub struct ThemeAssets; pub struct ThemeAssets;
#[derive(RustEmbed)]
#[folder = "static/mascots/"]
#[include = "*.png"]
pub struct MascotAssets;
impl Preferences { impl Preferences {
// Build preferences from cookies // Build preferences from cookies
pub fn new(req: &Request<Body>) -> Self { pub fn new(req: &Request<Body>) -> Self {
@ -605,9 +612,18 @@ impl Preferences {
let chunks: Vec<&str> = file.as_ref().split(".css").collect(); let chunks: Vec<&str> = file.as_ref().split(".css").collect();
themes.push(chunks[0].to_owned()); 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 { Self {
available_themes: themes, available_themes: themes,
available_mascots: mascots,
theme: setting(req, "theme"), theme: setting(req, "theme"),
mascot: setting(req, "mascot"),
front_page: setting(req, "front_page"), front_page: setting(req, "front_page"),
layout: setting(req, "layout"), layout: setting(req, "layout"),
wide: setting(req, "wide"), wide: setting(req, "wide"),

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@ -1774,3 +1774,17 @@ td, th {
background-color: var(--accent); background-color: var(--accent);
color: var(--text); color: var(--text);
} }
.mascot {
position: fixed;
right: 1em;
bottom: 1em;
left: 85%;
pointer-events: none;
opacity: 0.5;
z-index: 1;
}
.mascot > img {
max-width: 20em;
}

View File

@ -59,6 +59,13 @@
</a> </a>
</div> </div>
</nav> </nav>
{% if prefs.mascot != "none" && prefs.mascot != "" %}
<!-- MASCOT -->
<div class="mascot">
<img src="/mascot/{{ prefs.mascot }}.png">
</div>
{% endif %}
<!-- MAIN CONTENT --> <!-- MAIN CONTENT -->
{% block body %} {% block body %}

View File

@ -19,6 +19,12 @@
{% call utils::options(prefs.theme, prefs.available_themes, "system") %} {% call utils::options(prefs.theme, prefs.available_themes, "system") %}
</select> </select>
</div> </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>
<fieldset> <fieldset>
<legend>Interface</legend> <legend>Interface</legend>