diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 53051422..c826f766 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -136,6 +136,20 @@ impl Post { .expect("Error loading local posts page") } + /// Give a page of customized user feed, based on a list of followed users + pub fn user_feed_page(conn: &PgConnection, followed: Vec, (min, max): (i32, i32)) -> Vec { + use schema::post_authors; + let post_ids = post_authors::table.filter(post_authors::author_id.eq(any(followed))) + .select(post_authors::post_id); + + posts::table.order(posts::creation_date.desc()) + .filter(posts::id.eq(any(post_ids))) + .offset(min.into()) + .limit((max - min).into()) + .load::(conn) + .expect("Error loading user feed page") + } + pub fn get_authors(&self, conn: &PgConnection) -> Vec { use schema::users; use schema::post_authors; diff --git a/src/main.rs b/src/main.rs index c00c4570..c058e3fa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -59,6 +59,8 @@ fn main() { routes::instance::index, routes::instance::paginated_local, routes::instance::local, + routes::instance::paginated_feed, + routes::instance::feed, routes::instance::admin, routes::instance::update_settings, routes::instance::shared_inbox, diff --git a/src/routes/instance.rs b/src/routes/instance.rs index 159fc6cd..b78e5ece 100644 --- a/src/routes/instance.rs +++ b/src/routes/instance.rs @@ -62,6 +62,23 @@ fn local(conn: DbConn, user: Option) -> Template { paginated_local(conn, user, Page::first()) } +#[get("/feed")] +fn feed(conn: DbConn, user: User) -> Template { + paginated_feed(conn, user, Page::first()) +} + +#[get("/feed?")] +fn paginated_feed(conn: DbConn, user: User, page: Page) -> Template { + let followed = user.get_following(&*conn); + let articles = Post::user_feed_page(&*conn, followed.into_iter().map(|u| u.id).collect(), page.limits()); + Template::render("instance/feed", json!({ + "account": user.to_json(&*conn), + "page": page.page, + "n_pages": Page::total(Post::count_local(&*conn) as i32), + "articles": articles.into_iter().map(|p| p.to_json(&*conn)).collect::>() + })) +} + #[get("/admin")] fn admin(conn: DbConn, admin: Admin) -> Template { Template::render("instance/admin", json!({ diff --git a/templates/instance/feed.html.tera b/templates/instance/feed.html.tera new file mode 100644 index 00000000..58263260 --- /dev/null +++ b/templates/instance/feed.html.tera @@ -0,0 +1,23 @@ +{% extends "base" %} +{% import "macros" as macros %} + +{% block title %} +{{ "Your feed" | _ }} +{% endblock title %} + +{% block content %} +

+ {{ "Your feed" | _ }} +

+ + {% if articles | length > 0 %} +
+ {% for article in articles %} + {{ macros::post_card(article=article) }} + {% endfor %} +
+ {{ macros::paginate(page=page, total=n_pages) }} + {% else %} +

{{ "Nothing to see here yet. Try to follow more people." | _ }}

+ {% endif %} +{% endblock content %}