Greasy Fork

Greasy Fork is available in English.

哔哩哔哩番剧出差助手

为动态页面增加显示哔哩哔哩番剧出差动态功能

当前为 2021-07-13 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         哔哩哔哩番剧出差助手
// @namespace    bilibili_abroad_assistant
// @version      1.0.1
// @description  为动态页面增加显示哔哩哔哩番剧出差动态功能
// @author       溶酶菌
// @match        *://t.bilibili.com*
// @match        *://t.bilibili.com/*
// @icon         https://www.bilibili.com/favicon.ico
// @grant        none
// ==/UserScript==
(function () {
  'use strict';
  let loaded = false // 是否已加载
  let showBtn = () => document.querySelector('#show-abroad')
  let hideBtn = () => document.querySelector('#hide-abroad')
  let backtop = () => document.querySelector("#app > div > div.home-page.f-clear > div.back-top").click()
  let centerPanel = () => document.querySelector("#app > div > div.home-page.f-clear > div.home-container > div > div.center-panel")
  let cardList = () => document.querySelector("#app > div > div.home-page.f-clear > div.home-container > div > div.center-panel > div.card-list")
  let left = () => document.querySelector("#app > div > div.home-page.f-clear > div.home-container > div > div.left-panel > div.adaptive-scroll > div.scroll-content")
  let dynamicsPanel = () => document.querySelector('#dynamics-panel')
  let loadMoreBtn = () => document.querySelector('#load-more-btn')
  let loadingTips = () => document.querySelector('#loading-tips')
  let offset = ''
  let dateFormat = (fmt, date) => {
    let ret;
    const opt = {
      "Y+": date.getFullYear().toString(),        // 年
      "m+": (date.getMonth() + 1).toString(),     // 月
      "d+": date.getDate().toString(),            // 日
      "H+": date.getHours().toString(),           // 时
      "M+": date.getMinutes().toString(),         // 分
      "S+": date.getSeconds().toString()          // 秒
      // 有其他格式化字符需求可以继续添加,必须转化成字符串
    };
    for (let k in opt) {
      ret = new RegExp("(" + k + ")").exec(fmt);
      if (ret) {
        fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
      };
    };
    return fmt;
  }
  let loadData = function () {
    loadingTips().style.display = 'inline'
    loadMoreBtn().style.display = 'none'
    fetch(`https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/w_dyn_personal?host_uid=11783021&offset=${offset}`, {
      method: 'GET',
      credentials: 'include'
    }).then(res => res.json())
      .then(res => {
        offset = res.data.offset
        loadingTips().style.display = 'none'
        loadMoreBtn().style.display = 'inline'
        res.data.cards.forEach(card => {
          let face = card.desc.user_profile.info.face
          let uname = card.desc.user_profile.info.uname
          let action = card.display.usr_action_txt
          let timestamp = new Date(card.desc.timestamp * 1e3) // s -> ms
          let vCard = JSON.parse(card.card)
          let { pic, redirect_url, title } = vCard
          let { coin, danmaku, dislike, favorite, his_rank, like, now_rank, reply, share, view } = vCard.stat
          let itemDom = `<div data-v-60a2097c="" data-did="546051838395596670" class="card" style="margin-bottom: 8px;">
          <a data-v-60a2097c="" target="_blank" class="user-head c-pointer" href="https://space.bilibili.com/11783021/dynamic" style="background-image: url(&quot;${face}@48w_48h.webp&quot;); border-radius: 12px;"></a>
          <div data-v-60a2097c="" class="main-content" style="padding-bottom: 0px;"><a data-v-60a2097c="" href="//bangumi.bilibili.com/anime/timeline" target="_blank" class="d-i-block type-label c-pointer">番剧</a>
          <div data-v-60a2097c="" class="user-name fs-16 ls-0 d-i-block"><a data-v-60a2097c="" href="https://space.bilibili.com/11783021/dynamic" target="_blank" class="c-pointer">${uname}</a></div>
          <div data-v-60a2097c="" class="time fs-12 ls-0 tc-slate"><span data-v-60a2097c="">${dateFormat('YYYY-mm-dd HH:MM:SS', timestamp)}</span><span data-v-60a2097c=""> ${action}</span></div><div data-v-5bc56d64="" data-v-60a2097c="" class="card-content">
          <div data-v-5bc56d64="" data-ori-did="0" class="post-content"><div data-v-5bc56d64="" class="original-card-content"><div data-v-6d8fee64="" data-v-5bc56d64="" class="bangumi-container can-hover">
          <a data-v-2b044bfb="" data-v-6d8fee64="" target="_blank" href="${redirect_url}"><div data-v-6d8fee64="" data-v-2b044bfb="">
          <div data-v-6d8fee64="" data-v-2b044bfb="" class="image-area">
          <img data-v-6d8fee64="" data-v-2b044bfb="" src="${pic}@203w_127h_1e_1c.webp">
          <div data-v-6d8fee64="" data-v-2b044bfb="" class="tag">番剧</div></div><div data-v-6d8fee64="" data-v-2b044bfb="" class="text-area"><div data-v-6d8fee64="" data-v-2b044bfb="" class="title">${title}</div>
          <div data-v-6d8fee64="" data-v-2b044bfb="" class="content"></div><div data-v-6d8fee64="" data-v-2b044bfb="" class="view-danmaku"><div data-v-6d8fee64="" data-v-2b044bfb="">
          <i data-v-6d8fee64="" data-v-2b044bfb="" class="bp-icon-font icon-play-a"></i><span data-v-6d8fee64="" data-v-2b044bfb="" class="view">${view}</span></div><div data-v-6d8fee64="" data-v-2b044bfb="">
          <i data-v-6d8fee64="" data-v-2b044bfb="" class="bp-icon-font icon-danmu-a"></i><span data-v-6d8fee64="" data-v-2b044bfb="" class="danmaku">${danmaku}</span></div></div></div></div></a></div>
          </div></div><div data-v-5bc56d64=""></div></div><div data-v-60a2097c="" class="button-bar tc-slate"><div data-v-60a2097c="" class="single-button c-pointer">
          <span data-v-60a2097c="" class="text-bar"><i data-v-60a2097c="" class="bp-svg-icon single-icon transmit"></i><span data-v-60a2097c="" class="text-offset">
            ${share}
          </span></span></div><div data-v-60a2097c="" class="single-button c-pointer"><span data-v-60a2097c="" class="text-bar"><i data-v-60a2097c="" class="bp-svg-icon single-icon comment"></i><span data-v-60a2097c="" class="text-offset">
            ${reply}
          </span></span></div><div data-v-60a2097c="" class="single-button c-pointer p-rel"><span data-v-60a2097c="" class="text-bar"><i data-v-60a2097c="" class="custom-like-icon zan"></i><span data-v-60a2097c="" class="text-offset">${like}</span></span>
          </div></div></div><div data-v-60a2097c="" class="panel-area" style="display: none;"></div></div>`
          let cardWrap = document.createElement('div')
          cardWrap.innerHTML = itemDom
          dynamicsPanel().append(cardWrap)
        });

      });
  }

  let start = () => {
    if (!centerPanel()) {
      return
    }
    let dynamicsPanel = document.createElement('div')
    dynamicsPanel.id = 'dynamics-panel'
    dynamicsPanel.style.display = 'none'
    dynamicsPanel.style.marginTop = '8px'
    centerPanel().append(dynamicsPanel)

    let loadMorePanel = document.createElement('div')
    loadMorePanel.style.display = 'none'
    loadMorePanel.style.marginBottom = '8px'
    loadMorePanel.innerHTML = `<div style="text-align: center;border-radius: 4px;padding: 16px;background: #FFF;color: #00b5e5">
    <span id="load-more-btn" style="cursor: pointer;">加载更多</span>
    <span id="loading-tips" style="display: none;cursor: pointer;">正在加载...</span>
    </div>`
    centerPanel().append(loadMorePanel)

    let actionbar = document.createElement('div')
    actionbar.innerHTML =
      `<div style="margin-top: 8px;border-radius: 4px;position: sticky;top: 8px;background: #FFF;padding: 16px;display: flex;">
        <div class="avatar" style="box-shadow: 0 0 0 1px #f25d8e;border-radius: 22px;height: 38px;width:38px;background-size: 38px 38px;background-image: url(&quot;https://i0.hdslb.com/bfs/face/9f10323503739e676857f06f5e4f5eb323e9f3f2.jpg@96w_96h_100Q_1c.webp&quot;);"></div>
        <div style="margin-left: 11px;">
          <div>哔哩哔哩番剧出差</div>
          <div style="margin-top: 4px;font-size: 12px;color: #00b5e5">
            <span id="show-abroad" style="cursor: pointer">显示</span><span id="hide-abroad" style="cursor: pointer;display: none">隐藏</span>
          </div>
        </div>
    </div>`

    left().append(actionbar)

    let toggleMode = (show = true) => {
      showBtn().style.display = show ? 'none' : 'inline'
      hideBtn().style.display = show ? 'inline' : 'none'
      cardList().style.display = show ? 'none' : 'block'
      dynamicsPanel.style.display = show ? 'block' : 'none'
      loadMorePanel.style.display = show ? 'block' : 'none'
      backtop()
    }

    showBtn().onclick = () => {
      toggleMode(true)
      if (!loaded) {
        loadData()
        loaded = true
      }
    }
    hideBtn().onclick = () => {
      toggleMode(false)
    }

    loadMoreBtn().onclick = loadData
  }

  let sleep = function (time) {
    return new Promise((resolve) => setTimeout(resolve, time));
  };

  // 延迟执行,否则可能找不到对应的DOM
  sleep(500).then(() => {
    console.log('哔哩哔哩番剧出差助手运行')
    start()
  })
})();