|
|
|
@ -3,12 +3,12 @@
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
public extension CGPoint {
|
|
|
|
|
public func plusX(_ value: CGFloat) -> CGPoint {
|
|
|
|
|
return CGPoint(x: x + value, y: y)
|
|
|
|
|
public func offsetBy(dx: CGFloat) -> CGPoint {
|
|
|
|
|
return CGPoint(x: x + dx, y: y)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public func plusY(_ value: CGFloat) -> CGPoint {
|
|
|
|
|
return CGPoint(x: x, y: y + value)
|
|
|
|
|
public func offsetBy(dy: CGFloat) -> CGPoint {
|
|
|
|
|
return CGPoint(x: x, y: y + dy)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -218,7 +218,7 @@ public class LinkPreviewSent: NSObject, LinkPreviewState {
|
|
|
|
|
// MARK: -
|
|
|
|
|
|
|
|
|
|
@objc
|
|
|
|
|
public protocol LinkPreviewViewDelegate {
|
|
|
|
|
public protocol LinkPreviewViewDraftDelegate {
|
|
|
|
|
func linkPreviewCanCancel() -> Bool
|
|
|
|
|
func linkPreviewDidCancel()
|
|
|
|
|
}
|
|
|
|
@ -279,25 +279,25 @@ public class LinkPreviewImageView: UIImageView {
|
|
|
|
|
let path = UIBezierPath()
|
|
|
|
|
|
|
|
|
|
// It's sufficient to "draw" the rounded corners and not the edges that connect them.
|
|
|
|
|
path.addArc(withCenter: upperLeft.plusX(+upperLeftRounding).plusY(+upperLeftRounding),
|
|
|
|
|
path.addArc(withCenter: upperLeft.offsetBy(dx: +upperLeftRounding).offsetBy(dy: +upperLeftRounding),
|
|
|
|
|
radius: upperLeftRounding,
|
|
|
|
|
startAngle: CGFloat.pi * 1.0,
|
|
|
|
|
endAngle: CGFloat.pi * 1.5,
|
|
|
|
|
clockwise: true)
|
|
|
|
|
|
|
|
|
|
path.addArc(withCenter: upperRight.plusX(-upperRightRounding).plusY(+upperRightRounding),
|
|
|
|
|
path.addArc(withCenter: upperRight.offsetBy(dx: -upperRightRounding).offsetBy(dy: +upperRightRounding),
|
|
|
|
|
radius: upperRightRounding,
|
|
|
|
|
startAngle: CGFloat.pi * 1.5,
|
|
|
|
|
endAngle: CGFloat.pi * 0.0,
|
|
|
|
|
clockwise: true)
|
|
|
|
|
|
|
|
|
|
path.addArc(withCenter: lowerRight.plusX(-lowerRightRounding).plusY(-lowerRightRounding),
|
|
|
|
|
path.addArc(withCenter: lowerRight.offsetBy(dx: -lowerRightRounding).offsetBy(dy: -lowerRightRounding),
|
|
|
|
|
radius: lowerRightRounding,
|
|
|
|
|
startAngle: CGFloat.pi * 0.0,
|
|
|
|
|
endAngle: CGFloat.pi * 0.5,
|
|
|
|
|
clockwise: true)
|
|
|
|
|
|
|
|
|
|
path.addArc(withCenter: lowerLeft.plusX(+lowerLeftRounding).plusY(-lowerLeftRounding),
|
|
|
|
|
path.addArc(withCenter: lowerLeft.offsetBy(dx: +lowerLeftRounding).offsetBy(dy: -lowerLeftRounding),
|
|
|
|
|
radius: lowerLeftRounding,
|
|
|
|
|
startAngle: CGFloat.pi * 0.5,
|
|
|
|
|
endAngle: CGFloat.pi * 1.0,
|
|
|
|
@ -311,7 +311,7 @@ public class LinkPreviewImageView: UIImageView {
|
|
|
|
|
|
|
|
|
|
@objc
|
|
|
|
|
public class LinkPreviewView: UIStackView {
|
|
|
|
|
private weak var delegate: LinkPreviewViewDelegate?
|
|
|
|
|
private weak var draftDelegate: LinkPreviewViewDraftDelegate?
|
|
|
|
|
|
|
|
|
|
@objc
|
|
|
|
|
public var state: LinkPreviewState? {
|
|
|
|
@ -339,20 +339,20 @@ public class LinkPreviewView: UIStackView {
|
|
|
|
|
private var layoutConstraints = [NSLayoutConstraint]()
|
|
|
|
|
|
|
|
|
|
@objc
|
|
|
|
|
public init(delegate: LinkPreviewViewDelegate?) {
|
|
|
|
|
self.delegate = delegate
|
|
|
|
|
public init(draftDelegate: LinkPreviewViewDraftDelegate?) {
|
|
|
|
|
self.draftDelegate = draftDelegate
|
|
|
|
|
|
|
|
|
|
super.init(frame: .zero)
|
|
|
|
|
|
|
|
|
|
if let delegate = delegate,
|
|
|
|
|
delegate.linkPreviewCanCancel() {
|
|
|
|
|
if let draftDelegate = draftDelegate,
|
|
|
|
|
draftDelegate.linkPreviewCanCancel() {
|
|
|
|
|
self.isUserInteractionEnabled = true
|
|
|
|
|
self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(wasTapped)))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private var isApproval: Bool {
|
|
|
|
|
return delegate != nil
|
|
|
|
|
private var isDraft: Bool {
|
|
|
|
|
return draftDelegate != nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private func resetContents() {
|
|
|
|
@ -381,15 +381,15 @@ public class LinkPreviewView: UIStackView {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
guard isApproval else {
|
|
|
|
|
guard isDraft else {
|
|
|
|
|
createSentContents()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
guard state.isLoaded() else {
|
|
|
|
|
createLoadingContents()
|
|
|
|
|
createDraftLoadingContents()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
createApprovalContents(state: state)
|
|
|
|
|
createDraftContents(state: state)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private func createSentContents() {
|
|
|
|
@ -532,10 +532,10 @@ public class LinkPreviewView: UIStackView {
|
|
|
|
|
return label
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private let approvalHeight: CGFloat = 72
|
|
|
|
|
private let approvalMarginTop: CGFloat = 6
|
|
|
|
|
private let draftHeight: CGFloat = 72
|
|
|
|
|
private let draftMarginTop: CGFloat = 6
|
|
|
|
|
|
|
|
|
|
private func createApprovalContents(state: LinkPreviewState) {
|
|
|
|
|
private func createDraftContents(state: LinkPreviewState) {
|
|
|
|
|
self.axis = .horizontal
|
|
|
|
|
self.alignment = .fill
|
|
|
|
|
self.distribution = .fill
|
|
|
|
@ -543,19 +543,19 @@ public class LinkPreviewView: UIStackView {
|
|
|
|
|
self.isLayoutMarginsRelativeArrangement = true
|
|
|
|
|
let hMarginLeading: CGFloat = 6
|
|
|
|
|
let hMarginTrailing: CGFloat = 12
|
|
|
|
|
self.layoutMargins = UIEdgeInsets(top: approvalMarginTop,
|
|
|
|
|
self.layoutMargins = UIEdgeInsets(top: draftMarginTop,
|
|
|
|
|
left: CurrentAppContext().isRTL ? hMarginTrailing : hMarginLeading,
|
|
|
|
|
bottom: 0,
|
|
|
|
|
right: CurrentAppContext().isRTL ? hMarginLeading : hMarginTrailing)
|
|
|
|
|
|
|
|
|
|
self.layoutConstraints.append(self.autoSetDimension(.height, toSize: approvalHeight + approvalMarginTop))
|
|
|
|
|
self.layoutConstraints.append(self.autoSetDimension(.height, toSize: draftHeight + draftMarginTop))
|
|
|
|
|
|
|
|
|
|
// Image
|
|
|
|
|
|
|
|
|
|
if let imageView = createApprovalImageView(state: state) {
|
|
|
|
|
if let imageView = createDraftImageView(state: state) {
|
|
|
|
|
imageView.contentMode = .scaleAspectFill
|
|
|
|
|
imageView.autoPinToSquareAspectRatio()
|
|
|
|
|
let imageSize = approvalHeight
|
|
|
|
|
let imageSize = draftHeight
|
|
|
|
|
imageView.autoSetDimensions(to: CGSize(width: imageSize, height: imageSize))
|
|
|
|
|
imageView.setContentHuggingHigh()
|
|
|
|
|
imageView.setCompressionResistanceHigh()
|
|
|
|
@ -655,7 +655,7 @@ public class LinkPreviewView: UIStackView {
|
|
|
|
|
return imageView
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private func createApprovalImageView(state: LinkPreviewState) -> UIImageView? {
|
|
|
|
|
private func createDraftImageView(state: LinkPreviewState) -> UIImageView? {
|
|
|
|
|
guard state.isLoaded() else {
|
|
|
|
|
owsFailDebug("State not loaded.")
|
|
|
|
|
return nil
|
|
|
|
@ -673,11 +673,11 @@ public class LinkPreviewView: UIStackView {
|
|
|
|
|
return imageView
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private func createLoadingContents() {
|
|
|
|
|
private func createDraftLoadingContents() {
|
|
|
|
|
self.axis = .vertical
|
|
|
|
|
self.alignment = .center
|
|
|
|
|
|
|
|
|
|
self.layoutConstraints.append(self.autoSetDimension(.height, toSize: approvalHeight + approvalMarginTop))
|
|
|
|
|
self.layoutConstraints.append(self.autoSetDimension(.height, toSize: draftHeight + draftMarginTop))
|
|
|
|
|
|
|
|
|
|
let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
|
|
|
|
|
activityIndicator.startAnimating()
|
|
|
|
@ -698,7 +698,7 @@ public class LinkPreviewView: UIStackView {
|
|
|
|
|
let hotAreaInset: CGFloat = -20
|
|
|
|
|
let cancelButtonHotArea = cancelButton.bounds.insetBy(dx: hotAreaInset, dy: hotAreaInset)
|
|
|
|
|
if cancelButtonHotArea.contains(cancelLocation) {
|
|
|
|
|
self.delegate?.linkPreviewDidCancel()
|
|
|
|
|
self.draftDelegate?.linkPreviewDidCancel()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -794,6 +794,6 @@ public class LinkPreviewView: UIStackView {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@objc func didTapCancel(sender: UIButton) {
|
|
|
|
|
self.delegate?.linkPreviewDidCancel()
|
|
|
|
|
self.draftDelegate?.linkPreviewDidCancel()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|