From dcebc4653a4d6ebee20408baf342d6aa469f0038 Mon Sep 17 00:00:00 2001 From: Bat Date: Tue, 4 Sep 2018 11:37:58 +0100 Subject: [PATCH 01/12] Make it possible to unfollow someone I was sure it was already implemented, but it looks like it wasn't --- .../down.sql | 2 + .../up.sql | 2 + plume-models/src/follows.rs | 54 +++++++++++++++++-- plume-models/src/schema.rs | 1 + src/routes/user.rs | 26 ++++----- 5 files changed, 67 insertions(+), 18 deletions(-) create mode 100644 migrations/2018-09-04-103017_follows_add_ap_url/down.sql create mode 100644 migrations/2018-09-04-103017_follows_add_ap_url/up.sql diff --git a/migrations/2018-09-04-103017_follows_add_ap_url/down.sql b/migrations/2018-09-04-103017_follows_add_ap_url/down.sql new file mode 100644 index 00000000..a1d36e37 --- /dev/null +++ b/migrations/2018-09-04-103017_follows_add_ap_url/down.sql @@ -0,0 +1,2 @@ +-- This file should undo anything in `up.sql` +ALTER TABLE follows DROP COLUMN ap_url; diff --git a/migrations/2018-09-04-103017_follows_add_ap_url/up.sql b/migrations/2018-09-04-103017_follows_add_ap_url/up.sql new file mode 100644 index 00000000..e4c7d949 --- /dev/null +++ b/migrations/2018-09-04-103017_follows_add_ap_url/up.sql @@ -0,0 +1,2 @@ +-- Your SQL goes here +ALTER TABLE follows ADD COLUMN ap_url TEXT NOT NULL DEFAULT ''; diff --git a/plume-models/src/follows.rs b/plume-models/src/follows.rs index 57e26fa4..eca39d3d 100644 --- a/plume-models/src/follows.rs +++ b/plume-models/src/follows.rs @@ -1,7 +1,7 @@ -use activitypub::{Actor, activity::{Accept, Follow as FollowAct}, actor::Person}; +use activitypub::{Actor, activity::{Accept, Follow as FollowAct, Undo}, actor::Person}; use diesel::{self, PgConnection, ExpressionMethods, QueryDsl, RunQueryDsl}; -use plume_common::activity_pub::{broadcast, Id, IntoId, inbox::{FromActivity, Notify, WithInbox}, sign::Signer}; +use plume_common::activity_pub::{broadcast, Id, IntoId, inbox::{FromActivity, Notify, WithInbox, Deletable}, sign::Signer}; use blogs::Blog; use notifications::*; use users::User; @@ -12,19 +12,42 @@ use schema::follows; pub struct Follow { pub id: i32, pub follower_id: i32, - pub following_id: i32 + pub following_id: i32, + pub ap_url: String, } #[derive(Insertable)] #[table_name = "follows"] pub struct NewFollow { pub follower_id: i32, - pub following_id: i32 + pub following_id: i32, + pub ap_url: String, } impl Follow { insert!(follows, NewFollow); get!(follows); + find_by!(follows, find_by_ap_url, ap_url as String); + + pub fn find(conn: &PgConnection, from: i32, to: i32) -> Option { + follows::table.filter(follows::follower_id.eq(from)) + .filter(follows::following_id.eq(to)) + .get_result(conn) + .ok() + } + + pub fn into_activity(&self, conn: &PgConnection) -> FollowAct { + let user = User::get(conn, self.follower_id).unwrap(); + let target = User::get(conn, self.following_id).unwrap(); + + let mut act = FollowAct::default(); + act.follow_props.set_actor_link::(user.clone().into_id()).expect("Follow::into_activity: actor error"); + act.follow_props.set_object_object(user.into_activity(&*conn)).unwrap(); + act.object_props.set_id_string(self.ap_url.clone()).unwrap(); + act.object_props.set_to_link(target.clone().into_id()).expect("New Follow error while setting 'to'"); + act.object_props.set_cc_link_vec::(vec![]).expect("New Follow error while setting 'cc'"); + act + } /// from -> The one sending the follow request /// target -> The target of the request, responding with Accept @@ -36,9 +59,12 @@ impl Follow { from_id: i32, target_id: i32 ) -> Follow { + let from_url: String = from.clone().into_id().into(); + let target_url: String = target.clone().into_id().into(); let res = Follow::insert(conn, NewFollow { follower_id: from_id, - following_id: target_id + following_id: target_id, + ap_url: format!("{}/follow/{}", from_url, target_url), }); let mut accept = Accept::default(); @@ -77,3 +103,21 @@ impl Notify for Follow { }); } } + +impl Deletable for Follow { + fn delete(&self, conn: &PgConnection) -> Undo { + diesel::delete(self).execute(conn).expect("Coudn't delete follow"); + + let mut undo = Undo::default(); + undo.undo_props.set_actor_link(User::get(conn, self.follower_id).unwrap().into_id()).expect("Follow::delete: actor error"); + undo.object_props.set_id_string(format!("{}/undo", self.ap_url)).expect("Follow::delete: id error"); + undo.undo_props.set_object_object(self.into_activity(conn)).expect("Follow::delete: object error"); + undo + } + + fn delete_id(id: String, conn: &PgConnection) { + if let Some(follow) = Follow::find_by_ap_url(conn, id) { + follow.delete(conn); + } + } +} diff --git a/plume-models/src/schema.rs b/plume-models/src/schema.rs index 6a625bb8..1671bf72 100644 --- a/plume-models/src/schema.rs +++ b/plume-models/src/schema.rs @@ -42,6 +42,7 @@ table! { id -> Int4, follower_id -> Int4, following_id -> Int4, + ap_url -> Text, } } diff --git a/src/routes/user.rs b/src/routes/user.rs index ae3eb6d1..cd50ffc5 100644 --- a/src/routes/user.rs +++ b/src/routes/user.rs @@ -116,20 +116,20 @@ fn dashboard_auth() -> Flash { #[get("/@//follow")] fn follow(name: String, conn: DbConn, user: User, worker: Worker) -> Redirect { let target = User::find_by_fqn(&*conn, name.clone()).unwrap(); - let f = follows::Follow::insert(&*conn, follows::NewFollow { - follower_id: user.id, - following_id: target.id - }); - f.notify(&*conn); + if let Some(follow) = follows::Follow::find(&*conn, user.id, target.id) { + let delete_act = follow.delete(&*conn); + worker.execute(Thunk::of(move || broadcast(&user, delete_act, vec![target]))); + } else { + let f = follows::Follow::insert(&*conn, follows::NewFollow { + follower_id: user.id, + following_id: target.id, + ap_url: format!("{}/follow/{}", user.ap_url, target.ap_url), + }); + f.notify(&*conn); - let mut act = Follow::default(); - act.follow_props.set_actor_link::(user.clone().into_id()).unwrap(); - act.follow_props.set_object_object(user.into_activity(&*conn)).unwrap(); - act.object_props.set_id_string(format!("{}/follow/{}", user.ap_url, target.ap_url)).unwrap(); - act.object_props.set_to_link(target.clone().into_id()).expect("New Follow error while setting 'to'"); - act.object_props.set_cc_link_vec::(vec![]).expect("New Follow error while setting 'cc'"); - - worker.execute(Thunk::of(move || broadcast(&user, act, vec![target]))); + let act = f.into_activity(&*conn); + worker.execute(Thunk::of(move || broadcast(&user, act, vec![target]))); + } Redirect::to(uri!(details: name = name)) } From e508eada2686d8555a20a64bd4229af7f4f06cc0 Mon Sep 17 00:00:00 2001 From: Bat Date: Tue, 4 Sep 2018 11:39:24 +0100 Subject: [PATCH 02/12] Federate follow deletion --- src/inbox.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/inbox.rs b/src/inbox.rs index 5a4d0bbc..414e9601 100644 --- a/src/inbox.rs +++ b/src/inbox.rs @@ -55,6 +55,10 @@ pub trait Inbox { "Announce" => { Reshare::delete_id(act.undo_props.object_object::()?.object_props.id_string()?, conn); Ok(()) + }, + "Follow" => { + Follow::delete_id(act.undo_props.object_object::()?.object_props.id_string()?, conn); + Ok(()) } _ => Err(InboxError::CantUndo)? } From 7653551d570d13932676735020b737e0b3db9ccb Mon Sep 17 00:00:00 2001 From: Bat Date: Tue, 4 Sep 2018 11:45:41 +0100 Subject: [PATCH 03/12] Fix some compilation errors --- src/routes/user.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/routes/user.rs b/src/routes/user.rs index cd50ffc5..c4ee8f85 100644 --- a/src/routes/user.rs +++ b/src/routes/user.rs @@ -1,5 +1,5 @@ use activitypub::{ - activity::{Create, Follow}, + activity::Create, collection::OrderedCollection, object::Article }; @@ -16,7 +16,7 @@ use workerpool::thunk::*; use plume_common::activity_pub::{ ActivityStream, broadcast, Id, IntoId, ApRequest, - inbox::{FromActivity, Notify} + inbox::{FromActivity, Notify, Deletable} }; use plume_common::utils; use plume_models::{ @@ -71,7 +71,8 @@ fn details(name: String, conn: DbConn, account: Option, worker: Worker, fe .unwrap_or_else(|| User::fetch_from_url(&*fecth_followers_conn, user_id).expect("Couldn't fetch follower")); follows::Follow::insert(&*fecth_followers_conn, follows::NewFollow { follower_id: follower.id, - following_id: user_clone.id + following_id: user_clone.id, + ap_url: format!("{}/follow/{}", follower.ap_url, user_clone.ap_url), }); } })); From 94a386ea2cd166f9ff1539cac89154462ee31af1 Mon Sep 17 00:00:00 2001 From: Bat Date: Tue, 4 Sep 2018 12:26:13 +0100 Subject: [PATCH 04/12] Add subtitles to articles Fix #152 --- .../2018-09-04-104828_posts_add_subtitle/down.sql | 2 ++ .../2018-09-04-104828_posts_add_subtitle/up.sql | 2 ++ plume-models/src/posts.rs | 12 ++++++++---- plume-models/src/schema.rs | 1 + po/de.po | 4 ++++ po/en.po | 3 +++ po/fr.po | 8 +++++++- po/gl.po | 7 ++++++- po/nb.po | 4 ++++ po/pl.po | 4 ++++ po/plume.pot | 3 +++ src/routes/posts.rs | 4 +++- static/main.css | 7 +++++++ templates/macros.html.tera | 8 +++++++- templates/posts/details.html.tera | 1 + templates/posts/new.html.tera | 1 + 16 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 migrations/2018-09-04-104828_posts_add_subtitle/down.sql create mode 100644 migrations/2018-09-04-104828_posts_add_subtitle/up.sql diff --git a/migrations/2018-09-04-104828_posts_add_subtitle/down.sql b/migrations/2018-09-04-104828_posts_add_subtitle/down.sql new file mode 100644 index 00000000..0c39127b --- /dev/null +++ b/migrations/2018-09-04-104828_posts_add_subtitle/down.sql @@ -0,0 +1,2 @@ +-- This file should undo anything in `up.sql` +ALTER TABLE posts DROP COLUMN subtitle; diff --git a/migrations/2018-09-04-104828_posts_add_subtitle/up.sql b/migrations/2018-09-04-104828_posts_add_subtitle/up.sql new file mode 100644 index 00000000..17ab4754 --- /dev/null +++ b/migrations/2018-09-04-104828_posts_add_subtitle/up.sql @@ -0,0 +1,2 @@ +-- Your SQL goes here +ALTER TABLE posts ADD COLUMN subtitle TEXT NOT NULL DEFAULT ''; diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 5b67a66d..73c8c985 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -33,20 +33,22 @@ pub struct Post { pub published: bool, pub license: String, pub creation_date: NaiveDateTime, - pub ap_url: String + pub ap_url: String, + pub subtitle: String, } #[derive(Insertable)] #[table_name = "posts"] pub struct NewPost { - pub blog_id: i32, + pub blog_id: i32, pub slug: String, pub title: String, pub content: SafeString, pub published: bool, pub license: String, pub creation_date: Option, - pub ap_url: String + pub ap_url: String, + pub subtitle: String, } impl Post { @@ -185,6 +187,7 @@ impl Post { article.object_props.set_attributed_to_link_vec::(authors).expect("Article::into_activity: attributedTo error"); article.object_props.set_content_string(self.content.get().clone()).expect("Article::into_activity: content error"); article.object_props.set_published_utctime(Utc.from_utc_datetime(&self.creation_date)).expect("Article::into_activity: published error"); + article.object_props.set_summary_string(self.subtitle.clone()).expect("Article::into_activity: summary error"); article.object_props.set_tag_link_vec(mentions).expect("Article::into_activity: tag error"); article.object_props.set_url_string(self.ap_url.clone()).expect("Article::into_activity: url error"); article.object_props.set_to_link_vec::(to.into_iter().map(Id::new).collect()).expect("Article::into_activity: to error"); @@ -250,7 +253,8 @@ impl FromActivity for Post { license: String::from("CC-0"), // TODO // FIXME: This is wrong: with this logic, we may use the display URL as the AP ID. We need two different fields ap_url: article.object_props.url_string().unwrap_or(article.object_props.id_string().expect("Post::from_activity: url + id error")), - creation_date: Some(article.object_props.published_utctime().expect("Post::from_activity: published error").naive_utc()) + creation_date: Some(article.object_props.published_utctime().expect("Post::from_activity: published error").naive_utc()), + subtitle: article.object_props.summary_string().expect("Post::from_activity: summary error") }); for author in authors.into_iter() { diff --git a/plume-models/src/schema.rs b/plume-models/src/schema.rs index 1671bf72..7214871e 100644 --- a/plume-models/src/schema.rs +++ b/plume-models/src/schema.rs @@ -125,6 +125,7 @@ table! { license -> Varchar, creation_date -> Timestamp, ap_url -> Varchar, + subtitle -> Text, } } diff --git a/po/de.po b/po/de.po index e177a94a..cf8bd3d9 100644 --- a/po/de.po +++ b/po/de.po @@ -508,5 +508,9 @@ msgid "" "Sorry, but registrations are closed on this instance. Try to find another one" msgstr "" +#, fuzzy +msgid "Subtitle" +msgstr "Titel" + #~ msgid "Your password should be at least 8 characters long" #~ msgstr "Das Passwort sollte mindestens 8 Zeichen lang sein" diff --git a/po/en.po b/po/en.po index deccf96e..08d76670 100644 --- a/po/en.po +++ b/po/en.po @@ -497,3 +497,6 @@ msgstr "" msgid "" "Sorry, but registrations are closed on this instance. Try to find another one" msgstr "" + +msgid "Subtitle" +msgstr "" diff --git a/po/fr.po b/po/fr.po index e1f3d757..b9aeecd7 100644 --- a/po/fr.po +++ b/po/fr.po @@ -503,4 +503,10 @@ msgstr "Envoyer" msgid "" "Sorry, but registrations are closed on this instance. Try to find another one" -msgstr "Désolé, mais les inscriptions sont fermées sur cette instance. Essayez d'en trouver une autre." +msgstr "" +"Désolé, mais les inscriptions sont fermées sur cette instance. Essayez d'en " +"trouver une autre." + +#, fuzzy +msgid "Subtitle" +msgstr "Titre" diff --git a/po/gl.po b/po/gl.po index 7f68eef0..5c1eafbb 100644 --- a/po/gl.po +++ b/po/gl.po @@ -496,4 +496,9 @@ msgstr "Enviar" msgid "" "Sorry, but registrations are closed on this instance. Try to find another one" msgstr "" -"Lamentámolo, pero o rexistro en esta instancia está pechado. Inténteo en outra instancia" +"Lamentámolo, pero o rexistro en esta instancia está pechado. Inténteo en " +"outra instancia" + +#, fuzzy +msgid "Subtitle" +msgstr "Título" diff --git a/po/nb.po b/po/nb.po index 275ac691..07257571 100644 --- a/po/nb.po +++ b/po/nb.po @@ -512,6 +512,10 @@ msgid "" "Sorry, but registrations are closed on this instance. Try to find another one" msgstr "" +#, fuzzy +msgid "Subtitle" +msgstr "Tittel" + #~ msgid "One reshare" #~ msgid_plural "{{ count }} reshares" #~ msgstr[0] "Én deling" diff --git a/po/pl.po b/po/pl.po index 0b879eca..be9d2790 100644 --- a/po/pl.po +++ b/po/pl.po @@ -523,6 +523,10 @@ msgid "" "Sorry, but registrations are closed on this instance. Try to find another one" msgstr "" +#, fuzzy +msgid "Subtitle" +msgstr "Tytuł" + #~ msgid "One reshare" #~ msgid_plural "{{ count }} reshares" #~ msgstr[0] "Jedno udostępnienie" diff --git a/po/plume.pot b/po/plume.pot index ca6c8851..28d6ef68 100644 --- a/po/plume.pot +++ b/po/plume.pot @@ -486,3 +486,6 @@ msgstr "" msgid "Sorry, but registrations are closed on this instance. Try to find another one" msgstr "" + +msgid "Subtitle" +msgstr "" diff --git a/src/routes/posts.rs b/src/routes/posts.rs index 44376b89..678b2623 100644 --- a/src/routes/posts.rs +++ b/src/routes/posts.rs @@ -98,6 +98,7 @@ fn new(blog: String, user: User, conn: DbConn) -> Template { struct NewPostForm { #[validate(custom(function = "valid_slug", message = "Invalid title"))] pub title: String, + pub subtitle: String, pub content: String, pub license: String } @@ -150,7 +151,8 @@ fn create(blog_name: String, data: LenientForm, user: User, conn: D Instance::get_local(&*conn).map(|i| i.default_license).unwrap_or(String::from("CC-0")) }, ap_url: "".to_string(), - creation_date: None + creation_date: None, + subtitle: form.subtitle.clone() }); let post = post.update_ap_url(&*conn); PostAuthor::insert(&*conn, NewPostAuthor { diff --git a/static/main.css b/static/main.css index 58521bd5..5aa1c0f4 100644 --- a/static/main.css +++ b/static/main.css @@ -131,6 +131,13 @@ main h2 { font-weight: 300; } +main h2.article { + max-width: 40rem; + margin: 0.5em auto 1em; + color: rgba(36, 36, 36, 0.6); + font-size: 1.25em; +} + /* * == Article == */ diff --git a/templates/macros.html.tera b/templates/macros.html.tera index defe0137..e1a7e989 100644 --- a/templates/macros.html.tera +++ b/templates/macros.html.tera @@ -2,7 +2,13 @@

{{ article.post.title }}

{{ article.post.content | safe | striptags | truncate(length=200) }}

+

+ {% if article.post.subtitle | length > 0 %} + {{ article.post.subtitle }} + {% else %} + {{ article.post.content | safe | striptags | truncate(length=200) }} + {% endif %} +

{{ "By {{ link_1 }}{{ link_2 }}{{ link_3 }}{{ name | escape }}{{ link_4 }}" | _( diff --git a/templates/posts/details.html.tera b/templates/posts/details.html.tera index e7f3dd08..39cfdca5 100644 --- a/templates/posts/details.html.tera +++ b/templates/posts/details.html.tera @@ -11,6 +11,7 @@ {% block content %}

{{ article.post.title }}

+

{{ article.post.subtitle }}

{{ macros::input(name="title", label="Title", errors=errors, form=form, props="required") }} + {{ macros::input(name="subtitle", label="Subtitle", errors=errors, form=form, optional=true) }} {% if errors is defined and errors.content %} {% for err in errors.content %} From c0174a310c511fb312315de0d283e90d24f82e02 Mon Sep 17 00:00:00 2001 From: Bat Date: Tue, 4 Sep 2018 12:36:26 +0100 Subject: [PATCH 05/12] Add a forgotten " in template --- templates/base.html.tera | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/base.html.tera b/templates/base.html.tera index d65f9366..398857b0 100644 --- a/templates/base.html.tera +++ b/templates/base.html.tera @@ -30,7 +30,7 @@ {{ "Notifications" | _ }} - + {{ "Log Out" | _ }} From dbdc9f317e7f222e2d301ffc9baad3b2e33fa816 Mon Sep 17 00:00:00 2001 From: Bat Date: Tue, 4 Sep 2018 13:46:08 +0100 Subject: [PATCH 06/12] Show like/boost counters even when not logged in --- po/de.po | 6 ++++++ po/en.po | 6 ++++++ po/fr.po | 6 ++++++ po/gl.po | 6 ++++++ po/nb.po | 6 ++++++ po/pl.po | 6 ++++++ po/plume.pot | 6 ++++++ static/main.css | 32 +++++++++++++++---------------- templates/posts/details.html.tera | 19 ++++++++++++++---- 9 files changed, 73 insertions(+), 20 deletions(-) diff --git a/po/de.po b/po/de.po index cf8bd3d9..0fa6aa0d 100644 --- a/po/de.po +++ b/po/de.po @@ -512,5 +512,11 @@ msgstr "" msgid "Subtitle" msgstr "Titel" +msgid "Login to like" +msgstr "" + +msgid "Login to boost" +msgstr "" + #~ msgid "Your password should be at least 8 characters long" #~ msgstr "Das Passwort sollte mindestens 8 Zeichen lang sein" diff --git a/po/en.po b/po/en.po index 08d76670..5a2718e8 100644 --- a/po/en.po +++ b/po/en.po @@ -500,3 +500,9 @@ msgstr "" msgid "Subtitle" msgstr "" + +msgid "Login to like" +msgstr "" + +msgid "Login to boost" +msgstr "" diff --git a/po/fr.po b/po/fr.po index b9aeecd7..686c24d4 100644 --- a/po/fr.po +++ b/po/fr.po @@ -510,3 +510,9 @@ msgstr "" #, fuzzy msgid "Subtitle" msgstr "Titre" + +msgid "Login to like" +msgstr "" + +msgid "Login to boost" +msgstr "" diff --git a/po/gl.po b/po/gl.po index 5c1eafbb..2d4597fd 100644 --- a/po/gl.po +++ b/po/gl.po @@ -502,3 +502,9 @@ msgstr "" #, fuzzy msgid "Subtitle" msgstr "Título" + +msgid "Login to like" +msgstr "" + +msgid "Login to boost" +msgstr "" diff --git a/po/nb.po b/po/nb.po index 07257571..3e0019d2 100644 --- a/po/nb.po +++ b/po/nb.po @@ -516,6 +516,12 @@ msgstr "" msgid "Subtitle" msgstr "Tittel" +msgid "Login to like" +msgstr "" + +msgid "Login to boost" +msgstr "" + #~ msgid "One reshare" #~ msgid_plural "{{ count }} reshares" #~ msgstr[0] "Én deling" diff --git a/po/pl.po b/po/pl.po index be9d2790..7955c549 100644 --- a/po/pl.po +++ b/po/pl.po @@ -527,6 +527,12 @@ msgstr "" msgid "Subtitle" msgstr "Tytuł" +msgid "Login to like" +msgstr "" + +msgid "Login to boost" +msgstr "" + #~ msgid "One reshare" #~ msgid_plural "{{ count }} reshares" #~ msgstr[0] "Jedno udostępnienie" diff --git a/po/plume.pot b/po/plume.pot index 28d6ef68..9c0954b1 100644 --- a/po/plume.pot +++ b/po/plume.pot @@ -489,3 +489,9 @@ msgstr "" msgid "Subtitle" msgstr "" + +msgid "Login to like" +msgstr "" + +msgid "Login to boost" +msgstr "" diff --git a/static/main.css b/static/main.css index 5aa1c0f4..0e65fa79 100644 --- a/static/main.css +++ b/static/main.css @@ -207,8 +207,8 @@ main .article-meta .reshares > p { font-size: 1.5em; } -main .article-meta .likes button, -main .article-meta .reshares button { +main .article-meta .likes .action, +main .article-meta .reshares .action { display: flex; flex-direction: column; align-items: center; @@ -221,12 +221,12 @@ main .article-meta .reshares button { } main .article-meta .likes > p, -main .article-meta .likes button:hover { color: #E92F2F; } +main .article-meta .likes .action:hover { color: #E92F2F; } main .article-meta .reshares > p, -main .article-meta .reshares button:hover { color: #7765E3; } +main .article-meta .reshares .action:hover { color: #7765E3; } -main .article-meta .likes button i, -main .article-meta .reshares button i { +main .article-meta .likes .action i, +main .article-meta .reshares .action i { transition: background 0.1s ease-in; display: flex; align-items: center; @@ -239,37 +239,37 @@ main .article-meta .reshares button i { border-radius: 50%; } -main .article-meta .likes button i { +main .article-meta .likes .action i { color: #E92F2F; border: solid #E92F2F thin; font-weight: 400; } -main .article-meta .likes button:hover i { +main .article-meta .likes .action:hover i { background: rgba(233, 47, 47, 0.15); } -main .article-meta .reshares button i { +main .article-meta .reshares .action i { color: #7765E3; border: solid #7765E3 thin; font-weight: 600; } -main .article-meta .reshares button:hover i { +main .article-meta .reshares .action:hover i { background: rgba(119, 101, 227, 0.15); } -main .article-meta .likes button.liked i { background: #E92F2F; } -main .article-meta .likes button.liked:hover i { +main .article-meta .likes .action.liked i { background: #E92F2F; } +main .article-meta .likes .action.liked:hover i { background: rgba(233, 47, 47, 0.25); color: #E92F2F; } -main .article-meta .reshares button.reshared i { background: #7765E3; } -main .article-meta .reshares button.reshared:hover i { +main .article-meta .reshares .action.reshared i { background: #7765E3; } +main .article-meta .reshares .action.reshared:hover i { background: rgba(119, 101, 227, 0.25); color: #7765E3; } -main .article-meta .likes button.liked i, -main .article-meta .reshares button.reshared i { +main .article-meta .likes .action.liked i, +main .article-meta .reshares .action.reshared i { color: #F4F4F4; font-weight: 900; } diff --git a/templates/posts/details.html.tera b/templates/posts/details.html.tera index 39cfdca5..cae86e50 100644 --- a/templates/posts/details.html.tera +++ b/templates/posts/details.html.tera @@ -41,23 +41,34 @@

{{ n_likes }}

{% if has_liked %} - + {% else %} - + {% endif %}

{{ n_reshares }}

{% if has_reshared %} - + {% else %} - + {% endif %}
{% else %}

{{ "Login or use your Fediverse account to interact with this article" | _ }}

+
{% endif %}
From d60289aac8797fdad013c451ede0edbe471052f0 Mon Sep 17 00:00:00 2001 From: Bat Date: Tue, 4 Sep 2018 14:02:01 +0100 Subject: [PATCH 07/12] Local instance ID is 1, not 0 This prevented local users from being removed before broadcasting an activity. Fixes #113 --- plume-models/src/users.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 418a9888..76b1127c 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -567,7 +567,7 @@ impl WithInbox for User { } fn is_local(&self) -> bool { - self.instance_id == 0 + self.instance_id == 1 } } From 3b2d69893d3b082856fd1252367efa9af20c9c61 Mon Sep 17 00:00:00 2001 From: Bat Date: Tue, 4 Sep 2018 14:32:20 +0100 Subject: [PATCH 08/12] Better style for code blocks --- static/main.css | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/static/main.css b/static/main.css index 0e65fa79..b1d72d6e 100644 --- a/static/main.css +++ b/static/main.css @@ -167,6 +167,13 @@ article img { max-width: 100%; } +article pre { + background: #DADADA; + padding: 1em; + overflow: auto; + border-radius: 5px; +} + /* Article.Meta */ main .article-meta, main .article-meta button { From dd0663348ee09673dd0c6d7cbffd5a5fd94b4862 Mon Sep 17 00:00:00 2001 From: Bat Date: Tue, 4 Sep 2018 14:39:46 +0100 Subject: [PATCH 09/12] Better image styling --- static/main.css | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/static/main.css b/static/main.css index b1d72d6e..c30b313e 100644 --- a/static/main.css +++ b/static/main.css @@ -164,7 +164,9 @@ main article { } article img { - max-width: 100%; + max-width: 100%; + margin: 3em auto; + display: block; } article pre { From bba9a563298102a85c8a5afdfc2964366fd1114e Mon Sep 17 00:00:00 2001 From: Bat Date: Tue, 4 Sep 2018 14:55:15 +0100 Subject: [PATCH 10/12] Add author biography at the bottom of the post --- src/routes/posts.rs | 3 ++- static/main.css | 2 +- templates/posts/details.html.tera | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/routes/posts.rs b/src/routes/posts.rs index 678b2623..7ecf9f4b 100644 --- a/src/routes/posts.rs +++ b/src/routes/posts.rs @@ -57,7 +57,8 @@ fn details_response(blog: String, slug: String, conn: DbConn, user: Option "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![]))), "user_fqn": user.clone().map(|u| u.get_fqn(&*conn)).unwrap_or(String::new()), - "is_author": user.map(|u| post.get_authors(&*conn).into_iter().any(|a| u.id == a.id)).unwrap_or(false) + "is_author": user.clone().map(|u| post.get_authors(&*conn).into_iter().any(|a| u.id == a.id)).unwrap_or(false), + "is_following": user.map(|u| u.is_following(&*conn, post.get_authors(&*conn)[0].id)).unwrap_or(false) })) }) }) diff --git a/static/main.css b/static/main.css index c30b313e..c91cb76f 100644 --- a/static/main.css +++ b/static/main.css @@ -778,5 +778,5 @@ figcaption { } .avatar.padded { - margin-right: 1em; + margin-right: 2rem; } diff --git a/templates/posts/details.html.tera b/templates/posts/details.html.tera index cae86e50..ea8280c9 100644 --- a/templates/posts/details.html.tera +++ b/templates/posts/details.html.tera @@ -34,6 +34,20 @@