Telegraph图片浏览器

Telegraph图片浏览增强

// ==UserScript==
// @name         Telegraph图片浏览器
// @license      MIT
// @namespace    http://tampermonkey.net/
// @version      1.0.0
// @description  Telegraph图片浏览增强
// @author       montaro2018
// @match        https://telegra.ph/*
// @exclude      https://telegra.ph/
// @icon         https://www.google.com/s2/favicons?sz=64&domain=telegra.ph
// @resource     https://cdnjs.cloudflare.com/ajax/libs/webfonts/fa-solid-900.woff2
// @resource  fa https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/css/all.min.css
// @require      https://unpkg.com/vue@3/dist/vue.global.js
// @grant        unsafeWindow
// @grant        GM_addStyle
// @grant        GM_getResourceText
// @run-at       document-idle
// ==/UserScript==


const excludeUrl = "https://telegra.ph/";

unsafeWindow.Vue = Vue;

init();

function init() {
    injectStyle();
    createWrapper();
    var title = getTitle();
    var urls = getImageUrls();
    createVue(urls, title);
}

function injectStyle() {
    var fa = GM_getResourceText("fa");
    fa = fa.replaceAll("../webfonts", "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/webfonts");
    GM_addStyle(fa);
    GM_addStyle(`
  .tl_page_wrap {
    display:none;
  }
  #app {
    left: 0;
    top: 0;
    z-index: 99;
    position: absolute;
    width:100%;
    min-height: 100vh;
  }
.photo-viewer {
    background-color: #000;
}

.photo-viewer-header,
.photo-viewer-footer {
    height: 40px;
    display: flex;
    justify-content: center;
    line-height: 40px;
    background-color: #383838;
}

.photo-viewer-header,
.photo-viewer-content,
.photo-viewer-footer {
    color: #fff;
    text-align: center;
}

.photo-viewer-click-left,
.photo-viewer-click-right {
  top: 0;
  left: 0;
  width:50%;
  height: 100%;
  z-index: 99999;
  position: absolute;
}
.photo-viewer-click-right{
  left: 50%;
}

.photo-viewer-content {
    font-size: 0;
    position: relative;
    min-height: calc(100vh - 80px);
}

.photo-viewer-content img {
    max-height: calc(100vh - 80px);
    max-width: 100%;
}

.photo-viewer-btn {
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.photo-viewer-counter {
    padding: 0 15px;
}

.photo-viewer-btn:hover {
    cursor: pointer;
    background-color: #525252;
}`);
}

function createWrapper() {
    var app = document.createElement("div");
    app.id = "app";
    document.body.appendChild(app);
}

function getTitle() {
    console.log(document.innerHTML);
    return document.querySelector(".tl_article_header h1").innerText;
}

function getImageUrls() {
    var urls = [];
    var imgs = document.querySelectorAll(".figure_wrapper img");
    imgs.forEach(img => {
        urls.push(img.src);
    })
    return urls;
}

function createVue(urls, title) {
    const { createApp, ref, computed, watch, onMounted } = Vue;
    const app = createApp({
        template: `<photo-viewer :urls="urls" :title="title"/>`,
        setup() {
            return { urls: ref(urls), title: ref(title) };
        }
    });

    app.component(
        "PhotoViewer",
        {
            props: {
                "urls": Array,
                "title": String
            },
            template: `<div class="photo-viewer">
          <div class="photo-viewer-header">{{title}}</div>
          <div class="photo-viewer-content" ref="content">
            <div class="photo-viewer-click-left" @click.stop="clickLeft"></div>
            <div class="photo-viewer-click-right" @click.stop="clickRight"></div>
          </div>
          <div class="photo-viewer-footer">
              <div class="photo-viewer-btn photo-viewer-first" @click="first">
                  <i class="fa fa-chevron-left"></i><i class="fa fa-chevron-left"></i>
              </div>
              <div class="photo-viewer-btn photo-viewer-backword" @click="prev">
                  <i class="fa fa-chevron-left"></i>
              </div>
              <div class="photo-viewer-counter">{{counter}}</div>
              <div class="photo-viewer-btn photo-viewer-forward" @click="next">
                  <i class="fa fa-chevron-right"></i>
              </div>
              <div class="photo-viewer-btn photo-viewer-last" @click="last">
                  <i class="fa fa-chevron-right"></i><i class="fa fa-chevron-right"></i>
              </div>
          </div>
      </div>`,
        setup() {
            const currentIndex = ref(0);

            const imgs = ref(urls.map(url => {
                var img = document.createElement("img");
                img.src = url;
                return img;
            }));

            const img = computed(() => {
                return imgs.value[currentIndex.value];
            });

            watch(img, (newImg, oldImg) => {
                if (oldImg != null) {
                    oldImg.remove();
                }
                content.value.appendChild(newImg);
            })

            const total = computed(() => {
                return urls.length;
            })

            const counter = computed(() => {
                return `${currentIndex.value + 1}/${total.value}`
        });

          const content = ref(null);

          const url = computed(() => {
              return urls[currentIndex.value];
          });

          const first = function () {
              currentIndex.value = 0;
          }
          const last = function () {
              if (total.value > 0) {
                  currentIndex.value = total.value - 1;
              }
          }
          const prev = function () {
              if (currentIndex.value > 0) {
                  currentIndex.value--;
              }
          }
          const next = function () {
              if (currentIndex.value < total.value - 1) {
                  currentIndex.value++;

              }
          }
          const clickLeft = function (e) {
              prev();
          }
          const clickRight = function (e) {
              next();
          }

          onMounted(() => {
              document.addEventListener("keydown", e => {
                  if (e.key == "ArrowRight") {
                      next();
                  } else if (e.key == "ArrowLeft") {
                      prev();
                  }
              });
              content.value.appendChild(img.value);
          })
          return { imgs, img, currentIndex, counter, url, first, last, prev, next, clickLeft, clickRight, content };
      }
    }
  );
    app.mount("#app");
}