r34app gallery

Gallery view for results in https://r34.app

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name     r34app gallery
// @description Gallery view for results in https://r34.app
// @locale en
// @namespace r34app-gallery
// @version  1.4.1
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/jquery.magnific-popup.min.js
// @include https://r34.app/*
// ==/UserScript==

const styles = `
.mfp-bg{top:0;left:0;width:100%;height:100%;z-index:1042;overflow:hidden;position:fixed;background:#0b0b0b;opacity:0.95}.mfp-wrap{top:0;left:0;width:100%;height:100%;z-index:1043;position:fixed;outline:none !important;-webkit-backface-visibility:hidden}.mfp-container{text-align:center;position:absolute;width:100%;height:100%;left:0;top:0;padding:0 8px;box-sizing:border-box}.mfp-container:before{content:'';display:inline-block;height:100%;vertical-align:middle}.mfp-align-top .mfp-container:before{display:none}.mfp-content{position:relative;display:inline-block;vertical-align:middle;margin:0 auto;text-align:left;z-index:1045}.mfp-inline-holder .mfp-content,.mfp-ajax-holder .mfp-content{width:100%;cursor:auto}.mfp-ajax-cur{cursor:progress}.mfp-zoom-out-cur,.mfp-zoom-out-cur .mfp-image-holder .mfp-close{cursor:-moz-zoom-out;cursor:-webkit-zoom-out;cursor:zoom-out}.mfp-zoom{cursor:pointer;cursor:-webkit-zoom-in;cursor:-moz-zoom-in;cursor:zoom-in}.mfp-auto-cursor .mfp-content{cursor:auto}.mfp-close,.mfp-arrow,.mfp-preloader,.mfp-counter{-webkit-user-select:none;-moz-user-select:none;user-select:none}.mfp-loading.mfp-figure{display:none}.mfp-hide{display:none !important}.mfp-preloader{color:#CCC;position:absolute;top:50%;width:auto;text-align:center;margin-top:-0.8em;left:8px;right:8px;z-index:1044}.mfp-preloader a{color:#CCC}.mfp-preloader a:hover{color:#FFF}.mfp-s-ready .mfp-preloader{display:none}.mfp-s-error .mfp-content{display:none}button.mfp-close,button.mfp-arrow{overflow:visible;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;display:block;outline:0;padding:0;z-index:1046;box-shadow:none;touch-action:manipulation}button::-moz-focus-inner{padding:0;border:0}.mfp-close{width:44px;height:44px;line-height:44px;position:absolute;right:0;top:0;text-decoration:none;text-align:center;opacity:.65;padding:0 0 18px 10px;color:#FFF;font-style:normal;font-size:28px;font-family:Arial,Baskerville,monospace}.mfp-close:hover,.mfp-close:focus{opacity:1}.mfp-close:active{top:1px}.mfp-close-btn-in .mfp-close{color:#333}.mfp-image-holder .mfp-close,.mfp-iframe-holder .mfp-close{color:#FFF;right:-6px;text-align:right;padding-right:6px;width:100%}.mfp-counter{position:absolute;top:0;right:0;color:#CCC;font-size:12px;line-height:18px;white-space:nowrap}.mfp-arrow{position:absolute;opacity:.65;margin:0;top:50%;margin-top:-55px;padding:0;width:90px;height:110px;-webkit-tap-highlight-color:transparent}.mfp-arrow:active{margin-top:-54px}.mfp-arrow:hover,.mfp-arrow:focus{opacity:1}.mfp-arrow:before,.mfp-arrow:after{content:'';display:block;width:0;height:0;position:absolute;left:0;top:0;margin-top:35px;margin-left:35px;border:medium inset transparent}.mfp-arrow:after{border-top-width:13px;border-bottom-width:13px;top:8px}.mfp-arrow:before{border-top-width:21px;border-bottom-width:21px;opacity:.7}.mfp-arrow-left{left:0}.mfp-arrow-left:after{border-right:17px solid #FFF;margin-left:31px}.mfp-arrow-left:before{margin-left:25px;border-right:27px solid #3f3f3f}.mfp-arrow-right{right:0}.mfp-arrow-right:after{border-left:17px solid #FFF;margin-left:39px}.mfp-arrow-right:before{border-left:27px solid #3f3f3f}.mfp-iframe-holder{padding-top:40px;padding-bottom:40px}.mfp-iframe-holder .mfp-content{line-height:0;width:100%;max-width:900px}.mfp-iframe-holder .mfp-close{top:-40px}.mfp-iframe-scaler{width:100%;height:0;overflow:hidden;padding-top:56.25%}.mfp-iframe-scaler iframe{position:absolute;display:block;top:0;left:0;width:100%;height:100%;box-shadow:0 0 8px rgba(0,0,0,0.6);background:#000}img.mfp-img{width:auto;max-width:100%;height:auto;display:block;line-height:0;box-sizing:border-box;padding:40px 0 40px;margin:0 auto}.mfp-figure{line-height:0}.mfp-figure:after{content:'';position:absolute;left:0;top:40px;bottom:40px;display:block;right:0;width:auto;height:auto;z-index:-1;box-shadow:0 0 8px rgba(0,0,0,0.6);background:#444}.mfp-figure small{color:#bdbdbd;display:block;font-size:12px;line-height:14px}.mfp-figure figure{margin:0}.mfp-bottom-bar{margin-top:-36px;position:absolute;top:100%;left:0;width:100%;cursor:auto}.mfp-title{text-align:left;line-height:18px;color:#f3f3f3;word-wrap:break-word;padding-right:36px}.mfp-image-holder .mfp-content{max-width:100%}.mfp-gallery .mfp-image-holder .mfp-figure{cursor:pointer}@media screen and (max-width:800px) and (orientation:landscape),screen and (max-height:300px){.mfp-img-mobile .mfp-image-holder{padding-left:0;padding-right:0}.mfp-img-mobile img.mfp-img{padding:0}.mfp-img-mobile .mfp-figure:after{top:0;bottom:0}.mfp-img-mobile .mfp-figure small{display:inline;margin-left:5px}.mfp-img-mobile .mfp-bottom-bar{background:rgba(0,0,0,0.6);bottom:0;margin:0;top:auto;padding:3px 5px;position:fixed;box-sizing:border-box}.mfp-img-mobile .mfp-bottom-bar:empty{padding:0}.mfp-img-mobile .mfp-counter{right:5px;top:3px}.mfp-img-mobile .mfp-close{top:0;right:0;width:35px;height:35px;line-height:35px;background:rgba(0,0,0,0.6);position:fixed;text-align:center;padding:0}}@media all and (max-width:900px){.mfp-arrow{-webkit-transform:scale(0.75);transform:scale(0.75)}.mfp-arrow-left{-webkit-transform-origin:0 0;transform-origin:0 0}.mfp-arrow-right{-webkit-transform-origin:100%;transform-origin:100%}.mfp-container{padding-left:6px;padding-right:6px}}
`;

const otherStyles = `
  .r34-app-gallery-loader-info {
    position: fixed;
    z-index: 5000;
    bottom: 10px;
    right: 10px;
    text-size: 8px;
    color: white;
  }
  .r34-app-gallery-loader {
    position: fixed;
    z-index: 5000;
    bottom: 45px;
    right: 10px;
    width: 40px;
    height: 40px;
    display: none;
  }

  .r34-app-gallery-loader::after {
    content: " ";
    display: block;
    width: 36px;
    height: 36px;
    margin: 8px;
    border-radius: 50%;
    border: 6px solid #fff;
    border-color: #fff transparent #fff transparent;
    animation: lds-dual-ring 1.2s linear infinite;
  }

  .r34-app-gallery-loader.loading {
    display: block;
  }

  @keyframes lds-dual-ring {
    0% {
      transform: rotate(0deg);
    }
    100% {
      transform: rotate(360deg);
    }
  }
`;

var styleSheet = document.createElement("style");
styleSheet.innerText = styles;
document.head.appendChild(styleSheet);

var styleSheet2 = document.createElement("style");
styleSheet2.innerText = otherStyles;
document.head.appendChild(styleSheet2);

var initPlaySettingKey = "initPlay";
var playSpeedKey = "initPlaySpeed";
var initOpenKey = "initGalleryOpen";

var open = getSetting(initOpenKey || "false");
var isPlaying = getSetting(initPlaySettingKey);
var playSpeed = Number(getSetting(playSpeedKey) || 5000);
var playTimer = null;

var loading = document.createElement("div");
loading.classList.add("r34-app-gallery-loader");

document.body.appendChild(loading);

var info = document.createElement("div");
info.classList.add("r34-app-gallery-loader-info");
document.body.appendChild(info);

function startLoading() {
  loading.classList.add("loading");
}

function stopLoading() {
  loading.classList.remove("loading");
}

function updateInfo() {
  info.innerHTML = "Gallery " + (isPlaying === "true" ? "Playing" : "Pause") + " / Speed: " + playSpeed / 1000 + "s";
}

function setPlaySpeed(speed) {
  stop();
  var speedToSet = speed;
  if (speed < 1000) speedToSet = 1000;
  if (speed > 15000) speedToSet = 15000;
  setSetting(playSpeedKey, speedToSet.toString());
  playSpeed = speedToSet;
  play();
}

function playNext() {
  if ($.magnificPopup.instance.items.length - 1 === $.magnificPopup.instance.index) {
    movePage(1);
  } else {
    $.magnificPopup.instance.next();
  }
}

function play() {
  stop();

  isPlaying = "true";
  setSetting(initPlaySettingKey, "true");

  if (open != "true") {
    toggle();
  }

  playTimer = setInterval(function () {
    playNext();
  }, playSpeed);
}

function stop() {
  if (isPlaying === "false") return;

  isPlaying = "false";
  clearTimeout(playTimer);
  setSetting(initPlaySettingKey, "false");
}

function getImages() {
  return $("li img.w-full, li video");
}

function openGallery() {
  var images = getImages();
  var items = [];

  images.each(function () {
    var image = $(this);

    if (image.is("img")) {
      if (image.attr("alt") !== "Advertisement") {
        const src = image.attr('src');
        items.push({
          src: src,
          type: "image",
          title: image.attr("alt") || "",
        });
      }
    } else {
      items.push({
        src: image.attr('src'),
        type: "iframe",
      });
    }
  });
  

  $.magnificPopup.open(
    {
      items: items,
      gallery: {
        enabled: true,
      },
      image: {
        titleSrc: "title",
      },
    },
    0
  );

  open = "true";
  setSetting(initOpenKey, "true");
}

function closeGallery() {
  $.magnificPopup.close();
  open = "false";
  setSetting(initOpenKey, "false");
}

function toggle() {
  if (open === "true") {
    closeGallery();
    return;
  }

  openGallery();
}

var downloading = false;

function download(url, filename) {
  if (downloading) return;

  downloading = true;
  startLoading();

  fetch(url)
    .then((response) => response.blob())
    .then((blob) => {
      const link = document.createElement("a");
      link.href = URL.createObjectURL(blob);
      link.download = filename;
      link.click();
    })
    .catch(console.error)
    .finally(() => {
      downloading = false;
      stopLoading();
    });
}

function getImgUrl() {
  return $.magnificPopup.instance.currItem.src;
}

function getPage() {
  var searchParams = new URLSearchParams(window.location.search);
  const pageParam = searchParams.has("page") ? searchParams.get("page") : 0;
  return !Number.isNaN(Number(pageParam)) ? Number(pageParam) : 0;
}

function addParam(currentUrl, key, val) {
  var url = new URL(currentUrl);
  url.searchParams.set(key, val);
  return url.href;
}

function movePage(offset) {
  let page = getPage() + offset;
  if (page < 0) page = 0;
  window.location.href = addParam(window.location.href, "page", page);
}

function setSetting(setting, value) {
  localStorage.setItem(setting, value);
}

function getSetting(setting) {
  return localStorage.getItem(setting);
}

function canHandleKeyPress() {
  if (window.location.pathname === '/') return false;
  return true;
}

function init() {
  if (isPlaying === "true") {
    closeGallery();
    play();
  } else if (open === "true") {
    openGallery();
  }

  updateInfo();

  $(window).keypress(function (e) {   
    if (!canHandleKeyPress()) return;

    if (e.which == 53 || e.which == 115) {
      stop();
      // numeric 5
      toggle();
    } else if (e.which == 49 || e.which == 122) {
      // numeric 1
      movePage(-1);
    } else if (e.which == 51 || e.which == 99) {
      // numeric 2
      movePage(1);
    } else if (e.which == 56 || e.which == 119) {
      // numeric 8
      if (isPlaying === "true") {
        stop();
      } else {
        play();
      }
    } else if (e.which == 55 || e.which == 113) {
      // numeric 7
      setPlaySpeed(playSpeed + 1000);
    } else if (e.which == 57 || e.which == 101) {
      // numeric 9
      setPlaySpeed(playSpeed - 1000);
    }
    updateInfo();

    if (!open) return;

    if (e.which == 52 || e.which === 97) {
      // numeric 4
      $.magnificPopup.instance.prev();
    } else if (e.which == 54 || e.which == 100) {
      // numeric 6
      $.magnificPopup.instance.next();
    } else if (e.which == 50 || e.which == 120) {
      // numeric 2
      const url = getImgUrl();
      download(url, url.substring(url.lastIndexOf("/") + 1));
    }
  });
}

function checkIfImageExists() {
  var images = getImages();
  if (images.length === 0) {
    setTimeout(checkIfImageExists, 1000);
  } else {
    init();
  }
}

setTimeout(checkIfImageExists, 1000);