Partially fix friend request UI issues

pull/182/head
nielsandriesse 5 years ago
parent 868725f513
commit 5cc11b9014

@ -106,7 +106,7 @@ final class FriendRequestView : UIView {
updateUI()
}
private func updateUI() {
@objc public func updateUI() {
let thread = message.thread
let friendRequestStatus = FriendRequestProtocol.getFriendRequestUIStatus(for: thread)
guard let contactID = thread.contactIdentifier() else { return }
@ -127,7 +127,7 @@ final class FriendRequestView : UIView {
switch friendRequestStatus {
case .none: format = nil // The message failed to send
case .friends: format = nil
case .received: return
case .received: return // Should never occur
case .sent: format = NSLocalizedString("You've sent %@ a session request", comment: "")
case .expired: format = NSLocalizedString("Your session request to %@ has expired", comment: "")
}

@ -225,6 +225,8 @@ NS_ASSUME_NONNULL_BEGIN
[self.friendRequestView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.messageBubbleView],
[self.friendRequestView autoPinEdgeToSuperviewEdge:ALEdgeBottom]
]];
} else {
[self.friendRequestView removeFromSuperview];
}
if ([self updateAvatarView]) {

@ -518,7 +518,6 @@ typedef enum : NSUInteger {
- (void)handleGroupThreadUpdatedNotification:(NSNotification *)notification
{
OWSAssertIsOnMainThread();
// Check thread
NSString *threadID = (NSString *)notification.object;
if (![threadID isEqualToString:self.thread.uniqueId]) { return; }
@ -526,29 +525,34 @@ typedef enum : NSUInteger {
[self.thread reload];
// Update UI
[self hideInputIfNeeded];
[self resetContentAndLayout];
[self.collectionView.collectionViewLayout invalidateLayout];
for (id<ConversationViewItem> item in self.viewItems) {
[item clearCachedLayoutState];
}
[self.conversationViewModel reloadViewItems];
[self.collectionView reloadData];
}
- (void)handleUserFriendRequestStatusChangedNotification:(NSNotification *)notification
{
OWSAssertIsOnMainThread();
// Friend request status doesn't apply to group threads
if (self.thread.isGroupThread) { return; }
NSString *hexEncodedPublicKey = (NSString *)notification.object;
// Check if we should update the UI
__block BOOL needsUpdate;
__block NSSet<NSString *> *linkedDevices;
[OWSPrimaryStorage.sharedManager.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
NSSet<NSString *> *linkedDevices = [LKDatabaseUtilities getLinkedDeviceHexEncodedPublicKeysFor:self.thread.contactIdentifier in:transaction];
needsUpdate = [linkedDevices containsObject:hexEncodedPublicKey];
linkedDevices = [LKDatabaseUtilities getLinkedDeviceHexEncodedPublicKeysFor:self.thread.contactIdentifier in:transaction];
}];
if (!needsUpdate) { return; }
// Ensure the thread instance is up to date
[self.thread reload];
if (![linkedDevices containsObject:hexEncodedPublicKey]) { return; }
// Update the UI
[self updateInputBar];
[self.collectionView.collectionViewLayout invalidateLayout];
for (id<ConversationViewItem> item in self.viewItems) {
[item clearCachedLayoutState];
}
[self updateInputToolbar];
[self resetContentAndLayout];
[self.conversationViewModel reloadViewItems];
[self.collectionView reloadData];
}
- (void)handleThreadSessionRestoreDevicesChangedNotifiaction:(NSNotification *)notification
@ -665,6 +669,7 @@ typedef enum : NSUInteger {
self.inputToolbar.hidden = NO;
}
// Loki: In RSS feeds, don't hide the input bar entirely; just hide the text field inside.
if (self.isRSSFeed) {
[self.inputToolbar hideInputMethod];
}
@ -780,7 +785,7 @@ typedef enum : NSUInteger {
self.inputToolbar.inputToolbarDelegate = self;
self.inputToolbar.inputTextViewDelegate = self;
SET_SUBVIEW_ACCESSIBILITY_IDENTIFIER(self, _inputToolbar);
[self updateInputToolbar];
[self updateInputBar];
self.loadMoreHeader = [UILabel new];
self.loadMoreHeader.text = NSLocalizedString(@"CONVERSATION_VIEW_LOADING_MORE_MESSAGES", @"Indicates that the app is loading more messages in this conversation.");
@ -921,7 +926,7 @@ typedef enum : NSUInteger {
NSTimeInterval appearenceDuration = CACurrentMediaTime() - self.viewControllerCreatedAt;
OWSLogVerbose(@"First viewWillAppear took: %.2fms", appearenceDuration * 1000);
}
[self updateInputToolbarLayout];
[self updateInputBarLayout];
}
- (NSArray<id<ConversationViewItem>> *)viewItems
@ -1048,7 +1053,7 @@ typedef enum : NSUInteger {
- (void)updateSessionRestoreBanner {
BOOL isContactThread = [self.thread isKindOfClass:[TSContactThread class]];
BOOL shouldRemoveBanner = !isContactThread;
BOOL shouldDetachBanner = !isContactThread;
if (isContactThread) {
TSContactThread *thread = (TSContactThread *)self.thread;
if (thread.sessionRestoreDevices.count > 0) {
@ -1068,11 +1073,10 @@ typedef enum : NSUInteger {
}];
}
} else {
shouldRemoveBanner = true;
shouldDetachBanner = true;
}
}
if (shouldRemoveBanner && self.restoreSessionBannerView) {
if (shouldDetachBanner && self.restoreSessionBannerView != nil) {
[self.restoreSessionBannerView removeFromSuperview];
self.restoreSessionBannerView = nil;
}
@ -1461,7 +1465,7 @@ typedef enum : NSUInteger {
// Clear the "on open" state after the view has been presented.
self.actionOnOpen = ConversationViewActionNone;
[self updateInputToolbarLayout];
[self updateInputBarLayout];
[self ensureScrollDownButton];
}
@ -1668,7 +1672,7 @@ typedef enum : NSUInteger {
#pragma mark - Updating
- (void)updateInputToolbar {
- (void)updateInputBar {
BOOL shouldInputBarBeEnabled = [LKFriendRequestProtocol shouldInputBarBeEnabledForThread:self.thread];
[self.inputToolbar setUserInteractionEnabled:shouldInputBarBeEnabled];
NSString *placeholderText = shouldInputBarBeEnabled ? NSLocalizedString(@"Message", "") : NSLocalizedString(@"Pending session request", "");
@ -2890,6 +2894,15 @@ typedef enum : NSUInteger {
AudioServicesPlaySystemSound(soundId);
}
[self.typingIndicators didSendOutgoingMessageInThread:self.thread];
// Loki: Lock the input bar early
if ([self.thread isKindOfClass:TSContactThread.class] && [message isKindOfClass:LKFriendRequestMessage.class]) {
NSString *recipientID = self.thread.contactIdentifier;
OWSAssertIsOnMainThread();
[OWSPrimaryStorage.sharedManager.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[LKFriendRequestProtocol setFriendRequestStatusToSendingIfNeededForHexEncodedPublicKey:recipientID transaction:transaction];
}];
}
}
#pragma mark UIDocumentMenuDelegate
@ -5086,7 +5099,7 @@ typedef enum : NSUInteger {
}
[self dismissMenuActionsIfNecessary];
[self updateInputToolbar];
[self updateInputBar];
if (self.isGroupConversation) {
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
@ -5332,7 +5345,7 @@ typedef enum : NSUInteger {
// new size.
[strongSelf resetForSizeOrOrientationChange];
[strongSelf updateInputToolbarLayout];
[strongSelf updateInputBarLayout];
if (self.menuActionsViewController != nil) {
[self scrollToMenuActionInteraction:NO];
@ -5367,17 +5380,17 @@ typedef enum : NSUInteger {
// Try to update the lastKnownDistanceFromBottom; the content size may have changed.
[self updateLastKnownDistanceFromBottom];
}
[self updateInputToolbarLayout];
[self updateInputBarLayout];
}
- (void)viewSafeAreaInsetsDidChange
{
[super viewSafeAreaInsetsDidChange];
[self updateInputToolbarLayout];
[self updateInputBarLayout];
}
- (void)updateInputToolbarLayout
- (void)updateInputBarLayout
{
UIEdgeInsets safeAreaInsets = UIEdgeInsetsZero;
if (@available(iOS 11, *)) {

@ -123,6 +123,8 @@ typedef NS_ENUM(NSUInteger, ConversationUpdateItemType) {
- (void)appendUnsavedOutgoingTextMessage:(TSOutgoingMessage *)outgoingMessage;
- (BOOL)reloadViewItems;
@end
NS_ASSUME_NONNULL_END

@ -184,17 +184,6 @@ typedef void (^BuildOutgoingMessageCompletionBlock)(TSOutgoingMessage *savedMess
// If we're friends then the assumption is that we have the other user's pre key bundle.
NSString *messageClassAsString = (thread.isContactFriend || thread.isGroupThread || thread.isNoteToSelf) ? @"TSOutgoingMessage" : @"LKFriendRequestMessage";
Class messageClass = NSClassFromString(messageClassAsString);
if ([messageClassAsString isEqual:@"LKFriendRequestMessage"]) {
NSString *recipientID = thread.contactIdentifier;
if (recipientID != nil) {
dispatch_async(dispatch_get_main_queue(), ^{
[OWSPrimaryStorage.sharedManager.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[LKFriendRequestProtocol setFriendRequestStatusToSendingIfNeededForHexEncodedPublicKey:recipientID transaction:transaction];
}];
});
}
}
TSOutgoingMessage *message =
[[messageClass alloc] initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp]

@ -184,12 +184,12 @@ extern ConversationColorName const kConversationColorName_Default;
#pragma mark - Loki Friend Request Handling
/**
Remove any outgoing friend request message which failed to send
Remove any old outgoing friend request messages that failed to send.
*/
- (void)removeOldOutgoingFriendRequestMessagesIfNeededWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
/**
Remove any old incoming friend request message that is still pending
Remove any old incoming friend request messages that are pending.
*/
- (void)removeOldIncomingFriendRequestMessagesIfNeededWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;

@ -722,12 +722,13 @@ ConversationColorName const kConversationColorName_Default = ConversationColorNa
- (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
// Friend request status doesn't apply to group threads
if (self.isGroupThread) { return; }
// If we're friends with the other person then we don't need to remove any friend request messages
if ([LKFriendRequestProtocol isFriendsWithAnyLinkedDeviceOfHexEncodedPublicKey:self.contactIdentifier]) { return; }
NSMutableArray<NSString *> *idsToRemove = [NSMutableArray new];
__block TSMessage *_Nullable messageToKeep = nil; // We want to keep this interaction and not remove it
__block TSMessage *_Nullable messageToKeep = nil;
[self enumerateInteractionsWithTransaction:transaction usingBlock:^(TSInteraction *interaction, YapDatabaseReadTransaction *transaction) {
if (interaction.interactionType != interactionType) { return; }
@ -754,14 +755,14 @@ ConversationColorName const kConversationColorName_Default = ConversationColorNa
}
}];
for (NSString *interactionId in idsToRemove) {
// Don't delete the recent message
if (messageToKeep != nil && interactionId == messageToKeep.uniqueId) { continue; }
for (NSString *interactionID in idsToRemove) {
// Don't delete the most recent message
if (messageToKeep != nil && interactionID == messageToKeep.uniqueId) { continue; }
// We need to fetch each interaction, since [TSInteraction removeWithTransaction:] does important work
TSInteraction *_Nullable interaction = [TSInteraction fetchObjectWithUniqueID:interactionId transaction:transaction];
if (!interaction) {
OWSFailDebug(@"couldn't load thread's interaction for deletion.");
TSInteraction *_Nullable interaction = [TSInteraction fetchObjectWithUniqueID:interactionID transaction:transaction];
if (interaction == nil) {
OWSFailDebug(@"Couldn't load interaction.");
continue;
}
[interaction removeWithTransaction:transaction];

@ -40,6 +40,7 @@ typedef NS_ENUM(NSInteger, LKMessageFriendRequestStatus) {
@property (nonatomic, nullable) OWSLinkPreview *linkPreview;
// Loki friend request handling
@property (nonatomic) LKMessageFriendRequestStatus friendRequestStatus __deprecated_msg("no longer used as of version 1.1.2");
/// Only relevant to outgoing messages.
@property (nonatomic) uint64_t friendRequestExpiresAt;
@property (nonatomic, readonly) BOOL isFriendRequest;
@property (nonatomic, readonly) BOOL hasFriendRequestStatusMessage;

@ -475,13 +475,15 @@ static const NSUInteger OWSMessageSchemaVersion = 4;
- (BOOL)isFriendRequest
{
return [LKFriendRequestProtocol getFriendRequestUIStatusForThread:self.thread] != LKFriendRequestUIStatusFriends;
if (self.thread.isContactFriend) { return NO; }
return [self.uniqueId isEqual:self.thread.lastInteraction.uniqueId];
}
- (BOOL)hasFriendRequestStatusMessage
{
LKFriendRequestUIStatus friendRequestStatus = [LKFriendRequestProtocol getFriendRequestUIStatusForThread:self.thread];
return friendRequestStatus != LKFriendRequestUIStatusNone && friendRequestStatus != LKFriendRequestUIStatusFriends;
if (friendRequestStatus == LKFriendRequestUIStatusNone || friendRequestStatus == LKFriendRequestUIStatusFriends) { return NO; };
return [self.uniqueId isEqual:self.thread.lastInteraction.uniqueId];
}
#pragma mark - Open Groups

Loading…
Cancel
Save