mirror of
https://git.coom.tech/fuckjannies/lolipiss.git
synced 2024-06-29 05:52:35 +00:00
Support double embeds
This commit is contained in:
parent
19d5fb17ed
commit
27eaa92c82
|
@ -1,7 +1,7 @@
|
||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name PNGExtraEmbed
|
// @name PNGExtraEmbed
|
||||||
// @namespace https://coom.tech/
|
// @namespace https://coom.tech/
|
||||||
// @version 0.100
|
// @version 0.98
|
||||||
// @description uhh
|
// @description uhh
|
||||||
// @author You
|
// @author You
|
||||||
// @match https://boards.4channel.org/*
|
// @match https://boards.4channel.org/*
|
||||||
|
|
110
main.user.js
110
main.user.js
|
@ -1,7 +1,7 @@
|
||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name PNGExtraEmbed
|
// @name PNGExtraEmbed
|
||||||
// @namespace https://coom.tech/
|
// @namespace https://coom.tech/
|
||||||
// @version 0.100
|
// @version 0.98
|
||||||
// @description uhh
|
// @description uhh
|
||||||
// @author You
|
// @author You
|
||||||
// @match https://boards.4channel.org/*
|
// @match https://boards.4channel.org/*
|
||||||
|
@ -10924,7 +10924,6 @@
|
||||||
}));
|
}));
|
||||||
var appState = writable({
|
var appState = writable({
|
||||||
isCatalog: false,
|
isCatalog: false,
|
||||||
is4chanX: false,
|
|
||||||
foundPosts: []
|
foundPosts: []
|
||||||
});
|
});
|
||||||
appState.subscribe((v) => {
|
appState.subscribe((v) => {
|
||||||
|
@ -11300,30 +11299,30 @@
|
||||||
xmlhttprequest(gmopt);
|
xmlhttprequest(gmopt);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function GM_fetch(...[url, opt, lisn]) {
|
function blobTo(to, blob) {
|
||||||
function blobTo(to, blob) {
|
if (to == "arrayBuffer" && blob.arrayBuffer)
|
||||||
if (to == "arrayBuffer" && blob.arrayBuffer)
|
return blob.arrayBuffer();
|
||||||
return blob.arrayBuffer();
|
return new Promise((resolve, reject) => {
|
||||||
return new Promise((resolve, reject) => {
|
const fileReader = new FileReader();
|
||||||
const fileReader = new FileReader();
|
fileReader.onload = function(event) {
|
||||||
fileReader.onload = function(event) {
|
if (!event)
|
||||||
if (!event)
|
return;
|
||||||
return;
|
if (to == "base64")
|
||||||
if (to == "base64")
|
resolve(event.target.result);
|
||||||
resolve(event.target.result);
|
|
||||||
else
|
|
||||||
resolve(event.target.result);
|
|
||||||
};
|
|
||||||
if (to == "arrayBuffer")
|
|
||||||
fileReader.readAsArrayBuffer(blob);
|
|
||||||
else if (to == "base64")
|
|
||||||
fileReader.readAsDataURL(blob);
|
|
||||||
else if (to == "text")
|
|
||||||
fileReader.readAsText(blob, "utf-8");
|
|
||||||
else
|
else
|
||||||
reject("unknown to");
|
resolve(event.target.result);
|
||||||
});
|
};
|
||||||
}
|
if (to == "arrayBuffer")
|
||||||
|
fileReader.readAsArrayBuffer(blob);
|
||||||
|
else if (to == "base64")
|
||||||
|
fileReader.readAsDataURL(blob);
|
||||||
|
else if (to == "text")
|
||||||
|
fileReader.readAsText(blob, "utf-8");
|
||||||
|
else
|
||||||
|
reject("unknown to");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function GM_fetch(...[url, opt, lisn]) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const gmopt = {
|
const gmopt = {
|
||||||
url: url.toString(),
|
url: url.toString(),
|
||||||
|
@ -11427,19 +11426,6 @@
|
||||||
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();
|
||||||
|
@ -11449,7 +11435,7 @@
|
||||||
sources = new Set(s.sources);
|
sources = new Set(s.sources);
|
||||||
});
|
});
|
||||||
var cache = {};
|
var cache = {};
|
||||||
var findFileFrom = async (b, hex, abort) => {
|
var findFileFrom = async (b, hex) => {
|
||||||
try {
|
try {
|
||||||
if (b.domain in cache && hex in cache[b.domain])
|
if (b.domain in cache && hex in cache[b.domain])
|
||||||
return cache[b.domain][hex];
|
return cache[b.domain][hex];
|
||||||
|
@ -11509,7 +11495,7 @@
|
||||||
skip: true,
|
skip: true,
|
||||||
extract: extract4,
|
extract: extract4,
|
||||||
has_embed: has_embed4,
|
has_embed: has_embed4,
|
||||||
match: (fn) => !!fn.match(/^[0-9a-fA-F]{32}\.....?/)
|
match: (fn) => !!fn.match(/^[0-9a-fA-F]{32}\.....?$/)
|
||||||
};
|
};
|
||||||
|
|
||||||
// src/App.svelte
|
// src/App.svelte
|
||||||
|
@ -15575,9 +15561,14 @@
|
||||||
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")
|
||||||
|
@ -15609,7 +15600,7 @@
|
||||||
document.body.append(scrollHost);
|
document.body.append(scrollHost);
|
||||||
appState.set({
|
appState.set({
|
||||||
...cappState,
|
...cappState,
|
||||||
isCatalog: !!document.querySelector(".catalog-small") || !!location.pathname.match(/\/catalog$/)
|
isCatalog: !!document.querySelector(".catalog-small")
|
||||||
});
|
});
|
||||||
await Promise.all(posts.map((e) => processPost(e)));
|
await Promise.all(posts.map((e) => processPost(e)));
|
||||||
};
|
};
|
||||||
|
@ -15620,38 +15611,15 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
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 a = document.createElement("a");
|
const target = e.target;
|
||||||
|
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...)";
|
||||||
let target;
|
bts?.appendChild(a);
|
||||||
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)
|
||||||
|
@ -15692,7 +15660,7 @@
|
||||||
};
|
};
|
||||||
input.click();
|
input.click();
|
||||||
};
|
};
|
||||||
}, { once: !cappState.is4chanX });
|
}, { once: true });
|
||||||
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);
|
||||||
|
|
|
@ -247,11 +247,9 @@
|
||||||
<div
|
<div
|
||||||
class:contract={contracted}
|
class:contract={contracted}
|
||||||
class="place"
|
class="place"
|
||||||
|
|
||||||
on:click={e => e.preventDefault()}
|
on:click={e => e.preventDefault()}
|
||||||
on:auxclick={e => e.preventDefault()}
|
on:auxclick={e => e.preventDefault()}
|
||||||
on:mousedown={bepis}
|
on:mousedown={bepis}
|
||||||
|
|
||||||
on:mouseover={hoverStart}
|
on:mouseover={hoverStart}
|
||||||
on:mouseout={hoverStop}
|
on:mouseout={hoverStop}
|
||||||
on:mousemove={hoverUpdate}
|
on:mousemove={hoverUpdate}
|
||||||
|
@ -260,11 +258,7 @@
|
||||||
>
|
>
|
||||||
{#if isImage}
|
{#if isImage}
|
||||||
<!-- svelte-ignore a11y-missing-attribute -->
|
<!-- svelte-ignore a11y-missing-attribute -->
|
||||||
<img
|
<img bind:this={imgElem} alt={file.filename} src={furl || url} />
|
||||||
bind:this={imgElem}
|
|
||||||
alt={file.filename}
|
|
||||||
src={furl || url}
|
|
||||||
/>
|
|
||||||
{/if}
|
{/if}
|
||||||
{#if isAudio}
|
{#if isAudio}
|
||||||
<audio
|
<audio
|
||||||
|
@ -279,7 +273,7 @@
|
||||||
{#if isVideo}
|
{#if isVideo}
|
||||||
<!-- svelte-ignore a11y-media-has-caption -->
|
<!-- svelte-ignore a11y-media-has-caption -->
|
||||||
<!-- svelte-ignore a11y-missing-attribute -->
|
<!-- svelte-ignore a11y-missing-attribute -->
|
||||||
<video loop={$settings.loop} bind:this={videoElem} src={furl || url} />
|
<video loop={$settings.loop} bind:this={videoElem} src={furl || url} />
|
||||||
<!-- assoom videos will never be loaded from thumbnails -->
|
<!-- assoom videos will never be loaded from thumbnails -->
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
23
src/Embeddings.svelte
Normal file
23
src/Embeddings.svelte
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { EmbeddedFile } from './main';
|
||||||
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
import Embedding from './Embedding.svelte';
|
||||||
|
|
||||||
|
export const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
export let files: EmbeddedFile[]
|
||||||
|
export let id: string = '';
|
||||||
|
|
||||||
|
let children: {[k in number]: Embedding}= {}
|
||||||
|
export async function bepis(ev: MouseEvent) {
|
||||||
|
for (let child of Object.values(children))
|
||||||
|
child.bepis(ev);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#each files as file, i}
|
||||||
|
<Embedding bind:this={children[i]} {id} {file} />
|
||||||
|
{/each}
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
|
@ -1,14 +1,15 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { fileTypeFromBuffer } from 'file-type';
|
import { fileTypeFromBuffer } from 'file-type';
|
||||||
import type Embedding from './Embedding.svelte';
|
import type Embedding from './Embedding.svelte';
|
||||||
|
import type Embeddings from './Embeddings.svelte';
|
||||||
|
|
||||||
import type { EmbeddedFile } from './main';
|
import type { EmbeddedFile } from './main';
|
||||||
|
|
||||||
import { settings } from './stores'
|
import { settings } from './stores'
|
||||||
|
|
||||||
export let id = ''
|
export let id = ''
|
||||||
export let file: EmbeddedFile;
|
export let files: EmbeddedFile[];
|
||||||
export let inst: Embedding;
|
export let inst: Embedding | Embeddings;
|
||||||
|
|
||||||
let isVideo = false
|
let isVideo = false
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ import type { EmbeddedFile } from './main';
|
||||||
}
|
}
|
||||||
const isNotChrome = !navigator.userAgent.includes("Chrome/");
|
const isNotChrome = !navigator.userAgent.includes("Chrome/");
|
||||||
|
|
||||||
async function downloadFile() {
|
async function downloadFile(file: EmbeddedFile) {
|
||||||
const a = document.createElement("a") as HTMLAnchorElement;
|
const a = document.createElement("a") as HTMLAnchorElement;
|
||||||
document.body.appendChild(a);
|
document.body.appendChild(a);
|
||||||
a.style.display = 'none';
|
a.style.display = 'none';
|
||||||
|
@ -45,9 +46,10 @@ import type { EmbeddedFile } from './main';
|
||||||
class="fa clickable"
|
class="fa clickable"
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#each files as file}
|
||||||
<span
|
<span
|
||||||
title={file.filename}
|
title={file.filename}
|
||||||
on:click={downloadFile}
|
on:click={() => downloadFile(file)}
|
||||||
class="fa fa-download clickable"
|
class="fa fa-download clickable"
|
||||||
/>
|
/>
|
||||||
{#if file.source}
|
{#if file.source}
|
||||||
|
@ -75,6 +77,7 @@ import type { EmbeddedFile } from './main';
|
||||||
>[PEE contract]</a
|
>[PEE contract]</a
|
||||||
>
|
>
|
||||||
{/if}
|
{/if}
|
||||||
|
{/each}
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.clickable {
|
.clickable {
|
||||||
|
|
|
@ -61,4 +61,6 @@ div.hasext .catalog-host img {
|
||||||
|
|
||||||
.fileThumb.filehost {
|
.fileThumb.filehost {
|
||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
}
|
}
|
||||||
|
|
220
src/main.ts
220
src/main.ts
|
@ -12,7 +12,8 @@ import { GM_fetch, GM_head, headerStringToObject } from "./requests";
|
||||||
import App from "./App.svelte";
|
import App from "./App.svelte";
|
||||||
import ScrollHighlighter from "./ScrollHighlighter.svelte";
|
import ScrollHighlighter from "./ScrollHighlighter.svelte";
|
||||||
import SettingsButton from './SettingsButton.svelte';
|
import SettingsButton from './SettingsButton.svelte';
|
||||||
import Embedding from './Embedding.svelte';
|
//import Embedding from './Embedding.svelte';
|
||||||
|
import Embeddings from './Embeddings.svelte';
|
||||||
import EyeButton from './EyeButton.svelte';
|
import EyeButton from './EyeButton.svelte';
|
||||||
|
|
||||||
export interface ImageProcessor {
|
export interface ImageProcessor {
|
||||||
|
@ -82,41 +83,40 @@ type EmbeddedFileWithoutPreview = {
|
||||||
|
|
||||||
export type EmbeddedFile = EmbeddedFileWithPreview | EmbeddedFileWithoutPreview;
|
export type EmbeddedFile = EmbeddedFileWithPreview | EmbeddedFileWithoutPreview;
|
||||||
|
|
||||||
const processImage = async (src: string, fn: string, hex: string): Promise<[EmbeddedFile, boolean] | undefined> => {
|
const processImage = async (src: string, fn: string, hex: string): Promise<([EmbeddedFile, boolean] | undefined)[]> => {
|
||||||
const proc = processors.find(e => e.match(fn));
|
return Promise.all(processors.filter(e => e.match(fn)).map(async proc => {
|
||||||
if (!proc)
|
if (proc.skip) {
|
||||||
return;
|
// skip file downloading, file is referenced from the filename
|
||||||
if (proc.skip) {
|
// basically does things like filtering out blacklisted tags
|
||||||
// skip file downloading, file is referenced from the filename
|
const md5 = Buffer.from(hex, 'base64');
|
||||||
// basically does things like filtering out blacklisted tags
|
if (await proc.has_embed(md5, fn) === true)
|
||||||
const md5 = Buffer.from(hex, 'base64');
|
return [await proc.extract(md5, fn), true] as [EmbeddedFile, boolean];
|
||||||
if (await proc.has_embed(md5, fn) === true)
|
return;
|
||||||
return [await proc.extract(md5, fn), true];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const iter = streamRemote(src);
|
|
||||||
if (!iter)
|
|
||||||
return;
|
|
||||||
let cumul = Buffer.alloc(0);
|
|
||||||
let found: boolean | undefined;
|
|
||||||
let chunk: ReadableStreamDefaultReadResult<Buffer> = { done: true };
|
|
||||||
do {
|
|
||||||
const { value, done } = await iter.next(found === false);
|
|
||||||
if (done) {
|
|
||||||
chunk = { done: true } as ReadableStreamDefaultReadDoneResult;
|
|
||||||
} else {
|
|
||||||
chunk = { done: false, value } as ReadableStreamDefaultReadValueResult<Buffer>;
|
|
||||||
}
|
}
|
||||||
if (!done)
|
const iter = streamRemote(src);
|
||||||
cumul = Buffer.concat([cumul, value!]);
|
if (!iter)
|
||||||
found = await proc.has_embed(cumul);
|
return;
|
||||||
} while (found !== false && !chunk.done);
|
let cumul = Buffer.alloc(0);
|
||||||
await iter.next(false);
|
let found: boolean | undefined;
|
||||||
if (found === false) {
|
let chunk: ReadableStreamDefaultReadResult<Buffer> = { done: true };
|
||||||
//console.log(`Gave up on ${src} after downloading ${cumul.byteLength} bytes...`);
|
do {
|
||||||
return;
|
const { value, done } = await iter.next(found === false);
|
||||||
}
|
if (done) {
|
||||||
return [await proc.extract(cumul), false];
|
chunk = { done: true } as ReadableStreamDefaultReadDoneResult;
|
||||||
|
} else {
|
||||||
|
chunk = { done: false, value } as ReadableStreamDefaultReadValueResult<Buffer>;
|
||||||
|
}
|
||||||
|
if (!done)
|
||||||
|
cumul = Buffer.concat([cumul, value!]);
|
||||||
|
found = await proc.has_embed(cumul);
|
||||||
|
} while (found !== false && !chunk.done);
|
||||||
|
await iter.next(false);
|
||||||
|
if (found === false) {
|
||||||
|
//console.log(`Gave up on ${src} after downloading ${cumul.byteLength} bytes...`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return [await proc.extract(cumul), false] as [EmbeddedFile, boolean];
|
||||||
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
const textToElement = <T = HTMLElement>(s: string) =>
|
const textToElement = <T = HTMLElement>(s: string) =>
|
||||||
|
@ -127,81 +127,13 @@ const processPost = async (post: HTMLDivElement) => {
|
||||||
const origlink = post.querySelector('.file-info > a[target*="_blank"]') as HTMLAnchorElement;
|
const origlink = post.querySelector('.file-info > a[target*="_blank"]') as HTMLAnchorElement;
|
||||||
if (!thumb || !origlink)
|
if (!thumb || !origlink)
|
||||||
return;
|
return;
|
||||||
const res2 = await processImage(origlink.href,
|
let res2 = await processImage(origlink.href,
|
||||||
(origlink.querySelector('.fnfull') || origlink).textContent || '',
|
(origlink.querySelector('.fnfull') || origlink).textContent || '',
|
||||||
post.querySelector("[data-md5]")?.getAttribute('data-md5') || '');
|
post.querySelector("[data-md5]")?.getAttribute('data-md5') || '');
|
||||||
if (!res2)
|
res2 = res2?.filter(e => e);
|
||||||
|
if (!res2 || res2.length == 0)
|
||||||
return;
|
return;
|
||||||
const [res, external] = res2;
|
processAttachments(post, res2?.filter(e => e) as [EmbeddedFile, boolean][]);
|
||||||
const replyBox = post.querySelector('.post');
|
|
||||||
if (external)
|
|
||||||
replyBox?.classList.add('hasext');
|
|
||||||
else
|
|
||||||
replyBox?.classList.add('hasembed');
|
|
||||||
|
|
||||||
if (!cappState.foundPosts.includes(replyBox as HTMLElement))
|
|
||||||
cappState.foundPosts.push(replyBox as HTMLElement);
|
|
||||||
appState.set(cappState);
|
|
||||||
|
|
||||||
const isCatalog = replyBox?.classList.contains('catalog-post');
|
|
||||||
// add buttons
|
|
||||||
if (!isCatalog) {
|
|
||||||
const ft = post.querySelector('div.file') as HTMLDivElement;
|
|
||||||
const info = post.querySelector("span.file-info") as HTMLSpanElement;
|
|
||||||
|
|
||||||
const filehost: HTMLElement | null = ft.querySelector('.filehost');
|
|
||||||
const eyehost: HTMLElement | null = info.querySelector('.eyehost');
|
|
||||||
const imgcont = filehost || document.createElement('div');
|
|
||||||
const eyecont = eyehost || document.createElement('span');
|
|
||||||
|
|
||||||
if (!filehost) {
|
|
||||||
ft.append(imgcont);
|
|
||||||
imgcont.classList.add("fileThumb");
|
|
||||||
imgcont.classList.add("filehost");
|
|
||||||
} else {
|
|
||||||
imgcont.innerHTML = '';
|
|
||||||
}
|
|
||||||
if (!eyehost) {
|
|
||||||
info.append(eyecont);
|
|
||||||
eyecont.classList.add("eyehost");
|
|
||||||
} else {
|
|
||||||
eyecont.innerHTML = '';
|
|
||||||
}
|
|
||||||
const id = ~~(Math.random() * 20000000);
|
|
||||||
const emb = new Embedding({
|
|
||||||
target: imgcont,
|
|
||||||
props: {
|
|
||||||
file: res,
|
|
||||||
id: '' + id
|
|
||||||
}
|
|
||||||
});
|
|
||||||
new EyeButton({
|
|
||||||
target: eyecont,
|
|
||||||
props: {
|
|
||||||
file: res,
|
|
||||||
inst: emb,
|
|
||||||
id: '' + id
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const opFile = post.querySelector('.catalog-link');
|
|
||||||
const ahem = opFile?.querySelector('.catalog-host');
|
|
||||||
const imgcont = ahem || document.createElement('div');
|
|
||||||
imgcont.className = "catalog-host";
|
|
||||||
if (ahem) {
|
|
||||||
imgcont.innerHTML = '';
|
|
||||||
}
|
|
||||||
const emb = new Embedding({
|
|
||||||
target: imgcont,
|
|
||||||
props: {
|
|
||||||
file: res
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (!ahem)
|
|
||||||
opFile?.append(imgcont);
|
|
||||||
}
|
|
||||||
|
|
||||||
post.setAttribute('data-processed', "true");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const startup = async () => {
|
const startup = async () => {
|
||||||
|
@ -261,7 +193,7 @@ const getSelectedFile = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
//if (cappState!.is4chanX)
|
//if (cappState!.is4chanX)
|
||||||
document.addEventListener('4chanXInitFinished', startup);
|
document.addEventListener('4chanXInitFinished', startup);
|
||||||
/*else {
|
/*else {
|
||||||
document.addEventListener("QRGetFile", (e) => {
|
document.addEventListener("QRGetFile", (e) => {
|
||||||
const qr = document.getElementById('qrFile') as HTMLInputElement | null;
|
const qr = document.getElementById('qrFile') as HTMLInputElement | null;
|
||||||
|
@ -357,6 +289,78 @@ customStyles.appendChild(document.createTextNode(globalCss));
|
||||||
|
|
||||||
document.documentElement.insertBefore(customStyles, null);
|
document.documentElement.insertBefore(customStyles, null);
|
||||||
|
|
||||||
|
function processAttachments(post: HTMLDivElement, ress: [EmbeddedFile, boolean][]) {
|
||||||
|
const replyBox = post.querySelector('.post');
|
||||||
|
const external = ress[0][1];
|
||||||
|
if (external)
|
||||||
|
replyBox?.classList.add('hasext');
|
||||||
|
else
|
||||||
|
replyBox?.classList.add('hasembed');
|
||||||
|
|
||||||
|
if (!cappState.foundPosts.includes(replyBox as HTMLElement))
|
||||||
|
cappState.foundPosts.push(replyBox as HTMLElement);
|
||||||
|
appState.set(cappState);
|
||||||
|
|
||||||
|
const isCatalog = replyBox?.classList.contains('catalog-post');
|
||||||
|
// add buttons
|
||||||
|
if (!isCatalog) {
|
||||||
|
const ft = post.querySelector('div.file') as HTMLDivElement;
|
||||||
|
const info = post.querySelector("span.file-info") as HTMLSpanElement;
|
||||||
|
|
||||||
|
const filehost: HTMLElement | null = ft.querySelector('.filehost');
|
||||||
|
const eyehost: HTMLElement | null = info.querySelector('.eyehost');
|
||||||
|
const imgcont = filehost || document.createElement('div');
|
||||||
|
const eyecont = eyehost || document.createElement('span');
|
||||||
|
|
||||||
|
if (!filehost) {
|
||||||
|
ft.append(imgcont);
|
||||||
|
imgcont.classList.add("fileThumb");
|
||||||
|
imgcont.classList.add("filehost");
|
||||||
|
} else {
|
||||||
|
imgcont.innerHTML = '';
|
||||||
|
}
|
||||||
|
if (!eyehost) {
|
||||||
|
info.append(eyecont);
|
||||||
|
eyecont.classList.add("eyehost");
|
||||||
|
} else {
|
||||||
|
eyecont.innerHTML = '';
|
||||||
|
}
|
||||||
|
const id = ~~(Math.random() * 20000000);
|
||||||
|
const emb = new Embeddings({
|
||||||
|
target: imgcont,
|
||||||
|
props: {
|
||||||
|
files: ress.map(e => e[0]),
|
||||||
|
id: '' + id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
new EyeButton({
|
||||||
|
target: eyecont,
|
||||||
|
props: {
|
||||||
|
files: ress.map(e => e[0]),
|
||||||
|
inst: emb,
|
||||||
|
id: '' + id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const opFile = post.querySelector('.catalog-link');
|
||||||
|
const ahem = opFile?.querySelector('.catalog-host');
|
||||||
|
const imgcont = ahem || document.createElement('div');
|
||||||
|
imgcont.className = "catalog-host";
|
||||||
|
if (ahem) {
|
||||||
|
imgcont.innerHTML = '';
|
||||||
|
}
|
||||||
|
const emb = new Embeddings({
|
||||||
|
target: imgcont,
|
||||||
|
props: {
|
||||||
|
files: ress.map(e => e[0])
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!ahem)
|
||||||
|
opFile?.append(imgcont);
|
||||||
|
}
|
||||||
|
|
||||||
|
post.setAttribute('data-processed', "true");
|
||||||
|
}
|
||||||
//if ((window as any)['pagemode']) {
|
//if ((window as any)['pagemode']) {
|
||||||
// onload = () => {
|
// onload = () => {
|
||||||
// console.log("loaded");
|
// console.log("loaded");
|
||||||
|
|
|
@ -35,10 +35,6 @@ export const appState = writable({
|
||||||
foundPosts: [] as HTMLElement[]
|
foundPosts: [] as HTMLElement[]
|
||||||
});
|
});
|
||||||
|
|
||||||
appState.subscribe(v => {
|
|
||||||
console.log(v);
|
|
||||||
});
|
|
||||||
|
|
||||||
settings.subscribe(newVal => {
|
settings.subscribe(newVal => {
|
||||||
localSet('settings', newVal);
|
localSet('settings', newVal);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user