Merge MatrixKit develop with commit hash: b85b736313bec0592bd1cabc68035d97f5331137

This commit is contained in:
SBiOSoftWhare
2021-12-03 11:47:24 +01:00
parent af65f71177
commit f57941177e
475 changed files with 87437 additions and 0 deletions
@@ -0,0 +1,90 @@
/*
Copyright 2015 OpenMarket 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 "MXKTableViewCell.h"
#import "MXKCellRendering.h"
#import "MXKImageView.h"
/**
List the accessory view types for a 'MXKContactTableCell' instance.
*/
typedef enum : NSUInteger {
/**
Don't show accessory view by default.
*/
MXKContactTableCellAccessoryCustom,
/**
The accessory view is automatically handled. It shown only for contact with matrix identifier(s).
*/
MXKContactTableCellAccessoryMatrixIcon
} MXKContactTableCellAccessoryType;
#pragma mark - MXKCellRenderingDelegate cell tap locations
/**
Action identifier used when the user tapped on contact thumbnail view.
The `userInfo` dictionary contains an `NSString` object under the `kMXKContactCellContactIdKey` key, representing the contact id of the tapped avatar.
*/
extern NSString *const kMXKContactCellTapOnThumbnailView;
/**
Notifications `userInfo` keys
*/
extern NSString *const kMXKContactCellContactIdKey;
/**
'MXKContactTableCell' is a base class for displaying a contact.
*/
@interface MXKContactTableCell : MXKTableViewCell <MXKCellRendering>
@property (strong, nonatomic) IBOutlet MXKImageView *thumbnailView;
@property (strong, nonatomic) IBOutlet UILabel *contactDisplayNameLabel;
@property (strong, nonatomic) IBOutlet UILabel *matrixDisplayNameLabel;
@property (strong, nonatomic) IBOutlet UILabel *matrixIDLabel;
@property (strong, nonatomic) IBOutlet UIView *contactAccessoryView;
@property (unsafe_unretained, nonatomic) IBOutlet NSLayoutConstraint *contactAccessoryViewHeightConstraint;
@property (unsafe_unretained, nonatomic) IBOutlet NSLayoutConstraint *contactAccessoryViewWidthConstraint;
@property (strong, nonatomic) IBOutlet UIImageView *contactAccessoryImageView;
@property (strong, nonatomic) IBOutlet UIButton *contactAccessoryButton;
/**
The default picture displayed when no picture is available.
*/
@property (nonatomic) UIImage *picturePlaceholder;
/**
The thumbnail display box type ('MXKTableViewCellDisplayBoxTypeDefault' by default)
*/
@property (nonatomic) MXKTableViewCellDisplayBoxType thumbnailDisplayBoxType;
/**
The accessory view type ('MXKContactTableCellAccessoryCustom' by default)
*/
@property (nonatomic) MXKContactTableCellAccessoryType contactAccessoryViewType;
/**
Tell whether the matrix presence of the contact is displayed or not (NO by default)
*/
@property (nonatomic) BOOL hideMatrixPresence;
@end
@@ -0,0 +1,349 @@
/*
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
@@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="ChX-Tl-3Zt" customClass="MXKContactTableCell">
<rect key="frame" x="0.0" y="0.0" width="600" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="ChX-Tl-3Zt" id="SeD-4h-8Bk">
<rect key="frame" x="0.0" y="0.0" width="600" height="49"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleAspectFit" translatesAutoresizingMaskIntoConstraints="NO" id="2UL-NX-Nd1" userLabel="Contact Image View" customClass="MXKImageView">
<rect key="frame" x="8" y="5" width="40" height="40"/>
<color key="backgroundColor" red="0.89720267057418823" green="0.89720267057418823" blue="0.89720267057418823" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<gestureRecognizers/>
<constraints>
<constraint firstAttribute="height" constant="40" id="QUm-Hf-dkn"/>
<constraint firstAttribute="width" constant="40" id="z2e-H8-DcL"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Single line" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="AqS-OH-Gcq">
<rect key="frame" x="60" y="10" width="510" height="30"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="zWe-gm-gkP"/>
</constraints>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Line 1" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="MBc-s3-6mn">
<rect key="frame" x="60" y="8" width="510" height="22"/>
<constraints>
<constraint firstAttribute="height" constant="22" id="7wT-nd-kfp"/>
</constraints>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Line 2" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Dqg-OY-Nhb" userLabel="Line 2">
<rect key="frame" x="60" y="28" width="510" height="18"/>
<constraints>
<constraint firstAttribute="height" constant="18" id="BEu-8L-a1q"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="uMV-DW-X26" userLabel="Accessory View">
<rect key="frame" x="574" y="17" width="16" height="16"/>
<subviews>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="BcH-3j-P0i" userLabel="Accessory Image View">
<rect key="frame" x="0.0" y="0.0" width="16" height="16"/>
</imageView>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="j2S-s7-q50" userLabel="Accessory Button">
<rect key="frame" x="-7" y="-7" width="30" height="30"/>
<state key="normal">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
</button>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="centerY" secondItem="j2S-s7-q50" secondAttribute="centerY" id="3Qb-sa-m7f"/>
<constraint firstAttribute="bottom" secondItem="BcH-3j-P0i" secondAttribute="bottom" id="KIl-sC-FVk"/>
<constraint firstAttribute="centerX" secondItem="j2S-s7-q50" secondAttribute="centerX" id="Wp1-CK-YKk"/>
<constraint firstAttribute="width" constant="16" id="cWZ-C3-LfR"/>
<constraint firstAttribute="trailing" secondItem="BcH-3j-P0i" secondAttribute="trailing" id="mol-ud-P3Q"/>
<constraint firstItem="BcH-3j-P0i" firstAttribute="top" secondItem="uMV-DW-X26" secondAttribute="top" id="sT8-GB-Hzx"/>
<constraint firstItem="BcH-3j-P0i" firstAttribute="leading" secondItem="uMV-DW-X26" secondAttribute="leading" id="wTq-hz-2Wl"/>
<constraint firstAttribute="height" constant="16" id="xAv-oq-PkL"/>
</constraints>
</view>
</subviews>
<constraints>
<constraint firstAttribute="centerY" secondItem="2UL-NX-Nd1" secondAttribute="centerY" id="2z5-cx-W9f"/>
<constraint firstItem="Dqg-OY-Nhb" firstAttribute="leading" secondItem="2UL-NX-Nd1" secondAttribute="trailing" constant="12" id="5I6-PQ-4Bt"/>
<constraint firstAttribute="centerY" secondItem="AqS-OH-Gcq" secondAttribute="centerY" id="9jE-l2-2tm"/>
<constraint firstAttribute="trailing" secondItem="uMV-DW-X26" secondAttribute="trailing" constant="10" id="DDZ-6z-ppJ"/>
<constraint firstAttribute="centerY" secondItem="uMV-DW-X26" secondAttribute="centerY" id="OFV-RA-kUY"/>
<constraint firstItem="2UL-NX-Nd1" firstAttribute="leading" secondItem="SeD-4h-8Bk" secondAttribute="leading" constant="8" id="Tno-FP-CJJ"/>
<constraint firstItem="MBc-s3-6mn" firstAttribute="width" secondItem="Dqg-OY-Nhb" secondAttribute="width" id="Wk2-qO-Gdj"/>
<constraint firstItem="AqS-OH-Gcq" firstAttribute="leading" secondItem="2UL-NX-Nd1" secondAttribute="trailing" constant="12" id="dSV-cR-GP0"/>
<constraint firstItem="MBc-s3-6mn" firstAttribute="leading" secondItem="2UL-NX-Nd1" secondAttribute="trailing" constant="12" id="f7x-gz-aR7"/>
<constraint firstItem="uMV-DW-X26" firstAttribute="leading" secondItem="Dqg-OY-Nhb" secondAttribute="trailing" constant="4" id="oJV-sA-GzJ"/>
<constraint firstItem="AqS-OH-Gcq" firstAttribute="width" secondItem="MBc-s3-6mn" secondAttribute="width" id="qGv-M1-qC6"/>
<constraint firstItem="MBc-s3-6mn" firstAttribute="top" secondItem="SeD-4h-8Bk" secondAttribute="topMargin" id="qf2-UP-3lW"/>
<constraint firstAttribute="bottomMargin" secondItem="Dqg-OY-Nhb" secondAttribute="bottom" constant="-5" id="tLG-uu-oPr"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="contactAccessoryButton" destination="j2S-s7-q50" id="9hP-Zr-kHK"/>
<outlet property="contactAccessoryImageView" destination="BcH-3j-P0i" id="Omi-4G-fbt"/>
<outlet property="contactAccessoryView" destination="uMV-DW-X26" id="6kX-sp-tuz"/>
<outlet property="contactAccessoryViewHeightConstraint" destination="xAv-oq-PkL" id="MGt-PN-Brr"/>
<outlet property="contactAccessoryViewWidthConstraint" destination="cWZ-C3-LfR" id="0pP-6i-gop"/>
<outlet property="contactDisplayNameLabel" destination="AqS-OH-Gcq" id="Znz-dt-zKJ"/>
<outlet property="matrixDisplayNameLabel" destination="MBc-s3-6mn" id="BWe-zO-aM3"/>
<outlet property="matrixIDLabel" destination="Dqg-OY-Nhb" id="SlZ-le-uC1"/>
<outlet property="thumbnailView" destination="2UL-NX-Nd1" id="uMq-9r-M4G"/>
</connections>
</tableViewCell>
</objects>
</document>