156 lines
5.7 KiB
Rust
156 lines
5.7 KiB
Rust
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,
|
|
connect_activate => CommunitiesPageInput::FetchCommunities(model.communities_type, true),
|
|
},
|
|
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) => {
|
|
sender
|
|
.output_sender()
|
|
.emit(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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|