Plume/plume-models/src/notifications.rs

110 lines
4.1 KiB
Rust
Raw Normal View History

2018-09-27 23:06:40 +02:00
use chrono::NaiveDateTime;
use diesel::{self, RunQueryDsl, QueryDsl, ExpressionMethods};
2018-07-26 15:46:10 +02:00
use serde_json;
2018-05-13 14:44:18 +02:00
2018-09-27 23:06:40 +02:00
use Connection;
2018-07-26 15:46:10 +02:00
use comments::Comment;
use follows::Follow;
use likes::Like;
use mentions::Mention;
use posts::Post;
use reshares::Reshare;
use users::User;
2018-05-13 14:44:18 +02:00
use schema::notifications;
2018-07-26 15:46:10 +02:00
pub mod notification_kind {
pub const COMMENT: &'static str = "COMMENT";
pub const FOLLOW: &'static str = "FOLLOW";
pub const LIKE: &'static str = "LIKE";
pub const MENTION: &'static str = "MENTION";
pub const RESHARE: &'static str = "RESHARE";
}
2018-09-27 23:06:40 +02:00
#[derive(Clone, Queryable, Identifiable, Serialize)]
2018-05-13 14:44:18 +02:00
pub struct Notification {
pub id: i32,
2018-05-24 12:12:27 +02:00
pub user_id: i32,
2018-09-27 23:06:40 +02:00
pub creation_date: NaiveDateTime,
2018-07-26 15:46:10 +02:00
pub kind: String,
pub object_id: i32
2018-05-13 14:44:18 +02:00
}
#[derive(Insertable)]
#[table_name = "notifications"]
pub struct NewNotification {
2018-06-17 22:19:27 +02:00
pub user_id: i32,
2018-07-26 15:46:10 +02:00
pub kind: String,
pub object_id: i32
2018-05-13 14:44:18 +02:00
}
impl Notification {
insert!(notifications, NewNotification);
get!(notifications);
2018-05-13 15:35:55 +02:00
pub fn find_for_user(conn: &Connection, user: &User) -> Vec<Notification> {
2018-05-13 15:35:55 +02:00
notifications::table.filter(notifications::user_id.eq(user.id))
2018-05-24 12:12:27 +02:00
.order_by(notifications::creation_date.desc())
2018-05-13 15:35:55 +02:00
.load::<Notification>(conn)
.expect("Notification::find_for_user: notification loading error")
2018-05-13 15:35:55 +02:00
}
pub fn page_for_user(conn: &Connection, user: &User, (min, max): (i32, i32)) -> Vec<Notification> {
notifications::table.filter(notifications::user_id.eq(user.id))
.order_by(notifications::creation_date.desc())
.offset(min.into())
.limit((max - min).into())
.load::<Notification>(conn)
.expect("Notification::page_for_user: notification loading error")
}
2018-07-26 15:46:10 +02:00
pub fn find<S: Into<String>>(conn: &Connection, kind: S, obj: i32) -> Option<Notification> {
notifications::table.filter(notifications::kind.eq(kind.into()))
.filter(notifications::object_id.eq(obj))
.get_result::<Notification>(conn)
.ok()
}
pub fn to_json(&self, conn: &Connection) -> serde_json::Value {
2018-07-26 15:46:10 +02:00
let mut json = json!(self);
json["object"] = json!(match self.kind.as_ref() {
notification_kind::COMMENT => Comment::get(conn, self.object_id).map(|comment|
json!({
"post": comment.get_post(conn).to_json(conn),
"user": comment.get_author(conn).to_json(conn),
"id": comment.id
})
),
notification_kind::FOLLOW => Follow::get(conn, self.object_id).map(|follow|
json!({
"follower": User::get(conn, follow.follower_id).map(|u| u.to_json(conn))
})
),
notification_kind::LIKE => Like::get(conn, self.object_id).map(|like|
json!({
"post": Post::get(conn, like.post_id).map(|p| p.to_json(conn)),
"user": User::get(conn, like.user_id).map(|u| u.to_json(conn))
})
),
notification_kind::MENTION => Mention::get(conn, self.object_id).map(|mention|
json!({
"user": mention.get_user(conn).map(|u| u.to_json(conn)),
"url": mention.get_post(conn).map(|p| p.to_json(conn)["url"].clone())
.unwrap_or_else(|| {
let comment = mention.get_comment(conn).expect("Notification::to_json: comment not found error");
2018-07-26 15:46:10 +02:00
let post = comment.get_post(conn).to_json(conn);
json!(format!("{}#comment-{}", post["url"].as_str().expect("Notification::to_json: post url error"), comment.id))
2018-07-26 15:46:10 +02:00
})
})
),
notification_kind::RESHARE => Reshare::get(conn, self.object_id).map(|reshare|
json!({
"post": reshare.get_post(conn).map(|p| p.to_json(conn)),
"user": reshare.get_user(conn).map(|u| u.to_json(conn))
})
),
_ => Some(json!({}))
});
json
}
2018-05-13 14:44:18 +02:00
}