dynamic favicon that indicates if an entry is running (#4038)
This commit is contained in:
@@ -13,7 +13,8 @@ As announced in the [README](README.md) I only support the latest available rele
|
|||||||
## Reporting a Vulnerability
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
Please read the [Bughunter](https://www.kimai.org/documentation/bughunter.html) documentation before posting.
|
Please read the [Bughunter](https://www.kimai.org/documentation/bughunter.html) documentation before posting.
|
||||||
You can report any security related vulnerability in the [advisory section at GitHub](https://github.com/kimai/kimai/security/advisories) or via email to kpapst@gmx.net.
|
You can report any security related vulnerability in the [advisory section at GitHub](https://github.com/kimai/kimai/security/advisories)
|
||||||
|
or via email to [support@kimai.org](mailto:support@kimai.org).
|
||||||
|
|
||||||
I will work as fast as I can to fix the problem and publish a bugfix release / security update.
|
I will work as fast as I can to fix the problem and publish a bugfix release / security update.
|
||||||
Depending on the size of the required fixes, this might take a couple of hours or a couple of days.
|
Depending on the size of the required fixes, this might take a couple of hours or a couple of days.
|
||||||
@@ -22,3 +23,5 @@ You can expect that your message will be answered ASAP.
|
|||||||
|
|
||||||
You will be mentioned in the release notes if your issue is valid.
|
You will be mentioned in the release notes if your issue is valid.
|
||||||
I am grateful for any (discrete) disclosure of vulnerabilities!
|
I am grateful for any (discrete) disclosure of vulnerabilities!
|
||||||
|
|
||||||
|
Please note: if you are asking for money, I will not reply. I receive these scam messages every day...
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export default class KimaiActiveRecords extends KimaiPlugin {
|
|||||||
super();
|
super();
|
||||||
this._selector = '.ticktac-menu';
|
this._selector = '.ticktac-menu';
|
||||||
this._selectorEmpty = '.ticktac-menu-empty';
|
this._selectorEmpty = '.ticktac-menu-empty';
|
||||||
|
this._favIconUrl = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,8 +53,6 @@ export default class KimaiActiveRecords extends KimaiPlugin {
|
|||||||
// handle duration in the visible UI
|
// handle duration in the visible UI
|
||||||
this._updateBrowserTitle = !!this.getConfiguration('updateBrowserTitle');
|
this._updateBrowserTitle = !!this.getConfiguration('updateBrowserTitle');
|
||||||
|
|
||||||
// deactivated direct duration update, becuase it is unclear
|
|
||||||
// this._updateDuration();
|
|
||||||
const handle = () => {
|
const handle = () => {
|
||||||
this._updateDuration();
|
this._updateDuration();
|
||||||
};
|
};
|
||||||
@@ -77,6 +76,10 @@ export default class KimaiActiveRecords extends KimaiPlugin {
|
|||||||
// needs to search in document, to find all running entries, both in "ticktac" and listing pages
|
// needs to search in document, to find all running entries, both in "ticktac" and listing pages
|
||||||
const activeRecords = document.querySelectorAll('[data-since]:not([data-since=""])');
|
const activeRecords = document.querySelectorAll('[data-since]:not([data-since=""])');
|
||||||
|
|
||||||
|
if (this._updateBrowserTitle) {
|
||||||
|
this._changeFavicon(activeRecords.length > 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (activeRecords.length === 0) {
|
if (activeRecords.length === 0) {
|
||||||
if (this._updateBrowserTitle) {
|
if (this._updateBrowserTitle) {
|
||||||
if (document.body.dataset['title'] === undefined) {
|
if (document.body.dataset['title'] === undefined) {
|
||||||
@@ -195,4 +198,36 @@ export default class KimaiActiveRecords extends KimaiPlugin {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {boolean} running
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_changeFavicon(running)
|
||||||
|
{
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
const orig = document.getElementById('favicon');
|
||||||
|
if (this._favIconUrl === null) {
|
||||||
|
this._favIconUrl = orig.href;
|
||||||
|
}
|
||||||
|
const link = orig.cloneNode(true);
|
||||||
|
|
||||||
|
if (canvas.getContext && link) {
|
||||||
|
const ratio = window.devicePixelRatio;
|
||||||
|
const img = document.createElement('img');
|
||||||
|
canvas.height = canvas.width = 16 * ratio;
|
||||||
|
img.onload = function () {
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
|
||||||
|
if (running) {
|
||||||
|
const width = 5.5 * ratio;
|
||||||
|
ctx.fillStyle = 'rgb(182,57,57)';
|
||||||
|
ctx.fillRect((canvas.width / 2) - (width / 2), (canvas.height / 2) - (width / 2), width, width);
|
||||||
|
}
|
||||||
|
link.href = canvas.toDataURL('image/png');
|
||||||
|
orig.remove();
|
||||||
|
document.head.appendChild(link);
|
||||||
|
};
|
||||||
|
img.src = this._favIconUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
2
public/build/app.f0378e96.js
Normal file
2
public/build/app.f0378e96.js
Normal file
File diff suppressed because one or more lines are too long
@@ -3,7 +3,7 @@
|
|||||||
"app": {
|
"app": {
|
||||||
"js": [
|
"js": [
|
||||||
"/build/runtime.f0079159.js",
|
"/build/runtime.f0079159.js",
|
||||||
"/build/app.70a820f6.js"
|
"/build/app.f0378e96.js"
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
"/build/app.2005c135.css"
|
"/build/app.2005c135.css"
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
},
|
},
|
||||||
"integrity": {
|
"integrity": {
|
||||||
"/build/runtime.f0079159.js": "sha384-H22sAW1aTvyIPqvHOvGXWSWTxf0y6mptp+MsVmyXCfjx/WJjBbhX9gbUZ+qIuihV",
|
"/build/runtime.f0079159.js": "sha384-H22sAW1aTvyIPqvHOvGXWSWTxf0y6mptp+MsVmyXCfjx/WJjBbhX9gbUZ+qIuihV",
|
||||||
"/build/app.70a820f6.js": "sha384-WKz8wOwY8EYT1ncPkMRnEE3q5LnP76keOZxTD410dXpsowUktUg+vWUqDhVXwLat",
|
"/build/app.f0378e96.js": "sha384-ohZkuGMYJFa1nD/JJb1XJy6CYfqk/ubIo9QuY3yYJFg7NEG+0U93+YIIvUnCm2xm",
|
||||||
"/build/app.2005c135.css": "sha384-mXP2EO6K1kvUNEFBxLHjXlgkfWSFtyLC1rFhhX5qMbpOHvZrl8Ny1zP03ToPkF6d",
|
"/build/app.2005c135.css": "sha384-mXP2EO6K1kvUNEFBxLHjXlgkfWSFtyLC1rFhhX5qMbpOHvZrl8Ny1zP03ToPkF6d",
|
||||||
"/build/export-pdf.d367a32e.js": "sha384-Z5baqnzjI636nYFs4g63ViIKBZKRW4Jhv/7PQmTEQlqhfA7eK0vUMUtiyy0R5A9u",
|
"/build/export-pdf.d367a32e.js": "sha384-Z5baqnzjI636nYFs4g63ViIKBZKRW4Jhv/7PQmTEQlqhfA7eK0vUMUtiyy0R5A9u",
|
||||||
"/build/export-pdf.d8a6c23b.css": "sha384-ztepocHE4rnGE9eKZ4kL6jTKaePUyiwiB9TjJjstjpf/ckcKg1HedrEOOk/8ElJg",
|
"/build/export-pdf.d8a6c23b.css": "sha384-ztepocHE4rnGE9eKZ4kL6jTKaePUyiwiB9TjJjstjpf/ckcKg1HedrEOOk/8ElJg",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"build/app.css": "/build/app.2005c135.css",
|
"build/app.css": "/build/app.2005c135.css",
|
||||||
"build/app.js": "/build/app.70a820f6.js",
|
"build/app.js": "/build/app.f0378e96.js",
|
||||||
"build/export-pdf.css": "/build/export-pdf.d8a6c23b.css",
|
"build/export-pdf.css": "/build/export-pdf.d8a6c23b.css",
|
||||||
"build/export-pdf.js": "/build/export-pdf.d367a32e.js",
|
"build/export-pdf.js": "/build/export-pdf.d367a32e.js",
|
||||||
"build/invoice.css": "/build/invoice.5bea118e.css",
|
"build/invoice.css": "/build/invoice.5bea118e.css",
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ class Constants
|
|||||||
/**
|
/**
|
||||||
* The current release version
|
* The current release version
|
||||||
*/
|
*/
|
||||||
public const VERSION = '2.0.22';
|
public const VERSION = '2.0.23';
|
||||||
/**
|
/**
|
||||||
* The current release: major * 10000 + minor * 100 + patch
|
* The current release: major * 10000 + minor * 100 + patch
|
||||||
*/
|
*/
|
||||||
public const VERSION_ID = 20022;
|
public const VERSION_ID = 20023;
|
||||||
/**
|
/**
|
||||||
* The software name
|
* The software name
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}">
|
<link id="favicon" rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}">
|
||||||
<link rel="icon" type="image/png" href="{{ asset('favicon-16x16.png') }}" sizes="16x16">
|
<link rel="icon" type="image/png" href="{{ asset('favicon-16x16.png') }}" sizes="16x16">
|
||||||
<link rel="icon" type="image/png" href="{{ asset('favicon-32x32.png') }}" sizes="32x32">
|
<link rel="icon" type="image/png" href="{{ asset('favicon-32x32.png') }}" sizes="32x32">
|
||||||
<link rel="apple-touch-icon" href="{{ asset('apple-touch-icon.png') }}">
|
<link rel="apple-touch-icon" href="{{ asset('apple-touch-icon.png') }}">
|
||||||
|
|||||||
Reference in New Issue
Block a user