radicle: Add `Vec<Edit>` to revision description
This allows us to have embeds on a patch revision, and eventually also show the edits that have been made to a revision description.
This commit is contained in:
parent
2dea54c6ee
commit
a3a8060e5c
|
|
@ -44,7 +44,7 @@ pub fn run(
|
||||||
tx.edit(t, target)?;
|
tx.edit(t, target)?;
|
||||||
}
|
}
|
||||||
if let Some(d) = description {
|
if let Some(d) = description {
|
||||||
tx.edit_revision(root, d)?;
|
tx.edit_revision(root, d, Vec::default())?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ use std::ops::Deref;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use amplify::Wrapper;
|
use amplify::Wrapper;
|
||||||
|
use nonempty::NonEmpty;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use serde::ser::SerializeStruct;
|
use serde::ser::SerializeStruct;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
@ -17,7 +18,7 @@ use crate::cob::store::Transaction;
|
||||||
use crate::cob::store::{Cob, CobAction};
|
use crate::cob::store::{Cob, CobAction};
|
||||||
use crate::cob::thread;
|
use crate::cob::thread;
|
||||||
use crate::cob::thread::Thread;
|
use crate::cob::thread::Thread;
|
||||||
use crate::cob::thread::{Comment, CommentId, Reactions};
|
use crate::cob::thread::{Comment, CommentId, Edit, Reactions};
|
||||||
use crate::cob::{op, store, ActorId, Embed, EntryId, ObjectId, TypeName, Uri};
|
use crate::cob::{op, store, ActorId, Embed, EntryId, ObjectId, TypeName, Uri};
|
||||||
use crate::crypto::{PublicKey, Signer};
|
use crate::crypto::{PublicKey, Signer};
|
||||||
use crate::git;
|
use crate::git;
|
||||||
|
|
@ -218,6 +219,9 @@ pub enum Action {
|
||||||
RevisionEdit {
|
RevisionEdit {
|
||||||
revision: RevisionId,
|
revision: RevisionId,
|
||||||
description: String,
|
description: String,
|
||||||
|
/// Embeded content.
|
||||||
|
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||||
|
embeds: Vec<Embed<Uri>>,
|
||||||
},
|
},
|
||||||
/// React to the revision.
|
/// React to the revision.
|
||||||
#[serde(rename = "revision.react")]
|
#[serde(rename = "revision.react")]
|
||||||
|
|
@ -732,11 +736,17 @@ impl Patch {
|
||||||
Action::RevisionEdit {
|
Action::RevisionEdit {
|
||||||
revision,
|
revision,
|
||||||
description,
|
description,
|
||||||
|
embeds,
|
||||||
} => {
|
} => {
|
||||||
if let Some(redactable) = self.revisions.get_mut(&revision) {
|
if let Some(redactable) = self.revisions.get_mut(&revision) {
|
||||||
// If the revision was redacted concurrently, there's nothing to do.
|
// If the revision was redacted concurrently, there's nothing to do.
|
||||||
if let Some(revision) = redactable {
|
if let Some(revision) = redactable {
|
||||||
revision.description = description;
|
revision.description.push(Edit::new(
|
||||||
|
author,
|
||||||
|
description,
|
||||||
|
timestamp,
|
||||||
|
embeds,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::Missing(revision.into_inner()));
|
return Err(Error::Missing(revision.into_inner()));
|
||||||
|
|
@ -1247,7 +1257,7 @@ pub struct Revision {
|
||||||
/// Author of the revision.
|
/// Author of the revision.
|
||||||
pub(super) author: Author,
|
pub(super) author: Author,
|
||||||
/// Revision description.
|
/// Revision description.
|
||||||
pub(super) description: String,
|
pub(super) description: NonEmpty<Edit>,
|
||||||
/// Base branch commit, used as a merge base.
|
/// Base branch commit, used as a merge base.
|
||||||
pub(super) base: git::Oid,
|
pub(super) base: git::Oid,
|
||||||
/// Reference to the Git object containing the code (revision head).
|
/// Reference to the Git object containing the code (revision head).
|
||||||
|
|
@ -1273,9 +1283,11 @@ impl Revision {
|
||||||
timestamp: Timestamp,
|
timestamp: Timestamp,
|
||||||
resolves: BTreeSet<(EntryId, CommentId)>,
|
resolves: BTreeSet<(EntryId, CommentId)>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let description = Edit::new(*author.public_key(), description, timestamp, Vec::default());
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
author,
|
author,
|
||||||
description,
|
description: NonEmpty::new(description),
|
||||||
base,
|
base,
|
||||||
oid,
|
oid,
|
||||||
discussion: Thread::default(),
|
discussion: Thread::default(),
|
||||||
|
|
@ -1287,7 +1299,7 @@ impl Revision {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn description(&self) -> &str {
|
pub fn description(&self) -> &str {
|
||||||
self.description.as_str()
|
self.description.last().body.as_str()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Author of the revision.
|
/// Author of the revision.
|
||||||
|
|
@ -1496,10 +1508,15 @@ impl<R: ReadRepository> store::Transaction<Patch, R> {
|
||||||
&mut self,
|
&mut self,
|
||||||
revision: RevisionId,
|
revision: RevisionId,
|
||||||
description: impl ToString,
|
description: impl ToString,
|
||||||
|
embeds: Vec<Embed>,
|
||||||
) -> Result<(), store::Error> {
|
) -> Result<(), store::Error> {
|
||||||
|
let hashed = embeds.iter().map(|e| e.hashed()).collect();
|
||||||
|
|
||||||
|
self.embed(embeds)?;
|
||||||
self.push(Action::RevisionEdit {
|
self.push(Action::RevisionEdit {
|
||||||
revision,
|
revision,
|
||||||
description: description.to_string(),
|
description: description.to_string(),
|
||||||
|
embeds: hashed,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1806,10 +1823,11 @@ where
|
||||||
&mut self,
|
&mut self,
|
||||||
revision: RevisionId,
|
revision: RevisionId,
|
||||||
description: String,
|
description: String,
|
||||||
|
embeds: impl IntoIterator<Item = Embed>,
|
||||||
signer: &G,
|
signer: &G,
|
||||||
) -> Result<EntryId, Error> {
|
) -> Result<EntryId, Error> {
|
||||||
self.transaction("Edit revision", signer, |tx| {
|
self.transaction("Edit revision", signer, |tx| {
|
||||||
tx.edit_revision(revision, description)
|
tx.edit_revision(revision, description, embeds.into_iter().collect())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2621,6 +2639,7 @@ mod test {
|
||||||
&Action::RevisionEdit {
|
&Action::RevisionEdit {
|
||||||
revision: RevisionId(*h0.root().id()),
|
revision: RevisionId(*h0.root().id()),
|
||||||
description: String::from("Edited"),
|
description: String::from("Edited"),
|
||||||
|
embeds: Vec::default(),
|
||||||
},
|
},
|
||||||
&bob,
|
&bob,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,23 @@ pub struct Edit {
|
||||||
pub embeds: Vec<Embed<Uri>>,
|
pub embeds: Vec<Embed<Uri>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Edit {
|
||||||
|
/// Create a new edit.
|
||||||
|
pub fn new(
|
||||||
|
author: ActorId,
|
||||||
|
body: String,
|
||||||
|
timestamp: Timestamp,
|
||||||
|
embeds: Vec<Embed<Uri>>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
author,
|
||||||
|
timestamp,
|
||||||
|
body,
|
||||||
|
embeds,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A comment on a discussion thread.
|
/// A comment on a discussion thread.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct Comment<T = Infallible> {
|
pub struct Comment<T = Infallible> {
|
||||||
|
|
@ -123,12 +140,7 @@ impl<L> Comment<L> {
|
||||||
embeds: Vec<Embed<Uri>>,
|
embeds: Vec<Embed<Uri>>,
|
||||||
timestamp: Timestamp,
|
timestamp: Timestamp,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let edit = Edit {
|
let edit = Edit::new(author, body, timestamp, embeds);
|
||||||
author,
|
|
||||||
body,
|
|
||||||
embeds,
|
|
||||||
timestamp,
|
|
||||||
};
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
author,
|
author,
|
||||||
|
|
@ -180,12 +192,7 @@ impl<L> Comment<L> {
|
||||||
embeds: Vec<Embed<Uri>>,
|
embeds: Vec<Embed<Uri>>,
|
||||||
timestamp: Timestamp,
|
timestamp: Timestamp,
|
||||||
) {
|
) {
|
||||||
self.edits.push(Edit {
|
self.edits.push(Edit::new(author, body, timestamp, embeds));
|
||||||
author,
|
|
||||||
body,
|
|
||||||
embeds,
|
|
||||||
timestamp,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Comment reactions.
|
/// Comment reactions.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue