├── .gitignore ├── CHANGES.rst ├── CONTRIBUTING.rst ├── LICENSE ├── Podfile ├── Podfile.lock ├── README.rst ├── buildipa.sh ├── checkipa.sh ├── en.lproj └── Localizable.strings ├── icon.svg ├── matrixConsole.xcodeproj ├── project.pbxproj └── xcshareddata │ └── xcschemes │ └── matrixConsole.xcscheme ├── matrixConsole ├── API │ ├── RageShakeManager.h │ └── RageShakeManager.m ├── AppDelegate.h ├── AppDelegate.m ├── Assets │ ├── Images │ │ ├── close.png │ │ ├── gradient.png │ │ ├── icon_users.png │ │ ├── icon_users@2x.png │ │ ├── matrixConsole.png │ │ ├── matrixConsole@2x.png │ │ ├── tab_home.ico │ │ ├── tab_recents.png │ │ ├── tab_recents@2x.png │ │ ├── tab_settings.png │ │ ├── tab_settings@2x.png │ │ ├── video.png │ │ └── voice.png │ └── en.lproj │ │ ├── Localizable.strings │ │ └── MatrixConsole.strings ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── Images.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-29-1.png │ │ ├── Icon-29.png │ │ ├── Icon-29@2x-1.png │ │ ├── Icon-29@2x.png │ │ ├── Icon-29@3x.png │ │ ├── Icon-40.png │ │ ├── Icon-40@2x-1.png │ │ ├── Icon-40@2x.png │ │ ├── Icon-40@3x.png │ │ ├── Icon-50.png │ │ ├── Icon-50@2x.png │ │ ├── Icon-57.png │ │ ├── Icon-57@2x.png │ │ ├── Icon-60@2x.png │ │ ├── Icon-60@3x.png │ │ ├── Icon-72.png │ │ ├── Icon-72@2x.png │ │ ├── Icon-76.png │ │ ├── Icon-76@2x.png │ │ └── Icon-83_5@2x.png │ └── LaunchImage.launchimage │ │ ├── Contents.json │ │ ├── Default-Landscape.png │ │ ├── Default-Landscape@2x.png │ │ ├── Default-Landscape@2x~ipad.png │ │ ├── Default-Landscape~ipad.png │ │ ├── Default-Portrait.png │ │ ├── Default-Portrait@2x.png │ │ ├── Default-Portrait@2x~ipad.png │ │ ├── Default-Portrait~ipad.png │ │ ├── launch-568h@2x-1.png │ │ ├── launch-568h@2x.png │ │ ├── launch.png │ │ ├── launch@2x-1.png │ │ └── launch@2x.png ├── Info.plist ├── Resources │ └── countryCodes.plist ├── ViewController │ ├── AccountDetailsViewController.h │ ├── AccountDetailsViewController.m │ ├── AuthenticationViewController.h │ ├── AuthenticationViewController.m │ ├── ContactsViewController.h │ ├── ContactsViewController.m │ ├── GlobalNotificationSettingsViewController.h │ ├── GlobalNotificationSettingsViewController.m │ ├── HomeViewController.h │ ├── HomeViewController.m │ ├── MasterTabBarController.h │ ├── MasterTabBarController.m │ ├── RecentsViewController.h │ ├── RecentsViewController.m │ ├── RoomMembersViewController.h │ ├── RoomMembersViewController.m │ ├── RoomViewController.h │ ├── RoomViewController.m │ ├── SettingsViewController.h │ └── SettingsViewController.m ├── empty.mm ├── main.m └── matrixConsole-Defaults.plist ├── matrixConsoleTests ├── Info.plist └── matrixConsoleTests.m └── use-dev-pods.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | Pods/ 27 | 28 | # Do not track our workspace since it is created by CocoaPods 29 | *.xcworkspace 30 | -------------------------------------------------------------------------------- /CHANGES.rst: -------------------------------------------------------------------------------- 1 | Changes in Console in 0.6.11 (2016-08-02) 2 | =============================================== 3 | 4 | Improvements: 5 | * Upgrade MatrixKit version (v0.3.13). 6 | * Call: Check permissions before accessing to the camera and the microphone. 7 | * Call Better handle call invites when the app resumes. 8 | * Call: Improve the sending of local ICE candidates to avoid HTTP 429(Too Many Requests) response 9 | 10 | Bug fixes: 11 | * Call: Make audio continue to work when backgrounding the app. 12 | * Call: Added sanity check on creation of RTCICEServer objects as crashes have been reported. 13 | * Call: call must be available in 1:1 rooms (invited and banned users do not count). 14 | 15 | Changes in Console in 0.6.10 (2016-07-26) 16 | =============================================== 17 | 18 | Improvements: 19 | * Upgrade MatrixKit version (v0.3.12). 20 | * Enable VoIP for 1:1 room 21 | * Add Markdown support 22 | 23 | Changes in Console in 0.6.9 (2016-07-04) 24 | =============================================== 25 | 26 | Improvements: 27 | * Upgrade MatrixKit version (v0.3.10). 28 | 29 | Changes in Console in 0.6.8 (2016-06-01) 30 | =============================================== 31 | 32 | Improvements: 33 | * Upgrade MatrixKit version (v0.3.8). 34 | * Change App badge handling: Replace the missed notifications count with the missed discussions count. 35 | 36 | Changes in Console in 0.6.6 (2016-04-26) 37 | =============================================== 38 | 39 | Improvements: 40 | * Upgrade MatrixKit version (v0.3.6). 41 | 42 | Bug fixes: 43 | * The application icon badge number is wrong. 44 | 45 | Changes in Console in 0.6.5 (2016-04-08) 46 | =============================================== 47 | 48 | Improvements: 49 | * Upgrade MatrixKit version (v0.3.5). 50 | 51 | Bug fixes: 52 | * Multiple invitations on Start Chat action. 53 | 54 | Changes in Console in 0.6.4 (2016-03-17) 55 | =============================================== 56 | 57 | Improvements: 58 | * Upgrade MatrixKit version (v0.3.4). 59 | 60 | Changes in Console in 0.6.3 (2016-03-07) 61 | =============================================== 62 | 63 | Improvements: 64 | * Upgrade MatrixKit version (v0.3.3). 65 | 66 | Bug fixes: 67 | * SYIOS-202: IOS should no longer reset badge count on launch. 68 | 69 | Changes in Console in 0.6.2 (2016-02-09) 70 | =============================================== 71 | 72 | Improvements: 73 | * Upgrade MatrixKit version (v0.3.2). 74 | 75 | Changes in Console in 0.6.1 (2016-01-29) 76 | =============================================== 77 | 78 | Improvements: 79 | * Upgrade MatrixKit version (v0.3.1). 80 | 81 | Changes in Console in 0.6.0 (2016-01-22) 82 | =============================================== 83 | 84 | Improvements: 85 | * Upgrade MatrixKit version (v0.3.0). 86 | * AppDelegate: Customize the localized string table. 87 | * RoomViewController: Display member details in case of long press on avatar. 88 | 89 | Bug fixes: 90 | * lock/unlock whilst viewing photos => no navigation bar. 91 | 92 | Changes in Console in 0.5.7 (2015-11-30) 93 | =============================================== 94 | 95 | Improvements: 96 | * Upgrade MatrixKit version (v0.2.8). 97 | * defaults.plist: add pusher app ids definition. 98 | 99 | Bug fixes: 100 | * SettingsViewController: Account details view is not removed on logout. 101 | * SYIOS-177: Clear MXStore if the app systematically crashes at startup. 102 | 103 | Changes in Console in 0.5.6 (2015-11-13) 104 | =============================================== 105 | 106 | Improvements: 107 | * Upgrade MatrixKit version (v0.2.7). 108 | 109 | Changes in Console in 0.5.5 (2015-11-06) 110 | =============================================== 111 | 112 | Improvements: 113 | * Upgrade MatrixKit version (v0.2.5). 114 | * APNS handling: APNS registration is forced only at the first launch. 115 | * Fix screen flickering on logout. 116 | * AppDelegate: Handle unrecognized certificates by prompting user during authentication challenge. 117 | * Allow Chrome to be set as the default link handler. 118 | * SettingsViewController: reload table view only when it is visible. 119 | 120 | Bug fixes: 121 | * HomeViewController: Public room selection is ignored during search session. 122 | 123 | Changes in Console in 0.5.4 (2015-10-14) 124 | =============================================== 125 | 126 | Improvements: 127 | * Upgrade MatrixKit version (v0.2.4): fix App crash on iOS 9. 128 | 129 | Changes in Console in 0.5.3 (2015-09-14) 130 | =============================================== 131 | 132 | Improvements: 133 | * Upgrade MatrixKit version (v0.2.3). 134 | 135 | Bug fixes: 136 | * Bug Fix: App crashes on iPad iOS7. 137 | 138 | Changes in Console in 0.5.2 (2015-08-13) 139 | =============================================== 140 | 141 | * Upgrade MatrixKit version (v0.2.2). 142 | 143 | Changes in Console in 0.5.1 (2015-08-10) 144 | =============================================== 145 | 146 | Improvements: 147 | * Add localized strings (see MatrixConsole.strings) 148 | * Error handling: Alert user on MatrixKit error. 149 | * RecentsViewController: release the current room resources when user selects another room. 150 | 151 | Bug fixes: 152 | * Bug Fix: Settings - The slider related to the maximum cache size is not working. 153 | * Bug Fix: Settings - The user is logged out when he press "Clear cache" button. 154 | 155 | Changes in Console in 0.5.0 (2015-07-10) 156 | =============================================== 157 | 158 | Improvements: 159 | * Update Console by applying MatrixKit changes (see Changes in 0.2.0). 160 | * Support multi-sessions. 161 | * Multi-session handling: Prompt user to select an account before starting 162 | chat with someone. 163 | * Multi-session handling: Recents are interleaved. 164 | 165 | Bug fixes: 166 | * Bug Fix "grey-stuck-can't-click recent bug". The selected room was not 167 | reset correctly. 168 | * Room view controller: remove properly members listener. 169 | * Memory leaks: Dispose properly view controller resources. 170 | * Bug Fix: RoomViewController - Clicking on the user in the chat room 171 | displays the user's details but not his avatar. 172 | * RageShakeManager: Check whether the user can send email before prompting 173 | him. 174 | 175 | Changes in Console in 0.4.0 (2015-04-23) 176 | =============================================== 177 | 178 | Improvements: 179 | * Console has its own git repository. 180 | * Integration of MatrixKit. Most part of the code of Console-pre-0.4.0 has 181 | been redesigned and moved to MatrixKit. 182 | * Stability. MatrixKit better seperates model and viewcontroller which fixes 183 | random multithreading issues Console encountered. 184 | * Room page: unsent messages are no more lost when the user changes the room 185 | 186 | 187 | Changes in Matrix iOS Console in 0.3.2 and before 188 | ================================================= 189 | Console was hosted in the Matrix iOS SDK GitHub repository. 190 | Changes for these versions can be found here: 191 | https://github.com/matrix-org/matrix-ios-sdk/blob/v0.3.2/CHANGES.rst 192 | 193 | 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /CONTRIBUTING.rst: -------------------------------------------------------------------------------- 1 | Contributing code to the Matrix iOS Console 2 | =========================================== 3 | 4 | matrix-ios-console follows the same pattern as https://github.com/matrix-org/synapse/blob/master/CONTRIBUTING.rst 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, "6.0" 3 | 4 | source 'https://github.com/CocoaPods/Specs.git' 5 | 6 | target "matrixConsole" do 7 | 8 | 9 | # Different flavours of pods to MatrixKit 10 | # The tagged version on which this version of Console has been built 11 | pod 'MatrixKit', '0.3.13' 12 | 13 | # The lastest release available on the CocoaPods repository 14 | #pod 'MatrixKit' 15 | 16 | # The develop branch version 17 | #pod 'MatrixSDK', :git => 'https://github.com/matrix-org/matrix-ios-sdk.git', :branch => 'develop' 18 | #pod 'MatrixKit', :git => 'https://github.com/matrix-org/matrix-ios-kit.git', :branch => 'develop' 19 | 20 | # The one used for developping both MatrixSDK and MatrixKit 21 | # Note that MatrixSDK must be cloned into a folder called matrix-ios-sdk next to the MatrixKit folder 22 | #pod 'MatrixKit', :path => '../matrix-ios-kit/MatrixKit.podspec' 23 | #pod 'MatrixSDK', :path => '../matrix-ios-sdk/MatrixSDK.podspec' 24 | 25 | pod 'GBDeviceInfo', '~> 4.1.0' 26 | 27 | # The Google WebRTC stack 28 | pod 'WebRTC', '54.6.13869' 29 | 30 | end 31 | 32 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AFNetworking (3.1.0): 3 | - AFNetworking/NSURLSession (= 3.1.0) 4 | - AFNetworking/Reachability (= 3.1.0) 5 | - AFNetworking/Security (= 3.1.0) 6 | - AFNetworking/Serialization (= 3.1.0) 7 | - AFNetworking/UIKit (= 3.1.0) 8 | - AFNetworking/NSURLSession (3.1.0): 9 | - AFNetworking/Reachability 10 | - AFNetworking/Security 11 | - AFNetworking/Serialization 12 | - AFNetworking/Reachability (3.1.0) 13 | - AFNetworking/Security (3.1.0) 14 | - AFNetworking/Serialization (3.1.0) 15 | - AFNetworking/UIKit (3.1.0): 16 | - AFNetworking/NSURLSession 17 | - DTCoreText (1.6.17): 18 | - DTFoundation/Core (~> 1.7.5) 19 | - DTFoundation/DTAnimatedGIF (~> 1.7.5) 20 | - DTFoundation/DTHTMLParser (~> 1.7.5) 21 | - DTFoundation/UIKit (~> 1.7.5) 22 | - DTFoundation/Core (1.7.10) 23 | - DTFoundation/DTAnimatedGIF (1.7.10) 24 | - DTFoundation/DTHTMLParser (1.7.10): 25 | - DTFoundation/Core 26 | - DTFoundation/UIKit (1.7.10): 27 | - DTFoundation/Core 28 | - GBDeviceInfo (4.1.0): 29 | - GBDeviceInfo/Core (= 4.1.0) 30 | - GBDeviceInfo/Core (4.1.0) 31 | - GHMarkdownParser (0.1.2) 32 | - HPGrowingTextView (1.1) 33 | - libjingle_peerconnection (11177.2.0) 34 | - libPhoneNumber-iOS (0.8.15) 35 | - MatrixKit (0.3.13): 36 | - DTCoreText (~> 1.6.17) 37 | - GHMarkdownParser (~> 0.1.2) 38 | - HPGrowingTextView (~> 1.1) 39 | - libPhoneNumber-iOS (~> 0.8.14) 40 | - MatrixSDK (= 0.6.12) 41 | - MatrixSDK (0.6.12): 42 | - AFNetworking (~> 3.1.0) 43 | 44 | DEPENDENCIES: 45 | - GBDeviceInfo (~> 4.1.0) 46 | - libjingle_peerconnection 47 | - MatrixKit (= 0.3.13) 48 | 49 | SPEC CHECKSUMS: 50 | AFNetworking: 5e0e199f73d8626b11e79750991f5d173d1f8b67 51 | DTCoreText: 3ea8bba23dd2141ba18adb227a7dd33a822df1c4 52 | DTFoundation: 3b6b1b817d2a7fb02e7eaf2596c922a68145bd43 53 | GBDeviceInfo: e50df975a95e21faec93e2bf98376846fe17d307 54 | GHMarkdownParser: 14cbf59d0ab9450017d843dffd4a3ef691e5bd77 55 | HPGrowingTextView: 88a716d97fb853bcb08a4a08e4727da17efc9b19 56 | libjingle_peerconnection: 3458f646ddd61f08a9f3a0c43fb01fff5c165eb8 57 | libPhoneNumber-iOS: 62a740e1ea5741060f5cec0f788b52071115cf31 58 | MatrixKit: 4ed4963069510e2be2349d3310602a03b9d3a043 59 | MatrixSDK: 15f165271e3c677060be1f131edef9e643067677 60 | 61 | PODFILE CHECKSUM: b6af1506b3dc4f333ab208e672b05f8c06784bd8 62 | 63 | COCOAPODS: 1.0.1 64 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Console 2 | ======= 3 | 4 | Console is an iOS Matrix client. 5 | 6 | .. image:: https://linkmaker.itunes.apple.com/images/badges/en-us/badge_appstore-lrg.svg 7 | :target: https://itunes.apple.com/us/app/matrix-console/id970074271?mt=8 8 | 9 | It is also a sample that demonstrates how to use 10 | MatrixKit (https://github.com/matrix-org/matrix-ios-kit) and 11 | MatrixSDK (https://github.com/matrix-org/matrix-ios-sdk) in an iOS app. 12 | 13 | The app can be installed from the App Store at 14 | https://itunes.apple.com/gb/app/matrix-console/id970074271?mt=8 15 | or you can build from source as per below: 16 | 17 | Build instructions 18 | ================== 19 | 20 | Before opening the Console Xcode workspace, you need to build it with the 21 | CocoaPods command:: 22 | 23 | $ cd Console 24 | $ pod install 25 | 26 | This will load all dependencies for the Console source code, including MatrixKit and MatrixSDK. 27 | 28 | Then, open ``matrixConsole.xcworkspace`` with Xcode 29 | 30 | $ open matrixConsole.xcworkspace 31 | 32 | -------------------------------------------------------------------------------- /buildipa.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | builddir="build" 6 | outdir="out" 7 | 8 | sdk="iphoneos" 9 | basecmd="xcodebuild -scheme matrixConsole -workspace matrixConsole.xcworkspace -configuration Release -sdk $sdk -derivedDataPath $builddir" 10 | vars="" 11 | 12 | # Clean the Xcode build folder to avoid caching issues that happens sometimes 13 | rm -rf ~/Library/Developer/Xcode/DerivedData/* 14 | 15 | if [ -n "$GIT_BRANCH" ] 16 | then 17 | vars="$vars GIT_BRANCH=`echo $GIT_BRANCH | sed -e 's#origin\/##'`" 18 | fi 19 | if [ -n "$BUILD_NUMBER" ] 20 | then 21 | vars="$vars BUILD_NUMBER=$BUILD_NUMBER" 22 | fi 23 | 24 | if [ "$1" == 'clean' ] 25 | then 26 | if [ -d "matrixConsole.xcworkspace" ] 27 | then 28 | $basecmd clean 29 | fi 30 | rm -r "$builddir" "$outdir" || true 31 | else 32 | if [ ! -d "matrixConsole.xcworkspace" ] 33 | then 34 | echo "Please run pod install first" 35 | exit 1 36 | fi 37 | $basecmd -archivePath "out/matrixConsole.xcarchive" archive GCC_PREPROCESSOR_DEFINITIONS="\$(GCC_PREPROCESSOR_DEFINITIONS) $vars" "$@" 38 | xcrun -sdk $sdk PackageApplication -v $outdir/matrixConsole.xcarchive/Products/Applications/matrixConsole.app -o `pwd`/out/matrixConsole.ipa 39 | fi 40 | -------------------------------------------------------------------------------- /checkipa.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # From experimentation, the way I recommend building IPA files (as of Xcode 6 / iOS 8) is: 4 | # xcodebuild -archivePath foo.xcarchive archive 5 | # xcrun -sdk iphoneos PackageApplication -v foo.xcarchive/Products/Applications/foo.app -o `pwd`/foo.ipa 6 | # See the accomanying buildipa.sh for a complete example in context. 7 | # The purpose of this script is to check for the myriad symptoms of broken IPA files produced by other 8 | # tools, as discussed further below. 9 | 10 | if [ $# == 0 ] 11 | then 12 | echo "Usage: $0 " 13 | exit 10 14 | fi 15 | 16 | tmp=`mktemp -d ipacheck.XXXX` 17 | unzip -d "$tmp" $1 > /dev/null 18 | cd "$tmp" 19 | apsenv=`codesign -d --entitlements - Payload/*.app 2> /dev/null | grep aps-environment -a -A 1 | tail -n 1 | sed -e 's/.*>\(.*\)<.*/\1/'` 20 | xcent=`ls Payload/*.app/archived-expanded-entitlements.xcent 2> /dev/null` 21 | cd .. 22 | rm -r "$tmp" 23 | 24 | # Check for archived-expanded-entitlements.xcent 25 | # The absence of this file apparently can cause issues submitting to the iTunes store. 26 | # Its absence does not appear to cause problem installing enterprise builds (unless it's listed in 27 | # the code signature and absent, which can be caused by exporting IPA files using xcodebuild -exportArchive). 28 | # Note that in all cases I have tested, its contents does not match the entitlements embedded in the binary. 29 | # We assert that it at least exists. 30 | if [ -z "$xcent" ] 31 | then 32 | echo "$1 has no archived-expanded-entitlements.xcent." 33 | exit 2 34 | fi 35 | 36 | # Check the aps-environment embedded in the binary. 37 | # If this is incorrect or absent, you have a build with broken push. 38 | # Using xcodebuild -exportArchive -exportWithOriginalSigningIdentity is known to 39 | # strip the aps-environment string out of the binary's embedded entitlements. 40 | if [ "$apsenv" == 'production' ] 41 | then 42 | echo "$1's aps-environment is $apsenv: looks good" 43 | elif [ -z "$apsenv" ] 44 | then 45 | echo "$1 has no aps-environment: push will not work with this build!" 46 | exit 1 47 | else 48 | echo "$1's aps-environment is $apsenv. Is that what you wanted?" 49 | exit 1 50 | fi 51 | -------------------------------------------------------------------------------- /en.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | matrixConsole 4 | 5 | Created by David Baker on 15/01/2015. 6 | Copyright (c) 2015 matrix.org. All rights reserved. 7 | */ 8 | -------------------------------------------------------------------------------- /icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | Console 104 | 105 | 106 | -------------------------------------------------------------------------------- /matrixConsole.xcodeproj/xcshareddata/xcschemes/matrixConsole.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 78 | 80 | 86 | 87 | 88 | 89 | 90 | 91 | 97 | 99 | 105 | 106 | 107 | 108 | 110 | 111 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /matrixConsole/API/RageShakeManager.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import 19 | 20 | #import 21 | 22 | @interface RageShakeManager : NSObject 23 | 24 | + (id)sharedManager; 25 | 26 | /** 27 | Prompt user to report a crash. The alert is presented by the provided view controller. 28 | 29 | @param viewController the view controller which presents the alert 30 | */ 31 | - (void)promptCrashReportInViewController:(UIViewController*)viewController; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /matrixConsole/API/RageShakeManager.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #define RAGESHAKEMANAGER_MINIMUM_SHAKING_DURATION 2 18 | 19 | #import "RageShakeManager.h" 20 | 21 | #import "AppDelegate.h" 22 | 23 | #import "GBDeviceInfo_iOS.h" 24 | 25 | #import "NSBundle+MatrixKit.h" 26 | 27 | static RageShakeManager* sharedInstance = nil; 28 | 29 | @interface RageShakeManager() { 30 | bool isShaking; 31 | double startShakingTimeStamp; 32 | 33 | MXKAlert *confirmationAlert; 34 | 35 | MFMailComposeViewController* mailComposer; 36 | } 37 | @end 38 | 39 | @implementation RageShakeManager 40 | 41 | #pragma mark Singleton Method 42 | 43 | + (id)sharedManager { 44 | @synchronized(self) { 45 | if(sharedInstance == nil) 46 | sharedInstance = [[self alloc] init]; 47 | } 48 | return sharedInstance; 49 | } 50 | 51 | #pragma mark - 52 | 53 | - (instancetype)init { 54 | 55 | self = [super init]; 56 | if (self) { 57 | isShaking = NO; 58 | startShakingTimeStamp = 0; 59 | 60 | mailComposer = nil; 61 | confirmationAlert = nil; 62 | } 63 | 64 | return self; 65 | } 66 | 67 | - (void)promptCrashReportInViewController:(UIViewController*)viewController { 68 | if ([MXLogger crashLog] && [MFMailComposeViewController canSendMail]) { 69 | 70 | confirmationAlert = [[MXKAlert alloc] initWithTitle:NSLocalizedStringFromTable(@"bug_report_prompt", @"MatrixConsole", nil) message:nil style:MXKAlertStyleAlert]; 71 | 72 | __weak typeof(self) weakSelf = self; 73 | [confirmationAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { 74 | typeof(self) self = weakSelf; 75 | self->confirmationAlert = nil; 76 | 77 | // Erase the crash log (there is only chance for the user to send it) 78 | [MXLogger deleteCrashLog]; 79 | }]; 80 | 81 | [confirmationAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"ok"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { 82 | typeof(self) self = weakSelf; 83 | self->confirmationAlert = nil; 84 | 85 | [self sendEmail:viewController withSnapshot:NO]; 86 | }]; 87 | 88 | [confirmationAlert showInViewController:viewController]; 89 | } 90 | } 91 | 92 | #pragma mark - MXKResponderRageShaking 93 | 94 | - (void)startShaking:(UIResponder*)responder { 95 | 96 | // Start only if the application is in foreground 97 | if ([AppDelegate theDelegate].isAppForeground && !confirmationAlert) { 98 | NSLog(@"[RageShakeManager] Start shaking with [%@]", [responder class]); 99 | 100 | startShakingTimeStamp = [[NSDate date] timeIntervalSince1970]; 101 | isShaking = YES; 102 | } 103 | } 104 | 105 | - (void)stopShaking:(UIResponder*)responder { 106 | 107 | NSLog(@"[RageShakeManager] Stop shaking with [%@]", [responder class]); 108 | 109 | if (isShaking && [AppDelegate theDelegate].isAppForeground && !confirmationAlert 110 | && (([[NSDate date] timeIntervalSince1970] - startShakingTimeStamp) > RAGESHAKEMANAGER_MINIMUM_SHAKING_DURATION)) { 111 | 112 | if ([responder isKindOfClass:[UIViewController class]] && [MFMailComposeViewController canSendMail]) { 113 | confirmationAlert = [[MXKAlert alloc] initWithTitle:NSLocalizedStringFromTable(@"rage_shake_prompt", @"MatrixConsole", nil) message:nil style:MXKAlertStyleAlert]; 114 | 115 | __weak typeof(self) weakSelf = self; 116 | [confirmationAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { 117 | typeof(self) self = weakSelf; 118 | self->confirmationAlert = nil; 119 | }]; 120 | 121 | [confirmationAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"ok"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { 122 | typeof(self) self = weakSelf; 123 | self->confirmationAlert = nil; 124 | [self sendEmail:(UIViewController*)responder withSnapshot:YES]; 125 | }]; 126 | 127 | [confirmationAlert showInViewController:(UIViewController*)responder]; 128 | } 129 | } 130 | 131 | isShaking = NO; 132 | } 133 | 134 | - (void)cancel:(UIResponder*)responder { 135 | 136 | isShaking = NO; 137 | } 138 | 139 | /** 140 | Prepare and send a report email. The mail composer is presented by the provided view controller. 141 | 142 | @param controller the view controller which presents the alert. 143 | @param snapshot if this boolean value is YES, a screenshot of `controller` is sent as email attachment 144 | */ 145 | - (void)sendEmail:(UIViewController*)controller withSnapshot:(BOOL)snapshot { 146 | 147 | UIImage *image; 148 | 149 | if (snapshot) { 150 | AppDelegate* theDelegate = [AppDelegate theDelegate]; 151 | UIGraphicsBeginImageContextWithOptions(theDelegate.window.bounds.size, NO, [UIScreen mainScreen].scale); 152 | 153 | // Iterate over every window from back to front 154 | for (UIWindow *window in [[UIApplication sharedApplication] windows]) 155 | { 156 | if (![window respondsToSelector:@selector(screen)] || [window screen] == [UIScreen mainScreen]) 157 | { 158 | // -renderInContext: renders in the coordinate space of the layer, 159 | // so we must first apply the layer's geometry to the graphics context 160 | CGContextSaveGState(UIGraphicsGetCurrentContext()); 161 | // Center the context around the window's anchor point 162 | CGContextTranslateCTM(UIGraphicsGetCurrentContext(), [window center].x, [window center].y); 163 | // Apply the window's transform about the anchor point 164 | CGContextConcatCTM(UIGraphicsGetCurrentContext(), [window transform]); 165 | // Offset by the portion of the bounds left of and above the anchor point 166 | CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 167 | -[window bounds].size.width * [[window layer] anchorPoint].x, 168 | -[window bounds].size.height * [[window layer] anchorPoint].y); 169 | 170 | // Render the layer hierarchy to the current context 171 | [[window layer] renderInContext:UIGraphicsGetCurrentContext()]; 172 | 173 | // Restore the context 174 | CGContextRestoreGState(UIGraphicsGetCurrentContext()); 175 | } 176 | } 177 | image = UIGraphicsGetImageFromCurrentImageContext(); 178 | UIGraphicsEndImageContext(); 179 | 180 | // the image is copied in the clipboard 181 | [UIPasteboard generalPasteboard].image = image; 182 | } 183 | 184 | if (controller) { 185 | mailComposer = [[MFMailComposeViewController alloc] init]; 186 | 187 | if ([MXLogger crashLog]) { 188 | [mailComposer setSubject:@"Matrix crash report"]; 189 | } 190 | else { 191 | [mailComposer setSubject:@"Matrix bug report"]; 192 | } 193 | 194 | [mailComposer setToRecipients:[NSArray arrayWithObject:@"rageshake@matrix.org"]]; 195 | 196 | NSString* appVersion = [AppDelegate theDelegate].appVersion; 197 | NSString* build = [AppDelegate theDelegate].build; 198 | 199 | NSMutableString* message = [[NSMutableString alloc] init]; 200 | 201 | [message appendFormat:@"Something went wrong on my Matrix client: \n\n\n"]; 202 | 203 | [message appendFormat:@"-----> my comments <-----\n\n\n"]; 204 | 205 | [message appendFormat:@"------------------------------\n"]; 206 | [message appendFormat:@"Account info\n"]; 207 | 208 | NSArray *mxAccounts = [MXKAccountManager sharedManager].accounts; 209 | for (MXKAccount* account in mxAccounts) { 210 | NSString *disabled = account.disabled ? @" (disabled)" : @""; 211 | 212 | [message appendFormat:@"userId: %@%@\n", account.mxCredentials.userId, disabled]; 213 | if (account.mxSession.myUser.displayname) 214 | { 215 | [message appendFormat:@"displayname: %@\n", account.mxSession.myUser.displayname]; 216 | } 217 | [message appendFormat:@"homeServerURL: %@\n", account.mxCredentials.homeServer]; 218 | } 219 | 220 | [message appendFormat:@"------------------------------\n"]; 221 | [message appendFormat:@"Application info\n"]; 222 | [message appendFormat:@"Console version: %@\n", appVersion]; 223 | [message appendFormat:@"MatrixKit version: %@\n", MatrixKitVersion]; 224 | [message appendFormat:@"MatrixSDK version: %@\n", MatrixSDKVersion]; 225 | if (build.length) { 226 | [message appendFormat:@"Build: %@\n", build]; 227 | } 228 | [message appendFormat:@"------------------------------\n"]; 229 | [message appendFormat:@"Device info\n"]; 230 | [message appendFormat:@"model: %@\n", [GBDeviceInfo deviceInfo].modelString]; 231 | [message appendFormat:@"operatingSystem: %@ %@\n", [[UIDevice currentDevice] systemName], [[UIDevice currentDevice] systemVersion]]; 232 | 233 | [mailComposer setMessageBody:message isHTML:NO]; 234 | 235 | // Attach image only if required 236 | if (image) { 237 | [mailComposer addAttachmentData:UIImageJPEGRepresentation(image, 1.0) mimeType:@"image/jpg" fileName:@"screenshot.jpg"]; 238 | } 239 | 240 | // Add logs files 241 | NSMutableArray *logFiles = [NSMutableArray arrayWithArray:[MXLogger logFiles]]; 242 | if ([MXLogger crashLog]) { 243 | [logFiles addObject:[MXLogger crashLog]]; 244 | } 245 | for (NSString *logFile in logFiles) { 246 | NSData *logContent = [NSData dataWithContentsOfFile:logFile]; 247 | [mailComposer addAttachmentData:logContent mimeType:@"text/plain" fileName:[logFile lastPathComponent]]; 248 | } 249 | mailComposer.mailComposeDelegate = self; 250 | [controller presentViewController:mailComposer animated:YES completion:nil]; 251 | } 252 | } 253 | 254 | #pragma mark - MFMailComposeViewControllerDelegate delegate 255 | 256 | - (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error { 257 | // Do not send this crash anymore 258 | [MXLogger deleteCrashLog]; 259 | 260 | [controller dismissViewControllerAnimated:NO completion:nil]; 261 | } 262 | 263 | @end 264 | -------------------------------------------------------------------------------- /matrixConsole/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import 19 | 20 | #import "MasterTabBarController.h" 21 | 22 | @interface AppDelegate : UIResponder { 23 | BOOL isAPNSRegistered; 24 | 25 | // background sync management 26 | void (^_completionHandler)(UIBackgroundFetchResult); 27 | } 28 | 29 | @property (strong, nonatomic) UIWindow *window; 30 | @property (strong, nonatomic) MasterTabBarController *masterTabBarController; 31 | 32 | @property (strong, nonatomic) MXKAlert *errorNotification; 33 | 34 | @property (strong, nonatomic) NSString *appVersion; 35 | @property (strong, nonatomic) NSString *build; 36 | 37 | @property (nonatomic) BOOL isAppForeground; 38 | @property (nonatomic) BOOL isOffline; 39 | 40 | + (AppDelegate*)theDelegate; 41 | 42 | - (void)selectMatrixAccount:(void (^)(MXKAccount *selectedAccount))onSelection; 43 | 44 | - (void)registerUserNotificationSettings; 45 | 46 | - (void)reloadMatrixSessions:(BOOL)clearCache; 47 | 48 | - (void)logout; 49 | 50 | - (MXKAlert*)showErrorAsAlert:(NSError*)error; 51 | 52 | // Reopen an existing private OneToOne room with this userId or creates a new one (if it doesn't exist). 53 | - (void)startPrivateOneToOneRoomWithUserId:(NSString*)userId completion:(void (^)(void))completion; 54 | 55 | @end 56 | 57 | -------------------------------------------------------------------------------- /matrixConsole/Assets/Images/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Assets/Images/close.png -------------------------------------------------------------------------------- /matrixConsole/Assets/Images/gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Assets/Images/gradient.png -------------------------------------------------------------------------------- /matrixConsole/Assets/Images/icon_users.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Assets/Images/icon_users.png -------------------------------------------------------------------------------- /matrixConsole/Assets/Images/icon_users@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Assets/Images/icon_users@2x.png -------------------------------------------------------------------------------- /matrixConsole/Assets/Images/matrixConsole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Assets/Images/matrixConsole.png -------------------------------------------------------------------------------- /matrixConsole/Assets/Images/matrixConsole@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Assets/Images/matrixConsole@2x.png -------------------------------------------------------------------------------- /matrixConsole/Assets/Images/tab_home.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Assets/Images/tab_home.ico -------------------------------------------------------------------------------- /matrixConsole/Assets/Images/tab_recents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Assets/Images/tab_recents.png -------------------------------------------------------------------------------- /matrixConsole/Assets/Images/tab_recents@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Assets/Images/tab_recents@2x.png -------------------------------------------------------------------------------- /matrixConsole/Assets/Images/tab_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Assets/Images/tab_settings.png -------------------------------------------------------------------------------- /matrixConsole/Assets/Images/tab_settings@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Assets/Images/tab_settings@2x.png -------------------------------------------------------------------------------- /matrixConsole/Assets/Images/video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Assets/Images/video.png -------------------------------------------------------------------------------- /matrixConsole/Assets/Images/voice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Assets/Images/voice.png -------------------------------------------------------------------------------- /matrixConsole/Assets/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /** Single, end-to-end encrypted messages (ie. we don't know what they say) */ 18 | 19 | /* New message from a specific person, not referencing a room */ 20 | "MSG_FROM_USER" = "Message from %@"; 21 | 22 | /* New message from a specific person in a named room */ 23 | "MSG_FROM_USER_IN_ROOM" = "%@ posted in %@"; 24 | 25 | /** Single, unencrypted messages (where we can include the content */ 26 | 27 | /* New message from a specific person, not referencing a room. Content included. */ 28 | "MSG_FROM_USER_WITH_CONTENT" = "%@: %@"; 29 | 30 | /* New message from a specific person in a named room. Content included. */ 31 | "MSG_FROM_USER_IN_ROOM_WITH_CONTENT" = "%@ in %@: %@"; 32 | 33 | /* New action message from a specific person, not referencing a room. */ 34 | "ACTION_FROM_USER" = "* %@ %@"; 35 | 36 | /* New action message from a specific person in a named room. */ 37 | "ACTION_FROM_USER_IN_ROOM" = "%@: * %@ %@"; 38 | 39 | /** Image Messages **/ 40 | 41 | /* New action message from a specific person, not referencing a room. */ 42 | "IMAGE_FROM_USER" = "%@ sent you a picture"; 43 | 44 | /* New action message from a specific person in a named room. */ 45 | "IMAGE_FROM_USER_IN_ROOM" = "%@ posted a picture in %@"; 46 | 47 | /** Coalesced messages **/ 48 | 49 | /* Multiple unread messages in a room */ 50 | "UNREAD_IN_ROOM" = "%@ new messages in %@"; 51 | 52 | /* Multiple unread messages from a specific person, not referencing a room */ 53 | "MSGS_FROM_USER" = "%@ new messages in %@"; 54 | 55 | /* Multiple unread messages from two people */ 56 | "MSGS_FROM_TWO_USERS" = "%@ new messages from %@ and %@"; 57 | 58 | /* Multiple unread messages from three people */ 59 | "MSGS_FROM_THREE_USERS" = "%@ new messages from %@, %@ and %@"; 60 | 61 | /* Multiple unread messages from two plus people (ie. for 4+ people: 'others' replaces the third person) */ 62 | "MSGS_FROM_TWO_PLUS_USERS" = "%@ new messages from %@, %@ and others"; 63 | 64 | /* Multiple messages in two rooms */ 65 | "MSGS_IN_TWO_ROOMS" = "%@ new messages in %@ and %@"; 66 | 67 | /* Look, stuff's happened, alright? Just open the app. */ 68 | "MSGS_IN_TWO_PLUS_ROOMS" = "%@ new messages in %@, %@ and others"; 69 | 70 | /** Invites **/ 71 | 72 | /* A user has invited you to a chat */ 73 | "USER_INVITE_TO_CHAT" = "%@ has invited you to chat"; 74 | 75 | /* A user has invited you to an (unamed) group chat */ 76 | "USER_INVITE_TO_CHAT_GROUP_CHAT" = "%@ has invited you to a group chat"; 77 | 78 | /* A user has invited you to a named room */ 79 | "USER_INVITE_TO_NAMED_ROOM" = "%@ has invited you to %@"; 80 | 81 | /** Calls **/ 82 | 83 | /* Incoming one-to-one voice call */ 84 | "VOICE_CALL_FROM_USER" = "Call from %@"; 85 | 86 | /* Incoming one-to-one video call */ 87 | "VIDEO_CALL_FROM_USER" = "Video call from %@"; 88 | 89 | /* Incoming unnamed voice conference invite from a specific person */ 90 | "VOICE_CONF_FROM_USER" = "Group call from %@"; 91 | 92 | /* Incoming unnamed video conference invite from a specific person */ 93 | "VIDEO_CONF_FROM_USER" = "Video group call from %@"; 94 | 95 | /* Incoming named voice conference invite from a specific person */ 96 | "VOICE_CONF_NAMED_FROM_USER" = "Group call from %@: '%@'"; 97 | 98 | /* Incoming named video conference invite from a specific person */ 99 | "VIDEO_CONF_NAMED_FROM_USER" = "Video group call from %@: '%@'"; 100 | -------------------------------------------------------------------------------- /matrixConsole/Assets/en.lproj/MatrixConsole.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* *********************** */ 18 | /* iOS specific */ 19 | /* *********************** */ 20 | 21 | // Titles 22 | "recents" = "Recents"; 23 | "accounts" = "Accounts"; 24 | 25 | // Action 26 | "return_to_call" = "Return to call"; 27 | "join" = "Join"; 28 | "chat_with_user" = "Chat with %@"; 29 | 30 | // Contact 31 | "invitation_subject" = "Matrix.org is magic"; 32 | "contact_local_sync_prompt" = "Allow local contacts synchronization?"; 33 | 34 | // Settings 35 | "settings_config_ios_console_version" = "Console version: %@"; 36 | "settings_config_ios_kit_version" = "MatrixKit version: %@"; 37 | "settings_config_ios_sdk_version" = "MatrixSDK version: %@"; 38 | "settings_config_no_build_info" = "(no build info)"; 39 | "settings_contact_sync" = "Sync local contacts"; 40 | "settings_country_select" = "Select your country"; 41 | "settings_show_redactions" = "Show redactions"; 42 | "settings_show_unsupported_events" = "Show unsupported events"; 43 | "settings_open_links_in_chrome" = "Open links in Chrome"; 44 | "settings_max_cache_size" = "Maximum cache size (%@)"; 45 | 46 | // Accounts 47 | "account_logout_all" = "Logout all accounts"; 48 | 49 | // Others 50 | "public_room_section_title" = "Public Rooms (at %@):"; 51 | "public_room_empty_section_title" = "No Public Rooms (at %@)"; 52 | "mark_all_as_read_prompt" = "Mark all as read?"; 53 | "bug_report_prompt" = "The application has crashed last time. Would you like to submit a crash report?"; 54 | "rage_shake_prompt" = "You seem to be shaking the phone in frustration. Would you like to submit a bug report?"; 55 | 56 | /* -*- 57 | Automatic localization for en 58 | 59 | The following key/value pairs were extracted from the android i18n file: 60 | /console/src/main/res/values/strings.xml. 61 | */ 62 | 63 | 64 | // titles 65 | 66 | // button names 67 | "view" = "View"; 68 | "chat_with" = "Chat with "; 69 | 70 | // actions 71 | "create_room" = "Create Room"; 72 | "join_room" = "Join Room"; 73 | 74 | // Login Screen 75 | "login_error_must_start_http" = "URL must start with http[s]://"; 76 | 77 | // members list Screen 78 | 79 | // accounts list Screen 80 | 81 | // image size selection 82 | 83 | // invitation members list Screen 84 | 85 | // room creation dialog Screen 86 | 87 | // room info dialog Screen 88 | 89 | // contacts list screen 90 | "contacts" = "Contacts"; 91 | "invite_this_user_to_use_matrix" = "Invite this user to use matrix with"; 92 | "invitation_message" = "I\'d like to chat with you with matrix. Please, visit the website http://matrix.org to have more information."; 93 | 94 | // Settings screen 95 | "settings_webclient_push" = "To configure global notification settings (like rules), go find a webclient and hit Settings > Notifications."; 96 | "settings_title_config" = "Configuration"; 97 | "settings_title_rooms" = "Rooms"; 98 | "settings_title_commands" = "Commands"; 99 | "settings_config_build_number" = "Build: %@"; 100 | "settings_display_all_events" = "Display all events"; 101 | "settings_sort_by_last_seen" = "Sort members by last seen time"; 102 | "settings_display_left_members" = "Display left members"; 103 | "settings_clear_cache" = "Clear cache"; 104 | 105 | // Notification settings screen 106 | "notification_settings_global_notification_settings" = "Global Notification Settings"; 107 | 108 | // gcm section 109 | "settings_command_commands" = "The following commands are available in the room chat:\n\n /nick : change your display name\n /me : send the action you are doing. /me will be replaced by your display name\n /join : join a room\n /kick []: kick the user\n /ban []: ban the user\n /unban : unban the user\n /op : set user power level\n /deop : reset user power level to the room default value"; 110 | 111 | // Settings keys 112 | 113 | // call string 114 | 115 | -------------------------------------------------------------------------------- /matrixConsole/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /matrixConsole/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "29x29", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-29.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "29x29", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-29@2x.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-29@3x.png", 19 | "scale" : "3x" 20 | }, 21 | { 22 | "size" : "40x40", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-40@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-40@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "57x57", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-57.png", 37 | "scale" : "1x" 38 | }, 39 | { 40 | "size" : "57x57", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-57@2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "29x29", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-29-1.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "29x29", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-29@2x-1.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "40x40", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-40.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "40x40", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-40@2x-1.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "50x50", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-50.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "50x50", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-50@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "72x72", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-72.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "72x72", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-72@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "76x76", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-76.png", 109 | "scale" : "1x" 110 | }, 111 | { 112 | "size" : "76x76", 113 | "idiom" : "ipad", 114 | "filename" : "Icon-76@2x.png", 115 | "scale" : "2x" 116 | }, 117 | { 118 | "size" : "83.5x83.5", 119 | "idiom" : "ipad", 120 | "filename" : "Icon-83_5@2x.png", 121 | "scale" : "2x" 122 | } 123 | ], 124 | "info" : { 125 | "version" : 1, 126 | "author" : "xcode" 127 | } 128 | } -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-29-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-29-1.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-29.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-29@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-29@2x-1.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-29@2x.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-29@3x.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-40.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-40@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-40@2x-1.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-50.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-50@2x.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-57.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-57@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-57@2x.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-72.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-72@2x.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-76.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-83_5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/AppIcon.appiconset/Icon-83_5@2x.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "filename" : "launch@2x-1.png", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "extent" : "full-screen", 13 | "idiom" : "iphone", 14 | "subtype" : "retina4", 15 | "filename" : "launch-568h@2x-1.png", 16 | "minimum-system-version" : "7.0", 17 | "orientation" : "portrait", 18 | "scale" : "2x" 19 | }, 20 | { 21 | "orientation" : "portrait", 22 | "idiom" : "ipad", 23 | "extent" : "full-screen", 24 | "minimum-system-version" : "7.0", 25 | "filename" : "Default-Portrait~ipad.png", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "orientation" : "landscape", 30 | "idiom" : "ipad", 31 | "extent" : "full-screen", 32 | "minimum-system-version" : "7.0", 33 | "filename" : "Default-Landscape~ipad.png", 34 | "scale" : "1x" 35 | }, 36 | { 37 | "orientation" : "portrait", 38 | "idiom" : "ipad", 39 | "extent" : "full-screen", 40 | "minimum-system-version" : "7.0", 41 | "filename" : "Default-Portrait@2x~ipad.png", 42 | "scale" : "2x" 43 | }, 44 | { 45 | "orientation" : "landscape", 46 | "idiom" : "ipad", 47 | "extent" : "full-screen", 48 | "minimum-system-version" : "7.0", 49 | "filename" : "Default-Landscape@2x~ipad.png", 50 | "scale" : "2x" 51 | }, 52 | { 53 | "orientation" : "portrait", 54 | "idiom" : "iphone", 55 | "extent" : "full-screen", 56 | "filename" : "launch.png", 57 | "scale" : "1x" 58 | }, 59 | { 60 | "orientation" : "portrait", 61 | "idiom" : "iphone", 62 | "extent" : "full-screen", 63 | "filename" : "launch@2x.png", 64 | "scale" : "2x" 65 | }, 66 | { 67 | "orientation" : "portrait", 68 | "idiom" : "iphone", 69 | "extent" : "full-screen", 70 | "filename" : "launch-568h@2x.png", 71 | "subtype" : "retina4", 72 | "scale" : "2x" 73 | }, 74 | { 75 | "orientation" : "portrait", 76 | "idiom" : "ipad", 77 | "extent" : "to-status-bar", 78 | "filename" : "Default-Portrait.png", 79 | "scale" : "1x" 80 | }, 81 | { 82 | "orientation" : "landscape", 83 | "idiom" : "ipad", 84 | "extent" : "to-status-bar", 85 | "filename" : "Default-Landscape.png", 86 | "scale" : "1x" 87 | }, 88 | { 89 | "orientation" : "portrait", 90 | "idiom" : "ipad", 91 | "extent" : "to-status-bar", 92 | "filename" : "Default-Portrait@2x.png", 93 | "scale" : "2x" 94 | }, 95 | { 96 | "orientation" : "landscape", 97 | "idiom" : "ipad", 98 | "extent" : "to-status-bar", 99 | "filename" : "Default-Landscape@2x.png", 100 | "scale" : "2x" 101 | } 102 | ], 103 | "info" : { 104 | "version" : 1, 105 | "author" : "xcode" 106 | } 107 | } -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/LaunchImage.launchimage/Default-Landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/LaunchImage.launchimage/Default-Landscape.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/LaunchImage.launchimage/Default-Landscape@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/LaunchImage.launchimage/Default-Landscape@2x~ipad.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/LaunchImage.launchimage/Default-Landscape~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/LaunchImage.launchimage/Default-Landscape~ipad.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/LaunchImage.launchimage/Default-Portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/LaunchImage.launchimage/Default-Portrait.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/LaunchImage.launchimage/Default-Portrait@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/LaunchImage.launchimage/Default-Portrait@2x~ipad.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/LaunchImage.launchimage/Default-Portrait~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/LaunchImage.launchimage/Default-Portrait~ipad.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/LaunchImage.launchimage/launch-568h@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/LaunchImage.launchimage/launch-568h@2x-1.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/LaunchImage.launchimage/launch-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/LaunchImage.launchimage/launch-568h@2x.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/LaunchImage.launchimage/launch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/LaunchImage.launchimage/launch.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/LaunchImage.launchimage/launch@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/LaunchImage.launchimage/launch@2x-1.png -------------------------------------------------------------------------------- /matrixConsole/Images.xcassets/LaunchImage.launchimage/launch@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matrix-org/matrix-ios-console/7b8412de90c9bc0c6fb3cca4829c2a89d0404681/matrixConsole/Images.xcassets/LaunchImage.launchimage/launch@2x.png -------------------------------------------------------------------------------- /matrixConsole/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Console 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | org.matrix.console 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 0.6.11 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 0 25 | ITSAppUsesNonExemptEncryption 26 | 27 | LSApplicationQueriesSchemes 28 | 29 | googlechrome 30 | 31 | LSRequiresIPhoneOS 32 | 33 | NSAppTransportSecurity 34 | 35 | NSExceptionDomains 36 | 37 | cas.openmarket.com 38 | 39 | NSExceptionRequiresForwardSecrecy 40 | 41 | 42 | 43 | 44 | UIBackgroundModes 45 | 46 | audio 47 | remote-notification 48 | 49 | UILaunchStoryboardName 50 | LaunchScreen 51 | UIMainStoryboardFile 52 | Main 53 | UIRequiredDeviceCapabilities 54 | 55 | armv7 56 | 57 | UIStatusBarHidden 58 | 59 | UIStatusBarTintParameters 60 | 61 | UINavigationBar 62 | 63 | Style 64 | UIBarStyleDefault 65 | Translucent 66 | 67 | 68 | 69 | UISupportedInterfaceOrientations 70 | 71 | UIInterfaceOrientationPortrait 72 | UIInterfaceOrientationLandscapeLeft 73 | UIInterfaceOrientationLandscapeRight 74 | 75 | UISupportedInterfaceOrientations~ipad 76 | 77 | UIInterfaceOrientationPortrait 78 | UIInterfaceOrientationPortraitUpsideDown 79 | UIInterfaceOrientationLandscapeLeft 80 | UIInterfaceOrientationLandscapeRight 81 | 82 | UIViewControllerBasedStatusBarAppearance 83 | 84 | UserDefaults 85 | ${PRODUCT_NAME}-Defaults 86 | 87 | 88 | -------------------------------------------------------------------------------- /matrixConsole/ViewController/AccountDetailsViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | @interface AccountDetailsViewController : MXKAccountDetailsViewController 20 | 21 | @end 22 | 23 | -------------------------------------------------------------------------------- /matrixConsole/ViewController/AccountDetailsViewController.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import "AccountDetailsViewController.h" 18 | 19 | #import "RageShakeManager.h" 20 | 21 | @interface AccountDetailsViewController() 22 | { 23 | NSInteger globalNotificationSettingsRowIndex; 24 | 25 | // The "Global Notification Settings" button 26 | UIButton *globalNotifSettingsButton; 27 | } 28 | @end 29 | 30 | @implementation AccountDetailsViewController 31 | 32 | - (void)viewDidLoad 33 | { 34 | [super viewDidLoad]; 35 | // Do any additional setup after loading the view, typically from a nib. 36 | 37 | // Setup `MXKRoomMemberListViewController` properties 38 | self.rageShakeManager = [RageShakeManager sharedManager]; 39 | } 40 | 41 | - (void)destroy 42 | { 43 | [super destroy]; 44 | 45 | globalNotifSettingsButton = nil; 46 | } 47 | 48 | #pragma mark - TableView data source 49 | 50 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 51 | { 52 | NSInteger count = [super tableView:tableView numberOfRowsInSection:section]; 53 | 54 | // Add one button in notification section to edit global notification settings 55 | if (section == notificationsSection) 56 | { 57 | globalNotificationSettingsRowIndex = count++; 58 | } 59 | 60 | return count; 61 | } 62 | 63 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 64 | { 65 | UITableViewCell *cell; 66 | 67 | if (indexPath.section == notificationsSection && indexPath.row == globalNotificationSettingsRowIndex) 68 | { 69 | MXKTableViewCellWithButton *globalNotifSettingsBtnCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithButton defaultReuseIdentifier]]; 70 | if (!globalNotifSettingsBtnCell) 71 | { 72 | globalNotifSettingsBtnCell = [[MXKTableViewCellWithButton alloc] init]; 73 | } 74 | [globalNotifSettingsBtnCell.mxkButton setTitle:NSLocalizedStringFromTable(@"notification_settings_global_notification_settings", @"MatrixConsole", nil) forState:UIControlStateNormal]; 75 | [globalNotifSettingsBtnCell.mxkButton setTitle:NSLocalizedStringFromTable(@"notification_settings_global_notification_settings", @"MatrixConsole", nil) forState:UIControlStateHighlighted]; 76 | [globalNotifSettingsBtnCell.mxkButton addTarget:self action:@selector(onButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; 77 | 78 | globalNotifSettingsButton = globalNotifSettingsBtnCell.mxkButton; 79 | 80 | cell = globalNotifSettingsBtnCell; 81 | 82 | 83 | // MXKTableViewCellWithTextView *userInfoCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithTextView defaultReuseIdentifier]]; 84 | // if (!userInfoCell) 85 | // { 86 | // userInfoCell = [[MXKTableViewCellWithTextView alloc] init]; 87 | // } 88 | // 89 | // userInfoCell.mxkTextView.text = NSLocalizedStringFromTable(@"settings_webclient_push", @"MatrixConsole", nil); 90 | // cell = userInfoCell; 91 | } 92 | else 93 | { 94 | cell = [super tableView:tableView cellForRowAtIndexPath:indexPath]; 95 | } 96 | 97 | return cell; 98 | } 99 | 100 | 101 | #pragma mark - TableView delegate 102 | 103 | //- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 104 | //{ 105 | // if (indexPath.section == notificationsSection) 106 | // { 107 | // if (indexPath.row == globalNotificationSettingsRowIndex) 108 | // { 109 | // UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, MAXFLOAT)]; 110 | // textView.font = [UIFont systemFontOfSize:14]; 111 | // textView.text = NSLocalizedStringFromTable(@"settings_webclient_push", @"MatrixConsole", nil); 112 | // CGSize contentSize = [textView sizeThatFits:textView.frame.size]; 113 | // return contentSize.height + 1; 114 | // } 115 | // } 116 | // 117 | // return [super tableView:tableView heightForRowAtIndexPath:indexPath]; 118 | //} 119 | 120 | - (void)onButtonPressed:(id)sender 121 | { 122 | if (sender == globalNotifSettingsButton) 123 | { 124 | [self performSegueWithIdentifier:@"showGlobalNotificationSettings" sender:self]; 125 | } 126 | else 127 | { 128 | [super onButtonPressed:sender]; 129 | } 130 | } 131 | 132 | #pragma mark - Segues 133 | 134 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 135 | { 136 | // Keep ref on destinationViewController 137 | [super prepareForSegue:segue sender:sender]; 138 | 139 | if ([[segue identifier] isEqualToString:@"showGlobalNotificationSettings"]) 140 | { 141 | MXKNotificationSettingsViewController *notifSettingsViewController = segue.destinationViewController; 142 | notifSettingsViewController.mxAccount = self.mxAccount; 143 | } 144 | } 145 | 146 | @end 147 | -------------------------------------------------------------------------------- /matrixConsole/ViewController/AuthenticationViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | @interface AuthenticationViewController : MXKAuthenticationViewController 20 | 21 | @end 22 | 23 | -------------------------------------------------------------------------------- /matrixConsole/ViewController/AuthenticationViewController.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import "AuthenticationViewController.h" 18 | 19 | #import "RageShakeManager.h" 20 | 21 | @implementation AuthenticationViewController 22 | 23 | - (void)viewDidLoad { 24 | [super viewDidLoad]; 25 | 26 | // Setup `MXKAuthenticationViewController` properties 27 | self.rageShakeManager = [RageShakeManager sharedManager]; 28 | self.defaultHomeServerUrl = [[NSUserDefaults standardUserDefaults] objectForKey:@"homeserverurl"]; 29 | self.defaultIdentityServerUrl = [[NSUserDefaults standardUserDefaults] objectForKey:@"identityserverurl"]; 30 | 31 | // The view controller dismiss itself on successful login. 32 | self.delegate = self; 33 | } 34 | 35 | #pragma mark - MXKAuthenticationViewControllerDelegate 36 | 37 | - (void)authenticationViewController:(MXKAuthenticationViewController *)authenticationViewController didLogWithUserId:(NSString *)userId { 38 | 39 | // Report server url typed by the user as default url. 40 | if (self.homeServerTextField.text.length) { 41 | [[NSUserDefaults standardUserDefaults] setObject:self.homeServerTextField.text forKey:@"homeserverurl"]; 42 | } 43 | if (self.identityServerTextField.text.length) { 44 | [[NSUserDefaults standardUserDefaults] setObject:self.identityServerTextField.text forKey:@"identityserverurl"]; 45 | } 46 | [[NSUserDefaults standardUserDefaults] synchronize]; 47 | 48 | // Remove auth view controller on successful login 49 | if (self.navigationController) { 50 | // Pop the view controller 51 | [self.navigationController popViewControllerAnimated:YES]; 52 | } else { 53 | // Dismiss on successful login 54 | [self dismissViewControllerAnimated:YES completion:nil]; 55 | } 56 | 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /matrixConsole/ViewController/ContactsViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | // SMS 20 | #import 21 | #import 22 | 23 | /** 24 | 'ContactsViewController' inherits MXKContactListViewController to handle contact list. 25 | */ 26 | @interface ContactsViewController : MXKContactListViewController 27 | @end 28 | 29 | -------------------------------------------------------------------------------- /matrixConsole/ViewController/ContactsViewController.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import "ContactsViewController.h" 18 | 19 | #import "AppDelegate.h" 20 | 21 | #import "RageShakeManager.h" 22 | 23 | #import "NSBundle+MatrixKit.h" 24 | 25 | @interface ContactsViewController () 26 | { 27 | /** 28 | Tap on thumbnail --> display matrix information. 29 | */ 30 | MXKContact* selectedContact; 31 | } 32 | 33 | @property (strong, nonatomic) MXKAlert *startChatMenu; 34 | @property (strong, nonatomic) MXKAlert *allowContactSyncAlert; 35 | @end 36 | 37 | @implementation ContactsViewController 38 | 39 | - (void)viewDidLoad 40 | { 41 | [super viewDidLoad]; 42 | 43 | [self.tableView setSectionIndexColor:[AppDelegate theDelegate].masterTabBarController.tabBar.tintColor]; 44 | [self.tableView setSectionIndexBackgroundColor:[UIColor clearColor]]; 45 | 46 | // Set rageShake handler 47 | self.rageShakeManager = [RageShakeManager sharedManager]; 48 | 49 | // The view controller handles itself the selected contact 50 | self.delegate = self; 51 | } 52 | 53 | - (void)destroy 54 | { 55 | if (self.startChatMenu) 56 | { 57 | [self.startChatMenu dismiss:NO]; 58 | } 59 | if (self.allowContactSyncAlert) 60 | { 61 | [self.allowContactSyncAlert dismiss:NO]; 62 | } 63 | 64 | selectedContact = nil; 65 | 66 | [super destroy]; 67 | } 68 | 69 | #pragma mark - Actions 70 | 71 | - (IBAction)onSegmentValueChange:(id)sender 72 | { 73 | [super onSegmentValueChange:sender]; 74 | 75 | if (sender == self.contactsControls) 76 | { 77 | // Did the user select local contacts? 78 | if (self.contactsControls.selectedSegmentIndex) 79 | { 80 | MXKAppSettings* appSettings = [MXKAppSettings standardAppSettings]; 81 | 82 | if (!appSettings.syncLocalContacts) 83 | { 84 | __weak typeof(self) weakSelf = self; 85 | 86 | self.allowContactSyncAlert = [[MXKAlert alloc] initWithTitle:NSLocalizedStringFromTable(@"contact_local_sync_prompt", @"MatrixConsole", nil) message:nil style:MXKAlertStyleAlert]; 87 | 88 | [self.allowContactSyncAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"no"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) 89 | { 90 | weakSelf.allowContactSyncAlert = nil; 91 | }]; 92 | 93 | [self.allowContactSyncAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"yes"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) 94 | { 95 | weakSelf.allowContactSyncAlert = nil; 96 | dispatch_async(dispatch_get_main_queue(), ^{ 97 | appSettings.syncLocalContacts = YES; 98 | [weakSelf.tableView reloadData]; 99 | }); 100 | }]; 101 | 102 | [self.allowContactSyncAlert showInViewController:self]; 103 | } 104 | } 105 | } 106 | } 107 | 108 | #pragma mark - MXKContactListViewControllerDelegate 109 | 110 | - (void)contactListViewController:(MXKContactListViewController *)contactListViewController didSelectContact:(NSString*)contactId 111 | { 112 | // Check whether an action is already in progress 113 | if ([self hasPendingAction]) 114 | { 115 | return; 116 | } 117 | 118 | MXKContact *contact = [[MXKContactManager sharedManager] contactWithContactID:contactId]; 119 | 120 | __weak typeof(self) weakSelf = self; 121 | NSArray* matrixIDs = contact.matrixIdentifiers; 122 | 123 | // matrix user ? 124 | if (matrixIDs.count) 125 | { 126 | // Display action sheet only if at least one session is available for this user 127 | BOOL isSessionAvailable = NO; 128 | 129 | NSArray *mxSessions = self.mxSessions; 130 | for (NSString* userID in matrixIDs) 131 | { 132 | for (MXSession *mxSession in mxSessions) 133 | { 134 | if ([mxSession userWithUserId:userID]) 135 | { 136 | isSessionAvailable = YES; 137 | break; 138 | } 139 | } 140 | } 141 | 142 | if (isSessionAvailable) 143 | { 144 | // only 1 matrix ID 145 | if (matrixIDs.count == 1) 146 | { 147 | NSString* matrixID = [matrixIDs objectAtIndex:0]; 148 | 149 | self.startChatMenu = [[MXKAlert alloc] initWithTitle:[NSString stringWithFormat:NSLocalizedStringFromTable(@"chat_with_user", @"MatrixConsole", nil), matrixID] message:nil style:MXKAlertStyleAlert]; 150 | 151 | [self.startChatMenu addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { 152 | 153 | weakSelf.startChatMenu = nil; 154 | 155 | }]; 156 | 157 | [self.startChatMenu addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"ok"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { 158 | 159 | weakSelf.startChatMenu = nil; 160 | 161 | [weakSelf addPendingActionMask]; 162 | 163 | [[AppDelegate theDelegate] startPrivateOneToOneRoomWithUserId:matrixID completion:^{ 164 | 165 | [weakSelf removePendingActionMask]; 166 | 167 | }]; 168 | }]; 169 | } 170 | else 171 | { 172 | self.startChatMenu = [[MXKAlert alloc] initWithTitle:NSLocalizedStringFromTable(@"chat_with", @"MatrixConsole", nil) message:nil style:MXKAlertStyleActionSheet]; 173 | 174 | for(NSString* matrixID in matrixIDs) 175 | { 176 | [self.startChatMenu addActionWithTitle:matrixID style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { 177 | 178 | weakSelf.startChatMenu = nil; 179 | 180 | [weakSelf addPendingActionMask]; 181 | 182 | [[AppDelegate theDelegate] startPrivateOneToOneRoomWithUserId:matrixID completion:^{ 183 | 184 | [weakSelf removePendingActionMask]; 185 | 186 | }]; 187 | }]; 188 | } 189 | 190 | [self.startChatMenu addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { 191 | 192 | weakSelf.startChatMenu = nil; 193 | 194 | }]; 195 | 196 | self.startChatMenu.sourceView = self.tableView; 197 | } 198 | 199 | [self.startChatMenu showInViewController:self]; 200 | } 201 | } 202 | else 203 | { 204 | // invite to use matrix 205 | if (([MFMessageComposeViewController canSendText] ? contact.emailAddresses.count : 0) + (contact.phoneNumbers.count > 0)) 206 | { 207 | self.startChatMenu = [[MXKAlert alloc] initWithTitle:[NSString stringWithFormat:NSLocalizedStringFromTable(@"invite_this_user_to_use_matrix", @"MatrixConsole", nil)] message:nil style:MXKAlertStyleActionSheet]; 208 | 209 | // check if the target can send SMSes 210 | if ([MFMessageComposeViewController canSendText]) 211 | { 212 | // list phonenumbers 213 | for(MXKPhoneNumber* phonenumber in contact.phoneNumbers) 214 | { 215 | [self.startChatMenu addActionWithTitle:phonenumber.textNumber style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { 216 | 217 | // launch SMS composer 218 | MFMessageComposeViewController *messageComposer = [[MFMessageComposeViewController alloc] init]; 219 | 220 | if (messageComposer) 221 | { 222 | messageComposer.messageComposeDelegate = weakSelf; 223 | messageComposer.body = NSLocalizedStringFromTable(@"invitation_message", @"MatrixConsole", nil); 224 | messageComposer.recipients = [NSArray arrayWithObject:phonenumber.textNumber]; 225 | 226 | dispatch_async(dispatch_get_main_queue(), ^{ 227 | [weakSelf presentViewController:messageComposer animated:YES completion:nil]; 228 | }); 229 | } 230 | 231 | weakSelf.startChatMenu = nil; 232 | 233 | }]; 234 | } 235 | } 236 | 237 | // list emails 238 | for(MXKEmail* email in contact.emailAddresses) 239 | { 240 | [self.startChatMenu addActionWithTitle:email.emailAddress style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { 241 | 242 | dispatch_async(dispatch_get_main_queue(), ^{ 243 | 244 | NSString* subject = [NSLocalizedStringFromTable(@"invitation_subject", @"MatrixConsole", nil) stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 245 | NSString* body = [NSLocalizedStringFromTable(@"invitation_message", @"MatrixConsole", nil) stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 246 | 247 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"mailto:%@?subject=%@&body=%@", email.emailAddress, subject, body]]]; 248 | }); 249 | 250 | weakSelf.startChatMenu = nil; 251 | }]; 252 | } 253 | 254 | [self.startChatMenu addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) { 255 | 256 | weakSelf.startChatMenu = nil; 257 | 258 | }]; 259 | 260 | self.startChatMenu.sourceView = self.tableView; 261 | [self.startChatMenu showInViewController:self]; 262 | } 263 | } 264 | } 265 | 266 | - (void)contactListViewController:(MXKContactListViewController *)contactListViewController didTapContactThumbnail:(NSString*)contactId 267 | { 268 | MXKContact *contact = [[MXKContactManager sharedManager] contactWithContactID:contactId]; 269 | 270 | // open detailled sheet if there 271 | if (contact.matrixIdentifiers.count > 0) 272 | { 273 | selectedContact = contact; 274 | [self performSegueWithIdentifier:@"showContactDetails" sender:self]; 275 | } 276 | } 277 | 278 | #pragma mark - Segues 279 | 280 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 281 | { 282 | // Keep ref on destinationViewController 283 | [super prepareForSegue:segue sender:sender]; 284 | 285 | if ([segue.identifier isEqualToString:@"showContactDetails"]) 286 | { 287 | MXKContactDetailsViewController *contactDetailsViewController = segue.destinationViewController; 288 | // Set rageShake handler 289 | contactDetailsViewController.rageShakeManager = [RageShakeManager sharedManager]; 290 | // Set delegate to handle start chat option 291 | contactDetailsViewController.delegate = [AppDelegate theDelegate]; 292 | 293 | contactDetailsViewController.contact = selectedContact; 294 | selectedContact = nil; 295 | } 296 | } 297 | 298 | #pragma mark MFMessageComposeViewControllerDelegate 299 | 300 | - (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result 301 | { 302 | [self dismissViewControllerAnimated:YES completion:nil]; 303 | } 304 | 305 | @end 306 | -------------------------------------------------------------------------------- /matrixConsole/ViewController/GlobalNotificationSettingsViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | @interface GlobalNotificationSettingsViewController : MXKNotificationSettingsViewController 20 | 21 | @end 22 | 23 | -------------------------------------------------------------------------------- /matrixConsole/ViewController/GlobalNotificationSettingsViewController.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import "GlobalNotificationSettingsViewController.h" 18 | 19 | #import "RageShakeManager.h" 20 | 21 | @implementation GlobalNotificationSettingsViewController 22 | 23 | - (void)viewDidLoad 24 | { 25 | [super viewDidLoad]; 26 | // Do any additional setup after loading the view, typically from a nib. 27 | 28 | // Setup `MXKRoomMemberListViewController` properties 29 | self.rageShakeManager = [RageShakeManager sharedManager]; 30 | } 31 | @end 32 | -------------------------------------------------------------------------------- /matrixConsole/ViewController/HomeViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | @interface HomeViewController:MXKViewController 20 | 21 | @property (weak, nonatomic) IBOutlet UISearchBar *publicRoomsSearchBar; 22 | @property (weak, nonatomic) IBOutlet UITableView *tableView; 23 | 24 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *publicRoomsSearchBarHeightConstraint; 25 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *publicRoomsSearchBarTopConstraint; 26 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *tableViewBottomConstraint; 27 | 28 | /** 29 | Add a matrix REST Client. It is used to make Matrix API requests and retrieve public rooms. 30 | */ 31 | - (void)addRestClient:(MXRestClient*)restClient; 32 | 33 | /** 34 | Remove a matrix REST Client. 35 | */ 36 | - (void)removeRestClient:(MXRestClient*)restClient; 37 | 38 | /** 39 | Enable the search in recents list according to the room display name (YES by default). 40 | Set NO this property to disable this option and hide the related bar button. 41 | */ 42 | @property (nonatomic) BOOL enableSearch; 43 | 44 | @end 45 | 46 | -------------------------------------------------------------------------------- /matrixConsole/ViewController/MasterTabBarController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | #import 20 | 21 | #define TABBAR_HOME_INDEX 0 22 | #define TABBAR_RECENTS_INDEX 1 23 | #define TABBAR_CONTACTS_INDEX 2 24 | #define TABBAR_SETTINGS_INDEX 3 25 | #define TABBAR_COUNT 4 26 | 27 | @interface MasterTabBarController : UITabBarController 28 | 29 | // Associated matrix sessions (empty by default). 30 | @property (nonatomic, readonly) NSArray *mxSessions; 31 | 32 | // Current selected room id. nil if no room is presently visible. 33 | @property (strong, nonatomic) NSString *visibleRoomId; 34 | 35 | // Add a matrix session. This session is propagated to all view controllers handled by the tab bar controller. 36 | - (void)addMatrixSession:(MXSession*)mxSession; 37 | // Remove a matrix session. 38 | - (void)removeMatrixSession:(MXSession*)mxSession; 39 | 40 | - (void)showAuthenticationScreen; 41 | - (void)showRoomCreationForm; 42 | - (void)showRoom:(NSString*)roomId withMatrixSession:(MXSession*)mxSession; 43 | 44 | - (void)popRoomViewControllerAnimated:(BOOL)animated; 45 | 46 | @end 47 | 48 | -------------------------------------------------------------------------------- /matrixConsole/ViewController/MasterTabBarController.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import "MasterTabBarController.h" 18 | 19 | #import "AppDelegate.h" 20 | 21 | #import "HomeViewController.h" 22 | 23 | #import "RecentsViewController.h" 24 | 25 | #import "ContactsViewController.h" 26 | 27 | #import "SettingsViewController.h" 28 | 29 | @interface MasterTabBarController () 30 | { 31 | //Array of `MXSession` instances. 32 | NSMutableArray *mxSessionArray; 33 | 34 | // Tab bar view controllers 35 | HomeViewController *homeViewController; 36 | 37 | UINavigationController *recentsNavigationController; 38 | RecentsViewController *recentsViewController; 39 | 40 | ContactsViewController *contactsViewController; 41 | 42 | SettingsViewController *settingsViewController; 43 | } 44 | 45 | @end 46 | 47 | @implementation MasterTabBarController 48 | 49 | - (void)viewDidLoad 50 | { 51 | [super viewDidLoad]; 52 | // Do any additional setup after loading the view, typically from a nib. 53 | 54 | mxSessionArray = [NSMutableArray array]; 55 | 56 | // To simplify navigation into the app, we retrieve here the navigation controller and the view controller related 57 | // to the recents list in Recents Tab. 58 | // Note: UISplitViewController is not supported on iPhone for iOS < 8.0 59 | UIViewController* recents = [self.viewControllers objectAtIndex:TABBAR_RECENTS_INDEX]; 60 | recentsNavigationController = nil; 61 | if ([recents isKindOfClass:[UISplitViewController class]]) 62 | { 63 | UISplitViewController *splitViewController = (UISplitViewController *)recents; 64 | recentsNavigationController = [splitViewController.viewControllers objectAtIndex:0]; 65 | } 66 | else if ([recents isKindOfClass:[UINavigationController class]]) 67 | { 68 | recentsNavigationController = (UINavigationController*)recents; 69 | } 70 | 71 | if (recentsNavigationController) 72 | { 73 | for (UIViewController *viewController in recentsNavigationController.viewControllers) 74 | { 75 | if ([viewController isKindOfClass:[RecentsViewController class]]) 76 | { 77 | recentsViewController = (RecentsViewController*)viewController; 78 | } 79 | } 80 | } 81 | 82 | // Retrieve the home view controller 83 | UIViewController* home = [self.viewControllers objectAtIndex:TABBAR_HOME_INDEX]; 84 | if ([home isKindOfClass:[UINavigationController class]]) 85 | { 86 | UINavigationController *homeNavigationController = (UINavigationController*)home; 87 | for (UIViewController *viewController in homeNavigationController.viewControllers) 88 | { 89 | if ([viewController isKindOfClass:[HomeViewController class]]) 90 | { 91 | homeViewController = (HomeViewController*)viewController; 92 | } 93 | } 94 | } 95 | 96 | // Retrieve the constacts view controller 97 | UIViewController* contacts = [self.viewControllers objectAtIndex:TABBAR_CONTACTS_INDEX]; 98 | if ([contacts isKindOfClass:[UINavigationController class]]) 99 | { 100 | UINavigationController *contactsNavigationController = (UINavigationController*)contacts; 101 | for (UIViewController *viewController in contactsNavigationController.viewControllers) 102 | { 103 | if ([viewController isKindOfClass:[ContactsViewController class]]) 104 | { 105 | contactsViewController = (ContactsViewController*)viewController; 106 | } 107 | } 108 | } 109 | 110 | // Retrieve the settings view controller 111 | UIViewController* settings = [self.viewControllers objectAtIndex:TABBAR_SETTINGS_INDEX]; 112 | if ([settings isKindOfClass:[UINavigationController class]]) 113 | { 114 | UINavigationController *settingsNavigationController = (UINavigationController*)settings; 115 | for (UIViewController *viewController in settingsNavigationController.viewControllers) 116 | { 117 | if ([viewController isKindOfClass:[SettingsViewController class]]) 118 | { 119 | settingsViewController = (SettingsViewController*)viewController; 120 | } 121 | } 122 | } 123 | 124 | // Sanity check 125 | NSAssert(homeViewController &&recentsViewController && contactsViewController && settingsViewController, @"Something wrong in Main.storyboard"); 126 | } 127 | 128 | - (void)viewDidAppear:(BOOL)animated 129 | { 130 | [super viewDidAppear:animated]; 131 | 132 | // Check whether we're not logged in 133 | if (![MXKAccountManager sharedManager].accounts.count) 134 | { 135 | [self showAuthenticationScreen]; 136 | } 137 | } 138 | 139 | - (void)didReceiveMemoryWarning 140 | { 141 | [super didReceiveMemoryWarning]; 142 | 143 | // Dispose of any resources that can be recreated. 144 | 145 | // Memory warnings are now handled by 'MXKRoomDataSourceManager' instance to reload unused data source. 146 | // It is not required to reload all matrix sessions here 147 | // [[AppDelegate theDelegate] reloadMatrixSessions:NO]; 148 | } 149 | 150 | - (void)dealloc 151 | { 152 | mxSessionArray = nil; 153 | 154 | homeViewController = nil; 155 | recentsNavigationController = nil; 156 | recentsViewController = nil; 157 | contactsViewController = nil; 158 | settingsViewController = nil; 159 | } 160 | 161 | #pragma mark - 162 | 163 | - (void)restoreInitialDisplay 164 | { 165 | // Dismiss potential media picker 166 | if (self.presentedViewController) 167 | { 168 | [self dismissViewControllerAnimated:NO completion:nil]; 169 | } 170 | 171 | [self popRoomViewControllerAnimated:NO]; 172 | } 173 | 174 | #pragma mark - 175 | 176 | - (NSArray*)mxSessions 177 | { 178 | return [NSArray arrayWithArray:mxSessionArray]; 179 | } 180 | 181 | - (void)addMatrixSession:(MXSession *)mxSession 182 | { 183 | if (mxSession) 184 | { 185 | // Update recents data source (The recents view controller will be updated by its data source) 186 | if (!mxSessionArray.count) 187 | { 188 | // This is the first added session, list all the recents for the logged user 189 | MXKInterleavedRecentsDataSource *recentlistDataSource = [[MXKInterleavedRecentsDataSource alloc] initWithMatrixSession:mxSession]; 190 | [recentsViewController displayList:recentlistDataSource]; 191 | } 192 | else 193 | { 194 | [recentsViewController.dataSource addMatrixSession:mxSession]; 195 | } 196 | 197 | // Update home tab 198 | [homeViewController addMatrixSession:mxSession]; 199 | // Update contacts tab 200 | [contactsViewController addMatrixSession:mxSession]; 201 | // Update settings tab 202 | [settingsViewController addMatrixSession:mxSession]; 203 | 204 | [mxSessionArray addObject:mxSession]; 205 | } 206 | } 207 | 208 | - (void)removeMatrixSession:(MXSession*)mxSession 209 | { 210 | // Update recents data source 211 | [recentsViewController.dataSource removeMatrixSession:mxSession]; 212 | 213 | // Note: This session is removed automatically in home, contacts and settings tab 214 | // See MXKViewController or MXKTableViewController class. 215 | 216 | [mxSessionArray removeObject:mxSession]; 217 | 218 | // Check whether there are others sessions 219 | if (!mxSessionArray.count) 220 | { 221 | // Keep reference on existing dataSource to release it properly 222 | MXKRecentsDataSource *previousRecentlistDataSource = recentsViewController.dataSource; 223 | [recentsViewController displayList:nil]; 224 | [previousRecentlistDataSource destroy]; 225 | } 226 | } 227 | 228 | - (void)showAuthenticationScreen 229 | { 230 | [self restoreInitialDisplay]; 231 | [self performSegueWithIdentifier:@"showAuth" sender:self]; 232 | } 233 | 234 | - (void)showRoomCreationForm 235 | { 236 | // Switch in Home Tab 237 | [self setSelectedIndex:TABBAR_HOME_INDEX]; 238 | } 239 | 240 | - (void)showRoom:(NSString*)roomId withMatrixSession:(MXSession*)mxSession 241 | { 242 | [self restoreInitialDisplay]; 243 | 244 | // Switch on Recents Tab 245 | [self setSelectedIndex:TABBAR_RECENTS_INDEX]; 246 | 247 | // Select room to display its details (dispatch this action in order to let TabBarController end its refresh) 248 | dispatch_async(dispatch_get_main_queue(), ^{ 249 | [recentsViewController selectRoomWithId:roomId inMatrixSession:mxSession]; 250 | }); 251 | } 252 | 253 | - (void)popRoomViewControllerAnimated:(BOOL)animated 254 | { 255 | // Force back to recents list if room details is displayed in Recents Tab 256 | if (recentsViewController) 257 | { 258 | [recentsNavigationController popToViewController:recentsViewController animated:animated]; 259 | // For unknown reason, the navigation bar is not restored correctly by [popToViewController:animated:] 260 | // when a ViewController has hidden it (see MXKAttachmentsViewController). 261 | // Patch: restore navigation bar by default here. 262 | recentsNavigationController.navigationBarHidden = NO; 263 | 264 | // Release the current selected room 265 | [recentsViewController closeSelectedRoom]; 266 | } 267 | } 268 | 269 | - (void)setVisibleRoomId:(NSString *)roomId 270 | { 271 | if (roomId) 272 | { 273 | // Enable inApp notification for this room in all existing accounts. 274 | NSArray *mxAccounts = [MXKAccountManager sharedManager].accounts; 275 | for (MXKAccount *account in mxAccounts) 276 | { 277 | [account updateNotificationListenerForRoomId:roomId ignore:NO]; 278 | } 279 | } 280 | 281 | _visibleRoomId = roomId; 282 | } 283 | 284 | @end 285 | -------------------------------------------------------------------------------- /matrixConsole/ViewController/RecentsViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | @interface RecentsViewController : MXKRecentListViewController 20 | 21 | /** 22 | Open the room with the provided identifier in a specific matrix session. 23 | 24 | @param roomId the room identifier. 25 | @param mxSession the matrix session in which the room should be available. 26 | */ 27 | - (void)selectRoomWithId:(NSString*)roomId inMatrixSession:(MXSession*)mxSession; 28 | 29 | /** 30 | Close the current selected room (if any) 31 | */ 32 | - (void)closeSelectedRoom; 33 | 34 | @end 35 | 36 | -------------------------------------------------------------------------------- /matrixConsole/ViewController/RecentsViewController.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import "RecentsViewController.h" 18 | #import "RoomViewController.h" 19 | 20 | #import "AppDelegate.h" 21 | 22 | #import "RageShakeManager.h" 23 | 24 | #import "NSBundle+MatrixKit.h" 25 | 26 | @interface RecentsViewController () 27 | { 28 | 29 | // Recents refresh handling 30 | BOOL shouldScrollToTopOnRefresh; 31 | 32 | // Selected room description 33 | NSString *selectedRoomId; 34 | MXSession *selectedRoomSession; 35 | 36 | // Keep reference on the current room view controller to release it correctly 37 | RoomViewController *currentRoomViewController; 38 | 39 | // Keep the selected cell index to handle correctly split view controller display in landscape mode 40 | NSIndexPath *currentSelectedCellIndexPath; 41 | 42 | // "Mark all as read" option 43 | UITapGestureRecognizer *navigationBarTapGesture; 44 | MXKAlert *markAllAsReadAlert; 45 | } 46 | 47 | @end 48 | 49 | @implementation RecentsViewController 50 | 51 | - (void)awakeFromNib 52 | { 53 | [super awakeFromNib]; 54 | if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) 55 | { 56 | self.preferredContentSize = CGSizeMake(320.0, 600.0); 57 | } 58 | } 59 | 60 | - (void)viewDidLoad 61 | { 62 | [super viewDidLoad]; 63 | // Do any additional setup after loading the view, typically from a nib. 64 | self.navigationItem.leftBarButtonItem = self.editButtonItem; 65 | 66 | // Add navigation items 67 | NSArray *rightBarButtonItems = self.navigationItem.rightBarButtonItems; 68 | UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(createNewRoom:)]; 69 | self.navigationItem.rightBarButtonItems = rightBarButtonItems ? [rightBarButtonItems arrayByAddingObject:addButton] : @[addButton]; 70 | 71 | // Prepare tap gesture on title bar 72 | navigationBarTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onNavigationBarTap:)]; 73 | [navigationBarTapGesture setNumberOfTouchesRequired:1]; 74 | [navigationBarTapGesture setNumberOfTapsRequired:1]; 75 | [navigationBarTapGesture setDelegate:self]; 76 | 77 | // Initialisation 78 | currentSelectedCellIndexPath = nil; 79 | 80 | // Setup `MXKRecentListViewController` properties 81 | self.rageShakeManager = [RageShakeManager sharedManager]; 82 | 83 | // The view controller handles itself the selected recent 84 | self.delegate = self; 85 | } 86 | 87 | - (void)dealloc 88 | { 89 | [self closeSelectedRoom]; 90 | } 91 | 92 | - (void)destroy 93 | { 94 | if (markAllAsReadAlert) 95 | { 96 | [markAllAsReadAlert dismiss:NO]; 97 | markAllAsReadAlert = nil; 98 | } 99 | 100 | if (navigationBarTapGesture) 101 | { 102 | [self.navigationController.navigationBar removeGestureRecognizer:navigationBarTapGesture]; 103 | navigationBarTapGesture = nil; 104 | } 105 | 106 | [super destroy]; 107 | } 108 | 109 | - (void)setEditing:(BOOL)editing animated:(BOOL)animated 110 | { 111 | [super setEditing:editing animated:animated]; 112 | 113 | self.recentsTableView.editing = editing; 114 | } 115 | 116 | - (void)didReceiveMemoryWarning 117 | { 118 | [super didReceiveMemoryWarning]; 119 | // Dispose of any resources that can be recreated. 120 | } 121 | 122 | - (void)viewWillAppear:(BOOL)animated 123 | { 124 | [super viewWillAppear:animated]; 125 | 126 | [self updateNavigationBarTitle]; 127 | 128 | // Deselect the current selected row, it will be restored on viewDidAppear (if any) 129 | NSIndexPath *indexPath = [self.recentsTableView indexPathForSelectedRow]; 130 | if (indexPath) 131 | { 132 | [self.recentsTableView deselectRowAtIndexPath:indexPath animated:NO]; 133 | } 134 | 135 | [self.navigationController.navigationBar addGestureRecognizer:navigationBarTapGesture]; 136 | } 137 | 138 | - (void)viewWillDisappear:(BOOL)animated 139 | { 140 | [super viewWillDisappear:animated]; 141 | 142 | // Leave potential editing mode 143 | [self setEditing:NO]; 144 | 145 | selectedRoomId = nil; 146 | selectedRoomSession = nil; 147 | 148 | if (markAllAsReadAlert) 149 | { 150 | [markAllAsReadAlert dismiss:NO]; 151 | markAllAsReadAlert = nil; 152 | } 153 | 154 | [self.navigationController.navigationBar removeGestureRecognizer:navigationBarTapGesture]; 155 | } 156 | 157 | - (void)viewDidAppear:(BOOL)animated 158 | { 159 | [super viewDidAppear:animated]; 160 | 161 | // Release the current selected room (if any) except if the Room ViewController is still visible (see splitViewController.isCollapsed condition) 162 | // Note: 'isCollapsed' property is available in UISplitViewController for iOS 8 and later. 163 | if (!self.splitViewController || ([self.splitViewController respondsToSelector:@selector(isCollapsed)] && self.splitViewController.isCollapsed)) 164 | { 165 | // Release the current selected room (if any). 166 | [self closeSelectedRoom]; 167 | } 168 | else 169 | { 170 | // In case of split view controller where the primary and secondary view controllers are displayed side-by-side onscreen, 171 | // the selected room (if any) is highlighted. 172 | [self refreshCurrentSelectedCell:YES]; 173 | } 174 | } 175 | 176 | #pragma mark - 177 | 178 | - (void)selectRoomWithId:(NSString*)roomId inMatrixSession:(MXSession*)matrixSession 179 | { 180 | if (selectedRoomId && [selectedRoomId isEqualToString:roomId] 181 | && selectedRoomSession && selectedRoomSession == matrixSession) 182 | { 183 | // Nothing to do 184 | return; 185 | } 186 | 187 | selectedRoomId = roomId; 188 | selectedRoomSession = matrixSession; 189 | 190 | if (roomId && matrixSession) 191 | { 192 | [self performSegueWithIdentifier:@"showDetails" sender:self]; 193 | } 194 | else 195 | { 196 | [self closeSelectedRoom]; 197 | } 198 | } 199 | 200 | - (void)closeSelectedRoom 201 | { 202 | selectedRoomId = nil; 203 | selectedRoomSession = nil; 204 | 205 | if (currentRoomViewController) 206 | { 207 | if (currentRoomViewController.roomDataSource) 208 | { 209 | // Let the manager close this room data source 210 | MXSession *mxSession = currentRoomViewController.roomDataSource.mxSession; 211 | MXKRoomDataSourceManager *roomDataSourceManager = [MXKRoomDataSourceManager sharedManagerForMatrixSession:mxSession]; 212 | [roomDataSourceManager closeRoomDataSource:currentRoomViewController.roomDataSource forceClose:NO]; 213 | } 214 | 215 | [currentRoomViewController destroy]; 216 | currentRoomViewController = nil; 217 | } 218 | } 219 | 220 | #pragma mark - Internal methods 221 | 222 | - (void)updateNavigationBarTitle 223 | { 224 | self.navigationItem.title = NSLocalizedStringFromTable(@"recents", @"MatrixConsole", nil); 225 | } 226 | 227 | - (void)createNewRoom:(id)sender 228 | { 229 | [[AppDelegate theDelegate].masterTabBarController showRoomCreationForm]; 230 | } 231 | 232 | - (void)scrollToTop 233 | { 234 | // stop any scrolling effect 235 | [UIView setAnimationsEnabled:NO]; 236 | // before scrolling to the tableview top 237 | self.recentsTableView.contentOffset = CGPointMake(-self.recentsTableView.contentInset.left, -self.recentsTableView.contentInset.top); 238 | [UIView setAnimationsEnabled:YES]; 239 | } 240 | 241 | - (void)refreshCurrentSelectedCell:(BOOL)forceVisible 242 | { 243 | // Update here the index of the current selected cell (if any) - Useful in landscape mode with split view controller. 244 | currentSelectedCellIndexPath = nil; 245 | if (currentRoomViewController) 246 | { 247 | // Restore the current selected room id, it is erased when view controller disappeared (see viewWillDisappear). 248 | if (!selectedRoomId) 249 | { 250 | selectedRoomId = currentRoomViewController.roomDataSource.roomId; 251 | selectedRoomSession = currentRoomViewController.mainSession; 252 | } 253 | 254 | // Look for the rank of this selected room in displayed recents 255 | currentSelectedCellIndexPath = [self.dataSource cellIndexPathWithRoomId:selectedRoomId andMatrixSession:selectedRoomSession]; 256 | } 257 | 258 | if (currentSelectedCellIndexPath) 259 | { 260 | // Select the right row 261 | [self.recentsTableView selectRowAtIndexPath:currentSelectedCellIndexPath animated:YES scrollPosition:UITableViewScrollPositionNone]; 262 | 263 | if (forceVisible) 264 | { 265 | // Scroll table view to make the selected row appear at second position 266 | NSInteger topCellIndexPathRow = currentSelectedCellIndexPath.row ? currentSelectedCellIndexPath.row - 1: currentSelectedCellIndexPath.row; 267 | NSIndexPath* indexPath = [NSIndexPath indexPathForRow:topCellIndexPathRow inSection:currentSelectedCellIndexPath.section]; 268 | [self.recentsTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:NO]; 269 | } 270 | } 271 | else 272 | { 273 | NSIndexPath *indexPath = [self.recentsTableView indexPathForSelectedRow]; 274 | if (indexPath) 275 | { 276 | [self.recentsTableView deselectRowAtIndexPath:indexPath animated:NO]; 277 | } 278 | } 279 | } 280 | 281 | #pragma mark - 282 | 283 | - (void)onNavigationBarTap:(id)sender 284 | { 285 | if (self.dataSource.hasUnread) 286 | { 287 | __weak typeof(self) weakSelf = self; 288 | 289 | markAllAsReadAlert = [[MXKAlert alloc] initWithTitle:NSLocalizedStringFromTable(@"mark_all_as_read_prompt", @"MatrixConsole", nil) message:nil style:MXKAlertStyleAlert]; 290 | 291 | markAllAsReadAlert.cancelButtonIndex = [markAllAsReadAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"no"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) 292 | { 293 | typeof(self) strongSelf = weakSelf; 294 | strongSelf->markAllAsReadAlert = nil; 295 | }]; 296 | 297 | [markAllAsReadAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"yes"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) 298 | { 299 | typeof(self) strongSelf = weakSelf; 300 | 301 | strongSelf->markAllAsReadAlert = nil; 302 | 303 | [strongSelf.dataSource markAllAsRead]; 304 | [strongSelf updateNavigationBarTitle]; 305 | }]; 306 | 307 | [markAllAsReadAlert showInViewController:self]; 308 | } 309 | } 310 | 311 | #pragma mark - Segues 312 | 313 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 314 | { 315 | if ([[segue identifier] isEqualToString:@"showDetails"]) 316 | { 317 | UIViewController *controller; 318 | if ([[segue destinationViewController] isKindOfClass:[UINavigationController class]]) 319 | { 320 | controller = [[segue destinationViewController] topViewController]; 321 | } 322 | else 323 | { 324 | controller = [segue destinationViewController]; 325 | } 326 | 327 | if ([controller isKindOfClass:[RoomViewController class]]) 328 | { 329 | // Release existing Room view controller (if any) 330 | if (currentRoomViewController) 331 | { 332 | if (currentRoomViewController.roomDataSource) 333 | { 334 | // Let the manager close this room data source 335 | MXSession *mxSession = currentRoomViewController.roomDataSource.mxSession; 336 | MXKRoomDataSourceManager *roomDataSourceManager = [MXKRoomDataSourceManager sharedManagerForMatrixSession:mxSession]; 337 | [roomDataSourceManager closeRoomDataSource:currentRoomViewController.roomDataSource forceClose:NO]; 338 | } 339 | 340 | [currentRoomViewController destroy]; 341 | currentRoomViewController = nil; 342 | } 343 | 344 | currentRoomViewController = (RoomViewController *)controller; 345 | 346 | MXKRoomDataSourceManager *roomDataSourceManager = [MXKRoomDataSourceManager sharedManagerForMatrixSession:selectedRoomSession]; 347 | MXKRoomDataSource *roomDataSource = [roomDataSourceManager roomDataSourceForRoom:selectedRoomId create:YES]; 348 | [currentRoomViewController displayRoom:roomDataSource]; 349 | } 350 | 351 | // Reset unread count for this room 352 | //[roomDataSource resetUnreadCount]; // @TODO: This automatically done by roomDataSource. Is it a good thing? 353 | [self updateNavigationBarTitle]; 354 | 355 | if (self.splitViewController) 356 | { 357 | // Refresh selected cell without scrolling the selected cell (We suppose it's visible here) 358 | [self refreshCurrentSelectedCell:NO]; 359 | 360 | // IOS >= 8 361 | if ([self.splitViewController respondsToSelector:@selector(displayModeButtonItem)]) 362 | { 363 | controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem; 364 | } 365 | 366 | // 367 | controller.navigationItem.leftItemsSupplementBackButton = YES; 368 | } 369 | 370 | // Hide back button title 371 | self.navigationItem.backBarButtonItem =[[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil]; 372 | } 373 | } 374 | 375 | #pragma mark - MXKDataSourceDelegate 376 | - (void)dataSource:(MXKDataSource *)dataSource didCellChange:(id)changes 377 | { 378 | // Update the unreadCount in the title 379 | [self updateNavigationBarTitle]; 380 | 381 | [self.recentsTableView reloadData]; 382 | 383 | if (shouldScrollToTopOnRefresh) 384 | { 385 | [self scrollToTop]; 386 | shouldScrollToTopOnRefresh = NO; 387 | } 388 | 389 | // In case of split view controller where the primary and secondary view controllers are displayed side-by-side onscreen, 390 | // the selected room (if any) is updated and kept visible. 391 | // Note: 'isCollapsed' property is available in UISplitViewController for iOS 8 and later. 392 | if (self.splitViewController && (![self.splitViewController respondsToSelector:@selector(isCollapsed)] || !self.splitViewController.isCollapsed)) 393 | { 394 | [self refreshCurrentSelectedCell:YES]; 395 | } 396 | } 397 | 398 | #pragma mark - MXKRecentListViewControllerDelegate 399 | - (void)recentListViewController:(MXKRecentListViewController *)recentListViewController didSelectRoom:(NSString *)roomId inMatrixSession:(MXSession *)matrixSession 400 | { 401 | // Open the room 402 | [self selectRoomWithId:roomId inMatrixSession:matrixSession]; 403 | } 404 | 405 | #pragma mark - Override UISearchBarDelegate 406 | 407 | - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText 408 | { 409 | // Prepare table refresh on new search session 410 | shouldScrollToTopOnRefresh = YES; 411 | 412 | [super searchBar:searchBar textDidChange:searchText]; 413 | } 414 | 415 | - (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar 416 | { 417 | // Prepare table refresh on end of search 418 | shouldScrollToTopOnRefresh = YES; 419 | 420 | [super searchBarCancelButtonClicked: searchBar]; 421 | } 422 | 423 | @end 424 | -------------------------------------------------------------------------------- /matrixConsole/ViewController/RoomMembersViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | @class RoomMembersViewController; 20 | 21 | /** 22 | `RoomMembersViewController` delegate. 23 | */ 24 | @protocol RoomMembersViewControllerDelegate 25 | 26 | /** 27 | Tells the delegate that the user wants to mention a room member. 28 | 29 | @discussion the `RoomMembersViewController` instance is withdrawn automatically. 30 | 31 | @param roomMembersViewController the `RoomMembersViewController` instance. 32 | @param member the room member to mention. 33 | */ 34 | - (void)roomMembersViewController:(RoomMembersViewController *)roomMembersViewController mention:(MXRoomMember*)member; 35 | 36 | @end 37 | 38 | @interface RoomMembersViewController : MXKRoomMemberListViewController 39 | 40 | /** 41 | Enable mention option in member details view. NO by default 42 | */ 43 | @property (nonatomic) BOOL enableMention; 44 | 45 | /** 46 | The delegate for the view controller. 47 | */ 48 | @property (nonatomic) id roomMembersViewControllerDelegate; 49 | 50 | @end 51 | 52 | -------------------------------------------------------------------------------- /matrixConsole/ViewController/RoomMembersViewController.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import "RoomMembersViewController.h" 18 | 19 | #import "AppDelegate.h" 20 | #import "RageShakeManager.h" 21 | 22 | @interface RoomMembersViewController () 23 | { 24 | /** 25 | The selected member 26 | */ 27 | MXRoomMember *selectedMember; 28 | 29 | /** 30 | */ 31 | MXKRoomMemberDetailsViewController *detailsViewController; 32 | } 33 | 34 | @end 35 | 36 | @implementation RoomMembersViewController 37 | 38 | - (void)awakeFromNib 39 | { 40 | [super awakeFromNib]; 41 | 42 | if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) 43 | { 44 | self.preferredContentSize = CGSizeMake(320.0, 600.0); 45 | } 46 | } 47 | 48 | - (void)viewDidLoad 49 | { 50 | [super viewDidLoad]; 51 | 52 | // Setup `MXKRoomMemberListViewController` properties 53 | self.rageShakeManager = [RageShakeManager sharedManager]; 54 | 55 | // The view controller handles itself the selected roomMember 56 | self.delegate = self; 57 | } 58 | 59 | - (void)viewWillAppear:(BOOL)animated 60 | { 61 | [super viewWillAppear:animated]; 62 | 63 | if (detailsViewController) 64 | { 65 | [detailsViewController destroy]; 66 | detailsViewController = nil; 67 | } 68 | } 69 | 70 | - (void)dealloc 71 | { 72 | selectedMember = nil; 73 | } 74 | 75 | - (void)didReceiveMemoryWarning 76 | { 77 | [super didReceiveMemoryWarning]; 78 | // Dispose of any resources that can be recreated. 79 | } 80 | 81 | #pragma mark - 82 | 83 | - (void)setEnableMention:(BOOL)enableMention 84 | { 85 | if (_enableMention != enableMention) 86 | { 87 | _enableMention = enableMention; 88 | 89 | if (detailsViewController) 90 | { 91 | detailsViewController.enableMention = enableMention; 92 | } 93 | } 94 | } 95 | 96 | #pragma mark - Segues 97 | 98 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 99 | { 100 | // Keep ref on destinationViewController 101 | [super prepareForSegue:segue sender:sender]; 102 | 103 | if ([[segue identifier] isEqualToString:@"showDetails"]) 104 | { 105 | if (selectedMember) 106 | { 107 | detailsViewController = segue.destinationViewController; 108 | 109 | // Set rageShake handler 110 | detailsViewController.rageShakeManager = [RageShakeManager sharedManager]; 111 | // Set delegate to handle start chat option 112 | detailsViewController.delegate = self; 113 | detailsViewController.enableMention = _enableMention; 114 | 115 | [detailsViewController displayRoomMember:selectedMember withMatrixRoom:[self.mainSession roomWithRoomId:self.dataSource.roomId]]; 116 | } 117 | } 118 | } 119 | 120 | #pragma mark - MXKRoomMemberListViewControllerDelegate 121 | - (void)roomMemberListViewController:(MXKRoomMemberListViewController *)roomMemberListViewController didSelectMember:(MXRoomMember *)member 122 | { 123 | // Report the selected member and open details view 124 | selectedMember = member; 125 | [self performSegueWithIdentifier:@"showDetails" sender:self]; 126 | } 127 | 128 | #pragma mark - MXKRoomMemberDetailsViewControllerDelegate 129 | 130 | - (void)roomMemberDetailsViewController:(MXKRoomMemberDetailsViewController *)roomMemberDetailsViewController startChatWithMemberId:(NSString *)matrixId completion:(void (^)(void))completion 131 | { 132 | [[AppDelegate theDelegate] startPrivateOneToOneRoomWithUserId:matrixId completion:completion]; 133 | } 134 | 135 | - (void)roomMemberDetailsViewController:(MXKRoomMemberDetailsViewController *)roomMemberDetailsViewController mention:(MXRoomMember *)member 136 | { 137 | if (_roomMembersViewControllerDelegate) 138 | { 139 | id delegate = _roomMembersViewControllerDelegate; 140 | 141 | [self withdrawViewControllerAnimated:YES completion:^{ 142 | 143 | [delegate roomMembersViewController:self mention:member]; 144 | 145 | }]; 146 | } 147 | } 148 | 149 | @end 150 | -------------------------------------------------------------------------------- /matrixConsole/ViewController/RoomViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | #import "RoomMembersViewController.h" 20 | 21 | @interface RoomViewController : MXKRoomViewController 22 | 23 | @end 24 | 25 | -------------------------------------------------------------------------------- /matrixConsole/ViewController/RoomViewController.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import "RoomViewController.h" 18 | 19 | #import "MXKRoomBubbleTableViewCell.h" 20 | 21 | #import "AppDelegate.h" 22 | 23 | #import "RageShakeManager.h" 24 | 25 | @interface RoomViewController () 26 | { 27 | // Members list 28 | id membersListener; 29 | 30 | // Voip call options 31 | UIButton *voipVoiceCallButton; 32 | UIButton *voipVideoCallButton; 33 | UIBarButtonItem *voipVoiceCallBarButtonItem; 34 | UIBarButtonItem *voipVideoCallBarButtonItem; 35 | 36 | // the user taps on a member thumbnail 37 | MXRoomMember *selectedRoomMember; 38 | } 39 | 40 | @property (strong, nonatomic) IBOutlet UIBarButtonItem *showRoomMembersButtonItem; 41 | 42 | @property (strong, nonatomic) MXKAlert *actionMenu; 43 | 44 | @end 45 | 46 | @implementation RoomViewController 47 | 48 | - (void)viewDidLoad 49 | { 50 | [super viewDidLoad]; 51 | 52 | // Set room title view 53 | [self setRoomTitleViewClass:MXKRoomTitleViewWithTopic.class]; 54 | 55 | // Replace the default input toolbar view with the one based on `HPGrowingTextView`. 56 | [self setRoomInputToolbarViewClass:MXKRoomInputToolbarViewWithHPGrowingText.class]; 57 | self.inputToolbarView.enableAutoSaving = YES; 58 | 59 | // Set rageShake handler 60 | self.rageShakeManager = [RageShakeManager sharedManager]; 61 | } 62 | 63 | - (void)didReceiveMemoryWarning 64 | { 65 | [super didReceiveMemoryWarning]; 66 | // Dispose of any resources that can be recreated. 67 | } 68 | 69 | - (void)viewWillAppear:(BOOL)animated 70 | { 71 | [super viewWillAppear:animated]; 72 | } 73 | 74 | - (void)viewWillDisappear:(BOOL)animated 75 | { 76 | [super viewWillDisappear:animated]; 77 | 78 | // hide action 79 | if (self.actionMenu) 80 | { 81 | [self.actionMenu dismiss:NO]; 82 | self.actionMenu = nil; 83 | } 84 | 85 | if (self.roomDataSource) 86 | { 87 | if (membersListener) 88 | { 89 | [self.roomDataSource.room.liveTimeline removeListener:membersListener]; 90 | membersListener = nil; 91 | } 92 | } 93 | } 94 | 95 | - (void)viewDidAppear:(BOOL)animated 96 | { 97 | if (self.childViewControllers) 98 | { 99 | // Dispose data source defined for room member list view controller (if any) 100 | for (id childViewController in self.childViewControllers) 101 | { 102 | if ([childViewController isKindOfClass:[RoomMembersViewController class]]) 103 | { 104 | RoomMembersViewController *viewController = (RoomMembersViewController*)childViewController; 105 | MXKDataSource *dataSource = [viewController dataSource]; 106 | [viewController destroy]; 107 | [dataSource destroy]; 108 | } 109 | } 110 | } 111 | 112 | [super viewDidAppear:animated]; 113 | 114 | if (self.roomDataSource) 115 | { 116 | // Set visible room id 117 | [AppDelegate theDelegate].masterTabBarController.visibleRoomId = self.roomDataSource.roomId; 118 | } 119 | } 120 | 121 | - (void)viewDidDisappear:(BOOL)animated 122 | { 123 | [super viewDidDisappear:animated]; 124 | 125 | // Reset visible room id 126 | [AppDelegate theDelegate].masterTabBarController.visibleRoomId = nil; 127 | } 128 | 129 | #pragma mark - Override MXKRoomViewController 130 | 131 | - (void)displayRoom:(MXKRoomDataSource *)dataSource 132 | { 133 | // Remove members listener (if any) before changing dataSource. 134 | if (membersListener) 135 | { 136 | [self.roomDataSource.room.liveTimeline removeListener:membersListener]; 137 | membersListener = nil; 138 | } 139 | 140 | if (dataSource) 141 | { 142 | // Show the keyboard icon in the cells of the current writers 143 | dataSource.showTypingNotifications = YES; 144 | } 145 | 146 | [super displayRoom:dataSource]; 147 | } 148 | 149 | - (void)updateViewControllerAppearanceOnRoomDataSourceState 150 | { 151 | [super updateViewControllerAppearanceOnRoomDataSourceState]; 152 | 153 | // Update UI by considering dataSource state 154 | if (self.roomDataSource && self.roomDataSource.state == MXKDataSourceStateReady) 155 | { 156 | // Register a listener for events that concern room members 157 | if (!membersListener) 158 | { 159 | membersListener = [self.roomDataSource.room.liveTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXTimelineDirection direction, id customObject) { 160 | 161 | // Consider only live event 162 | if (direction == MXTimelineDirectionForwards) 163 | { 164 | // Update navigation bar items 165 | [self updateNavigationBarButtonItems]; 166 | } 167 | }]; 168 | } 169 | } 170 | else 171 | { 172 | // Remove members listener if any. 173 | if (membersListener) 174 | { 175 | [self.roomDataSource.room.liveTimeline removeListener:membersListener]; 176 | membersListener = nil; 177 | } 178 | } 179 | 180 | // Update navigation bar items 181 | [self updateNavigationBarButtonItems]; 182 | } 183 | 184 | - (BOOL)isIRCStyleCommand:(NSString*)string 185 | { 186 | // Override the default behavior for `/join` command in order to open automatically the joined room 187 | 188 | if ([string hasPrefix:kCmdJoinRoom]) 189 | { 190 | // Join a room 191 | NSString *roomAlias = [string substringFromIndex:kCmdJoinRoom.length + 1]; 192 | // Remove white space from both ends 193 | roomAlias = [roomAlias stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 194 | 195 | // Check 196 | if (roomAlias.length) 197 | { 198 | [self.mainSession joinRoom:roomAlias success:^(MXRoom *room) 199 | { 200 | // Show the room 201 | [[AppDelegate theDelegate].masterTabBarController showRoom:room.state.roomId withMatrixSession:self.mainSession]; 202 | } failure:^(NSError *error) 203 | { 204 | NSLog(@"[Console RoomVC] Join roomAlias (%@) failed: %@", roomAlias, error); 205 | //Alert user 206 | [[AppDelegate theDelegate] showErrorAsAlert:error]; 207 | }]; 208 | } 209 | else 210 | { 211 | // Display cmd usage in text input as placeholder 212 | self.inputToolbarView.placeholder = @"Usage: /join "; 213 | } 214 | return YES; 215 | } 216 | return [super isIRCStyleCommand:string]; 217 | } 218 | 219 | - (void)destroy 220 | { 221 | if (membersListener) 222 | { 223 | [self.roomDataSource.room.liveTimeline removeListener:membersListener]; 224 | membersListener = nil; 225 | } 226 | 227 | if (self.actionMenu) 228 | { 229 | [self.actionMenu dismiss:NO]; 230 | self.actionMenu = nil; 231 | } 232 | 233 | [super destroy]; 234 | } 235 | 236 | #pragma mark - 237 | 238 | - (void)updateNavigationBarButtonItems 239 | { 240 | // Update navigation bar buttons according to room members count 241 | if (self.roomDataSource && self.roomDataSource.state == MXKDataSourceStateReady) 242 | { 243 | // Check conditions to display voip call buttons 244 | if (self.roomDataSource.room.state.joinedMembers.count >= 2 && self.mainSession.callManager) 245 | { 246 | if (!voipVoiceCallBarButtonItem || !voipVideoCallBarButtonItem) 247 | { 248 | voipVoiceCallButton = [UIButton buttonWithType:UIButtonTypeCustom]; 249 | voipVoiceCallButton.frame = CGRectMake(0, 0, 36, 36); 250 | UIImage *voiceImage = [UIImage imageNamed:@"voice"]; 251 | [voipVoiceCallButton setImage:voiceImage forState:UIControlStateNormal]; 252 | [voipVoiceCallButton setImage:voiceImage forState:UIControlStateHighlighted]; 253 | [voipVoiceCallButton addTarget:self action:@selector(onButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; 254 | voipVoiceCallBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:voipVoiceCallButton]; 255 | 256 | voipVideoCallButton = [UIButton buttonWithType:UIButtonTypeCustom]; 257 | voipVideoCallButton.frame = CGRectMake(0, 0, 36, 36); 258 | UIImage *videoImage = [UIImage imageNamed:@"video"]; 259 | [voipVideoCallButton setImage:videoImage forState:UIControlStateNormal]; 260 | [voipVideoCallButton setImage:videoImage forState:UIControlStateHighlighted]; 261 | [voipVideoCallButton addTarget:self action:@selector(onButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; 262 | voipVideoCallBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:voipVideoCallButton]; 263 | } 264 | 265 | _showRoomMembersButtonItem.enabled = YES; 266 | 267 | self.navigationItem.rightBarButtonItems = @[_showRoomMembersButtonItem, voipVideoCallBarButtonItem, voipVoiceCallBarButtonItem]; 268 | } 269 | else 270 | { 271 | _showRoomMembersButtonItem.enabled = ([self.roomDataSource.room.state members].count != 0); 272 | self.navigationItem.rightBarButtonItems = @[_showRoomMembersButtonItem]; 273 | } 274 | } 275 | else 276 | { 277 | _showRoomMembersButtonItem.enabled = NO; 278 | self.navigationItem.rightBarButtonItems = @[_showRoomMembersButtonItem]; 279 | } 280 | } 281 | 282 | #pragma mark - MXKDataSource delegate 283 | 284 | - (void)dataSource:(MXKDataSource *)dataSource didRecognizeAction:(NSString *)actionIdentifier inCell:(id)cell userInfo:(NSDictionary *)userInfo 285 | { 286 | // Override default implementation in case of long press on avatar 287 | if ([actionIdentifier isEqualToString:kMXKRoomBubbleCellLongPressOnAvatarView]) 288 | { 289 | selectedRoomMember = [self.roomDataSource.room.state memberWithUserId:userInfo[kMXKRoomBubbleCellUserIdKey]]; 290 | if (selectedRoomMember) 291 | { 292 | [self performSegueWithIdentifier:@"showMemberDetails" sender:self]; 293 | } 294 | } 295 | else 296 | { 297 | // Keep default implementation for other actions 298 | [super dataSource:dataSource didRecognizeAction:actionIdentifier inCell:cell userInfo:userInfo]; 299 | } 300 | } 301 | 302 | #pragma mark - Segues 303 | 304 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 305 | { 306 | // Keep ref on destinationViewController 307 | [super prepareForSegue:segue sender:sender]; 308 | 309 | id pushedViewController = [segue destinationViewController]; 310 | 311 | if ([[segue identifier] isEqualToString:@"showMemberList"]) 312 | { 313 | if ([pushedViewController isKindOfClass:[RoomMembersViewController class]]) 314 | { 315 | RoomMembersViewController* membersController = (RoomMembersViewController*)pushedViewController; 316 | 317 | membersController.roomMembersViewControllerDelegate = self; 318 | membersController.enableMention = YES; 319 | 320 | // Dismiss keyboard 321 | [self dismissKeyboard]; 322 | 323 | MXKRoomMemberListDataSource *membersDataSource = [[MXKRoomMemberListDataSource alloc] initWithRoomId:self.roomDataSource.roomId andMatrixSession:self.mainSession]; 324 | [membersDataSource finalizeInitialization]; 325 | 326 | [membersController displayList:membersDataSource]; 327 | } 328 | } 329 | else if ([[segue identifier] isEqualToString:@"showMemberDetails"]) 330 | { 331 | if (selectedRoomMember) 332 | { 333 | MXKRoomMemberDetailsViewController *memberViewController = pushedViewController; 334 | 335 | // Set rageShake handler 336 | memberViewController.rageShakeManager = [RageShakeManager sharedManager]; 337 | 338 | // Set delegate to handle start chat option 339 | memberViewController.delegate = self; 340 | memberViewController.enableMention = YES; 341 | 342 | [memberViewController displayRoomMember:selectedRoomMember withMatrixRoom:self.roomDataSource.room]; 343 | 344 | selectedRoomMember = nil; 345 | } 346 | } 347 | } 348 | 349 | #pragma mark - MXKRoomMemberDetailsViewControllerDelegate 350 | 351 | - (void)roomMemberDetailsViewController:(MXKRoomMemberDetailsViewController *)roomMemberDetailsViewController startChatWithMemberId:(NSString *)matrixId completion:(void (^)(void))completion 352 | { 353 | [[AppDelegate theDelegate] startPrivateOneToOneRoomWithUserId:matrixId completion:completion]; 354 | } 355 | 356 | - (void)roomMemberDetailsViewController:(MXKRoomMemberDetailsViewController *)roomMemberDetailsViewController mention:(MXRoomMember *)member 357 | { 358 | [self mention:member]; 359 | } 360 | 361 | #pragma mark - RoomMembersViewControllerDelegate 362 | 363 | - (void)roomMembersViewController:(RoomMembersViewController *)roomMembersViewController mention:(MXRoomMember*)member 364 | { 365 | [self mention:member]; 366 | } 367 | 368 | #pragma mark - Action 369 | 370 | - (IBAction)onButtonPressed:(id)sender 371 | { 372 | if (sender == voipVoiceCallButton || sender == voipVideoCallButton) 373 | { 374 | BOOL isVideoCall = (sender == voipVideoCallButton); 375 | NSString *appDisplayName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]; 376 | 377 | // Check app permissions before placing the call 378 | [MXKTools checkAccessForCall:isVideoCall 379 | manualChangeMessageForAudio:[NSString stringWithFormat:[NSBundle mxk_localizedStringForKey:@"microphone_access_not_granted_for_call"], appDisplayName] 380 | manualChangeMessageForVideo:[NSString stringWithFormat:[NSBundle mxk_localizedStringForKey:@"camera_access_not_granted_for_call"], appDisplayName] 381 | showPopUpInViewController:self completionHandler:^(BOOL granted) { 382 | 383 | if (granted) 384 | { 385 | [self.roomDataSource.room placeCallWithVideo:isVideoCall success:nil failure:nil]; 386 | } 387 | else 388 | { 389 | NSLog(@"RoomViewController: Warning: The application does not have the perssion to place the call"); 390 | } 391 | }]; 392 | } 393 | } 394 | 395 | @end 396 | 397 | 398 | -------------------------------------------------------------------------------- /matrixConsole/ViewController/SettingsViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | @interface SettingsViewController : MXKTableViewController 20 | 21 | /** 22 | The application settings displayed in the view controller. 23 | By default the shared application settings are considered. 24 | */ 25 | @property (nonatomic) MXKAppSettings *settings; 26 | 27 | - (BOOL)isChromeInstalled; 28 | 29 | @end 30 | 31 | -------------------------------------------------------------------------------- /matrixConsole/empty.mm: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | /* 20 | This file exists only to force Xcode to use the GNU c++ standard library (libstdc++). 21 | Even if the project settings indicate they want to use libstdc++, if there is no .mm file, Xcode 22 | continues to use its c++ lib. That prevents the app from linking if it includes some .hh files. 23 | 24 | @see: http://stackoverflow.com/a/19250215/3936576 25 | 26 | */ 27 | -------------------------------------------------------------------------------- /matrixConsole/main.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "AppDelegate.h" 19 | 20 | #import 21 | 22 | int main(int argc, char * argv[]) { 23 | @autoreleasepool { 24 | 25 | // Redirect NSLogs to files only if we are not debugging 26 | if (!isatty(STDERR_FILENO)) { 27 | [MXLogger redirectNSLogToFiles:YES]; 28 | } 29 | // Catch and log crashes 30 | [MXLogger logCrashes:YES]; 31 | [MXLogger setBuildVersion:[AppDelegate theDelegate].build]; 32 | 33 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /matrixConsole/matrixConsole-Defaults.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | pushGatewayURL 6 | https://matrix.org/_matrix/push/v1/notify 7 | pusherAppIdDev 8 | org.matrix.console.ios.dev 9 | pusherAppIdProd 10 | org.matrix.console.ios.prod 11 | identityserverurl 12 | https://matrix.org 13 | homeserverurl 14 | https://matrix.org 15 | homeserver 16 | matrix.org 17 | apnsDeviceToken 18 | 19 | showAllEventsInRoomHistory 20 | 21 | showRedactionsInRoomHistory 22 | 23 | showUnsupportedEventsInRoomHistory 24 | 25 | sortRoomMembersUsingLastSeenTime 26 | 27 | showLeftMembersInRoomMemberList 28 | 29 | httpLinkScheme 30 | http 31 | httpsLinkScheme 32 | https 33 | syncLocalContacts 34 | 35 | maxAllowedMediaCacheSize 36 | 1073741824 37 | presenceColorForOnlineUser 38 | 3401011 39 | presenceColorForUnavailableUser 40 | 15066368 41 | presenceColorForOfflineUser 42 | 15020851 43 | 44 | 45 | -------------------------------------------------------------------------------- /matrixConsoleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.matrix.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /matrixConsoleTests/matrixConsoleTests.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 OpenMarket Ltd 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import 19 | 20 | @interface syMessagingTests : XCTestCase 21 | 22 | @end 23 | 24 | @implementation syMessagingTests 25 | 26 | - (void)setUp { 27 | [super setUp]; 28 | // Put setup code here. This method is called before the invocation of each test method in the class. 29 | } 30 | 31 | - (void)tearDown { 32 | // Put teardown code here. This method is called after the invocation of each test method in the class. 33 | [super tearDown]; 34 | } 35 | 36 | - (void)testExample { 37 | // This is an example of a functional test case. 38 | XCTAssert(YES, @"Pass"); 39 | } 40 | 41 | - (void)testPerformanceExample { 42 | // This is an example of a performance test case. 43 | [self measureBlock:^{ 44 | // Put the code you want to measure the time of here. 45 | }]; 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /use-dev-pods.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This script modifies Podfile in order to use Matrix pods on their develop branch. 4 | # It is intended to be used by Jenkins to build the develop version of the app. 5 | 6 | echo Moving Podfile to develop Matrix pods 7 | 8 | # Podfile.lock will be obsolete reset it 9 | rm -f Podfile.lock 10 | 11 | # Disable the active pods 12 | sed -i '' -E "s!^(pod)(.*MatrixSDK)!#\1\2!g" Podfile 13 | sed -i '' -E "s!^(pod)(.*MatrixKit)!#\1\2!g" Podfile 14 | # And enable the develop ones 15 | sed -i '' -E "s!^(#pod)(.*MatrixSDK)(.*develop)!pod\2\3!g" Podfile 16 | sed -i '' -E "s!^(#pod)(.*MatrixKit)(.*develop)!pod\2\3!g" Podfile 17 | --------------------------------------------------------------------------------