Files
bundesmessenger-ios/Riot/Modules/MatrixKit/Views/Contact/MXKContactTableCell.m

350 lines
10 KiB
Objective-C

/*
Copyright 2015 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import "MXKContactTableCell.h"
@import MatrixSDK.MXTools;
#import "MXKContactManager.h"
#import "MXKAppSettings.h"
#import "NSBundle+MatrixKit.h"
#pragma mark - Constant definitions
NSString *const kMXKContactCellTapOnThumbnailView = @"kMXKContactCellTapOnThumbnailView";
NSString *const kMXKContactCellContactIdKey = @"kMXKContactCellContactIdKey";
@interface MXKContactTableCell()
{
/**
The current displayed contact.
*/
MXKContact *contact;
/**
The observer of the presence for matrix user.
*/
id mxPresenceObserver;
}
@end
@implementation MXKContactTableCell
@synthesize delegate;
- (void)awakeFromNib
{
[super awakeFromNib];
self.thumbnailDisplayBoxType = MXKTableViewCellDisplayBoxTypeDefault;
// No accessory view by default
self.contactAccessoryViewType = MXKContactTableCellAccessoryCustom;
self.hideMatrixPresence = NO;
}
- (void)customizeTableViewCellRendering
{
[super customizeTableViewCellRendering];
self.thumbnailView.defaultBackgroundColor = [UIColor clearColor];
}
- (void)layoutSubviews
{
[super layoutSubviews];
if (self.thumbnailDisplayBoxType == MXKTableViewCellDisplayBoxTypeCircle)
{
// Round image view for thumbnail
self.thumbnailView.layer.cornerRadius = self.thumbnailView.frame.size.width / 2;
self.thumbnailView.clipsToBounds = YES;
}
else if (self.thumbnailDisplayBoxType == MXKTableViewCellDisplayBoxTypeRoundedCorner)
{
self.thumbnailView.layer.cornerRadius = 5;
self.thumbnailView.clipsToBounds = YES;
}
else
{
self.thumbnailView.layer.cornerRadius = 0;
self.thumbnailView.clipsToBounds = NO;
}
}
- (UIImage*)picturePlaceholder
{
return [NSBundle mxk_imageFromMXKAssetsBundleWithName:@"default-profile"];
}
- (void)setContactAccessoryViewType:(MXKContactTableCellAccessoryType)contactAccessoryViewType
{
_contactAccessoryViewType = contactAccessoryViewType;
if (contactAccessoryViewType == MXKContactTableCellAccessoryMatrixIcon)
{
// Load default matrix icon
self.contactAccessoryImageView.image = [NSBundle mxk_imageFromMXKAssetsBundleWithName:@"matrixUser"];
self.contactAccessoryImageView.hidden = NO;
self.contactAccessoryButton.hidden = YES;
// Update accessory view visibility
[self refreshMatrixIdentifiers];
}
else
{
// Hide accessory view by default
self.contactAccessoryView.hidden = YES;
self.contactAccessoryImageView.hidden = YES;
self.contactAccessoryButton.hidden = YES;
}
}
#pragma mark - MXKCellRendering
- (void)render:(MXKCellData *)cellData
{
// Sanity check: accept only object of MXKContact classes or sub-classes
NSParameterAssert([cellData isKindOfClass:[MXKContact class]]);
contact = (MXKContact*)cellData;
// remove any pending observers
[[NSNotificationCenter defaultCenter] removeObserver:self];
if (mxPresenceObserver)
{
[[NSNotificationCenter defaultCenter] removeObserver:mxPresenceObserver];
mxPresenceObserver = nil;
}
self.thumbnailView.layer.borderWidth = 0;
if (contact)
{
// Be warned when the thumbnail is updated
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onThumbnailUpdate:) name:kMXKContactThumbnailUpdateNotification object:nil];
if (! self.hideMatrixPresence)
{
// Observe contact presence change
mxPresenceObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXKContactManagerMatrixUserPresenceChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
// get the matrix identifiers
NSArray* matrixIdentifiers = self->contact.matrixIdentifiers;
if (matrixIdentifiers.count > 0)
{
// Consider only the first id
NSString *matrixUserID = matrixIdentifiers.firstObject;
if ([matrixUserID isEqualToString:notif.object])
{
[self refreshPresenceUserRing:[MXTools presence:[notif.userInfo objectForKey:kMXKContactManagerMatrixPresenceKey]]];
}
}
}];
}
if (!contact.isMatrixContact)
{
// Be warned when the linked matrix IDs are updated
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMatrixIdUpdate:) name:kMXKContactManagerDidUpdateLocalContactMatrixIDsNotification object:nil];
}
NSArray* matrixIDs = contact.matrixIdentifiers;
if (matrixIDs.count)
{
self.contactDisplayNameLabel.hidden = YES;
self.matrixDisplayNameLabel.hidden = NO;
self.matrixDisplayNameLabel.text = contact.displayName;
self.matrixIDLabel.hidden = NO;
self.matrixIDLabel.text = [matrixIDs firstObject];
}
else
{
self.contactDisplayNameLabel.hidden = NO;
self.contactDisplayNameLabel.text = contact.displayName;
self.matrixDisplayNameLabel.hidden = YES;
self.matrixIDLabel.hidden = YES;
}
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onContactThumbnailTap:)];
[tap setNumberOfTouchesRequired:1];
[tap setNumberOfTapsRequired:1];
[tap setDelegate:self];
[self.thumbnailView addGestureRecognizer:tap];
}
[self refreshContactThumbnail];
[self manageMatrixIcon];
}
+ (CGFloat)heightForCellData:(MXKCellData*)cellData withMaximumWidth:(CGFloat)maxWidth
{
// The height is fixed
return 50;
}
- (void)didEndDisplay
{
// remove any pending observers
[[NSNotificationCenter defaultCenter] removeObserver:self];
if (mxPresenceObserver) {
[[NSNotificationCenter defaultCenter] removeObserver:mxPresenceObserver];
mxPresenceObserver = nil;
}
// Remove all gesture recognizer
while (self.thumbnailView.gestureRecognizers.count)
{
[self.thumbnailView removeGestureRecognizer:self.thumbnailView.gestureRecognizers[0]];
}
self.delegate = nil;
contact = nil;
}
#pragma mark -
- (void)refreshMatrixIdentifiers
{
// Look for a potential matrix user linked with this contact
NSArray* matrixIdentifiers = contact.matrixIdentifiers;
if ((matrixIdentifiers.count > 0) && (! self.hideMatrixPresence))
{
// Consider only the first matrix identifier
NSString* matrixUserID = matrixIdentifiers.firstObject;
// Consider here all sessions reported into contact manager
NSArray* mxSessions = [MXKContactManager sharedManager].mxSessions;
for (MXSession *mxSession in mxSessions)
{
MXUser *mxUser = [mxSession userWithUserId:matrixUserID];
if (mxUser)
{
[self refreshPresenceUserRing:mxUser.presence];
break;
}
}
}
// Update accessory view visibility
if (self.contactAccessoryViewType == MXKContactTableCellAccessoryMatrixIcon)
{
self.contactAccessoryView.hidden = (!matrixIdentifiers.count);
}
}
- (void)refreshContactThumbnail
{
self.thumbnailView.image = [contact thumbnailWithPreferedSize:self.thumbnailView.frame.size];
if (!self.thumbnailView.image)
{
self.thumbnailView.image = self.picturePlaceholder;
}
}
- (void)refreshPresenceUserRing:(MXPresence)presenceStatus
{
UIColor* ringColor;
switch (presenceStatus)
{
case MXPresenceOnline:
ringColor = [[MXKAppSettings standardAppSettings] presenceColorForOnlineUser];
break;
case MXPresenceUnavailable:
ringColor = [[MXKAppSettings standardAppSettings] presenceColorForUnavailableUser];
break;
case MXPresenceOffline:
ringColor = [[MXKAppSettings standardAppSettings] presenceColorForOfflineUser];
break;
default:
ringColor = nil;
}
// if the thumbnail is defined
if (ringColor && (! self.hideMatrixPresence))
{
self.thumbnailView.layer.borderWidth = 2;
self.thumbnailView.layer.borderColor = ringColor.CGColor;
}
else
{
// remove the border
// else it draws black border
self.thumbnailView.layer.borderWidth = 0;
}
}
- (void)manageMatrixIcon
{
// try to update the thumbnail with the matrix thumbnail
if (contact.matrixIdentifiers)
{
[self refreshContactThumbnail];
}
[self refreshMatrixIdentifiers];
}
- (void)onMatrixIdUpdate:(NSNotification *)notif
{
// sanity check
if ([notif.object isKindOfClass:[NSString class]])
{
NSString* contactID = notif.object;
if ([contactID isEqualToString:contact.contactID])
{
[self manageMatrixIcon];
}
}
}
- (void)onThumbnailUpdate:(NSNotification *)notif
{
// sanity check
if ([notif.object isKindOfClass:[NSString class]])
{
NSString* contactID = notif.object;
if ([contactID isEqualToString:contact.contactID])
{
[self refreshContactThumbnail];
[self refreshMatrixIdentifiers];
}
}
}
#pragma mark - Action
- (IBAction)onContactThumbnailTap:(id)sender
{
if (self.delegate)
{
[self.delegate cell:self didRecognizeAction:kMXKContactCellTapOnThumbnailView userInfo:@{kMXKContactCellContactIdKey: contact.contactID}];
}
}
@end