Merge branch 'charlesmchen/permissiveSendMessageButton'

pull/1/head
Matthew Chen 7 years ago
commit 95c17afe7e

@ -187,7 +187,7 @@ typedef enum : NSUInteger {
#pragma mark - #pragma mark -
@protocol OWSMessagesToolbarContentDelegate <NSObject> @protocol OWSVoiceMemoGestureDelegate <NSObject>
- (void)voiceMemoGestureDidStart; - (void)voiceMemoGestureDidStart;
@ -201,9 +201,19 @@ typedef enum : NSUInteger {
#pragma mark - #pragma mark -
@protocol OWSSendMessageGestureDelegate <NSObject>
- (void)sendMessageGestureRecognized;
@end
#pragma mark -
@interface OWSMessagesToolbarContentView () <UIGestureRecognizerDelegate> @interface OWSMessagesToolbarContentView () <UIGestureRecognizerDelegate>
@property (nonatomic, nullable, weak) id<OWSMessagesToolbarContentDelegate> delegate; @property (nonatomic, nullable, weak) id<OWSVoiceMemoGestureDelegate> voiceMemoGestureDelegate;
@property (nonatomic, nullable, weak) id<OWSSendMessageGestureDelegate> sendMessageGestureDelegate;
@property (nonatomic) BOOL shouldShowVoiceMemoButton; @property (nonatomic) BOOL shouldShowVoiceMemoButton;
@ -255,6 +265,17 @@ typedef enum : NSUInteger {
longPressGestureRecognizer.minimumPressDuration = 0; longPressGestureRecognizer.minimumPressDuration = 0;
longPressGestureRecognizer.delegate = self; longPressGestureRecognizer.delegate = self;
[self addGestureRecognizer:longPressGestureRecognizer]; [self addGestureRecognizer:longPressGestureRecognizer];
// We want to be permissive about taps on the send button, so we:
//
// * Add the gesture recognizer to the button's superview instead of the button.
// * Filter the touches that the gesture recognizer receives by serving as its
// delegate.
UITapGestureRecognizer *tapGestureRecognizer =
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
tapGestureRecognizer.delegate = self;
[self addGestureRecognizer:tapGestureRecognizer];
self.userInteractionEnabled = YES; self.userInteractionEnabled = YES;
self.voiceMemoButton = button; self.voiceMemoButton = button;
@ -309,19 +330,19 @@ typedef enum : NSUInteger {
if (self.isRecordingVoiceMemo) { if (self.isRecordingVoiceMemo) {
// Cancel voice message if necessary. // Cancel voice message if necessary.
self.isRecordingVoiceMemo = NO; self.isRecordingVoiceMemo = NO;
[self.delegate voiceMemoGestureDidCancel]; [self.voiceMemoGestureDelegate voiceMemoGestureDidCancel];
} }
break; break;
case UIGestureRecognizerStateBegan: case UIGestureRecognizerStateBegan:
if (self.isRecordingVoiceMemo) { if (self.isRecordingVoiceMemo) {
// Cancel voice message if necessary. // Cancel voice message if necessary.
self.isRecordingVoiceMemo = NO; self.isRecordingVoiceMemo = NO;
[self.delegate voiceMemoGestureDidCancel]; [self.voiceMemoGestureDelegate voiceMemoGestureDidCancel];
} }
// Start voice message. // Start voice message.
self.isRecordingVoiceMemo = YES; self.isRecordingVoiceMemo = YES;
self.voiceMemoGestureStartLocation = [sender locationInView:self]; self.voiceMemoGestureStartLocation = [sender locationInView:self];
[self.delegate voiceMemoGestureDidStart]; [self.voiceMemoGestureDelegate voiceMemoGestureDidStart];
break; break;
case UIGestureRecognizerStateChanged: case UIGestureRecognizerStateChanged:
if (self.isRecordingVoiceMemo) { if (self.isRecordingVoiceMemo) {
@ -335,9 +356,9 @@ typedef enum : NSUInteger {
BOOL isCancelled = cancelAlpha >= 1.f; BOOL isCancelled = cancelAlpha >= 1.f;
if (isCancelled) { if (isCancelled) {
self.isRecordingVoiceMemo = NO; self.isRecordingVoiceMemo = NO;
[self.delegate voiceMemoGestureDidCancel]; [self.voiceMemoGestureDelegate voiceMemoGestureDidCancel];
} else { } else {
[self.delegate voiceMemoGestureDidChange:cancelAlpha]; [self.voiceMemoGestureDelegate voiceMemoGestureDidChange:cancelAlpha];
} }
} }
break; break;
@ -345,12 +366,23 @@ typedef enum : NSUInteger {
if (self.isRecordingVoiceMemo) { if (self.isRecordingVoiceMemo) {
// End voice message. // End voice message.
self.isRecordingVoiceMemo = NO; self.isRecordingVoiceMemo = NO;
[self.delegate voiceMemoGestureDidEnd]; [self.voiceMemoGestureDelegate voiceMemoGestureDidEnd];
} }
break; break;
} }
} }
- (void)handleTap:(UIGestureRecognizer *)sender
{
switch (sender.state) {
case UIGestureRecognizerStateRecognized:
[self.sendMessageGestureDelegate sendMessageGestureRecognized];
break;
default:
break;
}
}
- (void)cancelVoiceMemoIfNecessary - (void)cancelVoiceMemoIfNecessary
{ {
if (self.isRecordingVoiceMemo) { if (self.isRecordingVoiceMemo) {
@ -362,24 +394,40 @@ typedef enum : NSUInteger {
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{ {
if (self.rightBarButtonItem != self.voiceMemoButton) { if ([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]]) {
return NO; if (self.rightBarButtonItem != self.voiceMemoButton) {
} return NO;
}
// We want to be permissive about the voice message gesture, so we accept
// gesture that begin within N points of its bounds.
CGFloat kVoiceMemoGestureTolerancePoints = 10;
CGPoint location = [touch locationInView:self.voiceMemoButton];
CGRect hitTestRect = CGRectInset(
self.voiceMemoButton.bounds, -kVoiceMemoGestureTolerancePoints, -kVoiceMemoGestureTolerancePoints);
return CGRectContainsPoint(hitTestRect, location);
} else if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
if (self.rightBarButtonItem == self.voiceMemoButton) {
return NO;
}
// We want to be permissive about the voice message gesture, so we accept UIView *sendButton = self.rightBarButtonItem;
// gesture that begin within N points of the // We want to be permissive about taps on the send button, so we accept
CGFloat kVoiceMemoGestureTolerancePoints = 10; // gesture that begin within N points of its bounds.
CGPoint location = [touch locationInView:self.voiceMemoButton]; CGFloat kSendButtonTolerancePoints = 10;
CGRect hitTestRect = CGRectInset( CGPoint location = [touch locationInView:sendButton];
self.voiceMemoButton.bounds, -kVoiceMemoGestureTolerancePoints, -kVoiceMemoGestureTolerancePoints); CGRect hitTestRect = CGRectInset(sendButton.bounds, -kSendButtonTolerancePoints, -kSendButtonTolerancePoints);
return CGRectContainsPoint(hitTestRect, location); return CGRectContainsPoint(hitTestRect, location);
} else {
return YES;
}
} }
@end @end
#pragma mark - #pragma mark -
@interface OWSMessagesInputToolbar () @interface OWSMessagesInputToolbar () <OWSSendMessageGestureDelegate>
@property (nonatomic) UIView *voiceMemoUI; @property (nonatomic) UIView *voiceMemoUI;
@ -409,6 +457,7 @@ typedef enum : NSUInteger {
OWSAssert(views.count == 1); OWSAssert(views.count == 1);
OWSMessagesToolbarContentView *view = views[0]; OWSMessagesToolbarContentView *view = views[0];
OWSAssert([view isKindOfClass:[OWSMessagesToolbarContentView class]]); OWSAssert([view isKindOfClass:[OWSMessagesToolbarContentView class]]);
view.sendMessageGestureDelegate = self;
return view; return view;
} }
@ -587,13 +636,21 @@ typedef enum : NSUInteger {
[self.recordingLabel sizeToFit]; [self.recordingLabel sizeToFit];
} }
#pragma mark - OWSSendMessageGestureDelegate
- (void)sendMessageGestureRecognized
{
OWSAssert(self.sendButtonOnRight);
[self.delegate messagesInputToolbar:self didPressRightBarButton:self.contentView.rightBarButtonItem];
}
@end @end
#pragma mark - #pragma mark -
@interface MessagesViewController () <JSQMessagesComposerTextViewPasteDelegate, @interface MessagesViewController () <JSQMessagesComposerTextViewPasteDelegate,
OWSTextViewPasteDelegate, OWSTextViewPasteDelegate,
OWSMessagesToolbarContentDelegate, OWSVoiceMemoGestureDelegate,
OWSConversationSettingsViewDelegate, OWSConversationSettingsViewDelegate,
UIDocumentMenuDelegate, UIDocumentMenuDelegate,
UIDocumentPickerDelegate, UIDocumentPickerDelegate,
@ -1533,7 +1590,7 @@ typedef enum : NSUInteger {
OWSAssert(self.inputToolbar.contentView.textView); OWSAssert(self.inputToolbar.contentView.textView);
self.inputToolbar.contentView.textView.pasteDelegate = self; self.inputToolbar.contentView.textView.pasteDelegate = self;
((OWSMessagesComposerTextView *) self.inputToolbar.contentView.textView).textViewPasteDelegate = self; ((OWSMessagesComposerTextView *) self.inputToolbar.contentView.textView).textViewPasteDelegate = self;
((OWSMessagesToolbarContentView *)self.inputToolbar.contentView).delegate = self; ((OWSMessagesToolbarContentView *)self.inputToolbar.contentView).voiceMemoGestureDelegate = self;
} }
// Overiding JSQMVC layout defaults // Overiding JSQMVC layout defaults
@ -3987,7 +4044,7 @@ typedef enum : NSUInteger {
[self scrollToBottomAnimated:NO]; [self scrollToBottomAnimated:NO];
} }
#pragma mark - OWSMessagesToolbarContentDelegate #pragma mark - OWSVoiceMemoGestureDelegate
- (void)voiceMemoGestureDidStart - (void)voiceMemoGestureDidStart
{ {

Loading…
Cancel
Save