Merge pull request #746 from vector-im/vector_715

Feature - Converting existing rooms to/from DMs
This commit is contained in:
giomfo 2016-11-02 16:28:12 +01:00 committed by GitHub
commit 7d0489545f
18 changed files with 617 additions and 167 deletions

View file

@ -249,6 +249,11 @@
F08714CD1DB9EFEE0075F633 /* directChatOn.png in Resources */ = {isa = PBXBuildFile; fileRef = F08714C71DB9EFEE0075F633 /* directChatOn.png */; };
F08714CE1DB9EFEE0075F633 /* directChatOn@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F08714C81DB9EFEE0075F633 /* directChatOn@2x.png */; };
F08714CF1DB9EFEE0075F633 /* directChatOn@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = F08714C91DB9EFEE0075F633 /* directChatOn@3x.png */; };
F08714D31DC3709C0075F633 /* RoomTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F08714D11DC3709C0075F633 /* RoomTableViewCell.m */; };
F08714D41DC3709C0075F633 /* RoomTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F08714D21DC3709C0075F633 /* RoomTableViewCell.xib */; };
F08714D81DC384810075F633 /* start_chat.png in Resources */ = {isa = PBXBuildFile; fileRef = F08714D51DC384810075F633 /* start_chat.png */; };
F08714D91DC384810075F633 /* start_chat@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F08714D61DC384810075F633 /* start_chat@2x.png */; };
F08714DA1DC384810075F633 /* start_chat@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = F08714D71DC384810075F633 /* start_chat@3x.png */; };
F08BE09E1B87025B00C480FB /* EventFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = F08BE09D1B87025B00C480FB /* EventFormatter.m */; };
F08BE0A21B87064000C480FB /* RoomDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = F08BE0A11B87064000C480FB /* RoomDataSource.m */; };
F094A9A81B78D8F000B1FBBF /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F094A9A71B78D8F000B1FBBF /* main.m */; };
@ -634,6 +639,12 @@
F08714C71DB9EFEE0075F633 /* directChatOn.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = directChatOn.png; sourceTree = "<group>"; };
F08714C81DB9EFEE0075F633 /* directChatOn@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "directChatOn@2x.png"; sourceTree = "<group>"; };
F08714C91DB9EFEE0075F633 /* directChatOn@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "directChatOn@3x.png"; sourceTree = "<group>"; };
F08714D01DC3709C0075F633 /* RoomTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomTableViewCell.h; sourceTree = "<group>"; };
F08714D11DC3709C0075F633 /* RoomTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RoomTableViewCell.m; sourceTree = "<group>"; };
F08714D21DC3709C0075F633 /* RoomTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RoomTableViewCell.xib; sourceTree = "<group>"; };
F08714D51DC384810075F633 /* start_chat.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = start_chat.png; sourceTree = "<group>"; };
F08714D61DC384810075F633 /* start_chat@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "start_chat@2x.png"; sourceTree = "<group>"; };
F08714D71DC384810075F633 /* start_chat@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "start_chat@3x.png"; sourceTree = "<group>"; };
F08BE09C1B87025B00C480FB /* EventFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventFormatter.h; sourceTree = "<group>"; };
F08BE09D1B87025B00C480FB /* EventFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EventFormatter.m; sourceTree = "<group>"; };
F08BE0A01B87064000C480FB /* RoomDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomDataSource.h; sourceTree = "<group>"; };
@ -953,6 +964,9 @@
F00C47821BFF77C800DBABC9 /* RoomList */ = {
isa = PBXGroup;
children = (
F08714D01DC3709C0075F633 /* RoomTableViewCell.h */,
F08714D11DC3709C0075F633 /* RoomTableViewCell.m */,
F08714D21DC3709C0075F633 /* RoomTableViewCell.xib */,
F0AF11F21D1029CF00FEE52F /* RoomIdOrAliasTableViewCell.h */,
F0AF11F31D1029CF00FEE52F /* RoomIdOrAliasTableViewCell.m */,
F0AF11F41D1029CF00FEE52F /* RoomIdOrAliasTableViewCell.xib */,
@ -990,6 +1004,9 @@
F03BF5B41D8BF5B1002EF6A7 /* Images */ = {
isa = PBXGroup;
children = (
F08714D51DC384810075F633 /* start_chat.png */,
F08714D61DC384810075F633 /* start_chat@2x.png */,
F08714D71DC384810075F633 /* start_chat@3x.png */,
F08714C41DB9EFEE0075F633 /* directChatOff.png */,
F08714C51DB9EFEE0075F633 /* directChatOff@2x.png */,
F08714C61DB9EFEE0075F633 /* directChatOff@3x.png */,
@ -1568,6 +1585,7 @@
F0D2D9861C197DCB007B8C96 /* RoomIncomingAttachmentWithoutSenderInfoBubbleCell.xib in Resources */,
F023A0141D9034FE00C517FB /* call_video_mute_off_icon@2x.png in Resources */,
F03BF6881D8BF5B1002EF6A7 /* error@3x.png in Resources */,
F08714D81DC384810075F633 /* start_chat.png in Resources */,
7165A25C1C05CD42003635D7 /* SegmentedViewController.xib in Resources */,
F03BF65F1D8BF5B1002EF6A7 /* call_speaker_off_icon@2x.png in Resources */,
F03BF6B41D8BF5B1002EF6A7 /* priorityLow@2x.png in Resources */,
@ -1599,12 +1617,14 @@
F0C47F081D7766F200A7929E /* ringback.mp3 in Resources */,
F023A0101D9034FE00C517FB /* call_audio_mute_on_icon.png in Resources */,
F03BF6C21D8BF5B1002EF6A7 /* search_icon.png in Resources */,
F08714DA1DC384810075F633 /* start_chat@3x.png in Resources */,
F03BF65B1D8BF5B1002EF6A7 /* call_hangup_icon.png in Resources */,
F03BF6A31D8BF5B1002EF6A7 /* newmessages@3x.png in Resources */,
F0C34B701C15CA2E00C36F09 /* RoomOutgoingAttachmentWithPaginationTitleBubbleCell.xib in Resources */,
F03BF6C01D8BF5B1002EF6A7 /* search_bg@2x.png in Resources */,
F03BF6C41D8BF5B1002EF6A7 /* search_icon@3x.png in Resources */,
F023A0111D9034FE00C517FB /* call_audio_mute_on_icon@2x.png in Resources */,
F08714D91DC384810075F633 /* start_chat@2x.png in Resources */,
322574E51D86E0C1009181D3 /* InfoPlist.strings in Resources */,
F083C4931D9EAFC500E5246C /* file_photo_icon.png in Resources */,
F03BF6C51D8BF5B1002EF6A7 /* selection_tick.png in Resources */,
@ -1774,6 +1794,7 @@
F03BF6C81D8BF5B1002EF6A7 /* selection_untick.png in Resources */,
32A887221C89B9580037DC17 /* SimpleRoomTitleView.xib in Resources */,
F07ECA4E1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.xib in Resources */,
F08714D41DC3709C0075F633 /* RoomTableViewCell.xib in Resources */,
F03BF6961D8BF5B1002EF6A7 /* leave@2x.png in Resources */,
F0CC4DC11C4E26FA003BBE45 /* MediaAlbumTableCell.xib in Resources */,
);
@ -1915,6 +1936,7 @@
F0D2D9851C197DCB007B8C96 /* RoomIncomingAttachmentWithoutSenderInfoBubbleCell.m in Sources */,
71046D5E1C0C639300DCA984 /* RoomTitleView.m in Sources */,
F07ECA4D1D2BB0A60060C09F /* TableViewCellWithCheckBoxes.m in Sources */,
F08714D31DC3709C0075F633 /* RoomTableViewCell.m in Sources */,
F02BB04B1CBE2EE70022A025 /* PreviewRoomTitleView.m in Sources */,
F0C34B631C15C28300C36F09 /* RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.m in Sources */,
F09EE0061C5134BE0078712F /* RoomOutgoingTextMsgWithoutSenderNameBubbleCell.m in Sources */,

View file

@ -108,8 +108,8 @@ extern NSString *const kAppDelegateNetworkStatusDidChangeNotification;
- (void)showRoom:(NSString*)roomId andEventId:(NSString*)eventId withMatrixSession:(MXSession*)mxSession;
// Reopen an existing private OneToOne room with this userId or creates a new one (if it doesn't exist)
- (void)startPrivateOneToOneRoomWithUserId:(NSString*)userId completion:(void (^)(void))completion;
// Creates a new direct chat with the provided user id
- (void)createDirectChatWithUserId:(NSString*)userId completion:(void (^)(void))completion;
/**
Process the fragment part of a vector.im link.

View file

@ -1817,7 +1817,7 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
_visibleRoomId = roomId;
}
- (void)startPrivateOneToOneRoomWithUserId:(NSString*)userId completion:(void (^)(void))completion
- (void)createDirectChatWithUserId:(NSString*)userId completion:(void (^)(void))completion
{
// Handle here potential multiple accounts
[self selectMatrixAccount:^(MXKAccount *selectedAccount) {
@ -1826,55 +1826,39 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
if (mxSession)
{
MXRoom* mxRoom = [mxSession privateOneToOneRoomWithUserId:userId];
// Create a new room by inviting the other user only if it is defined and not oneself
NSArray *invite = ((userId && ![mxSession.myUser.userId isEqualToString:userId]) ? @[userId] : nil);
// if the room exists
if (mxRoom)
{
// open it
[self showRoom:mxRoom.state.roomId andEventId:nil withMatrixSession:mxSession];
if (completion)
{
completion();
}
}
else
{
// Create a new room by inviting the other user only if it is defined and not oneself
NSArray *invite = ((userId && ![mxSession.myUser.userId isEqualToString:userId]) ? @[userId] : nil);
[mxSession createRoom:nil
visibility:kMXRoomDirectoryVisibilityPrivate
roomAlias:nil
topic:nil
invite:invite
invite3PID:nil
isDirect:(invite.count != 0)
success:^(MXRoom *room) {
// Open created room
[self showRoom:room.state.roomId andEventId:nil withMatrixSession:mxSession];
if (completion)
{
completion();
}
[mxSession createRoom:nil
visibility:kMXRoomDirectoryVisibilityPrivate
roomAlias:nil
topic:nil
invite:invite
invite3PID:nil
isDirect:(invite.count != 0)
success:^(MXRoom *room) {
// Open created room
[self showRoom:room.state.roomId andEventId:nil withMatrixSession:mxSession];
if (completion)
{
completion();
}
failure:^(NSError *error) {
NSLog(@"[AppDelegate] Create room failed");
//Alert user
[self showErrorAsAlert:error];
if (completion)
{
completion();
}
}];
}
}
failure:^(NSError *error) {
NSLog(@"[AppDelegate] Create direct chat failed");
//Alert user
[self showErrorAsAlert:error];
if (completion)
{
completion();
}
}];
}
else if (completion)
{

Binary file not shown.

After

Width:  |  Height:  |  Size: 956 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -141,6 +141,10 @@
"room_participants_now" = "now";
"room_participants_ago" = "ago";
"room_participants_action_section_admin_tools" = "Admin tools";
"room_participants_action_section_direct_chats" = "Direct chats";
"room_participants_action_section_other" = "Other";
"room_participants_action_invite" = "Invite";
"room_participants_action_leave" = "Leave this room";
"room_participants_action_remove" = "Remove from this room";
@ -151,7 +155,7 @@
"room_participants_action_set_default_power_level" = "Reset to normal user";
"room_participants_action_set_moderator" = "Make moderator";
"room_participants_action_set_admin" = "Make admin";
"room_participants_action_start_chat" = "Start chat";
"room_participants_action_start_new_chat" = "Start new chat";
"room_participants_action_start_voice_call" = "Start voice call";
"room_participants_action_start_video_call" = "Start video call";
"room_participants_action_mention" = "Mention";

View file

@ -27,10 +27,17 @@
#import "AvatarGenerator.h"
#import "Tools.h"
#import "TableViewCellWithButton.h"
#import "RoomTableViewCell.h"
#import "TableViewCellWithButton.h"
#import "GBDeviceInfo_iOS.h"
#define TABLEVIEW_ROW_CELL_HEIGHT 46
#define TABLEVIEW_SECTION_HEADER_HEIGHT 28
#define TABLEVIEW_SECTION_HEADER_HEIGHT_WHEN_HIDDEN 0.01f
@interface ContactDetailsViewController ()
{
RoomMemberTitleView* contactTitleView;
@ -50,9 +57,16 @@
id mxPresenceObserver;
/**
List of the allowed actions on this member.
List of the basic actions on this contact.
*/
NSMutableArray<NSNumber*> *actionsArray;
NSInteger actionsIndex;
/**
List of the direct chats (room ids) with this contact.
*/
NSArray<NSString*> *directChatsArray;
NSInteger directChatsIndex;
/**
mask view while processing a request
@ -172,6 +186,10 @@
constant:0.0f];
[NSLayoutConstraint activateConstraints:@[topConstraint, bottomConstraint, leadingConstraint, trailingConstraint]];
// Register collection view cell class
[self.tableView registerClass:TableViewCellWithButton.class forCellReuseIdentifier:[TableViewCellWithButton defaultReuseIdentifier]];
[self.tableView registerClass:RoomTableViewCell.class forCellReuseIdentifier:[RoomTableViewCell defaultReuseIdentifier]];
// Hide line separators of empty cells
self.tableView.tableFooterView = [[UIView alloc] init];
@ -253,6 +271,7 @@
contactTitleView = nil;
actionsArray = nil;
directChatsArray = nil;
[self removePendingActionMask];
@ -493,21 +512,27 @@
#pragma mark - TableView data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
[actionsArray removeAllObjects];
NSInteger sectionCount = 0;
if (_contact.matrixIdentifiers.count)
[actionsArray removeAllObjects];
directChatsArray = nil;
actionsIndex = directChatsIndex = -1;
if (!self.mainSession)
{
// Consider the case of the user himself
if ([_contact.matrixIdentifiers indexOfObject:self.mainSession.myUser.userId] != NSNotFound)
return 0;
}
NSString *matrixId = self.firstMatrixId;
if (matrixId.length)
{
// Check whether the contact is not the user himself
if (![matrixId isEqualToString:self.mainSession.myUser.userId])
{
[actionsArray addObject:@(ContactDetailsActionStartChat)];
}
else
{
[actionsArray addObject:@(ContactDetailsActionStartChat)];
if (self.enableVoipCall)
{
// Offer voip call options
@ -516,7 +541,7 @@
}
// Check whether the option Ignore may be presented
if (![self.mainSession isUserIgnored:self.firstMatrixId])
if (![self.mainSession isUserIgnored:matrixId])
{
[actionsArray addObject:@(ContactDetailsActionIgnore)];
}
@ -524,15 +549,51 @@
{
[actionsArray addObject:@(ContactDetailsActionUnignore)];
}
actionsIndex = sectionCount++;
}
// Retrieve the existing direct chats
directChatsArray = self.mainSession.directRooms[matrixId];
directChatsIndex = sectionCount++;
}
// Else check whether the contact has been instantiated with an email or a matrix id
else if ([MXTools isEmailAddress:_contact.displayName] || [MXTools isMatrixUserIdentifier:_contact.displayName])
else if ([MXTools isEmailAddress:_contact.displayName])
{
[actionsArray addObject:@(ContactDetailsActionStartChat)];
directChatsIndex = sectionCount++;
}
else if ([MXTools isMatrixUserIdentifier:_contact.displayName])
{
// Retrieve the existing direct chats
directChatsArray = self.mainSession.directRooms[_contact.displayName];
directChatsIndex = sectionCount++;
}
return actionsArray.count;
return sectionCount;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == actionsIndex)
{
return actionsArray.count;
}
else if (section == directChatsIndex)
{
return (directChatsArray.count + 1);
}
return 0;
}
- (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if (section == directChatsIndex)
{
return NSLocalizedStringFromTable(@"room_participants_action_section_direct_chats", @"Vector", nil);
}
return nil;
}
- (NSString*)actionButtonTitle:(ContactDetailsAction)action
@ -565,25 +626,56 @@
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger row = indexPath.row;
UITableViewCell *cell;
TableViewCellWithButton *cell = [[TableViewCellWithButton alloc] init];
if (row < actionsArray.count)
if (indexPath.section == actionsIndex)
{
NSNumber *actionNumber = [actionsArray objectAtIndex:row];
TableViewCellWithButton *cellWithButton = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithButton defaultReuseIdentifier] forIndexPath:indexPath];
NSString *title = [self actionButtonTitle:actionNumber.unsignedIntegerValue];
if (indexPath.row < actionsArray.count)
{
NSNumber *actionNumber = [actionsArray objectAtIndex:indexPath.row];
NSString *title = [self actionButtonTitle:actionNumber.unsignedIntegerValue];
[cellWithButton.mxkButton setTitle:title forState:UIControlStateNormal];
[cellWithButton.mxkButton setTitle:title forState:UIControlStateHighlighted];
[cellWithButton.mxkButton setTitleColor:kVectorTextColorBlack forState:UIControlStateNormal];
[cellWithButton.mxkButton setTitleColor:kVectorTextColorBlack forState:UIControlStateHighlighted];
[cellWithButton.mxkButton addTarget:self action:@selector(onActionButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
cellWithButton.mxkButton.tag = actionNumber.unsignedIntegerValue;
}
[cell.mxkButton setTitle:title forState:UIControlStateNormal];
[cell.mxkButton setTitle:title forState:UIControlStateHighlighted];
cell = cellWithButton;
}
else if (indexPath.section == directChatsIndex)
{
RoomTableViewCell *roomCell = [tableView dequeueReusableCellWithIdentifier:[RoomTableViewCell defaultReuseIdentifier] forIndexPath:indexPath];
[cell.mxkButton setTitleColor:kVectorTextColorBlack forState:UIControlStateNormal];
[cell.mxkButton setTitleColor:kVectorTextColorBlack forState:UIControlStateHighlighted];
if (indexPath.row < directChatsArray.count)
{
MXRoom *room = [self.mainSession roomWithRoomId:directChatsArray[indexPath.row]];
if (room)
{
[roomCell render:room];
}
}
else
{
roomCell.avatarImageView.image = [UIImage imageNamed:@"start_chat"];
roomCell.avatarImageView.backgroundColor = [UIColor clearColor];
roomCell.titleLabel.text = NSLocalizedStringFromTable(@"room_participants_action_start_new_chat", @"Vector", nil);
}
[cell.mxkButton addTarget:self action:@selector(onActionButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
cell.mxkButton.tag = actionNumber.unsignedIntegerValue;
cell = roomCell;
}
else
{
// Create a fake cell to prevent app from crashing
cell = [[UITableViewCell alloc] init];
}
return cell;
@ -591,14 +683,53 @@
#pragma mark - TableView delegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == directChatsIndex)
{
return [RoomTableViewCell cellHeight];
}
return TABLEVIEW_ROW_CELL_HEIGHT;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if (section == actionsIndex)
{
return TABLEVIEW_SECTION_HEADER_HEIGHT_WHEN_HIDDEN;
}
return TABLEVIEW_SECTION_HEADER_HEIGHT;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
if (selectedCell && [selectedCell isKindOfClass:TableViewCellWithButton.class])
if (indexPath.section == directChatsIndex)
{
TableViewCellWithButton *cell = (TableViewCellWithButton*)selectedCell;
[self onActionButtonPressed:cell.mxkButton];
if (indexPath.row < directChatsArray.count)
{
// Open this room
[[AppDelegate theDelegate] showRoom:directChatsArray[indexPath.row] andEventId:nil withMatrixSession:self.mainSession];
}
else
{
// Create a new direct chat with the member
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.tag = ContactDetailsActionStartChat;
[self onActionButtonPressed:button];
}
}
else
{
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
if (selectedCell && [selectedCell isKindOfClass:TableViewCellWithButton.class])
{
TableViewCellWithButton *cell = (TableViewCellWithButton*)selectedCell;
[self onActionButtonPressed:cell.mxkButton];
}
}
}
@ -719,7 +850,7 @@
if (_contact.matrixIdentifiers.count)
{
[[AppDelegate theDelegate] startPrivateOneToOneRoomWithUserId:self.firstMatrixId completion:^{
[[AppDelegate theDelegate] createDirectChatWithUserId:self.firstMatrixId completion:^{
[self removePendingActionMask];
}];

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10117" systemVersion="15G1004" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
@ -95,9 +95,9 @@
<constraint firstAttribute="height" constant="198" id="bkF-2R-F6Q"/>
</constraints>
</imageView>
<tableView clipsSubviews="YES" contentMode="scaleToFill" bounces="NO" style="plain" separatorStyle="default" rowHeight="46" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="R6u-PR-DcU">
<tableView clipsSubviews="YES" contentMode="scaleToFill" style="grouped" separatorStyle="default" rowHeight="46" sectionHeaderHeight="28" sectionFooterHeight="8" translatesAutoresizingMaskIntoConstraints="NO" id="R6u-PR-DcU">
<rect key="frame" x="0.0" y="192" width="600" height="408"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="calibratedRGB"/>
<connections>
<outlet property="dataSource" destination="-1" id="DbO-MV-3hm"/>
<outlet property="delegate" destination="-1" id="dFh-bI-jUW"/>

View file

@ -626,7 +626,7 @@
{
[self startActivityIndicator];
[room setIsDirect:isDirect success:^{
[room setIsDirect:isDirect withUserId:nil success:^{
[self stopActivityIndicator];

View file

@ -28,11 +28,34 @@
#import "Tools.h"
#import "TableViewCellWithButton.h"
#import "RoomTableViewCell.h"
#define TABLEVIEW_ROW_CELL_HEIGHT 46
#define TABLEVIEW_SECTION_HEADER_HEIGHT 28
#define TABLEVIEW_SECTION_HEADER_HEIGHT_WHEN_HIDDEN 0.01f
@interface RoomMemberDetailsViewController ()
{
RoomMemberTitleView* memberTitleView;
/**
List of the admin actions on this member.
*/
NSMutableArray<NSNumber*> *adminActionsArray;
NSInteger adminToolsIndex;
/**
List of the basic actions on this member.
*/
NSMutableArray<NSNumber*> *otherActionsArray;
NSInteger otherActionsIndex;
/**
List of the direct chats (room ids) with this member.
*/
NSArray<NSString*> *directChatsArray;
NSInteger directChatsIndex;
/**
Observe UIApplicationWillChangeStatusBarOrientationNotification to hide/show bubbles bg.
*/
@ -63,6 +86,9 @@
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
adminActionsArray = [[NSMutableArray alloc] init];
otherActionsArray = [[NSMutableArray alloc] init];
// Setup `MXKViewControllerHandling` properties
self.defaultBarTintColor = kVectorNavBarTintColor;
self.enableBarTintColorStatusChange = NO;
@ -135,6 +161,10 @@
constant:0.0f];
[NSLayoutConstraint activateConstraints:@[topConstraint, bottomConstraint, leadingConstraint, trailingConstraint]];
// Register collection view cell class
[self.tableView registerClass:TableViewCellWithButton.class forCellReuseIdentifier:[TableViewCellWithButton defaultReuseIdentifier]];
[self.tableView registerClass:RoomTableViewCell.class forCellReuseIdentifier:[RoomTableViewCell defaultReuseIdentifier]];
// Hide line separators of empty cells
self.tableView.tableFooterView = [[UIView alloc] init];
@ -195,6 +225,10 @@
{
[super destroy];
adminActionsArray = nil;
otherActionsArray = nil;
directChatsArray = nil;
if (UIApplicationWillChangeStatusBarOrientationNotificationObserver)
{
[[NSNotificationCenter defaultCenter] removeObserver:UIApplicationWillChangeStatusBarOrientationNotificationObserver];
@ -306,19 +340,23 @@
#pragma mark - TableView data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSInteger sectionCount = 0;
// Check user's power level before allowing an action (kick, ban, ...)
MXRoomPowerLevels *powerLevels = [self.mxRoom.state powerLevels];
NSInteger memberPowerLevel = [powerLevels powerLevelOfUserWithUserID:self.mxRoomMember.userId];
NSInteger oneSelfPowerLevel = [powerLevels powerLevelOfUserWithUserID:self.mainSession.myUser.userId];
[actionsArray removeAllObjects];
[adminActionsArray removeAllObjects];
[otherActionsArray removeAllObjects];
directChatsArray = nil;
// Consider the case of the user himself
if ([self.mxRoomMember.userId isEqualToString:self.mainSession.myUser.userId])
{
[actionsArray addObject:@(MXKRoomMemberDetailsActionLeave)];
[otherActionsArray addObject:@(MXKRoomMemberDetailsActionLeave)];
if (oneSelfPowerLevel >= [powerLevels minimumPowerLevelForSendingEventAsStateEvent:kMXEventTypeStringRoomPowerLevels])
{
@ -337,35 +375,20 @@
if (adminCount > 1)
{
[actionsArray addObject:@(MXKRoomMemberDetailsActionSetModerator)];
[actionsArray addObject:@(MXKRoomMemberDetailsActionSetDefaultPowerLevel)];
[adminActionsArray addObject:@(MXKRoomMemberDetailsActionSetModerator)];
[adminActionsArray addObject:@(MXKRoomMemberDetailsActionSetDefaultPowerLevel)];
}
}
// Check whether the user is moderator (in this case he may reduce his power level to become normal user).
else if (oneSelfPowerLevel >= kVectorRoomModeratorLevel)
{
[actionsArray addObject:@(MXKRoomMemberDetailsActionSetDefaultPowerLevel)];
[adminActionsArray addObject:@(MXKRoomMemberDetailsActionSetDefaultPowerLevel)];
}
}
}
else if (self.mxRoomMember)
{
// offer to start a new chat only if the room is not a 1:1 room with this user
// it does not make sense : it would open the same room
MXRoom* room = [self.mainSession privateOneToOneRoomWithUserId:self.mxRoomMember.userId];
if (!room || (![room.state.roomId isEqualToString:self.mxRoom.state.roomId]))
{
[actionsArray addObject:@(MXKRoomMemberDetailsActionStartChat)];
}
if (self.enableVoipCall)
{
// Offer voip call options
[actionsArray addObject:@(MXKRoomMemberDetailsActionStartVoiceCall)];
[actionsArray addObject:@(MXKRoomMemberDetailsActionStartVideoCall)];
}
// Consider membership of the selected member
// Enumerate admin actions
switch (self.mxRoomMember.membership)
{
case MXMembershipInvite:
@ -377,45 +400,32 @@
// Check whether user is admin
if (oneSelfPowerLevel >= kVectorRoomAdminLevel)
{
[actionsArray addObject:@(MXKRoomMemberDetailsActionSetAdmin)];
[adminActionsArray addObject:@(MXKRoomMemberDetailsActionSetAdmin)];
}
// Check whether the member may become moderator
if (oneSelfPowerLevel >= kVectorRoomModeratorLevel && memberPowerLevel < kVectorRoomModeratorLevel)
{
[actionsArray addObject:@(MXKRoomMemberDetailsActionSetModerator)];
[adminActionsArray addObject:@(MXKRoomMemberDetailsActionSetModerator)];
}
if (memberPowerLevel >= kVectorRoomModeratorLevel)
{
[actionsArray addObject:@(MXKRoomMemberDetailsActionSetDefaultPowerLevel)];
[adminActionsArray addObject:@(MXKRoomMemberDetailsActionSetDefaultPowerLevel)];
}
}
// Check conditions to be able to kick someone
if (oneSelfPowerLevel >= [powerLevels kick] && oneSelfPowerLevel > memberPowerLevel)
{
[actionsArray addObject:@(MXKRoomMemberDetailsActionKick)];
[adminActionsArray addObject:@(MXKRoomMemberDetailsActionKick)];
}
// Check conditions to be able to ban someone
if (oneSelfPowerLevel >= [powerLevels ban] && oneSelfPowerLevel > memberPowerLevel)
{
[actionsArray addObject:@(MXKRoomMemberDetailsActionBan)];
[adminActionsArray addObject:@(MXKRoomMemberDetailsActionBan)];
}
// Check whether the option Ignore may be presented
if (self.mxRoomMember.membership == MXMembershipJoin)
{
// is he already ignored ?
if (![self.mainSession isUserIgnored:self.mxRoomMember.userId])
{
[actionsArray addObject:@(MXKRoomMemberDetailsActionIgnore)];
}
else
{
[actionsArray addObject:@(MXKRoomMemberDetailsActionUnignore)];
}
}
break;
}
case MXMembershipLeave:
@ -423,12 +433,12 @@
// Check conditions to be able to invite someone
if (oneSelfPowerLevel >= [powerLevels invite])
{
[actionsArray addObject:@(MXKRoomMemberDetailsActionInvite)];
[adminActionsArray addObject:@(MXKRoomMemberDetailsActionInvite)];
}
// Check conditions to be able to ban someone
if (oneSelfPowerLevel >= [powerLevels ban] && oneSelfPowerLevel > memberPowerLevel)
{
[actionsArray addObject:@(MXKRoomMemberDetailsActionBan)];
[adminActionsArray addObject:@(MXKRoomMemberDetailsActionBan)];
}
break;
}
@ -437,7 +447,7 @@
// Check conditions to be able to unban someone
if (oneSelfPowerLevel >= [powerLevels ban] && oneSelfPowerLevel > memberPowerLevel)
{
[actionsArray addObject:@(MXKRoomMemberDetailsActionUnban)];
[adminActionsArray addObject:@(MXKRoomMemberDetailsActionUnban)];
}
break;
}
@ -446,15 +456,85 @@
break;
}
}
// List the other actions
if (self.enableVoipCall)
{
// Offer voip call options
[otherActionsArray addObject:@(MXKRoomMemberDetailsActionStartVoiceCall)];
[otherActionsArray addObject:@(MXKRoomMemberDetailsActionStartVideoCall)];
}
// Check whether the option Ignore may be presented
if (self.mxRoomMember.membership == MXMembershipJoin)
{
// is he already ignored ?
if (![self.mainSession isUserIgnored:self.mxRoomMember.userId])
{
[otherActionsArray addObject:@(MXKRoomMemberDetailsActionIgnore)];
}
else
{
[otherActionsArray addObject:@(MXKRoomMemberDetailsActionUnignore)];
}
}
if (self.enableMention)
{
// Add mention option
[otherActionsArray addObject:@(MXKRoomMemberDetailsActionMention)];
}
}
if (self.enableMention)
// Retrieve the existing direct chats
directChatsArray = self.mainSession.directRooms[self.mxRoomMember.userId];
adminToolsIndex = otherActionsIndex = directChatsIndex = -1;
if (otherActionsArray.count)
{
// Add mention option
[actionsArray addObject:@(MXKRoomMemberDetailsActionMention)];
otherActionsIndex = sectionCount++;
}
if (adminActionsArray.count)
{
adminToolsIndex = sectionCount++;
}
directChatsIndex = sectionCount++;
return sectionCount;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == adminToolsIndex)
{
return adminActionsArray.count;
}
else if (section == otherActionsIndex)
{
return otherActionsArray.count;
}
else if (section == directChatsIndex)
{
return (directChatsArray.count + 1);
}
return actionsArray.count;
return 0;
}
- (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if (section == adminToolsIndex)
{
return NSLocalizedStringFromTable(@"room_participants_action_section_admin_tools", @"Vector", nil);
}
else if (section == directChatsIndex)
{
return NSLocalizedStringFromTable(@"room_participants_action_section_direct_chats", @"Vector", nil);
}
return nil;
}
- (NSString*)actionButtonTitle:(MXKRoomMemberDetailsAction)action
@ -514,48 +594,126 @@
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger row = indexPath.row;
UITableViewCell *cell;
TableViewCellWithButton *cell = [[TableViewCellWithButton alloc] init];
if (row < actionsArray.count)
if (indexPath.section == adminToolsIndex || indexPath.section == otherActionsIndex)
{
NSNumber *actionNumber = [actionsArray objectAtIndex:row];
TableViewCellWithButton *cellWithButton = [tableView dequeueReusableCellWithIdentifier:[TableViewCellWithButton defaultReuseIdentifier] forIndexPath:indexPath];
NSString *title = [self actionButtonTitle:actionNumber.unsignedIntegerValue];
[cell.mxkButton setTitle:title forState:UIControlStateNormal];
[cell.mxkButton setTitle:title forState:UIControlStateHighlighted];
if (actionNumber.unsignedIntegerValue == MXKRoomMemberDetailsActionKick)
NSNumber *actionNumber;
if (indexPath.section == adminToolsIndex && indexPath.row < adminActionsArray.count)
{
[cell.mxkButton setTitleColor:kVectorColorPinkRed forState:UIControlStateNormal];
[cell.mxkButton setTitleColor:kVectorColorPinkRed forState:UIControlStateHighlighted];
actionNumber = [adminActionsArray objectAtIndex:indexPath.row];
}
else if (indexPath.section == otherActionsIndex && indexPath.row < otherActionsArray.count)
{
actionNumber = [otherActionsArray objectAtIndex:indexPath.row];
}
if (actionNumber)
{
NSString *title = [self actionButtonTitle:actionNumber.unsignedIntegerValue];
[cellWithButton.mxkButton setTitle:title forState:UIControlStateNormal];
[cellWithButton.mxkButton setTitle:title forState:UIControlStateHighlighted];
if (actionNumber.unsignedIntegerValue == MXKRoomMemberDetailsActionKick)
{
[cellWithButton.mxkButton setTitleColor:kVectorColorPinkRed forState:UIControlStateNormal];
[cellWithButton.mxkButton setTitleColor:kVectorColorPinkRed forState:UIControlStateHighlighted];
}
else
{
[cellWithButton.mxkButton setTitleColor:kVectorTextColorBlack forState:UIControlStateNormal];
[cellWithButton.mxkButton setTitleColor:kVectorTextColorBlack forState:UIControlStateHighlighted];
}
[cellWithButton.mxkButton addTarget:self action:@selector(onActionButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
cellWithButton.mxkButton.tag = actionNumber.unsignedIntegerValue;
}
cell = cellWithButton;
}
else if (indexPath.section == directChatsIndex)
{
RoomTableViewCell *roomCell = [tableView dequeueReusableCellWithIdentifier:[RoomTableViewCell defaultReuseIdentifier] forIndexPath:indexPath];
if (indexPath.row < directChatsArray.count)
{
MXRoom *room = [self.mainSession roomWithRoomId:directChatsArray[indexPath.row]];
if (room)
{
[roomCell render:room];
}
}
else
{
[cell.mxkButton setTitleColor:kVectorTextColorBlack forState:UIControlStateNormal];
[cell.mxkButton setTitleColor:kVectorTextColorBlack forState:UIControlStateHighlighted];
roomCell.avatarImageView.image = [UIImage imageNamed:@"start_chat"];
roomCell.avatarImageView.backgroundColor = [UIColor clearColor];
roomCell.titleLabel.text = NSLocalizedStringFromTable(@"room_participants_action_start_new_chat", @"Vector", nil);
}
[cell.mxkButton addTarget:self action:@selector(onActionButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
cell.mxkButton.tag = actionNumber.unsignedIntegerValue;
cell = roomCell;
}
else
{
// Create a fake cell to prevent app from crashing
cell = [[UITableViewCell alloc] init];
}
return cell;
}
#pragma mark - TableView delegate
#pragma mark - UITableView delegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == directChatsIndex)
{
return [RoomTableViewCell cellHeight];
}
return TABLEVIEW_ROW_CELL_HEIGHT;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if (section == otherActionsIndex)
{
return TABLEVIEW_SECTION_HEADER_HEIGHT_WHEN_HIDDEN;
}
return TABLEVIEW_SECTION_HEADER_HEIGHT;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
if (selectedCell && [selectedCell isKindOfClass:TableViewCellWithButton.class])
if (indexPath.section == directChatsIndex)
{
TableViewCellWithButton *cell = (TableViewCellWithButton*)selectedCell;
[self onActionButtonPressed:cell.mxkButton];
if (indexPath.row < directChatsArray.count)
{
// Open this room
[[AppDelegate theDelegate] showRoom:directChatsArray[indexPath.row] andEventId:nil withMatrixSession:self.mainSession];
}
else
{
// Create a new direct chat with the member
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.tag = MXKRoomMemberDetailsActionStartChat;
[super onActionButtonPressed:button];
}
}
else
{
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
if (selectedCell && [selectedCell isKindOfClass:TableViewCellWithButton.class])
{
TableViewCellWithButton *cell = (TableViewCellWithButton*)selectedCell;
[self onActionButtonPressed:cell.mxkButton];
}
}
}

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10117" systemVersion="15G1004" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
@ -112,9 +112,9 @@
<constraint firstAttribute="height" constant="198" id="bkF-2R-F6Q"/>
</constraints>
</imageView>
<tableView clipsSubviews="YES" contentMode="scaleToFill" bounces="NO" style="plain" separatorStyle="default" rowHeight="46" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="R6u-PR-DcU">
<tableView clipsSubviews="YES" contentMode="scaleToFill" style="grouped" separatorStyle="default" rowHeight="46" sectionHeaderHeight="28" sectionFooterHeight="8" translatesAutoresizingMaskIntoConstraints="NO" id="R6u-PR-DcU">
<rect key="frame" x="0.0" y="192" width="600" height="408"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="calibratedRGB"/>
<connections>
<outlet property="dataSource" destination="-1" id="DbO-MV-3hm"/>
<outlet property="delegate" destination="-1" id="dFh-bI-jUW"/>

View file

@ -1177,6 +1177,7 @@
// Set delegate to handle action on member (start chat, mention)
memberDetailsViewController.delegate = self;
memberDetailsViewController.enableMention = _enableMention;
memberDetailsViewController.enableVoipCall = YES;
[memberDetailsViewController displayRoomMember:contact.mxMember withMatrixRoom:self.mxRoom];
@ -1214,7 +1215,7 @@
- (void)roomMemberDetailsViewController:(MXKRoomMemberDetailsViewController *)roomMemberDetailsViewController startChatWithMemberId:(NSString *)matrixId completion:(void (^)(void))completion
{
[[AppDelegate theDelegate] startPrivateOneToOneRoomWithUserId:matrixId completion:completion];
[[AppDelegate theDelegate] createDirectChatWithUserId:matrixId completion:completion];
}
- (void)roomMemberDetailsViewController:(MXKRoomMemberDetailsViewController *)roomMemberDetailsViewController mention:(MXRoomMember*)member

View file

@ -2513,6 +2513,7 @@ NSString *const kRoomSettingsAdvancedCellViewIdentifier = @"kRoomSettingsAdvance
RoomMemberDetailsViewController *roomMemberDetailsViewController = [RoomMemberDetailsViewController roomMemberDetailsViewController];
[roomMemberDetailsViewController displayRoomMember:bannedMembers[indexPath.row] withMatrixRoom:mxRoom];
roomMemberDetailsViewController.delegate = self;
roomMemberDetailsViewController.enableVoipCall = YES;
[self.parentViewController.navigationController pushViewController:roomMemberDetailsViewController animated:NO];
}
@ -2712,7 +2713,7 @@ NSString *const kRoomSettingsAdvancedCellViewIdentifier = @"kRoomSettingsAdvance
- (void)roomMemberDetailsViewController:(MXKRoomMemberDetailsViewController *)roomMemberDetailsViewController startChatWithMemberId:(NSString *)matrixId completion:(void (^)(void))completion
{
[[AppDelegate theDelegate] startPrivateOneToOneRoomWithUserId:matrixId completion:completion];
[[AppDelegate theDelegate] createDirectChatWithUserId:matrixId completion:completion];
}
#pragma mark - actions

View file

@ -2064,6 +2064,7 @@
// Set delegate to handle action on member (start chat, memtion)
memberViewController.delegate = self;
memberViewController.enableMention = YES;
memberViewController.enableVoipCall = YES;
[memberViewController displayRoomMember:selectedRoomMember withMatrixRoom:self.roomDataSource.room];
@ -2191,7 +2192,7 @@
- (void)roomMemberDetailsViewController:(MXKRoomMemberDetailsViewController *)roomMemberDetailsViewController startChatWithMemberId:(NSString *)matrixId completion:(void (^)(void))completion
{
[[AppDelegate theDelegate] startPrivateOneToOneRoomWithUserId:matrixId completion:completion];
[[AppDelegate theDelegate] createDirectChatWithUserId:matrixId completion:completion];
}
- (void)roomMemberDetailsViewController:(MXKRoomMemberDetailsViewController *)roomMemberDetailsViewController mention:(MXRoomMember*)member

View file

@ -0,0 +1,41 @@
/*
Copyright 2016 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 <MatrixKit/MatrixKit.h>
/**
The `RoomTableViewCell` cell displays a room (avatar and displayname).
*/
@interface RoomTableViewCell : MXKTableViewCell
@property (weak, nonatomic) IBOutlet MXKImageView *avatarImageView;
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
/**
Update the information displayed by the cell.
@param rooom the room to render.
*/
- (void)render:(MXRoom *)room;
/**
Get the cell height.
@return the cell height.
*/
+ (CGFloat)cellHeight;
@end

View file

@ -0,0 +1,55 @@
/*
Copyright 2016 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 "RoomTableViewCell.h"
#import "VectorDesignValues.h"
#import "MXRoom+Vector.h"
@implementation RoomTableViewCell
#pragma mark - Class methods
- (void)awakeFromNib
{
[super awakeFromNib];
self.titleLabel.textColor = kVectorTextColorBlack;
}
- (void)layoutSubviews
{
[super layoutSubviews];
// Round image view
[self.avatarImageView.layer setCornerRadius:self.avatarImageView.frame.size.width / 2];
self.avatarImageView.clipsToBounds = YES;
}
- (void)render:(MXRoom *)room
{
[room setRoomAvatarImageIn:self.avatarImageView];
self.avatarImageView.backgroundColor = [UIColor clearColor];
self.titleLabel.text = room.state.displayname;
}
+ (CGFloat)cellHeight
{
return 74;
}
@end

View file

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10117" systemVersion="15G1004" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" id="L2L-l5-wPx" customClass="RoomTableViewCell">
<rect key="frame" x="0.0" y="0.0" width="600" height="74"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="L2L-l5-wPx" id="aXz-IR-jj5">
<rect key="frame" x="0.0" y="0.0" width="600" height="73"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="FfX-ul-Kr4" customClass="MXKImageView">
<rect key="frame" x="14" y="16" width="42" height="42"/>
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="width" constant="42" id="DCk-EO-Wpn"/>
<constraint firstAttribute="width" secondItem="FfX-ul-Kr4" secondAttribute="height" multiplier="1:1" id="ycc-8M-xEj"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Lg1-xQ-AGn">
<rect key="frame" x="70" y="27" width="34" height="20"/>
<constraints>
<constraint firstAttribute="height" constant="20" id="NW9-MB-gf4"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="Lg1-xQ-AGn" firstAttribute="leading" secondItem="FfX-ul-Kr4" secondAttribute="trailing" constant="14" id="A6H-TC-2Pg"/>
<constraint firstItem="Lg1-xQ-AGn" firstAttribute="centerY" secondItem="aXz-IR-jj5" secondAttribute="centerY" id="O6E-Di-2d4"/>
<constraint firstAttribute="trailingMargin" relation="greaterThanOrEqual" secondItem="Lg1-xQ-AGn" secondAttribute="trailing" constant="15" id="U1F-vo-7f6"/>
<constraint firstItem="FfX-ul-Kr4" firstAttribute="centerY" secondItem="aXz-IR-jj5" secondAttribute="centerY" id="gUw-GV-DPX"/>
<constraint firstItem="FfX-ul-Kr4" firstAttribute="leading" secondItem="aXz-IR-jj5" secondAttribute="leadingMargin" constant="6" id="qey-6T-URF"/>
</constraints>
</tableViewCellContentView>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<connections>
<outlet property="avatarImageView" destination="FfX-ul-Kr4" id="NOo-Lj-BBY"/>
<outlet property="titleLabel" destination="Lg1-xQ-AGn" id="uqU-hH-KT0"/>
</connections>
</tableViewCell>
</objects>
</document>