diff --git a/src/api/community.rs b/src/api/community.rs index 6c703dc..bd422a3 100644 --- a/src/api/community.rs +++ b/src/api/community.rs @@ -12,7 +12,7 @@ pub fn get_community(name: String) -> std::result::Result Result { diff --git a/src/components/community_page.rs b/src/components/community_page.rs index 6ae7f40..13b5003 100644 --- a/src/components/community_page.rs +++ b/src/components/community_page.rs @@ -1,5 +1,5 @@ use crate::{util::markdown_to_pango_markup, dialogs::create_post::{CreatePostDialog, CREATE_POST_DIALOG_BROKER, DialogMsg, CreatePostDialogOutput, DialogType}}; -use lemmy_api_common::{community::GetCommunityResponse, lemmy_db_views::structs::PostView}; +use lemmy_api_common::{lemmy_db_views::structs::PostView, lemmy_db_views_actor::structs::CommunityView, lemmy_db_schema::SubscribedType}; use relm4::{prelude::*, factory::FactoryVecDeque}; use gtk::prelude::*; use relm4_components::web_image::WebImage; @@ -9,25 +9,27 @@ use crate::{api, util::get_web_image_msg}; use super::post_row::PostRow; pub struct CommunityPage { - info: GetCommunityResponse, + info: CommunityView, avatar: Controller, posts: FactoryVecDeque, #[allow(dead_code)] - create_post_dialog: Controller + create_post_dialog: Controller, } #[derive(Debug)] pub enum CommunityInput { - UpdateCommunity(GetCommunityResponse), + UpdateCommunity(CommunityView), DoneFetchPosts(Vec), OpenCreatePostDialog, CreatePostRequest(String, String), - CreatedPost(PostView) + CreatedPost(PostView), + ToggleSubscription, + UpdateSubscriptionState(SubscribedType) } #[relm4::component(pub)] impl SimpleComponent for CommunityPage { - type Init = GetCommunityResponse; + type Init = CommunityView; type Input = CommunityInput; type Output = crate::AppMsg; @@ -48,29 +50,47 @@ impl SimpleComponent for CommunityPage { }, gtk::Label { #[watch] - set_text: &model.info.community_view.community.name, + set_text: &model.info.community.name, add_css_class: "font-very-bold", }, gtk::Label { #[watch] - set_markup: &markdown_to_pango_markup(model.info.clone().community_view.community.description.unwrap_or("".to_string())), + set_markup: &markdown_to_pango_markup(model.info.clone().community.description.unwrap_or("".to_string())), set_use_markup: true, }, - gtk::Label { - #[watch] - set_text: &format!("{} subscribers", model.info.community_view.counts.subscribers), - }, - gtk::Box { set_orientation: gtk::Orientation::Horizontal, - set_margin_top: 10, - set_margin_bottom: 10, - set_hexpand: false, set_halign: gtk::Align::Center, + set_margin_bottom: 10, gtk::Label { #[watch] - set_text: &format!("{} posts, {} comments", model.info.community_view.counts.posts, model.info.community_view.counts.comments), + set_text: &format!("{} subscribers", model.info.counts.subscribers), + set_margin_end: 10, + }, + match model.info.subscribed { + SubscribedType::Subscribed => { + gtk::Button { + set_label: "Unsubscribe", + connect_clicked => CommunityInput::ToggleSubscription, + } + } + SubscribedType::NotSubscribed => { + gtk::Button { + set_label: "Subscribe", + connect_clicked => CommunityInput::ToggleSubscription, + } + } + SubscribedType::Pending => { + gtk::Label { + set_label: "Subscription pending", + } + } + }, + gtk::Label { + #[watch] + set_text: &format!("{} posts, {} comments", model.info.counts.posts, model.info.counts.comments), + set_margin_start: 10, }, gtk::Button { @@ -118,12 +138,12 @@ impl SimpleComponent for CommunityPage { match message { CommunityInput::UpdateCommunity(community) => { self.info = community.clone(); - self.avatar.emit(get_web_image_msg(community.community_view.community.icon)); + self.avatar.emit(get_web_image_msg(community.community.icon)); self.posts.guard().clear(); std::thread::spawn(move || { - if community.community_view.counts.posts == 0 { return; } - let community_posts = api::posts::list_posts(1, Some(community.community_view.community.name), None); + if community.counts.posts == 0 { return; } + let community_posts = api::posts::list_posts(1, Some(community.community.name), None); if let Ok(community_posts) = community_posts { sender.input(CommunityInput::DoneFetchPosts(community_posts)); } @@ -141,7 +161,7 @@ impl SimpleComponent for CommunityPage { self.posts.guard().push_front(post); } CommunityInput::CreatePostRequest(name, body) => { - let id = self.info.community_view.community.id.0.clone(); + let id = self.info.community.id.0.clone(); std::thread::spawn(move || { let message = match api::post::create_post(name, body, id) { Ok(post) => Some(CommunityInput::CreatedPost(post.post_view)), @@ -150,6 +170,23 @@ impl SimpleComponent for CommunityPage { if message.is_some() { sender.input(message.unwrap()) }; }); } + CommunityInput::ToggleSubscription => { + let community_id = self.info.community.id.0; + let new_state = match self.info.subscribed { + SubscribedType::NotSubscribed => true, + _ => false + }; + std::thread::spawn(move || { + let message = match api::community::follow_community(community_id, new_state) { + Ok(community) => Some(CommunityInput::UpdateSubscriptionState(community.community_view.subscribed)), + Err(err) => { println!("{}", err.to_string()); None } + }; + if message.is_some() { sender.input(message.unwrap()) }; + }); + } + CommunityInput::UpdateSubscriptionState(state) => { + self.info.subscribed = state; + } } } } diff --git a/src/main.rs b/src/main.rs index fa3cac3..9c08e94 100644 --- a/src/main.rs +++ b/src/main.rs @@ -272,7 +272,7 @@ impl SimpleComponent for App { let posts = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender()); let communities = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender()); let profile_page = ProfilePage::builder().launch(default_person()).forward(sender.input_sender(), |msg| msg); - let community_page = CommunityPage::builder().launch(default_community()).forward(sender.input_sender(), |msg| msg); + let community_page = CommunityPage::builder().launch(default_community().community_view).forward(sender.input_sender(), |msg| msg); let post_page = PostPage::builder().launch(default_post()).forward(sender.input_sender(), |msg| msg); let model = App { state, posts, communities, profile_page, community_page, post_page, message: None, latest_action: None }; @@ -383,7 +383,7 @@ impl SimpleComponent for App { }); } AppMsg::DoneFetchCommunity(community) => { - self.community_page.sender().emit(community_page::CommunityInput::UpdateCommunity(community)); + self.community_page.sender().emit(community_page::CommunityInput::UpdateCommunity(community.community_view)); self.state = AppState::Community; } AppMsg::OpenPost(post_id) => {