Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/localize ads UI #244

Merged
merged 5 commits into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions android/src/main/java/com/theoplayer/PlayerConfigAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import com.theoplayer.android.api.cast.CastStrategy
import com.theoplayer.android.api.cast.CastConfiguration
import com.theoplayer.android.api.pip.PipConfiguration
import com.theoplayer.android.api.player.NetworkConfiguration
import com.theoplayer.android.api.ui.UIConfiguration

private const val PROP_LICENSE = "license"
private const val PROP_LICENSE_URL = "licenseUrl"
private const val PROP_PRELOAD = "preload"
private const val PROP_LANGUAGE = "language"
private const val PROP_UI_ENABLED = "uiEnabled"
private const val PROP_CAST_STRATEGY = "strategy"
private const val PROP_RETRY_CONFIG = "retryConfiguration"
Expand All @@ -24,6 +26,7 @@ private const val PROP_RETRY_MIN_BACKOFF = "minimumBackoff"
private const val PROP_RETRY_MAX_BACKOFF = "maximumBackoff"
private const val PROP_CAST_CONFIGURATION = "cast"
private const val PROP_ADS_CONFIGURATION = "ads"
private const val PROP_UI_CONFIGURATION = "ui"

class PlayerConfigAdapter(private val configProps: ReadableMap?) {

Expand All @@ -45,6 +48,9 @@ class PlayerConfigAdapter(private val configProps: ReadableMap?) {
if (hasKey(PROP_RETRY_CONFIG)) {
networkConfiguration(networkConfig())
}
if (hasKey(PROP_UI_CONFIGURATION)) {
ui(uiConfig())
}
if (hasKey(PROP_HLS_DATE_RANGE)) {
hlsDateRange(getBoolean(PROP_HLS_DATE_RANGE))
}
Expand Down Expand Up @@ -96,6 +102,21 @@ class PlayerConfigAdapter(private val configProps: ReadableMap?) {
}.build()
}

/**
* Get UIConfiguration object; these properties apply:
* - language: The language used to localize the ui elements.
*/
private fun uiConfig(): UIConfiguration {
return UIConfiguration.Builder().apply {
configProps?.getMap(PROP_UI_CONFIGURATION)?.run {
val languageString = getString(PROP_LANGUAGE)
if (languageString != null && !TextUtils.isEmpty(languageString)) {
language(languageString)
}
}
}.build()
}

/**
* Create a AdsRenderingSettings object.
*/
Expand Down
3 changes: 3 additions & 0 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ const playerConfig: PlayerConfiguration = {
},
strategy: 'auto',
},
ui: {
language: 'en',
},
mediaControl: {
mediaSessionEnabled: true,
},
Expand Down
7 changes: 5 additions & 2 deletions ios/THEOplayerRCTView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class THEOplayerRCTView: UIView {
var presentationModeContext = THEOplayerRCTPresentationModeContext()
var adsConfig = AdsConfig()
var castConfig = CastConfig()
var uiConfig = UIConfig()

var pipConfig = PipConfig() {
didSet {
Expand All @@ -39,7 +40,6 @@ public class THEOplayerRCTView: UIView {
private var licenseUrl: String?
private var chromeless: Bool = true
private var hlsDateRange: Bool = false
private var config: THEOplayerConfiguration?

// MARK: - Initialisation / view setup
init() {
Expand Down Expand Up @@ -110,6 +110,7 @@ public class THEOplayerRCTView: UIView {
cssPaths: cssPaths,
pip: self.playerPipConfiguration(),
ads: self.playerAdsConfiguration(),
ui: self.playerUIConfiguration(),
cast: self.playerCastConfiguration(),
hlsDateRange: self.hlsDateRange,
license: self.license,
Expand All @@ -127,7 +128,8 @@ public class THEOplayerRCTView: UIView {
hlsDateRange: self.hlsDateRange,
license: self.license,
licenseUrl: self.licenseUrl,
pip: self.playerPipConfiguration()))
pip: self.playerPipConfiguration(),
ui: self.playerUIConfiguration()))
self.initAdsIntegration()
self.initBackgroundAudio()
self.initPip()
Expand Down Expand Up @@ -176,6 +178,7 @@ public class THEOplayerRCTView: UIView {
self.hlsDateRange = configDict["hlsDateRange"] as? Bool ?? false
self.parseAdsConfig(configDict: configDict)
self.parseCastConfig(configDict: configDict)
self.parseUIConfig(configDict: configDict)
if DEBUG_VIEW { PrintUtils.printLog(logText: "[NATIVE] config prop updated.") }

// Given the bridged config, create the initial THEOplayer instance
Expand Down
23 changes: 23 additions & 0 deletions ios/ui/THEOplayerRCTView+UIConfig.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// THEOplayerRCTView+UIConfig.swift

import Foundation
import THEOplayerSDK

struct UIConfig {
var language: String = "en"
}

extension THEOplayerRCTView {

func parseUIConfig(configDict: NSDictionary) {
if let uiConfig = configDict["ui"] as? NSDictionary {
if let uiLanguage = uiConfig["language"] as? String {
self.uiConfig.language = uiLanguage
}
}
}

func playerUIConfiguration() -> UIConfiguration? {
return UIConfiguration(language: self.uiConfig.language)
}
}
2 changes: 1 addition & 1 deletion react-native-theoplayer.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Pod::Spec.new do |s|
s.platforms = { :ios => "12.0", :tvos => "12.0" }
s.source = { :git => "https://www.theoplayer.com/.git", :tag => "#{s.version}" }

s.source_files = 'ios/*.{h,m,swift}', 'ios/ads/*.swift', 'ios/casting/*.swift', 'ios/contentprotection/*.swift', 'ios/pip/*.swift', 'ios/backgroundAudio/*.swift', 'ios/cache/*.swift', 'ios/eventBroadcasting/*.swift'
s.source_files = 'ios/*.{h,m,swift}', 'ios/ads/*.swift', 'ios/casting/*.swift', 'ios/contentprotection/*.swift', 'ios/pip/*.swift', 'ios/backgroundAudio/*.swift', 'ios/cache/*.swift', 'ios/eventBroadcasting/*.swift' , 'ios/ui/*.swift'
s.resources = ['ios/*.css']

# ReactNative Dependency
Expand Down
6 changes: 6 additions & 0 deletions src/api/config/PlayerConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { AdsConfiguration } from '../ads/AdsConfiguration';
import type { CastConfiguration } from '../cast/CastConfiguration';
import type { MediaControlConfiguration } from '../media/MediaControlConfiguration';
import type { RetryConfiguration } from '../utils/RetryConfiguration';
import type { UIConfiguration } from '../ui/UIConfiguration';

export interface PlayerConfiguration {
/**
Expand Down Expand Up @@ -36,6 +37,11 @@ export interface PlayerConfiguration {
*/
cast?: CastConfiguration;

/**
* The ui configuration for the underlying native player. Applies to Ad UI.
*/
ui?: UIConfiguration;

/**
* The configuration of media controls and media sessions across platforms.
*/
Expand Down
18 changes: 18 additions & 0 deletions src/api/ui/UIConfiguration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Describes the UI related configuration of the player.
*
* @public
*/
export interface UIConfiguration {
/**
* The language which is used for localization.
*
* @example
* ```
* ui: {
* language: 'es',
* }
* ```
*/
language?: string;
}
1 change: 1 addition & 0 deletions src/api/ui/barrel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './UIConfiguration';
Loading