// ==UserScript==
// @name NGA Likes Support
// @namespace https://greasyfork.org/users/263018
// @version 1.1.1
// @author snyssss
// @description 显示被点赞和粉丝数量
// @match *://bbs.nga.cn/*
// @match *://ngabbs.com/*
// @match *://nga.178.com/*
// @noframes
// @downloadURL none
// ==/UserScript==
((ui) => {
if (!ui) return;
// 钩子
const hookFunction = (object, functionName, callback) => {
((originalFunction) => {
object[functionName] = function () {
const returnValue = originalFunction.apply(this, arguments);
callback.apply(this, [returnValue, originalFunction, arguments]);
return returnValue;
};
})(object[functionName]);
};
class UserInfo {
execute(task) {
task().finally(() => {
if (this.waitingQueue.length) {
const next = this.waitingQueue.shift();
this.execute(next);
} else {
this.isRunning = false;
}
});
}
enqueue(task) {
if (this.isRunning) {
this.waitingQueue.push(task);
} else {
this.isRunning = true;
this.execute(task);
}
}
rearrange() {
if (this.data) {
const list = Object.values(this.children);
for (let i = 0; i < list.length; i++) {
if (list[i].source === undefined) {
list[i].create(this.data);
}
Object.entries(this.container).forEach((item) => {
list[i].clone(this.data, item);
});
}
}
}
reload() {
this.enqueue(async () => {
this.data = await new Promise((resolve) => {
fetch(`/nuke.php?lite=js&__lib=ucp&__act=get&uid=${this.uid}`)
.then((res) => res.blob())
.then((blob) => {
const reader = new FileReader();
reader.onload = () => {
const text = reader.result;
const result = JSON.parse(
text.replace("window.script_muti_get_var_store=", "")
);
resolve(result.data[0]);
};
reader.readAsText(blob, "GBK");
})
.catch(() => {
resolve();
});
});
Object.values(this.children).forEach((item) => item.destroy());
this.rearrange();
});
}
constructor(id) {
this.uid = id;
this.waitingQueue = [];
this.isRunning = false;
this.container = {};
this.children = {};
this.reload();
}
}
class UserInfoWidget {
destroy() {
if (this.source) {
this.source = undefined;
}
if (this.target) {
Object.values(this.target).forEach((item) => {
if (item.parentNode) {
item.parentNode.removeChild(item);
}
});
}
}
clone(data, [argid, container]) {
if (this.source) {
if (this.target[argid] === undefined) {
this.target[argid] = this.source.cloneNode(true);
if (this.callback) {
this.callback(data, this.target[argid]);
}
}
container.appendChild(this.target[argid]);
}
}
constructor(func, callback) {
this.create = (data) => {
this.destroy();
this.source = func(data);
this.target = {};
};
this.callback = callback;
}
}
ui.sn = ui.sn || {};
ui.sn.userInfo = ui.sn.userInfo || {};
((info) => {
const execute = (argid) => {
const args = ui.postArg.data[argid];
if (args.comment) return;
const uid = +args.pAid;
if (uid > 0) {
if (info[uid] === undefined) {
info[uid] = new UserInfo(uid);
}
if (document.contains(info[uid].container[argid]) === false) {
info[uid].container[argid] = args.uInfoC.querySelector(
"[name=uid]"
).parentNode;
}
info[uid].enqueue(async () => {
if (info[uid].children[8] === undefined) {
info[uid].children[8] = new UserInfoWidget((data) => {
const value =
Object.values(data.more_info || {}).find((item) => item.type === 8)
?.data || 0;
const element = document.createElement("SPAN");
element.className =
"small_colored_text_btn stxt block_txt_c2 vertmod";
element.style.cursor = "default";
element.innerHTML = `⯅ ${value}`;
return element;
});
}
if (info[uid].children[16] === undefined) {
info[uid].children[16] = new UserInfoWidget((data) => {
const value = data.follow_by_num || 0;
const element = document.createElement("SPAN");
element.className =
"small_colored_text_btn stxt block_txt_c2 vertmod";
element.style.cursor = "default";
element.innerHTML = `★ ${value}`;
return element;
});
}
info[uid].rearrange();
});
}
};
if (ui.postArg) {
Object.keys(ui.postArg.data).forEach((i) => execute(i));
}
let initialized = false;
hookFunction(ui, "eval", () => {
if (initialized) return;
if (ui.postDisp) {
hookFunction(
ui,
"postDisp",
(returnValue, originalFunction, arguments) => execute(arguments[0])
);
initialized = true;
}
});
})(ui.sn.userInfo);
})(commonui);