Fix friend request UI bugs

pull/26/head
Niels Andriesse 7 years ago
parent 33a5e59415
commit cbac37a95f

@ -12,6 +12,12 @@
enum Kind : String { case incoming, outgoing }
// MARK: Components
private lazy var topSpacer: UIView = {
let result = UIView()
result.autoSetDimension(.height, toSize: 12)
return result
}()
private lazy var label: UILabel = {
let result = UILabel()
result.textColor = Theme.secondaryColor
@ -47,6 +53,7 @@
let mainStackView = UIStackView()
mainStackView.axis = .vertical
mainStackView.distribution = .fill
mainStackView.addArrangedSubview(topSpacer)
mainStackView.addArrangedSubview(label)
switch kind {
case .incoming:
@ -85,23 +92,33 @@
buttonStackView.isHidden = message.friendRequestStatus != .pending
let format: String = {
switch (message.friendRequestStatus) {
case .none, .sendingOrFailed: preconditionFailure()
case .pending: return NSLocalizedString("%@ sent you a friend request", comment: "")
case .accepted: return NSLocalizedString("You've accepted %@'s friend request", comment: "")
case .declined: return NSLocalizedString("You've declined %@'s friend request", comment: "")
case .expired: return NSLocalizedString("%@'s friend request has expired", comment: "")
default: return NSLocalizedString("%@ sent you a friend request", comment: "")
default: preconditionFailure()
}
}()
label.text = String(format: format, message.authorId)
case .outgoing:
guard let message = message as? TSOutgoingMessage else { preconditionFailure() }
let format: String = {
let format: String? = {
switch (message.friendRequestStatus) {
case .none: preconditionFailure()
case .sendingOrFailed: return nil
case .pending: return NSLocalizedString("You've sent %@ a friend request", comment: "")
case .accepted: return NSLocalizedString("%@ accepted your friend request", comment: "")
case .declined: preconditionFailure()
case .expired: return NSLocalizedString("Your friend request to %@ has expired", comment: "")
default: return NSLocalizedString("You've sent %@ a friend request", comment: "")
default: preconditionFailure()
}
}()
label.text = String(format: format, message.thread.contactIdentifier()!)
if let format = format {
label.text = String(format: format, message.thread.contactIdentifier()!)
}
label.isHidden = (format == nil)
topSpacer.isHidden = (label.isHidden)
}
}
@ -121,9 +138,11 @@
// MARK: Measuring
@objc static func calculateHeight(message: TSMessage, conversationStyle: ConversationStyle) -> CGFloat {
let width = conversationStyle.contentWidth
let topSpacing: CGFloat = 12
let dummyFriendRequestView = FriendRequestView(message: message)
let labelHeight = dummyFriendRequestView.label.sizeThatFits(CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)).height
let hasTopSpacer = !dummyFriendRequestView.topSpacer.isHidden
let topSpacing: CGFloat = hasTopSpacer ? 12 : 0
let hasLabel = !dummyFriendRequestView.label.isHidden
let labelHeight = hasLabel ? dummyFriendRequestView.label.sizeThatFits(CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)).height : 0
let hasButtonStackView = dummyFriendRequestView.buttonStackView.superview != nil && !dummyFriendRequestView.buttonStackView.isHidden
let buttonHeight = hasButtonStackView ? dummyFriendRequestView.buttonHeight : 0
let totalHeight = topSpacing + labelHeight + buttonHeight

@ -214,7 +214,7 @@ NS_ASSUME_NONNULL_BEGIN
[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],
[self.friendRequestView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.messageBubbleView],
[self.friendRequestView autoPinEdgeToSuperviewEdge:ALEdgeBottom]
]];
}

@ -407,7 +407,7 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
}
} else if (self.interaction.interactionType == OWSInteractionType_OutgoingMessage
&& previousLayoutItem.interaction.interactionType == OWSInteractionType_OutgoingMessage
&& !([previousLayoutItem.interaction isKindOfClass:TSOutgoingMessage.class] && ((TSOutgoingMessage *)previousLayoutItem.interaction).isFriendRequest)) {
&& !((TSOutgoingMessage *)previousLayoutItem.interaction).hasFriendRequestStatusMessage) {
return 2.f;
}

@ -31,17 +31,17 @@ extern ConversationColorName const kConversationColorName_Default;
// Loki: Friend request status
typedef NS_ENUM(NSInteger, TSThreadFriendRequestStatus) {
/// New conversation, no messages sent or received.
/// New conversation; no messages sent or received.
TSThreadFriendRequestStatusNone,
/// This state is used to lock the input early while sending.
TSThreadFriendRequestStatusRequestSending,
/// Friend request sent, awaiting response.
/// Friend request sent; awaiting response.
TSThreadFriendRequestStatusRequestSent,
/// Friend request received, awaiting user input.
/// Friend request received; awaiting user input.
TSThreadFriendRequestStatusRequestReceived,
/// We are friends with the other user in this thread.
TSThreadFriendRequestStatusFriends,
/// Friend request sent but it timed out (i.e. the other user didn't accept within the allocated time).
/// A friend request was sent, but it timed out (i.e. the other user didn't accept within the allocated time).
TSThreadFriendRequestStatusRequestExpired
};
@ -205,12 +205,12 @@ typedef NS_ENUM(NSInteger, TSThreadFriendRequestStatus) {
/**
Remove any outgoing friend request message which failed to send
*/
- (void)removeOldOutgoingFriendRequestMessagesWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
- (void)removeOldOutgoingFriendRequestMessagesIfNeededWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
/**
Remove any old incoming friend request message that is still pending
*/
- (void)removeOldIncomingFriendRequestMessagesWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
- (void)removeOldIncomingFriendRequestMessagesIfNeededWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
@end

@ -708,17 +708,17 @@ ConversationColorName const kConversationColorName_Default = ConversationColorNa
#pragma mark - Loki Friend Request Handling
- (void)removeOldOutgoingFriendRequestMessagesWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
- (void)removeOldOutgoingFriendRequestMessagesIfNeededWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
[self removeOldFriendRequestMessages:OWSInteractionType_OutgoingMessage withTransaction:transaction];
[self removeOldFriendRequestMessagesIfNeeded:OWSInteractionType_OutgoingMessage withTransaction:transaction];
}
- (void)removeOldIncomingFriendRequestMessagesWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
- (void)removeOldIncomingFriendRequestMessagesIfNeededWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
[self removeOldFriendRequestMessages:OWSInteractionType_IncomingMessage withTransaction:transaction];
[self removeOldFriendRequestMessagesIfNeeded:OWSInteractionType_IncomingMessage withTransaction:transaction];
}
- (void)removeOldFriendRequestMessages:(OWSInteractionType)interactionType withTransaction:(YapDatabaseReadWriteTransaction *)transaction
- (void)removeOldFriendRequestMessagesIfNeeded:(OWSInteractionType)interactionType withTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
// If we're friends with the person then we don't need to remove any friend request messages
if (self.friendRequestStatus == TSThreadFriendRequestStatusFriends) { return; }
@ -743,7 +743,7 @@ ConversationColorName const kConversationColorName_Default = ConversationColorNa
} else {
// Or if we're sending then remove any failed friend request messages
TSOutgoingMessage *outgoingMessage = (TSOutgoingMessage *)message;
removeMessage = outgoingMessage.isFriendRequest && outgoingMessage.messageState == TSOutgoingMessageStateFailed;
removeMessage = outgoingMessage.friendRequestStatus == TSMessageFriendRequestStatusSendingOrFailed;
}
if (removeMessage) {

@ -6,8 +6,6 @@
@implementation LKFriendRequestMessage
- (BOOL)isFriendRequest { return YES; }
- (uint)ttl { return 4 * kDayInMs; } // Friend requests should stay for the longest on the storage server
- (SSKProtoContentBuilder *)contentBuilder:(SignalRecipient *)recipient {

@ -17,17 +17,13 @@ NS_ASSUME_NONNULL_BEGIN
@class TSQuotedMessage;
@class YapDatabaseReadWriteTransaction;
// Loki: Friend request status
typedef NS_ENUM(NSInteger, TSMessageFriendRequestStatus) {
/// Not a friend request message.
TSMessageFriendRequestStatusNone,
/// A pending friend request.
TSMessageFriendRequestStatusSendingOrFailed,
/// Either sent or received.
TSMessageFriendRequestStatusPending,
/// A friend request that has been accepted.
TSMessageFriendRequestStatusAccepted,
/// A friend request that has been declined.
TSMessageFriendRequestStatusDeclined,
/// A friend request that has expired.
TSMessageFriendRequestStatusExpired
};
@ -48,6 +44,7 @@ typedef NS_ENUM(NSInteger, TSMessageFriendRequestStatus) {
@property (nonatomic, readonly) NSString *friendRequestStatusDescription;
@property (nonatomic) uint64_t friendRequestExpiresAt;
@property (nonatomic, readonly) BOOL isFriendRequest;
@property (nonatomic, readonly) BOOL hasFriendRequestStatusMessage;
// ========
- (instancetype)initInteractionWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread NS_UNAVAILABLE;

@ -82,6 +82,7 @@ static const NSUInteger OWSMessageSchemaVersion = 4;
_quotedMessage = quotedMessage;
_contactShare = contactShare;
_linkPreview = linkPreview;
_friendRequestStatus = TSMessageFriendRequestStatusNone;
_friendRequestExpiresAt = 0;
return self;
@ -461,6 +462,7 @@ static const NSUInteger OWSMessageSchemaVersion = 4;
{
switch (self.friendRequestStatus) {
case TSMessageFriendRequestStatusNone: return @"none";
case TSMessageFriendRequestStatusSendingOrFailed: return @"sending or failed";
case TSMessageFriendRequestStatusPending: return @"pending";
case TSMessageFriendRequestStatusAccepted: return @"accepted";
case TSMessageFriendRequestStatusDeclined: return @"declined";
@ -483,6 +485,11 @@ static const NSUInteger OWSMessageSchemaVersion = 4;
return self.friendRequestStatus != TSMessageFriendRequestStatusNone;
}
- (BOOL)hasFriendRequestStatusMessage
{
return self.isFriendRequest && self.friendRequestStatus != TSMessageFriendRequestStatusSendingOrFailed;
}
@end
NS_ASSUME_NONNULL_END

@ -1529,7 +1529,7 @@ NS_ASSUME_NONNULL_BEGIN
// Remove any old incoming messages
if (incomingMessage.isFriendRequest) {
[thread removeOldIncomingFriendRequestMessagesWithTransaction:transaction];
[thread removeOldIncomingFriendRequestMessagesIfNeededWithTransaction:transaction];
}
// Any messages sent from the current user - from this device or another - should be automatically marked as read.

@ -1112,7 +1112,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
// Update the message and thread if needed
if (messageType == TSFriendRequestMessageType) {
[message.thread saveFriendRequestStatus:TSThreadFriendRequestStatusRequestSending withTransaction:transaction];
[message saveFriendRequestStatus:TSMessageFriendRequestStatusPending withTransaction:transaction];
[message saveFriendRequestStatus:TSMessageFriendRequestStatusSendingOrFailed withTransaction:transaction];
}
}];
// Convenience
@ -1121,6 +1121,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
// Update the thread if needed
if (messageType == TSFriendRequestMessageType) {
[message.thread saveFriendRequestStatus:TSThreadFriendRequestStatusNone withTransaction:transaction];
[message saveFriendRequestStatus:TSMessageFriendRequestStatusSendingOrFailed withTransaction:transaction];
}
// Update the PoW calculation status
[message saveIsCalculatingProofOfWork:NO withTransaction:transaction];
@ -1153,11 +1154,13 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
.thenOn(OWSDispatch.sendingQueue, ^(id result) {
if (isSuccess) { return; } // Succeed as soon as the first promise succeeds
isSuccess = YES;
// Update the message and thread if needed
if (messageType == TSFriendRequestMessageType) {
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
// Update the thread
[message.thread saveFriendRequestStatus:TSThreadFriendRequestStatusRequestSent withTransaction:transaction];
[message.thread removeOldOutgoingFriendRequestMessagesWithTransaction:transaction];
[message.thread removeOldOutgoingFriendRequestMessagesIfNeededWithTransaction:transaction];
// Update the message
[message saveFriendRequestStatus:TSMessageFriendRequestStatusPending withTransaction:transaction];
NSTimeInterval expirationInterval = 72 * kHourInterval;
NSDate *expirationDate = [[NSDate new] dateByAddingTimeInterval:expirationInterval];
[message saveFriendRequestExpiresAt:[NSDate ows_millisecondsSince1970ForDate:expirationDate] withTransaction:transaction];
@ -1240,16 +1243,6 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
*/
}
- (void)saveIsCalculatingProofOfWork:(BOOL)isCalculatingPoW forMessage:(OWSMessageSend *)messageSend
{
OWSAssertDebug(messageSend);
dispatch_async(OWSDispatch.sendingQueue, ^{
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[messageSend.message saveIsCalculatingProofOfWork:isCalculatingPoW withTransaction:transaction];
}];
});
}
- (void)messageSendDidSucceed:(OWSMessageSend *)messageSend
deviceMessages:(NSArray<NSDictionary *> *)deviceMessages
wasSentByUD:(BOOL)wasSentByUD
@ -1342,7 +1335,11 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
};
switch (statusCode) {
case 0: return messageSend.failure(responseError); // Loki
case 0: { // Loki
NSError *error = OWSErrorMakeFailedToSendOutgoingMessageError();
[error setIsRetryable:NO];
return messageSend.failure(error);
}
case 401: {
OWSLogWarn(@"Unable to send due to invalid credentials. Did the user's client get de-authed by "
@"registering elsewhere?");

Loading…
Cancel
Save