From 13f94f29aadf67a13dcfc74292cfb29ef59bcc30 Mon Sep 17 00:00:00 2001
From: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>
Date: Thu, 14 Sep 2023 14:09:31 -0400
Subject: [PATCH] account: add UPnP settings

Change-Id: I55ce4049e63da5bee308ef8a983aa2bb344e18ec
---
 Ring/Ring/Constants/Generated/Strings.swift   |  2 ++
 .../Features/Me/Me/MeViewController.swift     | 24 +++++++++++++++++++
 Ring/Ring/Features/Me/Me/MeViewModel.swift    | 21 +++++++++++++++-
 .../Resources/en.lproj/Localizable.strings    |  1 +
 Ring/Ring/Services/AccountsService.swift      |  4 ++++
 5 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/Ring/Ring/Constants/Generated/Strings.swift b/Ring/Ring/Constants/Generated/Strings.swift
index 515ae07b5..cd9b26a42 100644
--- a/Ring/Ring/Constants/Generated/Strings.swift
+++ b/Ring/Ring/Constants/Generated/Strings.swift
@@ -151,6 +151,8 @@ internal enum L10n {
     internal static let turnUsername = L10n.tr("Localizable", "accountPage.turnUsername", fallback: "TURN username")
     /// UNBLOCK
     internal static let unblockContact = L10n.tr("Localizable", "accountPage.unblockContact", fallback: "UNBLOCK")
+    /// Use UPnP
+    internal static let upnpEnabled = L10n.tr("Localizable", "accountPage.upnpEnabled", fallback: "Use UPnP")
     /// username: not registered
     internal static let usernameNotRegistered = L10n.tr("Localizable", "accountPage.usernameNotRegistered", fallback: "username: not registered")
     /// Enter desired username
diff --git a/Ring/Ring/Features/Me/Me/MeViewController.swift b/Ring/Ring/Features/Me/Me/MeViewController.swift
index 64d03a5e1..22d52364c 100644
--- a/Ring/Ring/Features/Me/Me/MeViewController.swift
+++ b/Ring/Ring/Features/Me/Me/MeViewController.swift
@@ -622,6 +622,30 @@ class MeViewController: EditProfileViewController, StoryboardBased, ViewModelBas
                         })
                         .disposed(by: cell.disposeBag)
                     return cell
+                case .upnpEnabled:
+                    let cell = DisposableCell()
+                    cell.backgroundColor = UIColor.jamiBackgroundColor
+                    cell.textLabel?.text = L10n.AccountPage.upnpEnabled
+                    let switchView = UISwitch()
+                    cell.selectionStyle = .none
+                    cell.accessoryType = UITableViewCell.AccessoryType.disclosureIndicator
+                    cell.accessoryView = switchView
+                    self.viewModel.upnpEnabled
+                        .asObservable()
+                        .startWith(self.viewModel.upnpEnabled.value)
+                        .observe(on: MainScheduler.instance)
+                        .bind(to: switchView.rx.value)
+                        .disposed(by: cell.disposeBag)
+                    switchView.rx
+                        .isOn.changed
+                        .debounce(Durations.switchThrottlingDuration.toTimeInterval(), scheduler: MainScheduler.instance)
+                        .distinctUntilChanged()
+                        .asObservable()
+                        .subscribe(onNext: {[weak self] enable in
+                            self?.viewModel.enableUpnp(enable: enable)
+                        })
+                        .disposed(by: cell.disposeBag)
+                    return cell
                 case .turnServer:
                     let cell = self
                         .configureTurnCell(cellType: .turnServer,
diff --git a/Ring/Ring/Features/Me/Me/MeViewModel.swift b/Ring/Ring/Features/Me/Me/MeViewModel.swift
index ee0a0a790..c783c8d39 100644
--- a/Ring/Ring/Features/Me/Me/MeViewModel.swift
+++ b/Ring/Ring/Features/Me/Me/MeViewModel.swift
@@ -63,6 +63,7 @@ enum SettingsSection: SectionModelType {
         case turnUsername
         case turnPassword
         case turnRealm
+        case upnpEnabled
     }
 
     var items: [SectionRow] {
@@ -241,7 +242,8 @@ class MeViewModel: ViewModel, Stateable {
                                            .turnServer,
                                            .turnUsername,
                                            .turnPassword,
-                                           .turnRealm]))
+                                           .turnRealm,
+                                           .upnpEnabled]))
     }()
 
     lazy var otherJamiSettings: Observable<SettingsSection> = {
@@ -804,6 +806,13 @@ class MeViewModel: ViewModel, Stateable {
         turnEnabled.accept(enable)
     }
 
+    func enableUpnp(enable: Bool) {
+        guard self.upnpEnabled.value != enable,
+              let account = self.accountService.currentAccount else { return }
+        self.accountService.enableUpnp(enable: enable, accountId: account.id)
+        upnpEnabled.accept(enable)
+    }
+
     func enableKeepAlive(enable: Bool) {
         guard self.keepAliveEnabled.value != enable,
               let account = self.accountService.currentAccount else { return }
@@ -821,6 +830,16 @@ class MeViewModel: ViewModel, Stateable {
         }
         return BehaviorRelay<Bool>(value: true)
     }()
+
+    lazy var upnpEnabled: BehaviorRelay<Bool> = {
+        if let account = self.accountService.currentAccount,
+           let details = account.details {
+            let enable = details.get(withConfigKeyModel:
+                                        ConfigKeyModel.init(withKey: .accountUpnpEnabled)).boolValue
+            return BehaviorRelay<Bool>(value: enable)
+        }
+        return BehaviorRelay<Bool>(value: true)
+    }()
     let turnServer = BehaviorRelay<String>(value: "")
     let turnUsername = BehaviorRelay<String>(value: "")
     let turnPassword = BehaviorRelay<String>(value: "")
diff --git a/Ring/Ring/Resources/en.lproj/Localizable.strings b/Ring/Ring/Resources/en.lproj/Localizable.strings
index 88968235a..f42d56d53 100644
--- a/Ring/Ring/Resources/en.lproj/Localizable.strings
+++ b/Ring/Ring/Resources/en.lproj/Localizable.strings
@@ -286,6 +286,7 @@
 "accountPage.turnUsername" = "TURN username";
 "accountPage.turnPassword" = "TURN password";
 "accountPage.turnRealm" = "TURN realm";
+"accountPage.upnpEnabled" = "Use UPnP";
 
 //Account
 "account.sipUsername" = "User Name";
diff --git a/Ring/Ring/Services/AccountsService.swift b/Ring/Ring/Services/AccountsService.swift
index cc4aeef2d..ac4160db7 100644
--- a/Ring/Ring/Services/AccountsService.swift
+++ b/Ring/Ring/Services/AccountsService.swift
@@ -941,6 +941,10 @@ class AccountsService: AccountAdapterDelegate {
         self.switchAccountPropertyTo(state: enable, accountId: accountId, property: ConfigKeyModel(withKey: ConfigKey.turnEnable))
     }
 
+    func enableUpnp(enable: Bool, accountId: String) {
+        self.switchAccountPropertyTo(state: enable, accountId: accountId, property: ConfigKeyModel(withKey: ConfigKey.accountUpnpEnabled))
+    }
+
     func setTurnSettings(accountId: String, server: String, username: String, password: String, realm: String) {
         let details = self.getAccountDetails(fromAccountId: accountId)
         details.set(withConfigKeyModel: ConfigKeyModel(withKey: ConfigKey.turnServer), withValue: server)
-- 
GitLab