mirror of
https://github.com/status-im/sourcecred.git
synced 2025-02-27 11:40:26 +00:00
Add GitHub reactions to the graph (#846)
* Define Reaction edges This adds support to `github/edges` for creating edges representing GitHub reactions. These edges are not actually added to the graph. Test plan: Unit tests * Add GitHub reactions to the graph This commit adds functional support for reactions in SourceCred. Only thumbs-up, heart, and hooray reactions are supported for now, as they are all unambiguously positive; adding support for negative reactions like thumbs-down will require some more thought. The reactions are added to the graph, and new edge types have been added to the UI. Test plan: The `graphView` class has been updated to do invariant checking for the reaction edges, including that the unsupported reaction types like "THUMBS_DOWN" aren't added to the graph. I've tested this feature by downloading data for a large repository (ipfs/go-ipfs). The reaction edges appear and transfer cred reasonably. The edge types are displayed in the weight config appropriately. Builds on #839, #840, and #845.
This commit is contained in:
parent
488c98c3e1
commit
62d3c180ee
@ -1,6 +1,7 @@
|
||||
# Changelog
|
||||
|
||||
## [Unreleased]
|
||||
- Add GitHub reactions to the graph (#846)
|
||||
- Detect references to commits (#833)
|
||||
- Detect references in commit messages (#829)
|
||||
- Add commit authorship to the graph (#826)
|
||||
|
@ -1541,6 +1541,242 @@ Array [
|
||||
"dstIndex": 2,
|
||||
"srcIndex": 36,
|
||||
},
|
||||
Object {
|
||||
"address": Array [
|
||||
"sourcecred",
|
||||
"github",
|
||||
"REACTS",
|
||||
"HEART",
|
||||
"5",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"6",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"ISSUE",
|
||||
"sourcecred",
|
||||
"example-github",
|
||||
"1",
|
||||
],
|
||||
"dstIndex": 25,
|
||||
"srcIndex": 42,
|
||||
},
|
||||
Object {
|
||||
"address": Array [
|
||||
"sourcecred",
|
||||
"github",
|
||||
"REACTS",
|
||||
"HEART",
|
||||
"5",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"6",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"ISSUE",
|
||||
"sourcecred",
|
||||
"example-github",
|
||||
"13",
|
||||
],
|
||||
"dstIndex": 29,
|
||||
"srcIndex": 42,
|
||||
},
|
||||
Object {
|
||||
"address": Array [
|
||||
"sourcecred",
|
||||
"github",
|
||||
"REACTS",
|
||||
"HEART",
|
||||
"5",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"6",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"PULL",
|
||||
"sourcecred",
|
||||
"example-github",
|
||||
"9",
|
||||
],
|
||||
"dstIndex": 37,
|
||||
"srcIndex": 42,
|
||||
},
|
||||
Object {
|
||||
"address": Array [
|
||||
"sourcecred",
|
||||
"github",
|
||||
"REACTS",
|
||||
"HEART",
|
||||
"5",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"8",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"COMMENT",
|
||||
"PULL",
|
||||
"sourcecred",
|
||||
"example-github",
|
||||
"5",
|
||||
"396430464",
|
||||
],
|
||||
"dstIndex": 23,
|
||||
"srcIndex": 42,
|
||||
},
|
||||
Object {
|
||||
"address": Array [
|
||||
"sourcecred",
|
||||
"github",
|
||||
"REACTS",
|
||||
"HOORAY",
|
||||
"5",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"6",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"ISSUE",
|
||||
"sourcecred",
|
||||
"example-github",
|
||||
"13",
|
||||
],
|
||||
"dstIndex": 29,
|
||||
"srcIndex": 42,
|
||||
},
|
||||
Object {
|
||||
"address": Array [
|
||||
"sourcecred",
|
||||
"github",
|
||||
"REACTS",
|
||||
"HOORAY",
|
||||
"5",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"8",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"COMMENT",
|
||||
"ISSUE",
|
||||
"sourcecred",
|
||||
"example-github",
|
||||
"11",
|
||||
"420813206",
|
||||
],
|
||||
"dstIndex": 8,
|
||||
"srcIndex": 42,
|
||||
},
|
||||
Object {
|
||||
"address": Array [
|
||||
"sourcecred",
|
||||
"github",
|
||||
"REACTS",
|
||||
"THUMBS_UP",
|
||||
"5",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"6",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"ISSUE",
|
||||
"sourcecred",
|
||||
"example-github",
|
||||
"12",
|
||||
],
|
||||
"dstIndex": 28,
|
||||
"srcIndex": 42,
|
||||
},
|
||||
Object {
|
||||
"address": Array [
|
||||
"sourcecred",
|
||||
"github",
|
||||
"REACTS",
|
||||
"THUMBS_UP",
|
||||
"5",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"6",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"ISSUE",
|
||||
"sourcecred",
|
||||
"example-github",
|
||||
"13",
|
||||
],
|
||||
"dstIndex": 29,
|
||||
"srcIndex": 42,
|
||||
},
|
||||
Object {
|
||||
"address": Array [
|
||||
"sourcecred",
|
||||
"github",
|
||||
"REACTS",
|
||||
"THUMBS_UP",
|
||||
"5",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"6",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"PULL",
|
||||
"sourcecred",
|
||||
"example-github",
|
||||
"9",
|
||||
],
|
||||
"dstIndex": 37,
|
||||
"srcIndex": 42,
|
||||
},
|
||||
Object {
|
||||
"address": Array [
|
||||
"sourcecred",
|
||||
"github",
|
||||
"REACTS",
|
||||
"THUMBS_UP",
|
||||
"5",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"8",
|
||||
"sourcecred",
|
||||
"github",
|
||||
"COMMENT",
|
||||
"ISSUE",
|
||||
"sourcecred",
|
||||
"example-github",
|
||||
"11",
|
||||
"420813206",
|
||||
],
|
||||
"dstIndex": 8,
|
||||
"srcIndex": 42,
|
||||
},
|
||||
Object {
|
||||
"address": Array [
|
||||
"sourcecred",
|
||||
|
@ -6,6 +6,8 @@ import * as N from "./nodes";
|
||||
import * as R from "./relationalView";
|
||||
import {createEdge} from "./edges";
|
||||
import {findMentionsAuthorReferences} from "./heuristics/mentionsAuthorReference";
|
||||
// TODO(@decentralion): Opportunity to reduce bundle size
|
||||
import {Reactions} from "./graphql";
|
||||
|
||||
export function createGraph(view: R.RelationalView): Graph {
|
||||
const creator = new GraphCreator();
|
||||
@ -49,6 +51,21 @@ class GraphCreator {
|
||||
}
|
||||
}
|
||||
|
||||
for (const reactable of view.reactableEntities()) {
|
||||
for (const {content, user} of reactable.reactions()) {
|
||||
// We only support unambiguously positive reactions for now
|
||||
if (
|
||||
content === Reactions.THUMBS_UP ||
|
||||
content === Reactions.HEART ||
|
||||
content === Reactions.HOORAY
|
||||
) {
|
||||
this.graph.addEdge(
|
||||
createEdge.reacts(content, user, reactable.address())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const mentionsAuthorReference of findMentionsAuthorReferences(view)) {
|
||||
this.graph.addEdge(createEdge.mentionsAuthor(mentionsAuthorReference));
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import * as GN from "./nodes";
|
||||
import * as GE from "./edges";
|
||||
|
||||
import * as GitNode from "../git/nodes";
|
||||
// TODO(@decentralion): Opportunity to reduce bundle size
|
||||
import {Reactions} from "./graphql";
|
||||
|
||||
import {
|
||||
Graph,
|
||||
@ -245,6 +247,14 @@ export class GraphView {
|
||||
srcAccessor: (x) => GN.toRaw((x: any).reference.src),
|
||||
dstAccessor: (x) => GN.toRaw((x: any).reference.dst),
|
||||
},
|
||||
[GE.REACTS_TYPE]: {
|
||||
homs: homProduct(
|
||||
[GN.Prefix.userlike],
|
||||
[GN.Prefix.issue, GN.Prefix.pull, GN.Prefix.comment]
|
||||
),
|
||||
srcAccessor: (x) => GN.toRaw((x: any).user),
|
||||
dstAccessor: (x) => GN.toRaw((x: any).reactable),
|
||||
},
|
||||
};
|
||||
|
||||
for (const edge of this._graph.edges({
|
||||
@ -299,5 +309,26 @@ export class GraphView {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (const reactionEdge of this._graph.edges({
|
||||
addressPrefix: GE.Prefix.reacts,
|
||||
srcPrefix: NodeAddress.empty,
|
||||
dstPrefix: NodeAddress.empty,
|
||||
})) {
|
||||
const address: GE.RawAddress = (reactionEdge.address: any);
|
||||
const reactsAddress: GE.ReactsAddress = (GE.fromRaw(address): any);
|
||||
const {reactionType} = reactsAddress;
|
||||
if (
|
||||
reactionType !== Reactions.THUMBS_UP &&
|
||||
reactionType !== Reactions.HEART &&
|
||||
reactionType !== Reactions.HOORAY
|
||||
) {
|
||||
throw new Error(
|
||||
`Invariant: Edge ${stringify(
|
||||
reactsAddress
|
||||
)} has unspported reactionType`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -339,6 +339,14 @@ describe("plugins/github/graphView", () => {
|
||||
expect(() => new GraphView(g)).toThrow("Invariant: Expected src");
|
||||
});
|
||||
});
|
||||
describe("reactions edges", () => {
|
||||
it("must have a supported type", () => {
|
||||
const unsupported = ["THUMBS_DOWN", "LAUGH", "CONFUSED"];
|
||||
for (const u of unsupported) {
|
||||
failsForEdge(GE.createEdge.reacts(u, userlike, issue));
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("are properly re-entrant", () => {
|
||||
|
@ -108,6 +108,30 @@ export class StaticPluginAdapter implements IStaticPluginAdapter {
|
||||
defaultBackwardWeight: 1 / 32,
|
||||
prefix: E.Prefix.mentionsAuthor,
|
||||
},
|
||||
{
|
||||
forwardName: "reacted ❤️ to",
|
||||
backwardName: "got ❤️ from",
|
||||
defaultForwardWeight: 2,
|
||||
// TODO(#811): Probably change this to 0
|
||||
defaultBackwardWeight: 1 / 32,
|
||||
prefix: E.Prefix.reactsHeart,
|
||||
},
|
||||
{
|
||||
forwardName: "reacted 👍 to",
|
||||
backwardName: "got 👍 from",
|
||||
defaultForwardWeight: 1,
|
||||
// TODO(#811): Probably change this to 0
|
||||
defaultBackwardWeight: 1 / 32,
|
||||
prefix: E.Prefix.reactsThumbsUp,
|
||||
},
|
||||
{
|
||||
forwardName: "reacted 🎉 to",
|
||||
backwardName: "got 🎉 from",
|
||||
defaultForwardWeight: 4,
|
||||
// TODO(#811): Probably change this to 0
|
||||
defaultBackwardWeight: 1 / 32,
|
||||
prefix: E.Prefix.reactsHooray,
|
||||
},
|
||||
];
|
||||
}
|
||||
async load(assets: Assets, repo: Repo): Promise<IDynamicPluginAdapater> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user