Skip to content

Commit

Permalink
#144: added favicon for executing/finished scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
bugy committed Apr 30, 2019
1 parent 8f1757d commit 2a29bec
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 1 deletion.
141 changes: 141 additions & 0 deletions web-src/js/components/favicon/favicon_manager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import {isNull} from '../../common';

export const defaultFavicon = createDefaultFavicon();
export let executingFavicon;
export let finishedFavicon;

const FILL_COLOR = '#66FF00';
const STROKE_COLOR = '#444444';

let currentIcon = 'defaultFavicon';

const faviconImage = new Image();
faviconImage.src = defaultFavicon.href;

faviconImage.onload = function () {
executingFavicon = createExecutingFavicon(faviconImage);
finishedFavicon = createFinishedFavicon(faviconImage);

setCurrentIcon();
};

export function setDefaultFavicon() {
currentIcon = 'defaultFavicon';

setFavicon(defaultFavicon);
}

export function setExecutingFavicon() {
currentIcon = 'executingFavicon';

if (!isNull(executingFavicon)) {
setFavicon(executingFavicon);
} else {
setFavicon(defaultFavicon);
}
}

export function setFinishedFavicon() {
currentIcon = 'finishedFavicon';

if (!isNull(finishedFavicon)) {
setFavicon(finishedFavicon);
} else {
setFavicon(defaultFavicon);
}
}

function setFavicon(favicon) {
const head = document.getElementsByTagName('head')[0];

for (let i = 0; i < head.childNodes.length; i++) {
const child = head.childNodes[i];
if ((child.tagName === 'LINK') && (child.type === 'image/x-icon')) {
head.replaceChild(favicon, child);
return;
}
}

head.appendChild(favicon);
}

function setCurrentIcon() {
switch (currentIcon) {
case 'executingFavicon': {
setFavicon(executingFavicon);
return;
}
case 'finishedFavicon': {
setFavicon(finishedFavicon);
return;
}
default: {
setFavicon(defaultFavicon);
}
}
}


function createLink(href) {
const link = document.createElement('link');
link.type = 'image/x-icon';
link.rel = 'shortcut icon';
link.href = href;
return link;
}

function createDefaultFavicon() {
return createLink('favicon.ico');
}

function createExecutingFavicon(baseImage) {
const {canvas, context} = prepareCanvas(baseImage);

const radius = baseImage.width / 5;
const offsetX = baseImage.width / 4 * 3;
const offsetY = baseImage.height / 4 * 3;

context.beginPath();
context.arc(offsetX, offsetY, radius, 0, 2 * Math.PI, true);
context.fillStyle = FILL_COLOR;
context.fill();

context.lineWidth = 2;
context.strokeStyle = STROKE_COLOR;
context.stroke();

return createLink(canvas.toDataURL('image/x-icon'));
}

function createFinishedFavicon(baseImage) {
const {canvas, context} = prepareCanvas(baseImage);

const offsetX = baseImage.width / 4 * 3;
const offsetY = baseImage.height / 4 * 3;

function drawTick(lineWidth, color) {
context.beginPath();
context.moveTo(offsetX - 10, offsetY - 8);
context.lineTo(offsetX, offsetY + 8);
context.lineTo(offsetX + 10, offsetY - 8);
context.lineWidth = lineWidth;
context.strokeStyle = color;
context.stroke();
}

drawTick(8, STROKE_COLOR);
drawTick(5, FILL_COLOR);

return createLink(canvas.toDataURL('image/x-icon'));
}

function prepareCanvas(baseImage) {
const canvas = document.createElement('canvas');
canvas.width = baseImage.width;
canvas.height = baseImage.height;

const context = canvas.getContext('2d');
context.drawImage(baseImage, 0, 0);

return {canvas, context};
}
29 changes: 28 additions & 1 deletion web-src/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
hasClass,
hide,
HttpRequestError,
HttpUnauthorizedError,
HttpUnauthorizedError, isEmptyArray,
isEmptyObject,
isNull,
logError,
Expand All @@ -19,6 +19,7 @@ import {
} from './common';

import './connections/rxWebsocket.js';
import {setDefaultFavicon, setExecutingFavicon, setFinishedFavicon} from './components/favicon/favicon_manager';
import {ScriptController} from './script/script-controller';
import {restoreExecutor} from './script/script-execution-model';
import './style_imports.js';
Expand All @@ -44,6 +45,8 @@ function onLoad() {
});
scriptSelectionListeners.push(updateTitle);

setDefaultFavicon();

var response = authorizedCallHttp('scripts');

var scripts = JSON.parse(response);
Expand Down Expand Up @@ -85,6 +88,7 @@ function onLoad() {
scriptMenuItems.set(script, scriptElement);

updateMenuItemState(script);
updateFavicon();
});

var contentPanel = document.getElementById('content-panel');
Expand Down Expand Up @@ -321,10 +325,12 @@ function initWelcomeIcon() {
function addRunningExecutor(scriptExecutor) {
runningScriptExecutors.push(scriptExecutor);
updateMenuItemState(scriptExecutor.scriptName);
updateFavicon();

scriptExecutor.addListener({
'onExecutionStop': function () {
updateMenuItemState(scriptExecutor.scriptName);
updateFavicon();
}
})
}
Expand All @@ -340,6 +346,7 @@ function showScript(selectedScript, parameterValues) {
removeElements(runningScriptExecutors, executorsToRemove);

updateMenuItemState(previousScriptName);
updateFavicon();
}

activeScriptController.destroy();
Expand Down Expand Up @@ -459,6 +466,26 @@ function updateMenuItemState(scriptName) {
}
}

function updateFavicon() {
if (isEmptyArray(runningScriptExecutors)) {
setDefaultFavicon();
return;
}

let hasExecuting = false;
runningScriptExecutors.forEach(function (executor) {
if (!executor.isFinished()) {
hasExecuting = true;
}
});

if (hasExecuting) {
setExecutingFavicon();
} else {
setFinishedFavicon();
}
}

export function authorizedCallHttp(url, object, method, asyncHandler) {
try {
return callHttp(url, object, method, asyncHandler);
Expand Down

0 comments on commit 2a29bec

Please sign in to comment.