// ==UserScript== // @name Arcalive gallery view // @namespace http://tampermonkey.net/ // @version 1.02 // @description arcalive 게시글의 이미지를 미리보여줍니다. // @author You // @include /^https:\/\/arca\.live\/b\/([a-z]*)?([?&][a-z]=.*)*/ // @icon https://www.google.com/s2/favicons?sz=64&domain=arca.live // @grant none // @license MIT // @downloadURL none // ==/UserScript== //'use strict'; // /* 파라미터 */ const FETCH_DELAY = 60; const IMAGE_ATTACH_POSITION = "날짜"; // 어디에다 이미지를 붙일지 선택 ! [제목, 날짜 중에서] const WIDTH_THRESHOLD = 1800; // px단위. 이 px보다 커야 이미지미리보기가 발생한다 const SENSITIVE_WARN_IMG = false; // 민감성 포스팅 이미지 경고 표시유무 /* 사이트의 셀렉터 변경될 경우 수정하기 */ const TABLE_IMAGE_SELECTOR = ".article-content tbody img"; const VIDEO_SELECTOR = ".article-content video"; const IMAGE_SELECTOR = ".article-content img"; const ATTACH_TARGET_SELECTOR = ".vcol.col-title"; const ARTICLES_SELECTOR = ".vrow:not(.notice)"; const ARTICLES_WITHOUT_NOTICE_SELECTOR = ".article-list a.vrow.column"; /* 수정할 일 없음 */ const IMAGE_WIDTH_SMALL = 150; const IMAGE_WIDTH_NORMAL = 200; const IMAGE_WIDTH_LARGE = 300; const IMAGE_WIDTH = IMAGE_WIDTH_LARGE; function vrowToGallery($vrow){ const $title = $vrow.querySelector('.vcol.col-title'); console.log($title) $vrow.replaceChildren($title); } async function imageFetchAndAttach(vrow, delay) { // 이미지 페칭해서 붙임. await new Promise((r) => setTimeout(r, delay)); const response = await fetch(vrow.href); const text = await response.text(); const html = new DOMParser().parseFromString(text, "text/html"); const tableImage = html.querySelector(TABLE_IMAGE_SELECTOR); const video = html.querySelector(VIDEO_SELECTOR); let image; if(tableImage) { image = tableImage; } else if (video && video.width >300) { image = new Image(); image.src = video.poster; } else { const imageCandidates = html.querySelectorAll(IMAGE_SELECTOR); image = Array.from(imageCandidates).find(image=>SENSITIVE_WARN_IMG || !(image.width===1000 && image.height===667)) ?? new Image(300, 300); } fitImageSizeAndAlter(image); const target = vrow.querySelector(ATTACH_TARGET_SELECTOR); if (target) { target.style.width = `${IMAGE_WIDTH}px`; target.before(image); } vrow.style.display='inline-flex'; vrow.style.flexDirection='column'; vrow.style.width=`${IMAGE_WIDTH}px` console.log("fetched"); } function fitImageSizeAndAlter(image) { const aspectRatio = image.height / image.width; image.style.display = 'block'; image.style.width = `${IMAGE_WIDTH}px`; image.style.height = `${aspectRatio * IMAGE_WIDTH}px`; } function moveImageWithMark(vrow, image) { const brTag = document.createElement("span"); let dest; switch (IMAGE_ATTACH_POSITION) { case "제목": dest = vrow.querySelector(".title"); dest.append(brTag, image); dest.prepend(mark); break; case "날짜": dest = vrow.querySelector(".col-time"); dest.prepend(image); image.append(brTag); break; } } let originalMediaWidth = getOriginalMediaWidth2(); const originalContentWrapper = getContentWrapperCloned(); let changedContentWrapper; let timer = null; function arcaliveDualMode() { if (window.innerWidth > 100) { removeRightSidebar(); extendContentWrapper(); moveHalfArticlesToRightPlane(); restoreMediaSize2(); changedContentWrapper = getContentWrapper(); changedContentWrapper.after(originalContentWrapper); applyIfWidthSufficient(); console.log("dualmode end"); } } function applyIfWidthSufficient() { if (window.innerWidth > WIDTH_THRESHOLD) { originalContentWrapper.style.display = "none"; originalContentWrapper.querySelector(".right-sidebar").style.display = "none"; changedContentWrapper.style.display = "block"; changedContentWrapper.querySelector(".right-sidebar").style.display = "none"; } else { originalContentWrapper.style.display = "block"; let originalSidebar = originalContentWrapper.querySelector(".right-sidebar"); originalSidebar.style.display = "block"; for (const el of originalSidebar.children) { el.style.display = "block"; } // TODO: Display Sidebar As small size. changedContentWrapper.style.display = "none"; changedContentWrapper.querySelector(".right-sidebar").style.display = "none"; } } function getOriginalMediaWidth() { let image = document.querySelector(".fr-view.article-content img"); let video = document.querySelector(".fr-view.article-content video"); const width = image?.offsetWidth ?? video?.offsetWidth ?? null; return width; } function getOriginalMediaWidth2() { const images = document.querySelectorAll(".fr-view.article-content img"); const videos = document.querySelectorAll(".fr-view.article-content video"); const widths = { image: [], video: [] }; images?.forEach((el) => widths.image.push(el.offsetWidth)); videos?.forEach((el) => widths.video.push(el.offsetWidth)); return widths; } function getContentWrapperCloned() { return getContentWrapper().cloneNode(true); } function getContentWrapper() { return document.querySelector(".content-wrapper.clearfix"); } function removeRightSidebar() { document.querySelector(".right-sidebar").style.display = "none"; } function extendContentWrapper() { const contentWrapper = document.querySelector(".content-wrapper.clearfix"); contentWrapper.style = "margin:0 5rem 0;max-width:100%"; const containerBoard = document.querySelector(".containe-fluid.board-article"); containerBoard.style = "margin:0"; } function moveHalfArticlesToRightPlane() { let articleListLeft; let articleListRight; let articleTableRight; cloneArticleListToRight(); styleBothAriticleLists(); moveHalfToRightPlane(); function cloneArticleListToRight() { articleListLeft = document.querySelector(".article-list"); articleListRight = articleListLeft.cloneNode(true); articleTableRight = articleListRight.querySelector(".list-table"); const removeArticle = (el) => el.tagName == "A" && el.remove(); articleTableRight.childNodes.forEach(removeArticle); } function styleBothAriticleLists() { articleListLeft.after(articleListRight); articleListLeft.style = "margin:5 0rem 0 0;float:left;width:49%;"; articleListRight.style = "margin:5 0rem 0 0;float:right;width:49%;"; } function moveHalfToRightPlane() { let articles = articleListLeft.querySelectorAll("a.vrow"); const totalHeight = Array.from(articles).reduce((acc, el, i) => acc + el.offsetHeight, 0); console.log(`totalHeight : ${totalHeight}px`); let height = 0; for (const article of articles) { height += article.offsetHeight; if (height > (totalHeight + article.offsetHeight) / 2) articleTableRight.append(article); } } } function restoreMediaSize2() { let images = document.querySelectorAll(".fr-view.article-content img"); let videos = document.querySelectorAll(".fr-view.article-content video"); images.forEach(function (el, i) { el.style.width = `${originalMediaWidth.image[i]}px`; }); videos.forEach(function (el, i) { el.style.width = `${originalMediaWidth.video[i]}px`; }); } async function start() { const $table = document.querySelector("body > div.root-container > div.content-wrapper.clearfix > article > div > div.article-list > div.list-table.table"); $table.style.display = 'flex'; $table.style.flexWrap = 'wrap'; $table.style.gap = '5px'; extendContentWrapper() const vrows = document.querySelectorAll(ARTICLES_SELECTOR); vrows.forEach(vrow=>vrowToGallery(vrow)); const vrowsPromiseArray = Array.from(vrows).map((vrow, i) => imageFetchAndAttach(vrow, i *FETCH_DELAY)); const articles = document.querySelectorAll(ARTICLES_WITHOUT_NOTICE_SELECTOR); articles.forEach((article) => { article.style = "height: auto !important"; }); Promise.all(vrowsPromiseArray); } addEventListener("load", setTimeout(start, 0));