pxoxq / Bilibili剧场版播放

// ==UserScript==
// @name         Bilibili剧场版播放
// @namespace    https://greasyfork.org/zh-CN/users/1129769-pxoxq
// @version      0.2
// @description  B站播放器剧场模式
// @author       pxoxq
// @license      AGPL-3.0-or-later
// @copyright 2023, pxoxq (https://openuserjs.org/users/pxoxq)
// @match        https://www.bilibili.com/
// @match        https://www.bilibili.com/?*
// @match        https://www.bilibili.com/video/**
// @match        https://www.bilibili.com/list/**
// @icon         https://www.bilibili.com/favicon.ico
// @grant        GM_addElement
// @grant        GM_addStyle
// @grant        window.onurlchange
// @require      https://scriptcat.org/lib/513/2.0.0/ElementGetter.js
// @require      https://code.jquery.com/jquery-3.7.1.min.js
// @updateURL https://openuserjs.org/meta/pxoxq/Bilibili剧场版播放.meta.js
// @downloadURL https://openuserjs.org/install/pxoxq/Bilibili剧场版播放.user.js
// ==/UserScript==

const BWidePlayerGolbalConf = {
  darkMode: false,
  wideModeDefault: true, // 默认宽屏
  shadowColers: {
    dark: ['#d3d4d5', '#818283'],
    white: ['#E3E5E7', '#F1F2F3']
  },
  indexBgDarkColor: '#22222B',
  indexBgColor: 'white',
  globalDarkClr: '#22222B',
  wideModePlayerHeight: 700,

  styles: {
    globalPrettify: ``,
    widePlayerStyles: ``,
  }
}

function bWidePlayerFlushStyle() {
  BWidePlayerGolbalConf.styles.widePlayerStyles = `
  .bpx-player-ctrl-wide{
    width:0px;
  }
  #wide-box::-webkit-scrollbar{
    display:none;
  }
  #wide-box, html{
  scrollbar-width:none;
  }
  #wide-box .mini-header__logo path{
    fill: #fb7299;
  }
  #wide-box #bilibili-player{
    width: 100vw !important;
  }
  #wide-box #playerWrap{
    order: -1;
    height: ${BWidePlayerGolbalConf.wideModePlayerHeight}px;
  }
  #wide-box #bilibili-player{
    height:${BWidePlayerGolbalConf.wideModePlayerHeight}px;
    position:relative;
  }
  /*右侧悬浮列表*/
  #wide-box #bilibili-player #reco_list,
  #wide-box #bilibili-player #multi_page,
  #wide-box #bilibili-player .base-video-sections-v1,
  #wide-box #bilibili-player .action-list-container{
    position:absolute;
    top:25px;
    right:0px;
    background-color: #f1f2f3d6;
    overflow: hidden;
    transition: all .28s linear;
    border: 1px solid #1F1F1F;
    width: 14px;
    height: 400px;
    opacity: 0.26;
    z-index: 999;
  }
  
  #wide-box #bilibili-player .base-video-sections-v1:hover{
    width: 280px;
    height: auto;
    opacity: 1;
  }
  #wide-box #bilibili-player .base-video-sections-v1:hover .video-sections-content-list{
    max-height:  unset;
    height:  ${BWidePlayerGolbalConf.wideModePlayerHeight - 200}px !important;
  }
  
  #wide-box #bilibili-player #reco_list{
    border-radius: 8px;
    top: 20px;
    width: 10px;
    overflow-y: scroll;
  }
  #wide-box #bilibili-player #reco_list::-webkit-scrollbar{
    width: 0px;
  }
  #wide-box #bilibili-player #reco_list{
    scrollbar-width:0px;
  }
  #wide-box #bilibili-player #reco_list .pic-box{
    width: 90px;
    height: 65px;
  }
  #wide-box #bilibili-player #reco_list .pic-box .video-awesome-img{
    width:100%;
    height:100%;
  }
  #wide-box #bilibili-player #reco_list .info .title{
    -webkit-line-clamp: 1;
  }
  #wide-box #bilibili-player #reco_list:hover{
    height: ${BWidePlayerGolbalConf.wideModePlayerHeight - 140}px;
    width: 280px;
    opacity:1;
    padding: 8px;
  }
  
  #wide-box #bilibili-player .action-list-container .main .cover{
    width: 70px;
  }
  #wide-box #bilibili-player .action-list-container:hover{
    width: 270px;
    height: auto;
    opacity: 1;
  }
  #wide-box #bilibili-player .action-list-container:hover #playlist-video-action-list,
  #wide-box #bilibili-player #playlist-video-action-list-body{
    max-height: ${BWidePlayerGolbalConf.wideModePlayerHeight - 160}px;
  }
  #wide-box #bilibili-player #multi_page:hover{
    width: auto;
    height:auto;
    opacity: 1;
  }
  #wide-box #bilibili-player #multi_page .cur-list{
    max-height: ${BWidePlayerGolbalConf.wideModePlayerHeight - 160}px;
  }
  #wide-box #bilibili-player #multi_page .list-box li{
    width:260px;
  }
  
  /*左侧栏视频信息左-包含播放器*/
  #wide-box .left-container.scroll-sticky,
  #wide-box div.playlist-container--left{
    display: flex;
    flex-direction: column;
  }
  /*收藏页去padding*/
  #wide-box div.playlist-container{
    padding: unset;
  }
  #wide-box div#mirror-vdcon{
    justify-content: left;
  }
  /*右侧栏*/
  #wide-box div.right-container.is-in-large-ab,
  #wide-box div.playlist-container--right{
    margin-top: ${BWidePlayerGolbalConf.wideModePlayerHeight}px;
  }
  #wide-box #danmukuBox{margin-top: 0;}
  #wide-box div.video-container-v1{
    padding: 0;
    justify-content: left;
  }
  /*左栏除视频编辑器*/ 
  #wide-box .left-container.scroll-sticky>div:not(#playerWrap),
  #wide-box div.playlist-container--left>div:not(#playerWrap){
   margin-left:100px;
  }
  #wide-box #biliMainHeader .bili-header__bar{
    background-color: #000;
  }
  #wide-box #app .bpx-player-sending-bar{
    background-color:black;
  }
  #wide-box #biliMainHeader .bili-header__bar a.default-entry{
    color:white;
  }
  #wide-box #biliMainHeader .bili-header__bar li svg{color: white}
  #wide-box .mini-header .right-entry .right-entry__outside .right-entry-text{color:white}
  #wide-box .mini-header__title span{color:white !important;}
  #wide-box .bpx-player-video-inputbar-wrap{background-color:#353232;}
  `
}

class BilibiliPrettifyInject {

  static flushStyle() {
    bWidePlayerFlushStyle()
    this.injectStyle(BWidePlayerGolbalConf.styles.indexSimplifyStyle)
    this.injectStyle(BWidePlayerGolbalConf.styles.widePlayerStyles)
  }

  static injectStyle(styleStr) {
    GM_addStyle(styleStr)
  }
}

class BilibiliPlayMode {
  // 记录Ctrl是否已经被点击一次
  static ctrlReady = false
  static init() {
    bWidePlayerFlushStyle()
    // 注入样式
    BilibiliPrettifyInject.injectStyle(BWidePlayerGolbalConf.styles.widePlayerStyles)

    // 按钮移位

    // 事件绑定
    this.__eventBind()
  }

  static __injectMenu() {

  }

  static __eventBind() {
    // 全局按键事件绑定
    document.onkeyup = (event) => {
      // 1. 双击Ctrl
      if (event.key == "Control") {
        if (!this.ctrlReady) {
          this.ctrlReady = true
          setTimeout(() => {
            this.ctrlReady = false
          }, 300)
        }
        else {
          this.ctrlReady = false
          // do something
          this.toggleWideMode()
        }
      }

    };

  }

  static toggleWideMode() {
    elmGetter.get('.rec-list > div .pic-box picture', document, 2.5 * 60e3).then(res => {
      console.log('xxxou: ', res)
      const mainBox = 'body'
      const boxId = $(mainBox).attr('id')
      let newId = ''
      if (!boxId) {
        newId = 'wide-box'
        this.videoFloatList()
      }
      else {
        this.videoFloatList(false)
      }
      $(mainBox).attr('id', newId)
    })
  }

  static videoFloatList(float = true) {
    const wrapperSelector = '#bilibili-player'
    if (float) {
      const wrapper = $(wrapperSelector)
      const favList = $('.action-list-container')
      if (favList && favList.length) {
        $(wrapper[0]).append(favList)
      }
      else {
        const multiList = $('#multi_page')
        // console.log('multi-page: ', multiList)
        if (multiList && multiList.length) {
          $(wrapper[0]).append(multiList)
        }
        else {
          const hejiList = $('.base-video-sections-v1')
          if (hejiList && hejiList.length) {
            $(wrapper[0]).append(hejiList)
          }
          else {
            const normalList = $('#reco_list')
            // console.log('reco list: ', normalList )
            if (normalList && normalList.length) {
              $(wrapper[0]).append(normalList)
            }
          }
        }
      }
    }
    else {
      const favList = $(`${wrapperSelector} .action-list-container`)
      if (favList && favList.length) {
        $('#danmukuBox').after($(favList))

      }
      else {
        const multiList = $(`${wrapperSelector} #multi_page`)
        if (multiList && multiList.length) {
          $('#danmukuBox').after($(multiList))
        }
        else {
          const hejiList = $(`${wrapperSelector} .base-video-sections-v1`)
          if (hejiList && hejiList.length) {
            $('#danmukuBox').after(hejiList)
          }
          else {
            const normalList = $(`${wrapperSelector} #reco_list`)
            if (normalList && normalList.length) {
              $('#danmukuBox').after($(normalList))
            }
          }
        }
      }
    }
  }
}

let firstCtrl = true

function __bWidePlayerInit() {
  bWidePlayerFlushStyle()
  BilibiliPlayMode.init()
  if (BWidePlayerGolbalConf.wideModeDefault) {
    BilibiliPlayMode.toggleWideMode()
  }

}

(function () {
  'use strict';
  __bWidePlayerInit()

})();