Merge remote-tracking branch 'private/release/2.45.0'
This commit is contained in:
commit
22f4177f05
@ -1,230 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objc
|
||||
public class SecondaryLinkingQRCodeViewController: OnboardingBaseViewController {
|
||||
|
||||
var provisioningController: ProvisioningController?
|
||||
|
||||
func configure(provisioningController: ProvisioningController) {
|
||||
assert(self.provisioningController == nil)
|
||||
self.provisioningController = provisioningController
|
||||
}
|
||||
|
||||
override public func loadView() {
|
||||
view = UIView()
|
||||
|
||||
view.backgroundColor = Theme.backgroundColor
|
||||
view.layoutMargins = .zero
|
||||
|
||||
let titleLabel = self.titleLabel(text: NSLocalizedString("ONBOARDING_SECONDARY_SCAN_CODE_TITLE", comment: "header text while displaying a QR code which, when scanned, will link this device."))
|
||||
view.addSubview(titleLabel)
|
||||
titleLabel.accessibilityIdentifier = "onboarding.linking.titleLabel"
|
||||
titleLabel.setContentHuggingHigh()
|
||||
|
||||
let bodyLabel = self.titleLabel(text: NSLocalizedString("ONBOARDING_SECONDARY_SCAN_CODE_BODY", comment: "body text while displaying a QR code which, when scanned, will link this device."))
|
||||
bodyLabel.font = UIFont.ows_dynamicTypeBody
|
||||
bodyLabel.numberOfLines = 0
|
||||
view.addSubview(bodyLabel)
|
||||
bodyLabel.accessibilityIdentifier = "onboarding.linking.bodyLabel"
|
||||
bodyLabel.setContentHuggingHigh()
|
||||
|
||||
guard let provisioningController = provisioningController else {
|
||||
owsFailDebug("provisioningController was unexpectedly nil")
|
||||
return
|
||||
}
|
||||
let qrCodeView = ProvisioningQRCodeView()
|
||||
provisioningController.getProvisioningQRImage().done { qrImage in
|
||||
qrCodeView.setQRImage(qrImage)
|
||||
}.retainUntilComplete()
|
||||
qrCodeView.setContentHuggingVerticalLow()
|
||||
|
||||
let explanationLabel = UILabel()
|
||||
explanationLabel.text = NSLocalizedString("ONBOARDING_SECONDARY_SCAN_CODE_HELP_TEXT",
|
||||
comment: "Link text for page with troubleshooting info shown on the QR scanning screen")
|
||||
explanationLabel.textColor = .ows_signalBlue
|
||||
explanationLabel.font = UIFont.ows_dynamicTypeSubheadlineClamped
|
||||
explanationLabel.numberOfLines = 0
|
||||
explanationLabel.textAlignment = .center
|
||||
explanationLabel.lineBreakMode = .byWordWrapping
|
||||
explanationLabel.isUserInteractionEnabled = true
|
||||
explanationLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTapExplanationLabel)))
|
||||
explanationLabel.accessibilityIdentifier = "onboarding.linking.helpLink"
|
||||
explanationLabel.setContentHuggingHigh()
|
||||
|
||||
let stackView = UIStackView(arrangedSubviews: [
|
||||
titleLabel,
|
||||
bodyLabel,
|
||||
qrCodeView,
|
||||
explanationLabel
|
||||
])
|
||||
stackView.axis = .vertical
|
||||
stackView.alignment = .fill
|
||||
stackView.layoutMargins = primaryLayoutMargins
|
||||
stackView.spacing = 12
|
||||
stackView.isLayoutMarginsRelativeArrangement = true
|
||||
view.addSubview(stackView)
|
||||
stackView.autoPinWidthToSuperview()
|
||||
stackView.autoPin(toTopLayoutGuideOf: self, withInset: 0)
|
||||
stackView.autoPin(toBottomLayoutGuideOf: self, withInset: 0)
|
||||
}
|
||||
|
||||
// MARK: - Events
|
||||
|
||||
@objc
|
||||
func didTapExplanationLabel(sender: UIGestureRecognizer) {
|
||||
guard sender.state == .recognized else {
|
||||
owsFailDebug("unexpected state: \(sender.state)")
|
||||
return
|
||||
}
|
||||
|
||||
let alert = UIAlertController(title: "TODO", message: nil, preferredStyle: .alert)
|
||||
alert.addAction(OWSAlerts.dismissAction)
|
||||
|
||||
presentAlert(alert)
|
||||
}
|
||||
}
|
||||
|
||||
class OnboardingConfirmSecondaryLinkViewController: OnboardingBaseViewController {
|
||||
var provisioningController: ProvisioningController?
|
||||
|
||||
func configure(provisioningController: ProvisioningController) {
|
||||
assert(self.provisioningController == nil)
|
||||
self.provisioningController = provisioningController
|
||||
}
|
||||
|
||||
let textField = UITextField()
|
||||
|
||||
// MARK: UIViewController overrides
|
||||
|
||||
override public func loadView() {
|
||||
view = UIView()
|
||||
|
||||
view.backgroundColor = Theme.backgroundColor
|
||||
view.layoutMargins = .zero
|
||||
|
||||
let titleLabel = self.titleLabel(text: NSLocalizedString("ONBOARDING_SECONDARY_CHOOSE_DEVICE_NAME", comment: "header text when this device is being added as a secondary"))
|
||||
view.addSubview(titleLabel)
|
||||
titleLabel.accessibilityIdentifier = "onboarding.linking.titleLabel"
|
||||
titleLabel.setContentHuggingHigh()
|
||||
|
||||
// FIXME NEEDS_DESIGN
|
||||
textField.borderStyle = .roundedRect
|
||||
let textFieldWrapper = UIView()
|
||||
textFieldWrapper.addSubview(textField)
|
||||
textField.autoSetDimension(.width, toSize: 200)
|
||||
textField.autoCenterInSuperview()
|
||||
|
||||
let primaryButton = self.primaryButton(title: NSLocalizedString("ONBOARDING_SECONDARY_COMPLETE_LINKING_PROCESS", comment: "body text while displaying a QR code which, when scanned, will link this device."),
|
||||
selector: #selector(didTapFinalizeLinking))
|
||||
primaryButton.accessibilityIdentifier = "onboarding.confirmLink.confirmButton"
|
||||
let primaryButtonView = OWSFlatButton.horizontallyWrap(primaryButton: primaryButton)
|
||||
|
||||
let stackView = UIStackView(arrangedSubviews: [
|
||||
titleLabel,
|
||||
textFieldWrapper,
|
||||
UIView.vStretchingSpacer(),
|
||||
primaryButtonView
|
||||
])
|
||||
|
||||
stackView.axis = .vertical
|
||||
stackView.alignment = .fill
|
||||
stackView.layoutMargins = primaryLayoutMargins
|
||||
stackView.spacing = 12
|
||||
stackView.isLayoutMarginsRelativeArrangement = true
|
||||
view.addSubview(stackView)
|
||||
stackView.autoPinWidthToSuperview()
|
||||
stackView.autoPin(toTopLayoutGuideOf: self, withInset: 0)
|
||||
stackView.autoPin(toBottomLayoutGuideOf: self, withInset: 0)
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
@objc
|
||||
func didTapFinalizeLinking() {
|
||||
// TODO sanatize
|
||||
guard let deviceName = textField.text?.ows_stripped() else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let provisioningController = self.provisioningController else {
|
||||
owsFailDebug("provisioningController was unexpectedly nil")
|
||||
return
|
||||
}
|
||||
|
||||
provisioningController.provisioningDidChooseDeviceName(deviceName)
|
||||
}
|
||||
}
|
||||
|
||||
public class ProvisioningQRCodeView: UIView {
|
||||
|
||||
// MARK: - UIView overrides
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
addSubview(qrCodeWrapper)
|
||||
qrCodeWrapper.autoCenterInSuperview()
|
||||
qrCodeWrapper.autoPinToSquareAspectRatio()
|
||||
NSLayoutConstraint.autoSetPriority(.defaultLow) {
|
||||
qrCodeWrapper.autoPinEdgesToSuperviewMargins()
|
||||
}
|
||||
|
||||
qrCodeWrapper.addSubview(placeholderView)
|
||||
placeholderView.autoPinEdgesToSuperviewMargins()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override public func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
qrCodeWrapper.layer.cornerRadius = qrCodeWrapper.frame.width / 2
|
||||
}
|
||||
|
||||
// MARK: - Subviews
|
||||
|
||||
var qrCodeView: UIView?
|
||||
|
||||
lazy var qrCodeWrapper: UIView = {
|
||||
let wrapper = UIView()
|
||||
wrapper.backgroundColor = .ows_gray02
|
||||
return wrapper
|
||||
}()
|
||||
|
||||
lazy var placeholderView: UIView = {
|
||||
let placeholder = UIView()
|
||||
|
||||
let activityIndicator = UIActivityIndicatorView(style: .white)
|
||||
placeholder.addSubview(activityIndicator)
|
||||
activityIndicator.autoCenterInSuperview()
|
||||
activityIndicator.autoSetDimensions(to: .init(width: 40, height: 40))
|
||||
activityIndicator.startAnimating()
|
||||
|
||||
return placeholder
|
||||
}()
|
||||
|
||||
// MARK: -
|
||||
|
||||
public func setQRImage(_ qrImage: UIImage) {
|
||||
assert(qrCodeView == nil)
|
||||
placeholderView.removeFromSuperview()
|
||||
|
||||
let qrCodeView = UIImageView(image: qrImage)
|
||||
|
||||
// Don't antialias QR Codes.
|
||||
qrCodeView.layer.magnificationFilter = .nearest
|
||||
qrCodeView.layer.minificationFilter = .nearest
|
||||
|
||||
self.qrCodeView = qrCodeView
|
||||
|
||||
qrCodeWrapper.addSubview(qrCodeView)
|
||||
qrCodeView.autoPinToSquareAspectRatio()
|
||||
qrCodeView.autoCenterInSuperview()
|
||||
qrCodeView.autoMatch(.height, to: .height, of: qrCodeWrapper, withMultiplier: 0.6)
|
||||
}
|
||||
}
|
||||
@ -255,6 +255,7 @@ private class SignalCallData: NSObject {
|
||||
|
||||
private func tryToSendIceUpdates() {
|
||||
AssertIsOnMainThread()
|
||||
Logger.info("")
|
||||
|
||||
guard !outgoingIceUpdatesInFlight else {
|
||||
Logger.verbose("Enqueued outgoing ice update")
|
||||
@ -279,6 +280,7 @@ private class SignalCallData: NSObject {
|
||||
let sendPromise = self.messageSender.sendMessage(.promise, callMessage.asPreparer)
|
||||
.done { [weak self] in
|
||||
AssertIsOnMainThread()
|
||||
Logger.info("sent ice update call message")
|
||||
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
@ -806,7 +808,7 @@ private class SignalCallData: NSObject {
|
||||
*/
|
||||
public func handleRemoteAddedIceCandidate(thread: TSContactThread, callId: UInt64, sdp: String, lineIndex: Int32, mid: String) {
|
||||
AssertIsOnMainThread()
|
||||
Logger.debug("for callId: \(callId)")
|
||||
Logger.info("for callId: \(callId)")
|
||||
|
||||
guard let callData = self.callData,
|
||||
callData.call.signalingId == callId else {
|
||||
@ -913,6 +915,7 @@ private class SignalCallData: NSObject {
|
||||
*/
|
||||
private func handleRinging() {
|
||||
AssertIsOnMainThread()
|
||||
Logger.info("")
|
||||
|
||||
guard let callData = self.callData else {
|
||||
// This will only be called for the current callConnection, so
|
||||
@ -1207,7 +1210,7 @@ private class SignalCallData: NSObject {
|
||||
let callMessage = OWSOutgoingCallMessage(thread: call.thread, hangupMessage: try hangupBuilder.build())
|
||||
let sendPromise = messageSender.sendMessage(.promise, callMessage.asPreparer)
|
||||
.done {
|
||||
Logger.debug("sent hangup call message to \(call.thread.contactAddress)")
|
||||
Logger.info("sent hangup call message to \(call.thread.contactAddress)")
|
||||
}.ensure {
|
||||
self.terminate(callData: callData)
|
||||
}.catch { error in
|
||||
@ -1393,6 +1396,7 @@ private class SignalCallData: NSObject {
|
||||
|
||||
public func callConnection(_ callConnectionParam: CallConnection, onCallEvent event: CallEvent, callId: UInt64) {
|
||||
AssertIsOnMainThread()
|
||||
Logger.info("")
|
||||
|
||||
guard FeatureFlags.calling else {
|
||||
Logger.info("Ignoring call event on unsupported device.")
|
||||
@ -1471,7 +1475,7 @@ private class SignalCallData: NSObject {
|
||||
|
||||
public func callConnection(_ callConnectionParam: CallConnection, onCallError error: String, callId: UInt64) {
|
||||
AssertIsOnMainThread()
|
||||
Logger.debug("Got an error from RingRTC: \(error)")
|
||||
Logger.info("Got an error from RingRTC: \(error)")
|
||||
|
||||
guard let callData = self.callData,
|
||||
callConnectionParam == callData.callConnection else {
|
||||
@ -1494,7 +1498,7 @@ private class SignalCallData: NSObject {
|
||||
let callMessage = OWSOutgoingCallMessage(thread: call.thread, hangupMessage: try hangupBuilder.build())
|
||||
let sendPromise = messageSender.sendMessage(.promise, callMessage.asPreparer)
|
||||
.done {
|
||||
Logger.debug("sent hangup call message to \(call.thread.contactAddress)")
|
||||
Logger.info("sent hangup call message to \(call.thread.contactAddress)")
|
||||
|
||||
guard self.callData === callData else {
|
||||
Logger.debug("Ignoring hangup send success for obsolete call.")
|
||||
@ -1522,6 +1526,7 @@ private class SignalCallData: NSObject {
|
||||
|
||||
public func callConnection(_ callConnectionParam: CallConnection, onAddRemoteVideoTrack track: RTCVideoTrack, callId: UInt64) {
|
||||
AssertIsOnMainThread()
|
||||
Logger.info("")
|
||||
|
||||
guard let callData = self.callData,
|
||||
callConnectionParam == callData.callConnection else {
|
||||
@ -1543,6 +1548,7 @@ private class SignalCallData: NSObject {
|
||||
|
||||
public func callConnection(_ callConnectionParam: CallConnection, onUpdateLocalVideoSession session: AVCaptureSession?, callId: UInt64) {
|
||||
AssertIsOnMainThread()
|
||||
Logger.info("")
|
||||
|
||||
guard let callData = self.callData,
|
||||
callConnectionParam == callData.callConnection else {
|
||||
@ -1564,7 +1570,7 @@ private class SignalCallData: NSObject {
|
||||
|
||||
public func callConnection(_ callConnectionParam: CallConnection, shouldSendOffer sdp: String, callId: UInt64) {
|
||||
AssertIsOnMainThread()
|
||||
Logger.debug("Got onSendOffer")
|
||||
Logger.info("")
|
||||
|
||||
guard let callData = self.callData,
|
||||
callConnectionParam == callData.callConnection else {
|
||||
@ -1592,7 +1598,7 @@ private class SignalCallData: NSObject {
|
||||
let callMessage = OWSOutgoingCallMessage(thread: call.thread, offerMessage: try offerBuilder.build())
|
||||
let sendPromise = messageSender.sendMessage(.promise, callMessage.asPreparer)
|
||||
.done {
|
||||
Logger.debug("sent offer call message to \(call.thread.contactAddress)")
|
||||
Logger.info("sent offer call message to \(call.thread.contactAddress)")
|
||||
|
||||
guard self.callData === callData else {
|
||||
Logger.debug("Ignoring call offer send success for obsolete call.")
|
||||
@ -1626,7 +1632,7 @@ private class SignalCallData: NSObject {
|
||||
|
||||
public func callConnection(_ callConnectionParam: CallConnection, shouldSendAnswer sdp: String, callId: UInt64) {
|
||||
AssertIsOnMainThread()
|
||||
Logger.debug("Got onSendAnswer")
|
||||
Logger.info("")
|
||||
|
||||
guard let callData = self.callData, callConnectionParam == callData.callConnection else {
|
||||
Logger.debug("Ignoring event from obsolete call.")
|
||||
@ -1646,7 +1652,7 @@ private class SignalCallData: NSObject {
|
||||
let callMessage = OWSOutgoingCallMessage(thread: call.thread, answerMessage: try answerBuilder.build())
|
||||
let sendPromise = messageSender.sendMessage(.promise, callMessage.asPreparer)
|
||||
.done {
|
||||
Logger.debug("sent answer call message to \(call.thread.contactAddress)")
|
||||
Logger.info("sent answer call message to \(call.thread.contactAddress)")
|
||||
|
||||
guard self.callData === callData else {
|
||||
Logger.debug("Ignoring call answer send success for obsolete call.")
|
||||
@ -1680,6 +1686,7 @@ private class SignalCallData: NSObject {
|
||||
|
||||
public func callConnection(_ callConnectionParam: CallConnection, shouldSendIceCandidates candidates: [RTCIceCandidate], callId: UInt64) {
|
||||
AssertIsOnMainThread()
|
||||
Logger.info("")
|
||||
|
||||
guard let callData = self.callData, callConnectionParam == callData.callConnection else {
|
||||
Logger.debug("Ignoring event from obsolete call.")
|
||||
@ -1704,7 +1711,7 @@ private class SignalCallData: NSObject {
|
||||
|
||||
public func callConnection(_ callConnectionParam: CallConnection, shouldSendHangup callId: UInt64) {
|
||||
AssertIsOnMainThread()
|
||||
Logger.debug("Got onSendHangup")
|
||||
Logger.info("")
|
||||
|
||||
guard let callData = deferredHangupList.removeValue(forKey: callId) else {
|
||||
owsFailDebug("obsolete call: \(callId)")
|
||||
@ -1725,7 +1732,7 @@ private class SignalCallData: NSObject {
|
||||
let callMessage = OWSOutgoingCallMessage(thread: call.thread, hangupMessage: try hangupBuilder.build())
|
||||
let sendPromise = messageSender.sendMessage(.promise, callMessage.asPreparer)
|
||||
.done {
|
||||
Logger.debug("sent hangup call message to \(call.thread.contactAddress)")
|
||||
Logger.info("sent hangup call message to \(call.thread.contactAddress)")
|
||||
}.ensure {
|
||||
self.terminate(callData: callData)
|
||||
}.catch { error in
|
||||
@ -1837,7 +1844,7 @@ private class SignalCallData: NSObject {
|
||||
*/
|
||||
private func terminate(callData: SignalCallData?) {
|
||||
AssertIsOnMainThread()
|
||||
Logger.debug("")
|
||||
Logger.info("")
|
||||
|
||||
callData?.terminate()
|
||||
|
||||
|
||||
@ -1709,21 +1709,6 @@
|
||||
/* Title of the 'onboarding PIN' view. */
|
||||
"ONBOARDING_PIN_TITLE" = "Enter your PIN";
|
||||
|
||||
/* header text when this device is being added as a secondary */
|
||||
"ONBOARDING_SECONDARY_CHOOSE_DEVICE_NAME" = "ONBOARDING_SECONDARY_CHOOSE_DEVICE_NAME";
|
||||
|
||||
/* body text while displaying a QR code which, when scanned, will link this device. */
|
||||
"ONBOARDING_SECONDARY_COMPLETE_LINKING_PROCESS" = "ONBOARDING_SECONDARY_COMPLETE_LINKING_PROCESS";
|
||||
|
||||
/* body text while displaying a QR code which, when scanned, will link this device. */
|
||||
"ONBOARDING_SECONDARY_SCAN_CODE_BODY" = "ONBOARDING_SECONDARY_SCAN_CODE_BODY";
|
||||
|
||||
/* Link text for page with troubleshooting info shown on the QR scanning screen */
|
||||
"ONBOARDING_SECONDARY_SCAN_CODE_HELP_TEXT" = "ONBOARDING_SECONDARY_SCAN_CODE_HELP_TEXT";
|
||||
|
||||
/* header text while displaying a QR code which, when scanned, will link this device. */
|
||||
"ONBOARDING_SECONDARY_SCAN_CODE_TITLE" = "ONBOARDING_SECONDARY_SCAN_CODE_TITLE";
|
||||
|
||||
/* Link to the 'terms and privacy policy' in the 'onboarding splash' view. */
|
||||
"ONBOARDING_SPLASH_TERM_AND_PRIVACY_POLICY" = "Terms & Privacy Policy";
|
||||
|
||||
|
||||
@ -122,6 +122,7 @@ class ImageEditorCropViewController: OWSViewController {
|
||||
strongSelf.updateCropViewLayout()
|
||||
}
|
||||
wrapperView.addSubview(clipView)
|
||||
clipView.setContentHuggingLow()
|
||||
|
||||
croppedImageLayer.contents = previewImage.cgImage
|
||||
croppedImageLayer.contentsScale = previewImage.scale
|
||||
@ -149,6 +150,7 @@ class ImageEditorCropViewController: OWSViewController {
|
||||
uncroppedContentView.layer.addSublayer(uncroppedImageLayer)
|
||||
wrapperView.addSubview(uncroppedContentView)
|
||||
uncroppedContentView.autoPin(toEdgesOf: croppedContentView)
|
||||
wrapperView.setContentHuggingLow()
|
||||
|
||||
// MARK: - Footer
|
||||
|
||||
@ -158,10 +160,16 @@ class ImageEditorCropViewController: OWSViewController {
|
||||
UIView.hStretchingSpacer(),
|
||||
cropLockButton
|
||||
])
|
||||
for button in footer.subviews {
|
||||
button.setContentHuggingVerticalHigh()
|
||||
button.setCompressionResistanceVerticalHigh()
|
||||
}
|
||||
footer.axis = .horizontal
|
||||
footer.spacing = 16
|
||||
footer.backgroundColor = .clear
|
||||
footer.isOpaque = false
|
||||
footer.setContentHuggingVerticalHigh()
|
||||
footer.setCompressionResistanceVerticalHigh()
|
||||
|
||||
let imageMargin: CGFloat = 20
|
||||
let stackView = UIStackView(arrangedSubviews: [
|
||||
|
||||
@ -134,6 +134,11 @@ public extension UIView {
|
||||
constraints.append(subview.autoPin(toAspectRatio: aspectRatio))
|
||||
constraints.append(subview.autoMatch(.width, to: .width, of: self, withMultiplier: 1.0, relation: .lessThanOrEqual))
|
||||
constraints.append(subview.autoMatch(.height, to: .height, of: self, withMultiplier: 1.0, relation: .lessThanOrEqual))
|
||||
NSLayoutConstraint.autoSetPriority(UILayoutPriority.defaultHigh) {
|
||||
constraints.append(subview.autoMatch(.width, to: .width, of: self, withMultiplier: 1.0, relation: .equal))
|
||||
constraints.append(subview.autoMatch(.height, to: .height, of: self, withMultiplier: 1.0, relation: .equal))
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user