Skip to content
This repository was archived by the owner on Jul 19, 2021. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ You can [install](https://chrome.google.com/extensions/detail/lnalnbkkohdcnaapee
### Version 0.3.2

* Merged Pull Request #7 from Nick Doyle (Manifest v2 & updated styling)
* add desktop notifications

### Version 0.3.1

Expand Down
70 changes: 64 additions & 6 deletions background.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,31 @@ var green;
var abortTimer;
var refreshTimer;
var jobs;
var previousJobsByName;
var xhr;
var showNotification;

function init() {
desc = localStorage.desc == 'true';
green = localStorage.green == 'true';
showNotification = localStorage.showNotification == 'true';

if (!localStorage.url) {
updateStatus(-1);
jobs = null;
return;
} else
requestUrl = localStorage.url;

refreshTime = localStorage.refreshTime || REFRESH_DEFAULT;
refreshTime *= 60 * 1000; // minutes in ms

if (typeof localStorage.username == 'string') {
auth = window.btoa((localStorage.username || '') + ':' + (localStorage.password || ''));
} else {
auth = null;
}

doRequest();
}

Expand All @@ -40,7 +44,7 @@ function doRequest() {
xhr = new XMLHttpRequest();
window.clearTimeout(abortTimer);
abortTimer = window.setTimeout(xhr.abort, REQUEST_TIMEOUT);

try {
xhr.onreadystatechange = checkResponse;
xhr.onerror = handleError;
Expand All @@ -54,14 +58,68 @@ function doRequest() {
}
}


// Displays a notification popup
function notify(message) {
try {
var notification = webkitNotifications.createNotification("./images/icon48.png", "Hudson", message);
var timeout = 15;

notification.show();
if( localStorage.showNotificationTime ) {
setTimeout(function () { notification.cancel(); }, localStorage.showNotificationTime * 1000);
}

} catch (e) {
alert("error displaying notification");
}
}


function checkResponse() {
if (xhr.readyState != 4) return;

if (xhr.status == 200 && xhr.responseText) {
var response = JSON.parse(xhr.responseText);
var topStatus = -1;
if (response.jobs) {
jobs = response.jobs;

if (previousJobsByName) {
var jobsByName = {};
var msgs = jobs
// find the jobs with status changes and reindex the jobs
.map(function (job) {
var previousJob = previousJobsByName[job.name];
jobsByName[job.name] = job;
if (!previousJob) {
return job.name + ' was added';
} else if (job.color !== previousJob.color) {
switch(job.color) {
case 'green_anime':
case 'blue_anime':
case 'green':
case 'blue':
return job.name + ' is now passing!';
case 'red_anime':
case 'red':
return job.name + ' is now failing!';
}
}
})
// filter out empty messages
.filter(Boolean);

if(msgs.length) {
notify(msgs.join('\n'));
}
previousJobsByName = jobsByName;
} else {
previousJobsByName = {};
jobs.forEach(function (job) {
previousJobsByName[job.name] = job;
});
}
if (localStorage.sorting == 'status') {
jobs.sort(sortByStatus);
} else {
Expand Down Expand Up @@ -97,7 +155,7 @@ function handleError(error) {
function sortByName(a, b) {
var o1 = a.name.toLowerCase();
var o2 = b.name.toLowerCase();

if (o1 < o2) return desc ? 1 : -1;
else if (o2 < o1) return desc ? -1 : 1;
else return 0;
Expand Down
20 changes: 18 additions & 2 deletions options.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
<link rel="stylesheet" type="text/css" href="style.css"/>
<script type="text/javascript" src="constants.js"></script>
<script type="text/javascript" src="options.js"></script>

</head>
<body>
<h1>Hudson Monitor</h1>
Expand Down Expand Up @@ -52,6 +51,24 @@ <h1>Hudson Monitor</h1>
</td>
</tr>
</table>
</fieldset>
<fieldset>
<legend><input type="checkbox" id="showNotifications"/> Desktop Notifications</legend>
<table>
<tr>
<td><label for="notificationTimeout">Hide notification after:</label></td>
<td colspan="2">
<select id="notificationTimeout" name="notificationTimeout">
<option value="0">never hide</option>
<option value="5">5 seconds</option>
<option value="15">15 seconds</option>
<option value="30">30 seconds</option>
<option value="60">1 minute</option>
<option value="300">5 minutes</option>
</select>
</td>
</tr>
</table>
</fieldset>
<fieldset>
<legend>
Expand Down Expand Up @@ -102,4 +119,3 @@ <h1>Hudson Monitor</h1>
</div>
</body>
</html>

106 changes: 88 additions & 18 deletions options.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* jshint eqeqeq:false, -W041: false, undef: true, browser:true */
/* global REFRESH_DEFAULT, REQUEST_TIMEOUT, STATUSES, chrome, webkitNotifications */
/*
Copyright 2010 Henning Hoefer

Expand All @@ -14,6 +16,7 @@
limitations under the License.
*/
var saveButton;
var cancelButton;
var urlInput;
var errorImage;
var refreshDropdown;
Expand All @@ -23,18 +26,24 @@ var passwordInput;
var sortByName;
var sortByStatus;
var sortDesc;
var greenBalls;
var notificationCheckbox;
var notificationTimeout;


function init() {
var inputs;
var i;

// All text inputs onKeyup = makeDirty
var inputs = document.querySelectorAll('input[type=text]');
for (var i = 0; i < inputs.length; i++) {
inputs = document.querySelectorAll('input[type=text]');
for (i = 0; i < inputs.length; i++) {
inputs[i].addEventListener('keyup', markDirty);
}

// All other inputs onChange = makeDirty
var inputs = document.querySelectorAll('input[type=password], input[type=checkbox], input[type=radio], select');
for (var i = 0; i < inputs.length; i++) {
inputs = document.querySelectorAll('input[type=password], input[type=checkbox], input[type=radio], select');
for (i = 0; i < inputs.length; i++) {
inputs[i].addEventListener('change', markDirty);
}

Expand All @@ -44,7 +53,7 @@ function init() {

saveButton.addEventListener('click', save);
cancelButton.addEventListener('click', init);

urlInput = document.getElementById('url');
errorImage = document.getElementById('error');
urlInput.value = localStorage.url || 'http://';
Expand All @@ -53,16 +62,33 @@ function init() {
} else {
errorImage.style.visibility = 'hidden';
}

refreshDropdown = document.getElementById('refresh');
var refreshTime = localStorage.refreshTime || REFRESH_DEFAULT;
for (var i = 0; i < refreshDropdown.options.length; i++) {
for (i = 0; i < refreshDropdown.options.length; i++) {
if (refreshDropdown.options[i].value == refreshTime) {
refreshDropdown.selectedIndex = i;
break;
}
}


notificationCheckbox = document.getElementById('showNotifications');
notificationTimeout = document.getElementById('notificationTimeout');
if (localStorage.showNotification == 'true') {
notificationCheckbox.checked = true;
notificationTimeout.disabled = false;
} else {
notificationCheckbox.checked = false;
notificationTimeout.disabled = true;
}
if (localStorage.notificationTimeout) {
notificationTimeout.options.forEach(function (option, i) {
if (option.value == localStorage.notificationTimeout) {
notificationTimeout.selectedIndex = i;
}
});
}

authCheckbox = document.getElementById('auth');
usernameInput = document.getElementById('username');
passwordInput = document.getElementById('password');
Expand All @@ -77,7 +103,7 @@ function init() {
usernameInput.disabled = true;
passwordInput.disabled = true;
}

sortByName = document.getElementById('sortByName');
sortByStatus = document.getElementById('sortByStatus');
sortDesc = document.getElementById('sortDesc');
Expand All @@ -88,11 +114,11 @@ function init() {
}
if (typeof localStorage.desc == 'string')
sortDesc.checked = true;

greenBalls = document.getElementById('greenBalls');
if (typeof localStorage.green == 'string')
greenBalls.checked = true;

markClean();
}

Expand All @@ -102,21 +128,27 @@ function save() {
} else {
delete localStorage.url;
}


if (notificationTimeout.value != "0") {
localStorage.notificationTimeout = notificationTimeout.value;
} else {
delete localStorage.notificationTimeout;
}

if (refreshDropdown.value != REFRESH_DEFAULT) {
localStorage.refreshTime = refreshDropdown.value;
} else {
delete localStorage.refreshTime;
}

if (authCheckbox.checked) {
localStorage.username = usernameInput.value;
localStorage.password = passwordInput.value;
} else {
delete localStorage.username;
delete localStorage.password;
}

if (sortByStatus.checked == true) {
localStorage.sorting = 'status';
} else {
Expand All @@ -127,13 +159,19 @@ function save() {
} else {
delete localStorage.desc;
}

if (greenBalls.checked == true) {
localStorage.green = 'true';
} else {
delete localStorage.green;
}


if (notificationCheckbox.checked == true) {
localStorage.showNotification = 'true';
} else {
delete localStorage.showNotification;
}

init();
chrome.extension.getBackgroundPage()["init"]();
}
Expand All @@ -144,20 +182,52 @@ function markDirty() {
} else {
errorImage.style.visibility = 'hidden';
}

if (authCheckbox.checked == true) {
usernameInput.disabled = false;
passwordInput.disabled = false;
} else {
usernameInput.disabled = true;
passwordInput.disabled = true;
}


if (notificationCheckbox.checked == true) {
requestUserPermission();
notificationTimeout.disabled = false;
} else {
notificationTimeout.disabled = true;
}

saveButton.disabled = false;
}

function markClean() {
saveButton.disabled = true;
}

function requestUserPermission() {
try {
if (notificationCheckbox.checked) {
if (checkUserPermission())
return;

if (typeof webkitNotifications != "undefined") {
webkitNotifications.requestPermission(function () {
notificationCheckbox.checked = checkUserPermission();
});
}
}
} catch (e) {
notificationCheckbox.checked = false;
}
}

function checkUserPermission() {
try {
return (webkitNotifications.checkPermission() === 0);
} catch (e) {
return false;
}
}

document.addEventListener('DOMContentLoaded', init);