Skip to content

Instantly share code, notes, and snippets.

@marktaiwan
Last active August 19, 2021 06:22
Show Gist options
  • Save marktaiwan/f52f4fabb73416779f28902630ac5196 to your computer and use it in GitHub Desktop.
Save marktaiwan/f52f4fabb73416779f28902630ac5196 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name Manual (You)
// @description Add arbitary posts to reply tracking
// @author Marker
// @namespace https://gist.github.com/marktaiwan
// @version 1.2
// @match https://boards.4chan.org/*
// @match https://boards.4channel.org/*
// @grant none
// @noframes
// @require https://raw.githubusercontent.com/soufianesakhi/node-creation-observer-js/master/release/node-creation-observer-latest.js
// @icon https://s.4cdn.org/image/favicon-ws.ico
// ==/UserScript==
/* global Main, Parser, NodeCreationObserver */
(function () {
'use strict';
const $ = (selector, parent = document) => parent.querySelector(selector);
const $$ = (selector, parent = document) => parent.querySelectorAll(selector);
const ADD_STRING = ' [Start tracking]';
const REM_STRING = ' [<b>Tracked</b>]';
function processPost(postEle) {
Parser.trackedReplies = Parser.getTrackedReplies(Main.board, Main.tid) ?? {};
const postId = $('.postInfo input[type="checkbox"]', postEle).name;
const postNum = $('.postInfo .postNum', postEle);
const isOwnPost = Object.keys(Parser.trackedReplies).some(key => key == '>>' + postId);
const button = document.createElement('a');
button.style.cursor = 'pointer';
button.innerHTML = isOwnPost ? REM_STRING : ADD_STRING;
button.dataset.ownPost = isOwnPost ? '1' : '0';
button.addEventListener('click', handleClick);
postNum.after(button);
}
function handleClick(e) {
const button = e.currentTarget;
const postEle = button.closest('.postContainer');
const threadId = Main.tid;
const postId = $('.postInfo input[type="checkbox"]', postEle).name;
if (button.dataset.ownPost == '1') {
delete Parser.trackedReplies['>>' + postId];
Parser.saveTrackedReplies(threadId, Parser.trackedReplies);
button.innerHTML = ADD_STRING;
button.dataset.ownPost = '0';
// Update replied posts by following the backlinks
const backlinks = $$('.backlink .quotelink', postEle);
for (const backlink of backlinks) {
const replyId = backlink.innerText.slice(2);
const replyEle = $('#pc' + replyId);
const trackedLinks = $$('.postMessage a.ql-tracked', replyEle);
for (const link of trackedLinks) {
if (link.innerText.endsWith(postId + ' (You)')) {
link.classList.remove('ql-tracked');
link.innerText = '>>' + postId;
}
}
}
} else {
Parser.trackedReplies['>>' + postId] = '1';
Parser.saveTrackedReplies(threadId, Parser.trackedReplies);
button.innerHTML = REM_STRING;
button.dataset.ownPost = '1';
// Update replied posts by following the backlinks
const backlinks = $$('.backlink .quotelink', postEle);
for (const backlink of backlinks) {
const replyId = backlink.innerText.slice(2);
const replyEle = $('#pc' + replyId);
parseTrackedReplies(replyEle);
}
}
}
function parseTrackedReplies(postEle) {
for (const link of $$('.quotelink', postEle)) {
if (!Parser.trackedReplies[link.textContent] || link.closest('.backlink')) continue;
link.classList.add('ql-tracked');
link.textContent += ' (You)';
Parser.hasYouMarkers = true;
}
}
NodeCreationObserver.init('post-tracker-observer');
if (Main.tid) NodeCreationObserver.onCreation('.postContainer', processPost);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment