-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.user.js
156 lines (137 loc) · 4.96 KB
/
main.user.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// ==UserScript==
// @name GitHub Enhancements
// @namespace http://github.mheducation.com/
// @version 0.1
// @description
// @author Christopher Carman
// @match https://github.mheducation.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
const APPROVALS_REQUIRED = 2;
function customStyles() {
let style = document.createElement('style');
style.type = 'text/css';
style.innerText = `
.badge {
color: white;
padding: 2px 4px;
margin: 0 4px;
font-size: smaller;
}
.no-dec {
text-decoration: none !important;
}
.task-progress .progress {
float: left;
}
`;
document.body.appendChild(style);
}
function progressBar(bars) {
let wrapper = document.createElement('span');
wrapper.setAttribute('data-monkey-cleanup', true);
wrapper.classList.add('task-progress');
let bar = document.createElement('span');
bar.classList.add('progress-bar');
let percentLeft = 1;
bars.forEach(function(info) {
let percent = info[0];
let color = info[1];
let progress = document.createElement('span');
let physicalPercent = Math.min(percent, percentLeft, 1);
progress.classList.add('progress');
progress.style.width = `${physicalPercent * 100}%`;
percentLeft -= physicalPercent;
if (color) {
progress.style.backgroundColor = color;
}
bar.appendChild(progress);
});
wrapper.appendChild(bar);
return wrapper;
}
function approvalsComboBar(approvals, rejections) {
let container = document.createElement('span');
container.setAttribute('data-monkey-cleanup', true);
let text = document.createElement('span');
let barcolor;
let badgecolor;
if(approvals < APPROVALS_REQUIRED) {
barcolor = 'cornflowerblue';
} else {
barcolor = 'limegreen';
}
if (rejections) {
badgecolor = 'darkorange';
} else {
badgecolor = barcolor;
}
text.classList.add('badge');
text.style.backgroundColor = badgecolor;
text.innerText = `${approvals + rejections} of ${APPROVALS_REQUIRED}`;
let progress = progressBar([[rejections/APPROVALS_REQUIRED, 'darkorange'], [approvals/APPROVALS_REQUIRED, barcolor]]);
container.appendChild(text);
container.appendChild(progress);
return container;
}
function expandReviewTooltips() {
if (window.location.pathname.includes('/pulls')) {
const reviewLinks = document.querySelectorAll('.js-issue-row .d-inline-block a.tooltipped[aria-label]');
for(let i = 0, n = reviewLinks.length; i < n; i++) {
const label = reviewLinks[i].getAttribute('aria-label');
if (label) {
if (label.match(/(?:(\d+)\s+review approval)|(?:(\d+)\s+reviews? requesting change)|review required/i)) {
const approvals = Number(RegExp.$1);
const rejections = Number(RegExp.$2);
reviewLinks[i].classList.remove('muted-link');
reviewLinks[i].classList.add('no-dec');
reviewLinks[i].innerHTML = '';
reviewLinks[i].appendChild(approvalsComboBar(approvals, rejections));
}
}
}
}
if(window.location.pathname.includes("/pull/")) {
const container = document.querySelector('.js-review-requests-menu');
if (!container) {
return;
}
const list = container.nextElementSibling;
const approvals = list.querySelectorAll('.octicon-check').length;
const rejections = list.querySelectorAll('.octicon-x').length;
const progress = approvalsComboBar(approvals, rejections);
container.children[0].appendChild(progress);
}
}
function cleanup() {
Array.from(document.querySelectorAll(`[data-monkey-cleanup]`)).map(function(element) {
element.remove();
});
}
function run() {
customStyles();
expandReviewTooltips();
}
function setupXHRProxy(callback) {
// Proxy XHR requests so we can hook in callbacks
// Yanked from https://stackoverflow.com/a/28303226/4175944
var oldXHR = window.XMLHttpRequest;
function newXHR() {
var realXHR = new oldXHR();
realXHR.addEventListener("readystatechange", function() {
if(realXHR.readyState === 4 && realXHR.status === 200){
setTimeout(callback, 1);
}
}, false);
return realXHR;
}
window.XMLHttpRequest = newXHR;
}
run();
setupXHRProxy(function() {
cleanup();
run();
});
})();