Clean
This commit is contained in:
parent
98fcfce5d1
commit
936424e344
|
@ -60,8 +60,11 @@ final class DeviceLinksVC : UIViewController, UITableViewDataSource, UITableView
|
|||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! Cell
|
||||
let deviceLink = deviceLinks[indexPath.row]
|
||||
cell.deviceLink = deviceLink
|
||||
let selectedBackgroundView = UIView()
|
||||
selectedBackgroundView.backgroundColor = Theme.cellSelectedColor
|
||||
cell.selectedBackgroundView = selectedBackgroundView
|
||||
let device = deviceLinks[indexPath.row].other
|
||||
cell.device = device
|
||||
return cell
|
||||
}
|
||||
|
||||
|
@ -86,6 +89,7 @@ final class DeviceLinksVC : UIViewController, UITableViewDataSource, UITableView
|
|||
}
|
||||
|
||||
func handleDeviceLinkAuthorized(_ deviceLink: DeviceLink) {
|
||||
dismiss(animated: true, completion: nil)
|
||||
updateDeviceLinks()
|
||||
}
|
||||
|
||||
|
@ -107,22 +111,25 @@ final class DeviceLinksVC : UIViewController, UITableViewDataSource, UITableView
|
|||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
let deviceLink = deviceLinks[indexPath.row]
|
||||
defer { tableView.deselectRow(at: indexPath, animated: true) }
|
||||
let device = deviceLinks[indexPath.row].other
|
||||
let sheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
|
||||
sheet.addAction(UIAlertAction(title: NSLocalizedString("Change Name", comment: ""), style: .default) { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
let deviceNameModal = DeviceNameModal()
|
||||
deviceNameModal.deviceLink = deviceLink
|
||||
deviceNameModal.device = device
|
||||
deviceNameModal.delegate = self
|
||||
self.present(deviceNameModal, animated: true, completion: nil)
|
||||
})
|
||||
sheet.addAction(UIAlertAction(title: NSLocalizedString("Unlink", comment: ""), style: .destructive) { _ in
|
||||
// TODO: Implement
|
||||
})
|
||||
sheet.addAction(UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel) { _ in })
|
||||
present(sheet, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
@objc func handleDeviceNameChanged(to name: String, for device: DeviceLink.Device) {
|
||||
dismiss(animated: true, completion: nil)
|
||||
updateUI()
|
||||
}
|
||||
}
|
||||
|
@ -132,13 +139,14 @@ final class DeviceLinksVC : UIViewController, UITableViewDataSource, UITableView
|
|||
private extension DeviceLinksVC {
|
||||
|
||||
final class Cell : UITableViewCell {
|
||||
var deviceLink: DeviceLink! { didSet { update() } }
|
||||
var device: DeviceLink.Device! { didSet { update() } }
|
||||
|
||||
// MARK: Components
|
||||
private lazy var titleLabel: UILabel = {
|
||||
let result = UILabel()
|
||||
result.textColor = Theme.primaryColor
|
||||
result.font = UIFont.ows_dynamicTypeSubheadlineClamped
|
||||
let font = UIFont.ows_dynamicTypeSubheadlineClamped
|
||||
result.font = UIFont(descriptor: font.fontDescriptor.withSymbolicTraits(.traitBold)!, size: font.pointSize)
|
||||
result.lineBreakMode = .byTruncatingTail
|
||||
return result
|
||||
}()
|
||||
|
@ -179,14 +187,8 @@ private extension DeviceLinksVC {
|
|||
|
||||
// MARK: Updating
|
||||
private func update() {
|
||||
if let displayName = deviceLink.displayName {
|
||||
titleLabel.text = displayName
|
||||
subtitleLabel.text = deviceLink.other.hexEncodedPublicKey
|
||||
subtitleLabel.isHidden = false
|
||||
} else {
|
||||
titleLabel.text = deviceLink.other.hexEncodedPublicKey
|
||||
subtitleLabel.isHidden = true
|
||||
}
|
||||
titleLabel.text = device.displayName
|
||||
subtitleLabel.text = Mnemonic.encode(hexEncodedString: device.hexEncodedPublicKey.removing05PrefixIfNeeded()).split(separator: " ")[0..<3].joined(separator: " ")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
@objc(LKDeviceNameModal)
|
||||
final class DeviceNameModal : Modal {
|
||||
@objc public var deviceLink: DeviceLink!
|
||||
@objc public var device: DeviceLink.Device!
|
||||
@objc public var delegate: DeviceNameModalDelegate?
|
||||
|
||||
// MARK: Components
|
||||
|
@ -9,8 +9,9 @@ final class DeviceNameModal : Modal {
|
|||
let result = UITextField()
|
||||
result.textColor = Theme.primaryColor
|
||||
result.font = .ows_dynamicTypeBodyClamped
|
||||
result.textAlignment = .center
|
||||
let placeholder = NSMutableAttributedString(string: NSLocalizedString("Enter a Name", comment: ""))
|
||||
placeholder.addAttribute(.foregroundColor, value: Theme.placeholderColor, range: NSRange(location: 0, length: placeholder.length))
|
||||
placeholder.addAttribute(.foregroundColor, value: UIColor.white.withAlphaComponent(0.5), range: NSRange(location: 0, length: placeholder.length))
|
||||
result.attributedPlaceholder = placeholder
|
||||
result.tintColor = .lokiGreen()
|
||||
result.keyboardAppearance = .dark
|
||||
|
@ -18,6 +19,11 @@ final class DeviceNameModal : Modal {
|
|||
}()
|
||||
|
||||
// MARK: Lifecycle
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillChangeFrameNotification(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
|
||||
}
|
||||
|
||||
override func populateContentView() {
|
||||
// Label
|
||||
let titleLabel = UILabel()
|
||||
|
@ -55,10 +61,29 @@ final class DeviceNameModal : Modal {
|
|||
contentView.pin(.bottom, to: .bottom, of: stackView, withInset: 16)
|
||||
}
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
|
||||
// MARK: Updating
|
||||
@objc private func handleKeyboardWillChangeFrameNotification(_ notification: Notification) {
|
||||
guard let newHeight = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.size.height else { return }
|
||||
verticalCenteringConstraint.constant = -(newHeight / 2)
|
||||
UIView.animate(withDuration: 0.25) {
|
||||
self.view.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Interaction
|
||||
@objc private func changeName() {
|
||||
let name = nameTextView.text!.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
|
||||
UserDefaults.standard.set(name, forKey: "\(deviceLink.other.hexEncodedPublicKey)_display_name")
|
||||
delegate?.handleDeviceNameChanged(to: name, for: deviceLink.other)
|
||||
if !name.isEmpty {
|
||||
UserDefaults.standard.set(name, forKey: "\(device.hexEncodedPublicKey)_display_name")
|
||||
delegate?.handleDeviceNameChanged(to: name, for: device)
|
||||
} else {
|
||||
let alert = UIAlertController(title: NSLocalizedString("Error", comment: ""), message: NSLocalizedString("Please pick a name", comment: ""), preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: ""), accessibilityIdentifier: nil, style: .default, handler: nil))
|
||||
present(alert, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ final class QRCodeModal : Modal {
|
|||
// Label
|
||||
let label = UILabel()
|
||||
label.font = UIFont.ows_dynamicTypeSubheadlineClamped
|
||||
label.text = NSLocalizedString("This is your personal QR code. Other people can scan it to start a secure conversation with you.", comment: "")
|
||||
label.text = NSLocalizedString("This is your QR code. Other people can scan it to start a secure conversation with you.", comment: "")
|
||||
label.numberOfLines = 0
|
||||
label.textAlignment = .center
|
||||
label.lineBreakMode = .byWordWrapping
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import NVActivityIndicatorView
|
||||
|
||||
@objc(LKSeedModal)
|
||||
final class SeedModal : Modal {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
@objc(LKModal)
|
||||
internal class Modal : UIViewController {
|
||||
private(set) var verticalCenteringConstraint: NSLayoutConstraint!
|
||||
|
||||
// MARK: Components
|
||||
lazy var contentView: UIView = {
|
||||
|
@ -31,7 +32,7 @@ internal class Modal : UIViewController {
|
|||
view.addSubview(contentView)
|
||||
contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 32).isActive = true
|
||||
view.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 32).isActive = true
|
||||
contentView.center(.vertical, in: view)
|
||||
verticalCenteringConstraint = contentView.center(.vertical, in: view)
|
||||
populateContentView()
|
||||
}
|
||||
|
||||
|
|
|
@ -22,14 +22,20 @@ extension UIView {
|
|||
}
|
||||
}
|
||||
|
||||
func pin(_ constraineeEdge: HorizontalEdge, to constrainerEdge: HorizontalEdge, of view: UIView, withInset inset: CGFloat = 0) {
|
||||
@discardableResult
|
||||
func pin(_ constraineeEdge: HorizontalEdge, to constrainerEdge: HorizontalEdge, of view: UIView, withInset inset: CGFloat = 0) -> NSLayoutConstraint {
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
anchor(from: constraineeEdge).constraint(equalTo: view.anchor(from: constrainerEdge), constant: inset).isActive = true
|
||||
let constraint = anchor(from: constraineeEdge).constraint(equalTo: view.anchor(from: constrainerEdge), constant: inset)
|
||||
constraint.isActive = true
|
||||
return constraint
|
||||
}
|
||||
|
||||
func pin(_ constraineeEdge: VerticalEdge, to constrainerEdge: VerticalEdge, of view: UIView, withInset inset: CGFloat = 0) {
|
||||
@discardableResult
|
||||
func pin(_ constraineeEdge: VerticalEdge, to constrainerEdge: VerticalEdge, of view: UIView, withInset inset: CGFloat = 0) -> NSLayoutConstraint {
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
anchor(from: constraineeEdge).constraint(equalTo: view.anchor(from: constrainerEdge), constant: inset).isActive = true
|
||||
let constraint = anchor(from: constraineeEdge).constraint(equalTo: view.anchor(from: constrainerEdge), constant: inset)
|
||||
constraint.isActive = true
|
||||
return constraint
|
||||
}
|
||||
|
||||
func pin(to view: UIView) {
|
||||
|
@ -37,12 +43,17 @@ extension UIView {
|
|||
[ VerticalEdge.top, VerticalEdge.bottom ].forEach { pin($0, to: $0, of: view) }
|
||||
}
|
||||
|
||||
func center(_ direction: Direction, in view: UIView) {
|
||||
@discardableResult
|
||||
func center(_ direction: Direction, in view: UIView) -> NSLayoutConstraint {
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
switch direction {
|
||||
case .horizontal: centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
|
||||
case .vertical: centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
|
||||
}
|
||||
let constraint: NSLayoutConstraint = {
|
||||
switch direction {
|
||||
case .horizontal: return centerXAnchor.constraint(equalTo: view.centerXAnchor)
|
||||
case .vertical: return centerYAnchor.constraint(equalTo: view.centerYAnchor)
|
||||
}
|
||||
}()
|
||||
constraint.isActive = true
|
||||
return constraint
|
||||
}
|
||||
|
||||
func center(in view: UIView) {
|
||||
|
@ -50,11 +61,16 @@ extension UIView {
|
|||
center(.vertical, in: view)
|
||||
}
|
||||
|
||||
func set(_ dimension: Dimension, to size: CGFloat) {
|
||||
@discardableResult
|
||||
func set(_ dimension: Dimension, to size: CGFloat) -> NSLayoutConstraint {
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
switch dimension {
|
||||
case .width: widthAnchor.constraint(equalToConstant: size).isActive = true
|
||||
case .height: heightAnchor.constraint(equalToConstant: size).isActive = true
|
||||
}
|
||||
let constraint: NSLayoutConstraint = {
|
||||
switch dimension {
|
||||
case .width: return widthAnchor.constraint(equalToConstant: size)
|
||||
case .height: return heightAnchor.constraint(equalToConstant: size)
|
||||
}
|
||||
}()
|
||||
constraint.isActive = true
|
||||
return constraint
|
||||
}
|
||||
}
|
||||
|
|
|
@ -247,6 +247,9 @@
|
|||
|
||||
[section addItem:[OWSTableItem itemWithTitle:NSLocalizedString(@"Share Public Key", @"") actionBlock:^{ [weakSelf sharePublicKey]; }]];
|
||||
[section addItem:[OWSTableItem itemWithTitle:NSLocalizedString(@"Show QR Code", @"") actionBlock:^{ [weakSelf showQRCode]; }]];
|
||||
if (isMasterDevice) {
|
||||
[section addItem:[OWSTableItem itemWithTitle:NSLocalizedString(@"Show Seed", @"") actionBlock:^{ [weakSelf showSeed]; }]];
|
||||
}
|
||||
[section addItem:[OWSTableItem itemWithTitle:NSLocalizedString(@"Clear All Data", @"") actionBlock:^{ [weakSelf clearAllData]; }]];
|
||||
|
||||
if (TSAccountManager.sharedInstance.isDeregistered) {
|
||||
|
|
|
@ -159,7 +159,7 @@ NSString *const kProfileView_LastPresentedDate = @"kProfileView_LastPresentedDat
|
|||
UILabel *avatarLabel = [UILabel new];
|
||||
avatarLabel.text = NSLocalizedString(@"Profile Picture", @"");
|
||||
avatarLabel.textColor = Theme.primaryColor;
|
||||
avatarLabel.font = [UIFont ows_mediumFontWithSize:fontSizePoints];
|
||||
avatarLabel.font = [UIFont ows_regularFontWithSize:fontSizePoints];
|
||||
[avatarRow addSubview:avatarLabel];
|
||||
[avatarLabel autoPinLeadingToSuperviewMargin];
|
||||
[avatarLabel autoVCenterInSuperview];
|
||||
|
|
|
@ -2612,7 +2612,7 @@
|
|||
"Loki News" = "Loki News";
|
||||
"Loki Messenger Updates" = "Loki Messenger Updates";
|
||||
"Show QR Code" = "Show QR Code";
|
||||
"This is your personal QR code. Other people can scan it to start a secure conversation with you." = "This is your personal QR code. Other people can scan it to start a secure conversation with you.";
|
||||
"This is your QR code. Other people can scan it to start a secure conversation with you." = "This is your QR code. Other people can scan it to start a secure conversation with you.";
|
||||
"Scan a QR Code Instead" = "Scan a QR Code Instead";
|
||||
"Loki Messenger needs camera access to scan QR codes." = "Loki Messenger needs camera access to scan QR codes.";
|
||||
"You can enable camera access in your device settings." = "You can enable camera access in your device settings.";
|
||||
|
@ -2663,3 +2663,5 @@
|
|||
"Change Device Name" = "Change Device Name";
|
||||
"Enter the new display name for your device below" = "Enter the new display name for your device below";
|
||||
"Enter a Name" = "Enter a Name";
|
||||
"Error" = "Error";
|
||||
"Please pick a name" = "Please pick a name";
|
||||
|
|
|
@ -4,14 +4,6 @@ public final class DeviceLink : NSObject, NSCoding {
|
|||
@objc public let master: Device
|
||||
@objc public let slave: Device
|
||||
|
||||
@objc public var displayName: String? {
|
||||
if let customDisplayName = UserDefaults.standard.string(forKey: "\(other.hexEncodedPublicKey)_display_name") {
|
||||
return customDisplayName
|
||||
} else {
|
||||
return Mnemonic.encode(hexEncodedString: other.hexEncodedPublicKey.removing05PrefixIfNeeded()).split(separator: " ")[0..<3].joined(separator: " ")
|
||||
}
|
||||
}
|
||||
|
||||
@objc public var isAuthorized: Bool { return master.signature != nil }
|
||||
|
||||
@objc public var other: Device {
|
||||
|
@ -25,6 +17,14 @@ public final class DeviceLink : NSObject, NSCoding {
|
|||
@objc public let hexEncodedPublicKey: String
|
||||
@objc public let signature: Data?
|
||||
|
||||
@objc public var displayName: String {
|
||||
if let customDisplayName = UserDefaults.standard.string(forKey: "\(hexEncodedPublicKey)_display_name") {
|
||||
return customDisplayName
|
||||
} else {
|
||||
return Mnemonic.encode(hexEncodedString: hexEncodedPublicKey.removing05PrefixIfNeeded()).split(separator: " ")[0..<3].joined(separator: " ")
|
||||
}
|
||||
}
|
||||
|
||||
@objc public init(hexEncodedPublicKey: String, signature: Data? = nil) {
|
||||
self.hexEncodedPublicKey = hexEncodedPublicKey
|
||||
self.signature = signature
|
||||
|
|
Loading…
Reference in New Issue