mirror of
https://github.com/danog/Telegram.git
synced 2024-12-04 02:17:51 +01:00
338 lines
11 KiB
Objective-C
338 lines
11 KiB
Objective-C
#import "TGGroupInfoController.h"
|
|
|
|
#import "TGStringUtils.h"
|
|
|
|
#import "TGBridgeContext.h"
|
|
#import "TGBridgeConversationSignals.h"
|
|
#import "TGBridgePeerSettingsSignals.h"
|
|
#import "TGBridgeChat.h"
|
|
#import "TGBridgeUser.h"
|
|
|
|
#import "WKInterfaceTable+TGDataDrivenTable.h"
|
|
#import "TGTableDeltaUpdater.h"
|
|
#import "TGInterfaceMenu.h"
|
|
|
|
#import "TGGroupInfoHeaderController.h"
|
|
#import "TGGroupInfoFooterController.h"
|
|
#import "TGUserRowController.h"
|
|
|
|
#import "TGInputController.h"
|
|
#import "TGUserInfoController.h"
|
|
#import "TGContactsController.h"
|
|
#import "TGProfilePhotoController.h"
|
|
|
|
NSString *const TGGroupInfoControllerIdentifier = @"TGGroupInfoController";
|
|
|
|
@implementation TGGroupInfoControllerContext
|
|
|
|
- (instancetype)initWithGroupChat:(TGBridgeChat *)groupChat
|
|
{
|
|
self = [super init];
|
|
if (self != nil)
|
|
{
|
|
_groupChat = groupChat;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
@end
|
|
|
|
@interface TGGroupInfoController () <TGTableDataSource>
|
|
{
|
|
SMetaDisposable *_chatDisposable;
|
|
SMetaDisposable *_peerSettingsDisposable;
|
|
SMetaDisposable *_updateSettingsDisposable;
|
|
|
|
TGInterfaceMenu *_menu;
|
|
|
|
TGGroupInfoControllerContext *_context;
|
|
TGBridgeChat *_chatModel;
|
|
NSDictionary *_userModels;
|
|
NSArray *_participantsModels;
|
|
NSArray *_currentParticipantsModels;
|
|
bool _muted;
|
|
|
|
NSDictionary *_preferredParticipantsOrder;
|
|
}
|
|
@end
|
|
|
|
@implementation TGGroupInfoController
|
|
|
|
- (instancetype)init
|
|
{
|
|
self = [super init];
|
|
if (self != nil)
|
|
{
|
|
_chatDisposable = [[SMetaDisposable alloc] init];
|
|
_peerSettingsDisposable = [[SMetaDisposable alloc] init];
|
|
_updateSettingsDisposable = [[SMetaDisposable alloc] init];
|
|
|
|
[self.table _setInitialHidden:true];
|
|
self.table.tableDataSource = self;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
[_chatDisposable dispose];
|
|
[_peerSettingsDisposable dispose];
|
|
[_updateSettingsDisposable dispose];
|
|
}
|
|
|
|
- (void)configureWithContext:(TGGroupInfoControllerContext *)context
|
|
{
|
|
_context = context;
|
|
|
|
self.title = TGLocalized(@"Watch.GroupInfo.Title");
|
|
|
|
__weak TGGroupInfoController *weakSelf = self;
|
|
[_chatDisposable setDisposable:[[[TGBridgeConversationSignals conversationWithPeerId:_context.groupChat.identifier] deliverOn:[SQueue mainQueue]] startWithNext:^(NSDictionary *models)
|
|
{
|
|
__strong TGGroupInfoController *strongSelf = weakSelf;
|
|
if (strongSelf == nil)
|
|
return;
|
|
|
|
strongSelf->_chatModel = models[TGBridgeChatKey];
|
|
strongSelf->_userModels = models[TGBridgeUsersDictionaryKey];
|
|
|
|
NSMutableArray *participantsModels = [[NSMutableArray alloc] init];
|
|
for (NSNumber *uid in strongSelf->_chatModel.participants)
|
|
{
|
|
TGBridgeUser *user = strongSelf->_userModels[uid];
|
|
if (user != nil)
|
|
[participantsModels addObject:user];
|
|
}
|
|
|
|
participantsModels = [TGGroupInfoController sortedParticipantsList:participantsModels preferredOrder:strongSelf->_preferredParticipantsOrder ownUid:strongSelf->_context.context.userId];
|
|
strongSelf->_preferredParticipantsOrder = [TGGroupInfoController participantsOrderForList:participantsModels];
|
|
|
|
strongSelf->_participantsModels = participantsModels;
|
|
|
|
[strongSelf performInterfaceUpdate:^(bool animated)
|
|
{
|
|
strongSelf.activityIndicator.hidden = true;
|
|
strongSelf.table.hidden = false;
|
|
|
|
NSArray *currentParticipantsModels = strongSelf->_currentParticipantsModels;
|
|
bool initial = (currentParticipantsModels == 0);
|
|
|
|
strongSelf->_currentParticipantsModels = strongSelf->_participantsModels;
|
|
|
|
if (animated && !initial)
|
|
{
|
|
[TGTableDeltaUpdater updateTable:strongSelf.table oldData:currentParticipantsModels newData:strongSelf->_currentParticipantsModels controllerClassForIndexPath:^Class(TGIndexPath *indexPath)
|
|
{
|
|
return [strongSelf table:strongSelf->_table rowControllerClassAtIndexPath:indexPath];
|
|
}];
|
|
|
|
[strongSelf.table reloadHeader];
|
|
[strongSelf.table reloadFooter];
|
|
}
|
|
else
|
|
{
|
|
[strongSelf.table reloadData];
|
|
}
|
|
}];
|
|
|
|
} error:^(id error)
|
|
{
|
|
|
|
} completed:^
|
|
{
|
|
|
|
}]];
|
|
|
|
[_peerSettingsDisposable setDisposable:[[TGBridgePeerSettingsSignals peerSettingsWithPeerId:_context.groupChat.identifier] startWithNext:^(NSDictionary *next)
|
|
{
|
|
__strong TGGroupInfoController *strongSelf = weakSelf;
|
|
if (strongSelf == nil)
|
|
return;
|
|
|
|
TGBridgePeerNotificationSettings *settings = next[@"notifications"];
|
|
bool muted = (settings.muteFor > 0);
|
|
|
|
if (strongSelf->_menu == nil || muted != strongSelf->_muted)
|
|
{
|
|
strongSelf->_muted = muted;
|
|
|
|
[strongSelf performInterfaceUpdate:^(bool animated)
|
|
{
|
|
[strongSelf updateMenuItemsMuted:strongSelf->_muted];
|
|
}];
|
|
}
|
|
}]];
|
|
}
|
|
|
|
- (void)willActivate
|
|
{
|
|
[super willActivate];
|
|
|
|
[self.table notifyVisiblityChange];
|
|
}
|
|
|
|
- (void)didDeactivate
|
|
{
|
|
[super didDeactivate];
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
- (void)updateMenuItemsMuted:(bool)muted
|
|
{
|
|
[_menu clearItems];
|
|
|
|
if (_menu == nil)
|
|
_menu = [[TGInterfaceMenu alloc] initForInterfaceController:self];
|
|
|
|
__weak TGGroupInfoController *weakSelf = self;
|
|
|
|
NSMutableArray *menuItems = [[NSMutableArray alloc] init];
|
|
|
|
bool muteForever = true;
|
|
int32_t muteFor = muteForever ? INT_MAX : 1;
|
|
NSString *muteTitle = muteForever ? TGLocalized(@"Watch.UserInfo.Mute") : [NSString stringWithFormat:TGLocalized([TGStringUtils integerValueFormat:@"Watch.UserInfo.Mute_" value:muteFor]), muteFor];
|
|
|
|
TGInterfaceMenuItem *muteItem = [[TGInterfaceMenuItem alloc] initWithItemIcon:muted ? WKMenuItemIconSpeaker : WKMenuItemIconMute title:muted ? TGLocalized(@"Watch.UserInfo.Unmute") : muteTitle actionBlock:^(TGInterfaceController *controller, TGInterfaceMenuItem *sender)
|
|
{
|
|
__strong TGGroupInfoController *strongSelf = weakSelf;
|
|
if (strongSelf == nil)
|
|
return;
|
|
|
|
TGBridgePeerNotificationSettings *settings = [[TGBridgePeerNotificationSettings alloc] init];
|
|
settings.muteFor = muted ? 0 : (muteFor == INT_MAX ? INT_MAX : muteFor * 60 * 60);
|
|
[strongSelf->_updateSettingsDisposable setDisposable:[[TGBridgePeerSettingsSignals updateNotificationSettingsWithPeerId:strongSelf->_context.groupChat.identifier settings:settings] startWithNext:nil completed:^
|
|
{
|
|
__strong TGGroupInfoController *strongSelf = weakSelf;
|
|
if (strongSelf == nil)
|
|
return;
|
|
|
|
strongSelf->_muted = !muted;
|
|
[strongSelf updateMenuItemsMuted:strongSelf->_muted];
|
|
}]];
|
|
}];
|
|
[menuItems addObject:muteItem];
|
|
|
|
[_menu addItems:menuItems];
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
- (Class)headerControllerClassForTable:(WKInterfaceTable *)table
|
|
{
|
|
return [TGGroupInfoHeaderController class];
|
|
}
|
|
|
|
- (void)table:(WKInterfaceTable *)table updateHeaderController:(TGGroupInfoHeaderController *)controller
|
|
{
|
|
__weak TGGroupInfoController *weakSelf = self;
|
|
controller.isVisible = ^bool
|
|
{
|
|
__strong TGGroupInfoController *strongSelf = weakSelf;
|
|
if (strongSelf == nil)
|
|
return false;
|
|
|
|
return strongSelf.isVisible;
|
|
};
|
|
controller.avatarPressed = ^
|
|
{
|
|
__strong TGGroupInfoController *strongSelf = weakSelf;
|
|
if (strongSelf == nil)
|
|
return;
|
|
|
|
TGProfilePhotoControllerContext *context = [[TGProfilePhotoControllerContext alloc] initWithImageUrl:strongSelf->_chatModel.groupPhotoSmall];
|
|
[strongSelf pushControllerWithClass:[TGProfilePhotoController class] context:context];
|
|
};
|
|
|
|
[controller updateWithGroupChat:_chatModel users:_userModels context:_context.context];
|
|
}
|
|
|
|
- (void)table:(WKInterfaceTable *)table updateFooterController:(TGGroupInfoFooterController *)controller
|
|
{
|
|
|
|
}
|
|
|
|
- (Class)table:(WKInterfaceTable *)table rowControllerClassAtIndexPath:(NSIndexPath *)indexPath
|
|
{
|
|
return [TGUserRowController class];
|
|
}
|
|
|
|
- (NSUInteger)numberOfRowsInTable:(WKInterfaceTable *)table section:(NSUInteger)section
|
|
{
|
|
return _currentParticipantsModels.count;
|
|
}
|
|
|
|
- (void)table:(WKInterfaceTable *)table updateRowController:(TGUserRowController *)controller forIndexPath:(TGIndexPath *)indexPath
|
|
{
|
|
__weak TGGroupInfoController *weakSelf = self;
|
|
controller.isVisible = ^bool
|
|
{
|
|
__strong TGGroupInfoController *strongSelf = weakSelf;
|
|
if (strongSelf == nil)
|
|
return false;
|
|
|
|
return strongSelf.isVisible;
|
|
};
|
|
[controller updateWithUser:_currentParticipantsModels[indexPath.row] context:_context.context];
|
|
}
|
|
|
|
- (id<TGInterfaceContext>)contextForSegueWithIdentifer:(NSString *)segueIdentifier table:(WKInterfaceTable *)table indexPath:(TGIndexPath *)indexPath
|
|
{
|
|
return [[TGUserInfoControllerContext alloc] initWithUser:_currentParticipantsModels[indexPath.row]];
|
|
}
|
|
|
|
+ (NSMutableArray *)sortedParticipantsList:(NSMutableArray *)list preferredOrder:(NSDictionary *)preferredOrder ownUid:(int32_t)ownUid
|
|
{
|
|
NSMutableArray *resultList = [list mutableCopy];
|
|
|
|
[resultList sortUsingComparator:^NSComparisonResult(TGBridgeUser *user1, TGBridgeUser *user2)
|
|
{
|
|
if (user1.identifier == ownUid)
|
|
return NSOrderedAscending;
|
|
else if (user2.identifier == ownUid)
|
|
return NSOrderedDescending;
|
|
|
|
NSNumber *order1 = preferredOrder[@(user1.identifier)];
|
|
NSNumber *order2 = preferredOrder[@(user2.identifier)];
|
|
|
|
if (order1 != nil && order2 != nil)
|
|
return order1.integerValue < order2.integerValue ? NSOrderedAscending : NSOrderedDescending;
|
|
|
|
if (user1.isOnline != user2.isOnline)
|
|
return user1.isOnline ? NSOrderedAscending : NSOrderedDescending;
|
|
|
|
if ((user1.lastSeen < 0) != (user2.lastSeen < 0))
|
|
return user1.lastSeen >= 0 ? NSOrderedAscending : NSOrderedDescending;
|
|
|
|
if (user1.isOnline || user1.lastSeen < 0)
|
|
return user1.identifier < user2.identifier ? NSOrderedAscending : NSOrderedDescending;
|
|
|
|
return user1.lastSeen > user2.lastSeen ? NSOrderedAscending : NSOrderedDescending;
|
|
}];
|
|
|
|
return resultList;
|
|
}
|
|
|
|
+ (NSDictionary *)participantsOrderForList:(NSArray *)list
|
|
{
|
|
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
|
|
|
|
NSInteger i = 0;
|
|
for (TGBridgeUser *user in list)
|
|
{
|
|
dictionary[@(user.identifier)] = @(i);
|
|
i++;
|
|
}
|
|
|
|
return dictionary;
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
+ (NSString *)identifier
|
|
{
|
|
return TGGroupInfoControllerIdentifier;
|
|
}
|
|
|
|
@end
|