// // ThemeOneVM.swift // WOKA // // Created by MacBook Pro on 23/05/24. // import UIKit import AVFoundation import JWPlayerKit class ThemeOneVM{ weak var vc : ThemeOneVC! var cloudMovingRight = false // Flag to track the direction of movement var isMovingRight = false // Flag to track the direction of movement var liveStreamURL = "https://d3volyx7jx7oal.cloudfront.net/master.m3u8" var avPlayer : AVPlayer! var playerLayer: AVPlayerLayer! var shouldAnimate = true func initView(){ vc.bottomArrow.addTapGesture { let sb = UIStoryboard(name: K.StoryBoard.theme, bundle: nil) let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Theme.moreVC) as! MoreVC vcPush.modalPresentationStyle = .overCurrentContext self.vc.present(vcPush, animated: true) } AuthFunc.shareInstance.initTimePeriods() startInitialTimer() moveCloudView() handleTaps() setUserData() handleNotificationCenter() addTapGestureToMovingView() vc.nameLabel.setContentHuggingPriority(.fittingSizeLevel, for: .horizontal) vc.nameLabel.setContentCompressionResistancePriority(.fittingSizeLevel, for: .horizontal) } private func handleNotificationCenter(){ NotificationCenter.default.addObserver(self, selector: #selector(appDidEnterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(appWillEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(self.reloadTheme), name: NSNotification.Name(rawValue: K.NotificationCenterReloads.reloadTheme), object: nil) } func setupAvPlayer(){ /* Av Player Setup */ let streamURL = URL(string: liveStreamURL) // Create AVPlayer with the stream URL avPlayer = AVPlayer(url: streamURL!) // avPlayer.isMuted = true // Create AVPlayerLayer playerLayer = AVPlayerLayer(player: avPlayer) playerLayer.videoGravity = .resizeAspectFill // You can set different videoGravity as per your need playerLayer.frame = self.vc.liveTvPlayer.bounds self.vc.liveTvPlayer.layer.addSublayer(playerLayer) avPlayer.play() avPlayer.volume = 0 } func setUserData(){ guard let data = AuthFunc.shareInstance.userData else{return} //set the first name as the name /* Check User Type, Dont show username if the user type is guest */ switch data.userType{ case "1": // child vc.nameLabel.text = data.fullname?.components(separatedBy: " ").first vc.notificationBtnn.isHidden = false case "2" : // adult vc.nameLabel.text = data.fullname?.components(separatedBy: " ").first vc.notificationBtnn.isHidden = false case "3": // Guest vc.nameLabel.text = "" vc.notificationBtnn.isHidden = true break default: break } if let avatar = data.avtar{ //https://wokaland.com/admin/storage/app/public/uploads/avtar/avatar2.png?d=1716889852 vc.avatarImage.imageURL("https://wokaland.com/admin/storage/app/public/uploads/avtar/avatar2.png?d=1716889852") } } // MARK: - Notification Center Handlers @objc func reloadTheme(){ self.vc.delegate?.didPressSwitchButton(from: self.vc) } @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() } // MARK: - Handle Tap Gesture func handleTaps(){ //WebSeries vc.webSeriesView.addTapGesture { ViewButtonAnimation.sharedInstance.btnTapped(in: self.vc, view: self.vc.webSeriesView) { let sb = UIStoryboard(name: K.StoryBoard.webSeries, bundle: nil) let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.WebSeries.webSeriesVC) as! WebSeriesVC self.vc.navigationController?.pushViewController(vcPush, animated: true) } } } // 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 = self else { return } let margin: CGFloat = 30 let screenWidth = vc.view.frame.width let viewWidth = vc.liveTVView.frame.width let maxX = screenWidth - margin - viewWidth / 2 let minX = margin + viewWidth / 2 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 = 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 } }) } func moveCloudView() { UIView.animate(withDuration: 23, delay: 0, options: [], animations: { [weak self] in guard let self else{return} if cloudMovingRight { // print("right") vc.cloud2.center.x += 140 // Move to the right vc.cloud1.center.x -= 140 // Move to the right } else { // print("left") vc.cloud2.center.x -= 140 // Move to the left vc.cloud1.center.x += 140 // Move to the left } }, completion: { [weak self] _ in guard let self else{return} cloudMovingRight.toggle() // Toggle the direction for the next iteration moveCloudView() // Recursively call moveView to create a continuous animation }) } // MARK: - LiveTV Tap Handling private func addTapGestureToMovingView(){ let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:))) vc.liveTVView.addGestureRecognizer(tap) vc.liveTVView.isUserInteractionEnabled = true } // function which is triggered when handleTap is called @objc func handleTap(_ sender: UITapGestureRecognizer) { Utilities.startProgressHUD(msg: "Loading...") print("tapped") let vc = self.vc.storyboard?.instantiateViewController(identifier: "PlayerVC") as! PlayerVC DispatchQueue.main.async { do { // Create a JWMediaTrack with the thumbnails .vtt file // let thumbnailTrack = try JWThumbnailTrackBuilder() // .file(URL(string:"https://content.jwplatform.com/videos/Agy4RIje-Ysj2G4DQ.mp4")!) // .build() // Create a JWPlayerItem let item = try JWPlayerItemBuilder() .file(URL(string: self.liveStreamURL)!) .title("Testing Title") // .posterImage(URL(string: "https://img.freepik.com/free-photo/painting-mountain-lake-with-mountain-background_188544-9126.jpg")!) // .mediaTracks([thumbnailTrack]) .build() // Create a config, and give it the item as a playlist. let config = try JWPlayerConfigurationBuilder() .playlist(items: [item]) .autostart(true) // .preload(.auto) // .repeatContent(true) .build() vc.config = config vc.dismissTapped = self.tapped vc.modalPresentationStyle = .overFullScreen Utilities.dismissProgressHUD() self.vc.present(vc, animated: false) { self.stopLiveStream() vc.transitionToFullScreen(animated: true) { print("FullScreen") } // vc.setDeviceOrientation(orientation: .landscapeRight) } // Utilities.dismissProgressHUD() // self.vc.navigationController?.pushViewController(vc, animated: true) // self.stopLiveStream() } catch { // Handle Error } } } func tapped(){ Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false) { _ in self.startLiveStream() self.vc.liveTvPlayer.layoutIfNeeded() } print("Sadasd") } func startLiveStream(){ avPlayer.play() avPlayer.volume = 0 } func stopLiveStream(){ avPlayer.pause() } // MARK: - Handle Time Change @objc func handleBackground(){ let currentTime = Date() for period in AuthFunc.shareInstance.timePeriods { if period.contains(currentTime: currentTime) { let details = period.details // Update view's background color with a gradient or single color DispatchQueue.main.async { [weak self] in guard let self else{return} if period.details.dayCycle == .night{ startStarGlowAnimation() }else{ //just hide the moon and star if its not night !vc.moonImage.isHidden ? vc.moonImage.isHidden = true : nil vc.star.forEach { image in !image.isHidden ? image.isHidden = true : nil } } vc.gradientView.applyGradient(colors: [details.color1, details.color2], startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0, y: 0.8)) vc.nameLabel.textColor = details.textColor vc.HelloLabel.textColor = details.textColor vc.welcomeLabel.textColor = details.textColor vc.homeGrass.image = UIImage(named: details.grass) } break } } } func startStarGlowAnimation() { vc.moonImage.isHidden ? vc.moonImage.isHidden = false : nil for (index, imageView) in vc.star.enumerated() { //If star is hidden just unhide it for the night time (vc.star[index].isHidden) ? (vc.star[index].isHidden = false) : nil let animation = CABasicAnimation(keyPath: "opacity") animation.fromValue = 1.0 animation.toValue = 0.07 animation.duration = 3.0 animation.autoreverses = true animation.repeatCount = .infinity // Calculate delay for each animation based on index let delay = Double(index) * 1 // Adjust the delay as needed // Apply the delay to the animation animation.beginTime = CACurrentMediaTime() + delay imageView.layer.add(animation, forKey: "glowAnimation") } } func startInitialTimer() { self.handleBackground() let now = Date() let nextMinute = Calendar.current.nextDate(after: now, matching: DateComponents(second: 0), matchingPolicy: .nextTime)! let timeInterval = nextMinute.timeIntervalSince(now) // Schedule the initial timer to fire at the start of the next minute vc.timer = Timer.scheduledTimer(timeInterval: timeInterval, target: self, selector: #selector(startRepeatingTimer), userInfo: nil, repeats: false) } @objc func startRepeatingTimer() { // Handle the minute change when the initial timer fires self.handleBackground() // Schedule the repeating timer to fire every minute vc.timer = Timer.scheduledTimer(timeInterval: 60, target: self, selector: #selector(handleBackground), userInfo: nil, repeats: true) } }