diff --git a/Podfile b/Podfile index f45c0b5..4fad18a 100644 --- a/Podfile +++ b/Podfile @@ -16,6 +16,9 @@ target 'WOKA' do # Image Loading & Caching pod 'SDWebImage', '~> 5.19.1' + #JwPlayer + pod 'JWPlayerKit', '>= 4.0.0' + # Bottom line is for removing IPHONEOS_DEPLOYMENT_TARGET post_install do |installer| installer.generated_projects.each do |project| diff --git a/WOKA.xcodeproj/project.pbxproj b/WOKA.xcodeproj/project.pbxproj index 65bd7f4..f771d9b 100644 --- a/WOKA.xcodeproj/project.pbxproj +++ b/WOKA.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 5202AAFE2BDF90590043B7BD /* TextFieldImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5202AAFD2BDF90590043B7BD /* TextFieldImage.swift */; }; 5202AB012BDFA7900043B7BD /* EmailValidation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5202AB002BDFA7900043B7BD /* EmailValidation.swift */; }; + 5219C2C22C086D9C00A1DF4D /* DataTypeConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5219C2C12C086D9B00A1DF4D /* DataTypeConversion.swift */; }; 522242662BFC74380085C632 /* MyListVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522242632BFC74380085C632 /* MyListVC.swift */; }; 522242682BFC74380085C632 /* TabBarVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522242652BFC74380085C632 /* TabBarVC.swift */; }; 5222426A2BFC7AFC0085C632 /* SideMenuVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522242692BFC7AFC0085C632 /* SideMenuVC.swift */; }; @@ -72,6 +73,7 @@ 52A3F6AB2BECBF550000BB0B /* LinkedChildVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52A3F6AA2BECBF550000BB0B /* LinkedChildVC.swift */; }; 52A3F6AD2BECC0340000BB0B /* TypeAlias.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52A3F6AC2BECC0340000BB0B /* TypeAlias.swift */; }; 52A3F6AF2BECC0690000BB0B /* LinkedChildVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52A3F6AE2BECC0690000BB0B /* LinkedChildVM.swift */; }; + 52AECA802C08BCB6004A7579 /* PlayerVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52AECA7F2C08BCB6004A7579 /* PlayerVC.swift */; }; 52B8D4D92C04A25E00ED65F3 /* UIViewController+Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B8D4CE2C04A25D00ED65F3 /* UIViewController+Container.swift */; }; 52B8D4DA2C04A25E00ED65F3 /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B8D4CF2C04A25D00ED65F3 /* Preferences.swift */; }; 52B8D4DB2C04A25E00ED65F3 /* TransitionContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B8D4D02C04A25D00ED65F3 /* TransitionContext.swift */; }; @@ -177,6 +179,7 @@ 5202AB002BDFA7900043B7BD /* EmailValidation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmailValidation.swift; sourceTree = ""; }; 520B6E3E2C0751E90091C478 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Theme.strings; sourceTree = ""; }; 520B6E402C0751EF0091C478 /* hi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hi; path = hi.lproj/Theme.strings; sourceTree = ""; }; + 5219C2C12C086D9B00A1DF4D /* DataTypeConversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataTypeConversion.swift; sourceTree = ""; }; 522242632BFC74380085C632 /* MyListVC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyListVC.swift; sourceTree = ""; }; 522242652BFC74380085C632 /* TabBarVC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabBarVC.swift; sourceTree = ""; }; 522242692BFC7AFC0085C632 /* SideMenuVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideMenuVC.swift; sourceTree = ""; }; @@ -238,6 +241,7 @@ 52A3F6AA2BECBF550000BB0B /* LinkedChildVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkedChildVC.swift; sourceTree = ""; }; 52A3F6AC2BECC0340000BB0B /* TypeAlias.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypeAlias.swift; sourceTree = ""; }; 52A3F6AE2BECC0690000BB0B /* LinkedChildVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkedChildVM.swift; sourceTree = ""; }; + 52AECA7F2C08BCB6004A7579 /* PlayerVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerVC.swift; sourceTree = ""; }; 52B8D4CE2C04A25D00ED65F3 /* UIViewController+Container.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+Container.swift"; sourceTree = ""; }; 52B8D4CF2C04A25D00ED65F3 /* Preferences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = ""; }; 52B8D4D02C04A25D00ED65F3 /* TransitionContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransitionContext.swift; sourceTree = ""; }; @@ -690,6 +694,7 @@ 525954592BEB67D200191286 /* DateFormatterLib.swift */, 5259545D2BEBBA1A00191286 /* LoadingIndicatorImageView.swift */, 52A3F6AC2BECC0340000BB0B /* TypeAlias.swift */, + 5219C2C12C086D9B00A1DF4D /* DataTypeConversion.swift */, ); path = Helpers; sourceTree = ""; @@ -819,6 +824,7 @@ children = ( 9CBCB2A92BE51A52007D7934 /* ThemeOneVC.swift */, 9C535DC12C00B36900DA6DCD /* ThemeTwoVC.swift */, + 52AECA7F2C08BCB6004A7579 /* PlayerVC.swift */, ); path = Controller; sourceTree = ""; @@ -1157,6 +1163,7 @@ 522242662BFC74380085C632 /* MyListVC.swift in Sources */, 5259542B2BEA292800191286 /* UserRegPostModel.swift in Sources */, 52C8B0572BDA57DB003B51D0 /* Constant.swift in Sources */, + 52AECA802C08BCB6004A7579 /* PlayerVC.swift in Sources */, 5202AB012BDFA7900043B7BD /* EmailValidation.swift in Sources */, 52B8D4E12C04A25E00ED65F3 /* BasicTransitionAnimator.swift in Sources */, 525954192BE8CC3400191286 /* ConstantString.swift in Sources */, @@ -1206,6 +1213,7 @@ 52C6E01E2BE3847F00E22D59 /* BorderView.swift in Sources */, 52FDBA7D2BFF481A009D7AC7 /* ThemeOneVM.swift in Sources */, 52C8B0742BDA7626003B51D0 /* OnBoardVC.swift in Sources */, + 5219C2C22C086D9C00A1DF4D /* DataTypeConversion.swift in Sources */, 525953CF2BE8B28F00191286 /* Utilities.swift in Sources */, 9CBCB2A12BE4E50A007D7934 /* TextFieldPassword.swift in Sources */, 9C56E8482BDBEFAB00E4CA14 /* AssetColor.swift in Sources */, @@ -1370,7 +1378,7 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu17; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -1435,7 +1443,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu17; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; diff --git a/WOKA.xcodeproj/xcshareddata/xcschemes/WOKA.xcscheme b/WOKA.xcodeproj/xcshareddata/xcschemes/WOKA.xcscheme index e31268e..8512c74 100644 --- a/WOKA.xcodeproj/xcshareddata/xcschemes/WOKA.xcscheme +++ b/WOKA.xcodeproj/xcshareddata/xcschemes/WOKA.xcscheme @@ -1,6 +1,6 @@ , NetworkManager.APIError>) in + NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Auth.guest_login, method: .post ,parameters: params, headers: header) {(result : Result, NetworkManager.APIError>) in switch result{ case .success(let data): switch data.success{ @@ -179,8 +172,10 @@ class LoginVM{ self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2) case 1: Utilities.dismissProgressHUD() + guard let dataUser = data.data else{return} self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2) { - UIApplication.setRootView(SideMenuController.instantiate(from: .Home)) + let userDataConverted = UserDataDM.ResultData(id: nil, username: dataUser.username, fullname: dataUser.fullname, birthdate: nil, email: nil, avtar: nil, userType: "3", languageMasterID: nil, lastLogin: nil, rememberToken: nil, childDetail: nil, language: nil, alreadyLoggedIn: nil) + AuthFunc.shareInstance.loginDefaults(data: userDataConverted) } default: break diff --git a/WOKA/Constants K/OnBoardVM.swift b/WOKA/Constants K/OnBoardVM.swift index 855f326..65fe1d6 100644 --- a/WOKA/Constants K/OnBoardVM.swift +++ b/WOKA/Constants K/OnBoardVM.swift @@ -120,7 +120,7 @@ class OnBoardVM{ ] let header : HTTPHeaders = ["device-id" : AuthFunc.shareInstance.getDeviceUUID(), "Accept-Language" : AuthFunc.shareInstance.languageSelected == .english ? "English" : "Hindi"] - + animationView?.pause() Utilities.startProgressHUD() NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Auth.guest_login, method: .post ,parameters: params, headers: header) {(result : Result, NetworkManager.APIError>) in switch result{ @@ -132,9 +132,10 @@ class OnBoardVM{ case 1: Utilities.dismissProgressHUD() guard let dataUser = data.data else{return} - AuthFunc.shareInstance.userData = UserDataDM.ResultData(id: nil, username: dataUser.username, fullname: dataUser.fullname, birthdate: nil, email: nil, avtar: nil, userType: "3", languageMasterID: nil, lastLogin: nil, rememberToken: nil, childDetail: nil, language: nil, alreadyLoggedIn: nil) + self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2) { - UIApplication.setRootView(SideMenuController.instantiate(from: .Home)) + let userDataConverted = UserDataDM.ResultData(id: nil, username: dataUser.username, fullname: dataUser.fullname, birthdate: nil, email: nil, avtar: nil, userType: "3", languageMasterID: nil, lastLogin: nil, rememberToken: nil, childDetail: nil, language: nil, alreadyLoggedIn: nil) + AuthFunc.shareInstance.loginDefaults(data: userDataConverted) } default: break diff --git a/WOKA/Constants K/UserDefaultsStruct.swift b/WOKA/Constants K/UserDefaultsStruct.swift index 4601a53..6257f42 100644 --- a/WOKA/Constants K/UserDefaultsStruct.swift +++ b/WOKA/Constants K/UserDefaultsStruct.swift @@ -21,6 +21,7 @@ extension K{ static let isUserLogined = "isUserLogined" static let userAccessToken = "userAccessToken" static let defaultLanguage = "defaultLanguage" + static let userType = "userType" } } diff --git a/WOKA/Helpers/DataTypeConversion.swift b/WOKA/Helpers/DataTypeConversion.swift new file mode 100644 index 0000000..fa6ac7b --- /dev/null +++ b/WOKA/Helpers/DataTypeConversion.swift @@ -0,0 +1,125 @@ +// +// DataTypeConversion.swift +// WOKA +// +// Created by MacBook Pro on 30/05/24. +// + +import UIKit + +// MARK: - Rounding Double + +extension Double { + var threeDigits: Double { + return (self * 1000).rounded(.toNearestOrEven) / 1000 + } + + var twoDigits: Double { + return (self * 100).rounded(.toNearestOrEven) / 100 + } + + var oneDigit: Double { + return (self * 10).rounded(.toNearestOrEven) / 10 + } +} + +//MARK: - Int To String +extension Int{ + func toString() -> String{ + let myString = String(self) + return myString + } + + func strFormat(decimal : Int)-> String{ + return String(format: "%.\(decimal)f%", self) + } +} + +extension Float{ + func strFormat(decimal : Int)-> String{ + return String(format: "%.\(decimal)f%", self) + } +} + +//MARK: - String To Double + +extension String { + func toDouble() -> Double? { + return NumberFormatter().number(from: self)?.doubleValue + } +} + +//MARK: - Double To String +extension Double { + func toString() -> String { + return String(format: "%.2f",self) + } + + func simpleString() -> String { + return String(self) + } + + func strFormat(decimal : Int)-> String{ + return String(format: "%.\(decimal)f%", self) + } + + func rounded(decimalPoint: Int) -> Double { + let power = pow(10, Double(decimalPoint)) + return (self * power).rounded() / power + } +} + +//MARK: - Double To Int +extension Double { + func toInt() -> Int { + return Int(self) + } +} + +//MARK: - String To Int +extension String { + func toInt() -> Int { + return Int(Double(self) ?? 0.0) + } +} + +//MARK: - String To Int +extension String { + func toCgFloat() -> CGFloat { + let val = Float(self) ?? 0.0 + return CGFloat(val) + } +} + +//MARK: - Int To String +extension Int { + func toCgFloat() -> CGFloat { + return CGFloat(self) + } +} + +//MARK: - Int To Double +extension Int { + func toDouble() -> Double { + return Double(self) + } +} + +//MARK: - filter number from string + +extension String { + var numbers: String { + return filter { "0"..."9" ~= $0 } + } +} + +extension Double { + func round(to decimalPlaces: Int) -> Double { + let precisionNumber = pow(10,Double(decimalPlaces)) + var n = self // self is a current value of the Double that you will round + n = n * precisionNumber + n.round() + n = n / precisionNumber + return n + } +} diff --git a/WOKA/Home/Controller/ExploreWokaVC.swift b/WOKA/Home/Controller/ExploreWokaVC.swift index cb42724..1fc4783 100644 --- a/WOKA/Home/Controller/ExploreWokaVC.swift +++ b/WOKA/Home/Controller/ExploreWokaVC.swift @@ -11,6 +11,8 @@ class ExploreWokaVC: UIViewController { @IBOutlet weak var blurView: UIView! @IBOutlet weak var extraView: UIView! + @IBOutlet weak var customView: UIView! + @IBOutlet weak var layerView: UIView! override func viewDidLoad() { super.viewDidLoad() @@ -18,6 +20,10 @@ class ExploreWokaVC: UIViewController { // Do any additional setup after loading the view. } + override func viewDidLayoutSubviews() { +// customView.drawCustomShape() + } + func drawBackgroundBlur() { let blurEffect = UIBlurEffect(style: .light) let blurredView = UIVisualEffectView(effect: blurEffect) @@ -36,3 +42,55 @@ class ExploreWokaVC: UIViewController { self.dismiss(animated: true) } } + +extension UIView{ + func drawCustomShape() { + let cornerRadius: CGFloat = 18.0 + let shapeOffset = self.frame.size.height * 0.2 + let triangleHeight: CGFloat = 20.0 // height of the triangle pointer + let triangleWidth: CGFloat = 40.0 // width of the triangle pointer + + // create shape layer + let shapeLayer = CAShapeLayer() + shapeLayer.frame = self.bounds + shapeLayer.lineWidth = 1.0 + shapeLayer.fillColor = UIColor.white.cgColor + + self.layer.addSublayer(shapeLayer) + + // create path + let path = UIBezierPath() + + // top left point + path.move(to: CGPoint(x: 0, y: cornerRadius)) + // top left corner + path.addQuadCurve(to: CGPoint(x: cornerRadius, y: 0), controlPoint: CGPoint(x: 0, y: 0)) + + // top right point + path.addLine(to: CGPoint(x: self.frame.size.width - cornerRadius, y: 0)) + // top right corner + path.addQuadCurve(to: CGPoint(x: self.frame.size.width, y: cornerRadius), controlPoint: CGPoint(x: self.frame.size.width, y: 0)) + + // bottom right point before corner + path.addLine(to: CGPoint(x: self.frame.size.width, y: self.frame.size.height - shapeOffset - cornerRadius)) + // bottom right corner + path.addQuadCurve(to: CGPoint(x: self.frame.size.width - cornerRadius, y: self.frame.size.height - shapeOffset), controlPoint: CGPoint(x: self.frame.size.width, y: self.frame.size.height - shapeOffset)) + + // move to bottom center point before the triangle + path.addLine(to: CGPoint(x: self.frame.size.width / 2 + triangleWidth / 2, y: self.frame.size.height - shapeOffset)) + + // add triangle pointer + path.addLine(to: CGPoint(x: self.frame.size.width / 2, y: self.frame.size.height - shapeOffset + triangleHeight)) + path.addLine(to: CGPoint(x: self.frame.size.width / 2 - triangleWidth / 2, y: self.frame.size.height - shapeOffset)) + +// // bottom left point before corner +// path.addLine(to: CGPoint(x: cornerRadius, y: self.frame.size.height - shapeOffset)) +// // bottom left corner + path.addQuadCurve(to: CGPoint(x: 0, y: self.frame.size.height - cornerRadius), controlPoint: CGPoint(x: 0, y: self.frame.size.height)) + + path.close() + + shapeLayer.path = path.cgPath + } + +} diff --git a/WOKA/Home/Home.storyboard b/WOKA/Home/Home.storyboard index bed2912..3da1844 100644 --- a/WOKA/Home/Home.storyboard +++ b/WOKA/Home/Home.storyboard @@ -15,6 +15,9 @@ Exo2-Medium + + Exo2-SemiBold + @@ -532,6 +535,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - @@ -477,17 +477,17 @@ - + - @@ -602,6 +617,9 @@ + + + diff --git a/WOKA/Theme/Controller/PlayerVC.swift b/WOKA/Theme/Controller/PlayerVC.swift new file mode 100644 index 0000000..916e380 --- /dev/null +++ b/WOKA/Theme/Controller/PlayerVC.swift @@ -0,0 +1,239 @@ +// +// PlayerVC.swift +// WOKA +// +// Created by MacBook Pro on 30/05/24. +// + +import UIKit +import JWPlayerKit +import AVKit + +class PlayerVC: JWPlayerViewController ,JWPlayerViewControllerDelegate{ + func playerViewController(_ controller: JWPlayerKit.JWPlayerViewController, relatedItemBeganPlaying item: JWPlayerKit.JWPlayerItem, atIndex index: Int, withMethod method: JWPlayerKit.JWRelatedMethod) { + + } + + override func jwplayer(_ player: any JWPlayer, didFinishLoadingWithTime loadTime: TimeInterval) { + print("LoadTime " , loadTime) + self.player.play() + } + + @IBOutlet weak var innerPlayerView: UIView! + + var previousScale: CGFloat = 1.0 + let backButton = UIButton(type: .system) + var config : JWPlayerConfiguration! + var dismissTapped : (() -> Void)? + + override func viewDidLoad() { + super.viewDidLoad() + self.delegate = self +// + +// self.forceFullScreenOnLandscape = true +// self.playerView.videoGravity = .resizeAspectFill + + +// let skinStylingBuilder = JWPlayerSkinBuilder() +// // Call methods on the builder to create your desired style. +// skinStylingBuilder.backgroundColor(UIColor.blue) +// skinStylingBuilder.fontColor(UIColor.red) +//// self.interfaceBehavior = .hidden +// self.playerView.captionStyle = .none +// // skinStylingBuilder.buttonsColor(UIColor.purple) +// +// let skinStyling = try? skinStylingBuilder.build() +// self.styling = skinStyling + + player.configurePlayer(with: config) +// self.playerView.allowsPictureInPicturePlayback = true +// self.player.seek(to: 15) + + NotificationCenter.default.addObserver(self, selector: #selector(applicationDidBecomeActive), name: UIApplication.willEnterForegroundNotification, object: nil) + + } + @objc func applicationDidBecomeActive() { + self.setDeviceOrientation(orientation: .landscapeRight) + } + // Handle device orientation change + + override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + if (size.width > self.view.frame.size.width) { + print("Landscape") + } else { + DispatchQueue.main.async { + self.dismiss(animated: true) +// self.navigationController?.popViewController(animated: true) + } + } + +// if (size.width != self.view.frame.size.width) { +// // Reload TableView to update cell's constraints. +// // Ensuring no dequeued cells have old constraints. +// DispatchQueue.main.async { +// } +// } + } + + + // Action for back button tap + @objc func backButtonTapped() { + // Perform actions when the back button is tapped, such as dismissing the current view controller + setDeviceOrientation(orientation: .portrait) + // or + // dismiss(animated: true, completion: nil) + } + + override func viewWillAppear(_ animated: Bool) { + self.navigationController?.isNavigationBarHidden = true + } + + override func viewWillDisappear(_ animated: Bool) { +// self.dismissFullScreen(animated: true) + player.stop() + } + + override func jwplayer(_ player: JWPlayer, didPauseWithReason reason: JWPauseReason) { + super.jwplayer(player, didPauseWithReason: reason) + // Implement custom behavior + } + + // MARK: - JWPlayerDelegate + + // Player is ready + override func jwplayerIsReady(_ player: JWPlayer) { + super.jwplayerIsReady(player) + print("IsReady") + + } + + // Setup error + override func jwplayer(_ player: JWPlayer, failedWithSetupError code: UInt, message: String) { + super.jwplayer(player, failedWithSetupError: code, message: message) + + } + + // Error + override func jwplayer(_ player: JWPlayer, failedWithError code: UInt, message: String) { + super.jwplayer(player, failedWithError: code, message: message) + + } + + // Warning + override func jwplayer(_ player: JWPlayer, encounteredWarning code: UInt, message: String) { + super.jwplayer(player, encounteredWarning: code, message: message) + + } + + // Ad error + override func jwplayer(_ player: JWPlayer, encounteredAdError code: UInt, message: String) { + super.jwplayer(player, encounteredAdError: code, message: message) + + } + + // Ad warning + override func jwplayer(_ player: JWPlayer, encounteredAdWarning code: UInt, message: String) { + super.jwplayer(player, failedWithSetupError: code, message: message) + + } + + override func jwplayer(_ player: JWPlayer, isBufferingWithReason reason: JWBufferReason) { + player.play() + print("Reason ", reason) + } + +} + +// MARK: - Full Screen + +extension PlayerVC{ + + + func playerViewControllerWillGoFullScreen(_ controller: JWPlayerViewController) -> JWFullScreenViewController? { +// controller.shouldEnterFullScreen = false + controller.dismiss(animated: false) { + self.setDeviceOrientation(orientation: .portrait) + } + return nil + } + + func playerViewControllerDidGoFullScreen(_ controller: JWPlayerViewController) { + return + } + + func playerViewControllerWillDismissFullScreen(_ controller: JWPlayerViewController) { + controller.dismiss(animated: false) { + self.setDeviceOrientation(orientation: .portrait) + self.dismissTapped?() + } + } + + func playerViewControllerDidDismissFullScreen(_ controller: JWPlayerViewController) { + self.dismissFullScreen(animated: true) { + self.navigationController?.popViewController(animated: true) + } + } + +} + +// MARK: - JWPlayerViewController Delegate Funcs + +extension PlayerVC{ + + func playerViewController(_ controller: JWPlayerKit.JWPlayerViewController, controlBarVisibilityChanged isVisible: Bool, frame: CGRect) { +// print("CC visible",isVisible) + isVisible ? (backButton.isHidden = false) : (backButton.isHidden = true) + } + + func playerViewController(_ controller: JWPlayerKit.JWPlayerViewController, sizeChangedFrom oldSize: CGSize, to newSize: CGSize) { + + } + + func playerViewController(_ controller: JWPlayerKit.JWPlayerViewController, screenTappedAt position: CGPoint) { + + } + + func playerViewController(_ controller: JWPlayerKit.JWPlayerViewController, relatedMenuOpenedWithItems items: [JWPlayerKit.JWPlayerItem], withMethod method: JWPlayerKit.JWRelatedInteraction) { + print("Item ",items) + } + +// func playerViewController(_ controller: JWPlayerKit.JWPlayerViewController, relatedItemBeganPlaying item: JWPlayerKit.JWPlayerItem, atIndex index: Int, withMethod method: JWPlayerKit.JWRelatedMethod) { +// +// } + + func playerViewController(_ controller: JWPlayerViewController, relatedMenuClosedWithMethod method: JWRelatedInteraction){ + print("Close") + } +} + + + +extension UIViewController { + + func setDeviceOrientation(orientation: UIInterfaceOrientationMask) { + if #available(iOS 16.0, *) { + let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene + windowScene?.requestGeometryUpdate(.iOS(interfaceOrientations: orientation)) + } else { + UIDevice.current.setValue(orientation.toUIInterfaceOrientation.rawValue, forKey: "orientation") + } + } +} + +extension UIInterfaceOrientationMask { + var toUIInterfaceOrientation: UIInterfaceOrientation { + switch self { + case .portrait: + return UIInterfaceOrientation.portrait + case .portraitUpsideDown: + return UIInterfaceOrientation.portraitUpsideDown + case .landscapeRight: + return UIInterfaceOrientation.landscapeRight + case .landscapeLeft: + return UIInterfaceOrientation.landscapeLeft + default: + return UIInterfaceOrientation.unknown + } + } +} diff --git a/WOKA/Theme/Controller/ThemeOneVC.swift b/WOKA/Theme/Controller/ThemeOneVC.swift index 10efb05..82d1ede 100644 --- a/WOKA/Theme/Controller/ThemeOneVC.swift +++ b/WOKA/Theme/Controller/ThemeOneVC.swift @@ -44,7 +44,6 @@ class ThemeOneVC: UIViewController { super.viewDidLoad() vm.vc = self vm.initView() - } // Define a function to customize tab bar item icon size diff --git a/WOKA/Theme/Controller/ThemeTwoVC.swift b/WOKA/Theme/Controller/ThemeTwoVC.swift index 4855379..8eaf1e2 100644 --- a/WOKA/Theme/Controller/ThemeTwoVC.swift +++ b/WOKA/Theme/Controller/ThemeTwoVC.swift @@ -31,6 +31,10 @@ class ThemeTwoVC: UIViewController { } } + override func viewDidLayoutSubviews() { + vm.setData() + } + @IBAction func sideBarBtnTapped(_ sender: UIButton) { self.sideMenuController?.revealMenu() } diff --git a/WOKA/Theme/View/HomeExploreCell.swift b/WOKA/Theme/View/HomeExploreCell.swift index fb5aa01..a2865aa 100644 --- a/WOKA/Theme/View/HomeExploreCell.swift +++ b/WOKA/Theme/View/HomeExploreCell.swift @@ -11,16 +11,25 @@ class HomeExploreCell: UICollectionViewCell { @IBOutlet weak var cellBtn: UIImageView! @IBOutlet weak var cellLabel: LocalisedElementsLabel! + @IBOutlet weak var mainView: UIView! override func awakeFromNib() { super.awakeFromNib() - self.addTapGesture { - + self.addTapGesture { [weak self] in + guard let self else{return} + btnTap() } } + func btnTap(){ - + UIView.animate(withDuration: 0.1, animations: { + self.mainView.transform = CGAffineTransform(scaleX: 0.9, y: 0.9) + }) { _ in + UIView.animate(withDuration: 0.1) { + self.mainView.transform = .identity + } + } } func setData(data : Theme2Struct){ diff --git a/WOKA/Theme/View/HomeExploreCell.xib b/WOKA/Theme/View/HomeExploreCell.xib index 73bbe3a..77cbb86 100644 --- a/WOKA/Theme/View/HomeExploreCell.xib +++ b/WOKA/Theme/View/HomeExploreCell.xib @@ -61,6 +61,7 @@ + diff --git a/WOKA/Theme/ViewModel/ThemeOneVM.swift b/WOKA/Theme/ViewModel/ThemeOneVM.swift index 8e52746..7ecda3f 100644 --- a/WOKA/Theme/ViewModel/ThemeOneVM.swift +++ b/WOKA/Theme/ViewModel/ThemeOneVM.swift @@ -6,19 +6,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! func initView(){ AuthFunc.shareInstance.initTimePeriods() startInitialTimer() - - moveCloudView() moveLiveTVView() + + moveCloudView() addTapGestureToMovingView() handleTaps() @@ -28,6 +33,62 @@ class ThemeOneVM{ NotificationCenter.default.addObserver(self, selector: #selector(self.reloadTheme), name: NSNotification.Name(rawValue: K.NotificationCenterReloads.reloadTheme), object: nil) setData() + setupAvPlayer() + avPlayer.play() + avPlayer.isMuted = true +// do{ +// 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() +// // Initialize the JWPlayer controller +// player.player.configurePlayer(with: config) +// player.interfaceBehavior = .hidden +// // Add the player's view to the container view +// player.view.translatesAutoresizingMaskIntoConstraints = false +// vc.liveTvPlayer.addSubview(player.view) +// +// // Add constraints to make the player fill the container view +// NSLayoutConstraint.activate([ +// player.view.leadingAnchor.constraint(equalTo: vc.liveTvPlayer.leadingAnchor), +// player.view.trailingAnchor.constraint(equalTo: vc.liveTvPlayer.trailingAnchor), +// player.view.topAnchor.constraint(equalTo: vc.liveTvPlayer.topAnchor), +// player.view.bottomAnchor.constraint(equalTo: vc.liveTvPlayer.bottomAnchor) +// ]) +// +// player.player.play() +// }catch{ +// +// } + + } + + private 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) } func setData(){ @@ -53,7 +114,7 @@ class ThemeOneVM{ } 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/" + avatar) + vc.avatarImage.imageURL("https://wokaland.com/admin/storage/app/public/uploads/avtar/avatar2.png?d=1716889852") } } @@ -144,50 +205,65 @@ class ThemeOneVM{ // function which is triggered when handleTap is called @objc func handleTap(_ sender: UITapGestureRecognizer) { print("tapped") -// let vc = self.storyboard?.instantiateViewController(identifier: "ViewController") as! ViewController -// -// 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.videoStreamURL)!) -// .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 -// } -// catch { -// // Handle Error -// } -// vc.dismissTapped = self.tapped -// -// vc.modalPresentationStyle = .overFullScreen -// self.present(vc, animated: false) { -// self.stopLiveStream() -// vc.transitionToFullScreen(animated: true) { -// print("FullScreen") -// } -//// vc.setDeviceOrientation(orientation: .landscapeRight) -// } -//// self.navigationController?.pushViewController(vc, animated: true) -// } + 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 + } + catch { + // Handle Error + } + vc.dismissTapped = self.tapped + + vc.modalPresentationStyle = .overFullScreen + self.vc.present(vc, animated: false) { + self.stopLiveStream() + vc.transitionToFullScreen(animated: true) { + print("FullScreen") + } +// vc.setDeviceOrientation(orientation: .landscapeRight) + } +// self.navigationController?.pushViewController(vc, animated: true) + } } + + func tapped(){ + Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false) { _ in + self.startLiveStream() + } + print("Sadasd") + } + + func startLiveStream(){ + avPlayer.play() + } + + func stopLiveStream(){ + avPlayer.pause() + } // MARK: - Handle Time Change @objc func handleBackground(){ diff --git a/WOKA/Theme/ViewModel/ThemeTwoVM.swift b/WOKA/Theme/ViewModel/ThemeTwoVM.swift index 7fa4628..039e119 100644 --- a/WOKA/Theme/ViewModel/ThemeTwoVM.swift +++ b/WOKA/Theme/ViewModel/ThemeTwoVM.swift @@ -26,7 +26,6 @@ class ThemeTwoVM{ func initView(){ setupCell() - setData() NotificationCenter.default.addObserver(self, selector: #selector(self.reloadTheme), name: NSNotification.Name(rawValue: K.NotificationCenterReloads.reloadTheme), object: nil) } @@ -51,7 +50,7 @@ class ThemeTwoVM{ 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/" + avatar) + vc.avatarImage.imageURL("https://i.pinimg.com/280x280_RS/da/0b/bd/da0bbdb22d191272f32fa2c7c7c8e5c2.jpg", color: .white) } }