Redesign menu items

This commit is contained in:
Bat 2018-09-03 14:59:02 +01:00
parent 1621915ee8
commit 3013eec579
12 changed files with 84 additions and 45 deletions

View file

@ -24,14 +24,14 @@ use routes::Page;
#[get("/~/<name>?<page>", rank = 2)] #[get("/~/<name>?<page>", rank = 2)]
fn paginated_details(name: String, conn: DbConn, user: Option<User>, page: Page) -> Template { fn paginated_details(name: String, conn: DbConn, user: Option<User>, page: Page) -> Template {
may_fail!(user, Blog::find_by_fqn(&*conn, name), "Requested blog couldn't be found", |blog| { may_fail!(user.map(|u| u.to_json(&*conn)), Blog::find_by_fqn(&*conn, name), "Requested blog couldn't be found", |blog| {
let posts = Post::blog_page(&*conn, &blog, page.limits()); let posts = Post::blog_page(&*conn, &blog, page.limits());
let articles = Post::get_for_blog(&*conn, &blog); let articles = Post::get_for_blog(&*conn, &blog);
let authors = &blog.list_authors(&*conn); let authors = &blog.list_authors(&*conn);
Template::render("blogs/details", json!({ Template::render("blogs/details", json!({
"blog": &blog.to_json(&*conn), "blog": &blog.to_json(&*conn),
"account": user, "account": user.clone().map(|u| u.to_json(&*conn)),
"is_author": user.map(|x| x.is_author_in(&*conn, blog.clone())), "is_author": user.map(|x| x.is_author_in(&*conn, blog.clone())),
"posts": posts.into_iter().map(|p| p.to_json(&*conn)).collect::<Vec<serde_json::Value>>(), "posts": posts.into_iter().map(|p| p.to_json(&*conn)).collect::<Vec<serde_json::Value>>(),
"authors": authors.into_iter().map(|u| u.to_json(&*conn)).collect::<Vec<serde_json::Value>>(), "authors": authors.into_iter().map(|u| u.to_json(&*conn)).collect::<Vec<serde_json::Value>>(),
@ -55,9 +55,9 @@ fn activity_details(name: String, conn: DbConn, _ap: ApRequest) -> ActivityStrea
} }
#[get("/blogs/new")] #[get("/blogs/new")]
fn new(user: User) -> Template { fn new(user: User, conn: DbConn) -> Template {
Template::render("blogs/new", json!({ Template::render("blogs/new", json!({
"account": user, "account": user.to_json(&*conn),
"errors": null, "errors": null,
"form": null "form": null
})) }))
@ -119,7 +119,7 @@ fn create(conn: DbConn, data: LenientForm<NewBlogForm>, user: User) -> Result<Re
} else { } else {
println!("{:?}", errors); println!("{:?}", errors);
Err(Template::render("blogs/new", json!({ Err(Template::render("blogs/new", json!({
"account": user, "account": user.to_json(&*conn),
"errors": errors.inner(), "errors": errors.inner(),
"form": form "form": form
}))) })))

View file

@ -63,7 +63,7 @@ fn create(blog_name: String, slug: String, data: LenientForm<NewCommentForm>, us
"has_liked": user.has_liked(&*conn, &post), "has_liked": user.has_liked(&*conn, &post),
"n_reshares": post.get_reshares(&*conn).len(), "n_reshares": post.get_reshares(&*conn).len(),
"has_reshared": user.has_reshared(&*conn, &post), "has_reshared": user.has_reshared(&*conn, &post),
"account": user, "account": user.to_json(&*conn),
"date": &post.creation_date.timestamp(), "date": &post.creation_date.timestamp(),
"previous": form.responding_to.map(|r| Comment::get(&*conn, r).expect("Error retrieving previous comment").to_json(&*conn, &vec![])), "previous": form.responding_to.map(|r| Comment::get(&*conn, r).expect("Error retrieving previous comment").to_json(&*conn, &vec![])),
"user_fqn": user.get_fqn(&*conn), "user_fqn": user.get_fqn(&*conn),

View file

@ -1,23 +1,26 @@
use rocket_contrib::Template; use rocket_contrib::Template;
use rocket::Request; use rocket::Request;
use rocket::request::FromRequest; use rocket::request::FromRequest;
use plume_models::db_conn::DbConn;
use plume_models::users::User; use plume_models::users::User;
#[catch(404)] #[catch(404)]
fn not_found(req: &Request) -> Template { fn not_found(req: &Request) -> Template {
let conn = req.guard::<DbConn>().expect("404: DbConn error");
let user = User::from_request(req).succeeded(); let user = User::from_request(req).succeeded();
Template::render("errors/404", json!({ Template::render("errors/404", json!({
"error_message": "Page not found", "error_message": "Page not found",
"account": user "account": user.map(|u| u.to_json(&*conn))
})) }))
} }
#[catch(500)] #[catch(500)]
fn server_error(req: &Request) -> Template { fn server_error(req: &Request) -> Template {
let conn = req.guard::<DbConn>().expect("500: DbConn error");
let user = User::from_request(req).succeeded(); let user = User::from_request(req).succeeded();
Template::render("errors/500", json!({ Template::render("errors/500", json!({
"error_message": "Server error", "error_message": "Server error",
"account": user "account": user.map(|u| u.to_json(&*conn))
})) }))
} }

View file

@ -23,7 +23,7 @@ fn paginated_index(conn: DbConn, user: Option<User>, page: Page) -> Template {
Template::render("instance/index", json!({ Template::render("instance/index", json!({
"instance": inst, "instance": inst,
"account": user, "account": user.map(|u| u.to_json(&*conn)),
"recents": recents.into_iter().map(|p| p.to_json(&*conn)).collect::<Vec<serde_json::Value>>(), "recents": recents.into_iter().map(|p| p.to_json(&*conn)).collect::<Vec<serde_json::Value>>(),
"page": page.page, "page": page.page,
"n_pages": Page::total(Post::count(&*conn) as i32), "n_pages": Page::total(Post::count(&*conn) as i32),
@ -47,7 +47,7 @@ fn index(conn: DbConn, user: Option<User>) -> Template {
#[get("/admin")] #[get("/admin")]
fn admin(conn: DbConn, admin: Admin) -> Template { fn admin(conn: DbConn, admin: Admin) -> Template {
Template::render("instance/admin", json!({ Template::render("instance/admin", json!({
"account": admin.0, "account": admin.0.to_json(&*conn),
"instance": Instance::get_local(&*conn), "instance": Instance::get_local(&*conn),
"errors": null, "errors": null,
"form": null "form": null
@ -79,7 +79,7 @@ fn update_settings(conn: DbConn, admin: Admin, form: LenientForm<InstanceSetting
Redirect::to(uri!(admin)) Redirect::to(uri!(admin))
}) })
.map_err(|e| Template::render("instance/admin", json!({ .map_err(|e| Template::render("instance/admin", json!({
"account": admin.0, "account": admin.0.to_json(&*conn),
"instance": Instance::get_local(&*conn), "instance": Instance::get_local(&*conn),
"errors": e.inner(), "errors": e.inner(),
"form": form "form": form
@ -127,7 +127,7 @@ fn nodeinfo(conn: DbConn) -> Json<serde_json::Value> {
#[get("/about")] #[get("/about")]
fn about(user: User, conn: DbConn) -> Template { fn about(user: User, conn: DbConn) -> Template {
Template::render("instance/about", json!({ Template::render("instance/about", json!({
"account": user, "account": user.to_json(&*conn),
"instance": Instance::get_local(&*conn), "instance": Instance::get_local(&*conn),
"admin": Instance::get_local(&*conn).map(|i| i.main_admin(&*conn).to_json(&*conn)), "admin": Instance::get_local(&*conn).map(|i| i.main_admin(&*conn).to_json(&*conn)),
"version": "0.1.0", "version": "0.1.0",

View file

@ -10,15 +10,15 @@ use plume_models::{db_conn::DbConn, medias::*, users::User};
fn list(user: User, conn: DbConn) -> Template { fn list(user: User, conn: DbConn) -> Template {
let medias = Media::for_user(&*conn, user.id); let medias = Media::for_user(&*conn, user.id);
Template::render("medias/index", json!({ Template::render("medias/index", json!({
"account": user, "account": user.to_json(&*conn),
"medias": medias.into_iter().map(|m| m.to_json(&*conn)).collect::<Vec<serde_json::Value>>() "medias": medias.into_iter().map(|m| m.to_json(&*conn)).collect::<Vec<serde_json::Value>>()
})) }))
} }
#[get("/medias/new")] #[get("/medias/new")]
fn new(user: User) -> Template { fn new(user: User, conn: DbConn) -> Template {
Template::render("medias/new", json!({ Template::render("medias/new", json!({
"account": user, "account": user.to_json(&*conn),
"form": {}, "form": {},
"errors": {} "errors": {}
})) }))
@ -92,7 +92,7 @@ fn read(data: &SavedData) -> String {
fn details(id: i32, user: User, conn: DbConn) -> Template { fn details(id: i32, user: User, conn: DbConn) -> Template {
let media = Media::get(&*conn, id); let media = Media::get(&*conn, id);
Template::render("medias/details", json!({ Template::render("medias/details", json!({
"account": user, "account": user.to_json(&*conn),
"media": media.map(|m| m.to_json(&*conn)) "media": media.map(|m| m.to_json(&*conn))
})) }))
} }

View file

@ -8,7 +8,7 @@ use routes::Page;
#[get("/notifications?<page>")] #[get("/notifications?<page>")]
fn paginated_notifications(conn: DbConn, user: User, page: Page) -> Template { fn paginated_notifications(conn: DbConn, user: User, page: Page) -> Template {
Template::render("notifications/index", json!({ Template::render("notifications/index", json!({
"account": user, "account": user.to_json(&*conn),
"notifications": Notification::page_for_user(&*conn, &user, page.limits()).into_iter().map(|n| n.to_json(&*conn)).collect::<Vec<_>>(), "notifications": Notification::page_for_user(&*conn, &user, page.limits()).into_iter().map(|n| n.to_json(&*conn)).collect::<Vec<_>>(),
"page": page.page, "page": page.page,
"n_pages": Page::total(Notification::find_for_user(&*conn, &user).len() as i32) "n_pages": Page::total(Notification::find_for_user(&*conn, &user).len() as i32)

View file

@ -35,8 +35,8 @@ fn details(blog: String, slug: String, conn: DbConn, user: Option<User>) -> Temp
#[get("/~/<blog>/<slug>?<query>")] #[get("/~/<blog>/<slug>?<query>")]
fn details_response(blog: String, slug: String, conn: DbConn, user: Option<User>, query: Option<CommentQuery>) -> Template { fn details_response(blog: String, slug: String, conn: DbConn, user: Option<User>, query: Option<CommentQuery>) -> Template {
may_fail!(user, Blog::find_by_fqn(&*conn, blog), "Couldn't find this blog", |blog| { may_fail!(user.map(|u| u.to_json(&*conn)), Blog::find_by_fqn(&*conn, blog), "Couldn't find this blog", |blog| {
may_fail!(user, Post::find_by_slug(&*conn, slug, blog.id), "Couldn't find this post", |post| { may_fail!(user.map(|u| u.to_json(&*conn)), Post::find_by_slug(&*conn, slug, blog.id), "Couldn't find this post", |post| {
let comments = Comment::list_by_post(&*conn, post.id); let comments = Comment::list_by_post(&*conn, post.id);
let comms = comments.clone(); let comms = comments.clone();
@ -53,7 +53,7 @@ fn details_response(blog: String, slug: String, conn: DbConn, user: Option<User>
"has_liked": user.clone().map(|u| u.has_liked(&*conn, &post)).unwrap_or(false), "has_liked": user.clone().map(|u| u.has_liked(&*conn, &post)).unwrap_or(false),
"n_reshares": post.get_reshares(&*conn).len(), "n_reshares": post.get_reshares(&*conn).len(),
"has_reshared": user.clone().map(|u| u.has_reshared(&*conn, &post)).unwrap_or(false), "has_reshared": user.clone().map(|u| u.has_reshared(&*conn, &post)).unwrap_or(false),
"account": &user, "account": &user.clone().map(|u| u.to_json(&*conn)),
"date": &post.creation_date.timestamp(), "date": &post.creation_date.timestamp(),
"previous": query.and_then(|q| q.responding_to.map(|r| Comment::get(&*conn, r).expect("Error retrieving previous comment").to_json(&*conn, &vec![]))), "previous": query.and_then(|q| q.responding_to.map(|r| Comment::get(&*conn, r).expect("Error retrieving previous comment").to_json(&*conn, &vec![]))),
"user_fqn": user.clone().map(|u| u.get_fqn(&*conn)).unwrap_or(String::new()), "user_fqn": user.clone().map(|u| u.get_fqn(&*conn)).unwrap_or(String::new()),
@ -86,7 +86,7 @@ fn new(blog: String, user: User, conn: DbConn) -> Template {
})) }))
} else { } else {
Template::render("posts/new", json!({ Template::render("posts/new", json!({
"account": user, "account": user.to_json(&*conn),
"instance": Instance::get_local(&*conn), "instance": Instance::get_local(&*conn),
"errors": null, "errors": null,
"form": null "form": null
@ -118,7 +118,7 @@ fn create(blog_name: String, data: LenientForm<NewPostForm>, user: User, conn: D
let blog = Blog::find_by_fqn(&*conn, blog_name.to_string()).unwrap(); let blog = Blog::find_by_fqn(&*conn, blog_name.to_string()).unwrap();
let form = data.get(); let form = data.get();
let slug = form.title.to_string().to_kebab_case(); let slug = form.title.to_string().to_kebab_case();
let mut errors = match form.validate() { let mut errors = match form.validate() {
Ok(_) => ValidationErrors::new(), Ok(_) => ValidationErrors::new(),
Err(e) => e Err(e) => e
@ -170,8 +170,8 @@ fn create(blog_name: String, data: LenientForm<NewPostForm>, user: User, conn: D
} }
} else { } else {
Err(Template::render("posts/new", json!({ Err(Template::render("posts/new", json!({
"account": user, "account": user.to_json(&*conn),
"instance": Instance::get_local(&*conn), "instance": Instance::get_local(&*conn),
"errors": errors.inner(), "errors": errors.inner(),
"form": form "form": form
}))) })))

View file

@ -13,10 +13,10 @@ use plume_models::{
}; };
#[get("/login")] #[get("/login")]
fn new(user: Option<User>) -> Template { fn new(user: Option<User>, conn: DbConn) -> Template {
Template::render("session/login", json!({ Template::render("session/login", json!({
"account": user, "account": user.map(|u| u.to_json(&*conn)),
"errors": null, "errors": null,
"form": null "form": null
})) }))
} }
@ -27,9 +27,9 @@ struct Message {
} }
#[get("/login?<message>")] #[get("/login?<message>")]
fn new_message(user: Option<User>, message: Message) -> Template { fn new_message(user: Option<User>, message: Message, conn: DbConn) -> Template {
Template::render("session/login", json!({ Template::render("session/login", json!({
"account": user, "account": user.map(|u| u.to_json(&*conn)),
"message": message.m, "message": message.m,
"errors": null, "errors": null,
"form": null "form": null

View file

@ -42,7 +42,7 @@ fn me(user: Option<User>) -> Result<Redirect, Flash<Redirect>> {
#[get("/@/<name>", rank = 2)] #[get("/@/<name>", rank = 2)]
fn details<'r>(name: String, conn: DbConn, account: Option<User>, worker: State<Pool<ThunkWorker<()>>>, fecth_articles_conn: DbConn, fecth_followers_conn: DbConn) -> Template { fn details<'r>(name: String, conn: DbConn, account: Option<User>, worker: State<Pool<ThunkWorker<()>>>, fecth_articles_conn: DbConn, fecth_followers_conn: DbConn) -> Template {
may_fail!(account, User::find_by_fqn(&*conn, name), "Couldn't find requested user", |user| { may_fail!(account.map(|a| a.to_json(&*conn)), User::find_by_fqn(&*conn, name), "Couldn't find requested user", |user| {
let recents = Post::get_recents_for_author(&*conn, &user, 6); let recents = Post::get_recents_for_author(&*conn, &user, 6);
let reshares = Reshare::get_recents_for_author(&*conn, &user, 6); let reshares = Reshare::get_recents_for_author(&*conn, &user, 6);
let user_id = user.id.clone(); let user_id = user.id.clone();
@ -82,7 +82,7 @@ fn details<'r>(name: String, conn: DbConn, account: Option<User>, worker: State<
"instance_url": user.get_instance(&*conn).public_domain, "instance_url": user.get_instance(&*conn).public_domain,
"is_remote": user.instance_id != Instance::local_id(&*conn), "is_remote": user.instance_id != Instance::local_id(&*conn),
"follows": account.clone().map(|x| x.is_following(&*conn, user.id)).unwrap_or(false), "follows": account.clone().map(|x| x.is_following(&*conn, user.id)).unwrap_or(false),
"account": account, "account": account.clone().map(|a| a.to_json(&*conn)),
"recents": recents.into_iter().map(|p| p.to_json(&*conn)).collect::<Vec<serde_json::Value>>(), "recents": recents.into_iter().map(|p| p.to_json(&*conn)).collect::<Vec<serde_json::Value>>(),
"reshares": reshares.into_iter().map(|r| r.get_post(&*conn).unwrap().to_json(&*conn)).collect::<Vec<serde_json::Value>>(), "reshares": reshares.into_iter().map(|r| r.get_post(&*conn).unwrap().to_json(&*conn)).collect::<Vec<serde_json::Value>>(),
"is_self": account.map(|a| a.id == user_id).unwrap_or(false), "is_self": account.map(|a| a.id == user_id).unwrap_or(false),
@ -95,7 +95,7 @@ fn details<'r>(name: String, conn: DbConn, account: Option<User>, worker: State<
fn dashboard(user: User, conn: DbConn) -> Template { fn dashboard(user: User, conn: DbConn) -> Template {
let blogs = Blog::find_for_author(&*conn, user.id); let blogs = Blog::find_for_author(&*conn, user.id);
Template::render("users/dashboard", json!({ Template::render("users/dashboard", json!({
"account": user, "account": user.to_json(&*conn),
"blogs": blogs "blogs": blogs
})) }))
} }
@ -132,7 +132,7 @@ fn follow_auth(name: String) -> Flash<Redirect> {
#[get("/@/<name>/followers?<page>")] #[get("/@/<name>/followers?<page>")]
fn followers_paginated(name: String, conn: DbConn, account: Option<User>, page: Page) -> Template { fn followers_paginated(name: String, conn: DbConn, account: Option<User>, page: Page) -> Template {
may_fail!(account, User::find_by_fqn(&*conn, name.clone()), "Couldn't find requested user", |user| { may_fail!(account.map(|a| a.to_json(&*conn)), User::find_by_fqn(&*conn, name.clone()), "Couldn't find requested user", |user| {
let user_id = user.id.clone(); let user_id = user.id.clone();
let followers_count = user.get_followers(&*conn).len(); let followers_count = user.get_followers(&*conn).len();
@ -142,7 +142,7 @@ fn followers_paginated(name: String, conn: DbConn, account: Option<User>, page:
"is_remote": user.instance_id != Instance::local_id(&*conn), "is_remote": user.instance_id != Instance::local_id(&*conn),
"follows": account.clone().map(|x| x.is_following(&*conn, user.id)).unwrap_or(false), "follows": account.clone().map(|x| x.is_following(&*conn, user.id)).unwrap_or(false),
"followers": user.get_followers_page(&*conn, page.limits()).into_iter().map(|f| f.to_json(&*conn)).collect::<Vec<serde_json::Value>>(), "followers": user.get_followers_page(&*conn, page.limits()).into_iter().map(|f| f.to_json(&*conn)).collect::<Vec<serde_json::Value>>(),
"account": account, "account": account.clone().map(|a| a.to_json(&*conn)),
"is_self": account.map(|a| a.id == user_id).unwrap_or(false), "is_self": account.map(|a| a.id == user_id).unwrap_or(false),
"n_followers": followers_count, "n_followers": followers_count,
"page": page.page, "page": page.page,
@ -164,19 +164,19 @@ fn activity_details(name: String, conn: DbConn, _ap: ApRequest) -> ActivityStrea
} }
#[get("/users/new")] #[get("/users/new")]
fn new(user: Option<User>) -> Template { fn new(user: Option<User>, conn: DbConn) -> Template {
Template::render("users/new", json!({ Template::render("users/new", json!({
"account": user, "account": user.map(|u| u.to_json(&*conn)),
"errors": null, "errors": null,
"form": null "form": null
})) }))
} }
#[get("/@/<name>/edit")] #[get("/@/<name>/edit")]
fn edit(name: String, user: User) -> Option<Template> { fn edit(name: String, user: User, conn: DbConn) -> Option<Template> {
if user.username == name && !name.contains("@") { if user.username == name && !name.contains("@") {
Some(Template::render("users/edit", json!({ Some(Template::render("users/edit", json!({
"account": user "account": user.to_json(&*conn)
}))) })))
} else { } else {
None None

View file

@ -572,6 +572,10 @@ form.new-post input[type="submit"]:hover { background: #DADADA; }
* Small Screens * * Small Screens *
* ================= */ * ================= */
.mobile-label {
display: none;
}
@media screen and (max-width: 900px) { @media screen and (max-width: 900px) {
header { header {
flex-direction: column; flex-direction: column;
@ -662,7 +666,11 @@ form.new-post input[type="submit"]:hover { background: #DADADA; }
.card { .card {
min-width: 80%; min-width: 80%;
min-height: 80%; min-height: 80%;
} }
.mobile-label {
display: initial;
}
} }
/*== Pagination ==*/ /*== Pagination ==*/
@ -735,3 +743,19 @@ figcaption {
height: auto; height: auto;
margin-right: 20px; margin-right: 20px;
} }
/** Avatars **/
.avatar {
border-radius: 100%;
}
.avatar.small {
width: 50px;
height: 50px;
}
.avatar.medium {
width: 100px;
height: 100px;
}

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>{% block title %}{% endblock title %} ⋅ {{ "Plume" | _ }}</title> <title>{% block title %}{% endblock title %} ⋅ {{ "Plume" | _ }}</title>
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="/static/main.css" /> <link rel="stylesheet" href="/static/main.css" />
<link rel="stylesheet" href="/static/fontawesome-5.0.10/css/fontawesome-all.min.css" /> <link rel="stylesheet" href="/static/fontawesome-5.0.10/css/fontawesome-all.min.css" />
</head> </head>
@ -21,10 +21,22 @@
</nav> </nav>
<nav> <nav>
{% if account %} {% if account %}
<a href="/dashboard">{{ "Dashboard" | _ }}</a> <a href="/dashboard">
<a href="/notifications">{{ "Notifications" | _ }}</a> <i class="fa fa-home" aria-label="{{ "Dashboard" | _ }}"></i>
<a href="/me">{{ "My account" | _ }}</a> <span class="mobile-label">{{ "Dashboard" | _ }}</span>
<a href="/logout">{{ "Log Out" | _ }}</a> </a>
<a href="/notifications">
<i class="fa fa-bell" aria-label="{{ "Notifications" | _ }}"></i>
<span class="mobile-label">{{ "Notifications" | _ }}</span>
</a>
<a href="/logout">
<i class="fa fa-sign-out-alt aria-label="{{ "Log Out" | _ }}"></i>
<span class="mobile-label">{{ "Log Out" | _ }}</span>
</a>
<a href="/me">
<img class="avatar small" src="{{ account.avatar }}" alt="{{ "My account" | _ }}">
<span class="mobile-label">{{ "My account" | _ }}</span>
</a>
{% else %} {% else %}
<a href="/login">{{ "Log In" | _ }}</a> <a href="/login">{{ "Log In" | _ }}</a>
<a href="/users/new">{{ "Register" | _ }}</a> <a href="/users/new">{{ "Register" | _ }}</a>

View file

@ -1,6 +1,6 @@
<div class="user"> <div class="user">
<div> <div>
<img src="{{ user.avatar }}" alt="{{ "{{ name}}'s avatar'" | _(name=user.name) }}"> <img class="avatar medium" src="{{ user.avatar }}" alt="{{ "{{ name}}'s avatar'" | _(name=user.name) }}">
</div> </div>
<h1> <h1>