mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-05-23 08:02:09 +02:00
Add Room Member Details screen
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 116 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
@@ -92,13 +92,26 @@
|
||||
"room_participants_invite_malformed_id_title" = "Invite Error";
|
||||
"room_participants_invite_malformed_id" = "Malformed ID. Should be an email address or a Matrix ID like '@localpart:domain'";
|
||||
|
||||
"room_participants_active" = "Active";
|
||||
"room_participants_active" = "Online";
|
||||
"room_participants_invite" = "Invite";
|
||||
"room_participants_leave" = "Left";
|
||||
"room_participants_ban" = "Banned";
|
||||
"room_participants_active_less_1_hour" = "Active less 1 hour ago";
|
||||
"room_participants_active_less_x_hours" = "Active less %lu hours ago";
|
||||
"room_participants_active_less_x_days" = "Active less %lu days ago";
|
||||
"room_participants_active_less_1_hour" = "Offline";
|
||||
"room_participants_active_less_x_hours" = "Offline %luh ago";
|
||||
"room_participants_active_less_x_days" = "Offline %lu days ago";
|
||||
|
||||
"room_participants_action_invite" = "Invite";
|
||||
"room_participants_action_leave" = "Leave from this room";
|
||||
"room_participants_action_remove" = "Remove from this room";
|
||||
"room_participants_action_ban" = "Block";
|
||||
"room_participants_action_unban" = "Unblock";
|
||||
"room_participants_action_set_default_power_level" = "Reset power level";
|
||||
"room_participants_action_set_moderator" = "Make moderator";
|
||||
"room_participants_action_set_admin" = "Make admin";
|
||||
"room_participants_action_set_custom_power_level" = "Set custom power level";
|
||||
"room_participants_action_start_chat" = "Start chat";
|
||||
"room_participants_action_start_voice_call" = "Start voice call";
|
||||
"room_participants_action_start_video_call" = "Start video call";
|
||||
|
||||
// Chat
|
||||
"room_one_user_is_typing" = "%@ is typing...";
|
||||
|
||||
@@ -34,12 +34,17 @@ extern UIColor *kVectorColorOrange;
|
||||
|
||||
#pragma mark - Vector Text Colors
|
||||
extern UIColor *kVectorTextColorBlack;
|
||||
extern UIColor *kVectorTextColorRed;
|
||||
extern UIColor *kVectorTextColorDarkGray;
|
||||
extern UIColor *kVectorTextColorGray;
|
||||
|
||||
#pragma mark - Vector Navigation Bar Tint Color
|
||||
extern UIColor *kVectorNavBarTintColor;
|
||||
|
||||
#pragma mark - Vector Standard Room Member Power Level
|
||||
extern NSUInteger const kVectorRoomModeratorLevel;
|
||||
extern NSUInteger const kVectorRoomAdminLevel;
|
||||
|
||||
/**
|
||||
`VectorDesignValues` class manages the Vector design parameters
|
||||
*/
|
||||
|
||||
@@ -23,11 +23,15 @@ UIColor *kVectorColorSiver;
|
||||
UIColor *kVectorColorOrange;
|
||||
|
||||
UIColor *kVectorTextColorBlack;
|
||||
UIColor *kVectorTextColorRed;
|
||||
UIColor *kVectorTextColorDarkGray;
|
||||
UIColor *kVectorTextColorGray;
|
||||
|
||||
UIColor *kVectorNavBarTintColor;
|
||||
|
||||
NSUInteger const kVectorRoomModeratorLevel = 50;
|
||||
NSUInteger const kVectorRoomAdminLevel = 100;
|
||||
|
||||
@implementation VectorDesignValues
|
||||
|
||||
+ (void)load
|
||||
@@ -42,6 +46,7 @@ UIColor *kVectorNavBarTintColor;
|
||||
kVectorColorSiver = [UIColor colorWithRed:(199.0 / 255.0) green:(199.0 / 255.0) blue:(204.0 / 255.0) alpha:1.0];
|
||||
|
||||
kVectorTextColorBlack = [UIColor colorWithRed:(60.0 / 255.0) green:(60.0 / 255.0) blue:(60.0 / 255.0) alpha:1.0];
|
||||
kVectorTextColorRed = [UIColor colorWithRed:(255.0 / 255.0) green:(0.0 / 255.0) blue:(100.0 / 255.0) alpha:1.0];
|
||||
kVectorTextColorDarkGray = [UIColor colorWithRed:(74.0 / 255.0) green:(74.0 / 255.0) blue:(74.0 / 255.0) alpha:1.0];
|
||||
kVectorTextColorGray = [UIColor colorWithRed:(157.0 / 255.0) green:(157.0 / 255.0) blue:(157.0 / 255.0) alpha:1.0];
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
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>
|
||||
|
||||
@interface RoomMemberDetailsViewController : MXKRoomMemberDetailsViewController
|
||||
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *actionTableViewTopConstraint;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIView *memberHeaderView;
|
||||
@property (weak, nonatomic) IBOutlet UILabel *roomMemberNameLabel;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UILabel *roomMemberStatusLabel;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIImageView *bottomImageView;
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,518 @@
|
||||
/*
|
||||
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 "RoomMemberDetailsViewController.h"
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import "RoomMemberTitleView.h"
|
||||
|
||||
#import "VectorDesignValues.h"
|
||||
|
||||
#import "RageShakeManager.h"
|
||||
|
||||
#import "AvatarGenerator.h"
|
||||
|
||||
#import "TableViewCellWithButton.h"
|
||||
|
||||
@interface RoomMemberDetailsViewController ()
|
||||
{
|
||||
RoomMemberTitleView* memberTitleView;
|
||||
|
||||
/**
|
||||
Observe UIApplicationWillChangeStatusBarOrientationNotification to hide/show bubbles bg.
|
||||
*/
|
||||
id UIApplicationWillChangeStatusBarOrientationNotificationObserver;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation RoomMemberDetailsViewController
|
||||
|
||||
#pragma mark - Class methods
|
||||
|
||||
+ (UINib *)nib
|
||||
{
|
||||
return [UINib nibWithNibName:NSStringFromClass(self.class)
|
||||
bundle:[NSBundle bundleForClass:self.class]];
|
||||
}
|
||||
|
||||
+ (instancetype)roomMemberDetailsViewController
|
||||
{
|
||||
return [[[self class] alloc] initWithNibName:NSStringFromClass(self.class)
|
||||
bundle:[NSBundle bundleForClass:self.class]];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view, typically from a nib.
|
||||
|
||||
// Setup `MXKViewControllerHandling` properties
|
||||
self.defaultBarTintColor = kVectorNavBarTintColor;
|
||||
self.enableBarTintColorStatusChange = NO;
|
||||
self.rageShakeManager = [RageShakeManager sharedManager];
|
||||
|
||||
// Set delegate to handle start chat option
|
||||
self.delegate = [AppDelegate theDelegate];
|
||||
|
||||
self.memberHeaderView.backgroundColor = kVectorColorLightGrey;
|
||||
self.roomMemberNameLabel.textColor = kVectorTextColorBlack;
|
||||
self.roomMemberStatusLabel.textColor = kVectorColorGreen;
|
||||
|
||||
self.navigationItem.titleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 600, 40)];
|
||||
|
||||
memberTitleView = [RoomMemberTitleView roomMemberTitleView];
|
||||
self.memberThumbnail = memberTitleView.memberAvatar;
|
||||
|
||||
// Add the title view and define edge constraints
|
||||
memberTitleView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[self.navigationItem.titleView addSubview:memberTitleView];
|
||||
|
||||
NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:memberTitleView
|
||||
attribute:NSLayoutAttributeTop
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self.navigationItem.titleView
|
||||
attribute:NSLayoutAttributeTop
|
||||
multiplier:1.0f
|
||||
constant:0.0f];
|
||||
NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint constraintWithItem:memberTitleView
|
||||
attribute:NSLayoutAttributeBottom
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self.navigationItem.titleView
|
||||
attribute:NSLayoutAttributeBottom
|
||||
multiplier:1.0f
|
||||
constant:0.0f];
|
||||
NSLayoutConstraint *leadingConstraint = [NSLayoutConstraint constraintWithItem:memberTitleView
|
||||
attribute:NSLayoutAttributeLeading
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self.navigationItem.titleView
|
||||
attribute:NSLayoutAttributeLeading
|
||||
multiplier:1.0f
|
||||
constant:0.0f];
|
||||
NSLayoutConstraint *trailingConstraint = [NSLayoutConstraint constraintWithItem:memberTitleView
|
||||
attribute:NSLayoutAttributeTrailing
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self.navigationItem.titleView
|
||||
attribute:NSLayoutAttributeTrailing
|
||||
multiplier:1.0f
|
||||
constant:0.0f];
|
||||
[NSLayoutConstraint activateConstraints:@[topConstraint, bottomConstraint, leadingConstraint, trailingConstraint]];
|
||||
|
||||
// Hide line separators of empty cells
|
||||
self.tableView.tableFooterView = [[UIView alloc] init];
|
||||
|
||||
// Observe UIApplicationWillChangeStatusBarOrientationNotification to hide/show bubbles bg.
|
||||
UIApplicationWillChangeStatusBarOrientationNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillChangeStatusBarOrientationNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
NSNumber *orientation = (NSNumber*)(notif.userInfo[UIApplicationStatusBarOrientationUserInfoKey]);
|
||||
self.bottomImageView.hidden = (orientation.integerValue == UIInterfaceOrientationLandscapeLeft || orientation.integerValue == UIInterfaceOrientationLandscapeRight);
|
||||
}];
|
||||
|
||||
UIInterfaceOrientation screenOrientation = [[UIApplication sharedApplication] statusBarOrientation];
|
||||
self.bottomImageView.hidden = (screenOrientation == UIInterfaceOrientationLandscapeLeft || screenOrientation == UIInterfaceOrientationLandscapeRight);
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
{
|
||||
[super viewWillAppear:animated];
|
||||
|
||||
// Hide the bottom border of the navigation bar to display the expander header
|
||||
[self hideNavigationBarBorder:YES];
|
||||
}
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated
|
||||
{
|
||||
[super viewWillDisappear:animated];
|
||||
|
||||
// Restore navigation bar display
|
||||
[self hideNavigationBarBorder:NO];
|
||||
}
|
||||
|
||||
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator
|
||||
{
|
||||
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
||||
|
||||
// Restore navigation bar display
|
||||
[self hideNavigationBarBorder:NO];
|
||||
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(coordinator.transitionDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
|
||||
// Hide the bottom border of the navigation bar
|
||||
[self hideNavigationBarBorder:YES];
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
- (void)destroy
|
||||
{
|
||||
[super destroy];
|
||||
|
||||
if (UIApplicationWillChangeStatusBarOrientationNotificationObserver)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:UIApplicationWillChangeStatusBarOrientationNotificationObserver];
|
||||
UIApplicationWillChangeStatusBarOrientationNotificationObserver = nil;
|
||||
}
|
||||
|
||||
[memberTitleView removeFromSuperview];
|
||||
memberTitleView = nil;
|
||||
}
|
||||
|
||||
- (UIImage*)picturePlaceholder
|
||||
{
|
||||
if (self.mxRoomMember)
|
||||
{
|
||||
// Use the vector style placeholder
|
||||
return [AvatarGenerator generateRoomMemberAvatar:self.mxRoomMember.userId displayName:self.mxRoomMember.displayname];
|
||||
}
|
||||
|
||||
return [UIImage imageNamed:@"placeholder"];
|
||||
}
|
||||
|
||||
- (void)updateMemberInfo
|
||||
{
|
||||
[super updateMemberInfo];
|
||||
|
||||
if (self.mxRoomMember)
|
||||
{
|
||||
self.roomMemberNameLabel.text = self.mxRoomMember.displayname ? self.mxRoomMember.displayname : self.mxRoomMember.userId;
|
||||
|
||||
NSString* presenceText = nil;
|
||||
|
||||
if (self.mxRoomMember.membership != MXMembershipJoin)
|
||||
{
|
||||
if (self.mxRoomMember.membership == MXMembershipInvite)
|
||||
{
|
||||
presenceText = NSLocalizedStringFromTable(@"room_participants_invite", @"Vector", nil);
|
||||
}
|
||||
else if (self.mxRoomMember.membership == MXMembershipLeave)
|
||||
{
|
||||
presenceText = NSLocalizedStringFromTable(@"room_participants_leave", @"Vector", nil);
|
||||
}
|
||||
else if (self.mxRoomMember.membership == MXMembershipBan)
|
||||
{
|
||||
presenceText = NSLocalizedStringFromTable(@"room_participants_ban", @"Vector", nil);
|
||||
}
|
||||
}
|
||||
else if (self.mxRoomMember.userId)
|
||||
{
|
||||
MXUser *user = [self.mxRoom.mxSession userWithUserId:self.mxRoomMember.userId];
|
||||
if (user)
|
||||
{
|
||||
if (user.presence == MXPresenceOnline)
|
||||
{
|
||||
presenceText = NSLocalizedStringFromTable(@"room_participants_active", @"Vector", nil);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSUInteger lastActiveMs = user.lastActiveAgo;
|
||||
|
||||
if (-1 != lastActiveMs)
|
||||
{
|
||||
NSUInteger lastActivehour = lastActiveMs / 1000 / 60 / 60;
|
||||
NSUInteger lastActiveDays = lastActivehour / 24;
|
||||
|
||||
if (lastActivehour < 1)
|
||||
{
|
||||
presenceText = NSLocalizedStringFromTable(@"room_participants_active_less_1_hour", @"Vector", nil);
|
||||
}
|
||||
else if (lastActivehour < 24)
|
||||
{
|
||||
presenceText = [NSString stringWithFormat:NSLocalizedStringFromTable(@"room_participants_active_less_x_hours", @"Vector", nil), lastActivehour];
|
||||
}
|
||||
else
|
||||
{
|
||||
presenceText = [NSString stringWithFormat:NSLocalizedStringFromTable(@"room_participants_active_less_x_days", @"Vector", nil), lastActiveDays];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.roomMemberStatusLabel.text = presenceText;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Hide/Show navigation bar border
|
||||
|
||||
- (void)hideNavigationBarBorder:(BOOL)isHidden
|
||||
{
|
||||
// Consider the main navigation controller if the current view controller is embedded inside a split view controller.
|
||||
UINavigationController *mainNavigationController = self.navigationController;
|
||||
if (self.splitViewController && self.splitViewController.isCollapsed && self.splitViewController.viewControllers.count)
|
||||
{
|
||||
mainNavigationController = self.splitViewController.viewControllers.firstObject;
|
||||
}
|
||||
|
||||
if (isHidden)
|
||||
{
|
||||
// The default shadow image is nil. When non-nil, this property represents a custom shadow image to show instead
|
||||
// of the default. For a custom shadow image to be shown, a custom background image must also be set with the
|
||||
// setBackgroundImage:forBarMetrics: method. If the default background image is used, then the default shadow
|
||||
// image will be used regardless of the value of this property.
|
||||
[mainNavigationController.navigationBar setShadowImage:[[UIImage alloc] init]];
|
||||
[mainNavigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Restore default navigationbar settings
|
||||
[mainNavigationController.navigationBar setShadowImage:nil];
|
||||
[mainNavigationController.navigationBar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - TableView data source
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
// Check user's power level before allowing an action (kick, ban, ...)
|
||||
MXRoomPowerLevels *powerLevels = [self.mxRoom.state powerLevels];
|
||||
NSUInteger memberPowerLevel = [powerLevels powerLevelOfUserWithUserID:self.mxRoomMember.userId];
|
||||
NSUInteger oneSelfPowerLevel = [powerLevels powerLevelOfUserWithUserID:self.mainSession.myUser.userId];
|
||||
|
||||
[actionsArray removeAllObjects];
|
||||
|
||||
// Consider the case of the user himself
|
||||
if ([self.mxRoomMember.userId isEqualToString:self.mainSession.myUser.userId])
|
||||
{
|
||||
[actionsArray addObject:@(MXKRoomMemberDetailsActionLeave)];
|
||||
|
||||
if (oneSelfPowerLevel >= [powerLevels minimumPowerLevelForSendingEventAsStateEvent:kMXEventTypeStringRoomPowerLevels])
|
||||
{
|
||||
// Check whether the user may reduce his power level to become moderator
|
||||
float normalizedOneSelfPowerLevel = [self.mxRoom.state memberNormalizedPowerLevel:self.mainSession.myUser.userId];
|
||||
if (normalizedOneSelfPowerLevel > 0.5)
|
||||
{
|
||||
[actionsArray addObject:@(MXKRoomMemberDetailsActionSetModerator)];
|
||||
}
|
||||
|
||||
[actionsArray addObject:@(MXKRoomMemberDetailsActionSetDefaultPowerLevel)];
|
||||
[actionsArray addObject:@(MXKRoomMemberDetailsActionSetCustomPowerLevel)];
|
||||
}
|
||||
}
|
||||
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
|
||||
switch (self.mxRoomMember.membership)
|
||||
{
|
||||
case MXMembershipInvite:
|
||||
case MXMembershipJoin:
|
||||
{
|
||||
// update power level
|
||||
if (oneSelfPowerLevel >= [powerLevels minimumPowerLevelForSendingEventAsStateEvent:kMXEventTypeStringRoomPowerLevels] && oneSelfPowerLevel > memberPowerLevel)
|
||||
{
|
||||
// Check whether user is admin
|
||||
float normalizedOneSelfPowerLevel = [self.mxRoom.state memberNormalizedPowerLevel:self.mainSession.myUser.userId];
|
||||
if (normalizedOneSelfPowerLevel == 1)
|
||||
{
|
||||
[actionsArray addObject:@(MXKRoomMemberDetailsActionSetAdmin)];
|
||||
}
|
||||
|
||||
// Check whether the member may become moderator
|
||||
float normalizedMemberPowerLevel = [self.mxRoom.state memberNormalizedPowerLevel:self.mxRoomMember.userId];
|
||||
if (normalizedOneSelfPowerLevel >= 0.5 && normalizedMemberPowerLevel < 0.5)
|
||||
{
|
||||
[actionsArray addObject:@(MXKRoomMemberDetailsActionSetModerator)];
|
||||
}
|
||||
|
||||
[actionsArray addObject:@(MXKRoomMemberDetailsActionSetDefaultPowerLevel)];
|
||||
[actionsArray addObject:@(MXKRoomMemberDetailsActionSetCustomPowerLevel)];
|
||||
}
|
||||
|
||||
// Check conditions to be able to kick someone
|
||||
if (oneSelfPowerLevel >= [powerLevels kick] && oneSelfPowerLevel > memberPowerLevel)
|
||||
{
|
||||
[actionsArray addObject:@(MXKRoomMemberDetailsActionKick)];
|
||||
}
|
||||
// Check conditions to be able to ban someone
|
||||
if (oneSelfPowerLevel >= [powerLevels ban] && oneSelfPowerLevel > memberPowerLevel)
|
||||
{
|
||||
[actionsArray addObject:@(MXKRoomMemberDetailsActionBan)];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MXMembershipLeave:
|
||||
{
|
||||
// Check conditions to be able to invite someone
|
||||
if (oneSelfPowerLevel >= [powerLevels invite])
|
||||
{
|
||||
[actionsArray addObject:@(MXKRoomMemberDetailsActionInvite)];
|
||||
}
|
||||
// Check conditions to be able to ban someone
|
||||
if (oneSelfPowerLevel >= [powerLevels ban] && oneSelfPowerLevel > memberPowerLevel)
|
||||
{
|
||||
[actionsArray addObject:@(MXKRoomMemberDetailsActionBan)];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MXMembershipBan:
|
||||
{
|
||||
// Check conditions to be able to unban someone
|
||||
if (oneSelfPowerLevel >= [powerLevels ban] && oneSelfPowerLevel > memberPowerLevel)
|
||||
{
|
||||
[actionsArray addObject:@(MXKRoomMemberDetailsActionUnban)];
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return actionsArray.count;
|
||||
}
|
||||
|
||||
- (NSString*)actionButtonTitle:(MXKRoomMemberDetailsAction)action
|
||||
{
|
||||
NSString *title;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MXKRoomMemberDetailsActionInvite:
|
||||
title = NSLocalizedStringFromTable(@"room_participants_action_invite", @"Vector", nil);
|
||||
break;
|
||||
case MXKRoomMemberDetailsActionLeave:
|
||||
title = NSLocalizedStringFromTable(@"room_participants_action_leave", @"Vector", nil);
|
||||
break;
|
||||
case MXKRoomMemberDetailsActionKick:
|
||||
title = NSLocalizedStringFromTable(@"room_participants_action_remove", @"Vector", nil);
|
||||
break;
|
||||
case MXKRoomMemberDetailsActionBan:
|
||||
title = NSLocalizedStringFromTable(@"room_participants_action_ban", @"Vector", nil);
|
||||
break;
|
||||
case MXKRoomMemberDetailsActionUnban:
|
||||
title = NSLocalizedStringFromTable(@"room_participants_action_unban", @"Vector", nil);
|
||||
break;
|
||||
case MXKRoomMemberDetailsActionSetDefaultPowerLevel:
|
||||
title = NSLocalizedStringFromTable(@"room_participants_action_set_default_power_level", @"Vector", nil);
|
||||
break;
|
||||
case MXKRoomMemberDetailsActionSetModerator:
|
||||
title = NSLocalizedStringFromTable(@"room_participants_action_set_moderator", @"Vector", nil);
|
||||
break;
|
||||
case MXKRoomMemberDetailsActionSetAdmin:
|
||||
title = NSLocalizedStringFromTable(@"room_participants_action_set_admin", @"Vector", nil);
|
||||
break;
|
||||
case MXKRoomMemberDetailsActionSetCustomPowerLevel:
|
||||
title = NSLocalizedStringFromTable(@"room_participants_action_set_custom_power_level", @"Vector", nil);
|
||||
break;
|
||||
case MXKRoomMemberDetailsActionStartChat:
|
||||
title = NSLocalizedStringFromTable(@"room_participants_action_start_chat", @"Vector", nil);
|
||||
break;
|
||||
case MXKRoomMemberDetailsActionStartVoiceCall:
|
||||
title = NSLocalizedStringFromTable(@"room_participants_action_start_voice_call", @"Vector", nil);
|
||||
break;
|
||||
case MXKRoomMemberDetailsActionStartVideoCall:
|
||||
title = NSLocalizedStringFromTable(@"room_participants_action_start_video_call", @"Vector", nil);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return title;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
NSInteger row = indexPath.row;
|
||||
|
||||
TableViewCellWithButton *cell = [[TableViewCellWithButton alloc] init];
|
||||
|
||||
if (row < actionsArray.count)
|
||||
{
|
||||
NSNumber *actionNumber = [actionsArray objectAtIndex:row];
|
||||
|
||||
NSString *title = [self actionButtonTitle:actionNumber.unsignedIntegerValue];
|
||||
|
||||
[cell.mxkButton setTitle:title forState:UIControlStateNormal];
|
||||
[cell.mxkButton setTitle:title forState:UIControlStateHighlighted];
|
||||
|
||||
if (actionNumber.unsignedIntegerValue == MXKRoomMemberDetailsActionKick)
|
||||
{
|
||||
[cell.mxkButton setTitleColor:kVectorTextColorRed forState:UIControlStateNormal];
|
||||
[cell.mxkButton setTitleColor:kVectorTextColorRed forState:UIControlStateHighlighted];
|
||||
}
|
||||
else
|
||||
{
|
||||
[cell.mxkButton setTitleColor:kVectorTextColorBlack forState:UIControlStateNormal];
|
||||
[cell.mxkButton setTitleColor:kVectorTextColorBlack forState:UIControlStateHighlighted];
|
||||
}
|
||||
|
||||
[cell.mxkButton addTarget:self action:@selector(onActionButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
cell.mxkButton.tag = actionNumber.unsignedIntegerValue;
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)onActionButtonPressed:(id)sender
|
||||
{
|
||||
if ([sender isKindOfClass:[UIButton class]])
|
||||
{
|
||||
// already a pending action
|
||||
if ([self hasPendingAction])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UIButton *button = (UIButton*)sender;
|
||||
|
||||
switch (button.tag)
|
||||
{
|
||||
case MXKRoomMemberDetailsActionSetDefaultPowerLevel:
|
||||
{
|
||||
[self setPowerLevel:self.mxRoom.state.powerLevels.usersDefault];
|
||||
break;
|
||||
}
|
||||
case MXKRoomMemberDetailsActionSetModerator:
|
||||
{
|
||||
[self setPowerLevel:kVectorRoomModeratorLevel];
|
||||
break;
|
||||
}
|
||||
case MXKRoomMemberDetailsActionSetAdmin:
|
||||
{
|
||||
[self setPowerLevel:kVectorRoomAdminLevel];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
[super onActionButtonPressed:sender];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9532" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9530"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="RoomMemberDetailsViewController">
|
||||
<connections>
|
||||
<outlet property="actionTableViewTopConstraint" destination="ZzT-DZ-sGQ" id="jbs-HH-zKB"/>
|
||||
<outlet property="bottomImageView" destination="7Dc-jk-9sT" id="BVN-bt-VXI"/>
|
||||
<outlet property="memberHeaderView" destination="YXr-As-Mqh" id="Eqb-qr-iAo"/>
|
||||
<outlet property="roomMemberNameLabel" destination="92g-hC-6jB" id="gcP-wz-8FT"/>
|
||||
<outlet property="roomMemberStatusLabel" destination="5le-5e-Vml" id="ODo-tG-ewy"/>
|
||||
<outlet property="tableView" destination="R6u-PR-DcU" id="Cm1-1y-meQ"/>
|
||||
<outlet property="view" destination="gX8-mM-6Ig" id="R3w-s7-1CY"/>
|
||||
</connections>
|
||||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="gX8-mM-6Ig">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="YXr-As-Mqh">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="192"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="92g-hC-6jB">
|
||||
<rect key="frame" x="278" y="125" width="45" height="21"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="21" id="WyU-2u-Lek"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="18"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5le-5e-Vml">
|
||||
<rect key="frame" x="281" y="153" width="39" height="21"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="21" id="7lY-ku-cPk"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="15"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="92g-hC-6jB" firstAttribute="centerX" secondItem="YXr-As-Mqh" secondAttribute="centerX" id="7Is-d0-FZp"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="92g-hC-6jB" secondAttribute="trailing" constant="32" id="Eyx-UF-fYc"/>
|
||||
<constraint firstItem="92g-hC-6jB" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="YXr-As-Mqh" secondAttribute="leading" constant="32" id="QZB-ue-Sih"/>
|
||||
<constraint firstAttribute="height" constant="192" id="at7-Bz-a4i"/>
|
||||
<constraint firstItem="5le-5e-Vml" firstAttribute="centerX" secondItem="YXr-As-Mqh" secondAttribute="centerX" id="bmA-Fq-uxO"/>
|
||||
<constraint firstItem="5le-5e-Vml" firstAttribute="top" secondItem="YXr-As-Mqh" secondAttribute="top" constant="153" id="cAW-ET-f5u"/>
|
||||
<constraint firstItem="5le-5e-Vml" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="YXr-As-Mqh" secondAttribute="leading" constant="42" id="ioz-jk-jrE"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="5le-5e-Vml" secondAttribute="trailing" constant="42" id="mad-qx-tHe"/>
|
||||
<constraint firstItem="92g-hC-6jB" firstAttribute="top" secondItem="YXr-As-Mqh" secondAttribute="top" constant="125" id="nSB-Hb-NhH"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="group.png" translatesAutoresizingMaskIntoConstraints="NO" id="7Dc-jk-9sT">
|
||||
<rect key="frame" x="0.0" y="402" width="600" height="198"/>
|
||||
<constraints>
|
||||
<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">
|
||||
<rect key="frame" x="0.0" y="192" width="600" height="408"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="-1" id="DbO-MV-3hm"/>
|
||||
<outlet property="delegate" destination="-1" id="dFh-bI-jUW"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="7Dc-jk-9sT" secondAttribute="trailing" id="3C8-er-hQ7"/>
|
||||
<constraint firstAttribute="trailing" secondItem="YXr-As-Mqh" secondAttribute="trailing" id="3DV-SV-Ifa"/>
|
||||
<constraint firstItem="YXr-As-Mqh" firstAttribute="leading" secondItem="gX8-mM-6Ig" secondAttribute="leading" id="EbV-lF-mAx"/>
|
||||
<constraint firstAttribute="bottom" secondItem="R6u-PR-DcU" secondAttribute="bottom" id="X1a-xq-1Aa"/>
|
||||
<constraint firstItem="R6u-PR-DcU" firstAttribute="top" secondItem="gX8-mM-6Ig" secondAttribute="top" constant="192" id="ZzT-DZ-sGQ"/>
|
||||
<constraint firstAttribute="trailing" secondItem="R6u-PR-DcU" secondAttribute="trailing" id="aMA-vf-GrY"/>
|
||||
<constraint firstItem="YXr-As-Mqh" firstAttribute="top" secondItem="gX8-mM-6Ig" secondAttribute="top" id="l7z-od-LJm"/>
|
||||
<constraint firstItem="7Dc-jk-9sT" firstAttribute="leading" secondItem="gX8-mM-6Ig" secondAttribute="leading" id="rNt-rC-Pxv"/>
|
||||
<constraint firstItem="R6u-PR-DcU" firstAttribute="leading" secondItem="gX8-mM-6Ig" secondAttribute="leading" id="rbT-O1-m3d"/>
|
||||
<constraint firstAttribute="bottom" secondItem="7Dc-jk-9sT" secondAttribute="bottom" id="yKK-K2-ebi"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="group.png" width="375" height="198"/>
|
||||
</resources>
|
||||
</document>
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#import "ContactTableViewCell.h"
|
||||
|
||||
#import "SegmentedViewController.h"
|
||||
|
||||
/**
|
||||
'RoomParticipantsViewController' instance is used to edit members of the room defined by the property 'mxRoom'.
|
||||
|
||||
@@ -58,6 +60,11 @@
|
||||
*/
|
||||
@property (nonatomic) BOOL isAddParticipantSearchBarEditing;
|
||||
|
||||
/**
|
||||
The potential segmented view controller in which the view controller is displayed.
|
||||
*/
|
||||
@property (nonatomic) SegmentedViewController *segmentedViewController;
|
||||
|
||||
|
||||
/**
|
||||
Customize the UITableViewCell before rendering it.
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
#import "RoomParticipantsViewController.h"
|
||||
|
||||
#import "RoomMemberDetailsViewController.h"
|
||||
|
||||
#import "VectorDesignValues.h"
|
||||
|
||||
#import "RageShakeManager.h"
|
||||
@@ -47,6 +49,8 @@
|
||||
|
||||
// Observe kMXSessionWillLeaveRoomNotification to be notified if the user leaves the current room.
|
||||
id leaveRoomNotificationObserver;
|
||||
|
||||
RoomMemberDetailsViewController *detailsViewController;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -161,6 +165,12 @@
|
||||
{
|
||||
[super viewWillAppear:animated];
|
||||
|
||||
if (detailsViewController)
|
||||
{
|
||||
[detailsViewController destroy];
|
||||
detailsViewController = nil;
|
||||
}
|
||||
|
||||
// Refresh display
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
@@ -795,6 +805,53 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (indexPath.section == participantsSection)
|
||||
{
|
||||
Contact *contact;
|
||||
|
||||
// oneself dedicated cell
|
||||
if (userMatrixId && indexPath.row == 0)
|
||||
{
|
||||
contact = [mxkContactsById objectForKey:userMatrixId];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSInteger index = indexPath.row;
|
||||
|
||||
if (userMatrixId)
|
||||
{
|
||||
index --;
|
||||
}
|
||||
|
||||
if (index < mutableParticipants.count)
|
||||
{
|
||||
NSString *userId = mutableParticipants[index];
|
||||
contact = [mxkContactsById objectForKey:userId];
|
||||
}
|
||||
}
|
||||
|
||||
if (contact)
|
||||
{
|
||||
detailsViewController = [RoomMemberDetailsViewController roomMemberDetailsViewController];
|
||||
[detailsViewController displayRoomMember:contact.mxMember withMatrixRoom:self.mxRoom];
|
||||
|
||||
// Check whether the view controller is displayed inside a segmented one.
|
||||
if (self.segmentedViewController)
|
||||
{
|
||||
// Hide back button title
|
||||
self.segmentedViewController.navigationItem.backBarButtonItem =[[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
|
||||
|
||||
[self.segmentedViewController.navigationController pushViewController:detailsViewController animated:YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Hide back button title
|
||||
self.navigationItem.backBarButtonItem =[[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
|
||||
|
||||
[self.navigationController pushViewController:detailsViewController animated:YES];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
}
|
||||
|
||||
@@ -937,6 +937,7 @@
|
||||
|
||||
RoomParticipantsViewController* participantsViewController = [[RoomParticipantsViewController alloc] init];
|
||||
participantsViewController.mxRoom = [session roomWithRoomId:roomid];
|
||||
participantsViewController.segmentedViewController = segmentedViewController;
|
||||
[viewControllers addObject:participantsViewController];
|
||||
|
||||
[titles addObject: NSLocalizedStringFromTable(@"room_details_settings", @"Vector", nil)];
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
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>
|
||||
|
||||
@interface RoomMemberTitleView : UIView
|
||||
|
||||
/**
|
||||
* Returns the `UINib` object initialized for the room member title view.
|
||||
*
|
||||
* @return The initialized `UINib` object or `nil` if there were errors during
|
||||
* initialization or the nib file could not be located.
|
||||
*/
|
||||
+ (UINib *)nib;
|
||||
|
||||
/**
|
||||
Creates and returns a new `RoomMemberTitleView-inherited` object.
|
||||
|
||||
@discussion This is the designated initializer for programmatic instantiation.
|
||||
@return An initialized `RoomMemberTitleView-inherited` object if successful, `nil` otherwise.
|
||||
*/
|
||||
+ (instancetype)roomMemberTitleView;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet MXKImageView *memberAvatar;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *memberAvatarCenterXConstraint;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
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 "RoomMemberTitleView.h"
|
||||
|
||||
@implementation RoomMemberTitleView
|
||||
|
||||
+ (UINib *)nib
|
||||
{
|
||||
return [UINib nibWithNibName:NSStringFromClass([self class])
|
||||
bundle:[NSBundle bundleForClass:[self class]]];
|
||||
}
|
||||
|
||||
+ (instancetype)roomMemberTitleView
|
||||
{
|
||||
return [[[self class] nib] instantiateWithOwner:nil options:nil].firstObject;
|
||||
}
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
[super awakeFromNib];
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
if (self.superview)
|
||||
{
|
||||
|
||||
// Center horizontally the avatar into the navigation bar
|
||||
CGRect frame = self.superview.frame;
|
||||
UINavigationBar *navigationBar;
|
||||
UIView *superView = self;
|
||||
while (superView.superview)
|
||||
{
|
||||
if ([superView.superview isKindOfClass:[UINavigationBar class]])
|
||||
{
|
||||
navigationBar = (UINavigationBar*)superView.superview;
|
||||
break;
|
||||
}
|
||||
|
||||
superView = superView.superview;
|
||||
}
|
||||
|
||||
if (navigationBar)
|
||||
{
|
||||
CGSize navBarSize = navigationBar.frame.size;
|
||||
CGFloat superviewCenterX = frame.origin.x + (frame.size.width / 2);
|
||||
|
||||
self.memberAvatarCenterXConstraint.constant = (navBarSize.width / 2) - superviewCenterX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9532" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9532"/>
|
||||
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="BkF-x3-7fX" customClass="RoomMemberTitleView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="240"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7U9-Y6-cEm" customClass="MXKImageView">
|
||||
<rect key="frame" x="258" y="13" width="84" height="84"/>
|
||||
<color key="backgroundColor" red="0.6886889638" green="1" blue="0.74383144840000004" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" secondItem="7U9-Y6-cEm" secondAttribute="height" multiplier="1:1" id="9ct-O9-7am"/>
|
||||
<constraint firstAttribute="width" constant="84" id="BeT-JY-cq1"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="7U9-Y6-cEm" firstAttribute="centerX" secondItem="BkF-x3-7fX" secondAttribute="centerX" id="C5g-ho-90L"/>
|
||||
<constraint firstItem="7U9-Y6-cEm" firstAttribute="top" secondItem="BkF-x3-7fX" secondAttribute="top" constant="13" id="Kwt-Sd-REk"/>
|
||||
</constraints>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<connections>
|
||||
<outlet property="memberAvatar" destination="7U9-Y6-cEm" id="8PP-8r-xoI"/>
|
||||
<outlet property="memberAvatarCenterXConstraint" destination="C5g-ho-90L" id="ILx-zG-Dbj"/>
|
||||
</connections>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
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 "MXKTableViewCellWithButton.h"
|
||||
|
||||
@interface TableViewCellWithButton : MXKTableViewCellWithButton
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
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 "TableViewCellWithButton.h"
|
||||
|
||||
@implementation TableViewCellWithButton
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9532" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9530"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="20U-7H-xmi" customClass="TableViewCellWithButton">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="20U-7H-xmi" id="cFw-g7-Cgn">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="43"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Ycy-33-7Zq">
|
||||
<rect key="frame" x="15" y="6" width="55" height="30"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<state key="normal" title="Submit">
|
||||
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="Ycy-33-7Zq" secondAttribute="trailing" constant="15" id="MQb-Pf-iyH"/>
|
||||
<constraint firstItem="Ycy-33-7Zq" firstAttribute="leading" secondItem="cFw-g7-Cgn" secondAttribute="leading" constant="15" id="gXR-S8-WYt"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Ycy-33-7Zq" secondAttribute="bottom" constant="7" id="roU-6C-3dH"/>
|
||||
<constraint firstItem="Ycy-33-7Zq" firstAttribute="top" secondItem="cFw-g7-Cgn" secondAttribute="top" constant="6" id="zIU-sw-6ea"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<outlet property="mxkButton" destination="Ycy-33-7Zq" id="rQt-Th-xOb"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
</document>
|
||||
Reference in New Issue
Block a user