Bitcoin Forum
November 09, 2024, 11:20:16 AM *
News: Latest Bitcoin Core release: 28.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1] 2 3 »  All
  Print  
Author Topic: [HACK] One-click mod report, not for the faint of heart  (Read 2052 times)
suchmoon (OP)
Legendary
*
Offline Offline

Activity: 3850
Merit: 9087


https://bpip.org


View Profile WWW
January 29, 2019, 12:09:55 AM
Last edit: February 27, 2022, 03:05:48 PM by suchmoon
Merited by Welsh (50), mprep (25), ABCbits (24), LoyceV (12), Vod (11), NeuroticFish (10), Mr. Big (10), o_e_l_e_o (10), malevolent (8), vapourminer (5), xandry (5), mikeywith (5), joniboini (5), DarkStar_ (4), ibminer (4), eaLiTy (3), actmyname (3), cabalism13 (3), sncc (3), Daniel91 (2), Halab (2), DireWolfM14 (2), logfiles (2), marlboroza (2), bones261 (2), eternalgloom (2), friends1980 (2), qwk (1), madnessteat (1), TheBeardedBaby (1), Jawhead999 (1), Charles-Tim (1), bitart (1), cissrawk (1), Blacknavy (1), Cryptotourist (1), vit05 (1)
 #1

This originated here: https://bitcointalk.org/index.php?topic=5103283.msg49470283#msg49470283

And I completely support the idea raised by that thread, i.e. make it easier to report certain types of posts. But until/unless that feature gets implemented perhaps you'll find my approach useful.

Edit 2022-02-27: this extension has been updated, see this post for more details: https://bitcointalk.org/index.php?topic=5103488.msg59370767#msg59370767

Caveats

1. This is a browser extension. Never install browser extensions obtained from random strangers on the internet unless you know exactly what you're doing. I'm not responsible if this extension steals all your money and runs away with your spouse.

2. This is mostly-untested code. It's alpha quality at best. I gutted it out of a larger extension that I'm using for other purposes. Treat it as an example or an idea. Feel free to steal any bits and pieces that you like or do whatever you want with it.

3. It works in Firefox/Tor browser and may work in Chrome. Probably won't work in mobile browsers.

4. You must have some knowledge of how WebExtensions and Promises work in order to make sense of the code. I'll try to explain below but a proper tutorial is out of the scope of this thread.

How this works

This is a browser extension built using WebExtensions API and consists of two main parts:

  • bct-content.js: content script, a copy of which runs on every Bitcointalk page once the extension is installed. Depending on which page it is, the content script will perform different actions:
    • Adds a link to the list of your submitted moderator reports to site's main menu: Loading.... Note that this list will work only after you've submitted 300 successful ("Good") reports.
    • If you open the report list, the extension collects the list of reported posts (see below how it's used).
    • Inside threads, on Patrol page, and in user's post/thread history it either marks posts that have been reported (please note this tracks only posts reported by you and not other users, and it only shows the status as of the last refresh of the report list), or creates one-click buttons to report posts to moderators. Clicking one of the buttons sends a message to the other part of the extension, which handles queuing etc.

                Loading...
                OR
                Loading...

    • On the "Report to moderator" page it expands the comment field for better visibility. If the page was opened automatically by one of the above buttons, it inserts the pre-selected comment, waits a specified amount of time to comply with throttling, and clicks "Submit".
    • In the board view it closes the tab if it came from the automated post report, otherwise it does nothing.
  • bct-background.js: background script, which listens to messages from content scripts and for each message opens the "Report to moderator" in a new tab, which is then handled by the content script as described above. This is done without taking focus away from what you're doing so you can keep browsing and reporting other posts.

The code that runs between when you click your button and when the extension clicks the "Submit" button is wrapped in a Promise so it should succeed or fail as a whole. Please note though that the actual submission of the report is not verified, i.e. if there is a failure after "Submit" was clicked - Bitcointalk down, CF fire hydrant, etc - you'll have to double-check your report history to see if the report was submitted successfully.

If the code succeeds it will add a yellow border on the left side of the post being reported, if it fails - a red one. Styling is configurable in bct-content.css. o_e_l_e_o created a custom stylesheet for a "blend in" look-and-feel.

In case of a failure check console log and please let me know if there is a bug that's causing it.

How to install

Get the files from github (clone the repo, or download as zip and unzip it). In Firefox/Tor go to "about:debugging", click Load Temporary Add-on, and choose any file in the folder. If you're brave enough to use Chrome - enable Developer Mode in extension settings and use "Load unpacked" to install the extension (thanks to HCP for the figuring it out).

The actual clicking of the "Submit" button is commented out - see this line in bct-content.js. I would like to avoid spamming our dear moderators with a bunch of malformed reports if anything goes wrong. If you decide to use the extension you can test it first by manually clicking "Submit" and then uncomment the line once you're comfortable.

REPORT_SUBMIT_DELAY sets the wait time before clicking "Submit". High activity accounts have a 4-seconds-betwen-posts allowance, so the default 4000ms delay works well with that. With a lower activity account you may run into throttling - adjust the delay as needed.

You can change button titles, report comments, add new buttons, in create_all_controls in bct-content.js.

Questions?

I'm sure I missed something or messed something up. Feel free to comment in the thread.

Files (current version)

Current version is available on GitHub. You can clone the repository, or if you don't want to use git you can just download the code as a zip file (you'll need to unzip it for installation). If you're upgrading from the original version and have customized it, you might want to create a branch off the first commit (which matches the original version), apply your custom code, and cherry-pick or merge from the main branch.

Old version

This version lacks latest features such as Chrome support and mod report parsing. I'm leaving the files embedded here as an archive, although the same version is also available on GitHub (see above).

manifest.json

Code:
{

  "manifest_version": 2,
  "name": "BCT Helper",
  "version": "0.1b",

  "description": "Adds some automation for bitcointalk.org.",

  "content_scripts": [
    {
      "matches": [ "*://bitcointalk.org/*" ],
      "js": [ "bct-content.js" ],
      "css": [ "bct-content.css" ],
      "run_at": "document_idle"
    }
  ],

  "background":
  {
    "scripts": ["bct-background.js"]
  },
  
  "permissions": [
    "tabs"
  ]
}

bct-content.css

Code:
div.post {
    border-left: 4px transparent solid;
}

div.post.post-wait {
    opacity: 0.5;
}

div.post.post-error {
    border-left: 4px red solid;
}

div.post.post-success {
    border-left: 4px yellow solid;
}

.bct-report-button-container {
    margin-top: 10px;
    background-color: #bbddbb;
}

.bct-report-input {
    margin-left: 5px;
    height: 12px;
}

.bct-report-button, .bct-report-button:hover {
    display: inline-block;
    border: 1px solid black;
    margin-left: 5px;
    padding: 1px 5px 1px 5px;
    transform: none;
}

.bct-report-button:hover {
    cursor: pointer;
}

bct-content.js

Code:
console.log("BCT-CONTENT initialized");
console.log("Page: " + window.location.href);
console.log("Referrer: " + document.referrer);

function process_background_message(message, sender, send_response) {
    browser.runtime.onMessage.removeListener(process_background_message);
    console.log("Content script received background message: " + JSON.stringify(message));
    if (message.action == "bct-tab-open-report" || message.action == "bct-tab-submit-report") {
        if (message.comment !== undefined) {
            document.getElementsByName("comment")[0].value = message.comment;
        }
        document.getElementsByName("comment")[0].focus();
        message.result = "OK";
    }
    if (message.action == "bct-tab-submit-report") {
        // mod report counts as post/PM for throttling - add a delay
        setTimeout(() => {
            send_response(message);
            // Uncomment the next line to allow reports to be submitted automatically
            //document.querySelector("input[type=submit][value=Submit]").click();
        }, 5000);
    } else {
        send_response(message);
    }
    // this is needed to make the sender wait for a response
    return true;
}

function report_post(post_container, thread_id, post_id, report_comment, auto_submit) {
    post_container.classList.add("post-wait");

    let event_detail = {
        event_id: (Math.random().toString(36) + '000000000000000000').slice(2, 18),
        action_name: "bct-report",
        action_url: "https://bitcointalk.org/index.php?action=reporttm;topic=" + thread_id + ";msg=" + post_id,
        action_payload: { post_id: post_id, comment: report_comment, auto: auto_submit }
    };

    browser.runtime.sendMessage(event_detail)
        .then((message_response) => {
            //console.log("message_response: " + JSON.stringify(message_response));
            console.log("message_response size: " + JSON.stringify(message_response).length);
            post_container.classList.remove("post-wait", "post-error", "post-success");
            post_container.classList.add("post-success");
        })
        .catch((error) => {
            console.log("Data request failed:");
            console.log(error);
            post_container.classList.remove("post-wait", "post-error", "post-success");
            post_container.classList.add("post-error");
        })
    ;
    
}

function extract_ids_from_url(post_url) {
    let url_parts = post_url.split("#msg");
    let post_id = url_parts[1];
    let thread_id = url_parts[0].split(".msg")[0].split("?topic=")[1];
    return [thread_id, post_id];
}

function create_button(post_container, button_title, report_comment, text_field, auto_submit) {
    let button = document.createElement("button");
    button.className = "bct-report-button";
    button.innerText = button_title;
    button.title = report_comment;
    button.addEventListener("click", (e) => {
        e.preventDefault();
        if (text_field) {
            if (text_field.value.trim()) {
                report_comment += " " + text_field.value.trim();
            } else {
                alert("Required value missing");
                return;
            }
        }
        report_post(post_container, post_container.thread_id, post_container.post_id, report_comment, auto_submit);
    });
    return button;
}

function create_span(text) {
    let span = document.createElement("span");
    span.innerText = text;
    return span;
}

function create_text_field(hint) {
    let text_field = document.createElement("input");
    text_field.className = "bct-report-input";
    text_field.type = "text";
    text_field.placeholder = hint;
    return text_field;
}

// inject the buttons into each message
document.querySelectorAll("div.post").forEach(post_container => {
    // Try to determine thread ID and post ID
    let link_object = null;
    if (post_container.parentNode.classList.contains("td_headerandpost")) {
        // Thread view
        // post -> td.td_headerandpost -> table ... -> div#subject_123456
        link_object = post_container.parentNode.firstElementChild.querySelector("div[id^='subject_'] a");
    } else {
        // Other views: patrol, user's post history, user's thread history
        let post_url_start = "https://bitcointalk.org/index.php?topic=";
        // post -> td -> tr -> tbody -> tr ... -> a[href contains #msg123456]
        link_object = post_container.parentNode.parentNode.parentNode.firstElementChild.querySelector("a[href^='" + post_url_start + "'][href*='#msg']");
    }
    if (link_object) {
        [post_container.thread_id, post_container.post_id] = extract_ids_from_url(link_object.getAttribute("href"));
        if (post_container.thread_id && post_container.post_id) {
            let button_container = document.createElement("div");
            button_container.className = "bct-report-button-container";
            post_container.appendChild(button_container);
            button_container.appendChild(create_span("Report as: "));
            button_container.appendChild(create_button(post_container, "zero value", "zero-value shitpost", null, true));
            button_container.appendChild(create_button(post_container, "multi post", "two or more consecutive posts in 24h", null, true));
            button_container.appendChild(create_button(post_container, "cross spam", "spamming their service across multiple threads - please check post history", null, true));
            button_container.appendChild(create_button(post_container, "non-english", "non-English post on English board", null, true));
            let url_field = create_text_field("URL of the original");
            button_container.appendChild(create_button(post_container, "copy from:", "copy-paste from:", url_field, true));
            button_container.appendChild(url_field);
            let board_field = create_text_field("correct board name");
            button_container.appendChild(create_button(post_container, "move to:", "wrong board, should be in", board_field, true));
            button_container.appendChild(board_field);
        } else {
            console.log("Found div.post and post URL but couldn't determine thread/post ID.");
        }
    } else {
        console.log("Found div.post but couldn't find post URL.");        
    }
});

if (window.location.href.startsWith("https://bitcointalk.org/index.php?action=reporttm")) {
    document.getElementsByName("comment")[0].style.width = "80%";
    browser.runtime.onMessage.addListener(process_background_message);
}
if (window.location.href.startsWith("https://bitcointalk.org/index.php?board=")) {
    if (document.referrer &&
        document.referrer.startsWith("https://bitcointalk.org/index.php?action=reporttm") &&
        document.referrer.endsWith(";a") // after automatic submission
    ) {
        console.log("Attempting to close this tab...");
        browser.runtime.sendMessage({ action_name: "close-this-tab" });
    }
}

bct-background.js

Code:
// This is an array of Promise.resolve functions that will be called sequentially with delay
let throttled_resolvers = [];
// Number of milliseconds to wait before resolving the next queued promise
let PROMISE_INTERVAL = 1300;
// Number of milliseconds to wait before rejecting the queued promise
let PROMISE_TIMEOUT = 120000;
// Number of milliseconds to wait for a tab to load
let TAB_TIMEOUT = 60000;

function handle_next_resolver() {
    let p = throttled_resolvers.shift();
    if (p === undefined) {
        setTimeout(handle_next_resolver, PROMISE_INTERVAL);
    }
    else {
        p.resolve();
    }
}

setTimeout(handle_next_resolver, PROMISE_INTERVAL);

function queue_promise() {
    return new Promise((resolve, reject) => {
        throttled_resolvers.push({ resolve: resolve });
        setTimeout(function () { reject(new Error("Queued promise has timed out.")); }, PROMISE_TIMEOUT);
    });
}

function check_if_tab_fully_loaded(tab) {

    function is_tab_complete(tab) {
        return tab.status === "complete" && tab.url !== "about:blank";
    }

    if (is_tab_complete(tab)) {
        return tab;
    } else {
        return new Promise((resolve, reject) => {

            const timer = setTimeout(
                function () {
                    browser.tabs.onUpdated.removeListener(on_updated);
                    if (is_tab_complete(tab)) {
                        resolve(tab);
                    } else {
                        reject(new Error("Tab status " + tab.status + ": " + tab.url));
                    }
                },
                TAB_TIMEOUT
            );
            
            function on_updated(tab_id, change_info, updated_tab) {
                if (tab_id == tab.id && is_tab_complete(updated_tab)) {
                    clearTimeout(timer);
                    browser.tabs.onUpdated.removeListener(on_updated);
                    resolve(updated_tab);
                }
            }

            browser.tabs.onUpdated.addListener(on_updated);

        });
    }
}

browser.runtime.onMessage.addListener(function(message, sender) {
    if (message.action_name === "close-this-tab") {
        //console.log("Background script closing tab:");
        //console.log(sender.tab);
        browser.tabs.remove(sender.tab.id);
    }
    else if (message.action_name === "bct-report") {
        /*
        Expected message format:
        {
            action_name: "bct-auto-report",
            action_url: "https://...",
            action_payload: { post_id: N, comment: "...", auto: true }
        }
        */
        let tab_url = message.action_url;
        let tab_action = "bct-tab-open-report";
        if (message.action_payload.auto) {
            tab_action = "bct-tab-submit-report";
            tab_url += ";a";
        }
        console.log(message);
        return queue_promise()
            .then(() =>
                browser.tabs.create({
                    url: tab_url,
                    windowId: sender.tab.windowId,
                    active: false
                })
            )
            .then((created_tab) => check_if_tab_fully_loaded(created_tab))
            .catch((error) => {
                error_message = "Tab load/check failed: " + error.message;
                console.log(error_message);
                throw new Error(error_message);
            })
            .then((loaded_tab) => browser.tabs.sendMessage(loaded_tab.id, { id: loaded_tab.id, action: tab_action, comment: message.action_payload.comment }))
            .then((tab_response) => {
                //console.log("Tab result: " + tab_response.result);
                message.action_result = tab_response.result;
                return message;
            })
            .catch((error) => {
                console.log("Request failed in the background:");
                console.log(error);
                throw new Error(error.message);
            })
            .finally(() => {
                setTimeout(handle_next_resolver, PROMISE_INTERVAL);
            })
        ;
    }
});
o_e_l_e_o
In memoriam
Legendary
*
Offline Offline

Activity: 2268
Merit: 18746


View Profile
January 29, 2019, 12:49:27 AM
 #2

Love this, and if I had 50 sMerits to give you I would. Reviewed the code, installed, works perfectly. Much better solution than the quick one I came up with given the queuing function.

Don't like your color scheme or position of the buttons, but that's easily fixed. Thank so much for taking the time to extract and share. I'll play around with it for a few days and let you know if I stumble across any issues.
suchmoon (OP)
Legendary
*
Offline Offline

Activity: 3850
Merit: 9087


https://bpip.org


View Profile WWW
January 29, 2019, 12:58:02 AM
 #3

Love this, and if I had 50 sMerits to give you I would. Reviewed the code, installed, works perfectly. Much better solution than the quick one I came up with given the queuing function.

Don't like your color scheme or position of the buttons, but that's easily fixed. Thank so much for taking the time to extract and share. I'll play around with it for a few days and let you know if I stumble across any issues.

You can change the colors in the CSS file obviously. I put the buttons on the bottom left so that there is no chance to accidentally confuse them with any other buttons like Edit or Report to moderator but you can inject them anywhere you like.

Edit: I should mention that queuing has certain limitations. "let PROMISE_TIMEOUT = 120000;" near the top of bct-background.js basically limits the time to wait for the report to be submitted to ~2 minutes. At 5 seconds between reports plus loading time it allows up to ~15 reports to be queued.
o_e_l_e_o
In memoriam
Legendary
*
Offline Offline

Activity: 2268
Merit: 18746


View Profile
January 29, 2019, 01:28:59 AM
Last edit: January 29, 2019, 01:41:16 AM by o_e_l_e_o
 #4

One small error I've found.

In bct-content.js, on line 63:
Code:
button.className = "post-report-button";

But your CSS file uses:
Code:
.bct-report-button

I've turned the buttons red and aligned them to the right, nestled nicely above "Report to moderator". Thanks again!

Edit: Actually, I didn't like the red either, so I've opted for a more familiar color scheme:

suchmoon (OP)
Legendary
*
Offline Offline

Activity: 3850
Merit: 9087


https://bpip.org


View Profile WWW
January 29, 2019, 01:47:47 AM
 #5

One small error I've found.

In bct-content.js, on line 63:
Code:
button.className = "post-report-button";

But your CSS file uses:
Code:
.bct-report-button

I've turned the buttons red and aligned them to the right, nestled nicely above "Report to moderator". Thanks again!

Edit: Actually, I didn't like the red either, so I've opted for a more familiar color scheme:



Thanks, I updated the class name in the OP.
o_e_l_e_o
In memoriam
Legendary
*
Offline Offline

Activity: 2268
Merit: 18746


View Profile
January 29, 2019, 02:01:53 AM
 #6

On looking at your code further, I see the new tabs are supposed to close after auto-submitting. On mine they don't, and my rusty JavaScript knowledge isn't allowing me to figure out why.
suchmoon (OP)
Legendary
*
Offline Offline

Activity: 3850
Merit: 9087


https://bpip.org


View Profile WWW
January 29, 2019, 02:07:26 AM
Last edit: January 29, 2019, 02:21:49 AM by suchmoon
 #7

On looking at your code further, I see the new tabs are supposed to close after auto-submitting. On mine they don't, and my rusty JavaScript knowledge isn't allowing me to figure out why.

Which browser are you using? Does the tab close if you click the "Submit" manually? Does the report page URL have ";a" at the end? Basically what it does after submission is this: if the referrer had ";a" in the URL - close the tab.

bct-content.js line 112 sends the message back to the background script to close the tab. This will happen after the page (the list of threads you're redirected to) is fully loaded.
bct-background.js line 70 receives the message and closes the tab.

I'll debug it on my end once I find some worthy shitposts to report Smiley
o_e_l_e_o
In memoriam
Legendary
*
Offline Offline

Activity: 2268
Merit: 18746


View Profile
January 29, 2019, 02:10:22 AM
 #8

Firefox, no, yes. I had figured out as much - the URLs on my browser are correct, but the tabs don't close.
suchmoon (OP)
Legendary
*
Offline Offline

Activity: 3850
Merit: 9087


https://bpip.org


View Profile WWW
January 29, 2019, 02:17:42 AM
Merited by o_e_l_e_o (2)
 #9

Firefox, no, yes. I had figured out as much - the URLs on my browser are correct, but the tabs don't close.

Weird. I just checked with Tor Browser, which is basically a Firefox clone, and it closed correctly. Can you add some extra logging at the top of bct-content.js:

Code:
console.log("Page: " + window.location.href);
console.log("Referrer: " + document.referrer);

Then reload the extension and check if it shows the referrer correctly, particularly after the submission. Ctrl+Shift+I, then Console to see the log.
o_e_l_e_o
In memoriam
Legendary
*
Offline Offline

Activity: 2268
Merit: 18746


View Profile
January 29, 2019, 02:23:52 AM
 #10

Code:
BCT-CONTENT initialized
Page: https://bitcointalk.org/index.php?board=1.0
Referrer: https://bitcointalk.org/

This was after a report was made automatically, and it had reloaded to Bitcoin Discussion front page. So yeah, it seems to not be picking up the referrer correctly.

Edit: Wait wait wait, I think I know the issue, and it's got nothing to do with your code. Gimme 5.

Edit 2: Yeah, got it. So as part of my Firefox set up, in about:config I have network.http.referer.trimmingPolicy set to 2, which means it only sends the origin rather than full URL. Changing it back to 0 solves the problem.
suchmoon (OP)
Legendary
*
Offline Offline

Activity: 3850
Merit: 9087


https://bpip.org


View Profile WWW
January 29, 2019, 02:37:25 AM
 #11

Code:
BCT-CONTENT initialized
Page: https://bitcointalk.org/index.php?board=1.0
Referrer: https://bitcointalk.org/

This was after a report was made automatically, and it had reloaded to Bitcoin Discussion front page. So yeah, it seems to not be picking up the referrer correctly.

Edit: Wait wait wait, I think I know the issue, and it's got nothing to do with your code. Gimme 5.

Edit 2: Yeah, got it. So as part of my Firefox set up, in about:config I have network.http.referer.trimmingPolicy set to 2, which means it only sends the origin rather than full URL. Changing it back to 0 solves the problem.

Whew. I tried it in Firefox 64 and it worked. Was gonna yell at you that you must have some weird privacy settings Smiley

Although relying on referrer is a bit wonky. I should probably find a better way.
eternalgloom
Legendary
*
Offline Offline

Activity: 1792
Merit: 1283



View Profile WWW
January 29, 2019, 11:02:46 AM
 #12

Works great! Not too hard to set up, just followed the instructions.

On a side-note, finally something that's being released for Firefox first.
Lately I'd been seriously considering moving to Chrome, just because custom 'extensions' like these seem to be developed for Chrome first and then get ported to FF as an afterthought.

Just reported my first post using this tool:


actmyname
Copper Member
Legendary
*
Offline Offline

Activity: 2562
Merit: 2510


Spear the bees


View Profile WWW
January 29, 2019, 11:10:37 AM
 #13

Brilliant. This is exactly the kind of tool that we need to address the SpamHorde™.

(now if only there were a way to reduce the wait time once you've made X good reports)

suchmoon (OP)
Legendary
*
Offline Offline

Activity: 3850
Merit: 9087


https://bpip.org


View Profile WWW
January 29, 2019, 01:26:15 PM
 #14

Works great! Not too hard to set up, just followed the instructions.

On a side-note, finally something that's being released for Firefox first.
Lately I'd been seriously considering moving to Chrome, just because custom 'extensions' like these seem to be developed for Chrome first and then get ported to FF as an afterthought.

Just reported my first post using this tool:



I'm using Tor Browser, which is essentially Firefox, so I built it for Firefox. However the WebExtensions API is supposed to be portable so it might work in Chrome as well.



Everyone trying this out - please make sure to personalize the buttons and set up the comments you want to submit. You can create as many buttons as you want, as well as other stuff like drop downs or text fields. I'll try to come up with an example of a text field for a URL (e.g. when reporting plagiarism).
eternalgloom
Legendary
*
Offline Offline

Activity: 1792
Merit: 1283



View Profile WWW
January 29, 2019, 01:36:49 PM
Merited by o_e_l_e_o (2)
 #15

Everyone trying this out - please make sure to personalize the buttons and set up the comments you want to submit. You can create as many buttons as you want, as well as other stuff like drop downs or text fields. I'll try to come up with an example of a text field for a URL (e.g. when reporting plagiarism).

Yeah, I've added a couple of buttons for myself. Changed in the bct-content.js file.
I'm not a programmer and figured it out pretty quickly. Other examples are definitely welcome though!

Code:
if (link_object) {
        let [thread_id, post_id] = ExtractIdsFromUrl(link_object.getAttribute("href"));
        if (thread_id && post_id) {
            let button_container = document.createElement("div");
            button_container.className = "bct-report-button-container";
            post_container.appendChild(button_container);
            button_container.appendChild(CreateButton("zero value", post_container, thread_id, post_id, "zero-value shitpost", true));
            button_container.appendChild(CreateButton("cross spam", post_container, thread_id, post_id, "spamming their service across multiple threads - please check post history", true));
            button_container.appendChild(CreateButton("non-english", post_container, thread_id, post_id, "non-english post", true));
            button_container.appendChild(CreateButton("price speculation", post_container, thread_id, post_id, "Wrong board, should be in Speculation", true));
        }

suchmoon (OP)
Legendary
*
Offline Offline

Activity: 3850
Merit: 9087


https://bpip.org


View Profile WWW
January 29, 2019, 01:53:28 PM
Last edit: November 30, 2020, 12:55:39 AM by suchmoon
Merited by eternalgloom (1)
 #16

Yeah, I've added a couple of buttons for myself. Changed in the bct-content.js file.
I'm not a programmer and figured it out pretty quickly. Other examples are definitely welcome though!

Awesome. Another one I use often is "multi posting" AKA "two or more consecutive posts in 24h". I'll post a small update later today with some other stuff than may come in useful.



I updated bct-content.js and bct-content.css with some small tweaks. CreateButton function has changed so if you had any customizations these will need to be slightly updated like this:

Code:
            button_container.appendChild(create_button(post_container, "button name", "comment to submit", null or text box - see below, true));

I added mouse-over on buttons to show the comment text that will be submitted, and added an option to pass a text field which allows to do something like this:

Loading...
Edited 2020-11-30 to fix a broken image

So in this example if you click the "copy from:" button the actual comment that gets submitted would be "copy-paste from: http://some.url/link", i.e. concatenates predefined text with what you enter in the box.
madnessteat
Legendary
*
Offline Offline

Activity: 2422
Merit: 2271



View Profile
January 29, 2019, 07:21:21 PM
 #17

~snip~

It's super suchmoon!


For a long time I did not understand why I do not have an extended interface window. My mistake was in one lost character from the code field. I added your hack to Russian locale

███████████████████████████
███████▄████████████▄██████
████████▄████████▄████████
███▀█████▀▄███▄▀█████▀███
█████▀█▀▄██▀▀▀██▄▀█▀█████
███████▄███████████▄███████
███████████████████████████
███████▀███████████▀███████
████▄██▄▀██▄▄▄██▀▄██▄████
████▄████▄▀███▀▄████▄████
██▄███▀▀█▀██████▀█▀███▄███
██▀█▀████████████████▀█▀███
███████████████████████████
 
 Duelbits 
██
██
██
██
██
██
██
██

██

██

██

██

██
TRY OUR UNIQUE GAMES!
    ◥ DICE  ◥ MINES  ◥ PLINKO  ◥ DUEL POKER  ◥ DICE DUELS   
█▀▀











█▄▄
 
███
▀▀▀
███
▀▀▀
███
▀▀▀
███
▀▀▀

███
▀▀▀
███
▀▀▀
 
███
▀▀▀

███
▀▀▀
███
▀▀▀
███
▀▀▀
███
▀▀▀
███
▀▀▀
 
███
▀▀▀
███
▀▀▀
███
▀▀▀
███
▀▀▀

███
▀▀▀
███
▀▀▀
 
███
▀▀▀
███
▀▀▀
███
▀▀▀

███
▀▀▀
███
▀▀▀
███
▀▀▀
 
███
▀▀▀
███
▀▀▀

███
▀▀▀
███
▀▀▀
███
▀▀▀

███
▀▀▀
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
 KENONEW 
 
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
▀▀█











▄▄█
10,000x
 
MULTIPLIER
██
██
██
██
██
██
██
██

██

██

██

██

██
 
NEARLY
UP TO
50%
REWARDS
██
██
██
██
██
██
██
██

██

██

██

██

██
[/tabl
bitart
Hero Member
*****
Offline Offline

Activity: 1442
Merit: 629


Vires in Numeris


View Profile
January 29, 2019, 07:58:28 PM
 #18

Nice code, thanks Smiley
Is it possible to ask theymos to just implement it into the code?
And only activate it for those who e.g. has at least 1,000 good reports?
It would be awesome Smiley
suchmoon (OP)
Legendary
*
Offline Offline

Activity: 3850
Merit: 9087


https://bpip.org


View Profile WWW
January 29, 2019, 08:11:23 PM
 #19

Nice code, thanks Smiley
Is it possible to ask theymos to just implement it into the code?
And only activate it for those who e.g. has at least 1,000 good reports?
It would be awesome Smiley

There is a petition for a similar feature: https://bitcointalk.org/index.php?topic=5103283

Perhaps if we pester theymos long enough he'll give in.
mikeywith
Legendary
*
Offline Offline

Activity: 2408
Merit: 6618


be constructive or S.T.F.U


View Profile
January 30, 2019, 02:26:14 AM
 #20

 wish it was posted a long time ago, but better late than never, will try it and let you know if i find any issues. thanks Grin

█▀▀▀











█▄▄▄
▀▀▀▀▀▀▀▀▀▀▀
e
▄▄▄▄▄▄▄▄▄▄▄
█████████████
████████████▄███
██▐███████▄█████▀
█████████▄████▀
███▐████▄███▀
████▐██████▀
█████▀█████
███████████▄
████████████▄
██▄█████▀█████▄
▄█████████▀█████▀
███████████▀██▀
████▀█████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
c.h.
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
▀▀▀█











▄▄▄█
▄██████▄▄▄
█████████████▄▄
███████████████
███████████████
███████████████
███████████████
███░░█████████
███▌▐█████████
█████████████
███████████▀
██████████▀
████████▀
▀██▀▀
Pages: [1] 2 3 »  All
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!