diff --git a/src/api/comment.rs b/src/api/comment.rs index 17e22f0..40c531b 100644 --- a/src/api/comment.rs +++ b/src/api/comment.rs @@ -1,17 +1,18 @@ -use lemmy_api_common::{sensitive::Sensitive, comment::{CommentResponse, CreateComment}, lemmy_db_schema::newtypes::{PostId, CommentId}}; +use lemmy_api_common::{comment::{CommentResponse, CreateComment}, lemmy_db_schema::newtypes::{PostId, CommentId}}; + +use crate::util; pub fn create_comment( post_id: i32, content: String, parent_id: Option, - auth: Sensitive, ) -> Result { let params = CreateComment { post_id: PostId(post_id), content, parent_id: parent_id.map(CommentId), - auth, + auth: util::get_auth_token().unwrap(), ..Default::default() }; super::post("/comment", ¶ms) diff --git a/src/components/community_page.rs b/src/components/community_page.rs index 119a289..59cc651 100644 --- a/src/components/community_page.rs +++ b/src/components/community_page.rs @@ -1,4 +1,4 @@ -use crate::{util::markdown_to_pango_markup, dialogs::create_post::{CreatePostDialog, CREATE_POST_DIALOG_BROKER, DialogMsg, CreatePostDialogOutput}}; +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 relm4::{prelude::*, factory::FactoryVecDeque}; use gtk::prelude::*; @@ -101,9 +101,9 @@ impl SimpleComponent for CommunityPage { let dialog = CreatePostDialog::builder() .transient_for(root) - .launch_with_broker((), &CREATE_POST_DIALOG_BROKER) + .launch_with_broker(DialogType::Post, &CREATE_POST_DIALOG_BROKER) .forward(sender.input_sender(), |msg| match msg { - CreatePostDialogOutput::CreatePostRequest(name, body) => CommunityInput::CreatePostRequest(name, body) + CreatePostDialogOutput::CreateRequest(name, body) => CommunityInput::CreatePostRequest(name, body) }); let model = CommunityPage { info: init, avatar, posts, create_post_dialog: dialog }; diff --git a/src/components/post_page.rs b/src/components/post_page.rs index 04316e1..0ebb012 100644 --- a/src/components/post_page.rs +++ b/src/components/post_page.rs @@ -1,9 +1,9 @@ -use lemmy_api_common::{lemmy_db_views::structs::{CommentView}, post::GetPostResponse}; +use lemmy_api_common::{lemmy_db_views::structs::CommentView, post::GetPostResponse}; use relm4::{prelude::*, factory::FactoryVecDeque}; use gtk::prelude::*; use relm4_components::web_image::WebImage; -use crate::{api, util::{get_web_image_msg, get_web_image_url, markdown_to_pango_markup}}; +use crate::{api, util::{get_web_image_msg, get_web_image_url, markdown_to_pango_markup}, dialogs::create_post::{CreatePostDialog, CreatePostDialogOutput, DialogMsg, CREATE_COMMENT_DIALOG_BROKER, DialogType}}; use super::comment_row::CommentRow; @@ -12,7 +12,9 @@ pub struct PostPage { image: Controller, creator_avatar: Controller, community_avatar: Controller, - comments: FactoryVecDeque + comments: FactoryVecDeque, + #[allow(dead_code)] + create_comment_dialog: Controller } #[derive(Debug)] @@ -21,7 +23,10 @@ pub enum PostInput { DoneFetchComments(Vec), OpenPerson, OpenCommunity, - OpenLink + OpenLink, + OpenCreateCommentDialog, + CreateCommentRequest(String), + CreatedComment(CommentView) } #[relm4::component(pub)] @@ -123,6 +128,12 @@ impl SimpleComponent for PostPage { #[watch] set_text: &format!("{} score", model.info.post_view.counts.score), }, + + gtk::Button { + set_label: "Comment", + set_margin_start: 10, + connect_clicked => PostInput::OpenCreateCommentDialog, + } }, gtk::Separator {}, @@ -144,7 +155,13 @@ impl SimpleComponent for PostPage { let comments = FactoryVecDeque::new(gtk::Box::default(), sender.output_sender()); let creator_avatar = WebImage::builder().launch("".to_string()).detach(); let community_avatar = WebImage::builder().launch("".to_string()).detach(); - let model = PostPage { info: init, image, comments, creator_avatar, community_avatar }; + let dialog = CreatePostDialog::builder() + .transient_for(root) + .launch_with_broker(DialogType::Comment, &CREATE_COMMENT_DIALOG_BROKER) + .forward(sender.input_sender(), |msg| match msg { + CreatePostDialogOutput::CreateRequest(_name, body) => PostInput::CreateCommentRequest(body) + }); + let model = PostPage { info: init, image, comments, creator_avatar, community_avatar, create_comment_dialog: dialog, }; let image = model.image.widget(); let comments = model.comments.widget(); @@ -199,6 +216,22 @@ impl SimpleComponent for PostPage { if link.is_empty() { return; } gtk::show_uri(None::<&relm4::gtk::Window>, &link, 0); } + PostInput::OpenCreateCommentDialog => { + CREATE_COMMENT_DIALOG_BROKER.send(DialogMsg::Show) + } + PostInput::CreatedComment(comment) => { + self.comments.guard().push_front(comment); + } + PostInput::CreateCommentRequest(body) => { + let id = self.info.post_view.post.id.0; + std::thread::spawn(move || { + let message = match api::comment::create_comment(id, body, None) { + Ok(comment) => Some(PostInput::CreatedComment(comment.comment_view)), + Err(err) => { println!("{}", err.to_string()); None } + }; + if message.is_some() { sender.input(message.unwrap()) }; + }); + } } } } diff --git a/src/dialogs/create_post.rs b/src/dialogs/create_post.rs index 20e0868..ce4f110 100644 --- a/src/dialogs/create_post.rs +++ b/src/dialogs/create_post.rs @@ -2,11 +2,20 @@ use relm4::{prelude::*, MessageBroker}; use gtk::prelude::*; pub static CREATE_POST_DIALOG_BROKER: MessageBroker = MessageBroker::new(); +pub static CREATE_COMMENT_DIALOG_BROKER: MessageBroker = MessageBroker::new(); + pub struct CreatePostDialog { + type_: DialogType, visible: bool, } +#[derive(Debug, Clone, Copy)] +pub enum DialogType { + Post, + Comment +} + #[derive(Debug)] pub enum DialogMsg { Show, @@ -16,12 +25,12 @@ pub enum DialogMsg { #[derive(Debug)] pub enum CreatePostDialogOutput { - CreatePostRequest(String, String) + CreateRequest(String, String) } #[relm4::component(pub)] impl SimpleComponent for CreatePostDialog { - type Init = (); + type Init = DialogType; type Input = DialogMsg; type Output = CreatePostDialogOutput; @@ -38,24 +47,43 @@ impl SimpleComponent for CreatePostDialog { set_width_request: 600, set_margin_all: 20, - gtk::Label { - set_halign: gtk::Align::Center, - set_valign: gtk::Align::Center, - set_label: "Create post", - add_css_class: "font-bold" - }, - #[name(name)] - gtk::Entry { - set_placeholder_text: Some("Title"), - set_margin_top: 10, - set_margin_bottom: 10, + match model.type_ { + DialogType::Post => { + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + gtk::Label { + set_halign: gtk::Align::Center, + set_valign: gtk::Align::Center, + set_label: "Create post", + add_css_class: "font-bold" + }, + #[name(name)] + gtk::Entry { + set_placeholder_text: Some("Title"), + set_margin_top: 10, + set_margin_bottom: 10, + }, + } + } + DialogType::Comment => { + gtk::Box { + gtk::Label { + set_halign: gtk::Align::Center, + set_valign: gtk::Align::Center, + set_label: "Create comment", + add_css_class: "font-bold" + }, + } + } }, gtk::Label { set_text: "Body:", + set_halign: gtk::Align::Start, }, #[name(body)] gtk::TextView { set_editable: true, + set_margin_top: 5, set_margin_bottom: 10, set_vexpand: true, }, @@ -74,8 +102,16 @@ impl SimpleComponent for CreatePostDialog { let body_buffer = body.buffer(); let (start, end) = &body_buffer.bounds(); let body = body_buffer.text(start, end, true).to_string(); - if name.is_empty() || body.is_empty() { return; } - sender.input(DialogMsg::Okay(name, body)) + match model.type_ { + DialogType::Post => { + if name.is_empty() || body.is_empty() { return; } + sender.input(DialogMsg::Okay(name, body)) + } + DialogType::Comment => { + if name.is_empty() { return; } + sender.input(DialogMsg::Okay(name, body)) + } + } }, } } @@ -89,11 +125,11 @@ impl SimpleComponent for CreatePostDialog { } fn init( - _init: Self::Init, + init: Self::Init, root: &Self::Root, sender: ComponentSender, ) -> ComponentParts { - let model = CreatePostDialog { visible: false }; + let model = CreatePostDialog { type_: init, visible: false }; let widgets = view_output!(); ComponentParts { model, widgets } } @@ -103,7 +139,7 @@ impl SimpleComponent for CreatePostDialog { DialogMsg::Show => self.visible = true, DialogMsg::Hide => self.visible = false, DialogMsg::Okay(name, body) => { - let _ = sender.output(CreatePostDialogOutput::CreatePostRequest(name, body)); + let _ = sender.output(CreatePostDialogOutput::CreateRequest(name, body)); self.visible = false; } }