Mailspring/internal_packages/github-contact-card/lib/github-user-store.es6
Max Stoiber c0c39e69b9 Fix Github Sidebar Plugin (#2003)
Hopefully fixes #1991

I don't have N1 setup locally, so this is a blind shot–would appreciate somebody who has it set up to pull this and verify this fixes the issue, but as far as I can tell it should.

The gist is:

> Looking at the code, what you do is use the `search/users` endpoint to find users by email and taking the repos from there. You then load the repositories of the username, but we can't sort those by most-starred: "sort string Can be one of `created`, `updated`, `pushed`, `full_name`. Default: `full_name`" *([src](https://developer.github.com/v3/repos/#list-user-repositories))*
> What we could instead do is use the search API, which **allows us to search for repositories by a specific user and sort by most starred**. This is a tiny bit hacky, but works perfectly fine. E.g. this is the URL for my most starred repos: `https://api.github.com/search/repositories?q=user:mxstbr&sort=stars&order=desc`
2016-04-19 16:13:30 -07:00

107 lines
3.3 KiB
JavaScript

import _ from 'underscore';
import request from 'request';
import NylasStore from 'nylas-store';
import {FocusedContactsStore} from 'nylas-exports';
// This package uses the Flux pattern - our Store is a small singleton that
// observes other parts of the application and vends data to our React
// component. If the user could interact with the GithubSidebar, this store
// would also listen for `Actions` emitted by our React components.
class GithubUserStore extends NylasStore {
constructor() {
super();
this._profile = null;
this._cache = {};
this._loading = false;
this._error = null;
// Register a callback with the FocusedContactsStore. This will tell us
// whenever the selected person has changed so we can refresh our data.
this.listenTo(FocusedContactsStore, this._onFocusedContactChanged);
}
// Getter Methods
profileForFocusedContact() {
return this._profile;
}
loading() {
return this._loading;
}
error() {
return this._error;
}
// Called when the FocusedContactStore `triggers`, notifying us that the data
// it vends has changed.
_onFocusedContactChanged = ()=> {
// Grab the new focused contact
const contact = FocusedContactsStore.focusedContact();
// First, clear the contact that we're currently showing and `trigger`. Since
// our React component observes our store, `trigger` causes our React component
// to re-render.
this._error = null;
this._profile = null;
if (contact) {
this._profile = this._cache[contact.email];
if (this._profile === undefined) {
// Make a Github search request to find the matching user profile
this._githubFetchProfile(contact.email);
}
}
this.trigger(this);
}
_githubFetchProfile(email) {
this._loading = true
this._githubRequest(`https://api.github.com/search/users?q=${email}`, (err, resp, data)=> {
if (err || !data) {
return;
}
if (data.message !== undefined) {
console.warn(data.message);
}
// Sometimes we get rate limit errors, etc., so we need to check and make
// sure we've gotten items before pulling the first one.
let profile = false;
if (data && data.items && data.items[0]) {
profile = data.items[0];
}
// If a profile was found, make a second request for the user's public
// repositories.
if (profile !== false) {
profile.repos = [];
this._githubRequest(`https://api.github.com/search/repositories?q=user:${profile.login}&sort=stars&order=desc`, (reposErr, reposResp, data)=> {
// Sort the repositories by their stars (`-` for descending order)
profile.repos = _.sortBy(data.items, (repo)=> -repo.stargazers_count);
// Trigger so that our React components refresh their state and display
// the updated data.
this.trigger(this);
});
}
this._loading = false;
this._profile = this._cache[email] = profile;
this.trigger(this);
});
}
// Wrap the Node `request` library and pass the User-Agent header, which is required
// by Github's API. Also pass `json:true`, which causes responses to be automatically
// parsed.
_githubRequest(url, callback) {
return request({url: url, headers: {'User-Agent': 'request'}, json: true}, callback);
}
}
export default new GithubUserStore();