animate in progress
This commit is contained in:
parent
aa15c68ff5
commit
3809744d97
|
@ -170,6 +170,7 @@
|
|||
63C5B66A1A82F3EE0011BEA8 /* OTRAudioPlaybackController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63C5B6691A82F3EE0011BEA8 /* OTRAudioPlaybackController.m */; };
|
||||
63D184861A2D3F2400334CD8 /* OTRNotificationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63D184851A2D3F2400334CD8 /* OTRNotificationController.m */; };
|
||||
63D27FC51A6DC51C00EC251A /* OTRMediaItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 63D27FC41A6DC51C00EC251A /* OTRMediaItem.m */; };
|
||||
63D58C261A8C154D003C5A2D /* OTRAudioRecorderViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63D58C251A8C154D003C5A2D /* OTRAudioRecorderViewController.m */; };
|
||||
63D64D661A2FBA8C00E21F77 /* OTRToastOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 63D64D651A2FBA8C00E21F77 /* OTRToastOptions.m */; };
|
||||
63F0FF641A798D8E001F0C99 /* OTRAudioControlsView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63F0FF631A798D8E001F0C99 /* OTRAudioControlsView.m */; };
|
||||
63F6E1911A69B9BA0011E6F7 /* OTRAttachmentPicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 63F6E1901A69B9BA0011E6F7 /* OTRAttachmentPicker.m */; };
|
||||
|
@ -549,6 +550,8 @@
|
|||
63D184851A2D3F2400334CD8 /* OTRNotificationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTRNotificationController.m; sourceTree = "<group>"; };
|
||||
63D27FC31A6DC51C00EC251A /* OTRMediaItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTRMediaItem.h; sourceTree = "<group>"; };
|
||||
63D27FC41A6DC51C00EC251A /* OTRMediaItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTRMediaItem.m; sourceTree = "<group>"; };
|
||||
63D58C241A8C154D003C5A2D /* OTRAudioRecorderViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTRAudioRecorderViewController.h; sourceTree = "<group>"; };
|
||||
63D58C251A8C154D003C5A2D /* OTRAudioRecorderViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTRAudioRecorderViewController.m; sourceTree = "<group>"; };
|
||||
63D64D641A2FBA8C00E21F77 /* OTRToastOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTRToastOptions.h; sourceTree = "<group>"; };
|
||||
63D64D651A2FBA8C00E21F77 /* OTRToastOptions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTRToastOptions.m; sourceTree = "<group>"; };
|
||||
63DC0EB31A1ABC86002C9598 /* OTR_Codesigning.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = OTR_Codesigning.xcconfig; path = configurations/OTR_Codesigning.xcconfig; sourceTree = "<group>"; };
|
||||
|
@ -890,6 +893,8 @@
|
|||
633106331A16D1A300C17BAE /* OTRListSettingViewController.m */,
|
||||
633106341A16D1A300C17BAE /* OTRMessagesViewController.h */,
|
||||
633106351A16D1A300C17BAE /* OTRMessagesViewController.m */,
|
||||
63D58C241A8C154D003C5A2D /* OTRAudioRecorderViewController.h */,
|
||||
63D58C251A8C154D003C5A2D /* OTRAudioRecorderViewController.m */,
|
||||
633106361A16D1A300C17BAE /* OTRNewAccountViewController.h */,
|
||||
633106371A16D1A300C17BAE /* OTRNewAccountViewController.m */,
|
||||
633106381A16D1A300C17BAE /* OTRNewBuddyViewController.h */,
|
||||
|
@ -1362,6 +1367,7 @@
|
|||
63C4BD1C1A1E9BE1001696CD /* OTRvCardAvatar.m in Sources */,
|
||||
63C4BD281A1E9BE1001696CD /* _OTRManagedOscarAccount.m in Sources */,
|
||||
633107031A16D1A300C17BAE /* OTRFingerprintsViewController.m in Sources */,
|
||||
63D58C261A8C154D003C5A2D /* OTRAudioRecorderViewController.m in Sources */,
|
||||
6331068C1A16D1A300C17BAE /* OTRSettingsManager.m in Sources */,
|
||||
6331070C1A16D1A300C17BAE /* OTRQRCodeViewController.m in Sources */,
|
||||
6331067B1A16D1A300C17BAE /* UIImage+ChatSecure.m in Sources */,
|
||||
|
|
|
@ -23,4 +23,6 @@
|
|||
+ (UIColor *)greenNoErrorColor;
|
||||
+ (UIColor *)warnColor;
|
||||
|
||||
+ (UIColor *)defaultBlueColor;
|
||||
|
||||
@end
|
||||
|
|
|
@ -103,4 +103,9 @@
|
|||
return [UIColor colorWithRed:0.94 green:0.77 blue:0 alpha:1];
|
||||
}
|
||||
|
||||
+ (UIColor *)defaultBlueColor
|
||||
{
|
||||
return [UIColor colorWithRed:0.0 green:122.0/255.0 blue:1.0 alpha:1.0];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -39,6 +39,8 @@ typedef NS_ENUM(NSUInteger, OTRBubbleMessageType) {
|
|||
|
||||
+ (UIImage *)wifiWithColor:(UIColor *)color;
|
||||
|
||||
+ (UIImage *)microphoneWithColor:(UIColor *)color size:(CGSize)size;
|
||||
|
||||
+ (UIImage *)imageWithIdentifier:(NSString *)identifier;
|
||||
+ (void)removeImageWithIdentifier:(NSString *)identifier;
|
||||
+ (void)setImage:(UIImage *)image forIdentifier:(NSString *)identifier;
|
||||
|
|
|
@ -22,6 +22,7 @@ NSString *const OTRTwitterImageKey = @"OTRTwitterImageKey";
|
|||
NSString *const OTRCheckmarkImageKey = @"OTRCeckmarkImageKey";
|
||||
NSString *const OTRErrorImageKey = @"OTRErrorImageKey";
|
||||
NSString *const OTRWifiImageKey = @"OTRWifiImageKey";
|
||||
NSString *const OTRMicrophoneImageKey = @"OTRMicrophoneImageKey";
|
||||
|
||||
@implementation OTRImages
|
||||
|
||||
|
@ -458,6 +459,99 @@ NSString *const OTRWifiImageKey = @"OTRWifiImageKey";
|
|||
}];
|
||||
}
|
||||
|
||||
+ (UIImage *)microphoneWithColor:(UIColor *)color size:(CGSize)size
|
||||
{
|
||||
if (!color) {
|
||||
color = [UIColor blackColor];
|
||||
}
|
||||
|
||||
if (CGSizeEqualToSize(size, CGSizeZero)) {
|
||||
size = CGSizeMake(69.232, 100);
|
||||
} else {
|
||||
CGFloat normalRatio = 0.69232;
|
||||
CGFloat ratio = size.width / size.height;
|
||||
if (ratio < 0.69232 ) {
|
||||
size.height = size.width / normalRatio;
|
||||
|
||||
} else {
|
||||
size.width = size.height * normalRatio;
|
||||
}
|
||||
}
|
||||
|
||||
NSString *identifier = [NSString stringWithFormat:@"%@%@",OTRMicrophoneImageKey,[color description]];
|
||||
return [UIImage imageWithIdentifier:identifier forSize:size andDrawingBlock:^{
|
||||
|
||||
CGRect group2 = CGRectMake(0, 0, size.width, size.height);
|
||||
|
||||
|
||||
//// Group 2
|
||||
{
|
||||
//// Bezier Drawing
|
||||
UIBezierPath* bezierPath = UIBezierPath.bezierPath;
|
||||
[bezierPath moveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.49999 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.69230 * CGRectGetHeight(group2))];
|
||||
[bezierPath addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.69616 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.63582 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.57639 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.69230 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.64177 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.67347 * CGRectGetHeight(group2))];
|
||||
[bezierPath addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.77775 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.50000 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.75055 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.59817 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.77775 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.55289 * CGRectGetHeight(group2))];
|
||||
[bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(group2) + 0.77775 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.19231 * CGRectGetHeight(group2))];
|
||||
[bezierPath addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.69616 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.05649 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.77775 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.13942 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.75057 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.09416 * CGRectGetHeight(group2))];
|
||||
[bezierPath addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.49999 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.00000 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.64177 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.01884 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.57639 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.00000 * CGRectGetHeight(group2))];
|
||||
[bezierPath addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.30382 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.05649 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.42360 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.00000 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.35822 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.01884 * CGRectGetHeight(group2))];
|
||||
[bezierPath addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.22222 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.19231 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.24942 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.09415 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.22222 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.13942 * CGRectGetHeight(group2))];
|
||||
[bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(group2) + 0.22222 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.50000 * CGRectGetHeight(group2))];
|
||||
[bezierPath addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.30382 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.63582 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.22222 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.55289 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.24943 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.59817 * CGRectGetHeight(group2))];
|
||||
[bezierPath addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.49999 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.69230 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.35821 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.67347 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.42360 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.69230 * CGRectGetHeight(group2))];
|
||||
[bezierPath closePath];
|
||||
bezierPath.miterLimit = 4;
|
||||
|
||||
[color setFill];
|
||||
[bezierPath fill];
|
||||
|
||||
|
||||
//// Bezier 3 Drawing
|
||||
UIBezierPath* bezier3Path = UIBezierPath.bezierPath;
|
||||
[bezier3Path moveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.98349 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.39603 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.94443 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.38461 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.97251 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.38842 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.95947 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.38461 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.90537 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.39603 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.92938 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.38461 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.91636 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.38842 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.88888 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.42307 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.89437 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.40365 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.88888 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.41266 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addLineToPoint: CGPointMake(CGRectGetMinX(group2) + 0.88888 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.50000 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.77473 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.69020 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.88888 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.57412 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.85082 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.63751 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.49999 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.76923 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.69864 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.74289 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.60706 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.76923 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.22525 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.69020 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.39293 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.76923 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.30136 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.74289 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.11111 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.50000 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.14916 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.63753 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.11111 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.57412 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addLineToPoint: CGPointMake(CGRectGetMinX(group2) + 0.11111 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.42307 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.09462 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.39603 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.11111 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.41266 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.10562 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.40365 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.05556 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.38461 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.08363 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.38842 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.07062 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.38461 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.01649 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.39603 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.04051 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.38461 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.02749 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.38842 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.00000 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.42307 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.00550 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.40365 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.00000 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.41266 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addLineToPoint: CGPointMake(CGRectGetMinX(group2) + 0.00000 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.50000 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.12803 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.73107 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.00000 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.58854 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.04268 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.66557 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.44443 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.84374 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.21338 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.79657 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.31885 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.83413 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addLineToPoint: CGPointMake(CGRectGetMinX(group2) + 0.44443 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.92307 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addLineToPoint: CGPointMake(CGRectGetMinX(group2) + 0.22222 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.92307 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.18316 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.93449 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.20717 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.92307 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.19415 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.92688 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.16666 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.96153 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.17216 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.94210 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.16666 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.95112 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.18316 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.98857 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.16666 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.97194 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.17216 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.98097 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.22222 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 1.00000 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.19415 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.99619 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.20717 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 1.00000 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addLineToPoint: CGPointMake(CGRectGetMinX(group2) + 0.77775 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 1.00000 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.81681 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.98857 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.79280 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 1.00000 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.80584 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.99619 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.83332 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.96153 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.82782 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.98097 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.83332 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.97194 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.81681 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.93449 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.83332 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.95112 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.82782 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.94210 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.77775 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.92307 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.80584 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.92688 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.79280 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.92307 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addLineToPoint: CGPointMake(CGRectGetMinX(group2) + 0.55556 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.92307 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addLineToPoint: CGPointMake(CGRectGetMinX(group2) + 0.55556 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.84374 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.87195 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.73107 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.68112 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.83413 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.78658 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.79657 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 1.00000 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.50000 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 0.95731 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.66557 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 1.00000 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.58854 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addLineToPoint: CGPointMake(CGRectGetMinX(group2) + 1.00000 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.42307 * CGRectGetHeight(group2))];
|
||||
[bezier3Path addCurveToPoint: CGPointMake(CGRectGetMinX(group2) + 0.98349 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.39603 * CGRectGetHeight(group2)) controlPoint1: CGPointMake(CGRectGetMinX(group2) + 1.00000 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.41266 * CGRectGetHeight(group2)) controlPoint2: CGPointMake(CGRectGetMinX(group2) + 0.99449 * CGRectGetWidth(group2), CGRectGetMinY(group2) + 0.40365 * CGRectGetHeight(group2))];
|
||||
[bezier3Path closePath];
|
||||
bezier3Path.miterLimit = 4;
|
||||
|
||||
[color setFill];
|
||||
[bezier3Path fill];
|
||||
}
|
||||
|
||||
}];
|
||||
}
|
||||
|
||||
+ (UIImage *)imageWithIdentifier:(NSString *)identifier
|
||||
{
|
||||
return [[self imageCache] objectForKey:identifier];
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// OTRAudioRecorderViewController.h
|
||||
// ChatSecure
|
||||
//
|
||||
// Created by David Chiles on 2/11/15.
|
||||
// Copyright (c) 2015 Chris Ballinger. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@class OTRBuddy;
|
||||
|
||||
@interface OTRAudioRecorderViewController : UIViewController
|
||||
|
||||
- (instancetype)initWithBuddy:(OTRBuddy *)buddy;
|
||||
|
||||
- (void)showAudioRecorderFromViewController:(UIViewController *)viewController animated:(BOOL)animated fromMicrophoneRectInWindow:(CGRect)rectInWindow;
|
||||
|
||||
|
||||
@end
|
|
@ -0,0 +1,364 @@
|
|||
//
|
||||
// OTRAudioRecorderViewController.m
|
||||
// ChatSecure
|
||||
//
|
||||
// Created by David Chiles on 2/11/15.
|
||||
// Copyright (c) 2015 Chris Ballinger. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OTRAudioRecorderViewController.h"
|
||||
#import "OTRAudioSessionManager.h"
|
||||
#import "OTRBuddy.h"
|
||||
#import "OTRMessage.h"
|
||||
#import "OTRAudioItem.h"
|
||||
#import "PureLayout.h"
|
||||
#import "Strings.h"
|
||||
#import "OTRDatabaseManager.h"
|
||||
#import "OTRUtilities.h"
|
||||
#import "OTRImages.h"
|
||||
#import "BButton.h"
|
||||
#import "OTRColors.h"
|
||||
|
||||
@import AVFoundation;
|
||||
|
||||
NSString *const kOTRAudioRecordAnimatePath = @"kOTRAudioRecordAnimatePath";
|
||||
|
||||
@interface OTRAudioRecorderViewController ()
|
||||
|
||||
@property (nonatomic, strong) OTRBuddy *buddy;
|
||||
@property (nonatomic, strong) OTRAudioSessionManager *audioSessionManager;
|
||||
|
||||
@property (nonatomic) BOOL addedConstraints;
|
||||
|
||||
@property (nonatomic, strong) UIView *microphoneView;
|
||||
@property (nonatomic, strong) UIView *blurredBackgroundView;
|
||||
@property (nonatomic, strong) UIImageView *microphoneImageView;
|
||||
@property (nonatomic, strong) UIButton *sendButton;
|
||||
@property (nonatomic, strong) UIButton *cancelButton;
|
||||
@property (nonatomic, strong) UILabel *timerLabel;
|
||||
|
||||
@property (nonatomic, strong) NSLayoutConstraint *sendButtonBottomConstraint;
|
||||
@property (nonatomic, strong) NSLayoutConstraint *cancelButtonBottomConstraint;
|
||||
|
||||
@property (nonatomic, strong) NSTimer *labelTimer;
|
||||
|
||||
@property (nonatomic) CGFloat microphoneRatio;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OTRAudioRecorderViewController
|
||||
|
||||
- (instancetype) initWithBuddy:(OTRBuddy *)buddy
|
||||
{
|
||||
if (self = [super init]) {
|
||||
self.buddy = buddy;
|
||||
self.audioSessionManager = [[OTRAudioSessionManager alloc] init];
|
||||
self.addedConstraints = NO;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
|
||||
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
|
||||
maskLayer.bounds = CGRectZero;
|
||||
[maskLayer setFillColor:[[UIColor blackColor] CGColor]];
|
||||
self.blurredBackgroundView.layer.mask = maskLayer;
|
||||
self.blurredBackgroundView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
|
||||
|
||||
self.microphoneView = [[UIView alloc] initWithFrame:CGRectZero];
|
||||
self.microphoneView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
|
||||
|
||||
UIColor *microphoneColor = [OTRColors defaultBlueColor];
|
||||
UIImage *microphoneImage = [OTRImages microphoneWithColor:microphoneColor size:CGSizeMake(CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds))];
|
||||
self.microphoneRatio = microphoneImage.size.width / microphoneImage.size.height;
|
||||
self.microphoneImageView = [[UIImageView alloc] initWithImage:microphoneImage];
|
||||
self.microphoneView.contentMode = UIViewContentModeScaleAspectFit;
|
||||
self.microphoneImageView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
|
||||
self.sendButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
self.sendButton.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[self.sendButton setTitle:@"Send" forState:UIControlStateNormal];
|
||||
[self.sendButton addTarget:self action:@selector(didPressSend:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
self.cancelButton = [[BButton alloc] initWithFrame:CGRectZero type:BButtonTypeDefault style:BButtonStyleBootstrapV3 icon:FATimes fontSize:12.0];
|
||||
self.cancelButton.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[self.cancelButton addTarget:self action:@selector(didPressCancel:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
self.timerLabel = [[UILabel alloc] initForAutoLayout];
|
||||
self.timerLabel.textColor = [UIColor whiteColor];
|
||||
self.timerLabel.numberOfLines = 1;
|
||||
self.timerLabel.minimumScaleFactor = 0.5;
|
||||
self.timerLabel.adjustsFontSizeToFitWidth = YES;
|
||||
self.timerLabel.textAlignment = NSTextAlignmentCenter;
|
||||
|
||||
[self.view addSubview:self.blurredBackgroundView];
|
||||
[self.view addSubview:self.microphoneView];
|
||||
[self.microphoneView addSubview:self.microphoneImageView];
|
||||
[self.microphoneView addSubview:self.timerLabel];
|
||||
[self.view addSubview:self.sendButton];
|
||||
[self.view addSubview:self.cancelButton];
|
||||
|
||||
[self.view setNeedsUpdateConstraints];
|
||||
|
||||
self.view.backgroundColor = [UIColor clearColor];
|
||||
}
|
||||
|
||||
#pragma - mark Presentation Methods
|
||||
|
||||
- (void)showAudioRecorderFromViewController:(UIViewController *)viewController animated:(BOOL)animated fromMicrophoneRectInWindow:(CGRect)rectInWindow
|
||||
{
|
||||
//Pressenting ViewController on top of another http://www.raywenderlich.com/forums/viewtopic.php?f=2&t=18661
|
||||
self.providesPresentationContextTransitionStyle = YES;
|
||||
self.modalPresentationStyle = UIModalPresentationOverCurrentContext;
|
||||
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
|
||||
self.modalPresentationCapturesStatusBarAppearance = UIModalPresentationOverCurrentContext;
|
||||
} else {
|
||||
self.modalPresentationStyle = UIModalPresentationCurrentContext;
|
||||
}
|
||||
|
||||
[viewController presentViewController:self animated:NO completion:^{
|
||||
//Animate microphon
|
||||
if (!animated) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
CGRect referenceFrameInMyView = [self.view convertRect:rectInWindow fromView:nil];
|
||||
self.microphoneView.frame = referenceFrameInMyView;
|
||||
|
||||
|
||||
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
|
||||
maskLayer.bounds = self.blurredBackgroundView.bounds;
|
||||
maskLayer.anchorPoint = CGPointMake(0, 0);
|
||||
CGFloat maxDimension = MAX(CGRectGetWidth(referenceFrameInMyView), CGRectGetHeight(referenceFrameInMyView));
|
||||
CGRect circleRect = referenceFrameInMyView;
|
||||
circleRect.size.height = maxDimension;
|
||||
circleRect.size.width = maxDimension;
|
||||
maskLayer.path = [UIBezierPath bezierPathWithOvalInRect:circleRect].CGPath;
|
||||
|
||||
self.blurredBackgroundView.layer.mask = maskLayer;
|
||||
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
NSTimeInterval duration = 0.5;
|
||||
|
||||
CGPathRef oldPath = maskLayer.path;
|
||||
CGFloat maxDimension = MAX(CGRectGetHeight(self.view.bounds), CGRectGetWidth(self.view.bounds));
|
||||
//Calculate square rect that is bounded by max dimension with same center point
|
||||
CGRect squareRect = CGRectInset(self.view.bounds, (CGRectGetWidth(self.view.bounds) - maxDimension)/2, (CGRectGetHeight(self.view.bounds)- maxDimension)/2);
|
||||
//Expand circle to twice the max dimension to cover entire view once done animating but still centered
|
||||
CGRect newCircleRect = CGRectInset(squareRect, -0.5 * maxDimension, -0.5 * maxDimension);
|
||||
CGPathRef newPath = [UIBezierPath bezierPathWithOvalInRect:newCircleRect].CGPath;
|
||||
|
||||
CABasicAnimation* revealAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
|
||||
revealAnimation.fromValue = (__bridge id)(oldPath);
|
||||
revealAnimation.toValue = (__bridge id)(newPath);
|
||||
revealAnimation.duration = duration;
|
||||
|
||||
[self.blurredBackgroundView.layer.mask addAnimation:revealAnimation forKey:kOTRAudioRecordAnimatePath];
|
||||
|
||||
((CAShapeLayer *)self.blurredBackgroundView.layer.mask).path = newPath;
|
||||
|
||||
[UIView animateWithDuration:duration animations:^{
|
||||
|
||||
self.microphoneView.frame = CGRectMake(0, 0, 100, 100);
|
||||
self.microphoneView.center = self.view.center;
|
||||
[self.view layoutIfNeeded];
|
||||
} completion:^(BOOL finished) {
|
||||
//Start recording once the microphone icon is presented
|
||||
if (!self.audioSessionManager.isRecording) {
|
||||
[self startRecording];
|
||||
}
|
||||
[UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.8 initialSpringVelocity:10 options:0 animations:^{
|
||||
[self.sendButtonBottomConstraint autoRemove];
|
||||
[self.cancelButtonBottomConstraint autoRemove];
|
||||
[self.view layoutIfNeeded];
|
||||
} completion:nil];
|
||||
}];
|
||||
});
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma - mark Private Methods
|
||||
|
||||
- (UIView *)blurredBackgroundView {
|
||||
if (!_blurredBackgroundView) {
|
||||
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
|
||||
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
|
||||
_blurredBackgroundView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
|
||||
} else {
|
||||
UIToolbar *toolbar = [[UIToolbar alloc] init];
|
||||
toolbar.barStyle = UIBarStyleDefault;
|
||||
_blurredBackgroundView = toolbar;
|
||||
}
|
||||
}
|
||||
return _blurredBackgroundView;
|
||||
}
|
||||
|
||||
- (void)updateTime:(id)sender
|
||||
{
|
||||
NSTimeInterval time = [self.audioSessionManager currentTimeRecordTime];
|
||||
time = round(time);
|
||||
NSUInteger minutes = (int)time / 60;
|
||||
NSUInteger seconds = (int)time % 60;
|
||||
|
||||
self.timerLabel.text = [NSString stringWithFormat:@"%lu:%02ld",(unsigned long)minutes,seconds];
|
||||
}
|
||||
|
||||
- (void)animateAwayViewsWithDuration:(NSTimeInterval)duration completion:(void (^)(BOOL finished))completion
|
||||
{
|
||||
CAShapeLayer *maskLayer = (CAShapeLayer *)self.blurredBackgroundView.layer.mask;
|
||||
CGPathRef oldPath = maskLayer.path;
|
||||
//Calculate new rect with same center but only 1 x 1
|
||||
CGRect newCircleRect = CGRectMake(CGRectGetMidX(self.view.bounds)-1, CGRectGetMidY(self.view.bounds)-1, 1, 1);
|
||||
CGPathRef newPath = [UIBezierPath bezierPathWithOvalInRect:newCircleRect].CGPath;
|
||||
|
||||
CABasicAnimation* revealAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
|
||||
revealAnimation.fromValue = (__bridge id)(oldPath);
|
||||
revealAnimation.toValue = (__bridge id)(newPath);
|
||||
revealAnimation.duration = duration;
|
||||
|
||||
[self.blurredBackgroundView.layer.mask addAnimation:revealAnimation forKey:kOTRAudioRecordAnimatePath];
|
||||
|
||||
((CAShapeLayer *)self.blurredBackgroundView.layer.mask).path = newPath;
|
||||
|
||||
[UIView animateWithDuration:duration animations:^{
|
||||
self.microphoneView.frame = CGRectMake(0, 0, 0, 0);
|
||||
self.microphoneView.center = self.view.center;
|
||||
[self.cancelButton removeFromSuperview];
|
||||
[self.view layoutIfNeeded];
|
||||
} completion:completion];
|
||||
}
|
||||
|
||||
- (void)startRecording
|
||||
{
|
||||
NSString *temporaryPath = NSTemporaryDirectory();
|
||||
NSString *fileName = [NSString stringWithFormat:@"%@.m4a",[[NSUUID UUID] UUIDString]];
|
||||
NSURL *url = [NSURL fileURLWithPath:[temporaryPath stringByAppendingPathComponent:fileName]];
|
||||
[self.audioSessionManager recordAudioToURL:url error:nil];
|
||||
[self.labelTimer invalidate];
|
||||
[self updateTime:nil];
|
||||
self.labelTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateTime:) userInfo:nil repeats:YES];
|
||||
}
|
||||
|
||||
- (void)stopRecording
|
||||
{
|
||||
[self.labelTimer invalidate];
|
||||
self.labelTimer = nil;
|
||||
[self updateTime:nil];
|
||||
__block NSURL *url = [self.audioSessionManager currentRecorderURL];
|
||||
[self.audioSessionManager stopRecording];
|
||||
|
||||
__block NSString *buddyUniqueId = self.buddy.uniqueId;
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
OTRMessage *message = [[OTRMessage alloc] init];
|
||||
message.incoming = NO;
|
||||
message.buddyUniqueId = buddyUniqueId;
|
||||
|
||||
OTRAudioItem *audioItem = [[OTRAudioItem alloc] init];
|
||||
audioItem.isIncoming = message.incoming;
|
||||
audioItem.filename = [[url absoluteString] lastPathComponent];
|
||||
|
||||
AVAsset *audioAsset = [AVAsset assetWithURL:url];
|
||||
audioItem.timeLength = CMTimeGetSeconds(audioAsset.duration);
|
||||
|
||||
message.mediaItemUniqueId = audioItem.uniqueId;
|
||||
|
||||
[[OTRDatabaseManager sharedInstance].readWriteDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
[audioItem saveWithTransaction:transaction];
|
||||
[message saveWithTransaction:transaction];
|
||||
}];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)removeFile:(NSURL *)url
|
||||
{
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:url.path]) {
|
||||
|
||||
[[NSFileManager defaultManager] removeItemAtURL:url error:nil];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma - mark AutoLayout
|
||||
- (void)updateViewConstraints
|
||||
{
|
||||
if (!self.addedConstraints) {
|
||||
|
||||
[self.blurredBackgroundView autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsZero];
|
||||
|
||||
[self.timerLabel autoAlignAxis:ALAxisVertical toSameAxisOfView:self.microphoneImageView];
|
||||
// The numbers .68 and .56 were calculated from the original svg to find the center of the microphone
|
||||
[self.timerLabel autoConstrainAttribute:ALAttributeHorizontal toAttribute:ALAttributeHorizontal ofView:self.microphoneImageView withMultiplier:0.68];
|
||||
[self.timerLabel autoMatchDimension:ALDimensionWidth toDimension:ALDimensionWidth ofView:self.microphoneImageView withMultiplier:0.56];
|
||||
|
||||
[self.microphoneImageView autoMatchDimension:ALDimensionHeight toDimension:ALDimensionHeight ofView:self.microphoneImageView.superview];
|
||||
[self.microphoneImageView autoMatchDimension:ALDimensionWidth toDimension:ALDimensionHeight ofView:self.microphoneImageView withMultiplier:self.microphoneRatio];
|
||||
[self.microphoneImageView autoCenterInSuperview];
|
||||
|
||||
[self.cancelButton autoPinEdgeToSuperviewEdge:ALEdgeLeading withInset:5];
|
||||
[UIView autoSetPriority:UILayoutPriorityDefaultLow forConstraints:^{
|
||||
[self.cancelButton autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:5];
|
||||
}];
|
||||
|
||||
[self.cancelButton autoSetDimension:ALDimensionHeight toSize:30];
|
||||
[self.cancelButton autoMatchDimension:ALDimensionWidth toDimension:ALDimensionHeight ofView:self.cancelButton];
|
||||
|
||||
[self.sendButton autoAlignAxis:ALAxisVertical toSameAxisOfView:self.microphoneView];
|
||||
[UIView autoSetPriority:UILayoutPriorityDefaultLow forConstraints:^{
|
||||
[self.sendButton autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.microphoneView];
|
||||
}];
|
||||
[self.sendButton autoSetDimension:ALDimensionHeight toSize:35];
|
||||
[self.sendButton autoMatchDimension:ALDimensionWidth toDimension:ALDimensionWidth ofView:self.microphoneView];
|
||||
|
||||
if (!self.sendButtonBottomConstraint) {
|
||||
self.sendButtonBottomConstraint = [NSLayoutConstraint constraintWithItem:self.sendButton attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:5];
|
||||
[self.view addConstraint:self.sendButtonBottomConstraint];
|
||||
}
|
||||
|
||||
if (!self.cancelButtonBottomConstraint) {
|
||||
self.cancelButtonBottomConstraint = [NSLayoutConstraint constraintWithItem:self.cancelButton attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:5];
|
||||
[self.view addConstraint:self.cancelButtonBottomConstraint];
|
||||
}
|
||||
|
||||
self.addedConstraints = YES;
|
||||
}
|
||||
[super updateViewConstraints];
|
||||
}
|
||||
|
||||
#pragma - mark Button Methods
|
||||
|
||||
- (void)didPressCancel:(id)sender
|
||||
{
|
||||
if (self.audioSessionManager.isRecording) {
|
||||
//Cancel
|
||||
NSURL *currentURL = [self.audioSessionManager currentRecorderURL];
|
||||
[self.audioSessionManager stopRecording];
|
||||
[self removeFile:currentURL];
|
||||
}
|
||||
|
||||
//Animate away the views
|
||||
[self animateAwayViewsWithDuration:0.5 completion:^(BOOL finished) {
|
||||
[self dismissViewControllerAnimated:NO completion:nil];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)didPressSend:(id)sender
|
||||
{
|
||||
if (self.audioSessionManager.isRecording) {
|
||||
[self stopRecording];
|
||||
}
|
||||
[self animateAwayViewsWithDuration:0.5 completion:^(BOOL finished) {
|
||||
[self dismissViewControllerAnimated:NO completion:nil];
|
||||
}];
|
||||
|
||||
}
|
||||
|
||||
@end
|
|
@ -42,6 +42,7 @@
|
|||
#import "OTRAudioControlsView.h"
|
||||
#import "OTRPlayPauseProgressView.h"
|
||||
#import "OTRAudioPlaybackController.h"
|
||||
#import "OTRAudioRecorderViewController.h"
|
||||
|
||||
@import AVFoundation;
|
||||
@import MediaPlayer;
|
||||
|
@ -752,6 +753,7 @@ typedef NS_ENUM(int, OTRDropDownType) {
|
|||
UIView *cellContainterView = ((JSQMessagesCollectionViewCell *)cell).messageBubbleContainerView;
|
||||
imageInfo.referenceRect = cellContainterView.bounds;
|
||||
imageInfo.referenceView = cellContainterView;
|
||||
imageInfo.referenceCornerRadius = 5;
|
||||
}
|
||||
|
||||
JTSImageViewController *imageViewer = [[JTSImageViewController alloc]
|
||||
|
@ -848,45 +850,18 @@ typedef NS_ENUM(int, OTRDropDownType) {
|
|||
|
||||
- (void)didPressSendButton:(UIButton *)button withMessageText:(NSString *)text senderId:(NSString *)senderId senderDisplayName:(NSString *)senderDisplayName date:(NSDate *)date
|
||||
{
|
||||
self.navigationController.providesPresentationContextTransitionStyle = YES;
|
||||
self.navigationController.definesPresentationContext = YES;
|
||||
OTRAudioRecorderViewController *recorderViewController = [[OTRAudioRecorderViewController alloc] initWithBuddy:self.buddy];
|
||||
CGRect rectInWindow = [self.microphoneButton convertRect:self.microphoneButton.frame toView:nil];
|
||||
[recorderViewController showAudioRecorderFromViewController:self animated:YES fromMicrophoneRectInWindow:rectInWindow];
|
||||
if ([[OTRProtocolManager sharedInstance] isAccountConnected:self.account]) {
|
||||
//Account is connected
|
||||
|
||||
if ([button isEqual:self.microphoneButton]) {
|
||||
//FIXME where should audio be saved
|
||||
if (self.audioSessionManager.isRecording) {
|
||||
__block NSURL *url = [self.audioSessionManager currentRecorderURL];
|
||||
[self.audioSessionManager stopRecording];
|
||||
|
||||
__weak typeof(self)weakSelf = self;
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
__strong typeof(weakSelf)strongSelf = weakSelf;
|
||||
OTRMessage *message = [[OTRMessage alloc] init];
|
||||
message.incoming = NO;
|
||||
message.buddyUniqueId = strongSelf.buddy.uniqueId;
|
||||
|
||||
OTRAudioItem *audioItem = [[OTRAudioItem alloc] init];
|
||||
audioItem.isIncoming = message.incoming;
|
||||
audioItem.filename = [[url absoluteString] lastPathComponent];
|
||||
|
||||
AVAsset *audioAsset = [AVAsset assetWithURL:url];
|
||||
audioItem.timeLength = CMTimeGetSeconds(audioAsset.duration);
|
||||
|
||||
message.mediaItemUniqueId = audioItem.uniqueId;
|
||||
|
||||
[[OTRDatabaseManager sharedInstance].readWriteDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
[audioItem saveWithTransaction:transaction];
|
||||
[message saveWithTransaction:transaction];
|
||||
}];
|
||||
});
|
||||
|
||||
|
||||
} else {
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
NSString *documentsPath = [paths firstObject];
|
||||
NSString *fileName = [NSString stringWithFormat:@"%@.m4a",[[NSUUID UUID] UUIDString]];
|
||||
NSURL *url = [NSURL fileURLWithPath:[documentsPath stringByAppendingPathComponent:fileName]];
|
||||
[self.audioSessionManager recordAudioToURL:url error:nil];
|
||||
}
|
||||
|
||||
OTRAudioRecorderViewController *recorderViewController = [[OTRAudioRecorderViewController alloc] initWithBuddy:self.buddy];
|
||||
//[recorderViewController showAudioRecorderFromViewController:self];
|
||||
|
||||
} else {
|
||||
OTRMessage *message = [[OTRMessage alloc] init];
|
||||
|
@ -1222,9 +1197,6 @@ heightForCellBottomLabelAtIndexPath:(NSIndexPath *)indexPath
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
[self.collectionView reloadData];
|
||||
|
||||
if (messageRowChanges.count && [self.collectionView numberOfItemsInSection:0] != 0) {
|
||||
NSUInteger lastMessageIndex = [self.collectionView numberOfItemsInSection:0] - 1;
|
||||
NSIndexPath *lastMessageIndexPath = [NSIndexPath indexPathForRow:lastMessageIndex inSection:0];
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="216px" height="146px" viewBox="0 0 216 146" enable-background="new 0 0 216 146" xml:space="preserve">
|
||||
<g>
|
||||
<path d="M108,99.07c7.17,0,13.307-2.553,18.412-7.657S134.07,80.17,134.07,73V31.286c0-7.17-2.551-13.307-7.658-18.413
|
||||
C121.307,7.768,115.17,5.214,108,5.214s-13.307,2.554-18.413,7.659s-7.659,11.243-7.659,18.413V73
|
||||
c0,7.17,2.554,13.309,7.659,18.413S100.83,99.07,108,99.07z"/>
|
||||
<path d="M153.38,58.905c-1.03-1.032-2.254-1.548-3.666-1.548s-2.634,0.516-3.666,1.548c-1.032,1.032-1.548,2.254-1.548,3.666V73
|
||||
c0,10.049-3.572,18.643-10.714,25.786C126.645,105.929,118.049,109.5,108,109.5s-18.644-3.571-25.787-10.714
|
||||
C75.071,91.645,71.5,83.049,71.5,73V62.571c0-1.412-0.516-2.634-1.548-3.666c-1.032-1.032-2.253-1.548-3.666-1.548
|
||||
s-2.635,0.516-3.667,1.548c-1.032,1.032-1.548,2.254-1.548,3.666V73c0,12.004,4.006,22.446,12.017,31.326
|
||||
c8.011,8.88,17.91,13.972,29.697,15.275v10.756H81.928c-1.412,0-2.634,0.516-3.666,1.548c-1.032,1.032-1.548,2.254-1.548,3.666
|
||||
c0,1.411,0.516,2.635,1.548,3.666c1.032,1.032,2.254,1.549,3.666,1.549h52.142c1.412,0,2.636-0.517,3.666-1.549
|
||||
c1.033-1.031,1.55-2.255,1.55-3.666c0-1.412-0.517-2.634-1.55-3.666c-1.03-1.032-2.254-1.548-3.666-1.548h-20.855v-10.756
|
||||
c11.785-1.303,21.684-6.395,29.696-15.275c8.012-8.88,12.019-19.322,12.019-31.326V62.571
|
||||
C154.93,61.159,154.413,59.938,153.38,58.905z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
Loading…
Reference in New Issue