Skip to content

Instantly share code, notes, and snippets.

@sharplet
Last active June 8, 2018 22:10
Show Gist options
  • Save sharplet/6474970 to your computer and use it in GitHub Desktop.
Save sharplet/6474970 to your computer and use it in GitHub Desktop.
Unearned Stack Overflow badges Dashing widget

Badge Overflow

An exceptionally handsome way to track your Stack Overflow badges.

Created by Adam & Stephanie Sharp.

Unearned Badges widget

A Dashing widget that tracks your progress toward unearned badges on Stack Overflow. It randomly selects a badge you haven't earned and shows your progress, or suggests things you could try in order to earn the badge. The widget's background colour dynamically changes depending on the badge's rank (bronze, silver, or gold).

Nice Answer

Tenacious

Reversal

Demo

You can view the demo dashboard at badgeoverflow.herokuapp.com. The code is available on GitHub.

Setup

  1. Install the widget:

    $ dashing install 6474970
    
  2. Add the gem badgeoverflow-core to your Gemfile:

    gem 'badgeoverflow-core', :git => "https://github.com/sharplet/badgeoverflow-core.git"
  3. Create the file config/badgeoverflow.yml and set the user ID you want to track progress for:

    user_id: 1
  4. Add the widget to your dashboard:

    <li data-row="2" data-col="1" data-sizex="2" data-sizey="1">
      <div data-id="unearned_badges" data-view="UnearnedBadges" data-title=""></div>
    </li>
  5. Optionally, add the font Cabin to dashboards/layout.erb:

    <link href='//fonts.googleapis.com/css?family=Cabin:400,500,600,700' rel='stylesheet' type='text/css'>

How it works

The widget talks to the Stack Exchange API via the badgeoverflow-core gem, which we wrote while developing the widget. The most significant part of this gem is the logic for calculating a user's progress toward a badge. We've implemented progress calculation for a large number of badges, and tried to make it as easy as possible to add more. For badges where we aren't (yet) calculating progress, we display the badge's description.

class Dashing.UnearnedBadges extends Dashing.Widget
onData: (data) ->
if data.background
$('.widget-unearned-badges').css 'background-color', data.background
<h1 class="title" data-bind="title"></h1>
<a data-bind-href="link">
<h3 class="heading" data-bind="text | raw"></h3>
</a>
<p class="subheading" data-bind="moreinfo | raw"></p>
<p class="updated-at" data-bind="updatedAtMessage"></p>
require 'badgeoverflow/core'
require 'badgeoverflow/helpers'
class StackOverflow::Badge
include RankColour
end
service = StackExchangeService.new
user_id = BadgeOverflowConfig.user_id
SCHEDULER.every '10m', :first_in => 0 do
named_badges = service.fetch 'badges/name', {
filter: '!9j_cPloMN',
order: 'desc',
sort: 'rank',
pagesize: 100
}
named_badges.map! { |b| StackOverflow::Badge.new(b, user_id) }
user_badges = service.fetch('users', 'badges', ids: user_id)
user_badges.map! { |b| StackOverflow::Badge.new(b, user_id) }
# get unearned badges
#
# where there is a set of badges (bronze, silver, gold),
# only keep lowest ranked unearned badge in array
unearned_badges = StackOverflow::Badge.first_badges_in_series(named_badges - user_badges)
random_badge = unearned_badges.sample
random_badge.calculate_progress!
send_event('unearned_badges', { :title => random_badge.progress_title,
:text => random_badge.name,
:link => random_badge.link,
:moreinfo => random_badge.progress_description,
:background => random_badge.colour_for_rank })
end
// ----------------------------------------------------------------------------
// Sass declarations
// ----------------------------------------------------------------------------
$background-color: #808080;
$title-color: rgba(255, 255, 255, 0.7);
$subheading-color: rgba(255, 255, 255, 0.9);
// ----------------------------------------------------------------------------
// Widget-unearned-badges styles
// ----------------------------------------------------------------------------
.widget-unearned-badges {
background-color: $background-color;
vertical-align: top !important;
font-family: "Cabin", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
.title {
color: $title-color;
font-weight: 500;
padding-bottom: 45px;
}
.heading {
font-size: 50px;
font-weight: 500;
padding-bottom: 60px;
}
.subheading {
color: $subheading-color;
font-size: 22px;
line-height: 1.4em;
font-weight: 400;
}
.updated-at {
color: rgba(255, 255, 255, 0.7);
}
p > a {
text-decoration: underline;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment