2
0

Unlock and user preferences implementation.

[FIXED]     Unlock screen.
[FIXED]     Internal fixes.
[ADDED]     Avatar selection in preferences.
[ADDED]     Implementation of the other preferences.
[IMPROVED]  UI of unlock and preferences screens.
This commit is contained in:
Maarten Billemont 2012-06-06 00:59:09 +02:00
parent 0491ba3f97
commit 77306e0046
53 changed files with 648 additions and 571 deletions

2
External/Pearl vendored

@ -1 +1 @@
Subproject commit 1ce39007b6018ac4991b4ec0ee5158ba019bcac1 Subproject commit e9dd56bc64735ebd28eef6c6dc748f480acc7c67

View File

@ -41,44 +41,6 @@
DA600C2815056428008E9AB6 /* MPConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = DA600C2715056427008E9AB6 /* MPConfig.m */; }; DA600C2815056428008E9AB6 /* MPConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = DA600C2715056427008E9AB6 /* MPConfig.m */; };
DA672D2F14F92C6B004A189C /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DA672D2E14F92C6B004A189C /* libz.dylib */; }; DA672D2F14F92C6B004A189C /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DA672D2E14F92C6B004A189C /* libz.dylib */; };
DA672D3014F9413D004A189C /* libPearl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC77CAD148291A600BCF976 /* libPearl.a */; }; DA672D3014F9413D004A189C /* libPearl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC77CAD148291A600BCF976 /* libPearl.a */; };
DA7DEFE8157978AC009D2085 /* avatar-female-1.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFC2157978AC009D2085 /* avatar-female-1.png */; };
DA7DEFE9157978AC009D2085 /* avatar-female-1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFC3157978AC009D2085 /* avatar-female-1@2x.png */; };
DA7DEFEA157978AC009D2085 /* avatar-female-2.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFC4157978AC009D2085 /* avatar-female-2.png */; };
DA7DEFEB157978AC009D2085 /* avatar-female-2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFC5157978AC009D2085 /* avatar-female-2@2x.png */; };
DA7DEFEC157978AC009D2085 /* avatar-female-silhouette-1.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFC6157978AC009D2085 /* avatar-female-silhouette-1.png */; };
DA7DEFED157978AC009D2085 /* avatar-female-silhouette-1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFC7157978AC009D2085 /* avatar-female-silhouette-1@2x.png */; };
DA7DEFEE157978AC009D2085 /* avatar-female-silhouette-2.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFC8157978AC009D2085 /* avatar-female-silhouette-2.png */; };
DA7DEFEF157978AC009D2085 /* avatar-female-silhouette-2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFC9157978AC009D2085 /* avatar-female-silhouette-2@2x.png */; };
DA7DEFF0157978AC009D2085 /* avatar-female-silhouette-3.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFCA157978AC009D2085 /* avatar-female-silhouette-3.png */; };
DA7DEFF1157978AC009D2085 /* avatar-female-silhouette-3@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFCB157978AC009D2085 /* avatar-female-silhouette-3@2x.png */; };
DA7DEFF2157978AC009D2085 /* avatar-female-silhouette-4.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFCC157978AC009D2085 /* avatar-female-silhouette-4.png */; };
DA7DEFF3157978AC009D2085 /* avatar-female-silhouette-4@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFCD157978AC009D2085 /* avatar-female-silhouette-4@2x.png */; };
DA7DEFF4157978AC009D2085 /* avatar-female-silhouette-5.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFCE157978AC009D2085 /* avatar-female-silhouette-5.png */; };
DA7DEFF5157978AC009D2085 /* avatar-female-silhouette-5@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFCF157978AC009D2085 /* avatar-female-silhouette-5@2x.png */; };
DA7DEFF6157978AC009D2085 /* avatar-female-silhouette-6.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFD0157978AC009D2085 /* avatar-female-silhouette-6.png */; };
DA7DEFF7157978AC009D2085 /* avatar-female-silhouette-6@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFD1157978AC009D2085 /* avatar-female-silhouette-6@2x.png */; };
DA7DEFF8157978AC009D2085 /* avatar-female-silhouette-7.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFD2157978AC009D2085 /* avatar-female-silhouette-7.png */; };
DA7DEFF9157978AC009D2085 /* avatar-female-silhouette-7@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFD3157978AC009D2085 /* avatar-female-silhouette-7@2x.png */; };
DA7DEFFA157978AC009D2085 /* avatar-male-1.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFD4157978AC009D2085 /* avatar-male-1.png */; };
DA7DEFFB157978AC009D2085 /* avatar-male-1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFD5157978AC009D2085 /* avatar-male-1@2x.png */; };
DA7DEFFC157978AC009D2085 /* avatar-male-2.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFD6157978AC009D2085 /* avatar-male-2.png */; };
DA7DEFFD157978AC009D2085 /* avatar-male-2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFD7157978AC009D2085 /* avatar-male-2@2x.png */; };
DA7DEFFE157978AC009D2085 /* avatar-male-3.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFD8157978AC009D2085 /* avatar-male-3.png */; };
DA7DEFFF157978AC009D2085 /* avatar-male-3@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFD9157978AC009D2085 /* avatar-male-3@2x.png */; };
DA7DF000157978AC009D2085 /* avatar-male-silhouette-1.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFDA157978AC009D2085 /* avatar-male-silhouette-1.png */; };
DA7DF001157978AC009D2085 /* avatar-male-silhouette-1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFDB157978AC009D2085 /* avatar-male-silhouette-1@2x.png */; };
DA7DF002157978AC009D2085 /* avatar-male-silhouette-2.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFDC157978AC009D2085 /* avatar-male-silhouette-2.png */; };
DA7DF003157978AC009D2085 /* avatar-male-silhouette-2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFDD157978AC009D2085 /* avatar-male-silhouette-2@2x.png */; };
DA7DF004157978AC009D2085 /* avatar-male-silhouette-3.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFDE157978AC009D2085 /* avatar-male-silhouette-3.png */; };
DA7DF005157978AC009D2085 /* avatar-male-silhouette-3@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFDF157978AC009D2085 /* avatar-male-silhouette-3@2x.png */; };
DA7DF006157978AC009D2085 /* avatar-male-silhouette-4.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFE0157978AC009D2085 /* avatar-male-silhouette-4.png */; };
DA7DF007157978AC009D2085 /* avatar-male-silhouette-4@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFE1157978AC009D2085 /* avatar-male-silhouette-4@2x.png */; };
DA7DF008157978AC009D2085 /* avatar-male-silhouette-5.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFE2157978AC009D2085 /* avatar-male-silhouette-5.png */; };
DA7DF009157978AC009D2085 /* avatar-male-silhouette-5@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFE3157978AC009D2085 /* avatar-male-silhouette-5@2x.png */; };
DA7DF00A157978AC009D2085 /* avatar-male-silhouette-6.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFE4157978AC009D2085 /* avatar-male-silhouette-6.png */; };
DA7DF00B157978AC009D2085 /* avatar-male-silhouette-6@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFE5157978AC009D2085 /* avatar-male-silhouette-6@2x.png */; };
DA7DF00C157978AC009D2085 /* avatar-male-silhouette-7.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFE6157978AC009D2085 /* avatar-male-silhouette-7.png */; };
DA7DF00D157978AC009D2085 /* avatar-male-silhouette-7@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7DEFE7157978AC009D2085 /* avatar-male-silhouette-7@2x.png */; };
DA95D59D14DF063C008D1B94 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; }; DA95D59D14DF063C008D1B94 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; };
DA95D5CF14DF0691008D1B94 /* IASKAppSettingsViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = DA95D5A814DF0691008D1B94 /* IASKAppSettingsViewController.h */; }; DA95D5CF14DF0691008D1B94 /* IASKAppSettingsViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = DA95D5A814DF0691008D1B94 /* IASKAppSettingsViewController.h */; };
DA95D5D014DF0691008D1B94 /* IASKAppSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DA95D5A914DF0691008D1B94 /* IASKAppSettingsViewController.m */; }; DA95D5D014DF0691008D1B94 /* IASKAppSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DA95D5A914DF0691008D1B94 /* IASKAppSettingsViewController.m */; };
@ -744,6 +706,44 @@
DAD312BE1552977200A3F9ED /* UIColor+HSV.m in Sources */ = {isa = PBXBuildFile; fileRef = DAD312BA1552977200A3F9ED /* UIColor+HSV.m */; }; DAD312BE1552977200A3F9ED /* UIColor+HSV.m in Sources */ = {isa = PBXBuildFile; fileRef = DAD312BA1552977200A3F9ED /* UIColor+HSV.m */; };
DAD312BF1552A1BD00A3F9ED /* libLocalytics.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAD3127115528CD200A3F9ED /* libLocalytics.a */; }; DAD312BF1552A1BD00A3F9ED /* libLocalytics.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAD3127115528CD200A3F9ED /* libLocalytics.a */; };
DAD312C21552A22700A3F9ED /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DAD312C01552A20800A3F9ED /* libsqlite3.dylib */; }; DAD312C21552A22700A3F9ED /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DAD312C01552A20800A3F9ED /* libsqlite3.dylib */; };
DAE4C969157E63BE00EFE047 /* avatar-0.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C943157E63BE00EFE047 /* avatar-0.png */; };
DAE4C96A157E63BE00EFE047 /* avatar-0@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C944157E63BE00EFE047 /* avatar-0@2x.png */; };
DAE4C96B157E63BE00EFE047 /* avatar-1.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C945157E63BE00EFE047 /* avatar-1.png */; };
DAE4C96C157E63BE00EFE047 /* avatar-1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C946157E63BE00EFE047 /* avatar-1@2x.png */; };
DAE4C96D157E63BE00EFE047 /* avatar-2.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C947157E63BE00EFE047 /* avatar-2.png */; };
DAE4C96E157E63BE00EFE047 /* avatar-2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C948157E63BE00EFE047 /* avatar-2@2x.png */; };
DAE4C96F157E63BE00EFE047 /* avatar-3.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C949157E63BE00EFE047 /* avatar-3.png */; };
DAE4C970157E63BE00EFE047 /* avatar-3@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C94A157E63BE00EFE047 /* avatar-3@2x.png */; };
DAE4C971157E63BE00EFE047 /* avatar-4.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C94B157E63BE00EFE047 /* avatar-4.png */; };
DAE4C972157E63BE00EFE047 /* avatar-4@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C94C157E63BE00EFE047 /* avatar-4@2x.png */; };
DAE4C973157E63BE00EFE047 /* avatar-5.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C94D157E63BE00EFE047 /* avatar-5.png */; };
DAE4C974157E63BE00EFE047 /* avatar-5@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C94E157E63BE00EFE047 /* avatar-5@2x.png */; };
DAE4C975157E63BE00EFE047 /* avatar-6.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C94F157E63BE00EFE047 /* avatar-6.png */; };
DAE4C976157E63BE00EFE047 /* avatar-6@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C950157E63BE00EFE047 /* avatar-6@2x.png */; };
DAE4C977157E63BE00EFE047 /* avatar-7.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C951157E63BE00EFE047 /* avatar-7.png */; };
DAE4C978157E63BE00EFE047 /* avatar-7@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C952157E63BE00EFE047 /* avatar-7@2x.png */; };
DAE4C979157E63BE00EFE047 /* avatar-8.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C953157E63BE00EFE047 /* avatar-8.png */; };
DAE4C97A157E63BE00EFE047 /* avatar-8@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C954157E63BE00EFE047 /* avatar-8@2x.png */; };
DAE4C97B157E63BE00EFE047 /* avatar-9.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C955157E63BE00EFE047 /* avatar-9.png */; };
DAE4C97C157E63BE00EFE047 /* avatar-9@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C956157E63BE00EFE047 /* avatar-9@2x.png */; };
DAE4C97D157E63BE00EFE047 /* avatar-10.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C957157E63BE00EFE047 /* avatar-10.png */; };
DAE4C97E157E63BE00EFE047 /* avatar-10@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C958157E63BE00EFE047 /* avatar-10@2x.png */; };
DAE4C97F157E63BE00EFE047 /* avatar-11.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C959157E63BE00EFE047 /* avatar-11.png */; };
DAE4C980157E63BE00EFE047 /* avatar-11@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C95A157E63BE00EFE047 /* avatar-11@2x.png */; };
DAE4C981157E63BE00EFE047 /* avatar-12.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C95B157E63BE00EFE047 /* avatar-12.png */; };
DAE4C982157E63BE00EFE047 /* avatar-12@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C95C157E63BE00EFE047 /* avatar-12@2x.png */; };
DAE4C983157E63BE00EFE047 /* avatar-13.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C95D157E63BE00EFE047 /* avatar-13.png */; };
DAE4C984157E63BE00EFE047 /* avatar-13@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C95E157E63BE00EFE047 /* avatar-13@2x.png */; };
DAE4C985157E63BE00EFE047 /* avatar-14.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C95F157E63BE00EFE047 /* avatar-14.png */; };
DAE4C986157E63BE00EFE047 /* avatar-14@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C960157E63BE00EFE047 /* avatar-14@2x.png */; };
DAE4C987157E63BE00EFE047 /* avatar-15.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C961157E63BE00EFE047 /* avatar-15.png */; };
DAE4C988157E63BE00EFE047 /* avatar-15@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C962157E63BE00EFE047 /* avatar-15@2x.png */; };
DAE4C989157E63BE00EFE047 /* avatar-16.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C963157E63BE00EFE047 /* avatar-16.png */; };
DAE4C98A157E63BE00EFE047 /* avatar-16@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C964157E63BE00EFE047 /* avatar-16@2x.png */; };
DAE4C98B157E63BE00EFE047 /* avatar-17.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C965157E63BE00EFE047 /* avatar-17.png */; };
DAE4C98C157E63BE00EFE047 /* avatar-17@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C966157E63BE00EFE047 /* avatar-17@2x.png */; };
DAE4C98D157E63BE00EFE047 /* avatar-18.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C967157E63BE00EFE047 /* avatar-18.png */; };
DAE4C98E157E63BE00EFE047 /* avatar-18@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE4C968157E63BE00EFE047 /* avatar-18@2x.png */; };
DAEBC45314F6364500987BF6 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAEBC45214F6364500987BF6 /* QuartzCore.framework */; }; DAEBC45314F6364500987BF6 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAEBC45214F6364500987BF6 /* QuartzCore.framework */; };
DAFE4A1315039824003ABA7C /* NSObject_PearlExport.h in Headers */ = {isa = PBXBuildFile; fileRef = DAFE45D815039823003ABA7C /* NSObject_PearlExport.h */; }; DAFE4A1315039824003ABA7C /* NSObject_PearlExport.h in Headers */ = {isa = PBXBuildFile; fileRef = DAFE45D815039823003ABA7C /* NSObject_PearlExport.h */; };
DAFE4A1415039824003ABA7C /* NSObject_PearlExport.m in Sources */ = {isa = PBXBuildFile; fileRef = DAFE45D915039823003ABA7C /* NSObject_PearlExport.m */; }; DAFE4A1415039824003ABA7C /* NSObject_PearlExport.m in Sources */ = {isa = PBXBuildFile; fileRef = DAFE45D915039823003ABA7C /* NSObject_PearlExport.m */; };
@ -952,44 +952,6 @@
DA672D2E14F92C6B004A189C /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; DA672D2E14F92C6B004A189C /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
DA79A9BB1557DB6F00BAA07A /* libscryptenc-ios.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libscryptenc-ios.a"; sourceTree = "<group>"; }; DA79A9BB1557DB6F00BAA07A /* libscryptenc-ios.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libscryptenc-ios.a"; sourceTree = "<group>"; };
DA79A9BD1557DDC700BAA07A /* scrypt.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = scrypt.xcodeproj; path = External/Pearl/External/iOSPorts/ports/security/scrypt/scrypt.xcodeproj; sourceTree = "<group>"; }; DA79A9BD1557DDC700BAA07A /* scrypt.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = scrypt.xcodeproj; path = External/Pearl/External/iOSPorts/ports/security/scrypt/scrypt.xcodeproj; sourceTree = "<group>"; };
DA7DEFC2157978AC009D2085 /* avatar-female-1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-1.png"; sourceTree = "<group>"; };
DA7DEFC3157978AC009D2085 /* avatar-female-1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-1@2x.png"; sourceTree = "<group>"; };
DA7DEFC4157978AC009D2085 /* avatar-female-2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-2.png"; sourceTree = "<group>"; };
DA7DEFC5157978AC009D2085 /* avatar-female-2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-2@2x.png"; sourceTree = "<group>"; };
DA7DEFC6157978AC009D2085 /* avatar-female-silhouette-1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-1.png"; sourceTree = "<group>"; };
DA7DEFC7157978AC009D2085 /* avatar-female-silhouette-1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-1@2x.png"; sourceTree = "<group>"; };
DA7DEFC8157978AC009D2085 /* avatar-female-silhouette-2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-2.png"; sourceTree = "<group>"; };
DA7DEFC9157978AC009D2085 /* avatar-female-silhouette-2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-2@2x.png"; sourceTree = "<group>"; };
DA7DEFCA157978AC009D2085 /* avatar-female-silhouette-3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-3.png"; sourceTree = "<group>"; };
DA7DEFCB157978AC009D2085 /* avatar-female-silhouette-3@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-3@2x.png"; sourceTree = "<group>"; };
DA7DEFCC157978AC009D2085 /* avatar-female-silhouette-4.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-4.png"; sourceTree = "<group>"; };
DA7DEFCD157978AC009D2085 /* avatar-female-silhouette-4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-4@2x.png"; sourceTree = "<group>"; };
DA7DEFCE157978AC009D2085 /* avatar-female-silhouette-5.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-5.png"; sourceTree = "<group>"; };
DA7DEFCF157978AC009D2085 /* avatar-female-silhouette-5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-5@2x.png"; sourceTree = "<group>"; };
DA7DEFD0157978AC009D2085 /* avatar-female-silhouette-6.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-6.png"; sourceTree = "<group>"; };
DA7DEFD1157978AC009D2085 /* avatar-female-silhouette-6@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-6@2x.png"; sourceTree = "<group>"; };
DA7DEFD2157978AC009D2085 /* avatar-female-silhouette-7.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-7.png"; sourceTree = "<group>"; };
DA7DEFD3157978AC009D2085 /* avatar-female-silhouette-7@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-7@2x.png"; sourceTree = "<group>"; };
DA7DEFD4157978AC009D2085 /* avatar-male-1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-1.png"; sourceTree = "<group>"; };
DA7DEFD5157978AC009D2085 /* avatar-male-1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-1@2x.png"; sourceTree = "<group>"; };
DA7DEFD6157978AC009D2085 /* avatar-male-2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-2.png"; sourceTree = "<group>"; };
DA7DEFD7157978AC009D2085 /* avatar-male-2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-2@2x.png"; sourceTree = "<group>"; };
DA7DEFD8157978AC009D2085 /* avatar-male-3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-3.png"; sourceTree = "<group>"; };
DA7DEFD9157978AC009D2085 /* avatar-male-3@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-3@2x.png"; sourceTree = "<group>"; };
DA7DEFDA157978AC009D2085 /* avatar-male-silhouette-1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-1.png"; sourceTree = "<group>"; };
DA7DEFDB157978AC009D2085 /* avatar-male-silhouette-1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-1@2x.png"; sourceTree = "<group>"; };
DA7DEFDC157978AC009D2085 /* avatar-male-silhouette-2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-2.png"; sourceTree = "<group>"; };
DA7DEFDD157978AC009D2085 /* avatar-male-silhouette-2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-2@2x.png"; sourceTree = "<group>"; };
DA7DEFDE157978AC009D2085 /* avatar-male-silhouette-3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-3.png"; sourceTree = "<group>"; };
DA7DEFDF157978AC009D2085 /* avatar-male-silhouette-3@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-3@2x.png"; sourceTree = "<group>"; };
DA7DEFE0157978AC009D2085 /* avatar-male-silhouette-4.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-4.png"; sourceTree = "<group>"; };
DA7DEFE1157978AC009D2085 /* avatar-male-silhouette-4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-4@2x.png"; sourceTree = "<group>"; };
DA7DEFE2157978AC009D2085 /* avatar-male-silhouette-5.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-5.png"; sourceTree = "<group>"; };
DA7DEFE3157978AC009D2085 /* avatar-male-silhouette-5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-5@2x.png"; sourceTree = "<group>"; };
DA7DEFE4157978AC009D2085 /* avatar-male-silhouette-6.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-6.png"; sourceTree = "<group>"; };
DA7DEFE5157978AC009D2085 /* avatar-male-silhouette-6@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-6@2x.png"; sourceTree = "<group>"; };
DA7DEFE6157978AC009D2085 /* avatar-male-silhouette-7.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-7.png"; sourceTree = "<group>"; };
DA7DEFE7157978AC009D2085 /* avatar-male-silhouette-7@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-7@2x.png"; sourceTree = "<group>"; };
DA902BD01576CA4A00C38161 /* keypad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = keypad.png; sourceTree = "<group>"; }; DA902BD01576CA4A00C38161 /* keypad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = keypad.png; sourceTree = "<group>"; };
DA95D59C14DF063C008D1B94 /* libInAppSettingsKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libInAppSettingsKit.a; sourceTree = BUILT_PRODUCTS_DIR; }; DA95D59C14DF063C008D1B94 /* libInAppSettingsKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libInAppSettingsKit.a; sourceTree = BUILT_PRODUCTS_DIR; };
DA95D5A814DF0691008D1B94 /* IASKAppSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKAppSettingsViewController.h; sourceTree = "<group>"; }; DA95D5A814DF0691008D1B94 /* IASKAppSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKAppSettingsViewController.h; sourceTree = "<group>"; };
@ -1733,6 +1695,44 @@
DAD312B91552977200A3F9ED /* UIColor+HSV.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIColor+HSV.h"; path = "External/Pearl/External/uicolor-utilities/UIColor+HSV.h"; sourceTree = SOURCE_ROOT; }; DAD312B91552977200A3F9ED /* UIColor+HSV.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIColor+HSV.h"; path = "External/Pearl/External/uicolor-utilities/UIColor+HSV.h"; sourceTree = SOURCE_ROOT; };
DAD312BA1552977200A3F9ED /* UIColor+HSV.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIColor+HSV.m"; path = "External/Pearl/External/uicolor-utilities/UIColor+HSV.m"; sourceTree = SOURCE_ROOT; }; DAD312BA1552977200A3F9ED /* UIColor+HSV.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIColor+HSV.m"; path = "External/Pearl/External/uicolor-utilities/UIColor+HSV.m"; sourceTree = SOURCE_ROOT; };
DAD312C01552A20800A3F9ED /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; }; DAD312C01552A20800A3F9ED /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; };
DAE4C943157E63BE00EFE047 /* avatar-0.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-0.png"; sourceTree = "<group>"; };
DAE4C944157E63BE00EFE047 /* avatar-0@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-0@2x.png"; sourceTree = "<group>"; };
DAE4C945157E63BE00EFE047 /* avatar-1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-1.png"; sourceTree = "<group>"; };
DAE4C946157E63BE00EFE047 /* avatar-1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-1@2x.png"; sourceTree = "<group>"; };
DAE4C947157E63BE00EFE047 /* avatar-2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-2.png"; sourceTree = "<group>"; };
DAE4C948157E63BE00EFE047 /* avatar-2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-2@2x.png"; sourceTree = "<group>"; };
DAE4C949157E63BE00EFE047 /* avatar-3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-3.png"; sourceTree = "<group>"; };
DAE4C94A157E63BE00EFE047 /* avatar-3@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-3@2x.png"; sourceTree = "<group>"; };
DAE4C94B157E63BE00EFE047 /* avatar-4.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-4.png"; sourceTree = "<group>"; };
DAE4C94C157E63BE00EFE047 /* avatar-4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-4@2x.png"; sourceTree = "<group>"; };
DAE4C94D157E63BE00EFE047 /* avatar-5.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-5.png"; sourceTree = "<group>"; };
DAE4C94E157E63BE00EFE047 /* avatar-5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-5@2x.png"; sourceTree = "<group>"; };
DAE4C94F157E63BE00EFE047 /* avatar-6.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-6.png"; sourceTree = "<group>"; };
DAE4C950157E63BE00EFE047 /* avatar-6@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-6@2x.png"; sourceTree = "<group>"; };
DAE4C951157E63BE00EFE047 /* avatar-7.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-7.png"; sourceTree = "<group>"; };
DAE4C952157E63BE00EFE047 /* avatar-7@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-7@2x.png"; sourceTree = "<group>"; };
DAE4C953157E63BE00EFE047 /* avatar-8.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-8.png"; sourceTree = "<group>"; };
DAE4C954157E63BE00EFE047 /* avatar-8@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-8@2x.png"; sourceTree = "<group>"; };
DAE4C955157E63BE00EFE047 /* avatar-9.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-9.png"; sourceTree = "<group>"; };
DAE4C956157E63BE00EFE047 /* avatar-9@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-9@2x.png"; sourceTree = "<group>"; };
DAE4C957157E63BE00EFE047 /* avatar-10.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-10.png"; sourceTree = "<group>"; };
DAE4C958157E63BE00EFE047 /* avatar-10@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-10@2x.png"; sourceTree = "<group>"; };
DAE4C959157E63BE00EFE047 /* avatar-11.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-11.png"; sourceTree = "<group>"; };
DAE4C95A157E63BE00EFE047 /* avatar-11@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-11@2x.png"; sourceTree = "<group>"; };
DAE4C95B157E63BE00EFE047 /* avatar-12.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-12.png"; sourceTree = "<group>"; };
DAE4C95C157E63BE00EFE047 /* avatar-12@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-12@2x.png"; sourceTree = "<group>"; };
DAE4C95D157E63BE00EFE047 /* avatar-13.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-13.png"; sourceTree = "<group>"; };
DAE4C95E157E63BE00EFE047 /* avatar-13@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-13@2x.png"; sourceTree = "<group>"; };
DAE4C95F157E63BE00EFE047 /* avatar-14.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-14.png"; sourceTree = "<group>"; };
DAE4C960157E63BE00EFE047 /* avatar-14@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-14@2x.png"; sourceTree = "<group>"; };
DAE4C961157E63BE00EFE047 /* avatar-15.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-15.png"; sourceTree = "<group>"; };
DAE4C962157E63BE00EFE047 /* avatar-15@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-15@2x.png"; sourceTree = "<group>"; };
DAE4C963157E63BE00EFE047 /* avatar-16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-16.png"; sourceTree = "<group>"; };
DAE4C964157E63BE00EFE047 /* avatar-16@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-16@2x.png"; sourceTree = "<group>"; };
DAE4C965157E63BE00EFE047 /* avatar-17.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-17.png"; sourceTree = "<group>"; };
DAE4C966157E63BE00EFE047 /* avatar-17@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-17@2x.png"; sourceTree = "<group>"; };
DAE4C967157E63BE00EFE047 /* avatar-18.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-18.png"; sourceTree = "<group>"; };
DAE4C968157E63BE00EFE047 /* avatar-18@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-18@2x.png"; sourceTree = "<group>"; };
DAEBC45214F6364500987BF6 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; DAEBC45214F6364500987BF6 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
DAFE45D815039823003ABA7C /* NSObject_PearlExport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSObject_PearlExport.h; sourceTree = "<group>"; }; DAFE45D815039823003ABA7C /* NSObject_PearlExport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSObject_PearlExport.h; sourceTree = "<group>"; };
DAFE45D915039823003ABA7C /* NSObject_PearlExport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSObject_PearlExport.m; sourceTree = "<group>"; }; DAFE45D915039823003ABA7C /* NSObject_PearlExport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSObject_PearlExport.m; sourceTree = "<group>"; };
@ -2003,44 +2003,44 @@
DA902B931576C0FB00C38161 /* Avatars */ = { DA902B931576C0FB00C38161 /* Avatars */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
DA7DEFC2157978AC009D2085 /* avatar-female-1.png */, DAE4C943157E63BE00EFE047 /* avatar-0.png */,
DA7DEFC3157978AC009D2085 /* avatar-female-1@2x.png */, DAE4C944157E63BE00EFE047 /* avatar-0@2x.png */,
DA7DEFC4157978AC009D2085 /* avatar-female-2.png */, DAE4C945157E63BE00EFE047 /* avatar-1.png */,
DA7DEFC5157978AC009D2085 /* avatar-female-2@2x.png */, DAE4C946157E63BE00EFE047 /* avatar-1@2x.png */,
DA7DEFC6157978AC009D2085 /* avatar-female-silhouette-1.png */, DAE4C947157E63BE00EFE047 /* avatar-2.png */,
DA7DEFC7157978AC009D2085 /* avatar-female-silhouette-1@2x.png */, DAE4C948157E63BE00EFE047 /* avatar-2@2x.png */,
DA7DEFC8157978AC009D2085 /* avatar-female-silhouette-2.png */, DAE4C949157E63BE00EFE047 /* avatar-3.png */,
DA7DEFC9157978AC009D2085 /* avatar-female-silhouette-2@2x.png */, DAE4C94A157E63BE00EFE047 /* avatar-3@2x.png */,
DA7DEFCA157978AC009D2085 /* avatar-female-silhouette-3.png */, DAE4C94B157E63BE00EFE047 /* avatar-4.png */,
DA7DEFCB157978AC009D2085 /* avatar-female-silhouette-3@2x.png */, DAE4C94C157E63BE00EFE047 /* avatar-4@2x.png */,
DA7DEFCC157978AC009D2085 /* avatar-female-silhouette-4.png */, DAE4C94D157E63BE00EFE047 /* avatar-5.png */,
DA7DEFCD157978AC009D2085 /* avatar-female-silhouette-4@2x.png */, DAE4C94E157E63BE00EFE047 /* avatar-5@2x.png */,
DA7DEFCE157978AC009D2085 /* avatar-female-silhouette-5.png */, DAE4C94F157E63BE00EFE047 /* avatar-6.png */,
DA7DEFCF157978AC009D2085 /* avatar-female-silhouette-5@2x.png */, DAE4C950157E63BE00EFE047 /* avatar-6@2x.png */,
DA7DEFD0157978AC009D2085 /* avatar-female-silhouette-6.png */, DAE4C951157E63BE00EFE047 /* avatar-7.png */,
DA7DEFD1157978AC009D2085 /* avatar-female-silhouette-6@2x.png */, DAE4C952157E63BE00EFE047 /* avatar-7@2x.png */,
DA7DEFD2157978AC009D2085 /* avatar-female-silhouette-7.png */, DAE4C953157E63BE00EFE047 /* avatar-8.png */,
DA7DEFD3157978AC009D2085 /* avatar-female-silhouette-7@2x.png */, DAE4C954157E63BE00EFE047 /* avatar-8@2x.png */,
DA7DEFD4157978AC009D2085 /* avatar-male-1.png */, DAE4C955157E63BE00EFE047 /* avatar-9.png */,
DA7DEFD5157978AC009D2085 /* avatar-male-1@2x.png */, DAE4C956157E63BE00EFE047 /* avatar-9@2x.png */,
DA7DEFD6157978AC009D2085 /* avatar-male-2.png */, DAE4C957157E63BE00EFE047 /* avatar-10.png */,
DA7DEFD7157978AC009D2085 /* avatar-male-2@2x.png */, DAE4C958157E63BE00EFE047 /* avatar-10@2x.png */,
DA7DEFD8157978AC009D2085 /* avatar-male-3.png */, DAE4C959157E63BE00EFE047 /* avatar-11.png */,
DA7DEFD9157978AC009D2085 /* avatar-male-3@2x.png */, DAE4C95A157E63BE00EFE047 /* avatar-11@2x.png */,
DA7DEFDA157978AC009D2085 /* avatar-male-silhouette-1.png */, DAE4C95B157E63BE00EFE047 /* avatar-12.png */,
DA7DEFDB157978AC009D2085 /* avatar-male-silhouette-1@2x.png */, DAE4C95C157E63BE00EFE047 /* avatar-12@2x.png */,
DA7DEFDC157978AC009D2085 /* avatar-male-silhouette-2.png */, DAE4C95D157E63BE00EFE047 /* avatar-13.png */,
DA7DEFDD157978AC009D2085 /* avatar-male-silhouette-2@2x.png */, DAE4C95E157E63BE00EFE047 /* avatar-13@2x.png */,
DA7DEFDE157978AC009D2085 /* avatar-male-silhouette-3.png */, DAE4C95F157E63BE00EFE047 /* avatar-14.png */,
DA7DEFDF157978AC009D2085 /* avatar-male-silhouette-3@2x.png */, DAE4C960157E63BE00EFE047 /* avatar-14@2x.png */,
DA7DEFE0157978AC009D2085 /* avatar-male-silhouette-4.png */, DAE4C961157E63BE00EFE047 /* avatar-15.png */,
DA7DEFE1157978AC009D2085 /* avatar-male-silhouette-4@2x.png */, DAE4C962157E63BE00EFE047 /* avatar-15@2x.png */,
DA7DEFE2157978AC009D2085 /* avatar-male-silhouette-5.png */, DAE4C963157E63BE00EFE047 /* avatar-16.png */,
DA7DEFE3157978AC009D2085 /* avatar-male-silhouette-5@2x.png */, DAE4C964157E63BE00EFE047 /* avatar-16@2x.png */,
DA7DEFE4157978AC009D2085 /* avatar-male-silhouette-6.png */, DAE4C965157E63BE00EFE047 /* avatar-17.png */,
DA7DEFE5157978AC009D2085 /* avatar-male-silhouette-6@2x.png */, DAE4C966157E63BE00EFE047 /* avatar-17@2x.png */,
DA7DEFE6157978AC009D2085 /* avatar-male-silhouette-7.png */, DAE4C967157E63BE00EFE047 /* avatar-18.png */,
DA7DEFE7157978AC009D2085 /* avatar-male-silhouette-7@2x.png */, DAE4C968157E63BE00EFE047 /* avatar-18@2x.png */,
); );
path = Avatars; path = Avatars;
sourceTree = "<group>"; sourceTree = "<group>";
@ -4059,44 +4059,44 @@
DACABB8D1572A4A5008BA211 /* tip_basic_black_top_right@2x.png in Resources */, DACABB8D1572A4A5008BA211 /* tip_basic_black_top_right@2x.png in Resources */,
DACABB901572B76A008BA211 /* tip_basic_black_top.png in Resources */, DACABB901572B76A008BA211 /* tip_basic_black_top.png in Resources */,
DACABB911572B76A008BA211 /* tip_basic_black_top@2x.png in Resources */, DACABB911572B76A008BA211 /* tip_basic_black_top@2x.png in Resources */,
DA7DEFE8157978AC009D2085 /* avatar-female-1.png in Resources */, DAE4C969157E63BE00EFE047 /* avatar-0.png in Resources */,
DA7DEFE9157978AC009D2085 /* avatar-female-1@2x.png in Resources */, DAE4C96A157E63BE00EFE047 /* avatar-0@2x.png in Resources */,
DA7DEFEA157978AC009D2085 /* avatar-female-2.png in Resources */, DAE4C96B157E63BE00EFE047 /* avatar-1.png in Resources */,
DA7DEFEB157978AC009D2085 /* avatar-female-2@2x.png in Resources */, DAE4C96C157E63BE00EFE047 /* avatar-1@2x.png in Resources */,
DA7DEFEC157978AC009D2085 /* avatar-female-silhouette-1.png in Resources */, DAE4C96D157E63BE00EFE047 /* avatar-2.png in Resources */,
DA7DEFED157978AC009D2085 /* avatar-female-silhouette-1@2x.png in Resources */, DAE4C96E157E63BE00EFE047 /* avatar-2@2x.png in Resources */,
DA7DEFEE157978AC009D2085 /* avatar-female-silhouette-2.png in Resources */, DAE4C96F157E63BE00EFE047 /* avatar-3.png in Resources */,
DA7DEFEF157978AC009D2085 /* avatar-female-silhouette-2@2x.png in Resources */, DAE4C970157E63BE00EFE047 /* avatar-3@2x.png in Resources */,
DA7DEFF0157978AC009D2085 /* avatar-female-silhouette-3.png in Resources */, DAE4C971157E63BE00EFE047 /* avatar-4.png in Resources */,
DA7DEFF1157978AC009D2085 /* avatar-female-silhouette-3@2x.png in Resources */, DAE4C972157E63BE00EFE047 /* avatar-4@2x.png in Resources */,
DA7DEFF2157978AC009D2085 /* avatar-female-silhouette-4.png in Resources */, DAE4C973157E63BE00EFE047 /* avatar-5.png in Resources */,
DA7DEFF3157978AC009D2085 /* avatar-female-silhouette-4@2x.png in Resources */, DAE4C974157E63BE00EFE047 /* avatar-5@2x.png in Resources */,
DA7DEFF4157978AC009D2085 /* avatar-female-silhouette-5.png in Resources */, DAE4C975157E63BE00EFE047 /* avatar-6.png in Resources */,
DA7DEFF5157978AC009D2085 /* avatar-female-silhouette-5@2x.png in Resources */, DAE4C976157E63BE00EFE047 /* avatar-6@2x.png in Resources */,
DA7DEFF6157978AC009D2085 /* avatar-female-silhouette-6.png in Resources */, DAE4C977157E63BE00EFE047 /* avatar-7.png in Resources */,
DA7DEFF7157978AC009D2085 /* avatar-female-silhouette-6@2x.png in Resources */, DAE4C978157E63BE00EFE047 /* avatar-7@2x.png in Resources */,
DA7DEFF8157978AC009D2085 /* avatar-female-silhouette-7.png in Resources */, DAE4C979157E63BE00EFE047 /* avatar-8.png in Resources */,
DA7DEFF9157978AC009D2085 /* avatar-female-silhouette-7@2x.png in Resources */, DAE4C97A157E63BE00EFE047 /* avatar-8@2x.png in Resources */,
DA7DEFFA157978AC009D2085 /* avatar-male-1.png in Resources */, DAE4C97B157E63BE00EFE047 /* avatar-9.png in Resources */,
DA7DEFFB157978AC009D2085 /* avatar-male-1@2x.png in Resources */, DAE4C97C157E63BE00EFE047 /* avatar-9@2x.png in Resources */,
DA7DEFFC157978AC009D2085 /* avatar-male-2.png in Resources */, DAE4C97D157E63BE00EFE047 /* avatar-10.png in Resources */,
DA7DEFFD157978AC009D2085 /* avatar-male-2@2x.png in Resources */, DAE4C97E157E63BE00EFE047 /* avatar-10@2x.png in Resources */,
DA7DEFFE157978AC009D2085 /* avatar-male-3.png in Resources */, DAE4C97F157E63BE00EFE047 /* avatar-11.png in Resources */,
DA7DEFFF157978AC009D2085 /* avatar-male-3@2x.png in Resources */, DAE4C980157E63BE00EFE047 /* avatar-11@2x.png in Resources */,
DA7DF000157978AC009D2085 /* avatar-male-silhouette-1.png in Resources */, DAE4C981157E63BE00EFE047 /* avatar-12.png in Resources */,
DA7DF001157978AC009D2085 /* avatar-male-silhouette-1@2x.png in Resources */, DAE4C982157E63BE00EFE047 /* avatar-12@2x.png in Resources */,
DA7DF002157978AC009D2085 /* avatar-male-silhouette-2.png in Resources */, DAE4C983157E63BE00EFE047 /* avatar-13.png in Resources */,
DA7DF003157978AC009D2085 /* avatar-male-silhouette-2@2x.png in Resources */, DAE4C984157E63BE00EFE047 /* avatar-13@2x.png in Resources */,
DA7DF004157978AC009D2085 /* avatar-male-silhouette-3.png in Resources */, DAE4C985157E63BE00EFE047 /* avatar-14.png in Resources */,
DA7DF005157978AC009D2085 /* avatar-male-silhouette-3@2x.png in Resources */, DAE4C986157E63BE00EFE047 /* avatar-14@2x.png in Resources */,
DA7DF006157978AC009D2085 /* avatar-male-silhouette-4.png in Resources */, DAE4C987157E63BE00EFE047 /* avatar-15.png in Resources */,
DA7DF007157978AC009D2085 /* avatar-male-silhouette-4@2x.png in Resources */, DAE4C988157E63BE00EFE047 /* avatar-15@2x.png in Resources */,
DA7DF008157978AC009D2085 /* avatar-male-silhouette-5.png in Resources */, DAE4C989157E63BE00EFE047 /* avatar-16.png in Resources */,
DA7DF009157978AC009D2085 /* avatar-male-silhouette-5@2x.png in Resources */, DAE4C98A157E63BE00EFE047 /* avatar-16@2x.png in Resources */,
DA7DF00A157978AC009D2085 /* avatar-male-silhouette-6.png in Resources */, DAE4C98B157E63BE00EFE047 /* avatar-17.png in Resources */,
DA7DF00B157978AC009D2085 /* avatar-male-silhouette-6@2x.png in Resources */, DAE4C98C157E63BE00EFE047 /* avatar-17@2x.png in Resources */,
DA7DF00C157978AC009D2085 /* avatar-male-silhouette-7.png in Resources */, DAE4C98D157E63BE00EFE047 /* avatar-18.png in Resources */,
DA7DF00D157978AC009D2085 /* avatar-male-silhouette-7@2x.png in Resources */, DAE4C98E157E63BE00EFE047 /* avatar-18@2x.png in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@ -7,6 +7,7 @@
// //
#import "MPAppDelegate_Key.h" #import "MPAppDelegate_Key.h"
#import "MPAppDelegate_Store.h"
@implementation MPAppDelegate_Shared (Key) @implementation MPAppDelegate_Shared (Key)
@ -63,10 +64,10 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
NSData *tryKey = keyForPassword(tryPassword); NSData *tryKey = keyForPassword(tryPassword);
NSData *tryKeyID = keyIDForKey(tryKey); NSData *tryKeyID = keyIDForKey(tryKey);
inf(@"Key ID known? %@.", user.keyID? @"YES": @"NO"); inf(@"Key ID was known? %@.", user.keyID? @"YES": @"NO");
if (user.keyID) if (user.keyID) {
// A key ID is known -> a password is set. // A key ID is known -> a master password is set.
// Make sure the user's entered password matches it. // Make sure the user's entered master password matches it.
if (![user.keyID isEqual:tryKeyID]) { if (![user.keyID isEqual:tryKeyID]) {
wrn(@"Key ID mismatch. Expected: %@, answer: %@.", [user.keyID encodeHex], [tryKeyID encodeHex]); wrn(@"Key ID mismatch. Expected: %@, answer: %@.", [user.keyID encodeHex], [tryKeyID encodeHex]);
@ -75,6 +76,11 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
#endif #endif
return NO; return NO;
} }
} else {
// A key ID is not known -> recording a new master password.
user.keyID = tryKeyID;
[[MPAppDelegate_Shared get] saveContext];
}
#ifdef TESTFLIGHT_SDK_VERSION #ifdef TESTFLIGHT_SDK_VERSION
[TestFlight passCheckpoint:MPTestFlightCheckpointMPEntered]; [TestFlight passCheckpoint:MPTestFlightCheckpointMPEntered];

View File

@ -12,6 +12,8 @@
#import "MPElementGeneratedEntity.h" #import "MPElementGeneratedEntity.h"
#import "MPUserEntity.h" #import "MPUserEntity.h"
#define MPAvatarCount 19
@interface MPElementEntity (MP) @interface MPElementEntity (MP)
@property (assign) MPElementType type; @property (assign) MPElementType type;

View File

@ -12,7 +12,7 @@
#define MP_salt nil #define MP_salt nil
#define MP_N 16384 #define MP_N 131072
#define MP_r 8 #define MP_r 8
#define MP_p 1 #define MP_p 1
#define MP_dkLen 64 #define MP_dkLen 64

View File

@ -114,7 +114,7 @@
return nil; return nil;
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([MPElementEntity class])]; NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([MPElementEntity class])];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"uses" ascending:NO]]; fetchRequest.sortDescriptors = [NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"uses_" ascending:NO]];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(%@ == '' OR name BEGINSWITH[cd] %@) AND user == %@", fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(%@ == '' OR name BEGINSWITH[cd] %@) AND user == %@",
query, query, [MPAppDelegate get].activeUser]; query, query, [MPAppDelegate get].activeUser];

View File

@ -18,5 +18,6 @@
- (void)loadKey:(BOOL)animated; - (void)loadKey:(BOOL)animated;
- (void)export; - (void)export;
- (void)changeMP;
@end @end

View File

@ -117,6 +117,29 @@
[self.window.rootViewController presentModalViewController:composer animated:YES]; [self.window.rootViewController presentModalViewController:composer animated:YES];
} }
- (void)changeMP {
[PearlAlert showAlertWithTitle:@"Changing Master Password"
message:
@"This will allow you to log in with a different master password.\n\n"
@"Note that you will only see the sites and passwords for the master password you log in with.\n"
@"If you log in with a different master password, your current sites will be unavailable.\n\n"
@"You can always change back to your current master password later.\n"
@"Your current sites and passwords will then become available again."
viewStyle:UIAlertViewStyleDefault
initAlert:nil tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) {
if (buttonIndex == [alert cancelButtonIndex])
return;
[[MPAppDelegate get] forgetSavedKey];
[[MPAppDelegate get] loadKey:YES];
[TestFlight passCheckpoint:MPTestFlightCheckpointMPChanged];
}
cancelTitle:[PearlStrings get].commonButtonAbort
otherTitles:[PearlStrings get].commonButtonContinue, nil];
}
#pragma mark - PearlConfigDelegate #pragma mark - PearlConfigDelegate
- (void)didUpdateConfigForKey:(SEL)configKey fromValue:(id)value { - (void)didUpdateConfigForKey:(SEL)configKey fromValue:(id)value {

View File

@ -404,23 +404,19 @@
[self performSegueWithIdentifier:@"UserProfile" sender:self]; [self performSegueWithIdentifier:@"UserProfile" sender:self];
break; break;
} }
case 4: {
[[MPAppDelegate get] export];
break;
}
#ifdef ADHOC #ifdef ADHOC
case 5: { case 4: {
[TestFlight openFeedbackView]; [TestFlight openFeedbackView];
break; break;
} }
case 6: case 5:
#else #else
case 5: { case 4: {
ATConnect *connection = [ATConnect sharedConnection]; ATConnect *connection = [ATConnect sharedConnection];
[connection presentFeedbackControllerFromViewController:self]; [connection presentFeedbackControllerFromViewController:self];
break; break;
} }
case 6: case 5:
#endif #endif
{ {
[[MPAppDelegate get] signOut:self]; [[MPAppDelegate get] signOut:self];

View File

@ -11,6 +11,12 @@
@interface MPPreferencesViewController : UITableViewController <IASKSettingsDelegate> @interface MPPreferencesViewController : UITableViewController <IASKSettingsDelegate>
@property (weak, nonatomic) IBOutlet UIScrollView *avatarScrollView; @property (weak, nonatomic) IBOutlet UIScrollView *avatarsView;
@property (weak, nonatomic) IBOutlet UIButton *avatarTemplate;
@property (weak, nonatomic) IBOutlet UISwitch *savePasswordSwitch;
@property (weak, nonatomic) IBOutlet UITableViewCell *exportCell;
@property (weak, nonatomic) IBOutlet UITableViewCell *changeMPCell;
- (IBAction)didToggleSwitch:(UISwitch *)sender;
@end @end

View File

@ -6,6 +6,7 @@
// Copyright (c) 2012 Lyndir. All rights reserved. // Copyright (c) 2012 Lyndir. All rights reserved.
// //
#import <QuartzCore/QuartzCore.h>
#import "MPPreferencesViewController.h" #import "MPPreferencesViewController.h"
#import "MPAppDelegate.h" #import "MPAppDelegate.h"
@ -14,31 +15,60 @@
@end @end
@implementation MPPreferencesViewController @implementation MPPreferencesViewController
@synthesize avatarScrollView; @synthesize avatarsView;
@synthesize avatarTemplate;
@synthesize savePasswordSwitch;
@synthesize exportCell;
@synthesize changeMPCell;
- (void)viewDidLoad { - (void)viewDidLoad {
__block NSInteger avatarIndex = 0; self.avatarTemplate.hidden = YES;
[self.avatarScrollView enumerateSubviews:^(UIView *subview, BOOL *stop, BOOL *recurse) {
UIButton *avatar = (UIButton *)subview;
avatar.toggleSelectionWhenTouchedInside = YES;
avatar.tag = avatarIndex++;
[avatar onSelect:^(BOOL selected) { for (int a = 0; a < MPAvatarCount; ++a) {
[MPAppDelegate get].activeUser.avatar = (unsigned)avatar.tag; UIButton *avatar = [self.avatarTemplate clone];
[self.avatarScrollView enumerateSubviews:^(UIView *subview_, BOOL *stop_, BOOL *recurse_) { avatar.togglesSelectionInSuperview = YES;
UIButton *avatar_ = (UIButton *)subview_; avatar.tag = a;
avatar_.selected = ([MPAppDelegate get].activeUser.avatar == (unsigned)avatar_.tag); avatar.hidden = NO;
} recurse:NO]; avatar.center = CGPointMake(
self.avatarTemplate.center.x * (a + 1) + self.avatarTemplate.bounds.size.width / 2 * a,
self.avatarTemplate.center.y);
[avatar setBackgroundImage:[UIImage imageNamed:PearlString(@"avatar-%d", a)]
forState:UIControlStateNormal];
avatar.layer.cornerRadius = avatar.bounds.size.height / 2;
avatar.layer.shadowColor = [UIColor blackColor].CGColor;
avatar.layer.shadowOpacity = 1;
avatar.layer.shadowRadius = 5;
avatar.backgroundColor = [UIColor clearColor];
[avatar onHighlightOrSelect:^(BOOL highlighted, BOOL selected) {
if (highlighted || selected)
avatar.backgroundColor = self.avatarTemplate.backgroundColor;
else
avatar.backgroundColor = [UIColor clearColor];
} options:0]; } options:0];
} recurse:NO]; [avatar onSelect:^(BOOL selected) {
if (selected)
[MPAppDelegate get].activeUser.avatar = (unsigned)avatar.tag;
} options:0];
avatar.selected = (a == [MPAppDelegate get].activeUser.avatar);
}
[super viewDidLoad]; [super viewDidLoad];
} }
- (void)viewWillAppear:(BOOL)animated { - (void)viewWillAppear:(BOOL)animated {
[self.avatarScrollView autoSizeContent]; [self.avatarsView autoSizeContent];
[self.avatarsView enumerateSubviews:^(UIView *subview, BOOL *stop, BOOL *recurse) {
if (subview.tag && ((UIControl *) subview).selected) {
[self.avatarsView setContentOffset:CGPointMake(subview.center.x - self.avatarsView.bounds.size.width / 2, 0) animated:animated];
}
} recurse:NO];
self.savePasswordSwitch.on = [MPAppDelegate get].activeUser.saveKey;
[super viewWillAppear:animated]; [super viewWillAppear:animated];
} }
@ -48,7 +78,29 @@
return (interfaceOrientation == UIInterfaceOrientationPortrait); return (interfaceOrientation == UIInterfaceOrientationPortrait);
} }
#pragma mark - - (void)viewDidUnload {
[self setAvatarsView:nil];
[self setAvatarTemplate:nil];
[self setAvatarsView:nil];
[self setSavePasswordSwitch:nil];
[self setExportCell:nil];
[self setChangeMPCell:nil];
[super viewDidUnload];
}
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
if (cell == self.exportCell)
[[MPAppDelegate get] export];
else if (cell == self.changeMPCell)
[[MPAppDelegate get] changeMP];
}
#pragma mark - IASKSettingsDelegate
- (void)settingsViewControllerDidEnd:(IASKAppSettingsViewController *)sender { - (void)settingsViewControllerDidEnd:(IASKAppSettingsViewController *)sender {
@ -56,8 +108,11 @@
[self.navigationController popViewControllerAnimated:YES]; [self.navigationController popViewControllerAnimated:YES];
} }
- (void)viewDidUnload { #pragma mark - IBActions
[self setAvatarScrollView:nil];
[super viewDidUnload]; - (IBAction)didToggleSwitch:(UISwitch *)sender {
[MPAppDelegate get].activeUser.saveKey = sender.on;
} }
@end @end

View File

@ -35,7 +35,7 @@
self.query = @""; self.query = @"";
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([MPElementEntity class])]; NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([MPElementEntity class])];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"uses" ascending:NO]]; fetchRequest.sortDescriptors = [NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"uses_" ascending:NO]];
self.fetchedResultsController = [PearlLazy lazyObjectLoadedFrom:^id{ self.fetchedResultsController = [PearlLazy lazyObjectLoadedFrom:^id{
NSFetchedResultsController *controller = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest NSFetchedResultsController *controller = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:[MPAppDelegate managedObjectContext] managedObjectContext:[MPAppDelegate managedObjectContext]

View File

@ -13,12 +13,14 @@
@property (weak, nonatomic) IBOutlet UIImageView *spinner; @property (weak, nonatomic) IBOutlet UIImageView *spinner;
@property (weak, nonatomic) IBOutlet UITextField *passwordField; @property (weak, nonatomic) IBOutlet UITextField *passwordField;
@property (weak, nonatomic) IBOutlet UIView *passwordView; @property (weak, nonatomic) IBOutlet UIView *passwordView;
@property (weak, nonatomic) IBOutlet UIScrollView *usersView; @property (weak, nonatomic) IBOutlet UIScrollView *avatarsView;
@property (weak, nonatomic) IBOutlet UILabel *usernameLabel; @property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@property (weak, nonatomic) IBOutlet UILabel *oldUsernameLabel; @property (weak, nonatomic) IBOutlet UILabel *oldNameLabel;
@property (weak, nonatomic) IBOutlet UIButton *userButtonTemplate; @property (weak, nonatomic) IBOutlet UIButton *avatarTemplate;
@property (weak, nonatomic) IBOutlet UILabel *deleteTip; @property (weak, nonatomic) IBOutlet UILabel *deleteTip;
@property(nonatomic, strong) UIColor *avatarShadowColor;
- (IBAction)deleteTargetedUser:(UILongPressGestureRecognizer *)sender; - (IBAction)deleteTargetedUser:(UILongPressGestureRecognizer *)sender;
@end @end

View File

@ -15,8 +15,8 @@
@interface MPUnlockViewController () @interface MPUnlockViewController ()
@property (strong, nonatomic) MPUserEntity *selectedUser; @property(strong, nonatomic) MPUserEntity *selectedUser;
@property (strong, nonatomic) NSMutableDictionary *avatarToUser; @property(strong, nonatomic) NSMutableDictionary *avatarToUser;
@end @end
@ -26,10 +26,12 @@
@synthesize spinner; @synthesize spinner;
@synthesize passwordField; @synthesize passwordField;
@synthesize passwordView; @synthesize passwordView;
@synthesize usersView; @synthesize avatarsView;
@synthesize usernameLabel, oldUsernameLabel; @synthesize nameLabel, oldNameLabel;
@synthesize userButtonTemplate; @synthesize avatarTemplate;
@synthesize deleteTip; @synthesize deleteTip;
@synthesize avatarShadowColor = _avatarShadowColor;
// [UIView animateWithDuration:1.0f delay:0 options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse animations:^{ // [UIView animateWithDuration:1.0f delay:0 options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse animations:^{
// self.lock.alpha = 0.5f; // self.lock.alpha = 0.5f;
@ -44,12 +46,12 @@
self.avatarToUser = [NSMutableDictionary dictionaryWithCapacity:3]; self.avatarToUser = [NSMutableDictionary dictionaryWithCapacity:3];
self.spinner.alpha = 0;
self.passwordField.text = nil; self.passwordField.text = nil;
self.usersView.decelerationRate = UIScrollViewDecelerationRateFast; self.avatarsView.decelerationRate = UIScrollViewDecelerationRateFast;
self.usersView.clipsToBounds = NO; self.avatarsView.clipsToBounds = NO;
self.usernameLabel.layer.cornerRadius = 5; self.nameLabel.layer.cornerRadius = 5;
self.userButtonTemplate.hidden = YES; self.avatarTemplate.hidden = YES;
self.spinner.alpha = 0;
[self updateLayoutAnimated:NO allowScroll:YES completion:nil]; [self updateLayoutAnimated:NO allowScroll:YES completion:nil];
@ -61,9 +63,9 @@
[self setSpinner:nil]; [self setSpinner:nil];
[self setPasswordField:nil]; [self setPasswordField:nil];
[self setPasswordView:nil]; [self setPasswordView:nil];
[self setUsersView:nil]; [self setAvatarsView:nil];
[self setUsernameLabel:nil]; [self setNameLabel:nil];
[self setUserButtonTemplate:nil]; [self setAvatarTemplate:nil];
[self setDeleteTip:nil]; [self setDeleteTip:nil];
[super viewDidUnload]; [super viewDidUnload];
} }
@ -78,16 +80,14 @@
- (void)viewDidAppear:(BOOL)animated { - (void)viewDidAppear:(BOOL)animated {
[[UIApplication sharedApplication] setStatusBarHidden:YES [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:animated ? UIStatusBarAnimationSlide : UIStatusBarAnimationNone];
withAnimation:animated? UIStatusBarAnimationSlide: UIStatusBarAnimationNone];
[super viewDidAppear:animated]; [super viewDidAppear:animated];
} }
- (void)viewWillDisappear:(BOOL)animated { - (void)viewWillDisappear:(BOOL)animated {
[[UIApplication sharedApplication] setStatusBarHidden:NO [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:animated ? UIStatusBarAnimationSlide : UIStatusBarAnimationNone];
withAnimation:animated? UIStatusBarAnimationSlide: UIStatusBarAnimationNone];
[super viewWillDisappear:animated]; [super viewWillDisappear:animated];
} }
@ -99,18 +99,18 @@
NSArray *users = [[MPAppDelegate managedObjectContext] executeFetchRequest:fetchRequest error:nil]; NSArray *users = [[MPAppDelegate managedObjectContext] executeFetchRequest:fetchRequest error:nil];
// Clean up avatars. // Clean up avatars.
for (UIView *view in [self.usersView subviews]) for (UIView *view in [self.avatarsView subviews])
if (view != self.userButtonTemplate) if (view != self.avatarTemplate)
[view removeFromSuperview]; [view removeFromSuperview];
[self.avatarToUser removeAllObjects]; [self.avatarToUser removeAllObjects];
// Create avatars. // Create avatars.
for (MPUserEntity *user in users) for (MPUserEntity *user in users)
[self setupAvatar:[self.userButtonTemplate clone] forUser:user]; [self setupAvatar:[self.avatarTemplate clone] forUser:user];
[self setupAvatar:[self.userButtonTemplate clone] forUser:nil]; [self setupAvatar:[self.avatarTemplate clone] forUser:nil];
// Scroll view's content changed, update its content size. // Scroll view's content changed, update its content size.
[self.usersView autoSizeContentIgnoreHidden:YES ignoreInvisible:YES limitPadding:NO ignoreSubviews:nil]; [self.avatarsView autoSizeContentIgnoreHidden:YES ignoreInvisible:YES limitPadding:NO ignoreSubviews:nil];
[self updateLayoutAnimated:YES allowScroll:YES completion:nil]; [self updateLayoutAnimated:YES allowScroll:YES completion:nil];
@ -125,27 +125,31 @@
[avatar onHighlightOrSelect:^(BOOL highlighted, BOOL selected) { [avatar onHighlightOrSelect:^(BOOL highlighted, BOOL selected) {
if (highlighted || selected) if (highlighted || selected)
avatar.backgroundColor = self.userButtonTemplate.backgroundColor; avatar.backgroundColor = self.avatarTemplate.backgroundColor;
else else
avatar.backgroundColor = [UIColor clearColor]; avatar.backgroundColor = [UIColor clearColor];
} options:0]; } options:0];
[avatar onSelect:^(BOOL selected) { [avatar onSelect:^(BOOL selected) {
self.selectedUser = selected? user: nil; self.selectedUser = selected ? user : nil;
if (user) if (user)
[self didToggleUserSelection]; [self didToggleUserSelection];
else if (selected) else if (selected)
[self didSelectNewUserAvatar:avatar]; [self didSelectNewUserAvatar:avatar];
} options:0]; } options:0];
avatar.toggleSelectionWhenTouchedInside = YES; avatar.togglesSelectionInSuperview = YES;
avatar.center = CGPointMake(avatar.center.x + [self.avatarToUser count] * 160, avatar.center.y); avatar.center = CGPointMake(avatar.center.x + [self.avatarToUser count] * 160, avatar.center.y);
avatar.hidden = NO; avatar.hidden = NO;
avatar.layer.cornerRadius = 5; avatar.layer.cornerRadius = avatar.bounds.size.height / 2;
avatar.layer.shadowColor = [UIColor blackColor].CGColor; avatar.layer.shadowColor = [UIColor blackColor].CGColor;
avatar.layer.shadowOpacity = 1; avatar.layer.shadowOpacity = 1;
avatar.layer.shadowRadius = 20; avatar.layer.shadowRadius = 20;
avatar.layer.masksToBounds = NO; avatar.layer.masksToBounds = NO;
avatar.backgroundColor = [UIColor clearColor]; avatar.backgroundColor = [UIColor clearColor];
dbg(@"User: %@, avatar: %d", user.name, user.avatar);
[avatar setBackgroundImage:[UIImage imageNamed:PearlString(@"avatar-%u", user.avatar)]
forState:UIControlStateNormal];
if (user) if (user)
[self.avatarToUser setObject:user forKey:[NSValue valueWithNonretainedObject:avatar]]; [self.avatarToUser setObject:user forKey:[NSValue valueWithNonretainedObject:avatar]];
@ -161,8 +165,7 @@
[self.passwordField resignFirstResponder]; [self.passwordField resignFirstResponder];
[self updateLayoutAnimated:YES allowScroll:YES completion:^(BOOL finished) { [self updateLayoutAnimated:YES allowScroll:YES completion:^(BOOL finished) {
if (finished) if (finished) if (self.selectedUser)
if (self.selectedUser)
[self.passwordField becomeFirstResponder]; [self.passwordField becomeFirstResponder];
}]; }];
} }
@ -196,15 +199,15 @@
- (void)updateLayoutAnimated:(BOOL)animated allowScroll:(BOOL)allowScroll completion:(void (^)(BOOL finished))completion { - (void)updateLayoutAnimated:(BOOL)animated allowScroll:(BOOL)allowScroll completion:(void (^)(BOOL finished))completion {
if (animated) { if (animated) {
self.oldUsernameLabel.text = self.usernameLabel.text; self.oldNameLabel.text = self.nameLabel.text;
self.oldUsernameLabel.alpha = 1; self.oldNameLabel.alpha = 1;
self.usernameLabel.alpha = 0; self.nameLabel.alpha = 0;
[UIView animateWithDuration:0.5f animations:^{ [UIView animateWithDuration:0.5f animations:^{
[self updateLayoutAnimated:NO allowScroll:allowScroll completion:nil]; [self updateLayoutAnimated:NO allowScroll:allowScroll completion:nil];
self.oldUsernameLabel.alpha = 0; self.oldNameLabel.alpha = 0;
self.usernameLabel.alpha = 1; self.nameLabel.alpha = 1;
} completion:^(BOOL finished) { } completion:^(BOOL finished) {
if (completion) if (completion)
completion(finished); completion(finished);
@ -214,18 +217,20 @@
if (self.selectedUser && !self.passwordView.alpha) { if (self.selectedUser && !self.passwordView.alpha) {
self.passwordView.alpha = 1; self.passwordView.alpha = 1;
self.usersView.center = CGPointMake(160, 100); self.avatarsView.center = CGPointMake(160, 100);
self.usersView.scrollEnabled = NO; self.avatarsView.scrollEnabled = NO;
self.usernameLabel.center = CGPointMake(160, 84); self.nameLabel.center = CGPointMake(160, 84);
self.usernameLabel.backgroundColor = [UIColor blackColor]; self.nameLabel.backgroundColor = [UIColor blackColor];
self.oldUsernameLabel.center = self.usernameLabel.center; self.oldNameLabel.center = self.nameLabel.center;
} else if (self.passwordView.alpha == 1) { self.avatarShadowColor = [UIColor whiteColor];
} else if (!self.selectedUser && self.passwordView.alpha == 1) {
self.passwordView.alpha = 0; self.passwordView.alpha = 0;
self.usersView.center = CGPointMake(160, 240); self.avatarsView.center = CGPointMake(160, 240);
self.usersView.scrollEnabled = YES; self.avatarsView.scrollEnabled = YES;
self.usernameLabel.center = CGPointMake(160, 296); self.nameLabel.center = CGPointMake(160, 296);
self.usernameLabel.backgroundColor = [UIColor clearColor]; self.nameLabel.backgroundColor = [UIColor clearColor];
self.oldUsernameLabel.center = self.usernameLabel.center; self.oldNameLabel.center = self.nameLabel.center;
self.avatarShadowColor = [UIColor lightGrayColor];
} }
MPUserEntity *targetedUser = self.selectedUser; MPUserEntity *targetedUser = self.selectedUser;
@ -236,76 +241,58 @@
targetedUser = [self userForAvatar:targetedAvatar]; targetedUser = [self userForAvatar:targetedAvatar];
} }
[self.usersView enumerateSubviews:^(UIView *subview, BOOL *stop, BOOL *recurse) { [self.avatarsView enumerateSubviews:^(UIView *subview, BOOL *stop, BOOL *recurse) {
const BOOL isTargeted = subview == targetedAvatar; const BOOL isTargeted = subview == targetedAvatar;
subview.userInteractionEnabled = isTargeted; subview.userInteractionEnabled = isTargeted;
subview.alpha = isTargeted ? 1: self.selectedUser? 0.1: 0.4; subview.alpha = isTargeted ? 1 : self.selectedUser ? 0.1 : 0.4;
if (!isTargeted && [subview.layer animationForKey:@"targetedShadow"]) {
CABasicAnimation *toShadowColorAnimation = [CABasicAnimation animationWithKeyPath:@"shadowColor"];
toShadowColorAnimation.toValue = (__bridge id)[UIColor blackColor].CGColor;
toShadowColorAnimation.duration = 0.5f;
CABasicAnimation *toShadowOpacityAnimation = [CABasicAnimation animationWithKeyPath:@"shadowOpacity"]; [self updateAvatarShadowColor:subview isTargeted:isTargeted];
toShadowOpacityAnimation.toValue = PearlFloat(1);
toShadowOpacityAnimation.duration = 0.5f;
CAAnimationGroup *group = [[CAAnimationGroup alloc] init];
group.animations = [NSArray arrayWithObjects:toShadowColorAnimation, toShadowOpacityAnimation, nil];
group.duration = 0.5f;
[subview.layer removeAnimationForKey:@"targetedShadow"];
[subview.layer addAnimation:group forKey:@"inactiveShadow"];
}
} recurse:NO]; } recurse:NO];
if (![targetedAvatar.layer animationForKey:@"targetedShadow"]) {
CABasicAnimation *toShadowColorAnimation = [CABasicAnimation animationWithKeyPath:@"shadowColor"];
toShadowColorAnimation.toValue = (__bridge id)[UIColor whiteColor].CGColor;
toShadowColorAnimation.beginTime = 0.0f;
toShadowColorAnimation.duration = 0.5f;
toShadowColorAnimation.fillMode = kCAFillModeForwards;
CABasicAnimation *toShadowOpacityAnimation = [CABasicAnimation animationWithKeyPath:@"shadowOpacity"];
toShadowOpacityAnimation.toValue = PearlFloat(0.2);
toShadowOpacityAnimation.duration = 0.5f;
CABasicAnimation *pulseShadowOpacityAnimation = [CABasicAnimation animationWithKeyPath:@"shadowOpacity"];
pulseShadowOpacityAnimation.fromValue = PearlFloat(0.2);
pulseShadowOpacityAnimation.toValue = PearlFloat(0.6);
pulseShadowOpacityAnimation.beginTime = 0.5f;
pulseShadowOpacityAnimation.duration = 2.0f;
pulseShadowOpacityAnimation.autoreverses = YES;
pulseShadowOpacityAnimation.repeatCount = NSIntegerMax;
CAAnimationGroup *group = [[CAAnimationGroup alloc] init];
group.animations = [NSArray arrayWithObjects:toShadowColorAnimation, toShadowOpacityAnimation, pulseShadowOpacityAnimation, nil];
group.duration = CGFLOAT_MAX;
[targetedAvatar.layer removeAnimationForKey:@"inactiveShadow"];
[targetedAvatar.layer addAnimation:group forKey:@"targetedShadow"];
}
if (allowScroll) { if (allowScroll) {
CGPoint targetContentOffset = CGPointMake(targetedAvatar.center.x - self.usersView.bounds.size.width / 2, self.usersView.contentOffset.y); CGPoint targetContentOffset = CGPointMake(targetedAvatar.center.x - self.avatarsView.bounds.size.width / 2, self.avatarsView.contentOffset.y);
if (!CGPointEqualToPoint(self.usersView.contentOffset, targetContentOffset)) if (!CGPointEqualToPoint(self.avatarsView.contentOffset, targetContentOffset))
[self.usersView setContentOffset:targetContentOffset animated:animated]; [self.avatarsView setContentOffset:targetContentOffset animated:animated];
} }
self.usernameLabel.text = targetedUser? targetedUser.name: @"New User"; self.nameLabel.text = targetedUser ? targetedUser.name : @"New User";
self.usernameLabel.bounds = CGRectSetHeight(self.usernameLabel.bounds, self.nameLabel.bounds = CGRectSetHeight(self.nameLabel.bounds,
[self.usernameLabel.text sizeWithFont:self.usernameLabel.font [self.nameLabel.text sizeWithFont:self.nameLabel.font
constrainedToSize:CGSizeMake(self.usernameLabel.bounds.size.width - 10, 100) constrainedToSize:CGSizeMake(self.nameLabel.bounds.size.width - 10, 100)
lineBreakMode:self.usernameLabel.lineBreakMode].height); lineBreakMode:self.nameLabel.lineBreakMode].height);
self.oldUsernameLabel.bounds = self.usernameLabel.bounds; self.oldNameLabel.bounds = self.nameLabel.bounds;
if (completion) if (completion)
completion(YES); completion(YES);
} }
- (void)tryMasterPassword {
[self setSpinnerActive:YES];
[self changeAvatarShadowColorTo:[UIColor colorWithName:@"lightskyblue"]];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
BOOL unlocked = [[MPAppDelegate get] tryMasterPassword:self.passwordField.text forUser:self.selectedUser];
dispatch_async(dispatch_get_main_queue(), ^{
if (unlocked) {
[self changeAvatarShadowColorTo:[UIColor colorWithName:@"greenyellow"]];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (long) (NSEC_PER_SEC * 1.5f)), dispatch_get_main_queue(), ^{
[self dismissModalViewControllerAnimated:YES];
});
} else
[self changeAvatarShadowColorTo:[UIColor colorWithName:@"crimson"]];
[self setSpinnerActive:NO];
});
});
}
- (UIButton *)findTargetedAvatar { - (UIButton *)findTargetedAvatar {
CGFloat xOfMiddle = self.usersView.contentOffset.x + self.usersView.bounds.size.width / 2; CGFloat xOfMiddle = self.avatarsView.contentOffset.x + self.avatarsView.bounds.size.width / 2;
return (UIButton *)[PearlUIUtils viewClosestTo:CGPointMake(xOfMiddle, self.usersView.contentOffset.y) ofArray:self.usersView.subviews]; return (UIButton *) [PearlUIUtils viewClosestTo:CGPointMake(xOfMiddle, self.avatarsView.contentOffset.y) ofArray:self.avatarsView.subviews];
} }
- (UIButton *)avatarForUser:(MPUserEntity *)user { - (UIButton *)avatarForUser:(MPUserEntity *)user {
@ -325,51 +312,117 @@
return NullToNil([self.avatarToUser objectForKey:[NSValue valueWithNonretainedObject:avatar]]); return NullToNil([self.avatarToUser objectForKey:[NSValue valueWithNonretainedObject:avatar]]);
} }
- (void)setSpinnerActive:(BOOL)active {
PearlMainThread(^{
CABasicAnimation *rotate = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
rotate.toValue = [NSNumber numberWithDouble:2 * M_PI];
rotate.duration = 5.0;
if (active) {
rotate.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
rotate.fromValue = [NSNumber numberWithFloat:0];
rotate.repeatCount = MAXFLOAT;
} else {
rotate.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
rotate.repeatCount = 1;
}
[self.spinner.layer removeAnimationForKey:@"rotation"];
[self.spinner.layer addAnimation:rotate forKey:@"rotation"];
[UIView animateWithDuration:0.3f animations:^{
self.spinner.alpha = active? 1: 0;
if (active)
[self avatarForUser:self.selectedUser].backgroundColor = [UIColor clearColor];
else
[self avatarForUser:self.selectedUser].backgroundColor = self.avatarTemplate.backgroundColor;
}];
});
}
- (void)changeAvatarShadowColorTo:(UIColor *)color {
self.avatarShadowColor = color;
if (self.selectedUser) {
UIButton *selectedAvatar = [self avatarForUser:self.selectedUser];
[selectedAvatar.layer removeAnimationForKey:@"targetedShadow"];
[self updateAvatarShadowColor:selectedAvatar isTargeted:YES];
}
}
- (void)updateAvatarShadowColor:(UIView *)avatar isTargeted:(BOOL)targeted {
if (targeted) {
if (![avatar.layer animationForKey:@"targetedShadow"]) {
CABasicAnimation *toShadowColorAnimation = [CABasicAnimation animationWithKeyPath:@"shadowColor"];
toShadowColorAnimation.toValue = (__bridge id) self.avatarShadowColor.CGColor;
toShadowColorAnimation.beginTime = 0.0f;
toShadowColorAnimation.duration = 0.5f;
toShadowColorAnimation.fillMode = kCAFillModeForwards;
CABasicAnimation *toShadowOpacityAnimation = [CABasicAnimation animationWithKeyPath:@"shadowOpacity"];
toShadowOpacityAnimation.toValue = PearlFloat(0.2);
toShadowOpacityAnimation.duration = 0.5f;
CABasicAnimation *pulseShadowOpacityAnimation = [CABasicAnimation animationWithKeyPath:@"shadowOpacity"];
pulseShadowOpacityAnimation.fromValue = PearlFloat(0.2);
pulseShadowOpacityAnimation.toValue = PearlFloat(0.6);
pulseShadowOpacityAnimation.beginTime = 0.5f;
pulseShadowOpacityAnimation.duration = 2.0f;
pulseShadowOpacityAnimation.autoreverses = YES;
pulseShadowOpacityAnimation.repeatCount = MAXFLOAT;
CAAnimationGroup *group = [[CAAnimationGroup alloc] init];
group.animations = [NSArray arrayWithObjects:toShadowColorAnimation, toShadowOpacityAnimation, pulseShadowOpacityAnimation, nil];
group.duration = MAXFLOAT;
[avatar.layer removeAnimationForKey:@"inactiveShadow"];
[avatar.layer addAnimation:group forKey:@"targetedShadow"];
}
} else {
if ([avatar.layer animationForKey:@"targetedShadow"]) {
CABasicAnimation *toShadowColorAnimation = [CABasicAnimation animationWithKeyPath:@"shadowColor"];
toShadowColorAnimation.toValue = (__bridge id) [UIColor blackColor].CGColor;
toShadowColorAnimation.duration = 0.5f;
CABasicAnimation *toShadowOpacityAnimation = [CABasicAnimation animationWithKeyPath:@"shadowOpacity"];
toShadowOpacityAnimation.toValue = PearlFloat(1);
toShadowOpacityAnimation.duration = 0.5f;
CAAnimationGroup *group = [[CAAnimationGroup alloc] init];
group.animations = [NSArray arrayWithObjects:toShadowColorAnimation, toShadowOpacityAnimation, nil];
group.duration = 0.5f;
[avatar.layer removeAnimationForKey:@"targetedShadow"];
[avatar.layer addAnimation:group forKey:@"inactiveShadow"];
}
}
}
#pragma mark - UITextFieldDelegate #pragma mark - UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField { - (BOOL)textFieldShouldReturn:(UITextField *)textField {
if (![textField.text length])
return NO;
[textField resignFirstResponder]; [textField resignFirstResponder];
CABasicAnimation *rotate = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; [self setSpinnerActive:YES];
rotate.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; [self changeAvatarShadowColorTo:[UIColor colorWithName:@"lightskyblue"]];
rotate.fromValue = [NSNumber numberWithFloat:0];
rotate.toValue = [NSNumber numberWithDouble:2 * M_PI];
rotate.repeatCount = MAXFLOAT;
rotate.duration = 3.0;
[self.spinner.layer removeAllAnimations]; if (self.selectedUser.keyID)
[self.spinner.layer addAnimation:rotate forKey:@"transform"]; [self tryMasterPassword];
[UIView animateWithDuration:0.3f animations:^{ else
self.spinner.alpha = 1.0f;
}];
// [self showMessage:@"Checking password..." state:MPLockscreenProgress];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
BOOL unlocked = [[MPAppDelegate get] tryMasterPassword:textField.text forUser:self.selectedUser];
dispatch_async(dispatch_get_main_queue(), ^{
if (unlocked) {
// [self showMessage:@"Success!" state:MPLockscreenSuccess];
if ([selectedUser.keyID length])
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (long)(NSEC_PER_SEC * 1.5f)), dispatch_get_main_queue(), ^{
[self dismissModalViewControllerAnimated:YES];
});
else {
[PearlAlert showAlertWithTitle:@"New Master Password" [PearlAlert showAlertWithTitle:@"New Master Password"
message:@"Please confirm the spelling of this new master password." message:@"Please confirm the spelling of this new master password."
viewStyle:UIAlertViewStyleSecureTextInput viewStyle:UIAlertViewStyleSecureTextInput
initAlert:nil initAlert:nil tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) {
tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) { [self setSpinnerActive:NO];
if (buttonIndex == [alert cancelButtonIndex]) {
[[MPAppDelegate get] unsetKey]; if (buttonIndex == [alert cancelButtonIndex])
return; return;
}
if (![[alert textFieldAtIndex:0].text isEqualToString:textField.text]) { if (![[alert textFieldAtIndex:0].text isEqualToString:textField.text]) {
[PearlAlert showAlertWithTitle:@"Incorrect Master Password" [PearlAlert showAlertWithTitle:@"Incorrect Master Password"
@ -377,36 +430,15 @@
@"The password you entered doesn't match with the master password you tried to use. " @"The password you entered doesn't match with the master password you tried to use. "
@"You've probably mistyped one of them.\n\n" @"You've probably mistyped one of them.\n\n"
@"Give it another try." @"Give it another try."
viewStyle:UIAlertViewStyleDefault initAlert:nil tappedButtonBlock:nil viewStyle:UIAlertViewStyleDefault initAlert:nil tappedButtonBlock:nil cancelTitle:[PearlStrings get].commonButtonOkay otherTitles:nil];
cancelTitle:[PearlStrings get].commonButtonOkay otherTitles:nil];
return; return;
} }
self.selectedUser.keyID = [MPAppDelegate get].activeUser.keyID; [self tryMasterPassword];
[[MPAppDelegate get] saveContext];
[self dismissModalViewControllerAnimated:YES];
} }
cancelTitle:[PearlStrings get].commonButtonCancel cancelTitle:[PearlStrings get].commonButtonCancel
otherTitles:[PearlStrings get].commonButtonContinue, nil]; otherTitles:[PearlStrings get].commonButtonContinue, nil];
}
} else {
// [self showMessage:@"Not valid." state:MPLockscreenError];
[UIView animateWithDuration:0.5f animations:^{
// self.changeMPView.alpha = 1.0f;
}];
}
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.3f animations:^{
self.spinner.alpha = 0.0f;
} completion:^(BOOL finished) {
[self.spinner.layer removeAllAnimations];
}];
});
});
});
return YES; return YES;
} }
@ -416,54 +448,30 @@
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset { - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
CGFloat xOfMiddle = targetContentOffset->x + scrollView.bounds.size.width / 2; CGFloat xOfMiddle = targetContentOffset->x + scrollView.bounds.size.width / 2;
UIButton *middleAvatar = (UIButton *)[PearlUIUtils viewClosestTo:CGPointMake(xOfMiddle, targetContentOffset->y) ofArray:scrollView.subviews]; UIButton *middleAvatar = (UIButton *) [PearlUIUtils viewClosestTo:CGPointMake(xOfMiddle, targetContentOffset->y) ofArray:scrollView.subviews];
*targetContentOffset = CGPointMake(middleAvatar.center.x - scrollView.bounds.size.width / 2, targetContentOffset->y); *targetContentOffset = CGPointMake(middleAvatar.center.x - scrollView.bounds.size.width / 2, targetContentOffset->y);
[self updateLayoutAnimated:NO allowScroll:NO completion:nil]; [self updateLayoutAnimated:NO allowScroll:NO completion:nil];
// [self scrollToAvatar:middleAvatar animated:YES]; // [self scrollToAvatar:middleAvatar animated:YES];
} }
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
[self updateLayoutAnimated:YES allowScroll:YES completion:nil]; [self updateLayoutAnimated:YES allowScroll:YES completion:nil];
// [self scrollToAvatar:middleAvatar animated:YES]; // [self scrollToAvatar:middleAvatar animated:YES];
} }
- (void)scrollViewDidScroll:(UIScrollView *)scrollView { - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// CGFloat xOfMiddle = scrollView.contentOffset.x + scrollView.bounds.size.width / 2; // CGFloat xOfMiddle = scrollView.contentOffset.x + scrollView.bounds.size.width / 2;
// UIButton *middleAvatar = (UIButton *)[PearlUIUtils viewClosestTo:CGPointMake(xOfMiddle, scrollView.contentOffset.y) ofArray:scrollView.subviews]; // UIButton *middleAvatar = (UIButton *)[PearlUIUtils viewClosestTo:CGPointMake(xOfMiddle, scrollView.contentOffset.y) ofArray:scrollView.subviews];
// //
[self updateLayoutAnimated:NO allowScroll:NO completion:nil]; [self updateLayoutAnimated:NO allowScroll:NO completion:nil];
// [self scrollToAvatar:middleAvatar animated:NO]; // [self scrollToAvatar:middleAvatar animated:NO];
} }
#pragma mark - IBActions #pragma mark - IBActions
- (IBAction)changeMP {
[PearlAlert showAlertWithTitle:@"Changing Master Password"
message:
@"This will allow you to log in with a different master password.\n\n"
@"Note that you will only see the sites and passwords for the master password you log in with.\n"
@"If you log in with a different master password, your current sites will be unavailable.\n\n"
@"You can always change back to your current master password later.\n"
@"Your current sites and passwords will then become available again."
viewStyle:UIAlertViewStyleDefault
initAlert:nil
tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) {
if (buttonIndex == [alert cancelButtonIndex])
return;
[[MPAppDelegate get] forgetSavedKey];
[[MPAppDelegate get] loadKey:YES];
[TestFlight passCheckpoint:MPTestFlightCheckpointMPChanged];
}
cancelTitle:[PearlStrings get].commonButtonAbort
otherTitles:[PearlStrings get].commonButtonContinue, nil];
}
- (IBAction)deleteTargetedUser:(UILongPressGestureRecognizer *)sender { - (IBAction)deleteTargetedUser:(UILongPressGestureRecognizer *)sender {
if (sender.state != UIGestureRecognizerStateBegan) if (sender.state != UIGestureRecognizerStateBegan)
@ -479,8 +487,7 @@
[PearlAlert showAlertWithTitle:@"Delete User" message: [PearlAlert showAlertWithTitle:@"Delete User" message:
PearlString(@"Do you want to delete all record of the following user?\n\n%@", targetedUser.name) PearlString(@"Do you want to delete all record of the following user?\n\n%@", targetedUser.name)
viewStyle:UIAlertViewStyleDefault viewStyle:UIAlertViewStyleDefault
initAlert:nil initAlert:nil tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) {
tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) {
if (buttonIndex == [alert cancelButtonIndex]) if (buttonIndex == [alert cancelButtonIndex])
return; return;

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="1.1" toolsVersion="2182" systemVersion="11E53" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="KZF-fe-y9n"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="1.1" toolsVersion="2182" systemVersion="11E53" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="KZF-fe-y9n">
<dependencies> <dependencies>
<deployment defaultVersion="1296" identifier="iOS"/>
<development defaultVersion="4200" identifier="xcode"/> <development defaultVersion="4200" identifier="xcode"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="1181"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="1181"/>
</dependencies> </dependencies>
@ -782,7 +783,7 @@ L4m3P4sSw0rD</string>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view> </view>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="ui_spinner.png" id="27q-lX-0vy"> <imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="ui_spinner.png" id="27q-lX-0vy">
<rect key="frame" x="105" y="29" width="110" height="110"/> <rect key="frame" x="105" y="30" width="110" height="110"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView> </imageView>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" delaysContentTouches="NO" id="Blg-F1-9NA"> <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" delaysContentTouches="NO" id="Blg-F1-9NA">
@ -792,9 +793,9 @@ L4m3P4sSw0rD</string>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="top" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" id="Ten-ig-gog"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="top" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" id="Ten-ig-gog">
<rect key="frame" x="105" y="10" width="110" height="110"/> <rect key="frame" x="105" y="10" width="110" height="110"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.40000000596046448" green="0.80000001192092896" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/> <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" backgroundImage="avatar-male-1.png"> <state key="normal" backgroundImage="avatar-0.png">
<color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/> <color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state> </state>
@ -834,14 +835,14 @@ L4m3P4sSw0rD</string>
</view> </view>
<nil key="simulatedStatusBarMetrics"/> <nil key="simulatedStatusBarMetrics"/>
<connections> <connections>
<outlet property="avatarTemplate" destination="Ten-ig-gog" id="0ZZ-z5-d5m"/>
<outlet property="avatarsView" destination="Blg-F1-9NA" id="2NL-jU-IMI"/>
<outlet property="deleteTip" destination="DBJ-Qi-ZcF" id="VXD-Zc-UYi"/> <outlet property="deleteTip" destination="DBJ-Qi-ZcF" id="VXD-Zc-UYi"/>
<outlet property="oldUsernameLabel" destination="8s0-nT-Aoq" id="mXR-VG-2js"/> <outlet property="nameLabel" destination="0NM-NI-7UR" id="GBg-Ry-sqj"/>
<outlet property="oldNameLabel" destination="8s0-nT-Aoq" id="plu-1H-MVc"/>
<outlet property="passwordField" destination="rTR-7Q-X8o" id="CDA-iP-kCm"/> <outlet property="passwordField" destination="rTR-7Q-X8o" id="CDA-iP-kCm"/>
<outlet property="passwordView" destination="7cc-yu-i0m" id="WoF-Ab-PPC"/> <outlet property="passwordView" destination="7cc-yu-i0m" id="WoF-Ab-PPC"/>
<outlet property="spinner" destination="27q-lX-0vy" id="jUx-GK-Lgf"/> <outlet property="spinner" destination="27q-lX-0vy" id="CGK-G9-PRI"/>
<outlet property="userButtonTemplate" destination="Ten-ig-gog" id="hSM-hh-ofy"/>
<outlet property="usernameLabel" destination="0NM-NI-7UR" id="Sa4-pY-87O"/>
<outlet property="usersView" destination="Blg-F1-9NA" id="SsC-1H-fIB"/>
</connections> </connections>
</viewController> </viewController>
<pongPressGestureRecognizer allowableMovement="10" minimumPressDuration="0.5" id="9WS-yS-aqQ"> <pongPressGestureRecognizer allowableMovement="10" minimumPressDuration="0.5" id="9WS-yS-aqQ">
@ -892,14 +893,14 @@ L4m3P4sSw0rD</string>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.12549020350000001" green="0.1411764771" blue="0.14901961389999999" alpha="1" colorSpace="calibratedRGB"/> <color key="backgroundColor" red="0.12549020350000001" green="0.1411764771" blue="0.14901961389999999" alpha="1" colorSpace="calibratedRGB"/>
<view key="tableFooterView" contentMode="scaleToFill" id="63M-7L-M7o"> <view key="tableFooterView" contentMode="scaleToFill" id="63M-7L-M7o">
<rect key="frame" x="0.0" y="508" width="320" height="20"/> <rect key="frame" x="0.0" y="492" width="320" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view> </view>
<sections> <sections>
<tableViewSection id="OJv-8V-W2l"> <tableViewSection id="OJv-8V-W2l">
<cells> <cells>
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" rowHeight="226" id="9gC-Vq-Ta8"> <tableViewCell contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" rowHeight="226" id="9gC-Vq-Ta8">
<rect key="frame" x="0.0" y="0.0" width="320" height="226"/> <rect key="frame" x="0.0" y="0.0" width="320" height="226"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center"> <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
@ -924,19 +925,16 @@ L4m3P4sSw0rD</string>
<color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/> <color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/>
<size key="shadowOffset" width="0.0" height="1"/> <size key="shadowOffset" width="0.0" height="1"/>
</label> </label>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" id="TMH-Xt-EnD"> <scrollView multipleTouchEnabled="YES" contentMode="scaleToFill" id="TMH-Xt-EnD">
<rect key="frame" x="0.0" y="95" width="320" height="130"/> <rect key="frame" x="0.0" y="95" width="320" height="130"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<view contentMode="scaleToFill" id="jEL-UA-da6"> <button opaque="NO" contentMode="scaleToFill" selected="YES" contentHorizontalAlignment="center" contentVerticalAlignment="top" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" id="6ap-Xw-Ubd">
<rect key="frame" x="0.0" y="0.0" width="614" height="130"/>
<autoresizingMask key="autoresizingMask" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="top" lineBreakMode="middleTruncation" id="6ap-Xw-Ubd">
<rect key="frame" x="20" y="10" width="110" height="110"/> <rect key="frame" x="20" y="10" width="110" height="110"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.40000000600000002" green="0.80000001190000003" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/> <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="avatar-male-1.png"> <state key="normal" backgroundImage="avatar-0.png">
<color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/> <color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state> </state>
@ -944,57 +942,6 @@ L4m3P4sSw0rD</string>
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state> </state>
</button> </button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="top" lineBreakMode="middleTruncation" id="DwC-Fa-yaI">
<rect key="frame" x="138" y="10" width="110" height="110"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="avatar-female-1.png">
<color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<state key="highlighted">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="top" lineBreakMode="middleTruncation" id="TF1-Zi-jZK">
<rect key="frame" x="256" y="10" width="110" height="110"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="avatar-male-2.png">
<color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<state key="highlighted">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="top" lineBreakMode="middleTruncation" id="32d-Yo-SGt">
<rect key="frame" x="366" y="10" width="110" height="110"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="avatar-female-2.png">
<color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<state key="highlighted">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="top" lineBreakMode="middleTruncation" id="LTD-gI-8bH">
<rect key="frame" x="484" y="10" width="110" height="110"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="avatar-male-3.png">
<color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<state key="highlighted">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
</subviews> </subviews>
</scrollView> </scrollView>
</subviews> </subviews>
@ -1006,11 +953,11 @@ L4m3P4sSw0rD</string>
</tableViewSection> </tableViewSection>
<tableViewSection id="TRa-Gy-tG5"> <tableViewSection id="TRa-Gy-tG5">
<cells> <cells>
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" rowHeight="119" id="n1H-sG-HDc"> <tableViewCell contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" rowHeight="66" id="n1H-sG-HDc">
<rect key="frame" x="0.0" y="226" width="320" height="119"/> <rect key="frame" x="0.0" y="226" width="320" height="66"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center"> <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="320" height="118"/> <rect key="frame" x="0.0" y="0.0" width="320" height="65"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Preferences" lineBreakMode="tailTruncation" minimumFontSize="10" id="ylz-i5-tem"> <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Preferences" lineBreakMode="tailTruncation" minimumFontSize="10" id="ylz-i5-tem">
@ -1031,18 +978,30 @@ L4m3P4sSw0rD</string>
<color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/> <color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/>
<size key="shadowOffset" width="0.0" height="1"/> <size key="shadowOffset" width="0.0" height="1"/>
</label> </label>
<imageView userInteractionEnabled="NO" contentMode="top" image="ui_list_first.png" id="tK4-bL-QK1"> </subviews>
<rect key="frame" x="10" y="75" width="300" height="50"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" rowHeight="44" id="0jz-0D-ggZ">
<rect key="frame" x="0.0" y="292" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="top" image="ui_list_first.png" id="8dk-FW-Tse">
<rect key="frame" x="10" y="0.0" width="300" height="50"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<rect key="contentStretch" x="0.10000000000000001" y="0.20000000000000001" width="0.79999999999999982" height="0.59999999999999964"/> <rect key="contentStretch" x="0.10000000000000001" y="0.20000000000000001" width="0.79999999999999982" height="0.59999999999999964"/>
</imageView> </imageView>
<imageView userInteractionEnabled="NO" contentMode="bottom" image="ui_list_last.png" id="fAY-fK-Uzn"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="bottom" image="ui_list_last.png" id="5oz-I2-Nos">
<rect key="frame" x="10" y="109" width="300" height="10"/> <rect key="frame" x="10" y="34" width="300" height="10"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<rect key="contentStretch" x="0.10000000000000001" y="0.20000000000000001" width="0.79999999999999982" height="0.59999999999999964"/> <rect key="contentStretch" x="0.10000000000000001" y="0.20000000000000001" width="0.79999999999999982" height="0.59999999999999964"/>
</imageView> </imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Save Password" lineBreakMode="tailTruncation" minimumFontSize="10" id="mmP-r2-iNF"> <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Save Password" lineBreakMode="tailTruncation" minimumFontSize="10" id="0Mf-7e-quo">
<rect key="frame" x="20" y="75" width="280" height="23"/> <rect key="frame" x="20" y="0.0" width="280" height="23"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<fontDescription key="fontDescription" name="GillSans" family="Gill Sans" pointSize="18"/> <fontDescription key="fontDescription" name="GillSans" family="Gill Sans" pointSize="18"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
@ -1050,17 +1009,20 @@ L4m3P4sSw0rD</string>
<color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/> <color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/>
<size key="shadowOffset" width="0.0" height="1"/> <size key="shadowOffset" width="0.0" height="1"/>
</label> </label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Stores your password on the device." lineBreakMode="tailTruncation" minimumFontSize="10" id="LRv-ac-sdH"> <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Stores your password on the device." lineBreakMode="tailTruncation" minimumFontSize="10" id="Hfj-40-OHR">
<rect key="frame" x="20" y="98" width="280" height="20"/> <rect key="frame" x="20" y="23" width="280" height="20"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<fontDescription key="fontDescription" name="GillSans-LightItalic" family="Gill Sans" pointSize="14"/> <fontDescription key="fontDescription" name="GillSans-LightItalic" family="Gill Sans" pointSize="14"/>
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/> <color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<switch opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" id="seh-qE-k6P"> <switch opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" id="ilG-0h-SOb">
<rect key="frame" x="221" y="83" width="79" height="27"/> <rect key="frame" x="221" y="8" width="79" height="27"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="onTintColor" red="0.12549020350000001" green="0.1411764771" blue="0.14901961389999999" alpha="1" colorSpace="calibratedRGB"/> <color key="onTintColor" red="0.12549020350000001" green="0.1411764771" blue="0.14901961389999999" alpha="1" colorSpace="calibratedRGB"/>
<connections>
<action selector="didToggleSwitch:" destination="oLN-6u-GLb" eventType="valueChanged" id="e5q-mf-XK7"/>
</connections>
</switch> </switch>
</subviews> </subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
@ -1071,11 +1033,11 @@ L4m3P4sSw0rD</string>
</tableViewSection> </tableViewSection>
<tableViewSection id="dN3-cJ-9WA"> <tableViewSection id="dN3-cJ-9WA">
<cells> <cells>
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" rowHeight="119" id="xBt-OT-BYA"> <tableViewCell contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" rowHeight="68" id="xBt-OT-BYA">
<rect key="frame" x="0.0" y="345" width="320" height="119"/> <rect key="frame" x="0.0" y="336" width="320" height="68"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center"> <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="320" height="118"/> <rect key="frame" x="0.0" y="0.0" width="320" height="67"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Operations" lineBreakMode="tailTruncation" minimumFontSize="10" id="VI9-uT-nrJ"> <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Operations" lineBreakMode="tailTruncation" minimumFontSize="10" id="VI9-uT-nrJ">
@ -1096,13 +1058,25 @@ L4m3P4sSw0rD</string>
<color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/> <color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/>
<size key="shadowOffset" width="0.0" height="1"/> <size key="shadowOffset" width="0.0" height="1"/>
</label> </label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="ui_list_first.png" id="zeK-qR-5wK"> </subviews>
<rect key="frame" x="10" y="75" width="300" height="44"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" rowHeight="44" id="X2m-92-Qzh">
<rect key="frame" x="0.0" y="404" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="ui_list_first.png" id="s1D-Yv-FNl">
<rect key="frame" x="10" y="0.0" width="300" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<rect key="contentStretch" x="0.10000000000000001" y="0.20000000000000001" width="0.79999999999999982" height="0.59999999999999964"/> <rect key="contentStretch" x="0.10000000000000001" y="0.20000000000000001" width="0.79999999999999982" height="0.59999999999999964"/>
</imageView> </imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Export" lineBreakMode="tailTruncation" minimumFontSize="10" id="DTP-qu-VqT"> <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Export" lineBreakMode="tailTruncation" minimumFontSize="10" id="Sw0-Yj-Xh0">
<rect key="frame" x="20" y="75" width="280" height="23"/> <rect key="frame" x="20" y="0.0" width="280" height="23"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<fontDescription key="fontDescription" name="GillSans" family="Gill Sans" pointSize="18"/> <fontDescription key="fontDescription" name="GillSans" family="Gill Sans" pointSize="18"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
@ -1110,8 +1084,8 @@ L4m3P4sSw0rD</string>
<color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/> <color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/>
<size key="shadowOffset" width="0.0" height="1"/> <size key="shadowOffset" width="0.0" height="1"/>
</label> </label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Save all your sites to a file." lineBreakMode="tailTruncation" minimumFontSize="10" id="oi9-2Y-2KM"> <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Save all your sites to a file." lineBreakMode="tailTruncation" minimumFontSize="10" id="DwF-cT-vUT">
<rect key="frame" x="20" y="98" width="280" height="20"/> <rect key="frame" x="20" y="23" width="280" height="20"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<fontDescription key="fontDescription" name="GillSans-LightItalic" family="Gill Sans" pointSize="14"/> <fontDescription key="fontDescription" name="GillSans-LightItalic" family="Gill Sans" pointSize="14"/>
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/> <color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
@ -1123,7 +1097,7 @@ L4m3P4sSw0rD</string>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</tableViewCell> </tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" id="glr-eJ-qKq"> <tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" id="glr-eJ-qKq">
<rect key="frame" x="0.0" y="464" width="320" height="44"/> <rect key="frame" x="0.0" y="448" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center"> <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="320" height="43"/> <rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
@ -1171,7 +1145,11 @@ L4m3P4sSw0rD</string>
</barButtonItem> </barButtonItem>
</navigationItem> </navigationItem>
<connections> <connections>
<outlet property="avatarScrollView" destination="TMH-Xt-EnD" id="zdf-xt-piZ"/> <outlet property="avatarTemplate" destination="6ap-Xw-Ubd" id="WW7-3k-5QJ"/>
<outlet property="avatarsView" destination="TMH-Xt-EnD" id="zdf-xt-piZ"/>
<outlet property="changeMPCell" destination="glr-eJ-qKq" id="EpZ-xu-JGh"/>
<outlet property="exportCell" destination="X2m-92-Qzh" id="zjs-9C-uKX"/>
<outlet property="savePasswordSwitch" destination="ilG-0h-SOb" id="iZD-gQ-pve"/>
</connections> </connections>
</tableViewController> </tableViewController>
</objects> </objects>
@ -1180,11 +1158,7 @@ L4m3P4sSw0rD</string>
</scenes> </scenes>
<resources> <resources>
<image name="Square-bottom.png" width="551" height="58"/> <image name="Square-bottom.png" width="551" height="58"/>
<image name="avatar-female-1.png" width="110" height="110"/> <image name="avatar-0.png" width="110" height="110"/>
<image name="avatar-female-2.png" width="110" height="110"/>
<image name="avatar-male-1.png" width="110" height="110"/>
<image name="avatar-male-2.png" width="110" height="110"/>
<image name="avatar-male-3.png" width="110" height="110"/>
<image name="background.png" width="480" height="480"/> <image name="background.png" width="480" height="480"/>
<image name="guide_page_0.png" width="320" height="480"/> <image name="guide_page_0.png" width="320" height="480"/>
<image name="guide_page_1.png" width="320" height="480"/> <image name="guide_page_1.png" width="320" height="480"/>
@ -1260,7 +1234,12 @@ L4m3P4sSw0rD</string>
<class className="MPPreferencesViewController" superclassName="UITableViewController"> <class className="MPPreferencesViewController" superclassName="UITableViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPPreferencesViewController.h"/> <source key="sourceIdentifier" type="project" relativePath="./Classes/MPPreferencesViewController.h"/>
<relationships> <relationships>
<relationship kind="outlet" name="avatarScrollView" candidateClass="UIScrollView"/> <relationship kind="action" name="didToggleSwitch:" candidateClass="UISwitch"/>
<relationship kind="outlet" name="avatarTemplate" candidateClass="UIButton"/>
<relationship kind="outlet" name="avatarsView" candidateClass="UIScrollView"/>
<relationship kind="outlet" name="changeMPCell" candidateClass="UITableViewCell"/>
<relationship kind="outlet" name="exportCell" candidateClass="UITableViewCell"/>
<relationship kind="outlet" name="savePasswordSwitch" candidateClass="UISwitch"/>
</relationships> </relationships>
</class> </class>
<class className="MPSearchDelegate" superclassName="NSObject"> <class className="MPSearchDelegate" superclassName="NSObject">
@ -1281,14 +1260,14 @@ L4m3P4sSw0rD</string>
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPUnlockViewController.h"/> <source key="sourceIdentifier" type="project" relativePath="./Classes/MPUnlockViewController.h"/>
<relationships> <relationships>
<relationship kind="action" name="deleteTargetedUser:" candidateClass="UILongPressGestureRecognizer"/> <relationship kind="action" name="deleteTargetedUser:" candidateClass="UILongPressGestureRecognizer"/>
<relationship kind="outlet" name="avatarTemplate" candidateClass="UIButton"/>
<relationship kind="outlet" name="avatarsView" candidateClass="UIScrollView"/>
<relationship kind="outlet" name="deleteTip" candidateClass="UILabel"/> <relationship kind="outlet" name="deleteTip" candidateClass="UILabel"/>
<relationship kind="outlet" name="oldUsernameLabel" candidateClass="UILabel"/> <relationship kind="outlet" name="nameLabel" candidateClass="UILabel"/>
<relationship kind="outlet" name="oldNameLabel" candidateClass="UILabel"/>
<relationship kind="outlet" name="passwordField" candidateClass="UITextField"/> <relationship kind="outlet" name="passwordField" candidateClass="UITextField"/>
<relationship kind="outlet" name="passwordView" candidateClass="UIView"/> <relationship kind="outlet" name="passwordView" candidateClass="UIView"/>
<relationship kind="outlet" name="spinner" candidateClass="UIImageView"/> <relationship kind="outlet" name="spinner" candidateClass="UIImageView"/>
<relationship kind="outlet" name="userButtonTemplate" candidateClass="UIButton"/>
<relationship kind="outlet" name="usernameLabel" candidateClass="UILabel"/>
<relationship kind="outlet" name="usersView" candidateClass="UIScrollView"/>
</relationships> </relationships>
</class> </class>
</classes> </classes>

View File

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB