// ==UserScript==
// @name FinecoBank.com Inbox: Mark all messages as read and Delete all messages
// @name:it FinecoBank.com Inbox: Segna tutti i messaggi come letti e Cancella tutti i messaggi
// @description This script adds two buttons in the page "Inbox" of FinecoBank.com that allow to mark all messages as read and to delete all messages.
// @description:it Questo script aggiunge due bottoni nella pagina "Inbox" di FinecoBank.com che consentono di segnare tutti i messaggi come letti e di cancellare tutti i messaggi.
// @match https://finecobank.com/*
// @grant none
//// @run-at document-start
// @version 1.0.8
// @author Cyrano68
// @license MIT
// @namespace https://greasyfork.org/users/788550
// ==/UserScript==
(function()
{
"use strict";
function getZeroFilledMillisecs(dateNow)
{
const millisecs = dateNow.getMilliseconds();
return ("00" + millisecs).slice(-3);
}
function consoleLog(text, showLog = true)
{
if (showLog)
{
const dateNow = new Date();
//const now = dateNow.toISOString();
const now = dateNow.toLocaleString() + "." + getZeroFilledMillisecs(dateNow);
console.log(`${now} ${text}`);
}
}
function getRandomInteger(min, max)
{
return Math.floor(Math.random() * (max - min) ) + min;
}
function setInterval2(callback, interval_ms, execCallbackNow)
{
// I defined a new "setInterval" function because I want to set the interval for a periodic timer
// and (if required) call immediately the callback function, instead of wait for the first timeout.
//
// Call the "setInterval" for the periodic timer.
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: setInterval2 - STARTING TIMER - interval_ms=${interval_ms}`);
const timerId = setInterval(callback, interval_ms);
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: setInterval2 - TIMER STARTED - timerId=${timerId}`);
if (execCallbackNow)
{
// Call immediately the callback function.
callback(timerId);
}
return timerId;
}
function urlMatchesArray(url, array, index)
{
for (let i = 0; i < array.length; ++i)
{
if (url.startsWith(array[i]))
{
index.value = i;
return true;
}
}
index.value = -1;
return false;
}
const myVersion = GM_info.script.version;
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: HELLO! Loading script (version: ${myVersion})...`);
let currUrl = window.location.href;
const targetUrls = ["https://finecobank.com/pvt/myfineco/mailbox"];
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: currUrl='${currUrl}', targetUrls='${targetUrls}'`);
document.addEventListener("DOMContentLoaded", onDOMContentLoaded);
window.addEventListener("load", onWindowLoaded);
function onDOMContentLoaded()
{
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onDOMContentLoaded - document.readyState=${document.readyState}`);
const myCSS = document.createElement("style");
// SEE: https://getcssscan.com/css-buttons-examples
myCSS.textContent = `
.button-3 {
appearance: none;
background-color: #2ea44f;
border: 1px solid rgba(27, 31, 35, .15);
border-radius: 6px;
box-shadow: rgba(27, 31, 35, .1) 0 1px 0;
box-sizing: border-box;
color: #fff;
cursor: pointer;
display: inline-block;
font-family: -apple-system,system-ui,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";
font-size: 14px;
font-weight: 600;
line-height: 20px;
padding: 6px 16px;
position: relative;
text-align: center;
text-decoration: none;
user-select: none;
-webkit-user-select: none;
touch-action: manipulation;
vertical-align: middle;
white-space: nowrap;
}
.button-3:focus:not(:focus-visible):not(.focus-visible) {
box-shadow: none;
outline: none;
}
.button-3:hover {
background-color: #2c974b;
}
.button-3:focus {
box-shadow: rgba(46, 164, 79, .4) 0 0 0 3px;
outline: none;
}
.button-3:disabled {
background-color: #94d3a2;
border-color: rgba(27, 31, 35, .1);
color: rgba(255, 255, 255, .8);
cursor: default;
}
.button-3:active {
background-color: #298e46;
box-shadow: rgba(20, 70, 32, .2) 0 1px 0 inset;
}
`;
document.body.appendChild(myCSS);
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onDOMContentLoaded - myCSS.outerHTML='${myCSS.outerHTML}'`);
}
function onWindowLoaded()
{
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onWindowLoaded - document.readyState=${document.readyState}`);
let index = {value: -1};
if (urlMatchesArray(currUrl, targetUrls, index))
{
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onWindowLoaded - Function 'urlMatchesArray(currUrl, targetUrls, index)' returned true, index=${index.value}`);
addMyObjects();
}
// Sometimes the javascript is not able to understand when the url changed, expecially in a SPA (single-page-application).
// Therefore I start a timer that periodically will check the current url and, if needed, add/remove the "MyObjects".
// NOTE: The start of the "CheckUrlTimer" is delayed of a random value.
const delay_ms = getRandomInteger(0, 1234);
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onWindowLoaded - delay_ms=${delay_ms}`);
setTimeout(checkUrl, delay_ms);
}
function checkUrl()
{
consoleLog("==> FinecoBank_com_Inbox_DeleteAll: checkUrl");
let timerId = 0;
const interval_ms = 1234; // 1.234s
timerId = setInterval2((inputTimerId) =>
{
// NOTE: The "inputTimerId" will be undefined when this callback is called by the "setInterval" function
// and will have a valid value when this callback is called by the "setInterval2" function.
//
const effectiveTimerId = (inputTimerId === undefined) ? timerId : inputTimerId;
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onCheckUrlTimeout - timerId=${timerId}, inputTimerId=${inputTimerId}, effectiveTimerId=${effectiveTimerId}`);
const prevUrl = currUrl;
currUrl = window.location.href;
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onCheckUrlTimeout - prevUrl='${prevUrl}, currUrl='${currUrl}'`);
if (currUrl !== prevUrl)
{
let index = {value: -1};
if (urlMatchesArray(currUrl, targetUrls, index))
{
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onCheckUrlTimeout - Function 'urlMatchesArray(currUrl, targetUrls, index)' returned true, index=${index.value} - Entered in the target url '${targetUrls[index.value]}'`);
addMyObjects();
}
else if (urlMatchesArray(prevUrl, targetUrls, index))
{
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onCheckUrlTimeout - Function 'urlMatchesArray(prevUrl, targetUrls, index)' returned true, index=${index.value} - Exited from the target url '${targetUrls[index.value]}'`);
removeMyObjects();
}
}
}, interval_ms, false);
}
function addMyObjects()
{
consoleLog("==> FinecoBank_com_Inbox_DeleteAll: addMyObjects");
let timerId = 0;
const interval_ms = 250;
timerId = setInterval2((inputTimerId) =>
{
// NOTE: The "inputTimerId" will be undefined when this callback is called by the "setInterval" function
// and will have a valid value when this callback is called by the "setInterval2" function.
//
const effectiveTimerId = (inputTimerId === undefined) ? timerId : inputTimerId;
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onAddMyObjectsTimeout - timerId=${timerId}, inputTimerId=${inputTimerId}, effectiveTimerId=${effectiveTimerId}`);
const divInbox = document.querySelector("div#inbox-client-app");
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onAddMyObjectsTimeout - divInbox=${divInbox}`);
if (divInbox !== null)
{
consoleLog("==> FinecoBank_com_Inbox_DeleteAll: onAddMyObjectsTimeout - data READY");
clearInterval(effectiveTimerId);
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onAddMyObjectsTimeout - TIMER STOPPED - effectiveTimerId=${effectiveTimerId}`);
// Create a new button that will allow to mark all messages as read.
const myButton1 = Object.assign(document.createElement("button"), {id: "myButton1", textContent: "MARK ALL AS READ", className: "button-3", style: "margin-right: 5px"});
myButton1.addEventListener("click", markAllAsRead);
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onAddMyObjectsTimeout - myButton1.outerHTML='${myButton1.outerHTML}'`);
// The button is placed before the "divInbox".
divInbox.before(myButton1);
// Create a new button that will allow to delete all messages.
const myButton2 = Object.assign(document.createElement("button"), {id: "myButton2", textContent: "DELETE ALL", className: "button-3", style: "margin-left: 5px"});
myButton2.addEventListener("click", deleteAll);
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onAddMyObjectsTimeout - myButton2.outerHTML='${myButton2.outerHTML}'`);
// The button is placed before the "divInbox".
divInbox.before(myButton2);
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onAddMyObjectsTimeout - DONE`);
}
else
{
consoleLog("==> FinecoBank_com_Inbox_DeleteAll: onAddMyObjectsTimeout - data NOT READY... wait");
}
}, interval_ms, true);
}
function removeMyObjects()
{
consoleLog("==> FinecoBank_com_Inbox_DeleteAll: removeMyObjects");
const myButton1 = document.querySelector("button#myButton1");
if ((myButton1 !== undefined) && (myButton1 !== null))
{
myButton1.remove();
}
const myButton2 = document.querySelector("button#myButton2");
if ((myButton2 !== undefined) && (myButton2 !== null))
{
myButton2.remove();
}
}
async function markAllAsRead()
{
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: markAllAsRead`);
let counter = 0;
while (true)
{
const divReadMessages = document.querySelectorAll("div#inbox-client-app div.messageRow.read.row");
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: markAllAsRead - counter=${counter} - divReadMessages.length=${divReadMessages.length}`);
const divUnreadMessages = document.querySelectorAll("div#inbox-client-app div.messageRow.messageunread.row");
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: markAllAsRead - counter=${counter} - divUnreadMessages.length=${divUnreadMessages.length}`);
if (divUnreadMessages.length == 0)
{
break;
}
const divUnreadMessage = divUnreadMessages[0];
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: markAllAsRead - counter=${counter} - divUnreadMessage.outerHTML=${divUnreadMessage.outerHTML}`);
const divButton = divUnreadMessage.querySelector("div[role=\"button\"]");
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: markAllAsRead - counter=${counter} - divButton=${divButton}`);
if (divButton !== null)
{
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: markAllAsRead - counter=${counter} - divButton.outerHTML='${divButton.outerHTML}'`);
await openCloseMessagePage(divButton);
await messageListReady();
}
counter++;
}
}
async function openCloseMessagePage(divButton)
{
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: openCloseMessagePage`);
divButton.click(); // Open the message-page.
const promise = new Promise((resolve, reject) =>
{
let timerId = 0;
const interval_ms = 250;
timerId = setInterval2((inputTimerId) =>
{
// NOTE: The "inputTimerId" will be undefined when this callback is called by the "setInterval" function
// and will have a valid value when this callback is called by the "setInterval2" function.
//
const effectiveTimerId = (inputTimerId === undefined) ? timerId : inputTimerId;
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onOpenCloseMessagePageTimeout - timerId=${timerId}, inputTimerId=${inputTimerId}, effectiveTimerId=${effectiveTimerId}`);
const divMsgNavigator = document.querySelector("div#msg-navigator");
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onOpenCloseMessagePageTimeout - divMsgNavigator=${divMsgNavigator}`);
if (divMsgNavigator !== null)
{
const pathX = divMsgNavigator.querySelector("path[data-name|='Icons / Close / Solid']");
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onOpenCloseMessagePageTimeout - pathX=${pathX}`);
if (pathX !== null)
{
const buttonX = pathX.closest("button.btn.btn-secondary");
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onOpenCloseMessagePageTimeout - buttonX='${buttonX}'`);
if (buttonX !== null)
{
clearInterval(effectiveTimerId);
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onOpenCloseMessagePageTimeout - TIMER STOPPED - effectiveTimerId=${effectiveTimerId}`);
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onOpenCloseMessagePageTimeout - buttonX.outerHTML='${buttonX.outerHTML}'`);
buttonX.click(); // Close the message-page.
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onOpenCloseMessagePageTimeout - RESOLVE`);
resolve();
}
}
}
}, interval_ms, true);
});
return promise;
}
async function messageListReady()
{
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: messageListReady`);
const promise = new Promise((resolve, reject) =>
{
let timerId = 0;
const interval_ms = 250;
timerId = setInterval2((inputTimerId) =>
{
// NOTE: The "inputTimerId" will be undefined when this callback is called by the "setInterval" function
// and will have a valid value when this callback is called by the "setInterval2" function.
//
const effectiveTimerId = (inputTimerId === undefined) ? timerId : inputTimerId;
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onMessageListReadyTimeout - timerId=${timerId}, inputTimerId=${inputTimerId}, effectiveTimerId=${effectiveTimerId}`);
const divReadMessages = document.querySelectorAll("div#inbox-client-app div.messageRow.read.row");
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onMessageListReadyTimeout - divReadMessages.length=${divReadMessages.length}`);
const divUnreadMessages = document.querySelectorAll("div#inbox-client-app div.messageRow.messageunread.row");
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onMessageListReadyTimeout - divUnreadMessages.length=${divUnreadMessages.length}`);
if ((divReadMessages.length + divUnreadMessages.length) > 0)
{
clearInterval(effectiveTimerId);
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onMessageListReadyTimeout - TIMER STOPPED - effectiveTimerId=${effectiveTimerId}`);
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onMessageListReadyTimeout - RESOLVE`);
resolve();
}
}, interval_ms, true);
});
return promise;
}
async function deleteAll()
{
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: deleteAll`);
let counter = 0;
while (true)
{
const divReadMessages = document.querySelectorAll("div#inbox-client-app div.messageRow.read.row");
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: deleteAll - counter=${counter} - divReadMessages.length=${divReadMessages.length}`);
const divUnreadMessages = document.querySelectorAll("div#inbox-client-app div.messageRow.messageunread.row");
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: deleteAll - counter=${counter} - divUnreadMessages.length=${divUnreadMessages.length}`);
if ((divReadMessages.length == 0) && (divUnreadMessages.length == 0))
{
break;
}
if (divReadMessages.length > 0)
{
const divReadMessage = divReadMessages[0];
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: deleteAll - counter=${counter} - divReadMessage.outerHTML=${divReadMessage.outerHTML}`);
const divButton = divReadMessage.querySelector("div[role=\"button\"]");
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: deleteAll - counter=${counter} - divButton=${divButton}`);
if (divButton !== null)
{
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: deleteAll - counter=${counter} - divButton.outerHTML='${divButton.outerHTML}'`);
await openDeleteMessagePage(divButton);
if ((divReadMessages.length + divUnreadMessages.length) > 1)
{
await messageListReady();
}
}
counter++;
}
else if (divUnreadMessages.length > 0)
{
const divUnreadMessage = divUnreadMessages[0];
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: deleteAll - counter=${counter} - divUnreadMessage.outerHTML=${divUnreadMessage.outerHTML}`);
const divButton = divUnreadMessage.querySelector("div[role=\"button\"]");
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: deleteAll - counter=${counter} - divButton=${divButton}`);
if (divButton !== null)
{
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: deleteAll - counter=${counter} - divButton.outerHTML='${divButton.outerHTML}'`);
await openDeleteMessagePage(divButton);
if ((divReadMessages.length + divUnreadMessages.length) > 1)
{
await messageListReady();
}
}
counter++;
}
}
}
async function openDeleteMessagePage(divButton)
{
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: openDeleteMessagePage`);
divButton.click(); // Open the message-page.
const promise = new Promise((resolve, reject) =>
{
let timerId = 0;
const interval_ms = 250;
timerId = setInterval2((inputTimerId) =>
{
// NOTE: The "inputTimerId" will be undefined when this callback is called by the "setInterval" function
// and will have a valid value when this callback is called by the "setInterval2" function.
//
const effectiveTimerId = (inputTimerId === undefined) ? timerId : inputTimerId;
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onOpenDeleteMessagePageTimeout - timerId=${timerId}, inputTimerId=${inputTimerId}, effectiveTimerId=${effectiveTimerId}`);
const divMsgNavigator = document.querySelector("div#msg-navigator");
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onOpenDeleteMessagePageTimeout - divMsgNavigator=${divMsgNavigator}`);
if (divMsgNavigator !== null)
{
const buttonTrash = document.querySelector("button.btn-trash.btn.btn-secondary");
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onOpenDeleteMessagePageTimeout - buttonTrash='${buttonTrash}'`);
if (buttonTrash !== null)
{
clearInterval(effectiveTimerId);
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onOpenDeleteMessagePageTimeout - TIMER STOPPED - effectiveTimerId=${effectiveTimerId}`);
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onOpenDeleteMessagePageTimeout - buttonTrash.outerHTML='${buttonTrash.outerHTML}'`);
buttonTrash.click(); // Delete the message-page.
consoleLog(`==> FinecoBank_com_Inbox_DeleteAll: onOpenDeleteMessagePageTimeout - RESOLVE`);
resolve();
}
}
}, interval_ms, true);
});
return promise;
}
consoleLog("==> FinecoBank_com_Inbox_DeleteAll: Script loaded");
})();