mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Forced the user config feature to be on (for testing) Fixed a bug where triggering the 'Delete for everyone' functionality would incorrectly try to delete from the recipient swarm (not possible) Fixed a bug where the 'profileNamePublisher' could only be set once resulting in potential issues if you try to restore different accounts within the same session Re-added the limit to the number of reactions to display before collapsing to make it consistent with the designs and other platforms Updated the SnodeAPI to ensure that when it retries it will actually select a new snode
210 lines
8.4 KiB
Swift
210 lines
8.4 KiB
Swift
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
|
|
|
import UIKit
|
|
import Combine
|
|
import SessionUIKit
|
|
import SessionMessagingKit
|
|
import SessionSnodeKit
|
|
import SignalUtilitiesKit
|
|
|
|
final class PNModeVC: BaseVC, OptionViewDelegate {
|
|
private let flow: Onboarding.Flow
|
|
|
|
private var optionViews: [OptionView] {
|
|
[ apnsOptionView, backgroundPollingOptionView ]
|
|
}
|
|
|
|
private var selectedOptionView: OptionView? {
|
|
return optionViews.first { $0.isSelected }
|
|
}
|
|
|
|
// MARK: - Initialization
|
|
|
|
init(flow: Onboarding.Flow) {
|
|
self.flow = flow
|
|
|
|
super.init(nibName: nil, bundle: nil)
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
// MARK: - Components
|
|
|
|
private lazy var apnsOptionView: OptionView = {
|
|
let result: OptionView = OptionView(
|
|
title: "fast_mode".localized(),
|
|
explanation: "fast_mode_explanation".localized(),
|
|
delegate: self,
|
|
isRecommended: true
|
|
)
|
|
result.accessibilityLabel = "Fast mode option"
|
|
|
|
return result
|
|
}()
|
|
|
|
private lazy var backgroundPollingOptionView: OptionView = {
|
|
let result: OptionView = OptionView(
|
|
title: "slow_mode".localized(),
|
|
explanation: "slow_mode_explanation".localized(),
|
|
delegate: self
|
|
)
|
|
result.accessibilityLabel = "Slow mode option"
|
|
|
|
return result
|
|
}()
|
|
|
|
// MARK: - Lifecycle
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
setUpNavBarSessionIcon()
|
|
|
|
let learnMoreButton = UIBarButtonItem(image: #imageLiteral(resourceName: "ic_info"), style: .plain, target: self, action: #selector(learnMore))
|
|
learnMoreButton.themeTintColor = .textPrimary
|
|
navigationItem.rightBarButtonItem = learnMoreButton
|
|
|
|
// Set up title label
|
|
let titleLabel = UILabel()
|
|
titleLabel.font = .boldSystemFont(ofSize: isIPhone5OrSmaller ? Values.largeFontSize : Values.veryLargeFontSize)
|
|
titleLabel.text = "vc_pn_mode_title".localized()
|
|
titleLabel.themeTextColor = .textPrimary
|
|
titleLabel.lineBreakMode = .byWordWrapping
|
|
titleLabel.numberOfLines = 0
|
|
|
|
// Set up spacers
|
|
let topSpacer = UIView.vStretchingSpacer()
|
|
let bottomSpacer = UIView.vStretchingSpacer()
|
|
let registerButtonBottomOffsetSpacer = UIView()
|
|
registerButtonBottomOffsetSpacer.set(.height, to: Values.onboardingButtonBottomOffset)
|
|
|
|
// Set up register button
|
|
let registerButton = SessionButton(style: .filled, size: .large)
|
|
registerButton.accessibilityLabel = "Continue with settings"
|
|
registerButton.setTitle("continue_2".localized(), for: .normal)
|
|
registerButton.addTarget(self, action: #selector(register), for: UIControl.Event.touchUpInside)
|
|
|
|
// Set up register button container
|
|
let registerButtonContainer = UIView(wrapping: registerButton, withInsets: UIEdgeInsets(top: 0, leading: Values.massiveSpacing, bottom: 0, trailing: Values.massiveSpacing), shouldAdaptForIPadWithWidth: Values.iPadButtonWidth)
|
|
|
|
// Set up options stack view
|
|
let optionsStackView = UIStackView(arrangedSubviews: optionViews)
|
|
optionsStackView.axis = .vertical
|
|
optionsStackView.spacing = Values.smallSpacing
|
|
optionsStackView.alignment = .fill
|
|
|
|
// Set up top stack view
|
|
let topStackView = UIStackView(arrangedSubviews: [ titleLabel, UIView.spacer(withHeight: isIPhone6OrSmaller ? Values.mediumSpacing : Values.veryLargeSpacing), optionsStackView ])
|
|
topStackView.axis = .vertical
|
|
topStackView.alignment = .fill
|
|
|
|
// Set up top stack view container
|
|
let topStackViewContainer = UIView(wrapping: topStackView, withInsets: UIEdgeInsets(top: 0, leading: Values.veryLargeSpacing, bottom: 0, trailing: Values.veryLargeSpacing))
|
|
|
|
// Set up main stack view
|
|
let mainStackView = UIStackView(arrangedSubviews: [ topSpacer, topStackViewContainer, bottomSpacer, registerButtonContainer, registerButtonBottomOffsetSpacer ])
|
|
mainStackView.axis = .vertical
|
|
mainStackView.alignment = .fill
|
|
view.addSubview(mainStackView)
|
|
mainStackView.pin(to: view)
|
|
topSpacer.heightAnchor.constraint(equalTo: bottomSpacer.heightAnchor, multiplier: 1).isActive = true
|
|
|
|
// Preselect APNs mode
|
|
optionViews[0].isSelected = true
|
|
}
|
|
|
|
// MARK: - Interaction
|
|
|
|
@objc private func learnMore() {
|
|
guard let url: URL = URL(string: "https://getsession.org/faq/#privacy") else { return }
|
|
|
|
UIApplication.shared.open(url)
|
|
}
|
|
|
|
func optionViewDidActivate(_ optionView: OptionView) {
|
|
optionViews.filter { $0 != optionView }.forEach { $0.isSelected = false }
|
|
}
|
|
|
|
@objc private func register() {
|
|
guard selectedOptionView != nil else {
|
|
let modal: ConfirmationModal = ConfirmationModal(
|
|
targetView: self.view,
|
|
info: ConfirmationModal.Info(
|
|
title: "vc_pn_mode_no_option_picked_modal_title".localized(),
|
|
cancelTitle: "BUTTON_OK".localized(),
|
|
cancelStyle: .alert_text
|
|
)
|
|
)
|
|
self.present(modal, animated: true)
|
|
return
|
|
}
|
|
UserDefaults.standard[.isUsingFullAPNs] = (selectedOptionView == apnsOptionView)
|
|
|
|
// If we are registering then we can just continue on
|
|
guard flow != .register else {
|
|
self.flow.completeRegistration()
|
|
|
|
// Go to the home screen
|
|
let homeVC: HomeVC = HomeVC()
|
|
self.navigationController?.setViewControllers([ homeVC ], animated: true)
|
|
return
|
|
}
|
|
|
|
// Check if we already have a profile name (ie. profile retrieval completed while waiting on
|
|
// this screen)
|
|
let existingProfileName: String? = Storage.shared
|
|
.read { db in
|
|
try Profile
|
|
.filter(id: getUserHexEncodedPublicKey(db))
|
|
.select(.name)
|
|
.asRequest(of: String.self)
|
|
.fetchOne(db)
|
|
}
|
|
|
|
guard existingProfileName?.isEmpty != false else {
|
|
// If we have one then we can go straight to the home screen
|
|
self.flow.completeRegistration()
|
|
|
|
// Go to the home screen
|
|
let homeVC: HomeVC = HomeVC()
|
|
self.navigationController?.setViewControllers([ homeVC ], animated: true)
|
|
return
|
|
}
|
|
|
|
// If we don't have one then show a loading indicator and try to retrieve the existing name
|
|
ModalActivityIndicatorViewController.present(fromViewController: self) { [weak self, flow = self.flow] viewController in
|
|
Onboarding.profileNamePublisher
|
|
.timeout(.seconds(15), scheduler: DispatchQueue.main, customError: { HTTPError.timeout })
|
|
.catch { _ -> AnyPublisher<String?, Error> in
|
|
SNLog("Onboarding failed to retrieve existing profile information")
|
|
return Just(nil)
|
|
.setFailureType(to: Error.self)
|
|
.eraseToAnyPublisher()
|
|
}
|
|
.receive(on: DispatchQueue.main)
|
|
.sinkUntilComplete(
|
|
receiveValue: { value in
|
|
// Hide the loading indicator
|
|
viewController.dismiss(animated: true)
|
|
|
|
// If we have no display name we need to collect one
|
|
guard value?.isEmpty == false else {
|
|
let displayNameVC: DisplayNameVC = DisplayNameVC(flow: flow)
|
|
self?.navigationController?.pushViewController(displayNameVC, animated: true)
|
|
return
|
|
}
|
|
|
|
// Otherwise we are done and can go to the home screen
|
|
self?.flow.completeRegistration()
|
|
|
|
// Go to the home screen
|
|
let homeVC: HomeVC = HomeVC()
|
|
self?.navigationController?.setViewControllers([ homeVC ], animated: true)
|
|
}
|
|
)
|
|
}
|
|
}
|
|
}
|