It may seem a bit obsessive and/or pedantic, but the following script allows me to see when posts are ready for reviewing.
I developed this UserScript for use with TamperMonkey to allow me to have a tab open for a review queue, and then when an item is ready for review, the tab will be highlighted with an asterisk on the far left. Until an item is ready, an animation effect is applied to the title to show that a timer is currently running before refreshing the page. I have considered inspecting the number of action buttons to discern if an item is ready to be reviewed instead of inspecting the URL but this technique seems to work fine.
Questions:
- How does the ecmascript-6 usage look?
- What would you change and/or code differently?
// ==UserScript==
// @name Highlight active review
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Bring attention to the user when a post is up for reviewing
// @author Sam Onela
// @match https://codereview.stackexchange.com/review/*
// ==/UserScript==
;(function() {
'use strict';
const INITIAL_CHECK_TIMEOUT = 1500;
const INTERVAL_DELAY = 400;
const RELOAD_DELAY = 6500;
const CLICK_CHECK_DELAY = 6000;
const ticks = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
let timeout = window.setTimeout(check, INITIAL_CHECK_TIMEOUT);
let interval;
function updateTitle(showAsterisk = false) {
var titleMatches = document.title.match(/^([\W]{1})Review/);
if (titleMatches && titleMatches.length > 1) {
const index = ticks.indexOf(titleMatches[1]);
document.title = document.title.replace(titleMatches[1], ticks[(index+1)%ticks.length]);
}
else {
document.title = (showAsterisk?'*': ticks[0]) + document.title;
}
}
function check(clickHandlerAdded = false){
if (timeout) {
window.clearTimeout(timeout);
timeout = 0;
}
if (window.location.pathname.match(/\d+/)) { // drilled in to a review item
updateTitle(true);
if (!clickHandlerAdded) {
document.addEventListener('click', (event) => timeout = window.setTimeout(check, CLICK_CHECK_DELAY, true));
}
}
else { //add spinner animation and then reload
updateTitle();
if (interval === undefined) {
interval = window.setInterval(updateTitle, INTERVAL_DELAY);
}
window.setTimeout(_=> window.location = window.location, RELOAD_DELAY);
}
}
})();
1 Answer 1
How does the es-6 usage look? What would you change and/or code differently?
1. Arrow Functions
I would personally recommend using arrow functions where you have not to stay consistent with the ES6 usage throughout your code.
Example:
;(function() {
... can be changed to:
;(() => {
Additionally, parenthesis are optional when only one parameter is given.
Example:
document.addEventListener('click', (event) => timeout ...
... can be changed to:
document.addEventListener('click', event => timeout ...
2. Constant Arrow Function Expressions
Since it does not appear that you have any intention of overwriting your functions, I would recommend using function expressions defined as constants, rather than function declarations.
Example:
function updateTitle(showAsterisk = false) {
... can be changed to:
const updateTitle = (showAsterisk = false) => {
3. Don't Use var
If you can use let
or const
, use them instead.
Example:
var titleMatches = document.title.match(/^([\W]{1})Review/);
... can be changed to:
const titleMatches = document.title.match(/^([\W]{1})Review/);
4. The window.
Prefix is Unnecessary
You do not need to use the window
prefix on window.setTimeout
, window.clearTimeout
, or window.location
.
Example:
window.clearTimeout(timeout);
... can be changed to:
clearTimeout(timeout);
Final Result
Ultimately, the final result of the changes I would make would look like the following:
// ==UserScript==
// @name Highlight active review
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Bring attention to the user when a post is up for reviewing
// @author Sam Onela
// @match https://codereview.stackexchange.com/review/*
// ==/UserScript==
;(() =>
{
'use strict';
const INITIAL_CHECK_TIMEOUT = 1500;
const INTERVAL_DELAY = 400;
const RELOAD_DELAY = 6500;
const CLICK_CHECK_DELAY = 6000;
const ticks = [
'⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'
];
let timeout = setTimeout(check, INITIAL_CHECK_TIMEOUT);
let interval;
const updateTitle = (showAsterisk = false) =>
{
let titleMatches = document.title.match(/^([\W]{1})Review/);
if (titleMatches && titleMatches.length > 1)
{
const index = ticks.indexOf(titleMatches[1]);
document.title = document.title.replace(titleMatches[1], ticks[( index + 1) % ticks.length]);
}
else
{
document.title = (showAsterisk ? '*' : ticks[0]) + document.title;
}
};
const check = (clickHandlerAdded = false) =>
{
if (timeout)
{
clearTimeout(timeout);
timeout = 0;
}
if (window.location.pathname.match(/\d+/)) // drilled in to a review item
{
updateTitle(true);
if (!clickHandlerAdded)
{
document.addEventListener('click', event => timeout = setTimeout(check, CLICK_CHECK_DELAY, true));
}
}
else //add spinner animation and then reload
{
updateTitle();
if (interval === undefined)
{
interval = setInterval(updateTitle, INTERVAL_DELAY);
}
setTimeout(_ => window.location = window.location, RELOAD_DELAY);
}
};
})();
Hope this helps!
-
1\$\begingroup\$ Good job answering the first question. I honestly originally wrote it not using es-6 features and then right before posting it I decided to switch it so things like
var
and old-school function declarations were left unchanged. \$\endgroup\$2018年04月06日 03:18:59 +00:00Commented Apr 6, 2018 at 3:18
Explore related questions
See similar questions with these tags.