GitHub Feed Filter

By vijaydev Last update Jun 15, 2011 — Installed 167 times.

There are 2 previous versions of this script.

// ==UserScript==
// @name           GitHub Feed Filter
// @description    Adds the ability to filter out GitHub feeds based on repositories and specific categories
// @namespace      http://vijaydev.wordpress.com
// @include        https://github.com/
// @include        https://github.com/#
// @include        https://github.com/dashboard
// ==/UserScript==

/* Bugs & TODOS
 * T: Optimize re-runs (next version)
 */

var Ghf = {
  $: unsafeWindow.jQuery, log: unsafeWindow.console.info,
  feeds: {}, counts: {}, ui: {},

  init: function() {
    this.searchterm = '';
    this.rel = '';
    this.feeds = {};
    this.counts = { 'all': 0, 'commits': 0, 'comments': 0, 'issues': 0 };
    this.ui = { body: [], bottom_bar: "<div class='bottom-bar'> </div> </div>", top_bar: "<div class='repos' id='your_feeds'> <div class='top-bar'> <h2 class='count'>News Feeds <em></em></h2> </div><div class='filter-bar'> <input class='filter_input' placeholder='Find a repository feed…' type='search'><ul class='repo_filterer'> <li class='all_repos'><a href='#' class='repo_filter filter_selected' rel='all'>All Feeds</a></li> <li><a href='#' class='repo_filter' rel='commits'>Commits</a></li> <li><a href='#' class='repo_filter' rel='comments'>Comments</a></li> <li><a href='#' class='repo_filter' rel='issues'>Issues</a></li> </ul> </div>" };
  },
  run: function() {
    this.init();
    this.searchterm = Ghf.$("#your_feeds .filter_input").val();
    this.rel = Ghf.$('#your_feeds .repo_filterer a.filter_selected').attr('rel');
    this.read_feeds();
    this.create_panel();
    this.show_panel();
    this.script_events();
    this.monitor_page();
  },
  Utils: {
    keys: function(obj) {
      var keys = [];
      for(var k in obj) keys.push(k);
      return keys;
    },
    add_style: function(css) {
      var style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = css;
      Ghf.$('head').append(style);
    }
  },
  add_feed: function(name, key, idx) {
    var f = this.feeds[name];
    if(f === undefined) {
      f = { all: [idx] };
      f[key] = [idx];
    }
    else if(f[key] === undefined) {
      f[key] = [idx];
      f['all'].push(idx);
    }
    else {
      f[key].push(idx);
      f['all'].push(idx);
    }
    this.feeds[name] = f;
    this.counts['all']++;
    this.counts[key]++;
  },
  read_feeds: function() {
    var self = this;
    Ghf.$('div.alert').each(function(idx) {
      var title = Ghf.$(this).find('div.title');
      var cat = Ghf.$(this).attr("class").split(' ')[1], x = -1;
      switch(cat) {
        case 'issues_opened': case 'issues_reopened': case 'issues_closed':
          x = 2, cat = 'issues';
        break;
        case 'issues_comment': case 'commit_comment':
          x = cat === 'issues_comment' ? 2 : 1, cat = 'comments';
        break;
        case 'push':
          x = 1, cat = 'commits';
        break;
      }
      if(x != -1)
        self.add_feed(Ghf.$(title.find('a')[x]).html(), cat, idx);
    });
  },
  create_panel: function() {
    var self = this;
    var repos = self.Utils.keys(self.feeds);
    self.ui.body.push('<ul id="feed_listing" class="repo_list">');
    for each(repo in repos) {
      var r = repo.split('/');
      var cats = self.Utils.keys(self.feeds[repo]);
      self.ui.body.push('<li class="public ' + cats.join(' ') + '"><a class="feedlink" href="#"><span class="owner">' + r[0] + '</span>/<span class="repo">' + r[1] + '</span></a>');
      Ghf.$.each(cats, function(idx, val) {
        self.ui.body.push('<span class="spancount" rel="' + val + '">(' + self.feeds[repo][val].length + ')</span>');
      });
      self.ui.body.push('</li>');
    }
    self.ui.body.push('</ul>');

    this.Utils.add_style('.feedlink { background:none !important; display:inline-block !important; } \n' + '.spancount { padding:0px 2px 5px 0 !important; color:#99A4AA !important; font-size:14px !important; }');
  },
  show_panel: function() {
    Ghf.$('div#your_feeds').remove();
    Ghf.$('div#your_repos').after(this.ui.top_bar + this.ui.body.join('') + this.ui.bottom_bar);
  },
  script_events: function() {
    this.set_spans('all');
    this.setup_search();
    this.attach_name_handlers();
    this.setup_cat_filters();

    Ghf.$("#your_feeds .filter_input").val(this.searchterm);
    if(this.rel !== '') {
      Ghf.$('#your_feeds a.repo_filter[rel="' + this.rel + '"]').click();
    }
  },
  attach_name_handlers: function() {
    var self = this;
    Ghf.$('#feed_listing li a').click(function(evt) {
      self.hide_feeds();
      Ghf.$.each(self.feeds[Ghf.$(this).text()][Ghf.$(this).siblings('span:visible').attr('rel')], self.show_feed_n);
      evt.preventDefault();
      evt.stopPropagation();
    });
  },
  setup_cat_filters: function() {
    var self = this;
    Ghf.$('#your_feeds .repo_filter').click(function(evt) {
      var t = Ghf.$(this), r = t.attr('rel');
      t.parents('ul').find('a').removeClass('filter_selected');
      t.addClass('filter_selected');
      self.set_spans(r);
      self.search(Ghf.$('#your_feeds .filter_input').val(), r);
      self.hide_feeds();
      Ghf.$.each(Ghf.$('ul#feed_listing li:visible a'), function(i, item) {
        Ghf.$.each(self.feeds[Ghf.$(item).text()][r], self.show_feed_n);
      });
      evt.preventDefault();
      evt.stopPropagation();
    });
  },
  setup_search: function() {
    var self = this;
    Ghf.$('#your_feeds .filter_input').addClass('native').bind('keyup blur click', function(e) { self.search(this.value); });
  },
  search: function(srch, rel) {
    var items = Ghf.$('ul#feed_listing li').hide();
    if(!rel)
      rel = Ghf.$('#your_feeds .repo_filterer a.filter_selected').attr('rel');
    Ghf.$('ul#feed_listing').find('li.' + rel).show();
    srch != "" && items.filter(":not(:contains_ci('" + srch + "'))").hide();
  },
  monitor_page: function() {
    Ghf.$('div.news .pagination a').click(function() {
      setTimeout(function() { Ghf.run(); }, 2000);
    });
  },
  hide_feeds: function() {
    Ghf.$('div.alert').hide();
  },
  show_feed_n: function(i, n) {
    Ghf.$('div.alert:eq(' + n + ')').show();
  },
  set_count: function(n) {
    Ghf.$("#your_feeds h2.count em").html("(" + n + ")");
  },
  set_spans: function(rel) {
    this.set_count(this.counts[rel]);
    var f = Ghf.$('ul#feed_listing');
    f.find("span[rel]").hide();
    f.find('span[rel="' + rel + '"]').show();
  }
};

Ghf.run();