mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Add progress & disable media views while uploading attachments.
// FREEBIE
This commit is contained in:
parent
3dc7f2528f
commit
9ae047a1da
|
@ -12,6 +12,8 @@
|
||||||
34330A5A1E7875FB00DF2FB9 /* fontawesome-webfont.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 34330A591E7875FB00DF2FB9 /* fontawesome-webfont.ttf */; };
|
34330A5A1E7875FB00DF2FB9 /* fontawesome-webfont.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 34330A591E7875FB00DF2FB9 /* fontawesome-webfont.ttf */; };
|
||||||
34330A5C1E787A9800DF2FB9 /* dripicons-v2.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 34330A5B1E787A9800DF2FB9 /* dripicons-v2.ttf */; };
|
34330A5C1E787A9800DF2FB9 /* dripicons-v2.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 34330A5B1E787A9800DF2FB9 /* dripicons-v2.ttf */; };
|
||||||
34330A5E1E787BD800DF2FB9 /* ElegantIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 34330A5D1E787BD800DF2FB9 /* ElegantIcons.ttf */; };
|
34330A5E1E787BD800DF2FB9 /* ElegantIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 34330A5D1E787BD800DF2FB9 /* ElegantIcons.ttf */; };
|
||||||
|
34330A611E788EA900DF2FB9 /* AttachmentUploadView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34330A601E788EA900DF2FB9 /* AttachmentUploadView.m */; };
|
||||||
|
34330AA31E79686200DF2FB9 /* OWSProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34330AA21E79686200DF2FB9 /* OWSProgressView.m */; };
|
||||||
344F2F671E57A932000D9322 /* UIViewController+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 344F2F661E57A932000D9322 /* UIViewController+OWS.m */; };
|
344F2F671E57A932000D9322 /* UIViewController+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 344F2F661E57A932000D9322 /* UIViewController+OWS.m */; };
|
||||||
34535D821E256BE9008A4747 /* UIView+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 34535D811E256BE9008A4747 /* UIView+OWS.m */; };
|
34535D821E256BE9008A4747 /* UIView+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 34535D811E256BE9008A4747 /* UIView+OWS.m */; };
|
||||||
348A08421E6A044E0057E290 /* MessagesViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 348A08411E6A044E0057E290 /* MessagesViewController.xib */; };
|
348A08421E6A044E0057E290 /* MessagesViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 348A08411E6A044E0057E290 /* MessagesViewController.xib */; };
|
||||||
|
@ -631,6 +633,10 @@
|
||||||
34330A591E7875FB00DF2FB9 /* fontawesome-webfont.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "fontawesome-webfont.ttf"; sourceTree = "<group>"; };
|
34330A591E7875FB00DF2FB9 /* fontawesome-webfont.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "fontawesome-webfont.ttf"; sourceTree = "<group>"; };
|
||||||
34330A5B1E787A9800DF2FB9 /* dripicons-v2.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "dripicons-v2.ttf"; sourceTree = "<group>"; };
|
34330A5B1E787A9800DF2FB9 /* dripicons-v2.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "dripicons-v2.ttf"; sourceTree = "<group>"; };
|
||||||
34330A5D1E787BD800DF2FB9 /* ElegantIcons.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = ElegantIcons.ttf; sourceTree = "<group>"; };
|
34330A5D1E787BD800DF2FB9 /* ElegantIcons.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = ElegantIcons.ttf; sourceTree = "<group>"; };
|
||||||
|
34330A5F1E788EA900DF2FB9 /* AttachmentUploadView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AttachmentUploadView.h; sourceTree = "<group>"; };
|
||||||
|
34330A601E788EA900DF2FB9 /* AttachmentUploadView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AttachmentUploadView.m; sourceTree = "<group>"; };
|
||||||
|
34330AA11E79686200DF2FB9 /* OWSProgressView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSProgressView.h; sourceTree = "<group>"; };
|
||||||
|
34330AA21E79686200DF2FB9 /* OWSProgressView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSProgressView.m; sourceTree = "<group>"; };
|
||||||
344F2F651E57A932000D9322 /* UIViewController+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIViewController+OWS.h"; path = "util/UIViewController+OWS.h"; sourceTree = "<group>"; };
|
344F2F651E57A932000D9322 /* UIViewController+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIViewController+OWS.h"; path = "util/UIViewController+OWS.h"; sourceTree = "<group>"; };
|
||||||
344F2F661E57A932000D9322 /* UIViewController+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIViewController+OWS.m"; path = "util/UIViewController+OWS.m"; sourceTree = "<group>"; };
|
344F2F661E57A932000D9322 /* UIViewController+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIViewController+OWS.m"; path = "util/UIViewController+OWS.m"; sourceTree = "<group>"; };
|
||||||
34535D801E256BE9008A4747 /* UIView+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+OWS.h"; sourceTree = "<group>"; };
|
34535D801E256BE9008A4747 /* UIView+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+OWS.h"; sourceTree = "<group>"; };
|
||||||
|
@ -2105,38 +2111,40 @@
|
||||||
76EB052B18170B33006006FC /* Views */ = {
|
76EB052B18170B33006006FC /* Views */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
45F3AEB51DFDE7900080CE33 /* AvatarImageView.swift */,
|
||||||
|
451764291DE939FD00EDB8B9 /* ContactCell.swift */,
|
||||||
|
451764281DE939FD00EDB8B9 /* ContactCell.xib */,
|
||||||
|
76EB052E18170B33006006FC /* ContactTableViewCell.h */,
|
||||||
|
76EB052F18170B33006006FC /* ContactTableViewCell.m */,
|
||||||
|
A5509ECB1A69B1D600ABA4BC /* CountryCodeTableViewCell.h */,
|
||||||
|
A5509ECC1A69B1D600ABA4BC /* CountryCodeTableViewCell.m */,
|
||||||
45B201751DAECBFE00C461E0 /* HighlightableLabel.swift */,
|
45B201751DAECBFE00C461E0 /* HighlightableLabel.swift */,
|
||||||
45C681C11D305C9E0050903A /* OWSDisplayedMessageCollectionViewCell.h */,
|
FCAC963D19FEF99A0046DFC5 /* InboxTableViewCell.h */,
|
||||||
45C681C21D305C9E0050903A /* OWSDisplayedMessageCollectionViewCell.m */,
|
FCAC963E19FEF99A0046DFC5 /* InboxTableViewCell.m */,
|
||||||
45C681C31D305C9E0050903A /* OWSDisplayedMessageCollectionViewCell.xib */,
|
4531C9C21DD8E6D800F08304 /* JSQMessagesCollectionViewCell+OWS.h */,
|
||||||
|
4531C9C31DD8E6D800F08304 /* JSQMessagesCollectionViewCell+OWS.m */,
|
||||||
|
45E1F3A41DEF20A100852CF1 /* NoSignalContactsView.swift */,
|
||||||
|
45E1F3A21DEF1DF000852CF1 /* NoSignalContactsView.xib */,
|
||||||
45C681B91D305C080050903A /* OWSCallCollectionViewCell.h */,
|
45C681B91D305C080050903A /* OWSCallCollectionViewCell.h */,
|
||||||
45C681BA1D305C080050903A /* OWSCallCollectionViewCell.m */,
|
45C681BA1D305C080050903A /* OWSCallCollectionViewCell.m */,
|
||||||
45C681C01D305C9E0050903A /* OWSCallCollectionViewCell.xib */,
|
45C681C01D305C9E0050903A /* OWSCallCollectionViewCell.xib */,
|
||||||
|
459311FA1D75C948008DD4F0 /* OWSDeviceTableViewCell.h */,
|
||||||
|
459311FB1D75C948008DD4F0 /* OWSDeviceTableViewCell.m */,
|
||||||
|
45C681C11D305C9E0050903A /* OWSDisplayedMessageCollectionViewCell.h */,
|
||||||
|
45C681C21D305C9E0050903A /* OWSDisplayedMessageCollectionViewCell.m */,
|
||||||
|
45C681C31D305C9E0050903A /* OWSDisplayedMessageCollectionViewCell.xib */,
|
||||||
|
450873C91D9D86F4006B54F2 /* OWSExpirableMessageView.h */,
|
||||||
|
450873C11D9D5149006B54F2 /* OWSExpirationTimerView.h */,
|
||||||
|
450873C21D9D5149006B54F2 /* OWSExpirationTimerView.m */,
|
||||||
450873C51D9D867B006B54F2 /* OWSIncomingMessageCollectionViewCell.h */,
|
450873C51D9D867B006B54F2 /* OWSIncomingMessageCollectionViewCell.h */,
|
||||||
450873C61D9D867B006B54F2 /* OWSIncomingMessageCollectionViewCell.m */,
|
450873C61D9D867B006B54F2 /* OWSIncomingMessageCollectionViewCell.m */,
|
||||||
45F2B1951D9CA207000D2C69 /* OWSIncomingMessageCollectionViewCell.xib */,
|
45F2B1951D9CA207000D2C69 /* OWSIncomingMessageCollectionViewCell.xib */,
|
||||||
45F2B1921D9C9F48000D2C69 /* OWSOutgoingMessageCollectionViewCell.h */,
|
45F2B1921D9C9F48000D2C69 /* OWSOutgoingMessageCollectionViewCell.h */,
|
||||||
45F2B1931D9C9F48000D2C69 /* OWSOutgoingMessageCollectionViewCell.m */,
|
45F2B1931D9C9F48000D2C69 /* OWSOutgoingMessageCollectionViewCell.m */,
|
||||||
45F2B1961D9CA207000D2C69 /* OWSOutgoingMessageCollectionViewCell.xib */,
|
45F2B1961D9CA207000D2C69 /* OWSOutgoingMessageCollectionViewCell.xib */,
|
||||||
A5509ECB1A69B1D600ABA4BC /* CountryCodeTableViewCell.h */,
|
34330AA11E79686200DF2FB9 /* OWSProgressView.h */,
|
||||||
A5509ECC1A69B1D600ABA4BC /* CountryCodeTableViewCell.m */,
|
34330AA21E79686200DF2FB9 /* OWSProgressView.m */,
|
||||||
FCAC963D19FEF99A0046DFC5 /* InboxTableViewCell.h */,
|
|
||||||
FCAC963E19FEF99A0046DFC5 /* InboxTableViewCell.m */,
|
|
||||||
76EB052E18170B33006006FC /* ContactTableViewCell.h */,
|
|
||||||
76EB052F18170B33006006FC /* ContactTableViewCell.m */,
|
|
||||||
451764291DE939FD00EDB8B9 /* ContactCell.swift */,
|
|
||||||
451764281DE939FD00EDB8B9 /* ContactCell.xib */,
|
|
||||||
76EB053818170B33006006FC /* xibs */,
|
76EB053818170B33006006FC /* xibs */,
|
||||||
459311FA1D75C948008DD4F0 /* OWSDeviceTableViewCell.h */,
|
|
||||||
459311FB1D75C948008DD4F0 /* OWSDeviceTableViewCell.m */,
|
|
||||||
450873C11D9D5149006B54F2 /* OWSExpirationTimerView.h */,
|
|
||||||
450873C21D9D5149006B54F2 /* OWSExpirationTimerView.m */,
|
|
||||||
450873C91D9D86F4006B54F2 /* OWSExpirableMessageView.h */,
|
|
||||||
4531C9C21DD8E6D800F08304 /* JSQMessagesCollectionViewCell+OWS.h */,
|
|
||||||
4531C9C31DD8E6D800F08304 /* JSQMessagesCollectionViewCell+OWS.m */,
|
|
||||||
45E1F3A21DEF1DF000852CF1 /* NoSignalContactsView.xib */,
|
|
||||||
45E1F3A41DEF20A100852CF1 /* NoSignalContactsView.swift */,
|
|
||||||
45F3AEB51DFDE7900080CE33 /* AvatarImageView.swift */,
|
|
||||||
);
|
);
|
||||||
name = Views;
|
name = Views;
|
||||||
path = views;
|
path = views;
|
||||||
|
@ -2173,19 +2181,21 @@
|
||||||
B62D53F41A23CC8B009AAF82 /* TSMessageAdapters */ = {
|
B62D53F41A23CC8B009AAF82 /* TSMessageAdapters */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
A5E9D4BA1A65FAD800E4481C /* TSVideoAttachmentAdapter.h */,
|
34330A5F1E788EA900DF2FB9 /* AttachmentUploadView.h */,
|
||||||
A5E9D4B91A65FAD800E4481C /* TSVideoAttachmentAdapter.m */,
|
34330A601E788EA900DF2FB9 /* AttachmentUploadView.m */,
|
||||||
B6A3EB491A423B3800B2236B /* TSPhotoAdapter.h */,
|
|
||||||
B6A3EB4A1A423B3800B2236B /* TSPhotoAdapter.m */,
|
|
||||||
4CE0E3751B95453C007210CF /* TSAnimatedAdapter.h */,
|
|
||||||
4CE0E3761B954546007210CF /* TSAnimatedAdapter.m */,
|
|
||||||
B62D53F51A23CCAD009AAF82 /* TSMessageAdapter.h */,
|
|
||||||
B62D53F61A23CCAD009AAF82 /* TSMessageAdapter.m */,
|
|
||||||
B6D3CBCE1C1376BE00C039DF /* TSContentAdapters.h */,
|
|
||||||
341BB7471DB727EE001E2975 /* JSQMediaItem+OWS.h */,
|
341BB7471DB727EE001E2975 /* JSQMediaItem+OWS.h */,
|
||||||
341BB7481DB727EE001E2975 /* JSQMediaItem+OWS.m */,
|
341BB7481DB727EE001E2975 /* JSQMediaItem+OWS.m */,
|
||||||
4526BD481CA61C8D00166BC8 /* OWSMessageEditing.h */,
|
|
||||||
45666ECE1D995B94008FE134 /* OWSMessageData.h */,
|
45666ECE1D995B94008FE134 /* OWSMessageData.h */,
|
||||||
|
4526BD481CA61C8D00166BC8 /* OWSMessageEditing.h */,
|
||||||
|
4CE0E3751B95453C007210CF /* TSAnimatedAdapter.h */,
|
||||||
|
4CE0E3761B954546007210CF /* TSAnimatedAdapter.m */,
|
||||||
|
B6D3CBCE1C1376BE00C039DF /* TSContentAdapters.h */,
|
||||||
|
B62D53F51A23CCAD009AAF82 /* TSMessageAdapter.h */,
|
||||||
|
B62D53F61A23CCAD009AAF82 /* TSMessageAdapter.m */,
|
||||||
|
B6A3EB491A423B3800B2236B /* TSPhotoAdapter.h */,
|
||||||
|
B6A3EB4A1A423B3800B2236B /* TSPhotoAdapter.m */,
|
||||||
|
A5E9D4BA1A65FAD800E4481C /* TSVideoAttachmentAdapter.h */,
|
||||||
|
A5E9D4B91A65FAD800E4481C /* TSVideoAttachmentAdapter.m */,
|
||||||
);
|
);
|
||||||
name = TSMessageAdapters;
|
name = TSMessageAdapters;
|
||||||
path = TSMessageAdapaters;
|
path = TSMessageAdapaters;
|
||||||
|
@ -3262,6 +3272,7 @@
|
||||||
B63761ED19E1FBE8005735D1 /* HttpRequestOrResponse.m in Sources */,
|
B63761ED19E1FBE8005735D1 /* HttpRequestOrResponse.m in Sources */,
|
||||||
76EB05A018170B33006006FC /* IpAddress.m in Sources */,
|
76EB05A018170B33006006FC /* IpAddress.m in Sources */,
|
||||||
FCAC965119FF0A6E0046DFC5 /* MessagesViewController.m in Sources */,
|
FCAC965119FF0A6E0046DFC5 /* MessagesViewController.m in Sources */,
|
||||||
|
34330AA31E79686200DF2FB9 /* OWSProgressView.m in Sources */,
|
||||||
453D28BA1D332DB100D523F0 /* OWSMessagesBubblesSizeCalculator.m in Sources */,
|
453D28BA1D332DB100D523F0 /* OWSMessagesBubblesSizeCalculator.m in Sources */,
|
||||||
45F170AC1E2F0351003FC1F2 /* CallAudioSession.swift in Sources */,
|
45F170AC1E2F0351003FC1F2 /* CallAudioSession.swift in Sources */,
|
||||||
B68EF9BB1C0B1EBD009C3DCD /* FLAnimatedImageView.m in Sources */,
|
B68EF9BB1C0B1EBD009C3DCD /* FLAnimatedImageView.m in Sources */,
|
||||||
|
@ -3371,6 +3382,7 @@
|
||||||
45C681BC1D305C080050903A /* OWSCallCollectionViewCell.m in Sources */,
|
45C681BC1D305C080050903A /* OWSCallCollectionViewCell.m in Sources */,
|
||||||
76EB064018170B33006006FC /* AnonymousTerminator.m in Sources */,
|
76EB064018170B33006006FC /* AnonymousTerminator.m in Sources */,
|
||||||
76EB058818170B33006006FC /* PropertyListPreferences.m in Sources */,
|
76EB058818170B33006006FC /* PropertyListPreferences.m in Sources */,
|
||||||
|
34330A611E788EA900DF2FB9 /* AttachmentUploadView.m in Sources */,
|
||||||
76EB05B218170B33006006FC /* DH3KKeyAgreementProtocol.m in Sources */,
|
76EB05B218170B33006006FC /* DH3KKeyAgreementProtocol.m in Sources */,
|
||||||
B63761EC19E1FBE8005735D1 /* HttpRequest.m in Sources */,
|
B63761EC19E1FBE8005735D1 /* HttpRequest.m in Sources */,
|
||||||
45666F7B1D9C0533008FE134 /* OWSDatabaseMigration.m in Sources */,
|
45666F7B1D9C0533008FE134 /* OWSDatabaseMigration.m in Sources */,
|
||||||
|
|
24
Signal/src/Models/TSMessageAdapaters/AttachmentUploadView.h
Normal file
24
Signal/src/Models/TSMessageAdapaters/AttachmentUploadView.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
//
|
||||||
|
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
@class TSAttachmentStream;
|
||||||
|
|
||||||
|
typedef void (^AttachmentStateBlock)(BOOL isAttachmentReady);
|
||||||
|
|
||||||
|
// This entity is used by various attachment adapters to
|
||||||
|
// coordinate view state with attachment uploads.
|
||||||
|
// During attachment uploads we want to:
|
||||||
|
//
|
||||||
|
// * Dim the media view using a mask layer.
|
||||||
|
// * Show and update a progress bar.
|
||||||
|
// * Disable any media view controls using a callback.
|
||||||
|
@interface AttachmentUploadView : NSObject
|
||||||
|
|
||||||
|
@property (nonatomic, readonly) TSAttachmentStream *attachment;
|
||||||
|
|
||||||
|
- (instancetype)initWithAttachment:(TSAttachmentStream *)attachment
|
||||||
|
superview:(UIView *)superview
|
||||||
|
attachmentStateCallback:(AttachmentStateBlock)attachmentStateCallback;
|
||||||
|
|
||||||
|
@end
|
118
Signal/src/Models/TSMessageAdapaters/AttachmentUploadView.m
Normal file
118
Signal/src/Models/TSMessageAdapaters/AttachmentUploadView.m
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
//
|
||||||
|
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "AttachmentUploadView.h"
|
||||||
|
#import "OWSProgressView.h"
|
||||||
|
#import "OWSUploadingService.h"
|
||||||
|
#import "TSAttachmentStream.h"
|
||||||
|
|
||||||
|
@interface AttachmentUploadView ()
|
||||||
|
|
||||||
|
@property (nonatomic) TSAttachmentStream *attachment;
|
||||||
|
|
||||||
|
@property (nonatomic) OWSProgressView *progressView;
|
||||||
|
|
||||||
|
@property (nonatomic) CALayer *maskLayer;
|
||||||
|
|
||||||
|
@property (nonatomic) AttachmentStateBlock attachmentStateCallback;
|
||||||
|
|
||||||
|
@property (nonatomic) BOOL isAttachmentReady;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
|
||||||
|
@implementation AttachmentUploadView
|
||||||
|
|
||||||
|
- (instancetype)initWithAttachment:(TSAttachmentStream *)attachment
|
||||||
|
superview:(UIView *)superview
|
||||||
|
attachmentStateCallback:(AttachmentStateBlock)attachmentStateCallback
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
|
||||||
|
if (self) {
|
||||||
|
OWSAssert(attachment);
|
||||||
|
OWSAssert(superview);
|
||||||
|
|
||||||
|
self.attachment = attachment;
|
||||||
|
self.attachmentStateCallback = attachmentStateCallback;
|
||||||
|
|
||||||
|
_maskLayer = [CALayer layer];
|
||||||
|
[_maskLayer setBackgroundColor:[UIColor blackColor].CGColor];
|
||||||
|
[_maskLayer setOpacity:0.4f];
|
||||||
|
[_maskLayer setFrame:superview.frame];
|
||||||
|
[superview.layer addSublayer:_maskLayer];
|
||||||
|
|
||||||
|
const CGFloat progressWidth = round(superview.frame.size.width * 0.45f);
|
||||||
|
const CGFloat progressHeight = round(progressWidth * 0.11f);
|
||||||
|
CGRect progressFrame = CGRectMake(round((superview.frame.size.width - progressWidth) * 0.5f),
|
||||||
|
round((superview.frame.size.height - progressHeight) * 0.5f),
|
||||||
|
progressWidth,
|
||||||
|
progressHeight);
|
||||||
|
// The progress view is white. It will only be shown
|
||||||
|
// while the mask layer is visible, so it will show up
|
||||||
|
// even against all-white attachments.
|
||||||
|
_progressView = [OWSProgressView new];
|
||||||
|
_progressView.color = [UIColor whiteColor];
|
||||||
|
_progressView.frame = progressFrame;
|
||||||
|
[superview addSubview:_progressView];
|
||||||
|
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||||
|
selector:@selector(attachmentUploadProgress:)
|
||||||
|
name:kAttachmentUploadProgressNotification
|
||||||
|
object:nil];
|
||||||
|
|
||||||
|
_isAttachmentReady = self.attachment.isUploaded;
|
||||||
|
|
||||||
|
[self ensureViewState];
|
||||||
|
|
||||||
|
if (attachmentStateCallback) {
|
||||||
|
self.attachmentStateCallback(_isAttachmentReady);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setIsAttachmentReady:(BOOL)isAttachmentReady
|
||||||
|
{
|
||||||
|
if (_isAttachmentReady == isAttachmentReady) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_isAttachmentReady = isAttachmentReady;
|
||||||
|
|
||||||
|
[self ensureViewState];
|
||||||
|
|
||||||
|
if (self.attachmentStateCallback) {
|
||||||
|
self.attachmentStateCallback(isAttachmentReady);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)ensureViewState
|
||||||
|
{
|
||||||
|
_maskLayer.hidden = self.isAttachmentReady;
|
||||||
|
_progressView.hidden = self.isAttachmentReady;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)attachmentUploadProgress:(NSNotification *)notification
|
||||||
|
{
|
||||||
|
NSDictionary *userinfo = [notification userInfo];
|
||||||
|
double progress = [[userinfo objectForKey:kAttachmentUploadProgressKey] doubleValue];
|
||||||
|
NSString *attachmentID = [userinfo objectForKey:kAttachmentUploadAttachmentIDKey];
|
||||||
|
if ([self.attachment.uniqueId isEqualToString:attachmentID]) {
|
||||||
|
if (!isnan(progress)) {
|
||||||
|
[_progressView setProgress:(float)progress];
|
||||||
|
self.isAttachmentReady = self.attachment.isUploaded;
|
||||||
|
} else {
|
||||||
|
self.isAttachmentReady = YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -1,9 +1,5 @@
|
||||||
//
|
//
|
||||||
// TSAnimatedAdapter.h
|
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||||
// Signal
|
|
||||||
//
|
|
||||||
// Created by Mike Okner (@mikeokner) on 2015-09-01.
|
|
||||||
// Copyright (c) 2015 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#import "OWSMessageEditing.h"
|
#import "OWSMessageEditing.h"
|
||||||
|
@ -13,7 +9,7 @@
|
||||||
|
|
||||||
@interface TSAnimatedAdapter : JSQMediaItem <OWSMessageEditing>
|
@interface TSAnimatedAdapter : JSQMediaItem <OWSMessageEditing>
|
||||||
|
|
||||||
- (instancetype)initWithAttachment:(TSAttachmentStream *)attachment;
|
- (instancetype)initWithAttachment:(TSAttachmentStream *)attachment incoming:(BOOL)incoming;
|
||||||
|
|
||||||
- (BOOL)isImage;
|
- (BOOL)isImage;
|
||||||
- (BOOL)isAudio;
|
- (BOOL)isAudio;
|
||||||
|
|
|
@ -1,30 +1,30 @@
|
||||||
//
|
//
|
||||||
// TSAnimatedAdapter.m
|
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||||
// Signal
|
|
||||||
//
|
|
||||||
// Created by Mike Okner (@mikeokner) on 2015-09-01.
|
|
||||||
// Copyright (c) 2015 Open Whisper Systems. All rights reserved.
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#import "TSAnimatedAdapter.h"
|
#import "TSAnimatedAdapter.h"
|
||||||
|
#import "AttachmentUploadView.h"
|
||||||
#import "FLAnimatedImage.h"
|
#import "FLAnimatedImage.h"
|
||||||
#import "TSAttachmentStream.h"
|
|
||||||
#import "JSQMediaItem+OWS.h"
|
#import "JSQMediaItem+OWS.h"
|
||||||
|
#import "TSAttachmentStream.h"
|
||||||
#import <AssetsLibrary/AssetsLibrary.h>
|
#import <AssetsLibrary/AssetsLibrary.h>
|
||||||
#import <JSQMessagesViewController/JSQMessagesMediaViewBubbleImageMasker.h>
|
#import <JSQMessagesViewController/JSQMessagesMediaViewBubbleImageMasker.h>
|
||||||
#import <MobileCoreServices/MobileCoreServices.h>
|
#import <MobileCoreServices/MobileCoreServices.h>
|
||||||
|
|
||||||
@interface TSAnimatedAdapter ()
|
@interface TSAnimatedAdapter ()
|
||||||
|
|
||||||
@property (strong, nonatomic) UIImageView *cachedImageView;
|
@property (nonatomic) UIImageView *cachedImageView;
|
||||||
@property (strong, nonatomic) UIImage *image;
|
@property (nonatomic) UIImage *image;
|
||||||
@property (strong, nonatomic) TSAttachmentStream *attachment;
|
@property (nonatomic) TSAttachmentStream *attachment;
|
||||||
|
@property (nonatomic) AttachmentUploadView *attachmentUploadView;
|
||||||
|
@property (nonatomic) BOOL incoming;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation TSAnimatedAdapter
|
@implementation TSAnimatedAdapter
|
||||||
|
|
||||||
- (instancetype)initWithAttachment:(TSAttachmentStream *)attachment {
|
- (instancetype)initWithAttachment:(TSAttachmentStream *)attachment incoming:(BOOL)incoming
|
||||||
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
if (self) {
|
if (self) {
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
_attachmentId = attachment.uniqueId;
|
_attachmentId = attachment.uniqueId;
|
||||||
_image = [attachment image];
|
_image = [attachment image];
|
||||||
_fileData = [NSData dataWithContentsOfURL:[attachment mediaURL]];
|
_fileData = [NSData dataWithContentsOfURL:[attachment mediaURL]];
|
||||||
|
_incoming = incoming;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -78,6 +79,12 @@
|
||||||
[JSQMessagesMediaViewBubbleImageMasker applyBubbleImageMaskToMediaView:imageView
|
[JSQMessagesMediaViewBubbleImageMasker applyBubbleImageMaskToMediaView:imageView
|
||||||
isOutgoing:self.appliesMediaViewMaskAsOutgoing];
|
isOutgoing:self.appliesMediaViewMaskAsOutgoing];
|
||||||
self.cachedImageView = imageView;
|
self.cachedImageView = imageView;
|
||||||
|
|
||||||
|
if (!self.incoming) {
|
||||||
|
self.attachmentUploadView = [[AttachmentUploadView alloc] initWithAttachment:self.attachment
|
||||||
|
superview:imageView
|
||||||
|
attachmentStateCallback:nil];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return self.cachedImageView;
|
return self.cachedImageView;
|
||||||
|
|
|
@ -127,15 +127,19 @@
|
||||||
for (NSString *attachmentID in message.attachmentIds) {
|
for (NSString *attachmentID in message.attachmentIds) {
|
||||||
TSAttachment *attachment = [TSAttachment fetchObjectWithUniqueID:attachmentID];
|
TSAttachment *attachment = [TSAttachment fetchObjectWithUniqueID:attachmentID];
|
||||||
|
|
||||||
|
BOOL isIncomingAttachment = [interaction isKindOfClass:[TSIncomingMessage class]];
|
||||||
|
|
||||||
if ([attachment isKindOfClass:[TSAttachmentStream class]]) {
|
if ([attachment isKindOfClass:[TSAttachmentStream class]]) {
|
||||||
TSAttachmentStream *stream = (TSAttachmentStream *)attachment;
|
TSAttachmentStream *stream = (TSAttachmentStream *)attachment;
|
||||||
if ([stream isAnimated]) {
|
if ([stream isAnimated]) {
|
||||||
adapter.mediaItem = [[TSAnimatedAdapter alloc] initWithAttachment:stream];
|
adapter.mediaItem =
|
||||||
|
[[TSAnimatedAdapter alloc] initWithAttachment:stream incoming:isIncomingAttachment];
|
||||||
adapter.mediaItem.appliesMediaViewMaskAsOutgoing =
|
adapter.mediaItem.appliesMediaViewMaskAsOutgoing =
|
||||||
[interaction isKindOfClass:[TSOutgoingMessage class]];
|
[interaction isKindOfClass:[TSOutgoingMessage class]];
|
||||||
break;
|
break;
|
||||||
} else if ([stream isImage]) {
|
} else if ([stream isImage]) {
|
||||||
adapter.mediaItem = [[TSPhotoAdapter alloc] initWithAttachment:stream];
|
adapter.mediaItem =
|
||||||
|
[[TSPhotoAdapter alloc] initWithAttachment:stream incoming:isIncomingAttachment];
|
||||||
adapter.mediaItem.appliesMediaViewMaskAsOutgoing =
|
adapter.mediaItem.appliesMediaViewMaskAsOutgoing =
|
||||||
[interaction isKindOfClass:[TSOutgoingMessage class]];
|
[interaction isKindOfClass:[TSOutgoingMessage class]];
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// Created by Frederic Jacobs on 17/12/14.
|
//
|
||||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
#import "OWSMessageEditing.h"
|
#import "OWSMessageEditing.h"
|
||||||
#import <JSQMessagesViewController/JSQPhotoMediaItem.h>
|
#import <JSQMessagesViewController/JSQPhotoMediaItem.h>
|
||||||
|
@ -8,7 +9,7 @@
|
||||||
|
|
||||||
@interface TSPhotoAdapter : JSQPhotoMediaItem <OWSMessageEditing>
|
@interface TSPhotoAdapter : JSQPhotoMediaItem <OWSMessageEditing>
|
||||||
|
|
||||||
- (instancetype)initWithAttachment:(TSAttachmentStream *)attachment;
|
- (instancetype)initWithAttachment:(TSAttachmentStream *)attachment incoming:(BOOL)incoming;
|
||||||
|
|
||||||
- (BOOL)isImage;
|
- (BOOL)isImage;
|
||||||
- (BOOL)isAudio;
|
- (BOOL)isAudio;
|
||||||
|
|
|
@ -3,18 +3,23 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#import "TSPhotoAdapter.h"
|
#import "TSPhotoAdapter.h"
|
||||||
#import "TSAttachmentStream.h"
|
#import "AttachmentUploadView.h"
|
||||||
#import "JSQMediaItem+OWS.h"
|
#import "JSQMediaItem+OWS.h"
|
||||||
|
#import "TSAttachmentStream.h"
|
||||||
#import <JSQMessagesViewController/JSQMessagesMediaViewBubbleImageMasker.h>
|
#import <JSQMessagesViewController/JSQMessagesMediaViewBubbleImageMasker.h>
|
||||||
|
|
||||||
@interface TSPhotoAdapter ()
|
@interface TSPhotoAdapter ()
|
||||||
|
|
||||||
@property (strong, nonatomic) UIImageView *cachedImageView;
|
@property (nonatomic) UIImageView *cachedImageView;
|
||||||
|
@property (nonatomic) AttachmentUploadView *attachmentUploadView;
|
||||||
|
@property (nonatomic) BOOL incoming;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation TSPhotoAdapter
|
@implementation TSPhotoAdapter
|
||||||
|
|
||||||
- (instancetype)initWithAttachment:(TSAttachmentStream *)attachment {
|
- (instancetype)initWithAttachment:(TSAttachmentStream *)attachment incoming:(BOOL)incoming
|
||||||
|
{
|
||||||
self = [super initWithImage:attachment.image];
|
self = [super initWithImage:attachment.image];
|
||||||
|
|
||||||
if (!self) {
|
if (!self) {
|
||||||
|
@ -24,6 +29,7 @@
|
||||||
_cachedImageView = nil;
|
_cachedImageView = nil;
|
||||||
_attachment = attachment;
|
_attachment = attachment;
|
||||||
_attachmentId = attachment.uniqueId;
|
_attachmentId = attachment.uniqueId;
|
||||||
|
_incoming = incoming;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -58,6 +64,12 @@
|
||||||
[JSQMessagesMediaViewBubbleImageMasker applyBubbleImageMaskToMediaView:imageView
|
[JSQMessagesMediaViewBubbleImageMasker applyBubbleImageMaskToMediaView:imageView
|
||||||
isOutgoing:self.appliesMediaViewMaskAsOutgoing];
|
isOutgoing:self.appliesMediaViewMaskAsOutgoing];
|
||||||
self.cachedImageView = imageView;
|
self.cachedImageView = imageView;
|
||||||
|
|
||||||
|
if (!self.incoming) {
|
||||||
|
self.attachmentUploadView = [[AttachmentUploadView alloc] initWithAttachment:self.attachment
|
||||||
|
superview:imageView
|
||||||
|
attachmentStateCallback:nil];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return self.cachedImageView;
|
return self.cachedImageView;
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
// Created by Frederic Jacobs on 17/12/14.
|
//
|
||||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
#import "TSVideoAttachmentAdapter.h"
|
#import "TSVideoAttachmentAdapter.h"
|
||||||
|
#import "AttachmentUploadView.h"
|
||||||
|
#import "JSQMediaItem+OWS.h"
|
||||||
#import "MIMETypeUtil.h"
|
#import "MIMETypeUtil.h"
|
||||||
#import "TSAttachmentStream.h"
|
#import "TSAttachmentStream.h"
|
||||||
#import "TSMessagesManager.h"
|
#import "TSMessagesManager.h"
|
||||||
#import "TSStorageManager+keyingMaterial.h"
|
#import "TSStorageManager+keyingMaterial.h"
|
||||||
#import "JSQMediaItem+OWS.h"
|
|
||||||
#import <FFCircularProgressView.h>
|
|
||||||
#import <JSQMessagesViewController/JSQMessagesMediaViewBubbleImageMasker.h>
|
#import <JSQMessagesViewController/JSQMessagesMediaViewBubbleImageMasker.h>
|
||||||
#import <MobileCoreServices/MobileCoreServices.h>
|
#import <MobileCoreServices/MobileCoreServices.h>
|
||||||
#import <SCWaveformView.h>
|
#import <SCWaveformView.h>
|
||||||
|
@ -15,18 +16,17 @@
|
||||||
|
|
||||||
@interface TSVideoAttachmentAdapter ()
|
@interface TSVideoAttachmentAdapter ()
|
||||||
|
|
||||||
@property UIImage *image;
|
@property (nonatomic) UIImage *image;
|
||||||
@property (strong, nonatomic) UIImageView *cachedImageView;
|
@property (nonatomic) UIImageView *cachedImageView;
|
||||||
@property (strong, nonatomic) UIImageView *videoPlayButton;
|
@property (nonatomic) UIImageView *videoPlayButton;
|
||||||
@property (strong, nonatomic) CALayer *maskLayer;
|
@property (nonatomic) TSAttachmentStream *attachment;
|
||||||
@property (strong, nonatomic) FFCircularProgressView *progressView;
|
@property (nonatomic) UIProgressView *audioProgress;
|
||||||
@property (strong, nonatomic) TSAttachmentStream *attachment;
|
@property (nonatomic) SCWaveformView *waveform;
|
||||||
@property (strong, nonatomic) UIProgressView *audioProgress;
|
@property (nonatomic) UIButton *audioPlayPauseButton;
|
||||||
@property (strong, nonatomic) SCWaveformView *waveform;
|
@property (nonatomic) UILabel *durationLabel;
|
||||||
@property (strong, nonatomic) UIButton *audioPlayPauseButton;
|
@property (nonatomic) UIView *audioBubble;
|
||||||
@property (strong, nonatomic) UILabel *durationLabel;
|
|
||||||
@property (strong, nonatomic) UIView *audioBubble;
|
|
||||||
@property (nonatomic) BOOL incoming;
|
@property (nonatomic) BOOL incoming;
|
||||||
|
@property (nonatomic) AttachmentUploadView *attachmentUploadView;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -121,23 +121,16 @@
|
||||||
_videoPlayButton.frame = CGRectMake((size.width / 2) - 18, (size.height / 2) - 18, 37, 37);
|
_videoPlayButton.frame = CGRectMake((size.width / 2) - 18, (size.height / 2) - 18, 37, 37);
|
||||||
[self.cachedImageView addSubview:_videoPlayButton];
|
[self.cachedImageView addSubview:_videoPlayButton];
|
||||||
_videoPlayButton.hidden = YES;
|
_videoPlayButton.hidden = YES;
|
||||||
_maskLayer = [CALayer layer];
|
|
||||||
[_maskLayer setBackgroundColor:[UIColor blackColor].CGColor];
|
if (!_incoming) {
|
||||||
[_maskLayer setOpacity:0.4f];
|
__weak TSVideoAttachmentAdapter *weakSelf = self;
|
||||||
[_maskLayer setFrame:self.cachedImageView.frame];
|
self.attachmentUploadView = [[AttachmentUploadView alloc] initWithAttachment:self.attachment
|
||||||
[self.cachedImageView.layer addSublayer:_maskLayer];
|
superview:imageView
|
||||||
_progressView = [[FFCircularProgressView alloc]
|
attachmentStateCallback:^(BOOL isAttachmentReady) {
|
||||||
initWithFrame:CGRectMake((size.width / 2) - 18, (size.height / 2) - 18, 37, 37)];
|
weakSelf.videoPlayButton.hidden
|
||||||
[_cachedImageView addSubview:_progressView];
|
= !isAttachmentReady;
|
||||||
if (_attachment.isDownloaded) {
|
}];
|
||||||
_videoPlayButton.hidden = NO;
|
|
||||||
_maskLayer.hidden = YES;
|
|
||||||
_progressView.hidden = YES;
|
|
||||||
}
|
}
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
||||||
selector:@selector(attachmentUploadProgress:)
|
|
||||||
name:@"attachmentUploadProgress"
|
|
||||||
object:nil];
|
|
||||||
}
|
}
|
||||||
} else if ([self isAudio]) {
|
} else if ([self isAudio]) {
|
||||||
NSError *err = NULL;
|
NSError *err = NULL;
|
||||||
|
@ -192,7 +185,20 @@
|
||||||
[_audioBubble addSubview:_audioPlayPauseButton];
|
[_audioBubble addSubview:_audioPlayPauseButton];
|
||||||
[_audioBubble addSubview:_durationLabel];
|
[_audioBubble addSubview:_durationLabel];
|
||||||
|
|
||||||
|
if (!_incoming) {
|
||||||
|
__weak TSVideoAttachmentAdapter *weakSelf = self;
|
||||||
|
self.attachmentUploadView = [[AttachmentUploadView alloc] initWithAttachment:self.attachment
|
||||||
|
superview:_audioBubble
|
||||||
|
attachmentStateCallback:^(BOOL isAttachmentReady) {
|
||||||
|
weakSelf.audioPlayPauseButton.enabled
|
||||||
|
= isAttachmentReady;
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
return _audioBubble;
|
return _audioBubble;
|
||||||
|
} else {
|
||||||
|
// Unknown media type.
|
||||||
|
OWSAssert(0);
|
||||||
}
|
}
|
||||||
return self.cachedImageView;
|
return self.cachedImageView;
|
||||||
}
|
}
|
||||||
|
@ -215,35 +221,6 @@
|
||||||
return [super hash];
|
return [super hash];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)attachmentUploadProgress:(NSNotification *)notification {
|
|
||||||
NSDictionary *userinfo = [notification userInfo];
|
|
||||||
double progress = [[userinfo objectForKey:@"progress"] doubleValue];
|
|
||||||
NSString *attachmentID = [userinfo objectForKey:@"attachmentID"];
|
|
||||||
if ([_attachmentId isEqualToString:attachmentID]) {
|
|
||||||
NSLog(@"is downloaded: %d", _attachment.isDownloaded);
|
|
||||||
if (!isnan(progress)) {
|
|
||||||
[_progressView setProgress:(float)progress];
|
|
||||||
}
|
|
||||||
if (progress >= 1) {
|
|
||||||
_maskLayer.hidden = YES;
|
|
||||||
_progressView.hidden = YES;
|
|
||||||
_videoPlayButton.hidden = NO;
|
|
||||||
_attachment.isDownloaded = YES; // TODO isn't this redundant with attachment processor?
|
|
||||||
[[TSMessagesManager sharedManager]
|
|
||||||
.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
|
||||||
[_attachment saveWithTransaction:transaction];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// set progress on bar
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)dealloc {
|
|
||||||
_image = nil;
|
|
||||||
_cachedImageView = nil;
|
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setAppliesMediaViewMaskAsOutgoing:(BOOL)appliesMediaViewMaskAsOutgoing {
|
- (void)setAppliesMediaViewMaskAsOutgoing:(BOOL)appliesMediaViewMaskAsOutgoing {
|
||||||
[super setAppliesMediaViewMaskAsOutgoing:appliesMediaViewMaskAsOutgoing];
|
[super setAppliesMediaViewMaskAsOutgoing:appliesMediaViewMaskAsOutgoing];
|
||||||
_cachedImageView = nil;
|
_cachedImageView = nil;
|
||||||
|
|
|
@ -180,29 +180,29 @@ typedef enum : NSUInteger {
|
||||||
NSUInteger _unreadCount;
|
NSUInteger _unreadCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@property TSThread *thread;
|
@property (nonatomic) TSThread *thread;
|
||||||
@property TSMessageAdapter *lastDeliveredMessage;
|
@property (nonatomic) TSMessageAdapter *lastDeliveredMessage;
|
||||||
@property (nonatomic, strong) YapDatabaseConnection *editingDatabaseConnection;
|
@property (nonatomic) YapDatabaseConnection *editingDatabaseConnection;
|
||||||
@property (nonatomic, strong) YapDatabaseConnection *uiDatabaseConnection;
|
@property (nonatomic) YapDatabaseConnection *uiDatabaseConnection;
|
||||||
@property (nonatomic, strong) YapDatabaseViewMappings *messageMappings;
|
@property (nonatomic) YapDatabaseViewMappings *messageMappings;
|
||||||
|
|
||||||
@property (nonatomic, retain) JSQMessagesBubbleImage *outgoingBubbleImageData;
|
@property (nonatomic) JSQMessagesBubbleImage *outgoingBubbleImageData;
|
||||||
@property (nonatomic, retain) JSQMessagesBubbleImage *incomingBubbleImageData;
|
@property (nonatomic) JSQMessagesBubbleImage *incomingBubbleImageData;
|
||||||
@property (nonatomic, retain) JSQMessagesBubbleImage *currentlyOutgoingBubbleImageData;
|
@property (nonatomic) JSQMessagesBubbleImage *currentlyOutgoingBubbleImageData;
|
||||||
@property (nonatomic, retain) JSQMessagesBubbleImage *outgoingMessageFailedImageData;
|
@property (nonatomic) JSQMessagesBubbleImage *outgoingMessageFailedImageData;
|
||||||
|
|
||||||
@property (nonatomic, strong) NSTimer *audioPlayerPoller;
|
@property (nonatomic) NSTimer *audioPlayerPoller;
|
||||||
@property (nonatomic, strong) TSVideoAttachmentAdapter *currentMediaAdapter;
|
@property (nonatomic) TSVideoAttachmentAdapter *currentMediaAdapter;
|
||||||
|
|
||||||
@property (nonatomic, retain) NSTimer *readTimer;
|
@property (nonatomic) NSTimer *readTimer;
|
||||||
@property (nonatomic, strong) UIView *navigationBarTitleView;
|
@property (nonatomic) UIView *navigationBarTitleView;
|
||||||
@property (nonatomic, strong) UILabel *navigationBarTitleLabel;
|
@property (nonatomic) UILabel *navigationBarTitleLabel;
|
||||||
@property (nonatomic, strong) UILabel *navigationBarSubtitleLabel;
|
@property (nonatomic) UILabel *navigationBarSubtitleLabel;
|
||||||
@property (nonatomic, retain) UIButton *attachButton;
|
@property (nonatomic) UIButton *attachButton;
|
||||||
|
|
||||||
@property (nonatomic) CGFloat previousCollectionViewFrameWidth;
|
@property (nonatomic) CGFloat previousCollectionViewFrameWidth;
|
||||||
|
|
||||||
@property NSUInteger page;
|
@property (nonatomic) NSUInteger page;
|
||||||
@property (nonatomic) BOOL composeOnOpen;
|
@property (nonatomic) BOOL composeOnOpen;
|
||||||
@property (nonatomic) BOOL peek;
|
@property (nonatomic) BOOL peek;
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ typedef enum : NSUInteger {
|
||||||
@property (nonatomic, readonly) TSNetworkManager *networkManager;
|
@property (nonatomic, readonly) TSNetworkManager *networkManager;
|
||||||
@property (nonatomic, readonly) OutboundCallInitiator *outboundCallInitiator;
|
@property (nonatomic, readonly) OutboundCallInitiator *outboundCallInitiator;
|
||||||
|
|
||||||
@property NSCache *messageAdapterCache;
|
@property (nonatomic) NSCache *messageAdapterCache;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
14
Signal/src/views/OWSProgressView.h
Normal file
14
Signal/src/views/OWSProgressView.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
//
|
||||||
|
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface OWSProgressView : UIView
|
||||||
|
|
||||||
|
@property (nonatomic) UIColor *color;
|
||||||
|
@property (nonatomic) CGFloat progress;
|
||||||
|
|
||||||
|
@end
|
120
Signal/src/views/OWSProgressView.m
Normal file
120
Signal/src/views/OWSProgressView.m
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
//
|
||||||
|
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "OWSProgressView.h"
|
||||||
|
|
||||||
|
@interface OWSProgressView ()
|
||||||
|
|
||||||
|
@property (nonatomic) CAShapeLayer *borderLayer;
|
||||||
|
@property (nonatomic) CAShapeLayer *progressLayer;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
|
||||||
|
@implementation OWSProgressView
|
||||||
|
|
||||||
|
- (id)init
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
[self initCommon];
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)initWithFrame:(CGRect)frame
|
||||||
|
{
|
||||||
|
self = [super initWithFrame:frame];
|
||||||
|
if (self) {
|
||||||
|
[self initCommon];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)initCommon
|
||||||
|
{
|
||||||
|
self.opaque = NO;
|
||||||
|
self.userInteractionEnabled = NO;
|
||||||
|
self.backgroundColor = [UIColor clearColor];
|
||||||
|
self.color = [UIColor whiteColor];
|
||||||
|
|
||||||
|
self.borderLayer = [CAShapeLayer new];
|
||||||
|
self.borderLayer.fillColor = self.color.CGColor;
|
||||||
|
[self.layer addSublayer:self.borderLayer];
|
||||||
|
|
||||||
|
self.progressLayer = [CAShapeLayer new];
|
||||||
|
self.progressLayer.fillColor = self.color.CGColor;
|
||||||
|
[self.layer addSublayer:self.progressLayer];
|
||||||
|
|
||||||
|
[self setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisVertical];
|
||||||
|
[self setContentHuggingPriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisVertical];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)layoutSubviews
|
||||||
|
{
|
||||||
|
[super layoutSubviews];
|
||||||
|
[self update];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setProgress:(CGFloat)progress
|
||||||
|
{
|
||||||
|
if (_progress != progress) {
|
||||||
|
_progress = progress;
|
||||||
|
[self update];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setColor:(UIColor *)color
|
||||||
|
{
|
||||||
|
if (![_color isEqual:color]) {
|
||||||
|
_color = color;
|
||||||
|
[self update];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)update
|
||||||
|
{
|
||||||
|
CGFloat kBorderThickness = self.bounds.size.height * 0.15f;
|
||||||
|
CGFloat kOuterRadius = self.bounds.size.height * 0.3f;
|
||||||
|
CGFloat kInnerRadius = kOuterRadius - kBorderThickness;
|
||||||
|
// We want to slightly overlap the border with the progress
|
||||||
|
// to achieve a clean effect.
|
||||||
|
CGFloat kProgressInset = kBorderThickness - 0.5f;
|
||||||
|
|
||||||
|
UIBezierPath *borderPath = [UIBezierPath new];
|
||||||
|
|
||||||
|
// Add the outer border.
|
||||||
|
[borderPath appendPath:[UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:kOuterRadius]];
|
||||||
|
[borderPath
|
||||||
|
appendPath:[UIBezierPath bezierPathWithRoundedRect:CGRectInset(self.bounds, kBorderThickness, kBorderThickness)
|
||||||
|
cornerRadius:kInnerRadius]];
|
||||||
|
|
||||||
|
self.borderLayer.path = borderPath.CGPath;
|
||||||
|
self.borderLayer.fillColor = self.color.CGColor;
|
||||||
|
self.borderLayer.fillRule = kCAFillRuleEvenOdd;
|
||||||
|
|
||||||
|
UIBezierPath *progressPath = [UIBezierPath new];
|
||||||
|
|
||||||
|
// Add the inner progress.
|
||||||
|
CGRect progressRect = CGRectInset(self.bounds, kProgressInset, kProgressInset);
|
||||||
|
progressRect.size.width *= MAX(0.f, MIN(1.f, self.progress));
|
||||||
|
[progressPath appendPath:[UIBezierPath bezierPathWithRect:progressRect]];
|
||||||
|
|
||||||
|
self.progressLayer.path = progressPath.CGPath;
|
||||||
|
self.progressLayer.fillColor = self.color.CGColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGSize)sizeThatFits:(CGSize)size
|
||||||
|
{
|
||||||
|
return CGSizeMake(150, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGSize)intrinsicContentSize
|
||||||
|
{
|
||||||
|
return CGSizeMake(UIViewNoIntrinsicMetric, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
Loading…
Reference in a new issue