Radish alpha
r
Radicle web interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
httpd: Add reactions to revisions, improve json for comment reactions
Sebastian Martinez committed 2 years ago
commit 7b9350e1544f0e2e3b6fc9c10ac211913412f572
parent e9be685edfc23d35627f46426b3008caf41d46cd
2 files changed +120 -16
modified radicle-httpd/src/api/json.rs
@@ -1,10 +1,11 @@
//! Utilities for building JSON responses of our API.

+
use std::collections::BTreeMap;
use std::path::Path;
use std::str;

use base64::prelude::{Engine, BASE64_STANDARD};
-
use radicle::cob::CodeLocation;
+
use radicle::cob::{CodeLocation, Reaction};
use serde_json::{json, Value};

use radicle::cob::issue::{Issue, IssueId};
@@ -130,6 +131,15 @@ pub(crate) fn patch(
                "author": author(rev.author(), aliases.alias(rev.author().id())),
                "description": rev.description(),
                "edits": rev.edits().map(|e| edit(e, aliases)).collect::<Vec<_>>(),
+
                "reactions": rev.reactions().iter().flat_map(|(location, reaction)| {
+
                    let reactions = reaction.iter().fold(BTreeMap::new(), |mut acc: BTreeMap<&Reaction, Vec<_>>, (author, emoji)| {
+
                        acc.entry(emoji).or_default().push(author);
+
                        acc
+
                    });
+
                    reactions.iter().map(|(emoji, authors)|
+
                        json!({"location": location, "emoji": emoji, "authors": authors })
+
                    ).collect::<Vec<_>>()
+
                }).collect::<Vec<_>>(),
                "base": rev.base(),
                "oid": rev.head(),
                "refs": get_refs(repo, patch.author().id(), &rev.head()).unwrap_or_default(),
@@ -191,7 +201,9 @@ fn issue_comment(id: &CommentId, comment: &Comment, aliases: &impl AliasStore) -
        "body": comment.body(),
        "edits": comment.edits().map(|e| edit(e, aliases)).collect::<Vec<_>>(),
        "embeds": comment.embeds().to_vec(),
-
        "reactions": comment.reactions().collect::<Vec<_>>(),
+
        "reactions": comment.reactions().iter().map(|(emoji, authors)|
+
            json!({ "emoji": emoji, "authors": authors })
+
        ).collect::<Vec<_>>(),
        "timestamp": comment.timestamp().as_secs(),
        "replyTo": comment.reply_to(),
        "resolved": comment.resolved(),
@@ -210,7 +222,9 @@ fn patch_comment(
        "body": comment.body(),
        "edits": comment.edits().map(|e| edit(e, aliases)).collect::<Vec<_>>(),
        "embeds": comment.embeds().to_vec(),
-
        "reactions": comment.reactions().collect::<Vec<_>>(),
+
        "reactions": comment.reactions().iter().map(|(emoji, authors)|
+
            json!({ "emoji": emoji, "authors": authors })
+
        ).collect::<Vec<_>>(),
        "timestamp": comment.timestamp().as_secs(),
        "replyTo": comment.reply_to(),
        "location": comment.location(),
@@ -230,7 +244,9 @@ fn review_comment(
        "body": comment.body(),
        "edits": comment.edits().map(|e| edit(e, aliases)).collect::<Vec<_>>(),
        "embeds": comment.embeds().to_vec(),
-
        "reactions": comment.reactions().collect::<Vec<_>>(),
+
        "reactions": comment.reactions().iter().map(|(emoji, authors)|
+
            json!({ "emoji": emoji, "authors": authors })
+
        ).collect::<Vec<_>>(),
        "timestamp": comment.timestamp().as_secs(),
        "replyTo": comment.reply_to(),
        "location": comment.location(),
modified radicle-httpd/src/api/v1/projects.rs
@@ -869,6 +869,12 @@ async fn patch_update_handler(
            patch.edit_revision(revision, description, embeds, &signer)?
        }
        patch::Action::RevisionRedact { revision } => patch.redact(revision, &signer)?,
+
        patch::Action::RevisionReact {
+
            revision,
+
            reaction,
+
            active,
+
            location,
+
        } => patch.react(revision, reaction, location, active, &signer)?,
        patch::Action::RevisionComment {
            revision,
            body,
@@ -903,9 +909,6 @@ async fn patch_update_handler(
        patch::Action::RevisionCommentRedact { revision, comment } => {
            patch.comment_redact(revision, comment, &signer)?
        }
-
        _ => {
-
            todo!();
-
        }
    };

    announce_refs(node, repo.id())?;
@@ -2281,10 +2284,10 @@ mod routes {
                    }
                  ],
                  "reactions": [
-
                    [
-
                    "z6Mkk7oqY4pPxhMmGEotDYsFo97vhCj85BLY1H256HrJmjN8",
-
                    "🚀",
-
                    ],
+
                    {
+
                      "emoji": "🚀",
+
                      "authors": ["z6Mkk7oqY4pPxhMmGEotDYsFo97vhCj85BLY1H256HrJmjN8"]
+
                    },
                  ],
                  "timestamp": TIMESTAMP,
                  "replyTo": null,
@@ -2433,6 +2436,7 @@ mod routes {
                "revisions": [
                  {
                    "id": CONTRIBUTOR_PATCH_ID,
+
                    "reactions": [],
                    "author": {
                      "id": CONTRIBUTOR_DID,
                    },
@@ -2485,6 +2489,7 @@ mod routes {
                "revisions": [
                  {
                    "id": CONTRIBUTOR_PATCH_ID,
+
                    "reactions": [],
                    "author": {
                      "id": CONTRIBUTOR_DID,
                    },
@@ -2576,6 +2581,7 @@ mod routes {
                "revisions": [
                  {
                    "id": CREATED_PATCH_ID,
+
                    "reactions": [],
                    "author": {
                      "id": CONTRIBUTOR_DID,
                    },
@@ -2662,6 +2668,7 @@ mod routes {
                      "embeds": [],
                    },
                  ],
+
                  "reactions": [],
                  "base": PARENT,
                  "oid": HEAD,
                  "refs": [
@@ -2736,6 +2743,7 @@ mod routes {
                      "embeds": [],
                    },
                  ],
+
                  "reactions": [],
                  "base": PARENT,
                  "oid": HEAD,
                  "refs": [
@@ -2809,6 +2817,7 @@ mod routes {
                      "embeds": [],
                    },
                  ],
+
                  "reactions": [],
                  "base": PARENT,
                  "oid": HEAD,
                  "refs": [
@@ -2834,6 +2843,7 @@ mod routes {
                        "embeds": [],
                    },
                  ],
+
                  "reactions": [],
                  "base": PARENT,
                  "oid": HEAD,
                  "refs": [
@@ -2893,6 +2903,7 @@ mod routes {
              "revisions": [
                {
                  "id": CONTRIBUTOR_PATCH_ID,
+
                  "reactions": [],
                  "author": {
                    "id": CONTRIBUTOR_DID,
                  },
@@ -2943,6 +2954,52 @@ mod routes {

        assert_eq!(response.status(), StatusCode::OK);

+
        let body = serde_json::to_vec(&json!({
+
          "type": "revision.react",
+
          "revision": CONTRIBUTOR_PATCH_ID,
+
          "reaction": "🚀",
+
          "location": {
+
            "commit": INITIAL_COMMIT,
+
            "path": "./README.md",
+
            "new": {
+
              "type": "lines",
+
              "range": {
+
                "start": 0,
+
                "end": 1
+
              }
+
            }
+
          },
+
          "active": true,
+
        }))
+
        .unwrap();
+
        let response = patch(
+
            &app,
+
            format!("/projects/{CONTRIBUTOR_RID}/patches/{CONTRIBUTOR_PATCH_ID}"),
+
            Some(Body::from(body)),
+
            Some(SESSION_ID.to_string()),
+
        )
+
        .await;
+

+
        assert_eq!(response.status(), StatusCode::OK);
+

+
        let body = serde_json::to_vec(&json!({
+
          "type": "revision.react",
+
          "revision": CONTRIBUTOR_PATCH_ID,
+
          "reaction": "🙏",
+
          "location": null,
+
          "active": true,
+
        }))
+
        .unwrap();
+
        let response = patch(
+
            &app,
+
            format!("/projects/{CONTRIBUTOR_RID}/patches/{CONTRIBUTOR_PATCH_ID}"),
+
            Some(Body::from(body)),
+
            Some(SESSION_ID.to_string()),
+
        )
+
        .await;
+

+
        assert_eq!(response.status(), StatusCode::OK);
+

        let response = get(
            &app,
            format!("/projects/{CONTRIBUTOR_RID}/patches/{CONTRIBUTOR_PATCH_ID}"),
@@ -2987,6 +3044,29 @@ mod routes {
                      "embeds": [],
                    },
                  ],
+
                  "reactions": [
+
                    {
+
                      "location": null,
+
                      "emoji": "🙏",
+
                      "authors": ["z6Mkk7oqY4pPxhMmGEotDYsFo97vhCj85BLY1H256HrJmjN8"],
+
                    },
+
                    {
+
                      "location": {
+
                        "commit": INITIAL_COMMIT,
+
                        "path": "./README.md",
+
                        "old": null,
+
                        "new": {
+
                          "type": "lines",
+
                          "range": {
+
                            "start": 0,
+
                            "end": 1
+
                          }
+
                        }
+
                      },
+
                      "emoji": "🚀",
+
                      "authors": ["z6Mkk7oqY4pPxhMmGEotDYsFo97vhCj85BLY1H256HrJmjN8"]
+
                    },
+
                  ],
                  "base": PARENT,
                  "oid": HEAD,
                  "refs": [
@@ -3123,6 +3203,7 @@ mod routes {
                      "embeds": [],
                    },
                  ],
+
                  "reactions": [],
                  "base": PARENT,
                  "oid": HEAD,
                  "refs": [
@@ -3169,7 +3250,12 @@ mod routes {
                          "content": "git:94381b429d7f7fe87e1bade52d893ab348ae29cc",
                        }
                      ],
-
                      "reactions": [["z6Mkk7oqY4pPxhMmGEotDYsFo97vhCj85BLY1H256HrJmjN8","🚀"]],
+
                      "reactions": [
+
                        {
+
                          "emoji": "🚀",
+
                          "authors": ["z6Mkk7oqY4pPxhMmGEotDYsFo97vhCj85BLY1H256HrJmjN8"]
+
                        },
+
                      ],
                      "timestamp": TIMESTAMP,
                      "replyTo": null,
                      "location": null,
@@ -3350,6 +3436,7 @@ mod routes {
                      "embeds": [],
                    },
                  ],
+
                  "reactions": [],
                  "base": PARENT,
                  "oid": HEAD,
                  "refs": [
@@ -3406,10 +3493,10 @@ mod routes {
                            },
                          ],
                          "reactions": [
-
                            [
-
                              "z6Mkk7oqY4pPxhMmGEotDYsFo97vhCj85BLY1H256HrJmjN8",
-
                              "🚀",
-
                            ],
+
                            {
+
                              "emoji": "🚀",
+
                              "authors": ["z6Mkk7oqY4pPxhMmGEotDYsFo97vhCj85BLY1H256HrJmjN8"],
+
                            },
                          ],
                          "timestamp": 1671125284,
                          "replyTo": null,
@@ -3506,6 +3593,7 @@ mod routes {
                      "embeds": [],
                    },
                  ],
+
                  "reactions": [],
                  "base": PARENT,
                  "oid": HEAD,
                  "refs": [