Browse Source

Merge pull request #620 from deltachat/autodelete2

ui for autodelete
cyBerta 5 years ago
parent
commit
8db6dbb944

+ 1 - 0
.swiftlint.yml

@@ -8,6 +8,7 @@ disabled_rules:
 - todo
 - trailing_whitespace
 - type_body_length
+- for_where
 
 excluded:
 - Carthage

+ 8 - 0
deltachat-ios.xcodeproj/project.pbxproj

@@ -159,6 +159,8 @@
 		AEE6EC482283045D00EDC689 /* EditSettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEE6EC472283045D00EDC689 /* EditSettingsController.swift */; };
 		AEFBE22F23FEF23D0045327A /* ProviderInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEFBE22E23FEF23D0045327A /* ProviderInfoCell.swift */; };
 		AEFBE23123FF09B20045327A /* TypeAlias.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEFBE23023FF09B20045327A /* TypeAlias.swift */; };
+		B20462E42440A4A600367A57 /* SettingsAutodelOverviewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B20462E32440A4A600367A57 /* SettingsAutodelOverviewController.swift */; };
+		B20462E62440C99600367A57 /* SettingsAutodelSetController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B20462E52440C99600367A57 /* SettingsAutodelSetController.swift */; };
 		B21005DB23383664004C70C5 /* SettingsClassicViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B21005DA23383664004C70C5 /* SettingsClassicViewController.swift */; };
 		B26B3BC7236DC3DC008ED35A /* SwitchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B26B3BC6236DC3DC008ED35A /* SwitchCell.swift */; };
 /* End PBXBuildFile section */
@@ -398,6 +400,8 @@
 		B20462E02440805C00367A57 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/InfoPlist.strings; sourceTree = "<group>"; };
 		B20462E12440805C00367A57 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/Localizable.strings; sourceTree = "<group>"; };
 		B20462E22440805C00367A57 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = id; path = id.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
+		B20462E32440A4A600367A57 /* SettingsAutodelOverviewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsAutodelOverviewController.swift; sourceTree = "<group>"; };
+		B20462E52440C99600367A57 /* SettingsAutodelSetController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsAutodelSetController.swift; sourceTree = "<group>"; };
 		B21005DA23383664004C70C5 /* SettingsClassicViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsClassicViewController.swift; sourceTree = "<group>"; };
 		B253ED992336E759004DD215 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/InfoPlist.strings; sourceTree = "<group>"; };
 		B253ED9A2336E759004DD215 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = "<group>"; };
@@ -773,6 +777,8 @@
 				30149D9222F21129003C12B5 /* QrViewController.swift */,
 				B21005DA23383664004C70C5 /* SettingsClassicViewController.swift */,
 				78E45E3921D3CFBC00D4B15E /* SettingsController.swift */,
+				B20462E32440A4A600367A57 /* SettingsAutodelOverviewController.swift */,
+				B20462E52440C99600367A57 /* SettingsAutodelSetController.swift */,
 				AE76E5ED242BF2EA003CF461 /* WelcomeViewController.swift */,
 			);
 			path = Controller;
@@ -1180,6 +1186,7 @@
 				7AE0A5491FC42F65005ECB4B /* NewChatViewController.swift in Sources */,
 				305961E52346125100C80F33 /* LabelAlignment.swift in Sources */,
 				AE77838F23E4276D0093EABD /* ContactCellViewModel.swift in Sources */,
+				B20462E62440C99600367A57 /* SettingsAutodelSetController.swift in Sources */,
 				305961E82346125100C80F33 /* Sender.swift in Sources */,
 				305961EE2346125100C80F33 /* AvatarPosition.swift in Sources */,
 				3015634423A003BA00E9DEF4 /* AudioRecorderController.swift in Sources */,
@@ -1234,6 +1241,7 @@
 				305962092346125100C80F33 /* AudioMessageSizeCalculator.swift in Sources */,
 				305961DB2346125100C80F33 /* AudioItem.swift in Sources */,
 				305962012346125100C80F33 /* PlayButtonView.swift in Sources */,
+				B20462E42440A4A600367A57 /* SettingsAutodelOverviewController.swift in Sources */,
 				789E879D21D6DF86003ED1C5 /* ProgressHud.swift in Sources */,
 				305961F32346125100C80F33 /* MediaMessageCell.swift in Sources */,
 				305962102346154D00C80F33 /* String+Extension.swift in Sources */,

+ 115 - 0
deltachat-ios/Controller/SettingsAutodelOverviewController.swift

@@ -0,0 +1,115 @@
+import UIKit
+
+class SettingsAutodelOverviewController: UITableViewController {
+
+    var dcContext: DcContext
+
+    private struct SectionConfigs {
+        let headerTitle: String?
+        let footerTitle: String?
+        let cells: [UITableViewCell]
+    }
+
+    private enum CellTags: Int {
+        case autodelDevice = 0
+        case autodelServer = 1
+    }
+
+    func autodelSummary() -> String {
+        return String.localized("off")
+    }
+
+    private lazy var autodelDeviceCell: UITableViewCell = {
+        let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
+        cell.tag = CellTags.autodelDevice.rawValue
+        cell.textLabel?.text = String.localized("autodel_device_title")
+        cell.accessoryType = .disclosureIndicator
+        cell.detailTextLabel?.text = SettingsAutodelSetController.getSummary(dcContext, fromServer: false)
+        return cell
+    }()
+
+    private lazy var autodelServerCell: UITableViewCell = {
+        let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
+        cell.tag = CellTags.autodelServer.rawValue
+        cell.textLabel?.text = String.localized("autodel_server_title")
+        cell.accessoryType = .disclosureIndicator
+        cell.detailTextLabel?.text = SettingsAutodelSetController.getSummary(dcContext, fromServer: true)
+        return cell
+    }()
+
+    private lazy var sections: [SectionConfigs] = {
+        let autodelSection = SectionConfigs(
+            headerTitle: nil,
+            footerTitle: nil,
+            cells: [autodelDeviceCell]
+        )
+        let autodelSection2 = SectionConfigs(
+            headerTitle: nil,
+            footerTitle: nil,
+            cells: [autodelServerCell]
+        )
+        return [autodelSection, autodelSection2]
+    }()
+
+    init(dcContext: DcContext) {
+        self.dcContext = dcContext
+        super.init(style: .grouped)
+        self.title = String.localized("autodel_title")
+        hidesBottomBarWhenPushed = true
+    }
+
+    required init?(coder aDecoder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+
+    override func viewDidLoad() {
+        super.viewDidLoad()
+    }
+
+    override func viewWillAppear(_ animated: Bool) {
+        super.viewWillAppear(animated)
+        autodelDeviceCell.detailTextLabel?.text = SettingsAutodelSetController.getSummary(dcContext, fromServer: false)
+        autodelServerCell.detailTextLabel?.text = SettingsAutodelSetController.getSummary(dcContext, fromServer: true)
+    }
+
+    // MARK: - Table view data source
+
+    override func numberOfSections(in tableView: UITableView) -> Int {
+        return sections.count
+    }
+
+    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+        return sections[section].cells.count
+    }
+
+    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+        return sections[indexPath.section].cells[indexPath.row]
+    }
+
+    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
+        return sections[section].headerTitle
+    }
+
+    override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
+        return sections[section].footerTitle
+    }
+
+    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+        guard let cell = tableView.cellForRow(at: indexPath), let cellTag = CellTags(rawValue: cell.tag) else {
+            safe_fatalError()
+            return
+        }
+        tableView.deselectRow(at: indexPath, animated: false) // to achieve highlight effect
+
+        switch cellTag {
+        case .autodelDevice:
+            let controller = SettingsAutodelSetController(dcContext: dcContext, fromServer: false)
+            navigationController?.pushViewController(controller, animated: true)
+
+        case .autodelServer:
+            let controller = SettingsAutodelSetController(dcContext: dcContext, fromServer: true)
+            navigationController?.pushViewController(controller, animated: true)
+        }
+
+    }
+}

+ 156 - 0
deltachat-ios/Controller/SettingsAutodelSetController.swift

@@ -0,0 +1,156 @@
+import UIKit
+
+class SettingsAutodelSetController: UITableViewController {
+
+    var dcContext: DcContext
+
+    private struct Options {
+        let value: Int
+        let descr: String
+    }
+
+    private static let autodelDeviceOptions: [Options] = {
+        return [
+            Options(value: 0, descr: "off"),
+            Options(value: 3600, descr: "autodel_after_1_hour"),
+            Options(value: 86400, descr: "autodel_after_1_day"),
+            Options(value: 604800, descr: "autodel_after_1_week"),
+            Options(value: 2419200, descr: "autodel_after_4_weeks"),
+        ]
+    }()
+
+    private static let autodelServerOptions: [Options] = {
+        return [
+            Options(value: 0, descr: "off"),
+            Options(value: 1, descr: "autodel_at_once"),
+            Options(value: 3600, descr: "autodel_after_1_hour"),
+            Options(value: 86400, descr: "autodel_after_1_day"),
+            Options(value: 604800, descr: "autodel_after_1_week"),
+            Options(value: 2419200, descr: "autodel_after_4_weeks"),
+        ]
+    }()
+
+    private lazy var autodelOptions: [Options] = {
+        return fromServer ? SettingsAutodelSetController.autodelServerOptions : SettingsAutodelSetController.autodelDeviceOptions
+    }()
+
+    var fromServer: Bool
+    var currVal: Int
+
+    private var cancelButton: UIBarButtonItem {
+        let button =  UIBarButtonItem(title: String.localized("cancel"), style: .plain, target: self, action: #selector(cancelButtonPressed))
+        return button
+    }
+
+    private var okButton: UIBarButtonItem {
+        let button =  UIBarButtonItem(title: String.localized("ok"), style: .done, target: self, action: #selector(okButtonPressed))
+        return button
+    }
+
+    var staticCells: [UITableViewCell] {
+        return autodelOptions.map({
+            let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
+            cell.textLabel?.text = String.localized($0.descr)
+            cell.selectionStyle = .none
+            cell.accessoryType = $0.value==currVal ? .checkmark : .none
+            return cell
+        })
+    }
+
+    init(dcContext: DcContext, fromServer: Bool) {
+        self.dcContext = dcContext
+        self.fromServer = fromServer
+        self.currVal = dcContext.getConfigInt(fromServer ? "delete_server_after" :  "delete_device_after")
+        super.init(style: .grouped)
+        self.title = String.localized("autodel_title_short")
+        hidesBottomBarWhenPushed = true
+    }
+
+    required init?(coder aDecoder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        navigationItem.leftBarButtonItem = cancelButton
+        navigationItem.rightBarButtonItem = okButton
+    }
+
+    static public func getSummary(_ dcContext: DcContext, fromServer: Bool) -> String {
+        let val = dcContext.getConfigInt(fromServer ? "delete_server_after" :  "delete_device_after")
+        let options = fromServer ? SettingsAutodelSetController.autodelServerOptions : SettingsAutodelSetController.autodelDeviceOptions
+        for option in options {
+            if option.value == val {
+                return String.localized(option.descr)
+            }
+        }
+        return "Err"
+    }
+
+    func valToIndex(val: Int) -> Int {
+        var index = 0
+        for option in autodelOptions {
+            if option.value == val {
+                return index
+            }
+            index += 1
+        }
+        return 0 // default to "off"
+    }
+
+    // MARK: - Table view data source
+
+    override func numberOfSections(in tableView: UITableView) -> Int {
+        return 1
+    }
+
+    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+        return autodelOptions.count
+    }
+
+    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+        let oldSelectedCell = tableView.cellForRow(at: IndexPath.init(row: self.valToIndex(val: self.currVal), section: 0))
+        let newSelectedCell = tableView.cellForRow(at: IndexPath.init(row: indexPath.row, section: 0))
+        let newVal = self.autodelOptions[indexPath.row].value
+
+        if newVal != currVal && newVal != 0 {
+            let delCount = dcContext.estimateDeletionCnt(fromServer: fromServer, timeout: newVal)
+            let newDescr = "\"" + String.localized(self.autodelOptions[indexPath.row].descr) + "\""
+            let msg = String.localizedStringWithFormat(String.localized(fromServer ? "autodel_server_ask" : "autodel_device_ask"), delCount, newDescr)
+            let alert = UIAlertController(
+                title: String.localized(fromServer ? "autodel_server_title" : "autodel_device_title"),
+                message: msg,
+                preferredStyle: .alert)
+            alert.addAction(UIAlertAction(title: String.localized("autodel_confirm"), style: .destructive, handler: { _ in
+                oldSelectedCell?.accessoryType = .none
+                newSelectedCell?.accessoryType = .checkmark
+                self.currVal = newVal
+            }))
+            alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel))
+            present(alert, animated: true, completion: nil)
+        } else {
+            oldSelectedCell?.accessoryType = .none
+            newSelectedCell?.accessoryType = .checkmark
+            currVal = newVal
+        }
+    }
+
+    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+        return staticCells[indexPath.row]
+    }
+
+    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
+        return String.localized(fromServer ? "autodel_server_title" : "autodel_device_title")
+    }
+
+    // MARK: - actions
+
+    @objc private func cancelButtonPressed() {
+        navigationController?.popViewController(animated: true)
+    }
+
+    @objc private func okButtonPressed() {
+        dcContext.setConfigInt(fromServer ? "delete_server_after" :  "delete_device_after", currVal)
+        navigationController?.popViewController(animated: true)
+    }
+}

+ 24 - 1
deltachat-ios/Controller/SettingsController.swift

@@ -21,6 +21,7 @@ internal final class SettingsViewController: UITableViewController {
         case exportBackup = 8
         case advanced = 9
         case help = 10
+        case autodel = 11
     }
 
     weak var coordinator: SettingsCoordinator?
@@ -76,6 +77,25 @@ internal final class SettingsViewController: UITableViewController {
         return cell
     }()
 
+    func autodelSummary() -> String {
+        let delDeviceAfter = dcContext.getConfigInt("delete_device_after")
+        let delServerAfter = dcContext.getConfigInt("delete_server_after")
+        if delDeviceAfter==0 && delServerAfter==0 {
+            return String.localized("off")
+        } else {
+            return String.localized("on")
+        }
+    }
+
+    private lazy var autodelCell: UITableViewCell = {
+        let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
+        cell.tag = CellTags.autodel.rawValue
+        cell.textLabel?.text = String.localized("autodel_title")
+        cell.accessoryType = .disclosureIndicator
+        cell.detailTextLabel?.text = autodelSummary()
+        return cell
+    }()
+
     private var notificationSwitch: UISwitch = {
         let switchControl = UISwitch()
         switchControl.isUserInteractionEnabled = false // toggled by cell tap
@@ -166,7 +186,7 @@ internal final class SettingsViewController: UITableViewController {
         let preferencesSection = SectionConfigs(
             headerTitle: nil,
             footerTitle: String.localized("pref_read_receipts_explain"),
-            cells: [contactRequestCell, chatPreferenceCell, blockedContactsCell, notificationCell, receiptConfirmationCell]
+            cells: [contactRequestCell, chatPreferenceCell, blockedContactsCell, autodelCell, notificationCell, receiptConfirmationCell]
         )
         let autocryptSection = SectionConfigs(
             headerTitle: String.localized("autocrypt"),
@@ -282,6 +302,7 @@ internal final class SettingsViewController: UITableViewController {
         case .contactRequest: self.coordinator?.showContactRequests()
         case .preferences: coordinator?.showClassicMail()
         case .blockedContacts: coordinator?.showBlockedContacts()
+        case .autodel: coordinator?.showAutodelOptions()
         case .notifications: handleNotificationToggle()
         case .receiptConfirmation: handleReceiptConfirmationToggle()
         case .autocryptPreferences: handleAutocryptPreferencesToggle()
@@ -415,5 +436,7 @@ internal final class SettingsViewController: UITableViewController {
         profileCell.update(contact: selfContact, displayName: displayName, address: email)
 
         chatPreferenceCell.detailTextLabel?.text = SettingsClassicViewController.getValString(val: dcContext.showEmails)
+
+        autodelCell.detailTextLabel?.text = autodelSummary()
     }
 }

+ 5 - 0
deltachat-ios/Coordinator/AppCoordinator.swift

@@ -300,6 +300,11 @@ class SettingsCoordinator: Coordinator {
         navigationController.pushViewController(blockedContactsController, animated: true)
     }
 
+    func showAutodelOptions() {
+        let settingsAutodelOverviewController = SettingsAutodelOverviewController(dcContext: dcContext)
+        navigationController.pushViewController(settingsAutodelOverviewController, animated: true)
+    }
+
     func showContactRequests() {
         let deaddropViewController = MailboxViewController(dcContext: dcContext, chatId: Int(DC_CHAT_ID_DEADDROP))
         let deaddropCoordinator = MailboxCoordinator(dcContext: dcContext, navigationController: navigationController)

+ 5 - 1
deltachat-ios/DC/Wrapper.swift

@@ -306,7 +306,7 @@ class DcContext {
         }
     }
 
-    private func setConfigInt(_ key: String, _ value: Int) {
+    func setConfigInt(_ key: String, _ value: Int) {
         setConfig(key, String(value))
     }
 
@@ -314,6 +314,10 @@ class DcContext {
         return Int(dc_get_fresh_msg_cnt(contextPointer, UInt32(chatId)))
     }
 
+    func estimateDeletionCnt(fromServer: Bool, timeout: Int) -> Int {
+        return Int(dc_estimate_deletion_cnt(contextPointer, fromServer ? 1 : 0, Int64(timeout)))
+    }
+
     func emptyServer(flags: Int) {
         dc_empty_server(contextPointer, UInt32(flags))
     }