Settings > Security: Add Manage Session screen

This commit is contained in:
manuroe 2020-01-29 17:56:24 +01:00
parent d41fca982d
commit f136c714c6
7 changed files with 815 additions and 1 deletions

View file

@ -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 */,

View file

@ -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";

View file

@ -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")

View file

@ -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>

View file

@ -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

View file

@ -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

View file

@ -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];
}
}