feat(posts): option to set the sort order
This commit is contained in:
parent
2cd1c678bd
commit
b96ad40fb4
|
@ -1,5 +1,5 @@
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
lemmy_db_schema::ListingType,
|
lemmy_db_schema::{ListingType, SortType},
|
||||||
lemmy_db_views::structs::PostView,
|
lemmy_db_views::structs::PostView,
|
||||||
post::{GetPosts, GetPostsResponse},
|
post::{GetPosts, GetPostsResponse},
|
||||||
};
|
};
|
||||||
|
@ -10,10 +10,12 @@ pub fn list_posts(
|
||||||
page: i64,
|
page: i64,
|
||||||
community_name: Option<String>,
|
community_name: Option<String>,
|
||||||
listing_type: Option<ListingType>,
|
listing_type: Option<ListingType>,
|
||||||
|
sort_type: Option<SortType>,
|
||||||
) -> std::result::Result<Vec<PostView>, reqwest::Error> {
|
) -> std::result::Result<Vec<PostView>, reqwest::Error> {
|
||||||
let params = GetPosts {
|
let params = GetPosts {
|
||||||
page: Some(page),
|
page: Some(page),
|
||||||
type_: listing_type,
|
type_: listing_type,
|
||||||
|
sort: sort_type,
|
||||||
community_name,
|
community_name,
|
||||||
auth: settings::get_current_account().jwt,
|
auth: settings::get_current_account().jwt,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
|
@ -184,7 +184,7 @@ impl SimpleComponent for CommunityPage {
|
||||||
self.current_posts_page += 1;
|
self.current_posts_page += 1;
|
||||||
let page = self.current_posts_page;
|
let page = self.current_posts_page;
|
||||||
std::thread::spawn(move || {
|
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 {
|
if let Ok(community_posts) = community_posts {
|
||||||
sender.input(CommunityInput::DoneFetchPosts(community_posts));
|
sender.input(CommunityInput::DoneFetchPosts(community_posts));
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,4 +15,5 @@ pub mod post_row;
|
||||||
pub mod posts_page;
|
pub mod posts_page;
|
||||||
pub mod private_message_row;
|
pub mod private_message_row;
|
||||||
pub mod profile_page;
|
pub mod profile_page;
|
||||||
|
pub mod sort_dropown;
|
||||||
pub mod voting_row;
|
pub mod voting_row;
|
||||||
|
|
|
@ -1,21 +1,24 @@
|
||||||
use gtk::prelude::*;
|
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 relm4::{factory::FactoryVecDeque, prelude::*};
|
||||||
|
|
||||||
use crate::api;
|
use crate::api;
|
||||||
|
|
||||||
use super::post_row::PostRow;
|
use super::{post_row::PostRow, sort_dropown::{SortDropdown, SortDropdownOutput}};
|
||||||
|
|
||||||
pub struct PostsPage {
|
pub struct PostsPage {
|
||||||
|
sort_dropdown: Controller<SortDropdown>,
|
||||||
posts: FactoryVecDeque<PostRow>,
|
posts: FactoryVecDeque<PostRow>,
|
||||||
|
posts_order: SortType,
|
||||||
posts_type: ListingType,
|
posts_type: ListingType,
|
||||||
posts_page: i64,
|
posts_page: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum PostsPageInput {
|
pub enum PostsPageInput {
|
||||||
FetchPosts(ListingType, bool),
|
FetchPosts(ListingType, SortType, bool),
|
||||||
DoneFetchPosts(Vec<PostView>),
|
DoneFetchPosts(Vec<PostView>),
|
||||||
|
UpdateOrder(SortType),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
|
@ -40,20 +43,27 @@ impl SimpleComponent for PostsPage {
|
||||||
set_label: "All",
|
set_label: "All",
|
||||||
#[watch]
|
#[watch]
|
||||||
set_active: model.posts_type == ListingType::All,
|
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 {
|
gtk::ToggleButton {
|
||||||
set_label: "Local",
|
set_label: "Local",
|
||||||
#[watch]
|
#[watch]
|
||||||
set_active: model.posts_type ==ListingType::Local,
|
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 {
|
gtk::ToggleButton {
|
||||||
set_label: "Subscribed",
|
set_label: "Subscribed",
|
||||||
#[watch]
|
#[watch]
|
||||||
set_active: model.posts_type == ListingType::Subscribed,
|
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]
|
#[local_ref]
|
||||||
posts_box -> gtk::Box {
|
posts_box -> gtk::Box {
|
||||||
|
@ -62,7 +72,7 @@ impl SimpleComponent for PostsPage {
|
||||||
},
|
},
|
||||||
gtk::Button {
|
gtk::Button {
|
||||||
set_label: "More",
|
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,
|
set_margin_all: 10,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,12 +84,20 @@ impl SimpleComponent for PostsPage {
|
||||||
root: &Self::Root,
|
root: &Self::Root,
|
||||||
sender: ComponentSender<Self>,
|
sender: ComponentSender<Self>,
|
||||||
) -> ComponentParts<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 posts = FactoryVecDeque::new(gtk::Box::default(), sender.output_sender());
|
||||||
let model = Self {
|
let model = Self {
|
||||||
|
sort_dropdown,
|
||||||
posts,
|
posts,
|
||||||
posts_type: ListingType::Local,
|
posts_type: ListingType::Local,
|
||||||
|
posts_order: SortType::Hot,
|
||||||
posts_page: 1,
|
posts_page: 1,
|
||||||
};
|
};
|
||||||
|
let sort_dropdown = model.sort_dropdown.widget();
|
||||||
let posts_box = model.posts.widget();
|
let posts_box = model.posts.widget();
|
||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
ComponentParts { model, widgets }
|
ComponentParts { model, widgets }
|
||||||
|
@ -87,8 +105,9 @@ impl SimpleComponent for PostsPage {
|
||||||
|
|
||||||
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
|
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
|
||||||
match message {
|
match message {
|
||||||
PostsPageInput::FetchPosts(type_, remove_previous) => {
|
PostsPageInput::FetchPosts(type_, order, remove_previous) => {
|
||||||
self.posts_type = type_;
|
self.posts_type = type_;
|
||||||
|
self.posts_order = order;
|
||||||
let page = if remove_previous {
|
let page = if remove_previous {
|
||||||
1
|
1
|
||||||
} else {
|
} else {
|
||||||
|
@ -102,7 +121,7 @@ impl SimpleComponent for PostsPage {
|
||||||
}
|
}
|
||||||
self.posts_page = page;
|
self.posts_page = page;
|
||||||
std::thread::spawn(move || {
|
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) => {
|
Ok(posts) => {
|
||||||
sender.input(PostsPageInput::DoneFetchPosts(posts));
|
sender.input(PostsPageInput::DoneFetchPosts(posts));
|
||||||
}
|
}
|
||||||
|
@ -123,6 +142,10 @@ impl SimpleComponent for PostsPage {
|
||||||
self.posts.guard().push_back(post);
|
self.posts.guard().push_back(post);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PostsPageInput::UpdateOrder(order) => {
|
||||||
|
self.posts_order = order;
|
||||||
|
sender.input_sender().emit(PostsPageInput::FetchPosts(self.posts_type, order, true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 }
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ use lemmy_api_common::{
|
||||||
community::GetCommunityResponse,
|
community::GetCommunityResponse,
|
||||||
lemmy_db_schema::{
|
lemmy_db_schema::{
|
||||||
newtypes::{CommunityId, PersonId, PostId},
|
newtypes::{CommunityId, PersonId, PostId},
|
||||||
ListingType,
|
ListingType, SortType,
|
||||||
},
|
},
|
||||||
post::GetPostResponse,
|
post::GetPostResponse,
|
||||||
};
|
};
|
||||||
|
@ -465,7 +465,7 @@ impl SimpleComponent for App {
|
||||||
AppMsg::OpenPosts => self
|
AppMsg::OpenPosts => self
|
||||||
.posts_page
|
.posts_page
|
||||||
.sender()
|
.sender()
|
||||||
.emit(PostsPageInput::FetchPosts(ListingType::Local, true)),
|
.emit(PostsPageInput::FetchPosts(ListingType::Local, SortType::Hot, true)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue