Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
Weblate 2018-04-19 21:15:54 +00:00
commit 40ceb7a880
29 changed files with 1058 additions and 241 deletions

View file

@ -39,3 +39,7 @@ Evan Tang <etang110 at gmail.com>
Joey Watts <joey.watts.96 at gmail.com>
* PR #1777 Add support for interactive notifications
Arash Tabrizian <a.tabriziyan at gmail.com>
* PR #1828 Fix issue #1793 Confirmation popup when leaving room
* PR #1824 Fix issue #1816 Support specifying kick and ban msgs

View file

@ -1,3 +1,28 @@
Changes in 0.6.13 (2018-04-20)
===============================================
Improvements:
* Upgrade MatrixKit version (v0.7.10).
* The minimal iOS version is now 9.0.
* Render stickers in the timeline (#1819).
* Support specifying kick and ban msgs (#1816), thanks to @atabrizian (PR #1824).
* Confirmation popup when leaving room (#1793), thanks to @atabrizian (PR #1828).
Bug fixes:
* Global Messages search: some search results are missing.
* Crash on URL like https://riot.im/#/app/register?hs_url=... (#1838).
Changes in 0.6.13 (2018-03-30)
===============================================
Improvements:
* Upgrade MatrixKit version (v0.7.9).
* Make state event redaction handling gentler with homeserver (vector-im/riot-ios#1823).
Bug fixes:
* Room summary is not updated after redaction of the room display name (vector-im/riot-ios#1822).
Changes in 0.6.12 (2018-03-12)
===============================================

View file

@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
platform :ios, "8.0"
platform :ios, "9.0"
# Use frameforks to allow usage of pod written in Swift (like PiwikTracker)
use_frameworks!
@ -9,7 +9,7 @@ source 'https://github.com/CocoaPods/Specs.git'
# Different flavours of pods to MatrixKit
# The current MatrixKit pod version
$matrixKitVersion = '0.7.8'
$matrixKitVersion = '0.7.9'
# The develop branch version
#$matrixKitVersion = 'develop'

View file

@ -43,34 +43,34 @@ PODS:
- GZIP (1.2.1)
- HPGrowingTextView (1.1)
- libPhoneNumber-iOS (0.9.13)
- MatrixKit (0.7.8):
- MatrixKit (0.7.9):
- cmark (~> 0.24.1)
- DTCoreText (~> 1.6.21)
- HPGrowingTextView (~> 1.1)
- libPhoneNumber-iOS (~> 0.9.13)
- MatrixKit/Core (= 0.7.8)
- MatrixSDK (= 0.10.6)
- MatrixKit/AppExtension (0.7.8):
- MatrixKit/Core (= 0.7.9)
- MatrixSDK (= 0.10.7)
- MatrixKit/AppExtension (0.7.9):
- cmark (~> 0.24.1)
- DTCoreText (~> 1.6.21)
- DTCoreText/Extension
- HPGrowingTextView (~> 1.1)
- libPhoneNumber-iOS (~> 0.9.13)
- MatrixSDK (= 0.10.6)
- MatrixKit/Core (0.7.8):
- MatrixSDK (= 0.10.7)
- MatrixKit/Core (0.7.9):
- cmark (~> 0.24.1)
- DTCoreText (~> 1.6.21)
- HPGrowingTextView (~> 1.1)
- libPhoneNumber-iOS (~> 0.9.13)
- MatrixSDK (= 0.10.6)
- MatrixSDK (0.10.6):
- MatrixSDK/Core (= 0.10.6)
- MatrixSDK/Core (0.10.6):
- MatrixSDK (= 0.10.7)
- MatrixSDK (0.10.7):
- MatrixSDK/Core (= 0.10.7)
- MatrixSDK/Core (0.10.7):
- AFNetworking (~> 3.2.0)
- GZIP (~> 1.2.1)
- OLMKit (~> 2.2.2)
- Realm (~> 3.1.1)
- MatrixSDK/JingleCallStack (0.10.6):
- MatrixSDK/JingleCallStack (0.10.7):
- MatrixSDK/Core
- WebRTC (= 63.11.20455)
- OLMKit (2.2.2):
@ -90,8 +90,8 @@ DEPENDENCIES:
- cmark
- DTCoreText
- GBDeviceInfo (~> 5.1.0)
- MatrixKit (= 0.7.8)
- MatrixKit/AppExtension (= 0.7.8)
- MatrixKit (= 0.7.9)
- MatrixKit/AppExtension (= 0.7.9)
- MatrixSDK/JingleCallStack
- OLMKit
- PiwikTracker (from `https://github.com/manuroe/matomo-sdk-ios.git`, branch `feature/CustomVariables`)
@ -115,13 +115,13 @@ SPEC CHECKSUMS:
GZIP: 7ee835f989fb3c6ea79005fc90b8fa6af710a70d
HPGrowingTextView: 88a716d97fb853bcb08a4a08e4727da17efc9b19
libPhoneNumber-iOS: e444379ac18bbfbdefad571da735b2cd7e096caa
MatrixKit: 4a44fc7c77b312d921604af249c891144b228d5c
MatrixSDK: 9d2edb30d020fb8478e03d5b69097b7ce273bc63
MatrixKit: 1945e24b20e0ba0853798c347404cdf0efb780e3
MatrixSDK: a08af4179df86082affa188b5b2099def9eb2843
OLMKit: b9d8c0ffee9ea8c45bc0aaa9afb47f93fba7efbd
PiwikTracker: 42862c7b13028065c3dfd36b4dc38db8a5765acf
Realm: 42d1c38a5b1bbcc828b48a7ce702cb86fc68adf4
WebRTC: f2a6203584745fe53532633397557876b5d71640
PODFILE CHECKSUM: 4a8ff7d0d54b2e3369a8e4d32f2814e24404033f
PODFILE CHECKSUM: 7abb83aba898f3755b58b5859fd52321f7d97bb2
COCOAPODS: 1.4.0

View file

@ -7,6 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
02543BAE206E6C59001CDAB2 /* RoomSelectedStickerBubbleCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 02543BAB206E6C58001CDAB2 /* RoomSelectedStickerBubbleCell.m */; };
02543BAF206E6C59001CDAB2 /* RoomSelectedStickerBubbleCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 02543BAC206E6C58001CDAB2 /* RoomSelectedStickerBubbleCell.xib */; };
2435179C1F375B9400D0683E /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 2466B7551F2F80B800AE27B0 /* Info.plist */; };
2435179F1F375C0F00D0683E /* Vector.strings in Resources */ = {isa = PBXBuildFile; fileRef = 327382C01F276AED00356143 /* Vector.strings */; };
2439DD621F6BBE760090F42D /* RecentRoomTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2439DD611F6BBE760090F42D /* RecentRoomTableViewCell.m */; };
@ -656,6 +658,9 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
02543BAB206E6C58001CDAB2 /* RoomSelectedStickerBubbleCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RoomSelectedStickerBubbleCell.m; sourceTree = "<group>"; };
02543BAC206E6C58001CDAB2 /* RoomSelectedStickerBubbleCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RoomSelectedStickerBubbleCell.xib; sourceTree = "<group>"; };
02543BAD206E6C59001CDAB2 /* RoomSelectedStickerBubbleCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomSelectedStickerBubbleCell.h; sourceTree = "<group>"; };
12AA0005C8B3D8D8162584C5 /* Pods-RiotShareExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RiotShareExtension.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RiotShareExtension/Pods-RiotShareExtension.debug.xcconfig"; sourceTree = "<group>"; };
22D76C11C202B6BC5917A049 /* Pods-RiotPods-RiotShareExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RiotPods-RiotShareExtension.release.xcconfig"; path = "Pods/Target Support Files/Pods-RiotPods-RiotShareExtension/Pods-RiotPods-RiotShareExtension.release.xcconfig"; sourceTree = "<group>"; };
23D7292481328A48B8D5D4ED /* Pods_RiotPods_RiotShareExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RiotPods_RiotShareExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@ -2428,6 +2433,9 @@
F083BCD51E7009EC00A9B29C /* RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h */,
F083BCD61E7009EC00A9B29C /* RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m */,
F083BCD71E7009EC00A9B29C /* RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib */,
02543BAD206E6C59001CDAB2 /* RoomSelectedStickerBubbleCell.h */,
02543BAB206E6C58001CDAB2 /* RoomSelectedStickerBubbleCell.m */,
02543BAC206E6C58001CDAB2 /* RoomSelectedStickerBubbleCell.xib */,
);
path = RoomBubbleList;
sourceTree = "<group>";
@ -3217,6 +3225,7 @@
F083BD3A1E7009ED00A9B29C /* call_chat_icon@2x.png in Resources */,
F083BE711E7009ED00A9B29C /* RoomOutgoingTextMsgBubbleCell.xib in Resources */,
F083BD5E1E7009ED00A9B29C /* create_room@3x.png in Resources */,
02543BAF206E6C59001CDAB2 /* RoomSelectedStickerBubbleCell.xib in Resources */,
F083BE6B1E7009ED00A9B29C /* RoomOutgoingAttachmentBubbleCell.xib in Resources */,
F083BD4C1E7009ED00A9B29C /* camera_capture@2x.png in Resources */,
F083BD8F1E7009ED00A9B29C /* file_video_icon.png in Resources */,
@ -3635,6 +3644,7 @@
F083BE601E7009ED00A9B29C /* RoomIncomingTextMsgBubbleCell.m in Sources */,
F083BE2F1E7009ED00A9B29C /* ContactTableViewCell.m in Sources */,
F083BE901E7009ED00A9B29C /* RoomTitleView.m in Sources */,
02543BAE206E6C59001CDAB2 /* RoomSelectedStickerBubbleCell.m in Sources */,
F083BE6E1E7009ED00A9B29C /* RoomOutgoingAttachmentWithPaginationTitleBubbleCell.m in Sources */,
3233F7311F31F4BF006ACA81 /* JitsiViewController.m in Sources */,
F083BE2A1E7009ED00A9B29C /* UsersDevicesViewController.m in Sources */,
@ -4009,7 +4019,7 @@
DEVELOPMENT_TEAM = 7J4U792NQT;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = RiotShareExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = im.vector.app.shareExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
@ -4032,7 +4042,7 @@
DEVELOPMENT_TEAM = 7J4U792NQT;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = RiotShareExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = im.vector.app.shareExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
@ -4193,7 +4203,7 @@
"\"$(PROJECT_DIR)/Riot/libs/jitsi-meet\"",
);
INFOPLIST_FILE = Riot/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = im.vector.app;
PRODUCT_NAME = "$(TARGET_NAME)";
@ -4227,7 +4237,7 @@
"\"$(PROJECT_DIR)/Riot/libs/jitsi-meet\"",
);
INFOPLIST_FILE = Riot/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = im.vector.app;
PRODUCT_NAME = "$(TARGET_NAME)";

View file

@ -101,7 +101,14 @@ extern NSString *const kAppDelegateNetworkStatusDidChangeNotification;
// Reload all running matrix sessions
- (void)reloadMatrixSessions:(BOOL)clearCache;
- (void)logout;
/**
Log out all the accounts after asking for a potential confirmation.
Show the authentication screen on successful logout.
@param askConfirmation tell whether a confirmation is required before logging out.
@param completion the block to execute at the end of the operation.
*/
- (void)logoutWithConfirmation:(BOOL)askConfirmation completion:(void (^)(BOOL isLoggedOut))completion;
#pragma mark - Matrix Accounts handling

View file

@ -1,6 +1,7 @@
/*
Copyright 2014 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
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.
@ -207,6 +208,8 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
@property (strong, nonatomic) UIAlertController *mxInAppNotification;
@property (strong, nonatomic) UIAlertController *logoutConfirmation;
@property (nonatomic, nullable, copy) void (^registrationForRemoteNotificationsCompletion)(NSError *);
@ -1587,6 +1590,15 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
else
notificationBody = [NSString stringWithFormat:NSLocalizedString(@"USER_INVITE_TO_CHAT", nil), eventSenderName];
}
else if (event.eventType == MXEventTypeSticker)
{
NSString *roomDisplayName = room.summary.displayname;
if (roomDisplayName.length && ![roomDisplayName isEqualToString:eventSenderName])
notificationBody = [NSString stringWithFormat:NSLocalizedString(@"MSG_FROM_USER_IN_ROOM", nil), eventSenderName, roomDisplayName];
else
notificationBody = [NSString stringWithFormat:NSLocalizedString(@"MSG_FROM_USER", nil), eventSenderName];
}
return notificationBody;
}
@ -2074,6 +2086,7 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
}];
}
}
// Check whether this is a registration links.
else if ([pathParams[0] isEqualToString:@"register"])
{
NSLog(@"[AppDelegate] Universal link with registration parameters");
@ -2385,7 +2398,7 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
// Logout the app when there is no available account
if (![MXKAccountManager sharedManager].accounts.count)
{
[self logout];
[self logoutWithConfirmation:NO completion:nil];
}
}];
@ -2557,8 +2570,90 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
}
}
- (void)logout
- (void)logoutWithConfirmation:(BOOL)askConfirmation completion:(void (^)(BOOL isLoggedOut))completion
{
// Check whether we have to ask confirmation before logging out.
if (askConfirmation)
{
if (self.logoutConfirmation)
{
[self.logoutConfirmation dismissViewControllerAnimated:NO completion:nil];
self.logoutConfirmation = nil;
}
__weak typeof(self) weakSelf = self;
NSString *message = NSLocalizedStringFromTable(@"settings_sign_out_confirmation", @"Vector", nil);
// If the user has encrypted rooms, warn he will lose his e2e keys
MXSession *session = self.mxSessions.firstObject;
for (MXRoom *room in session.rooms)
{
if (room.state.isEncrypted)
{
message = [message stringByAppendingString:[NSString stringWithFormat:@"\n\n%@", NSLocalizedStringFromTable(@"settings_sign_out_e2e_warn", @"Vector", nil)]];
break;
}
}
// Ask confirmation
self.logoutConfirmation = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"settings_sign_out", @"Vector", nil) message:message preferredStyle:UIAlertControllerStyleAlert];
[self.logoutConfirmation addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"settings_sign_out", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self.logoutConfirmation = nil;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self logoutWithConfirmation:NO completion:completion];
});
}
}]];
[self.logoutConfirmation addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self.logoutConfirmation = nil;
if (completion)
{
completion(NO);
}
}
}]];
[self.logoutConfirmation mxk_setAccessibilityIdentifier: @"AppDelegateLogoutConfirmationAlert"];
[self showNotificationAlert:self.logoutConfirmation];
return;
}
// Display a loading wheel during the logout process
id topVC;
if (_masterTabBarController && _masterTabBarController == _masterNavigationController.visibleViewController)
{
topVC = _masterTabBarController.selectedViewController;
}
else
{
topVC = _masterNavigationController.visibleViewController;
}
if (topVC && [topVC respondsToSelector:@selector(startActivityIndicator)])
{
[topVC startActivityIndicator];
}
self.pushRegistry = nil;
isPushRegistered = NO;
@ -2577,7 +2672,12 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
#endif
// Logout all matrix account
[[MXKAccountManager sharedManager] logout];
[[MXKAccountManager sharedManager] logoutWithCompletion:^{
if (completion)
{
completion (YES);
}
// Return to authentication screen
[_masterTabBarController showAuthenticationScreen];
@ -2586,6 +2686,8 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
// Reset the contact manager
[[MXKContactManager sharedManager] reset];
}];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
@ -2907,7 +3009,7 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
typeof(self) self = weakSelf;
self->_errorNotification = nil;
[self logout];
[self logoutWithConfirmation:NO completion:nil];
}
}]];

View file

@ -256,6 +256,8 @@
"room_event_action_view_source" = "View Source";
"room_event_action_report" = "Report content";
"room_event_action_report_prompt_reason" = "Reason for reporting this content";
"room_event_action_kick_prompt_reason" = "Reason for kicking this user";
"room_event_action_ban_prompt_reason" = "Reason for banning this user";
"room_event_action_report_prompt_ignore_user" = "Do you want to hide all messages from this user?";
"room_event_action_save" = "Save";
"room_event_action_resend" = "Resend";

View file

@ -1,6 +1,7 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
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.
@ -57,9 +58,12 @@
} failure:^(NSError *error) {
NSLog(@"[MXRoom+Riot] Failed to update the tag %@ of room (%@)", tag, self.state.roomId);
NSString *userId = self.mxSession.myUser.userId;
// Notify user
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error];
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification
object:error
userInfo:userId ? @{kMXKErrorUserIdKey: userId} : nil];
if (completion)
{

View file

@ -17,11 +17,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.6.12</string>
<string>0.6.13</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.6.12</string>
<string>0.6.13</string>
<key>ITSAppUsesNonExemptEncryption</key>
<true/>
<key>ITSEncryptionExportComplianceCode</key>

View file

@ -391,6 +391,9 @@
}
}
}
// Auto animate the sticker in case of animated gif
bubbleCell.isAutoAnimatedGif = (cellData.attachment && cellData.attachment.type == MXKAttachmentTypeSticker);
}
return cell;

View file

@ -1,6 +1,7 @@
/*
Copyright 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
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.
@ -46,8 +47,8 @@
MXKRoomDataSource *roomDataSource;
if (roomId)
{
roomDataSource = [roomDataSourceManager roomDataSourceForRoom:roomId create:NO];
// Check whether the user knows this room to create the room data source if it doesn't exist.
roomDataSource = [roomDataSourceManager roomDataSourceForRoom:roomId create:([self.mxSession roomWithRoomId:roomId])];
if (roomDataSource)
{
// Prepare text font used to highlight the search pattern.

View file

@ -1,6 +1,7 @@
/*
Copyright 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
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.
@ -39,7 +40,7 @@
// Check attachment if any
if ([searchDataSource.eventFormatter isSupportedAttachment:event])
{
// Note: event.eventType is equal here to MXEventTypeRoomMessage
// Note: event.eventType may be equal here to MXEventTypeRoomMessage or MXEventTypeSticker
attachment = [[MXKAttachment alloc] initWithEvent:event andMatrixSession:searchDataSource.mxSession];
}
@ -101,7 +102,7 @@
- (BOOL)isAttachmentWithThumbnail
{
return (attachment && (attachment.type == MXKAttachmentTypeImage || attachment.type == MXKAttachmentTypeVideo));
return (attachment && (attachment.type == MXKAttachmentTypeImage || attachment.type == MXKAttachmentTypeVideo || attachment.type == MXKAttachmentTypeSticker));
}
- (UIImage*)attachmentIcon

View file

@ -372,13 +372,19 @@
}
else
{
NSLog(@"[MasterTabBarController] Universal link: Logout current sessions and open AuthViewController to complete the registration");
NSLog(@"[MasterTabBarController] Universal link: Prompt to logout current sessions and open AuthViewController to complete the registration");
// Keep a ref on the params
authViewControllerRegistrationParameters = parameters;
// And do a logout out. It will then display AuthViewController
[[AppDelegate theDelegate] logout];
// Prompt to logout. It will then display AuthViewController if the user is logged out.
[[AppDelegate theDelegate] logoutWithConfirmation:YES completion:^(BOOL isLoggedOut) {
if (!isLoggedOut)
{
// Reset temporary params
authViewControllerRegistrationParameters = nil;
}
}];
}
}

View file

@ -1,6 +1,7 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
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.
@ -950,8 +951,39 @@
{
if (editedRoomId)
{
NSString *currentRoomId = editedRoomId;
__weak typeof(self) weakSelf = self;
// confirm leave
NSString *promptMessage = NSLocalizedStringFromTable(@"room_participants_leave_prompt_msg", @"Vector", nil);
currentAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"room_participants_leave_prompt_title", @"Vector", nil)
message:promptMessage
preferredStyle:UIAlertControllerStyleAlert];
[currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
}
}]];
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"leave", @"Vector", nil)
style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
// Check whether the user didn't leave the room yet
MXRoom *room = [self.mainSession roomWithRoomId:editedRoomId];
// TODO: Handle multi-account
MXRoom *room = [self.mainSession roomWithRoomId:currentRoomId];
if (room)
{
[self startActivityIndicator];
@ -966,22 +998,32 @@
[room leave:^{
if (weakSelf)
{
typeof(self) self = weakSelf;
[self stopActivityIndicator];
// Force table refresh
[self cancelEditionMode:YES];
}
} failure:^(NSError *error) {
NSLog(@"[RecentsViewController] Failed to leave room (%@)", room.state.roomId);
// Notify MatrixKit user
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error];
NSLog(@"[RecentsViewController] Failed to leave room");
if (weakSelf)
{
typeof(self) self = weakSelf;
// Notify the end user
NSString *userId = room.mxSession.myUser.userId;
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification
object:error
userInfo:userId ? @{kMXKErrorUserIdKey: userId} : nil];
[self stopActivityIndicator];
// Leave editing mode
[self cancelEditionMode:isRefreshPending];
}
}];
}
else
@ -990,6 +1032,12 @@
[self cancelEditionMode:isRefreshPending];
}
}
}]];
[currentAlert mxk_setAccessibilityIdentifier:@"LeaveEditedRoomAlert"];
[self presentViewController:currentAlert animated:YES completion:nil];
}
}
- (void)updateEditedRoomTag:(NSString*)tag
@ -1023,7 +1071,10 @@
{
if (editedRoomId)
{
__weak typeof(self) weakSelf = self;
// Check whether the user didn't leave the room
// TODO: handle multi-account
MXRoom *room = [self.mainSession roomWithRoomId:editedRoomId];
if (room)
{
@ -1031,23 +1082,32 @@
[room setIsDirect:isDirect withUserId:nil success:^{
if (weakSelf)
{
typeof(self) self = weakSelf;
[self stopActivityIndicator];
// Leave editing mode
[self cancelEditionMode:isRefreshPending];
}
} failure:^(NSError *error) {
if (weakSelf)
{
typeof(self) self = weakSelf;
[self stopActivityIndicator];
NSLog(@"[RecentsViewController] Failed to update direct tag of the room (%@)", editedRoomId);
// Notify MatrixKit user
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error];
// Notify the end user
NSString *userId = self.mainSession.myUser.userId; // TODO: handle multi-account
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification
object:error
userInfo:userId ? @{kMXKErrorUserIdKey: userId} : nil];
// Leave editing mode
[self cancelEditionMode:isRefreshPending];
}
}];
}

View file

@ -1,6 +1,7 @@
/*
Copyright 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
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.
@ -415,9 +416,7 @@
{
// Restore the status bar
typeof(self) self = weakSelf;
self->devicesArray = usersDevicesInfoMap.map[userId].allValues;
// Reload the full table to take into account a potential change on a device status.
[super updateMemberInfo];
}
@ -425,9 +424,15 @@
} failure:^(NSError *error) {
NSLog(@"[RoomMemberDetailsVC] Crypto failed to download device info for user: %@", userId);
if (weakSelf)
{
// Restore the status bar
typeof(self) self = weakSelf;
// Notify the end user
NSString *myUserId = self.mainSession.myUser.userId;
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error userInfo:myUserId ? @{kMXKErrorUserIdKey: myUserId} : nil];
}
// Notify MatrixKit user
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error];
}];
}
@ -938,6 +943,130 @@
[self setPowerLevel:kRiotRoomAdminLevel promptUser:YES];
break;
}
case MXKRoomMemberDetailsActionBan:
{
__weak typeof(self) weakSelf = self;
// Ban
currentAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"room_event_action_ban_prompt_reason", @"Vector", nil)
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[currentAlert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.secureTextEntry = NO;
textField.placeholder = nil;
textField.keyboardType = UIKeyboardTypeDefault;
}];
[currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
}
}]];
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"ban", @"Vector", nil)
style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
[self startActivityIndicator];
// kick user
UITextField *textField = [self->currentAlert textFields].firstObject;
[self.mxRoom banUser:self.mxRoomMember.userId reason:textField.text success:^{
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
} failure:^(NSError *error) {
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
NSLog(@"[RoomMemberDetailVC] Ban user (%@) failed", self.mxRoomMember.userId);
//Alert user
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
}
}]];
[currentAlert mxk_setAccessibilityIdentifier:@"RoomMemberDetailsVCBanAlert"];
[self presentViewController:currentAlert animated:YES completion:nil];
break;
}
case MXKRoomMemberDetailsActionKick:
{
__weak typeof(self) weakSelf = self;
// Kick
currentAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"room_event_action_kick_prompt_reason", @"Vector", nil)
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[currentAlert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.secureTextEntry = NO;
textField.placeholder = nil;
textField.keyboardType = UIKeyboardTypeDefault;
}];
[currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
}
}]];
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"remove", @"Vector", nil)
style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
[self startActivityIndicator];
// kick user
UITextField *textField = [self->currentAlert textFields].firstObject;
[self.mxRoom kickUser:self.mxRoomMember.userId reason:textField.text success:^{
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
} failure:^(NSError *error) {
__strong __typeof(weakSelf)self = weakSelf;
[self stopActivityIndicator];
NSLog(@"[RoomMemberDetailVC] Removing user (%@) failed", self.mxRoomMember.userId);
//Alert user
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
}
}]];
[currentAlert mxk_setAccessibilityIdentifier:@"RoomMemberDetailsVCKickAlert"];
[self presentViewController:currentAlert animated:YES completion:nil];
break;
}
default:
{
[super onActionButtonPressed:sender];

View file

@ -1,6 +1,7 @@
/*
Copyright 2014 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
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.
@ -97,6 +98,8 @@
#import "RoomMembershipExpandedBubbleCell.h"
#import "RoomMembershipExpandedWithPaginationTitleBubbleCell.h"
#import "RoomSelectedStickerBubbleCell.h"
#import "MXKRoomBubbleTableViewCell+Riot.h"
#import "AvatarGenerator.h"
@ -310,6 +313,8 @@
[self.bubblesTableView registerClass:RoomMembershipExpandedBubbleCell.class forCellReuseIdentifier:RoomMembershipExpandedBubbleCell.defaultReuseIdentifier];
[self.bubblesTableView registerClass:RoomMembershipExpandedWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomMembershipExpandedWithPaginationTitleBubbleCell.defaultReuseIdentifier];
[self.bubblesTableView registerClass:RoomSelectedStickerBubbleCell.class forCellReuseIdentifier:RoomSelectedStickerBubbleCell.defaultReuseIdentifier];
// Prepare expanded header
expandedHeader = [ExpandedRoomTitleView roomTitleView];
expandedHeader.delegate = self;
@ -1760,7 +1765,12 @@
{
if (bubbleData.isAttachmentWithThumbnail)
{
if (bubbleData.isPaginationFirstBubble)
// Check whether the provided celldata corresponds to a selected sticker
if (customizedRoomDataSource.selectedEventId && (bubbleData.attachment.type == MXKAttachmentTypeSticker) && [bubbleData.attachment.eventId isEqualToString:customizedRoomDataSource.selectedEventId])
{
cellViewClass = RoomSelectedStickerBubbleCell.class;
}
else if (bubbleData.isPaginationFirstBubble)
{
cellViewClass = isEncryptedRoom ? RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.class : RoomIncomingAttachmentWithPaginationTitleBubbleCell.class;
}
@ -1805,7 +1815,12 @@
// Handle here outgoing bubbles
if (bubbleData.isAttachmentWithThumbnail)
{
if (bubbleData.isPaginationFirstBubble)
// Check whether the provided celldata corresponds to a selected sticker
if (customizedRoomDataSource.selectedEventId && (bubbleData.attachment.type == MXKAttachmentTypeSticker) && [bubbleData.attachment.eventId isEqualToString:customizedRoomDataSource.selectedEventId])
{
cellViewClass = RoomSelectedStickerBubbleCell.class;
}
else if (bubbleData.isPaginationFirstBubble)
{
cellViewClass = isEncryptedRoom ? RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.class :RoomOutgoingAttachmentWithPaginationTitleBubbleCell.class;
}
@ -1909,13 +1924,39 @@
[self showEditButtonAlertMenuForEvent:selectedEvent inCell:cell level:0];
}
}
else if ([actionIdentifier isEqualToString:kMXKRoomBubbleCellTapOnAttachmentView]
&& ((MXKRoomBubbleTableViewCell*)cell).bubbleData.attachment.eventSentState == MXEventSentStateFailed)
else if ([actionIdentifier isEqualToString:kMXKRoomBubbleCellTapOnAttachmentView])
{
if (((MXKRoomBubbleTableViewCell*)cell).bubbleData.attachment.eventSentState == MXEventSentStateFailed)
{
// Shortcut: when clicking on an unsent media, show the action sheet to resend it
MXEvent *selectedEvent = [self.roomDataSource eventWithEventId:((MXKRoomBubbleTableViewCell*)cell).bubbleData.attachment.eventId];
[self dataSource:dataSource didRecognizeAction:kMXKRoomBubbleCellRiotEditButtonPressed inCell:cell userInfo:@{kMXKRoomBubbleCellEventKey:selectedEvent}];
}
else if (((MXKRoomBubbleTableViewCell*)cell).bubbleData.attachment.type == MXKAttachmentTypeSticker)
{
// We don't open the attachments viewer when the user taps on a sticker.
// We consider this tap like a selection.
// Check whether a selection already exist or not
if (customizedRoomDataSource.selectedEventId)
{
[self cancelEventSelection];
}
else
{
// Highlight this event in displayed message
customizedRoomDataSource.selectedEventId = ((MXKRoomBubbleTableViewCell*)cell).bubbleData.attachment.eventId;
}
// Force table refresh
[self dataSource:self.roomDataSource didCellChange:nil];
}
else
{
// Keep default implementation
[super dataSource:dataSource didRecognizeAction:actionIdentifier inCell:cell userInfo:userInfo];
}
}
else if ([actionIdentifier isEqualToString:kRoomEncryptedDataBubbleCellTapOnEncryptionIcon])
{
// Retrieve the tapped event
@ -2156,6 +2197,8 @@
}]];
}
if (attachment.type != MXKAttachmentTypeSticker)
{
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_copy", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
@ -2188,6 +2231,7 @@
}
}]];
}
// Check status of the selected event
if (selectedEvent.sentState == MXEventSentStatePreparing ||
@ -2234,7 +2278,7 @@
}
}
if (level == 1)
if (level == 1 && (attachment.type != MXKAttachmentTypeSticker))
{
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_share", @"Vector", nil)
style:UIAlertActionStyleDefault

View file

@ -1,6 +1,7 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
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.
@ -707,7 +708,8 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
[self stopActivityIndicator];
// Notify user
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error];
NSString *myUserId = self.mainSession.myUser.userId; // TODO: Hanlde multi-account
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error userInfo:myUserId ? @{kMXKErrorUserIdKey: myUserId} : nil];
}
}
}
@ -817,8 +819,8 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
{
[self stopActivityIndicator];
// Notify user
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error];
NSString *myUserId = self.mainSession.myUser.userId; // TODO: Hanlde multi-account
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error userInfo:myUserId ? @{kMXKErrorUserIdKey: myUserId} : nil];
}
}
@ -2446,8 +2448,8 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
NSLog(@"[SettingsViewController] Unignore %@ failed", ignoredUserId);
// Notify user
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error];
NSString *myUserId = session.myUser.userId;
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error userInfo:myUserId ? @{kMXKErrorUserIdKey: myUserId} : nil];
}];
}
@ -2570,63 +2572,24 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
- (void)onSignout:(id)sender
{
[currentAlert dismissViewControllerAnimated:NO completion:nil];
__weak typeof(self) weakSelf = self;
NSString *message = NSLocalizedStringFromTable(@"settings_sign_out_confirmation", @"Vector", nil);
// If the user has encrypted rooms, warn he will lose his e2e keys
MXSession* session = [[AppDelegate theDelegate].mxSessions objectAtIndex:0];
for (MXRoom *room in session.rooms)
{
if (room.state.isEncrypted)
{
message = [message stringByAppendingString:[NSString stringWithFormat:@"\n\n%@", NSLocalizedStringFromTable(@"settings_sign_out_e2e_warn", @"Vector", nil)]];
break;
}
}
// Ask confirmation
currentAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"settings_sign_out", @"Vector", nil) message:message preferredStyle:UIAlertControllerStyleAlert];
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"settings_sign_out", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
// Feedback: disable button and run activity indicator
UIButton *button = (UIButton*)sender;
button.enabled = NO;
[self startActivityIndicator];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
__weak typeof(self) weakSelf = self;
[[MXKAccountManager sharedManager] logout];
[[AppDelegate theDelegate] logoutWithConfirmation:YES completion:^(BOOL isLoggedOut) {
});
}
}]];
[currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action) {
if (weakSelf)
if (!isLoggedOut && weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
// Enable the button and stop activity indicator
button.enabled = YES;
[self stopActivityIndicator];
}
}]];
[currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCSignoutAlert"];
[self presentViewController:currentAlert animated:YES completion:nil];
}];
}
- (void)onRemove3PID:(NSIndexPath*)path
@ -2724,8 +2687,8 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
[self stopActivityIndicator];
// Notify user
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error];
NSString *myUserId = self.mainSession.myUser.userId; // TODO: Hanlde multi-account
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error userInfo:myUserId ? @{kMXKErrorUserIdKey: myUserId} : nil];
}
}];
}
@ -2930,7 +2893,7 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[[MXKAccountManager sharedManager] logout];
[[AppDelegate theDelegate] logoutWithConfirmation:NO completion:nil];
});
}
@ -3413,7 +3376,8 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
}
// Notify user
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error];
NSString *myUserId = session.myUser.userId; // TODO: Hanlde multi-account
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error userInfo:myUserId ? @{kMXKErrorUserIdKey: myUserId} : nil];
}];
}
@ -3515,7 +3479,8 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
}
// Notify user
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error];
NSString *myUserId = session.myUser.userId;
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error userInfo:myUserId ? @{kMXKErrorUserIdKey: myUserId} : nil];
}];
}

View file

@ -21,12 +21,6 @@
@implementation RoomOutgoingAttachmentBubbleCell
- (void)awakeFromNib
{
[super awakeFromNib];
self.readReceiptsAlignment = ReadReceiptAlignmentRight;
}
- (void)customizeTableViewCellRendering
{
[super customizeTableViewCellRendering];

View file

@ -21,12 +21,6 @@
@implementation RoomOutgoingAttachmentWithPaginationTitleBubbleCell
- (void)awakeFromNib
{
[super awakeFromNib];
self.readReceiptsAlignment = ReadReceiptAlignmentRight;
}
- (void)customizeTableViewCellRendering
{
[super customizeTableViewCellRendering];

View file

@ -21,13 +21,6 @@
@implementation RoomOutgoingAttachmentWithoutSenderInfoBubbleCell
- (void)awakeFromNib
{
[super awakeFromNib];
self.readReceiptsAlignment = ReadReceiptAlignmentRight;
}
- (void)customizeTableViewCellRendering
{
[super customizeTableViewCellRendering];

View file

@ -21,12 +21,6 @@
@implementation RoomOutgoingTextMsgBubbleCell
- (void)awakeFromNib
{
[super awakeFromNib];
self.readReceiptsAlignment = ReadReceiptAlignmentRight;
}
- (void)customizeTableViewCellRendering
{
[super customizeTableViewCellRendering];

View file

@ -21,13 +21,6 @@
@implementation RoomOutgoingTextMsgWithoutSenderInfoBubbleCell
- (void)awakeFromNib
{
[super awakeFromNib];
self.readReceiptsAlignment = ReadReceiptAlignmentRight;
}
- (void)customizeTableViewCellRendering
{
[super customizeTableViewCellRendering];

View file

@ -0,0 +1,33 @@
/*
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 "RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.h"
/**
`RoomSelectedStickerBubbleCell` is used to display the current selected sticker if any
*/
@interface RoomSelectedStickerBubbleCell : RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell
@property (weak, nonatomic) IBOutlet UIView *descriptionContainerView;
@property (weak, nonatomic) IBOutlet UIView *arrowView;
@property (weak, nonatomic) IBOutlet UIView *descriptionView;
@property (weak, nonatomic) IBOutlet UILabel *descriptionLabel;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *userNameLabelTopConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *attachViewLeadingConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *descriptionContainerViewBottomConstraint;
@end

View file

@ -0,0 +1,242 @@
/*
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 "RoomSelectedStickerBubbleCell.h"
#import "RoomEncryptedDataBubbleCell.h"
#import "RoomIncomingAttachmentBubbleCell.h"
#import "RoomIncomingAttachmentWithoutSenderInfoBubbleCell.h"
#import "RoomIncomingAttachmentWithPaginationTitleBubbleCell.h"
#import "RoomIncomingEncryptedAttachmentBubbleCell.h"
#import "RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.h"
#import "RiotDesignValues.h"
@implementation RoomSelectedStickerBubbleCell
- (void)awakeFromNib
{
[super awakeFromNib];
// define arrow mask
CAShapeLayer *arrowMaskLayer = [[CAShapeLayer alloc] init];
arrowMaskLayer.frame = self.arrowView.bounds;
CGSize viewSize = self.arrowView.frame.size;
UIBezierPath *path = [[UIBezierPath alloc] init];
[path moveToPoint:CGPointMake(0, viewSize.height)]; // arrow left bottom point
[path addLineToPoint:CGPointMake(viewSize.width / 2, 0)]; // arrow head
[path addLineToPoint:CGPointMake(viewSize.width, viewSize.height)]; // arrow right bottom point
[path closePath]; // arrow top side
arrowMaskLayer.path = path.CGPath;
self.arrowView.layer.mask = arrowMaskLayer;
self.arrowView.backgroundColor = kRiotSecondaryBgColor;
self.descriptionView.backgroundColor = kRiotSecondaryBgColor;
[self.descriptionView.layer setCornerRadius:10];
}
- (void)render:(MXKCellData *)cellData
{
[self prepareRender:cellData];
if (bubbleData)
{
// Retrieve the component which stores the sticker (Only one component is handled by the bubble in case of sticker).
MXKRoomBubbleComponent *component = bubbleData.bubbleComponents.firstObject;
// Handle the pagination and the sender information
// Look for the original cell class to extract the constraints value.
Class<MXKCellRendering> modelCellViewClass = nil;
if (bubbleData.shouldHideSenderInformation)
{
modelCellViewClass = bubbleData.isEncryptedRoom ? RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.class : RoomIncomingAttachmentWithoutSenderInfoBubbleCell.class;
self.paginationTitleView.hidden = YES;
self.pictureView.hidden = YES;
self.userNameLabel.hidden = YES;
self.userNameTapGestureMaskView.userInteractionEnabled = NO;
}
else
{
if (bubbleData.isPaginationFirstBubble)
{
modelCellViewClass = bubbleData.isEncryptedRoom ? RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.class : RoomIncomingAttachmentWithPaginationTitleBubbleCell.class;
self.paginationTitleView.hidden = NO;
self.paginationLabel.text = [[bubbleData.eventFormatter dateStringFromDate:bubbleData.date withTime:NO] uppercaseString];
}
else
{
modelCellViewClass = bubbleData.isEncryptedRoom ? RoomIncomingEncryptedAttachmentBubbleCell.class : RoomIncomingAttachmentBubbleCell.class;
self.paginationTitleView.hidden = YES;
}
// Hanlde sender avatar
self.pictureView.hidden = NO;
NSString *avatarThumbURL = nil;
if (bubbleData.senderAvatarUrl)
{
// Suppose this url is a matrix content uri, we use SDK to get the well adapted thumbnail from server
avatarThumbURL = [bubbleData.mxSession.matrixRestClient urlOfContentThumbnail:bubbleData.senderAvatarUrl toFitViewSize:self.pictureView.frame.size withMethod:MXThumbnailingMethodCrop];
}
self.pictureView.enableInMemoryCache = YES;
[self.pictureView setImageURL:avatarThumbURL withType:nil andImageOrientation:UIImageOrientationUp previewImage: bubbleData.senderAvatarPlaceholder ? bubbleData.senderAvatarPlaceholder : self.picturePlaceholder];
// Display sender's name except if the name appears in the displayed text (see emote and membership events)
if (bubbleData.shouldHideSenderName == NO)
{
if (bubbleData.senderFlair)
{
[self renderSenderFlair];
}
else
{
self.userNameLabel.text = bubbleData.senderDisplayName;
}
self.userNameLabel.hidden = NO;
self.userNameTapGestureMaskView.userInteractionEnabled = YES;
}
else
{
self.userNameLabel.hidden = YES;
self.userNameTapGestureMaskView.userInteractionEnabled = NO;
}
}
// Retrieve the suitable content size for the attachment thumbnail
CGSize contentSize = bubbleData.contentSize;
// Update image view frame in order to center loading wheel (if any)
CGRect frame = self.attachmentView.frame;
frame.size.width = contentSize.width;
frame.size.height = contentSize.height;
self.attachmentView.frame = frame;
// Retrieve the MIME type
NSString *mimetype = nil;
if (bubbleData.attachment.thumbnailInfo)
{
mimetype = bubbleData.attachment.thumbnailInfo[@"mimetype"];
}
else if (bubbleData.attachment.contentInfo)
{
mimetype = bubbleData.attachment.contentInfo[@"mimetype"];
}
// Display the sticker
self.attachmentView.backgroundColor = [UIColor clearColor];
self.attachmentView.mediaFolder = bubbleData.roomId;
self.attachmentView.enableInMemoryCache = YES;
[self.attachmentView setAttachmentThumb:bubbleData.attachment];
// Set the description
NSAttributedString *description = component.attributedTextMessage;
if (description.length)
{
self.descriptionContainerView.hidden = NO;
self.descriptionLabel.attributedText = description;
}
else
{
self.descriptionContainerView.hidden = YES;
}
// Adjust Attachment width constant
self.attachViewWidthConstraint.constant = contentSize.width;
// Handle the encryption view
if (bubbleData.isEncryptedRoom)
{
// Set the right device info icon
self.encryptionStatusView.hidden = NO;
self.encryptionStatusView.image = [RoomEncryptedDataBubbleCell encryptionIconForEvent:component.event andSession:bubbleData.mxSession];
}
else
{
self.encryptionStatusView.hidden = YES;
}
// Hide by default the info container
self.bubbleInfoContainer.hidden = YES;
// Adjust the layout according to the original cell, the one used to display the sticker unselected.
if ([modelCellViewClass nib])
{
MXKRoomBubbleTableViewCell* cell= (MXKRoomBubbleTableViewCell*)[[modelCellViewClass nib] instantiateWithOwner:nil options:nil].firstObject;
if (cell.userNameLabel)
{
frame = cell.userNameLabel.frame;
self.userNameLabelTopConstraint.constant = frame.origin.y;
}
frame = cell.attachmentView.frame;
self.attachViewLeadingConstraint.constant = frame.origin.x;
self.attachViewTopConstraint.constant = cell.attachViewTopConstraint.constant;
self.attachViewBottomConstraint.constant = cell.attachViewBottomConstraint.constant;
self.bubbleInfoContainerTopConstraint.constant = cell.bubbleInfoContainerTopConstraint.constant;
}
}
}
+ (CGFloat)heightForCellData:(MXKCellData*)cellData withMaximumWidth:(CGFloat)maxWidth
{
// Sanity check: accept only object of MXKRoomBubbleCellData classes or sub-classes
NSParameterAssert([cellData isKindOfClass:[MXKRoomBubbleCellData class]]);
MXKRoomBubbleCellData *bubbleData = (MXKRoomBubbleCellData*)cellData;
// Look for the original cell class to extract the constraints value.
Class modelCellViewClass = nil;
if (bubbleData.shouldHideSenderInformation)
{
modelCellViewClass = bubbleData.isEncryptedRoom ? RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.class : RoomIncomingAttachmentWithoutSenderInfoBubbleCell.class;
}
else
{
if (bubbleData.isPaginationFirstBubble)
{
modelCellViewClass = bubbleData.isEncryptedRoom ? RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.class : RoomIncomingAttachmentWithPaginationTitleBubbleCell.class;
}
else
{
modelCellViewClass = bubbleData.isEncryptedRoom ? RoomIncomingEncryptedAttachmentBubbleCell.class : RoomIncomingAttachmentBubbleCell.class;
}
}
CGFloat rowHeight = [modelCellViewClass heightForCellData:cellData withMaximumWidth:maxWidth];
// Finalize the cell height by adding the height of the description.
// Retrieve the component which stores the sticker (Only one component is handled by the bubble in case of sticker).
MXKRoomBubbleComponent *component = bubbleData.bubbleComponents.firstObject;
NSAttributedString *description = component.attributedTextMessage;
if (description.length)
{
RoomSelectedStickerBubbleCell* cell = (RoomSelectedStickerBubbleCell*)[self cellWithOriginalXib];
CGRect frame = cell.frame;
frame.size.width = maxWidth;
frame.size.height = 300;
cell.frame = frame;
cell.descriptionLabel.attributedText = description;
[cell layoutIfNeeded];
rowHeight += cell.descriptionContainerView.frame.size.height + cell.descriptionContainerViewBottomConstraint.constant;
}
return rowHeight;
}
@end

View file

@ -0,0 +1,209 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14109" 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="14088"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<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"/>
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="WmY-Jw-mqv" customClass="RoomSelectedStickerBubbleCell">
<rect key="frame" x="0.0" y="0.0" width="600" height="180"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="WmY-Jw-mqv" id="ef1-Tq-U3Z">
<rect key="frame" x="0.0" y="0.0" width="600" height="179.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="SFg-55-RF4" userLabel="Pagination Title View">
<rect key="frame" x="67" y="10" width="523" height="24"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wkY-7Y-sGw" userLabel="Pagination Label">
<rect key="frame" x="0.0" y="0.0" width="513" height="18"/>
<accessibility key="accessibilityConfiguration" identifier="PaginationLabel"/>
<constraints>
<constraint firstAttribute="height" constant="18" id="PiZ-Ag-oxc"/>
</constraints>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<color key="textColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0kR-4b-Wav" userLabel="Pagination Separator View">
<rect key="frame" x="0.0" y="23" width="523" height="1"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="wkY-7Y-sGw" secondAttribute="trailing" constant="10" id="4DU-xA-diS"/>
<constraint firstItem="wkY-7Y-sGw" firstAttribute="top" secondItem="SFg-55-RF4" secondAttribute="top" id="6Cz-bj-kUg"/>
<constraint firstItem="0kR-4b-Wav" firstAttribute="leading" secondItem="SFg-55-RF4" secondAttribute="leading" id="JnC-Xe-1qa"/>
<constraint firstAttribute="bottom" secondItem="0kR-4b-Wav" secondAttribute="bottom" id="PHN-VL-Vv5"/>
<constraint firstAttribute="height" constant="24" id="Qo9-cw-LCa"/>
<constraint firstItem="0kR-4b-Wav" firstAttribute="top" secondItem="wkY-7Y-sGw" secondAttribute="bottom" constant="5" id="c44-l0-OW4"/>
<constraint firstAttribute="trailing" secondItem="0kR-4b-Wav" secondAttribute="trailing" id="i6x-Qa-JZG"/>
<constraint firstItem="wkY-7Y-sGw" firstAttribute="leading" secondItem="SFg-55-RF4" secondAttribute="leading" id="uq9-MP-Dmm"/>
</constraints>
</view>
<view clipsSubviews="YES" contentMode="scaleAspectFill" translatesAutoresizingMaskIntoConstraints="NO" id="hgp-Z5-rAj" userLabel="Picture View" customClass="MXKImageView">
<rect key="frame" x="13" y="54" 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="NQk-ck-Lo8"/>
<constraint firstAttribute="height" constant="30" id="dNT-QU-CUG"/>
</constraints>
</view>
<imageView userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="e2e_verified.png" translatesAutoresizingMaskIntoConstraints="NO" id="SfO-mO-OOz">
<rect key="frame" x="41" y="68" width="28" height="28"/>
<accessibility key="accessibilityConfiguration" identifier="EncryptionStatusView"/>
<constraints>
<constraint firstAttribute="width" constant="28" id="AZL-1M-R2e"/>
<constraint firstAttribute="height" constant="28" id="P35-h8-egI"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="User name:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="8" translatesAutoresizingMaskIntoConstraints="NO" id="q9c-0p-QyP">
<rect key="frame" x="67" y="54" width="448" height="18"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="UserNameLabel"/>
<constraints>
<constraint firstAttribute="height" constant="18" placeholder="YES" id="5ZO-W1-tS2"/>
</constraints>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<color key="textColor" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleAspectFit" translatesAutoresizingMaskIntoConstraints="NO" id="5IE-JS-uf3" userLabel="Attachment View" customClass="MXKImageView">
<rect key="frame" x="67" y="75" width="192" height="46.5"/>
<color key="backgroundColor" red="0.93725490196078431" green="0.93725490196078431" blue="0.95686274509803926" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="AttachmentView"/>
<constraints>
<constraint firstAttribute="width" constant="192" id="9zO-jU-qTb"/>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="34" id="C5F-6D-LZx"/>
</constraints>
</view>
<view hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IOg-Kt-8vW">
<rect key="frame" x="515" y="54" width="70" height="125.5"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="BubbleInfoContainer"/>
<constraints>
<constraint firstAttribute="width" constant="70" id="tLr-6k-ArA"/>
</constraints>
</view>
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3b7-4a-YL0">
<rect key="frame" x="12" y="3" width="576" height="174"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="4ru-pn-Aka">
<rect key="frame" x="57" y="48" width="458" height="30"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lgz-UT-c2U">
<rect key="frame" x="67" y="131.5" width="53.5" height="38"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Bk9-l7-4ug">
<rect key="frame" x="10" y="0.0" width="20" height="10"/>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
<constraints>
<constraint firstAttribute="height" constant="10" id="JYF-su-bXV"/>
<constraint firstAttribute="width" constant="20" id="o8q-GT-1HB"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lql-N7-aOv">
<rect key="frame" x="0.0" y="10" width="53.5" height="28"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PwC-m9-IC3">
<rect key="frame" x="8" y="5" width="37.5" height="18"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="PwC-m9-IC3" secondAttribute="bottom" constant="5" id="9IY-ct-GK4"/>
<constraint firstItem="PwC-m9-IC3" firstAttribute="top" secondItem="lql-N7-aOv" secondAttribute="top" constant="5" id="Ptz-mS-jIO"/>
<constraint firstAttribute="trailing" secondItem="PwC-m9-IC3" secondAttribute="trailing" constant="8" id="aFv-U3-X8p"/>
<constraint firstItem="PwC-m9-IC3" firstAttribute="leading" secondItem="lql-N7-aOv" secondAttribute="leading" constant="8" id="wdB-ZN-l8I"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="lql-N7-aOv" firstAttribute="top" secondItem="Bk9-l7-4ug" secondAttribute="bottom" id="4ls-NU-aG9"/>
<constraint firstAttribute="trailing" secondItem="lql-N7-aOv" secondAttribute="trailing" id="80S-HL-oVy"/>
<constraint firstItem="Bk9-l7-4ug" firstAttribute="leading" secondItem="lgz-UT-c2U" secondAttribute="leading" constant="10" id="AVi-Mf-7UD"/>
<constraint firstItem="lql-N7-aOv" firstAttribute="leading" secondItem="lgz-UT-c2U" secondAttribute="leading" id="BjZ-jz-Xmd"/>
<constraint firstAttribute="bottom" secondItem="lql-N7-aOv" secondAttribute="bottom" id="m3I-Ml-oAP"/>
<constraint firstItem="Bk9-l7-4ug" firstAttribute="top" secondItem="lgz-UT-c2U" secondAttribute="top" id="qsk-cV-cyd"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="4ru-pn-Aka" firstAttribute="bottom" secondItem="q9c-0p-QyP" secondAttribute="bottom" constant="6" id="0Cl-Or-gY1"/>
<constraint firstItem="3b7-4a-YL0" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="topMargin" constant="-8" id="10i-70-PDz"/>
<constraint firstItem="SfO-mO-OOz" firstAttribute="top" secondItem="SFg-55-RF4" secondAttribute="bottom" constant="34" id="7ug-dI-P4H"/>
<constraint firstItem="5IE-JS-uf3" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" constant="75" id="96U-67-5TP"/>
<constraint firstItem="lgz-UT-c2U" firstAttribute="leading" secondItem="5IE-JS-uf3" secondAttribute="leading" id="B0j-24-Z8x"/>
<constraint firstAttribute="trailing" secondItem="q9c-0p-QyP" secondAttribute="trailing" constant="85" id="Bkh-h2-JOQ"/>
<constraint firstItem="4ru-pn-Aka" firstAttribute="trailing" secondItem="q9c-0p-QyP" secondAttribute="trailing" id="Coe-gt-nwe"/>
<constraint firstAttribute="bottom" secondItem="lgz-UT-c2U" secondAttribute="bottom" constant="10" id="IAx-xw-tKp"/>
<constraint firstItem="q9c-0p-QyP" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" constant="54" id="Ixr-7h-f8j"/>
<constraint firstItem="4ru-pn-Aka" firstAttribute="top" secondItem="q9c-0p-QyP" secondAttribute="top" constant="-6" id="K0X-dz-PvH"/>
<constraint firstItem="lgz-UT-c2U" firstAttribute="top" secondItem="5IE-JS-uf3" secondAttribute="bottom" constant="10" id="MOf-5l-vZU"/>
<constraint firstItem="5IE-JS-uf3" firstAttribute="leading" secondItem="ef1-Tq-U3Z" secondAttribute="leading" constant="67" id="Q0k-2f-DNG"/>
<constraint firstAttribute="bottom" secondItem="IOg-Kt-8vW" secondAttribute="bottom" id="TPw-iE-nii"/>
<constraint firstItem="q9c-0p-QyP" firstAttribute="leading" secondItem="5IE-JS-uf3" secondAttribute="leading" id="UnW-3c-mf6"/>
<constraint firstItem="IOg-Kt-8vW" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" constant="54" id="XSL-TG-m62"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="lgz-UT-c2U" secondAttribute="trailing" constant="15" id="YHV-bx-NYo"/>
<constraint firstItem="3b7-4a-YL0" firstAttribute="leading" secondItem="ef1-Tq-U3Z" secondAttribute="leadingMargin" constant="-8" id="aGh-ad-trR"/>
<constraint firstAttribute="trailingMargin" secondItem="3b7-4a-YL0" secondAttribute="trailing" constant="-8" id="abE-n9-N8T"/>
<constraint firstItem="4ru-pn-Aka" firstAttribute="leading" secondItem="q9c-0p-QyP" secondAttribute="leading" constant="-10" id="djP-gt-Mas"/>
<constraint firstAttribute="trailing" secondItem="IOg-Kt-8vW" secondAttribute="trailing" constant="15" id="hQV-lO-7aQ"/>
<constraint firstItem="SFg-55-RF4" firstAttribute="leading" secondItem="q9c-0p-QyP" secondAttribute="leading" id="hwY-nq-Oyw"/>
<constraint firstAttribute="trailing" secondItem="SFg-55-RF4" secondAttribute="trailing" constant="10" id="jvR-oT-EQF"/>
<constraint firstItem="SfO-mO-OOz" firstAttribute="leading" secondItem="ef1-Tq-U3Z" secondAttribute="leading" constant="41" id="nW4-ob-PSQ"/>
<constraint firstItem="hgp-Z5-rAj" firstAttribute="leading" secondItem="ef1-Tq-U3Z" secondAttribute="leading" constant="13" id="tuw-aU-ncu"/>
<constraint firstItem="SFg-55-RF4" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" constant="10" id="wJX-7V-bJB"/>
<constraint firstAttribute="bottomMargin" secondItem="3b7-4a-YL0" secondAttribute="bottom" constant="-8" id="wpa-8Z-Gy3"/>
<constraint firstItem="hgp-Z5-rAj" firstAttribute="top" secondItem="q9c-0p-QyP" secondAttribute="top" id="xVT-Xe-sq0"/>
</constraints>
</tableViewCellContentView>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" identifier="RoomBubbleCell"/>
<connections>
<outlet property="arrowView" destination="Bk9-l7-4ug" id="mDe-UL-4nb"/>
<outlet property="attachViewBottomConstraint" destination="MOf-5l-vZU" id="Xr2-3T-bs2"/>
<outlet property="attachViewLeadingConstraint" destination="Q0k-2f-DNG" id="JEV-IK-2NO"/>
<outlet property="attachViewMinHeightConstraint" destination="C5F-6D-LZx" id="frk-Ox-WbA"/>
<outlet property="attachViewTopConstraint" destination="96U-67-5TP" id="Ugm-cH-32E"/>
<outlet property="attachViewWidthConstraint" destination="9zO-jU-qTb" id="fOO-VW-fe1"/>
<outlet property="attachmentView" destination="5IE-JS-uf3" id="imT-1z-hR1"/>
<outlet property="bubbleInfoContainer" destination="IOg-Kt-8vW" id="TAw-QY-Y9e"/>
<outlet property="bubbleInfoContainerTopConstraint" destination="XSL-TG-m62" id="qVf-vJ-4aP"/>
<outlet property="bubbleOverlayContainer" destination="3b7-4a-YL0" id="KNb-h4-YHD"/>
<outlet property="descriptionContainerView" destination="lgz-UT-c2U" id="Tip-cN-J3S"/>
<outlet property="descriptionContainerViewBottomConstraint" destination="IAx-xw-tKp" id="m9G-uX-pnD"/>
<outlet property="descriptionLabel" destination="PwC-m9-IC3" id="Xf9-RK-KCJ"/>
<outlet property="descriptionView" destination="lql-N7-aOv" id="7Sb-9t-j0p"/>
<outlet property="encryptionStatusView" destination="SfO-mO-OOz" id="8BV-oD-e0i"/>
<outlet property="paginationLabel" destination="wkY-7Y-sGw" id="9Uh-tX-t0I"/>
<outlet property="paginationSeparatorView" destination="0kR-4b-Wav" id="c7x-Sh-aj6"/>
<outlet property="paginationTitleView" destination="SFg-55-RF4" id="mbP-6I-gOn"/>
<outlet property="pictureView" destination="hgp-Z5-rAj" id="rKM-QG-RJN"/>
<outlet property="userNameLabel" destination="q9c-0p-QyP" id="JId-R7-LoM"/>
<outlet property="userNameLabelTopConstraint" destination="Ixr-7h-f8j" id="RqB-b5-7D2"/>
<outlet property="userNameTapGestureMaskView" destination="4ru-pn-Aka" id="28k-f4-1LY"/>
</connections>
</tableViewCell>
</objects>
<resources>
<image name="e2e_verified.png" width="10" height="12"/>
</resources>
</document>

View file

@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>0.6.12</string>
<string>0.6.13</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSExtension</key>

View file

@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>0.6.12</string>
<string>0.6.13</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSExtension</key>

View file

@ -30,7 +30,9 @@ rm -r "$tmp"
if [ -z "$xcent" ]
then
echo "$1 has no archived-expanded-entitlements.xcent."
exit 2
# It seems that since Xcode 9.3, this file is no more present (https://forums.developer.apple.com/thread/99923)
#exit 2
fi
# Check the aps-environment embedded in the binary.