- Handled the playlist sending to the player

- Playing the selected index.
- Got an jwplayer update, now playlist will b visible from bottom bar button, it will show the list of episodes and user can select.
- If user does seek the player , we will provide autoplay.
- Worked on next button issue
This commit is contained in:
2024-06-25 19:41:04 +05:30
parent 93956e6e98
commit 3462b48095
11 changed files with 416 additions and 34 deletions

View File

@@ -61,6 +61,7 @@
5259545A2BEB67D200191286 /* DateFormatterLib.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525954592BEB67D200191286 /* DateFormatterLib.swift */; };
5259545C2BEBB80400191286 /* AvatarDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5259545B2BEBB80400191286 /* AvatarDM.swift */; };
5259545E2BEBBA1A00191286 /* LoadingIndicatorImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5259545D2BEBBA1A00191286 /* LoadingIndicatorImageView.swift */; };
525FD79B2C2AFB990062C80F /* JWPlayerKit in Frameworks */ = {isa = PBXBuildFile; productRef = 525FD79A2C2AFB990062C80F /* JWPlayerKit */; };
52663FF52BDFAB830001D8CE /* TextFieldErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52663FF42BDFAB830001D8CE /* TextFieldErrorView.swift */; };
52663FF72BDFACF60001D8CE /* ShadowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52663FF62BDFACF60001D8CE /* ShadowView.swift */; };
52663FF92BDFAF110001D8CE /* EmailVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52663FF82BDFAF110001D8CE /* EmailVM.swift */; };
@@ -151,7 +152,7 @@
52D774F12BDFC53B001D87DE /* StringSubScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52D774F02BDFC53B001D87DE /* StringSubScript.swift */; };
52DAC6482C21762900E2F85B /* WebSeries.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 52DAC6472C21762900E2F85B /* WebSeries.storyboard */; };
52DAC64E2C21775300E2F85B /* WebSeriesVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52DAC64D2C21775300E2F85B /* WebSeriesVC.swift */; };
52E59A922C29AE3F00BB9B04 /* JWPlayerKit in Frameworks */ = {isa = PBXBuildFile; productRef = 52E59A912C29AE3F00BB9B04 /* JWPlayerKit */; };
52E214C72C2AD47F00BC2D29 /* EpisodeDetailsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52E214C62C2AD47F00BC2D29 /* EpisodeDetailsVC.swift */; };
52FB2D8F2BDF898F0009B0C7 /* TextFieldPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52FB2D8E2BDF898F0009B0C7 /* TextFieldPadding.swift */; };
52FDBA782BFF23F4009D7AC7 /* TimePeriod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52FDBA772BFF23F4009D7AC7 /* TimePeriod.swift */; };
52FDBA7B2BFF2712009D7AC7 /* AuthFuncTimeHandling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52FDBA7A2BFF2712009D7AC7 /* AuthFuncTimeHandling.swift */; };
@@ -407,6 +408,7 @@
52D774F02BDFC53B001D87DE /* StringSubScript.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringSubScript.swift; sourceTree = "<group>"; };
52DAC6472C21762900E2F85B /* WebSeries.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = WebSeries.storyboard; sourceTree = "<group>"; };
52DAC64D2C21775300E2F85B /* WebSeriesVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebSeriesVC.swift; sourceTree = "<group>"; };
52E214C62C2AD47F00BC2D29 /* EpisodeDetailsVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EpisodeDetailsVC.swift; sourceTree = "<group>"; };
52E7E0F62BDF7DD500C86E10 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/AuthenticationSB.strings; sourceTree = "<group>"; };
52E7E0F82BDF7DD900C86E10 /* hi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hi; path = hi.lproj/AuthenticationSB.strings; sourceTree = "<group>"; };
52FB2D8E2BDF898F0009B0C7 /* TextFieldPadding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldPadding.swift; sourceTree = "<group>"; };
@@ -489,7 +491,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
52E59A922C29AE3F00BB9B04 /* JWPlayerKit in Frameworks */,
525FD79B2C2AFB990062C80F /* JWPlayerKit in Frameworks */,
9C1C69FA2C106B290035B2C7 /* RSKPlaceholderTextView in Frameworks */,
619A5A1BD8BD968ADC83C106 /* Pods_WOKA.framework in Frameworks */,
);
@@ -976,6 +978,7 @@
children = (
52DAC64D2C21775300E2F85B /* WebSeriesVC.swift */,
5242FE582C24203E0086A86D /* WebSeriesSeasonVC.swift */,
52E214C62C2AD47F00BC2D29 /* EpisodeDetailsVC.swift */,
);
path = Controller;
sourceTree = "<group>";
@@ -1296,7 +1299,7 @@
name = WOKA;
packageProductDependencies = (
9C1C69F92C106B290035B2C7 /* RSKPlaceholderTextView */,
52E59A912C29AE3F00BB9B04 /* JWPlayerKit */,
525FD79A2C2AFB990062C80F /* JWPlayerKit */,
);
productName = WOKA;
productReference = 523ED25A2BDA2BC700CFED02 /* WOKA.app */;
@@ -1373,7 +1376,7 @@
mainGroup = 523ED2512BDA2BC700CFED02;
packageReferences = (
9C1C69F82C106B290035B2C7 /* XCRemoteSwiftPackageReference "RSKPlaceholderTextView" */,
52E59A902C29AE3F00BB9B04 /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */,
525FD7992C2AFB990062C80F /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */,
);
productRefGroup = 523ED25B2BDA2BC700CFED02 /* Products */;
projectDirPath = "";
@@ -1654,6 +1657,7 @@
52AC2D252C295A7900337473 /* TeaserDM.swift in Sources */,
9C535DC22C00B36900DA6DCD /* ThemeTwoVC.swift in Sources */,
9CA7C6C22C1095B600D73742 /* ProfileVM.swift in Sources */,
52E214C72C2AD47F00BC2D29 /* EpisodeDetailsVC.swift in Sources */,
52D774F12BDFC53B001D87DE /* StringSubScript.swift in Sources */,
9CBE1B3F2C0F37B300CA6E61 /* DPDConstants.swift in Sources */,
52B8D4DA2C04A25E00ED65F3 /* Preferences.swift in Sources */,
@@ -2082,7 +2086,7 @@
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
52E59A902C29AE3F00BB9B04 /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */ = {
525FD7992C2AFB990062C80F /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/jwplayer/JWPlayerKit-package.git";
requirement = {
@@ -2101,9 +2105,9 @@
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
52E59A912C29AE3F00BB9B04 /* JWPlayerKit */ = {
525FD79A2C2AFB990062C80F /* JWPlayerKit */ = {
isa = XCSwiftPackageProductDependency;
package = 52E59A902C29AE3F00BB9B04 /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */;
package = 525FD7992C2AFB990062C80F /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */;
productName = JWPlayerKit;
};
9C1C69F92C106B290035B2C7 /* RSKPlaceholderTextView */ = {

View File

@@ -0,0 +1,24 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "PlayButton@2x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -56,13 +56,12 @@ extension K{
static let myOrdersVC = "MyOrdersVC"
}
/*
Web Series
*/
// MARK: - Web Series
struct WebSeries{
static let webSeriesVC = "WebSeriesVC"
static let webSeriesSeasonVC = "WebSeriesSeasonVC"
static let episodeDetailsVC = "EpisodeDetailsVC"
}
}
}

View File

@@ -225,3 +225,4 @@
"TEASERS" = "टीज़र";
"CONTINUE WATCHING" = "देखना जारी रखें";
"PLAY TRAILER" = "प्ले ट्रेलर";
"Teaser" = "टीज़र";

View File

@@ -1031,10 +1031,10 @@
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemBrownColor">
<color red="0.63529411759999999" green="0.51764705879999995" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.63529411764705879" green="0.51764705882352946" blue="0.36862745098039218" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemGreenColor">
<color red="0.20392156859999999" green="0.78039215689999997" blue="0.34901960780000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.20392156862745098" green="0.7803921568627451" blue="0.34901960784313724" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
</resources>
</document>

View File

@@ -13,7 +13,7 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate {
@IBOutlet weak var innerPlayerView: UIView!
var previousScale: CGFloat = 1.0
let backButton = UIButton(type: .system)
// let backButton = UIButton(type: .system)
var config: JWPlayerConfiguration!
var dismissTapped: (() -> Void)?
var videoIndex : Int?
@@ -30,6 +30,7 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate {
UIView.setAnimationsEnabled(true)
}
func rotateToPotraitScapeDevice(){
let appDelegate = UIApplication.shared.delegate as! AppDelegate
@@ -46,11 +47,16 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
player.configurePlayer(with: config)
self.rotateToLandsScapeDevice()
self.delegate = self
player.configurePlayer(with: config)
//Disable Picture in Picture
playerView.allowsPictureInPicturePlayback = false
// playerView.captionStyle = .none
}
@objc func applicationDidBecomeActive() {
self.setDeviceOrientation(orientation: .landscapeRight)
}
@@ -65,13 +71,9 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate {
}
}
// @objc func backButtonTapped() {
// setDeviceOrientation(orientation: .portrait)
// }
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.isNavigationBarHidden = true
// self.navigationController?.isNavigationBarHidden = true
}
override func viewWillDisappear(_ animated: Bool) {
@@ -86,11 +88,35 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate {
print("LoadTime", loadTime)
// self.player.play()
}
//Playlist Functions
//
// override func jwplayer(_ player: any JWPlayer, didLoadPlaylist playlist: [JWPlayerItem]) {
// print("DidLoad", playlist.count , playlist)
//// player.loadPlayerItemAt(index: videoIndex ?? 0)
//// player.play(relatedContent: videoIndex ?? 0)
//
// }
//
override func jwplayerHasSeeked(_ player: any JWPlayer) {
// player.play()
if player.getState() != .playing{
print("Again Play")
player.play()
}
print("Seeked")
}
override func jwplayer(_ player: any JWPlayer, didLoadPlaylistItem item: JWPlayerItem, at index: UInt) {
// player.loadPlayerItemAt(index: 4)
// player.play(relatedContent: 4)
print("Item" , item)
}
override func jwplayerIsReady(_ player: JWPlayer) {
super.jwplayerIsReady(player)
player.loadPlayerItemAt(index: 4)
player.seek(to: 30)
// player.seek(to: 30)
// player.play()
print("IsReady")
}
@@ -207,7 +233,7 @@ extension PlayerVC {
extension PlayerVC {
func playerViewController(_ controller: JWPlayerKit.JWPlayerViewController, controlBarVisibilityChanged isVisible: Bool, frame: CGRect) {
backButton.isHidden = !isVisible
// backButton.isHidden = !isVisible
}
func playerViewController(_ controller: JWPlayerKit.JWPlayerViewController, sizeChangedFrom oldSize: CGSize, to newSize: CGSize) {

View File

@@ -0,0 +1,92 @@
//
// EpisodeDetailsVC.swift
// WOKA
//
// Created by MacBook Pro on 25/06/24.
//
import UIKit
class EpisodeDetailsVC: UIViewController {
@IBOutlet weak var episodeImage: UIImageView!
@IBOutlet weak var episodeTitle: UILabel!
@IBOutlet weak var mediaType: UILabel!
@IBOutlet weak var episodeTimeLine: UILabel!
@IBOutlet weak var episodeDesc: UITextView!
@IBOutlet weak var watchBtn: LocalisedElementsButton!
// Completion block to be executed when the alert is dismissed
var onDoneBlock: (() -> Void)?
var teaserData : TeaserDM.ResultData?
var episodeData : SeasonEpisodeListingDM.EpisodeDatum?
override func viewDidLoad() {
super.viewDidLoad()
episodeDesc.font = FontCustom.shareInstance.customFont(fontName: .Exo2_Medium, size: 16)
watchBtn.addShadowAndCorner(radius: 25, shadowColor: .black, shadowOpacity: 0.6, shadowOffset: CGSize(width: 0, height: 0.5), shadowRadius: 5)
if teaserData != nil{
initTeaser()
}
if episodeData != nil{
initEpisode()
}
}
func initEpisode(){
guard let episodeData else{return}
episodeImage.imageURL(episodeData.thumbnailPath ?? "", color: .black)
if AuthFunc.shareInstance.getDefaultLanguage() == .english{
guard let englishData = episodeData.contentMoreDetails?.filter({$0.languageMasterID == 1}).first else{return}
episodeTitle.text = englishData.title
if let desc = englishData.description?.replacingOccurrences(of: "<br>", with: "").htmlToAttributedString{
let sizeText = NSMutableAttributedString(attributedString: desc)
sizeText.setFontFace(font: FontCustom.shareInstance.customFont(fontName: .Exo2_Regular, size: 15),color: UIColor.appColor(.TextDarkBlue)!)
self.episodeDesc.attributedText = sizeText
}
}else{
guard let hindiData = episodeData.contentMoreDetails?.filter({$0.languageMasterID == 2}).first else{return}
episodeTitle.text = hindiData.title
if let desc = hindiData.description?.replacingOccurrences(of: "<br>", with: "").htmlToAttributedString{
let sizeText = NSMutableAttributedString(attributedString: desc)
sizeText.setFontFace(font: FontCustom.shareInstance.customFont(fontName: .Exo2_Regular, size: 15),color: UIColor.appColor(.TextDarkBlue)!)
self.episodeDesc.attributedText = sizeText
}
}
mediaType.text = "Episode".localized(loc: AuthFunc.shareInstance.languageSelected.rawValue) + " " + (episodeData.episodeNumber?.toString() ?? "0")
episodeTimeLine.text = episodeData.episodeDuration
}
func initTeaser(){
guard let teaserData else{return}
episodeImage.imageURL(teaserData.thumbnailPath ?? "", color: .black)
if AuthFunc.shareInstance.getDefaultLanguage() == .english{
guard let englishData = teaserData.contentMoreDetails?.filter({$0.languageMasterID == 1}).first else{return}
episodeTitle.text = englishData.title
episodeDesc.text = englishData.description
}else{
guard let hindiData = teaserData.contentMoreDetails?.filter({$0.languageMasterID == 2}).first else{return}
episodeTitle.text = hindiData.title
episodeDesc.text = hindiData.description
}
mediaType.text = "Teaser".localized(loc: AuthFunc.shareInstance.languageSelected.rawValue) + " " + (teaserData.serialNumber?.toString() ?? "0")
episodeTimeLine.text = teaserData.teaserDuration
}
@IBAction func closeBtnTapped(_ sender: UIButton) {
self.dismiss(animated: true)
}
@IBAction func watchBtnTapped(_ sender: LocalisedElementsButton) {
self.dismiss(animated: true) {
self.onDoneBlock?()
}
}
}

View File

@@ -110,21 +110,62 @@ extension WebSeriesSeasonVC : TableViewSRC{
cell.btnTapped = { [self] () -> Void in
var urls = [String]()
var title = [String]()
var poster = [String]()
if let episodeData = vm.seasonEpisodeData.first?.episodeData{
for i in episodeData{
urls.append(i.episodeURL ?? "")
title.append(i.episodeTitle ?? "Episode")
poster.append(i.thumbnailPath ?? "")
}
}
if let data = vm.seasonEpisodeData.first?.episodeData?[indexPath.row] , let url = data.episodeURL{
JWPlayerManager.shared.presentPlayer(from: self, withURLs: urls, titles: title,startIndex: indexPath.row)
}
// if let data = vm.seasonEpisodeData.first?.episodeData?[indexPath.row] , let url = data.episodeURL{
// Ensure indexPath.row is valid before proceeding
if indexPath.row < urls.count {
JWPlayerManager.shared.presentPlayer(from: self, withURLs: urls, poster: poster, titles: title, startIndex: indexPath.row)
} else {
print("Index out of bounds for episode data")
}// }
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let sb = UIStoryboard(name: K.StoryBoard.webSeries, bundle: nil)
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.WebSeries.episodeDetailsVC) as! EpisodeDetailsVC
switch tableView{
case teaserTableView:
let data = vm.teaserData[indexPath.row]
vcPush.teaserData = data
default:
let data = vm.seasonEpisodeData.first?.episodeData?[indexPath.row]
vcPush.episodeData = data
}
vcPush.onDoneBlock = { [weak self] in
guard let self else{return}
var urls = [String]()
var title = [String]()
var poster = [String]()
if let episodeData = vm.seasonEpisodeData.first?.episodeData{
for i in episodeData{
urls.append(i.episodeURL ?? "")
title.append(i.episodeTitle ?? "Episode")
poster.append(i.thumbnailPath ?? "")
}
}
// if let data = vm.seasonEpisodeData.first?.episodeData?[indexPath.row] , let url = data.episodeURL{
JWPlayerManager.shared.presentPlayer(from: self, withURLs: urls, poster: poster, titles: title,startIndex: indexPath.row)
// }
}
vcPush.modalPresentationStyle = .overCurrentContext
vcPush.modalTransitionStyle = .crossDissolve
self.present(vcPush, animated: true)
}
}
// MARK: - CollectionView Delegate

View File

@@ -13,7 +13,7 @@ class JWPlayerManager {
private init() {}
func presentPlayer(from viewController: UIViewController, withURLs liveStreamURLs: [String], titles: [String]? = nil, startIndex: Int = 0, completion: (() -> Void)? = nil) {
func presentPlayer(from viewController: UIViewController, withURLs liveStreamURLs: [String], poster : [String], titles: [String]? = nil, startIndex: Int = 0, completion: (() -> Void)? = nil) {
DispatchQueue.main.async {
Utilities.startProgressHUD(msg: "Loading...")
}
@@ -46,9 +46,13 @@ class JWPlayerManager {
// Use the corresponding title if provided, otherwise use a default title
let itemTitle = titles?[index] ?? "Default Title \(index + 1)"
let itemPoster = poster[index]
let item = try JWPlayerItemBuilder()
.file(url)
.title(itemTitle)
.posterImage(URL(string: itemPoster)!)
.build()
items.append(item)

View File

@@ -404,17 +404,16 @@
<rect key="frame" x="0.0" y="453" width="373" height="50"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="PzY-0K-yPM" customClass="LocalisedElementsButton" customModule="WOKA" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="150" height="50"/>
<rect key="frame" x="0.0" y="0.0" width="130" height="50"/>
<color key="backgroundColor" red="0.36862745099999999" green="0.1215686275" blue="0.76862745099999996" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" constant="150" id="UqM-B3-bVp"/>
<constraint firstAttribute="width" constant="130" id="UqM-B3-bVp"/>
<constraint firstAttribute="height" constant="50" id="ldT-CD-cmn"/>
</constraints>
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="18"/>
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<inset key="titleEdgeInsets" minX="15" minY="0.0" maxX="0.0" maxY="0.0"/>
<inset key="imageEdgeInsets" minX="0.0" minY="5" maxX="10" maxY="5"/>
<state key="normal" title="WATCH" image="PlayButton">
<state key="normal" title="WATCH" image="PlayButtonSmall">
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="small"/>
</state>
<userDefinedRuntimeAttributes>
@@ -647,10 +646,199 @@
</objects>
<point key="canvasLocation" x="762.59541984732823" y="3.5211267605633805"/>
</scene>
<!--Episode DetailsVC-->
<scene sceneID="d1D-ZL-WHo">
<objects>
<viewController storyboardIdentifier="EpisodeDetailsVC" id="g22-Ng-gIp" customClass="EpisodeDetailsVC" customModule="WOKA" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="cwv-LV-FrW">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view alpha="0.59999999999999998" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="J0B-2b-uIR">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
<stackView opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="7Za-5O-Y7M">
<rect key="frame" x="20" y="128.66666666666669" width="353" height="619.66666666666652"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Biv-5W-r1q">
<rect key="frame" x="0.0" y="0.0" width="353" height="50"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="07b-JG-Iwe">
<rect key="frame" x="308" y="10" width="40" height="40"/>
<constraints>
<constraint firstAttribute="width" secondItem="07b-JG-Iwe" secondAttribute="height" multiplier="1:1" id="xqV-XC-IUL"/>
</constraints>
<color key="tintColor" red="0.1058823529" green="0.050980392159999999" blue="0.60392156860000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" image="CloseIconEmpty"/>
<connections>
<action selector="closeBtnTapped:" destination="g22-Ng-gIp" eventType="touchUpInside" id="C4H-4g-Z0D"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="aUg-cW-rLl"/>
<constraint firstAttribute="trailing" secondItem="07b-JG-Iwe" secondAttribute="trailing" constant="5" id="cC3-hP-Jva"/>
<constraint firstItem="07b-JG-Iwe" firstAttribute="top" secondItem="Biv-5W-r1q" secondAttribute="top" constant="10" id="i0N-vz-YHw"/>
<constraint firstAttribute="bottom" secondItem="07b-JG-Iwe" secondAttribute="bottom" id="vec-dZ-Ib1"/>
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="nlc-mN-jov" userLabel="MainStack">
<rect key="frame" x="0.0" y="50" width="353" height="569.66666666666663"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="iP0-wt-fB0" customClass="ShadowView" customModule="WOKA" customModuleProvider="target">
<rect key="frame" x="13" y="5" width="327" height="200"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="kLS-Wx-OhG">
<rect key="frame" x="8" y="8" width="311" height="184"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<integer key="value" value="10"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</imageView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="kLS-Wx-OhG" secondAttribute="bottom" constant="8" id="4lF-ru-7cP"/>
<constraint firstItem="kLS-Wx-OhG" firstAttribute="top" secondItem="iP0-wt-fB0" secondAttribute="top" constant="8" id="6MV-9u-rnZ"/>
<constraint firstAttribute="height" constant="200" id="9xg-2j-XbK"/>
<constraint firstAttribute="trailing" secondItem="kLS-Wx-OhG" secondAttribute="trailing" constant="8" id="DuK-eU-oVn"/>
<constraint firstItem="kLS-Wx-OhG" firstAttribute="leading" secondItem="iP0-wt-fB0" secondAttribute="leading" constant="8" id="j3j-OP-KCn"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<integer key="value" value="10"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="d6P-D7-drT">
<rect key="frame" x="13" y="215.00000000000003" width="327" height="45.999999999999972"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="dasdasdas" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7uy-rI-kJq">
<rect key="frame" x="0.0" y="0.0" width="327" height="21.666666666666668"/>
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="18"/>
<color key="textColor" name="TextDarkBlue"/>
<nil key="highlightedColor"/>
</label>
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" translatesAutoresizingMaskIntoConstraints="NO" id="ulr-0l-lOP">
<rect key="frame" x="0.0" y="26.666666666666629" width="327" height="19.333333333333329"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" usesAttributedText="YES" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5oH-Sl-hBR">
<rect key="frame" x="0.0" y="0.0" width="59.333333333333336" height="19.333333333333332"/>
<attributedString key="attributedText">
<fragment content="Teaser 1">
<attributes>
<color key="NSColor" name="TextDarkBlue"/>
<font key="NSFont" size="16" name="Exo2-SemiBold"/>
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
</attributes>
</fragment>
</attributedString>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" usesAttributedText="YES" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xIn-Hw-0Dg">
<rect key="frame" x="267.66666666666669" y="0.0" width="59.333333333333314" height="19.333333333333332"/>
<attributedString key="attributedText">
<fragment content="Teaser 1">
<attributes>
<color key="NSColor" name="TextDarkBlue"/>
<font key="NSFont" size="16" name="Exo2-SemiBold"/>
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
</attributes>
</fragment>
</attributedString>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
</stackView>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="43n-nG-E8Z">
<rect key="frame" x="13" y="271" width="327" height="208.66666666666663"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<string key="text">Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda.</string>
<color key="textColor" systemColor="labelColor"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" translatesAutoresizingMaskIntoConstraints="NO" id="0wf-Tv-Y2a">
<rect key="frame" x="13" y="489.66666666666674" width="327" height="50"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="VL1-Bn-5IK" customClass="LocalisedElementsButton" customModule="WOKA" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="150" height="50"/>
<color key="backgroundColor" red="0.36862745099999999" green="0.1215686275" blue="0.76862745099999996" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" constant="150" id="3bE-0Z-Ldw"/>
<constraint firstAttribute="height" constant="50" id="y75-rR-kXp"/>
</constraints>
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="18"/>
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<inset key="titleEdgeInsets" minX="15" minY="0.0" maxX="0.0" maxY="0.0"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="10" maxY="0.0"/>
<state key="normal" title="WATCH" image="PlayButtonSmall">
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="small"/>
</state>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<integer key="value" value="25"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="watchBtnTapped:" destination="sPj-Um-9Xm" eventType="touchUpInside" id="LEH-1L-qeL"/>
<action selector="watchBtnTapped:" destination="g22-Ng-gIp" eventType="touchUpInside" id="dsc-Nv-k9U"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="50" id="2Mn-ie-bCe"/>
</constraints>
</stackView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<edgeInsets key="layoutMargins" top="5" left="13" bottom="30" right="13"/>
</stackView>
</subviews>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<integer key="value" value="10"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</stackView>
</subviews>
<viewLayoutGuide key="safeArea" id="5w4-1v-170"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="J0B-2b-uIR" secondAttribute="bottom" id="2nZ-MT-cya"/>
<constraint firstItem="J0B-2b-uIR" firstAttribute="trailing" secondItem="5w4-1v-170" secondAttribute="trailing" id="Hdd-yu-67K"/>
<constraint firstItem="43n-nG-E8Z" firstAttribute="height" relation="greaterThanOrEqual" secondItem="cwv-LV-FrW" secondAttribute="height" multiplier="0.211268" id="IRh-AV-xaB"/>
<constraint firstItem="5w4-1v-170" firstAttribute="trailing" secondItem="7Za-5O-Y7M" secondAttribute="trailing" constant="20" id="LTo-2V-J9b"/>
<constraint firstItem="J0B-2b-uIR" firstAttribute="top" secondItem="cwv-LV-FrW" secondAttribute="top" id="Nbp-o0-xQb"/>
<constraint firstItem="7Za-5O-Y7M" firstAttribute="top" secondItem="5w4-1v-170" secondAttribute="top" constant="69.666666666666629" id="kGp-zI-AZq"/>
<constraint firstItem="J0B-2b-uIR" firstAttribute="leading" secondItem="5w4-1v-170" secondAttribute="leading" id="sSi-np-Hr4"/>
<constraint firstItem="7Za-5O-Y7M" firstAttribute="centerY" secondItem="5w4-1v-170" secondAttribute="centerY" id="w50-e0-Wah"/>
<constraint firstItem="7Za-5O-Y7M" firstAttribute="leading" secondItem="5w4-1v-170" secondAttribute="leading" constant="20" id="xuG-Qs-784"/>
</constraints>
</view>
<connections>
<outlet property="episodeDesc" destination="43n-nG-E8Z" id="Qee-o0-zfy"/>
<outlet property="episodeImage" destination="kLS-Wx-OhG" id="C9D-k2-KHk"/>
<outlet property="episodeTimeLine" destination="xIn-Hw-0Dg" id="FGk-wp-Ghe"/>
<outlet property="episodeTitle" destination="7uy-rI-kJq" id="HkH-ak-UlL"/>
<outlet property="mediaType" destination="5oH-Sl-hBR" id="ZWt-um-7TV"/>
<outlet property="watchBtn" destination="VL1-Bn-5IK" id="ieR-wY-pID"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="jGE-lo-GkG" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1610" y="4"/>
</scene>
</scenes>
<resources>
<image name="CloseIconEmpty" width="30" height="30"/>
<image name="MasilaComingSoon" width="200" height="100"/>
<image name="PlayButton" width="42.666667938232422" height="42.666667938232422"/>
<image name="PlayButtonSmall" width="28.333333969116211" height="28.333333969116211"/>
<image name="ShareImage" width="18" height="18"/>
<image name="SupportBottomArrow" width="16.333333969116211" height="16.333333969116211"/>
<image name="WebSeriesSeasonsBackground" width="142.66667175292969" height="187.33332824707031"/>
@@ -660,6 +848,9 @@
<namedColor name="TextDarkBlue">
<color red="0.10599999874830246" green="0.050999999046325684" blue="0.60399997234344482" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
<systemColor name="labelColor">
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>