Greasy Fork is available in English.
Fullscreen toggle with drag & long press (PC + Mobile)
// ==UserScript==
// @name Mini Fullscreen Toggle Button (Majsoul)
// @namespace https://greasyfork.org/en/users/1572947-yakumanchiban
// @icon https://i.imgur.com/k4arlC3.jpeg
// @version 1.6-universal
// @description Fullscreen toggle with drag & long press (PC + Mobile)
// @author Yakumanchiban
// @match https://mahjongsoul.game.yo-star.com/*
// @match https://majsoul.com/*
// @match https://game.maj-soul.com/*
// @match https://majsoul.union-game.com/*
// @match https://game.mahjongsoul.com/*
// @license MIT
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
IT
(function () {
'use strict';
const CHANNEL_URL = 'https://greasyfork.org/en/users/1572947-yakumanchiban';
const LONG_PRESS_MS = 900;
const DRAG_THRESHOLD = 8;
const pos = GM_getValue('btnPos', {
x: window.innerWidth - 40,
y: window.innerHeight / 2
});
const btn = document.createElement('div');
btn.textContent = 'fullscreen';
Object.assign(btn.style, {
position: 'fixed',
left: pos.x + 'px',
top: pos.y + 'px',
transform: 'rotate(90deg)',
fontSize: '10px',
padding: '2px 4px',
background: '#fff',
color: '#000',
opacity: '0.6',
borderRadius: '3px',
zIndex: '999999',
userSelect: 'none',
touchAction: 'none', // PENTING untuk mobile
cursor: 'pointer'
});
document.body.appendChild(btn);
let startX = 0;
let startY = 0;
let dragging = false;
let longPressed = false;
let timer = null;
btn.addEventListener('pointerdown', (e) => {
startX = e.clientX;
startY = e.clientY;
dragging = false;
longPressed = false;
timer = setTimeout(() => {
longPressed = true;
window.location.href = CHANNEL_URL;
}, LONG_PRESS_MS);
btn.setPointerCapture(e.pointerId);
});
btn.addEventListener('pointermove', (e) => {
const dx = e.clientX - startX;
const dy = e.clientY - startY;
if (!dragging && Math.hypot(dx, dy) > DRAG_THRESHOLD) {
dragging = true;
clearTimeout(timer);
timer = null;
}
if (dragging) {
btn.style.left = (e.clientX - 10) + 'px';
btn.style.top = (e.clientY - 10) + 'px';
}
});
btn.addEventListener('pointerup', () => {
if (timer) {
clearTimeout(timer);
timer = null;
}
if (dragging) {
GM_setValue('btnPos', {
x: parseInt(btn.style.left),
y: parseInt(btn.style.top)
});
}
});
btn.addEventListener('click', () => {
if (dragging || longPressed) return;
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen();
btn.textContent = 'windowed';
} else {
document.exitFullscreen();
btn.textContent = 'fullscreen';
}
});
})();