<body>
<div id="wrapper">
<div id="sidebar-wrapper">
<ul class="sidebar-nav">
<li>
<a class="nohover" href="index.html"><img class="twitch-img img-responsive" src="https://dl.dropboxusercontent.com/s/9d32agss7hkk34h/twitch-logo3.png" alt="twitch logo"></a>
</li>
<li id="search">
<input class="searching form-control" type="text" placeholder="Search...">
</li>
<li>
<a id="all" href="#">All</a>
</li>
<li>
<a id="online" href="#">Online</a>
</li>
<li>
<a id="offline" href="#">Offline</a>
</li>
</ul>
</div>
<div id="page-content-wrapper">
<div class="container-fluid">
<div class="heading row">
<div class="col-xs-12">
<a href="#" class="btn btn-default" id="menu-toggle">Menu</a>
<h1 class="title text-center">Twitch TV Status</h1>
</div>
</div>
<div class="row">
<div id="loader" class="col-xs-12 text-center">
<p class="loading">Loading.....</p>
</div>
</div>
<div class="main-content row">
</div>
</div>
</div>
</div>
</body>
@import url(https://fonts.googleapis.com/css?family=Roboto:400,700);
@import url(https://fonts.googleapis.com/css?family=Nunito:400,700);
/* THE SIDEBAR EFFECT CREDIT T0 : https://startbootstrap.com */
/*
* Start Bootstrap - Simple Sidebar HTML Template (https://startbootstrap.com)
* Code licensed under the Apache License v2.0.
* For details, see http://www.apache.org/licenses/LICENSE-2.0.
*/
h1,h2,h3,h4,h5,h6{
font-family: 'Roboto', sans-serif;
}
a{
color:#615192;
}
a:hover,
a:active,
a:focus,
a:visited{
text-decoration:none;
}
body{
background:#764B8E;
font-family: 'Nunito', sans-serif;
}
.twitch-img{
width:300px;
}
#search{
padding:10px 18px;
}
#menu-toggle{
margin-top:-15px;
margin-left:-30px;
}
.title{
font-family: 'Roboto', sans-serif;
font-size:60px;
font-weight:bold;
color:#f5f5f5;
margin-top:50px;
margin-bottom:100px;
}
.status-text{
display:inline-block;
margin:6px 0 0 0;
}
.panel{
max-width:300px;
height:430px;
}
.panel-default{
border: 0;
}
.panel .panel-info {
padding: 0;
}
.loading{
font-size:40px;
}
#wrapper {
padding-left: 0;
-webkit-transition: all 0.5s ease;
-moz-transition: all 0.5s ease;
-o-transition: all 0.5s ease;
transition: all 0.5s ease;
}
#wrapper.toggled {
padding-left: 250px;
}
#sidebar-wrapper {
z-index: 1000;
position: fixed;
left: 250px;
width: 0;
height: 100%;
margin-left: -250px;
overflow-y: auto;
background:#261758;
-webkit-transition: all 0.5s ease;
-moz-transition: all 0.5s ease;
-o-transition: all 0.5s ease;
transition: all 0.5s ease;
}
#wrapper.toggled #sidebar-wrapper {
width: 250px;
}
#page-content-wrapper {
width: 100%;
position: absolute;
padding: 15px;
}
#wrapper.toggled #page-content-wrapper {
position: absolute;
margin-right: -250px;
}
/* Sidebar Styles */
.sidebar-nav {
position: absolute;
top: 0;
width: 250px;
margin: 0;
padding: 0;
list-style: none;
}
.sidebar-nav li {
text-indent: 20px;
line-height: 40px;
}
.sidebar-nav li a {
display: block;
text-decoration: none;
color: #f5f5f5;
}
.sidebar-nav li a:not(.nohover):hover {
text-decoration: none;
color: #fff;
background: rgba(255,255,255,0.2);
}
.sidebar-nav li a:active,
.sidebar-nav li a:focus {
text-decoration: none;
}
@media(min-width:620px) {
.title{
font-size:72px;
}
#wrapper {
padding-left: 250px;
}
#wrapper.toggled {
padding-left: 0;
}
#sidebar-wrapper {
width: 250px;
}
#wrapper.toggled #sidebar-wrapper {
width:0px;
}
#page-content-wrapper {
padding: 20px;
position: relative;
}
#wrapper.toggled #page-content-wrapper {
position: relative;
margin-right: 0;
}
}
(function($){
"use strict"
var twitchBaseUrl = 'https://api.twitch.tv/kraken/streams/'
var twitchUserNames = ["freecodecamp", "storbeck", "terakilobyte", "habathcx", "RobotCaleb", "thomasballinger", "noobs2ninjas", "beohoff", "medrybw", "brunofin", "comster404"];
var defaultlogo = "https://dl.dropboxusercontent.com/s/c189pkhw98kxq5l/default-logo.jpg"; // default logo if user dont have one
var closedlogo = "https://dl.dropboxusercontent.com/s/vpc3wuq4vr2prb1/closedAccount.png"; // closed account logo
var greenStatus = "https://dl.dropboxusercontent.com/s/zmjmj8u7kw4vryq/green-statv2.png";
var redStatus = "https://dl.dropboxusercontent.com/s/2amcjasm2kydzj6/red-statusv2.png";
var twitchUserInfo = []; // all users data to be stored in
var onlineUsers = []; // online user data to be stored in
var offlineUsers = []; //offline user data to be stored in
var totalRequest = (twitchUserNames.length * 2); // total request thats going to be made
var completedRequest = 0; // keep track of requests
var closedAccount = 0; // counting closed account thats not going to make a second request
//get twitch user stream data first
function getTwitchStreamData(){
twitchUserNames.forEach(function(names, index) {
$.ajax({url:twitchBaseUrl + names + '?client_id=l2y4sabamn5zz4gk8p2h1r0x3binu51&callback=?',dataType:'jsonp',error:function(xhr,status,error){
// handle closed account when 'GET' request completely fails
twitchClosedAccount(names,index);
}}).then(function(theStream) {
if(theStream._links){
twitchUserInfo[index] = {};
twitchUserInfo[index].user_stream = (theStream.stream ? true : false);
if (twitchUserInfo[index].user_stream) {
onlineUsers.push(twitchUserInfo[index]);
} else {
offlineUsers.push(twitchUserInfo[index]);
}
completedRequest += 1;
// get user channel data next
getTwitchChannelData(theStream._links.channel,index);
}else{
// handle special case when twitch api handle a 'GET' request on a closed account and returns an error object
twitchClosedAccount(names,index);
}
});
});
}
// later get channel data after getting stream data
function getTwitchChannelData(url,index){
$.ajax({url:url + '?client_id=l2y4sabamn5zz4gk8p2h1r0x3binu51&callback=?',dataType:'jsonp'}).then(function(theChannel){
console.log(theChannel)
twitchUserInfo[index].user_name = theChannel.display_name;
twitchUserInfo[index].user_logo = (theChannel.logo ? theChannel.logo : defaultlogo);
twitchUserInfo[index].user_url = theChannel.url;
twitchUserInfo[index].user_status = (twitchUserInfo[index].user_stream ? "Online" : "Offline");
twitchUserInfo[index].user_status_details = (twitchUserInfo[index].user_stream ? theChannel.status : null);
// trim string at length greater than 22
if (twitchUserInfo[index].user_status_details) {
twitchUserInfo[index].user_status_details = (twitchUserInfo[index].user_status_details.length > 22 ? twitchUserInfo[index].user_status_details.substring(0, 22) + "..." : twitchUserInfo[index].user_status_details)
}
twitchUserInfo[index].icon_status = (twitchUserInfo[index].user_stream ? greenStatus : redStatus);
completedRequest += 1;
})
}
function twitchClosedAccount(names,index){
closedAccount += 1;
twitchUserInfo[index] = {};
offlineUsers.push(twitchUserInfo[index]);
// default values for closed accounts
twitchUserInfo[index].user_name = names;
twitchUserInfo[index].user_logo = closedlogo;
twitchUserInfo[index].user_url = '#'
twitchUserInfo[index].user_status = "Offline";
twitchUserInfo[index].user_status_details = "Account Closed"
twitchUserInfo[index].icon_status = redStatus;
completedRequest += 1;
}
function getAll(){
$('#all').on('click',function(e){
e.preventDefault();
$('.main-content').empty();
twitchUserInfo.forEach(function(twitchUser) {
var baseContent = "<div class='col-xs-12 col-sm-6 col-md-4'>" +
"<div class='panel panel-default'>" +
"<div class='panel-info'>" +
"<img src='" + twitchUser.user_logo + "' class='img-responsive'>" +
"</div>" +
"<div class='panel-body'>" +
"<p class='lead'>" +
"<a href='" + twitchUser.user_url + "'" + " target='_blank'>" + twitchUser.user_name + "</a></p>" +
"<p class='status-text'>Status: " + twitchUser.user_status + "</p>" +
"<img class='status-img pull-right'" + "src='" + twitchUser.icon_status + "'/>";
if (twitchUser.user_status_details) {
baseContent = baseContent + "<p>" + twitchUser.user_status_details + "</p>" + "</div>" + "</div>" + "</div>";
$('.main-content').append(baseContent);
} else {
baseContent = baseContent + "</div>" + "</div>" + "</div>";
$('.main-content').append(baseContent);
}
});
})
}
function getOnline(){
$('#online').on('click', function(e) {
e.preventDefault();
$('.main-content').empty();
onlineUsers.forEach(function(onlineUser) {
var Content = "<div class='col-xs-12 col-sm-6 col-md-4'>" +
"<div class='panel panel-default'>" +
"<div class='panel-info'>" +
"<img src='" + onlineUser.user_logo + "' class='img-responsive'>" +
"</div>" +
"<div class='panel-body'>" +
"<p class='lead'>" +
"<a href='" + onlineUser.user_url + "'" + " target='_blank'>" + onlineUser.user_name + "</a></p>" +
"<p class='status-text'>Status: " + onlineUser.user_status + "</p>" +
"<img class='status-img pull-right'" + "src='" + onlineUser.icon_status + "'/>" +
"<p>" + onlineUser.user_status_details + "</p>" +
"</div>" +
"</div>" +
"</div>"
$('.main-content').append(Content);
})
})
}
function getOffline(){
$('#offline').on('click',function(e){
e.preventDefault();
$('.main-content').empty();
offlineUsers.forEach(function(offlineUser){
var baseContent = "<div class='col-xs-12 col-sm-6 col-md-4'>" +
"<div class='panel panel-default'>" +
"<div class='panel-info'>" +
"<img src='" + offlineUser.user_logo + "' class='img-responsive'>" +
"</div>" +
"<div class='panel-body'>" +
"<p class='lead'>" +
"<a href='" + offlineUser.user_url + "'" + " target='_blank'>" + offlineUser.user_name + "</a></p>" +
"<p class='status-text'>Status: " + offlineUser.user_status + "</p>" +
"<img class='status-img pull-right'" + "src='" + offlineUser.icon_status + "'/>";
if (offlineUser.user_status_details) {
baseContent = baseContent + "<p>" + offlineUser.user_status_details + "</p>" + "</div>" + "</div>" + "</div>";
$('.main-content').append(baseContent);
} else {
baseContent = baseContent + "</div>" + "</div>" + "</div>";
$('.main-content').append(baseContent);
}
})
})
}
// runs when all async request have been completed
function DisplayTwitchUserData(stopInterval) {
clearInterval(stopInterval);
// load all on intial start up
twitchUserInfo.forEach(function(twitchUser) {
var baseContent = "<div class='col-xs-12 col-sm-6 col-md-4'>" +
"<div class='panel panel-default'>" +
"<div class='panel-info'>" +
"<img src='" + twitchUser.user_logo + "' class='img-responsive'>" +
"</div>" +
"<div class='panel-body'>" +
"<p class='lead'>" +
"<a href='" + twitchUser.user_url + "'" + " target='_blank'>" + twitchUser.user_name + "</a></p>" +
"<p class='status-text'>Status: " + twitchUser.user_status + "</p>" +
"<img class='status-img pull-right'" + "src='" + twitchUser.icon_status + "'/>";
if (twitchUser.user_status_details) {
baseContent = baseContent + "<p>" + twitchUser.user_status_details + "</p>" + "</div>" + "</div>" + "</div>";
$("#loader").css("display", "none");
$('.main-content').append(baseContent);
} else {
baseContent = baseContent + "</div>" + "</div>" + "</div>";
$("#loader").css("display", "none");
$('.main-content').append(baseContent);
}
});
// set all, online, and offline button to be used
getAll();
getOnline();
getOffline();
// set search feature
$('.searching').on("keyup",function(){
var searchWord = $(this).val().toLowerCase();
$('.panel-body .lead a').each(function(){
var checkUserName = $(this).text().toLowerCase();
$(this).closest('.panel')[ checkUserName.indexOf(searchWord) !== -1 ? 'show' : 'hide' ]();
})
})
}
$(document).ready(function() {
// sidebar toggle
$("#menu-toggle").click(function(e) {
e.preventDefault();
$("#wrapper").toggleClass("toggled");
});
// makes aysnc request to twitch server and get user twitch data
getTwitchStreamData();
// check to make sure all async request have been completed
var completeAsyncRequest = setInterval(function() {
if ((completedRequest !== 0) && completedRequest === (totalRequest = totalRequest - closedAccount)) {
var stopInterval = completeAsyncRequest;
DisplayTwitchUserData(stopInterval);
}
}, 2000)
})
})(jQuery)