- // ==UserScript==
- // @name Medium Member Bypass
- // @author UniverseDev
- // @license GPL-3.0-or-later
- // @namespace http://tampermonkey.net/
- // @version 12.9
- // @description Modern Medium GUI with multiple bypass services.
- // @match *://*.medium.com/*
- // @match https://freedium.cfd/*
- // @match https://readmedium.com/*
- // @match https://md.vern.cc/*
- // @grant GM_registerMenuCommand
- // @grant GM_setValue
- // @grant GM_getValue
- // ==/UserScript==
-
- (() => {
- 'use strict';
-
- const config = {
- bypassUrls: {
- freedium: 'https://freedium.cfd',
- readmedium: 'https://readmedium.com',
- libmedium: 'https://md.vern.cc/',
- },
- currentBypass: GM_getValue('currentBypass', 'freedium'),
- memberOnlyDivSelector: 'p.bf.b.bg.z.bk',
- autoRedirectDelay: GM_getValue('redirectDelay', 5000),
- autoRedirectEnabled: GM_getValue('autoRedirect', true),
- darkModeEnabled: GM_getValue('darkModeEnabled', false),
- isBypassSession: GM_getValue('isBypassSession', false),
- };
-
- const injectStyles = () => {
- const style = document.createElement('style');
- style.textContent = `
- .medium-settings {
- position: fixed;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- width: 360px;
- background-color: var(--background-color, white);
- box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
- border-radius: 16px;
- font-family: 'Arial', sans-serif;
- z-index: 10000;
- padding: 20px;
- display: none;
- color: var(--text-color, #333);
- cursor: grab;
- }
- .medium-settings.dark {
- --background-color: #333;
- --text-color: white;
- }
- .medium-settings-header {
- font-size: 22px;
- font-weight: bold;
- margin-bottom: 20px;
- text-align: center;
- }
- .medium-settings-toggle {
- margin: 15px 0;
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
- .medium-settings-input {
- margin-left: 10px;
- width: 70px;
- padding: 6px;
- text-align: center;
- border: 1px solid #ccc;
- border-radius: 4px;
- }
- .medium-settings-button {
- background-color: var(--button-bg-color, #1a8917);
- color: var(--button-text-color, white);
- border: none;
- padding: 8px 14px;
- border-radius: 20px;
- cursor: pointer;
- font-weight: bold;
- transition: background-color 0.3s;
- }
- .medium-settings-button:hover {
- background-color: #155c11;
- }
- .medium-notification {
- position: fixed;
- bottom: 20px;
- right: 20px;
- background-color: #1a8917;
- color: white;
- padding: 15px;
- border-radius: 20px;
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
- font-family: 'Arial', sans-serif;
- z-index: 10000;
- opacity: 0;
- transform: translateY(20px);
- transition: all 0.3s ease;
- }
- .medium-notification.show {
- opacity: 1;
- transform: translateY(0);
- }
- `;
- document.head.appendChild(style);
- };
-
- const stealthNotification = (message) => {
- const notification = document.createElement('div');
- notification.className = 'medium-notification';
- notification.textContent = message;
- document.body.appendChild(notification);
-
- setTimeout(() => notification.classList.add('show'), 50);
- setTimeout(() => {
- notification.classList.remove('show');
- setTimeout(() => notification.remove(), 300);
- }, 3000);
- };
-
- const showMediumSettings = () => {
- let existingPanel = document.querySelector('.medium-settings');
- if (existingPanel) {
- existingPanel.style.display = 'block';
- return;
- }
-
- const settingsContainer = document.createElement('div');
- settingsContainer.className = `medium-settings ${config.darkModeEnabled ? 'dark' : ''}`;
-
- settingsContainer.innerHTML = `
- <div class="medium-settings-header">Medium Settings</div>
- <div class="medium-settings-toggle">
- <span>Auto-Redirect</span>
- <button class="medium-settings-button" id="toggleRedirect">${config.autoRedirectEnabled ? 'ON' : 'OFF'}</button>
- </div>
- <div class="medium-settings-toggle">
- <span>Redirect Delay (ms)</span>
- <input type="number" class="medium-settings-input" id="redirectDelay" value="${config.autoRedirectDelay}" />
- </div>
- <div class="medium-settings-toggle">
- <span>Dark Mode</span>
- <button class="medium-settings-button" id="toggleDarkMode">${config.darkModeEnabled ? 'ON' : 'OFF'}</button>
- </div>
- <div class="medium-settings-toggle">
- <span>Bypass Service</span>
- <select id="bypassSelector" class="medium-settings-input">
- ${Object.keys(config.bypassUrls).map((key) => `
- <option value="${key}" ${config.currentBypass === key ? 'selected' : ''}>${key}</option>
- `).join('')}
- </select>
- </div>
- <div class="medium-settings-toggle">
- <button class="medium-settings-button" id="bypassNow">Bypass Now</button>
- </div>
- <div class="medium-settings-toggle">
- <button class="medium-settings-button" id="resetDefaults">Reset to Default</button>
- </div>
- <div class="medium-settings-toggle">
- <button class="medium-settings-button" id="saveSettings">Save</button>
- <button class="medium-settings-button" id="closeSettings">Close</button>
- </div>
- `;
-
- document.body.appendChild(settingsContainer);
-
- let isDragging = false;
- let startX, startY;
-
- settingsContainer.addEventListener('mousedown', (e) => {
- isDragging = true;
- startX = e.clientX - settingsContainer.offsetLeft;
- startY = e.clientY - settingsContainer.offsetTop;
- settingsContainer.style.cursor = 'grabbing';
- });
-
- document.addEventListener('mousemove', (e) => {
- if (!isDragging) return;
- settingsContainer.style.left = `${e.clientX - startX}px`;
- settingsContainer.style.top = `${e.clientY - startY}px`;
- });
-
- document.addEventListener('mouseup', () => {
- isDragging = false;
- settingsContainer.style.cursor = 'grab';
- });
-
- settingsContainer.querySelector('#toggleRedirect').addEventListener('click', () => {
- config.autoRedirectEnabled = !config.autoRedirectEnabled;
- GM_setValue('autoRedirect', config.autoRedirectEnabled);
- settingsContainer.querySelector('#toggleRedirect').textContent = config.autoRedirectEnabled ? 'ON' : 'OFF';
- stealthNotification('Auto-Redirect toggled');
- });
-
- settingsContainer.querySelector('#toggleDarkMode').addEventListener('click', () => {
- config.darkModeEnabled = !config.darkModeEnabled;
- GM_setValue('darkModeEnabled', config.darkModeEnabled);
- settingsContainer.classList.toggle('dark', config.darkModeEnabled);
- settingsContainer.querySelector('#toggleDarkMode').textContent = config.darkModeEnabled ? 'ON' : 'OFF';
- stealthNotification('Dark Mode toggled');
- });
-
- settingsContainer.querySelector('#bypassSelector').addEventListener('change', (e) => {
- config.currentBypass = e.target.value;
- GM_setValue('currentBypass', config.currentBypass);
- stealthNotification(`Bypass service set to ${config.currentBypass}`);
- });
-
- settingsContainer.querySelector('#bypassNow').addEventListener('click', () => {
- window.location.href = config.bypassUrls[config.currentBypass] + window.location.pathname;
- });
-
- settingsContainer.querySelector('#resetDefaults').addEventListener('click', () => {
- config.autoRedirectDelay = 5000;
- config.autoRedirectEnabled = true;
- config.darkModeEnabled = false;
- config.currentBypass = 'freedium';
-
- GM_setValue('redirectDelay', config.autoRedirectDelay);
- GM_setValue('autoRedirect', config.autoRedirectEnabled);
- GM_setValue('darkModeEnabled', config.darkModeEnabled);
- GM_setValue('currentBypass', config.currentBypass);
-
- settingsContainer.querySelector('#redirectDelay').value = config.autoRedirectDelay;
- settingsContainer.querySelector('#toggleRedirect').textContent = 'ON';
- settingsContainer.querySelector('#toggleDarkMode').textContent = 'OFF';
- settingsContainer.querySelector('#bypassSelector').value = 'freedium';
- settingsContainer.classList.remove('dark');
- stealthNotification('Settings reset to defaults');
- });
-
- settingsContainer.querySelector('#saveSettings').addEventListener('click', () => {
- const newDelay = parseInt(settingsContainer.querySelector('#redirectDelay').value, 10);
- if (!isNaN(newDelay) && newDelay >= 0) {
- config.autoRedirectDelay = newDelay;
- GM_setValue('redirectDelay', newDelay);
- stealthNotification('Settings saved');
- }
- });
-
- settingsContainer.querySelector('#closeSettings').addEventListener('click', () => {
- settingsContainer.style.display = 'none';
- });
-
- settingsContainer.style.display = 'block';
- };
-
- const performAutoRedirect = () => {
- // Prevent redirection loop
- if (config.isBypassSession) {
- GM_setValue('isBypassSession', false);
- return;
- }
-
- // Redirect logic
- if (config.autoRedirectEnabled && document.querySelector(config.memberOnlyDivSelector)) {
- setTimeout(() => {
- window.location.href = config.bypassUrls[config.currentBypass] + window.location.pathname;
- }, config.autoRedirectDelay);
- stealthNotification('Redirecting to bypass service...');
- }
- };
-
- const initializeScript = () => {
- injectStyles();
-
- const isBypassPage = Object.values(config.bypassUrls).some((url) => window.location.href.startsWith(url));
-
- if (isBypassPage) {
- GM_setValue('isBypassSession', true);
- } else if (window.location.href.startsWith('https://medium.com/')) {
- GM_registerMenuCommand('Open Medium Settings', showMediumSettings);
- performAutoRedirect();
- }
- };
-
- initializeScript();
- })();