diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..ab1f416 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/LeechBlockNG.iml b/.idea/LeechBlockNG.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/LeechBlockNG.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..a20905f --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..7e16894 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/blocked.html b/blocked.html index b639868..74b0c54 100644 --- a/blocked.html +++ b/blocked.html @@ -33,12 +33,16 @@

The page you're trying to access has been blocked by Block Set)

The page will be unblocked at: the end of time

- - - - diff --git a/blocked.js b/blocked.js index 2787bed..61e51fc 100644 --- a/blocked.js +++ b/blocked.js @@ -5,6 +5,23 @@ var gBlockedURL; var gBlockedSet; var gHashCode; +// Motivational messages +const motivationalMessages = [ + "Stay focused — you’ve got this.", + "Distraction blocked. Productivity active.", + "Use this time intentionally.", + "Focus mode is enabled.", + "Every minute of focus counts.", + "Small progress is still progress." +]; +//Break messages +const breakMessages = [ + "Take a 1–3 minute stretch break.", + "Relax your eyes for 20 seconds.", + "Drink some water.", + "Stand up and move around.", + "Take a deep breath before continuing later." +]; // Create 32-bit integer hash code from string // @@ -21,6 +38,8 @@ function hashCode32(str) { function processBlockInfo(info) { if (!info) return; + console.log("unblockTime raw:", info.unblockTime); + gBlockedURL = info.blockedURL; gBlockedSet = info.blockedSet; gHashCode = info.password ? hashCode32(info.password) : 0; @@ -79,22 +98,130 @@ function processBlockInfo(info) { passwordSubmit.onclick = onSubmitPassword; } - let customMsgDiv = document.getElementById("lbCustomMsgDiv"); - let customMsg = document.getElementById("lbCustomMsg"); - if (customMsgDiv && customMsg) { - if (info.customMsg) { - customMsg.innerText = info.customMsg; - customMsgDiv.style.display = ""; - } else { - customMsgDiv.style.display = "none"; - } - } - let unblockTime = document.getElementById("lbUnblockTime"); if (info.unblockTime && unblockTime) { unblockTime.innerText = info.unblockTime; } + //FEATURE 1: COUNTDOWN + let countdownEl = document.getElementById("lbCountdown"); + let countdownText = document.getElementById("lbCountdownText"); + + // MOTIVATIONAL MESSAGE ROTATION + let motivationEl = document.getElementById("lbMotivation"); + + if (motivationEl) { + + // pick random starting message + let messageIndex = Math.floor(Math.random() * motivationalMessages.length); + + function updateMotivation() { + motivationEl.innerText = motivationalMessages[messageIndex]; + messageIndex = (messageIndex + 1) % motivationalMessages.length; + } + + // show first message immediately + updateMotivation(); + // rotate every 15 seconds + setInterval(updateMotivation, 15000); + } + + // BREAK REMINDER SYSTEM + let breakEl = document.getElementById("lbBreakReminder"); + + if (breakEl) { + const TEN_MIN = 10 * 60 * 1000; + + function showBreakMessage() { + let msg = breakMessages[Math.floor(Math.random() * breakMessages.length)]; + breakEl.innerText = msg; + } + + // show first break message after 5 min + setTimeout(() =>{ + showBreakMessage(); + + // update every 10 min + setInterval(showBreakMessage, TEN_MIN); + }, TEN_MIN/2); + } + + if (info.unblockTime && countdownEl) { + function parseTimeString(timeStr) { + let now = new Date(); + + let parts = timeStr.trim().split(" "); + if (parts.length !== 2) return NaN; + + let [time, modifier] = parts; + let timeParts = time.split(":").map(Number); + + if (timeParts.length < 2) return NaN; + + let hours = timeParts[0]; + let minutes = timeParts[1]; + let seconds = timeParts[2] || 0; + + if (isNaN(hours) || isNaN(minutes)) return NaN; + + if (modifier === "PM" && hours !== 12) hours += 12; + if (modifier === "AM" && hours === 12) hours = 0; + + return new Date( + now.getFullYear(), + now.getMonth(), + now.getDate(), + hours, + minutes, + seconds + ).getTime(); + } + + let endTime = parseTimeString(info.unblockTime); + if (isNaN(endTime)) { + console.error("Bad unblockTime format:", info.unblockTime); + countdownEl.innerText = "Invalid time"; + return; + } + let startTime = Date.now(); + let totalDuration = endTime - startTime; + + function updateCountdown() { + let now = Date.now(); + let diff = endTime - now; + + if (diff <= 0) { + countdownEl.innerText = "Unblocking..."; + clearInterval(timer); + return; + } + + // text + countdownEl.innerText = formatRemaining(diff); + + // progress + let progress = (totalDuration - diff) / totalDuration; + progress = Math.max(0, Math.min(1, progress)); + + let bar = document.getElementById("lbProgressBar"); + let percent = document.getElementById("lbProgressPercent"); + + if (bar) { + bar.style.width = (progress * 100) + "%"; + } + + if (percent) { + percent.innerText = Math.round(progress * 100) + "% completed"; + } + } + + updateCountdown(); + let timer = setInterval(updateCountdown, 1000); + + } else if (countdownText) { + countdownText.style.display = "none"; + } + let delaySecs = document.getElementById("lbDelaySeconds"); if (info.delaySecs && delaySecs) { delaySecs.innerText = info.delaySecs; @@ -179,6 +306,34 @@ function reloadBlockedPage() { document.location.href = gBlockedURL; } } +// Formats timer in hours, minutes and secodns for display +// +function formatRemaining(ms) { + if (ms <= 0) return "0 minutes"; + + let totalSeconds = Math.floor(ms / 1000); + + let hours = Math.floor(totalSeconds / 3600); + let minutes = Math.floor((totalSeconds % 3600) / 60); + let seconds = totalSeconds % 60; + + let parts = []; + + if (hours > 0) { + parts.push(`${hours} hour${hours !== 1 ? "s" : ""}`); + } + + if (minutes > 0) { + parts.push(`${minutes} minute${minutes !== 1 ? "s" : ""}`); + } + + // optional: only show seconds if under 1 minute remaining + if (hours === 0 && minutes < 5) { + parts.push(`${seconds} second${seconds !== 1 ? "s" : ""}`); + } + + return parts.join(" "); +} // Request block info from extension browser.runtime.sendMessage({ type: "blocked" }).then(processBlockInfo); diff --git a/stats.html b/stats.html index 68654b8..36b3699 100644 --- a/stats.html +++ b/stats.html @@ -21,7 +21,28 @@