Audio attachments UI

This commit is contained in:
Jack Rogers 2015-01-24 13:48:40 -10:00 committed by Frederic Jacobs
parent d740f801c6
commit 1eef08628a
19 changed files with 155 additions and 87 deletions

View File

@ -19,3 +19,4 @@ pod 'DJWActionSheet'
pod 'UICKeyChainStore', :podspec => 'Podspecs/UICKeyChainStore.podspec'
pod 'APDropDownNavToolbar', :git => 'https://github.com/corbett/APDropDownNavToolbar.git', :branch => 'master'
pod 'FFCircularProgressView', '>= 0.1'
pod 'SCWaveformView'

View File

@ -45,6 +45,7 @@ PODS:
- PastelogKit (1.2):
- CocoaLumberjack (~> 1.9)
- ProtocolBuffers (1.9.3)
- SCWaveformView (1.0.0)
- SocketRocket (0.3.1-beta2)
- SQLCipher/common (3.1.0)
- SQLCipher/fts (3.1.0):
@ -71,6 +72,7 @@ DEPENDENCIES:
- Mantle (~> 1.5)
- OpenSSL (~> 1.0.200)
- PastelogKit (~> 1.2)
- SCWaveformView
- SocketRocket (from `https://github.com/square/SocketRocket.git`, commit `954750c018`)
- SSKeychain
- TwistedOakCollapsingFutures (~> 1.0)
@ -117,6 +119,7 @@ SPEC CHECKSUMS:
OpenSSL: 4c7be3eca71139f52984542d8c4c0752154d26c3
PastelogKit: 8bab71b1d187617a83e7124cffe9eb1a600e6695
ProtocolBuffers: e80f9e4fc401aec9d3c30be70db87fcd5f1cb880
SCWaveformView: 55f0cd6e80df1a46ff70892bc4041f5b7d8ad43c
SocketRocket: 9cbe08469513356cddc0afcab1ff160bd190296a
SQLCipher: 981110217eb93c2779c34fb59e646a1c1da918d8
SSKeychain: cc48bd3ad24fcd9125adb9e0d23dd50b8bbd08b9

2
Pods

@ -1 +1 @@
Subproject commit a5b5acb189a2f9f5ddb14dd0552199324a9167a3
Subproject commit 19ec30e1b24355b4115a21b6895a49f378ad40c4

View File

@ -287,6 +287,14 @@
AA0C8E498E2046B0B81EEE6E /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8313AE91B4954215858A5662 /* libPods.a */; };
AD41D7B51A6F6F0600241130 /* play_button.png in Resources */ = {isa = PBXBuildFile; fileRef = AD41D7B31A6F6F0600241130 /* play_button.png */; };
AD41D7B61A6F6F0600241130 /* play_button@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AD41D7B41A6F6F0600241130 /* play_button@2x.png */; };
AD83FF3F1A73426500B5C81A /* audio_pause_button_blue.png in Resources */ = {isa = PBXBuildFile; fileRef = AD83FF381A73426500B5C81A /* audio_pause_button_blue.png */; };
AD83FF401A73426500B5C81A /* audio_pause_button_blue@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AD83FF391A73426500B5C81A /* audio_pause_button_blue@2x.png */; };
AD83FF411A73426500B5C81A /* audio_play_button_blue@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AD83FF3A1A73426500B5C81A /* audio_play_button_blue@2x.png */; };
AD83FF421A73426500B5C81A /* audio_play_button.png in Resources */ = {isa = PBXBuildFile; fileRef = AD83FF3B1A73426500B5C81A /* audio_play_button.png */; };
AD83FF431A73426500B5C81A /* audio_play_button@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AD83FF3C1A73426500B5C81A /* audio_play_button@2x.png */; };
AD83FF441A73426500B5C81A /* audio_pause_button.png in Resources */ = {isa = PBXBuildFile; fileRef = AD83FF3D1A73426500B5C81A /* audio_pause_button.png */; };
AD83FF451A73426500B5C81A /* audio_pause_button@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AD83FF3E1A73426500B5C81A /* audio_pause_button@2x.png */; };
AD83FF471A73428300B5C81A /* audio_play_button_blue.png in Resources */ = {isa = PBXBuildFile; fileRef = AD83FF461A73428300B5C81A /* audio_play_button_blue.png */; };
B10C9B5F1A7049EC00ECA2BF /* pause_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B10C9B5B1A7049EC00ECA2BF /* pause_icon.png */; };
B10C9B601A7049EC00ECA2BF /* pause_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B10C9B5C1A7049EC00ECA2BF /* pause_icon@2x.png */; };
B10C9B611A7049EC00ECA2BF /* play_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B10C9B5D1A7049EC00ECA2BF /* play_icon.png */; };
@ -885,6 +893,14 @@
A5E9D4BA1A65FAD800E4481C /* TSVideoAttachmentAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSVideoAttachmentAdapter.h; sourceTree = "<group>"; };
AD41D7B31A6F6F0600241130 /* play_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = play_button.png; sourceTree = "<group>"; };
AD41D7B41A6F6F0600241130 /* play_button@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "play_button@2x.png"; sourceTree = "<group>"; };
AD83FF381A73426500B5C81A /* audio_pause_button_blue.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = audio_pause_button_blue.png; sourceTree = "<group>"; };
AD83FF391A73426500B5C81A /* audio_pause_button_blue@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "audio_pause_button_blue@2x.png"; sourceTree = "<group>"; };
AD83FF3A1A73426500B5C81A /* audio_play_button_blue@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "audio_play_button_blue@2x.png"; sourceTree = "<group>"; };
AD83FF3B1A73426500B5C81A /* audio_play_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = audio_play_button.png; sourceTree = "<group>"; };
AD83FF3C1A73426500B5C81A /* audio_play_button@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "audio_play_button@2x.png"; sourceTree = "<group>"; };
AD83FF3D1A73426500B5C81A /* audio_pause_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = audio_pause_button.png; sourceTree = "<group>"; };
AD83FF3E1A73426500B5C81A /* audio_pause_button@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "audio_pause_button@2x.png"; sourceTree = "<group>"; };
AD83FF461A73428300B5C81A /* audio_play_button_blue.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = audio_play_button_blue.png; sourceTree = "<group>"; };
B10C9B5B1A7049EC00ECA2BF /* pause_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = pause_icon.png; sourceTree = "<group>"; };
B10C9B5C1A7049EC00ECA2BF /* pause_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "pause_icon@2x.png"; sourceTree = "<group>"; };
B10C9B5D1A7049EC00ECA2BF /* play_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = play_icon.png; sourceTree = "<group>"; };
@ -2136,6 +2152,14 @@
B633C4FD1A1D190B0059AC12 /* Images */ = {
isa = PBXGroup;
children = (
AD83FF461A73428300B5C81A /* audio_play_button_blue.png */,
AD83FF381A73426500B5C81A /* audio_pause_button_blue.png */,
AD83FF391A73426500B5C81A /* audio_pause_button_blue@2x.png */,
AD83FF3A1A73426500B5C81A /* audio_play_button_blue@2x.png */,
AD83FF3B1A73426500B5C81A /* audio_play_button.png */,
AD83FF3C1A73426500B5C81A /* audio_play_button@2x.png */,
AD83FF3D1A73426500B5C81A /* audio_pause_button.png */,
AD83FF3E1A73426500B5C81A /* audio_pause_button@2x.png */,
B10C9B5B1A7049EC00ECA2BF /* pause_icon.png */,
B10C9B5C1A7049EC00ECA2BF /* pause_icon@2x.png */,
B10C9B5D1A7049EC00ECA2BF /* play_icon.png */,
@ -2906,17 +2930,20 @@
AD41D7B61A6F6F0600241130 /* play_button@2x.png in Resources */,
B633C5DC1A1D190B0059AC12 /* shred@2x.png in Resources */,
B633C5E61A1D190B0059AC12 /* speaker_on@2x.png in Resources */,
AD83FF3F1A73426500B5C81A /* audio_pause_button_blue.png in Resources */,
B633C5BB1A1D190B0059AC12 /* message_bubble.png in Resources */,
B633C5B51A1D190B0059AC12 /* lock@2x.png in Resources */,
A5509ECA1A69AB8B00ABA4BC /* Storyboard.storyboard in Resources */,
A507A3B11A6C60E300BEED0D /* InboxTableViewCell.xib in Resources */,
FCA52AE81A2B676C00CCADFA /* call_incoming@2x.png in Resources */,
AD83FF421A73426500B5C81A /* audio_play_button.png in Resources */,
FC1F90C01A22342B004F8253 /* group_photo@2x.png in Resources */,
FCA52AE91A2B676C00CCADFA /* call_missed@2x.png in Resources */,
B633C5C41A1D190B0059AC12 /* mute_on@2x.png in Resources */,
B633C5CE1A1D190B0059AC12 /* quit@2x.png in Resources */,
FCA52AEB1A2B676C00CCADFA /* checkmark_light@2x.png in Resources */,
B633C5D01A1D190B0059AC12 /* red-delete@2x.png in Resources */,
AD83FF441A73426500B5C81A /* audio_pause_button.png in Resources */,
AD41D7B51A6F6F0600241130 /* play_button.png in Resources */,
B633C59D1A1D190B0059AC12 /* endcall@2x.png in Resources */,
B633C5B41A1D190B0059AC12 /* keypad@2x.png in Resources */,
@ -2935,13 +2962,16 @@
FCB626A51A3B00FA00FDB504 /* info@2x.png in Resources */,
B633C5971A1D190B0059AC12 /* delete@2x.png in Resources */,
FC9120431A39F9E00074545C /* qr_scan_fingerprint@2x.png in Resources */,
AD83FF401A73426500B5C81A /* audio_pause_button_blue@2x.png in Resources */,
B66DBF4A19D5BBC8006EA940 /* Images.xcassets in Resources */,
FCA52AE71A2B676C00CCADFA /* call_failed@2x.png in Resources */,
70B8FEE21909FE360042E3F0 /* 171756__nenadsimic__picked-coin-echo-2.wav in Resources */,
B633C5801A1D190B0059AC12 /* archive@2x.png in Resources */,
AD83FF431A73426500B5C81A /* audio_play_button@2x.png in Resources */,
FC1F90C71A223991004F8253 /* signals_tab@2x.png in Resources */,
FCB626B51A3B067900FDB504 /* ArrowBottom@2x.png in Resources */,
B633C5C31A1D190B0059AC12 /* mute_off@2x.png in Resources */,
AD83FF411A73426500B5C81A /* audio_play_button_blue@2x.png in Resources */,
FCB626B71A3B067900FDB504 /* ArrowTop@3x.png in Resources */,
FC1F90C61A223991004F8253 /* settings_tab@2x.png in Resources */,
FCA52AEA1A2B676C00CCADFA /* call_outgoing@2x.png in Resources */,
@ -2979,8 +3009,10 @@
B633C5961A1D190B0059AC12 /* DefaultContactImage.png in Resources */,
B10C9B5F1A7049EC00ECA2BF /* pause_icon.png in Resources */,
E148751218A06AFD002CC4F3 /* HelveticaNeueLTStd-Bd.otf in Resources */,
AD83FF471A73428300B5C81A /* audio_play_button_blue.png in Resources */,
FCA52AE61A2B676C00CCADFA /* call_canceled@2x.png in Resources */,
FC3BD9861A30A62D005B96BB /* twitter@2x.png in Resources */,
AD83FF451A73426500B5C81A /* audio_pause_button@2x.png in Resources */,
E148751318A06AFD002CC4F3 /* HelveticaNeueLTStd-Th.otf in Resources */,
FC3BD9841A306483005B96BB /* signals_error@2x.png in Resources */,
E148751418A06AFD002CC4F3 /* HelveticaNeueLTStd-Lt.otf in Resources */,

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -2,10 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
@ -69,9 +65,13 @@
<array>
<string>armv7</string>
</array>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>

View File

@ -54,8 +54,12 @@ NSString * const TSAttachementFileRelationshipEdge = @"TSAttachementFileEdge";
- (NSString*)filePath {
if ([self isVideo] || [self isAudio]) {
return [[[[self class] attachmentsFolder] stringByAppendingFormat:@"/%@", self.uniqueId] stringByAppendingPathExtension:[self mediaExtension]];
NSString *path = [[[[self class] attachmentsFolder] stringByAppendingFormat:@"/%@", self.uniqueId] stringByAppendingPathExtension:[self mediaExtension]];
NSURL *pathURL = [NSURL URLWithString:path];
NSString *mp3String = [NSString stringWithFormat:@"%@.mp3", [[pathURL URLByDeletingPathExtension] absoluteString]];
if ([[NSFileManager defaultManager] fileExistsAtPath:mp3String]) {
return mp3String;
} else return path;
}
else {
return [[[self class] attachmentsFolder] stringByAppendingFormat:@"/%@", self.uniqueId];

View File

@ -147,7 +147,6 @@ static NSString *const CONTACT_BROWSE_TABLE_CELL_IDENTIFIER = @"ContactTableView
return [latestAlphabeticalContacts valueForKey:self.latestSortedAlphabeticalContactKeys[index]];
}
-(NSMutableDictionary*)alphabetDictionaryInit
{
NSDictionary * dic;
@ -167,7 +166,6 @@ static NSString *const CONTACT_BROWSE_TABLE_CELL_IDENTIFIER = @"ContactTableView
return [dic mutableCopy];
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

View File

@ -86,6 +86,7 @@ typedef enum : NSUInteger {
@property (nonatomic, retain) JSQMessagesBubbleImage *incomingBubbleImageData;
@property (nonatomic, retain) JSQMessagesBubbleImage *outgoingMessageFailedImageData;
@property (nonatomic, strong) NSTimer *audioPlayerPoller;
@property (nonatomic, strong) TSVideoAttachmentAdapter *currentMediaAdapter;
@property (nonatomic, retain) NSTimer *readTimer;
@ -645,7 +646,7 @@ typedef enum : NSUInteger {
// fileurl disappeared should look up in db as before. will do refactor
// full screen, check this setup with a .mov
TSVideoAttachmentAdapter* messageMedia = (TSVideoAttachmentAdapter*)[messageItem media];
_currentMediaAdapter = messageMedia;
__block TSAttachment *attachment = nil;
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
attachment = [TSAttachment fetchObjectWithUniqueID:messageMedia.attachmentId transaction:transaction];
@ -682,7 +683,7 @@ typedef enum : NSUInteger {
} else {
BOOL isResuming = NO;
[_audioPlayerPoller invalidate];
// loop through all the other bubbles and set their isPlaying to false
NSInteger num_bubbles = [self collectionView:collectionView numberOfItemsInSection:0];
for (NSInteger i=0; i<num_bubbles; i++) {
@ -698,6 +699,7 @@ typedef enum : NSUInteger {
msgMedia.isPaused = NO;
[msgMedia setAudioIconToPlay];
[msgMedia setAudioProgressFromFloat:0];
[msgMedia resetAudioDuration];
}
}
}
@ -710,17 +712,20 @@ typedef enum : NSUInteger {
[messageMedia setAudioIconToPause];
messageMedia.isAudioPlaying = YES;
messageMedia.isPaused = NO;
_audioPlayerPoller = [NSTimer scheduledTimerWithTimeInterval:.01 target:self selector:@selector(audioPlayerUpdated:) userInfo:@{@"adapter": messageMedia} repeats:YES];
_audioPlayerPoller = [NSTimer scheduledTimerWithTimeInterval:.05 target:self selector:@selector(audioPlayerUpdated:) userInfo:@{@"adapter": messageMedia} repeats:YES];
} else {
// if you are tapping an audio msg for the first time to play
messageMedia.isAudioPlaying = YES;
NSError *error;
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:attStream.mediaURL error:&error];
if (error) {
NSLog(@"error: %@", error);
}
[_audioPlayer prepareToPlay];
[_audioPlayer play];
[messageMedia setAudioIconToPause];
_audioPlayer.delegate = self;
_audioPlayerPoller = [NSTimer scheduledTimerWithTimeInterval:.01 target:self selector:@selector(audioPlayerUpdated:) userInfo:@{@"adapter": messageMedia} repeats:YES];
_audioPlayerPoller = [NSTimer scheduledTimerWithTimeInterval:.05 target:self selector:@selector(audioPlayerUpdated:) userInfo:@{@"adapter": messageMedia} repeats:YES];
}
}
}
@ -1293,9 +1298,7 @@ typedef enum : NSUInteger {
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];
[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];
@ -1308,33 +1311,17 @@ typedef enum : NSUInteger {
}
- (void)audioPlayerUpdated:(NSTimer*)timer {
NSDictionary *dict = [timer userInfo];
TSVideoAttachmentAdapter *messageMedia = dict[@"adapter"];
double current = [_audioPlayer currentTime]/[_audioPlayer duration];
[messageMedia setAudioProgressFromFloat:(float)current];
NSTimeInterval duration = ([_audioPlayer duration] - [_audioPlayer currentTime]);
[messageMedia setDurationOfAudio:duration];
double interval = [_audioPlayer duration] - [_audioPlayer currentTime];
[_currentMediaAdapter setDurationOfAudio:interval];
[_currentMediaAdapter setAudioProgressFromFloat:(float)current];
}
- (void) audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
// stop audio polling
[_audioPlayerPoller invalidate];
// reset all audio bars to 0
JSQMessagesCollectionView *collectionView = self.collectionView;
NSInteger num_bubbles = [self collectionView:collectionView numberOfItemsInSection:0];
for (NSInteger i=0; i<num_bubbles; i++) {
NSIndexPath *index_path = [NSIndexPath indexPathForRow:i inSection:0];
TSMessageAdapter *msgAdapter = [collectionView.dataSource collectionView:collectionView messageDataForItemAtIndexPath:index_path];
if (msgAdapter.messageType == TSIncomingMessageAdapter && msgAdapter.isMediaMessage) {
TSVideoAttachmentAdapter* msgMedia = (TSVideoAttachmentAdapter*)[msgAdapter media];
if ([msgMedia isAudio]) {
[msgMedia setAudioProgressFromFloat:0];
[msgMedia setAudioIconToPlay];
[msgMedia removeDurationLabel];
}
}
}
[_currentMediaAdapter setAudioProgressFromFloat:0];
[_currentMediaAdapter setDurationOfAudio:_audioPlayer.duration];
[_currentMediaAdapter setAudioIconToPlay];
}
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder
@ -1344,7 +1331,6 @@ typedef enum : NSUInteger {
}
}
#pragma mark Accessory View
-(void)didPressAccessoryButton:(UIButton *)sender

View File

@ -109,7 +109,7 @@
break;
}
else {
adapter.mediaItem = [[TSVideoAttachmentAdapter alloc] initWithAttachment:stream];
adapter.mediaItem = [[TSVideoAttachmentAdapter alloc] initWithAttachment:stream incoming:[interaction isKindOfClass:[TSIncomingMessage class]]];
adapter.mediaItem.appliesMediaViewMaskAsOutgoing = [interaction isKindOfClass:[TSOutgoingMessage class]];
break;
}

View File

@ -17,7 +17,7 @@
@property (nonatomic) BOOL isAudioPlaying;
@property (nonatomic) BOOL isPaused;
- (instancetype)initWithAttachment:(TSAttachmentStream*)attachment;
- (instancetype)initWithAttachment:(TSAttachmentStream*)attachment incoming:(BOOL)incoming;
- (BOOL)isImage;
- (BOOL)isAudio;
@ -26,6 +26,6 @@
- (void)setAudioIconToPlay;
- (void)setAudioIconToPause;
- (void)setDurationOfAudio:(NSTimeInterval)duration;
- (void)removeDurationLabel;
- (void)resetAudioDuration;
@end

View File

@ -15,26 +15,30 @@
#import "TSStorageManager+keyingMaterial.h"
#import "TSNetworkManager.h"
#import "UIColor+OWS.h"
#import "SCWaveformView.h"
#define AUDIO_BAR_HEIGHT 30;
#define AUDIO_BAR_HEIGHT 36
@interface TSVideoAttachmentAdapter ()
@property UIImage *image;
@property (strong, nonatomic) UIImageView *cachedImageView;
@property (strong, nonatomic) UIImageView *playButton;
@property (strong, nonatomic) UIImageView *videoPlayButton;
@property (strong, nonatomic) CALayer *maskLayer;
@property (strong, nonatomic) FFCircularProgressView *progressView;
@property (strong, nonatomic) TSAttachmentStream *attachment;
@property (strong, nonatomic) UIProgressView *audioProgress;
@property (strong, nonatomic) UIImageView *playPauseButton;
@property (nonatomic) UILabel *durationLabel;
@property (strong, nonatomic) SCWaveformView *waveform;
@property (strong, nonatomic) UIButton *audioPlayPauseButton;
@property (strong, nonatomic) UILabel *durationLabel;
@property (strong, nonatomic) UIView *audioBubble;
@property (nonatomic) BOOL incoming;
@end
@implementation TSVideoAttachmentAdapter
- (instancetype)initWithAttachment:(TSAttachmentStream*)attachment{
- (instancetype)initWithAttachment:(TSAttachmentStream*)attachment incoming:(BOOL)incoming {
self = [super initWithFileURL:[attachment mediaURL] isReadyToPlay:YES];
if (self) {;
@ -42,7 +46,8 @@
_cachedImageView = nil;
_attachmentId = attachment.uniqueId;
_contentType = attachment.contentType;
_attachment = attachment;
_attachment = attachment;
_incoming = incoming;
}
return self;
@ -61,38 +66,40 @@
return [_contentType containsString:@"video/"];
}
-(void) setAudioProgressFromFloat:(float)progress {
[_audioProgress setProgress:progress];
}
-(void) setAudioIconToPause {
[_playPauseButton removeFromSuperview];
_playPauseButton = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"pause_icon"]];
_playPauseButton.frame = CGRectMake(10, 8, 10, 14);
[_audioProgress addSubview:_playPauseButton];
}
-(void) setAudioIconToPlay {
[_playPauseButton removeFromSuperview];
_playPauseButton = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"play_icon"]];
_playPauseButton.frame = CGRectMake(10, 8, 10, 14);
[_audioProgress addSubview:_playPauseButton];
}
-(void) setDurationOfAudio:(NSTimeInterval)duration {
[_durationLabel removeFromSuperview];
-(NSString*)formatDuration:(NSTimeInterval)duration {
double dur = duration;
int minutes = (int) (dur/60);
int seconds = (int) (dur - minutes*60);
NSString *minutes_str = [NSString stringWithFormat:@"%01d", minutes];
NSString *seconds_str = [NSString stringWithFormat:@"%02d", seconds];
NSString *label_text = [NSString stringWithFormat:@"%@:%@", minutes_str, seconds_str];
return label_text;
}
CGSize size = [self mediaViewDisplaySize];
_durationLabel = [[UILabel alloc] initWithFrame:CGRectMake(size.width - 40, 0, 50, 30)];
_durationLabel.text = label_text;
_durationLabel.textColor = [UIColor whiteColor];
[_audioProgress addSubview:_durationLabel];
- (void)setAudioProgressFromFloat:(float)progress {
dispatch_async(dispatch_get_main_queue(), ^{
[_waveform setProgress:progress];
[_waveform generateWaveforms];
[_waveform setNeedsDisplay];
});
}
- (void)resetAudioDuration {
NSError *err;
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:_attachment.mediaURL error:&err];
_durationLabel.text = [self formatDuration:player.duration];
}
- (void)setDurationOfAudio:(NSTimeInterval)duration {
_durationLabel.text = [self formatDuration:duration];
}
- (void)setAudioIconToPlay {
[_audioPlayPauseButton setBackgroundImage:[UIImage imageNamed:@"audio_play_button_blue"] forState:UIControlStateNormal];
}
- (void)setAudioIconToPause {
[_audioPlayPauseButton setBackgroundImage:[UIImage imageNamed:@"audio_pause_button_blue"] forState:UIControlStateNormal];
}
-(void) removeDurationLabel {
@ -113,10 +120,10 @@
[JSQMessagesMediaViewBubbleImageMasker applyBubbleImageMaskToMediaView:imageView isOutgoing:self.appliesMediaViewMaskAsOutgoing];
self.cachedImageView = imageView;
UIImage *img = [UIImage imageNamed:@"play_button"];
_playButton = [[UIImageView alloc] initWithImage:img];
_playButton.frame = CGRectMake((size.width/2)-18, (size.height/2)-18, 37, 37);
[self.cachedImageView addSubview:_playButton];
_playButton.hidden = YES;
_videoPlayButton = [[UIImageView alloc] initWithImage:img];
_videoPlayButton.frame = CGRectMake((size.width/2)-18, (size.height/2)-18, 37, 37);
[self.cachedImageView addSubview:_videoPlayButton];
_videoPlayButton.hidden = YES;
_maskLayer = [CALayer layer];
[_maskLayer setBackgroundColor:[UIColor blackColor].CGColor];
[_maskLayer setOpacity:0.4f];
@ -125,23 +132,60 @@
_progressView = [[FFCircularProgressView alloc] initWithFrame:CGRectMake((size.width/2)-18, (size.height/2)-18, 37, 37)];
[_cachedImageView addSubview:_progressView];
if (_attachment.isDownloaded) {
_playButton.hidden = NO;
_videoPlayButton.hidden = NO;
_maskLayer.hidden = YES;
_progressView.hidden = YES;
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(attachmentUploadProgress:) name:@"attachmentUploadProgress" object:nil];
}
} else if ([self isAudio]) {
UIImageView *backgroundImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, size.width, 30)];
backgroundImage.backgroundColor = [UIColor colorWithRed:189/255.0f green:190/255.0f blue:194/255.0f alpha:1.0f];
//aac files like from android don't play, gotta convert
NSString *convertedFile = [NSString stringWithFormat:@"%@.mp3", _attachment.mediaURL.URLByDeletingPathExtension.absoluteString];
NSError * err = NULL;
NSFileManager *fm = [NSFileManager defaultManager];
[fm moveItemAtURL:_attachment.mediaURL toURL:[NSURL URLWithString:convertedFile] error:&err];
NSURL *url = [NSURL URLWithString:convertedFile];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil];
_waveform = [[SCWaveformView alloc] init];
_waveform.frame = CGRectMake(42.0, 0.0, size.width-84, size.height);
_waveform.asset = asset;
_waveform.progressColor = [UIColor whiteColor];
_waveform.backgroundColor = [UIColor colorWithRed:229/255.0f green:228/255.0f blue:234/255.0f alpha:1.0f];
[_waveform generateWaveforms];
_waveform.progress = 0.0;
_audioBubble = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, size.width, size.height)];
_audioBubble.backgroundColor = [UIColor colorWithRed:10/255.0f green:130/255.0f blue:253/255.0f alpha:1.0f];
_audioBubble.layer.cornerRadius = 18;
_audioBubble.layer.masksToBounds = YES;
_audioProgress = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 0, size.width, 4)];
_playPauseButton = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"play_icon"]];
_playPauseButton.frame = CGRectMake(10, 8, 10, 14);
[_audioProgress addSubview:_playPauseButton];
return _audioProgress;
_audioPlayPauseButton = [[UIButton alloc] initWithFrame:CGRectMake(3, 3, 30, 30)];
[_audioPlayPauseButton setBackgroundImage:[UIImage imageNamed:@"audio_play_button"] forState:UIControlStateNormal];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&err];
_durationLabel = [[UILabel alloc] init];
_durationLabel.text = [self formatDuration:player.duration];
_durationLabel.font = [UIFont systemFontOfSize:14];
[_durationLabel sizeToFit];
_durationLabel.frame = CGRectMake((size.width - _durationLabel.frame.size.width) - 10, _durationLabel.frame.origin.y, _durationLabel.frame.size.width, AUDIO_BAR_HEIGHT);
_durationLabel.backgroundColor = [UIColor clearColor];
_durationLabel.textColor = [UIColor whiteColor];
if (_incoming) {
_audioBubble.backgroundColor = [UIColor colorWithRed:229/255.0f green:228/255.0f blue:234/255.0f alpha:1.0f];
_waveform.normalColor = [UIColor whiteColor];
_waveform.progressColor = [UIColor colorWithRed:107/255.0f green:185/255.0f blue:254/255.0f alpha:1.0f];
[_audioPlayPauseButton setBackgroundImage:[UIImage imageNamed:@"audio_play_button_blue"] forState:UIControlStateNormal];
_durationLabel.textColor = [UIColor darkTextColor];
}
[_audioBubble addSubview:_waveform];
[_audioBubble addSubview:_audioPlayPauseButton];
[_audioBubble addSubview:_durationLabel];
return _audioBubble;
}
return self.cachedImageView;
}
@ -179,7 +223,7 @@
if (progress >= 1) {
_maskLayer.hidden = YES;
_progressView.hidden = YES;
_playButton.hidden = NO;
_videoPlayButton.hidden = NO;
_attachment.isDownloaded = YES;
[[TSMessagesManager sharedManager].dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[_attachment saveWithTransaction:transaction];