diff --git a/CHANGES.rst b/CHANGES.rst index d39122e9d..4a95b11c6 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -25,6 +25,7 @@ Improvements: * Privacy: Settings: Add a Discovery section (#2606). * Privacy: Make NSContactsUsageDescription more generic and mention that 3pids are now uploaded hashed (#2521). * Privacy: Settings: Add IDENTITY SERVER section (#2604). + * Privacy: Make IS terms wording clearer when we fallback to vector.im (#2760). Bug fix: * Theme: Make button theming work (#2734). diff --git a/Riot/AppDelegate.m b/Riot/AppDelegate.m index a3a8b4184..4c4336ca1 100644 --- a/Riot/AppDelegate.m +++ b/Riot/AppDelegate.m @@ -4844,6 +4844,7 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe ServiceTermsModalCoordinatorBridgePresenter *serviceTermsModalCoordinatorBridgePresenter = [[ServiceTermsModalCoordinatorBridgePresenter alloc] initWithSession:mxSession baseUrl:baseURL serviceType:MXServiceTypeIdentityService + outOfContext:YES accessToken:accessToken]; serviceTermsModalCoordinatorBridgePresenter.delegate = self; diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index f1f5923d9..7dffc2faa 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -784,11 +784,19 @@ // Service terms "service_terms_modal_title" = "Terms Of Service"; -"service_terms_modal_message" = "To continue you need to accept the Terms of this service (%@)."; +"service_terms_modal_message" = "To continue you need to accept the terms of this service (%@)."; "service_terms_modal_accept_button" = "Accept"; -"service_terms_modal_description_for_identity_server" = "Be discoverable by others"; +"service_terms_modal_decline_button" = "Decline"; + +"service_terms_modal_description_for_identity_server_1" = "Find others by phone or email"; +"service_terms_modal_description_for_identity_server_2" = "Be found by phone or email"; "service_terms_modal_description_for_integration_manager" = "Use Bots, bridges, widgets and sticker packs"; +// Service terms - Variant for identity server when displayed out of a context +"service_terms_modal_title_identity_server" = "Contact discovery"; +"service_terms_modal_message_identity_server" = "Accept the terms of the identity server (%@) to discover contacts."; + + // Deactivate account "deactivate_account_title" = "Deactivate Account"; diff --git a/Riot/Generated/Strings.swift b/Riot/Generated/Strings.swift index b538feab9..ef7a91758 100644 --- a/Riot/Generated/Strings.swift +++ b/Riot/Generated/Strings.swift @@ -2518,22 +2518,38 @@ internal enum VectorL10n { internal static var serviceTermsModalAcceptButton: String { return VectorL10n.tr("Vector", "service_terms_modal_accept_button") } - /// Be discoverable by others - internal static var serviceTermsModalDescriptionForIdentityServer: String { - return VectorL10n.tr("Vector", "service_terms_modal_description_for_identity_server") + /// Decline + internal static var serviceTermsModalDeclineButton: String { + return VectorL10n.tr("Vector", "service_terms_modal_decline_button") + } + /// Find others by phone or email + internal static var serviceTermsModalDescriptionForIdentityServer1: String { + return VectorL10n.tr("Vector", "service_terms_modal_description_for_identity_server_1") + } + /// Be found by phone or email + internal static var serviceTermsModalDescriptionForIdentityServer2: String { + return VectorL10n.tr("Vector", "service_terms_modal_description_for_identity_server_2") } /// Use Bots, bridges, widgets and sticker packs internal static var serviceTermsModalDescriptionForIntegrationManager: String { return VectorL10n.tr("Vector", "service_terms_modal_description_for_integration_manager") } - /// To continue you need to accept the Terms of this service (%@). + /// To continue you need to accept the terms of this service (%@). internal static func serviceTermsModalMessage(_ p1: String) -> String { return VectorL10n.tr("Vector", "service_terms_modal_message", p1) } + /// Accept the terms of the identity server (%@) to discover contacts. + internal static func serviceTermsModalMessageIdentityServer(_ p1: String) -> String { + return VectorL10n.tr("Vector", "service_terms_modal_message_identity_server", p1) + } /// Terms Of Service internal static var serviceTermsModalTitle: String { return VectorL10n.tr("Vector", "service_terms_modal_title") } + /// Contact discovery + internal static var serviceTermsModalTitleIdentityServer: String { + return VectorL10n.tr("Vector", "service_terms_modal_title_identity_server") + } /// Add email address internal static var settingsAddEmailAddress: String { return VectorL10n.tr("Vector", "settings_add_email_address") diff --git a/Riot/Modules/Integrations/IntegrationManagerViewController.m b/Riot/Modules/Integrations/IntegrationManagerViewController.m index 470556421..6a412fd24 100644 --- a/Riot/Modules/Integrations/IntegrationManagerViewController.m +++ b/Riot/Modules/Integrations/IntegrationManagerViewController.m @@ -707,6 +707,7 @@ NSString *const kIntegrationManagerAddIntegrationScreen = @"add_integ"; ServiceTermsModalCoordinatorBridgePresenter *serviceTermsModalCoordinatorBridgePresenter = [[ServiceTermsModalCoordinatorBridgePresenter alloc] initWithSession:mxSession baseUrl:config.baseUrl serviceType:MXServiceTypeIntegrationManager + outOfContext:NO accessToken:config.scalarToken]; serviceTermsModalCoordinatorBridgePresenter.delegate = self; diff --git a/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenCoordinator.swift b/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenCoordinator.swift index d10923dee..dcf1ce7fa 100644 --- a/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenCoordinator.swift +++ b/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenCoordinator.swift @@ -37,9 +37,9 @@ final class ServiceTermsModalScreenCoordinator: ServiceTermsModalScreenCoordinat // MARK: - Setup - init(serviceTerms: MXServiceTerms) { + init(serviceTerms: MXServiceTerms, outOfContext: Bool = false) { - let serviceTermsModalScreenViewModel = ServiceTermsModalScreenViewModel(serviceTerms: serviceTerms) + let serviceTermsModalScreenViewModel = ServiceTermsModalScreenViewModel(serviceTerms: serviceTerms, outOfContext: outOfContext) let serviceTermsModalScreenViewController = ServiceTermsModalScreenViewController.instantiate(with: serviceTermsModalScreenViewModel) self.serviceTermsModalScreenViewModel = serviceTermsModalScreenViewModel self.serviceTermsModalScreenViewController = serviceTermsModalScreenViewController diff --git a/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenViewController.storyboard b/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenViewController.storyboard index 9631169c5..19192ed77 100644 --- a/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenViewController.storyboard +++ b/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenViewController.storyboard @@ -37,32 +37,46 @@ - + - + + + + + + + - - - + + + - + @@ -98,6 +112,7 @@ + diff --git a/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenViewController.swift b/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenViewController.swift index 30f91177e..2f8997cfd 100644 --- a/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenViewController.swift +++ b/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenViewController.swift @@ -31,7 +31,8 @@ final class ServiceTermsModalScreenViewController: UIViewController { @IBOutlet private weak var messageLabel: UILabel! @IBOutlet private weak var tableView: UITableView! @IBOutlet private weak var acceptButton: UIButton! - + @IBOutlet private weak var declineButton: UIButton! + // MARK: Private private var viewModel: ServiceTermsModalScreenViewModelType! @@ -94,6 +95,9 @@ final class ServiceTermsModalScreenViewController: UIViewController { self.acceptButton.backgroundColor = theme.backgroundColor theme.applyStyle(onButton: self.acceptButton) + theme.applyStyle(onButton: self.declineButton) + self.declineButton.setTitleColor(self.theme.warningColor, for: .normal) + self.refreshViews() } @@ -120,6 +124,17 @@ final class ServiceTermsModalScreenViewController: UIViewController { self.acceptButton.setTitle(VectorL10n.serviceTermsModalAcceptButton, for: .normal) self.acceptButton.setTitle(VectorL10n.serviceTermsModalAcceptButton, for: .highlighted) self.refreshAcceptButton() + + if self.viewModel.outOfContext + && self.viewModel.serviceType == MXServiceTypeIdentityService { + self.title = VectorL10n.serviceTermsModalTitleIdentityServer + self.messageLabel.text = VectorL10n.serviceTermsModalMessageIdentityServer(self.viewModel.serviceUrl) + + self.declineButton.setTitle(VectorL10n.serviceTermsModalDeclineButton, for: .normal) + self.declineButton.setTitle(VectorL10n.serviceTermsModalDeclineButton, for: .highlighted) + } else { + self.declineButton.isHidden = true + } } private func setupTableView() { @@ -269,7 +284,9 @@ extension ServiceTermsModalScreenViewController: UITableViewDataSource { var labelDetail: String = "" switch self.viewModel.serviceType { case MXServiceTypeIdentityService: - labelDetail = VectorL10n.serviceTermsModalDescriptionForIdentityServer + labelDetail = VectorL10n.serviceTermsModalDescriptionForIdentityServer1 + + "\n" + + VectorL10n.serviceTermsModalDescriptionForIdentityServer2 case MXServiceTypeIntegrationManager: labelDetail = VectorL10n.serviceTermsModalDescriptionForIntegrationManager default: break @@ -280,7 +297,6 @@ extension ServiceTermsModalScreenViewController: UITableViewDataSource { label.append(NSAttributedString(string: "\n")) label.append(NSAttributedString(string: labelDetail, attributes: [.foregroundColor: theme.textSecondaryColor])) - return label } } diff --git a/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenViewModel.swift b/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenViewModel.swift index 919aaa874..88c7e8900 100644 --- a/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenViewModel.swift +++ b/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenViewModel.swift @@ -19,9 +19,10 @@ import Foundation final class ServiceTermsModalScreenViewModel: ServiceTermsModalScreenViewModelType { - + // MARK: - Properties - + let outOfContext: Bool + // MARK: Private private let serviceTerms: MXServiceTerms @@ -42,8 +43,9 @@ final class ServiceTermsModalScreenViewModel: ServiceTermsModalScreenViewModelTy // MARK: - Setup - init(serviceTerms: MXServiceTerms) { + init(serviceTerms: MXServiceTerms, outOfContext: Bool) { self.serviceTerms = serviceTerms + self.outOfContext = outOfContext } deinit { diff --git a/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenViewModelType.swift b/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenViewModelType.swift index 2a812f6b2..74c43d705 100644 --- a/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenViewModelType.swift +++ b/Riot/Modules/ServiceTerms/Modal/Modal/ServiceTermsModalScreenViewModelType.swift @@ -33,6 +33,9 @@ protocol ServiceTermsModalScreenViewModelType { var serviceUrl: String { get } var serviceType: MXServiceType { get } + /// If true, terms are displayed out of a context of a flow (like a background 3pids lookup) + /// In this case, the wording needs to provide more information about the intent + var outOfContext: Bool { get } var policies: [MXLoginPolicyData]? { get set } var alreadyAcceptedPoliciesUrls: [String] { get set } diff --git a/Riot/Modules/ServiceTerms/Modal/ServiceTermsModalCoordinator.swift b/Riot/Modules/ServiceTerms/Modal/ServiceTermsModalCoordinator.swift index 433d02baa..c3163c6fb 100644 --- a/Riot/Modules/ServiceTerms/Modal/ServiceTermsModalCoordinator.swift +++ b/Riot/Modules/ServiceTerms/Modal/ServiceTermsModalCoordinator.swift @@ -28,6 +28,7 @@ final class ServiceTermsModalCoordinator: ServiceTermsModalCoordinatorType { private let navigationRouter: NavigationRouterType private let session: MXSession private let serviceTerms: MXServiceTerms + private let outOfContext: Bool // MARK: Public @@ -37,10 +38,11 @@ final class ServiceTermsModalCoordinator: ServiceTermsModalCoordinatorType { weak var delegate: ServiceTermsModalCoordinatorDelegate? // MARK: - Setup - init(session: MXSession, baseUrl: String, serviceType: MXServiceType, accessToken: String) { + init(session: MXSession, baseUrl: String, serviceType: MXServiceType, outOfContext: Bool, accessToken: String) { self.navigationRouter = NavigationRouter(navigationController: RiotNavigationController()) self.session = session self.serviceTerms = MXServiceTerms(baseUrl: baseUrl, serviceType: serviceType, matrixSession: session, accessToken: accessToken) + self.outOfContext = outOfContext } // MARK: - Public methods @@ -62,7 +64,7 @@ final class ServiceTermsModalCoordinator: ServiceTermsModalCoordinatorType { // MARK: - Private methods private func createServiceTermsModalLoadTermsScreenCoordinator() -> ServiceTermsModalScreenCoordinator { - let coordinator = ServiceTermsModalScreenCoordinator(serviceTerms: self.serviceTerms) + let coordinator = ServiceTermsModalScreenCoordinator(serviceTerms: self.serviceTerms, outOfContext: self.outOfContext) coordinator.delegate = self return coordinator } diff --git a/Riot/Modules/ServiceTerms/Modal/ServiceTermsModalCoordinatorBridgePresenter.swift b/Riot/Modules/ServiceTerms/Modal/ServiceTermsModalCoordinatorBridgePresenter.swift index f3b05f288..365ae2624 100644 --- a/Riot/Modules/ServiceTerms/Modal/ServiceTermsModalCoordinatorBridgePresenter.swift +++ b/Riot/Modules/ServiceTerms/Modal/ServiceTermsModalCoordinatorBridgePresenter.swift @@ -35,6 +35,7 @@ final class ServiceTermsModalCoordinatorBridgePresenter: NSObject { private let session: MXSession private let baseUrl: String private let serviceType: MXServiceType + private let outOfContext: Bool private let accessToken: String private var coordinator: ServiceTermsModalCoordinator? @@ -48,10 +49,11 @@ final class ServiceTermsModalCoordinatorBridgePresenter: NSObject { // MARK: - Setup - init(session: MXSession, baseUrl: String, serviceType: MXServiceType, accessToken: String) { + init(session: MXSession, baseUrl: String, serviceType: MXServiceType, outOfContext: Bool = false, accessToken: String) { self.session = session self.baseUrl = baseUrl self.serviceType = serviceType + self.outOfContext = outOfContext self.accessToken = accessToken super.init() } @@ -64,7 +66,7 @@ final class ServiceTermsModalCoordinatorBridgePresenter: NSObject { // } func present(from viewController: UIViewController, animated: Bool) { - let serviceTermsModalCoordinator = ServiceTermsModalCoordinator(session: self.session, baseUrl: self.baseUrl, serviceType: self.serviceType, accessToken: accessToken) + let serviceTermsModalCoordinator = ServiceTermsModalCoordinator(session: self.session, baseUrl: self.baseUrl, serviceType: self.serviceType, outOfContext: self.outOfContext, accessToken: accessToken) serviceTermsModalCoordinator.delegate = self viewController.present(serviceTermsModalCoordinator.toPresentable(), animated: animated, completion: nil) serviceTermsModalCoordinator.start()