Implement a serializer for user preferences (#336)

This commit is contained in:
Jeidnx 2024-12-02 17:29:57 +01:00 committed by GitHub
parent e4fc22cf90
commit d7ec07cd0d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 70 additions and 5 deletions

13
Cargo.lock generated
View file

@ -1384,6 +1384,7 @@ dependencies = [
"serde",
"serde_json",
"serde_json_path",
"serde_urlencoded",
"serde_yaml",
"tegen",
"time",
@ -1797,6 +1798,18 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
dependencies = [
"form_urlencoded",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "serde_yaml"
version = "0.9.34+deprecated"

View file

@ -50,6 +50,7 @@ async-recursion = "1.1.1"
common-words-all = { version = "0.0.2", default-features = false, features = ["english", "one"] }
hyper-rustls = { version = "0.24.2", features = [ "http2" ] }
tegen = "0.1.4"
serde_urlencoded = "0.7.1"
[dev-dependencies]

View file

@ -13,7 +13,7 @@ use once_cell::sync::Lazy;
use regex::Regex;
use rinja::Template;
use rust_embed::RustEmbed;
use serde::Serialize;
use serde::{Serialize, Serializer};
use serde_json::Value;
use serde_json_path::{JsonPath, JsonPathExt};
use std::collections::{HashMap, HashSet};
@ -601,8 +601,9 @@ pub struct Params {
pub before: Option<String>,
}
#[derive(Default)]
#[derive(Default, Serialize)]
pub struct Preferences {
#[serde(skip)]
pub available_themes: Vec<String>,
pub theme: String,
pub front_page: String,
@ -620,12 +621,21 @@ pub struct Preferences {
pub disable_visit_reddit_confirmation: String,
pub comment_sort: String,
pub post_sort: String,
#[serde(serialize_with = "serialize_vec_with_plus")]
pub subscriptions: Vec<String>,
#[serde(serialize_with = "serialize_vec_with_plus")]
pub filters: Vec<String>,
pub hide_awards: String,
pub hide_score: String,
}
fn serialize_vec_with_plus<S>(vec: &Vec<String>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&vec.join("+"))
}
#[derive(RustEmbed)]
#[folder = "static/themes/"]
#[include = "*.css"]
@ -665,6 +675,10 @@ impl Preferences {
hide_score: setting(req, "hide_score"),
}
}
pub fn to_urlencoded(&self) -> Result<String, String> {
serde_urlencoded::to_string(self).map_err(|e| e.to_string())
}
}
/// Gets a `HashSet` of filters from the cookie in the given `Request`.
@ -1277,7 +1291,7 @@ pub fn get_post_url(post: &Post) -> String {
#[cfg(test)]
mod tests {
use super::{format_num, format_url, rewrite_urls};
use super::{format_num, format_url, rewrite_urls, Preferences};
#[test]
fn format_num_works() {
@ -1344,6 +1358,35 @@ mod tests {
assert_eq!(format_url("nsfw"), "");
assert_eq!(format_url("spoiler"), "");
}
#[test]
fn serialize_prefs() {
let prefs = Preferences {
available_themes: vec![],
theme: "laserwave".to_owned(),
front_page: "default".to_owned(),
layout: "compact".to_owned(),
wide: "on".to_owned(),
blur_spoiler: "on".to_owned(),
show_nsfw: "off".to_owned(),
blur_nsfw: "on".to_owned(),
hide_hls_notification: "off".to_owned(),
video_quality: "best".to_owned(),
hide_sidebar_and_summary: "off".to_owned(),
use_hls: "on".to_owned(),
autoplay_videos: "on".to_owned(),
fixed_navbar: "on".to_owned(),
disable_visit_reddit_confirmation: "on".to_owned(),
comment_sort: "confidence".to_owned(),
post_sort: "top".to_owned(),
subscriptions: vec!["memes".to_owned(), "mildlyinteresting".to_owned()],
filters: vec![],
hide_awards: "off".to_owned(),
hide_score: "off".to_owned(),
};
let urlencoded = serde_urlencoded::to_string(prefs).expect("Failed to serialize Prefs");
assert_eq!(urlencoded, "theme=laserwave&front_page=default&layout=compact&wide=on&blur_spoiler=on&show_nsfw=off&blur_nsfw=on&hide_hls_notification=off&video_quality=best&hide_sidebar_and_summary=off&use_hls=on&autoplay_videos=on&fixed_navbar=on&disable_visit_reddit_confirmation=on&comment_sort=confidence&post_sort=top&subscriptions=memes%2Bmildlyinteresting&filters=&hide_awards=off&hide_score=off")
}
}
#[test]

View file

@ -161,8 +161,16 @@
{% endif %}
<div id="settings_note">
<p><b>Note:</b> settings and subscriptions are saved in browser cookies. Clearing your cookies will reset them.</p><br>
<p>You can restore your current settings and subscriptions after clearing your cookies using <a href="/settings/restore/?theme={{ prefs.theme }}&front_page={{ prefs.front_page }}&layout={{ prefs.layout }}&wide={{ prefs.wide }}&post_sort={{ prefs.post_sort }}&comment_sort={{ prefs.comment_sort }}&show_nsfw={{ prefs.show_nsfw }}&use_hls={{ prefs.use_hls }}&hide_hls_notification={{ prefs.hide_hls_notification }}&hide_awards={{ prefs.hide_awards }}&fixed_navbar={{ prefs.fixed_navbar }}&subscriptions={{ prefs.subscriptions.join("%2B") }}&filters={{ prefs.filters.join("%2B") }}">this link</a>.</p>
<p><b>Note:</b> settings and subscriptions are saved in browser cookies. Clearing your cookies will reset them.</p>
<br>
{% match prefs.to_urlencoded() %}
{% when Ok with (encoded_prefs) %}
<p>You can restore your current settings and subscriptions after clearing your cookies using <a
href="/settings/restore/?{{ encoded_prefs }}">this link</a>.</p>
{% when Err with (err) %}
<p>There was an error creating your restore link: {{ err }}</p>
<p>Please report this issue</p>
{% endmatch %}
</div>
</div>