Skip to content

Instantly share code, notes, and snippets.

@maxpowa
Last active May 22, 2020 17:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save maxpowa/d3eb439b990fbee8cff2ae45d726c834 to your computer and use it in GitHub Desktop.
Save maxpowa/d3eb439b990fbee8cff2ae45d726c834 to your computer and use it in GitHub Desktop.
recent repos on sidebar
// ==UserScript==
// @name Github Chronological Repo List
// @namespace https://gist.github.com/maxpowa/d3eb439b990fbee8cff2ae45d726c834
// @description Bring back chronological repo list on the github home page
// @include https://github.com/
// @version 0.0.2
// @require https://openuserjs.org/src/libs/sizzle/GM_config.js
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
GM_config.init(
{
'id': 'ghcrl', // The id used for this instance of GM_config
'fields': // Fields object
{
'user_token': // This is the id of the field
{
'label': 'Github Personal access token from https://github.com/settings/tokens',
'type': 'text', // Makes this setting a text field
'default': '' // Default value if user doesn't change it
}
}
});
if (GM_config.get('user_token').length === 0) {
GM_config.open();
}
(async function() {
const USER_TOKEN = GM_config.get('user_token');
const MAX_REPOS_TO_DISPLAY = 7;
const username = document.head.querySelector('[name=user-login]').content;
const headers = new Headers({
'Authorization': 'Basic ' + btoa(`${username}:${USER_TOKEN}`)
});
const fetches = []
for (let page = 1; page < 10; page++) {
fetches.push(fetch(`https://api.github.com/users/${username}/events?page=${page}`, {
method: 'GET',
headers,
}));
}
const responses = await Promise.all(fetches);
const allEventsArray = await Promise.all(responses.filter(res => res.ok).map(res => res.json()));
const recentActivity = [].concat.apply([], allEventsArray);
const repos = recentActivity.reduce((acc, value) => {
const count = acc[value.repo.name] || 0;
return {
...acc,
[value.repo.name]: count + 1,
}
}, {});
const insertAfter = (el, referenceNode) => {
referenceNode.parentNode.insertBefore(el, referenceNode.nextSibling);
}
const truncatedSpan = text => `<span class="css-truncate css-truncate-target" style="max-width: 48%" title="${text}">${text}</span>`;
const wrapper = document.createElement('div');
wrapper.innerHTML = `<div class="mb-3 custom-timeline" role="navigation">
<div class="js-repos-container">
<h4 class="f5 mb-1 flex-items-center">Recent Activity</h4>
<ul class="custom-recent-activity-list list-style-none pr-3">
</ul>
</div>
</div>`;
insertAfter(wrapper, document.body.querySelector('div.dashboard-sidebar .account-switcher'));
const listElement = wrapper.querySelector('.custom-recent-activity-list');
Object.keys(repos).slice(0, MAX_REPOS_TO_DISPLAY + 1).map((repo) => listElement.innerHTML += `<li>
<div class="width-full text-bold">
<a class="d-flex flex-items-baseline flex-items-center f5 mb-2" href="/${repo}">
${truncatedSpan(repo.split('/')[0])}/${truncatedSpan(repo.split('/')[1])}
</a>
</div>
</li>`);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment