diff options
author | Danilo Ercoli <ercoli@gmail.com> | 2016-02-03 13:48:06 +0100 |
---|---|---|
committer | Danilo Ercoli <ercoli@gmail.com> | 2016-02-03 13:48:06 +0100 |
commit | 03eae1f43f9c014b515b66b3311bd76b9fb8c16d (patch) | |
tree | d19c8ad0a907791196f2bc409bfe4cfe2aac0956 | |
parent | 8fced36944ae89c9bdc1a9531d2f4b6dbde0aee9 (diff) | |
download | gradle-perf-android-medium-03eae1f43f9c014b515b66b3311bd76b9fb8c16d.tar.gz |
Download available plans for a site.
Refactoring!!
6 files changed, 220 insertions, 28 deletions
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/main/MySiteFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/main/MySiteFragment.java index d9f4661be..6c9520188 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/main/MySiteFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/main/MySiteFragment.java @@ -80,6 +80,9 @@ public class MySiteFragment extends Fragment mBlogLocalId = BlogUtils.getBlogLocalId(blog); refreshBlogDetails(blog); + + // Prefetch available plans for the site + PlansUtils.downloadAvailablePlansForSite(false, blog, null); } @Override @@ -359,27 +362,6 @@ public class MySiteFragment extends Fragment mBlogTitleTextView.setText(blogTitle); mBlogSubtitleTextView.setText(homeURL); - - //Reload plans details for the current blog. - if (PlansUtils.isPlanFeatureAvailableForBlog(blog)) { - WordPress.getRestClientUtils().get("sites/" + blog.getDotComBlogId() + "/plans", new RestRequest.Listener() { - @Override - public void onResponse(JSONObject response) { - if (response != null) { - AppLog.d(AppLog.T.UTILS, response.toString()); - } else { - - } - } - }, new RestRequest.ErrorListener() { - @Override - public void onErrorResponse(VolleyError volleyError) { - // JSONObject errorObject = VolleyUtils.volleyErrorToJSON(volleyError); - AppLog.e(AppLog.T.UTILS, "Error", volleyError); - } - }); - } - // Hide the Plan item if the Plans feature is not available. mPlansContainer.setVisibility(PlansUtils.isPlanFeatureAvailableForBlog(blog) ? View.VISIBLE : View.GONE); } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/plans/PlansUtils.java b/WordPress/src/main/java/org/wordpress/android/ui/plans/PlansUtils.java index 3ba322072..afb70f0be 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/plans/PlansUtils.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/plans/PlansUtils.java @@ -1,5 +1,6 @@ package org.wordpress.android.ui.plans; +import android.support.annotation.Nullable; import android.text.TextUtils; import com.android.volley.VolleyError; @@ -12,6 +13,7 @@ import org.wordpress.android.WordPress; import org.wordpress.android.models.Blog; import org.wordpress.android.ui.plans.models.Feature; import org.wordpress.android.ui.plans.models.Plan; +import org.wordpress.android.ui.plans.models.SitePlan; import org.wordpress.android.ui.prefs.AppPrefs; import org.wordpress.android.util.AppLog; import org.wordpress.android.util.RateLimitedTask; @@ -25,7 +27,71 @@ import java.util.Map; public class PlansUtils { private static final int SECONDS_BETWEEN_PLANS_UPDATE = 20 * 60; // 20 minutes + private static HashMap<Integer, List<SitePlan>> availablePlansForSites = new HashMap<>(); + public interface AvailablePlansListener { + void onResponse(List<SitePlan> plans); + void onError(Exception volleyError); + } + + public static boolean downloadAvailablePlansForSite(boolean force, final Blog blog, final AvailablePlansListener listener) { + if (!PlansUtils.isPlanFeatureAvailableForBlog(blog)) { + return false; + } + + if (!force && PlansUtils.getAvailablelPlansForSite(blog) != null) { + // Plans for the site already available. + return false; + } + + Map<String, String> params = getDefaultRestCallParameters(); + WordPress.getRestClientUtils().get("sites/" + blog.getDotComBlogId() + "/plans", params, null, new RestRequest.Listener() { + @Override + public void onResponse(JSONObject response) { + if (response != null) { + AppLog.d(AppLog.T.PLANS, response.toString()); + List<SitePlan> plans = new ArrayList<>(); + try { + JSONArray planIDs = response.names(); + if (planIDs != null) { + for (int i=0; i < planIDs.length(); i ++) { + String currentKey = planIDs.getString(i); + JSONObject currentPlanJSON = response.getJSONObject(currentKey); + SitePlan currentPlan = new SitePlan(Long.valueOf(currentKey), currentPlanJSON, blog); + plans.add(currentPlan); + } + } + availablePlansForSites.put(blog.getLocalTableBlogId(), plans); + if (listener!= null) { + listener.onResponse(plans); + } + } catch (JSONException e) { + AppLog.e(AppLog.T.PLANS, "Can't parse the plans list returned from the server", e); + if (listener!= null) { + listener.onError(e); + } + } + } + } + }, new RestRequest.ErrorListener() { + @Override + public void onErrorResponse(VolleyError volleyError) { + AppLog.e(AppLog.T.UTILS, "Error", volleyError); + if (listener!= null) { + listener.onError(volleyError); + } + } + }); + + return true; + } + + @Nullable + public static List<SitePlan> getAvailablelPlansForSite(Blog blog) { + return availablePlansForSites.get(blog.getLocalTableBlogId()); + } + + @Nullable public static Plan getGlobalPlan(long planId) { List<Plan> plans = getGlobalPlans(); if (plans == null || plans.size() == 0) { @@ -41,6 +107,7 @@ public class PlansUtils { return null; } + @Nullable public static List<Plan> getGlobalPlans() { String plansString = AppPrefs.getGlobalPlans(); if (TextUtils.isEmpty(plansString)) { @@ -64,6 +131,7 @@ public class PlansUtils { return plans; } + @Nullable public static List<Long> getGlobalPlansIDS() { List<Plan> plans = getGlobalPlans(); if (plans == null) { @@ -78,7 +146,8 @@ public class PlansUtils { return plansIDS; } - public static List<Feature> getGlobalPlansFeatures() { + @Nullable + public static List<Feature> getFeatures() { String featuresString = AppPrefs.getGlobalPlansFeatures(); if (TextUtils.isEmpty(featuresString)) { return null; @@ -108,7 +177,7 @@ public class PlansUtils { return features; } - public static void updateGlobalPlans(final RestRequest.Listener listener, final RestRequest.ErrorListener errorListener) { + public static void downloadGlobalPlans(final RestRequest.Listener listener, final RestRequest.ErrorListener errorListener) { Map<String, String> params = getDefaultRestCallParameters(); WordPress.getRestClientUtils().get("plans/", params, null, new RestRequest.Listener() { @Override @@ -119,7 +188,7 @@ public class PlansUtils { AppPrefs.setGlobalPlans(response.toString()); // Load details of features from the server. - updateGlobalPlansFeatures(null, null); + downloadFeatures(null, null); } if (listener != null) { @@ -137,7 +206,7 @@ public class PlansUtils { }); } - public static void updateGlobalPlansFeatures(final RestRequest.Listener listener, final RestRequest.ErrorListener errorListener) { + public static void downloadFeatures(final RestRequest.Listener listener, final RestRequest.ErrorListener errorListener) { Map<String, String> params = getDefaultRestCallParameters(); WordPress.getRestClientUtils().get("plans/features/", params, null, new RestRequest.Listener() { @Override @@ -168,7 +237,7 @@ public class PlansUtils { */ public static RateLimitedTask sAvailablePlans = new RateLimitedTask(SECONDS_BETWEEN_PLANS_UPDATE) { protected boolean run() { - updateGlobalPlans(null, null); + downloadGlobalPlans(null, null); return true; } }; diff --git a/WordPress/src/main/java/org/wordpress/android/ui/plans/models/Feature.java b/WordPress/src/main/java/org/wordpress/android/ui/plans/models/Feature.java index 5eb5fc14f..ec01308d0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/plans/models/Feature.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/plans/models/Feature.java @@ -8,6 +8,22 @@ import java.util.Hashtable; import java.util.List; public class Feature { + /* + + We "need" the IDs of plans to parse Feature correctly, since the Feature contains the IDs of plans + where it's available as first level key. The value is the label of the feature in that plan. + See the example below: + + { + "product_slug": "space", + "title": "Space", + "description": "Increase your available storage space and add the ability to upload audio files.", + "1": "3GB", + "1003": "13GB", + "1008": "Unlimited" + }, + */ + private String mProductSlug; private String mTitle; private String mDescription; diff --git a/WordPress/src/main/java/org/wordpress/android/ui/plans/models/Plan.java b/WordPress/src/main/java/org/wordpress/android/ui/plans/models/Plan.java index 59ec83ecd..dae3ea338 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/plans/models/Plan.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/plans/models/Plan.java @@ -4,6 +4,7 @@ package org.wordpress.android.ui.plans.models; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import org.wordpress.android.util.JSONUtils; import java.util.ArrayList; import java.util.Hashtable; @@ -65,8 +66,7 @@ public class Plan { mCost = planJSONObject.getLong("cost"); mBillPeriod = planJSONObject.getInt("bill_period"); mProductType = planJSONObject.getString("product_type"); - String rawAvailable = planJSONObject.optString("available"); - isAvailable = "yes".equals(rawAvailable) || "1".equals(rawAvailable) || "true".equals(rawAvailable); + isAvailable = JSONUtils.isStringTrue(planJSONObject, "available"); mBillPeriodLabel = planJSONObject.getString("bill_period_label"); mPrice = planJSONObject.getString("price"); mFormattedPrice = planJSONObject.getString("formatted_price"); diff --git a/WordPress/src/main/java/org/wordpress/android/ui/plans/models/SitePlan.java b/WordPress/src/main/java/org/wordpress/android/ui/plans/models/SitePlan.java new file mode 100644 index 000000000..b28dd2548 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/plans/models/SitePlan.java @@ -0,0 +1,120 @@ +package org.wordpress.android.ui.plans.models; + +import android.support.annotation.Nullable; + +import org.json.JSONException; +import org.json.JSONObject; +import org.wordpress.android.models.Blog; +import org.wordpress.android.util.JSONUtils; + +/** + * This class represent an available Plan for a site. + */ +public class SitePlan { + /* + "1003": { + "raw_price": 99, + "formatted_price": "$99", + "raw_discount": 0, + "formatted_discount": "$0", + "product_slug": "value_bundle", + "product_name": "WordPress.com Premium", + "can_start_trial": true + "expiry": "2100-08-01", + "free_trial": false, + "user_facing_expiry": "2100-07-29", + "subscribed_date": "2014-11-19 13:54:00" + }, + */ + + protected long mBlogLocalTableID; + protected long mProductID; + protected int mRawPrice; + protected String mFormattedPrice; + protected int mRawDiscount; + protected String mFormattedDiscount; + protected String mProductName; + protected String mProductSlug; + protected boolean mIsCurrentPlan; + protected boolean mCanStartTrial; + protected String mExpiry; + protected boolean mFreeTrial; + protected String mUserFacingExpiry; + protected String mSubscribedDate; + + public SitePlan(long productID, JSONObject planJSONObject, Blog blog) throws JSONException { + mBlogLocalTableID = blog.getLocalTableBlogId(); + mProductID = productID; + mProductName = planJSONObject.getString("product_name"); + mProductSlug = planJSONObject.getString("product_slug"); + mRawPrice = planJSONObject.getInt("raw_price"); + mRawDiscount = planJSONObject.getInt("raw_discount"); + mFormattedPrice = planJSONObject.getString("formatted_price"); + mFormattedDiscount = planJSONObject.getString("formatted_discount"); + mCanStartTrial = JSONUtils.getBool(planJSONObject, "can_start_trial"); + mIsCurrentPlan = JSONUtils.getBool(planJSONObject, "current_plan"); + mExpiry = planJSONObject.optString("expiry"); + mUserFacingExpiry = planJSONObject.optString("user_facing_expiry"); + mSubscribedDate = planJSONObject.optString("subscribed_date"); + mFreeTrial = JSONUtils.getBool(planJSONObject, "free_trial"); + } + + public long getProductID() { + return mProductID; + } + + public int getRawPrice() { + return mRawPrice; + } + + public String getFormattedPrice() { + return mFormattedPrice; + } + + public int getRawDiscount() { + return mRawDiscount; + } + + public String getFormattedDiscount() { + return mFormattedDiscount; + } + + public String getProductName() { + return mProductName; + } + + public String getProductSlug() { + return mProductSlug; + } + + public boolean isCurrentPlan() { + return mIsCurrentPlan; + } + + public boolean canStartTrial() { + return mCanStartTrial; + } + + public long getBlogLocalTableID() { + return mBlogLocalTableID; + } + + @Nullable + public String getSubscribedDate() { + return mSubscribedDate; + } + + @Nullable + public String getUserFacingExpiry() { + return mUserFacingExpiry; + } + + public boolean isFreeTrial() { + return mFreeTrial; + } + + @Nullable + public String getExpiry() { + return mExpiry; + } +}
\ No newline at end of file diff --git a/libs/utils/WordPressUtils/src/main/java/org/wordpress/android/util/JSONUtils.java b/libs/utils/WordPressUtils/src/main/java/org/wordpress/android/util/JSONUtils.java index 4166a1f68..251d32a38 100644 --- a/libs/utils/WordPressUtils/src/main/java/org/wordpress/android/util/JSONUtils.java +++ b/libs/utils/WordPressUtils/src/main/java/org/wordpress/android/util/JSONUtils.java @@ -213,6 +213,11 @@ public class JSONUtils { return true; } + public static boolean isStringTrue(JSONObject json, String name) { + String rawAvailable = json.optString(name).toLowerCase(); + return "yes".equals(rawAvailable) || "1".equals(rawAvailable) || "true".equals(rawAvailable); + } + /* * returns the JSONObject child of the passed parent that matches the passed query * this is basically an "optJSONObject" that supports nested queries, for example: |