1
0
mirror of https://github.com/danog/Telegram.git synced 2024-12-04 02:17:51 +01:00
Telegram/Watch/Bridge/TGBridgeAudioSignals.m
2016-02-25 01:03:51 +01:00

170 lines
5.0 KiB
Objective-C

#import "TGBridgeAudioSignals.h"
#import "TGBridgeAudioSubscription.h"
#import "TGBridgeAudioMediaAttachment.h"
#import "TGBridgeResponse.h"
#import "TGBridgeClient.h"
#import "TGFileCache.h"
#import "TGBridgeMessage.h"
#import "TGExtensionDelegate.h"
#import <libkern/OSAtomic.h>
@interface TGBridgeAudioManager : NSObject
{
NSMutableArray *_pendingUrls;
OSSpinLock _pendingUrlsLock;
}
@end
@implementation TGBridgeAudioManager
- (instancetype)init
{
self = [super init];
if (self != nil)
{
_pendingUrls = [[NSMutableArray alloc] init];
}
return self;
}
- (void)addUrl:(NSString *)url
{
OSSpinLockLock(&_pendingUrlsLock);
[_pendingUrls addObject:url];
OSSpinLockUnlock(&_pendingUrlsLock);
}
- (void)removeUrl:(NSString *)url
{
OSSpinLockLock(&_pendingUrlsLock);
[_pendingUrls removeObject:url];
OSSpinLockUnlock(&_pendingUrlsLock);
}
- (bool)hasUrl:(NSString *)url
{
OSSpinLockLock(&_pendingUrlsLock);
bool contains = [_pendingUrls containsObject:url];
OSSpinLockUnlock(&_pendingUrlsLock);
return contains;
}
@end
@implementation TGBridgeAudioSignals
+ (SSignal *)audioForAttachment:(TGBridgeMediaAttachment *)attachment conversationId:(int64_t)conversationId messageId:(int32_t)messageId
{
NSString *url = nil;
if ([attachment isKindOfClass:[TGBridgeAudioMediaAttachment class]])
url = [NSString stringWithFormat:@"%lld", ((TGBridgeAudioMediaAttachment *)attachment).identifier];
else
url = [NSString stringWithFormat:@"%lld", ((TGBridgeDocumentMediaAttachment *)attachment).documentId];
SSignal *remoteSignal = [[[[TGBridgeClient instance] requestSignalWithSubscription:[[TGBridgeAudioSubscription alloc] initWithAttachment:attachment conversationId:conversationId messageId:messageId]] onDispose:^
{
// cancel download
}] mapToSignal:^SSignal *(__unused id next)
{
return [self _downloadedFileWithUrl:url];
}];
return [[self _cachedOrPendingWithUrl:url] catch:^SSignal *(id error)
{
return remoteSignal;
}];
}
+ (SSignal *)_loadCachedWithUrl:(NSString *)url
{
return [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
{
TGFileCache *audioCache = [TGExtensionDelegate instance].audioCache;
if ([audioCache hasDataForKey:url])
{
[subscriber putNext:[audioCache urlForKey:url]];
[subscriber putCompletion];
}
else
{
[subscriber putError:nil];
}
return nil;
}];
}
+ (SSignal *)_downloadedFileWithUrl:(NSString *)url
{
return [[self _loadCachedWithUrl:url] catch:^SSignal *(id error)
{
return [[[TGBridgeClient instance] fileSignalForKey:url] take:1];
}];
}
+ (SSignal *)_cachedOrPendingWithUrl:(NSString *)url
{
return [[self _loadCachedWithUrl:url] catch:^SSignal *(id error)
{
if ([[self audioManager] hasUrl:url])
return [self _downloadedFileWithUrl:url];
return [SSignal fail:nil];
}];
}
+ (SSignal *)sentAudioForConversationId:(int64_t)conversationId
{
return [[[TGBridgeClient instance] requestSignalWithSubscription:[[TGBridgeAudioSentSubscription alloc] initWithConversationId:conversationId]] onNext:^(TGBridgeMessage *next)
{
int64_t identifier = 0;
int64_t localIdentifier = 0;
for (TGBridgeMediaAttachment *attachment in next.media)
{
if ([attachment isKindOfClass:[TGBridgeAudioMediaAttachment class]])
{
identifier = ((TGBridgeAudioMediaAttachment *)attachment).audioId;
localIdentifier = ((TGBridgeAudioMediaAttachment *)attachment).localAudioId;
}
else if ([attachment isKindOfClass:[TGBridgeDocumentMediaAttachment class]])
{
identifier = ((TGBridgeDocumentMediaAttachment *)attachment).documentId;
localIdentifier = ((TGBridgeDocumentMediaAttachment *)attachment).localDocumentId;
}
}
if (identifier != 0 && localIdentifier != 0)
{
TGFileCache *audioCache = [[TGExtensionDelegate instance] audioCache];
NSString *localId = [NSString stringWithFormat:@"%lld", localIdentifier];
NSString *audioId = [NSString stringWithFormat:@"%lld", identifier];
if ([audioCache hasDataForKey:localId] && ![audioCache hasDataForKey:audioId])
{
NSURL *localUrl = [audioCache urlForKey:localId];
NSURL *remoteUrl = [audioCache urlForKey:audioId];
[[NSFileManager defaultManager] moveItemAtURL:localUrl toURL:remoteUrl error:nil];
}
}
}];
}
+ (TGBridgeAudioManager *)audioManager
{
static dispatch_once_t onceToken;
static TGBridgeAudioManager *manager;
dispatch_once(&onceToken, ^
{
manager = [[TGBridgeAudioManager alloc] init];
});
return manager;
}
@end