From 3563d7d469ecacb93f4fa50d8534a4649c2d096d Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Thu, 6 Oct 2022 13:11:17 +1100 Subject: [PATCH] clean --- .../Content Views/ReactionContainerView.swift | 3 +- .../Message Cells/VisibleMessageCell.swift | 2 +- Session/Settings/SettingsVC.swift | 681 ------------------ .../OWSNavigationController.m | 186 ----- 4 files changed, 2 insertions(+), 870 deletions(-) delete mode 100644 Session/Settings/SettingsVC.swift delete mode 100644 SignalUtilitiesKit/Shared View Controllers/OWSNavigationController.m diff --git a/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift b/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift index febc2ee61..583142633 100644 --- a/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift +++ b/Session/Conversations/Message Cells/Content Views/ReactionContainerView.swift @@ -13,7 +13,6 @@ final class ReactionContainerView: UIView { private var collapsedCount: Int = 0 private var showingAllReactions: Bool = false private var showNumbers: Bool = true - private var maxEmojisPerLine = UIDevice.current.isIPad ? 10 : (isIPhone6OrSmaller ? 5 : 6) private var oldSize: CGSize = .zero var reactions: [ReactionViewModel] = [] @@ -114,7 +113,7 @@ final class ReactionContainerView: UIView { // button appear horizontally centered (if we don't do this it gets offset to one side) guard frame != CGRect.zero, frame.size != oldSize else { return } - var targetSuperview: UIView? = { + let targetSuperview: UIView? = { var result: UIView? = self.superview while result != nil, result?.isKind(of: UITableViewCell.self) != true { diff --git a/Session/Conversations/Message Cells/VisibleMessageCell.swift b/Session/Conversations/Message Cells/VisibleMessageCell.swift index d70a5f3d3..5c0641334 100644 --- a/Session/Conversations/Message Cells/VisibleMessageCell.swift +++ b/Session/Conversations/Message Cells/VisibleMessageCell.swift @@ -372,7 +372,7 @@ final class VisibleMessageCell: MessageCell, TappableLabelDelegate { for: cellViewModel, maxWidth: VisibleMessageCell.getMaxWidth( for: cellViewModel, - includingOppositeGutter: false + includingOppositeGutter: UIDevice.current.isIPad ), showExpandedReactions: showExpandedReactions ) diff --git a/Session/Settings/SettingsVC.swift b/Session/Settings/SettingsVC.swift deleted file mode 100644 index 9b4c4177c..000000000 --- a/Session/Settings/SettingsVC.swift +++ /dev/null @@ -1,681 +0,0 @@ -// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. - -import UIKit -import SessionUIKit -import SessionUtilitiesKit -import SessionMessagingKit -import SignalUtilitiesKit - -final class SettingsVC: BaseVC, AvatarViewHelperDelegate { - private var displayNameToBeUploaded: String? - private var isEditingDisplayName = false { didSet { handleIsEditingDisplayNameChanged() } } - - private var viewWidth: NSLayoutConstraint? - - // MARK: - Components - - private lazy var profilePictureView: ProfilePictureView = { - let result = ProfilePictureView() - let size = Values.largeProfilePictureSize - result.size = size - result.set(.width, to: size) - result.set(.height, to: size) - result.accessibilityLabel = "Edit profile picture button" - result.isAccessibilityElement = true - - return result - }() - - private lazy var profilePictureUtilities: AvatarViewHelper = { - let result = AvatarViewHelper() - result.delegate = self - - return result - }() - - private lazy var displayNameLabel: UILabel = { - let result = UILabel() - result.textColor = Colors.text - result.font = .boldSystemFont(ofSize: Values.veryLargeFontSize) - result.lineBreakMode = .byTruncatingTail - result.textAlignment = .center - - return result - }() - - private lazy var displayNameTextField: TextField = { - let result = TextField(placeholder: NSLocalizedString("vc_settings_display_name_text_field_hint", comment: ""), usesDefaultHeight: false) - result.textAlignment = .center - result.accessibilityLabel = "Edit display name text field" - - return result - }() - - private lazy var publicKeyLabel: UILabel = { - let result = UILabel() - result.textColor = Colors.text - result.font = Fonts.spaceMono(ofSize: isIPhone5OrSmaller ? Values.mediumFontSize : Values.largeFontSize) - result.numberOfLines = 0 - result.textAlignment = .center - result.lineBreakMode = .byCharWrapping - result.text = getUserHexEncodedPublicKey() - - return result - }() - - private lazy var copyButton: Button = { - let result = Button(style: .prominentOutline, size: .medium) - result.setTitle(NSLocalizedString("copy", comment: ""), for: UIControl.State.normal) - result.addTarget(self, action: #selector(copyPublicKey), for: UIControl.Event.touchUpInside) - - return result - }() - - private lazy var settingButtonsStackView: UIStackView = { - let result = UIStackView() - result.axis = .vertical - result.alignment = .fill - - return result - }() - - private lazy var inviteButton: UIButton = { - let result = UIButton() - result.setTitle(NSLocalizedString("vc_settings_invite_a_friend_button_title", comment: ""), for: UIControl.State.normal) - result.setTitleColor(Colors.text, for: UIControl.State.normal) - result.titleLabel!.font = .boldSystemFont(ofSize: Values.smallFontSize) - result.addTarget(self, action: #selector(sendInvitation), for: UIControl.Event.touchUpInside) - - return result - }() - - private lazy var faqButton: UIButton = { - let result = UIButton() - result.setTitle(NSLocalizedString("vc_settings_faq_button_title", comment: ""), for: UIControl.State.normal) - result.setTitleColor(Colors.text, for: UIControl.State.normal) - result.titleLabel!.font = .boldSystemFont(ofSize: Values.smallFontSize) - result.addTarget(self, action: #selector(openFAQ), for: UIControl.Event.touchUpInside) - - return result - }() - - private lazy var surveyButton: UIButton = { - let result = UIButton() - result.setTitle(NSLocalizedString("vc_settings_survey_button_title", comment: ""), for: UIControl.State.normal) - result.setTitleColor(Colors.text, for: UIControl.State.normal) - result.titleLabel?.font = .boldSystemFont(ofSize: Values.smallFontSize) - result.addTarget(self, action: #selector(openSurvey), for: UIControl.Event.touchUpInside) - - return result - }() - - private lazy var supportButton: UIButton = { - let result = UIButton() - result.setTitle(NSLocalizedString("vc_settings_support_button_title", comment: ""), for: UIControl.State.normal) - result.setTitleColor(Colors.text, for: UIControl.State.normal) - result.titleLabel!.font = .boldSystemFont(ofSize: Values.smallFontSize) - result.addTarget(self, action: #selector(shareLogs), for: UIControl.Event.touchUpInside) - - return result - }() - - private lazy var helpTranslateButton: UIButton = { - let result = UIButton() - result.setTitle(NSLocalizedString("vc_settings_help_us_translate_button_title", comment: ""), for: UIControl.State.normal) - result.setTitleColor(Colors.text, for: UIControl.State.normal) - result.titleLabel!.font = .boldSystemFont(ofSize: Values.smallFontSize) - result.addTarget(self, action: #selector(helpTranslate), for: UIControl.Event.touchUpInside) - - return result - }() - - private lazy var logoImageView: UIImageView = { - let result = UIImageView() - result.set(.height, to: 24) - result.contentMode = .scaleAspectFit - - return result - }() - - private lazy var versionLabel: UILabel = { - let result = UILabel() - result.textColor = Colors.text.withAlphaComponent(Values.mediumOpacity) - result.font = .systemFont(ofSize: Values.verySmallFontSize) - result.numberOfLines = 0 - result.textAlignment = .center - result.lineBreakMode = .byCharWrapping - let version = Bundle.main.infoDictionary!["CFBundleShortVersionString"]! - let buildNumber = Bundle.main.infoDictionary!["CFBundleVersion"]! - result.text = "Version \(version) (\(buildNumber))" - - return result - }() - - // MARK: - Settings - - private static let buttonHeight = isIPhone5OrSmaller ? CGFloat(52) : CGFloat(75) - - // MARK: - Lifecycle - - override func viewDidLoad() { - super.viewDidLoad() - - setUpGradientBackground() - setUpNavBarStyle() - setNavBarTitle(NSLocalizedString("vc_settings_title", comment: "")) - - // Navigation bar buttons - updateNavigationBarButtons() - - // Profile picture view - let profile: Profile = Profile.fetchOrCreateCurrentUser() - let profilePictureTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(showEditProfilePictureUI)) - profilePictureView.addGestureRecognizer(profilePictureTapGestureRecognizer) - profilePictureView - .update( - publicKey: profile.id, - profile: profile, - threadVariant: .contact - ) - // Display name label - displayNameLabel.text = profile.name - - // Display name container - let displayNameContainer = UIView() - displayNameContainer.accessibilityLabel = "Edit display name text field" - displayNameContainer.isAccessibilityElement = true - displayNameContainer.addSubview(displayNameLabel) - displayNameLabel.pin(to: displayNameContainer) - displayNameContainer.addSubview(displayNameTextField) - displayNameTextField.pin(to: displayNameContainer) - displayNameContainer.set(.height, to: 40) - displayNameTextField.alpha = 0 - let displayNameContainerTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(showEditDisplayNameUI)) - displayNameContainer.addGestureRecognizer(displayNameContainerTapGestureRecognizer) - - // Header view - let headerStackView = UIStackView(arrangedSubviews: [ profilePictureView, displayNameContainer ]) - headerStackView.axis = .vertical - headerStackView.spacing = Values.smallSpacing - headerStackView.alignment = .center - - // Separator - let separator = Separator(title: NSLocalizedString("your_session_id", comment: "")) - - // Share button - let shareButton = Button(style: .regular, size: .medium) - shareButton.setTitle(NSLocalizedString("share", comment: ""), for: UIControl.State.normal) - shareButton.addTarget(self, action: #selector(sharePublicKey), for: UIControl.Event.touchUpInside) - - // Button container - let buttonContainer = UIStackView(arrangedSubviews: [ copyButton, shareButton ]) - buttonContainer.axis = .horizontal - buttonContainer.spacing = UIDevice.current.isIPad ? Values.iPadButtonSpacing : Values.mediumSpacing - buttonContainer.distribution = .fillEqually - - if (UIDevice.current.isIPad) { - buttonContainer.layoutMargins = UIEdgeInsets(top: 0, left: Values.iPadButtonContainerMargin, bottom: 0, right: Values.iPadButtonContainerMargin) - buttonContainer.isLayoutMarginsRelativeArrangement = true - } - // User session id container - let userPublicKeyContainer = UIView(wrapping: publicKeyLabel, withInsets: .zero, shouldAdaptForIPadWithWidth: Values.iPadUserSessionIdContainerWidth) - - // Top stack view - let topStackView = UIStackView(arrangedSubviews: [ headerStackView, separator, userPublicKeyContainer, buttonContainer ]) - topStackView.axis = .vertical - topStackView.spacing = Values.largeSpacing - topStackView.alignment = .fill - topStackView.layoutMargins = UIEdgeInsets(top: 0, left: Values.largeSpacing, bottom: 0, right: Values.largeSpacing) - topStackView.isLayoutMarginsRelativeArrangement = true - - // Setting buttons stack view - getSettingButtons().forEach { settingButtonOrSeparator in - settingButtonsStackView.addArrangedSubview(settingButtonOrSeparator) - } - - // Oxen logo - updateLogo() - let logoContainer = UIView() - logoContainer.addSubview(logoImageView) - logoImageView.pin(.top, to: .top, of: logoContainer) - logoContainer.pin(.bottom, to: .bottom, of: logoImageView) - logoImageView.centerXAnchor.constraint(equalTo: logoContainer.centerXAnchor, constant: -2).isActive = true - - // Main stack view - let stackView = UIStackView(arrangedSubviews: [ topStackView, settingButtonsStackView, inviteButton, faqButton, surveyButton, supportButton, helpTranslateButton, logoContainer, versionLabel ]) - stackView.axis = .vertical - stackView.spacing = Values.largeSpacing - stackView.alignment = .fill - stackView.layoutMargins = UIEdgeInsets(top: Values.mediumSpacing, left: 0, bottom: Values.mediumSpacing, right: 0) - stackView.isLayoutMarginsRelativeArrangement = true - viewWidth = stackView.set(.width, to: UIScreen.main.bounds.width) - - // Scroll view - let scrollView = UIScrollView() - scrollView.showsVerticalScrollIndicator = false - scrollView.addSubview(stackView) - stackView.pin(to: scrollView) - view.addSubview(scrollView) - scrollView.pin(to: view) - } - - override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { - super.viewWillTransition(to: size, with: coordinator) - viewWidth?.constant = size.width - } - - private func getSettingButtons() -> [UIView] { - func getSeparator() -> UIView { - let result = UIView() - result.backgroundColor = Colors.separator - result.set(.height, to: Values.separatorThickness) - - return result - } - - func getSettingButton(withTitle title: String, color: UIColor, action selector: Selector) -> UIButton { - let button = UIButton() - button.setTitle(title, for: UIControl.State.normal) - button.setTitleColor(color, for: UIControl.State.normal) - button.titleLabel!.font = .boldSystemFont(ofSize: Values.mediumFontSize) - button.titleLabel!.textAlignment = .center - - func getImage(withColor color: UIColor) -> UIImage { - let rect = CGRect(origin: CGPoint.zero, size: CGSize(width: 1, height: 1)) - UIGraphicsBeginImageContext(rect.size) - - let context = UIGraphicsGetCurrentContext()! - context.setFillColor(color.cgColor) - context.fill(rect) - - let image = UIGraphicsGetImageFromCurrentImageContext() - UIGraphicsEndImageContext() - - return image! - } - - let backgroundColor = isLightMode ? UIColor(hex: 0xF9F9F9) : UIColor(hex: 0x1B1B1B) - button.setBackgroundImage(getImage(withColor: backgroundColor), for: UIControl.State.normal) - - let selectedColor = isLightMode ? UIColor(hex: 0xDFDFDF) : UIColor(hex: 0x0C0C0C) - button.setBackgroundImage(getImage(withColor: selectedColor), for: UIControl.State.highlighted) - button.addTarget(self, action: selector, for: UIControl.Event.touchUpInside) - button.set(.height, to: SettingsVC.buttonHeight) - - return button - } - - let pathButton = getSettingButton(withTitle: NSLocalizedString("vc_path_title", comment: ""), color: Colors.text, action: #selector(showPath)) - let pathStatusView = PathStatusView() - pathStatusView.set(.width, to: PathStatusView.size) - pathStatusView.set(.height, to: PathStatusView.size) - - pathButton.addSubview(pathStatusView) - pathStatusView.pin(.leading, to: .trailing, of: pathButton.titleLabel!, withInset: Values.smallSpacing) - pathStatusView.autoVCenterInSuperview() - - return [ - getSeparator(), - pathButton, - getSeparator(), - getSettingButton(withTitle: NSLocalizedString("vc_settings_privacy_button_title", comment: ""), color: Colors.text, action: #selector(showPrivacySettings)), - getSeparator(), - getSettingButton(withTitle: NSLocalizedString("vc_settings_notifications_button_title", comment: ""), color: Colors.text, action: #selector(showNotificationSettings)), - getSeparator(), - getSettingButton(withTitle: NSLocalizedString("MESSAGE_REQUESTS_TITLE", comment: ""), color: Colors.text, action: #selector(showMessageRequests)), - getSeparator(), - getSettingButton(withTitle: NSLocalizedString("CHATS_TITLE", comment: ""), color: Colors.text, action: #selector(showChatSettings)), - getSeparator(), - getSettingButton(withTitle: NSLocalizedString("vc_settings_recovery_phrase_button_title", comment: ""), color: Colors.text, action: #selector(showSeed)), - getSeparator(), - getSettingButton(withTitle: NSLocalizedString("vc_settings_clear_all_data_button_title", comment: ""), color: Colors.destructive, action: #selector(clearAllData)), - getSeparator() - ] - } - - // MARK: - General - - @objc private func enableCopyButton() { - copyButton.isUserInteractionEnabled = true - - UIView.transition( - with: copyButton, - duration: 0.25, - options: .transitionCrossDissolve, - animations: { - self.copyButton.setTitle("copy".localized(), for: .normal) - }, - completion: nil - ) - } - - func avatarActionSheetTitle() -> String? { return "Update Profile Picture" } - func fromViewController() -> UIViewController { return self } - func hasClearAvatarAction() -> Bool { return false } - func clearAvatarActionLabel() -> String { return "Clear" } - - // MARK: - Updating - - private func handleIsEditingDisplayNameChanged() { - updateNavigationBarButtons() - - UIView.animate(withDuration: 0.25) { - self.displayNameLabel.alpha = self.isEditingDisplayName ? 0 : 1 - self.displayNameTextField.alpha = self.isEditingDisplayName ? 1 : 0 - } - - if isEditingDisplayName { - displayNameTextField.becomeFirstResponder() - } - else { - displayNameTextField.resignFirstResponder() - } - } - - private func updateNavigationBarButtons() { - if isEditingDisplayName { - let cancelButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(handleCancelDisplayNameEditingButtonTapped)) - cancelButton.tintColor = Colors.text - cancelButton.accessibilityLabel = "Cancel button" - cancelButton.isAccessibilityElement = true - navigationItem.leftBarButtonItem = cancelButton - - let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(handleSaveDisplayNameButtonTapped)) - doneButton.tintColor = Colors.text - doneButton.accessibilityLabel = "Done button" - doneButton.isAccessibilityElement = true - navigationItem.rightBarButtonItem = doneButton - } - else { - let closeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "X"), style: .plain, target: self, action: #selector(close)) - closeButton.tintColor = Colors.text - closeButton.accessibilityLabel = "Close button" - closeButton.isAccessibilityElement = true - navigationItem.leftBarButtonItem = closeButton - - let appModeIcon: UIImage - if isSystemDefault { - appModeIcon = isDarkMode ? #imageLiteral(resourceName: "ic_theme_auto").withTintColor(.white) : #imageLiteral(resourceName: "ic_theme_auto").withTintColor(.black) - } - else { - appModeIcon = isDarkMode ? #imageLiteral(resourceName: "ic_dark_theme_on").withTintColor(.white) : #imageLiteral(resourceName: "ic_dark_theme_off").withTintColor(.black) - } - - let appModeButton = UIButton() - appModeButton.setImage(appModeIcon, for: UIControl.State.normal) - appModeButton.tintColor = Colors.text - appModeButton.addTarget(self, action: #selector(switchAppMode), for: UIControl.Event.touchUpInside) - appModeButton.accessibilityLabel = "Switch app mode button" - - let qrCodeIcon = isDarkMode ? #imageLiteral(resourceName: "QRCode").withTintColor(.white) : #imageLiteral(resourceName: "QRCode").withTintColor(.black) - let qrCodeButton = UIButton() - qrCodeButton.setImage(qrCodeIcon, for: UIControl.State.normal) - qrCodeButton.tintColor = Colors.text - qrCodeButton.addTarget(self, action: #selector(showQRCode), for: UIControl.Event.touchUpInside) - qrCodeButton.accessibilityLabel = "Show QR code button" - - let stackView = UIStackView(arrangedSubviews: [ appModeButton, qrCodeButton ]) - stackView.axis = .horizontal - stackView.spacing = Values.mediumSpacing - navigationItem.rightBarButtonItem = UIBarButtonItem(customView: stackView) - } - } - - func avatarDidChange(_ image: UIImage?, filePath: String?) { - updateProfile( - profilePicture: image, - profilePictureFilePath: filePath, - isUpdatingDisplayName: false, - isUpdatingProfilePicture: true - ) - } - - func clearAvatar() { - updateProfile( - profilePicture: nil, - profilePictureFilePath: nil, - isUpdatingDisplayName: false, - isUpdatingProfilePicture: true - ) - } - - private func updateProfile( - profilePicture: UIImage?, - profilePictureFilePath: String?, - isUpdatingDisplayName: Bool, - isUpdatingProfilePicture: Bool - ) { - let userDefaults = UserDefaults.standard - let name: String? = (displayNameToBeUploaded ?? Profile.fetchOrCreateCurrentUser().name) - let imageFilePath: String? = (profilePictureFilePath ?? ProfileManager.profileAvatarFilepath(id: getUserHexEncodedPublicKey())) - - ModalActivityIndicatorViewController.present(fromViewController: navigationController!, canCancel: false) { [weak self, displayNameToBeUploaded] modalActivityIndicator in - ProfileManager.updateLocal( - queue: DispatchQueue.global(qos: .default), - profileName: (name ?? ""), - image: profilePicture, - imageFilePath: imageFilePath, - requiredSync: true, - success: { db, updatedProfile in - if displayNameToBeUploaded != nil { - userDefaults[.lastDisplayNameUpdate] = Date() - } - - if isUpdatingProfilePicture { - userDefaults[.lastProfilePictureUpdate] = Date() - } - - try MessageSender.syncConfiguration(db, forceSyncNow: true).retainUntilComplete() - - // Wait for the database transaction to complete before updating the UI - db.afterNextTransactionCommit { _ in - DispatchQueue.main.async { - modalActivityIndicator.dismiss { - self?.profilePictureView.update( - publicKey: updatedProfile.id, - profile: updatedProfile, - threadVariant: .contact - ) - self?.displayNameLabel.text = name - self?.displayNameToBeUploaded = nil - } - } - } - }, - failure: { error in - DispatchQueue.main.async { - modalActivityIndicator.dismiss { - let isMaxFileSizeExceeded = (error == .avatarUploadMaxFileSizeExceeded) - let title = isMaxFileSizeExceeded ? "Maximum File Size Exceeded" : "Couldn't Update Profile" - let message = isMaxFileSizeExceeded ? "Please select a smaller photo and try again" : "Please check your internet connection and try again" - let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) - alert.addAction(UIAlertAction(title: "BUTTON_OK".localized(), style: .default, handler: nil)) - self?.present(alert, animated: true, completion: nil) - } - } - } - ) - } - } - - @objc override internal func handleAppModeChangedNotification(_ notification: Notification) { - super.handleAppModeChangedNotification(notification) - - updateNavigationBarButtons() - settingButtonsStackView.arrangedSubviews.forEach { settingButton in - settingButtonsStackView.removeArrangedSubview(settingButton) - settingButton.removeFromSuperview() - } - getSettingButtons().forEach { settingButtonOrSeparator in - settingButtonsStackView.addArrangedSubview(settingButtonOrSeparator) // Re-do the setting buttons - } - updateLogo() - } - - private func updateLogo() { - let logoName = isLightMode ? "OxenLightMode" : "OxenDarkMode" - logoImageView.image = UIImage(named: logoName)! - } - - // MARK: - Interaction - - @objc private func close() { - dismiss(animated: true, completion: nil) - } - - @objc private func switchAppMode() { - let alertVC = UIAlertController.init(title: nil, message: nil, preferredStyle: .actionSheet) - let systemModeAction = UIAlertAction.init(title: NSLocalizedString("system_mode_theme", comment: ""), style: .default) { _ in - AppModeManager.shared.setAppModeToSystemDefault() - } - alertVC.addAction(systemModeAction) - - let darkModeAction = UIAlertAction.init(title: NSLocalizedString("dark_mode_theme", comment: ""), style: .default) { _ in - AppModeManager.shared.setCurrentAppMode(to: .dark) - } - alertVC.addAction(darkModeAction) - - let lightModeAction = UIAlertAction.init(title: NSLocalizedString("light_mode_theme", comment: ""), style: .default) { _ in - AppModeManager.shared.setCurrentAppMode(to: .light) - } - alertVC.addAction(lightModeAction) - - let cancelAction = UIAlertAction.init(title: NSLocalizedString("TXT_CANCEL_TITLE", comment: ""), style: .cancel) {_ in } - alertVC.addAction(cancelAction) - - self.presentAlert(alertVC) - } - - @objc private func showQRCode() { - let qrCodeVC = QRCodeVC() - navigationController!.pushViewController(qrCodeVC, animated: true) - } - - @objc private func handleCancelDisplayNameEditingButtonTapped() { - isEditingDisplayName = false - } - - @objc private func handleSaveDisplayNameButtonTapped() { - func showError(title: String, message: String = "") { - let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) - alert.addAction(UIAlertAction(title: NSLocalizedString("BUTTON_OK", comment: ""), style: .default, handler: nil)) - presentAlert(alert) - } - let displayName = displayNameTextField.text!.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) - guard !displayName.isEmpty else { - return showError(title: NSLocalizedString("vc_settings_display_name_missing_error", comment: "")) - } - guard !ProfileManager.isToLong(profileName: displayName) else { - return showError(title: NSLocalizedString("vc_settings_display_name_too_long_error", comment: "")) - } - isEditingDisplayName = false - displayNameToBeUploaded = displayName - updateProfile( - profilePicture: nil, - profilePictureFilePath: nil, - isUpdatingDisplayName: true, - isUpdatingProfilePicture: false - ) - } - - @objc private func showEditProfilePictureUI() { - profilePictureUtilities.showChangeAvatarUI() - } - - @objc private func showEditDisplayNameUI() { - isEditingDisplayName = true - } - - @objc private func copyPublicKey() { - UIPasteboard.general.string = getUserHexEncodedPublicKey() - copyButton.isUserInteractionEnabled = false - UIView.transition(with: copyButton, duration: 0.25, options: .transitionCrossDissolve, animations: { - self.copyButton.setTitle(NSLocalizedString("copied", comment: ""), for: UIControl.State.normal) - }, completion: nil) - Timer.scheduledTimer(timeInterval: 4, target: self, selector: #selector(enableCopyButton), userInfo: nil, repeats: false) - } - - @objc private func sharePublicKey() { - let shareVC = UIActivityViewController(activityItems: [ getUserHexEncodedPublicKey() ], applicationActivities: nil) - if UIDevice.current.isIPad { - shareVC.excludedActivityTypes = [] - shareVC.popoverPresentationController?.permittedArrowDirections = [] - shareVC.popoverPresentationController?.sourceView = self.view - shareVC.popoverPresentationController?.sourceRect = self.view.bounds - } - navigationController!.present(shareVC, animated: true, completion: nil) - } - - @objc private func showPath() { - let pathVC = PathVC() - navigationController!.pushViewController(pathVC, animated: true) - } - - @objc private func showPrivacySettings() { - let privacySettingsVC = PrivacySettingsTableViewController() - navigationController!.pushViewController(privacySettingsVC, animated: true) - } - - @objc private func showNotificationSettings() { - let notificationSettingsVC = NotificationSettingsViewController() - navigationController!.pushViewController(notificationSettingsVC, animated: true) - } - - @objc private func showMessageRequests() { - let viewController: MessageRequestsViewController = MessageRequestsViewController() - self.navigationController?.pushViewController(viewController, animated: true) - } - - @objc private func showChatSettings() { - let chatSettingsVC = ChatSettingsViewController() - navigationController!.pushViewController(chatSettingsVC, animated: true) - } - - @objc private func showSeed() { - let seedModal = SeedModal() - seedModal.modalPresentationStyle = .overFullScreen - seedModal.modalTransitionStyle = .crossDissolve - present(seedModal, animated: true, completion: nil) - } - - @objc private func clearAllData() { - let nukeDataModal = NukeDataModal() - nukeDataModal.modalPresentationStyle = .overFullScreen - nukeDataModal.modalTransitionStyle = .crossDissolve - present(nukeDataModal, animated: true, completion: nil) - } - - @objc private func sendInvitation() { - let invitation = "Hey, I've been using Session to chat with complete privacy and security. Come join me! Download it at https://getsession.org/. My Session ID is \(getUserHexEncodedPublicKey()) !" - let shareVC = UIActivityViewController(activityItems: [ invitation ], applicationActivities: nil) - if UIDevice.current.isIPad { - shareVC.excludedActivityTypes = [] - shareVC.popoverPresentationController?.permittedArrowDirections = [] - shareVC.popoverPresentationController?.sourceView = self.view - shareVC.popoverPresentationController?.sourceRect = self.view.bounds - } - navigationController!.present(shareVC, animated: true, completion: nil) - } - - @objc private func openFAQ() { - let url = URL(string: "https://getsession.org/faq")! - UIApplication.shared.open(url) - } - - @objc private func openSurvey() { - let url = URL(string: "https://getsession.org/survey")! - UIApplication.shared.open(url) - } - - @objc private func shareLogs() { - let shareLogsModal = ShareLogsModal() - shareLogsModal.modalPresentationStyle = .overFullScreen - shareLogsModal.modalTransitionStyle = .crossDissolve - present(shareLogsModal, animated: true, completion: nil) - } - - @objc private func helpTranslate() { - let url = URL(string: "https://crowdin.com/project/session-ios")! - UIApplication.shared.open(url) - } -} diff --git a/SignalUtilitiesKit/Shared View Controllers/OWSNavigationController.m b/SignalUtilitiesKit/Shared View Controllers/OWSNavigationController.m deleted file mode 100644 index 945403c46..000000000 --- a/SignalUtilitiesKit/Shared View Controllers/OWSNavigationController.m +++ /dev/null @@ -1,186 +0,0 @@ -// -// Copyright (c) 2019 Open Whisper Systems. All rights reserved. -// - -#import "AppContext.h" -#import "OWSNavigationController.h" -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface UINavigationController (OWSNavigationController) - -@end - -#pragma mark - - -// Expose that UINavigationController already secretly implements UIGestureRecognizerDelegate -// so we can call [super navigationBar:shouldPopItem] in our own implementation to take advantage -// of the important side effects of that method. -@interface OWSNavigationController () - -@end - -#pragma mark - - -@implementation OWSNavigationController - -- (instancetype)init -{ - self = [super initWithNavigationBarClass:[OWSNavigationBar class] toolbarClass:nil]; - if (!self) { - return self; - } - [self setupNavbar]; - - return self; -} - -- (instancetype)initWithRootViewController:(UIViewController *)rootViewController -{ - self = [self init]; - if (!self) { - return self; - } - [self pushViewController:rootViewController animated:NO]; - - return self; -} - -- (void)dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -#pragma mark - - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.interactivePopGestureRecognizer.delegate = self; -} - -- (BOOL)prefersStatusBarHidden -{ - if (self.ows_prefersStatusBarHidden) { - return self.ows_prefersStatusBarHidden.boolValue; - } - return [super prefersStatusBarHidden]; -} - -#pragma mark - UINavigationBarDelegate - -- (void)setupNavbar -{ - if (![self.navigationBar isKindOfClass:[OWSNavigationBar class]]) { - OWSFailDebug(@"navigationBar was unexpected class: %@", self.navigationBar); - return; - } - OWSNavigationBar *navbar = (OWSNavigationBar *)self.navigationBar; - navbar.navBarLayoutDelegate = self; - [self updateLayoutForNavbar:navbar]; -} - -// All OWSNavigationController serve as the UINavigationBarDelegate for their navbar. -// We override shouldPopItem: in order to cancel some back button presses - for example, -// if a view has unsaved changes. -- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item -{ - OWSAssertDebug(self.interactivePopGestureRecognizer.delegate == self); - UIViewController *topViewController = self.topViewController; - - // wasBackButtonClicked is YES if the back button was pressed but not - // if a back gesture was performed or if the view is popped programmatically. - BOOL wasBackButtonClicked = topViewController.navigationItem == item; - BOOL result = YES; - if (wasBackButtonClicked) { - if ([topViewController conformsToProtocol:@protocol(OWSNavigationView)]) { - id navigationView = (id)topViewController; - result = ![navigationView shouldCancelNavigationBack]; - } - } - - // If we're not going to cancel the pop/back, we need to call the super - // implementation since it has important side effects. - if (result) { - // NOTE: result might end up NO if the super implementation cancels the - // the pop/back. - [super navigationBar:navigationBar shouldPopItem:item]; - result = YES; - } - return result; -} - -#pragma mark - UIGestureRecognizerDelegate - -// We serve as the UIGestureRecognizerDelegate of the interactivePopGestureRecognizer -// in order to cancel some "back" gestures - for example, -// if a view has unsaved changes. -- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer -{ - OWSAssertDebug(gestureRecognizer == self.interactivePopGestureRecognizer); - - UIViewController *topViewController = self.topViewController; - if ([topViewController conformsToProtocol:@protocol(OWSNavigationView)]) { - id navigationView = (id)topViewController; - return ![navigationView shouldCancelNavigationBack]; - } else { - UIViewController *rootViewController = self.viewControllers.firstObject; - if (topViewController == rootViewController) { - return NO; - } else { - return YES; - } - } -} - -#pragma mark - NavBarLayoutDelegate - -- (void)navBarCallLayoutDidChangeWithNavbar:(OWSNavigationBar *)navbar -{ - [self updateLayoutForNavbar:navbar]; - [self setNeedsStatusBarAppearanceUpdate]; -} - -- (UIStatusBarStyle)preferredStatusBarStyle -{ - if (!CurrentAppContext().isMainApp) { - return super.preferredStatusBarStyle; - } else if (OWSWindowManager.sharedManager.hasCall) { - // Status bar is overlaying the green "call banner" - return UIStatusBarStyleLightContent; - } else { - return LKAppModeUtilities.isLightMode ? UIStatusBarStyleDefault : UIStatusBarStyleLightContent; - } -} - -- (void)updateLayoutForNavbar:(OWSNavigationBar *)navbar -{ - OWSLogDebug(@""); - - [UIView setAnimationsEnabled:NO]; - - if (!CurrentAppContext().isMainApp) { - self.additionalSafeAreaInsets = UIEdgeInsetsZero; - } else if (OWSWindowManager.sharedManager.hasCall) { - self.additionalSafeAreaInsets = UIEdgeInsetsMake(20, 0, 0, 0); - } else { - self.additionalSafeAreaInsets = UIEdgeInsetsZero; - } - - [navbar layoutSubviews]; - [UIView setAnimationsEnabled:YES]; -} - -#pragma mark - Orientation - -- (BOOL)shouldAutorotate -{ - return YES; -} - -@end - -NS_ASSUME_NONNULL_END