// ==UserScript==
// @name Focus Assistant - Site Blocker
// @namespace https://gf.qytechs.cn/users/1111205-geekfox
// @version 1.2
// @description Blocks distracting websites with a full-screen red overlay to help you stay focused.
// @author GeekFox
// @match *://*/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand
// @run-at document-start
// @license MIT
// ==/UserScript==
(function () {
'use strict';
// 获取存储的设置
const BLOCKED_SITES_KEY = 'blockedSites';
const BLOCK_ENABLED_KEY = 'blockEnabled';
let blockedSites = GM_getValue(BLOCKED_SITES_KEY, []);
let blockEnabled = GM_getValue(BLOCK_ENABLED_KEY, true);
// 注册(不可用)菜单命令
GM_registerMenuCommand('📝 编辑屏蔽网站列表', openSettings);
GM_registerMenuCommand(blockEnabled ? '✅ 屏蔽已启用' : '❌ 屏蔽已禁用', toggleBlocking);
GM_registerMenuCommand('➕ 添加当前网站', addCurrentSite);
GM_registerMenuCommand('⏳ 临时禁用屏蔽(1小时)', disableTemporarily);
// 检查当前网站是否需要屏蔽
function shouldBlockSite() {
if (!blockEnabled) return false;
const hostname = window.location.hostname;
return blockedSites.some(site => {
// 支持通配符匹配
const regex = new RegExp('^' + site.replace(/\*/g, '.*') + '$');
return regex.test(hostname);
});
}
// 创建屏蔽页面
function createBlockPage() {
// 移除页面原有内容
document.documentElement.innerHTML = '';
// 创建全屏覆盖层
const overlay = document.createElement('div');
overlay.style = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg, #ff0000, #b30000);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 999999;
color: white;
font-family: Arial, sans-serif;
text-align: center;
padding: 20px;
box-sizing: border-box;
`;
// 添加标题
const title = document.createElement('h1');
title.textContent = 'BE FOCUSED!';
title.style = `
font-size: 6em;
font-weight: 900;
margin: 0;
text-shadow: 0px 4px 10px rgba(0, 0, 0, 0.5);
letter-spacing: 2px;
`;
// 添加消息
const message = document.createElement('p');
message.textContent = 'This website has been blocked to help you stay focused on your work.';
message.style = `
font-size: 1.8em;
max-width: 800px;
margin: 20px 0;
line-height: 1.5;
`;
// 添加当前网站信息
const siteInfo = document.createElement('p');
siteInfo.textContent = `Blocked site: ${window.location.hostname}`;
siteInfo.style = `
font-size: 1.5em;
margin: 10px 0;
color: rgba(255, 255, 255, 0.8);
`;
// 添加设置链接
const settingsLink = document.createElement('button');
settingsLink.textContent = 'Edit Blocked Sites';
settingsLink.style = `
background: white;
color: #ff0000;
border: none;
padding: 15px 30px;
font-size: 1.3em;
font-weight: bold;
border-radius: 8px;
cursor: pointer;
margin-top: 30px;
box-shadow: 0px 4px 15px rgba(0, 0, 0, 0.2);
transition: transform 0.2s, box-shadow 0.2s;
`;
settingsLink.onmouseover = () => {
settingsLink.style.transform = 'scale(1.05)';
settingsLink.style.boxShadow = '0px 6px 20px rgba(0, 0, 0, 0.3)';
};
settingsLink.onmouseout = () => {
settingsLink.style.transform = 'scale(1)';
settingsLink.style.boxShadow = '0px 4px 15px rgba(0, 0, 0, 0.2)';
};
settingsLink.onclick = openSettings;
// 添加计时器
const timer = document.createElement('div');
timer.id = 'focus-timer';
timer.style = `
margin-top: 30px;
font-size: 1.5em;
background: rgba(0, 0, 0, 0.2);
padding: 10px 20px;
border-radius: 8px;
`;
// 组装页面
overlay.appendChild(title);
overlay.appendChild(message);
overlay.appendChild(siteInfo);
overlay.appendChild(settingsLink);
overlay.appendChild(timer);
document.body.appendChild(overlay);
// 开始倒计时
startTimer(timer);
}
// 专注计时器
function startTimer(element) {
let seconds = 0;
setInterval(() => {
seconds++;
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const secs = seconds % 60;
element.textContent = `You've been focused for: ${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
}, 1000);
}
// 打开设置
function openSettings() {
// 创建设置弹窗
const modal = document.createElement('div');
modal.style = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000000;
`;
// 设置内容
const content = document.createElement('div');
content.style = `
background: white;
border-radius: 12px;
padding: 30px;
width: 80%;
max-width: 600px;
max-height: 80vh;
overflow: auto;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
`;
// 标题
const title = document.createElement('h2');
title.textContent = 'Focus Assistant Settings';
title.style = `
color: #b30000;
margin-top: 0;
text-align: center;
`;
// 说明
const instructions = document.createElement('p');
instructions.innerHTML = 'Enter websites to block (one per line).<br>Use <code>*</code> as wildcard (e.g., <code>*.youtube.com</code>).';
instructions.style = 'margin-bottom: 20px;';
// 网站列表文本框
const textarea = document.createElement('textarea');
textarea.style = `
width: 100%;
height: 200px;
padding: 10px;
box-sizing: border-box;
border: 2px solid #ddd;
border-radius: 8px;
font-family: monospace;
margin-bottom: 20px;
`;
textarea.value = blockedSites.join('\n');
// 按钮容器
const buttonContainer = document.createElement('div');
buttonContainer.style = `
display: flex;
justify-content: space-between;
gap: 10px;
`;
// 保存按钮
const saveButton = document.createElement('button');
saveButton.textContent = 'Save';
saveButton.style = `
flex: 1;
padding: 12px;
background: #28a745;
color: white;
border: none;
border-radius: 8px;
font-size: 1.1em;
cursor: pointer;
`;
saveButton.onclick = () => {
blockedSites = textarea.value.split('\n')
.map(site => site.trim())
.filter(site => site.length > 0);
GM_setValue(BLOCKED_SITES_KEY, blockedSites);
modal.remove();
if (shouldBlockSite()) {
createBlockPage();
}
};
// 取消按钮
const cancelButton = document.createElement('button');
cancelButton.textContent = 'Cancel';
cancelButton.style = `
flex: 1;
padding: 12px;
background: #6c757d;
color: white;
border: none;
border-radius: 8px;
font-size: 1.1em;
cursor: pointer;
`;
cancelButton.onclick = () => modal.remove();
// 添加当前网站按钮
const addCurrentButton = document.createElement('button');
addCurrentButton.textContent = 'Add Current';
addCurrentButton.style = `
flex: 1;
padding: 12px;
background: #007bff;
color: white;
border: none;
border-radius: 8px;
font-size: 1.1em;
cursor: pointer;
`;
addCurrentButton.onclick = () => {
const currentSite = window.location.hostname;
if (!textarea.value.includes(currentSite)) {
textarea.value += (textarea.value ? '\n' : '') + currentSite;
}
};
// 组装元素
buttonContainer.appendChild(saveButton);
buttonContainer.appendChild(cancelButton);
buttonContainer.appendChild(addCurrentButton);
content.appendChild(title);
content.appendChild(instructions);
content.appendChild(textarea);
content.appendChild(buttonContainer);
modal.appendChild(content);
document.body.appendChild(modal);
}
// 添加当前网站
function addCurrentSite() {
const currentSite = window.location.hostname;
if (!blockedSites.includes(currentSite)) {
blockedSites.push(currentSite);
GM_setValue(BLOCKED_SITES_KEY, blockedSites);
if (shouldBlockSite()) {
createBlockPage();
}
}
}
// 切换屏蔽状态
function toggleBlocking() {
blockEnabled = !blockEnabled;
GM_setValue(BLOCK_ENABLED_KEY, blockEnabled);
location.reload(); // 刷新页面应用更改
}
// 临时禁用屏蔽
function disableTemporarily() {
blockEnabled = false;
GM_setValue(BLOCK_ENABLED_KEY, blockEnabled);
// 1小时后自动重新启用
setTimeout(() => {
blockEnabled = true;
GM_setValue(BLOCK_ENABLED_KEY, blockEnabled);
}, 60 * 60 * 1000);
location.reload();
}
// 页面加载时检查是否需要屏蔽
if (shouldBlockSite()) {
// 使用setTimeout确保DOM完全加载
window.addEventListener('DOMContentLoaded', createBlockPage);
}
})();