Move all the view controllers related to the communities

This commit is contained in:
Giom Foret 2018-01-08 19:18:56 +01:00
parent 5c8ebf04f1
commit ebcb53df42
14 changed files with 0 additions and 4240 deletions

View file

@ -1,50 +0,0 @@
/*
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import "SegmentedViewController.h"
@interface GroupDetailsViewController : SegmentedViewController
@property (strong, readonly, nonatomic) MXGroup *group;
@property (strong, readonly, nonatomic) MXSession *mxSession;
/**
Returns the `UINib` object initialized for a `GroupDetailsViewController`.
@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 `GroupDetailsViewController` object.
@discussion This is the designated initializer for programmatic instantiation.
@return An initialized `GroupDetailsViewController` object if successful, `nil` otherwise.
*/
+ (instancetype)groupDetailsViewController;
/**
Set the group for which the details are displayed.
Provide the related matrix session.
@param group
@param mxSession
*/
- (void)setGroup:(MXGroup*)group withMatrixSession:(MXSession*)mxSession;
@end

View file

@ -1,206 +0,0 @@
/*
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import "GroupDetailsViewController.h"
#import "GroupHomeViewController.h"
#import "GroupParticipantsViewController.h"
#import "GroupRoomsViewController.h"
#import "AppDelegate.h"
@interface GroupDetailsViewController ()
{
GroupHomeViewController *groupHomeViewController;
GroupParticipantsViewController *groupParticipantsViewController;
GroupRoomsViewController *groupRoomsViewController;
/**
mask view while processing a request
*/
UIActivityIndicatorView * pendingMaskSpinnerView;
/**
Current alert (if any).
*/
UIAlertController *currentAlert;
/**
The current visibility of the status bar in this view controller.
*/
BOOL isStatusBarHidden;
}
@end
@implementation GroupDetailsViewController
#pragma mark - Class methods
+ (UINib *)nib
{
return [UINib nibWithNibName:NSStringFromClass(self.class)
bundle:[NSBundle bundleForClass:self.class]];
}
+ (instancetype)groupDetailsViewController
{
return [[[self class] alloc] initWithNibName:NSStringFromClass(self.class)
bundle:[NSBundle bundleForClass:self.class]];
}
#pragma mark -
- (void)finalizeInit
{
[super finalizeInit];
// Setup `MXKViewControllerHandling` properties
self.enableBarTintColorStatusChange = NO;
self.rageShakeManager = [RageShakeManager sharedManager];
self.sectionHeaderTintColor = kRiotColorBlue;
// Keep visible the status bar by default.
isStatusBarHidden = NO;
}
- (void)viewDidLoad
{
NSMutableArray* viewControllers = [[NSMutableArray alloc] init];
NSMutableArray* titles = [[NSMutableArray alloc] init];
// home tab
[titles addObject: NSLocalizedStringFromTable(@"group_details_home", @"Vector", nil)];
groupHomeViewController = [GroupHomeViewController groupHomeViewController];
if (_group)
{
[groupHomeViewController setGroup:_group withMatrixSession:_mxSession];
}
[viewControllers addObject:groupHomeViewController];
// People tab
[titles addObject: NSLocalizedStringFromTable(@"group_details_people", @"Vector", nil)];
groupParticipantsViewController = [GroupParticipantsViewController groupParticipantsViewController];
if (_group)
{
[groupParticipantsViewController setGroup:_group withMatrixSession:_mxSession];
}
[viewControllers addObject:groupParticipantsViewController];
// Rooms tab
[titles addObject: NSLocalizedStringFromTable(@"group_details_rooms", @"Vector", nil)];
groupRoomsViewController = [GroupRoomsViewController groupRoomsViewController];
if (_group)
{
[groupRoomsViewController setGroup:_group withMatrixSession:_mxSession];
}
[viewControllers addObject:groupRoomsViewController];
self.title = NSLocalizedStringFromTable(@"group_details_title", @"Vector", nil);
[self initWithTitles:titles viewControllers:viewControllers defaultSelected:0];
[super viewDidLoad];
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
return kRiotDesignStatusBarStyle;
}
- (BOOL)prefersStatusBarHidden
{
// Return the current status bar visibility.
return isStatusBarHidden;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Screen tracking
[[AppDelegate theDelegate] trackScreen:@"GroupDetails"];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
// Consider the main navigation controller if the current view controller is embedded inside a split view controller.
UINavigationController *mainNavigationController = self.navigationController;
if (self.splitViewController.isCollapsed && self.splitViewController.viewControllers.count)
{
mainNavigationController = self.splitViewController.viewControllers.firstObject;
}
if (mainNavigationController.navigationBar.tintColor == kRiotColorBlue)
{
// Restore default tintColor
mainNavigationController.navigationBar.tintColor = kRiotColorGreen;
}
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
// Consider the main navigation controller if the current view controller is embedded inside a split view controller.
UINavigationController *mainNavigationController = self.navigationController;
if (self.splitViewController.isCollapsed && self.splitViewController.viewControllers.count)
{
mainNavigationController = self.splitViewController.viewControllers.firstObject;
}
mainNavigationController.navigationBar.tintColor = kRiotColorBlue;
}
- (void)destroy
{
[super destroy];
}
- (void)setGroup:(MXGroup*)group withMatrixSession:(MXSession*)mxSession
{
_group = group;
_mxSession = mxSession;
[self addMatrixSession:mxSession];
if (groupHomeViewController)
{
[groupHomeViewController setGroup:group withMatrixSession:mxSession];
}
if (groupParticipantsViewController)
{
[groupParticipantsViewController setGroup:group withMatrixSession:mxSession];
}
if (groupRoomsViewController)
{
[groupRoomsViewController setGroup:group withMatrixSession:mxSession];
}
}
- (void)withdrawViewControllerAnimated:(BOOL)animated completion:(void (^)(void))completion
{
[super withdrawViewControllerAnimated:animated completion:completion];
// Fill the secondary navigation view controller of the split view controller if it is empty.
UINavigationController *secondaryNavigationController = [AppDelegate theDelegate].secondaryNavigationController;
if (secondaryNavigationController && !secondaryNavigationController.viewControllers.count)
{
[[AppDelegate theDelegate] restoreEmptyDetailsViewController];
}
}
@end

View file

@ -1,52 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13529"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="SegmentedViewController">
<connections>
<outlet property="selectionContainer" destination="ynH-uD-aQj" id="taa-CW-XgW"/>
<outlet property="selectionContainerHeightConstraint" destination="fZ1-SQ-nxS" id="kQ4-n9-Gmt"/>
<outlet property="selectionContainerTopConstraint" destination="eLe-5q-IfV" id="UhZ-9k-P1r"/>
<outlet property="view" destination="1TG-Rn-axS" id="WxL-e2-rVK"/>
<outlet property="viewControllerContainer" destination="Hbe-uP-aJY" id="mD3-w0-UXi"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="1TG-Rn-axS">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ynH-uD-aQj" userLabel="Selection Container">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<accessibility key="accessibilityConfiguration" identifier="SegmentedVCSelectionContainer"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="fZ1-SQ-nxS"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Hbe-uP-aJY" userLabel="Selected UITableView Container">
<rect key="frame" x="0.0" y="44" width="375" height="623"/>
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="SegmentedVCUITableViewContainer"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="SegmentedVCView"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="Hbe-uP-aJY" secondAttribute="bottom" id="GHr-ci-L7A"/>
<constraint firstItem="Hbe-uP-aJY" firstAttribute="leading" secondItem="ynH-uD-aQj" secondAttribute="leading" id="HTN-hD-pve"/>
<constraint firstItem="ynH-uD-aQj" firstAttribute="width" secondItem="1TG-Rn-axS" secondAttribute="width" id="N0o-xo-47p"/>
<constraint firstItem="Hbe-uP-aJY" firstAttribute="top" secondItem="ynH-uD-aQj" secondAttribute="bottom" id="Ovm-KQ-gUw"/>
<constraint firstItem="Hbe-uP-aJY" firstAttribute="width" secondItem="1TG-Rn-axS" secondAttribute="width" id="YKU-mG-Loo"/>
<constraint firstItem="ynH-uD-aQj" firstAttribute="leading" secondItem="1TG-Rn-axS" secondAttribute="leading" id="drw-gq-mYE"/>
<constraint firstItem="ynH-uD-aQj" firstAttribute="top" secondItem="1TG-Rn-axS" secondAttribute="top" id="eLe-5q-IfV"/>
</constraints>
</view>
</objects>
</document>

View file

@ -1,73 +0,0 @@
/*
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import <MatrixKit/MatrixKit.h>
@interface GroupHomeViewController : MXKViewController <UIGestureRecognizerDelegate>
@property (weak, nonatomic) IBOutlet UIView *mainHeaderContainer;
@property (weak, nonatomic) IBOutlet MXKImageView *groupAvatar;
@property (weak, nonatomic) IBOutlet UIView *groupAvatarMask;
@property (weak, nonatomic) IBOutlet UILabel *groupName;
@property (weak, nonatomic) IBOutlet UIView *groupNameMask;
@property (weak, nonatomic) IBOutlet UILabel *groupDescription;
@property (weak, nonatomic) IBOutlet UIView *countsContainer;
@property (weak, nonatomic) IBOutlet UIView *membersCountContainer;
@property (weak, nonatomic) IBOutlet UIView *roomsCountContainer;
@property (weak, nonatomic) IBOutlet UILabel *membersCountLabel;
@property (weak, nonatomic) IBOutlet UILabel *roomsCountLabel;
@property (weak, nonatomic) IBOutlet UIView *inviteContainer;
@property (weak, nonatomic) IBOutlet UILabel *inviteLabel;
@property (weak, nonatomic) IBOutlet UIView *buttonsContainer;
@property (weak, nonatomic) IBOutlet UIButton *leftButton;
@property (weak, nonatomic) IBOutlet UIButton *rightButton;
@property (weak, nonatomic) IBOutlet UIView *separatorView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *separatorViewTopConstraint;
@property (weak, nonatomic) IBOutlet UITextView *groupLongDescription;
@property (strong, readonly, nonatomic) MXGroup *group;
@property (strong, readonly, nonatomic) MXSession *mxSession;
/**
Returns the `UINib` object initialized for a `GroupHomeViewController`.
@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 `GroupHomeViewController` object.
@discussion This is the designated initializer for programmatic instantiation.
@return An initialized `GroupHomeViewController` object if successful, `nil` otherwise.
*/
+ (instancetype)groupHomeViewController;
/**
Set the group for which the details are displayed.
Provide the related matrix session.
@param group
@param mxSession
*/
- (void)setGroup:(MXGroup*)group withMatrixSession:(MXSession*)mxSession;
@end

View file

@ -1,517 +0,0 @@
/*
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import "GroupHomeViewController.h"
#import "AppDelegate.h"
#import "RiotDesignValues.h"
#import "MXGroup+Riot.h"
@interface GroupHomeViewController ()
{
MXHTTPOperation *currentRequest;
/**
The current visibility of the status bar in this view controller.
*/
BOOL isStatusBarHidden;
// Observe kRiotDesignValuesDidChangeThemeNotification to handle user interface theme change.
id kRiotDesignValuesDidChangeThemeNotificationObserver;
}
@end
@implementation GroupHomeViewController
#pragma mark - Class methods
+ (UINib *)nib
{
return [UINib nibWithNibName:NSStringFromClass(self.class)
bundle:[NSBundle bundleForClass:self.class]];
}
+ (instancetype)groupHomeViewController
{
return [[[self class] alloc] initWithNibName:NSStringFromClass(self.class)
bundle:[NSBundle bundleForClass:self.class]];
}
#pragma mark -
- (void)finalizeInit
{
[super finalizeInit];
// Setup `MXKViewControllerHandling` properties
self.enableBarTintColorStatusChange = NO;
self.rageShakeManager = [RageShakeManager sharedManager];
// Keep visible the status bar by default.
isStatusBarHidden = NO;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.leftButton setTitle:NSLocalizedStringFromTable(@"decline", @"Vector", nil) forState:UIControlStateNormal];
[self.leftButton setTitle:NSLocalizedStringFromTable(@"decline", @"Vector", nil) forState:UIControlStateHighlighted];
[self.rightButton setTitle:NSLocalizedStringFromTable(@"join", @"Vector", nil) forState:UIControlStateNormal];
[self.rightButton setTitle:NSLocalizedStringFromTable(@"join", @"Vector", nil) forState:UIControlStateHighlighted];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
[tap setNumberOfTouchesRequired:1];
[tap setNumberOfTapsRequired:1];
[tap setDelegate:self];
[_groupNameMask addGestureRecognizer:tap];
_groupNameMask.userInteractionEnabled = YES;
// Add tap to show the group avatar in fullscreen
tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
[tap setNumberOfTouchesRequired:1];
[tap setNumberOfTapsRequired:1];
[tap setDelegate:self];
[_groupAvatarMask addGestureRecognizer:tap];
_groupAvatarMask.userInteractionEnabled = YES;
// Observe user interface theme change.
kRiotDesignValuesDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kRiotDesignValuesDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
[self userInterfaceThemeDidChange];
}];
[self userInterfaceThemeDidChange];
}
- (void)userInterfaceThemeDidChange
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
self.view.backgroundColor = kRiotPrimaryBgColor;
self.mainHeaderContainer.backgroundColor = kRiotSecondaryBgColor;
_groupName.textColor = kRiotPrimaryTextColor;
_groupDescription.textColor = kRiotTopicTextColor;
_groupDescription.numberOfLines = 0;
self.inviteLabel.textColor = kRiotTopicTextColor;
self.inviteLabel.numberOfLines = 0;
self.separatorView.backgroundColor = kRiotSecondaryBgColor;
_groupLongDescription.textColor = kRiotSecondaryTextColor;
_groupLongDescription.tintColor = kRiotColorBlue;
[self.leftButton.layer setCornerRadius:5];
self.leftButton.clipsToBounds = YES;
self.leftButton.backgroundColor = kRiotColorBlue;
[self.rightButton.layer setCornerRadius:5];
self.rightButton.clipsToBounds = YES;
self.rightButton.backgroundColor = kRiotColorBlue;
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
return kRiotDesignStatusBarStyle;
}
- (BOOL)prefersStatusBarHidden
{
// Return the current status bar visibility.
return isStatusBarHidden;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Screen tracking
[[AppDelegate theDelegate] trackScreen:@"GroupDetailsHome"];
if (_group)
{
// Restore the listeners on the group update.
[self registerOnGroupChangeNotifications];
// Check whether the selected group is stored in the user's session, or if it is a group preview.
// Replace the displayed group instance with the one stored in the session (if any).
MXGroup *storedGroup = [_mxSession groupWithGroupId:_group.groupId];
BOOL isPreview = (!storedGroup);
// Force refresh
[self refreshDisplayWithGroup:(isPreview ? _group : storedGroup)];
// Prepare a block called on successful update in case of a group preview.
// Indeed the group update notifications are triggered by the matrix session only for the user's groups.
void (^success)(void) = ^void(void)
{
[self refreshDisplayWithGroup:_group];
};
// Trigger a refresh on the group summary.
[self.mxSession updateGroupSummary:_group success:(isPreview ? success : nil) failure:^(NSError *error) {
NSLog(@"[GroupHomeViewController] viewWillAppear: group summary update failed %@", _group.groupId);
}];
// Trigger a refresh on the group members (ignore here the invited users).
[self.mxSession updateGroupUsers:_group success:(isPreview ? success : nil) failure:^(NSError *error) {
NSLog(@"[GroupHomeViewController] viewWillAppear: group members update failed %@", _group.groupId);
}];
// Trigger a refresh on the group rooms.
[self.mxSession updateGroupRooms:_group success:(isPreview ? success : nil) failure:^(NSError *error) {
NSLog(@"[GroupHomeViewController] viewWillAppear: group rooms update failed %@", _group.groupId);
}];
}
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self cancelRegistrationOnGroupChangeNotifications];
}
- (void)destroy
{
// Note: all observers are removed during super call.
[super destroy];
_group = nil;
_mxSession = nil;
[currentRequest cancel];
currentRequest = nil;
if (kRiotDesignValuesDidChangeThemeNotificationObserver)
{
[[NSNotificationCenter defaultCenter] removeObserver:kRiotDesignValuesDidChangeThemeNotificationObserver];
kRiotDesignValuesDidChangeThemeNotificationObserver = nil;
}
}
- (void)setGroup:(MXGroup*)group withMatrixSession:(MXSession*)mxSession
{
if (_mxSession != mxSession)
{
[self cancelRegistrationOnGroupChangeNotifications];
_mxSession = mxSession;
[self registerOnGroupChangeNotifications];
}
[self addMatrixSession:mxSession];
[self refreshDisplayWithGroup:group];
}
#pragma mark -
- (void)registerOnGroupChangeNotifications
{
if (_mxSession)
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didUpdateGroupDetails:) name:kMXSessionDidUpdateGroupSummaryNotification object:_mxSession];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didUpdateGroupDetails:) name:kMXSessionDidUpdateGroupUsersNotification object:_mxSession];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didUpdateGroupDetails:) name:kMXSessionDidUpdateGroupRoomsNotification object:_mxSession];
}
}
- (void)cancelRegistrationOnGroupChangeNotifications
{
// Remove any pending observers
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDidUpdateGroupSummaryNotification object:_mxSession];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDidUpdateGroupUsersNotification object:_mxSession];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDidUpdateGroupRoomsNotification object:_mxSession];
}
- (void)didUpdateGroupDetails:(NSNotification *)notif
{
MXGroup *group = notif.userInfo[kMXSessionNotificationGroupKey];
if (group && [group.groupId isEqualToString:_group.groupId])
{
// Update the current displayed group instance with the one stored in the session
[self refreshDisplayWithGroup:group];
}
}
- (void)refreshDisplayWithGroup:(MXGroup*)group
{
_group = group;
if (_group)
{
[_group setGroupAvatarImageIn:_groupAvatar matrixSession:self.mxSession];
_groupName.text = _group.summary.profile.name;
if (!_groupName.text.length)
{
_groupName.text = _group.groupId;
}
_groupDescription.text = _group.summary.profile.shortDescription;
if (_group.users.totalUserCountEstimate == 1)
{
_membersCountLabel.text = NSLocalizedStringFromTable(@"group_home_one_member_format", @"Vector", nil);
_membersCountContainer.hidden = NO;
}
else if (_group.users.totalUserCountEstimate > 1)
{
_membersCountLabel.text = [NSString stringWithFormat:NSLocalizedStringFromTable(@"group_home_multi_members_format", @"Vector", nil), _group.users.totalUserCountEstimate];
_membersCountContainer.hidden = NO;
}
else
{
_membersCountLabel.text = nil;
_membersCountContainer.hidden = YES;
}
if (_group.rooms.totalRoomCountEstimate == 1)
{
_roomsCountLabel.text = NSLocalizedStringFromTable(@"group_home_one_room_format", @"Vector", nil);
_roomsCountContainer.hidden = NO;
}
else if (_group.rooms.totalRoomCountEstimate > 1)
{
_roomsCountLabel.text = [NSString stringWithFormat:NSLocalizedStringFromTable(@"group_home_multi_rooms_format", @"Vector", nil), _group.rooms.totalRoomCountEstimate];
_roomsCountContainer.hidden = NO;
}
else
{
_roomsCountLabel.text = nil;
_roomsCountContainer.hidden = YES;
}
_countsContainer.hidden = (_membersCountContainer.isHidden && _roomsCountContainer.isHidden);
if (_group.membership == MXMembershipInvite)
{
self.inviteContainer.hidden = NO;
if (_group.inviter)
{
NSString *inviter = _group.inviter;
if ([MXTools isMatrixUserIdentifier:inviter])
{
// Get the user that corresponds to this member
MXUser *user = [self.mxSession userWithUserId:inviter];
if (user.displayname.length)
{
inviter = user.displayname;
}
}
self.inviteLabel.text = [NSString stringWithFormat:NSLocalizedStringFromTable(@"group_invitation_format", @"Vector", nil), inviter];
}
else
{
self.inviteLabel.text = nil;
}
[self.inviteContainer layoutIfNeeded];
if (_separatorViewTopConstraint.constant != self.inviteContainer.frame.size.height)
{
_separatorViewTopConstraint.constant = self.inviteContainer.frame.size.height;
[self.view layoutIfNeeded];
}
}
else
{
self.inviteContainer.hidden = YES;
if (_separatorViewTopConstraint.constant != 0)
{
_separatorViewTopConstraint.constant = 0;
[self.view layoutIfNeeded];
}
}
if (_group.summary.profile.longDescription.length)
{
//@TODO: implement a specific html renderer to support h1/h2 and handle the Matrix media content URI (in the form of "mxc://...").
MXKEventFormatter *eventFormatter = [[MXKEventFormatter alloc] initWithMatrixSession:self.mxSession];
_groupLongDescription.attributedText = [eventFormatter renderHTMLString:_group.summary.profile.longDescription forEvent:nil];
_groupLongDescription.contentOffset = CGPointZero;
}
else
{
_groupLongDescription.text = nil;
}
}
else
{
_groupAvatar.image = nil;
_groupName.text = nil;
_groupDescription.text = nil;
self.inviteLabel.text = nil;
_groupLongDescription.text = nil;
self.inviteContainer.hidden = YES;
_groupLongDescription.text = nil;
_separatorViewTopConstraint.constant = 0;
_membersCountLabel.text = nil;
_roomsCountLabel.text = nil;
_countsContainer.hidden = YES;
}
// Round image view for thumbnail
_groupAvatar.layer.cornerRadius = _groupAvatar.frame.size.width / 2;
_groupAvatar.clipsToBounds = YES;
_groupAvatar.defaultBackgroundColor = kRiotSecondaryBgColor;
}
#pragma mark - Action
- (IBAction)onButtonPressed:(id)sender
{
if (!currentRequest)
{
if (sender == self.rightButton)
{
// Accept the invite
__weak typeof(self) weakSelf = self;
[self startActivityIndicator];
currentRequest = [self.mxSession acceptGroupInvite:_group.groupId success:^{
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentRequest = nil;
[self stopActivityIndicator];
[self refreshDisplayWithGroup:[_mxSession groupWithGroupId:_group.groupId]];
}
} failure:^(NSError *error) {
NSLog(@"[GroupDetailsViewController] join group (%@) failed", _group.groupId);
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentRequest = nil;
[self stopActivityIndicator];
}
// Alert user
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
}
else if (sender == self.leftButton)
{
// Decline the invite
__weak typeof(self) weakSelf = self;
[self startActivityIndicator];
currentRequest = [self.mxSession leaveGroup:_group.groupId success:^{
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentRequest = nil;
[self stopActivityIndicator];
[self withdrawViewControllerAnimated:YES completion:nil];
}
} failure:^(NSError *error) {
NSLog(@"[GroupDetailsViewController] leave group (%@) failed", _group.groupId);
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentRequest = nil;
[self stopActivityIndicator];
}
// Alert user
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
}
}
}
- (void)handleTapGesture:(UITapGestureRecognizer*)tapGestureRecognizer
{
UIView *view = tapGestureRecognizer.view;
if (view == _groupNameMask && _group.summary.profile.name)
{
if ([_groupName.text isEqualToString:_group.summary.profile.name])
{
// Display group's matrix id
_groupName.text = _group.groupId;
}
else
{
// Restore display name
_groupName.text = _group.summary.profile.name;
}
}
else if (view == _groupAvatarMask)
{
// Show the avatar in full screen
__block MXKImageView * avatarFullScreenView = [[MXKImageView alloc] initWithFrame:CGRectZero];
avatarFullScreenView.stretchable = YES;
[avatarFullScreenView setRightButtonTitle:[NSBundle mxk_localizedStringForKey:@"ok"] handler:^(MXKImageView* imageView, NSString* buttonTitle) {
[avatarFullScreenView dismissSelection];
[avatarFullScreenView removeFromSuperview];
avatarFullScreenView = nil;
isStatusBarHidden = NO;
// Trigger status bar update
[self setNeedsStatusBarAppearanceUpdate];
}];
NSString *avatarURL = [self.mainSession.matrixRestClient urlOfContent:_group.summary.profile.avatarUrl];
[avatarFullScreenView setImageURL:avatarURL
withType:nil
andImageOrientation:UIImageOrientationUp
previewImage:self.groupAvatar.image];
[avatarFullScreenView showFullScreen];
isStatusBarHidden = YES;
// Trigger status bar update
[self setNeedsStatusBarAppearanceUpdate];
}
}
@end

View file

@ -1,282 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="GroupHomeViewController">
<connections>
<outlet property="buttonsContainer" destination="EqU-yd-Ntb" id="SpC-UD-z6O"/>
<outlet property="countsContainer" destination="hkg-GN-Tej" id="cWs-i0-bVQ"/>
<outlet property="groupAvatar" destination="ehl-88-DfA" id="bKF-ij-hsH"/>
<outlet property="groupAvatarMask" destination="kYc-LP-Nip" id="u4M-Yf-wQy"/>
<outlet property="groupDescription" destination="jXh-2B-Bso" id="daH-OS-1BL"/>
<outlet property="groupLongDescription" destination="oUL-bJ-tfM" id="ZA0-1e-RrG"/>
<outlet property="groupName" destination="5UX-lR-Ac5" id="kzg-n6-ZXM"/>
<outlet property="groupNameMask" destination="mKE-ro-fuy" id="0DZ-3m-LNx"/>
<outlet property="inviteContainer" destination="nR4-eE-qJo" id="rsc-Gd-rLL"/>
<outlet property="inviteLabel" destination="UHk-6Y-MSO" id="JO0-8a-h78"/>
<outlet property="leftButton" destination="jTB-nL-KcP" id="iPW-qf-LbT"/>
<outlet property="mainHeaderContainer" destination="AKb-7n-nhQ" id="RUh-ZE-ul2"/>
<outlet property="membersCountContainer" destination="PgZ-iJ-yNZ" id="YKC-dF-QOE"/>
<outlet property="membersCountLabel" destination="qJ8-8X-Xzm" id="LRd-io-EFg"/>
<outlet property="rightButton" destination="xfk-oh-9db" id="JGC-zW-2vD"/>
<outlet property="roomsCountContainer" destination="xkH-zg-3jY" id="xo8-mh-emk"/>
<outlet property="roomsCountLabel" destination="XuG-pe-Lzn" id="Bbg-xa-lxp"/>
<outlet property="separatorView" destination="dlP-kX-cll" id="TMm-OR-eFJ"/>
<outlet property="separatorViewTopConstraint" destination="tSb-HY-8nq" id="jM0-gg-k1g"/>
<outlet property="view" destination="1TG-Rn-axS" id="WxL-e2-rVK"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="1TG-Rn-axS">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="AKb-7n-nhQ">
<rect key="frame" x="0.0" y="0.0" width="375" height="106.5"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kYc-LP-Nip">
<rect key="frame" x="8" y="5" width="80" height="80"/>
<subviews>
<view clipsSubviews="YES" contentMode="scaleAspectFill" translatesAutoresizingMaskIntoConstraints="NO" id="ehl-88-DfA" customClass="MXKImageView">
<rect key="frame" x="10" y="10" width="60" height="60"/>
<color key="backgroundColor" red="0.6886889638" green="1" blue="0.74383144840000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="MemberAvatar"/>
<constraints>
<constraint firstAttribute="width" secondItem="ehl-88-DfA" secondAttribute="height" multiplier="1:1" id="KSI-3d-yr8"/>
<constraint firstAttribute="width" constant="60" id="RFO-L1-XfN"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="ContactDetailsVCAvatarMask"/>
<constraints>
<constraint firstItem="ehl-88-DfA" firstAttribute="centerY" secondItem="kYc-LP-Nip" secondAttribute="centerY" id="120-Fe-9lk"/>
<constraint firstAttribute="width" secondItem="kYc-LP-Nip" secondAttribute="height" multiplier="1:1" id="HNr-XL-fXe"/>
<constraint firstItem="ehl-88-DfA" firstAttribute="centerX" secondItem="kYc-LP-Nip" secondAttribute="centerX" id="LMN-31-ZCn"/>
<constraint firstAttribute="width" constant="80" id="zV6-TZ-Oan"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5UX-lR-Ac5">
<rect key="frame" x="92" y="18" width="43.5" height="20.5"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jXh-2B-Bso">
<rect key="frame" x="92" y="44.5" width="37.5" height="18"/>
<accessibility key="accessibilityConfiguration" identifier="RoomTopic"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="mKE-ro-fuy">
<rect key="frame" x="87" y="15" width="53.5" height="25.5"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="ContactDetailsVCNameLabelMask"/>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="hkg-GN-Tej">
<rect key="frame" x="88" y="78.5" width="279" height="20"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="PgZ-iJ-yNZ">
<rect key="frame" x="0.0" y="0.0" width="86.5" height="20"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="tab_groups_selected.png" translatesAutoresizingMaskIntoConstraints="NO" id="YI6-IK-PkI">
<rect key="frame" x="4" y="2.5" width="15" height="15"/>
<constraints>
<constraint firstAttribute="width" secondItem="YI6-IK-PkI" secondAttribute="height" multiplier="1:1" id="azu-dv-Abo"/>
<constraint firstAttribute="width" constant="15" id="zka-UU-93t"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="2 members" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qJ8-8X-Xzm">
<rect key="frame" x="23" y="3.5" width="63.5" height="14"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption1"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" secondItem="qJ8-8X-Xzm" secondAttribute="height" constant="6" id="Aao-5S-pox"/>
<constraint firstItem="qJ8-8X-Xzm" firstAttribute="leading" secondItem="YI6-IK-PkI" secondAttribute="trailing" constant="4" id="NOr-CS-0zv"/>
<constraint firstAttribute="trailing" secondItem="qJ8-8X-Xzm" secondAttribute="trailing" id="ZwB-qD-I8A"/>
<constraint firstItem="YI6-IK-PkI" firstAttribute="leading" secondItem="PgZ-iJ-yNZ" secondAttribute="leading" constant="4" id="bkS-hZ-KQv"/>
<constraint firstItem="qJ8-8X-Xzm" firstAttribute="centerY" secondItem="PgZ-iJ-yNZ" secondAttribute="centerY" id="jdb-bW-4Oy"/>
<constraint firstItem="YI6-IK-PkI" firstAttribute="centerY" secondItem="PgZ-iJ-yNZ" secondAttribute="centerY" id="vCJ-Yz-2eu"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xkH-zg-3jY">
<rect key="frame" x="94.5" y="0.0" width="68" height="20"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="tab_rooms.png" translatesAutoresizingMaskIntoConstraints="NO" id="aZ9-Gu-utv">
<rect key="frame" x="4" y="2.5" width="15" height="15"/>
<constraints>
<constraint firstAttribute="width" constant="15" id="3df-1e-XMS"/>
<constraint firstAttribute="width" secondItem="aZ9-Gu-utv" secondAttribute="height" multiplier="1:1" id="hnv-qQ-D9X"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="2 rooms" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XuG-pe-Lzn">
<rect key="frame" x="22" y="3.5" width="46" height="14.5"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption1"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="XuG-pe-Lzn" secondAttribute="trailing" id="021-fG-7GQ"/>
<constraint firstItem="XuG-pe-Lzn" firstAttribute="leading" secondItem="aZ9-Gu-utv" secondAttribute="trailing" constant="3" id="3p6-oX-xHD"/>
<constraint firstItem="XuG-pe-Lzn" firstAttribute="centerY" secondItem="xkH-zg-3jY" secondAttribute="centerY" id="GvC-ox-7fH"/>
<constraint firstItem="aZ9-Gu-utv" firstAttribute="leading" secondItem="xkH-zg-3jY" secondAttribute="leading" constant="4" id="bbe-FJ-udn"/>
<constraint firstItem="aZ9-Gu-utv" firstAttribute="centerY" secondItem="xkH-zg-3jY" secondAttribute="centerY" id="fwX-jo-52x"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="PgZ-iJ-yNZ" firstAttribute="leading" secondItem="hkg-GN-Tej" secondAttribute="leading" id="1Hr-5B-w2S"/>
<constraint firstItem="PgZ-iJ-yNZ" firstAttribute="width" relation="lessThanOrEqual" secondItem="hkg-GN-Tej" secondAttribute="width" multiplier="0.5" id="1pU-62-CzD"/>
<constraint firstItem="xkH-zg-3jY" firstAttribute="top" secondItem="hkg-GN-Tej" secondAttribute="top" id="46J-yD-cKS"/>
<constraint firstAttribute="height" secondItem="PgZ-iJ-yNZ" secondAttribute="height" id="5AD-Zs-aXU"/>
<constraint firstItem="xkH-zg-3jY" firstAttribute="leading" secondItem="PgZ-iJ-yNZ" secondAttribute="trailing" constant="8" id="Cds-AK-yuk"/>
<constraint firstItem="xkH-zg-3jY" firstAttribute="width" relation="lessThanOrEqual" secondItem="hkg-GN-Tej" secondAttribute="width" multiplier="0.5" id="Jjt-EP-UFP"/>
<constraint firstItem="xkH-zg-3jY" firstAttribute="height" secondItem="PgZ-iJ-yNZ" secondAttribute="height" id="JkC-AN-RWn"/>
<constraint firstItem="PgZ-iJ-yNZ" firstAttribute="top" secondItem="hkg-GN-Tej" secondAttribute="top" id="ZyS-oe-dDv"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="xkH-zg-3jY" secondAttribute="trailing" id="aLt-Y9-7ZP"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="hkg-GN-Tej" secondAttribute="bottom" constant="8" id="04P-82-XhO"/>
<constraint firstItem="hkg-GN-Tej" firstAttribute="top" secondItem="jXh-2B-Bso" secondAttribute="bottom" constant="16" id="FVO-09-Pc5"/>
<constraint firstItem="5UX-lR-Ac5" firstAttribute="top" secondItem="AKb-7n-nhQ" secondAttribute="top" constant="18" id="FlH-ol-0TP"/>
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="kYc-LP-Nip" secondAttribute="bottom" priority="750" constant="10" id="G39-KZ-VFJ"/>
<constraint firstItem="mKE-ro-fuy" firstAttribute="centerX" secondItem="5UX-lR-Ac5" secondAttribute="centerX" id="G8w-Th-eCj"/>
<constraint firstItem="kYc-LP-Nip" firstAttribute="top" secondItem="AKb-7n-nhQ" secondAttribute="top" constant="5" id="IJD-FB-fWm"/>
<constraint firstItem="jXh-2B-Bso" firstAttribute="leading" secondItem="kYc-LP-Nip" secondAttribute="trailing" constant="4" id="Ot2-58-G82"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="jXh-2B-Bso" secondAttribute="trailing" constant="8" id="QeR-3r-KrK"/>
<constraint firstAttribute="trailing" secondItem="hkg-GN-Tej" secondAttribute="trailing" constant="8" id="RHn-bj-Dld"/>
<constraint firstItem="kYc-LP-Nip" firstAttribute="leading" secondItem="AKb-7n-nhQ" secondAttribute="leading" constant="8" id="Y6V-cp-eRq"/>
<constraint firstItem="hkg-GN-Tej" firstAttribute="leading" secondItem="kYc-LP-Nip" secondAttribute="trailing" id="Z8J-Tk-BGi"/>
<constraint firstItem="5UX-lR-Ac5" firstAttribute="leading" secondItem="kYc-LP-Nip" secondAttribute="trailing" constant="4" id="fxX-Ak-zfG"/>
<constraint firstItem="mKE-ro-fuy" firstAttribute="height" secondItem="5UX-lR-Ac5" secondAttribute="height" constant="5" id="jtN-q7-iqn"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="5UX-lR-Ac5" secondAttribute="trailing" constant="8" id="k8p-VY-5zr"/>
<constraint firstItem="mKE-ro-fuy" firstAttribute="centerY" secondItem="5UX-lR-Ac5" secondAttribute="centerY" id="nzz-nn-a5u"/>
<constraint firstItem="mKE-ro-fuy" firstAttribute="width" secondItem="5UX-lR-Ac5" secondAttribute="width" constant="10" id="o6d-6K-UUD"/>
<constraint firstItem="jXh-2B-Bso" firstAttribute="top" secondItem="mKE-ro-fuy" secondAttribute="bottom" constant="4" id="wyz-Qr-ka3"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nR4-eE-qJo">
<rect key="frame" x="0.0" y="106.5" width="375" height="105.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="UHk-6Y-MSO">
<rect key="frame" x="167" y="15" width="42" height="20.5"/>
<accessibility key="accessibilityConfiguration" identifier="PreviewLabel"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="EqU-yd-Ntb" userLabel="buttonsContainer">
<rect key="frame" x="30" y="55.5" width="315" height="30"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="jTB-nL-KcP" userLabel="Left Button">
<rect key="frame" x="0.0" y="0.0" width="151" height="30"/>
<color key="backgroundColor" red="0.6886889638" green="1" blue="0.74383144840000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="LeftButton"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="16"/>
<state key="normal" title="Left button">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="gNs-ys-XsX"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="xfk-oh-9db" userLabel="Right Button">
<rect key="frame" x="164" y="0.0" width="151" height="30"/>
<color key="backgroundColor" red="0.6886889638" green="1" blue="0.74383144840000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="RightButton"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="16"/>
<state key="normal" title="Right Button">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="88I-7i-Arx"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="xfk-oh-9db" firstAttribute="height" secondItem="EqU-yd-Ntb" secondAttribute="height" id="HRj-9b-sf9"/>
<constraint firstItem="xfk-oh-9db" firstAttribute="width" secondItem="EqU-yd-Ntb" secondAttribute="width" multiplier="0.48" id="JXG-Qy-PTf"/>
<constraint firstAttribute="trailing" secondItem="xfk-oh-9db" secondAttribute="trailing" id="KnR-27-pqz"/>
<constraint firstItem="jTB-nL-KcP" firstAttribute="top" secondItem="EqU-yd-Ntb" secondAttribute="top" id="SvJ-kv-poF"/>
<constraint firstItem="xfk-oh-9db" firstAttribute="top" secondItem="EqU-yd-Ntb" secondAttribute="top" id="WI3-b5-AgB"/>
<constraint firstAttribute="height" constant="30" id="ZZd-YY-Gd2"/>
<constraint firstItem="jTB-nL-KcP" firstAttribute="height" secondItem="EqU-yd-Ntb" secondAttribute="height" id="fxc-lx-cMI"/>
<constraint firstItem="jTB-nL-KcP" firstAttribute="leading" secondItem="EqU-yd-Ntb" secondAttribute="leading" id="gQS-yN-cek"/>
<constraint firstItem="jTB-nL-KcP" firstAttribute="width" secondItem="EqU-yd-Ntb" secondAttribute="width" multiplier="0.48" id="qmv-b5-hHq"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="EqU-yd-Ntb" firstAttribute="leading" secondItem="nR4-eE-qJo" secondAttribute="leading" constant="30" id="0A0-CA-Han"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="UHk-6Y-MSO" secondAttribute="trailing" constant="31" id="1AA-2G-22p"/>
<constraint firstItem="EqU-yd-Ntb" firstAttribute="top" secondItem="UHk-6Y-MSO" secondAttribute="bottom" constant="20" id="T4l-2m-fsZ"/>
<constraint firstAttribute="trailing" secondItem="EqU-yd-Ntb" secondAttribute="trailing" constant="30" id="cCk-lA-SDz"/>
<constraint firstItem="UHk-6Y-MSO" firstAttribute="centerX" secondItem="nR4-eE-qJo" secondAttribute="centerX" id="dlW-cX-D6T"/>
<constraint firstItem="UHk-6Y-MSO" firstAttribute="top" secondItem="nR4-eE-qJo" secondAttribute="top" constant="15" id="oNr-AR-g3d"/>
<constraint firstItem="UHk-6Y-MSO" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="nR4-eE-qJo" secondAttribute="leading" constant="31" id="r7D-qk-LEG"/>
<constraint firstAttribute="bottom" secondItem="EqU-yd-Ntb" secondAttribute="bottom" constant="20" id="zlf-mL-iWH"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="dlP-kX-cll">
<rect key="frame" x="0.0" y="204.5" width="375" height="1"/>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
<accessibility key="accessibilityConfiguration" identifier="BottomBorderView"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="tUj-3s-NIW"/>
</constraints>
</view>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" editable="NO" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="oUL-bJ-tfM">
<rect key="frame" x="8" y="205.5" width="359" height="453.5"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<string key="text">Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda.</string>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
<dataDetectorType key="dataDetectorTypes" link="YES"/>
</textView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="SegmentedVCView"/>
<constraints>
<constraint firstItem="AKb-7n-nhQ" firstAttribute="top" secondItem="1TG-Rn-axS" secondAttribute="top" id="3NU-eX-o9z"/>
<constraint firstAttribute="trailing" secondItem="oUL-bJ-tfM" secondAttribute="trailing" constant="8" id="4G6-iX-BjR"/>
<constraint firstAttribute="bottom" secondItem="oUL-bJ-tfM" secondAttribute="bottom" constant="8" id="Cfg-1K-EMs"/>
<constraint firstItem="AKb-7n-nhQ" firstAttribute="leading" secondItem="1TG-Rn-axS" secondAttribute="leading" id="O32-n9-j7o"/>
<constraint firstItem="nR4-eE-qJo" firstAttribute="leading" secondItem="1TG-Rn-axS" secondAttribute="leading" id="QRs-15-AIO"/>
<constraint firstItem="oUL-bJ-tfM" firstAttribute="leading" secondItem="1TG-Rn-axS" secondAttribute="leading" constant="8" id="bG6-iY-kCj"/>
<constraint firstItem="nR4-eE-qJo" firstAttribute="top" secondItem="AKb-7n-nhQ" secondAttribute="bottom" id="e0J-TS-0Z2"/>
<constraint firstAttribute="trailing" secondItem="AKb-7n-nhQ" secondAttribute="trailing" id="jEv-Pg-vBb"/>
<constraint firstAttribute="trailing" secondItem="nR4-eE-qJo" secondAttribute="trailing" id="kB6-fy-TZ7"/>
<constraint firstItem="dlP-kX-cll" firstAttribute="leading" secondItem="1TG-Rn-axS" secondAttribute="leading" id="p9g-6c-wFe"/>
<constraint firstAttribute="trailing" secondItem="dlP-kX-cll" secondAttribute="trailing" id="qdC-Jn-j6W"/>
<constraint firstItem="oUL-bJ-tfM" firstAttribute="top" secondItem="dlP-kX-cll" secondAttribute="bottom" id="qoC-BS-r0k"/>
<constraint firstItem="dlP-kX-cll" firstAttribute="top" secondItem="AKb-7n-nhQ" secondAttribute="bottom" constant="98" id="tSb-HY-8nq"/>
</constraints>
<point key="canvasLocation" x="26.5" y="51.5"/>
</view>
</objects>
<resources>
<image name="tab_groups_selected.png" width="25" height="25"/>
<image name="tab_rooms.png" width="25" height="25"/>
</resources>
</document>

View file

@ -1,85 +0,0 @@
/*
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import "ContactsTableViewController.h"
@class Contact;
/**
'GroupParticipantsViewController' instance is used to list members of the group defined by the property 'mxGroup'.
When this property is nil, the view controller is empty.
*/
@interface GroupParticipantsViewController : MXKViewController <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UIGestureRecognizerDelegate, ContactsTableViewControllerDelegate>
{
@protected
/**
Section indexes
*/
NSInteger participantsSection;
NSInteger invitedSection;
/**
The current list of joined members.
*/
NSMutableArray<Contact*> *actualParticipants;
/**
The current list of invited members.
*/
NSMutableArray<Contact*> *invitedParticipants;
}
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (weak, nonatomic) IBOutlet UIView *searchBarHeader;
@property (weak, nonatomic) IBOutlet UISearchBar *searchBarView;
@property (weak, nonatomic) IBOutlet UIView *searchBarHeaderBorder;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *searchBarTopConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *tableViewBottomConstraint;
/**
A matrix group (nil by default).
*/
@property (strong, readonly, nonatomic) MXGroup *group;
@property (strong, readonly, nonatomic) MXSession *mxSession;
/**
Returns the `UINib` object initialized for a `GroupParticipantsViewController`.
@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 `GroupParticipantsViewController` object.
@discussion This is the designated initializer for programmatic instantiation.
@return An initialized `GroupParticipantsViewController` object if successful, `nil` otherwise.
*/
+ (instancetype)groupParticipantsViewController;
/**
Set the group for which the details are displayed.
Provide the related matrix session.
@param group
@param mxSession
*/
- (void)setGroup:(MXGroup*)group withMatrixSession:(MXSession*)mxSession;
@end

File diff suppressed because it is too large Load diff

View file

@ -1,87 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13527"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="GroupParticipantsViewController">
<connections>
<outlet property="searchBarHeader" destination="Zm7-AB-ZtE" id="6ee-P0-twi"/>
<outlet property="searchBarHeaderBorder" destination="gcy-W7-89G" id="tsy-SP-KaJ"/>
<outlet property="searchBarTopConstraint" destination="sUb-hD-qXJ" id="rzi-JJ-nnP"/>
<outlet property="searchBarView" destination="bsq-3U-VjV" id="x3M-wX-RW8"/>
<outlet property="tableView" destination="kNf-Ll-jvH" id="uzM-uQ-peQ"/>
<outlet property="tableViewBottomConstraint" destination="jLY-ml-Psl" id="Q2b-sC-Yqn"/>
<outlet property="view" destination="iN0-l3-epB" id="csR-cn-S4h"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Zm7-AB-ZtE">
<rect key="frame" x="0.0" y="0.0" width="375" height="50"/>
<subviews>
<searchBar contentMode="redraw" searchBarStyle="minimal" translatesAutoresizingMaskIntoConstraints="NO" id="bsq-3U-VjV">
<rect key="frame" x="0.0" y="0.0" width="375" height="50"/>
<textInputTraits key="textInputTraits" returnKeyType="done"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="accessibilityIdentifier" value="RoomParticipantsVCSearchBarView"/>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="delegate" destination="-1" id="UYv-bz-JBZ"/>
</connections>
</searchBar>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gcy-W7-89G">
<rect key="frame" x="0.0" y="49" width="375" height="1"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="Rka-an-qn3"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<accessibility key="accessibilityConfiguration" identifier="RoomParticipantsVCSearchBarHeader"/>
<constraints>
<constraint firstItem="gcy-W7-89G" firstAttribute="leading" secondItem="Zm7-AB-ZtE" secondAttribute="leading" id="4Yn-dN-O2U"/>
<constraint firstItem="bsq-3U-VjV" firstAttribute="leading" secondItem="Zm7-AB-ZtE" secondAttribute="leading" id="6ze-Az-ymf"/>
<constraint firstAttribute="bottom" secondItem="bsq-3U-VjV" secondAttribute="bottom" id="KDW-SI-sG6"/>
<constraint firstAttribute="trailing" secondItem="bsq-3U-VjV" secondAttribute="trailing" id="ZlE-SL-UfQ"/>
<constraint firstAttribute="trailing" secondItem="gcy-W7-89G" secondAttribute="trailing" id="hqD-vA-OM5"/>
<constraint firstAttribute="bottom" secondItem="gcy-W7-89G" secondAttribute="bottom" id="ibU-h7-mHt"/>
<constraint firstAttribute="height" constant="50" id="kSM-fg-IHB"/>
<constraint firstItem="bsq-3U-VjV" firstAttribute="top" secondItem="Zm7-AB-ZtE" secondAttribute="top" id="qpF-Za-XTL"/>
</constraints>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" keyboardDismissMode="onDrag" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="kNf-Ll-jvH">
<rect key="frame" x="0.0" y="50" width="375" height="617"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="accessibilityIdentifier" value="RoomParticipantsVCTableView"/>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="dataSource" destination="-1" id="tlI-w1-VJw"/>
<outlet property="delegate" destination="-1" id="xcS-Zy-x2X"/>
</connections>
</tableView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="RoomParticipantsVCView"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="Zm7-AB-ZtE" secondAttribute="trailing" id="0W7-Iv-Cs1"/>
<constraint firstAttribute="trailing" secondItem="kNf-Ll-jvH" secondAttribute="trailing" id="1KS-nO-Jys"/>
<constraint firstItem="Zm7-AB-ZtE" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="Irh-6y-0cw"/>
<constraint firstItem="kNf-Ll-jvH" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="hfq-4u-4J8"/>
<constraint firstAttribute="bottom" secondItem="kNf-Ll-jvH" secondAttribute="bottom" id="jLY-ml-Psl"/>
<constraint firstItem="Zm7-AB-ZtE" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="sUb-hD-qXJ"/>
<constraint firstItem="kNf-Ll-jvH" firstAttribute="top" secondItem="Zm7-AB-ZtE" secondAttribute="bottom" id="tYv-VV-8dI"/>
</constraints>
</view>
</objects>
</document>

View file

@ -1,73 +0,0 @@
/*
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import <MatrixKit/MatrixKit.h>
/**
'GroupRoomsViewController' instance is used to list the rooms of the group defined by the property 'mxGroup'.
When this property is nil, the view controller is empty.
*/
@interface GroupRoomsViewController : MXKViewController <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate>
{
@protected
/**
The current list of the rooms.
*/
NSArray<MXGroupRoom*> *groupRooms;
}
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (weak, nonatomic) IBOutlet UIView *searchBarHeader;
@property (weak, nonatomic) IBOutlet UISearchBar *searchBarView;
@property (weak, nonatomic) IBOutlet UIView *searchBarHeaderBorder;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *searchBarTopConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *tableViewBottomConstraint;
/**
A matrix group (nil by default).
*/
@property (strong, readonly, nonatomic) MXGroup *group;
@property (strong, readonly, nonatomic) MXSession *mxSession;
/**
Returns the `UINib` object initialized for a `GroupRoomsViewController`.
@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 `GroupRoomsViewController` object.
@discussion This is the designated initializer for programmatic instantiation.
@return An initialized `GroupRoomsViewController` object if successful, `nil` otherwise.
*/
+ (instancetype)groupRoomsViewController;
/**
Set the group for which the rooms are listed.
Provide the related matrix session.
@param group
@param mxSession
*/
- (void)setGroup:(MXGroup*)group withMatrixSession:(MXSession*)mxSession;
@end

View file

@ -1,623 +0,0 @@
/*
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import "GroupRoomsViewController.h"
#import "AppDelegate.h"
#import "GroupRoomTableViewCell.h"
#import "RageShakeManager.h"
@interface GroupRoomsViewController ()
{
// Search result
NSString *currentSearchText;
NSMutableArray<MXGroupRoom*> *filteredGroupRooms;
// Observe kRiotDesignValuesDidChangeThemeNotification to handle user interface theme change.
id kRiotDesignValuesDidChangeThemeNotificationObserver;
}
@end
@implementation GroupRoomsViewController
#pragma mark - Class methods
+ (UINib *)nib
{
return [UINib nibWithNibName:NSStringFromClass(self.class)
bundle:[NSBundle bundleForClass:self.class]];
}
+ (instancetype)groupRoomsViewController
{
return [[[self class] alloc] initWithNibName:NSStringFromClass(self.class)
bundle:[NSBundle bundleForClass:self.class]];
}
#pragma mark -
- (void)finalizeInit
{
[super finalizeInit];
// Setup `MXKViewControllerHandling` properties
self.enableBarTintColorStatusChange = NO;
self.rageShakeManager = [RageShakeManager sharedManager];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Check whether the view controller has been pushed via storyboard
if (!self.tableView)
{
// Instantiate view controller objects
[[[self class] nib] instantiateWithOwner:self options:nil];
}
// Adjust Top and Bottom constraints to take into account potential navBar and tabBar.
[NSLayoutConstraint deactivateConstraints:@[_searchBarTopConstraint, _tableViewBottomConstraint]];
_searchBarTopConstraint = [NSLayoutConstraint constraintWithItem:self.topLayoutGuide
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.searchBarHeader
attribute:NSLayoutAttributeTop
multiplier:1.0f
constant:0.0f];
_tableViewBottomConstraint = [NSLayoutConstraint constraintWithItem:self.bottomLayoutGuide
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.tableView
attribute:NSLayoutAttributeBottom
multiplier:1.0f
constant:0.0f];
[NSLayoutConstraint activateConstraints:@[_searchBarTopConstraint, _tableViewBottomConstraint]];
_searchBarView.placeholder = NSLocalizedStringFromTable(@"group_rooms_filter_rooms", @"Vector", nil);
_searchBarView.returnKeyType = UIReturnKeyDone;
_searchBarView.autocapitalizationType = UITextAutocapitalizationTypeNone;
// Search bar header is hidden when no group is provided
_searchBarHeader.hidden = (self.group == nil);
// Enable self-sizing cells and section headers.
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 74;
self.tableView.sectionHeaderHeight = 0;
// Hide line separators of empty cells
self.tableView.tableFooterView = [[UIView alloc] init];
[self.tableView registerClass:GroupRoomTableViewCell.class forCellReuseIdentifier:@"RoomTableViewCellId"];
// Observe user interface theme change.
kRiotDesignValuesDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kRiotDesignValuesDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
[self userInterfaceThemeDidChange];
}];
[self userInterfaceThemeDidChange];
}
- (void)userInterfaceThemeDidChange
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
[self refreshSearchBarItemsColor:_searchBarView];
_searchBarHeaderBorder.backgroundColor = kRiotAuxiliaryColor;
// Check the table view style to select its bg color.
self.tableView.backgroundColor = ((self.tableView.style == UITableViewStylePlain) ? kRiotPrimaryBgColor : kRiotSecondaryBgColor);
self.view.backgroundColor = self.tableView.backgroundColor;
if (self.tableView.dataSource)
{
[self.tableView reloadData];
}
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
return kRiotDesignStatusBarStyle;
}
// This method is called when the viewcontroller is added or removed from a container view controller.
- (void)didMoveToParentViewController:(nullable UIViewController *)parent
{
[super didMoveToParentViewController:parent];
}
- (void)destroy
{
if (kRiotDesignValuesDidChangeThemeNotificationObserver)
{
[[NSNotificationCenter defaultCenter] removeObserver:kRiotDesignValuesDidChangeThemeNotificationObserver];
kRiotDesignValuesDidChangeThemeNotificationObserver = nil;
}
_group = nil;
_mxSession = nil;
filteredGroupRooms = nil;
groupRooms = nil;
// Note: all observers are removed during super call.
[super destroy];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Screen tracking
[[AppDelegate theDelegate] trackScreen:@"GroupDetailsRooms"];
if (_group)
{
// Restore the listeners on the group update.
[self registerOnGroupChangeNotifications];
// Check whether the selected group is stored in the user's session, or if it is a group preview.
// Replace the displayed group instance with the one stored in the session (if any).
MXGroup *storedGroup = [_mxSession groupWithGroupId:_group.groupId];
BOOL isPreview = (!storedGroup);
// Force refresh
[self refreshDisplayWithGroup:(isPreview ? _group : storedGroup)];
// Prepare a block called on successful update in case of a group preview.
// Indeed the group update notifications are triggered by the matrix session only for the user's groups.
void (^success)(void) = ^void(void)
{
[self refreshDisplayWithGroup:_group];
};
// Trigger a refresh on the group rooms.
[self.mxSession updateGroupRooms:_group success:(isPreview ? success : nil) failure:^(NSError *error) {
NSLog(@"[GroupRoomsViewController] viewWillAppear: group rooms update failed %@", _group.groupId);
}];
}
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self cancelRegistrationOnGroupChangeNotifications];
// cancel any pending search
[self searchBarCancelButtonClicked:_searchBarView];
}
- (void)withdrawViewControllerAnimated:(BOOL)animated completion:(void (^)(void))completion
{
// Check whether the current view controller is displayed inside a segmented view controller in order to withdraw the right item
if (self.parentViewController && [self.parentViewController isKindOfClass:SegmentedViewController.class])
{
[((SegmentedViewController*)self.parentViewController) withdrawViewControllerAnimated:animated completion:completion];
}
else
{
[super withdrawViewControllerAnimated:animated completion:completion];
}
}
- (void)setGroup:(MXGroup*)group withMatrixSession:(MXSession*)mxSession
{
// Cancel any pending search
[self searchBarCancelButtonClicked:_searchBarView];
if (_mxSession != mxSession)
{
[self cancelRegistrationOnGroupChangeNotifications];
_mxSession = mxSession;
[self registerOnGroupChangeNotifications];
}
[self addMatrixSession:mxSession];
[self refreshDisplayWithGroup:group];
}
#pragma mark -
- (void)registerOnGroupChangeNotifications
{
if (_mxSession)
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didUpdateGroupRooms:) name:kMXSessionDidUpdateGroupRoomsNotification object:_mxSession];
}
}
- (void)cancelRegistrationOnGroupChangeNotifications
{
// Remove any pending observers
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDidUpdateGroupRoomsNotification object:_mxSession];
}
- (void)didUpdateGroupRooms:(NSNotification *)notif
{
MXGroup *group = notif.userInfo[kMXSessionNotificationGroupKey];
if (group && [group.groupId isEqualToString:_group.groupId])
{
// Update the current displayed group instance with the one stored in the session.
[self refreshDisplayWithGroup:group];
}
}
- (void)refreshDisplayWithGroup:(MXGroup *)group
{
_group = group;
if (_group)
{
_searchBarHeader.hidden = NO;
groupRooms = _group.rooms.chunk;
}
else
{
// Search bar header is hidden when no group is provided
_searchBarHeader.hidden = YES;
groupRooms = nil;
}
// Reload search result if any
if (currentSearchText.length)
{
NSString *searchText = currentSearchText;
currentSearchText = nil;
[self searchBar:_searchBarView textDidChange:searchText];
}
else
{
[self refreshTableView];
}
}
- (void)startActivityIndicator
{
// Check whether the current view controller is displayed inside a segmented view controller in order to run the right activity view
if (self.parentViewController && [self.parentViewController isKindOfClass:SegmentedViewController.class])
{
[((SegmentedViewController*)self.parentViewController) startActivityIndicator];
// Force stop the activity view of the view controller
[self.activityIndicator stopAnimating];
}
else
{
[super startActivityIndicator];
}
}
- (void)stopActivityIndicator
{
// Check whether the current view controller is displayed inside a segmented view controller in order to stop the right activity view
if (self.parentViewController && [self.parentViewController isKindOfClass:SegmentedViewController.class])
{
[((SegmentedViewController*)self.parentViewController) stopActivityIndicator];
// Force stop the activity view of the view controller
[self.activityIndicator stopAnimating];
}
else
{
[super stopActivityIndicator];
}
}
#pragma mark - Internals
- (void)refreshTableView
{
[self.tableView reloadData];
}
- (void)pushViewController:(UIViewController*)viewController
{
// Check whether the view controller is displayed inside a segmented one.
if (self.parentViewController.navigationController)
{
// Hide back button title
self.parentViewController.navigationItem.backBarButtonItem =[[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
[self.parentViewController.navigationController pushViewController:viewController animated:YES];
}
else
{
// Hide back button title
self.navigationItem.backBarButtonItem =[[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
[self.navigationController pushViewController:viewController animated:YES];
}
}
#pragma mark - UITableView data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSInteger count = 0;
if (currentSearchText.length)
{
if (filteredGroupRooms.count)
{
count++;
}
}
else
{
if (groupRooms.count)
{
count++;
}
}
return count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger count = 0;
if (currentSearchText.length)
{
count = filteredGroupRooms.count;
}
else
{
count = groupRooms.count;
}
return count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
GroupRoomTableViewCell* roomCell = [tableView dequeueReusableCellWithIdentifier:@"RoomTableViewCellId" forIndexPath:indexPath];
roomCell.selectionStyle = UITableViewCellSelectionStyleNone;
MXGroupRoom *room;
NSArray *rooms;
if (currentSearchText.length)
{
rooms = filteredGroupRooms;
}
else
{
rooms = groupRooms;
}
if (indexPath.row < rooms.count)
{
room = rooms[indexPath.row];
}
if (room)
{
[roomCell render:room withMatrixSession:self.mxSession];
}
return roomCell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}
- (void)tableView:(UITableView*)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath*)indexPath
{
// iOS8 requires this method to enable editing (see editActionsForRowAtIndexPath).
}
#pragma mark - UITableView delegate
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return tableView.estimatedRowHeight;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.backgroundColor = kRiotPrimaryBgColor;
// Update the selected background view
if (kRiotSelectedBgColor)
{
cell.selectedBackgroundView = [[UIView alloc] init];
cell.selectedBackgroundView.backgroundColor = kRiotSelectedBgColor;
}
else
{
if (tableView.style == UITableViewStylePlain)
{
cell.selectedBackgroundView = nil;
}
else
{
cell.selectedBackgroundView.backgroundColor = nil;
}
}
// Refresh here the estimated row height
tableView.estimatedRowHeight = cell.frame.size.height;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
//- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
//{
// NSMutableArray* actions;
//
// // @TODO Add the swipe to remove this room from the community if the current user is admin
// actions = [[NSMutableArray alloc] init];
//
// // Patch: Force the width of the button by adding whitespace characters into the title string.
// UITableViewRowAction *leaveAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@" " handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){
//
// // @TODO Remove the room
//
// }];
//
// leaveAction.backgroundColor = [MXKTools convertImageToPatternColor:@"remove_icon_blue" backgroundColor:kRiotSecondaryBgColor patternSize:CGSizeMake(74, 74) resourceSize:CGSizeMake(24, 24)];
// [actions insertObject:leaveAction atIndex:0];
//
// return actions;
//}
#pragma mark - UISearchBar delegate
- (void)refreshSearchBarItemsColor:(UISearchBar *)searchBar
{
// bar tint color
searchBar.barTintColor = searchBar.tintColor = kRiotColorBlue;
searchBar.tintColor = kRiotColorBlue;
// FIXME: this all seems incredibly fragile and tied to gutwrenching the current UISearchBar internals.
// text color
UITextField *searchBarTextField = [searchBar valueForKey:@"_searchField"];
searchBarTextField.textColor = kRiotSecondaryTextColor;
// Magnifying glass icon.
UIImageView *leftImageView = (UIImageView *)searchBarTextField.leftView;
leftImageView.image = [leftImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
leftImageView.tintColor = kRiotColorBlue;
// remove the gray background color
UIView *effectBackgroundTop = [searchBarTextField valueForKey:@"_effectBackgroundTop"];
UIView *effectBackgroundBottom = [searchBarTextField valueForKey:@"_effectBackgroundBottom"];
effectBackgroundTop.hidden = YES;
effectBackgroundBottom.hidden = YES;
// place holder
searchBarTextField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:searchBarTextField.placeholder
attributes:@{NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle),
NSUnderlineColorAttributeName: kRiotColorBlue,
NSForegroundColorAttributeName: kRiotColorBlue}];
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
// Update search results.
NSUInteger index;
MXGroupRoom *groupRoom;
searchText = [searchText stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if (!currentSearchText.length || [searchText hasPrefix:currentSearchText] == NO)
{
// Copy participants and invited participants
filteredGroupRooms = [NSMutableArray arrayWithArray:groupRooms];
}
currentSearchText = searchText;
// Filter group participants
if (currentSearchText.length)
{
for (index = 0; index < filteredGroupRooms.count;)
{
groupRoom = filteredGroupRooms[index];
NSString *displayName = groupRoom.name;
if (!displayName)
{
displayName = groupRoom.canonicalAlias;
}
if (!displayName)
{
displayName = groupRoom.roomId;
}
if ([displayName rangeOfString:currentSearchText options:NSCaseInsensitiveSearch].location == NSNotFound)
{
[filteredGroupRooms removeObjectAtIndex:index];
}
else
{
index++;
}
}
}
else
{
filteredGroupRooms = nil;
}
// Refresh display
[self refreshTableView];
}
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
searchBar.showsCancelButton = YES;
return YES;
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar
{
searchBar.showsCancelButton = NO;
return YES;
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
// "Done" key has been pressed.
// Dismiss keyboard
[_searchBarView resignFirstResponder];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
if (currentSearchText)
{
currentSearchText = nil;
filteredGroupRooms = nil;
[self refreshTableView];
}
searchBar.text = nil;
// Leave search
[searchBar resignFirstResponder];
}
@end

View file

@ -1,87 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="GroupRoomsViewController">
<connections>
<outlet property="searchBarHeader" destination="Zm7-AB-ZtE" id="6ee-P0-twi"/>
<outlet property="searchBarHeaderBorder" destination="gcy-W7-89G" id="tsy-SP-KaJ"/>
<outlet property="searchBarTopConstraint" destination="sUb-hD-qXJ" id="rzi-JJ-nnP"/>
<outlet property="searchBarView" destination="bsq-3U-VjV" id="x3M-wX-RW8"/>
<outlet property="tableView" destination="kNf-Ll-jvH" id="uzM-uQ-peQ"/>
<outlet property="tableViewBottomConstraint" destination="jLY-ml-Psl" id="Q2b-sC-Yqn"/>
<outlet property="view" destination="iN0-l3-epB" id="csR-cn-S4h"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Zm7-AB-ZtE">
<rect key="frame" x="0.0" y="0.0" width="375" height="50"/>
<subviews>
<searchBar contentMode="redraw" searchBarStyle="minimal" translatesAutoresizingMaskIntoConstraints="NO" id="bsq-3U-VjV">
<rect key="frame" x="0.0" y="0.0" width="375" height="50"/>
<textInputTraits key="textInputTraits" returnKeyType="done"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="accessibilityIdentifier" value="RoomParticipantsVCSearchBarView"/>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="delegate" destination="-1" id="UYv-bz-JBZ"/>
</connections>
</searchBar>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gcy-W7-89G">
<rect key="frame" x="0.0" y="49" width="375" height="1"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="Rka-an-qn3"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<accessibility key="accessibilityConfiguration" identifier="RoomParticipantsVCSearchBarHeader"/>
<constraints>
<constraint firstItem="gcy-W7-89G" firstAttribute="leading" secondItem="Zm7-AB-ZtE" secondAttribute="leading" id="4Yn-dN-O2U"/>
<constraint firstItem="bsq-3U-VjV" firstAttribute="leading" secondItem="Zm7-AB-ZtE" secondAttribute="leading" id="6ze-Az-ymf"/>
<constraint firstAttribute="bottom" secondItem="bsq-3U-VjV" secondAttribute="bottom" id="KDW-SI-sG6"/>
<constraint firstAttribute="trailing" secondItem="bsq-3U-VjV" secondAttribute="trailing" id="ZlE-SL-UfQ"/>
<constraint firstAttribute="trailing" secondItem="gcy-W7-89G" secondAttribute="trailing" id="hqD-vA-OM5"/>
<constraint firstAttribute="bottom" secondItem="gcy-W7-89G" secondAttribute="bottom" id="ibU-h7-mHt"/>
<constraint firstAttribute="height" constant="50" id="kSM-fg-IHB"/>
<constraint firstItem="bsq-3U-VjV" firstAttribute="top" secondItem="Zm7-AB-ZtE" secondAttribute="top" id="qpF-Za-XTL"/>
</constraints>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" keyboardDismissMode="onDrag" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="kNf-Ll-jvH">
<rect key="frame" x="0.0" y="50" width="375" height="617"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="accessibilityIdentifier" value="RoomParticipantsVCTableView"/>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="dataSource" destination="-1" id="tlI-w1-VJw"/>
<outlet property="delegate" destination="-1" id="xcS-Zy-x2X"/>
</connections>
</tableView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="RoomParticipantsVCView"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="Zm7-AB-ZtE" secondAttribute="trailing" id="0W7-Iv-Cs1"/>
<constraint firstAttribute="trailing" secondItem="kNf-Ll-jvH" secondAttribute="trailing" id="1KS-nO-Jys"/>
<constraint firstItem="Zm7-AB-ZtE" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="Irh-6y-0cw"/>
<constraint firstItem="kNf-Ll-jvH" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="hfq-4u-4J8"/>
<constraint firstAttribute="bottom" secondItem="kNf-Ll-jvH" secondAttribute="bottom" id="jLY-ml-Psl"/>
<constraint firstItem="Zm7-AB-ZtE" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="sUb-hD-qXJ"/>
<constraint firstItem="kNf-Ll-jvH" firstAttribute="top" secondItem="Zm7-AB-ZtE" secondAttribute="bottom" id="tYv-VV-8dI"/>
</constraints>
</view>
</objects>
</document>

View file

@ -1,52 +0,0 @@
/*
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import <MatrixKit/MatrixKit.h>
/**
The `GroupsViewController` screen is the view controller displayed when `Groups` tab is selected.
*/
@interface GroupsViewController : MXKGroupListViewController <MXKGroupListViewControllerDelegate>
{
@protected
/**
The group identifier related to the cell which is in editing mode (if any).
*/
NSString *editedGroupId;
/**
Current alert (if any).
*/
UIAlertController *currentAlert;
/**
The image view of the (+) button.
*/
UIImageView* plusButtonImageView;
}
/**
If YES, the table view will scroll at the top on the next data source refresh.
It comes back to NO after each refresh.
*/
@property (nonatomic) BOOL shouldScrollToTopOnRefresh;
/**
Tell whether the search bar at the top of the groups table is enabled. YES by default.
*/
@property (nonatomic) BOOL enableSearchBar;
@end

View file

@ -1,799 +0,0 @@
/*
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import "GroupsViewController.h"
#import "GroupTableViewCell.h"
#import "GroupInviteTableViewCell.h"
#import "AppDelegate.h"
@interface GroupsViewController ()
{
// Tell whether a groups refresh is pending (suspended during editing mode).
BOOL isRefreshPending;
// Observe UIApplicationDidEnterBackgroundNotification to cancel editing mode when app leaves the foreground state.
id UIApplicationDidEnterBackgroundNotificationObserver;
// Observe kAppDelegateDidTapStatusBarNotification to handle tap on clock status bar.
id kAppDelegateDidTapStatusBarNotificationObserver;
MXHTTPOperation *currentRequest;
// The fake search bar displayed at the top of the recents table. We switch on the actual search bar (self.groupsSearchBar)
// when the user selects it.
UISearchBar *tableSearchBar;
// Observe kRiotDesignValuesDidChangeThemeNotification to handle user interface theme change.
id kRiotDesignValuesDidChangeThemeNotificationObserver;
}
@end
@implementation GroupsViewController
- (void)finalizeInit
{
[super finalizeInit];
// Setup `MXKViewControllerHandling` properties
self.enableBarTintColorStatusChange = NO;
self.rageShakeManager = [RageShakeManager sharedManager];
// Enable the search bar in the recents table, and remove the search option from the navigation bar.
_enableSearchBar = YES;
self.enableBarButtonSearch = NO;
// Create the fake search bar
tableSearchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 600, 44)];
tableSearchBar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
tableSearchBar.showsCancelButton = NO;
tableSearchBar.placeholder = NSLocalizedStringFromTable(@"search_default_placeholder", @"Vector", nil);
tableSearchBar.delegate = self;
// Set itself as delegate by default.
self.delegate = self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.accessibilityIdentifier = @"GroupsVCView";
self.groupsTableView.accessibilityIdentifier = @"GroupsVCTableView";
//Register here the customized cell view class used to render groups
[self.groupsTableView registerNib:GroupTableViewCell.nib forCellReuseIdentifier:GroupTableViewCell.defaultReuseIdentifier];
[self.groupsTableView registerNib:GroupInviteTableViewCell.nib forCellReuseIdentifier:GroupInviteTableViewCell.defaultReuseIdentifier];
// Hide line separators of empty cells
self.groupsTableView.tableFooterView = [[UIView alloc] init];
// Enable self-sizing cells and section headers.
self.groupsTableView.rowHeight = UITableViewAutomaticDimension;
self.groupsTableView.estimatedRowHeight = 74;
self.groupsTableView.sectionHeaderHeight = UITableViewAutomaticDimension;
self.groupsTableView.estimatedSectionHeaderHeight = 30;
self.groupsTableView.estimatedSectionFooterHeight = 0;
// Observe UIApplicationDidEnterBackgroundNotification to refresh bubbles when app leaves the foreground state.
UIApplicationDidEnterBackgroundNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
// Leave potential editing mode
[self cancelEditionMode:isRefreshPending];
}];
self.groupsSearchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;
self.groupsSearchBar.placeholder = NSLocalizedStringFromTable(@"search_default_placeholder", @"Vector", nil);
// @TODO: Add programmatically the (+) button.
//[self addPlusButton];
// Observe user interface theme change.
kRiotDesignValuesDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kRiotDesignValuesDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
[self userInterfaceThemeDidChange];
}];
[self userInterfaceThemeDidChange];
}
- (void)userInterfaceThemeDidChange
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
// Use the primary bg color for the recents table view in plain style.
self.groupsTableView.backgroundColor = kRiotPrimaryBgColor;
topview.backgroundColor = kRiotSecondaryBgColor;
self.view.backgroundColor = kRiotPrimaryBgColor;
tableSearchBar.barStyle = self.groupsSearchBar.barStyle = kRiotDesignSearchBarStyle;
tableSearchBar.tintColor = self.groupsSearchBar.tintColor = kRiotDesignSearchBarTintColor;
if (self.groupsTableView.dataSource)
{
// Force table refresh
[self cancelEditionMode:YES];
}
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
return kRiotDesignStatusBarStyle;
}
- (void)destroy
{
[super destroy];
if (currentRequest)
{
[currentRequest cancel];
currentRequest = nil;
}
if (currentAlert)
{
[currentAlert dismissViewControllerAnimated:NO completion:nil];
currentAlert = nil;
}
if (UIApplicationDidEnterBackgroundNotificationObserver)
{
[[NSNotificationCenter defaultCenter] removeObserver:UIApplicationDidEnterBackgroundNotificationObserver];
UIApplicationDidEnterBackgroundNotificationObserver = nil;
}
if (kRiotDesignValuesDidChangeThemeNotificationObserver)
{
[[NSNotificationCenter defaultCenter] removeObserver:kRiotDesignValuesDidChangeThemeNotificationObserver];
kRiotDesignValuesDidChangeThemeNotificationObserver = nil;
}
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
self.groupsTableView.editing = editing;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Screen tracking
[[AppDelegate theDelegate] trackScreen:@"Groups"];
// Deselect the current selected row, it will be restored on viewDidAppear (if any)
NSIndexPath *indexPath = [self.groupsTableView indexPathForSelectedRow];
if (indexPath)
{
[self.groupsTableView deselectRowAtIndexPath:indexPath animated:NO];
}
// Observe kAppDelegateDidTapStatusBarNotificationObserver.
kAppDelegateDidTapStatusBarNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kAppDelegateDidTapStatusBarNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
[self scrollToTop:YES];
}];
[AppDelegate theDelegate].masterTabBarController.navigationItem.title = NSLocalizedStringFromTable(@"title_groups", @"Vector", nil);
[AppDelegate theDelegate].masterTabBarController.navigationController.navigationBar.tintColor = kRiotColorBlue;
[AppDelegate theDelegate].masterTabBarController.tabBar.tintColor = kRiotColorBlue;
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
// Leave potential editing mode
[self cancelEditionMode:NO];
if (kAppDelegateDidTapStatusBarNotificationObserver)
{
[[NSNotificationCenter defaultCenter] removeObserver:kAppDelegateDidTapStatusBarNotificationObserver];
kAppDelegateDidTapStatusBarNotificationObserver = nil;
}
if ([AppDelegate theDelegate].masterTabBarController.tabBar.tintColor == kRiotColorBlue)
{
// Restore default tintColor
[AppDelegate theDelegate].masterTabBarController.navigationController.navigationBar.tintColor = kRiotColorGreen;
[AppDelegate theDelegate].masterTabBarController.tabBar.tintColor = kRiotColorGreen;
}
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// Release the current selected item (if any) except if the second view controller is still visible.
if (self.splitViewController.isCollapsed)
{
// Release the current selected group (if any).
[[AppDelegate theDelegate].masterTabBarController releaseSelectedItem];
}
else
{
// In case of split view controller where the primary and secondary view controllers are displayed side-by-side onscreen,
// the selected group (if any) is highlighted.
[self refreshCurrentSelectedCell:YES];
}
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
#pragma mark - Override MXKGroupListViewController
- (void)refreshGroupsTable
{
// Refresh the tabBar icon badges
[[AppDelegate theDelegate].masterTabBarController refreshTabBarBadges];
isRefreshPending = NO;
if (editedGroupId)
{
// Check whether the user didn't leave the room
if ([self.dataSource cellIndexPathWithGroupId:editedGroupId])
{
isRefreshPending = YES;
return;
}
else
{
// Cancel the editing mode, a new refresh will be triggered.
[self cancelEditionMode:YES];
return;
}
}
[self.groupsTableView reloadData];
// Check conditions to display the fake search bar into the table header
if (_enableSearchBar && self.groupsSearchBar.isHidden && self.groupsTableView.tableHeaderView == nil)
{
// Add the search bar by hiding it by default.
self.groupsTableView.tableHeaderView = tableSearchBar;
self.groupsTableView.contentOffset = CGPointMake(0, self.groupsTableView.contentOffset.y + tableSearchBar.frame.size.height);
}
if (_shouldScrollToTopOnRefresh)
{
[self scrollToTop:NO];
_shouldScrollToTopOnRefresh = NO;
}
// In case of split view controller where the primary and secondary view controllers are displayed side-by-side on screen,
// the selected group (if any) is updated.
if (!self.splitViewController.isCollapsed)
{
[self refreshCurrentSelectedCell:NO];
}
}
- (void)hideSearchBar:(BOOL)hidden
{
[super hideSearchBar:hidden];
if (!hidden)
{
// Remove the fake table header view if any
self.groupsTableView.tableHeaderView = nil;
self.groupsTableView.contentInset = UIEdgeInsetsZero;
}
}
#pragma mark -
- (void)refreshCurrentSelectedCell:(BOOL)forceVisible
{
// Update here the index of the current selected cell (if any) - Useful in landscape mode with split view controller.
NSIndexPath *currentSelectedCellIndexPath = nil;
MasterTabBarController *masterTabBarController = [AppDelegate theDelegate].masterTabBarController;
if (masterTabBarController.currentGroupDetailViewController)
{
// Look for the rank of this selected group in displayed groups
currentSelectedCellIndexPath = [self.dataSource cellIndexPathWithGroupId:masterTabBarController.selectedGroup.groupId];
}
if (currentSelectedCellIndexPath)
{
// Select the right row
[self.groupsTableView selectRowAtIndexPath:currentSelectedCellIndexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
if (forceVisible)
{
// Scroll table view to make the selected row appear at second position
NSInteger topCellIndexPathRow = currentSelectedCellIndexPath.row ? currentSelectedCellIndexPath.row - 1: currentSelectedCellIndexPath.row;
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:topCellIndexPathRow inSection:currentSelectedCellIndexPath.section];
[self.groupsTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];
}
}
else
{
NSIndexPath *indexPath = [self.groupsTableView indexPathForSelectedRow];
if (indexPath)
{
[self.groupsTableView deselectRowAtIndexPath:indexPath animated:NO];
}
}
}
- (void)cancelEditionMode:(BOOL)forceRefresh
{
if (self.groupsTableView.isEditing || self.isEditing)
{
// Leave editing mode first
isRefreshPending = forceRefresh;
[self setEditing:NO];
}
else if (forceRefresh)
{
// Clean
editedGroupId = nil;
[self refreshGroupsTable];
}
}
#pragma mark - MXKDataSourceDelegate
- (Class<MXKCellRendering>)cellViewClassForCellData:(MXKCellData*)cellData
{
id<MXKGroupCellDataStoring> cellDataStoring = (id<MXKGroupCellDataStoring> )cellData;
if (cellDataStoring.group.membership != MXMembershipInvite)
{
return GroupTableViewCell.class;
}
else
{
return GroupInviteTableViewCell.class;
}
}
- (NSString *)cellReuseIdentifierForCellData:(MXKCellData*)cellData
{
Class class = [self cellViewClassForCellData:cellData];
if ([class respondsToSelector:@selector(defaultReuseIdentifier)])
{
return [class defaultReuseIdentifier];
}
return nil;
}
- (void)dataSource:(MXKDataSource *)dataSource didRecognizeAction:(NSString *)actionIdentifier inCell:(id<MXKCellRendering>)cell userInfo:(NSDictionary *)userInfo
{
// Handle here user actions on groups for Riot app
if ([actionIdentifier isEqualToString:kGroupInviteTableViewCellPreviewButtonPressed])
{
// Retrieve the invited group
MXGroup *invitedGroup = userInfo[kGroupInviteTableViewCellRoomKey];
// Display the room preview
[[AppDelegate theDelegate].masterTabBarController selectGroup:invitedGroup inMatrixSession:self.mainSession];
}
else if ([actionIdentifier isEqualToString:kGroupInviteTableViewCellDeclineButtonPressed])
{
// Retrieve the invited group
MXGroup *invitedGroup = userInfo[kGroupInviteTableViewCellRoomKey];
NSIndexPath *indexPath = [self.dataSource cellIndexPathWithGroupId:invitedGroup.groupId];
if (indexPath)
{
[self.dataSource leaveGroupAtIndexPath:indexPath];
}
}
else
{
// Keep default implementation for other actions if any
if ([super respondsToSelector:@selector(cell:didRecognizeAction:userInfo:)])
{
[super dataSource:dataSource didRecognizeAction:actionIdentifier inCell:cell userInfo:userInfo];
}
}
}
#pragma mark - UITableView delegate
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
{
[super tableView:tableView willDisplayCell:cell forRowAtIndexPath:indexPath];
cell.backgroundColor = kRiotPrimaryBgColor;
// Update the selected background view
if (kRiotSelectedBgColor)
{
cell.selectedBackgroundView = [[UIView alloc] init];
cell.selectedBackgroundView.backgroundColor = kRiotSelectedBgColor;
}
else
{
if (tableView.style == UITableViewStylePlain)
{
cell.selectedBackgroundView = nil;
}
else
{
cell.selectedBackgroundView.backgroundColor = nil;
}
}
}
- (nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
MXKTableViewHeaderFooterWithLabel *sectionHeader;
if (tableView.numberOfSections > 1)
{
sectionHeader = [tableView dequeueReusableHeaderFooterViewWithIdentifier:MXKTableViewHeaderFooterWithLabel.defaultReuseIdentifier];
sectionHeader.mxkContentView.backgroundColor = kRiotSecondaryBgColor;
sectionHeader.mxkLabel.textColor = kRiotPrimaryTextColor;
sectionHeader.mxkLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
NSString* title = [self.dataSource tableView:tableView titleForHeaderInSection:section];
NSUInteger count = [self.dataSource tableView:tableView numberOfRowsInSection:section];
if (count)
{
NSString *roomCount = [NSString stringWithFormat:@" %tu", count];
NSMutableAttributedString *mutableSectionTitle = [[NSMutableAttributedString alloc] initWithString:title
attributes:@{NSForegroundColorAttributeName: kRiotPrimaryTextColor}];
[mutableSectionTitle appendAttributedString:[[NSMutableAttributedString alloc] initWithString:roomCount
attributes:@{NSForegroundColorAttributeName: kRiotAuxiliaryColor}]];
sectionHeader.mxkLabel.attributedText = mutableSectionTitle;
}
else
{
sectionHeader.mxkLabel.text = title;
}
}
return sectionHeader;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [self.groupsTableView cellForRowAtIndexPath:indexPath];
if ([cell isKindOfClass:[GroupInviteTableViewCell class]])
{
// hide the selection
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}
else
{
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
}
}
- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableArray* actions;
// add the swipe to delete only on joined group
if (indexPath.section == self.dataSource.joinedGroupsSection)
{
// Store the identifier of the room related to the edited cell.
id<MXKGroupCellDataStoring> cellData = [self.dataSource cellDataAtIndex:indexPath];
editedGroupId = cellData.group.groupId;
actions = [[NSMutableArray alloc] init];
// Patch: Force the width of the button by adding whitespace characters into the title string.
UITableViewRowAction *leaveAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@" " handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){
[self.dataSource leaveGroupAtIndexPath:indexPath];
}];
leaveAction.backgroundColor = [MXKTools convertImageToPatternColor:@"remove_icon_blue" backgroundColor:kRiotSecondaryBgColor patternSize:CGSizeMake(74, 74) resourceSize:CGSizeMake(24, 24)];
[actions insertObject:leaveAction atIndex:0];
}
return actions;
}
- (void)tableView:(UITableView*)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
[self cancelEditionMode:isRefreshPending];
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[super scrollViewDidScroll:scrollView];
if (scrollView == self.groupsTableView)
{
if (!self.groupsSearchBar.isHidden)
{
if (!self.groupsSearchBar.text.length && (scrollView.contentOffset.y + scrollView.mxk_adjustedContentInset.top > self.groupsSearchBar.frame.size.height))
{
// Hide the search bar
[self hideSearchBar:YES];
// Refresh display
[self refreshGroupsTable];
}
}
}
}
#pragma mark - Room handling
- (void)addPlusButton
{
// Add room options button
plusButtonImageView = [[UIImageView alloc] init];
[plusButtonImageView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:plusButtonImageView];
plusButtonImageView.backgroundColor = [UIColor clearColor];
plusButtonImageView.contentMode = UIViewContentModeCenter;
plusButtonImageView.image = [UIImage imageNamed:@"create_group"];
plusButtonImageView.layer.shadowOpacity = 0.3;
plusButtonImageView.layer.shadowOffset = CGSizeMake(0, 3);
CGFloat side = 78.0f;
NSLayoutConstraint* widthConstraint = [NSLayoutConstraint constraintWithItem:plusButtonImageView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1
constant:side];
NSLayoutConstraint* heightConstraint = [NSLayoutConstraint constraintWithItem:plusButtonImageView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1
constant:side];
NSLayoutConstraint* trailingConstraint = [NSLayoutConstraint constraintWithItem:plusButtonImageView
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeTrailing
multiplier:1
constant:0];
NSLayoutConstraint* bottomConstraint = [NSLayoutConstraint constraintWithItem:self.bottomLayoutGuide
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:plusButtonImageView
attribute:NSLayoutAttributeBottom
multiplier:1
constant:9];
[NSLayoutConstraint activateConstraints:@[widthConstraint, heightConstraint, trailingConstraint, bottomConstraint]];
plusButtonImageView.userInteractionEnabled = YES;
// Handle tap gesture
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onPlusButtonPressed)];
[tap setNumberOfTouchesRequired:1];
[tap setNumberOfTapsRequired:1];
[plusButtonImageView addGestureRecognizer:tap];
}
- (void)onPlusButtonPressed
{
__weak typeof(self) weakSelf = self;
[currentAlert dismissViewControllerAnimated:NO completion:nil];
currentAlert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
// [currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_recents_start_chat_with", @"Vector", nil)
// style:UIAlertActionStyleDefault
// handler:^(UIAlertAction * action) {
//
// if (weakSelf)
// {
// typeof(self) self = weakSelf;
// self->currentAlert = nil;
//
// [self performSegueWithIdentifier:@"presentStartChat" sender:self];
// }
//
// }]];
//
// [currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_recents_create_empty_room", @"Vector", nil)
// style:UIAlertActionStyleDefault
// handler:^(UIAlertAction * action) {
//
// if (weakSelf)
// {
// typeof(self) self = weakSelf;
// self->currentAlert = nil;
//
// [self createAnEmptyRoom];
// }
//
// }]];
//
// [currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_recents_join_room", @"Vector", nil)
// style:UIAlertActionStyleDefault
// handler:^(UIAlertAction * action) {
//
// if (weakSelf)
// {
// typeof(self) self = weakSelf;
// self->currentAlert = nil;
//
// [self joinARoom];
// }
//
// }]];
[currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
}
}]];
[currentAlert popoverPresentationController].sourceView = plusButtonImageView;
[currentAlert popoverPresentationController].sourceRect = plusButtonImageView.bounds;
[currentAlert mxk_setAccessibilityIdentifier:@"GroupsVCCreateRoomAlert"];
[self presentViewController:currentAlert animated:YES completion:nil];
}
//- (void)joinARoom
//{
// [currentAlert dismissViewControllerAnimated:NO completion:nil];
//
// __weak typeof(self) weakSelf = self;
//
// // Prompt the user to type a room id or room alias
// currentAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"room_recents_join_room_title", @"Vector", nil)
// message:NSLocalizedStringFromTable(@"room_recents_join_room_prompt", @"Vector", nil)
// preferredStyle:UIAlertControllerStyleAlert];
//
// [currentAlert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
//
// textField.secureTextEntry = NO;
// textField.placeholder = nil;
// textField.keyboardType = UIKeyboardTypeDefault;
// }];
//
// [currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
// style:UIAlertActionStyleDefault
// handler:^(UIAlertAction * action) {
//
// if (weakSelf)
// {
// typeof(self) self = weakSelf;
// self->currentAlert = nil;
// }
//
// }]];
//
// [currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"join", @"Vector", nil)
// style:UIAlertActionStyleDefault
// handler:^(UIAlertAction * action) {
//
// if (weakSelf)
// {
// typeof(self) self = weakSelf;
//
// UITextField *textField = [self->currentAlert textFields].firstObject;
// NSString *roomAliasOrId = textField.text;
//
// self->currentAlert = nil;
//
// [self.activityIndicator startAnimating];
//
// self->currentRequest = [self.mainSession joinRoom:textField.text success:^(MXRoom *room) {
//
// self->currentRequest = nil;
// [self.activityIndicator stopAnimating];
//
// // Show the room
// [[AppDelegate theDelegate] showRoom:room.state.roomId andEventId:nil withMatrixSession:self.mainSession];
//
// } failure:^(NSError *error) {
//
// NSLog(@"[RecentsViewController] Join joinARoom (%@) failed", roomAliasOrId);
//
// self->currentRequest = nil;
// [self.activityIndicator stopAnimating];
//
// // Alert user
// [[AppDelegate theDelegate] showErrorAsAlert:error];
// }];
// }
//
// }]];
//
// [currentAlert mxk_setAccessibilityIdentifier:@"RecentsVCJoinARoomAlert"];
// [self presentViewController:currentAlert animated:YES completion:nil];
//}
#pragma mark - Table view scrolling
- (void)scrollToTop:(BOOL)animated
{
[self.groupsTableView setContentOffset:CGPointMake(-self.groupsTableView.mxk_adjustedContentInset.left, -self.groupsTableView.mxk_adjustedContentInset.top) animated:animated];
}
#pragma mark - MXKGroupListViewControllerDelegate
- (void)groupListViewController:(MXKGroupListViewController *)groupListViewController didSelectGroup:(MXGroup *)group inMatrixSession:(MXSession *)mxSession
{
// Open the room
[[AppDelegate theDelegate].masterTabBarController selectGroup:group inMatrixSession:mxSession];
}
#pragma mark - UISearchBarDelegate
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
if (searchBar == tableSearchBar)
{
[self hideSearchBar:NO];
[self.groupsSearchBar becomeFirstResponder];
return NO;
}
return YES;
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
dispatch_async(dispatch_get_main_queue(), ^{
[self.groupsSearchBar setShowsCancelButton:YES animated:NO];
});
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
[self.groupsSearchBar setShowsCancelButton:NO animated:NO];
}
@end