Implement incoming friend request UI
This commit is contained in:
parent
0a653e928b
commit
3dda1f17e1
|
@ -555,6 +555,8 @@
|
|||
B6B226971BE4B7D200860F4D /* ContactsUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6B226961BE4B7D200860F4D /* ContactsUI.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||
B6F509971AA53F760068F56A /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = B6F509951AA53F760068F56A /* Localizable.strings */; };
|
||||
B6FE7EB71ADD62FA00A6D22F /* PushKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6FE7EB61ADD62FA00A6D22F /* PushKit.framework */; };
|
||||
B8162F0322891AD600D46544 /* FriendRequestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8162F0222891AD600D46544 /* FriendRequestView.swift */; };
|
||||
B8162F0522892C5F00D46544 /* FriendRequestViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */; };
|
||||
B821F2F82272CED3002C88C0 /* OnboardingAccountDetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B821F2F72272CED3002C88C0 /* OnboardingAccountDetailsViewController.swift */; };
|
||||
B821F2FA2272CEEE002C88C0 /* OnboardingKeyPairViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B821F2F92272CEEE002C88C0 /* OnboardingKeyPairViewController.swift */; };
|
||||
B843951A228510FB000563FE /* Poller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8439519228510FB000563FE /* Poller.swift */; };
|
||||
|
@ -1340,6 +1342,8 @@
|
|||
B6BC3D0C1AA544B100C2907F /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = translations/da.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
B6F509961AA53F760068F56A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = translations/en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
B6FE7EB61ADD62FA00A6D22F /* PushKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PushKit.framework; path = System/Library/Frameworks/PushKit.framework; sourceTree = SDKROOT; };
|
||||
B8162F0222891AD600D46544 /* FriendRequestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FriendRequestView.swift; sourceTree = "<group>"; };
|
||||
B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FriendRequestViewDelegate.swift; sourceTree = "<group>"; };
|
||||
B821F2F72272CED3002C88C0 /* OnboardingAccountDetailsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingAccountDetailsViewController.swift; sourceTree = "<group>"; };
|
||||
B821F2F92272CEEE002C88C0 /* OnboardingKeyPairViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingKeyPairViewController.swift; sourceTree = "<group>"; };
|
||||
B8439519228510FB000563FE /* Poller.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Poller.swift; path = Signal/src/Loki/Poller.swift; sourceTree = SOURCE_ROOT; };
|
||||
|
@ -1526,13 +1530,11 @@
|
|||
children = (
|
||||
3441FD9E21A3604F00BB9542 /* BackupRestoreViewController.swift */,
|
||||
349ED98F221B0194008045B0 /* Onboarding2FAViewController.swift */,
|
||||
B821F2F72272CED3002C88C0 /* OnboardingAccountDetailsViewController.swift */,
|
||||
3448E1612213585C004B052E /* OnboardingBaseViewController.swift */,
|
||||
3448E1652215B313004B052E /* OnboardingCaptchaViewController.swift */,
|
||||
3448E15D221333F5004B052E /* OnboardingController.swift */,
|
||||
3448E15B22133274004B052E /* OnboardingPermissionsViewController.swift */,
|
||||
34A4C61F22175C5C0042EF2E /* OnboardingProfileViewController.swift */,
|
||||
B821F2F92272CEEE002C88C0 /* OnboardingKeyPairViewController.swift */,
|
||||
3448E15F22134C88004B052E /* OnboardingSplashViewController.swift */,
|
||||
34A4C61D221613D00042EF2E /* OnboardingVerificationViewController.swift */,
|
||||
346E9D5321B040B600562252 /* RegistrationController.swift */,
|
||||
|
@ -2599,6 +2601,10 @@
|
|||
B8439518228510E9000563FE /* Loki */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B8162F0222891AD600D46544 /* FriendRequestView.swift */,
|
||||
B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */,
|
||||
B821F2F72272CED3002C88C0 /* OnboardingAccountDetailsViewController.swift */,
|
||||
B821F2F92272CEEE002C88C0 /* OnboardingKeyPairViewController.swift */,
|
||||
B8439519228510FB000563FE /* Poller.swift */,
|
||||
);
|
||||
path = Loki;
|
||||
|
@ -3675,10 +3681,12 @@
|
|||
457C87B82032645C008D52D6 /* DebugUINotifications.swift in Sources */,
|
||||
4C21D5D8223AC60F00EF8A77 /* PhotoCapture.swift in Sources */,
|
||||
4C13C9F620E57BA30089A98B /* ColorPickerViewController.swift in Sources */,
|
||||
B8162F0522892C5F00D46544 /* FriendRequestViewDelegate.swift in Sources */,
|
||||
B821F2FA2272CEEE002C88C0 /* OnboardingKeyPairViewController.swift in Sources */,
|
||||
4CC1ECFB211A553000CC13BE /* AppUpdateNag.swift in Sources */,
|
||||
3448E16022134C89004B052E /* OnboardingSplashViewController.swift in Sources */,
|
||||
34B6A903218B3F63007C4606 /* TypingIndicatorView.swift in Sources */,
|
||||
B8162F0322891AD600D46544 /* FriendRequestView.swift in Sources */,
|
||||
458E38371D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m in Sources */,
|
||||
34B6A905218B4C91007C4606 /* TypingIndicatorInteraction.swift in Sources */,
|
||||
4517642B1DE939FD00EDB8B9 /* ContactCell.swift in Sources */,
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
|
||||
@objc final class FriendRequestView : UIView {
|
||||
@objc var message: TSIncomingMessage! { didSet { handleMessageChanged() } }
|
||||
@objc weak var delegate: FriendRequestViewDelegate?
|
||||
|
||||
// MARK: Components
|
||||
private lazy var label: UILabel = {
|
||||
let result = UILabel()
|
||||
result.textColor = Theme.secondaryColor
|
||||
result.font = UIFont.ows_dynamicTypeSubheadlineClamped
|
||||
result.numberOfLines = 0
|
||||
result.textAlignment = .center
|
||||
result.lineBreakMode = .byWordWrapping
|
||||
return result
|
||||
}()
|
||||
|
||||
// MARK: Initialization
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
initialize()
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
initialize()
|
||||
}
|
||||
|
||||
private func initialize() {
|
||||
let mainStackView = UIStackView()
|
||||
mainStackView.axis = .vertical
|
||||
mainStackView.distribution = .fill
|
||||
mainStackView.addArrangedSubview(label)
|
||||
let buttonStackView = UIStackView()
|
||||
buttonStackView.axis = .horizontal
|
||||
buttonStackView.distribution = .fillEqually
|
||||
mainStackView.addArrangedSubview(buttonStackView)
|
||||
let buttonFont = UIFont.ows_dynamicTypeBodyClamped.ows_mediumWeight()
|
||||
let buttonHeight = buttonFont.pointSize * 48 / 17
|
||||
let acceptButton = OWSFlatButton.button(title: NSLocalizedString("Accept", comment: ""), font: buttonFont, titleColor: .ows_materialBlue, backgroundColor: .clear, target: self, selector: #selector(accept))
|
||||
acceptButton.autoSetDimension(.height, toSize: buttonHeight)
|
||||
buttonStackView.addArrangedSubview(acceptButton)
|
||||
let declineButton = OWSFlatButton.button(title: NSLocalizedString("Decline", comment: ""), font: buttonFont, titleColor: .ows_destructiveRed, backgroundColor: .clear, target: self, selector: #selector(decline))
|
||||
declineButton.autoSetDimension(.height, toSize: buttonHeight)
|
||||
buttonStackView.addArrangedSubview(declineButton)
|
||||
addSubview(mainStackView)
|
||||
mainStackView.autoPin(toEdgesOf: self)
|
||||
}
|
||||
|
||||
// MARK: Updating
|
||||
private func handleMessageChanged() {
|
||||
assert(message != nil)
|
||||
label.text = String(format: NSLocalizedString("%@ sent you a friend request", comment: ""), message.authorId)
|
||||
}
|
||||
|
||||
// MARK: Interaction
|
||||
@objc private func accept() {
|
||||
delegate?.acceptFriendRequest(message)
|
||||
}
|
||||
|
||||
@objc private func decline() {
|
||||
delegate?.declineFriendRequest(message)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
@objc protocol FriendRequestViewDelegate {
|
||||
@objc func acceptFriendRequest(_ friendRequest: TSIncomingMessage)
|
||||
@objc func declineFriendRequest(_ friendRequest: TSIncomingMessage)
|
||||
}
|
|
@ -65,7 +65,7 @@ final class OnboardingAccountDetailsViewController : OnboardingBaseViewControlle
|
|||
topSpacer.autoMatch(.height, to: .height, of: bottomSpacer)
|
||||
}
|
||||
|
||||
public override func viewDidAppear(_ animated: Bool) {
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
userNameTextField.becomeFirstResponder()
|
||||
}
|
|
@ -91,7 +91,7 @@ final class OnboardingKeyPairViewController : OnboardingBaseViewController {
|
|||
self.userName = userName
|
||||
}
|
||||
|
||||
override public func viewDidLoad() {
|
||||
override func viewDidLoad() {
|
||||
super.loadView()
|
||||
setUpViewHierarchy()
|
||||
handleModeChanged() // Perform initial update
|
|
@ -1,6 +1,6 @@
|
|||
import PromiseKit
|
||||
|
||||
@objc public final class Poller : NSObject {
|
||||
@objc final class Poller : NSObject {
|
||||
private var isStarted = false
|
||||
private var currentJob: Promise<Void>?
|
||||
|
||||
|
@ -8,12 +8,12 @@ import PromiseKit
|
|||
private static let interval: TimeInterval = 30
|
||||
|
||||
// MARK: Initialization
|
||||
@objc public static let shared = Poller()
|
||||
@objc static let shared = Poller()
|
||||
|
||||
private override init() { }
|
||||
|
||||
// MARK: General
|
||||
@objc public func startIfNeeded() {
|
||||
@objc func startIfNeeded() {
|
||||
guard !isStarted else { return }
|
||||
Timer.scheduledTimer(timeInterval: Poller.interval, target: self, selector: #selector(poll), userInfo: nil, repeats: true)
|
||||
isStarted = true
|
||||
|
|
|
@ -5,12 +5,14 @@
|
|||
#import "ConversationViewCell.h"
|
||||
|
||||
@class OWSMessageBubbleView;
|
||||
@protocol FriendRequestViewDelegate;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OWSMessageCell : ConversationViewCell
|
||||
|
||||
@property (nonatomic, readonly) OWSMessageBubbleView *messageBubbleView;
|
||||
@property (nonatomic, nullable, weak) id<FriendRequestViewDelegate> friendRequestViewDelegate;
|
||||
|
||||
+ (NSString *)cellReuseIdentifier;
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@property (nonatomic) OWSMessageHeaderView *headerView;
|
||||
@property (nonatomic) OWSMessageBubbleView *messageBubbleView;
|
||||
@property (nonatomic) AvatarImageView *avatarView;
|
||||
@property (nonatomic, nullable) FriendRequestView *friendRequestView;
|
||||
@property (nonatomic, nullable) UIImageView *sendFailureBadgeView;
|
||||
|
||||
@property (nonatomic, nullable) NSMutableArray<NSLayoutConstraint *> *viewConstraints;
|
||||
|
@ -164,6 +165,21 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
withInset:self.conversationStyle.gutterTrailing
|
||||
relation:NSLayoutRelationGreaterThanOrEqual],
|
||||
]];
|
||||
|
||||
if ([self.viewItem.interaction isKindOfClass:TSIncomingMessage.class]) {
|
||||
TSIncomingMessage *message = (TSIncomingMessage *)self.message;
|
||||
if (YES) { // TODO: message.isFriendRequest
|
||||
self.friendRequestView = [FriendRequestView new];
|
||||
self.friendRequestView.message = message;
|
||||
self.friendRequestView.delegate = self.friendRequestViewDelegate;
|
||||
[self.contentView addSubview:self.friendRequestView];
|
||||
[self.viewConstraints addObjectsFromArray:@[
|
||||
[self.friendRequestView autoPinEdgeToSuperviewEdge:ALEdgeLeading withInset:self.conversationStyle.gutterLeading],
|
||||
[self.friendRequestView autoPinEdgeToSuperviewEdge:ALEdgeTrailing withInset:self.conversationStyle.gutterTrailing],
|
||||
[self.friendRequestView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.messageBubbleView withOffset:12.f]
|
||||
]];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (self.shouldHaveSendFailureBadge) {
|
||||
self.sendFailureBadgeView = [UIImageView new];
|
||||
|
@ -339,6 +355,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
if (self.shouldHaveSendFailureBadge) {
|
||||
cellSize.width += self.sendFailureBadgeSize + self.sendFailureBadgeSpacing;
|
||||
}
|
||||
|
||||
if (self.friendRequestView != nil) {
|
||||
cellSize.height += 118.f; // TODO: Measure dynamically
|
||||
}
|
||||
|
||||
cellSize = CGSizeCeil(cellSize);
|
||||
|
||||
|
@ -359,6 +379,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
[self.headerView removeFromSuperview];
|
||||
|
||||
[self.friendRequestView removeFromSuperview];
|
||||
self.friendRequestView = nil;
|
||||
|
||||
self.avatarView.image = nil;
|
||||
[self.avatarView removeFromSuperview];
|
||||
|
||||
|
|
|
@ -123,6 +123,7 @@ typedef enum : NSUInteger {
|
|||
ConversationViewCellDelegate,
|
||||
ConversationInputTextViewDelegate,
|
||||
ConversationSearchControllerDelegate,
|
||||
FriendRequestViewDelegate,
|
||||
LongTextViewDelegate,
|
||||
MessageActionsDelegate,
|
||||
MessageDetailViewDelegate,
|
||||
|
@ -4282,6 +4283,18 @@ typedef enum : NSUInteger {
|
|||
animated:YES];
|
||||
}
|
||||
|
||||
#pragma mark - FriendRequestViewDelegate
|
||||
|
||||
- (void)acceptFriendRequest:(TSIncomingMessage *)friendRequest
|
||||
{
|
||||
[ThreadUtil enqueueFriendRequestAcceptMessageInThread:self.thread];
|
||||
}
|
||||
|
||||
- (void)declineFriendRequest:(TSIncomingMessage *)friendRequest
|
||||
{
|
||||
OWSLogDebug(@"decline friend request button pressed"); // TODO: Implement
|
||||
}
|
||||
|
||||
#pragma mark - ConversationViewLayoutDelegate
|
||||
|
||||
- (NSArray<id<ConversationViewLayoutItem>> *)layoutItems
|
||||
|
@ -4567,6 +4580,7 @@ typedef enum : NSUInteger {
|
|||
if ([cell isKindOfClass:[OWSMessageCell class]]) {
|
||||
OWSMessageCell *messageCell = (OWSMessageCell *)cell;
|
||||
messageCell.messageBubbleView.delegate = self;
|
||||
messageCell.friendRequestViewDelegate = self;
|
||||
}
|
||||
cell.conversationStyle = self.conversationStyle;
|
||||
|
||||
|
|
|
@ -2571,3 +2571,6 @@
|
|||
"Calculating proof of work" = "Calculating proof of work";
|
||||
"Failed to calculate proof of work." = "Failed to calculate proof of work.";
|
||||
"Share Public Key" = "Share Public Key";
|
||||
"%@ sent you a friend request" = "%@ sent you a friend request";
|
||||
"Accept" = "Accept";
|
||||
"Decline" = "Decline";
|
||||
|
|
|
@ -44,6 +44,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
#pragma mark - Durable Message Enqueue
|
||||
|
||||
+ (TSOutgoingMessage *)enqueueFriendRequestAcceptMessageInThread:(TSThread *)thread;
|
||||
|
||||
+ (TSOutgoingMessage *)enqueueMessageWithText:(NSString *)fullMessageText
|
||||
inThread:(TSThread *)thread
|
||||
quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel
|
||||
|
|
Loading…
Reference in New Issue