project: conform to a swifty way of coding
This commit:
- adapts code to a more Swifty way of coding
- uses previously added frameworks to make the code "type safer"
Change-Id: I5332e2843e82cac4f4f9af79714993863ef5963d
diff --git a/Ring/.swiftlint.yml b/Ring/.swiftlint.yml
index 07e9a65..fab1ed2 100644
--- a/Ring/.swiftlint.yml
+++ b/Ring/.swiftlint.yml
@@ -1,4 +1,5 @@
disabled_rules: # rule identifiers to exclude from running
+ - todo
opt_in_rules: # some rules are only opt-in
- empty_count
diff --git a/Ring/Ring.xcodeproj/project.pbxproj b/Ring/Ring.xcodeproj/project.pbxproj
index 48fd347..21d3015 100644
--- a/Ring/Ring.xcodeproj/project.pbxproj
+++ b/Ring/Ring.xcodeproj/project.pbxproj
@@ -18,7 +18,7 @@
0273C2FF1E0C438F00CF00BA /* AccountAdapterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0273C2FE1E0C438F00CF00BA /* AccountAdapterDelegate.swift */; };
0273C3051E0C68B100CF00BA /* CreateProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0273C3031E0C68B100CF00BA /* CreateProfileViewController.swift */; };
0273C3061E0C68B100CF00BA /* CreateRingAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0273C3041E0C68B100CF00BA /* CreateRingAccountViewController.swift */; };
- 0273C3081E0C68BF00CF00BA /* RoundedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0273C3071E0C68BF00CF00BA /* RoundedButton.swift */; };
+ 0273C3081E0C68BF00CF00BA /* DesignableButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0273C3071E0C68BF00CF00BA /* DesignableButton.swift */; };
029CE9D71E1D8C860000C8E1 /* ServiceEventTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 029CE9D61E1D8C860000C8E1 /* ServiceEventTests.swift */; };
02AED8191DD4C4B100F740BA /* librestbed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 02AED8181DD4C4B100F740BA /* librestbed.a */; };
02B22DFC1DF755BB000358C9 /* AccountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02B22DFA1DF755BB000358C9 /* AccountModel.swift */; };
@@ -30,9 +30,8 @@
02DD80C81E1EAD70009A3510 /* AccountConfigModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02DD80C71E1EAD70009A3510 /* AccountConfigModel.swift */; };
02DD80CA1E1EAF1A009A3510 /* AccountCredentialsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02DD80C91E1EAF1A009A3510 /* AccountCredentialsModel.swift */; };
02DD80CD1E1EB2E4009A3510 /* ConfigKeyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02DD80CC1E1EB2E4009A3510 /* ConfigKeyModel.swift */; };
- 02E1A0251DDE4ABA00D75B59 /* BoolStringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043866371D2304A700E06CE2 /* BoolStringExtension.swift */; };
+ 02E1A0251DDE4ABA00D75B59 /* String+Bool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043866371D2304A700E06CE2 /* String+Bool.swift */; };
043866211D218B1100E06CE2 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 043866201D218B1100E06CE2 /* AudioToolbox.framework */; };
- 043866361D22D06500E06CE2 /* AccountTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043866351D22D06500E06CE2 /* AccountTableViewCell.swift */; };
043999F71D1C2D9D00E99CD9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043999F61D1C2D9D00E99CD9 /* AppDelegate.swift */; };
04399A031D1C2D9D00E99CD9 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 04399A021D1C2D9D00E99CD9 /* Images.xcassets */; };
04399A111D1C2D9D00E99CD9 /* RingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04399A101D1C2D9D00E99CD9 /* RingTests.swift */; };
@@ -94,6 +93,10 @@
04399B151D1C341A00E99CD9 /* libyaml-cpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 04399AE31D1C341A00E99CD9 /* libyaml-cpp.a */; };
1A1E476D1F0E808500EA9A36 /* Reusable.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1E476C1F0E808500EA9A36 /* Reusable.framework */; };
1A1E476F1F0E894600EA9A36 /* SwiftyBeaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1E476E1F0E894600EA9A36 /* SwiftyBeaver.framework */; };
+ 1A3D28A71F0EB9DB00B524EE /* Bool+String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A3D28A61F0EB9DB00B524EE /* Bool+String.swift */; };
+ 1A3D28A91F0EBF0200B524EE /* UIView+Ring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A3D28A81F0EBF0200B524EE /* UIView+Ring.swift */; };
+ 1A8306331F0EDAA50099D98C /* AccountTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A8306321F0EDAA50099D98C /* AccountTableViewCell.swift */; };
+ 1AABA7461F0FE9C000739605 /* UIColor+Ring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AABA7451F0FE9C000739605 /* UIColor+Ring.swift */; };
1ABE07BA1F0C16F100D36361 /* ContactViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ABE07B91F0C16F100D36361 /* ContactViewModel.swift */; };
1ABE07BC1F0C22CC00D36361 /* WalkthroughStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1ABE07BB1F0C22CC00D36361 /* WalkthroughStoryboard.storyboard */; };
1ABE07D21F0D8FE800D36361 /* Images.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ABE07D01F0D8FE800D36361 /* Images.swift */; };
@@ -113,7 +116,6 @@
563AEC771EA664C0003A5641 /* RegistrationResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 563AEC761EA664C0003A5641 /* RegistrationResponse.m */; };
564775831EE5CFC500A0C855 /* Realm.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 564775811EE5CFC500A0C855 /* Realm.framework */; };
564775841EE5CFC500A0C855 /* RealmSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 564775821EE5CFC500A0C855 /* RealmSwift.framework */; };
- 564C44591E8D7F8F000F92B1 /* LocalizedStringTableNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = 564C44581E8D7F8F000F92B1 /* LocalizedStringTableNames.swift */; };
564C445B1E8EA44E000F92B1 /* Durations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 564C445A1E8EA44E000F92B1 /* Durations.swift */; };
564C44601E943C37000F92B1 /* NameRegistrationAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 564C445F1E943C37000F92B1 /* NameRegistrationAdapter.mm */; };
564C44621E943DE6000F92B1 /* NameService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 564C44611E943DE6000F92B1 /* NameService.swift */; };
@@ -128,7 +130,7 @@
56AC64DF1E804ECC00EA1AA9 /* SwitchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AC64DE1E804ECC00EA1AA9 /* SwitchCell.swift */; };
56AC64E11E80542300EA1AA9 /* TextFieldCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AC64E01E80542300EA1AA9 /* TextFieldCell.swift */; };
56AC64E31E805F0200EA1AA9 /* TextCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AC64E21E805F0200EA1AA9 /* TextCell.swift */; };
- 56AC650E1E85694D00EA1AA9 /* RoundedTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AC650D1E85694D00EA1AA9 /* RoundedTextField.swift */; };
+ 56AC650E1E85694D00EA1AA9 /* DesignableTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AC650D1E85694D00EA1AA9 /* DesignableTextField.swift */; };
56BBC99F1ED714CB00CDAF8B /* MessagesAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC99E1ED714CB00CDAF8B /* MessagesAdapter.mm */; };
56BBC9A21ED714DF00CDAF8B /* MessagesAdapterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9A01ED714DF00CDAF8B /* MessagesAdapterDelegate.swift */; };
56BBC9A31ED714DF00CDAF8B /* ConversationsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9A11ED714DF00CDAF8B /* ConversationsService.swift */; };
@@ -150,7 +152,6 @@
56BBC9DF1EDDC9D300CDAF8B /* LookupNameResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9DE1EDDC9D300CDAF8B /* LookupNameResponse.m */; };
56BBC9E01EDDC9E600CDAF8B /* ConversationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9AF1ED7155700CDAF8B /* ConversationViewModel.swift */; };
56BBC9E31EDDCC8100CDAF8B /* ConversationSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9E21EDDCC8100CDAF8B /* ConversationSection.swift */; };
- 56BBC9E71EDE1DDF00CDAF8B /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9E61EDE1DDF00CDAF8B /* Colors.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -187,7 +188,7 @@
0273C3001E0C445200CF00BA /* RingPrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RingPrefixHeader.pch; path = Ring/RingPrefixHeader.pch; sourceTree = "<group>"; };
0273C3031E0C68B100CF00BA /* CreateProfileViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateProfileViewController.swift; sourceTree = "<group>"; };
0273C3041E0C68B100CF00BA /* CreateRingAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateRingAccountViewController.swift; sourceTree = "<group>"; };
- 0273C3071E0C68BF00CF00BA /* RoundedButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoundedButton.swift; sourceTree = "<group>"; };
+ 0273C3071E0C68BF00CF00BA /* DesignableButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DesignableButton.swift; sourceTree = "<group>"; };
028568301DF610A9003A8D8D /* RingTests-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RingTests-Bridging-Header.h"; sourceTree = "<group>"; };
029CE9D61E1D8C860000C8E1 /* ServiceEventTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServiceEventTests.swift; sourceTree = "<group>"; };
02AED8181DD4C4B100F740BA /* librestbed.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = librestbed.a; path = ../DEPS/x86_64/lib/librestbed.a; sourceTree = "<group>"; };
@@ -201,8 +202,7 @@
02DD80C91E1EAF1A009A3510 /* AccountCredentialsModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountCredentialsModel.swift; sourceTree = "<group>"; };
02DD80CC1E1EB2E4009A3510 /* ConfigKeyModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigKeyModel.swift; sourceTree = "<group>"; };
043866201D218B1100E06CE2 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
- 043866351D22D06500E06CE2 /* AccountTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountTableViewCell.swift; sourceTree = "<group>"; };
- 043866371D2304A700E06CE2 /* BoolStringExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoolStringExtension.swift; sourceTree = "<group>"; };
+ 043866371D2304A700E06CE2 /* String+Bool.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Bool.swift"; sourceTree = "<group>"; };
043999F31D1C2D9D00E99CD9 /* Ring.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Ring.app; sourceTree = BUILT_PRODUCTS_DIR; };
043999F61D1C2D9D00E99CD9 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
04399A021D1C2D9D00E99CD9 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
@@ -274,6 +274,10 @@
04399AE31D1C341A00E99CD9 /* libyaml-cpp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libyaml-cpp.a"; path = "../fat/lib/libyaml-cpp.a"; sourceTree = "<group>"; };
1A1E476C1F0E808500EA9A36 /* Reusable.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Reusable.framework; path = Carthage/Build/iOS/Reusable.framework; sourceTree = "<group>"; };
1A1E476E1F0E894600EA9A36 /* SwiftyBeaver.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftyBeaver.framework; path = Carthage/Build/iOS/SwiftyBeaver.framework; sourceTree = "<group>"; };
+ 1A3D28A61F0EB9DB00B524EE /* Bool+String.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Bool+String.swift"; sourceTree = "<group>"; };
+ 1A3D28A81F0EBF0200B524EE /* UIView+Ring.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Ring.swift"; sourceTree = "<group>"; };
+ 1A8306321F0EDAA50099D98C /* AccountTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountTableViewCell.swift; sourceTree = "<group>"; };
+ 1AABA7451F0FE9C000739605 /* UIColor+Ring.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Ring.swift"; sourceTree = "<group>"; };
1ABE07B91F0C16F100D36361 /* ContactViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactViewModel.swift; sourceTree = "<group>"; };
1ABE07BB1F0C22CC00D36361 /* WalkthroughStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = WalkthroughStoryboard.storyboard; sourceTree = "<group>"; };
1ABE07D01F0D8FE800D36361 /* Images.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Images.swift; sourceTree = "<group>"; };
@@ -296,7 +300,6 @@
563AEC761EA664C0003A5641 /* RegistrationResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RegistrationResponse.m; sourceTree = "<group>"; };
564775811EE5CFC500A0C855 /* Realm.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Realm.framework; path = Carthage/Build/iOS/Realm.framework; sourceTree = "<group>"; };
564775821EE5CFC500A0C855 /* RealmSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RealmSwift.framework; path = Carthage/Build/iOS/RealmSwift.framework; sourceTree = "<group>"; };
- 564C44581E8D7F8F000F92B1 /* LocalizedStringTableNames.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocalizedStringTableNames.swift; sourceTree = "<group>"; };
564C445A1E8EA44E000F92B1 /* Durations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Durations.swift; sourceTree = "<group>"; };
564C445E1E943C37000F92B1 /* NameRegistrationAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NameRegistrationAdapter.h; sourceTree = "<group>"; };
564C445F1E943C37000F92B1 /* NameRegistrationAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NameRegistrationAdapter.mm; sourceTree = "<group>"; };
@@ -312,15 +315,13 @@
56AC64DE1E804ECC00EA1AA9 /* SwitchCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwitchCell.swift; sourceTree = "<group>"; };
56AC64E01E80542300EA1AA9 /* TextFieldCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldCell.swift; sourceTree = "<group>"; };
56AC64E21E805F0200EA1AA9 /* TextCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextCell.swift; sourceTree = "<group>"; };
- 56AC650D1E85694D00EA1AA9 /* RoundedTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoundedTextField.swift; sourceTree = "<group>"; };
+ 56AC650D1E85694D00EA1AA9 /* DesignableTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DesignableTextField.swift; sourceTree = "<group>"; };
56BBC99D1ED714CB00CDAF8B /* MessagesAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessagesAdapter.h; sourceTree = "<group>"; };
56BBC99E1ED714CB00CDAF8B /* MessagesAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MessagesAdapter.mm; sourceTree = "<group>"; };
56BBC9A01ED714DF00CDAF8B /* MessagesAdapterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessagesAdapterDelegate.swift; sourceTree = "<group>"; };
56BBC9A11ED714DF00CDAF8B /* ConversationsService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationsService.swift; sourceTree = "<group>"; };
56BBC9A51ED7151500CDAF8B /* MessageModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageModel.swift; sourceTree = "<group>"; };
56BBC9A71ED7152300CDAF8B /* SmartlistViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartlistViewController.swift; sourceTree = "<group>"; };
- 56BBC9A91ED7153800CDAF8B /* Global.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = Global.strings; path = Base.lproj/Global.strings; sourceTree = "<group>"; };
- 56BBC9AB1ED7154300CDAF8B /* Smartlist.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = Smartlist.strings; path = Base.lproj/Smartlist.strings; sourceTree = "<group>"; };
56BBC9AE1ED7155700CDAF8B /* ConversationModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationModel.swift; sourceTree = "<group>"; };
56BBC9AF1ED7155700CDAF8B /* ConversationViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationViewModel.swift; sourceTree = "<group>"; };
56BBC9B21ED7156500CDAF8B /* ConversationCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationCell.swift; sourceTree = "<group>"; };
@@ -338,7 +339,6 @@
56BBC9DD1EDDC9D300CDAF8B /* LookupNameResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LookupNameResponse.h; sourceTree = "<group>"; };
56BBC9DE1EDDC9D300CDAF8B /* LookupNameResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LookupNameResponse.m; sourceTree = "<group>"; };
56BBC9E21EDDCC8100CDAF8B /* ConversationSection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationSection.swift; sourceTree = "<group>"; };
- 56BBC9E61EDE1DDF00CDAF8B /* Colors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -500,6 +500,7 @@
02E1A0271DDE4C3900D75B59 /* Account */ = {
isa = PBXGroup;
children = (
+ 1A8306321F0EDAA50099D98C /* AccountTableViewCell.swift */,
02B22DFA1DF755BB000358C9 /* AccountModel.swift */,
5516C29E1E71CEFF009D3D2D /* AccountModelHelper.swift */,
02B22DFB1DF755BB000358C9 /* CreateRingAccountViewModel.swift */,
@@ -540,9 +541,8 @@
043866341D22D04E00E06CE2 /* UI */ = {
isa = PBXGroup;
children = (
- 0273C3071E0C68BF00CF00BA /* RoundedButton.swift */,
- 043866351D22D06500E06CE2 /* AccountTableViewCell.swift */,
- 56AC650D1E85694D00EA1AA9 /* RoundedTextField.swift */,
+ 0273C3071E0C68BF00CF00BA /* DesignableButton.swift */,
+ 56AC650D1E85694D00EA1AA9 /* DesignableTextField.swift */,
);
path = UI;
sourceTree = "<group>";
@@ -551,7 +551,10 @@
isa = PBXGroup;
children = (
56BBC9BB1ED7161200CDAF8B /* Date+Helpers.swift */,
- 043866371D2304A700E06CE2 /* BoolStringExtension.swift */,
+ 043866371D2304A700E06CE2 /* String+Bool.swift */,
+ 1A3D28A61F0EB9DB00B524EE /* Bool+String.swift */,
+ 1A3D28A81F0EBF0200B524EE /* UIView+Ring.swift */,
+ 1AABA7451F0FE9C000739605 /* UIColor+Ring.swift */,
);
path = Extensions;
sourceTree = "<group>";
@@ -589,7 +592,6 @@
56BBC9AD1ED7154800CDAF8B /* Conversations */,
56BBC9A41ED7150200CDAF8B /* Messages */,
564C44571E8D7F68000F92B1 /* Constants */,
- 56AC64D61E80121200EA1AA9 /* Internationalization */,
0273C3021E0C689600CF00BA /* Walkthrough */,
02EFCACF1E0C3DD600FD8ED1 /* Bridging */,
02E1A0271DDE4C3900D75B59 /* Account */,
@@ -756,22 +758,11 @@
isa = PBXGroup;
children = (
1ABE07C51F0D862D00D36361 /* Generated */,
- 56BBC9E61EDE1DDF00CDAF8B /* Colors.swift */,
- 564C44581E8D7F8F000F92B1 /* LocalizedStringTableNames.swift */,
564C445A1E8EA44E000F92B1 /* Durations.swift */,
);
path = Constants;
sourceTree = "<group>";
};
- 56AC64D61E80121200EA1AA9 /* Internationalization */ = {
- isa = PBXGroup;
- children = (
- 56BBC9AB1ED7154300CDAF8B /* Smartlist.strings */,
- 56BBC9A91ED7153800CDAF8B /* Global.strings */,
- );
- name = Internationalization;
- sourceTree = "<group>";
- };
56AC64DD1E804EB500EA1AA9 /* Cells */ = {
isa = PBXGroup;
children = (
@@ -1038,14 +1029,16 @@
557086521E8ADB9D001A7CE4 /* SystemAdapter.mm in Sources */,
5669A8031EAA58E6003C7B93 /* LinkDeviceToAccountViewController.swift in Sources */,
0273C3051E0C68B100CF00BA /* CreateProfileViewController.swift in Sources */,
- 02E1A0251DDE4ABA00D75B59 /* BoolStringExtension.swift in Sources */,
+ 02E1A0251DDE4ABA00D75B59 /* String+Bool.swift in Sources */,
04399AAC1D1C304300E99CD9 /* AccountAdapter.mm in Sources */,
+ 1AABA7461F0FE9C000739605 /* UIColor+Ring.swift in Sources */,
02DD80C81E1EAD70009A3510 /* AccountConfigModel.swift in Sources */,
02B22E091DF7585F000358C9 /* DaemonService.swift in Sources */,
0273C3061E0C68B100CF00BA /* CreateRingAccountViewController.swift in Sources */,
56BBC99F1ED714CB00CDAF8B /* MessagesAdapter.mm in Sources */,
56BBC9CF1EDC5E7000CDAF8B /* MessageCell.swift in Sources */,
02C9B63F1E1D4E8C00F82F0C /* ServiceEvent.swift in Sources */,
+ 1A3D28A71F0EB9DB00B524EE /* Bool+String.swift in Sources */,
56BBC9D21EDC5E7000CDAF8B /* MessageViewModel.swift in Sources */,
02DD80CD1E1EB2E4009A3510 /* ConfigKeyModel.swift in Sources */,
56BBC9E31EDDCC8100CDAF8B /* ConversationSection.swift in Sources */,
@@ -1059,14 +1052,13 @@
56AC64E11E80542300EA1AA9 /* TextFieldCell.swift in Sources */,
1ABE07E21F0D924700D36361 /* Strings.swift in Sources */,
56AC64E31E805F0200EA1AA9 /* TextCell.swift in Sources */,
- 56AC650E1E85694D00EA1AA9 /* RoundedTextField.swift in Sources */,
+ 56AC650E1E85694D00EA1AA9 /* DesignableTextField.swift in Sources */,
56BBC9BF1ED7168400CDAF8B /* SmartlistViewModel.swift in Sources */,
02B22E011DF755E5000358C9 /* MainTabBarViewController.swift in Sources */,
564C44641E943E1E000F92B1 /* NameRegistrationAdapterDelegate.swift in Sources */,
043999F71D1C2D9D00E99CD9 /* AppDelegate.swift in Sources */,
02B22DFC1DF755BB000358C9 /* AccountModel.swift in Sources */,
56AC64DF1E804ECC00EA1AA9 /* SwitchCell.swift in Sources */,
- 56BBC9E71EDE1DDF00CDAF8B /* Colors.swift in Sources */,
56BBC9B91ED715FE00CDAF8B /* ContactModel.swift in Sources */,
56BBC9BA1ED715FE00CDAF8B /* ContactHelper.swift in Sources */,
04399AAE1D1C304300E99CD9 /* Utils.mm in Sources */,
@@ -1075,17 +1067,18 @@
563AEC771EA664C0003A5641 /* RegistrationResponse.m in Sources */,
02B22DFD1DF755BB000358C9 /* CreateRingAccountViewModel.swift in Sources */,
564C445B1E8EA44E000F92B1 /* Durations.swift in Sources */,
+ 1A8306331F0EDAA50099D98C /* AccountTableViewCell.swift in Sources */,
56BBC9DF1EDDC9D300CDAF8B /* LookupNameResponse.m in Sources */,
+ 1A3D28A91F0EBF0200B524EE /* UIView+Ring.swift in Sources */,
1ABE07D21F0D8FE800D36361 /* Images.swift in Sources */,
56BBC9CD1EDC5E7000CDAF8B /* MessageAccessoryView.swift in Sources */,
02DD80CA1E1EAF1A009A3510 /* AccountCredentialsModel.swift in Sources */,
- 0273C3081E0C68BF00CF00BA /* RoundedButton.swift in Sources */,
+ 0273C3081E0C68BF00CF00BA /* DesignableButton.swift in Sources */,
56BBC9BC1ED7161200CDAF8B /* Date+Helpers.swift in Sources */,
562FB6CD1EFAD18A00C61A78 /* ConversationViewController.swift in Sources */,
564C44621E943DE6000F92B1 /* NameService.swift in Sources */,
56BBC9E01EDDC9E600CDAF8B /* ConversationViewModel.swift in Sources */,
1ABE07BA1F0C16F100D36361 /* ContactViewModel.swift in Sources */,
- 043866361D22D06500E06CE2 /* AccountTableViewCell.swift in Sources */,
04399AAD1D1C304300E99CD9 /* DRingAdapter.mm in Sources */,
0273C2FF1E0C438F00CF00BA /* AccountAdapterDelegate.swift in Sources */,
02B22DFF1DF755DB000358C9 /* AccountsService.swift in Sources */,
@@ -1094,7 +1087,6 @@
56BBC9A21ED714DF00CDAF8B /* MessagesAdapterDelegate.swift in Sources */,
56BBC9B41ED7156500CDAF8B /* ConversationCell.swift in Sources */,
564C44601E943C37000F92B1 /* NameRegistrationAdapter.mm in Sources */,
- 564C44591E8D7F8F000F92B1 /* LocalizedStringTableNames.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/Ring/Ring/UI/AccountTableViewCell.swift b/Ring/Ring/Account/AccountTableViewCell.swift
similarity index 81%
rename from Ring/Ring/UI/AccountTableViewCell.swift
rename to Ring/Ring/Account/AccountTableViewCell.swift
index 508c669..866d74b 100644
--- a/Ring/Ring/UI/AccountTableViewCell.swift
+++ b/Ring/Ring/Account/AccountTableViewCell.swift
@@ -19,8 +19,9 @@
*/
import UIKit
+import Reusable
-class AccountTableViewCell: UITableViewCell {
+class AccountTableViewCell: UITableViewCell, NibReusable {
// MARK: - Properties
@IBOutlet weak var activeSwitch: UISwitch!
@@ -29,15 +30,6 @@
var account: AccountModel!
- // MARK: - UITableViewCell
- override func awakeFromNib() {
- super.awakeFromNib()
- }
-
- override func setSelected(_ selected: Bool, animated: Bool) {
- super.setSelected(selected, animated: animated)
- }
-
// MARK: - Actions
@IBAction func switchAccountState(_ sender: UISwitch) {
// account.isEnabled = sender.isOn
diff --git a/Ring/Ring/Account/CreateRingAccountViewModel.swift b/Ring/Ring/Account/CreateRingAccountViewModel.swift
index 97fd4bc..7dbd192 100644
--- a/Ring/Ring/Account/CreateRingAccountViewModel.swift
+++ b/Ring/Ring/Account/CreateRingAccountViewModel.swift
@@ -140,17 +140,11 @@
.asObservable().map ({ status in
switch status {
case .lookingUp:
- return NSLocalizedString("LookingForUsernameAvailability",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
+ return L10n.Createaccount.lookingForUsernameAvailability.smartString
case .invalid:
- return NSLocalizedString("InvalidUsername",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
+ return L10n.Createaccount.invalidUsername.smartString
case .alreadyTaken:
- return NSLocalizedString("UsernameAlreadyTaken",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
+ return L10n.Createaccount.usernameAlreadyTaken.smartString
default:
return ""
}
@@ -181,7 +175,7 @@
//Loookup name request observer
self.username.asObservable().subscribe(onNext: { [unowned self] username in
self.nameService.lookupName(withAccount: "", nameserver: "", name: username)
- }).addDisposableTo(disposeBag)
+ }).disposed(by: disposeBag)
//Name registration observer
self.accountService
@@ -200,7 +194,7 @@
name: self.username.value)
}
})
- .addDisposableTo(disposeBag)
+ .disposed(by: disposeBag)
//Account creation state observer
self.accountService
@@ -215,7 +209,7 @@
}
}, onError: { _ in
self.accountCreationState.onError(AccountCreationError.unknown)
- }).addDisposableTo(disposeBag)
+ }).disposed(by: disposeBag)
}
}
@@ -238,34 +232,22 @@
var title: String {
switch self {
case .generic:
- return NSLocalizedString("AccountCannotBeFoundTitle",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
+ return L10n.Alerts.accountCannotBeFoundTitle.smartString
case .network:
- return NSLocalizedString("AccountNoNetworkTitle",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
+ return L10n.Alerts.accountNoNetworkTitle.smartString
default:
- return NSLocalizedString("AccountDefaultErrorTitle",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
+ return L10n.Alerts.accountDefaultErrorTitle.smartString
}
}
var message: String {
switch self {
case .generic:
- return NSLocalizedString("AcountCannotBeFoundMessage",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
+ return L10n.Alerts.accountDefaultErrorMessage.smartString
case .network:
- return NSLocalizedString("AccountNoNetworkMessage",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
+ return L10n.Alerts.accountNoNetworkMessage.smartString
default:
- return NSLocalizedString("AccountDefaultErrorMessage",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
+ return L10n.Alerts.accountDefaultErrorMessage.smartString
}
}
}
diff --git a/Ring/Ring/Constants/Durations.swift b/Ring/Ring/Constants/Durations.swift
index d62b37d..bd0c87c 100644
--- a/Ring/Ring/Constants/Durations.swift
+++ b/Ring/Ring/Constants/Durations.swift
@@ -20,9 +20,16 @@
import Foundation
-/**
- Time interval between TextField events in seconds
-*/
-let textFieldThrottlingDuration = 0.5
+public enum Durations {
+ case textFieldThrottlingDuration
+ case alertFlashDuration
-let alertFlashDuration = 1.0
+ var value: Double {
+ switch self {
+ case .textFieldThrottlingDuration:
+ return 0.5
+ case .alertFlashDuration:
+ return 1.0
+ }
+ }
+}
diff --git a/Ring/Ring/Constants/Generated/Strings.swift b/Ring/Ring/Constants/Generated/Strings.swift
index f5a7610..bbbad24 100644
--- a/Ring/Ring/Constants/Generated/Strings.swift
+++ b/Ring/Ring/Constants/Generated/Strings.swift
@@ -13,64 +13,83 @@
// swiftlint:disable valid_docs
enum L10n {
- /// Account Added
- static let accountAddedTitle = L10n.tr("AccountAddedTitle")
- /// Can't find account
- static let accountCannotBeFoundTitle = L10n.tr("AccountCannotBeFoundTitle")
- /// The account couldn't be created.
- static let accountDefaultErrorMessage = L10n.tr("AccountDefaultErrorMessage")
- /// Unknown error
- static let accountDefaultErrorTitle = L10n.tr("AccountDefaultErrorTitle")
- /// Could not add account because Ring couldn't connect to the distributed network. Check your device connectivity.
- static let accountNoNetworkMessage = L10n.tr("AccountNoNetworkMessage")
- /// Can't connect to the network
- static let accountNoNetworkTitle = L10n.tr("AccountNoNetworkTitle")
- /// Account couldn't be found on the Ring network. Make sure it was exported on Ring from an existing device, and that provided credentials are correct.
- static let acountCannotBeFoundMessage = L10n.tr("AcountCannotBeFoundMessage")
- /// Choose strong password you will remember to protect your Ring account.
- static let chooseStrongPassword = L10n.tr("ChooseStrongPassword")
- /// Conversations
- static let conversations = L10n.tr("Conversations")
- /// Create a Ring account
- static let createAccount = L10n.tr("CreateAccount")
- /// Create your Ring account
- static let createAccountFormTitle = L10n.tr("CreateAccountFormTitle")
- /// Enter new username
- static let enterNewUsernamePlaceholder = L10n.tr("EnterNewUsernamePlaceholder")
- /// Home
- static let homeTabBarTitle = L10n.tr("HomeTabBarTitle")
- /// Invalid username
- static let invalidUsername = L10n.tr("InvalidUsername")
- /// Link this device to an account
- static let linkDeviceButton = L10n.tr("LinkDeviceButton")
- /// Looking for username availability...
- static let lookingForUsernameAvailability = L10n.tr("LookingForUsernameAvailability")
- /// New Password
- static let newPasswordPlaceholder = L10n.tr("NewPasswordPlaceholder")
- /// No results
- static let noResults = L10n.tr("NoResults")
- /// 6 characters minimum
- static let passwordCharactersNumberError = L10n.tr("PasswordCharactersNumberError")
- /// Passwords do not match
- static let passwordNotMatchingError = L10n.tr("PasswordNotMatchingError")
- /// Register public username (experimental)
- static let registerPublicUsername = L10n.tr("RegisterPublicUsername")
- /// Repeat new password
- static let repeatPasswordPlaceholder = L10n.tr("RepeatPasswordPlaceholder")
- /// Searching...
- static let searching = L10n.tr("Searching")
- /// User found
- static let userFound = L10n.tr("UserFound")
- /// Username already taken
- static let usernameAlreadyTaken = L10n.tr("UsernameAlreadyTaken")
- /// Adding account
- static let waitCreateAccountTitle = L10n.tr("WaitCreateAccountTitle")
- /// A Ring account allows you to reach people securely in peer to peer through fully distributed network
- static let welcomeText = L10n.tr("WelcomeText")
- /// Welcome to Ring
- static let welcomeTitle = L10n.tr("WelcomeTitle")
- /// Yesterday
- static let yesterday = L10n.tr("Yesterday")
+
+ enum Alerts {
+ /// Account Added
+ static let accountAddedTitle = L10n.tr("alerts.accountAddedTitle")
+ /// Can't find account
+ static let accountCannotBeFoundTitle = L10n.tr("alerts.accountCannotBeFoundTitle")
+ /// The account couldn't be created.
+ static let accountDefaultErrorMessage = L10n.tr("alerts.accountDefaultErrorMessage")
+ /// Unknown error
+ static let accountDefaultErrorTitle = L10n.tr("alerts.accountDefaultErrorTitle")
+ /// Could not add account because Ring couldn't connect to the distributed network. Check your device connectivity.
+ static let accountNoNetworkMessage = L10n.tr("alerts.accountNoNetworkMessage")
+ /// Can't connect to the network
+ static let accountNoNetworkTitle = L10n.tr("alerts.accountNoNetworkTitle")
+ /// Account couldn't be found on the Ring network. Make sure it was exported on Ring from an existing device, and that provided credentials are correct.
+ static let acountCannotBeFoundMessage = L10n.tr("alerts.acountCannotBeFoundMessage")
+ }
+
+ enum Createaccount {
+ /// Choose strong password you will remember to protect your Ring account.
+ static let chooseStrongPassword = L10n.tr("createAccount.chooseStrongPassword")
+ /// Create your Ring account
+ static let createAccountFormTitle = L10n.tr("createAccount.createAccountFormTitle")
+ /// Enter new username
+ static let enterNewUsernamePlaceholder = L10n.tr("createAccount.enterNewUsernamePlaceholder")
+ /// Invalid username
+ static let invalidUsername = L10n.tr("createAccount.invalidUsername")
+ /// Loading...
+ static let loading = L10n.tr("createAccount.loading")
+ /// Looking for username availability...
+ static let lookingForUsernameAvailability = L10n.tr("createAccount.lookingForUsernameAvailability")
+ /// New Password
+ static let newPasswordPlaceholder = L10n.tr("createAccount.newPasswordPlaceholder")
+ /// 6 characters minimum
+ static let passwordCharactersNumberError = L10n.tr("createAccount.passwordCharactersNumberError")
+ /// Passwords do not match
+ static let passwordNotMatchingError = L10n.tr("createAccount.passwordNotMatchingError")
+ /// Register public username (experimental)
+ static let registerPublicUsername = L10n.tr("createAccount.registerPublicUsername")
+ /// Repeat new password
+ static let repeatPasswordPlaceholder = L10n.tr("createAccount.repeatPasswordPlaceholder")
+ /// Username already taken
+ static let usernameAlreadyTaken = L10n.tr("createAccount.usernameAlreadyTaken")
+ /// Adding account
+ static let waitCreateAccountTitle = L10n.tr("createAccount.waitCreateAccountTitle")
+ }
+
+ enum Global {
+ /// Home
+ static let homeTabBarTitle = L10n.tr("global.homeTabBarTitle")
+ /// Ok
+ static let ok = L10n.tr("global.ok")
+ }
+
+ enum Smartlist {
+ /// Conversations
+ static let conversations = L10n.tr("smartlist.conversations")
+ /// No results
+ static let noResults = L10n.tr("smartlist.noResults")
+ /// Searching...
+ static let searching = L10n.tr("smartlist.searching")
+ /// User found
+ static let userFound = L10n.tr("smartlist.userFound")
+ /// Yesterday
+ static let yesterday = L10n.tr("smartlist.yesterday")
+ }
+
+ enum Welcome {
+ /// Create a Ring account
+ static let createAccount = L10n.tr("welcome.createAccount")
+ /// Link this device to an account
+ static let linkDeviceButton = L10n.tr("welcome.linkDeviceButton")
+ /// A Ring account allows you to reach people securely in peer to peer through fully distributed network
+ static let text = L10n.tr("welcome.text")
+ /// Welcome to Ring
+ static let title = L10n.tr("welcome.title")
+ }
}
struct LocalizableString {
diff --git a/Ring/Ring/Contacts/ContactHelper.swift b/Ring/Ring/Contacts/ContactHelper.swift
index c1f91b6..b55c883 100644
--- a/Ring/Ring/Contacts/ContactHelper.swift
+++ b/Ring/Ring/Contacts/ContactHelper.swift
@@ -39,7 +39,7 @@
} else {
userName.value = lookupNameResponse.address
}
- }).addDisposableTo(disposeBag)
+ }).disposed(by: disposeBag)
nameService.lookupAddress(withAccount: "", nameserver: "", address: ringId)
diff --git a/Ring/Ring/Contacts/ContactViewModel.swift b/Ring/Ring/Contacts/ContactViewModel.swift
index 15ef8b4..c15eeeb 100644
--- a/Ring/Ring/Contacts/ContactViewModel.swift
+++ b/Ring/Ring/Contacts/ContactViewModel.swift
@@ -73,7 +73,7 @@
} else {
self.userName.value = lookupNameResponse.address
}
- }).addDisposableTo(disposeBag)
+ }).disposed(by: disposeBag)
nameService.lookupAddress(withAccount: "", nameserver: "", address: self.contact.ringId)
}
diff --git a/Ring/Ring/Conversations/ConversationCell.swift b/Ring/Ring/Conversations/ConversationCell.swift
index d3fd4fd..12082a6 100644
--- a/Ring/Ring/Conversations/ConversationCell.swift
+++ b/Ring/Ring/Conversations/ConversationCell.swift
@@ -20,8 +20,9 @@
import UIKit
import RxSwift
+import Reusable
-class ConversationCell: UITableViewCell {
+class ConversationCell: UITableViewCell, NibReusable {
@IBOutlet weak var profileImage: UIImageView!
@IBOutlet weak var nameLabel: UILabel!
@@ -30,11 +31,6 @@
@IBOutlet weak var lastMessageDateLabel: UILabel!
@IBOutlet weak var lastMessagePreviewLabel: UILabel!
- override func awakeFromNib() {
- super.awakeFromNib()
-
- }
-
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
self.newMessagesIndicator.backgroundColor = UIColor.red
diff --git a/Ring/Ring/Conversations/ConversationCell.xib b/Ring/Ring/Conversations/ConversationCell.xib
index 6f54e38..a82c301 100644
--- a/Ring/Ring/Conversations/ConversationCell.xib
+++ b/Ring/Ring/Conversations/ConversationCell.xib
@@ -1,21 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16A323" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
- <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
- <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="ConversationCellId" rowHeight="76" id="KGk-i7-Jjw" customClass="ConversationCell" customModule="Ring" customModuleProvider="target">
+ <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="76" id="KGk-i7-Jjw" customClass="ConversationCell" customModule="Ring" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="358" height="76"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
- <rect key="frame" x="0.0" y="0.0" width="358" height="76"/>
+ <rect key="frame" x="0.0" y="0.0" width="358" height="75.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_contact_picture" translatesAutoresizingMaskIntoConstraints="NO" id="pFB-Jn-TNP">
diff --git a/Ring/Ring/Conversations/ConversationViewController.swift b/Ring/Ring/Conversations/ConversationViewController.swift
index 221444e..81c3afd 100644
--- a/Ring/Ring/Conversations/ConversationViewController.swift
+++ b/Ring/Ring/Conversations/ConversationViewController.swift
@@ -71,7 +71,7 @@
}
func setupUI() {
- self.viewModel?.userName.asObservable().bind(to: self.navigationItem.rx.title).addDisposableTo(disposeBag)
+ self.viewModel?.userName.asObservable().bind(to: self.navigationItem.rx.title).disposed(by: disposeBag)
self.tableView.contentInset.bottom = messageAccessoryView.frame.size.height
self.tableView.scrollIndicatorInsets.bottom = messageAccessoryView.frame.size.height
@@ -97,22 +97,21 @@
self.tableView.separatorStyle = .none
//Register cell
- self.tableView.register(UINib.init(nibName: "MessageCell", bundle: nil),
- forCellReuseIdentifier: "MessageCellId")
+ self.tableView.register(cellType: MessageCell.self)
//Bind the TableView to the ViewModel
self.viewModel?.messages
- .bind(to: tableView.rx.items(cellIdentifier: "MessageCellId",
+ .bind(to: tableView.rx.items(cellIdentifier: "MessageCell",
cellType: MessageCell.self)) { _, messageViewModel, cell in
cell.messageLabel.text = messageViewModel.content
cell.bubblePosition = messageViewModel.bubblePosition()
- }.addDisposableTo(disposeBag)
+ }.disposed(by: disposeBag)
//Scroll to bottom when reloaded
self.tableView.rx.methodInvoked(#selector(UITableView.reloadData)).subscribe(onNext: { _ in
self.scrollToBottomIfNeed()
self.updateBottomOffset()
- }).addDisposableTo(disposeBag)
+ }).disposed(by: disposeBag)
}
fileprivate func updateBottomOffset() {
@@ -153,7 +152,7 @@
}
lazy var messageAccessoryView: MessageAccessoryView = {
- return MessageAccessoryView.instanceFromNib()
+ return MessageAccessoryView.loadFromNib()
}()
func setupBindings() {
@@ -162,7 +161,7 @@
self.messageAccessoryView.messageTextField.rx.controlEvent(.editingDidEndOnExit).subscribe(onNext: { _ in
self.viewModel?.sendMessage(withContent: self.messageAccessoryView.messageTextField.text!)
self.messageAccessoryView.messageTextField.text = ""
- }).addDisposableTo(disposeBag)
+ }).disposed(by: disposeBag)
}
// Avoid the keyboard to be hidden when the Send button is touched
diff --git a/Ring/Ring/Conversations/ConversationViewModel.swift b/Ring/Ring/Conversations/ConversationViewModel.swift
index 2cd71b8..f67985b 100644
--- a/Ring/Ring/Conversations/ConversationViewModel.swift
+++ b/Ring/Ring/Conversations/ConversationViewModel.swift
@@ -89,7 +89,7 @@
self.log.error("Realm persistence with error: \(error)")
}
- }).addDisposableTo(self.disposeBag)
+ }).disposed(by: self.disposeBag)
return tmp
}
@@ -134,7 +134,7 @@
if todayDay == day && todayMonth == month && todayYear == year {
return hourFormatter.string(from: lastMessageDate)
} else if day == todayDay - 1 {
- return NSLocalizedString("Yesterday", tableName: "Smartlist", comment: "")
+ return L10n.Smartlist.yesterday.smartString
} else if todayYear == year && todayWeekOfYear == weekOfYear {
return lastMessageDate.dayOfWeek()
} else {
@@ -158,7 +158,7 @@
.subscribe(onCompleted: {
let accountHelper = AccountModelHelper(withAccount: self.accountService.currentAccount!)
self.saveMessage(withContent: content, byAuthor: accountHelper.ringId!, toConversationWith: (self.conversation.recipient?.ringId)!)
- }).addDisposableTo(disposeBag)
+ }).disposed(by: disposeBag)
}
fileprivate func saveMessage(withContent content: String, byAuthor author: String, toConversationWith account: String) {
@@ -167,7 +167,7 @@
.subscribe(onCompleted: { [unowned self] in
self.log.debug("Message saved")
})
- .addDisposableTo(disposeBag)
+ .disposed(by: disposeBag)
}
func setMessagesAsRead() {
@@ -175,7 +175,7 @@
.setMessagesAsRead(forConversation: self.conversation)
.subscribe(onCompleted: { [unowned self] in
self.log.debug("Message set as read")
- }).addDisposableTo(disposeBag)
+ }).disposed(by: disposeBag)
}
fileprivate var unreadMessagesCount: Int {
diff --git a/Ring/Ring/Constants/LocalizedStringTableNames.swift b/Ring/Ring/Extensions/Bool+String.swift
similarity index 77%
copy from Ring/Ring/Constants/LocalizedStringTableNames.swift
copy to Ring/Ring/Extensions/Bool+String.swift
index 72818c0..c065b40 100644
--- a/Ring/Ring/Constants/LocalizedStringTableNames.swift
+++ b/Ring/Ring/Extensions/Bool+String.swift
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2017 Savoir-faire Linux Inc.
+ * Copyright (C) 2016 Savoir-faire Linux Inc.
*
- * Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ * Author: Thibault Wittemberg <thibault.wittemberg@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,6 +20,8 @@
import Foundation
-struct LocalizedStringTableNames {
- static let walkthrough = "Walkthrough"
+extension Bool {
+ func toString() -> String {
+ return self ? "true" : "false"
+ }
}
diff --git a/Ring/Ring/Extensions/BoolStringExtension.swift b/Ring/Ring/Extensions/String+Bool.swift
similarity index 80%
rename from Ring/Ring/Extensions/BoolStringExtension.swift
rename to Ring/Ring/Extensions/String+Bool.swift
index ce59513..477e428 100644
--- a/Ring/Ring/Extensions/BoolStringExtension.swift
+++ b/Ring/Ring/Extensions/String+Bool.swift
@@ -22,22 +22,13 @@
extension String {
func toBool() -> Bool? {
- switch self {
- case "True", "true", "yes", "1":
+ switch self.lowercased() {
+ case "true", "yes", "1":
return true
- case "False", "false", "no", "0":
+ case "false", "no", "0":
return false
default:
return nil
}
}
}
-
-extension Bool {
- func toString() -> String {
- if self == true {
- return "true"
- }
- return "false"
- }
-}
diff --git a/Ring/Ring/Constants/Colors.swift b/Ring/Ring/Extensions/UIColor+Ring.swift
similarity index 66%
rename from Ring/Ring/Constants/Colors.swift
rename to Ring/Ring/Extensions/UIColor+Ring.swift
index 94d112f..20d90c9 100644
--- a/Ring/Ring/Constants/Colors.swift
+++ b/Ring/Ring/Extensions/UIColor+Ring.swift
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2017 Savoir-faire Linux Inc.
+ * Copyright (C) 2016 Savoir-faire Linux Inc.
*
- * Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ * Author: Thibault Wittemberg <thibault.wittemberg@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,11 +18,14 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+import Foundation
import UIKit
-class Colors {
- static let ringMainColor = UIColor(colorLiteralRed: 10.0/255.0,
- green: 116.0/255.0,
- blue: 137.0/255.0,
- alpha: 1.0)
+extension UIColor {
+
+ static let ringMain = UIColor(colorLiteralRed: 10.0/255.0,
+ green: 116.0/255.0,
+ blue: 137.0/255.0,
+ alpha: 1.0)
+
}
diff --git a/Ring/Ring/Extensions/UIView+Ring.swift b/Ring/Ring/Extensions/UIView+Ring.swift
new file mode 100644
index 0000000..a6a96d2
--- /dev/null
+++ b/Ring/Ring/Extensions/UIView+Ring.swift
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2016 Savoir-faire Linux Inc.
+ *
+ * Author: Thibault Wittemberg <thibault.wittemberg@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+import Foundation
+import UIKit
+
+extension UIView {
+
+ @IBInspectable
+ var cornerRadius: CGFloat {
+ get {
+ return self.layer.cornerRadius
+ }
+
+ set {
+ self.clipsToBounds = true
+ self.layer.cornerRadius = newValue
+ }
+ }
+
+ @IBInspectable
+ var roundedCorners: Bool {
+ get {
+ return self.cornerRadius == self.frame.height / 2
+ }
+
+ set {
+ if newValue {
+ self.cornerRadius = self.frame.height / 2
+ } else {
+ self.cornerRadius = 0
+ }
+ }
+ }
+
+ @IBInspectable
+ var borderWidth: CGFloat {
+ get {
+ return self.layer.borderWidth
+ }
+
+ set {
+ self.layer.borderWidth = newValue
+ }
+ }
+
+ @IBInspectable
+ var borderColor: UIColor {
+ get {
+ return UIColor(cgColor: self.layer.borderColor ?? UIColor.clear.cgColor)
+ }
+
+ set {
+ self.layer.borderColor = newValue.cgColor
+ }
+ }
+
+}
diff --git a/Ring/Ring/MainTabBar/MainTabBarViewController.swift b/Ring/Ring/MainTabBar/MainTabBarViewController.swift
index 20f2eae..26be014 100644
--- a/Ring/Ring/MainTabBar/MainTabBarViewController.swift
+++ b/Ring/Ring/MainTabBar/MainTabBarViewController.swift
@@ -26,7 +26,7 @@
override func viewDidLoad() {
super.viewDidLoad()
UITabBarItem.appearance()
- .setTitleTextAttributes( [NSForegroundColorAttributeName: Colors.ringMainColor], for: .selected)
+ .setTitleTextAttributes( [NSForegroundColorAttributeName: UIColor.ringMain], for: .selected)
}
override func viewDidAppear(_ animated: Bool) {
diff --git a/Ring/Ring/Messages/MessageAccessoryView.swift b/Ring/Ring/Messages/MessageAccessoryView.swift
index 1d01570..8c46e55 100644
--- a/Ring/Ring/Messages/MessageAccessoryView.swift
+++ b/Ring/Ring/Messages/MessageAccessoryView.swift
@@ -19,16 +19,10 @@
*/
import UIKit
+import Reusable
-class MessageAccessoryView: UIView {
+class MessageAccessoryView: UIView, NibLoadable {
@IBOutlet weak var messageTextField: UITextField!
- class func instanceFromNib() -> MessageAccessoryView {
- guard let view = UINib(nibName: "MessageAccessoryView", bundle: nil).instantiate(withOwner: nil, options: nil).first as? MessageAccessoryView else {
- fatalError("The view you are trying to instantiate is not a MessageAccessoryView")
- }
- return view
- }
-
}
diff --git a/Ring/Ring/Messages/MessageCell.swift b/Ring/Ring/Messages/MessageCell.swift
index 7cc80f6..aeebe9a 100644
--- a/Ring/Ring/Messages/MessageCell.swift
+++ b/Ring/Ring/Messages/MessageCell.swift
@@ -19,13 +19,14 @@
*/
import UIKit
+import Reusable
enum BubblePosition {
case received
case sent
}
-class MessageCell: UITableViewCell {
+class MessageCell: UITableViewCell, NibReusable {
@IBOutlet weak var bubble: UIView!
@IBOutlet weak var messageLabel: UILabel!
@@ -44,7 +45,7 @@
self.containerLeadingConstraint.priority = 1
self.minimumLeadingConstraint.priority = 999
- self.bubble.backgroundColor = Colors.ringMainColor
+ self.bubble.backgroundColor = UIColor.ringMain
self.messageLabel.textColor = UIColor.white
} else {
self.minimumLeadingConstraint.priority = 1
diff --git a/Ring/Ring/Messages/MessageCell.xib b/Ring/Ring/Messages/MessageCell.xib
index 0bf5445..65174d4 100644
--- a/Ring/Ring/Messages/MessageCell.xib
+++ b/Ring/Ring/Messages/MessageCell.xib
@@ -1,21 +1,21 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
- <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
- <tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="MessageCellId" rowHeight="60" id="KGk-i7-Jjw" customClass="MessageCell" customModule="Ring" customModuleProvider="target">
+ <tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" rowHeight="60" id="KGk-i7-Jjw" customClass="MessageCell" customModule="Ring" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="510" height="47"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
- <rect key="frame" x="0.0" y="0.0" width="510" height="46"/>
+ <rect key="frame" x="0.0" y="0.0" width="510" height="46.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view clipsSubviews="YES" contentMode="scaleToFill" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="kZJ-Ay-LTR">
diff --git a/Ring/Ring/Resources/Main.storyboard b/Ring/Ring/Resources/Main.storyboard
index 0b24cd4..fe011f2 100644
--- a/Ring/Ring/Resources/Main.storyboard
+++ b/Ring/Ring/Resources/Main.storyboard
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12120" systemVersion="16A323" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="qdG-Sd-QaE">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="qdG-Sd-QaE">
<device id="retina4_0" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
- <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@@ -50,7 +50,7 @@
<rect key="frame" x="0.0" y="28" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="i1O-Yc-WGd" id="Bz1-A3-Z3f">
- <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
+ <rect key="frame" x="0.0" y="0.0" width="320" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bm0-lC-K2F">
@@ -96,7 +96,7 @@
<rect key="frame" x="0.0" y="72" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Ok2-8L-eMm" id="m64-AI-t2h">
- <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
+ <rect key="frame" x="0.0" y="0.0" width="320" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Add Account" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kZv-uf-BsD" userLabel="Account Name Label">
@@ -332,11 +332,11 @@
<rect key="frame" x="0.0" y="0.0" width="320" height="455"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<prototypes>
- <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="MessageCellId" id="8rX-Qa-Ypu">
+ <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="MessageCell" id="8rX-Qa-Ypu">
<rect key="frame" x="0.0" y="28" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="8rX-Qa-Ypu" id="7vA-nx-B3h">
- <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
+ <rect key="frame" x="0.0" y="0.0" width="320" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
</tableViewCellContentView>
</tableViewCell>
diff --git a/Ring/Ring/Resources/en.lproj/Localizable.strings b/Ring/Ring/Resources/en.lproj/Localizable.strings
index b95453e..8521f93 100644
--- a/Ring/Ring/Resources/en.lproj/Localizable.strings
+++ b/Ring/Ring/Resources/en.lproj/Localizable.strings
@@ -19,51 +19,46 @@
*/
// Global
-"HomeTabBarTitle" = "Home";
+"global.homeTabBarTitle" = "Home";
+"global.ok" = "Ok";
// Smartlist
-"Yesterday" = "Yesterday";
-
-"UserFound" = "User found";
-"Conversations" = "Conversations";
-
-"Searching" = "Searching...";
-"NoResults" = "No results";
+"smartlist.yesterday" = "Yesterday";
+"smartlist.userFound" = "User found";
+"smartlist.conversations" = "Conversations";
+"smartlist.searching" = "Searching...";
+"smartlist.noResults" = "No results";
// Walkthrough
//Welcome Screen
-
-"WelcomeTitle" = "Welcome to Ring";
-"WelcomeText" = "A Ring account allows you to reach people securely in peer to peer through fully distributed network";
-"LinkDeviceButton" = "Link this device to an account";
-"CreateAccount" = "Create a Ring account";
+"welcome.title" = "Welcome to Ring";
+"welcome.text" = "A Ring account allows you to reach people securely in peer to peer through fully distributed network";
+"welcome.linkDeviceButton" = "Link this device to an account";
+"welcome.createAccount" = "Create a Ring account";
//Create Account form
-
-"CreateAccountFormTitle" = "Create your Ring account";
-"RegisterPublicUsername" = "Register public username (experimental)";
-"ChooseStrongPassword" = "Choose strong password you will remember to protect your Ring account.";
-"EnterNewUsernamePlaceholder" = "Enter new username";
-"NewPasswordPlaceholder" = "New Password";
-"RepeatPasswordPlaceholder" = "Repeat new password";
-"PasswordCharactersNumberError" = "6 characters minimum";
-"PasswordNotMatchingError" = "Passwords do not match";
-"LookingForUsernameAvailability" = "Looking for username availability...";
-"InvalidUsername" = "Invalid username";
-"UsernameAlreadyTaken" = "Username already taken";
+"createAccount.createAccountFormTitle" = "Create your Ring account";
+"createAccount.registerPublicUsername" = "Register public username (experimental)";
+"createAccount.chooseStrongPassword" = "Choose strong password you will remember to protect your Ring account.";
+"createAccount.enterNewUsernamePlaceholder" = "Enter new username";
+"createAccount.newPasswordPlaceholder" = "New Password";
+"createAccount.repeatPasswordPlaceholder" = "Repeat new password";
+"createAccount.passwordCharactersNumberError" = "6 characters minimum";
+"createAccount.passwordNotMatchingError" = "Passwords do not match";
+"createAccount.lookingForUsernameAvailability" = "Looking for username availability...";
+"createAccount.invalidUsername" = "Invalid username";
+"createAccount.usernameAlreadyTaken" = "Username already taken";
+"createAccount.loading" = "Loading...";
//Progress View
-"WaitCreateAccountTitle" = "Adding account";
+"createAccount.waitCreateAccountTitle" = "Adding account";
//Alerts
-"AccountCannotBeFoundTitle" = "Can't find account";
-"AcountCannotBeFoundMessage" = "Account couldn't be found on the Ring network. Make sure it was exported on Ring from an existing device, and that provided credentials are correct.";
-
-"AccountAddedTitle" = "Account Added";
-
-"AccountNoNetworkTitle" = "Can't connect to the network";
-"AccountNoNetworkMessage" = "Could not add account because Ring couldn't connect to the distributed network. Check your device connectivity.";
-
-"AccountDefaultErrorTitle" = "Unknown error";
-"AccountDefaultErrorMessage" = "The account couldn't be created.";
+"alerts.accountCannotBeFoundTitle" = "Can't find account";
+"alerts.acountCannotBeFoundMessage" = "Account couldn't be found on the Ring network. Make sure it was exported on Ring from an existing device, and that provided credentials are correct.";
+"alerts.accountAddedTitle" = "Account Added";
+"alerts.accountNoNetworkTitle" = "Can't connect to the network";
+"alerts.accountNoNetworkMessage" = "Could not add account because Ring couldn't connect to the distributed network. Check your device connectivity.";
+"alerts.accountDefaultErrorTitle" = "Unknown error";
+"alerts.accountDefaultErrorMessage" = "The account couldn't be created.";
diff --git a/Ring/Ring/Services/AccountsService.swift b/Ring/Ring/Services/AccountsService.swift
index e18d32e..1392d97 100644
--- a/Ring/Ring/Services/AccountsService.swift
+++ b/Ring/Ring/Services/AccountsService.swift
@@ -119,7 +119,7 @@
init(withAccountAdapter accountAdapter: AccountAdapter) {
self.accountList = []
- self.responseStream.addDisposableTo(disposeBag)
+ self.responseStream.disposed(by: disposeBag)
//~ Create a shared stream based on the responseStream one.
self.sharedResponseStream = responseStream.share()
diff --git a/Ring/Ring/Services/ConversationsService.swift b/Ring/Ring/Services/ConversationsService.swift
index f69d022..3be76e5 100644
--- a/Ring/Ring/Services/ConversationsService.swift
+++ b/Ring/Ring/Services/ConversationsService.swift
@@ -18,7 +18,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-import UIKit
import RxSwift
import RealmSwift
import SwiftyBeaver
@@ -159,20 +158,26 @@
}
func deleteConversation(conversation: ConversationModel) {
- try! realm.write {
- //Remove all messages from the conversation
- for message in conversation.messages {
- realm.delete(message)
+ do {
+ try realm.write {
+
+ //Remove all messages from the conversation
+ for message in conversation.messages {
+ realm.delete(message)
+ }
+
+ realm.delete(conversation)
}
-
- realm.delete(conversation)
+ } catch let error {
+ self.log.error("\(error)")
}
}
- //MARK: Message Adapter delegate
+ // MARK: Message Adapter delegate
- func didReceiveMessage(_ message: [String: String], from senderAccount: String,
+ func didReceiveMessage(_ message: [String: String],
+ from senderAccount: String,
to receiverAccountId: String) {
if let content = message[textPlainMIMEType] {
@@ -180,12 +185,14 @@
.subscribe(onCompleted: { [unowned self] in
self.log.info("Message saved")
})
- .addDisposableTo(disposeBag)
+ .disposed(by: disposeBag)
}
}
- func messageStatusChanged(_ status: MessageStatus, for messageId: UInt64,
- from senderAccountId: String, to receiverAccount: String) {
+ func messageStatusChanged(_ status: MessageStatus,
+ for messageId: UInt64,
+ from senderAccountId: String,
+ to receiverAccount: String) {
log.debug("messageStatusChanged: \(status.rawValue) for: \(messageId) from: \(senderAccountId) to: \(receiverAccount)")
}
}
diff --git a/Ring/Ring/Services/NameService.swift b/Ring/Ring/Services/NameService.swift
index 2b8df9e..d16824d 100644
--- a/Ring/Ring/Services/NameService.swift
+++ b/Ring/Ring/Services/NameService.swift
@@ -18,7 +18,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-import UIKit
import RxSwift
import SwiftyBeaver
diff --git a/Ring/Ring/Settings/AccountDetailsViewController.swift b/Ring/Ring/Settings/AccountDetailsViewController.swift
index a5dbc4a..3be87e9 100644
--- a/Ring/Ring/Settings/AccountDetailsViewController.swift
+++ b/Ring/Ring/Settings/AccountDetailsViewController.swift
@@ -27,13 +27,4 @@
@IBOutlet weak var detailsLabel: UILabel!
- // MARK: - UIViewController
- override func viewDidLoad() {
- super.viewDidLoad()
- }
-
- override func didReceiveMemoryWarning() {
- super.didReceiveMemoryWarning()
- }
-
}
diff --git a/Ring/Ring/Settings/MeViewController.swift b/Ring/Ring/Settings/MeViewController.swift
index 995e0c0..d57fdd4 100644
--- a/Ring/Ring/Settings/MeViewController.swift
+++ b/Ring/Ring/Settings/MeViewController.swift
@@ -33,11 +33,11 @@
super.viewDidLoad()
if !accountService.accounts.isEmpty {
-// let acc = accountService.accounts[0]
-// nameLabel.text = acc.displayName
-// if let username = acc.username {
-// createQRFromString(username);
-// }
+ // let acc = accountService.accounts[0]
+ // nameLabel.text = acc.displayName
+ // if let username = acc.username {
+ // createQRFromString(username);
+ // }
}
}
@@ -74,17 +74,15 @@
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row < accountService.accounts.count {
- if let cell = tableView.dequeueReusableCell(withIdentifier: "accountTableCell", for: indexPath) as? AccountTableViewCell {
- let account = accountService.accounts[indexPath.row]
+ let cell = tableView.dequeueReusableCell(for: indexPath, cellType: AccountTableViewCell.self)
+ let account = accountService.accounts[indexPath.row]
- cell.account = account
- // cell.accountNameLabel.text = account.alias
- // cell.activeSwitch.setOn(account.isEnabled, animated: false)
- // cell.accountTypeLabel.text = account.accountType.rawValue
- return cell
- } else {
- return tableView.dequeueReusableCell(withIdentifier: "accountTableCell", for: indexPath)
- }
+ cell.account = account
+ // cell.accountNameLabel.text = account.alias
+ // cell.activeSwitch.setOn(account.isEnabled, animated: false)
+ // cell.accountTypeLabel.text = account.accountType.rawValue
+ return cell
+
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "addAccountTableCell", for: indexPath)
return cell
@@ -127,5 +125,4 @@
vc.account = cell.account
}
}
-
}
diff --git a/Ring/Ring/Smartlist/SmartlistViewController.swift b/Ring/Ring/Smartlist/SmartlistViewController.swift
index a0e2b8a..52c5406 100644
--- a/Ring/Ring/Smartlist/SmartlistViewController.swift
+++ b/Ring/Ring/Smartlist/SmartlistViewController.swift
@@ -22,10 +22,9 @@
import RxSwift
import RxDataSources
import RxCocoa
+import Reusable
//Constants
-fileprivate let conversationCellIdentifier = "ConversationCellId"
-fileprivate let conversationCellNibName = "ConversationCell"
fileprivate let showMessages = "ShowMessages"
fileprivate let smartlistRowHeight: CGFloat = 64.0
@@ -70,14 +69,12 @@
func setupUI() {
- let title = NSLocalizedString("HomeTabBarTitle", tableName: "Global", comment: "")
-
- self.title = title
- self.navigationItem.title = title
+ self.title = L10n.Global.homeTabBarTitle.smartString
+ self.navigationItem.title = L10n.Global.homeTabBarTitle.smartString
self.viewModel.hideNoConversationsMessage
.bind(to: self.noConversationsView.rx.isHidden)
- .addDisposableTo(disposeBag)
+ .disposed(by: disposeBag)
self.navigationItem.rightBarButtonItem = self.editButtonItem
}
@@ -125,16 +122,15 @@
tableView: UITableView,
indexPath: IndexPath,
item: ConversationSection.Item) in
- if let cell = tableView.dequeueReusableCell(withIdentifier: conversationCellIdentifier, for: indexPath) as? ConversationCell {
- item.userName.asObservable().bind(to: cell.nameLabel.rx.text).addDisposableTo(self.disposeBag)
- cell.newMessagesLabel.text = item.unreadMessages
- cell.lastMessageDateLabel.text = item.lastMessageReceivedDate
- cell.newMessagesIndicator.isHidden = item.hideNewMessagesLabel
- cell.lastMessagePreviewLabel.text = item.lastMessage
- return cell
- } else {
- return tableView.dequeueReusableCell(withIdentifier: conversationCellIdentifier, for: indexPath)
- }
+
+ let cell = tableView.dequeueReusableCell(for: indexPath, cellType: ConversationCell.self)
+
+ item.userName.asObservable().bind(to: cell.nameLabel.rx.text).disposed(by: self.disposeBag)
+ cell.newMessagesLabel.text = item.unreadMessages
+ cell.lastMessageDateLabel.text = item.lastMessageReceivedDate
+ cell.newMessagesIndicator.isHidden = item.hideNewMessagesLabel
+ cell.lastMessagePreviewLabel.text = item.lastMessage
+ return cell
}
//Allows to delete
@@ -148,11 +144,11 @@
//Bind TableViews to DataSources
self.viewModel.conversations
.bind(to: self.conversationsTableView.rx.items(dataSource: conversationsDataSource))
- .addDisposableTo(disposeBag)
+ .disposed(by: disposeBag)
self.viewModel.searchResults
.bind(to: self.searchResultsTableView.rx.items(dataSource: searchResultsDatasource))
- .addDisposableTo(disposeBag)
+ .disposed(by: disposeBag)
//Set header titles
searchResultsDatasource.titleForHeaderInSection = { dataSource, index in
@@ -167,48 +163,49 @@
self.searchResultsTableView.rowHeight = smartlistRowHeight
//Register Cell
- self.conversationsTableView.register(UINib.init(nibName: conversationCellNibName, bundle: nil), forCellReuseIdentifier: conversationCellIdentifier)
- self.searchResultsTableView.register(UINib.init(nibName: conversationCellNibName, bundle: nil), forCellReuseIdentifier: conversationCellIdentifier)
+ self.conversationsTableView.register(cellType: ConversationCell.self)
+ self.searchResultsTableView.register(cellType: ConversationCell.self)
//Bind to ViewModel to show or hide the filtered results
self.viewModel.isSearching.subscribe(onNext: { isSearching in
self.searchResultsTableView.isHidden = !isSearching
- }).addDisposableTo(disposeBag)
+ }).disposed(by: disposeBag)
//Show the Messages screens and pass the viewModel for Conversations
self.conversationsTableView.rx.modelSelected(ConversationViewModel.self).subscribe(onNext: { item in
self.selectedItem = item
self.performSegue(withIdentifier: showMessages, sender: nil)
- }).addDisposableTo(disposeBag)
+ }).disposed(by: disposeBag)
//Show the Messages screens and pass the viewModel for Search Results
self.searchResultsTableView.rx.modelSelected(ConversationViewModel.self).subscribe(onNext: { item in
self.selectedItem = item
self.performSegue(withIdentifier: showMessages, sender: nil)
- }).addDisposableTo(disposeBag)
+ }).disposed(by: disposeBag)
//Deselect the rows
self.conversationsTableView.rx.itemSelected.subscribe(onNext: { [unowned self] indexPath in
self.conversationsTableView.deselectRow(at: indexPath, animated: true)
- }).addDisposableTo(disposeBag)
+ }).disposed(by: disposeBag)
self.searchResultsTableView.rx.itemSelected.subscribe(onNext: { [unowned self] indexPath in
self.searchResultsTableView.deselectRow(at: indexPath, animated: true)
- }).addDisposableTo(disposeBag)
+ }).disposed(by: disposeBag)
//Bind the search status label
self.viewModel.searchStatus
.observeOn(MainScheduler.instance)
.bind(to: self.searchTableViewLabel.rx.text)
- .addDisposableTo(disposeBag)
+ .disposed(by: disposeBag)
- self.searchResultsTableView.rx.setDelegate(self).addDisposableTo(disposeBag)
+ self.searchResultsTableView.rx.setDelegate(self).disposed(by: disposeBag)
//Swipe to delete action
- self.conversationsTableView.rx.itemDeleted.subscribe(onNext:{ [unowned self] indexPath in
- let convToDelete :ConversationViewModel = try! self.conversationsTableView.rx.model(at: indexPath)
- self.viewModel.delete(conversationViewModel: convToDelete)
- }).addDisposableTo(disposeBag)
+ self.conversationsTableView.rx.itemDeleted.subscribe(onNext: { [unowned self] indexPath in
+ if let convToDelete: ConversationViewModel = try? self.conversationsTableView.rx.model(at: indexPath) {
+ self.viewModel.delete(conversationViewModel: convToDelete)
+ }
+ }).disposed(by: disposeBag)
}
func setupSearchBar() {
@@ -217,29 +214,29 @@
//Bind the SearchBar to the ViewModel
self.searchBar.rx.text.orEmpty
- .debounce(textFieldThrottlingDuration, scheduler: MainScheduler.instance)
+ .debounce(Durations.textFieldThrottlingDuration.value, scheduler: MainScheduler.instance)
.bind(to: self.viewModel.searchBarText)
- .addDisposableTo(disposeBag)
+ .disposed(by: disposeBag)
//Show Cancel button
self.searchBar.rx.textDidBeginEditing.subscribe(onNext: { [unowned self] in
self.searchBar.setShowsCancelButton(true, animated: true)
- }).addDisposableTo(disposeBag)
+ }).disposed(by: disposeBag)
//Hide Cancel button
self.searchBar.rx.textDidEndEditing.subscribe(onNext: { [unowned self] in
self.searchBar.setShowsCancelButton(false, animated: true)
- }).addDisposableTo(disposeBag)
+ }).disposed(by: disposeBag)
//Cancel button event
self.searchBar.rx.cancelButtonClicked.subscribe(onNext: { [unowned self] in
self.cancelSearch()
- }).addDisposableTo(disposeBag)
+ }).disposed(by: disposeBag)
//Search button event
self.searchBar.rx.searchButtonClicked.subscribe(onNext: { [unowned self] in
self.searchBar.resignFirstResponder()
- }).addDisposableTo(disposeBag)
+ }).disposed(by: disposeBag)
}
func cancelSearch() {
diff --git a/Ring/Ring/Smartlist/SmartlistViewModel.swift b/Ring/Ring/Smartlist/SmartlistViewModel.swift
index 24fead9..7e2b1b0 100644
--- a/Ring/Ring/Smartlist/SmartlistViewModel.swift
+++ b/Ring/Ring/Smartlist/SmartlistViewModel.swift
@@ -87,13 +87,11 @@
var sections = [ConversationSection]()
if contactFoundConversation != nil {
- let headerTitle = NSLocalizedString("UserFound", tableName: "Smartlist", comment: "")
- sections.append(ConversationSection(header: headerTitle, items: [contactFoundConversation!]))
+ sections.append(ConversationSection(header: L10n.Smartlist.userFound.smartString, items: [contactFoundConversation!]))
}
if !filteredResults.isEmpty {
- let headerTitle = NSLocalizedString("Conversations", tableName: "Smartlist", comment: "")
- sections.append(ConversationSection(header: headerTitle, items: filteredResults))
+ sections.append(ConversationSection(header: L10n.Smartlist.conversations.smartString, items: filteredResults))
}
return sections
@@ -112,7 +110,7 @@
//Observes search bar text
searchBarText.asObservable().observeOn(MainScheduler.instance).subscribe(onNext: { [unowned self] text in
self.search(withText: text)
- }).addDisposableTo(disposeBag)
+ }).disposed(by: disposeBag)
//Observe username lookup
self.nameService.usernameLookupStatus.observeOn(MainScheduler.instance).subscribe(onNext: { usernameLookupStatus in
@@ -136,13 +134,12 @@
self.searchStatus.onNext("")
} else {
if self.filteredResults.value.isEmpty {
- let searchStatusText = NSLocalizedString("NoResults", tableName: "Smartlist", comment: "")
- self.searchStatus.onNext(searchStatusText)
+ self.searchStatus.onNext(L10n.Smartlist.noResults.smartString)
} else {
self.searchStatus.onNext("")
}
}
- }).addDisposableTo(disposeBag)
+ }).disposed(by: disposeBag)
}
fileprivate func search(withText text: String) {
@@ -167,8 +164,7 @@
}
self.nameService.lookupName(withAccount: "", nameserver: "", name: text)
- let searchStatusText = NSLocalizedString("Searching", tableName: "Smartlist", comment: "")
- self.searchStatus.onNext(searchStatusText)
+ self.searchStatus.onNext(L10n.Smartlist.searching.smartString)
}
}
@@ -180,7 +176,7 @@
self.conversationsService
.addConversation(conversation: selectedItem.conversation)
.subscribe()
- .addDisposableTo(disposeBag)
+ .disposed(by: disposeBag)
}
}
diff --git a/Ring/Ring/Constants/LocalizedStringTableNames.swift b/Ring/Ring/UI/DesignableButton.swift
similarity index 76%
copy from Ring/Ring/Constants/LocalizedStringTableNames.swift
copy to Ring/Ring/UI/DesignableButton.swift
index 72818c0..ad771dd 100644
--- a/Ring/Ring/Constants/LocalizedStringTableNames.swift
+++ b/Ring/Ring/UI/DesignableButton.swift
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2017 Savoir-faire Linux Inc.
+ * Copyright (C) 2016 Savoir-faire Linux Inc.
*
- * Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ * Author: Edric Ladent-Milaret <edric.ladent-milaret@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,8 +18,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-import Foundation
+import UIKit
-struct LocalizedStringTableNames {
- static let walkthrough = "Walkthrough"
+@IBDesignable
+class DesignableButton: UIButton {
+ // just to make the UIView+Ring extension IBDesignable
}
diff --git a/Ring/Ring/Constants/LocalizedStringTableNames.swift b/Ring/Ring/UI/DesignableTextField.swift
similarity index 86%
rename from Ring/Ring/Constants/LocalizedStringTableNames.swift
rename to Ring/Ring/UI/DesignableTextField.swift
index 72818c0..7e7f2da 100644
--- a/Ring/Ring/Constants/LocalizedStringTableNames.swift
+++ b/Ring/Ring/UI/DesignableTextField.swift
@@ -18,8 +18,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-import Foundation
+import UIKit
-struct LocalizedStringTableNames {
- static let walkthrough = "Walkthrough"
+@IBDesignable
+class DesignableTextField: UITextField {
+ // just to make the UIView+Ring extension IBDesignable
}
diff --git a/Ring/Ring/UI/RoundedButton.swift b/Ring/Ring/UI/RoundedButton.swift
deleted file mode 100644
index 1f51c4e..0000000
--- a/Ring/Ring/UI/RoundedButton.swift
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2016 Savoir-faire Linux Inc.
- *
- * Author: Edric Ladent-Milaret <edric.ladent-milaret@savoirfairelinux.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-import UIKit
-
-class RoundedButton: UIButton {
- required init?(coder aDecoder: NSCoder) {
- super.init(coder: aDecoder)
-
- //Button layout
- self.layer.borderColor = self.backgroundColor?.cgColor
- self.layer.borderWidth = 1.0
- self.clipsToBounds = true
- self.layer.cornerRadius = 15.0
- self.contentEdgeInsets = UIEdgeInsets(top: 8.0, left: 8.0, bottom: 8.0, right: 8.0)
-
- //Text colors
- self.setTitleColor(UIColor.white, for: .normal)
- self.setTitleColor(UIColor.gray, for: .disabled)
- }
-}
diff --git a/Ring/Ring/UI/RoundedTextField.swift b/Ring/Ring/UI/RoundedTextField.swift
deleted file mode 100644
index 5478afd..0000000
--- a/Ring/Ring/UI/RoundedTextField.swift
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2017 Savoir-faire Linux Inc.
- *
- * Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-import UIKit
-
-class RoundedTextField: UITextField {
-
- required init?(coder aDecoder: NSCoder) {
- super.init(coder: aDecoder)
- self.layer.borderColor = UIColor.white.cgColor
- self.layer.borderWidth = 1.0
- self.clipsToBounds = true
- }
-
- override func layoutSubviews() {
- super.layoutSubviews()
- self.layer.cornerRadius = self.frame.size.height / 2.0
- }
-
-}
diff --git a/Ring/Ring/Walkthrough/Cell/SwitchCell.swift b/Ring/Ring/Walkthrough/Cell/SwitchCell.swift
index 2c5214b..8f1ebde 100644
--- a/Ring/Ring/Walkthrough/Cell/SwitchCell.swift
+++ b/Ring/Ring/Walkthrough/Cell/SwitchCell.swift
@@ -19,8 +19,9 @@
*/
import UIKit
+import Reusable
-class SwitchCell: UITableViewCell {
+class SwitchCell: UITableViewCell, NibReusable {
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var registerSwitch: UISwitch!
diff --git a/Ring/Ring/Walkthrough/Cell/SwitchCell.xib b/Ring/Ring/Walkthrough/Cell/SwitchCell.xib
index a6dacee..d659bb2 100644
--- a/Ring/Ring/Walkthrough/Cell/SwitchCell.xib
+++ b/Ring/Ring/Walkthrough/Cell/SwitchCell.xib
@@ -1,21 +1,21 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
- <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
- <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="SwitchCellId" rowHeight="69" id="Yif-IF-81k" customClass="SwitchCell" customModule="Ring" customModuleProvider="target">
+ <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="69" id="Yif-IF-81k" customClass="SwitchCell" customModule="Ring" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="320" height="69"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Yif-IF-81k" id="EOF-e2-nje">
- <rect key="frame" x="0.0" y="0.0" width="320" height="68"/>
+ <rect key="frame" x="0.0" y="0.0" width="320" height="68.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" text="Register public username (experimental)" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tA2-KH-hQH">
diff --git a/Ring/Ring/Walkthrough/Cell/TextCell.swift b/Ring/Ring/Walkthrough/Cell/TextCell.swift
index 8e4f42f..829592b 100644
--- a/Ring/Ring/Walkthrough/Cell/TextCell.swift
+++ b/Ring/Ring/Walkthrough/Cell/TextCell.swift
@@ -19,8 +19,9 @@
*/
import UIKit
+import Reusable
-class TextCell: UITableViewCell {
+class TextCell: UITableViewCell, NibReusable {
@IBOutlet weak var label: UILabel!
diff --git a/Ring/Ring/Walkthrough/Cell/TextCell.xib b/Ring/Ring/Walkthrough/Cell/TextCell.xib
index 2501045..720806f 100644
--- a/Ring/Ring/Walkthrough/Cell/TextCell.xib
+++ b/Ring/Ring/Walkthrough/Cell/TextCell.xib
@@ -1,21 +1,21 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
- <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
- <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="TextCellId" rowHeight="69" id="6fR-7o-uTx" customClass="TextCell" customModule="Ring" customModuleProvider="target">
+ <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="69" id="6fR-7o-uTx" customClass="TextCell" customModule="Ring" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="320" height="69"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="6fR-7o-uTx" id="dja-bC-isJ">
- <rect key="frame" x="0.0" y="0.0" width="320" height="68"/>
+ <rect key="frame" x="0.0" y="0.0" width="320" height="68.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jFA-AW-xcV">
diff --git a/Ring/Ring/Walkthrough/Cell/TextFieldCell.swift b/Ring/Ring/Walkthrough/Cell/TextFieldCell.swift
index 3ca3796..47f31cd 100644
--- a/Ring/Ring/Walkthrough/Cell/TextFieldCell.swift
+++ b/Ring/Ring/Walkthrough/Cell/TextFieldCell.swift
@@ -19,8 +19,9 @@
*/
import UIKit
+import Reusable
-class TextFieldCell: UITableViewCell {
+class TextFieldCell: UITableViewCell, NibReusable {
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var errorMessageLabel: UILabel!
diff --git a/Ring/Ring/Walkthrough/Cell/TextFieldCell.xib b/Ring/Ring/Walkthrough/Cell/TextFieldCell.xib
index 51abaea..56900cf 100644
--- a/Ring/Ring/Walkthrough/Cell/TextFieldCell.xib
+++ b/Ring/Ring/Walkthrough/Cell/TextFieldCell.xib
@@ -1,24 +1,24 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
- <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
- <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="TextFieldCellId" rowHeight="80" id="U14-3B-dOe" customClass="TextFieldCell" customModule="Ring" customModuleProvider="target">
+ <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="80" id="U14-3B-dOe" customClass="TextFieldCell" customModule="Ring" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="320" height="80"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="U14-3B-dOe" id="4gJ-Ji-yr3">
- <rect key="frame" x="0.0" y="0.0" width="320" height="79"/>
+ <rect key="frame" x="0.0" y="0.0" width="320" height="79.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
- <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="let-RU-Vya" customClass="RoundedTextField" customModule="Ring" customModuleProvider="target">
+ <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="let-RU-Vya" customClass="DesignableTextField" customModule="Ring" customModuleProvider="target">
<rect key="frame" x="16" y="8" width="288" height="42"/>
<nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
diff --git a/Ring/Ring/Walkthrough/CreateRingAccountViewController.swift b/Ring/Ring/Walkthrough/CreateRingAccountViewController.swift
index 47584db..4f60f33 100644
--- a/Ring/Ring/Walkthrough/CreateRingAccountViewController.swift
+++ b/Ring/Ring/Walkthrough/CreateRingAccountViewController.swift
@@ -39,21 +39,13 @@
*/
private let log = SwiftyBeaver.self
- var mAccountViewModel = CreateRingAccountViewModel(withAccountService: AppDelegate.accountService,
+ var accountViewModel = CreateRingAccountViewModel(withAccountService: AppDelegate.accountService,
nameService: AppDelegate.nameService)
- @IBOutlet weak var mCreateAccountButton: RoundedButton!
- @IBOutlet weak var mCreateAccountTitleLabel: UILabel!
+ @IBOutlet weak var createAccountButton: DesignableButton!
+ @IBOutlet weak var createAccountTitleLabel: UILabel!
- /**
- Cell identifiers
- */
-
- let mSwitchCellId = "SwitchCellId"
- let mTextFieldCellId = "TextFieldCellId"
- let mTextCellId = "TextCellId"
-
- var mDisposeBag = DisposeBag()
+ var disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
@@ -66,15 +58,9 @@
}
func registerCells() {
- self.tableView.register(UINib.init(nibName: "SwitchCell", bundle: nil),
- forCellReuseIdentifier: mSwitchCellId)
-
- self.tableView.register(UINib.init(nibName: "TextFieldCell", bundle: nil),
- forCellReuseIdentifier: mTextFieldCellId)
-
- self.tableView.register(UINib.init(nibName: "TextCell", bundle: nil),
- forCellReuseIdentifier: mTextCellId)
-
+ self.tableView.register(cellType: SwitchCell.self)
+ self.tableView.register(cellType: TextFieldCell.self)
+ self.tableView.register(cellType: TextCell.self)
}
/**
@@ -84,17 +70,17 @@
fileprivate func bindViews() {
//Add Account button action
- self.mCreateAccountButton
+ self.createAccountButton
.rx
.tap
.takeUntil(self.rx.deallocated)
.subscribe(onNext: {
- self.mAccountViewModel.createAccount()
+ self.accountViewModel.createAccount()
})
- .addDisposableTo(self.mDisposeBag)
+ .disposed(by: self.disposeBag)
//Add Account Registration state
- self.mAccountViewModel.accountCreationState.observeOn(MainScheduler.instance).subscribe(
+ self.accountViewModel.accountCreationState.observeOn(MainScheduler.instance).subscribe(
onNext: { [unowned self] state in
switch state {
case .started:
@@ -112,18 +98,18 @@
self.showErrorAlert(error)
}
self.setCreateAccountAsIdle()
- }).addDisposableTo(mDisposeBag)
+ }).disposed(by: disposeBag)
//Show or hide user name field
- self.mAccountViewModel.registerUsername.asObservable()
+ self.accountViewModel.registerUsername.asObservable()
.subscribe(onNext: { [weak self] showUsernameField in
self?.toggleRegisterSwitch(showUsernameField)
- }).addDisposableTo(mDisposeBag)
+ }).disposed(by: disposeBag)
//Enables create account button
- self.mAccountViewModel.canCreateAccount
- .bind(to: self.mCreateAccountButton.rx.isEnabled)
- .addDisposableTo(mDisposeBag)
+ self.accountViewModel.canCreateAccount
+ .bind(to: self.createAccountButton.rx.isEnabled)
+ .disposed(by: disposeBag)
}
/**
@@ -133,43 +119,31 @@
fileprivate func setupUI() {
self.tableView.estimatedRowHeight = 44.0
self.tableView.rowHeight = UITableViewAutomaticDimension
-
- self.mCreateAccountTitleLabel.text = NSLocalizedString("CreateAccountFormTitle",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
+ self.createAccountTitleLabel.text = L10n.Createaccount.createAccountFormTitle.smartString
}
fileprivate func setCreateAccountAsLoading() {
log.debug("Creating account...")
- self.mCreateAccountButton.setTitle("Loading...", for: .normal)
- self.mCreateAccountButton.isUserInteractionEnabled = false
-
- let title = NSLocalizedString("WaitCreateAccountTitle",
- tableName:LocalizedStringTableNames.walkthrough,
- comment: "")
-
- HUD.show(.labeledProgress(title: title, subtitle: nil))
+ self.createAccountButton.setTitle(L10n.Createaccount.loading.smartString, for: .normal)
+ self.createAccountButton.isUserInteractionEnabled = false
+ HUD.show(.labeledProgress(title: L10n.Createaccount.waitCreateAccountTitle.smartString, subtitle: nil))
}
fileprivate func setCreateAccountAsIdle() {
- self.mCreateAccountButton.setTitle("Create a Ring account", for: .normal)
- self.mCreateAccountButton.isUserInteractionEnabled = true
+ self.createAccountButton.setTitle(L10n.Welcome.createAccount.smartString, for: .normal)
+ self.createAccountButton.isUserInteractionEnabled = true
HUD.hide()
}
fileprivate func showDeviceAddedAlert() {
- let title = NSLocalizedString("AccountAddedTitle",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
-
- HUD.flash(.labeledSuccess(title: title, subtitle: nil), delay: alertFlashDuration)
+ HUD.flash(.labeledSuccess(title: L10n.Alerts.accountAddedTitle.smartString, subtitle: nil), delay: Durations.alertFlashDuration.value)
}
fileprivate func showErrorAlert(_ error: AccountCreationError) {
let alert = UIAlertController.init(title: error.title,
message: error.message,
preferredStyle: .alert)
- alert.addAction(UIAlertAction.init(title: "OK", style: .default, handler: nil))
+ alert.addAction(UIAlertAction.init(title: L10n.Global.ok.smartString, style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
@@ -181,12 +155,12 @@
let usernameFieldCellIndex = 1
- if show && !mCells.contains(.usernameField) {
- self.mCells.insert(.usernameField, at: usernameFieldCellIndex)
+ if show && !cells.contains(.usernameField) {
+ self.cells.insert(.usernameField, at: usernameFieldCellIndex)
self.tableView.insertRows(at: [IndexPath(row: usernameFieldCellIndex, section: 0)],
with: .automatic)
- } else if !show && mCells.contains(.usernameField) {
- self.mCells.remove(at: usernameFieldCellIndex)
+ } else if !show && cells.contains(.usernameField) {
+ self.cells.remove(at: usernameFieldCellIndex)
self.tableView.deleteRows(at: [IndexPath(row: usernameFieldCellIndex, section: 0)],
with: .automatic)
}
@@ -194,7 +168,7 @@
}
// MARK: TableView datasource
- fileprivate var mCells: [CreateRingAccountCellType] = [.registerPublicUsername,
+ fileprivate var cells: [CreateRingAccountCellType] = [.registerPublicUsername,
.passwordNotice,
.newPasswordField,
.repeatPasswordField]
@@ -204,128 +178,84 @@
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- return mCells.count
+ return cells.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- let currentCellType = mCells[indexPath.row]
+ let currentCellType = cells[indexPath.row]
if currentCellType == .registerPublicUsername {
- if let cell = tableView.dequeueReusableCell(withIdentifier: mSwitchCellId,
- for: indexPath) as? SwitchCell {
- cell.titleLabel.text = NSLocalizedString("RegisterPublicUsername",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
- cell.titleLabel.textColor = .white
+ let cell = tableView.dequeueReusableCell(for: indexPath, cellType: SwitchCell.self)
- _ = cell.registerSwitch.rx.value.bind(to: self.mAccountViewModel.registerUsername)
- .addDisposableTo(mDisposeBag)
-
- return cell
- } else {
- return tableView.dequeueReusableCell(withIdentifier: mSwitchCellId, for: indexPath)
- }
-
+ cell.titleLabel.text = L10n.Createaccount.registerPublicUsername.smartString
+ cell.titleLabel.textColor = .white
+ cell.registerSwitch.rx.value.bind(to: self.accountViewModel.registerUsername).disposed(by: disposeBag)
+ return cell
} else if currentCellType == .usernameField {
- if let cell = tableView.dequeueReusableCell(withIdentifier: mTextFieldCellId,
- for: indexPath) as? TextFieldCell {
- cell.textField.isSecureTextEntry = false
- cell.textField.placeholder = NSLocalizedString("EnterNewUsernamePlaceholder",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
+ let cell = tableView.dequeueReusableCell(for: indexPath, cellType: TextFieldCell.self)
- //Binds the username field value to the ViewModel
- _ = cell.textField.rx.text.orEmpty
- .throttle(textFieldThrottlingDuration, scheduler: MainScheduler.instance)
- .distinctUntilChanged()
- .bind(to: self.mAccountViewModel.username)
- .addDisposableTo(mDisposeBag)
+ cell.textField.isSecureTextEntry = false
+ cell.textField.placeholder = L10n.Createaccount.enterNewUsernamePlaceholder.smartString
- //Switch to new password cell when return button is touched
- _ = cell.textField.rx.controlEvent(.editingDidEndOnExit).subscribe(onNext: {
- self.switchToCell(withType: .newPasswordField)
- }).addDisposableTo(mDisposeBag)
+ //Binds the username field value to the ViewModel
+ cell.textField.rx.text.orEmpty
+ .throttle(Durations.textFieldThrottlingDuration.value, scheduler: MainScheduler.instance)
+ .distinctUntilChanged()
+ .bind(to: self.accountViewModel.username)
+ .disposed(by: disposeBag)
- _ = self.mAccountViewModel.usernameValidationMessage
- .bind(to: cell.errorMessageLabel.rx.text)
- .addDisposableTo(mDisposeBag)
+ //Switch to new password cell when return button is touched
+ cell.textField.rx.controlEvent(.editingDidEndOnExit).subscribe(onNext: {
+ self.switchToCell(withType: .newPasswordField)
+ }).disposed(by: disposeBag)
- return cell
- } else {
- return tableView.dequeueReusableCell(withIdentifier: mTextFieldCellId, for: indexPath)
- }
-
+ self.accountViewModel.usernameValidationMessage.bind(to: cell.errorMessageLabel.rx.text).disposed(by: disposeBag)
+ return cell
} else if currentCellType == .passwordNotice {
- if let cell = tableView.dequeueReusableCell(withIdentifier: mTextCellId, for: indexPath) as? TextCell {
- cell.label.text = NSLocalizedString("ChooseStrongPassword",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
- return cell
- } else {
- return tableView.dequeueReusableCell(withIdentifier: mTextCellId, for: indexPath)
- }
-
+ let cell = tableView.dequeueReusableCell(for: indexPath, cellType: TextCell.self)
+ cell.label.text = L10n.Createaccount.chooseStrongPassword.smartString
+ return cell
} else if currentCellType == .newPasswordField {
- if let cell = tableView.dequeueReusableCell(withIdentifier: mTextFieldCellId,
- for: indexPath) as? TextFieldCell {
- cell.textField.isSecureTextEntry = true
- cell.textField.placeholder = NSLocalizedString("NewPasswordPlaceholder",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
+ let cell = tableView.dequeueReusableCell(for: indexPath, cellType: TextFieldCell.self)
- cell.errorMessageLabel.text = NSLocalizedString("PasswordCharactersNumberError",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
+ cell.textField.isSecureTextEntry = true
+ cell.textField.placeholder = L10n.Createaccount.newPasswordPlaceholder.smartString
+ cell.errorMessageLabel.text = L10n.Createaccount.passwordCharactersNumberError.smartString
- //Binds the password field value to the ViewModel
- _ = cell.textField.rx.text.orEmpty.bind(to: self.mAccountViewModel.password)
- .addDisposableTo(mDisposeBag)
+ //Binds the password field value to the ViewModel
+ cell.textField.rx.text.orEmpty.bind(to: self.accountViewModel.password).disposed(by: disposeBag)
- //Binds the observer to show the error label if the field is not empty
- _ = self.mAccountViewModel.hidePasswordError.bind(to: cell.errorMessageLabel.rx.isHidden)
- .addDisposableTo(mDisposeBag)
+ //Binds the observer to show the error label if the field is not empty
+ self.accountViewModel.hidePasswordError.bind(to: cell.errorMessageLabel.rx.isHidden).disposed(by: disposeBag)
- //Switch to the repeat pasword cell when return button is touched
- _ = cell.textField.rx.controlEvent(.editingDidEndOnExit)
- .subscribe(onNext: {
- self.switchToCell(withType: .repeatPasswordField)
- }).addDisposableTo(mDisposeBag)
+ //Switch to the repeat pasword cell when return button is touched
+ cell.textField.rx.controlEvent(.editingDidEndOnExit)
+ .subscribe(onNext: {
+ self.switchToCell(withType: .repeatPasswordField)
+ }).disposed(by: disposeBag)
- return cell
- } else {
- return tableView.dequeueReusableCell(withIdentifier: mTextFieldCellId, for: indexPath)
- }
-
+ return cell
} else {
- if let cell = tableView.dequeueReusableCell(withIdentifier: mTextFieldCellId,
- for: indexPath) as? TextFieldCell {
- cell.textField.isSecureTextEntry = true
- cell.textField.placeholder = NSLocalizedString("RepeatPasswordPlaceholder",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
+ let cell = tableView.dequeueReusableCell(for: indexPath, cellType: TextFieldCell.self)
- cell.errorMessageLabel.text = NSLocalizedString("PasswordNotMatchingError",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
+ cell.textField.isSecureTextEntry = true
+ cell.textField.placeholder = L10n.Createaccount.repeatPasswordPlaceholder.smartString
+ cell.errorMessageLabel.text = L10n.Createaccount.passwordNotMatchingError.smartString
- //Binds the repeat password field value to the ViewModel
- _ = cell.textField.rx.text.orEmpty.bind(to: self.mAccountViewModel.repeatPassword)
- .addDisposableTo(mDisposeBag)
+ //Binds the repeat password field value to the ViewModel
+ cell.textField.rx.text.orEmpty.bind(to: self.accountViewModel.repeatPassword).disposed(by: disposeBag)
- //Binds the observer to the text field 'hidden' property
- _ = self.mAccountViewModel.hideRepeatPasswordError.bind(to: cell.errorMessageLabel.rx.isHidden)
- .addDisposableTo(mDisposeBag)
+ //Binds the observer to the text field 'hidden' property
+ self.accountViewModel.hideRepeatPasswordError.bind(to: cell.errorMessageLabel.rx.isHidden).disposed(by: disposeBag)
- return cell
- } else {
- return tableView.dequeueReusableCell(withIdentifier: mTextFieldCellId, for: indexPath)
- }
+ return cell
+
}
}
fileprivate func switchToCell(withType cellType: CreateRingAccountCellType) {
- if let cellIndex = self.mCells.index(of: cellType) {
+ if let cellIndex = self.cells.index(of: cellType) {
if let cell = tableView.cellForRow(at: IndexPath(row: cellIndex, section: 0))
as? TextFieldCell {
cell.textField.becomeFirstResponder()
diff --git a/Ring/Ring/Walkthrough/WalkthroughStoryboard.storyboard b/Ring/Ring/Walkthrough/WalkthroughStoryboard.storyboard
index 80b5584..b56028f 100644
--- a/Ring/Ring/Walkthrough/WalkthroughStoryboard.storyboard
+++ b/Ring/Ring/Walkthrough/WalkthroughStoryboard.storyboard
@@ -1,11 +1,11 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="GnB-zf-djy">
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="GnB-zf-djy">
<device id="retina3_5" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
- <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
@@ -42,7 +42,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="DXu-A1-gcl">
- <rect key="frame" x="25" y="100" width="271" height="280"/>
+ <rect key="frame" x="25" y="90" width="271" height="300"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" verticalHuggingPriority="251" image="logo-ring-beta2-blanc" translatesAutoresizingMaskIntoConstraints="NO" id="7CK-fT-m09">
<rect key="frame" x="45.5" y="0.0" width="180" height="66"/>
@@ -64,28 +64,34 @@
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
- <button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="R0q-9u-3WR" customClass="RoundedButton" customModule="Ring" customModuleProvider="target">
- <rect key="frame" x="33.5" y="204" width="204" height="30"/>
+ <button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="R0q-9u-3WR" customClass="DesignableButton" customModule="Ring" customModuleProvider="target">
+ <rect key="frame" x="20" y="204" width="231" height="40"/>
<color key="backgroundColor" red="0.0" green="0.29803921570000003" blue="0.37647058820000001" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
- <constraint firstAttribute="height" constant="30" id="d0X-Cl-Ry4"/>
+ <constraint firstAttribute="height" constant="40" id="d0X-Cl-Ry4"/>
</constraints>
<state key="normal" title="Link this device to an account">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/>
+ </userDefinedRuntimeAttributes>
<connections>
<action selector="linkDeviceToAccountAction:" destination="zOM-us-BHp" eventType="touchUpInside" id="bul-x6-xBK"/>
</connections>
</button>
- <button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8Ve-ZD-TXf" customClass="RoundedButton" customModule="Ring" customModuleProvider="target">
- <rect key="frame" x="33.5" y="250" width="204" height="30"/>
+ <button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8Ve-ZD-TXf" customClass="DesignableButton" customModule="Ring" customModuleProvider="target">
+ <rect key="frame" x="20" y="260" width="231" height="40"/>
<color key="backgroundColor" red="0.0" green="0.29803921570000003" blue="0.37647058820000001" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
- <constraint firstAttribute="height" constant="30" id="5Qb-T3-Su0"/>
+ <constraint firstAttribute="height" constant="40" id="5Qb-T3-Su0"/>
</constraints>
<state key="normal" title="Create a Ring account">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/>
+ </userDefinedRuntimeAttributes>
<connections>
<action selector="createAccountAction:" destination="zOM-us-BHp" eventType="touchUpInside" id="o0k-MC-tsv"/>
</connections>
@@ -93,9 +99,9 @@
</subviews>
<constraints>
<constraint firstItem="8Ve-ZD-TXf" firstAttribute="leading" secondItem="R0q-9u-3WR" secondAttribute="leading" id="U0b-w9-yjf"/>
- <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="R0q-9u-3WR" secondAttribute="trailing" constant="32" id="WpG-GI-pPu"/>
+ <constraint firstAttribute="trailing" secondItem="R0q-9u-3WR" secondAttribute="trailing" constant="20" id="WpG-GI-pPu"/>
<constraint firstItem="8Ve-ZD-TXf" firstAttribute="trailing" secondItem="R0q-9u-3WR" secondAttribute="trailing" id="bE8-0O-Ead"/>
- <constraint firstItem="R0q-9u-3WR" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="DXu-A1-gcl" secondAttribute="leading" constant="32" id="yWE-sO-6tc"/>
+ <constraint firstItem="R0q-9u-3WR" firstAttribute="leading" secondItem="DXu-A1-gcl" secondAttribute="leading" constant="20" id="yWE-sO-6tc"/>
</constraints>
</stackView>
</subviews>
@@ -135,12 +141,19 @@
<rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
- <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8M5-AJ-pxH" customClass="RoundedButton" customModule="Ring" customModuleProvider="target">
- <rect key="frame" x="145" y="225" width="30" height="30"/>
+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8M5-AJ-pxH" customClass="DesignableButton" customModule="Ring" customModuleProvider="target">
+ <rect key="frame" x="110" y="220" width="100" height="40"/>
<color key="backgroundColor" red="0.0" green="0.29803921570000003" blue="0.37647058820000001" alpha="1" colorSpace="calibratedRGB"/>
+ <constraints>
+ <constraint firstAttribute="width" constant="100" id="2t1-a8-dxY"/>
+ <constraint firstAttribute="height" constant="40" id="cln-HK-ZE8"/>
+ </constraints>
<state key="normal" title="Skip">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/>
+ </userDefinedRuntimeAttributes>
<connections>
<action selector="skip:" destination="dmb-i6-bo9" eventType="touchUpInside" id="PAR-5w-VRm"/>
</connections>
@@ -192,22 +205,25 @@
<rect key="frame" x="0.0" y="130" width="320" height="54"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
- <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="UQJ-hF-j2O" customClass="RoundedButton" customModule="Ring" customModuleProvider="target">
- <rect key="frame" x="120.5" y="8" width="79" height="30"/>
+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="UQJ-hF-j2O" customClass="DesignableButton" customModule="Ring" customModuleProvider="target">
+ <rect key="frame" x="110" y="7" width="100" height="40"/>
<color key="backgroundColor" red="0.0" green="0.29803921570000003" blue="0.37647058820000001" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
- <constraint firstAttribute="height" constant="30" id="RGF-Ib-dT9"/>
+ <constraint firstAttribute="height" constant="40" id="RGF-Ib-dT9"/>
+ <constraint firstAttribute="width" constant="100" id="p9O-j8-fcB"/>
</constraints>
<state key="normal" title="Link Device">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/>
+ </userDefinedRuntimeAttributes>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="UQJ-hF-j2O" firstAttribute="centerX" secondItem="bQ2-6Y-CIW" secondAttribute="centerX" id="7LD-pW-9BH"/>
- <constraint firstItem="UQJ-hF-j2O" firstAttribute="top" secondItem="bQ2-6Y-CIW" secondAttribute="top" constant="8" id="FY8-ef-pse"/>
- <constraint firstAttribute="bottom" secondItem="UQJ-hF-j2O" secondAttribute="bottom" constant="16" id="pmA-aY-Do4"/>
+ <constraint firstItem="UQJ-hF-j2O" firstAttribute="centerY" secondItem="bQ2-6Y-CIW" secondAttribute="centerY" id="f6F-dX-f0m"/>
</constraints>
</view>
<connections>
@@ -251,21 +267,25 @@
<rect key="frame" x="0.0" y="130" width="320" height="54"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
- <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="gsT-SB-0AP" customClass="RoundedButton" customModule="Ring" customModuleProvider="target">
- <rect key="frame" x="84" y="8" width="152" height="30"/>
+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="gsT-SB-0AP" customClass="DesignableButton" customModule="Ring" customModuleProvider="target">
+ <rect key="frame" x="70" y="7" width="180" height="40"/>
<color key="backgroundColor" red="0.0" green="0.29803921570000003" blue="0.37647058820000001" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
- <constraint firstAttribute="height" constant="30" id="KVf-AW-ms7"/>
+ <constraint firstAttribute="height" constant="40" id="b0c-dD-zDx"/>
</constraints>
<state key="normal" title="Create a Ring account">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="boolean" keyPath="roundedCorners" value="YES"/>
+ </userDefinedRuntimeAttributes>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
- <constraint firstItem="gsT-SB-0AP" firstAttribute="top" secondItem="MnN-De-arJ" secondAttribute="top" constant="8" id="pqs-B0-TWU"/>
- <constraint firstAttribute="bottom" secondItem="gsT-SB-0AP" secondAttribute="bottom" constant="16" id="qOI-R4-9EJ"/>
+ <constraint firstAttribute="trailing" secondItem="gsT-SB-0AP" secondAttribute="trailing" constant="70" id="MsB-8o-KHc"/>
+ <constraint firstItem="gsT-SB-0AP" firstAttribute="leading" secondItem="MnN-De-arJ" secondAttribute="leading" constant="70" id="PjH-ny-nr4"/>
+ <constraint firstItem="gsT-SB-0AP" firstAttribute="centerY" secondItem="MnN-De-arJ" secondAttribute="centerY" id="gt1-U3-e6s"/>
<constraint firstItem="gsT-SB-0AP" firstAttribute="centerX" secondItem="MnN-De-arJ" secondAttribute="centerX" id="tMA-Qg-oxa"/>
</constraints>
</view>
@@ -275,14 +295,14 @@
</connections>
</tableView>
<connections>
- <outlet property="mCreateAccountButton" destination="gsT-SB-0AP" id="9Fj-aJ-0Ik"/>
- <outlet property="mCreateAccountTitleLabel" destination="AIX-eC-baN" id="YUL-yb-Ecy"/>
+ <outlet property="createAccountButton" destination="gsT-SB-0AP" id="SxP-Y3-eoo"/>
+ <outlet property="createAccountTitleLabel" destination="AIX-eC-baN" id="kg4-gi-v7Q"/>
<segue destination="E3W-r7-J4y" kind="show" identifier="AccountToPermissionsSegue" id="Zig-iC-h9U"/>
</connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="W0G-TV-Z9c" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
- <point key="canvasLocation" x="2078" y="581"/>
+ <point key="canvasLocation" x="2077.5" y="580"/>
</scene>
<!--View Controller-->
<scene sceneID="c8H-6M-3dO">
diff --git a/Ring/Ring/Walkthrough/WelcomeViewController.swift b/Ring/Ring/Walkthrough/WelcomeViewController.swift
index 5f6c478..29892dd 100644
--- a/Ring/Ring/Walkthrough/WelcomeViewController.swift
+++ b/Ring/Ring/Walkthrough/WelcomeViewController.swift
@@ -24,8 +24,8 @@
@IBOutlet weak var welcomeLabel: UILabel!
@IBOutlet weak var descriptionLabel: UILabel!
- @IBOutlet weak var linkDeviceButton: RoundedButton!
- @IBOutlet weak var createAccountButton: RoundedButton!
+ @IBOutlet weak var linkDeviceButton: DesignableButton!
+ @IBOutlet weak var createAccountButton: DesignableButton!
let createProfileSegueIdentifier = "CreateProfileSegue"
let linkDeviceToAccountSegueIdentifier = "LinkDeviceToAccountSegue"
@@ -74,17 +74,9 @@
func setupUI() {
- self.welcomeLabel.text = NSLocalizedString("WelcomeTitle",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
- self.descriptionLabel.text = NSLocalizedString("WelcomeText",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: "")
- self.linkDeviceButton.setTitle(NSLocalizedString("LinkDeviceButton",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: ""), for: .normal)
- self.createAccountButton.setTitle(NSLocalizedString("CreateAccount",
- tableName: LocalizedStringTableNames.walkthrough,
- comment: ""), for: .normal)
+ self.welcomeLabel.text = L10n.Welcome.title.smartString
+ self.descriptionLabel.text = L10n.Welcome.text.smartString
+ self.linkDeviceButton.setTitle(L10n.Welcome.linkDeviceButton.smartString, for: .normal)
+ self.createAccountButton.setTitle(L10n.Welcome.createAccount.smartString, for: .normal)
}
}