diff --git a/Vector.xcodeproj/project.pbxproj b/Vector.xcodeproj/project.pbxproj index 7dcc13148..71cf842c5 100644 --- a/Vector.xcodeproj/project.pbxproj +++ b/Vector.xcodeproj/project.pbxproj @@ -7,6 +7,16 @@ objects = { /* Begin PBXBuildFile section */ + F001D75E1B8207C000A162C3 /* RoomIncomingBubbleTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F001D7551B8207C000A162C3 /* RoomIncomingBubbleTableViewCell.m */; }; + F001D75F1B8207C000A162C3 /* RoomIncomingBubbleTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F001D7561B8207C000A162C3 /* RoomIncomingBubbleTableViewCell.xib */; }; + F001D7601B8207C000A162C3 /* RoomOutgoingBubbleTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F001D7581B8207C000A162C3 /* RoomOutgoingBubbleTableViewCell.m */; }; + F001D7611B8207C000A162C3 /* RoomOutgoingBubbleTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F001D7591B8207C000A162C3 /* RoomOutgoingBubbleTableViewCell.xib */; }; + F001D7621B8207C000A162C3 /* RoomInputToolbarView.m in Sources */ = {isa = PBXBuildFile; fileRef = F001D75C1B8207C000A162C3 /* RoomInputToolbarView.m */; }; + F001D7631B8207C000A162C3 /* RoomInputToolbarView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F001D75D1B8207C000A162C3 /* RoomInputToolbarView.xib */; }; + F001D7661B82198B00A162C3 /* attach_media.png in Resources */ = {isa = PBXBuildFile; fileRef = F001D7641B82198B00A162C3 /* attach_media.png */; }; + F001D7691B821A8500A162C3 /* send.png in Resources */ = {isa = PBXBuildFile; fileRef = F001D7681B821A8500A162C3 /* send.png */; }; + F001D76C1B821E4F00A162C3 /* MediaPickerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F001D76B1B821E4F00A162C3 /* MediaPickerViewController.m */; }; + F001D76E1B83156000A162C3 /* MediaPickerViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F001D76D1B83156000A162C3 /* MediaPickerViewController.xib */; }; F02D87C69D1FFCD2C1531F3D /* libPods-Vector.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B179239B79688A61A3F465F /* libPods-Vector.a */; }; F0316E3A1B7DF45A00F03620 /* add.png in Resources */ = {isa = PBXBuildFile; fileRef = F0316E381B7DF45A00F03620 /* add.png */; }; F0316E3B1B7DF45A00F03620 /* add@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F0316E391B7DF45A00F03620 /* add@2x.png */; }; @@ -75,6 +85,20 @@ 11865E69C29698A4179E1F3F /* Pods-Vector.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Vector.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Vector/Pods-Vector.debug.xcconfig"; sourceTree = ""; }; 435C7E1A9BC3DE28D526540F /* Pods-Vector.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Vector.release.xcconfig"; path = "Pods/Target Support Files/Pods-Vector/Pods-Vector.release.xcconfig"; sourceTree = ""; }; 9B179239B79688A61A3F465F /* libPods-Vector.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Vector.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + F001D7541B8207C000A162C3 /* RoomIncomingBubbleTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomIncomingBubbleTableViewCell.h; sourceTree = ""; }; + F001D7551B8207C000A162C3 /* RoomIncomingBubbleTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RoomIncomingBubbleTableViewCell.m; sourceTree = ""; }; + F001D7561B8207C000A162C3 /* RoomIncomingBubbleTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RoomIncomingBubbleTableViewCell.xib; sourceTree = ""; }; + F001D7571B8207C000A162C3 /* RoomOutgoingBubbleTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomOutgoingBubbleTableViewCell.h; sourceTree = ""; }; + F001D7581B8207C000A162C3 /* RoomOutgoingBubbleTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RoomOutgoingBubbleTableViewCell.m; sourceTree = ""; }; + F001D7591B8207C000A162C3 /* RoomOutgoingBubbleTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RoomOutgoingBubbleTableViewCell.xib; sourceTree = ""; }; + F001D75B1B8207C000A162C3 /* RoomInputToolbarView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomInputToolbarView.h; sourceTree = ""; }; + F001D75C1B8207C000A162C3 /* RoomInputToolbarView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RoomInputToolbarView.m; sourceTree = ""; }; + F001D75D1B8207C000A162C3 /* RoomInputToolbarView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RoomInputToolbarView.xib; sourceTree = ""; }; + F001D7641B82198B00A162C3 /* attach_media.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = attach_media.png; sourceTree = ""; }; + F001D7681B821A8500A162C3 /* send.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = send.png; sourceTree = ""; }; + F001D76A1B821E4F00A162C3 /* MediaPickerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPickerViewController.h; sourceTree = ""; }; + F001D76B1B821E4F00A162C3 /* MediaPickerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MediaPickerViewController.m; sourceTree = ""; }; + F001D76D1B83156000A162C3 /* MediaPickerViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MediaPickerViewController.xib; sourceTree = ""; }; F0316E381B7DF45A00F03620 /* add.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = add.png; sourceTree = ""; }; F0316E391B7DF45A00F03620 /* add@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "add@2x.png"; sourceTree = ""; }; F0316E3C1B7E28DE00F03620 /* remove.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = remove.png; sourceTree = ""; }; @@ -181,6 +205,38 @@ name = Pods; sourceTree = ""; }; + F001D7521B8207C000A162C3 /* Views */ = { + isa = PBXGroup; + children = ( + F001D7531B8207C000A162C3 /* RoomBubbleList */, + F001D75A1B8207C000A162C3 /* RoomInputToolbar */, + ); + path = Views; + sourceTree = ""; + }; + F001D7531B8207C000A162C3 /* RoomBubbleList */ = { + isa = PBXGroup; + children = ( + F001D7541B8207C000A162C3 /* RoomIncomingBubbleTableViewCell.h */, + F001D7551B8207C000A162C3 /* RoomIncomingBubbleTableViewCell.m */, + F001D7561B8207C000A162C3 /* RoomIncomingBubbleTableViewCell.xib */, + F001D7571B8207C000A162C3 /* RoomOutgoingBubbleTableViewCell.h */, + F001D7581B8207C000A162C3 /* RoomOutgoingBubbleTableViewCell.m */, + F001D7591B8207C000A162C3 /* RoomOutgoingBubbleTableViewCell.xib */, + ); + path = RoomBubbleList; + sourceTree = ""; + }; + F001D75A1B8207C000A162C3 /* RoomInputToolbar */ = { + isa = PBXGroup; + children = ( + F001D75B1B8207C000A162C3 /* RoomInputToolbarView.h */, + F001D75C1B8207C000A162C3 /* RoomInputToolbarView.m */, + F001D75D1B8207C000A162C3 /* RoomInputToolbarView.xib */, + ); + path = RoomInputToolbar; + sourceTree = ""; + }; F094A9991B78D8F000B1FBBF = { isa = PBXGroup; children = ( @@ -209,6 +265,7 @@ F094AA101B78E42600B1FBBF /* Model */, F094AA131B78E42600B1FBBF /* Resources */, F094AA151B78E42600B1FBBF /* ViewController */, + F001D7521B8207C000A162C3 /* Views */, F094A9A91B78D8F000B1FBBF /* AppDelegate.h */, F094A9AA1B78D8F000B1FBBF /* AppDelegate.m */, F094A9B21B78D8F000B1FBBF /* Main.storyboard */, @@ -294,6 +351,9 @@ F094AA1D1B78E42600B1FBBF /* GlobalNotificationSettingsViewController.m */, F094AA201B78E42600B1FBBF /* MasterTabBarController.h */, F094AA211B78E42600B1FBBF /* MasterTabBarController.m */, + F001D76A1B821E4F00A162C3 /* MediaPickerViewController.h */, + F001D76B1B821E4F00A162C3 /* MediaPickerViewController.m */, + F001D76D1B83156000A162C3 /* MediaPickerViewController.xib */, F094AA221B78E42600B1FBBF /* RecentsViewController.h */, F094AA231B78E42600B1FBBF /* RecentsViewController.m */, F0DD7D801B7B363300C4BE02 /* RoomCreationStep1ViewController.h */, @@ -313,6 +373,8 @@ F0DD7D1B1B7AA8C900C4BE02 /* Images */ = { isa = PBXGroup; children = ( + F001D7681B821A8500A162C3 /* send.png */, + F001D7641B82198B00A162C3 /* attach_media.png */, F0316E451B7E4C9A00F03620 /* placeholder.png */, F0316E461B7E4C9A00F03620 /* placeholder@2x.png */, F0316E3C1B7E28DE00F03620 /* remove.png */, @@ -427,24 +489,29 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + F001D7631B8207C000A162C3 /* RoomInputToolbarView.xib in Resources */, F0DD7D651B7AA8C900C4BE02 /* logo@2x.png in Resources */, F0DD7D611B7AA8C900C4BE02 /* hide@2x.png in Resources */, F0DD7D751B7AA8C900C4BE02 /* typing@2x.png in Resources */, F0316E3A1B7DF45A00F03620 /* add.png in Resources */, F0DD7D671B7AA8C900C4BE02 /* members@2x.png in Resources */, F0DD7D721B7AA8C900C4BE02 /* tab_settings.png in Resources */, + F001D7611B8207C000A162C3 /* RoomOutgoingBubbleTableViewCell.xib in Resources */, F0DD7D7B1B7AA8C900C4BE02 /* voip@2x.png in Resources */, F094AA2E1B78E42600B1FBBF /* countryCodes.plist in Resources */, F0DD7D7E1B7AAA3C00C4BE02 /* icon_users.png in Resources */, F094AA2B1B78E42600B1FBBF /* Localizable.strings in Resources */, F0DD7D4C1B7AA8C900C4BE02 /* attach.png in Resources */, F0316E3E1B7E28DE00F03620 /* remove.png in Resources */, + F001D76E1B83156000A162C3 /* MediaPickerViewController.xib in Resources */, F0316E3F1B7E28DE00F03620 /* remove@2x.png in Resources */, F0DD7D691B7AA8C900C4BE02 /* menu@2x.png in Resources */, F0DD7D731B7AA8C900C4BE02 /* tab_settings@2x.png in Resources */, F0316E481B7E4C9A00F03620 /* placeholder@2x.png in Resources */, + F001D75F1B8207C000A162C3 /* RoomIncomingBubbleTableViewCell.xib in Resources */, F0DD7D641B7AA8C900C4BE02 /* logo.png in Resources */, F0316E3B1B7DF45A00F03620 /* add@2x.png in Resources */, + F001D7691B821A8500A162C3 /* send.png in Resources */, F0DD7D7F1B7AAA3C00C4BE02 /* icon_users@2x.png in Resources */, F094A9B41B78D8F000B1FBBF /* Main.storyboard in Resources */, F0316E471B7E4C9A00F03620 /* placeholder.png in Resources */, @@ -454,6 +521,7 @@ F0DD7D7A1B7AA8C900C4BE02 /* voip.png in Resources */, F094A9B91B78D8F000B1FBBF /* LaunchScreen.xib in Resources */, F094A9B61B78D8F000B1FBBF /* Images.xcassets in Resources */, + F001D7661B82198B00A162C3 /* attach_media.png in Resources */, F0DD7D6D1B7AA8C900C4BE02 /* search@2x.png in Resources */, F0DD7D791B7AA8C900C4BE02 /* video@2x.png in Resources */, F0DD7D661B7AA8C900C4BE02 /* members.png in Resources */, @@ -516,6 +584,8 @@ F094A9AB1B78D8F000B1FBBF /* AppDelegate.m in Sources */, F094AA2F1B78E42600B1FBBF /* AccountDetailsViewController.m in Sources */, F094AA051B78E3D400B1FBBF /* empty.mm in Sources */, + F001D76C1B821E4F00A162C3 /* MediaPickerViewController.m in Sources */, + F001D75E1B8207C000A162C3 /* RoomIncomingBubbleTableViewCell.m in Sources */, F094AA321B78E42600B1FBBF /* GlobalNotificationSettingsViewController.m in Sources */, F094A9A81B78D8F000B1FBBF /* main.m in Sources */, F0DD7D881B7B507100C4BE02 /* RoomCreationStep2ViewController.m in Sources */, @@ -523,6 +593,8 @@ F094AA2D1B78E42600B1FBBF /* RecentListDataSource.m in Sources */, F094AA2A1B78E42600B1FBBF /* RageShakeManager.m in Sources */, F094AA351B78E42600B1FBBF /* RecentsViewController.m in Sources */, + F001D7621B8207C000A162C3 /* RoomInputToolbarView.m in Sources */, + F001D7601B8207C000A162C3 /* RoomOutgoingBubbleTableViewCell.m in Sources */, F094AA371B78E42600B1FBBF /* RoomViewController.m in Sources */, F094AA381B78E42600B1FBBF /* SettingsViewController.m in Sources */, F094AA341B78E42600B1FBBF /* MasterTabBarController.m in Sources */, diff --git a/Vector/Assets/Images/attach_media.png b/Vector/Assets/Images/attach_media.png new file mode 100644 index 000000000..c70c5222f Binary files /dev/null and b/Vector/Assets/Images/attach_media.png differ diff --git a/Vector/Assets/Images/send.png b/Vector/Assets/Images/send.png new file mode 100644 index 000000000..c70c5222f Binary files /dev/null and b/Vector/Assets/Images/send.png differ diff --git a/Vector/ViewController/MediaPickerViewController.h b/Vector/ViewController/MediaPickerViewController.h new file mode 100644 index 000000000..1a70e9c0b --- /dev/null +++ b/Vector/ViewController/MediaPickerViewController.h @@ -0,0 +1,64 @@ +/* + 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 + +@class MediaPickerViewController; + +/** + `MediaPickerViewController` delegate. + */ +@protocol MediaPickerViewControllerDelegate + +/** + Tells the delegate. + + @param mediaPickerController the `MediaPickerViewController` instance. + @param . + */ +- (void)todo:(MediaPickerViewController *)mediaPickerController; + +@end + +/** + */ +@interface MediaPickerViewController : MXKViewController + +/** + * Returns the `UINib` object initialized for a `MediaPickerViewController`. + * + * @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 `MediaPickerViewController` object. + * + * @discussion This is the designated initializer for programmatic instantiation. + * + * @return An initialized `MediaPickerViewController` object if successful, `nil` otherwise. + */ ++ (instancetype)mediaPickerViewController; + +/** + The delegate for the view controller. + */ +@property (nonatomic) id delegate; + + +@end + diff --git a/Vector/ViewController/MediaPickerViewController.m b/Vector/ViewController/MediaPickerViewController.m new file mode 100644 index 000000000..bd0ad51fe --- /dev/null +++ b/Vector/ViewController/MediaPickerViewController.m @@ -0,0 +1,79 @@ +/* + 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 "MediaPickerViewController.h" + +@interface MediaPickerViewController () +{ + +} + +@end + +@implementation MediaPickerViewController + +#pragma mark - Class methods + ++ (UINib *)nib +{ + return [UINib nibWithNibName:NSStringFromClass([MediaPickerViewController class]) + bundle:[NSBundle bundleForClass:[MediaPickerViewController class]]]; +} + ++ (instancetype)mediaPickerViewController +{ + return [[[self class] alloc] initWithNibName:NSStringFromClass([MediaPickerViewController class]) + bundle:[NSBundle bundleForClass:[MediaPickerViewController class]]]; +} + + + +#pragma mark - + +- (void)viewDidLoad +{ + [super viewDidLoad]; + // Do any additional setup after loading the view, typically from a nib. +} + +- (void)dealloc +{ +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; +} + +- (void)viewWillDisappear:(BOOL)animated +{ + [super viewWillDisappear:animated]; +} + +#pragma mark - Override MXKViewController + +- (void)destroy +{ + [super destroy]; +} + +@end diff --git a/Vector/ViewController/MediaPickerViewController.xib b/Vector/ViewController/MediaPickerViewController.xib new file mode 100644 index 000000000..997cac451 --- /dev/null +++ b/Vector/ViewController/MediaPickerViewController.xib @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/Vector/ViewController/RoomViewController.m b/Vector/ViewController/RoomViewController.m index 1faf2aeca..35b5c417b 100644 --- a/Vector/ViewController/RoomViewController.m +++ b/Vector/ViewController/RoomViewController.m @@ -16,12 +16,11 @@ #import "RoomViewController.h" -#import "MXKRoomBubbleTableViewCell.h" - #import "AppDelegate.h" - #import "RageShakeManager.h" +#import "RoomInputToolbarView.h" + @interface RoomViewController () { // Members list @@ -52,8 +51,8 @@ // Set room title view [self setRoomTitleViewClass:MXKRoomTitleViewWithTopic.class]; - // Replace the default input toolbar view with the one based on `HPGrowingTextView`. - [self setRoomInputToolbarViewClass:MXKRoomInputToolbarViewWithHPGrowingText.class]; + // Replace the default input toolbar view. + [self setRoomInputToolbarViewClass:RoomInputToolbarView.class]; // Set rageShake handler self.rageShakeManager = [RageShakeManager sharedManager]; diff --git a/Vector/Views/RoomBubbleList/RoomIncomingBubbleTableViewCell.h b/Vector/Views/RoomBubbleList/RoomIncomingBubbleTableViewCell.h new file mode 100644 index 000000000..ae8322b70 --- /dev/null +++ b/Vector/Views/RoomBubbleList/RoomIncomingBubbleTableViewCell.h @@ -0,0 +1,24 @@ +/* + 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 + +/** + `RoomIncomingBubbleTableViewCell` displays incoming message bubbles. + */ +@interface RoomIncomingBubbleTableViewCell : MXKRoomIncomingBubbleTableViewCell + +@end diff --git a/Vector/Views/RoomBubbleList/RoomIncomingBubbleTableViewCell.m b/Vector/Views/RoomBubbleList/RoomIncomingBubbleTableViewCell.m new file mode 100644 index 000000000..f560fddb0 --- /dev/null +++ b/Vector/Views/RoomBubbleList/RoomIncomingBubbleTableViewCell.m @@ -0,0 +1,91 @@ +/* + 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 "RoomIncomingBubbleTableViewCell.h" + +#import "NSBundle+MatrixKit.h" + +#pragma mark - UI Constant definitions +#define MXKROOMBUBBLETABLEVIEWCELL_INCOMING_HEIGHT_REDUCTION_WHEN_SENDER_INFO_IS_HIDDEN -10 + +@implementation RoomIncomingBubbleTableViewCell + +- (void)awakeFromNib +{ + [super awakeFromNib]; + + self.typingBadge.image = [NSBundle mxk_imageFromMXKAssetsBundleWithName:@"icon_keyboard"]; +} + +- (void)render:(MXKCellData *)cellData +{ + [super render:cellData]; + + if (self.bubbleData) + { + // Check whether the previous message has been sent by the same user. + // The user's picture and name are displayed only for the first message. + // Handle sender's picture and adjust view's constraints + if (self.bubbleData.isSameSenderAsPreviousBubble) + { + self.pictureView.hidden = YES; + self.msgTextViewTopConstraint.constant = self.class.cellWithOriginalXib.msgTextViewTopConstraint.constant + MXKROOMBUBBLETABLEVIEWCELL_INCOMING_HEIGHT_REDUCTION_WHEN_SENDER_INFO_IS_HIDDEN; + self.attachViewTopConstraint.constant = self.class.cellWithOriginalXib.attachViewTopConstraint.constant + MXKROOMBUBBLETABLEVIEWCELL_INCOMING_HEIGHT_REDUCTION_WHEN_SENDER_INFO_IS_HIDDEN; + + if (!self.dateTimeLabelContainer.hidden) + { + self.dateTimeLabelContainerTopConstraint.constant += MXKROOMBUBBLETABLEVIEWCELL_INCOMING_HEIGHT_REDUCTION_WHEN_SENDER_INFO_IS_HIDDEN; + } + } + + // Display user's display name except if the name appears in the displayed text (see emote and membership event) + self.userNameLabel.hidden = (self.bubbleData.isSameSenderAsPreviousBubble || self.bubbleData.startsWithSenderName); + self.userNameLabel.text = self.bubbleData.senderDisplayName; + // Set typing badge visibility + self.typingBadge.hidden = (self.pictureView.hidden || !self.bubbleData.isTyping); + if (!self.typingBadge.hidden) + { + [self.typingBadge.superview bringSubviewToFront:self.typingBadge]; + } + } +} + ++ (CGFloat)heightForCellData:(MXKCellData *)cellData withMaximumWidth:(CGFloat)maxWidth +{ + CGFloat rowHeight = [super heightForCellData:cellData withMaximumWidth:maxWidth]; + + MXKRoomBubbleCellData *bubbleData = (MXKRoomBubbleCellData*)cellData; + + // Check whether the previous message has been sent by the same user. + // The user's picture and name are displayed only for the first message. + if (bubbleData.isSameSenderAsPreviousBubble) + { + // Reduce top margin -> row height reduction + rowHeight += MXKROOMBUBBLETABLEVIEWCELL_INCOMING_HEIGHT_REDUCTION_WHEN_SENDER_INFO_IS_HIDDEN; + } + else + { + // We consider a minimun cell height in order to display correctly user's picture + if (rowHeight < self.cellWithOriginalXib.frame.size.height) + { + rowHeight = self.cellWithOriginalXib.frame.size.height; + } + } + + return rowHeight; +} + +@end diff --git a/Vector/Views/RoomBubbleList/RoomIncomingBubbleTableViewCell.xib b/Vector/Views/RoomBubbleList/RoomIncomingBubbleTableViewCell.xib new file mode 100644 index 000000000..e4247d558 --- /dev/null +++ b/Vector/Views/RoomBubbleList/RoomIncomingBubbleTableViewCell.xib @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Vector/Views/RoomBubbleList/RoomOutgoingBubbleTableViewCell.h b/Vector/Views/RoomBubbleList/RoomOutgoingBubbleTableViewCell.h new file mode 100644 index 000000000..ccbec7710 --- /dev/null +++ b/Vector/Views/RoomBubbleList/RoomOutgoingBubbleTableViewCell.h @@ -0,0 +1,24 @@ +/* + 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 + +/** + `RoomOutgoingBubbleTableViewCell` displays outgoing message bubbles. + */ +@interface RoomOutgoingBubbleTableViewCell : MXKRoomOutgoingBubbleTableViewCell + +@end diff --git a/Vector/Views/RoomBubbleList/RoomOutgoingBubbleTableViewCell.m b/Vector/Views/RoomBubbleList/RoomOutgoingBubbleTableViewCell.m new file mode 100644 index 000000000..cd98d02f0 --- /dev/null +++ b/Vector/Views/RoomBubbleList/RoomOutgoingBubbleTableViewCell.m @@ -0,0 +1,221 @@ +/* + 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 "RoomOutgoingBubbleTableViewCell.h" + +#pragma mark - UI Constant definitions +#define MXKROOMBUBBLETABLEVIEWCELL_OUTGOING_HEIGHT_REDUCTION_WHEN_SENDER_INFO_IS_HIDDEN -10 + +@implementation RoomOutgoingBubbleTableViewCell + +- (void)dealloc +{ + [self stopAnimating]; +} + +- (void)render:(MXKCellData *)cellData +{ + [super render:cellData]; + + if (self.bubbleData) + { + // Check whether the previous message has been sent by the same user. + // The user's picture and name are displayed only for the first message. + // Handle sender's picture and adjust view's constraints + if (self.bubbleData.isSameSenderAsPreviousBubble) + { + self.pictureView.hidden = YES; + self.msgTextViewTopConstraint.constant = self.class.cellWithOriginalXib.msgTextViewTopConstraint.constant + MXKROOMBUBBLETABLEVIEWCELL_OUTGOING_HEIGHT_REDUCTION_WHEN_SENDER_INFO_IS_HIDDEN; + self.attachViewTopConstraint.constant = self.class.cellWithOriginalXib.attachViewTopConstraint.constant + MXKROOMBUBBLETABLEVIEWCELL_OUTGOING_HEIGHT_REDUCTION_WHEN_SENDER_INFO_IS_HIDDEN; + + if (!self.dateTimeLabelContainer.hidden) + { + self.dateTimeLabelContainerTopConstraint.constant += MXKROOMBUBBLETABLEVIEWCELL_OUTGOING_HEIGHT_REDUCTION_WHEN_SENDER_INFO_IS_HIDDEN; + } + } + + // Add unsent label for failed components + for (MXKRoomBubbleComponent *component in self.bubbleData.bubbleComponents) + { + if (component.event.mxkState == MXKEventStateSendingFailed) + { + UIButton *unsentButton = [[UIButton alloc] initWithFrame:CGRectMake(0, component.position.y, 58 , 20)]; + + [unsentButton setTitle:[NSBundle mxk_localizedStringForKey:@"unsent"] forState:UIControlStateNormal]; + [unsentButton setTitle:[NSBundle mxk_localizedStringForKey:@"unsent"] forState:UIControlStateSelected]; + [unsentButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; + [unsentButton setTitleColor:[UIColor redColor] forState:UIControlStateSelected]; + + unsentButton.backgroundColor = [UIColor whiteColor]; + unsentButton.titleLabel.font = [UIFont systemFontOfSize:14]; + + [unsentButton addTarget:self action:@selector(onResendToggle:) forControlEvents:UIControlEventTouchUpInside]; + + [self.dateTimeLabelContainer addSubview:unsentButton]; + self.dateTimeLabelContainer.hidden = NO; + self.dateTimeLabelContainer.userInteractionEnabled = YES; + + // ensure that dateTimeLabelContainer is at front to catch the tap event + [self.dateTimeLabelContainer.superview bringSubviewToFront:self.dateTimeLabelContainer]; + } + } + + if (self.attachmentView) + { + // Check if the image is uploading + MXKRoomBubbleComponent *component = self.bubbleData.bubbleComponents.firstObject; + if (MXKEventStateUploading == component.event.mxkState) + { + // Retrieve the uploadId embedded in the fake url + self.bubbleData.uploadId = component.event.content[@"url"]; + + // And start showing upload progress + [self startUploadAnimating]; + self.attachmentView.hideActivityIndicator = YES; + } + else + { + self.attachmentView.hideActivityIndicator = NO; + } + } + } +} + ++ (CGFloat)heightForCellData:(MXKCellData *)cellData withMaximumWidth:(CGFloat)maxWidth +{ + CGFloat rowHeight = [super heightForCellData:cellData withMaximumWidth:maxWidth]; + + MXKRoomBubbleCellData *bubbleData = (MXKRoomBubbleCellData*)cellData; + + // Check whether the previous message has been sent by the same user. + // The user's picture and name are displayed only for the first message. + if (bubbleData.isSameSenderAsPreviousBubble) + { + // Reduce top margin -> row height reduction + rowHeight += MXKROOMBUBBLETABLEVIEWCELL_OUTGOING_HEIGHT_REDUCTION_WHEN_SENDER_INFO_IS_HIDDEN; + } + else + { + // We consider a minimun cell height in order to display correctly user's picture + if (rowHeight < self.cellWithOriginalXib.frame.size.height) + { + rowHeight = self.cellWithOriginalXib.frame.size.height; + } + } + + return rowHeight; +} + + +- (void)didEndDisplay +{ + [super didEndDisplay]; + + // Hide potential loading wheel + [self stopAnimating]; + + self.dateTimeLabelContainer.userInteractionEnabled = NO; +} + +-(void)startUploadAnimating +{ + [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXKMediaUploadProgressNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onUploadProgress:) name:kMXKMediaUploadProgressNotification object:nil]; + + self.activityIndicator.hidden = NO; + [self.activityIndicator startAnimating]; + + MXKMediaLoader *uploader = [MXKMediaManager existingUploaderWithId:self.bubbleData.uploadId]; + if (uploader && uploader.statisticsDict) + { + [self.activityIndicator stopAnimating]; + [self updateProgressUI:uploader.statisticsDict]; + + // Check whether the upload is ended + if (self.progressChartView.progress == 1.0) + { + self.progressView.hidden = YES; + } + } + else + { + self.progressView.hidden = YES; + } +} + + +-(void)stopAnimating +{ + [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXKMediaUploadProgressNotification object:nil]; + [self.activityIndicator stopAnimating]; +} + +- (void)onUploadProgress:(NSNotification *)notif +{ + // sanity check + if ([notif.object isKindOfClass:[NSString class]]) + { + NSString *uploadId = notif.object; + if ([uploadId isEqualToString:self.bubbleData.uploadId]) + { + [self.activityIndicator stopAnimating]; + [self updateProgressUI:notif.userInfo]; + + // the upload is ended + if (self.progressChartView.progress == 1.0) + { + self.progressView.hidden = YES; + } + } + } +} + +#pragma mark - User actions + +- (IBAction)onResendToggle:(id)sender +{ + if ([sender isKindOfClass:[UIButton class]] && self.delegate) + { + MXEvent *selectedEvent = nil; + if (self.bubbleData.bubbleComponents.count == 1) + { + MXKRoomBubbleComponent *component = [self.bubbleData.bubbleComponents firstObject]; + selectedEvent = component.event; + } + else if (self.bubbleData.bubbleComponents.count) + { + // Here the selected view is a textView (attachment has no more than one component) + + // Look for the selected component + UIButton *unsentButton = (UIButton *)sender; + for (MXKRoomBubbleComponent *component in self.bubbleData.bubbleComponents) + { + if (unsentButton.frame.origin.y == component.position.y) + { + selectedEvent = component.event; + break; + } + } + } + + if (selectedEvent) + { + [self.delegate cell:self didRecognizeAction:kMXKRoomBubbleCellUnsentButtonPressed userInfo:@{kMXKRoomBubbleCellEventKey:selectedEvent}]; + } + } +} + +@end \ No newline at end of file diff --git a/Vector/Views/RoomBubbleList/RoomOutgoingBubbleTableViewCell.xib b/Vector/Views/RoomBubbleList/RoomOutgoingBubbleTableViewCell.xib new file mode 100644 index 000000000..445241af8 --- /dev/null +++ b/Vector/Views/RoomBubbleList/RoomOutgoingBubbleTableViewCell.xib @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Vector/Views/RoomInputToolbar/RoomInputToolbarView.h b/Vector/Views/RoomInputToolbar/RoomInputToolbarView.h new file mode 100644 index 000000000..429f774db --- /dev/null +++ b/Vector/Views/RoomInputToolbar/RoomInputToolbarView.h @@ -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 + +#import "MediaPickerViewController.h" + +/** + `RoomInputToolbarView` instance is a view used to handle all kinds of available inputs + for a room (message composer, attachments selection...). + */ +@interface RoomInputToolbarView : MXKRoomInputToolbarViewWithHPGrowingText + + +@end diff --git a/Vector/Views/RoomInputToolbar/RoomInputToolbarView.m b/Vector/Views/RoomInputToolbar/RoomInputToolbarView.m new file mode 100644 index 000000000..d64809145 --- /dev/null +++ b/Vector/Views/RoomInputToolbar/RoomInputToolbarView.m @@ -0,0 +1,511 @@ +/* + 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 +//#import +// +//#import +//#import + +#define MXKROOM_INPUT_TOOLBAR_VIEW_LARGE_IMAGE_SIZE 1024 +#define MXKROOM_INPUT_TOOLBAR_VIEW_MEDIUM_IMAGE_SIZE 768 +#define MXKROOM_INPUT_TOOLBAR_VIEW_SMALL_IMAGE_SIZE 512 + +@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]; + + self.leftInputToolbarButton.backgroundColor = [UIColor clearColor]; + [self.leftInputToolbarButton setImage:[UIImage imageNamed:@"attach_media"] forState:UIControlStateNormal]; + [self.leftInputToolbarButton setImage:[UIImage imageNamed:@"attach_media"] forState:UIControlStateHighlighted]; + + self.rightInputToolbarButton.backgroundColor = [UIColor clearColor]; + [self.rightInputToolbarButton setImage:[UIImage imageNamed:@"send"] forState:UIControlStateNormal]; + [self.rightInputToolbarButton setImage:[UIImage imageNamed:@"send"] forState:UIControlStateHighlighted]; + [self.rightInputToolbarButton setTitle:nil forState:UIControlStateNormal]; + [self.rightInputToolbarButton setTitle:nil forState:UIControlStateHighlighted]; + self.rightInputToolbarButton.enabled = YES; +} + +- (void)setTextMessage:(NSString *)textMessage +{ + [super setTextMessage:textMessage]; + + // Force right button to be enabled (even if the text input is empty) + self.rightInputToolbarButton.enabled = YES; +} + +#pragma mark - HPGrowingTextView delegate + +- (void)growingTextViewDidChange:(HPGrowingTextView *)sender +{ + [super growingTextViewDidChange:sender]; + + // Force right button to be enabled (even if the text input is empty) + self.rightInputToolbarButton.enabled = YES; +} + +- (BOOL)growingTextViewShouldReturn:(HPGrowingTextView *)growingTextView +{ + NSString *message = self.textMessage; + + // Reset message + self.textMessage = nil; + + // Send button has been pressed + if (message.length && [self.delegate respondsToSelector:@selector(roomInputToolbarView:sendTextMessage:)]) + { + [self.delegate roomInputToolbarView:self sendTextMessage:message]; + } + + return YES; +} + +#pragma mark - Override MXKRoomInputToolbarView + +- (IBAction)onTouchUpInside:(UIButton*)button +{ + if (button == self.leftInputToolbarButton) + { + // Check whether media attachment is supported + if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:presentViewController:)]) + { + mediaPicker = [MediaPickerViewController mediaPickerViewController]; + mediaPicker.delegate = self; + UINavigationController *navigationController = [UINavigationController new]; + [navigationController pushViewController:mediaPicker animated:NO]; + + [self.delegate roomInputToolbarView:self presentViewController:mediaPicker]; + } + else + { + NSLog(@"[RoomInputToolbarView] Attach media is not supported"); + } + } + else if (button == self.rightInputToolbarButton) + { + // Check whether media attachment is supported + if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:presentViewController:)]) + { + mediaPicker = [MediaPickerViewController mediaPickerViewController]; + mediaPicker.delegate = self; + UINavigationController *navigationController = [UINavigationController new]; + [navigationController pushViewController:mediaPicker animated:NO]; + + [self.delegate roomInputToolbarView:self presentViewController:mediaPicker]; + } + else + { + NSLog(@"[RoomInputToolbarView] Attach media is not supported"); + } + } +// else if (button == self.rightInputToolbarButton) +// { +// +// NSString *message = self.textMessage; +// +// // Reset message +// self.textMessage = nil; +// +// // Send button has been pressed +// if (message.length && [self.delegate respondsToSelector:@selector(roomInputToolbarView:sendTextMessage:)]) +// { +// [self.delegate roomInputToolbarView:self sendTextMessage:message]; +// } +// } +} + + +- (void)destroy +{ + [super destroy]; +} + +//#pragma mark - UIImagePickerControllerDelegate +// +//- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info +//{ +// NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType]; +// if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) +// { +// +// /* +// NSData *dataOfGif = [NSData dataWithContentsOfFile: [info objectForKey:UIImagePickerControllerReferenceURL]]; +// +// NSLog(@"%d", dataOfGif.length); +// +// ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; +// [library assetForURL:[info objectForKey:UIImagePickerControllerReferenceURL] resultBlock:^(ALAsset *asset) +// { +// +// NSLog(@"%@", asset.defaultRepresentation.metadata); +// +// +// NSLog(@"%@", asset.defaultRepresentation.url); +// +// NSData *dataOfGif = [NSData dataWithContentsOfURL: asset.defaultRepresentation.url]; +// +// NSLog(@"%d", dataOfGif.length); +// ; +// +// } failureBlock:^(NSError *error) +// { +// +// }]; +// +// */ +// +// if (![self.delegate respondsToSelector:@selector(roomInputToolbarView:sendImage:)]) +// { +// NSLog(@"[RoomInputToolbarView] Attach image is not supported"); +// } +// else +// { +// UIImage *selectedImage = [info objectForKey:UIImagePickerControllerOriginalImage]; +// if (selectedImage) +// { +// // media picker does not offer a preview +// // so add a preview to let the user validates his selection +// if (picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary) +// { +// __weak typeof(self) weakSelf = self; +// +// imageValidationView = [[MXKImageView alloc] initWithFrame:CGRectZero]; +// imageValidationView.stretchable = YES; +// +// // the user validates the image +// [imageValidationView setRightButtonTitle:[NSBundle mxk_localizedStringForKey:@"ok"] handler:^(MXKImageView* imageView, NSString* buttonTitle) +// { +// __strong __typeof(weakSelf)strongSelf = weakSelf; +// +// // Dismiss the image view +// [strongSelf dismissImageValidationView]; +// +// // prompt user about image compression +// [strongSelf promptCompressionForSelectedImage:info]; +// }]; +// +// // the user wants to use an other image +// [imageValidationView setLeftButtonTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] handler:^(MXKImageView* imageView, NSString* buttonTitle) +// { +// __strong __typeof(weakSelf)strongSelf = weakSelf; +// +// // dismiss the image view +// [strongSelf dismissImageValidationView]; +// +// // Open again media gallery +// strongSelf->mediaPicker = [[UIImagePickerController alloc] init]; +// strongSelf->mediaPicker.delegate = strongSelf; +// strongSelf->mediaPicker.sourceType = picker.sourceType; +// strongSelf->mediaPicker.allowsEditing = NO; +// strongSelf->mediaPicker.mediaTypes = picker.mediaTypes; +// [strongSelf.delegate roomInputToolbarView:strongSelf presentMediaPicker:strongSelf->mediaPicker]; +// }]; +// +// imageValidationView.image = selectedImage; +// [imageValidationView showFullScreen]; +// } +// else +// { +// // Save the original image in user's photos library and suggest compression before sending image +// [MXKMediaManager saveImageToPhotosLibrary:selectedImage success:nil failure:nil]; +// [self promptCompressionForSelectedImage:info]; +// } +// } +// } +// } +// else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie]) +// { +// NSURL* selectedVideo = [info objectForKey:UIImagePickerControllerMediaURL]; +// +// // Check the selected video, and ignore multiple calls (observed when user pressed several time Choose button) +// if (selectedVideo && !tmpVideoPlayer) +// { +// if (picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary) +// { +// [MXKMediaManager saveMediaToPhotosLibrary:selectedVideo isImage:NO success:nil failure:nil]; +// } +// +// // Create video thumbnail +// tmpVideoPlayer = [[MPMoviePlayerController alloc] initWithContentURL:selectedVideo]; +// if (tmpVideoPlayer) +// { +// [tmpVideoPlayer setShouldAutoplay:NO]; +// [[NSNotificationCenter defaultCenter] addObserver:self +// selector:@selector(moviePlayerThumbnailImageRequestDidFinishNotification:) +// name:MPMoviePlayerThumbnailImageRequestDidFinishNotification +// object:nil]; +// [tmpVideoPlayer requestThumbnailImagesAtTimes:@[@1.0f] timeOption:MPMovieTimeOptionNearestKeyFrame]; +// // We will finalize video attachment when thumbnail will be available (see movie player callback) +// return; +// } +// } +// } +// +// [self dismissMediaPicker]; +//} +// +//- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker +//{ +// [self dismissMediaPicker]; +//} +// +//- (void)dismissImageValidationView +//{ +// if (imageValidationView) +// { +// [imageValidationView dismissSelection]; +// [imageValidationView removeFromSuperview]; +// imageValidationView = nil; +// } +//} +// +//- (void)promptCompressionForSelectedImage:(NSDictionary*)selectedImageInfo +//{ +// if (currentAlert) +// { +// [currentAlert dismiss:NO]; +// currentAlert = nil; +// } +// +// UIImage *selectedImage = [selectedImageInfo objectForKey:UIImagePickerControllerOriginalImage]; +// CGSize originalSize = selectedImage.size; +// NSLog(@"Selected image size : %f %f", originalSize.width, originalSize.height); +// +// [self getSelectedImageFileData:selectedImageInfo success:^(NSData *selectedImageFileData) { +// +// long long smallFilesize = 0; +// long long mediumFilesize = 0; +// long long largeFilesize = 0; +// +// // succeed to get the file size (provided by the photo library) +// long long originalFileSize = selectedImageFileData.length; +// NSLog(@"- use the photo library file size: %tu", originalFileSize); +// +// CGFloat maxSize = MAX(originalSize.width, originalSize.height); +// if (maxSize >= MXKROOM_INPUT_TOOLBAR_VIEW_SMALL_IMAGE_SIZE) +// { +// CGFloat factor = MXKROOM_INPUT_TOOLBAR_VIEW_SMALL_IMAGE_SIZE / maxSize; +// smallFilesize = factor * factor * originalFileSize; +// } +// else +// { +// NSLog(@"- too small to fit in %d", MXKROOM_INPUT_TOOLBAR_VIEW_SMALL_IMAGE_SIZE); +// } +// +// if (maxSize >= MXKROOM_INPUT_TOOLBAR_VIEW_MEDIUM_IMAGE_SIZE) +// { +// CGFloat factor = MXKROOM_INPUT_TOOLBAR_VIEW_MEDIUM_IMAGE_SIZE / maxSize; +// mediumFilesize = factor * factor * originalFileSize; +// } +// else +// { +// NSLog(@"- too small to fit in %d", MXKROOM_INPUT_TOOLBAR_VIEW_MEDIUM_IMAGE_SIZE); +// } +// +// if (maxSize >= MXKROOM_INPUT_TOOLBAR_VIEW_LARGE_IMAGE_SIZE) +// { +// CGFloat factor = MXKROOM_INPUT_TOOLBAR_VIEW_LARGE_IMAGE_SIZE / maxSize; +// largeFilesize = factor * factor * originalFileSize; +// } +// else +// { +// NSLog(@"- too small to fit in %d", MXKROOM_INPUT_TOOLBAR_VIEW_LARGE_IMAGE_SIZE); +// } +// +// if (smallFilesize || mediumFilesize || largeFilesize) +// { +// currentAlert = [[MXKAlert alloc] initWithTitle:[NSBundle mxk_localizedStringForKey:@"attachment_size_prompt"] message:nil style:MXKAlertStyleActionSheet]; +// __weak typeof(self) weakSelf = self; +// +// if (smallFilesize) +// { +// NSString *title = [NSString stringWithFormat:[NSBundle mxk_localizedStringForKey:@"attachment_small"], [MXKTools fileSizeToString: (int)smallFilesize]]; +// [currentAlert addActionWithTitle:title style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { +// __strong __typeof(weakSelf)strongSelf = weakSelf; +// strongSelf->currentAlert = nil; +// +// // Send the small image +// UIImage *smallImage = [MXKTools resize:selectedImage toFitInSize:CGSizeMake(MXKROOM_INPUT_TOOLBAR_VIEW_SMALL_IMAGE_SIZE, MXKROOM_INPUT_TOOLBAR_VIEW_SMALL_IMAGE_SIZE)]; +// [strongSelf.delegate roomInputToolbarView:weakSelf sendImage:smallImage]; +// }]; +// } +// +// if (mediumFilesize) +// { +// NSString *title = [NSString stringWithFormat:[NSBundle mxk_localizedStringForKey:@"attachment_medium"], [MXKTools fileSizeToString: (int)mediumFilesize]]; +// [currentAlert addActionWithTitle:title style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { +// __strong __typeof(weakSelf)strongSelf = weakSelf; +// strongSelf->currentAlert = nil; +// +// // Send the medium image +// UIImage *mediumImage = [MXKTools resize:selectedImage toFitInSize:CGSizeMake(MXKROOM_INPUT_TOOLBAR_VIEW_MEDIUM_IMAGE_SIZE, MXKROOM_INPUT_TOOLBAR_VIEW_MEDIUM_IMAGE_SIZE)]; +// [strongSelf.delegate roomInputToolbarView:weakSelf sendImage:mediumImage]; +// }]; +// } +// +// if (largeFilesize) +// { +// NSString *title = [NSString stringWithFormat:[NSBundle mxk_localizedStringForKey:@"attachment_large"], [MXKTools fileSizeToString: (int)largeFilesize]]; +// [currentAlert addActionWithTitle:title style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { +// __strong __typeof(weakSelf)strongSelf = weakSelf; +// strongSelf->currentAlert = nil; +// +// // Send the large image +// UIImage *largeImage = [MXKTools resize:selectedImage toFitInSize:CGSizeMake(MXKROOM_INPUT_TOOLBAR_VIEW_LARGE_IMAGE_SIZE, MXKROOM_INPUT_TOOLBAR_VIEW_LARGE_IMAGE_SIZE)]; +// [strongSelf.delegate roomInputToolbarView:weakSelf sendImage:largeImage]; +// }]; +// } +// +// NSString *title = [NSString stringWithFormat:[NSBundle mxk_localizedStringForKey:@"attachment_original"], [MXKTools fileSizeToString: (int)originalFileSize]]; +// [currentAlert addActionWithTitle:title style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { +// __strong __typeof(weakSelf)strongSelf = weakSelf; +// strongSelf->currentAlert = nil; +// +// // Send the original image +// [strongSelf.delegate roomInputToolbarView:weakSelf sendImage:selectedImage]; +// }]; +// +// currentAlert.cancelButtonIndex = [currentAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { +// __strong __typeof(weakSelf)strongSelf = weakSelf; +// strongSelf->currentAlert = nil; +// }]; +// +// currentAlert.sourceView = self; +// +// [self.delegate roomInputToolbarView:self presentMXKAlert:currentAlert]; +// } +// else +// { +// // Send the original image +// [self.delegate roomInputToolbarView:self sendImage:selectedImage]; +// } +// } failure:^(NSError *error) { +// +// // Send the original image +// [self.delegate roomInputToolbarView:self sendImage:selectedImage]; +// }]; +//} + +//- (void)getSelectedImageFileData:(NSDictionary*)selectedImageInfo success:(void (^)(NSData *selectedImageFileData))success failure:(void (^)(NSError *error))failure +//{ +// ALAssetsLibrary *assetLibrary=[[ALAssetsLibrary alloc] init]; +// [assetLibrary assetForURL:[selectedImageInfo valueForKey:UIImagePickerControllerReferenceURL] resultBlock:^(ALAsset *asset) { +// +// NSData *selectedImageFileData; +// +// // asset may be nil if the image is not saved in photos library +// if (asset) +// { +// ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation]; +// +// // Check whether the user select an image with a cropping +// if ([[assetRepresentation metadata] objectForKey:@"AdjustmentXMP"]) +// { +// // In case of crop we have to consider the original image +// selectedImageFileData = UIImageJPEGRepresentation([selectedImageInfo objectForKey:UIImagePickerControllerOriginalImage], 0.9); +// } +// else +// { +// // cannot use assetRepresentation size to get the image size +// // it gives wrong result with panorama picture +// unsigned long imageDataSize = (unsigned long)[assetRepresentation size]; +// uint8_t* imageDataBytes = malloc(imageDataSize); +// [assetRepresentation getBytes:imageDataBytes fromOffset:0 length:imageDataSize error:nil]; +// +// selectedImageFileData = [NSData dataWithBytesNoCopy:imageDataBytes length:imageDataSize freeWhenDone:YES]; +// } +// } +// else +// { +// selectedImageFileData = UIImageJPEGRepresentation([selectedImageInfo objectForKey:UIImagePickerControllerOriginalImage], 0.9); +// } +// +// if (success) +// { +// success (selectedImageFileData); +// } +// } failureBlock:^(NSError *err) { +// +// if (failure) +// { +// failure (err); +// } +// }]; +//} + +#pragma mark - Media Picker handling + +//- (void)dismissMediaPicker +//{ +// mediaPicker.delegate = nil; +// +// if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:dismissMediaPicker:)]) +// { +// [self.delegate roomInputToolbarView:self dismissMediaPicker:mediaPicker]; +// } +//} +// +//- (void)moviePlayerThumbnailImageRequestDidFinishNotification:(NSNotification *)notification +//{ +// // Finalize video attachment +// UIImage* videoThumbnail = [[notification userInfo] objectForKey:MPMoviePlayerThumbnailImageKey]; +// NSURL* selectedVideo = [tmpVideoPlayer contentURL]; +// [tmpVideoPlayer stop]; +// tmpVideoPlayer = nil; +// +// if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:sendVideo:withThumbnail:)]) +// { +// [self.delegate roomInputToolbarView:self sendVideo:selectedVideo withThumbnail:videoThumbnail]; +// } +// else +// { +// NSLog(@"[RoomInputToolbarView] Attach video is not supported"); +// } +// +// [self dismissMediaPicker]; +//} + +@end diff --git a/Vector/Views/RoomInputToolbar/RoomInputToolbarView.xib b/Vector/Views/RoomInputToolbar/RoomInputToolbarView.xib new file mode 100644 index 000000000..2bcfc33b5 --- /dev/null +++ b/Vector/Views/RoomInputToolbar/RoomInputToolbarView.xib @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +