Move communities page into a separate component
This commit is contained in:
parent
ae6bf45879
commit
0755f2a0de
|
@ -0,0 +1,152 @@
|
|||
use gtk::prelude::*;
|
||||
use lemmy_api_common::{
|
||||
lemmy_db_schema::ListingType, lemmy_db_views_actor::structs::CommunityView,
|
||||
};
|
||||
use relm4::{factory::FactoryVecDeque, prelude::*};
|
||||
|
||||
use crate::api;
|
||||
|
||||
use super::community_row::CommunityRow;
|
||||
|
||||
pub struct CommunitiesPage {
|
||||
communities: FactoryVecDeque<CommunityRow>,
|
||||
communities_page: i64,
|
||||
communities_type: ListingType,
|
||||
community_search_buffer: gtk::EntryBuffer,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CommunitiesPageInput {
|
||||
DoneFetchCommunities(Vec<CommunityView>),
|
||||
FetchCommunities(ListingType, bool),
|
||||
}
|
||||
|
||||
#[relm4::component(pub)]
|
||||
impl SimpleComponent for CommunitiesPage {
|
||||
type Init = ();
|
||||
type Input = CommunitiesPageInput;
|
||||
type Output = crate::AppMsg;
|
||||
|
||||
view! {
|
||||
gtk::Box {
|
||||
gtk::ScrolledWindow {
|
||||
set_vexpand: true,
|
||||
set_hexpand: true,
|
||||
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 10,
|
||||
set_margin_all: 10,
|
||||
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_spacing: 10,
|
||||
|
||||
gtk::ToggleButton {
|
||||
set_label: "All",
|
||||
#[watch]
|
||||
set_active: model.communities_type == ListingType::All,
|
||||
connect_clicked => CommunitiesPageInput::FetchCommunities(ListingType::All, true),
|
||||
},
|
||||
gtk::ToggleButton {
|
||||
set_label: "Local",
|
||||
#[watch]
|
||||
set_active: model.communities_type == ListingType::Local,
|
||||
connect_clicked => CommunitiesPageInput::FetchCommunities(ListingType::Local, true),
|
||||
},
|
||||
gtk::ToggleButton {
|
||||
set_label: "Subscribed",
|
||||
#[watch]
|
||||
set_active: model.communities_type == ListingType::Subscribed,
|
||||
connect_clicked => CommunitiesPageInput::FetchCommunities(ListingType::Subscribed, true),
|
||||
}
|
||||
},
|
||||
|
||||
gtk::Box {
|
||||
set_spacing: 10,
|
||||
|
||||
gtk::Entry {
|
||||
set_hexpand: true,
|
||||
set_tooltip_text: Some("Search"),
|
||||
set_buffer: &model.community_search_buffer,
|
||||
},
|
||||
gtk::Button {
|
||||
set_label: "Search",
|
||||
connect_clicked => CommunitiesPageInput::FetchCommunities(model.communities_type, true),
|
||||
}
|
||||
},
|
||||
|
||||
#[local_ref]
|
||||
communities_box -> gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 5,
|
||||
},
|
||||
|
||||
gtk::Button {
|
||||
set_label: "More",
|
||||
connect_clicked => CommunitiesPageInput::FetchCommunities(model.communities_type, false),
|
||||
set_margin_top: 10,
|
||||
set_margin_bottom: 10,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn init(
|
||||
_init: Self::Init,
|
||||
root: &Self::Root,
|
||||
sender: ComponentSender<Self>,
|
||||
) -> ComponentParts<Self> {
|
||||
let communities = FactoryVecDeque::new(gtk::Box::default(), sender.output_sender());
|
||||
let community_search_buffer = gtk::EntryBuffer::builder().build();
|
||||
let model = CommunitiesPage {
|
||||
communities,
|
||||
community_search_buffer,
|
||||
communities_page: 1,
|
||||
communities_type: ListingType::Local,
|
||||
};
|
||||
let communities_box = model.communities.widget();
|
||||
let widgets = view_output!();
|
||||
ComponentParts { model, widgets }
|
||||
}
|
||||
|
||||
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
|
||||
match message {
|
||||
CommunitiesPageInput::FetchCommunities(listing_type, remove_previous) => {
|
||||
let query_text = self.community_search_buffer.text().as_str().to_owned();
|
||||
let query = if query_text.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(query_text)
|
||||
};
|
||||
let page = if remove_previous {
|
||||
1
|
||||
} else {
|
||||
self.communities_page + 1
|
||||
};
|
||||
self.communities_page = page;
|
||||
self.communities_type = listing_type;
|
||||
std::thread::spawn(move || {
|
||||
match api::communities::fetch_communities(page, query, Some(listing_type)) {
|
||||
Ok(communities) => {
|
||||
sender.input(CommunitiesPageInput::DoneFetchCommunities(communities));
|
||||
}
|
||||
Err(err) => {
|
||||
let _ = sender.output(crate::AppMsg::ShowMessage(err.to_string()));
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
CommunitiesPageInput::DoneFetchCommunities(communities) => {
|
||||
if self.communities_page == 1 {
|
||||
self.communities.guard().clear();
|
||||
}
|
||||
for community in communities {
|
||||
self.communities.guard().push_back(community);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
pub mod comment_row;
|
||||
pub mod communities_page;
|
||||
pub mod community_page;
|
||||
pub mod community_row;
|
||||
pub mod inbox_page;
|
||||
|
|
110
src/main.rs
110
src/main.rs
|
@ -7,8 +7,8 @@ pub mod util;
|
|||
|
||||
use api::{community::default_community, post::default_post, user::default_person};
|
||||
use components::{
|
||||
communities_page::{CommunitiesPage, CommunitiesPageInput},
|
||||
community_page::{self, CommunityPage},
|
||||
community_row::CommunityRow,
|
||||
inbox_page::{InboxInput, InboxPage},
|
||||
instances_page::{InstancePageInput, InstancesPage},
|
||||
post_page::{self, PostPage},
|
||||
|
@ -24,7 +24,6 @@ use lemmy_api_common::{
|
|||
ListingType,
|
||||
},
|
||||
lemmy_db_views::structs::PostView,
|
||||
lemmy_db_views_actor::structs::CommunityView,
|
||||
person::GetPersonDetailsResponse,
|
||||
post::GetPostResponse,
|
||||
};
|
||||
|
@ -55,18 +54,15 @@ struct App {
|
|||
message: Option<String>,
|
||||
back_queue: Vec<AppMsg>,
|
||||
posts: FactoryVecDeque<PostRow>,
|
||||
communities: FactoryVecDeque<CommunityRow>,
|
||||
instances_page: Controller<InstancesPage>,
|
||||
profile_page: Controller<ProfilePage>,
|
||||
community_page: Controller<CommunityPage>,
|
||||
communities_page: Controller<CommunitiesPage>,
|
||||
post_page: Controller<PostPage>,
|
||||
inbox_page: Controller<InboxPage>,
|
||||
logged_in: bool,
|
||||
current_communities_type: Option<ListingType>,
|
||||
current_posts_type: Option<ListingType>,
|
||||
current_communities_page: i64,
|
||||
current_posts_page: i64,
|
||||
community_search_buffer: gtk::EntryBuffer,
|
||||
about_dialog: Controller<AboutDialog>,
|
||||
}
|
||||
|
||||
|
@ -81,8 +77,6 @@ pub enum AppMsg {
|
|||
DoneChoosingInstance(String),
|
||||
StartFetchPosts(Option<ListingType>, bool),
|
||||
DoneFetchPosts(Vec<PostView>),
|
||||
DoneFetchCommunities(Vec<CommunityView>),
|
||||
FetchCommunities(Option<ListingType>, bool),
|
||||
OpenCommunity(CommunityId),
|
||||
DoneFetchCommunity(GetCommunityResponse),
|
||||
OpenPerson(PersonId),
|
||||
|
@ -90,6 +84,7 @@ pub enum AppMsg {
|
|||
OpenPost(PostId),
|
||||
DoneFetchPost(GetPostResponse),
|
||||
OpenInbox,
|
||||
OpenCommunities,
|
||||
PopBackStack,
|
||||
ShowAbout,
|
||||
}
|
||||
|
@ -124,7 +119,7 @@ impl SimpleComponent for App {
|
|||
},
|
||||
pack_start = >k::Button {
|
||||
set_label: "Communities",
|
||||
connect_clicked => AppMsg::FetchCommunities(None, true),
|
||||
connect_clicked => AppMsg::OpenCommunities,
|
||||
},
|
||||
pack_start = >k::Button {
|
||||
set_label: "Recommended",
|
||||
|
@ -132,12 +127,6 @@ impl SimpleComponent for App {
|
|||
#[watch]
|
||||
set_visible: model.logged_in,
|
||||
},
|
||||
pack_start = >k::Button {
|
||||
set_label: "Joined",
|
||||
connect_clicked => AppMsg::FetchCommunities(Some(ListingType::Subscribed), true),
|
||||
#[watch]
|
||||
set_visible: model.logged_in,
|
||||
},
|
||||
pack_start = >k::Button {
|
||||
set_label: "Inbox",
|
||||
connect_clicked => AppMsg::OpenInbox,
|
||||
|
@ -233,42 +222,8 @@ impl SimpleComponent for App {
|
|||
}
|
||||
},
|
||||
AppState::Communities => gtk::Box {
|
||||
gtk::ScrolledWindow {
|
||||
set_vexpand: true,
|
||||
set_hexpand: true,
|
||||
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 10,
|
||||
|
||||
gtk::Box {
|
||||
set_margin_all: 10,
|
||||
|
||||
gtk::Entry {
|
||||
set_hexpand: true,
|
||||
set_tooltip_text: Some("Search"),
|
||||
set_margin_end: 10,
|
||||
set_buffer: &model.community_search_buffer,
|
||||
},
|
||||
gtk::Button {
|
||||
set_label: "Search",
|
||||
connect_clicked => AppMsg::FetchCommunities(model.current_communities_type, true),
|
||||
}
|
||||
},
|
||||
|
||||
#[local_ref]
|
||||
communities_box -> gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 5,
|
||||
},
|
||||
|
||||
gtk::Button {
|
||||
set_label: "More",
|
||||
connect_clicked => AppMsg::FetchCommunities(model.current_communities_type, false),
|
||||
set_margin_all: 10,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[local_ref]
|
||||
communities_page -> gtk::Box {}
|
||||
}
|
||||
|
||||
AppState::Person => {
|
||||
|
@ -340,7 +295,6 @@ impl SimpleComponent for App {
|
|||
|
||||
// initialize all controllers and factories
|
||||
let posts = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender());
|
||||
let communities = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender());
|
||||
let instances_page = InstancesPage::builder()
|
||||
.launch(())
|
||||
.forward(sender.input_sender(), |msg| msg);
|
||||
|
@ -356,7 +310,9 @@ impl SimpleComponent for App {
|
|||
let inbox_page = InboxPage::builder()
|
||||
.launch(())
|
||||
.forward(sender.input_sender(), |msg| msg);
|
||||
let community_search_buffer = gtk::EntryBuffer::builder().build();
|
||||
let communities_page = CommunitiesPage::builder()
|
||||
.launch(())
|
||||
.forward(sender.input_sender(), |msg| msg);
|
||||
let about_dialog = AboutDialog::builder()
|
||||
.launch(root.toplevel_window().unwrap())
|
||||
.detach();
|
||||
|
@ -366,18 +322,15 @@ impl SimpleComponent for App {
|
|||
back_queue: vec![],
|
||||
logged_in,
|
||||
posts,
|
||||
communities,
|
||||
instances_page,
|
||||
profile_page,
|
||||
community_page,
|
||||
post_page,
|
||||
inbox_page,
|
||||
communities_page,
|
||||
message: None,
|
||||
current_communities_type: None,
|
||||
current_posts_type: None,
|
||||
current_communities_page: 1,
|
||||
current_posts_page: 1,
|
||||
community_search_buffer,
|
||||
about_dialog,
|
||||
};
|
||||
|
||||
|
@ -388,12 +341,12 @@ impl SimpleComponent for App {
|
|||
|
||||
// setup all widgets and different stack pages
|
||||
let posts_box = model.posts.widget();
|
||||
let communities_box = model.communities.widget();
|
||||
let instances_page = model.instances_page.widget();
|
||||
let profile_page = model.profile_page.widget();
|
||||
let community_page = model.community_page.widget();
|
||||
let post_page = model.post_page.widget();
|
||||
let inbox_page = model.inbox_page.widget();
|
||||
let communities_page = model.communities_page.widget();
|
||||
|
||||
let widgets = view_output!();
|
||||
|
||||
|
@ -438,7 +391,7 @@ impl SimpleComponent for App {
|
|||
fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>) {
|
||||
// save the back queue
|
||||
match msg {
|
||||
AppMsg::DoneFetchCommunities(_)
|
||||
AppMsg::OpenCommunities
|
||||
| AppMsg::DoneFetchCommunity(_)
|
||||
| AppMsg::DoneFetchPerson(_)
|
||||
| AppMsg::DoneFetchPost(_)
|
||||
|
@ -506,39 +459,14 @@ impl SimpleComponent for App {
|
|||
self.posts.guard().push_back(post);
|
||||
}
|
||||
}
|
||||
AppMsg::FetchCommunities(listing_type, remove_previous) => {
|
||||
let query_text = self.community_search_buffer.text().as_str().to_owned();
|
||||
let query = if query_text.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(query_text)
|
||||
};
|
||||
AppMsg::OpenCommunities => {
|
||||
self.state = AppState::Communities;
|
||||
let page = if remove_previous {
|
||||
1
|
||||
} else {
|
||||
self.current_communities_page + 1
|
||||
};
|
||||
self.current_communities_page = page;
|
||||
self.current_communities_type = listing_type;
|
||||
std::thread::spawn(move || {
|
||||
let message =
|
||||
match api::communities::fetch_communities(page, query, listing_type) {
|
||||
Ok(communities) => AppMsg::DoneFetchCommunities(communities),
|
||||
Err(err) => AppMsg::ShowMessage(err.to_string()),
|
||||
};
|
||||
sender.input(message);
|
||||
});
|
||||
}
|
||||
|
||||
AppMsg::DoneFetchCommunities(communities) => {
|
||||
self.state = AppState::Communities;
|
||||
if self.current_communities_page == 1 {
|
||||
self.communities.guard().clear();
|
||||
}
|
||||
for community in communities {
|
||||
self.communities.guard().push_back(community);
|
||||
}
|
||||
self.communities_page
|
||||
.sender()
|
||||
.emit(CommunitiesPageInput::FetchCommunities(
|
||||
ListingType::Local,
|
||||
true,
|
||||
));
|
||||
}
|
||||
AppMsg::OpenPerson(person_id) => {
|
||||
self.state = AppState::Loading;
|
||||
|
|
Loading…
Reference in New Issue