Implement preliminary linked devices screen redesign

This commit is contained in:
Niels Andriesse 2019-12-05 14:31:45 +11:00
parent c279eb1be4
commit 67053af50a
18 changed files with 150 additions and 118 deletions

View File

@ -2704,11 +2704,6 @@
B86BD08223399ABF000F5AE3 /* Settings */ = {
isa = PBXGroup;
children = (
B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */,
B894D0702339D6F300B4D94D /* DeviceLinkingModalDelegate.swift */,
B80C6B562384A56D00FDBC8B /* DeviceLinksVC.swift */,
B80C6B582384C4E700FDBC8B /* DeviceNameModal.swift */,
B80C6B5A2384C7F900FDBC8B /* DeviceNameModalDelegate.swift */,
B86BD08023399883000F5AE3 /* QRCodeModal.swift */,
);
path = Settings;
@ -2779,11 +2774,8 @@
children = (
B8B5BCEB2394D869003823C9 /* Button.swift */,
B8BB82AA238F669C00BA5194 /* ConversationCell.swift */,
B86BD08323399ACF000F5AE3 /* Modal.swift */,
B894D0742339EDCF00B4D94D /* NukeDataModal.swift */,
B8BB82AC238F734800BA5194 /* ProfilePictureView.swift */,
B8BB82B02390C37000BA5194 /* SearchBar.swift */,
B86BD08523399CEF000F5AE3 /* SeedModal.swift */,
B8BB82B82394911B00BA5194 /* Separator.swift */,
B8CCF638239721E20091D419 /* TabBar.swift */,
B8BB82B423947F2D00BA5194 /* TextField.swift */,
@ -2802,10 +2794,18 @@
B8CCF63D2397580E0091D419 /* View Controllers */ = {
isa = PBXGroup;
children = (
B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */,
B894D0702339D6F300B4D94D /* DeviceLinkingModalDelegate.swift */,
B80C6B562384A56D00FDBC8B /* DeviceLinksVC.swift */,
B80C6B582384C4E700FDBC8B /* DeviceNameModal.swift */,
B80C6B5A2384C7F900FDBC8B /* DeviceNameModalDelegate.swift */,
B8BB82A4238F627000BA5194 /* HomeVC.swift */,
B86BD08323399ACF000F5AE3 /* Modal.swift */,
B8CCF63623961D6D0091D419 /* NewPrivateChatVC.swift */,
B894D0742339EDCF00B4D94D /* NukeDataModal.swift */,
B8CCF63E23975CFB0091D419 /* JoinPublicChatVC.swift */,
B893063E2383961A005EAA8E /* ScanQRCodeWrapperVC.swift */,
B86BD08523399CEF000F5AE3 /* SeedModal.swift */,
B8CCF6422397711F0091D419 /* SettingsVC.swift */,
);
path = "View Controllers";

View File

@ -61,10 +61,10 @@ final class ConversationCell : UITableViewCell {
private func setUpViewHierarchy() {
// Set the cell background color
backgroundColor = Colors.conversationCellBackground
backgroundColor = Colors.cellBackground
// Set up the highlight color
let selectedBackgroundView = UIView()
selectedBackgroundView.backgroundColor = Colors.conversationCellSelected
selectedBackgroundView.backgroundColor = Colors.cellSelected
self.selectedBackgroundView = selectedBackgroundView
// Set up the unread messages indicator view
unreadMessagesIndicatorView.set(.width, to: Values.accentLineThickness)

View File

@ -17,8 +17,8 @@ final class Colors : NSObject {
@objc static let destructive = UIColor(hex: 0xFF453A)
@objc static let unimportant = UIColor(hex: 0xD8D8D8)
@objc static let border = UIColor(hex: 0x979797)
@objc static let conversationCellBackground = UIColor(hex: 0x1B1B1B)
@objc static let conversationCellSelected = UIColor(hex: 0x0C0C0C)
@objc static let cellBackground = UIColor(hex: 0x1B1B1B)
@objc static let cellSelected = UIColor(hex: 0x0C0C0C)
@objc static let navigationBarBackground = UIColor(hex: 0x161616)
@objc static let searchBarPlaceholder = UIColor(hex: 0x8E8E93) // Also used for the icons
@objc static let searchBarBackground = UIColor(red: 142 / 255, green: 142 / 255, blue: 147 / 255, alpha: 0.12)

View File

@ -19,8 +19,7 @@ final class Gradient : NSObject {
let layer = CAGradientLayer()
layer.frame = UIScreen.main.bounds
layer.colors = [ gradient.start.cgColor, gradient.end.cgColor ]
let index = UInt32((self.layer.sublayers ?? []).count)
self.layer.insertSublayer(layer, at: index)
self.layer.insertSublayer(layer, at: 0)
}
}

View File

@ -32,11 +32,12 @@ final class Values : NSObject {
@objc static let separatorLabelHeight = CGFloat(24)
@objc static var separatorThickness: CGFloat { return 1 / UIScreen.main.scale }
@objc static let tabBarHeight = CGFloat(48)
@objc static let settingsButtonHeight = CGFloat(75)
@objc static let settingButtonHeight = CGFloat(75)
@objc static let modalCornerRadius = CGFloat(10)
@objc static let modalButtonCornerRadius = CGFloat(5)
// MARK: - Distances
@objc static let verySmallSpacing = CGFloat(4)
@objc static let smallSpacing = CGFloat(8)
@objc static let mediumSpacing = CGFloat(16)
@objc static let largeSpacing = CGFloat(24)

View File

@ -10,9 +10,7 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate {
enum Mode : String { case master, slave }
// MARK: Components
private lazy var topSpacer = UIView.spacer(withHeight: 8)
private lazy var spinner = NVActivityIndicatorView(frame: CGRect.zero, type: .circleStrokeSpin, color: .white, padding: nil)
private lazy var spinner = NVActivityIndicatorView(frame: CGRect.zero, type: .circleStrokeSpin, color: Colors.text, padding: nil)
private lazy var qrCodeImageView: UIImageView = {
let result = UIImageView()
@ -22,8 +20,8 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate {
private lazy var titleLabel: UILabel = {
let result = UILabel()
result.textColor = Theme.primaryColor
result.font = UIFont.ows_dynamicTypeHeadlineClamped
result.textColor = Colors.text
result.font = .boldSystemFont(ofSize: Values.mediumFontSize)
result.numberOfLines = 0
result.lineBreakMode = .byWordWrapping
result.textAlignment = .center
@ -32,8 +30,8 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate {
private lazy var subtitleLabel: UILabel = {
let result = UILabel()
result.textColor = Theme.primaryColor
result.font = UIFont.ows_dynamicTypeCaption1Clamped
result.textColor = Colors.text.withAlphaComponent(Values.unimportantElementOpacity)
result.font = .systemFont(ofSize: Values.smallFontSize)
result.numberOfLines = 0
result.lineBreakMode = .byWordWrapping
result.textAlignment = .center
@ -42,8 +40,8 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate {
private lazy var mnemonicLabel: UILabel = {
let result = UILabel()
result.textColor = Theme.primaryColor
result.font = UIFont.ows_dynamicTypeCaption1Clamped
result.textColor = Colors.text
result.font = .systemFont(ofSize: Values.smallFontSize)
result.numberOfLines = 0
result.lineBreakMode = .byWordWrapping
result.textAlignment = .center
@ -51,19 +49,23 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate {
}()
private lazy var buttonStackView: UIStackView = {
let result = UIStackView(arrangedSubviews: [ authorizeButton, cancelButton ])
let result = UIStackView(arrangedSubviews: [ cancelButton, authorizeButton ])
result.axis = .horizontal
result.spacing = Values.mediumSpacing
result.distribution = .fillEqually
return result
}()
private lazy var authorizeButton: OWSFlatButton = {
let result = OWSFlatButton.button(title: NSLocalizedString("Authorize", comment: ""), font: .ows_dynamicTypeBodyClamped, titleColor: .white, backgroundColor: .clear, target: self, selector: #selector(authorizeDeviceLink))
result.setBackgroundColors(upColor: .clear, downColor: .clear)
private lazy var authorizeButton: UIButton = {
let result = UIButton()
result.set(.height, to: Values.mediumButtonHeight)
result.layer.cornerRadius = Values.modalButtonCornerRadius
result.backgroundColor = Colors.accent
result.titleLabel!.font = .systemFont(ofSize: Values.smallFontSize)
result.setTitleColor(Colors.text, for: UIControl.State.normal)
result.setTitle(NSLocalizedString("Authorize", comment: ""), for: UIControl.State.normal)
return result
}()
private lazy var bottomSpacer = UIView.spacer(withHeight: 8)
// MARK: Lifecycle
init(mode: Mode, delegate: DeviceLinkingModalDelegate?) {
@ -93,17 +95,13 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate {
}
override func populateContentView() {
let stackView = UIStackView(arrangedSubviews: [ topSpacer, titleLabel, subtitleLabel, mnemonicLabel, buttonStackView, bottomSpacer ])
let stackView = UIStackView(arrangedSubviews: [ titleLabel, subtitleLabel, mnemonicLabel, buttonStackView ])
switch mode {
case .master:
stackView.insertArrangedSubview(qrCodeImageView, at: 1)
stackView.insertArrangedSubview(UIView.spacer(withHeight: 2), at: 2)
case .slave:
stackView.insertArrangedSubview(spinner, at: 1)
stackView.insertArrangedSubview(UIView.spacer(withHeight: 8), at: 2)
case .master: stackView.insertArrangedSubview(qrCodeImageView, at: 0)
case .slave: stackView.insertArrangedSubview(spinner, at: 0)
}
contentView.addSubview(stackView)
stackView.spacing = 16
stackView.spacing = Values.largeSpacing
stackView.axis = .vertical
switch mode {
case .master:
@ -137,21 +135,17 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate {
let hexEncodedPublicKey = OWSIdentityManager.shared().identityKeyPair()!.hexEncodedPublicKey.removing05PrefixIfNeeded()
mnemonicLabel.text = Mnemonic.hash(hexEncodedString: hexEncodedPublicKey)
}
let buttonHeight = cancelButton.titleLabel!.font.pointSize * 48 / 17
authorizeButton.set(.height, to: buttonHeight)
cancelButton.set(.height, to: buttonHeight)
authorizeButton.addTarget(self, action: #selector(authorizeDeviceLink), for: UIControl.Event.touchUpInside)
authorizeButton.isHidden = true
bottomSpacer.isHidden = true
stackView.pin(.leading, to: .leading, of: contentView, withInset: 16)
stackView.pin(.top, to: .top, of: contentView, withInset: 16)
contentView.pin(.trailing, to: .trailing, of: stackView, withInset: 16)
contentView.pin(.bottom, to: .bottom, of: stackView, withInset: 16)
stackView.pin(.leading, to: .leading, of: contentView, withInset: Values.largeSpacing)
stackView.pin(.top, to: .top, of: contentView, withInset: Values.largeSpacing)
contentView.pin(.trailing, to: .trailing, of: stackView, withInset: Values.largeSpacing)
contentView.pin(.bottom, to: .bottom, of: stackView, withInset: Values.largeSpacing)
}
// MARK: Device Linking
func requestUserAuthorization(for deviceLink: DeviceLink) {
self.deviceLink = deviceLink
topSpacer.isHidden = true
qrCodeImageView.isHidden = true
titleLabel.text = NSLocalizedString("Linking Request Received", comment: "")
subtitleLabel.text = NSLocalizedString("Please check that the words below match the ones shown on your other device", comment: "")
@ -186,14 +180,12 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate {
func handleDeviceLinkAuthorized(_ deviceLink: DeviceLink) {
let session = DeviceLinkingSession.current!
session.stopListeningForLinkingAuthorization()
topSpacer.isHidden = true
spinner.stopAnimating()
spinner.isHidden = true
titleLabel.text = NSLocalizedString("Device Link Authorized", comment: "")
subtitleLabel.text = NSLocalizedString("Your device has been linked successfully", comment: "")
mnemonicLabel.isHidden = true
buttonStackView.isHidden = true
bottomSpacer.isHidden = false
LokiStorageAPI.addDeviceLink(deviceLink).catch { error in
print("[Loki] Failed to add device link due to error: \(error).")
}

View File

@ -18,38 +18,53 @@ final class DeviceLinksVC : UIViewController, UITableViewDataSource, UITableView
private lazy var callToActionView : UIStackView = {
let explanationLabel = UILabel()
explanationLabel.textColor = Theme.primaryColor
explanationLabel.font = UIFont.ows_dynamicTypeSubheadlineClamped
explanationLabel.textColor = Colors.text
explanationLabel.font = .systemFont(ofSize: Values.smallFontSize)
explanationLabel.numberOfLines = 0
explanationLabel.lineBreakMode = .byWordWrapping
explanationLabel.textAlignment = .center
explanationLabel.text = NSLocalizedString("You don't have any linked devices yet", comment: "")
let linkNewDeviceButtonFont = UIFont.ows_dynamicTypeBodyClamped.ows_mediumWeight()
let linkNewDeviceButtonHeight = linkNewDeviceButtonFont.pointSize * 48 / 17
let linkNewDeviceButton = OWSFlatButton.button(title: NSLocalizedString("Link a Device", comment: ""), font: linkNewDeviceButtonFont, titleColor: .lokiGreen(), backgroundColor: .clear, target: self, selector: #selector(linkNewDevice))
linkNewDeviceButton.setBackgroundColors(upColor: .clear, downColor: .clear)
linkNewDeviceButton.autoSetDimension(.height, toSize: linkNewDeviceButtonHeight)
linkNewDeviceButton.button.contentHorizontalAlignment = .left
let linkNewDeviceButton = Button(style: .prominent, size: .medium)
linkNewDeviceButton.setTitle(NSLocalizedString("Link a Device", comment: ""), for: UIControl.State.normal)
linkNewDeviceButton.addTarget(self, action: #selector(linkNewDevice), for: UIControl.Event.touchUpInside)
linkNewDeviceButton.set(.width, to: 160)
let result = UIStackView(arrangedSubviews: [ explanationLabel, linkNewDeviceButton ])
result.axis = .vertical
result.spacing = 4
result.spacing = Values.mediumSpacing
result.alignment = .center
return result
}()
// MARK: Lifecycle
override func viewDidLoad() {
title = NSLocalizedString("Linked Devices", comment: "")
let masterDeviceHexEncodedPublicKey = UserDefaults.standard.string(forKey: "masterDeviceHexEncodedPublicKey")
let isMasterDevice = (masterDeviceHexEncodedPublicKey == nil)
if isMasterDevice {
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(linkNewDevice))
}
view.backgroundColor = Theme.backgroundColor
// Set gradient background
view.backgroundColor = .clear
let gradient = Gradients.defaultLokiBackground
view.setGradient(gradient)
// Set navigation bar background color
let navigationBar = navigationController!.navigationBar
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.shadowImage = UIImage()
navigationBar.isTranslucent = false
navigationBar.barTintColor = Colors.navigationBarBackground
// Customize title
let titleLabel = UILabel()
titleLabel.text = NSLocalizedString("Linked Devices", comment: "")
titleLabel.textColor = Colors.text
titleLabel.font = .boldSystemFont(ofSize: Values.veryLargeFontSize)
navigationItem.titleView = titleLabel
// Set up link new device button
let linkNewDeviceButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(linkNewDevice))
linkNewDeviceButton.tintColor = Colors.text
navigationItem.rightBarButtonItem = linkNewDeviceButton
// Set up constraints
view.addSubview(tableView)
tableView.pin(to: view)
view.addSubview(callToActionView)
callToActionView.center(in: view)
callToActionView.center(.horizontal, in: view)
let verticalCenteringConstraint = callToActionView.center(.vertical, in: view)
verticalCenteringConstraint.constant = -16 // Makes things appear centered visually
// Perform initial update
updateDeviceLinks()
}
@ -61,7 +76,7 @@ final class DeviceLinksVC : UIViewController, UITableViewDataSource, UITableView
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! Cell
let selectedBackgroundView = UIView()
selectedBackgroundView.backgroundColor = Theme.cellSelectedColor
selectedBackgroundView.backgroundColor = Colors.cellSelected
cell.selectedBackgroundView = selectedBackgroundView
let device = deviceLinks[indexPath.row].other
cell.device = device
@ -102,6 +117,7 @@ final class DeviceLinksVC : UIViewController, UITableViewDataSource, UITableView
if deviceLinks.isEmpty {
let deviceLinkingModal = DeviceLinkingModal(mode: .master, delegate: self)
deviceLinkingModal.modalPresentationStyle = .overFullScreen
deviceLinkingModal.modalTransitionStyle = .crossDissolve
present(deviceLinkingModal, animated: true, completion: nil)
} else {
let alert = UIAlertController(title: NSLocalizedString("Multi Device Limit Reached", comment: ""), message: NSLocalizedString("It's currently not allowed to link more than one device.", comment: ""), preferredStyle: .alert)
@ -119,6 +135,8 @@ final class DeviceLinksVC : UIViewController, UITableViewDataSource, UITableView
let deviceNameModal = DeviceNameModal()
deviceNameModal.device = deviceLink.other
deviceNameModal.delegate = self
deviceNameModal.modalPresentationStyle = .overFullScreen
deviceNameModal.modalTransitionStyle = .crossDissolve
self.present(deviceNameModal, animated: true, completion: nil)
})
sheet.addAction(UIAlertAction(title: NSLocalizedString("Unlink", comment: ""), style: .destructive) { [weak self] _ in
@ -169,17 +187,16 @@ private extension DeviceLinksVC {
// MARK: Components
private lazy var titleLabel: UILabel = {
let result = UILabel()
result.textColor = Theme.primaryColor
let font = UIFont.ows_dynamicTypeSubheadlineClamped
result.font = UIFont(descriptor: font.fontDescriptor.withSymbolicTraits(.traitBold)!, size: font.pointSize)
result.textColor = Colors.text
result.font = .boldSystemFont(ofSize: Values.mediumFontSize)
result.lineBreakMode = .byTruncatingTail
return result
}()
private lazy var subtitleLabel: UILabel = {
let result = UILabel()
result.textColor = Theme.primaryColor
result.font = UIFont.ows_dynamicTypeCaption1Clamped
result.textColor = Colors.text
result.font = .systemFont(ofSize: Values.smallFontSize)
result.lineBreakMode = .byTruncatingTail
return result
}()
@ -196,18 +213,18 @@ private extension DeviceLinksVC {
}
private func setUpViewHierarchy() {
backgroundColor = .clear
backgroundColor = Colors.cellBackground
let stackView = UIStackView(arrangedSubviews: [ titleLabel, subtitleLabel ])
stackView.axis = .vertical
stackView.distribution = .equalCentering
stackView.spacing = 4
stackView.spacing = Values.verySmallSpacing
stackView.set(.height, to: 36)
contentView.addSubview(stackView)
stackView.pin(.leading, to: .leading, of: contentView, withInset: 16)
stackView.pin(.top, to: .top, of: contentView, withInset: 8)
contentView.pin(.trailing, to: .trailing, of: stackView, withInset: 16)
contentView.pin(.bottom, to: .bottom, of: stackView, withInset: 8)
stackView.set(.width, to: UIScreen.main.bounds.width - 2 * 16)
stackView.pin(.leading, to: .leading, of: contentView, withInset: Values.largeSpacing)
stackView.pin(.top, to: .top, of: contentView, withInset: Values.mediumSpacing)
contentView.pin(.trailing, to: .trailing, of: stackView, withInset: Values.largeSpacing)
contentView.pin(.bottom, to: .bottom, of: stackView, withInset: Values.mediumSpacing)
stackView.set(.width, to: UIScreen.main.bounds.width - 2 * Values.largeSpacing)
}
// MARK: Updating

View File

@ -5,15 +5,15 @@ final class DeviceNameModal : Modal {
@objc public var delegate: DeviceNameModalDelegate?
// MARK: Components
private lazy var nameTextView: UITextField = {
private lazy var nameTextField: UITextField = {
let result = UITextField()
result.textColor = Theme.primaryColor
result.font = .ows_dynamicTypeBodyClamped
result.textColor = Colors.text
result.font = .systemFont(ofSize: Values.mediumFontSize)
result.textAlignment = .center
let placeholder = NSMutableAttributedString(string: NSLocalizedString("Enter a Name", comment: ""))
placeholder.addAttribute(.foregroundColor, value: UIColor.white.withAlphaComponent(0.5), range: NSRange(location: 0, length: placeholder.length))
placeholder.addAttribute(.foregroundColor, value: Colors.text.withAlphaComponent(Values.unimportantElementOpacity), range: NSRange(location: 0, length: placeholder.length))
result.attributedPlaceholder = placeholder
result.tintColor = .lokiGreen()
result.tintColor = Colors.accent
result.keyboardAppearance = .dark
return result
}()
@ -21,44 +21,51 @@ final class DeviceNameModal : Modal {
// MARK: Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillChangeFrameNotification(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(handleKeyboardWillChangeFrameNotification(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
notificationCenter.addObserver(self, selector: #selector(handleKeyboardWillHideNotification(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}
override func populateContentView() {
// Label
// Set up title label
let titleLabel = UILabel()
titleLabel.textColor = Theme.primaryColor
titleLabel.font = UIFont.ows_dynamicTypeHeadlineClamped
titleLabel.textColor = Colors.text
titleLabel.font = .boldSystemFont(ofSize: Values.mediumFontSize)
titleLabel.text = NSLocalizedString("Change Device Name", comment: "")
titleLabel.numberOfLines = 0
titleLabel.lineBreakMode = .byWordWrapping
titleLabel.textAlignment = .center
// Explanation label
// Set up explanation label
let explanationLabel = UILabel()
explanationLabel.font = UIFont.ows_dynamicTypeCaption1Clamped
explanationLabel.textColor = Colors.text
explanationLabel.font = .systemFont(ofSize: Values.smallFontSize)
explanationLabel.text = NSLocalizedString("Enter the new display name for your device below", comment: "")
explanationLabel.numberOfLines = 0
explanationLabel.textAlignment = .center
explanationLabel.lineBreakMode = .byWordWrapping
explanationLabel.textColor = UIColor.ows_white
// Button stack view
let okButton = OWSFlatButton.button(title: NSLocalizedString("OK", comment: ""), font: .ows_dynamicTypeBodyClamped, titleColor: .white, backgroundColor: .clear, target: self, selector: #selector(changeName))
okButton.setBackgroundColors(upColor: .clear, downColor: .clear)
let buttonStackView = UIStackView(arrangedSubviews: [ okButton, cancelButton ])
// Set up OK button
let okButton = UIButton()
okButton.set(.height, to: Values.mediumButtonHeight)
okButton.layer.cornerRadius = Values.modalButtonCornerRadius
okButton.backgroundColor = Colors.accent
okButton.titleLabel!.font = .systemFont(ofSize: Values.smallFontSize)
okButton.setTitleColor(Colors.text, for: UIControl.State.normal)
okButton.setTitle(NSLocalizedString("OK", comment: ""), for: UIControl.State.normal)
okButton.addTarget(self, action: #selector(changeName), for: UIControl.Event.touchUpInside)
// Set up button stack view
let buttonStackView = UIStackView(arrangedSubviews: [ cancelButton, okButton ])
buttonStackView.axis = .horizontal
buttonStackView.spacing = Values.mediumSpacing
buttonStackView.distribution = .fillEqually
let buttonHeight = cancelButton.titleLabel!.font.pointSize * 48 / 17
okButton.set(.height, to: buttonHeight)
cancelButton.set(.height, to: buttonHeight)
// Stack view
let stackView = UIStackView(arrangedSubviews: [ UIView.spacer(withHeight: 2), titleLabel, explanationLabel, nameTextView, buttonStackView ])
let stackView = UIStackView(arrangedSubviews: [ titleLabel, explanationLabel, nameTextField, buttonStackView ])
stackView.axis = .vertical
stackView.spacing = 16
stackView.spacing = Values.largeSpacing
contentView.addSubview(stackView)
stackView.pin(.leading, to: .leading, of: contentView, withInset: 16)
stackView.pin(.top, to: .top, of: contentView, withInset: 16)
contentView.pin(.trailing, to: .trailing, of: stackView, withInset: 16)
contentView.pin(.bottom, to: .bottom, of: stackView, withInset: 16)
stackView.pin(.leading, to: .leading, of: contentView, withInset: Values.largeSpacing)
stackView.pin(.top, to: .top, of: contentView, withInset: Values.largeSpacing)
contentView.pin(.trailing, to: .trailing, of: stackView, withInset: Values.largeSpacing)
contentView.pin(.bottom, to: .bottom, of: stackView, withInset: Values.largeSpacing)
}
deinit {
@ -74,9 +81,16 @@ final class DeviceNameModal : Modal {
}
}
@objc private func handleKeyboardWillHideNotification(_ notification: Notification) {
verticalCenteringConstraint.constant = 0
UIView.animate(withDuration: 0.25) {
self.view.layoutIfNeeded()
}
}
// MARK: Interaction
@objc private func changeName() {
let name = nameTextView.text!.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
let name = nameTextField.text!.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
if !name.isEmpty {
UserDefaults.standard.set(name, forKey: "\(device.hexEncodedPublicKey)_display_name")
delegate?.handleDeviceNameChanged(to: name, for: device)

View File

@ -72,7 +72,7 @@ final class HomeVC : UIViewController, UITableViewDataSource, UITableViewDelegat
let titleLabel = UILabel()
titleLabel.text = NSLocalizedString("Messages", comment: "")
titleLabel.textColor = Colors.text
titleLabel.font = UIFont.boldSystemFont(ofSize: Values.veryLargeFontSize)
titleLabel.font = .boldSystemFont(ofSize: Values.veryLargeFontSize)
navigationItem.titleView = titleLabel
// Set up table view
tableView.dataSource = self

View File

@ -62,7 +62,7 @@ final class JoinPublicChatVC : UIViewController, UIPageViewControllerDataSource,
let titleLabel = UILabel()
titleLabel.text = NSLocalizedString("Join Public Chat", comment: "")
titleLabel.textColor = Colors.text
titleLabel.font = UIFont.boldSystemFont(ofSize: Values.veryLargeFontSize)
titleLabel.font = .boldSystemFont(ofSize: Values.veryLargeFontSize)
navigationItem.titleView = titleLabel
// Set up page VC
let hasCameraAccess = (AVCaptureDevice.authorizationStatus(for: .video) == .authorized)

View File

@ -61,7 +61,7 @@ final class NewPrivateChatVC : UIViewController, UIPageViewControllerDataSource,
let titleLabel = UILabel()
titleLabel.text = NSLocalizedString("New Conversation", comment: "")
titleLabel.textColor = Colors.text
titleLabel.font = UIFont.boldSystemFont(ofSize: Values.veryLargeFontSize)
titleLabel.font = .boldSystemFont(ofSize: Values.veryLargeFontSize)
navigationItem.titleView = titleLabel
// Set up page VC
let hasCameraAccess = (AVCaptureDevice.authorizationStatus(for: .video) == .authorized)

View File

@ -2,8 +2,7 @@
final class SettingsVC : UIViewController {
private lazy var userHexEncodedPublicKey: String = {
let userDefaults = UserDefaults.standard
if let masterHexEncodedPublicKey = userDefaults.string(forKey: "masterDeviceHexEncodedPublicKey") {
if let masterHexEncodedPublicKey = UserDefaults.standard.string(forKey: "masterDeviceHexEncodedPublicKey") {
return masterHexEncodedPublicKey
} else {
return OWSIdentityManager.shared().identityKeyPair()!.hexEncodedPublicKey
@ -54,6 +53,9 @@ final class SettingsVC : UIViewController {
let closeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "X"), style: .plain, target: self, action: #selector(close))
closeButton.tintColor = Colors.text
navigationItem.leftBarButtonItem = closeButton
let backButton = UIBarButtonItem(title: NSLocalizedString("Back", comment: ""), style: .plain, target: nil, action: nil)
backButton.tintColor = Colors.text
navigationItem.backBarButtonItem = backButton
let qrCodeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "QRCodeFilled"), style: .plain, target: self, action: #selector(showQRCode))
qrCodeButton.tintColor = Colors.text
navigationItem.rightBarButtonItem = qrCodeButton
@ -61,7 +63,7 @@ final class SettingsVC : UIViewController {
let titleLabel = UILabel()
titleLabel.text = NSLocalizedString("Settings", comment: "")
titleLabel.textColor = Colors.text
titleLabel.font = UIFont.boldSystemFont(ofSize: Values.veryLargeFontSize)
titleLabel.font = .boldSystemFont(ofSize: Values.veryLargeFontSize)
navigationItem.titleView = titleLabel
// Set up profile picture view
profilePictureView.hexEncodedPublicKey = userHexEncodedPublicKey
@ -140,16 +142,20 @@ final class SettingsVC : UIViewController {
button.setBackgroundImage(getImage(withColor: Colors.buttonBackground), for: UIControl.State.normal)
button.setBackgroundImage(getImage(withColor: Colors.settingButtonSelected), for: UIControl.State.highlighted)
button.addTarget(self, action: selector, for: UIControl.Event.touchUpInside)
button.set(.height, to: Values.settingsButtonHeight)
button.set(.height, to: Values.settingButtonHeight)
return button
}
return [
var result = [
getSettingButton(withTitle: NSLocalizedString("Privacy", comment: ""), color: Colors.text, action: #selector(showPrivacySettings)),
getSettingButton(withTitle: NSLocalizedString("Notifications", comment: ""), color: Colors.text, action: #selector(showNotificationSettings)),
getSettingButton(withTitle: NSLocalizedString("Linked Devices", comment: ""), color: Colors.text, action: #selector(showLinkedDevices)),
getSettingButton(withTitle: NSLocalizedString("Show Seed", comment: ""), color: Colors.text, action: #selector(showSeed)),
getSettingButton(withTitle: NSLocalizedString("Clear All Data", comment: ""), color: Colors.destructive, action: #selector(clearAllData))
getSettingButton(withTitle: NSLocalizedString("Notifications", comment: ""), color: Colors.text, action: #selector(showNotificationSettings))
]
let isMasterDevice = (UserDefaults.standard.string(forKey: "masterDeviceHexEncodedPublicKey") == nil)
if isMasterDevice {
result.append(getSettingButton(withTitle: NSLocalizedString("Linked Devices", comment: ""), color: Colors.text, action: #selector(showLinkedDevices)))
result.append(getSettingButton(withTitle: NSLocalizedString("Show Seed", comment: ""), color: Colors.text, action: #selector(showSeed)))
}
result.append(getSettingButton(withTitle: NSLocalizedString("Clear All Data", comment: ""), color: Colors.destructive, action: #selector(clearAllData)))
return result
}
override func viewWillAppear(_ animated: Bool) {

View File

@ -2175,7 +2175,7 @@
"SETTINGS_NAV_BAR_TITLE" = "Settings";
/* table section footer */
"SETTINGS_NOTIFICATION_CONTENT_DESCRIPTION" = "Call and Message notifications can appear while your phone is locked. You may wish to limit what is shown in these notifications.";
"SETTINGS_NOTIFICATION_CONTENT_DESCRIPTION" = "Notifications can appear while your phone is locked. You may wish to limit what is shown in these notifications.";
/* table section header */
"SETTINGS_NOTIFICATION_CONTENT_TITLE" = "Notification Content";
@ -2708,3 +2708,6 @@
"This will delete your entire account, including all data, any messages currently linked to your public key, as well as your personal key pair." = "This will delete your entire account, including all data, any messages currently linked to your public key, as well as your personal key pair.";
"Delete" = "Delete";
"This is your personal password. It can be used to restore your account or migrate your account to a new device." = "This is your personal password. It can be used to restore your account or migrate your account to a new device.";
"Notifications can appear while your phone is locked. You may wish to limit what is shown in these notifications." = "Notifications can appear while your phone is locked. You may wish to limit what is shown in these notifications.";
"Notifications" = "Notifications";
"Back" = "Back";