408 lines
16 KiB
Swift
408 lines
16 KiB
Swift
//
|
|
// AudioBookHomeVC.swift
|
|
// WOKA
|
|
//
|
|
// Created by MacBook Pro on 02/07/24.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
class AudioBookHomeVC: UIViewController {
|
|
|
|
var vm = AudioBookHomeVM()
|
|
|
|
@IBOutlet weak var scrollView: UIScrollView!
|
|
@IBOutlet weak var headerHeight: NSLayoutConstraint!
|
|
@IBOutlet weak var continueWatchingCV: UICollectionView!
|
|
@IBOutlet weak var audioListingTableView: UITableView!
|
|
@IBOutlet weak var tableHeight: NSLayoutConstraint!
|
|
@IBOutlet weak var topLabel: UILabel!
|
|
@IBOutlet weak var headerViewTopConstraint: NSLayoutConstraint!
|
|
@IBOutlet weak var continueWatchingStack: UIStackView!
|
|
@IBOutlet weak var headerView: ShimmerEffectView!
|
|
@IBOutlet weak var headerImage: UIImageView!
|
|
@IBOutlet weak var headerTitleLabel: UILabel!
|
|
@IBOutlet weak var listenView: ShimmerEffectView!
|
|
|
|
@IBOutlet weak var loadMoreBtn: LocalisedElementsButton!
|
|
@IBOutlet weak var loadMoreActivityIndicator: UIActivityIndicatorView!
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
vm.vc = self
|
|
self.title = "AUDIO BOOKS".localized(loc: AuthFunc.shareInstance.languageSelected.rawValue)
|
|
vm.initView()
|
|
scrollView.delegate = self
|
|
|
|
let color1 = #colorLiteral(red: 0, green: 0.4784313725, blue: 0.7529411765, alpha: 1)
|
|
let color2 = #colorLiteral(red: 0, green: 0.7529411765, blue: 0.7529411765, alpha: 1)
|
|
self.view.applyGradient(colors: [color1,color2], startPoint: .Point.left.point , endPoint: .Point.right.point)
|
|
|
|
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
|
|
navigationController?.navigationBar.shadowImage = UIImage()
|
|
}
|
|
|
|
override func viewWillAppear(_ animated: Bool) {
|
|
super.viewWillAppear(animated)
|
|
navigationController?.setNavigationBarHidden(false, animated: animated)
|
|
self.navigationController?.setColor(color: .white)
|
|
}
|
|
|
|
override func viewWillDisappear(_ animated: Bool) {
|
|
super.viewWillDisappear(animated)
|
|
self.navigationController?.setNavigationBarHidden(true, animated: animated)
|
|
}
|
|
|
|
override func viewDidDisappear(_ animated: Bool) {
|
|
super.viewDidDisappear(animated)
|
|
self.navigationController?.navigationBar.removeGradientBackground()
|
|
|
|
// Customize the navigation bar's appearance
|
|
self.navigationController?.setColor(color: .black)
|
|
|
|
if self.isMovingFromParent {
|
|
// Back button was pressed
|
|
PersistentStorage.shared.addOthersCount()
|
|
}
|
|
}
|
|
|
|
override func viewDidAppear(_ animated: Bool) {
|
|
if K.GVar.reloadContinueAudioBooks{
|
|
K.GVar.reloadContinueAudioBooks = false
|
|
vm.getContinueWatching()
|
|
}
|
|
}
|
|
|
|
override func viewDidLayoutSubviews() {
|
|
vm.updateTableHeight()
|
|
}
|
|
|
|
@IBAction func loadMoreBtn(_ sender: LocalisedElementsButton) {
|
|
loadMoreBtn.isHidden = true
|
|
vm.pageNo += 1
|
|
loadMoreActivityIndicator.startAnimating()
|
|
vm.getShowListing()
|
|
}
|
|
|
|
@IBAction func listenAudioBtnTapped(_ sender: LocalisedElementsButton) {
|
|
guard let data = vm.headerData, let postID = data.id else{return}
|
|
PersistentStorage.shared.addAudioCount(postID: postID)
|
|
var playerItems = [JwPlayerItemCreate]()
|
|
if AuthFunc.shareInstance.getDefaultLanguage() == .english{
|
|
if let englishData = data.contentMoreDetails?.filter({$0.languageMasterID == 1}).first, let url = englishData.url{
|
|
playerItems.append(JwPlayerItemCreate(url: url, poster: data.thumbnailPath, titles: englishData.title))
|
|
}
|
|
}else{
|
|
if let hindiData = data.contentMoreDetails?.filter({$0.languageMasterID == 2}).first, let url = hindiData.url{
|
|
playerItems.append(JwPlayerItemCreate(url: url, poster: data.thumbnailPath, titles: hindiData.title))
|
|
}
|
|
}
|
|
JWPlayerManager.shared.presentPlayer(from: self, playerItems: playerItems, startIndex: 0, contentType: .audioBooks, videoIDs: [postID])
|
|
}
|
|
}
|
|
|
|
// MARK: - Delegate for reload
|
|
|
|
extension AudioBookHomeVC : ReloadSeriesFavLike{
|
|
|
|
func updateRows(index: Int, type: FavCellCLick, isFav: Bool?, isLike: Bool?, id: Int?) {
|
|
|
|
if let isFav{
|
|
if let continueDataIndex = vm.continueWatchingData.firstIndex(where:{$0.id == id}) {
|
|
vm.continueWatchingData[continueDataIndex].markAsFavourite = isFav
|
|
continueWatchingCV.reloadItems(at: [IndexPath(row: continueDataIndex, section: 0)])
|
|
}
|
|
|
|
if let audioListDataIndex = vm.audioListData.firstIndex(where:{$0.id == id}) {
|
|
vm.audioListData[audioListDataIndex].markAsFavourite = isFav
|
|
audioListingTableView.reloadRows(at: [IndexPath(row: audioListDataIndex, section: 0)],with: .none)
|
|
}
|
|
}
|
|
|
|
if let isLike{
|
|
if let continueDataIndex = vm.continueWatchingData.firstIndex(where:{$0.id == id}) {
|
|
vm.continueWatchingData[continueDataIndex].isLiked = isLike
|
|
if isLike{
|
|
vm.continueWatchingData[continueDataIndex].likesCount! += 1
|
|
}else{
|
|
vm.continueWatchingData[continueDataIndex].likesCount! -= 1
|
|
}
|
|
continueWatchingCV.reloadItems(at: [IndexPath(row: continueDataIndex, section: 0)])
|
|
}
|
|
|
|
if let audioListDataIndex = vm.audioListData.firstIndex(where:{$0.id == id}) {
|
|
vm.audioListData[audioListDataIndex].isLiked = isLike
|
|
if isLike{
|
|
vm.audioListData[audioListDataIndex].likesCount! += 1
|
|
}else{
|
|
vm.audioListData[audioListDataIndex].likesCount! -= 1
|
|
}
|
|
audioListingTableView.reloadRows(at: [IndexPath(row: audioListDataIndex, section: 0)],with: .none)
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// MARK: - TableView DataSource , Delegates
|
|
|
|
extension AudioBookHomeVC : TableViewSRC{
|
|
|
|
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
|
return vm.audioListData.count == 0 ? 2 : vm.audioListData.count
|
|
}
|
|
|
|
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
|
let cell = tableView.dequeueReusableCell(withIdentifier: K.CellIdentifier.WebSeries.webSeriesShowListingCell) as! WebSeriesShowListingCell
|
|
|
|
if vm.audioListData.count == 0{
|
|
cell.showShimmer()
|
|
}else{
|
|
let data = vm.audioListData[indexPath.row]
|
|
cell.setAudioData(data: data)
|
|
cell.stopShimmer()
|
|
}
|
|
|
|
cell.btnTapped = { [weak self] (type) -> Void in
|
|
guard let self else{return}
|
|
let data = vm.audioListData[indexPath.row]
|
|
guard let postID = data.id ,let postType = data.contentMoreDetails?.first?.postType else{return}
|
|
let isFav = data.markAsFavourite
|
|
let isLiked = data.isLiked
|
|
PersistentStorage.shared.addAudioCount(postID: postID)
|
|
vm.updateFavLikes(type: type, isFav: isFav, isLiked: isLiked, postID: postID, postType: postType)
|
|
}
|
|
|
|
return cell
|
|
}
|
|
|
|
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
|
let data = vm.audioListData[indexPath.row]
|
|
|
|
/*
|
|
Updated the top header data
|
|
*/
|
|
vm.headerData = data
|
|
|
|
if let postID = data.id{
|
|
PersistentStorage.shared.addAudioCount(postID: postID)
|
|
}
|
|
|
|
vm.setHeaderData()
|
|
|
|
let sb = UIStoryboard(name: K.StoryBoard.audioBooks, bundle: nil)
|
|
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.AudioBooks.audioBookDetailsVC) as! AudioBookDetailsVC
|
|
vcPush.modalPresentationStyle = .overCurrentContext
|
|
vcPush.modalTransitionStyle = .crossDissolve
|
|
vcPush.audioData = data
|
|
vcPush.delegate = self
|
|
self.present(vcPush, animated: true)
|
|
}
|
|
}
|
|
|
|
// MARK: - CollectionView Delegate and Data Source
|
|
|
|
extension AudioBookHomeVC : CollectionViewSRC{
|
|
|
|
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
|
return vm.continueWatchingData.count
|
|
}
|
|
|
|
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
|
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: K.CellIdentifier.AudioBooks.continueAudioCell, for: indexPath) as! ContinueAudioCell
|
|
let data = vm.continueWatchingData[indexPath.row]
|
|
cell.setAudioData(data: data)
|
|
|
|
cell.btnTapped = { [self] (type) -> Void in
|
|
guard let postID = data.id ,let postType = data.contentMoreDetails?.first?.postType else{return}
|
|
let isFav = data.markAsFavourite
|
|
let isLiked = data.isLiked
|
|
PersistentStorage.shared.addAudioCount(postID: postID)
|
|
vm.updateFavLikes(type: type, isFav: isFav, isLiked: isLiked, postID: postID, postType: postType)
|
|
}
|
|
return cell
|
|
}
|
|
|
|
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
|
let data = vm.continueWatchingData[indexPath.row]
|
|
vm.headerData = data
|
|
if let postID = data.id{
|
|
PersistentStorage.shared.addAudioCount(postID: postID)
|
|
}
|
|
|
|
vm.setHeaderData()
|
|
|
|
let sb = UIStoryboard(name: K.StoryBoard.audioBooks, bundle: nil)
|
|
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.AudioBooks.audioBookDetailsVC) as! AudioBookDetailsVC
|
|
vcPush.modalPresentationStyle = .overCurrentContext
|
|
vcPush.modalTransitionStyle = .crossDissolve
|
|
vcPush.audioData = data
|
|
vcPush.delegate = self
|
|
self.present(vcPush, animated: true)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// MARK: - Collection Flow Layout
|
|
|
|
extension AudioBookHomeVC : UICollectionViewDelegateFlowLayout{
|
|
|
|
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
|
|
return 5
|
|
}
|
|
|
|
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
|
|
let inset: CGFloat = 10
|
|
return UIEdgeInsets(top: 0, left: inset, bottom: 0, right: inset)
|
|
}
|
|
|
|
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
|
|
return 0 // Space between cells
|
|
}
|
|
|
|
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
|
|
let widthPerItem = collectionView.frame.width - 30 // Adjust to your desired width
|
|
return CGSize(width: widthPerItem, height: 230)
|
|
}
|
|
}
|
|
|
|
// MARK: - Animating scrollView
|
|
|
|
extension AudioBookHomeVC: UIScrollViewDelegate {
|
|
|
|
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
|
|
|
// Get the current vertical offset of the scroll view
|
|
let y = scrollView.contentOffset.y
|
|
|
|
// Define the height range for the header view
|
|
let minHeaderHeight: CGFloat = 0.0 // Height at which the header becomes invisible
|
|
let maxHeaderHeight: CGFloat = 200.0 // Maximum height when fully visible
|
|
|
|
// Calculate the new height for the header view based on the scroll position
|
|
let newHeaderHeight: CGFloat
|
|
if y < 0 {
|
|
// When scrolling up beyond the top, ensure the header view is fully expanded
|
|
newHeaderHeight = maxHeaderHeight
|
|
} else {
|
|
// Calculate the new height for the header view, ensuring it doesn't go below the minimum height
|
|
newHeaderHeight = max(minHeaderHeight, maxHeaderHeight - y)
|
|
}
|
|
|
|
// Update the header view's height constraint with the new height
|
|
headerHeight.constant = newHeaderHeight
|
|
|
|
// Animate the layout changes to smoothly transition the header height
|
|
UIView.animate(withDuration: 0.3) {
|
|
self.view.layoutIfNeeded()
|
|
}
|
|
}
|
|
}
|
|
|
|
class UINavigationBarGradientView: UIView {
|
|
|
|
enum Point {
|
|
case topRight, topLeft
|
|
case bottomRight, bottomLeft
|
|
case left , right
|
|
case custom(point: CGPoint)
|
|
|
|
var point: CGPoint {
|
|
switch self {
|
|
case .topRight: return CGPoint(x: 1, y: 0)
|
|
case .topLeft: return CGPoint(x: 0, y: 0)
|
|
case .bottomRight: return CGPoint(x: 1, y: 1)
|
|
case .bottomLeft: return CGPoint(x: 0, y: 1)
|
|
case .left : return CGPoint(x: 0, y: 0)
|
|
case .right : return CGPoint(x: 0.8, y: 0)
|
|
case .custom(let point): return point
|
|
}
|
|
}
|
|
}
|
|
|
|
private weak var gradientLayer: CAGradientLayer!
|
|
|
|
convenience init(colors: [UIColor], startPoint: Point = .topLeft,
|
|
endPoint: Point = .bottomLeft, locations: [NSNumber] = [0, 1]) {
|
|
self.init(frame: .zero)
|
|
let gradientLayer = CAGradientLayer()
|
|
gradientLayer.frame = frame
|
|
layer.addSublayer(gradientLayer)
|
|
self.gradientLayer = gradientLayer
|
|
set(colors: colors, startPoint: startPoint, endPoint: endPoint, locations: locations)
|
|
backgroundColor = .clear
|
|
}
|
|
|
|
func set(colors: [UIColor], startPoint: Point = .topLeft,
|
|
endPoint: Point = .bottomLeft, locations: [NSNumber] = [0, 1]) {
|
|
gradientLayer.colors = colors.map { $0.cgColor }
|
|
gradientLayer.startPoint = startPoint.point
|
|
gradientLayer.endPoint = endPoint.point
|
|
gradientLayer.locations = locations
|
|
}
|
|
|
|
func setupConstraints() {
|
|
guard let parentView = superview else { return }
|
|
translatesAutoresizingMaskIntoConstraints = false
|
|
topAnchor.constraint(equalTo: parentView.topAnchor).isActive = true
|
|
leftAnchor.constraint(equalTo: parentView.leftAnchor).isActive = true
|
|
parentView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
|
|
parentView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
|
|
}
|
|
|
|
override func layoutSubviews() {
|
|
super.layoutSubviews()
|
|
guard let gradientLayer = gradientLayer else { return }
|
|
gradientLayer.frame = frame
|
|
superview?.addSubview(self)
|
|
}
|
|
}
|
|
|
|
extension UINavigationBar {
|
|
func setGradientBackground(colors: [UIColor],
|
|
startPoint: UINavigationBarGradientView.Point = .topLeft,
|
|
endPoint: UINavigationBarGradientView.Point = .bottomLeft,
|
|
locations: [NSNumber] = [0, 1]) {
|
|
guard let backgroundView = value(forKey: "backgroundView") as? UIView else { return }
|
|
guard let gradientView = backgroundView.subviews.first(where: { $0 is UINavigationBarGradientView }) as? UINavigationBarGradientView else {
|
|
let gradientView = UINavigationBarGradientView(colors: colors, startPoint: startPoint,
|
|
endPoint: endPoint, locations: locations)
|
|
backgroundView.addSubview(gradientView)
|
|
gradientView.setupConstraints()
|
|
return
|
|
}
|
|
gradientView.set(colors: colors, startPoint: startPoint, endPoint: endPoint, locations: locations)
|
|
}
|
|
|
|
func removeGradientBackground() {
|
|
guard let backgroundView = value(forKey: "backgroundView") as? UIView else { return }
|
|
if let gradientView = backgroundView.subviews.first(where: { $0 is UINavigationBarGradientView }) {
|
|
gradientView.removeFromSuperview()
|
|
}
|
|
}
|
|
}
|
|
|
|
extension CGPoint{
|
|
|
|
enum Point {
|
|
case topRight, topLeft
|
|
case bottomRight, bottomLeft
|
|
case left , right
|
|
case custom(point: CGPoint)
|
|
|
|
var point: CGPoint {
|
|
switch self {
|
|
case .topRight: return CGPoint(x: 1, y: 0)
|
|
case .topLeft: return CGPoint(x: 0, y: 0)
|
|
case .bottomRight: return CGPoint(x: 1, y: 1)
|
|
case .bottomLeft: return CGPoint(x: 0, y: 1)
|
|
case .left : return CGPoint(x: 0, y: 0)
|
|
case .right : return CGPoint(x: 0.8, y: 0)
|
|
case .custom(let point): return point
|
|
}
|
|
}
|
|
}
|
|
}
|