aboutsummaryrefslogtreecommitdiff
path: root/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsAbstractFragment.java
diff options
context:
space:
mode:
Diffstat (limited to 'WordPress/src/main/java/org/wordpress/android/ui/stats/StatsAbstractFragment.java')
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/stats/StatsAbstractFragment.java361
1 files changed, 361 insertions, 0 deletions
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsAbstractFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsAbstractFragment.java
new file mode 100644
index 000000000..a6d761b9c
--- /dev/null
+++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsAbstractFragment.java
@@ -0,0 +1,361 @@
+package org.wordpress.android.ui.stats;
+
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.content.Intent;
+import android.os.Bundle;
+
+import com.android.volley.NoConnectionError;
+import com.android.volley.VolleyError;
+
+import org.wordpress.android.R;
+import org.wordpress.android.WordPress;
+import org.wordpress.android.models.AccountHelper;
+import org.wordpress.android.models.Blog;
+import org.wordpress.android.ui.stats.service.StatsService;
+import org.wordpress.android.util.AppLog;
+
+import de.greenrobot.event.EventBus;
+
+
+public abstract class StatsAbstractFragment extends Fragment {
+ public static final String TAG = StatsAbstractFragment.class.getSimpleName();
+
+ public static final String ARGS_VIEW_TYPE = "ARGS_VIEW_TYPE";
+ public static final String ARGS_TIMEFRAME = "ARGS_TIMEFRAME";
+ public static final String ARGS_SELECTED_DATE = "ARGS_SELECTED_DATE";
+ static final String ARG_REST_RESPONSE = "ARG_REST_RESPONSE";
+ static final String ARGS_IS_SINGLE_VIEW = "ARGS_IS_SINGLE_VIEW";
+
+ // The number of results to return for NON Paged REST endpoints.
+ private static final int MAX_RESULTS_REQUESTED = 100;
+
+ private String mDate;
+ private StatsTimeframe mStatsTimeframe = StatsTimeframe.DAY;
+
+ protected abstract StatsService.StatsEndpointsEnum[] sectionsToUpdate();
+ protected abstract void showPlaceholderUI();
+ protected abstract void updateUI();
+ protected abstract void showErrorUI(String label);
+
+ /**
+ * Wheter or not previous data is available.
+ * @return True if previous data is already available in the fragment
+ */
+ protected abstract boolean hasDataAvailable();
+
+ /**
+ * Called in onSaveIstance. Fragments should persist data here.
+ * @param outState Bundle in which to place fragment saved state.
+ */
+ protected abstract void saveStatsData(Bundle outState);
+
+ /**
+ * Called in OnCreate. Fragment should restore here previous saved data.
+ * @param savedInstanceState If the fragment is being re-created from a previous saved state, this is the state.
+ */
+ protected abstract void restoreStatsData(Bundle savedInstanceState); // called in onCreate
+
+ protected StatsResourceVars mResourceVars;
+
+ public void refreshStats() {
+ refreshStats(-1, null);
+ }
+ // call an update for the stats shown in the fragment
+ void refreshStats(int pageNumberRequested, StatsService.StatsEndpointsEnum[] sections) {
+ if (!isAdded()) {
+ return;
+ }
+
+ // if no sections to update is passed to the method, default to fragment
+ if (sections == null) {
+ sections = sectionsToUpdate();
+ }
+
+ //AppLog.d(AppLog.T.STATS, this.getClass().getCanonicalName() + " > refreshStats");
+
+ final Blog currentBlog = WordPress.getBlog(getLocalTableBlogID());
+ if (currentBlog == null) {
+ AppLog.w(AppLog.T.STATS, "Current blog is null. This should never happen here.");
+ return;
+ }
+
+ final String blogId = currentBlog.getDotComBlogId();
+ // Make sure the blogId is available.
+ if (blogId == null) {
+ AppLog.e(AppLog.T.STATS, "remote blogID is null: " + currentBlog.getHomeURL());
+ return;
+ }
+
+ // Check credentials for jetpack blogs first
+ if (!currentBlog.isDotcomFlag()
+ && !currentBlog.hasValidJetpackCredentials() && !AccountHelper.isSignedInWordPressDotCom()) {
+ AppLog.w(AppLog.T.STATS, "Current blog is a Jetpack blog without valid .com credentials stored");
+ return;
+ }
+
+ // Do not pass the array of StatsEndpointsEnum to the Service. Otherwise we get
+ // java.lang.RuntimeException: Unable to start service org.wordpress.android.ui.stats.service.StatsService
+ // with Intent { cmp=org.wordpress.android/.ui.stats.service.StatsService (has extras) }: java.lang.ClassCastException:
+ // java.lang.Object[] cannot be cast to org.wordpress.android.ui.stats.service.StatsService$StatsEndpointsEnum[]
+ // on older devices.
+ // We should use Enumset, or array of int. Going for the latter, since we have an array and cannot create an Enumset easily.
+ int[] sectionsForTheService = new int[sections.length];
+ for (int i=0; i < sections.length; i++){
+ sectionsForTheService[i] = sections[i].ordinal();
+ }
+
+ // start service to get stats
+ Intent intent = new Intent(getActivity(), StatsService.class);
+ intent.putExtra(StatsService.ARG_BLOG_ID, blogId);
+ intent.putExtra(StatsService.ARG_PERIOD, mStatsTimeframe);
+ intent.putExtra(StatsService.ARG_DATE, mDate);
+ if (isSingleView()) {
+ // Single Item screen: request 20 items per page on paged requests. Default to the first 100 items otherwise.
+ int maxElementsToRetrieve = pageNumberRequested > 0 ? StatsService.MAX_RESULTS_REQUESTED_PER_PAGE : MAX_RESULTS_REQUESTED;
+ intent.putExtra(StatsService.ARG_MAX_RESULTS, maxElementsToRetrieve);
+ }
+ if (pageNumberRequested > 0) {
+ intent.putExtra(StatsService.ARG_PAGE_REQUESTED, pageNumberRequested);
+ }
+ intent.putExtra(StatsService.ARG_SECTION, sectionsForTheService);
+ getActivity().startService(intent);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // AppLog.d(AppLog.T.STATS, this.getClass().getCanonicalName() + " > onCreate");
+
+ if (savedInstanceState != null) {
+ if (savedInstanceState.containsKey(ARGS_TIMEFRAME)) {
+ mStatsTimeframe = (StatsTimeframe) savedInstanceState.getSerializable(ARGS_TIMEFRAME);
+ }
+ if (savedInstanceState.containsKey(ARGS_SELECTED_DATE)) {
+ mDate = savedInstanceState.getString(ARGS_SELECTED_DATE);
+ }
+ restoreStatsData(savedInstanceState); // Each fragment will override this to restore fragment dependant data
+ }
+
+ // AppLog.d(AppLog.T.STATS, "mStatsTimeframe: " + mStatsTimeframe.getLabel());
+ // AppLog.d(AppLog.T.STATS, "mDate: " + mDate);
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ mResourceVars = new StatsResourceVars(activity);
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ /* AppLog.d(AppLog.T.STATS, this.getClass().getCanonicalName() + " > saving instance state");
+ AppLog.d(AppLog.T.STATS, "mStatsTimeframe: " + mStatsTimeframe.getLabel());
+ AppLog.d(AppLog.T.STATS, "mDate: " + mDate); */
+
+ outState.putString(ARGS_SELECTED_DATE, mDate);
+ outState.putSerializable(ARGS_TIMEFRAME, mStatsTimeframe);
+ saveStatsData(outState); // Each fragment will override this
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ // Init the UI
+ if (hasDataAvailable()) {
+ updateUI();
+ } else {
+ showPlaceholderUI();
+ refreshStats();
+ }
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ EventBus.getDefault().register(this);
+ }
+
+ @Override
+ public void onStop() {
+ EventBus.getDefault().unregister(this);
+ super.onStop();
+ }
+
+ public boolean shouldUpdateFragmentOnUpdateEvent(StatsEvents.SectionUpdatedAbstract event) {
+ if (!isAdded()) {
+ return false;
+ }
+
+ if (!getDate().equals(event.mDate)) {
+ return false;
+ }
+
+ if (!isSameBlog(event)) {
+ return false;
+ }
+
+ if (!event.mTimeframe.equals(getTimeframe())) {
+ return false;
+ }
+
+ return true;
+ }
+
+ boolean isSameBlog(StatsEvents.SectionUpdatedAbstract event) {
+ final Blog currentBlog = WordPress.getBlog(getLocalTableBlogID());
+ if (currentBlog != null && currentBlog.getDotComBlogId() != null) {
+ return event.mRequestBlogId.equals(currentBlog.getDotComBlogId());
+ }
+ return false;
+ }
+
+ protected void showErrorUI(VolleyError error) {
+ if (!isAdded()) {
+ return;
+ }
+
+ String label = "<b>" + getString(R.string.error_refresh_stats) + "</b>";
+
+ if (error instanceof NoConnectionError) {
+ label += "<br/>" + getString(R.string.no_network_message);
+ }
+
+ if (StatsUtils.isRESTDisabledError(error)) {
+ label += "<br/>" + getString(R.string.stats_enable_rest_api_in_jetpack);
+ }
+
+ showErrorUI(label);
+ }
+
+ protected void showErrorUI() {
+ String label = "<b>" + getString(R.string.error_refresh_stats) + "</b>";
+ showErrorUI(label);
+ }
+
+ public boolean shouldUpdateFragmentOnErrorEvent(StatsEvents.SectionUpdateError errorEvent) {
+ if (!shouldUpdateFragmentOnUpdateEvent(errorEvent)) {
+ return false;
+ }
+
+ StatsService.StatsEndpointsEnum sectionToUpdate = errorEvent.mEndPointName;
+ StatsService.StatsEndpointsEnum[] sectionsToUpdate = sectionsToUpdate();
+
+ for (int i = 0; i < sectionsToUpdate().length; i++) {
+ if (sectionToUpdate == sectionsToUpdate[i]) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static StatsAbstractFragment newVisitorsAndViewsInstance(StatsViewType viewType, int localTableBlogID,
+ StatsTimeframe timeframe, String date, StatsVisitorsAndViewsFragment.OverviewLabel itemToSelect) {
+ StatsVisitorsAndViewsFragment fragment = (StatsVisitorsAndViewsFragment) newInstance(viewType, localTableBlogID, timeframe, date);
+ fragment.setSelectedOverviewItem(itemToSelect);
+ return fragment;
+ }
+
+ public static StatsAbstractFragment newInstance(StatsViewType viewType, int localTableBlogID,
+ StatsTimeframe timeframe, String date ) {
+ StatsAbstractFragment fragment = null;
+
+ switch (viewType) {
+ //case TIMEFRAME_SELECTOR:
+ // fragment = new StatsDateSelectorFragment();
+ // break;
+ case GRAPH_AND_SUMMARY:
+ fragment = new StatsVisitorsAndViewsFragment();
+ break;
+ case TOP_POSTS_AND_PAGES:
+ fragment = new StatsTopPostsAndPagesFragment();
+ break;
+ case REFERRERS:
+ fragment = new StatsReferrersFragment();
+ break;
+ case CLICKS:
+ fragment = new StatsClicksFragment();
+ break;
+ case GEOVIEWS:
+ fragment = new StatsGeoviewsFragment();
+ break;
+ case AUTHORS:
+ fragment = new StatsAuthorsFragment();
+ break;
+ case VIDEO_PLAYS:
+ fragment = new StatsVideoplaysFragment();
+ break;
+ case COMMENTS:
+ fragment = new StatsCommentsFragment();
+ break;
+ case TAGS_AND_CATEGORIES:
+ fragment = new StatsTagsAndCategoriesFragment();
+ break;
+ case PUBLICIZE:
+ fragment = new StatsPublicizeFragment();
+ break;
+ case FOLLOWERS:
+ fragment = new StatsFollowersFragment();
+ break;
+ case SEARCH_TERMS:
+ fragment = new StatsSearchTermsFragment();
+ break;
+ case INSIGHTS_MOST_POPULAR:
+ fragment = new StatsInsightsMostPopularFragment();
+ break;
+ case INSIGHTS_ALL_TIME:
+ fragment = new StatsInsightsAllTimeFragment();
+ break;
+ case INSIGHTS_TODAY:
+ fragment = new StatsInsightsTodayFragment();
+ break;
+ case INSIGHTS_LATEST_POST_SUMMARY:
+ fragment = new StatsInsightsLatestPostSummaryFragment();
+ break;
+ }
+
+ fragment.setTimeframe(timeframe);
+ fragment.setDate(date);
+
+ Bundle args = new Bundle();
+ args.putSerializable(ARGS_VIEW_TYPE, viewType);
+ args.putInt(StatsActivity.ARG_LOCAL_TABLE_BLOG_ID, localTableBlogID);
+ fragment.setArguments(args);
+
+ return fragment;
+ }
+
+ public void setDate(String newDate) {
+ mDate = newDate;
+ }
+
+ String getDate() {
+ return mDate;
+ }
+
+ public void setTimeframe(StatsTimeframe newTimeframe) {
+ mStatsTimeframe = newTimeframe;
+ }
+
+ StatsTimeframe getTimeframe() {
+ return mStatsTimeframe;
+ }
+
+ StatsViewType getViewType() {
+ return (StatsViewType) getArguments().getSerializable(ARGS_VIEW_TYPE);
+ }
+
+ int getLocalTableBlogID() {
+ return getArguments().getInt(StatsActivity.ARG_LOCAL_TABLE_BLOG_ID);
+ }
+
+ boolean isSingleView() {
+ return getArguments().getBoolean(ARGS_IS_SINGLE_VIEW, false);
+ }
+
+ protected abstract String getTitle();
+} \ No newline at end of file