235 lines
7.9 KiB
Rust
235 lines
7.9 KiB
Rust
use crate::{
|
|
apub::actions::{CreateComment, DeleteComment, DeleteReact, UpdateComment},
|
|
Action, Context, Error, Outbound, Required,
|
|
};
|
|
|
|
impl Action for CreateComment {
|
|
fn perform(&self, ctx: &Context) -> Result<Option<Box<dyn Outbound + Send>>, Error> {
|
|
let submission = ctx
|
|
.store
|
|
.submissions
|
|
.by_id(self.submission_id)?
|
|
.req("submission by id")?;
|
|
|
|
let submissioner_id = submission.profile_id();
|
|
|
|
ctx.check_block(submissioner_id, self.profile_id)?;
|
|
|
|
let comment_data = if let Some(comment_id) = self.comment_id {
|
|
let commenter_id = ctx
|
|
.store
|
|
.comments
|
|
.by_id(comment_id)?
|
|
.req("comment by id")?
|
|
.profile_id();
|
|
|
|
ctx.check_block(commenter_id, self.profile_id)?;
|
|
|
|
Some(commenter_id)
|
|
} else {
|
|
None
|
|
};
|
|
|
|
let mut changes =
|
|
ctx.store
|
|
.comments
|
|
.create(ctx, self.submission_id, self.profile_id, self.comment_id);
|
|
|
|
changes.published(self.published);
|
|
|
|
if let Some(updated) = self.updated {
|
|
changes.updated(updated);
|
|
}
|
|
if let Some(body) = &self.body {
|
|
changes.body(body);
|
|
}
|
|
if let Some(body_source) = &self.body_source {
|
|
changes.body_source(body_source);
|
|
}
|
|
|
|
let comment = changes.save()??;
|
|
|
|
if let Some(apub_id) = &self.note_apub_id {
|
|
ctx.apub.comment(apub_id, comment.id())?;
|
|
}
|
|
|
|
if let Some(commenter_id) = comment_data {
|
|
if commenter_id != submissioner_id && commenter_id != self.profile_id {
|
|
if let Ok(true) = ctx.is_local(commenter_id) {
|
|
ctx.store
|
|
.view
|
|
.comments
|
|
.new(commenter_id, comment.id(), self.published);
|
|
}
|
|
}
|
|
};
|
|
|
|
if let Ok(true) = ctx.is_local(submissioner_id) {
|
|
if submissioner_id != self.profile_id {
|
|
ctx.store
|
|
.view
|
|
.comments
|
|
.new(submissioner_id, comment.id(), self.published);
|
|
}
|
|
}
|
|
|
|
if !submission.is_local_only() {
|
|
if ctx.is_local(self.profile_id)? && ctx.is_local(submissioner_id)? {
|
|
return Ok(Some(Box::new(
|
|
crate::apub::results::AnnounceCommentCreated {
|
|
submissioner_id,
|
|
comment_id: comment.id(),
|
|
},
|
|
)));
|
|
} else if ctx.is_local(self.profile_id)? {
|
|
return Ok(Some(Box::new(crate::apub::results::CommentCreated {
|
|
comment_id: comment.id(),
|
|
})));
|
|
} else if ctx.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(),
|
|
submissioner_id,
|
|
})));
|
|
}
|
|
}
|
|
} else {
|
|
return Ok(Some(Box::new(crate::apub::results::LocalCommentCreated {
|
|
comment_id: comment.id(),
|
|
})));
|
|
}
|
|
|
|
Ok(None)
|
|
}
|
|
}
|
|
|
|
impl Action for UpdateComment {
|
|
fn perform(&self, ctx: &Context) -> Result<Option<Box<dyn Outbound + Send>>, Error> {
|
|
let comment = ctx
|
|
.store
|
|
.comments
|
|
.by_id(self.comment_id)?
|
|
.req("comment by id")?;
|
|
|
|
if comment.deleted() {
|
|
return Err(Error::Deleted);
|
|
}
|
|
|
|
let mut changes = comment.update(ctx);
|
|
changes.updated(self.updated);
|
|
if let Some(body) = &self.body {
|
|
changes.body(body);
|
|
}
|
|
if let Some(body_source) = &self.body_source {
|
|
changes.body_source(body_source);
|
|
}
|
|
let comment = if changes.any_changes() {
|
|
changes.save()??
|
|
} else {
|
|
comment
|
|
};
|
|
|
|
let submission = ctx
|
|
.store
|
|
.submissions
|
|
.by_id(comment.submission_id())?
|
|
.req("submission by id")?;
|
|
|
|
let submissioner_id = submission.profile_id();
|
|
let is_local_only = submission.is_local_only();
|
|
|
|
if !is_local_only {
|
|
if ctx.is_local(comment.profile_id())? && ctx.is_local(submissioner_id)? {
|
|
return Ok(Some(Box::new(
|
|
crate::apub::results::AnnounceCommentUpdated {
|
|
submissioner_id,
|
|
comment_id: comment.id(),
|
|
},
|
|
)));
|
|
} else if ctx.is_local(comment.profile_id())? {
|
|
return Ok(Some(Box::new(crate::apub::results::CommentUpdated {
|
|
comment_id: comment.id(),
|
|
})));
|
|
} else if ctx.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(),
|
|
submissioner_id,
|
|
})));
|
|
}
|
|
}
|
|
} else {
|
|
return Ok(Some(Box::new(crate::apub::results::LocalCommentUpdated {
|
|
comment_id: comment.id(),
|
|
})));
|
|
}
|
|
|
|
Ok(None)
|
|
}
|
|
}
|
|
|
|
fn delete_react(react_id: uuid::Uuid, ctx: &Context) -> Result<(), Error> {
|
|
Action::perform(&DeleteReact { react_id }, ctx)?;
|
|
Ok(())
|
|
}
|
|
|
|
impl Action for DeleteComment {
|
|
fn perform(&self, ctx: &Context) -> Result<Option<Box<dyn Outbound + Send>>, Error> {
|
|
let comment_id = self.comment_id;
|
|
let opt = ctx.store.comments.delete(comment_id)?;
|
|
|
|
if let Some(undo_comment) = opt {
|
|
ctx.store.view.comments.remove(comment_id);
|
|
|
|
let note_apub_id = ctx
|
|
.apub
|
|
.apub_for_comment(comment_id)?
|
|
.req("apub id for comment id")?;
|
|
ctx.apub.delete_object(¬e_apub_id)?;
|
|
let comment_id = undo_comment.0.id();
|
|
let ctx_clone = ctx.clone();
|
|
|
|
ctx.spawn_blocking(move || {
|
|
for react_id in ctx_clone.store.reacts.for_comment(comment_id) {
|
|
if let Err(e) = delete_react(react_id, &ctx_clone) {
|
|
log::error!("Error deleing react {}: {}", react_id, e);
|
|
}
|
|
}
|
|
});
|
|
|
|
let submissioner_id = ctx
|
|
.store
|
|
.submissions
|
|
.by_id(undo_comment.0.submission_id())?
|
|
.req("submission by id")?
|
|
.profile_id();
|
|
|
|
if ctx.is_local(undo_comment.0.profile_id())? && ctx.is_local(submissioner_id)? {
|
|
return Ok(Some(Box::new(
|
|
crate::apub::results::AnnounceCommentDeleted {
|
|
note_apub_id,
|
|
submissioner_id,
|
|
commenter_id: undo_comment.0.profile_id(),
|
|
},
|
|
)));
|
|
} else if ctx.is_local(undo_comment.0.profile_id())? {
|
|
return Ok(Some(Box::new(crate::apub::results::CommentDeleted {
|
|
note_apub_id,
|
|
commenter_id: undo_comment.0.profile_id(),
|
|
submission_id: undo_comment.0.submission_id(),
|
|
reply_to_id: undo_comment.0.comment_id(),
|
|
})));
|
|
} else if ctx.is_local(submissioner_id)? {
|
|
if let Some(apub_id) = &self.delete_apub_id {
|
|
return Ok(Some(Box::new(crate::apub::results::RemoteCommentDeleted {
|
|
delete_apub_id: apub_id.to_owned(),
|
|
submissioner_id,
|
|
})));
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(None)
|
|
}
|
|
}
|