• github-user-store.coffee

  • ¶
    _ = 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) =>
          return if err or not 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)