Last active
June 19, 2026 04:11
-
-
Save AuroraWright/6c710b4ce64a7e26a7470aa0b845a76f to your computer and use it in GitHub Desktop.
ttsuscript fork
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name ッツ UI Enhancements (4:3 ereader) | |
| // @namespace http://tampermonkey.net/ | |
| // @version 21.4 | |
| // @description E-ink enhancements for ttu ebook-reader | |
| // @author KanjiEater, Glacey | |
| // @match https://reader.ttsu.app/* | |
| // @homepageURL https://gist.github.com/Glacey/8c8b3cbcd40a56a6460edb29dd6f9202 | |
| // @grant GM_addStyle | |
| // @run-at document-idle | |
| // @noframes | |
| // ==/UserScript== | |
| (function() { | |
| 'use strict'; | |
| // Search "Optional" for common settings changes | |
| // --- SECTION 1: CUSTOM CSS STYLES --- | |
| const allCustomStyles = ` | |
| /* | |
| * SECTION A1: MOBILE BEHAVIOR ENHANCEMENTS | |
| */ | |
| /* Book Manager: Disable save image popup on long tap */ | |
| .book-cover { | |
| pointer-events: none !important; | |
| } | |
| /* Buttons: Remove focus ring on tap */ | |
| * { -webkit-tap-highlight-color: transparent !important; } | |
| *:focus, *:focus-visible { | |
| outline: none !important; | |
| box-shadow: none !important; | |
| } | |
| /* Reader: Remove pull-to-refresh on Chromium browsers */ | |
| html, body { | |
| overscroll-behavior-y: none !important; | |
| } | |
| .ttu-whispersync-container.side-menu .overflow-auto { | |
| touch-action: pan-y !important; | |
| overflow-y: scroll !important; | |
| } | |
| /* (Optional) Book Manager: Remove book title + transparent jacket to prevent yomitan popups and get a cleaner look at covers */ | |
| .bg-gray-800 { | |
| display: none !important; | |
| } | |
| /* (Optional) Reader/Book Manager: Unhide top menu buttons. Disable this on narrow screens (causes overflow) */ | |
| div[class*="sm:flex"], | |
| div[class*="sm\:flex"] { | |
| display: flex !important; | |
| visibility: visible !important; | |
| opacity: 1 !important; | |
| } | |
| div[class*="flex"][class*="sm:hidden"], | |
| div[class*="flex"][class*="sm\:hidden"] { | |
| display: none !important; | |
| } | |
| /* | |
| * SECTION A2: E-INK BEHAVIOR ENHANCEMENTS | |
| */ | |
| /* Whispersync highlight -> Underline */ | |
| span[class^="ttu-whispersync-line-highlight-"].active, | |
| span[class^="ttu-whispersync-line-highlight-"].menu-open { | |
| background: none !important; padding: 0 !important; margin: 0 !important; color: inherit !important; | |
| text-decoration-line: underline !important; text-decoration-style: solid !important; | |
| text-decoration-thickness: 2px !important; text-decoration-color: #333 !important; | |
| text-underline-position: left !important; text-underline-offset: 4px !important; | |
| } | |
| rt span[class^="ttu-whispersync-line-highlight-"].active, | |
| rt span[class^="ttu-whispersync-line-highlight-"].menu-open { | |
| text-decoration: none !important; | |
| } | |
| /* Remove cloud sync icon pulse */ | |
| #ttu-page-footer .animate-pulse { | |
| animation: none !important; | |
| } | |
| /* Top Bar / Footer: Disable transitions */ | |
| .elevation-4, | |
| div.bg-gray-700, | |
| #ttu-page-footer { | |
| transition: none !important; | |
| animation: none !important; | |
| } | |
| /* Top Bar: Add a border */ | |
| .elevation-4 { | |
| border-bottom: 2px solid #e5e5e5 !important; | |
| } | |
| /* Top Bar: Change background to white */ | |
| div.bg-gray-700 { | |
| background-color: #ffffff !important; | |
| } | |
| /* Top Bar: Change text to black */ | |
| div.bg-gray-700, | |
| div.bg-gray-700 .text-white { | |
| color: #000000; | |
| } | |
| /* Top Bar: Lighter gray text for white background */ | |
| .text-gray-500 { | |
| color: rgba(229, 231, 235, 1) !important; | |
| } | |
| /* Remove ripple circle animation click */ | |
| .v-ripple__container, | |
| span.absolute.inset-0.h-full.w-full { | |
| display: none !important; | |
| } | |
| /* General: Disable native swipe scrolling, handled by userscript */ | |
| .overflow-auto, | |
| .mdc-drawer-app-content, | |
| body { | |
| touch-action: none !important; | |
| } | |
| /* Settings: Change settings highlight to gray */ | |
| div.bg-gray-900, | |
| button.bg-gray-900 { | |
| background-color: #e5e5e5 !important; /* Light gray selection */ | |
| color: #000000 !important; /* Force text to black */ | |
| } | |
| /* Settings: Change hover color */ | |
| div[class*="hover:bg-gray-"]:hover, | |
| button[class*="hover:bg-gray-"]:hover { | |
| background-color: #cccccc !important; | |
| } | |
| /* Popups: Gray border */ | |
| section.mdc-elevation--z24 { | |
| border: 2px solid #e5e5e5 !important; | |
| } | |
| /* Remove drop shadows (Book Manager selection, Offline Notification).*/ | |
| .mdc-elevation--z1, | |
| .mdc-elevation--z2, | |
| .mdc-elevation--z4, | |
| .mdc-elevation--z24, | |
| .box-shadow, | |
| [class*="shadow"] { | |
| box-shadow: none !important; | |
| -webkit-box-shadow: none !important; | |
| } | |
| /* Reader: Popup dark backdrop removal (Tracker menu, Offline notification) */ | |
| div[class*="bg-black/[.32]"] { | |
| background-color: transparent !important; | |
| } | |
| /* Reader/Image Gallery: Disable opening animation */ | |
| [style*="__svelte"] { | |
| animation: none !important; | |
| } | |
| /* Reader: Eink friendly loading spinner */ | |
| @keyframes eink-dot1 { | |
| 0%,100% { background: #000; border-color: #000; } | |
| 50% { background: none; border-color: #000; } | |
| } | |
| @keyframes eink-dot2 { | |
| 0%,100% { background: none; border-color: #000; } | |
| 50% { background: #000; border-color: #000; } | |
| } | |
| .fixed.inset-0.flex.h-full.items-center.justify-center.text-7xl svg { | |
| display: none !important; | |
| } | |
| .fixed.inset-0.flex.h-full.items-center.justify-center.text-7xl { | |
| flex-direction: row !important; | |
| writing-mode: horizontal-tb !important; | |
| gap: 14px !important; | |
| } | |
| .fixed.inset-0.flex.h-full.items-center.justify-center.text-7xl::before, | |
| .fixed.inset-0.flex.h-full.items-center.justify-center.text-7xl::after { | |
| content: "" !important; | |
| width: 14px !important; | |
| height: 14px !important; | |
| border-radius: 50% !important; | |
| border: 3px solid #000 !important; | |
| display: block !important; | |
| box-sizing: border-box !important; | |
| flex-shrink: 0 !important; | |
| } | |
| .fixed.inset-0.flex.h-full.items-center.justify-center.text-7xl::before { | |
| animation: eink-dot1 2.4s steps(1) infinite !important; | |
| } | |
| .fixed.inset-0.flex.h-full.items-center.justify-center.text-7xl::after { | |
| animation: eink-dot2 2.4s steps(1) infinite !important; | |
| } | |
| /* Whispersync: Eink friendly loading spinner */ | |
| .ttu-whispersync-container .backdrop .spinner { | |
| animation:ttu-whispersync-spinner-rotation 8s steps(8) infinite !important; | |
| } | |
| /* Whispersync: Dark backdrop removal */ | |
| .ttu-whispersync-container .backdrop { | |
| background-color: transparent !important; | |
| } | |
| /* Book Manager: Black/gray transparent progress bar, no rounded edges */ | |
| .bg-gray-400 { | |
| background-color: rgba(229, 231, 235, 0.8); | |
| } | |
| .to-red-900 { | |
| --tw-gradient-to: rgba(0, 0, 0, 0.8) var(--tw-gradient-to-position) !important; | |
| } | |
| .from-red-600 { | |
| --tw-gradient-from: rgba(0, 0, 0, 0.8) var(--tw-gradient-from-position) !important; | |
| --tw-gradient-to: rgba(0, 0, 0, 0.8) var(--tw-gradient-to-position) !important; | |
| --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to) !important; | |
| } | |
| .rounded { | |
| border-radius: 0rem; | |
| } | |
| /* Book Manager: Change background to white */ | |
| :root { | |
| --background-color: #ffffff; | |
| } | |
| /* Book Manager: Change selected book highlight color */ | |
| div[title="Book selected"] { | |
| background-color: rgba(0,0,0,0.35) !important; | |
| } | |
| /* Book Manager: Change book selected button to white */ | |
| div[title="Book selected"] svg { | |
| color: white !important; | |
| } | |
| /* Book Manager: Change Book Selection untapped color to gray */ | |
| div[title="Enable Book Selection"] svg { | |
| color: #777 !important; | |
| } | |
| /* Book Manager: Increase greyed out option visibility */ | |
| .opacity-5 { | |
| opacity: .3 !important; | |
| } | |
| /* | |
| * SECTION B: BOOK MANAGER | |
| */ | |
| /* Book Manager: Increase top icon clickbox widths, adjust positioning fit narrow screens */ | |
| div[title="Enable Book Selection"] svg { | |
| width: 200px !important; | |
| position: absolute; | |
| left: -75px; | |
| } | |
| div[title="Disable Book Selection"] svg { | |
| width: 200px !important; | |
| position: absolute; | |
| left: -75px; | |
| } | |
| div[title="Select all Books"] svg { | |
| width: 100px !important; | |
| position: absolute !important;; | |
| left: -110px; | |
| } | |
| div[title="Back to Book"] svg { | |
| width: 100px !important; | |
| position: absolute !important; | |
| left: -140px; | |
| } | |
| /* | |
| * SECTION C: TRACKER PANEL | |
| */ | |
| .mb-7 div[title='Toggle Tracker'], | |
| .mb-7 div[title='Update Position'], | |
| .mb-7 div[title='Toggle Freeze Position'] { | |
| /* Tracker panel button size */ | |
| width: 60px !important; | |
| height: 60px !important; | |
| display: flex !important; | |
| align-items: center !important; | |
| justify-content: center !important; | |
| //z-index: 11 !important; Prioritize over close button | |
| } | |
| .mb-7 div[title='Toggle Tracker'] svg, | |
| .mb-7 div[title='Update Position'] svg, | |
| .mb-7 div[title='Toggle Freeze Position'] svg { | |
| width: 2.2rem !important; | |
| height: 2.2rem !important; | |
| } | |
| /* Reduce tracker panel width so it's easier to click out */ | |
| .max-w-xl { | |
| max-width:25rem; | |
| } | |
| /* Remove tracker panel header and close button */ | |
| div[class*="min-h-"][class*="60px"] { | |
| min-height: 0px !important; | |
| height: 0px !important; | |
| } | |
| div[role="button"][title="Close Tracker Menu"] svg { | |
| width: 2.2rem !important; | |
| height: 2.2rem !important; | |
| } | |
| /* Increase close button clickbox */ | |
| div[role="button"][title="Close Tracker Menu"] { | |
| width: 200px !important; | |
| height: 200px !important; | |
| justify-content: center !important; | |
| } | |
| /* Pin close button to the bottom of the screen to prevent accidental yomitan popups after closing */ | |
| div[title="Close Tracker Menu"] { | |
| position: absolute !important; | |
| bottom: -75px !important; | |
| right: -75px !important; | |
| //z-index: 10 !important; 1 lower than tracker buttons (no daily goal) | |
| } | |
| /* Remove margin between "Remaining Time Left" and tracker buttons for better visual balance + help content fit the screen */ | |
| .mb-6 { | |
| margin-bottom: 0rem !important; | |
| } | |
| /* Reduce top margin to help content fit on screen without scrolling */ | |
| div.mt-4:nth-child(3){ | |
| margin-top: 1rem !important; | |
| } | |
| /* Remove bottom margin to help content fit on screen without scrolling */ | |
| div.mb-7:last-child { | |
| margin-bottom: 0rem !important; | |
| } | |
| /* | |
| * SECTION D: FOOTER | |
| */ | |
| #ttu-page-footer { | |
| height: auto !important; | |
| pointer-events: none !important; /* Uncomment this to disable footer taps from toggling the progress bar */ | |
| } | |
| #ttu-page-footer > div:first-child { | |
| flex-wrap: wrap !important; | |
| width: auto !important; | |
| } | |
| .book-content--writing-vertical-rl .main, | |
| .book-content--writing-vertical-rl .ttu-book-body-wrapper:not(:has(.main)) { | |
| padding-bottom: 30px !important; /* Padding between the footer and text */ | |
| box-sizing: border-box !important; | |
| } | |
| #ttu-page-footer button, | |
| #ttu-page-footer div[role="button"]:not([title="Click to copy Progress"]) { | |
| display: flex !important; | |
| align-items: center !important; | |
| justify-content: center !important; | |
| flex-shrink: 0; | |
| height: 34px !important; /* Clickbox height from bottom margin */ | |
| margin-bottom: 5px !important; /* Additional bottom margin for lowering clickbox */ | |
| margin-inline: 13px !important; /* Footer icon spacing */ | |
| } | |
| /* Footer icon size */ | |
| #ttu-page-footer svg { | |
| width: 1.2rem !important; | |
| height: 1.2rem !important; | |
| } | |
| /* Progress tracker visual changes */ | |
| div[title="Click to copy Progress"] { | |
| padding: 6px 6px !important; | |
| } | |
| /* | |
| * SECTION E: WHISPERSYNC FLYOUT MENU | |
| */ | |
| /* Whispersync menu icon size */ | |
| #ttu-page-footer .ttu-whispersync-container svg { | |
| width: 1.4rem !important; | |
| height: 1.4rem !important; | |
| } | |
| /* Whispersync menu icon spacing fix */ | |
| #ttu-page-footer .ttu-whispersync-container button, | |
| #ttu-page-footer .ttu-whispersync-container div[role="button"] { | |
| width: auto !important; height: auto !important; | |
| margin: 0 !important; | |
| } | |
| /* Whispersync menu icon wrapping fix */ | |
| .ttu-whispersync-container.side-menu .flex.items-center.w-full.m-t-b { | |
| display: flex !important; | |
| flex-wrap: wrap !important; | |
| justify-content: center !important; | |
| } | |
| #ttu-page-footer .ttu-whispersync-container.side-menu .m-t-b button { | |
| width: 60px !important; /* Flyout player button spacing */ | |
| height: 60px !important; | |
| display: flex !important; | |
| align-items: center !important; | |
| justify-content: center !important; | |
| } | |
| /* Flyout player button size */ | |
| #ttu-page-footer .ttu-whispersync-container.side-menu .m-t-b button svg { | |
| width: 2.2rem !important; | |
| height: 2.2rem !important; | |
| } | |
| /* Speed change flex menu fix */ | |
| .ttu-whispersync-container .playback-display { | |
| align-items: center !important; | |
| } | |
| .ttu-whispersync-container .playback-rates { | |
| width:fit-content !important; | |
| } | |
| .ttu-whispersync-container .m-x-s { | |
| margin-left:0rem; | |
| margin-right:0rem; | |
| width:35px; | |
| text-align: center !important; | |
| } | |
| /* Move speed change button before mute to accodomate the larger popup */ | |
| .ttu-whispersync-container .flex.items-center.w-full.m-t-b { | |
| button[title="Toggle mute"] { order: 6 !important; } | |
| } | |
| /* SECTION F: IMAGE GALLERY EINK REWORK */ | |
| /* 1. Spoiler label */ | |
| button.spoiler-label.svelte-17iwc5x { | |
| /* ネタバレ text */ | |
| color: rgba(0, 0, 0, 0.6) !important; | |
| font-size: 32px !important; | |
| /* Fullscreen clickbox */ | |
| background-color: transparent !important; | |
| position: absolute !important; | |
| top: 0 !important; | |
| left: 0 !important; | |
| width: 100% !important; | |
| height: 100% !important; | |
| display: flex !important; | |
| align-items: center !important; | |
| justify-content: center !important; | |
| /* Remove site defaults that cause misalignment */ | |
| transform: none !important; | |
| margin: 0 !important; | |
| border: none !important; | |
| z-index: 5 !important; | |
| cursor: pointer !important; | |
| } | |
| .spoiler.svelte-17iwc5x img.svelte-17iwc5x{ | |
| filter: blur(10px); /* Reduced image blur for E-Ink */ | |
| } | |
| /* 2. Close gallery button */ | |
| div.sticky.top-0.flex.justify-between.p-2.z-10 { | |
| background-color: transparent !important; | |
| position: absolute !important; | |
| top: 0 !important; | |
| left: 0 !important; | |
| pointer-events: none !important; | |
| z-index: 100 !important; | |
| } | |
| button[title="Close Image Gallery"] { | |
| /* Clickbox settings */ | |
| pointer-events: auto !important; | |
| width: 70px !important; | |
| height: 80px !important; | |
| display: flex !important; | |
| align-items: center !important; | |
| justify-content: center !important; | |
| } | |
| button[title="Close Image Gallery"] svg { | |
| /* Icon Settings */ | |
| width: 32px !important; | |
| height: 32px !important; | |
| color: rgba(0, 0, 0, 0.6) !important; | |
| } | |
| /* 3. Gallery layout */ | |
| .overflow-auto.p-2 { | |
| display: flex !important; | |
| flex-direction: column !important; | |
| overflow-y: scroll !important; | |
| height: 100vh !important; | |
| padding: 0 !important; | |
| -ms-overflow-style: none !important; | |
| scrollbar-width: none !important; | |
| scroll-snap-type: none !important; | |
| scroll-behavior: auto !important; | |
| touch-action: none !important; | |
| } | |
| .overflow-auto.p-2 > button { | |
| min-height: 100vh !important; | |
| height: 100vh !important; | |
| width: 100vw !important; | |
| display: flex !important; | |
| align-items: center !important; | |
| justify-content: center !important; | |
| margin: 0 !important; | |
| flex-shrink: 0 !important; | |
| } | |
| .overflow-auto.p-2 img { | |
| max-height: 100vh !important; | |
| max-width: 100vw !important; | |
| object-fit: contain !important; | |
| } | |
| /* 4. Custom Gallery Counter */ | |
| #ttu-gallery-counter { | |
| position: fixed !important; | |
| bottom: 10px !important; | |
| left: 10px !important; | |
| background-color: rgba(0, 0, 0, 0.6) !important; | |
| color: #ffffff !important; | |
| padding: 3px 7px !important; | |
| border-radius: 3px !important; | |
| font-size: 12px !important; | |
| z-index: 1000 !important; | |
| writing-mode: horizontal-tb !important; | |
| pointer-events: none !important; | |
| } | |
| `; | |
| GM_addStyle(allCustomStyles); | |
| // --- SECTION 2: JAVASCRIPT PAGE TURN FUNCTIONS --- | |
| /* Settings */ | |
| const DISABLE_READER_SWIPE = true; // (Optional) Disables vertical swipe page turning while reading. Vertical swipe page turns fix the page turn buttons on iReader devices, not necessary on others | |
| const SWIPE_THRESHOLD = 30; | |
| const SCROLL_FACTOR_SETTINGS = 0.75; | |
| const SCROLL_FACTOR_LIBRARY = 0.72; // Scroll 2 books at a time. Adjust for other devices | |
| /* -------- */ | |
| let isProcessing = false; | |
| let touchstartY = 0; | |
| let galleryIndex = 0; | |
| let currentCtx = 'READER'; | |
| // 1. Context Detection | |
| const getAppContext = () => { | |
| const url = window.location.href.toLowerCase(); | |
| if (document.querySelector('.overflow-auto.p-2')) return 'GALLERY'; | |
| else if (url.includes('manage')) return 'LIBRARY'; | |
| else if (url.includes('settings')) return 'SETTINGS'; | |
| else if (document.querySelector('.ttu-whispersync-container.side-menu:not(.hidden)')) return 'WHISPERSYNC'; | |
| else return 'READER'; | |
| }; | |
| // 2. Key Press Function | |
| const sendKey = (keyName) => { | |
| const keyCode = keyName === 'PageUp' ? 33 : 34; | |
| const opts = { key: keyName, code: keyName, keyCode, which: keyCode, bubbles: true }; | |
| document.dispatchEvent(new KeyboardEvent('keydown', opts)); | |
| document.dispatchEvent(new KeyboardEvent('keyup', opts)); | |
| }; | |
| // 3. Touch Interceptor (Swipe -> Key) | |
| document.addEventListener('touchstart', e => { | |
| currentCtx = getAppContext(); | |
| touchstartY = e.changedTouches[0].screenY; | |
| //console.log('Context:', currentCtx); | |
| isProcessing = false; | |
| }, { capture: true, passive: true }); | |
| document.addEventListener('touchmove', e => { | |
| if (currentCtx === 'READER' && DISABLE_READER_SWIPE) { | |
| return; | |
| } | |
| else if (currentCtx !== 'READER') { | |
| if (e.cancelable) e.preventDefault(); | |
| e.stopImmediatePropagation(); | |
| } | |
| if (isProcessing) return; | |
| const diffY = e.changedTouches[0].screenY - touchstartY; | |
| if (Math.abs(diffY) > SWIPE_THRESHOLD) { | |
| isProcessing = true; | |
| sendKey(diffY < 0 ? 'PageDown' : 'PageUp'); | |
| } | |
| }, { capture: true, passive: false }); | |
| // 4. Reduced Motion Scrolling | |
| window.addEventListener('keydown', (e) => { | |
| const ctx = getAppContext(); | |
| const isDown = e.key === 'PageDown' || e.key === 'ArrowDown'; | |
| const isUp = e.key === 'PageUp' || e.key === 'ArrowUp'; | |
| if (!isDown && !isUp) return; | |
| // Gallery Scrolling | |
| if (ctx === 'GALLERY') { | |
| e.preventDefault(); | |
| e.stopImmediatePropagation(); | |
| const gallery = document.querySelector('.overflow-auto.p-2'); | |
| const images = getImageButtons(); | |
| if (images.length === 0) return; | |
| const oldIndex = galleryIndex; | |
| if (isDown && galleryIndex < images.length - 1) galleryIndex++; | |
| else if (isUp && galleryIndex > 0) galleryIndex--; | |
| if (oldIndex !== galleryIndex) { | |
| gallery.scrollTo({ | |
| top: galleryIndex * window.innerHeight, | |
| behavior: 'auto' | |
| }); | |
| updateGalleryCounter(); | |
| } | |
| } | |
| // Book Manager + Settings Scrolling | |
| else if (ctx === 'LIBRARY' || ctx === 'SETTINGS') { | |
| e.preventDefault(); | |
| e.stopImmediatePropagation(); | |
| const factor = (ctx === 'SETTINGS') ? SCROLL_FACTOR_SETTINGS : SCROLL_FACTOR_LIBRARY; | |
| //console.log(`Scroll Context: ${ctx} | Applied Factor: ${factor}`); | |
| const distance = factor * window.innerHeight; | |
| window.scrollBy({ top: isDown ? distance : -distance, behavior: 'auto' }); | |
| } | |
| // Whispersync Menu Scrolling | |
| else if (ctx === 'WHISPERSYNC') { | |
| e.preventDefault(); | |
| e.stopImmediatePropagation(); | |
| const panels = document.querySelectorAll('.ttu-whispersync-container.side-menu .overflow-auto'); | |
| const settingsPanel = panels[panels.length - 1]; | |
| const subtitlePanel = document.querySelector('.ttu-whispersync-container.subtitle-container'); | |
| const panel = (subtitlePanel && subtitlePanel.scrollHeight > subtitlePanel.clientHeight) | |
| ? subtitlePanel | |
| : settingsPanel; | |
| if (!panel) return; | |
| const distance = 0.75 * panel.clientHeight; | |
| panel.scrollTop += isDown ? distance : -distance; | |
| } | |
| }, { capture: true }); | |
| // 5. Custom Gallery Functions | |
| const getImageButtons = () => { | |
| const gallery = document.querySelector('.overflow-auto.p-2'); | |
| if (!gallery) return []; | |
| return Array.from(gallery.querySelectorAll(':scope > button')).filter(btn => | |
| btn.querySelector('img') || btn.hasAttribute('data-image-index') | |
| ); | |
| }; | |
| const updateGalleryCounter = () => { | |
| const images = getImageButtons(); | |
| let counter = document.getElementById('ttu-gallery-counter'); | |
| if (images.length === 0) { if (counter) counter.remove(); return; } | |
| if (!counter) { | |
| counter = document.createElement('div'); | |
| counter.id = 'ttu-gallery-counter'; | |
| document.body.appendChild(counter); | |
| } | |
| counter.innerText = `${galleryIndex + 1} / ${images.length}`; | |
| }; | |
| const galleryObs = new MutationObserver(() => { | |
| const g = document.querySelector('.overflow-auto.p-2'); | |
| const counter = document.getElementById('ttu-gallery-counter'); | |
| if (g) { | |
| if (!g.dataset.jumpAttached) { | |
| g.dataset.jumpAttached = "true"; | |
| galleryIndex = 0; | |
| g.scrollTop = 0; | |
| setTimeout(updateGalleryCounter, 50); | |
| } | |
| } else { | |
| if (counter) counter.remove(); | |
| } | |
| }); | |
| galleryObs.observe(document.body, { childList: true, subtree: true }); | |
| // --- (OPTIONAL): OFFLINE POPUP REMOVER --- | |
| const uiObserver = new MutationObserver((mutations) => { | |
| for (const mutation of mutations) { | |
| if (mutation.addedNodes.length) { | |
| // Task 1: Hide Load Error | |
| const h2 = document.querySelector('h2.weight-medium'); | |
| if (h2 && h2.innerText === "Load Error") { | |
| h2.closest('div.z-50').style.display = 'none'; | |
| } | |
| } | |
| } | |
| }); | |
| uiObserver.observe(document.body, { childList: true, subtree: true }); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment