NotificationSound.swift 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. //
  2. // NotificationSound.swift
  3. // NexilisLite
  4. //
  5. // Created by Akhmad Al Qindi Irsyam on 28/11/22.
  6. //
  7. import UIKit
  8. import AVFoundation
  9. public class NotificationSound: UIViewController, UITableViewDelegate, UITableViewDataSource {
  10. public var isPersonal = true
  11. let tableView = UITableView()
  12. var data: [NotifSound] = []
  13. var isSelectedSound = 0
  14. var lastSelectedSound = 0
  15. public override func viewDidLoad() {
  16. super.viewDidLoad()
  17. let attributes = [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 16.0), NSAttributedString.Key.foregroundColor: UIColor.white]
  18. let navBarAppearance = UINavigationBarAppearance()
  19. navBarAppearance.configureWithOpaqueBackground()
  20. navBarAppearance.backgroundColor = self.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : UIColor.mainColor
  21. navBarAppearance.titleTextAttributes = attributes
  22. navigationController?.navigationBar.standardAppearance = navBarAppearance
  23. navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
  24. view.addSubview(tableView)
  25. tableView.translatesAutoresizingMaskIntoConstraints = false
  26. tableView.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor).isActive = true
  27. tableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
  28. tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
  29. tableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
  30. tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellNotifSound")
  31. tableView.delegate = self
  32. tableView.dataSource = self
  33. self.title = "Notification Message(s)".localized()
  34. if !isPersonal {
  35. self.title = "Notification Message(s) Group".localized()
  36. }
  37. navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Cancel".localized(), style: .plain, target: self, action: #selector(cancel(sender:)))
  38. navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Save".localized(), style: .plain, target: self, action: #selector(save(sender:)))
  39. data.append(NotifSound(id: 001, name: "Nexilis Message (Default)", isSelected: false))
  40. data.append(NotifSound(id: 002, name: "Dutifully", isSelected: false))
  41. data.append(NotifSound(id: 003, name: "Elegant", isSelected: false))
  42. data.append(NotifSound(id: 004, name: "Eventually", isSelected: false))
  43. data.append(NotifSound(id: 005, name: "Hangover", isSelected: false))
  44. data.append(NotifSound(id: 006, name: "Juntos", isSelected: false))
  45. data.append(NotifSound(id: 007, name: "Light Hearted", isSelected: false))
  46. data.append(NotifSound(id: 008, name: "Magic", isSelected: false))
  47. data.append(NotifSound(id: 009, name: "Out of Nowhere", isSelected: false))
  48. data.append(NotifSound(id: 010, name: "Relax", isSelected: false))
  49. data.append(NotifSound(id: 011, name: "Strong Minded", isSelected: false))
  50. data.append(NotifSound(id: 012, name: "Swift gesture", isSelected: false))
  51. data.append(NotifSound(id: 013, name: "Upset", isSelected: false))
  52. var selectedSound: String = SecureUserDefaults.shared.value(forKey: "newNotifSoundPersonal") ?? ""
  53. if !isPersonal {
  54. selectedSound = SecureUserDefaults.shared.value(forKey: "newNotifSoundGroup") ?? ""
  55. }
  56. if !selectedSound.isEmpty {
  57. let selectedSoundId = Int(selectedSound.components(separatedBy: ":")[0])
  58. let idx = data.firstIndex(where: {$0.id == selectedSoundId})
  59. if idx != nil {
  60. data[idx!].isSelected = true
  61. isSelectedSound = selectedSoundId!
  62. } else {
  63. data[0].isSelected = true
  64. isSelectedSound = 001
  65. }
  66. } else {
  67. data[0].isSelected = true
  68. isSelectedSound = 001
  69. }
  70. }
  71. @objc func cancel(sender: Any) {
  72. navigationController?.dismiss(animated: true, completion: nil)
  73. }
  74. @objc func save(sender: Any) {
  75. let idx = data.firstIndex(where: {$0.id == isSelectedSound})
  76. if isPersonal {
  77. SecureUserDefaults.shared.set("\(data[idx!].id):\(data[idx!].name)", forKey: "newNotifSoundPersonal")
  78. } else {
  79. SecureUserDefaults.shared.set("\(data[idx!].id):\(data[idx!].name)", forKey: "newNotifSoundGroup")
  80. }
  81. //stopSound
  82. if Nexilis.sharedAudioPlayer != nil && Nexilis.sharedAudioPlayer!.isPlaying {
  83. Nexilis.sharedAudioPlayer?.stop()
  84. }
  85. navigationController?.dismiss(animated: true, completion: nil)
  86. }
  87. // MARK: - Table view data source
  88. public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  89. let idx = data.firstIndex(where: {$0.id == isSelectedSound})
  90. data[idx!].isSelected = false
  91. let idxNew = data.firstIndex(where: {$0.id == data[indexPath.row].id})
  92. data[idxNew!].isSelected = true
  93. if lastSelectedSound != 0 {
  94. //stopSound
  95. Nexilis.sharedAudioPlayer?.stop()
  96. }
  97. lastSelectedSound = data[indexPath.row].id
  98. isSelectedSound = data[indexPath.row].id
  99. //playSound
  100. var nameSound = data[indexPath.row].name.replacingOccurrences(of: " ", with: "_")
  101. var fromPref = false
  102. if nameSound.contains("_(Default)") {
  103. if !Utils.getDefaultIncomingMsg().isEmpty {
  104. nameSound = Utils.getDefaultIncomingMsg()
  105. fromPref = true
  106. } else {
  107. nameSound = nameSound.replacingOccurrences(of: "_(Default)", with: "")
  108. }
  109. }
  110. var soundURL: URL?
  111. if fromPref {
  112. let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
  113. let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
  114. let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
  115. if let dirPath = paths.first {
  116. let audioURL = URL(fileURLWithPath: dirPath).appendingPathComponent(nameSound)
  117. if !FileManager.default.fileExists(atPath: audioURL.path) && !FileEncryption.shared.isSecureExists(filename: nameSound) {
  118. Download().startHTTP(forKey: nameSound,downloadUrl: Utils.getURLBase() + "filepalio/ringtone/") { (name, progress) in
  119. guard progress == 100 else {
  120. return
  121. }
  122. playAudio()
  123. }
  124. } else {
  125. playAudio()
  126. }
  127. func playAudio() {
  128. if FileManager.default.fileExists(atPath: audioURL.path) {
  129. do {
  130. do {
  131. try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
  132. try AVAudioSession.sharedInstance().setActive(true)
  133. } catch {
  134. }
  135. Nexilis.sharedAudioPlayer = try AVAudioPlayer(contentsOf: audioURL)
  136. Nexilis.sharedAudioPlayer?.prepareToPlay()
  137. Nexilis.sharedAudioPlayer?.play()
  138. } catch {
  139. }
  140. } else if FileEncryption.shared.isSecureExists(filename: nameSound) {
  141. do {
  142. if let audioData = try FileEncryption.shared.readSecure(filename: nameSound) {
  143. let cachesDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
  144. let tempPath = cachesDirectory.appendingPathComponent(nameSound)
  145. try audioData.write(to: tempPath)
  146. do {
  147. do {
  148. try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
  149. try AVAudioSession.sharedInstance().setActive(true)
  150. } catch {
  151. }
  152. Nexilis.sharedAudioPlayer = try AVAudioPlayer(contentsOf: tempPath)
  153. Nexilis.sharedAudioPlayer?.prepareToPlay()
  154. Nexilis.sharedAudioPlayer?.play()
  155. } catch {
  156. }
  157. }
  158. } catch {
  159. }
  160. }
  161. }
  162. }
  163. } else {
  164. soundURL = Bundle.resourceBundle(for: Nexilis.self).url(forResource: nameSound, withExtension: "mp3")
  165. if soundURL == nil {
  166. soundURL = Bundle.resourcesMediaBundle(for: Nexilis.self).url(forResource: nameSound, withExtension: "mp3")
  167. }
  168. do {
  169. do {
  170. try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
  171. try AVAudioSession.sharedInstance().setActive(true)
  172. } catch {
  173. }
  174. Nexilis.sharedAudioPlayer = try AVAudioPlayer(contentsOf: soundURL!)
  175. Nexilis.sharedAudioPlayer?.prepareToPlay()
  176. Nexilis.sharedAudioPlayer?.play()
  177. } catch {
  178. }
  179. }
  180. tableView.reloadData()
  181. }
  182. public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  183. return data.count
  184. }
  185. public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  186. let cell = tableView.dequeueReusableCell(withIdentifier: "cellNotifSound", for: indexPath)
  187. var content = cell.defaultContentConfiguration()
  188. content.text = data[indexPath.row].name
  189. cell.contentConfiguration = content
  190. cell.accessoryType = data[indexPath.row].isSelected ? .checkmark : .none
  191. cell.selectionStyle = .none
  192. return cell
  193. }
  194. }