Structure project almost by features. Start by organizing view controllers.

This commit is contained in:
SBiOSoftWhare
2018-07-05 18:51:58 +02:00
parent f26e845a13
commit fb58bbc651
119 changed files with 776 additions and 404 deletions
@@ -0,0 +1,22 @@
/*
Copyright 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import <MatrixKit/MatrixKit.h>
@interface AttachmentsViewController : MXKAttachmentsViewController
@end
@@ -0,0 +1,90 @@
/*
Copyright 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import "AttachmentsViewController.h"
#import "AppDelegate.h"
@interface AttachmentsViewController ()
{
// Observe kRiotDesignValuesDidChangeThemeNotification to handle user interface theme change.
id kRiotDesignValuesDidChangeThemeNotificationObserver;
}
@end
@implementation AttachmentsViewController
#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.
self.attachmentsCollection.accessibilityIdentifier =@"AttachmentsVC";
// 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.view.backgroundColor = kRiotPrimaryBgColor;
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
self.navigationBar.tintColor = kRiotSecondaryBgColor;
self.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName: kRiotPrimaryTextColor};
self.backButton.tintColor = kRiotColorGreen;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Screen tracking
[[Analytics sharedInstance] trackScreen:@"AttachmentsViewer"];
}
- (void)destroy
{
[super destroy];
if (kRiotDesignValuesDidChangeThemeNotificationObserver)
{
[[NSNotificationCenter defaultCenter] removeObserver:kRiotDesignValuesDidChangeThemeNotificationObserver];
kRiotDesignValuesDidChangeThemeNotificationObserver = nil;
}
}
@end
@@ -0,0 +1,24 @@
/*
Copyright 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import <MatrixKit/MatrixKit.h>
/**
This view controller displays the attachments of a room. Only one matrix session is handled by this view controller.
*/
@interface RoomFilesViewController : MXKRoomViewController
@end
@@ -0,0 +1,227 @@
/*
Copyright 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import "RoomFilesViewController.h"
#import "FilesSearchTableViewCell.h"
#import "AppDelegate.h"
#import "AttachmentsViewController.h"
@interface RoomFilesViewController ()
{
/**
Observe kRiotDesignValuesDidChangeThemeNotification to handle user interface theme change.
*/
id kRiotDesignValuesDidChangeThemeNotificationObserver;
}
@end
@implementation RoomFilesViewController
#pragma mark -
- (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
self.autoJoinInvitedRoom = NO;
}
return self;
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
self.autoJoinInvitedRoom = NO;
}
return self;
}
#pragma mark -
- (void)finalizeInit
{
[super finalizeInit];
// Setup `MXKViewControllerHandling` properties
self.enableBarTintColorStatusChange = NO;
self.rageShakeManager = [RageShakeManager sharedManager];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do not show toolbar
[self setRoomInputToolbarViewClass:nil];
// set the default extra
[self setRoomActivitiesViewClass:nil];
// Custom the attachmnet viewer
[self setAttachmentsViewerClass:AttachmentsViewController.class];
// Register first customized cell view classes used to render bubbles
[self.bubblesTableView registerClass:FilesSearchTableViewCell.class forCellReuseIdentifier:FilesSearchTableViewCell.defaultReuseIdentifier];
self.bubblesTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
// Hide line separators of empty cells
self.bubblesTableView.tableFooterView = [[UIView alloc] init];
[self setNavBarButtons];
// Update the inputToolBar height (This will trigger a layout refresh)
[UIView setAnimationsEnabled:NO];
[self roomInputToolbarView:self.inputToolbarView heightDidChanged:0 completion:nil];
[UIView setAnimationsEnabled: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;
// Check the table view style to select its bg color.
self.bubblesTableView.backgroundColor = ((self.bubblesTableView.style == UITableViewStylePlain) ? kRiotPrimaryBgColor : kRiotSecondaryBgColor);
self.view.backgroundColor = self.bubblesTableView.backgroundColor;
if (self.bubblesTableView.dataSource)
{
[self.bubblesTableView reloadData];
}
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
return kRiotDesignStatusBarStyle;
}
- (void)destroy
{
[super destroy];
if (kRiotDesignValuesDidChangeThemeNotificationObserver)
{
[[NSNotificationCenter defaultCenter] removeObserver:kRiotDesignValuesDidChangeThemeNotificationObserver];
kRiotDesignValuesDidChangeThemeNotificationObserver = nil;
}
}
// This method is called when the viewcontroller is added or removed from a container view controller.
- (void)didMoveToParentViewController:(nullable UIViewController *)parent
{
[super didMoveToParentViewController:parent];
[self setNavBarButtons];
}
- (void)setNavBarButtons
{
// Check whether the view controller is currently displayed inside a segmented view controller or not.
UIViewController* topViewController = ((self.parentViewController) ? self.parentViewController : self);
topViewController.navigationItem.rightBarButtonItem = nil;
topViewController.navigationItem.leftBarButtonItem = nil;
}
#pragma mark - MXKDataSourceDelegate
- (Class<MXKCellRendering>)cellViewClassForCellData:(MXKCellData*)cellData
{
Class cellViewClass = nil;
// Sanity check
if ([cellData conformsToProtocol:@protocol(MXKRoomBubbleCellDataStoring)])
{
id<MXKRoomBubbleCellDataStoring> bubbleData = (id<MXKRoomBubbleCellDataStoring>)cellData;
// Select the suitable table view cell class
if (bubbleData.attachment)
{
cellViewClass = FilesSearchTableViewCell.class;
}
}
return cellViewClass;
}
- (NSString *)cellReuseIdentifierForCellData:(MXKCellData*)cellData
{
Class class = [self cellViewClassForCellData:cellData];
if ([class respondsToSelector:@selector(defaultReuseIdentifier)])
{
return [class defaultReuseIdentifier];
}
return nil;
}
#pragma mark - UITableView delegate
- (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;
}
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.bubblesTableView)
{
UITableViewCell *cell = [self.bubblesTableView cellForRowAtIndexPath:indexPath];
[self showAttachmentInCell:cell];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
}
@end
@@ -0,0 +1,35 @@
/*
Copyright 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import <MatrixKit/MatrixKit.h>
#import "DeviceTableViewCell.h"
@interface RoomMemberDetailsViewController : MXKRoomMemberDetailsViewController <UIGestureRecognizerDelegate, DeviceTableViewCellDelegate>
@property (weak, nonatomic) IBOutlet UIView *roomMemberAvatarHeaderBackground;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *roomMemberAvatarHeaderBackgroundHeightConstraint;
@property (weak, nonatomic) IBOutlet UIView *memberHeaderView;
@property (weak, nonatomic) IBOutlet UIView *roomMemberAvatarMask;
@property (weak, nonatomic) IBOutlet UILabel *roomMemberNameLabel;
@property (weak, nonatomic) IBOutlet UIView *roomMemberNameLabelMask;
@property (weak, nonatomic) IBOutlet UILabel *roomMemberStatusLabel;
@property (weak, nonatomic) IBOutlet UIImageView *bottomImageView;
@end
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,165 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13196" 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="13173"/>
<capability name="Aspect ratio constraints" 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="RoomMemberDetailsViewController">
<connections>
<outlet property="bottomImageView" destination="7Dc-jk-9sT" id="BVN-bt-VXI"/>
<outlet property="memberHeaderView" destination="YXr-As-Mqh" id="Eqb-qr-iAo"/>
<outlet property="memberThumbnail" destination="GQ1-rP-ckr" id="abr-hr-C3p"/>
<outlet property="roomMemberAvatarHeaderBackground" destination="ouj-VM-zdT" id="YeD-zt-8y5"/>
<outlet property="roomMemberAvatarHeaderBackgroundHeightConstraint" destination="dBL-G6-Yec" id="QXZ-ZP-0Rn"/>
<outlet property="roomMemberAvatarMask" destination="MAS-3M-3cg" id="nLI-7d-5Hu"/>
<outlet property="roomMemberNameLabel" destination="92g-hC-6jB" id="gcP-wz-8FT"/>
<outlet property="roomMemberNameLabelMask" destination="wEo-Mk-SgZ" id="uEv-LU-eEI"/>
<outlet property="roomMemberStatusLabel" destination="5le-5e-Vml" id="ODo-tG-ewy"/>
<outlet property="tableView" destination="R6u-PR-DcU" id="Cm1-1y-meQ"/>
<outlet property="view" destination="gX8-mM-6Ig" id="R3w-s7-1CY"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="gX8-mM-6Ig">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="YXr-As-Mqh">
<rect key="frame" x="0.0" y="0.0" width="375" height="192"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ouj-VM-zdT">
<rect key="frame" x="0.0" y="0.0" width="375" height="117"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="RoomMemberDetailsVCAvatarHeaderBackground"/>
<constraints>
<constraint firstAttribute="height" constant="117" id="dBL-G6-Yec"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="MAS-3M-3cg">
<rect key="frame" x="137.5" y="0.0" width="100" height="125"/>
<subviews>
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="GQ1-rP-ckr" customClass="MXKImageView">
<rect key="frame" x="7.5" y="31" width="84" height="84"/>
<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" constant="84" id="HfP-Pj-zLa"/>
<constraint firstAttribute="width" secondItem="GQ1-rP-ckr" secondAttribute="height" multiplier="1:1" id="a1T-Y0-Iic"/>
</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="RoomMemberDetailsVCAvatarMask"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="GQ1-rP-ckr" secondAttribute="bottom" constant="10" id="3pC-So-WvO"/>
<constraint firstItem="GQ1-rP-ckr" firstAttribute="centerX" secondItem="MAS-3M-3cg" secondAttribute="centerX" id="ZGI-nR-gGx"/>
<constraint firstAttribute="width" constant="100" id="fwv-qE-IV1"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="92g-hC-6jB">
<rect key="frame" x="165" y="125" width="45" height="21"/>
<accessibility key="accessibilityConfiguration" identifier="RoomMemberDetailsVCNameLabel"/>
<constraints>
<constraint firstAttribute="height" constant="21" id="WyU-2u-Lek"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="18"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5le-5e-Vml">
<rect key="frame" x="168" y="153" width="39" height="21"/>
<accessibility key="accessibilityConfiguration" identifier="RoomMemberDetailsVCStatusLabel"/>
<constraints>
<constraint firstAttribute="height" constant="21" id="7lY-ku-cPk"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="15"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wEo-Mk-SgZ">
<rect key="frame" x="0.0" y="119" width="375" height="33"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="RoomMemberDetailsVCNameLabelMask"/>
<constraints>
<constraint firstAttribute="height" constant="33" id="qhK-10-7AW"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="RoomMemberDetailsVCHeaderView"/>
<constraints>
<constraint firstItem="wEo-Mk-SgZ" firstAttribute="centerY" secondItem="92g-hC-6jB" secondAttribute="centerY" id="3Zt-MD-sZK"/>
<constraint firstItem="5le-5e-Vml" firstAttribute="top" secondItem="92g-hC-6jB" secondAttribute="bottom" constant="7" id="5zX-1T-n38"/>
<constraint firstItem="92g-hC-6jB" firstAttribute="centerX" secondItem="YXr-As-Mqh" secondAttribute="centerX" id="7Is-d0-FZp"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="92g-hC-6jB" secondAttribute="trailing" constant="32" id="Eyx-UF-fYc"/>
<constraint firstAttribute="trailing" secondItem="ouj-VM-zdT" secondAttribute="trailing" id="FRy-TL-gS2"/>
<constraint firstItem="wEo-Mk-SgZ" firstAttribute="centerX" secondItem="92g-hC-6jB" secondAttribute="centerX" id="K1f-RX-kpp"/>
<constraint firstItem="wEo-Mk-SgZ" firstAttribute="width" secondItem="YXr-As-Mqh" secondAttribute="width" id="P5e-q6-OIS"/>
<constraint firstItem="92g-hC-6jB" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="YXr-As-Mqh" secondAttribute="leading" constant="32" id="QZB-ue-Sih"/>
<constraint firstItem="5le-5e-Vml" firstAttribute="centerX" secondItem="YXr-As-Mqh" secondAttribute="centerX" id="bmA-Fq-uxO"/>
<constraint firstItem="5le-5e-Vml" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="YXr-As-Mqh" secondAttribute="leading" constant="42" id="ioz-jk-jrE"/>
<constraint firstAttribute="bottom" secondItem="5le-5e-Vml" secondAttribute="bottom" constant="18" id="j10-rX-tMf"/>
<constraint firstItem="MAS-3M-3cg" firstAttribute="top" secondItem="YXr-As-Mqh" secondAttribute="top" id="jJp-cP-Vgp"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="5le-5e-Vml" secondAttribute="trailing" constant="42" id="mad-qx-tHe"/>
<constraint firstItem="92g-hC-6jB" firstAttribute="top" secondItem="ouj-VM-zdT" secondAttribute="bottom" constant="8" id="rKl-Gw-ajI"/>
<constraint firstItem="ouj-VM-zdT" firstAttribute="leading" secondItem="YXr-As-Mqh" secondAttribute="leading" id="rWQ-Ru-7Ej"/>
<constraint firstItem="MAS-3M-3cg" firstAttribute="bottom" secondItem="92g-hC-6jB" secondAttribute="top" id="rgU-C1-YMW"/>
<constraint firstItem="ouj-VM-zdT" firstAttribute="top" secondItem="YXr-As-Mqh" secondAttribute="top" id="srY-tD-AhJ"/>
<constraint firstItem="MAS-3M-3cg" firstAttribute="centerX" secondItem="YXr-As-Mqh" secondAttribute="centerX" id="vNM-7Z-K2b"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="RBF-EK-dhz">
<rect key="frame" x="0.0" y="317" width="375" height="33"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="33" id="40l-B3-pDk"/>
</constraints>
</view>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="group.png" translatesAutoresizingMaskIntoConstraints="NO" id="7Dc-jk-9sT">
<rect key="frame" x="0.0" y="469" width="375" height="198"/>
<accessibility key="accessibilityConfiguration" identifier="RoomMemberDetailsVCBottomImageView"/>
<constraints>
<constraint firstAttribute="height" constant="198" id="bkF-2R-F6Q"/>
</constraints>
</imageView>
<tableView clipsSubviews="YES" contentMode="scaleToFill" style="grouped" separatorStyle="default" rowHeight="46" sectionHeaderHeight="28" sectionFooterHeight="8" translatesAutoresizingMaskIntoConstraints="NO" id="R6u-PR-DcU">
<rect key="frame" x="0.0" y="192" width="375" height="475"/>
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="accessibilityIdentifier" value="RoomMemberDetailsVCTableView"/>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="dataSource" destination="-1" id="DbO-MV-3hm"/>
<outlet property="delegate" destination="-1" id="dFh-bI-jUW"/>
</connections>
</tableView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="RoomMemberDetailsVC"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="7Dc-jk-9sT" secondAttribute="trailing" id="3C8-er-hQ7"/>
<constraint firstAttribute="trailing" secondItem="YXr-As-Mqh" secondAttribute="trailing" id="3DV-SV-Ifa"/>
<constraint firstItem="YXr-As-Mqh" firstAttribute="leading" secondItem="gX8-mM-6Ig" secondAttribute="leading" id="EbV-lF-mAx"/>
<constraint firstItem="RBF-EK-dhz" firstAttribute="centerY" secondItem="gX8-mM-6Ig" secondAttribute="centerY" id="PO0-bP-cQ5"/>
<constraint firstItem="RBF-EK-dhz" firstAttribute="trailing" secondItem="7Dc-jk-9sT" secondAttribute="trailing" id="RTr-1M-aeU"/>
<constraint firstItem="R6u-PR-DcU" firstAttribute="top" secondItem="YXr-As-Mqh" secondAttribute="bottom" id="VW4-0P-ALX"/>
<constraint firstAttribute="bottom" secondItem="R6u-PR-DcU" secondAttribute="bottom" id="X1a-xq-1Aa"/>
<constraint firstAttribute="trailing" secondItem="R6u-PR-DcU" secondAttribute="trailing" id="aMA-vf-GrY"/>
<constraint firstItem="RBF-EK-dhz" firstAttribute="leading" secondItem="7Dc-jk-9sT" secondAttribute="leading" id="dHb-9z-eww"/>
<constraint firstItem="YXr-As-Mqh" firstAttribute="top" secondItem="gX8-mM-6Ig" secondAttribute="top" id="l7z-od-LJm"/>
<constraint firstItem="7Dc-jk-9sT" firstAttribute="leading" secondItem="gX8-mM-6Ig" secondAttribute="leading" id="rNt-rC-Pxv"/>
<constraint firstItem="R6u-PR-DcU" firstAttribute="leading" secondItem="gX8-mM-6Ig" secondAttribute="leading" id="rbT-O1-m3d"/>
<constraint firstAttribute="bottom" secondItem="7Dc-jk-9sT" secondAttribute="bottom" id="yKK-K2-ebi"/>
</constraints>
</view>
</objects>
<resources>
<image name="group.png" width="375" height="198"/>
</resources>
</document>
@@ -0,0 +1,110 @@
/*
Copyright 2015 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import "SegmentedViewController.h"
#import "ContactsTableViewController.h"
@class Contact;
@class RoomParticipantsViewController;
/**
`RoomParticipantsViewController` delegate.
*/
@protocol RoomParticipantsViewControllerDelegate <NSObject>
/**
Tells the delegate that the user wants to mention a room member.
@discussion the `RoomParticipantsViewController` instance is withdrawn automatically.
@param roomParticipantsViewController the `RoomParticipantsViewController` instance.
@param member the room member to mention.
*/
- (void)roomParticipantsViewController:(RoomParticipantsViewController *)roomParticipantsViewController mention:(MXRoomMember*)member;
@end
/**
'RoomParticipantsViewController' instance is used to edit members of the room defined by the property 'mxRoom'.
When this property is nil, the view controller is empty.
*/
@interface RoomParticipantsViewController : MXKViewController <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UIGestureRecognizerDelegate, MXKRoomMemberDetailsViewControllerDelegate, 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;
/**
The contact used to describe the current user (nil if the user is not a participant of the room).
*/
Contact *userParticipant;
}
@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 room (nil by default).
*/
@property (nonatomic) MXRoom *mxRoom;
/**
Enable mention option in member details view. NO by default
*/
@property (nonatomic) BOOL enableMention;
/**
The delegate for the view controller.
*/
@property (nonatomic) id<RoomParticipantsViewControllerDelegate> delegate;
/**
Returns the `UINib` object initialized for a `RoomParticipantsViewController`.
@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 `RoomParticipantsViewController` object.
@discussion This is the designated initializer for programmatic instantiation.
@return An initialized `RoomParticipantsViewController` object if successful, `nil` otherwise.
*/
+ (instancetype)roomParticipantsViewController;
@end
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16F73" 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="12089"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="RoomParticipantsViewController">
<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>
@@ -0,0 +1,24 @@
/*
Copyright 2017 Aram Sargsyan
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 <UIKit/UIKit.h>
#import <MatrixKit/MatrixKit.h>
@interface ReadReceiptsViewController : MXKViewController
+ (void)openInViewController:(UIViewController *)viewController fromContainer:(MXKReceiptSendersContainer *)receiptSendersContainer withSession:(MXSession *)session;
@end
@@ -0,0 +1,268 @@
/*
Copyright 2017 Aram Sargsyan
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 "ReadReceiptsViewController.h"
#import <MatrixKit/MatrixKit.h>
#import "RageShakeManager.h"
#import "RiotDesignValues.h"
@interface ReadReceiptsViewController () <UITableViewDataSource, UITableViewDelegate>
{
// Observe kRiotDesignValuesDidChangeThemeNotification to handle user interface theme change.
id kRiotDesignValuesDidChangeThemeNotificationObserver;
}
@property (nonatomic) MXRestClient* restClient;
@property (nonatomic) MXSession *session;
@property (nonatomic) NSArray <MXRoomMember *> *roomMembers;
@property (nonatomic) NSArray <UIImage *> *placeholders;
@property (nonatomic) NSArray <MXReceiptData *> *receipts;
@property (weak, nonatomic) IBOutlet UIView *overlayView;
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UIView *containerView;
@property (weak, nonatomic) IBOutlet UITableView *receiptsTableView;
@property (weak, nonatomic) IBOutlet UIButton *closeButton;
@end
@implementation ReadReceiptsViewController
#pragma mark - Public
+ (void)openInViewController:(UIViewController *)viewController fromContainer:(MXKReceiptSendersContainer *)receiptSendersContainer withSession:(MXSession *)session
{
ReadReceiptsViewController *receiptsController = [[[self class] alloc] initWithNibName:NSStringFromClass([self class]) bundle:nil];
receiptsController.restClient = receiptSendersContainer.restClient;
receiptsController.session = session;
receiptsController.roomMembers = receiptSendersContainer.roomMembers;
receiptsController.placeholders = receiptSendersContainer.placeholders;
receiptsController.receipts = receiptSendersContainer.readReceipts;
receiptsController.providesPresentationContextTransitionStyle = YES;
receiptsController.definesPresentationContext = YES;
receiptsController.modalPresentationStyle = UIModalPresentationOverFullScreen;
receiptsController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[viewController presentViewController:receiptsController animated:YES completion:nil];
}
#pragma mark - Lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Setup `MXKViewControllerHandling` properties
self.enableBarTintColorStatusChange = NO;
self.rageShakeManager = [RageShakeManager sharedManager];
[self configureViews];
[self configureReceiptsTableView];
[self addOverlayViewGesture];
// Observe user interface theme change.
kRiotDesignValuesDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kRiotDesignValuesDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
[self userInterfaceThemeDidChange];
}];
[self userInterfaceThemeDidChange];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)userInterfaceThemeDidChange
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
self.overlayView.backgroundColor = kRiotOverlayColor;
self.overlayView.alpha = 1.0;
self.titleLabel.textColor = kRiotPrimaryTextColor;
self.containerView.backgroundColor = kRiotPrimaryBgColor;
// Check the table view style to select its bg color.
self.receiptsTableView.backgroundColor = ((self.receiptsTableView.style == UITableViewStylePlain) ? kRiotPrimaryBgColor : kRiotSecondaryBgColor);
self.closeButton.tintColor = kRiotColorGreen;
if (self.receiptsTableView.dataSource)
{
// Force table refresh
[self.receiptsTableView reloadData];
}
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
return kRiotDesignStatusBarStyle;
}
- (void)destroy
{
if (kRiotDesignValuesDidChangeThemeNotificationObserver)
{
[[NSNotificationCenter defaultCenter] removeObserver:kRiotDesignValuesDidChangeThemeNotificationObserver];
kRiotDesignValuesDidChangeThemeNotificationObserver = nil;
}
[super destroy];
}
- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
{
[super dismissViewControllerAnimated:flag completion:completion];
[self destroy];
}
#pragma mark - Views
- (void)configureViews
{
self.containerView.layer.cornerRadius = 20;
self.titleLabel.text = NSLocalizedStringFromTable(@"read_receipts_list", @"Vector", nil);
[_closeButton setTitle:[NSBundle mxk_localizedStringForKey:@"close"] forState:UIControlStateNormal];
[_closeButton setTitle:[NSBundle mxk_localizedStringForKey:@"close"] forState:UIControlStateHighlighted];
}
- (void)configureReceiptsTableView
{
self.receiptsTableView.dataSource = self;
self.receiptsTableView.delegate = self;
self.receiptsTableView.showsVerticalScrollIndicator = NO;
self.receiptsTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.receiptsTableView registerNib:[MXKReadReceiptTableViewCell nib] forCellReuseIdentifier:[MXKReadReceiptTableViewCell defaultReuseIdentifier]];
}
- (void)addOverlayViewGesture
{
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(overlayTap)];
[tapRecognizer setNumberOfTapsRequired:1];
[tapRecognizer setNumberOfTouchesRequired:1];
[self.overlayView addGestureRecognizer:tapRecognizer];
}
#pragma mark - Actions
- (void)overlayTap
{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)onCloseButtonPress:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.roomMembers.count;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MXKReadReceiptTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[MXKReadReceiptTableViewCell defaultReuseIdentifier] forIndexPath:indexPath];
cell.displayNameLabel.textColor = kRiotPrimaryTextColor;
cell.receiptDescriptionLabel.textColor = kRiotSecondaryTextColor;
if (indexPath.row < self.roomMembers.count)
{
NSString *name = self.roomMembers[indexPath.row].displayname;
if (name.length == 0) {
name = self.roomMembers[indexPath.row].userId;
}
cell.displayNameLabel.text = name;
}
if (indexPath.row < self.placeholders.count)
{
NSString *avatarUrl = self.roomMembers[indexPath.row].avatarUrl;
if (self.restClient && avatarUrl)
{
CGFloat side = CGRectGetWidth(cell.avatarImageView.frame);
avatarUrl = [self.restClient urlOfContentThumbnail:avatarUrl toFitViewSize:CGSizeMake(side, side) withMethod:MXThumbnailingMethodCrop];
}
[cell.avatarImageView setImageURL:avatarUrl withType:nil andImageOrientation:UIImageOrientationUp previewImage:self.placeholders[indexPath.row]];
}
if (indexPath.row < self.receipts.count)
{
NSString *receiptReadText = NSLocalizedStringFromTable(@"receipt_status_read", @"Vector", nil);
NSString *receiptTimeText = [(MXKEventFormatter*)self.session.roomSummaryUpdateDelegate dateStringFromTimestamp:self.receipts[indexPath.row].ts withTime:YES];
NSMutableAttributedString *receiptDescription = [[NSMutableAttributedString alloc] initWithString:receiptReadText attributes:@{NSForegroundColorAttributeName : kRiotSecondaryTextColor, NSFontAttributeName : [UIFont boldSystemFontOfSize:15]}];
[receiptDescription appendAttributedString:[[NSAttributedString alloc] initWithString:receiptTimeText attributes:@{NSForegroundColorAttributeName : kRiotSecondaryTextColor, NSFontAttributeName : [UIFont systemFontOfSize:15]}]];
cell.receiptDescriptionLabel.attributedText = receiptDescription;
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
#pragma mark - UITableViewDelegate
- (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;
}
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 70;
}
@end
@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16F73" 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="12089"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ReadReceiptsViewController">
<connections>
<outlet property="closeButton" destination="np9-sm-bvz" id="6Na-H8-nmE"/>
<outlet property="containerView" destination="kg4-Yk-K6b" id="DNS-mH-6HR"/>
<outlet property="overlayView" destination="41Z-5b-umc" id="gpj-Ux-mhK"/>
<outlet property="receiptsTableView" destination="9qg-nd-kFU" id="ZWb-Hn-hIe"/>
<outlet property="titleLabel" destination="jsl-CT-BFF" id="7co-HF-mWI"/>
<outlet property="view" destination="iN0-l3-epB" id="bVY-jN-77v"/>
</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 alpha="0.5" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="41Z-5b-umc" userLabel="Overlay View">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
</view>
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kg4-Yk-K6b" userLabel="Master Container View">
<rect key="frame" x="10" y="58.5" width="355" height="550"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="YD2-h3-4xX" userLabel="Title Container View">
<rect key="frame" x="0.0" y="0.0" width="355" height="40"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jsl-CT-BFF" userLabel="Title Label">
<rect key="frame" x="156.5" y="10" width="41.5" height="19.5"/>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="jsl-CT-BFF" firstAttribute="centerY" secondItem="YD2-h3-4xX" secondAttribute="centerY" id="3nq-G3-rhK"/>
<constraint firstItem="jsl-CT-BFF" firstAttribute="centerX" secondItem="YD2-h3-4xX" secondAttribute="centerX" id="YfA-8b-6PG"/>
<constraint firstAttribute="height" constant="40" id="vYa-wu-b0l"/>
</constraints>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="9qg-nd-kFU">
<rect key="frame" x="0.0" y="40" width="355" height="460"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</tableView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="np9-sm-bvz">
<rect key="frame" x="296" y="510" width="39" height="30"/>
<state key="normal" title="Close"/>
<connections>
<action selector="onCloseButtonPress:" destination="-1" eventType="touchUpInside" id="3LU-e2-3qZ"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="9qg-nd-kFU" secondAttribute="bottom" constant="50" id="9tH-uU-nTl"/>
<constraint firstAttribute="trailing" secondItem="9qg-nd-kFU" secondAttribute="trailing" id="MLa-NR-q4z"/>
<constraint firstItem="YD2-h3-4xX" firstAttribute="leading" secondItem="kg4-Yk-K6b" secondAttribute="leading" id="X5O-8F-CyO"/>
<constraint firstAttribute="trailing" secondItem="YD2-h3-4xX" secondAttribute="trailing" id="aUL-jB-exK"/>
<constraint firstItem="YD2-h3-4xX" firstAttribute="top" secondItem="kg4-Yk-K6b" secondAttribute="top" id="aUc-NR-Suw"/>
<constraint firstAttribute="bottom" secondItem="np9-sm-bvz" secondAttribute="bottom" constant="10" id="fYr-Lb-UtL"/>
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="550" id="j5U-sf-HMF"/>
<constraint firstItem="9qg-nd-kFU" firstAttribute="leading" secondItem="kg4-Yk-K6b" secondAttribute="leading" id="p5C-BH-56n"/>
<constraint firstAttribute="trailing" secondItem="np9-sm-bvz" secondAttribute="trailing" constant="20" symbolic="YES" id="pEK-YF-c4b"/>
<constraint firstItem="9qg-nd-kFU" firstAttribute="top" secondItem="YD2-h3-4xX" secondAttribute="bottom" id="thD-Si-NzK"/>
<constraint firstAttribute="height" relation="lessThanOrEqual" constant="550" id="wln-eD-ner"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="41Z-5b-umc" secondAttribute="bottom" id="2qB-lj-z6b"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="kg4-Yk-K6b" secondAttribute="trailing" constant="10" id="96x-1M-6KX"/>
<constraint firstItem="41Z-5b-umc" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="CoG-Nf-HX8"/>
<constraint firstItem="kg4-Yk-K6b" firstAttribute="top" relation="greaterThanOrEqual" secondItem="iN0-l3-epB" secondAttribute="top" constant="40" id="ERj-JN-Ljg"/>
<constraint firstItem="kg4-Yk-K6b" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="M3i-yJ-w5M"/>
<constraint firstAttribute="trailing" secondItem="41Z-5b-umc" secondAttribute="trailing" id="USj-F9-gZi"/>
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="kg4-Yk-K6b" secondAttribute="bottom" constant="10" id="Xl6-6H-Rb6"/>
<constraint firstItem="kg4-Yk-K6b" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" priority="750" constant="40" id="Zmw-aZ-NHG"/>
<constraint firstAttribute="bottom" secondItem="kg4-Yk-K6b" secondAttribute="bottom" priority="750" constant="10" id="hTL-dj-W5I"/>
<constraint firstItem="kg4-Yk-K6b" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="hgX-JU-Hm1"/>
<constraint firstAttribute="trailing" secondItem="kg4-Yk-K6b" secondAttribute="trailing" priority="750" constant="10" id="lJU-iL-6th"/>
<constraint firstItem="kg4-Yk-K6b" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="qYN-Lz-Uvz"/>
<constraint firstItem="kg4-Yk-K6b" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" priority="750" constant="10" id="xg1-8A-kJZ"/>
<constraint firstItem="41Z-5b-umc" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="z6e-1g-MG7"/>
</constraints>
</view>
</objects>
</document>
+81
View File
@@ -0,0 +1,81 @@
/*
Copyright 2014 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import <MatrixKit/MatrixKit.h>
#import "RoomTitleView.h"
#import "RoomPreviewData.h"
#import "RoomParticipantsViewController.h"
#import "ContactsTableViewController.h"
#import "UIViewController+RiotSearch.h"
@interface RoomViewController : MXKRoomViewController <UISearchBarDelegate, UIGestureRecognizerDelegate, RoomTitleViewTapGestureDelegate, RoomParticipantsViewControllerDelegate, MXKRoomMemberDetailsViewControllerDelegate, ContactsTableViewControllerDelegate>
// The expanded header
@property (weak, nonatomic) IBOutlet UIView *expandedHeaderContainer;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *expandedHeaderContainerHeightConstraint;
// The preview header
@property (weak, nonatomic) IBOutlet UIView *previewHeaderContainer;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *previewHeaderContainerHeightConstraint;
// The jump to last unread banner
@property (weak, nonatomic) IBOutlet UIView *jumpToLastUnreadBannerContainer;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *jumpToLastUnreadBannerContainerTopConstraint;
@property (weak, nonatomic) IBOutlet UIButton *jumpToLastUnreadButton;
@property (weak, nonatomic) IBOutlet UILabel *jumpToLastUnreadLabel;
@property (weak, nonatomic) IBOutlet UIButton *resetReadMarkerButton;
/**
Force the display of the expanded header.
The default value is NO: this expanded header is hidden on new instantiated RoomViewController object.
When this property is YES, the expanded header is forced each time the view controller appears.
*/
@property (nonatomic) BOOL showExpandedHeader;
/**
Preview data for a room invitation received by email, or a link to a room.
*/
@property (nonatomic, readonly) RoomPreviewData *roomPreviewData;
/**
Tell whether a badge must be added next to the chevron (back button) showing number of unread rooms.
YES by default.
*/
@property (nonatomic) BOOL showMissedDiscussionsBadge;
/**
Display the preview of a room that is unknown for the user.
This room can come from an email invitation link or a simple link to a room.
@param roomPreviewData the data for the room preview.
*/
- (void)displayRoomPreview:(RoomPreviewData*)roomPreviewData;
/**
Action used to handle some buttons.
*/
- (IBAction)onButtonPressed:(id)sender;
@end
File diff suppressed because it is too large Load Diff
+180
View File
@@ -0,0 +1,180 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16F73" 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="12089"/>
<capability name="Aspect ratio constraints" 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="RoomViewController">
<connections>
<outlet property="bubblesTableView" destination="BGD-sd-SQR" id="OG4-Tw-Ovt"/>
<outlet property="bubblesTableViewBottomConstraint" destination="Ksk-39-kfi" id="CTo-Ux-4NP"/>
<outlet property="bubblesTableViewTopConstraint" destination="X14-4s-uGM" id="Hic-6h-N05"/>
<outlet property="expandedHeaderContainer" destination="uK2-9a-rZj" id="0lY-NB-cR1"/>
<outlet property="expandedHeaderContainerHeightConstraint" destination="w9z-HS-7wJ" id="6uK-Bn-TcU"/>
<outlet property="jumpToLastUnreadBannerContainer" destination="S6r-bo-jxw" id="Ady-Eh-4E0"/>
<outlet property="jumpToLastUnreadBannerContainerTopConstraint" destination="xYa-gT-4x0" id="jnh-3C-bQB"/>
<outlet property="jumpToLastUnreadButton" destination="ISb-UT-u0O" id="fs0-sQ-lRe"/>
<outlet property="jumpToLastUnreadLabel" destination="S1q-B4-Df3" id="McV-gv-bUa"/>
<outlet property="previewHeaderContainer" destination="54r-18-K1g" id="Klt-RV-V1E"/>
<outlet property="previewHeaderContainerHeightConstraint" destination="goj-GZ-IkD" id="GbA-T9-kiL"/>
<outlet property="resetReadMarkerButton" destination="c4g-BY-xOo" id="KuR-hH-rz1"/>
<outlet property="roomActivitiesContainer" destination="XX4-n6-hCm" id="uD0-ab-8s8"/>
<outlet property="roomActivitiesContainerHeightConstraint" destination="E8v-l2-8eV" id="ebD-oV-ttx"/>
<outlet property="roomInputToolbarContainer" destination="nLd-BP-JAE" id="1dp-P1-0js"/>
<outlet property="roomInputToolbarContainerBottomConstraint" destination="kQ6-Cg-FMi" id="nHr-fR-XnV"/>
<outlet property="roomInputToolbarContainerHeightConstraint" destination="5eD-Fm-RDb" id="6ny-5w-1UA"/>
<outlet property="view" destination="iN0-l3-epB" id="ieV-u7-rXU"/>
</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>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" keyboardDismissMode="interactive" style="plain" separatorStyle="none" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="BGD-sd-SQR">
<rect key="frame" x="0.0" y="0.0" width="375" height="626"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="accessibilityIdentifier" value="RoomVCBubblesTableView"/>
</userDefinedRuntimeAttributes>
</tableView>
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="uK2-9a-rZj" userLabel="Expanded Header Container" customClass="ExpandedRoomTitleView">
<rect key="frame" x="0.0" y="0.0" width="375" height="215"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="RoomVCExpandedHeaderContainer"/>
<constraints>
<constraint firstAttribute="height" constant="215" id="w9z-HS-7wJ"/>
</constraints>
</view>
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="54r-18-K1g">
<rect key="frame" x="0.0" y="0.0" width="375" height="368"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="RoomVCPreviewHeaderContainer"/>
<constraints>
<constraint firstAttribute="height" constant="368" id="goj-GZ-IkD"/>
</constraints>
</view>
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="S6r-bo-jxw">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ISb-UT-u0O">
<rect key="frame" x="5" y="0.0" width="51" height="44"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="XgY-bC-cpU"/>
</constraints>
<connections>
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="7pe-19-Zxc"/>
</connections>
</button>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="jump_to_unread.png" translatesAutoresizingMaskIntoConstraints="NO" id="Vlz-UJ-Jz8">
<rect key="frame" x="13" y="7" width="30" height="30"/>
<constraints>
<constraint firstAttribute="width" constant="30" id="JCI-mP-w3F"/>
<constraint firstAttribute="width" secondItem="Vlz-UJ-Jz8" secondAttribute="height" multiplier="1:1" id="gEk-9p-KUO"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="S1q-B4-Df3">
<rect key="frame" x="56" y="22.5" width="0.0" height="0.0"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="c4g-BY-xOo">
<rect key="frame" x="335" y="0.0" width="44" height="44"/>
<constraints>
<constraint firstAttribute="width" constant="44" id="2YD-H9-DyP"/>
<constraint firstAttribute="width" secondItem="c4g-BY-xOo" secondAttribute="height" multiplier="1:1" id="DG6-tf-YUj"/>
</constraints>
<connections>
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="8by-6v-ZGR"/>
</connections>
</button>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="cancel.png" translatesAutoresizingMaskIntoConstraints="NO" id="TYG-1i-OrY">
<rect key="frame" x="347" y="12" width="20" height="20"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="2Nx-YU-skd"/>
<constraint firstAttribute="width" secondItem="TYG-1i-OrY" secondAttribute="height" multiplier="1:1" id="jBy-Ex-gBc"/>
</constraints>
</imageView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="knN-q1-QkJ" userLabel="Separator View">
<rect key="frame" x="10" y="43" width="365" height="1"/>
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="1" id="8k7-fr-b8R"/>
<constraint firstAttribute="height" constant="1" id="G1Q-g6-4kp"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="7TA-9m-DJm"/>
<constraint firstItem="ISb-UT-u0O" firstAttribute="trailing" secondItem="S1q-B4-Df3" secondAttribute="trailing" id="ABS-rW-2Up"/>
<constraint firstItem="knN-q1-QkJ" firstAttribute="leading" secondItem="S6r-bo-jxw" secondAttribute="leading" constant="10" id="DL5-gC-Y2y"/>
<constraint firstAttribute="bottom" secondItem="knN-q1-QkJ" secondAttribute="bottom" id="HrB-BI-pbX"/>
<constraint firstItem="Vlz-UJ-Jz8" firstAttribute="centerY" secondItem="S6r-bo-jxw" secondAttribute="centerY" id="Oyl-YW-LyY"/>
<constraint firstItem="c4g-BY-xOo" firstAttribute="centerY" secondItem="TYG-1i-OrY" secondAttribute="centerY" id="PY6-yg-tuv"/>
<constraint firstAttribute="trailing" secondItem="knN-q1-QkJ" secondAttribute="trailing" id="RFO-8F-wd7"/>
<constraint firstItem="S1q-B4-Df3" firstAttribute="centerY" secondItem="S6r-bo-jxw" secondAttribute="centerY" id="YEJ-zl-raJ"/>
<constraint firstItem="ISb-UT-u0O" firstAttribute="leading" secondItem="S6r-bo-jxw" secondAttribute="leading" constant="5" id="Znj-wf-lOm"/>
<constraint firstAttribute="trailing" secondItem="TYG-1i-OrY" secondAttribute="trailing" constant="8" id="bcg-1X-Ujo"/>
<constraint firstItem="TYG-1i-OrY" firstAttribute="centerY" secondItem="S6r-bo-jxw" secondAttribute="centerY" id="dr9-xy-Nhj"/>
<constraint firstItem="Vlz-UJ-Jz8" firstAttribute="leading" secondItem="S6r-bo-jxw" secondAttribute="leading" constant="13" id="rya-xy-hDd"/>
<constraint firstItem="S1q-B4-Df3" firstAttribute="leading" secondItem="S6r-bo-jxw" secondAttribute="leading" constant="56" id="t7w-84-xaw"/>
<constraint firstItem="c4g-BY-xOo" firstAttribute="centerX" secondItem="TYG-1i-OrY" secondAttribute="centerX" id="tXP-dn-3bC"/>
<constraint firstItem="ISb-UT-u0O" firstAttribute="centerY" secondItem="Vlz-UJ-Jz8" secondAttribute="centerY" id="w7t-WC-VjP"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XX4-n6-hCm" userLabel="Activities Container">
<rect key="frame" x="0.0" y="606" width="375" height="20"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="RoomVCActivitiesContainer"/>
<constraints>
<constraint firstAttribute="height" constant="20" id="E8v-l2-8eV"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nLd-BP-JAE" userLabel="Room Input Toolbar Container">
<rect key="frame" x="0.0" y="626" width="375" height="41"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<accessibility key="accessibilityConfiguration" identifier="RoomVCRoomInputToolbarContainer"/>
<constraints>
<constraint firstAttribute="height" constant="41" id="5eD-Fm-RDb"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="RoomVCView"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="BGD-sd-SQR" secondAttribute="trailing" id="0la-ok-MBr"/>
<constraint firstItem="S6r-bo-jxw" firstAttribute="width" secondItem="BGD-sd-SQR" secondAttribute="width" id="3Mr-fA-bfF"/>
<constraint firstItem="nLd-BP-JAE" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="4Q7-hr-rqi"/>
<constraint firstAttribute="trailing" secondItem="54r-18-K1g" secondAttribute="trailing" id="6NN-Vs-ci8"/>
<constraint firstItem="54r-18-K1g" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="BC8-KU-Pus"/>
<constraint firstAttribute="trailing" secondItem="uK2-9a-rZj" secondAttribute="trailing" id="HbF-85-ctI"/>
<constraint firstAttribute="bottom" secondItem="BGD-sd-SQR" secondAttribute="bottom" constant="41" id="Ksk-39-kfi"/>
<constraint firstItem="XX4-n6-hCm" firstAttribute="bottom" secondItem="nLd-BP-JAE" secondAttribute="top" id="QO8-nF-xys"/>
<constraint firstItem="XX4-n6-hCm" firstAttribute="width" secondItem="iN0-l3-epB" secondAttribute="width" id="WhE-lH-ZtR"/>
<constraint firstItem="BGD-sd-SQR" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="X14-4s-uGM"/>
<constraint firstAttribute="trailing" secondItem="nLd-BP-JAE" secondAttribute="trailing" id="YAu-gd-ItG"/>
<constraint firstItem="S6r-bo-jxw" firstAttribute="centerX" secondItem="BGD-sd-SQR" secondAttribute="centerX" id="a2s-5o-q2d"/>
<constraint firstItem="XX4-n6-hCm" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="csl-KT-4s9"/>
<constraint firstItem="54r-18-K1g" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="ghf-co-a4t"/>
<constraint firstItem="BGD-sd-SQR" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="haP-Kv-OLI"/>
<constraint firstAttribute="bottom" secondItem="nLd-BP-JAE" secondAttribute="bottom" id="kQ6-Cg-FMi"/>
<constraint firstItem="uK2-9a-rZj" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="u8r-eN-1g8"/>
<constraint firstItem="S6r-bo-jxw" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="xYa-gT-4x0"/>
<constraint firstItem="uK2-9a-rZj" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="y6b-JK-CF5"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
</view>
</objects>
<resources>
<image name="cancel.png" width="20" height="20"/>
<image name="jump_to_unread.png" width="30" height="30"/>
</resources>
</document>
@@ -0,0 +1,26 @@
/*
Copyright 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import <MatrixKit/MatrixKit.h>
@interface RoomFilesSearchViewController : MXKSearchViewController
/**
The event selected in the search results
*/
@property (nonatomic, readonly) MXEvent *selectedEvent;
@end
@@ -0,0 +1,187 @@
/*
Copyright 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import "RoomFilesSearchViewController.h"
#import "RoomSearchViewController.h"
#import "UIViewController+RiotSearch.h"
#import "FilesSearchCellData.h"
#import "FilesSearchTableViewCell.h"
#import "AppDelegate.h"
@interface RoomFilesSearchViewController ()
{
// Observe kAppDelegateDidTapStatusBarNotification to handle tap on clock status bar.
id kAppDelegateDidTapStatusBarNotificationObserver;
// Observe kRiotDesignValuesDidChangeThemeNotification to handle user interface theme change.
id kRiotDesignValuesDidChangeThemeNotificationObserver;
}
@end
@implementation RoomFilesSearchViewController
- (void)finalizeInit
{
[super finalizeInit];
// Setup `MXKViewControllerHandling` properties
self.enableBarTintColorStatusChange = NO;
self.rageShakeManager = [RageShakeManager sharedManager];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Hide line separators of empty cells
self.searchTableView.tableFooterView = [[UIView alloc] init];
// Register cell class used to display the files search result
[self.searchTableView registerClass:FilesSearchTableViewCell.class forCellReuseIdentifier:FilesSearchTableViewCell.defaultReuseIdentifier];
self.searchTableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
// 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;
// Check the table view style to select its bg color.
self.searchTableView.backgroundColor = ((self.searchTableView.style == UITableViewStylePlain) ? kRiotPrimaryBgColor : kRiotSecondaryBgColor);
self.view.backgroundColor = self.searchTableView.backgroundColor;
self.noResultsLabel.textColor = kRiotPrimaryBgColor;
if (self.searchTableView.dataSource)
{
[self.searchTableView reloadData];
}
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
return kRiotDesignStatusBarStyle;
}
- (void)destroy
{
[super destroy];
if (kRiotDesignValuesDidChangeThemeNotificationObserver)
{
[[NSNotificationCenter defaultCenter] removeObserver:kRiotDesignValuesDidChangeThemeNotificationObserver];
kRiotDesignValuesDidChangeThemeNotificationObserver = nil;
}
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Screen tracking
[[Analytics sharedInstance] trackScreen:@"RoomFilesSearch"];
// Observe kAppDelegateDidTapStatusBarNotificationObserver.
kAppDelegateDidTapStatusBarNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kAppDelegateDidTapStatusBarNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
[self.searchTableView setContentOffset:CGPointMake(-self.searchTableView.mxk_adjustedContentInset.left, -self.searchTableView.mxk_adjustedContentInset.top) animated:YES];
}];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
if (kAppDelegateDidTapStatusBarNotificationObserver)
{
[[NSNotificationCenter defaultCenter] removeObserver:kAppDelegateDidTapStatusBarNotificationObserver];
kAppDelegateDidTapStatusBarNotificationObserver = nil;
}
}
#pragma mark - MXKDataSourceDelegate
- (Class<MXKCellRendering>)cellViewClassForCellData:(MXKCellData*)cellData
{
return FilesSearchTableViewCell.class;
}
- (NSString *)cellReuseIdentifierForCellData:(MXKCellData*)cellData
{
return FilesSearchTableViewCell.defaultReuseIdentifier;
}
#pragma mark - Override UITableView delegate
- (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;
}
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Data in the cells are actually Vector RoomBubbleCellData
FilesSearchCellData *cellData = (FilesSearchCellData*)[self.dataSource cellDataAtIndex:indexPath.row];
_selectedEvent = cellData.searchResult.result;
// Hide the keyboard handled by the search text input which belongs to RoomSearchViewController
[((RoomSearchViewController*)self.parentViewController).searchBar resignFirstResponder];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// Make the RoomSearchViewController (that contains this VC) open the RoomViewController
[self.parentViewController performSegueWithIdentifier:@"showTimeline" sender:self];
// Reset the selected event. RoomSearchViewController got it when here
_selectedEvent = nil;
}
@end
@@ -0,0 +1,26 @@
/*
Copyright 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import <MatrixKit/MatrixKit.h>
@interface RoomMessagesSearchViewController : MXKSearchViewController
/**
The event selected in the search results
*/
@property (nonatomic, readonly) MXEvent *selectedEvent;
@end
@@ -0,0 +1,223 @@
/*
Copyright 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import "RoomMessagesSearchViewController.h"
#import "RoomSearchViewController.h"
#import "UIViewController+RiotSearch.h"
// Use RoomViewController cells to display results
#import "RoomBubbleCellData.h"
#import "RoomIncomingAttachmentBubbleCell.h"
#import "RoomIncomingTextMsgBubbleCell.h"
#import "AppDelegate.h"
@interface RoomMessagesSearchViewController ()
{
// Observe kAppDelegateDidTapStatusBarNotification to handle tap on clock status bar.
id kAppDelegateDidTapStatusBarNotificationObserver;
// Observe kRiotDesignValuesDidChangeThemeNotification to handle user interface theme change.
id kRiotDesignValuesDidChangeThemeNotificationObserver;
}
@end
@implementation RoomMessagesSearchViewController
- (void)finalizeInit
{
[super finalizeInit];
// Setup `MXKViewControllerHandling` properties
self.enableBarTintColorStatusChange = NO;
self.rageShakeManager = [RageShakeManager sharedManager];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Hide line separators of empty cells
self.searchTableView.tableFooterView = [[UIView alloc] init];
// Reuse cells from the RoomViewController to display results
[self.searchTableView registerClass:RoomIncomingTextMsgBubbleCell.class forCellReuseIdentifier:RoomIncomingTextMsgBubbleCell.defaultReuseIdentifier];
[self.searchTableView registerClass:RoomIncomingAttachmentBubbleCell.class forCellReuseIdentifier:RoomIncomingAttachmentBubbleCell.defaultReuseIdentifier];
// 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;
// Check the table view style to select its bg color.
self.searchTableView.backgroundColor = ((self.searchTableView.style == UITableViewStylePlain) ? kRiotPrimaryBgColor : kRiotSecondaryBgColor);
self.view.backgroundColor = self.searchTableView.backgroundColor;
self.noResultsLabel.textColor = kRiotPrimaryBgColor;
if (self.searchTableView.dataSource)
{
[self.searchTableView reloadData];
}
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
return kRiotDesignStatusBarStyle;
}
- (void)destroy
{
[super destroy];
if (kRiotDesignValuesDidChangeThemeNotificationObserver)
{
[[NSNotificationCenter defaultCenter] removeObserver:kRiotDesignValuesDidChangeThemeNotificationObserver];
kRiotDesignValuesDidChangeThemeNotificationObserver = nil;
}
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Screen tracking
[[Analytics sharedInstance] trackScreen:@"RoomMessagesSearch"];
// Observe kAppDelegateDidTapStatusBarNotificationObserver.
kAppDelegateDidTapStatusBarNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kAppDelegateDidTapStatusBarNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
[self.searchTableView setContentOffset:CGPointMake(-self.searchTableView.mxk_adjustedContentInset.left, -self.searchTableView.mxk_adjustedContentInset.top) animated:YES];
}];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
if (kAppDelegateDidTapStatusBarNotificationObserver)
{
[[NSNotificationCenter defaultCenter] removeObserver:kAppDelegateDidTapStatusBarNotificationObserver];
kAppDelegateDidTapStatusBarNotificationObserver = nil;
}
}
#pragma mark - MXKDataSourceDelegate
- (Class<MXKCellRendering>)cellViewClassForCellData:(MXKCellData*)cellData
{
Class cellViewClass = nil;
// Sanity check
if ([cellData conformsToProtocol:@protocol(MXKRoomBubbleCellDataStoring)])
{
id<MXKRoomBubbleCellDataStoring> bubbleData = (id<MXKRoomBubbleCellDataStoring>)cellData;
// Select the suitable table view cell class
if (bubbleData.isAttachmentWithThumbnail)
{
cellViewClass = RoomIncomingAttachmentBubbleCell.class;
}
else
{
cellViewClass = RoomIncomingTextMsgBubbleCell.class;
}
}
return cellViewClass;
}
- (NSString *)cellReuseIdentifierForCellData:(MXKCellData*)cellData
{
Class class = [self cellViewClassForCellData:cellData];
if ([class respondsToSelector:@selector(defaultReuseIdentifier)])
{
return [class defaultReuseIdentifier];
}
return nil;
}
#pragma mark - Override UITableView delegate
- (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;
}
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// `MXKRoomBubbleTableViewCell` cells displayed by the `RoomViewController`
// do not have line separators.
// The +1 here is for the line separator which is displayed by `RoomSearchViewController`.
return [super tableView:tableView heightForRowAtIndexPath:indexPath] + 1;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Data in the cells are actually Vector RoomBubbleCellData
RoomBubbleCellData *cellData = (RoomBubbleCellData*)[self.dataSource cellDataAtIndex:indexPath.row];
_selectedEvent = cellData.bubbleComponents[0].event;
// Hide the keyboard handled by the search text input which belongs to RoomSearchViewController
[((RoomSearchViewController*)self.parentViewController).searchBar resignFirstResponder];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// Make the RoomSearchViewController (that contains this VC) open the RoomViewController
[self.parentViewController performSegueWithIdentifier:@"showTimeline" sender:self];
// Reset the selected event. RoomSearchViewController got it when here
_selectedEvent = nil;
}
@end
@@ -0,0 +1,28 @@
/*
Copyright 2015 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import <MatrixKit/MatrixKit.h>
#import "SegmentedViewController.h"
@interface RoomSearchViewController : SegmentedViewController
/**
The room data source concerned by the search session.
*/
@property (nonatomic) MXKRoomDataSource *roomDataSource;
@end
@@ -0,0 +1,361 @@
/*
Copyright 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import "RoomSearchViewController.h"
#import "RoomMessagesSearchViewController.h"
#import "RoomSearchDataSource.h"
#import "RoomFilesSearchViewController.h"
#import "FilesSearchCellData.h"
#import "AppDelegate.h"
@interface RoomSearchViewController ()
{
RoomMessagesSearchViewController *messagesSearchViewController;
RoomSearchDataSource *messagesSearchDataSource;
RoomFilesSearchViewController *filesSearchViewController;
MXKSearchDataSource *filesSearchDataSource;
}
@end
@implementation RoomSearchViewController
- (void)finalizeInit
{
[super finalizeInit];
// The navigation bar tint color and the rageShake Manager are handled by super (see SegmentedViewController).
}
- (void)viewDidLoad
{
// Set up the SegmentedVC tabs before calling [super viewDidLoad]
NSMutableArray* viewControllers = [[NSMutableArray alloc] init];
NSMutableArray* titles = [[NSMutableArray alloc] init];
[titles addObject: NSLocalizedStringFromTable(@"search_messages", @"Vector", nil)];
messagesSearchViewController = [RoomMessagesSearchViewController searchViewController];
[viewControllers addObject:messagesSearchViewController];
// add Files tab
[titles addObject: NSLocalizedStringFromTable(@"search_files", @"Vector", nil)];
filesSearchViewController = [RoomFilesSearchViewController searchViewController];
[viewControllers addObject:filesSearchViewController];
[self initWithTitles:titles viewControllers:viewControllers defaultSelected:0];
[super viewDidLoad];
// Add the Riot background image when search bar is empty
[self addBackgroundImageViewToView:self.view];
// Initialize here the data sources if a matrix session has been already set.
[self initializeDataSources];
self.searchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;
}
- (void)userInterfaceThemeDidChange
{
[super userInterfaceThemeDidChange];
UIImageView *backgroundImageView = self.backgroundImageView;
if (backgroundImageView)
{
UIImage *image = [MXKTools paintImage:backgroundImageView.image withColor:kRiotKeyboardColor];
backgroundImageView.image = image;
}
}
- (void)destroy
{
[super destroy];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Let's child display the loading not this view controller
if (self.activityIndicator)
{
[self.activityIndicator stopAnimating];
self.activityIndicator = nil;
}
// Screen tracking
[[Analytics sharedInstance] trackScreen:@"RoomsSearch"];
// Enable the search field by default at the screen opening
if (self.searchBarHidden)
{
[self showSearch:NO];
}
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// Refresh the search results.
// Note: We wait for 'viewDidAppear' call to consider the actual view size during this update.
[self updateSearch];
}
#pragma mark -
- (void)setRoomDataSource:(MXKRoomDataSource *)roomDataSource
{
// Remove existing matrix session if any
while (self.mainSession)
{
[self removeMatrixSession:self.mainSession];
}
_roomDataSource = roomDataSource;
[self addMatrixSession:_roomDataSource.mxSession];
// Check whether the controller'€™s view is already loaded into memory.
if (messagesSearchViewController)
{
// Prepare data sources
[self initializeDataSources];
}
}
- (void)initializeDataSources
{
MXSession *mainSession = self.mainSession;
if (mainSession && _roomDataSource)
{
// Init the search for messages
messagesSearchDataSource = [[RoomSearchDataSource alloc] initWithRoomDataSource:_roomDataSource];
[messagesSearchViewController displaySearch:messagesSearchDataSource];
// Init the search for attachments
filesSearchDataSource = [[MXKSearchDataSource alloc] initWithMatrixSession:mainSession];
filesSearchDataSource.roomEventFilter.rooms = @[_roomDataSource.roomId];
filesSearchDataSource.roomEventFilter.containsURL = YES;
filesSearchDataSource.shouldShowRoomDisplayName = NO;
[filesSearchDataSource registerCellDataClass:FilesSearchCellData.class forCellIdentifier:kMXKSearchCellDataIdentifier];
[filesSearchViewController displaySearch:filesSearchDataSource];
}
}
#pragma mark - Override MXKViewController
- (void)setKeyboardHeight:(CGFloat)keyboardHeight
{
[self setKeyboardHeightForBackgroundImage:keyboardHeight];
[super setKeyboardHeight:keyboardHeight];
[self checkAndShowBackgroundImage];
}
- (void)startActivityIndicator
{
// Redirect the operation to the currently displayed VC
// It is a MXKViewController or a MXKTableViewController. So it supports startActivityIndicator
[self.selectedViewController performSelector:@selector(startActivityIndicator)];
}
- (void)stopActivityIndicator
{
// The selected view controller mwy have changed since the call of [self startActivityIndicator]
// So, stop the activity indicator for all children
for (UIViewController *viewController in self.viewControllers)
{
[viewController performSelector:@selector(stopActivityIndicator)];
}
}
#pragma mark - Override UIViewController+VectorSearch
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
if (!self.searchBar.text.length)
{
// Reset current search if any
[self updateSearch];
}
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
if (self.selectedViewController == messagesSearchViewController || self.selectedViewController == filesSearchViewController)
{
// As the messages/files search is done homeserver-side, launch it only on the "Search" button
[self updateSearch];
}
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
// Leave the screen
[self.navigationController popViewControllerAnimated:YES];
}
- (void)setKeyboardHeightForBackgroundImage:(CGFloat)keyboardHeight
{
[super setKeyboardHeightForBackgroundImage:keyboardHeight];
if (keyboardHeight > 0)
{
[self checkAndShowBackgroundImage];
}
}
// Check conditions before displaying the background
- (void)checkAndShowBackgroundImage
{
// Note: This background is hidden when keyboard is dismissed.
// The other conditions depend on the current selected view controller.
if (self.selectedViewController == messagesSearchViewController)
{
self.backgroundImageView.hidden = ((messagesSearchDataSource.serverCount != 0) || !messagesSearchViewController.noResultsLabel.isHidden || (self.keyboardHeight == 0));
}
else if (self.selectedViewController == filesSearchViewController)
{
self.backgroundImageView.hidden = ((filesSearchDataSource.serverCount != 0) || !filesSearchViewController.noResultsLabel.isHidden || (self.keyboardHeight == 0));
}
else
{
self.backgroundImageView.hidden = (self.keyboardHeight == 0);
}
if (!self.backgroundImageView.hidden)
{
[self.backgroundImageView layoutIfNeeded];
[self.selectedViewController.view layoutIfNeeded];
// Check whether there is enough space to display this background
// For example, in landscape with the iPhone 5 & 6 screen size, the backgroundImageView must be hidden.
if (self.backgroundImageView.frame.origin.y < 0 || (self.selectedViewController.view.frame.size.height - self.backgroundImageViewBottomConstraint.constant) < self.backgroundImageView.frame.size.height)
{
self.backgroundImageView.hidden = YES;
}
}
}
#pragma mark - Override SegmentedViewController
- (void)setSelectedIndex:(NSUInteger)selectedIndex
{
[super setSelectedIndex:selectedIndex];
[self updateSearch];
}
#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
[super prepareForSegue:segue sender:sender];
if ([[segue identifier] isEqualToString:@"showTimeline"])
{
// Check whether an event has been selected from messages or files search tab
MXEvent *selectedSearchEvent = messagesSearchViewController.selectedEvent;
MXSession *selectedSearchEventSession = messagesSearchDataSource.mxSession;
if (!selectedSearchEvent)
{
selectedSearchEvent = filesSearchViewController.selectedEvent;
selectedSearchEventSession = filesSearchDataSource.mxSession;
}
if (selectedSearchEvent)
{
RoomViewController *roomViewController = segue.destinationViewController;
RoomDataSource *roomDataSource = [[RoomDataSource alloc] initWithRoomId:selectedSearchEvent.roomId initialEventId:selectedSearchEvent.eventId andMatrixSession:selectedSearchEventSession];
[roomDataSource finalizeInitialization];
roomDataSource.markTimelineInitialEvent = YES;
[roomViewController displayRoom:roomDataSource];
roomViewController.hasRoomDataSourceOwnership = YES;
roomViewController.navigationItem.leftItemsSupplementBackButton = YES;
}
// Hide back button title
self.navigationItem.backBarButtonItem =[[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
}
}
#pragma mark - Search
// Update search results under the currently selected tab
- (void)updateSearch
{
if (self.searchBar.text.length)
{
self.backgroundImageView.hidden = YES;
// Forward the search request to the data source
if (self.selectedViewController == messagesSearchViewController)
{
// Launch the search only if the keyboard is no more visible
if (!self.searchBar.isFirstResponder)
{
// Do it asynchronously to give time to messagesSearchViewController to be set up
// so that it can display its loading wheel
dispatch_async(dispatch_get_main_queue(), ^{
[messagesSearchDataSource searchMessages:self.searchBar.text force:NO];
messagesSearchViewController.shouldScrollToBottomOnRefresh = YES;
});
}
}
else if (self.selectedViewController == filesSearchViewController)
{
// Launch the search only if the keyboard is no more visible
if (!self.searchBar.isFirstResponder)
{
// Do it asynchronously to give time to filesSearchViewController to be set up
// so that it can display its loading wheel
dispatch_async(dispatch_get_main_queue(), ^{
[filesSearchDataSource searchMessages:self.searchBar.text force:NO];
filesSearchViewController.shouldScrollToBottomOnRefresh = YES;
});
}
}
}
else
{
// Nothing to search - Reset search result (if any)
if (messagesSearchDataSource.searchText.length)
{
[messagesSearchDataSource searchMessages:nil force:NO];
}
if (filesSearchDataSource.searchText.length)
{
[filesSearchDataSource searchMessages:nil force:NO];
}
}
[self checkAndShowBackgroundImage];
}
@end
@@ -0,0 +1,56 @@
/*
Copyright 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import <MatrixKit/MatrixKit.h>
#import "MediaPickerViewController.h"
#import "TableViewCellWithCheckBoxes.h"
/**
List the settings fields. Used to preselect/edit a field
*/
typedef enum : NSUInteger {
/**
Default.
*/
RoomSettingsViewControllerFieldNone,
/**
The room name.
*/
RoomSettingsViewControllerFieldName,
/**
The room topic.
*/
RoomSettingsViewControllerFieldTopic,
/**
The room avatar.
*/
RoomSettingsViewControllerFieldAvatar
} RoomSettingsViewControllerField;
@interface RoomSettingsViewController : MXKRoomSettingsViewController <UITextViewDelegate, UITextFieldDelegate, MediaPickerViewControllerDelegate, MXKRoomMemberDetailsViewControllerDelegate, TableViewCellWithCheckBoxesDelegate>
/**
Select a settings field in order to edit it ('RoomSettingsViewControllerFieldNone' by default).
*/
@property (nonatomic) RoomSettingsViewControllerField selectedRoomSettingsField;
@end
File diff suppressed because it is too large Load Diff