mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-18 10:41:20 -08:00
refactor(core): [CORE-20] type entry and converge initialization
This commit is contained in:
1 parent
ccf77c4ed2
commit
ee895a558f
100 files changed
+33854
-839
No files matched your search
@@ -1,40 +0,0 @@
|
||||
import { def } from '../utils'
|
||||
|
||||
export default function airplayMix(art) {
|
||||
const {
|
||||
i18n,
|
||||
notice,
|
||||
proxy,
|
||||
template: { $video },
|
||||
} = art
|
||||
|
||||
let available = true
|
||||
|
||||
if (window.WebKitPlaybackTargetAvailabilityEvent && $video.webkitShowPlaybackTargetPicker) {
|
||||
proxy($video, 'webkitplaybacktargetavailabilitychanged', (event) => {
|
||||
switch (event.availability) {
|
||||
case 'available':
|
||||
available = true
|
||||
break
|
||||
case 'not-available':
|
||||
available = false
|
||||
break
|
||||
}
|
||||
})
|
||||
}
|
||||
else {
|
||||
available = false
|
||||
}
|
||||
|
||||
def(art, 'airplay', {
|
||||
value() {
|
||||
if (available) {
|
||||
$video.webkitShowPlaybackTargetPicker()
|
||||
art.emit('airplay')
|
||||
}
|
||||
else {
|
||||
notice.show = i18n.get('AirPlay Not Available')
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import type { NoticeSink } from '../notice'
|
||||
import { isClosing } from '../lifecycle/instance'
|
||||
import { def } from '../utils'
|
||||
|
||||
export interface AirplayHost {
|
||||
template: { $video: EventTarget & { webkitShowPlaybackTargetPicker?: () => void } }
|
||||
i18n: { get: (key: string) => string }
|
||||
notice: NoticeSink
|
||||
proxy: (target: EventTarget, name: string, listener: (event: Event & { availability?: string }) => void) => unknown
|
||||
emit: (name: 'airplay') => unknown
|
||||
}
|
||||
|
||||
export default function airplayMix(art: AirplayHost): void {
|
||||
if (isClosing(art))
|
||||
return
|
||||
const {
|
||||
i18n,
|
||||
notice,
|
||||
proxy,
|
||||
template: { $video },
|
||||
} = art
|
||||
|
||||
let available = true
|
||||
|
||||
const supported = (window as Window & { WebKitPlaybackTargetAvailabilityEvent?: unknown }).WebKitPlaybackTargetAvailabilityEvent
|
||||
if (isClosing(art))
|
||||
return
|
||||
const picker = supported && $video.webkitShowPlaybackTargetPicker
|
||||
if (isClosing(art))
|
||||
return
|
||||
if (picker) {
|
||||
proxy($video, 'webkitplaybacktargetavailabilitychanged', (event) => {
|
||||
if (isClosing(art))
|
||||
return
|
||||
switch (event.availability) {
|
||||
case 'available':
|
||||
available = true
|
||||
break
|
||||
case 'not-available':
|
||||
available = false
|
||||
break
|
||||
}
|
||||
})
|
||||
}
|
||||
else {
|
||||
available = false
|
||||
}
|
||||
|
||||
if (isClosing(art))
|
||||
return
|
||||
def(art, 'airplay', {
|
||||
value() {
|
||||
if (isClosing(art))
|
||||
return
|
||||
if (available) {
|
||||
const picker = $video.webkitShowPlaybackTargetPicker
|
||||
if (isClosing(art))
|
||||
return
|
||||
Reflect.apply(picker!, $video, [])
|
||||
if (!isClosing(art))
|
||||
art.emit('airplay')
|
||||
}
|
||||
else {
|
||||
const message = i18n.get('AirPlay Not Available')
|
||||
if (!isClosing(art))
|
||||
notice.show = message
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
import { def } from '../utils'
|
||||
|
||||
export default function attrMix(art) {
|
||||
const {
|
||||
template: { $video },
|
||||
} = art
|
||||
|
||||
def(art, 'attr', {
|
||||
value(key, value) {
|
||||
if (value === undefined)
|
||||
return $video[key]
|
||||
$video[key] = value
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { def } from '../utils'
|
||||
|
||||
export interface AttributeMethods {
|
||||
attr: {
|
||||
(key: PropertyKey): unknown
|
||||
(key: PropertyKey, value: unknown): unknown
|
||||
}
|
||||
}
|
||||
|
||||
export default function attrMix(art: { template: { $video: object } }): void {
|
||||
const {
|
||||
template: { $video },
|
||||
} = art
|
||||
|
||||
def(art, 'attr', {
|
||||
value(key: PropertyKey, value?: unknown): unknown {
|
||||
// attr intentionally exposes arbitrary native/proxy properties, including symbols.
|
||||
const target = $video as Record<PropertyKey, unknown>
|
||||
if (value === undefined)
|
||||
return target[key]
|
||||
target[key] = value
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import { def } from '../utils'
|
||||
|
||||
export default function cssVarMix(art) {
|
||||
const { $player } = art.template
|
||||
|
||||
def(art, 'cssVar', {
|
||||
value(key, value) {
|
||||
if (value) {
|
||||
return $player.style.setProperty(key, value)
|
||||
}
|
||||
else {
|
||||
return getComputedStyle($player).getPropertyValue(key)
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { def } from '../utils'
|
||||
|
||||
export interface CssVariableMethods {
|
||||
cssVar: {
|
||||
(key: string): string
|
||||
(key: string, value: unknown): string | void
|
||||
}
|
||||
}
|
||||
|
||||
export default function cssVarMix(art: { template: { $player: HTMLElement } }): void {
|
||||
const { $player } = art.template
|
||||
|
||||
def(art, 'cssVar', {
|
||||
value(key: string, value?: unknown): string | void {
|
||||
if (value) {
|
||||
// Retain Web IDL conversion and the historical truthy write condition.
|
||||
return $player.style.setProperty(key, value as string)
|
||||
}
|
||||
else {
|
||||
return getComputedStyle($player).getPropertyValue(key)
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
import airplayMix from './airplayMix'
|
||||
import aspectRatioMix from './aspectRatioMix'
|
||||
import attrMix from './attrMix'
|
||||
import autoHeightMix from './autoHeightMix'
|
||||
import autoSizeMix from './autoSizeMix'
|
||||
import cssVarMix from './cssVarMix'
|
||||
import currentTimeMix from './currentTimeMix'
|
||||
import durationMix from './durationMix'
|
||||
import eventInit from './eventInit'
|
||||
import flipMix from './flipMix'
|
||||
import fullscreenMix from './fullscreenMix'
|
||||
import fullscreenWebMix from './fullscreenWebMix'
|
||||
import loadedMix from './loadedMix'
|
||||
import miniMix from './miniMix'
|
||||
import optionInit from './optionInit'
|
||||
import pauseMix from './pauseMix'
|
||||
import pipMix from './pipMix'
|
||||
import playbackRateMix from './playbackRateMix'
|
||||
import playedMix from './playedMix'
|
||||
import playingMix from './playingMix'
|
||||
import playMix from './playMix'
|
||||
import posterMix from './posterMix'
|
||||
import qualityMix from './qualityMix'
|
||||
import rectMix from './rectMix'
|
||||
import screenshotMix from './screenshotMix'
|
||||
import seekMix from './seekMix'
|
||||
import stateMix from './stateMix'
|
||||
import subtitleOffsetMix from './subtitleOffsetMix'
|
||||
import switchMix from './switchMix'
|
||||
import themeMix from './themeMix'
|
||||
import thumbnailsMix from './thumbnailsMix'
|
||||
import toggleMix from './toggleMix'
|
||||
import typeMix from './typeMix'
|
||||
import urlMix from './urlMix'
|
||||
import volumeMix from './volumeMix'
|
||||
|
||||
export default class Player {
|
||||
constructor(art) {
|
||||
urlMix(art)
|
||||
attrMix(art)
|
||||
playMix(art)
|
||||
pauseMix(art)
|
||||
toggleMix(art)
|
||||
seekMix(art)
|
||||
volumeMix(art)
|
||||
currentTimeMix(art)
|
||||
durationMix(art)
|
||||
switchMix(art)
|
||||
playbackRateMix(art)
|
||||
aspectRatioMix(art)
|
||||
screenshotMix(art)
|
||||
fullscreenMix(art)
|
||||
fullscreenWebMix(art)
|
||||
pipMix(art)
|
||||
loadedMix(art)
|
||||
playedMix(art)
|
||||
playingMix(art)
|
||||
autoSizeMix(art)
|
||||
rectMix(art)
|
||||
flipMix(art)
|
||||
miniMix(art)
|
||||
posterMix(art)
|
||||
autoHeightMix(art)
|
||||
cssVarMix(art)
|
||||
themeMix(art)
|
||||
typeMix(art)
|
||||
stateMix(art)
|
||||
subtitleOffsetMix(art)
|
||||
airplayMix(art)
|
||||
qualityMix(art)
|
||||
thumbnailsMix(art)
|
||||
eventInit(art)
|
||||
optionInit(art)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
import type { MediaSurface } from '../media/types'
|
||||
import type { UrlHost } from '../source/types'
|
||||
import { isClosing } from '../lifecycle/instance'
|
||||
import airplayMix from './airplayMix'
|
||||
import aspectRatioMix from './aspectRatioMix'
|
||||
import attrMix from './attrMix'
|
||||
import autoHeightMix from './autoHeightMix'
|
||||
import autoSizeMix from './autoSizeMix'
|
||||
import cssVarMix from './cssVarMix'
|
||||
import currentTimeMix from './currentTimeMix'
|
||||
import durationMix from './durationMix'
|
||||
import eventInit from './eventInit'
|
||||
import flipMix from './flipMix'
|
||||
import fullscreenMix from './fullscreenMix'
|
||||
import fullscreenWebMix from './fullscreenWebMix'
|
||||
import loadedMix from './loadedMix'
|
||||
import miniMix from './miniMix'
|
||||
import optionInit from './optionInit'
|
||||
import pauseMix from './pauseMix'
|
||||
import pipMix from './pipMix'
|
||||
import playbackRateMix from './playbackRateMix'
|
||||
import playedMix from './playedMix'
|
||||
import playingMix from './playingMix'
|
||||
import playMix from './playMix'
|
||||
import posterMix from './posterMix'
|
||||
import qualityMix from './qualityMix'
|
||||
import rectMix from './rectMix'
|
||||
import screenshotMix from './screenshotMix'
|
||||
import seekMix from './seekMix'
|
||||
import stateMix from './stateMix'
|
||||
import subtitleOffsetMix from './subtitleOffsetMix'
|
||||
import switchMix from './switchMix'
|
||||
import themeMix from './themeMix'
|
||||
import thumbnailsMix from './thumbnailsMix'
|
||||
import toggleMix from './toggleMix'
|
||||
import typeMix from './typeMix'
|
||||
import urlMix from './urlMix'
|
||||
import volumeMix from './volumeMix'
|
||||
|
||||
// Installation requirements come from the owning modules. Some properties are
|
||||
// installed here and consumed only by later callbacks, after construction.
|
||||
type PlayerDependencies = Parameters<typeof airplayMix>[0]
|
||||
& Parameters<typeof aspectRatioMix>[0]
|
||||
& Parameters<typeof attrMix>[0]
|
||||
& Parameters<typeof autoHeightMix>[0]
|
||||
& Parameters<typeof autoSizeMix>[0]
|
||||
& Parameters<typeof cssVarMix>[0]
|
||||
& Parameters<typeof currentTimeMix>[0]
|
||||
& Parameters<typeof durationMix>[0]
|
||||
& Parameters<typeof eventInit>[0]
|
||||
& Parameters<typeof flipMix>[0]
|
||||
& Parameters<typeof fullscreenMix>[0]
|
||||
& Parameters<typeof fullscreenWebMix>[0]
|
||||
& Parameters<typeof loadedMix>[0]
|
||||
& Parameters<typeof miniMix>[0]
|
||||
& Parameters<typeof optionInit>[0]
|
||||
& Parameters<typeof pauseMix>[0]
|
||||
& Parameters<typeof pipMix>[0]
|
||||
& Parameters<typeof playbackRateMix>[0]
|
||||
& Parameters<typeof playedMix>[0]
|
||||
& Parameters<typeof playingMix>[0]
|
||||
& Parameters<typeof playMix>[0]
|
||||
& Parameters<typeof posterMix>[0]
|
||||
& Parameters<typeof qualityMix>[0]
|
||||
& Parameters<typeof rectMix>[0]
|
||||
& Parameters<typeof screenshotMix>[0]
|
||||
& Parameters<typeof seekMix>[0]
|
||||
& Parameters<typeof stateMix>[0]
|
||||
& Parameters<typeof subtitleOffsetMix>[0]
|
||||
& Parameters<typeof switchMix>[0]
|
||||
& Parameters<typeof themeMix>[0]
|
||||
& Parameters<typeof thumbnailsMix>[0]
|
||||
& Parameters<typeof toggleMix>[0]
|
||||
& Parameters<typeof typeMix>[0]
|
||||
& Parameters<typeof volumeMix>[0]
|
||||
|
||||
// The order is observable through descriptors, subscriptions and option writes.
|
||||
const installers: readonly ((art: PlayerDependencies) => void)[] = [
|
||||
attrMix,
|
||||
playMix,
|
||||
pauseMix,
|
||||
toggleMix,
|
||||
seekMix,
|
||||
volumeMix,
|
||||
currentTimeMix,
|
||||
durationMix,
|
||||
switchMix,
|
||||
playbackRateMix,
|
||||
aspectRatioMix,
|
||||
screenshotMix,
|
||||
fullscreenMix,
|
||||
fullscreenWebMix,
|
||||
pipMix,
|
||||
loadedMix,
|
||||
playedMix,
|
||||
playingMix,
|
||||
autoSizeMix,
|
||||
rectMix,
|
||||
flipMix,
|
||||
miniMix,
|
||||
posterMix,
|
||||
autoHeightMix,
|
||||
cssVarMix,
|
||||
themeMix,
|
||||
typeMix,
|
||||
stateMix,
|
||||
subtitleOffsetMix,
|
||||
airplayMix,
|
||||
qualityMix,
|
||||
thumbnailsMix,
|
||||
eventInit,
|
||||
optionInit,
|
||||
]
|
||||
|
||||
export type PlayerHost<Host> = UrlHost<MediaSurface, Host> & PlayerDependencies
|
||||
|
||||
export default class Player<Host extends PlayerHost<Host>> {
|
||||
constructor(art: Host) {
|
||||
if (isClosing(art))
|
||||
return
|
||||
urlMix<MediaSurface, Host>(art)
|
||||
for (const install of installers) {
|
||||
if (isClosing(art))
|
||||
return
|
||||
install(art)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
import { clamp, setStyle } from '../utils'
|
||||
|
||||
export default function optionInit(art) {
|
||||
const {
|
||||
option,
|
||||
storage,
|
||||
template: { $video, $poster },
|
||||
} = art
|
||||
|
||||
for (const key in option.moreVideoAttr) {
|
||||
art.attr(key, option.moreVideoAttr[key])
|
||||
}
|
||||
|
||||
if (option.muted) {
|
||||
art.muted = option.muted
|
||||
}
|
||||
|
||||
if (option.volume) {
|
||||
$video.volume = clamp(option.volume, 0, 1)
|
||||
}
|
||||
|
||||
const volumeStorage = storage.get('volume')
|
||||
if (typeof volumeStorage === 'number') {
|
||||
$video.volume = clamp(volumeStorage, 0, 1)
|
||||
}
|
||||
|
||||
if (option.poster) {
|
||||
setStyle($poster, 'backgroundImage', `url(${option.poster})`)
|
||||
}
|
||||
|
||||
if (option.autoplay) {
|
||||
$video.autoplay = option.autoplay
|
||||
}
|
||||
|
||||
if (option.playsInline) {
|
||||
$video.playsInline = true
|
||||
$video['webkit-playsinline'] = true
|
||||
}
|
||||
|
||||
if (option.theme) {
|
||||
option.cssVar['--art-theme'] = option.theme
|
||||
}
|
||||
|
||||
for (const key in option.cssVar) {
|
||||
art.cssVar(key, option.cssVar[key])
|
||||
}
|
||||
|
||||
art.url = option.url
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
import type { ResolvedOption } from '../option/types'
|
||||
import type { AttributeMethods } from './attrMix'
|
||||
import type { CssVariableMethods } from './cssVarMix'
|
||||
import { isClosing } from '../lifecycle/instance'
|
||||
import { clamp, setStyle } from '../utils'
|
||||
|
||||
export interface InitialOptionHost extends AttributeMethods, CssVariableMethods {
|
||||
option: Pick<ResolvedOption, 'moreVideoAttr' | 'muted' | 'volume' | 'poster' | 'autoplay' | 'playsInline' | 'theme' | 'cssVar' | 'url'>
|
||||
storage: { get: (key: string) => unknown }
|
||||
template: {
|
||||
$video: Pick<HTMLMediaElement, 'volume'> & { 'autoplay'?: boolean, 'playsInline'?: boolean, 'webkit-playsinline'?: boolean }
|
||||
$poster: HTMLElement
|
||||
}
|
||||
muted: boolean
|
||||
get url(): string | null
|
||||
set url(value: string)
|
||||
}
|
||||
|
||||
export default function optionInit(art: InitialOptionHost): void {
|
||||
if (isClosing(art))
|
||||
return
|
||||
const {
|
||||
option,
|
||||
storage,
|
||||
template: { $video, $poster },
|
||||
} = art
|
||||
|
||||
for (const key in option.moreVideoAttr) {
|
||||
if (isClosing(art))
|
||||
return
|
||||
const value = (option.moreVideoAttr as Record<string, unknown>)[key]
|
||||
if (isClosing(art))
|
||||
return
|
||||
art.attr(key, value)
|
||||
}
|
||||
|
||||
if (isClosing(art))
|
||||
return
|
||||
if (option.muted) {
|
||||
const value = option.muted
|
||||
if (isClosing(art))
|
||||
return
|
||||
art.muted = value
|
||||
}
|
||||
|
||||
if (isClosing(art))
|
||||
return
|
||||
if (option.volume) {
|
||||
const value = clamp(option.volume, 0, 1)
|
||||
if (isClosing(art))
|
||||
return
|
||||
$video.volume = value
|
||||
}
|
||||
|
||||
if (isClosing(art))
|
||||
return
|
||||
const volumeStorage = storage.get('volume')
|
||||
if (isClosing(art))
|
||||
return
|
||||
if (typeof volumeStorage === 'number') {
|
||||
$video.volume = clamp(volumeStorage, 0, 1)
|
||||
}
|
||||
|
||||
if (isClosing(art))
|
||||
return
|
||||
if (option.poster) {
|
||||
const value = `url(${option.poster})`
|
||||
if (isClosing(art))
|
||||
return
|
||||
setStyle($poster, 'backgroundImage', value)
|
||||
}
|
||||
|
||||
if (isClosing(art))
|
||||
return
|
||||
if (option.autoplay) {
|
||||
const value = option.autoplay
|
||||
if (isClosing(art))
|
||||
return
|
||||
$video.autoplay = value
|
||||
}
|
||||
|
||||
if (isClosing(art))
|
||||
return
|
||||
if (option.playsInline) {
|
||||
if (isClosing(art))
|
||||
return
|
||||
$video.playsInline = true
|
||||
if (isClosing(art))
|
||||
return
|
||||
$video['webkit-playsinline'] = true
|
||||
}
|
||||
|
||||
if (isClosing(art))
|
||||
return
|
||||
if (option.theme) {
|
||||
const styles = option.cssVar
|
||||
const theme = option.theme
|
||||
if (isClosing(art))
|
||||
return
|
||||
styles['--art-theme'] = theme
|
||||
}
|
||||
|
||||
for (const key in option.cssVar) {
|
||||
if (isClosing(art))
|
||||
return
|
||||
const value = (option.cssVar as Record<string, unknown>)[key]
|
||||
if (isClosing(art))
|
||||
return
|
||||
art.cssVar(key, value)
|
||||
}
|
||||
|
||||
if (isClosing(art))
|
||||
return
|
||||
const url = option.url
|
||||
if (!isClosing(art))
|
||||
art.url = url
|
||||
}
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import { def, setStyle } from '../utils'
|
||||
|
||||
export default function posterMix(art) {
|
||||
export default function posterMix(art: { template: { $poster: HTMLElement } }): void {
|
||||
const {
|
||||
template: { $poster },
|
||||
} = art
|
||||
@@ -8,13 +8,13 @@ export default function posterMix(art) {
|
||||
def(art, 'poster', {
|
||||
get: () => {
|
||||
try {
|
||||
return $poster.style.backgroundImage.match(/"(.*)"/)[1]
|
||||
return $poster.style.backgroundImage.match(/"(.*)"/)![1]!
|
||||
}
|
||||
catch {
|
||||
return ''
|
||||
}
|
||||
},
|
||||
set(url) {
|
||||
set(url: string) {
|
||||
setStyle($poster, 'backgroundImage', `url(${url})`)
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,43 @@
|
||||
import type { Thumbnails } from '../../types/option'
|
||||
import type { QualityItem } from '../control/types'
|
||||
import type { PipProperty } from '../display/types'
|
||||
import type { RectState } from '../media/hosts'
|
||||
import type { Position, SeekMethods, StateProperty } from '../media/playback'
|
||||
import type { SwitchMethods } from '../source/types'
|
||||
import type { AttributeMethods } from './attrMix'
|
||||
import type { CssVariableMethods } from './cssVarMix'
|
||||
|
||||
// Runtime descriptors installed by Player, distinct from each installer's inputs.
|
||||
// Declaring these on the entry must never emit class fields before installation.
|
||||
export interface PlayerProperties extends AttributeMethods, CssVariableMethods, Position, SeekMethods, SwitchMethods, RectState, PipProperty, StateProperty {
|
||||
get url(): string | null
|
||||
set url(value: string)
|
||||
play: () => Promise<unknown>
|
||||
pause: () => unknown
|
||||
toggle: () => unknown
|
||||
volume: number
|
||||
muted: boolean
|
||||
playbackRate: number
|
||||
aspectRatio: string
|
||||
flip: string
|
||||
fullscreen?: boolean
|
||||
fullscreenWeb: boolean
|
||||
mini: boolean
|
||||
readonly loaded: number
|
||||
readonly loadedTime: number
|
||||
readonly played: number
|
||||
readonly playing: boolean
|
||||
autoSize: () => void
|
||||
autoHeight: () => void
|
||||
poster: string
|
||||
theme: string
|
||||
type: string
|
||||
subtitleOffset: number
|
||||
airplay: () => void
|
||||
get quality(): undefined
|
||||
set quality(value: QualityItem[])
|
||||
thumbnails: Thumbnails
|
||||
getDataURL: () => Promise<string>
|
||||
getBlobUrl: () => Promise<string>
|
||||
screenshot: (name?: string) => Promise<string>
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { ComponentHost, EntryOption } from '../component/types'
|
||||
import type { QualityItem } from '../control/types'
|
||||
import type { ComponentHost } from '../component/types'
|
||||
import type { ControlOption, QualityItem } from '../control/types'
|
||||
import type { NoticeSink } from '../notice'
|
||||
import { captureSelection } from '../component/selection'
|
||||
import { isClosing } from '../lifecycle/instance'
|
||||
import { def } from '../utils'
|
||||
|
||||
export interface QualityHost extends ComponentHost {
|
||||
controls: { update: (option: EntryOption<QualityHost>) => unknown }
|
||||
notice: { set show(message: string) }
|
||||
controls: { update: (option: ControlOption) => unknown }
|
||||
notice: NoticeSink
|
||||
i18n: { get: (key: string) => string }
|
||||
switchQuality: (url: string) => Promise<unknown>
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { CaptureMedia } from '../capture/frame'
|
||||
import type { NoticeSink } from '../notice'
|
||||
import { captureBlobUrl, drawFrame } from '../capture/frame'
|
||||
import { isClosing } from '../lifecycle/instance'
|
||||
import { captureSource } from '../source/operation'
|
||||
@@ -6,7 +7,7 @@ import { def, download, secondToTime } from '../utils'
|
||||
|
||||
export interface ScreenshotHost {
|
||||
template: { $video: CaptureMedia }
|
||||
notice: { set show(value: unknown) }
|
||||
notice: NoticeSink
|
||||
getDataURL: () => Promise<string>
|
||||
emit: (name: 'screenshot', dataUri: string) => unknown
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,11 +1,12 @@
|
||||
import type { CssVariableMethods } from './cssVarMix'
|
||||
import { def } from '../utils'
|
||||
|
||||
export default function themeMix(art) {
|
||||
export default function themeMix(art: CssVariableMethods): void {
|
||||
def(art, 'theme', {
|
||||
get() {
|
||||
return art.cssVar('--art-theme')
|
||||
},
|
||||
set(theme) {
|
||||
set(theme: string) {
|
||||
art.cssVar('--art-theme', theme)
|
||||
},
|
||||
})
|
||||
@@ -1,11 +1,11 @@
|
||||
import { def } from '../utils'
|
||||
|
||||
export default function typeMix(art) {
|
||||
export default function typeMix(art: { option: { type: string } }): void {
|
||||
def(art, 'type', {
|
||||
get() {
|
||||
return art.option.type
|
||||
},
|
||||
set(type) {
|
||||
set(type: string) {
|
||||
art.option.type = type
|
||||
},
|
||||
})
|
||||
Reference in new issue
Block a user