- added api for fetching the episode as per the selected category

- made the category collection cells dynamic
- handled the category selection will call the episode api
- solved activity indicator view at the splash start-up
- handled the app lifecycle for live tv app going in foreground and background
- handled play pause while the live tv view apperas and disappears
- Made the likes and favourites dynamic on episode screen
This commit is contained in:
Bilal
2024-06-21 19:35:40 +05:30
parent 95495dc414
commit 1f650bd2b7
20 changed files with 559 additions and 168 deletions

View File

@@ -156,6 +156,9 @@
52FDBA7D2BFF481A009D7AC7 /* ThemeOneVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52FDBA7C2BFF481A009D7AC7 /* ThemeOneVM.swift */; };
52FDDAB52BF34DC300E037C1 /* YesNoAlertVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52FDDAB42BF34DC300E037C1 /* YesNoAlertVC.swift */; };
619A5A1BD8BD968ADC83C106 /* Pods_WOKA.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BBA543A4216400A2864E3D3E /* Pods_WOKA.framework */; };
9C007F202C255DF200F798C2 /* SeasonEpisodeListingDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C007F1F2C255DF200F798C2 /* SeasonEpisodeListingDM.swift */; };
9C007F232C25603800F798C2 /* WebSeriesEpisodeCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C007F212C25603800F798C2 /* WebSeriesEpisodeCell.swift */; };
9C007F242C25603800F798C2 /* WebSeriesEpisodeCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9C007F222C25603800F798C2 /* WebSeriesEpisodeCell.xib */; };
9C0A853F2BEE35340093783D /* ForgotPassDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C0A853E2BEE35340093783D /* ForgotPassDM.swift */; };
9C0A85412BEE35670093783D /* ResetPassUserNameVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C0A85402BEE35670093783D /* ResetPassUserNameVM.swift */; };
9C0A85432BEE3EC90093783D /* NewPasswordVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C0A85422BEE3EC90093783D /* NewPasswordVM.swift */; };
@@ -407,6 +410,9 @@
52FDBA7A2BFF2712009D7AC7 /* AuthFuncTimeHandling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthFuncTimeHandling.swift; sourceTree = "<group>"; };
52FDBA7C2BFF481A009D7AC7 /* ThemeOneVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeOneVM.swift; sourceTree = "<group>"; };
52FDDAB42BF34DC300E037C1 /* YesNoAlertVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YesNoAlertVC.swift; sourceTree = "<group>"; };
9C007F1F2C255DF200F798C2 /* SeasonEpisodeListingDM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeasonEpisodeListingDM.swift; sourceTree = "<group>"; };
9C007F212C25603800F798C2 /* WebSeriesEpisodeCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebSeriesEpisodeCell.swift; sourceTree = "<group>"; };
9C007F222C25603800F798C2 /* WebSeriesEpisodeCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WebSeriesEpisodeCell.xib; sourceTree = "<group>"; };
9C0A853E2BEE35340093783D /* ForgotPassDM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForgotPassDM.swift; sourceTree = "<group>"; };
9C0A85402BEE35670093783D /* ResetPassUserNameVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResetPassUserNameVM.swift; sourceTree = "<group>"; };
9C0A85422BEE3EC90093783D /* NewPasswordVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewPasswordVM.swift; sourceTree = "<group>"; };
@@ -987,6 +993,8 @@
52D6A2562C22C1E300145908 /* WebSeriesShowListingCell.xib */,
528E5F202C24660F00E33E4E /* SeasonCategoryCell.swift */,
528E5F212C24660F00E33E4E /* SeasonCategoryCell.xib */,
9C007F212C25603800F798C2 /* WebSeriesEpisodeCell.swift */,
9C007F222C25603800F798C2 /* WebSeriesEpisodeCell.xib */,
);
path = View;
sourceTree = "<group>";
@@ -998,6 +1006,7 @@
52D6A24D2C22B3AB00145908 /* WebSeriesShowListDM.swift */,
52D6A2532C22B93F00145908 /* CategoryListingDM.swift */,
528E5F1A2C24531200E33E4E /* SeasonListingDM.swift */,
9C007F1F2C255DF200F798C2 /* SeasonEpisodeListingDM.swift */,
);
path = Model;
sourceTree = "<group>";
@@ -1385,6 +1394,7 @@
525954302BEA394400191286 /* CustomAlerts.storyboard in Resources */,
52C8B0632BDA6993003B51D0 /* Localizable.strings in Resources */,
523ED2672BDA2BC900CFED02 /* Assets.xcassets in Resources */,
9C007F242C25603800F798C2 /* WebSeriesEpisodeCell.xib in Resources */,
527AC6FE2C173A5100434FB7 /* SongListCell.xib in Resources */,
523ED26A2BDA2BC900CFED02 /* Base in Resources */,
52C8B05B2BDA5924003B51D0 /* WokaSplashSound.m4a in Resources */,
@@ -1491,6 +1501,7 @@
9C535DC62C00BF2400DA6DCD /* HomeExploreCell.swift in Sources */,
52D774EF2BDFC50D001D87DE /* StringValidations.swift in Sources */,
52D6A2512C22B58200145908 /* WebSeriesShowListingCell.swift in Sources */,
9C007F232C25603800F798C2 /* WebSeriesEpisodeCell.swift in Sources */,
5272FCE32BDFDB05000ECB1D /* UserDetailsRegisterVC.swift in Sources */,
525954102BE8B72900191286 /* FontCustom.swift in Sources */,
5202AAFE2BDF90590043B7BD /* TextFieldImage.swift in Sources */,
@@ -1533,6 +1544,7 @@
52BC3BF02C1701F8002FACA6 /* BlogDM.swift in Sources */,
525954192BE8CC3400191286 /* ConstantString.swift in Sources */,
52D774EB2BDFC0BF001D87DE /* OTPVC.swift in Sources */,
9C007F202C255DF200F798C2 /* SeasonEpisodeListingDM.swift in Sources */,
52D2F3D82C24043D009E52FF /* ShimmerEffectView.swift in Sources */,
9C27E16F2BDB866500EC1DA9 /* CellIdentifier.swift in Sources */,
52BC3BF22C170264002FACA6 /* MoreVM.swift in Sources */,

View File

@@ -19,5 +19,8 @@
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

View File

@@ -42,6 +42,7 @@ extension K{
static let webSeriesCell = "WebSeriesCell"
static let webSeriesShowListingCell = "WebSeriesShowListingCell"
static let seasonCategoryCell = "SeasonCategoryCell"
static let webSeriesEpisodeCell = "WebSeriesEpisodeCell"
}
}
}

View File

@@ -1222,7 +1222,7 @@
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</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

@@ -84,6 +84,7 @@ struct APIEndPoints {
static let watch_show_listing = makeURL(path: "watch_show_listing")
static let category_listing = makeURL(path: "category_listing")
static let season_listing = makeURL(path: "season_listing")
static let season_episode_listing = makeURL(path: "season_episode_listing")
}
// Other endpoint categories...

View File

@@ -42,15 +42,6 @@ class SplashVC: UIViewController {
AuthFunc.shareInstance.languageSelected = .english
}
// let sb1 = UIStoryboard(name: "Home", bundle: nil)
// let vc1 = sb1.instantiateViewController(withIdentifier: "SideMenu") as! SideMenuController
// self.navigationController?.pushViewController(vc1, animated: true)
// UIApplication.setRootView(SideMenuController.instantiate(from: .Home))
//
// return
let sb = UIStoryboard(name: K.StoryBoard.main, bundle: nil)
let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.OnBoarding.onBoardVC) as! OnBoardVC
@@ -59,10 +50,6 @@ class SplashVC: UIViewController {
transition.duration = 0.3 // Set the duration of the animation
transition.type = CATransitionType.fade // Set the type of animation to fade
// Optionally, set other properties such as timing function, subtype, etc.
// transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
// transition.subtype = CATransitionSubtype.fromTop
// Get the navigation controller
guard let navigationController = navigationController else { return }

View File

@@ -14,6 +14,25 @@ class SplashVM{
weak var vc : SplashVC!
var player: AVAudioPlayer?
func initView(){
vc.activityIndicator.hidesWhenStopped = true
let color1 = #colorLiteral(red: 0.144693464, green: 0.1426281333, blue: 0.6686832905, alpha: 1)
let color2 = #colorLiteral(red: 0.4862745098, green: 0.1960784314, blue: 0.7019607843, alpha: 1)
vc.hindiBtn.applyGradient(colors: [color1, color2], startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0, y: 0.8))
vc.englishBtn.applyGradient(colors: [color1, color2], startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0, y: 0.8))
vc.hindiBtn.roundCorner()
vc.englishBtn.roundCorner()
selectTheme()
// check if user has selected the default language
if let language = AuthFunc.shareInstance.getDefaultLanguage(){
AuthFunc.shareInstance.languageSelected = language
}else{
AuthFunc.shareInstance.setDefaultLanguage(language: .english)
}
}
// Play initial sound
func playSplashSound() {
guard let path = Bundle.main.path(forResource: K.StaticFilesString.wokaSplashSound, ofType:"m4a") else {
return }
@@ -28,24 +47,6 @@ class SplashVM{
}
}
func initView(){
let color1 = #colorLiteral(red: 0.144693464, green: 0.1426281333, blue: 0.6686832905, alpha: 1)
let color2 = #colorLiteral(red: 0.4862745098, green: 0.1960784314, blue: 0.7019607843, alpha: 1)
vc.hindiBtn.applyGradient(colors: [color1, color2], startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0, y: 0.8))
vc.englishBtn.applyGradient(colors: [color1, color2], startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0, y: 0.8))
vc.hindiBtn.roundCorner()
vc.englishBtn.roundCorner()
selectTheme()
vc.activityIndicator.stopAnimating()
// check if user has selected the default language
if let language = AuthFunc.shareInstance.getDefaultLanguage(){
AuthFunc.shareInstance.languageSelected = language
}else{
AuthFunc.shareInstance.setDefaultLanguage(language: .english)
}
}
func selectTheme(){
let theme = UserDefaults.standard.string(forKey: K.UserDefaultsStruct.themeDefault)
if theme != nil{
@@ -55,6 +56,8 @@ class SplashVM{
}
}
// MARK: - Get the user data if loginned
func getUserData(){
if AuthFunc.shareInstance.getUserType() == 3{
//setusertype
@@ -98,6 +101,7 @@ class SplashVM{
}
}
// handling activity indicator
func startStopIndicator(start : Bool , hide : Bool = false){
if hide{
vc.activityIndicator.stopAnimating()

View File

@@ -19,13 +19,16 @@ class AboutUsVc: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setColor(color: .black)
navigationController?.setNavigationBarHidden(false, animated: animated)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
navigationController?.setNavigationBarHidden(true, animated: animated)
self.navigationController?.setColor(color: .white)
}
}

View File

@@ -53,6 +53,7 @@ class MyOrdersVC: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setColor(color: .black)
navigationController?.setNavigationBarHidden(false, animated: animated)
}

View File

@@ -48,6 +48,21 @@ class ThemeOneVC: UIViewController {
vm.initView()
}
override func viewWillDisappear(_ animated: Bool) {
vm.shouldAnimate = false
if let player = vm.avPlayer{
player.pause()
}
}
override func viewDidAppear(_ animated: Bool) {
vm.shouldAnimate = true
vm.moveLiveTVView()
if let player = vm.avPlayer{
player.play()
}
}
override func viewDidLayoutSubviews() {
vm.setupAvPlayer()
}

View File

@@ -18,6 +18,8 @@ class ThemeOneVM{
var avPlayer : AVPlayer!
var playerLayer: AVPlayerLayer!
var shouldAnimate = true
func initView(){
vc.bottomArrow.addTapGesture {
let sb = UIStoryboard(name: K.StoryBoard.theme, bundle: nil)
@@ -27,7 +29,6 @@ class ThemeOneVM{
}
AuthFunc.shareInstance.initTimePeriods()
startInitialTimer()
moveLiveTVView()
moveCloudView()
handleTaps()
setUserData()
@@ -102,12 +103,14 @@ class ThemeOneVM{
@objc func appDidEnterBackground() {
// Code to execute when the app enters the background
print("App entered background")
self.avPlayer.pause()
self.handleBackground()
}
@objc func appWillEnterForeground() {
// Code to execute when the app enters the foreground
print("App will enter foreground")
self.avPlayer.play()
self.handleBackground()
}
@@ -123,29 +126,42 @@ class ThemeOneVM{
}
}
//LiveTV
}
// MARK: - Animate Clouds and LiveTV
func centerLiveTVViewHorizontally() {
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
self.vc.liveTVView.center.x = self.vc.view.center.x // Center the liveTVView horizontally
}
}
func moveLiveTVView() {
guard shouldAnimate else {
self.centerLiveTVViewHorizontally()
return
} // Stop animating if shouldAnimate is false
guard let vc = self.vc else { return } // Ensure the view controller is available
UIView.animate(withDuration: 6, delay: 0, options: [.allowUserInteraction], animations: { [weak self] in
guard let self else{return}
guard let self = self else { return }
let margin: CGFloat = 30
let screenWidth = self.vc.view.frame.width
let viewWidth = self.vc.liveTVView.frame.width
let screenWidth = vc.view.frame.width
let viewWidth = vc.liveTVView.frame.width
let maxX = screenWidth - margin - viewWidth / 2
let minX = margin + viewWidth / 2
if isMovingRight {
if self.isMovingRight {
vc.liveTVView.center.x = maxX // Move to the right
} else {
vc.liveTVView.center.x = minX // Move to the left
}
}, completion: { [weak self] _ in
guard let self else{return}
isMovingRight.toggle() // Toggle the direction for the next iteration
moveLiveTVView() // Recursively call moveLiveTVView to create a continuous animation
guard let self = self else { return }
self.isMovingRight.toggle() // Toggle the direction for the next iteration
DispatchQueue.main.async { // Ensure the recursive call is made on the main thread
self.moveLiveTVView() // Recursively call moveLiveTVView to create a continuous animation
}
})
}

View File

@@ -19,12 +19,24 @@ class WebSeriesSeasonVC: UIViewController {
@IBOutlet weak var seasonDesc: UILabel!
@IBOutlet weak var categoryCV: UICollectionView!
@IBOutlet weak var episodeTableView: UITableView!
@IBOutlet weak var tableHeight: NSLayoutConstraint!
@IBOutlet weak var addIcon: UIImageView!
@IBOutlet weak var addLabel: UILabel!
@IBOutlet weak var likeIcon: UIImageView!
@IBOutlet weak var likeLabel: UILabel!
@IBOutlet weak var totalLikes: UILabel!
@IBOutlet weak var addStack: UIStackView!
@IBOutlet weak var shareStack: UIStackView!
@IBOutlet weak var likeStack: UIStackView!
override func viewDidLoad() {
super.viewDidLoad()
vm.vc = self
vm.initView()
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.shadowImage = UIImage()
}
@@ -51,8 +63,25 @@ class WebSeriesSeasonVC: UIViewController {
@IBAction func watchBtnTapped(_ sender: LocalisedElementsButton) {
}
@IBAction func btnTapped(_ sender: LocalisedElementsButton) {
}
// MARK: - TableView DataSource , Delegates
extension WebSeriesSeasonVC : TableViewSRC{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return vm.seasonEpisodeData.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: K.CellIdentifier.WebSeries.webSeriesEpisodeCell) as! WebSeriesEpisodeCell
let data = vm.seasonEpisodeData[indexPath.row]
cell.setData(data: data)
return cell
}
}
@@ -68,12 +97,14 @@ extension WebSeriesSeasonVC : CollectionViewSRC{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: K.CellIdentifier.WebSeries.seasonCategoryCell, for: indexPath) as! SeasonCategoryCell
let data = vm.seasonListingData[indexPath.row]
cell.setData(title: data.seasonNumber ?? "Season", iselected: indexPath.row == vm.selectedCateogory)
cell.setData(title: data.seasonNumber ?? "Season", iselected: data.id == vm.episodeSelectedCateogory)
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print(indexPath.row)
vm.episodeSelectedCateogory = vm.seasonListingData[indexPath.row].id
vm.getSeasonEpisode()
self.categoryCV.reloadData()
}
}
@@ -83,76 +114,19 @@ extension WebSeriesSeasonVC : UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
// Generate a random string for testing purposes
let randomText = vm.seasonListingData[indexPath.row].seasonNumber!
// Define the font for the text
let font = FontCustom.shareInstance.customFont(fontName: .Exo2_Bold, size: 18) // You can adjust the font size as needed
let font = FontCustom.shareInstance.customFont(fontName: .Exo2_Bold, size: 18) // Adjust the font size as needed
// Calculate the width of the text
let textWidth = randomText.size(withAttributes: [.font: font]).width
let attributes = [NSAttributedString.Key.font: font]
let textWidth = (randomText as NSString).size(withAttributes: attributes).width
// Set the cell width based on the text width and any additional padding
let cellWidth = textWidth + 25 // Add any additional spacing you want
return CGSize(width: cellWidth, height: 50)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
section == 0 ? 15 : 5
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
}
}
// Helper method to calculate text width
extension String {
func width(withConstrainedHeight height: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [.font: font], context: nil)
return ceil(boundingBox.width)
}
}
@IBDesignable
class VerticalButton: UIButton {
@IBInspectable public var padding: CGFloat = 20.0 {
didSet {
setNeedsLayout()
}
}
override var intrinsicContentSize: CGSize {
let maxSize = CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)
if let titleSize = titleLabel?.sizeThatFits(maxSize), let imageSize = imageView?.sizeThatFits(maxSize) {
let width = ceil(max(imageSize.width, titleSize.width))
let height = ceil(imageSize.height + titleSize.height + padding)
return CGSize(width: width, height: height)
}
return super.intrinsicContentSize
}
override func layoutSubviews() {
if let image = imageView?.image, let title = titleLabel?.attributedText {
let imageSize = image.size
let titleSize = title.size()
if effectiveUserInterfaceLayoutDirection == .leftToRight {
titleEdgeInsets = UIEdgeInsets(top: 0.0, left: -imageSize.width, bottom: -(imageSize.height + padding), right: 0.0)
imageEdgeInsets = UIEdgeInsets(top: -(titleSize.height + padding), left: 0.0, bottom: 0.0, right: -titleSize.width)
}
else {
titleEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: -(imageSize.height + padding), right: -imageSize.width)
imageEdgeInsets = UIEdgeInsets(top: -(titleSize.height + padding), left: -titleSize.width, bottom: 0.0, right: 0.0)
}
}
super.layoutSubviews()
// 14 for container view + 10 for inside spacing.
let padding: CGFloat = 24 + 20 // Adjust padding as needed
let cellWidth = textWidth + padding
return CGSize(width: cellWidth , height: 60)
}
}

View File

@@ -195,7 +195,7 @@ extension WebSeriesVC : TableViewSRC{
let sb = UIStoryboard(name: K.StoryBoard.webSeries, bundle: nil)
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.WebSeries.webSeriesSeasonVC) as! WebSeriesSeasonVC
vcPush.vm.watchShowID = showData.id
vcPush.vm.showData = showData
if let selectedIndex = vm.dropDownModule.indexForSelectedRow{
let categoryID = vm.categoryListingData[selectedIndex]
vcPush.vm.categoryID = categoryID.id

View File

@@ -0,0 +1,105 @@
//
// SeasonEpisodeListingDM.swift
// WOKA
//
// Created by Bilal on 21/06/2024.
//
import Foundation
// MARK: - SeasonEpisodeListingDM
struct SeasonEpisodeListingDM: Codable {
let result: [ResultData]?
let totalRecords: Int?
enum CodingKeys: String, CodingKey {
case result
case totalRecords = "total_records"
}
// MARK: - Result
struct ResultData: Codable {
let id, watchShowsMasterID: Int?
let seasonNumber: String?
let noOfEpisodes: Int?
let seasonDescription: String?
let releaseYear: Int?
let seasonTitle: String?
let trailerURL: String?
let thumbnailPath: String?
let thumbnailImgURL: String?
let tagsKeyword, releaseDate, mediaType: String?
let seasonMoreDetails: [MoreDetail]?
let episodeData: [EpisodeDatum]?
let episodeTotalRecords: Int?
enum CodingKeys: String, CodingKey {
case id
case watchShowsMasterID = "watch_shows_master_id"
case seasonNumber = "season_number"
case noOfEpisodes = "no_of_episodes"
case seasonDescription = "season_description"
case releaseYear = "release_year"
case seasonTitle = "season_title"
case trailerURL = "trailer_url"
case thumbnailPath = "thumbnail_path"
case thumbnailImgURL = "thumbnail_img_url"
case tagsKeyword = "tags_keyword"
case releaseDate = "release_date"
case mediaType = "media_type"
case seasonMoreDetails = "season_more_details"
case episodeData = "episode_data"
case episodeTotalRecords = "episode_total_records"
}
}
// MARK: - EpisodeDatum
struct EpisodeDatum: Codable {
let id, watchShowsMasterID, seasonMasterID, episodeNumber: Int?
let episodeTitle, episodeDescription: String?
let thumbnailPath: String?
let thumbnailImgURL: String?
let episodeURL: String?
let languageMasterID: Int?
let tagsKeyword, episodeDuration, releaseDate: String?
let contentMoreDetails: [MoreDetail]?
enum CodingKeys: String, CodingKey {
case id
case watchShowsMasterID = "watch_shows_master_id"
case seasonMasterID = "season_master_id"
case episodeNumber = "episode_number"
case episodeTitle = "episode_title"
case episodeDescription = "episode_description"
case thumbnailPath = "thumbnail_path"
case thumbnailImgURL = "thumbnail_img_url"
case episodeURL = "episode_url"
case languageMasterID = "language_master_id"
case tagsKeyword = "tags_keyword"
case episodeDuration = "episode_duration"
case releaseDate = "release_date"
case contentMoreDetails = "content_more_details"
}
}
// MARK: - MoreDetail
struct MoreDetail: Codable {
let id, contentID, postType, languageMasterID: Int?
let title, description, tagsKeywords: String?
let contentHDURL, contentSDURL, trailerHDURL, trailerSDURL: String?
enum CodingKeys: String, CodingKey {
case id
case contentID = "content_id"
case postType = "post_type"
case languageMasterID = "language_master_id"
case title, description
case tagsKeywords = "tags_keywords"
case contentHDURL = "content_hd_url"
case contentSDURL = "content_sd_url"
case trailerHDURL = "trailer_hd_url"
case trailerSDURL = "trailer_sd_url"
}
}
}

View File

@@ -18,7 +18,7 @@ class SeasonCategoryCell: UICollectionViewCell {
}
override func layoutSubviews() {
outerView.roundCorner()
outerView.roundCorner(radius: 25)
}
func setData(title : String , iselected : Bool){

View File

@@ -7,6 +7,11 @@
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<customFonts key="customFonts">
<array key="Exo2-SemiBold.ttf">
<string>Exo2-SemiBold</string>
</array>
</customFonts>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
@@ -17,11 +22,11 @@
<rect key="frame" x="0.0" y="0.0" width="193" height="58"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="HMN-pO-RGh">
<rect key="frame" x="10" y="5" width="173" height="48"/>
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="HMN-pO-RGh">
<rect key="frame" x="7" y="5" width="179" height="48"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="wordWrap" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="83B-dW-gdG">
<rect key="frame" x="10" y="0.0" width="153" height="48"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="83B-dW-gdG">
<rect key="frame" x="5" y="0.0" width="169" height="48"/>
<fontDescription key="fontDescription" name="Exo2-SemiBold" family="Exo 2" pointSize="18"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
@@ -30,8 +35,8 @@
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="83B-dW-gdG" secondAttribute="bottom" id="KH0-hj-diX"/>
<constraint firstAttribute="trailing" secondItem="83B-dW-gdG" secondAttribute="trailing" constant="10" id="SZk-hQ-AoF"/>
<constraint firstItem="83B-dW-gdG" firstAttribute="leading" secondItem="HMN-pO-RGh" secondAttribute="leading" constant="10" id="bPU-V8-tsf"/>
<constraint firstAttribute="trailing" secondItem="83B-dW-gdG" secondAttribute="trailing" constant="5" id="SZk-hQ-AoF"/>
<constraint firstItem="83B-dW-gdG" firstAttribute="leading" secondItem="HMN-pO-RGh" secondAttribute="leading" constant="5" id="bPU-V8-tsf"/>
<constraint firstItem="83B-dW-gdG" firstAttribute="top" secondItem="HMN-pO-RGh" secondAttribute="top" id="mgG-mx-kxk"/>
</constraints>
</view>
@@ -40,8 +45,8 @@
<viewLayoutGuide key="safeArea" id="ZTg-uK-7eu"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="HMN-pO-RGh" secondAttribute="trailing" constant="10" id="ERp-LI-fWH"/>
<constraint firstItem="HMN-pO-RGh" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" constant="10" id="hc8-Nb-nf4"/>
<constraint firstAttribute="trailing" secondItem="HMN-pO-RGh" secondAttribute="trailing" constant="7" id="ERp-LI-fWH"/>
<constraint firstItem="HMN-pO-RGh" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" constant="7" id="hc8-Nb-nf4"/>
<constraint firstAttribute="bottom" secondItem="HMN-pO-RGh" secondAttribute="bottom" constant="5" id="lwt-U3-qk0"/>
<constraint firstItem="HMN-pO-RGh" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" constant="5" id="r30-MA-j6Q"/>
</constraints>

View File

@@ -0,0 +1,42 @@
//
// WebSeriesEpisodeCell.swift
// WOKA
//
// Created by Bilal on 21/06/2024.
//
import UIKit
class WebSeriesEpisodeCell: UITableViewCell {
@IBOutlet weak var seasonImage: UIImageView!
@IBOutlet weak var seasonTitle: UILabel!
@IBOutlet weak var seasonTime: UILabel!
@IBOutlet weak var playBtn: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func setData(data : SeasonEpisodeListingDM.ResultData){
if let url = data.thumbnailPath{
self.seasonImage.imageURL(url, color: UIColor.appColor(.TextDarkBlue)!)
}
if AuthFunc.shareInstance.getDefaultLanguage() == .english{
seasonTitle.text = data.seasonMoreDetails?.filter({$0.languageMasterID == 1}).first?.title
}else{
seasonTitle.text = data.seasonMoreDetails?.filter({$0.languageMasterID == 2}).first?.title
}
}
@IBAction func playBtnTapped(_ sender: UIButton) {
}
}

View File

@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<customFonts key="customFonts">
<array key="Exo2-Bold.ttf">
<string>Exo2-Bold</string>
</array>
<array key="Exo2-Regular.ttf">
<string>Exo2-Regular</string>
</array>
</customFonts>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" rowHeight="110" id="KGk-i7-Jjw" customClass="WebSeriesEpisodeCell" customModule="WOKA" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="427" height="110"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
<rect key="frame" x="0.0" y="0.0" width="427" height="110"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<stackView opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="Hdb-eb-Ymv">
<rect key="frame" x="10" y="6" width="407" height="98"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="tkG-6M-lbm">
<rect key="frame" x="8" y="13.666666666666671" width="120" height="71"/>
<constraints>
<constraint firstAttribute="width" constant="120" id="EpM-Fv-rvr"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<integer key="value" value="10"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</imageView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="RoA-pj-myv">
<rect key="frame" x="138" y="11" width="211" height="76"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalCompressionResistancePriority="749" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Oux-y5-3S0">
<rect key="frame" x="0.0" y="0.0" width="211" height="54"/>
<string key="text">Episodes
Episodes
Episodes</string>
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="15"/>
<color key="textColor" name="TextDarkBlue"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Episodes" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wAx-mz-nFB">
<rect key="frame" x="0.0" y="59" width="211" height="17"/>
<fontDescription key="fontDescription" name="Exo2-Regular" family="Exo 2" pointSize="14"/>
<color key="textColor" name="TextDarkBlue"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="b4V-gS-TvG">
<rect key="frame" x="359" y="8" width="40" height="82"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="uFk-k1-Xsm">
<rect key="frame" x="0.0" y="21" width="40" height="40"/>
<constraints>
<constraint firstAttribute="width" secondItem="uFk-k1-Xsm" secondAttribute="height" multiplier="1:1" id="o0n-9n-a4G"/>
</constraints>
<color key="tintColor" name="TextDarkBlue"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" image="PlayButton"/>
<connections>
<action selector="playBtnTapped:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="Twk-L6-Wxv"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="width" constant="40" id="LDG-0X-ybq"/>
<constraint firstAttribute="trailing" secondItem="uFk-k1-Xsm" secondAttribute="trailing" id="QqG-Bb-GB2"/>
<constraint firstItem="uFk-k1-Xsm" firstAttribute="centerY" secondItem="b4V-gS-TvG" secondAttribute="centerY" id="WvO-ca-78l"/>
<constraint firstItem="uFk-k1-Xsm" firstAttribute="centerX" secondItem="b4V-gS-TvG" secondAttribute="centerX" id="p5o-kE-Cch"/>
<constraint firstItem="uFk-k1-Xsm" firstAttribute="leading" secondItem="b4V-gS-TvG" secondAttribute="leading" id="r6e-Fk-yoc"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<integer key="value" value="10"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</stackView>
</subviews>
<constraints>
<constraint firstItem="Hdb-eb-Ymv" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="10" id="Fo2-be-R0q"/>
<constraint firstItem="Hdb-eb-Ymv" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="6" id="KuZ-pj-Tjb"/>
<constraint firstAttribute="bottom" secondItem="Hdb-eb-Ymv" secondAttribute="bottom" constant="6" id="Mlz-wa-5eU"/>
<constraint firstAttribute="trailing" secondItem="Hdb-eb-Ymv" secondAttribute="trailing" constant="10" id="OFO-EO-QlO"/>
</constraints>
</tableViewCellContentView>
<viewLayoutGuide key="safeArea" id="njF-e1-oar"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<connections>
<outlet property="playBtn" destination="uFk-k1-Xsm" id="mvh-qJ-7R2"/>
<outlet property="seasonImage" destination="tkG-6M-lbm" id="GA4-IY-qts"/>
<outlet property="seasonTime" destination="wAx-mz-nFB" id="hEm-Ie-Keg"/>
<outlet property="seasonTitle" destination="Oux-y5-3S0" id="G2f-co-QNp"/>
</connections>
<point key="canvasLocation" x="211.4503816793893" y="11.971830985915494"/>
</tableViewCell>
</objects>
<resources>
<image name="PlayButton" width="32" height="32"/>
<namedColor name="TextDarkBlue">
<color red="0.10599999874830246" green="0.050999999046325684" blue="0.60399997234344482" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

View File

@@ -12,29 +12,86 @@ class WebSeriesSeasonVM{
weak var vc : WebSeriesSeasonVC!
var watchShowID : Int?
// var watchShowID : Int?
var categoryID : Int?
var selectedCateogory = 0
var episodeSelectedCateogory : Int?
var seasonListingData = [SeasonListingDM.Result]()
var seasonEpisodeData = [SeasonEpisodeListingDM.ResultData]()
var showData : WebSeriesShowListDM.ShowDatum?
func initView(){
getSeasonListing()
setupCell()
setShowData()
vc.shareStack.addTapGesture {
print("share")
}
}
func setShowData(){
guard let showData else{return}
vc.totalLikes.text = showData.likesCount?.toString() ?? "0"
if let like = showData.isLiked{
switch like{
case true:
vc.likeIcon.image = UIImage(systemName: "hand.thumbsup.fill")
vc.likeLabel.text = "Liked"
case false:
vc.likeIcon.image = UIImage(systemName: "hand.thumbsup")
vc.likeLabel.text = "Like"
}
}
if let favourite = showData.markAsFavourite{
if let categoryIds = showData.favouriteCategoryIDS?.rawValue { // if string, it means category is selected for multiple language
let components = categoryIds.components(separatedBy: ",")
if favourite == true && (components.first == categoryID?.toString() || components.last == categoryID?.toString()){
vc.addIcon.image = UIImage(systemName: "heart.fill")
vc.addLabel.text = "Added"
}else{
vc.addIcon.image = UIImage(systemName: "heart")
vc.addLabel.text = "Add"
}
return
}
if favourite == true && showData.favouriteCategoryIDS?.intValue == categoryID{
vc.addIcon.image = UIImage(systemName: "heart.fill")
vc.addLabel.text = "Added"
}else{
vc.addIcon.image = UIImage(systemName: "heart")
vc.addLabel.text = "Add"
}
// switch favourite{
// case true:
// favBtn.setImage(UIImage(systemName: "heart.fill"), for: .normal)
// case false:
// favBtn.setImage(UIImage(systemName: "heart"), for: .normal)
//
// }
}
}
func setupCell(){
vc.categoryCV.register(UINib(nibName: K.CellIdentifier.WebSeries.seasonCategoryCell, bundle: nil), forCellWithReuseIdentifier: K.CellIdentifier.WebSeries.seasonCategoryCell)
vc.categoryCV.delegate = vc.self
vc.categoryCV.dataSource = vc.self
vc.episodeTableView.register(UINib(nibName: K.CellIdentifier.WebSeries.webSeriesEpisodeCell, bundle: nil), forCellReuseIdentifier: K.CellIdentifier.WebSeries.webSeriesEpisodeCell)
vc.episodeTableView.delegate = vc.self
vc.episodeTableView.dataSource = vc.self
}
// MARK: - Api Calls
func getSeasonListing(){
Utilities.startProgressHUD()
guard let watchShowID, let categoryID else{return}
guard let watchShowID = showData?.id, let categoryID else{return}
let headers : HTTPHeaders = ["access-token" : AuthFunc.shareInstance.getAccessToken()]
let params : Parameters = ["watch_show_id" : watchShowID,
"category_id" : categoryID]
@@ -57,6 +114,8 @@ class WebSeriesSeasonVM{
guard let data = data.data?.result else{return}
self.seasonListingData = data
setSeasonData()
episodeSelectedCateogory = seasonListingData.first?.id
getSeasonEpisode()
self.vc.categoryCV.reloadData()
default:
break
@@ -99,4 +158,48 @@ class WebSeriesSeasonVM{
vc.seasonEpisodes.text = data.noOfEpisodes?.toString()
vc.seasonMediaType.text = data.mediaType
}
func getSeasonEpisode(){
Utilities.startProgressHUD()
guard let watchShowID = showData?.id, let episodeSelectedCateogory else{return}
let headers : HTTPHeaders = ["access-token" : AuthFunc.shareInstance.getAccessToken()]
let params : Parameters = ["watch_show_id" : watchShowID,
"season_id" : episodeSelectedCateogory]
NetworkManager.shareInstance.apiRequest(url: APIEndPoints.WebSeries.season_episode_listing, method: .post,parameters: params,headers : headers) { [weak self](result : Result<BaseResponseModel<SeasonEpisodeListingDM>, NetworkManager.APIError>) in
switch result{
case .success(let data):
guard let self else{
Utilities.dismissProgressHUD()
return
}
switch data.success{
case 0:
/*
Error
*/
Utilities.dismissProgressHUD()
vc.toast(msg: data.message ?? "Unrecognised error" , time: 2)
case 1:
Utilities.dismissProgressHUD()
guard let data = data.data?.result else{return}
self.seasonEpisodeData.removeAll()
self.seasonEpisodeData = data
self.vc.episodeTableView.reloadData()
self.vc.tableHeight.constant = self.vc.episodeTableView.contentSize.height + 100
self.vc.episodeTableView.layoutIfNeeded()
self.vc.tableHeight.constant = self.vc.episodeTableView.contentSize.height
default:
break
}
case .failure(let error):
guard let self else{
Utilities.dismissProgressHUD()
return
}
Utilities.dismissProgressHUD()
vc.toast(msg: error.localizedDescription , time: 2)
}
}
}
}

View File

@@ -265,7 +265,7 @@
<rect key="frame" x="0.0" y="59" width="393" height="793"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="JVZ-ee-mig">
<rect key="frame" x="0.0" y="0.0" width="393" height="1163"/>
<rect key="frame" x="0.0" y="0.0" width="393" height="623"/>
<subviews>
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8zm-IG-hTk">
<rect key="frame" x="0.0" y="0.0" width="393" height="553"/>
@@ -366,9 +366,8 @@
</stackView>
</subviews>
</stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="DLr-9j-LSn">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="DLr-9j-LSn">
<rect key="frame" x="0.0" y="275" width="373" height="168"/>
<string key="text">A set of moral stories inspired from the interactions of Mughal Emperor Akbar and his wisest courtier Birbal. The Akbar Birbal stories have been especially edited to suit the young kids and each story teaches audience an important moral lesson. </string>
<fontDescription key="fontDescription" name="Exo2-Regular" family="Exo 2" pointSize="14"/>
<color key="textColor" name="TextDarkBlue"/>
<nil key="highlightedColor"/>
@@ -397,20 +396,20 @@
</connections>
</button>
<stackView opaque="NO" contentMode="scaleToFill" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="6gf-lV-70S">
<rect key="frame" x="233" y="0.0" width="140" height="50"/>
<rect key="frame" x="247.66666666666671" y="0.0" width="125.33333333333334" height="50"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="iyr-1k-HHN">
<rect key="frame" x="0.0" y="0.0" width="38.333333333333336" height="50"/>
<rect key="frame" x="0.0" y="0.0" width="30" height="50"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" image="heart" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="QkS-fP-ADo">
<rect key="frame" x="4.3333333333333428" y="1.9999999999999964" width="30" height="32.333333333333329"/>
<rect key="frame" x="0.0" y="1.9999999999999964" width="30" height="32.333333333333329"/>
<color key="tintColor" name="TextDarkBlue"/>
<constraints>
<constraint firstAttribute="width" constant="30" id="4SG-I2-B6S"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="ADDED" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tlx-NG-HWl">
<rect key="frame" x="0.0" y="35.333333333333371" width="38.333333333333336" height="14.666666666666664"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="ADD" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tlx-NG-HWl">
<rect key="frame" x="3.3333333333333144" y="35.333333333333371" width="23.666666666666668" height="14.666666666666664"/>
<fontDescription key="fontDescription" name="Exo2-Regular" family="Exo 2" pointSize="12"/>
<color key="textColor" name="TextDarkBlue"/>
<nil key="highlightedColor"/>
@@ -418,17 +417,17 @@
</subviews>
</stackView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9xJ-TL-8CA">
<rect key="frame" x="46.333333333333314" y="0.0" width="1" height="50"/>
<rect key="frame" x="38" y="0.0" width="1" height="50"/>
<color key="backgroundColor" name="TextDarkBlue"/>
<constraints>
<constraint firstAttribute="width" constant="0.80000000000000004" id="y2u-9V-Gis"/>
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="Lag-16-uzP">
<rect key="frame" x="55.333333333333314" y="0.0" width="36.666666666666657" height="50"/>
<rect key="frame" x="47" y="0.0" width="36.666666666666657" height="50"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" image="ShareImage" translatesAutoresizingMaskIntoConstraints="NO" id="Azy-gL-vtW">
<rect key="frame" x="3.3333333333333712" y="0.0" width="30" height="35.333333333333336"/>
<rect key="frame" x="3.3333333333333144" y="0.0" width="30" height="35.333333333333336"/>
<color key="tintColor" name="TextDarkBlue"/>
<constraints>
<constraint firstAttribute="width" constant="30" id="DYv-5U-6mY"/>
@@ -443,24 +442,24 @@
</subviews>
</stackView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gs2-gk-Fn0">
<rect key="frame" x="100" y="0.0" width="0.6666666666666714" height="50"/>
<rect key="frame" x="91.666666666666629" y="0.0" width="0.6666666666666714" height="50"/>
<color key="backgroundColor" name="TextDarkBlue"/>
<constraints>
<constraint firstAttribute="width" constant="0.80000000000000004" id="2M1-wj-hEy"/>
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="8UJ-rG-fB2">
<rect key="frame" x="108.66666666666669" y="0.0" width="31.333333333333343" height="50"/>
<rect key="frame" x="100.33333333333331" y="0.0" width="25" height="50"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" image="hand.thumbsup" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="f9M-ON-9gL">
<rect key="frame" x="3.3333333333333144" y="-0.33333333333333215" width="25" height="35.333333333333329"/>
<rect key="frame" x="0.0" y="-0.33333333333333215" width="25" height="35.333333333333329"/>
<color key="tintColor" name="TextDarkBlue"/>
<constraints>
<constraint firstAttribute="width" constant="25" id="UAK-v9-EKA"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="LIKED" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Q4V-Gl-g6v">
<rect key="frame" x="0.0" y="35.333333333333371" width="31.333333333333332" height="14.666666666666664"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="LIKE" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Q4V-Gl-g6v">
<rect key="frame" x="1" y="35.333333333333371" width="23.333333333333332" height="14.666666666666664"/>
<fontDescription key="fontDescription" name="Exo2-Regular" family="Exo 2" pointSize="12"/>
<color key="textColor" name="TextDarkBlue"/>
<nil key="highlightedColor"/>
@@ -497,13 +496,13 @@
</userDefinedRuntimeAttributes>
</view>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="heV-KP-ndD">
<rect key="frame" x="0.0" y="558" width="393" height="300"/>
<rect key="frame" x="0.0" y="558" width="393" height="60"/>
<subviews>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="rAO-uI-Djj">
<rect key="frame" x="0.0" y="0.0" width="393" height="70"/>
<rect key="frame" x="5" y="0.0" width="383" height="60"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="70" id="0ZK-IU-MRo"/>
<constraint firstAttribute="height" constant="60" id="0ZK-IU-MRo"/>
</constraints>
<collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal" minimumLineSpacing="10" minimumInteritemSpacing="10" id="7l5-M2-DPF">
<size key="itemSize" width="128" height="70"/>
@@ -513,31 +512,16 @@
</collectionViewFlowLayout>
<cells/>
</collectionView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="749" image="HomeGrassDay" translatesAutoresizingMaskIntoConstraints="NO" id="PYp-GX-xml">
<rect key="frame" x="0.0" y="70" width="393" height="230"/>
</imageView>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="300" id="3Uq-sp-2CX"/>
</constraints>
<edgeInsets key="layoutMargins" top="0.0" left="5" bottom="0.0" right="5"/>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="soQ-RR-JbO">
<rect key="frame" x="0.0" y="863" width="393" height="300"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Select Video Language" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="AKn-0T-GcN" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="393" height="21.666666666666668"/>
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="18"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="749" image="HomeGrassDay" translatesAutoresizingMaskIntoConstraints="NO" id="JBe-8V-5pR">
<rect key="frame" x="0.0" y="21.666666666666629" width="393" height="278.33333333333331"/>
</imageView>
</subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="-1" estimatedRowHeight="244" sectionHeaderHeight="-1" estimatedSectionHeaderHeight="-1" sectionFooterHeight="-1" estimatedSectionFooterHeight="-1" translatesAutoresizingMaskIntoConstraints="NO" id="RJP-uy-ll3">
<rect key="frame" x="0.0" y="623" width="393" height="0.0"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="300" id="MFb-mi-H2z"/>
<constraint firstAttribute="height" id="F3X-r1-O8N"/>
</constraints>
</stackView>
</tableView>
</subviews>
</stackView>
</subviews>
@@ -546,7 +530,7 @@
<constraint firstItem="JVZ-ee-mig" firstAttribute="leading" secondItem="6BC-EI-c6S" secondAttribute="leading" id="539-an-m3X"/>
<constraint firstItem="JVZ-ee-mig" firstAttribute="top" secondItem="Ka5-Rt-V3L" secondAttribute="top" id="Bgm-6h-ooD"/>
<constraint firstItem="6BC-EI-c6S" firstAttribute="trailing" secondItem="JVZ-ee-mig" secondAttribute="trailing" id="by6-GS-3rU"/>
<constraint firstAttribute="bottom" secondItem="JVZ-ee-mig" secondAttribute="bottom" id="pLq-j1-zx6"/>
<constraint firstItem="QMw-h5-HV5" firstAttribute="bottom" secondItem="JVZ-ee-mig" secondAttribute="bottom" id="pLq-j1-zx6"/>
<constraint firstItem="JVZ-ee-mig" firstAttribute="width" secondItem="QMw-h5-HV5" secondAttribute="width" id="phT-Ue-AAx"/>
</constraints>
<viewLayoutGuide key="contentLayoutGuide" id="QMw-h5-HV5"/>
@@ -564,13 +548,23 @@
</constraints>
</view>
<connections>
<outlet property="addIcon" destination="QkS-fP-ADo" id="H3a-fb-Mgw"/>
<outlet property="addLabel" destination="tlx-NG-HWl" id="IHA-Oz-faM"/>
<outlet property="addStack" destination="iyr-1k-HHN" id="PBF-2C-nPZ"/>
<outlet property="categoryCV" destination="rAO-uI-Djj" id="9vd-ge-YZ5"/>
<outlet property="episodeTableView" destination="RJP-uy-ll3" id="EEa-5i-fyE"/>
<outlet property="likeIcon" destination="f9M-ON-9gL" id="Iyp-MI-UfT"/>
<outlet property="likeLabel" destination="Q4V-Gl-g6v" id="p5K-OM-Lmn"/>
<outlet property="likeStack" destination="8UJ-rG-fB2" id="Ktz-EP-lgH"/>
<outlet property="seasonDate" destination="3AX-wl-iqI" id="4Zq-76-ZN2"/>
<outlet property="seasonDesc" destination="DLr-9j-LSn" id="hpg-2G-M9N"/>
<outlet property="seasonEpisodes" destination="G0i-Q1-Tic" id="t9J-Zm-eqb"/>
<outlet property="seasonImage" destination="ygJ-Op-sJP" id="cXY-pG-3ce"/>
<outlet property="seasonMediaType" destination="F1N-Se-lI3" id="8Wb-HP-3bZ"/>
<outlet property="seasonTitle" destination="AdX-OP-Gcd" id="I39-xA-Z1d"/>
<outlet property="shareStack" destination="Lag-16-uzP" id="jjy-Lv-6on"/>
<outlet property="tableHeight" destination="F3X-r1-O8N" id="O70-hN-czC"/>
<outlet property="totalLikes" destination="Egv-Cu-aPK" id="uTn-bf-zWw"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="ZBM-os-iEI" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
@@ -579,7 +573,6 @@
</scene>
</scenes>
<resources>
<image name="HomeGrassDay" width="570.66668701171875" height="641.33331298828125"/>
<image name="MasilaComingSoon" width="200" height="100"/>
<image name="PlayButton" width="32" height="32"/>
<image name="ShareImage" width="18" height="18"/>