hyaenidae/profiles/src/apub/actions/comment.rs

170 lines
5.2 KiB
Rust

use crate::{
apub::actions::{AnnounceComment, CreateComment, DeleteComment, DeleteReact, UpdateComment},
Action, Context, Error, Outbound, Required,
};
impl Action for CreateComment {
fn perform(&self, context: &Context) -> Result<Option<Box<dyn Outbound + Send>>, Error> {
let submissioner_id = context
.store
.submissions
.by_id(self.submission_id)?
.req()?
.profile_id();
context.check_block(submissioner_id, self.profile_id)?;
let comment_data = if let Some(comment_id) = self.comment_id {
let commenter_id = context
.store
.comments
.by_id(comment_id)?
.req()?
.profile_id();
context.check_block(commenter_id, self.profile_id)?;
Some(commenter_id)
} else {
None
};
let comment = context.store.comments.create(
self.submission_id,
self.profile_id,
self.comment_id,
&self.body,
self.published,
)?;
if let Some(apub_id) = &self.note_apub_id {
context.apub.comment(apub_id, comment.id())?;
}
if let Some(commenter_id) = comment_data {
if let Ok(true) = context.is_local(commenter_id) {
context
.store
.view
.comments
.new(commenter_id, comment.id(), self.published);
}
};
if let Ok(true) = context.is_local(submissioner_id) {
context
.store
.view
.comments
.new(submissioner_id, comment.id(), self.published);
}
if context.is_local(self.profile_id)? {
return Ok(Some(Box::new(crate::apub::results::CommentCreated {
comment_id: comment.id(),
})));
}
if context.is_local(submissioner_id)? {
if let Some(apub_id) = &self.note_apub_id {
return Ok(Some(Box::new(crate::apub::results::RemoteCommentCreated {
note_apub_id: apub_id.clone(),
profile_id: submissioner_id,
})));
}
}
Ok(None)
}
}
impl Action for AnnounceComment {
fn perform(&self, _: &Context) -> Result<Option<Box<dyn Outbound + Send>>, Error> {
Ok(None)
}
}
impl Action for UpdateComment {
fn perform(&self, context: &Context) -> Result<Option<Box<dyn Outbound + Send>>, Error> {
let comment = context.store.comments.by_id(self.comment_id)?.req()?;
let mut changes = comment.update();
if let Some(body) = &self.body {
changes.body(body);
}
context.store.comments.update(&changes)?;
if context.is_local(comment.profile_id())? {
return Ok(Some(Box::new(crate::apub::results::CommentUpdated {
comment_id: comment.id(),
})));
}
let submissioner_id = context
.store
.submissions
.by_id(comment.submission_id())?
.req()?
.profile_id();
if context.is_local(submissioner_id)? {
if let Some(apub_id) = &self.update_apub_id {
return Ok(Some(Box::new(crate::apub::results::RemoteCommentUpdated {
update_apub_id: apub_id.to_owned(),
profile_id: submissioner_id,
})));
}
}
Ok(None)
}
}
fn delete_react(react_id: uuid::Uuid, context: &Context) -> Result<(), Error> {
Action::perform(&DeleteReact { react_id }, context)?;
Ok(())
}
impl Action for DeleteComment {
fn perform(&self, context: &Context) -> Result<Option<Box<dyn Outbound + Send>>, Error> {
let opt = context.store.comments.delete(self.comment_id)?;
context.store.view.comments.remove(self.comment_id);
context.apub.delete_object(&self.note_apub_id)?;
if let Some(undo_comment) = opt {
let comment_id = undo_comment.0.id();
let context_clone = context.clone();
context.spawn_blocking(move || {
for react_id in context_clone.store.reacts.for_comment(comment_id) {
if let Err(e) = delete_react(react_id, &context_clone) {
log::error!("Error deleing react {}: {}", react_id, e);
}
}
});
if context.is_local(undo_comment.0.profile_id())? {
return Ok(Some(Box::new(crate::apub::results::CommentCreated {
comment_id: undo_comment.0.id(),
})));
}
let submissioner_id = context
.store
.submissions
.by_id(undo_comment.0.submission_id())?
.req()?
.profile_id();
if context.is_local(submissioner_id)? {
return Ok(Some(Box::new(crate::apub::results::RemoteCommentCreated {
note_apub_id: self.note_apub_id.clone(),
profile_id: submissioner_id,
})));
}
}
Ok(None)
}
}