ListGroupImages.swift 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. //
  2. // ListGroupImages.swift
  3. // DigiXLite
  4. //
  5. // Created by Akhmad Al Qindi Irsyam on 28/07/23.
  6. //
  7. import UIKit
  8. import Popover
  9. class ListGroupImages: UIViewController, UITableViewDataSource, UITableViewDelegate {
  10. var listGroupingImages: [ImageGrouping]!
  11. var imageTapped: Int!
  12. var titleName: String!
  13. let tableViewImages = UITableView()
  14. var isInitiator = false
  15. var forwardSession = false
  16. var deleteSession = false
  17. var tableViewPopOver = UITableView()
  18. var popover: Popover!
  19. var startYVisible: CGFloat!
  20. var endYVisible: CGFloat!
  21. var indexSelected = 0
  22. var updateEditor: (([ImageGrouping], [String: Any?], Bool) -> ())?
  23. var isSelectAll = false
  24. var viewMultipleSelect = UIView()
  25. var constraintBottomViewMultipleSelect: NSLayoutConstraint!
  26. let centeredTitleView = CenteredTitleSubtitleView(frame: CGRect(x: 0, y: 0, width: 200, height: 44))
  27. override func viewDidLoad() {
  28. super.viewDidLoad()
  29. view.backgroundColor = .white
  30. centeredTitleView.titleLabel.text = titleName
  31. centeredTitleView.subtitleLabel.text = String(listGroupingImages.count) + " " + "images".localized()
  32. navigationItem.titleView = centeredTitleView
  33. let selectButton = UIBarButtonItem(title: "Select".localized(), style: .plain, target: self, action: #selector(selectAction))
  34. selectButton.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], for: .normal)
  35. navigationItem.rightBarButtonItem = selectButton
  36. tableViewImages.register(UITableViewCell.self, forCellReuseIdentifier: "cellGrupingImages")
  37. tableViewImages.dataSource = self
  38. tableViewImages.delegate = self
  39. tableViewImages.separatorStyle = .none
  40. self.view.addSubview(tableViewImages)
  41. tableViewImages.anchor(top: self.view.safeAreaLayoutGuide.topAnchor, left: self.view.safeAreaLayoutGuide.leftAnchor, bottom: self.view.safeAreaLayoutGuide.bottomAnchor, right: self.view.safeAreaLayoutGuide.rightAnchor)
  42. DispatchQueue.main.async {[self] in
  43. tableViewImages.scrollToRow(at: IndexPath(row: imageTapped, section: 0), at: .top, animated: false)
  44. }
  45. let center: NotificationCenter = NotificationCenter.default
  46. center.addObserver(self, selector: #selector(onStatusChat(notification:)), name: NSNotification.Name(rawValue: DigiX.listenerStatusChat), object: nil)
  47. self.view.addSubview(viewMultipleSelect)
  48. viewMultipleSelect.backgroundColor = .white.withAlphaComponent(0.9)
  49. viewMultipleSelect.anchor(left: self.view.safeAreaLayoutGuide.leftAnchor, right: self.view.safeAreaLayoutGuide.rightAnchor, height: 50)
  50. constraintBottomViewMultipleSelect = viewMultipleSelect.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: 50)
  51. constraintBottomViewMultipleSelect.isActive = true
  52. }
  53. @objc func onStatusChat(notification: NSNotification) {
  54. DispatchQueue.main.async { [self] in
  55. let data:[AnyHashable : Any] = notification.userInfo!
  56. if let dataMessage = data["message"] as? TMessage {
  57. var messageId = dataMessage.getBody(key: CoreMessage_TMessageKey.MESSAGE_ID)
  58. messageId = messageId.contains("-2") ? String(messageId.split(separator: ",")[1]) : messageId
  59. if let idx = listGroupingImages.firstIndex(where: { $0.messageId == messageId }) {
  60. listGroupingImages[idx].status = dataMessage.getBody(key: CoreMessage_TMessageKey.STATUS)
  61. listGroupingImages[idx].dataMessage["status"] = dataMessage.getBody(key: CoreMessage_TMessageKey.STATUS)
  62. tableViewImages.reloadRows(at: [IndexPath(row: idx, section: 0)], with: .none)
  63. }
  64. }
  65. }
  66. }
  67. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  68. if tableView == tableViewPopOver {
  69. return 5
  70. }
  71. return listGroupingImages.count
  72. }
  73. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  74. if tableView == tableViewPopOver {
  75. let cell = tableView.dequeueReusableCell(withIdentifier: "cellPopOver", for: indexPath as IndexPath)
  76. var content = cell.defaultContentConfiguration()
  77. content.textProperties.font = UIFont.systemFont(ofSize: 14)
  78. content.imageProperties.tintColor = .black
  79. switch indexPath.row {
  80. case 0:
  81. if listGroupingImages[indexSelected].dataMessage["is_stared"] as! String == "1" {
  82. content.image = UIImage(systemName: "star.slash.fill")
  83. content.text = "Unstar".localized()
  84. } else {
  85. content.image = UIImage(systemName: "star.fill")
  86. content.text = "Star".localized()
  87. }
  88. case 1:
  89. content.image = UIImage(systemName: "arrowshape.turn.up.left.fill")
  90. content.text = "Reply".localized()
  91. case 2:
  92. content.image = UIImage(systemName: "arrowshape.turn.up.right.fill")
  93. content.text = "Forward".localized()
  94. case 3:
  95. content.image = UIImage(systemName: "info.circle.fill")
  96. content.text = "Info".localized()
  97. default:
  98. content.image = UIImage(systemName: "trash.fill")
  99. content.text = "Delete".localized()
  100. }
  101. cell.contentConfiguration = content
  102. return cell
  103. }
  104. let cell = tableView.dequeueReusableCell(withIdentifier: "cellGrupingImages", for: indexPath as IndexPath)
  105. cell.contentView.subviews.forEach({ $0.removeFromSuperview() })
  106. cell.backgroundColor = .clear
  107. cell.selectionStyle = .none
  108. let containerImages = UIImageView()
  109. containerImages.contentMode = .scaleAspectFit
  110. cell.contentView.addSubview(containerImages)
  111. containerImages.anchor(top: cell.contentView.topAnchor, left: cell.contentView.leftAnchor, right: cell.contentView.rightAnchor, height: ListGroupImages.getImageSize(image: listGroupingImages[indexPath.row].thumbId, screenWidth: UIScreen.main.bounds.width, screenHeight: UIScreen.main.bounds.height)!.height)
  112. if !forwardSession && !deleteSession {
  113. let longPressRecognizer = LongPressImageVIew(target: self, action: #selector(handleLongPress(_:)))
  114. longPressRecognizer.imageView = containerImages
  115. longPressRecognizer.index = indexPath.row
  116. containerImages.isUserInteractionEnabled = true
  117. containerImages.addGestureRecognizer(longPressRecognizer)
  118. }
  119. let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
  120. let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
  121. let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
  122. if let dirPath = paths.first {
  123. let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent(listGroupingImages[indexPath.row].imageId)
  124. let image = UIImage(contentsOfFile: imageURL.path)
  125. if image == nil {
  126. let thumbURL = URL(fileURLWithPath: dirPath).appendingPathComponent(listGroupingImages[indexPath.row].thumbId)
  127. let image = UIImage(contentsOfFile: thumbURL.path)
  128. containerImages.image = image
  129. } else {
  130. containerImages.image = image
  131. }
  132. if !FileManager.default.fileExists(atPath: imageURL.path) {
  133. let blurEffect = UIBlurEffect(style: UIBlurEffect.Style.light)
  134. let blurEffectView = UIVisualEffectView(effect: blurEffect)
  135. blurEffectView.frame = CGRect(x: 0, y: 0, width: containerImages.frame.size.width, height: containerImages.frame.size.height)
  136. blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
  137. containerImages.addSubview(blurEffectView)
  138. }
  139. }
  140. let containerTimeStatus = UIView()
  141. containerImages.addSubview(containerTimeStatus)
  142. containerTimeStatus.anchor(bottom: containerImages.bottomAnchor, right: containerImages.rightAnchor, height: 20)
  143. let widthcontainerTimeStatus = containerTimeStatus.widthAnchor.constraint(equalToConstant: 60)
  144. widthcontainerTimeStatus.isActive = true
  145. containerTimeStatus.layer.cornerRadius = 5.0
  146. containerTimeStatus.layer.masksToBounds = true
  147. containerTimeStatus.backgroundColor = .black.withAlphaComponent(0.25)
  148. let timeInImage = UILabel()
  149. containerTimeStatus.addSubview(timeInImage)
  150. let date = Date(milliseconds: Int64(listGroupingImages[indexPath.row].time) ?? 100)
  151. let formatter = DateFormatter()
  152. formatter.dateFormat = "HH:mm"
  153. formatter.locale = NSLocale(localeIdentifier: "id") as Locale?
  154. timeInImage.text = formatter.string(from: date as Date)
  155. timeInImage.textColor = .white
  156. timeInImage.font = UIFont.systemFont(ofSize: 12, weight: .medium)
  157. if isInitiator {
  158. let statusInImage = UIImageView()
  159. containerTimeStatus.addSubview(statusInImage)
  160. statusInImage.anchor(right: containerTimeStatus.rightAnchor, centerY: containerTimeStatus.centerYAnchor, width: 20, height: 20)
  161. if listGroupingImages[indexPath.row].status == "1" || listGroupingImages[indexPath.row].status == "2" {
  162. statusInImage.image = UIImage(named: "checklist", in: Bundle.resourceBundle(for: DigiX.self), with: nil)!.withTintColor(UIColor.white)
  163. } else if listGroupingImages[indexPath.row].status == "3" {
  164. statusInImage.image = UIImage(named: "double-checklist", in: Bundle.resourceBundle(for: DigiX.self), with: nil)!.withTintColor(UIColor.white)
  165. } else {
  166. statusInImage.image = UIImage(named: "double-checklist", in: Bundle.resourceBundle(for: DigiX.self), with: nil)!.withTintColor(UIColor.systemBlue)
  167. }
  168. timeInImage.anchor(right: statusInImage.leftAnchor, centerY: containerTimeStatus.centerYAnchor, height: 15)
  169. } else {
  170. timeInImage.anchor(right: containerTimeStatus.rightAnchor, paddingRight: 5, centerY: containerTimeStatus.centerYAnchor, height: 20)
  171. widthcontainerTimeStatus.constant = widthcontainerTimeStatus.constant - 10
  172. }
  173. if listGroupingImages[indexPath.row].dataMessage["is_stared"] as! String == "1" {
  174. let iconStar = UIImageView()
  175. containerTimeStatus.addSubview(iconStar)
  176. iconStar.anchor(right: timeInImage.leftAnchor, paddingRight: 2, centerY: containerTimeStatus.centerYAnchor, width: 20, height: 20)
  177. widthcontainerTimeStatus.constant = widthcontainerTimeStatus.constant + 20
  178. iconStar.image = UIImage(systemName: "star.fill")
  179. iconStar.tintColor = .white
  180. }
  181. if deleteSession || forwardSession {
  182. let containerSelect = UIView()
  183. containerImages.addSubview(containerSelect)
  184. containerSelect.anchor(top: containerImages.topAnchor, left: containerImages.leftAnchor, bottom: containerImages.bottomAnchor, right: containerImages.rightAnchor)
  185. let iconSelected = UIImageView(frame: CGRect(x: 0, y: 0, width: 25.0, height: 25.0))
  186. iconSelected.backgroundColor = .lightGray.withAlphaComponent(0.3)
  187. iconSelected.layer.borderWidth = 2
  188. iconSelected.layer.borderColor = UIColor.black.cgColor
  189. iconSelected.layer.cornerRadius = 12.5
  190. iconSelected.layer.masksToBounds = true
  191. iconSelected.tintColor = .black
  192. containerSelect.addSubview(iconSelected)
  193. iconSelected.anchor(top: containerSelect.topAnchor, left: containerSelect.leftAnchor, paddingTop: 10, paddingLeft: 10, width: 25.0, height: 25.0)
  194. if listGroupingImages[indexPath.row].isSelected {
  195. containerSelect.backgroundColor = .white.withAlphaComponent(0.2)
  196. iconSelected.image = UIImage(systemName: "checkmark.circle.fill")
  197. }
  198. }
  199. return cell
  200. }
  201. func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
  202. if tableView == tableViewImages {
  203. return ListGroupImages.getImageSize(image: listGroupingImages[indexPath.row].thumbId, screenWidth: UIScreen.main.bounds.width, screenHeight: UIScreen.main.bounds.height)!.height + 15
  204. }
  205. return UITableView.automaticDimension
  206. }
  207. func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  208. if tableView == tableViewPopOver {
  209. popover.dismiss()
  210. switch indexPath.row {
  211. case 0:
  212. popover.dismiss()
  213. if listGroupingImages[indexSelected].dataMessage["is_stared"] as! String == "0" {
  214. DispatchQueue.global().async { [self] in
  215. Database.shared.database?.inTransaction({ (fmdb, rollback) in
  216. _ = Database.shared.updateRecord(fmdb: fmdb, table: "MESSAGE", cvalues: [
  217. "is_stared" : 1
  218. ], _where: "message_id = '\(listGroupingImages[indexSelected].messageId)'")
  219. })
  220. }
  221. listGroupingImages[indexSelected].dataMessage["is_stared"] = "1"
  222. } else {
  223. DispatchQueue.global().async { [self] in
  224. Database.shared.database?.inTransaction({ (fmdb, rollback) in
  225. _ = Database.shared.updateRecord(fmdb: fmdb, table: "MESSAGE", cvalues: [
  226. "is_stared" : 0
  227. ], _where: "message_id = '\(listGroupingImages[indexSelected].messageId)'")
  228. })
  229. }
  230. listGroupingImages[indexSelected].dataMessage["is_stared"] = "0"
  231. }
  232. tableViewImages.reloadRows(at: [IndexPath(row: indexSelected, section: 0)], with: .none)
  233. updateEditor!(listGroupingImages, [:], false)
  234. case 1:
  235. popover.dismiss()
  236. self.navigationController?.popViewController(animated: true)
  237. updateEditor!([], listGroupingImages[indexSelected].dataMessage, false)
  238. case 2:
  239. popover.dismiss()
  240. listGroupingImages[indexSelected].isSelected = true
  241. selectActions(isDeleteSession: false)
  242. case 3:
  243. popover.dismiss()
  244. let messageInfoVC = MessageInfo()
  245. messageInfoVC.data = listGroupingImages[indexSelected].dataMessage
  246. messageInfoVC.dataPerson = listGroupingImages[indexPath.row].dataPerson
  247. self.navigationController?.pushViewController(messageInfoVC, animated: true)
  248. default :
  249. popover.dismiss()
  250. listGroupingImages[indexSelected].isSelected = true
  251. selectActions(isDeleteSession: true)
  252. }
  253. } else if deleteSession || forwardSession {
  254. if listGroupingImages[indexPath.row].isSelected {
  255. listGroupingImages[indexPath.row].isSelected = false
  256. } else {
  257. listGroupingImages[indexPath.row].isSelected = true
  258. }
  259. if listGroupingImages.filter({ $0.isSelected }).count != listGroupingImages.count && isSelectAll {
  260. changetoLeftBarButton(isSelectAllButton: true)
  261. } else if listGroupingImages.filter({ $0.isSelected }).count == listGroupingImages.count && !isSelectAll {
  262. changetoLeftBarButton(isSelectAllButton: false)
  263. }
  264. viewMultipleSelect.subviews.forEach({ $0.removeFromSuperview() })
  265. addSubviewMultipleSelect()
  266. tableView.reloadRows(at: [indexPath], with: .none)
  267. }
  268. }
  269. func scrollViewDidScroll(_ scrollView: UIScrollView) {
  270. let visibleRect = CGRect(origin: scrollView.contentOffset, size: scrollView.bounds.size)
  271. let visibleTableViewRect = tableViewImages.convert(visibleRect, from: tableViewImages)
  272. let startY = visibleTableViewRect.origin.y
  273. let endY = startY + visibleTableViewRect.size.height
  274. startYVisible = startY
  275. endYVisible = endY
  276. }
  277. @objc func handleLongPress(_ gestureRecognizer: LongPressImageVIew) {
  278. if gestureRecognizer.state == .began {
  279. indexSelected = gestureRecognizer.index
  280. let contentOffset = tableViewImages.contentOffset
  281. let location = gestureRecognizer.location(in: tableViewImages)
  282. let xTouch = location.x - contentOffset.x
  283. var yTouch = location.y - contentOffset.y + 100
  284. let boundary = startYVisible != nil ? (endYVisible - startYVisible) / 2 - 50 : (UIScreen.main.bounds.height - 64) / 2 - 50
  285. let yTouchDiff = startYVisible != nil ? location.y - startYVisible : location.y - 0.0
  286. tableViewPopOver = UITableView(frame: CGRect(x: 0, y: 10, width: 140, height: 220))
  287. popover = Popover()
  288. if yTouchDiff >= boundary {
  289. yTouch = location.y - contentOffset.y + 20
  290. tableViewPopOver = UITableView(frame: CGRect(x: 0, y: 0, width: 140, height: 220))
  291. popover.popoverType = .up
  292. }
  293. tableViewPopOver.register(UITableViewCell.self, forCellReuseIdentifier: "cellPopOver")
  294. tableViewPopOver.dataSource = self
  295. tableViewPopOver.delegate = self
  296. tableViewPopOver.layoutMargins = UIEdgeInsets.zero
  297. tableViewPopOver.separatorInset = UIEdgeInsets.zero
  298. tableViewPopOver.isScrollEnabled = false
  299. let viewTable = UITableView(frame: CGRect(x: 0, y: 0, width: 140, height: 220))
  300. viewTable.addSubview(tableViewPopOver)
  301. let touchPoint = CGPoint( x: xTouch, y: yTouch)
  302. popover.show(viewTable, point: touchPoint)
  303. UINotificationFeedbackGenerator().notificationOccurred(.success)
  304. }
  305. }
  306. @objc func selectAction() {
  307. selectActions(isDeleteSession: true)
  308. }
  309. func selectActions(isDeleteSession: Bool) {
  310. self.navigationItem.setHidesBackButton(true, animated: true)
  311. changetoLeftBarButton(isSelectAllButton: true)
  312. let doneButton = UIBarButtonItem(title: "Done".localized(), style: .plain, target: self, action: #selector(doneAction))
  313. doneButton.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 16)], for: .normal)
  314. navigationItem.rightBarButtonItem = doneButton
  315. deleteSession = isDeleteSession
  316. forwardSession = !isDeleteSession
  317. constraintBottomViewMultipleSelect.constant = 0
  318. UIView.animate(withDuration: 0.35, animations: {
  319. self.view.layoutIfNeeded()
  320. })
  321. addSubviewMultipleSelect()
  322. tableViewImages.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 50, right: 0)
  323. tableViewImages.reloadData()
  324. }
  325. @objc func selectAllAction() {
  326. listGroupingImages.forEach({ $0.isSelected = true })
  327. changetoLeftBarButton(isSelectAllButton: false)
  328. viewMultipleSelect.subviews.forEach({ $0.removeFromSuperview() })
  329. addSubviewMultipleSelect()
  330. tableViewImages.reloadData()
  331. }
  332. @objc func deselectAllAction() {
  333. listGroupingImages.forEach({ $0.isSelected = false })
  334. changetoLeftBarButton(isSelectAllButton: true)
  335. viewMultipleSelect.subviews.forEach({ $0.removeFromSuperview() })
  336. addSubviewMultipleSelect()
  337. tableViewImages.reloadData()
  338. }
  339. @objc func doneAction() {
  340. navigationItem.leftBarButtonItem = nil
  341. let selectButton = UIBarButtonItem(title: "Select".localized(), style: .plain, target: self, action: #selector(selectAction))
  342. selectButton.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], for: .normal)
  343. navigationItem.rightBarButtonItem = selectButton
  344. self.navigationItem.setHidesBackButton(false, animated: true)
  345. listGroupingImages.forEach({ $0.isSelected = false })
  346. deleteSession = false
  347. forwardSession = false
  348. tableViewImages.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
  349. constraintBottomViewMultipleSelect.constant = 50
  350. viewMultipleSelect.subviews.forEach({ $0.removeFromSuperview() })
  351. UIView.animate(withDuration: 0.35, animations: {
  352. self.view.layoutIfNeeded()
  353. })
  354. tableViewImages.reloadData()
  355. }
  356. func changetoLeftBarButton(isSelectAllButton: Bool) {
  357. if isSelectAllButton {
  358. let selectAllButton = UIBarButtonItem(title: "Select All".localized(), style: .plain, target: self, action: #selector(selectAllAction))
  359. selectAllButton.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], for: .normal)
  360. navigationItem.leftBarButtonItem = selectAllButton
  361. isSelectAll = false
  362. } else {
  363. let deselectAllButton = UIBarButtonItem(title: "Deselect All".localized(), style: .plain, target: self, action: #selector(deselectAllAction))
  364. deselectAllButton.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], for: .normal)
  365. navigationItem.leftBarButtonItem = deselectAllButton
  366. isSelectAll = true
  367. }
  368. }
  369. func addSubviewMultipleSelect() {
  370. viewMultipleSelect.addTopBorder(with: .lightGray, andWidth: 1)
  371. let container = UIView()
  372. viewMultipleSelect.addSubview(container)
  373. container.translatesAutoresizingMaskIntoConstraints = false
  374. NSLayoutConstraint.activate([
  375. container.leadingAnchor.constraint(equalTo: viewMultipleSelect.leadingAnchor),
  376. container.trailingAnchor.constraint(equalTo:viewMultipleSelect.trailingAnchor),
  377. container.bottomAnchor.constraint(equalTo: viewMultipleSelect.bottomAnchor),
  378. container.heightAnchor.constraint(equalToConstant: 50)
  379. ])
  380. let title = UILabel()
  381. container.addSubview(title)
  382. title.translatesAutoresizingMaskIntoConstraints = false
  383. NSLayoutConstraint.activate([
  384. title.centerXAnchor.constraint(equalTo: container.centerXAnchor),
  385. title.centerYAnchor.constraint(equalTo:container.centerYAnchor),
  386. ])
  387. let countSelected = listGroupingImages.filter({ $0.isSelected }).count
  388. title.text = "\(countSelected) " + "Selected".localized()
  389. title.textColor = .mainColor
  390. title.font = UIFont.systemFont(ofSize: 15.0).bold
  391. let button = UIImageView()
  392. container.addSubview(button)
  393. button.translatesAutoresizingMaskIntoConstraints = false
  394. NSLayoutConstraint.activate([
  395. button.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 15),
  396. button.centerYAnchor.constraint(equalTo:container.centerYAnchor),
  397. button.widthAnchor.constraint(equalToConstant: 30),
  398. button.heightAnchor.constraint(equalToConstant: 30),
  399. ])
  400. if forwardSession {
  401. button.image = UIImage(systemName: "arrowshape.turn.up.right")
  402. if countSelected == 0 {
  403. button.tintColor = .gray
  404. } else {
  405. button.tintColor = .mainColor
  406. }
  407. } else if deleteSession {
  408. button.image = UIImage(systemName: "trash")
  409. if countSelected == 0 {
  410. button.tintColor = .gray
  411. } else {
  412. button.tintColor = .red
  413. }
  414. }
  415. let buttonGesture = UITapGestureRecognizer(target: self, action: #selector(sessionAction))
  416. button.isUserInteractionEnabled = true
  417. button.addGestureRecognizer(buttonGesture)
  418. }
  419. @objc func sessionAction() {
  420. if forwardSession {
  421. let tempDataMessages = listGroupingImages.filter({ $0.isSelected })
  422. var dataMessages: [[String: Any?]] = []
  423. for i in 0..<tempDataMessages.count {
  424. dataMessages.append(tempDataMessages[i].dataMessage)
  425. }
  426. let contactChatNav = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "contactChatNav") as! UINavigationController
  427. contactChatNav.modalPresentationStyle = .custom
  428. contactChatNav.navigationBar.tintColor = .white
  429. contactChatNav.navigationBar.barTintColor = .mainColor
  430. contactChatNav.navigationBar.isTranslucent = false
  431. let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
  432. contactChatNav.navigationBar.titleTextAttributes = textAttributes
  433. contactChatNav.view.backgroundColor = .mainColor
  434. if let controller = contactChatNav.viewControllers.first as? ContactChatViewController {
  435. controller.isChooser = { [weak self] scope, pin in
  436. if scope == "3" {
  437. let editorPersonalVC = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "editorPersonalVC") as! EditorPersonal
  438. editorPersonalVC.unique_l_pin = pin
  439. editorPersonalVC.dataMessageForward = dataMessages
  440. self?.navigationController?.replaceAllViewController(with: editorPersonalVC, animated: true)
  441. } else {
  442. let editorGroupVC = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "editorGroupVC") as! EditorGroup
  443. editorGroupVC.unique_l_pin = pin
  444. editorGroupVC.dataMessageForward = dataMessages
  445. self?.navigationController?.replaceAllViewController(with: editorGroupVC, animated: true)
  446. }
  447. }
  448. }
  449. self.present(contactChatNav, animated: true, completion: nil)
  450. } else if deleteSession {
  451. let tempDataMessages = listGroupingImages.filter({ $0.isSelected })
  452. let countSelected = tempDataMessages.count
  453. if countSelected == 0 {
  454. return
  455. }
  456. let alertController = LibAlertController(title: "Delete".localized() + " \(countSelected) " + "messages?", message: nil, preferredStyle: .actionSheet)
  457. if let action = self.actionDelete(for: "me", title: "Delete".localized() + " \(countSelected) " + "For Me".localized(), dataMessages: tempDataMessages) {
  458. alertController.addAction(action)
  459. }
  460. let idMe = UserDefaults.standard.string(forKey: "me") as String?
  461. let dataStatusRead = tempDataMessages.filter({ $0.status == "4" })
  462. if tempDataMessages[0].dataMessage["f_pin"] as? String == idMe && dataStatusRead.count == 0 {
  463. if let action = self.actionDelete(for: "everyone", title: "Delete".localized() + " \(countSelected) " + "For Everyone".localized(), dataMessages: tempDataMessages) {
  464. alertController.addAction(action)
  465. }
  466. }
  467. alertController.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: nil))
  468. self.present(alertController, animated: true)
  469. }
  470. }
  471. private func actionDelete(for type: String, title: String, dataMessages: [ImageGrouping]) -> UIAlertAction? {
  472. return UIAlertAction(title: title, style: .destructive) { [unowned self] _ in
  473. let tempDataDelete = listGroupingImages
  474. for i in 0..<dataMessages.count {
  475. if (type == "me") {
  476. self.deleteMessage(l_pin: dataMessages[i].lPin, message_id: dataMessages[i].messageId, scope: "3", type: "1", chat: "")
  477. listGroupingImages.removeAll(where: { $0.messageId == dataMessages[i].messageId })
  478. } else {
  479. self.deleteMessage(l_pin: dataMessages[i].lPin, message_id: dataMessages[i].messageId, scope: "3", type: "2", chat: "")
  480. if let idxTemp = tempDataDelete!.firstIndex(where: { $0.messageId == dataMessages[i].messageId}) {
  481. tempDataDelete![idxTemp].dataMessage["lock"] = "1"
  482. }
  483. listGroupingImages.removeAll(where: { $0.messageId == dataMessages[i].messageId })
  484. }
  485. }
  486. centeredTitleView.subtitleLabel.text = String(listGroupingImages.count) + " " + "images".localized()
  487. updateEditor!(type == "me" ? listGroupingImages : tempDataDelete!, [:], true)
  488. doneAction()
  489. }
  490. }
  491. private func deleteMessage(l_pin: String, message_id: String, scope: String, type: String, chat: String) {
  492. let tmessage = CoreMessage_TMessageBank.deleteMessage(l_pin: l_pin, messageId: message_id, scope: scope, type: type, chat: chat)
  493. DigiX.deleteQueueMessage(message: tmessage)
  494. }
  495. static func getImageSize(image: String, screenWidth: CGFloat, screenHeight: CGFloat) -> CGSize? {
  496. let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
  497. let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
  498. let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
  499. if let dirPath = paths.first {
  500. let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent(image)
  501. let image = UIImage(contentsOfFile: imageURL.path)
  502. let imageWidth = image!.size.width
  503. let imageHeight = image!.size.height
  504. // Calculate the aspect ratio of the image
  505. let aspectRatio = imageWidth / imageHeight
  506. // Calculate the size to display the image while maintaining its aspect ratio
  507. var displayWidth: CGFloat = 0.0
  508. var displayHeight: CGFloat = 0.0
  509. if imageWidth > imageHeight {
  510. // Landscape image
  511. displayWidth = screenWidth
  512. displayHeight = screenWidth / aspectRatio
  513. } else {
  514. // Portrait or square image
  515. displayHeight = screenHeight
  516. displayWidth = screenHeight * aspectRatio
  517. }
  518. return CGSize(width: displayWidth, height: displayHeight)
  519. }
  520. return nil
  521. }
  522. }
  523. class CenteredTitleSubtitleView: UIView {
  524. let titleLabel: UILabel = {
  525. let label = UILabel()
  526. label.textAlignment = .center
  527. label.font = UIFont.boldSystemFont(ofSize: 18)
  528. label.textColor = .white
  529. return label
  530. }()
  531. let subtitleLabel: UILabel = {
  532. let label = UILabel()
  533. label.textAlignment = .center
  534. label.font = UIFont.systemFont(ofSize: 14)
  535. label.textColor = .lightGray
  536. return label
  537. }()
  538. override init(frame: CGRect) {
  539. super.init(frame: frame)
  540. setupSubviews()
  541. }
  542. required init?(coder: NSCoder) {
  543. super.init(coder: coder)
  544. setupSubviews()
  545. }
  546. private func setupSubviews() {
  547. addSubview(titleLabel)
  548. addSubview(subtitleLabel)
  549. // Add any constraints or frames you prefer
  550. // Here's an example using autolayout anchors
  551. titleLabel.translatesAutoresizingMaskIntoConstraints = false
  552. titleLabel.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
  553. titleLabel.topAnchor.constraint(equalTo: topAnchor).isActive = true
  554. subtitleLabel.translatesAutoresizingMaskIntoConstraints = false
  555. subtitleLabel.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
  556. subtitleLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor).isActive = true
  557. }
  558. }
  559. class LongPressImageVIew: UILongPressGestureRecognizer {
  560. var imageView = UIImageView()
  561. var index = 0
  562. }