1
0
mirror of https://github.com/danog/Telegram.git synced 2024-12-03 09:57:46 +01:00
Telegram/Telegraph/TGChatListSignals.m
2016-02-25 01:03:51 +01:00

241 lines
8.0 KiB
Objective-C

#import "TGChatListSignals.h"
#import "TGDatabase.h"
#import "ActionStage.h"
#import "TGTelegraph.h"
@interface TGChatListAdapter : NSObject <ASWatcher>
{
NSMutableArray *_list;
void (^_listUpdated)(NSArray *);
NSUInteger _limit;
}
@property (nonatomic, strong) ASHandle *actionHandle;
@end
@implementation TGChatListAdapter
- (instancetype)initWithList:(NSArray *)list limit:(NSUInteger)limit listUpdated:(void (^)(NSArray *))listUpdated
{
self = [super init];
if (self != nil)
{
_actionHandle = [[ASHandle alloc] initWithDelegate:self];
[ActionStageInstance() watchForPaths:@[
@"/tg/conversations",
@"/tg/broadcastConversations",
@"/tg/channelListSyncrhonized",
@"/dialogListReloaded"
] watcher:self];
_list = [[NSMutableArray alloc] init];
[_list addObjectsFromArray:list];
_limit = limit;
_listUpdated = [listUpdated copy];
}
return self;
}
- (void)dealloc
{
[_actionHandle reset];
[ActionStageInstance() removeWatcher:self];
}
- (void)actionStageResourceDispatched:(NSString *)path resource:(id)resource arguments:(id)__unused arguments
{
if ([path isEqualToString:@"/dialogListReloaded"])
{
[TGDatabaseInstance() loadConversationListFromDate:INT_MAX limit:(int)_limit excludeConversationIds:@[] completion:^(NSArray *chatList, __unused bool loadedAllRegular)
{
[ActionStageInstance() dispatchOnStageQueue:^
{
[_list removeAllObjects];
for (TGConversation *conversation in chatList) {
if (!conversation.isDeactivated) {
[_list addObject:conversation];
}
}
NSArray *items = [NSArray arrayWithArray:_list];
if (_listUpdated)
_listUpdated(items);
}];
}];
}
else if ([path isEqualToString:@"/tg/conversations"] || [path isEqualToString:@"/tg/broadcastConversations"])
{
NSMutableArray *conversations = [((SGraphObjectNode *)resource).object mutableCopy];
if (conversations.count == 0)
return;
for (NSInteger i = 0; i < (NSInteger)conversations.count; i++)
{
TGConversation *conversation = conversations[i];
if (conversation.isChannel && conversation.kind != TGConversationKindPersistentChannel) {
[conversations removeObjectAtIndex:i];
i--;
}
if (conversation.isDeactivated) {
[conversations removeObjectAtIndex:i];
i--;
}
}
[conversations sortUsingComparator:^NSComparisonResult(id obj1, id obj2)
{
int date1 = (int)((TGConversation *)obj1).date;
int date2 = (int)((TGConversation *)obj2).date;
if (date1 < date2)
return NSOrderedAscending;
else if (date1 > date2)
return NSOrderedDescending;
else
return NSOrderedSame;
}];
NSMutableDictionary *conversationIdToIndex = [[NSMutableDictionary alloc] init];
int index = -1;
for (TGConversation *conversation in _list)
{
index++;
int64_t conversationId = conversation.conversationId;
conversationIdToIndex[@(conversationId)] = @(index);
}
for (int i = 0; i < (int)conversations.count; i++)
{
TGConversation *conversation = [conversations objectAtIndex:i];
int64_t conversationId = conversation.conversationId;
NSNumber *conversationIndex = conversationIdToIndex[@(conversationId)];
if (conversationIndex != nil)
{
TGConversation *newConversation = [conversation copy];
if (!newConversation.isDeleted)
{
//[self initializeDialogListData:newConversation customUser:nil selfUser:selfUser];
}
[_list replaceObjectAtIndex:[conversationIndex unsignedIntegerValue] withObject:newConversation];
[conversations removeObjectAtIndex:i];
i--;
}
}
for (int i = 0; i < (int)_list.count; i++)
{
TGConversation *conversation = [_list objectAtIndex:i];
if (conversation.isDeleted)
{
[_list removeObjectAtIndex:i];
i--;
}
}
for (TGConversation *conversation in conversations)
{
TGConversation *newConversation = [conversation copy];
if (!newConversation.isDeleted)
{
//[self initializeDialogListData:newConversation customUser:nil selfUser:selfUser];
[_list addObject:newConversation];
}
}
[_list sortUsingComparator:^NSComparisonResult(id obj1, id obj2)
{
int date1 = (int)((TGConversation *)obj1).date;
int date2 = (int)((TGConversation *)obj2).date;
if (date1 < date2)
return NSOrderedDescending;
else if (date1 > date2)
return NSOrderedAscending;
else
return NSOrderedSame;
}];
NSArray *items = [NSArray arrayWithArray:_list];
if (_listUpdated)
_listUpdated(items);
}
else if ([path isEqualToString:@"/tg/channelListSyncrhonized"]) {
[self actionStageResourceDispatched:@"/tg/conversations" resource:[[SGraphObjectNode alloc] initWithObject:resource] arguments:@{@"filterEarliest": @true}];
}
}
@end
@implementation TGChatListSignals
+ (SSignal *)currentChatListWithLimit:(NSUInteger)limit
{
return [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
{
[TGDatabaseInstance() loadConversationListFromDate:INT_MAX limit:(int)limit excludeConversationIds:@[] completion:^(NSArray *chatList, __unused bool loadedAllRegular)
{
NSMutableArray *filteredResult = [[NSMutableArray alloc] initWithArray:chatList];
[filteredResult sortUsingComparator:^NSComparisonResult(TGConversation *lhs, TGConversation *rhs) {
if (lhs.date > rhs.date) {
return NSOrderedAscending;
} else if (lhs.date < rhs.date) {
return NSOrderedDescending;
} else {
if (lhs.conversationId < rhs.conversationId) {
return NSOrderedDescending;
} else {
return NSOrderedAscending;
}
}
}];
for (NSUInteger i = 0; i < filteredResult.count; i++)
{
TGConversation *conversation = filteredResult[i];
if (conversation.isChannel && conversation.kind != TGConversationKindPersistentChannel)
{
[filteredResult removeObjectAtIndex:i];
i--;
}
}
[subscriber putNext:filteredResult];
[subscriber putCompletion];
}];
return nil;
}];
}
+ (SSignal *)chatListWithLimit:(NSUInteger)limit
{
__block NSArray *initialList = nil;
SSignal *incrementalSignal = [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
{
TGChatListAdapter *adapter = [[TGChatListAdapter alloc] initWithList:initialList limit:limit listUpdated:^(NSArray *list)
{
[subscriber putNext:list];
}];
return [[SBlockDisposable alloc] initWithBlock:^
{
[adapter description];
}];
}];
return [[[self currentChatListWithLimit:limit] onNext:^(id next)
{
initialList = next;
}] then:incrementalSignal];
}
@end