aboutsummaryrefslogtreecommitdiff
path: root/WordPress/src/main/java/org/wordpress
diff options
context:
space:
mode:
authorMaxime Biais <maxime.biais@gmail.com>2015-03-05 10:30:08 +0100
committerMaxime Biais <maxime.biais@gmail.com>2015-03-05 10:30:08 +0100
commite062faec6a63223494bf4ef21a1bf438f1036a7f (patch)
tree54177c80c1a1aa2380f95f19836d4f0c6d6c2897 /WordPress/src/main/java/org/wordpress
parent38c196a37ff236713d75060d9d0d5185302a4447 (diff)
parent2c6eb865f4aeefabdd0a7f66a058fe3f6e400829 (diff)
downloadgradle-perf-android-medium-e062faec6a63223494bf4ef21a1bf438f1036a7f.tar.gz
Merge branch 'develop' into update/color-values
Diffstat (limited to 'WordPress/src/main/java/org/wordpress')
-rw-r--r--WordPress/src/main/java/org/wordpress/android/datasets/ReaderPostTable.java14
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/WPDrawerActivity.java9
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderCommentListActivity.java9
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java16
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderPostAdapter.java2
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/stats/StatsActivity.java11
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/stats/StatsAuthorsFragment.java24
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/stats/StatsBarGraph.java22
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/stats/StatsConstants.java2
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/stats/StatsSinglePostDetailsActivity.java5
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/stats/StatsUtils.java16
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/stats/StatsViewAllActivity.java17
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/stats/StatsViewHolder.java1
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/stats/StatsVisitorsAndViewsFragment.java138
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/stats/StatsWPLinkMovementMethod.java1
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/stats/service/StatsService.java5
-rw-r--r--WordPress/src/main/java/org/wordpress/android/widgets/TypefaceCache.java55
17 files changed, 244 insertions, 103 deletions
diff --git a/WordPress/src/main/java/org/wordpress/android/datasets/ReaderPostTable.java b/WordPress/src/main/java/org/wordpress/android/datasets/ReaderPostTable.java
index 0a1231c81..e9ea6801d 100644
--- a/WordPress/src/main/java/org/wordpress/android/datasets/ReaderPostTable.java
+++ b/WordPress/src/main/java/org/wordpress/android/datasets/ReaderPostTable.java
@@ -383,6 +383,20 @@ public class ReaderPostTable {
}
/*
+ * returns the id of the newest post with the passed tag
+ */
+ public static long getNewestPostIdWithTag(final ReaderTag tag) {
+ if (tag == null) {
+ return 0;
+ }
+ String sql = "SELECT tbl_posts.post_id FROM tbl_posts, tbl_post_tags"
+ + " WHERE tbl_posts.post_id = tbl_post_tags.post_id AND tbl_posts.blog_id = tbl_post_tags.blog_id"
+ + " AND tbl_post_tags.tag_name=? AND tbl_post_tags.tag_type=?"
+ + " ORDER BY published DESC LIMIT 1";
+ String[] args = {tag.getTagName(), Integer.toString(tag.tagType.toInt())};
+ return SqlUtils.longForQuery(ReaderDatabase.getReadableDb(), sql, args);
+ }
+ /*
* returns the iso8601 published date of the oldest post with the passed tag
*/
public static String getOldestPubDateWithTag(final ReaderTag tag) {
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/WPDrawerActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/WPDrawerActivity.java
index aae0b5572..9e0223864 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/WPDrawerActivity.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/WPDrawerActivity.java
@@ -57,6 +57,7 @@ import org.wordpress.android.util.WPActivityUtils;
import org.xmlrpc.android.ApiHelper;
import org.xmlrpc.android.ApiHelper.ErrorType;
+import java.util.IllegalFormatCodePointException;
import java.util.List;
import java.util.Map;
@@ -291,7 +292,13 @@ public abstract class WPDrawerActivity extends ActionBarActivity {
FragmentManager fm = getFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
- fm.popBackStack();
+ try {
+ fm.popBackStack();
+ } catch (IllegalStateException e) {
+ // onClick event can be fired after the onSaveInstanceState call,
+ // and make the app crash. Catching this exception avoid the crash. If this existed,
+ // we would use popBackStackAllowingStateLoss.
+ }
} else if (isStaticMenuDrawer()) {
finish();
} else {
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderCommentListActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderCommentListActivity.java
index 78cc71e6d..3c963979d 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderCommentListActivity.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderCommentListActivity.java
@@ -71,6 +71,7 @@ public class ReaderCommentListActivity extends ActionBarActivity {
private boolean mIsUpdatingComments;
private boolean mHasUpdatedComments;
+ private boolean mIsSubmittingComment;
private long mReplyToCommentId;
private int mRestorePosition;
@@ -358,7 +359,9 @@ public class ReaderCommentListActivity extends ActionBarActivity {
private void checkEmptyView() {
TextView txtEmpty = (TextView) findViewById(R.id.text_empty);
- boolean isEmpty = hasCommentAdapter() && getCommentAdapter().isEmpty();
+ boolean isEmpty = hasCommentAdapter()
+ && getCommentAdapter().isEmpty()
+ && !mIsSubmittingComment;
if (isEmpty && !NetworkUtils.isNetworkAvailable(this)) {
txtEmpty.setText(R.string.no_network_message);
txtEmpty.setVisibility(View.VISIBLE);
@@ -406,6 +409,7 @@ public class ReaderCommentListActivity extends ActionBarActivity {
mImgSubmitComment.setEnabled(false);
mEditComment.setEnabled(false);
+ mIsSubmittingComment = true;
// generate a "fake" comment id to assign to the new comment so we can add it to the db
// and reflect it in the adapter before the API call returns
@@ -417,6 +421,7 @@ public class ReaderCommentListActivity extends ActionBarActivity {
if (isFinishing()) {
return;
}
+ mIsSubmittingComment = false;
mImgSubmitComment.setEnabled(true);
mEditComment.setEnabled(true);
if (succeeded) {
@@ -431,6 +436,7 @@ public class ReaderCommentListActivity extends ActionBarActivity {
ToastUtils.showToast(
ReaderCommentListActivity.this, R.string.reader_toast_err_comment_failed, ToastUtils.Duration.LONG);
}
+ checkEmptyView();
}
};
@@ -449,6 +455,7 @@ public class ReaderCommentListActivity extends ActionBarActivity {
getCommentAdapter().addComment(newComment);
// make sure it's scrolled into view
scrollToCommentId(fakeCommentId);
+ checkEmptyView();
}
}
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java
index f5790086b..8b04df9eb 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java
@@ -999,10 +999,26 @@ public class ReaderPostListFragment extends Fragment
return;
}
+ // show "new posts" bar if new posts were downloaded in a followed tag and the adapter
+ // isn't empty (if it's empty, we want to display the new posts immediately)
+ boolean showNewPostsBar;
if (event.getResult() == ReaderActions.UpdateResult.HAS_NEW
&& !isPostAdapterEmpty()
&& event.getAction() == UpdateAction.REQUEST_NEWER
&& getPostListType() == ReaderPostListType.TAG_FOLLOWED) {
+ // make sure that these new posts will actually appear at the top of the list - we
+ // don't want to show "new posts" if the new posts are older ones since the user
+ // expects to see the new posts at the top of the list. we do this by getting the
+ // id of the newest post in the database (which will contain the newly downloaded
+ // posts) and comparing it to the id of the first post in the adapter
+ long newestPostId = ReaderPostTable.getNewestPostIdWithTag(getCurrentTag());
+ ReaderPost post = getPostAdapter().getItem(0);
+ showNewPostsBar = (post != null && post.postId != newestPostId);
+ } else {
+ showNewPostsBar = false;
+ }
+
+ if (showNewPostsBar) {
showNewPostsBar();
refreshPosts();
} else if (event.getResult().isNewOrChanged()) {
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderPostAdapter.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderPostAdapter.java
index b57517eb8..6ad8c2722 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderPostAdapter.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderPostAdapter.java
@@ -450,7 +450,7 @@ public class ReaderPostAdapter extends RecyclerView.Adapter<ReaderPostAdapter.Re
new LoadPostsTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
- ReaderPost getItem(int position) {
+ public ReaderPost getItem(int position) {
if (isValidPosition(position)) {
return mPosts.get(position);
} else {
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsActivity.java
index cb51da028..090fbae97 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsActivity.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsActivity.java
@@ -47,9 +47,9 @@ import org.wordpress.android.util.RateLimitedTask;
import org.wordpress.android.util.StringUtils;
import org.wordpress.android.util.ToastUtils;
import org.wordpress.android.util.ToastUtils.Duration;
+import org.wordpress.android.util.ptr.CustomSwipeRefreshLayout;
import org.wordpress.android.util.ptr.SwipeToRefreshHelper;
import org.wordpress.android.util.ptr.SwipeToRefreshHelper.RefreshListener;
-import org.wordpress.android.util.ptr.CustomSwipeRefreshLayout;
import org.xmlrpc.android.ApiHelper;
import org.xmlrpc.android.XMLRPCCallback;
import org.xmlrpc.android.XMLRPCClientInterface;
@@ -67,7 +67,6 @@ import java.util.Map;
* </p>
*/
public class StatsActivity extends WPDrawerActivity implements ScrollViewExt.ScrollViewListener,
- StatsAuthorsFragment.OnAuthorsSectionChangeListener,
StatsVisitorsAndViewsFragment.OnDateChangeListener,
StatsAbstractListFragment.OnRequestDataListener,
StatsAbstractFragment.TimeframeDateProvider {
@@ -368,14 +367,6 @@ public class StatsActivity extends WPDrawerActivity implements ScrollViewExt.Scr
ft.commitAllowingStateLoss();
}
- // AuthorsFragment should be dismissed when 0 or 1 author.
- public void onAuthorsVisibilityChange(boolean isEmpty) {
- View authorsContainer = this.findViewById(R.id.stats_top_authors_container);
- if (authorsContainer != null) {
- authorsContainer.setVisibility(isEmpty ? View.GONE : View.VISIBLE);
- }
- }
-
@Override
public void onMoreDataRequested(StatsService.StatsEndpointsEnum endPointNeedUpdate, int pageNumber) {
// nope
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsAuthorsFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsAuthorsFragment.java
index 303e67d13..96aec4595 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsAuthorsFragment.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsAuthorsFragment.java
@@ -20,22 +20,6 @@ import java.util.List;
public class StatsAuthorsFragment extends StatsAbstractListFragment {
public static final String TAG = StatsAuthorsFragment.class.getSimpleName();
- private OnAuthorsSectionChangeListener mListener;
-
- // Container Activity must implement this interface
- public interface OnAuthorsSectionChangeListener {
- public void onAuthorsVisibilityChange(boolean isEmpty);
- }
-
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- try {
- mListener = (OnAuthorsSectionChangeListener) activity;
- } catch (ClassCastException e) {
- throw new ClassCastException(activity.toString() + " must implement OnAuthorsSectionChangeListener");
- }
- }
@Override
protected void updateUI() {
@@ -50,22 +34,18 @@ public class StatsAuthorsFragment extends StatsAbstractListFragment {
if (isDataEmpty()) {
showHideNoResultsUI(true);
- mListener.onAuthorsVisibilityChange(true); // Hide the authors section if completely empty
return;
}
List<AuthorModel> authors = ((AuthorsModel) mDatamodels[0]).getAuthors();
- // Do not show the authors section if there is one author only
- if (authors == null || authors.size() <= 1) {
+ if (authors == null || authors.size() == 0) {
showHideNoResultsUI(true);
- mListener.onAuthorsVisibilityChange(true);
return;
}
BaseExpandableListAdapter adapter = new MyExpandableListAdapter(getActivity(), authors);
StatsUIHelper.reloadGroupViews(getActivity(), adapter, mGroupIdToExpandedMap, mList, getMaxNumberOfItemsToShowInList());
showHideNoResultsUI(false);
- mListener.onAuthorsVisibilityChange(false);
}
@Override
@@ -97,7 +77,7 @@ public class StatsAuthorsFragment extends StatsAbstractListFragment {
}
@Override
protected int getEmptyLabelTitleResId() {
- return R.string.stats_empty_top_authors;
+ return R.string.stats_empty_top_posts_title;
}
@Override
protected int getEmptyLabelDescResId() {
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsBarGraph.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsBarGraph.java
index 473948420..1f1853ffa 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsBarGraph.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsBarGraph.java
@@ -110,20 +110,9 @@ class StatsBarGraph extends GraphView {
}
}
- private class HorizontalLabelsBackgroundColor implements IndexDependentColor {
- public int get(int index) {
- if (mBarPositionToHighlight == index) {
- return getResources().getColor(R.color.notification_status_unapproved_dark);
- } else {
- return Color.WHITE;
- }
- }
- }
-
private void setProperties() {
GraphViewStyle gStyle = getGraphViewStyle();
gStyle.setHorizontalLabelsIndexDependentColor(new HorizontalLabelsColor());
- gStyle.setHorizontalLabelsBackgroundIndexDependentColor(new HorizontalLabelsBackgroundColor());
gStyle.setHorizontalLabelsColor(getResources().getColor(R.color.blue_dark));
gStyle.setVerticalLabelsColor(getResources().getColor(R.color.stats_bar_graph_vertical_label));
gStyle.setTextSize(getResources().getDimensionPixelSize(R.dimen.text_sz_extra_small));
@@ -158,6 +147,10 @@ class StatsBarGraph extends GraphView {
double minY, double diffX, double diffY, float horstart,
GraphViewSeriesStyle style) {
float colwidth = graphwidth / values.length;
+ int maxColumnSize = getGraphViewStyle().getMaxColumnWidth();
+ if (maxColumnSize > 0 && colwidth > maxColumnSize) {
+ colwidth = maxColumnSize;
+ }
paint.setStrokeWidth(style.thickness);
paint.setColor(style.color);
@@ -184,9 +177,8 @@ class StatsBarGraph extends GraphView {
float bottom = graphheight + border - 1;
// Draw the orange selection behind the selected bar
- if (mBarPositionToHighlight == i) {
- paint.setColor(getResources().getColor(R.color.notification_status_unapproved_dark));
- paint.setAlpha(50);
+ if (mBarPositionToHighlight == i && style.outerhighlightColor != 0x00ffffff) {
+ paint.setColor(style.outerhighlightColor);
canvas.drawRect(left, 10f, right, bottom, paint);
}
@@ -204,7 +196,7 @@ class StatsBarGraph extends GraphView {
// draw a real bar
paint.setAlpha(255);
if (mBarPositionToHighlight == i) {
- paint.setColor(getResources().getColor(R.color.notification_status_unapproved_dark));
+ paint.setColor(style.highlightColor);
} else {
paint.setColor(style.color);
}
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsConstants.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsConstants.java
index 614064b81..267b6a250 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsConstants.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsConstants.java
@@ -10,6 +10,6 @@ public class StatsConstants {
public static final String STATS_OUTPUT_DATE_MONTH_LONG_FORMAT = "MMMM";
public static final String STATS_OUTPUT_DATE_YEAR_FORMAT = "yyyy";
-
+ public static final int STATS_GRAPH_BAR_MAX_COLUMN_WIDTH_DP = 100;
}
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsSinglePostDetailsActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsSinglePostDetailsActivity.java
index 70a1d6346..b27c49fa9 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsSinglePostDetailsActivity.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsSinglePostDetailsActivity.java
@@ -36,8 +36,8 @@ import org.wordpress.android.util.DisplayUtils;
import org.wordpress.android.util.FormatUtils;
import org.wordpress.android.util.NetworkUtils;
import org.wordpress.android.util.ToastUtils;
-import org.wordpress.android.util.ptr.SwipeToRefreshHelper;
import org.wordpress.android.util.ptr.CustomSwipeRefreshLayout;
+import org.wordpress.android.util.ptr.SwipeToRefreshHelper;
import java.lang.ref.WeakReference;
import java.util.List;
@@ -342,6 +342,9 @@ public class StatsSinglePostDetailsActivity extends ActionBarActivity
mGraphView.addSeries(mCurrentSeriesOnScreen);
//mGraphView.getGraphViewStyle().setNumHorizontalLabels(getNumOfHorizontalLabels(dataToShowOnGraph.length));
mGraphView.getGraphViewStyle().setNumHorizontalLabels(dataToShowOnGraph.length);
+ mGraphView.getGraphViewStyle().setMaxColumnWidth(
+ DisplayUtils.dpToPx(this, StatsConstants.STATS_GRAPH_BAR_MAX_COLUMN_WIDTH_DP)
+ );
mGraphView.setHorizontalLabels(horLabels);
mGraphView.setGestureListener(this);
mSelectedBarGraphIndex = (mSelectedBarGraphIndex != -1) ? mSelectedBarGraphIndex : dataToShowOnGraph.length - 1;
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsUtils.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsUtils.java
index 42cfbd852..4bcb76602 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsUtils.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsUtils.java
@@ -5,13 +5,13 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
+import com.android.volley.NetworkResponse;
import com.android.volley.VolleyError;
import org.json.JSONException;
import org.json.JSONObject;
import org.wordpress.android.R;
import org.wordpress.android.WordPress;
-import org.wordpress.android.WordPressDB;
import org.wordpress.android.models.Blog;
import org.wordpress.android.ui.WPWebViewActivity;
import org.wordpress.android.ui.reader.ReaderActivityLauncher;
@@ -270,6 +270,20 @@ public class StatsUtils {
}
}
+ public static synchronized void logVolleyErrorDetails(final VolleyError volleyError) {
+ if (volleyError == null) {
+ AppLog.e(T.STATS, "Tried to log a VolleyError, but the error obj was null!");
+ return;
+ }
+ if (volleyError.networkResponse != null) {
+ NetworkResponse networkResponse = volleyError.networkResponse;
+ AppLog.e(T.STATS, "Network status code: " + networkResponse.statusCode);
+ if (networkResponse.data != null) {
+ AppLog.e(T.STATS, "Network data: " + new String(networkResponse.data));
+ }
+ }
+ AppLog.e(T.STATS, "Volley Error details: " + volleyError.getMessage(), volleyError);
+ }
public static synchronized Serializable parseResponse(StatsService.StatsEndpointsEnum endpointName, String blogID, JSONObject response)
throws JSONException {
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsViewAllActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsViewAllActivity.java
index 7fcb5d93a..4f5c50308 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsViewAllActivity.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsViewAllActivity.java
@@ -26,8 +26,8 @@ import org.wordpress.android.ui.stats.service.StatsService;
import org.wordpress.android.util.AppLog;
import org.wordpress.android.util.NetworkUtils;
import org.wordpress.android.util.ToastUtils;
-import org.wordpress.android.util.ptr.SwipeToRefreshHelper;
import org.wordpress.android.util.ptr.CustomSwipeRefreshLayout;
+import org.wordpress.android.util.ptr.SwipeToRefreshHelper;
import java.io.Serializable;
import java.lang.ref.WeakReference;
@@ -43,8 +43,7 @@ import java.util.concurrent.ThreadPoolExecutor;
* Single item details activity.
*/
public class StatsViewAllActivity extends ActionBarActivity
- implements StatsAuthorsFragment.OnAuthorsSectionChangeListener,
- StatsAbstractListFragment.OnRequestDataListener,
+ implements StatsAbstractListFragment.OnRequestDataListener,
StatsAbstractFragment.TimeframeDateProvider {
private boolean mIsInFront;
@@ -383,11 +382,6 @@ public class StatsViewAllActivity extends ActionBarActivity
}, 75L);
}
- @Override
- public void onAuthorsVisibilityChange(boolean isEmpty) {
- // Nothing to do here, since the section must not disappear here.
- }
-
private class RestListener implements RestRequest.Listener, RestRequest.ErrorListener {
private final String mRequestBlogId;
private final StatsTimeframe mTimeframe;
@@ -431,10 +425,9 @@ public class StatsViewAllActivity extends ActionBarActivity
@Override
public void onErrorResponse(final VolleyError volleyError) {
- if (volleyError != null) {
- AppLog.e(AppLog.T.STATS, "Error while reading Stats details "
- + volleyError.getMessage(), volleyError);
- }
+ AppLog.e(AppLog.T.STATS, "Error while reading Stats details!");
+ StatsUtils.logVolleyErrorDetails(volleyError);
+
if (mActivityRef.get() == null || mActivityRef.get().isFinishing()) {
return;
}
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsViewHolder.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsViewHolder.java
index 5a1eeff80..562381915 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsViewHolder.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsViewHolder.java
@@ -14,7 +14,6 @@ import android.widget.TextView;
import org.wordpress.android.R;
import org.wordpress.android.WordPress;
-import org.wordpress.android.WordPressDB;
import org.wordpress.android.ui.WPWebViewActivity;
import org.wordpress.android.ui.stats.models.PostModel;
import org.wordpress.android.util.AppLog;
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsVisitorsAndViewsFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsVisitorsAndViewsFragment.java
index e58bbfbf4..ca8c95ce7 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsVisitorsAndViewsFragment.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsVisitorsAndViewsFragment.java
@@ -6,16 +6,16 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.drawable.Drawable;
+import android.os.Build;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
-import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.CheckBox;
import android.widget.CheckedTextView;
import android.widget.ImageView;
import android.widget.LinearLayout;
-import android.widget.RadioGroup;
import android.widget.TextView;
import com.android.volley.VolleyError;
@@ -35,7 +35,6 @@ import org.wordpress.android.util.DisplayUtils;
import org.wordpress.android.util.FormatUtils;
import org.wordpress.android.util.NetworkUtils;
import org.wordpress.android.util.StringUtils;
-import org.wordpress.android.widgets.TypefaceCache;
import java.io.Serializable;
import java.text.ParseException;
@@ -51,14 +50,21 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment
public static final String TAG = StatsVisitorsAndViewsFragment.class.getSimpleName();
private static final String ARG_SELECTED_GRAPH_BAR = "ARG_SELECTED_GRAPH_BAR";
private static final String ARG_SELECTED_OVERVIEW_ITEM = "ARG_SELECTED_OVERVIEW_ITEM";
+ private static final String ARG_CHECKBOX_SELECTED = "ARG_CHECKBOX_SELECTED";
+
private LinearLayout mGraphContainer;
private StatsBarGraph mGraphView;
- private GraphViewSeries mCurrentSeriesOnScreen;
private LinearLayout mModuleButtonsContainer;
private TextView mDateTextView;
private String[] mStatsDate;
+ private LinearLayout mLegendContainer;
+ private CheckedTextView mLegendLabel;
+ private LinearLayout mVisitorsCheckboxContainer;
+ private CheckBox mVisitorsCheckbox;
+ private boolean mIsCheckboxChecked;
+
private OnDateChangeListener mListener;
final OverviewLabel[] overviewItems = {OverviewLabel.VIEWS, OverviewLabel.VISITORS, OverviewLabel.LIKES,
@@ -92,6 +98,19 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment
mGraphContainer = (LinearLayout) view.findViewById(R.id.stats_bar_chart_fragment_container);
mModuleButtonsContainer = (LinearLayout) view.findViewById(R.id.stats_pager_tabs);
+ mLegendContainer = (LinearLayout) view.findViewById(R.id.stats_legend_container);
+ mLegendLabel = (CheckedTextView) view.findViewById(R.id.stats_legend_label);
+ mLegendLabel.setCheckMarkDrawable(null); // Make sure to set a null drawable here. Otherwise the touching area is the same of a TextView
+ mVisitorsCheckboxContainer = (LinearLayout) view.findViewById(R.id.stats_checkbox_visitors_container);
+ mVisitorsCheckbox = (CheckBox) view.findViewById(R.id.stats_checkbox_visitors);
+ mVisitorsCheckbox.setOnClickListener(onCheckboxClicked);
+
+ // Fix an issue on devices with 4.1 or lower, where the Checkbox already uses padding by default internally and overriding it with paddingLeft
+ // causes the issue report here https://github.com/wordpress-mobile/WordPress-Android/pull/2377#issuecomment-77067993
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ mVisitorsCheckbox.setPadding(getResources().getDimensionPixelSize(R.dimen.margin_medium), 0, 0, 0);
+ }
+
// Make sure we've all the info to build the tab correctly. This is ALWAYS true
if (mModuleButtonsContainer.getChildCount() == overviewItems.length) {
for (int i = 0; i < mModuleButtonsContainer.getChildCount(); i++) {
@@ -213,6 +232,16 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment
}
};
+
+ View.OnClickListener onCheckboxClicked = new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ // Is the view now checked?
+ mIsCheckboxChecked = ((CheckBox) view).isChecked();
+ updateUI();
+ }
+ };
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -227,6 +256,10 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment
if (savedInstanceState.containsKey(ARG_SELECTED_GRAPH_BAR)) {
mSelectedBarGraphBarIndex = savedInstanceState.getInt(ARG_SELECTED_GRAPH_BAR, -1);
}
+
+ mIsCheckboxChecked = savedInstanceState.getBoolean(ARG_CHECKBOX_SELECTED, true);
+ } else {
+ mIsCheckboxChecked = true;
}
}
@@ -242,6 +275,7 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment
outState.putSerializable(ARG_REST_RESPONSE, mVisitsData);
outState.putInt(ARG_SELECTED_GRAPH_BAR, mSelectedBarGraphBarIndex);
outState.putInt(ARG_SELECTED_OVERVIEW_ITEM, mSelectedOverviewItemIndex);
+ outState.putBoolean(ARG_CHECKBOX_SELECTED, mVisitorsCheckbox.isChecked());
super.onSaveInstanceState(outState);
}
@@ -302,13 +336,34 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment
return;
}
+ // Read the selected Tab in the UI
+ OverviewLabel selectedStatsType = overviewItems[mSelectedOverviewItemIndex];
+ // Update the Legend and enable/disable the visitors checkboxes
+ mLegendContainer.setVisibility(View.VISIBLE);
+ mLegendLabel.setText(StringUtils.capitalize(selectedStatsType.getLabel().toLowerCase()));
+ switch(selectedStatsType) {
+ case VIEWS:
+ mVisitorsCheckboxContainer.setVisibility(View.VISIBLE);
+ mVisitorsCheckbox.setEnabled(true);
+ mVisitorsCheckbox.setChecked(mIsCheckboxChecked);
+ break;
+ default:
+ mVisitorsCheckboxContainer.setVisibility(View.GONE);
+ break;
+ }
+
+ // Setting Up labels and prepare variables that hold series
final String[] horLabels = new String[dataToShowOnGraph.length];
mStatsDate = new String[dataToShowOnGraph.length];
- GraphView.GraphViewData[] views = new GraphView.GraphViewData[dataToShowOnGraph.length];
+ GraphView.GraphViewData[] mainSeriesItems = new GraphView.GraphViewData[dataToShowOnGraph.length];
- OverviewLabel selectedStatsType = overviewItems[mSelectedOverviewItemIndex];
+ GraphView.GraphViewData[] secondarySeriesItems = null;
+ if (mIsCheckboxChecked && selectedStatsType == OverviewLabel.VIEWS) {
+ secondarySeriesItems = new GraphView.GraphViewData[dataToShowOnGraph.length];
+ }
+ // Fill series variables with data
for (int i = 0; i < dataToShowOnGraph.length; i++) {
int currentItemValue = 0;
switch(selectedStatsType) {
@@ -325,18 +380,17 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment
currentItemValue = dataToShowOnGraph[i].getComments();
break;
}
- views[i] = new GraphView.GraphViewData(i, currentItemValue);
+ mainSeriesItems[i] = new GraphView.GraphViewData(i, currentItemValue);
+
+ if (mIsCheckboxChecked && secondarySeriesItems != null) {
+ secondarySeriesItems[i] = new GraphView.GraphViewData(i, dataToShowOnGraph[i].getVisitors());
+ }
String currentItemStatsDate = dataToShowOnGraph[i].getPeriod();
horLabels[i] = getDateLabelForBarInGraph(currentItemStatsDate);
mStatsDate[i] = currentItemStatsDate;
}
- mCurrentSeriesOnScreen = new GraphViewSeries(views);
- mCurrentSeriesOnScreen.getStyle().color = getResources().getColor(R.color.stats_bar_graph_views);
- mCurrentSeriesOnScreen.getStyle().padding = DisplayUtils.dpToPx(getActivity(), 5);
-
-
if (mGraphContainer.getChildCount() >= 1 && mGraphContainer.getChildAt(0) instanceof GraphView) {
mGraphView = (StatsBarGraph) mGraphContainer.getChildAt(0);
} else {
@@ -346,10 +400,44 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment
}
mGraphView.removeAllSeries();
- mGraphView.addSeries(mCurrentSeriesOnScreen);
- //mGraphView.getGraphViewStyle().setNumHorizontalLabels(getNumOfHorizontalLabels(dataToShowOnGraph.length));
+
+ GraphViewSeries mainSeriesOnScreen = new GraphViewSeries(mainSeriesItems);
+ mainSeriesOnScreen.getStyle().color = getResources().getColor(R.color.stats_bar_graph_views);
+ mainSeriesOnScreen.getStyle().highlightColor = getResources().getColor(R.color.calypso_orange_dark);
+ mainSeriesOnScreen.getStyle().outerhighlightColor = getResources().getColor(R.color.stats_bar_graph_outer_highlight);
+ mainSeriesOnScreen.getStyle().padding = DisplayUtils.dpToPx(getActivity(), 5);
+ mGraphView.addSeries(mainSeriesOnScreen);
+
+ // Add the Visitors series if it's checked in the legend
+ if (mIsCheckboxChecked && secondarySeriesItems != null && selectedStatsType == OverviewLabel.VIEWS) {
+ GraphViewSeries secondarySeries = new GraphViewSeries(secondarySeriesItems);
+ secondarySeries.getStyle().padding = DisplayUtils.dpToPx(getActivity(), 10);
+ secondarySeries.getStyle().color = getResources().getColor(R.color.stats_bar_graph_views_inner);
+ secondarySeries.getStyle().highlightColor = getResources().getColor(R.color.orange_dark);
+ mGraphView.addSeries(secondarySeries);
+ }
+
+ // Setup the Y-axis on Visitors and Views Tabs.
+ // Views and Visitors tabs have the exact same Y-axis as shifting from one Y-axis to another defeats
+ // the purpose of making these bars visually easily to compare.
+ switch(selectedStatsType) {
+ case VISITORS:
+ double maxYValue = getMaxYValueForVisitorsAndView(dataToShowOnGraph);
+ mGraphView.setManualYAxisBounds(maxYValue, 0d);
+ break;
+ default:
+ mGraphView.setManualYAxis(false);
+ break;
+ }
+
+ // Set the Graph Style
mGraphView.getGraphViewStyle().setNumHorizontalLabels(dataToShowOnGraph.length);
+ // Set the maximum size a column can get on the screen in PX
+ mGraphView.getGraphViewStyle().setMaxColumnWidth(
+ DisplayUtils.dpToPx(getActivity(), StatsConstants.STATS_GRAPH_BAR_MAX_COLUMN_WIDTH_DP)
+ );
mGraphView.setHorizontalLabels(horLabels);
+
mGraphView.setGestureListener(this);
int barSelectedOnGraph;
@@ -371,6 +459,23 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment
mGraphView.highlightBar(barSelectedOnGraph);
}
+ // Find the max value in Visitors and Views data.
+ // Only checks the Views data, since Visitors is for sure less-equals than Views.
+ private double getMaxYValueForVisitorsAndView(final VisitModel[] dataToShowOnGraph) {
+ if (dataToShowOnGraph == null || dataToShowOnGraph.length == 0) {
+ return 0d;
+ }
+ double largest = Integer.MIN_VALUE;
+
+ for (int i = 0; i < dataToShowOnGraph.length; i++) {
+ int currentItemValue = dataToShowOnGraph[i].getViews();
+ if (currentItemValue > largest) {
+ largest = currentItemValue;
+ }
+ }
+ return largest;
+ }
+
//update the area right below the graph
private void updateUIBelowTheGraph(int itemPosition) {
if (!isAdded()) {
@@ -503,6 +608,11 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment
if (!isAdded()) {
return;
}
+
+ // Hide the legend
+ mLegendContainer.setVisibility(View.GONE);
+ mVisitorsCheckboxContainer.setVisibility(View.GONE);
+
mSelectedBarGraphBarIndex = -1;
Context context = mGraphContainer.getContext();
if (context != null) {
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsWPLinkMovementMethod.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsWPLinkMovementMethod.java
index e77d73daa..e6b26a73c 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsWPLinkMovementMethod.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsWPLinkMovementMethod.java
@@ -9,7 +9,6 @@ import android.view.MotionEvent;
import android.widget.TextView;
import org.wordpress.android.WordPress;
-import org.wordpress.android.WordPressDB;
import org.wordpress.android.ui.WPWebViewActivity;
import org.wordpress.android.util.AppLog;
import org.wordpress.android.util.UrlUtils;
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/service/StatsService.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/service/StatsService.java
index c1211739d..246c7e5bf 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/stats/service/StatsService.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/service/StatsService.java
@@ -6,6 +6,7 @@ import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils;
+import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.VolleyError;
import com.wordpress.rest.RestRequest;
@@ -303,9 +304,7 @@ public class StatsService extends Service {
}
mNumberOfFinishedNetworkCalls++;
AppLog.e(T.STATS, this.getClass().getName() + " responded with an Error");
- if (volleyError != null) {
- AppLog.e(T.STATS, "Error details: \n" + volleyError.getMessage(), volleyError);
- }
+ StatsUtils.logVolleyErrorDetails(volleyError);
mResponseObjectModel = volleyError;
notifySectionUpdated();
checkAllRequestsFinished();
diff --git a/WordPress/src/main/java/org/wordpress/android/widgets/TypefaceCache.java b/WordPress/src/main/java/org/wordpress/android/widgets/TypefaceCache.java
index 6db0fe359..98c32c23d 100644
--- a/WordPress/src/main/java/org/wordpress/android/widgets/TypefaceCache.java
+++ b/WordPress/src/main/java/org/wordpress/android/widgets/TypefaceCache.java
@@ -11,33 +11,50 @@ import org.wordpress.android.R;
import java.util.Hashtable;
public class TypefaceCache {
- protected static final int VARIATION_NORMAL = 0;
- protected static final int VARIATION_LIGHT = 1;
+ private static final int VARIATION_NORMAL = 0;
+ private static final int VARIATION_LIGHT = 1;
- private static final Hashtable<String, Typeface> mTypefaceCache = new Hashtable<String, Typeface>();
+ private static final Hashtable<String, Typeface> mTypefaceCache = new Hashtable<>();
public static Typeface getTypeface(Context context) {
return getTypeface(context, Typeface.NORMAL, VARIATION_NORMAL);
}
- public static Typeface getTypeface(Context context, int fontStyle, int variation) {
- if (context == null)
+ private static Typeface getTypeface(Context context, int fontStyle, int variation) {
+ if (context == null) {
return null;
+ }
- // note that the "light" variation doesn't support bold or bold-italic
final String typefaceName;
- switch (fontStyle) {
- case Typeface.BOLD:
- typefaceName = "OpenSans-Bold.ttf";
- break;
- case Typeface.ITALIC:
- typefaceName = (variation == VARIATION_LIGHT ? "OpenSans-LightItalic.ttf" : "OpenSans-Italic.ttf");
- break;
- case Typeface.BOLD_ITALIC:
- typefaceName = "OpenSans-BoldItalic.ttf";
- break;
- default:
- typefaceName = (variation == VARIATION_LIGHT ? "OpenSans-Light.ttf" : "OpenSans-Regular.ttf");
- break;
+ if (variation == VARIATION_LIGHT) {
+ switch (fontStyle) {
+ case Typeface.BOLD:
+ typefaceName = "OpenSans-LightBold.ttf";
+ break;
+ case Typeface.ITALIC:
+ typefaceName = "OpenSans-LightItalic.ttf";
+ break;
+ case Typeface.BOLD_ITALIC:
+ typefaceName = "OpenSans-LightBoldItalic.ttf";
+ break;
+ default:
+ typefaceName = "OpenSans-Light.ttf";
+ break;
+ }
+ } else {
+ switch (fontStyle) {
+ case Typeface.BOLD:
+ typefaceName = "OpenSans-Bold.ttf";
+ break;
+ case Typeface.ITALIC:
+ typefaceName = "OpenSans-Italic.ttf";
+ break;
+ case Typeface.BOLD_ITALIC:
+ typefaceName = "OpenSans-BoldItalic.ttf";
+ break;
+ default:
+ typefaceName = "OpenSans-Regular.ttf";
+ break;
+ }
}
return getTypefaceForTypefaceName(context, typefaceName);