Skip to content

Commit

Permalink
fix: fix loading state in Player
Browse files Browse the repository at this point in the history
  • Loading branch information
ambar committed Jan 21, 2022
1 parent 8f27cd1 commit c884140
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 42 deletions.
25 changes: 6 additions & 19 deletions packages/griffith/src/components/Player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -370,22 +370,21 @@ class InnerPlayer extends Component<InnerPlayerProps, State> {
handleVideoError = () => {
this.setState({
isPlaying: false,
isLoading: false,
})
}

handleVideoDurationChange = (duration: any) => {
handleVideoDurationChange = (duration: number) => {
this.setState({duration})
}

handleVideoTimeUpdate = (currentTime: any) => {
handleVideoTimeUpdate = (currentTime: number) => {
const {isLoading} = this.state
if (isLoading || this.isSeeking) return
if (this.isSeeking) return
this.setState({currentTime})
}

handleVideoVolumeChange = (volume: any) => {
handleVideoVolumeChange = (volume: number) => {
volume = Math.round(volume * 100) / 100
this.setState({volume})
storage.set('@griffith/history-volume', volume)
Expand All @@ -407,19 +406,8 @@ class InnerPlayer extends Component<InnerPlayerProps, State> {
}
}

handleVideoWaiting = () => {
if (this.showLoaderTimeout !== null) return
this.showLoaderTimeout = setTimeout(() => {
this.setState({isLoading: true})
}, 1000)
}

handleVideoPlaying = () => {
if (this.showLoaderTimeout !== null) {
clearTimeout(this.showLoaderTimeout)
this.showLoaderTimeout = null
}
this.setState({isLoading: false})
handleLoadingChange = (isLoading: boolean) => {
this.setState({isLoading})
}

handleVideoSeeking = () => {
Expand Down Expand Up @@ -621,8 +609,7 @@ class InnerPlayer extends Component<InnerPlayerProps, State> {
onError={this.handleVideoError}
onDurationChange={this.handleVideoDurationChange}
onTimeUpdate={this.handleVideoTimeUpdate}
onWaiting={this.handleVideoWaiting}
onPlaying={this.handleVideoPlaying}
onLoadingChange={this.handleLoadingChange}
onSeeking={this.handleVideoSeeking}
onSeeked={this.handleVideoSeeked}
onProgress={this.handleVideoProgress}
Expand Down
46 changes: 25 additions & 21 deletions packages/griffith/src/components/Video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,13 @@ type VideoProps = {
volume: number
currentQuality?: Quality
sources?: PlaySource[]
onLoadingChange?: (isLoading: boolean) => void
onPlay?: (...args: any[]) => any
onPause?: (...args: any[]) => any
onEnded?: (...args: any[]) => any
onLoadedData?: (...args: any[]) => any
onDurationChange?: (...args: any[]) => any
onTimeUpdate?: (...args: any[]) => any
onWaiting: (...args: any[]) => any
onPlaying: (...args: any[]) => any
onSeeking?: (...args: any[]) => any
onSeeked?: (...args: any[]) => any
onProgress?: (values: ProgressValue[]) => any
Expand Down Expand Up @@ -235,7 +234,7 @@ class Video extends Component<VideoProps> {
this.setRate(this.props.currentPlaybackRate)
this.props.onEvent(
EVENTS.CHANGE_QUALITY_SUCCESS,
(this.props as any).currentQuality
this.props.currentQuality
)
}
}
Expand All @@ -247,23 +246,29 @@ class Video extends Component<VideoProps> {
}
}

handleLoadedData = () => {
const {onLoadedData} = this.props
onLoadedData && onLoadedData()
}

handleWaiting = () => {
if (!this.loading) {
this.loading = true
}
this.props.onWaiting()
}

handlePlaying = () => {
if (this.loading) {
this.loading = false
prevLoadingEvent?: 'waiting' | 'canplay' | 'playing' | 'error' = undefined
handleNativeEvent = (e: React.SyntheticEvent<HTMLVideoElement, Event>) => {
const type = e.type
if (
type === 'waiting' ||
type === 'canplay' ||
type === 'playing' ||
type === 'error'
) {
if (type === 'waiting') {
this.loading = true
this.props.onLoadingChange?.(this.loading)
} else if (
// 修复 Safari 中可能不触发 playing 问题:https://github.com/zhihu/griffith/issues/234
(type === 'canplay' && this.prevLoadingEvent === 'waiting') ||
type === 'playing' ||
type === 'error'
) {
this.loading = false
this.props.onLoadingChange?.(this.loading)
}
this.prevLoadingEvent = type
}
this.props.onPlaying()
}

handleTimeUpdate = (arg: any) => {
Expand Down Expand Up @@ -375,8 +380,7 @@ class Video extends Component<VideoProps> {
onDurationChange={this.handleDurationChange}
onTimeUpdate={this.handleTimeUpdate}
onProgress={this.handleProgress}
onWaiting={this.handleWaiting}
onPlaying={this.handlePlaying}
onNativeEvent={this.handleNativeEvent}
paused={paused}
sources={sources}
currentQuality={currentQuality}
Expand Down
11 changes: 9 additions & 2 deletions packages/griffith/src/components/VideoWithMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ function getMediaEventPayload(event: VideoEvent) {
export type VideoComponentType = React.ComponentType<NativeVideoProps>

type VideoWithMessageProps = NativeVideoProps & {
onNativeEvent?: (event: VideoEvent) => void
Video: VideoComponentType
}

Expand All @@ -56,11 +57,12 @@ const VideoWithMessage = React.forwardRef<
}, [props])

const newProps = useMemo(() => {
const newProps: Partial<NativeVideoProps> = {}
const newProps: Partial<VideoWithMessageProps> = {}
eventMap.forEach(([eventName, key]) => {
newProps[key] = (event: VideoEvent, ...args: any[]) => {
emitEvent(eventName, getMediaEventPayload(event))
const handler = propsRef.current[key] as AnyFunction
propsRef.current.onNativeEvent?.(event)
return handler?.(event, ...args)
}
})
Expand All @@ -80,7 +82,12 @@ const VideoWithMessage = React.forwardRef<
[updateVideoSize]
)

const {Video, ...otherProps} = props
const {
Video,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onNativeEvent,
...otherProps
} = props

return (
<Video
Expand Down

0 comments on commit c884140

Please sign in to comment.