|
|
@ -577,6 +577,7 @@ typedef enum : NSUInteger {
|
|
|
|
@property (nonatomic) MPMoviePlayerController *videoPlayer;
|
|
|
|
@property (nonatomic) MPMoviePlayerController *videoPlayer;
|
|
|
|
@property (nonatomic) AVAudioRecorder *audioRecorder;
|
|
|
|
@property (nonatomic) AVAudioRecorder *audioRecorder;
|
|
|
|
@property (nonatomic) OWSAudioAttachmentPlayer *audioAttachmentPlayer;
|
|
|
|
@property (nonatomic) OWSAudioAttachmentPlayer *audioAttachmentPlayer;
|
|
|
|
|
|
|
|
@property (nonatomic) NSUUID *voiceMessageUUID;
|
|
|
|
|
|
|
|
|
|
|
|
@property (nonatomic) NSTimer *readTimer;
|
|
|
|
@property (nonatomic) NSTimer *readTimer;
|
|
|
|
@property (nonatomic) UIView *navigationBarTitleView;
|
|
|
|
@property (nonatomic) UIView *navigationBarTitleView;
|
|
|
@ -608,6 +609,7 @@ typedef enum : NSUInteger {
|
|
|
|
|
|
|
|
|
|
|
|
@property (nonatomic) NSCache *messageAdapterCache;
|
|
|
|
@property (nonatomic) NSCache *messageAdapterCache;
|
|
|
|
@property (nonatomic) BOOL userHasScrolled;
|
|
|
|
@property (nonatomic) BOOL userHasScrolled;
|
|
|
|
|
|
|
|
@property (nonatomic) NSDate *lastMessageSentDate;
|
|
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
@ -1547,6 +1549,7 @@ typedef enum : NSUInteger {
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
[ThreadUtil sendMessageWithText:text inThread:self.thread messageSender:self.messageSender];
|
|
|
|
[ThreadUtil sendMessageWithText:text inThread:self.thread messageSender:self.messageSender];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
self.lastMessageSentDate = [NSDate new];
|
|
|
|
if (updateKeyboardState)
|
|
|
|
if (updateKeyboardState)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
[self toggleDefaultKeyboard];
|
|
|
|
[self toggleDefaultKeyboard];
|
|
|
@ -2871,6 +2874,7 @@ typedef enum : NSUInteger {
|
|
|
|
(unsigned long)attachment.data.length,
|
|
|
|
(unsigned long)attachment.data.length,
|
|
|
|
[attachment mimeType]);
|
|
|
|
[attachment mimeType]);
|
|
|
|
[ThreadUtil sendMessageWithAttachment:attachment inThread:self.thread messageSender:self.messageSender];
|
|
|
|
[ThreadUtil sendMessageWithAttachment:attachment inThread:self.thread messageSender:self.messageSender];
|
|
|
|
|
|
|
|
self.lastMessageSentDate = [NSDate new];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (NSURL *)videoTempFolder {
|
|
|
|
- (NSURL *)videoTempFolder {
|
|
|
@ -3109,6 +3113,9 @@ typedef enum : NSUInteger {
|
|
|
|
{
|
|
|
|
{
|
|
|
|
OWSAssert([NSThread isMainThread]);
|
|
|
|
OWSAssert([NSThread isMainThread]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NSUUID *voiceMessageUUID = [NSUUID UUID];
|
|
|
|
|
|
|
|
self.voiceMessageUUID = voiceMessageUUID;
|
|
|
|
|
|
|
|
|
|
|
|
__weak typeof(self) weakSelf = self;
|
|
|
|
__weak typeof(self) weakSelf = self;
|
|
|
|
[[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
|
|
|
|
[[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
@ -3117,6 +3124,12 @@ typedef enum : NSUInteger {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (strongSelf.voiceMessageUUID != voiceMessageUUID) {
|
|
|
|
|
|
|
|
// This voice message recording has been cancelled
|
|
|
|
|
|
|
|
// before recording could begin.
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (granted) {
|
|
|
|
if (granted) {
|
|
|
|
[strongSelf startRecordingVoiceMemo];
|
|
|
|
[strongSelf startRecordingVoiceMemo];
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
@ -3195,9 +3208,12 @@ typedef enum : NSUInteger {
|
|
|
|
|
|
|
|
|
|
|
|
DDLogInfo(@"endRecordingVoiceMemo");
|
|
|
|
DDLogInfo(@"endRecordingVoiceMemo");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.voiceMessageUUID = nil;
|
|
|
|
|
|
|
|
|
|
|
|
if (!self.audioRecorder) {
|
|
|
|
if (!self.audioRecorder) {
|
|
|
|
|
|
|
|
// No voice message recording is in progress.
|
|
|
|
|
|
|
|
// We may be cancelling before the recording could begin.
|
|
|
|
DDLogError(@"%@ Missing audioRecorder", self.tag);
|
|
|
|
DDLogError(@"%@ Missing audioRecorder", self.tag);
|
|
|
|
OWSAssert(0);
|
|
|
|
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -3210,6 +3226,8 @@ typedef enum : NSUInteger {
|
|
|
|
DDLogInfo(@"Discarding voice message; too short.");
|
|
|
|
DDLogInfo(@"Discarding voice message; too short.");
|
|
|
|
self.audioRecorder = nil;
|
|
|
|
self.audioRecorder = nil;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[self dismissKeyBoard];
|
|
|
|
|
|
|
|
|
|
|
|
[OWSAlerts
|
|
|
|
[OWSAlerts
|
|
|
|
showAlertWithTitle:
|
|
|
|
showAlertWithTitle:
|
|
|
|
NSLocalizedString(@"VOICE_MESSAGE_TOO_SHORT_ALERT_TITLE",
|
|
|
|
NSLocalizedString(@"VOICE_MESSAGE_TOO_SHORT_ALERT_TITLE",
|
|
|
@ -3263,6 +3281,7 @@ typedef enum : NSUInteger {
|
|
|
|
|
|
|
|
|
|
|
|
[self.audioRecorder stop];
|
|
|
|
[self.audioRecorder stop];
|
|
|
|
self.audioRecorder = nil;
|
|
|
|
self.audioRecorder = nil;
|
|
|
|
|
|
|
|
self.voiceMessageUUID = nil;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#pragma mark Accessory View
|
|
|
|
#pragma mark Accessory View
|
|
|
@ -3573,6 +3592,17 @@ typedef enum : NSUInteger {
|
|
|
|
|
|
|
|
|
|
|
|
DDLogInfo(@"voiceMemoGestureDidStart");
|
|
|
|
DDLogInfo(@"voiceMemoGestureDidStart");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const CGFloat kIgnoreMessageSendDoubleTapDurationSeconds = 2.f;
|
|
|
|
|
|
|
|
if (self.lastMessageSentDate &&
|
|
|
|
|
|
|
|
[[NSDate new] timeIntervalSinceDate:self.lastMessageSentDate] < kIgnoreMessageSendDoubleTapDurationSeconds) {
|
|
|
|
|
|
|
|
// If users double-taps the message send button, the second tap can look like a
|
|
|
|
|
|
|
|
// very short voice message gesture. We want to ignore such gestures.
|
|
|
|
|
|
|
|
[((OWSMessagesToolbarContentView *)self.inputToolbar.contentView)cancelVoiceMemoIfNecessary];
|
|
|
|
|
|
|
|
[((OWSMessagesInputToolbar *)self.inputToolbar) hideVoiceMemoUI:NO];
|
|
|
|
|
|
|
|
[self cancelRecordingVoiceMemo];
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[((OWSMessagesInputToolbar *)self.inputToolbar)showVoiceMemoUI];
|
|
|
|
[((OWSMessagesInputToolbar *)self.inputToolbar)showVoiceMemoUI];
|
|
|
|
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
|
|
|
|
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
|
|
|
|
[self requestRecordingVoiceMemo];
|
|
|
|
[self requestRecordingVoiceMemo];
|
|
|
|