mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-30 16:22:39 +00:00
Console: Improve Authentication screen to support multiple kinds of flow during login and registration.
This commit is contained in:
parent
204267f4f3
commit
75e1a606ac
9 changed files with 1031 additions and 207 deletions
|
@ -65,6 +65,7 @@
|
||||||
F08B6FCC1A1DE7F80094A35B /* matrixConsole.jpg in Resources */ = {isa = PBXBuildFile; fileRef = F08B6FCB1A1DE7F80094A35B /* matrixConsole.jpg */; };
|
F08B6FCC1A1DE7F80094A35B /* matrixConsole.jpg in Resources */ = {isa = PBXBuildFile; fileRef = F08B6FCB1A1DE7F80094A35B /* matrixConsole.jpg */; };
|
||||||
F08DCBDB1A093BFA008C65B6 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F08DCBDA1A093BFA008C65B6 /* MobileCoreServices.framework */; };
|
F08DCBDB1A093BFA008C65B6 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F08DCBDA1A093BFA008C65B6 /* MobileCoreServices.framework */; };
|
||||||
F08E67961A77965A00AABD4C /* MXC3PID.m in Sources */ = {isa = PBXBuildFile; fileRef = F08E67931A77965A00AABD4C /* MXC3PID.m */; };
|
F08E67961A77965A00AABD4C /* MXC3PID.m in Sources */ = {isa = PBXBuildFile; fileRef = F08E67931A77965A00AABD4C /* MXC3PID.m */; };
|
||||||
|
F0AC79331A8394510056D042 /* AuthInputsView.m in Sources */ = {isa = PBXBuildFile; fileRef = F0AC79321A8394510056D042 /* AuthInputsView.m */; };
|
||||||
F0CA8D3D1A80DE08004320A4 /* EventDetailsView.m in Sources */ = {isa = PBXBuildFile; fileRef = F0CA8D3C1A80DE08004320A4 /* EventDetailsView.m */; };
|
F0CA8D3D1A80DE08004320A4 /* EventDetailsView.m in Sources */ = {isa = PBXBuildFile; fileRef = F0CA8D3C1A80DE08004320A4 /* EventDetailsView.m */; };
|
||||||
F0CEA5AE19E6895E00E47915 /* logoHighRes.png in Resources */ = {isa = PBXBuildFile; fileRef = F0CEA5AC19E6895E00E47915 /* logoHighRes.png */; };
|
F0CEA5AE19E6895E00E47915 /* logoHighRes.png in Resources */ = {isa = PBXBuildFile; fileRef = F0CEA5AC19E6895E00E47915 /* logoHighRes.png */; };
|
||||||
F0CEA5AF19E6895E00E47915 /* tab_recents.png in Resources */ = {isa = PBXBuildFile; fileRef = F0CEA5AD19E6895E00E47915 /* tab_recents.png */; };
|
F0CEA5AF19E6895E00E47915 /* tab_recents.png in Resources */ = {isa = PBXBuildFile; fileRef = F0CEA5AD19E6895E00E47915 /* tab_recents.png */; };
|
||||||
|
@ -189,6 +190,8 @@
|
||||||
F08DCBDA1A093BFA008C65B6 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
|
F08DCBDA1A093BFA008C65B6 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
|
||||||
F08E67921A77965A00AABD4C /* MXC3PID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXC3PID.h; sourceTree = "<group>"; };
|
F08E67921A77965A00AABD4C /* MXC3PID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXC3PID.h; sourceTree = "<group>"; };
|
||||||
F08E67931A77965A00AABD4C /* MXC3PID.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXC3PID.m; sourceTree = "<group>"; };
|
F08E67931A77965A00AABD4C /* MXC3PID.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXC3PID.m; sourceTree = "<group>"; };
|
||||||
|
F0AC79311A8394510056D042 /* AuthInputsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AuthInputsView.h; sourceTree = "<group>"; };
|
||||||
|
F0AC79321A8394510056D042 /* AuthInputsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AuthInputsView.m; sourceTree = "<group>"; };
|
||||||
F0CA8D3B1A80DE08004320A4 /* EventDetailsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventDetailsView.h; sourceTree = "<group>"; };
|
F0CA8D3B1A80DE08004320A4 /* EventDetailsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventDetailsView.h; sourceTree = "<group>"; };
|
||||||
F0CA8D3C1A80DE08004320A4 /* EventDetailsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EventDetailsView.m; sourceTree = "<group>"; };
|
F0CA8D3C1A80DE08004320A4 /* EventDetailsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EventDetailsView.m; sourceTree = "<group>"; };
|
||||||
F0CEA5AC19E6895E00E47915 /* logoHighRes.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logoHighRes.png; sourceTree = "<group>"; };
|
F0CEA5AC19E6895E00E47915 /* logoHighRes.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logoHighRes.png; sourceTree = "<group>"; };
|
||||||
|
@ -328,6 +331,8 @@
|
||||||
F03EF5FC19F1762000A0EE52 /* View */ = {
|
F03EF5FC19F1762000A0EE52 /* View */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
F0AC79311A8394510056D042 /* AuthInputsView.h */,
|
||||||
|
F0AC79321A8394510056D042 /* AuthInputsView.m */,
|
||||||
7176294D1A77FED800927125 /* ContactDetailsTableCell.h */,
|
7176294D1A77FED800927125 /* ContactDetailsTableCell.h */,
|
||||||
7176294E1A77FED800927125 /* ContactDetailsTableCell.m */,
|
7176294E1A77FED800927125 /* ContactDetailsTableCell.m */,
|
||||||
71193D2A1A6E433900E59A9E /* ContactTableCell.h */,
|
71193D2A1A6E433900E59A9E /* ContactTableCell.h */,
|
||||||
|
@ -649,6 +654,7 @@
|
||||||
F03EF5F719F171EB00A0EE52 /* AuthenticationViewController.m in Sources */,
|
F03EF5F719F171EB00A0EE52 /* AuthenticationViewController.m in Sources */,
|
||||||
F0D3C30F1A01330F0000D49E /* SettingsTableViewCell.m in Sources */,
|
F0D3C30F1A01330F0000D49E /* SettingsTableViewCell.m in Sources */,
|
||||||
71D2E4EC1A49814B000DE015 /* RoomMemberActionsCell.m in Sources */,
|
71D2E4EC1A49814B000DE015 /* RoomMemberActionsCell.m in Sources */,
|
||||||
|
F0AC79331A8394510056D042 /* AuthInputsView.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,6 +38,7 @@ typedef enum : NSUInteger {
|
||||||
@property (strong, nonatomic) NSString *userId;
|
@property (strong, nonatomic) NSString *userId;
|
||||||
@property (strong, nonatomic, readonly) NSString *localPartFromUserId;
|
@property (strong, nonatomic, readonly) NSString *localPartFromUserId;
|
||||||
@property (strong, nonatomic) NSString *accessToken;
|
@property (strong, nonatomic) NSString *accessToken;
|
||||||
|
@property (strong, nonatomic) NSString *identityServerURL;
|
||||||
|
|
||||||
// The type of events to display
|
// The type of events to display
|
||||||
@property (strong, nonatomic) NSArray *eventsFilterForMessages;
|
@property (strong, nonatomic) NSArray *eventsFilterForMessages;
|
||||||
|
|
|
@ -52,8 +52,6 @@ static MatrixSDKHandler *sharedHandler = nil;
|
||||||
|
|
||||||
@implementation MatrixSDKHandler
|
@implementation MatrixSDKHandler
|
||||||
|
|
||||||
@synthesize homeServerURL, homeServer, userLogin, userId, accessToken;
|
|
||||||
|
|
||||||
+ (MatrixSDKHandler *)sharedHandler {
|
+ (MatrixSDKHandler *)sharedHandler {
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
if(sharedHandler == nil)
|
if(sharedHandler == nil)
|
||||||
|
@ -79,6 +77,9 @@ static MatrixSDKHandler *sharedHandler = nil;
|
||||||
// Read potential homeserver url in shared defaults object
|
// Read potential homeserver url in shared defaults object
|
||||||
if (self.homeServerURL) {
|
if (self.homeServerURL) {
|
||||||
self.mxRestClient = [[MXRestClient alloc] initWithHomeServer:self.homeServerURL];
|
self.mxRestClient = [[MXRestClient alloc] initWithHomeServer:self.homeServerURL];
|
||||||
|
if (self.identityServerURL) {
|
||||||
|
[self.mxRestClient setIdentityServer:self.identityServerURL];
|
||||||
|
}
|
||||||
|
|
||||||
if (self.accessToken) {
|
if (self.accessToken) {
|
||||||
[self openSession];
|
[self openSession];
|
||||||
|
@ -99,6 +100,11 @@ static MatrixSDKHandler *sharedHandler = nil;
|
||||||
|
|
||||||
self.mxRestClient = [[MXRestClient alloc] initWithCredentials:credentials];
|
self.mxRestClient = [[MXRestClient alloc] initWithCredentials:credentials];
|
||||||
if (self.mxRestClient) {
|
if (self.mxRestClient) {
|
||||||
|
// Set identity server (if any)
|
||||||
|
if (self.identityServerURL) {
|
||||||
|
[self.mxRestClient setIdentityServer:self.identityServerURL];
|
||||||
|
}
|
||||||
|
|
||||||
// Use MXFileStore as MXStore to permanently store events
|
// Use MXFileStore as MXStore to permanently store events
|
||||||
_mxFileStore = [[MXFileStore alloc] init];
|
_mxFileStore = [[MXFileStore alloc] init];
|
||||||
|
|
||||||
|
@ -204,6 +210,9 @@ static MatrixSDKHandler *sharedHandler = nil;
|
||||||
[self.mxRestClient close];
|
[self.mxRestClient close];
|
||||||
if (self.homeServerURL) {
|
if (self.homeServerURL) {
|
||||||
self.mxRestClient = [[MXRestClient alloc] initWithHomeServer:self.homeServerURL];
|
self.mxRestClient = [[MXRestClient alloc] initWithHomeServer:self.homeServerURL];
|
||||||
|
if (self.identityServerURL) {
|
||||||
|
[self.mxRestClient setIdentityServer:self.identityServerURL];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.mxRestClient = nil;
|
self.mxRestClient = nil;
|
||||||
}
|
}
|
||||||
|
@ -386,10 +395,14 @@ static MatrixSDKHandler *sharedHandler = nil;
|
||||||
return [[NSUserDefaults standardUserDefaults] objectForKey:@"homeserverurl"];
|
return [[NSUserDefaults standardUserDefaults] objectForKey:@"homeserverurl"];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setHomeServerURL:(NSString *)inHomeserverURL {
|
- (void)setHomeServerURL:(NSString *)inHomeServerURL {
|
||||||
if (inHomeserverURL.length) {
|
if (inHomeServerURL.length) {
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:inHomeserverURL forKey:@"homeserverurl"];
|
[[NSUserDefaults standardUserDefaults] setObject:inHomeServerURL forKey:@"homeserverurl"];
|
||||||
self.mxRestClient = [[MXRestClient alloc] initWithHomeServer:inHomeserverURL];
|
self.mxRestClient = [[MXRestClient alloc] initWithHomeServer:inHomeServerURL];
|
||||||
|
// Set identity server (if any)
|
||||||
|
if (self.identityServerURL) {
|
||||||
|
[self.mxRestClient setIdentityServer:self.identityServerURL];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"homeserverurl"];
|
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"homeserverurl"];
|
||||||
// Reinitialize matrix handler
|
// Reinitialize matrix handler
|
||||||
|
@ -471,6 +484,24 @@ static MatrixSDKHandler *sharedHandler = nil;
|
||||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSString *)identityServerURL {
|
||||||
|
return [[NSUserDefaults standardUserDefaults] objectForKey:@"identityserverurl"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setIdentityServerURL:(NSString *)inIdentityServerURL {
|
||||||
|
if (inIdentityServerURL.length) {
|
||||||
|
[[NSUserDefaults standardUserDefaults] setObject:inIdentityServerURL forKey:@"identityserverurl"];
|
||||||
|
} else {
|
||||||
|
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"identityserverurl"];
|
||||||
|
}
|
||||||
|
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||||
|
|
||||||
|
// Update the current restClient
|
||||||
|
if (self.mxRestClient) {
|
||||||
|
[self.mxRestClient setIdentityServer:self.identityServerURL];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - Matrix user's settings
|
#pragma mark - Matrix user's settings
|
||||||
|
|
||||||
- (void)setUserPresence:(MXPresence)userPresence andStatusMessage:(NSString *)statusMessage completion:(void (^)(void))completion {
|
- (void)setUserPresence:(MXPresence)userPresence andStatusMessage:(NSString *)statusMessage completion:(void (^)(void))completion {
|
||||||
|
|
|
@ -1037,62 +1037,313 @@
|
||||||
<rect key="frame" x="0.0" y="20" width="600" height="580"/>
|
<rect key="frame" x="0.0" y="20" width="600" height="580"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="d6h-O8-aBs" userLabel="Content View">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="d6h-O8-aBs" userLabel="Content View">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="400"/>
|
<rect key="frame" x="0.0" y="0.0" width="600" height="640"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Matrix ID (e.g. @bob:matrix.org or bob)" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="DkI-2d-TR5">
|
|
||||||
<rect key="frame" x="164" y="185" width="272" height="30"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="height" constant="30" id="WJU-Hb-iFm"/>
|
|
||||||
<constraint firstAttribute="width" constant="272" id="gzb-uu-iH0"/>
|
|
||||||
</constraints>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
|
||||||
<textInputTraits key="textInputTraits" returnKeyType="next"/>
|
|
||||||
<connections>
|
|
||||||
<outlet property="delegate" destination="ZlD-EU-ncw" id="q6h-TW-hTR"/>
|
|
||||||
</connections>
|
|
||||||
</textField>
|
|
||||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Password" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="gDT-bj-MHE">
|
|
||||||
<rect key="frame" x="164" y="225" width="272" height="30"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="width" constant="272" id="awG-2v-nb2"/>
|
|
||||||
<constraint firstAttribute="height" constant="30" id="wHP-r9-WAA"/>
|
|
||||||
</constraints>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
|
||||||
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="done" secureTextEntry="YES"/>
|
|
||||||
<connections>
|
|
||||||
<outlet property="delegate" destination="ZlD-EU-ncw" id="eB5-lZ-ZaG"/>
|
|
||||||
</connections>
|
|
||||||
</textField>
|
|
||||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="URL (e.g. http://matrix.org:80)" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="iBz-4w-0cv">
|
|
||||||
<rect key="frame" x="247" y="305" width="210" height="30"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="width" constant="210" id="0Oj-hY-AuE"/>
|
|
||||||
<constraint firstAttribute="height" constant="30" id="waN-MT-6d2"/>
|
|
||||||
</constraints>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
|
||||||
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="done"/>
|
|
||||||
<connections>
|
|
||||||
<outlet property="delegate" destination="ZlD-EU-ncw" id="fJ9-39-2ag"/>
|
|
||||||
</connections>
|
|
||||||
</textField>
|
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="logoHighRes.png" translatesAutoresizingMaskIntoConstraints="NO" id="9oD-IQ-d8J">
|
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="logoHighRes.png" translatesAutoresizingMaskIntoConstraints="NO" id="9oD-IQ-d8J">
|
||||||
<rect key="frame" x="180" y="68" width="240" height="102"/>
|
<rect key="frame" x="180" y="33" width="240" height="102"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="240" id="YfR-TZ-HGu"/>
|
<constraint firstAttribute="width" constant="240" id="YfR-TZ-HGu"/>
|
||||||
<constraint firstAttribute="height" constant="102" id="qiX-ir-FRf"/>
|
<constraint firstAttribute="height" constant="102" id="qiX-ir-FRf"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</imageView>
|
</imageView>
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fnl-LF-rEL">
|
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Create account:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pvw-BQ-kaV">
|
||||||
<rect key="frame" x="281" y="265" width="38" height="30"/>
|
<rect key="frame" x="88" y="147" width="110" height="18"/>
|
||||||
<state key="normal" title="Login">
|
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="sQb-Oi-ER6" userLabel="AuthInputsContainerView">
|
||||||
|
<rect key="frame" x="150" y="170" width="300" height="180"/>
|
||||||
|
<subviews>
|
||||||
|
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="O8N-hu-Ewh" userLabel="AuthInputsPasswordBasedView" customClass="AuthInputsPasswordBasedView">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="300" height="179"/>
|
||||||
|
<subviews>
|
||||||
|
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Matrix ID (e.g. @bob:matrix.org or bob)" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="DkI-2d-TR5">
|
||||||
|
<rect key="frame" x="14" y="8" width="272" height="30"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="height" constant="30" id="WJU-Hb-iFm"/>
|
||||||
|
<constraint firstAttribute="width" constant="272" id="gzb-uu-iH0"/>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<textInputTraits key="textInputTraits" returnKeyType="next"/>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="O8N-hu-Ewh" id="xI6-ue-Bbw"/>
|
||||||
|
</connections>
|
||||||
|
</textField>
|
||||||
|
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Password" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="gDT-bj-MHE">
|
||||||
|
<rect key="frame" x="14" y="46" width="272" height="30"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" constant="272" id="awG-2v-nb2"/>
|
||||||
|
<constraint firstAttribute="height" constant="30" id="wHP-r9-WAA"/>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="done" secureTextEntry="YES"/>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="O8N-hu-Ewh" id="enP-M1-s27"/>
|
||||||
|
</connections>
|
||||||
|
</textField>
|
||||||
|
<textField hidden="YES" opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Display name (e.g. Bob Obson)" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Q4X-yt-15e" userLabel="DisplayName">
|
||||||
|
<rect key="frame" x="14" y="84" width="272" height="30"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" constant="272" id="A1t-Ov-vXU"/>
|
||||||
|
<constraint firstAttribute="height" constant="30" id="RLA-my-oRJ"/>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="next" secureTextEntry="YES"/>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="O8N-hu-Ewh" id="zHD-oq-zzj"/>
|
||||||
|
</connections>
|
||||||
|
</textField>
|
||||||
|
<textField hidden="YES" opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Email address (optional)" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="hnv-Gw-Cnj" userLabel="Email">
|
||||||
|
<rect key="frame" x="14" y="126" width="272" height="30"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="height" constant="30" id="IMW-ae-dUp"/>
|
||||||
|
<constraint firstAttribute="width" constant="272" id="hKn-H5-T9d"/>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="done" secureTextEntry="YES"/>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="O8N-hu-Ewh" id="F7K-1W-Nnc"/>
|
||||||
|
</connections>
|
||||||
|
</textField>
|
||||||
|
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="9ig-1b-AUZ" userLabel="EmailInfoLabel">
|
||||||
|
<rect key="frame" x="14" y="156" width="272" height="15"/>
|
||||||
|
<string key="text">Specify an email address lets other users find you on Matrix more easily, and will give you a way to reset your password in the future.</string>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="9ig-1b-AUZ" secondAttribute="bottom" constant="8" id="7NI-xg-RWo"/>
|
||||||
|
<constraint firstItem="gDT-bj-MHE" firstAttribute="top" secondItem="DkI-2d-TR5" secondAttribute="bottom" constant="8" id="DxY-3A-IYe"/>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="hnv-Gw-Cnj" secondAttribute="centerX" id="Ew9-Ir-5ZG"/>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="Q4X-yt-15e" secondAttribute="centerX" id="Fd9-Vj-hlF"/>
|
||||||
|
<constraint firstItem="hnv-Gw-Cnj" firstAttribute="top" secondItem="Q4X-yt-15e" secondAttribute="bottom" constant="12" id="MWH-Pv-fFJ"/>
|
||||||
|
<constraint firstItem="9ig-1b-AUZ" firstAttribute="leading" secondItem="O8N-hu-Ewh" secondAttribute="leading" constant="14" id="OYt-bj-cVD"/>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="gDT-bj-MHE" secondAttribute="centerX" id="PVZ-Fq-dKH"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="9ig-1b-AUZ" secondAttribute="trailing" constant="14" id="S77-1a-wps"/>
|
||||||
|
<constraint firstItem="9ig-1b-AUZ" firstAttribute="top" secondItem="hnv-Gw-Cnj" secondAttribute="bottom" id="Soy-zj-uRP"/>
|
||||||
|
<constraint firstItem="DkI-2d-TR5" firstAttribute="top" secondItem="O8N-hu-Ewh" secondAttribute="top" constant="8" id="VWB-qs-WRa"/>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="9ig-1b-AUZ" secondAttribute="centerX" id="dqb-WC-1x4"/>
|
||||||
|
<constraint firstItem="Q4X-yt-15e" firstAttribute="top" secondItem="gDT-bj-MHE" secondAttribute="bottom" constant="8" id="fH8-wa-qMI"/>
|
||||||
|
<constraint firstAttribute="width" constant="300" id="lGG-Df-1bn"/>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="DkI-2d-TR5" secondAttribute="centerX" id="sKP-5W-sQk"/>
|
||||||
|
</constraints>
|
||||||
|
<connections>
|
||||||
|
<outlet property="displayNameTextField" destination="Q4X-yt-15e" id="WdS-ab-6Bv"/>
|
||||||
|
<outlet property="emailInfoLabel" destination="9ig-1b-AUZ" id="dK0-5x-JgB"/>
|
||||||
|
<outlet property="emailTextField" destination="hnv-Gw-Cnj" id="hsS-Rv-43G"/>
|
||||||
|
<outlet property="passWordTextField" destination="gDT-bj-MHE" id="cqv-gD-CQe"/>
|
||||||
|
<outlet property="userLoginTextField" destination="DkI-2d-TR5" id="1a2-ak-xgB"/>
|
||||||
|
</connections>
|
||||||
|
</view>
|
||||||
|
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="G6Y-YQ-PvU" userLabel="AuthInputsEmailCodeBasedView" customClass="AuthInputsEmailCodeBasedView">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="300" height="122"/>
|
||||||
|
<subviews>
|
||||||
|
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Matrix ID (e.g. @bob:matrix.org or bob)" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="e5U-3R-SLf">
|
||||||
|
<rect key="frame" x="14" y="8" width="272" height="30"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="height" constant="30" id="dAe-Fy-Ro8"/>
|
||||||
|
<constraint firstAttribute="width" constant="272" id="vJi-7m-V1p"/>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<textInputTraits key="textInputTraits" returnKeyType="next"/>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="G6Y-YQ-PvU" id="SYJ-uu-LGE"/>
|
||||||
|
</connections>
|
||||||
|
</textField>
|
||||||
|
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Email address" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="E10-8t-uAc" userLabel="Email-Token">
|
||||||
|
<rect key="frame" x="14" y="46" width="272" height="30"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="height" constant="30" id="aSd-cp-L7s"/>
|
||||||
|
<constraint firstAttribute="width" constant="272" id="szQ-eZ-pTJ"/>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="done" secureTextEntry="YES"/>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="G6Y-YQ-PvU" id="LKy-hf-UiJ"/>
|
||||||
|
</connections>
|
||||||
|
</textField>
|
||||||
|
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Please enter your email validation token:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EjR-UX-T9v">
|
||||||
|
<rect key="frame" x="20" y="8" width="261" height="30"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<textField hidden="YES" opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Display name (e.g. Bob Obson)" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="6Pu-F7-Xd3" userLabel="DisplayName">
|
||||||
|
<rect key="frame" x="14" y="84" width="272" height="30"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" constant="272" id="2UG-Lc-4TW"/>
|
||||||
|
<constraint firstAttribute="height" constant="30" id="n5C-7V-kJk"/>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="done" secureTextEntry="YES"/>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="G6Y-YQ-PvU" id="sdq-n3-nd8"/>
|
||||||
|
</connections>
|
||||||
|
</textField>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="e5U-3R-SLf" secondAttribute="centerX" id="7C3-hj-pCD"/>
|
||||||
|
<constraint firstItem="6Pu-F7-Xd3" firstAttribute="top" secondItem="E10-8t-uAc" secondAttribute="bottom" constant="8" id="Cu8-aC-0Ri"/>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="EjR-UX-T9v" secondAttribute="centerX" id="Utq-C1-03Y"/>
|
||||||
|
<constraint firstItem="E10-8t-uAc" firstAttribute="top" secondItem="e5U-3R-SLf" secondAttribute="bottom" constant="8" id="VT1-qc-FBw"/>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="E10-8t-uAc" secondAttribute="centerX" id="XCM-Eo-2h5"/>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="6Pu-F7-Xd3" secondAttribute="centerX" id="bHU-Aa-fRf"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="6Pu-F7-Xd3" secondAttribute="bottom" constant="8" id="dmV-e8-Ak8"/>
|
||||||
|
<constraint firstItem="E10-8t-uAc" firstAttribute="top" secondItem="EjR-UX-T9v" secondAttribute="bottom" constant="8" id="gwg-Ln-72n"/>
|
||||||
|
<constraint firstItem="EjR-UX-T9v" firstAttribute="top" secondItem="G6Y-YQ-PvU" secondAttribute="top" constant="8" id="ktN-en-LeS"/>
|
||||||
|
<constraint firstItem="e5U-3R-SLf" firstAttribute="top" secondItem="G6Y-YQ-PvU" secondAttribute="top" constant="8" id="pVD-lt-GF6"/>
|
||||||
|
<constraint firstAttribute="width" constant="300" id="uor-7L-vf9"/>
|
||||||
|
</constraints>
|
||||||
|
<connections>
|
||||||
|
<outlet property="displayNameTextField" destination="6Pu-F7-Xd3" id="dz7-PB-74N"/>
|
||||||
|
<outlet property="emailAndTokenTextField" destination="E10-8t-uAc" id="vWQ-ED-DWS"/>
|
||||||
|
<outlet property="promptEmailTokenLabel" destination="EjR-UX-T9v" id="4AO-pW-pp2"/>
|
||||||
|
<outlet property="userLoginTextField" destination="e5U-3R-SLf" id="ywh-V7-6GX"/>
|
||||||
|
</connections>
|
||||||
|
</view>
|
||||||
|
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="J51-Cj-6mb">
|
||||||
|
<rect key="frame" x="140" y="80" width="20" height="20"/>
|
||||||
|
</activityIndicatorView>
|
||||||
|
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Currently we do not support authentication flows defined by this Home Server" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="eg7-eh-lZv" userLabel="noFlowLabel">
|
||||||
|
<rect key="frame" x="9" y="8" width="283" height="17"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<color key="textColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="70b-I3-Cuk" userLabel="retryButton">
|
||||||
|
<rect key="frame" x="128" y="30" width="45" height="30"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" constant="45" id="4zv-VS-Uz6"/>
|
||||||
|
<constraint firstAttribute="height" constant="30" id="eae-iR-11I"/>
|
||||||
|
</constraints>
|
||||||
|
<state key="normal" title="Retry">
|
||||||
|
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
|
</state>
|
||||||
|
<connections>
|
||||||
|
<action selector="onButtonPressed:" destination="ZlD-EU-ncw" eventType="touchUpInside" id="VMc-vT-H6d"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="70b-I3-Cuk" secondAttribute="centerX" id="2G2-j8-QdO"/>
|
||||||
|
<constraint firstAttribute="centerY" secondItem="J51-Cj-6mb" secondAttribute="centerY" id="6R3-QL-izy"/>
|
||||||
|
<constraint firstItem="G6Y-YQ-PvU" firstAttribute="top" secondItem="sQb-Oi-ER6" secondAttribute="top" id="7zC-MV-yX9"/>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="G6Y-YQ-PvU" secondAttribute="centerX" id="Eft-0W-r1l"/>
|
||||||
|
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="eg7-eh-lZv" secondAttribute="trailing" constant="8" id="Ffa-SN-6DV"/>
|
||||||
|
<constraint firstItem="eg7-eh-lZv" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="sQb-Oi-ER6" secondAttribute="leading" constant="8" id="NQi-Wl-keg"/>
|
||||||
|
<constraint firstItem="O8N-hu-Ewh" firstAttribute="top" secondItem="sQb-Oi-ER6" secondAttribute="top" id="Qhd-nd-xQH"/>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="eg7-eh-lZv" secondAttribute="centerX" id="Rpn-e0-6X2"/>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="O8N-hu-Ewh" secondAttribute="centerX" id="eAO-Dq-dp1"/>
|
||||||
|
<constraint firstItem="eg7-eh-lZv" firstAttribute="top" secondItem="sQb-Oi-ER6" secondAttribute="top" constant="8" id="fqE-nJ-QQK"/>
|
||||||
|
<constraint firstAttribute="height" constant="180" id="gDV-QE-CXd"/>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="J51-Cj-6mb" secondAttribute="centerX" id="jiI-Qk-jML"/>
|
||||||
|
<constraint firstItem="70b-I3-Cuk" firstAttribute="top" secondItem="eg7-eh-lZv" secondAttribute="bottom" constant="5" id="pGi-gI-AOX"/>
|
||||||
|
<constraint firstAttribute="width" constant="300" id="xde-gy-DHI"/>
|
||||||
|
</constraints>
|
||||||
|
</view>
|
||||||
|
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fnl-LF-rEL" userLabel="SubmitBtn">
|
||||||
|
<rect key="frame" x="273" y="360" width="55" height="33"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<state key="normal" title="Submit">
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
</state>
|
</state>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="onButtonPressed:" destination="ZlD-EU-ncw" eventType="touchUpInside" id="ER9-1w-3CL"/>
|
<action selector="onButtonPressed:" destination="ZlD-EU-ncw" eventType="touchUpInside" id="ER9-1w-3CL"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bYl-BD-hfc">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5a8-4J-rqy" userLabel="HomeServerView">
|
||||||
<rect key="frame" x="248" y="345" width="105" height="30"/>
|
<rect key="frame" x="124" y="408" width="352" height="30"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Home Server:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="TW9-CJ-pH0">
|
||||||
|
<rect key="frame" x="0.0" y="6" width="96" height="18"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" constant="96" id="TVu-Hn-mwn"/>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="URL (e.g. https://matrix.org)" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="iBz-4w-0cv">
|
||||||
|
<rect key="frame" x="102" y="0.0" width="250" height="30"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" priority="750" constant="250" id="3Jy-CR-r4b"/>
|
||||||
|
<constraint firstAttribute="height" constant="30" id="waN-MT-6d2"/>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="done"/>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="ZlD-EU-ncw" id="fJ9-39-2ag"/>
|
||||||
|
</connections>
|
||||||
|
</textField>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="iBz-4w-0cv" firstAttribute="leading" secondItem="TW9-CJ-pH0" secondAttribute="trailing" constant="6" id="41G-OL-N3Z"/>
|
||||||
|
<constraint firstItem="TW9-CJ-pH0" firstAttribute="top" secondItem="5a8-4J-rqy" secondAttribute="top" constant="6" id="IzW-2x-BS6"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="iBz-4w-0cv" secondAttribute="bottom" id="TXJ-ht-9MJ"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="TW9-CJ-pH0" secondAttribute="bottom" constant="6" id="YTz-Xx-gKA"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="iBz-4w-0cv" secondAttribute="trailing" id="YUC-u1-UJC"/>
|
||||||
|
<constraint firstItem="iBz-4w-0cv" firstAttribute="top" secondItem="5a8-4J-rqy" secondAttribute="top" id="jpl-f7-eHN"/>
|
||||||
|
<constraint firstItem="TW9-CJ-pH0" firstAttribute="leading" secondItem="5a8-4J-rqy" secondAttribute="leading" id="mXd-CX-Ehu"/>
|
||||||
|
</constraints>
|
||||||
|
</view>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Your home server stores all your conservation and account data." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="LKF-ef-JTA" userLabel="HomeServerInfoLabel">
|
||||||
|
<rect key="frame" x="107" y="438" width="387" height="16"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="F4V-zC-19g" userLabel="IdentityServerView">
|
||||||
|
<rect key="frame" x="119" y="462" width="363" height="30"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Identity Server:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="MHk-DJ-BFj">
|
||||||
|
<rect key="frame" x="0.0" y="6" width="107" height="18"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" constant="107" id="JcY-aa-68S"/>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="URL (e.g. https://matrix.org)" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="yfy-fB-piy">
|
||||||
|
<rect key="frame" x="113" y="0.0" width="250" height="30"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="height" constant="30" id="1F5-e4-bJG"/>
|
||||||
|
<constraint firstAttribute="width" priority="750" constant="250" id="l5u-xy-hOo"/>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="done"/>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="ZlD-EU-ncw" id="7a0-Jw-Wg8"/>
|
||||||
|
</connections>
|
||||||
|
</textField>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="MHk-DJ-BFj" secondAttribute="bottom" constant="6" id="FAd-Dl-1I7"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="yfy-fB-piy" secondAttribute="trailing" id="Vcv-Uh-OAO"/>
|
||||||
|
<constraint firstItem="yfy-fB-piy" firstAttribute="top" secondItem="F4V-zC-19g" secondAttribute="top" id="ek8-U6-AJf"/>
|
||||||
|
<constraint firstItem="yfy-fB-piy" firstAttribute="leading" secondItem="MHk-DJ-BFj" secondAttribute="trailing" constant="6" id="qQD-zl-EVh"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="yfy-fB-piy" secondAttribute="bottom" id="sVj-ei-7Yd"/>
|
||||||
|
<constraint firstItem="MHk-DJ-BFj" firstAttribute="leading" secondItem="F4V-zC-19g" secondAttribute="leading" id="tvn-1T-DLz"/>
|
||||||
|
<constraint firstItem="MHk-DJ-BFj" firstAttribute="top" secondItem="F4V-zC-19g" secondAttribute="top" constant="6" id="xHO-pQ-fCR"/>
|
||||||
|
</constraints>
|
||||||
|
</view>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="0ot-Cn-Okj" userLabel="IdentityServerInfoLabel">
|
||||||
|
<rect key="frame" x="8" y="492" width="584" height="16"/>
|
||||||
|
<string key="text">Matrix provides identity servers to track which emails etc. belong to which Matrix IDs. Only https://matrix.org currently exists.</string>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bYl-BD-hfc" userLabel="authSwitchButton">
|
||||||
|
<rect key="frame" x="248" y="520" width="105" height="30"/>
|
||||||
<state key="normal" title="Create account">
|
<state key="normal" title="Create account">
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
</state>
|
</state>
|
||||||
|
@ -1100,45 +1351,46 @@
|
||||||
<action selector="onButtonPressed:" destination="ZlD-EU-ncw" eventType="touchUpInside" id="MWy-Uy-9Nc"/>
|
<action selector="onButtonPressed:" destination="ZlD-EU-ncw" eventType="touchUpInside" id="MWy-Uy-9Nc"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Home Server:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="TW9-CJ-pH0">
|
|
||||||
<rect key="frame" x="142" y="309" width="106" height="21"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="J51-Cj-6mb">
|
|
||||||
<rect key="frame" x="290" y="190" width="20" height="20"/>
|
|
||||||
</activityIndicatorView>
|
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="DkI-2d-TR5" firstAttribute="top" secondItem="9oD-IQ-d8J" secondAttribute="bottom" constant="15" id="00V-X5-82v"/>
|
<constraint firstAttribute="centerX" secondItem="0ot-Cn-Okj" secondAttribute="centerX" id="01i-Qj-xeO"/>
|
||||||
<constraint firstAttribute="height" constant="400" id="42v-uQ-LsL"/>
|
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="5a8-4J-rqy" secondAttribute="trailing" constant="8" id="0M5-HS-blg"/>
|
||||||
<constraint firstItem="TW9-CJ-pH0" firstAttribute="top" secondItem="gDT-bj-MHE" secondAttribute="bottom" constant="54" id="49b-un-Aog"/>
|
<constraint firstAttribute="height" constant="640" id="42v-uQ-LsL"/>
|
||||||
<constraint firstItem="iBz-4w-0cv" firstAttribute="top" secondItem="fnl-LF-rEL" secondAttribute="bottom" constant="10" id="6Vs-3k-pOs"/>
|
<constraint firstAttribute="centerX" secondItem="LKF-ef-JTA" secondAttribute="centerX" id="69A-yA-IEW"/>
|
||||||
<constraint firstItem="bYl-BD-hfc" firstAttribute="top" secondItem="iBz-4w-0cv" secondAttribute="bottom" constant="10" id="Gba-vG-eZb"/>
|
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="F4V-zC-19g" secondAttribute="trailing" constant="8" id="8ab-Z4-kg9"/>
|
||||||
<constraint firstItem="fnl-LF-rEL" firstAttribute="top" secondItem="gDT-bj-MHE" secondAttribute="bottom" constant="10" id="Is5-SQ-bcL"/>
|
<constraint firstItem="5a8-4J-rqy" firstAttribute="top" secondItem="fnl-LF-rEL" secondAttribute="bottom" constant="15" id="BDw-eQ-BRA"/>
|
||||||
|
<constraint firstItem="0ot-Cn-Okj" firstAttribute="top" secondItem="F4V-zC-19g" secondAttribute="bottom" id="INC-BK-58n"/>
|
||||||
<constraint firstAttribute="centerX" secondItem="9oD-IQ-d8J" secondAttribute="centerX" id="JLJ-dk-JdK"/>
|
<constraint firstAttribute="centerX" secondItem="9oD-IQ-d8J" secondAttribute="centerX" id="JLJ-dk-JdK"/>
|
||||||
<constraint firstAttribute="centerY" secondItem="J51-Cj-6mb" secondAttribute="centerY" id="RJl-T1-G3f"/>
|
<constraint firstAttribute="centerX" secondItem="5a8-4J-rqy" secondAttribute="centerX" id="L9E-M9-JZR"/>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="pvw-BQ-kaV" secondAttribute="centerX" multiplier="2.1" id="PQx-8d-2WE"/>
|
||||||
<constraint firstAttribute="centerX" secondItem="fnl-LF-rEL" secondAttribute="centerX" id="Sgz-AH-2EN"/>
|
<constraint firstAttribute="centerX" secondItem="fnl-LF-rEL" secondAttribute="centerX" id="Sgz-AH-2EN"/>
|
||||||
<constraint firstAttribute="centerX" secondItem="TW9-CJ-pH0" secondAttribute="centerX" constant="105" id="V29-yw-qHo"/>
|
<constraint firstItem="5a8-4J-rqy" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="d6h-O8-aBs" secondAttribute="leading" constant="8" id="VRZ-uz-BCX"/>
|
||||||
|
<constraint firstItem="F4V-zC-19g" firstAttribute="top" secondItem="LKF-ef-JTA" secondAttribute="bottom" constant="8" id="YYC-7e-ggI"/>
|
||||||
|
<constraint firstItem="LKF-ef-JTA" firstAttribute="top" secondItem="5a8-4J-rqy" secondAttribute="bottom" id="arP-7h-TB2"/>
|
||||||
<constraint firstAttribute="width" constant="600" placeholder="YES" id="b29-CD-6mb"/>
|
<constraint firstAttribute="width" constant="600" placeholder="YES" id="b29-CD-6mb"/>
|
||||||
<constraint firstAttribute="centerX" secondItem="DkI-2d-TR5" secondAttribute="centerX" id="dS4-GI-IBQ"/>
|
<constraint firstItem="sQb-Oi-ER6" firstAttribute="top" secondItem="pvw-BQ-kaV" secondAttribute="bottom" constant="5" id="dUA-me-Oly"/>
|
||||||
<constraint firstItem="gDT-bj-MHE" firstAttribute="top" secondItem="DkI-2d-TR5" secondAttribute="bottom" constant="10" id="fE4-6M-Yc0"/>
|
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="0ot-Cn-Okj" secondAttribute="trailing" constant="8" id="gz6-Ih-fPV"/>
|
||||||
<constraint firstAttribute="centerY" secondItem="DkI-2d-TR5" secondAttribute="centerY" id="mc2-E4-S5v"/>
|
<constraint firstItem="fnl-LF-rEL" firstAttribute="top" secondItem="sQb-Oi-ER6" secondAttribute="bottom" constant="10" id="icu-FA-ijI"/>
|
||||||
<constraint firstAttribute="centerX" secondItem="gDT-bj-MHE" secondAttribute="centerX" id="oih-er-0Uz"/>
|
<constraint firstItem="0ot-Cn-Okj" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="d6h-O8-aBs" secondAttribute="leading" constant="8" id="lBq-aj-naj"/>
|
||||||
|
<constraint firstItem="bYl-BD-hfc" firstAttribute="top" secondItem="0ot-Cn-Okj" secondAttribute="bottom" constant="12" id="lbG-dp-rtx"/>
|
||||||
|
<constraint firstItem="LKF-ef-JTA" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="d6h-O8-aBs" secondAttribute="leading" constant="8" id="pn0-tX-vwe"/>
|
||||||
|
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="LKF-ef-JTA" secondAttribute="trailing" constant="8" id="prS-UK-oXJ"/>
|
||||||
<constraint firstAttribute="centerX" secondItem="bYl-BD-hfc" secondAttribute="centerX" id="rLh-01-K2X"/>
|
<constraint firstAttribute="centerX" secondItem="bYl-BD-hfc" secondAttribute="centerX" id="rLh-01-K2X"/>
|
||||||
<constraint firstAttribute="centerX" secondItem="iBz-4w-0cv" secondAttribute="centerX" constant="-52" id="umi-df-iLV"/>
|
<constraint firstAttribute="centerX" secondItem="F4V-zC-19g" secondAttribute="centerX" id="wgS-c7-SWD"/>
|
||||||
<constraint firstAttribute="centerX" secondItem="J51-Cj-6mb" secondAttribute="centerX" id="xKM-Lu-0MM"/>
|
<constraint firstItem="sQb-Oi-ER6" firstAttribute="top" secondItem="9oD-IQ-d8J" secondAttribute="bottom" constant="35" id="whU-LM-RDN"/>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="sQb-Oi-ER6" secondAttribute="centerX" id="xGd-ig-cIb"/>
|
||||||
|
<constraint firstItem="sQb-Oi-ER6" firstAttribute="top" secondItem="d6h-O8-aBs" secondAttribute="top" constant="170" id="ynf-Lz-N7e"/>
|
||||||
|
<constraint firstItem="F4V-zC-19g" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="d6h-O8-aBs" secondAttribute="leading" constant="8" id="zTN-SN-HQK"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="d6h-O8-aBs" firstAttribute="leading" secondItem="udG-Mx-F4c" secondAttribute="leading" id="0AZ-PL-Sqy"/>
|
<constraint firstItem="d6h-O8-aBs" firstAttribute="leading" secondItem="udG-Mx-F4c" secondAttribute="leading" id="0AZ-PL-Sqy"/>
|
||||||
<constraint firstAttribute="bottom" secondItem="d6h-O8-aBs" secondAttribute="bottom" constant="180" id="3LQ-0u-kCA"/>
|
|
||||||
<constraint firstItem="d6h-O8-aBs" firstAttribute="top" secondItem="udG-Mx-F4c" secondAttribute="top" id="qxm-bJ-sOv"/>
|
<constraint firstItem="d6h-O8-aBs" firstAttribute="top" secondItem="udG-Mx-F4c" secondAttribute="top" id="qxm-bJ-sOv"/>
|
||||||
<constraint firstAttribute="trailing" secondItem="d6h-O8-aBs" secondAttribute="trailing" id="xYP-vJ-Pau"/>
|
<constraint firstAttribute="trailing" secondItem="d6h-O8-aBs" secondAttribute="trailing" id="xYP-vJ-Pau"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="d6h-O8-aBs" secondAttribute="bottom" id="zJF-4I-K30"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</scrollView>
|
</scrollView>
|
||||||
</subviews>
|
</subviews>
|
||||||
|
@ -1152,14 +1404,22 @@
|
||||||
</view>
|
</view>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="activityIndicator" destination="J51-Cj-6mb" id="hYh-tr-rjl"/>
|
<outlet property="activityIndicator" destination="J51-Cj-6mb" id="hYh-tr-rjl"/>
|
||||||
|
<outlet property="authInputContainerViewHeightConstraint" destination="gDV-QE-CXd" id="w2j-CW-jC6"/>
|
||||||
|
<outlet property="authInputsContainerView" destination="sQb-Oi-ER6" id="16R-BA-8pJ"/>
|
||||||
|
<outlet property="authInputsEmailCodeBasedView" destination="G6Y-YQ-PvU" id="8IM-sx-LeP"/>
|
||||||
|
<outlet property="authInputsPasswordBasedView" destination="O8N-hu-Ewh" id="1ZN-jj-Txd"/>
|
||||||
|
<outlet property="authSwitchButton" destination="bYl-BD-hfc" id="RmX-1U-gbu"/>
|
||||||
<outlet property="contentView" destination="d6h-O8-aBs" id="hId-Ic-rv4"/>
|
<outlet property="contentView" destination="d6h-O8-aBs" id="hId-Ic-rv4"/>
|
||||||
<outlet property="contentViewBottomConstraint" destination="3LQ-0u-kCA" id="LuL-eo-fCe"/>
|
<outlet property="contentViewHeightConstraint" destination="42v-uQ-LsL" id="d3Y-uv-J8T"/>
|
||||||
<outlet property="createAccountBtn" destination="bYl-BD-hfc" id="Kvu-Go-kEM"/>
|
<outlet property="createAccountLabel" destination="pvw-BQ-kaV" id="HvM-wg-gEw"/>
|
||||||
|
<outlet property="homeServerInfoLabel" destination="LKF-ef-JTA" id="0EM-71-189"/>
|
||||||
<outlet property="homeServerTextField" destination="iBz-4w-0cv" id="mPB-je-wz5"/>
|
<outlet property="homeServerTextField" destination="iBz-4w-0cv" id="mPB-je-wz5"/>
|
||||||
<outlet property="loginBtn" destination="fnl-LF-rEL" id="2aj-8W-Q6g"/>
|
<outlet property="identityServerInfoLabel" destination="0ot-Cn-Okj" id="fch-En-eR0"/>
|
||||||
<outlet property="passWordTextField" destination="gDT-bj-MHE" id="pP1-zd-BQn"/>
|
<outlet property="identityServerTextField" destination="yfy-fB-piy" id="gwN-t1-TX9"/>
|
||||||
|
<outlet property="noFlowLabel" destination="eg7-eh-lZv" id="eQi-Nt-5Ik"/>
|
||||||
|
<outlet property="retryButton" destination="70b-I3-Cuk" id="jHb-ZS-hrR"/>
|
||||||
<outlet property="scrollView" destination="udG-Mx-F4c" id="Aot-SZ-PxD"/>
|
<outlet property="scrollView" destination="udG-Mx-F4c" id="Aot-SZ-PxD"/>
|
||||||
<outlet property="userLoginTextField" destination="DkI-2d-TR5" id="2ZH-ps-oDN"/>
|
<outlet property="submitButton" destination="fnl-LF-rEL" id="a9E-g2-2C2"/>
|
||||||
</connections>
|
</connections>
|
||||||
</viewController>
|
</viewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="mvZ-se-pqQ" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="mvZ-se-pqQ" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
|
|
60
matrixConsole/View/AuthInputsView.h
Normal file
60
matrixConsole/View/AuthInputsView.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
Copyright 2014 OpenMarket 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 <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
// Authentication type: register or login
|
||||||
|
typedef enum {
|
||||||
|
AuthenticationTypeRegister,
|
||||||
|
AuthenticationTypeLogin
|
||||||
|
}
|
||||||
|
AuthenticationType;
|
||||||
|
|
||||||
|
@class AuthInputsView;
|
||||||
|
|
||||||
|
@protocol AuthInputsViewDelegate <NSObject>
|
||||||
|
@optional
|
||||||
|
- (void)authInputsDoneKeyHasBeenPressed:(AuthInputsView *)authInputsView;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface AuthInputsView : UIView <UITextFieldDelegate>
|
||||||
|
|
||||||
|
@property (nonatomic) AuthenticationType authType;
|
||||||
|
@property (nonatomic) id <AuthInputsViewDelegate> delegate;
|
||||||
|
// Optional fields added in case of registration
|
||||||
|
@property (weak, nonatomic) IBOutlet UITextField *displayNameTextField;
|
||||||
|
|
||||||
|
- (CGFloat)actualHeight;
|
||||||
|
- (BOOL)areAllRequiredFieldsFilled;
|
||||||
|
- (void)dismissKeyboard;
|
||||||
|
|
||||||
|
- (void)nextStep;
|
||||||
|
- (void)resetStep;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface AuthInputsPasswordBasedView : AuthInputsView
|
||||||
|
@property (weak, nonatomic) IBOutlet UITextField *userLoginTextField;
|
||||||
|
@property (weak, nonatomic) IBOutlet UITextField *passWordTextField;
|
||||||
|
// Optional fields added in case of registration
|
||||||
|
@property (weak, nonatomic) IBOutlet UITextField *emailTextField;
|
||||||
|
@property (weak, nonatomic) IBOutlet UILabel *emailInfoLabel;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface AuthInputsEmailCodeBasedView : AuthInputsView
|
||||||
|
@property (weak, nonatomic) IBOutlet UITextField *userLoginTextField;
|
||||||
|
@property (weak, nonatomic) IBOutlet UITextField *emailAndTokenTextField;
|
||||||
|
@property (weak, nonatomic) IBOutlet UILabel *promptEmailTokenLabel;
|
||||||
|
@end
|
209
matrixConsole/View/AuthInputsView.m
Normal file
209
matrixConsole/View/AuthInputsView.m
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
/*
|
||||||
|
Copyright 2014 OpenMarket 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 "AuthInputsView.h"
|
||||||
|
#import "MatrixSDKHandler.h"
|
||||||
|
|
||||||
|
@implementation AuthInputsView
|
||||||
|
|
||||||
|
- (CGFloat)actualHeight {
|
||||||
|
return self.frame.size.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)areAllRequiredFieldsFilled {
|
||||||
|
// Currently no field to check here
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setAuthType:(AuthenticationType)authType {
|
||||||
|
if (authType == AuthenticationTypeLogin) {
|
||||||
|
self.displayNameTextField.hidden = YES;
|
||||||
|
} else {
|
||||||
|
self.displayNameTextField.hidden = NO;
|
||||||
|
}
|
||||||
|
_authType = authType;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dismissKeyboard {
|
||||||
|
[self.displayNameTextField resignFirstResponder];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)nextStep {
|
||||||
|
self.displayNameTextField.hidden = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)resetStep {
|
||||||
|
self.authType = _authType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark - AuthInputsPasswordBasedView
|
||||||
|
|
||||||
|
@implementation AuthInputsPasswordBasedView
|
||||||
|
|
||||||
|
- (CGFloat)actualHeight {
|
||||||
|
if (self.authType == AuthenticationTypeLogin) {
|
||||||
|
return self.displayNameTextField.frame.origin.y;
|
||||||
|
}
|
||||||
|
return super.actualHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)areAllRequiredFieldsFilled {
|
||||||
|
BOOL ret = [super areAllRequiredFieldsFilled];
|
||||||
|
|
||||||
|
// Check user login and pass fields
|
||||||
|
ret = (ret && self.userLoginTextField.text.length && self.passWordTextField.text.length);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setAuthType:(AuthenticationType)authType {
|
||||||
|
if (authType == AuthenticationTypeLogin) {
|
||||||
|
self.passWordTextField.returnKeyType = UIReturnKeyDone;
|
||||||
|
self.emailTextField.hidden = YES;
|
||||||
|
self.emailInfoLabel.hidden = YES;
|
||||||
|
} else {
|
||||||
|
self.passWordTextField.returnKeyType = UIReturnKeyNext;
|
||||||
|
self.emailTextField.hidden = NO;
|
||||||
|
self.emailInfoLabel.hidden = NO;
|
||||||
|
}
|
||||||
|
super.authType = authType;
|
||||||
|
|
||||||
|
// Prefill text field
|
||||||
|
self.userLoginTextField.text = [[MatrixSDKHandler sharedHandler] userLogin];
|
||||||
|
self.passWordTextField.text = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dismissKeyboard {
|
||||||
|
[self.userLoginTextField resignFirstResponder];
|
||||||
|
[self.passWordTextField resignFirstResponder];
|
||||||
|
[self.emailTextField resignFirstResponder];
|
||||||
|
|
||||||
|
[super dismissKeyboard];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark UITextField delegate
|
||||||
|
|
||||||
|
- (void)textFieldDidEndEditing:(UITextField *)textField {
|
||||||
|
if (textField == self.userLoginTextField) {
|
||||||
|
[[MatrixSDKHandler sharedHandler] setUserLogin:textField.text];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)textFieldShouldReturn:(UITextField*)textField {
|
||||||
|
if (textField.returnKeyType == UIReturnKeyDone) {
|
||||||
|
// "Done" key has been pressed
|
||||||
|
[textField resignFirstResponder];
|
||||||
|
|
||||||
|
if (self.delegate && [self.delegate respondsToSelector:@selector(authInputsDoneKeyHasBeenPressed:)]) {
|
||||||
|
// Launch authentication now
|
||||||
|
[self.delegate authInputsDoneKeyHasBeenPressed:self];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//"Next" key has been pressed
|
||||||
|
if (textField == self.userLoginTextField) {
|
||||||
|
[self.passWordTextField becomeFirstResponder];
|
||||||
|
} else if (textField == self.passWordTextField) {
|
||||||
|
[self.displayNameTextField becomeFirstResponder];
|
||||||
|
} else if (textField == self.displayNameTextField) {
|
||||||
|
[self.emailTextField becomeFirstResponder];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark - AuthInputsEmailCodeBasedView
|
||||||
|
|
||||||
|
@implementation AuthInputsEmailCodeBasedView
|
||||||
|
|
||||||
|
- (CGFloat)actualHeight {
|
||||||
|
if (self.authType == AuthenticationTypeLogin) {
|
||||||
|
return self.displayNameTextField.frame.origin.y;
|
||||||
|
}
|
||||||
|
return super.actualHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)areAllRequiredFieldsFilled {
|
||||||
|
BOOL ret = [super areAllRequiredFieldsFilled];
|
||||||
|
|
||||||
|
// Check required fields //FIXME what are required fields in this authentication flow?
|
||||||
|
ret = (ret && self.userLoginTextField.text.length && self.emailAndTokenTextField.text.length);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setAuthType:(AuthenticationType)authType {
|
||||||
|
// Set initial layout
|
||||||
|
self.userLoginTextField.hidden = NO;
|
||||||
|
self.promptEmailTokenLabel.hidden = YES;
|
||||||
|
|
||||||
|
if (authType == AuthenticationTypeLogin) {
|
||||||
|
self.emailAndTokenTextField.returnKeyType = UIReturnKeyDone;
|
||||||
|
} else {
|
||||||
|
self.emailAndTokenTextField.returnKeyType = UIReturnKeyNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.authType = authType;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dismissKeyboard {
|
||||||
|
[self.userLoginTextField resignFirstResponder];
|
||||||
|
[self.emailAndTokenTextField resignFirstResponder];
|
||||||
|
|
||||||
|
[super dismissKeyboard];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)nextStep {
|
||||||
|
// Consider here the email token has been requested with success
|
||||||
|
[super nextStep];
|
||||||
|
|
||||||
|
self.userLoginTextField.hidden = YES;
|
||||||
|
self.promptEmailTokenLabel.hidden = NO;
|
||||||
|
self.emailAndTokenTextField.returnKeyType = UIReturnKeyDone;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark UITextField delegate
|
||||||
|
|
||||||
|
- (void)textFieldDidEndEditing:(UITextField *)textField {
|
||||||
|
if (textField == self.userLoginTextField) {
|
||||||
|
[[MatrixSDKHandler sharedHandler] setUserLogin:textField.text];
|
||||||
|
}
|
||||||
|
// FIXME store user's email in matrixSDKHandler like userId
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)textFieldShouldReturn:(UITextField*)textField {
|
||||||
|
if (textField.returnKeyType == UIReturnKeyDone) {
|
||||||
|
// "Done" key has been pressed
|
||||||
|
[textField resignFirstResponder];
|
||||||
|
|
||||||
|
if (self.delegate && [self.delegate respondsToSelector:@selector(authInputsDoneKeyHasBeenPressed:)]) {
|
||||||
|
// Launch authentication now
|
||||||
|
[self.delegate authInputsDoneKeyHasBeenPressed:self];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//"Next" key has been pressed
|
||||||
|
if (textField == self.userLoginTextField) {
|
||||||
|
[self.emailAndTokenTextField becomeFirstResponder];
|
||||||
|
} else if (textField == self.emailAndTokenTextField) {
|
||||||
|
[self.displayNameTextField becomeFirstResponder];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -16,7 +16,9 @@
|
||||||
|
|
||||||
#import "RageShakableViewController.h"
|
#import "RageShakableViewController.h"
|
||||||
|
|
||||||
@interface AuthenticationViewController : RageShakableViewController <UITextFieldDelegate>
|
#import "AuthInputsView.h"
|
||||||
|
|
||||||
|
@interface AuthenticationViewController : RageShakableViewController <UITextFieldDelegate, AuthInputsViewDelegate>
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -20,24 +20,51 @@
|
||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
#import "MXCAlert.h"
|
#import "MXCAlert.h"
|
||||||
|
|
||||||
@interface AuthenticationViewController ()
|
#import "AFNetworkReachabilityManager.h"
|
||||||
{
|
|
||||||
|
@interface AuthenticationViewController () {
|
||||||
|
// Current request in progress
|
||||||
|
NSOperation *mxAuthFlowRequest;
|
||||||
|
|
||||||
|
// Array of flows supported by the home server and implemented by the app (for the current auth type)
|
||||||
|
NSMutableArray *supportedFlows;
|
||||||
|
|
||||||
|
// The current view in which auth inputs are displayed
|
||||||
|
AuthInputsView *currentAuthInputsView;
|
||||||
|
|
||||||
// reference to any opened alert view
|
// reference to any opened alert view
|
||||||
MXCAlert *alert;
|
MXCAlert *alert;
|
||||||
}
|
}
|
||||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *contentViewBottomConstraint;
|
|
||||||
|
// Return true if the provided flow (kMXLoginFlowType) is supported by the application
|
||||||
|
+ (BOOL)isImplementedFlowType:(NSString*)flowType;
|
||||||
|
|
||||||
|
// The current authentication type
|
||||||
|
@property (nonatomic) AuthenticationType authType;
|
||||||
|
@property (nonatomic) MXLoginFlow *selectedFlow;
|
||||||
|
|
||||||
@property (strong, nonatomic) IBOutlet UIScrollView *scrollView;
|
@property (strong, nonatomic) IBOutlet UIScrollView *scrollView;
|
||||||
@property (weak, nonatomic) IBOutlet UIView *contentView;
|
@property (weak, nonatomic) IBOutlet UIView *contentView;
|
||||||
|
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *contentViewHeightConstraint;
|
||||||
|
|
||||||
|
@property (weak, nonatomic) IBOutlet UILabel *createAccountLabel;
|
||||||
|
|
||||||
|
@property (weak, nonatomic) IBOutlet UIView *authInputsContainerView;
|
||||||
|
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *authInputContainerViewHeightConstraint;
|
||||||
|
@property (weak, nonatomic) IBOutlet AuthInputsPasswordBasedView *authInputsPasswordBasedView;
|
||||||
|
@property (weak, nonatomic) IBOutlet AuthInputsEmailCodeBasedView *authInputsEmailCodeBasedView;
|
||||||
|
|
||||||
@property (weak, nonatomic) IBOutlet UITextField *homeServerTextField;
|
@property (weak, nonatomic) IBOutlet UITextField *homeServerTextField;
|
||||||
@property (weak, nonatomic) IBOutlet UITextField *userLoginTextField;
|
@property (weak, nonatomic) IBOutlet UILabel *homeServerInfoLabel;
|
||||||
@property (weak, nonatomic) IBOutlet UITextField *passWordTextField;
|
@property (weak, nonatomic) IBOutlet UITextField *identityServerTextField;
|
||||||
|
@property (weak, nonatomic) IBOutlet UILabel *identityServerInfoLabel;
|
||||||
|
|
||||||
@property (weak, nonatomic) IBOutlet UIButton *loginBtn;
|
@property (weak, nonatomic) IBOutlet UIButton *submitButton;
|
||||||
@property (weak, nonatomic) IBOutlet UIButton *createAccountBtn;
|
@property (weak, nonatomic) IBOutlet UIButton *authSwitchButton;
|
||||||
|
|
||||||
@property (strong, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator;
|
@property (strong, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator;
|
||||||
|
@property (weak, nonatomic) IBOutlet UILabel *noFlowLabel;
|
||||||
|
@property (weak, nonatomic) IBOutlet UIButton *retryButton;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -47,9 +74,6 @@
|
||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
// Do any additional setup after loading the view, typically from a nib.
|
// Do any additional setup after loading the view, typically from a nib.
|
||||||
|
|
||||||
// Finalize scrollView content size
|
|
||||||
_contentViewBottomConstraint.constant = 0;
|
|
||||||
|
|
||||||
// Force contentView in full width
|
// Force contentView in full width
|
||||||
NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:self.contentView
|
NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:self.contentView
|
||||||
attribute:NSLayoutAttributeLeading
|
attribute:NSLayoutAttributeLeading
|
||||||
|
@ -68,13 +92,31 @@
|
||||||
multiplier:1.0
|
multiplier:1.0
|
||||||
constant:0];
|
constant:0];
|
||||||
[self.view addConstraint:rightConstraint];
|
[self.view addConstraint:rightConstraint];
|
||||||
|
|
||||||
// Prefill text field
|
_scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
|
||||||
_userLoginTextField.text = [[MatrixSDKHandler sharedHandler] userLogin];
|
|
||||||
|
_submitButton.enabled = NO;
|
||||||
|
_authSwitchButton.enabled = YES;
|
||||||
|
_authInputsPasswordBasedView.delegate = self;
|
||||||
|
_authInputsEmailCodeBasedView.delegate = self;
|
||||||
|
|
||||||
|
supportedFlows = [NSMutableArray array];
|
||||||
|
|
||||||
_homeServerTextField.text = [[MatrixSDKHandler sharedHandler] homeServerURL];
|
_homeServerTextField.text = [[MatrixSDKHandler sharedHandler] homeServerURL];
|
||||||
_passWordTextField.text = nil;
|
_identityServerTextField.text = [[MatrixSDKHandler sharedHandler] identityServerURL];
|
||||||
_loginBtn.enabled = NO;
|
|
||||||
_loginBtn.alpha = 0.5;
|
// Set default auth type
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
self.authType = AuthenticationTypeLogin;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
supportedFlows = nil;
|
||||||
|
if (mxAuthFlowRequest){
|
||||||
|
[mxAuthFlowRequest cancel];
|
||||||
|
mxAuthFlowRequest = nil;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)didReceiveMemoryWarning {
|
- (void)didReceiveMemoryWarning {
|
||||||
|
@ -85,6 +127,9 @@
|
||||||
- (void)viewWillAppear:(BOOL)animated {
|
- (void)viewWillAppear:(BOOL)animated {
|
||||||
[super viewWillAppear:animated];
|
[super viewWillAppear:animated];
|
||||||
|
|
||||||
|
// Update supported authentication flow
|
||||||
|
[self refreshSupportedAuthFlow];
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onKeyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onKeyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onKeyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onKeyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
|
||||||
|
|
||||||
|
@ -94,18 +139,311 @@
|
||||||
|
|
||||||
- (void)viewWillDisappear:(BOOL)animated {
|
- (void)viewWillDisappear:(BOOL)animated {
|
||||||
[super viewWillDisappear:animated];
|
[super viewWillDisappear:animated];
|
||||||
|
|
||||||
|
[self dismissKeyboard];
|
||||||
|
|
||||||
// close any opened alert
|
// close any opened alert
|
||||||
if (alert) {
|
if (alert) {
|
||||||
[alert dismiss:NO];
|
[alert dismiss:NO];
|
||||||
alert = nil;
|
alert = nil;
|
||||||
}
|
}
|
||||||
|
[[NSNotificationCenter defaultCenter] removeObserver:self name:AFNetworkingReachabilityDidChangeNotification object:nil];
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
|
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
|
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
|
[[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
|
||||||
|
+ (BOOL)isImplementedFlowType:(NSString*)flowType {
|
||||||
|
if ([flowType isEqualToString:kMXLoginFlowTypePassword] || [flowType isEqualToString:kMXLoginFlowTypeEmailCode]) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setAuthType:(AuthenticationType)authType {
|
||||||
|
if (authType == AuthenticationTypeLogin) {
|
||||||
|
_createAccountLabel.hidden = YES;
|
||||||
|
[_submitButton setTitle:@"Login" forState:UIControlStateNormal];
|
||||||
|
[_submitButton setTitle:@"Login" forState:UIControlStateHighlighted];
|
||||||
|
[_authSwitchButton setTitle:@"Create account" forState:UIControlStateNormal];
|
||||||
|
[_authSwitchButton setTitle:@"Create account" forState:UIControlStateHighlighted];
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_createAccountLabel.hidden = NO;
|
||||||
|
[_submitButton setTitle:@"Sign up" forState:UIControlStateNormal];
|
||||||
|
[_submitButton setTitle:@"Sign up" forState:UIControlStateHighlighted];
|
||||||
|
[_authSwitchButton setTitle:@"Back" forState:UIControlStateNormal];
|
||||||
|
[_authSwitchButton setTitle:@"Back" forState:UIControlStateHighlighted];
|
||||||
|
}
|
||||||
|
|
||||||
|
_authType = authType;
|
||||||
|
|
||||||
|
// Update supported authentication flow
|
||||||
|
[self refreshSupportedAuthFlow];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setSelectedFlow:(MXLoginFlow *)selectedFlow {
|
||||||
|
// Hide views which depend on auth flow
|
||||||
|
_submitButton.hidden = YES;
|
||||||
|
_authInputsPasswordBasedView.hidden = YES;
|
||||||
|
_authInputsEmailCodeBasedView.hidden = YES;
|
||||||
|
_noFlowLabel.hidden = YES;
|
||||||
|
_retryButton.hidden = YES;
|
||||||
|
currentAuthInputsView = nil;
|
||||||
|
|
||||||
|
// Select the right auth inputs view
|
||||||
|
if ([selectedFlow.type isEqualToString:kMXLoginFlowTypePassword]) {
|
||||||
|
currentAuthInputsView = _authInputsPasswordBasedView;
|
||||||
|
} else if ([selectedFlow.type isEqualToString:kMXLoginFlowTypeEmailCode]) {
|
||||||
|
currentAuthInputsView = _authInputsEmailCodeBasedView;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentAuthInputsView) {
|
||||||
|
_submitButton.hidden = NO;
|
||||||
|
currentAuthInputsView.hidden = NO;
|
||||||
|
currentAuthInputsView.authType = _authType;
|
||||||
|
_authInputContainerViewHeightConstraint.constant = currentAuthInputsView.actualHeight;
|
||||||
|
} else {
|
||||||
|
// No input fields are displayed
|
||||||
|
_authInputContainerViewHeightConstraint.constant = 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
[self.view layoutIfNeeded];
|
||||||
|
|
||||||
|
// Refresh content view height
|
||||||
|
_contentViewHeightConstraint.constant = _authSwitchButton.frame.origin.y + _authSwitchButton.frame.size.height + 15;
|
||||||
|
|
||||||
|
_selectedFlow = selectedFlow;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setUserInteractionEnabled:(BOOL)isEnabled {
|
||||||
|
_submitButton.enabled = (isEnabled && currentAuthInputsView.areAllRequiredFieldsFilled && _homeServerTextField.text.length);
|
||||||
|
_authSwitchButton.enabled = isEnabled;
|
||||||
|
|
||||||
|
_homeServerTextField.enabled = isEnabled;
|
||||||
|
_identityServerTextField.enabled = isEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)refreshSupportedAuthFlow {
|
||||||
|
MatrixSDKHandler *mxHandler = [MatrixSDKHandler sharedHandler];
|
||||||
|
|
||||||
|
// Stop reachability monitoring
|
||||||
|
[[AFNetworkReachabilityManager sharedManager] stopMonitoring];
|
||||||
|
[[NSNotificationCenter defaultCenter] removeObserver:self name:AFNetworkingReachabilityDidChangeNotification object:nil];
|
||||||
|
|
||||||
|
// Cancel protential request in progress
|
||||||
|
[mxAuthFlowRequest cancel];
|
||||||
|
mxAuthFlowRequest = nil;
|
||||||
|
|
||||||
|
[_activityIndicator startAnimating];
|
||||||
|
self.selectedFlow = nil;
|
||||||
|
if (_authType == AuthenticationTypeLogin) {
|
||||||
|
mxAuthFlowRequest = [mxHandler.mxRestClient getLoginFlow:^(NSArray *flows) {
|
||||||
|
[self handleHomeServerFlows:flows];
|
||||||
|
} failure:^(NSError *error) {
|
||||||
|
[self onFailureDuringFlowRefresh:error];
|
||||||
|
}];
|
||||||
|
} else {
|
||||||
|
mxAuthFlowRequest = [mxHandler.mxRestClient getRegisterFlow:^(NSArray *flows) {
|
||||||
|
[self handleHomeServerFlows:flows];
|
||||||
|
} failure:^(NSError *error) {
|
||||||
|
[self onFailureDuringFlowRefresh:error];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)handleHomeServerFlows:(NSArray *)flows {
|
||||||
|
[_activityIndicator stopAnimating];
|
||||||
|
|
||||||
|
[supportedFlows removeAllObjects];
|
||||||
|
for (MXLoginFlow* flow in flows) {
|
||||||
|
if ([AuthenticationViewController isImplementedFlowType:flow.type]) {
|
||||||
|
[supportedFlows addObject:flow];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (supportedFlows.count) {
|
||||||
|
// FIXME display supported flows
|
||||||
|
// Currently we select password based auth
|
||||||
|
for (MXLoginFlow* flow in supportedFlows) {
|
||||||
|
if ([flow.type isEqualToString:kMXLoginFlowTypePassword]) {
|
||||||
|
self.selectedFlow = flow;
|
||||||
|
break;
|
||||||
|
} else if ([flow.type isEqualToString:kMXLoginFlowTypeEmailCode]) {
|
||||||
|
self.selectedFlow = flow;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_selectedFlow) {
|
||||||
|
// Notify user that no flow is supported
|
||||||
|
_noFlowLabel.text = [NSString stringWithFormat:@"Currently we do not support %@ flows defined by this Home Server", _authType == AuthenticationTypeLogin ? @"Login" : @"Registration"];
|
||||||
|
_noFlowLabel.hidden = NO;
|
||||||
|
_retryButton.hidden = NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)onFailureDuringFlowRefresh:(NSError*)error {
|
||||||
|
[_activityIndicator stopAnimating];
|
||||||
|
|
||||||
|
if ([error.domain isEqualToString:NSURLErrorDomain] && error.code == kCFURLErrorCancelled) {
|
||||||
|
// Ignore this error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSLog(@"GET auth flows failed: %@", error);
|
||||||
|
// Alert user
|
||||||
|
NSString *title = [error.userInfo valueForKey:NSLocalizedFailureReasonErrorKey];
|
||||||
|
if (!title)
|
||||||
|
{
|
||||||
|
title = @"Error";
|
||||||
|
}
|
||||||
|
NSString *msg = [error.userInfo valueForKey:NSLocalizedDescriptionKey];
|
||||||
|
|
||||||
|
alert = [[MXCAlert alloc] initWithTitle:title message:msg style:MXCAlertStyleAlert];
|
||||||
|
alert.cancelButtonIndex = [alert addActionWithTitle:@"Dismiss" style:MXCAlertActionStyleDefault handler:^(MXCAlert *alert) {}];
|
||||||
|
[alert showInViewController:self];
|
||||||
|
|
||||||
|
// Display failure reason
|
||||||
|
_noFlowLabel.hidden = NO;
|
||||||
|
_noFlowLabel.text = [error.userInfo valueForKey:NSLocalizedDescriptionKey];
|
||||||
|
if (!_noFlowLabel.text.length) {
|
||||||
|
_noFlowLabel.text = @"We failed to retrieve authentication flow from this Home Server";
|
||||||
|
}
|
||||||
|
_retryButton.hidden = NO;
|
||||||
|
|
||||||
|
// Handle specific error code here
|
||||||
|
if ([error.domain isEqualToString:NSURLErrorDomain]) {
|
||||||
|
// Check network reachability
|
||||||
|
if (error.code == NSURLErrorNotConnectedToInternet) {
|
||||||
|
// Start monitoring in order to launch a new request when network will be available
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onReachabilityStatusChange:) name:AFNetworkingReachabilityDidChangeNotification object:nil];
|
||||||
|
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
|
||||||
|
} else if (error.code == kCFURLErrorTimedOut) {
|
||||||
|
// Send a new request in 2 sec
|
||||||
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||||
|
[self refreshSupportedAuthFlow];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)onReachabilityStatusChange:(NSNotification *)notif {
|
||||||
|
AFNetworkReachabilityManager *reachabilityManager = [AFNetworkReachabilityManager sharedManager];
|
||||||
|
AFNetworkReachabilityStatus status = reachabilityManager.networkReachabilityStatus;
|
||||||
|
|
||||||
|
if (status == AFNetworkReachabilityStatusReachableViaWiFi || status == AFNetworkReachabilityStatusReachableViaWWAN) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[self refreshSupportedAuthFlow];
|
||||||
|
});
|
||||||
|
} else if (status == AFNetworkReachabilityStatusNotReachable) {
|
||||||
|
_noFlowLabel.text = @"Please check your network connectivity";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)onButtonPressed:(id)sender {
|
||||||
|
[self dismissKeyboard];
|
||||||
|
|
||||||
|
if (sender == _submitButton) {
|
||||||
|
MatrixSDKHandler *matrix = [MatrixSDKHandler sharedHandler];
|
||||||
|
if (matrix.mxRestClient) {
|
||||||
|
// Disable user interaction to prevent multiple requests
|
||||||
|
[self setUserInteractionEnabled:NO];
|
||||||
|
[_activityIndicator startAnimating];
|
||||||
|
|
||||||
|
if (_authType == AuthenticationTypeLogin) {
|
||||||
|
if ([_selectedFlow.type isEqualToString:kMXLoginFlowTypePassword]) {
|
||||||
|
[matrix.mxRestClient loginWithUser:matrix.userLogin andPassword:_authInputsPasswordBasedView.passWordTextField.text
|
||||||
|
success:^(MXCredentials *credentials){
|
||||||
|
[_activityIndicator stopAnimating];
|
||||||
|
|
||||||
|
// Report credentials
|
||||||
|
[matrix setUserId:credentials.userId];
|
||||||
|
[matrix setAccessToken:credentials.accessToken];
|
||||||
|
// Extract homeServer name from userId
|
||||||
|
NSArray *components = [credentials.userId componentsSeparatedByString:@":"];
|
||||||
|
if (components.count == 2) {
|
||||||
|
[matrix setHomeServer:[components lastObject]];
|
||||||
|
} else {
|
||||||
|
NSLog(@"Unexpected error: the userId is not correctly formatted: %@", credentials.userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
[self dismissViewControllerAnimated:YES completion:nil];
|
||||||
|
}
|
||||||
|
failure:^(NSError *error){
|
||||||
|
[self onFailureDuringAuthRequest:error];
|
||||||
|
}];
|
||||||
|
} else {
|
||||||
|
// FIXME
|
||||||
|
[self onFailureDuringAuthRequest:[NSError errorWithDomain:nil code:0 userInfo:@{@"error": @"Not supported yet"}]];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// FIXME
|
||||||
|
[self onFailureDuringAuthRequest:[NSError errorWithDomain:nil code:0 userInfo:@{@"error": @"Not supported yet"}]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (sender == _authSwitchButton){
|
||||||
|
if (_authType == AuthenticationTypeLogin) {
|
||||||
|
self.authType = AuthenticationTypeRegister;
|
||||||
|
} else {
|
||||||
|
self.authType = AuthenticationTypeLogin;
|
||||||
|
}
|
||||||
|
} else if (sender == _retryButton) {
|
||||||
|
[self refreshSupportedAuthFlow];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)onFailureDuringAuthRequest:(NSError *)error {
|
||||||
|
[_activityIndicator stopAnimating];
|
||||||
|
[self setUserInteractionEnabled:YES];
|
||||||
|
|
||||||
|
NSLog(@"Auth request failed: %@", error);
|
||||||
|
|
||||||
|
// translate the error code to a human message
|
||||||
|
NSString* message = error.localizedDescription;
|
||||||
|
NSDictionary* dict = error.userInfo;
|
||||||
|
|
||||||
|
// detect if it is a Matrix SDK issue
|
||||||
|
if (dict) {
|
||||||
|
NSString* localizedError = [dict valueForKey:@"error"];
|
||||||
|
NSString* errCode = [dict valueForKey:@"errcode"];
|
||||||
|
|
||||||
|
if (errCode) {
|
||||||
|
if ([errCode isEqualToString:@"M_FORBIDDEN"]) {
|
||||||
|
message = @"Invalid username/password";
|
||||||
|
} else if (localizedError.length > 0) {
|
||||||
|
message = localizedError;
|
||||||
|
} else if ([errCode isEqualToString:@"M_UNKNOWN_TOKEN"]) {
|
||||||
|
message = @"The access token specified was not recognised";
|
||||||
|
} else if ([errCode isEqualToString:@"M_BAD_JSON"]) {
|
||||||
|
message = @"Malformed JSON";
|
||||||
|
} else if ([errCode isEqualToString:@"M_NOT_JSON"]) {
|
||||||
|
message = @"Did not contain valid JSON";
|
||||||
|
} else if ([errCode isEqualToString:@"M_LIMIT_EXCEEDED"]) {
|
||||||
|
message = @"Too many requests have been sent";
|
||||||
|
} else if ([errCode isEqualToString:@"M_USER_IN_USE"]) {
|
||||||
|
message = @"This user name is already used";
|
||||||
|
} else if ([errCode isEqualToString:@"M_LOGIN_EMAIL_URL_NOT_YET"]) {
|
||||||
|
message = @"The email link which has not been clicked yet";
|
||||||
|
} else {
|
||||||
|
message = errCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Alert user
|
||||||
|
alert = [[MXCAlert alloc] initWithTitle:@"Login Failed" message:message style:MXCAlertStyleAlert];
|
||||||
|
[alert addActionWithTitle:@"Dismiss" style:MXCAlertActionStyleCancel handler:^(MXCAlert *alert) {}];
|
||||||
|
[alert showInViewController:self];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Keyboard handling
|
||||||
|
|
||||||
- (void)onKeyboardWillShow:(NSNotification *)notif {
|
- (void)onKeyboardWillShow:(NSNotification *)notif {
|
||||||
NSValue *rectVal = notif.userInfo[UIKeyboardFrameEndUserInfoKey];
|
NSValue *rectVal = notif.userInfo[UIKeyboardFrameEndUserInfoKey];
|
||||||
CGRect endRect = rectVal.CGRectValue;
|
CGRect endRect = rectVal.CGRectValue;
|
||||||
|
@ -114,13 +452,6 @@
|
||||||
// Handle portrait/landscape mode
|
// Handle portrait/landscape mode
|
||||||
insets.bottom = (endRect.origin.y == 0) ? endRect.size.width : endRect.size.height;
|
insets.bottom = (endRect.origin.y == 0) ? endRect.size.width : endRect.size.height;
|
||||||
self.scrollView.contentInset = insets;
|
self.scrollView.contentInset = insets;
|
||||||
|
|
||||||
for (UITextField *tf in @[ self.userLoginTextField, self.passWordTextField, self.homeServerTextField]) {
|
|
||||||
if ([tf isFirstResponder]) {
|
|
||||||
CGRect tfFrame = tf.frame;
|
|
||||||
[self.scrollView scrollRectToVisible:tfFrame animated:YES];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)onKeyboardWillHide:(NSNotification *)notif {
|
- (void)onKeyboardWillHide:(NSNotification *)notif {
|
||||||
|
@ -131,137 +462,59 @@
|
||||||
|
|
||||||
- (void)dismissKeyboard {
|
- (void)dismissKeyboard {
|
||||||
// Hide the keyboard
|
// Hide the keyboard
|
||||||
[_userLoginTextField resignFirstResponder];
|
[currentAuthInputsView dismissKeyboard];
|
||||||
[_passWordTextField resignFirstResponder];
|
|
||||||
[_homeServerTextField resignFirstResponder];
|
[_homeServerTextField resignFirstResponder];
|
||||||
|
[_identityServerTextField resignFirstResponder];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - UITextField delegate
|
#pragma mark - UITextField delegate
|
||||||
|
|
||||||
- (void)onTextFieldChange:(NSNotification *)notif {
|
- (void)onTextFieldChange:(NSNotification *)notif {
|
||||||
NSString *user = _userLoginTextField.text;
|
|
||||||
NSString *pass = _passWordTextField.text;
|
|
||||||
NSString *homeServerURL = _homeServerTextField.text;
|
NSString *homeServerURL = _homeServerTextField.text;
|
||||||
|
|
||||||
if (user.length && pass.length && homeServerURL.length) {
|
if (currentAuthInputsView.areAllRequiredFieldsFilled && homeServerURL.length) {
|
||||||
_loginBtn.enabled = YES;
|
_submitButton.enabled = YES;
|
||||||
_loginBtn.alpha = 1;
|
|
||||||
} else {
|
} else {
|
||||||
_loginBtn.enabled = NO;
|
_submitButton.enabled = NO;
|
||||||
_loginBtn.alpha = 0.5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)textFieldDidEndEditing:(UITextField *)textField {
|
- (void)textFieldDidEndEditing:(UITextField *)textField {
|
||||||
MatrixSDKHandler *matrix = [MatrixSDKHandler sharedHandler];
|
MatrixSDKHandler *mxHandler = [MatrixSDKHandler sharedHandler];
|
||||||
|
if (textField == _homeServerTextField) {
|
||||||
if (textField == _userLoginTextField) {
|
if (![[mxHandler homeServerURL] isEqualToString:textField.text]) {
|
||||||
[matrix setUserLogin:textField.text];
|
[mxHandler setHomeServerURL:textField.text];
|
||||||
|
if (!textField.text.length) {
|
||||||
|
// Force refresh with default value
|
||||||
|
textField.text = [mxHandler homeServerURL];
|
||||||
|
}
|
||||||
|
// Refresh UI
|
||||||
|
[self refreshSupportedAuthFlow];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (textField == _homeServerTextField) {
|
else if (textField == _identityServerTextField) {
|
||||||
[matrix setHomeServerURL:textField.text];
|
[mxHandler setIdentityServerURL:textField.text];
|
||||||
if (!textField.text.length) {
|
if (!textField.text.length) {
|
||||||
// Force refresh with default value
|
// Force refresh with default value
|
||||||
textField.text = [[MatrixSDKHandler sharedHandler] homeServerURL];
|
textField.text = [mxHandler identityServerURL];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)textFieldShouldReturn:(UITextField*) textField {
|
- (BOOL)textFieldShouldReturn:(UITextField*)textField {
|
||||||
if (textField == _userLoginTextField) {
|
if (textField.returnKeyType == UIReturnKeyDone) {
|
||||||
// "Next" key has been pressed
|
|
||||||
[_passWordTextField becomeFirstResponder];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// "Done" key has been pressed
|
// "Done" key has been pressed
|
||||||
[textField resignFirstResponder];
|
[textField resignFirstResponder];
|
||||||
|
|
||||||
if (_loginBtn.isEnabled) {
|
|
||||||
// Launch authentication now
|
|
||||||
[self onButtonPressed:_loginBtn];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark - AuthInputsViewDelegate delegate
|
||||||
|
|
||||||
- (IBAction)onButtonPressed:(id)sender {
|
- (void)authInputsDoneKeyHasBeenPressed:(AuthInputsView *)authInputsView {
|
||||||
[self dismissKeyboard];
|
if (_submitButton.isEnabled) {
|
||||||
|
// Launch authentication now
|
||||||
if (sender == _loginBtn) {
|
[self onButtonPressed:_submitButton];
|
||||||
MatrixSDKHandler *matrix = [MatrixSDKHandler sharedHandler];
|
|
||||||
|
|
||||||
if (matrix.mxRestClient)
|
|
||||||
{
|
|
||||||
// Disable login button to prevent multiple requests
|
|
||||||
_loginBtn.enabled = NO;
|
|
||||||
[_activityIndicator startAnimating];
|
|
||||||
|
|
||||||
[matrix.mxRestClient loginWithUser:matrix.userLogin andPassword:_passWordTextField.text
|
|
||||||
success:^(MXCredentials *credentials){
|
|
||||||
[_activityIndicator stopAnimating];
|
|
||||||
|
|
||||||
// Report credentials
|
|
||||||
[matrix setUserId:credentials.userId];
|
|
||||||
[matrix setAccessToken:credentials.accessToken];
|
|
||||||
// Extract homeServer name from userId
|
|
||||||
NSArray *components = [credentials.userId componentsSeparatedByString:@":"];
|
|
||||||
if (components.count == 2) {
|
|
||||||
[matrix setHomeServer:[components lastObject]];
|
|
||||||
} else {
|
|
||||||
NSLog(@"Unexpected error: the userId is not correctly formatted: %@", credentials.userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
[self dismissViewControllerAnimated:YES completion:nil];
|
|
||||||
}
|
|
||||||
failure:^(NSError *error){
|
|
||||||
[_activityIndicator stopAnimating];
|
|
||||||
_loginBtn.enabled = YES;
|
|
||||||
|
|
||||||
NSLog(@"Login failed: %@", error);
|
|
||||||
|
|
||||||
// translate the error code to a human message
|
|
||||||
NSString* message = error.localizedDescription;
|
|
||||||
NSDictionary* dict = error.userInfo;
|
|
||||||
|
|
||||||
// detect if it is a Matrix SDK issue
|
|
||||||
if (dict) {
|
|
||||||
NSString* localizedError = [dict valueForKey:@"error"];
|
|
||||||
NSString* errCode = [dict valueForKey:@"errcode"];
|
|
||||||
|
|
||||||
if (errCode) {
|
|
||||||
if ([errCode isEqualToString:@"M_FORBIDDEN"]) {
|
|
||||||
message = @"Invalid username/password";
|
|
||||||
} else if (localizedError .length > 0) {
|
|
||||||
message = localizedError;
|
|
||||||
} else if ([errCode isEqualToString:@"M_UNKNOWN_TOKEN"]) {
|
|
||||||
message = @"The access token specified was not recognised";
|
|
||||||
} else if ([errCode isEqualToString:@"M_BAD_JSON"]) {
|
|
||||||
message = @"Malformed JSON";
|
|
||||||
} else if ([errCode isEqualToString:@"M_NOT_JSON"]) {
|
|
||||||
message = @"Did not contain valid JSON";
|
|
||||||
} else if ([errCode isEqualToString:@"M_LIMIT_EXCEEDED"]) {
|
|
||||||
message = @"Too many requests have been sent";
|
|
||||||
} else if ([errCode isEqualToString:@"M_USER_IN_USE"]) {
|
|
||||||
message = @"This user name is already used";
|
|
||||||
} else if ([errCode isEqualToString:@"M_LOGIN_EMAIL_URL_NOT_YET"]) {
|
|
||||||
message = @"The email link which has not been clicked yet";
|
|
||||||
} else {
|
|
||||||
message = errCode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Alert user
|
|
||||||
alert = [[MXCAlert alloc] initWithTitle:@"Login Failed" message:message style:MXCAlertStyleAlert];
|
|
||||||
[alert addActionWithTitle:@"Dismiss" style:MXCAlertActionStyleCancel handler:^(MXCAlert *alert) {}];
|
|
||||||
[alert showInViewController:self];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
} else if (sender == _createAccountBtn){
|
|
||||||
// TODO
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>identityserverurl</key>
|
||||||
|
<string>https://matrix.org</string>
|
||||||
<key>homeserverurl</key>
|
<key>homeserverurl</key>
|
||||||
<string>http://matrix.org</string>
|
<string>https://matrix.org</string>
|
||||||
<key>homeserver</key>
|
<key>homeserver</key>
|
||||||
<string>matrix.org</string>
|
<string>matrix.org</string>
|
||||||
<key>apnsIsActive</key>
|
<key>apnsIsActive</key>
|
||||||
|
|
Loading…
Reference in a new issue