Files
Woka_Native_iOS/WOKA/Theme/Controller/MoreVC.swift
BilalKhanWDI 7efcbb2d24 - Worked on my list and notification bottom Banner
- Tc - 69 fixed
- Tc - 70 fixed
- TC 71 fixed
- Added local ads to fm and more section
- Added local ads to mylist
- Fixed a bug for sync
* Fixed the crashing by temporary updating the wokastaging with raw data
2024-10-01 19:57:04 +05:30

319 lines
11 KiB
Swift

//
// MoreVC.swift
// WOKA
//
// Created by MacBook Pro on 10/06/24.
//
import UIKit
import AVFoundation
import GoogleMobileAds
class MoreVC: UIViewController {
@IBOutlet weak var blogsCollectionView: UICollectionView!
@IBOutlet weak var homeBtn: UIView!
@IBOutlet weak var songTableView: UITableView!
@IBOutlet weak var blogRetryStack: UIStackView!
@IBOutlet weak var blogActivityIndicator: UIActivityIndicatorView!
@IBOutlet weak var blogRetryBtn: LocalisedElementsButton!
@IBOutlet weak var songRetryStack: UIStackView!
@IBOutlet weak var songActivityIndicator: UIActivityIndicatorView!
@IBOutlet weak var songRetry: LocalisedElementsButton!
@IBOutlet weak var trailerTask: UIStackView!
@IBOutlet weak var trailerView: UIView!
@IBOutlet weak var customAdImage: UIImageView!
@IBOutlet weak var customAdHeight: NSLayoutConstraint!
var vm = MoreVM()
var timeObserverToken: Any?
override func viewDidLoad() {
super.viewDidLoad()
vm.vc = self
vm.initView()
NotificationCenter.default.addObserver(self,selector: #selector(appDidEnterBackground),name: UIApplication.didEnterBackgroundNotification,object: nil)
NotificationCenter.default.addObserver(self,selector: #selector(appWillEnterForeground),name: UIApplication.didBecomeActiveNotification,object: nil)
}
deinit{
NotificationCenter.default.post(name: .enableDisableSideBar, object: nil, userInfo: ["type": true])
NotificationCenter.default.removeObserver(self,name: UIApplication.didEnterBackgroundNotification, object: nil)
NotificationCenter.default.removeObserver(self,name: UIApplication.didBecomeActiveNotification, object: nil)
do {
try AVAudioSession.sharedInstance().setActive(false)
} catch {
print("Failed to deactivate audio session: \(error.localizedDescription)")
}
vm.player?.pause()
}
override func viewWillAppear(_ animated: Bool) {
NotificationCenter.default.post(name: .enableDisableSideBar, object: nil, userInfo: ["type": false])
}
@IBAction func playTrailerBtnTapped(_ sender: LocalisedElementsButton) {
PersistentStorage.shared.addTrailerCount()
let item = JwPlayerItemCreate(url: APIEndPoints.StaticURLs.masilaUrl, poster: nil, titles: "Masila")
JWPlayerManager.shared.presentPlayer(from: self, playerItems: [item], contentType: .trailer, videoIDs: [0])
}
@IBAction func retryBtnTapped(_ sender: LocalisedElementsButton) {
}
// MARK: - App Lifecycle
@objc func appDidEnterBackground() {
if let currentIndexPlayingSong = vm.currentIndexPlayingSong{
let song = vm.songData[currentIndexPlayingSong]
vm.setupNowPlayingInfo(songTitle: song.title ?? "WOKA Song")
vm.setupRemoteCommandCenter()
}
}
@objc func appWillEnterForeground(){
vm.stopMPNowPlayin()
}
}
// MARK: - TableView DataSource , Delegates
extension MoreVC : TableViewSRC{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return vm.songData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SongListCell", for: indexPath) as! SongListCell
let songData = vm.songData[indexPath.row]
// let isActive = (indexPath.row == vm.currentIndexPlayingSong)
if let index = vm.currentIndexPlayingSong , index == indexPath.row{
cell.setData(data: songData,playerStatus: vm.playerStatus, active: true, currentTime: currentTimePlayer)
}else{
cell.setData(data: songData,playerStatus: .stopped , active: false, currentTime: 0)
}
return cell
}
func getFormattedTime(from player: AVPlayer) -> String {
let currentTime = player.currentTime()
let seconds = CMTimeGetSeconds(currentTime)
if !seconds.isFinite {
return "00:00:00"
}
let hours = Int(seconds) / 3600
let minutes = (Int(seconds) % 3600) / 60
let secs = Int(seconds) % 60
return String(format: "%02d:%02d:%02d", hours, minutes, secs)
}
func handleTap(indexPath : IndexPath){
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let cell = tableView.cellForRow(at: indexPath) else { return }
addAnimation(cell: cell) { [weak self] in
guard let self else{return}
vm.handleInlinePlay(indexPath: indexPath.row)
}
}
func addAnimation(cell : UITableViewCell, completion : @escaping () -> Void){
UIView.animate(withDuration: 0.1,animations: {
cell.transform = CGAffineTransform(scaleX: 0.95, y: 0.95)
},
completion: { _ in
UIView.animate(withDuration: 0.1) {
cell.transform = CGAffineTransform.identity
completion()
}
})
}
func startPlaying(song: SongBlogDM.PaintDatum, at indexPath: IndexPath) {
// Set up and start the player
stopPlaying()
if let urlString = song.contentMoreDetails?.first?.url , let url = URL(string: urlString){
vm.player = AVPlayer(url: url)
vm.player?.play()
vm.playerStatus = .play
vm.currentIndexPlayingSong = indexPath.row
addPeriodicTimeObserver()
vm.observePlayer()
}
}
func stopPlaying() {
// Remove the periodic time observer
removePeriodicTimeObserver()
// Stop the player
vm.player?.pause()
// vm.player = nil
vm.playerStatus = .stopped
vm.currentIndexPlayingSong = nil
}
func removePeriodicTimeObserver() {
if let token = timeObserverToken {
vm.player?.removeTimeObserver(token)
timeObserverToken = nil
}
}
func addPeriodicTimeObserver() {
let interval = CMTime(seconds: 1, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
timeObserverToken = vm.player?.addPeriodicTimeObserver(forInterval: interval, queue: .main) { [weak self] time in
guard let self = self else { return }
currentTimePlayer = Int(CMTimeGetSeconds(time))
if let currentPlayingIndex = self.vm.currentIndexPlayingSong,
let cell = self.songTableView.cellForRow(at: IndexPath(row: currentPlayingIndex, section: 0)) as? SongListCell {
cell.updateCurrentTime()
}
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 60
}
}
// MARK: - CollectionView DataSource Delegate
extension MoreVC : CollectionViewSRC{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return vm.blogData.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: K.CellIdentifier.Home.blogsCell, for: indexPath) as! BlogsCell
cell.setData(data : vm.blogData[indexPath.row])
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
PersistentStorage.shared.addOthersCount()
let data = vm.blogData[indexPath.row]
let sb = UIStoryboard(name: K.StoryBoard.theme, bundle: nil)
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Theme.blogDetailsVC) as! BlogDetailsVC
vcPush.blogData = data
vcPush.modalPresentationStyle = .overCurrentContext
vcPush.modalTransitionStyle = .crossDissolve
self.present(vcPush, animated: true)
}
}
// MARK: - Collection Flow Layout
extension MoreVC : UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 5
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 5
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let itemsPerRow: CGFloat = 2.2
let paddingSpace = 5 * (itemsPerRow + 1)
let availableWidth = collectionView.frame.width - paddingSpace
let widthPerItem = availableWidth / itemsPerRow
return CGSize(width: widthPerItem, height: widthPerItem)
}
}
// MARK: - Google Ad Banner Delegate
extension MoreVC : GADBannerViewDelegate{
func bannerViewDidReceiveAd(_ bannerView: GADBannerView) {
bannerView.alpha = 0
bannerView.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
UIView.animate(withDuration: 0.3, animations: { [weak self] in
guard let self else{return}
trailerView.alpha = 0
bannerView.alpha = 1
})
print("bannerViewDidReceiveAd")
}
func bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error) {
print("bannerView:didFailToReceiveAdWithError: \(error.localizedDescription)")
}
func bannerViewDidRecordImpression(_ bannerView: GADBannerView) {
print("bannerViewDidRecordImpression")
}
func bannerViewWillPresentScreen(_ bannerView: GADBannerView) {
print("bannerViewWillPresentScreen")
}
func bannerViewWillDismissScreen(_ bannerView: GADBannerView) {
print("bannerViewWillDIsmissScreen")
}
func bannerViewDidDismissScreen(_ bannerView: GADBannerView) {
print("bannerViewDidDismissScreen")
}
}
//class VideoAVPlayer {
//
// var player: AVPlayer?
// var playerObserver: NSKeyValueObservation?
// var status = PlayerStatus.loading
//
// init(url: URL) {
// self.player = AVPlayer(url: url)
// observePlayer()
// }
//
// private func observePlayer() {
// playerObserver = player?.observe(\.timeControlStatus, options: [.new, .old], changeHandler: { [weak self] player, change in
// guard let self = self else { return }
// switch player.timeControlStatus {
// case .playing:
// print("Player is playing")
// self.status = .play
// case .paused:
// print("Player is paused")
// self.status = .pause
// case .waitingToPlayAtSpecifiedRate:
// print("Player is waiting to play at specified rate")
// self.status = .loading
// @unknown default:
// print("Unknown player status")
// }
// })
// }
//
// deinit {
// playerObserver?.invalidate()
// }
//
// func play() {
// player?.play()
// }
//
// func pause() {
// player?.pause()
// }
//}