From 77306e0046c942fd234bd3d3b3e540a352731273 Mon Sep 17 00:00:00 2001 From: Maarten Billemont Date: Wed, 6 Jun 2012 00:59:09 +0200 Subject: [PATCH] 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. --- External/Pearl | 2 +- MasterPassword-iOS.xcodeproj/project.pbxproj | 304 +++++----- MasterPassword/MPAppDelegate_Key.m | 16 +- MasterPassword/MPEntities.h | 2 + MasterPassword/MPTypes.m | 2 +- .../Mac/MPPasswordWindowController.m | 2 +- MasterPassword/iOS/MPAppDelegate.h | 1 + MasterPassword/iOS/MPAppDelegate.m | 23 + MasterPassword/iOS/MPMainViewController.m | 12 +- .../iOS/MPPreferencesViewController.h | 8 +- .../iOS/MPPreferencesViewController.m | 95 +++- MasterPassword/iOS/MPSearchDelegate.m | 2 +- MasterPassword/iOS/MPUnlockViewController.h | 10 +- MasterPassword/iOS/MPUnlockViewController.m | 535 +++++++++--------- .../iOS/MainStoryboard_iPhone.storyboard | 205 +++---- .../{avatar-male-1.png => avatar-0.png} | Bin .../{avatar-male-1@2x.png => avatar-0@2x.png} | Bin .../{avatar-male-2.png => avatar-1.png} | Bin .../{avatar-female-1.png => avatar-10.png} | Bin ...vatar-female-1@2x.png => avatar-10@2x.png} | Bin .../{avatar-female-2.png => avatar-11.png} | Bin ...vatar-female-2@2x.png => avatar-11@2x.png} | Bin ...-female-silhouette-1.png => avatar-12.png} | Bin ...e-silhouette-1@2x.png => avatar-12@2x.png} | Bin ...-female-silhouette-2.png => avatar-13.png} | Bin ...e-silhouette-2@2x.png => avatar-13@2x.png} | Bin ...-female-silhouette-3.png => avatar-14.png} | Bin ...e-silhouette-3@2x.png => avatar-14@2x.png} | Bin ...-female-silhouette-4.png => avatar-15.png} | Bin ...e-silhouette-4@2x.png => avatar-15@2x.png} | Bin ...-female-silhouette-5.png => avatar-16.png} | Bin ...e-silhouette-5@2x.png => avatar-16@2x.png} | Bin ...-female-silhouette-6.png => avatar-17.png} | Bin ...e-silhouette-6@2x.png => avatar-17@2x.png} | Bin ...-female-silhouette-7.png => avatar-18.png} | Bin ...e-silhouette-7@2x.png => avatar-18@2x.png} | Bin .../{avatar-male-2@2x.png => avatar-1@2x.png} | Bin .../{avatar-male-3.png => avatar-2.png} | Bin .../{avatar-male-3@2x.png => avatar-2@2x.png} | Bin ...tar-male-silhouette-1.png => avatar-3.png} | Bin ...le-silhouette-1@2x.png => avatar-3@2x.png} | Bin ...tar-male-silhouette-2.png => avatar-4.png} | Bin ...le-silhouette-2@2x.png => avatar-4@2x.png} | Bin ...tar-male-silhouette-3.png => avatar-5.png} | Bin ...le-silhouette-3@2x.png => avatar-5@2x.png} | Bin ...tar-male-silhouette-4.png => avatar-6.png} | Bin ...le-silhouette-4@2x.png => avatar-6@2x.png} | Bin ...tar-male-silhouette-5.png => avatar-7.png} | Bin ...le-silhouette-5@2x.png => avatar-7@2x.png} | Bin ...tar-male-silhouette-6.png => avatar-8.png} | Bin ...le-silhouette-6@2x.png => avatar-8@2x.png} | Bin ...tar-male-silhouette-7.png => avatar-9.png} | Bin ...le-silhouette-7@2x.png => avatar-9@2x.png} | Bin 53 files changed, 648 insertions(+), 571 deletions(-) rename Resources/Avatars/{avatar-male-1.png => avatar-0.png} (100%) rename Resources/Avatars/{avatar-male-1@2x.png => avatar-0@2x.png} (100%) rename Resources/Avatars/{avatar-male-2.png => avatar-1.png} (100%) rename Resources/Avatars/{avatar-female-1.png => avatar-10.png} (100%) rename Resources/Avatars/{avatar-female-1@2x.png => avatar-10@2x.png} (100%) rename Resources/Avatars/{avatar-female-2.png => avatar-11.png} (100%) rename Resources/Avatars/{avatar-female-2@2x.png => avatar-11@2x.png} (100%) rename Resources/Avatars/{avatar-female-silhouette-1.png => avatar-12.png} (100%) rename Resources/Avatars/{avatar-female-silhouette-1@2x.png => avatar-12@2x.png} (100%) rename Resources/Avatars/{avatar-female-silhouette-2.png => avatar-13.png} (100%) rename Resources/Avatars/{avatar-female-silhouette-2@2x.png => avatar-13@2x.png} (100%) rename Resources/Avatars/{avatar-female-silhouette-3.png => avatar-14.png} (100%) rename Resources/Avatars/{avatar-female-silhouette-3@2x.png => avatar-14@2x.png} (100%) rename Resources/Avatars/{avatar-female-silhouette-4.png => avatar-15.png} (100%) rename Resources/Avatars/{avatar-female-silhouette-4@2x.png => avatar-15@2x.png} (100%) rename Resources/Avatars/{avatar-female-silhouette-5.png => avatar-16.png} (100%) rename Resources/Avatars/{avatar-female-silhouette-5@2x.png => avatar-16@2x.png} (100%) rename Resources/Avatars/{avatar-female-silhouette-6.png => avatar-17.png} (100%) rename Resources/Avatars/{avatar-female-silhouette-6@2x.png => avatar-17@2x.png} (100%) rename Resources/Avatars/{avatar-female-silhouette-7.png => avatar-18.png} (100%) rename Resources/Avatars/{avatar-female-silhouette-7@2x.png => avatar-18@2x.png} (100%) rename Resources/Avatars/{avatar-male-2@2x.png => avatar-1@2x.png} (100%) rename Resources/Avatars/{avatar-male-3.png => avatar-2.png} (100%) rename Resources/Avatars/{avatar-male-3@2x.png => avatar-2@2x.png} (100%) rename Resources/Avatars/{avatar-male-silhouette-1.png => avatar-3.png} (100%) rename Resources/Avatars/{avatar-male-silhouette-1@2x.png => avatar-3@2x.png} (100%) rename Resources/Avatars/{avatar-male-silhouette-2.png => avatar-4.png} (100%) rename Resources/Avatars/{avatar-male-silhouette-2@2x.png => avatar-4@2x.png} (100%) rename Resources/Avatars/{avatar-male-silhouette-3.png => avatar-5.png} (100%) rename Resources/Avatars/{avatar-male-silhouette-3@2x.png => avatar-5@2x.png} (100%) rename Resources/Avatars/{avatar-male-silhouette-4.png => avatar-6.png} (100%) rename Resources/Avatars/{avatar-male-silhouette-4@2x.png => avatar-6@2x.png} (100%) rename Resources/Avatars/{avatar-male-silhouette-5.png => avatar-7.png} (100%) rename Resources/Avatars/{avatar-male-silhouette-5@2x.png => avatar-7@2x.png} (100%) rename Resources/Avatars/{avatar-male-silhouette-6.png => avatar-8.png} (100%) rename Resources/Avatars/{avatar-male-silhouette-6@2x.png => avatar-8@2x.png} (100%) rename Resources/Avatars/{avatar-male-silhouette-7.png => avatar-9.png} (100%) rename Resources/Avatars/{avatar-male-silhouette-7@2x.png => avatar-9@2x.png} (100%) diff --git a/External/Pearl b/External/Pearl index 1ce39007..e9dd56bc 160000 --- a/External/Pearl +++ b/External/Pearl @@ -1 +1 @@ -Subproject commit 1ce39007b6018ac4991b4ec0ee5158ba019bcac1 +Subproject commit e9dd56bc64735ebd28eef6c6dc748f480acc7c67 diff --git a/MasterPassword-iOS.xcodeproj/project.pbxproj b/MasterPassword-iOS.xcodeproj/project.pbxproj index 912bdd33..b12d66ed 100644 --- a/MasterPassword-iOS.xcodeproj/project.pbxproj +++ b/MasterPassword-iOS.xcodeproj/project.pbxproj @@ -41,44 +41,6 @@ DA600C2815056428008E9AB6 /* MPConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = DA600C2715056427008E9AB6 /* MPConfig.m */; }; DA672D2F14F92C6B004A189C /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DA672D2E14F92C6B004A189C /* libz.dylib */; }; 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 */; }; DA95D5CF14DF0691008D1B94 /* IASKAppSettingsViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = DA95D5A814DF0691008D1B94 /* IASKAppSettingsViewController.h */; }; 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 */; }; DAD312BF1552A1BD00A3F9ED /* libLocalytics.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAD3127115528CD200A3F9ED /* libLocalytics.a */; }; 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 */; }; 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 */; }; @@ -952,44 +952,6 @@ 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 = ""; }; DA79A9BD1557DDC700BAA07A /* scrypt.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = scrypt.xcodeproj; path = External/Pearl/External/iOSPorts/ports/security/scrypt/scrypt.xcodeproj; sourceTree = ""; }; - DA7DEFC2157978AC009D2085 /* avatar-female-1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-1.png"; sourceTree = ""; }; - DA7DEFC3157978AC009D2085 /* avatar-female-1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-1@2x.png"; sourceTree = ""; }; - DA7DEFC4157978AC009D2085 /* avatar-female-2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-2.png"; sourceTree = ""; }; - DA7DEFC5157978AC009D2085 /* avatar-female-2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-2@2x.png"; sourceTree = ""; }; - DA7DEFC6157978AC009D2085 /* avatar-female-silhouette-1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-1.png"; sourceTree = ""; }; - DA7DEFC7157978AC009D2085 /* avatar-female-silhouette-1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-1@2x.png"; sourceTree = ""; }; - DA7DEFC8157978AC009D2085 /* avatar-female-silhouette-2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-2.png"; sourceTree = ""; }; - DA7DEFC9157978AC009D2085 /* avatar-female-silhouette-2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-2@2x.png"; sourceTree = ""; }; - DA7DEFCA157978AC009D2085 /* avatar-female-silhouette-3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-3.png"; sourceTree = ""; }; - DA7DEFCB157978AC009D2085 /* avatar-female-silhouette-3@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-3@2x.png"; sourceTree = ""; }; - DA7DEFCC157978AC009D2085 /* avatar-female-silhouette-4.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-4.png"; sourceTree = ""; }; - DA7DEFCD157978AC009D2085 /* avatar-female-silhouette-4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-4@2x.png"; sourceTree = ""; }; - DA7DEFCE157978AC009D2085 /* avatar-female-silhouette-5.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-5.png"; sourceTree = ""; }; - DA7DEFCF157978AC009D2085 /* avatar-female-silhouette-5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-5@2x.png"; sourceTree = ""; }; - DA7DEFD0157978AC009D2085 /* avatar-female-silhouette-6.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-6.png"; sourceTree = ""; }; - DA7DEFD1157978AC009D2085 /* avatar-female-silhouette-6@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-6@2x.png"; sourceTree = ""; }; - DA7DEFD2157978AC009D2085 /* avatar-female-silhouette-7.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-7.png"; sourceTree = ""; }; - DA7DEFD3157978AC009D2085 /* avatar-female-silhouette-7@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-female-silhouette-7@2x.png"; sourceTree = ""; }; - DA7DEFD4157978AC009D2085 /* avatar-male-1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-1.png"; sourceTree = ""; }; - DA7DEFD5157978AC009D2085 /* avatar-male-1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-1@2x.png"; sourceTree = ""; }; - DA7DEFD6157978AC009D2085 /* avatar-male-2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-2.png"; sourceTree = ""; }; - DA7DEFD7157978AC009D2085 /* avatar-male-2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-2@2x.png"; sourceTree = ""; }; - DA7DEFD8157978AC009D2085 /* avatar-male-3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-3.png"; sourceTree = ""; }; - DA7DEFD9157978AC009D2085 /* avatar-male-3@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-3@2x.png"; sourceTree = ""; }; - DA7DEFDA157978AC009D2085 /* avatar-male-silhouette-1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-1.png"; sourceTree = ""; }; - DA7DEFDB157978AC009D2085 /* avatar-male-silhouette-1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-1@2x.png"; sourceTree = ""; }; - DA7DEFDC157978AC009D2085 /* avatar-male-silhouette-2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-2.png"; sourceTree = ""; }; - DA7DEFDD157978AC009D2085 /* avatar-male-silhouette-2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-2@2x.png"; sourceTree = ""; }; - DA7DEFDE157978AC009D2085 /* avatar-male-silhouette-3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-3.png"; sourceTree = ""; }; - DA7DEFDF157978AC009D2085 /* avatar-male-silhouette-3@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-3@2x.png"; sourceTree = ""; }; - DA7DEFE0157978AC009D2085 /* avatar-male-silhouette-4.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-4.png"; sourceTree = ""; }; - DA7DEFE1157978AC009D2085 /* avatar-male-silhouette-4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-4@2x.png"; sourceTree = ""; }; - DA7DEFE2157978AC009D2085 /* avatar-male-silhouette-5.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-5.png"; sourceTree = ""; }; - DA7DEFE3157978AC009D2085 /* avatar-male-silhouette-5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-5@2x.png"; sourceTree = ""; }; - DA7DEFE4157978AC009D2085 /* avatar-male-silhouette-6.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-6.png"; sourceTree = ""; }; - DA7DEFE5157978AC009D2085 /* avatar-male-silhouette-6@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-6@2x.png"; sourceTree = ""; }; - DA7DEFE6157978AC009D2085 /* avatar-male-silhouette-7.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-7.png"; sourceTree = ""; }; - DA7DEFE7157978AC009D2085 /* avatar-male-silhouette-7@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-male-silhouette-7@2x.png"; sourceTree = ""; }; DA902BD01576CA4A00C38161 /* keypad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = keypad.png; sourceTree = ""; }; 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 = ""; }; @@ -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; }; 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; }; + DAE4C943157E63BE00EFE047 /* avatar-0.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-0.png"; sourceTree = ""; }; + DAE4C944157E63BE00EFE047 /* avatar-0@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-0@2x.png"; sourceTree = ""; }; + DAE4C945157E63BE00EFE047 /* avatar-1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-1.png"; sourceTree = ""; }; + DAE4C946157E63BE00EFE047 /* avatar-1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-1@2x.png"; sourceTree = ""; }; + DAE4C947157E63BE00EFE047 /* avatar-2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-2.png"; sourceTree = ""; }; + DAE4C948157E63BE00EFE047 /* avatar-2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-2@2x.png"; sourceTree = ""; }; + DAE4C949157E63BE00EFE047 /* avatar-3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-3.png"; sourceTree = ""; }; + DAE4C94A157E63BE00EFE047 /* avatar-3@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-3@2x.png"; sourceTree = ""; }; + DAE4C94B157E63BE00EFE047 /* avatar-4.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-4.png"; sourceTree = ""; }; + DAE4C94C157E63BE00EFE047 /* avatar-4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-4@2x.png"; sourceTree = ""; }; + DAE4C94D157E63BE00EFE047 /* avatar-5.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-5.png"; sourceTree = ""; }; + DAE4C94E157E63BE00EFE047 /* avatar-5@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-5@2x.png"; sourceTree = ""; }; + DAE4C94F157E63BE00EFE047 /* avatar-6.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-6.png"; sourceTree = ""; }; + DAE4C950157E63BE00EFE047 /* avatar-6@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-6@2x.png"; sourceTree = ""; }; + DAE4C951157E63BE00EFE047 /* avatar-7.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-7.png"; sourceTree = ""; }; + DAE4C952157E63BE00EFE047 /* avatar-7@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-7@2x.png"; sourceTree = ""; }; + DAE4C953157E63BE00EFE047 /* avatar-8.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-8.png"; sourceTree = ""; }; + DAE4C954157E63BE00EFE047 /* avatar-8@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-8@2x.png"; sourceTree = ""; }; + DAE4C955157E63BE00EFE047 /* avatar-9.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-9.png"; sourceTree = ""; }; + DAE4C956157E63BE00EFE047 /* avatar-9@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-9@2x.png"; sourceTree = ""; }; + DAE4C957157E63BE00EFE047 /* avatar-10.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-10.png"; sourceTree = ""; }; + DAE4C958157E63BE00EFE047 /* avatar-10@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-10@2x.png"; sourceTree = ""; }; + DAE4C959157E63BE00EFE047 /* avatar-11.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-11.png"; sourceTree = ""; }; + DAE4C95A157E63BE00EFE047 /* avatar-11@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-11@2x.png"; sourceTree = ""; }; + DAE4C95B157E63BE00EFE047 /* avatar-12.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-12.png"; sourceTree = ""; }; + DAE4C95C157E63BE00EFE047 /* avatar-12@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-12@2x.png"; sourceTree = ""; }; + DAE4C95D157E63BE00EFE047 /* avatar-13.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-13.png"; sourceTree = ""; }; + DAE4C95E157E63BE00EFE047 /* avatar-13@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-13@2x.png"; sourceTree = ""; }; + DAE4C95F157E63BE00EFE047 /* avatar-14.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-14.png"; sourceTree = ""; }; + DAE4C960157E63BE00EFE047 /* avatar-14@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-14@2x.png"; sourceTree = ""; }; + DAE4C961157E63BE00EFE047 /* avatar-15.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-15.png"; sourceTree = ""; }; + DAE4C962157E63BE00EFE047 /* avatar-15@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-15@2x.png"; sourceTree = ""; }; + DAE4C963157E63BE00EFE047 /* avatar-16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-16.png"; sourceTree = ""; }; + DAE4C964157E63BE00EFE047 /* avatar-16@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-16@2x.png"; sourceTree = ""; }; + DAE4C965157E63BE00EFE047 /* avatar-17.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-17.png"; sourceTree = ""; }; + DAE4C966157E63BE00EFE047 /* avatar-17@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-17@2x.png"; sourceTree = ""; }; + DAE4C967157E63BE00EFE047 /* avatar-18.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-18.png"; sourceTree = ""; }; + DAE4C968157E63BE00EFE047 /* avatar-18@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-18@2x.png"; sourceTree = ""; }; 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 = ""; }; DAFE45D915039823003ABA7C /* NSObject_PearlExport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSObject_PearlExport.m; sourceTree = ""; }; @@ -2003,44 +2003,44 @@ DA902B931576C0FB00C38161 /* Avatars */ = { isa = PBXGroup; children = ( - DA7DEFC2157978AC009D2085 /* avatar-female-1.png */, - DA7DEFC3157978AC009D2085 /* avatar-female-1@2x.png */, - DA7DEFC4157978AC009D2085 /* avatar-female-2.png */, - DA7DEFC5157978AC009D2085 /* avatar-female-2@2x.png */, - DA7DEFC6157978AC009D2085 /* avatar-female-silhouette-1.png */, - DA7DEFC7157978AC009D2085 /* avatar-female-silhouette-1@2x.png */, - DA7DEFC8157978AC009D2085 /* avatar-female-silhouette-2.png */, - DA7DEFC9157978AC009D2085 /* avatar-female-silhouette-2@2x.png */, - DA7DEFCA157978AC009D2085 /* avatar-female-silhouette-3.png */, - DA7DEFCB157978AC009D2085 /* avatar-female-silhouette-3@2x.png */, - DA7DEFCC157978AC009D2085 /* avatar-female-silhouette-4.png */, - DA7DEFCD157978AC009D2085 /* avatar-female-silhouette-4@2x.png */, - DA7DEFCE157978AC009D2085 /* avatar-female-silhouette-5.png */, - DA7DEFCF157978AC009D2085 /* avatar-female-silhouette-5@2x.png */, - DA7DEFD0157978AC009D2085 /* avatar-female-silhouette-6.png */, - DA7DEFD1157978AC009D2085 /* avatar-female-silhouette-6@2x.png */, - DA7DEFD2157978AC009D2085 /* avatar-female-silhouette-7.png */, - DA7DEFD3157978AC009D2085 /* avatar-female-silhouette-7@2x.png */, - DA7DEFD4157978AC009D2085 /* avatar-male-1.png */, - DA7DEFD5157978AC009D2085 /* avatar-male-1@2x.png */, - DA7DEFD6157978AC009D2085 /* avatar-male-2.png */, - DA7DEFD7157978AC009D2085 /* avatar-male-2@2x.png */, - DA7DEFD8157978AC009D2085 /* avatar-male-3.png */, - DA7DEFD9157978AC009D2085 /* avatar-male-3@2x.png */, - DA7DEFDA157978AC009D2085 /* avatar-male-silhouette-1.png */, - DA7DEFDB157978AC009D2085 /* avatar-male-silhouette-1@2x.png */, - DA7DEFDC157978AC009D2085 /* avatar-male-silhouette-2.png */, - DA7DEFDD157978AC009D2085 /* avatar-male-silhouette-2@2x.png */, - DA7DEFDE157978AC009D2085 /* avatar-male-silhouette-3.png */, - DA7DEFDF157978AC009D2085 /* avatar-male-silhouette-3@2x.png */, - DA7DEFE0157978AC009D2085 /* avatar-male-silhouette-4.png */, - DA7DEFE1157978AC009D2085 /* avatar-male-silhouette-4@2x.png */, - DA7DEFE2157978AC009D2085 /* avatar-male-silhouette-5.png */, - DA7DEFE3157978AC009D2085 /* avatar-male-silhouette-5@2x.png */, - DA7DEFE4157978AC009D2085 /* avatar-male-silhouette-6.png */, - DA7DEFE5157978AC009D2085 /* avatar-male-silhouette-6@2x.png */, - DA7DEFE6157978AC009D2085 /* avatar-male-silhouette-7.png */, - DA7DEFE7157978AC009D2085 /* avatar-male-silhouette-7@2x.png */, + DAE4C943157E63BE00EFE047 /* avatar-0.png */, + DAE4C944157E63BE00EFE047 /* avatar-0@2x.png */, + DAE4C945157E63BE00EFE047 /* avatar-1.png */, + DAE4C946157E63BE00EFE047 /* avatar-1@2x.png */, + DAE4C947157E63BE00EFE047 /* avatar-2.png */, + DAE4C948157E63BE00EFE047 /* avatar-2@2x.png */, + DAE4C949157E63BE00EFE047 /* avatar-3.png */, + DAE4C94A157E63BE00EFE047 /* avatar-3@2x.png */, + DAE4C94B157E63BE00EFE047 /* avatar-4.png */, + DAE4C94C157E63BE00EFE047 /* avatar-4@2x.png */, + DAE4C94D157E63BE00EFE047 /* avatar-5.png */, + DAE4C94E157E63BE00EFE047 /* avatar-5@2x.png */, + DAE4C94F157E63BE00EFE047 /* avatar-6.png */, + DAE4C950157E63BE00EFE047 /* avatar-6@2x.png */, + DAE4C951157E63BE00EFE047 /* avatar-7.png */, + DAE4C952157E63BE00EFE047 /* avatar-7@2x.png */, + DAE4C953157E63BE00EFE047 /* avatar-8.png */, + DAE4C954157E63BE00EFE047 /* avatar-8@2x.png */, + DAE4C955157E63BE00EFE047 /* avatar-9.png */, + DAE4C956157E63BE00EFE047 /* avatar-9@2x.png */, + DAE4C957157E63BE00EFE047 /* avatar-10.png */, + DAE4C958157E63BE00EFE047 /* avatar-10@2x.png */, + DAE4C959157E63BE00EFE047 /* avatar-11.png */, + DAE4C95A157E63BE00EFE047 /* avatar-11@2x.png */, + DAE4C95B157E63BE00EFE047 /* avatar-12.png */, + DAE4C95C157E63BE00EFE047 /* avatar-12@2x.png */, + DAE4C95D157E63BE00EFE047 /* avatar-13.png */, + DAE4C95E157E63BE00EFE047 /* avatar-13@2x.png */, + DAE4C95F157E63BE00EFE047 /* avatar-14.png */, + DAE4C960157E63BE00EFE047 /* avatar-14@2x.png */, + DAE4C961157E63BE00EFE047 /* avatar-15.png */, + DAE4C962157E63BE00EFE047 /* avatar-15@2x.png */, + DAE4C963157E63BE00EFE047 /* avatar-16.png */, + DAE4C964157E63BE00EFE047 /* avatar-16@2x.png */, + DAE4C965157E63BE00EFE047 /* avatar-17.png */, + DAE4C966157E63BE00EFE047 /* avatar-17@2x.png */, + DAE4C967157E63BE00EFE047 /* avatar-18.png */, + DAE4C968157E63BE00EFE047 /* avatar-18@2x.png */, ); path = Avatars; sourceTree = ""; @@ -4059,44 +4059,44 @@ DACABB8D1572A4A5008BA211 /* tip_basic_black_top_right@2x.png in Resources */, DACABB901572B76A008BA211 /* tip_basic_black_top.png in Resources */, DACABB911572B76A008BA211 /* tip_basic_black_top@2x.png in Resources */, - DA7DEFE8157978AC009D2085 /* avatar-female-1.png in Resources */, - DA7DEFE9157978AC009D2085 /* avatar-female-1@2x.png in Resources */, - DA7DEFEA157978AC009D2085 /* avatar-female-2.png in Resources */, - DA7DEFEB157978AC009D2085 /* avatar-female-2@2x.png in Resources */, - DA7DEFEC157978AC009D2085 /* avatar-female-silhouette-1.png in Resources */, - DA7DEFED157978AC009D2085 /* avatar-female-silhouette-1@2x.png in Resources */, - DA7DEFEE157978AC009D2085 /* avatar-female-silhouette-2.png in Resources */, - DA7DEFEF157978AC009D2085 /* avatar-female-silhouette-2@2x.png in Resources */, - DA7DEFF0157978AC009D2085 /* avatar-female-silhouette-3.png in Resources */, - DA7DEFF1157978AC009D2085 /* avatar-female-silhouette-3@2x.png in Resources */, - DA7DEFF2157978AC009D2085 /* avatar-female-silhouette-4.png in Resources */, - DA7DEFF3157978AC009D2085 /* avatar-female-silhouette-4@2x.png in Resources */, - DA7DEFF4157978AC009D2085 /* avatar-female-silhouette-5.png in Resources */, - DA7DEFF5157978AC009D2085 /* avatar-female-silhouette-5@2x.png in Resources */, - DA7DEFF6157978AC009D2085 /* avatar-female-silhouette-6.png in Resources */, - DA7DEFF7157978AC009D2085 /* avatar-female-silhouette-6@2x.png in Resources */, - DA7DEFF8157978AC009D2085 /* avatar-female-silhouette-7.png in Resources */, - DA7DEFF9157978AC009D2085 /* avatar-female-silhouette-7@2x.png in Resources */, - DA7DEFFA157978AC009D2085 /* avatar-male-1.png in Resources */, - DA7DEFFB157978AC009D2085 /* avatar-male-1@2x.png in Resources */, - DA7DEFFC157978AC009D2085 /* avatar-male-2.png in Resources */, - DA7DEFFD157978AC009D2085 /* avatar-male-2@2x.png in Resources */, - DA7DEFFE157978AC009D2085 /* avatar-male-3.png in Resources */, - DA7DEFFF157978AC009D2085 /* avatar-male-3@2x.png in Resources */, - DA7DF000157978AC009D2085 /* avatar-male-silhouette-1.png in Resources */, - DA7DF001157978AC009D2085 /* avatar-male-silhouette-1@2x.png in Resources */, - DA7DF002157978AC009D2085 /* avatar-male-silhouette-2.png in Resources */, - DA7DF003157978AC009D2085 /* avatar-male-silhouette-2@2x.png in Resources */, - DA7DF004157978AC009D2085 /* avatar-male-silhouette-3.png in Resources */, - DA7DF005157978AC009D2085 /* avatar-male-silhouette-3@2x.png in Resources */, - DA7DF006157978AC009D2085 /* avatar-male-silhouette-4.png in Resources */, - DA7DF007157978AC009D2085 /* avatar-male-silhouette-4@2x.png in Resources */, - DA7DF008157978AC009D2085 /* avatar-male-silhouette-5.png in Resources */, - DA7DF009157978AC009D2085 /* avatar-male-silhouette-5@2x.png in Resources */, - DA7DF00A157978AC009D2085 /* avatar-male-silhouette-6.png in Resources */, - DA7DF00B157978AC009D2085 /* avatar-male-silhouette-6@2x.png in Resources */, - DA7DF00C157978AC009D2085 /* avatar-male-silhouette-7.png in Resources */, - DA7DF00D157978AC009D2085 /* avatar-male-silhouette-7@2x.png in Resources */, + DAE4C969157E63BE00EFE047 /* avatar-0.png in Resources */, + DAE4C96A157E63BE00EFE047 /* avatar-0@2x.png in Resources */, + DAE4C96B157E63BE00EFE047 /* avatar-1.png in Resources */, + DAE4C96C157E63BE00EFE047 /* avatar-1@2x.png in Resources */, + DAE4C96D157E63BE00EFE047 /* avatar-2.png in Resources */, + DAE4C96E157E63BE00EFE047 /* avatar-2@2x.png in Resources */, + DAE4C96F157E63BE00EFE047 /* avatar-3.png in Resources */, + DAE4C970157E63BE00EFE047 /* avatar-3@2x.png in Resources */, + DAE4C971157E63BE00EFE047 /* avatar-4.png in Resources */, + DAE4C972157E63BE00EFE047 /* avatar-4@2x.png in Resources */, + DAE4C973157E63BE00EFE047 /* avatar-5.png in Resources */, + DAE4C974157E63BE00EFE047 /* avatar-5@2x.png in Resources */, + DAE4C975157E63BE00EFE047 /* avatar-6.png in Resources */, + DAE4C976157E63BE00EFE047 /* avatar-6@2x.png in Resources */, + DAE4C977157E63BE00EFE047 /* avatar-7.png in Resources */, + DAE4C978157E63BE00EFE047 /* avatar-7@2x.png in Resources */, + DAE4C979157E63BE00EFE047 /* avatar-8.png in Resources */, + DAE4C97A157E63BE00EFE047 /* avatar-8@2x.png in Resources */, + DAE4C97B157E63BE00EFE047 /* avatar-9.png in Resources */, + DAE4C97C157E63BE00EFE047 /* avatar-9@2x.png in Resources */, + DAE4C97D157E63BE00EFE047 /* avatar-10.png in Resources */, + DAE4C97E157E63BE00EFE047 /* avatar-10@2x.png in Resources */, + DAE4C97F157E63BE00EFE047 /* avatar-11.png in Resources */, + DAE4C980157E63BE00EFE047 /* avatar-11@2x.png in Resources */, + DAE4C981157E63BE00EFE047 /* avatar-12.png in Resources */, + DAE4C982157E63BE00EFE047 /* avatar-12@2x.png in Resources */, + DAE4C983157E63BE00EFE047 /* avatar-13.png in Resources */, + DAE4C984157E63BE00EFE047 /* avatar-13@2x.png in Resources */, + DAE4C985157E63BE00EFE047 /* avatar-14.png in Resources */, + DAE4C986157E63BE00EFE047 /* avatar-14@2x.png in Resources */, + DAE4C987157E63BE00EFE047 /* avatar-15.png in Resources */, + DAE4C988157E63BE00EFE047 /* avatar-15@2x.png in Resources */, + DAE4C989157E63BE00EFE047 /* avatar-16.png in Resources */, + DAE4C98A157E63BE00EFE047 /* avatar-16@2x.png in Resources */, + DAE4C98B157E63BE00EFE047 /* avatar-17.png in Resources */, + DAE4C98C157E63BE00EFE047 /* avatar-17@2x.png in Resources */, + DAE4C98D157E63BE00EFE047 /* avatar-18.png in Resources */, + DAE4C98E157E63BE00EFE047 /* avatar-18@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/MasterPassword/MPAppDelegate_Key.m b/MasterPassword/MPAppDelegate_Key.m index c279aaa8..e9df9faa 100644 --- a/MasterPassword/MPAppDelegate_Key.m +++ b/MasterPassword/MPAppDelegate_Key.m @@ -7,6 +7,7 @@ // #import "MPAppDelegate_Key.h" +#import "MPAppDelegate_Store.h" @implementation MPAppDelegate_Shared (Key) @@ -63,10 +64,10 @@ static NSDictionary *keyQuery(MPUserEntity *user) { NSData *tryKey = keyForPassword(tryPassword); NSData *tryKeyID = keyIDForKey(tryKey); - inf(@"Key ID known? %@.", user.keyID? @"YES": @"NO"); - if (user.keyID) - // A key ID is known -> a password is set. - // Make sure the user's entered password matches it. + inf(@"Key ID was known? %@.", user.keyID? @"YES": @"NO"); + if (user.keyID) { + // A key ID is known -> a master password is set. + // Make sure the user's entered master password matches it. if (![user.keyID isEqual:tryKeyID]) { wrn(@"Key ID mismatch. Expected: %@, answer: %@.", [user.keyID encodeHex], [tryKeyID encodeHex]); @@ -75,7 +76,12 @@ static NSDictionary *keyQuery(MPUserEntity *user) { #endif 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 [TestFlight passCheckpoint:MPTestFlightCheckpointMPEntered]; #endif diff --git a/MasterPassword/MPEntities.h b/MasterPassword/MPEntities.h index e65ce7d2..224957a1 100644 --- a/MasterPassword/MPEntities.h +++ b/MasterPassword/MPEntities.h @@ -12,6 +12,8 @@ #import "MPElementGeneratedEntity.h" #import "MPUserEntity.h" +#define MPAvatarCount 19 + @interface MPElementEntity (MP) @property (assign) MPElementType type; diff --git a/MasterPassword/MPTypes.m b/MasterPassword/MPTypes.m index 84310fd8..a211aedc 100644 --- a/MasterPassword/MPTypes.m +++ b/MasterPassword/MPTypes.m @@ -12,7 +12,7 @@ #define MP_salt nil -#define MP_N 16384 +#define MP_N 131072 #define MP_r 8 #define MP_p 1 #define MP_dkLen 64 diff --git a/MasterPassword/Mac/MPPasswordWindowController.m b/MasterPassword/Mac/MPPasswordWindowController.m index 3b4a2422..91bd698c 100644 --- a/MasterPassword/Mac/MPPasswordWindowController.m +++ b/MasterPassword/Mac/MPPasswordWindowController.m @@ -114,7 +114,7 @@ return nil; 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 == %@", query, query, [MPAppDelegate get].activeUser]; diff --git a/MasterPassword/iOS/MPAppDelegate.h b/MasterPassword/iOS/MPAppDelegate.h index b933ec9a..48e421bf 100644 --- a/MasterPassword/iOS/MPAppDelegate.h +++ b/MasterPassword/iOS/MPAppDelegate.h @@ -18,5 +18,6 @@ - (void)loadKey:(BOOL)animated; - (void)export; +- (void)changeMP; @end diff --git a/MasterPassword/iOS/MPAppDelegate.m b/MasterPassword/iOS/MPAppDelegate.m index 1caa5774..cccd5261 100644 --- a/MasterPassword/iOS/MPAppDelegate.m +++ b/MasterPassword/iOS/MPAppDelegate.m @@ -117,6 +117,29 @@ [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 - (void)didUpdateConfigForKey:(SEL)configKey fromValue:(id)value { diff --git a/MasterPassword/iOS/MPMainViewController.m b/MasterPassword/iOS/MPMainViewController.m index 3ac63619..51bab77a 100644 --- a/MasterPassword/iOS/MPMainViewController.m +++ b/MasterPassword/iOS/MPMainViewController.m @@ -404,23 +404,19 @@ [self performSegueWithIdentifier:@"UserProfile" sender:self]; break; } - case 4: { - [[MPAppDelegate get] export]; - break; - } #ifdef ADHOC - case 5: { + case 4: { [TestFlight openFeedbackView]; break; } - case 6: + case 5: #else - case 5: { + case 4: { ATConnect *connection = [ATConnect sharedConnection]; [connection presentFeedbackControllerFromViewController:self]; break; } - case 6: + case 5: #endif { [[MPAppDelegate get] signOut:self]; diff --git a/MasterPassword/iOS/MPPreferencesViewController.h b/MasterPassword/iOS/MPPreferencesViewController.h index 397def33..0e9897d7 100644 --- a/MasterPassword/iOS/MPPreferencesViewController.h +++ b/MasterPassword/iOS/MPPreferencesViewController.h @@ -11,6 +11,12 @@ @interface MPPreferencesViewController : UITableViewController -@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 diff --git a/MasterPassword/iOS/MPPreferencesViewController.m b/MasterPassword/iOS/MPPreferencesViewController.m index 69807559..4c89c728 100644 --- a/MasterPassword/iOS/MPPreferencesViewController.m +++ b/MasterPassword/iOS/MPPreferencesViewController.m @@ -6,6 +6,7 @@ // Copyright (c) 2012 Lyndir. All rights reserved. // +#import #import "MPPreferencesViewController.h" #import "MPAppDelegate.h" @@ -14,31 +15,60 @@ @end @implementation MPPreferencesViewController -@synthesize avatarScrollView; +@synthesize avatarsView; +@synthesize avatarTemplate; +@synthesize savePasswordSwitch; +@synthesize exportCell; +@synthesize changeMPCell; + - (void)viewDidLoad { - __block NSInteger avatarIndex = 0; - [self.avatarScrollView enumerateSubviews:^(UIView *subview, BOOL *stop, BOOL *recurse) { - UIButton *avatar = (UIButton *)subview; - avatar.toggleSelectionWhenTouchedInside = YES; - avatar.tag = avatarIndex++; - - [avatar onSelect:^(BOOL selected) { - [MPAppDelegate get].activeUser.avatar = (unsigned)avatar.tag; - [self.avatarScrollView enumerateSubviews:^(UIView *subview_, BOOL *stop_, BOOL *recurse_) { - UIButton *avatar_ = (UIButton *)subview_; - avatar_.selected = ([MPAppDelegate get].activeUser.avatar == (unsigned)avatar_.tag); - } recurse:NO]; + self.avatarTemplate.hidden = YES; + + for (int a = 0; a < MPAvatarCount; ++a) { + UIButton *avatar = [self.avatarTemplate clone]; + avatar.togglesSelectionInSuperview = YES; + avatar.tag = a; + avatar.hidden = 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]; - } 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]; } - (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]; } @@ -48,7 +78,29 @@ 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 { @@ -56,8 +108,11 @@ [self.navigationController popViewControllerAnimated:YES]; } -- (void)viewDidUnload { - [self setAvatarScrollView:nil]; - [super viewDidUnload]; +#pragma mark - IBActions + +- (IBAction)didToggleSwitch:(UISwitch *)sender { + + [MPAppDelegate get].activeUser.saveKey = sender.on; } + @end diff --git a/MasterPassword/iOS/MPSearchDelegate.m b/MasterPassword/iOS/MPSearchDelegate.m index 4fc9e754..7b71e7c0 100644 --- a/MasterPassword/iOS/MPSearchDelegate.m +++ b/MasterPassword/iOS/MPSearchDelegate.m @@ -35,7 +35,7 @@ self.query = @""; 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{ NSFetchedResultsController *controller = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[MPAppDelegate managedObjectContext] diff --git a/MasterPassword/iOS/MPUnlockViewController.h b/MasterPassword/iOS/MPUnlockViewController.h index aa2ba09e..b7c89187 100644 --- a/MasterPassword/iOS/MPUnlockViewController.h +++ b/MasterPassword/iOS/MPUnlockViewController.h @@ -13,12 +13,14 @@ @property (weak, nonatomic) IBOutlet UIImageView *spinner; @property (weak, nonatomic) IBOutlet UITextField *passwordField; @property (weak, nonatomic) IBOutlet UIView *passwordView; -@property (weak, nonatomic) IBOutlet UIScrollView *usersView; -@property (weak, nonatomic) IBOutlet UILabel *usernameLabel; -@property (weak, nonatomic) IBOutlet UILabel *oldUsernameLabel; -@property (weak, nonatomic) IBOutlet UIButton *userButtonTemplate; +@property (weak, nonatomic) IBOutlet UIScrollView *avatarsView; +@property (weak, nonatomic) IBOutlet UILabel *nameLabel; +@property (weak, nonatomic) IBOutlet UILabel *oldNameLabel; +@property (weak, nonatomic) IBOutlet UIButton *avatarTemplate; @property (weak, nonatomic) IBOutlet UILabel *deleteTip; +@property(nonatomic, strong) UIColor *avatarShadowColor; + - (IBAction)deleteTargetedUser:(UILongPressGestureRecognizer *)sender; @end diff --git a/MasterPassword/iOS/MPUnlockViewController.m b/MasterPassword/iOS/MPUnlockViewController.m index af4ded39..ded748d8 100644 --- a/MasterPassword/iOS/MPUnlockViewController.m +++ b/MasterPassword/iOS/MPUnlockViewController.m @@ -15,8 +15,8 @@ @interface MPUnlockViewController () -@property (strong, nonatomic) MPUserEntity *selectedUser; -@property (strong, nonatomic) NSMutableDictionary *avatarToUser; +@property(strong, nonatomic) MPUserEntity *selectedUser; +@property(strong, nonatomic) NSMutableDictionary *avatarToUser; @end @@ -26,10 +26,12 @@ @synthesize spinner; @synthesize passwordField; @synthesize passwordView; -@synthesize usersView; -@synthesize usernameLabel, oldUsernameLabel; -@synthesize userButtonTemplate; +@synthesize avatarsView; +@synthesize nameLabel, oldNameLabel; +@synthesize avatarTemplate; @synthesize deleteTip; +@synthesize avatarShadowColor = _avatarShadowColor; + // [UIView animateWithDuration:1.0f delay:0 options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse animations:^{ // self.lock.alpha = 0.5f; @@ -44,12 +46,12 @@ self.avatarToUser = [NSMutableDictionary dictionaryWithCapacity:3]; - self.spinner.alpha = 0; self.passwordField.text = nil; - self.usersView.decelerationRate = UIScrollViewDecelerationRateFast; - self.usersView.clipsToBounds = NO; - self.usernameLabel.layer.cornerRadius = 5; - self.userButtonTemplate.hidden = YES; + self.avatarsView.decelerationRate = UIScrollViewDecelerationRateFast; + self.avatarsView.clipsToBounds = NO; + self.nameLabel.layer.cornerRadius = 5; + self.avatarTemplate.hidden = YES; + self.spinner.alpha = 0; [self updateLayoutAnimated:NO allowScroll:YES completion:nil]; @@ -61,15 +63,15 @@ [self setSpinner:nil]; [self setPasswordField:nil]; [self setPasswordView:nil]; - [self setUsersView:nil]; - [self setUsernameLabel:nil]; - [self setUserButtonTemplate:nil]; + [self setAvatarsView:nil]; + [self setNameLabel:nil]; + [self setAvatarTemplate:nil]; [self setDeleteTip:nil]; [super viewDidUnload]; } - (void)viewWillAppear:(BOOL)animated { - + self.selectedUser = nil; [self updateUsers]; @@ -78,42 +80,40 @@ - (void)viewDidAppear:(BOOL)animated { - [[UIApplication sharedApplication] setStatusBarHidden:YES - withAnimation:animated? UIStatusBarAnimationSlide: UIStatusBarAnimationNone]; + [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:animated ? UIStatusBarAnimationSlide : UIStatusBarAnimationNone]; [super viewDidAppear:animated]; } - (void)viewWillDisappear:(BOOL)animated { - [[UIApplication sharedApplication] setStatusBarHidden:NO - withAnimation:animated? UIStatusBarAnimationSlide: UIStatusBarAnimationNone]; + [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:animated ? UIStatusBarAnimationSlide : UIStatusBarAnimationNone]; [super viewWillDisappear:animated]; } - (void)updateUsers { - + NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([MPUserEntity class])]; fetchRequest.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"lastUsed" ascending:NO]]; NSArray *users = [[MPAppDelegate managedObjectContext] executeFetchRequest:fetchRequest error:nil]; - + // Clean up avatars. - for (UIView *view in [self.usersView subviews]) - if (view != self.userButtonTemplate) + for (UIView *view in [self.avatarsView subviews]) + if (view != self.avatarTemplate) [view removeFromSuperview]; [self.avatarToUser removeAllObjects]; - + // Create avatars. for (MPUserEntity *user in users) - [self setupAvatar:[self.userButtonTemplate clone] forUser:user]; - [self setupAvatar:[self.userButtonTemplate clone] forUser:nil]; - + [self setupAvatar:[self.avatarTemplate clone] forUser:user]; + [self setupAvatar:[self.avatarTemplate clone] forUser:nil]; + // 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.deleteTip.alpha = 0; if ([users count] > 1) [UIView animateWithDuration:0.5f animations:^{ @@ -122,89 +122,92 @@ } - (UIButton *)setupAvatar:(UIButton *)avatar forUser:(MPUserEntity *)user { - + [avatar onHighlightOrSelect:^(BOOL highlighted, BOOL selected) { if (highlighted || selected) - avatar.backgroundColor = self.userButtonTemplate.backgroundColor; + avatar.backgroundColor = self.avatarTemplate.backgroundColor; else avatar.backgroundColor = [UIColor clearColor]; } options:0]; [avatar onSelect:^(BOOL selected) { - self.selectedUser = selected? user: nil; + self.selectedUser = selected ? user : nil; if (user) [self didToggleUserSelection]; else if (selected) [self didSelectNewUserAvatar:avatar]; } options:0]; - avatar.toggleSelectionWhenTouchedInside = YES; + avatar.togglesSelectionInSuperview = YES; avatar.center = CGPointMake(avatar.center.x + [self.avatarToUser count] * 160, avatar.center.y); avatar.hidden = NO; - avatar.layer.cornerRadius = 5; + avatar.layer.cornerRadius = avatar.bounds.size.height / 2; avatar.layer.shadowColor = [UIColor blackColor].CGColor; avatar.layer.shadowOpacity = 1; avatar.layer.shadowRadius = 20; avatar.layer.masksToBounds = NO; 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) [self.avatarToUser setObject:user forKey:[NSValue valueWithNonretainedObject:avatar]]; - + if (self.selectedUser && user == self.selectedUser) avatar.selected = YES; - + return avatar; } - (void)didToggleUserSelection { - + if (!self.selectedUser) [self.passwordField resignFirstResponder]; - + [self updateLayoutAnimated:YES allowScroll:YES completion:^(BOOL finished) { - if (finished) - if (self.selectedUser) - [self.passwordField becomeFirstResponder]; + if (finished) if (self.selectedUser) + [self.passwordField becomeFirstResponder]; }]; } - (void)didSelectNewUserAvatar:(UIButton *)newUserAvatar { - - [PearlAlert showAlertWithTitle:@"New User" - message:@"Enter your name:" viewStyle:UIAlertViewStylePlainTextInput - initAlert:^(UIAlertView *alert, UITextField *firstField) { - firstField.autocapitalizationType = UITextAutocapitalizationTypeWords; - firstField.autocorrectionType = UITextAutocorrectionTypeYes; - firstField.spellCheckingType = UITextSpellCheckingTypeYes; - firstField.keyboardType = UIKeyboardTypeAlphabet; - } - tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) { - newUserAvatar.selected = NO; - - if (buttonIndex == [alert cancelButtonIndex]) - return; - - MPUserEntity *newUser = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([MPUserEntity class]) - inManagedObjectContext:[MPAppDelegate managedObjectContext]]; - newUser.name = [alert textFieldAtIndex:0].text; - self.selectedUser = newUser; - - [self updateUsers]; - } - cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:[PearlStrings get].commonButtonSave, nil]; + + [PearlAlert showAlertWithTitle:@"New User" + message:@"Enter your name:" viewStyle:UIAlertViewStylePlainTextInput + initAlert:^(UIAlertView *alert, UITextField *firstField) { + firstField.autocapitalizationType = UITextAutocapitalizationTypeWords; + firstField.autocorrectionType = UITextAutocorrectionTypeYes; + firstField.spellCheckingType = UITextSpellCheckingTypeYes; + firstField.keyboardType = UIKeyboardTypeAlphabet; + } + tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) { + newUserAvatar.selected = NO; + + if (buttonIndex == [alert cancelButtonIndex]) + return; + + MPUserEntity *newUser = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([MPUserEntity class]) + inManagedObjectContext:[MPAppDelegate managedObjectContext]]; + newUser.name = [alert textFieldAtIndex:0].text; + self.selectedUser = newUser; + + [self updateUsers]; + } + cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:[PearlStrings get].commonButtonSave, nil]; } - (void)updateLayoutAnimated:(BOOL)animated allowScroll:(BOOL)allowScroll completion:(void (^)(BOOL finished))completion { - + if (animated) { - self.oldUsernameLabel.text = self.usernameLabel.text; - self.oldUsernameLabel.alpha = 1; - self.usernameLabel.alpha = 0; - + self.oldNameLabel.text = self.nameLabel.text; + self.oldNameLabel.alpha = 1; + self.nameLabel.alpha = 0; + [UIView animateWithDuration:0.5f animations:^{ [self updateLayoutAnimated:NO allowScroll:allowScroll completion:nil]; - - self.oldUsernameLabel.alpha = 0; - self.usernameLabel.alpha = 1; + + self.oldNameLabel.alpha = 0; + self.nameLabel.alpha = 1; } completion:^(BOOL finished) { if (completion) completion(finished); @@ -214,20 +217,22 @@ if (self.selectedUser && !self.passwordView.alpha) { self.passwordView.alpha = 1; - self.usersView.center = CGPointMake(160, 100); - self.usersView.scrollEnabled = NO; - self.usernameLabel.center = CGPointMake(160, 84); - self.usernameLabel.backgroundColor = [UIColor blackColor]; - self.oldUsernameLabel.center = self.usernameLabel.center; - } else if (self.passwordView.alpha == 1) { + self.avatarsView.center = CGPointMake(160, 100); + self.avatarsView.scrollEnabled = NO; + self.nameLabel.center = CGPointMake(160, 84); + self.nameLabel.backgroundColor = [UIColor blackColor]; + self.oldNameLabel.center = self.nameLabel.center; + self.avatarShadowColor = [UIColor whiteColor]; + } else if (!self.selectedUser && self.passwordView.alpha == 1) { self.passwordView.alpha = 0; - self.usersView.center = CGPointMake(160, 240); - self.usersView.scrollEnabled = YES; - self.usernameLabel.center = CGPointMake(160, 296); - self.usernameLabel.backgroundColor = [UIColor clearColor]; - self.oldUsernameLabel.center = self.usernameLabel.center; + self.avatarsView.center = CGPointMake(160, 240); + self.avatarsView.scrollEnabled = YES; + self.nameLabel.center = CGPointMake(160, 296); + self.nameLabel.backgroundColor = [UIColor clearColor]; + self.oldNameLabel.center = self.nameLabel.center; + self.avatarShadowColor = [UIColor lightGrayColor]; } - + MPUserEntity *targetedUser = self.selectedUser; UIButton *selectedAvatar = [self avatarForUser:self.selectedUser]; UIButton *targetedAvatar = selectedAvatar; @@ -235,178 +240,205 @@ targetedAvatar = [self findTargetedAvatar]; 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; - + subview.userInteractionEnabled = isTargeted; - 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"]; - 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"]; - } + subview.alpha = isTargeted ? 1 : self.selectedUser ? 0.1 : 0.4; + + [self updateAvatarShadowColor:subview isTargeted:isTargeted]; } 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) { - CGPoint targetContentOffset = CGPointMake(targetedAvatar.center.x - self.usersView.bounds.size.width / 2, self.usersView.contentOffset.y); - if (!CGPointEqualToPoint(self.usersView.contentOffset, targetContentOffset)) - [self.usersView setContentOffset:targetContentOffset animated:animated]; + CGPoint targetContentOffset = CGPointMake(targetedAvatar.center.x - self.avatarsView.bounds.size.width / 2, self.avatarsView.contentOffset.y); + if (!CGPointEqualToPoint(self.avatarsView.contentOffset, targetContentOffset)) + [self.avatarsView setContentOffset:targetContentOffset animated:animated]; } - - self.usernameLabel.text = targetedUser? targetedUser.name: @"New User"; - self.usernameLabel.bounds = CGRectSetHeight(self.usernameLabel.bounds, - [self.usernameLabel.text sizeWithFont:self.usernameLabel.font - constrainedToSize:CGSizeMake(self.usernameLabel.bounds.size.width - 10, 100) - lineBreakMode:self.usernameLabel.lineBreakMode].height); - self.oldUsernameLabel.bounds = self.usernameLabel.bounds; + + self.nameLabel.text = targetedUser ? targetedUser.name : @"New User"; + self.nameLabel.bounds = CGRectSetHeight(self.nameLabel.bounds, + [self.nameLabel.text sizeWithFont:self.nameLabel.font + constrainedToSize:CGSizeMake(self.nameLabel.bounds.size.width - 10, 100) + lineBreakMode:self.nameLabel.lineBreakMode].height); + self.oldNameLabel.bounds = self.nameLabel.bounds; if (completion) completion(YES); } -- (UIButton *)findTargetedAvatar { +- (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]; + }); + }); +} - CGFloat xOfMiddle = self.usersView.contentOffset.x + self.usersView.bounds.size.width / 2; - return (UIButton *)[PearlUIUtils viewClosestTo:CGPointMake(xOfMiddle, self.usersView.contentOffset.y) ofArray:self.usersView.subviews]; +- (UIButton *)findTargetedAvatar { + + CGFloat xOfMiddle = self.avatarsView.contentOffset.x + self.avatarsView.bounds.size.width / 2; + return (UIButton *) [PearlUIUtils viewClosestTo:CGPointMake(xOfMiddle, self.avatarsView.contentOffset.y) ofArray:self.avatarsView.subviews]; } - (UIButton *)avatarForUser:(MPUserEntity *)user { - + __block UIButton *avatar = nil; if (user) [self.avatarToUser enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { if (obj == user) avatar = [key nonretainedObjectValue]; }]; - + return avatar; } - (MPUserEntity *)userForAvatar:(UIButton *)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 - (BOOL)textFieldShouldReturn:(UITextField *)textField { - if (![textField.text length]) - return NO; - [textField resignFirstResponder]; - CABasicAnimation *rotate = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; - rotate.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; - rotate.fromValue = [NSNumber numberWithFloat:0]; - rotate.toValue = [NSNumber numberWithDouble:2 * M_PI]; - rotate.repeatCount = MAXFLOAT; - rotate.duration = 3.0; + [self setSpinnerActive:YES]; + [self changeAvatarShadowColorTo:[UIColor colorWithName:@"lightskyblue"]]; - [self.spinner.layer removeAllAnimations]; - [self.spinner.layer addAnimation:rotate forKey:@"transform"]; + if (self.selectedUser.keyID) + [self tryMasterPassword]; - [UIView animateWithDuration:0.3f animations:^{ - 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" - message:@"Please confirm the spelling of this new master password." - viewStyle:UIAlertViewStyleSecureTextInput - initAlert:nil - tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) { - if (buttonIndex == [alert cancelButtonIndex]) { - [[MPAppDelegate get] unsetKey]; - return; - } - - if (![[alert textFieldAtIndex:0].text isEqualToString:textField.text]) { - [PearlAlert showAlertWithTitle:@"Incorrect Master Password" - message: - @"The password you entered doesn't match with the master password you tried to use. " - @"You've probably mistyped one of them.\n\n" - @"Give it another try." - viewStyle:UIAlertViewStyleDefault initAlert:nil tappedButtonBlock:nil - cancelTitle:[PearlStrings get].commonButtonOkay otherTitles:nil]; - return; - } - - self.selectedUser.keyID = [MPAppDelegate get].activeUser.keyID; - [[MPAppDelegate get] saveContext]; - - [self dismissModalViewControllerAnimated:YES]; + else + [PearlAlert showAlertWithTitle:@"New Master Password" + message:@"Please confirm the spelling of this new master password." + viewStyle:UIAlertViewStyleSecureTextInput + initAlert:nil tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) { + [self setSpinnerActive:NO]; + + if (buttonIndex == [alert cancelButtonIndex]) + return; + + if (![[alert textFieldAtIndex:0].text isEqualToString:textField.text]) { + [PearlAlert showAlertWithTitle:@"Incorrect Master Password" + message: + @"The password you entered doesn't match with the master password you tried to use. " + @"You've probably mistyped one of them.\n\n" + @"Give it another try." + viewStyle:UIAlertViewStyleDefault initAlert:nil tappedButtonBlock:nil cancelTitle:[PearlStrings get].commonButtonOkay otherTitles:nil]; + return; } - cancelTitle:[PearlStrings get].commonButtonCancel - 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]; - }]; - }); - }); - }); + + [self tryMasterPassword]; + } + cancelTitle:[PearlStrings get].commonButtonCancel + otherTitles:[PearlStrings get].commonButtonContinue, nil]; + return YES; } @@ -416,54 +448,30 @@ - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset { 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); - + [self updateLayoutAnimated:NO allowScroll:NO completion:nil]; -// [self scrollToAvatar:middleAvatar animated:YES]; + // [self scrollToAvatar:middleAvatar animated:YES]; } - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { [self updateLayoutAnimated:YES allowScroll:YES completion:nil]; -// [self scrollToAvatar:middleAvatar animated:YES]; + // [self scrollToAvatar:middleAvatar animated:YES]; } - (void)scrollViewDidScroll:(UIScrollView *)scrollView { -// CGFloat xOfMiddle = scrollView.contentOffset.x + scrollView.bounds.size.width / 2; -// UIButton *middleAvatar = (UIButton *)[PearlUIUtils viewClosestTo:CGPointMake(xOfMiddle, scrollView.contentOffset.y) ofArray:scrollView.subviews]; -// + // CGFloat xOfMiddle = scrollView.contentOffset.x + scrollView.bounds.size.width / 2; + // UIButton *middleAvatar = (UIButton *)[PearlUIUtils viewClosestTo:CGPointMake(xOfMiddle, scrollView.contentOffset.y) ofArray:scrollView.subviews]; + // [self updateLayoutAnimated:NO allowScroll:NO completion:nil]; -// [self scrollToAvatar:middleAvatar animated:NO]; + // [self scrollToAvatar:middleAvatar animated:NO]; } #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 { if (sender.state != UIGestureRecognizerStateBegan) @@ -479,15 +487,14 @@ [PearlAlert showAlertWithTitle:@"Delete User" message: PearlString(@"Do you want to delete all record of the following user?\n\n%@", targetedUser.name) viewStyle:UIAlertViewStyleDefault - initAlert:nil - tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) { - if (buttonIndex == [alert cancelButtonIndex]) - return; - - [[MPAppDelegate get].managedObjectContext deleteObject:targetedUser]; - [[MPAppDelegate get] saveContext]; - - [self updateUsers]; - } cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:@"Delete", nil]; + initAlert:nil tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) { + if (buttonIndex == [alert cancelButtonIndex]) + return; + + [[MPAppDelegate get].managedObjectContext deleteObject:targetedUser]; + [[MPAppDelegate get] saveContext]; + + [self updateUsers]; + } cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:@"Delete", nil]; } @end diff --git a/MasterPassword/iOS/MainStoryboard_iPhone.storyboard b/MasterPassword/iOS/MainStoryboard_iPhone.storyboard index 2465ee27..3b9acd45 100644 --- a/MasterPassword/iOS/MainStoryboard_iPhone.storyboard +++ b/MasterPassword/iOS/MainStoryboard_iPhone.storyboard @@ -1,6 +1,7 @@ + @@ -782,7 +783,7 @@ L4m3P4sSw0rD - + @@ -792,9 +793,9 @@ L4m3P4sSw0rD - - - - - - - + @@ -1006,11 +953,11 @@ L4m3P4sSw0rD - - + + - + - - + + + + + + + + + + + + + + - - + + - @@ -1071,11 +1033,11 @@ L4m3P4sSw0rD - - + + - + - - + + + + + + + + + + + + + + - - + @@ -1171,7 +1145,11 @@ L4m3P4sSw0rD - + + + + + @@ -1180,11 +1158,7 @@ L4m3P4sSw0rD - - - - - + @@ -1260,7 +1234,12 @@ L4m3P4sSw0rD - + + + + + + @@ -1281,14 +1260,14 @@ L4m3P4sSw0rD + + - + + - - - diff --git a/Resources/Avatars/avatar-male-1.png b/Resources/Avatars/avatar-0.png similarity index 100% rename from Resources/Avatars/avatar-male-1.png rename to Resources/Avatars/avatar-0.png diff --git a/Resources/Avatars/avatar-male-1@2x.png b/Resources/Avatars/avatar-0@2x.png similarity index 100% rename from Resources/Avatars/avatar-male-1@2x.png rename to Resources/Avatars/avatar-0@2x.png diff --git a/Resources/Avatars/avatar-male-2.png b/Resources/Avatars/avatar-1.png similarity index 100% rename from Resources/Avatars/avatar-male-2.png rename to Resources/Avatars/avatar-1.png diff --git a/Resources/Avatars/avatar-female-1.png b/Resources/Avatars/avatar-10.png similarity index 100% rename from Resources/Avatars/avatar-female-1.png rename to Resources/Avatars/avatar-10.png diff --git a/Resources/Avatars/avatar-female-1@2x.png b/Resources/Avatars/avatar-10@2x.png similarity index 100% rename from Resources/Avatars/avatar-female-1@2x.png rename to Resources/Avatars/avatar-10@2x.png diff --git a/Resources/Avatars/avatar-female-2.png b/Resources/Avatars/avatar-11.png similarity index 100% rename from Resources/Avatars/avatar-female-2.png rename to Resources/Avatars/avatar-11.png diff --git a/Resources/Avatars/avatar-female-2@2x.png b/Resources/Avatars/avatar-11@2x.png similarity index 100% rename from Resources/Avatars/avatar-female-2@2x.png rename to Resources/Avatars/avatar-11@2x.png diff --git a/Resources/Avatars/avatar-female-silhouette-1.png b/Resources/Avatars/avatar-12.png similarity index 100% rename from Resources/Avatars/avatar-female-silhouette-1.png rename to Resources/Avatars/avatar-12.png diff --git a/Resources/Avatars/avatar-female-silhouette-1@2x.png b/Resources/Avatars/avatar-12@2x.png similarity index 100% rename from Resources/Avatars/avatar-female-silhouette-1@2x.png rename to Resources/Avatars/avatar-12@2x.png diff --git a/Resources/Avatars/avatar-female-silhouette-2.png b/Resources/Avatars/avatar-13.png similarity index 100% rename from Resources/Avatars/avatar-female-silhouette-2.png rename to Resources/Avatars/avatar-13.png diff --git a/Resources/Avatars/avatar-female-silhouette-2@2x.png b/Resources/Avatars/avatar-13@2x.png similarity index 100% rename from Resources/Avatars/avatar-female-silhouette-2@2x.png rename to Resources/Avatars/avatar-13@2x.png diff --git a/Resources/Avatars/avatar-female-silhouette-3.png b/Resources/Avatars/avatar-14.png similarity index 100% rename from Resources/Avatars/avatar-female-silhouette-3.png rename to Resources/Avatars/avatar-14.png diff --git a/Resources/Avatars/avatar-female-silhouette-3@2x.png b/Resources/Avatars/avatar-14@2x.png similarity index 100% rename from Resources/Avatars/avatar-female-silhouette-3@2x.png rename to Resources/Avatars/avatar-14@2x.png diff --git a/Resources/Avatars/avatar-female-silhouette-4.png b/Resources/Avatars/avatar-15.png similarity index 100% rename from Resources/Avatars/avatar-female-silhouette-4.png rename to Resources/Avatars/avatar-15.png diff --git a/Resources/Avatars/avatar-female-silhouette-4@2x.png b/Resources/Avatars/avatar-15@2x.png similarity index 100% rename from Resources/Avatars/avatar-female-silhouette-4@2x.png rename to Resources/Avatars/avatar-15@2x.png diff --git a/Resources/Avatars/avatar-female-silhouette-5.png b/Resources/Avatars/avatar-16.png similarity index 100% rename from Resources/Avatars/avatar-female-silhouette-5.png rename to Resources/Avatars/avatar-16.png diff --git a/Resources/Avatars/avatar-female-silhouette-5@2x.png b/Resources/Avatars/avatar-16@2x.png similarity index 100% rename from Resources/Avatars/avatar-female-silhouette-5@2x.png rename to Resources/Avatars/avatar-16@2x.png diff --git a/Resources/Avatars/avatar-female-silhouette-6.png b/Resources/Avatars/avatar-17.png similarity index 100% rename from Resources/Avatars/avatar-female-silhouette-6.png rename to Resources/Avatars/avatar-17.png diff --git a/Resources/Avatars/avatar-female-silhouette-6@2x.png b/Resources/Avatars/avatar-17@2x.png similarity index 100% rename from Resources/Avatars/avatar-female-silhouette-6@2x.png rename to Resources/Avatars/avatar-17@2x.png diff --git a/Resources/Avatars/avatar-female-silhouette-7.png b/Resources/Avatars/avatar-18.png similarity index 100% rename from Resources/Avatars/avatar-female-silhouette-7.png rename to Resources/Avatars/avatar-18.png diff --git a/Resources/Avatars/avatar-female-silhouette-7@2x.png b/Resources/Avatars/avatar-18@2x.png similarity index 100% rename from Resources/Avatars/avatar-female-silhouette-7@2x.png rename to Resources/Avatars/avatar-18@2x.png diff --git a/Resources/Avatars/avatar-male-2@2x.png b/Resources/Avatars/avatar-1@2x.png similarity index 100% rename from Resources/Avatars/avatar-male-2@2x.png rename to Resources/Avatars/avatar-1@2x.png diff --git a/Resources/Avatars/avatar-male-3.png b/Resources/Avatars/avatar-2.png similarity index 100% rename from Resources/Avatars/avatar-male-3.png rename to Resources/Avatars/avatar-2.png diff --git a/Resources/Avatars/avatar-male-3@2x.png b/Resources/Avatars/avatar-2@2x.png similarity index 100% rename from Resources/Avatars/avatar-male-3@2x.png rename to Resources/Avatars/avatar-2@2x.png diff --git a/Resources/Avatars/avatar-male-silhouette-1.png b/Resources/Avatars/avatar-3.png similarity index 100% rename from Resources/Avatars/avatar-male-silhouette-1.png rename to Resources/Avatars/avatar-3.png diff --git a/Resources/Avatars/avatar-male-silhouette-1@2x.png b/Resources/Avatars/avatar-3@2x.png similarity index 100% rename from Resources/Avatars/avatar-male-silhouette-1@2x.png rename to Resources/Avatars/avatar-3@2x.png diff --git a/Resources/Avatars/avatar-male-silhouette-2.png b/Resources/Avatars/avatar-4.png similarity index 100% rename from Resources/Avatars/avatar-male-silhouette-2.png rename to Resources/Avatars/avatar-4.png diff --git a/Resources/Avatars/avatar-male-silhouette-2@2x.png b/Resources/Avatars/avatar-4@2x.png similarity index 100% rename from Resources/Avatars/avatar-male-silhouette-2@2x.png rename to Resources/Avatars/avatar-4@2x.png diff --git a/Resources/Avatars/avatar-male-silhouette-3.png b/Resources/Avatars/avatar-5.png similarity index 100% rename from Resources/Avatars/avatar-male-silhouette-3.png rename to Resources/Avatars/avatar-5.png diff --git a/Resources/Avatars/avatar-male-silhouette-3@2x.png b/Resources/Avatars/avatar-5@2x.png similarity index 100% rename from Resources/Avatars/avatar-male-silhouette-3@2x.png rename to Resources/Avatars/avatar-5@2x.png diff --git a/Resources/Avatars/avatar-male-silhouette-4.png b/Resources/Avatars/avatar-6.png similarity index 100% rename from Resources/Avatars/avatar-male-silhouette-4.png rename to Resources/Avatars/avatar-6.png diff --git a/Resources/Avatars/avatar-male-silhouette-4@2x.png b/Resources/Avatars/avatar-6@2x.png similarity index 100% rename from Resources/Avatars/avatar-male-silhouette-4@2x.png rename to Resources/Avatars/avatar-6@2x.png diff --git a/Resources/Avatars/avatar-male-silhouette-5.png b/Resources/Avatars/avatar-7.png similarity index 100% rename from Resources/Avatars/avatar-male-silhouette-5.png rename to Resources/Avatars/avatar-7.png diff --git a/Resources/Avatars/avatar-male-silhouette-5@2x.png b/Resources/Avatars/avatar-7@2x.png similarity index 100% rename from Resources/Avatars/avatar-male-silhouette-5@2x.png rename to Resources/Avatars/avatar-7@2x.png diff --git a/Resources/Avatars/avatar-male-silhouette-6.png b/Resources/Avatars/avatar-8.png similarity index 100% rename from Resources/Avatars/avatar-male-silhouette-6.png rename to Resources/Avatars/avatar-8.png diff --git a/Resources/Avatars/avatar-male-silhouette-6@2x.png b/Resources/Avatars/avatar-8@2x.png similarity index 100% rename from Resources/Avatars/avatar-male-silhouette-6@2x.png rename to Resources/Avatars/avatar-8@2x.png diff --git a/Resources/Avatars/avatar-male-silhouette-7.png b/Resources/Avatars/avatar-9.png similarity index 100% rename from Resources/Avatars/avatar-male-silhouette-7.png rename to Resources/Avatars/avatar-9.png diff --git a/Resources/Avatars/avatar-male-silhouette-7@2x.png b/Resources/Avatars/avatar-9@2x.png similarity index 100% rename from Resources/Avatars/avatar-male-silhouette-7@2x.png rename to Resources/Avatars/avatar-9@2x.png