import UIKit
//
class HomeDashboardViewController: BaseViewController, HomeViewModelDelegate
{
func notificationsCountDidChange(count: Int) {
checkNotification(count: count);
}
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var homeLbl: UILabel!
@IBOutlet weak var searchBtn: UIButton!
@IBOutlet weak var navBarImageView: UIImageView!
@IBOutlet weak var nearbyProgramsCollectionView: UICollectionView!
@IBOutlet weak var popularProgramsCollectionView: UICollectionView!
@IBOutlet weak var servicesCollectionView: UICollectionView!
@IBOutlet weak var stretchesCollectionView: UICollectionView!
@IBOutlet weak var storiesCollectionView: UICollectionView!
@IBOutlet weak var notification: UIButton!
var homeViewModel = HomeViewModel()
override func viewDidLoad() {
super.viewDidLoad()
homeViewModel.delegate = self
searchBtn.layer.cornerRadius = 6
homeViewModel.saveDeviceTokenForNotification()
homeViewModel.currentLocationDelegate = self
scrollView.delegate = self
self.navigationController?.navigationBar.isHidden = true
//self.setupRefreshControl()
self.registerCellsForCollectionView()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if persistentData.shared.index == 2 {
persistentData.shared.index = 0
self.tabBarController?.selectedIndex = 1
}
}
override func viewWillAppear(_ animated: Bool) {
//storiesCollectionView.reloadData()
callApisForData()
self.setupRefreshControl()
}
@IBAction func searchBtnAction(_ sender: Any) {
tabBarController?.selectedIndex = 2
}
@IBAction func nearbySeeAllAction(_ sender: Any) {
let nearbyProgramsVC = self.storyboard!.instantiateViewController(withIdentifier: "NearbyProgramsViewController") as! NearbyProgramsViewController
// homeViewModel.setProgramList(programs: homeViewModel.nearbyPrograms, programListingViewModel: nearbyProgramsVC.programListingViewModel)
nearbyProgramsVC.programListingViewModel.currentLocation = homeViewModel.currentLocation
self.navigationController?.pushViewController(nearbyProgramsVC, animated: true)
}
@IBAction func popularSeeAllAction(_ sender: Any) {
AppModule().onShowProgramListingViewController(fromVC: .fromPopularPrograms, searchVal: nil, currentLocation: homeViewModel.currentLocation, status: nil)
}
@IBAction func serviceSeeAllAction(_ sender: Any) {
let serviceListingVC = self.storyboard!.instantiateViewController(withIdentifier: "ServiceListingViewController") as! ServiceListingViewController
serviceListingVC.viewModel.preferredServices = self.homeViewModel.preferredServices
serviceListingVC.viewModel.otherServices = self.homeViewModel.otherServices
serviceListingVC.viewModel.currentLocation = self.homeViewModel.currentLocation
self.navigationController?.pushViewController(serviceListingVC, animated: true)
}
@IBAction func stretchSeeAllAction(_ sender: Any) {
let stretchListingVC = self.storyboard!.instantiateViewController(withIdentifier: "StretchesListingViewController") as! StretchesListingViewController
// stretchListingVC.listingViewModel.stretches = self.homeViewModel.stretches
stretchListingVC.listingViewModel.currentLocation = self.homeViewModel.currentLocation
self.navigationController?.pushViewController(stretchListingVC, animated: true)
}
@IBAction func didTapNotifications(_ sender: UIButton)
{
AppModule().onShowNotificationViewController()
}
}
// MARK: - private methods
extension HomeDashboardViewController
{
fileprivate func setupRefreshControl()
{
scrollView.refreshControl = UIRefreshControl()
scrollView.refreshControl?.tintColor = .white
scrollView.refreshControl?.addTarget(self, action: #selector(refreshData), for: .valueChanged)
}
@objc func refreshData() {
callApisForData()
}
fileprivate func registerCellsForCollectionView()
{
nearbyProgramsCollectionView.register(UINib(nibName: "ProgramCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "ProgramCell")
popularProgramsCollectionView.register(UINib(nibName: "ProgramCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "ProgramCell")
storiesCollectionView.register(UINib(nibName: "FitnessStoryCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "FitnessStoryCell")
[nearbyProgramsCollectionView,popularProgramsCollectionView,servicesCollectionView,stretchesCollectionView,storiesCollectionView].forEach {
$0?.registerReusableCell(NodataCollectionViewCell.self)
setProgramsCollectionView(collectionView: $0!)
}
if scrollView.contentOffset.y < 0 {
homeLbl.font = homeLbl.font.withSize(26)
} else if scrollView.contentOffset.y > 80 {
homeLbl.font = homeLbl.font.withSize(18)
}
}
func setProgramsCollectionView(collectionView:UICollectionView) {
collectionView.backgroundColor = .clear
collectionView.delegate = self
collectionView.dataSource = self
}
}
// MARK: - UICollectionViewDataSource methods
extension HomeDashboardViewController:UICollectionViewDataSource
{
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
switch collectionView {
case nearbyProgramsCollectionView:
let count = homeViewModel.nearbyPrograms.count > 3 ? 3 : (homeViewModel.nearbyPrograms.isEmpty ? 1 : homeViewModel.nearbyPrograms.count)
return count
case popularProgramsCollectionView:
let count = homeViewModel.popularPrograms.count > 3 ? 3 : (homeViewModel.popularPrograms.isEmpty ? 1 : homeViewModel.popularPrograms.count)
return count
case servicesCollectionView:
let count = homeViewModel.allServices.count > 8 ? 8 : (homeViewModel.allServices.isEmpty ? 1 : homeViewModel.allServices.count)
return count
case stretchesCollectionView:
let count = homeViewModel.stretches.count > 5 ? 5 : (homeViewModel.stretches.isEmpty ? 1 : homeViewModel.stretches.count)
return count
case storiesCollectionView:
// let count = homeViewModel.stories.isEmpty ? 1 : homeViewModel.stories.count
let count = homeViewModel.stories.count + 1
return count
default:
return 0
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
switch collectionView {
case nearbyProgramsCollectionView, popularProgramsCollectionView:
if collectionView == nearbyProgramsCollectionView && homeViewModel.nearbyPrograms.isEmpty {
let cell = collectionView.dequeueReusableCell(indexPath: indexPath) as NodataCollectionViewCell
cell.configureEmptyCell(model: NoItemModel.init(title: "No Nearby programs found"))
return cell
}
if collectionView == popularProgramsCollectionView && homeViewModel.popularPrograms.isEmpty {
let cell = collectionView.dequeueReusableCell(indexPath: indexPath) as NodataCollectionViewCell
cell.configureEmptyCell(model: NoItemModel.init(title: "No Popular programs found"))
return cell
}
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ProgramCell", for: indexPath) as! ProgramCollectionViewCell
cell.contentView.layer.cornerRadius = 6
cell.contentView.layer.borderWidth = 1.0
cell.contentView.layer.borderColor = UIColor.clear.cgColor
cell.contentView.layer.masksToBounds = true;
cell.backgroundColor = .clear
cell.layer.cornerRadius = 6
cell.layer.shadowColor = UIColor.black.cgColor
cell.layer.shadowOffset = CGSize(width: 0, height: 3.0)
cell.layer.shadowRadius = 2.0
cell.layer.shadowOpacity = 0.1
cell.layer.masksToBounds = false
let data = collectionView == popularProgramsCollectionView ? homeViewModel.popularPrograms : homeViewModel.nearbyPrograms
let program = data[indexPath.row]["program"] as! ProgramDetails
let professional = data[indexPath.row]["professional"] as! PFUser
cell.setCell(bannerImage: program.bannerImage, title: program.title!, service: (program.service!.title!).uppercased(), profileImage: professional.profilePic, name: professional.firstName! + " " + professional.lastName!, distance: "")
cell.bannerImageView.setImage(from: URL(string: program.bannerImageUrl!)!)
cell.profileImageView.image = nil
if professional.profilePicUrl != nil {
cell.profileImageView.setImage(from: URL(string: professional.profilePicUrl!)!)
}
cell.professionalAction = {
AppModule().onShowProfileDashboardViewController(userId: professional.userId!, isSelf: false)
}
return cell
case servicesCollectionView:
guard collectionView == servicesCollectionView,!homeViewModel.allServices.isEmpty else {
let cell = collectionView.dequeueReusableCell(indexPath: indexPath) as NodataCollectionViewCell
cell.configureEmptyCell(model: NoItemModel.init(title: "No services found"))
return cell
}
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ServiceCollectionViewCell", for: indexPath) as! ServicesCollectionViewCell
cell.setCell(image: homeViewModel.allServices[indexPath.row].image, title: homeViewModel.allServices[indexPath.row].title!)
cell.thumbnailImageView.setImage(from: URL(string: homeViewModel.allServices[indexPath.row].imageUrl ?? "https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.istockphoto.com%2Fphotos%2Fplaceholder-image&psig=AOvVaw3TryFVtuyNX_qfo1BcEQpI&ust=1652188928517000&source=images&cd=vfe&ved=0CAwQjRxqFwoTCMCurMTB0vcCFQAAAAAdAAAAABAD")!)
return cell
case stretchesCollectionView:
guard collectionView == stretchesCollectionView,!homeViewModel.stretches.isEmpty else {
let cell = collectionView.dequeueReusableCell(indexPath: indexPath) as NodataCollectionViewCell
cell.configureEmptyCell(model: NoItemModel.init(title: "No mobility videos available"))
return cell
}
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "StretchesCollectionViewCell", for: indexPath) as! StretchesCollectionViewCell
cell.setCell(image: homeViewModel.stretches[indexPath.row].previewImage, title: homeViewModel.stretches[indexPath.row].title!, duration: homeViewModel.splitDuration(duration: homeViewModel.stretches[indexPath.row].duration ?? 0))
if let imageURL = homeViewModel.stretches[indexPath.row].previewImageUrl, let picUrl = URL.init(string: imageURL){
cell.previewImageView.setImage(from: picUrl)
}else{
cell.previewImageView.image = UIImage(named: "CreateMobility")
}
return cell
case storiesCollectionView:
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FitnessStoryCell", for: indexPath) as! FitnessStoryCollectionViewCell
// if homeViewModel.stories.isEmpty {
// cell.noStoryCell()
// } else {
// homeViewModel.stories[indexPath.row].imageUrl != nil ? cell.thumbnailImageView.setImage(from: homeViewModel.stories[indexPath.row].imageUrl!) : cell.thumbnailImageView.setImage(from: homeViewModel.stories[indexPath.row].previewUrl!)
// cell.setData(name: (homeViewModel.stories[indexPath.row].user?.name)!, seen: (homeViewModel.stories[indexPath.row].seen))
// }
if indexPath.row == 0 {
cell.addStoryCell(name: "Add your story")
} else {
let row = indexPath.row - 1
homeViewModel.stories[row].imageUrl != nil ? cell.thumbnailImageView.setImage(from: homeViewModel.stories[row].imageUrl!) : cell.thumbnailImageView.setImage(from: homeViewModel.stories[row].previewUrl!)
cell.setData(name: (homeViewModel.stories[row].user?.name)!, seen: (homeViewModel.stories[row].seen))
}
return cell
default:
return UICollectionViewCell()
}
}
}
// MARK: - UICollectionViewDelegate methods
extension HomeDashboardViewController:UICollectionViewDelegate
{
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
switch collectionView {
case nearbyProgramsCollectionView:
guard !homeViewModel.nearbyPrograms.isEmpty else
{
return
}
let program = homeViewModel.nearbyPrograms[indexPath.row]["program"] as! ProgramDetails
self.presentProgramDetailsVC(id: program.id!, checkBackAction: nil)
case popularProgramsCollectionView:
guard !homeViewModel.popularPrograms.isEmpty else
{
return
}
let program = homeViewModel.popularPrograms[indexPath.row]["program"] as! ProgramDetails
self.presentProgramDetailsVC(id: program.id!, checkBackAction: nil)
case servicesCollectionView:
guard !homeViewModel.allServices.isEmpty else
{
return
}
// let serviceBasedProgramsVC = self.storyboard!.instantiateViewController(withIdentifier: "ServiceBasedProgramsViewController") as! ServiceBasedProgramsViewController
// serviceBasedProgramsVC.programListingViewModel.serviceSelected = homeViewModel.allServices[indexPath.row]
// self.navigationController?.pushViewController(serviceBasedProgramsVC, animated: true)
AppModule().onShowServiceBasedProgramsViewController(serviceSelected: homeViewModel.allServices[indexPath.row])
case stretchesCollectionView:
guard !homeViewModel.stretches.isEmpty else
{
return
}
presentVideoPlayer(url: homeViewModel.stretches[indexPath.row].videoUrl!)
case storiesCollectionView:
// if !homeViewModel.stories.isEmpty {
// presentFitnessStoriesVC(stories: homeViewModel.stories, selectedIndex: indexPath.row, isSelf: false, fromVC: .Home, storyDataDelegate: self)
// }
if indexPath.row == 0 {
AppModule().onShowCreateStoryViewController()
} else {
presentFitnessStoriesVC(stories: homeViewModel.stories, selectedIndex: indexPath.row - 1, isSelf: false, fromVC: .Home, storyDataDelegate: self)
}
default:
let program = homeViewModel.nearbyPrograms[indexPath.row]["program"] as! ProgramDetails
self.presentProgramDetailsVC(id: program.id!, checkBackAction: nil)
}
}
}
// MARK: - UICollectionViewDelegateFlowLayout methods
extension HomeDashboardViewController:UICollectionViewDelegateFlowLayout
{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
switch collectionView {
case nearbyProgramsCollectionView, popularProgramsCollectionView:
if collectionView == nearbyProgramsCollectionView && homeViewModel.nearbyPrograms.isEmpty {
return CGSize(width: 200, height: nearbyProgramsCollectionView.bounds.height)
}
if collectionView == popularProgramsCollectionView && homeViewModel.nearbyPrograms.isEmpty
{
return CGSize(width: 200, height: popularProgramsCollectionView.bounds.height)
}
let size = CGSize(width: 200, height: nearbyProgramsCollectionView.bounds.height - 20)
return size
case servicesCollectionView:
guard !homeViewModel.stretches.isEmpty else
{
return CGSize(width: 70, height: servicesCollectionView.bounds.height)
}
let size = CGSize(width: 70, height: nearbyProgramsCollectionView.bounds.height - 20)
return size
case stretchesCollectionView:
guard !homeViewModel.stretches.isEmpty else
{
return CGSize(width: 178, height: storiesCollectionView.bounds.height-40)
}
let size = CGSize(width: 178, height: nearbyProgramsCollectionView.bounds.height)
return size
case storiesCollectionView:
let size = CGSize(width: 70, height: nearbyProgramsCollectionView.bounds.height)
return size
default:
return CGSize()
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: 20, height: 0)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 20
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize
{
switch collectionView {
case nearbyProgramsCollectionView, popularProgramsCollectionView, stretchesCollectionView:
return CGSize(width: 30, height: 0)
case servicesCollectionView:
return CGSize(width: (homeViewModel.allServices.count * 5), height: 0)
case storiesCollectionView:
return CGSize(width: (homeViewModel.stories.count * 10), height: 0)
default:
return CGSize(width: 10, height: 0)
}
}
}
// MARK: - Scrollview delegate methods
extension HomeDashboardViewController:UIScrollViewDelegate
{
func scrollViewDidScroll(_ scrollView: UIScrollView) {
searchBtn.alpha = 1 - scrollView.contentOffset.y/50
if (26 - scrollView.contentOffset.y/10) > 18 && (26 - scrollView.contentOffset.y/10) < 26 {
homeLbl.font = homeLbl.font.withSize(26 - scrollView.contentOffset.y/10)
}
if scrollView.contentOffset.y < 0 {
homeLbl.font = homeLbl.font.withSize(26)
} else if scrollView.contentOffset.y > 80 {
homeLbl.font = homeLbl.font.withSize(18)
}
}
}
// MARK: - CurrentLocationDelegate methods
extension HomeDashboardViewController:CurrentLocationDelegate
{
func currentLocationUpdate(success: Bool, errorTitle: String?, errorMessage: String?)
{
if !success
{
self.scrollView.refreshControl?.endRefreshing()
self.scrollView.setContentOffset(CGPoint(x: 0, y: 0), animated: true)
// self.alert.presentAlertWithTitleAndMessage(title: errorTitle!, message: errorMessage! + " The location you entered while signing up will be used.", controller: self)
// self.alert.presentAlertWithTitleAndActions(actions: [{
//
// }], buttonTitles: ["OK"], controller: self, message: errorMessage! + " The location you entered while signing up will be used.", title: errorTitle!)
}
}
}
// MARK: - API Call methods
extension HomeDashboardViewController
{
func callApisForData()
{
self.scrollView.refreshControl?.endRefreshing()
self.showActivity()
homeViewModel.getLocation()
homeViewModel.getData(onSuccess: {
DispatchQueue.main.async {
self.hideActivity()
// self.scrollView.refreshControl?.endRefreshing()
self.popularProgramsCollectionView.reloadData()
self.nearbyProgramsCollectionView.reloadData()
self.servicesCollectionView.reloadData()
self.stretchesCollectionView.reloadData()
self.storiesCollectionView.reloadData()
}
}) { (error) in
DispatchQueue.main.async {
self.hideActivity()
}
}
}
func checkNotification(count: Int){
if count >= 1{
let notificationBadge = UIImage(named: "notificationBadge")
self.notification.setImage(notificationBadge, for: .normal)
}
else{
let noNotifications = UIImage(named: "noNotifications")
self.notification.setImage(noNotifications, for: .normal)
}
}
}
extension HomeDashboardViewController: StoryDataDelegate {
func setStories(stories: [FitnessStory]) {
self.homeViewModel.stories = stories
}
}