Generate URL to restore settings, including subscriptions. Closes #89 (#116)

* Start recursive comments

* Update comment.html

* Fix move error

* Comment improvements

* Fix merge

* Remove extra endif from post.html

* Fix post.html

* Restore setting from link

* Tweak settings page

Co-authored-by: spikecodes <19519553+spikecodes@users.noreply.github.com>
This commit is contained in:
robrobinbin 2021-02-13 21:55:23 +01:00 committed by GitHub
parent ff8685ae4c
commit 93cfc713c6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 76 additions and 46 deletions

View file

@ -166,6 +166,7 @@ async fn main() -> tide::Result<()> {
// Configure settings // Configure settings
app.at("/settings/").get(settings::get).post(settings::set); app.at("/settings/").get(settings::get).post(settings::set);
app.at("/settings/restore/").get(settings::restore);
// Subreddit services // Subreddit services
// See posts and info about subreddit // See posts and info about subreddit

View file

@ -12,6 +12,7 @@ struct SettingsTemplate {
} }
#[derive(serde::Deserialize, Default)] #[derive(serde::Deserialize, Default)]
#[serde(default)]
pub struct SettingsForm { pub struct SettingsForm {
theme: Option<String>, theme: Option<String>,
front_page: Option<String>, front_page: Option<String>,
@ -19,6 +20,8 @@ pub struct SettingsForm {
wide: Option<String>, wide: Option<String>,
comment_sort: Option<String>, comment_sort: Option<String>,
show_nsfw: Option<String>, show_nsfw: Option<String>,
redirect: Option<String>,
subscriptions: Option<String>,
} }
// FUNCTIONS // FUNCTIONS
@ -56,3 +59,39 @@ pub async fn set(mut req: Request<()>) -> tide::Result {
Ok(res) Ok(res)
} }
// Set cookies using response "Set-Cookie" header
pub async fn restore(req: Request<()>) -> tide::Result {
let form: SettingsForm = req.query()?;
let path = match form.redirect {
Some(value) => format!("/{}/", value),
None => "/".to_string()
};
let mut res = Response::builder(302)
.content_type("text/html")
.header("Location", path.to_owned())
.body(format!("Redirecting to <a href=\"{0}\">{0}</a>...", path))
.build();
let names = vec!["theme", "front_page", "layout", "wide", "comment_sort", "show_nsfw", "subscriptions"];
let values = vec![form.theme, form.front_page, form.layout, form.wide, form.comment_sort, form.show_nsfw, form.subscriptions];
for (i, name) in names.iter().enumerate() {
match values.get(i) {
Some(value) => res.insert_cookie(
Cookie::build(name.to_owned(), value.to_owned().unwrap_or_default())
.path("/")
.http_only(true)
.expires(OffsetDateTime::now_utc() + Duration::weeks(52))
.finish(),
),
None => res.remove_cookie(Cookie::named(name.to_owned())),
};
}
Ok(res)
}

View file

@ -87,7 +87,7 @@ pub async fn subscriptions(req: Request<()>) -> tide::Result {
let query = req.url().query().unwrap_or_default().to_string(); let query = req.url().query().unwrap_or_default().to_string();
let action: Vec<String> = req.url().path().split('/').map(String::from).collect(); let action: Vec<String> = req.url().path().split('/').map(String::from).collect();
let mut sub_list = prefs(req).subs; let mut sub_list = prefs(req).subscriptions;
// Find each subreddit name (separated by '+') in sub parameter // Find each subreddit name (separated by '+') in sub parameter
for part in sub.split('+') { for part in sub.split('+') {

View file

@ -146,7 +146,7 @@ pub struct Preferences {
pub wide: String, pub wide: String,
pub show_nsfw: String, pub show_nsfw: String,
pub comment_sort: String, pub comment_sort: String,
pub subs: Vec<String>, pub subscriptions: Vec<String>,
} }
// //
@ -162,7 +162,7 @@ pub fn prefs(req: Request<()>) -> Preferences {
wide: cookie(&req, "wide"), wide: cookie(&req, "wide"),
show_nsfw: cookie(&req, "show_nsfw"), show_nsfw: cookie(&req, "show_nsfw"),
comment_sort: cookie(&req, "comment_sort"), comment_sort: cookie(&req, "comment_sort"),
subs: cookie(&req, "subscriptions") subscriptions: cookie(&req, "subscriptions")
.split('+') .split('+')
.map(String::from) .map(String::from)
.filter(|s| !s.is_empty()) .filter(|s| !s.is_empty())

View file

@ -958,19 +958,21 @@ a.search_subreddit:hover {
/* Settings */ /* Settings */
#settings, #settings > form { #settings {
display: flex; max-width: 450px;
flex-direction: column;
align-items: center;
} }
#settings_note { #settings_note {
font-size: 14px; font-size: 14px;
max-width: 300px;
margin-top: 10px; margin-top: 10px;
opacity: 0.75; opacity: 0.75;
} }
#settings_note a {
color: var(--accent);
}
.prefs { .prefs {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -979,6 +981,7 @@ a.search_subreddit:hover {
padding: 20px; padding: 20px;
background: var(--post); background: var(--post);
border-radius: 5px; border-radius: 5px;
margin-bottom: 20px;
} }
.prefs > div { .prefs > div {
@ -987,10 +990,7 @@ a.search_subreddit:hover {
width: 100%; width: 100%;
height: 35px; height: 35px;
align-items: center; align-items: center;
} margin-top: 10px;
.prefs > div:not(:last-of-type) {
margin-bottom: 10px;
} }
.prefs select { .prefs select {
@ -1017,22 +1017,6 @@ input[type="submit"] {
-moz-appearance: none; -moz-appearance: none;
} }
#settings_subs {
list-style: none;
padding: 0;
}
#settings_subs > li {
display: flex;
margin: 10px 0;
}
#settings_subs > li:last-of-type { margin-bottom: 0; }
#settings_subs > li > span {
padding: 10px 0;
margin-right: auto;
}
#settings_subs .unsubscribe { #settings_subs .unsubscribe {
margin-left: 30px; margin-left: 30px;
} }
@ -1176,6 +1160,10 @@ td, th {
right: 10px; right: 10px;
min-width: auto; min-width: auto;
} }
#settings {
max-width: unset;
}
aside, #subreddit, #user { aside, #subreddit, #user {
margin: 0; margin: 0;

View file

@ -46,25 +46,27 @@
<label for="show_nsfw">Show NSFW posts:</label> <label for="show_nsfw">Show NSFW posts:</label>
<input type="checkbox" name="show_nsfw" {% if prefs.show_nsfw == "on" %}checked{% endif %}> <input type="checkbox" name="show_nsfw" {% if prefs.show_nsfw == "on" %}checked{% endif %}>
</div> </div>
<input id="save" type="submit" value="Save">
</div> </div>
<p id="settings_note"><b>Note:</b> settings are saved in browser cookies. Clearing your cookie data will reset them.</p>
<input id="save" type="submit" value="Save">
</form> </form>
{% if prefs.subs.len() > 0 %} {% if prefs.subscriptions.len() > 0 %}
<aside class="prefs"> <div class="prefs" id="settings_subs">
<p>Subscribed Subreddits</p> <p>Subscribed Subreddits</p>
<ul id="settings_subs"> {% for sub in prefs.subscriptions %}
{% for sub in prefs.subs %} <div>
<li> <span>{{ sub }}</span>
<span>{{ sub }}</span> <form action="/r/{{ sub }}/unsubscribe/?redirect=settings" method="POST">
<form action="/r/{{ sub }}/unsubscribe/?redirect=settings" method="POST"> <button class="unsubscribe">Unsubscribe</button>
<button class="unsubscribe">Unsubscribe</button> </form>
</form> </div>
</li> {% endfor %}
{% endfor %} </div>
</ul>
</aside>
{% endif %} {% 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 }}&comment_sort={{ prefs.comment_sort }}&show_nsfw={{ prefs.show_nsfw }}&subscriptions={{ prefs.subscriptions.join("%2B") }}">this link</a>.</p>
</div>
</div> </div>
{% endblock %} {% endblock %}

View file

@ -85,7 +85,7 @@
<div>{{ sub.active }}</div> <div>{{ sub.active }}</div>
</div> </div>
<div id="sub_subscription"> <div id="sub_subscription">
{% if prefs.subs.contains(sub.name) %} {% if prefs.subscriptions.contains(sub.name) %}
<form action="/r/{{ sub.name }}/unsubscribe/" method="POST"> <form action="/r/{{ sub.name }}/unsubscribe/" method="POST">
<button class="unsubscribe">Unsubscribe</button> <button class="unsubscribe">Unsubscribe</button>
</form> </form>

View file

@ -41,7 +41,7 @@
{%- endmacro %} {%- endmacro %}
{% macro sub_list(current) -%} {% macro sub_list(current) -%}
{% if prefs.subs.len() > 0 %} {% if prefs.subscriptions.len() > 0 %}
<details id="feeds"> <details id="feeds">
<summary>Feeds</summary> <summary>Feeds</summary>
<div id="feed_list"> <div id="feed_list">
@ -50,7 +50,7 @@
<a href="/r/popular">Popular</a> <a href="/r/popular">Popular</a>
<a href="/r/all">All</a> <a href="/r/all">All</a>
<p>REDDIT FEEDS</p> <p>REDDIT FEEDS</p>
{% for sub in prefs.subs %} {% for sub in prefs.subscriptions %}
<a href="/r/{{ sub }}" {% if sub == current %}class="selected"{% endif %}>{{ sub }}</a> <a href="/r/{{ sub }}" {% if sub == current %}class="selected"{% endif %}>{{ sub }}</a>
{% endfor %} {% endfor %}
</div> </div>