Merge branch 'develop' into element_3579
29
CHANGES.rst
|
@ -22,6 +22,34 @@ Changes to be released in next version
|
|||
Others
|
||||
*
|
||||
|
||||
Changes in 1.1.2 (2020-12-02)
|
||||
=================================================
|
||||
|
||||
✨ Features
|
||||
* Added blur background support for iPhone and iPad (#3842)
|
||||
|
||||
🙌 Improvements
|
||||
* Room History: Remove the report option for outgoing messages.
|
||||
* Empty views: Add empty screen when there is nothing to display on home, people, favourites and rooms screen (#3836).
|
||||
|
||||
🐛 Bugfix
|
||||
* Restore the modular widget events in the rooms histories.
|
||||
|
||||
⚠️ API Changes
|
||||
* Slight API changes for SlidingModalPresenter to avoid race conditions while sharing a presenter. (#3842)
|
||||
|
||||
🗣 Translations
|
||||
*
|
||||
|
||||
🧱 Build
|
||||
*
|
||||
|
||||
Others
|
||||
*
|
||||
|
||||
Improvements:
|
||||
* Upgrade MatrixKit version ([v0.13.2](https://github.com/matrix-org/matrix-ios-kit/releases/tag/v0.13.2)).
|
||||
|
||||
Changes in 1.1.1 (2020-11-24)
|
||||
=================================================
|
||||
|
||||
|
@ -63,6 +91,7 @@ Changes in 1.1.0 (2020-11-17)
|
|||
* MXProfiler: Use this new module to track launch animation time reliably.
|
||||
* KeyValueStore improvements.
|
||||
* Jitsi: Support authenticated Jitsi widgets (#3655).
|
||||
* Room invites: Allow to accept a room invite without preview.
|
||||
|
||||
🐛 Bugfix
|
||||
* Fix analytics in order to track performance improvements.
|
||||
|
|
|
@ -31,6 +31,10 @@ class AppConfiguration: CommonConfiguration {
|
|||
// Enable CallKit for app
|
||||
MXKAppSettings.standard()?.isCallKitEnabled = true
|
||||
|
||||
// Get modular widget events in rooms histories
|
||||
MXKAppSettings.standard()?.addSupportedEventTypes([kWidgetMatrixEventTypeString,
|
||||
kWidgetModularEventTypeString])
|
||||
|
||||
// Hide undecryptable messages that were sent while the user was not in the room
|
||||
MXKAppSettings.standard()?.hidePreJoinedUndecryptableEvents = true
|
||||
|
||||
|
|
|
@ -25,19 +25,31 @@ final class BuildSettings: NSObject {
|
|||
|
||||
// MARK: - Bundle Settings
|
||||
static var bundleDisplayName: String {
|
||||
Bundle.app.object(forInfoDictionaryKey: "CFBundleDisplayName") as! String
|
||||
guard let bundleDisplayName = Bundle.app.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String else {
|
||||
fatalError("CFBundleDisplayName should be defined")
|
||||
}
|
||||
return bundleDisplayName
|
||||
}
|
||||
|
||||
static var applicationGroupIdentifier: String {
|
||||
Bundle.app.object(forInfoDictionaryKey: "applicationGroupIdentifier") as! String
|
||||
guard let applicationGroupIdentifier = Bundle.app.object(forInfoDictionaryKey: "applicationGroupIdentifier") as? String else {
|
||||
fatalError("applicationGroupIdentifier should be defined")
|
||||
}
|
||||
return applicationGroupIdentifier
|
||||
}
|
||||
|
||||
static var baseBundleIdentifier: String {
|
||||
Bundle.app.object(forInfoDictionaryKey: "baseBundleIdentifier") as! String
|
||||
guard let baseBundleIdentifier = Bundle.app.object(forInfoDictionaryKey: "baseBundleIdentifier") as? String else {
|
||||
fatalError("baseBundleIdentifier should be defined")
|
||||
}
|
||||
return baseBundleIdentifier
|
||||
}
|
||||
|
||||
static var keychainAccessGroup: String {
|
||||
Bundle.app.object(forInfoDictionaryKey: "keychainAccessGroup") as! String
|
||||
guard let keychainAccessGroup = Bundle.app.object(forInfoDictionaryKey: "keychainAccessGroup") as? String else {
|
||||
fatalError("keychainAccessGroup should be defined")
|
||||
}
|
||||
return keychainAccessGroup
|
||||
}
|
||||
|
||||
static var pushKitAppIdProd: String {
|
||||
|
|
11
INSTALL.md
|
@ -6,9 +6,7 @@ To build Element iOS project you need:
|
|||
|
||||
- Xcode 12.1+.
|
||||
- [Ruby](https://www.ruby-lang.org/), a dynamic programming language used by several build tools.
|
||||
- [cmake](https://gitlab.kitware.com/cmake/cmake), used to build [cmark](https://github.com/commonmark/cmark) dependency of [MatrixKit](https://github.com/matrix-org/matrix-ios-kit) pod.
|
||||
- [CocoaPods](https://cocoapods.org), library dependencies manager for Xcode projects.
|
||||
- [Homebrew](http://brew.sh/) (recommended), is a package manager for macOS that can be used to install cmake.
|
||||
- [bundler](https://bundler.io/) (optional), is also a dependency manager used to manage build tools dependency (CocoaPods, Fastlane).
|
||||
|
||||
### Install Ruby
|
||||
|
@ -17,15 +15,6 @@ Ruby is required for several build tools like CocoaPods, bundler and fastlane. R
|
|||
|
||||
If you do not want to grant the ruby package manager, [RubyGems](https://rubygems.org/), admin privileges and you prefer install gems into your user directory, you can read instructions from the CocoaPods [guide about sudo-less installation](https://guides.cocoapods.org/using/getting-started.html#sudo-less-installation).
|
||||
|
||||
### Install cmake
|
||||
|
||||
There are several ways to install cmake, downloading binary from [official website](https://cmake.org/download/) or using a package manager like [MacPorts](https://ports.macports.org/port/cmake/summary) or [Homebrew](http://brew.sh/).
|
||||
To keep it up to date, we recommend you to install cmake using [Homebrew](http://brew.sh/):
|
||||
|
||||
```
|
||||
brew install cmake
|
||||
```
|
||||
|
||||
### Install CocoaPods
|
||||
|
||||
To install CocoaPods you can grab the right version by using `bundler` (recommended) or you can directly install it with RubyGems:
|
||||
|
|
2
Podfile
|
@ -11,7 +11,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.13.1'
|
||||
$matrixKitVersion = '= 0.13.2'
|
||||
# $matrixKitVersion = :local
|
||||
# $matrixKitVersion = {'develop' => 'develop'}
|
||||
|
||||
|
|
50
Podfile.lock
|
@ -47,7 +47,7 @@ PODS:
|
|||
- GBDeviceInfo/Core (6.4.0)
|
||||
- GZIP (1.3.0)
|
||||
- HPGrowingTextView (1.1)
|
||||
- JitsiMeetSDK (2.10.2)
|
||||
- JitsiMeetSDK (2.11.0)
|
||||
- KeychainAccess (4.2.1)
|
||||
- KituraContracts (1.2.1):
|
||||
- LoggerAPI (~> 1.7)
|
||||
|
@ -60,38 +60,38 @@ PODS:
|
|||
- MatomoTracker (7.2.2):
|
||||
- MatomoTracker/Core (= 7.2.2)
|
||||
- MatomoTracker/Core (7.2.2)
|
||||
- MatrixKit (0.13.1):
|
||||
- MatrixKit (0.13.2):
|
||||
- Down (~> 0.9.3)
|
||||
- DTCoreText (~> 1.6.23)
|
||||
- HPGrowingTextView (~> 1.1)
|
||||
- libPhoneNumber-iOS (~> 0.9.13)
|
||||
- MatrixKit/Core (= 0.13.1)
|
||||
- MatrixSDK (= 0.17.3)
|
||||
- MatrixKit/AppExtension (0.13.1):
|
||||
- MatrixKit/Core (= 0.13.2)
|
||||
- MatrixSDK (= 0.17.4)
|
||||
- MatrixKit/AppExtension (0.13.2):
|
||||
- Down (~> 0.9.3)
|
||||
- DTCoreText (~> 1.6.23)
|
||||
- DTCoreText/Extension
|
||||
- HPGrowingTextView (~> 1.1)
|
||||
- libPhoneNumber-iOS (~> 0.9.13)
|
||||
- MatrixSDK (= 0.17.3)
|
||||
- MatrixKit/Core (0.13.1):
|
||||
- MatrixSDK (= 0.17.4)
|
||||
- MatrixKit/Core (0.13.2):
|
||||
- Down (~> 0.9.3)
|
||||
- DTCoreText (~> 1.6.23)
|
||||
- HPGrowingTextView (~> 1.1)
|
||||
- libPhoneNumber-iOS (~> 0.9.13)
|
||||
- MatrixSDK (= 0.17.3)
|
||||
- MatrixSDK (0.17.3):
|
||||
- MatrixSDK/Core (= 0.17.3)
|
||||
- MatrixSDK/Core (0.17.3):
|
||||
- MatrixSDK (= 0.17.4)
|
||||
- MatrixSDK (0.17.4):
|
||||
- MatrixSDK/Core (= 0.17.4)
|
||||
- MatrixSDK/Core (0.17.4):
|
||||
- AFNetworking (~> 4.0.0)
|
||||
- GZIP (~> 1.3.0)
|
||||
- libbase58 (~> 0.1.4)
|
||||
- OLMKit (~> 3.1.0)
|
||||
- Realm (= 10.1.2)
|
||||
- MatrixSDK/JingleCallStack (0.17.3):
|
||||
- JitsiMeetSDK (= 2.10.2)
|
||||
- Realm (= 10.1.4)
|
||||
- MatrixSDK/JingleCallStack (0.17.4):
|
||||
- JitsiMeetSDK (= 2.11.0)
|
||||
- MatrixSDK/Core
|
||||
- MatrixSDK/SwiftSupport (0.17.3):
|
||||
- MatrixSDK/SwiftSupport (0.17.4):
|
||||
- MatrixSDK/Core
|
||||
- OLMKit (3.1.0):
|
||||
- OLMKit/olmc (= 3.1.0)
|
||||
|
@ -99,9 +99,9 @@ PODS:
|
|||
- OLMKit/olmc (3.1.0)
|
||||
- OLMKit/olmcpp (3.1.0)
|
||||
- ReadMoreTextView (3.0.1)
|
||||
- Realm (10.1.2):
|
||||
- Realm/Headers (= 10.1.2)
|
||||
- Realm/Headers (10.1.2)
|
||||
- Realm (10.1.4):
|
||||
- Realm/Headers (= 10.1.4)
|
||||
- Realm/Headers (10.1.4)
|
||||
- Reusable (4.1.1):
|
||||
- Reusable/Storyboard (= 4.1.1)
|
||||
- Reusable/View (= 4.1.1)
|
||||
|
@ -129,8 +129,8 @@ DEPENDENCIES:
|
|||
- KeychainAccess (~> 4.2.1)
|
||||
- KTCenterFlowLayout (~> 1.3.1)
|
||||
- MatomoTracker (~> 7.2.2)
|
||||
- MatrixKit (= 0.13.1)
|
||||
- MatrixKit/AppExtension (= 0.13.1)
|
||||
- MatrixKit (= 0.13.2)
|
||||
- MatrixKit/AppExtension (= 0.13.2)
|
||||
- MatrixSDK
|
||||
- MatrixSDK/JingleCallStack
|
||||
- MatrixSDK/SwiftSupport
|
||||
|
@ -193,7 +193,7 @@ SPEC CHECKSUMS:
|
|||
GBDeviceInfo: f29249891446a392e64b9c9bbef9554aad2a6beb
|
||||
GZIP: 416858efbe66b41b206895ac6dfd5493200d95b3
|
||||
HPGrowingTextView: 88a716d97fb853bcb08a4a08e4727da17efc9b19
|
||||
JitsiMeetSDK: d7612d73befd3f7f51f989458a816bbd05d0bc8e
|
||||
JitsiMeetSDK: ddc915b751b0166aa4fdfee938bd60cc87aff9f3
|
||||
KeychainAccess: 9b07f665298d13c3a85881bd3171f6f49b8151c1
|
||||
KituraContracts: e845e60dc8627ad0a76fa55ef20a45451d8f830b
|
||||
KTCenterFlowLayout: 6e02b50ab2bd865025ae82fe266ed13b6d9eaf97
|
||||
|
@ -202,11 +202,11 @@ SPEC CHECKSUMS:
|
|||
LoggerAPI: ad9c4a6f1e32f518fdb43a1347ac14d765ab5e3d
|
||||
Logging: beeb016c9c80cf77042d62e83495816847ef108b
|
||||
MatomoTracker: a59ec4da0f580be57bdc6baa708a71a86532a832
|
||||
MatrixKit: 47bc0d4414761f5a88fc1e6429cb0d8ab4d10b2f
|
||||
MatrixSDK: 673536e6b013185ce149ba61ff24b84becab40fd
|
||||
MatrixKit: 411348d4690b414e18958a0437c13edc21054a18
|
||||
MatrixSDK: 39282219213aebf621326f6335073b5a2b1e9113
|
||||
OLMKit: 4ee0159d63feeb86d836fdcfefe418e163511639
|
||||
ReadMoreTextView: 19147adf93abce6d7271e14031a00303fe28720d
|
||||
Realm: 031fdd4be7094d01b43af1a5e49766ab644bb800
|
||||
Realm: 80f4fb2971ccb9adc27a47d0955ae8e533a7030b
|
||||
Reusable: 53a9acf5c536f229b31b5865782414b508252ddb
|
||||
SwiftBase32: 9399c25a80666dc66b51e10076bf591e3bbb8f17
|
||||
SwiftGen: 67860cc7c3cfc2ed25b9b74cfd55495fc89f9108
|
||||
|
@ -215,6 +215,6 @@ SPEC CHECKSUMS:
|
|||
zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c
|
||||
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
|
||||
|
||||
PODFILE CHECKSUM: 1f3cfce328f9e786da7240ccb9391754c65531eb
|
||||
PODFILE CHECKSUM: 5f40ae970fc6a939c548fedf78849358a895c315
|
||||
|
||||
COCOAPODS: 1.10.0
|
||||
|
|
|
@ -203,9 +203,9 @@
|
|||
B110872621F098F0003554A5 /* ActivityIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B110872221F098F0003554A5 /* ActivityIndicatorView.swift */; };
|
||||
B11291EA238D35590077B478 /* SlidingModalPresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B11291E9238D35590077B478 /* SlidingModalPresentable.swift */; };
|
||||
B11291EC238D704C0077B478 /* FloatingPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = B11291EB238D704C0077B478 /* FloatingPoint.swift */; };
|
||||
B11F4D1C25680010009F1586 /* HomeEmptyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B11F4D1A25680010009F1586 /* HomeEmptyView.xib */; };
|
||||
B11F4D1D25680010009F1586 /* HomeEmptyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B11F4D1B25680010009F1586 /* HomeEmptyView.swift */; };
|
||||
B113DD3D255E876A0022942A /* JitsiWellKnown.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1E5EF9C2541C06000E8A883 /* JitsiWellKnown.swift */; };
|
||||
B120863722EF375F001F89E0 /* ReactionHistoryBridgeCoordinatorPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B120863622EF375F001F89E0 /* ReactionHistoryBridgeCoordinatorPresenter.swift */; };
|
||||
B124BBD725645F3F0028996D /* RoomIdComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = B124BBD625645F3F0028996D /* RoomIdComponents.swift */; };
|
||||
B125FE1B231D5BF200B72806 /* SettingsDiscoveryTableViewSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = B125FE1A231D5BF200B72806 /* SettingsDiscoveryTableViewSection.swift */; };
|
||||
B125FE1D231D5DE400B72806 /* SettingsDiscoveryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B125FE1C231D5DE400B72806 /* SettingsDiscoveryViewModel.swift */; };
|
||||
B125FE1F231D5DF700B72806 /* SettingsDiscoveryViewModelType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B125FE1E231D5DF700B72806 /* SettingsDiscoveryViewModelType.swift */; };
|
||||
|
@ -333,7 +333,6 @@
|
|||
B190F55922CE356800AEB493 /* EditHistoryHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B190F55822CE356800AEB493 /* EditHistoryHeaderView.swift */; };
|
||||
B190F55B22CE35FD00AEB493 /* EditHistoryHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B190F55A22CE35FD00AEB493 /* EditHistoryHeaderView.xib */; };
|
||||
B190F55D22CE5A9700AEB493 /* EditHistorySection.swift in Sources */ = {isa = PBXBuildFile; fileRef = B190F55C22CE5A9600AEB493 /* EditHistorySection.swift */; };
|
||||
B1920713255068B300F5062F /* RoomIdComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1920712255068B200F5062F /* RoomIdComponents.swift */; };
|
||||
B1963B2B228F1C4900CBA17F /* BubbleReactionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1963B25228F1C4800CBA17F /* BubbleReactionsView.swift */; };
|
||||
B1963B2C228F1C4900CBA17F /* BubbleReactionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1963B26228F1C4800CBA17F /* BubbleReactionViewCell.xib */; };
|
||||
B1963B2D228F1C4900CBA17F /* BubbleReactionsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1963B27228F1C4800CBA17F /* BubbleReactionsViewModel.swift */; };
|
||||
|
@ -346,6 +345,8 @@
|
|||
B19EFA3921F8BB2C00FC070E /* KeyBackupRecoverCoordinatorType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B19EFA3821F8BB2C00FC070E /* KeyBackupRecoverCoordinatorType.swift */; };
|
||||
B19EFA3B21F8BB4100FC070E /* KeyBackupRecoverCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B19EFA3A21F8BB4100FC070E /* KeyBackupRecoverCoordinator.swift */; };
|
||||
B1A5B33E227ADF2A004CBA85 /* UIImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1A5B33D227ADF2A004CBA85 /* UIImage.swift */; };
|
||||
B1A67946257559CF00BB0C69 /* RootTabEmptyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B11F4D2025681500009F1586 /* RootTabEmptyView.swift */; };
|
||||
B1A67947257559D500BB0C69 /* RootTabEmptyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B11F4D1E256814E5009F1586 /* RootTabEmptyView.xib */; };
|
||||
B1A6805424B7C65200E312CC /* MajorUpdateManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1A6805324B7C65200E312CC /* MajorUpdateManager.swift */; };
|
||||
B1A68593229E807A00D6C09A /* RoomBubbleCellLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1A68592229E807800D6C09A /* RoomBubbleCellLayout.swift */; };
|
||||
B1A6C10723881EF2002882FD /* SlidingModalPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1A6C10623881EF2002882FD /* SlidingModalPresenter.swift */; };
|
||||
|
@ -752,7 +753,8 @@
|
|||
B1E5368921FB1E20001F3AFF /* UIButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1E5368821FB1E20001F3AFF /* UIButton.swift */; };
|
||||
B1E5368D21FB7245001F3AFF /* KeyBackupRecoverFromPassphraseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1E5368C21FB7245001F3AFF /* KeyBackupRecoverFromPassphraseViewController.swift */; };
|
||||
B1E5368F21FB7258001F3AFF /* KeyBackupRecoverFromPassphraseViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B1E5368E21FB7258001F3AFF /* KeyBackupRecoverFromPassphraseViewController.storyboard */; };
|
||||
B1E5EF9D2541C06000E8A883 /* JitsiWellKnown.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1E5EF9C2541C06000E8A883 /* JitsiWellKnown.swift */; };
|
||||
B1F9072D255CDA1200DD14E5 /* RecentsViewController+RoomInvite.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1F9072C255CDA1200DD14E5 /* RecentsViewController+RoomInvite.swift */; };
|
||||
B1F9072F255CE06000DD14E5 /* InviteRecentTableViewCell+ButtonViewsUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1F9072E255CE06000DD14E5 /* InviteRecentTableViewCell+ButtonViewsUpdate.swift */; };
|
||||
B1FDF56021F5FE5500BA3834 /* KeyBackupSetupPassphraseViewAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FDF55F21F5FE5500BA3834 /* KeyBackupSetupPassphraseViewAction.swift */; };
|
||||
DB1392A2332C3CAF6C9962EF /* Pods_RiotPods_RiotNSE.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4D418D054E4032F2CFA8B51 /* Pods_RiotPods_RiotNSE.framework */; };
|
||||
EC1CA85F24C1DEC400DE9EBF /* EnterPinCodeViewModelType.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1CA85124C1DEC400DE9EBF /* EnterPinCodeViewModelType.swift */; };
|
||||
|
@ -1241,9 +1243,10 @@
|
|||
B110872221F098F0003554A5 /* ActivityIndicatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorView.swift; sourceTree = "<group>"; };
|
||||
B11291E9238D35590077B478 /* SlidingModalPresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SlidingModalPresentable.swift; sourceTree = "<group>"; };
|
||||
B11291EB238D704C0077B478 /* FloatingPoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FloatingPoint.swift; sourceTree = "<group>"; };
|
||||
B11F4D1A25680010009F1586 /* HomeEmptyView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = HomeEmptyView.xib; sourceTree = "<group>"; };
|
||||
B11F4D1B25680010009F1586 /* HomeEmptyView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeEmptyView.swift; sourceTree = "<group>"; };
|
||||
B11F4D1E256814E5009F1586 /* RootTabEmptyView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RootTabEmptyView.xib; sourceTree = "<group>"; };
|
||||
B11F4D2025681500009F1586 /* RootTabEmptyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootTabEmptyView.swift; sourceTree = "<group>"; };
|
||||
B120863622EF375F001F89E0 /* ReactionHistoryBridgeCoordinatorPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactionHistoryBridgeCoordinatorPresenter.swift; sourceTree = "<group>"; };
|
||||
B124BBD625645F3F0028996D /* RoomIdComponents.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomIdComponents.swift; sourceTree = "<group>"; };
|
||||
B125FE1A231D5BF200B72806 /* SettingsDiscoveryTableViewSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsDiscoveryTableViewSection.swift; sourceTree = "<group>"; };
|
||||
B125FE1C231D5DE400B72806 /* SettingsDiscoveryViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsDiscoveryViewModel.swift; sourceTree = "<group>"; };
|
||||
B125FE1E231D5DF700B72806 /* SettingsDiscoveryViewModelType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsDiscoveryViewModelType.swift; sourceTree = "<group>"; };
|
||||
|
@ -1421,7 +1424,6 @@
|
|||
B190F55822CE356800AEB493 /* EditHistoryHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditHistoryHeaderView.swift; sourceTree = "<group>"; };
|
||||
B190F55A22CE35FD00AEB493 /* EditHistoryHeaderView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = EditHistoryHeaderView.xib; sourceTree = "<group>"; };
|
||||
B190F55C22CE5A9600AEB493 /* EditHistorySection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditHistorySection.swift; sourceTree = "<group>"; };
|
||||
B1920712255068B200F5062F /* RoomIdComponents.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomIdComponents.swift; sourceTree = "<group>"; };
|
||||
B1963B25228F1C4800CBA17F /* BubbleReactionsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BubbleReactionsView.swift; sourceTree = "<group>"; };
|
||||
B1963B26228F1C4800CBA17F /* BubbleReactionViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = BubbleReactionViewCell.xib; sourceTree = "<group>"; };
|
||||
B1963B27228F1C4800CBA17F /* BubbleReactionsViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BubbleReactionsViewModel.swift; sourceTree = "<group>"; };
|
||||
|
@ -1983,6 +1985,8 @@
|
|||
B1EDFDF32525E9690020EEFF /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/Vector.strings; sourceTree = "<group>"; };
|
||||
B1EDFDF42525E9690020EEFF /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
B1EDFDF52525E96A0020EEFF /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
B1F9072C255CDA1200DD14E5 /* RecentsViewController+RoomInvite.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecentsViewController+RoomInvite.swift"; sourceTree = "<group>"; };
|
||||
B1F9072E255CE06000DD14E5 /* InviteRecentTableViewCell+ButtonViewsUpdate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "InviteRecentTableViewCell+ButtonViewsUpdate.swift"; sourceTree = "<group>"; };
|
||||
B1FDF55F21F5FE5500BA3834 /* KeyBackupSetupPassphraseViewAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyBackupSetupPassphraseViewAction.swift; sourceTree = "<group>"; };
|
||||
B43DC75D1590BB8A4243BD4D /* Pods-RiotPods-Riot.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RiotPods-Riot.release.xcconfig"; path = "Target Support Files/Pods-RiotPods-Riot/Pods-RiotPods-Riot.release.xcconfig"; sourceTree = "<group>"; };
|
||||
BABB6681FBD79219B1213D6C /* Pods-RiotTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RiotTests.debug.xcconfig"; path = "Target Support Files/Pods-RiotTests/Pods-RiotTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
|
@ -3231,6 +3235,14 @@
|
|||
path = OnBoarding;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B180A645255DF59800F5E6FF /* Room */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B124BBD625645F3F0028996D /* RoomIdComponents.swift */,
|
||||
);
|
||||
path = Room;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B183226923F59F3E0035B2E8 /* Buttons */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -3271,14 +3283,6 @@
|
|||
path = SelfVerifyWait;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B19207112550683500F5062F /* Room */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B1920712255068B200F5062F /* RoomIdComponents.swift */,
|
||||
);
|
||||
path = Room;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B1963B24228F1C4800CBA17F /* BubbleReactions */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -3783,6 +3787,7 @@
|
|||
B1B556DB20EE6C4C00210D55 /* RecentsViewController.h */,
|
||||
B1B556D920EE6C4C00210D55 /* RecentsViewController.m */,
|
||||
B1B556DA20EE6C4C00210D55 /* RecentsViewController.xib */,
|
||||
B1F9072C255CDA1200DD14E5 /* RecentsViewController+RoomInvite.swift */,
|
||||
B16932F320F3C4B800746532 /* DataSources */,
|
||||
B16932F420F3C4C000746532 /* CellData */,
|
||||
B1B5594E20EF9A8600210D55 /* Views */,
|
||||
|
@ -4458,8 +4463,6 @@
|
|||
B1B5594320EF7BD000210D55 /* TableViewCellWithCollectionView.h */,
|
||||
B1B5594020EF7BD000210D55 /* TableViewCellWithCollectionView.m */,
|
||||
B1B5593F20EF7BD000210D55 /* TableViewCellWithCollectionView.xib */,
|
||||
B11F4D1B25680010009F1586 /* HomeEmptyView.swift */,
|
||||
B11F4D1A25680010009F1586 /* HomeEmptyView.xib */,
|
||||
);
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
|
@ -4472,6 +4475,8 @@
|
|||
B1B5594F20EF9A8600210D55 /* RecentTableViewCell.h */,
|
||||
B1B5595020EF9A8600210D55 /* RecentTableViewCell.m */,
|
||||
B1B5595120EF9A8600210D55 /* RecentTableViewCell.xib */,
|
||||
B11F4D2025681500009F1586 /* RootTabEmptyView.swift */,
|
||||
B11F4D1E256814E5009F1586 /* RootTabEmptyView.xib */,
|
||||
);
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
|
@ -4500,6 +4505,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
B1B5597420EFB02900210D55 /* InviteRecentTableViewCell.h */,
|
||||
B1F9072E255CE06000DD14E5 /* InviteRecentTableViewCell+ButtonViewsUpdate.swift */,
|
||||
B1B5597220EFB02900210D55 /* InviteRecentTableViewCell.m */,
|
||||
B1B5597320EFB02900210D55 /* InviteRecentTableViewCell.xib */,
|
||||
);
|
||||
|
@ -4522,7 +4528,7 @@
|
|||
B1B5598A20EFC42100210D55 /* Settings */,
|
||||
32242F0B21E8FBA900725742 /* Theme */,
|
||||
B1B5598020EFC3DF00210D55 /* Widgets */,
|
||||
B19207112550683500F5062F /* Room */,
|
||||
B180A645255DF59800F5E6FF /* Room */,
|
||||
);
|
||||
path = Managers;
|
||||
sourceTree = "<group>";
|
||||
|
@ -5932,12 +5938,12 @@
|
|||
B1B558BB20EF768F00210D55 /* RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.xib in Resources */,
|
||||
B1B557A720EF5A1B00210D55 /* DeviceTableViewCell.xib in Resources */,
|
||||
B14084C823BF76CB0010F692 /* BubbleCellContentView.xib in Resources */,
|
||||
B1A67947257559D500BB0C69 /* RootTabEmptyView.xib in Resources */,
|
||||
B1B557D220EF5E3500210D55 /* MediaAlbumTableCell.xib in Resources */,
|
||||
B1B558C520EF768F00210D55 /* RoomOutgoingEncryptedTextMsgBubbleCell.xib in Resources */,
|
||||
B1B5582B20EF666100210D55 /* DirectoryRecentTableViewCell.xib in Resources */,
|
||||
B105778F2213052A00334B1E /* KeyBackupSetupSuccessFromRecoveryKeyViewController.storyboard in Resources */,
|
||||
EC1CA89924C9C9A200DE9EBF /* SetupBiometricsViewController.storyboard in Resources */,
|
||||
B11F4D1C25680010009F1586 /* HomeEmptyView.xib in Resources */,
|
||||
B1B5590F20EF782800210D55 /* TableViewCellWithPhoneNumberTextField.xib in Resources */,
|
||||
B1B5578520EF564900210D55 /* GroupTableViewCellWithSwitch.xib in Resources */,
|
||||
B1B557B320EF5AEF00210D55 /* EventDetailsView.xib in Resources */,
|
||||
|
@ -6229,6 +6235,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
EC711B7B24A63B37008F830C /* SecretsSetupRecoveryKeyCoordinator.swift in Sources */,
|
||||
B1F9072D255CDA1200DD14E5 /* RecentsViewController+RoomInvite.swift in Sources */,
|
||||
B1B557D120EF5E3500210D55 /* MediaAlbumTableCell.m in Sources */,
|
||||
32607D71243E0A55006674CC /* KeyBackupRecoverFromPrivateKeyViewState.swift in Sources */,
|
||||
EC51E7A92514D2E100AAE7DB /* RoomInfoListViewModelType.swift in Sources */,
|
||||
|
@ -6346,6 +6353,7 @@
|
|||
B157FAA823264BED00EBFBD4 /* SettingsDiscoveryThreePidDetailsCoordinatorBridgePresenter.swift in Sources */,
|
||||
B169330B20F3CA3A00746532 /* Contact.m in Sources */,
|
||||
B1A5B33E227ADF2A004CBA85 /* UIImage.swift in Sources */,
|
||||
B113DD3D255E876A0022942A /* JitsiWellKnown.swift in Sources */,
|
||||
EC51E7AC2514D2E100AAE7DB /* RoomInfoListCoordinatorType.swift in Sources */,
|
||||
B1D4752A21EE52B10067973F /* KeyBackupSetupIntroViewController.swift in Sources */,
|
||||
B10A3E9424FE8254007C380F /* AppCoordinatorType.swift in Sources */,
|
||||
|
@ -6504,6 +6512,7 @@
|
|||
32F6B96B2270623100BBA352 /* KeyVerificationDataLoadingViewAction.swift in Sources */,
|
||||
B1B558C920EF768F00210D55 /* RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.m in Sources */,
|
||||
B1B5571B20EE6C4D00210D55 /* DeactivateAccountViewController.m in Sources */,
|
||||
B1A67946257559CF00BB0C69 /* RootTabEmptyView.swift in Sources */,
|
||||
B1DCC63922E85E9A00625807 /* EmojiMartStore.swift in Sources */,
|
||||
B10A3E9024FE4368007C380F /* ElementViewController.swift in Sources */,
|
||||
B1B5590620EF768F00210D55 /* RoomMembershipCollapsedWithPaginationTitleBubbleCell.m in Sources */,
|
||||
|
@ -6523,6 +6532,7 @@
|
|||
B126768A2523E4D100BE6B98 /* SecretsResetViewModel.swift in Sources */,
|
||||
B1DCC62422E60CA900625807 /* EmojiPickerCategoryViewData.swift in Sources */,
|
||||
B1550FCB2420E8F500CE097B /* QRCodeReaderViewController.swift in Sources */,
|
||||
B124BBD725645F3F0028996D /* RoomIdComponents.swift in Sources */,
|
||||
324A2056225FC571004FE8B0 /* DeviceVerificationIncomingCoordinator.swift in Sources */,
|
||||
B16932F720F3C50E00746532 /* RecentsDataSource.m in Sources */,
|
||||
B1DCC63B22E85EF800625807 /* EmojiMartCategory.swift in Sources */,
|
||||
|
@ -6685,7 +6695,6 @@
|
|||
EC51E7A62514D2E100AAE7DB /* RoomInfoCoordinatorBridgePresenter.swift in Sources */,
|
||||
EC1CA87524C8259700DE9EBF /* KeychainStore.swift in Sources */,
|
||||
B1B5575220EE6C4D00210D55 /* RoomKeyRequestViewController.m in Sources */,
|
||||
B1920713255068B300F5062F /* RoomIdComponents.swift in Sources */,
|
||||
32A6001A22C661100042C1D9 /* EditHistoryCoordinator.swift in Sources */,
|
||||
F083BD1E1E7009ED00A9B29C /* LegacyAppDelegate.m in Sources */,
|
||||
B1B558E620EF768F00210D55 /* RoomIncomingAttachmentWithoutSenderInfoBubbleCell.m in Sources */,
|
||||
|
@ -6699,6 +6708,7 @@
|
|||
B18DEDD9243377C10075FEF7 /* KeyVerificationSelfVerifyWaitViewController.swift in Sources */,
|
||||
EC1CA89524C9C9A200DE9EBF /* SetupBiometricsViewController.swift in Sources */,
|
||||
324A2052225FC571004FE8B0 /* DeviceVerificationIncomingViewAction.swift in Sources */,
|
||||
B1F9072F255CE06000DD14E5 /* InviteRecentTableViewCell+ButtonViewsUpdate.swift in Sources */,
|
||||
EC85D72C2477DCF2002C44C9 /* KeyVerificationManuallyVerifyViewState.swift in Sources */,
|
||||
EC1CA86E24C5BA4500DE9EBF /* PinCodePreferences.swift in Sources */,
|
||||
B105778D2213051E00334B1E /* KeyBackupSetupSuccessFromRecoveryKeyViewController.swift in Sources */,
|
||||
|
@ -6883,7 +6893,6 @@
|
|||
B18DEDD5243377C10075FEF7 /* KeyVerificationSelfVerifyWaitViewModel.swift in Sources */,
|
||||
EC711B8B24A63B37008F830C /* SecretsRecoveryWithPassphraseViewState.swift in Sources */,
|
||||
ECAE7AE524EC0E01002FA813 /* TableViewSections.swift in Sources */,
|
||||
B1E5EF9D2541C06000E8A883 /* JitsiWellKnown.swift in Sources */,
|
||||
B1CE83DA2422817200D07506 /* KeyVerificationVerifyByScanningViewModel.swift in Sources */,
|
||||
32242F0921E8B05F00725742 /* UIColor.swift in Sources */,
|
||||
B16932E720F3C37100746532 /* HomeMessagesSearchDataSource.m in Sources */,
|
||||
|
@ -6921,7 +6930,6 @@
|
|||
B10A3E9C24FE88CB007C380F /* RootRouter.swift in Sources */,
|
||||
B1C562E8228C7CF20037F12A /* ContextualMenuItemView.swift in Sources */,
|
||||
B14F143022144F6500FA0595 /* KeyBackupRecoverFromRecoveryKeyCoordinatorType.swift in Sources */,
|
||||
B11F4D1D25680010009F1586 /* HomeEmptyView.swift in Sources */,
|
||||
B1E5368921FB1E20001F3AFF /* UIButton.swift in Sources */,
|
||||
B1DCC63422E72C1B00625807 /* UISearchBar.swift in Sources */,
|
||||
32A6001622C661100042C1D9 /* EditHistoryViewState.swift in Sources */,
|
||||
|
@ -7339,7 +7347,7 @@
|
|||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1.1.2;
|
||||
CURRENT_PROJECT_VERSION = 1.1.3;
|
||||
DEFINES_MODULE = YES;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
|
@ -7359,7 +7367,7 @@
|
|||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 1.1.2;
|
||||
MARKETING_VERSION = 1.1.3;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -7398,7 +7406,7 @@
|
|||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 1.1.2;
|
||||
CURRENT_PROJECT_VERSION = 1.1.3;
|
||||
DEFINES_MODULE = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
|
@ -7411,7 +7419,7 @@
|
|||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 1.1.2;
|
||||
MARKETING_VERSION = 1.1.3;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
6
Riot/Assets/Images.xcassets/Favourites/Contents.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
23
Riot/Assets/Images.xcassets/Favourites/favourites_empty_screen_artwork.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "favourites_empty_screen_artwork.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "favourites_empty_screen_artwork@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "favourites_empty_screen_artwork@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 85 KiB |
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "favourites_empty_screen_artwork_dark.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "favourites_empty_screen_artwork_dark@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "favourites_empty_screen_artwork_dark@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 93 KiB |
After Width: | Height: | Size: 171 KiB |
|
@ -1,17 +1,17 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "home_placeholder_artwork.png",
|
||||
"filename" : "home_empty_screen_artwork.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "home_placeholder_artwork@2x.png",
|
||||
"filename" : "home_empty_screen_artwork@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "home_placeholder_artwork@3x.png",
|
||||
"filename" : "home_empty_screen_artwork@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
BIN
Riot/Assets/Images.xcassets/Home/home_empty_screen_artwork.imageset/home_empty_screen_artwork.png
vendored
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
Riot/Assets/Images.xcassets/Home/home_empty_screen_artwork.imageset/home_empty_screen_artwork@2x.png
vendored
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
Riot/Assets/Images.xcassets/Home/home_empty_screen_artwork.imageset/home_empty_screen_artwork@3x.png
vendored
Normal file
After Width: | Height: | Size: 104 KiB |
23
Riot/Assets/Images.xcassets/Home/home_empty_screen_artwork_dark.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "home_empty_screen_artwork_dark.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "home_empty_screen_artwork_dark@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "home_empty_screen_artwork_dark@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 103 KiB |
After Width: | Height: | Size: 116 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 73 KiB |
23
Riot/Assets/Images.xcassets/People/people_empty_screen_artwork.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "people_empty_screen_artwork.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "people_empty_screen_artwork@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "people_empty_screen_artwork@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 159 KiB |
23
Riot/Assets/Images.xcassets/People/people_empty_screen_artwork_dark.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "people_empty_screen_artwork_dark.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "people_empty_screen_artwork_dark@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "people_empty_screen_artwork_dark@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 160 KiB |
23
Riot/Assets/Images.xcassets/Rooms/rooms_empty_screen_artwork.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "rooms_empty_screen_artwork.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "rooms_empty_screen_artwork@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "rooms_empty_screen_artwork@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
Riot/Assets/Images.xcassets/Rooms/rooms_empty_screen_artwork.imageset/rooms_empty_screen_artwork.png
vendored
Normal file
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 176 KiB |
23
Riot/Assets/Images.xcassets/Rooms/rooms_empty_screen_artwork_dark.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "rooms_empty_screen_artwork_dark.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "rooms_empty_screen_artwork_dark@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "rooms_empty_screen_artwork_dark@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 177 KiB |
|
@ -181,9 +181,16 @@
|
|||
"people_conversation_section" = "CONVERSATIONS";
|
||||
"people_no_conversation" = "No conversations";
|
||||
|
||||
"people_empty_view_title" = "People";
|
||||
"people_empty_view_information" = "Chat securely with anyone.
|
||||
Tap the + to start adding people.";
|
||||
|
||||
// Rooms tab
|
||||
"room_directory_no_public_room" = "No public rooms available";
|
||||
|
||||
"rooms_empty_view_title" = "Rooms";
|
||||
"rooms_empty_view_information" = "Rooms are great for any group chat, private or public. Tap the + to find existing rooms, or make new ones.";
|
||||
|
||||
// Groups tab
|
||||
"group_invite_section" = "INVITES";
|
||||
"group_section" = "COMMUNITIES";
|
||||
|
@ -1519,5 +1526,10 @@
|
|||
|
||||
// MARK: - Home
|
||||
|
||||
"home_empty_view_title" = "Welcome to Element,\n%@";
|
||||
"home_empty_view_information" = "The all-in-one secure chat app for teams, friends and organisations. Tap the \"+\" button below to add people and rooms.";
|
||||
"home_empty_view_title" = "Welcome to %@,\n%@";
|
||||
"home_empty_view_information" = "The all-in-one secure chat app for teams, friends and organisations. Tap the + button below to add people and rooms.";
|
||||
|
||||
// MARK: - Favourites
|
||||
|
||||
"favourites_empty_view_title" = "Favourite rooms and people";
|
||||
"favourites_empty_view_information" = "You can favourite a few ways - the quickest is just to press and hold. Tap the star and they’ll automatically appear here for safe keeping.";
|
||||
|
|
|
@ -1204,3 +1204,8 @@
|
|||
"less" = "Vähem";
|
||||
"secrets_setup_recovery_passphrase_summary_information" = "Jäta oma turvafraas meelde. Seda saad kasutada ligipääsuks oma krüptitud sõnumitele ja andmetele.";
|
||||
"secrets_setup_recovery_passphrase_summary_title" = "Salvesta oma turvafraas";
|
||||
"home_empty_view_information" = "Kõik ühes suhtlusrakendus rühmade, sõpruskondade ja organisatsioonide jaoks. Teiste kasutajate ka jututubade lisamiseks klõpsi plussiga nuppu.";
|
||||
|
||||
// MARK: - Home
|
||||
|
||||
"home_empty_view_title" = "Tere tulemast kasutama suhtlusrakendust Element,\n%@";
|
||||
|
|
|
@ -2,5 +2,6 @@
|
|||
"NSCameraUsageDescription" = "L'appareil photo est utilisé pour prendre des photos et des vidéos et pour passer des appels vidéo.";
|
||||
"NSPhotoLibraryUsageDescription" = "La photothèque est utilisée pour envoyer des photos et des vidéos.";
|
||||
"NSMicrophoneUsageDescription" = "Le microphone est utilisé pour prendre des vidéos et passer des appels.";
|
||||
"NSContactsUsageDescription" = "Pour découvrir vos contacts qui utilisent déjà Matrix, Element peut envoyer les adresses e-mails et les numéros de téléphone de votre carnet d’adresse à votre serveur d’identité Matrix. Si votre serveur d’identité le prend en charge, les données personnelles sont hachées avant l’envoi − vérifiez sa politique de vie privée pour plus de détails.";
|
||||
"NSContactsUsageDescription" = "Pour découvrir vos contacts qui utilisent déjà Matrix, Element peut envoyer les adresses e-mail et les numéros de téléphone de votre carnet d’adresse à votre serveur d’identité Matrix. Si votre serveur d’identité le prend en charge, les données personnelles sont hachées avant l’envoi − vérifiez sa politique de vie privée pour plus de détails.";
|
||||
"NSCalendarsUsageDescription" = "Voir vos rendez-vous prévus dans l’application.";
|
||||
"NSFaceIDUsageDescription" = "Face ID est utilisé pour accéder à votre application.";
|
||||
|
|
|
@ -1235,3 +1235,8 @@
|
|||
"secrets_recovery_reset_action_part_2" = "Redefinir tudo";
|
||||
"secrets_setup_recovery_passphrase_summary_information" = "Lembre-se da sua frase de segurança. Ela pode ser usada para desbloquear suas mensagens e dados criptografados.";
|
||||
"secrets_setup_recovery_passphrase_summary_title" = "Salve a sua frase de segurança";
|
||||
"home_empty_view_information" = "O aplicativo de conversas seguro e completo para equipes, amigos e organizações. Toque no botão \"+\" abaixo para adicionar pessoas e salas.";
|
||||
|
||||
// MARK: - Home
|
||||
|
||||
"home_empty_view_title" = "Boas-vindas ao Element,\n%@";
|
||||
|
|
|
@ -414,7 +414,7 @@
|
|||
"auth_identity_server_placeholder" = "URL (например https://vector.im)";
|
||||
"room_ongoing_conference_call_with_close" = "Текущий групповой звонок. Войдите как %@ или %@. %@.";
|
||||
"room_ongoing_conference_call_close" = "Закрыть";
|
||||
"room_conference_call_no_power" = "Вам нужно разрешение на управление конференцией в этой комнате";
|
||||
"room_conference_call_no_power" = "Вам нужно разрешение на управление конференцией в этой комнате";
|
||||
"room_preview_unlinked_email_warning" = "Это приглашение было отправлено %@, и оно не связано с этой учетной записью. Возможно, вы пожелаете войти в систему с другой учетной записью или добавить этот адрес ел.почты к вашей учетной записи.";
|
||||
"settings_labs_create_conference_with_jitsi" = "Создать групповой вызов с jitsi";
|
||||
"call_already_displayed" = "Вызов уже установлен.";
|
||||
|
@ -547,7 +547,7 @@
|
|||
"room_resource_limit_exceeded_message_contact_2_link" = "обратитесь к администратору сервиса";
|
||||
"room_resource_limit_exceeded_message_contact_3" = " для продолжения его использования.";
|
||||
"room_event_action_view_decrypted_source" = "Посмотреть расшифрованный источник";
|
||||
"room_resource_usage_limit_reached_message_1_default" = "Превышен один из ресурсных лимитов сервера, по этому ";
|
||||
"room_resource_usage_limit_reached_message_1_default" = "Превышен один из ресурсных лимитов сервера, по этому ";
|
||||
"room_resource_usage_limit_reached_message_1_monthly_active_user" = "Сервер достиг ежемесячного ограничения активных пользователей, так что ";
|
||||
"room_resource_usage_limit_reached_message_2" = "некоторые пользователи не смогут залогиниться.";
|
||||
"room_resource_usage_limit_reached_message_contact_3" = " что бы увеличить лимит.";
|
||||
|
@ -987,7 +987,7 @@
|
|||
// Room widget permissions
|
||||
"room_widget_permission_title" = "Загрузить виджет";
|
||||
"room_widget_permission_creator_info_title" = "Этот виджет был добавлен:";
|
||||
"room_widget_permission_webview_information_title" = "Использование может оставить cookie на вашем устройстве и отправить данные в %@:\n";
|
||||
"room_widget_permission_webview_information_title" = "Использование может оставить cookie на вашем устройстве и отправить данные в %@:\n";
|
||||
"room_widget_permission_information_title" = "Использование может отправить данные в %@:\n";
|
||||
"room_widget_permission_display_name_permission" = "Ваше отображаемое имя";
|
||||
"room_widget_permission_avatar_url_permission" = "URL вашего аватара";
|
||||
|
@ -1037,7 +1037,7 @@
|
|||
"device_verification_self_verify_wait_title" = "Завершите настройку безопасности";
|
||||
"device_verification_self_verify_wait_new_sign_in_title" = "Подтвердите вход";
|
||||
"device_verification_self_verify_wait_information" = "Подтвердите этот сеанс на одном из других ваших сеансов, предоставив ему доступ к зашифрованным сообщениям.\n\nИспользуйте последнюю версию Element на других ваших устройствах:";
|
||||
"device_verification_self_verify_wait_additional_information" = "или другой, поддерживаемый кросс-подпись Matrix клиент";
|
||||
"device_verification_self_verify_wait_additional_information" = "Это работает с Element и другими клиентами Matrix с поддержкой кросс-подписи.";
|
||||
"device_verification_self_verify_wait_recover_secrets_without_passphrase" = "Используйте ключ восстановления";
|
||||
"device_verification_self_verify_wait_recover_secrets_with_passphrase" = "Используйте пароль восстановления или ключ";
|
||||
"device_verification_self_verify_wait_recover_secrets_additional_information" = "Если вы не можете получить доступ к существующему сеансу";
|
||||
|
@ -1247,3 +1247,10 @@
|
|||
|
||||
"secrets_recovery_reset_action_part_1" = "Забыли или потеряли все варианты восстановления? ";
|
||||
"less" = "Меньше";
|
||||
"home_empty_view_information" = "Комплексное безопасное приложение для общения в чате для команд, друзей и организаций. Нажмите кнопку \"+\" внизу, чтобы добавить людей и комнаты.";
|
||||
|
||||
// MARK: - Home
|
||||
|
||||
"home_empty_view_title" = "Добро пожаловать в Element!\n%@";
|
||||
"secrets_setup_recovery_passphrase_summary_information" = "Запомните свою секретную фразу. Её можно использовать для разблокировки ваших зашифрованных сообщений и данных.";
|
||||
"secrets_setup_recovery_passphrase_summary_title" = "Сохраните вашу секретную фразу";
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
import Foundation
|
||||
|
||||
extension UITableViewCell {
|
||||
|
||||
private enum AccessoryImageAlpha {
|
||||
static let highlighted: CGFloat = 0.3
|
||||
}
|
||||
|
||||
/// Returns safe area insetted separator inset. Should only be used when custom constraints on custom table view cells are being set according to separator insets.
|
||||
@objc var vc_separatorInset: UIEdgeInsets {
|
||||
|
@ -30,8 +34,10 @@ extension UITableViewCell {
|
|||
}
|
||||
|
||||
@objc func vc_setAccessoryDisclosureIndicator(withTintColor tintColor: UIColor) {
|
||||
let disclosureImageView = UIImageView(image: Asset.Images.disclosureIcon.image)
|
||||
let disclosureImage = Asset.Images.disclosureIcon.image.withRenderingMode(.alwaysTemplate)
|
||||
let disclosureImageView = UIImageView(image: disclosureImage)
|
||||
disclosureImageView.tintColor = tintColor
|
||||
disclosureImageView.highlightedImage = disclosureImage.vc_withAlpha(AccessoryImageAlpha.highlighted)
|
||||
self.accessoryView = disclosureImageView
|
||||
}
|
||||
|
||||
|
|
|
@ -59,13 +59,16 @@ internal enum Asset {
|
|||
internal static let encryptionNormal = ImageAsset(name: "encryption_normal")
|
||||
internal static let encryptionTrusted = ImageAsset(name: "encryption_trusted")
|
||||
internal static let encryptionWarning = ImageAsset(name: "encryption_warning")
|
||||
internal static let favouritesEmptyScreenArtwork = ImageAsset(name: "favourites_empty_screen_artwork")
|
||||
internal static let favouritesEmptyScreenArtworkDark = ImageAsset(name: "favourites_empty_screen_artwork_dark")
|
||||
internal static let roomActionDirectChat = ImageAsset(name: "room_action_direct_chat")
|
||||
internal static let roomActionFavourite = ImageAsset(name: "room_action_favourite")
|
||||
internal static let roomActionLeave = ImageAsset(name: "room_action_leave")
|
||||
internal static let roomActionNotification = ImageAsset(name: "room_action_notification")
|
||||
internal static let roomActionPriorityHigh = ImageAsset(name: "room_action_priority_high")
|
||||
internal static let roomActionPriorityLow = ImageAsset(name: "room_action_priority_low")
|
||||
internal static let homePlaceholderArtwork = ImageAsset(name: "home_placeholder_artwork")
|
||||
internal static let homeEmptyScreenArtwork = ImageAsset(name: "home_empty_screen_artwork")
|
||||
internal static let homeEmptyScreenArtworkDark = ImageAsset(name: "home_empty_screen_artwork_dark")
|
||||
internal static let plusFloatingAction = ImageAsset(name: "plus_floating_action")
|
||||
internal static let closeBanner = ImageAsset(name: "close_banner")
|
||||
internal static let importFilesButton = ImageAsset(name: "import_files_button")
|
||||
|
@ -77,6 +80,8 @@ internal enum Asset {
|
|||
internal static let cameraStop = ImageAsset(name: "camera_stop")
|
||||
internal static let cameraVideoCapture = ImageAsset(name: "camera_video_capture")
|
||||
internal static let videoIcon = ImageAsset(name: "video_icon")
|
||||
internal static let peopleEmptyScreenArtwork = ImageAsset(name: "people_empty_screen_artwork")
|
||||
internal static let peopleEmptyScreenArtworkDark = ImageAsset(name: "people_empty_screen_artwork_dark")
|
||||
internal static let peopleFloatingAction = ImageAsset(name: "people_floating_action")
|
||||
internal static let error = ImageAsset(name: "error")
|
||||
internal static let scrolldown = ImageAsset(name: "scrolldown")
|
||||
|
@ -98,6 +103,8 @@ internal enum Asset {
|
|||
internal static let modIcon = ImageAsset(name: "mod_icon")
|
||||
internal static let moreReactions = ImageAsset(name: "more_reactions")
|
||||
internal static let scrollup = ImageAsset(name: "scrollup")
|
||||
internal static let roomsEmptyScreenArtwork = ImageAsset(name: "rooms_empty_screen_artwork")
|
||||
internal static let roomsEmptyScreenArtworkDark = ImageAsset(name: "rooms_empty_screen_artwork_dark")
|
||||
internal static let roomsFloatingAction = ImageAsset(name: "rooms_floating_action")
|
||||
internal static let userIcon = ImageAsset(name: "user_icon")
|
||||
internal static let fileDocIcon = ImageAsset(name: "file_doc_icon")
|
||||
|
|
|
@ -1230,6 +1230,14 @@ internal enum VectorL10n {
|
|||
internal static var externalLinkConfirmationTitle: String {
|
||||
return VectorL10n.tr("Vector", "external_link_confirmation_title")
|
||||
}
|
||||
/// You can favourite a few ways - the quickest is just to press and hold. Tap the star and they’ll automatically appear here for safe keeping.
|
||||
internal static var favouritesEmptyViewInformation: String {
|
||||
return VectorL10n.tr("Vector", "favourites_empty_view_information")
|
||||
}
|
||||
/// Favourite rooms and people
|
||||
internal static var favouritesEmptyViewTitle: String {
|
||||
return VectorL10n.tr("Vector", "favourites_empty_view_title")
|
||||
}
|
||||
/// File upload
|
||||
internal static var fileUploadErrorTitle: String {
|
||||
return VectorL10n.tr("Vector", "file_upload_error_title")
|
||||
|
@ -1346,13 +1354,13 @@ internal enum VectorL10n {
|
|||
internal static var groupSection: String {
|
||||
return VectorL10n.tr("Vector", "group_section")
|
||||
}
|
||||
/// The all-in-one secure chat app for teams, friends and organisations. Tap the "+" button below to add people and rooms.
|
||||
/// The all-in-one secure chat app for teams, friends and organisations. Tap the + button below to add people and rooms.
|
||||
internal static var homeEmptyViewInformation: String {
|
||||
return VectorL10n.tr("Vector", "home_empty_view_information")
|
||||
}
|
||||
/// Welcome to Element,\n%@
|
||||
internal static func homeEmptyViewTitle(_ p1: String) -> String {
|
||||
return VectorL10n.tr("Vector", "home_empty_view_title", p1)
|
||||
/// Welcome to %@,\n%@
|
||||
internal static func homeEmptyViewTitle(_ p1: String, _ p2: String) -> String {
|
||||
return VectorL10n.tr("Vector", "home_empty_view_title", p1, p2)
|
||||
}
|
||||
/// Could not connect to the homeserver.
|
||||
internal static var homeserverConnectionLost: String {
|
||||
|
@ -2018,6 +2026,14 @@ internal enum VectorL10n {
|
|||
internal static var peopleConversationSection: String {
|
||||
return VectorL10n.tr("Vector", "people_conversation_section")
|
||||
}
|
||||
/// Chat securely with anyone.\nTap the + to start adding people.
|
||||
internal static var peopleEmptyViewInformation: String {
|
||||
return VectorL10n.tr("Vector", "people_empty_view_information")
|
||||
}
|
||||
/// People
|
||||
internal static var peopleEmptyViewTitle: String {
|
||||
return VectorL10n.tr("Vector", "people_empty_view_title")
|
||||
}
|
||||
/// INVITES
|
||||
internal static var peopleInvitesSection: String {
|
||||
return VectorL10n.tr("Vector", "people_invites_section")
|
||||
|
@ -3202,6 +3218,14 @@ internal enum VectorL10n {
|
|||
internal static var roomWidgetPermissionWidgetIdPermission: String {
|
||||
return VectorL10n.tr("Vector", "room_widget_permission_widget_id_permission")
|
||||
}
|
||||
/// Rooms are great for any group chat, private or public. Tap the + to find existing rooms, or make new ones.
|
||||
internal static var roomsEmptyViewInformation: String {
|
||||
return VectorL10n.tr("Vector", "rooms_empty_view_information")
|
||||
}
|
||||
/// Rooms
|
||||
internal static var roomsEmptyViewTitle: String {
|
||||
return VectorL10n.tr("Vector", "rooms_empty_view_title")
|
||||
}
|
||||
/// Save
|
||||
internal static var save: String {
|
||||
return VectorL10n.tr("Vector", "save")
|
||||
|
|
|
@ -59,6 +59,10 @@ extern NSString *const kThemeServiceDidChangeThemeNotification;
|
|||
*/
|
||||
- (id<Theme>)themeWithThemeId:(NSString*)themeId;
|
||||
|
||||
|
||||
/// Retrun YES if the current is Dark or Black
|
||||
- (BOOL)isCurrentThemeDark;
|
||||
|
||||
#pragma mark - Riot Colors not yet themeable
|
||||
|
||||
@property (nonatomic, readonly) UIColor *riotColorCuriousBlue;
|
||||
|
|
|
@ -95,6 +95,16 @@ NSString *const kThemeServiceDidChangeThemeNotification = @"kThemeServiceDidChan
|
|||
return theme;
|
||||
}
|
||||
|
||||
- (BOOL)isCurrentThemeDark
|
||||
{
|
||||
if ([self.theme.identifier isEqualToString:@"dark"] || [self.theme.identifier isEqualToString:@"black"])
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark - Private methods
|
||||
|
||||
- (instancetype)init
|
||||
|
|
|
@ -1763,7 +1763,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
|
||||
[self configureCallManagerIfRequiredForSession:mxSession];
|
||||
|
||||
[self.configuration setupSettingsFor:mxSession];
|
||||
[self.configuration setupSettingsFor:mxSession];
|
||||
}
|
||||
else if (mxSession.state == MXSessionStateStoreDataReady)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// Copyright 2020 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension RecentsViewController {
|
||||
|
||||
@objc func canShowRoomPreview(for room: MXRoom) -> Bool {
|
||||
// Do not show room preview if room is not direct
|
||||
guard room.isDirect else {
|
||||
return false
|
||||
}
|
||||
|
||||
let membershipTransitionState = room.summary.membershipTransitionState
|
||||
|
||||
// NOTE: For the moment do not offer the possibility to show room preview when invitation action is in progress
|
||||
|
||||
switch membershipTransitionState {
|
||||
case .failedJoining, .failedLeaving:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
#import <MatrixKit/MatrixKit.h>
|
||||
|
||||
@class RootTabEmptyView;
|
||||
|
||||
@interface RecentsViewController : MXKRecentListViewController <MXKRecentListViewControllerDelegate>
|
||||
{
|
||||
@protected
|
||||
|
@ -83,6 +85,11 @@
|
|||
*/
|
||||
@property (nonatomic) NSString *screenName;
|
||||
|
||||
/**
|
||||
Empty view to display when there is no item to show on the screen.
|
||||
*/
|
||||
@property (nonatomic, weak) RootTabEmptyView *emptyView;
|
||||
|
||||
/**
|
||||
Return the sticky header for the specified section of the table view
|
||||
|
||||
|
@ -177,5 +184,17 @@
|
|||
- (void)didTapOnSectionHeader:(UIGestureRecognizer*)gestureRecognizer;
|
||||
- (void)didSwipeOnSectionHeader:(UISwipeGestureRecognizer*)gestureRecognizer;
|
||||
|
||||
#pragma mark - Empty view
|
||||
|
||||
/**
|
||||
Overrides this method to fill the empty view with data.
|
||||
*/
|
||||
- (void)updateEmptyView;
|
||||
|
||||
/**
|
||||
Overrides this method to indicate if empty view should be shown. Returns NO by default.
|
||||
*/
|
||||
- (BOOL)shouldShowEmptyView;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@
|
|||
}];
|
||||
|
||||
self.recentsSearchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;
|
||||
self.recentsSearchBar.placeholder = NSLocalizedStringFromTable(@"search_default_placeholder", @"Vector", nil);
|
||||
self.recentsSearchBar.placeholder = NSLocalizedStringFromTable(@"search_default_placeholder", @"Vector", nil);
|
||||
|
||||
// Observe user interface theme change.
|
||||
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
@ -184,6 +184,8 @@
|
|||
// Force table refresh
|
||||
[self cancelEditionMode:YES];
|
||||
}
|
||||
|
||||
[self.emptyView updateWithTheme:ThemeService.shared.theme];
|
||||
|
||||
[self setNeedsStatusBarAppearanceUpdate];
|
||||
}
|
||||
|
@ -452,6 +454,79 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void)joinRoom:(MXRoom*)room completion:(void(^)(BOOL succeed))completion
|
||||
{
|
||||
[room join:^{
|
||||
// `recentsTableView` will be reloaded `roomChangeMembershipStateDataSourceDidChangeRoomMembershipState` function
|
||||
|
||||
if (completion)
|
||||
{
|
||||
completion(YES);
|
||||
}
|
||||
|
||||
} failure:^(NSError * _Nonnull error) {
|
||||
NSLog(@"[RecentsViewController] Failed to join an invited room (%@)", room.roomId);
|
||||
[self presentRoomJoinFailedAlertForError:error completion:^{
|
||||
if (completion)
|
||||
{
|
||||
completion(NO);
|
||||
}
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)leaveRoom:(MXRoom*)room completion:(void(^)(BOOL succeed))completion
|
||||
{
|
||||
// Decline the invitation
|
||||
[room leave:^{
|
||||
|
||||
// `recentsTableView` will be reloaded `roomChangeMembershipStateDataSourceDidChangeRoomMembershipState` function
|
||||
|
||||
if (completion)
|
||||
{
|
||||
completion(YES);
|
||||
}
|
||||
} failure:^(NSError * _Nonnull error) {
|
||||
NSLog(@"[RecentsViewController] Failed to reject an invited room (%@)", room.roomId);
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
|
||||
if (completion)
|
||||
{
|
||||
completion(NO);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)presentRoomJoinFailedAlertForError:(NSError*)error completion:(void(^)(void))completion
|
||||
{
|
||||
MXWeakify(self);
|
||||
NSString *msg = [error.userInfo valueForKey:NSLocalizedDescriptionKey];
|
||||
if ([msg isEqualToString:@"No known servers"])
|
||||
{
|
||||
// minging kludge until https://matrix.org/jira/browse/SYN-678 is fixed
|
||||
// 'Error when trying to join an empty room should be more explicit'
|
||||
msg = [NSBundle mxk_localizedStringForKey:@"room_error_join_failed_empty_room"];
|
||||
}
|
||||
|
||||
[self->currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
|
||||
self->currentAlert = [UIAlertController alertControllerWithTitle:[NSBundle mxk_localizedStringForKey:@"room_error_join_failed_title"] message:msg preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"ok"]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
self->currentAlert = nil;
|
||||
|
||||
if (completion)
|
||||
{
|
||||
completion();
|
||||
}
|
||||
}]];
|
||||
|
||||
[self presentViewController:self->currentAlert animated:YES completion:nil];
|
||||
}
|
||||
|
||||
#pragma mark - Sticky Headers
|
||||
|
||||
- (void)setEnableStickyHeaders:(BOOL)enableStickyHeaders
|
||||
|
@ -820,23 +895,23 @@
|
|||
// Display the room preview
|
||||
[self dispayRoomWithRoomId:invitedRoom.roomId inMatrixSession:invitedRoom.mxSession];
|
||||
}
|
||||
else if ([actionIdentifier isEqualToString:kInviteRecentTableViewCellDeclineButtonPressed])
|
||||
else if ([actionIdentifier isEqualToString:kInviteRecentTableViewCellAcceptButtonPressed])
|
||||
{
|
||||
// Retrieve the invited room
|
||||
MXRoom *invitedRoom = userInfo[kInviteRecentTableViewCellRoomKey];
|
||||
|
||||
// Accept invitation
|
||||
[self joinRoom:invitedRoom completion:nil];
|
||||
}
|
||||
else if ([actionIdentifier isEqualToString:kInviteRecentTableViewCellDeclineButtonPressed])
|
||||
{
|
||||
// Retrieve the invited room
|
||||
MXRoom *invitedRoom = userInfo[kInviteRecentTableViewCellRoomKey];
|
||||
|
||||
[self cancelEditionMode:isRefreshPending];
|
||||
|
||||
// Decline the invitation
|
||||
[invitedRoom leave:^{
|
||||
|
||||
[self.recentsTableView reloadData];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
NSLog(@"[RecentsViewController] Failed to reject an invited room (%@)", invitedRoom.roomId);
|
||||
|
||||
}];
|
||||
[self leaveRoom:invitedRoom completion:nil];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -848,6 +923,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void)dataSource:(MXKDataSource *)dataSource didCellChange:(id)changes
|
||||
{
|
||||
[super dataSource:dataSource didCellChange:changes];
|
||||
|
||||
[self showEmptyViewIfNeeded];
|
||||
}
|
||||
|
||||
#pragma mark - Swipe actions
|
||||
|
||||
- (void)tableView:(UITableView*)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
|
@ -1271,8 +1353,21 @@
|
|||
|
||||
if ([cell isKindOfClass:[InviteRecentTableViewCell class]])
|
||||
{
|
||||
// hide the selection
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:NO];
|
||||
id<MXKRecentCellDataStoring> cellData = [self.dataSource cellDataAtIndexPath:indexPath];
|
||||
|
||||
// Retrieve the invited room
|
||||
MXRoom* invitedRoom = cellData.roomSummary.room;
|
||||
|
||||
// Check if can show preview for the invited room
|
||||
if ([self canShowRoomPreviewFor:invitedRoom])
|
||||
{
|
||||
// Display the room preview
|
||||
[self dispayRoomWithRoomId:invitedRoom.roomId inMatrixSession:invitedRoom.mxSession];
|
||||
}
|
||||
else
|
||||
{
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:NO];
|
||||
}
|
||||
}
|
||||
else if ([cell isKindOfClass:[DirectoryRecentTableViewCell class]])
|
||||
{
|
||||
|
@ -1871,4 +1966,90 @@
|
|||
coordinatorBridgePresenter = nil;
|
||||
}
|
||||
|
||||
#pragma mark - Empty view management
|
||||
|
||||
- (void)showEmptyViewIfNeeded
|
||||
{
|
||||
[self showEmptyView:[self shouldShowEmptyView]];
|
||||
}
|
||||
|
||||
- (void)showEmptyView:(BOOL)show
|
||||
{
|
||||
if (!self.viewIfLoaded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (show && !self.emptyView)
|
||||
{
|
||||
RootTabEmptyView *emptyView = [RootTabEmptyView instantiate];
|
||||
[emptyView updateWithTheme:ThemeService.shared.theme];
|
||||
[self addEmptyView:emptyView];
|
||||
|
||||
self.emptyView = emptyView;
|
||||
|
||||
[self updateEmptyView];
|
||||
}
|
||||
else if (!show)
|
||||
{
|
||||
[self.emptyView removeFromSuperview];
|
||||
}
|
||||
|
||||
self.recentsTableView.hidden = show;
|
||||
self.stickyHeadersTopContainer.hidden = show;
|
||||
self.stickyHeadersBottomContainer.hidden = show;
|
||||
}
|
||||
|
||||
- (void)updateEmptyView
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (void)addEmptyView:(RootTabEmptyView*)emptyView
|
||||
{
|
||||
if (!self.isViewLoaded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NSLayoutConstraint *emptyViewBottomConstraint;
|
||||
NSLayoutConstraint *contentViewBottomConstraint;
|
||||
|
||||
if (plusButtonImageView && plusButtonImageView.isHidden == NO)
|
||||
{
|
||||
[self.view insertSubview:emptyView belowSubview:plusButtonImageView];
|
||||
|
||||
contentViewBottomConstraint = [NSLayoutConstraint constraintWithItem:emptyView.contentView
|
||||
attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationLessThanOrEqual toItem:plusButtonImageView
|
||||
attribute:NSLayoutAttributeTop
|
||||
multiplier:1.0
|
||||
constant:0];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self.view addSubview:emptyView];
|
||||
}
|
||||
|
||||
emptyViewBottomConstraint = [emptyView.bottomAnchor constraintEqualToAnchor:emptyView.superview.bottomAnchor];
|
||||
|
||||
emptyView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
|
||||
[NSLayoutConstraint activateConstraints:@[
|
||||
[emptyView.topAnchor constraintEqualToAnchor:emptyView.superview.topAnchor],
|
||||
[emptyView.leftAnchor constraintEqualToAnchor:emptyView.superview.leftAnchor],
|
||||
[emptyView.rightAnchor constraintEqualToAnchor:emptyView.superview.rightAnchor],
|
||||
emptyViewBottomConstraint
|
||||
]];
|
||||
|
||||
if (contentViewBottomConstraint)
|
||||
{
|
||||
contentViewBottomConstraint.active = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)shouldShowEmptyView
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2020 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -17,15 +17,18 @@
|
|||
import Foundation
|
||||
import Reusable
|
||||
|
||||
/// `RootTabEmptyView` is a view to display when there is no UI item to display on a screen.
|
||||
@objcMembers
|
||||
final class HomeEmptyView: UIView, NibLoadable {
|
||||
final class RootTabEmptyView: UIView, NibLoadable {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// MARK: Outlets
|
||||
|
||||
|
||||
@IBOutlet private weak var imageView: UIImageView!
|
||||
@IBOutlet private weak var titleLabel: UILabel!
|
||||
@IBOutlet private weak var informationLabel: UILabel!
|
||||
@IBOutlet private(set) weak var contentView: UIView!
|
||||
|
||||
// MARK: Private
|
||||
|
||||
|
@ -35,8 +38,8 @@ final class HomeEmptyView: UIView, NibLoadable {
|
|||
|
||||
// MARK: - Setup
|
||||
|
||||
class func instantiate() -> HomeEmptyView {
|
||||
let view = HomeEmptyView.loadFromNib()
|
||||
class func instantiate() -> RootTabEmptyView {
|
||||
let view = RootTabEmptyView.loadFromNib()
|
||||
view.theme = ThemeService.shared().theme
|
||||
return view
|
||||
}
|
||||
|
@ -51,13 +54,15 @@ final class HomeEmptyView: UIView, NibLoadable {
|
|||
|
||||
// MARK: - Public
|
||||
|
||||
func fill(with displayName: String) {
|
||||
self.titleLabel.text = VectorL10n.homeEmptyViewTitle(displayName)
|
||||
func fill(with image: UIImage, title: String, informationText: String) {
|
||||
self.imageView.image = image
|
||||
self.titleLabel.text = title
|
||||
self.informationLabel.text = informationText
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Themable
|
||||
extension HomeEmptyView: Themable {
|
||||
extension RootTabEmptyView: Themable {
|
||||
|
||||
func update(theme: Theme) {
|
||||
self.theme = theme
|
82
Riot/Modules/Common/Recents/Views/RootTabEmptyView.xib
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17156" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina3_5" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17126"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="J88-vf-gR0" customClass="RootTabEmptyView" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="W21-Nb-gxV">
|
||||
<rect key="frame" x="0.0" y="-11" width="320" height="471"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" image="favourites_empty_screen_artwork" translatesAutoresizingMaskIntoConstraints="NO" id="GiH-8q-wk4">
|
||||
<rect key="frame" x="20" y="0.0" width="280" height="312"/>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="Favourite rooms and people" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hPm-Rh-n4I">
|
||||
<rect key="frame" x="20" y="352" width="280" height="26.5"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="22"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalCompressionResistancePriority="751" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qtf-2C-k84">
|
||||
<rect key="frame" x="20" y="394.5" width="280" height="76.5"/>
|
||||
<string key="text">You can favourite a few ways - the quickest is just to press and hold. Tap the star and they’ll automatically appear here for safe keeping.</string>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="GiH-8q-wk4" firstAttribute="centerX" secondItem="W21-Nb-gxV" secondAttribute="centerX" id="4EG-lk-E0u"/>
|
||||
<constraint firstAttribute="trailing" secondItem="hPm-Rh-n4I" secondAttribute="trailing" constant="20" id="AM8-hv-gBz"/>
|
||||
<constraint firstAttribute="height" priority="750" id="C1l-wr-eoZ"/>
|
||||
<constraint firstAttribute="width" priority="750" constant="500" id="S2l-qI-mpV"/>
|
||||
<constraint firstItem="GiH-8q-wk4" firstAttribute="top" secondItem="W21-Nb-gxV" secondAttribute="top" id="W3M-PC-qDd"/>
|
||||
<constraint firstItem="hPm-Rh-n4I" firstAttribute="leading" secondItem="W21-Nb-gxV" secondAttribute="leading" constant="20" id="hGp-9R-Kyf"/>
|
||||
<constraint firstItem="GiH-8q-wk4" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="W21-Nb-gxV" secondAttribute="leading" constant="20" id="keV-Px-gON"/>
|
||||
<constraint firstItem="qtf-2C-k84" firstAttribute="top" secondItem="hPm-Rh-n4I" secondAttribute="bottom" constant="16" id="le5-E4-ZNn"/>
|
||||
<constraint firstItem="hPm-Rh-n4I" firstAttribute="top" secondItem="GiH-8q-wk4" secondAttribute="bottom" constant="40" id="p3e-Vz-8K2"/>
|
||||
<constraint firstItem="qtf-2C-k84" firstAttribute="trailing" secondItem="hPm-Rh-n4I" secondAttribute="trailing" id="usx-iP-bVX"/>
|
||||
<constraint firstAttribute="bottom" secondItem="qtf-2C-k84" secondAttribute="bottom" id="v8S-8L-5iz"/>
|
||||
<constraint firstItem="qtf-2C-k84" firstAttribute="leading" secondItem="hPm-Rh-n4I" secondAttribute="leading" id="y4i-MQ-k9k"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="GiH-8q-wk4" secondAttribute="trailing" constant="20" id="z8B-Kv-tcM"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="90o-VV-dSQ"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="W21-Nb-gxV" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="90o-VV-dSQ" secondAttribute="leading" id="LUz-h9-rSV"/>
|
||||
<constraint firstItem="W21-Nb-gxV" firstAttribute="centerX" secondItem="90o-VV-dSQ" secondAttribute="centerX" id="qZB-eU-8py"/>
|
||||
<constraint firstItem="90o-VV-dSQ" firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="W21-Nb-gxV" secondAttribute="bottom" constant="20" id="rN5-0T-Dwi"/>
|
||||
<constraint firstItem="W21-Nb-gxV" firstAttribute="centerY" secondItem="90o-VV-dSQ" secondAttribute="centerY" priority="749" id="v8m-V6-NgZ"/>
|
||||
<constraint firstItem="90o-VV-dSQ" firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="W21-Nb-gxV" secondAttribute="trailing" id="zad-h2-2yk"/>
|
||||
</constraints>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<connections>
|
||||
<outlet property="contentView" destination="W21-Nb-gxV" id="DUU-Wg-1Dw"/>
|
||||
<outlet property="imageView" destination="GiH-8q-wk4" id="Ivi-Cn-yK8"/>
|
||||
<outlet property="informationLabel" destination="qtf-2C-k84" id="Gga-9K-vvU"/>
|
||||
<outlet property="titleLabel" destination="hPm-Rh-n4I" id="bbO-3C-WCy"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="139" y="92"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="favourites_empty_screen_artwork" width="420" height="312"/>
|
||||
<systemColor name="systemBackgroundColor">
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
|
@ -114,4 +114,42 @@
|
|||
return 0.0f;
|
||||
}
|
||||
|
||||
#pragma mark - Empty view management
|
||||
|
||||
- (void)updateEmptyView
|
||||
{
|
||||
[self.emptyView fillWith:[self emptyViewArtwork]
|
||||
title:NSLocalizedStringFromTable(@"favourites_empty_view_title", @"Vector", nil)
|
||||
informationText:NSLocalizedStringFromTable(@"favourites_empty_view_information", @"Vector", nil)];
|
||||
}
|
||||
|
||||
- (UIImage*)emptyViewArtwork
|
||||
{
|
||||
if (ThemeService.shared.isCurrentThemeDark)
|
||||
{
|
||||
return [UIImage imageNamed:@"favourites_empty_screen_artwork_dark"];
|
||||
}
|
||||
else
|
||||
{
|
||||
return [UIImage imageNamed:@"favourites_empty_screen_artwork"];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)shouldShowEmptyView
|
||||
{
|
||||
// Do not present empty screen while searching
|
||||
if (recentsDataSource.searchPatternsList.count)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
return [self totalItemCounts] == 0;
|
||||
}
|
||||
|
||||
// Total items to display on the screen
|
||||
- (NSUInteger)totalItemCounts
|
||||
{
|
||||
return recentsDataSource.favoriteCellDataArray.count;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -46,8 +46,6 @@
|
|||
@property (nonatomic, strong) CrossSigningSetupBannerCell *keyVerificationSetupBannerPrototypeCell;
|
||||
@property (nonatomic, strong) AuthenticatedSessionViewControllerFactory *authenticatedSessionViewControllerFactory;
|
||||
|
||||
@property (nonatomic, weak) HomeEmptyView *homeEmptyView;
|
||||
|
||||
@end
|
||||
|
||||
@implementation HomeViewController
|
||||
|
@ -101,9 +99,7 @@
|
|||
// Take the lead on the shared data source.
|
||||
recentsDataSource.areSectionsShrinkable = NO;
|
||||
[recentsDataSource setDelegate:self andRecentsDataSourceMode:RecentsDataSourceModeHome];
|
||||
}
|
||||
|
||||
[self updateEmptyViewDisplayName];
|
||||
}
|
||||
|
||||
[self moveAllCollectionsToLeft];
|
||||
}
|
||||
|
@ -281,28 +277,15 @@
|
|||
{
|
||||
[super onMatrixSessionChange];
|
||||
|
||||
[self updateEmptyViewDisplayName];
|
||||
}
|
||||
|
||||
- (void)userInterfaceThemeDidChange
|
||||
{
|
||||
[super userInterfaceThemeDidChange];
|
||||
|
||||
[self.homeEmptyView updateWithTheme:ThemeService.shared.theme];
|
||||
[self updateEmptyView];
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDataSource
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
||||
{
|
||||
NSInteger numberOfSections = [recentsDataSource numberOfSectionsInTableView:tableView];
|
||||
|
||||
BOOL showEmptyView = [self shouldShowEmptyView];
|
||||
|
||||
[self showEmptyView:showEmptyView];
|
||||
|
||||
// Return the actual number of sections prepared in recents dataSource.
|
||||
return numberOfSections;
|
||||
return [recentsDataSource numberOfSectionsInTableView:tableView];
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
|
@ -819,51 +802,40 @@
|
|||
|
||||
#pragma mark - Empty view management
|
||||
|
||||
- (void)showEmptyView:(BOOL)show
|
||||
{
|
||||
if (show && !self.homeEmptyView)
|
||||
{
|
||||
HomeEmptyView *homeEmptyView = [HomeEmptyView instantiate];
|
||||
[homeEmptyView updateWithTheme:ThemeService.shared.theme];
|
||||
[self addEmptyView:homeEmptyView];
|
||||
|
||||
self.homeEmptyView = homeEmptyView;
|
||||
|
||||
[self updateEmptyViewDisplayName];
|
||||
}
|
||||
else if (!show)
|
||||
{
|
||||
[self.homeEmptyView removeFromSuperview];
|
||||
}
|
||||
|
||||
self.recentsTableView.hidden = show;
|
||||
}
|
||||
|
||||
- (void)updateEmptyViewDisplayName
|
||||
- (void)updateEmptyView
|
||||
{
|
||||
MXUser *myUser = self.mainSession.myUser;
|
||||
NSString *displayName = myUser.displayname ?: myUser.userId;
|
||||
displayName = displayName ?: @"";
|
||||
|
||||
[self.homeEmptyView fillWith:displayName ?: @""];
|
||||
NSString *appName = [[NSBundle mainBundle] infoDictionary][@"CFBundleDisplayName"];
|
||||
NSString *title = [NSString stringWithFormat:NSLocalizedStringFromTable(@"home_empty_view_title", @"Vector", nil), appName, displayName];
|
||||
|
||||
[self.emptyView fillWith:[self emptyViewArtwork]
|
||||
title:title
|
||||
informationText:NSLocalizedStringFromTable(@"home_empty_view_information", @"Vector", nil)];
|
||||
}
|
||||
|
||||
- (void)addEmptyView:(UIView*)emptyView
|
||||
- (UIImage*)emptyViewArtwork
|
||||
{
|
||||
[self.view insertSubview:emptyView belowSubview:plusButtonImageView];
|
||||
|
||||
emptyView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
|
||||
[NSLayoutConstraint activateConstraints:@[
|
||||
[emptyView.topAnchor constraintEqualToAnchor:emptyView.superview.topAnchor],
|
||||
[emptyView.leftAnchor constraintEqualToAnchor:emptyView.superview.leftAnchor],
|
||||
[emptyView.rightAnchor constraintEqualToAnchor:emptyView.superview.rightAnchor],
|
||||
[emptyView.bottomAnchor constraintEqualToAnchor:plusButtonImageView.topAnchor]
|
||||
]];
|
||||
if (ThemeService.shared.isCurrentThemeDark)
|
||||
{
|
||||
return [UIImage imageNamed:@"home_empty_screen_artwork_dark"];
|
||||
}
|
||||
else
|
||||
{
|
||||
return [UIImage imageNamed:@"home_empty_screen_artwork"];
|
||||
}
|
||||
}
|
||||
|
||||
// By default on fresh account
|
||||
- (BOOL)shouldShowEmptyView
|
||||
{
|
||||
// Do not present empty screen while searching
|
||||
if (recentsDataSource.searchPatternsList.count)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Check if some banners should be displayed
|
||||
if (recentsDataSource.secureBackupBannerSection != -1 || recentsDataSource.crossSigningBannerSection != -1)
|
||||
{
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17156" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="ipad11_0rounded" orientation="portrait" layout="fullscreen" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17126"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" interfaceStyle="light" id="iN0-l3-epB" customClass="HomeEmptyView" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="834" height="1194"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="t3v-kk-6CZ">
|
||||
<rect key="frame" x="167" y="422.5" width="500" height="329"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="home_placeholder_artwork" translatesAutoresizingMaskIntoConstraints="NO" id="zqO-Va-GFE">
|
||||
<rect key="frame" x="74.5" y="0.0" width="351" height="210"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" secondItem="zqO-Va-GFE" secondAttribute="height" multiplier="117:70" id="8wR-xM-Yr6"/>
|
||||
<constraint firstAttribute="width" priority="750" constant="351" id="YYD-3y-TVU"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Welcome to Element, displayname" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bE0-ZK-O5U">
|
||||
<rect key="frame" x="20" y="244" width="460" height="26.5"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="22"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="The all-in-one secure chat app for teams, friends and organisations. Tap the + to add people and rooms." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oDI-nL-0YT">
|
||||
<rect key="frame" x="20" y="290.5" width="460" height="38.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="zqO-Va-GFE" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="t3v-kk-6CZ" secondAttribute="leading" constant="20" id="9BF-g4-67e"/>
|
||||
<constraint firstItem="bE0-ZK-O5U" firstAttribute="leading" secondItem="t3v-kk-6CZ" secondAttribute="leading" constant="20" id="Kwy-Zn-eMU"/>
|
||||
<constraint firstItem="oDI-nL-0YT" firstAttribute="leading" secondItem="bE0-ZK-O5U" secondAttribute="leading" id="S5F-Gm-C9u"/>
|
||||
<constraint firstAttribute="bottom" secondItem="oDI-nL-0YT" secondAttribute="bottom" id="b0H-Xf-aPl"/>
|
||||
<constraint firstItem="bE0-ZK-O5U" firstAttribute="top" secondItem="zqO-Va-GFE" secondAttribute="bottom" constant="34" id="bge-Ww-e17"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="zqO-Va-GFE" secondAttribute="trailing" constant="20" id="e3g-cO-CHE"/>
|
||||
<constraint firstItem="oDI-nL-0YT" firstAttribute="trailing" secondItem="bE0-ZK-O5U" secondAttribute="trailing" id="gQR-kx-Uhd"/>
|
||||
<constraint firstAttribute="width" priority="750" constant="500" id="gjt-uV-AcJ"/>
|
||||
<constraint firstItem="zqO-Va-GFE" firstAttribute="top" secondItem="t3v-kk-6CZ" secondAttribute="top" id="jy7-kx-A43"/>
|
||||
<constraint firstItem="zqO-Va-GFE" firstAttribute="centerX" secondItem="t3v-kk-6CZ" secondAttribute="centerX" id="qQk-qi-UI1"/>
|
||||
<constraint firstAttribute="trailing" secondItem="bE0-ZK-O5U" secondAttribute="trailing" constant="20" id="uk3-KG-AIo"/>
|
||||
<constraint firstItem="oDI-nL-0YT" firstAttribute="top" secondItem="bE0-ZK-O5U" secondAttribute="bottom" constant="20" id="w5K-Ws-VAa"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="t3v-kk-6CZ" firstAttribute="centerY" secondItem="vUN-kp-3ea" secondAttribute="centerY" priority="750" id="W8b-rv-ohe"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="t3v-kk-6CZ" secondAttribute="trailing" id="dMQ-uX-M5v"/>
|
||||
<constraint firstItem="t3v-kk-6CZ" firstAttribute="centerX" secondItem="vUN-kp-3ea" secondAttribute="centerX" id="kei-a8-rSq"/>
|
||||
<constraint firstItem="t3v-kk-6CZ" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="vUN-kp-3ea" secondAttribute="leading" id="nbt-PT-72V"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="t3v-kk-6CZ" secondAttribute="bottom" constant="10" id="roL-YU-0XB"/>
|
||||
</constraints>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<connections>
|
||||
<outlet property="informationLabel" destination="oDI-nL-0YT" id="8Tl-sD-IsU"/>
|
||||
<outlet property="titleLabel" destination="bE0-ZK-O5U" id="IkE-pG-HZH"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="139" y="92"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="home_placeholder_artwork" width="351" height="210"/>
|
||||
<systemColor name="systemBackgroundColor">
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
|
@ -461,4 +461,71 @@
|
|||
[super searchBarCancelButtonClicked:searchBar];
|
||||
}
|
||||
|
||||
#pragma mark - Empty view management
|
||||
|
||||
- (void)updateEmptyView
|
||||
{
|
||||
[self.emptyView fillWith:[self emptyViewArtwork]
|
||||
title:NSLocalizedStringFromTable(@"people_empty_view_title", @"Vector", nil)
|
||||
informationText:NSLocalizedStringFromTable(@"people_empty_view_information", @"Vector", nil)];
|
||||
}
|
||||
|
||||
- (UIImage*)emptyViewArtwork
|
||||
{
|
||||
if (ThemeService.shared.isCurrentThemeDark)
|
||||
{
|
||||
return [UIImage imageNamed:@"people_empty_screen_artwork_dark"];
|
||||
}
|
||||
else
|
||||
{
|
||||
return [UIImage imageNamed:@"people_empty_screen_artwork"];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)shouldShowEmptyView
|
||||
{
|
||||
// Do not present empty screen while searching
|
||||
if (recentsDataSource.searchPatternsList.count)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
return [self totalItemCounts] == 0;
|
||||
}
|
||||
|
||||
// Total items to display on the screen
|
||||
- (NSUInteger)totalItemCounts
|
||||
{
|
||||
return recentsDataSource.invitesCellDataArray.count
|
||||
+ recentsDataSource.conversationCellDataArray.count
|
||||
+ recentsDataSource.peopleCellDataArray.count
|
||||
+ [self numberOfContactsInContactsDataSource];
|
||||
}
|
||||
|
||||
- (NSUInteger)numberOfContactsInContactsDataSource
|
||||
{
|
||||
BOOL areLocalContactsAccessAuthorized = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts] == CNAuthorizationStatusAuthorized;
|
||||
|
||||
NSInteger nbOfItemsInContactDataSource = 0;
|
||||
|
||||
for (NSInteger i = 0; i < contactsSectionNumber; i++)
|
||||
{
|
||||
nbOfItemsInContactDataSource += [contactsDataSource tableView:self.recentsTableView numberOfRowsInSection:i];
|
||||
}
|
||||
|
||||
NSInteger numberOfContactsInContactsDataSource;
|
||||
|
||||
// No local contacts to show and no search in directory
|
||||
if (!areLocalContactsAccessAuthorized && contactsSectionNumber == 1 && nbOfItemsInContactDataSource <= 1)
|
||||
{
|
||||
numberOfContactsInContactsDataSource = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
numberOfContactsInContactsDataSource = nbOfItemsInContactDataSource;
|
||||
}
|
||||
|
||||
return numberOfContactsInContactsDataSource;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
//
|
||||
// Copyright 2020 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension InviteRecentTableViewCell {
|
||||
|
||||
@objc func resetButtonViews() {
|
||||
self.leftButton.isEnabled = true
|
||||
self.rightButton.isEnabled = true
|
||||
self.leftButtonActivityIndicator.stopAnimating()
|
||||
self.rightButtonActivityIndicator.stopAnimating()
|
||||
}
|
||||
|
||||
/// Update buttons according to current MXMembershipChangeState of the room
|
||||
@objc func updateButtonViews(with room: MXRoom) {
|
||||
let membershipTransitionState = room.summary.membershipTransitionState
|
||||
|
||||
var joinButtonIsLoading = false
|
||||
var leaveButtonIsLoading = false
|
||||
|
||||
switch membershipTransitionState {
|
||||
case .joining:
|
||||
joinButtonIsLoading = true
|
||||
case .leaving:
|
||||
leaveButtonIsLoading = true
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
let areButtonsEnabled = !(joinButtonIsLoading || leaveButtonIsLoading)
|
||||
|
||||
self.leftButton.isEnabled = areButtonsEnabled
|
||||
self.rightButton.isEnabled = areButtonsEnabled
|
||||
|
||||
if leaveButtonIsLoading {
|
||||
self.leftButtonActivityIndicator.startAnimating()
|
||||
} else {
|
||||
self.leftButtonActivityIndicator.stopAnimating()
|
||||
}
|
||||
|
||||
if joinButtonIsLoading {
|
||||
self.rightButtonActivityIndicator.startAnimating()
|
||||
} else {
|
||||
self.rightButtonActivityIndicator.stopAnimating()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,6 +25,13 @@
|
|||
*/
|
||||
extern NSString *const kInviteRecentTableViewCellPreviewButtonPressed;
|
||||
|
||||
/**
|
||||
Action identifier used when the user pressed 'accept' button displayed on room invitation.
|
||||
|
||||
The `userInfo` dictionary contains an `MXRoom` object under the `kInviteRecentTableViewCellRoomKey` key, representing the room of the invitation.
|
||||
*/
|
||||
extern NSString *const kInviteRecentTableViewCellAcceptButtonPressed;
|
||||
|
||||
/**
|
||||
Action identifier used when the user pressed 'decline' button displayed on room invitation.
|
||||
|
||||
|
@ -45,6 +52,9 @@ extern NSString *const kInviteRecentTableViewCellRoomKey;
|
|||
@property (weak, nonatomic) IBOutlet UIButton *leftButton;
|
||||
@property (weak, nonatomic) IBOutlet UIButton *rightButton;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *leftButtonActivityIndicator;
|
||||
@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *rightButtonActivityIndicator;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIView *noticeBadgeView;
|
||||
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#pragma mark - Constant definitions
|
||||
|
||||
NSString *const kInviteRecentTableViewCellAcceptButtonPressed = @"kInviteRecentTableViewCellAcceptButtonPressed";
|
||||
NSString *const kInviteRecentTableViewCellPreviewButtonPressed = @"kInviteRecentTableViewCellPreviewButtonPressed";
|
||||
NSString *const kInviteRecentTableViewCellDeclineButtonPressed = @"kInviteRecentTableViewCellDeclineButtonPressed";
|
||||
|
||||
|
@ -42,14 +43,12 @@ NSString *const kInviteRecentTableViewCellRoomKey = @"kInviteRecentTableViewCell
|
|||
[self.leftButton.layer setCornerRadius:5];
|
||||
self.leftButton.clipsToBounds = YES;
|
||||
[self.leftButton setTitle:NSLocalizedStringFromTable(@"decline", @"Vector", nil) forState:UIControlStateNormal];
|
||||
[self.leftButton setTitle:NSLocalizedStringFromTable(@"decline", @"Vector", nil) forState:UIControlStateHighlighted];
|
||||
[self.leftButton addTarget:self action:@selector(onDeclinePressed:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
[self.rightButton.layer setCornerRadius:5];
|
||||
self.rightButton.clipsToBounds = YES;
|
||||
[self.rightButton setTitle:NSLocalizedStringFromTable(@"preview", @"Vector", nil) forState:UIControlStateNormal];
|
||||
[self.rightButton setTitle:NSLocalizedStringFromTable(@"preview", @"Vector", nil) forState:UIControlStateHighlighted];
|
||||
[self.rightButton addTarget:self action:@selector(onPreviewPressed:) forControlEvents:UIControlEventTouchUpInside];
|
||||
[self.rightButton setTitle:NSLocalizedStringFromTable(@"accept", @"Vector", nil) forState:UIControlStateNormal];
|
||||
[self.rightButton addTarget:self action:@selector(onRightButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
[self.noticeBadgeView.layer setCornerRadius:10];
|
||||
|
||||
|
@ -66,20 +65,29 @@ NSString *const kInviteRecentTableViewCellRoomKey = @"kInviteRecentTableViewCell
|
|||
self.noticeBadgeView.backgroundColor = ThemeService.shared.theme.noticeColor;
|
||||
}
|
||||
|
||||
- (void)onDeclinePressed:(id)sender
|
||||
- (void)prepareForReuse
|
||||
{
|
||||
if (self.delegate)
|
||||
{
|
||||
MXRoom *room = roomCellData.roomSummary.room;
|
||||
|
||||
if (room)
|
||||
{
|
||||
[self.delegate cell:self didRecognizeAction:kInviteRecentTableViewCellDeclineButtonPressed userInfo:@{kInviteRecentTableViewCellRoomKey:room}];
|
||||
}
|
||||
}
|
||||
[super prepareForReuse];
|
||||
|
||||
[self resetButtonViews];
|
||||
self.accessoryView = nil;
|
||||
}
|
||||
|
||||
- (void)onPreviewPressed:(id)sender
|
||||
- (void)onDeclinePressed:(id)sender
|
||||
{
|
||||
[self notifyDelegateWithActionIdentifier:kInviteRecentTableViewCellDeclineButtonPressed];
|
||||
}
|
||||
|
||||
- (void)onRightButtonPressed:(id)sender
|
||||
{
|
||||
MXRoom *room = roomCellData.roomSummary.room;
|
||||
|
||||
NSString *actionIdentifier = room.isDirect ? kInviteRecentTableViewCellAcceptButtonPressed : kInviteRecentTableViewCellPreviewButtonPressed;
|
||||
|
||||
[self notifyDelegateWithActionIdentifier:actionIdentifier];
|
||||
}
|
||||
|
||||
- (void)notifyDelegateWithActionIdentifier:(NSString*)actionIdentifier
|
||||
{
|
||||
if (self.delegate)
|
||||
{
|
||||
|
@ -87,7 +95,7 @@ NSString *const kInviteRecentTableViewCellRoomKey = @"kInviteRecentTableViewCell
|
|||
|
||||
if (room)
|
||||
{
|
||||
[self.delegate cell:self didRecognizeAction:kInviteRecentTableViewCellPreviewButtonPressed userInfo:@{kInviteRecentTableViewCellRoomKey:room}];
|
||||
[self.delegate cell:self didRecognizeAction:actionIdentifier userInfo:@{kInviteRecentTableViewCellRoomKey:room}];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,6 +103,33 @@ NSString *const kInviteRecentTableViewCellRoomKey = @"kInviteRecentTableViewCell
|
|||
- (void)render:(MXKCellData *)cellData
|
||||
{
|
||||
[super render:cellData];
|
||||
|
||||
MXRoom *room = roomCellData.roomSummary.room;
|
||||
|
||||
if (room.roomId)
|
||||
{
|
||||
[self updateViewsWithRoom:room showPreviewButton:NO];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateViewsWithRoom:(MXRoom*)room showPreviewButton:(BOOL)showPreviewButton
|
||||
{
|
||||
NSString *rightButtonTitle;
|
||||
|
||||
if (!showPreviewButton)
|
||||
{
|
||||
rightButtonTitle = NSLocalizedStringFromTable(@"accept", @"Vector", nil);
|
||||
[self vc_setAccessoryDisclosureIndicatorWithCurrentTheme];
|
||||
}
|
||||
else
|
||||
{
|
||||
rightButtonTitle = NSLocalizedStringFromTable(@"preview", @"Vector", nil);
|
||||
self.accessoryView = nil;
|
||||
}
|
||||
|
||||
[self.rightButton setTitle:rightButtonTitle forState:UIControlStateNormal];
|
||||
|
||||
[self updateButtonViewsWith:room];
|
||||
}
|
||||
|
||||
+ (CGFloat)heightForCellData:(MXKCellData *)cellData withMaximumWidth:(CGFloat)maxWidth
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17156" 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="14088"/>
|
||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17126"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
|
@ -16,7 +13,7 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="600" height="105"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="L2L-l5-wPx" id="aXz-IR-jj5">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="104.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="105"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="RX5-eD-c3c" userLabel="Room avatar" customClass="MXKImageView">
|
||||
|
@ -33,7 +30,7 @@
|
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="RoomTitle" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Lg1-xQ-AGn">
|
||||
<rect key="frame" x="69" y="14" width="79" height="21"/>
|
||||
<rect key="frame" x="69" y="14" width="78" height="21"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="TitleLabel"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="21" id="BeP-eL-JKM"/>
|
||||
|
@ -55,8 +52,8 @@
|
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tjf-WP-vTl" userLabel="buttonsContainer">
|
||||
<rect key="frame" x="68" y="65" width="478" height="30"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Fc3-Id-aaG" userLabel="Left Button">
|
||||
<rect key="frame" x="0.0" y="0.0" width="229" height="30"/>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Fc3-Id-aaG" userLabel="Left Button">
|
||||
<rect key="frame" x="0.0" y="0.0" width="229.5" height="30"/>
|
||||
<color key="backgroundColor" red="0.028153735480000001" green="0.82494870580000002" blue="0.051896891280000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="LeftButton"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="16"/>
|
||||
|
@ -64,8 +61,8 @@
|
|||
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="lGf-lB-FsE" userLabel="Right Button">
|
||||
<rect key="frame" x="249" y="0.0" width="229" height="30"/>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="lGf-lB-FsE" userLabel="Right Button">
|
||||
<rect key="frame" x="248.5" y="0.0" width="229.5" height="30"/>
|
||||
<color key="backgroundColor" red="0.028153735480000001" green="0.82494870580000002" blue="0.051896891280000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="RightButton"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="16"/>
|
||||
|
@ -73,16 +70,26 @@
|
|||
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
</button>
|
||||
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="medium" translatesAutoresizingMaskIntoConstraints="NO" id="CzJ-mZ-Ryu">
|
||||
<rect key="frame" x="104.5" y="5" width="20" height="20"/>
|
||||
</activityIndicatorView>
|
||||
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="medium" translatesAutoresizingMaskIntoConstraints="NO" id="f3G-yI-qc9">
|
||||
<rect key="frame" x="353.5" y="5" width="20" height="20"/>
|
||||
</activityIndicatorView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="lGf-lB-FsE" firstAttribute="width" secondItem="tjf-WP-vTl" secondAttribute="width" multiplier="0.48" id="5fb-f6-oS3"/>
|
||||
<constraint firstItem="Fc3-Id-aaG" firstAttribute="leading" secondItem="tjf-WP-vTl" secondAttribute="leading" id="5x7-DE-zYg"/>
|
||||
<constraint firstItem="f3G-yI-qc9" firstAttribute="centerY" secondItem="lGf-lB-FsE" secondAttribute="centerY" id="9Yy-DW-vZP"/>
|
||||
<constraint firstItem="lGf-lB-FsE" firstAttribute="height" secondItem="tjf-WP-vTl" secondAttribute="height" id="QaA-wP-PHx"/>
|
||||
<constraint firstAttribute="trailing" secondItem="lGf-lB-FsE" secondAttribute="trailing" id="S8h-oW-Egj"/>
|
||||
<constraint firstItem="Fc3-Id-aaG" firstAttribute="height" secondItem="tjf-WP-vTl" secondAttribute="height" id="T0D-Z8-Iap"/>
|
||||
<constraint firstItem="CzJ-mZ-Ryu" firstAttribute="centerY" secondItem="Fc3-Id-aaG" secondAttribute="centerY" id="Yjd-zv-BcY"/>
|
||||
<constraint firstItem="lGf-lB-FsE" firstAttribute="top" secondItem="tjf-WP-vTl" secondAttribute="top" id="Zst-Zf-1kd"/>
|
||||
<constraint firstItem="Fc3-Id-aaG" firstAttribute="width" secondItem="tjf-WP-vTl" secondAttribute="width" multiplier="0.48" id="b8E-xg-a44"/>
|
||||
<constraint firstItem="CzJ-mZ-Ryu" firstAttribute="centerX" secondItem="Fc3-Id-aaG" secondAttribute="centerX" id="cAm-MG-goF"/>
|
||||
<constraint firstAttribute="height" constant="30" id="lTf-u3-Z4R"/>
|
||||
<constraint firstItem="f3G-yI-qc9" firstAttribute="centerX" secondItem="lGf-lB-FsE" secondAttribute="centerX" id="oa9-ji-H4n"/>
|
||||
<constraint firstItem="Fc3-Id-aaG" firstAttribute="top" secondItem="tjf-WP-vTl" secondAttribute="top" id="rLo-t4-61H"/>
|
||||
</constraints>
|
||||
</view>
|
||||
|
@ -90,7 +97,7 @@
|
|||
<rect key="frame" x="563" y="14" width="27" height="20"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="!" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ztl-w2-d20">
|
||||
<rect key="frame" x="11" y="2" width="5" height="17"/>
|
||||
<rect key="frame" x="11" y="1.5" width="5" height="17"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="14"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
|
@ -106,7 +113,7 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="e2e_verified" translatesAutoresizingMaskIntoConstraints="NO" id="hVY-f3-80Y">
|
||||
<rect key="frame" x="50" y="42" width="11" height="13"/>
|
||||
<rect key="frame" x="50" y="42.5" width="11" height="13"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="EncryptedRoomIcon"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="11" id="0fX-ec-zEX"/>
|
||||
|
@ -145,11 +152,14 @@
|
|||
<outlet property="encryptedRoomIcon" destination="hVY-f3-80Y" id="wyu-Sn-VaV"/>
|
||||
<outlet property="lastEventDescription" destination="dQt-mN-T6b" id="MSz-h1-cAL"/>
|
||||
<outlet property="leftButton" destination="Fc3-Id-aaG" id="cx4-98-B32"/>
|
||||
<outlet property="leftButtonActivityIndicator" destination="CzJ-mZ-Ryu" id="4Jt-iD-QeD"/>
|
||||
<outlet property="noticeBadgeView" destination="gCG-UR-b2u" id="hTT-qW-DMa"/>
|
||||
<outlet property="rightButton" destination="lGf-lB-FsE" id="DDr-zp-yX9"/>
|
||||
<outlet property="rightButtonActivityIndicator" destination="f3G-yI-qc9" id="4gn-jb-wdm"/>
|
||||
<outlet property="roomAvatar" destination="RX5-eD-c3c" id="dIC-8p-inL"/>
|
||||
<outlet property="roomTitle" destination="Lg1-xQ-AGn" id="q7Q-TM-5C8"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="-45" y="122"/>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
<resources>
|
||||
|
|
|
@ -36,9 +36,7 @@ final class RoomCreationModalCoordinatorBridgePresenter: NSObject {
|
|||
private let bubbleData: MXKRoomBubbleCellDataStoring
|
||||
private var coordinator: RoomCreationEventsModalCoordinator?
|
||||
private lazy var slidingModalPresenter: SlidingModalPresenter = {
|
||||
let presenter = SlidingModalPresenter()
|
||||
presenter.isSpanning = true
|
||||
return presenter
|
||||
return SlidingModalPresenter()
|
||||
}()
|
||||
|
||||
// MARK: Public
|
||||
|
@ -64,6 +62,7 @@ final class RoomCreationModalCoordinatorBridgePresenter: NSObject {
|
|||
slidingModalPresenter.present(roomCreationEventsModalCoordinator.toSlidingModalPresentable(),
|
||||
from: viewController,
|
||||
animated: animated,
|
||||
options: .spanning,
|
||||
completion: nil)
|
||||
|
||||
roomCreationEventsModalCoordinator.start()
|
||||
|
|
|
@ -2711,113 +2711,116 @@
|
|||
}
|
||||
}
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_report", @"Vector", nil)
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
if (![selectedEvent.sender isEqualToString:self.mainSession.myUser.userId])
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_report", @"Vector", nil)
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
[self cancelEventSelection];
|
||||
|
||||
// Prompt user to enter a description of the problem content.
|
||||
self->currentAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"room_event_action_report_prompt_reason", @"Vector", nil) message:nil preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[self->currentAlert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
|
||||
textField.secureTextEntry = NO;
|
||||
textField.placeholder = nil;
|
||||
textField.keyboardType = UIKeyboardTypeDefault;
|
||||
}];
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"ok"] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
NSString *text = [self->currentAlert textFields].firstObject.text;
|
||||
self->currentAlert = nil;
|
||||
[self cancelEventSelection];
|
||||
|
||||
// Prompt user to enter a description of the problem content.
|
||||
self->currentAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"room_event_action_report_prompt_reason", @"Vector", nil) message:nil preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[self->currentAlert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
|
||||
textField.secureTextEntry = NO;
|
||||
textField.placeholder = nil;
|
||||
textField.keyboardType = UIKeyboardTypeDefault;
|
||||
}];
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"ok"] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
|
||||
[self startActivityIndicator];
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
NSString *text = [self->currentAlert textFields].firstObject.text;
|
||||
self->currentAlert = nil;
|
||||
|
||||
[self startActivityIndicator];
|
||||
|
||||
[self.roomDataSource.room reportEvent:selectedEvent.eventId score:-100 reason:text success:^{
|
||||
|
||||
__strong __typeof(weakSelf)self = weakSelf;
|
||||
[self stopActivityIndicator];
|
||||
|
||||
// Prompt user to ignore content from this user
|
||||
self->currentAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"room_event_action_report_prompt_ignore_user", @"Vector", nil) message:nil preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"yes"] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
self->currentAlert = nil;
|
||||
|
||||
[self startActivityIndicator];
|
||||
|
||||
// Add the user to the blacklist: ignored users
|
||||
[self.mainSession ignoreUsers:@[selectedEvent.sender] success:^{
|
||||
|
||||
__strong __typeof(weakSelf)self = weakSelf;
|
||||
[self stopActivityIndicator];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
__strong __typeof(weakSelf)self = weakSelf;
|
||||
[self stopActivityIndicator];
|
||||
|
||||
NSLog(@"[RoomVC] Ignore user (%@) failed", selectedEvent.sender);
|
||||
//Alert user
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
|
||||
}];
|
||||
}
|
||||
|
||||
}]];
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"no"] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
self->currentAlert = nil;
|
||||
}
|
||||
|
||||
}]];
|
||||
|
||||
[self presentViewController:self->currentAlert animated:YES completion:nil];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
__strong __typeof(weakSelf)self = weakSelf;
|
||||
[self stopActivityIndicator];
|
||||
|
||||
NSLog(@"[RoomVC] Report event (%@) failed", selectedEvent.eventId);
|
||||
//Alert user
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
|
||||
}];
|
||||
}
|
||||
|
||||
[self.roomDataSource.room reportEvent:selectedEvent.eventId score:-100 reason:text success:^{
|
||||
|
||||
__strong __typeof(weakSelf)self = weakSelf;
|
||||
[self stopActivityIndicator];
|
||||
|
||||
// Prompt user to ignore content from this user
|
||||
self->currentAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"room_event_action_report_prompt_ignore_user", @"Vector", nil) message:nil preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"yes"] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
self->currentAlert = nil;
|
||||
|
||||
[self startActivityIndicator];
|
||||
|
||||
// Add the user to the blacklist: ignored users
|
||||
[self.mainSession ignoreUsers:@[selectedEvent.sender] success:^{
|
||||
|
||||
__strong __typeof(weakSelf)self = weakSelf;
|
||||
[self stopActivityIndicator];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
__strong __typeof(weakSelf)self = weakSelf;
|
||||
[self stopActivityIndicator];
|
||||
|
||||
NSLog(@"[RoomVC] Ignore user (%@) failed", selectedEvent.sender);
|
||||
//Alert user
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
|
||||
}];
|
||||
}
|
||||
|
||||
}]];
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"no"] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
self->currentAlert = nil;
|
||||
}
|
||||
|
||||
}]];
|
||||
|
||||
[self presentViewController:self->currentAlert animated:YES completion:nil];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
__strong __typeof(weakSelf)self = weakSelf;
|
||||
[self stopActivityIndicator];
|
||||
|
||||
NSLog(@"[RoomVC] Report event (%@) failed", selectedEvent.eventId);
|
||||
//Alert user
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
|
||||
}];
|
||||
}
|
||||
}]];
|
||||
|
||||
}]];
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
self->currentAlert = nil;
|
||||
}
|
||||
|
||||
}]];
|
||||
|
||||
[self presentViewController:self->currentAlert animated:YES completion:nil];
|
||||
}
|
||||
|
||||
[self->currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
self->currentAlert = nil;
|
||||
}
|
||||
|
||||
}]];
|
||||
}]];
|
||||
}
|
||||
|
||||
[self presentViewController:self->currentAlert animated:YES completion:nil];
|
||||
}
|
||||
|
||||
}]];
|
||||
|
||||
if (self.roomDataSource.room.summary.isEncrypted)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_view_encryption", @"Vector", nil)
|
||||
|
|
|
@ -375,4 +375,45 @@
|
|||
self.roomsDirectoryCoordinatorBridgePresenter = nil;
|
||||
}
|
||||
|
||||
#pragma mark - Empty view management
|
||||
|
||||
- (void)updateEmptyView
|
||||
{
|
||||
[self.emptyView fillWith:[self emptyViewArtwork]
|
||||
title:NSLocalizedStringFromTable(@"rooms_empty_view_title", @"Vector", nil)
|
||||
informationText:NSLocalizedStringFromTable(@"rooms_empty_view_information", @"Vector", nil)];
|
||||
}
|
||||
|
||||
- (UIImage*)emptyViewArtwork
|
||||
{
|
||||
if (ThemeService.shared.isCurrentThemeDark)
|
||||
{
|
||||
return [UIImage imageNamed:@"rooms_empty_screen_artwork_dark"];
|
||||
}
|
||||
else
|
||||
{
|
||||
return [UIImage imageNamed:@"rooms_empty_screen_artwork"];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)shouldShowEmptyView
|
||||
{
|
||||
// Do not present empty screen while searching
|
||||
if (recentsDataSource.searchPatternsList.count)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Otherwise check the number of items to display
|
||||
return [self totalItemCounts] == 0;
|
||||
}
|
||||
|
||||
// Total items to display on the screen
|
||||
- (NSUInteger)totalItemCounts
|
||||
{
|
||||
return recentsDataSource.conversationCellDataArray.count
|
||||
+ recentsDataSource.publicRoomsDirectoryDataSource.roomsCount
|
||||
+ recentsDataSource.invitesCellDataArray.count;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -39,6 +39,23 @@ class SlidingModalContainerView: UIView, Themable, NibLoadable {
|
|||
|
||||
// MARK: - Properties
|
||||
|
||||
private weak var blurView: UIVisualEffectView?
|
||||
var blurBackground: Bool = false {
|
||||
didSet {
|
||||
if blurBackground {
|
||||
let blurView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
|
||||
blurView.frame = self.dimmingView.bounds
|
||||
blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||
self.dimmingView.addSubview(blurView)
|
||||
self.blurView = blurView
|
||||
self.dimmingView.backgroundColor = .clear
|
||||
} else {
|
||||
self.blurView?.removeFromSuperview()
|
||||
self.dimmingView.backgroundColor = UIColor.black.withAlphaComponent(Constants.dimmingColorAlpha)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Outlets
|
||||
|
||||
@IBOutlet private weak var dimmingView: UIView!
|
||||
|
@ -61,6 +78,9 @@ class SlidingModalContainerView: UIView, Themable, NibLoadable {
|
|||
return -(self.contentViewHeightConstraint.constant + bottomSafeAreaHeight)
|
||||
}
|
||||
|
||||
// used to avoid changing constraint during animations
|
||||
private var lastBounds: CGRect?
|
||||
|
||||
// MARK: Public
|
||||
|
||||
var contentViewFrame: CGRect {
|
||||
|
@ -92,12 +112,26 @@ class SlidingModalContainerView: UIView, Themable, NibLoadable {
|
|||
super.layoutSubviews()
|
||||
|
||||
self.contentView.layer.cornerRadius = Constants.cornerRadius
|
||||
|
||||
guard lastBounds != nil else {
|
||||
lastBounds = bounds
|
||||
return
|
||||
}
|
||||
|
||||
if UIDevice.current.userInterfaceIdiom == .pad && lastBounds != bounds {
|
||||
lastBounds = bounds
|
||||
self.contentViewBottomConstraint.constant = (UIScreen.main.bounds.height + self.dismissContentViewBottomConstant) / 2
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func preparePresentAnimation() {
|
||||
self.contentViewBottomConstraint.constant = 0
|
||||
if UIDevice.current.userInterfaceIdiom == .pad {
|
||||
self.contentViewBottomConstraint.constant = (UIScreen.main.bounds.height + self.dismissContentViewBottomConstant) / 2
|
||||
} else {
|
||||
self.contentViewBottomConstraint.constant = 0
|
||||
}
|
||||
}
|
||||
|
||||
func prepareDismissAnimation() {
|
||||
|
|
|
@ -30,6 +30,7 @@ final class SlidingModalPresentationAnimator: NSObject {
|
|||
|
||||
private let isPresenting: Bool
|
||||
private let isSpanning: Bool
|
||||
private let blurBackground: Bool
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
|
@ -37,9 +38,10 @@ final class SlidingModalPresentationAnimator: NSObject {
|
|||
///
|
||||
/// - Parameter isPresenting: true to animate presentation or false to animate dismissal
|
||||
/// - Parameter isSpanning: true to remove left, bottom and right spaces between the screen edges and the content view
|
||||
required public init(isPresenting: Bool, isSpanning: Bool) {
|
||||
required public init(isPresenting: Bool, isSpanning: Bool, blurBackground: Bool) {
|
||||
self.isPresenting = isPresenting
|
||||
self.isSpanning = isSpanning
|
||||
self.blurBackground = blurBackground
|
||||
super.init()
|
||||
}
|
||||
|
||||
|
@ -58,7 +60,9 @@ final class SlidingModalPresentationAnimator: NSObject {
|
|||
|
||||
let containerView = transitionContext.containerView
|
||||
|
||||
let slidingModalContainerView = isSpanning ? SpanningSlidingModalContainerView.instantiate() : SlidingModalContainerView.instantiate()
|
||||
// Spanning not available for iPad
|
||||
let slidingModalContainerView = isSpanning && UIDevice.current.userInterfaceIdiom != .pad ? SpanningSlidingModalContainerView.instantiate() : SlidingModalContainerView.instantiate()
|
||||
slidingModalContainerView.blurBackground = self.blurBackground
|
||||
slidingModalContainerView.alpha = 0
|
||||
slidingModalContainerView.updateDimmingViewAlpha(0.0)
|
||||
|
||||
|
|
|
@ -19,9 +19,11 @@ import Foundation
|
|||
/// `SlidingModalPresentationDelegate` handle a custom sliding UIViewController transition.
|
||||
public class SlidingModalPresentationDelegate: NSObject {
|
||||
private let isSpanning: Bool
|
||||
private let blurBackground: Bool
|
||||
|
||||
public init(isSpanning: Bool) {
|
||||
public init(isSpanning: Bool, blurBackground: Bool) {
|
||||
self.isSpanning = isSpanning
|
||||
self.blurBackground = blurBackground
|
||||
super.init()
|
||||
}
|
||||
}
|
||||
|
@ -30,11 +32,11 @@ public class SlidingModalPresentationDelegate: NSObject {
|
|||
extension SlidingModalPresentationDelegate: UIViewControllerTransitioningDelegate {
|
||||
|
||||
public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
|
||||
return SlidingModalPresentationAnimator(isPresenting: true, isSpanning: isSpanning)
|
||||
return SlidingModalPresentationAnimator(isPresenting: true, isSpanning: isSpanning, blurBackground: blurBackground)
|
||||
}
|
||||
|
||||
public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
|
||||
return SlidingModalPresentationAnimator(isPresenting: false, isSpanning: isSpanning)
|
||||
return SlidingModalPresentationAnimator(isPresenting: false, isSpanning: isSpanning, blurBackground: blurBackground)
|
||||
}
|
||||
|
||||
public func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
|
||||
|
|
|
@ -16,6 +16,16 @@
|
|||
|
||||
import UIKit
|
||||
|
||||
/// Availbale options for present method
|
||||
struct SlidingModalOption: OptionSet {
|
||||
let rawValue: UInt32
|
||||
|
||||
/// Is content view spanning the screen width and to the bottom
|
||||
static let spanning = SlidingModalOption(rawValue: 1 << 0)
|
||||
/// the background is blurred in order to obfuscate the view behind the popup
|
||||
static let blurBackground = SlidingModalOption(rawValue: 1 << 1)
|
||||
}
|
||||
|
||||
/// `SlidingModalPresenter` allows to present a custom UIViewController or UIView conforming to `SlidingModalPresentable` as a modal with a vertical sliding animation from a UIViewController.
|
||||
final class SlidingModalPresenter: NSObject {
|
||||
|
||||
|
@ -28,38 +38,41 @@ final class SlidingModalPresenter: NSObject {
|
|||
}
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
|
||||
// swiftlint:disable weak_delegate
|
||||
private var transitionDelegate: SlidingModalPresentationDelegate?
|
||||
// swiftlint:enable weak_delegate
|
||||
private weak var presentingViewController: UIViewController?
|
||||
|
||||
/// Is content view spanning the screen width and to the bottom
|
||||
var isSpanning: Bool = false
|
||||
|
||||
// MARK: - Presentation options
|
||||
|
||||
@objc static let NoOption: UInt32 = 0
|
||||
@objc static let SpanningOption: UInt32 = SlidingModalOption.spanning.rawValue
|
||||
@objc static let BlurBackgroungOption: UInt32 = SlidingModalOption.blurBackground.rawValue
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
@objc func present(_ viewController: SlidingModalPresentable.ViewControllerType, from presentingViewController: UIViewController, animated: Bool, completion: (() -> Void)?) {
|
||||
self.present(viewController, from: presentingViewController, animated: animated, options: [], completion: completion)
|
||||
}
|
||||
|
||||
@objc func present(_ viewController: SlidingModalPresentable.ViewControllerType, from presentingViewController: UIViewController, animated: Bool, options: UInt32, completion: (() -> Void)?) {
|
||||
self.present(viewController, from: presentingViewController, animated: animated, options: SlidingModalOption(rawValue: options), completion: completion)
|
||||
}
|
||||
|
||||
func present(_ viewController: SlidingModalPresentable.ViewControllerType, from presentingViewController: UIViewController, animated: Bool, options: SlidingModalOption, completion: (() -> Void)?) {
|
||||
|
||||
NSLog("[SlidingModalPresenter] present \(type(of: viewController))")
|
||||
|
||||
if UIDevice.current.userInterfaceIdiom == .pad {
|
||||
viewController.modalPresentationStyle = .formSheet
|
||||
|
||||
let preferredHeight = viewController.layoutHeightFittingWidth(TabletContentSize.preferred.width).clamped(to: TabletContentSize.minHeight...TabletContentSize.maxHeight)
|
||||
|
||||
viewController.preferredContentSize = CGSize(width: TabletContentSize.preferred.width, height: preferredHeight)
|
||||
} else {
|
||||
let transitionDelegate = SlidingModalPresentationDelegate(isSpanning: isSpanning)
|
||||
|
||||
viewController.modalPresentationStyle = .custom
|
||||
viewController.transitioningDelegate = transitionDelegate
|
||||
|
||||
// Presented view controller does not affect the statusbar appearance
|
||||
viewController.modalPresentationCapturesStatusBarAppearance = false
|
||||
|
||||
self.transitionDelegate = transitionDelegate
|
||||
}
|
||||
let transitionDelegate = SlidingModalPresentationDelegate(isSpanning: options.contains(.spanning), blurBackground: options.contains(.blurBackground))
|
||||
|
||||
viewController.modalPresentationStyle = .custom
|
||||
viewController.transitioningDelegate = transitionDelegate
|
||||
|
||||
// Presented view controller does not affect the statusbar appearance
|
||||
viewController.modalPresentationCapturesStatusBarAppearance = false
|
||||
|
||||
self.transitionDelegate = transitionDelegate
|
||||
|
||||
presentingViewController.present(viewController, animated: animated, completion: completion)
|
||||
|
||||
|
|
|
@ -25,3 +25,4 @@
|
|||
#import "RoomFilesViewController.h"
|
||||
#import "RoomSettingsViewController.h"
|
||||
#import "JitsiWidgetData.h"
|
||||
#import "InviteRecentTableViewCell.h"
|
||||
|
|