Filter reactions by user?


#1

I want to show a list of pull requests (filtered by state and label) and display the titles together with the total amount of reactions as well as show if I reacted to them or not. I want basically the same functionality that GItHub’s UI has where it shows e.g. all hearts for a comment and at the same time it shows if I reacted with a heart to it or not.

Here is what my query looks so far …

{
  repository(owner: "octonews", name: "octonews") {
    pullRequests(first: 100, states: MERGED, labels: ["octonews"], orderBy: {field:CREATED_AT, direction:DESC}) {
      edges {
        node {
          title
          # get total count, that works nicely
          total: reactions(content: HEART) {
            totalCount
          },
          # get information if I reacted to the current PR or not (login === current user). No idea how to do that?
          reactions(content:HEART, first:100) {
            edges {
              node {
                user {
                  login
                }
              }
            }
          }
        }
      }
    }
  }
}

I hope this makes sense? Is this possible yet?


#2

Hi @gr2m!

I think there might be exactly what you’re looking for in here, and a few other niceties along the way.

In the repository to reaction connection, there is a property next to totalCount called viewerHasReacted, which is "Whether or not the authenticated user has left a reaction on the subject." - I think that’s what you require!

Additionally, on the User object there is a field called isViewer, which is true if the viewer and the user object you’re looking at are the same account.

To test this, I went into that repository and left a :heart: on https://github.com/octonews/octonews/pull/36 and then ran the query:

{
  repository(owner: "octonews", name: "octonews") {
    pullRequests(first: 100, states: MERGED, labels: ["octonews"], orderBy: {field: CREATED_AT, direction: DESC}) {
      edges {
        node {
          number
          title
          total: reactions(content: HEART) {
            totalCount
            viewerHasReacted
          }
          reactions(content: HEART, first: 100) {
            edges {
              node {
                user {
                  login
                  isViewer
                }
              }
            }
          }
        }
      }
    }
  }
}

For me, that looked like:

{
  "data": {
    "repository": {
      "pullRequests": {
        "edges": [
          {
            "node": {
              "number": 36,
              "title": "📰 Offline First",
              "total": {
                "totalCount": 1,
                "viewerHasReacted": true
              },
              "reactions": {
                "edges": [
                  {
                    "node": {
                      "user": {
                        "login": "nickvanw",
                        "isViewer": true
                      }
                    }
                  }
                ]
              }
            }
          },
          {
            "node": {
              "number": 32,
              "title": "📰 lodash.chain",
              "total": {
                "totalCount": 0,
                "viewerHasReacted": false
              },
              "reactions": {
                "edges": []
              }
            }
          },
          {
            "node": {
              "number": 27,
              "title": "📰 Twitter mentors",
              "total": {
                "totalCount": 0,
                "viewerHasReacted": false
              },
              "reactions": {
                "edges": []
              }
            }
          },
          {
            "node": {
              "number": 25,
              "title": "📰 A history of why the US is the only rich country without universal health care",
              "total": {
                "totalCount": 2,
                "viewerHasReacted": false
              },
              "reactions": {
                "edges": [
                  {
                    "node": {
                      "user": {
                        "login": "gr2m-test",
                        "isViewer": false
                      }
                    }
                  },
                  {
                    "node": {
                      "user": {
                        "login": "gr2m",
                        "isViewer": false
                      }
                    }
                  }
                ]
              }
            }
          },
          {
            "node": {
              "number": 24,
              "title": "📰 quantum information is sent instantaneously - faster than light",
              "total": {
                "totalCount": 1,
                "viewerHasReacted": false
              },
              "reactions": {
                "edges": [
                  {
                    "node": {
                      "user": {
                        "login": "gr2m",
                        "isViewer": false
                      }
                    }
                  }
                ]
              }
            }
          },
          {
            "node": {
              "number": 21,
              "title": "📰 Yellowstone Bears Eat 40,000 Moths a Day In August",
              "total": {
                "totalCount": 0,
                "viewerHasReacted": false
              },
              "reactions": {
                "edges": []
              }
            }
          },
          {
            "node": {
              "number": 15,
              "title": "📰 Scoopie Dooby Doo!",
              "total": {
                "totalCount": 0,
                "viewerHasReacted": false
              },
              "reactions": {
                "edges": []
              }
            }
          }
        ]
      }
    }
  }
}

Which shows viewerHasReacted as true :fireworks:!

Let me know if I’ve misunderstood the request, or if you need anything else!


#3

wow I totally missed viewerHasReacted. It’s perfect for my use case, thank you! It would be nice if I could optionally do something like this

viewerHasReacted(content: HEART)

But that’s not a deal breaker in my case. Thanks a ton!


#4

In my case not getting the type of reaction is a dealbreaker, as for my purposes, only +1s count.
If I’m understanding things right, in my case I would need to retrieve all reactions for every post and loop through them? And since it doesn’t seem to support ordering them by user, I might also need to paginate?
Surely, it should be simpler than this to just figure out if the current user has +1d an issue?


#5

Hey @LeaVerou

Would a content argument on viewerHasReacted solve your usecase? If so, I can put in a schema request for that, it seems like a reasonable request :slight_smile:


#6

Yes, it would! Thank you!


#7

So I think you could do something like that by doing this:

{
  repository(owner: "octonews", name: "octonews") {
    pullRequests(first: 100, states: MERGED, labels: ["octonews"], orderBy: {field: CREATED_AT, direction: DESC}) {
      edges {
        node {
          number
          title
          viewerHearted: reactions(content: HEART) {
            viewerHasReacted
          }
        }
      }
    }
  }
}

By defining the content and grabbing the viewerHasReacted, you can see if the viewer has reacted for the specified reaction. Would this work for you?


#8

Thanks! I was wondering about that too. Yes, I think that would work, though I haven’t tried it yet.