Last active
December 9, 2019 11:11
-
-
Save Decicus/03d8c3b9e576febd96e0f64cdf64d8d6 to your computer and use it in GitHub Desktop.
Very basic progress bar / goal example with Twitch subpoints - Licensed under MIT License
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title></title> | |
<link href="https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/cosmo/bootstrap.min.css" rel="stylesheet" integrity="sha384-qdQEsAI45WFCO5QwXBelBe1rR9Nwiss4rGEqiszC+9olH1ScrLrMQr1KmDR964uZ" crossorigin="anonymous"> | |
<style type="text/css"> | |
body { | |
margin-top: 40px; | |
} | |
</style> | |
<script type="text/javascript"> | |
const params = new URLSearchParams(window.location.search); | |
/** | |
* The channel that should be used in the subpoints API. | |
*/ | |
const channel = params.get('channel') || 'decicus'; | |
/** | |
* The "goal" of how many subpoints you want | |
*/ | |
const goal = parseInt(params.get('goal'), 10) || 25; | |
/** | |
* How many subpoints to subtract from the final count. | |
* | |
* This is ignored when `useTestValues` is true, | |
* because it generates random numbers anyways. | |
*/ | |
const subtract = parseInt(params.get('subtract'), 10) || 0; | |
/** | |
* Default: `true` = It displays: "5.55%" instead | |
* | |
* `false` = It displays: "subpoints / goal" - Example: 555 / 100000 | |
*/ | |
const percentageText = params.get('percentage_text') === '0' ? false : true; | |
/** | |
* Specify the height of the progress bar. | |
* | |
* Default is 20 (px) | |
*/ | |
const height = params.get('height') || '20'; | |
/** | |
* How often the subpoints should be updated. | |
*/ | |
const intervalSeconds = 60; | |
/** | |
* Default: `false` - Normal behavior. Regularly requests a new subpoints from the API and updates values accordingly. | |
* | |
* `true` - Instead of using the API, it will generate a random number between 0 and `goal` | |
* and use that value in progress bar. | |
* Mainly used for debugging / testing purposes | |
*/ | |
const useTestValues = params.get('test') === '1'; | |
</script> | |
</head> | |
<body> | |
<div class="container-fluid"> | |
<div id="progress-parent" class="progress mx-auto" style="height: 0px;"> | |
<div id="bar" class="progress-bar bg-success" style="width: 0%;"></div> | |
</div> | |
</div> | |
<script type="text/javascript"> | |
const bar = document.getElementById('bar'); | |
const progressParent = document.getElementById('progress-parent'); | |
/** | |
* Logging mainly used for debugging | |
*/ | |
function log(funcName, text) | |
{ | |
// Only log when using test values | |
if (!useTestValues) | |
{ | |
return; | |
} | |
const validTypes = ['string', 'number']; | |
console.log(`[${funcName}] ${text}`); | |
// Log objects and such separately. | |
if (!validTypes.includes(typeof text)) { | |
console.log(text); | |
} | |
} | |
/** | |
* Contacts the API to retrieve the current subpoints. | |
*/ | |
async function getSubpoints() | |
{ | |
const response = await fetch(`https://decapi.me/twitch/subpoints/${channel}?subtract=${subtract}`); | |
const subpoints = await response.text(); | |
/** | |
* Verify that the response is only digits. Error responses should be ignored | |
*/ | |
if (/^\d+$/.test(subpoints)) { | |
log('getSubpoints', subpoints); | |
return parseInt(subpoints, 10); | |
} | |
log('getSubpoints', 'null'); | |
return null; | |
} | |
/** | |
* Updates the progress bar with the correct visuals. | |
*/ | |
async function setProgressBar(subpoints) | |
{ | |
const ratio = subpoints / goal; | |
const percentage = `${(ratio * 100).toFixed(2)}%`; | |
const ratioText = `${subpoints} / ${goal}`; | |
log('setProgressBar', percentage); | |
log('setProgressBar', ratioText); | |
bar.style.width = percentage; | |
bar.innerText = percentageText ? percentage : ratioText; | |
progressParent.style.height = `${height}px`; | |
} | |
/** | |
* Used for testing. | |
* Generates a random "subpoints" value to see how the progress bar behaves. | |
*/ | |
async function testRandomSubpoints() | |
{ | |
return Math.floor(Math.random() * goal) + 1; | |
} | |
/** | |
* Helper function for updating subpoints | |
* This checks if we should use test values or not. | |
*/ | |
async function updateSubpoints() | |
{ | |
let subpoints = null; | |
if (useTestValues) | |
{ | |
subpoints = await testRandomSubpoints(); | |
} | |
else | |
{ | |
subpoints = await getSubpoints(); | |
} | |
log('updateSubpoints', subpoints); | |
if (Number.isInteger(subpoints)) | |
{ | |
setProgressBar(subpoints); | |
} | |
} | |
document.addEventListener('DOMContentLoaded', async() => { | |
await updateSubpoints(); | |
setInterval(async() => { | |
await updateSubpoints(); | |
}, intervalSeconds * 1000); | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment