Phone calls in MessageView.

pull/1/head
Frederic Jacobs 10 years ago
parent 2082c2ada7
commit 0266621ceb

@ -81,7 +81,7 @@ EXTERNAL SOURCES:
CHECKOUT OPTIONS:
JSQMessagesViewController:
:commit: 84d1b659f350ac3e10464d44b87243fa4622acf4
:commit: 9dffc05aa72ad701ecb038a2833cdf53df4b16d7
:git: https://github.com/dtsbourg/JSQMessagesViewController
SocketRocket:
:commit: d0585af165

@ -1 +1 @@
Subproject commit e0662ba2d55acd60164b74d245983fb69017ceeb
Subproject commit 4104112c445b2a0fa19fd15f2b97d7be7d46d3c4

@ -10,25 +10,13 @@
*
*/
@interface RecentCallManager : NSObject {
@private ObservableValueController* observableRecentsController;
}
@interface RecentCallManager : NSObject
- (ObservableValue *)getObservableRecentCalls;
- (void)watchForCallsThrough:(PhoneManager*)phoneManager
untilCancelled:(TOCCancelToken*)untilCancelledToken;
- (void)watchForContactUpdatesFrom:(ContactsManager*) contactManager
untillCancelled:(TOCCancelToken*) cancelToken;
- (void)addRecentCall:(RecentCall *)recentCall;
- (void)removeRecentCall:(RecentCall *)recentCall;
- (void)archiveRecentCall:(RecentCall *)recentCall;
- (void)clearRecentCalls;
- (void)addMissedCallDueToBusy:(ResponderSessionDescriptor*)incomingCallDescriptor;
- (NSArray *)recentsForSearchString:(NSString *)optionalSearchString
andExcludeArchived:(BOOL)excludeArchived;
- (void)saveContactsToDefaults;
- (BOOL)isPhoneNumberPresentInRecentCalls:(PhoneNumber*) phoneNumber;
- (NSUInteger)missedCallCount;
@end

@ -3,50 +3,28 @@
#import "FunctionalUtil.h"
#import "ObservableValue.h"
#import "PreferencesUtil.h"
#import "NSDate+millisecondTimeStamp.h"
#import "TSCall.h"
#import "TSStorageManager.h"
#import "TSContactThread.h"
#define RECENT_CALLS_DEFAULT_KEY @"RPRecentCallsDefaultKey"
typedef BOOL (^SearchTermConditionalBlock)(RecentCall*, NSUInteger, BOOL*);
@interface RecentCallManager () {
NSMutableArray *_allRecents;
}
@interface RecentCallManager ()
@property YapDatabaseConnection *dbConnection;
@end
@implementation RecentCallManager
- (id)init {
if (self = [super init]) {
[self initRecentCallsObservable];
- (instancetype)init{
self = [super init];
if (self) {
_dbConnection = [TSStorageManager sharedManager].newDatabaseConnection;
}
return self;
}
-(void) initRecentCallsObservable {
_allRecents = [self loadContactsFromDefaults];
observableRecentsController = [ObservableValueController observableValueControllerWithInitialValue:_allRecents];
}
- (ObservableValue *)getObservableRecentCalls {
return observableRecentsController;
}
-(void) watchForContactUpdatesFrom:(ContactsManager*) contactManager untillCancelled:(TOCCancelToken*) cancelToken{
[contactManager.getObservableRedPhoneUsers watchLatestValue:^(NSArray* latestUsers) {
for (RecentCall* recentCall in _allRecents) {
if (![contactManager latestContactWithRecordId:recentCall.contactRecordID]) {
Contact* contact = [contactManager latestContactForPhoneNumber:recentCall.phoneNumber];
if(contact){
[self updateRecentCall:recentCall withContactId:contact.recordID];
}
}
}
} onThread:NSThread.mainThread untilCancelled:cancelToken];
}
-(void) watchForCallsThrough:(PhoneManager*)phoneManager
- (void)watchForCallsThrough:(PhoneManager*)phoneManager
untilCancelled:(TOCCancelToken*)untilCancelledToken {
require(phoneManager != nil);
@ -54,10 +32,10 @@ typedef BOOL (^SearchTermConditionalBlock)(RecentCall*, NSUInteger, BOOL*);
if (latestCall != nil) {
[self addCall:latestCall];
}
} onThread:NSThread.mainThread untilCancelled:untilCancelledToken];
} onThread:NSThread.currentThread untilCancelled:untilCancelledToken];
}
-(void) addCall:(CallState*)call {
- (void)addCall:(CallState*)call {
require(call != nil);
[call.futureCallLocallyAcceptedOrRejected finallyDo:^(TOCFuture* interactionCompletion) {
@ -75,12 +53,12 @@ typedef BOOL (^SearchTermConditionalBlock)(RecentCall*, NSUInteger, BOOL*);
}];
}
-(Contact*) tryGetContactForCall:(CallState*)call {
- (Contact*)tryGetContactForCall:(CallState*)call {
if (call.potentiallySpecifiedContact != nil) return call.potentiallySpecifiedContact;
return [self tryGetContactForNumber:call.remoteNumber];
}
-(Contact*) tryGetContactForNumber:(PhoneNumber*)number {
- (Contact*)tryGetContactForNumber:(PhoneNumber*)number {
return [Environment.getCurrent.contactsManager latestContactForPhoneNumber:number];
}
@ -93,92 +71,11 @@ typedef BOOL (^SearchTermConditionalBlock)(RecentCall*, NSUInteger, BOOL*);
andCallType:RPRecentCallTypeMissed]];
}
-(void) updateRecentCall:(RecentCall*) recentCall withContactId:(ABRecordID) contactId {
[recentCall updateRecentCallWithContactId:contactId];
[observableRecentsController updateValue:_allRecents.copy];
[self saveContactsToDefaults];
}
- (void)addRecentCall:(RecentCall *)recentCall {
[_allRecents insertObject:recentCall atIndex:0];
[observableRecentsController updateValue:_allRecents.copy];
[self saveContactsToDefaults];
}
- (void)removeRecentCall:(RecentCall *)recentCall {
[_allRecents removeObject:recentCall];
[observableRecentsController updateValue:_allRecents.copy];
[self saveContactsToDefaults];
}
- (void)archiveRecentCall:(RecentCall *)recentCall {
NSUInteger indexOfRecent = [_allRecents indexOfObject:recentCall];
recentCall.isArchived = YES;
_allRecents[indexOfRecent] = recentCall;
[self saveContactsToDefaults];
[observableRecentsController updateValue:_allRecents.copy];
}
- (void)clearRecentCalls {
[_allRecents removeAllObjects];
[observableRecentsController updateValue:_allRecents.copy];
[self saveContactsToDefaults];
}
- (void)saveContactsToDefaults {
NSUserDefaults *defaults = NSUserDefaults.standardUserDefaults;
NSData *saveData = [NSKeyedArchiver archivedDataWithRootObject:_allRecents.copy];
[defaults setObject:saveData forKey:RECENT_CALLS_DEFAULT_KEY];
[defaults synchronize];
}
- (NSMutableArray *)loadContactsFromDefaults {
NSUserDefaults *defaults = NSUserDefaults.standardUserDefaults;
NSData *encodedData = [defaults objectForKey:RECENT_CALLS_DEFAULT_KEY];
id data = [NSKeyedUnarchiver unarchiveObjectWithData:encodedData];
if(![data isKindOfClass:NSArray.class]) {
return [NSMutableArray array];
} else {
return [NSMutableArray arrayWithArray:data];
}
}
- (NSArray *)recentsForSearchString:(NSString *)optionalSearchString andExcludeArchived:(BOOL)excludeArchived {
ContactsManager *contactsManager = Environment.getCurrent.contactsManager;
SearchTermConditionalBlock searchBlock = ^BOOL(RecentCall *obj, NSUInteger idx, BOOL *stop) {
BOOL nameMatchesSearch = YES;
BOOL numberMatchesSearch = YES;
if (optionalSearchString) {
NSString *contactName = [contactsManager latestContactWithRecordId:obj.contactRecordID].fullName;
nameMatchesSearch = [ContactsManager name:contactName matchesQuery:optionalSearchString];
numberMatchesSearch = [ContactsManager phoneNumber:obj.phoneNumber matchesQuery:optionalSearchString];
}
if (excludeArchived) {
return !obj.isArchived && (nameMatchesSearch || numberMatchesSearch);
} else {
return (nameMatchesSearch || numberMatchesSearch);
}
};
NSIndexSet *newsFeedIndexes = [_allRecents indexesOfObjectsPassingTest:searchBlock];
return [_allRecents objectsAtIndexes:newsFeedIndexes];
}
- (NSUInteger)missedCallCount {
SearchTermConditionalBlock missedCallBlock = ^BOOL(RecentCall *recentCall, NSUInteger idx, BOOL *stop) {
return !recentCall.userNotified;
};
return [[_allRecents indexesOfObjectsPassingTest:missedCallBlock] count];
}
-(BOOL) isPhoneNumberPresentInRecentCalls:(PhoneNumber*) phoneNumber {
return [_allRecents any:^int(RecentCall* call) {
return [call.phoneNumber resolvesInternationallyTo:phoneNumber];
- (void)addRecentCall:(RecentCall*)recentCall {
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactId:recentCall.phoneNumber.toE164 transaction:transaction];
TSCall *call = [[TSCall alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] withCallNumber:recentCall.phoneNumber.toE164 callType:recentCall.callType inThread:thread];
[call saveWithTransaction:transaction];
}];
}

@ -131,8 +131,6 @@ phoneDirectoryManager;
[recentCallManager watchForCallsThrough:phoneManager
untilCancelled:nil];
[recentCallManager watchForContactUpdatesFrom:contactsManager
untillCancelled:nil];
}
return e;

@ -84,45 +84,31 @@
if ([interaction isKindOfClass:[TSCall class]])
{
TSCall * callInteraction = (TSCall*)interaction;
BOOL isOutgoing = callInteraction.wasCaller;
switch (callInteraction.callType) {
case TSCallTypeSuccess:
return isOutgoing ? TSLastActionCallOutgoing : TSLastActionCallIncoming;
break;
case TSCallTypeMissed:
return isOutgoing ? TSLastActionCallOutgoingMissed : TSLastActionCallIncomingMissed;
break;
case TSCallTypeBusy:
return isOutgoing ? TSLastActionCallOutgoingMissed : TSLastActionCallIncomingMissed;
break;
case TSCallTypeFailed:
return isOutgoing ? TSLastActionCallOutgoingFailed : TSLastActionNone;
break;
case RPRecentCallTypeMissed:
return TSLastActionCallIncomingMissed;
case RPRecentCallTypeIncoming:
return TSLastActionCallIncoming;
case RPRecentCallTypeOutgoing:
return TSLastActionCallOutgoing;
default:
return TSLastActionNone;
break;
}
} else if ([interaction isKindOfClass:[TSOutgoingMessage class]]) {
TSOutgoingMessage * outgoingMessageInteraction = (TSOutgoingMessage*)interaction;
switch (outgoingMessageInteraction.messageState) {
case TSOutgoingMessageStateAttemptingOut:
return TSLastActionNone;
break;
case TSOutgoingMessageStateUnsent:
return TSLastActionMessageUnsent;
break;
case TSOutgoingMessageStateSent:
return TSLastActionMessageSent;
break;
case TSOutgoingMessageStateDelivered:
return TSLastActionMessageDelivered;
break;
default:
return TSLastActionNone;
break;
}
} else if ([interaction isKindOfClass:[TSIncomingMessage class]]) {

@ -11,23 +11,15 @@
#import "TSInteraction.h"
#import "Contact.h"
@interface TSCall : TSInteraction
#import "RecentCall.h"
typedef NS_ENUM(NSInteger, TSCallType) {
TSCallTypeSuccess,
TSCallTypeMissed,
TSCallTypeBusy,
TSCallTypeFailed
};
@interface TSCall : TSInteraction
@property (nonatomic, readonly) NSNumber *duration;
@property (nonatomic, readonly) BOOL wasCaller;
@property (nonatomic, readonly) TSCallType callType;
@property (nonatomic) NSString *redPhoneNumber;
@property (nonatomic, readonly)RPRecentCallType callType;
- (instancetype)initWithTimestamp:(uint64_t)timeStamp
withCallNumber:(NSString*)contactNumber
wasCaller:(BOOL)caller callType:(TSCallType)callType
duration:(NSNumber*)duration;
callType:(RPRecentCallType)callType
inThread:(TSContactThread*)thread;
@end

@ -12,19 +12,27 @@
- (instancetype)initWithTimestamp:(uint64_t)timeStamp
withCallNumber:(NSString*)contactNumber
wasCaller:(BOOL)caller callType:(TSCallType)callType
duration:(NSNumber*)duration
callType:(RPRecentCallType)callType
inThread:(TSContactThread*)thread
{
self = [super initWithTimestamp:timeStamp inThread:nil];
self = [super initWithTimestamp:timeStamp inThread:thread];
if (self) {
_wasCaller = caller;
_callType = callType;
_duration = duration;
_redPhoneNumber = contactNumber;
}
return self;
}
- (NSString*)description{
switch (_callType) {
case RPRecentCallTypeIncoming:
return @"Incoming call";
case RPRecentCallTypeOutgoing:
return @"Outgoing call";
case RPRecentCallTypeMissed:
return @"Missed call";
}
}
@end

@ -190,7 +190,7 @@
}
}];
if(ignoreMessage) {
DDLogDebug(@"recevied message from group that I left, ignoring");
DDLogDebug(@"Received message from group that I left, ignoring");
return;
}

@ -113,7 +113,7 @@
PhoneNumber *phoneNumber = self.phoneNumberForCurrentInput;
BOOL shouldTryCall = [Environment.getCurrent.phoneDirectoryManager.getCurrentFilter containsPhoneNumber:phoneNumber] || [Environment.getCurrent.recentCallManager isPhoneNumberPresentInRecentCalls:phoneNumber];
BOOL shouldTryCall = [Environment.getCurrent.phoneDirectoryManager.getCurrentFilter containsPhoneNumber:phoneNumber];
if (shouldTryCall){
[self initiateCallToPhoneNumber:phoneNumber];

@ -377,7 +377,7 @@
[[UIPasteboard generalPasteboard] setImage:self.image];
break;
default:
DDLogWarn(@"Illegal Action sheet field #%ld <%s>",tappedButtonIndex, __PRETTY_FUNCTION__);
DDLogWarn(@"Illegal Action sheet field #%ld <%s>",(long)tappedButtonIndex, __PRETTY_FUNCTION__);
break;
}
}

@ -56,7 +56,7 @@
self.detailLabel.text = @"Low";
break;
default:
DDLogWarn(@"Unknown Image Quality setting : %ld <%s>", [Environment.preferences imageUploadQuality], __PRETTY_FUNCTION__);
DDLogWarn(@"Unknown Image Quality setting : %lu <%s>", [Environment.preferences imageUploadQuality], __PRETTY_FUNCTION__);
break;
}
}

@ -17,7 +17,7 @@
@interface TSMessageAdapter : NSObject <JSQMessageData>
+ (instancetype)messageViewDataWithInteraction:(TSInteraction*)interaction inThread:(TSThread*)thread;
+ (id<JSQMessageData>)messageViewDataWithInteraction:(TSInteraction*)interaction inThread:(TSThread*)thread;
@property TSMessageAdapterType messageType;

@ -6,6 +6,9 @@
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
//
#import "JSQCall.h"
#import "NSDate+millisecondTimeStamp.h"
#import "TSMessageAdapter.h"
#import "TSIncomingMessage.h"
#import "TSOutgoingMessage.h"
@ -119,6 +122,7 @@
} else if ([interaction isKindOfClass:[TSCall class]]){
adapter.messageBody = @"Placeholder for TSCalls";
adapter.messageType = TSCallAdapter;
return [self jsqCallForTSCall:(TSCall*)interaction thread:(TSContactThread*)thread];
} else if ([interaction isKindOfClass:[TSInfoMessage class]]){
TSInfoMessage * infoMessage = (TSInfoMessage*)interaction;
adapter.infoMessageType = infoMessage.messageType;
@ -138,6 +142,25 @@
return adapter;
}
+ (JSQCall*)jsqCallForTSCall:(TSCall*)call thread:(TSContactThread*)thread{
CallStatus status = 0;
switch (call.callType) {
case RPRecentCallTypeOutgoing:
status = kCallOutgoing;
break;
case RPRecentCallTypeMissed:
status = kCallMissed;
break;
case RPRecentCallTypeIncoming:
status = kCallIncoming;
break;
}
JSQCall *jsqCall = [[JSQCall alloc] initWithCallerId:thread.contactIdentifier callerDisplayName:thread.name date:call.date status:status];
return jsqCall;
}
- (NSString*)senderId{
if (_senderId) {
return _senderId;

Loading…
Cancel
Save