Created
October 10, 2020 14:41
-
-
Save MaxMatti/7c4375c5fa956c3aebed5e9f84619b33 to your computer and use it in GitHub Desktop.
[WIP] Creates an overlay for https://boards.4chan.org/wg/catalog to display and scroll through all posted images above a certain resolution.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name WG-Viewer | |
// @namespace http://tampermonkey.net/ | |
// @version 0.1 | |
// @description view images above a certain resolution | |
// @author Max Staff <[email protected]> | |
// @match https://boards.4chan.org/wg/catalog | |
// @grant GM.xmlHttpRequest | |
// ==/UserScript== | |
var minWidth = 3500; | |
var minHeight = 2000; | |
var previewImageCount = 5; | |
var mainImageDisplaySize = 10; | |
var threads = []; | |
var images = []; | |
var displayImages = {}; | |
var imagePos = 0; | |
var displayContainer; | |
var displayNextBtn; | |
var displayPrevBtn; | |
var styleString = ` | |
div#displayContainer { | |
position: fixed; | |
margin: 5%; | |
padding: 10px; | |
top: 0; | |
right: 0; | |
bottom: 0; | |
left: 0; | |
background-color: #000000; | |
display: grid; | |
grid-template-columns: [left] repeat(` + previewImageCount + `, 1fr) [center] repeat(` + previewImageCount + `, 1fr) [right]; | |
grid-template-rows: ` + mainImageDisplaySize + `fr 1fr auto auto; | |
column-gap: 10px; | |
row-gap: 10px; | |
transition: 0.2s; | |
} | |
img.displayMainImage { | |
grid-row: 1; | |
grid-column-start: left; | |
grid-column-end: right; | |
object-fit: cover; | |
max-height: 100%; | |
max-width: 100%; | |
place-self: center; | |
transition: 0.2s; | |
} | |
img.displayPreviewImage { | |
grid-row: 2; | |
object-fit: cover; | |
max-height: 100%; | |
max-width: 100%; | |
place-self: center; | |
opacity: 0; | |
cursor: pointer; | |
transition: 0.2s; | |
} | |
button#displayPrevBtn { | |
grid-row: 3; | |
grid-column-start: left; | |
grid-column-end: center; | |
} | |
button#displayNextBtn { | |
grid-row: 3; | |
grid-column-start: center; | |
grid-column-end: right; | |
} | |
button#ballernBtn { | |
grid-row: 4; | |
grid-column-start: left; | |
grid-column-end: right; | |
} | |
`; | |
var previewImageSvg = "data:image/svg+xml,%3C%3Fxml version='1.0' encoding='utf-8'%3F%3E%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' style='margin: auto; display: block; shape-rendering: auto;' width='200px' height='200px' viewBox='0 0 100 100' preserveAspectRatio='xMidYMid'%3E%3Ccircle cx='50' cy='50' r='32' stroke-width='8' stroke='%23e15b64' stroke-dasharray='50.26548245743669 50.26548245743669' fill='none' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' dur='1s' repeatCount='indefinite' keyTimes='0;1' values='0 50 50;360 50 50'%3E%3C/animateTransform%3E%3C/circle%3E%3Ccircle cx='50' cy='50' r='23' stroke-width='8' stroke='%23f8b26a' stroke-dasharray='36.12831551628262 36.12831551628262' stroke-dashoffset='36.12831551628262' fill='none' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' dur='1s' repeatCount='indefinite' keyTimes='0;1' values='0 50 50;-360 50 50'%3E%3C/animateTransform%3E%3C/circle%3E%3C/svg%3E"; | |
function handleNextThread() { | |
var thread = threads.pop(); | |
var req = GM.xmlHttpRequest({ | |
method: "GET", | |
url: "https://a.4cdn.org/wg/thread/" + thread + ".json", | |
onload: function(response) { | |
var content = JSON.parse(response.responseText); | |
for (var i = 0; i < content.posts.length; ++i) { | |
content.posts[i]; | |
if ("tim" in content.posts[i] && "ext" in content.posts[i] && "w" in content.posts[i] && "h" in content.posts[i] && content.posts[i].w > minWidth && content.posts[i].h > minHeight) { | |
images.push("https://i.4cdn.org/wg/" + content.posts[i].tim + content.posts[i].ext); | |
} | |
} | |
updateImages(); | |
console.log("Thread done: " + thread); | |
window.setTimeout(handleNextThread, 1000); | |
} | |
}); | |
} | |
function buttonClicked(e) { | |
var req = GM.xmlHttpRequest({ | |
method: "GET", | |
url: "https://a.4cdn.org/wg/threads.json", | |
onload: function(response) { | |
var content = JSON.parse(response.responseText); | |
for (var i = 0; i < content.length; ++i) { | |
for (var j = 0; j < content[i].threads.length; ++j) { | |
threads.push(content[i].threads[j].no); | |
} | |
} | |
window.setTimeout(handleNextThread, 1000); | |
} | |
}); | |
} | |
function nextImage(e) { | |
if (images.length == 0) { | |
return; | |
} | |
++imagePos; | |
if (imagePos >= images.length) { | |
imagePos = 0; | |
} | |
updateImages(); | |
} | |
function prevImage(e) { | |
if (images.length == 0) { | |
return; | |
} | |
--imagePos; | |
if (imagePos <= 0) { | |
imagePos = images.length - 1; | |
} | |
updateImages(); | |
} | |
function updateImages() { | |
if (images.length == 0) { | |
return; | |
} | |
for (var i = 0; i < previewImageCount * 2 + 1; ++i) { | |
var src = images[(imagePos - previewImageCount + i + images.length) % images.length]; | |
if (!(src in displayImages)) { | |
var img = document.createElement("img"); | |
img.src = src; | |
img.addEventListener("click", clickPreviewImage, true); | |
img.addEventListener("load", previewImageLoaded, true); | |
displayImages[src] = img; | |
} | |
displayImages[src].className = (i == previewImageCount) ? "displayMainImage" : "displayPreviewImage"; | |
displayContainer.appendChild(displayImages[src]); | |
} | |
for (i = 0; i < displayContainer.children.length; ++i) { | |
if (displayContainer.children[i].className != "displayPreviewImage") { | |
continue; | |
} | |
src = displayContainer.children[i].src; | |
if (Math.abs(imagePos - images.indexOf(src)) > previewImageCount) { | |
displayContainer.removeChild(displayContainer.children[i]); | |
} | |
} | |
} | |
function previewImageLoaded(e) { | |
e.currentTarget.style.opacity = 1; | |
} | |
function clickPreviewImage(e) { | |
if (images.length == 0) { | |
return; | |
} | |
imagePos = images.indexOf(e.currentTarget.src); | |
if (imagePos < 0 || imagePos >= images.length) { | |
imagePos = 0; | |
} | |
updateImages(); | |
} | |
function handleKeyPress(e) { | |
if (e.code == "ArrowRight") { | |
nextImage(e); | |
} else if (e.code == "ArrowLeft") { | |
prevImage(e); | |
} else { | |
console.log(e.code); | |
} | |
} | |
function load(e) { | |
if (document.getElementById("ballernBtn")) { | |
return; | |
} | |
document.addEventListener('keydown', handleKeyPress, true); | |
var style = document.createElement("style"); | |
style.type = "text/css"; | |
style.innerHTML = styleString; | |
document.head.appendChild(style); | |
displayContainer = document.createElement("div"); | |
displayContainer.id = "displayContainer"; | |
displayPrevBtn = document.createElement("button"); | |
displayPrevBtn.id = "displayPrevBtn"; | |
displayPrevBtn.innerHTML = "<"; | |
displayPrevBtn.addEventListener("click", prevImage, true); | |
displayNextBtn = document.createElement("button"); | |
displayNextBtn.id = "displayNextBtn"; | |
displayNextBtn.innerHTML = ">"; | |
displayNextBtn.addEventListener("click", nextImage, true); | |
var ballernBtn = document.createElement("button"); | |
ballernBtn.id = "ballernBtn"; | |
ballernBtn.innerHTML = "load images"; | |
ballernBtn.addEventListener("click", buttonClicked, true); | |
displayContainer.appendChild(displayPrevBtn); | |
displayContainer.appendChild(displayNextBtn); | |
displayContainer.appendChild(ballernBtn); | |
document.body.appendChild(displayContainer); | |
} | |
(function() { | |
'use strict'; | |
document.addEventListener("load", load, true); | |
// Your code here... | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment