mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-28 15:22:39 +00:00
Settings > Security: Add Manage Session screen
This commit is contained in:
parent
d41fca982d
commit
f136c714c6
7 changed files with 815 additions and 1 deletions
|
@ -100,6 +100,8 @@
|
|||
32BF995321FA2A1300698084 /* SettingsKeyBackupViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32BF995221FA2A1300698084 /* SettingsKeyBackupViewState.swift */; };
|
||||
32BF995521FA2AB700698084 /* SettingsKeyBackupViewAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32BF995421FA2AB700698084 /* SettingsKeyBackupViewAction.swift */; };
|
||||
32BF995721FB07A400698084 /* SettingsKeyBackupTableViewSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32BF995621FB07A400698084 /* SettingsKeyBackupTableViewSection.swift */; };
|
||||
32D5D16023E1EE2700E3E37C /* ManageSessionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 32D5D15D23E1EE2700E3E37C /* ManageSessionViewController.m */; };
|
||||
32D5D16123E1EE2700E3E37C /* ManageSession.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 32D5D15E23E1EE2700E3E37C /* ManageSession.storyboard */; };
|
||||
32DB557522FDADE50016329E /* ServiceTermsModalCoordinatorType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32DB556922FDADE50016329E /* ServiceTermsModalCoordinatorType.swift */; };
|
||||
32DB557622FDADE50016329E /* ServiceTermsModalCoordinatorBridgePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32DB556A22FDADE50016329E /* ServiceTermsModalCoordinatorBridgePresenter.swift */; };
|
||||
32DB557722FDADE50016329E /* ServiceTermsModalCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32DB556B22FDADE50016329E /* ServiceTermsModalCoordinator.swift */; };
|
||||
|
@ -777,6 +779,9 @@
|
|||
32BF995221FA2A1300698084 /* SettingsKeyBackupViewState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsKeyBackupViewState.swift; sourceTree = "<group>"; };
|
||||
32BF995421FA2AB700698084 /* SettingsKeyBackupViewAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsKeyBackupViewAction.swift; sourceTree = "<group>"; };
|
||||
32BF995621FB07A400698084 /* SettingsKeyBackupTableViewSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsKeyBackupTableViewSection.swift; sourceTree = "<group>"; };
|
||||
32D5D15D23E1EE2700E3E37C /* ManageSessionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ManageSessionViewController.m; sourceTree = "<group>"; };
|
||||
32D5D15E23E1EE2700E3E37C /* ManageSession.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = ManageSession.storyboard; sourceTree = "<group>"; };
|
||||
32D5D15F23E1EE2700E3E37C /* ManageSessionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ManageSessionViewController.h; sourceTree = "<group>"; };
|
||||
32D7159E2146CC6F00DF59C9 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Vector.strings; sourceTree = "<group>"; };
|
||||
32D7159F2146CC7F00DF59C9 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
32D715A02146CC8800DF59C9 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
|
@ -1811,6 +1816,7 @@
|
|||
3291DC8823E0BE380009732F /* Security */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
32D5D15C23E1EE2700E3E37C /* ManageSession */,
|
||||
3291DC8B23E0BFF10009732F /* SecurityViewController.h */,
|
||||
3291DC8C23E0BFF10009732F /* SecurtiyViewController.m */,
|
||||
3291DC8923E0BE820009732F /* Security.storyboard */,
|
||||
|
@ -1875,6 +1881,16 @@
|
|||
path = KeyBackup;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
32D5D15C23E1EE2700E3E37C /* ManageSession */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
32D5D15D23E1EE2700E3E37C /* ManageSessionViewController.m */,
|
||||
32D5D15E23E1EE2700E3E37C /* ManageSession.storyboard */,
|
||||
32D5D15F23E1EE2700E3E37C /* ManageSessionViewController.h */,
|
||||
);
|
||||
path = ManageSession;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
32DB556722FDADE50016329E /* ServiceTerms */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -4215,6 +4231,7 @@
|
|||
B1B557C120EF5B4500210D55 /* DisabledRoomInputToolbarView.xib in Resources */,
|
||||
B1DCC61722E5E17100625807 /* EmojiPickerViewController.storyboard in Resources */,
|
||||
32891D6C2264CBA300C82226 /* SimpleScreenTemplateViewController.storyboard in Resources */,
|
||||
32D5D16123E1EE2700E3E37C /* ManageSession.storyboard in Resources */,
|
||||
B1963B2C228F1C4900CBA17F /* BubbleReactionViewCell.xib in Resources */,
|
||||
B1664DA320F4F96200808783 /* Vector.strings in Resources */,
|
||||
B1B557C720EF5CD400210D55 /* DirectoryServerDetailTableViewCell.xib in Resources */,
|
||||
|
@ -4753,6 +4770,7 @@
|
|||
B1DCC62822E60CE300625807 /* EmojiCategory.swift in Sources */,
|
||||
B14084CC23BF9DE90010F692 /* KeyVerificationConclusionWithPaginationTitleBubbleCell.swift in Sources */,
|
||||
B1B5578F20EF568D00210D55 /* GroupTableViewCell.m in Sources */,
|
||||
32D5D16023E1EE2700E3E37C /* ManageSessionViewController.m in Sources */,
|
||||
B1B5573220EE6C4D00210D55 /* GroupHomeViewController.m in Sources */,
|
||||
B1B5595220EF9A8700210D55 /* RecentTableViewCell.m in Sources */,
|
||||
32F6B96C2270623100BBA352 /* DeviceVerificationDataLoadingCoordinatorType.swift in Sources */,
|
||||
|
|
|
@ -557,6 +557,15 @@
|
|||
"security_settings_export_keys_manually" = "Export keys manually";
|
||||
|
||||
|
||||
// Manage session
|
||||
"manage_session_title" = "Manage session";
|
||||
"manage_session_info" = "SESSION INFO";
|
||||
"manage_session_name" = "Device name";
|
||||
"manage_session_trusted" = "Trusted by you";
|
||||
"manage_session_not_trusted" = "Not trusted";
|
||||
"manage_session_sign_out" = "Sign out of this device";
|
||||
|
||||
|
||||
// Identity server settings
|
||||
"identity_server_settings_title" = "Identity Server";
|
||||
|
||||
|
|
|
@ -1534,6 +1534,30 @@ internal enum VectorL10n {
|
|||
internal static var leave: String {
|
||||
return VectorL10n.tr("Vector", "leave")
|
||||
}
|
||||
/// SESSION INFO
|
||||
internal static var manageSessionInfo: String {
|
||||
return VectorL10n.tr("Vector", "manage_session_info")
|
||||
}
|
||||
/// Device name
|
||||
internal static var manageSessionName: String {
|
||||
return VectorL10n.tr("Vector", "manage_session_name")
|
||||
}
|
||||
/// Not trusted
|
||||
internal static var manageSessionNotTrusted: String {
|
||||
return VectorL10n.tr("Vector", "manage_session_not_trusted")
|
||||
}
|
||||
/// Sign out of this device
|
||||
internal static var manageSessionSignOut: String {
|
||||
return VectorL10n.tr("Vector", "manage_session_sign_out")
|
||||
}
|
||||
/// Manage session
|
||||
internal static var manageSessionTitle: String {
|
||||
return VectorL10n.tr("Vector", "manage_session_title")
|
||||
}
|
||||
/// Trusted by you
|
||||
internal static var manageSessionTrusted: String {
|
||||
return VectorL10n.tr("Vector", "manage_session_trusted")
|
||||
}
|
||||
/// Library
|
||||
internal static var mediaPickerLibrary: String {
|
||||
return VectorL10n.tr("Vector", "media_picker_library")
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="QHp-lE-M7m">
|
||||
<device id="retina6_1" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Manage Session View Controller-->
|
||||
<scene sceneID="KQ6-RY-1vS">
|
||||
<objects>
|
||||
<tableViewController id="QHp-lE-M7m" customClass="ManageSessionViewController" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="Fpr-At-4Wb">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="JHA-Ac-OAZ">
|
||||
<rect key="frame" x="0.0" y="55.5" width="414" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="JHA-Ac-OAZ" id="Soh-58-aeC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</prototypes>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="QHp-lE-M7m" id="F5e-nl-xhe"/>
|
||||
<outlet property="delegate" destination="QHp-lE-M7m" id="TJn-MA-abi"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Zo3-gk-o9e" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="65" y="68"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
Copyright 2020 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <MatrixKit/MatrixKit.h>
|
||||
|
||||
#import "DeviceView.h"
|
||||
|
||||
|
||||
@interface ManageSessionViewController : MXKTableViewController
|
||||
|
||||
+ (ManageSessionViewController*)instantiateWithMatrixSession:(MXSession*)matrixSession andDevice:(MXDevice*)device;
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,691 @@
|
|||
/*
|
||||
Copyright 2020 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "ManageSessionViewController.h"
|
||||
|
||||
#import <MatrixKit/MatrixKit.h>
|
||||
|
||||
#import <OLMKit/OLMKit.h>
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "AvatarGenerator.h"
|
||||
|
||||
#import "ThemeService.h"
|
||||
|
||||
#import "Riot-Swift.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
SECTION_SESSION_INFO,
|
||||
SECTION_ACTION,
|
||||
SECTION_COUNT
|
||||
};
|
||||
|
||||
enum {
|
||||
SESSION_INFO_SESSION_NAME,
|
||||
SESSION_INFO_TRUST,
|
||||
SESSION_INFO_COUNT
|
||||
};
|
||||
|
||||
enum {
|
||||
ACTION_REMOVE_SESSION,
|
||||
ACTION_COUNT
|
||||
};
|
||||
|
||||
|
||||
@interface ManageSessionViewController () <
|
||||
MXKDataSourceDelegate,
|
||||
MXKDeviceViewDelegate,
|
||||
MXKEncryptionInfoViewDelegate>
|
||||
{
|
||||
// The device to display
|
||||
MXDevice *device;
|
||||
|
||||
// Current alert (if any).
|
||||
UIAlertController *currentAlert;
|
||||
|
||||
DeviceView *deviceView;
|
||||
|
||||
// Observe kAppDelegateDidTapStatusBarNotification to handle tap on clock status bar.
|
||||
id kAppDelegateDidTapStatusBarNotificationObserver;
|
||||
|
||||
// Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change.
|
||||
id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
|
||||
// The current pushed view controller
|
||||
UIViewController *pushedViewController;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation ManageSessionViewController
|
||||
|
||||
#pragma mark - Setup & Teardown
|
||||
|
||||
+ (ManageSessionViewController*)instantiateWithMatrixSession:(MXSession*)matrixSession andDevice:(MXDevice*)device;
|
||||
{
|
||||
ManageSessionViewController* viewController = [[UIStoryboard storyboardWithName:@"ManageSession" bundle:[NSBundle mainBundle]] instantiateInitialViewController];
|
||||
[viewController addMatrixSession:matrixSession];
|
||||
viewController->device = device;
|
||||
return viewController;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - View life cycle
|
||||
|
||||
- (void)finalizeInit
|
||||
{
|
||||
[super finalizeInit];
|
||||
|
||||
// Setup `MXKViewControllerHandling` properties
|
||||
self.enableBarTintColorStatusChange = NO;
|
||||
self.rageShakeManager = [RageShakeManager sharedManager];
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view, typically from a nib.
|
||||
|
||||
self.navigationItem.title = NSLocalizedStringFromTable(@"manage_session_title", @"Vector", nil);
|
||||
|
||||
// Remove back bar button title when pushing a view controller
|
||||
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
|
||||
|
||||
[self.tableView registerClass:MXKTableViewCellWithLabelAndTextField.class forCellReuseIdentifier:[MXKTableViewCellWithLabelAndTextField defaultReuseIdentifier]];
|
||||
[self.tableView registerClass:MXKTableViewCellWithLabelAndSwitch.class forCellReuseIdentifier:[MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier]];
|
||||
[self.tableView registerNib:MXKTableViewCellWithTextView.nib forCellReuseIdentifier:[MXKTableViewCellWithTextView defaultReuseIdentifier]];
|
||||
|
||||
// Enable self sizing cells
|
||||
self.tableView.rowHeight = UITableViewAutomaticDimension;
|
||||
self.tableView.estimatedRowHeight = 50;
|
||||
|
||||
// Observe user interface theme change.
|
||||
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
[self userInterfaceThemeDidChange];
|
||||
|
||||
}];
|
||||
[self userInterfaceThemeDidChange];
|
||||
}
|
||||
|
||||
- (void)userInterfaceThemeDidChange
|
||||
{
|
||||
[ThemeService.shared.theme applyStyleOnNavigationBar:self.navigationController.navigationBar];
|
||||
|
||||
self.activityIndicator.backgroundColor = ThemeService.shared.theme.overlayBackgroundColor;
|
||||
|
||||
// Check the table view style to select its bg color.
|
||||
self.tableView.backgroundColor = ((self.tableView.style == UITableViewStylePlain) ? ThemeService.shared.theme.backgroundColor : ThemeService.shared.theme.headerBackgroundColor);
|
||||
self.view.backgroundColor = self.tableView.backgroundColor;
|
||||
self.tableView.separatorColor = ThemeService.shared.theme.lineBreakColor;
|
||||
|
||||
if (self.tableView.dataSource)
|
||||
{
|
||||
[self refreshSettings];
|
||||
}
|
||||
}
|
||||
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle
|
||||
{
|
||||
return ThemeService.shared.theme.statusBarStyle;
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning
|
||||
{
|
||||
[super didReceiveMemoryWarning];
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
- (void)destroy
|
||||
{
|
||||
// Release the potential pushed view controller
|
||||
[self releasePushedViewController];
|
||||
|
||||
if (kThemeServiceDidChangeThemeNotificationObserver)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:kThemeServiceDidChangeThemeNotificationObserver];
|
||||
kThemeServiceDidChangeThemeNotificationObserver = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onMatrixSessionStateDidChange:(NSNotification *)notif
|
||||
{
|
||||
MXSession *mxSession = notif.object;
|
||||
|
||||
// Check whether the concerned session is a new one which is not already associated with this view controller.
|
||||
if (mxSession.state == MXSessionStateInitialised && [self.mxSessions indexOfObject:mxSession] != NSNotFound)
|
||||
{
|
||||
// Store this new session
|
||||
[self addMatrixSession:mxSession];
|
||||
}
|
||||
else
|
||||
{
|
||||
[super onMatrixSessionStateDidChange:notif];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
{
|
||||
[super viewWillAppear:animated];
|
||||
|
||||
// Screen tracking
|
||||
[[Analytics sharedInstance] trackScreen:@"Settings"];
|
||||
|
||||
// Release the potential pushed view controller
|
||||
[self releasePushedViewController];
|
||||
|
||||
// Refresh display
|
||||
[self refreshSettings];
|
||||
|
||||
// Observe kAppDelegateDidTapStatusBarNotificationObserver.
|
||||
kAppDelegateDidTapStatusBarNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kAppDelegateDidTapStatusBarNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
[self.tableView setContentOffset:CGPointMake(-self.tableView.mxk_adjustedContentInset.left, -self.tableView.mxk_adjustedContentInset.top) animated:YES];
|
||||
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated
|
||||
{
|
||||
[super viewWillDisappear:animated];
|
||||
|
||||
if (currentAlert)
|
||||
{
|
||||
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
currentAlert = nil;
|
||||
}
|
||||
|
||||
if (kAppDelegateDidTapStatusBarNotificationObserver)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:kAppDelegateDidTapStatusBarNotificationObserver];
|
||||
kAppDelegateDidTapStatusBarNotificationObserver = nil;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Internal methods
|
||||
|
||||
- (void)pushViewController:(UIViewController*)viewController
|
||||
{
|
||||
// Keep ref on pushed view controller
|
||||
pushedViewController = viewController;
|
||||
|
||||
// Hide back button title
|
||||
self.navigationItem.backBarButtonItem =[[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
|
||||
|
||||
[self.navigationController pushViewController:viewController animated:YES];
|
||||
}
|
||||
|
||||
- (void)releasePushedViewController
|
||||
{
|
||||
if (pushedViewController)
|
||||
{
|
||||
if ([pushedViewController isKindOfClass:[UINavigationController class]])
|
||||
{
|
||||
UINavigationController *navigationController = (UINavigationController*)pushedViewController;
|
||||
for (id subViewController in navigationController.viewControllers)
|
||||
{
|
||||
if ([subViewController respondsToSelector:@selector(destroy)])
|
||||
{
|
||||
[subViewController destroy];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ([pushedViewController respondsToSelector:@selector(destroy)])
|
||||
{
|
||||
[(id)pushedViewController destroy];
|
||||
}
|
||||
|
||||
pushedViewController = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)reset
|
||||
{
|
||||
// Remove observers
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
||||
if (deviceView)
|
||||
{
|
||||
[deviceView removeFromSuperview];
|
||||
deviceView = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showDeviceDetails:(MXDevice *)device
|
||||
{
|
||||
deviceView = [[DeviceView alloc] initWithDevice:device andMatrixSession:self.mainSession];
|
||||
deviceView.delegate = self;
|
||||
|
||||
// Add the view and define edge constraints
|
||||
[self.tableView.superview addSubview:deviceView];
|
||||
[self.tableView.superview bringSubviewToFront:deviceView];
|
||||
|
||||
NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:deviceView
|
||||
attribute:NSLayoutAttributeTop
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self.tableView
|
||||
attribute:NSLayoutAttributeTop
|
||||
multiplier:1.0f
|
||||
constant:0.0f];
|
||||
|
||||
NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:deviceView
|
||||
attribute:NSLayoutAttributeLeft
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self.tableView
|
||||
attribute:NSLayoutAttributeLeft
|
||||
multiplier:1.0f
|
||||
constant:0.0f];
|
||||
|
||||
NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem:deviceView
|
||||
attribute:NSLayoutAttributeWidth
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self.tableView
|
||||
attribute:NSLayoutAttributeWidth
|
||||
multiplier:1.0f
|
||||
constant:0.0f];
|
||||
|
||||
NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:deviceView
|
||||
attribute:NSLayoutAttributeHeight
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self.tableView
|
||||
attribute:NSLayoutAttributeHeight
|
||||
multiplier:1.0f
|
||||
constant:0.0f];
|
||||
|
||||
[NSLayoutConstraint activateConstraints:@[topConstraint, leftConstraint, widthConstraint, heightConstraint]];
|
||||
}
|
||||
|
||||
- (void)deviceView:(DeviceView*)theDeviceView presentAlertController:(UIAlertController *)alert
|
||||
{
|
||||
[self presentViewController:alert animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)dismissDeviceView:(MXKDeviceView *)theDeviceView didUpdate:(BOOL)isUpdated
|
||||
{
|
||||
[deviceView removeFromSuperview];
|
||||
deviceView = nil;
|
||||
}
|
||||
|
||||
- (void)refreshSettings
|
||||
{
|
||||
// Trigger a full table reloadData
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
- (void)requestAccountPasswordWithTitle:(NSString*)title message:(NSString*)message onComplete:(void (^)(NSString *password))onComplete
|
||||
{
|
||||
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
|
||||
// Prompt the user before deleting the device.
|
||||
currentAlert = [UIAlertController alertControllerWithTitle:title
|
||||
message:message
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[currentAlert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
|
||||
textField.secureTextEntry = YES;
|
||||
textField.placeholder = nil;
|
||||
textField.keyboardType = UIKeyboardTypeDefault;
|
||||
}];
|
||||
|
||||
MXWeakify(self);
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action)
|
||||
{
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
self->currentAlert = nil;
|
||||
}]];
|
||||
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"continue"]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
UITextField *textField = [self->currentAlert textFields].firstObject;
|
||||
self->currentAlert = nil;
|
||||
|
||||
onComplete(textField.text);
|
||||
}]];
|
||||
|
||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||
}
|
||||
|
||||
#pragma mark - Segues
|
||||
|
||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
|
||||
{
|
||||
// Keep ref on destinationViewController
|
||||
[super prepareForSegue:segue sender:sender];
|
||||
|
||||
// FIXME add night mode
|
||||
}
|
||||
|
||||
#pragma mark - UITableView data source
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
||||
{
|
||||
return SECTION_COUNT;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
NSInteger count = 0;
|
||||
|
||||
switch (section)
|
||||
{
|
||||
case SECTION_SESSION_INFO:
|
||||
count = SESSION_INFO_COUNT;
|
||||
break;
|
||||
case SECTION_ACTION:
|
||||
count = ACTION_COUNT;
|
||||
break;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
- (MXKTableViewCellWithLabelAndTextField*)getLabelAndTextFieldCell:(UITableView*)tableview forIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
MXKTableViewCellWithLabelAndTextField *cell = [tableview dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndTextField defaultReuseIdentifier] forIndexPath:indexPath];
|
||||
|
||||
cell.mxkLabelLeadingConstraint.constant = cell.separatorInset.left;
|
||||
cell.mxkTextFieldLeadingConstraint.constant = 16;
|
||||
cell.mxkTextFieldTrailingConstraint.constant = 15;
|
||||
|
||||
cell.mxkLabel.textColor = ThemeService.shared.theme.textPrimaryColor;
|
||||
|
||||
cell.mxkTextField.userInteractionEnabled = YES;
|
||||
cell.mxkTextField.borderStyle = UITextBorderStyleNone;
|
||||
cell.mxkTextField.textAlignment = NSTextAlignmentRight;
|
||||
cell.mxkTextField.textColor = ThemeService.shared.theme.textSecondaryColor;
|
||||
cell.mxkTextField.font = [UIFont systemFontOfSize:16];
|
||||
cell.mxkTextField.placeholder = nil;
|
||||
|
||||
cell.accessoryType = UITableViewCellAccessoryNone;
|
||||
cell.accessoryView = nil;
|
||||
|
||||
cell.alpha = 1.0f;
|
||||
cell.userInteractionEnabled = YES;
|
||||
|
||||
[cell layoutIfNeeded];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (MXKTableViewCellWithLabelAndSwitch*)getLabelAndSwitchCell:(UITableView*)tableview forIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
MXKTableViewCellWithLabelAndSwitch *cell = [tableview dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier] forIndexPath:indexPath];
|
||||
|
||||
cell.mxkLabelLeadingConstraint.constant = cell.separatorInset.left;
|
||||
cell.mxkSwitchTrailingConstraint.constant = 15;
|
||||
|
||||
cell.mxkLabel.textColor = ThemeService.shared.theme.textPrimaryColor;
|
||||
|
||||
[cell.mxkSwitch removeTarget:self action:nil forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
// Force layout before reusing a cell (fix switch displayed outside the screen)
|
||||
[cell layoutIfNeeded];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (MXKTableViewCell*)getDefaultTableViewCell:(UITableView*)tableView
|
||||
{
|
||||
MXKTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCell defaultReuseIdentifier]];
|
||||
if (!cell)
|
||||
{
|
||||
cell = [[MXKTableViewCell alloc] init];
|
||||
}
|
||||
else
|
||||
{
|
||||
cell.selectionStyle = UITableViewCellSelectionStyleDefault;
|
||||
cell.accessoryType = UITableViewCellAccessoryNone;
|
||||
cell.accessoryView = nil;
|
||||
cell.imageView.image = nil;
|
||||
}
|
||||
cell.textLabel.accessibilityIdentifier = nil;
|
||||
cell.textLabel.font = [UIFont systemFontOfSize:17];
|
||||
cell.textLabel.textColor = ThemeService.shared.theme.textPrimaryColor;
|
||||
cell.contentView.backgroundColor = UIColor.clearColor;
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (MXKTableViewCell*)trustCellWithDevice:(MXDevice*)device forTableView:(UITableView*)tableView
|
||||
{
|
||||
MXKTableViewCell *cell = [self getDefaultTableViewCell:tableView];
|
||||
|
||||
NSString *deviceId = device.deviceId;
|
||||
MXDeviceInfo *deviceInfo = [self.mainSession.crypto deviceWithDeviceId:deviceId ofUser:self.mainSession.myUser.userId];
|
||||
|
||||
cell.textLabel.numberOfLines = 0;
|
||||
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
|
||||
|
||||
if (deviceInfo.trustLevel.isVerified)
|
||||
{
|
||||
cell.textLabel.text = NSLocalizedStringFromTable(@"manage_session_trusted", @"Vector", nil);
|
||||
cell.imageView.image = [UIImage imageNamed:@"encryption_trusted"];
|
||||
}
|
||||
else
|
||||
{
|
||||
cell.textLabel.text = NSLocalizedStringFromTable(@"manage_session_not_trusted", @"Vector", nil);
|
||||
cell.imageView.image = [UIImage imageNamed:@"encryption_warning"];
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (MXKTableViewCell*)descriptionCellForTableView:(UITableView*)tableView withText:(NSString*)text
|
||||
{
|
||||
MXKTableViewCell *cell = [self getDefaultTableViewCell:tableView];
|
||||
cell.textLabel.text = text;
|
||||
cell.textLabel.textColor = ThemeService.shared.theme.textPrimaryColor;
|
||||
cell.textLabel.numberOfLines = 0;
|
||||
cell.contentView.backgroundColor = ThemeService.shared.theme.headerBackgroundColor;
|
||||
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
|
||||
- (MXKTableViewCellWithTextView*)textViewCellForTableView:(UITableView*)tableView atIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
MXKTableViewCellWithTextView *textViewCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithTextView defaultReuseIdentifier] forIndexPath:indexPath];
|
||||
|
||||
textViewCell.mxkTextView.textColor = ThemeService.shared.theme.textPrimaryColor;
|
||||
textViewCell.mxkTextView.font = [UIFont systemFontOfSize:17];
|
||||
textViewCell.mxkTextView.backgroundColor = [UIColor clearColor];
|
||||
textViewCell.mxkTextViewLeadingConstraint.constant = tableView.separatorInset.left;
|
||||
textViewCell.mxkTextViewTrailingConstraint.constant = tableView.separatorInset.right;
|
||||
textViewCell.mxkTextView.accessibilityIdentifier = nil;
|
||||
|
||||
return textViewCell;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
NSInteger section = indexPath.section;
|
||||
NSInteger row = indexPath.row;
|
||||
|
||||
// set the cell to a default value to avoid application crashes
|
||||
UITableViewCell *cell = [[UITableViewCell alloc] init];
|
||||
cell.backgroundColor = [UIColor redColor];
|
||||
|
||||
MXSession* session = self.mainSession;
|
||||
switch (section)
|
||||
{
|
||||
case SECTION_SESSION_INFO:
|
||||
switch (row)
|
||||
{
|
||||
case SESSION_INFO_SESSION_NAME:
|
||||
{
|
||||
MXKTableViewCellWithLabelAndTextField *displaynameCell = [self getLabelAndTextFieldCell:tableView forIndexPath:indexPath];
|
||||
|
||||
displaynameCell.mxkLabel.text = NSLocalizedStringFromTable(@"manage_session_name", @"Vector", nil);
|
||||
displaynameCell.mxkTextField.text = device.displayName;
|
||||
displaynameCell.mxkTextField.userInteractionEnabled = NO;
|
||||
|
||||
cell = displaynameCell;
|
||||
break;
|
||||
}
|
||||
case SESSION_INFO_TRUST:
|
||||
{
|
||||
cell = [self trustCellWithDevice:device forTableView:tableView];
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case SECTION_ACTION:
|
||||
switch (row)
|
||||
{
|
||||
case ACTION_REMOVE_SESSION:
|
||||
{
|
||||
MXKTableViewCellWithButton *deactivateAccountBtnCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithButton defaultReuseIdentifier]];
|
||||
|
||||
if (!deactivateAccountBtnCell)
|
||||
{
|
||||
deactivateAccountBtnCell = [[MXKTableViewCellWithButton alloc] init];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fix https://github.com/vector-im/riot-ios/issues/1354
|
||||
deactivateAccountBtnCell.mxkButton.titleLabel.text = nil;
|
||||
}
|
||||
|
||||
NSString *btnTitle = NSLocalizedStringFromTable(@"manage_session_sign_out", @"Vector", nil);
|
||||
[deactivateAccountBtnCell.mxkButton setTitle:btnTitle forState:UIControlStateNormal];
|
||||
[deactivateAccountBtnCell.mxkButton setTitle:btnTitle forState:UIControlStateHighlighted];
|
||||
[deactivateAccountBtnCell.mxkButton setTintColor:ThemeService.shared.theme.warningColor];
|
||||
deactivateAccountBtnCell.mxkButton.titleLabel.font = [UIFont systemFontOfSize:17];
|
||||
|
||||
[deactivateAccountBtnCell.mxkButton removeTarget:self action:nil forControlEvents:UIControlEventTouchUpInside];
|
||||
//[deactivateAccountBtnCell.mxkButton addTarget:self action:@selector(deactivateAccountAction) forControlEvents:UIControlEventTouchUpInside];
|
||||
deactivateAccountBtnCell.mxkButton.accessibilityIdentifier = nil;
|
||||
|
||||
cell = deactivateAccountBtnCell;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
|
||||
{
|
||||
switch (section)
|
||||
{
|
||||
case SECTION_SESSION_INFO:
|
||||
return NSLocalizedStringFromTable(@"manage_session_info", @"Vector", nil);
|
||||
case SECTION_ACTION:
|
||||
return @"";
|
||||
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
|
||||
{
|
||||
if ([view isKindOfClass:UITableViewHeaderFooterView.class])
|
||||
{
|
||||
// Customize label style
|
||||
UITableViewHeaderFooterView *tableViewHeaderFooterView = (UITableViewHeaderFooterView*)view;
|
||||
tableViewHeaderFooterView.textLabel.textColor = ThemeService.shared.theme.textPrimaryColor;
|
||||
tableViewHeaderFooterView.textLabel.font = [UIFont systemFontOfSize:15];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - UITableView delegate
|
||||
|
||||
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
|
||||
{
|
||||
cell.backgroundColor = ThemeService.shared.theme.backgroundColor;
|
||||
|
||||
if (cell.selectionStyle != UITableViewCellSelectionStyleNone)
|
||||
{
|
||||
// Update the selected background view
|
||||
if (ThemeService.shared.theme.selectedBackgroundColor)
|
||||
{
|
||||
cell.selectedBackgroundView = [[UIView alloc] init];
|
||||
cell.selectedBackgroundView.backgroundColor = ThemeService.shared.theme.selectedBackgroundColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tableView.style == UITableViewStylePlain)
|
||||
{
|
||||
cell.selectedBackgroundView = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
cell.selectedBackgroundView.backgroundColor = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
|
||||
{
|
||||
if (section == SECTION_SESSION_INFO)
|
||||
{
|
||||
return 44;
|
||||
}
|
||||
return 24;
|
||||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
|
||||
{
|
||||
if (section == SECTION_SESSION_INFO)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 24;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
if (self.tableView == tableView)
|
||||
{
|
||||
NSInteger section = indexPath.section;
|
||||
NSInteger row = indexPath.row;
|
||||
|
||||
if (section == SECTION_SESSION_INFO)
|
||||
{
|
||||
//[self showDeviceDetails:devicesArray[deviceIndex]];
|
||||
}
|
||||
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - actions
|
||||
|
||||
|
||||
#pragma mark - MXKDataSourceDelegate
|
||||
|
||||
- (void)dataSource:(MXKDataSource *)dataSource didCellChange:(id)changes
|
||||
{
|
||||
// Group data has been updated. Do a simple full reload
|
||||
[self refreshSettings];
|
||||
}
|
||||
|
||||
@end
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#import "SecurityViewController.h"
|
||||
|
||||
#import "ManageSessionViewController.h"
|
||||
|
||||
#import <MatrixKit/MatrixKit.h>
|
||||
|
||||
#import <OLMKit/OLMKit.h>
|
||||
|
@ -902,7 +904,9 @@ UIDocumentInteractionControllerDelegate>
|
|||
NSUInteger deviceIndex = row;
|
||||
if (deviceIndex < devicesArray.count)
|
||||
{
|
||||
[self showDeviceDetails:devicesArray[deviceIndex]];
|
||||
ManageSessionViewController *viewController = [ManageSessionViewController instantiateWithMatrixSession:self.mainSession andDevice:devicesArray[deviceIndex]];
|
||||
|
||||
[self pushViewController:viewController];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue