您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Live-update (auto-refresh) LetsRun.com threads and get notified when new posts come in
- // ==UserScript==
- // @name LRC Live
- // @namespace lrc-live
- // @description Live-update (auto-refresh) LetsRun.com threads and get notified when new posts come in
- // @match https://www.letsrun.com/forum/flat_read.php*
- // @version 1.3
- // @grant none
- // ==/UserScript==
- const urlParams = new URLSearchParams(window.location.search);
- const pageNo = +urlParams.get('page') || 0;
- const pages = document.querySelector('span.items-stretch')?.querySelectorAll('a[aria-label="pagination.goto_page"]') || [];
- const lastPage = +pages[pages.length - 1]?.innerText || 0;
- if (pageNo === lastPage) {
- const template = document.createElement('template');
- template.innerHTML = '<a role="button" title="Toggle LRC Live" class="button font-bold button-red shadow-md mt-2" style="width: 100%">Start LRC Live</a>';
- const liveButton = template.content.firstChild;
- const threadContainer = document.querySelector('div.forum-thread-page-container');
- threadContainer.parentNode.insertBefore(liveButton, threadContainer.nextSibling);
- const thread = +urlParams.get('thread');
- const posts = document.querySelectorAll('li.forum-post-container');
- const postIds = [...posts].map(post => post.querySelector('div').getAttribute('id'));
- const postList = document.querySelector('ul.post-list');
- const postCountText = document.querySelector('p.text-gray-700');
- const postCounters = postCountText ? [...postCountText.querySelectorAll('span.font-semibold')].slice(1) : [];
- let wireKey = posts.length;
- let checkPageNo = posts.length === 20 ? pageNo + 1 : pageNo;
- let enabled = false;
- let interval;
- liveButton.addEventListener('click', async () => {
- liveButton.classList.toggle('button-red');
- liveButton.classList.toggle('button-green');
- enabled = !enabled;
- if (enabled) {
- liveButton.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="default-icon dbr-spin mr-2 h-3 w-3"><path d="M296 48c0 22.091-17.909 40-40 40s-40-17.909-40-40 17.909-40 40-40 40 17.909 40 40zm-40 376c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40zm248-168c0-22.091-17.909-40-40-40s-40 17.909-40 40 17.909 40 40 40 40-17.909 40-40zm-416 0c0-22.091-17.909-40-40-40S8 233.909 8 256s17.909 40 40 40 40-17.909 40-40zm20.922-187.078c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40c0-22.092-17.909-40-40-40zm294.156 294.156c-22.091 0-40 17.909-40 40s17.909 40 40 40c22.092 0 40-17.909 40-40s-17.908-40-40-40zm-294.156 0c-22.091 0-40 17.909-40 40s17.909 40 40 40 40-17.909 40-40-17.909-40-40-40z"></path></svg> LRC Live is running, new posts in this thread will appear above... (click to stop)';
- const perm = await Notification.requestPermission();
- const notify = perm === 'granted';
- interval = window.setInterval(async () => {
- try {
- const url = 'https://www.letsrun.com/forum/flat_read.php?' + new URLSearchParams({ thread, page: checkPageNo });
- const checkPage = await fetch(url);
- const checkPageText = await checkPage.text();
- const checkPageDoc = new DOMParser().parseFromString(checkPageText, 'text/html');
- const checkPosts = checkPageDoc.querySelectorAll('li.forum-post-container');
- [...checkPosts].forEach(post => {
- const postDiv = post.querySelector('div');
- const postId = postDiv.getAttribute('id');
- if (postIds.includes(postId)) return;
- postIds.push(postId);
- postDiv.setAttribute('wire:key', wireKey++);
- if (postDiv.classList.contains('mt-0')) {
- postDiv.classList.remove('mt-0');
- postDiv.classList.add('mt-1');
- }
- postList.appendChild(post);
- postCounters.forEach(pc => pc.innerText = +pc.innerText + 1);
- if (notify) {
- const n = new Notification(`LRC Live: New post in "${document.title}"`, { body: post.querySelector('div.post-body').innerText, icon: '/assets/images/letsrun-logo.png' });
- document.addEventListener('visibilitychange', () => {
- if (document.visibilityState === 'visible') n.close();
- });
- }
- });
- if (checkPosts.length === 20) checkPageNo++;
- } catch (err) { console.error(err); }
- }, 5000);
- } else {
- liveButton.innerText = 'Start LRC Live';
- window.clearInterval(interval);
- }
- });
- }