- # 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)