您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Block all users who love a certain tweet
当前为
// ==UserScript== // @name Twitter Block With Love // @namespace https://www.eolstudy.com // @version 1.1 // @description Block all users who love a certain tweet // @author Eol // @run-at document-end // @match https://twitter.com/* // @match https://mobile.twitter.com/* // @require https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js // @require https://cdn.jsdelivr.net/npm/qs/dist/qs.min.js // @require https://code.jquery.com/jquery-3.4.1.min.js // @require https://greasyfork.org/scripts/2199-waitforkeyelements/code/waitForKeyElements.js?version=6349 // ==/UserScript== /* global axios $ Qs waitForKeyElements*/ (_ => { var lang = document.documentElement.lang // alert("lang = " + document.documentElement.lang) const translations = { // add your own language here by copy one and modifying it "en": { lang_name: "English", likedby: "Timeline: Liked by", // aria-label title: "Liked by", btn: "Block All", success: "All Users Blocked!" }, "en-GB": { lang_name: "British English", likedby: "Timeline: Liked by", title: "Liked by", btn: "Block All", success: "All Users Blocked!" }, "zh": { lang_name: "简体中文", likedby: '时间线:喜欢者', title: "喜欢者", btn: "拉清单", success: "已屏蔽所有为这条推文打心的账户!" }, "zh-Hant": { lang_name: "正體中文", likedby: '時間軸:已被喜歡', title: "已被喜歡", btn: "全部封鎖", success: "已封鎖所有喜歡了這條推文的賬戶!" }, "ja": { lang_name: "日本語", likedby: "タイムライン: いいねしたユーザー", title: "いいねしたユーザー", btn: "一括でブロック", success: "全てブロックした!" } } var i18n = (translations[lang]) if (!i18n) { var langnames = [] for(let l in translations) langnames.push(translations[l].lang_name) langnames = langnames.join(", ") alert("Twitter Block With Love userscript does not support your language. Please add your language to the translations string in the editor, or switch the language of Twitter Web App to the following languages: " + langnames + ".") } function get_cookie (cname) { var name = cname + "=" var ca = document.cookie.split(';') for(var i=0; i<ca.length; i++) { var c = ca[i].trim() if (c.indexOf(name)==0) { return c.substring(name.length,c.length) } } return "" } const ajax = axios.create({ baseURL: 'https://api.twitter.com', withCredentials: true, headers: { 'Authorization': 'Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA', 'X-Twitter-Auth-Type': 'OAuth2Session', 'X-Twitter-Active-User': 'yes', 'X-Csrf-Token': get_cookie('ct0') } }) function get_tweet_id () { // https://twitter.com/any/thing/status/1234567/anything => 1234567/anything => 1234567 return location.href.split('status/')[1].split('/')[0] } async function fetch_likers (tweetId) { const users = await ajax.get(`/2/timeline/liked_by.json?tweet_id=${tweetId}`).then( res => res.data.globalObjects.users ) let likers = [] for (let user in users) { likers.push(users[user].id_str) } return likers } function block_user (id) { ajax.post('/1.1/blocks/create.json', Qs.stringify({ user_id: id }), { headers: { "Content-Type":'application/x-www-form-urlencoded' } }) } async function block_all_likers () { const tweet_id = get_tweet_id() const likers = await fetch_likers(tweet_id) likers.forEach(id => block_user(id)) } function clear_view () { const container = $('div[aria-label="'+ i18n.likedby + '"]') container.children().fadeOut(400, _ => { const notice = $(` <div style=" color: rgb(224, 36, 94); text-align: center; margin-top: 3em; font-size: x-large; "> <span>${i18n.success}</span> </div> `) container.append(notice) }) } function mount_block_button (dom) { const btn_mousedown = 'bwl-btn-mousedown' const btn_hover = 'bwl-btn-hover' $('head').append(` <style> .bwl-btn-base { min-height: 30px; padding-left: 1em; padding-right: 1em; border: 1px solid rgb(29, 161, 242) !important; border-radius: 9999px; } .${btn_mousedown} { background-color: rgba(29, 161, 242, 0.2); cursor: pointer; } .${btn_hover} { background-color: rgba(29, 161, 242, 0.1); cursor: pointer; } .bwl-btn-inner-wrapper { font-weight: bold; -webkit-box-align: center; align-items: center; -webkit-box-flex: 1; flex-grow: 1; color: rgba(29,161,242,1.00); display: flex; } .bwl-text-font { font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif; } </style> `) const button = $(` <div aria-haspopup="true" role="button" data-focusable="true" class="bwl-btn-base" > <div class="bwl-btn-inner-wrapper"> <span> <span class="bwl-text-font">${i18n.btn}</span> </span> </div> </div> `) .addClass(dom.prop('classList')[0]) .hover(function () { $(this).addClass(btn_hover) }, function () { $(this).removeClass(btn_hover) $(this).removeClass(btn_mousedown) }) .on('selectstart', function () { return false }) .mousedown(function () { $(this).removeClass(btn_hover) $(this).addClass(btn_mousedown) }) .mouseup(function () { $(this).removeClass(btn_mousedown) if ($(this).is(':hover')) { $(this).addClass(btn_hover) } }) .click(block_all_likers) .click(clear_view) dom.append(button) } function main () { waitForKeyElements('h2:has(> span:contains(' + i18n.title + '))', dom => { mount_block_button(dom.parent().parent().parent()) }) } main() })()