aboutsummaryrefslogtreecommitdiff
path: root/WordPress/src/main/java
diff options
context:
space:
mode:
authorNick Bradbury <nbradbury@users.noreply.github.com>2016-09-11 22:03:10 -0400
committerDan Roundhill <dan@automattic.com>2016-09-11 19:03:10 -0700
commit6bb1957779ff42042ff9384b4c68f9de264d9ca1 (patch)
tree63ba42460573cbbd98ba3fc2416b4bc98673a339 /WordPress/src/main/java
parent2c5b50ef248202cc0135160a761b02cdfb3c2621 (diff)
downloadgradle-perf-android-medium-6bb1957779ff42042ff9384b4c68f9de264d9ca1.tar.gz
Issue/4462 reader traintracks (#4540)
* Added TRAIN_TRACKS_RENDER and TRAIN_TRACKS_INTERACT to AnalyticsTracker * Added AnalyticsRailcar model * Added TRAIN_TRACKS_RENDER and TRAIN_TRACKS_INTERACT to nosara tracker * Added TRAIN_TRACKS_RENDER and TRAIN_TRACKS_INTERACT to mixpanel tracker * Moved model, added trackWithRailcar * Changed AnalyticsRailcar to never return null for String getters * Added railcarJson to ReaderPost model * Added railcar_json to post table * Include railcar if it exists when tracking reader post details * Removed AnalyticsRailcar model * Only track railcar for interact/render events * Track TRAIN_TRACKS_RENDER when a post with a railcar is rendered * Added trackRailcarInteract(), required changing AnalyticsTrackerNosara to return event name * Call trackRailcarInteract when tracking reader post event * Use trackWithReaderPostDetails when tracking a post being liked/unliked * Use trackWithReaderPostDetails when tracking a search result being tapped * Removed unused canTrackRailcarInteract from trackWithBlogDetails * Use HashSet to store rendered post IDs * Renamed "Interact" to "Interaction"
Diffstat (limited to 'WordPress/src/main/java')
-rw-r--r--WordPress/src/main/java/org/wordpress/android/datasets/ReaderDatabase.java3
-rw-r--r--WordPress/src/main/java/org/wordpress/android/datasets/ReaderPostTable.java12
-rw-r--r--WordPress/src/main/java/org/wordpress/android/models/ReaderPost.java20
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostDetailFragment.java4
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java2
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderPostAdapter.java18
-rw-r--r--WordPress/src/main/java/org/wordpress/android/util/AnalyticsUtils.java81
7 files changed, 128 insertions, 12 deletions
diff --git a/WordPress/src/main/java/org/wordpress/android/datasets/ReaderDatabase.java b/WordPress/src/main/java/org/wordpress/android/datasets/ReaderDatabase.java
index ef9504c37..9ae4f5521 100644
--- a/WordPress/src/main/java/org/wordpress/android/datasets/ReaderDatabase.java
+++ b/WordPress/src/main/java/org/wordpress/android/datasets/ReaderDatabase.java
@@ -19,7 +19,7 @@ import java.io.OutputStream;
*/
public class ReaderDatabase extends SQLiteOpenHelper {
protected static final String DB_NAME = "wpreader.db";
- private static final int DB_VERSION = 124;
+ private static final int DB_VERSION = 125;
/*
* version history
@@ -76,6 +76,7 @@ public class ReaderDatabase extends SQLiteOpenHelper {
* 122 - changed tbl_posts primary key to pseudo_id
* 123 - changed tbl_posts.published to tbl_posts.date
* 124 - returned tbl_posts.published
+ * 125 - added tbl_posts.railcar_json
*/
/*
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 1cd234f53..af9b06891 100644
--- a/WordPress/src/main/java/org/wordpress/android/datasets/ReaderPostTable.java
+++ b/WordPress/src/main/java/org/wordpress/android/datasets/ReaderPostTable.java
@@ -63,7 +63,8 @@ public class ReaderPostTable {
+ "attachments_json," // 34
+ "discover_json," // 35
+ "xpost_post_id," // 36
- + "xpost_blog_id"; // 37
+ + "xpost_blog_id," // 37
+ + "railcar_json"; // 38
// used when querying multiple rows and skipping tbl_posts.text
private static final String COLUMN_NAMES_NO_TEXT =
@@ -102,7 +103,8 @@ public class ReaderPostTable {
+ "tbl_posts.attachments_json," // 33
+ "tbl_posts.discover_json," // 34
+ "tbl_posts.xpost_post_id," // 35
- + "tbl_posts.xpost_blog_id"; // 36
+ + "tbl_posts.xpost_blog_id," // 36
+ + "tbl_posts.railcar_json"; // 37
protected static void createTables(SQLiteDatabase db) {
db.execSQL("CREATE TABLE tbl_posts ("
@@ -143,6 +145,7 @@ public class ReaderPostTable {
+ " discover_json TEXT,"
+ " xpost_post_id INTEGER DEFAULT 0,"
+ " xpost_blog_id INTEGER DEFAULT 0,"
+ + " railcar_json TEXT,"
+ " PRIMARY KEY (pseudo_id)"
+ ")");
@@ -642,7 +645,7 @@ public class ReaderPostTable {
SQLiteStatement stmtPosts = db.compileStatement(
"INSERT OR REPLACE INTO tbl_posts ("
+ COLUMN_NAMES
- + ") VALUES (?1,?2,?3,?4,?5,?6,?7,?8,?9,?10,?11,?12,?13,?14,?15,?16,?17,?18,?19,?20,?21,?22,?23,?24,?25,?26,?27,?28,?29,?30,?31,?32,?33,?34,?35,?36,?37)");
+ + ") VALUES (?1,?2,?3,?4,?5,?6,?7,?8,?9,?10,?11,?12,?13,?14,?15,?16,?17,?18,?19,?20,?21,?22,?23,?24,?25,?26,?27,?28,?29,?30,?31,?32,?33,?34,?35,?36,?37,?38)");
SQLiteStatement stmtTags = db.compileStatement(
"INSERT OR REPLACE INTO tbl_post_tags (post_id, blog_id, feed_id, pseudo_id, tag_name, tag_type) VALUES (?1,?2,?3,?4,?5,?6)");
@@ -687,6 +690,7 @@ public class ReaderPostTable {
stmtPosts.bindString(35, post.getDiscoverJson());
stmtPosts.bindLong (36, post.xpostPostId);
stmtPosts.bindLong (37, post.xpostBlogId);
+ stmtPosts.bindString(38, post.getRailcarJson());
stmtPosts.execute();
}
@@ -907,6 +911,8 @@ public class ReaderPostTable {
post.xpostPostId = c.getLong(c.getColumnIndex("xpost_post_id"));
post.xpostBlogId = c.getLong(c.getColumnIndex("xpost_blog_id"));
+ post.setRailcarJson(c.getString(c.getColumnIndex("railcar_json")));
+
return post;
}
diff --git a/WordPress/src/main/java/org/wordpress/android/models/ReaderPost.java b/WordPress/src/main/java/org/wordpress/android/models/ReaderPost.java
index a0b95e7e6..8ce09db51 100644
--- a/WordPress/src/main/java/org/wordpress/android/models/ReaderPost.java
+++ b/WordPress/src/main/java/org/wordpress/android/models/ReaderPost.java
@@ -10,7 +10,6 @@ import org.wordpress.android.ui.reader.models.ReaderBlogIdPostId;
import org.wordpress.android.ui.reader.utils.ImageSizeMap;
import org.wordpress.android.ui.reader.utils.ReaderImageScanner;
import org.wordpress.android.ui.reader.utils.ReaderUtils;
-import org.wordpress.android.util.AppLog;
import org.wordpress.android.util.DateTimeUtils;
import org.wordpress.android.util.GravatarUtils;
import org.wordpress.android.util.HtmlUtils;
@@ -75,6 +74,8 @@ public class ReaderPost {
public long xpostPostId;
public long xpostBlogId;
+ private String railcarJson;
+
public static ReaderPost fromJson(JSONObject json) {
if (json == null) {
throw new IllegalArgumentException("null json post");
@@ -209,6 +210,12 @@ public class ReaderPost {
.getLargestImage(ReaderConstants.MIN_FEATURED_IMAGE_WIDTH);
}
+ // "railcar" data - currently used in search streams, used by TrainTracks
+ JSONObject jsonRailcar = json.optJSONObject("railcar");
+ if (jsonRailcar != null) {
+ post.setRailcarJson(jsonRailcar.toString());
+ }
+
return post;
}
@@ -604,6 +611,17 @@ public class ReaderPost {
return (isWP() || isJetpack) && (!isDiscoverPost());
}
+
+ public String getRailcarJson() {
+ return StringUtils.notNullStr(railcarJson);
+ }
+ public void setRailcarJson(String jsonRailcar) {
+ this.railcarJson = StringUtils.notNullStr(jsonRailcar);
+ }
+ public boolean hasRailcar() {
+ return !TextUtils.isEmpty(railcarJson);
+ }
+
/****
* the following are transient variables - not stored in the db or returned in the json - whose
* sole purpose is to cache commonly-used values for the post that speeds up using them inside
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostDetailFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostDetailFragment.java
index 2ecfec4bd..f88c9baaf 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostDetailFragment.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostDetailFragment.java
@@ -353,9 +353,9 @@ public class ReaderPostDetailFragment extends Fragment
refreshIconCounts();
if (isAskingToLike) {
- AnalyticsUtils.trackWithBlogDetails(AnalyticsTracker.Stat.READER_ARTICLE_LIKED, mBlogId);
+ AnalyticsUtils.trackWithReaderPostDetails(AnalyticsTracker.Stat.READER_ARTICLE_LIKED, mPost);
} else {
- AnalyticsUtils.trackWithBlogDetails(AnalyticsTracker.Stat.READER_ARTICLE_UNLIKED, mBlogId);
+ AnalyticsUtils.trackWithReaderPostDetails(AnalyticsTracker.Stat.READER_ARTICLE_UNLIKED, mPost);
}
}
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 f245cd9ec..69409385e 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
@@ -1444,7 +1444,7 @@ public class ReaderPostListFragment extends Fragment
post.postId);
break;
case SEARCH_RESULTS:
- AnalyticsTracker.track(AnalyticsTracker.Stat.READER_SEARCH_RESULT_TAPPED);
+ AnalyticsUtils.trackWithReaderPostDetails(AnalyticsTracker.Stat.READER_SEARCH_RESULT_TAPPED, post);
ReaderActivityLauncher.showReaderPostDetail(getActivity(), post.blogId, post.postId);
break;
}
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 f2d10a421..090f79fe3 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
@@ -46,6 +46,8 @@ import org.wordpress.android.util.ToastUtils;
import org.wordpress.android.util.UrlUtils;
import org.wordpress.android.widgets.WPNetworkImageView;
+import java.util.HashSet;
+
public class ReaderPostAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ReaderTag mCurrentTag;
private long mCurrentBlogId;
@@ -64,6 +66,7 @@ public class ReaderPostAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
private final ReaderTypes.ReaderPostListType mPostListType;
private final ReaderPostList mPosts = new ReaderPostList();
+ private final HashSet<String> mRenderedIds = new HashSet<>();
private ReaderInterfaces.OnPostSelectedListener mPostSelectedListener;
private ReaderInterfaces.OnTagSelectedListener mOnTagSelectedListener;
@@ -456,6 +459,13 @@ public class ReaderPostAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
});
checkLoadMore(position);
+
+ // if we haven't already rendered this post and it has a "railcar" attached to it, add it
+ // to the rendered list and record the TrainTracks render event
+ if (post.hasRailcar() && !mRenderedIds.contains(post.getPseudoId())) {
+ mRenderedIds.add(post.getPseudoId());
+ AnalyticsUtils.trackRailcarRender(post.getRailcarJson());
+ }
}
/*
@@ -604,6 +614,7 @@ public class ReaderPostAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
public void setCurrentTag(ReaderTag tag) {
if (!ReaderTag.isSameTag(tag, mCurrentTag)) {
mCurrentTag = tag;
+ mRenderedIds.clear();
reload();
}
}
@@ -617,6 +628,7 @@ public class ReaderPostAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
if (blogId != mCurrentBlogId || feedId != mCurrentFeedId) {
mCurrentBlogId = blogId;
mCurrentFeedId = feedId;
+ mRenderedIds.clear();
reload();
}
}
@@ -758,7 +770,7 @@ public class ReaderPostAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
/*
* triggered when user taps the like button (textView)
*/
- private void toggleLike(Context context, ReaderPostViewHolder holder,ReaderPost post) {
+ private void toggleLike(Context context, ReaderPostViewHolder holder, ReaderPost post) {
if (post == null || !NetworkUtils.checkConnection(context)) {
return;
}
@@ -773,12 +785,12 @@ public class ReaderPostAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
}
if (isAskingToLike) {
- AnalyticsUtils.trackWithBlogDetails(AnalyticsTracker.Stat.READER_ARTICLE_LIKED, mCurrentBlogId != 0 ? mCurrentBlogId : null);
+ AnalyticsUtils.trackWithReaderPostDetails(AnalyticsTracker.Stat.READER_ARTICLE_LIKED, post);
// Consider a like to be enough to push a page view - solves a long-standing question
// from folks who ask 'why do I have more likes than page views?'.
ReaderPostActions.bumpPageViewForPost(post);
} else {
- AnalyticsUtils.trackWithBlogDetails(AnalyticsTracker.Stat.READER_ARTICLE_LIKED, mCurrentBlogId != 0 ? mCurrentBlogId : null);
+ AnalyticsUtils.trackWithReaderPostDetails(AnalyticsTracker.Stat.READER_ARTICLE_LIKED, post);
}
// update post in array and on screen
diff --git a/WordPress/src/main/java/org/wordpress/android/util/AnalyticsUtils.java b/WordPress/src/main/java/org/wordpress/android/util/AnalyticsUtils.java
index 9348cdc47..c8dd0867a 100644
--- a/WordPress/src/main/java/org/wordpress/android/util/AnalyticsUtils.java
+++ b/WordPress/src/main/java/org/wordpress/android/util/AnalyticsUtils.java
@@ -2,19 +2,32 @@ package org.wordpress.android.util;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
+import android.support.annotation.NonNull;
import android.text.Html;
+import android.text.TextUtils;
+import org.json.JSONException;
+import org.json.JSONObject;
import org.wordpress.android.WordPress;
+import org.wordpress.android.analytics.AnalyticsMetadata;
import org.wordpress.android.analytics.AnalyticsTracker;
import org.wordpress.android.analytics.AnalyticsTrackerMixpanel;
-import org.wordpress.android.analytics.AnalyticsMetadata;
+import org.wordpress.android.analytics.AnalyticsTrackerNosara;
import org.wordpress.android.models.AccountHelper;
import org.wordpress.android.models.Blog;
import org.wordpress.android.models.ReaderPost;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
+import static org.wordpress.android.analytics.AnalyticsTracker.Stat.READER_ARTICLE_COMMENTED_ON;
+import static org.wordpress.android.analytics.AnalyticsTracker.Stat.READER_ARTICLE_LIKED;
+import static org.wordpress.android.analytics.AnalyticsTracker.Stat.READER_ARTICLE_OPENED;
+import static org.wordpress.android.analytics.AnalyticsTracker.Stat.READER_SEARCH_RESULT_TAPPED;
+import static org.wordpress.android.analytics.AnalyticsTracker.Stat.TRAIN_TRACKS_INTERACT;
+import static org.wordpress.android.analytics.AnalyticsTracker.Stat.TRAIN_TRACKS_RENDER;
+
public class AnalyticsUtils {
private static String BLOG_ID_KEY = "blog_id";
private static String POST_ID_KEY = "post_id";
@@ -186,6 +199,72 @@ public class AnalyticsUtils {
properties.put(FEED_ID_KEY, post.feedId);
properties.put(FEED_ITEM_ID_KEY, post.feedItemId);
properties.put(IS_JETPACK_KEY, post.isJetpack);
+
AnalyticsTracker.track(stat, properties);
+
+ // record a railcar interact event if the post has a railcar and this can be tracked
+ // as an interaction
+ if (canTrackRailcarInteraction(stat) && post.hasRailcar()) {
+ trackRailcarInteraction(stat, post.getRailcarJson());
+ }
+ }
+
+ /**
+ * Track when a railcar item has been rendered
+ *
+ * @param post The JSON string of the railcar
+ *
+ */
+ public static void trackRailcarRender(String railcarJson) {
+ if (TextUtils.isEmpty(railcarJson)) return;
+
+ AnalyticsTracker.track(TRAIN_TRACKS_RENDER, railcarJsonToProperties(railcarJson));
+ }
+
+ /**
+ * Track when a railcar item has been interacted with
+ *
+ * @param stat The event that caused the interaction
+ * @param post The JSON string of the railcar
+ *
+ */
+ private static void trackRailcarInteraction(AnalyticsTracker.Stat stat, String railcarJson) {
+ if (TextUtils.isEmpty(railcarJson)) return;
+
+ Map<String, Object> properties = railcarJsonToProperties(railcarJson);
+ properties.put("action", AnalyticsTrackerNosara.getEventNameForStat(stat));
+ AnalyticsTracker.track(TRAIN_TRACKS_INTERACT, properties);
+ }
+
+ /**
+ * @param stat The event that would cause the interaction
+ * @return True if the passed stat event can be recorded as a railcar interaction
+ */
+ private static boolean canTrackRailcarInteraction(AnalyticsTracker.Stat stat) {
+ return stat == READER_ARTICLE_LIKED
+ || stat == READER_ARTICLE_OPENED
+ || stat == READER_SEARCH_RESULT_TAPPED
+ || stat == READER_ARTICLE_COMMENTED_ON;
}
+
+ /*
+ * Converts the JSON string of a railcar to a properties list using the existing json key names
+ */
+ private static Map<String, Object> railcarJsonToProperties(@NonNull String railcarJson) {
+ Map<String, Object> properties = new HashMap<>();
+ try {
+ JSONObject jsonRailcar = new JSONObject(railcarJson);
+ Iterator<String> iter = jsonRailcar.keys();
+ while (iter.hasNext()) {
+ String key = iter.next();
+ Object value = jsonRailcar.get(key);
+ properties.put(key, value);
+ }
+ } catch (JSONException e) {
+ AppLog.e(AppLog.T.READER, e);
+ }
+
+ return properties;
+ }
+
}