Bug Fix: Screen when placing a voip call can be incredibly ugly

#597
This commit is contained in:
giomfo 2016-09-09 15:11:12 +02:00
parent 3cb52bd198
commit f74b5fac9a
15 changed files with 99 additions and 50 deletions

View file

@ -49,7 +49,7 @@
}
}
UIImage* avatarImage = [AvatarGenerator generateRoomAvatar:self.state.roomId andDisplayName:self.vectorDisplayname];
UIImage* avatarImage = [AvatarGenerator generateAvatarForMatrixItem:self.state.roomId withDisplayName:self.vectorDisplayname];
if (roomAvatarUrl)
{

View file

@ -27,7 +27,7 @@
// replace the identicon icon by the Vector style one
if (_mxMember && ([_mxMember.avatarUrl rangeOfString:@"identicon"].location != NSNotFound))
{
thumbnail = [AvatarGenerator generateRoomMemberAvatar:_mxMember.userId displayName:_mxMember.displayname];
thumbnail = [AvatarGenerator generateAvatarForMatrixItem:_mxMember.userId withDisplayName:_mxMember.displayname];
}
else
{

View file

@ -34,7 +34,7 @@ static NSAttributedString *readReceiptVerticalWhitespace = nil;
if (self)
{
// Use the vector style placeholder
self.senderAvatarPlaceholder = [AvatarGenerator generateRoomMemberAvatar:self.senderId displayName:self.senderDisplayName];
self.senderAvatarPlaceholder = [AvatarGenerator generateAvatarForMatrixItem:self.senderId withDisplayName:self.senderDisplayName];
// Increase maximum number of components
self.maxComponentCount = 20;

View file

@ -157,7 +157,7 @@
if (roomMember)
{
[roomMembers addObject:roomMember];
[placeholders addObject:[AvatarGenerator generateRoomMemberAvatar:roomMember.userId displayName:roomMember.displayname]];
[placeholders addObject:[AvatarGenerator generateAvatarForMatrixItem:roomMember.userId withDisplayName:roomMember.displayname]];
}
}
}

View file

@ -22,7 +22,7 @@
@interface AvatarGenerator : NSObject
/**
Create an UIImage with the text and the background color.
Create a squared UIImage with the text and the background color.
@param text the text.
@param color the background color.
@return the avatar image.
@ -30,20 +30,22 @@
+ (UIImage *)imageFromText:(NSString*)text withBackgroundColor:(UIColor*)color;
/**
Generate an avatar for a room.
@param roomId the id of the room.
@param displayName the display name of the room.
Generate a squared avatar for a matrix item (room, room member...).
@param itemId the matrix identifier of the item
@param displayname the item displayname (if nil, the itemId is used by default).
@return the avatar image
*/
+ (UIImage*)generateRoomAvatar:(NSString*)roomId andDisplayName:(NSString*)displayName;
+ (UIImage*)generateAvatarForMatrixItem:(NSString*)itemId withDisplayName:(NSString*)displayname;
/**
Generate an avatar for a room member.
@param userId the member userId
@param displayname the member displayname
Generate a squared avatar for a matrix item (room, room member...) with a preferred size
@param itemId the matrix identifier of the item
@param displayname the item displayname (if nil, the itemId is used by default).
@param size the expected size of the returned image
@param fontSize the expected font size
@return the avatar image
*/
+ (UIImage*)generateRoomMemberAvatar:(NSString*)userId displayName:(NSString*)displayname;
+ (UIImage*)generateAvatarForMatrixItem:(NSString*)itemId withDisplayName:(NSString*)displayname size:(CGFloat)size andFontSize:(CGFloat)fontSize;
/**
Generate an avatar for a text.

View file

@ -64,8 +64,26 @@ static UILabel* backgroundLabel = nil;
}
/**
Create an UIImage with the text and the background color.
Return the first valid character for avatar creation.
*/
+ (NSString *)firstChar:(NSString *)text
{
if ([text hasPrefix:@"@"] || [text hasPrefix:@"#"] || [text hasPrefix:@"!"])
{
text = [text substringFromIndex:1];
}
// default firstchar
NSString* firstChar = @" ";
if (text.length > 0)
{
firstChar = [[text substringToIndex:1] uppercaseString];
}
return firstChar;
}
+ (UIImage *)imageFromText:(NSString*)text withBackgroundColor:(UIColor*)color
{
if (!backgroundLabel)
@ -93,24 +111,37 @@ static UILabel* backgroundLabel = nil;
return image;
}
+ (UIImage *)imageFromText:(NSString*)text withBackgroundColor:(UIColor*)color size:(CGFloat)size andFontSize:(CGFloat)fontSize
{
UILabel *bgLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, size, size)];
bgLabel.textColor = [UIColor whiteColor];
bgLabel.textAlignment = NSTextAlignmentCenter;
bgLabel.font = [UIFont boldSystemFontOfSize:fontSize];
bgLabel.text = text;
bgLabel.backgroundColor = color;
// Create a "canvas" (image context) to draw in.
UIGraphicsBeginImageContextWithOptions(bgLabel.frame.size, NO, 0);
// set to the top quality
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
[[bgLabel layer] renderInContext: UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Return the image.
return image;
}
/**
Returns the UIImage for the text and a selected color.
It checks first if it is not yet cached before generating one.
*/
+ (UIImage*)avatarForText:(NSString*)aText andColorIndex:(NSUInteger)colorIndex
+ (UIImage*)avatarForText:(NSString*)text andColorIndex:(NSUInteger)colorIndex
{
if ([aText hasPrefix:@"@"] || [aText hasPrefix:@"#"] || [aText hasPrefix:@"!"])
{
aText = [aText substringFromIndex:1];
}
// default firstchar
NSString* firstChar = @" ";
if (aText.length > 0)
{
firstChar = [[aText substringToIndex:1] uppercaseString];
}
NSString* firstChar = [AvatarGenerator firstChar:text];
// the images are cached to avoid create them several times
// the key is <first upper character><index in the colors array>
@ -138,18 +169,17 @@ static UILabel* backgroundLabel = nil;
return [AvatarGenerator avatarForText:text andColorIndex:[AvatarGenerator colorIndexForText:text]];
}
+ (UIImage*)generateRoomMemberAvatar:(NSString*)userId displayName:(NSString*)displayname
+ (UIImage*)generateAvatarForMatrixItem:(NSString*)itemId withDisplayName:(NSString*)displayname
{
// the selected color is based on the userId
NSUInteger index = [AvatarGenerator colorIndexForText:userId];
NSString* text = displayname ? displayname : userId;
return [AvatarGenerator avatarForText:text andColorIndex:index];
return [AvatarGenerator avatarForText:(displayname ? displayname : itemId) andColorIndex:[AvatarGenerator colorIndexForText:itemId]];
}
+ (UIImage*)generateRoomAvatar:(NSString*)roomId andDisplayName:(NSString*)displayName
+ (UIImage*)generateAvatarForMatrixItem:(NSString*)itemId withDisplayName:(NSString*)displayname size:(CGFloat)size andFontSize:(CGFloat)fontSize
{
return [AvatarGenerator avatarForText:displayName andColorIndex:[AvatarGenerator colorIndexForText:roomId]];
NSString* firstChar = [AvatarGenerator firstChar:(displayname ? displayname : itemId)];
NSUInteger colorIndex = [AvatarGenerator colorIndexForText:itemId];
return [AvatarGenerator imageFromText:firstChar withBackgroundColor:[colorsList objectAtIndex:colorIndex] size:size andFontSize:fontSize];
}
@end

View file

@ -24,4 +24,6 @@
@property (weak, nonatomic) IBOutlet UIView *gradientMaskContainerView;
@property (weak, nonatomic) IBOutlet UIButton *chatButton;
@property (unsafe_unretained, nonatomic) IBOutlet NSLayoutConstraint *callerImageViewWidthConstraint;
@end

View file

@ -110,6 +110,11 @@
gradientMaskLayer.bounds = CGRectMake(0, 0, self.callContainerView.frame.size.width, self.callContainerView.frame.size.height + 20);
gradientMaskLayer.anchorPoint = CGPointZero;
// Define caller image view size
CGSize size = [[UIScreen mainScreen] bounds].size;
CGFloat minSize = MIN(size.width, size.height);
self.callerImageViewWidthConstraint.constant = minSize / 2;
// CAConstraint is not supported on IOS.
// it seems only being supported on Mac OS.
@ -136,6 +141,10 @@
gradientMaskLayer.bounds = newBounds;
}
}
// The caller image view is circular
self.callerImageView.layer.cornerRadius = self.callerImageViewWidthConstraint.constant / 2;
self.callerImageView.clipsToBounds = YES;
}
- (void)dealloc
@ -156,14 +165,16 @@
- (UIImage*)picturePlaceholder
{
CGFloat fontSize = floor(self.callerImageViewWidthConstraint.constant * 0.7);
if (self.peer)
{
// Use the vector style placeholder
return [AvatarGenerator generateRoomMemberAvatar:self.peer.userId displayName:self.peer.displayname];
return [AvatarGenerator generateAvatarForMatrixItem:self.peer.userId withDisplayName:self.peer.displayname size:self.callerImageViewWidthConstraint.constant andFontSize:fontSize];
}
else if (self.mxCall.room)
{
return [AvatarGenerator generateRoomAvatar:self.mxCall.room.roomId andDisplayName:self.mxCall.room.state.displayname];
return [AvatarGenerator generateAvatarForMatrixItem:self.mxCall.room.roomId withDisplayName:self.mxCall.room.vectorDisplayname size:self.callerImageViewWidthConstraint.constant andFontSize:fontSize];
}
return [UIImage imageNamed:@"placeholder"];

View file

@ -3,6 +3,7 @@
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
</dependencies>
<objects>
@ -15,6 +16,7 @@
<outlet property="callControlContainerView" destination="nk9-Un-LVP" id="ZV3-qr-BtW"/>
<outlet property="callStatusLabel" destination="29y-MK-OWH" id="Kcn-MX-MUH"/>
<outlet property="callerImageView" destination="v1I-LH-wvv" id="dpZ-KD-4Hg"/>
<outlet property="callerImageViewWidthConstraint" destination="PAF-29-Cis" id="Crz-nE-p4c"/>
<outlet property="callerNameLabel" destination="IW8-8P-mS3" id="eaa-oo-l01"/>
<outlet property="cameraSwitchButton" destination="Iiz-W1-oNW" id="bsM-mH-ti8"/>
<outlet property="chatButton" destination="xCi-hD-FBs" id="h3w-6I-Agn"/>
@ -46,8 +48,12 @@
<rect key="frame" x="277" y="285" width="46" height="30"/>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="v1I-LH-wvv" customClass="MXKImageView">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
<rect key="frame" x="150" y="90" width="300" height="300"/>
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="width" constant="300" id="PAF-29-Cis"/>
<constraint firstAttribute="width" secondItem="v1I-LH-wvv" secondAttribute="height" multiplier="1:1" id="pzY-9x-dH7"/>
</constraints>
</view>
<view hidden="YES" contentMode="scaleAspectFill" translatesAutoresizingMaskIntoConstraints="NO" id="Tjb-57-yB1">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
@ -270,23 +276,21 @@
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="v1I-LH-wvv" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" multiplier="0.8" id="7bF-kf-k3o"/>
<constraint firstAttribute="bottom" secondItem="STO-VX-5VW" secondAttribute="bottom" id="DhB-zy-SJA"/>
<constraint firstAttribute="trailing" secondItem="JAR-tn-sGN" secondAttribute="trailing" id="IGf-YS-JEj"/>
<constraint firstAttribute="bottom" secondItem="JAR-tn-sGN" secondAttribute="bottom" id="KDu-Kr-vji"/>
<constraint firstItem="STO-VX-5VW" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="Tyh-Du-Ztt"/>
<constraint firstItem="v1I-LH-wvv" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="VF9-js-1ub"/>
<constraint firstItem="6gQ-zo-2Zw" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" priority="750" constant="420" id="VUy-XN-XzH"/>
<constraint firstAttribute="trailing" secondItem="STO-VX-5VW" secondAttribute="trailing" id="X0Q-UU-v3g"/>
<constraint firstItem="JAR-tn-sGN" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="Z6W-gz-KKT"/>
<constraint firstItem="v1I-LH-wvv" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="ZfI-qE-l2V"/>
<constraint firstItem="Tjb-57-yB1" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="aKy-Ol-bhc"/>
<constraint firstAttribute="bottom" secondItem="Tjb-57-yB1" secondAttribute="bottom" id="akt-pO-kWM"/>
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="6gQ-zo-2Zw" secondAttribute="bottom" constant="74" id="bmf-4N-mLk"/>
<constraint firstItem="v1I-LH-wvv" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="cq1-0k-TFN"/>
<constraint firstItem="6gQ-zo-2Zw" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" id="dq3-4E-bhT"/>
<constraint firstItem="STO-VX-5VW" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="e4c-aG-jOB"/>
<constraint firstAttribute="trailing" secondItem="v1I-LH-wvv" secondAttribute="trailing" id="eL2-a4-lJd"/>
<constraint firstItem="Tjb-57-yB1" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="mW3-RA-hx2"/>
<constraint firstAttribute="bottom" secondItem="v1I-LH-wvv" secondAttribute="bottom" id="o10-x3-vgo"/>
<constraint firstItem="JAR-tn-sGN" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="pei-Ab-VHX"/>
<constraint firstAttribute="trailing" secondItem="Tjb-57-yB1" secondAttribute="trailing" id="rXn-dm-69F"/>
</constraints>

View file

@ -376,7 +376,7 @@
if (matrixId)
{
image = [AvatarGenerator generateRoomMemberAvatar:matrixId displayName:_contact.displayName];
image = [AvatarGenerator generateAvatarForMatrixItem:matrixId withDisplayName:_contact.displayName];
}
else
{

View file

@ -215,7 +215,7 @@
if (self.mxRoomMember)
{
// Use the vector style placeholder
return [AvatarGenerator generateRoomMemberAvatar:self.mxRoomMember.userId displayName:self.mxRoomMember.displayname];
return [AvatarGenerator generateAvatarForMatrixItem:self.mxRoomMember.userId withDisplayName:self.mxRoomMember.displayname];
}
return [UIImage imageNamed:@"placeholder"];

View file

@ -925,7 +925,7 @@
MXKImageView *userPictureView = roomInputToolbarView.pictureView;
if (userPictureView)
{
UIImage *preview = [AvatarGenerator generateRoomMemberAvatar:self.mainSession.myUser.userId displayName:self.mainSession.myUser.displayname];
UIImage *preview = [AvatarGenerator generateAvatarForMatrixItem:self.mainSession.myUser.userId withDisplayName:self.mainSession.myUser.displayname];
NSString *avatarThumbURL = nil;
if (self.mainSession.myUser.avatarUrl)
{
@ -1204,7 +1204,7 @@
}
else if (roomPreviewData.roomId && roomPreviewData.roomName)
{
roomAvatarTitleView.roomAvatarPlaceholder = [AvatarGenerator generateRoomAvatar:roomPreviewData.roomId andDisplayName:roomPreviewData.roomName];
roomAvatarTitleView.roomAvatarPlaceholder = [AvatarGenerator generateAvatarForMatrixItem:roomPreviewData.roomId withDisplayName:roomPreviewData.roomName];
}
else
{

View file

@ -691,7 +691,7 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
}
else
{
UIImage* avatarImage = [AvatarGenerator generateRoomMemberAvatar:myUser.userId displayName:myUser.displayname];
UIImage* avatarImage = [AvatarGenerator generateAvatarForMatrixItem:myUser.userId withDisplayName:myUser.displayname];
if (myUser.avatarUrl)
{

View file

@ -180,7 +180,7 @@
if (matrixId)
{
image = [AvatarGenerator generateRoomMemberAvatar:matrixId displayName:contact.displayName];
image = [AvatarGenerator generateAvatarForMatrixItem:matrixId withDisplayName:contact.displayName];
}
else if (contact.isThirdPartyInvite)
{

View file

@ -42,7 +42,7 @@
}
// Set the avatar
UIImage* avatarImage = [AvatarGenerator generateRoomAvatar:publicRoom.roomId andDisplayName:self.roomDisplayName.text];
UIImage* avatarImage = [AvatarGenerator generateAvatarForMatrixItem:publicRoom.roomId withDisplayName:self.roomDisplayName.text];
if (publicRoom.avatarUrl)
{