From 76fbeb64dd7757c4911138625b472f8c6206655b Mon Sep 17 00:00:00 2001 From: William Van Haevre Date: Tue, 19 Dec 2023 17:22:14 +0100 Subject: [PATCH 1/5] Setup UIConfiguration --- example/src/App.tsx | 3 +++ src/api/config/PlayerConfiguration.ts | 6 ++++++ src/api/ui/UIConfiguration.ts | 18 ++++++++++++++++++ src/api/ui/barrel.ts | 1 + 4 files changed, 28 insertions(+) create mode 100644 src/api/ui/UIConfiguration.ts create mode 100644 src/api/ui/barrel.ts diff --git a/example/src/App.tsx b/example/src/App.tsx index 041b1feba..04d8b7f15 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -45,6 +45,9 @@ const playerConfig: PlayerConfiguration = { }, strategy: 'auto', }, + ui: { + language: 'en', + }, mediaControl: { mediaSessionEnabled: true, }, diff --git a/src/api/config/PlayerConfiguration.ts b/src/api/config/PlayerConfiguration.ts index 5e8691d35..59a924275 100644 --- a/src/api/config/PlayerConfiguration.ts +++ b/src/api/config/PlayerConfiguration.ts @@ -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 { /** @@ -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. */ diff --git a/src/api/ui/UIConfiguration.ts b/src/api/ui/UIConfiguration.ts new file mode 100644 index 000000000..7687dfcdb --- /dev/null +++ b/src/api/ui/UIConfiguration.ts @@ -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; +} diff --git a/src/api/ui/barrel.ts b/src/api/ui/barrel.ts new file mode 100644 index 000000000..1d00e19e7 --- /dev/null +++ b/src/api/ui/barrel.ts @@ -0,0 +1 @@ +export * from './UIConfiguration'; From 11f672fbb1a8c19f61463e7921c4e6a3729f03e4 Mon Sep 17 00:00:00 2001 From: William Van Haevre Date: Tue, 19 Dec 2023 17:43:13 +0100 Subject: [PATCH 2/5] Drop unused property on iOS --- ios/THEOplayerRCTView.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/ios/THEOplayerRCTView.swift b/ios/THEOplayerRCTView.swift index e801849b6..125988eae 100644 --- a/ios/THEOplayerRCTView.swift +++ b/ios/THEOplayerRCTView.swift @@ -39,7 +39,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() { From f90a88b0108886e1e027679b7d113033ed797b69 Mon Sep 17 00:00:00 2001 From: William Van Haevre Date: Tue, 19 Dec 2023 17:56:29 +0100 Subject: [PATCH 3/5] Process uiConfiguration on iOS bridge --- ios/THEOplayerRCTView.swift | 6 +++++- ios/ui/THEOplayerRCTView+UIConfig.swift | 23 +++++++++++++++++++++++ react-native-theoplayer.podspec | 2 +- 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 ios/ui/THEOplayerRCTView+UIConfig.swift diff --git a/ios/THEOplayerRCTView.swift b/ios/THEOplayerRCTView.swift index 125988eae..8e0a143a0 100644 --- a/ios/THEOplayerRCTView.swift +++ b/ios/THEOplayerRCTView.swift @@ -19,6 +19,7 @@ public class THEOplayerRCTView: UIView { var presentationModeContext = THEOplayerRCTPresentationModeContext() var adsConfig = AdsConfig() var castConfig = CastConfig() + var uiConfig = UIConfig() var pipConfig = PipConfig() { didSet { @@ -109,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, @@ -126,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() @@ -175,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 diff --git a/ios/ui/THEOplayerRCTView+UIConfig.swift b/ios/ui/THEOplayerRCTView+UIConfig.swift new file mode 100644 index 000000000..130d7b500 --- /dev/null +++ b/ios/ui/THEOplayerRCTView+UIConfig.swift @@ -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) + } +} diff --git a/react-native-theoplayer.podspec b/react-native-theoplayer.podspec index c6315747c..eb3185e71 100644 --- a/react-native-theoplayer.podspec +++ b/react-native-theoplayer.podspec @@ -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 From 2cea5b88540fb8391638dfba365996c7e5164d20 Mon Sep 17 00:00:00 2001 From: William Van Haevre Date: Tue, 19 Dec 2023 18:15:50 +0100 Subject: [PATCH 4/5] Process uiConfiguration on Android bridge --- .../com/theoplayer/PlayerConfigAdapter.kt | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/android/src/main/java/com/theoplayer/PlayerConfigAdapter.kt b/android/src/main/java/com/theoplayer/PlayerConfigAdapter.kt index b1cc193ac..6f601f5d4 100644 --- a/android/src/main/java/com/theoplayer/PlayerConfigAdapter.kt +++ b/android/src/main/java/com/theoplayer/PlayerConfigAdapter.kt @@ -9,12 +9,14 @@ import com.theoplayer.android.api.ads.AdsConfiguration import com.theoplayer.android.api.ads.AdPreloadType import com.theoplayer.android.api.cast.CastStrategy import com.theoplayer.android.api.cast.CastConfiguration +import com.theoplayer.android.api.cast.UIConfiguration import com.theoplayer.android.api.pip.PipConfiguration import com.theoplayer.android.api.player.NetworkConfiguration 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" @@ -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?) { @@ -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)) } @@ -96,6 +102,23 @@ class PlayerConfigAdapter(private val configProps: ReadableMap?) { }.build() } + /** + * Get UIConfiguration object; these properties apply: + * - language: The language used to localize the ui elements. + */ + fun uiConfig(): UIConfiguration { + return UIConfiguration.Builder().apply { + configProps?.getMap(PROP_UI_CONFIGURATION)?.run { + if (hasKey(PROP_LANGUAGE)) { + val languageString = getString(PROP_LANGUAGE) + if (!TextUtils.isEmpty(languageString)) { + language(languageString) + } + } + } + }.build() + } + /** * Create a AdsRenderingSettings object. */ From 52f8119794422a657a3e497cf5b3020815203ca9 Mon Sep 17 00:00:00 2001 From: Tom Van Laerhoven Date: Wed, 20 Dec 2023 13:06:41 +0100 Subject: [PATCH 5/5] Fix UI config --- .../com/theoplayer/PlayerConfigAdapter.kt | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/android/src/main/java/com/theoplayer/PlayerConfigAdapter.kt b/android/src/main/java/com/theoplayer/PlayerConfigAdapter.kt index 6f601f5d4..b64843599 100644 --- a/android/src/main/java/com/theoplayer/PlayerConfigAdapter.kt +++ b/android/src/main/java/com/theoplayer/PlayerConfigAdapter.kt @@ -9,9 +9,9 @@ import com.theoplayer.android.api.ads.AdsConfiguration import com.theoplayer.android.api.ads.AdPreloadType import com.theoplayer.android.api.cast.CastStrategy import com.theoplayer.android.api.cast.CastConfiguration -import com.theoplayer.android.api.cast.UIConfiguration 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" @@ -103,21 +103,19 @@ class PlayerConfigAdapter(private val configProps: ReadableMap?) { } /** - * Get UIConfiguration object; these properties apply: - * - language: The language used to localize the ui elements. - */ - fun uiConfig(): UIConfiguration { - return UIConfiguration.Builder().apply { - configProps?.getMap(PROP_UI_CONFIGURATION)?.run { - if (hasKey(PROP_LANGUAGE)) { - val languageString = getString(PROP_LANGUAGE) - if (!TextUtils.isEmpty(languageString)) { - language(languageString) - } - } + * 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() - } + } + }.build() + } /** * Create a AdsRenderingSettings object.