NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name Feedly Switch Theme
// @namespace https://openuserjs.org/users/burn
// @version 0.2.7
// @description Changes the theme based on times you set
// @author Burn
// @copyright 2021, burn (https://openuserjs.org/users/burn)
// @license LGPL-3.0-or-later
// @updateURL https://openuserjs.org/meta/burn/Feedly_Switch_Theme.meta.js
// @downloadURL https://openuserjs.org/install/burn/Feedly_Switch_Theme.user.js
// @match https://feedly.com/*
// @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_deleteValue
// @grant GM.getValue
// @grant GM.setValue
// @grant GM.deleteValue
// ==/UserScript==
/*jshint esversion: 8 */
(async function() {
'use strict';
let DBG = false,
timeNow = new Date(),
storeName = "FeedlySwitchTheme",
lightTheme = {
timeStart : new Date(timeNow.getFullYear(), timeNow.getMonth(), timeNow.getDate(),
8, // hours
0, // minutes
0), //seconds
timeEnd : new Date(timeNow.getFullYear(), timeNow.getMonth(), timeNow.getDate(),
18,
0,
0),
cssClass: 'theme--light'
},
darkTheme = {
timeStart : new Date(timeNow.getFullYear(), timeNow.getMonth(), timeNow.getDate(),
18,
0,
0),
timeEnd : new Date(timeNow.getFullYear(), timeNow.getMonth(), timeNow.getDate() + 1,
8,
0,
0),
cssClass: 'theme--dark'
},
buttonSwitch = '[aria-label="Switch Between Themes"]',
observerConfig = {
attributes: false,
childList: true,
subtree: true
},
spy = 0;
// helpers functions
let log = s => {
return (DBG && console.log('|burn| ' + s));
},
qSel = (q, c) => {
let d = (typeof c === 'object') ? c : document;
return d.querySelector(q) || false;
},
qSelAll = (q, c) => {
let d = (typeof c === 'object') ? c : document;
return d.querySelectorAll(q) || false;
},
serialize = (name, val) => {
GM.setValue(name, JSON.stringify(val));
},
deserialize = async (name, def) => {
log('in serialize');
def = def || '{}';
let tmpOut = await GM.getValue(name, def);
log("deserialize: " + tmpOut);
return JSON.parse(tmpOut);
},
delayClick = (targetEl) => {
setTimeout(() => {
log('in delayClick');
targetEl.click();
}, 500);
};
function callback(mutationsList, observer) {
mutationsList.forEach(mutation => {
let entry = {
mutation: mutation,
el: mutation.target,
value: mutation.target.textContent,
oldValue: mutation.oldValue
};
//log(entry.el);
if (false !== qSel(buttonSwitch, entry.el) && spy === 0) {
log('found button element');
if (timeNow >= lightTheme.timeStart && timeNow < lightTheme.timeEnd) {
log('times OK, checking current theme');
if (document.body.classList.contains(darkTheme.cssClass)) {
log('setting light theme');
spy = 1;
delayClick(qSel(buttonSwitch, entry.el));
observer.disconnect();
}
} else {
if (document.body.classList.contains(lightTheme.cssClass)) {
log('setting dark theme');
spy = 1;
delayClick(qSel(buttonSwitch, entry.el));
observer.disconnect();
} else {
log('dark theme found, exiting');
}
}
}
}); // end foreach
} // end callback
let observer = new MutationObserver(callback);
observer.observe(document.body, observerConfig);
})();