您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Shows additional user information on the sidebar of modmail
当前为
- // ==UserScript==
- // @name [Reddit] ModmailExtraInfo
- // @namespace HKR
- // @match https://mod.reddit.com/mail/*
- // @grant none
- // @version 1.6
- // @author HKR
- // @description Shows additional user information on the sidebar of modmail
- // @require https://greasyfork.org/scripts/21927-arrive-js/code/arrivejs.js
- // @icon https://www.redditstatic.com/modmail/favicon/favicon-32x32.png
- // @supportURL https://github.com/Hakorr/Userscripts/issues
- // ==/UserScript==
- /* NOTE: (If you want to use the Custom Responses) Reddit's sync feature removes the script's added text. This is a bug in my script and can be fixed with time.
- If you block "https://oauth.reddit.com/api/mod/conversations/*****?markRead=false&redditWebClient=modmail", the added text will stay. Thanks for understanding.*/
- /* VARIABLES FOR RESPONSES */
- var subTag = document.getElementsByClassName("ThreadTitle__community")[0].href.slice(23);
- var userTag = "u/" + document.getElementsByClassName("InfoBar__username")[0].innerText;
- var modmail = `[modmail](https://www.reddit.com/message/compose?to=/${subTag})`;
- /* SETTINGS */
- var textColor = null;
- var lightModeTextColor = "#6e6e6e";
- var darkModeTextColor = "#757575";
- var titleColor = null;
- var lightModeTitleColor = "#2c2c2c";
- var darkModeTitleColor = "#a7a7a7";
- var listBoxColor = null;
- var lightModeListColor = "#fff";
- var darkModeListColor = "#242424";
- var dataColor = "#0079d3";
- var enableCustomResponses = true;
- //Feel free to edit and add more responses suitable for you! Replace means if to replace all text or just to add the text.
- var responses = [
- {
- "name":"Select a template",
- "replace":true,
- "content":``
- },
- {
- "name":"Default approved",
- "replace":true,
- "content":`Hey, approved the post!`
- },
- {
- "name":"Default rule broken",
- "replace":true,
- "content":`Your post broke our rules.\n\nThe action will not be reverted.`
- },
- {
- "name":"Add thanks",
- "replace":false,
- "content":`\n\nThank you!`
- },
- {
- "name":"Add subreddit mention",
- "replace":false,
- "content":`${subTag}`
- },
- {
- "name":"Add user mention",
- "replace":false,
- "content":`${userTag}`
- },
- {
- "name":"Add Modmail link",
- "replace":false,
- "content":`${modmail}`
- },
- {
- "name":"Add Content Policy",
- "replace":false,
- "content":`[Content Policy](https://www.redditinc.com/policies/content-policy)`
- },
- {
- "name":"Add User Agreement",
- "replace":false,
- "content":`[User Agreement](https://www.redditinc.com/policies/user-agreement)`
- },
- {
- "name":"Add Rickroll",
- "replace":false,
- "content":`[link](https://www.youtube.com/watch?v=dQw4w9WgXcQ)`
- }
- ];
- /* ---------- JS & HTML ---------- */
- function Get(url) {
- var xmlHttp = new XMLHttpRequest();
- xmlHttp.open( "GET", url, false );
- xmlHttp.send( null );
- return xmlHttp.responseText;
- }
- function time(UNIX_timestamp){
- var a = new Date(UNIX_timestamp * 1000);
- var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
- var year = a.getFullYear();
- var month = months[a.getMonth()];
- var date = a.getDate();
- var hour = fixnumber(a.getHours());
- var min = fixnumber(a.getMinutes());
- var sec = fixnumber(a.getSeconds());
- var time = date + ' ' + month + ' ' + year + ' ' + hour + ':' + min + ':' + sec ;
- return time;
- }
- function fixnumber(number) {
- if(number < 10) return "0" + number;
- else return number;
- }
- function sanitize(evilstring) {
- const decoder = document.createElement('div')
- decoder.innerHTML = evilstring;
- return decoder.textContent;
- }
- //Function that appends HTML into the Modmail page
- function addInfo(){
- //Load and parse username
- var username = document.getElementsByClassName("InfoBar__username")[0].innerText;
- var about = "https://www.reddit.com/user/" + username + "/about.json";
- var user = JSON.parse(Get(about));
- //Separator HTML element
- var seperator = document.createElement('div');
- seperator.innerHTML = '<div class="InfoBar__modActions"></div>';
- //HTML element that contains all the data
- var userDetails = document.createElement('div');
- userDetails.classList.add("InfoBar__age");
- userDetails.innerHTML = `
- <img class="profileIcon" src="${user.data.icon_img}" width="25">
- <a class="InfoBar__username" href="https://www.reddit.com/user/${user.data.name}">${user.data.subreddit.display_name_prefixed}</a>
- <h1 style="color: ${textColor} ; font-size: 11px; margin-top: 17px; margin-bottom: 10px;">${sanitize(user.data.subreddit.public_description)}</h1>
- <h1 class="dataTitle">Main</h1>
- <div class="dataText">
- <p>Created: <span class="value">${time(user.data.created)}</span></p>
- <p>UserID: <span class="value">${user.data.id}</span></p>
- <p>Verified: <span class="value">${user.data.verified}</span></p>
- <p>Employee: <span class="value">${user.data.is_employee}</span></p>
- <p>NSFW Profile: <span class="value">${user.data.subreddit.over_18}</span></p>
- </div>
- <h1 class="dataTitle">Karma</h1>
- <div class="dataText">
- <p>Post: <span class="value">${user.data.link_karma}</span></p>
- <p>Comment: <span class="value">${user.data.comment_karma}</span></p>
- <p>Total: <span class="value">${user.data.total_karma}</span></p>
- <p>Awardee: <span class="value">${user.data.awardee_karma}</span></p>
- <p>Awarder: <span class="value">${user.data.awarder_karma}</span></p>
- </div>
- <h1 class="dataTitle">Links</h1>
- <div style="padding-left: 10px;">
- <a class="InfoBar__recent" href="https://redditmetis.com/user/${user.data.name}" target="_blank">Redditmetis</a>
- <a class="InfoBar__recent" href="https://www.reddit.com/search?q=${user.data.name}" target="_blank">Reddit Search</a>
- <a class="InfoBar__recent" href="https://www.google.com/search?q=%22${user.data.name}%22" target="_blank">Google Search</a>
- </div>
- `;
- //Arrange items and append
- document.getElementsByClassName("ThreadViewer__infobar")[0].appendChild(seperator);
- document.getElementsByClassName("ThreadViewer__infobar")[0].appendChild(userDetails);
- document.getElementsByClassName("ThreadViewer__infobar")[0].appendChild(document.getElementsByClassName("ThreadViewer__infobar")[0].firstChild);
- document.getElementsByClassName("InfoBar")[0].appendChild(document.getElementsByClassName("InfoBar__modActions")[0]);
- document.getElementsByClassName("InfoBar")[0].insertBefore(document.getElementsByClassName("InfoBar__modActions")[0],document.getElementsByClassName("InfoBar")[0].firstChild);
- if(document.getElementsByClassName("InfoBar__banText")[0])
- document.getElementsByClassName("ThreadViewer__infobar")[0].insertBefore(document.getElementsByClassName("InfoBar__banText")[0],document.getElementsByClassName("ThreadViewer__infobar")[0].firstChild);
- document.getElementsByClassName("InfoBar__username")[1].outerHTML = "";
- document.getElementsByClassName("InfoBar__age")[1].outerHTML = "";
- document.getElementsByClassName("InfoBar__modActions")[1].outerHTML = "";
- }
- function addResponseBox() {
- //Listbox element
- var responseBox = document.createElement('div');
- responseBox.classList.add("select");
- responseBox.innerHTML = `
- <h2 class="dataTitle">Response templates</h2>
- <select id="responseListbox" onchange="listBoxChanged(this.value);" onfocus="this.selectedIndex = -1;"/>
- <span class="focus"></span>
- `;
- //Script element to head
- var headJS = document.createElement('script');
- headJS.innerHTML = `
- function listBoxChanged(message) {
- var messageBox = document.getElementsByClassName("Textarea ThreadViewerReplyForm__replyText")[0];
- var responses = ${JSON.stringify(responses)};
- var response = responses.find(x => x.content == message);
- response.replace ? messageBox.value = message : messageBox.value += message;
- console.log("Set message to: " + message);
- }
- `;
- function populate() {
- var select = document.getElementById("responseListbox");
- for(var i = 0; i < responses.length; i++) {
- select.options[select.options.length] = new Option(responses[i].name, responses[i].content);
- }
- }
- document.getElementsByClassName("ThreadViewer__replyContainer")[0].prepend(responseBox);
- var head = document.getElementsByTagName('head')[0];
- head.appendChild(headJS);
- populate();
- }
- function themeColors() {
- var darkTheme = document.getElementsByClassName("theme-dark").length ? true : false;
- if(darkTheme) {
- console.log("Dark mode detected!");
- textColor = darkModeTextColor;
- titleColor = darkModeTitleColor;
- listBoxColor = darkModeListColor;
- } else {
- console.log("Light mode detected!");
- textColor = lightModeTextColor;
- titleColor = lightModeTitleColor;
- listBoxColor = lightModeListColor;
- }
- }
- //When Modmail conversation has been opened, load the HTML elements with the correct data
- const elementToWatch = 'a[class="InfoBar__username"]';
- document.arrive(elementToWatch, function () {
- themeColors();
- addInfo();
- if(enableCustomResponses) addResponseBox();
- });
- if(document.getElementsByClassName("InfoBar__username")[0]) {
- themeColors();
- addInfo();
- if(enableCustomResponses) addResponseBox();
- }
- //Took advice for the listbox CSS from moderncss.dev/custom-select-styles-with-pure-css, thanks!
- var css = `
- .profileIcon:hover {
- -ms-transform: scale(6);
- -webkit-transform: scale(6);
- transform: scale(6);
- }
- .profileIcon {
- position: relative;
- bottom: 4px;
- margin-bottom: 10px;
- float: left; border-radius: 50%;
- transition: transform .2s;
- }
- .InfoBar__recentsNone {
- color: #6e6e6e;
- }
- .InfoBar__metadata, .InfoBar__recents {
- margin: 6px 0;
- margin-left: 10px;
- }
- .value {
- color: ${dataColor};
- }
- .InfoBar__banText {
- padding-bottom: 15px;
- }
- .InfoBar__username, .InfoBar__username:visited {
- padding-left: 10px;
- }
- .ThreadViewer__infobarContainer {
- display: table;
- }
- .ThreadViewer__threadContainer.m-has-infobar {
- right: 340px;
- }
- .dataText {
- color: ${textColor};
- font-size: 13px;
- padding-left: 10px;
- }
- .dataTitle {
- color: ${titleColor};
- font-size: 15px;
- margin-bottom: 3px;
- margin-top: 5px;
- }
- .responseListbox {
- width: 50%;
- }
- :root {
- --select-border: #0079d3;
- --select-focus: blue;
- --select-arrow: var(--select-border);
- }
- *,
- *::before,
- *::after {
- box-sizing: border-box;
- }
- select {
- appearance: none;
- background-color: ${listBoxColor};
- color: ${textColor};
- border: none;
- padding: 0 1em 0 0;
- margin: 0;
- width: 100%;
- font-family: inherit;
- font-size: inherit;
- cursor: inherit;
- line-height: inherit;
- outline: none;
- position: relative;
- }
- .select {
- width: 100%;
- min-width: 15ch;
- max-width: 30ch;
- border: 1px solid var(--select-border);
- border-radius: 0.25em;
- padding: 0.25em 0.5em;
- font-size: 0.9rem;
- cursor: pointer;
- line-height: 1.1;
- background-color: ${listBoxColor};
- }
- select::-ms-expand {
- display: none;
- }
- option {
- white-space: normal;
- outline-color: var(--select-focus);
- }
- select:focus + .focus {
- position: absolute;
- top: -1px;
- left: -1px;
- right: -1px;
- bottom: -1px;
- border: 2px solid var(--select-focus);
- border-radius: inherit;
- }
- `;
- //Apply the custom css
- var styleSheet = document.createElement("style");
- styleSheet.type = "text/css";
- styleSheet.innerText = css;
- document.head.appendChild(styleSheet);