Skip to content
This repository has been archived by the owner on Jan 16, 2023. It is now read-only.

Commit

Permalink
Merge pull request #389 from clappr/feature/replay_button
Browse files Browse the repository at this point in the history
Replay Button
  • Loading branch information
BruunoMM authored Jul 10, 2020
2 parents 8b1d8dd + 4b9c3ad commit fb86572
Show file tree
Hide file tree
Showing 12 changed files with 205 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ open class AVFoundationPlayback: Playback {
let newPosition = CMTimeGetSeconds(timeInterval.seek().time)
let userInfo = ["position": newPosition]

trigger(.willSeek, userInfo: ["position": position])
trigger(.willSeek, userInfo: userInfo)

player?.currentItem?.seek(to: timeInterval) { [weak self] in
self?.trigger(.didUpdatePosition, userInfo: userInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ open class PosterPlugin: UIContainerPlugin {
if let playback = playback {
listenTo(playback, eventName: Event.playing.rawValue) { [weak self] _ in self?.playbackStarted() }
listenTo(playback, eventName: Event.stalling.rawValue) { [weak self] _ in self?.playbackStalled() }
listenTo(playback, eventName: Event.didComplete.rawValue) { [weak self] _ in self?.playbackEnded() }
}
}

Expand All @@ -101,13 +100,7 @@ open class PosterPlugin: UIContainerPlugin {
fileprivate func playbackStarted() {
view.isHidden = true
}

fileprivate func playbackEnded() {
container?.mediaControlEnabled = false
playButton.isHidden = false
view.isHidden = false
}


fileprivate func updatePoster(_ info: EventUserInfo) {
Logger.logInfo("Updating poster", scope: pluginName)
guard let posterUrl = info?[kPosterUrl] as? String else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ open class MediaControl: UICorePlugin, UIGestureRecognizerDelegate {
private var alwaysVisible = false
private var currentlyShowing = false
private var currentlyHiding = false
private var isDrawerActive = false
private var isChromeless: Bool { core?.options.bool(kChromeless) ?? false }

required public init(context: UIObject) {
Expand Down Expand Up @@ -72,7 +73,12 @@ open class MediaControl: UICorePlugin, UIGestureRecognizerDelegate {
}

listenTo(playback, eventName: Event.didComplete.rawValue) { [weak self] _ in
self?.hide()
self?.onComplete()
self?.listenToOnce(playback, eventName: Event.playing.rawValue) { [weak self] _ in
self?.show { [weak self] in
self?.disappearAfterSomeTime()
}
}
}

listenTo(playback, eventName: Event.didPause.rawValue) { [weak self] _ in
Expand Down Expand Up @@ -122,16 +128,24 @@ open class MediaControl: UICorePlugin, UIGestureRecognizerDelegate {
}

listenTo(context, event: .didShowDrawerPlugin) { [weak self] _ in
self?.isDrawerActive = true
self?.hide()
}

listenTo(context, event: .didHideDrawerPlugin) { [weak self] _ in
let statesToShow: [PlaybackState] = [.playing, .paused]
let statesToShow: [PlaybackState] = [.playing, .paused, .idle]
self?.isDrawerActive = false

guard let state = self?.activePlayback?.state, statesToShow.contains(state) else { return }
self?.show()
}
}

func onComplete() {
guard !isDrawerActive else { return }
keepVisible()
show()
}

func show(animated: Bool = false, completion: (() -> Void)? = nil) {
if currentlyShowing || isChromeless {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ open class PlayButton: MediaControl.Element {

public var playIcon = UIImage.fromName("play", for: PlayButton.self)!
public var pauseIcon = UIImage.fromName("pause", for: PlayButton.self)!
public var replayIcon = UIImage.fromName("replay", for: PlayButton.self)!

public var button: UIButton? {
didSet {
Expand All @@ -26,6 +27,12 @@ open class PlayButton: MediaControl.Element {
private var canShowPauseIcon: Bool {
activePlayback?.state == .playing
}

private var shouldReplay: Bool {
guard let playback = activePlayback else { return false }

return playback.position >= playback.duration
}

override open func bindEvents() {
bindPlaybackEvents()
Expand All @@ -38,6 +45,8 @@ open class PlayButton: MediaControl.Element {
listenTo(playback, event: .playing) { [weak self] _ in self?.onPlay() }
listenTo(playback, event: .stalling) { [weak self] _ in self?.hide() }
listenTo(playback, event: .didStop) { [weak self] _ in self?.onStop() }
listenTo(playback, event: .didComplete) { [weak self] _ in self?.onComplete() }
listenTo(playback, event: .willSeek) { [weak self] info in self?.onWillSeek(info) }
}

override open func render() {
Expand Down Expand Up @@ -71,7 +80,21 @@ open class PlayButton: MediaControl.Element {
show()
changeToPlayIcon()
}

private func onComplete() {
show()
changeToReplayIcon()
}

private func onWillSeek(_ info: EventUserInfo) {
guard let playback = activePlayback,
let position = info?["position"] as? Double,
position != playback.duration else { return }

show()
canShowPlayIcon ? changeToPlayIcon() : changeToPauseIcon()
}

public func hide() {
view.isHidden = true
}
Expand All @@ -82,7 +105,7 @@ open class PlayButton: MediaControl.Element {

@objc func togglePlayPause() {
guard let playback = activePlayback else { return }

switch playback.state {
case .playing:
pause()
Expand All @@ -98,6 +121,9 @@ open class PlayButton: MediaControl.Element {
}

private func play() {
if shouldReplay {
activePlayback?.seek(0)
}
activePlayback?.play()
}

Expand All @@ -112,4 +138,8 @@ open class PlayButton: MediaControl.Element {

button?.setImage(pauseIcon, for: .normal)
}

private func changeToReplayIcon() {
button?.setImage(replayIcon, for: .normal)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "iconReplay.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "[email protected]",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "[email protected]",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,11 @@ class PosterPluginTests: QuickSpec {
}

context("when playback trigger a end event") {
it("reveal itself") {
it("do not reveal itself") {
core.activeContainer?.playback?.trigger(Event.playing.rawValue)
core.activeContainer?.playback?.trigger(Event.didComplete.rawValue)

expect(posterPlugin.view.isHidden).to(beFalse())
expect(posterPlugin.view.isHidden).to(beTrue())
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ class MediaControlTests: QuickSpec {
expect(mediaControl.view.isHidden).to(beTrue())
}

context("when a option to keep media control always visible is given") {
it("doesn't hide the mediacontrol and stop timer") {
context("when kMediaControlAlwaysVisible is true") {
it("keeps the media control visible without timer") {
let options: Options = [kMediaControlAlwaysVisible: true]
let core = Core(options: options)
let mediaControl = MediaControl(context: core)
Expand Down Expand Up @@ -142,7 +142,7 @@ class MediaControlTests: QuickSpec {
}

context("when ready") {
it("shows the media control") {
it("hides the media control") {
mediaControlHidden()

coreStub.activePlayback?.trigger(Event.ready)
Expand All @@ -153,7 +153,7 @@ class MediaControlTests: QuickSpec {
}

context("when playing") {
it("shows the media control") {
it("hides the media control") {
mediaControlHidden()

coreStub.activePlayback?.trigger(Event.playing)
Expand All @@ -172,13 +172,14 @@ class MediaControlTests: QuickSpec {
}

context("when complete") {
it("hides the media control") {
mediaControlVisible()
it("shows the media control") {
mediaControl.view.isHidden = true
mediaControl.view.alpha = 0.0

coreStub.activePlayback?.trigger(Event.didComplete)

expect(mediaControl.view.isHidden).to(beTrue())
expect(mediaControl.view.alpha).toEventually(equal(0))
expect(mediaControl.view.isHidden).toEventually(beFalse())
expect(mediaControl.view.alpha).toEventually(equal(1))
}
}

Expand Down Expand Up @@ -315,34 +316,38 @@ class MediaControlTests: QuickSpec {
}

context("when the drawer events are triggered") {
it("dont show Media Control when the video ended") {
var didCallShow = false
context("and the video ends") {
it("dont show Media Control") {
var didCallShow = false

coreStub.trigger(.didShowDrawerPlugin)
coreStub.activePlayback?.trigger(.didComplete)
coreStub.trigger(.didHideDrawerPlugin)
coreStub.trigger(.didShowDrawerPlugin)
coreStub.activePlayback?.trigger(.didComplete)
coreStub.trigger(.didHideDrawerPlugin)

mediaControl.show() { didCallShow = true }
mediaControl.show() { didCallShow = true }

expect(didCallShow).to(beFalse())
expect(didCallShow).to(beFalse())
}
}

it("shows Media Control when the video is not ended") {
var didCallShow = false

coreStub.playbackMock?.set(state: .playing)

coreStub.trigger(.didShowDrawerPlugin)
coreStub.trigger(.didHideDrawerPlugin)

mediaControl.show() { didCallShow = true }

expect(didCallShow).to(beTrue())
context("and the video does not end") {
it("shows Media Control") {
var didCallShow = false

coreStub.playbackMock?.set(state: .playing)

coreStub.trigger(.didShowDrawerPlugin)
coreStub.trigger(.didHideDrawerPlugin)

mediaControl.show() { didCallShow = true }

expect(didCallShow).to(beTrue())
}
}
}

func mediaControlHidden() {
coreStub.activePlayback?.trigger(Event.didComplete)
mediaControl.hide()
}

func mediaControlVisible() {
Expand Down
Loading

0 comments on commit fb86572

Please sign in to comment.