Files
Woka_Native_iOS/WOKA/Theme/Controller/MoreVC.swift
BilalKhanWDI bb68fa1e3c - Completed Apply Coupon Functionality
- Made a selection for the coupon selected, also added no coupon found when coupon is not there
- Added Masila view in more section
- Added Play trailer from Manila in more section
- Gave other connectivity
2024-07-24 19:59:08 +05:30

293 lines
11 KiB
Swift

//
// MoreVC.swift
// WOKA
//
// Created by MacBook Pro on 10/06/24.
//
import UIKit
import AVFoundation
class MoreVC: UIViewController {
@IBOutlet weak var blogsCollectionView: UICollectionView!
@IBOutlet weak var homeBtn: UIView!
@IBOutlet weak var songTableView: UITableView!
var vm = MoreVM()
var timeObserverToken: Any?
override func viewDidLoad() {
super.viewDidLoad()
vm.vc = self
vm.initView()
}
override func viewWillAppear(_ animated: Bool) {
NotificationCenter.default.post(name: .enableDisableSideBar, object: nil, userInfo: ["type": false])
}
override func viewWillDisappear(_ animated: Bool) {
NotificationCenter.default.post(name: .enableDisableSideBar, object: nil, userInfo: ["type": true])
vm.player?.pause()
}
@IBAction func playTrailerBtnTapped(_ sender: LocalisedElementsButton) {
let item = JwPlayerItemCreate(url: APIEndPoints.StaticURLs.masilaUrl, poster: nil, titles: "Masila")
JWPlayerManager.shared.presentPlayer(from: self, playerItems: [item], contentType: .trailer)
}
}
// 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}
/*
this will declare if the song is playing or not
*/
if let playingIndex = vm.currentIndexPlayingSong {
if indexPath.row == playingIndex{ // if same row is selected pause the row
print(vm.playerStatus)
switch vm.playerStatus{
case .play: // if player is playing pause it.
print("Player is playing")
vm.player?.pause()
vm.playerStatus = .pause
tableView.reloadRows(at: [IndexPath(row: vm.currentIndexPlayingSong!, section: 0)], with: .none)
case .pause:
vm.player?.play()
vm.playerStatus = .resume
tableView.reloadRows(at: [IndexPath(row: vm.currentIndexPlayingSong!, section: 0)], with: .none)
case .loading:
print("Player is loading")
case .resume:
print("Player is resume")
default:
break
}
}else{
/*
this means other cell was playing now stop it and play this new cell
first reload the playing cell and pause the audio
*/
//Reset Old Cell
vm.playerStatus = .stopped
tableView.reloadRows(at: [IndexPath(row: vm.currentIndexPlayingSong!, section: 0)], with: .none)
//Update new cell
vm.currentIndexPlayingSong = indexPath.row
vm.playerStatus = .loading
currentTimePlayer = 0
tableView.reloadRows(at: [indexPath], with: .none)
let data = vm.songData[indexPath.row]
startPlaying(song: data, at: indexPath)
print("Other cell playing")
}
}else{
// if there is no playing audio before
vm.playerStatus = .loading
vm.currentIndexPlayingSong = indexPath.row
currentTimePlayer = 0
tableView.reloadRows(at: [indexPath], with: .none)
let data = vm.songData[indexPath.row]
startPlaying(song: data, at: indexPath)
print("First Play")
}
}
}
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) {
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)
}
}
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()
}
}