Add support for /nap/.

dotnetflags
C-xC-c 5 years ago
parent f3bc243690
commit e543e31617

@ -35,12 +35,10 @@ namespace BantFlags.Controllers
if (ver > 1) if (ver > 1)
{ {
// Improved data structuring, see Docs/GetPosts // Improved data structuring, see Docs/GetPosts
return Json(await Database.GetPosts_V2(post_nrs)); return Json(await Database.GetPosts_V2(post_nrs, board));
}
else
{
return Json(await Database.GetPosts_V1(post_nrs));
} }
return Json(await Database.GetPosts_V1(post_nrs, board));
} }
/// <summary> /// <summary>

@ -26,7 +26,7 @@ namespace BantFlags.Data.Database
public async Task UpdateKnownFlags() public async Task UpdateKnownFlags()
{ {
var flags = await GetFlags(); var flags = await GetFlags();
flags.Remove("empty, or there were errors. Re-set your flags."); flags.Remove("empty, or there were errors. Re-set your flags."); // So users can't select this.
FlagList = string.Join("\n", flags); FlagList = string.Join("\n", flags);
KnownFlags = flags.ToHashSet(); KnownFlags = flags.ToHashSet();

@ -8,29 +8,30 @@ namespace BantFlags.Data.Database
public partial class DatabaseService public partial class DatabaseService
{ {
// Maybe this could be better but I don't know SQL lol // Maybe this could be better but I don't know SQL lol
private readonly string GetPostsQuery = @"SELECT posts.post_nr, flags.flag FROM flags LEFT JOIN (postflags) ON (postflags.flag = flags.id) LEFT JOIN (posts) ON (postflags.post_nr = posts.id) WHERE FIND_IN_SET(posts.post_nr, (@posts))"; private readonly string GetPostsQuery = @"SELECT posts.post_nr, flags.flag FROM flags LEFT JOIN (postflags) ON (postflags.flag = flags.id) LEFT JOIN (posts) ON (postflags.post_nr = posts.id) WHERE FIND_IN_SET(posts.post_nr, (@posts)) AND posts.board = @board";
/// <summary> /// <summary>
/// Returns the post numbers and their flags from the post numbers in the input. /// Returns the post numbers and their flags from the post numbers in the input.
/// </summary> /// </summary>
/// <param name="input">List of post numbers on the page.</param> /// <param name="post_nr">List of post numbers on the page.</param>
public async Task<IEnumerable<IGrouping<int, DataRow>>> GetPosts(string input) public async Task<IEnumerable<IGrouping<int, DataRow>>> GetPosts(string post_nr, string board)
{ {
using var rentedConnection = await ConnectionPool.RentConnectionAsync(); using var rentedConnection = await ConnectionPool.RentConnectionAsync();
DataTable table = await rentedConnection.Object.CreateQuery(GetPostsQuery) DataTable table = await rentedConnection.Object.CreateQuery(GetPostsQuery)
.SetParam("@posts", input) .SetParam("@posts", post_nr)
.SetParam("@board", board)
.ExecuteTableAsync(); .ExecuteTableAsync();
return table.AsEnumerable() return table.AsEnumerable()
.GroupBy(x => x.GetValue<int>("post_nr")); .GroupBy(x => x.GetValue<int>("post_nr"));
} }
public async Task<List<Dictionary<string, string>>> GetPosts_V1(string input) public async Task<List<Dictionary<string, string>>> GetPosts_V1(string post_nr, string board)
{ {
List<Dictionary<string, string>> posts = new List<Dictionary<string, string>>(); List<Dictionary<string, string>> posts = new List<Dictionary<string, string>>();
var x = await GetPosts(input); var x = await GetPosts(post_nr, board);
x.ForEach(x => posts.Add(new Dictionary<string, string> x.ForEach(x => posts.Add(new Dictionary<string, string>
{ {
{"post_nr", x.Key.ToString() }, {"post_nr", x.Key.ToString() },
@ -40,9 +41,9 @@ namespace BantFlags.Data.Database
return posts; return posts;
} }
public async Task<Dictionary<int, IEnumerable<string>>> GetPosts_V2(string input) public async Task<Dictionary<int, IEnumerable<string>>> GetPosts_V2(string post_nr, string board)
{ {
var posts = await GetPosts(input); var posts = await GetPosts(post_nr, board);
return posts return posts
.ToDictionary( .ToDictionary(
x => x.Key, x => x.Key,

@ -21,12 +21,13 @@ namespace BantFlags.Data
public static Result<PostModel> Create(string post_nr, string board, string regions, string splitFlag, HashSet<string> knownFlags) public static Result<PostModel> Create(string post_nr, string board, string regions, string splitFlag, HashSet<string> knownFlags)
{ {
string[] empty = new string[] { "empty, or there were errors. Re-set your flags." }; string[] empty = { "empty, or there were errors. Re-set your flags." };
string[] boards = { "bant", "nap", "srsbsn" }; // TODO: Move this to appsettings and make a singleton for it.
if (!int.TryParse(post_nr, out int postNumber)) if (!int.TryParse(post_nr, out int postNumber))
return Result<PostModel>.Fail("Invalid post number."); return Result<PostModel>.Fail("Invalid post number.");
if (board != "bant") if (!boards.Contains(board))
return Result<PostModel>.Fail("Invalid board parameter."); return Result<PostModel>.Fail("Invalid board parameter.");
if (regions == null) if (regions == null)

@ -46,6 +46,7 @@ namespace BantFlags.Data
public Method FlagMethod { get; set; } public Method FlagMethod { get; set; }
// This is bad but we need it so Flags can be generated by the input tag helper
public Flag() public Flag()
{ {
} }
@ -78,7 +79,7 @@ namespace BantFlags.Data
public static async Task<Result<Flag>> CreateFromFile(IFormFile upload, HashSet<string> names) public static async Task<Result<Flag>> CreateFromFile(IFormFile upload, HashSet<string> names)
{ {
byte[] PNGHeader = new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }; byte[] PNGHeader = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };
if (upload.ContentType.ToLower() != "image/png") if (upload.ContentType.ToLower() != "image/png")
return Result<Flag>.Fail("Image must be a png."); return Result<Flag>.Fail("Image must be a png.");
@ -116,6 +117,11 @@ namespace BantFlags.Data
return Result<Flag>.Pass(new Flag(name, Method.Add)); return Result<Flag>.Pass(new Flag(name, Method.Add));
} }
/// <summary>
/// Filters file names created by users.
/// </summary>
/// <param name="name">The file name to validate.</param>
/// <param name="names">The list of current file names.</param>
private static Result<string> ValidateFileName(string name, HashSet<string> names) private static Result<string> ValidateFileName(string name, HashSet<string> names)
{ {
if (string.IsNullOrWhiteSpace(name)) if (string.IsNullOrWhiteSpace(name))

@ -165,10 +165,12 @@ namespace BantFlags
case Method.Delete: case Method.Delete:
await Database.DeleteFlagAsync(flag); await Database.DeleteFlagAsync(flag);
if (System.IO.File.Exists(WebRoot + "/flags/dead/" + flagname)) if (System.IO.File.Exists(WebRoot + "/flags/dead/" + flagname))
{ {
System.IO.File.Delete(WebRoot + "/flags/dead/" + flagname); System.IO.File.Delete(WebRoot + "/flags/dead/" + flagname); // TODO: This is not the right way to handle it.
} }
Directory.Move(WebRoot + "/flags/" + flagname, WebRoot + "/flags/dead/" + flagname); Directory.Move(WebRoot + "/flags/" + flagname, WebRoot + "/flags/dead/" + flagname);
break; break;

@ -6,6 +6,7 @@
// @include http*://archive.nyafuu.org/bant/* // @include http*://archive.nyafuu.org/bant/*
// @include http*://archived.moe/bant/* // @include http*://archived.moe/bant/*
// @include http*://thebarchive.com/bant/* // @include http*://thebarchive.com/bant/*
// @include http*://nineball.party/*
// @exclude http*://boards.4chan.org/bant/catalog // @exclude http*://boards.4chan.org/bant/catalog
// @exclude http*://archive.nyafuu.org/bant/statistics/ // @exclude http*://archive.nyafuu.org/bant/statistics/
// @exclude http*://archived.moe/bant/statistics/ // @exclude http*://archived.moe/bant/statistics/
@ -29,10 +30,7 @@ const debugMode = false;
// DO NOT EDIT ANYTHING IN THIS SCRIPT DIRECTLY - YOUR FLAGS SHOULD BE CONFIGURED USING THE CONFIGURATION BOXES // DO NOT EDIT ANYTHING IN THIS SCRIPT DIRECTLY - YOUR FLAGS SHOULD BE CONFIGURED USING THE CONFIGURATION BOXES
// //
const postRemoveCounter = 60; const postRemoveCounter = 60;
const requestRetryInterval = 5000; // TODO: maybe a max retries counter? const requestRetryInterval = 5000; // TODO: maybe a max retries counter as well?
const regionDivider = "||"; //TODO: We can probably remove this and seperate by ,
const is_archive = window.location.host !== "boards.4chan.org";
const boardID = "bant"; //TODO: Hardcode /bant/ or accept other boards.
const version = 2; // Breaking changes. const version = 2; // Breaking changes.
const back_end = 'https://flags.plum.moe/'; const back_end = 'https://flags.plum.moe/';
const api_flags = 'api/flags'; const api_flags = 'api/flags';
@ -45,14 +43,21 @@ const max_flags = 30;
var regions = []; // The flags we have selected. var regions = []; // The flags we have selected.
var postNrs = []; // all post numbers in the thread. var postNrs = []; // all post numbers in the thread.
var board_id = ""; // The board we get flags for.
const site = {
fourchan: window.location.host === 'boards.4chan.org',
nineball: window.location.host === 'nineball.party'
};
// There are multiple foolfuuka archives we support; this has to be called after site is initialised as to not check each of them.
// I.E. we'd have to go window.location.host === 'archive.nyafuu.org' || window.location.host === 'archived.moe'
site.foolfuuka = !site.fourchan && !site.nineball;
// //
// DO NOT EDIT ANYTHING IN THIS SCRIPT DIRECTLY - YOUR FLAGS SHOULD BE CONFIGURED USING THE CONFIGURATION BOXES // DO NOT EDIT ANYTHING IN THIS SCRIPT DIRECTLY - YOUR FLAGS SHOULD BE CONFIGURED USING THE CONFIGURATION BOXES
// //
const elementsInClass = x => document.getElementsByClassName(x);
const sliceCall = x => Array.prototype.slice.call(x); const sliceCall = x => Array.prototype.slice.call(x);
const firstChildInClass = (parent, className) => parent.getElementsByClassName(className)[0];
const createAndAssign = (element, source) => Object.assign(document.createElement(element), source); const createAndAssign = (element, source) => Object.assign(document.createElement(element), source);
function addGlobalStyle(css) { function addGlobalStyle(css) {
@ -70,7 +75,7 @@ function addGlobalStyle(css) {
function debug(text) { function debug(text) {
if (debugMode) { if (debugMode) {
console.log("[BantFlags] " + text); console.log('[BantFlags] ' + text);
} }
} }
@ -85,27 +90,25 @@ function MakeRequest(method, url, data, func) {
url: url, url: url,
data: data, data: data,
headers: { headers: {
"Content-Type": "application/x-www-form-urlencoded" "Content-Type": 'application/x-www-form-urlencoded'
}, },
onload: func onload: func
}); });
} }
function retry(func, resp) { function retry(func, resp) {
console.log("[BantFlags] Could not fetch flags, status: " + resp.status); console.log('[BantFlags] Could not fetch flags, status: ' + resp.status);
console.log(resp.statusText); console.log(resp.statusText);
setTimeout(func, requestRetryInterval); setTimeout(func, requestRetryInterval);
} }
/** nSetup, preferences */ /** nSetup, preferences */
// TODO: this shouldn't be a class. // TODO: this shouldn't be a object.
var nsetup = { // not anymore a clone of the original setup var nsetup = { // not anymore a clone of the original setup
namespace: 'BintFlegs', // TODO: should be const. namespace: 'BintFlegs', // TODO: should be const.
flagsLoaded: false, flagsLoaded: false,
form: "<span id=\"bantflags_container\"></span>" + form: '<span id="bantflags_container"></span><button type="button" id="append_flag_button" title="Click to add selected flag to your flags. Click on flags to remove them. Saving happens automatically, you only need to refresh the pages that have an outdated flaglist on the page."><<</button><button id="flagLoad" type="button">Click to load flags.</button><select id="flagSelect"></select>',
"<button type=\"button\" id=\"append_flag_button\" title=\"Click to add selected flag to your flags. Click on flags to remove them. Saving happens automatically, you only need to refresh the pages that have an outdated flaglist on the page.\"><<</button>" +
"<button id=\"flagLoad\" type=\"button\">Click to load flags.</button><select id=\"flagSelect\"></select>",
fillHtml: function () { // TODO: this function should have a better name. Only called by nsetup.init, can be inlined? fillHtml: function () { // TODO: this function should have a better name. Only called by nsetup.init, can be inlined?
// resolve flags // resolve flags
@ -120,7 +123,7 @@ var nsetup = { // not anymore a clone of the original setup
return; return;
} }
let flagSelect = document.getElementById("flagSelect"); let flagSelect = document.getElementById('flagSelect');
let flagLoad = document.getElementById('flagLoad'); let flagLoad = document.getElementById('flagLoad');
let flagsSupported = resp.responseText.split('\n'); let flagsSupported = resp.responseText.split('\n');
@ -128,7 +131,7 @@ var nsetup = { // not anymore a clone of the original setup
let flag = flagsSupported[i]; let flag = flagsSupported[i];
flagSelect.appendChild(createAndAssign('option', { flagSelect.appendChild(createAndAssign('option', {
value: flag, value: flag,
innerHTML: "<img src=\"" + back_end + flag_dir + flag + ".png\"" + " title=\"" + flag + "\">" + " " + flag innerHTML: '<img src="' + back_end + flag_dir + flag + '.png" title="' + flag + '"> ' + flag
})); }));
} }
@ -143,12 +146,12 @@ var nsetup = { // not anymore a clone of the original setup
}, },
setFlag: function (flag) { setFlag: function (flag) {
let UID = Math.random().toString(36).substring(7); let UID = Math.random().toString(36).substring(7);
let flagName = flag ? flag : document.getElementById("flagSelect").value; let flagName = flag ? flag : document.getElementById('flagSelect').value;
let flagContainer = document.getElementById("bantflags_container"); let flagContainer = document.getElementById('bantflags_container');
flagContainer.appendChild(createAndAssign('img', { flagContainer.appendChild(createAndAssign('img', {
title: flagName, title: flagName,
src: back_end + flag_dir + flagName + ".png", src: back_end + flag_dir + flagName + '.png',
id: UID, id: UID,
className: 'bantflags_flag' className: 'bantflags_flag'
})); }));
@ -158,13 +161,11 @@ var nsetup = { // not anymore a clone of the original setup
} }
document.getElementById(UID).addEventListener("click", function () { document.getElementById(UID).addEventListener("click", function () {
console.log("removing flag");
let flagToRemove = document.getElementById(UID); let flagToRemove = document.getElementById(UID);
flagToRemove.parentNode.removeChild(flagToRemove); flagToRemove.parentNode.removeChild(flagToRemove);
nsetup.toggleFlagButton('on'); nsetup.toggleFlagButton('on');
nsetup.save(nsetup.parse()); nsetup.save(nsetup.parse());
console.log("flag removed");
}); });
if (!flag) { if (!flag) {
@ -175,15 +176,22 @@ var nsetup = { // not anymore a clone of the original setup
init: function () { init: function () {
// here we insert the form for placing flags. How? // here we insert the form for placing flags. How?
let flagsForm = createAndAssign("div", { let flagsForm = createAndAssign('div', {
className: 'flagsForm', className: 'flagsForm',
innerHTML: nsetup.form innerHTML: nsetup.form
}); });
addGlobalStyle('.flagsForm{float: right; clear: right; margin: 20px 10px;} #flagSelect{display:none;}'); addGlobalStyle('.flagsForm{float: right; clear: right; margin: 20px 10px;} #flagSelect{display:none;}');
addGlobalStyle(".bantflags_flag { padding: 1px;} [title^='Romania'] { position: relative; animation: shakeAnim 0.1s linear infinite;} @keyframes shakeAnim { 0% {left: 1px;} 25% {top: 2px;} 50% {left: 1px;} 75% {left: 0px;} 100% {left: 2px;}}"); addGlobalStyle('.bantflags_flag { padding: 1px;} [title^="Romania"] { position: relative; animation: shakeAnim 0.1s linear infinite;} @keyframes shakeAnim { 0% {left: 1px;} 25% {top: 2px;} 50% {left: 1px;} 75% {left: 0px;} 100% {left: 2px;}}');
firstChildInClass(document, 'bottomCtrl').parentNode.appendChild(flagsForm); if (site.fourchan) {
document.getElementById('delform').appendChild(flagsForm);
}
// nineball and we're not in the index
if (site.nineball && document.querySelector('threads .pagination') === null) {
document.querySelector('threads section').append(flagsForm);
}
for (var i in regions) { for (var i in regions) {
nsetup.setFlag(regions[i]); nsetup.setFlag(regions[i]);
@ -196,7 +204,7 @@ var nsetup = { // not anymore a clone of the original setup
}, },
parse: function () { parse: function () {
let flagsArray = []; let flagsArray = [];
let flagElements = elementsInClass("bantflags_flag"); let flagElements = document.getElementsByClassName("bantflags_flag");
for (var i = 0; i < flagElements.length; i++) { for (var i = 0; i < flagElements.length; i++) {
flagsArray[i] = flagElements[i].title; flagsArray[i] = flagElements[i].title;
@ -212,68 +220,64 @@ regions = GM_getValue(nsetup.namespace); // TODO: move this to other init stuff
if (!regions) { if (!regions) {
regions = []; regions = [];
setTimeout(function () { setTimeout(function () {
window.confirm("Bant Flags: No Flags detected"); window.confirm('Bant Flags: No Flags detected');
}, 2000); }, 2000);
} }
/** parse the posts already on the page before thread updater kicks in */ /** parse the posts already on the page before thread updater kicks in */
function parse4chanPosts() { function parse4chanPosts() {
let posts = sliceCall(elementsInClass('postContainer')); let posts = document.querySelectorAll('.postContainer');
for (var i = 0; i < posts.length; i++) { for (var i = 0; i < posts.length; i++) {
let postNumber = posts[i].id.replace("pc", ""); let postNumber = posts[i].id.replace('pc', ''); // Fuck you 4chan
postNrs.push(postNumber); postNrs.push(postNumber);
} }
debug(postNrs); debug(postNrs);
} }
function parseFoolFuukaPosts() { function getposts(selector) {
let nums = x => x.filter(x => x.id !== '').map(x => x.id); let posts = document.querySelectorAll(selector);
let getPostNumbers = x => nums(sliceCall(elementsInClass(x)));
postNrs = getPostNumbers('thread').concat(getPostNumbers('post')); for (var i = 0; i < posts.length; i++) {
postNrs.push(posts[i].id);
}
debug(postNrs); debug(postNrs);
} }
function onFlagsLoad(response) { function onFlagsLoad(response) {
// because we only care about the end result, not how we got there.
// grandparent -> first parent -> first child.
let hopHTML = (post_nr, first, second) =>
firstChildInClass(firstChildInClass(document.getElementById(post_nr), first), second);
let MakeFlag = (flag) => let MakeFlag = (flag) =>
createAndAssign('a', { createAndAssign('a', {
innerHTML: "<img src=\"" + back_end + flag_dir + flag + ".png\" title=\"" + flag + "\">", innerHTML: '<img src="' + back_end + flag_dir + flag + '.png" title="' + flag + '"> ',
className: "bantFlag", className: 'bantFlag',
target: "_blank" target: '_blank'
}); });
debug("JSON: " + response.responseText); debug('JSON: ' + response.responseText);
var jsonData = JSON.parse(response.responseText); var jsonData = JSON.parse(response.responseText);
Object.keys(jsonData).forEach(function (post) { Object.keys(jsonData).forEach(function (post) {
let flagContainer = is_archive var flagContainer;
? hopHTML(post, "post_data", "post_type") if (site.nineball) { flagContainer = document.querySelector('[id="' + post + '"] header'); }
: hopHTML("pc" + post, "postInfo", "nameBlock"); if (site.fourchan) { flagContainer = document.querySelector('[id="pc' + post + '"] .postInfo .nameBlock'); }
let currentFlag = firstChildInClass(flagContainer, 'flag'); if (site.foolfuuka) { flagContainer = document.querySelector('[id="' + post + '"] .post_data .post_type'); }
let flags = jsonData[post];
// If we have a bantflag and the original post has a flag let flags = jsonData[post];
if (flags.length > 0 && currentFlag !== undefined) { if (flags.length > 0) {
console.log("[BantFlags] Resolving flags for >>" + post); console.log('[BantFlags] Resolving flags for >>' + post);
for (var i = 0; i < flags.length; i++) { for (var i = 0; i < flags.length; i++) {
let flag = flags[i]; let flag = flags[i];
let newFlag = MakeFlag(flag); let newFlag = MakeFlag(flag);
if (is_archive) { if (site.foolfuuka) {
newFlag.style = "padding: 0px 0px 0px " + (3 + 2 * (i > 0)) + "px; vertical-align:;display: inline-block; width: 16px; height: 11px; position: relative;"; newFlag.style = 'padding: 0px 0px 0px ' + (3 + 2 * (i > 0)) + 'px; vertical-align:;display: inline-block; width: 16px; height: 11px; position: relative;';
}
if (site.nineball) {
newFlag.title = flag;
} }
flagContainer.append(newFlag); flagContainer.append(newFlag);
console.log("\t -> " + flag); console.log('\t -> ' + flag);
} }
} }
}); });
@ -281,11 +285,13 @@ function onFlagsLoad(response) {
postNrs = []; postNrs = [];
} }
/** Gets flags from the database. */
function resolveRefFlags() { function resolveRefFlags() {
debug('Board is: ' + board_id);
MakeRequest( MakeRequest(
"POST", 'POST',
back_end + api_get, back_end + api_get,
"post_nrs=" + encodeURIComponent(postNrs) + "&board=" + encodeURIComponent(boardID) + "&version=" + encodeURIComponent(version), 'post_nrs=' + encodeURIComponent(postNrs) + '&board=' + encodeURIComponent(board_id) + '&version=' + encodeURIComponent(version),
function (resp) { function (resp) {
if (resp.status !== 200) { if (resp.status !== 200) {
retry(resolveRefFlags, resp); retry(resolveRefFlags, resp);
@ -297,26 +303,39 @@ function resolveRefFlags() {
} }
// Flags need to be parsed and aligned differently between boards. // Flags need to be parsed and aligned differently between boards.
if (is_archive) { if (site.fourchan) {
debug("FoolFuuka."); debug('4chan');
parseFoolFuukaPosts(); board_id = 'bant';
addGlobalStyle('.bantFlag{top: -2px !important;left: -1px !important}');
}
else {
debug("4chan.");
parse4chanPosts(); parse4chanPosts();
addGlobalStyle('.flag{top: 0px !important;left: -1px !important}'); addGlobalStyle('.flag{top: 0px !important;left: -1px !important}');
addGlobalStyle(".bantFlag {padding: 0px 0px 0px 5px; vertical-align:;display: inline-block; width: 16px; height: 11px; position: relative;}"); addGlobalStyle('.bantFlag {padding: 0px 0px 0px 5px; vertical-align:;display: inline-block; width: 16px; height: 11px; position: relative;}');
} }
resolveRefFlags(); // Get flags from db. if (site.nineball) {
debug(regions);
debug('Nineball');
board_id = window.location.pathname.split('/')[1]; // 'nap' or 'srsbsn'
getposts('section[id], article[id]');
if (!is_archive) { addGlobalStyle('.bantFlag {cursor: default} .bantFlag img {pointer-events: none;}');
}
if (site.foolfuuka) { // Archive.
debug('FoolFuuka');
board_id = 'bant';
getposts('article[id]');
addGlobalStyle('.bantFlag{top: -2px !important;left: -1px !important}');
}
resolveRefFlags(); // Get flags from DB.
// Posting new flags and getting flags as posts are added to the thread.
if (site.fourchan) {
let GetEvDetail = e => e.detail || e.wrappedJSObject.detail; let GetEvDetail = e => e.detail || e.wrappedJSObject.detail;
let method = "POST", let method = 'POST',
url = back_end + api_post, url = back_end + api_post,
func = function (resp) { func = function (resp) {
debug(resp.responseText); debug(resp.responseText);
@ -332,7 +351,7 @@ if (!is_archive) {
//setTimeout to support greasemonkey 1.x //setTimeout to support greasemonkey 1.x
setTimeout(function () { setTimeout(function () {
var data = "post_nr=" + encodeURIComponent(e.detail.postID) + "&board=" + encodeURIComponent(e.detail.boardID) + "&regions=" + encodeURIComponent(regions) + "&version=" + encodeURIComponent(version); var data = 'post_nr=' + encodeURIComponent(e.detail.postID) + '&board=' + encodeURIComponent(e.detail.boardID) + '&regions=' + encodeURIComponent(regions) + '&version=' + encodeURIComponent(version);
MakeRequest(method, url, data, func); MakeRequest(method, url, data, func);
}, 0); }, 0);
}, false); }, false);
@ -343,7 +362,7 @@ if (!is_archive) {
//setTimeout to support greasemonkey 1.x //setTimeout to support greasemonkey 1.x
setTimeout(function () { setTimeout(function () {
var data = "post_nr=" + encodeURIComponent(evDetail.postId) + "&board=" + encodeURIComponent(boardID) + "&regions=" + encodeURIComponent(regions) + "&version=" + encodeURIComponent(version); var data = 'post_nr=' + encodeURIComponent(evDetail.postId) + '&board=' + encodeURIComponent(board_id) + '&regions=' + encodeURIComponent(regions) + '&version=' + encodeURIComponent(version);
MakeRequest(method, url, data, func); MakeRequest(method, url, data, func);
}, 0); }, 0);
}, false); }, false);
@ -380,7 +399,7 @@ if (!is_archive) {
//add to temp posts and the DOM element to allPostsOnPage //add to temp posts and the DOM element to allPostsOnPage
lastPosts.forEach(function (post_container) { lastPosts.forEach(function (post_container) {
var post_nr = post_container.id.replace("pc", ""); var post_nr = post_container.id.replace('pc', '');
postNrs.push(post_nr); postNrs.push(post_nr);
}); });
@ -390,3 +409,26 @@ if (!is_archive) {
/** setup init and start first calls */ /** setup init and start first calls */
nsetup.init(); nsetup.init();
} }
if (site.nineball) {
nsetup.init();
new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (mutation.addedNodes[0].nodeName == 'HEADER') { // When you make a post
let data = 'post_nr=' + encodeURIComponent(mutation.target.id) + '&board=' + encodeURIComponent(board_id) + '&regions=' + encodeURIComponent(regions) + '&version=' + encodeURIComponent(version);
MakeRequest(
'POST',
back_end + api_post,
data,
function (resp) {
postNrs.push(mutation.target.id);
setTimeout(resolveRefFlags, 0);
});
}
if (mutation.addedNodes[0].nodeName == 'ARTICLE') { // When someone else makes a post
postNrs.push(mutation.addedNodes[0].id);
setTimeout(resolveRefFlags, 1500); // Wait 1.5s so the database can process the post, since they appear instantly.
}
});
}).observe(document.querySelector('threads'), { childList: true, subtree: true });
}
Loading…
Cancel
Save