- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Feat] Added additional buttons for contextual actions
Eduard Mazur
authored and
Eduard Mazur
committed
Jan 14, 2025
1 parent
6cc1bff
commit d398e14
Showing
9 changed files
with
191 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// | ||
// ContextualActionData.swift | ||
// react-native-video | ||
// | ||
// Created by Eduard Mazur on 14.01.2025. | ||
// | ||
|
||
import Foundation | ||
|
||
struct ContextualActionData { | ||
let action: String | ||
let startAt: Double | ||
let endAt: Double? | ||
} | ||
|
||
public enum ContextualButtonState { | ||
case none | ||
case skipIntro | ||
case nextEpisode | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// | ||
// RCTVideo+ContextualActions.swift | ||
// react-native-video | ||
// | ||
// Created by Eduard Mazur on 14.01.2025. | ||
// | ||
|
||
import AVKit | ||
|
||
@available(tvOS 15.0, *) | ||
extension RCTVideo { | ||
func configureContextualActions() { | ||
guard let player = playerForContextualActions else { | ||
print("Player is not initialized.") | ||
return | ||
} | ||
|
||
let interval = CMTime(seconds: 0.5, preferredTimescale: CMTimeScale(NSEC_PER_SEC)) | ||
|
||
timeObserverToken = player.addPeriodicTimeObserver(forInterval: interval, queue: .main) { [weak self] currentTime in | ||
self?.updateContextualActions(currentTime: currentTime) | ||
} | ||
} | ||
|
||
func removeContextualActionsTimeObserver() { | ||
guard let player = playerForContextualActions, let token = timeObserverToken else { return } | ||
player.removeTimeObserver(token) | ||
timeObserverToken = nil | ||
} | ||
|
||
func updateContextualActions(currentTime: CMTime) { | ||
let currentSeconds = CMTimeGetSeconds(currentTime) | ||
|
||
guard let playerViewController = playerViewControllerForContextualActions else { | ||
return | ||
} | ||
|
||
for actionData in contextualActionData { | ||
if currentSeconds >= actionData.startAt, | ||
let endAt = actionData.endAt, currentSeconds < endAt { | ||
handleAction(actionData, playerViewController: playerViewController) | ||
return | ||
} else if currentSeconds >= actionData.startAt, actionData.endAt == nil { | ||
handleAction(actionData, playerViewController: playerViewController) | ||
return | ||
} | ||
} | ||
|
||
if currentContextualState != .none { | ||
playerViewController.contextualActions = [] | ||
currentContextualState = .none | ||
} | ||
} | ||
|
||
func handleAction(_ actionData: ContextualActionData, playerViewController: AVPlayerViewController) { | ||
switch actionData.action { | ||
case "SkipIntro": | ||
if currentContextualState != .skipIntro { | ||
let skipIntroAction = UIAction(title: "Skip Intro") { [weak self] _ in | ||
self?.handleSkipIntro() | ||
} | ||
playerViewController.contextualActions = [skipIntroAction] | ||
currentContextualState = .skipIntro | ||
} | ||
case "NextEpisode": | ||
if currentContextualState != .nextEpisode { | ||
let nextEpisodeAction = UIAction(title: "Next Episode") { [weak self] _ in | ||
self?.handleNextEpisode() | ||
} | ||
playerViewController.contextualActions = [nextEpisodeAction] | ||
currentContextualState = .nextEpisode | ||
} | ||
default: | ||
break | ||
} | ||
} | ||
|
||
func handleSkipIntro() { | ||
onSkipIntro?(["message": "Skip Intro triggered"]) | ||
let skipTime = CMTime(seconds: 120, preferredTimescale: 1) | ||
playerForContextualActions?.seek(to: skipTime, toleranceBefore: .zero, toleranceAfter: .zero) | ||
} | ||
|
||
func handleNextEpisode() { | ||
onNextEpisode?(["message": "Next Episode triggered"]) | ||
print("Next episode triggered") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
#import "RCTVideoSwiftLog.h" | ||
#import <React/RCTViewManager.h> | ||
|
||
#import <React/RCTEventDispatcher.h> | ||
#if __has_include(<react-native-video/RCTVideoCache.h>) | ||
#import "RCTVideoCache.h" | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters