diff --git a/src/activity_pub/activity.rs b/src/activity_pub/activity.rs index 7edfa37e..b318b5bf 100644 --- a/src/activity_pub/activity.rs +++ b/src/activity_pub/activity.rs @@ -46,7 +46,7 @@ impl Activity for Accept { fn serialize(&self) -> serde_json::Value { json!({ "type": "Accept", - "id": self.id, + "id": self.id, "actor": self.actor, "object": self.object, "published": self.date.to_rfc3339() @@ -136,7 +136,43 @@ impl Activity for Follow { fn serialize(&self) -> serde_json::Value { json!({ "type": "Follow", - "id": self.id, + "id": self.id, + "actor": self.actor, + "object": self.object + }) + } +} + +#[derive(Clone)] +pub struct Like { + id: String, + actor: serde_json::Value, + object: serde_json::Value +} + +impl Like { + pub fn new(actor: &A, obj: &B, conn: &PgConnection) -> Like { + Like { + id: format!("{}/like/{}", actor.compute_id(conn), obj.compute_id(conn)), + actor: serde_json::Value::String(actor.compute_id(conn)), + object: serde_json::Value::String(obj.compute_id(conn)) + } + } +} + +impl Activity for Like { + fn get_id(&self) -> String { + self.id.clone() + } + + fn get_type(&self) -> String { + "Follow".to_string() + } + + fn serialize(&self) -> serde_json::Value { + json!({ + "type": "Follow", + "id": self.id, "actor": self.actor, "object": self.object }) diff --git a/src/main.rs b/src/main.rs index 610f6339..78544691 100644 --- a/src/main.rs +++ b/src/main.rs @@ -92,7 +92,9 @@ fn main() { routes::posts::create, routes::comments::new, - routes::comments::create + routes::comments::create, + + routes::likes::create ]) .manage(init_pool()) .attach(Template::fairing()) diff --git a/src/models/posts.rs b/src/models/posts.rs index 992f6631..36cc54ee 100644 --- a/src/models/posts.rs +++ b/src/models/posts.rs @@ -8,6 +8,7 @@ use activity_pub::{PUBLIC_VISIBILTY, ap_url}; use activity_pub::actor::Actor; use activity_pub::object::Object; use models::blogs::Blog; +use models::likes::Like; use models::users::User; use models::post_authors::PostAuthor; use schema::posts; @@ -85,6 +86,13 @@ impl Post { .into_iter().nth(0).unwrap() } + pub fn get_likes(&self, conn: &PgConnection) -> Vec { + use schema::likes; + likes::table.filter(likes::post_id.eq(self.id)) + .load::(conn) + .expect("Couldn't load likes associted to post") + } + pub fn update_ap_url(&self, conn: &PgConnection) { if self.ap_url.len() == 0 { diesel::update(self) diff --git a/src/routes/likes.rs b/src/routes/likes.rs new file mode 100644 index 00000000..ff558cfd --- /dev/null +++ b/src/routes/likes.rs @@ -0,0 +1,21 @@ +use rocket::response::Redirect; + +use activity_pub::activity::Like; +use activity_pub::outbox::broadcast; +use db_conn::DbConn; +use models::likes; +use models::posts::Post; +use models::users::User; + +#[get("/~///like")] +fn create(blog: String, slug: String, user: User, conn: DbConn) -> Redirect { + let post = Post::find_by_slug(&*conn, slug.clone()).unwrap(); + likes::Like::insert(&*conn, likes::NewLike { + post_id: post.id, + user_id: user.id + }); + let act = Like::new(&user, &post, &*conn); + broadcast(&*conn, &user, act, user.get_followers(&*conn)); + + Redirect::to(format!("/~/{}/{}/", blog, slug).as_ref()) +} diff --git a/src/routes/mod.rs b/src/routes/mod.rs index 7a225a9d..4b4a40af 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -1,6 +1,7 @@ pub mod blogs; pub mod comments; pub mod instance; +pub mod likes; pub mod posts; pub mod session; pub mod user; diff --git a/src/routes/posts.rs b/src/routes/posts.rs index dd9f2b73..e88cc3e3 100644 --- a/src/routes/posts.rs +++ b/src/routes/posts.rs @@ -31,7 +31,8 @@ fn details(blog: String, slug: String, conn: DbConn) -> Template { "content": c.content, "author": c.get_author(&*conn) }) - }).collect::>() + }).collect::>(), + "n_likes": post.get_likes(&*conn).len() })) } diff --git a/templates/posts/details.tera b/templates/posts/details.tera index 0c62d14f..959c04cf 100644 --- a/templates/posts/details.tera +++ b/templates/posts/details.tera @@ -13,6 +13,12 @@

License: {{ post.license }}


+ +

+ {{ n_likes }} like{{ n_likes | pluralize }} +

+ Add yours +

Comments

{% for comment in comments %}