Compare commits
3 commits
29addcaf9a
...
82fc7fc10f
Author | SHA1 | Date | |
---|---|---|---|
82fc7fc10f | |||
601f239d76 | |||
fccbef27ee |
|
@ -90,6 +90,13 @@ impl InstanceSettings {
|
|||
None => Ok(UserPreferences::default())
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a UserPreferences instance from a list of weights.
|
||||
///
|
||||
/// This is shorthand for [`UserPreferences::from_preferences`].
|
||||
pub fn create_preferences(prefs: &[u8]) -> UserPreferences {
|
||||
UserPreferences::from_preferences(prefs)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for InstanceSettings {
|
||||
|
|
|
@ -25,6 +25,7 @@ use data_encoding::BASE32_NOPAD;
|
|||
/// Because parsing a prefstring must be done in relation to an [`InstanceSettings`], the
|
||||
/// `UserPreferences` struct shares a lifetime with the settings it was created with.
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum UserPreferences {
|
||||
V0(v0::UserPreferencesV0)
|
||||
}
|
||||
|
@ -140,3 +141,15 @@ impl Preference for UserPreferences {
|
|||
UserPreferences::V0(UserPreferencesV0::from_preferences(prefs))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_prefstring_bytes_round_trip() {
|
||||
let prefs = UserPreferences::default();
|
||||
let bytes = prefs.as_prefstring_bytes();
|
||||
assert_eq!(prefs, UserPreferences::from_prefstring_bytes(&bytes).unwrap());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ impl Preference for UserPreferencesV0 {
|
|||
defaults_byte |= 0b10000000;
|
||||
}
|
||||
defaults_byte |= self.default_weight & 0b01111111;
|
||||
vec![defaults_byte]
|
||||
vec![0, defaults_byte]
|
||||
.into_iter()
|
||||
.chain(self.commands.iter().map(|cmd| cmd.into()))
|
||||
.collect()
|
||||
|
@ -606,4 +606,19 @@ mod tests {
|
|||
let prefs = UserPreferencesV0::from_preferences(&pref_vals);
|
||||
assert_eq!(prefs, expected_prefs);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_as_prefstring_bytes() {
|
||||
let prefs = UserPreferencesV0::default();
|
||||
let expected_bytes = vec![0 , 0b10000001];
|
||||
assert_eq!(expected_bytes, prefs.as_prefstring_bytes());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_prefstring_bytes() {
|
||||
let bytes = vec![0 , 0b10000001];
|
||||
let prefs = UserPreferencesV0::from_prefstring_bytes(&bytes).unwrap();
|
||||
let expected_prefs = UserPreferencesV0::default();
|
||||
assert_eq!(expected_prefs, prefs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,5 +8,6 @@ edition = "2021"
|
|||
[dependencies]
|
||||
pronouns_today = {path = ".."}
|
||||
actix-web = "3"
|
||||
log = "0.4.14"
|
||||
env_logger = "0.9.0"
|
||||
log = "0.4"
|
||||
env_logger = "0.9"
|
||||
askama = "0.10"
|
||||
|
|
108
web/src/main.rs
108
web/src/main.rs
|
@ -1,48 +1,100 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use actix_web::error::ErrorBadRequest;
|
||||
use actix_web::http::header::LOCATION;
|
||||
use actix_web::middleware::Logger;
|
||||
use actix_web::{App, HttpServer, Responder, get, web, Result};
|
||||
use pronouns_today::InstanceSettings;
|
||||
use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder, Result};
|
||||
use askama::Template;
|
||||
use pronouns_today::user_preferences::Preference;
|
||||
use pronouns_today::{InstanceSettings, Pronoun};
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "index.html")]
|
||||
struct IndexTemplate<'a> {
|
||||
short: String,
|
||||
pronouns: Vec<(usize, &'a Pronoun)>,
|
||||
}
|
||||
|
||||
fn render_page(pronoun: &Pronoun, settings: &InstanceSettings) -> String {
|
||||
IndexTemplate {
|
||||
short: pronoun.render_threeform(),
|
||||
pronouns: settings.pronoun_list.iter().enumerate().collect(),
|
||||
}
|
||||
.render()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[get("/")]
|
||||
async fn default(settings: web::Data<InstanceSettings>) -> Result<impl Responder> {
|
||||
eprintln!("default");
|
||||
let pronouns = settings.select_pronouns(None, None).map_err(ErrorBadRequest)?;
|
||||
Ok(format!(include_str!("../static/pronouns.html"), pronouns.render_threeform()))
|
||||
eprintln!("default");
|
||||
let pronoun = settings
|
||||
.select_pronouns(None, None)
|
||||
.map_err(ErrorBadRequest)?;
|
||||
Ok(HttpResponse::Ok()
|
||||
.content_type("text/html")
|
||||
.body(render_page(&pronoun, &settings)))
|
||||
}
|
||||
|
||||
#[post("/")]
|
||||
async fn create_link(
|
||||
settings: web::Data<InstanceSettings>,
|
||||
form: web::Form<HashMap<usize, u8>>,
|
||||
) -> Result<impl Responder> {
|
||||
eprintln!("create {:?}", form);
|
||||
let weights: Vec<_> = (0..settings.pronoun_list.len())
|
||||
.map(|i| form.get(&i).map(|v| *v).unwrap_or(0))
|
||||
.collect();
|
||||
let prefs = InstanceSettings::create_preferences(&weights);
|
||||
eprintln!("prefs: {:?}", prefs);
|
||||
let pref_string = prefs.as_prefstring();
|
||||
eprintln!("prefstring: {}", pref_string);
|
||||
Ok(HttpResponse::SeeOther()
|
||||
.header(LOCATION, format!("/{}", pref_string))
|
||||
.finish())
|
||||
}
|
||||
|
||||
#[get("/{prefs}")]
|
||||
async fn only_prefs(
|
||||
web::Path(prefs): web::Path<String>,
|
||||
settings: web::Data<InstanceSettings>,
|
||||
web::Path(prefs): web::Path<String>,
|
||||
settings: web::Data<InstanceSettings>,
|
||||
) -> Result<impl Responder> {
|
||||
eprintln!("prefs");
|
||||
let pronouns = settings.select_pronouns(None, Some(&prefs)).map_err(ErrorBadRequest)?;
|
||||
Ok(format!(include_str!("../static/pronouns.html"), pronouns.render_threeform()))
|
||||
eprintln!("prefs {}", prefs);
|
||||
let pronoun = settings
|
||||
.select_pronouns(None, Some(&prefs))
|
||||
.map_err(ErrorBadRequest)?;
|
||||
Ok(HttpResponse::Ok()
|
||||
.content_type("text/html")
|
||||
.body(render_page(&pronoun, &settings)))
|
||||
}
|
||||
|
||||
#[get("/{name}/{prefs}")]
|
||||
async fn prefs_and_name(
|
||||
web::Path((name, prefs)): web::Path<(String, String)>,
|
||||
settings: web::Data<InstanceSettings>,
|
||||
web::Path((name, prefs)): web::Path<(String, String)>,
|
||||
settings: web::Data<InstanceSettings>,
|
||||
) -> Result<impl Responder> {
|
||||
eprintln!("prefs+name");
|
||||
let pronouns = settings.select_pronouns(Some(&name), Some(&prefs)).map_err(ErrorBadRequest)?;
|
||||
Ok(format!(include_str!("../static/pronouns.html"), pronouns.render_threeform()))
|
||||
eprintln!("prefs+name");
|
||||
let pronoun = settings
|
||||
.select_pronouns(Some(&name), Some(&prefs))
|
||||
.map_err(ErrorBadRequest)?;
|
||||
Ok(HttpResponse::Ok()
|
||||
.content_type("text/html")
|
||||
.body(render_page(&pronoun, &settings)))
|
||||
}
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
env_logger::init();
|
||||
HttpServer::new(|| {
|
||||
let logger = Logger::default();
|
||||
App::new()
|
||||
.data(InstanceSettings::default())
|
||||
.wrap(logger)
|
||||
.service(prefs_and_name)
|
||||
.service(only_prefs)
|
||||
.service(default)
|
||||
})
|
||||
.bind("127.0.0.1:8080")?
|
||||
.run()
|
||||
.await
|
||||
env_logger::init();
|
||||
HttpServer::new(|| {
|
||||
let logger = Logger::default();
|
||||
App::new()
|
||||
.data(InstanceSettings::default())
|
||||
.wrap(logger)
|
||||
.service(prefs_and_name)
|
||||
.service(only_prefs)
|
||||
.service(default)
|
||||
.service(create_link)
|
||||
})
|
||||
.bind("127.0.0.1:8080")?
|
||||
.run()
|
||||
.await
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>My Pronouns Today</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>My pronouns today are: {}</h1>
|
||||
</body>
|
||||
</html>
|
28
web/templates/index.html
Normal file
28
web/templates/index.html
Normal file
|
@ -0,0 +1,28 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>My Pronouns Today</title>
|
||||
<style>
|
||||
#form {
|
||||
display: none;
|
||||
}
|
||||
:checked + #form {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>My pronouns today are: {{ short }}</h1>
|
||||
|
||||
<label for="form-toggle">Create your own custom link!</label>
|
||||
<input type="checkbox" id="form-toggle" style="display: none;"/>
|
||||
<div id="form">
|
||||
<form action="/" method="post">
|
||||
{% for item in pronouns %}
|
||||
<label for="{{ item.0 }}">{{ item.1.render_threeform() }}</label>
|
||||
<input type="number" id="{{ item.0 }}" name="{{ item.0 }}" value="1"/><br/>
|
||||
{% endfor %}
|
||||
<input type="submit" value="Create!">
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in a new issue