mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-28 23:32:41 +00:00
Merge pull request #3573 from vector-im/release/1.0.6/release
Release 1.0.6
This commit is contained in:
commit
1fa30ece52
177 changed files with 1398 additions and 1589 deletions
5
.github/PULL_REQUEST_TEMPLATE.md
vendored
5
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
@ -1,8 +1,7 @@
|
|||
### Pull Request Checklist
|
||||
|
||||
<!-- Please read CONTRIBUTING.rst before submitting your pull request -->
|
||||
|
||||
* [ ] UI change has been tested on both light and dark themes
|
||||
* [ ] I read the [contributing guide](https://github.com/vector-im/element-ios/blob/develop/CONTRIBUTING.md)
|
||||
* [ ] UI change has been tested on both light and dark themes, in portrait and landscape orientations and on iPhone and iPad simulators
|
||||
* [ ] Pull request is based on the develop branch
|
||||
* [ ] Pull request updates [CHANGES.rst](https://github.com/vector-im/riot-ios/blob/develop/CHANGES.rst)
|
||||
* [ ] Pull request includes screenshots or videos of UI changes
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -33,5 +33,7 @@ Pods/
|
|||
fastlane/report.xml
|
||||
fastlane/Reports
|
||||
fastlane/README.md
|
||||
fastlane/Preview.html
|
||||
fastlane/metadata/
|
||||
|
||||
provisioning_profiles/
|
||||
|
|
36
CHANGES.rst
36
CHANGES.rst
|
@ -1,3 +1,39 @@
|
|||
Changes in 1.0.6 (2020-08-26)
|
||||
=================================================
|
||||
|
||||
Features:
|
||||
*
|
||||
|
||||
Improvements:
|
||||
* Upgrade MatrixKit version ([v0.12.15](https://github.com/matrix-org/matrix-ios-kit/releases/tag/v0.12.15)).
|
||||
* Config fixes.
|
||||
* Introduce TableViewSections. Refactor RoomSettingsViewController & SettingsViewController.
|
||||
* AuthenticationVC: Make forgot password button and phone number text field configurable.
|
||||
* Introduce httpAdditionalHeaders in BuildSettings.
|
||||
|
||||
Bugfix:
|
||||
* Fix biometry name null case (#3551).
|
||||
* Avoid email validation link to redirect to web app (#3513).
|
||||
* Wait for first sync complete before stopping loading screen (#3336).
|
||||
* Disable key backup on extensions (#3371).
|
||||
* Gracefully cancel verification on iOS 13 drag gesture (#3556).
|
||||
|
||||
API Change:
|
||||
*
|
||||
|
||||
Translations:
|
||||
*
|
||||
|
||||
Others:
|
||||
* Ignore fastlane/Preview.html
|
||||
* SonarCloud: Fix some code smells.
|
||||
|
||||
Build:
|
||||
*
|
||||
|
||||
Test:
|
||||
*
|
||||
|
||||
Changes in 1.0.5 (2020-08-13)
|
||||
=================================================
|
||||
|
||||
|
|
33
CONTRIBUTING.md
Normal file
33
CONTRIBUTING.md
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Contributing code to Matrix
|
||||
|
||||
Please read Synapse [contributing guide](https://github.com/matrix-org/synapse/blob/master/CONTRIBUTING.md).
|
||||
|
||||
# Contributing code to Element iOS
|
||||
|
||||
## I want to help translating
|
||||
|
||||
If you want to fix an issue for an English string, please submit a pull request to the Element iOS GitHub repository.
|
||||
If you want to fix an issue for another language, add a missing translation, or add a new language, please read [Element Web translating guide](https://github.com/vector-im/element-web/blob/develop/docs/translating.md) first and then use the Element iOS [Weblate](https://translate.riot.im/projects/riot-ios/).
|
||||
|
||||
If you have any question regarding translations please ask in [Element Translation room](https://matrix.to/#/#element-translations:matrix.org).
|
||||
|
||||
## Setting up a development environment
|
||||
|
||||
Please refer to the [installation guide](INSTALL.md) to setup the project.
|
||||
|
||||
## Implement a new screen or new screen flow
|
||||
|
||||
New screen flows are currently using MVVM-Coordinator pattern. Please refer to the screen template [Readme](Tools/Templates/README.md) to create a new screen or a new screen flow.
|
||||
|
||||
## Coding style
|
||||
|
||||
For Swift coding style we use [SwiftLint](https://github.com/realm/SwiftLint) to check some conventions at compile time (rules are located in the `.swiftlint.yml` file).
|
||||
Otherwise please have a look to [Apple Swift conventions](https://swift.org/documentation/api-design-guidelines.html#conventions). We are also using some of the conventions of [raywenderlich.com Swift style guide](https://github.com/raywenderlich/swift-style-guide).
|
||||
|
||||
## Pull request
|
||||
|
||||
When you are making a pull request please read carefully the [Pull Request Checklist](https://github.com/vector-im/element-ios/blob/develop/.github/PULL_REQUEST_TEMPLATE.md).
|
||||
|
||||
## Thanks
|
||||
|
||||
Thanks for contributing to Matrix projects!
|
|
@ -1,4 +0,0 @@
|
|||
Contributing code to Riot iOS
|
||||
==================================
|
||||
|
||||
riot-ios follows the same pattern as https://github.com/matrix-org/synapse/blob/master/CONTRIBUTING.md
|
|
@ -36,6 +36,9 @@ class AppConfiguration: CommonConfiguration {
|
|||
|
||||
// Each room member will be considered as a potential contact.
|
||||
MXKContactManager.shared().contactManagerMXRoomSource = MXKContactManagerMXRoomSource.all
|
||||
|
||||
// Enable key backup on app
|
||||
MXSDKOptions.sharedInstance().enableKeyBackupWhenStartingMXCrypto = true
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -166,7 +166,7 @@ final class BuildSettings: NSObject {
|
|||
static let allowLocalContactsAccess: Bool = true
|
||||
|
||||
|
||||
// MARK: - Screen settings -
|
||||
// MARK: - General Settings Screen
|
||||
|
||||
static let settingsScreenShowUserFirstName: Bool = false
|
||||
static let settingsScreenShowUserSurname: Bool = false
|
||||
|
@ -182,13 +182,31 @@ final class BuildSettings: NSObject {
|
|||
static let settingsScreenAllowBugReportingManually: Bool = true
|
||||
static let settingsScreenAllowDeactivatingAccount: Bool = true
|
||||
|
||||
// MARK: - Room Settings Screen
|
||||
|
||||
static let roomSettingsScreenShowLowPriorityOption: Bool = true
|
||||
static let roomSettingsScreenShowDirectChatOption: Bool = true
|
||||
static let roomSettingsScreenAllowChangingAccessSettings: Bool = true
|
||||
static let roomSettingsScreenAllowChangingHistorySettings: Bool = true
|
||||
static let roomSettingsScreenShowAddressSettings: Bool = true
|
||||
static let roomSettingsScreenShowFlairSettings: Bool = true
|
||||
static let roomSettingsScreenShowAdvancedSettings: Bool = true
|
||||
|
||||
// MARK: - Message
|
||||
static let messageDetailsAllowShare: Bool = true
|
||||
static let messageDetailsAllowPermalink: Bool = true
|
||||
static let messageDetailsAllowViewSource: Bool = true
|
||||
static let messageDetailsAllowSave: Bool = true
|
||||
|
||||
// MARK: - HTTP
|
||||
/// Additional HTTP headers will be sent by all requests. Not recommended to use request-specific headers, like `Authorization`.
|
||||
/// Empty dictionary by default.
|
||||
static let httpAdditionalHeaders: [String: String] = [:]
|
||||
|
||||
|
||||
// MARK: - Authentication Screen
|
||||
static let authScreenShowRegister = true
|
||||
static let authScreenShowPhoneNumber = true
|
||||
static let authScreenShowForgotPassword = true
|
||||
static let authScreenShowCustomServerOptions = true
|
||||
}
|
||||
|
|
|
@ -40,6 +40,11 @@ class CommonConfiguration: NSObject, Configurable {
|
|||
|
||||
// Enable lazy loading
|
||||
settings.syncWithLazyLoadOfRoomMembers = true
|
||||
|
||||
settings.messageDetailsAllowSharing = BuildSettings.messageDetailsAllowShare
|
||||
settings.messageDetailsAllowSaving = BuildSettings.messageDetailsAllowSave
|
||||
|
||||
MXKContactManager.shared().allowLocalContactsAccess = BuildSettings.allowLocalContactsAccess
|
||||
}
|
||||
|
||||
private func setupMatrixSDKSettings() {
|
||||
|
@ -59,6 +64,12 @@ class CommonConfiguration: NSObject, Configurable {
|
|||
|
||||
// Use UIKit BackgroundTask for handling background tasks in the SDK
|
||||
sdkOptions.backgroundModeHandler = MXUIKitBackgroundModeHandler()
|
||||
|
||||
// Pass httpAdditionalHeaders to the SDK
|
||||
sdkOptions.httpAdditionalHeaders = BuildSettings.httpAdditionalHeaders
|
||||
|
||||
// Disable key backup on common
|
||||
sdkOptions.enableKeyBackupWhenStartingMXCrypto = false
|
||||
}
|
||||
|
||||
|
||||
|
|
157
INSTALL.md
Normal file
157
INSTALL.md
Normal file
|
@ -0,0 +1,157 @@
|
|||
# Installation
|
||||
|
||||
## Install build tools
|
||||
|
||||
To build Element iOS project you need:
|
||||
|
||||
- Xcode 11.4+.
|
||||
- [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) 1.9.3. Manages library dependencies 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
|
||||
|
||||
Ruby is required for several build tools like CocoaPods, bundler and fastlane. Ruby is preinstalled on macOS, the system version is sufficient to build the porject tools, it's not required to install the latest version. If you want to install the lastest version of Ruby please check [official instructions](https://www.ruby-lang.org/en/documentation/installation/#homebrew).
|
||||
|
||||
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:
|
||||
|
||||
```
|
||||
gem install cocoapods
|
||||
```
|
||||
|
||||
In the last case please ensure that you are using the same version as indicated at the end of the `Podfile.lock` file.
|
||||
|
||||
### Install bundler (optional)
|
||||
|
||||
By using `bundler` you will ensure to use the right versions of build tools used to build and deliver the project. You can find dependency definitions in the `Gemfile`. To install `bundler`:
|
||||
|
||||
```
|
||||
gem install bundler
|
||||
```
|
||||
|
||||
## Choose Matrix SDKs version to build
|
||||
|
||||
To choose the [MatrixKit](https://github.com/matrix-org/matrix-ios-kit) version (and depending MatrixSDK and OLMKit) you want to develop and build against you will have to modify the right definitions of `$matrixKitVersion` variable in the `Podfile`.
|
||||
|
||||
### Determine your needs
|
||||
|
||||
To select which `$matrixKitVersion` value to use you have to determine your needs:
|
||||
|
||||
- **Build an App Store release version**
|
||||
|
||||
To build the last published App Store code you just need to checkout master branch. If you want to build an older App Store version just checkout the tag of the corresponding version. You have nothing to modify in the `Podfile`. In this case `$matrixKitVersion` will be set to a specific version of the MatrixKit already published on CocoaPods repository.
|
||||
|
||||
- **Build last development code and modify Element project only**
|
||||
|
||||
If you want to build last development code you have to checkout the develop branch and use `$matrixKitVersion = {'develop' => 'develop'}` in the `Podfile`. This will also use MatrixKit and MatrixSDK develop branches.
|
||||
|
||||
- **Build specific branch of Kit and SDK and modify Element project only**
|
||||
|
||||
If you want to build a specific branch for the MatrixKit and the MatrixSDK you have to indicate them using a dictionary like this: `$matrixKitVersion = {'kit branch name' => 'sdk branch name'}`.
|
||||
|
||||
- **Build any branch and be able to modify MatrixKit and MatrixSDK locally**
|
||||
|
||||
If you want to modify MatrixKit and/or MatrixSDK locally and see the result in Element project you have to uncommment `$matrixKitVersion = :local` in the `Podfile`.
|
||||
But before you have to checkout [MatrixKit](https://github.com/matrix-org/matrix-ios-kit) repository in `../matrix-ios-kit` and [MatrixSDK](https://github.com/matrix-org/matrix-ios-sdk) in `../matrix-ios-sdk` locally relatively to your Element iOS project folder.
|
||||
Be sure to use compatible branches for Element iOS, MatrixKit and MatrixSDK. For example if you want to modify Element iOS from develop branch use MatrixKit and MatrixSDK develop branches and then make your modifications.
|
||||
|
||||
**Important**: By working with local pods (development pods) you will need to use legacy build system in Xcode, to have your local changes taken into account. To enable it go to Xcode menu and select `File > Workspace Settings… > Build System` and then choose `Legacy Build System`.
|
||||
|
||||
### Modify `$matrixKitVersion` after installation of dependencies
|
||||
|
||||
Assuming you have already completed the **Install dependencies** instructions from **Build** section below.
|
||||
|
||||
Each time you edit `$matrixKitVersion` variable in the `Podfile` you will have to run the `pod install` command.
|
||||
|
||||
## Build
|
||||
|
||||
### Install dependencies
|
||||
|
||||
Before opening the Element Xcode workspace, you need to install dependencies via CocoaPods.
|
||||
|
||||
To be sure to use the right CocoaPods version you can use `bundler`:
|
||||
|
||||
```
|
||||
$ cd Riot
|
||||
$ bundle install
|
||||
$ bundle exec pod install
|
||||
```
|
||||
|
||||
Or if you prefer to use directly CocoaPods:
|
||||
|
||||
```
|
||||
$ cd Riot
|
||||
$ pod install
|
||||
```
|
||||
|
||||
This will load all dependencies for the Element source code, including [MatrixKit](https://github.com/matrix-org/matrix-ios-kit)
|
||||
and [MatrixSDK](https://github.com/matrix-org/matrix-ios-sdk).
|
||||
|
||||
### Open workspace
|
||||
|
||||
Then, open `Riot.xcworkspace` with Xcode.
|
||||
|
||||
```
|
||||
$ open Riot.xcworkspace
|
||||
```
|
||||
|
||||
**Note**: If you have multiple Xcode versions installed don't forget to use the right version of Command Line Tools when you are building the app. To check the Command Line Tools version go to `Xcode > Preferences > Locations > Command Line Tools` and check that the displayed version match your Xcode version.
|
||||
|
||||
### Configure project
|
||||
|
||||
You may need to change the bundle identifier and app group identifier to be unique to get Xcode to build the app. Make sure to change the bundle identifier, application group identifier and app name in the `Config/Common.xcconfig` file to your new identifiers.
|
||||
|
||||
## Generate IPA
|
||||
|
||||
To build the IPA we are currently using [fastlane](https://fastlane.tools/).
|
||||
|
||||
**Set your project informations**
|
||||
|
||||
Before making the release you need to modify the `fastlane/.env.default` file and set all your project informations like your App ID, Team ID, certificate names and so on.
|
||||
|
||||
**Install or update build tools**
|
||||
|
||||
The preferred way to use the fastlane script is to use `bundler`, to be sure to use the right dependency versions.
|
||||
|
||||
After opening the terminal in the project root folder. The first time you perform a release you need to run:
|
||||
|
||||
`bundle install`
|
||||
|
||||
For other times:
|
||||
|
||||
`bundle update`
|
||||
|
||||
**Run fastlane script**
|
||||
|
||||
Before executing the release command you need to export your Apple ID in environment variables:
|
||||
|
||||
`export APPLE_ID="foo.bar@apple.com"`
|
||||
|
||||
To make an App Store release you can directly execute this command:
|
||||
|
||||
`bundle exec fastlane app_store build_number:<your_build_number>`
|
||||
|
||||
Or you can use the wrapper script located at `/Tools/Release/buildRelease.sh`. For that go to the `Release` folder:
|
||||
|
||||
`$ cd ./Tools/Release/`
|
||||
|
||||
And then indicate a branch or a tag like this:
|
||||
|
||||
`$ ./buildRelease.sh <tag or branch>`
|
||||
|
||||
|
2
Podfile
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.12.12'
|
||||
$matrixKitVersion = '= 0.12.15'
|
||||
# $matrixKitVersion = :local
|
||||
# $matrixKitVersion = {'develop' => 'develop'}
|
||||
|
||||
|
|
51
README.md
Normal file
51
README.md
Normal file
|
@ -0,0 +1,51 @@
|
|||
# Element iOS
|
||||
|
||||
![GitHub release (latest by date)](https://img.shields.io/github/v/release/vector-im/element-ios)
|
||||
![badge-languages](https://img.shields.io/badge/languages-Swift%20%7C%20ObjC-orange.svg)
|
||||
[![Swift 5.x](https://img.shields.io/badge/Swift-5.x-orange)](https://developer.apple.com/swift)
|
||||
[![Build status](https://badge.buildkite.com/cc8f93e32da93fa7c1172398bd8af66254490567c7195a5f3f.svg?branch=develop)](https://buildkite.com/matrix-dot-org/element-ios/builds?branch=develop)
|
||||
[![Weblate](https://translate.riot.im/widgets/riot-ios/-/svg-badge.svg)](https://translate.riot.im/engage/riot-ios/?utm_source=widget)
|
||||
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=im.vector.app.ios&metric=alert_status)](https://sonarcloud.io/dashboard?id=im.vector.app.ios)
|
||||
[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=im.vector.app.ios&metric=bugs)](https://sonarcloud.io/dashboard?id=im.vector.app.ios)
|
||||
[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=im.vector.app.ios&metric=vulnerabilities)](https://sonarcloud.io/dashboard?id=im.vector.app.ios)
|
||||
[![Element iOS Matrix room #element-ios:matrix.org](https://img.shields.io/matrix/element-ios:matrix.org.svg?label=%23element-ios:matrix.org&logo=matrix&server_fqdn=matrix.org)](https://matrix.to/#/#element-ios:matrix.org)
|
||||
![GitHub](https://img.shields.io/github/license/vector-im/element-ios)
|
||||
[![Twitter URL](https://img.shields.io/twitter/url?label=Element&url=https%3A%2F%2Ftwitter.com%2Felement_hq)](https://twitter.com/element_hq)
|
||||
|
||||
Element iOS is an iOS [Matrix](https://matrix.org/) client provided by [Element](https://element.io/). It is based on [MatrixKit](https://github.com/matrix-org/matrix-ios-kit) and [MatrixSDK](https://github.com/matrix-org/matrix-ios-sdk).
|
||||
|
||||
<p align="center">
|
||||
<a href=https://itunes.apple.com/us/app/element/id1083446067?mt=8>
|
||||
<img alt="Download on the app store" src="https://linkmaker.itunes.apple.com/images/badges/en-us/badge_appstore-lrg.svg" width=160>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## Beta testing
|
||||
|
||||
You can try last beta build by accessing our [TestFlight Public Link](https://testflight.apple.com/join/lCeTuDKM). For questions and feedback about latest TestFlight build, please access the Element iOS Matrix room: [#element-ios:matrix.org](https://matrix.to/#/#element-ios:matrix.org).
|
||||
|
||||
## Build instructions
|
||||
|
||||
To build the application please refer to the [installation guide](./INSTALL.md).
|
||||
|
||||
## Contributing
|
||||
|
||||
If you want to contribute to Element iOS code or translations please refer to the [contribution guide](CONTRIBUTING.md).
|
||||
|
||||
## Support
|
||||
|
||||
When you are experiencing an issue on Element iOS, please first search in [GitHub issues](https://github.com/vector-im/element-ios/issues)
|
||||
and then in [#element-ios:matrix.org](https://matrix.to/#/#element-ios:matrix.org).
|
||||
If after your research you still have a question, ask at [#element-ios:matrix.org](https://matrix.to/#/#element-ios:matrix.org). Otherwise feel free to create a GitHub issue if you encounter a bug or a crash, by explaining clearly in detail what happened. You can also perform bug reporting (Rageshake) from the Element application by shaking your phone or going to the application settings. This is especially recommended when you encounter a crash.
|
||||
|
||||
## Copyright & License
|
||||
|
||||
Copyright (c) 2014-2017 OpenMarket Ltd
|
||||
Copyright (c) 2017 Vector Creations Ltd
|
||||
Copyright (c) 2017-2020 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with the License. You may obtain a copy of the License in the [LICENSE](LICENSE) file, or at:
|
||||
|
||||
[http://www.apache.org/licenses/LICENSE-2.0](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.
|
53
README.rst
53
README.rst
|
@ -1,53 +0,0 @@
|
|||
Element iOS
|
||||
==========
|
||||
|
||||
.. image:: https://img.shields.io/matrix/element-ios:matrix.org.svg?label=%23element-ios:matrix.org
|
||||
:alt: #element-ios:matrix.org
|
||||
:target: https://matrix.to/#/#element-ios:matrix.org
|
||||
|
||||
Element iOS is an iOS Matrix client.
|
||||
|
||||
.. image:: https://linkmaker.itunes.apple.com/images/badges/en-us/badge_appstore-lrg.svg
|
||||
:target: https://itunes.apple.com/us/app/element/id1083446067?mt=8
|
||||
|
||||
It is based on MatrixKit (https://github.com/matrix-org/matrix-ios-kit) and MatrixSDK (https://github.com/matrix-org/matrix-ios-sdk).
|
||||
|
||||
You can build the app from source as per below:
|
||||
|
||||
Build instructions
|
||||
==================
|
||||
|
||||
Before opening the Element Xcode workspace, you need to build it with the
|
||||
CocoaPods command::
|
||||
|
||||
$ cd Element
|
||||
$ bundle install
|
||||
$ bundle exec pod install
|
||||
|
||||
This will load all dependencies for the Element source code, including MatrixKit
|
||||
and MatrixSDK. You will need an recent and updated (``pod setup``) install of
|
||||
CocoaPods.
|
||||
|
||||
Then, open ``Riot.xcworkspace`` with Xcode
|
||||
|
||||
$ open Riot.xcworkspace
|
||||
|
||||
Developing
|
||||
==========
|
||||
|
||||
Uncomment the right definitions of ``$matrixKitVersion`` for the version you want to develop and build against. For example, if you are trying to build the develop branch, uncomment ``$matrixKitVersion = 'develop'`` and make sure the more specific MatrixKit version is commented out. Once you are done editing the ``Podfile``, run ``pod install``.
|
||||
|
||||
You may need to change the bundle identifier and app group identifier to be unique to get Xcode to build the app. Make sure to change the application group identifier everywhere by running a search for ``group.im.vector`` and changing every spot that identifier is used to your new identifier.
|
||||
|
||||
Copyright & License
|
||||
==================
|
||||
|
||||
Copyright (c) 2014-2017 OpenMarket Ltd
|
||||
Copyright (c) 2017 Vector Creations Ltd
|
||||
Copyright (c) 2017-2019 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with the License. You may obtain a copy of the License in the LICENSE file, or 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.
|
|
@ -750,8 +750,6 @@
|
|||
EC1CA89A24C9C9A200DE9EBF /* SetupBiometricsCoordinatorType.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1CA89224C9C9A200DE9EBF /* SetupBiometricsCoordinatorType.swift */; };
|
||||
EC1CA89B24C9C9A200DE9EBF /* SetupBiometricsViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1CA89324C9C9A200DE9EBF /* SetupBiometricsViewState.swift */; };
|
||||
EC1CA89C24C9C9A200DE9EBF /* SetupBiometricsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1CA89424C9C9A200DE9EBF /* SetupBiometricsViewModel.swift */; };
|
||||
EC1CA8C824D3160100DE9EBF /* Row.m in Sources */ = {isa = PBXBuildFile; fileRef = EC1CA8C724D3160100DE9EBF /* Row.m */; };
|
||||
EC1CA8CB24D3168F00DE9EBF /* Section.m in Sources */ = {isa = PBXBuildFile; fileRef = EC1CA8CA24D3168F00DE9EBF /* Section.m */; };
|
||||
EC1CA8D424D8103400DE9EBF /* App-Common.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = EC1CA8D324D8103400DE9EBF /* App-Common.xcconfig */; };
|
||||
EC1CA8D624D8108700DE9EBF /* ShareExtension-Common.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = EC1CA8D524D8108700DE9EBF /* ShareExtension-Common.xcconfig */; };
|
||||
EC1CA8D824D8118400DE9EBF /* SiriIntents-Common.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = EC1CA8D724D8118400DE9EBF /* SiriIntents-Common.xcconfig */; };
|
||||
|
@ -843,10 +841,14 @@
|
|||
EC85D754247C0F5B002C44C9 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC85D753247C0F5B002C44C9 /* Constants.swift */; };
|
||||
EC85D755247C0F84002C44C9 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC85D753247C0F5B002C44C9 /* Constants.swift */; };
|
||||
EC85D757247E700F002C44C9 /* NSEMemoryStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC85D756247E700F002C44C9 /* NSEMemoryStore.swift */; };
|
||||
EC9A3EC524E1616900A8CFAE /* PushNotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC9A3EC424E1616900A8CFAE /* PushNotificationManager.swift */; };
|
||||
EC9A3EC624E1632C00A8CFAE /* PushNotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC9A3EC424E1616900A8CFAE /* PushNotificationManager.swift */; };
|
||||
EC9A3EC524E1616900A8CFAE /* PushNotificationStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC9A3EC424E1616900A8CFAE /* PushNotificationStore.swift */; };
|
||||
EC9A3EC624E1632C00A8CFAE /* PushNotificationStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC9A3EC424E1616900A8CFAE /* PushNotificationStore.swift */; };
|
||||
EC9A3EC724E1634100A8CFAE /* KeyValueStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1CA87124C823E700DE9EBF /* KeyValueStore.swift */; };
|
||||
EC9A3EC824E1634800A8CFAE /* KeychainStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1CA87424C8259700DE9EBF /* KeychainStore.swift */; };
|
||||
ECAE7AE524EC0E01002FA813 /* TableViewSections.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECAE7AE424EC0E01002FA813 /* TableViewSections.swift */; };
|
||||
ECAE7AE724EC15F7002FA813 /* Section.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECAE7AE624EC15F7002FA813 /* Section.swift */; };
|
||||
ECAE7AE924EC1888002FA813 /* Row.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECAE7AE824EC1888002FA813 /* Row.swift */; };
|
||||
ECAE7AEE24EFDD1F002FA813 /* MXSessionState.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECAE7AED24EFDD1F002FA813 /* MXSessionState.swift */; };
|
||||
ECB101302477CFDB00CF8C11 /* UITableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB1012C2477CFDB00CF8C11 /* UITableView.swift */; };
|
||||
ECB101312477CFDB00CF8C11 /* UILabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB1012D2477CFDB00CF8C11 /* UILabel.swift */; };
|
||||
ECB101322477CFDB00CF8C11 /* UIDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB1012E2477CFDB00CF8C11 /* UIDevice.swift */; };
|
||||
|
@ -986,7 +988,6 @@
|
|||
3267EFB320E379FD00FF1CAA /* CHANGES.rst */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGES.rst; sourceTree = "<group>"; };
|
||||
3267EFB420E379FD00FF1CAA /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; fileEncoding = 4; path = Podfile; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
|
||||
3267EFB520E379FD00FF1CAA /* AUTHORS.rst */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AUTHORS.rst; sourceTree = "<group>"; };
|
||||
3267EFB620E379FD00FF1CAA /* README.rst */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.rst; sourceTree = "<group>"; };
|
||||
3275FD8B21A5A2C500B9C13D /* TermsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TermsView.swift; sourceTree = "<group>"; };
|
||||
3281BCF62201FA4200F4A383 /* UIControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIControl.swift; sourceTree = "<group>"; };
|
||||
3284A35020A07C210044F922 /* postMessageAPI.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = postMessageAPI.js; sourceTree = "<group>"; };
|
||||
|
@ -1697,6 +1698,7 @@
|
|||
B1B5598F20EFC5E400210D55 /* DecryptionFailure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DecryptionFailure.h; sourceTree = "<group>"; };
|
||||
B1B5599020EFC5E400210D55 /* Analytics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Analytics.h; sourceTree = "<group>"; };
|
||||
B1B5599120EFC5E400210D55 /* DecryptionFailureTracker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DecryptionFailureTracker.m; sourceTree = "<group>"; };
|
||||
B1B7F22824F3F8E900FD567B /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
||||
B1B9194A2118984300FE25B5 /* RoomPredecessorBubbleCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RoomPredecessorBubbleCell.xib; sourceTree = "<group>"; };
|
||||
B1B9DED922E9B7350065E677 /* SerializationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SerializationService.swift; sourceTree = "<group>"; };
|
||||
B1B9DEDB22E9B7440065E677 /* SerializationServiceType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SerializationServiceType.swift; sourceTree = "<group>"; };
|
||||
|
@ -1877,10 +1879,6 @@
|
|||
EC1CA8BB24D1B4BF00DE9EBF /* SiriIntents-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "SiriIntents-Debug.xcconfig"; sourceTree = "<group>"; };
|
||||
EC1CA8BC24D1B4CF00DE9EBF /* NSE-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "NSE-Debug.xcconfig"; sourceTree = "<group>"; };
|
||||
EC1CA8BD24D1B4CF00DE9EBF /* NSE-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "NSE-Release.xcconfig"; sourceTree = "<group>"; };
|
||||
EC1CA8C624D3160100DE9EBF /* Row.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Row.h; sourceTree = "<group>"; };
|
||||
EC1CA8C724D3160100DE9EBF /* Row.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Row.m; sourceTree = "<group>"; };
|
||||
EC1CA8C924D3168F00DE9EBF /* Section.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Section.h; sourceTree = "<group>"; };
|
||||
EC1CA8CA24D3168F00DE9EBF /* Section.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Section.m; sourceTree = "<group>"; };
|
||||
EC1CA8D324D8103400DE9EBF /* App-Common.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "App-Common.xcconfig"; sourceTree = "<group>"; };
|
||||
EC1CA8D524D8108700DE9EBF /* ShareExtension-Common.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "ShareExtension-Common.xcconfig"; sourceTree = "<group>"; };
|
||||
EC1CA8D724D8118400DE9EBF /* SiriIntents-Common.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "SiriIntents-Common.xcconfig"; sourceTree = "<group>"; };
|
||||
|
@ -1975,7 +1973,11 @@
|
|||
EC85D750247C0E8F002C44C9 /* UNUserNotificationCenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UNUserNotificationCenter.swift; sourceTree = "<group>"; };
|
||||
EC85D753247C0F5B002C44C9 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
|
||||
EC85D756247E700F002C44C9 /* NSEMemoryStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSEMemoryStore.swift; sourceTree = "<group>"; };
|
||||
EC9A3EC424E1616900A8CFAE /* PushNotificationManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PushNotificationManager.swift; sourceTree = "<group>"; };
|
||||
EC9A3EC424E1616900A8CFAE /* PushNotificationStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PushNotificationStore.swift; sourceTree = "<group>"; };
|
||||
ECAE7AE424EC0E01002FA813 /* TableViewSections.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewSections.swift; sourceTree = "<group>"; };
|
||||
ECAE7AE624EC15F7002FA813 /* Section.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Section.swift; sourceTree = "<group>"; };
|
||||
ECAE7AE824EC1888002FA813 /* Row.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Row.swift; sourceTree = "<group>"; };
|
||||
ECAE7AED24EFDD1F002FA813 /* MXSessionState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXSessionState.swift; sourceTree = "<group>"; };
|
||||
ECB1012C2477CFDB00CF8C11 /* UITableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITableView.swift; sourceTree = "<group>"; };
|
||||
ECB1012D2477CFDB00CF8C11 /* UILabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UILabel.swift; sourceTree = "<group>"; };
|
||||
ECB1012E2477CFDB00CF8C11 /* UIDevice.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIDevice.swift; sourceTree = "<group>"; };
|
||||
|
@ -3197,7 +3199,6 @@
|
|||
B1B5567720EE6C4C00210D55 /* Settings */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EC1CA8C524D315EA00DE9EBF /* Models */,
|
||||
B1B5567F20EE6C4C00210D55 /* SettingsViewController.h */,
|
||||
B1B5567E20EE6C4C00210D55 /* SettingsViewController.m */,
|
||||
B1B5578120EF564900210D55 /* Views */,
|
||||
|
@ -3467,6 +3468,7 @@
|
|||
B1B556CD20EE6C4C00210D55 /* Common */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
ECAE7AEA24EC223D002FA813 /* Models */,
|
||||
EC85D7312477DD54002C44C9 /* SectionHeaders */,
|
||||
B183226923F59F3E0035B2E8 /* Buttons */,
|
||||
B1963B3622933B9500CBA17F /* CollectionView */,
|
||||
|
@ -4613,17 +4615,6 @@
|
|||
path = SetupBiometrics;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
EC1CA8C524D315EA00DE9EBF /* Models */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EC1CA8C624D3160100DE9EBF /* Row.h */,
|
||||
EC1CA8C724D3160100DE9EBF /* Row.m */,
|
||||
EC1CA8C924D3168F00DE9EBF /* Section.h */,
|
||||
EC1CA8CA24D3168F00DE9EBF /* Section.m */,
|
||||
);
|
||||
path = Models;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
EC3B066324AC6ADD000DF9BF /* CrossSigning */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -4838,7 +4829,7 @@
|
|||
children = (
|
||||
EC85D73C2477DDD0002C44C9 /* PushNotificationService.h */,
|
||||
EC85D73D2477DDD0002C44C9 /* PushNotificationService.m */,
|
||||
EC9A3EC424E1616900A8CFAE /* PushNotificationManager.swift */,
|
||||
EC9A3EC424E1616900A8CFAE /* PushNotificationStore.swift */,
|
||||
);
|
||||
path = PushNotification;
|
||||
sourceTree = "<group>";
|
||||
|
@ -4857,6 +4848,16 @@
|
|||
path = RiotNSE;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
ECAE7AEA24EC223D002FA813 /* Models */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
ECAE7AE424EC0E01002FA813 /* TableViewSections.swift */,
|
||||
ECAE7AE624EC15F7002FA813 /* Section.swift */,
|
||||
ECAE7AE824EC1888002FA813 /* Row.swift */,
|
||||
);
|
||||
path = Models;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F083BB021E7005FD00A9B29C /* RiotTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -4965,6 +4966,7 @@
|
|||
B1DCC63322E72C1B00625807 /* UISearchBar.swift */,
|
||||
B11291EB238D704C0077B478 /* FloatingPoint.swift */,
|
||||
32FD757524D2C9BA00BA7B37 /* Bundle.swift */,
|
||||
ECAE7AED24EFDD1F002FA813 /* MXSessionState.swift */,
|
||||
);
|
||||
path = Categories;
|
||||
sourceTree = "<group>";
|
||||
|
@ -5015,7 +5017,7 @@
|
|||
F094A9991B78D8F000B1FBBF = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3267EFB620E379FD00FF1CAA /* README.rst */,
|
||||
B1B7F22824F3F8E900FD567B /* README.md */,
|
||||
3267EFB320E379FD00FF1CAA /* CHANGES.rst */,
|
||||
3267EFB520E379FD00FF1CAA /* AUTHORS.rst */,
|
||||
3267EFB420E379FD00FF1CAA /* Podfile */,
|
||||
|
@ -5706,7 +5708,7 @@
|
|||
EC2B4EF224A1EF34005EB739 /* DataProtectionHelper.swift in Sources */,
|
||||
EC85D7462477E5F7002C44C9 /* NotificationService.swift in Sources */,
|
||||
32FD755424D074C700BA7B37 /* CommonConfiguration.swift in Sources */,
|
||||
EC9A3EC624E1632C00A8CFAE /* PushNotificationManager.swift in Sources */,
|
||||
EC9A3EC624E1632C00A8CFAE /* PushNotificationStore.swift in Sources */,
|
||||
32FD757424D2BEF700BA7B37 /* InfoPlist.swift in Sources */,
|
||||
EC85D752247C0F52002C44C9 /* UNUserNotificationCenter.swift in Sources */,
|
||||
EC9A3EC724E1634100A8CFAE /* KeyValueStore.swift in Sources */,
|
||||
|
@ -5898,6 +5900,7 @@
|
|||
F05927C91FDED836009F2A68 /* MXGroup+Riot.m in Sources */,
|
||||
B1B5594520EF7BD000210D55 /* TableViewCellWithCollectionView.m in Sources */,
|
||||
B1A6C109238828A6002882FD /* SlidingModalPresentationDelegate.swift in Sources */,
|
||||
ECAE7AEE24EFDD1F002FA813 /* MXSessionState.swift in Sources */,
|
||||
32DB557722FDADE50016329E /* ServiceTermsModalCoordinator.swift in Sources */,
|
||||
B185145B24B8C98200EE19EA /* MajorUpdateViewController.swift in Sources */,
|
||||
32DB557922FDADE50016329E /* ServiceTermsModalScreenViewModel.swift in Sources */,
|
||||
|
@ -6058,7 +6061,6 @@
|
|||
B1A6C10D23882D1D002882FD /* SlidingModalPresentationController.swift in Sources */,
|
||||
32A6001D22C661100042C1D9 /* EditHistoryCoordinatorType.swift in Sources */,
|
||||
F083BDFA1E7009ED00A9B29C /* RoomPreviewData.m in Sources */,
|
||||
EC1CA8CB24D3168F00DE9EBF /* Section.m in Sources */,
|
||||
B1B557B420EF5AEF00210D55 /* EventDetailsView.m in Sources */,
|
||||
EC85D751247C0E8F002C44C9 /* UNUserNotificationCenter.swift in Sources */,
|
||||
B1BEE73823DF44A60003A4CB /* UserVerificationSessionsStatusViewAction.swift in Sources */,
|
||||
|
@ -6083,7 +6085,6 @@
|
|||
EC711B7624A63B37008F830C /* SecretsSetupRecoveryKeyViewState.swift in Sources */,
|
||||
32FDC1CD2386CD390084717A /* RiotSettingIntegrationProvisioning.swift in Sources */,
|
||||
B1BEE73523DF44A60003A4CB /* UserVerificationSessionsStatusViewModel.swift in Sources */,
|
||||
EC1CA8C824D3160100DE9EBF /* Row.m in Sources */,
|
||||
B1B5572020EE6C4D00210D55 /* ContactsTableViewController.m in Sources */,
|
||||
EC85D7142477DCD7002C44C9 /* KeyVerificationScanConfirmationViewState.swift in Sources */,
|
||||
EC711B9124A63B37008F830C /* SecretsRecoveryWithKeyCoordinatorType.swift in Sources */,
|
||||
|
@ -6171,7 +6172,7 @@
|
|||
EC711BA924A63B58008F830C /* SecureBackupSetupCoordinatorBridgePresenter.swift in Sources */,
|
||||
B1B558C720EF768F00210D55 /* RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.m in Sources */,
|
||||
B1B336C5242B933700F95EC4 /* KeyVerificationSelfVerifyStartViewModel.swift in Sources */,
|
||||
EC9A3EC524E1616900A8CFAE /* PushNotificationManager.swift in Sources */,
|
||||
EC9A3EC524E1616900A8CFAE /* PushNotificationStore.swift in Sources */,
|
||||
B1B558F020EF768F00210D55 /* RoomOutgoingAttachmentWithPaginationTitleBubbleCell.m in Sources */,
|
||||
926FA53F1F4C132000F826C2 /* MXSession+Riot.m in Sources */,
|
||||
EC711B8324A63B37008F830C /* SecretsSetupRecoveryPassphraseCoordinator.swift in Sources */,
|
||||
|
@ -6224,6 +6225,7 @@
|
|||
B14084CE23BFA0990010F692 /* KeyVerificationIncomingRequestApprovalWithPaginationTitleBubbleCell.swift in Sources */,
|
||||
B14F143222144F6500FA0595 /* KeyBackupRecoverFromRecoveryKeyCoordinator.swift in Sources */,
|
||||
B110872621F098F0003554A5 /* ActivityIndicatorView.swift in Sources */,
|
||||
ECAE7AE924EC1888002FA813 /* Row.swift in Sources */,
|
||||
B1CE83E02422817200D07506 /* KeyVerificationVerifyBySASViewController.swift in Sources */,
|
||||
B19EFA3921F8BB2C00FC070E /* KeyBackupRecoverCoordinatorType.swift in Sources */,
|
||||
B1C3360322F1ED600021BA8D /* MediaPickerCoordinator.swift in Sources */,
|
||||
|
@ -6294,6 +6296,7 @@
|
|||
B125FE1B231D5BF200B72806 /* SettingsDiscoveryTableViewSection.swift in Sources */,
|
||||
B18DEDD5243377C10075FEF7 /* KeyVerificationSelfVerifyWaitViewModel.swift in Sources */,
|
||||
EC711B8B24A63B37008F830C /* SecretsRecoveryWithPassphraseViewState.swift in Sources */,
|
||||
ECAE7AE524EC0E01002FA813 /* TableViewSections.swift in Sources */,
|
||||
B1CE83DA2422817200D07506 /* KeyVerificationVerifyByScanningViewModel.swift in Sources */,
|
||||
32242F0921E8B05F00725742 /* UIColor.swift in Sources */,
|
||||
B16932E720F3C37100746532 /* HomeMessagesSearchDataSource.m in Sources */,
|
||||
|
@ -6311,6 +6314,7 @@
|
|||
B1B558FF20EF768F00210D55 /* RoomIncomingTextMsgBubbleCell.m in Sources */,
|
||||
EC85D7342477DD54002C44C9 /* SectionHeaderView.m in Sources */,
|
||||
B1098C0021ECFE65000DDA48 /* KeyBackupSetupPassphraseViewController.swift in Sources */,
|
||||
ECAE7AE724EC15F7002FA813 /* Section.swift in Sources */,
|
||||
B1B5591020EF782800210D55 /* TableViewCellWithPhoneNumberTextField.m in Sources */,
|
||||
B1CE83E52422817200D07506 /* KeyVerificationVerifyBySASViewModel.swift in Sources */,
|
||||
B1DB4F06223015080065DBFA /* Character.swift in Sources */,
|
||||
|
@ -6715,7 +6719,7 @@
|
|||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1.0.5;
|
||||
CURRENT_PROJECT_VERSION = 1.0.6;
|
||||
DEFINES_MODULE = YES;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
|
@ -6735,7 +6739,7 @@
|
|||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 1.0.5;
|
||||
MARKETING_VERSION = 1.0.6;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -6773,7 +6777,7 @@
|
|||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 1.0.5;
|
||||
CURRENT_PROJECT_VERSION = 1.0.6;
|
||||
DEFINES_MODULE = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
|
@ -6786,7 +6790,7 @@
|
|||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 1.0.5;
|
||||
MARKETING_VERSION = 1.0.6;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
|
|
|
@ -74,7 +74,7 @@ extern NSString *const AppDelegateUniversalLinkDidChangeNotification;
|
|||
|
||||
/**
|
||||
Let the AppDelegate handle and display self verification requests.
|
||||
Default is YES;
|
||||
Default is YES.
|
||||
*/
|
||||
@property (nonatomic) BOOL handleSelfVerificationRequest;
|
||||
|
||||
|
|
|
@ -237,6 +237,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
Related push notification service instance. Will be created when launch finished.
|
||||
*/
|
||||
@property (nonatomic, strong) PushNotificationService *pushNotificationService;
|
||||
@property (nonatomic, strong) PushNotificationStore *pushNotificationStore;
|
||||
@property (nonatomic, strong) LocalAuthenticationService *localAuthenticationService;
|
||||
|
||||
@property (nonatomic, strong) MajorUpdateManager *majorUpdateManager;
|
||||
|
@ -412,23 +413,6 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
NSLog(@"[AppDelegate] didFinishLaunchingWithOptions");
|
||||
#endif
|
||||
|
||||
// User credentials (in MXKAccount) are no more stored in NSUserDefaults but in a file
|
||||
// as advised at https://forums.developer.apple.com/thread/15685#45849.
|
||||
// So, there is no more need to loop (sometimes forever) until
|
||||
// [application isProtectedDataAvailable] becomes YES.
|
||||
// But, as we are not so sure, loop but no more than 10s.
|
||||
// // TODO: Remove this loop.
|
||||
// NSUInteger loopCount = 0;
|
||||
//
|
||||
// // Check whether the content protection is active before going further.
|
||||
// // Should fix the spontaneous logout.
|
||||
// while (![application isProtectedDataAvailable] && loopCount++ < 50)
|
||||
// {
|
||||
// // Wait for protected data.
|
||||
// [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.2f]];
|
||||
// }
|
||||
//
|
||||
// NSLog(@"[AppDelegate] didFinishLaunchingWithOptions: isProtectedDataAvailable: %@ (%tu)", @([application isProtectedDataAvailable]), loopCount);
|
||||
NSLog(@"[AppDelegate] didFinishLaunchingWithOptions: isProtectedDataAvailable: %@", @([application isProtectedDataAvailable]));
|
||||
|
||||
_configuration = [AppConfiguration new];
|
||||
|
@ -510,7 +494,8 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
|
||||
self.localAuthenticationService = [[LocalAuthenticationService alloc] initWithPinCodePreferences:[PinCodePreferences shared]];
|
||||
|
||||
self.pushNotificationService = [[PushNotificationService alloc] initWithPushNotificationManager:PushNotificationManager.shared];
|
||||
self.pushNotificationStore = [PushNotificationStore new];
|
||||
self.pushNotificationService = [[PushNotificationService alloc] initWithPushNotificationStore:self.pushNotificationStore];
|
||||
self.pushNotificationService.delegate = self;
|
||||
|
||||
// Add matrix observers, and initialize matrix sessions if the app is not launched in background.
|
||||
|
@ -1993,14 +1978,6 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
|
||||
// Use MXFileStore as MXStore to permanently store events.
|
||||
accountManager.storeClass = [MXFileStore class];
|
||||
|
||||
// Disable APNS use.
|
||||
// if (accountManager.apnsDeviceToken)
|
||||
// {
|
||||
// // We use now Pushkit, unregister for all remote notifications received via Apple Push Notification service.
|
||||
// [[UIApplication sharedApplication] unregisterForRemoteNotifications];
|
||||
// [accountManager setApnsDeviceToken:nil];
|
||||
// }
|
||||
|
||||
// Observers have been defined, we can start a matrix session for each enabled accounts.
|
||||
NSLog(@"[AppDelegate] initMatrixSessions: prepareSessionForActiveAccounts (app state: %tu)", [[UIApplication sharedApplication] applicationState]);
|
||||
|
@ -2250,8 +2227,8 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
// Reset user pin code
|
||||
[PinCodePreferences.shared reset];
|
||||
|
||||
// Reset push notification manager
|
||||
[PushNotificationManager.shared reset];
|
||||
// Reset push notification store
|
||||
[self.pushNotificationStore reset];
|
||||
|
||||
#ifdef MX_CALL_STACK_ENDPOINT
|
||||
// Erase all created certificates and private keys by MXEndpointCallStack
|
||||
|
@ -2430,6 +2407,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
// Stay in launching during the first server sync if the store is empty.
|
||||
isLaunching = (mainSession.rooms.count == 0 && launchAnimationContainerView);
|
||||
default:
|
||||
isLaunching = NO;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1121,6 +1121,7 @@
|
|||
"device_verification_self_verify_wait_recover_secrets_without_passphrase" = "Use Recovery Key";
|
||||
"device_verification_self_verify_wait_recover_secrets_with_passphrase" = "Use Recovery Passphrase or Key";
|
||||
"device_verification_self_verify_wait_recover_secrets_additional_information" = "If you can't accessing an existing session";
|
||||
"device_verification_self_verify_wait_recover_secrets_checking_availability" = "Checking for other verification capabilities ...";
|
||||
|
||||
// MARK: Verify
|
||||
|
||||
|
|
|
@ -14,22 +14,12 @@
|
|||
// limitations under the License.
|
||||
//
|
||||
|
||||
#import "Row.h"
|
||||
import Foundation
|
||||
|
||||
@implementation Row
|
||||
|
||||
+ (instancetype)rowWithTag:(NSInteger)tag
|
||||
{
|
||||
return [[self alloc] initWithTag:tag];
|
||||
}
|
||||
|
||||
- (instancetype)initWithTag:(NSInteger)tag
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.tag = tag;
|
||||
extension MXSessionState: Comparable {
|
||||
|
||||
public static func < (lhs: MXSessionState, rhs: MXSessionState) -> Bool {
|
||||
return lhs.rawValue < rhs.rawValue
|
||||
}
|
||||
return self;
|
||||
|
||||
}
|
||||
|
||||
@end
|
|
@ -135,7 +135,8 @@ internal struct ImageAsset {
|
|||
#if os(iOS) || os(tvOS)
|
||||
let image = Image(named: name, in: bundle, compatibleWith: nil)
|
||||
#elseif os(macOS)
|
||||
let image = bundle.image(forResource: NSImage.Name(name))
|
||||
let name = NSImage.Name(self.name)
|
||||
let image = (bundle == .main) ? NSImage(named: name) : bundle.image(forResource: name)
|
||||
#elseif os(watchOS)
|
||||
let image = Image(named: name)
|
||||
#endif
|
||||
|
|
|
@ -52,8 +52,7 @@ internal enum InfoPlist {
|
|||
// MARK: - Implementation Details
|
||||
|
||||
private func arrayFromPlist<T>(at path: String) -> [T] {
|
||||
let bundle = BundleToken.bundle
|
||||
guard let url = bundle.url(forResource: path, withExtension: nil),
|
||||
guard let url = BundleToken.bundle.url(forResource: path, withExtension: nil),
|
||||
let data = NSArray(contentsOf: url) as? [T] else {
|
||||
fatalError("Unable to load PLIST at path: \(path)")
|
||||
}
|
||||
|
@ -64,8 +63,7 @@ private struct PlistDocument {
|
|||
let data: [String: Any]
|
||||
|
||||
init(path: String) {
|
||||
let bundle = BundleToken.bundle
|
||||
guard let url = bundle.url(forResource: path, withExtension: nil),
|
||||
guard let url = BundleToken.bundle.url(forResource: path, withExtension: nil),
|
||||
let data = NSDictionary(contentsOf: url) as? [String: Any] else {
|
||||
fatalError("Unable to load PLIST at path: \(path)")
|
||||
}
|
||||
|
|
|
@ -926,6 +926,10 @@ internal enum VectorL10n {
|
|||
internal static var deviceVerificationSelfVerifyWaitRecoverSecretsAdditionalInformation: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_self_verify_wait_recover_secrets_additional_information")
|
||||
}
|
||||
/// Checking for other verification capabilities ...
|
||||
internal static var deviceVerificationSelfVerifyWaitRecoverSecretsCheckingAvailability: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_self_verify_wait_recover_secrets_checking_availability")
|
||||
}
|
||||
/// Use Recovery Passphrase or Key
|
||||
internal static var deviceVerificationSelfVerifyWaitRecoverSecretsWithPassphrase: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_self_verify_wait_recover_secrets_with_passphrase")
|
||||
|
|
|
@ -34,8 +34,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
|
||||
/// Designated initializer
|
||||
/// @param pushNotificationManager Push Notification Manager instance
|
||||
- (instancetype)initWithPushNotificationManager:(PushNotificationManager *)pushNotificationManager;
|
||||
/// @param pushNotificationStore Push Notification Store instance
|
||||
- (instancetype)initWithPushNotificationStore:(PushNotificationStore *)pushNotificationStore;
|
||||
|
||||
/**
|
||||
Is push really registered.
|
||||
|
|
|
@ -22,16 +22,14 @@
|
|||
#import <PushKit/PushKit.h>
|
||||
|
||||
@interface PushNotificationService()<PKPushRegistryDelegate>
|
||||
{
|
||||
/**
|
||||
Matrix session observer used to detect new opened sessions.
|
||||
*/
|
||||
id matrixSessionStateObserver;
|
||||
}
|
||||
|
||||
/**
|
||||
Matrix session observer used to detect new opened sessions.
|
||||
*/
|
||||
@property (nonatomic, weak) id matrixSessionStateObserver;
|
||||
@property (nonatomic, nullable, copy) void (^registrationForRemoteNotificationsCompletion)(NSError *);
|
||||
@property (nonatomic, strong) PKPushRegistry *pushRegistry;
|
||||
@property (nonatomic, strong) PushNotificationManager *pushNotificationManager;
|
||||
@property (nonatomic, strong) PushNotificationStore *pushNotificationStore;
|
||||
|
||||
/// Should PushNotificationService receive VoIP pushes
|
||||
@property (nonatomic, assign) BOOL shouldReceiveVoIPPushes;
|
||||
|
@ -40,11 +38,11 @@
|
|||
|
||||
@implementation PushNotificationService
|
||||
|
||||
- (instancetype)initWithPushNotificationManager:(PushNotificationManager *)pushNotificationManager
|
||||
- (instancetype)initWithPushNotificationStore:(PushNotificationStore *)pushNotificationStore
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
self.pushNotificationManager = pushNotificationManager;
|
||||
self.pushNotificationStore = pushNotificationStore;
|
||||
_pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
|
||||
self.shouldReceiveVoIPPushes = YES;
|
||||
}
|
||||
|
@ -117,7 +115,7 @@
|
|||
|
||||
_isPushRegistered = YES;
|
||||
|
||||
if (!_pushNotificationManager.pushKitToken)
|
||||
if (!_pushNotificationStore.pushKitToken)
|
||||
{
|
||||
[self configurePushKit];
|
||||
}
|
||||
|
@ -162,7 +160,7 @@
|
|||
|
||||
- (void)applicationDidEnterBackground
|
||||
{
|
||||
if (_pushNotificationManager.pushKitToken)
|
||||
if (_pushNotificationStore.pushKitToken)
|
||||
{
|
||||
self.shouldReceiveVoIPPushes = YES;
|
||||
}
|
||||
|
@ -172,7 +170,7 @@
|
|||
{
|
||||
[[UNUserNotificationCenter currentNotificationCenter] removeUnwantedNotifications];
|
||||
[[UNUserNotificationCenter currentNotificationCenter] removeCallNotificationsFor:nil];
|
||||
if (_pushNotificationManager.pushKitToken)
|
||||
if (_pushNotificationStore.pushKitToken)
|
||||
{
|
||||
self.shouldReceiveVoIPPushes = NO;
|
||||
}
|
||||
|
@ -184,7 +182,7 @@
|
|||
{
|
||||
_shouldReceiveVoIPPushes = shouldReceiveVoIPPushes;
|
||||
|
||||
if (_shouldReceiveVoIPPushes && _pushNotificationManager.pushKitToken)
|
||||
if (_shouldReceiveVoIPPushes && _pushNotificationStore.pushKitToken)
|
||||
{
|
||||
MXSession *session = [AppDelegate theDelegate].mxSessions.firstObject;
|
||||
if (session.state >= MXSessionStateStoreDataReady)
|
||||
|
@ -194,7 +192,11 @@
|
|||
else
|
||||
{
|
||||
// add an observer for session state
|
||||
matrixSessionStateObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionStateDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
MXWeakify(self);
|
||||
|
||||
NSNotificationCenter * __weak notificationCenter = [NSNotificationCenter defaultCenter];
|
||||
self.matrixSessionStateObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionStateDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
MXSession *mxSession = (MXSession*)notif.object;
|
||||
|
||||
if ([[AppDelegate theDelegate].mxSessions containsObject:mxSession]
|
||||
|
@ -202,8 +204,7 @@
|
|||
&& self->_shouldReceiveVoIPPushes)
|
||||
{
|
||||
[self configurePushKit];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self->matrixSessionStateObserver];
|
||||
self->matrixSessionStateObserver = nil;
|
||||
[notificationCenter removeObserver:self.matrixSessionStateObserver];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
@ -230,15 +231,12 @@
|
|||
if (account.mxSession.state == MXSessionStatePaused)
|
||||
{
|
||||
NSLog(@"[PushNotificationService] launchBackgroundSync");
|
||||
__weak typeof(self) weakSelf = self;
|
||||
MXWeakify(self);
|
||||
|
||||
[account backgroundSync:20000 success:^{
|
||||
|
||||
// Sanity check
|
||||
if (!weakSelf)
|
||||
{
|
||||
return;
|
||||
}
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[[UNUserNotificationCenter currentNotificationCenter] removeUnwantedNotifications];
|
||||
[[UNUserNotificationCenter currentNotificationCenter] removeCallNotificationsFor:nil];
|
||||
|
@ -450,7 +448,7 @@
|
|||
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)pushCredentials forType:(PKPushType)type
|
||||
{
|
||||
NSLog(@"[PushNotificationService] did update PushKit credentials");
|
||||
_pushNotificationManager.pushKitToken = pushCredentials.token;
|
||||
_pushNotificationStore.pushKitToken = pushCredentials.token;
|
||||
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive)
|
||||
{
|
||||
self.shouldReceiveVoIPPushes = NO;
|
||||
|
@ -459,7 +457,7 @@
|
|||
|
||||
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type withCompletionHandler:(void (^)(void))completion
|
||||
{
|
||||
NSLog(@"[PushNotificationService] did receive PushKit push with payload: %@", payload.dictionaryPayload);
|
||||
NSLog(@"[PushNotificationService] didReceiveIncomingPushWithPayload: %@", payload.dictionaryPayload);
|
||||
|
||||
NSString *roomId = payload.dictionaryPayload[@"room_id"];
|
||||
NSString *eventId = payload.dictionaryPayload[@"event_id"];
|
||||
|
@ -469,14 +467,14 @@
|
|||
|
||||
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground)
|
||||
{
|
||||
NSLog(@"[PushNotificationService] application is in bg");
|
||||
NSLog(@"[PushNotificationService] didReceiveIncomingPushWithPayload: application is in bg");
|
||||
|
||||
if (@available(iOS 13.0, *))
|
||||
{
|
||||
// for iOS 13, we'll just report the incoming call in the same runloop. It means we cannot call an async API here.
|
||||
MXEvent *lastCallInvite = _pushNotificationManager.lastCallInvite;
|
||||
MXEvent *lastCallInvite = _pushNotificationStore.lastCallInvite;
|
||||
// remove event
|
||||
_pushNotificationManager.lastCallInvite = nil;
|
||||
_pushNotificationStore.lastCallInvite = nil;
|
||||
MXSession *session = [AppDelegate theDelegate].mxSessions.firstObject;
|
||||
// when we have a VoIP push while the application is killed, session.callManager will not be ready yet. Configure it.
|
||||
[[AppDelegate theDelegate] configureCallManagerIfRequiredForSession:session];
|
||||
|
@ -486,30 +484,26 @@
|
|||
[session decryptEvent:lastCallInvite inTimeline:nil];
|
||||
}
|
||||
|
||||
NSLog(@"[PushNotificationService] lastCallInvite: %@", lastCallInvite);
|
||||
NSLog(@"[PushNotificationService] didReceiveIncomingPushWithPayload: lastCallInvite: %@", lastCallInvite);
|
||||
|
||||
if ([lastCallInvite.eventId isEqualToString:eventId])
|
||||
{
|
||||
SEL handleCallInvite = NSSelectorFromString(@"handleCallInvite:");
|
||||
if ([session.callManager respondsToSelector:handleCallInvite])
|
||||
{
|
||||
[session.callManager performSelector:handleCallInvite withObject:lastCallInvite];
|
||||
}
|
||||
[session.callManager handleCallEvent:lastCallInvite];
|
||||
MXCall *call = [session.callManager callWithCallId:lastCallInvite.content[@"call_id"]];
|
||||
if (call)
|
||||
{
|
||||
[session.callManager.callKitAdapter reportIncomingCall:call];
|
||||
NSLog(@"[PushNotificationService] Reporting new call in room %@ for the event: %@", roomId, eventId);
|
||||
NSLog(@"[PushNotificationService] didReceiveIncomingPushWithPayload: Reporting new call in room %@ for the event: %@", roomId, eventId);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"[PushNotificationService] Error on call object on room %@ for the event: %@", roomId, eventId);
|
||||
NSLog(@"[PushNotificationService] didReceiveIncomingPushWithPayload: Error on call object on room %@ for the event: %@", roomId, eventId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// It's a serious error. There is nothing to avoid iOS to kill us here.
|
||||
NSLog(@"[PushNotificationService] iOS 13 and in bg, but we don't have the last callInvite event for the event %@. There is something wrong.", eventId);
|
||||
NSLog(@"[PushNotificationService] didReceiveIncomingPushWithPayload: iOS 13 and in bg, but we don't have the last callInvite event for the event %@. There is something wrong.", eventId);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -520,7 +514,7 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"[PushNotificationService] application is not in bg. There is something wrong.");
|
||||
NSLog(@"[PushNotificationService] didReceiveIncomingPushWithPayload: application is not in bg. There is something wrong.");
|
||||
}
|
||||
|
||||
completion();
|
||||
|
|
|
@ -19,7 +19,7 @@ import KeychainAccess
|
|||
import MatrixSDK
|
||||
|
||||
@objcMembers
|
||||
final class PushNotificationManager: NSObject {
|
||||
final class PushNotificationStore: NSObject {
|
||||
|
||||
// MARK: - Constants
|
||||
|
||||
|
@ -32,8 +32,6 @@ final class PushNotificationManager: NSObject {
|
|||
static let lastCallInvite: String = "lastCallInvite"
|
||||
}
|
||||
|
||||
static let shared = PushNotificationManager()
|
||||
|
||||
/// Store. Defaults to `KeychainStore`
|
||||
private let store: KeyValueStore
|
||||
|
|
@ -929,8 +929,15 @@
|
|||
{
|
||||
authInputsview = (AuthInputsView*)self.authInputsView;
|
||||
}
|
||||
|
||||
BOOL showForgotPasswordButton = NO;
|
||||
|
||||
self.forgotPasswordButton.hidden = (self.authType != MXKAuthenticationTypeLogin) || authInputsview.isSingleSignOnRequired;
|
||||
if (BuildSettings.authScreenShowForgotPassword)
|
||||
{
|
||||
showForgotPasswordButton = (self.authType == MXKAuthenticationTypeLogin) && !authInputsview.isSingleSignOnRequired;
|
||||
}
|
||||
|
||||
self.forgotPasswordButton.hidden = !showForgotPasswordButton;
|
||||
|
||||
// Adjust minimum leading constraint of the submit button
|
||||
if (self.forgotPasswordButton.isHidden)
|
||||
|
|
|
@ -204,6 +204,8 @@
|
|||
|
||||
if ([self isFlowSupported:kMXLoginFlowTypePassword])
|
||||
{
|
||||
BOOL showPhoneTextField = BuildSettings.authScreenShowPhoneNumber;
|
||||
|
||||
self.passWordTextField.returnKeyType = UIReturnKeyDone;
|
||||
self.phoneTextField.returnKeyType = UIReturnKeyNext;
|
||||
|
||||
|
@ -219,13 +221,27 @@
|
|||
attributes:@{NSForegroundColorAttributeName: ThemeService.shared.theme.placeholderTextColor}];
|
||||
|
||||
self.userLoginContainer.hidden = NO;
|
||||
self.messageLabel.hidden = NO;
|
||||
self.phoneContainer.hidden = NO;
|
||||
self.messageLabel.hidden = !showPhoneTextField;
|
||||
self.phoneContainer.hidden = !showPhoneTextField;
|
||||
self.passwordContainer.hidden = NO;
|
||||
|
||||
self.messageLabelTopConstraint.constant = 59;
|
||||
self.phoneContainerTopConstraint.constant = 70;
|
||||
self.passwordContainerTopConstraint.constant = 150;
|
||||
|
||||
CGFloat phoneContainerTopConstraintConstant = 0.0;
|
||||
CGFloat passwordContainerTopConstraintConstant = 0.0;
|
||||
|
||||
if (showPhoneTextField)
|
||||
{
|
||||
phoneContainerTopConstraintConstant = 70;
|
||||
passwordContainerTopConstraintConstant = 150;
|
||||
}
|
||||
else
|
||||
{
|
||||
passwordContainerTopConstraintConstant = 50;
|
||||
}
|
||||
|
||||
self.phoneContainerTopConstraint.constant = phoneContainerTopConstraintConstant;
|
||||
self.passwordContainerTopConstraint.constant = passwordContainerTopConstraintConstant;
|
||||
|
||||
self.currentLastContainer = self.passwordContainer;
|
||||
}
|
||||
|
@ -649,22 +665,9 @@
|
|||
|
||||
NSString *identityServer = restClient.identityServer;
|
||||
|
||||
// Create the next link that is common to all Vector.im clients
|
||||
NSString *nextLink = [NSString stringWithFormat:@"%@/#/register?client_secret=%@&hs_url=%@&session_id=%@",
|
||||
BuildSettings.applicationWebAppUrlString,
|
||||
[self->submittedEmail.clientSecret stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]],
|
||||
[restClient.homeserver stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]],
|
||||
[self->currentSession.session stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]]];
|
||||
|
||||
if (identityServer)
|
||||
{
|
||||
nextLink = [NSString stringWithFormat:@"%@&is_url=%@", nextLink,
|
||||
[identityServer stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]]];
|
||||
}
|
||||
|
||||
[self->submittedEmail requestValidationTokenWithMatrixRestClient:restClient
|
||||
isDuringRegistration:YES
|
||||
nextLink:nextLink
|
||||
nextLink:nil
|
||||
success:^
|
||||
{
|
||||
NSMutableDictionary *threepidCreds = [NSMutableDictionary dictionaryWithDictionary:@{
|
||||
|
|
|
@ -221,10 +221,6 @@
|
|||
[super viewWillDisappear:animated];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
}
|
||||
|
||||
#pragma mark - override MXKViewController
|
||||
|
||||
- (void)destroy
|
||||
|
@ -366,7 +362,7 @@
|
|||
{
|
||||
// Detect if we should display the prompt to fallback to the STUN server defined
|
||||
// in the app plist if the homeserver does not provide STUN or TURN servers.
|
||||
// We should if the call ends while we were in connecting state
|
||||
// We should display it if the call ends while we were in connecting state
|
||||
if (!self.mainSession.callManager.turnServers
|
||||
&& !self.mainSession.callManager.fallbackSTUNServer
|
||||
&& !RiotSettings.shared.isAllowStunServerFallbackHasBeenSetOnce)
|
||||
|
@ -388,6 +384,7 @@
|
|||
}
|
||||
|
||||
default:
|
||||
// There is nothing to do for other states
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,8 +30,7 @@ final class CameraAccessAlertPresenter {
|
|||
let alert = UIAlertController(title: VectorL10n.camera, message: VectorL10n.cameraAccessNotGranted(appDisplayName), preferredStyle: .alert)
|
||||
|
||||
let cancelActionTitle = Bundle.mxk_localizedString(forKey: "ok")
|
||||
let cancelAction = UIAlertAction(title: cancelActionTitle, style: .cancel, handler: { _ in
|
||||
})
|
||||
let cancelAction = UIAlertAction(title: cancelActionTitle, style: .cancel)
|
||||
|
||||
let settingsActionTitle = Bundle.mxk_localizedString(forKey: "settings")
|
||||
let settingsAction = UIAlertAction(title: settingsActionTitle, style: .default, handler: { _ in
|
||||
|
|
|
@ -14,19 +14,20 @@
|
|||
// limitations under the License.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
import Foundation
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/// Row object for tableviews
|
||||
@interface Row: NSObject
|
||||
|
||||
@property (nonatomic, assign) NSInteger tag;
|
||||
|
||||
+ (instancetype)rowWithTag:(NSInteger)tag;
|
||||
|
||||
- (instancetype)initWithTag:(NSInteger)tag;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@objcMembers
|
||||
final class Row: NSObject {
|
||||
|
||||
let tag: Int
|
||||
|
||||
init(withTag tag: Int) {
|
||||
self.tag = tag
|
||||
super.init()
|
||||
}
|
||||
|
||||
static func row(withTag tag: Int) -> Row {
|
||||
return Row(withTag: tag)
|
||||
}
|
||||
|
||||
}
|
52
Riot/Modules/Common/Models/Section.swift
Normal file
52
Riot/Modules/Common/Models/Section.swift
Normal file
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
// Copyright 2020 Vector Creations Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers
|
||||
final class Section: NSObject {
|
||||
|
||||
let tag: Int
|
||||
var rows: [Row]
|
||||
var headerTitle: String?
|
||||
|
||||
init(withTag tag: Int) {
|
||||
self.tag = tag
|
||||
self.rows = []
|
||||
super.init()
|
||||
}
|
||||
|
||||
static func section(withTag tag: Int) -> Section {
|
||||
return Section(withTag: tag)
|
||||
}
|
||||
|
||||
func addRow(_ row: Row) {
|
||||
rows.append(row)
|
||||
}
|
||||
|
||||
func addRow(withTag tag: Int) {
|
||||
addRow(Row.row(withTag: tag))
|
||||
}
|
||||
|
||||
func indexOfRow(withTag tag: Int) -> Int? {
|
||||
return rows.firstIndex(where: { $0.tag == tag })
|
||||
}
|
||||
|
||||
var hasAnyRows: Bool {
|
||||
return rows.count > 0
|
||||
}
|
||||
|
||||
}
|
97
Riot/Modules/Common/Models/TableViewSections.swift
Normal file
97
Riot/Modules/Common/Models/TableViewSections.swift
Normal file
|
@ -0,0 +1,97 @@
|
|||
//
|
||||
// Copyright 2020 Vector Creations Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objc
|
||||
protocol TableViewSectionsDelegate {
|
||||
func tableViewSectionsDidUpdateSections(_ sections: TableViewSections)
|
||||
}
|
||||
|
||||
@objcMembers
|
||||
final class TableViewSections: NSObject {
|
||||
|
||||
/// Delegate object
|
||||
weak var delegate: TableViewSectionsDelegate?
|
||||
|
||||
/// Sections. Updating this will trigger `tableViewSectionsDidUpdateSections` of the delegate object.
|
||||
var sections: [Section] = [] {
|
||||
didSet {
|
||||
delegate?.tableViewSectionsDidUpdateSections(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Finds the exact indexpath for the given row and section tag. If cannot find, returns nil
|
||||
/// - Parameters:
|
||||
/// - rowTag: Tag for row
|
||||
/// - sectionTag: Tag for section
|
||||
/// - Returns: IndexPath object if found, otherwise nil.
|
||||
func exactIndexPath(forRowTag rowTag: Int, sectionTag: Int) -> IndexPath? {
|
||||
guard let sectionIndex = sections.firstIndex(where: { $0.tag == sectionTag }) else {
|
||||
return nil
|
||||
}
|
||||
guard let indexOfRow = sections[sectionIndex].indexOfRow(withTag: rowTag) else {
|
||||
return nil
|
||||
}
|
||||
return IndexPath(row: indexOfRow, section: sectionIndex)
|
||||
}
|
||||
|
||||
/// Finds the nearest next indexPath for given row tag and section tag. If the section finishes, also checks for the next section. If cannot find any row available, returns nil.
|
||||
/// - Parameters:
|
||||
/// - rowTag: Tag for row
|
||||
/// - sectionTag: Tag for section
|
||||
/// - Returns: IndexPath object if found, otherwise nil.
|
||||
func nearestIndexPath(forRowTag rowTag: Int, sectionTag: Int) -> IndexPath? {
|
||||
let sectionIndex = sections.firstIndex(where: { $0.tag == sectionTag })
|
||||
|
||||
if let sectionIndex = sectionIndex {
|
||||
if let indexOfRow = sections[sectionIndex].indexOfRow(withTag: rowTag) {
|
||||
return IndexPath(row: indexOfRow, section: sectionIndex)
|
||||
} else if rowTag + 1 < sections[sectionIndex].rows.count {
|
||||
return nearestIndexPath(forRowTag: rowTag + 1, sectionTag: sectionTag)
|
||||
} else if sectionTag + 1 < sections.count {
|
||||
return nearestIndexPath(forRowTag: 0, sectionTag: sectionTag + 1)
|
||||
}
|
||||
} else if sectionTag + 1 < sections.count {
|
||||
// try to return the first row of the next section
|
||||
return nearestIndexPath(forRowTag: 0, sectionTag: sectionTag + 1)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Section at index.
|
||||
/// - Parameter index: Index of desired section
|
||||
/// - Returns: Section object if index is in bounds of the sections array. Otherwise nil.
|
||||
func section(atIndex index: Int) -> Section? {
|
||||
if index < sections.count {
|
||||
return sections[index]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func tagsIndexPath(fromTableViewIndexPath indexPath: IndexPath) -> IndexPath? {
|
||||
guard let section = section(atIndex: indexPath.section) else {
|
||||
// section not found
|
||||
return nil
|
||||
}
|
||||
guard indexPath.row < section.rows.count else {
|
||||
return nil
|
||||
}
|
||||
return IndexPath(row: section.rows[indexPath.row].tag, section: section.tag)
|
||||
}
|
||||
|
||||
}
|
|
@ -615,48 +615,6 @@
|
|||
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
|
||||
|
||||
// [currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_recents_start_chat_with", @"Vector", nil)
|
||||
// style:UIAlertActionStyleDefault
|
||||
// handler:^(UIAlertAction * action) {
|
||||
//
|
||||
// if (weakSelf)
|
||||
// {
|
||||
// typeof(self) self = weakSelf;
|
||||
// self->currentAlert = nil;
|
||||
//
|
||||
// [self performSegueWithIdentifier:@"presentStartChat" sender:self];
|
||||
// }
|
||||
//
|
||||
// }]];
|
||||
//
|
||||
// [currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_recents_create_empty_room", @"Vector", nil)
|
||||
// style:UIAlertActionStyleDefault
|
||||
// handler:^(UIAlertAction * action) {
|
||||
//
|
||||
// if (weakSelf)
|
||||
// {
|
||||
// typeof(self) self = weakSelf;
|
||||
// self->currentAlert = nil;
|
||||
//
|
||||
// [self createAnEmptyRoom];
|
||||
// }
|
||||
//
|
||||
// }]];
|
||||
//
|
||||
// [currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_recents_join_room", @"Vector", nil)
|
||||
// style:UIAlertActionStyleDefault
|
||||
// handler:^(UIAlertAction * action) {
|
||||
//
|
||||
// if (weakSelf)
|
||||
// {
|
||||
// typeof(self) self = weakSelf;
|
||||
// self->currentAlert = nil;
|
||||
//
|
||||
// [self joinARoom];
|
||||
// }
|
||||
//
|
||||
// }]];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
@ -676,76 +634,6 @@
|
|||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
}
|
||||
|
||||
//- (void)joinARoom
|
||||
//{
|
||||
// [currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
//
|
||||
// __weak typeof(self) weakSelf = self;
|
||||
//
|
||||
// // Prompt the user to type a room id or room alias
|
||||
// currentAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"room_recents_join_room_title", @"Vector", nil)
|
||||
// message:NSLocalizedStringFromTable(@"room_recents_join_room_prompt", @"Vector", nil)
|
||||
// preferredStyle:UIAlertControllerStyleAlert];
|
||||
//
|
||||
// [currentAlert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
|
||||
//
|
||||
// textField.secureTextEntry = NO;
|
||||
// textField.placeholder = nil;
|
||||
// textField.keyboardType = UIKeyboardTypeDefault;
|
||||
// }];
|
||||
//
|
||||
// [currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
|
||||
// style:UIAlertActionStyleDefault
|
||||
// handler:^(UIAlertAction * action) {
|
||||
//
|
||||
// if (weakSelf)
|
||||
// {
|
||||
// typeof(self) self = weakSelf;
|
||||
// self->currentAlert = nil;
|
||||
// }
|
||||
//
|
||||
// }]];
|
||||
//
|
||||
// [currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"join", @"Vector", nil)
|
||||
// style:UIAlertActionStyleDefault
|
||||
// handler:^(UIAlertAction * action) {
|
||||
//
|
||||
// if (weakSelf)
|
||||
// {
|
||||
// typeof(self) self = weakSelf;
|
||||
//
|
||||
// NSString *roomAliasOrId = [self->currentAlert textFields].firstObject.text;
|
||||
//
|
||||
// self->currentAlert = nil;
|
||||
//
|
||||
// [self.activityIndicator startAnimating];
|
||||
//
|
||||
// self->currentRequest = [self.mainSession joinRoom:roomAliasOrId success:^(MXRoom *room) {
|
||||
//
|
||||
// self->currentRequest = nil;
|
||||
// [self.activityIndicator stopAnimating];
|
||||
//
|
||||
// // Show the room
|
||||
// [[AppDelegate theDelegate] showRoom:room.roomId andEventId:nil withMatrixSession:self.mainSession];
|
||||
//
|
||||
// } failure:^(NSError *error) {
|
||||
//
|
||||
// NSLog(@"[RecentsViewController] Join joinARoom (%@) failed", roomAliasOrId);
|
||||
//
|
||||
// self->currentRequest = nil;
|
||||
// [self.activityIndicator stopAnimating];
|
||||
//
|
||||
// // Alert user
|
||||
// [[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
// }];
|
||||
// }
|
||||
//
|
||||
// }]];
|
||||
//
|
||||
// [currentAlert mxk_setAccessibilityIdentifier:@"RecentsVCJoinARoomAlert"];
|
||||
// [self presentViewController:currentAlert animated:YES completion:nil];
|
||||
//}
|
||||
|
||||
#pragma mark - Table view scrolling
|
||||
|
||||
- (void)scrollToTop:(BOOL)animated
|
||||
|
|
|
@ -577,25 +577,6 @@
|
|||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
}
|
||||
|
||||
//- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
//{
|
||||
// NSMutableArray* actions;
|
||||
//
|
||||
// // @TODO Add the swipe to remove this room from the community if the current user is admin
|
||||
// actions = [[NSMutableArray alloc] init];
|
||||
//
|
||||
// // Patch: Force the width of the button by adding whitespace characters into the title string.
|
||||
// UITableViewRowAction *leaveAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@" " handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){
|
||||
//
|
||||
// // @TODO Remove the room
|
||||
//
|
||||
// }];
|
||||
//
|
||||
// leaveAction.backgroundColor = [MXKTools convertImageToPatternColor:@"remove_icon_blue" backgroundColor:ThemeService.shared.theme.headerBackgroundColor patternSize:CGSizeMake(74, 74) resourceSize:CGSizeMake(24, 24)];
|
||||
// [actions insertObject:leaveAction atIndex:0];
|
||||
//
|
||||
// return actions;
|
||||
//}
|
||||
|
||||
#pragma mark - UISearchBar delegate
|
||||
|
||||
|
|
|
@ -66,11 +66,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (void)destroy
|
||||
{
|
||||
[super destroy];
|
||||
|
|
|
@ -114,11 +114,6 @@
|
|||
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (void)destroy
|
||||
{
|
||||
[super destroy];
|
||||
|
|
|
@ -349,7 +349,7 @@ NSString *const kIntegrationManagerAddIntegrationScreen = @"add_integ";
|
|||
|
||||
if (!widget_id)
|
||||
{
|
||||
[self sendLocalisedError:@"widget_integration_unable_to_create" toRequest:requestId]; // new Error("Missing required widget fields."));
|
||||
[self sendLocalisedError:@"widget_integration_unable_to_create" toRequest:requestId];
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -213,10 +213,12 @@ static const NSString *kJitsiDataErrorKey = @"error";
|
|||
|
||||
- (void)conferenceWillJoin:(NSDictionary *)data
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
- (void)conferenceJoined:(NSDictionary *)data
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
- (void)conferenceTerminated:(NSDictionary *)data
|
||||
|
|
|
@ -40,8 +40,6 @@ final class KeyBackupRecoverFromPrivateKeyViewModel: KeyBackupRecoverFromPrivate
|
|||
self.keyBackupVersion = keyBackupVersion
|
||||
}
|
||||
|
||||
deinit {
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
|
|
|
@ -128,7 +128,9 @@ final class KeyVerificationCoordinatorBridgePresenter: NSObject {
|
|||
|
||||
private func present(coordinator keyVerificationCoordinator: KeyVerificationCoordinator, from viewController: UIViewController, animated: Bool) {
|
||||
keyVerificationCoordinator.delegate = self
|
||||
viewController.present(keyVerificationCoordinator.toPresentable(), animated: animated, completion: nil)
|
||||
let presentable = keyVerificationCoordinator.toPresentable()
|
||||
presentable.presentationController?.delegate = self
|
||||
viewController.present(presentable, animated: animated, completion: nil)
|
||||
keyVerificationCoordinator.start()
|
||||
|
||||
self.coordinator = keyVerificationCoordinator
|
||||
|
@ -146,3 +148,13 @@ extension KeyVerificationCoordinatorBridgePresenter: KeyVerificationCoordinatorD
|
|||
self.delegate?.keyVerificationCoordinatorBridgePresenterDelegateDidCancel(self)
|
||||
}
|
||||
}
|
||||
|
||||
extension KeyVerificationCoordinatorBridgePresenter: UIAdaptivePresentationControllerDelegate {
|
||||
|
||||
func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
|
||||
if let coordinator = self.coordinator {
|
||||
keyVerificationCoordinatorDidCancel(coordinator)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -53,9 +53,6 @@ final class KeyVerificationScanConfirmationViewModel: KeyVerificationScanConfirm
|
|||
self.verificationKind = verificationKind
|
||||
}
|
||||
|
||||
deinit {
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func process(viewAction: KeyVerificationScanConfirmationViewAction) {
|
||||
|
|
|
@ -46,9 +46,6 @@ final class KeyVerificationVerifyBySASViewModel: KeyVerificationVerifyBySASViewM
|
|||
self.verificationKind = verificationKind
|
||||
}
|
||||
|
||||
deinit {
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func process(viewAction: KeyVerificationVerifyBySASViewAction) {
|
||||
|
|
|
@ -51,10 +51,7 @@ final class DeviceVerificationIncomingViewModel: DeviceVerificationIncomingViewM
|
|||
|
||||
self.mediaManager = session.mediaManager
|
||||
}
|
||||
|
||||
deinit {
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func process(viewAction: DeviceVerificationIncomingViewAction) {
|
||||
|
|
|
@ -45,9 +45,6 @@ final class KeyVerificationSelfVerifyStartViewModel: KeyVerificationSelfVerifySt
|
|||
self.keyVerificationService = KeyVerificationService()
|
||||
}
|
||||
|
||||
deinit {
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func process(viewAction: KeyVerificationSelfVerifyStartViewAction) {
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="79A-qb-tmk">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="79A-qb-tmk">
|
||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
|
@ -19,16 +17,16 @@
|
|||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="asO-rj-82y">
|
||||
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tIM-sl-gwE">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="412.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="527"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IlB-Ch-LEo">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="412.5"/>
|
||||
<rect key="frame" x="27.5" y="0.0" width="320" height="527"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="d5Y-pj-XsI">
|
||||
<rect key="frame" x="20" y="20" width="335" height="84"/>
|
||||
<rect key="frame" x="20" y="20" width="280" height="84"/>
|
||||
<string key="text">Verify this session from one of your others sessions, granting it access to encrypted messages.
|
||||
|
||||
Use the latest Riot on your other devices:</string>
|
||||
|
@ -37,7 +35,7 @@ Use the latest Riot on your other devices:</string>
|
|||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="ANK-XS-dY7">
|
||||
<rect key="frame" x="27.5" y="144" width="320" height="95.5"/>
|
||||
<rect key="frame" x="0.0" y="144" width="320" height="95.5"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="14" translatesAutoresizingMaskIntoConstraints="NO" id="3at-ql-vhb">
|
||||
<rect key="frame" x="0.0" y="0.0" width="160" height="95.5"/>
|
||||
|
@ -85,19 +83,43 @@ Riot X for Android</string>
|
|||
</constraints>
|
||||
</stackView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="or another cross-signing capable Matrix client" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rFM-AQ-wAB">
|
||||
<rect key="frame" x="20" y="259.5" width="335" height="14.5"/>
|
||||
<rect key="frame" x="20" y="259.5" width="280" height="14.5"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
|
||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="8oJ-o6-DLK">
|
||||
<rect key="frame" x="20" y="294" width="335" height="118.5"/>
|
||||
<rect key="frame" x="20" y="294" width="280" height="233"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="dXT-cL-ukJ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="280" height="114.5"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Checking for other verification capabilities ..." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="A4x-sK-d5C">
|
||||
<rect key="frame" x="20" y="10" width="240" 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>
|
||||
<activityIndicatorView opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" style="medium" translatesAutoresizingMaskIntoConstraints="NO" id="esP-Lt-anU">
|
||||
<rect key="frame" x="0.0" y="64.5" width="280" height="20"/>
|
||||
</activityIndicatorView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="esP-Lt-anU" firstAttribute="leading" secondItem="dXT-cL-ukJ" secondAttribute="leading" id="1Rg-vU-DJm"/>
|
||||
<constraint firstItem="A4x-sK-d5C" firstAttribute="top" secondItem="dXT-cL-ukJ" secondAttribute="top" constant="10" id="7We-Ox-BZt"/>
|
||||
<constraint firstItem="A4x-sK-d5C" firstAttribute="leading" secondItem="dXT-cL-ukJ" secondAttribute="leading" constant="20" id="FuM-Cv-7mT"/>
|
||||
<constraint firstAttribute="trailing" secondItem="A4x-sK-d5C" secondAttribute="trailing" constant="20" id="Lk0-BP-Fdw"/>
|
||||
<constraint firstAttribute="trailing" secondItem="esP-Lt-anU" secondAttribute="trailing" id="SJY-m2-DP4"/>
|
||||
<constraint firstItem="esP-Lt-anU" firstAttribute="top" secondItem="A4x-sK-d5C" secondAttribute="bottom" constant="16" id="Tif-UR-9I2"/>
|
||||
<constraint firstAttribute="bottom" secondItem="esP-Lt-anU" secondAttribute="bottom" constant="30" id="gcZ-sx-3Ff"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nf8-Ye-b9r">
|
||||
<rect key="frame" x="0.0" y="0.0" width="335" height="118.5"/>
|
||||
<rect key="frame" x="0.0" y="114.5" width="280" height="118.5"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="OEt-k0-vgM" customClass="RoundedButton" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="10" width="335" height="44"/>
|
||||
<rect key="frame" x="0.0" y="10" width="280" height="44"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="44" id="7ws-Nc-I7y"/>
|
||||
</constraints>
|
||||
|
@ -110,7 +132,7 @@ Riot X for Android</string>
|
|||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="If you can't accessing an existing session" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4Ou-cM-K9C">
|
||||
<rect key="frame" x="20" y="64" width="295" height="24.5"/>
|
||||
<rect key="frame" x="20" y="64" width="240" height="24.5"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
|
||||
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
|
@ -189,6 +211,9 @@ Riot X for Android</string>
|
|||
<outlet property="mobileClientImageView" destination="P0P-X4-uSQ" id="WtT-ix-yq8"/>
|
||||
<outlet property="mobileClientLabel" destination="gLH-sE-KCq" id="jQ0-7U-mr8"/>
|
||||
<outlet property="recoverSecretsAdditionalInformationLabel" destination="4Ou-cM-K9C" id="80N-lF-x2L"/>
|
||||
<outlet property="recoverSecretsAvailabilityActivityIndicatorView" destination="esP-Lt-anU" id="4jv-GA-Hm9"/>
|
||||
<outlet property="recoverSecretsAvailabilityLoadingContainerView" destination="dXT-cL-ukJ" id="rBM-Hj-c3o"/>
|
||||
<outlet property="recoverSecretsAvailabilityLoadingLabel" destination="A4x-sK-d5C" id="n5k-IO-RkV"/>
|
||||
<outlet property="recoverSecretsButton" destination="OEt-k0-vgM" id="RHU-ps-4m7"/>
|
||||
<outlet property="recoverSecretsContainerView" destination="nf8-Ye-b9r" id="4az-pe-0Uc"/>
|
||||
</connections>
|
||||
|
|
|
@ -40,7 +40,9 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController {
|
|||
|
||||
@IBOutlet private weak var additionalInformationLabel: UILabel!
|
||||
|
||||
|
||||
@IBOutlet private weak var recoverSecretsAvailabilityLoadingContainerView: UIView!
|
||||
@IBOutlet private weak var recoverSecretsAvailabilityLoadingLabel: UILabel!
|
||||
@IBOutlet private weak var recoverSecretsAvailabilityActivityIndicatorView: UIActivityIndicatorView!
|
||||
@IBOutlet private weak var recoverSecretsContainerView: UIView!
|
||||
@IBOutlet private weak var recoverSecretsButton: RoundedButton!
|
||||
@IBOutlet private weak var recoverSecretsAdditionalInformationLabel: UILabel!
|
||||
|
@ -102,6 +104,8 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController {
|
|||
self.mobileClientLabel.textColor = theme.textPrimaryColor
|
||||
self.mobileClientImageView.tintColor = theme.tintColor
|
||||
self.additionalInformationLabel.textColor = theme.textSecondaryColor
|
||||
self.recoverSecretsAvailabilityLoadingLabel.textColor = theme.textSecondaryColor
|
||||
self.recoverSecretsAvailabilityActivityIndicatorView.color = theme.tintColor
|
||||
}
|
||||
|
||||
private func registerThemeServiceDidChangeThemeNotification() {
|
||||
|
@ -141,6 +145,8 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController {
|
|||
switch viewState {
|
||||
case .loading:
|
||||
self.renderLoading()
|
||||
case .secretsRecoveryCheckingAvailability(let text):
|
||||
self.renderSecretsRecoveryCheckingAvailability(withText: text)
|
||||
case .loaded(let viewData):
|
||||
self.renderLoaded(viewData: viewData)
|
||||
case .cancelled(let reason):
|
||||
|
@ -156,6 +162,13 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController {
|
|||
self.activityPresenter.presentActivityIndicator(on: self.view, animated: true)
|
||||
}
|
||||
|
||||
private func renderSecretsRecoveryCheckingAvailability(withText text: String?) {
|
||||
self.recoverSecretsAvailabilityLoadingLabel.text = text
|
||||
self.recoverSecretsAvailabilityActivityIndicatorView.startAnimating()
|
||||
self.recoverSecretsAvailabilityLoadingContainerView.isHidden = false
|
||||
self.recoverSecretsContainerView.isHidden = true
|
||||
}
|
||||
|
||||
private func renderLoaded(viewData: KeyVerificationSelfVerifyWaitViewData) {
|
||||
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
|
||||
|
||||
|
@ -180,6 +193,8 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController {
|
|||
}
|
||||
}
|
||||
|
||||
self.recoverSecretsAvailabilityLoadingContainerView.isHidden = true
|
||||
self.recoverSecretsAvailabilityActivityIndicatorView.stopAnimating()
|
||||
self.recoverSecretsContainerView.isHidden = hideRecoverSecrets
|
||||
self.recoverSecretsButton.setTitle(recoverSecretsButtonTitle, for: .normal)
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
|
|||
private let keyVerificationService: KeyVerificationService
|
||||
private let verificationManager: MXKeyVerificationManager
|
||||
private let isNewSignIn: Bool
|
||||
private let secretsRecoveryAvailability: SecretsRecoveryAvailability
|
||||
private var secretsRecoveryAvailability: SecretsRecoveryAvailability
|
||||
private var keyVerificationRequest: MXKeyVerificationRequest?
|
||||
|
||||
// MARK: Public
|
||||
|
@ -62,7 +62,8 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
|
|||
switch self.secretsRecoveryAvailability {
|
||||
case .notAvailable:
|
||||
fatalError("Should not happen: When recovery is not available button is hidden")
|
||||
case .available(let secretsRecoveryMode): self.coordinatorDelegate?.keyVerificationSelfVerifyWaitViewModel(self, wantsToRecoverSecretsWith: secretsRecoveryMode)
|
||||
case .available(let secretsRecoveryMode):
|
||||
self.coordinatorDelegate?.keyVerificationSelfVerifyWaitViewModel(self, wantsToRecoverSecretsWith: secretsRecoveryMode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +86,31 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
|
|||
}, failure: { [weak self] error in
|
||||
self?.update(viewState: .error(error))
|
||||
})
|
||||
|
||||
continueLoadData()
|
||||
} else {
|
||||
// be sure that session has completed its first sync
|
||||
if session.state >= MXSessionStateRunning {
|
||||
continueLoadData()
|
||||
} else {
|
||||
// show loader
|
||||
self.update(viewState: .secretsRecoveryCheckingAvailability(VectorL10n.deviceVerificationSelfVerifyWaitRecoverSecretsCheckingAvailability))
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(sessionStateChanged), name: .mxSessionStateDidChange, object: session)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
private func sessionStateChanged() {
|
||||
if session.state >= MXSessionStateRunning {
|
||||
NotificationCenter.default.removeObserver(self, name: .mxSessionStateDidChange, object: session)
|
||||
continueLoadData()
|
||||
}
|
||||
}
|
||||
|
||||
private func continueLoadData() {
|
||||
// update availability again
|
||||
self.secretsRecoveryAvailability = session.crypto.recoveryService.vc_availability
|
||||
|
||||
let viewData = KeyVerificationSelfVerifyWaitViewData(isNewSignIn: self.isNewSignIn, secretsRecoveryAvailability: self.secretsRecoveryAvailability)
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ struct KeyVerificationSelfVerifyWaitViewData {
|
|||
/// KeyVerificationSelfVerifyWaitViewController view state
|
||||
enum KeyVerificationSelfVerifyWaitViewState {
|
||||
case loading
|
||||
case secretsRecoveryCheckingAvailability(_ text: String?)
|
||||
case loaded(_ viewData: KeyVerificationSelfVerifyWaitViewData)
|
||||
case cancelled(MXTransactionCancelCode)
|
||||
case cancelledByMe(MXTransactionCancelCode)
|
||||
|
|
|
@ -45,9 +45,6 @@ final class DeviceVerificationStartViewModel: DeviceVerificationStartViewModelTy
|
|||
self.otherDevice = otherDevice
|
||||
}
|
||||
|
||||
deinit {
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func process(viewAction: DeviceVerificationStartViewAction) {
|
||||
|
|
|
@ -59,9 +59,6 @@ final class UserVerificationStartViewModel: UserVerificationStartViewModelType {
|
|||
self.keyVerificationService = KeyVerificationService()
|
||||
}
|
||||
|
||||
deinit {
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func process(viewAction: UserVerificationStartViewAction) {
|
||||
|
|
|
@ -134,8 +134,7 @@ final class UserVerificationCoordinator: NSObject, UserVerificationCoordinatorTy
|
|||
message: VectorL10n.keyVerificationBootstrapNotSetupMessage,
|
||||
preferredStyle: .alert)
|
||||
|
||||
let cancelAction = UIAlertAction(title: Bundle.mxk_localizedString(forKey: "ok"), style: .cancel, handler: { _ in
|
||||
})
|
||||
let cancelAction = UIAlertAction(title: Bundle.mxk_localizedString(forKey: "ok"), style: .cancel)
|
||||
alert.addAction(cancelAction)
|
||||
|
||||
self.presenter.toPresentable().present(alert, animated: true, completion: nil)
|
||||
|
|
|
@ -64,8 +64,7 @@ final class SingleImagePickerPresenter: NSObject {
|
|||
self.presentPhotoLibray(sourceView: sourceView, sourceRect: sourceRect, animated: animated)
|
||||
})
|
||||
|
||||
let cancelAction = UIAlertAction(title: VectorL10n.cancel, style: .cancel, handler: { _ in
|
||||
})
|
||||
let cancelAction = UIAlertAction(title: VectorL10n.cancel, style: .cancel)
|
||||
|
||||
alert.addAction(cameraAction)
|
||||
alert.addAction(photoLibraryAction)
|
||||
|
|
|
@ -792,8 +792,8 @@
|
|||
// Refresh here the preview header according to the coming screen orientation.
|
||||
|
||||
// Retrieve the affine transform indicating the amount of rotation being applied to the interface.
|
||||
// This transform is the identity transform when no rotation is applied;
|
||||
// otherwise, it is a transform that applies a 90 degree, -90 degree, or 180 degree rotation.
|
||||
// This transform is the identity transform when no rotation is applied.
|
||||
// Otherwise, it is a transform that applies a 90 degree, -90 degree, or 180 degree rotation.
|
||||
CGAffineTransform transform = coordinator.targetTransform;
|
||||
|
||||
// Consider here only the transform that applies a +/- 90 degree.
|
||||
|
@ -2609,40 +2609,43 @@
|
|||
}
|
||||
else // Add action for attachment
|
||||
{
|
||||
if (attachment.type == MXKAttachmentTypeImage || attachment.type == MXKAttachmentTypeVideo)
|
||||
if (BuildSettings.messageDetailsAllowSave)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_save", @"Vector", nil)
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
|
||||
[self cancelEventSelection];
|
||||
|
||||
[self startActivityIndicator];
|
||||
|
||||
[attachment save:^{
|
||||
|
||||
__strong __typeof(weakSelf)self = weakSelf;
|
||||
[self stopActivityIndicator];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
__strong __typeof(weakSelf)self = weakSelf;
|
||||
[self stopActivityIndicator];
|
||||
|
||||
//Alert user
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
|
||||
}];
|
||||
|
||||
// Start animation in case of download during attachment preparing
|
||||
[roomBubbleTableViewCell startProgressUI];
|
||||
}
|
||||
|
||||
}]];
|
||||
if (attachment.type == MXKAttachmentTypeImage || attachment.type == MXKAttachmentTypeVideo)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_save", @"Vector", nil)
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
|
||||
[self cancelEventSelection];
|
||||
|
||||
[self startActivityIndicator];
|
||||
|
||||
[attachment save:^{
|
||||
|
||||
__strong __typeof(weakSelf)self = weakSelf;
|
||||
[self stopActivityIndicator];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
__strong __typeof(weakSelf)self = weakSelf;
|
||||
[self stopActivityIndicator];
|
||||
|
||||
//Alert user
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
|
||||
}];
|
||||
|
||||
// Start animation in case of download during attachment preparing
|
||||
[roomBubbleTableViewCell startProgressUI];
|
||||
}
|
||||
|
||||
}]];
|
||||
}
|
||||
}
|
||||
|
||||
// Check status of the selected event
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -248,14 +248,6 @@
|
|||
|
||||
#pragma mark - HPGrowingTextView delegate
|
||||
|
||||
//- (BOOL)growingTextViewShouldReturn:(HPGrowingTextView *)hpGrowingTextView
|
||||
//{
|
||||
// // The return sends the message rather than giving a carriage return.
|
||||
// [self onTouchUpInside:self.rightInputToolbarButton];
|
||||
//
|
||||
// return NO;
|
||||
//}
|
||||
|
||||
- (void)growingTextViewDidChange:(HPGrowingTextView *)hpGrowingTextView
|
||||
{
|
||||
// Clean the carriage return added on return press
|
||||
|
|
|
@ -84,11 +84,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (void)destroy
|
||||
{
|
||||
[super destroy];
|
||||
|
|
|
@ -48,9 +48,6 @@ final class ServiceTermsModalScreenViewModel: ServiceTermsModalScreenViewModelTy
|
|||
self.outOfContext = outOfContext
|
||||
}
|
||||
|
||||
deinit {
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func process(viewAction: ServiceTermsModalScreenViewAction) {
|
||||
|
|
|
@ -111,6 +111,8 @@ final class PinCodePreferences: NSObject {
|
|||
func localizedBiometricsName() -> String? {
|
||||
if isBiometricsAvailable {
|
||||
let context = LAContext()
|
||||
// canEvaluatePolicy should be called for biometryType to be set
|
||||
_ = context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil)
|
||||
switch context.biometryType {
|
||||
case .touchID:
|
||||
return VectorL10n.biometricsModeTouchId
|
||||
|
@ -126,6 +128,8 @@ final class PinCodePreferences: NSObject {
|
|||
func biometricsIcon() -> UIImage? {
|
||||
if isBiometricsAvailable {
|
||||
let context = LAContext()
|
||||
// canEvaluatePolicy should be called for biometryType to be set
|
||||
_ = context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil)
|
||||
switch context.biometryType {
|
||||
case .touchID:
|
||||
return Asset.Images.touchidIcon.image
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
//
|
||||
// Copyright 2020 Vector Creations Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class Row;
|
||||
|
||||
/// Section object for tableviews
|
||||
@interface Section: NSObject
|
||||
|
||||
@property (nonatomic, assign) NSInteger tag;
|
||||
@property (nonatomic, strong) NSMutableArray<Row*> *rows;
|
||||
@property (nonatomic, copy) NSString *headerTitle;
|
||||
|
||||
+ (instancetype)sectionWithTag:(NSInteger)tag;
|
||||
- (instancetype)initWithTag:(NSInteger)tag;
|
||||
|
||||
- (void)addRow:(Row *)row;
|
||||
- (void)addRowWithTag:(NSInteger)tag;
|
||||
- (NSInteger)indexOfRowForTag:(NSInteger)tag;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -1,54 +0,0 @@
|
|||
//
|
||||
// Copyright 2020 Vector Creations Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
#import "Section.h"
|
||||
#import "Row.h"
|
||||
|
||||
@implementation Section
|
||||
|
||||
+ (instancetype)sectionWithTag:(NSInteger)tag
|
||||
{
|
||||
return [[self alloc] initWithTag:tag];
|
||||
}
|
||||
|
||||
- (instancetype)initWithTag:(NSInteger)tag
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.tag = tag;
|
||||
_rows = [NSMutableArray arrayWithCapacity:10];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)addRow:(Row *)row
|
||||
{
|
||||
[_rows addObject:row];
|
||||
}
|
||||
|
||||
- (void)addRowWithTag:(NSInteger)tag
|
||||
{
|
||||
[_rows addObject:[Row rowWithTag:tag]];
|
||||
}
|
||||
|
||||
- (NSInteger)indexOfRowForTag:(NSInteger)tag
|
||||
{
|
||||
return [_rows indexOfObjectPassingTest:^BOOL(Row * _Nonnull row, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
return row.tag == tag;
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
|
@ -732,7 +732,6 @@ enum {
|
|||
{
|
||||
NSLog(@"[ManageSessionVC] Delete device (%@) failed, auth session flow type is not supported", self->device.deviceId);
|
||||
[self.activityIndicator stopAnimating];
|
||||
//[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
}
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
|
|
@ -42,9 +42,6 @@
|
|||
#import "GroupsDataSource.h"
|
||||
#import "GroupTableViewCellWithSwitch.h"
|
||||
|
||||
#import "Row.h"
|
||||
#import "Section.h"
|
||||
|
||||
#import "GBDeviceInfo_iOS.h"
|
||||
|
||||
#import "Riot-Swift.h"
|
||||
|
@ -96,12 +93,6 @@ enum
|
|||
NOTIFICATION_SETTINGS_GLOBAL_SETTINGS_INDEX,
|
||||
NOTIFICATION_SETTINGS_PIN_MISSED_NOTIFICATIONS_INDEX,
|
||||
NOTIFICATION_SETTINGS_PIN_UNREAD_INDEX,
|
||||
//NOTIFICATION_SETTINGS_CONTAINING_MY_USER_NAME_INDEX,
|
||||
//NOTIFICATION_SETTINGS_CONTAINING_MY_DISPLAY_NAME_INDEX,
|
||||
//NOTIFICATION_SETTINGS_SENT_TO_ME_INDEX,
|
||||
//NOTIFICATION_SETTINGS_INVITED_TO_ROOM_INDEX,
|
||||
//NOTIFICATION_SETTINGS_PEOPLE_LEAVE_JOIN_INDEX,
|
||||
//NOTIFICATION_SETTINGS_CALL_INVITATION_INDEX,
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -167,11 +158,12 @@ SecureBackupSetupCoordinatorBridgePresenterDelegate,
|
|||
SignOutAlertPresenterDelegate,
|
||||
SingleImagePickerPresenterDelegate,
|
||||
SettingsDiscoveryTableViewSectionDelegate, SettingsDiscoveryViewModelCoordinatorDelegate,
|
||||
SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
||||
SettingsIdentityServerCoordinatorBridgePresenterDelegate,
|
||||
TableViewSectionsDelegate>
|
||||
{
|
||||
// Current alert (if any).
|
||||
UIAlertController *currentAlert;
|
||||
|
||||
|
||||
// listener
|
||||
id removedAccountObserver;
|
||||
id accountUserInfoObserver;
|
||||
|
@ -253,7 +245,7 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
@property (nonatomic, strong) SecureBackupSetupCoordinatorBridgePresenter *secureBackupSetupCoordinatorBridgePresenter;
|
||||
@property (nonatomic, strong) AuthenticatedSessionViewControllerFactory *authenticatedSessionViewControllerFactory;
|
||||
|
||||
@property (nonatomic, strong) NSArray<Section*> *sections;
|
||||
@property (nonatomic, strong) TableViewSections *tableViewSections;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -470,78 +462,7 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
}
|
||||
|
||||
// update sections
|
||||
self.sections = tmpSections;
|
||||
}
|
||||
|
||||
- (void)setSections:(NSArray<Section *> *)sections
|
||||
{
|
||||
_sections = sections;
|
||||
|
||||
// reload table
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
/// Returns index of section for the given tag. If cannot find, return `NSNotFound`
|
||||
/// @param tag Tag for section
|
||||
- (NSInteger)indexOfSectionForTag:(NSInteger)tag
|
||||
{
|
||||
return [_sections indexOfObjectPassingTest:^BOOL(Section * _Nonnull section, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
return section.tag == tag;
|
||||
}];
|
||||
}
|
||||
|
||||
/// Finds the exact indexpath for the given row and section tag. If cannot find, returns nil
|
||||
/// @param rowTag Tag for row
|
||||
/// @param sectionTag Tag for section
|
||||
- (NSIndexPath *)exactIndexPathForRowTag:(NSInteger)rowTag sectionTag:(NSInteger)sectionTag
|
||||
{
|
||||
NSInteger sectionIndex = [self indexOfSectionForTag:sectionTag];
|
||||
if (sectionIndex != NSNotFound)
|
||||
{
|
||||
Section *section = _sections[sectionIndex];
|
||||
NSInteger rowIndex = [section indexOfRowForTag:rowTag];
|
||||
if (rowIndex != NSNotFound)
|
||||
{
|
||||
return [NSIndexPath indexPathForRow:rowIndex inSection:sectionIndex];
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
/// Finds the nearest next indexPath for given row tag and section tag. If the section finishes, also checks for the next section. If cannot find any row available, returns nil.
|
||||
/// @param rowTag Tag for row
|
||||
/// @param sectionTag Tag for section
|
||||
- (NSIndexPath *)nearestIndexPathForRowTag:(NSInteger)rowTag sectionTag:(NSInteger)sectionTag
|
||||
{
|
||||
NSInteger sectionIndex = [self indexOfSectionForTag:sectionTag];
|
||||
if (sectionIndex != NSNotFound)
|
||||
{
|
||||
Section *section = _sections[sectionIndex];
|
||||
NSInteger rowIndex = [section indexOfRowForTag:rowTag];
|
||||
if (rowIndex != NSNotFound)
|
||||
{
|
||||
// exact row found, return it
|
||||
return [NSIndexPath indexPathForRow:rowIndex inSection:sectionIndex];
|
||||
}
|
||||
else if (rowTag + 1 < section.rows.count)
|
||||
{
|
||||
// try to return next row in the same section
|
||||
return [self nearestIndexPathForRowTag:rowTag + 1 sectionTag:sectionTag];
|
||||
}
|
||||
else if (sectionTag + 1 < _sections.count)
|
||||
{
|
||||
// try to return the first row of the next section
|
||||
return [self nearestIndexPathForRowTag:0 sectionTag:sectionTag + 1];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
else if (sectionTag + 1 < _sections.count)
|
||||
{
|
||||
// try to return the first row of the next section
|
||||
return [self nearestIndexPathForRowTag:0 sectionTag:sectionTag + 1];
|
||||
}
|
||||
return nil;
|
||||
_tableViewSections.sections = tmpSections;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
|
@ -624,6 +545,8 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
self.signOutAlertPresenter = [SignOutAlertPresenter new];
|
||||
self.signOutAlertPresenter.delegate = self;
|
||||
|
||||
_tableViewSections = [TableViewSections new];
|
||||
_tableViewSections.delegate = self;
|
||||
[self updateSections];
|
||||
}
|
||||
|
||||
|
@ -881,8 +804,8 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
[self.tableView beginUpdates];
|
||||
|
||||
// Refresh the corresponding table view cell with animation
|
||||
NSIndexPath *addEmailIndexPath = [self exactIndexPathForRowTag:USER_SETTINGS_ADD_EMAIL_INDEX
|
||||
sectionTag:SECTION_TAG_USER_SETTINGS];
|
||||
NSIndexPath *addEmailIndexPath = [self.tableViewSections exactIndexPathForRowTag:USER_SETTINGS_ADD_EMAIL_INDEX
|
||||
sectionTag:SECTION_TAG_USER_SETTINGS];
|
||||
if (addEmailIndexPath)
|
||||
{
|
||||
[self.tableView reloadRowsAtIndexPaths:@[addEmailIndexPath] withRowAnimation:UITableViewRowAnimationFade];
|
||||
|
@ -912,8 +835,8 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
[self.tableView beginUpdates];
|
||||
|
||||
// Refresh the corresponding table view cell with animation
|
||||
NSIndexPath *addPhoneIndexPath = [self exactIndexPathForRowTag:USER_SETTINGS_ADD_PHONENUMBER_INDEX
|
||||
sectionTag:SECTION_TAG_USER_SETTINGS];
|
||||
NSIndexPath *addPhoneIndexPath = [self.tableViewSections exactIndexPathForRowTag:USER_SETTINGS_ADD_PHONENUMBER_INDEX
|
||||
sectionTag:SECTION_TAG_USER_SETTINGS];
|
||||
if (addPhoneIndexPath)
|
||||
{
|
||||
[self.tableView reloadRowsAtIndexPaths:@[addPhoneIndexPath] withRowAnimation:UITableViewRowAnimationFade];
|
||||
|
@ -1400,16 +1323,12 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
// update the save button if there is an update
|
||||
[self updateSaveButtonStatus];
|
||||
|
||||
return _sections.count;
|
||||
return _tableViewSections.sections.count;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
Section *sectionObject = nil;
|
||||
if (section < _sections.count)
|
||||
{
|
||||
sectionObject = _sections[section];
|
||||
}
|
||||
Section *sectionObject = [_tableViewSections sectionAtIndex:section];
|
||||
return sectionObject.rows.count;
|
||||
}
|
||||
|
||||
|
@ -1496,19 +1415,9 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
Section *sectionObj = nil;
|
||||
NSInteger section = NSNotFound;
|
||||
NSInteger row = NSNotFound;
|
||||
|
||||
if (indexPath.section < _sections.count)
|
||||
{
|
||||
sectionObj = _sections[indexPath.section];
|
||||
section = sectionObj.tag;
|
||||
if (indexPath.row < sectionObj.rows.count)
|
||||
{
|
||||
row = sectionObj.rows[indexPath.row].tag;
|
||||
}
|
||||
}
|
||||
NSIndexPath *tagsIndexPath = [_tableViewSections tagsIndexPathFromTableViewIndexPath:indexPath];
|
||||
NSInteger section = tagsIndexPath.section;
|
||||
NSInteger row = tagsIndexPath.row;
|
||||
|
||||
// set the cell to a default value to avoid application crashes
|
||||
UITableViewCell *cell = [[UITableViewCell alloc] init];
|
||||
|
@ -2369,11 +2278,7 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
|
||||
- (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
|
||||
{
|
||||
Section *sectionObj = nil;
|
||||
if (section < _sections.count)
|
||||
{
|
||||
sectionObj = _sections[section];
|
||||
}
|
||||
Section *sectionObj = [_tableViewSections sectionAtIndex:section];
|
||||
return sectionObj.headerTitle;
|
||||
}
|
||||
|
||||
|
@ -2390,19 +2295,9 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
|
||||
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
Section *sectionObj = nil;
|
||||
NSInteger section = NSNotFound;
|
||||
NSInteger row = NSNotFound;
|
||||
|
||||
if (indexPath.section < _sections.count)
|
||||
{
|
||||
sectionObj = _sections[indexPath.section];
|
||||
section = sectionObj.tag;
|
||||
if (indexPath.row < sectionObj.rows.count)
|
||||
{
|
||||
row = sectionObj.rows[indexPath.row].tag;
|
||||
}
|
||||
}
|
||||
NSIndexPath *tagsIndexPath = [_tableViewSections tagsIndexPathFromTableViewIndexPath:indexPath];
|
||||
NSInteger section = tagsIndexPath.section;
|
||||
NSInteger row = tagsIndexPath.row;
|
||||
|
||||
if (section == SECTION_TAG_USER_SETTINGS)
|
||||
{
|
||||
|
@ -2456,19 +2351,9 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
|
||||
- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
Section *sectionObj = nil;
|
||||
NSInteger section = NSNotFound;
|
||||
NSInteger row = NSNotFound;
|
||||
|
||||
if (indexPath.section < _sections.count)
|
||||
{
|
||||
sectionObj = _sections[indexPath.section];
|
||||
section = sectionObj.tag;
|
||||
if (indexPath.row < sectionObj.rows.count)
|
||||
{
|
||||
row = sectionObj.rows[indexPath.row].tag;
|
||||
}
|
||||
}
|
||||
NSIndexPath *tagsIndexPath = [_tableViewSections tagsIndexPathFromTableViewIndexPath:indexPath];
|
||||
NSInteger section = tagsIndexPath.section;
|
||||
NSInteger row = tagsIndexPath.row;
|
||||
|
||||
NSMutableArray* actions;
|
||||
|
||||
|
@ -2501,19 +2386,9 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
{
|
||||
if (self.tableView == tableView)
|
||||
{
|
||||
Section *sectionObj = nil;
|
||||
NSInteger section = NSNotFound;
|
||||
NSInteger row = NSNotFound;
|
||||
|
||||
if (indexPath.section < _sections.count)
|
||||
{
|
||||
sectionObj = _sections[indexPath.section];
|
||||
section = sectionObj.tag;
|
||||
if (indexPath.row < sectionObj.rows.count)
|
||||
{
|
||||
row = sectionObj.rows[indexPath.row].tag;
|
||||
}
|
||||
}
|
||||
NSIndexPath *tagsIndexPath = [_tableViewSections tagsIndexPathFromTableViewIndexPath:indexPath];
|
||||
NSInteger section = tagsIndexPath.section;
|
||||
NSInteger row = tagsIndexPath.row;
|
||||
|
||||
if (section == SECTION_TAG_USER_INTERFACE)
|
||||
{
|
||||
|
@ -2535,7 +2410,7 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
// settingsDiscoveryTableViewSection is a dynamic section, so check number of rows before scroll to avoid crashes
|
||||
if (self.settingsDiscoveryTableViewSection.numberOfRows > 0)
|
||||
{
|
||||
NSIndexPath *discoveryIndexPath = [self exactIndexPathForRowTag:0 sectionTag:SECTION_TAG_DISCOVERY];
|
||||
NSIndexPath *discoveryIndexPath = [_tableViewSections exactIndexPathForRowTag:0 sectionTag:SECTION_TAG_DISCOVERY];
|
||||
if (discoveryIndexPath)
|
||||
{
|
||||
[tableView scrollToRowAtIndexPath:discoveryIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
|
||||
|
@ -2544,7 +2419,7 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
else
|
||||
{
|
||||
// this won't be precise in scroll location, but seems the best option for now
|
||||
NSIndexPath *discoveryIndexPath = [self nearestIndexPathForRowTag:0 sectionTag:SECTION_TAG_DISCOVERY];
|
||||
NSIndexPath *discoveryIndexPath = [_tableViewSections nearestIndexPathForRowTag:0 sectionTag:SECTION_TAG_DISCOVERY];
|
||||
if (discoveryIndexPath)
|
||||
{
|
||||
[tableView scrollToRowAtIndexPath:discoveryIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
|
||||
|
@ -2744,19 +2619,9 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
|
||||
- (void)onRemove3PID:(NSIndexPath*)indexPath
|
||||
{
|
||||
Section *sectionObj = nil;
|
||||
NSInteger section = NSNotFound;
|
||||
NSInteger row = NSNotFound;
|
||||
|
||||
if (indexPath.section < _sections.count)
|
||||
{
|
||||
sectionObj = _sections[indexPath.section];
|
||||
section = sectionObj.tag;
|
||||
if (indexPath.row < sectionObj.rows.count)
|
||||
{
|
||||
row = sectionObj.rows[indexPath.row].tag;
|
||||
}
|
||||
}
|
||||
NSIndexPath *tagsIndexPath = [_tableViewSections tagsIndexPathFromTableViewIndexPath:indexPath];
|
||||
NSInteger section = tagsIndexPath.section;
|
||||
NSInteger row = tagsIndexPath.row;
|
||||
|
||||
if (section == SECTION_TAG_USER_SETTINGS)
|
||||
{
|
||||
|
@ -3143,46 +3008,6 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
[self pushViewController:newPhoneNumberCountryPicker];
|
||||
}
|
||||
|
||||
//- (void)onRuleUpdate:(id)sender
|
||||
//{
|
||||
// MXPushRule* pushRule = nil;
|
||||
// MXSession* session = [[AppDelegate theDelegate].mxSessions objectAtIndex:0];
|
||||
//
|
||||
// NSInteger row = ((UIView*)sender).tag;
|
||||
//
|
||||
// if (row == NOTIFICATION_SETTINGS_CONTAINING_MY_DISPLAY_NAME_INDEX)
|
||||
// {
|
||||
// pushRule = [session.notificationCenter ruleById:kMXNotificationCenterContainDisplayNameRuleID];
|
||||
// }
|
||||
// else if (row == NOTIFICATION_SETTINGS_CONTAINING_MY_USER_NAME_INDEX)
|
||||
// {
|
||||
// pushRule = [session.notificationCenter ruleById:kMXNotificationCenterContainUserNameRuleID];
|
||||
// }
|
||||
// else if (row == NOTIFICATION_SETTINGS_SENT_TO_ME_INDEX)
|
||||
// {
|
||||
// pushRule = [session.notificationCenter ruleById:kMXNotificationCenterOneToOneRoomRuleID];
|
||||
// }
|
||||
// else if (row == NOTIFICATION_SETTINGS_INVITED_TO_ROOM_INDEX)
|
||||
// {
|
||||
// pushRule = [session.notificationCenter ruleById:kMXNotificationCenterInviteMeRuleID];
|
||||
// }
|
||||
// else if (row == NOTIFICATION_SETTINGS_PEOPLE_LEAVE_JOIN_INDEX)
|
||||
// {
|
||||
// pushRule = [session.notificationCenter ruleById:kMXNotificationCenterMemberEventRuleID];
|
||||
// }
|
||||
// else if (row == NOTIFICATION_SETTINGS_CALL_INVITATION_INDEX)
|
||||
// {
|
||||
// pushRule = [session.notificationCenter ruleById:kMXNotificationCenterCallRuleID];
|
||||
// }
|
||||
//
|
||||
// if (pushRule)
|
||||
// {
|
||||
// // toggle the rule
|
||||
// [session.notificationCenter enableRule:pushRule isEnabled:!pushRule.enabled];
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
- (void)onSave:(id)sender
|
||||
{
|
||||
// sanity check
|
||||
|
@ -3623,8 +3448,8 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
SingleImagePickerPresenter *singleImagePickerPresenter = [[SingleImagePickerPresenter alloc] initWithSession:self.mainSession];
|
||||
singleImagePickerPresenter.delegate = self;
|
||||
|
||||
NSIndexPath *indexPath = [self exactIndexPathForRowTag:USER_SETTINGS_PROFILE_PICTURE_INDEX
|
||||
sectionTag:SECTION_TAG_USER_SETTINGS];
|
||||
NSIndexPath *indexPath = [_tableViewSections exactIndexPathForRowTag:USER_SETTINGS_PROFILE_PICTURE_INDEX
|
||||
sectionTag:SECTION_TAG_USER_SETTINGS];
|
||||
if (indexPath)
|
||||
{
|
||||
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
|
||||
|
@ -3723,7 +3548,7 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
style:UIAlertActionStyleCancel
|
||||
handler:nil]];
|
||||
|
||||
NSIndexPath *indexPath = [self exactIndexPathForRowTag:USER_INTERFACE_THEME_INDEX
|
||||
NSIndexPath *indexPath = [_tableViewSections exactIndexPathForRowTag:USER_INTERFACE_THEME_INDEX
|
||||
sectionTag:SECTION_TAG_USER_INTERFACE];
|
||||
if (indexPath)
|
||||
{
|
||||
|
@ -3845,7 +3670,7 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
|
||||
MXKAccount* account = [MXKAccountManager sharedManager].activeAccounts.firstObject;
|
||||
|
||||
[account changePassword:currentPasswordTextField.text with:newPasswordTextField1.text success:^{
|
||||
[account changePassword:self->currentPasswordTextField.text with:self->newPasswordTextField1.text success:^{
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
|
@ -4280,7 +4105,7 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
}
|
||||
else if ([tableViewCellClass isEqual:[MXKTableViewCellWithTextView class]])
|
||||
{
|
||||
NSIndexPath *indexPath = [self exactIndexPathForRowTag:forRow sectionTag:SECTION_TAG_DISCOVERY];
|
||||
NSIndexPath *indexPath = [_tableViewSections exactIndexPathForRowTag:forRow sectionTag:SECTION_TAG_DISCOVERY];
|
||||
if (indexPath)
|
||||
{
|
||||
tableViewCell = [self textViewCellForTableView:self.tableView atIndexPath:indexPath];
|
||||
|
@ -4307,7 +4132,7 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
}
|
||||
else if ([tableViewCellClass isEqual:[MXKTableViewCellWithLabelAndSwitch class]])
|
||||
{
|
||||
NSIndexPath *indexPath = [self exactIndexPathForRowTag:forRow sectionTag:SECTION_TAG_DISCOVERY];
|
||||
NSIndexPath *indexPath = [_tableViewSections exactIndexPathForRowTag:forRow sectionTag:SECTION_TAG_DISCOVERY];
|
||||
if (indexPath)
|
||||
{
|
||||
tableViewCell = [self getLabelAndSwitchCell:self.tableView forIndexPath:indexPath];
|
||||
|
@ -4336,7 +4161,7 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
|
||||
- (void)settingsDiscoveryViewModelDidTapUserSettingsLink:(SettingsDiscoveryViewModel *)viewModel
|
||||
{
|
||||
NSIndexPath *discoveryIndexPath = [self exactIndexPathForRowTag:USER_SETTINGS_ADD_EMAIL_INDEX
|
||||
NSIndexPath *discoveryIndexPath = [_tableViewSections exactIndexPathForRowTag:USER_SETTINGS_ADD_EMAIL_INDEX
|
||||
sectionTag:SECTION_TAG_USER_SETTINGS];
|
||||
if (discoveryIndexPath)
|
||||
{
|
||||
|
@ -4363,4 +4188,11 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
|||
[self refreshSettings];
|
||||
}
|
||||
|
||||
#pragma mark - TableViewSectionsDelegate
|
||||
|
||||
- (void)tableViewSectionsDidUpdateSections:(TableViewSections *)sections
|
||||
{
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -72,7 +72,7 @@ final class SignOutAlertPresenter: NSObject {
|
|||
self.delegate?.signOutAlertPresenterDidTapSignOutAction(self)
|
||||
}
|
||||
|
||||
let cancelAction = UIAlertAction(title: VectorL10n.cancel, style: .cancel, handler: nil)
|
||||
let cancelAction = UIAlertAction(title: VectorL10n.cancel, style: .cancel)
|
||||
|
||||
alertContoller.addAction(signoutAction)
|
||||
alertContoller.addAction(cancelAction)
|
||||
|
@ -93,7 +93,7 @@ final class SignOutAlertPresenter: NSObject {
|
|||
self.delegate?.signOutAlertPresenterDidTapBackupAction(self)
|
||||
}
|
||||
|
||||
let cancelAction = UIAlertAction(title: VectorL10n.cancel, style: .cancel, handler: nil)
|
||||
let cancelAction = UIAlertAction(title: VectorL10n.cancel, style: .cancel)
|
||||
|
||||
alertContoller.addAction(doNotWantKeyBackupAction)
|
||||
alertContoller.addAction(setUpKeyBackupAction)
|
||||
|
@ -130,7 +130,7 @@ final class SignOutAlertPresenter: NSObject {
|
|||
self.delegate?.signOutAlertPresenterDidTapSignOutAction(self)
|
||||
}
|
||||
|
||||
let cancelAction = UIAlertAction(title: VectorL10n.signOutKeyBackupInProgressAlertCancelAction, style: .cancel, handler: nil)
|
||||
let cancelAction = UIAlertAction(title: VectorL10n.signOutKeyBackupInProgressAlertCancelAction, style: .cancel)
|
||||
|
||||
alertContoller.addAction(discardKeyBackupAction)
|
||||
alertContoller.addAction(cancelAction)
|
||||
|
|
|
@ -40,7 +40,7 @@ class NotificationService: UNNotificationServiceExtension {
|
|||
let url = URL(string: BuildSettings.serverConfigSygnalAPIUrlString)!
|
||||
return MXPushGatewayRestClient(pushGateway: url.scheme! + "://" + url.host!, andOnUnrecognizedCertificateBlock: nil)
|
||||
}()
|
||||
private var pushNotificationManager: PushNotificationManager = .shared
|
||||
private var pushNotificationStore: PushNotificationStore = PushNotificationStore()
|
||||
|
||||
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
|
||||
// Set static application settings
|
||||
|
@ -549,11 +549,11 @@ class NotificationService: UNNotificationServiceExtension {
|
|||
/// Attempts to send trigger a VoIP push for the given event
|
||||
/// - Parameter event: The call invite event.
|
||||
private func sendVoipPush(forEvent event: MXEvent) {
|
||||
guard let token = pushNotificationManager.pushKitToken else {
|
||||
guard let token = pushNotificationStore.pushKitToken else {
|
||||
return
|
||||
}
|
||||
|
||||
pushNotificationManager.lastCallInvite = event
|
||||
pushNotificationStore.lastCallInvite = event
|
||||
|
||||
let appId = BuildSettings.pushKitAppId
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ The `buildable` folder contains templates with source files that build.
|
|||
The goal is to turn these templates as Xcode templates. They are part of the Riot project in order to ensure they build
|
||||
|
||||
# ScreenTemplate
|
||||
This is the boilerplate to create a screen that follows the MVVM-C pattern used within the Riot app.
|
||||
This is the boilerplate to create a screen that follows the MVVM-C pattern used within the Element app.
|
||||
|
||||
To create a screen from this template (before it becomes an Xcode template):
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
We do not want to release for tvOS.
|
|
@ -1,15 +0,0 @@
|
|||
Una aplicació de xat, sota el vostre control i totalment flexible. El Element us permet comunicar-vos de la manera que preferiu. Fet per al [matrix] - l’estàndard per a la comunicació oberta i descentralitzada.
|
||||
|
||||
Obteniu un compte gratuït de matrix.org, executeu el vostre servidor propi a https://ems.element.io, o empreu un altre servidor de Matrix.
|
||||
|
||||
Per què triar Element?
|
||||
|
||||
• COMUNICACIÓ COMPLETA: Creeu sales al voltant dels vostres equips, els vostre amics o la vostra comunitat - de la manera que preferiu! Converseu, compartiu fitxers, afegiu ginys i feu trucades de veu i vídeo - tot de manera gratuïta.
|
||||
|
||||
• INTEGRACIONS POTENTS: Empreu el Element amb les eines que ja coneixeu i us agraden. Amb el Element fins i tot podeu conversar amb usuaris i grups d’altres aplicacions de xat.
|
||||
|
||||
• PRIVAT I SEGUR: Mantingueu les vostres converses en secret. Xifratge punt a punt us assegura que les comunicacions privades continuaran sent privades.
|
||||
|
||||
• OBERT, NO TANCAT: Programari lliure, i construït damunt de Matrix. Sigueu els propietaris de les vostres dades hostatjant el vostre servidor propi, o emprant un en què confieu.
|
||||
|
||||
• ALLÀ ON SIGUEU: Esteu en contacte allà on esteu amb una sincronització total de l’historial dels missatges en tots els vostres dispositius, i en línia a https://element.io/app.
|
|
@ -1 +0,0 @@
|
|||
messaging,collaboration,messenger,chat,secure,open,private,E2EE,decentralised,encrypted,self-host
|
|
@ -1 +0,0 @@
|
|||
https://element.io
|
|
@ -1 +0,0 @@
|
|||
Element (previously Riot.im)
|
|
@ -1 +0,0 @@
|
|||
https://riot.im/privacy
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -1 +0,0 @@
|
|||
Secure decentralised chat/VoIP
|
|
@ -1 +0,0 @@
|
|||
https://element.io
|
|
@ -1 +0,0 @@
|
|||
New Vector Ltd, 2017-2020
|
|
@ -1 +0,0 @@
|
|||
We do not want to release for tvOS.
|
|
@ -1,15 +0,0 @@
|
|||
Eine Chat-App unter deiner Kontrolle und total flexibel. Element lässt dich auf die Art kommunizieren wie du willst. Die App wurde gemacht für [matrix] - dem Standard für offene, dezentrale Komunikation.
|
||||
|
||||
Hole dir ein kostenloses Konto auf matrix.org, hol dir einen eigenen Server auf https://ems.element.io oder nutze einen anderen Matrix-Server.
|
||||
|
||||
Warum solltest du Element wählen?
|
||||
|
||||
• KOMPLETTE KOMMUNIKATION: Baue Räume um deine Teams, deine Freunde, deine Community - wie auch immer du willst! Chatte, teile Dateien, füge Widgets hinzu und führe Sprach- und Videotelefonate - alles kostenlos.
|
||||
|
||||
• MÄCHTIGE INTEGRATIONEN: Benutze Element mit den Werkzeugen die du kennst und liebst. Mit Element kannst du sogar mit Personen und Gruppen chatten, die andere Chat-Anwendungen benutzen.
|
||||
|
||||
• PRIVAT UND SICHER: Halte deine Konversationen geheim. Aktuellste Ende-zu-Ende-Verschlüsselung sorgt dafür, dass deine private Kommunikation auch privat bleibt.
|
||||
|
||||
• OFFEN - NICHT VERSCHLOSSEN: Quelloffen und basierend auf Matrix. Behalte deine Daten indem du deinen eigenen Server betreibst oder einen auswählst dem du vertraust.
|
||||
|
||||
• WO AUCH IMMER DU BIST: Bleibe im Kontakt wo auch immer du bist wobei deine Nachrichtenhistorie zwischen all deinen Geräten synchronisiert wird. Das andere \"Gerät\" kann auch ein Browser sein. Schau dir dazu auch Element an.
|
|
@ -1 +0,0 @@
|
|||
messaging,collaboration,messenger,chat,secure,open,private,E2EE,decentralised,encrypted,self-host
|
|
@ -1 +0,0 @@
|
|||
https://element.io/
|
|
@ -1 +0,0 @@
|
|||
Element (previously Riot.im)
|
|
@ -1 +0,0 @@
|
|||
https://riot.im/privacy
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -1 +0,0 @@
|
|||
Secure decentralised chat/VoIP
|
|
@ -1 +0,0 @@
|
|||
https://element.io/
|
|
@ -1 +0,0 @@
|
|||
We do not want to release for tvOS.
|
|
@ -1,30 +0,0 @@
|
|||
Element is a new type of messenger and collaboration app that:
|
||||
|
||||
1. Puts you in control to preserve your privacy
|
||||
2. Lets you communicate with anyone in the Matrix network, and even beyond by integrating with apps such as Slack
|
||||
3. Protects you from advertising, datamining, backdoors and walled gardens
|
||||
4. Secures you through end-to-end encryption, with cross-signing to verify others
|
||||
|
||||
Element is completely different from other messaging and collaboration apps because it is decentralised and open source.
|
||||
|
||||
Element lets you self-host - or choose a host - so that you have privacy, ownership and control of your data and conversations. It gives you access to an open network; so you’re not just stuck speaking to other Element users only. And it is very secure.
|
||||
|
||||
Element is able to do all this because it operates on Matrix - the standard for open, decentralised communication.
|
||||
|
||||
Element puts you in control by letting you choose who hosts your conversations. From the Element app, you can choose to host in different ways:
|
||||
|
||||
1. Get a free account on the matrix.org public server
|
||||
2. Self-host your account by running a server on your own hardware
|
||||
3. Sign up for an account on a custom server by simply subscribing to the Element Matrix Services hosting platform
|
||||
|
||||
Why choose Element?
|
||||
|
||||
OWN YOUR DATA: You decide where to keep your data and messages. You own it and control it, not some MEGACORP that mines your data or gives access to third parties.
|
||||
|
||||
OPEN MESSAGING AND COLLABORATION: You can chat with anyone else in the Matrix network, whether they’re using Element or another Matrix app, and even if they are using a different messaging system of the likes of Slack, IRC or XMPP.
|
||||
|
||||
SUPER-SECURE: Real end-to-end encryption (only those in the conversation can decrypt messages), and cross-signing to verify the devices of conversation participants.
|
||||
|
||||
COMPLETE COMMUNICATION: Messaging, voice and video calls, file sharing, screen sharing and a whole bunch of integrations, bots and widgets. Build rooms, communities, stay in touch and get things done.
|
||||
|
||||
EVERYWHERE YOU ARE: Stay in touch wherever you are with fully synchronised message history across all your devices and on the web at https://element.io/app.
|
|
@ -1 +0,0 @@
|
|||
collaboration,chat,secure,matrix,private,E2EE,decentralised,encrypted,self-host
|
|
@ -1 +0,0 @@
|
|||
http://element.io
|
|
@ -1 +0,0 @@
|
|||
Element (previously Riot.im)
|
|
@ -1 +0,0 @@
|
|||
https://riot.im/privacy
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -1 +0,0 @@
|
|||
Secure decentralised chat/VoIP
|
|
@ -1 +0,0 @@
|
|||
http://element.io
|
|
@ -1 +0,0 @@
|
|||
We do not want to release for tvOS.
|
|
@ -1,15 +0,0 @@
|
|||
Une application de discussion, que vous contrôlez et entièrement flexible. Element vous laisse communiquer comme vous le souhaitez. Conçu pour [matrix], le standard pour les communications libres et décentralisées.
|
||||
|
||||
Créez un compte matrix.org gratuit, gérez votre propre serveur sur https://ems.element.io ou utilisez un autre serveur Matrix.
|
||||
|
||||
Pourquoi choisir Element ?
|
||||
|
||||
• COMMUNICATION COMPLÈTE : Construisez des salons autours de vos équipes, de vos amis, de votre communauté comme vous le souhaitez ! Discutez, partagez des fichiers, ajoutez des widgets et passez des appels audio et vidéo gratuitement.
|
||||
|
||||
• INTÉGRATIONS PUISSANTES : Utilisez Element avec les outils que vous connaissez déjà. Avec Element vous pouvez même discuter avec les utilisateurs et les groupes qui utilisent d’autres applications de discussion.
|
||||
|
||||
• PRIVÉ ET SÉCURISÉ : Gardez vos conversations secrètes. Un chiffrement de bout en bout de pointe vous garanti que vos communications privées restent privées.
|
||||
|
||||
• OUVERT, PAS FERMÉ : Open source, et construit autour de Matrix. Restez en possession de vos données en hébergeant votre propre serveur, ou choisissez celui auquel vous faites confiance.
|
||||
|
||||
• PARTOUT OÙ VOUS ÊTES : Restez en contact où que vous soyez avec la synchronisation complète de l’historique de vos messages entre vos différents appareils et en ligne sur https://element.io/app.
|
|
@ -1 +0,0 @@
|
|||
messaging,collaboration,messenger,chat,secure,open,private,E2EE,decentralised,encrypted,self-host
|
|
@ -1 +0,0 @@
|
|||
https://element.io/
|
|
@ -1 +0,0 @@
|
|||
Element (previously Riot.im)
|
|
@ -1 +0,0 @@
|
|||
https://riot.im/privacy
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue