-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSocial Media Timer.user.js
173 lines (147 loc) · 6.68 KB
/
Social Media Timer.user.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// ==UserScript==
// @name Social Media Timer
// @namespace me.mitchgordon.timer
// @version 0.3.1
// @description Makes sure you don't waste your life on facebook. This app will kick you off Facebook for 30 minutes after you've been browsing for more than 5.
// Place more matches in the line below to track different websites.
// @match https://*.facebook.com/*
// @copyright 2012+, You
// ==/UserScript==
// Tampermonkey has this annoying habit of starting multiple scripts for one page with iframes
if (window.top != window.self)
return;
// The time the site will not be blocked in seconds
var onTime = 5 * 60;
// The time the site will be blocked in seconds
var offTime = 30 * 60;
// Is logging enabled?
var logging = false;
function log(val) {
if (logging)
console.log(val);
}
// The tag used to store data in local storage
var stateId = "SocialMediaTimer";
// Is this the main thread that's decrementing the timer?
var mainThread = false;
// Have we written a message to the page yet?
var written = false;
// The id of the timing event we're going to schedule.
var intervalId;
// This stuff handles when the main thread quits without cleaning up after itself
// How many times have we gotten the counter and seen the same number as before?
var sameSecondsCount = 0;
// What was the last value we saw?
var lastSeconds = 0;
// And just in case, we'll put everything in an event so it only gets called once per window load.
window.addEventListener("load", function() {
var currentState;
//Check if we've ever run
//If we haven't, set the default options
var stateString = localStorage.getItem(stateId);
if (stateString === null) {
currentState = {timing: false, allowed: true, secondsLeft: onTime};
localStorage.setItem(stateId, JSON.stringify(currentState));
}
// Then decrement and check the timer every second
intervalId = setInterval( everySecond, 1000);
});
window.addEventListener("beforeunload", function(evt) {
// If we're the main thread, we need to let other threads know we're not decrementing
// the counter any more.
if (mainThread) {
var stateString = localStorage.getItem(stateId);
if (stateString !== null) {
var currentState = JSON.parse(stateString);
currentState.timing = false;
localStorage.setItem(stateId, JSON.stringify(currentState));
}
}
});
function onTimeHandler(currentState) {
// If the time left is less than zero, then browsing time is over.
if (currentState.secondsLeft <= 0) {
// Turn off the site and set a date for the site to come back on.
currentState.allowed = false;
currentState.timing = false;
mainThread = false;
var returnTime = new Date();
returnTime.setSeconds(returnTime.getSeconds() + offTime);
currentState.returnTime = returnTime;
log("Time's up. Setting return time to " + currentState.returnTime);
}
// Otherwise, just decrement the time left
else {
currentState.secondsLeft = currentState.secondsLeft - 1;
log("Decrementing time to " + currentState.secondsLeft);
}
}
function offTimeHandler(currentState) {
// If timer expired, then off time is over.
currentState.returnTime = new Date(currentState.returnTime);
log("Time till back on: " + (currentState.returnTime - new Date()) );
if ( new Date() > currentState.returnTime ) {
// Reset the timer for on time.
currentState.timing = false;
currentState.allowed = true;
currentState.secondsLeft = onTime;
}
// Otherwise, overwrite the page and tell the user when facebook will come back on.
else if (!written) {
// This has to be one line for some reason. If you call document.write() twice back to back like we did before, you get an infinite recursion/stack overflow.
document.write("<div>Time's up. This site will be off until " + currentState.returnTime.toTimeString() + ". Go be productive.</div><button id='social_media_timer_reset'>This is wrong! Give me more time!</button>");
document.getElementById('social_media_timer_reset').addEventListener('click', function () {
localStorage.setItem(stateId, JSON.stringify({allowed:true, timing: false, secondsLeft: onTime}));
location.reload();
});
written = true;
}
}
// Decrements the timer and checks if it's time to switch modes.
function everySecond() {
// Grab the current state
var stateString = localStorage.getItem(stateId);
if (stateString !== null) {
var currentState = JSON.parse(stateString);
// If the website is currently allowed to be browsed,
// and we haven't already over-written the page, (don't count down if the user hasn't reloaded yet)
// and we're the main thread or there is no other main thread
log("Written: " + written);
log("MainThread: " + mainThread);
if (currentState.allowed && !written && (mainThread || currentState.timing === false)) {
// Then this thread will become the main thread that decrements the timer
mainThread = true;
currentState.timing = true;
onTimeHandler(currentState);
// Save the state object
localStorage.setItem(stateId, JSON.stringify(currentState));
}
else if (currentState.allowed && written) {
// If we've already written over the page so that browsing is impossible, but the page is on
// Tell them to refresh the page
var status = "This page is now back on. Please refresh to browse.";
document.getElementById("status").innerHTML = status;
alert(status);
clearInterval(intervalId);
}
else if (!currentState.allowed) {
// Or if the site is not allowed to be browsed
offTimeHandler(currentState);
// Save the state object
localStorage.setItem(stateId, JSON.stringify(currentState));
}
else if (currentState.allowed) {
// Do the check to see if the main thread bailed without cleaning up
sameSecondsCount = (currentState.secondsLeft == lastSeconds) ? sameSecondsCount + 1 : 0;
lastSeconds = currentState.secondsLeft;
// If the timer hasn't changed in 5 seconds, take over as main thread
if (sameSecondsCount > 5) {
mainThread = true;
currentState.timing = true;
// Save the state object
localStorage.setItem(stateId, JSON.stringify(currentState));
}
}
log("Current state: " + JSON.stringify(currentState));
}
}