🏠 Home 

Greasy Fork is available in English.

Focus Mode for Social Media

block time-wasting social media & other


安装此脚本?
// ==UserScript==
// @name        Focus Mode for Social Media
// @namespace   Violentmonkey Scripts
// @include     https://twitter.com/home
// @include     https://www.youtube.com*
// @include     https://www.instagram.com/
// @include     https://github.com/
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_deleteValue
// @grant       GM_registerMenuCommand
// @grant       GM_unregisterMenuCommand
// @grant       GM_addStyle
// @grant       GM_xmlhttpRequest
// @version     2.1
// @license     MIT
// @author      KraXen72
// @description block time-wasting social media & other
// ==/UserScript==
const getStylesheetUrl = (hostname) => `https://kraxen72.github.io/focus-stylesheets/${hostname}.css`
const site = window.location.hostname
let styleSheetCSS = "";
// const resetSeconds = 30*60
const resetSeconds = 30*10
class Toggle {
constructor(css, uuid, initialValue = true) {
if (!css) throw new Error("Please provide CSS to inject!");
this.css = css
this.state = GM_getValue(`${site}_state`, initialValue)
this.disabledTimestamp = GM_getValue(`${site}_disabled_timestamp`, -1)
this.styleTag = null
this.menuCommand = false;
this.menuCommandId = uuid
this.attemptReenable()
this.sync()
}
enable() {
this.state = true
this.disabledTimestamp = -1
this.sync()
}
disable() {
this.state = false
this.disabledTimestamp = new Date().getTime()
this.sync()
}
toggle() {
if (this.state) {
this.disable()
} else {
this.enable()
}
}
attemptReenable() {
if (this.state) return;
// if disabled but timestamp is -1, enable it to fix the edge-case.
if ((new Date().getTime() - this.disabledTimestamp) <= resetSeconds*1000 && this.disabledTimestamp !== -1) {
console.log("focusMode: resetSeconds has not elapsed yet")
return;
}
console.log("focusMode: resetSeconds has elapsed, enabling.")
this.state = true;
this.disabledTimestamp = -1
this.sync()
}
updateCSS() {
if (this.state) {
if (!this.styleTag) this.styleTag = GM_addStyle(this.css)
} else {
if (this.styleTag) this.styleTag.remove();
this.styleTag = null
}
}
saveData() {
GM_setValue(`${site}_state`, this.state)
if (this.disabledTimestamp === -1) {
GM_deleteValue(`${site}_disabled_timestamp`)
} else {
GM_setValue(`${site}_disabled_timestamp`, this.disabledTimestamp)
}
}
updateMenuCommand() {
const caption = `focusMode: ${site}: ${this.state ? '✅' : '❌'}`
if (this.menuCommand) {
GM_unregisterMenuCommand(this.menuCommandId)
}
GM_registerMenuCommand(caption, () => this.toggle.apply(this), { id: this.menuCommandId })
this.menuCommand = true;
}
sync() {
this.saveData()
this.updateCSS()
this.updateMenuCommand()
}
}
function sameDay(date1, date2) {
return date1.getFullYear() === date2.getFullYear()
&& date1.getMonth() === date2.getMonth()
&& date1.getDate() === date2.getDate();
}
function zeropad(number, finalWidth, customCharacter) {
customCharacter = customCharacter || '0';
number = number + '';
return number.length >= finalWidth ? number : new Array(finalWidth - number.length + 1).join(customCharacter) + number;
}
let togggleInstance;
function init() {
new Promise(async (res, rej) => {
const lastFetchDate = new Date(GM_getValue("lastFetchDate", null))
const currDate = new Date()
const fetchedToday = sameDay(lastFetchDate, currDate)
const storedCSS = GM_getValue("css_"+site, null)
console.log(lastFetchDate, currDate)
if (fetchedToday && storedCSS) {
console.log("focusMode: already fetched today and found stored css. not fetching.")
res(storedCSS)
} else {
const data = await new Promise((resolve, reject) => GM_xmlhttpRequest({
url: getStylesheetUrl(site),
method: 'GET',
onabort: () => resolve(GM_getValue("css_"+site, "")),
onerror: () => resolve(GM_getValue("css_"+site, "")),
onload: (response) => resolve(response.responseText)
}))
console.log(`focusMode: fetched updated css for ${site}`)
GM_setValue("lastFetchDate", new Date().toDateString())
GM_setValue("css_"+site, resText)
res(data)
}
}).then(data => {
let currDate = new Date()
if (site === "www.youtube.com") {
console.log("focusMode: yt override kicking in...")
data = data.replaceAll("%focus%", (currDate.getHours() <= 6) ? `bro go to sleep please it's ${zeropad(currDate.getHours(), 2)}:${zeropad(currDate.getMinutes(), 2)}am` : "focus")
}
if (typeof toggleInstance === "undefined") {
toggleInstance = new Toggle(data, btoa(Math.round(Math.random()*100)));
}
toggleInstance.attemptReenable();
console.log("focusMode: initialized", toggleInstance, data)
})
}
let lastUrl = window.location.href;
new MutationObserver(() => {
const currentUrl = window.location.href;
if (currentUrl !== lastUrl) {
lastUrl = currentUrl;
init();
setTimeout(() => { if (typeof toggleInstance !== "undefined") toggleInstance.sync(); }, 0);
}
}).observe(document, { childList: true, subtree: true });
init();