Merge remote-tracking branch 'upstream/develop' into wiedmer_proximity_sensor

This commit is contained in:
Simon Wiedmer
2022-02-14 08:24:25 +01:00
323 changed files with 5645 additions and 1918 deletions
@@ -125,7 +125,7 @@
"notice_room_history_visible_to_members_from_joined_point" = "%@ hat den zukünftigen Raumverlauf für alle Raumteilnehmer ab deren Einladung sichtbar gemacht.";
"notice_room_history_visible_to_members_from_joined_point_for_dm" = "%@ hat den zukünftigen Verlauf für alle Raumteilnehmer ab deren Einladung sichtbar gemacht.";
"notice_crypto_unable_to_decrypt" = "** Entschlüsselung nicht möglich: %@ **";
"notice_crypto_error_unknown_inbound_session_id" = "Die Sitzung des Absenders hat uns keine Schlüssel für diese Nachricht gesendet.";
"notice_crypto_error_unknown_inbound_session_id" = "Die absendende Sitzung hat uns keine Schlüssel für diese Nachricht gesendet.";
"notice_sticker" = "Aufkleber";
"notice_in_reply_to" = "Als Antwort auf";
// room display name
@@ -99,7 +99,7 @@
"notice_image_attachment" = "anexo de imagem";
"notice_audio_attachment" = "anexo de áudio";
"notice_video_attachment" = "anexo de vídeo";
"notice_location_attachment" = "anexo de local";
"notice_location_attachment" = "anexo de localização";
"notice_file_attachment" = "anexo de arquivo";
"notice_invalid_attachment" = "anexo inválido";
"notice_unsupported_attachment" = "Anexo insuportado: %@";
@@ -476,3 +476,6 @@
"auth_username_in_use" = "Имя пользователя занято";
"rename" = "Переименовать";
"room_displayname_all_other_members_left" = "%@ (Вышел)";
"attachment_unsupported_preview_message" = "Этот тип файла не поддерживается.";
"attachment_unsupported_preview_title" = "Не удалось показать предварительный просмотр";
"message_reply_to_sender_sent_their_location" = "поделились своим местоположением.";
@@ -119,9 +119,9 @@
// Others
"user_id_title" = "ID používateľa:";
"e2e_passphrase_create" = "Vytvoriť heslo";
"e2e_passphrase_confirm" = "Potvrďte heslo";
"e2e_passphrase_enter" = "Zadajte heslo";
"e2e_passphrase_create" = "Vytvoriť prístupovú frázu";
"e2e_passphrase_confirm" = "Potvrďte prístupovú frázu";
"e2e_passphrase_enter" = "Zadajte prístupovú frázu";
// Search
"search_no_results" = "Žiadne výsledky";
@@ -547,3 +547,4 @@
"account_link_email" = "Prepojený email";
"account_linked_emails" = "Prepojené e-maily";
"room_event_encryption_info_event_fingerprint_key" = "Deklarovaný kľúč odtlačkov prstov Ed25519\n";
"notification_settings_notify_all_other" = "Oznámiť pre všetky ostatné správy/miestnosti";
@@ -259,9 +259,9 @@
"user_id_placeholder" = "t.ex.: @sven:hemserver";
"ssl_homeserver_url" = "Hemserver-URL: %@";
// Permissions
"camera_access_not_granted_for_call" = "Videosamtal kräver åtkomst till kameran men %@ har inte behörighet att använda den";
"microphone_access_not_granted_for_call" = "Samtal kräver åtkomst till mikrofonen men %@ har inte behörighet att använda den";
"local_contacts_access_not_granted" = "Upptäckt av användare från lokala kontakter kräver åtkomst till dina kontakter men %@ har inte behörighet att komma åt dem";
"camera_access_not_granted_for_call" = "Videosamtal kräver åtkomst till kameran men %@ är inte behörig att använda den";
"microphone_access_not_granted_for_call" = "Samtal kräver åtkomst till mikrofonen men %@ är inte behörig att använda den";
"local_contacts_access_not_granted" = "Upptäckt av användare från lokala kontakter kräver åtkomst till dina kontakter men %@ är inte behörig att komma åt dem";
"local_contacts_access_discovery_warning_title" = "Användarupptäckt";
"local_contacts_access_discovery_warning" = "För att upptäcka kontakter som redan använder Matrix kan %@ skicka e-postadresser och telefonnummer i din adressbok till din valda Matrixidentitetsserver. Där det stöds hashas personuppgifter innan de skickas - kontrollera din identitetsservers integritetspolicy för mer information.";
// Country picker
@@ -462,7 +462,7 @@
"call_voice_with_user" = "Röstsamtal med %@";
"call_ringing" = "Ringer…";
"e2e_passphrase_too_short" = "Lösenfras för kort (den måste vara minst %d tecken långt)";
"microphone_access_not_granted_for_voice_message" = "Röstmeddelanden kräver åtkomst till mikrofonen, men %@ har inte behörighet att använda den";
"microphone_access_not_granted_for_voice_message" = "Röstmeddelanden kräver åtkomst till mikrofonen, men %@ är inte behörig att använda den";
"message_reply_to_sender_sent_a_voice_message" = "skickade ett röstmeddelande.";
"attachment_large_with_resolution" = "Stor %@ (~%@)";
"attachment_medium_with_resolution" = "Mellan %@ (~%@)";
@@ -175,7 +175,11 @@
_attachmentsCollection.hidden = YES;
// Display collection cell in full screen
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
self.automaticallyAdjustsScrollViewInsets = NO;
#pragma clang diagnostic pop
}
- (BOOL)prefersStatusBarHidden
@@ -215,6 +215,8 @@
// and report the inputAccessoryView.superview of the firstResponder in self.keyboardView.
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
- (void)setKeyboardHeight:(CGFloat)keyboardHeight
{
// Deduce the bottom inset for the scroll view (Don't forget the potential tabBar)
@@ -229,6 +231,7 @@
insets.bottom = scrollViewInsetBottom;
self.authenticationScrollView.contentInset = insets;
}
#pragma clang diagnostic pop
- (void)destroy
{
@@ -981,7 +984,10 @@
{
// Trigger here a register request in order to associate the filled userId and password to the current session id
// This will check the availability of the userId at the same time
NSDictionary *parameters = @{@"auth": @{},
NSDictionary *parameters = @{@"auth": @{
@"session": self.authInputsView.authSession.session,
@"type": kMXLoginFlowTypeDummy
},
@"username": self.authInputsView.userId,
@"password": self.authInputsView.password,
@"bind_email": @(NO),
@@ -152,7 +152,7 @@ NSString* const kMXKCountryPickerViewControllerCountryCellId = @"kMXKCountryPick
{
UISearchController *searchController = [[UISearchController alloc]
initWithSearchResultsController:nil];
searchController.dimsBackgroundDuringPresentation = NO;
searchController.obscuresBackgroundDuringPresentation = NO;
searchController.hidesNavigationBarDuringPresentation = NO;
searchController.searchResultsUpdater = self;
@@ -92,6 +92,8 @@
[[[self class] nib] instantiateWithOwner:self options:nil];
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
// Adjust search bar Top constraint to take into account potential navBar.
if (_groupsSearchBarTopConstraint)
{
@@ -123,6 +125,7 @@
[NSLayoutConstraint activateConstraints:@[_groupsTableViewBottomConstraint]];
}
#pragma clang diagnostic pop
// Hide search bar by default
[self hideSearchBar:YES];
@@ -209,6 +212,8 @@
self.keyboardView = _groupsSearchBar.inputAccessoryView.superview;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
- (void)setKeyboardHeight:(CGFloat)keyboardHeight
{
// Deduce the bottom constraint for the table view (Don't forget the potential tabBar)
@@ -225,6 +230,7 @@
// Force layout immediately to take into account new constraint
[self.view layoutIfNeeded];
}
#pragma clang diagnostic pop
- (void)destroy
{
@@ -160,7 +160,7 @@ NSString* const kMXKLanguagePickerCellDataKeyLanguage = @"language";
{
UISearchController *searchController = [[UISearchController alloc]
initWithSearchResultsController:nil];
searchController.dimsBackgroundDuringPresentation = NO;
searchController.obscuresBackgroundDuringPresentation = NO;
searchController.hidesNavigationBarDuringPresentation = NO;
searchController.searchResultsUpdater = self;
@@ -97,6 +97,8 @@
[[[self class] nib] instantiateWithOwner:self options:nil];
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
// Adjust search bar Top constraint to take into account potential navBar.
if (_recentsSearchBarTopConstraint)
{
@@ -126,6 +128,7 @@
_recentsTableViewBottomConstraint.active = YES;
}
#pragma clang diagnostic pop
// Hide search bar by default
[self hideSearchBar:YES];
@@ -229,6 +232,8 @@
self.keyboardView = _recentsSearchBar.inputAccessoryView.superview;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
- (void)setKeyboardHeight:(CGFloat)keyboardHeight
{
// Deduce the bottom constraint for the table view (Don't forget the potential tabBar)
@@ -245,6 +250,7 @@
// Force layout immediately to take into account new constraint
[self.view layoutIfNeeded];
}
#pragma clang diagnostic pop
- (void)destroy
{
@@ -421,7 +427,9 @@
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
// Let dataSource provide the section header.
return [dataSource viewForHeaderInSection:section withFrame:[tableView rectForHeaderInSection:section]];
return [dataSource viewForHeaderInSection:section
withFrame:[tableView rectForHeaderInSection:section]
inTableView:tableView];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
@@ -105,6 +105,8 @@
// Adjust Top and Bottom constraints to take into account potential navBar and tabBar.
[NSLayoutConstraint deactivateConstraints:@[_membersSearchBarTopConstraint, _membersTableViewBottomConstraint]];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
_membersSearchBarTopConstraint = [NSLayoutConstraint constraintWithItem:self.topLayoutGuide
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
@@ -120,6 +122,7 @@
attribute:NSLayoutAttributeBottom
multiplier:1.0f
constant:0.0f];
#pragma clang diagnostic pop
[NSLayoutConstraint activateConstraints:@[_membersSearchBarTopConstraint, _membersTableViewBottomConstraint]];
@@ -225,6 +228,8 @@
self.keyboardView = _membersSearchBar.inputAccessoryView.superview;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
- (void)setKeyboardHeight:(CGFloat)keyboardHeight
{
// Deduce the bottom constraint for the table view (Don't forget the potential tabBar)
@@ -241,6 +246,7 @@
// Force layout immediately to take into account new constraint
[self.view layoutIfNeeded];
}
#pragma clang diagnostic pop
- (void)destroy
{
@@ -76,6 +76,8 @@
// Adjust Top and Bottom constraints to take into account potential navBar and tabBar.
[NSLayoutConstraint deactivateConstraints:@[_searchSearchBarTopConstraint, _searchTableViewBottomConstraint]];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
_searchSearchBarTopConstraint = [NSLayoutConstraint constraintWithItem:self.topLayoutGuide
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
@@ -91,6 +93,7 @@
attribute:NSLayoutAttributeBottom
multiplier:1.0f
constant:0.0f];
#pragma clang diagnostic pop
[NSLayoutConstraint activateConstraints:@[_searchSearchBarTopConstraint, _searchTableViewBottomConstraint]];
@@ -140,6 +143,8 @@
self.keyboardView = _searchSearchBar.inputAccessoryView.superview;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
- (void)setKeyboardHeight:(CGFloat)keyboardHeight
{
// Deduce the bottom constraint for the table view (Don't forget the potential tabBar)
@@ -156,6 +161,7 @@
// Force layout immediately to take into account new constraint
[self.view layoutIfNeeded];
}
#pragma clang diagnostic pop
- (void)destroy
{
@@ -133,6 +133,9 @@ NSString *const kMXKWebViewViewControllerJavaScriptEnableLog =
multiplier:1.0
constant:0];
// Force webview in full height
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:webView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
@@ -147,6 +150,7 @@ NSString *const kMXKWebViewViewControllerJavaScriptEnableLog =
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0];
#pragma clang diagnostic pop
[NSLayoutConstraint activateConstraints:@[leftConstraint, rightConstraint, topConstraint, bottomConstraint]];
+140 -136
View File
@@ -104,7 +104,9 @@ public class UTI: RawRepresentable, Equatable {
// UTTypeCreatePreferredIdentifierForTag only returns nil if the tag class is unknwown, which can't happen to us since we use an
// enum of known values. Hence we can force-cast the result.
// swiftlint:disable force_unwrapping
let identifier = (unmanagedIdentifier?.takeRetainedValue() as String?)!
// swiftlint:enable force_unwrapping
self.init(rawValue: identifier)
}
@@ -122,7 +124,7 @@ public class UTI: RawRepresentable, Equatable {
public convenience init(withExtension fileExtension: String, conformingTo conforming: UTI? = nil) {
self.init(withTagClass:.fileExtension, value: fileExtension, conformingTo: conforming)
self.init(withTagClass: .fileExtension, value: fileExtension, conformingTo: conforming)
}
/**
@@ -138,7 +140,7 @@ public class UTI: RawRepresentable, Equatable {
public convenience init(withMimeType mimeType: String, conformingTo conforming: UTI? = nil) {
self.init(withTagClass:.mimeType, value: mimeType, conformingTo: conforming)
self.init(withTagClass: .mimeType, value: mimeType, conformingTo: conforming)
}
#if os(macOS)
@@ -146,7 +148,9 @@ public class UTI: RawRepresentable, Equatable {
/**
Initialize an UTI with a pasteboard type.
- Important: **This function is de-facto deprecated!** The old cocoa pasteboard types ( `NSStringPboardType`, `NSPDFPboardType`, etc) have been deprecated in favour of actual UTIs, and the constants are not available anymore in Swift. This function only works correctly with the values of these old constants, but _not_ with the replacement values (like `NSPasteboardTypeString` etc), since these already are UTIs.
- Important: **This function is de-facto deprecated!** The old cocoa pasteboard types ( `NSStringPboardType`, `NSPDFPboardType`, etc) have been deprecated in favour of actual UTIs, and the
constants are not available anymore in Swift. This function only works correctly with the values of these old constants, but _not_ with the replacement values (like `NSPasteboardTypeString` etc), since these
already are UTIs.
- Parameters:
- pbType: The pasteboard type (e.g. NSPDFPboardType).
- conformingTo: If specified, the returned UTI must conform to this UTI. If nil is specified, this parameter is ignored. The default is nil.
@@ -155,7 +159,7 @@ public class UTI: RawRepresentable, Equatable {
*/
public convenience init(withPBType pbType: String, conformingTo conforming: UTI? = nil) {
self.init(withTagClass:.pbType, value: pbType, conformingTo: conforming)
self.init(withTagClass: .pbType, value: pbType, conformingTo: conforming)
}
/**
@@ -172,7 +176,7 @@ public class UTI: RawRepresentable, Equatable {
public convenience init(withOSType osType: String, conformingTo conforming: UTI? = nil) {
self.init(withTagClass:.osType, value: osType, conformingTo: conforming)
self.init(withTagClass: .osType, value: osType, conformingTo: conforming)
}
#endif
@@ -297,7 +301,7 @@ public class UTI: RawRepresentable, Equatable {
return UTTypeConformsTo(self.rawCFValue, otherUTI.rawCFValue) as Bool
}
public static func ==(lhs: UTI, rhs: UTI) -> Bool {
public static func == (lhs: UTI, rhs: UTI) -> Bool {
return UTTypeEqual(lhs.rawCFValue, rhs.rawCFValue) as Bool
}
@@ -319,11 +323,11 @@ public class UTI: RawRepresentable, Equatable {
/// Returns a uniform types declaration as a Dictionary, or nil if if no declaration for that type can be found.
public var declaration: [AnyHashable:Any]? {
public var declaration: [AnyHashable: Any]? {
let unmanagedDeclaration = UTTypeCopyDeclaration(self.rawCFValue)
guard let declaration = unmanagedDeclaration?.takeRetainedValue() as? [AnyHashable:Any] else {
guard let declaration = unmanagedDeclaration?.takeRetainedValue() as? [AnyHashable: Any] else {
return nil
}
@@ -356,137 +360,137 @@ public class UTI: RawRepresentable, Equatable {
public extension UTI {
static let item = UTI(rawValue: kUTTypeItem as String)
static let content = UTI(rawValue: kUTTypeContent as String)
static let compositeContent = UTI(rawValue: kUTTypeCompositeContent as String)
static let message = UTI(rawValue: kUTTypeMessage as String)
static let contact = UTI(rawValue: kUTTypeContact as String)
static let archive = UTI(rawValue: kUTTypeArchive as String)
static let diskImage = UTI(rawValue: kUTTypeDiskImage as String)
static let data = UTI(rawValue: kUTTypeData as String)
static let directory = UTI(rawValue: kUTTypeDirectory as String)
static let resolvable = UTI(rawValue: kUTTypeResolvable as String)
static let symLink = UTI(rawValue: kUTTypeSymLink as String)
static let executable = UTI(rawValue: kUTTypeExecutable as String)
static let mountPoint = UTI(rawValue: kUTTypeMountPoint as String)
static let aliasFile = UTI(rawValue: kUTTypeAliasFile as String)
static let aliasRecord = UTI(rawValue: kUTTypeAliasRecord as String)
static let urlBookmarkData = UTI(rawValue: kUTTypeURLBookmarkData as String)
static let url = UTI(rawValue: kUTTypeURL as String)
static let fileURL = UTI(rawValue: kUTTypeFileURL as String)
static let text = UTI(rawValue: kUTTypeText as String)
static let plainText = UTI(rawValue: kUTTypePlainText as String)
static let utf8PlainText = UTI(rawValue: kUTTypeUTF8PlainText as String)
static let utf16ExternalPlainText = UTI(rawValue: kUTTypeUTF16ExternalPlainText as String)
static let utf16PlainText = UTI(rawValue: kUTTypeUTF16PlainText as String)
static let delimitedText = UTI(rawValue: kUTTypeDelimitedText as String)
static let commaSeparatedText = UTI(rawValue: kUTTypeCommaSeparatedText as String)
static let tabSeparatedText = UTI(rawValue: kUTTypeTabSeparatedText as String)
static let utf8TabSeparatedText = UTI(rawValue: kUTTypeUTF8TabSeparatedText as String)
static let rtf = UTI(rawValue: kUTTypeRTF as String)
static let html = UTI(rawValue: kUTTypeHTML as String)
static let xml = UTI(rawValue: kUTTypeXML as String)
static let sourceCode = UTI(rawValue: kUTTypeSourceCode as String)
static let assemblyLanguageSource = UTI(rawValue: kUTTypeAssemblyLanguageSource as String)
static let cSource = UTI(rawValue: kUTTypeCSource as String)
static let objectiveCSource = UTI(rawValue: kUTTypeObjectiveCSource as String)
static let item = UTI(rawValue: kUTTypeItem as String)
static let content = UTI(rawValue: kUTTypeContent as String)
static let compositeContent = UTI(rawValue: kUTTypeCompositeContent as String)
static let message = UTI(rawValue: kUTTypeMessage as String)
static let contact = UTI(rawValue: kUTTypeContact as String)
static let archive = UTI(rawValue: kUTTypeArchive as String)
static let diskImage = UTI(rawValue: kUTTypeDiskImage as String)
static let data = UTI(rawValue: kUTTypeData as String)
static let directory = UTI(rawValue: kUTTypeDirectory as String)
static let resolvable = UTI(rawValue: kUTTypeResolvable as String)
static let symLink = UTI(rawValue: kUTTypeSymLink as String)
static let executable = UTI(rawValue: kUTTypeExecutable as String)
static let mountPoint = UTI(rawValue: kUTTypeMountPoint as String)
static let aliasFile = UTI(rawValue: kUTTypeAliasFile as String)
static let aliasRecord = UTI(rawValue: kUTTypeAliasRecord as String)
static let urlBookmarkData = UTI(rawValue: kUTTypeURLBookmarkData as String)
static let url = UTI(rawValue: kUTTypeURL as String)
static let fileURL = UTI(rawValue: kUTTypeFileURL as String)
static let text = UTI(rawValue: kUTTypeText as String)
static let plainText = UTI(rawValue: kUTTypePlainText as String)
static let utf8PlainText = UTI(rawValue: kUTTypeUTF8PlainText as String)
static let utf16ExternalPlainText = UTI(rawValue: kUTTypeUTF16ExternalPlainText as String)
static let utf16PlainText = UTI(rawValue: kUTTypeUTF16PlainText as String)
static let delimitedText = UTI(rawValue: kUTTypeDelimitedText as String)
static let commaSeparatedText = UTI(rawValue: kUTTypeCommaSeparatedText as String)
static let tabSeparatedText = UTI(rawValue: kUTTypeTabSeparatedText as String)
static let utf8TabSeparatedText = UTI(rawValue: kUTTypeUTF8TabSeparatedText as String)
static let rtf = UTI(rawValue: kUTTypeRTF as String)
static let html = UTI(rawValue: kUTTypeHTML as String)
static let xml = UTI(rawValue: kUTTypeXML as String)
static let sourceCode = UTI(rawValue: kUTTypeSourceCode as String)
static let assemblyLanguageSource = UTI(rawValue: kUTTypeAssemblyLanguageSource as String)
static let cSource = UTI(rawValue: kUTTypeCSource as String)
static let objectiveCSource = UTI(rawValue: kUTTypeObjectiveCSource as String)
@available( OSX 10.11, iOS 9.0, * )
static let swiftSource = UTI(rawValue: kUTTypeSwiftSource as String)
static let cPlusPlusSource = UTI(rawValue: kUTTypeCPlusPlusSource as String)
static let objectiveCPlusPlusSource = UTI(rawValue: kUTTypeObjectiveCPlusPlusSource as String)
static let cHeader = UTI(rawValue: kUTTypeCHeader as String)
static let cPlusPlusHeader = UTI(rawValue: kUTTypeCPlusPlusHeader as String)
static let javaSource = UTI(rawValue: kUTTypeJavaSource as String)
static let script = UTI(rawValue: kUTTypeScript as String)
static let appleScript = UTI(rawValue: kUTTypeAppleScript as String)
static let osaScript = UTI(rawValue: kUTTypeOSAScript as String)
static let osaScriptBundle = UTI(rawValue: kUTTypeOSAScriptBundle as String)
static let javaScript = UTI(rawValue: kUTTypeJavaScript as String)
static let shellScript = UTI(rawValue: kUTTypeShellScript as String)
static let perlScript = UTI(rawValue: kUTTypePerlScript as String)
static let pythonScript = UTI(rawValue: kUTTypePythonScript as String)
static let rubyScript = UTI(rawValue: kUTTypeRubyScript as String)
static let phpScript = UTI(rawValue: kUTTypePHPScript as String)
static let json = UTI(rawValue: kUTTypeJSON as String)
static let propertyList = UTI(rawValue: kUTTypePropertyList as String)
static let xmlPropertyList = UTI(rawValue: kUTTypeXMLPropertyList as String)
static let binaryPropertyList = UTI(rawValue: kUTTypeBinaryPropertyList as String)
static let pdf = UTI(rawValue: kUTTypePDF as String)
static let rtfd = UTI(rawValue: kUTTypeRTFD as String)
static let flatRTFD = UTI(rawValue: kUTTypeFlatRTFD as String)
static let txnTextAndMultimediaData = UTI(rawValue: kUTTypeTXNTextAndMultimediaData as String)
static let webArchive = UTI(rawValue: kUTTypeWebArchive as String)
static let image = UTI(rawValue: kUTTypeImage as String)
static let jpeg = UTI(rawValue: kUTTypeJPEG as String)
static let jpeg2000 = UTI(rawValue: kUTTypeJPEG2000 as String)
static let tiff = UTI(rawValue: kUTTypeTIFF as String)
static let pict = UTI(rawValue: kUTTypePICT as String)
static let gif = UTI(rawValue: kUTTypeGIF as String)
static let png = UTI(rawValue: kUTTypePNG as String)
static let quickTimeImage = UTI(rawValue: kUTTypeQuickTimeImage as String)
static let appleICNS = UTI(rawValue: kUTTypeAppleICNS as String)
static let bmp = UTI(rawValue: kUTTypeBMP as String)
static let ico = UTI(rawValue: kUTTypeICO as String)
static let rawImage = UTI(rawValue: kUTTypeRawImage as String)
static let scalableVectorGraphics = UTI(rawValue: kUTTypeScalableVectorGraphics as String)
static let swiftSource = UTI(rawValue: kUTTypeSwiftSource as String)
static let cPlusPlusSource = UTI(rawValue: kUTTypeCPlusPlusSource as String)
static let objectiveCPlusPlusSource = UTI(rawValue: kUTTypeObjectiveCPlusPlusSource as String)
static let cHeader = UTI(rawValue: kUTTypeCHeader as String)
static let cPlusPlusHeader = UTI(rawValue: kUTTypeCPlusPlusHeader as String)
static let javaSource = UTI(rawValue: kUTTypeJavaSource as String)
static let script = UTI(rawValue: kUTTypeScript as String)
static let appleScript = UTI(rawValue: kUTTypeAppleScript as String)
static let osaScript = UTI(rawValue: kUTTypeOSAScript as String)
static let osaScriptBundle = UTI(rawValue: kUTTypeOSAScriptBundle as String)
static let javaScript = UTI(rawValue: kUTTypeJavaScript as String)
static let shellScript = UTI(rawValue: kUTTypeShellScript as String)
static let perlScript = UTI(rawValue: kUTTypePerlScript as String)
static let pythonScript = UTI(rawValue: kUTTypePythonScript as String)
static let rubyScript = UTI(rawValue: kUTTypeRubyScript as String)
static let phpScript = UTI(rawValue: kUTTypePHPScript as String)
static let json = UTI(rawValue: kUTTypeJSON as String)
static let propertyList = UTI(rawValue: kUTTypePropertyList as String)
static let xmlPropertyList = UTI(rawValue: kUTTypeXMLPropertyList as String)
static let binaryPropertyList = UTI(rawValue: kUTTypeBinaryPropertyList as String)
static let pdf = UTI(rawValue: kUTTypePDF as String)
static let rtfd = UTI(rawValue: kUTTypeRTFD as String)
static let flatRTFD = UTI(rawValue: kUTTypeFlatRTFD as String)
static let txnTextAndMultimediaData = UTI(rawValue: kUTTypeTXNTextAndMultimediaData as String)
static let webArchive = UTI(rawValue: kUTTypeWebArchive as String)
static let image = UTI(rawValue: kUTTypeImage as String)
static let jpeg = UTI(rawValue: kUTTypeJPEG as String)
static let jpeg2000 = UTI(rawValue: kUTTypeJPEG2000 as String)
static let tiff = UTI(rawValue: kUTTypeTIFF as String)
static let pict = UTI(rawValue: kUTTypePICT as String)
static let gif = UTI(rawValue: kUTTypeGIF as String)
static let png = UTI(rawValue: kUTTypePNG as String)
static let quickTimeImage = UTI(rawValue: kUTTypeQuickTimeImage as String)
static let appleICNS = UTI(rawValue: kUTTypeAppleICNS as String)
static let bmp = UTI(rawValue: kUTTypeBMP as String)
static let ico = UTI(rawValue: kUTTypeICO as String)
static let rawImage = UTI(rawValue: kUTTypeRawImage as String)
static let scalableVectorGraphics = UTI(rawValue: kUTTypeScalableVectorGraphics as String)
@available(OSX 10.12, iOS 9.1, watchOS 2.1, *)
static let livePhoto = UTI(rawValue: kUTTypeLivePhoto as String)
static let livePhoto = UTI(rawValue: kUTTypeLivePhoto as String)
@available(OSX 10.12, iOS 9.1, *)
static let audiovisualContent = UTI(rawValue: kUTTypeAudiovisualContent as String)
static let movie = UTI(rawValue: kUTTypeMovie as String)
static let video = UTI(rawValue: kUTTypeVideo as String)
static let audio = UTI(rawValue: kUTTypeAudio as String)
static let quickTimeMovie = UTI(rawValue: kUTTypeQuickTimeMovie as String)
static let mpeg = UTI(rawValue: kUTTypeMPEG as String)
static let mpeg2Video = UTI(rawValue: kUTTypeMPEG2Video as String)
static let mpeg2TransportStream = UTI(rawValue: kUTTypeMPEG2TransportStream as String)
static let mp3 = UTI(rawValue: kUTTypeMP3 as String)
static let mpeg4 = UTI(rawValue: kUTTypeMPEG4 as String)
static let mpeg4Audio = UTI(rawValue: kUTTypeMPEG4Audio as String)
static let appleProtectedMPEG4Audio = UTI(rawValue: kUTTypeAppleProtectedMPEG4Audio as String)
static let appleProtectedMPEG4Video = UTI(rawValue: kUTTypeAppleProtectedMPEG4Video as String)
static let aviMovie = UTI(rawValue: kUTTypeAVIMovie as String)
static let audioInterchangeFileFormat = UTI(rawValue: kUTTypeAudioInterchangeFileFormat as String)
static let waveformAudio = UTI(rawValue: kUTTypeWaveformAudio as String)
static let midiAudio = UTI(rawValue: kUTTypeMIDIAudio as String)
static let playlist = UTI(rawValue: kUTTypePlaylist as String)
static let m3UPlaylist = UTI(rawValue: kUTTypeM3UPlaylist as String)
static let folder = UTI(rawValue: kUTTypeFolder as String)
static let volume = UTI(rawValue: kUTTypeVolume as String)
static let package = UTI(rawValue: kUTTypePackage as String)
static let bundle = UTI(rawValue: kUTTypeBundle as String)
static let pluginBundle = UTI(rawValue: kUTTypePluginBundle as String)
static let spotlightImporter = UTI(rawValue: kUTTypeSpotlightImporter as String)
static let quickLookGenerator = UTI(rawValue: kUTTypeQuickLookGenerator as String)
static let xpcService = UTI(rawValue: kUTTypeXPCService as String)
static let framework = UTI(rawValue: kUTTypeFramework as String)
static let application = UTI(rawValue: kUTTypeApplication as String)
static let applicationBundle = UTI(rawValue: kUTTypeApplicationBundle as String)
static let applicationFile = UTI(rawValue: kUTTypeApplicationFile as String)
static let unixExecutable = UTI(rawValue: kUTTypeUnixExecutable as String)
static let windowsExecutable = UTI(rawValue: kUTTypeWindowsExecutable as String)
static let javaClass = UTI(rawValue: kUTTypeJavaClass as String)
static let javaArchive = UTI(rawValue: kUTTypeJavaArchive as String)
static let systemPreferencesPane = UTI(rawValue: kUTTypeSystemPreferencesPane as String)
static let gnuZipArchive = UTI(rawValue: kUTTypeGNUZipArchive as String)
static let bzip2Archive = UTI(rawValue: kUTTypeBzip2Archive as String)
static let zipArchive = UTI(rawValue: kUTTypeZipArchive as String)
static let spreadsheet = UTI(rawValue: kUTTypeSpreadsheet as String)
static let presentation = UTI(rawValue: kUTTypePresentation as String)
static let database = UTI(rawValue: kUTTypeDatabase as String)
static let vCard = UTI(rawValue: kUTTypeVCard as String)
static let toDoItem = UTI(rawValue: kUTTypeToDoItem as String)
static let calendarEvent = UTI(rawValue: kUTTypeCalendarEvent as String)
static let emailMessage = UTI(rawValue: kUTTypeEmailMessage as String)
static let internetLocation = UTI(rawValue: kUTTypeInternetLocation as String)
static let inkText = UTI(rawValue: kUTTypeInkText as String)
static let font = UTI(rawValue: kUTTypeFont as String)
static let bookmark = UTI(rawValue: kUTTypeBookmark as String)
static let _3DContent = UTI(rawValue: kUTType3DContent as String)
static let pkcs12 = UTI(rawValue: kUTTypePKCS12 as String)
static let x509Certificate = UTI(rawValue: kUTTypeX509Certificate as String)
static let electronicPublication = UTI(rawValue: kUTTypeElectronicPublication as String)
static let log = UTI(rawValue: kUTTypeLog as String)
static let audiovisualContent = UTI(rawValue: kUTTypeAudiovisualContent as String)
static let movie = UTI(rawValue: kUTTypeMovie as String)
static let video = UTI(rawValue: kUTTypeVideo as String)
static let audio = UTI(rawValue: kUTTypeAudio as String)
static let quickTimeMovie = UTI(rawValue: kUTTypeQuickTimeMovie as String)
static let mpeg = UTI(rawValue: kUTTypeMPEG as String)
static let mpeg2Video = UTI(rawValue: kUTTypeMPEG2Video as String)
static let mpeg2TransportStream = UTI(rawValue: kUTTypeMPEG2TransportStream as String)
static let mp3 = UTI(rawValue: kUTTypeMP3 as String)
static let mpeg4 = UTI(rawValue: kUTTypeMPEG4 as String)
static let mpeg4Audio = UTI(rawValue: kUTTypeMPEG4Audio as String)
static let appleProtectedMPEG4Audio = UTI(rawValue: kUTTypeAppleProtectedMPEG4Audio as String)
static let appleProtectedMPEG4Video = UTI(rawValue: kUTTypeAppleProtectedMPEG4Video as String)
static let aviMovie = UTI(rawValue: kUTTypeAVIMovie as String)
static let audioInterchangeFileFormat = UTI(rawValue: kUTTypeAudioInterchangeFileFormat as String)
static let waveformAudio = UTI(rawValue: kUTTypeWaveformAudio as String)
static let midiAudio = UTI(rawValue: kUTTypeMIDIAudio as String)
static let playlist = UTI(rawValue: kUTTypePlaylist as String)
static let m3UPlaylist = UTI(rawValue: kUTTypeM3UPlaylist as String)
static let folder = UTI(rawValue: kUTTypeFolder as String)
static let volume = UTI(rawValue: kUTTypeVolume as String)
static let package = UTI(rawValue: kUTTypePackage as String)
static let bundle = UTI(rawValue: kUTTypeBundle as String)
static let pluginBundle = UTI(rawValue: kUTTypePluginBundle as String)
static let spotlightImporter = UTI(rawValue: kUTTypeSpotlightImporter as String)
static let quickLookGenerator = UTI(rawValue: kUTTypeQuickLookGenerator as String)
static let xpcService = UTI(rawValue: kUTTypeXPCService as String)
static let framework = UTI(rawValue: kUTTypeFramework as String)
static let application = UTI(rawValue: kUTTypeApplication as String)
static let applicationBundle = UTI(rawValue: kUTTypeApplicationBundle as String)
static let applicationFile = UTI(rawValue: kUTTypeApplicationFile as String)
static let unixExecutable = UTI(rawValue: kUTTypeUnixExecutable as String)
static let windowsExecutable = UTI(rawValue: kUTTypeWindowsExecutable as String)
static let javaClass = UTI(rawValue: kUTTypeJavaClass as String)
static let javaArchive = UTI(rawValue: kUTTypeJavaArchive as String)
static let systemPreferencesPane = UTI(rawValue: kUTTypeSystemPreferencesPane as String)
static let gnuZipArchive = UTI(rawValue: kUTTypeGNUZipArchive as String)
static let bzip2Archive = UTI(rawValue: kUTTypeBzip2Archive as String)
static let zipArchive = UTI(rawValue: kUTTypeZipArchive as String)
static let spreadsheet = UTI(rawValue: kUTTypeSpreadsheet as String)
static let presentation = UTI(rawValue: kUTTypePresentation as String)
static let database = UTI(rawValue: kUTTypeDatabase as String)
static let vCard = UTI(rawValue: kUTTypeVCard as String)
static let toDoItem = UTI(rawValue: kUTTypeToDoItem as String)
static let calendarEvent = UTI(rawValue: kUTTypeCalendarEvent as String)
static let emailMessage = UTI(rawValue: kUTTypeEmailMessage as String)
static let internetLocation = UTI(rawValue: kUTTypeInternetLocation as String)
static let inkText = UTI(rawValue: kUTTypeInkText as String)
static let font = UTI(rawValue: kUTTypeFont as String)
static let bookmark = UTI(rawValue: kUTTypeBookmark as String)
static let _3DContent = UTI(rawValue: kUTType3DContent as String)
static let pkcs12 = UTI(rawValue: kUTTypePKCS12 as String)
static let x509Certificate = UTI(rawValue: kUTTypeX509Certificate as String)
static let electronicPublication = UTI(rawValue: kUTTypeElectronicPublication as String)
static let log = UTI(rawValue: kUTTypeLog as String)
}
#if os(OSX)
-1
View File
@@ -69,7 +69,6 @@
#import "MXKRoomCreationView.h"
#import "MXKRoomInputToolbarView.h"
#import "MXKRoomInputToolbarViewWithHPGrowingText.h"
#import "MXKRoomDataSourceManager.h"
@@ -75,10 +75,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
// Internal list of ignored rooms
NSMutableArray* ignoredRooms;
// If a server sync is in progress, the pause is delayed at the end of sync (except if resume is called).
BOOL isPauseRequested;
// Background sync management
MXOnBackgroundSyncDone backgroundSyncDone;
MXOnBackgroundSyncFail backgroundSyncFails;
@@ -91,7 +88,9 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
id NSCurrentLocaleDidChangeNotificationObserver;
}
@property (nonatomic, strong) id<MXBackgroundTask> backgroundTask;
/// Will be true if the session is not in a pauseable state or we requested for the session to pause but not finished yet. Will be reverted to false again after `resume` called.
@property (nonatomic, assign, getter=isPauseRequested) BOOL pauseRequested;
@property (nonatomic, strong) id<MXBackgroundTask> pauseBackgroundTask;
@property (nonatomic, strong) id<MXBackgroundTask> backgroundSyncBgTask;
@end
@@ -515,6 +514,32 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
return _others;
}
- (void)setPauseRequested:(BOOL)pauseRequested
{
if (_pauseRequested != pauseRequested)
{
_pauseRequested = pauseRequested;
if (_pauseRequested)
{
// Make sure the SDK finish its work before the app goes sleeping in background
id<MXBackgroundModeHandler> handler = [MXSDKOptions sharedInstance].backgroundModeHandler;
if (handler)
{
if (!self.pauseBackgroundTask.isRunning)
{
self.pauseBackgroundTask = [handler startBackgroundTaskWithName:@"[MXKAccount] pauseInBackgroundTask"
expirationHandler:nil];
}
}
}
else
{
[self cancelPauseBackgroundTask];
}
}
}
#pragma mark - Matrix user's profile
- (void)setUserDisplayName:(NSString*)displayname success:(void (^)(void))success failure:(void (^)(NSError *error))failure
@@ -966,38 +991,25 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
- (void)pauseInBackgroundTask
{
// Reset internal flag
isPauseRequested = NO;
if (mxSession && mxSession.isPauseable)
if (mxSession == nil)
{
// no session to pause
return;
}
// mark that we want to pause when possible
self.pauseRequested = YES;
if (mxSession.isPauseable)
{
id<MXBackgroundModeHandler> handler = [MXSDKOptions sharedInstance].backgroundModeHandler;
if (handler)
{
if (!self.backgroundTask.isRunning)
{
self.backgroundTask = [handler startBackgroundTaskWithName:@"[MXKAccount] pauseInBackgroundTask" expirationHandler:nil];
}
}
// Pause SDK
[mxSession pause];
// Update user presence
__weak typeof(self) weakSelf = self;
MXWeakify(self);
[self setUserPresence:MXPresenceUnavailable andStatusMessage:nil completion:^{
if (weakSelf)
{
typeof(self) self = weakSelf;
if (self.backgroundTask.isRunning)
{
[self.backgroundTask stop];
self.backgroundTask = nil;
}
}
MXStrongifyAndReturnIfNil(self);
[self cancelPauseBackgroundTask];
}];
}
else
@@ -1007,65 +1019,61 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
reachabilityObserver = nil;
[initialServerSyncTimer invalidate];
initialServerSyncTimer = nil;
if (mxSession.state == MXSessionStateSyncInProgress || mxSession.state == MXSessionStateInitialised || mxSession.state == MXSessionStateStoreDataReady)
{
// Make sure the SDK finish its work before the app goes sleeping in background
id<MXBackgroundModeHandler> handler = [MXSDKOptions sharedInstance].backgroundModeHandler;
if (handler)
{
if (!self.backgroundTask.isRunning)
{
self.backgroundTask = [handler startBackgroundTaskWithName:@"[MXKAccount] pauseInBackgroundTask" expirationHandler:nil];
}
}
MXLogDebug(@"[MXKAccount] Pause is delayed at the end of sync (current state %tu)", mxSession.state);
isPauseRequested = YES;
}
MXLogDebug(@"[MXKAccount] Pause is delayed due to the session state: %@", [MXTools readableSessionState: mxSession.state]);
}
}
- (void)resume
{
isPauseRequested = NO;
if (mxSession)
if (mxSession == nil)
{
MXLogVerbose(@"[MXKAccount] resume with session state: %tu", mxSession.state);
[self cancelBackgroundSync];
if (mxSession.state == MXSessionStatePaused || mxSession.state == MXSessionStatePauseRequested)
// no session to resume
return;
}
// mark that we don't want to pause anymore
self.pauseRequested = NO;
MXLogVerbose(@"[MXKAccount] resume: with session state: %@", [MXTools readableSessionState:mxSession.state]);
[self cancelBackgroundSync];
switch (mxSession.state)
{
case MXSessionStatePaused:
case MXSessionStatePauseRequested:
{
// Resume SDK and update user presence
[mxSession resume:^{
[self setUserPresence:MXPresenceOnline andStatusMessage:nil completion:nil];
[self refreshAPNSPusher];
[self refreshPushKitPusher];
}];
break;
}
else if (mxSession.state == MXSessionStateStoreDataReady || mxSession.state == MXSessionStateInitialSyncFailed)
case MXSessionStateStoreDataReady:
case MXSessionStateInitialSyncFailed:
{
// The session initialisation was uncompleted, we try to complete it here.
[self launchInitialServerSync];
[self refreshAPNSPusher];
[self refreshPushKitPusher];
break;
}
else if (mxSession.state == MXSessionStateSyncInProgress)
case MXSessionStateSyncInProgress:
{
[self refreshAPNSPusher];
[self refreshPushKitPusher];
break;
}
// Cancel background task
if (self.backgroundTask.isRunning)
{
[self.backgroundTask stop];
self.backgroundTask = nil;
}
default:
break;
}
}
@@ -1616,16 +1624,16 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
- (void)onMatrixSessionStateChange
{
// Check if pause has been requested
if (self.isPauseRequested && mxSession.isPauseable)
{
MXLogDebug(@"[MXKAccount] Apply the pending pause.");
[self pauseInBackgroundTask];
return;
}
if (mxSession.state == MXSessionStateRunning)
{
// Check if pause has been requested
if (isPauseRequested)
{
MXLogDebug(@"[MXKAccount] Apply the pending pause.");
[self pauseInBackgroundTask];
return;
}
// Check whether the session was not already running
if (!userUpdateListener)
{
@@ -1662,7 +1670,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
}
else if (mxSession.state == MXSessionStatePaused)
{
isPauseRequested = NO;
self.pauseRequested = NO;
}
}
@@ -1754,6 +1762,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
dispatch_group_leave(dispatchGroup);
} failure:^(NSError *error) {
MXLogError(@"[MXKAccount] onDateTimeFormatUpdate: event fetch failed: %@", error);
dispatch_group_leave(dispatchGroup);
}];
}
@@ -1774,6 +1783,16 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
}
}
- (void)cancelPauseBackgroundTask
{
// Cancel background task
if (self.pauseBackgroundTask.isRunning)
{
[self.pauseBackgroundTask stop];
self.pauseBackgroundTask = nil;
}
}
#pragma mark - Crypto
- (void)resetDeviceId
{
@@ -1890,7 +1909,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
}
else
{
MXLogDebug(@"[MXKAccount] cannot start background Sync (invalid state %tu)", mxSession.state);
MXLogDebug(@"[MXKAccount] cannot start background Sync (invalid state %@)", [MXTools readableSessionState:mxSession.state]);
failure([NSError errorWithDomain:kMXKAccountErrorDomain code:0 userInfo:nil]);
}
}
@@ -104,6 +104,8 @@ NSString *const MXKAccountManagerDataType = @"org.matrix.kit.MXKAccountManagerDa
}
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
- (void)saveAccounts
{
NSDate *startDate = [NSDate date];
@@ -123,6 +125,7 @@ NSString *const MXKAccountManagerDataType = @"org.matrix.kit.MXKAccountManagerDa
MXLogDebug(@"[MXKAccountManager] saveAccounts. Done (result: %@) in %.0fms", @(result), [[NSDate date] timeIntervalSinceDate:startDate] * 1000);
}
#pragma clang diagnostic pop
- (void)addAccount:(MXKAccount *)account andOpenSession:(BOOL)openSession
{
@@ -608,6 +611,8 @@ NSString *const MXKAccountManagerDataType = @"org.matrix.kit.MXKAccountManagerDa
return [matrixKitCacheFolder stringByAppendingPathComponent:kMXKAccountsKey];
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
- (void)loadAccounts
{
MXLogDebug(@"[MXKAccountManager] loadAccounts");
@@ -675,6 +680,7 @@ NSString *const MXKAccountManagerDataType = @"org.matrix.kit.MXKAccountManagerDa
mxAccounts = [NSMutableArray array];
}
}
#pragma clang diagnostic pop
- (NSData*)encryptData:(NSData*)data
{
@@ -708,6 +714,8 @@ NSString *const MXKAccountManagerDataType = @"org.matrix.kit.MXKAccountManagerDa
return data;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
- (void)migrateAccounts
{
NSString *pathOld = [[MXKAppSettings cacheFolder] stringByAppendingPathComponent:kMXKAccountsKeyOld];
@@ -727,6 +735,7 @@ NSString *const MXKAccountManagerDataType = @"org.matrix.kit.MXKAccountManagerDa
[fileManager removeItemAtPath:pathOld error:nil];
}
}
#pragma clang diagnostic pop
- (void)readAndWriteCredentials:(void (^)(NSArray<MXCredentials*> * _Nullable readData, void (^completion)(BOOL didUpdateCredentials)))readAnWriteHandler
{
@@ -93,6 +93,8 @@ extern NSString *const kMXKContactDefaultContactPrefixId;
*/
- (void)resetMatrixThumbnail;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
/**
The contact ID from native phonebook record
*/
@@ -105,6 +107,7 @@ extern NSString *const kMXKContactDefaultContactPrefixId;
@return MXKContact instance
*/
- (id)initLocalContactWithABRecord:(ABRecordRef)record;
#pragma clang diagnostic pop
/**
Create a matrix contact with the dedicated info
@@ -40,6 +40,8 @@ NSString *const kMXKContactDefaultContactPrefixId = @"Default_";
@implementation MXKContact
@synthesize isMatrixContact, isThirdPartyInvite;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ (NSString*)contactID:(ABRecordRef)record
{
return [NSString stringWithFormat:@"%@%d", kMXKContactLocalContactPrefixId, ABRecordGetRecordID(record)];
@@ -217,6 +219,7 @@ NSString *const kMXKContactDefaultContactPrefixId = @"Default_";
}
return self;
}
#pragma clang diagnostic pop
- (id)initMatrixContactWithDisplayName:(NSString*)displayName andMatrixID:(NSString*)matrixID
{
@@ -537,6 +537,8 @@ NSString *const MXKContactManagerDataType = @"org.matrix.kit.MXKContactManagerDa
}
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- (void)refreshLocalContacts
{
MXLogDebug(@"[MXKContactManager] refreshLocalContacts : Started");
@@ -721,6 +723,7 @@ NSString *const MXKContactManagerDataType = @"org.matrix.kit.MXKContactManagerDa
});
}
}
#pragma clang diagnostic pop
- (void)updateMatrixIDsForLocalContact:(MXKContact *)contact
{
@@ -1582,6 +1585,9 @@ static NSString *matrixIDsDictFile = @"matrixIDsDictV2";
static NSString *localContactsFile = @"localContactsV2";
static NSString *contactsBookInfoFile = @"contactsV2";
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- (NSString*)dataFilePathForComponent:(NSString*)component
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
@@ -1857,6 +1863,8 @@ static NSString *contactsBookInfoFile = @"contactsV2";
}
}
#pragma clang diagnostic pop
- (BOOL)encryptAndSaveData:(NSData*)data toFile:(NSString*)fileName
{
NSError *error = nil;
@@ -1865,6 +1873,10 @@ static NSString *contactsBookInfoFile = @"contactsV2";
if (error == nil)
{
[cipher writeToFile:[self dataFilePathForComponent:fileName] atomically:YES];
[[NSFileManager defaultManager] excludeItemFromBackupAt:[NSURL fileURLWithPath:fileName] error:&error];
if (error) {
MXLogDebug(@"[MXKContactManager] Cannot exclude item from backup %@", error.localizedDescription);
}
}
else
{
+21 -8
View File
@@ -29,6 +29,10 @@
@property (nonatomic) NSString *sid;
@property (nonatomic) MXIdentityService *identityService;
@property (nonatomic) NSString *submitUrl;
/**
HTTP client dedicated to sending MSISDN token to custom URLs.
*/
@property (nonatomic, strong) MXHTTPClient *msisdnSubmissionHttpClient;
@end
@@ -255,14 +259,23 @@
@"token": token
};
MXHTTPClient *httpClient = [[MXHTTPClient alloc] initWithBaseURL:nil andOnUnrecognizedCertificateBlock:nil];
return [httpClient requestWithMethod:@"POST"
path:url
parameters:parameters
success:^(NSDictionary *JSONResponse) {
success();
}
failure:failure];
self.msisdnSubmissionHttpClient = [[MXHTTPClient alloc] initWithBaseURL:nil andOnUnrecognizedCertificateBlock:nil];
MXWeakify(self);
return [self.msisdnSubmissionHttpClient requestWithMethod:@"POST"
path:url
parameters:parameters
success:^(NSDictionary *JSONResponse) {
success();
MXStrongifyAndReturnIfNil(self);
self.msisdnSubmissionHttpClient = nil;
}
failure:^(NSError *error) {
failure(error);
MXStrongifyAndReturnIfNil(self);
self.msisdnSubmissionHttpClient = nil;
}];
}
- (void)add3PIDToUser:(BOOL)bind
@@ -19,6 +19,7 @@
#import "MXKAppSettings.h"
#import "MXKTools.h"
@import MatrixSDK;
// get ISO country name
@@ -66,11 +67,10 @@ static NSString *const kMXAppGroupID = @"group.org.matrix";
{
NSString *cacheFolder;
// Check for a potential application group id
NSString *applicationGroupIdentifier = [MXSDKOptions sharedInstance].applicationGroupIdentifier;
if (applicationGroupIdentifier)
// Check for a potential application group container
NSURL *sharedContainerURL = [[NSFileManager defaultManager] applicationGroupContainerURL];
if (sharedContainerURL)
{
NSURL *sharedContainerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:applicationGroupIdentifier];
cacheFolder = [sharedContainerURL path];
}
else
@@ -86,7 +86,7 @@ static NSString *const kMXAppGroupID = @"group.org.matrix";
if (cacheFolder && ![[NSFileManager defaultManager] fileExistsAtPath:cacheFolder])
{
NSError *error;
[[NSFileManager defaultManager] createDirectoryAtPath:cacheFolder withIntermediateDirectories:YES attributes:nil error:&error];
[[NSFileManager defaultManager] createDirectoryExcludedFromBackupAtPath:cacheFolder error:&error];
if (error)
{
MXLogDebug(@"[MXKAppSettings] cacheFolder: Error: Cannot create MatrixKit folder at %@. Error: %@", cacheFolder, error);
@@ -670,6 +670,8 @@ static NSString *const kMXAppGroupID = @"group.org.matrix";
}
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
- (NSString*)phonebookCountryCode
{
NSString* res = phonebookCountryCode;
@@ -699,6 +701,7 @@ static NSString *const kMXAppGroupID = @"group.org.matrix";
return res;
}
#pragma clang diagnostic pop
- (void)setPhonebookCountryCode:(NSString *)stringValue
{
@@ -46,6 +46,11 @@
*/
NSAttributedString *attributedTextMessage;
/**
Same as attributedTextMessage but without vertical positioning vertical blank space.
*/
NSAttributedString *attributedTextMessageWithoutPositioningSpace;
/**
The optional text pattern to be highlighted in the body of the message.
*/
@@ -28,7 +28,7 @@
@implementation MXKRoomBubbleCellData
@synthesize senderId, targetId, roomId, senderDisplayName, senderAvatarUrl, senderAvatarPlaceholder, targetDisplayName, targetAvatarUrl, targetAvatarPlaceholder, isEncryptedRoom, isPaginationFirstBubble, shouldHideSenderInformation, date, isIncoming, isAttachmentWithThumbnail, isAttachmentWithIcon, attachment, senderFlair;
@synthesize textMessage, attributedTextMessage;
@synthesize textMessage, attributedTextMessage, attributedTextMessageWithoutPositioningSpace;
@synthesize shouldHideSenderName, isTyping, showBubbleDateTime, showBubbleReceipts, useCustomDateTimeLabel, useCustomReceipts, useCustomUnsentButton, hasNoDisplay;
@synthesize tag;
@synthesize collapsable, collapsed, collapsedAttributedTextMessage, prevCollapsableCellData, nextCollapsableCellData, collapseState;
@@ -163,6 +163,10 @@
*/
@property (nonatomic) NSAttributedString *attributedTextMessage;
/**
Same as attributedTextMessage but without vertical positioning blank space
*/
@property (nonatomic) NSAttributedString *attributedTextMessageWithoutPositioningSpace;
/**
The raw text message (without attributes)
*/
@@ -56,7 +56,7 @@
#pragma mark - Override MXKRecentsDataSource
- (UIView *)viewForHeaderInSection:(NSInteger)section withFrame:(CGRect)frame
- (UIView *)viewForHeaderInSection:(NSInteger)section withFrame:(CGRect)frame inTableView:(UITableView*)tableView
{
UIView *sectionHeader = nil;
@@ -88,9 +88,10 @@
@param section the section index
@param frame the drawing area for the header of the specified section.
@param tableView the table view
@return the section header.
*/
- (UIView *)viewForHeaderInSection:(NSInteger)section withFrame:(CGRect)frame;
- (UIView *)viewForHeaderInSection:(NSInteger)section withFrame:(CGRect)frame inTableView:(UITableView*)tableView;
/**
Get the data for the cell at the given index path.
@@ -257,7 +257,7 @@
}
}
- (UIView *)viewForHeaderInSection:(NSInteger)section withFrame:(CGRect)frame
- (UIView *)viewForHeaderInSection:(NSInteger)section withFrame:(CGRect)frame inTableView:(UITableView*)tableView
{
UIView *sectionHeader = nil;
@@ -30,8 +30,8 @@ extern NSString *const kMXKRecentCellIdentifier;
/**
The recents data source based on a unique matrix session.
Deprecated: Please see MXSession.roomListDataManager
*/
MXK_DEPRECATED_ATTRIBUTE_WITH_MSG("See MXSession.roomListDataManager")
@interface MXKSessionRecentsDataSource : MXKDataSource {
@protected
@@ -17,9 +17,6 @@
#import <UIKit/UIKit.h>
#define MXK_DEPRECATED_ATTRIBUTE __attribute__((deprecated))
#define MXK_DEPRECATED_ATTRIBUTE_WITH_MSG(msg) __attribute((deprecated((msg))))
/**
The Matrix iOS Kit version.
*/
@@ -24,7 +24,8 @@ import MobileCoreServices
/// MXKDocumentPickerPresenter presents a controller that provides access to documents or destinations outside the apps sandbox.
/// Internally presents a UIDocumentPickerViewController in UIDocumentPickerMode.import.
/// Note: You must turn on the iCloud Documents capabilities in Xcode (see https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/DocumentPickerProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40014451)
/// Note: You must turn on the iCloud Documents capabilities in Xcode
/// (see https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/DocumentPickerProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40014451)
@objcMembers
public class MXKDocumentPickerPresenter: NSObject {
+1 -1
View File
@@ -1112,7 +1112,7 @@ manualChangeMessageForVideo:(NSString*)manualChangeMessageForVideo
// Caution: We need here to escape the non-ASCII characters (like '#' in room alias)
// to convert the link into a legal URL string.
NSString *link = [attributedString.string substringWithRange:match.range];
link = [link stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
link = [link stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
[*mutableAttributedString addAttribute:NSLinkAttributeName value:link range:match.range];
}
}];
+9 -1
View File
@@ -20,7 +20,7 @@ import MobileCoreServices
// We do not use the SwiftUTI pod anymore
// The library is embedded in MatrixKit. See Libs/SwiftUTI/README.md for more details
//import SwiftUTI
// import SwiftUTI
/// MXKUTI represents a Universal Type Identifier (e.g. kUTTypePNG).
/// See https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/understanding_utis/understand_utis_conc/understand_utis_conc.html#//apple_ref/doc/uid/TP40001319-CH202-SW5 for more information.
@@ -134,6 +134,8 @@ extension MXKUTI {
self.init(rawValue: uti as String)
}
// swiftlint:disable unused_optional_binding
/// Initialize with local file URL.
/// This method is currently applicable only to URLs for file system resources.
///
@@ -153,6 +155,8 @@ extension MXKUTI {
}
}
// swiftlint:enable unused_optional_binding
public convenience init?(localFileURL: URL) {
self.init(localFileURL: localFileURL, loadResourceValues: true)
}
@@ -173,6 +177,8 @@ extension MXKUTI {
}
}
// swiftlint:disable force_unwrapping
// MARK: - Some system defined UTIs
extension MXKUTI {
public static let data = MXKUTI(cfRawValue: kUTTypeData)!
@@ -190,6 +196,8 @@ extension MXKUTI {
public static let xml = MXKUTI(cfRawValue: kUTTypeXML)!
}
// swiftlint:enable force_unwrapping
// MARK: - Convenience static methods
extension MXKUTI {
@@ -120,7 +120,7 @@ sendObjectMessage({ \
MXLogDebug(@"[MXKAuthenticationFallbackWebView] URL has js: prefix");
// Listen only to scheme of the JS-WKWebView bridge
NSString *jsonString = [[[urlString componentsSeparatedByString:@"js:"] lastObject] stringByReplacingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSString *jsonString = [[[urlString componentsSeparatedByString:@"js:"] lastObject] stringByRemovingPercentEncoding];
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
@@ -102,7 +102,7 @@ var onloadCallback = function() { \
if ([urlString hasPrefix:@"js:"])
{
// Listen only to scheme of the JS-WKWebView bridge
NSString *jsonString = [[[urlString componentsSeparatedByString:@"js:"] lastObject] stringByReplacingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSString *jsonString = [[[urlString componentsSeparatedByString:@"js:"] lastObject] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
@@ -417,7 +417,7 @@ static NSAttributedString *verticalWhitespace = nil;
[_mxSession.crypto setDeviceVerification:MXDeviceVerified forDevice:_mxDeviceInfo.deviceId ofUser:_mxDeviceInfo.userId success:^{
// Refresh data
_mxDeviceInfo = [self.mxSession.crypto eventDeviceInfo:self.mxEvent];
self->_mxDeviceInfo = [self.mxSession.crypto eventDeviceInfo:self.mxEvent];
if (self->_delegate)
{
[self->_delegate encryptionInfoView:self didDeviceInfoVerifiedChange:self.mxDeviceInfo];
@@ -473,7 +473,7 @@ static NSAttributedString *verticalWhitespace = nil;
[_mxSession.crypto setDeviceVerification:verificationStatus forDevice:_mxDeviceInfo.deviceId ofUser:_mxDeviceInfo.userId success:^{
// Refresh data
_mxDeviceInfo = [self.mxSession.crypto eventDeviceInfo:self.mxEvent];
self->_mxDeviceInfo = [self.mxSession.crypto eventDeviceInfo:self.mxEvent];
if (self->_delegate)
{
@@ -75,11 +75,9 @@
- (MXKCellData*)renderedCellData;
/**
Reset the cell.
Stop processes no more needed when cell is not visible.
The cell is no more displayed. This is time to release resources and removing listeners.
In case of UITableViewCell or UIContentViewCell object, the cell must reset in a state
that it can be reusable.
The cell is no more displayed but still recycled. This is time to stop animation.
*/
- (void)didEndDisplay;
@@ -1,33 +0,0 @@
/*
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 "MXKRoomInputToolbarView.h"
#import <HPGrowingTextView/HPGrowingTextView.h>
/**
`MXKRoomInputToolbarViewWithHPGrowingText` is a MXKRoomInputToolbarView-inherited class in which message
composer is based on `HPGrowingTextView`.
Toolbar buttons are not overridden by this class. We keep the default implementation.
*/
@interface MXKRoomInputToolbarViewWithHPGrowingText : MXKRoomInputToolbarView <HPGrowingTextViewDelegate>
{
@protected
HPGrowingTextView *growingTextView;
}
@end
@@ -1,187 +0,0 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import "MXKRoomInputToolbarViewWithHPGrowingText.h"
@interface MXKRoomInputToolbarViewWithHPGrowingText()
{
// HPGrowingTextView triggers growingTextViewDidChange event when it recomposes itself
// Save the last edited text to prevent unexpected typing events
NSString* lastEditedText;
}
/**
Message composer defined in `messageComposerContainer`.
*/
@property (nonatomic) IBOutlet HPGrowingTextView *growingTextView;
@end
@implementation MXKRoomInputToolbarViewWithHPGrowingText
@synthesize growingTextView;
+ (UINib *)nib
{
return [UINib nibWithNibName:NSStringFromClass([MXKRoomInputToolbarViewWithHPGrowingText class])
bundle:[NSBundle bundleForClass:[MXKRoomInputToolbarViewWithHPGrowingText class]]];
}
- (void)awakeFromNib
{
[super awakeFromNib];
// Handle message composer based on HPGrowingTextView use
growingTextView.delegate = self;
[growingTextView setTranslatesAutoresizingMaskIntoConstraints: NO];
// Add an accessory view to the text view in order to retrieve keyboard view.
inputAccessoryView = [[UIView alloc] initWithFrame:CGRectZero];
growingTextView.internalTextView.inputAccessoryView = self.inputAccessoryView;
// on IOS 8, the growing textview animation could trigger weird UI animations
// indeed, the messages tableView can be refreshed while its height is updated (e.g. when setting a message)
growingTextView.animateHeightChange = NO;
lastEditedText = nil;
}
- (void)dealloc
{
[self destroy];
}
-(void)customizeViewRendering
{
[super customizeViewRendering];
// set text input font
growingTextView.font = [UIFont systemFontOfSize:14];
// draw a rounded border around the textView
growingTextView.layer.cornerRadius = 5;
growingTextView.layer.borderWidth = 1;
growingTextView.layer.borderColor = [UIColor lightGrayColor].CGColor;
growingTextView.clipsToBounds = YES;
growingTextView.backgroundColor = [UIColor whiteColor];
}
- (void)destroy
{
if (growingTextView)
{
growingTextView.delegate = nil;
growingTextView = nil;
}
[super destroy];
}
- (void)setMaxHeight:(CGFloat)maxHeight
{
growingTextView.maxHeight = maxHeight - (self.messageComposerContainerTopConstraint.constant + self.messageComposerContainerBottomConstraint.constant);
[growingTextView refreshHeight];
super.maxHeight = maxHeight;
}
- (NSString*)textMessage
{
return growingTextView.text;
}
- (void)setTextMessage:(NSString *)textMessage
{
growingTextView.text = textMessage;
self.rightInputToolbarButton.enabled = textMessage.length;
}
- (void)pasteText:(NSString *)text
{
self.textMessage = [growingTextView.text stringByReplacingCharactersInRange:growingTextView.selectedRange withString:text];
}
- (void)setPlaceholder:(NSString *)inPlaceholder
{
[super setPlaceholder:inPlaceholder];
growingTextView.placeholder = inPlaceholder;
}
- (BOOL)becomeFirstResponder
{
return [growingTextView becomeFirstResponder];
}
- (void)dismissKeyboard
{
[growingTextView resignFirstResponder];
}
#pragma mark - HPGrowingTextView delegate
- (void)growingTextViewDidEndEditing:(HPGrowingTextView *)sender
{
if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:isTyping:)])
{
[self.delegate roomInputToolbarView:self isTyping:NO];
}
}
- (void)growingTextViewDidChange:(HPGrowingTextView *)sender
{
NSString *msg = growingTextView.text;
// HPGrowingTextView triggers growingTextViewDidChange event when it recomposes itself.
// Save the last edited text to prevent unexpected typing events
if (![lastEditedText isEqualToString:msg])
{
lastEditedText = msg;
if (msg.length)
{
if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:isTyping:)])
{
[self.delegate roomInputToolbarView:self isTyping:YES];
}
self.rightInputToolbarButton.enabled = YES;
}
else
{
if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:isTyping:)])
{
[self.delegate roomInputToolbarView:self isTyping:NO];
}
self.rightInputToolbarButton.enabled = NO;
}
}
}
- (void)growingTextView:(HPGrowingTextView *)growingTextView willChangeHeight:(float)height
{
// Update growing text's superview (toolbar view)
CGFloat updatedHeight = height + (self.messageComposerContainerTopConstraint.constant + self.messageComposerContainerBottomConstraint.constant);
if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:heightDidChanged:completion:)])
{
[self.delegate roomInputToolbarView:self heightDidChanged:updatedHeight completion:nil];
}
}
- (BOOL)growingTextView:(HPGrowingTextView *)growingTextView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
return self.isEditable;
}
@end
@@ -1,85 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="MXKRoomInputToolbarViewWithHPGrowingText">
<rect key="frame" x="0.0" y="0.0" width="600" height="41"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="contactAdd" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Hga-l8-Wua" userLabel="left Button">
<rect key="frame" x="8" y="0.0" width="35" height="41"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="35" id="ptO-BQ-NhS"/>
</constraints>
<state key="normal">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="onTouchUpInside:" destination="iN0-l3-epB" eventType="touchUpInside" id="jVG-We-DmS"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Owf-M8-qJi" userLabel="right Button">
<rect key="frame" x="552" y="0.0" width="44" height="41"/>
<constraints>
<constraint firstAttribute="width" constant="44" id="9FZ-CI-diT"/>
</constraints>
<state key="normal" title="Send">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="onTouchUpInside:" destination="iN0-l3-epB" eventType="touchUpInside" id="jed-Mz-rxe"/>
</connections>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="QWp-NV-uh5" userLabel="Message Composer Container">
<rect key="frame" x="51" y="4" width="497" height="33"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="pkf-YH-tco" customClass="HPGrowingTextView">
<rect key="frame" x="0.0" y="0.0" width="497" height="33"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="pkf-YH-tco" secondAttribute="bottom" id="L3A-Oo-Ml2"/>
<constraint firstItem="pkf-YH-tco" firstAttribute="top" secondItem="QWp-NV-uh5" secondAttribute="top" id="VPn-k0-0vc"/>
<constraint firstItem="pkf-YH-tco" firstAttribute="leading" secondItem="QWp-NV-uh5" secondAttribute="leading" id="mXj-f3-DcT"/>
<constraint firstAttribute="trailing" secondItem="pkf-YH-tco" secondAttribute="trailing" id="n4K-Do-gHr"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="0.89720267057418823" green="0.89720267057418823" blue="0.89720267057418823" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="Owf-M8-qJi" secondAttribute="trailing" constant="4" id="2M8-Gu-0f6"/>
<constraint firstItem="QWp-NV-uh5" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="4" id="570-8j-VYY"/>
<constraint firstAttribute="bottom" secondItem="QWp-NV-uh5" secondAttribute="bottom" constant="4" id="9Ya-0H-03W"/>
<constraint firstItem="Hga-l8-Wua" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="8" id="Bc8-T7-wmA"/>
<constraint firstItem="Hga-l8-Wua" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="Cvk-xZ-ODy"/>
<constraint firstItem="Owf-M8-qJi" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="SV8-U3-8dd"/>
<constraint firstAttribute="bottom" secondItem="Hga-l8-Wua" secondAttribute="bottom" id="Slr-2H-laO"/>
<constraint firstItem="Owf-M8-qJi" firstAttribute="leading" secondItem="QWp-NV-uh5" secondAttribute="trailing" constant="4" id="UEd-gb-jgR"/>
<constraint firstItem="QWp-NV-uh5" firstAttribute="leading" secondItem="Hga-l8-Wua" secondAttribute="trailing" constant="8" id="cCr-Am-M7d"/>
<constraint firstAttribute="bottom" secondItem="Owf-M8-qJi" secondAttribute="bottom" id="ycc-x9-PAv"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<nil key="simulatedTopBarMetrics"/>
<nil key="simulatedBottomBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<connections>
<outlet property="growingTextView" destination="pkf-YH-tco" id="VeP-WI-6Xh"/>
<outlet property="leftInputToolbarButton" destination="Hga-l8-Wua" id="zbm-3b-hoY"/>
<outlet property="messageComposerContainer" destination="QWp-NV-uh5" id="7EX-Un-ZIe"/>
<outlet property="messageComposerContainerBottomConstraint" destination="9Ya-0H-03W" id="226-iu-6tU"/>
<outlet property="messageComposerContainerTopConstraint" destination="570-8j-VYY" id="VKv-Qh-PCs"/>
<outlet property="rightInputToolbarButton" destination="Owf-M8-qJi" id="seO-ly-Bgg"/>
</connections>
</view>
</objects>
</document>