add the typing area above the text input in the roomviewcontroller.

This commit is contained in:
yannick
2015-11-24 16:19:45 +00:00
8 changed files with 300 additions and 0 deletions
+3
View File
@@ -73,6 +73,9 @@
"room_option_start_group_video" = "Start group video chat";
"room_option_share_location" = "Share location";
"room_option_share_contact" = "Share contact";
"room_one_user_is_typing" = "%@ is typing...";
"room_two_users_are_typing" = "%@ & %@ are typing...";
"room_many_users_are_typing" = "%@, %@ & others are typing...";
// Settings
"account_logout_all" = "Logout all accounts";
+118
View File
@@ -21,6 +21,8 @@
#import "RoomInputToolbarView.h"
#import "RoomActivitiesView.h"
#import "RoomParticipantsViewController.h"
#import "RoomDetailsViewController.h"
@@ -32,6 +34,12 @@
// the user taps on a member thumbnail
MXRoomMember *selectedRoomMember;
// List of members who are typing in the room.
NSArray *currentTypingUsers;
// Typing notifications listener.
id typingNotifListener;
}
@property (strong, nonatomic) MXKAlert *currentAlert;
@@ -51,6 +59,9 @@
[self setRoomInputToolbarViewClass:RoomInputToolbarView.class];
[self roomInputToolbarView:self.inputToolbarView heightDidChanged:((RoomInputToolbarView*)self.inputToolbarView).mainToolbarHeightConstraint.constant completion:nil];
// set extra area
[self setRoomActivitiesViewClass:RoomActivitiesView.class];
// Set rageShake handler
self.rageShakeManager = [RageShakeManager sharedManager];
@@ -117,6 +128,12 @@
[self.menuListView addConstraint:heightConstraint];
}
[self.view setNeedsUpdateConstraints];
if (self.roomDataSource)
{
// this room view controller has its own typing management.
self.roomDataSource.showTypingNotifications = NO;
}
}
- (void)didReceiveMemoryWarning
@@ -128,6 +145,8 @@
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self listenTypingNotifications];
}
- (void)viewWillDisappear:(BOOL)animated
@@ -143,6 +162,8 @@
// Hide menu list view
menuListTopConstraint.constant = 0;
[self removeTypingNotificationsListener];
}
- (void)viewDidAppear:(BOOL)animated
@@ -416,6 +437,103 @@
return NO;
}
#pragma mark - typing management
- (void)removeTypingNotificationsListener
{
if (self.roomDataSource)
{
// Remove the previous live listener
if (typingNotifListener)
{
[self.roomDataSource.room removeListener:typingNotifListener];
currentTypingUsers = nil;
}
}
}
- (void)listenTypingNotifications
{
if (self.roomDataSource)
{
// Add typing notification listener
typingNotifListener = [self.roomDataSource.room listenToEventsOfTypes:@[kMXEventTypeStringTypingNotification] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState)
{
// Handle only live events
if (direction == MXEventDirectionForwards)
{
// Retrieve typing users list
NSMutableArray *typingUsers = [NSMutableArray arrayWithArray:self.roomDataSource.room.typingUsers];
// Remove typing info for the current user
NSUInteger index = [typingUsers indexOfObject:self.mainSession.myUser.userId];
if (index != NSNotFound)
{
[typingUsers removeObjectAtIndex:index];
}
// Ignore this notification if both arrays are empty
if (currentTypingUsers.count || typingUsers.count)
{
currentTypingUsers = typingUsers;
[self refreshTypingView];
}
}
}];
currentTypingUsers = self.roomDataSource.room.typingUsers;
[self refreshTypingView];
}
}
- (void)refreshTypingView
{
NSString* text = nil;
NSUInteger count = currentTypingUsers.count;
// get the room member names
NSMutableArray *names = [[NSMutableArray alloc] init];
// keeps the only the first two users
//
for(int i = 0; i < MIN(count, 2); i++) {
NSString* name = [currentTypingUsers objectAtIndex:i];
MXRoomMember* member = [self.roomDataSource.room.state memberWithUserId:name];
if (nil != member)
{
name = member.displayname;
}
[names addObject:name];
}
if (0 == count)
{
// something to do ?
}
else if (1 == count)
{
text = [NSString stringWithFormat:NSLocalizedStringFromTable(@"room_one_user_is_typing", @"Vector", nil), [names objectAtIndex:0]];
}
else if (2 == count)
{
text = [NSString stringWithFormat:NSLocalizedStringFromTable(@"room_two_users_are_typing", @"Vector", nil), [names objectAtIndex:0], [names objectAtIndex:1]];
}
else
{
text = [NSString stringWithFormat:NSLocalizedStringFromTable(@"room_many_users_are_typing", @"Vector", nil), [names objectAtIndex:0], [names objectAtIndex:1]];
}
if (self.activitiesView)
{
[((RoomActivitiesView*) self.activitiesView) updateTypingMessage:text];
}
}
@end
BIN
View File
Binary file not shown.
@@ -0,0 +1,34 @@
/*
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>
/**
`RoomExtraInfosInfoView` instance is a view used to display extra information
*/
@interface RoomActivitiesView : MXKRoomActivitiesView
@property (weak, nonatomic) IBOutlet UIImageView *typingImageView;
@property (weak, nonatomic) IBOutlet UILabel *messageLabel;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *mainHeightConstraint;
// update the displayed typing message.
// nil message hides the typing icon too.
- (void)updateTypingMessage:(NSString*)message;
@end
@@ -0,0 +1,62 @@
/*
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 "RoomActivitiesView.h"
@implementation RoomActivitiesView
+ (UINib *)nib
{
return [UINib nibWithNibName:NSStringFromClass([RoomActivitiesView class])
bundle:[NSBundle bundleForClass:[RoomActivitiesView class]]];
}
- (CGFloat)height
{
return self.mainHeightConstraint.constant;
}
- (void)awakeFromNib
{
[super awakeFromNib];
// Remove default toolbar background color
self.backgroundColor = [UIColor whiteColor];
// TODO : put this mint grey color as a resource
self.typingImageView.backgroundColor = [UIColor colorWithRed:(98.0/256.0) green:(206.0/256.0) blue:(156.0/256.0) alpha:1.0];
self.typingImageView.layer.cornerRadius = self.typingImageView.frame.size.height / 2;
}
// update the displayed typing message.
// nil message hides the typing icon too.
- (void)updateTypingMessage:(NSString*)message
{
if (message)
{
self.typingImageView.hidden = false;
self.messageLabel.hidden = false;
self.messageLabel.text = message;
}
else
{
self.typingImageView.hidden = true;
self.messageLabel.hidden = true;
}
}
@end
@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="8191" systemVersion="14F27" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
</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" userLabel="Room Extras Infos View" customClass="RoomActivitiesView">
<rect key="frame" x="0.0" y="0.0" width="600" height="50"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qhJ-5H-64e" userLabel="Container">
<rect key="frame" x="0.0" y="0.0" width="600" height="50"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="typing.png" translatesAutoresizingMaskIntoConstraints="NO" id="d6j-oN-9uA">
<rect key="frame" x="8" y="5" width="40" height="40"/>
<color key="backgroundColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="657-fV-gDE"/>
<constraint firstAttribute="width" constant="40" id="vxL-QJ-z0p"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7bS-1u-GUX" userLabel="Message Label">
<rect key="frame" x="56" y="5" width="536" height="40"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="PVB-be-euJ"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="7bS-1u-GUX" firstAttribute="leading" secondItem="d6j-oN-9uA" secondAttribute="trailing" constant="8" id="6Js-Lq-pKz"/>
<constraint firstItem="7bS-1u-GUX" firstAttribute="top" secondItem="qhJ-5H-64e" secondAttribute="top" constant="5" id="EYf-ry-ZeK"/>
<constraint firstItem="d6j-oN-9uA" firstAttribute="top" secondItem="qhJ-5H-64e" secondAttribute="top" constant="5" id="MEa-LJ-cGx"/>
<constraint firstItem="d6j-oN-9uA" firstAttribute="leading" secondItem="qhJ-5H-64e" secondAttribute="leading" constant="8" id="YYC-Q1-IoC"/>
<constraint firstAttribute="trailing" secondItem="7bS-1u-GUX" secondAttribute="trailing" constant="8" id="tCW-EI-6Yt"/>
<constraint firstAttribute="height" constant="50" id="xPK-Yw-hQ9"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="qhJ-5H-64e" firstAttribute="width" secondItem="iN0-l3-epB" secondAttribute="width" id="4o2-V9-a4L"/>
<constraint firstItem="qhJ-5H-64e" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="wDi-7P-36c"/>
<constraint firstItem="qhJ-5H-64e" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="wsu-Zi-OE6"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<nil key="simulatedTopBarMetrics"/>
<nil key="simulatedBottomBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<connections>
<outlet property="mainHeightConstraint" destination="xPK-Yw-hQ9" id="dJ5-pI-KyT"/>
<outlet property="messageLabel" destination="7bS-1u-GUX" id="5c1-hT-y49"/>
<outlet property="typingImageView" destination="d6j-oN-9uA" id="kvp-J3-bVj"/>
</connections>
</view>
</objects>
<resources>
<image name="typing.png" width="20" height="20"/>
</resources>
</document>