|
@@ -9,9 +9,9 @@ import UIKit
|
|
|
import FMDB
|
|
|
import NexilisLite
|
|
|
import Speech
|
|
|
+import QuickLook
|
|
|
|
|
|
-class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGestureRecognizerDelegate, UITextFieldDelegate {
|
|
|
-
|
|
|
+class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGestureRecognizerDelegate, UITextFieldDelegate, UICollectionViewDelegate, UICollectionViewDataSource, QLPreviewControllerDataSource {
|
|
|
var isChooser: ((String, String) -> ())?
|
|
|
|
|
|
var isAdmin: Bool = false
|
|
@@ -37,10 +37,30 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
|
|
|
let textViewSearch = UITextField()
|
|
|
let imageVoiceSb = UIImageView()
|
|
|
let imageNewChatSb = UIImageView()
|
|
|
+ let imageClearSearch = UIImageView()
|
|
|
+ @IBOutlet weak var viewToolbar: UIView!
|
|
|
+ @IBOutlet weak var heightToolbar: NSLayoutConstraint!
|
|
|
+ var viewCategorySearch: UIScrollView!
|
|
|
+ var leftTVSearch: NSLayoutConstraint!
|
|
|
+ var viewCatInTV: UIView!
|
|
|
+ var imageViewSearch: UIImageView!
|
|
|
+ var gridImage: UICollectionView!
|
|
|
+ var previewItem: NSURL?
|
|
|
+ var audioPlayer: AVAudioPlayer?
|
|
|
|
|
|
- override var preferredStatusBarStyle: UIStatusBarStyle {
|
|
|
- return self.traitCollection.userInterfaceStyle == .dark ? .default : .lightContent // Change this to .default for black text color
|
|
|
- }
|
|
|
+ let UNREAD_TAG = 10
|
|
|
+ let PHOTOS_TAG = 11
|
|
|
+ let DOCUMENTS_TAG = 12
|
|
|
+ let LINKS_TAG = 13
|
|
|
+ let VIDEOS_TAG = 14
|
|
|
+ let GIFS_TAG = 15
|
|
|
+ let AUDIOS_TAG = 16
|
|
|
+
|
|
|
+ var selectedTag = 0
|
|
|
+
|
|
|
+// override var preferredStatusBarStyle: UIStatusBarStyle {
|
|
|
+// return self.traitCollection.userInterfaceStyle == .dark ? .default : .lightContent // Change this to .default for black text color
|
|
|
+// }
|
|
|
|
|
|
lazy var searchController: UISearchController = {
|
|
|
var searchController = UISearchController(searchResultsController: nil)
|
|
@@ -91,7 +111,56 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
|
|
|
case 1:
|
|
|
fillteredData = self.groups.filter { $0.name.lowercased().contains(searchText.lowercased()) }
|
|
|
default:
|
|
|
- fillteredData = self.chats.filter { $0.name.lowercased().contains(searchText.lowercased()) || $0.messageText.lowercased().contains(searchText.lowercased()) }
|
|
|
+ if selectedTag == 0 {
|
|
|
+ fillteredData = self.chats.filter { $0.name.lowercased().contains(searchText.lowercased()) || $0.messageText.lowercased().contains(searchText.lowercased()) }
|
|
|
+ } else {
|
|
|
+ switch(selectedTag) {
|
|
|
+ case UNREAD_TAG :
|
|
|
+ fillteredData = self.chats.filter { $0.counter != "0" }
|
|
|
+ break
|
|
|
+ case PHOTOS_TAG, VIDEOS_TAG :
|
|
|
+ fillteredData = Chat.getData(isImage: selectedTag == PHOTOS_TAG, isVideo: selectedTag == VIDEOS_TAG)
|
|
|
+ if fillteredData.count > 0 {
|
|
|
+ if gridImage != nil && gridImage.isDescendant(of: self.view) {
|
|
|
+ gridImage.removeFromSuperview()
|
|
|
+ }
|
|
|
+ let width = self.view.frame.width / 3 - 2
|
|
|
+ let cellSize = CGSize(width:width, height:width)
|
|
|
+ let layout = UICollectionViewFlowLayout()
|
|
|
+ layout.scrollDirection = .vertical
|
|
|
+ layout.itemSize = cellSize
|
|
|
+ layout.sectionInset = UIEdgeInsets(top: 1, left: 1, bottom: 1, right: 1)
|
|
|
+ layout.minimumLineSpacing = 1.0
|
|
|
+ layout.minimumInteritemSpacing = 1.0
|
|
|
+
|
|
|
+ gridImage = UICollectionView(frame: .zero, collectionViewLayout: layout)
|
|
|
+ self.view.addSubview(gridImage)
|
|
|
+ gridImage.anchor(top: tableView.topAnchor, left: tableView.leftAnchor, bottom: tableView.bottomAnchor, right: tableView.rightAnchor)
|
|
|
+ gridImage.backgroundColor = .clear
|
|
|
+
|
|
|
+ gridImage.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "gridCell")
|
|
|
+
|
|
|
+ gridImage.delegate = self
|
|
|
+ gridImage.dataSource = self
|
|
|
+
|
|
|
+ tableView.isHidden = true
|
|
|
+ }
|
|
|
+ break
|
|
|
+ case DOCUMENTS_TAG :
|
|
|
+ fillteredData = Chat.getData(isDoc: true)
|
|
|
+ break
|
|
|
+ case GIFS_TAG :
|
|
|
+ break
|
|
|
+ case LINKS_TAG :
|
|
|
+ fillteredData = Chat.getData(isLink: true)
|
|
|
+ break
|
|
|
+ case AUDIOS_TAG :
|
|
|
+ fillteredData = Chat.getData(isAudio: true)
|
|
|
+ break
|
|
|
+ default:
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
tableView.reloadData()
|
|
@@ -141,7 +210,119 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
|
|
|
NotificationCenter.default.addObserver(self, selector: #selector(onReloadTab(notification:)), name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil)
|
|
|
NotificationCenter.default.addObserver(self, selector: #selector(onReloadTab(notification:)), name: NSNotification.Name(rawValue: "onTopic"), object: nil)
|
|
|
|
|
|
+ imageViewSearch = UIImageView(image: UIImage(named: self.traitCollection.userInterfaceStyle == .dark ? "nx_search_bar_dark" : "nx_search_bar", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!)
|
|
|
+ imageViewSearch.contentMode = .scaleToFill
|
|
|
+ viewToolbar.addSubview(imageViewSearch)
|
|
|
+ imageViewSearch.anchor(top: viewToolbar.topAnchor, left: viewToolbar.leftAnchor, right: viewToolbar.rightAnchor, paddingTop: 5, paddingLeft: 10, paddingRight: 10, height: 35)
|
|
|
+ imageViewSearch.isUserInteractionEnabled = true
|
|
|
+
|
|
|
+ viewCategorySearch = UIScrollView()
|
|
|
+ viewCategorySearch.showsHorizontalScrollIndicator = false
|
|
|
+ viewToolbar.addSubview(viewCategorySearch)
|
|
|
+ viewCategorySearch.anchor(top: imageViewSearch.bottomAnchor, left: viewToolbar.leftAnchor, right: viewToolbar.rightAnchor, paddingLeft: 10, paddingRight: 10, height: 40)
|
|
|
+ viewCategorySearch.isHidden = true
|
|
|
+
|
|
|
+ let groupViewCat = UIStackView()
|
|
|
+ viewCategorySearch.addSubview(groupViewCat)
|
|
|
+ groupViewCat.anchor(left: viewCategorySearch.leftAnchor, right: viewCategorySearch.rightAnchor, centerY: viewCategorySearch.centerYAnchor, height: 30)
|
|
|
+ groupViewCat.axis = .horizontal
|
|
|
+ groupViewCat.spacing = 10
|
|
|
+
|
|
|
+ for i in 0..<7 {
|
|
|
+ var widthView: CGFloat = 105
|
|
|
+ var iconCat = UIImage(systemName: "bubble.right")
|
|
|
+ var textCat = "Unread".localized()
|
|
|
+ var tag = UNREAD_TAG
|
|
|
+ if i == 1 {
|
|
|
+ widthView = 100
|
|
|
+ iconCat = UIImage(systemName: "photo")
|
|
|
+ textCat = "Photos".localized()
|
|
|
+ tag = PHOTOS_TAG
|
|
|
+ } else if i == 2 {
|
|
|
+ widthView = 130
|
|
|
+ iconCat = UIImage(systemName: "doc")
|
|
|
+ textCat = "Documents".localized()
|
|
|
+ tag = DOCUMENTS_TAG
|
|
|
+ } else if i == 3 {
|
|
|
+ widthView = 80
|
|
|
+ iconCat = UIImage(systemName: "link")
|
|
|
+ textCat = "Links".localized()
|
|
|
+ tag = LINKS_TAG
|
|
|
+ } else if i == 4 {
|
|
|
+ widthView = 100
|
|
|
+ iconCat = UIImage(systemName: "video")
|
|
|
+ textCat = "Videos".localized()
|
|
|
+ tag = VIDEOS_TAG
|
|
|
+ } else if i == 5 {
|
|
|
+ widthView = 80
|
|
|
+ iconCat = UIImage(systemName: "photo.on.rectangle")
|
|
|
+ textCat = "GIFs".localized()
|
|
|
+ tag = GIFS_TAG
|
|
|
+ } else if i == 6 {
|
|
|
+ widthView = 80
|
|
|
+ iconCat = UIImage(systemName: "music.note")
|
|
|
+ textCat = "Audio".localized()
|
|
|
+ tag = AUDIOS_TAG
|
|
|
+ }
|
|
|
+ let viewCat = UIView(frame: CGRect(x: 0, y: 0, width: widthView, height: 30))
|
|
|
+ groupViewCat.addArrangedSubview(viewCat)
|
|
|
+ viewCat.anchor(width: widthView, height: 30)
|
|
|
+ viewCat.layer.cornerRadius = 15
|
|
|
+ viewCat.layer.borderColor = UIColor.gray.cgColor
|
|
|
+ viewCat.layer.borderWidth = 0.5
|
|
|
+ viewCat.backgroundColor = .white
|
|
|
+ viewCat.isUserInteractionEnabled = true
|
|
|
+ viewCat.tag = tag
|
|
|
+ viewCat.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(onTapCategory(_:))))
|
|
|
+
|
|
|
+
|
|
|
+ let imageIcon = UIImageView()
|
|
|
+ imageIcon.image = iconCat
|
|
|
+ imageIcon.tintColor = .black
|
|
|
+ viewCat.addSubview(imageIcon)
|
|
|
+ imageIcon.anchor(left: viewCat.leftAnchor, paddingLeft: 10, centerY: viewCat.centerYAnchor)
|
|
|
+
|
|
|
+ let imageText = UILabel()
|
|
|
+ imageText.text = textCat
|
|
|
+ viewCat.addSubview(imageText)
|
|
|
+ imageText.anchor(left: imageIcon.rightAnchor, paddingLeft: 5, centerY: viewCat.centerYAnchor)
|
|
|
+ imageText.font = .systemFont(ofSize: 15)
|
|
|
+ }
|
|
|
+
|
|
|
+ let imageSetting = UIImageView(image: UIImage(named: "nx_setting_sb", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!)
|
|
|
+ imageSetting.contentMode = .scaleToFill
|
|
|
+ imageViewSearch.addSubview(imageSetting)
|
|
|
+ imageSetting.anchor(right: imageViewSearch.rightAnchor, paddingRight: 15, centerY: imageViewSearch.centerYAnchor, width: 20, height: 20)
|
|
|
+ imageSetting.isUserInteractionEnabled = true
|
|
|
+ imageSetting.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(settingTapped)))
|
|
|
+
|
|
|
+ imageVoiceSb.image = UIImage(named: "nx_mic", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!
|
|
|
+ imageVoiceSb.contentMode = .scaleAspectFit
|
|
|
+ imageViewSearch.addSubview(imageVoiceSb)
|
|
|
+ imageVoiceSb.anchor(right: imageSetting.leftAnchor, paddingRight: 10, centerY: imageViewSearch.centerYAnchor, width: 20, height: 20)
|
|
|
+ imageVoiceSb.isUserInteractionEnabled = true
|
|
|
+ imageVoiceSb.isHidden = true
|
|
|
+ imageVoiceSb.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(recordAudio)))
|
|
|
|
|
|
+ imageClearSearch.image = UIImage(systemName: "xmark")
|
|
|
+ imageClearSearch.contentMode = .scaleAspectFit
|
|
|
+ imageClearSearch.tintColor = .gray
|
|
|
+ imageViewSearch.addSubview(imageClearSearch)
|
|
|
+ imageClearSearch.anchor(right: imageVoiceSb.leftAnchor, paddingRight: 5, centerY: imageViewSearch.centerYAnchor, width: 20, height: 20)
|
|
|
+ imageClearSearch.isUserInteractionEnabled = true
|
|
|
+ imageClearSearch.isHidden = true
|
|
|
+ imageClearSearch.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(clearSearch)))
|
|
|
+
|
|
|
+ textViewSearch.placeholder = "Search...".localized()
|
|
|
+ textViewSearch.isUserInteractionEnabled = true
|
|
|
+ imageViewSearch.addSubview(textViewSearch)
|
|
|
+ textViewSearch.font = .systemFont(ofSize: 11)
|
|
|
+ textViewSearch.anchor(top: imageViewSearch.topAnchor, bottom: imageViewSearch.bottomAnchor, right: imageViewSearch.rightAnchor, paddingTop: 5, paddingBottom: 5, paddingRight: 90)
|
|
|
+ leftTVSearch = textViewSearch.leftAnchor.constraint(equalTo: imageViewSearch.leftAnchor, constant: 20.0)
|
|
|
+ NSLayoutConstraint.activate([
|
|
|
+ leftTVSearch
|
|
|
+ ])
|
|
|
+ textViewSearch.delegate = self
|
|
|
|
|
|
tableView.tableHeaderView = segment
|
|
|
tableView.tableFooterView = UIView()
|
|
@@ -199,6 +380,30 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ @objc func clearSearch(){
|
|
|
+ selectedTag = 0
|
|
|
+ if gridImage != nil && gridImage.isDescendant(of: self.view) {
|
|
|
+ gridImage.removeFromSuperview()
|
|
|
+ tableView.isHidden = false
|
|
|
+ }
|
|
|
+ textViewSearch.text = ""
|
|
|
+ imageClearSearch.isHidden = true
|
|
|
+ if !textViewSearch.isFirstResponder {
|
|
|
+ viewCategorySearch.isHidden = true
|
|
|
+ imageVoiceSb.isHidden = true
|
|
|
+ heightToolbar.constant = 45
|
|
|
+ filterContentForSearchText("")
|
|
|
+ } else if heightToolbar.constant == 45 {
|
|
|
+ viewCategorySearch.isHidden = false
|
|
|
+ heightToolbar.constant = 85
|
|
|
+ }
|
|
|
+
|
|
|
+ if leftTVSearch.constant != 20 {
|
|
|
+ viewCatInTV.removeFromSuperview()
|
|
|
+ leftTVSearch.constant = 20
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
func setupSpeech() {
|
|
|
|
|
|
self.speechRecognizer?.delegate = self
|
|
@@ -384,7 +589,7 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
|
|
|
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
|
|
|
navigationController?.navigationBar.shadowImage = UIImage()
|
|
|
navigationController?.navigationBar.isTranslucent = true
|
|
|
- navigationController?.setNavigationBarHidden(false, animated: false)
|
|
|
+ navigationController?.setNavigationBarHidden(true, animated: false)
|
|
|
navigationController?.navigationBar.tintColor = self.traitCollection.userInterfaceStyle == .dark ? .white : .black
|
|
|
navigationController?.navigationBar.overrideUserInterfaceStyle = self.traitCollection.userInterfaceStyle == .dark ? .dark : .light
|
|
|
navigationController?.navigationBar.barStyle = .default
|
|
@@ -398,47 +603,7 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
|
|
|
// tabBarController?.navigationItem.rightBarButtonItem = menuItem
|
|
|
// }
|
|
|
// tabBarController?.navigationItem.searchController = searchController
|
|
|
- let customView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: 30))
|
|
|
- customView.isUserInteractionEnabled = true
|
|
|
-
|
|
|
- let imageViewSearch = UIImageView(image: UIImage(named: self.traitCollection.userInterfaceStyle == .dark ? "nx_search_bar_dark" : "nx_search_bar", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!)
|
|
|
- imageViewSearch.contentMode = .scaleToFill
|
|
|
- customView.addSubview(imageViewSearch)
|
|
|
- imageViewSearch.anchor(top: customView.topAnchor, left: customView.leftAnchor, bottom: customView.bottomAnchor, right: customView.rightAnchor, height: 35)
|
|
|
- imageViewSearch.isUserInteractionEnabled = true
|
|
|
|
|
|
- let imageSetting = UIImageView(image: UIImage(named: "nx_setting_sb", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!)
|
|
|
- imageSetting.contentMode = .scaleToFill
|
|
|
- imageViewSearch.addSubview(imageSetting)
|
|
|
- imageSetting.anchor(right: customView.rightAnchor, paddingRight: 18, centerY: customView.centerYAnchor, width: 20, height: 20)
|
|
|
- imageSetting.isUserInteractionEnabled = true
|
|
|
- imageSetting.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(settingTapped)))
|
|
|
-
|
|
|
- imageVoiceSb.image = UIImage(named: "nx_mic", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!
|
|
|
- imageVoiceSb.contentMode = .scaleAspectFit
|
|
|
- imageViewSearch.addSubview(imageVoiceSb)
|
|
|
- imageVoiceSb.anchor(top: imageViewSearch.topAnchor, right: imageSetting.leftAnchor, paddingTop: 5, paddingRight: 15, width: 20, height: 20)
|
|
|
- imageVoiceSb.isUserInteractionEnabled = true
|
|
|
- imageVoiceSb.isHidden = true
|
|
|
- imageVoiceSb.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(recordAudio)))
|
|
|
-
|
|
|
- imageNewChatSb.image = UIImage(systemName: "square.and.pencil")!
|
|
|
- imageNewChatSb.tintColor = .nxColor
|
|
|
- imageNewChatSb.contentMode = .scaleAspectFit
|
|
|
- imageViewSearch.addSubview(imageNewChatSb)
|
|
|
- imageNewChatSb.anchor(top: imageViewSearch.topAnchor, right: imageVoiceSb.leftAnchor, paddingTop: 5, paddingRight: 15, width: 20, height: 20)
|
|
|
- imageNewChatSb.isUserInteractionEnabled = true
|
|
|
- imageNewChatSb.isHidden = true
|
|
|
- imageNewChatSb.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(startConversation)))
|
|
|
-
|
|
|
- textViewSearch.placeholder = "Search...".localized()
|
|
|
- textViewSearch.isUserInteractionEnabled = true
|
|
|
- imageViewSearch.addSubview(textViewSearch)
|
|
|
- textViewSearch.font = .systemFont(ofSize: 11)
|
|
|
- textViewSearch.anchor(top: imageViewSearch.topAnchor, left: imageViewSearch.leftAnchor, bottom: imageViewSearch.bottomAnchor, right: imageViewSearch.rightAnchor, paddingTop: 5, paddingLeft: 20, paddingBottom: 5, paddingRight: 120)
|
|
|
- textViewSearch.delegate = self
|
|
|
-
|
|
|
- tabBarController?.navigationItem.titleView = customView
|
|
|
let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
|
|
|
speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: lang ?? "en"))
|
|
|
backgroundImage.backgroundColor = self.traitCollection.userInterfaceStyle == .dark ? .black : .white
|
|
@@ -496,9 +661,54 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
|
|
|
|
|
|
func textFieldDidChangeSelection(_ textField: UITextField) {
|
|
|
if textField == textViewSearch {
|
|
|
- let textSerch = textField.text ?? ""
|
|
|
+ var textSerch = textField.text ?? ""
|
|
|
+ textSerch = textSerch.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
|
+ if !textSerch.isEmpty && imageClearSearch.isHidden {
|
|
|
+ imageClearSearch.isHidden = false
|
|
|
+ } else if textSerch.isEmpty && !imageClearSearch.isHidden {
|
|
|
+ imageClearSearch.isHidden = true
|
|
|
+ }
|
|
|
+ if textField.text?.count == 1 && leftTVSearch.constant != 20 {
|
|
|
+ selectedTag = 0
|
|
|
+ if gridImage != nil && gridImage.isDescendant(of: self.view) {
|
|
|
+ gridImage.removeFromSuperview()
|
|
|
+ tableView.isHidden = false
|
|
|
+ }
|
|
|
+ textField.text = ""
|
|
|
+ viewCatInTV.removeFromSuperview()
|
|
|
+ leftTVSearch.constant = 20
|
|
|
+ }
|
|
|
filterContentForSearchText(textSerch)
|
|
|
}
|
|
|
+ if viewCatInTV != nil && viewCatInTV.isDescendant(of: imageViewSearch) {
|
|
|
+ viewCategorySearch.isHidden = true
|
|
|
+ heightToolbar.constant = 45
|
|
|
+ } else if (viewCatInTV == nil || !viewCatInTV.isDescendant(of: imageViewSearch)) && segment.selectedSegmentIndex == 0 {
|
|
|
+ viewCategorySearch.isHidden = false
|
|
|
+ heightToolbar.constant = 85
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func textFieldDidBeginEditing(_ textField: UITextField) {
|
|
|
+ if textField == textViewSearch {
|
|
|
+ if segment.selectedSegmentIndex == 0 && (viewCatInTV == nil || !viewCatInTV.isDescendant(of: imageViewSearch)) {
|
|
|
+ heightToolbar.constant = 85
|
|
|
+ viewCategorySearch.isHidden = false
|
|
|
+ imageVoiceSb.isHidden = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func textFieldDidEndEditing(_ textField: UITextField) {
|
|
|
+ if textField == textViewSearch {
|
|
|
+ if let text = textField.text {
|
|
|
+ if text.isEmpty {
|
|
|
+ viewCategorySearch.isHidden = true
|
|
|
+ imageVoiceSb.isHidden = true
|
|
|
+ heightToolbar.constant = 45
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
override func viewWillDisappear(_ animated: Bool) {
|
|
@@ -514,8 +724,77 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
|
|
|
}
|
|
|
|
|
|
@objc func settingTapped() {
|
|
|
- imageVoiceSb.isHidden = !imageVoiceSb.isHidden
|
|
|
- imageNewChatSb.isHidden = !imageNewChatSb.isHidden
|
|
|
+// imageVoiceSb.isHidden = !imageVoiceSb.isHidden
|
|
|
+// imageNewChatSb.isHidden = !imageNewChatSb.isHidden
|
|
|
+ startConversation()
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func onTapCategory(_ sender: UITapGestureRecognizer) {
|
|
|
+ if let tappedView = sender.view {
|
|
|
+ if viewCatInTV != nil && viewCatInTV.isDescendant(of: imageViewSearch) {
|
|
|
+ viewCatInTV.removeFromSuperview()
|
|
|
+ }
|
|
|
+ var width1: CGFloat = 67
|
|
|
+ var width2: CGFloat = 80
|
|
|
+ viewCatInTV = UIView()
|
|
|
+ imageViewSearch.addSubview(viewCatInTV)
|
|
|
+
|
|
|
+ var iconCat = UIImage(systemName: "bubble.right")
|
|
|
+ var textCat = "Unread".localized()
|
|
|
+
|
|
|
+ selectedTag = tappedView.tag
|
|
|
+
|
|
|
+ if tappedView.tag == PHOTOS_TAG {
|
|
|
+ iconCat = UIImage(systemName: "photo")
|
|
|
+ textCat = "Photos".localized()
|
|
|
+ } else if tappedView.tag == DOCUMENTS_TAG {
|
|
|
+ iconCat = UIImage(systemName: "doc")
|
|
|
+ textCat = "Documents".localized()
|
|
|
+ width1 = 97
|
|
|
+ width2 = 110
|
|
|
+ } else if tappedView.tag == LINKS_TAG {
|
|
|
+ iconCat = UIImage(systemName: "link")
|
|
|
+ textCat = "Links".localized()
|
|
|
+ width1 = 57
|
|
|
+ width2 = 70
|
|
|
+ } else if tappedView.tag == VIDEOS_TAG {
|
|
|
+ iconCat = UIImage(systemName: "video")
|
|
|
+ textCat = "Videos".localized()
|
|
|
+ } else if tappedView.tag == GIFS_TAG {
|
|
|
+ iconCat = UIImage(systemName: "photo.on.rectangle")
|
|
|
+ textCat = "GIFs".localized()
|
|
|
+ width1 = 52
|
|
|
+ width2 = 65
|
|
|
+ } else if tappedView.tag == AUDIOS_TAG {
|
|
|
+ iconCat = UIImage(systemName: "music.note")
|
|
|
+ textCat = "Audio".localized()
|
|
|
+ width1 = 62
|
|
|
+ width2 = 75
|
|
|
+ }
|
|
|
+
|
|
|
+ viewCatInTV.frame = CGRect(x: 0, y: 0, width: width1, height: 30)
|
|
|
+ viewCatInTV.anchor(left: imageViewSearch.leftAnchor, paddingLeft: 20, centerY: imageViewSearch.centerYAnchor, width: width1, height: 25)
|
|
|
+ viewCatInTV.backgroundColor = .white
|
|
|
+ viewCatInTV.layer.cornerRadius = 8
|
|
|
+ viewCatInTV.clipsToBounds = true
|
|
|
+ viewCatInTV.backgroundColor = .black
|
|
|
+
|
|
|
+ textViewSearch.text = "~ "
|
|
|
+ leftTVSearch.constant = width2
|
|
|
+
|
|
|
+ let imageIcon = UIImageView()
|
|
|
+ imageIcon.image = iconCat
|
|
|
+ imageIcon.tintColor = .white
|
|
|
+ viewCatInTV.addSubview(imageIcon)
|
|
|
+ imageIcon.anchor(left: viewCatInTV.leftAnchor, paddingLeft: 5, centerY: viewCatInTV.centerYAnchor, width: 12, height: 12)
|
|
|
+
|
|
|
+ let imageText = UILabel()
|
|
|
+ imageText.text = textCat
|
|
|
+ viewCatInTV.addSubview(imageText)
|
|
|
+ imageText.textColor = .white
|
|
|
+ imageText.anchor(left: imageIcon.rightAnchor, paddingLeft: 3, centerY: viewCatInTV.centerYAnchor, height: 12)
|
|
|
+ imageText.font = .systemFont(ofSize: 12)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@objc func onReloadTab(notification: NSNotification) {
|
|
@@ -544,8 +823,9 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
|
|
|
let chatData = dataMessage.mBodies
|
|
|
if chatData[CoreMessage_TMessageKey.IS_CALL_CENTER] == nil || chatData[CoreMessage_TMessageKey.IS_CALL_CENTER] == "0" {
|
|
|
var indexChat: Int?
|
|
|
- if chatData[CoreMessage_TMessageKey.MESSAGE_SCOPE_ID] == "3" && chatData[CoreMessage_TMessageKey.F_PIN] != User.getMyPin() {
|
|
|
- indexChat = chats.firstIndex(where: { $0.fpin == chatData[CoreMessage_TMessageKey.F_PIN] })
|
|
|
+ if chatData[CoreMessage_TMessageKey.MESSAGE_SCOPE_ID] == "3" {
|
|
|
+ let f_pin = chatData[CoreMessage_TMessageKey.F_PIN] != User.getMyPin() ? chatData[CoreMessage_TMessageKey.F_PIN] : chatData[CoreMessage_TMessageKey.L_PIN]
|
|
|
+ indexChat = chats.firstIndex(where: { $0.pin == f_pin })
|
|
|
} else if chatData[CoreMessage_TMessageKey.MESSAGE_SCOPE_ID] == "4" && chatData[CoreMessage_TMessageKey.F_PIN] != User.getMyPin() {
|
|
|
indexChat = chats.firstIndex(where: { (chatData[CoreMessage_TMessageKey.CHAT_ID] ?? "").isEmpty ? $0.pin == chatData[CoreMessage_TMessageKey.L_PIN] : $0.pin == chatData[CoreMessage_TMessageKey.CHAT_ID] })
|
|
|
}
|
|
@@ -1130,6 +1410,294 @@ extension SecondTabViewController: UITableViewDelegate, UITableViewDataSource {
|
|
|
}
|
|
|
data = chats[indexPath.row]
|
|
|
}
|
|
|
+ if selectedTag != UNREAD_TAG && selectedTag != 0 {
|
|
|
+ let title = UILabel()
|
|
|
+ let subtitle = UILabel()
|
|
|
+ title.textColor = .black
|
|
|
+ subtitle.textColor = .gray
|
|
|
+ title.font = .systemFont(ofSize: 16, weight: .medium)
|
|
|
+ subtitle.font = .systemFont(ofSize: 14)
|
|
|
+ content.addSubview(title)
|
|
|
+ content.addSubview(subtitle)
|
|
|
+ title.anchor(top: content.topAnchor, left: content.leftAnchor, paddingTop: 10, paddingLeft: 20)
|
|
|
+ subtitle.anchor(top: title.bottomAnchor, left: content.leftAnchor, right: content.rightAnchor, paddingLeft: 20, paddingRight: 20)
|
|
|
+ subtitle.numberOfLines = 2
|
|
|
+ title.text = data.name
|
|
|
+
|
|
|
+ let imageArrowRight = UIImageView(image: UIImage(systemName: "chevron.right"))
|
|
|
+ content.addSubview(imageArrowRight)
|
|
|
+ imageArrowRight.tintColor = .gray
|
|
|
+ imageArrowRight.anchor(top: content.topAnchor, right: content.rightAnchor, paddingTop: 10, paddingRight: 20)
|
|
|
+
|
|
|
+ let timeView = UILabel()
|
|
|
+ content.addSubview(timeView)
|
|
|
+ timeView.anchor(top: content.topAnchor, right: imageArrowRight.leftAnchor, paddingTop: 10, paddingRight: 20)
|
|
|
+ timeView.textColor = .gray
|
|
|
+ timeView.font = UIFont.systemFont(ofSize: 16)
|
|
|
+
|
|
|
+ let date = Date(milliseconds: Int64(data.serverDate)!)
|
|
|
+ let calendar = Calendar.current
|
|
|
+
|
|
|
+ if (calendar.isDateInToday(date)) {
|
|
|
+ let formatter = DateFormatter()
|
|
|
+ formatter.dateFormat = "HH:mm"
|
|
|
+ formatter.locale = NSLocale(localeIdentifier: "id") as Locale?
|
|
|
+ timeView.text = formatter.string(from: date as Date)
|
|
|
+ } else {
|
|
|
+ let startOfNow = calendar.startOfDay(for: Date())
|
|
|
+ let startOfTimeStamp = calendar.startOfDay(for: date)
|
|
|
+ let components = calendar.dateComponents([.day], from: startOfNow, to: startOfTimeStamp)
|
|
|
+ let day = -(components.day!)
|
|
|
+ if day == 1 {
|
|
|
+ timeView.text = "Yesterday".localized()
|
|
|
+ } else {
|
|
|
+ if day < 7 {
|
|
|
+ let formatter = DateFormatter()
|
|
|
+ formatter.dateFormat = "EEEE"
|
|
|
+ let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
|
|
|
+ if lang == "id" {
|
|
|
+ formatter.locale = NSLocale(localeIdentifier: "id") as Locale?
|
|
|
+ }
|
|
|
+ timeView.text = formatter.string(from: date)
|
|
|
+ } else {
|
|
|
+ let formatter = DateFormatter()
|
|
|
+ formatter.dateFormat = "M/dd/yy"
|
|
|
+ formatter.locale = NSLocale(localeIdentifier: "id") as Locale?
|
|
|
+ let stringFormat = formatter.string(from: date as Date)
|
|
|
+ timeView.text = stringFormat
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ cell.separatorInset = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 0)
|
|
|
+
|
|
|
+ let container = UIView()
|
|
|
+ content.addSubview(container)
|
|
|
+ container.anchor(top: subtitle.bottomAnchor, left: content.leftAnchor, right: content.rightAnchor, paddingTop: 5, paddingLeft: 20, paddingRight: 20, height: selectedTag == LINKS_TAG ? 75 : 60)
|
|
|
+ container.backgroundColor = .lightGray.withAlphaComponent(0.3)
|
|
|
+ container.layer.cornerRadius = 15
|
|
|
+ container.clipsToBounds = true
|
|
|
+ container.isUserInteractionEnabled = true
|
|
|
+
|
|
|
+ if selectedTag == DOCUMENTS_TAG {
|
|
|
+ subtitle.text = "📄 " + "Document".localized()
|
|
|
+
|
|
|
+ let imageFile = UIImageView(image: UIImage(systemName: "doc.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 45)))
|
|
|
+ container.addSubview(imageFile)
|
|
|
+ imageFile.tintColor = .black
|
|
|
+ imageFile.anchor(top: container.topAnchor, left: container.leftAnchor, bottom: container.bottomAnchor, paddingTop: 5, paddingLeft: 5, paddingBottom: 5, width: 45)
|
|
|
+
|
|
|
+ let nameFile = UILabel()
|
|
|
+ container.addSubview(nameFile)
|
|
|
+ nameFile.font = .systemFont(ofSize: 12, weight: .medium)
|
|
|
+ nameFile.textColor = .black
|
|
|
+ nameFile.numberOfLines = 2
|
|
|
+ nameFile.anchor(top: container.topAnchor, left: imageFile.rightAnchor, right: container.rightAnchor, paddingTop: 5, paddingLeft: 10, paddingRight: 5)
|
|
|
+ nameFile.text = data.messageText.components(separatedBy: "|")[0]
|
|
|
+
|
|
|
+ let fileSub = UILabel()
|
|
|
+ let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
|
|
|
+ let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
|
|
|
+ let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
|
|
|
+ let arrExtFile = (data.messageText.components(separatedBy: "|")[0]).split(separator: ".")
|
|
|
+ let finalExtFile = arrExtFile[arrExtFile.count - 1]
|
|
|
+ if let dirPath = paths.first {
|
|
|
+ let fileURL = URL(fileURLWithPath: dirPath).appendingPathComponent(data.file)
|
|
|
+ if FileManager.default.fileExists(atPath: fileURL.path) {
|
|
|
+ if let dataFile = try? Data(contentsOf: fileURL) {
|
|
|
+ var sizeOfFile = Int(dataFile.count / 1000000)
|
|
|
+ if (sizeOfFile < 1) {
|
|
|
+ sizeOfFile = Int(dataFile.count / 1000)
|
|
|
+ if (finalExtFile.count > 4) {
|
|
|
+ fileSub.text = "\(sizeOfFile) kB \u{2022} TXT"
|
|
|
+ }else {
|
|
|
+ fileSub.text = "\(sizeOfFile) kB \u{2022} \(finalExtFile.uppercased())"
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (finalExtFile.count > 4) {
|
|
|
+ fileSub.text = "\(sizeOfFile) MB \u{2022} TXT"
|
|
|
+ }else {
|
|
|
+ fileSub.text = "\(sizeOfFile) MB \u{2022} \(finalExtFile.uppercased())"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ fileSub.text = ""
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if FileEncryption.shared.isSecureExists(filename: data.file) {
|
|
|
+ if let dataFile = try? FileEncryption.shared.readSecure(filename: data.file) {
|
|
|
+ var sizeOfFile = Int(dataFile.count / 1000000)
|
|
|
+ if (sizeOfFile < 1) {
|
|
|
+ sizeOfFile = Int(dataFile.count / 1000)
|
|
|
+ if (finalExtFile.count > 4) {
|
|
|
+ fileSub.text = "\(sizeOfFile) kB \u{2022} TXT"
|
|
|
+ }else {
|
|
|
+ fileSub.text = "\(sizeOfFile) kB \u{2022} \(finalExtFile.uppercased())"
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (finalExtFile.count > 4) {
|
|
|
+ fileSub.text = "\(sizeOfFile) MB \u{2022} TXT"
|
|
|
+ }else {
|
|
|
+ fileSub.text = "\(sizeOfFile) MB \u{2022} \(finalExtFile.uppercased())"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ fileSub.text = ""
|
|
|
+ }
|
|
|
+ }
|
|
|
+ container.addSubview(fileSub)
|
|
|
+ fileSub.anchor(top: nameFile.bottomAnchor, left: imageFile.rightAnchor, bottom: container.bottomAnchor, paddingLeft: 10, paddingBottom: 5)
|
|
|
+ fileSub.font = .systemFont(ofSize: 10)
|
|
|
+ fileSub.textColor = .gray
|
|
|
+ let objectTap = ObjectGesture(target: self, action: #selector(onContSearch(_:)))
|
|
|
+ objectTap.file_id = data.file
|
|
|
+ container.addGestureRecognizer(objectTap)
|
|
|
+ }
|
|
|
+ } else if selectedTag == LINKS_TAG {
|
|
|
+ var text = ""
|
|
|
+ var txtData = data.messageText
|
|
|
+ if txtData.contains("■"){
|
|
|
+ txtData = txtData.components(separatedBy: "■")[0]
|
|
|
+ txtData = txtData.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
|
+ }
|
|
|
+ let listTextSplitBreak = txtData.components(separatedBy: "\n")
|
|
|
+ let indexFirstLinkSplitBreak = listTextSplitBreak.firstIndex(where: { $0.contains("www.") || $0.contains("http://") || $0.contains("https://") })
|
|
|
+ if indexFirstLinkSplitBreak != nil {
|
|
|
+ let listTextSplitSpace = listTextSplitBreak[indexFirstLinkSplitBreak!].components(separatedBy: " ")
|
|
|
+ let indexFirstLinkSplitSpace = listTextSplitSpace.firstIndex(where: { ($0.starts(with: "www.") && $0.components(separatedBy: ".").count > 2) || ($0.starts(with: "http://") && $0.components(separatedBy: ".").count > 1) || ($0.starts(with: "https://") && $0.components(separatedBy: ".").count > 1) })
|
|
|
+ if indexFirstLinkSplitSpace != nil {
|
|
|
+ text = listTextSplitSpace[indexFirstLinkSplitSpace!]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ var dataURL = ""
|
|
|
+ subtitle.text = txtData
|
|
|
+ Database.shared.database?.inTransaction({ (fmdb, rollback) in
|
|
|
+ do {
|
|
|
+ if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select data_link from LINK_PREVIEW where link='\(text)'"), cursor.next() {
|
|
|
+ if let data = cursor.string(forColumnIndex: 0) {
|
|
|
+ dataURL = data
|
|
|
+ }
|
|
|
+ cursor.close()
|
|
|
+ }
|
|
|
+ } catch {
|
|
|
+ rollback.pointee = true
|
|
|
+ print("Access database error: \(error.localizedDescription)")
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ var title = ""
|
|
|
+ var description = ""
|
|
|
+ var imageUrl: String?
|
|
|
+ var link = text
|
|
|
+
|
|
|
+ let objectTap = ObjectGesture(target: self, action: #selector(onContSearch(_:)))
|
|
|
+ objectTap.message_id = link
|
|
|
+ container.addGestureRecognizer(objectTap)
|
|
|
+
|
|
|
+ let imagePreview = UIImageView()
|
|
|
+ container.addSubview(imagePreview)
|
|
|
+ imagePreview.translatesAutoresizingMaskIntoConstraints = false
|
|
|
+ imagePreview.leadingAnchor.constraint(equalTo: container.leadingAnchor).isActive = true
|
|
|
+ imagePreview.bottomAnchor.constraint(equalTo: container.bottomAnchor).isActive = true
|
|
|
+ imagePreview.topAnchor.constraint(equalTo: container.topAnchor).isActive = true
|
|
|
+ imagePreview.widthAnchor.constraint(equalToConstant: 80.0).isActive = true
|
|
|
+
|
|
|
+ imagePreview.image = UIImage(systemName: "link", withConfiguration: UIImage.SymbolConfiguration(pointSize: 45))
|
|
|
+ imagePreview.contentMode = .center
|
|
|
+ imagePreview.clipsToBounds = true
|
|
|
+ imagePreview.tintColor = .black
|
|
|
+ imagePreview.backgroundColor = .gray.withAlphaComponent(0.3)
|
|
|
+
|
|
|
+ let titlePreview = UILabel()
|
|
|
+ container.addSubview(titlePreview)
|
|
|
+ titlePreview.translatesAutoresizingMaskIntoConstraints = false
|
|
|
+ titlePreview.leadingAnchor.constraint(equalTo: imagePreview.trailingAnchor, constant: 5.0).isActive = true
|
|
|
+ titlePreview.topAnchor.constraint(equalTo: container.topAnchor, constant: 10.0).isActive = true
|
|
|
+ titlePreview.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -5.0).isActive = true
|
|
|
+ titlePreview.text = title
|
|
|
+ titlePreview.font = UIFont.systemFont(ofSize: 14.0, weight: .bold)
|
|
|
+ titlePreview.textColor = self.traitCollection.userInterfaceStyle == .dark ? .white : .black
|
|
|
+
|
|
|
+ let descPreview = UILabel()
|
|
|
+ container.addSubview(descPreview)
|
|
|
+ descPreview.translatesAutoresizingMaskIntoConstraints = false
|
|
|
+ descPreview.leadingAnchor.constraint(equalTo: imagePreview.trailingAnchor, constant: 5.0).isActive = true
|
|
|
+ descPreview.topAnchor.constraint(equalTo: titlePreview.bottomAnchor).isActive = true
|
|
|
+ descPreview.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -5.0).isActive = true
|
|
|
+ descPreview.text = description
|
|
|
+ descPreview.font = UIFont.systemFont(ofSize: 12.0)
|
|
|
+ descPreview.textColor = .gray
|
|
|
+ descPreview.numberOfLines = 1
|
|
|
+
|
|
|
+ let linkPreview = UILabel()
|
|
|
+ container.addSubview(linkPreview)
|
|
|
+ linkPreview.translatesAutoresizingMaskIntoConstraints = false
|
|
|
+ linkPreview.leadingAnchor.constraint(equalTo: imagePreview.trailingAnchor, constant: 5.0).isActive = true
|
|
|
+ linkPreview.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -5.0).isActive = true
|
|
|
+ linkPreview.font = UIFont.systemFont(ofSize: 10.0)
|
|
|
+ linkPreview.textColor = .gray
|
|
|
+ linkPreview.numberOfLines = 1
|
|
|
+
|
|
|
+ if !dataURL.isEmpty {
|
|
|
+ if let data = try! JSONSerialization.jsonObject(with: dataURL.data(using: String.Encoding.utf8)!, options: []) as? [String: Any] {
|
|
|
+ title = data["title"] as! String
|
|
|
+ description = data["description"] as! String
|
|
|
+ imageUrl = data["imageUrl"] as? String
|
|
|
+ link = data["link"] as! String
|
|
|
+
|
|
|
+ if imageUrl != nil {
|
|
|
+ imagePreview.loadImageAsync(with: imageUrl)
|
|
|
+ imagePreview.contentMode = .scaleToFill
|
|
|
+ imagePreview.clipsToBounds = true
|
|
|
+ }
|
|
|
+
|
|
|
+ titlePreview.text = title
|
|
|
+ descPreview.text = description
|
|
|
+ linkPreview.text = link
|
|
|
+ linkPreview.topAnchor.constraint(equalTo: descPreview.bottomAnchor, constant: 8.0).isActive = true
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ linkPreview.text = link
|
|
|
+ linkPreview.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true
|
|
|
+ }
|
|
|
+ } else if selectedTag == AUDIOS_TAG {
|
|
|
+ subtitle.text = "♫ " + "Audio".localized()
|
|
|
+
|
|
|
+ let imageAudio = UIImageView()
|
|
|
+ imageAudio.image = UIImage(systemName: "music.note", withConfiguration: UIImage.SymbolConfiguration(pointSize: 35))
|
|
|
+ container.addSubview(imageAudio)
|
|
|
+ imageAudio.anchor(left: container.leftAnchor, paddingLeft: 10, centerY: container.centerYAnchor)
|
|
|
+ imageAudio.tintColor = .black
|
|
|
+
|
|
|
+ let nameAudio = UILabel()
|
|
|
+ container.addSubview(nameAudio)
|
|
|
+ nameAudio.anchor(left: imageAudio.rightAnchor, right: container.rightAnchor, paddingLeft: 10, paddingRight: 10, centerY: container.centerYAnchor)
|
|
|
+ nameAudio.numberOfLines = 2
|
|
|
+ nameAudio.text = data.messageText.components(separatedBy: "|")[0]
|
|
|
+ nameAudio.font = .systemFont(ofSize: 16, weight: .medium)
|
|
|
+
|
|
|
+ let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
|
|
|
+ let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
|
|
|
+ let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
|
|
|
+ if let dirPath = paths.first {
|
|
|
+ let audioURL = URL(fileURLWithPath: dirPath).appendingPathComponent(data.audio)
|
|
|
+ if !FileManager.default.fileExists(atPath: audioURL.path) && !FileEncryption.shared.isSecureExists(filename: data.audio) {
|
|
|
+ Download().startHTTP(forKey: data.audio) { (name, progress) in
|
|
|
+ guard progress == 100 else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ tableView.reloadRows(at: [indexPath], with: .none)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ let objectTap = ObjectGesture(target: self, action: #selector(onContSearch(_:)))
|
|
|
+ objectTap.audio_id = data.audio
|
|
|
+ container.addGestureRecognizer(objectTap)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return cell
|
|
|
+ }
|
|
|
+
|
|
|
let imageView = UIImageView()
|
|
|
content.addSubview(imageView)
|
|
|
imageView.translatesAutoresizingMaskIntoConstraints = false
|
|
@@ -1378,7 +1946,105 @@ extension SecondTabViewController: UITableViewDelegate, UITableViewDataSource {
|
|
|
return cell
|
|
|
}
|
|
|
|
|
|
+ @objc func onContSearch(_ sender: ObjectGesture) {
|
|
|
+ if selectedTag == PHOTOS_TAG {
|
|
|
+
|
|
|
+ } else if selectedTag == VIDEOS_TAG {
|
|
|
+
|
|
|
+ } else if selectedTag == DOCUMENTS_TAG {
|
|
|
+ let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
|
|
|
+ let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
|
|
|
+ let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
|
|
|
+ if let dirPath = paths.first {
|
|
|
+ let fileURL = URL(fileURLWithPath: dirPath).appendingPathComponent(sender.file_id)
|
|
|
+ if FileManager.default.fileExists(atPath: fileURL.path) {
|
|
|
+ self.previewItem = fileURL as NSURL
|
|
|
+ let previewController = QLPreviewController()
|
|
|
+ let rightBarButton = UIBarButtonItem()
|
|
|
+ previewController.navigationItem.rightBarButtonItem = rightBarButton
|
|
|
+ previewController.dataSource = self
|
|
|
+ previewController.modalPresentationStyle = .custom
|
|
|
+
|
|
|
+ self.present(previewController, animated: true)
|
|
|
+ } else if FileEncryption.shared.isSecureExists(filename: sender.file_id) {
|
|
|
+ do {
|
|
|
+ if let docData = try FileEncryption.shared.readSecure(filename: sender.file_id) {
|
|
|
+
|
|
|
+ let cachesDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
|
|
|
+ let tempPath = cachesDirectory.appendingPathComponent(sender.file_id)
|
|
|
+ try docData.write(to: tempPath)
|
|
|
+ self.previewItem = tempPath as NSURL
|
|
|
+ let previewController = QLPreviewController()
|
|
|
+ let rightBarButton = UIBarButtonItem()
|
|
|
+ previewController.navigationItem.rightBarButtonItem = rightBarButton
|
|
|
+ previewController.dataSource = self
|
|
|
+ previewController.modalPresentationStyle = .custom
|
|
|
+ self.present(previewController,animated: true)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if selectedTag == LINKS_TAG {
|
|
|
+ var stringURl = sender.message_id
|
|
|
+ if stringURl.lowercased().starts(with: "www.") {
|
|
|
+ stringURl = "https://" + stringURl.replacingOccurrences(of: "www.", with: "")
|
|
|
+ }
|
|
|
+ guard let url = URL(string: stringURl) else { return }
|
|
|
+ UIApplication.shared.open(url)
|
|
|
+ } else if selectedTag == AUDIOS_TAG {
|
|
|
+ let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
|
|
|
+ let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
|
|
|
+ let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
|
|
|
+ if let dirPath = paths.first {
|
|
|
+ let audioURL = URL(fileURLWithPath: dirPath).appendingPathComponent(sender.audio_id)
|
|
|
+ if FileManager.default.fileExists(atPath: audioURL.path) {
|
|
|
+ do {
|
|
|
+ if audioPlayer == nil || audioPlayer?.url != audioURL {
|
|
|
+ audioPlayer = try AVAudioPlayer(contentsOf: audioURL)
|
|
|
+ audioPlayer?.prepareToPlay()
|
|
|
+ audioPlayer?.play()
|
|
|
+ } else if audioPlayer!.isPlaying {
|
|
|
+ audioPlayer?.pause()
|
|
|
+ } else {
|
|
|
+ audioPlayer?.play()
|
|
|
+ }
|
|
|
+ } catch {
|
|
|
+
|
|
|
+ }
|
|
|
+ } else if FileEncryption.shared.isSecureExists(filename: sender.audio_id) {
|
|
|
+ do {
|
|
|
+ if let audioData = try FileEncryption.shared.readSecure(filename: sender.audio_id) {
|
|
|
+ let cachesDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
|
|
|
+ let tempPath = cachesDirectory.appendingPathComponent(sender.audio_id)
|
|
|
+ try audioData.write(to: tempPath)
|
|
|
+ if audioPlayer == nil || audioPlayer?.url != tempPath {
|
|
|
+ audioPlayer = try AVAudioPlayer(contentsOf: tempPath)
|
|
|
+ audioPlayer?.prepareToPlay()
|
|
|
+ audioPlayer?.play()
|
|
|
+ } else if audioPlayer!.isPlaying {
|
|
|
+ audioPlayer?.pause()
|
|
|
+ } else {
|
|
|
+ audioPlayer?.play()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
|
|
|
+ if fillteredData.count > 0 && selectedTag != UNREAD_TAG && selectedTag != 0 {
|
|
|
+ if selectedTag == LINKS_TAG {
|
|
|
+ return 160.0
|
|
|
+ }
|
|
|
+ return 130.0
|
|
|
+ }
|
|
|
return 75.0
|
|
|
}
|
|
|
|
|
@@ -1397,6 +2063,141 @@ extension SecondTabViewController: UITableViewDelegate, UITableViewDataSource {
|
|
|
return status
|
|
|
}
|
|
|
|
|
|
+ func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
|
|
+ return fillteredData.count
|
|
|
+ }
|
|
|
+
|
|
|
+ func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
|
|
+ let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "gridCell", for: indexPath)
|
|
|
+ if cell.contentView.subviews.count > 0 {
|
|
|
+ cell.contentView.subviews.forEach { $0.removeFromSuperview() }
|
|
|
+ }
|
|
|
+ let data = fillteredData[indexPath.row] as! Chat
|
|
|
+ let thumb = data.thumb
|
|
|
+ let imgData = data.image
|
|
|
+ let vidData = data.video
|
|
|
+ let image = UIImageView()
|
|
|
+ cell.contentView.addSubview(image)
|
|
|
+ let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
|
|
|
+ let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
|
|
|
+ let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
|
|
|
+ if let dirPath = paths.first {
|
|
|
+ let thumbURL = URL(fileURLWithPath: dirPath).appendingPathComponent(thumb)
|
|
|
+ let imageT : UIImage? = {
|
|
|
+ if let img = Nexilis.imageCache.object(forKey: thumb as NSString) {
|
|
|
+ return img
|
|
|
+ }
|
|
|
+ else if let img = UIImage(contentsOfFile: thumbURL.path)?.resize(target: CGSize(width: 500, height: 500)) {
|
|
|
+ Nexilis.imageCache.setObject(img, forKey: thumb as NSString)
|
|
|
+ return img
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ }()
|
|
|
+ if imageT != nil {
|
|
|
+ image.image = imageT
|
|
|
+ }
|
|
|
+
|
|
|
+ let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent(imgData)
|
|
|
+ let videoURL = URL(fileURLWithPath: dirPath).appendingPathComponent(vidData)
|
|
|
+ if (!FileManager.default.fileExists(atPath: imageURL.path) && !FileEncryption.shared.isSecureExists(filename: imageURL.lastPathComponent)) || (!FileManager.default.fileExists(atPath: videoURL.path) && !FileEncryption.shared.isSecureExists(filename: videoURL.lastPathComponent)) {
|
|
|
+ let blurEffect = UIBlurEffect(style: UIBlurEffect.Style.light)
|
|
|
+ let blurEffectView = UIVisualEffectView(effect: blurEffect)
|
|
|
+ blurEffectView.frame = CGRect(x: 0, y: 0, width: image.frame.size.width, height: image.frame.size.height)
|
|
|
+ blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
|
+ image.addSubview(blurEffectView)
|
|
|
+ if !imgData.isEmpty {
|
|
|
+ let imageDownload = UIImageView(image: UIImage(systemName: "arrow.down.circle.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 50, weight: .bold, scale: .default)))
|
|
|
+ image.addSubview(imageDownload)
|
|
|
+ imageDownload.tintColor = .black.withAlphaComponent(0.3)
|
|
|
+ imageDownload.translatesAutoresizingMaskIntoConstraints = false
|
|
|
+ imageDownload.centerXAnchor.constraint(equalTo: image.centerXAnchor).isActive = true
|
|
|
+ imageDownload.centerYAnchor.constraint(equalTo: image.centerYAnchor).isActive = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!vidData.isEmpty) {
|
|
|
+ let imagePlay = UIImageView(image: UIImage(systemName: "play.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .bold, scale: .default))?.imageWithInsets(insets: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))?.withTintColor(.white))
|
|
|
+ imagePlay.circle()
|
|
|
+ image.addSubview(imagePlay)
|
|
|
+ imagePlay.backgroundColor = .black.withAlphaComponent(0.3)
|
|
|
+ imagePlay.translatesAutoresizingMaskIntoConstraints = false
|
|
|
+ imagePlay.centerXAnchor.constraint(equalTo: image.centerXAnchor).isActive = true
|
|
|
+ imagePlay.centerYAnchor.constraint(equalTo: image.centerYAnchor).isActive = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ image.contentMode = .scaleAspectFill
|
|
|
+ image.clipsToBounds = true
|
|
|
+ image.anchor(top: cell.contentView.topAnchor, left: cell.contentView.leftAnchor, bottom: cell.contentView.bottomAnchor, right: cell.contentView.rightAnchor)
|
|
|
+ return cell
|
|
|
+ }
|
|
|
+
|
|
|
+ func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
|
|
+ let data = fillteredData[indexPath.row] as! Chat
|
|
|
+ let imgData = data.image
|
|
|
+ let vidData = data.video
|
|
|
+ let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
|
|
|
+ let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
|
|
|
+ let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
|
|
|
+ if let dirPath = paths.first {
|
|
|
+ if selectedTag == PHOTOS_TAG {
|
|
|
+ let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent(imgData)
|
|
|
+ if FileManager.default.fileExists(atPath: imageURL.path) {
|
|
|
+ let image = UIImage(contentsOfFile: imageURL.path) ?? UIImage()
|
|
|
+ APIS.openImageNexilis(image: image)
|
|
|
+ } else if FileEncryption.shared.isSecureExists(filename: imgData) {
|
|
|
+ do {
|
|
|
+ let data = try FileEncryption.shared.readSecure(filename: imgData)
|
|
|
+ let image = UIImage(data: data!) ?? UIImage()
|
|
|
+ APIS.openImageNexilis(image: image)
|
|
|
+ }
|
|
|
+ catch {
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ Download().startHTTP(forKey: imgData) { (name, progress) in
|
|
|
+ guard progress == 100 else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ DispatchQueue.main.async {
|
|
|
+ collectionView.reloadItems(at: [indexPath])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ let videoURL = URL(fileURLWithPath: dirPath).appendingPathComponent(vidData)
|
|
|
+ if FileManager.default.fileExists(atPath: videoURL.path) {
|
|
|
+ APIS.openVideoNexilis(videoURL: videoURL)
|
|
|
+ } else if FileEncryption.shared.isSecureExists(filename: vidData) {
|
|
|
+ do {
|
|
|
+ if let secureData = try FileEncryption.shared.readSecure(filename: vidData) {
|
|
|
+ let cachesDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
|
|
|
+ let tempPath = cachesDirectory.appendingPathComponent(vidData)
|
|
|
+ try secureData.write(to: tempPath)
|
|
|
+ APIS.openVideoNexilis(videoURL: tempPath)
|
|
|
+ }
|
|
|
+ } catch {
|
|
|
+
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ Download().startHTTP(forKey: vidData) { (name, progress) in
|
|
|
+ guard progress == 100 else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ DispatchQueue.main.async {
|
|
|
+ collectionView.reloadItems(at: [indexPath])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
|
|
|
+ return self.previewItem != nil ? 1 : 0
|
|
|
+ }
|
|
|
+
|
|
|
+ func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> any QLPreviewItem {
|
|
|
+ return self.previewItem!
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
|