Organize views by feature

This commit is contained in:
SBiOSoftWhare
2018-07-06 16:42:45 +02:00
parent 263c8f9246
commit fbe1264a5a
247 changed files with 1085 additions and 972 deletions
@@ -0,0 +1,40 @@
/*
Copyright 2018 New Vector 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>
/**
`DisabledRoomInputToolbarView` instance is an input toolbar to show to the end user
that they have limited permission to interact with the room.
*/
@interface DisabledRoomInputToolbarView : MXKRoomInputToolbarView
@property (weak, nonatomic) IBOutlet UIView *mainToolbarView;
@property (weak, nonatomic) IBOutlet UIView *separatorView;
@property (strong, nonatomic) IBOutlet MXKImageView *pictureView;
@property (weak, nonatomic) IBOutlet UITextView *disabledReasonTextView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *mainToolbarMinHeightConstraint;
/**
Display the limitation reason message.
@param reason the reason why the user cannot interact with the room.
*/
- (void)setDisabledReason:(NSString*)reason;
@end
@@ -0,0 +1,66 @@
/*
Copyright 2018 New Vector 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 "DisabledRoomInputToolbarView.h"
#import "RiotDesignValues.h"
@implementation DisabledRoomInputToolbarView
+ (UINib *)nib
{
return [UINib nibWithNibName:NSStringFromClass([DisabledRoomInputToolbarView class])
bundle:[NSBundle bundleForClass:[DisabledRoomInputToolbarView class]]];
}
+ (instancetype)roomInputToolbarView
{
if ([[self class] nib])
{
return [[[self class] nib] instantiateWithOwner:nil options:nil].firstObject;
}
else
{
return [[self alloc] init];
}
}
#pragma mark - Override MXKView
-(void)customizeViewRendering
{
[super customizeViewRendering];
// Remove default toolbar background color
self.backgroundColor = [UIColor clearColor];
self.separatorView.backgroundColor = kRiotAuxiliaryColor;
self.disabledReasonTextView.font = [UIFont systemFontOfSize:15];
self.disabledReasonTextView.textColor = kRiotPrimaryTextColor;
self.disabledReasonTextView.tintColor = kRiotColorGreen;
self.disabledReasonTextView.editable = NO;
self.disabledReasonTextView.scrollEnabled = NO;
}
#pragma mark -
- (void)setDisabledReason:(NSString *)reason
{
self.disabledReasonTextView.text = reason;
}
@end
@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13771"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="DisabledRoomInputToolbarView">
<rect key="frame" x="0.0" y="0.0" width="600" height="46"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="a84-Vc-6ud" userLabel="MainToolBar View">
<rect key="frame" x="0.0" y="0.0" width="600" height="46"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3ln-yI-ef9" userLabel="Separator View">
<rect key="frame" x="10" y="0.0" width="580" height="1"/>
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="WBM-ts-zPX"/>
</constraints>
</view>
<view clipsSubviews="YES" contentMode="scaleAspectFill" translatesAutoresizingMaskIntoConstraints="NO" id="dd4-pE-Es1" userLabel="Picture View" customClass="MXKImageView">
<rect key="frame" x="13" y="8" width="30" height="30"/>
<color key="backgroundColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="PictureView"/>
<constraints>
<constraint firstAttribute="width" constant="30" id="gwh-Qs-gY1"/>
<constraint firstAttribute="height" constant="30" id="wMB-Ec-D9s"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="QWp-NV-uh5" userLabel="Message Composer Container">
<rect key="frame" x="52" y="4" width="533" height="38"/>
<subviews>
<view contentMode="scaleToFill" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="wgb-ON-N29" customClass="UITextView">
<rect key="frame" x="0.0" y="0.0" width="533" height="38"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="GrowingTextView"/>
</view>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="wgb-ON-N29" firstAttribute="centerY" secondItem="QWp-NV-uh5" secondAttribute="centerY" id="PZl-Tb-mDv"/>
<constraint firstAttribute="trailing" secondItem="wgb-ON-N29" secondAttribute="trailing" id="ms6-mg-0xf"/>
<constraint firstItem="wgb-ON-N29" firstAttribute="height" secondItem="QWp-NV-uh5" secondAttribute="height" priority="750" id="pOn-UI-aTZ"/>
<constraint firstItem="wgb-ON-N29" firstAttribute="leading" secondItem="QWp-NV-uh5" secondAttribute="leading" id="yvw-X3-WtY"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="46" id="1FO-iu-urG"/>
<constraint firstItem="3ln-yI-ef9" firstAttribute="leading" secondItem="a84-Vc-6ud" secondAttribute="leading" constant="10" id="BwP-sF-qE1"/>
<constraint firstItem="QWp-NV-uh5" firstAttribute="leading" secondItem="a84-Vc-6ud" secondAttribute="leading" constant="52" id="ErD-eB-stF"/>
<constraint firstItem="dd4-pE-Es1" firstAttribute="leading" secondItem="a84-Vc-6ud" secondAttribute="leading" constant="13" id="Jem-U2-oEq"/>
<constraint firstAttribute="bottom" secondItem="QWp-NV-uh5" secondAttribute="bottom" constant="4" id="NGr-2o-sOP"/>
<constraint firstAttribute="trailing" secondItem="3ln-yI-ef9" secondAttribute="trailing" constant="10" id="RXB-PN-3n8"/>
<constraint firstItem="QWp-NV-uh5" firstAttribute="top" secondItem="a84-Vc-6ud" secondAttribute="top" constant="4" id="WyZ-3i-OHi"/>
<constraint firstAttribute="height" constant="46" id="Yjj-ua-rbe"/>
<constraint firstAttribute="trailing" secondItem="QWp-NV-uh5" secondAttribute="trailing" constant="15" id="hXO-cY-Jgz"/>
<constraint firstItem="dd4-pE-Es1" firstAttribute="top" secondItem="a84-Vc-6ud" secondAttribute="top" constant="8" id="xjT-If-1cd"/>
<constraint firstItem="3ln-yI-ef9" firstAttribute="top" secondItem="a84-Vc-6ud" secondAttribute="top" id="yUF-5t-x03"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="DisabledRoomInputToolbarView"/>
<constraints>
<constraint firstItem="a84-Vc-6ud" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="VBS-kE-WiP"/>
<constraint firstAttribute="trailing" secondItem="a84-Vc-6ud" secondAttribute="trailing" id="cNb-nJ-iAI"/>
<constraint firstAttribute="bottom" secondItem="a84-Vc-6ud" secondAttribute="bottom" id="jFc-lW-hpZ"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<nil key="simulatedTopBarMetrics"/>
<nil key="simulatedBottomBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<connections>
<outlet property="disabledReasonTextView" destination="wgb-ON-N29" id="JnB-sr-s3I"/>
<outlet property="mainToolbarMinHeightConstraint" destination="1FO-iu-urG" id="2U6-h2-0zQ"/>
<outlet property="mainToolbarView" destination="a84-Vc-6ud" id="5p3-Ft-0gv"/>
<outlet property="messageComposerContainer" destination="QWp-NV-uh5" id="APR-B5-ogC"/>
<outlet property="messageComposerContainerBottomConstraint" destination="NGr-2o-sOP" id="oez-6D-IKA"/>
<outlet property="messageComposerContainerTopConstraint" destination="WyZ-3i-OHi" id="OcO-1f-bNA"/>
<outlet property="pictureView" destination="dd4-pE-Es1" id="rb6-z2-pJ9"/>
<outlet property="separatorView" destination="3ln-yI-ef9" id="HQ3-B4-Goj"/>
</connections>
</view>
</objects>
</document>
@@ -0,0 +1,41 @@
/*
Copyright 2015 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 <Foundation/Foundation.h>
#import <HPGrowingTextView/HPGrowingTextView.h>
#import "RoomInputToolbarView.h"
@interface KeyboardGrowingTextView: HPGrowingTextView
- (NSArray<UIKeyCommand *> *)keyCommands;
@end
@implementation KeyboardGrowingTextView
- (NSArray<UIKeyCommand *> *)keyCommands {
return @[
[UIKeyCommand keyCommandWithInput:@"\r" modifierFlags:0 action:@selector(keyCommandSelector:)]
];
}
- (void)keyCommandSelector:(UIKeyCommand *)sender {
if ([sender.input isEqualToString:@"\r"] && [self.delegate isKindOfClass: RoomInputToolbarView.class]){
RoomInputToolbarView *ritv = (RoomInputToolbarView *)self.delegate;
[ritv onTouchUpInside:ritv.rightInputToolbarButton]; // touch the Send button.
}
}
@end
@@ -0,0 +1,77 @@
/*
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 "MediaPickerViewController.h"
@protocol RoomInputToolbarViewDelegate <MXKRoomInputToolbarViewDelegate>
/**
Tells the delegate that the user wants to display the sticker picker.
@param toolbarView the room input toolbar view.
*/
- (void)roomInputToolbarViewPresentStickerPicker:(MXKRoomInputToolbarView*)toolbarView;
@end
/**
`RoomInputToolbarView` instance is a view used to handle all kinds of available inputs
for a room (message composer, attachments selection...).
*/
@interface RoomInputToolbarView : MXKRoomInputToolbarViewWithHPGrowingText <MediaPickerViewControllerDelegate>
/**
The delegate notified when inputs are ready.
*/
@property (nonatomic) id<RoomInputToolbarViewDelegate> delegate;
@property (weak, nonatomic) IBOutlet UIView *mainToolbarView;
@property (weak, nonatomic) IBOutlet UIView *separatorView;
@property (strong, nonatomic) IBOutlet MXKImageView *pictureView;
@property (strong, nonatomic) IBOutlet UIImageView *encryptedRoomIcon;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *mainToolbarMinHeightConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *mainToolbarHeightConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *messageComposerContainerLeadingConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *messageComposerContainerTrailingConstraint;
@property (weak, nonatomic) IBOutlet UIButton *attachMediaButton;
@property (weak, nonatomic) IBOutlet UIButton *voiceCallButton;
@property (weak, nonatomic) IBOutlet UIButton *hangupCallButton;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *voiceCallButtonWidthConstraint;
/**
Tell whether the call option is supported. YES by default.
*/
@property (nonatomic) BOOL supportCallOption;
/**
Tell whether the filled data will be sent encrypted. NO by default.
*/
@property (nonatomic) BOOL isEncryptionEnabled;
/**
Tell whether a call is active.
*/
@property (nonatomic) BOOL activeCall;
@end
@@ -0,0 +1,432 @@
/*
Copyright 2015 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 "RoomInputToolbarView.h"
#import "RiotDesignValues.h"
#import "GBDeviceInfo_iOS.h"
#import "UINavigationController+Riot.h"
#import <MediaPlayer/MediaPlayer.h>
#import <Photos/Photos.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import "WidgetManager.h"
#import "IntegrationManagerViewController.h"
@interface RoomInputToolbarView()
{
MediaPickerViewController *mediaPicker;
// The intermediate action sheet
UIAlertController *actionSheet;
}
@end
@implementation RoomInputToolbarView
@dynamic delegate;
+ (UINib *)nib
{
return [UINib nibWithNibName:NSStringFromClass([RoomInputToolbarView class])
bundle:[NSBundle bundleForClass:[RoomInputToolbarView class]]];
}
+ (instancetype)roomInputToolbarView
{
if ([[self class] nib])
{
return [[[self class] nib] instantiateWithOwner:nil options:nil].firstObject;
}
else
{
return [[self alloc] init];
}
}
- (void)awakeFromNib
{
[super awakeFromNib];
_supportCallOption = YES;
self.rightInputToolbarButton.hidden = YES;
[self.rightInputToolbarButton setTitleColor:kRiotColorGreen forState:UIControlStateNormal];
[self.rightInputToolbarButton setTitleColor:kRiotColorGreen forState:UIControlStateHighlighted];
self.isEncryptionEnabled = _isEncryptionEnabled;
}
#pragma mark - Override MXKView
-(void)customizeViewRendering
{
[super customizeViewRendering];
// Remove default toolbar background color
self.backgroundColor = [UIColor clearColor];
self.separatorView.backgroundColor = kRiotAuxiliaryColor;
// Custom the growingTextView display
growingTextView.layer.cornerRadius = 0;
growingTextView.layer.borderWidth = 0;
growingTextView.backgroundColor = [UIColor clearColor];
growingTextView.font = [UIFont systemFontOfSize:15];
growingTextView.textColor = kRiotPrimaryTextColor;
growingTextView.tintColor = kRiotColorGreen;
growingTextView.internalTextView.keyboardAppearance = kRiotKeyboard;
}
#pragma mark -
- (void)setSupportCallOption:(BOOL)supportCallOption
{
if (_supportCallOption != supportCallOption)
{
_supportCallOption = supportCallOption;
if (supportCallOption)
{
self.voiceCallButtonWidthConstraint.constant = 46;
}
else
{
self.voiceCallButtonWidthConstraint.constant = 0;
}
[self setNeedsUpdateConstraints];
}
}
- (void)setIsEncryptionEnabled:(BOOL)isEncryptionEnabled
{
_isEncryptionEnabled = isEncryptionEnabled;
// Consider the default placeholder
NSString *placeholder= NSLocalizedStringFromTable(@"room_message_short_placeholder", @"Vector", nil);
if (_isEncryptionEnabled)
{
self.encryptedRoomIcon.image = [UIImage imageNamed:@"e2e_verified"];
// Check the device screen size before using large placeholder
if ([GBDeviceInfo deviceInfo].family == GBDeviceFamilyiPad || [GBDeviceInfo deviceInfo].displayInfo.display >= GBDeviceDisplay4p7Inch)
{
placeholder = NSLocalizedStringFromTable(@"encrypted_room_message_placeholder", @"Vector", nil);
}
}
else
{
self.encryptedRoomIcon.image = [UIImage imageNamed:@"e2e_unencrypted"];
// Check the device screen size before using large placeholder
if ([GBDeviceInfo deviceInfo].family == GBDeviceFamilyiPad || [GBDeviceInfo deviceInfo].displayInfo.display >= GBDeviceDisplay4p7Inch)
{
placeholder = NSLocalizedStringFromTable(@"room_message_placeholder", @"Vector", nil);
}
}
self.placeholder = placeholder;
}
- (void)setActiveCall:(BOOL)activeCall
{
if (_activeCall != activeCall)
{
_activeCall = activeCall;
self.voiceCallButton.hidden = (_activeCall || !self.rightInputToolbarButton.hidden);
self.hangupCallButton.hidden = (!_activeCall || !self.rightInputToolbarButton.hidden);
}
}
#pragma mark - HPGrowingTextView delegate
//- (BOOL)growingTextViewShouldReturn:(HPGrowingTextView *)hpGrowingTextView
//{
// // The return sends the message rather than giving a carriage return.
// [self onTouchUpInside:self.rightInputToolbarButton];
//
// return NO;
//}
- (void)growingTextViewDidChange:(HPGrowingTextView *)hpGrowingTextView
{
// Clean the carriage return added on return press
if ([self.textMessage isEqualToString:@"\n"])
{
self.textMessage = nil;
}
[super growingTextViewDidChange:hpGrowingTextView];
if (self.rightInputToolbarButton.isEnabled && self.rightInputToolbarButton.isHidden)
{
self.rightInputToolbarButton.hidden = NO;
self.attachMediaButton.hidden = YES;
self.voiceCallButton.hidden = YES;
self.hangupCallButton.hidden = YES;
self.messageComposerContainerTrailingConstraint.constant = self.frame.size.width - self.rightInputToolbarButton.frame.origin.x + 4;
}
else if (!self.rightInputToolbarButton.isEnabled && !self.rightInputToolbarButton.isHidden)
{
self.rightInputToolbarButton.hidden = YES;
self.attachMediaButton.hidden = NO;
self.voiceCallButton.hidden = _activeCall;
self.hangupCallButton.hidden = !_activeCall;
self.messageComposerContainerTrailingConstraint.constant = self.frame.size.width - self.attachMediaButton.frame.origin.x + 4;
}
}
- (void)growingTextView:(HPGrowingTextView *)hpGrowingTextView willChangeHeight:(float)height
{
// Update height of the main toolbar (message composer)
CGFloat updatedHeight = height + (self.messageComposerContainerTopConstraint.constant + self.messageComposerContainerBottomConstraint.constant);
if (updatedHeight < self.mainToolbarMinHeightConstraint.constant)
{
updatedHeight = self.mainToolbarMinHeightConstraint.constant;
}
self.mainToolbarHeightConstraint.constant = updatedHeight;
// Update toolbar superview
if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:heightDidChanged:completion:)])
{
[self.delegate roomInputToolbarView:self heightDidChanged:updatedHeight completion:nil];
}
}
#pragma mark - Override MXKRoomInputToolbarView
- (IBAction)onTouchUpInside:(UIButton*)button
{
if (button == self.attachMediaButton)
{
// Check whether media attachment is supported
if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:presentViewController:)])
{
// Ask the user the kind of the call: voice or video?
actionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
__weak typeof(self) weakSelf = self;
[actionSheet addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_action_send_photo_or_video", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->actionSheet = nil;
[self showMediaPicker];
}
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_action_send_sticker", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->actionSheet = nil;
[self.delegate roomInputToolbarViewPresentStickerPicker:self];
}
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->actionSheet = nil;
}
}]];
[actionSheet popoverPresentationController].sourceView = self.voiceCallButton;
[actionSheet popoverPresentationController].sourceRect = self.voiceCallButton.bounds;
[self.window.rootViewController presentViewController:actionSheet animated:YES completion:nil];
}
else
{
NSLog(@"[RoomInputToolbarView] Attach media is not supported");
}
}
else if (button == self.voiceCallButton)
{
if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:placeCallWithVideo:)])
{
// Ask the user the kind of the call: voice or video?
actionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
__weak typeof(self) weakSelf = self;
[actionSheet addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"voice", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->actionSheet = nil;
[self.delegate roomInputToolbarView:self placeCallWithVideo:NO];
}
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"video", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->actionSheet = nil;
[self.delegate roomInputToolbarView:self placeCallWithVideo:YES];
}
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->actionSheet = nil;
}
}]];
[actionSheet popoverPresentationController].sourceView = self.voiceCallButton;
[actionSheet popoverPresentationController].sourceRect = self.voiceCallButton.bounds;
[self.window.rootViewController presentViewController:actionSheet animated:YES completion:nil];
}
}
else if (button == self.hangupCallButton)
{
if ([self.delegate respondsToSelector:@selector(roomInputToolbarViewHangupCall:)])
{
[self.delegate roomInputToolbarViewHangupCall:self];
}
}
[super onTouchUpInside:button];
}
- (void)showMediaPicker
{
// MediaPickerViewController is based on the Photos framework. So it is available only for iOS 8 and later.
Class PHAsset_class = NSClassFromString(@"PHAsset");
if (PHAsset_class)
{
mediaPicker = [MediaPickerViewController mediaPickerViewController];
mediaPicker.mediaTypes = @[(NSString *)kUTTypeImage, (NSString *)kUTTypeMovie];
mediaPicker.delegate = self;
UINavigationController *navigationController = [UINavigationController new];
[navigationController pushViewController:mediaPicker animated:NO];
[self.delegate roomInputToolbarView:self presentViewController:navigationController];
}
else
{
// We use UIImagePickerController by default for iOS < 8
self.leftInputToolbarButton = self.attachMediaButton;
[super onTouchUpInside:self.leftInputToolbarButton];
}
}
- (void)destroy
{
[self dismissMediaPicker];
if (actionSheet)
{
[actionSheet dismissViewControllerAnimated:NO completion:nil];
actionSheet = nil;
}
[super destroy];
}
#pragma mark - MediaPickerViewController Delegate
- (void)mediaPickerController:(MediaPickerViewController *)mediaPickerController didSelectImage:(NSData*)imageData withMimeType:(NSString *)mimetype isPhotoLibraryAsset:(BOOL)isPhotoLibraryAsset
{
[self dismissMediaPicker];
[self sendSelectedImage:imageData withMimeType:mimetype andCompressionMode:MXKRoomInputToolbarCompressionModePrompt isPhotoLibraryAsset:isPhotoLibraryAsset];
}
- (void)mediaPickerController:(MediaPickerViewController *)mediaPickerController didSelectVideo:(NSURL*)videoURL
{
[self dismissMediaPicker];
BOOL isPhotoLibraryAsset = ![videoURL.path hasPrefix:NSTemporaryDirectory()];
[self sendSelectedVideo:videoURL isPhotoLibraryAsset:isPhotoLibraryAsset];
}
- (void)mediaPickerController:(MediaPickerViewController *)mediaPickerController didSelectAssets:(NSArray<PHAsset*>*)assets
{
[self dismissMediaPicker];
[self sendSelectedAssets:assets withCompressionMode:MXKRoomInputToolbarCompressionModePrompt];
}
#pragma mark - Media picker handling
- (void)dismissMediaPicker
{
if (mediaPicker)
{
[mediaPicker withdrawViewControllerAnimated:YES completion:nil];
[mediaPicker destroy];
mediaPicker = nil;
}
}
#pragma mark - Clipboard - Handle image/data paste from general pasteboard
- (void)paste:(id)sender
{
// TODO Custom here the validation screen for each available item
[super paste:sender];
}
@end
@@ -0,0 +1,184 @@
<?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"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="RoomInputToolbarView">
<rect key="frame" x="0.0" y="0.0" width="600" height="46"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="a84-Vc-6ud" userLabel="MainToolBar View">
<rect key="frame" x="0.0" y="0.0" width="600" height="46"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3ln-yI-ef9" userLabel="Separator View">
<rect key="frame" x="10" y="0.0" width="580" height="1"/>
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="WBM-ts-zPX"/>
</constraints>
</view>
<view clipsSubviews="YES" contentMode="scaleAspectFill" translatesAutoresizingMaskIntoConstraints="NO" id="dd4-pE-Es1" userLabel="Picture View" customClass="MXKImageView">
<rect key="frame" x="13" y="8" width="30" height="30"/>
<color key="backgroundColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="PictureView"/>
<constraints>
<constraint firstAttribute="width" constant="30" id="gwh-Qs-gY1"/>
<constraint firstAttribute="height" constant="30" id="wMB-Ec-D9s"/>
</constraints>
</view>
<imageView userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="e2e_unencrypted.png" translatesAutoresizingMaskIntoConstraints="NO" id="fRI-9x-jgw">
<rect key="frame" x="41" y="7" width="28" height="28"/>
<accessibility key="accessibilityConfiguration" identifier="EncryptedRoomIcon"/>
<constraints>
<constraint firstAttribute="height" constant="28" id="JHs-nc-tML"/>
<constraint firstAttribute="width" constant="28" id="K0H-Va-ZsL"/>
</constraints>
</imageView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="QWp-NV-uh5" userLabel="Message Composer Container">
<rect key="frame" x="62" y="4" width="443" height="38"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wgb-ON-N29" customClass="KeyboardGrowingTextView">
<rect key="frame" x="0.0" y="0.0" width="443" height="38"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="GrowingTextView"/>
</view>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="wgb-ON-N29" firstAttribute="top" secondItem="QWp-NV-uh5" secondAttribute="top" id="0jt-Ye-2DW"/>
<constraint firstAttribute="trailing" secondItem="wgb-ON-N29" secondAttribute="trailing" id="30f-rE-CKj"/>
<constraint firstItem="wgb-ON-N29" firstAttribute="leading" secondItem="QWp-NV-uh5" secondAttribute="leading" id="N7q-ch-iRz"/>
<constraint firstAttribute="bottom" secondItem="wgb-ON-N29" secondAttribute="bottom" id="fFG-SH-Hjh"/>
</constraints>
</view>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="G8Z-CM-tGs" userLabel="send Button">
<rect key="frame" x="550" y="0.0" width="46" height="46"/>
<accessibility key="accessibilityConfiguration" identifier="SendButton"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="46" id="KnT-92-5v2"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="15"/>
<state key="normal" title="Send"/>
<connections>
<action selector="onTouchUpInside:" destination="iN0-l3-epB" eventType="touchUpInside" id="Y9g-uz-rAz"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Hga-l8-Wua" userLabel="attach Button">
<rect key="frame" x="508" y="0.0" width="46" height="46"/>
<accessibility key="accessibilityConfiguration" identifier="AttachButton"/>
<constraints>
<constraint firstAttribute="width" constant="46" id="O2T-T8-EjV"/>
<constraint firstAttribute="width" secondItem="Hga-l8-Wua" secondAttribute="height" multiplier="1:1" id="f0T-3f-BJu"/>
</constraints>
<state key="normal" image="upload_icon.png"/>
<state key="highlighted" image="upload_icon.png"/>
<connections>
<action selector="onTouchUpInside:" destination="iN0-l3-epB" eventType="touchUpInside" id="WbU-WH-gwL"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Owf-M8-qJi" userLabel="voice call Button">
<rect key="frame" x="554" y="0.0" width="46" height="46"/>
<accessibility key="accessibilityConfiguration" identifier="VoiceCallButton"/>
<constraints>
<constraint firstAttribute="width" secondItem="Owf-M8-qJi" secondAttribute="height" multiplier="1:1" id="1Ni-y7-Nsa"/>
<constraint firstAttribute="width" constant="46" id="9FZ-CI-diT"/>
</constraints>
<state key="normal" image="voice_call_icon.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="voice_call_icon.png"/>
<connections>
<action selector="onTouchUpInside:" destination="iN0-l3-epB" eventType="touchUpInside" id="Cxg-BO-TfK"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="2nY-YP-BvA" userLabel="hangup call Button">
<rect key="frame" x="554" y="0.0" width="46" height="46"/>
<accessibility key="accessibilityConfiguration" identifier="HangupCallButton"/>
<constraints>
<constraint firstAttribute="width" secondItem="2nY-YP-BvA" secondAttribute="height" multiplier="1:1" id="59L-Jf-tXO"/>
</constraints>
<state key="normal" image="call_hangup_icon.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" image="call_hangup_icon.png"/>
<connections>
<action selector="onTouchUpInside:" destination="iN0-l3-epB" eventType="touchUpInside" id="PB3-d8-Kbf"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="fRI-9x-jgw" firstAttribute="top" secondItem="a84-Vc-6ud" secondAttribute="top" constant="7" id="08y-JY-NN5"/>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="46" id="1FO-iu-urG"/>
<constraint firstItem="G8Z-CM-tGs" firstAttribute="top" secondItem="a84-Vc-6ud" secondAttribute="top" id="8cV-eb-Kog"/>
<constraint firstItem="3ln-yI-ef9" firstAttribute="leading" secondItem="a84-Vc-6ud" secondAttribute="leading" constant="10" id="BwP-sF-qE1"/>
<constraint firstItem="QWp-NV-uh5" firstAttribute="leading" secondItem="a84-Vc-6ud" secondAttribute="leading" constant="62" id="ErD-eB-stF"/>
<constraint firstItem="Owf-M8-qJi" firstAttribute="leading" secondItem="Hga-l8-Wua" secondAttribute="trailing" id="GKh-R5-jqV"/>
<constraint firstItem="fRI-9x-jgw" firstAttribute="leading" secondItem="a84-Vc-6ud" secondAttribute="leading" constant="41" id="GvU-rY-bWW"/>
<constraint firstItem="dd4-pE-Es1" firstAttribute="leading" secondItem="a84-Vc-6ud" secondAttribute="leading" constant="13" id="Jem-U2-oEq"/>
<constraint firstAttribute="bottom" secondItem="QWp-NV-uh5" secondAttribute="bottom" constant="4" id="NGr-2o-sOP"/>
<constraint firstAttribute="trailing" secondItem="3ln-yI-ef9" secondAttribute="trailing" constant="10" id="RXB-PN-3n8"/>
<constraint firstAttribute="trailing" secondItem="G8Z-CM-tGs" secondAttribute="trailing" constant="4" id="Sua-LC-3yW"/>
<constraint firstAttribute="bottom" secondItem="Owf-M8-qJi" secondAttribute="bottom" id="Wo7-Qc-PSL"/>
<constraint firstItem="QWp-NV-uh5" firstAttribute="top" secondItem="a84-Vc-6ud" secondAttribute="top" constant="4" id="WyZ-3i-OHi"/>
<constraint firstAttribute="height" constant="46" id="Yjj-ua-rbe"/>
<constraint firstAttribute="bottom" secondItem="2nY-YP-BvA" secondAttribute="bottom" id="asf-hj-bby"/>
<constraint firstAttribute="trailing" secondItem="2nY-YP-BvA" secondAttribute="trailing" id="gNM-BS-Uwc"/>
<constraint firstAttribute="trailing" secondItem="QWp-NV-uh5" secondAttribute="trailing" constant="95" id="hXO-cY-Jgz"/>
<constraint firstItem="2nY-YP-BvA" firstAttribute="width" secondItem="Owf-M8-qJi" secondAttribute="width" id="mHj-eR-atg"/>
<constraint firstItem="Hga-l8-Wua" firstAttribute="top" secondItem="a84-Vc-6ud" secondAttribute="top" id="pPH-Fp-phr"/>
<constraint firstAttribute="trailing" secondItem="Owf-M8-qJi" secondAttribute="trailing" id="vCd-Md-dvr"/>
<constraint firstAttribute="bottom" secondItem="G8Z-CM-tGs" secondAttribute="bottom" id="vpk-lw-TnO"/>
<constraint firstItem="dd4-pE-Es1" firstAttribute="top" secondItem="a84-Vc-6ud" secondAttribute="top" constant="8" id="xjT-If-1cd"/>
<constraint firstItem="3ln-yI-ef9" firstAttribute="top" secondItem="a84-Vc-6ud" secondAttribute="top" id="yUF-5t-x03"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="RoomInputToolbarView"/>
<constraints>
<constraint firstItem="a84-Vc-6ud" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="VBS-kE-WiP"/>
<constraint firstAttribute="trailing" secondItem="a84-Vc-6ud" secondAttribute="trailing" id="cNb-nJ-iAI"/>
<constraint firstAttribute="bottom" secondItem="a84-Vc-6ud" secondAttribute="bottom" id="jFc-lW-hpZ"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<nil key="simulatedTopBarMetrics"/>
<nil key="simulatedBottomBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<connections>
<outlet property="attachMediaButton" destination="Hga-l8-Wua" id="Osr-ek-c91"/>
<outlet property="encryptedRoomIcon" destination="fRI-9x-jgw" id="cfG-Sr-Fga"/>
<outlet property="growingTextView" destination="wgb-ON-N29" id="nwF-uV-Ng9"/>
<outlet property="hangupCallButton" destination="2nY-YP-BvA" id="a0m-xv-sVg"/>
<outlet property="mainToolbarHeightConstraint" destination="Yjj-ua-rbe" id="Lu8-UC-Vbo"/>
<outlet property="mainToolbarMinHeightConstraint" destination="1FO-iu-urG" id="2U6-h2-0zQ"/>
<outlet property="mainToolbarView" destination="a84-Vc-6ud" id="5p3-Ft-0gv"/>
<outlet property="messageComposerContainer" destination="QWp-NV-uh5" id="APR-B5-ogC"/>
<outlet property="messageComposerContainerBottomConstraint" destination="NGr-2o-sOP" id="oez-6D-IKA"/>
<outlet property="messageComposerContainerLeadingConstraint" destination="ErD-eB-stF" id="Ha9-DG-Nw2"/>
<outlet property="messageComposerContainerTopConstraint" destination="WyZ-3i-OHi" id="OcO-1f-bNA"/>
<outlet property="messageComposerContainerTrailingConstraint" destination="hXO-cY-Jgz" id="lHZ-MU-vyC"/>
<outlet property="pictureView" destination="dd4-pE-Es1" id="rb6-z2-pJ9"/>
<outlet property="rightInputToolbarButton" destination="G8Z-CM-tGs" id="NCk-5m-aNF"/>
<outlet property="separatorView" destination="3ln-yI-ef9" id="HQ3-B4-Goj"/>
<outlet property="voiceCallButton" destination="Owf-M8-qJi" id="krT-w1-mfT"/>
<outlet property="voiceCallButtonWidthConstraint" destination="9FZ-CI-diT" id="jYt-Pe-8DY"/>
</connections>
</view>
</objects>
<resources>
<image name="call_hangup_icon.png" width="26" height="27"/>
<image name="e2e_unencrypted.png" width="14" height="12"/>
<image name="upload_icon.png" width="21" height="26"/>
<image name="voice_call_icon.png" width="24" height="27"/>
</resources>
</document>