Merge pull request #2554 from FoundTheWOUT/upstream-preview

PlayerAgent support LightOff action.
This commit is contained in:
Grant Howard 2021-11-28 16:22:22 +08:00 committed by GitHub
commit 81356db93c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 96 additions and 67 deletions

View File

@ -1,7 +1,10 @@
import { ComponentMetadata } from '@/components/types'
import { playerAgent } from '@/components/video/player-agent'
import { videoChange } from '@/core/observer'
import { allVideoUrls } from '@/core/utils/urls'
let playerAgentInstance
export const component: ComponentMetadata = {
name: 'playerAutoLight',
displayName: '播放时自动关灯',
@ -17,19 +20,26 @@ export const component: ComponentMetadata = {
if (isEmbeddedPlayer()) {
return
}
const autoPlay = lodash.get(
JSON.parse(localStorage.getItem('bilibili_player_settings')),
'video_status.autoplay',
false,
)
videoChange(() => {
const video = dq('video') as HTMLVideoElement
if (autoPlay) {
videoChange(async () => {
if (playerAgentInstance != null) {
const oldVideo = await playerAgentInstance.query.video.element()
oldVideo.removeEventListener('ended', lightOn)
oldVideo.removeEventListener('pause', lightOn)
oldVideo.removeEventListener('play', lightOff)
}
playerAgentInstance = playerAgent
const { query, isAutoPlay } = playerAgentInstance
const video = await query.video.element()
if (isAutoPlay()) {
lightOff()
}
video.addEventListener('ended', () => lightOn())
video.addEventListener('pause', () => lightOn())
video.addEventListener('play', () => lightOff())
video.addEventListener('ended', lightOn)
video.addEventListener('pause', lightOn)
video.addEventListener('play', lightOff)
})
},
}

View File

@ -40,11 +40,6 @@ const entry: ComponentEntry = async ({ settings: { options } }) => {
if (!video) {
return
}
const autoPlay = lodash.get(
JSON.parse(localStorage.getItem('bilibili_player_settings')),
'video_status.autoplay',
false,
)
const action = actions.get(options.mode)
const onplay = () => {
const isNormalMode = !dq('body[class*=player-mode-]')
@ -52,7 +47,7 @@ const entry: ComponentEntry = async ({ settings: { options } }) => {
action()
}
}
if (options.applyOnPlay && !autoPlay) {
if (options.applyOnPlay && !playerAgent.isAutoPlay()) {
video.addEventListener('play', onplay, { once: true })
} else {
onplay()

View File

@ -27,7 +27,14 @@ export const component: ComponentMetadata = {
const videoEl = await video.element() as HTMLVideoElement
// const playerWrap = await video.wrap()
const playerWrap = (dq('.player-wrap') || dq('.player-module')) as HTMLElement
// 如果有 video-player 优先的使用该盒子
// 因为在稍后再看页面medialist视频也有 player-wrap
// 选择 player-wrap 会导致闪烁。
const playerWrap = (
document.getElementById('video-player')
?? (dq('.player-wrap') || dq('.player-module'))
) as HTMLElement
let observer: IntersectionObserver
let intersectionLock = true // Lock intersection action
@ -101,13 +108,8 @@ export const component: ComponentMetadata = {
)
function mountPlayListener() {
const autoPlay = lodash.get(
JSON.parse(localStorage.getItem('bilibili_player_settings')),
'video_status.autoplay',
false,
)
videoChange(async () => {
if (autoPlay) {
if (playerAgent.isAutoPlay()) {
addPlayerOutEvent()
}
videoEl.addEventListener('play', addPlayerOutEvent)

View File

@ -61,6 +61,10 @@ interface PlayerQuery<QueryResult> extends CustomNestedQuery<QueryResult> {
webFullscreen: QueryResult
fullscreen: QueryResult
}
settings: {
wrap: QueryResult,
lightOff: QueryResult
}
}
toastWrap: QueryResult
danmakuTipLayer: QueryResult
@ -125,6 +129,22 @@ export abstract class PlayerAgent {
raiseEvent(checkbox, 'change')
return checkbox.checked
}
abstract toggleLight(on: boolean): void
// eslint-disable-next-line class-methods-use-this
getPlayerConfig(target:string) {
return lodash.get(
JSON.parse(localStorage.getItem('bilibili_player_settings')),
target,
false,
)
}
isAutoPlay() {
return this.getPlayerConfig('video_status.autoplay')
}
abstract isMute(): boolean
/** 更改音量 (%) */
abstract changeVolume(change: number): number
@ -181,6 +201,10 @@ export class VideoPlayerAgent extends PlayerAgent {
webFullscreen: '.bilibili-player-video-web-fullscreen',
fullscreen: '.bilibili-player-video-btn-fullscreen',
},
settings: {
wrap: '.bilibili-player-video-btn-setting-wrap',
lightOff: '.bilibili-player-video-btn-setting-right-others-content-lightoff .bui-checkbox-input',
},
},
toastWrap: '.bilibili-player-video-toast-wrp',
danmakuTipLayer: '.bilibili-player-dm-tip-wrap',
@ -225,6 +249,11 @@ export class VideoPlayerAgent extends PlayerAgent {
this.nativeApi.seek(video.currentTime + change, video.paused)
return this.nativeApi.getCurrentTime()
}
async toggleLight(on:boolean) {
const checkbox = await this.query.control.settings.lightOff() as HTMLInputElement
checkbox.checked = !on
raiseEvent(checkbox, 'change')
}
}
export class BwpPlayerAgent extends VideoPlayerAgent {
type: AgentType = 'bwp'
@ -277,6 +306,10 @@ export class BangumiPlayerAgent extends PlayerAgent {
webFullscreen: '.squirtle-video-pagefullscreen',
fullscreen: '.squirtle-video-fullscreen',
},
settings: {
wrap: '.squirtle-setting-wrap',
lightOff: '.squirtle-lightoff',
},
},
toastWrap: '.bpx-player-tooltip-area',
danmakuTipLayer: '.bpx-player-dialog-wrap',
@ -321,6 +354,15 @@ export class BangumiPlayerAgent extends PlayerAgent {
video.currentTime = lodash.clamp(video.currentTime + change, 0, video.duration)
return video.currentTime
}
toggleLight(on: boolean) {
const checkbox = this.query.control.settings.lightOff.sync()
const canLightOff = !checkbox.classList.contains('active') && !on
const canLightOn = checkbox.classList.contains('active') && on
if (canLightOff || canLightOn) {
checkbox.dispatchEvent(new MouseEvent('click'))
}
}
}
export const playerAgent = (() => {

View File

@ -1,52 +1,32 @@
import { select } from '@/core/spin-query'
import { matchUrlPattern, raiseEvent, none } from '@/core/utils'
import { matchUrlPattern, none } from '@/core/utils'
import { loadLazyPlayerSettingsPanel } from '@/core/utils/lazy-panel'
import { playerUrls } from '@/core/utils/urls'
import { playerAgent } from './player-agent'
let initialized = false
// let initialized = false
const setLightAdaptor = {
bangumi: (doLightOn: boolean) => async () => {
if (!initialized) {
loadLazyPlayerSettingsPanel('.squirtle-setting-wrap', '.squirtle-video-setting')
initialized = true
}
const checkbox = await select('.squirtle-lightoff') as HTMLElement
const event = new MouseEvent('click')
// 处于关灯状态,要开灯 -> 开灯
checkbox.classList.contains('active') && doLightOn ? checkbox.dispatchEvent(event) : ''
// 处于开灯状态,要关灯 -> 关灯
!checkbox.classList.contains('active') && !doLightOn ? checkbox.dispatchEvent(event) : ''
},
fallback: (on: boolean) => {
if (!playerUrls.some(url => matchUrlPattern(url))) {
return none
}
return async () => {
if (!initialized) {
loadLazyPlayerSettingsPanel(
'.bilibili-player-video-btn-setting',
'.bilibili-player-video-btn-setting-wrap',
{
style: '.bilibili-player-video-btn-setting-wrap { display: none !important }',
},
)
initialized = true
}
const checkbox = await select('.bilibili-player-video-btn-setting-right-others-content-lightoff .bui-checkbox-input') as HTMLInputElement
checkbox.checked = !on
raiseEvent(checkbox, 'change')
}
},
}
const setLight = (on: boolean) => {
if (!playerUrls.some(url => matchUrlPattern(url))) {
return none
}
return async () => {
const playerAgentInstance = playerAgent
const {
query: {
control: { settings, buttons },
},
} = playerAgentInstance
let setLight = setLightAdaptor.fallback
for (const key in setLightAdaptor) {
if (Object.prototype.hasOwnProperty.call(setLightAdaptor, key)) {
if (matchUrlPattern(key)) {
setLight = setLightAdaptor[key]
}
// if (!initialized) {
loadLazyPlayerSettingsPanel(
buttons.settings.selector,
settings.wrap.selector,
)
// initialized = true
// }
playerAgentInstance.toggleLight(on)
}
}
export const lightOn = setLight(true)
export const lightOff = setLight(false)