Commit 3652cfb0 authored by Loïc Siret's avatar Loïc Siret Committed by Alexandre Lision

multi-device: rewording and view improvement

Correct wording concerning multidevice Linking function.
Fix windows size in the account creation wizard.
Addings user hints to better understand Linking function.

Tuleap: #1158
Change-Id: I0d68a68ba61f51200052bb1a4428b82e79848447
parent 4823c951
...@@ -100,8 +100,8 @@ QMetaObject::Connection accountConnection; ...@@ -100,8 +100,8 @@ QMetaObject::Connection accountConnection;
} }
break; break;
case Account::ExportOnRingStatus::WRONG_PASSWORD:{ case Account::ExportOnRingStatus::WRONG_PASSWORD:{
NSLog(@"Export ended with Wrong Password"); NSLog(@"Export ended with wrong password");
[self showError:NSLocalizedString(@"Export ended with Wrong Password", @"Error shown to the user" )]; [self showError:NSLocalizedString(@"The password you entered does not unlock this account", @"Error shown to the user" )];
} }
break; break;
case Account::ExportOnRingStatus::NETWORK_ERROR:{ case Account::ExportOnRingStatus::NETWORK_ERROR:{
...@@ -121,18 +121,23 @@ QMetaObject::Connection accountConnection; ...@@ -121,18 +121,23 @@ QMetaObject::Connection accountConnection;
} }
//TODO: Move String formatting to a dedicated Utility Classes //TODO: Move String formatting to a dedicated Utility Classes
- (NSAttributedString *)formatPinMessage:(NSString*) pin - (NSAttributedString*) formatPinMessage:(NSString*) pin
{ {
NSMutableAttributedString* hereIsThePin = [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"Your generated pin:","Title shown to user to concat with Pin")]; NSMutableAttributedString* thePin = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"\n%@\n", pin]];
NSMutableAttributedString* thePin = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@" %@\n", pin]];
[thePin beginEditing]; [thePin beginEditing];
NSRange range = NSMakeRange(0, [thePin length]); NSRange range = NSMakeRange(0, [thePin length]);
[thePin addAttribute:NSFontAttributeName value:[NSFont fontWithName:@"Helvetica-Bold" size:12.0] range:range]; [thePin addAttribute:NSFontAttributeName value:[NSFont fontWithName:@"Helvetica-Bold" size:20.0] range:range];
[hereIsThePin appendAttributedString:thePin];
NSMutableAttributedString* infos = [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"This pin and the account password should be entered on your new device within 5 minutes. On most client, this is done from \"Existing Ring account\" menu. You may generate a new pin at any moment.","Infos on how to use the pin")];
[hereIsThePin appendAttributedString:infos];
return hereIsThePin; NSMutableParagraphStyle* mutParaStyle=[[NSMutableParagraphStyle alloc] init];
[mutParaStyle setAlignment:NSCenterTextAlignment];
[thePin addAttributes:[NSDictionary dictionaryWithObject:mutParaStyle forKey:NSParagraphStyleAttributeName] range:range];
NSMutableAttributedString* infos = [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"To complete the processs, you need to open Ring on the new device and choose the option \"Link this device to an account\". Your pin is valid for 10 minutes.","Title shown to user to concat with Pin")];
[thePin appendAttributedString:infos];
[thePin endEditing];
return thePin;
} }
@end @end
...@@ -56,6 +56,7 @@ ...@@ -56,6 +56,7 @@
__unsafe_unretained IBOutlet NSProgressIndicator* progressBar; __unsafe_unretained IBOutlet NSProgressIndicator* progressBar;
__unsafe_unretained IBOutlet NSView* errorContainer; __unsafe_unretained IBOutlet NSView* errorContainer;
__unsafe_unretained IBOutlet NSPopover* helpContainer;
Account* accountToCreate; Account* accountToCreate;
NSTimer* errorTimer; NSTimer* errorTimer;
...@@ -83,6 +84,12 @@ ...@@ -83,6 +84,12 @@
[errorContainer setHidden:YES]; [errorContainer setHidden:YES];
} }
- (IBAction)showHelp:(id)sender
{
[helpContainer showRelativeToRect:[sender bounds] ofView:sender preferredEdge:NSMaxYEdge];
}
- (IBAction)importRingAccount:(id)sender - (IBAction)importRingAccount:(id)sender
{ {
[self showLoading]; [self showLoading];
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
@protocol RingWizardNewDelegate <NSObject> @protocol RingWizardNewDelegate <NSObject>
- (void)didCreateAccountWithSuccess:(BOOL)success; - (void)didCreateAccountWithSuccess:(BOOL)success;
- (void)showView:(NSView*)view;
@end @end
@interface RingWizardNewAccountVC : NSViewController @interface RingWizardNewAccountVC : NSViewController
...@@ -29,5 +30,9 @@ ...@@ -29,5 +30,9 @@
@property (nonatomic, weak)NSString* alias; @property (nonatomic, weak)NSString* alias;
@property (nonatomic, weak)NSString* password; @property (nonatomic, weak)NSString* password;
@property (nonatomic, weak)NSString* repeatPassword;
@property (readonly)BOOL isRepeatPasswordValid;
@property (readonly)BOOL isPasswordValid;
- (void)show; - (void)show;
@end @end
...@@ -49,21 +49,41 @@ ...@@ -49,21 +49,41 @@
@implementation RingWizardNewAccountVC @implementation RingWizardNewAccountVC
{ {
__unsafe_unretained IBOutlet NSView* loadingView;
__unsafe_unretained IBOutlet NSView* creationView;
__unsafe_unretained IBOutlet NSButton* photoView; __unsafe_unretained IBOutlet NSButton* photoView;
__unsafe_unretained IBOutlet NSTextField* nicknameField; __unsafe_unretained IBOutlet NSTextField* nicknameField;
__unsafe_unretained IBOutlet NSSecureTextField* passwordField; __unsafe_unretained IBOutlet NSSecureTextField* passwordField;
__unsafe_unretained IBOutlet NSProgressIndicator* progressBar; __unsafe_unretained IBOutlet NSSecureTextField* passwordRepeatField;
__unsafe_unretained IBOutlet NSTextField* indicationLabel;
__unsafe_unretained IBOutlet NSTextField* passwordLabel; __unsafe_unretained IBOutlet NSTextField* passwordLabel;
__unsafe_unretained IBOutlet NSTextField* passwordRepeatLabel;
__unsafe_unretained IBOutlet NSImageView* passwordCheck;
__unsafe_unretained IBOutlet NSImageView* passwordRepeatCheck;
__unsafe_unretained IBOutlet NSButton* createButton; __unsafe_unretained IBOutlet NSButton* createButton;
__unsafe_unretained IBOutlet NSButton* cancelButton; __unsafe_unretained IBOutlet NSButton* cancelButton;
__unsafe_unretained IBOutlet NSProgressIndicator* progressBar;
Account* accountToCreate; Account* accountToCreate;
NSTimer* errorTimer; NSTimer* errorTimer;
QMetaObject::Connection stateChanged; QMetaObject::Connection stateChanged;
} }
NSInteger const NICKNAME_TAG = 1; NSInteger const NICKNAME_TAG = 1;
//ERROR CODE for textfields validations
NSInteger const ERROR_PASSWORD_TOO_SHORT = -1;
NSInteger const ERROR_REPEAT_MISMATCH = -2;
- (BOOL)produceError:(NSError**)error withCode:(NSInteger)code andMessage:(NSString*)message
{
if (error != NULL){
NSDictionary *errorDetail = @{NSLocalizedDescriptionKey: message};
*error = [NSError errorWithDomain:@"Input" code:code userInfo:errorDetail];
}
return NO;
}
- (void)show - (void)show
{ {
...@@ -81,11 +101,25 @@ NSInteger const NICKNAME_TAG = 1; ...@@ -81,11 +101,25 @@ NSInteger const NICKNAME_TAG = 1;
[photoView setWantsLayer: YES]; [photoView setWantsLayer: YES];
photoView.layer.cornerRadius = photoView.frame.size.width / 2; photoView.layer.cornerRadius = photoView.frame.size.width / 2;
photoView.layer.masksToBounds = YES; photoView.layer.masksToBounds = YES;
[self display:creationView];
}
- (void)removeSubviews
{
while ([self.view.subviews count] > 0){
[[self.view.subviews firstObject] removeFromSuperview];
}
}
- (void)display:(NSView *)view
{
[self.delegate showView:view];
} }
- (IBAction)editPhoto:(id)sender - (IBAction)editPhoto:(id)sender
{ {
auto pictureTaker = [IKPictureTaker pictureTaker]; auto pictureTaker = [IKPictureTaker pictureTaker];
[pictureTaker beginPictureTakerSheetForWindow:[self.delegate window] [pictureTaker beginPictureTakerSheetForWindow:[self.delegate window]
withDelegate:self withDelegate:self
...@@ -104,18 +138,66 @@ NSInteger const NICKNAME_TAG = 1; ...@@ -104,18 +138,66 @@ NSInteger const NICKNAME_TAG = 1;
[photoView setImage:[NSImage imageNamed:@"default_user_icon"]]; [photoView setImage:[NSImage imageNamed:@"default_user_icon"]];
} }
#pragma mark - Input validation
- (BOOL)isPasswordValid
{
return self.password.length >= 6;
}
- (BOOL)isRepeatPasswordValid
{
return [self.password isEqualToString:self.repeatPassword];
}
- (BOOL)validateRepeatPassword:(NSError **)error
{
if (!self.isRepeatPasswordValid){
return [self produceError:error
withCode:ERROR_REPEAT_MISMATCH
andMessage:NSLocalizedString(@"Passwords don't match",
@"Indication for user")];
}
return YES;
}
- (BOOL)validatePassword:(NSError **)error
{
if (!self.isRepeatPasswordValid){
return [self produceError:error
withCode:ERROR_PASSWORD_TOO_SHORT
andMessage:NSLocalizedString(@"Password is too short",
@"Indication for user")];
}
return YES;
}
- (BOOL)validateUserInputPassword:(NSError **)error
{
return [self validatePassword:error] && [self validateRepeatPassword:error];
}
- (IBAction)createRingAccount:(id)sender - (IBAction)createRingAccount:(id)sender
{ {
[nicknameField setHidden:YES]; NSError *error = nil;
[progressBar setHidden:NO]; if (![self validateUserInputPassword:&error]){
[createButton setHidden:YES]; NSAlert* alert = [NSAlert alertWithMessageText:[error localizedDescription]
[photoView setHidden:YES]; defaultButton:NSLocalizedString(@"Revise Input",
[passwordField setHidden:YES]; @"Button title")
[passwordLabel setHidden:YES]; alternateButton:nil
[cancelButton setHidden:YES]; otherButton:nil
informativeTextWithFormat:@"%@",error];
[alert beginSheetModalForWindow:passwordField.window
modalDelegate:nil
didEndSelector:NULL
contextInfo:NULL];
return;
}
[self display:loadingView];
[progressBar startAnimation:nil]; [progressBar startAnimation:nil];
[indicationLabel setStringValue:NSLocalizedString(@"Just a moment...",
@"Indication for user")];
if ([self.alias isEqualToString:@""]) { if ([self.alias isEqualToString:@""]) {
self.alias = NSLocalizedString(@"Unknown", @"Name used when user leave field empty"); self.alias = NSLocalizedString(@"Unknown", @"Name used when user leave field empty");
...@@ -139,7 +221,7 @@ NSInteger const NICKNAME_TAG = 1; ...@@ -139,7 +221,7 @@ NSInteger const NICKNAME_TAG = 1;
profile->save(); profile->save();
} }
QModelIndex qIdx = AccountModel::instance().protocolModel()->selectionModel()->currentIndex(); QModelIndex qIdx = AccountModel::instance().protocolModel()->selectionModel()->currentIndex();
[self setCallback]; [self setCallback];
...@@ -229,4 +311,14 @@ NSInteger const NICKNAME_TAG = 1; ...@@ -229,4 +311,14 @@ NSInteger const NICKNAME_TAG = 1;
self.alias = alias; self.alias = alias;
} }
+ (NSSet *)keyPathsForValuesAffectingIsPasswordValid
{
return [NSSet setWithObjects:@"password", nil];
}
+ (NSSet *)keyPathsForValuesAffectingIsRepeatPasswordValid
{
return [NSSet setWithObjects:@"password", @"repeatPassword", nil];
}
@end @end
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
NSOpenSavePanelDelegate, RingWizardChooseDelegate, RingWizardNewDelegate, NSOpenSavePanelDelegate, RingWizardChooseDelegate, RingWizardNewDelegate,
RingWizardLinkDelegate> RingWizardLinkDelegate>
- (void)showChooseWithCancelButton:(BOOL)showCancel; - (void)showChooseWithCancelButton:(BOOL)showCancel;
- (void)showNewAccountVC; - (void)showNewAccountVC;
- (void)showLinkAccountVC; - (void)showLinkAccountVC;
......
...@@ -41,26 +41,26 @@ ...@@ -41,26 +41,26 @@
IBOutlet RingWizardNewAccountVC* newAccountWC; IBOutlet RingWizardNewAccountVC* newAccountWC;
IBOutlet RingWizardLinkAccountVC* linkAccountWC; IBOutlet RingWizardLinkAccountVC* linkAccountWC;
IBOutlet RingWizardChooseVC* chooseActiontWC; IBOutlet RingWizardChooseVC* chooseActiontWC;
float initialHeight;
float currentHeight;
BOOL isCancelable; BOOL isCancelable;
} }
- (instancetype)initWithWindowNibName:(NSString *)windowNibName{
self = [super initWithWindowNibName:windowNibName];
chooseActiontWC = [[RingWizardChooseVC alloc] initWithNibName:@"RingWizardChoose" bundle:nil];
linkAccountWC = [[RingWizardLinkAccountVC alloc] initWithNibName:@"RingWizardLinkAccount" bundle:nil];
newAccountWC = [[RingWizardNewAccountVC alloc] initWithNibName:@"RingWizardChoose" bundle:nil];
return self;
}
- (void)windowDidLoad - (void)windowDidLoad
{ {
[super windowDidLoad]; [super windowDidLoad];
[self.window setBackgroundColor:[NSColor ringGreyHighlight]];
chooseActiontWC = [[RingWizardChooseVC alloc] initWithNibName:@"RingWizardChoose" bundle:nil];
[chooseActiontWC setDelegate:self]; [chooseActiontWC setDelegate:self];
linkAccountWC = [[RingWizardLinkAccountVC alloc] initWithNibName:@"RingWizardLinkAccount" bundle:nil];
[linkAccountWC setDelegate:self]; [linkAccountWC setDelegate:self];
newAccountWC = [[RingWizardNewAccountVC alloc] initWithNibName:@"RingWizardNewAccount" bundle:nil];
[newAccountWC setDelegate:self]; [newAccountWC setDelegate:self];
initialHeight = self.window.frame.size.height; [self.window setBackgroundColor:[NSColor ringGreyHighlight]];
currentHeight = self.window.frame.size.height; [self showChooseWithCancelButton:isCancelable];
isCancelable = NO;
[self showView:chooseActiontWC.view];
} }
- (void)removeSubviews - (void)removeSubviews
...@@ -71,33 +71,31 @@ ...@@ -71,33 +71,31 @@
} }
} }
#define minHeight 135 #define headerHeight 60
- (void)showView: (NSView*) view #define minHeight 141
#define defaultMargin 20
- (void)showView:(NSView*)view
{ {
[self removeSubviews]; [self removeSubviews];
NSRect frame = [self.container frame]; NSRect frame = [self.container frame];
frame.size.height = MAX(minHeight, view.bounds.size.height); float sizeFrame = MAX(minHeight, view.bounds.size.height);
frame.size.height = sizeFrame;
[view setFrame:frame]; [view setFrame:frame];
[self.container setFrame:frame]; [self.container setFrame:frame];
float size = 0; float size = headerHeight + sizeFrame + defaultMargin;
NSView *container = self.window.contentView; NSRect frameWindows = self.window.frame;
for (NSView *child in container.subviews){ frameWindows.size.height = size;
size += child.frame.size.height; [self.window setFrame:frameWindows display:YES animate:YES];
}
if (currentHeight != size){
currentHeight = size;
NSRect frameWindows = self.window.frame;
frameWindows.size.height = currentHeight;
[self.window setFrame:frameWindows display:YES animate:YES];
}
[self.container addSubview:view]; [self.container addSubview:view];
} }
- (void)showChooseWithCancelButton:(BOOL)showCancel - (void)showChooseWithCancelButton:(BOOL)showCancel
{ {
[self showView: chooseActiontWC.view];
[chooseActiontWC showCancelButton:showCancel]; [chooseActiontWC showCancelButton:showCancel];
isCancelable = showCancel; isCancelable = showCancel;
[self showView:chooseActiontWC.view];
} }
- (void)showNewAccountVC - (void)showNewAccountVC
......
/* Class = "NSTextFieldCell"; title = "To use this account on other devices, you must first expose it on Ring. 
This will generate a PIN code that you must enter on the new device to setup the account. 
The PIN is valid for 10 minutes."; ObjectID = "Kzk-fW-9c3"; */
"Kzk-fW-9c3.title" = "To use this account on other devices, you must first expose it on Ring. 
This will generate a PIN code that you must enter on the new device to setup the account. 
The PIN is valid for 10 minutes.";
/* Class = "NSTextFieldCell"; title = "Use the same Ring account on multiple devices. Below is the list of devices linked to this Ring account"; ObjectID = "kMd-iv-UAy"; */
"kMd-iv-UAy.title" = "Use the same Ring account on multiple devices. Below is the list of devices linked to this Ring account";
/* Class = "NSTextFieldCell"; placeholderString = "Status"; ObjectID = "mAD-1Z-aYB"; */
"mAD-1Z-aYB.placeholderString" = "Status";
/* Class = "NSButtonCell"; title = "Link another device to this account"; ObjectID = "uDY-qB-G0I"; */
"uDY-qB-G0I.title" = "Link another device to this account";
/* Class = "NSTextFieldCell"; placeholderString = "Name"; ObjectID = "w62-Jz-2tu"; */
"w62-Jz-2tu.placeholderString" = "Name";
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11201" systemVersion="15G1004" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> <document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11201" systemVersion="16B2553a" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies> <dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11201"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11201"/>
</dependencies> </dependencies>
...@@ -12,19 +12,18 @@ ...@@ -12,19 +12,18 @@
</customObject> </customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/> <customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="Hz6-mo-xeY"> <customView misplaced="YES" id="Hz6-mo-xeY">
<rect key="frame" x="0.0" y="0.0" width="576" height="389"/> <rect key="frame" x="0.0" y="0.0" width="576" height="409"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews> <subviews>
<scrollView fixedFrame="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="57" horizontalPageScroll="10" verticalLineScroll="57" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Cn2-3f-RfE"> <scrollView misplaced="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="57" horizontalPageScroll="10" verticalLineScroll="57" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Cn2-3f-RfE">
<rect key="frame" x="20" y="20" width="536" height="219"/> <rect key="frame" x="20" y="134" width="536" height="219"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <clipView key="contentView" id="5RD-uP-uce">
<clipView key="contentView" ambiguous="YES" id="5RD-uP-uce">
<rect key="frame" x="0.0" y="0.0" width="536" height="219"/> <rect key="frame" x="0.0" y="0.0" width="536" height="219"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<outlineView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" autosaveColumns="NO" rowHeight="55" rowSizeStyle="automatic" viewBased="YES" outlineTableColumn="Sv0-5z-dC2" id="20b-Ji-RbX" customClass="RingOutlineView"> <outlineView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" autosaveColumns="NO" rowHeight="55" rowSizeStyle="automatic" viewBased="YES" outlineTableColumn="Sv0-5z-dC2" id="20b-Ji-RbX" customClass="RingOutlineView">
<rect key="frame" x="0.0" y="0.0" width="536" height="219"/> <rect key="frame" x="1" y="0.0" width="536" height="219"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/> <size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
...@@ -55,9 +54,9 @@ ...@@ -55,9 +54,9 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField verticalHuggingPriority="750" tag="100" translatesAutoresizingMaskIntoConstraints="NO" id="UbS-VO-lii" userLabel="Name label"> <textField verticalHuggingPriority="750" tag="100" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="UbS-VO-lii" userLabel="Name label">
<rect key="frame" x="38" y="26" width="208" height="21"/> <rect key="frame" x="38" y="26" width="208" height="21"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" placeholderString="Name" id="w62-Jz-2tu"> <textFieldCell key="cell" sendsActionOnEndEditing="YES" placeholderString="Name" id="w62-Jz-2tu">
<font key="font" metaFont="system" size="17"/> <font key="font" metaFont="system" size="17"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
...@@ -88,27 +87,40 @@ ...@@ -88,27 +87,40 @@
</subviews> </subviews>
</clipView> </clipView>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="xKj-nZ-7Mx"> <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="xKj-nZ-7Mx">
<rect key="frame" x="0.0" y="-16" width="0.0" height="16"/> <rect key="frame" x="-8" y="-15" width="0.0" height="15"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</scroller> </scroller>
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="eiD-YY-HVN"> <scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="eiD-YY-HVN">
<rect key="frame" x="-16" y="0.0" width="16" height="0.0"/> <rect key="frame" x="-15" y="-8" width="15" height="0.0"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</scroller> </scroller>
</scrollView> </scrollView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="K8a-3i-BoE"> <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="K8a-3i-BoE">
<rect key="frame" x="18" y="310" width="540" height="54"/> <rect key="frame" x="18" y="361" width="540" height="34"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <constraints>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Use the same Ring account on multiple devices." id="kMd-iv-UAy"> <constraint firstAttribute="height" constant="34" id="naw-cT-zM2"/>
</constraints>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Use the same Ring account on multiple devices. Below is the list of devices linked to this Ring account" id="kMd-iv-UAy">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hbO-OT-jpc"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qbe-Z5-0NO">
<rect key="frame" x="220" y="274" width="136" height="32"/> <rect key="frame" x="18" y="52" width="540" height="79"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <constraints>
<buttonCell key="cell" type="push" title="Add new device" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="uDY-qB-G0I"> <constraint firstAttribute="height" constant="79" id="t9o-hB-b8b"/>
</constraints>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="Kzk-fW-9c3">
<font key="font" metaFont="system"/>
<string key="title">To use this account on other devices, you must first expose it on Ring. 
This will generate a PIN code that you must enter on the new device to setup the account. 
The PIN is valid for 10 minutes.</string>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hbO-OT-jpc">
<rect key="frame" x="155" y="16" width="266" height="32"/>
<buttonCell key="cell" type="push" title="Link another device to this account" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="uDY-qB-G0I">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
...@@ -117,7 +129,21 @@ ...@@ -117,7 +129,21 @@
</connections> </connections>
</button> </button>
</subviews> </subviews>
<point key="canvasLocation" x="377" y="270.5"/> <constraints>
<constraint firstAttribute="trailing" secondItem="K8a-3i-BoE" secondAttribute="trailing" constant="20" symbolic="YES" id="04L-Oh-TeA"/>
<constraint firstItem="K8a-3i-BoE" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="14" id="0o1-PJ-Ud6"/>
<constraint firstItem="Cn2-3f-RfE" firstAttribute="leading" secondItem="qbe-Z5-0NO" secondAttribute="leading" id="ICB-cT-5Xz"/>
<constraint firstItem="K8a-3i-BoE" firstAttribute="leading" secondItem="Cn2-3f-RfE" secondAttribute="leading" id="Jiu-i8-QaL"/>