Skip to content

Instantly share code, notes, and snippets.

@Jean13
Created January 26, 2016 03:42
Show Gist options
  • Save Jean13/9d7823ddda47653a1d4f to your computer and use it in GitHub Desktop.
Save Jean13/9d7823ddda47653a1d4f to your computer and use it in GitHub Desktop.
Twitch.tv Status
head
title Twitch.tv Status
.wrapper
h1 Twitch Steamer Status
nav.nav
ul.left
li
a#all.active(href='#') All
li
a#online(href='#') Online
li
a#offline(href='#') Offline
#activeBar.activeBar.moveLeft
form.search
i.fa.fa-search.left
input#search.searchbar(type='text' placeholder='Search...')
.bar
form
input#input(type='text' placeholder='Enter channel name...')
input#button(type='submit', value='Add Channel')
#panel.panel
#footer
#author
| app created by
a(href='http://codepen.io/Jean13')
| Jean González
a
$(document).ready(function() {
function truncate(str, num) {
var newStr
if (str.length > num) {
newStr = str.slice(0, num - 3);
newStr += '\u2026';
} else {
newStr = str;
}
return newStr;
}
var twitchName = [
'freecodecamp',
'storbeck',
'habathcx',
'RobotCaleb',
'devwars',
'inostupid',
'yomama',
'Noobs2Ninjas',
'medrybw',
'sing_sing',
'nl_kripp',
'screwattack',
'kingdime',
'vgbootcamp'
];
var twitchNameLength = twitchName.length;
twitchName.sort();
var input = document.getElementById("input");
var button = document.getElementById("button");
var $nav = $('.nav'),
$navItems = $nav.find('ul li > a'),
$all = $('#all'),
$online = $('#online'),
$offline = $('#offline'),
$activeBar = $('#activeBar'),
$panel = $('#panel'),
$search = $('#search'),
$streamers;
var streams = [],
channels = [],
online = [],
offline = [],
count = 0;
function createStreamList(i) {
$.ajax({
dataType: 'jsonp',
url: 'https://api.twitch.tv/kraken/streams/' + twitchName[i]
}).then(function(streamsData) {
$.ajax({
dataType: 'jsonp',
url: 'https://api.twitch.tv/kraken/channels/' + twitchName[i]
}).then(function(channelsData) {
streams[i] = streamsData;
channels[i] = channelsData;
count++;
if (count === twitchNameLength) {
createAll();
showAll();
}
});
});
}
function createAll() {
for (var i = 0; i < twitchNameLength; i++) {
if (streams[i].stream !== null) {
online[i] = (
'<a class="streamLink" href=' + channels[i].url + ' target="_blank">' +
'<div class="streamers">' +
'<img class="profilePicture left" src=' + channels[i].logo + '>' +
'<div class="group left">' +
'<h2 class="displayName">' + channels[i].display_name + '<i class="fa fa-circle-thin"></i></h2>' + '<p id="flw">' + channels[i].followers + '</p>' +
'<p class="status">' + truncate(channels[i].status, 28) + '</p>' +
'</div>' +
'</div>' +
'</a>'
);
} else {
offline[i] = (
'<div class="streamers offline">' +
'<img class="profilePicture left" src=' + channels[i].logo + '>' +
'<div class="group left">' +
'<h2 class="displayName">' + channels[i].display_name + '</h2>' +
'</div>' +
'</div>'
);
}
}
}
function showAll() {
$(this).addClass('active');
$online.removeClass('active');
$offline.removeClass('active');
$activeBar.removeClass().addClass('activeBar moveLeft');
$panel.html(online.join('')).append(offline.join(''));
doAnimation();
doRipple();
}
function showOnline() {
$(this).addClass('active');
$all.removeClass('active');
$offline.removeClass('active');
$activeBar.removeClass().addClass('activeBar moveCenter');
$panel.html(online.join(''));
doAnimation();
doRipple();
}
function showOffline() {
$(this).addClass('active');
$all.removeClass('active');
$online.removeClass('active');
$activeBar.removeClass().addClass('activeBar moveRight');
$panel.html(offline.join(''));
doAnimation();
doRipple();
}
function doAnimation() {
$streamers = $panel.find('.streamers');
$streamers.each(function(index) {
$(this).addClass('animate ani-' + index);
});
}
function doRipple() {
$streamers.on('click', function(e) {
var width = $(this).outerWidth();
var x = e.pageX;
var y = e.pageY;
var offsetX = x - $(this).offset().left;
var offsetY = y - $(this).offset().top;
var layerX = Math.round(offsetX - (width / 2));
var layerY = Math.round(offsetY - (width / 2));
$(this).find('span').remove();
$(this).append('<span class="layer rippleStream"></span>');
$('.layer').css({
top: layerY + 'px',
left: layerX + 'px',
}).addClass('animateLayer');
});
}
$search.keyup(function(e) {
$streamers.each(function(index) {
var text = $(this).text().toUpperCase();
var input = $search.val().toUpperCase();
if (text.indexOf(input) === -1) $(this).hide();
else $(this).show();
});
e.preventDefault();
});
$navItems.on('click', function(e) {
var width = $(this).outerWidth();
var x = e.pageX;
var y = e.pageY;
var offsetX = x - $(this).offset().left;
var offsetY = y - $(this).offset().top;
var layerX = Math.round(offsetX - (width / 2));
var layerY = Math.round(offsetY - (width / 2));
$(this).find('span').remove();
$(this).append('<span class="layer rippleNav"></span>');
$('.layer').css({
top: layerY + 'px',
left: layerX + 'px',
}).addClass('animateLayer');
});
$all.on('click', showAll);
$online.on('click', showOnline);
$offline.on('click', showOffline);
for (var j = 0; j < twitchNameLength; j++) {
createStreamList(j);
};
button.onclick = function addTW() {
twitchName.unshift(input.value);
var twitchNameLength = twitchName.length;
var count = 0;
createStreamList(0);
createAll();
showAll();
};
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/Fugiman/Twitch-Channel-Status/1d74252edf89110507cbf3088f9c3eaa38fac9d3/twitch-channel-status.min.js"></script>
@import "bourbon";
@import url(https://fonts.googleapis.com/css?family=Cinzel|Philosopher|Kreon|Merriweather|Electrolize|Orbitron|Geo);
$lightPurple: #b000c5;
$darkPurple: #410049;
$somePurple: #51295c;
$someWhite: #f0f0f0;
$darkGreen: #134704;
$darkBlue: #0047df;
* {box-sizing: border-box;}
h1 {
font-family: 'Geo';
font-size: 16px;
color: white;
background: orange;
margin-bottom: -0.1%;
border-radius: 2% 0 0 0;
text-transform: uppercase;
box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23);
}
h2, h3, h4 {
margin: 0;
padding: 0;
font-family: 'Geo';
font-weight: 300;
line-height: 1.1;
letter-spacing: 0.025em;
}
p {
margin: 0;
font-family: 'Electrolize';
font-weight: 100;
font-size: 16px;
}
a {
font-family: 'Electrolize';
font-weight: 300;
text-decoration: none;
text-transform: uppercase;
opacity: 0.7;
}
#button {
border-radius: 5%;
background: $lightPurple;
color: white;
opacity: 0.9;
font-family: 'Electrolize';
font-weight: 300;
border-color: orange;
}
input {
font-family: 'Electrolize';
}
#footer {
}
#author {
font-family: 'Electrolize';
color: green;
}
.wrapper {
background: white;
width: 325px;
height: 100%;
margin: 0 auto;
padding-bottom: 30px;
margin-bottom: 2%;
text-align: center;
box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23);
}
.nav {
background: $lightPurple;
height: 60px;
width: 100%;
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
position: relative;
}
.nav > ul {
margin: 0;
padding: 0;
width: 100%;
list-style: none;
}
.nav ul li {
width: 33.334%;
height: 60px;
float: left;
overflow: hidden;
}
.nav ul li > a {
display: block;
color: white;
line-height: 60px;
border-left: 1px solid rgba(255, 255, 255, 0.3);
opacity: 0.7;
position: relative;
}
.nav ul li:first-child > a {
border-left: none;
}
.nav ul li > a:hover {
opacity: 1;
transition: all .15s ease;
}
.nav ul li > .active {
opacity: 1;
}
.activeBar {
background: white;
height: 3px;
width: 33.334%;
position: absolute;
bottom: 0;
transition: left 0.2s ease-in-out;
}
.moveLeft {
left: 0;
}
.moveCenter {
left: 109px;
}
.moveRight {
left: 217px;
}
.search {
position: relative;
}
.searchbar {
width: 305px;
height: 30px;
margin: 1em 0;
padding-left: 28px;
border: none;
box-shadow: 0 1px 0 rgba(0,0,0,0.12);
font: 300 1rem 'Roboto';
letter-spacing: 0.025em;
}
.searchbar::-webkit-input-placeholder { opacity: 0.54; }
.searchbar:focus::-webkit-input-placeholder { opacity: 0.87; }
.searchbar::-moz-placeholder { opacity: 0.54; }
.searchbar:focus::-moz-placeholder { opacity: 0.87; }
.searchbar:focus {
outline: none;
opacity: 0.87;
}
.bar {
width: 305px;
height: 3px;
background: $darkPurple;
position: absolute;
bottom: 15px;
left: 10px;
transform: scaleX(0);
transition: transform 0.2s ease-in-out;
}
.searchbar:focus + .bar {
transform: scaleX(1);
}
.streamLink {
text-transform: none;
color: inherit;
opacity: 1;
}
.offline {
color: rgba(0, 0, 0, 0.38);
font-style: italic;
}
.streamers {
height: 92px;
border-right: #FFF;
position: relative;
overflow: hidden;
clear: both;
}
.streamers:after {
content: '';
width: 233px;
height: 1px;
position: absolute;
bottom: 0;
left: 92px;
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
}
.streamers:hover {
border-right: 5px solid $darkPurple;
transition: border-right .15s ease;
}
.profilePicture {
height: 60px;
width: 60px;
border-radius: 50%;
margin: 16px;
}
.group {
margin: 16px 0 0 0;
height: 60px;
position: relative;
width: 200px;
}
.displayName {
text-align: left;
line-height: 60px;
font-size: 18px;
width: 211px;
}
.status {
text-align: left;
font-size: 16px;
position: absolute;
bottom: 0; left: 0;
width: 255px;
opacity: 0.38;
}
.fa-search {
position: absolute;
width: 25px;
height: 25px;
top: 23px;
left: 10px;
z-index: 1;
opacity: 0.54;
}
.fa-circle-thin {
float: right;
line-height: 60px;
color: $darkBlue;
opacity: 0.54;
}
.left {
float: left;
}
.animate { transform: scale(0); animation: animate 0.25s ease-in-out forwards; }
@keyframes animate { 100% { transform: scale(1); } }
.ani-0 { animation-delay: 0ms; }
.ani-1 { animation-delay: 75ms; }
.ani-2 { animation-delay: 150ms; }
.ani-3 { animation-delay: 225ms; }
.ani-4 { animation-delay: 300ms; }
.ani-5 { animation-delay: 375ms; }
.layer { border-radius: 50%; position: absolute; transform: scale(0); }
.rippleStream { background: #FF80AB; width: 325px; height: 325px;}
.rippleNav { background: #1E88E5; width: 108px; height: 108px;}
.animateLayer { animation: ripple 0.5s linear; }
@keyframes ripple { 100% { opacity: 0; transform: scale(2.75); } }
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet" />

Twitch.tv Status

A Twitch.tv Status Tracker application. See whether users are online or not, and what they are streaming.

A Pen by Jean on CodePen.

License.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment