diff --git a/MasterPassword.xcworkspace/xcshareddata/MasterPassword.xccheckout b/MasterPassword.xcworkspace/xcshareddata/MasterPassword.xccheckout
index f775dc76..80126f53 100644
--- a/MasterPassword.xcworkspace/xcshareddata/MasterPassword.xccheckout
+++ b/MasterPassword.xcworkspace/xcshareddata/MasterPassword.xccheckout
@@ -50,7 +50,7 @@
3E67FB08419C920516AAC3B00DAAF23073B8CF77
../External/RHStatusItemView
3ED8592497DB6A564366943C9AAD5A46341B5076
- ../External/AttributedMarkdown/
+ ../External/AttributedMarkdown
4DDCFFD91B41F00326AD14553BD66CFD366ABD91
../External/Pearl
8A15A8EA0B3D0B497C4883425BC74DF995224BB3
diff --git a/MasterPassword/ObjC/MPAppDelegate_InApp.m b/MasterPassword/ObjC/MPAppDelegate_InApp.m
index bcb1c180..bfbce092 100644
--- a/MasterPassword/ObjC/MPAppDelegate_InApp.m
+++ b/MasterPassword/ObjC/MPAppDelegate_InApp.m
@@ -139,9 +139,9 @@ PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObserve
case SKPaymentTransactionStatePurchased: {
inf( @"purchased: %@", transaction.payment.productIdentifier );
if ([transaction.payment.productIdentifier isEqualToString:MPProductFuel]) {
- float currentFuel = [[MPiOSConfig get].developmentFuel floatValue];
+ float currentFuel = [[MPiOSConfig get].developmentFuelRemaining floatValue];
float purchasedFuel = transaction.payment.quantity / MP_FUEL_HOURLY_RATE;
- [MPiOSConfig get].developmentFuel = @(currentFuel + purchasedFuel);
+ [MPiOSConfig get].developmentFuelRemaining = @(currentFuel + purchasedFuel);
if (![MPiOSConfig get].developmentFuelChecked || !currentFuel)
[MPiOSConfig get].developmentFuelChecked = [NSDate date];
}
diff --git a/MasterPassword/ObjC/iOS/MPStoreViewController.h b/MasterPassword/ObjC/iOS/MPStoreViewController.h
index 7f53d101..2b25d1d4 100644
--- a/MasterPassword/ObjC/iOS/MPStoreViewController.h
+++ b/MasterPassword/ObjC/iOS/MPStoreViewController.h
@@ -20,6 +20,7 @@
@property(weak, nonatomic) IBOutlet UITableViewCell *loadingCell;
@property(weak, nonatomic) IBOutlet NSLayoutConstraint *fuelMeterConstraint;
@property(weak, nonatomic) IBOutlet UIButton *fuelSpeedButton;
+@property(weak, nonatomic) IBOutlet UILabel *fuelStatusLabel;
+ (NSString *)latestStoreFeatures;
diff --git a/MasterPassword/ObjC/iOS/MPStoreViewController.m b/MasterPassword/ObjC/iOS/MPStoreViewController.m
index ea87385c..78b71a67 100644
--- a/MasterPassword/ObjC/iOS/MPStoreViewController.m
+++ b/MasterPassword/ObjC/iOS/MPStoreViewController.m
@@ -252,18 +252,24 @@ PearlEnum( MPDevelopmentFuelConsumption,
- (void)updateFuel {
CGFloat weeklyFuelConsumption = [self weeklyFuelConsumption]; /* consume x fuel / week */
- CGFloat fuel = [[MPiOSConfig get].developmentFuel floatValue]; /* x fuel left */
+ CGFloat fuelRemaining = [[MPiOSConfig get].developmentFuelRemaining floatValue]; /* x fuel left */
+ CGFloat fuelInvested = [[MPiOSConfig get].developmentFuelInvested floatValue]; /* x fuel left */
NSDate *now = [NSDate date];
NSTimeInterval fuelSecondsElapsed = -[[MPiOSConfig get].developmentFuelChecked timeIntervalSinceDate:now];
if (fuelSecondsElapsed > 3600 || ![MPiOSConfig get].developmentFuelChecked) {
NSTimeInterval weeksElapsed = fuelSecondsElapsed / (3600 * 24 * 7 /* 1 week */); /* x weeks elapsed */
- fuel -= weeklyFuelConsumption * weeksElapsed;
+ NSTimeInterval fuelConsumed = weeklyFuelConsumption * weeksElapsed;
+ fuelRemaining -= fuelConsumed;
+ fuelInvested += fuelConsumed;
[MPiOSConfig get].developmentFuelChecked = now;
- [MPiOSConfig get].developmentFuel = @(fuel);
+ [MPiOSConfig get].developmentFuelRemaining = @(fuelRemaining);
+ [MPiOSConfig get].developmentFuelInvested = @(fuelInvested);
}
- CGFloat fuelRatio = weeklyFuelConsumption == 0? 0: fuel / weeklyFuelConsumption; /* x weeks worth of fuel left */
+ CGFloat fuelRatio = weeklyFuelConsumption == 0? 0: fuelRemaining / weeklyFuelConsumption; /* x weeks worth of fuel left */
[self.fuelMeterConstraint updateConstant:MIN( 0.5f, fuelRatio - 0.5f ) * 160]; /* -80pt = 0 weeks left, 80pt = >=1 week left */
+ self.fuelStatusLabel.text = strf( @"fuel left: %0.1f work hours\ninvested: %0.1f work hours", fuelRemaining, fuelInvested );
+ self.fuelStatusLabel.hidden = (fuelRemaining + fuelInvested) == 0;
}
- (CGFloat)weeklyFuelConsumption {
@@ -302,7 +308,7 @@ PearlEnum( MPDevelopmentFuelConsumption,
- (NSInteger)quantityForProductIdentifier:(NSString *)productIdentifier {
if ([productIdentifier isEqualToString:MPProductFuel])
- return (NSInteger)(MP_FUEL_HOURLY_RATE * [self weeklyFuelConsumption]);
+ return (NSInteger)(MP_FUEL_HOURLY_RATE * [self weeklyFuelConsumption] + .5f);
return 1;
}
diff --git a/MasterPassword/ObjC/iOS/MPiOSConfig.h b/MasterPassword/ObjC/iOS/MPiOSConfig.h
index 795ca9d9..4061ce56 100644
--- a/MasterPassword/ObjC/iOS/MPiOSConfig.h
+++ b/MasterPassword/ObjC/iOS/MPiOSConfig.h
@@ -18,7 +18,8 @@
@property(nonatomic, retain) NSNumber *loginNameTipShown;
@property(nonatomic, retain) NSNumber *traceMode;
@property(nonatomic, retain) NSNumber *dictationSearch;
-@property(nonatomic, retain) NSNumber *developmentFuel;
+@property(nonatomic, retain) NSNumber *developmentFuelRemaining;
+@property(nonatomic, retain) NSNumber *developmentFuelInvested;
@property(nonatomic, retain) NSNumber *developmentFuelConsumption;
@property(nonatomic, retain) NSDate *developmentFuelChecked;
diff --git a/MasterPassword/ObjC/iOS/MPiOSConfig.m b/MasterPassword/ObjC/iOS/MPiOSConfig.m
index 917578ce..b6806958 100644
--- a/MasterPassword/ObjC/iOS/MPiOSConfig.m
+++ b/MasterPassword/ObjC/iOS/MPiOSConfig.m
@@ -9,7 +9,7 @@
@implementation MPiOSConfig
@dynamic helpHidden, siteInfoHidden, showSetup, actionsTipShown, typeTipShown, loginNameTipShown, traceMode, dictationSearch;
-@dynamic developmentFuel, developmentFuelConsumption, developmentFuelChecked;
+@dynamic developmentFuelRemaining, developmentFuelInvested, developmentFuelConsumption, developmentFuelChecked;
- (id)init {
diff --git a/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj b/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj
index 196fa088..8e3f43e3 100644
--- a/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj
+++ b/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj
@@ -2961,6 +2961,7 @@
isa = PBXNativeTarget;
buildConfigurationList = DA5BFA6D147E415C00F98B1E /* Build configuration list for PBXNativeTarget "MasterPassword" */;
buildPhases = (
+ DA8D88E019DA412A00B189D0 /* Run Script: genassets */,
DA5BFA40147E415C00F98B1E /* Sources */,
DA5BFA41147E415C00F98B1E /* Frameworks */,
DA5BFA42147E415C00F98B1E /* Resources */,
@@ -3399,6 +3400,21 @@
shellPath = "/bin/bash -e";
shellScript = "PATH+=:/usr/libexec\n\naddPlistWithKey() {\n local key=$1 type=$2 value=$3 plist=${4:-\"$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH\"}\n \n PlistBuddy -c \"Delete :'$key'\" \"$plist\" 2>/dev/null || true\n PlistBuddy -c \"Add :'$key' '$type' '$value'\" \"$plist\"\n}\nsetPlistWithKey() {\n local key=$1 value=$2 plist=${3:-\"$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH\"}\n \n PlistBuddy -c \"Set :'$key' '$value'\" \"$plist\"\n}\ngetPlistWithKey() {\n local key=$1 plist=${2:-\"$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH\"}\n \n PlistBuddy -c \"Print :'$key'\" \"$plist\"\n}\nsetSettingWithTitle() {\n local i title=$1 value=$2 plist=${3:-\"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Settings.bundle/Root.plist\"}\n \n for (( i=0; 1; ++i )); do\n PlistBuddy -c \"Print :PreferenceSpecifiers:$i\" \"$plist\" &>/dev/null || break\n echo \"Checking preference specifier $i\"\n \n [[ $(PlistBuddy -c \"Print :PreferenceSpecifiers:$i:Title\" \"$plist\" 2>/dev/null) = $title ]] || continue\n \n echo \"Correct title, setting value.\"\n PlistBuddy -c \"Set :PreferenceSpecifiers:$i:DefaultValue $value\" \"$plist\"\n break\n done\n}\n\ndescription=$(git describe --always --dirty --long)\nversion=${description%-g*}\nIFS=- read major minor <<< \"$version\"\nprintf -v version '%s.%02d' \"$major\" \"$minor\"\nprintf -v commit '%09d' \"$((16#${description##*-g}))\"\n\naddPlistWithKey GITDescription string \"$description\"\nsetPlistWithKey CFBundleVersion \"${version//.}$commit\" # No separator between version and commit because I had already submitted a CFBundleVersion with a really high major. Cry.\nsetPlistWithKey CFBundleShortVersionString \"$version\"\n\nsetSettingWithTitle \"Build\" \"$commit\"\nsetSettingWithTitle \"Version\" \"$version\"\nsetSettingWithTitle \"Copyright\" \"$(getPlistWithKey NSHumanReadableCopyright)\"\n\nif [[ $DEPLOYMENT_LOCATION = YES ]]; then\n # This build is a release. Do some release checks.\n passed=1\n [[ $description != *-dirty ]] || \\\n { passed=0; echo >&2 \"ERROR: Cannot release a dirty version, first commit any changes.\"; }\n [[ $(PlistBuddy -c \"Print :'API Key'\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Crashlytics.plist\") ]] || \\\n { passed=0; echo >&2 \"ERROR: Cannot release: Crashlytics API key is missing.\"; }\n (( passed )) || \\\n { echo >&2 \"Failed to pass release checks. Fix the above errors and re-try. Aborting.\"; exit 1; }\nfi";
};
+ DA8D88E019DA412A00B189D0 /* Run Script: genassets */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Run Script: genassets";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = "/bin/sh -e";
+ shellScript = "exec env PATH=\"/usr/local/bin:$PATH\" ../../../Scripts/genassets";
+ showEnvVarsInLog = 0;
+ };
DAD3125D155288AA00A3F9ED /* Run Script: Crashlytics */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
diff --git a/MasterPassword/ObjC/iOS/Storyboard.storyboard b/MasterPassword/ObjC/iOS/Storyboard.storyboard
index 2b342bfa..b9d6d823 100644
--- a/MasterPassword/ObjC/iOS/Storyboard.storyboard
+++ b/MasterPassword/ObjC/iOS/Storyboard.storyboard
@@ -97,6 +97,7 @@
Exo2.0-Thin
Exo2.0-Thin
Exo2.0-Thin
+ Exo2.0-Thin
SourceCodePro-Black
@@ -2824,7 +2825,7 @@ See