Browse Source

Add ATF

pull/46/head 0.100
coomdev 2 years ago
parent
commit
962664cff4
  1. 2
      main.meta.js
  2. 63
      main.user.js
  3. 1
      src/App.svelte
  4. 66
      src/main.ts
  5. 1
      src/stores.ts
  6. 31
      src/thirdeye.ts

2
main.meta.js

@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name PNGExtraEmbed // @name PNGExtraEmbed
// @namespace https://coom.tech/ // @namespace https://coom.tech/
// @version 0.98 // @version 0.99
// @description uhh // @description uhh
// @author You // @author You
// @match https://boards.4channel.org/* // @match https://boards.4channel.org/*

63
main.user.js

@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name PNGExtraEmbed // @name PNGExtraEmbed
// @namespace https://coom.tech/ // @namespace https://coom.tech/
// @version 0.98 // @version 0.99
// @description uhh // @description uhh
// @author You // @author You
// @match https://boards.4channel.org/* // @match https://boards.4channel.org/*
@ -10924,6 +10924,7 @@
})); }));
var appState = writable({ var appState = writable({
isCatalog: false, isCatalog: false,
is4chanX: false,
foundPosts: [] foundPosts: []
}); });
appState.subscribe((v) => { appState.subscribe((v) => {
@ -11426,6 +11427,19 @@
preview_url: e.preview_url, preview_url: e.preview_url,
tags: e.tags.split(" ") tags: e.tags.split(" ")
})) }))
},
{
name: "ATFbooru",
domain: "booru.allthefallen.moe",
endpoint: "/posts.json?tags=md5:",
quirks: (a) => a.map((e) => ({
source: e.source,
page: `https://booru.allthefallen.moe/posts/${e.id}`,
ext: e.file_url.substr(e.file_url.lastIndexOf(".") + 1),
full_url: e.file_url,
preview_url: e.preview_url,
tags: e.tag_string.split(" ")
}))
} }
]; ];
var black = /* @__PURE__ */ new Set(); var black = /* @__PURE__ */ new Set();
@ -12050,7 +12064,8 @@
"capi-v2.sankakucomplex.com", "capi-v2.sankakucomplex.com",
"api.rule34.xxx", "api.rule34.xxx",
"danbooru.donmai.us", "danbooru.donmai.us",
"lolibooru.moe" "lolibooru.moe",
"boory.allthefallen.moe"
]; ];
let selectobj; let selectobj;
let selectobj2; let selectobj2;
@ -15560,14 +15575,9 @@
post.setAttribute("data-processed", "true"); post.setAttribute("data-processed", "true");
}; };
var startup = async () => { var startup = async () => {
if (typeof window["FCX"] != "undefined")
appState.set({ ...cappState, is4chanX: true });
await Promise.all([...document.querySelectorAll(".postContainer")].filter((e) => e.textContent?.includes("191 KB")).map((e) => processPost(e))); await Promise.all([...document.querySelectorAll(".postContainer")].filter((e) => e.textContent?.includes("191 KB")).map((e) => processPost(e)));
document.addEventListener("ThreadUpdate", async (e) => {
const newPosts = e.detail.newPosts;
for (const post of newPosts) {
const postContainer = document.getElementById("pc" + post.substring(post.indexOf(".") + 1));
processPost(postContainer);
}
});
const mo = new MutationObserver((reco) => { const mo = new MutationObserver((reco) => {
for (const rec of reco) for (const rec of reco)
if (rec.type == "childList") if (rec.type == "childList")
@ -15599,7 +15609,7 @@
document.body.append(scrollHost); document.body.append(scrollHost);
appState.set({ appState.set({
...cappState, ...cappState,
isCatalog: !!document.querySelector(".catalog-small") isCatalog: !!document.querySelector(".catalog-small") || !!location.pathname.match(/\/catalog$/)
}); });
await Promise.all(posts.map((e) => processPost(e))); await Promise.all(posts.map((e) => processPost(e)));
}; };
@ -15610,15 +15620,38 @@
}); });
}; };
document.addEventListener("4chanXInitFinished", startup); document.addEventListener("4chanXInitFinished", startup);
document.addEventListener("ThreadUpdate", async (e) => {
const newPosts = e.detail.newPosts;
for (const post of newPosts) {
const postContainer = document.getElementById("pc" + post.substring(post.indexOf(".") + 1));
processPost(postContainer);
}
});
if (cappState.is4chanX) {
const qr = window["QR"];
const show = qr.show.bind(qr);
qr.show = (...args) => {
show(...args);
document.dispatchEvent(new CustomEvent("QRDialogCreation", {
detail: document.getElementById("quickReply")
}));
};
}
document.addEventListener("QRDialogCreation", (e) => { document.addEventListener("QRDialogCreation", (e) => {
const target = e.target; const a = document.createElement("a");
const bts = target.querySelector("#qr-filename-container");
const i = document.createElement("i"); const i = document.createElement("i");
i.className = "fa fa-magnet"; i.className = "fa fa-magnet";
const a = document.createElement("a");
a.appendChild(i); a.appendChild(i);
a.title = "Embed File (Select a file before...)"; a.title = "Embed File (Select a file before...)";
bts?.appendChild(a); let target;
if (cappState.is4chanX) {
i.innerText = "\u{1F9F2}";
target = e.detail;
target.querySelector("input[type=submit]")?.insertAdjacentElement("beforebegin", a);
} else {
target = e.target;
target.querySelector("#qr-filename-container")?.appendChild(a);
}
a.onclick = async (e2) => { a.onclick = async (e2) => {
const file = await getSelectedFile(); const file = await getSelectedFile();
if (!file) if (!file)
@ -15659,7 +15692,7 @@
}; };
input.click(); input.click();
}; };
}, { once: true }); }, { once: !cappState.is4chanX });
var customStyles = document.createElement("style"); var customStyles = document.createElement("style");
customStyles.appendChild(document.createTextNode(global_default)); customStyles.appendChild(document.createTextNode(global_default));
document.documentElement.insertBefore(customStyles, null); document.documentElement.insertBefore(customStyles, null);

1
src/App.svelte

@ -18,6 +18,7 @@
'api.rule34.xxx', 'api.rule34.xxx',
'danbooru.donmai.us', 'danbooru.donmai.us',
'lolibooru.moe', 'lolibooru.moe',
'boory.allthefallen.moe'
] ]
let selectobj: HTMLSelectElement let selectobj: HTMLSelectElement

66
src/main.ts

@ -65,7 +65,7 @@ async function* streamRemote(url: string, chunkSize = 16 * 1024, fetchRestOnNonC
} }
type EmbeddedFileWithPreview = { type EmbeddedFileWithPreview = {
page?: {title: string, url: string}; // can be a booru page page?: { title: string, url: string }; // can be a booru page
source?: string; // can be like a twitter post this was posted in originally source?: string; // can be like a twitter post this was posted in originally
thumbnail: Buffer; thumbnail: Buffer;
filename: string; filename: string;
@ -205,18 +205,11 @@ const processPost = async (post: HTMLDivElement) => {
}; };
const startup = async () => { const startup = async () => {
if (typeof (window as any)['FCX'] != "undefined")
appState.set({ ...cappState, is4chanX: true });
await Promise.all([...document.querySelectorAll('.postContainer')].filter(e => e.textContent?.includes("191 KB")).map(e => processPost(e as any))); await Promise.all([...document.querySelectorAll('.postContainer')].filter(e => e.textContent?.includes("191 KB")).map(e => processPost(e as any)));
// Basically this is a misnommer: fires even when inlining existings posts, also posts are inlined through some kind of dom projection
document.addEventListener('ThreadUpdate', <any>(async (e: CustomEvent<any>) => {
const newPosts = e.detail.newPosts;
for (const post of newPosts) {
const postContainer = document.getElementById("pc" + post.substring(post.indexOf(".") + 1)) as HTMLDivElement;
processPost(postContainer);
}
}));
// keep this to handle posts getting inlined // keep this to handle posts getting inlined
const mo = new MutationObserver(reco => { const mo = new MutationObserver(reco => {
for (const rec of reco) for (const rec of reco)
@ -255,7 +248,7 @@ const startup = async () => {
appState.set({ appState.set({
...cappState, ...cappState,
isCatalog: !!document.querySelector('.catalog-small'), isCatalog: !!document.querySelector('.catalog-small') || !!location.pathname.match(/\/catalog$/),
}); });
await Promise.all(posts.map(e => processPost(e as any))); await Promise.all(posts.map(e => processPost(e as any)));
}; };
@ -267,17 +260,54 @@ const getSelectedFile = () => {
}); });
}; };
document.addEventListener('4chanXInitFinished', startup); //if (cappState!.is4chanX)
document.addEventListener('4chanXInitFinished', startup);
/*else {
document.addEventListener("QRGetFile", (e) => {
const qr = document.getElementById('qrFile') as HTMLInputElement | null;
document.dispatchEvent(new CustomEvent("QRFile", { detail: (qr?.files || [])[0] }));
});
startup();
}*/
// Basically this is a misnommer: fires even when inlining existings posts, also posts are inlined through some kind of dom projection
document.addEventListener('ThreadUpdate', <any>(async (e: CustomEvent<any>) => {
const newPosts = e.detail.newPosts;
for (const post of newPosts) {
const postContainer = document.getElementById("pc" + post.substring(post.indexOf(".") + 1)) as HTMLDivElement;
processPost(postContainer);
}
}));
if (cappState!.is4chanX) {
const qr = (window as any)['QR'];
const show = qr.show.bind(qr);
qr.show = (...args: any[]) => {
show(...args);
document.dispatchEvent(new CustomEvent("QRDialogCreation", {
detail: document.getElementById('quickReply')
}));
};
}
document.addEventListener('QRDialogCreation', <any>((e: CustomEvent<string>) => { document.addEventListener('QRDialogCreation', <any>((e: CustomEvent<HTMLElement>) => {
const target = e.target as HTMLDivElement; const a = document.createElement('a');
const bts = target.querySelector('#qr-filename-container');
const i = document.createElement('i'); const i = document.createElement('i');
i.className = "fa fa-magnet"; i.className = "fa fa-magnet";
const a = document.createElement('a');
a.appendChild(i); a.appendChild(i);
a.title = "Embed File (Select a file before...)"; a.title = "Embed File (Select a file before...)";
bts?.appendChild(a);
let target;
if (cappState.is4chanX) {
i.innerText = "🧲";
target = e.detail;
target.querySelector("input[type=submit]")?.insertAdjacentElement("beforebegin", a);
}
else {
target = e.target as HTMLDivElement;
target.querySelector('#qr-filename-container')?.appendChild(a);
}
a.onclick = async (e) => { a.onclick = async (e) => {
const file = await getSelectedFile(); const file = await getSelectedFile();
if (!file) if (!file)
@ -319,7 +349,7 @@ document.addEventListener('QRDialogCreation', <any>((e: CustomEvent<string>) =>
}); });
input.click(); input.click();
}; };
}), { once: true }); }), { once: !cappState!.is4chanX }); // 4chan's normal extension destroys the QR form everytime
const customStyles = document.createElement('style'); const customStyles = document.createElement('style');

1
src/stores.ts

@ -31,6 +31,7 @@ export const settings = writable(localLoad('settings', {
export const appState = writable({ export const appState = writable({
isCatalog: false, isCatalog: false,
is4chanX: false,
foundPosts: [] as HTMLElement[] foundPosts: [] as HTMLElement[]
}); });

31
src/thirdeye.ts

@ -26,7 +26,7 @@ function firstThatFor<T>(promises: Promise<T>[], pred: (v: T) => boolean) {
if (pred(v)) if (pred(v))
return v; return v;
throw v; throw v;
})) }));
} }
const gelquirk: (s: string) => tran = prefix => (a => const gelquirk: (s: string) => tran = prefix => (a =>
@ -109,7 +109,34 @@ export const boorus: Booru[] = [
preview_url: e.preview_url, preview_url: e.preview_url,
tags: e.tags.split(' ') tags: e.tags.split(' ')
} as BooruMatch)) } as BooruMatch))
} },
{
name: "ATFbooru",
domain: "booru.allthefallen.moe",
endpoint: "/posts.json?tags=md5:",
quirks: a =>
a.map((e: any) => ({
source: e.source,
page: `https://booru.allthefallen.moe/posts/${e.id}`,
ext: e.file_url.substr(e.file_url.lastIndexOf('.') + 1),
full_url: e.file_url,
preview_url: e.preview_url,
tags: e.tag_string.split(' ')
} as BooruMatch))
},
// {
// name: "Rule34Paheal", domain: "rule34.paheal.net",
// endpoint: "/posts.json?tags=md5:",
// quirks: a =>
// a.map((e: any) => ({
// source: e.source,
// page: `https://rule34.paheal.net/post/view/${e.id}`,
// ext: e.file_url.substr(e.file_url.lastIndexOf('.') + 1),
// full_url: e.file_url,
// preview_url: e.preview_url,
// tags: e.tag_string.split(' ')
// } as BooruMatch))
// }
]; ];
let black = new Set<string>(); let black = new Set<string>();

Loading…
Cancel
Save