element-ios/Vector/Views/RoomInputToolbar/RoomInputToolbarView.m

315 lines
12 KiB
Mathematica
Raw Normal View History

2015-08-18 08:04:30 +00:00
/*
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 "RoomInputToolbarView.h"
#import <MediaPlayer/MediaPlayer.h>
#import <Photos/Photos.h>
2015-08-18 08:04:30 +00:00
@interface RoomInputToolbarView()
{
MediaPickerViewController *mediaPicker;
}
@end
@implementation RoomInputToolbarView
+ (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];
2015-08-18 14:24:48 +00:00
// Remove default toolbar background color
self.backgroundColor = [UIColor whiteColor];
self.startVoiceCallLabel.text = NSLocalizedStringFromTable(@"room_option_start_group_voice", @"Vector", nil);
self.startVoiceCallLabel.numberOfLines = 0;
self.startVideoCallLabel.text = NSLocalizedStringFromTable(@"room_option_start_group_video", @"Vector", nil);
self.startVideoCallLabel.numberOfLines = 0;
self.shareLocationLabel.text = NSLocalizedStringFromTable(@"room_option_share_location", @"Vector", nil);
self.shareLocationLabel.numberOfLines = 0;
self.shareContactLabel.text = NSLocalizedStringFromTable(@"room_option_share_contact", @"Vector", nil);
self.shareContactLabel.numberOfLines = 0;
2015-08-18 08:04:30 +00:00
self.rightInputToolbarButton.hidden = YES;
2015-08-18 08:04:30 +00:00
}
#pragma mark - HPGrowingTextView delegate
2015-08-18 08:51:28 +00:00
- (BOOL)growingTextViewShouldReturn:(HPGrowingTextView *)growingTextView
2015-08-18 08:04:30 +00:00
{
2015-08-18 08:51:28 +00:00
// The return sends the message rather than giving a carriage return.
[self onTouchUpInside:self.rightInputToolbarButton];
2015-08-18 08:04:30 +00:00
2015-08-18 08:51:28 +00:00
return NO;
2015-08-18 08:04:30 +00:00
}
2015-08-18 08:51:28 +00:00
- (void)growingTextViewDidChange:(HPGrowingTextView *)growingTextView
2015-08-18 08:04:30 +00:00
{
2015-08-18 08:51:28 +00:00
// Clean the carriage return added on return press
if ([self.textMessage isEqualToString:@"\n"])
2015-08-18 08:04:30 +00:00
{
2015-08-18 08:51:28 +00:00
self.textMessage = nil;
2015-08-18 08:04:30 +00:00
}
2015-08-18 08:51:28 +00:00
[super growingTextViewDidChange:growingTextView];
if (self.rightInputToolbarButton.isEnabled && self.rightInputToolbarButton.isHidden)
{
self.rightInputToolbarButton.hidden = NO;
self.attachMediaButton.hidden = YES;
self.optionMenuButton.hidden = YES;
if (self.optionMenuView.isHidden == NO)
{
// Hide option menu
[self onTouchUpInside:self.optionMenuButton];
}
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.optionMenuButton.hidden = NO;
self.messageComposerContainerTrailingConstraint.constant = self.frame.size.width - self.attachMediaButton.frame.origin.x + 4;
}
2015-08-18 08:04:30 +00:00
}
2015-08-18 14:24:48 +00:00
- (void)growingTextView:(HPGrowingTextView *)growingTextView willChangeHeight:(float)height
{
// Update height of the main toolbar (message composer)
self.mainToolbarHeightConstraint.constant = height + (self.messageComposerContainerTopConstraint.constant + self.messageComposerContainerBottomConstraint.constant);
// Compute height of the whole toolbar (including potential option menu)
CGFloat updatedHeight = self.mainToolbarHeightConstraint.constant;
if (self.optionMenuView.isHidden == NO)
{
updatedHeight += self.optionMenuView.frame.size.height;
}
2015-08-18 14:24:48 +00:00
// Update toolbar superview
if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:heightDidChanged:completion:)])
{
[self.delegate roomInputToolbarView:self heightDidChanged:updatedHeight completion:nil];
}
2015-08-18 14:24:48 +00:00
}
2015-08-18 08:04:30 +00:00
#pragma mark - Override MXKRoomInputToolbarView
- (IBAction)onTouchUpInside:(UIButton*)button
{
2015-08-18 08:51:28 +00:00
if (button == self.attachMediaButton)
2015-08-18 08:04:30 +00:00
{
// Check whether media attachment is supported
if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:presentViewController:)])
{
// 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.multipleSelections = YES;
mediaPicker.selectionButtonCustomLabel = NSLocalizedStringFromTable(@"media_picker_attach", @"Vector", nil);
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];
}
2015-08-18 08:04:30 +00:00
}
else
{
NSLog(@"[RoomInputToolbarView] Attach media is not supported");
}
}
2015-08-18 08:51:28 +00:00
else if (button == self.optionMenuButton)
2015-08-18 08:04:30 +00:00
{
// Compute the height of the whole toolbar (message composer + option menu (if any))
CGFloat updatedHeight = self.mainToolbarHeightConstraint.constant;
BOOL hideOptionMenuView = !self.optionMenuView.isHidden;
2015-08-18 14:24:48 +00:00
if (self.optionMenuView.isHidden)
{
// The option menu will appear
updatedHeight += self.optionMenuView.frame.size.height;
self.optionMenuView.hidden = NO;
2015-08-18 14:24:48 +00:00
}
// Update toolbar superview
if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:heightDidChanged:completion:)])
2015-08-18 14:24:48 +00:00
{
[self.delegate roomInputToolbarView:self heightDidChanged:updatedHeight completion:^(BOOL finished) {
if (hideOptionMenuView)
{
self.optionMenuView.hidden = YES;
}
}];
2015-08-18 14:24:48 +00:00
}
// Refresh max height of the growning text
self.maxHeight = self.maxHeight;
}
else if (button == self.startVoiceCallButton)
{
if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:placeCallWithVideo:)])
{
[self.delegate roomInputToolbarView:self placeCallWithVideo:NO];
}
2015-08-19 09:05:47 +00:00
// Hide option menu
[self onTouchUpInside:self.optionMenuButton];
2015-08-18 14:24:48 +00:00
}
else if (button == self.startVideoCallButton)
{
if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:placeCallWithVideo:)])
{
[self.delegate roomInputToolbarView:self placeCallWithVideo:YES];
}
2015-08-19 09:05:47 +00:00
// Hide option menu
[self onTouchUpInside:self.optionMenuButton];
2015-08-18 14:24:48 +00:00
}
else if (button == self.shareLocationButton)
{
// TODO
2015-08-19 09:05:47 +00:00
// Hide option menu
[self onTouchUpInside:self.optionMenuButton];
2015-08-18 14:24:48 +00:00
}
else if (button == self.shareContactButton)
{
// TODO
2015-08-19 09:05:47 +00:00
// Hide option menu
[self onTouchUpInside:self.optionMenuButton];
2015-08-18 08:04:30 +00:00
}
2015-08-18 08:51:28 +00:00
[super onTouchUpInside:button];
2015-08-18 08:04:30 +00:00
}
- (void)destroy
{
[self dismissMediaPicker];
2015-08-18 08:04:30 +00:00
[super destroy];
}
#pragma mark - MediaPickerViewController Delegate
2015-08-18 08:04:30 +00:00
- (void)mediaPickerController:(MediaPickerViewController *)mediaPickerController didSelectImage:(UIImage*)image withURL:(NSURL *)imageURL
{
[self dismissMediaPicker];
[self sendSelectedImage:image withCompressionMode:MXKRoomInputToolbarCompressionModePrompt andLocalURL:imageURL];
}
- (void)mediaPickerController:(MediaPickerViewController *)mediaPickerController didSelectVideo:(NSURL*)videoURL isCameraRecording:(BOOL)isCameraRecording
{
[self dismissMediaPicker];
[self sendSelectedVideo:videoURL isCameraRecording:isCameraRecording];
}
- (void)mediaPickerController:(MediaPickerViewController *)mediaPickerController didSelectAssets:(NSArray *)assets
{
[self dismissMediaPicker];
// We don't prompt user about image compression if several items have been selected
MXKRoomInputToolbarCompressionMode imageCompressionMode = (assets.count > 1) ? MXKRoomInputToolbarCompressionModeMedium : MXKRoomInputToolbarCompressionModePrompt;
PHContentEditingInputRequestOptions *editOptions = [[PHContentEditingInputRequestOptions alloc] init];
for (NSUInteger index = 0; index < assets.count; index++)
{
PHAsset *asset = assets[index];
[asset requestContentEditingInputWithOptions:editOptions
completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
if (contentEditingInput.mediaType == PHAssetMediaTypeImage)
{
// Here the fullSizeImageURL is related to a local file path
NSData *data = [NSData dataWithContentsOfURL:contentEditingInput.fullSizeImageURL];
UIImage *image = [UIImage imageWithData:data];
[self sendSelectedImage:image withCompressionMode:imageCompressionMode andLocalURL:contentEditingInput.fullSizeImageURL];
}
else if (contentEditingInput.mediaType == PHAssetMediaTypeVideo)
{
if ([contentEditingInput.avAsset isKindOfClass:[AVURLAsset class]])
{
AVURLAsset *avURLAsset = (AVURLAsset*)contentEditingInput.avAsset;
[self sendSelectedVideo:[avURLAsset URL] isCameraRecording:NO];
}
else
{
NSLog(@"[RoomInputToolbarView] Selected video asset is not initialized from an URL!");
}
}
}];
}
}
2015-08-18 08:04:30 +00:00
#pragma mark - Media picker handling
- (void)dismissMediaPicker
{
if (mediaPicker)
{
[mediaPicker withdrawViewControllerAnimated:YES completion:nil];
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];
}
2015-08-18 08:04:30 +00:00
@end