1
0
mirror of https://github.com/danog/Telegram.git synced 2024-12-11 08:59:48 +01:00
Telegram/Watch/Extension/TGNeoChatRowController.m
2016-02-25 01:03:51 +01:00

210 lines
6.3 KiB
Objective-C

#import "TGNeoChatRowController.h"
#import "TGBridgeContext.h"
#import "TGBridgeChat.h"
#import "TGBridgeUser.h"
#import "TGBridgeUserCache.h"
#import "TGNeoChatViewModel.h"
#import "TGAvatarViewModel.h"
NSString *const TGNeoChatRowIdentifier = @"TGNeoChatRow";
@interface TGNeoChatRowController ()
{
TGBridgeChat *_currentChat;
NSDictionary *_currentUsers;
TGNeoChatViewModel *_viewModel;
SMetaDisposable *_renderDisposable;
TGAvatarViewModel *_avatarViewModel;
bool _pendingRendering;
}
@end
@implementation TGNeoChatRowController
- (instancetype)init
{
self = [super init];
if (self != nil)
{
_renderDisposable = [[SMetaDisposable alloc] init];
}
return self;
}
- (void)dealloc
{
[_renderDisposable dispose];
}
- (void)setupInterface
{
[super setupInterface];
_avatarViewModel = [[TGAvatarViewModel alloc] init];
_avatarViewModel.group = self.avatarGroup;
_avatarViewModel.label = self.avatarLabel;
[self.avatarLabel _setInitialHidden:true];
[self.statusGroup _setInitialHidden:true];
}
- (void)updateWithChat:(TGBridgeChat *)chat forForward:(bool)forForward context:(TGBridgeContext *)context
{
TGBridgeChat *oldChat = _currentChat;
_currentChat = chat;
NSDictionary *oldUsers = _currentUsers;
_currentUsers = [[TGBridgeUserCache instance] usersWithIndexSet:[chat involvedUserIds]];
bool shouldUpdate = [self shouldUpdateContentFrom:oldChat oldUsers:oldUsers to:_currentChat newUsers:_currentUsers];
if (shouldUpdate)
{
_viewModel = [[TGNeoChatViewModel alloc] initWithChat:chat users:_currentUsers context:context];
CGSize containerSize = [[WKInterfaceDevice currentDevice] screenBounds].size;
CGSize contentSize = [_viewModel layoutWithContainerSize:containerSize];
self.contentGroup.width = contentSize.width;
self.contentGroup.height = contentSize.height;
SSignal *signal = [TGNeoRenderableViewModel renderSignalForViewModel:_viewModel];
__weak TGNeoChatRowController *weakSelf = self;
[_renderDisposable setDisposable:[signal startWithNext:^(UIImage *image)
{
__strong TGNeoChatRowController *strongSelf = weakSelf;
if (strongSelf == nil)
return;
[strongSelf->_contentGroup setBackgroundImage:image];
}]];
}
if (chat.isGroup || chat.isChannel)
[_avatarViewModel updateWithChat:chat isVisible:self.isVisible];
else
[_avatarViewModel updateWithUser:_currentUsers[@(chat.identifier)] context:context isVisible:self.isVisible];
if (forForward)
return;
bool shouldUpdateStatus = [self shouldUpdateStatusFrom:oldChat to:_currentChat];
if (shouldUpdateStatus)
{
if ((chat.outgoing && chat.unread) || chat.deliveryError)
{
self.statusGroup.hidden = false;
if (chat.deliveryError)
{
self.statusGroup.width = 15;
self.statusLabel.text = @"!";
self.statusLabel.hidden = false;
self.statusGroup.backgroundColor = [UIColor hexColor:0xff4a5c];
[self.statusGroup setBackgroundImageNamed:nil];
}
else if (!(_currentChat.identifier > 0 && [_currentUsers[@(_currentChat.identifier)] isBot]) && chat.unread)
{
self.statusGroup.width = 15;
self.statusLabel.hidden = true;
self.statusGroup.backgroundColor = [UIColor clearColor];
[self.statusGroup setBackgroundImageNamed:@"StatusDot"];
}
}
else if (!chat.outgoing && chat.unreadCount > 0)
{
self.statusGroup.hidden = false;
self.statusLabel.text = [NSString stringWithFormat:@"%ld", (long)chat.unreadCount];
self.statusLabel.hidden = false;
if (chat.unreadCount < 10)
self.statusGroup.width = 15;
else
[self.statusGroup sizeToFitWidth];
self.statusGroup.backgroundColor = [UIColor hexColor:0x2ea4e5];
[self.statusGroup setBackgroundImageNamed:nil];
}
else
{
self.statusGroup.hidden = true;
}
}
}
- (bool)_nameHasChangedFrom:(NSString *)oldName newName:(NSString *)newName
{
return (![oldName isEqualToString:newName] && !(oldName == nil && newName == nil));
}
- (bool)shouldUpdateContentFrom:(TGBridgeChat *)oldChat oldUsers:(NSDictionary *)oldUsers to:(TGBridgeChat *)newChat newUsers:(NSDictionary *)newUsers
{
if (oldChat == nil)
return true;
if (oldChat.identifier != newChat.identifier)
return true;
if (newChat.isGroup || newChat.isChannelGroup)
{
if (![oldChat.groupTitle isEqualToString:newChat.groupTitle])
return true;
if (oldChat.fromUid != newChat.fromUid)
return true;
TGBridgeUser *oldUser = oldUsers[@(oldChat.fromUid)];
TGBridgeUser *newUser = newUsers[@(newChat.fromUid)];
if ([self _nameHasChangedFrom:oldUser.firstName newName:newUser.firstName] || [self _nameHasChangedFrom:oldUser.lastName newName:newUser.firstName])
return true;
}
else
{
TGBridgeUser *oldUser = oldUsers[@(oldChat.identifier)];
TGBridgeUser *newUser = newUsers[@(newChat.identifier)];
if ([self _nameHasChangedFrom:oldUser.firstName newName:newUser.firstName] || [self _nameHasChangedFrom:oldUser.lastName newName:newUser.firstName])
return true;
}
if (![oldChat.text isEqualToString:newChat.text])
return true;
if (fabs(oldChat.date - newChat.date) > FLT_EPSILON)
return true;
return false;
}
- (void)notifyVisiblityChange
{
[_avatarViewModel updateIfNeeded];
}
- (bool)shouldUpdateStatusFrom:(TGBridgeChat *)oldChat to:(TGBridgeChat *)newChat
{
if (oldChat.outgoing != newChat.outgoing)
return true;
if (oldChat.deliveryError != newChat.deliveryError)
return true;
if (newChat.outgoing && oldChat.unread != newChat.unread)
return true;
if (!newChat.deliveryError && oldChat.unreadCount != newChat.unreadCount)
return true;
return false;
}
+ (NSString *)identifier
{
return TGNeoChatRowIdentifier;
}
@end