Mailspring/examples/N1-Github-Contact-Card-Section/lib/github-user-store.coffee
Ben Gotow 42ad243824 fix(message-sidebar): New ContactCard injectable role, updated FocusedContactStore
- The FocusedContactStore was triggering too often, and leaving it up to the FullcontactStore to fetch the full Contact model for the focused contact (pulled from thread.)

The FocusedContactStore triggers more responsibly, and registering for the role "MessageListSidebar:ContactCard" now gives you the focused contact as a full database model. The whole ContactCard region also fades in and out.
2015-09-24 18:58:53 -07:00

83 lines
2.8 KiB
CoffeeScript

_ = require 'underscore-plus'
Reflux = require 'reflux'
request = require 'request'
{FocusedContactsStore} = require 'nylas-exports'
module.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.
GithubUserStore = Reflux.createStore
init: ->
@_profile = null
@_cache = {}
@_loading = false
@_error = null
# Register a callback with the FocusedContactsStore. This will tell us
# whenever the selected person has changed so we can refresh our data.
@listenTo FocusedContactsStore, @_onFocusedContactChanged
# Getter Methods
profileForFocusedContact: ->
@_profile
loading: ->
@_loading
error: ->
@_error
# Called when the FocusedContactStore `triggers`, notifying us that the data
# it vends has changed.
_onFocusedContactChanged: ->
# Grab the new focused contact
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.
@_error = null
@_profile = null
if contact
@_profile = @_cache[contact.email]
# Make a Github search request to find the matching user profile
@_githubFetchProfile(contact.email) unless @_profile?
@trigger(@)
_githubFetchProfile: (email) ->
@_loading = true
@_githubRequest "https://api.github.com/search/users?q=#{email}", (err, resp, data) =>
console.warn(data.message) if 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.
profile = data?.items?[0] ? false
# If a profile was found, make a second request for the user's public
# repositories.
if profile
profile.repos = []
@_githubRequest profile.repos_url, (err, resp, repos) =>
# Sort the repositories by their stars (`-` for descending order)
profile.repos = _.sortBy repos, (repo) -> -repo.stargazers_count
# Trigger so that our React components refresh their state and display
# the updated data.
@trigger(@)
@_loading = false
@_profile = @_cache[email] = profile
@trigger(@)
# 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) ->
request({url: url, headers: {'User-Agent': 'request'}, json: true}, callback)