您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add score indicator to threads using the (likes/replies) metric.
// ==UserScript== // @name QQ/SB/SV Score // @author C89sd // @namespace https://greasyfork.org/users/1376767 // @version 0.3 // @description Add score indicator to threads using the (likes/replies) metric. // @match https://*.questionablequesting.com/* // @match https://*.spacebattles.com/* // @match https://*.sufficientvelocity.com/* // @grant GM_addStyle // @noframes // ==/UserScript== 'use strict'; const ALIGN_LEFT = true; const COMPACT = false; if (window.location.href.includes('/threads/')) return; let scale, PT; const domain = window.location.hostname.split('.').slice(-2, -1)[0].toLowerCase(); if (domain === "spacebattles") scale = 10.24/10.24; if (domain === "questionablequesting") scale = 10.24/ 2.4; if (domain === "sufficientvelocity") scale = 10.24/ 9.8; scale = scale * (100 / (10.24 * 2.0)); // didn't measure std so assume x2 interval PT = 0 // scale = scale // PT = 1 // #MEASURE_SCALE# // const KEY = 'average'; // const data = JSON.parse(localStorage.getItem(KEY) || '{"sum":0,"count":0}'); GM_addStyle(` /* Hide on large screens */ .mscore { display: none; } /* Show on mobile */ @media (max-width: 650px) { .mscore { display: block; } .mscore.mright { float: right !important; } .mscore.mleft.mcompact { padding-left: 4px !important; } .mscore::before { content: none !important; } .mscore.mleft:not(.mcompact)::before{ content: "\\00A0\\00B7\\20\\00A0\\00A0" !important; } } `); function parseKmDigit(text) { if (!text) return NaN; const cleanedText = text.trim().toLowerCase(); const multiplier = cleanedText.endsWith('k') ? 1000 : cleanedText.endsWith('m') ? 1000000 : 1; return parseFloat(cleanedText.replace(/,/g, '')) * multiplier; } const threads = document.getElementsByClassName('structItem--thread'); // const threads = document.querySelectorAll('.js-threadList>.structItem--thread, .structItemContainer>.structItem--thread'); for (const thread of threads) { const meta = thread.querySelector(':scope > .structItem-cell--meta'); if (!meta) { console.log('Scorer skip: no meta cell', thread); continue; } const titleAttr = meta.getAttribute('title'); const likesMatch = titleAttr?.match(/([\d,]+)/); if (!likesMatch) { console.log('Scorer skip: no likes match in title', thread); continue; } const likes = parseInt(likesMatch[1].replace(/,/g, ''), 10); const repliesText = meta.firstElementChild?.lastElementChild?.textContent; let replies = parseKmDigit(repliesText); if (replies === 0) replies = 1; if (isNaN(likes) || isNaN(replies)) { console.log('Scorer skip: NaN likes/replies', {likes, replies, thread}); continue; } if (replies >= 1000) { const pagesEl = thread.querySelector('.structItem-pageJump a:last-of-type'); const pages = pagesEl ? parseInt(pagesEl.textContent, 10) : 1; replies = Math.max(replies, Math.floor((pages - 0.5) * 25)); } const score = (scale * likes / replies).toFixed(PT); { const desktopScoreEl = document.createElement('dl'); desktopScoreEl.className = 'pairs pairs--justified structItem-minor'; const dt = document.createElement('dt'); dt.textContent = 'Score'; const dd = document.createElement('dd'); dd.appendChild(document.createTextNode(score)); desktopScoreEl.appendChild(dt); desktopScoreEl.appendChild(dd); meta.appendChild(desktopScoreEl); } { const mobileScoreEl = document.createElement('div'); mobileScoreEl.className = 'structItem-cell structItem-cell--latest mscore ' + (ALIGN_LEFT ? "mleft" : "mright") + (COMPACT ? " mcompact":""); mobileScoreEl.textContent = score; if (ALIGN_LEFT) thread.insertBefore(mobileScoreEl, thread.querySelector('.structItem-cell--latest') || null); else thread.appendChild(mobileScoreEl); } // #MEASURE_SCALE# // data.sum += score; data.count++; } // #MEASURE_SCALE# // localStorage.setItem(KEY, JSON.stringify(data)); // console.log(`${KEY}: ${(data.sum/data.count).toFixed(2)} (n=${data.count})`);