refactor posts/home page
This commit is contained in:
parent
b38d225540
commit
6266004dcb
|
@ -164,9 +164,7 @@ impl FactoryComponent for CommentRow {
|
|||
let comment_id = self.comment.comment.id;
|
||||
std::thread::spawn(move || {
|
||||
let _ = api::comment::delete_comment(comment_id);
|
||||
sender
|
||||
.output_sender()
|
||||
.emit(crate::AppMsg::StartFetchPosts(None, true));
|
||||
sender.output_sender().emit(crate::AppMsg::OpenPosts);
|
||||
});
|
||||
}
|
||||
CommentRowMsg::OpenEditor(is_new) => {
|
||||
|
|
|
@ -128,7 +128,7 @@ impl SimpleComponent for InstancesPage {
|
|||
current_account.instance_url = url[0..url.len() - 1].to_string();
|
||||
current_account.jwt = None;
|
||||
settings::update_current_account(current_account);
|
||||
crate::AppMsg::StartFetchPosts(None, true)
|
||||
crate::AppMsg::OpenPosts
|
||||
}
|
||||
Err(err) => crate::AppMsg::ShowMessage(err.to_string()),
|
||||
};
|
||||
|
|
|
@ -119,9 +119,7 @@ impl SimpleComponent for LoginPage {
|
|||
});
|
||||
}
|
||||
LoginPageInput::Cancel => {
|
||||
sender
|
||||
.output_sender()
|
||||
.emit(crate::AppMsg::StartFetchPosts(None, true));
|
||||
sender.output_sender().emit(crate::AppMsg::OpenPosts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ pub mod mention_row;
|
|||
pub mod moderates_row;
|
||||
pub mod post_page;
|
||||
pub mod post_row;
|
||||
pub mod posts_page;
|
||||
pub mod private_message_row;
|
||||
pub mod profile_page;
|
||||
pub mod voting_row;
|
||||
|
|
|
@ -316,9 +316,7 @@ impl SimpleComponent for PostPage {
|
|||
let post_id = self.info.post_view.post.id;
|
||||
std::thread::spawn(move || {
|
||||
let _ = api::post::delete_post(post_id);
|
||||
sender
|
||||
.output_sender()
|
||||
.emit(crate::AppMsg::StartFetchPosts(None, true));
|
||||
sender.output_sender().emit(crate::AppMsg::OpenPosts);
|
||||
});
|
||||
}
|
||||
PostPageInput::OpenEditPostDialog => {
|
||||
|
|
|
@ -165,9 +165,7 @@ impl FactoryComponent for PostRow {
|
|||
let post_id = self.post.post.id;
|
||||
std::thread::spawn(move || {
|
||||
let _ = api::post::delete_post(post_id);
|
||||
sender
|
||||
.output_sender()
|
||||
.emit(crate::AppMsg::StartFetchPosts(None, true));
|
||||
sender.output_sender().emit(crate::AppMsg::OpenPosts);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
use gtk::prelude::*;
|
||||
use lemmy_api_common::{lemmy_db_schema::ListingType, lemmy_db_views::structs::PostView};
|
||||
use relm4::{factory::FactoryVecDeque, prelude::*};
|
||||
|
||||
use crate::api;
|
||||
|
||||
use super::post_row::PostRow;
|
||||
|
||||
pub struct PostsPage {
|
||||
posts: FactoryVecDeque<PostRow>,
|
||||
posts_type: ListingType,
|
||||
posts_page: i64,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PostsPageInput {
|
||||
FetchPosts(ListingType, bool),
|
||||
DoneFetchPosts(Vec<PostView>),
|
||||
}
|
||||
|
||||
#[relm4::component(pub)]
|
||||
impl SimpleComponent for PostsPage {
|
||||
type Init = ();
|
||||
type Input = PostsPageInput;
|
||||
type Output = crate::AppMsg;
|
||||
|
||||
view! {
|
||||
gtk::ScrolledWindow {
|
||||
set_hexpand: true,
|
||||
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_margin_all: 10,
|
||||
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_spacing: 10,
|
||||
|
||||
gtk::ToggleButton {
|
||||
set_label: "All",
|
||||
#[watch]
|
||||
set_active: model.posts_type == ListingType::All,
|
||||
connect_clicked => PostsPageInput::FetchPosts(ListingType::All, true),
|
||||
},
|
||||
gtk::ToggleButton {
|
||||
set_label: "Local",
|
||||
#[watch]
|
||||
set_active: model.posts_type ==ListingType::Local,
|
||||
connect_clicked => PostsPageInput::FetchPosts(ListingType::Local, true),
|
||||
},
|
||||
gtk::ToggleButton {
|
||||
set_label: "Subscribed",
|
||||
#[watch]
|
||||
set_active: model.posts_type == ListingType::Subscribed,
|
||||
connect_clicked => PostsPageInput::FetchPosts(ListingType::Subscribed, true),
|
||||
}
|
||||
},
|
||||
#[local_ref]
|
||||
posts_box -> gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 5,
|
||||
},
|
||||
gtk::Button {
|
||||
set_label: "More",
|
||||
connect_clicked => PostsPageInput::FetchPosts(model.posts_type, false),
|
||||
set_margin_all: 10,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn init(
|
||||
_init: Self::Init,
|
||||
root: &Self::Root,
|
||||
sender: ComponentSender<Self>,
|
||||
) -> ComponentParts<Self> {
|
||||
let posts = FactoryVecDeque::new(gtk::Box::default(), sender.output_sender());
|
||||
let model = Self {
|
||||
posts,
|
||||
posts_type: ListingType::Subscribed,
|
||||
posts_page: 1,
|
||||
};
|
||||
let posts_box = model.posts.widget();
|
||||
let widgets = view_output!();
|
||||
ComponentParts { model, widgets }
|
||||
}
|
||||
|
||||
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
|
||||
match message {
|
||||
PostsPageInput::FetchPosts(type_, remove_previous) => {
|
||||
self.posts_type = type_;
|
||||
let page = if remove_previous {
|
||||
1
|
||||
} else {
|
||||
self.posts_page + 1
|
||||
};
|
||||
// show the loading indicator if it's the first page
|
||||
if page == 1 {
|
||||
sender
|
||||
.output_sender()
|
||||
.emit(crate::AppMsg::UpdateState(crate::AppState::Loading));
|
||||
}
|
||||
self.posts_page = page;
|
||||
std::thread::spawn(move || {
|
||||
match api::posts::list_posts(page, None, Some(type_)) {
|
||||
Ok(posts) => {
|
||||
sender.input(PostsPageInput::DoneFetchPosts(posts));
|
||||
}
|
||||
Err(err) => sender
|
||||
.output_sender()
|
||||
.emit(crate::AppMsg::ShowMessage(err.to_string())),
|
||||
};
|
||||
});
|
||||
}
|
||||
PostsPageInput::DoneFetchPosts(posts) => {
|
||||
sender
|
||||
.output_sender()
|
||||
.emit(crate::AppMsg::UpdateState(crate::AppState::Posts));
|
||||
if self.posts_page == 1 {
|
||||
self.posts.guard().clear();
|
||||
}
|
||||
for post in posts {
|
||||
self.posts.guard().push_back(post);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
93
src/main.rs
93
src/main.rs
|
@ -12,7 +12,7 @@ use components::{
|
|||
inbox_page::{InboxInput, InboxPage},
|
||||
instances_page::{InstancesPage, InstancesPageInput},
|
||||
post_page::{self, PostPage},
|
||||
post_row::PostRow,
|
||||
posts_page::{PostsPage, PostsPageInput},
|
||||
profile_page::{ProfileInput, ProfilePage},
|
||||
};
|
||||
use dialogs::about::AboutDialog;
|
||||
|
@ -23,12 +23,10 @@ use lemmy_api_common::{
|
|||
newtypes::{CommunityId, PersonId, PostId},
|
||||
ListingType,
|
||||
},
|
||||
lemmy_db_views::structs::PostView,
|
||||
post::GetPostResponse,
|
||||
};
|
||||
use relm4::{
|
||||
actions::{RelmAction, RelmActionGroup},
|
||||
factory::FactoryVecDeque,
|
||||
prelude::*,
|
||||
set_global_css,
|
||||
};
|
||||
|
@ -53,8 +51,8 @@ struct App {
|
|||
state: AppState,
|
||||
message: Option<String>,
|
||||
back_queue: Vec<AppMsg>,
|
||||
posts: FactoryVecDeque<PostRow>,
|
||||
instances_page: Controller<InstancesPage>,
|
||||
posts_page: Controller<PostsPage>,
|
||||
profile_page: Controller<ProfilePage>,
|
||||
community_page: Controller<CommunityPage>,
|
||||
communities_page: Controller<CommunitiesPage>,
|
||||
|
@ -62,8 +60,6 @@ struct App {
|
|||
inbox_page: Controller<InboxPage>,
|
||||
login_page: Controller<LoginPage>,
|
||||
logged_in: bool,
|
||||
current_posts_type: Option<ListingType>,
|
||||
current_posts_page: i64,
|
||||
about_dialog: Controller<AboutDialog>,
|
||||
}
|
||||
|
||||
|
@ -74,8 +70,7 @@ pub enum AppMsg {
|
|||
LoggedIn,
|
||||
Logout,
|
||||
ShowMessage(String),
|
||||
StartFetchPosts(Option<ListingType>, bool),
|
||||
DoneFetchPosts(Vec<PostView>),
|
||||
OpenPosts,
|
||||
OpenCommunity(CommunityId),
|
||||
DoneFetchCommunity(GetCommunityResponse),
|
||||
OpenPerson(PersonId),
|
||||
|
@ -112,19 +107,13 @@ impl SimpleComponent for App {
|
|||
set_visible: model.back_queue.len() > 1,
|
||||
},
|
||||
pack_start = >k::Button {
|
||||
set_label: "Home",
|
||||
connect_clicked => AppMsg::StartFetchPosts(None, true),
|
||||
set_label: "Posts",
|
||||
connect_clicked => AppMsg::OpenPosts,
|
||||
},
|
||||
pack_start = >k::Button {
|
||||
set_label: "Communities",
|
||||
connect_clicked => AppMsg::OpenCommunities,
|
||||
},
|
||||
pack_start = >k::Button {
|
||||
set_label: "Recommended",
|
||||
connect_clicked => AppMsg::StartFetchPosts(Some(ListingType::Subscribed), true),
|
||||
#[watch]
|
||||
set_visible: model.logged_in,
|
||||
},
|
||||
pack_start = >k::Button {
|
||||
set_label: "Inbox",
|
||||
connect_clicked => AppMsg::OpenInbox,
|
||||
|
@ -134,24 +123,9 @@ impl SimpleComponent for App {
|
|||
},
|
||||
|
||||
match model.state {
|
||||
AppState::Posts => gtk::ScrolledWindow {
|
||||
set_hexpand: true,
|
||||
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
|
||||
#[local_ref]
|
||||
posts_box -> gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 5,
|
||||
},
|
||||
|
||||
gtk::Button {
|
||||
set_label: "More",
|
||||
connect_clicked => AppMsg::StartFetchPosts(model.current_posts_type, false),
|
||||
set_margin_all: 10,
|
||||
}
|
||||
}
|
||||
AppState::Posts => gtk::Box {
|
||||
#[local_ref]
|
||||
posts_page -> gtk::ScrolledWindow {}
|
||||
},
|
||||
AppState::Loading => gtk::Box {
|
||||
set_hexpand: true,
|
||||
|
@ -248,8 +222,10 @@ impl SimpleComponent for App {
|
|||
};
|
||||
let logged_in = current_account.jwt.is_some();
|
||||
|
||||
// initialize all controllers and factories
|
||||
let posts = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender());
|
||||
// initialize all controllers for the various components
|
||||
let posts_page = PostsPage::builder()
|
||||
.launch(())
|
||||
.forward(sender.input_sender(), |msg| msg);
|
||||
let instances_page = InstancesPage::builder()
|
||||
.launch(())
|
||||
.forward(sender.input_sender(), |msg| msg);
|
||||
|
@ -279,7 +255,7 @@ impl SimpleComponent for App {
|
|||
state,
|
||||
back_queue: vec![],
|
||||
logged_in,
|
||||
posts,
|
||||
posts_page,
|
||||
instances_page,
|
||||
profile_page,
|
||||
community_page,
|
||||
|
@ -288,18 +264,16 @@ impl SimpleComponent for App {
|
|||
communities_page,
|
||||
login_page,
|
||||
message: None,
|
||||
current_posts_type: None,
|
||||
current_posts_page: 1,
|
||||
about_dialog,
|
||||
};
|
||||
|
||||
// fetch posts if that's the initial page
|
||||
if !current_account.instance_url.is_empty() {
|
||||
sender.input(AppMsg::StartFetchPosts(None, true))
|
||||
sender.input(AppMsg::OpenPosts)
|
||||
};
|
||||
|
||||
// setup all widgets and different stack pages
|
||||
let posts_box = model.posts.widget();
|
||||
let posts_page = model.posts_page.widget();
|
||||
let instances_page = model.instances_page.widget();
|
||||
let profile_page = model.profile_page.widget();
|
||||
let community_page = model.community_page.widget();
|
||||
|
@ -355,7 +329,7 @@ impl SimpleComponent for App {
|
|||
| AppMsg::DoneFetchCommunity(_)
|
||||
| AppMsg::OpenPerson(_)
|
||||
| AppMsg::DoneFetchPost(_)
|
||||
| AppMsg::DoneFetchPosts(_)
|
||||
| AppMsg::OpenPosts
|
||||
| AppMsg::ShowMessage(_) => self.back_queue.push(msg.clone()),
|
||||
_ => {}
|
||||
}
|
||||
|
@ -367,35 +341,6 @@ impl SimpleComponent for App {
|
|||
.sender()
|
||||
.emit(InstancesPageInput::FetchInstances);
|
||||
}
|
||||
AppMsg::StartFetchPosts(type_, remove_previous) => {
|
||||
self.current_posts_type = type_;
|
||||
let page = if remove_previous {
|
||||
1
|
||||
} else {
|
||||
self.current_posts_page + 1
|
||||
};
|
||||
// show the loading indicator if it's the first page
|
||||
if page == 1 {
|
||||
self.state = AppState::Loading;
|
||||
}
|
||||
self.current_posts_page = page;
|
||||
std::thread::spawn(move || {
|
||||
let message = match api::posts::list_posts(page, None, type_) {
|
||||
Ok(posts) => AppMsg::DoneFetchPosts(posts),
|
||||
Err(err) => AppMsg::ShowMessage(err.to_string()),
|
||||
};
|
||||
sender.input(message);
|
||||
});
|
||||
}
|
||||
AppMsg::DoneFetchPosts(posts) => {
|
||||
self.state = AppState::Posts;
|
||||
if self.current_posts_page == 1 {
|
||||
self.posts.guard().clear();
|
||||
}
|
||||
for post in posts {
|
||||
self.posts.guard().push_back(post);
|
||||
}
|
||||
}
|
||||
AppMsg::OpenCommunities => {
|
||||
self.state = AppState::Communities;
|
||||
self.communities_page
|
||||
|
@ -465,7 +410,7 @@ impl SimpleComponent for App {
|
|||
AppMsg::LoggedIn => {
|
||||
self.logged_in = true;
|
||||
self.back_queue.clear();
|
||||
sender.input(AppMsg::StartFetchPosts(None, true));
|
||||
sender.input(AppMsg::OpenPosts);
|
||||
}
|
||||
AppMsg::PopBackStack => {
|
||||
let action = self.back_queue.get(self.back_queue.len() - 2);
|
||||
|
@ -479,6 +424,10 @@ impl SimpleComponent for App {
|
|||
AppMsg::UpdateState(state) => {
|
||||
self.state = state;
|
||||
}
|
||||
AppMsg::OpenPosts => self
|
||||
.posts_page
|
||||
.sender()
|
||||
.emit(PostsPageInput::FetchPosts(ListingType::Subscribed, true)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue