108 lines
4.1 KiB
Objective-C
108 lines
4.1 KiB
Objective-C
#import "RecentCallManager.h"
|
|
#import "ContactsManager.h"
|
|
#import "FunctionalUtil.h"
|
|
#import "ObservableValue.h"
|
|
#import "PreferencesUtil.h"
|
|
#import "PushManager.h"
|
|
#import "NSDate+millisecondTimeStamp.h"
|
|
#import "TSCall.h"
|
|
#import "TSContactThread.h"
|
|
#import "TSMessagesManager.h"
|
|
#import "TSStorageManager.h"
|
|
|
|
@interface RecentCallManager ()
|
|
@property YapDatabaseConnection *dbConnection;
|
|
@end
|
|
|
|
@implementation RecentCallManager
|
|
|
|
- (instancetype)init{
|
|
self = [super init];
|
|
|
|
if (self) {
|
|
_dbConnection = [TSStorageManager sharedManager].newDatabaseConnection;
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void)watchForCallsThrough:(PhoneManager*)phoneManager
|
|
untilCancelled:(TOCCancelToken*)untilCancelledToken {
|
|
require(phoneManager != nil);
|
|
|
|
[phoneManager.currentCallObservable watchLatestValue:^(CallState* latestCall) {
|
|
if (latestCall != nil) {
|
|
[self addCall:latestCall];
|
|
}
|
|
} onThread:NSThread.currentThread untilCancelled:untilCancelledToken];
|
|
}
|
|
|
|
- (void)addCall:(CallState*)call {
|
|
require(call != nil);
|
|
|
|
[call.futureTermination finallyDo:^(TOCFuture* interactionCompletion) {
|
|
bool isOutgoingCall = call.initiatedLocally;
|
|
bool isMissedCall = [self isMissedCall:interactionCompletion];
|
|
|
|
Contact* contact = [self tryGetContactForCall:call];
|
|
|
|
RPRecentCallType callType = isOutgoingCall ? RPRecentCallTypeOutgoing
|
|
: isMissedCall ? RPRecentCallTypeMissed
|
|
: RPRecentCallTypeIncoming;
|
|
|
|
[self addRecentCall:[RecentCall recentCallWithContactID:contact.recordID
|
|
andNumber:call.remoteNumber
|
|
andCallType:callType]];
|
|
}];
|
|
}
|
|
|
|
- (BOOL)isMissedCall:(TOCFuture*)interactionCompletion {
|
|
if ([interactionCompletion hasResult]) {
|
|
if ([[interactionCompletion forceGetResult] isKindOfClass:[CallTermination class]]) {
|
|
CallTermination *termination = (CallTermination*)interactionCompletion.forceGetResult;
|
|
if (termination.type == CallTerminationType_HangupRemote) {
|
|
return YES;
|
|
}
|
|
}
|
|
}
|
|
return NO;
|
|
}
|
|
|
|
- (Contact*)tryGetContactForCall:(CallState*)call {
|
|
if (call.potentiallySpecifiedContact != nil) return call.potentiallySpecifiedContact;
|
|
return [self tryGetContactForNumber:call.remoteNumber];
|
|
}
|
|
|
|
- (Contact*)tryGetContactForNumber:(PhoneNumber*)number {
|
|
return [Environment.getCurrent.contactsManager latestContactForPhoneNumber:number];
|
|
}
|
|
|
|
- (void)addMissedCallDueToBusy:(ResponderSessionDescriptor*)incomingCallDescriptor {
|
|
require(incomingCallDescriptor != nil);
|
|
|
|
Contact* contact = [self tryGetContactForNumber:incomingCallDescriptor.initiatorNumber];
|
|
[self addRecentCall:[RecentCall recentCallWithContactID:contact.recordID
|
|
andNumber:incomingCallDescriptor.initiatorNumber
|
|
andCallType:RPRecentCallTypeMissed]];
|
|
}
|
|
|
|
- (void)addRecentCall:(RecentCall*)recentCall {
|
|
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
|
TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactId:recentCall.phoneNumber.toE164 transaction:transaction];
|
|
|
|
uint64_t callDateSeconds = (uint64_t)[recentCall.date timeIntervalSince1970];
|
|
TSCall *call = [[TSCall alloc] initWithTimestamp:callDateSeconds*1000 withCallNumber:recentCall.phoneNumber.toE164 callType:recentCall.callType inThread:thread];
|
|
if(recentCall.isArchived) { //for migration only from Signal versions with RedPhone only
|
|
NSDate *date = [NSDate dateWithTimeIntervalSince1970:(callDateSeconds+60)]; // archive has to happen in the future of the original call
|
|
[thread archiveThreadWithTransaction:transaction referenceDate:date];
|
|
}
|
|
|
|
[call saveWithTransaction:transaction];
|
|
|
|
[[TSMessagesManager sharedManager] notifyUserForCall:call inThread:thread];
|
|
}];
|
|
}
|
|
|
|
|
|
@end
|