您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
Hide or show the Messenger chat list based on user interaction. Includes features for resizing and locking Chat list visibility.
当前为
// ==UserScript== // @name Messenger Hide Chat List // @namespace imxitiz's-Script // @version 2.1 // @grant none // @license GNU GPLv3 // @author imxitiz // @match https://www.messenger.com/* // @description Hide or show the Messenger chat list based on user interaction. Includes features for resizing and locking Chat list visibility. // ==/UserScript== (function () { "use strict"; let hasInitialized = false; const hideThreshold = 20; // Threshold in pixels to determine if sidebar should be hidden let eventParent; let isResizing = false; let userDefinedFlexBasis = parseFloat(getLocalStorageItem("userDefinedFlexBasis")) || 30; let userResizedOnce = getSessionStorageItem("userResizedOnce") === "true" || false; let active = parseInt(getSessionStorageItem("active")) || 0; // active states: // 0 - Normal behavior: sidebar hidden on hover // 1 - Always visible // 2 - Always hidden(lock) // 3 - Always hidden(hiddent but not locked) let lockPosition = JSON.parse(getSessionStorageItem("lockPosition")) || { x: 0, y: 0, }; const clickThreshold = 80; // Threshold in pixels for precise unlocking let wrongLockedPlaceAttempt = 0; // Helper functions for storage function setSessionStorageItem(key, value) { sessionStorage.setItem(key, value); } function getSessionStorageItem(key) { return sessionStorage.getItem(key); } function setLocalStorageItem(key, value) { localStorage.setItem(key, value); } function getLocalStorageItem(key) { return localStorage.getItem(key); } // Create and append the resize handle to the sidebar function createResizeHandle() { try { const sidebar = document.querySelector( 'div[aria-label="Thread list"]' ); if (!sidebar) { throw new Error("Sidebar element not found"); } // Create resize handle only if it doesn't already exist if (!document.getElementById("resize-handle")) { const resizeHandle = document.createElement("div"); resizeHandle.id = "resize-handle"; resizeHandle.style.width = "10px"; resizeHandle.style.height = "100%"; resizeHandle.style.position = "absolute"; resizeHandle.style.top = "0"; resizeHandle.style.right = "0"; resizeHandle.style.cursor = "ew-resize"; resizeHandle.style.backgroundColor = userResizedOnce ? "transparent" : "red"; resizeHandle.style.zIndex = "1000"; sidebar.appendChild(resizeHandle); // Add event listeners for resizing resizeHandle.addEventListener("mousedown", function () { isResizing = true; document.addEventListener("mousemove", resizeChatList); document.addEventListener("mouseup", stopResize); }); } } catch (error) { console.error("Error creating resize handle: ", error); setTimeout(createResizeHandle, 1000); // Retry after 1 second if there's an error } } // Update sidebar visibility based on user interactions and settings function updateSidebarVisibility() { const sidebar = document.querySelector('div[aria-label="Thread list"]'); const inboxSwitcher = document.querySelector( 'div[aria-label="Inbox switcher"]' ); if (sidebar && inboxSwitcher) { if (!hasInitialized) { sidebar.style.maxWidth = "0"; // Initial max-width sidebar.style.minWidth = "0"; // Ensure consistent width sidebar.style.margin = "0"; hasInitialized = true; createResizeHandle(); // Create resize handle on initial setup } const isMouseOverSidebar = isMouseOver(sidebar) || isMouseOver(inboxSwitcher); if (active === 1) { // Always show the sidebar sidebar.style.maxWidth = `${userDefinedFlexBasis}%`; sidebar.style.minWidth = `${userDefinedFlexBasis}%`; sidebar.style.margin = "0"; } else if (active === 2 || active === 3) { // Always hide the sidebar sidebar.style.maxWidth = "0"; sidebar.style.minWidth = "0"; } else { // Normal behavior if ( isMouseOverSidebar || eventParent.clientX <= hideThreshold || isResizing ) { // Show sidebar sidebar.style.maxWidth = `${userDefinedFlexBasis}%`; sidebar.style.minWidth = `${userDefinedFlexBasis}%`; sidebar.style.margin = "0"; } else { // Hide sidebar sidebar.style.maxWidth = "0"; sidebar.style.minWidth = "0"; } } } } // Resize the chat list while the mouse is moving function resizeChatList(e) { if (isResizing) { const sidebar = document.querySelector( 'div[aria-label="Thread list"]' ); const containerWidth = sidebar.parentElement.clientWidth; let newFlexBasis = ((e.clientX - sidebar.getBoundingClientRect().left) / containerWidth) * 100; if (newFlexBasis >= 10 && newFlexBasis <= 100) { userDefinedFlexBasis = newFlexBasis; sidebar.style.maxWidth = `${userDefinedFlexBasis}%`; sidebar.style.minWidth = `${userDefinedFlexBasis}%`; } if (!userResizedOnce) { userResizedOnce = true; setSessionStorageItem("userResizedOnce", "true"); let resizeHandle = document.getElementById("resize-handle"); resizeHandle.style.backgroundColor = "transparent"; } setLocalStorageItem("userDefinedFlexBasis", userDefinedFlexBasis); } } // Stop resizing when the mouse button is released function stopResize() { isResizing = false; document.removeEventListener("mousemove", resizeChatList); document.removeEventListener("mouseup", stopResize); } // Check if mouse is over the element or its children function isMouseOver(element) { return element.contains(eventParent.target); } // Calculate distance between two points function calculateDistance(pos1, pos2) { return Math.sqrt( Math.pow(pos1.x - pos2.x, 2) + Math.pow(pos1.y - pos2.y, 2) ); } // Check if mouse is near the locked position function isNearLockPosition(x, y, lockPosition) { const distance = calculateDistance(lockPosition, { x, y }); return distance <= clickThreshold; } // Helper function to show notifications function showNotification(message, time = 5000) { // if previous notification found, remove it const previousNotification = document.querySelector("div[role='alert']"); if (previousNotification) { document.body.removeChild(previousNotification); } const notification = document.createElement("div"); notification.setAttribute("role", "alert"); notification.textContent = message; notification.style.position = "fixed"; notification.style.top = "50%"; notification.style.left = "50%"; notification.style.transform = "translate(-50%, -50%)"; notification.style.padding = "10px"; notification.style.backgroundColor = "#333"; notification.style.color = "#fff"; notification.style.fontFamily = "Arial, sans-serif"; notification.style.fontSize = "20px"; notification.style.borderRadius = "5px"; notification.style.zIndex = "100000"; notification.style.opacity = "0"; notification.style.transition = "opacity 0.5s"; document.body.appendChild(notification); // Fade in the notification setTimeout(() => { notification.style.opacity = "1"; }, 100); // Fade out and remove the notification after 3 seconds setTimeout(() => { notification.style.opacity = "0"; setTimeout(() => { if (document.body.contains(notification)) document.body.removeChild(notification); }, 500); }, time); } // Triple click event listener function handleClick(event, clickcount = 0) { if (event.detail === 3 || clickcount === 3) { const inboxSwitcher = document.querySelector( 'div[aria-label="Inbox switcher"]' ); if (active === 0) { if (isMouseOver(inboxSwitcher)) { active = 1; showNotification("Now chat list is always visible.", 3000); } else { // if triple right click then lock hidden if (event.button === 2) { active = 2; lockPosition = { x: event.clientX, y: event.clientY }; setSessionStorageItem( "lockPosition", JSON.stringify(lockPosition) ); showNotification( "You have to triple click exactly here to unlock the chat list." ); } else { // else or if triple left click then unlocked hidden active = 3; showNotification( "Now chat list is always hidden, but not locked." ); } } } else if (active === 1) { if (isMouseOver(inboxSwitcher)) { active = 0; showNotification("Now chat list is shown on hover.", 3000); } else { if (event.button === 2) { active = 2; lockPosition = { x: event.clientX, y: event.clientY }; setSessionStorageItem( "lockPosition", JSON.stringify(lockPosition) ); showNotification( "You have to triple click exactly here to unlock the chat list." ); } else { active = 3; showNotification( "Now chat list is always hidden, but not locked." ); } } } else if (active === 2) { if ( isNearLockPosition( event.clientX, event.clientY, lockPosition ) ) { active = 0; wrongLockedPlaceAttempt = 0; showNotification("Chat list unlocked successfully."); } else { wrongLockedPlaceAttempt++; if (wrongLockedPlaceAttempt >= 10) { showNotification( "You can always logout and login again to reset the lock position." ); } else { if (wrongLockedPlaceAttempt >= 5) { showNotification( "Please logout and login again to reset the lock position." ); } } const clickPosition = { x: event.clientX, y: event.clientY, }; const distance = calculateDistance( lockPosition, clickPosition ); if (distance <= clickThreshold * 1.2) { showNotification( "You are near the locked position, try again!!!" ); } } } else { if (isMouseOver(inboxSwitcher)) { active = 1; showNotification("Now chat list is always visible.", 3000); } else { if (event.button === 2) { active = 2; lockPosition = { x: event.clientX, y: event.clientY }; setSessionStorageItem( "lockPosition", JSON.stringify(lockPosition) ); showNotification( "You have to triple click exactly here to unlock the chat list." ); } else { active = 0; showNotification( "Now chat list is shown on hover.", 3000 ); } } } setSessionStorageItem("active", active); } } // Initialize the script function init() { document.addEventListener("mousemove", function (event) { eventParent = event; updateSidebarVisibility(); }); document.addEventListener("click", handleClick); let lastRightClickTime = 0; let rightClickCount = 0; document.addEventListener("contextmenu", function (event) { const avoidElements = [ "IMG", "VIDEO", "AUDIO", "SOURCE", "A", "BUTTON", "INPUT", "SELECT", "TEXTAREA", "IFRAME", "EMBED", "OBJECT", "CANVAS", "SVG", ]; if ( avoidElements.includes(event.target.tagName) || event.target.isContentEditable ) { return; } event.preventDefault(); const currentTime = new Date().getTime(); if (currentTime - lastRightClickTime < 500) { rightClickCount++; } else { rightClickCount = 1; } lastRightClickTime = currentTime; handleClick(event, rightClickCount); }); } init(); })();