GroupDetailViewController.swift 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033
  1. //
  2. // GroupViewController.swift
  3. // Qmera
  4. //
  5. // Created by Yayan Dwi on 24/09/21.
  6. //
  7. import UIKit
  8. import NotificationBannerSwift
  9. import nuSDKService
  10. class GroupDetailViewController: UITableViewController {
  11. enum Flag {
  12. case edit
  13. case view
  14. }
  15. var flag: Flag = .edit
  16. var data: String = ""
  17. static let SUBGROUP_LEVEL_LIMIT = 10
  18. private var group: Group?
  19. private var isAdmin: Bool = false
  20. private var imageVideoPicker : ImageVideoPicker!
  21. private var tempImage: UIImage?
  22. private let imageAdmin = UIImageView()
  23. private let imageAddContact = UIImageView()
  24. private enum Section {
  25. case profile
  26. case description
  27. case access
  28. case topic
  29. case detail
  30. case member
  31. case exit
  32. }
  33. private var sections: [Section] = [
  34. .profile,
  35. .description,
  36. .access,
  37. .topic,
  38. .detail
  39. ]
  40. var checkReadMessage: (() -> ())?
  41. private let idSubGroup = Date().currentTimeMillis().toHex()
  42. var fromNotification = false
  43. override func viewDidLoad() {
  44. super.viewDidLoad()
  45. imageVideoPicker = ImageVideoPicker(presentationController: self, delegate: self)
  46. let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
  47. navigationController?.navigationBar.titleTextAttributes = textAttributes
  48. navigationController?.navigationBar.topItem?.backButtonTitle = ""
  49. if fromNotification {
  50. let imageButton = UIImageView(frame: CGRect(x: -16, y: 0, width: 20, height: 44))
  51. imageButton.image = UIImage(systemName: "chevron.backward", withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .regular, scale: .default))?.withTintColor(.white)
  52. imageButton.contentMode = .left
  53. let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(didTapExit))
  54. imageButton.isUserInteractionEnabled = true
  55. imageButton.addGestureRecognizer(tapGestureRecognizer)
  56. let leftItem = UIBarButtonItem(customView: imageButton)
  57. self.navigationItem.leftBarButtonItem = leftItem
  58. }
  59. reload()
  60. let center: NotificationCenter = NotificationCenter.default
  61. center.addObserver(self, selector: #selector(updateData(notification:)), name: NSNotification.Name(rawValue: "onGroup"), object: nil)
  62. center.addObserver(self, selector: #selector(updateData(notification:)), name: NSNotification.Name(rawValue: "onTopic"), object: nil)
  63. center.addObserver(self, selector: #selector(updateData(notification:)), name: NSNotification.Name(rawValue: "onMember"), object: nil)
  64. }
  65. override func viewWillDisappear(_ animated: Bool) {
  66. if self.isMovingFromParent {
  67. self.checkReadMessage?()
  68. }
  69. }
  70. var alert2: UIAlertController?
  71. var textFields = [UITextField]()
  72. // MARK: - Data source
  73. @objc func didTapExit() {
  74. self.dismiss(animated: true, completion: nil)
  75. }
  76. func reload() {
  77. getData { group in
  78. self.group = group
  79. if let myData = self.group?.members.first(where: { member in
  80. return member.pin == UserDefaults.standard.string(forKey: "me")!
  81. }) {
  82. if myData.position == "1" {
  83. self.isAdmin = true
  84. } else {
  85. self.isAdmin = false
  86. }
  87. }
  88. if self.sections.count == 5, group.groupType != "1" {
  89. self.sections.append(.member)
  90. self.sections.append(.exit)
  91. }
  92. DispatchQueue.main.async {
  93. self.title = group.name
  94. self.tableView.reloadData()
  95. if group.official == "1" && !group.parent.isEmpty {
  96. Database.shared.database?.inTransaction({ (fmdb, rollback) in
  97. if let cursorImage = Database.shared.getRecords(fmdb: fmdb, query: "SELECT image_id FROM GROUPZ where group_type = 1 AND official = 1"), cursorImage.next() {
  98. self.group?.profile = cursorImage.string(forColumnIndex: 0)!
  99. cursorImage.close()
  100. }
  101. })
  102. }
  103. if self.isAdmin && group.official != "1" {
  104. var children : [UIAction] = []
  105. if Int(group.level)! <= GroupDetailViewController.SUBGROUP_LEVEL_LIMIT {
  106. children.append(UIAction(title: "Add Sub Group".localized(), handler: {(_) in
  107. self.createSubGroup()
  108. }))
  109. }
  110. children.append(UIAction(title: "Change Name Group".localized(), handler: {(_) in
  111. self.edit()
  112. }))
  113. let menu = UIMenu(title: "", children: children)
  114. let moreIcon = UIBarButtonItem(image: UIImage(systemName: "ellipsis"), menu: menu)
  115. self.navigationItem.rightBarButtonItem = moreIcon
  116. }
  117. }
  118. }
  119. }
  120. func createSubGroup() {
  121. self.alert2 = LibAlertController(title: "Create Sub Group".localized(), message: nil, preferredStyle: .alert)
  122. self.textFields.removeAll()
  123. self.alert2?.addTextField{ (texfield) in
  124. texfield.placeholder = "Group's Name".localized()
  125. texfield.addTarget(self, action: #selector(self.alertTextFieldDidChange(_:)), for: UIControl.Event.editingChanged)
  126. }
  127. let submitAction = UIAlertAction(title: "Create".localized(), style: .default, handler: { (action) -> Void in
  128. let textField = self.alert2?.textFields![0]
  129. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  130. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  131. imageView.tintColor = .white
  132. let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  133. banner.show()
  134. return
  135. }
  136. var level = self.group!.level
  137. if level.isEmpty || level == "-1"{
  138. level = "2"
  139. } else {
  140. level = "\(Int(level)! + 1)"
  141. }
  142. //print(("level: \(level)")
  143. DispatchQueue.main.async {
  144. if let response = DigiX.writeAndWait(message: CoreMessage_TMessageBank.getCreateSubGroup(group_id: self.idSubGroup, group_name: textField!.text!, parent_id: self.group!.id, level: level)) {
  145. if response.isOk() {
  146. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "groupDetailView") as! GroupDetailViewController
  147. controller.data = self.idSubGroup
  148. self.navigationController?.show(controller, sender: nil)
  149. self.navigationController?.viewControllers.removeSubrange(1...(self.navigationController?.viewControllers.count)! - 2)
  150. } else {
  151. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  152. imageView.tintColor = .white
  153. let banner = FloatingNotificationBanner(title: "Unable to access servers".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  154. banner.show()
  155. }
  156. }
  157. }
  158. })
  159. self.alert2?.addAction(submitAction)
  160. self.alert2?.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: nil))
  161. self.present(self.alert2!, animated: true, completion: nil)
  162. }
  163. func edit() {
  164. let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "groupNameView") as! GroupNameViewController
  165. controller.data = self.data
  166. controller.name = group?.name
  167. controller.isDismiss = {
  168. self.reload()
  169. }
  170. let navController = UINavigationController(rootViewController: controller)
  171. let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
  172. UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
  173. let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
  174. navController.navigationBar.titleTextAttributes = textAttributes
  175. navigationController?.present(navController, animated: true)
  176. }
  177. @objc func updateData(notification: NSNotification) {
  178. let data:[AnyHashable : Any] = notification.userInfo!
  179. if data["code"] as! String == "A008" && data["member"] as! String == UserDefaults.standard.string(forKey: "me")! {
  180. DispatchQueue.main.async {
  181. self.navigationController?.popViewController(animated: true)
  182. }
  183. } else if data["f_pin"] as! String != UserDefaults.standard.string(forKey: "me")! || data["code"] as! String == "BD" {
  184. DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
  185. self.reload()
  186. }
  187. }
  188. }
  189. private func getData(completion: @escaping (Group) -> ()) {
  190. DispatchQueue.global().async {
  191. let query = "select g.group_id, g.f_name, g.image_id, g.quote, g.created_by, g.created_date, g.parent, g.group_type, g.is_open, g.official, g.level from GROUPZ g where g.group_id = '\(self.data)'"
  192. Database.shared.database?.inTransaction({ fmdb, rollback in
  193. if let cursor = Database.shared.getRecords(fmdb: fmdb, query: query), cursor.next() {
  194. let group = Group(id: cursor.string(forColumnIndex: 0) ?? "",
  195. name: cursor.string(forColumnIndex: 1) ?? "",
  196. profile: cursor.string(forColumnIndex: 2) ?? "",
  197. quote: cursor.string(forColumnIndex: 3) ?? "",
  198. by: cursor.string(forColumnIndex: 4) ?? "",
  199. date: cursor.string(forColumnIndex: 5) ?? "",
  200. parent: cursor.string(forColumnIndex: 6) ?? "",
  201. groupType: cursor.string(forColumnIndex: 7) ?? "",
  202. isOpen: cursor.string(forColumnIndex: 8) ?? "",
  203. official: cursor.string(forColumnIndex: 9) ?? "",
  204. level: cursor.string(forColumnIndex: 10) ?? "")
  205. cursor.close()
  206. group.topics.append(Topic(chatId: "", title: "Lounge".localized(), thumb: ""))
  207. if let cursorTopic = Database.shared.getRecords(fmdb: fmdb, query: "select chat_id, title, thumb from DISCUSSION_FORUM where group_id = '\(self.data)'") {
  208. while cursorTopic.next() {
  209. let topic = Topic(chatId: cursorTopic.string(forColumnIndex: 0) ?? "",
  210. title: cursorTopic.string(forColumnIndex: 1) ?? "",
  211. thumb: cursorTopic.string(forColumnIndex: 2) ?? "")
  212. group.topics.append(topic)
  213. }
  214. cursorTopic.close()
  215. }
  216. if let cursorMember = Database.shared.getRecords(fmdb: fmdb, query: "select f_pin, first_name, last_name, thumb_id, position from GROUPZ_MEMBER where group_id = '\(self.data)' order by 2 asc") {
  217. while cursorMember.next() {
  218. let member = Member(pin: cursorMember.string(forColumnIndex: 0) ?? "",
  219. firstName: cursorMember.string(forColumnIndex: 1) ?? "",
  220. lastName: cursorMember.string(forColumnIndex: 2) ?? "",
  221. thumb: cursorMember.string(forColumnIndex: 3) ?? "",
  222. position: cursorMember.string(forColumnIndex: 4) ?? "")
  223. if let cursorUser = Database.shared.getRecords(fmdb: fmdb, query: "SELECT user_type, official_account FROM BUDDY where f_pin='\(member.pin)'"), cursorUser.next() {
  224. member.userType = cursorUser.string(forColumnIndex: 0)
  225. member.official = cursorUser.string(forColumnIndex: 1)
  226. cursorUser.close()
  227. }
  228. group.members.append(member)
  229. }
  230. cursorMember.close()
  231. }
  232. completion(group)
  233. }
  234. })
  235. }
  236. }
  237. // MARK: - Cell selected
  238. override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  239. tableView.deselectRow(at: indexPath, animated: false)
  240. switch sections[indexPath.section] {
  241. case .profile:
  242. if isAdmin {
  243. let alert = LibAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
  244. alert.addAction(UIAlertAction(title: "Take Photo".localized(), style: .default, handler: { action in
  245. self.imageVideoPicker.present(source: .imageCamera)
  246. }))
  247. alert.addAction(UIAlertAction(title: "Choose Photo".localized(), style: .default, handler: { action in
  248. self.imageVideoPicker.present(source: .imageAlbum)
  249. }))
  250. alert.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: { action in
  251. }))
  252. navigationController?.present(alert, animated: true)
  253. }
  254. case .description:
  255. if let g = group, isAdmin {
  256. let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "groupDescView") as! GroupDescViewController
  257. controller.data = g.id
  258. controller.quote = g.quote
  259. controller.isDismiss = {
  260. self.reload()
  261. }
  262. let navController = UINavigationController(rootViewController: controller)
  263. let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
  264. UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
  265. let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
  266. navController.navigationBar.titleTextAttributes = textAttributes
  267. navigationController?.present(navController, animated: true)
  268. }
  269. case .access:
  270. if let g = group, isAdmin, g.official != "1" {
  271. var currentAccess = g.isOpen
  272. if currentAccess.isEmpty || currentAccess == "0" {
  273. currentAccess = "1"
  274. } else {
  275. currentAccess = "0"
  276. }
  277. DigiX.showLoader()
  278. self.changeOpenGroup(open: currentAccess) { result in
  279. if result {
  280. DispatchQueue.main.async {
  281. DigiX.hideLoader(completion: {
  282. g.isOpen = currentAccess
  283. tableView.reloadRows(at: [indexPath], with: .none)
  284. })
  285. }
  286. } else {
  287. DispatchQueue.main.async {
  288. DigiX.hideLoader(completion: {
  289. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  290. imageView.tintColor = .white
  291. let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  292. banner.show()
  293. })
  294. }
  295. }
  296. }
  297. }
  298. case .topic:
  299. if let g = group, isAdmin, indexPath.row == 0 {
  300. let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "groupTopicView") as! GroupTopicViewController
  301. controller.data = g.id
  302. controller.isDismiss = {
  303. self.reload()
  304. }
  305. let navController = UINavigationController(rootViewController: controller)
  306. let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
  307. UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
  308. let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
  309. navController.navigationBar.titleTextAttributes = textAttributes
  310. navigationController?.present(navController, animated: true)
  311. } else if let g = group, isAdmin {
  312. let topic = g.topics[indexPath.row - 1]
  313. if topic.chatId.isEmpty {
  314. if let controller = self.previousViewController as? EditorGroup {
  315. if controller.dataTopic["chat_id"] as! String == topic.chatId {
  316. self.navigationController?.popViewController(animated: true)
  317. return
  318. }
  319. controller.unique_l_pin = g.id
  320. controller.loadData()
  321. self.navigationController?.popViewController(animated: true)
  322. } else {
  323. self.navigationController?.popViewController(animated: true)
  324. let editorGroupVC = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "editorGroupVC") as! EditorGroup
  325. editorGroupVC.hidesBottomBarWhenPushed = true
  326. editorGroupVC.unique_l_pin = g.id
  327. self.navigationController?.viewControllers.first?.show(editorGroupVC, sender: nil)
  328. }
  329. return
  330. }
  331. let alert = LibAlertController(title: nil, message: topic.title, preferredStyle: .actionSheet)
  332. alert.addAction(UIAlertAction(title: "Enter Topic", style: .default, handler: { action in
  333. if let controller = self.previousViewController as? EditorGroup {
  334. if controller.dataTopic["chat_id"] as! String == topic.chatId {
  335. self.navigationController?.popViewController(animated: true)
  336. return
  337. }
  338. controller.unique_l_pin = topic.chatId
  339. controller.loadData()
  340. self.navigationController?.popViewController(animated: true)
  341. } else {
  342. self.navigationController?.popViewController(animated: true)
  343. let editorGroupVC = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "editorGroupVC") as! EditorGroup
  344. editorGroupVC.hidesBottomBarWhenPushed = true
  345. editorGroupVC.unique_l_pin = topic.chatId
  346. self.navigationController?.viewControllers.first?.show(editorGroupVC, sender: nil)
  347. }
  348. }))
  349. alert.addAction(UIAlertAction(title: "Rename Topic", style: .default, handler: { action in
  350. self.alert2 = LibAlertController(title: "Change Topic's Name".localized(), message: nil, preferredStyle: .alert)
  351. self.textFields.removeAll()
  352. self.alert2?.addTextField{ (texfield) in
  353. texfield.text = topic.title
  354. texfield.placeholder = "Topic's Name"
  355. texfield.addTarget(self, action: #selector(self.alertTextFieldDidChange(_:)), for: UIControl.Event.editingChanged)
  356. }
  357. let submitAction = UIAlertAction(title: "Rename".localized(), style: .default, handler: { (action) -> Void in
  358. let textField = self.alert2?.textFields![0]
  359. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  360. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  361. imageView.tintColor = .white
  362. let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  363. banner.show()
  364. return
  365. }
  366. if textField!.text! == topic.title {
  367. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  368. imageView.tintColor = .white
  369. let banner = FloatingNotificationBanner(title: "Topic name has been used. Enter another topic name".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  370. banner.show()
  371. return
  372. }
  373. if textField!.text! == "Lounge" || textField!.text! == "Beranda" {
  374. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  375. imageView.tintColor = .white
  376. let banner = FloatingNotificationBanner(title: "Topic already registered".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  377. banner.show()
  378. return
  379. }
  380. DispatchQueue.main.async {
  381. if let g = self.group, let _ = DigiX.write(message: CoreMessage_TMessageBank.getUpdateChat(p_chat_id: topic.chatId, p_f_pin: g.id, p_title: textField!.text!, p_anonym: "", p_image: topic.thumb)) {
  382. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  383. imageView.tintColor = .white
  384. let banner = FloatingNotificationBanner(title: "Successfully changed".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
  385. banner.show()
  386. }
  387. }
  388. })
  389. self.alert2?.addAction(submitAction)
  390. self.alert2?.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: nil))
  391. self.present(self.alert2!, animated: true, completion: nil)
  392. }))
  393. alert.addAction(UIAlertAction(title: "Remove Topic".localized(), style: .destructive, handler: { action in
  394. let message = "Remove \(topic.title) from the \"\(g.name)\" group?"
  395. let notif = LibAlertController(title: nil, message: message, preferredStyle: .actionSheet)
  396. notif.addAction(UIAlertAction(title: "Remove".localized(), style: .destructive, handler: { notifAction in
  397. self.removeTopic(chatId: topic.chatId) { result in
  398. if result, let index = g.topics.firstIndex(of: topic) {
  399. Database.shared.database?.inTransaction({ (fmdb, rollback) in
  400. _ = Database.shared.deleteRecord(fmdb: fmdb, table: "DISCUSSION_FORUM", _where: "chat_id = '\(topic.chatId)'")
  401. _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE", _where: "chat_id='\(topic.chatId)'")
  402. _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", _where: "l_pin='\(topic.chatId)'")
  403. })
  404. var data: [AnyHashable : Any] = [:]
  405. data["code"] = CoreMessage_TMessageCode.DELETE_CHAT
  406. data["f_pin"] = UserDefaults.standard.string(forKey: "me")!
  407. data["topicId"] = topic.chatId
  408. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "onTopic"), object: nil, userInfo: data)
  409. DispatchQueue.main.async {
  410. tableView.beginUpdates()
  411. tableView.deleteRows(at: [indexPath], with: .none)
  412. g.topics.remove(at: index)
  413. tableView.endUpdates()
  414. }
  415. }
  416. }
  417. }))
  418. notif.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: { notifAction in
  419. }))
  420. self.navigationController?.present(notif, animated: true, completion: nil)
  421. }))
  422. alert.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: { action in
  423. }))
  424. navigationController?.present(alert, animated: true)
  425. } else if let g = group {
  426. let topic = g.topics[indexPath.row]
  427. if topic.chatId.isEmpty {
  428. if let controller = self.previousViewController as? EditorGroup {
  429. if controller.dataTopic["chat_id"] as! String == topic.chatId {
  430. self.navigationController?.popViewController(animated: true)
  431. return
  432. }
  433. controller.unique_l_pin = g.id
  434. controller.loadData()
  435. self.navigationController?.popViewController(animated: true)
  436. } else {
  437. self.navigationController?.popViewController(animated: true)
  438. let editorGroupVC = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "editorGroupVC") as! EditorGroup
  439. editorGroupVC.hidesBottomBarWhenPushed = true
  440. editorGroupVC.unique_l_pin = g.id
  441. self.navigationController?.viewControllers.first?.show(editorGroupVC, sender: nil)
  442. }
  443. return
  444. }
  445. else if let controller = self.previousViewController as? EditorGroup {
  446. if controller.dataTopic["chat_id"] as! String == topic.chatId {
  447. self.navigationController?.popViewController(animated: true)
  448. return
  449. }
  450. controller.unique_l_pin = topic.chatId
  451. controller.loadData()
  452. self.navigationController?.popViewController(animated: true)
  453. } else {
  454. self.navigationController?.popViewController(animated: true)
  455. let editorGroupVC = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "editorGroupVC") as! EditorGroup
  456. editorGroupVC.hidesBottomBarWhenPushed = true
  457. editorGroupVC.unique_l_pin = topic.chatId
  458. self.navigationController?.viewControllers.first?.show(editorGroupVC, sender: nil)
  459. }
  460. }
  461. case .member:
  462. if let g = group, isAdmin, indexPath.row == 0 {
  463. let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "groupMemberView") as! GroupMemberViewController
  464. controller.group = g
  465. if g.official == "1" && g.level == "3" {
  466. controller.isContactCenterInvite = true
  467. }
  468. controller.isDismiss = {
  469. self.reload()
  470. }
  471. let navController = UINavigationController(rootViewController: controller)
  472. let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
  473. UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
  474. let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
  475. navController.navigationBar.titleTextAttributes = textAttributes
  476. navController.navigationBar.largeTitleTextAttributes = textAttributes
  477. navigationController?.present(navController, animated: true)
  478. } else if let g = group, isAdmin {
  479. let member = g.members[indexPath.row - 1]
  480. if member.pin != UserDefaults.standard.string(forKey: "me")! {
  481. if member.pin == g.by {
  482. let data = User.getDataCanNil(pin: member.pin)
  483. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "profileView") as! ProfileViewController
  484. controller.flag = data == nil ? .invite : .friend
  485. controller.user = member
  486. controller.name = member.fullName
  487. controller.data = member.pin
  488. controller.picture = member.thumb
  489. self.navigationController?.show(controller, sender: nil)
  490. return
  491. }
  492. let alert = LibAlertController(title: nil, message: "\(member.firstName) \(member.lastName)", preferredStyle: .actionSheet)
  493. alert.addAction(UIAlertAction(title: "Info".localized(), style: .default, handler: { action in
  494. let data = User.getDataCanNil(pin: member.pin)
  495. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "profileView") as! ProfileViewController
  496. controller.flag = data == nil ? .invite : .friend
  497. controller.user = member
  498. controller.name = member.fullName
  499. controller.data = member.pin
  500. controller.picture = member.thumb
  501. controller.isDismiss = {
  502. self.reload()
  503. }
  504. self.navigationController?.show(controller, sender: nil)
  505. }))
  506. alert.addAction(UIAlertAction(title: member.position == "0" ? "Make Group Admin".localized() : "Remove Group Admin".localized(), style: member.position == "0" ? .default : .destructive, handler: { action in
  507. let message = "\(member.position == "0" ? "Make" : "Remove") \(member.fullName) from the \"\(g.name)\" group Admin?"
  508. let notif = LibAlertController(title: nil, message: message, preferredStyle: .actionSheet)
  509. notif.addAction(UIAlertAction(title: member.position == "0" ? "Make".localized() : "Remove".localized(), style: member.position == "0" ? .default : .destructive, handler: { notifAction in
  510. self.changePosition(pin: member.pin, isAdmin: member.position == "0") { result in
  511. if result {
  512. DispatchQueue.main.async {
  513. tableView.beginUpdates()
  514. member.position = member.position == "1" ? "0" : "1"
  515. tableView.reloadRows(at: [indexPath], with: .none)
  516. tableView.endUpdates()
  517. }
  518. }
  519. }
  520. }))
  521. notif.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: { notifAction in
  522. }))
  523. self.navigationController?.present(notif, animated: true, completion: nil)
  524. }))
  525. alert.addAction(UIAlertAction(title: "Remove From Group".localized(), style: .destructive, handler: { action in
  526. let message = "Remove \(member.fullName) from the \"\(g.name)\" group?"
  527. let notif = LibAlertController(title: nil, message: message, preferredStyle: .actionSheet)
  528. notif.addAction(UIAlertAction(title: "Remove".localized(), style: .destructive, handler: { notifAction in
  529. self.exitGroup(pin: member.pin) { result in
  530. if result, let index = g.members.firstIndex(of: member) {
  531. DispatchQueue.main.async {
  532. tableView.beginUpdates()
  533. tableView.deleteRows(at: [indexPath], with: .none)
  534. g.members.remove(at: index)
  535. tableView.endUpdates()
  536. }
  537. }
  538. }
  539. }))
  540. notif.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: { notifAction in
  541. }))
  542. self.navigationController?.present(notif, animated: true, completion: nil)
  543. }))
  544. alert.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: { action in
  545. }))
  546. navigationController?.present(alert, animated: true)
  547. }
  548. } else if let g = group {
  549. let member = g.members[indexPath.row]
  550. if member.pin == UserDefaults.standard.string(forKey: "me") {
  551. // skip self profile
  552. return
  553. }
  554. let data = User.getDataCanNil(pin: member.pin)
  555. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "profileView") as! ProfileViewController
  556. controller.flag = data == nil ? .invite : .friend
  557. controller.user = member
  558. controller.name = member.fullName
  559. controller.data = member.pin
  560. controller.picture = member.thumb
  561. controller.isDismiss = {
  562. self.reload()
  563. }
  564. self.navigationController?.show(controller, sender: nil)
  565. }
  566. case .exit:
  567. if let g = group {
  568. let idMe = UserDefaults.standard.string(forKey: "me") as String?
  569. let admins = g.members.filter { member in
  570. return member.position == "1"
  571. }
  572. var isDeleted = false
  573. if admins.count == 1 {
  574. if admins.first?.pin == idMe {
  575. isDeleted = true
  576. }
  577. }
  578. let message: String
  579. if isDeleted {
  580. message = "Are you sure want to delete the group?".localized()
  581. // message = "Are you sure want to delete the \"\(g.name)\" group?".localized()
  582. } else {
  583. message = "Are you sure want to exit the group?".localized()
  584. // message = "Are you sure want to exit the \"\(g.name)\" group?".localized()
  585. }
  586. let alert = LibAlertController(title: nil, message: message, preferredStyle: .actionSheet)
  587. alert.addAction(UIAlertAction(title: isDeleted ? "Delete Group".localized() : "Exit Group".localized(), style: .destructive, handler: { action in
  588. self.exitGroup(pin: isDeleted ? "ALL": UserDefaults.standard.string(forKey: "me")!) { result in
  589. if result {
  590. DispatchQueue.main.async {
  591. self.navigationController?.popToRootViewController(animated: true)
  592. }
  593. }
  594. }
  595. }))
  596. alert.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: { action in
  597. }))
  598. navigationController?.present(alert, animated: true)
  599. }
  600. default:
  601. //print(("No handler..")
  602. break
  603. }
  604. }
  605. @objc func alertTextFieldDidChange(_ sender: UITextField) {
  606. if(!textFields.isEmpty){
  607. alert2?.actions[0].isEnabled = textFields[0].text!.trimmingCharacters(in: .whitespaces).count > 0
  608. }
  609. else {
  610. alert2?.actions[0].isEnabled = sender.text!.trimmingCharacters(in: .whitespaces).count > 0
  611. }
  612. }
  613. private func removeTopic(chatId: String, completion: @escaping (Bool) -> ()) {
  614. DispatchQueue.global().async {
  615. var result: Bool = false
  616. if let g = self.group, let response = DigiX.writeAndWait(message: CoreMessage_TMessageBank.getDeleteChat(chat_id: chatId, f_pin: g.id)), response.isOk() {
  617. result = true
  618. }
  619. completion(result)
  620. }
  621. }
  622. private func changePosition(pin: String, isAdmin: Bool = true, completion: @escaping (Bool) -> ()) {
  623. DispatchQueue.global().async {
  624. var result: Bool = false
  625. if let g = self.group, let response = DigiX.writeAndWait(message: CoreMessage_TMessageBank.getChangeGroupMemberPosition(p_group_id: g.id, p_pin: pin, p_position: isAdmin ? "1" : "0")), response.isOk() {
  626. result = true
  627. }
  628. completion(result)
  629. }
  630. }
  631. private func exitGroup(pin: String, completion: @escaping (Bool) -> ()) {
  632. DispatchQueue.global().async {
  633. var result: Bool = false
  634. if let g = self.group, let response = DigiX.writeAndWait(message: CoreMessage_TMessageBank.getExitGroup(p_group_id: g.id, p_pin: pin)), response.isOk() {
  635. result = true
  636. }
  637. completion(result)
  638. }
  639. }
  640. private func changeOpenGroup(open: String, completion: @escaping (Bool) -> ()) {
  641. DispatchQueue.global().async {
  642. var result: Bool = false
  643. if let g = self.group, let response = DigiX.writeAndWait(message: CoreMessage_TMessageBank.getChangeGroupInfo(p_group_id: g.id, p_open: open)), response.isOk() {
  644. result = true
  645. } else {
  646. result = false
  647. }
  648. completion(result)
  649. }
  650. }
  651. private func checkIsFriend(pin: String) -> Bool {
  652. var isFriend = true
  653. Database.shared.database?.inTransaction({ fmdb, rollback in
  654. if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select f_pin from BUDDY where f_pin = '\(pin)'"), cursor.next() {
  655. cursor.close()
  656. } else {
  657. isFriend = false
  658. }
  659. })
  660. return isFriend
  661. }
  662. // MARK: - Table view data source
  663. override func numberOfSections(in tableView: UITableView) -> Int {
  664. return sections.count
  665. }
  666. override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  667. guard let g = group else {
  668. return 1
  669. }
  670. switch sections[section] {
  671. case .topic:
  672. return isAdmin ? g.topics.count + 1 : g.topics.count
  673. case .detail:
  674. return 3
  675. case .member:
  676. return isAdmin ? g.members.count + 1 : g.members.count
  677. default:
  678. return 1
  679. }
  680. }
  681. override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
  682. switch sections[section] {
  683. case .description:
  684. return "Description".localized()
  685. case .topic:
  686. return "Topic".localized()
  687. case .detail:
  688. return "Detail".localized()
  689. case .member:
  690. return "Member".localized()
  691. default:
  692. return nil
  693. }
  694. }
  695. override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  696. switch sections[indexPath.section] {
  697. case .profile:
  698. let cell = tableView.dequeueReusableCell(withIdentifier: "profileCell", for: indexPath) as! ProfileCell
  699. cell.cover.image = UIImage(named: "Sofa", in: Bundle.resourceBundle(for: DigiX.self), with: nil)
  700. guard let g = group else {
  701. return cell
  702. }
  703. if let image = tempImage {
  704. cell.profile.image = image
  705. } else {
  706. getImage(name: g.profile, placeholderImage: UIImage(systemName: "person.2.circle.fill"), tableView: tableView, indexPath: indexPath) { result, isDownloaded, image in
  707. cell.profile.image = image
  708. }
  709. }
  710. return cell
  711. case .description:
  712. let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
  713. cell.accessoryView = nil
  714. cell.accessoryType = .disclosureIndicator
  715. var content = cell.defaultContentConfiguration()
  716. if let g = group {
  717. content.text = g.quote.isEmpty ? "No description".localized() : g.quote
  718. }
  719. cell.contentConfiguration = content
  720. cell.selectionStyle = .default
  721. return cell
  722. case .access:
  723. let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
  724. var content = cell.defaultContentConfiguration()
  725. if let g = group {
  726. if g.isOpen.isEmpty || g.isOpen == "0" {
  727. content.text = "Private".localized()
  728. content.secondaryText = "Only members can be access this group".localized()
  729. } else if g.isOpen == "1" {
  730. content.text = "Public".localized()
  731. content.secondaryText = "All user can be access this group".localized()
  732. }
  733. if isAdmin && group?.official != "1" {
  734. let changeOpen = UISwitch()
  735. changeOpen.isUserInteractionEnabled = false
  736. if g.isOpen == "1" {
  737. changeOpen.setOn(true, animated: true)
  738. } else {
  739. changeOpen.setOn(false, animated: true)
  740. }
  741. cell.accessoryView = changeOpen
  742. }
  743. }
  744. content.textProperties.color = .mainColor
  745. cell.contentConfiguration = content
  746. cell.accessoryType = .none
  747. return cell
  748. case .topic:
  749. let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
  750. cell.accessoryView = nil
  751. cell.accessoryType = .none
  752. var content = cell.defaultContentConfiguration()
  753. if let g = group {
  754. if indexPath.row == 0, isAdmin {
  755. content.image = UIImage(systemName: "plus.circle")
  756. content.imageProperties.tintColor = .mainColor
  757. content.text = "Add Topic".localized()
  758. cell.accessoryType = .disclosureIndicator
  759. cell.selectionStyle = .default
  760. } else {
  761. let topic = g.topics[isAdmin ? indexPath.row - 1 : indexPath.row]
  762. getImage(name: topic.thumb, placeholderImage: UIImage(systemName: "message.fill"), isCircle: true, tableView: tableView, indexPath: indexPath) { result, isDownloaded, image in
  763. content.image = image
  764. if !result {
  765. content.imageProperties.tintColor = .mainColor
  766. }
  767. }
  768. content.text = topic.title
  769. content.secondaryText = topic.description
  770. cell.selectionStyle = isAdmin ? .default : .none
  771. }
  772. }
  773. cell.contentConfiguration = content
  774. return cell
  775. case .detail:
  776. let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
  777. cell.accessoryView = nil
  778. cell.accessoryType = .none
  779. cell.selectionStyle = .none
  780. var content = cell.defaultContentConfiguration()
  781. content.prefersSideBySideTextAndSecondaryText = true
  782. if let g = group {
  783. switch indexPath.row {
  784. case 1:
  785. content.text = "Created date".localized()
  786. content.secondaryText = Date(milliseconds: Int64(g.date)!).format(dateFormat: "dd, MMM yyyy")
  787. case 2:
  788. content.text = "Members".localized()
  789. content.secondaryText = String(g.members.count)
  790. default:
  791. content.text = "Created by".localized()
  792. Database.shared.database?.inTransaction({ fmdb, rollback in
  793. if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select first_name || ' ' || ifnull(last_name, '') from BUDDY where f_pin = '\(g.by)'") {
  794. if cursor.next() {
  795. content.secondaryText = cursor.string(forColumnIndex: 0) ?? "Unknown".localized()
  796. }
  797. cursor.close()
  798. }
  799. })
  800. }
  801. }
  802. cell.contentConfiguration = content
  803. return cell
  804. case .member:
  805. let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
  806. cell.selectionStyle = isAdmin ? .default : .none
  807. cell.accessoryView = nil
  808. var content = cell.defaultContentConfiguration()
  809. content.prefersSideBySideTextAndSecondaryText = true
  810. if let g = group {
  811. if indexPath.row == 0, isAdmin {
  812. content.image = UIImage(systemName: "plus.circle")
  813. content.imageProperties.tintColor = .mainColor
  814. content.text = "Add Member".localized()
  815. cell.accessoryType = .disclosureIndicator
  816. } else {
  817. let member = g.members[isAdmin ? indexPath.row - 1 : indexPath.row]
  818. content.imageProperties.maximumSize = CGSize(width: 20, height: 20)
  819. getImage(name: member.thumb, placeholderImage: UIImage(systemName: "person.fill"), isCircle: true, tableView: tableView, indexPath: indexPath) { result, isDownloaded, image in
  820. content.image = image
  821. if !result {
  822. content.imageProperties.tintColor = .mainColor
  823. }
  824. }
  825. if member.userType == "23" || member.official == "1" {
  826. content.attributedText = self.set(image: UIImage(named: "ic_internal", in: Bundle.resourceBundle(for: DigiX.self), with: nil)!, with: " " + (member.firstName + " " + member.lastName).trimmingCharacters(in: .whitespaces), size: 15, y: 0)
  827. } else if member.userType == "24" {
  828. content.attributedText = self.set(image: UIImage(named: "pb_call_center", in: Bundle.resourceBundle(for: DigiX.self), with: nil)!, with: " " + (member.firstName + " " + member.lastName).trimmingCharacters(in: .whitespaces), size: 15, y: 0)
  829. } else {
  830. content.text = (member.firstName + " " + member.lastName).trimmingCharacters(in: .whitespaces)
  831. }
  832. if !checkIsFriend(pin: member.pin) {
  833. if member.position == "1" {
  834. content.secondaryAttributedText = self.set(image: UIImage(named: "pb_twsn_group_admin_11", in: Bundle.resourceBundle(for: DigiX.self), with: nil)!, image2: UIImage(named: "pb_add_contact", in: Bundle.resourceBundle(for: DigiX.self), with: nil)!, with: "", size: 20, y: 0, moreImage: true)
  835. } else {
  836. content.secondaryAttributedText = self.set(image: UIImage(named: "pb_add_contact", in: Bundle.resourceBundle(for: DigiX.self), with: nil)!, with: "", size: 20, y: 0)
  837. }
  838. } else {
  839. content.secondaryAttributedText = member.position == "1" ? self.set(image: UIImage(named: "pb_twsn_group_admin_11", in: Bundle.resourceBundle(for: DigiX.self), with: nil)!, with: "", size: 20, y: 0) : NSAttributedString(string: "")
  840. }
  841. cell.accessoryType = .none
  842. }
  843. }
  844. cell.contentConfiguration = content
  845. return cell
  846. case .exit:
  847. let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
  848. if let g = group {
  849. let idMe = UserDefaults.standard.string(forKey: "me") as String?
  850. let admins = g.members.filter { member in
  851. return member.position == "1"
  852. }
  853. var isDeleted = false
  854. if admins.count == 1 {
  855. if admins.first?.pin == idMe {
  856. isDeleted = true
  857. }
  858. }
  859. cell.accessoryView = nil
  860. cell.accessoryType = .none
  861. var content = cell.defaultContentConfiguration()
  862. content.text = isDeleted ? "Delete Group".localized() : "Exit Group".localized()
  863. content.textProperties.color = .red
  864. cell.contentConfiguration = content
  865. cell.selectionStyle = .default
  866. return cell
  867. }
  868. return cell
  869. }
  870. }
  871. override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
  872. switch sections[indexPath.section] {
  873. case .profile:
  874. return 200
  875. default:
  876. return UITableView.automaticDimension
  877. }
  878. }
  879. }
  880. // MARK: - Cell
  881. class ProfileCell: UITableViewCell {
  882. @IBOutlet weak var cover: UIImageView!
  883. @IBOutlet weak var profile: UIImageView!
  884. override func layoutSubviews() {
  885. super.layoutSubviews()
  886. profile.circle()
  887. }
  888. }
  889. // MARK: - Extension
  890. extension GroupDetailViewController: ImageVideoPickerDelegate {
  891. func didSelect(imagevideo: Any?) {
  892. if let info = imagevideo as? [UIImagePickerController.InfoKey: Any], let cell = tableView.cellForRow(at: IndexPath(row: 0, section: 0)) as? ProfileCell, let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
  893. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  894. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  895. imageView.tintColor = .white
  896. let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  897. banner.show()
  898. return
  899. }
  900. guard let g = group else {
  901. return
  902. }
  903. DispatchQueue.global().async {
  904. let resize = image.resize(target: CGSize(width: 800, height: 600))
  905. let documentDir = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
  906. let fileDir = documentDir.appendingPathComponent("THUMB_\(g.id)\(Date().currentTimeMillis().toHex())")
  907. if !FileManager.default.fileExists(atPath: fileDir.path), let data = resize.jpegData(compressionQuality: 0.8) {
  908. try! data.write(to: fileDir)
  909. DispatchQueue.main.async {
  910. DigiX.showLoader()
  911. }
  912. Network().upload(name: fileDir.lastPathComponent) { result, progress in
  913. guard result, progress == 100 else {
  914. return
  915. }
  916. if let response = DigiX.writeAndWait(message: CoreMessage_TMessageBank.getChangeGroupInfo(p_group_id: g.id, p_thumb_id: fileDir.lastPathComponent)), response.isOk() {
  917. Database.shared.database?.inTransaction({ fmdb, rollback in
  918. _ = Database.shared.updateRecord(fmdb: fmdb, table: "GROUPZ", cvalues: ["image_id": fileDir.lastPathComponent], _where: "group_id = '\(g.id)'")
  919. DispatchQueue.main.async {
  920. DigiX.hideLoader(completion: {
  921. self.tempImage = image
  922. cell.profile.image = self.tempImage
  923. })
  924. }
  925. })
  926. } else {
  927. DispatchQueue.main.async {
  928. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  929. imageView.tintColor = .white
  930. let banner = FloatingNotificationBanner(title: "Unable to access servers".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  931. banner.show()
  932. }
  933. }
  934. }
  935. }
  936. }
  937. }
  938. }
  939. func set(image: UIImage, image2: UIImage = UIImage(), with text: String, size: CGFloat, y: CGFloat, moreImage: Bool = false) -> NSAttributedString {
  940. let attachment = NSTextAttachment()
  941. let attachment2 = NSTextAttachment()
  942. attachment.image = image
  943. attachment.bounds = CGRect(x: 0, y: y, width: size, height: size)
  944. attachment2.image = image2
  945. attachment2.bounds = CGRect(x: 0, y: y, width: size, height: size)
  946. let attachmentStr = NSAttributedString(attachment: attachment)
  947. let attachmentStr2 = NSAttributedString(attachment: attachment2)
  948. let mutableAttributedString = NSMutableAttributedString()
  949. if moreImage {
  950. mutableAttributedString.append(attachmentStr2)
  951. }
  952. mutableAttributedString.append(attachmentStr)
  953. let textString = NSAttributedString(string: text)
  954. mutableAttributedString.append(textString)
  955. return mutableAttributedString
  956. }
  957. }