aboutsummaryrefslogtreecommitdiff
path: root/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsGeoviewsFragment.java
diff options
context:
space:
mode:
Diffstat (limited to 'WordPress/src/main/java/org/wordpress/android/ui/stats/StatsGeoviewsFragment.java')
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/stats/StatsGeoviewsFragment.java299
1 files changed, 299 insertions, 0 deletions
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsGeoviewsFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsGeoviewsFragment.java
new file mode 100644
index 000000000..3622c817a
--- /dev/null
+++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsGeoviewsFragment.java
@@ -0,0 +1,299 @@
+package org.wordpress.android.ui.stats;
+
+import android.app.Activity;
+import android.net.http.SslError;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.webkit.SslErrorHandler;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.ArrayAdapter;
+import android.widget.LinearLayout;
+
+import org.wordpress.android.R;
+import org.wordpress.android.ui.stats.models.GeoviewModel;
+import org.wordpress.android.ui.stats.models.GeoviewsModel;
+import org.wordpress.android.ui.stats.service.StatsService;
+import org.wordpress.android.util.AppLog;
+import org.wordpress.android.util.DisplayUtils;
+import org.wordpress.android.util.FormatUtils;
+import org.wordpress.android.util.GravatarUtils;
+import org.wordpress.android.widgets.WPNetworkImageView;
+
+import java.util.List;
+
+
+public class StatsGeoviewsFragment extends StatsAbstractListFragment {
+ public static final String TAG = StatsGeoviewsFragment.class.getSimpleName();
+
+ private GeoviewsModel mCountries;
+
+ @Override
+ protected boolean hasDataAvailable() {
+ return mCountries != null;
+ }
+ @Override
+ protected void saveStatsData(Bundle outState) {
+ if (hasDataAvailable()) {
+ outState.putSerializable(ARG_REST_RESPONSE, mCountries);
+ }
+ }
+ @Override
+ protected void restoreStatsData(Bundle savedInstanceState) {
+ if (savedInstanceState.containsKey(ARG_REST_RESPONSE)) {
+ mCountries = (GeoviewsModel) savedInstanceState.getSerializable(ARG_REST_RESPONSE);
+ }
+ }
+
+ @SuppressWarnings("unused")
+ public void onEventMainThread(StatsEvents.CountriesUpdated event) {
+ if (!shouldUpdateFragmentOnUpdateEvent(event)) {
+ return;
+ }
+
+ mCountries = event.mCountries;
+ updateUI();
+ }
+
+ @SuppressWarnings("unused")
+ public void onEventMainThread(StatsEvents.SectionUpdateError event) {
+ if (!shouldUpdateFragmentOnErrorEvent(event)) {
+ return;
+ }
+
+ mCountries = null;
+ showErrorUI(event.mError);
+ }
+
+ private void hideMap() {
+ if (!isAdded()) {
+ return;
+ }
+
+ mTopPagerContainer.setVisibility(View.GONE);
+ }
+
+ private void showMap(final List<GeoviewModel> countries) {
+ if (!isAdded()) {
+ return;
+ }
+
+ // setting up different margins for the map. We're basically remove left margins since the
+ // chart service produce a map that's slightly shifted on the right. See the Web version.
+ int dp4 = DisplayUtils.dpToPx(mTopPagerContainer.getContext(), 4);
+ LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
+ layoutParams.setMargins(0, 0, dp4, 0);
+ mTopPagerContainer.setLayoutParams(layoutParams);
+
+ mTopPagerContainer.removeAllViews();
+
+ // must wait for mTopPagerContainer to be fully laid out (ie: measured). Then we can read the width and
+ // calculate the right height for the map div
+ mTopPagerContainer.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ mTopPagerContainer.getViewTreeObserver().removeGlobalOnLayoutListener(this);
+ if (!isAdded()) {
+ return;
+ }
+
+ StringBuilder dataToLoad = new StringBuilder();
+
+ for (int i = 0; i < countries.size(); i++) {
+ final GeoviewModel currentCountry = countries.get(i);
+ dataToLoad.append("['").append(currentCountry.getCountryFullName()).append("',")
+ .append(currentCountry.getViews()).append("],");
+ }
+
+ // This is the label that is shown when the user taps on a region
+ String label = getResources().getString(getTotalsLabelResId());
+
+ // See: https://developers.google.com/chart/interactive/docs/gallery/geochart
+ // Loading the v42 of the Google Charts API, since the latest stable version has a problem with the legend. https://github.com/wordpress-mobile/WordPress-Android/issues/4131
+ // https://developers.google.com/chart/interactive/docs/release_notes#release-candidate-details
+ String htmlPage = "<html>" +
+ "<head>" +
+ "<script type=\"text/javascript\" src=\"https://www.gstatic.com/charts/loader.js\"></script>" +
+ "<script type=\"text/javascript\" src=\"https://www.google.com/jsapi\"></script>" +
+ "<script type=\"text/javascript\">" +
+ "google.charts.load('42', {'packages':['geochart']});" +
+ "google.charts.setOnLoadCallback(drawRegionsMap);" +
+ "function drawRegionsMap() {" +
+ "var data = google.visualization.arrayToDataTable(" +
+ "[" +
+ "['Country', '" + label + "']," +
+ dataToLoad +
+ "]);" +
+ "var options = {keepAspectRatio: true, region: 'world', colorAxis: { colors: [ '#FFF088', '#F34605' ] }, enableRegionInteractivity: true};" +
+ "var chart = new google.visualization.GeoChart(document.getElementById('regions_div'));" +
+ "chart.draw(data, options);" +
+ "}" +
+ "</script>" +
+ "</head>" +
+ "<body>" +
+ "<div id=\"regions_div\" style=\"width: 100%; height: 100%;\"></div>" +
+ "</body>" +
+ "</html>";
+
+ WebView webView = new WebView(getActivity());
+ mTopPagerContainer.addView(webView);
+
+ int width = mTopPagerContainer.getWidth();
+ int height = width * 3 / 4;
+
+ LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) webView.getLayoutParams();
+ params.width = WebView.LayoutParams.MATCH_PARENT;
+ params.height = height;
+
+ webView.setLayoutParams(params);
+
+ webView.setWebViewClient(new MyWebViewClient()); // Hide map in case of unrecoverable errors
+ webView.getSettings().setJavaScriptEnabled(true);
+ webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
+ webView.loadData(htmlPage, "text/html", "UTF-8");
+
+ }
+ });
+ mTopPagerContainer.setVisibility(View.VISIBLE);
+ }
+
+ // Hide the Map in case of errors
+ private class MyWebViewClient extends WebViewClient {
+ @Override
+ public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
+ super.onReceivedError(view, errorCode, description, failingUrl);
+ mTopPagerContainer.setVisibility(View.GONE);
+ AppLog.e(AppLog.T.STATS, "Cannot load geochart."
+ + " ErrorCode: " + errorCode
+ + " Description: " + description
+ + " Failing URL: " + failingUrl);
+ }
+ @Override
+ public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
+ super.onReceivedSslError(view, handler, error);
+ mTopPagerContainer.setVisibility(View.GONE);
+ AppLog.e(AppLog.T.STATS, "Cannot load geochart. SSL ERROR. " + error.toString());
+ }
+ }
+
+ @Override
+ protected void updateUI() {
+ if (!isAdded()) {
+ return;
+ }
+
+ if (hasCountries()) {
+ List<GeoviewModel> countries = getCountries();
+ ArrayAdapter adapter = new GeoviewsAdapter(getActivity(), countries);
+ StatsUIHelper.reloadLinearLayout(getActivity(), adapter, mList, getMaxNumberOfItemsToShowInList());
+ showHideNoResultsUI(false);
+ showMap(countries);
+ } else {
+ showHideNoResultsUI(true);
+ hideMap();
+ }
+ }
+
+ private boolean hasCountries() {
+ return mCountries != null && mCountries.getCountries() != null;
+ }
+
+ private List<GeoviewModel> getCountries() {
+ if (!hasCountries()) {
+ return null;
+ }
+ return mCountries.getCountries();
+ }
+
+ @Override
+ protected boolean isViewAllOptionAvailable() {
+ return (hasCountries()
+ && mCountries.getCountries().size() > MAX_NUM_OF_ITEMS_DISPLAYED_IN_LIST);
+ }
+
+ @Override
+ protected boolean isExpandableList() {
+ return false;
+ }
+
+ private class GeoviewsAdapter extends ArrayAdapter<GeoviewModel> {
+
+ private final List<GeoviewModel> list;
+ private final Activity context;
+ private final LayoutInflater inflater;
+
+ public GeoviewsAdapter(Activity context, List<GeoviewModel> list) {
+ super(context, R.layout.stats_list_cell, list);
+ this.context = context;
+ this.list = list;
+ inflater = LayoutInflater.from(context);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View rowView = convertView;
+ // reuse views
+ if (rowView == null) {
+ rowView = inflater.inflate(R.layout.stats_list_cell, parent, false);
+ // configure view holder
+ StatsViewHolder viewHolder = new StatsViewHolder(rowView);
+ rowView.setTag(viewHolder);
+ }
+
+ final GeoviewModel currentRowData = list.get(position);
+ StatsViewHolder holder = (StatsViewHolder) rowView.getTag();
+ // fill data
+ String entry = currentRowData.getCountryFullName();
+ String imageUrl = currentRowData.getFlatFlagIconURL();
+ int total = currentRowData.getViews();
+
+ holder.setEntryText(entry);
+ holder.totalsTextView.setText(FormatUtils.formatDecimal(total));
+
+ // image (country flag)
+ holder.networkImageView.setImageUrl(
+ GravatarUtils.fixGravatarUrl(imageUrl, mResourceVars.headerAvatarSizePx),
+ WPNetworkImageView.ImageType.BLAVATAR);
+ holder.networkImageView.setVisibility(View.VISIBLE);
+
+ return rowView;
+ }
+ }
+
+ @Override
+ protected int getEntryLabelResId() {
+ return R.string.stats_entry_country;
+ }
+
+ @Override
+ protected int getTotalsLabelResId() {
+ return R.string.stats_totals_views;
+ }
+
+ @Override
+ protected int getEmptyLabelTitleResId() {
+ return R.string.stats_empty_geoviews;
+ }
+
+ @Override
+ protected int getEmptyLabelDescResId() {
+ return R.string.stats_empty_geoviews_desc;
+ }
+
+ @Override
+ protected StatsService.StatsEndpointsEnum[] sectionsToUpdate() {
+ return new StatsService.StatsEndpointsEnum[]{
+ StatsService.StatsEndpointsEnum.GEO_VIEWS
+ };
+ }
+
+ @Override
+ public String getTitle() {
+ return getString(R.string.stats_view_countries);
+ }
+}