Support for commenting on posts
This commit is contained in:
parent
99f35bfe7a
commit
10b5059420
|
@ -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<i32>,
|
||||
auth: Sensitive<String>,
|
||||
) -> Result<CommentResponse, reqwest::Error> {
|
||||
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)
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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<WebImage>,
|
||||
creator_avatar: Controller<WebImage>,
|
||||
community_avatar: Controller<WebImage>,
|
||||
comments: FactoryVecDeque<CommentRow>
|
||||
comments: FactoryVecDeque<CommentRow>,
|
||||
#[allow(dead_code)]
|
||||
create_comment_dialog: Controller<CreatePostDialog>
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -21,7 +23,10 @@ pub enum PostInput {
|
|||
DoneFetchComments(Vec<CommentView>),
|
||||
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()) };
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,20 @@ use relm4::{prelude::*, MessageBroker};
|
|||
use gtk::prelude::*;
|
||||
|
||||
pub static CREATE_POST_DIALOG_BROKER: MessageBroker<DialogMsg> = MessageBroker::new();
|
||||
pub static CREATE_COMMENT_DIALOG_BROKER: MessageBroker<DialogMsg> = 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,6 +47,10 @@ impl SimpleComponent for CreatePostDialog {
|
|||
set_width_request: 600,
|
||||
set_margin_all: 20,
|
||||
|
||||
match model.type_ {
|
||||
DialogType::Post => {
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
gtk::Label {
|
||||
set_halign: gtk::Align::Center,
|
||||
set_valign: gtk::Align::Center,
|
||||
|
@ -50,12 +63,27 @@ impl SimpleComponent for CreatePostDialog {
|
|||
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();
|
||||
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<Self>,
|
||||
) -> ComponentParts<Self> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue