cob: Move comment reactions to comment
To simplify the code, we move comment reactions to the comment struct itself.
This commit is contained in:
parent
8b010c27a2
commit
e4ab523669
|
|
@ -11,7 +11,7 @@ use radicle::cob::patch::Merge;
|
|||
use radicle::cob::patch::Review;
|
||||
use radicle::cob::patch::{Patch, PatchId};
|
||||
use radicle::cob::thread;
|
||||
use radicle::cob::thread::{CommentId, Thread};
|
||||
use radicle::cob::thread::CommentId;
|
||||
use radicle::cob::{ActorId, Author, Reaction, Timestamp};
|
||||
use radicle::git::RefString;
|
||||
use radicle::node::AliasStore;
|
||||
|
|
@ -105,7 +105,7 @@ pub(crate) fn issue(id: IssueId, issue: Issue, aliases: &impl AliasStore) -> Val
|
|||
"assignees": issue.assigned().collect::<Vec<_>>(),
|
||||
"discussion": issue
|
||||
.comments()
|
||||
.map(|(id, comment)| Comment::new(id, comment, issue.thread(), aliases))
|
||||
.map(|(id, comment)| Comment::new(id, comment, aliases))
|
||||
.collect::<Vec<_>>(),
|
||||
"tags": issue.tags().collect::<Vec<_>>(),
|
||||
})
|
||||
|
|
@ -136,7 +136,7 @@ pub(crate) fn patch(
|
|||
"oid": rev.head(),
|
||||
"refs": get_refs(repo, patch.author().id(), &rev.head()).unwrap_or(vec![]),
|
||||
"discussions": rev.discussion().comments()
|
||||
.map(|(id, comment)| Comment::new(id, comment, rev.discussion(), aliases))
|
||||
.map(|(id, comment)| Comment::new(id, comment, aliases))
|
||||
.collect::<Vec<_>>(),
|
||||
"timestamp": rev.timestamp(),
|
||||
"reviews": rev.reviews().map(|(nid, _review)| review(nid, aliases.alias(nid), _review)).collect::<Vec<_>>(),
|
||||
|
|
@ -245,18 +245,13 @@ struct Comment<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Comment<'a> {
|
||||
fn new(
|
||||
id: &'a CommentId,
|
||||
comment: &'a thread::Comment,
|
||||
thread: &'a Thread,
|
||||
aliases: &impl AliasStore,
|
||||
) -> Self {
|
||||
fn new(id: &'a CommentId, comment: &'a thread::Comment, aliases: &impl AliasStore) -> Self {
|
||||
let comment_author = Author::new(comment.author());
|
||||
Self {
|
||||
id: *id,
|
||||
author: author(&comment_author, aliases.alias(comment_author.id())),
|
||||
body: comment.body(),
|
||||
reactions: thread.reactions(id).collect::<Vec<_>>(),
|
||||
reactions: comment.reactions().collect::<Vec<_>>(),
|
||||
timestamp: comment.timestamp(),
|
||||
reply_to: comment.reply_to(),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -836,7 +836,7 @@ mod test {
|
|||
|
||||
let id = issue.id;
|
||||
let issue = issues.get(&id).unwrap().unwrap();
|
||||
let (_, r) = issue.reactions(&comment).next().unwrap();
|
||||
let (_, r) = issue.comment(&comment).unwrap().reactions().next().unwrap();
|
||||
|
||||
assert_eq!(r, &reaction);
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ pub struct Comment {
|
|||
author: ActorId,
|
||||
/// The comment body.
|
||||
edits: GMap<Lamport, Max<Edit>>,
|
||||
/// Reactions to this comment.
|
||||
reactions: LWWSet<(ActorId, Reaction)>,
|
||||
/// Comment this is a reply to.
|
||||
/// Should always be set, except for the root comment.
|
||||
reply_to: Option<CommentId>,
|
||||
|
|
@ -78,6 +80,7 @@ impl Comment {
|
|||
|
||||
Self {
|
||||
author,
|
||||
reactions: LWWSet::default(),
|
||||
edits: GMap::singleton(Lamport::initial(), Max::from(edit)),
|
||||
reply_to,
|
||||
}
|
||||
|
|
@ -124,6 +127,11 @@ impl Comment {
|
|||
pub fn edit(&mut self, clock: Lamport, body: String, timestamp: Timestamp) {
|
||||
self.edits.insert(clock, Edit { body, timestamp }.into())
|
||||
}
|
||||
|
||||
/// Comment reactions.
|
||||
pub fn reactions(&self) -> impl Iterator<Item = (&ActorId, &Reaction)> {
|
||||
self.reactions.iter().map(|(a, r)| (a, r))
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Comment {
|
||||
|
|
@ -175,16 +183,13 @@ impl From<Action> for nonempty::NonEmpty<Action> {
|
|||
pub struct Thread {
|
||||
/// The comments under the thread.
|
||||
comments: GMap<CommentId, Redactable<Comment>>,
|
||||
/// Reactions to changes.
|
||||
reactions: GMap<CommentId, LWWSet<(ActorId, Reaction), Lamport>>,
|
||||
/// Comment timeline.
|
||||
timeline: GSet<(Lamport, EntryId)>,
|
||||
timeline: GSet<(Lamport, CommentId)>,
|
||||
}
|
||||
|
||||
impl Semilattice for Thread {
|
||||
fn merge(&mut self, other: Self) {
|
||||
self.comments.merge(other.comments);
|
||||
self.reactions.merge(other.reactions);
|
||||
self.timeline.merge(other.timeline);
|
||||
}
|
||||
}
|
||||
|
|
@ -193,7 +198,6 @@ impl Thread {
|
|||
pub fn new(id: CommentId, comment: Comment) -> Self {
|
||||
Self {
|
||||
comments: GMap::singleton(id, Redactable::Present(comment)),
|
||||
reactions: GMap::default(),
|
||||
timeline: GSet::default(),
|
||||
}
|
||||
}
|
||||
|
|
@ -244,17 +248,6 @@ impl Thread {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn reactions<'a>(
|
||||
&'a self,
|
||||
to: &'a CommentId,
|
||||
) -> impl Iterator<Item = (&ActorId, &Reaction)> {
|
||||
self.reactions
|
||||
.get(to)
|
||||
.into_iter()
|
||||
.flat_map(move |rs| rs.iter())
|
||||
.map(|(a, r)| (a, r))
|
||||
}
|
||||
|
||||
pub fn comments(&self) -> impl DoubleEndedIterator<Item = (&CommentId, &Comment)> + '_ {
|
||||
self.timeline.iter().filter_map(|(_, id)| {
|
||||
self.comments
|
||||
|
|
@ -335,14 +328,17 @@ impl cob::store::FromHistory for Thread {
|
|||
active,
|
||||
} => {
|
||||
let key = (op.author, reaction);
|
||||
let reactions = if active {
|
||||
LWWSet::singleton(key, op.clock)
|
||||
if let Some(redactable) = self.comments.get_mut(&to) {
|
||||
if let Redactable::Present(comment) = redactable {
|
||||
if active {
|
||||
comment.reactions.insert(key, op.clock);
|
||||
} else {
|
||||
comment.reactions.remove(key, op.clock);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let mut set = LWWSet::default();
|
||||
set.remove(key, op.clock);
|
||||
set
|
||||
};
|
||||
self.reactions.insert(to, reactions);
|
||||
return Err(Error::Missing(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue