feat(posts): option to set the sort order

This commit is contained in:
Bnyro 2023-08-06 13:41:38 +02:00
parent 2cd1c678bd
commit b96ad40fb4
6 changed files with 109 additions and 14 deletions

View File

@ -1,5 +1,5 @@
use lemmy_api_common::{
lemmy_db_schema::ListingType,
lemmy_db_schema::{ListingType, SortType},
lemmy_db_views::structs::PostView,
post::{GetPosts, GetPostsResponse},
};
@ -10,10 +10,12 @@ pub fn list_posts(
page: i64,
community_name: Option<String>,
listing_type: Option<ListingType>,
sort_type: Option<SortType>,
) -> std::result::Result<Vec<PostView>, reqwest::Error> {
let params = GetPosts {
page: Some(page),
type_: listing_type,
sort: sort_type,
community_name,
auth: settings::get_current_account().jwt,
..Default::default()

View File

@ -184,7 +184,7 @@ impl SimpleComponent for CommunityPage {
self.current_posts_page += 1;
let page = self.current_posts_page;
std::thread::spawn(move || {
let community_posts = api::posts::list_posts(page, Some(name), None);
let community_posts = api::posts::list_posts(page, Some(name), None, None);
if let Ok(community_posts) = community_posts {
sender.input(CommunityInput::DoneFetchPosts(community_posts));
}

View File

@ -15,4 +15,5 @@ pub mod post_row;
pub mod posts_page;
pub mod private_message_row;
pub mod profile_page;
pub mod sort_dropown;
pub mod voting_row;

View File

@ -1,21 +1,24 @@
use gtk::prelude::*;
use lemmy_api_common::{lemmy_db_schema::ListingType, lemmy_db_views::structs::PostView};
use lemmy_api_common::{lemmy_db_schema::{ListingType, SortType}, lemmy_db_views::structs::PostView};
use relm4::{factory::FactoryVecDeque, prelude::*};
use crate::api;
use super::post_row::PostRow;
use super::{post_row::PostRow, sort_dropown::{SortDropdown, SortDropdownOutput}};
pub struct PostsPage {
sort_dropdown: Controller<SortDropdown>,
posts: FactoryVecDeque<PostRow>,
posts_order: SortType,
posts_type: ListingType,
posts_page: i64,
}
#[derive(Debug)]
pub enum PostsPageInput {
FetchPosts(ListingType, bool),
FetchPosts(ListingType, SortType, bool),
DoneFetchPosts(Vec<PostView>),
UpdateOrder(SortType),
}
#[relm4::component(pub)]
@ -40,20 +43,27 @@ impl SimpleComponent for PostsPage {
set_label: "All",
#[watch]
set_active: model.posts_type == ListingType::All,
connect_clicked => PostsPageInput::FetchPosts(ListingType::All, true),
connect_clicked => PostsPageInput::FetchPosts(ListingType::All, model.posts_order, true),
},
gtk::ToggleButton {
set_label: "Local",
#[watch]
set_active: model.posts_type ==ListingType::Local,
connect_clicked => PostsPageInput::FetchPosts(ListingType::Local, true),
connect_clicked => PostsPageInput::FetchPosts(ListingType::Local, model.posts_order, true),
},
gtk::ToggleButton {
set_label: "Subscribed",
#[watch]
set_active: model.posts_type == ListingType::Subscribed,
connect_clicked => PostsPageInput::FetchPosts(ListingType::Subscribed, true),
}
connect_clicked => PostsPageInput::FetchPosts(ListingType::Subscribed, model.posts_order, true),
},
gtk::Box {
set_hexpand: true,
},
#[local_ref]
sort_dropdown -> gtk::DropDown {},
},
#[local_ref]
posts_box -> gtk::Box {
@ -62,7 +72,7 @@ impl SimpleComponent for PostsPage {
},
gtk::Button {
set_label: "More",
connect_clicked => PostsPageInput::FetchPosts(model.posts_type, false),
connect_clicked => PostsPageInput::FetchPosts(model.posts_type, model.posts_order, false),
set_margin_all: 10,
}
}
@ -74,12 +84,20 @@ impl SimpleComponent for PostsPage {
root: &Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let sort_dropdown = SortDropdown::builder().launch(()).forward(sender.input_sender(), |msg| {
match msg {
SortDropdownOutput::New(sort_order) => PostsPageInput::UpdateOrder(sort_order),
}
});
let posts = FactoryVecDeque::new(gtk::Box::default(), sender.output_sender());
let model = Self {
sort_dropdown,
posts,
posts_type: ListingType::Local,
posts_order: SortType::Hot,
posts_page: 1,
};
let sort_dropdown = model.sort_dropdown.widget();
let posts_box = model.posts.widget();
let widgets = view_output!();
ComponentParts { model, widgets }
@ -87,8 +105,9 @@ impl SimpleComponent for PostsPage {
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
match message {
PostsPageInput::FetchPosts(type_, remove_previous) => {
PostsPageInput::FetchPosts(type_, order, remove_previous) => {
self.posts_type = type_;
self.posts_order = order;
let page = if remove_previous {
1
} else {
@ -102,7 +121,7 @@ impl SimpleComponent for PostsPage {
}
self.posts_page = page;
std::thread::spawn(move || {
match api::posts::list_posts(page, None, Some(type_)) {
match api::posts::list_posts(page, None, Some(type_), Some(order)) {
Ok(posts) => {
sender.input(PostsPageInput::DoneFetchPosts(posts));
}
@ -123,6 +142,10 @@ impl SimpleComponent for PostsPage {
self.posts.guard().push_back(post);
}
}
PostsPageInput::UpdateOrder(order) => {
self.posts_order = order;
sender.input_sender().emit(PostsPageInput::FetchPosts(self.posts_type, order, true));
}
}
}
}

View File

@ -0,0 +1,69 @@
use lemmy_api_common::lemmy_db_schema::SortType;
use relm4::prelude::*;
pub struct SortDropdown {}
#[derive(Debug)]
pub enum SortDropdownOutput {
New(SortType),
}
pub struct Widgets {}
impl SimpleComponent for SortDropdown {
type Init = ();
type Input = ();
type Output = SortDropdownOutput;
type Root = gtk::DropDown;
type Widgets = Widgets;
fn init_root() -> Self::Root {
gtk::DropDown::from_strings(&[
"Hot",
"New",
"Active",
"Old",
"Top All",
"Top Today",
"Top Week",
"Top Month",
"Top Year",
"Most comments",
"New comments",
"Top current hour",
"Top 6 hours",
])
}
fn init(
_init: Self::Init,
root: &Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let model = Self {};
let dropdown = root.clone();
dropdown.connect_selected_item_notify(move |dropdown| {
let sort_type = match dropdown.selected() {
0 => SortType::Hot,
1 => SortType::New,
2 => SortType::Active,
3 => SortType::Old,
4 => SortType::TopAll,
5 => SortType::TopDay,
6 => SortType::TopWeek,
7 => SortType::TopMonth,
8 => SortType::TopYear,
9 => SortType::MostComments,
10 => SortType::NewComments,
11 => SortType::TopHour,
12 => SortType::TopSixHour,
_ => SortType::Active,
};
sender
.output_sender()
.emit(SortDropdownOutput::New(sort_type));
});
let widgets = Widgets {};
ComponentParts { model, widgets }
}
}

View File

@ -22,7 +22,7 @@ use lemmy_api_common::{
community::GetCommunityResponse,
lemmy_db_schema::{
newtypes::{CommunityId, PersonId, PostId},
ListingType,
ListingType, SortType,
},
post::GetPostResponse,
};
@ -465,7 +465,7 @@ impl SimpleComponent for App {
AppMsg::OpenPosts => self
.posts_page
.sender()
.emit(PostsPageInput::FetchPosts(ListingType::Local, true)),
.emit(PostsPageInput::FetchPosts(ListingType::Local, SortType::Hot, true)),
}
}
}