Skip to content

Instantly share code, notes, and snippets.

@ymohammad
Created July 17, 2017 13:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ymohammad/4217cc2260670d8d06cb5cb212d872f9 to your computer and use it in GitHub Desktop.
Save ymohammad/4217cc2260670d8d06cb5cb212d872f9 to your computer and use it in GitHub Desktop.
Twitch Streamers
<header class="site-header">
<div>
<img src="http://s.jtvnw.net/jtv_user_pictures/hosted_images/GlitchIcon_purple.png" class="twitch-logo" />
<span class="site-header-style">TWITCH STREAMERS</span>
</div>
</header>
<div id="button-holder">
<fieldset>
<div class="switch-toggle well stream-status">
<input id="all" name="view3" type="radio" checked>
<label for="all" onclick="">View All</label>
<input id="online" name="view3" type="radio">
<label for="online" onclick="">Online</label>
<input id="offline" name="view3" type="radio">
<label for="offline" onclick="">Offline</label>
<input id="featured" name="view3" type="radio">
<label for="featured" onclick="">Featured</label>
<a class="btn btn-primary"></a>
</div>
</fieldset>
</div>
<div class="row stream-input-div">
<input type="text" name="channel_name" id="channel_id" class="stream-input" placeholder="Enter Channel Name">
<span class="stream-btn" id="connect-id">Connect</span>
</div>
<div id="search-result-div">
</div>
<div id="loading-div-background">
<div id="loading-div" class="ui-corner-all" >
<img style="height:80px;margin:30px;" src="https://i.stack.imgur.com/FhHRx.gif" alt="Loading.."/>
<h2 style="color:gray;font-weight:normal;">Please wait....</h2>
</div>
</div>
<footer class="site-footer" id="footer-id">
</footer>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.3/jquery-ui.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script type="text/javascript">
var twitchApiUrl = "https://api.twitch.tv/kraken";
/* $.getJSON('https://api.twitch.tv/kraken/streams/featured?callback=?', function(data) {
console.log(data);
});
$.getJSON('https://api.twitch.tv/kraken/streams/ESL_SC2?callback=?', function(data) {
console.log(data);
}); */
var ONLINE_STATUS = "Online";
var OFFLINE_STATUS = "Offline";
var ACCOUNT_LOCKED_STATUS = "Account Closed";
var resultStreamArr = [];
var regularStreamersArr = ["brunofin", "ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas", "XXADAFAFAFAAFAFAF", "comster404"];
for (var eachInd = 0; eachInd < regularStreamersArr.length; eachInd++) {
fetchStream(regularStreamersArr[eachInd]);
}
$(window).bind("load", function() {
showSearchArray();
$('#all').click(function(eventObj) {
showSearchArray();
});
$('#online').click(function(eventObj) {
prepareNShowOnlineChannel();
});
$('#offline').click(function(eventObj) {
prepareNShowOffLineChannel();
});
$('#featured').click(function(eventObj) {
fetchFeaturedStreams();
});
$('#connect-id').click(function(eventObj) {
getChannelInfo();
});
});
function getChannelInfo() {
var streamName = document.getElementById("channel_id").value;
console.log("got cannel name :" + streamName);
if (streamName) {
$("#loading-div-background").show();
$.getJSON(twitchApiUrl + '/streams/' + streamName + '?callback=?', function(data) {
var queryChannelInfoArr = [];
var streamObj = prepareNGetStreamObject(data, streamName);
if (streamObj.status !== ONLINE_STATUS) {
$.getJSON(twitchApiUrl + '/channels/' + streamName + '?callback=?', function(channelData) {
var queryChannelInfoArr = [];
if (channelData.error) {
streamObj.logoImgUrl = "http://s.jtvnw.net/jtv_user_pictures/hosted_images/GlitchIcon_WhiteonPurple.png";
} else {
streamObj.logoImgUrl = channelData.logo;
streamObj.displayName = channelData.display_name;
streamObj.streaming = channelData.status;
streamObj.channelUrl = channelData.url;
}
queryChannelInfoArr.push(streamObj);
displayArrayContent(queryChannelInfoArr);
console.log("... inside call.");
console.log(queryChannelInfoArr);
});
} else {
queryChannelInfoArr.push(streamObj);
displayArrayContent(queryChannelInfoArr);
}
$("#loading-div-background").hide();
});
}
}
/**
* It fetches the featured (promoted) stream objects. Note that the number of promoted streams varies
* from day to day, and there is no guarantee on how many streams will be promoted at a given time.
*/
function fetchFeaturedStreams() {
$contentDiv = $("#search-result-div");
//contentDiv.innerHTML = "";
$("#loading-div-background").show();
$.getJSON(twitchApiUrl + '/streams/featured?callback=?', function(data) {
var featuredStreamArr = [];
if (data.featured) {
var streamCount = data.featured.length;
for (var eachStrmInd = 0; eachStrmInd < streamCount; eachStrmInd++) {
featuredStreamArr.push(prepareNGetStreamObject(data.featured[eachStrmInd]));
}
} else if(data.error) {
var streamError = new StreamError(data.error, data.message, data.status);
streamObj = new Stream("featured", null, "featured", null, null, null, streamError);
featuredStreamArr.push(streamObj)
}
$("#loading-div-background").hide();
displayArrayContent(featuredStreamArr);
});
}
/**
* This function prepare the local Stream object by fetching the required information from server object.
* @param {Object} serverDataObj - The object receieved after the server call.
*/
function prepareNGetStreamObject(serverDataObj, streamName) {
var streamObj = null;
var name = streamName;
var logoImg = null;
var displayName = streamName;
var status = OFFLINE_STATUS;
var streaming = null;
var viewersCount = 0;
var streamError = null;
var channelUrl = null;
if (serverDataObj.stream) {
logoImg = serverDataObj.stream.channel.logo;
displayName = serverDataObj.stream.channel.display_name;
status = ONLINE_STATUS;
streaming = serverDataObj.stream.channel.status;
viewersCount = serverDataObj.stream.viewers;
channelUrl = serverDataObj.stream.channel.url;
} else if(serverDataObj.error) {
if (serverDataObj.status === 422) {
status = ACCOUNT_LOCKED_STATUS;
} else {
status = serverDataObj.error;
}
streamError = new StreamError(serverDataObj.error, serverDataObj.message, serverDataObj.status);
}
streamObj = new Stream(name, logoImg, displayName, status, streaming, viewersCount, streamError, channelUrl);
return streamObj;
}
/**
* This functions fetches the Stream information and fill the resultStreamArr.
* @param {string} streamName - The name of the Streaming channel (unique name).
*/
function fetchStream(streamName) {
$.getJSON(twitchApiUrl + '/streams/' + streamName + '?callback=?', function(data) {
var streamObj = prepareNGetStreamObject(data, streamName);
if (streamObj.status !== ONLINE_STATUS) {
$.getJSON(twitchApiUrl + '/channels/' + streamName + '?callback=?', function(channelData) {
if (channelData.error) {
streamObj.logoImgUrl = "http://s.jtvnw.net/jtv_user_pictures/hosted_images/GlitchIcon_WhiteonPurple.png";
} else {
streamObj.logoImgUrl = channelData.logo;
streamObj.displayName = channelData.display_name;
streamObj.streaming = channelData.status;
streamObj.channelUrl = channelData.url;
}
resultStreamArr.push(streamObj);
});
} else {
resultStreamArr.push(streamObj);
}
});
}
/**
* Gets the current Streams summary and display on the page.
*/
function currentStreamsSummary() {
$.getJSON(twitchApiStreamUrl + '/summary?callback=?', function(data) {
console.log(data);
});
}
/**
* Basic Stream Object to store streams information.
* @constructor
* @param {string} name - The name of the Streaming channel (unique name).
* @param {string} logoImg - The image url of the channel logo.
* @param {string} displayName - The display Name of the channel.
* @param {string} status - Status of the streaming (offline/online).
* @param {string} streaming - The streaming information.
* @param {int} viewersCount - Number of unsers currently viewing the channel.
* @param {StreamError} streamError - The stream error object.
* @param {string} channelUrl - Channel Url.
*/
function Stream(name, logoImg, displayName, status, streaming, viewersCount, streamError, channelUrl) {
this.name = name;
this.logoImgUrl = logoImg;
this.displayName = displayName;
this.status = status;
this.streaming = streaming;
this.viewersCount = viewersCount;
this.streamError = streamError
this.channelUrl = channelUrl
this.isEqual = function(streamObj) {
var returnVal = false;
if (streamObj && streamObj.name) {
if (this.name === streamObj.name) {
returnVal = true;
}
}
return returnVal;
}
this.isOnline = function() {
if(this.status === ONLINE_STATUS) {
return true;
}
return false;
}
this.isOffline = function() {
if(this.status === OFFLINE_STATUS) {
return true;
}
return false;
}
}
/**
* Stream Error Object to store streams error information.
* @constructor
* @param {string} error - The error generated by the API Call.
* @param {string} message - The error message for the given API call.
* @param {string} status - The status code of the channel.
*/
function StreamError(error, message, status) {
this.error = error;
this.message = message;
this.status = status;
}
function prepareNShowOffLineChannel() {
var offlineArr = [];
if (resultStreamArr && resultStreamArr.length > 0) {
resultStreamArr.forEach(function(currentValue){
if (currentValue.isOffline()) {
offlineArr.push(currentValue);
}
}, offlineArr);
}
displayArrayContent(offlineArr);
}
function prepareNShowOnlineChannel() {
var onlineArr = [];
if (resultStreamArr && resultStreamArr.length > 0) {
resultStreamArr.forEach(function(currentValue){
if (currentValue.isOnline()) {
onlineArr.push(currentValue);
}
}, onlineArr);
}
displayArrayContent(onlineArr);
}
function showSearchArray()
{
displayArrayContent(resultStreamArr);
}
function displayArrayContent(contentArray) {
if (contentArray && contentArray.length > 0) {
var searchResultSize = contentArray.length;
console.log("the array count :" + searchResultSize);
var searchSrc = "<ul>";
var eachStreamObj = null;
var eachSearchListSrc = null;
var thumbnailImgSrc = null;
for (var searchIndex = 0; searchIndex < searchResultSize; searchIndex++) {
eachStreamObj = contentArray[searchIndex];
thumbnailImgSrc = "";
if(eachStreamObj.logoImgUrl) {
thumbnailImgSrc = " <img src='" + eachStreamObj.logoImgUrl + "' />";
}
eachSearchListSrc = "<li> ";
if (eachStreamObj.channelUrl) {
eachSearchListSrc += " <a href='" + (eachStreamObj.channelUrl) + "' target='_blank'>";
}
eachSearchListSrc += thumbnailImgSrc +
"<h3>" + eachStreamObj.displayName + "</h3></a>" +
"<p>Status: " + eachStreamObj.status + "</p>";
if (eachStreamObj.status === ONLINE_STATUS) {
eachSearchListSrc += "<p>Streaming: " + eachStreamObj.streaming + "</p>" +
"<p>Currently viewing:" + eachStreamObj.viewersCount;
}
eachSearchListSrc +=" " +
"</li>";
searchSrc += eachSearchListSrc;
}
searchSrc += "</ul>"
var contentDiv = document.getElementById("search-result-div");
contentDiv.innerHTML = searchSrc;
var footerContainer = document.getElementById("footer-id");
footerContainer.innerHTML = "<div>Developed by <a href='https://www.linkedin.com/in/mohammad-sufiyan-al-yousufi-0279743a' target='_blank' style='font-size: inherit;''> Mohammad Sufiyan Al Yousufi </a>.<br>Contact information: <a href='mailto:mdsufyan2005@gmail.com' style='font-size: inherit; ''>mdsufyan2005@gmail.com</a><br>© 2016 AlySufiyan Software Development Labs </div>";
}
}
</script>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
.site-header {
position: relative;
height: 150px;
box-shadow: 0 0 0 2px rgba(0,0,0,.07),0 0 0 1px rgba(0,0,0,.2);
background-color: #F6F6F6;
width: 100%;
margin: 0 0 8px;
border-bottom: 5px solid #de1b1b;
}
.site-header-style {
text-align: center;
letter-spacing: 10px;
font-family: Black Ops One;
font-size: 40px;
margin: 0 auto 14px;
display: block;
padding-bottom: 10px;
}
body {
background-color: #2B2B2B
}
.twitch-logo {
width: 140px;
height: 96px;
margin: 0 0 0 45%;
}
.stream-btn {
-webkit-border-radius: 7;
-moz-border-radius: 7;
border-radius: 7px;
text-shadow: 0px 1px 3px #666666;
font-family: Gravitas;
font-weight: bolder;
color: #ffffff;
font-size: 16px;
padding: 5px 15px 5px 15px;
border: solid #2B2B2B 2px;
text-decoration: none;
background-color: #337ab7;
border-color: #2e6da4;
margin-left: 10px;
}
.stream-btn:hover {
background: #000;
text-decoration: none;
border: solid #fff 2px;
cursor: pointer;
}
.stream-status {
width: 35%;
margin-left: 33%;
text-align: center;
margin-top: 1%;
margin-bottom: 1%;
}
.stream-input-div {
color: #F6F6F6;
font-size: 15px;
text-align: center;
padding: 5px 5px 5px 5px;
font-family: Alegreya;
}
.stream-input {
padding: 5px 5px 5px 5px;
border-radius: 7px;
width: 26.5%;
height: 10%;
color: #000;
font-family: sans-serif;
font-size: 15px;
font-weight: bolder;
margin-left: 8px;
}
.site-footer {
background-color: #F6F6F6;
border-top: 1px solid #333;
color: #000;
font-size: 15px;
text-align: center;
padding: 15px 0;
font-family: Alegreya;
}
#search-result-div {
margin-top: 2%;
margin-left: 20%;
text-align: center;
}
ul {
list-style-type: none;
width: 100%;
text-align:left;
}
h3 {
font: bold 1.5vw/1.5 Helvetica, Verdana, sans-serif;
display:inline;
}
li img {
float: left;
margin: 0 15px 0 0;
width: 100px;
height: 96px;
}
li p {
font: 200 0.9vw/1.5 Georgia, Times New Roman, serif;
margin: 0 0 1px;
}
li {
padding: 10px;
overflow: auto;
background-color: #E9E581;
color: #000;
border: solid;
border-width: 0.1px;
width: 70%;
}
li:hover {
background: #90C3D4;
cursor: pointer;
-moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.6);
-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.6);
box-shadow: 0 0 10px rgba(0, 0, 0, 0.6);
}
#search-result-div a:link {color: #337ab7;}
#search-result-div a:visited {color: #999999;}
#search-result-div a:hover {color: #333333;}
#search-result-div a:focus {color: #333333;}
#search-result-div a:active {color: #009900;}
#loading-div-background
{
display:none;
opacity: 0.8;
position:fixed;
top:0;
left:0;
background:black;
width:100%;
height:100%;
}
#loading-div
{
width: 300px;
height: 200px;
background-color: #0c0b0b;
text-align:center;
position:absolute;
left: 50%;
top: 50%;
margin-left:-150px;
margin-top: -100px;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Gravitas+One" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Black+Ops+One" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Alegreya" rel="stylesheet" />
<link href="https://code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/css-toggle-switch/latest/toggle-switch.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment