123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404 |
- // _____ _
- // |_ _| |_ _ _ ___ ___ _ __ __ _
- // | | | ' \| '_/ -_) -_) ' \/ _` |_
- // |_| |_||_|_| \___\___|_|_|_\__,_(_)
- //
- // Threema iOS Client
- // Copyright (c) 2020 Threema GmbH
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU Affero General Public License, version 3,
- // as published by the Free Software Foundation.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU Affero General Public License for more details.
- //
- // You should have received a copy of the GNU Affero General Public License
- // along with this program. If not, see <https://www.gnu.org/licenses/>.
- import UIKit
- class GlobalNotificationSettingsViewController: ThemedTableViewController {
- @IBOutlet weak var inAppSoundsSwitch: UISwitch!
- @IBOutlet weak var inAppVibrateSwitch: UISwitch!
- @IBOutlet weak var inAppPreviewSwitch: UISwitch!
- @IBOutlet weak var inAppSoundsLabel: UILabel!
- @IBOutlet weak var inAppVibrateLabel: UILabel!
- @IBOutlet weak var inAppPreviewLabel: UILabel!
-
- @IBOutlet weak var pushSoundLabel: UILabel!
- @IBOutlet weak var pushGroupSoundLabel: UILabel!
- @IBOutlet weak var pushDecryptLabel: UILabel!
- @IBOutlet weak var pushShowNicknameLabel: UILabel!
-
- @IBOutlet weak var pushSoundValueLabel: UILabel!
- @IBOutlet weak var pushGroupSoundValueLabel: UILabel!
- @IBOutlet weak var pushGroupSoundCell: UITableViewCell!
- @IBOutlet weak var pushDecryptSwitch: UISwitch!
-
- @IBOutlet weak var pushPreviewCell: UITableViewCell!
-
- @IBOutlet weak var voIPSoundLabel: UILabel!
- @IBOutlet weak var voIPSoundValueLabel: UILabel!
- @IBOutlet weak var pushShowNicknameSwitch: UISwitch!
-
- @IBOutlet weak var masterDndLabel: UILabel!
- @IBOutlet weak var masterDndSwitch: UISwitch!
-
- @IBOutlet weak var masterDndDaysCell: UITableViewCell!
- @IBOutlet weak var masterDndStartTimeCell: UITableViewCell!
- @IBOutlet weak var masterDndEndTimeCell: UITableViewCell!
- @IBOutlet weak var masterDndDaysLabel: UILabel!
- @IBOutlet weak var masterDndDaysValueLabel: UILabel!
- @IBOutlet weak var masterDndStartTimeLabel: UILabel!
- @IBOutlet weak var masterDndStartTimeValueLabel: UILabel!
- @IBOutlet weak var masterDndEndTimeLabel: UILabel!
- @IBOutlet weak var masterDndEndTimeValueLabel: UILabel!
-
- let mdmSetup: MDMSetup
-
- var timePickerIndexPath: IndexPath?
- var selectedCellForPickerIndexPath: IndexPath?
-
- typealias TimeOfDay = (hour: Int, minute: Int)
-
- required init?(coder aDecoder: NSCoder) {
- self.mdmSetup = MDMSetup(setup: false)
- super.init(coder: aDecoder)
- }
-
- override func viewDidLoad() {
- super.viewDidLoad()
-
- tableView.register(UINib(nibName: TimePickerwCell.nibName(), bundle: nil), forCellReuseIdentifier: TimePickerwCell.reuseIdentifier())
- }
-
- override func viewWillAppear(_ animated: Bool) {
- super.viewWillAppear(animated)
-
- self.setupSwitches()
- self.setupLabels()
-
- self.tableView.reloadData()
- }
-
- override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
- if segue.identifier == "EditPushGroupSound" {
- if let psvc = segue.destination as? PushSoundViewController {
- psvc.group = true
- }
- }
- }
-
- // MARK Private functions
-
- private func setupSwitches() {
- self.inAppSoundsSwitch.isOn = UserSettings.shared().inAppSounds
- self.inAppVibrateSwitch.isOn = UserSettings.shared().inAppVibrate
- self.inAppPreviewSwitch.isOn = UserSettings.shared().inAppPreview
- self.pushShowNicknameSwitch.isOn = UserSettings.shared().pushShowNickname
- self.pushDecryptSwitch.isOn = UserSettings.shared().pushDecrypt
- self.masterDndSwitch.isOn = UserSettings.shared().enableMasterDnd
-
- self.pushDecryptSwitch.isEnabled = !mdmSetup.existsMdmKey(MDM_KEY_DISABLE_MESSAGE_PREVIEW)
- }
-
- private func setupLabels() {
- self.inAppSoundsLabel.text = BundleUtil.localizedString(forKey: "settings_notifications_inapp_sounds")
- self.inAppVibrateLabel.text = BundleUtil.localizedString(forKey: "settings_notifications_inapp_vibrate")
- self.inAppPreviewLabel.text = BundleUtil.localizedString(forKey: "settings_notifications_inapp_preview")
-
- self.pushSoundLabel.text = BundleUtil.localizedString(forKey: "settings_notifications_push_sound")
- self.pushGroupSoundLabel.text = BundleUtil.localizedString(forKey: "settings_notifications_push_groupsound")
- self.pushDecryptLabel.text = BundleUtil.localizedString(forKey: "settings_notifications_push_preview")
- self.pushShowNicknameLabel.text = BundleUtil.localizedString(forKey: "settings_notifications_push_showNickname")
-
- self.voIPSoundLabel.text = BundleUtil.localizedString(forKey: "settings_notifications_call_sound")
-
- let pushSoundName = "sound_\(UserSettings.shared().pushSound!)"
- self.pushSoundValueLabel.text = BundleUtil.localizedString(forKey: pushSoundName)
-
- let pushGroupSoundName = "sound_\(UserSettings.shared().pushGroupSound!)"
- self.pushGroupSoundValueLabel.text = BundleUtil.localizedString(forKey: pushGroupSoundName)
- let voIPSoundName = "sound_\(UserSettings.shared().voIPSound!)"
- self.voIPSoundValueLabel.text = BundleUtil.localizedString(forKey: voIPSoundName)
-
- self.masterDndLabel.text = BundleUtil.localizedString(forKey: "settings_notifications_masterDnd")
- self.masterDndDaysLabel.text = BundleUtil.localizedString(forKey: "settings_notifications_masterDnd_workingDays")
-
- var workingDayShortString = ""
- let workingDays = UserSettings.shared().masterDndWorkingDays!
-
- if workingDays.count > 0 {
- let sortedWorkingDays = workingDays.sortedArray { (a, b) -> ComparisonResult in
- var dayA = a as! Int
- var dayB = b as! Int
-
- if dayA < Calendar.current.firstWeekday {
- dayA += Calendar.current.weekdaySymbols.count
- }
- if dayB < Calendar.current.firstWeekday {
- dayB += Calendar.current.weekdaySymbols.count
- }
-
- if dayA < dayB {
- return .orderedAscending
- }
- if dayA > dayB {
- return .orderedDescending
- }
- return .orderedSame
- }
-
- for dayNumber in sortedWorkingDays {
- if workingDayShortString.count > 0 {
- workingDayShortString.append(", ")
- }
- workingDayShortString.append(Calendar.current.shortWeekdaySymbols[(dayNumber as! Int)-1])
- }
- self.masterDndDaysValueLabel.text = workingDayShortString
- } else {
- self.masterDndDaysValueLabel.text = ""
- }
-
- self.masterDndStartTimeLabel.text = BundleUtil.localizedString(forKey: "settings_notifications_masterDnd_startTime")
- self.masterDndStartTimeValueLabel.text = UserSettings.shared().masterDndStartTime
- self.masterDndEndTimeLabel.text = BundleUtil.localizedString(forKey: "settings_notifications_masterDnd_endTime")
- self.masterDndEndTimeValueLabel.text = UserSettings.shared().masterDndEndTime
- self.pushDecryptLabel.isEnabled = !mdmSetup.existsMdmKey(MDM_KEY_DISABLE_MESSAGE_PREVIEW)
- }
-
- // MARK IBActions
-
- @IBAction func inAppSoundsChanged(sender: UISwitch) {
- UserSettings.shared().inAppSounds = self.inAppSoundsSwitch.isOn
- }
-
- @IBAction func inAppVibrateChanged(sender: UISwitch) {
- UserSettings.shared().inAppVibrate = self.inAppVibrateSwitch.isOn
- }
-
- @IBAction func inAppPreviewChanged(sender: UISwitch) {
- UserSettings.shared().inAppPreview = self.inAppPreviewSwitch.isOn
- }
-
- @IBAction func pushDecryptChanged(sender: UISwitch) {
- UserSettings.shared().pushDecrypt = self.pushDecryptSwitch.isOn
- }
-
- @IBAction func pushShowNicknameChanged(sender: UISwitch) {
- UserSettings.shared()?.pushShowNickname = self.pushShowNicknameSwitch.isOn
- }
-
- @IBAction func masterDndChanged(sender: UISwitch) {
- UserSettings.shared().enableMasterDnd = sender.isOn
- self.tableView.beginUpdates()
- if let timePickerIndexPath = timePickerIndexPath {
- tableView.deleteRows(at: [timePickerIndexPath], with: .fade)
- self.timePickerIndexPath = nil
- self.selectedCellForPickerIndexPath = nil
- }
- self.tableView.reloadSections(IndexSet(integer: 3), with: .none)
- self.tableView.endUpdates()
- }
- // MARK: - Table view data source
-
- override func numberOfSections(in tableView: UITableView) -> Int {
- if LicenseStore.requiresLicenseKey() == true {
- return 4
- }
- return 3
- }
-
- override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- if timePickerIndexPath != nil, section == timePickerIndexPath?.section {
- return super.tableView(tableView, numberOfRowsInSection: section) + 1
- }
- if section == 3, !masterDndSwitch.isOn {
- return 1
- }
- return super.tableView(tableView, numberOfRowsInSection: section)
- }
-
- override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
- if timePickerIndexPath == indexPath {
- return TimePickerwCell.cellHeight()
- } else {
- return super.tableView(tableView, estimatedHeightForRowAt: indexPath)
- }
- }
-
- override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
- if timePickerIndexPath == indexPath {
- return TimePickerwCell.cellHeight()
- } else {
- return super.tableView(tableView, heightForRowAt: indexPath)
- }
- }
-
- override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- if timePickerIndexPath == indexPath {
- let dateCell = tableView.cellForRow(at: selectedCellForPickerIndexPath!)
- let datePickerCell = tableView.dequeueReusableCell(withIdentifier: TimePickerwCell.reuseIdentifier()) as! TimePickerwCell
- var time = "00:00"
-
- if dateCell?.tag == 1 {
- time = UserSettings.shared().masterDndStartTime!
- }
- if dateCell?.tag == 2 {
- time = UserSettings.shared().masterDndEndTime!
- }
- let date = dateFromTimeString(timeString: time)
- datePickerCell.updateCell(date: date, indexPath: indexPath)
- datePickerCell.delegate = self
- return datePickerCell
- } else {
- if timePickerIndexPath != nil, indexPath.section == 3, indexPath.row >= timePickerIndexPath!.row {
- let newIndexPath = IndexPath(row: indexPath.row - 1, section: indexPath.section)
- return super.tableView(tableView, cellForRowAt: newIndexPath)
- } else {
- return super.tableView(tableView, cellForRowAt: indexPath)
- }
- }
- }
-
- override func tableView(_ tableView: UITableView, indentationLevelForRowAt indexPath: IndexPath) -> Int {
- return 0
- }
-
- override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
- switch section {
- case 0:
- return BundleUtil.localizedString(forKey: "settings_notifications_inapp_section")
- case 1:
- return BundleUtil.localizedString(forKey: "settings_notifications_push_section")
- case 2:
- return BundleUtil.localizedString(forKey: "settings_notifications_call_section")
- case 3:
- return BundleUtil.localizedString(forKey: "settings_notifications_masterDnd_section_header")
- default:
- return nil
- }
- }
-
- override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
- switch section {
- case 1:
- if mdmSetup.disableMessagePreview() {
- return BundleUtil.localizedString(forKey: "disabled_by_device_policy")
- }
- case 3:
- return BundleUtil.localizedString(forKey: "settings_notifications_masterDnd_section_footer")
- default:
- return nil
- }
- return nil
- }
-
- override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
- let cell = tableView.cellForRow(at: indexPath)
- var scrollToPicker = false
- if cell?.tag == 1 || cell?.tag == 2 {
- tableView.beginUpdates()
- if let timePickerIndexPath = timePickerIndexPath, timePickerIndexPath.row - 1 == indexPath.row {
- tableView.deleteRows(at: [timePickerIndexPath], with: .fade)
- self.timePickerIndexPath = nil
- self.selectedCellForPickerIndexPath = nil
- } else {
- if let timePickerIndexPath = timePickerIndexPath {
- tableView.deleteRows(at: [timePickerIndexPath], with: .fade)
- }
- timePickerIndexPath = indexPathToInsertTimePicker(indexPath: indexPath)
- selectedCellForPickerIndexPath = indexPath
- tableView.insertRows(at: [timePickerIndexPath!], with: .fade)
- scrollToPicker = true
- }
- tableView.endUpdates()
- } else {
- if let timePickerIndexPath = timePickerIndexPath {
- tableView.beginUpdates()
- tableView.deleteRows(at: [timePickerIndexPath], with: .fade)
- self.timePickerIndexPath = nil
- self.selectedCellForPickerIndexPath = nil
- tableView.endUpdates()
- }
- }
-
- tableView.deselectRow(at: tableView.indexPathForSelectedRow!, animated: true)
- if scrollToPicker {
- tableView.scrollToRow(at: timePickerIndexPath!, at: .middle, animated: true)
- }
- }
-
- // MARK: private functions
-
- private func indexPathToInsertTimePicker(indexPath: IndexPath) -> IndexPath {
- if let timePickerIndexPath = timePickerIndexPath, timePickerIndexPath.row < indexPath.row {
- return indexPath
- } else {
- return IndexPath(row: indexPath.row + 1, section: indexPath.section)
- }
- }
-
- private func timeOfDayFromTimeString(timeString: String) -> TimeOfDay {
- let components: [String] = timeString.components(separatedBy: ":")
- return TimeOfDay(hour: Int(components[0])!, minute: Int(components[1])!)
- }
-
- private func dateFromTimeString(timeString: String) -> Date {
- let components: [String] = timeString.components(separatedBy: ":")
- return Calendar.current.date(bySettingHour: Int(components[0])!, minute: Int(components[1])!, second: 0, of: Date())!
- }
- }
- extension GlobalNotificationSettingsViewController: TimePickerDelegate {
- func didChangeTime(date: Date, indexPath: IndexPath) {
- let cell = tableView.cellForRow(at: indexPath)
- let calendar = Calendar.current
-
- let hour = calendar.component(.hour, from: date)
- let minute = calendar.component(.minute, from: date)
- let newTimeString = String(format: "%02d:%02d", hour, minute)
-
- if cell?.tag == 1 {
- let newStartTime = timeOfDayFromTimeString(timeString: newTimeString)
- let endTime = timeOfDayFromTimeString(timeString: UserSettings.shared().masterDndEndTime)
-
- if newStartTime < endTime {
- UserSettings.shared().masterDndStartTime = newTimeString
- self.masterDndStartTimeValueLabel.text = newTimeString
- } else {
- if timePickerIndexPath != nil {
- if let datePickerCell = self.tableView.cellForRow(at: timePickerIndexPath!) as? TimePickerwCell {
- let date = dateFromTimeString(timeString: UserSettings.shared().masterDndStartTime)
- datePickerCell.updateCell(date: date, indexPath: timePickerIndexPath!)
- }
- }
- }
- }
- if cell?.tag == 2 {
- let newEndTime = timeOfDayFromTimeString(timeString: newTimeString)
- let startTime = timeOfDayFromTimeString(timeString: UserSettings.shared().masterDndStartTime)
-
- if newEndTime > startTime {
- UserSettings.shared().masterDndEndTime = newTimeString
- self.masterDndEndTimeValueLabel.text = newTimeString
- } else {
- if timePickerIndexPath != nil {
- if let datePickerCell = self.tableView.cellForRow(at: timePickerIndexPath!) as? TimePickerwCell {
- let date = dateFromTimeString(timeString: UserSettings.shared().masterDndEndTime)
- datePickerCell.updateCell(date: date, indexPath: timePickerIndexPath!)
- }
- }
- }
- }
- }
- }
|