2017-06-16 01:20:27 +02:00
|
|
|
window.addEventListener('load', () => {
|
|
|
|
const repo = getQueryParams().q;
|
|
|
|
if (repo) {
|
|
|
|
document.getElementById('q').value = repo;
|
|
|
|
fetchData();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2017-03-30 20:17:39 +02:00
|
|
|
document.getElementById('form').addEventListener('submit', (e) => {
|
2017-06-16 01:20:27 +02:00
|
|
|
e.preventDefault();
|
|
|
|
fetchData();
|
|
|
|
});
|
2017-03-30 20:17:39 +02:00
|
|
|
|
2017-03-30 19:44:00 +02:00
|
|
|
function fetchData() {
|
2017-06-16 01:20:27 +02:00
|
|
|
const repo = document.getElementById('q').value;
|
|
|
|
const re = /[-_\w]+\/[-_.\w]+/;
|
|
|
|
|
|
|
|
window.history.pushState('', '', `?q=${repo}`);
|
2017-03-30 19:44:00 +02:00
|
|
|
|
|
|
|
if (re.test(repo)) {
|
2017-06-16 01:20:27 +02:00
|
|
|
fetchAndShow(repo);
|
2017-03-30 19:44:00 +02:00
|
|
|
} else {
|
2017-06-16 01:20:27 +02:00
|
|
|
showMsg('Invalid GitHub repository! Format is <username>/<repo>', 'danger');
|
2017-03-30 19:44:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function fetchAndShow(repo) {
|
2017-06-16 01:20:27 +02:00
|
|
|
document.getElementById('find').disabled = true;
|
|
|
|
document.getElementById('spinner').removeAttribute('hidden');
|
|
|
|
|
2017-03-30 19:44:00 +02:00
|
|
|
fetch(`https://api.github.com/repos/${repo}/forks?sort=stargazers`)
|
2017-06-16 01:20:27 +02:00
|
|
|
.then((response) => response.json())
|
|
|
|
.then((data) => {
|
|
|
|
showData(data);
|
|
|
|
|
|
|
|
document.getElementById('find').disabled = false;
|
|
|
|
document.getElementById('spinner').setAttribute('hidden', 'hidden');
|
|
|
|
});
|
2017-03-30 19:44:00 +02:00
|
|
|
}
|
|
|
|
|
2017-06-16 01:20:27 +02:00
|
|
|
function showMsg(msg, type) {
|
|
|
|
let alert_type = 'alert-info';
|
|
|
|
|
|
|
|
if (type === 'danger') {
|
|
|
|
alert_type = 'alert-danger';
|
|
|
|
}
|
|
|
|
|
|
|
|
document.getElementById('footer').innerHTML = '';
|
|
|
|
|
|
|
|
document.getElementById('data-body').innerHTML = `
|
|
|
|
<div class="alert ${alert_type} alert-dismissible fade show" role="alert">
|
|
|
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
|
|
|
<span aria-hidden="true">×</span>
|
|
|
|
</button>
|
|
|
|
${msg}
|
|
|
|
</div>
|
|
|
|
`;
|
2017-03-30 19:44:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function showData(data) {
|
|
|
|
if (!Array.isArray(data)) {
|
2017-06-16 01:20:27 +02:00
|
|
|
showMsg('GitHub repository does not exist', 'danger');
|
|
|
|
return;
|
2017-03-30 19:44:00 +02:00
|
|
|
}
|
2017-06-16 01:20:27 +02:00
|
|
|
|
2017-03-30 19:44:00 +02:00
|
|
|
if (data.length === 0) {
|
2017-06-16 01:20:27 +02:00
|
|
|
showMsg('No forks exist!');
|
|
|
|
return;
|
2017-03-30 19:44:00 +02:00
|
|
|
}
|
2017-06-16 01:20:27 +02:00
|
|
|
|
|
|
|
const html = [];
|
|
|
|
const thead = `
|
|
|
|
<thead>
|
|
|
|
<tr class="table-active">
|
|
|
|
<th><i class="fa fa-github" aria-hidden="true"></i> Repository</th>
|
|
|
|
<th><i class="fa fa-star" aria-hidden="true"></i> Stargazers</th>
|
|
|
|
<th><i class="fa fa-code-fork" aria-hidden="true"></i> Forks</th>
|
2017-11-28 17:41:16 +01:00
|
|
|
<th><i class="fa fa-clock-o" aria-hidden="true"></i> Last Push</th>
|
2017-06-16 01:20:27 +02:00
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
`;
|
|
|
|
|
2017-03-30 19:44:00 +02:00
|
|
|
for (const fork of data) {
|
|
|
|
const item = `
|
|
|
|
<tr>
|
|
|
|
<td><a href="${fork.html_url}">${fork.full_name}</a></td>
|
|
|
|
<td>${fork.stargazers_count}</td>
|
|
|
|
<td>${fork.forks_count}</td>
|
2017-11-28 12:13:07 +01:00
|
|
|
<td>${timeSince(fork.pushed_at)} ago</td>
|
2017-03-30 19:44:00 +02:00
|
|
|
</tr>
|
2017-06-16 01:20:27 +02:00
|
|
|
`;
|
|
|
|
html.push(item);
|
2017-03-30 19:44:00 +02:00
|
|
|
}
|
2017-06-16 01:20:27 +02:00
|
|
|
|
2017-03-30 19:52:43 +02:00
|
|
|
document.getElementById('data-body').innerHTML = `
|
2017-06-16 01:20:27 +02:00
|
|
|
<div class="table-responsive rounded">
|
|
|
|
<table class="table table-striped table-bordered table-hover">
|
|
|
|
${thead}
|
|
|
|
<tbody>${html.join('')}</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
`;
|
|
|
|
|
|
|
|
document.getElementById('footer').innerHTML = `${data.length} ${data.length == 1 ? 'result' : 'results'}`;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getQueryParams() {
|
|
|
|
let query = location.search;
|
|
|
|
if (!query) {
|
|
|
|
return { };
|
|
|
|
}
|
|
|
|
|
|
|
|
return (/^[?#]/.test(query) ? query.slice(1) : query)
|
|
|
|
.split('&')
|
|
|
|
.reduce((params, param) => {
|
|
|
|
let [ key, value ] = param.split('=');
|
|
|
|
params[key] = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : '';
|
|
|
|
return params;
|
|
|
|
}, { });
|
2017-03-30 19:44:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function timeSince(date_str) {
|
2017-06-16 01:20:27 +02:00
|
|
|
const date = new Date(date_str);
|
2017-03-30 19:44:00 +02:00
|
|
|
const seconds = Math.floor((new Date() - date) / 1000);
|
|
|
|
|
|
|
|
let interval = Math.floor(seconds / 31536000);
|
|
|
|
|
|
|
|
if (interval > 1) {
|
2017-06-16 01:20:27 +02:00
|
|
|
return interval + ' years';
|
2017-03-30 19:44:00 +02:00
|
|
|
}
|
2017-06-16 01:20:27 +02:00
|
|
|
|
2017-03-30 19:44:00 +02:00
|
|
|
interval = Math.floor(seconds / 2592000);
|
|
|
|
if (interval > 1) {
|
2017-06-16 01:20:27 +02:00
|
|
|
return interval + ' months';
|
2017-03-30 19:44:00 +02:00
|
|
|
}
|
2017-06-16 01:20:27 +02:00
|
|
|
|
2017-03-30 19:44:00 +02:00
|
|
|
interval = Math.floor(seconds / 86400);
|
|
|
|
if (interval > 1) {
|
2017-06-16 01:20:27 +02:00
|
|
|
return interval + ' days';
|
2017-03-30 19:44:00 +02:00
|
|
|
}
|
2017-06-16 01:20:27 +02:00
|
|
|
|
2017-03-30 19:44:00 +02:00
|
|
|
interval = Math.floor(seconds / 3600);
|
|
|
|
if (interval > 1) {
|
2017-06-16 01:20:27 +02:00
|
|
|
return interval + ' hours';
|
2017-03-30 19:44:00 +02:00
|
|
|
}
|
2017-06-16 01:20:27 +02:00
|
|
|
|
2017-03-30 19:44:00 +02:00
|
|
|
interval = Math.floor(seconds / 60);
|
|
|
|
if (interval > 1) {
|
2017-06-16 01:20:27 +02:00
|
|
|
return interval + ' minutes';
|
2017-03-30 19:44:00 +02:00
|
|
|
}
|
2017-06-16 01:20:27 +02:00
|
|
|
|
|
|
|
return Math.floor(seconds) + ' seconds';
|
2017-03-30 19:44:00 +02:00
|
|
|
}
|