The old UIButton API is still functional as long as we don't use UIButton.Configuration, so we can safely ignore these warnings until we're ready to adopt the configuration API across the codebase.
152 lines
5.1 KiB
Swift
152 lines
5.1 KiB
Swift
//
|
|
// Copyright 2024 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import SignalServiceKit
|
|
|
|
protocol FindByUsernameDelegate: AnyObject {
|
|
func findByUsername(address: SignalServiceAddress)
|
|
var shouldShowQRCodeButton: Bool { get }
|
|
func openQRCodeScanner()
|
|
}
|
|
|
|
public class FindByUsernameViewController: OWSTableViewController2 {
|
|
|
|
weak var findByUsernameDelegate: FindByUsernameDelegate?
|
|
|
|
private lazy var usernameTextField = OWSTextField(
|
|
placeholder: OWSLocalizedString(
|
|
"FIND_BY_USERNAME_PLACEHOLDER",
|
|
comment: "A placeholder value for the text field for finding an account by their username"
|
|
),
|
|
returnKeyType: .done,
|
|
autocorrectionType: .no,
|
|
autocapitalizationType: .none,
|
|
editingChanged: { [weak self] in
|
|
self?.textFieldDidChange()
|
|
},
|
|
returnPressed: { [weak self] in
|
|
self?.didTapNext()
|
|
}
|
|
)
|
|
|
|
public override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
updateTableContents()
|
|
|
|
title = OWSLocalizedString(
|
|
"FIND_BY_USERNAME_TITLE",
|
|
comment: "Title for the view for finding accounts by their username"
|
|
)
|
|
|
|
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
|
title: CommonStrings.nextButton,
|
|
style: .done,
|
|
target: self,
|
|
action: #selector(didTapNext)
|
|
)
|
|
navigationItem.rightBarButtonItem?.isEnabled = false
|
|
}
|
|
|
|
public override func viewDidAppear(_ animated: Bool) {
|
|
usernameTextField.becomeFirstResponder()
|
|
}
|
|
|
|
// MARK: Table contents
|
|
|
|
private func updateTableContents() {
|
|
let textField = self.usernameTextField
|
|
let contents = OWSTableContents()
|
|
defer {
|
|
self.contents = contents
|
|
}
|
|
|
|
contents.add(OWSTableSection(
|
|
title: nil,
|
|
items: [
|
|
.textFieldItem(textField),
|
|
],
|
|
footerTitle: OWSLocalizedString(
|
|
"FIND_BY_USERNAME_FOOTER",
|
|
comment: "A footer below the username text field describing what should be entered"
|
|
)
|
|
))
|
|
|
|
guard findByUsernameDelegate?.shouldShowQRCodeButton ?? false else {
|
|
return
|
|
}
|
|
|
|
let qrButtonSection = OWSTableSection(items: [
|
|
OWSTableItem(customCellBlock: { [weak self] in
|
|
let cell = OWSTableItem.newCell()
|
|
let button = OWSRoundedButton {
|
|
self?.findByUsernameDelegate?.openQRCodeScanner()
|
|
}
|
|
let font = UIFont.dynamicTypeSubheadline
|
|
let title = NSAttributedString.composed(of: [
|
|
NSAttributedString.with(image: Theme.iconImage(.qrCode), font: font),
|
|
" ",
|
|
OWSLocalizedString(
|
|
"FIND_BY_USERNAME_SCAN_QR_CODE_BUTTON",
|
|
comment: "A button below the username text field which opens a username QR code scanner"
|
|
)
|
|
]).styled(
|
|
with: .font(font.medium()),
|
|
.color(Theme.primaryTextColor)
|
|
)
|
|
button.setAttributedTitle(title, for: .normal)
|
|
button.backgroundColor = Theme.tableCell2PresentedBackgroundColor
|
|
button.dimsWhenHighlighted = true
|
|
button.ows_contentEdgeInsets = .init(hMargin: 16, vMargin: 6)
|
|
cell.addSubview(button)
|
|
button.autoPinEdge(toSuperviewMargin: .top)
|
|
button.autoPinEdge(toSuperviewMargin: .bottom)
|
|
button.autoCenterInSuperviewMargins()
|
|
button.autoPinEdge(toSuperviewMargin: .leading, relation: .greaterThanOrEqual)
|
|
button.autoPinEdge(toSuperviewMargin: .trailing, relation: .greaterThanOrEqual)
|
|
return cell
|
|
}),
|
|
])
|
|
qrButtonSection.hasBackground = false
|
|
contents.add(qrButtonSection)
|
|
}
|
|
|
|
// MARK: Actions
|
|
|
|
@objc
|
|
private func textFieldDidChange() {
|
|
do {
|
|
_ = try Usernames.HashedUsername(forUsername: usernameTextField.text ?? "")
|
|
navigationItem.rightBarButtonItem?.isEnabled = true
|
|
} catch {
|
|
navigationItem.rightBarButtonItem?.isEnabled = false
|
|
}
|
|
}
|
|
|
|
@objc
|
|
private func didTapNext() {
|
|
guard let username = usernameTextField.text else { return }
|
|
usernameTextField.resignFirstResponder()
|
|
databaseStorage.read { tx in
|
|
UsernameQuerier().queryForUsername(
|
|
username: username,
|
|
fromViewController: self,
|
|
tx: tx,
|
|
failureSheetDismissalDelegate: self,
|
|
onSuccess: { [weak self] aci in
|
|
AssertIsOnMainThread()
|
|
self?.findByUsernameDelegate?.findByUsername(address: SignalServiceAddress(aci))
|
|
}
|
|
)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
extension FindByUsernameViewController: SheetDismissalDelegate {
|
|
public func didDismissPresentedSheet() {
|
|
usernameTextField.becomeFirstResponder()
|
|
}
|
|
}
|