mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-29 07:42:40 +00:00
Merge branch 'release/1.6.8/master'
This commit is contained in:
commit
a14d82fb9b
54 changed files with 1057 additions and 654 deletions
4
.github/ISSUE_TEMPLATE/bug.yml
vendored
4
.github/ISSUE_TEMPLATE/bug.yml
vendored
|
@ -64,9 +64,9 @@ body:
|
|||
- type: dropdown
|
||||
id: rageshake
|
||||
attributes:
|
||||
label: Have you submitted a rageshake?
|
||||
label: Will you send logs?
|
||||
description: |
|
||||
Did you know that you can shake your phone to submit logs for this issue? Trigger the defect, then shake your phone and you will see a popup asking if you would like to open the bug report screen. Click YES, and describe the issue, mentioning that you have also filed a bug. Submit the report to send anonymous logs to the developers.
|
||||
Did you know that you can shake your phone to submit logs for this issue? Trigger the defect, then shake your phone and you will see a popup asking if you would like to open the bug report screen. Click YES, and describe the issue, mentioning that you have also filed a bug (it's helpful if you can include a link to the bug). Send the report to submit anonymous logs to the developers.
|
||||
options:
|
||||
- 'Yes'
|
||||
- 'No'
|
||||
|
|
32
CHANGES.md
32
CHANGES.md
|
@ -1,3 +1,35 @@
|
|||
## Changes in 1.6.8 (2021-11-17)
|
||||
|
||||
🙌 Improvements
|
||||
|
||||
- Upgrade MatrixKit version ([v0.16.10](https://github.com/matrix-org/matrix-ios-kit/releases/tag/v0.16.10)).
|
||||
- Using mutable room list fetch sort options after chaning them to be a structure. ([#4384](https://github.com/vector-im/element-ios/issues/4384))
|
||||
- Share Extension: Remove the image compression prompt when the showMediaSizeSelection setting is disabled. ([#4815](https://github.com/vector-im/element-ios/issues/4815))
|
||||
- Replaced GrowingTextView with simpler, custom implementation. Cleaned up the RoomInputToolbar header. ([#4976](https://github.com/vector-im/element-ios/issues/4976))
|
||||
- Settings: Update about section footer text. ([#5090](https://github.com/vector-im/element-ios/issues/5090))
|
||||
- MXSession: Add logs to track if E2EE is enabled by default on the current HS. ([#5129](https://github.com/vector-im/element-ios/issues/5129))
|
||||
|
||||
🐛 Bugfixes
|
||||
|
||||
- Fixed share extension and message forwarding room list accessory view icon. ([#5041](https://github.com/vector-im/element-ios/issues/5041))
|
||||
- Fixed message composer not following keyboard when swiping to dismiss. ([#5042](https://github.com/vector-im/element-ios/issues/5042))
|
||||
- RoomVC: Fix retain cycles that prevents `RoomViewController` to be deallocated. ([#5055](https://github.com/vector-im/element-ios/issues/5055))
|
||||
- Share Extension: Fix missing avatars and don't list spaces as rooms. ([#5057](https://github.com/vector-im/element-ios/issues/5057))
|
||||
- Fix retain cycles that prevents deallocation in several classes. ([#5058](https://github.com/vector-im/element-ios/issues/5058))
|
||||
- Fixed retain cycles between the user suggestion coordinator and the suggestion service, and in the suggestion service currentTextTrigger subject sink. ([#5063](https://github.com/vector-im/element-ios/issues/5063))
|
||||
- Ensure alerts with weak references are retained until they've been presented. ([#5071](https://github.com/vector-im/element-ios/issues/5071))
|
||||
- Message Composer: Ensure there is no text view when the user isn't allowed to send messages. ([#5079](https://github.com/vector-im/element-ios/issues/5079))
|
||||
- Home: Fix bug where favourited DM would be shown in both Favourites and People section. ([#5081](https://github.com/vector-im/element-ios/issues/5081))
|
||||
- Fix a crash when selected space is not home and a clear cache or logout is performed. ([#5082](https://github.com/vector-im/element-ios/issues/5082))
|
||||
- Room Previews: Fix room previews not loading. ([#5083](https://github.com/vector-im/element-ios/issues/5083))
|
||||
- Do not make the placeholder appearing when leaving a room on iPhone. ([#5084](https://github.com/vector-im/element-ios/issues/5084))
|
||||
- Fix room ordering when switching between Home and People/Rooms/Favourites. ([#5105](https://github.com/vector-im/element-ios/issues/5105))
|
||||
|
||||
Others
|
||||
|
||||
- Improve wording around rageshakes in the defect issue template. ([#4987](https://github.com/vector-im/element-ios/issues/4987))
|
||||
|
||||
|
||||
## Changes in 1.6.6 (2021-10-21)
|
||||
|
||||
✨ Features
|
||||
|
|
|
@ -15,5 +15,5 @@
|
|||
//
|
||||
|
||||
// Version
|
||||
MARKETING_VERSION = 1.6.6
|
||||
CURRENT_PROJECT_VERSION = 1.6.6
|
||||
MARKETING_VERSION = 1.6.8
|
||||
CURRENT_PROJECT_VERSION = 1.6.8
|
||||
|
|
3
Podfile
3
Podfile
|
@ -13,7 +13,7 @@ use_frameworks!
|
|||
# - `{ {kit spec hash} => {sdk spec hash}` to depend on specific pod options (:git => …, :podspec => …) for each repo. Used by Fastfile during CI
|
||||
#
|
||||
# Warning: our internal tooling depends on the name of this variable name, so be sure not to change it
|
||||
$matrixKitVersion = '= 0.16.9'
|
||||
$matrixKitVersion = '= 0.16.10'
|
||||
# $matrixKitVersion = :local
|
||||
# $matrixKitVersion = {'develop' => 'develop'}
|
||||
|
||||
|
@ -73,7 +73,6 @@ abstract_target 'RiotPods' do
|
|||
pod 'SideMenu', '~> 6.5'
|
||||
pod 'DSWaveformImage', '~> 6.1.1'
|
||||
pod 'ffmpeg-kit-ios-audio', '~> 4.5'
|
||||
pod 'GrowingTextView', '~> 0.7.2'
|
||||
|
||||
pod 'FLEX', '~> 4.5.0', :configurations => ['Debug']
|
||||
|
||||
|
|
30
Podfile.lock
30
Podfile.lock
|
@ -43,7 +43,6 @@ PODS:
|
|||
- GBDeviceInfo (6.6.0):
|
||||
- GBDeviceInfo/Core (= 6.6.0)
|
||||
- GBDeviceInfo/Core (6.6.0)
|
||||
- GrowingTextView (0.7.2)
|
||||
- GZIP (1.3.0)
|
||||
- HPGrowingTextView (1.1)
|
||||
- JitsiMeetSDK (3.10.2)
|
||||
|
@ -59,29 +58,29 @@ PODS:
|
|||
- MatomoTracker (7.4.1):
|
||||
- MatomoTracker/Core (= 7.4.1)
|
||||
- MatomoTracker/Core (7.4.1)
|
||||
- MatrixKit (0.16.9):
|
||||
- MatrixKit (0.16.10):
|
||||
- Down (~> 0.11.0)
|
||||
- DTCoreText (~> 1.6.25)
|
||||
- HPGrowingTextView (~> 1.1)
|
||||
- libPhoneNumber-iOS (~> 0.9.13)
|
||||
- MatrixKit/Core (= 0.16.9)
|
||||
- MatrixSDK (= 0.20.9)
|
||||
- MatrixKit/Core (0.16.9):
|
||||
- MatrixKit/Core (= 0.16.10)
|
||||
- MatrixSDK (= 0.20.10)
|
||||
- MatrixKit/Core (0.16.10):
|
||||
- Down (~> 0.11.0)
|
||||
- DTCoreText (~> 1.6.25)
|
||||
- HPGrowingTextView (~> 1.1)
|
||||
- libPhoneNumber-iOS (~> 0.9.13)
|
||||
- MatrixSDK (= 0.20.9)
|
||||
- MatrixSDK (0.20.9):
|
||||
- MatrixSDK/Core (= 0.20.9)
|
||||
- MatrixSDK/Core (0.20.9):
|
||||
- MatrixSDK (= 0.20.10)
|
||||
- MatrixSDK (0.20.10):
|
||||
- MatrixSDK/Core (= 0.20.10)
|
||||
- MatrixSDK/Core (0.20.10):
|
||||
- AFNetworking (~> 4.0.0)
|
||||
- GZIP (~> 1.3.0)
|
||||
- libbase58 (~> 0.1.4)
|
||||
- OLMKit (~> 3.2.5)
|
||||
- Realm (= 10.16.0)
|
||||
- SwiftyBeaver (= 1.9.5)
|
||||
- MatrixSDK/JingleCallStack (0.20.9):
|
||||
- MatrixSDK/JingleCallStack (0.20.10):
|
||||
- JitsiMeetSDK (= 3.10.2)
|
||||
- MatrixSDK/Core
|
||||
- OLMKit (3.2.5):
|
||||
|
@ -122,11 +121,10 @@ DEPENDENCIES:
|
|||
- FLEX (~> 4.5.0)
|
||||
- FlowCommoniOS (~> 1.12.0)
|
||||
- GBDeviceInfo (~> 6.6.0)
|
||||
- GrowingTextView (~> 0.7.2)
|
||||
- KeychainAccess (~> 4.2.2)
|
||||
- KTCenterFlowLayout (~> 1.3.1)
|
||||
- MatomoTracker (~> 7.4.1)
|
||||
- MatrixKit (= 0.16.9)
|
||||
- MatrixKit (= 0.16.10)
|
||||
- MatrixSDK
|
||||
- MatrixSDK/JingleCallStack
|
||||
- OLMKit
|
||||
|
@ -156,7 +154,6 @@ SPEC REPOS:
|
|||
- FLEX
|
||||
- FlowCommoniOS
|
||||
- GBDeviceInfo
|
||||
- GrowingTextView
|
||||
- GZIP
|
||||
- HPGrowingTextView
|
||||
- JitsiMeetSDK
|
||||
|
@ -198,7 +195,6 @@ SPEC CHECKSUMS:
|
|||
FLEX: e51461dd6f0bfb00643c262acdfea5d5d12c596b
|
||||
FlowCommoniOS: e9ecbc97fb9ce5c593fb3da0e1073b65a3902026
|
||||
GBDeviceInfo: ed0db16230d2fa280e1cbb39a5a7f60f6946aaec
|
||||
GrowingTextView: 876bf42005b5e4a4fd740597db12caaf41f0fe6c
|
||||
GZIP: 416858efbe66b41b206895ac6dfd5493200d95b3
|
||||
HPGrowingTextView: 88a716d97fb853bcb08a4a08e4727da17efc9b19
|
||||
JitsiMeetSDK: 2f118fa770f23e518f3560fc224fae3ac7062223
|
||||
|
@ -210,8 +206,8 @@ SPEC CHECKSUMS:
|
|||
LoggerAPI: ad9c4a6f1e32f518fdb43a1347ac14d765ab5e3d
|
||||
Logging: beeb016c9c80cf77042d62e83495816847ef108b
|
||||
MatomoTracker: 24a846c9d3aa76933183fe9d47fd62c9efa863fb
|
||||
MatrixKit: ed209774b5c3408974c52cfe2aaba4d2e8b4b05b
|
||||
MatrixSDK: 9e312e3874027bf9eab61be7d0779102f8bd323a
|
||||
MatrixKit: c3f0bb056ceeb015e2f1688543ac4dbcf88bef2f
|
||||
MatrixSDK: 0e2ed8fc6f004cac4b4ab46f038a86fe49ce4007
|
||||
OLMKit: 9fb4799c4a044dd2c06bda31ec31a12191ad30b5
|
||||
ReadMoreTextView: 19147adf93abce6d7271e14031a00303fe28720d
|
||||
Realm: b6027801398f3743fc222f096faa85281b506e6c
|
||||
|
@ -226,6 +222,6 @@ SPEC CHECKSUMS:
|
|||
zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c
|
||||
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
|
||||
|
||||
PODFILE CHECKSUM: 2740772a9b2d32e17876526875dfc58f67240ba0
|
||||
PODFILE CHECKSUM: 675c24e5fcaf580998f32fde709fc3be1b2bde22
|
||||
|
||||
COCOAPODS: 1.11.2
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
buildImplicitDependencies = "YES"
|
||||
runPostActionsOnFailure = "NO">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
|
|
|
@ -19,5 +19,8 @@
|
|||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,5 +19,8 @@
|
|||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1016,6 +1016,9 @@ Tap the + to start adding people.";
|
|||
// Share extension
|
||||
"share_extension_auth_prompt" = "Login in the main app to share content";
|
||||
"share_extension_failed_to_encrypt" = "Failed to send. Check in the main app the encryption settings for this room";
|
||||
"share_extension_low_quality_video_title" = "Video will be sent in low quality";
|
||||
"share_extension_low_quality_video_message" = "Send in %@ for better quality, or send in low quality below.";
|
||||
"share_extension_send_now" = "Send now";
|
||||
|
||||
// Room key request dialog
|
||||
"e2e_room_key_request_title" = "Encryption key request";
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
MXLogWarning(@"[MXSession] E2EE is disabled by default on this homeserver.\nWellknown content: %@", self.homeserverWellknown.JSONDictionary);
|
||||
success(NO);
|
||||
return [MXHTTPOperation new];
|
||||
}
|
||||
|
|
|
@ -4775,6 +4775,18 @@ public class VectorL10n: NSObject {
|
|||
public static var shareExtensionFailedToEncrypt: String {
|
||||
return VectorL10n.tr("Vector", "share_extension_failed_to_encrypt")
|
||||
}
|
||||
/// Send in %@ for better quality, or send in low quality below.
|
||||
public static func shareExtensionLowQualityVideoMessage(_ p1: String) -> String {
|
||||
return VectorL10n.tr("Vector", "share_extension_low_quality_video_message", p1)
|
||||
}
|
||||
/// Video will be sent in low quality
|
||||
public static var shareExtensionLowQualityVideoTitle: String {
|
||||
return VectorL10n.tr("Vector", "share_extension_low_quality_video_title")
|
||||
}
|
||||
/// Send now
|
||||
public static var shareExtensionSendNow: String {
|
||||
return VectorL10n.tr("Vector", "share_extension_send_now")
|
||||
}
|
||||
/// Feedback
|
||||
public static var sideMenuActionFeedback: String {
|
||||
return VectorL10n.tr("Vector", "side_menu_action_feedback")
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
/**
|
||||
The delegate object to receive analytics events.
|
||||
*/
|
||||
@property (nonatomic) id<MXAnalyticsDelegate> delegate;
|
||||
@property (nonatomic, weak) id<MXAnalyticsDelegate> delegate;
|
||||
|
||||
/**
|
||||
Report an event unable to decrypt.
|
||||
|
|
|
@ -143,7 +143,7 @@ final class RiotSettings: NSObject {
|
|||
@UserDefault(key: "roomsAllowToJoinPublicRooms", defaultValue: BuildSettings.roomsAllowToJoinPublicRooms, storage: defaults)
|
||||
var roomsAllowToJoinPublicRooms
|
||||
|
||||
@UserDefault(key: UserDefaultsKeys.showAllRoomsInHomeSpace, defaultValue: false, storage: defaults)
|
||||
@UserDefault(key: UserDefaultsKeys.showAllRoomsInHomeSpace, defaultValue: true, storage: defaults)
|
||||
var showAllRoomsInHomeSpace
|
||||
|
||||
// MARK: - Room Screen
|
||||
|
|
|
@ -228,7 +228,7 @@ extension AppCoordinator: LegacyAppDelegateDelegate {
|
|||
}
|
||||
|
||||
func legacyAppDelegateRestoreEmptyDetailsViewController(_ legacyAppDelegate: LegacyAppDelegate!) {
|
||||
self.splitViewCoordinator?.restorePlaceholderDetails()
|
||||
self.splitViewCoordinator?.resetDetails(animated: false)
|
||||
}
|
||||
|
||||
func legacyAppDelegate(_ legacyAppDelegate: LegacyAppDelegate!, didAddMatrixSession session: MXSession!) {
|
||||
|
|
|
@ -40,7 +40,7 @@ FOUNDATION_EXPORT NSString *const RecentsViewControllerDataReadyNotification;
|
|||
/**
|
||||
Current alert (if any).
|
||||
*/
|
||||
UIAlertController *currentAlert;
|
||||
__weak UIAlertController *currentAlert;
|
||||
|
||||
/**
|
||||
The list of the section headers currently displayed in the recents table.
|
||||
|
|
|
@ -50,13 +50,13 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
NSIndexPath* lastPotentialCellPath;
|
||||
|
||||
// Observe UIApplicationDidEnterBackgroundNotification to cancel editing mode when app leaves the foreground state.
|
||||
id UIApplicationDidEnterBackgroundNotificationObserver;
|
||||
__weak id UIApplicationDidEnterBackgroundNotificationObserver;
|
||||
|
||||
// Observe kAppDelegateDidTapStatusBarNotification to handle tap on clock status bar.
|
||||
id kAppDelegateDidTapStatusBarNotificationObserver;
|
||||
__weak id kAppDelegateDidTapStatusBarNotificationObserver;
|
||||
|
||||
// Observe kMXNotificationCenterDidUpdateRules to update missed messages counts.
|
||||
id kMXNotificationCenterDidUpdateRulesObserver;
|
||||
__weak id kMXNotificationCenterDidUpdateRulesObserver;
|
||||
|
||||
MXHTTPOperation *currentRequest;
|
||||
|
||||
|
@ -65,7 +65,7 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
UISearchBar *tableSearchBar;
|
||||
|
||||
// Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change.
|
||||
id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
__weak id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
}
|
||||
|
||||
@property (nonatomic, strong) CreateRoomCoordinatorBridgePresenter *createRoomCoordinatorBridgePresenter;
|
||||
|
@ -156,11 +156,15 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
// Apply dragging settings
|
||||
self.enableDragging = _enableDragging;
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Observe UIApplicationDidEnterBackgroundNotification to refresh bubbles when app leaves the foreground state.
|
||||
UIApplicationDidEnterBackgroundNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
// Leave potential editing mode
|
||||
[self cancelEditionMode:isRefreshPending];
|
||||
[self cancelEditionMode:self->isRefreshPending];
|
||||
|
||||
}];
|
||||
|
||||
|
@ -170,6 +174,8 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
// Observe user interface theme change.
|
||||
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self userInterfaceThemeDidChange];
|
||||
|
||||
}];
|
||||
|
@ -268,9 +274,13 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
[self.recentsTableView deselectRowAtIndexPath:indexPath animated:NO];
|
||||
}
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Observe kAppDelegateDidTapStatusBarNotificationObserver.
|
||||
kAppDelegateDidTapStatusBarNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kAppDelegateDidTapStatusBarNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self scrollToTop:YES];
|
||||
|
||||
}];
|
||||
|
@ -278,6 +288,8 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
// Observe kMXNotificationCenterDidUpdateRules to refresh missed messages counts
|
||||
kMXNotificationCenterDidUpdateRulesObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXNotificationCenterDidUpdateRules object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self refreshRecentsTable];
|
||||
|
||||
}];
|
||||
|
@ -527,11 +539,13 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
|
||||
[self->currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
|
||||
self->currentAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n roomErrorJoinFailedTitle] message:msg preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *errorAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n roomErrorJoinFailedTitle]
|
||||
message:msg
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[errorAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
self->currentAlert = nil;
|
||||
|
||||
|
@ -541,7 +555,8 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
}
|
||||
}]];
|
||||
|
||||
[self presentViewController:self->currentAlert animated:YES completion:nil];
|
||||
[self presentViewController:errorAlert animated:YES completion:nil];
|
||||
currentAlert = errorAlert;
|
||||
}
|
||||
|
||||
#pragma mark - Sticky Headers
|
||||
|
@ -1190,13 +1205,13 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
}
|
||||
|
||||
// confirm leave
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:title
|
||||
message:message
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *leavePrompt = [UIAlertController alertControllerWithTitle:title
|
||||
message:message
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel]
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction * action) {
|
||||
[leavePrompt addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel]
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -1206,8 +1221,8 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n leave]
|
||||
style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
[leavePrompt addAction:[UIAlertAction actionWithTitle:[VectorL10n leave]
|
||||
style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -1268,8 +1283,9 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert mxk_setAccessibilityIdentifier:@"LeaveEditedRoomAlert"];
|
||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
[leavePrompt mxk_setAccessibilityIdentifier:@"LeaveEditedRoomAlert"];
|
||||
[self presentViewController:leavePrompt animated:YES completion:nil];
|
||||
currentAlert = leavePrompt;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1824,11 +1840,11 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
|
||||
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
|
||||
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomRecentsStartChatWith]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionSheet addAction:[UIAlertAction actionWithTitle:[VectorL10n roomRecentsStartChatWith]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -1840,9 +1856,9 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomRecentsCreateEmptyRoom]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionSheet addAction:[UIAlertAction actionWithTitle:[VectorL10n roomRecentsCreateEmptyRoom]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -1854,9 +1870,9 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomRecentsJoinRoom]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionSheet addAction:[UIAlertAction actionWithTitle:[VectorL10n roomRecentsJoinRoom]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -1870,10 +1886,9 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
|
||||
if (self.mainSession.callManager.supportsPSTN)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction
|
||||
actionWithTitle:[VectorL10n roomOpenDialpad]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionSheet addAction:[UIAlertAction actionWithTitle:[VectorL10n roomOpenDialpad]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -1886,9 +1901,9 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
}]];
|
||||
}
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel]
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionSheet addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel]
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -1898,11 +1913,12 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert popoverPresentationController].sourceView = plusButtonImageView;
|
||||
[currentAlert popoverPresentationController].sourceRect = plusButtonImageView.bounds;
|
||||
[actionSheet popoverPresentationController].sourceView = plusButtonImageView;
|
||||
[actionSheet popoverPresentationController].sourceRect = plusButtonImageView.bounds;
|
||||
|
||||
[currentAlert mxk_setAccessibilityIdentifier:@"RecentsVCCreateRoomAlert"];
|
||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
[actionSheet mxk_setAccessibilityIdentifier:@"RecentsVCCreateRoomAlert"];
|
||||
[self presentViewController:actionSheet animated:YES completion:nil];
|
||||
currentAlert = actionSheet;
|
||||
}
|
||||
|
||||
- (void)openDialpad
|
||||
|
@ -1996,7 +2012,7 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
}
|
||||
|
||||
// Check whether the user has already joined the selected public room
|
||||
if ([self.recentsDataSource.publicRoomsDirectoryDataSource.mxSession roomWithRoomId:publicRoom.roomId])
|
||||
if ([self.recentsDataSource.publicRoomsDirectoryDataSource.mxSession isJoinedOnRoom:publicRoom.roomId])
|
||||
{
|
||||
// Open the public room
|
||||
[self showRoomWithRoomId:publicRoom.roomId
|
||||
|
|
|
@ -20,7 +20,12 @@ import Foundation
|
|||
public class RecentsListService: NSObject, RecentsListServiceProtocol {
|
||||
|
||||
private weak var session: MXSession?
|
||||
public private(set) var mode: RecentsDataSourceMode
|
||||
public private(set) var mode: RecentsDataSourceMode {
|
||||
didSet {
|
||||
refresh()
|
||||
}
|
||||
}
|
||||
|
||||
public private(set) var query: String?
|
||||
public private(set) var space: MXSpace?
|
||||
|
||||
|
@ -427,7 +432,7 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol {
|
|||
private func updateDirectFetcher(_ fetcher: MXRoomListDataFetcher, for mode: RecentsDataSourceMode) {
|
||||
switch mode {
|
||||
case .home:
|
||||
fetcher.fetchOptions.filterOptions.notDataTypes = [.invited, .lowPriority]
|
||||
fetcher.fetchOptions.filterOptions.notDataTypes = [.invited, .favorited, .lowPriority]
|
||||
case .people:
|
||||
fetcher.fetchOptions.filterOptions.notDataTypes = [.lowPriority]
|
||||
default:
|
||||
|
@ -440,7 +445,7 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol {
|
|||
case .home:
|
||||
fetcher.fetchOptions.sortOptions = sortOptions
|
||||
case .favourites:
|
||||
let newSortOptions = sortOptions
|
||||
var newSortOptions = sortOptions
|
||||
newSortOptions.favoriteTag = true
|
||||
fetcher.fetchOptions.sortOptions = newSortOptions
|
||||
default:
|
||||
|
|
|
@ -60,6 +60,18 @@ public class MockRoomSummary: NSObject, MXRoomSummaryProtocol {
|
|||
|
||||
public var highlightCount: UInt = 0
|
||||
|
||||
public var hasAnyUnread: Bool {
|
||||
return localUnreadEventCount > 0
|
||||
}
|
||||
|
||||
public var hasAnyNotification: Bool {
|
||||
return notificationCount > 0
|
||||
}
|
||||
|
||||
public var hasAnyHighlight: Bool {
|
||||
return highlightCount > 0
|
||||
}
|
||||
|
||||
public var isDirect: Bool {
|
||||
return isTyped(.direct)
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
NSLayoutConstraint *leftMarkerViewConstraint;
|
||||
|
||||
// Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change.
|
||||
id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
__weak id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -183,9 +183,13 @@
|
|||
|
||||
[self createSegmentedViews];
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Observe user interface theme change.
|
||||
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self userInterfaceThemeDidChange];
|
||||
|
||||
}];
|
||||
|
|
|
@ -27,10 +27,10 @@
|
|||
BOOL isRefreshPending;
|
||||
|
||||
// Observe UIApplicationDidEnterBackgroundNotification to cancel editing mode when app leaves the foreground state.
|
||||
id UIApplicationDidEnterBackgroundNotificationObserver;
|
||||
__weak id UIApplicationDidEnterBackgroundNotificationObserver;
|
||||
|
||||
// Observe kAppDelegateDidTapStatusBarNotification to handle tap on clock status bar.
|
||||
id kAppDelegateDidTapStatusBarNotificationObserver;
|
||||
__weak id kAppDelegateDidTapStatusBarNotificationObserver;
|
||||
|
||||
MXHTTPOperation *currentRequest;
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
|||
UISearchBar *tableSearchBar;
|
||||
|
||||
// Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change.
|
||||
id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
__weak id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -98,11 +98,15 @@
|
|||
self.groupsTableView.estimatedSectionHeaderHeight = 30;
|
||||
self.groupsTableView.estimatedSectionFooterHeight = 0;
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Observe UIApplicationDidEnterBackgroundNotification to refresh bubbles when app leaves the foreground state.
|
||||
UIApplicationDidEnterBackgroundNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
// Leave potential editing mode
|
||||
[self cancelEditionMode:isRefreshPending];
|
||||
[self cancelEditionMode:self->isRefreshPending];
|
||||
|
||||
}];
|
||||
|
||||
|
@ -117,6 +121,8 @@
|
|||
// Observe user interface theme change.
|
||||
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self userInterfaceThemeDidChange];
|
||||
|
||||
}];
|
||||
|
@ -207,9 +213,13 @@
|
|||
[self.groupsTableView deselectRowAtIndexPath:indexPath animated:NO];
|
||||
}
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Observe kAppDelegateDidTapStatusBarNotificationObserver.
|
||||
kAppDelegateDidTapStatusBarNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kAppDelegateDidTapStatusBarNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self scrollToTop:YES];
|
||||
|
||||
}];
|
||||
|
|
|
@ -43,6 +43,10 @@ final class GroupDetailsCoordinator: GroupDetailsCoordinatorProtocol {
|
|||
self.groupDetailsViewController = groupDetailsViewController
|
||||
}
|
||||
|
||||
deinit {
|
||||
groupDetailsViewController.destroy()
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func start() {
|
||||
|
|
|
@ -122,7 +122,7 @@
|
|||
/**
|
||||
The delegate for the view controller.
|
||||
*/
|
||||
@property (nonatomic) id<ContactsTableViewControllerDelegate> contactsTableViewControllerDelegate;
|
||||
@property (nonatomic, weak) id<ContactsTableViewControllerDelegate> contactsTableViewControllerDelegate;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -33,12 +33,12 @@
|
|||
/**
|
||||
Observe kAppDelegateDidTapStatusBarNotification to handle tap on clock status bar.
|
||||
*/
|
||||
id kAppDelegateDidTapStatusBarNotificationObserver;
|
||||
__weak id kAppDelegateDidTapStatusBarNotificationObserver;
|
||||
|
||||
/**
|
||||
Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change.
|
||||
*/
|
||||
id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
__weak id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
}
|
||||
|
||||
@property (nonatomic, strong) FindYourContactsFooterView *findYourContactsFooterView;
|
||||
|
@ -102,9 +102,13 @@
|
|||
self.contactsTableView.tableFooterView = [[UIView alloc] init];
|
||||
self.contactsAreFilteredWithSearch = NO;
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Observe user interface theme change.
|
||||
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self userInterfaceThemeDidChange];
|
||||
|
||||
}];
|
||||
|
@ -158,10 +162,14 @@
|
|||
|
||||
// Screen tracking
|
||||
[[Analytics sharedInstance] trackScreen:_screenName];
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Observe kAppDelegateDidTapStatusBarNotification.
|
||||
kAppDelegateDidTapStatusBarNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kAppDelegateDidTapStatusBarNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self.contactsTableView setContentOffset:CGPointMake(-self.contactsTableView.adjustedContentInset.left, -self.contactsTableView.adjustedContentInset.top) animated:YES];
|
||||
|
||||
}];
|
||||
|
|
|
@ -47,12 +47,12 @@
|
|||
/**
|
||||
Observe UIApplicationWillChangeStatusBarOrientationNotification to hide/show bubbles bg.
|
||||
*/
|
||||
id UIApplicationWillChangeStatusBarOrientationNotificationObserver;
|
||||
__weak id UIApplicationWillChangeStatusBarOrientationNotificationObserver;
|
||||
|
||||
/**
|
||||
The observer of the presence for matrix user.
|
||||
*/
|
||||
id mxPresenceObserver;
|
||||
__weak id mxPresenceObserver;
|
||||
|
||||
/**
|
||||
List of the basic actions on this contact.
|
||||
|
@ -79,7 +79,7 @@
|
|||
/**
|
||||
Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change.
|
||||
*/
|
||||
id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
__weak id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
|
||||
/**
|
||||
The current visibility of the status bar in this view controller.
|
||||
|
@ -182,9 +182,13 @@
|
|||
self.bottomImageView.hidden = (orientation.integerValue == UIInterfaceOrientationLandscapeLeft || orientation.integerValue == UIInterfaceOrientationLandscapeRight);
|
||||
}];
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Observe user interface theme change.
|
||||
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self userInterfaceThemeDidChange];
|
||||
|
||||
}];
|
||||
|
@ -379,9 +383,13 @@
|
|||
// Be warned when the thumbnail is updated
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onThumbnailUpdate:) name:kMXKContactThumbnailUpdateNotification object:nil];
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Observe contact presence change
|
||||
mxPresenceObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXKContactManagerMatrixUserPresenceChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
NSString* matrixId = self.firstMatrixId;
|
||||
|
||||
if (matrixId && [matrixId isEqualToString:notif.object])
|
||||
|
|
|
@ -105,8 +105,8 @@ final class EnterNewRoomDetailsViewController: UIViewController {
|
|||
|
||||
var section3: Section?
|
||||
if RiotSettings.shared.roomCreationScreenAllowEncryptionConfiguration {
|
||||
let row_3_0 = Row(type: .withSwitch(isOn: viewModel.roomCreationParameters.isEncrypted, onValueChanged: { (theSwitch) in
|
||||
self.viewModel.roomCreationParameters.isEncrypted = theSwitch.isOn
|
||||
let row_3_0 = Row(type: .withSwitch(isOn: viewModel.roomCreationParameters.isEncrypted, onValueChanged: { [weak self] (theSwitch) in
|
||||
self?.viewModel.roomCreationParameters.isEncrypted = theSwitch.isOn
|
||||
}), text: VectorL10n.createRoomEnableEncryption, accessoryType: .none) {
|
||||
// no-op
|
||||
}
|
||||
|
@ -117,11 +117,20 @@ final class EnterNewRoomDetailsViewController: UIViewController {
|
|||
|
||||
var section4: Section?
|
||||
if RiotSettings.shared.roomCreationScreenAllowRoomTypeConfiguration {
|
||||
let row_4_0 = Row(type: .default, text: VectorL10n.createRoomTypePrivate, accessoryType: viewModel.roomCreationParameters.isPublic ? .none : .checkmark) {
|
||||
let row_4_0 = Row(type: .default, text: VectorL10n.createRoomTypePrivate, accessoryType: viewModel.roomCreationParameters.isPublic ? .none : .checkmark) { [weak self] in
|
||||
guard let self = self else {
|
||||
return
|
||||
}
|
||||
|
||||
self.viewModel.roomCreationParameters.isPublic = false
|
||||
self.updateSections()
|
||||
}
|
||||
let row_4_1 = Row(type: .default, text: VectorL10n.createRoomTypePublic, accessoryType: viewModel.roomCreationParameters.isPublic ? .checkmark : .none) {
|
||||
let row_4_1 = Row(type: .default, text: VectorL10n.createRoomTypePublic, accessoryType: viewModel.roomCreationParameters.isPublic ? .checkmark : .none) { [weak self] in
|
||||
|
||||
guard let self = self else {
|
||||
return
|
||||
}
|
||||
|
||||
self.viewModel.roomCreationParameters.isPublic = true
|
||||
self.updateSections()
|
||||
// scroll bottom to show user new fields
|
||||
|
@ -149,8 +158,8 @@ final class EnterNewRoomDetailsViewController: UIViewController {
|
|||
}
|
||||
|
||||
if viewModel.roomCreationParameters.isPublic {
|
||||
let row_5_0 = Row(type: .withSwitch(isOn: viewModel.roomCreationParameters.showInDirectory, onValueChanged: { (theSwitch) in
|
||||
self.viewModel.roomCreationParameters.showInDirectory = theSwitch.isOn
|
||||
let row_5_0 = Row(type: .withSwitch(isOn: viewModel.roomCreationParameters.showInDirectory, onValueChanged: { [weak self] (theSwitch) in
|
||||
self?.viewModel.roomCreationParameters.showInDirectory = theSwitch.isOn
|
||||
}), text: VectorL10n.createRoomShowInDirectory, accessoryType: .none) {
|
||||
// no-op
|
||||
}
|
||||
|
@ -389,7 +398,10 @@ extension EnterNewRoomDetailsViewController: UITableViewDataSource {
|
|||
cell.mxkLabel.text = row.text
|
||||
cell.mxkSwitch.isOn = isOn
|
||||
cell.mxkSwitch.removeTarget(nil, action: nil, for: .valueChanged)
|
||||
cell.mxkSwitch.vc_addAction(for: .valueChanged) {
|
||||
cell.mxkSwitch.vc_addAction(for: .valueChanged) { [weak cell] in
|
||||
guard let cell = cell else {
|
||||
return
|
||||
}
|
||||
onValueChanged?(cell.mxkSwitch)
|
||||
}
|
||||
cell.mxkLabelLeadingConstraint.constant = cell.vc_separatorInset.left
|
||||
|
|
|
@ -190,7 +190,7 @@
|
|||
MXPublicRoom *publicRoom = [dataSource roomAtIndexPath:indexPath];
|
||||
|
||||
// Check whether the user has already joined the selected public room
|
||||
if ([dataSource.mxSession roomWithRoomId:publicRoom.roomId])
|
||||
if ([dataSource.mxSession isJoinedOnRoom:publicRoom.roomId])
|
||||
{
|
||||
// Open the public room.
|
||||
[self showRoomWithId:publicRoom.roomId inMatrixSession:dataSource.mxSession];
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
/**
|
||||
The delegate for the view controller.
|
||||
*/
|
||||
@property (nonatomic) id<JitsiViewControllerDelegate> delegate;
|
||||
@property (nonatomic, weak) id<JitsiViewControllerDelegate> delegate;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ const CGFloat kTypingCellHeight = 24;
|
|||
// Timer used to debounce cells refresh
|
||||
@property (nonatomic, strong) NSTimer *refreshCellsTimer;
|
||||
|
||||
@property (nonatomic, readonly) id<RoomDataSourceDelegate> roomDataSourceDelegate;
|
||||
@property (nonatomic, weak, readonly) id<RoomDataSourceDelegate> roomDataSourceDelegate;
|
||||
|
||||
@property(nonatomic, readwrite) RoomEncryptionTrustLevel encryptionTrustLevel;
|
||||
|
||||
|
|
|
@ -54,6 +54,6 @@
|
|||
/**
|
||||
The delegate.
|
||||
*/
|
||||
@property (nonatomic) id<RoomMemberTitleViewDelegate> delegate;
|
||||
@property (nonatomic, weak) id<RoomMemberTitleViewDelegate> delegate;
|
||||
|
||||
@end
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
/**
|
||||
The delegate for the view controller.
|
||||
*/
|
||||
@property (nonatomic) id<RoomParticipantsViewControllerDelegate> delegate;
|
||||
@property (nonatomic, weak) id<RoomParticipantsViewControllerDelegate> delegate;
|
||||
|
||||
/**
|
||||
Returns the `UINib` object initialized for a `RoomParticipantsViewController`.
|
||||
|
|
|
@ -77,6 +77,10 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol {
|
|||
|
||||
super.init()
|
||||
}
|
||||
|
||||
deinit {
|
||||
roomViewController.destroy()
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
|
@ -90,9 +94,12 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol {
|
|||
self.roomViewController.delegate = self
|
||||
|
||||
// Detect when view controller has been dismissed by gesture when presented modally (not in full screen).
|
||||
self.roomViewController.presentationController?.delegate = self
|
||||
// FIXME: Find a better way to manage modal dismiss. This makes the `roomViewController` to never be released
|
||||
// self.roomViewController.presentationController?.delegate = self
|
||||
|
||||
if let eventId = self.selectedEventId {
|
||||
if let previewData = self.parameters.previewData {
|
||||
self.loadRoomPreview(withData: previewData, completion: completion)
|
||||
} else if let eventId = self.selectedEventId {
|
||||
self.loadRoom(withId: self.parameters.roomId, and: eventId, completion: completion)
|
||||
} else {
|
||||
self.loadRoom(withId: self.parameters.roomId, completion: completion)
|
||||
|
@ -178,6 +185,13 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol {
|
|||
completion?()
|
||||
}
|
||||
}
|
||||
|
||||
private func loadRoomPreview(withData previewData: RoomPreviewData, completion: (() -> Void)?) {
|
||||
|
||||
self.roomViewController.displayRoomPreview(previewData)
|
||||
|
||||
completion?()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - RoomIdentifiable
|
||||
|
|
|
@ -152,11 +152,10 @@ final class RoomInfoCoordinator: NSObject, RoomInfoCoordinatorType {
|
|||
case .search:
|
||||
MXKRoomDataSourceManager.sharedManager(forMatrixSession: session)?.roomDataSource(forRoom: self.room.roomId, create: false, onComplete: { (roomDataSource) in
|
||||
guard let dataSource = roomDataSource else { return }
|
||||
let storyboard = UIStoryboard(name: "Main", bundle: nil)
|
||||
if let search = storyboard.instantiateViewController(withIdentifier: "RoomSearch") as? RoomSearchViewController {
|
||||
search.roomDataSource = dataSource
|
||||
self.navigationRouter.push(search, animated: animated, popCompletion: nil)
|
||||
}
|
||||
let roomSearchViewController: RoomSearchViewController = RoomSearchViewController.instantiate()
|
||||
roomSearchViewController.loadViewIfNeeded()
|
||||
roomSearchViewController.roomDataSource = dataSource
|
||||
self.navigationRouter.push(roomSearchViewController, animated: animated, popCompletion: nil)
|
||||
})
|
||||
case .notifications:
|
||||
let coordinator = createRoomNotificationSettingsCoordinator()
|
||||
|
|
|
@ -50,8 +50,8 @@ final class RoomInfoListViewController: UIViewController {
|
|||
|
||||
private lazy var basicInfoView: RoomInfoBasicView = {
|
||||
let view = RoomInfoBasicView.loadFromNib()
|
||||
view.onTopicSizeChange = { _ in
|
||||
self.view.setNeedsLayout()
|
||||
view.onTopicSizeChange = { [weak self] _ in
|
||||
self?.view.setNeedsLayout()
|
||||
}
|
||||
return view
|
||||
}()
|
||||
|
|
|
@ -144,7 +144,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
{
|
||||
|
||||
// The preview header
|
||||
PreviewRoomTitleView *previewHeader;
|
||||
__weak PreviewRoomTitleView *previewHeader;
|
||||
|
||||
// The customized room data source for Vector
|
||||
RoomDataSource *customizedRoomDataSource;
|
||||
|
@ -156,7 +156,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
NSArray *currentTypingUsers;
|
||||
|
||||
// Typing notifications listener.
|
||||
id typingNotifListener;
|
||||
__weak id typingNotifListener;
|
||||
|
||||
// The position of the first touch down event stored in case of scrolling when the expanded header is visible.
|
||||
CGPoint startScrollingPoint;
|
||||
|
@ -168,33 +168,33 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
UIView *missedDiscussionsDotView;
|
||||
|
||||
// Potential encryption details view.
|
||||
EncryptionInfoView *encryptionInfoView;
|
||||
__weak EncryptionInfoView *encryptionInfoView;
|
||||
|
||||
// The list of unknown devices that prevent outgoing messages from being sent
|
||||
MXUsersDevicesMap<MXDeviceInfo*> *unknownDevices;
|
||||
|
||||
// Observe kAppDelegateDidTapStatusBarNotification to handle tap on clock status bar.
|
||||
id kAppDelegateDidTapStatusBarNotificationObserver;
|
||||
__weak id kAppDelegateDidTapStatusBarNotificationObserver;
|
||||
|
||||
// Observe kAppDelegateNetworkStatusDidChangeNotification to handle network status change.
|
||||
id kAppDelegateNetworkStatusDidChangeNotificationObserver;
|
||||
__weak id kAppDelegateNetworkStatusDidChangeNotificationObserver;
|
||||
|
||||
// Observers to manage MXSession state (and sync errors)
|
||||
id kMXSessionStateDidChangeObserver;
|
||||
__weak id kMXSessionStateDidChangeObserver;
|
||||
|
||||
// Observers to manage ongoing conference call banner
|
||||
id kMXCallStateDidChangeObserver;
|
||||
id kMXCallManagerConferenceStartedObserver;
|
||||
id kMXCallManagerConferenceFinishedObserver;
|
||||
__weak id kMXCallStateDidChangeObserver;
|
||||
__weak id kMXCallManagerConferenceStartedObserver;
|
||||
__weak id kMXCallManagerConferenceFinishedObserver;
|
||||
|
||||
// Observers to manage widgets
|
||||
id kMXKWidgetManagerDidUpdateWidgetObserver;
|
||||
__weak id kMXKWidgetManagerDidUpdateWidgetObserver;
|
||||
|
||||
// Observer kMXRoomSummaryDidChangeNotification to keep updated the missed discussion count
|
||||
id mxRoomSummaryDidChangeObserver;
|
||||
__weak id mxRoomSummaryDidChangeObserver;
|
||||
|
||||
// Observer for removing the re-request explanation/waiting dialog
|
||||
id mxEventDidDecryptNotificationObserver;
|
||||
__weak id mxEventDidDecryptNotificationObserver;
|
||||
|
||||
// The table view cell in which the read marker is displayed (nil by default).
|
||||
MXKRoomBubbleTableViewCell *readMarkerTableViewCell;
|
||||
|
@ -209,13 +209,13 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
NSArray<UIBarButtonItem *> *rightBarButtonItems;
|
||||
|
||||
// Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change.
|
||||
id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
__weak id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
|
||||
// Observe URL preview updates to refresh cells.
|
||||
id URLPreviewDidUpdateNotificationObserver;
|
||||
__weak id URLPreviewDidUpdateNotificationObserver;
|
||||
|
||||
// Listener for `m.room.tombstone` event type
|
||||
id tombstoneEventNotificationsListener;
|
||||
__weak id tombstoneEventNotificationsListener;
|
||||
|
||||
// Homeserver notices
|
||||
MXServerNotices *serverNotices;
|
||||
|
@ -454,9 +454,13 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
self.jumpToLastUnreadLabel.text = [VectorL10n roomJumpToFirstUnread];
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Observe user interface theme change.
|
||||
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self userInterfaceThemeDidChange];
|
||||
|
||||
}];
|
||||
|
@ -587,9 +591,13 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
[self listenTombstoneEventNotifications];
|
||||
[self listenMXSessionStateChangeNotifications];
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Observe kAppDelegateDidTapStatusBarNotification.
|
||||
kAppDelegateDidTapStatusBarNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kAppDelegateDidTapStatusBarNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self setBubbleTableViewContentOffset:CGPointMake(-self.bubblesTableView.adjustedContentInset.left, -self.bubblesTableView.adjustedContentInset.top) animated:YES];
|
||||
}];
|
||||
|
||||
|
@ -661,9 +669,13 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
[AppDelegate theDelegate].visibleRoomId = self.roomDataSource.roomId;
|
||||
}
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Observe network reachability
|
||||
kAppDelegateNetworkStatusDidChangeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kAppDelegateNetworkStatusDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self refreshActivitiesViewDisplay];
|
||||
|
||||
}];
|
||||
|
@ -673,6 +685,8 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
// Observe missed notifications
|
||||
mxRoomSummaryDidChangeObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXRoomSummaryDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
MXRoomSummary *roomSummary = notif.object;
|
||||
|
||||
if ([roomSummary.roomId isEqualToString:self.roomDataSource.roomId])
|
||||
|
@ -1084,16 +1098,12 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
if (self.roomDataSource)
|
||||
{
|
||||
// Restore tool bar view and room activities view if none
|
||||
if (!self.inputToolbarView)
|
||||
{
|
||||
[self updateRoomInputToolbarViewClassIfNeeded];
|
||||
|
||||
[self refreshRoomInputToolbar];
|
||||
|
||||
self.inputToolbarView.hidden = (self.roomDataSource.state != MXKDataSourceStateReady);
|
||||
}
|
||||
// Update the input toolbar class and update the layout
|
||||
[self updateRoomInputToolbarViewClassIfNeeded];
|
||||
|
||||
self.inputToolbarView.hidden = (self.roomDataSource.state != MXKDataSourceStateReady);
|
||||
|
||||
// Restore room activities view if none
|
||||
if (!self.activitiesView)
|
||||
{
|
||||
// And the extra area
|
||||
|
@ -1178,6 +1188,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
}
|
||||
|
||||
[self updateInputToolBarViewHeight];
|
||||
[self refreshRoomInputToolbar];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1398,8 +1409,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
}
|
||||
if (URLPreviewDidUpdateNotificationObserver)
|
||||
{
|
||||
[NSNotificationCenter.defaultCenter removeObserver:URLPreviewDidUpdateNotificationObserver];
|
||||
URLPreviewDidUpdateNotificationObserver = nil;
|
||||
[NSNotificationCenter.defaultCenter removeObserver:URLPreviewDidUpdateNotificationObserver];
|
||||
}
|
||||
|
||||
[self removeCallNotificationsListeners];
|
||||
|
@ -1555,8 +1565,12 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
- (void)registerURLPreviewNotifications
|
||||
{
|
||||
MXWeakify(self);
|
||||
|
||||
URLPreviewDidUpdateNotificationObserver = [NSNotificationCenter.defaultCenter addObserverForName:URLPreviewDidUpdateNotification object:nil queue:NSOperationQueue.mainQueue usingBlock:^(NSNotification * _Nonnull notification) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
// Ensure this is the correct room
|
||||
if (![(NSString*)notification.userInfo[@"roomId"] isEqualToString:self.roomDataSource.roomId])
|
||||
{
|
||||
|
@ -2045,20 +2059,22 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
[VectorL10n widgetStickerPickerNoStickerpacksAlert],
|
||||
[VectorL10n widgetStickerPickerNoStickerpacksAlertAddNow]];
|
||||
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:nil message:alertMessage preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *installPrompt = [UIAlertController alertControllerWithTitle:nil
|
||||
message:alertMessage
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n no]
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction * action)
|
||||
[installPrompt addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n no]
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction * action)
|
||||
{
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
self->currentAlert = nil;
|
||||
|
||||
}]];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n yes]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action)
|
||||
[installPrompt addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n yes]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action)
|
||||
{
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
self->currentAlert = nil;
|
||||
|
@ -2073,8 +2089,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
[self presentViewController:modularVC animated:NO completion:nil];
|
||||
}]];
|
||||
|
||||
[currentAlert mxk_setAccessibilityIdentifier:@"RoomVCStickerPickerAlert"];
|
||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
[installPrompt mxk_setAccessibilityIdentifier:@"RoomVCStickerPickerAlert"];
|
||||
[self presentViewController:installPrompt animated:YES completion:nil];
|
||||
currentAlert = installPrompt;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2240,6 +2257,12 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
}
|
||||
|
||||
UIViewController *suggestionsViewController = self.userSuggestionCoordinator.toPresentable;
|
||||
|
||||
if (!suggestionsViewController)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
[suggestionsViewController.view setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
|
||||
[self addChildViewController:suggestionsViewController];
|
||||
|
@ -2336,11 +2359,14 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
if (isVisible)
|
||||
{
|
||||
previewHeader = [PreviewRoomTitleView roomTitleView];
|
||||
PreviewRoomTitleView *previewHeader = [PreviewRoomTitleView roomTitleView];
|
||||
previewHeader.delegate = self;
|
||||
previewHeader.tapGestureDelegate = self;
|
||||
previewHeader.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[self.previewHeaderContainer addSubview:previewHeader];
|
||||
|
||||
self->previewHeader = previewHeader;
|
||||
|
||||
// Force preview header in full width
|
||||
NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:previewHeader
|
||||
attribute:NSLayoutAttributeLeading
|
||||
|
@ -3119,14 +3145,14 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
}
|
||||
|
||||
__weak __typeof(self) weakSelf = self;
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
|
||||
UIAlertController *actionsMenu = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
|
||||
|
||||
// Add actions for a failed event
|
||||
if (selectedEvent.sentState == MXEventSentStateFailed)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n retry]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n retry]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3140,9 +3166,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionDelete]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionDelete]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3177,9 +3203,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
selectedEvent.sentState == MXEventSentStateEncrypting ||
|
||||
selectedEvent.sentState == MXEventSentStateSending)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionCancelSend]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action)
|
||||
[actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionCancelSend]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action)
|
||||
{
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3197,9 +3223,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
}]];
|
||||
}
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionForward]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionForward]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
self.shareManager = [[ShareManager alloc] initWithShareItemProvider:[[SimpleShareItemProvider alloc] initWithTextMessage:selectedComponent.textMessage]
|
||||
type:ShareManagerTypeForward];
|
||||
|
||||
|
@ -3216,9 +3242,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
if (!isJitsiCallEvent)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionQuote]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionQuote]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3238,9 +3264,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
if (!isJitsiCallEvent && BuildSettings.messageDetailsAllowShare)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionShare]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionShare]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3272,9 +3298,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
attachment.type == MXKAttachmentTypeVideo ||
|
||||
attachment.type == MXKAttachmentTypeVoiceMessage) {
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionForward]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionForward]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
self.shareManager = [[ShareManager alloc] initWithShareItemProvider:[[SimpleShareItemProvider alloc] initWithAttachment:attachment]
|
||||
type:ShareManagerTypeForward];
|
||||
|
||||
|
@ -3294,9 +3320,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
{
|
||||
if (attachment.type == MXKAttachmentTypeImage || attachment.type == MXKAttachmentTypeVideo)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionSave]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionSave]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3339,9 +3365,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
NSString *uploadId = roomBubbleTableViewCell.bubbleData.attachment.contentURL;
|
||||
if ([MXMediaManager existingUploaderWithId:uploadId])
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionCancelSend]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionCancelSend]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
// Get again the loader
|
||||
MXMediaLoader *loader = [MXMediaManager existingUploaderWithId:uploadId];
|
||||
|
@ -3377,9 +3403,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
{
|
||||
if (BuildSettings.messageDetailsAllowShare)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionShare]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionShare]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3427,9 +3453,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
NSString *downloadId = roomBubbleTableViewCell.bubbleData.attachment.downloadId;
|
||||
if ([MXMediaManager existingDownloaderWithIdentifier:downloadId])
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionCancelDownload]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionCancelDownload]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3455,9 +3481,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
// because it breaks everything
|
||||
if (selectedEvent.eventType != MXEventTypeRoomEncryption)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionRedact]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionRedact]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3489,9 +3515,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
if (BuildSettings.messageDetailsAllowPermalink)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionPermalink]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionPermalink]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3518,9 +3544,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
// Add reaction history if event contains reactions
|
||||
if (roomBubbleTableViewCell.bubbleData.reactions[selectedEvent.eventId].aggregatedReactionsWithNonZeroCount)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionReactionHistory]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionReactionHistory]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
[self cancelEventSelection];
|
||||
|
||||
|
@ -3531,9 +3557,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
if (BuildSettings.messageDetailsAllowViewSource)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionViewSource]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionViewSource]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3551,9 +3577,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
// Add "View Decrypted Source" for e2ee event we can decrypt
|
||||
if (selectedEvent.isEncrypted && selectedEvent.clearEvent)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionViewDecryptedSource]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionViewDecryptedSource]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3571,9 +3597,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
if (![selectedEvent.sender isEqualToString:self.mainSession.myUser.userId] && RiotSettings.shared.roomContextualMenuShowReportContentOption)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionReport]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionReport]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3582,15 +3608,15 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
[self cancelEventSelection];
|
||||
|
||||
// Prompt user to enter a description of the problem content.
|
||||
self->currentAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomEventActionReportPromptReason] message:nil preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *reportReasonAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomEventActionReportPromptReason] message:nil preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[self->currentAlert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
|
||||
[reportReasonAlert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
|
||||
textField.secureTextEntry = NO;
|
||||
textField.placeholder = nil;
|
||||
textField.keyboardType = UIKeyboardTypeDefault;
|
||||
}];
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
[reportReasonAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3606,9 +3632,11 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
[self stopActivityIndicator];
|
||||
|
||||
// Prompt user to ignore content from this user
|
||||
self->currentAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomEventActionReportPromptIgnoreUser] message:nil preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *ignoreUserAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomEventActionReportPromptIgnoreUser]
|
||||
message:nil
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n yes] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
[ignoreUserAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n yes] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3637,7 +3665,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
}]];
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n no] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
[ignoreUserAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n no] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3647,7 +3675,8 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
}]];
|
||||
|
||||
[self presentViewController:self->currentAlert animated:YES completion:nil];
|
||||
[self presentViewController:ignoreUserAlert animated:YES completion:nil];
|
||||
self->currentAlert = ignoreUserAlert;
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
|
@ -3663,7 +3692,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
}]];
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) {
|
||||
[reportReasonAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3673,7 +3702,8 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
}]];
|
||||
|
||||
[self presentViewController:self->currentAlert animated:YES completion:nil];
|
||||
[self presentViewController:reportReasonAlert animated:YES completion:nil];
|
||||
self->currentAlert = reportReasonAlert;
|
||||
}
|
||||
|
||||
}]];
|
||||
|
@ -3681,9 +3711,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
if (!isJitsiCallEvent && self.roomDataSource.room.summary.isEncrypted)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionViewEncryption]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionViewEncryption]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3698,9 +3728,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
}
|
||||
}
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n cancel]
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction * action) {
|
||||
[actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n cancel]
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3711,20 +3741,17 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
}]];
|
||||
|
||||
// Do not display empty action sheet
|
||||
if (currentAlert.actions.count > 1)
|
||||
if (actionsMenu.actions.count > 1)
|
||||
{
|
||||
NSInteger bubbleComponentIndex = [roomBubbleTableViewCell.bubbleData bubbleComponentIndexForEventId:selectedEvent.eventId];
|
||||
|
||||
CGRect sourceRect = [roomBubbleTableViewCell componentFrameInContentViewForIndex:bubbleComponentIndex];
|
||||
|
||||
[currentAlert mxk_setAccessibilityIdentifier:@"RoomVCEventMenuAlert"];
|
||||
[currentAlert popoverPresentationController].sourceView = roomBubbleTableViewCell;
|
||||
[currentAlert popoverPresentationController].sourceRect = sourceRect;
|
||||
[self presentViewController:currentAlert animated:animated completion:nil];
|
||||
}
|
||||
else
|
||||
{
|
||||
currentAlert = nil;
|
||||
[actionsMenu mxk_setAccessibilityIdentifier:@"RoomVCEventMenuAlert"];
|
||||
[actionsMenu popoverPresentationController].sourceView = roomBubbleTableViewCell;
|
||||
[actionsMenu popoverPresentationController].sourceRect = sourceRect;
|
||||
[self presentViewController:actionsMenu animated:animated completion:nil];
|
||||
currentAlert = actionsMenu;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4097,14 +4124,14 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
- (void)showVoiceCallActionSheet
|
||||
{
|
||||
// Ask the user the kind of the call: voice or dialpad?
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:nil
|
||||
message:nil
|
||||
preferredStyle:UIAlertControllerStyleActionSheet];
|
||||
UIAlertController *callActionSheet = [UIAlertController alertControllerWithTitle:nil
|
||||
message:nil
|
||||
preferredStyle:UIAlertControllerStyleActionSheet];
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomPlaceVoiceCall]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[callActionSheet addAction:[UIAlertAction actionWithTitle:[VectorL10n roomPlaceVoiceCall]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -4116,9 +4143,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomOpenDialpad]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[callActionSheet addAction:[UIAlertAction actionWithTitle:[VectorL10n roomOpenDialpad]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -4130,9 +4157,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel]
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction * action) {
|
||||
[callActionSheet addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel]
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -4142,9 +4169,10 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert popoverPresentationController].barButtonItem = self.navigationItem.rightBarButtonItems.firstObject;
|
||||
[currentAlert popoverPresentationController].permittedArrowDirections = UIPopoverArrowDirectionUp;
|
||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
[callActionSheet popoverPresentationController].barButtonItem = self.navigationItem.rightBarButtonItems.firstObject;
|
||||
[callActionSheet popoverPresentationController].permittedArrowDirections = UIPopoverArrowDirectionUp;
|
||||
[self presentViewController:callActionSheet animated:YES completion:nil];
|
||||
currentAlert = callActionSheet;
|
||||
}
|
||||
|
||||
- (void)placeCallWithVideo2:(BOOL)video
|
||||
|
@ -4196,20 +4224,21 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
MXWeakify(self);
|
||||
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomNoPrivilegesToCreateGroupCall]
|
||||
message:nil
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *unprivilegedAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomNoPrivilegesToCreateGroupCall]
|
||||
message:nil
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action)
|
||||
[unprivilegedAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action)
|
||||
{
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
self->currentAlert = nil;
|
||||
}]];
|
||||
|
||||
[currentAlert mxk_setAccessibilityIdentifier:@"RoomVCCallAlert"];
|
||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
[unprivilegedAlert mxk_setAccessibilityIdentifier:@"RoomVCCallAlert"];
|
||||
[self presentViewController:unprivilegedAlert animated:YES completion:nil];
|
||||
currentAlert = unprivilegedAlert;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4768,10 +4797,14 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
- (void)listenCallNotifications
|
||||
{
|
||||
MXWeakify(self);
|
||||
|
||||
kMXCallStateDidChangeObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXCallStateDidChange object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
MXCall *call = notif.object;
|
||||
if ([call.room.roomId isEqualToString:customizedRoomDataSource.roomId])
|
||||
if ([call.room.roomId isEqualToString:self->customizedRoomDataSource.roomId])
|
||||
{
|
||||
[self refreshActivitiesViewDisplay];
|
||||
[self refreshRoomInputToolbar];
|
||||
|
@ -4779,16 +4812,20 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
}];
|
||||
kMXCallManagerConferenceStartedObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXCallManagerConferenceStarted object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
NSString *roomId = notif.object;
|
||||
if ([roomId isEqualToString:customizedRoomDataSource.roomId])
|
||||
if ([roomId isEqualToString:self->customizedRoomDataSource.roomId])
|
||||
{
|
||||
[self refreshActivitiesViewDisplay];
|
||||
}
|
||||
}];
|
||||
kMXCallManagerConferenceFinishedObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXCallManagerConferenceFinished object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
NSString *roomId = notif.object;
|
||||
if ([roomId isEqualToString:customizedRoomDataSource.roomId])
|
||||
if ([roomId isEqualToString:self->customizedRoomDataSource.roomId])
|
||||
{
|
||||
[self refreshActivitiesViewDisplay];
|
||||
[self refreshRoomInputToolbar];
|
||||
|
@ -5129,6 +5166,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
[VectorL10n roomUnsentMessagesUnknownDevicesNotification] :
|
||||
[VectorL10n roomUnsentMessagesNotification];
|
||||
|
||||
MXWeakify(self);
|
||||
RoomActivitiesView *roomActivitiesView = (RoomActivitiesView*) self.activitiesView;
|
||||
self.activitiesViewExpanded = YES;
|
||||
[roomActivitiesView displayUnsentMessagesNotification:notification withResendLink:^{
|
||||
|
@ -5140,57 +5178,53 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
[self cancelAllUnsentMessages];
|
||||
|
||||
} andIconTapGesture:^{
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
if (currentAlert)
|
||||
if (self->currentAlert)
|
||||
{
|
||||
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
[self->currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
}
|
||||
|
||||
__weak __typeof(self) weakSelf = self;
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
|
||||
MXWeakify(self);
|
||||
UIAlertController *resendAlert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomResendUnsentMessages]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[resendAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomResendUnsentMessages]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
[self resendAllUnsentMessages];
|
||||
self->currentAlert = nil;
|
||||
}
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self resendAllUnsentMessages];
|
||||
self->currentAlert = nil;
|
||||
|
||||
}]];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomDeleteUnsentMessages]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[resendAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomDeleteUnsentMessages]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
[self cancelAllUnsentMessages];
|
||||
self->currentAlert = nil;
|
||||
}
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self cancelAllUnsentMessages];
|
||||
self->currentAlert = nil;
|
||||
|
||||
}]];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n cancel]
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction * action) {
|
||||
[resendAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n cancel]
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
self->currentAlert = nil;
|
||||
}
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
self->currentAlert = nil;
|
||||
|
||||
}]];
|
||||
|
||||
[currentAlert mxk_setAccessibilityIdentifier:@"RoomVCUnsentMessagesMenuAlert"];
|
||||
[currentAlert popoverPresentationController].sourceView = roomActivitiesView;
|
||||
[currentAlert popoverPresentationController].sourceRect = roomActivitiesView.bounds;
|
||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
[resendAlert mxk_setAccessibilityIdentifier:@"RoomVCUnsentMessagesMenuAlert"];
|
||||
[resendAlert popoverPresentationController].sourceView = roomActivitiesView;
|
||||
[resendAlert popoverPresentationController].sourceRect = roomActivitiesView.bounds;
|
||||
[self presentViewController:resendAlert animated:YES completion:nil];
|
||||
self->currentAlert = resendAlert;
|
||||
|
||||
}];
|
||||
}
|
||||
|
@ -5230,13 +5264,13 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
}
|
||||
}
|
||||
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:[VectorL10n unknownDevicesAlertTitle]
|
||||
message:[VectorL10n unknownDevicesAlert]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *unknownDevicesAlert = [UIAlertController alertControllerWithTitle:[VectorL10n unknownDevicesAlertTitle]
|
||||
message:[VectorL10n unknownDevicesAlert]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n unknownDevicesVerify]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[unknownDevicesAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n unknownDevicesVerify]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -5248,9 +5282,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n unknownDevicesSendAnyway]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[unknownDevicesAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n unknownDevicesSendAnyway]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -5271,8 +5305,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert mxk_setAccessibilityIdentifier:@"RoomVCUnknownDevicesAlert"];
|
||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
[unknownDevicesAlert mxk_setAccessibilityIdentifier:@"RoomVCUnknownDevicesAlert"];
|
||||
[self presentViewController:unknownDevicesAlert animated:YES completion:nil];
|
||||
currentAlert = unknownDevicesAlert;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5334,15 +5369,17 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
- (void)cancelAllUnsentMessages
|
||||
{
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomUnsentMessagesCancelTitle] message:[VectorL10n roomUnsentMessagesCancelMessage] preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *cancelAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomUnsentMessagesCancelTitle]
|
||||
message:[VectorL10n roomUnsentMessagesCancelMessage]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
MXWeakify(self);
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) {
|
||||
[cancelAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
self->currentAlert = nil;
|
||||
}]];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n delete] style:UIAlertActionStyleDestructive handler:^(UIAlertAction * action) {
|
||||
[cancelAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n delete] style:UIAlertActionStyleDestructive handler:^(UIAlertAction * action) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
// Remove unsent event ids
|
||||
for (NSUInteger index = 0; index < self.roomDataSource.room.outgoingMessages.count;)
|
||||
|
@ -5359,9 +5396,11 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
}
|
||||
|
||||
[self refreshActivitiesViewDisplay];
|
||||
self->currentAlert = nil;
|
||||
}]];
|
||||
|
||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
[self presentViewController:cancelAlert animated:YES completion:nil];
|
||||
currentAlert = cancelAlert;
|
||||
}
|
||||
|
||||
# pragma mark - Encryption Information view
|
||||
|
@ -5373,7 +5412,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
// Remove potential existing subviews
|
||||
[self dismissTemporarySubViews];
|
||||
|
||||
encryptionInfoView = [[EncryptionInfoView alloc] initWithEvent:event andMatrixSession:self.roomDataSource.mxSession];
|
||||
EncryptionInfoView *encryptionInfoView = [[EncryptionInfoView alloc] initWithEvent:event andMatrixSession:self.roomDataSource.mxSession];
|
||||
|
||||
// Add shadow on added view
|
||||
encryptionInfoView.layer.cornerRadius = 5;
|
||||
|
@ -5383,6 +5422,8 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
// Add the view and define edge constraints
|
||||
[self.view addSubview:encryptionInfoView];
|
||||
|
||||
self->encryptionInfoView = encryptionInfoView;
|
||||
|
||||
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:encryptionInfoView
|
||||
attribute:NSLayoutAttributeTop
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
|
@ -5588,11 +5629,11 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
// Invite ?
|
||||
NSString *promptMsg = [VectorL10n roomParticipantsInvitePromptMsg:contact.displayName];
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomParticipantsInvitePromptTitle]
|
||||
message:promptMsg
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *invitePrompt = [UIAlertController alertControllerWithTitle:[VectorL10n roomParticipantsInvitePromptTitle]
|
||||
message:promptMsg
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel]
|
||||
[invitePrompt addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel]
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
|
@ -5604,7 +5645,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n invite]
|
||||
[invitePrompt addAction:[UIAlertAction actionWithTitle:[VectorL10n invite]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
|
@ -5699,8 +5740,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert mxk_setAccessibilityIdentifier:@"RoomVCInviteAlert"];
|
||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
[invitePrompt mxk_setAccessibilityIdentifier:@"RoomVCInviteAlert"];
|
||||
[self presentViewController:invitePrompt animated:YES completion:nil];
|
||||
currentAlert = invitePrompt;
|
||||
}
|
||||
|
||||
#pragma mark - Re-request encryption keys
|
||||
|
@ -5744,8 +5786,6 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
alert = [UIAlertController alertControllerWithTitle:VectorL10n.rerequestKeysAlertTitle
|
||||
message:[VectorL10n e2eRoomKeyRequestMessage:AppInfo.current.displayName]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
currentAlert = alert;
|
||||
|
||||
|
||||
[alert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok]
|
||||
style:UIAlertActionStyleDefault
|
||||
|
@ -5759,7 +5799,8 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
self->currentAlert = nil;
|
||||
}]];
|
||||
|
||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
[self presentViewController:alert animated:YES completion:nil];
|
||||
currentAlert = alert;
|
||||
}
|
||||
|
||||
- (void)presentReviewUnverifiedSessionsAlert
|
||||
|
@ -5839,8 +5880,12 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
|
||||
- (void)listenMXSessionStateChangeNotifications
|
||||
{
|
||||
MXWeakify(self);
|
||||
|
||||
kMXSessionStateDidChangeObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionStateDidChangeNotification object:self.roomDataSource.mxSession queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
if (self.roomDataSource.mxSession.state == MXSessionStateSyncError
|
||||
|| self.roomDataSource.mxSession.state == MXSessionStateRunning)
|
||||
{
|
||||
|
@ -6029,18 +6074,19 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
|||
[self hideContextualMenuAnimated:YES cancelEventSelection:YES completion:^{
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
self->currentAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomEventActionDeleteConfirmationTitle]
|
||||
message:[VectorL10n roomEventActionDeleteConfirmationMessage]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *deleteConfirmation = [UIAlertController alertControllerWithTitle:[VectorL10n roomEventActionDeleteConfirmationTitle]
|
||||
message:[VectorL10n roomEventActionDeleteConfirmationMessage]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
[deleteConfirmation addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
}]];
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n delete] style:UIAlertActionStyleDestructive handler:^(UIAlertAction * action) {
|
||||
[deleteConfirmation addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n delete] style:UIAlertActionStyleDestructive handler:^(UIAlertAction * action) {
|
||||
[self.roomDataSource removeEventWithEventId:event.eventId];
|
||||
}]];
|
||||
|
||||
[self presentViewController:self->currentAlert animated:YES completion:nil];
|
||||
[self presentViewController:deleteConfirmation animated:YES completion:nil];
|
||||
self->currentAlert = deleteConfirmation;
|
||||
}];
|
||||
};
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@
|
|||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oni-F4-X1U" userLabel="User suggestion container">
|
||||
<rect key="frame" x="0.0" y="626" width="375" height="0.0"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" placeholder="YES" id="1Cd-cT-gOr"/>
|
||||
</constraints>
|
||||
|
|
|
@ -25,4 +25,6 @@
|
|||
*/
|
||||
@property (nonatomic) MXKRoomDataSource *roomDataSource;
|
||||
|
||||
+ (instancetype)instantiate;
|
||||
|
||||
@end
|
||||
|
|
|
@ -37,6 +37,13 @@
|
|||
|
||||
@implementation RoomSearchViewController
|
||||
|
||||
+ (instancetype)instantiate
|
||||
{
|
||||
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
|
||||
RoomSearchViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"RoomSearch"];
|
||||
return viewController;
|
||||
}
|
||||
|
||||
- (void)finalizeInit
|
||||
{
|
||||
[super finalizeInit];
|
||||
|
|
|
@ -14,26 +14,100 @@
|
|||
// limitations under the License.
|
||||
//
|
||||
|
||||
import GrowingTextView
|
||||
|
||||
@objc protocol RoomInputToolbarTextViewDelegate: AnyObject {
|
||||
func textView(_ textView: RoomInputToolbarTextView, didChangeHeight height: CGFloat)
|
||||
func textView(_ textView: RoomInputToolbarTextView, didReceivePasteForMediaFromSender sender: Any?)
|
||||
}
|
||||
|
||||
class RoomInputToolbarTextView: GrowingTextView {
|
||||
@objcMembers
|
||||
class RoomInputToolbarTextView: UITextView {
|
||||
|
||||
@objc weak var toolbarDelegate: RoomInputToolbarTextViewDelegate?
|
||||
|
||||
override var keyCommands: [UIKeyCommand]? {
|
||||
return [UIKeyCommand(input: "\r", modifierFlags: [], action: #selector(keyCommandSelector(_:)))]
|
||||
private var heightConstraint: NSLayoutConstraint!
|
||||
|
||||
weak var toolbarDelegate: RoomInputToolbarTextViewDelegate?
|
||||
|
||||
var placeholder: String? {
|
||||
didSet {
|
||||
setNeedsDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func keyCommandSelector(_ keyCommand: UIKeyCommand) {
|
||||
guard keyCommand.input == "\r", let delegate = (self.delegate as? RoomInputToolbarView) else {
|
||||
var placeholderColor: UIColor = UIColor(white: 0.8, alpha: 1.0) {
|
||||
didSet {
|
||||
setNeedsDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
var minHeight: CGFloat = 30.0 {
|
||||
didSet {
|
||||
updateUI()
|
||||
}
|
||||
}
|
||||
|
||||
var maxHeight: CGFloat = 0.0 {
|
||||
didSet {
|
||||
updateUI()
|
||||
}
|
||||
}
|
||||
|
||||
override var text: String! {
|
||||
didSet {
|
||||
updateUI()
|
||||
}
|
||||
}
|
||||
|
||||
override init(frame: CGRect, textContainer: NSTextContainer?) {
|
||||
super.init(frame: frame, textContainer: textContainer)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
private func commonInit() {
|
||||
contentMode = .redraw
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(textDidChange), name: UITextView.textDidChangeNotification, object: self)
|
||||
|
||||
if let heightConstraint = constraints.filter({ $0.firstAttribute == .height && $0.relation == .equal }).first {
|
||||
self.heightConstraint = heightConstraint
|
||||
} else {
|
||||
heightConstraint = self.heightAnchor.constraint(equalToConstant: minHeight)
|
||||
addConstraint(heightConstraint)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Overrides
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
updateUI()
|
||||
}
|
||||
|
||||
override func draw(_ rect: CGRect) {
|
||||
super.draw(rect)
|
||||
|
||||
guard text.isEmpty, let placeholder = placeholder else {
|
||||
return
|
||||
}
|
||||
|
||||
delegate.onTouchUp(inside: delegate.rightInputToolbarButton)
|
||||
var attributes: [NSAttributedString.Key: Any] = [.foregroundColor: placeholderColor]
|
||||
if let font = font {
|
||||
attributes[.font] = font
|
||||
}
|
||||
|
||||
let frame = rect.inset(by: .init(top: textContainerInset.top,
|
||||
left: textContainerInset.left + textContainer.lineFragmentPadding,
|
||||
bottom: textContainerInset.bottom,
|
||||
right: textContainerInset.right))
|
||||
|
||||
placeholder.draw(in: frame, withAttributes: attributes)
|
||||
}
|
||||
|
||||
override var keyCommands: [UIKeyCommand]? {
|
||||
return [UIKeyCommand(input: "\r", modifierFlags: [], action: #selector(keyCommandSelector(_:)))]
|
||||
}
|
||||
|
||||
/// Overrides paste to handle images pasted from Safari, passing them up to the input toolbar.
|
||||
|
@ -49,4 +123,36 @@ class RoomInputToolbarTextView: GrowingTextView {
|
|||
super.paste(sender)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
@objc private func textDidChange(notification: Notification) {
|
||||
if let sender = notification.object as? RoomInputToolbarTextView, sender == self {
|
||||
updateUI()
|
||||
}
|
||||
}
|
||||
|
||||
private func updateUI() {
|
||||
var height = sizeThatFits(CGSize(width: bounds.size.width, height: CGFloat.greatestFiniteMagnitude)).height
|
||||
height = minHeight > 0 ? max(height, minHeight) : height
|
||||
height = maxHeight > 0 ? min(height, maxHeight) : height
|
||||
|
||||
// Update placeholder
|
||||
self.setNeedsDisplay()
|
||||
|
||||
guard height != heightConstraint.constant else {
|
||||
return
|
||||
}
|
||||
|
||||
heightConstraint.constant = height
|
||||
toolbarDelegate?.textView(self, didChangeHeight: height)
|
||||
}
|
||||
|
||||
@objc private func keyCommandSelector(_ keyCommand: UIKeyCommand) {
|
||||
guard keyCommand.input == "\r", let delegate = (self.delegate as? RoomInputToolbarView) else {
|
||||
return
|
||||
}
|
||||
|
||||
delegate.onTouchUp(inside: delegate.rightInputToolbarButton)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,28 +60,10 @@ typedef enum : NSUInteger
|
|||
*/
|
||||
@property (nonatomic, weak) id<RoomInputToolbarViewDelegate> delegate;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIView *mainToolbarView;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *mainToolbarMinHeightConstraint;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *mainToolbarHeightConstraint;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *messageComposerContainerTrailingConstraint;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIButton *attachMediaButton;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIImageView *inputTextBackgroundView;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *inputContextViewHeightConstraint;
|
||||
@property (weak, nonatomic) IBOutlet UIImageView *inputContextImageView;
|
||||
@property (weak, nonatomic) IBOutlet UILabel *inputContextLabel;
|
||||
@property (weak, nonatomic) IBOutlet UIButton *inputContextButton;
|
||||
@property (weak, nonatomic) IBOutlet RoomActionsBar *actionsBar;
|
||||
@property (weak, nonatomic) UIView *voiceMessageToolbarView;
|
||||
|
||||
/**
|
||||
Tell whether the filled data will be sent encrypted. NO by default.
|
||||
*/
|
||||
@property (nonatomic) BOOL isEncryptionEnabled;
|
||||
@property (nonatomic, assign) BOOL isEncryptionEnabled;
|
||||
|
||||
/**
|
||||
Sender of the event being edited / replied.
|
||||
|
@ -91,11 +73,31 @@ typedef enum : NSUInteger
|
|||
/**
|
||||
Destination of the message in the composer.
|
||||
*/
|
||||
@property (nonatomic) RoomInputToolbarViewSendMode sendMode;
|
||||
@property (nonatomic, assign) RoomInputToolbarViewSendMode sendMode;
|
||||
|
||||
/**
|
||||
YES if action menu is opened. NO otherwise
|
||||
*/
|
||||
@property (nonatomic, getter=isActionMenuOpened) BOOL actionMenuOpened;
|
||||
@property (nonatomic, assign) BOOL actionMenuOpened;
|
||||
|
||||
/**
|
||||
The input toolbar's main height constraint
|
||||
*/
|
||||
@property (nonatomic, weak, readonly) NSLayoutConstraint *mainToolbarHeightConstraint;
|
||||
|
||||
/**
|
||||
The input toolbar's action bar
|
||||
*/
|
||||
@property (nonatomic, weak, readonly) RoomActionsBar *actionsBar;
|
||||
|
||||
/**
|
||||
The attach media button
|
||||
*/
|
||||
@property (nonatomic, weak, readonly) UIButton *attachMediaButton;
|
||||
|
||||
/**
|
||||
Adds a voice message toolbar view to be displayed inside this input toolbar
|
||||
*/
|
||||
- (void)setVoiceMessageToolbarView:(UIView *)toolbarView;
|
||||
|
||||
@end
|
||||
|
|
|
@ -17,34 +17,40 @@
|
|||
|
||||
#import "RoomInputToolbarView.h"
|
||||
|
||||
#import "ThemeService.h"
|
||||
#import "Riot-Swift.h"
|
||||
|
||||
#import "GBDeviceInfo_iOS.h"
|
||||
|
||||
#import "UINavigationController+Riot.h"
|
||||
static const CGFloat kContextBarHeight = 24;
|
||||
static const CGFloat kActionMenuAttachButtonSpringVelocity = 7;
|
||||
static const CGFloat kActionMenuAttachButtonSpringDamping = .45;
|
||||
|
||||
#import "WidgetManager.h"
|
||||
#import "IntegrationManagerViewController.h"
|
||||
static const NSTimeInterval kSendModeAnimationDuration = .15;
|
||||
static const NSTimeInterval kActionMenuAttachButtonAnimationDuration = .4;
|
||||
static const NSTimeInterval kActionMenuContentAlphaAnimationDuration = .2;
|
||||
static const NSTimeInterval kActionMenuComposerHeightAnimationDuration = .3;
|
||||
|
||||
@import GrowingTextView;
|
||||
@interface RoomInputToolbarView() <UITextViewDelegate, RoomInputToolbarTextViewDelegate>
|
||||
|
||||
const double kContextBarHeight = 24;
|
||||
const NSTimeInterval kSendModeAnimationDuration = .15;
|
||||
const NSTimeInterval kActionMenuAttachButtonAnimationDuration = .4;
|
||||
const CGFloat kActionMenuAttachButtonSpringVelocity = 7;
|
||||
const CGFloat kActionMenuAttachButtonSpringDamping = .45;
|
||||
const NSTimeInterval kActionMenuContentAlphaAnimationDuration = .2;
|
||||
const NSTimeInterval kActionMenuComposerHeightAnimationDuration = .3;
|
||||
const CGFloat kComposerContainerTrailingPadding = 12;
|
||||
@property (nonatomic, weak) IBOutlet UIView *mainToolbarView;
|
||||
|
||||
@interface RoomInputToolbarView() <GrowingTextViewDelegate, RoomInputToolbarTextViewDelegate>
|
||||
{
|
||||
// The intermediate action sheet
|
||||
UIAlertController *actionSheet;
|
||||
}
|
||||
@property (nonatomic, weak) IBOutlet UIButton *attachMediaButton;
|
||||
|
||||
@property (nonatomic, weak) IBOutlet RoomInputToolbarTextView *textView;
|
||||
@property (nonatomic, weak) IBOutlet UIImageView *inputTextBackgroundView;
|
||||
|
||||
@property (nonatomic, weak) IBOutlet UIImageView *inputContextImageView;
|
||||
@property (nonatomic, weak) IBOutlet UILabel *inputContextLabel;
|
||||
@property (nonatomic, weak) IBOutlet UIButton *inputContextButton;
|
||||
|
||||
@property (nonatomic, weak) IBOutlet RoomActionsBar *actionsBar;
|
||||
|
||||
@property (nonatomic, weak) IBOutlet NSLayoutConstraint *mainToolbarMinHeightConstraint;
|
||||
@property (nonatomic, weak) IBOutlet NSLayoutConstraint *mainToolbarHeightConstraint;
|
||||
@property (nonatomic, weak) IBOutlet NSLayoutConstraint *messageComposerContainerTrailingConstraint;
|
||||
@property (nonatomic, weak) IBOutlet NSLayoutConstraint *inputContextViewHeightConstraint;
|
||||
|
||||
@property (nonatomic, weak) UIView *voiceMessageToolbarView;
|
||||
|
||||
@property (nonatomic, assign) CGFloat expandedMainToolbarHeight;
|
||||
|
||||
@end
|
||||
|
@ -52,22 +58,10 @@ const CGFloat kComposerContainerTrailingPadding = 12;
|
|||
@implementation RoomInputToolbarView
|
||||
@dynamic delegate;
|
||||
|
||||
+ (UINib *)nib
|
||||
{
|
||||
return [UINib nibWithNibName:NSStringFromClass([RoomInputToolbarView class])
|
||||
bundle:[NSBundle bundleForClass:[RoomInputToolbarView class]]];
|
||||
}
|
||||
|
||||
+ (instancetype)roomInputToolbarView
|
||||
{
|
||||
if ([[self class] nib])
|
||||
{
|
||||
return [[[self class] nib] instantiateWithOwner:nil options:nil].firstObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
return [[self alloc] init];
|
||||
}
|
||||
UINib *nib = [UINib nibWithNibName:NSStringFromClass([RoomInputToolbarView class]) bundle:nil];
|
||||
return [nib instantiateWithOwner:nil options:nil].firstObject;
|
||||
}
|
||||
|
||||
- (void)awakeFromNib
|
||||
|
@ -85,6 +79,10 @@ const CGFloat kComposerContainerTrailingPadding = 12;
|
|||
[self updateUIWithTextMessage:nil animated:NO];
|
||||
|
||||
self.textView.toolbarDelegate = self;
|
||||
|
||||
// Add an accessory view to the text view in order to retrieve keyboard view.
|
||||
inputAccessoryView = [[UIView alloc] initWithFrame:CGRectZero];
|
||||
self.textView.inputAccessoryView = inputAccessoryView;
|
||||
}
|
||||
|
||||
- (void)setVoiceMessageToolbarView:(UIView *)voiceMessageToolbarView
|
||||
|
@ -311,6 +309,11 @@ const CGFloat kComposerContainerTrailingPadding = 12;
|
|||
self.textView.placeholder = inPlaceholder;
|
||||
}
|
||||
|
||||
- (void)pasteText:(NSString *)text
|
||||
{
|
||||
self.textMessage = [self.textView.text stringByReplacingCharactersInRange:self.textView.selectedRange withString:text];
|
||||
}
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (IBAction)cancelAction:(id)sender
|
||||
|
@ -321,7 +324,7 @@ const CGFloat kComposerContainerTrailingPadding = 12;
|
|||
}
|
||||
}
|
||||
|
||||
#pragma mark - GrowingTextViewDelegate
|
||||
#pragma mark - UITextViewDelegate
|
||||
|
||||
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
|
||||
{
|
||||
|
@ -347,7 +350,9 @@ const CGFloat kComposerContainerTrailingPadding = 12;
|
|||
[self.delegate roomInputToolbarViewDidChangeTextMessage:self];
|
||||
}
|
||||
|
||||
- (void)textViewDidChangeHeight:(GrowingTextView *)textView height:(CGFloat)height
|
||||
#pragma mark - RoomInputToolbarTextViewDelegate
|
||||
|
||||
- (void)textView:(RoomInputToolbarTextView *)textView didChangeHeight:(CGFloat)height
|
||||
{
|
||||
// Update height of the main toolbar (message composer)
|
||||
CGFloat updatedHeight = height + (self.messageComposerContainerTopConstraint.constant + self.messageComposerContainerBottomConstraint.constant) + self.inputContextViewHeightConstraint.constant;
|
||||
|
@ -372,13 +377,18 @@ const CGFloat kComposerContainerTrailingPadding = 12;
|
|||
}
|
||||
}
|
||||
|
||||
- (void)textView:(RoomInputToolbarTextView *)textView didReceivePasteForMediaFromSender:(id)sender
|
||||
{
|
||||
[self paste:sender];
|
||||
}
|
||||
|
||||
#pragma mark - Override MXKRoomInputToolbarView
|
||||
|
||||
- (IBAction)onTouchUpInside:(UIButton*)button
|
||||
{
|
||||
if (button == self.attachMediaButton)
|
||||
{
|
||||
self.actionMenuOpened = !self.isActionMenuOpened;
|
||||
self.actionMenuOpened = !self.actionMenuOpened;
|
||||
}
|
||||
|
||||
[super onTouchUpInside:button];
|
||||
|
@ -396,12 +406,6 @@ const CGFloat kComposerContainerTrailingPadding = 12;
|
|||
|
||||
- (void)destroy
|
||||
{
|
||||
if (actionSheet)
|
||||
{
|
||||
[actionSheet dismissViewControllerAnimated:NO completion:nil];
|
||||
actionSheet = nil;
|
||||
}
|
||||
|
||||
[super destroy];
|
||||
}
|
||||
|
||||
|
@ -458,20 +462,6 @@ const CGFloat kComposerContainerTrailingPadding = 12;
|
|||
}
|
||||
}
|
||||
|
||||
#pragma mark - Clipboard - Handle image/data paste from general pasteboard
|
||||
|
||||
- (void)paste:(id)sender
|
||||
{
|
||||
// TODO Custom here the validation screen for each available item
|
||||
|
||||
[super paste:sender];
|
||||
}
|
||||
|
||||
- (void)textView:(GrowingTextView *)textView didReceivePasteForMediaFromSender:(id)sender
|
||||
{
|
||||
[self paste:sender];
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (void)updateUIWithTextMessage:(NSString *)textMessage animated:(BOOL)animated
|
||||
|
|
|
@ -178,16 +178,16 @@ ServiceTermsModalCoordinatorBridgePresenterDelegate,
|
|||
TableViewSectionsDelegate>
|
||||
{
|
||||
// Current alert (if any).
|
||||
UIAlertController *currentAlert;
|
||||
__weak UIAlertController *currentAlert;
|
||||
|
||||
// listener
|
||||
id removedAccountObserver;
|
||||
id accountUserInfoObserver;
|
||||
id pushInfoUpdateObserver;
|
||||
__weak id removedAccountObserver;
|
||||
__weak id accountUserInfoObserver;
|
||||
__weak id pushInfoUpdateObserver;
|
||||
|
||||
id notificationCenterWillUpdateObserver;
|
||||
id notificationCenterDidUpdateObserver;
|
||||
id notificationCenterDidFailObserver;
|
||||
__weak id notificationCenterWillUpdateObserver;
|
||||
__weak id notificationCenterDidUpdateObserver;
|
||||
__weak id notificationCenterDidFailObserver;
|
||||
|
||||
// profile updates
|
||||
// avatar
|
||||
|
@ -216,10 +216,10 @@ TableViewSectionsDelegate>
|
|||
GroupsDataSource *groupsDataSource;
|
||||
|
||||
// Observe kAppDelegateDidTapStatusBarNotification to handle tap on clock status bar.
|
||||
id kAppDelegateDidTapStatusBarNotificationObserver;
|
||||
__weak id kAppDelegateDidTapStatusBarNotificationObserver;
|
||||
|
||||
// Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change.
|
||||
id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
__weak id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
|
||||
// Postpone destroy operation when saving, pwd reset or email binding is in progress
|
||||
BOOL isSavingInProgress;
|
||||
|
@ -541,13 +541,8 @@ TableViewSectionsDelegate>
|
|||
sectionAbout.headerTitle = VectorL10n.settingsAbout;
|
||||
|
||||
if (BuildSettings.settingsScreenShowAdvancedSettings)
|
||||
{
|
||||
sectionAbout.footerTitle = [NSString stringWithFormat:@"Element %@ (%@) / Olm %@\n%@\n%@",
|
||||
AppInfo.current.appVersion.bundleShortVersion,
|
||||
AppInfo.current.appVersion.bundleVersion,
|
||||
[OLMKit versionString],
|
||||
[MatrixKitL10n settingsConfigUserId:account.mxCredentials.userId],
|
||||
[MatrixKitL10n settingsConfigHomeServer:account.mxCredentials.homeServer]];
|
||||
{
|
||||
sectionAbout.footerTitle = [self buildAboutSectionFooterTitleWithAccount:account];
|
||||
}
|
||||
|
||||
[tmpSections addObject:sectionAbout];
|
||||
|
@ -612,9 +607,13 @@ TableViewSectionsDelegate>
|
|||
self.tableView.sectionFooterHeight = UITableViewAutomaticDimension;
|
||||
self.tableView.estimatedSectionFooterHeight = 50;
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Add observer to handle removed accounts
|
||||
removedAccountObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXKAccountManagerDidRemoveAccountNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
if ([MXKAccountManager sharedManager].accounts.count)
|
||||
{
|
||||
// Refresh table to remove this account
|
||||
|
@ -626,6 +625,8 @@ TableViewSectionsDelegate>
|
|||
// Add observer to handle accounts update
|
||||
accountUserInfoObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXKAccountUserInfoDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self stopActivityIndicator];
|
||||
|
||||
[self refreshSettings];
|
||||
|
@ -635,6 +636,8 @@ TableViewSectionsDelegate>
|
|||
// Add observer to push settings
|
||||
pushInfoUpdateObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXKAccountAPNSActivityDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self stopActivityIndicator];
|
||||
|
||||
[self refreshSettings];
|
||||
|
@ -663,6 +666,8 @@ TableViewSectionsDelegate>
|
|||
// Observe user interface theme change.
|
||||
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self userInterfaceThemeDidChange];
|
||||
|
||||
}];
|
||||
|
@ -777,10 +782,14 @@ TableViewSectionsDelegate>
|
|||
|
||||
// Refresh linked emails and phone numbers in parallel
|
||||
[self loadAccount3PIDs];
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Observe kAppDelegateDidTapStatusBarNotificationObserver.
|
||||
kAppDelegateDidTapStatusBarNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kAppDelegateDidTapStatusBarNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self.tableView setContentOffset:CGPointMake(-self.tableView.adjustedContentInset.left, -self.tableView.adjustedContentInset.top) animated:YES];
|
||||
|
||||
}];
|
||||
|
@ -977,9 +986,11 @@ TableViewSectionsDelegate>
|
|||
{
|
||||
MXWeakify(self);
|
||||
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n accountEmailValidationTitle] message:message preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *validationAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n accountEmailValidationTitle]
|
||||
message:message
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
[validationAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
self->currentAlert = nil;
|
||||
[self stopActivityIndicator];
|
||||
|
@ -988,14 +999,15 @@ TableViewSectionsDelegate>
|
|||
self.newEmailEditingEnabled = NO;
|
||||
}]];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n continue] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
[validationAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n continue] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
[self tryFinaliseAddEmailSession:threePidAddSession withAuthenticationParameters:authenticationParameters
|
||||
threePidAddManager:threePidAddManager];
|
||||
}]];
|
||||
|
||||
[currentAlert mxk_setAccessibilityIdentifier:@"SettingsVCEmailValidationAlert"];
|
||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
[validationAlert mxk_setAccessibilityIdentifier:@"SettingsVCEmailValidationAlert"];
|
||||
[self presentViewController:validationAlert animated:YES completion:nil];
|
||||
currentAlert = validationAlert;
|
||||
}
|
||||
|
||||
- (void)tryFinaliseAddEmailSession:(MX3PidAddSession*)threePidAddSession withAuthenticationParameters:(NSDictionary*)authParams threePidAddManager:(MX3PidAddManager*)threePidAddManager
|
||||
|
@ -1035,11 +1047,13 @@ TableViewSectionsDelegate>
|
|||
MXLogDebug(@"[SettingsViewController] tryFinaliseAddEmailSession: Wrong credentials");
|
||||
|
||||
// Ask password again
|
||||
self->currentAlert = [UIAlertController alertControllerWithTitle:nil
|
||||
message:[VectorL10n settingsAdd3pidInvalidPasswordMessage]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *passwordPrompt = [UIAlertController alertControllerWithTitle:nil
|
||||
message:[VectorL10n settingsAdd3pidInvalidPasswordMessage]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n retry] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
MXWeakify(self);
|
||||
[passwordPrompt addAction:[UIAlertAction actionWithTitle:[VectorL10n retry] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
self->currentAlert = nil;
|
||||
|
||||
[self showAuthenticationIfNeededForAdding:kMX3PIDMediumEmail withSession:self.mainSession completion:^(NSDictionary *authParams) {
|
||||
|
@ -1047,7 +1061,8 @@ TableViewSectionsDelegate>
|
|||
}];
|
||||
}]];
|
||||
|
||||
[self presentViewController:self->currentAlert animated:YES completion:nil];
|
||||
[self presentViewController:passwordPrompt animated:YES completion:nil];
|
||||
self->currentAlert = passwordPrompt;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1088,9 +1103,11 @@ TableViewSectionsDelegate>
|
|||
MXWeakify(self);
|
||||
|
||||
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n accountMsisdnValidationTitle] message:message preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *validationAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n accountMsisdnValidationTitle]
|
||||
message:message
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
[validationAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
self->currentAlert = nil;
|
||||
|
@ -1101,13 +1118,13 @@ TableViewSectionsDelegate>
|
|||
self.newPhoneEditingEnabled = NO;
|
||||
}]];
|
||||
|
||||
[currentAlert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
|
||||
[validationAlert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
|
||||
textField.secureTextEntry = NO;
|
||||
textField.placeholder = nil;
|
||||
textField.keyboardType = UIKeyboardTypeDecimalPad;
|
||||
}];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n submit] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
[validationAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n submit] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
|
@ -1126,8 +1143,9 @@ TableViewSectionsDelegate>
|
|||
}
|
||||
}]];
|
||||
|
||||
[currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCMsisdnValidationAlert"];
|
||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
[validationAlert mxk_setAccessibilityIdentifier: @"SettingsVCMsisdnValidationAlert"];
|
||||
[self presentViewController:validationAlert animated:YES completion:nil];
|
||||
currentAlert = validationAlert;
|
||||
}
|
||||
|
||||
- (void)finaliseAddPhoneNumberSession:(MX3PidAddSession*)threePidAddSession withToken:(NSString*)token andAuthenticationParameters:(NSDictionary*)authParams message:(NSString*)message threePidAddManager:(MX3PidAddManager*)threePidAddManager
|
||||
|
@ -1166,11 +1184,13 @@ TableViewSectionsDelegate>
|
|||
MXLogDebug(@"[SettingsViewController] finaliseAddPhoneNumberSession: Wrong authentication credentials");
|
||||
|
||||
// Ask password again
|
||||
self->currentAlert = [UIAlertController alertControllerWithTitle:nil
|
||||
message:[VectorL10n settingsAdd3pidInvalidPasswordMessage]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *passwordPrompt = [UIAlertController alertControllerWithTitle:nil
|
||||
message:[VectorL10n settingsAdd3pidInvalidPasswordMessage]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n retry] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
MXWeakify(self);
|
||||
[passwordPrompt addAction:[UIAlertAction actionWithTitle:[VectorL10n retry] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
self->currentAlert = nil;
|
||||
|
||||
[self showAuthenticationIfNeededForAdding:kMX3PIDMediumMSISDN withSession:self.mainSession completion:^(NSDictionary *authParams) {
|
||||
|
@ -1178,7 +1198,8 @@ TableViewSectionsDelegate>
|
|||
}];
|
||||
}]];
|
||||
|
||||
[self presentViewController:self->currentAlert animated:YES completion:nil];
|
||||
[self presentViewController:passwordPrompt animated:YES completion:nil];
|
||||
self->currentAlert = passwordPrompt;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1218,17 +1239,20 @@ TableViewSectionsDelegate>
|
|||
}
|
||||
|
||||
|
||||
self->currentAlert = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *errorAlert = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
MXWeakify(self);
|
||||
[errorAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
self->currentAlert = nil;
|
||||
|
||||
// Ask again the sms token
|
||||
[self showValidationMsisdnDialogWithMessage:message for3PidAddSession:threePidAddSession threePidAddManager:threePidAddManager authenticationParameters:authParams];
|
||||
}]];
|
||||
|
||||
[self->currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCErrorAlert"];
|
||||
[self presentViewController:self->currentAlert animated:YES completion:nil];
|
||||
[errorAlert mxk_setAccessibilityIdentifier: @"SettingsVCErrorAlert"];
|
||||
[self presentViewController:errorAlert animated:YES completion:nil];
|
||||
self->currentAlert = errorAlert;
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
@ -1396,6 +1420,35 @@ TableViewSectionsDelegate>
|
|||
}
|
||||
}
|
||||
|
||||
- (NSString*)buildAboutSectionFooterTitleWithAccount:(MXKAccount*)account
|
||||
{
|
||||
NSMutableString *footerText = [NSMutableString new];
|
||||
|
||||
AppInfo *appInfo = AppInfo.current;
|
||||
|
||||
NSString *appName = appInfo.displayName;
|
||||
NSString *appVersion = appInfo.appVersion.bundleShortVersion;
|
||||
NSString *buildVersion = appInfo.appVersion.bundleVersion;
|
||||
|
||||
NSString *appVersionInfo = [NSString stringWithFormat:@"%@ %@ (%@)", appName, appVersion, buildVersion];
|
||||
|
||||
NSString *loggedUserInfo = [MatrixKitL10n settingsConfigUserId:account.mxCredentials.userId];
|
||||
|
||||
NSString *homeserverInfo = [MatrixKitL10n settingsConfigHomeServer:account.mxCredentials.homeServer];
|
||||
|
||||
NSString *sdkVersionInfo = [NSString stringWithFormat:@"Matrix SDK %@", MatrixSDKVersion];
|
||||
|
||||
NSString *olmVersionInfo = [NSString stringWithFormat:@"OLM %@", [OLMKit versionString]];
|
||||
|
||||
[footerText appendFormat:@"%@\n", loggedUserInfo];
|
||||
[footerText appendFormat:@"%@\n", homeserverInfo];
|
||||
[footerText appendFormat:@"%@\n", appVersionInfo];
|
||||
[footerText appendFormat:@"%@\n", sdkVersionInfo];
|
||||
[footerText appendFormat:@"%@", olmVersionInfo];
|
||||
|
||||
return [footerText copy];
|
||||
}
|
||||
|
||||
#pragma mark - 3Pid Add
|
||||
|
||||
- (void)showAuthenticationIfNeededForAdding:(MX3PIDMedium)medium withSession:(MXSession*)session completion:(void (^)(NSDictionary* authParams))completion
|
||||
|
@ -2592,11 +2645,11 @@ TableViewSectionsDelegate>
|
|||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:[VectorL10n settingsUnignoreUser:ignoredUserId] message:nil preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *unignorePrompt = [UIAlertController alertControllerWithTitle:[VectorL10n settingsUnignoreUser:ignoredUserId] message:nil preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n yes]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[unignorePrompt addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n yes]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -2625,9 +2678,9 @@ TableViewSectionsDelegate>
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n no]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[unignorePrompt addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n no]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -2637,8 +2690,9 @@ TableViewSectionsDelegate>
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCUnignoreAlert"];
|
||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
[unignorePrompt mxk_setAccessibilityIdentifier: @"SettingsVCUnignoreAlert"];
|
||||
[self presentViewController:unignorePrompt animated:YES completion:nil];
|
||||
currentAlert = unignorePrompt;
|
||||
}
|
||||
}
|
||||
else if (section == SECTION_TAG_ABOUT)
|
||||
|
@ -2824,9 +2878,9 @@ TableViewSectionsDelegate>
|
|||
}
|
||||
|
||||
// Remove ?
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:[VectorL10n settingsRemovePromptTitle] message:promptMsg preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *removePrompt = [UIAlertController alertControllerWithTitle:[VectorL10n settingsRemovePromptTitle] message:promptMsg preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel]
|
||||
[removePrompt addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel]
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
|
@ -2838,7 +2892,7 @@ TableViewSectionsDelegate>
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n remove]
|
||||
[removePrompt addAction:[UIAlertAction actionWithTitle:[VectorL10n remove]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
|
@ -2878,8 +2932,9 @@ TableViewSectionsDelegate>
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCRemove3PIDAlert"];
|
||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
[removePrompt mxk_setAccessibilityIdentifier: @"SettingsVCRemove3PIDAlert"];
|
||||
[self presentViewController:removePrompt animated:YES completion:nil];
|
||||
currentAlert = removePrompt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2901,9 +2956,9 @@ TableViewSectionsDelegate>
|
|||
NSString *title = [VectorL10n settingsNotificationsDisabledAlertTitle];
|
||||
NSString *message = [VectorL10n settingsNotificationsDisabledAlertMessage];
|
||||
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *showSettingsPrompt = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel]
|
||||
[showSettingsPrompt addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel]
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
|
@ -2927,13 +2982,14 @@ TableViewSectionsDelegate>
|
|||
}
|
||||
}];
|
||||
|
||||
[currentAlert addAction:settingsAction];
|
||||
currentAlert.preferredAction = settingsAction;
|
||||
[showSettingsPrompt addAction:settingsAction];
|
||||
showSettingsPrompt.preferredAction = settingsAction;
|
||||
|
||||
[currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCPushNotificationsAlert"];
|
||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
[showSettingsPrompt mxk_setAccessibilityIdentifier: @"SettingsVCPushNotificationsAlert"];
|
||||
[self presentViewController:showSettingsPrompt animated:YES completion:nil];
|
||||
currentAlert = showSettingsPrompt;
|
||||
|
||||
// Keep off the switch
|
||||
// Keep the the switch off.
|
||||
sender.on = NO;
|
||||
}
|
||||
else if ([MXKAccountManager sharedManager].activeAccounts.count)
|
||||
|
@ -3322,11 +3378,11 @@ TableViewSectionsDelegate>
|
|||
|
||||
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *errorAlert = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[errorAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3347,9 +3403,9 @@ TableViewSectionsDelegate>
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n retry]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[errorAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n retry]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3363,8 +3419,9 @@ TableViewSectionsDelegate>
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCSaveChangesFailedAlert"];
|
||||
[rootViewController presentViewController:currentAlert animated:YES completion:nil];
|
||||
[errorAlert mxk_setAccessibilityIdentifier: @"SettingsVCSaveChangesFailedAlert"];
|
||||
[rootViewController presentViewController:errorAlert animated:YES completion:nil];
|
||||
currentAlert = errorAlert;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3385,13 +3442,13 @@ TableViewSectionsDelegate>
|
|||
|
||||
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n accountErrorEmailWrongTitle]
|
||||
message:[MatrixKitL10n accountErrorEmailWrongDescription]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *errorAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n accountErrorEmailWrongTitle]
|
||||
message:[MatrixKitL10n accountErrorEmailWrongDescription]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[errorAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -3402,8 +3459,9 @@ TableViewSectionsDelegate>
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCAddEmailAlert"];
|
||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
[errorAlert mxk_setAccessibilityIdentifier: @"SettingsVCAddEmailAlert"];
|
||||
[self presentViewController:errorAlert animated:YES completion:nil];
|
||||
currentAlert = errorAlert;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -3495,11 +3553,11 @@ TableViewSectionsDelegate>
|
|||
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
__weak typeof(self) weakSelf = self;
|
||||
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n accountErrorMsisdnWrongTitle]
|
||||
message:[MatrixKitL10n accountErrorMsisdnWrongDescription]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *errorAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n accountErrorMsisdnWrongTitle]
|
||||
message:[MatrixKitL10n accountErrorMsisdnWrongDescription]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok]
|
||||
[errorAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
|
@ -3511,8 +3569,9 @@ TableViewSectionsDelegate>
|
|||
|
||||
}]];
|
||||
|
||||
[currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCAddMsisdnAlert"];
|
||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
[errorAlert mxk_setAccessibilityIdentifier: @"SettingsVCAddMsisdnAlert"];
|
||||
[self presentViewController:errorAlert animated:YES completion:nil];
|
||||
currentAlert = errorAlert;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -3868,9 +3927,9 @@ TableViewSectionsDelegate>
|
|||
{
|
||||
[self->currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
|
||||
self->currentAlert = [UIAlertController alertControllerWithTitle:nil message:[VectorL10n settingsPasswordUpdated] preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *successAlert = [UIAlertController alertControllerWithTitle:nil message:[VectorL10n settingsPasswordUpdated] preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok]
|
||||
[successAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
|
@ -3890,8 +3949,9 @@ TableViewSectionsDelegate>
|
|||
|
||||
}]];
|
||||
|
||||
[self->currentAlert mxk_setAccessibilityIdentifier:@"SettingsVCOnPasswordUpdatedAlert"];
|
||||
[self presentViewController:self->currentAlert animated:YES completion:nil];
|
||||
[successAlert mxk_setAccessibilityIdentifier:@"SettingsVCOnPasswordUpdatedAlert"];
|
||||
[self presentViewController:successAlert animated:YES completion:nil];
|
||||
self->currentAlert = successAlert;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3916,9 +3976,9 @@ TableViewSectionsDelegate>
|
|||
{
|
||||
[self->currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
|
||||
self->currentAlert = [UIAlertController alertControllerWithTitle:nil message:[VectorL10n settingsFailToUpdatePassword] preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *errorAlert = [UIAlertController alertControllerWithTitle:nil message:[VectorL10n settingsFailToUpdatePassword] preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok]
|
||||
[errorAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
|
@ -3939,8 +3999,9 @@ TableViewSectionsDelegate>
|
|||
|
||||
}]];
|
||||
|
||||
[self->currentAlert mxk_setAccessibilityIdentifier:@"SettingsVCPasswordChangeFailedAlert"];
|
||||
[rootViewController presentViewController:self->currentAlert animated:YES completion:nil];
|
||||
[errorAlert mxk_setAccessibilityIdentifier:@"SettingsVCPasswordChangeFailedAlert"];
|
||||
[rootViewController presentViewController:errorAlert animated:YES completion:nil];
|
||||
self->currentAlert = errorAlert;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -131,6 +131,9 @@ final class SpaceListViewModel: SpaceListViewModelType {
|
|||
|
||||
private func loadData() {
|
||||
guard let session = self.userSessionsService.mainUserSession?.matrixSession else {
|
||||
// If there is no main session, reset current selection and give an empty section list
|
||||
// It can happen when the user make a clear cache or logout
|
||||
self.resetList()
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -243,4 +246,15 @@ final class SpaceListViewModel: SpaceListViewModelType {
|
|||
return spaceViewData.spaceId
|
||||
}
|
||||
}
|
||||
|
||||
private func resetList() {
|
||||
self.sections = []
|
||||
|
||||
let selectedIndexPath = IndexPath(row: 0, section: 0)
|
||||
|
||||
self.selectedIndexPath = selectedIndexPath
|
||||
self.homeIndexPath = selectedIndexPath
|
||||
|
||||
self.update(viewState: .loaded([]))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,20 +125,20 @@ final class SplitViewCoordinator: NSObject, SplitViewCoordinatorType {
|
|||
}
|
||||
|
||||
// TODO: Do not expose publicly this method
|
||||
func restorePlaceholderDetails() {
|
||||
func resetDetails(animated: Bool) {
|
||||
// Be sure that the primary is then visible too.
|
||||
if splitViewController.displayMode == .primaryHidden {
|
||||
splitViewController.preferredDisplayMode = .allVisible
|
||||
}
|
||||
|
||||
self.resetDetailNavigationControllerWithPlaceholder(animated: false)
|
||||
self.resetDetailNavigationController(animated: animated)
|
||||
|
||||
// Release the current selected item (room/contact/group...).
|
||||
self.tabBarCoordinator?.releaseSelectedItems()
|
||||
}
|
||||
}
|
||||
|
||||
func popToHome(animated: Bool, completion: (() -> Void)?) {
|
||||
self.resetDetailNavigationControllerWithPlaceholder(animated: animated)
|
||||
self.resetDetails(animated: animated)
|
||||
|
||||
// Force back to the main screen if this is not the one that is displayed
|
||||
self.tabBarCoordinator?.popToHome(animated: animated, completion: completion)
|
||||
|
@ -172,6 +172,17 @@ final class SplitViewCoordinator: NSObject, SplitViewCoordinatorType {
|
|||
// Set placeholder screen as root controller of detail navigation controller
|
||||
let placeholderDetailsVC = self.createPlaceholderDetailsViewController()
|
||||
detailNavigationRouter.setRootModule(placeholderDetailsVC, hideNavigationBar: false, animated: animated, popCompletion: nil)
|
||||
}
|
||||
|
||||
private func resetDetailNavigationController(animated: Bool) {
|
||||
|
||||
if self.splitViewController.isCollapsed {
|
||||
if let topMostNavigationController = self.selectedNavigationRouter?.modules.last as? UINavigationController, topMostNavigationController == self.detailNavigationController {
|
||||
self.selectedNavigationRouter?.popModule(animated: animated)
|
||||
}
|
||||
} else {
|
||||
self.resetDetailNavigationControllerWithPlaceholder(animated: animated)
|
||||
}
|
||||
}
|
||||
|
||||
private func isPlaceholderShown(from secondaryViewController: UIViewController) -> Bool {
|
||||
|
@ -270,7 +281,7 @@ extension SplitViewCoordinator: UISplitViewControllerDelegate {
|
|||
}
|
||||
|
||||
// Restore detail navigation controller with placeholder as root
|
||||
self.resetDetailNavigationControllerWithPlaceholder(animated: false)
|
||||
self.resetDetailNavigationController(animated: false)
|
||||
|
||||
// Return up to date detail navigation controller
|
||||
// In any cases `detailNavigationController` will be used as secondary view of the split view controller.
|
||||
|
@ -353,6 +364,6 @@ extension SplitViewCoordinator: SplitViewMasterPresentableDelegate {
|
|||
}
|
||||
|
||||
func splitViewMasterPresentableWantsToResetDetail(_ presentable: Presentable) {
|
||||
self.resetDetailNavigationControllerWithPlaceholder(animated: false)
|
||||
self.resetDetails(animated: false)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,8 +30,10 @@ protocol SplitViewCoordinatorType: Coordinator, Presentable {
|
|||
/// - Parameter spaceId: The id of the Space to use.
|
||||
func start(with spaceId: String?)
|
||||
|
||||
/// Restore navigation stack and show home screen
|
||||
func popToHome(animated: Bool, completion: (() -> Void)?)
|
||||
|
||||
|
||||
// TODO: Do not expose publicly this method
|
||||
func restorePlaceholderDetails()
|
||||
/// Remove detail screens and display placeholder if needed
|
||||
func resetDetails(animated: Bool)
|
||||
}
|
||||
|
|
|
@ -41,7 +41,8 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
|
|||
private let masterNavigationController: UINavigationController
|
||||
|
||||
private var currentSpaceId: String?
|
||||
private var homeViewControllerWrapperViewController: HomeViewControllerWithBannerWrapperViewController?
|
||||
|
||||
private weak var versionCheckCoordinator: VersionCheckCoordinator?
|
||||
|
||||
private var currentMatrixSession: MXSession? {
|
||||
return parameters.userSessionsService.mainUserSession?.matrixSession
|
||||
|
@ -77,8 +78,7 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
|
|||
}
|
||||
|
||||
func start(with spaceId: String?) {
|
||||
self.currentSpaceId = spaceId
|
||||
|
||||
|
||||
// If start has been done once do not setup view controllers again
|
||||
if self.hasStartedOnce == false {
|
||||
let masterTabBarController = self.createMasterTabBarController()
|
||||
|
@ -98,16 +98,12 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
|
|||
self.registerUserSessionsServiceNotifications()
|
||||
self.registerSessionChange()
|
||||
|
||||
if let homeViewController = homeViewControllerWrapperViewController {
|
||||
let versionCheckCoordinator = VersionCheckCoordinator(rootViewController: masterTabBarController,
|
||||
bannerPresenter: homeViewController,
|
||||
themeService: ThemeService.shared())
|
||||
versionCheckCoordinator.start()
|
||||
add(childCoordinator: versionCheckCoordinator)
|
||||
}
|
||||
self.updateMasterTabBarController(with: spaceId, forceReload: true)
|
||||
} else {
|
||||
self.updateMasterTabBarController(with: spaceId)
|
||||
}
|
||||
|
||||
self.updateMasterTabBarController(with: spaceId)
|
||||
|
||||
self.currentSpaceId = spaceId
|
||||
}
|
||||
|
||||
func toPresentable() -> UIViewController {
|
||||
|
@ -211,21 +207,25 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
|
|||
}
|
||||
searchBarButtonItem.accessibilityLabel = VectorL10n.searchDefaultPlaceholder
|
||||
|
||||
tabBarController.navigationItem.rightBarButtonItem = searchBarButtonItem
|
||||
|
||||
self.updateTabControllers(for: tabBarController, showCommunities: true)
|
||||
tabBarController.navigationItem.rightBarButtonItem = searchBarButtonItem
|
||||
|
||||
return tabBarController
|
||||
}
|
||||
|
||||
private func createHomeViewController() -> UIViewController {
|
||||
private func createVersionCheckCoordinator(withRootViewController rootViewController: UIViewController, bannerPresentrer: BannerPresentationProtocol) -> VersionCheckCoordinator {
|
||||
let versionCheckCoordinator = VersionCheckCoordinator(rootViewController: rootViewController,
|
||||
bannerPresenter: bannerPresentrer,
|
||||
themeService: ThemeService.shared())
|
||||
return versionCheckCoordinator
|
||||
}
|
||||
|
||||
private func createHomeViewController() -> HomeViewControllerWithBannerWrapperViewController {
|
||||
let homeViewController: HomeViewController = HomeViewController.instantiate()
|
||||
homeViewController.tabBarItem.tag = Int(TABBAR_HOME_INDEX)
|
||||
homeViewController.tabBarItem.image = homeViewController.tabBarItem.image
|
||||
homeViewController.accessibilityLabel = VectorL10n.titleHome
|
||||
|
||||
let wrapperViewController = HomeViewControllerWithBannerWrapperViewController(viewController: homeViewController)
|
||||
homeViewControllerWrapperViewController = wrapperViewController
|
||||
let wrapperViewController = HomeViewControllerWithBannerWrapperViewController(viewController: homeViewController)
|
||||
return wrapperViewController
|
||||
}
|
||||
|
||||
|
@ -280,18 +280,35 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
|
|||
gesture.delegate = self
|
||||
}
|
||||
|
||||
private func updateMasterTabBarController(with spaceId: String?) {
|
||||
private func updateMasterTabBarController(with spaceId: String?, forceReload: Bool = false) {
|
||||
|
||||
guard forceReload || spaceId != self.currentSpaceId else { return }
|
||||
|
||||
self.updateTabControllers(for: self.masterTabBarController, showCommunities: spaceId == nil)
|
||||
self.masterTabBarController.filterRooms(withParentId: spaceId, inMatrixSession: self.currentMatrixSession)
|
||||
}
|
||||
|
||||
// TODO: Avoid to reinstantiate controllers everytime
|
||||
private func updateTabControllers(for tabBarController: MasterTabBarController, showCommunities: Bool) {
|
||||
var viewControllers: [UIViewController] = []
|
||||
|
||||
|
||||
let homeViewController = self.createHomeViewController()
|
||||
|
||||
viewControllers.append(homeViewController)
|
||||
|
||||
if let existingVersionCheckCoordinator = self.versionCheckCoordinator {
|
||||
self.remove(childCoordinator: existingVersionCheckCoordinator)
|
||||
}
|
||||
|
||||
if let masterTabBarController = self.masterTabBarController {
|
||||
|
||||
let versionCheckCoordinator = self.createVersionCheckCoordinator(withRootViewController: masterTabBarController, bannerPresentrer: homeViewController)
|
||||
versionCheckCoordinator.start()
|
||||
self.add(childCoordinator: versionCheckCoordinator)
|
||||
|
||||
self.versionCheckCoordinator = versionCheckCoordinator
|
||||
}
|
||||
|
||||
if RiotSettings.shared.homeScreenShowFavouritesTab {
|
||||
let favouritesViewController = self.createFavouritesViewController()
|
||||
viewControllers.append(favouritesViewController)
|
||||
|
|
|
@ -299,13 +299,12 @@ final class NavigationRouter: NSObject, NavigationRouterType {
|
|||
self.postNotification(withName: NavigationRouter.willPopModule, for: viewController)
|
||||
}
|
||||
|
||||
private func didPopViewController(_ viewController: UIViewController) {
|
||||
private func didPopViewController(_ viewController: UIViewController) {
|
||||
self.postNotification(withName: NavigationRouter.didPopModule, for: viewController)
|
||||
|
||||
// Call completion closure associated to the view controller
|
||||
// So associated coordinator can be deallocated
|
||||
runCompletion(for: viewController)
|
||||
|
||||
self.postNotification(withName: NavigationRouter.didPopModule, for: viewController)
|
||||
|
||||
self.removeModule(for: viewController)
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
|
||||
for (MXRoomSummary *roomSummary in roomsSummaries)
|
||||
{
|
||||
if (!roomSummary.hiddenFromUser)
|
||||
if (!roomSummary.hiddenFromUser && roomSummary.roomType == MXRoomTypeRoom)
|
||||
{
|
||||
[roomSummary setMatrixSession:session];
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
static const CGFloat kLargeImageSizeMaxDimension = 2048.0;
|
||||
static const CGSize kThumbnailSize = {800.0, 600.0};
|
||||
/// A safe maximum file size for an image to send the original.
|
||||
static const NSUInteger kImageMaxFileSize = 20 * 1024 * 1024;
|
||||
|
||||
typedef NS_ENUM(NSInteger, ImageCompressionMode)
|
||||
{
|
||||
|
@ -314,30 +316,43 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode)
|
|||
|
||||
if ([self.shareItemProvider areAllItemsImages])
|
||||
{
|
||||
// When all items are images, they're processed together from the
|
||||
// pending list, immediately after the final image has been loaded.
|
||||
[self.pendingImages addObject:imageData];
|
||||
}
|
||||
else
|
||||
{
|
||||
CGSize imageSize = [self imageSizeFromImageData:imageData];
|
||||
// Otherwise, the image is sent as is, without prompting for a resize
|
||||
// as that wouldn't make much sense with multiple content types.
|
||||
self.imageCompressionMode = ImageCompressionModeNone;
|
||||
self.actualLargeSize = MAX(imageSize.width, imageSize.height);
|
||||
|
||||
[self sendImageData:imageData toRooms:rooms success:requestSuccess failure:requestFailure];
|
||||
}
|
||||
|
||||
// Only prompt for image resize if all items are images
|
||||
// Ignore showMediaCompressionPrompt setting due to memory constraints with full size images.
|
||||
// When there are multiple content types the image will have been sent above.
|
||||
// Otherwise, if we have loaded all of the images we can send them all together.
|
||||
if ([self.shareItemProvider areAllItemsImages])
|
||||
{
|
||||
if ([self.shareItemProvider areAllItemsLoaded])
|
||||
{
|
||||
UIAlertController *compressionPrompt = [self compressionPromptForPendingImagesWithShareBlock:^{
|
||||
MXWeakify(self);
|
||||
void (^sendPendingImages)(void) = ^void() {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
[self sendImageDatas:self.pendingImages.copy toRooms:rooms success:requestSuccess failure:requestFailure];
|
||||
}];
|
||||
};
|
||||
|
||||
if (compressionPrompt)
|
||||
if (RiotSettings.shared.showMediaCompressionPrompt)
|
||||
{
|
||||
[self presentCompressionPrompt:compressionPrompt];
|
||||
// Create a compression prompt which will be nil when the sizes can't be determined or if there are no pending images.
|
||||
UIAlertController *compressionPrompt = [self compressionPromptForPendingImagesWithShareBlock:sendPendingImages];
|
||||
if (compressionPrompt)
|
||||
{
|
||||
[self presentCompressionPrompt:compressionPrompt];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self.imageCompressionMode = ImageCompressionModeNone;
|
||||
sendPendingImages();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -410,26 +425,26 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode)
|
|||
}
|
||||
}
|
||||
|
||||
- (void)resetPendingData
|
||||
- (BOOL)roomsContainEncryptedRoom:(NSArray<MXRoom *> *)rooms
|
||||
{
|
||||
[self.pendingImages removeAllObjects];
|
||||
[self.imageUploadProgresses removeAllObjects];
|
||||
}
|
||||
|
||||
- (BOOL)isAPendingImageNotOrientedUp
|
||||
{
|
||||
BOOL isAPendingImageNotOrientedUp = NO;
|
||||
BOOL foundEncryptedRoom = NO;
|
||||
|
||||
for (NSData *imageData in self.pendingImages)
|
||||
for (MXRoom *room in rooms)
|
||||
{
|
||||
if ([self isImageOrientationNotUpOrUndeterminedForImageData:imageData])
|
||||
if (room.summary.isEncrypted)
|
||||
{
|
||||
isAPendingImageNotOrientedUp = YES;
|
||||
foundEncryptedRoom = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return isAPendingImageNotOrientedUp;
|
||||
return foundEncryptedRoom;
|
||||
}
|
||||
|
||||
- (void)resetPendingData
|
||||
{
|
||||
[self.pendingImages removeAllObjects];
|
||||
[self.imageUploadProgresses removeAllObjects];
|
||||
}
|
||||
|
||||
// TODO: When select multiple images:
|
||||
|
@ -442,8 +457,6 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode)
|
|||
return nil;
|
||||
}
|
||||
|
||||
BOOL isAPendingImageNotOrientedUp = [self isAPendingImageNotOrientedUp];
|
||||
|
||||
NSData *firstImageData = self.pendingImages.firstObject;
|
||||
UIImage *firstImage = [UIImage imageWithData:firstImageData];
|
||||
|
||||
|
@ -451,16 +464,8 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode)
|
|||
|
||||
if (compressionSizes.small.fileSize == 0 && compressionSizes.medium.fileSize == 0 && compressionSizes.large.fileSize == 0)
|
||||
{
|
||||
if (isAPendingImageNotOrientedUp && self.pendingImages.count > 1)
|
||||
{
|
||||
self.imageCompressionMode = ImageCompressionModeSmall;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.imageCompressionMode = ImageCompressionModeNone;
|
||||
}
|
||||
|
||||
MXLogDebug(@"[ShareManager] Send %lu image(s) without compression prompt using compression mode: %ld", (unsigned long)self.pendingImages.count, (long)self.imageCompressionMode);
|
||||
self.imageCompressionMode = ImageCompressionModeNone;
|
||||
MXLogDebug(@"[ShareManager] Bypass compression prompt and send originals for %lu image(s) due to undetermined file sizes", (unsigned long)self.pendingImages.count);
|
||||
|
||||
shareBlock();
|
||||
|
||||
|
@ -480,7 +485,7 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode)
|
|||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
self.imageCompressionMode = ImageCompressionModeSmall;
|
||||
[self logCompressionSizeChoice:compressionSizes.large];
|
||||
[self logCompressionSizeChoice:compressionSizes.small];
|
||||
|
||||
shareBlock();
|
||||
}]];
|
||||
|
@ -495,7 +500,7 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode)
|
|||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
self.imageCompressionMode = ImageCompressionModeMedium;
|
||||
[self logCompressionSizeChoice:compressionSizes.large];
|
||||
[self logCompressionSizeChoice:compressionSizes.medium];
|
||||
|
||||
shareBlock();
|
||||
}]];
|
||||
|
@ -520,8 +525,8 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode)
|
|||
}]];
|
||||
}
|
||||
|
||||
// To limit memory consumption, we suggest the original resolution only if the image orientation is up, or if the image size is moderate
|
||||
if (!isAPendingImageNotOrientedUp || !compressionSizes.large.fileSize)
|
||||
// To limit memory consumption when encrypting, we suggest the original resolution only if the image size is moderate
|
||||
if (compressionSizes.original.fileSize < kImageMaxFileSize)
|
||||
{
|
||||
NSString *fileSizeString = [MXTools fileSizeToString:compressionSizes.original.fileSize];
|
||||
|
||||
|
@ -532,7 +537,7 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode)
|
|||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
self.imageCompressionMode = ImageCompressionModeNone;
|
||||
[self logCompressionSizeChoice:compressionSizes.large];
|
||||
[self logCompressionSizeChoice:compressionSizes.original];
|
||||
|
||||
shareBlock();
|
||||
}]];
|
||||
|
@ -626,46 +631,6 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode)
|
|||
return CGSizeMake(width, height);
|
||||
}
|
||||
|
||||
- (NSNumber*)cgImageimageOrientationNumberFromImageData:(NSData*)imageData
|
||||
{
|
||||
NSNumber *orientationNumber;
|
||||
|
||||
CGImageSourceRef imageSource = CGImageSourceCreateWithData((CFDataRef)imageData, NULL);
|
||||
|
||||
CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL);
|
||||
|
||||
CFRelease(imageSource);
|
||||
|
||||
if (imageProperties != NULL)
|
||||
{
|
||||
CFNumberRef orientationNum = CFDictionaryGetValue(imageProperties, kCGImagePropertyOrientation);
|
||||
|
||||
// Check orientation and flip size if required
|
||||
if (orientationNum != NULL)
|
||||
{
|
||||
orientationNumber = (__bridge NSNumber *)orientationNum;
|
||||
}
|
||||
|
||||
CFRelease(imageProperties);
|
||||
}
|
||||
|
||||
return orientationNumber;
|
||||
}
|
||||
|
||||
- (BOOL)isImageOrientationNotUpOrUndeterminedForImageData:(NSData*)imageData
|
||||
{
|
||||
BOOL isImageNotOrientedUp = YES;
|
||||
|
||||
NSNumber *cgImageOrientationNumber = [self cgImageimageOrientationNumberFromImageData:imageData];
|
||||
|
||||
if (cgImageOrientationNumber && cgImageOrientationNumber.unsignedIntegerValue == (NSUInteger)kCGImagePropertyOrientationUp)
|
||||
{
|
||||
isImageNotOrientedUp = NO;
|
||||
}
|
||||
|
||||
return isImageNotOrientedUp;
|
||||
}
|
||||
|
||||
- (void)logCompressionSizeChoice:(MXKImageCompressionSize)compressionSize
|
||||
{
|
||||
NSString *fileSize = [MXTools fileSizeToString:compressionSize.fileSize round:NO];
|
||||
|
@ -826,19 +791,9 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode)
|
|||
|
||||
MXWeakify(self);
|
||||
|
||||
// Ignore showMediaCompressionPrompt setting due to memory constraints when encrypting large videos.
|
||||
UIAlertController *compressionPrompt = [MXKTools videoConversionPromptForVideoAsset:videoAsset withCompletion:^(NSString *presetName) {
|
||||
void (^sendVideo)(void) = ^void() {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
// If the preset name is nil, the user cancelled.
|
||||
if (!presetName)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the chosen video conversion preset.
|
||||
[MXSDKOptions sharedInstance].videoConversionPresetName = presetName;
|
||||
|
||||
[self didStartSending];
|
||||
if (!videoLocalUrl)
|
||||
{
|
||||
|
@ -876,9 +831,57 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode)
|
|||
success();
|
||||
}
|
||||
});
|
||||
}];
|
||||
};
|
||||
|
||||
[self presentCompressionPrompt:compressionPrompt];
|
||||
BOOL allRoomsAreUnencrypted = ![self roomsContainEncryptedRoom:rooms];
|
||||
|
||||
// When rooms are unencrypted convert the video according to the user's normal preferences
|
||||
if (allRoomsAreUnencrypted)
|
||||
{
|
||||
if (!RiotSettings.shared.showMediaCompressionPrompt)
|
||||
{
|
||||
[MXSDKOptions sharedInstance].videoConversionPresetName = AVCaptureSessionPreset1920x1080;
|
||||
sendVideo();
|
||||
}
|
||||
else
|
||||
{
|
||||
UIAlertController *compressionPrompt = [MXKTools videoConversionPromptForVideoAsset:videoAsset withCompletion:^(NSString *presetName) {
|
||||
// If the preset name is nil, the user cancelled.
|
||||
if (!presetName)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the chosen video conversion preset.
|
||||
[MXSDKOptions sharedInstance].videoConversionPresetName = presetName;
|
||||
sendVideo();
|
||||
}];
|
||||
|
||||
[self presentCompressionPrompt:compressionPrompt];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// When rooms are encrypted we quickly run out of memory encrypting the video
|
||||
// Prompt the user if they're happy to send a low quality video (320p).
|
||||
UIAlertController *lowQualityPrompt = [UIAlertController alertControllerWithTitle:VectorL10n.shareExtensionLowQualityVideoTitle
|
||||
message:[VectorL10n shareExtensionLowQualityVideoMessage:AppInfo.current.displayName]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:MatrixKitL10n.cancel style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
|
||||
// Do nothing
|
||||
}];
|
||||
UIAlertAction *sendAction = [UIAlertAction actionWithTitle:VectorL10n.shareExtensionSendNow style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
|
||||
[MXSDKOptions sharedInstance].videoConversionPresetName = AVAssetExportPresetMediumQuality;
|
||||
sendVideo();
|
||||
}];
|
||||
|
||||
[lowQualityPrompt addAction:cancelAction];
|
||||
[lowQualityPrompt addAction:sendAction];
|
||||
[lowQualityPrompt setPreferredAction:sendAction];
|
||||
|
||||
[self presentCompressionPrompt:lowQualityPrompt];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)sendVoiceMessage:(NSURL *)fileUrl
|
||||
|
@ -1021,17 +1024,7 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode)
|
|||
break;
|
||||
}
|
||||
|
||||
if (CGSizeEqualToSize(newImageSize, CGSizeZero))
|
||||
{
|
||||
// No resize to make
|
||||
// Make sure the uploaded image orientation is up
|
||||
if ([self isImageOrientationNotUpOrUndeterminedForImageData:imageData])
|
||||
{
|
||||
UIImage *image = [UIImage imageWithData:imageData];
|
||||
convertedImage = [MXKTools forceImageOrientationUp:image];
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!CGSizeEqualToSize(newImageSize, CGSizeZero))
|
||||
{
|
||||
// Resize the image and set image in right orientation too
|
||||
convertedImage = [MXKTools resizeImageWithData:imageData toFitInSize:newImageSize];
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
|
||||
self.roomTitleLabel.textColor = ThemeService.shared.theme.textPrimaryColor;
|
||||
self.contentView.backgroundColor = ThemeService.shared.theme.backgroundColor;
|
||||
self.selectionButton.tintColor = ThemeService.shared.theme.tintColor;
|
||||
|
||||
[self.selectionButton setImage:[UIImage imageNamed:@"radio-button-default"] forState:UIControlStateNormal];
|
||||
[self.selectionButton setImage:[UIImage imageNamed:@"radio-button-selected"] forState:UIControlStateSelected];
|
||||
|
@ -85,7 +86,7 @@
|
|||
[self.avatarImageView vc_setRoomAvatarImageWith:roomCellData.avatarUrl
|
||||
roomId:roomCellData.roomIdentifier
|
||||
displayName:roomCellData.roomDisplayname
|
||||
mediaManager:roomCellData.mxSession.mediaManager];
|
||||
mediaManager:roomCellData.roomSummary.mxSession.mediaManager];
|
||||
|
||||
self.roomTitleLabel.text = roomCellData.roomDisplayname;
|
||||
if (!self.roomTitleLabel.text.length)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19162" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19144"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
|
@ -40,14 +40,15 @@
|
|||
<constraint firstAttribute="width" constant="11" id="Mai-xD-TqV"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="m0f-of-6xq">
|
||||
<button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="m0f-of-6xq">
|
||||
<rect key="frame" x="562" y="29" width="16" height="16"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="16" id="Wue-Ih-eVg"/>
|
||||
<constraint firstAttribute="width" constant="16" id="s5a-PW-58p"/>
|
||||
</constraints>
|
||||
<state key="normal" title="Button"/>
|
||||
<buttonConfiguration key="configuration" style="plain" image="radio-button-selected"/>
|
||||
<state key="normal" image="radio-button-selected">
|
||||
<color key="titleColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</state>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
|
|
|
@ -28,18 +28,18 @@ private class ShareExtensionItem: ShareItemProtocol {
|
|||
}
|
||||
|
||||
var type: ShareItemType {
|
||||
if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.text.rawValue) {
|
||||
return .text
|
||||
} else if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.url.rawValue) {
|
||||
return .URL
|
||||
} else if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.fileUrl.rawValue) {
|
||||
return .fileURL
|
||||
} else if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.image.rawValue) {
|
||||
if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.image.rawValue) {
|
||||
return .image
|
||||
} else if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.video.rawValue) {
|
||||
return .video
|
||||
} else if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.movie.rawValue) {
|
||||
return .movie
|
||||
} else if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.fileUrl.rawValue) {
|
||||
return .fileURL
|
||||
} else if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.url.rawValue) {
|
||||
return .URL
|
||||
} else if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.text.rawValue) {
|
||||
return .text
|
||||
}
|
||||
|
||||
return .unknown
|
||||
|
|
|
@ -34,11 +34,10 @@ final class UserSuggestionCoordinator: Coordinator {
|
|||
|
||||
private let parameters: UserSuggestionCoordinatorParameters
|
||||
|
||||
private var userSuggestionHostingController: UIViewController!
|
||||
private var userSuggestionService: UserSuggestionServiceProtocol!
|
||||
private var userSuggestionViewModel: UserSuggestionViewModelProtocol!
|
||||
|
||||
private var roomMembers: [MXRoomMember] = []
|
||||
private var userSuggestionHostingController: UIViewController
|
||||
private var userSuggestionService: UserSuggestionServiceProtocol
|
||||
private var userSuggestionViewModel: UserSuggestionViewModelProtocol
|
||||
private var roomMemberProvider: UserSuggestionCoordinatorRoomMemberProvider
|
||||
|
||||
// MARK: Public
|
||||
|
||||
|
@ -54,9 +53,10 @@ final class UserSuggestionCoordinator: Coordinator {
|
|||
init(parameters: UserSuggestionCoordinatorParameters) {
|
||||
self.parameters = parameters
|
||||
|
||||
userSuggestionService = UserSuggestionService(roomMembersProvider: self)
|
||||
roomMemberProvider = UserSuggestionCoordinatorRoomMemberProvider(room: parameters.room)
|
||||
userSuggestionService = UserSuggestionService(roomMemberProvider: roomMemberProvider)
|
||||
userSuggestionViewModel = UserSuggestionViewModel.makeUserSuggestionViewModel(userSuggestionService: userSuggestionService)
|
||||
|
||||
|
||||
let view = UserSuggestionList(viewModel: userSuggestionViewModel.context)
|
||||
.addDependency(AvatarService.instantiate(mediaManager: parameters.mediaManager))
|
||||
|
||||
|
@ -69,7 +69,7 @@ final class UserSuggestionCoordinator: Coordinator {
|
|||
|
||||
switch result {
|
||||
case .selectedItemWithIdentifier(let identifier):
|
||||
guard let member = self.roomMembers.filter({ $0.userId == identifier }).first else {
|
||||
guard let member = self.roomMemberProvider.roomMembers.filter({ $0.userId == identifier }).first else {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -93,9 +93,18 @@ final class UserSuggestionCoordinator: Coordinator {
|
|||
}
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
extension UserSuggestionCoordinator: RoomMembersProviderProtocol {
|
||||
private class UserSuggestionCoordinatorRoomMemberProvider: RoomMembersProviderProtocol {
|
||||
|
||||
private let room: MXRoom
|
||||
|
||||
var roomMembers: [MXRoomMember] = []
|
||||
|
||||
init(room: MXRoom) {
|
||||
self.room = room;
|
||||
}
|
||||
|
||||
func fetchMembers(_ members: @escaping ([RoomMembersProviderMember]) -> Void) {
|
||||
parameters.room.members({ [weak self] roomMembers in
|
||||
room.members({ [weak self] roomMembers in
|
||||
guard let self = self, let joinedMembers = roomMembers?.joinedMembers else {
|
||||
return
|
||||
}
|
||||
|
@ -108,7 +117,7 @@ extension UserSuggestionCoordinator: RoomMembersProviderProtocol {
|
|||
self.roomMembers = joinedMembers
|
||||
members(self.roomMembersToProviderMembers(joinedMembers))
|
||||
}, failure: { error in
|
||||
MXLog.error("[UserSuggestionCoordinator] Failed loading room with error: \(String(describing: error))")
|
||||
MXLog.error("[UserSuggestionCoordinatorRoomMemberProvider] Failed loading room with error: \(String(describing: error))")
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ enum MockUserSuggestionScreenState: MockScreenState, CaseIterable {
|
|||
}
|
||||
|
||||
var screenView: ([Any], AnyView) {
|
||||
let service = UserSuggestionService(roomMembersProvider: self)
|
||||
let service = UserSuggestionService(roomMemberProvider: self)
|
||||
let listViewModel = UserSuggestionViewModel.makeUserSuggestionViewModel(userSuggestionService: service)
|
||||
|
||||
let viewModel = UserSuggestionListWithInputViewModel(listViewModel: listViewModel) { textMessage in
|
||||
|
|
|
@ -45,7 +45,7 @@ class UserSuggestionService: UserSuggestionServiceProtocol {
|
|||
|
||||
// MARK: Private
|
||||
|
||||
private let roomMembersProvider: RoomMembersProviderProtocol
|
||||
private let roomMemberProvider: RoomMembersProviderProtocol
|
||||
|
||||
private var suggestionItems: [UserSuggestionItemProtocol] = []
|
||||
private let currentTextTriggerSubject = CurrentValueSubject<String?, Never>(nil)
|
||||
|
@ -61,13 +61,13 @@ class UserSuggestionService: UserSuggestionServiceProtocol {
|
|||
|
||||
// MARK: - Setup
|
||||
|
||||
init(roomMembersProvider: RoomMembersProviderProtocol) {
|
||||
self.roomMembersProvider = roomMembersProvider
|
||||
init(roomMemberProvider: RoomMembersProviderProtocol) {
|
||||
self.roomMemberProvider = roomMemberProvider
|
||||
|
||||
currentTextTriggerSubject
|
||||
.debounce(for: 0.5, scheduler: RunLoop.main)
|
||||
.removeDuplicates()
|
||||
.sink { self.fetchAndFilterMembersForTextTrigger($0) }
|
||||
.sink { [weak self] in self?.fetchAndFilterMembersForTextTrigger($0) }
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ class UserSuggestionService: UserSuggestionServiceProtocol {
|
|||
|
||||
partialName.removeFirst() // remove the '@' prefix
|
||||
|
||||
roomMembersProvider.fetchMembers { [weak self] members in
|
||||
roomMemberProvider.fetchMembers { [weak self] members in
|
||||
guard let self = self else {
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue