AB test the social reminders

pull/14/head
Sam Bosley 13 years ago
parent 80ec3cbe17
commit 9a0a1ab6c9

@ -121,6 +121,11 @@ public final class Task extends RemoteModel {
public static final LongProperty REMINDER_LAST = new LongProperty( public static final LongProperty REMINDER_LAST = new LongProperty(
TABLE, "lastNotified"); TABLE, "lastNotified");
/** What kind of reminder the last reminder was: private task,
* social with no faces, social with faces */
public static final StringProperty SOCIAL_REMINDER = new StringProperty(
TABLE, "socialReminder");
/** Unixtime snooze is set (0 -> no snooze) */ /** Unixtime snooze is set (0 -> no snooze) */
public static final LongProperty REMINDER_SNOOZE = new LongProperty( public static final LongProperty REMINDER_SNOOZE = new LongProperty(
TABLE, "snoozeTime"); TABLE, "snoozeTime");
@ -208,6 +213,13 @@ public final class Task extends RemoteModel {
public static final int IMPORTANCE_SHOULD_DO = 2; public static final int IMPORTANCE_SHOULD_DO = 2;
public static final int IMPORTANCE_NONE = 3; public static final int IMPORTANCE_NONE = 3;
// --- social reminder types
public static final String REMINDER_SOCIAL_UNSEEN = "unseen";
public static final String REMINDER_SOCIAL_PRIVATE = "private";
public static final String REMINDER_SOCIAL_NO_FACES = "no_faces";
public static final String REMINDER_SOCIAL_FACES = "faces";
/** /**
* @return colors that correspond to importance values * @return colors that correspond to importance values
*/ */
@ -244,6 +256,7 @@ public final class Task extends RemoteModel {
defaultValues.put(REMINDER_PERIOD.name, 0); defaultValues.put(REMINDER_PERIOD.name, 0);
defaultValues.put(REMINDER_FLAGS.name, 0); defaultValues.put(REMINDER_FLAGS.name, 0);
defaultValues.put(REMINDER_LAST.name, 0); defaultValues.put(REMINDER_LAST.name, 0);
defaultValues.put(SOCIAL_REMINDER.name, REMINDER_SOCIAL_UNSEEN);
defaultValues.put(REMINDER_SNOOZE.name, 0); defaultValues.put(REMINDER_SNOOZE.name, 0);
defaultValues.put(ESTIMATED_SECONDS.name, 0); defaultValues.put(ESTIMATED_SECONDS.name, 0);
defaultValues.put(ELAPSED_SECONDS.name, 0); defaultValues.put(ELAPSED_SECONDS.name, 0);

@ -186,6 +186,7 @@ public class Notifications extends BroadcastReceiver {
// update last reminder time // update last reminder time
task.setValue(Task.REMINDER_LAST, DateUtilities.now()); task.setValue(Task.REMINDER_LAST, DateUtilities.now());
task.setValue(Task.SOCIAL_REMINDER, Task.REMINDER_SOCIAL_UNSEEN);
taskDao.saveExisting(task); taskDao.saveExisting(task);
Context context = ContextManager.getContext(); Context context = ContextManager.getContext();

@ -7,6 +7,7 @@ package com.todoroo.astrid.reminders;
import java.util.Date; import java.util.Date;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.concurrent.atomic.AtomicBoolean;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
@ -114,9 +115,8 @@ public class ReminderDialog extends Dialog {
findViewById(R.id.reminder_complete).setOnClickListener(new View.OnClickListener() { findViewById(R.id.reminder_complete).setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View arg0) { public void onClick(View arg0) {
Task task = new Task(); Task task = taskService.fetchById(taskId, Task.ID, Task.REMINDER_LAST, Task.SOCIAL_REMINDER);
task.setId(taskId); taskService.setComplete(task, true);
PluginServices.getTaskService().setComplete(task, true);
activity.sendBroadcast(new Intent(AstridApiConstants.BROADCAST_EVENT_REFRESH)); activity.sendBroadcast(new Intent(AstridApiConstants.BROADCAST_EVENT_REFRESH));
Toast.makeText(activity, Toast.makeText(activity,
R.string.rmd_NoA_completed_toast, R.string.rmd_NoA_completed_toast,
@ -147,19 +147,22 @@ public class ReminderDialog extends Dialog {
private void setupSpeechBubble(Activity activity, long taskId) { private void setupSpeechBubble(Activity activity, long taskId) {
((TextView) findViewById(R.id.reminder_message)).setText( ((TextView) findViewById(R.id.reminder_message)).setText(
Notifications.getRandomReminder(activity.getResources().getStringArray(R.array.reminder_responses))); Notifications.getRandomReminder(activity.getResources().getStringArray(R.array.reminder_responses)));
if (true)
addFacesToReminder(activity, taskId); Task task = taskService.fetchById(taskId, Task.ID, Task.SHARED_WITH);
addFacesToReminder(activity, task);
} }
private void addFacesToReminder(Activity activity, long taskId) { private void addFacesToReminder(Activity activity, Task task) {
LinkedHashSet<String> pictureUrls = new LinkedHashSet<String>(); LinkedHashSet<String> pictureUrls = new LinkedHashSet<String>();
addSharedWithFaces(taskId, pictureUrls); AtomicBoolean isSharedTask = new AtomicBoolean(false);
addSharedWithFaces(task, pictureUrls, isSharedTask);
if (pictureUrls.size() < MAX_FACES) { if (pictureUrls.size() < MAX_FACES) {
addTagFaces(taskId, pictureUrls); addTagFaces(task.getId(), pictureUrls, isSharedTask);
} }
if (pictureUrls.size() > 0) { if (pictureUrls.size() > 0 && Preferences.getBoolean(R.string.p_social_reminders, false)) {
DisplayMetrics metrics = activity.getResources().getDisplayMetrics(); DisplayMetrics metrics = activity.getResources().getDisplayMetrics();
LinearLayout layout = new LinearLayout(activity); LinearLayout layout = new LinearLayout(activity);
LinearLayout.LayoutParams containerParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); LinearLayout.LayoutParams containerParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
@ -188,15 +191,23 @@ public class ReminderDialog extends Dialog {
((TextView) findViewById(R.id.reminder_message)).setText( ((TextView) findViewById(R.id.reminder_message)).setText(
Notifications.getRandomReminder(activity.getResources().getStringArray(R.array.reminders_social))); Notifications.getRandomReminder(activity.getResources().getStringArray(R.array.reminders_social)));
task.setValue(Task.SOCIAL_REMINDER, Task.REMINDER_SOCIAL_FACES);
} else {
if (isSharedTask.get())
task.setValue(Task.SOCIAL_REMINDER, Task.REMINDER_SOCIAL_NO_FACES);
else
task.setValue(Task.SOCIAL_REMINDER, Task.REMINDER_SOCIAL_PRIVATE);
} }
} }
private void addPicturesFromJSONArray(JSONArray array, LinkedHashSet<String> pictureUrls) throws JSONException { private void addPicturesFromJSONArray(JSONArray array, LinkedHashSet<String> pictureUrls, AtomicBoolean isSharedTask) throws JSONException {
for (int i = 0; i < array.length(); i++) { for (int i = 0; i < array.length(); i++) {
JSONObject person = array.getJSONObject(i); JSONObject person = array.getJSONObject(i);
if (person.has("picture")) { //$NON-NLS-1$ if (person.has("picture")) { //$NON-NLS-1$
if (person.optLong("id") == ActFmPreferenceService.userId()) //$NON-NLS-1$ if (person.optLong("id") == ActFmPreferenceService.userId()) //$NON-NLS-1$
continue; continue;
isSharedTask.set(true);
String pictureUrl = person.getString("picture"); //$NON-NLS-1$ String pictureUrl = person.getString("picture"); //$NON-NLS-1$
if (!TextUtils.isEmpty(pictureUrl)) { if (!TextUtils.isEmpty(pictureUrl)) {
pictureUrls.add(pictureUrl); pictureUrls.add(pictureUrl);
@ -205,20 +216,19 @@ public class ReminderDialog extends Dialog {
} }
} }
private void addSharedWithFaces(long taskId, LinkedHashSet<String> pictureUrls) { private void addSharedWithFaces(Task t, LinkedHashSet<String> pictureUrls, AtomicBoolean isSharedTask) {
Task t = taskService.fetchById(taskId, Task.SHARED_WITH);
try { try {
JSONObject sharedWith = new JSONObject(t.getValue(Task.SHARED_WITH)); JSONObject sharedWith = new JSONObject(t.getValue(Task.SHARED_WITH));
if (sharedWith.has("p")) { //$NON-NLS-1$ if (sharedWith.has("p")) { //$NON-NLS-1$
JSONArray people = sharedWith.getJSONArray("p"); //$NON-NLS-1$ JSONArray people = sharedWith.getJSONArray("p"); //$NON-NLS-1$
addPicturesFromJSONArray(people, pictureUrls); addPicturesFromJSONArray(people, pictureUrls, isSharedTask);
} }
} catch (JSONException e) { } catch (JSONException e) {
// //
} }
} }
private void addTagFaces(long taskId, LinkedHashSet<String> pictureUrls) { private void addTagFaces(long taskId, LinkedHashSet<String> pictureUrls, AtomicBoolean isSharedTask) {
TodorooCursor<TagData> tags = tagService.getTagDataForTask(taskId, TagData.MEMBER_COUNT.gt(0), TagData.MEMBERS); TodorooCursor<TagData> tags = tagService.getTagDataForTask(taskId, TagData.MEMBER_COUNT.gt(0), TagData.MEMBERS);
try { try {
TagData td = new TagData(); TagData td = new TagData();
@ -226,7 +236,7 @@ public class ReminderDialog extends Dialog {
td.readFromCursor(tags); td.readFromCursor(tags);
try { try {
JSONArray people = new JSONArray(td.getValue(TagData.MEMBERS)); JSONArray people = new JSONArray(td.getValue(TagData.MEMBERS));
addPicturesFromJSONArray(people, pictureUrls); addPicturesFromJSONArray(people, pictureUrls, isSharedTask);
} catch (JSONException e) { } catch (JSONException e) {
// //
} }

@ -67,6 +67,9 @@
<!-- show featured lists --> <!-- show featured lists -->
<string name="p_show_featured_lists">show_featured_lists_labs</string> <string name="p_show_featured_lists">show_featured_lists_labs</string>
<!-- social reminders (show faces) -->
<string name="p_social_reminders">social_reminders</string>
<!-- account status section key --> <!-- account status section key -->
<string name="p_account">account</string> <string name="p_account">account</string>

@ -88,8 +88,6 @@ import com.todoroo.astrid.helper.AsyncImageView;
import com.todoroo.astrid.helper.TaskAdapterAddOnManager; import com.todoroo.astrid.helper.TaskAdapterAddOnManager;
import com.todoroo.astrid.notes.NotesAction; import com.todoroo.astrid.notes.NotesAction;
import com.todoroo.astrid.notes.NotesDecorationExposer; import com.todoroo.astrid.notes.NotesDecorationExposer;
import com.todoroo.astrid.service.StatisticsConstants;
import com.todoroo.astrid.service.StatisticsService;
import com.todoroo.astrid.service.TaskService; import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.service.ThemeService; import com.todoroo.astrid.service.ThemeService;
import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.tags.TagService;
@ -139,6 +137,8 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
Task.NOTES, Task.NOTES,
Task.USER_ID, Task.USER_ID,
Task.USER, Task.USER,
Task.REMINDER_LAST,
Task.SOCIAL_REMINDER,
TASK_RABBIT_ID, // Task rabbit metadata id (non-zero means it exists) TASK_RABBIT_ID, // Task rabbit metadata id (non-zero means it exists)
TAGS // Concatenated list of tags TAGS // Concatenated list of tags
}; };
@ -1212,9 +1212,6 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
completedItems.put(task.getId(), newState); completedItems.put(task.getId(), newState);
taskService.setComplete(task, newState); taskService.setComplete(task, newState);
if(newState)
StatisticsService.reportEvent(StatisticsConstants.TASK_COMPLETED_V2);
} }
} }

@ -40,7 +40,7 @@ public class Database extends AbstractDatabase {
* Database version number. This variable must be updated when database * Database version number. This variable must be updated when database
* tables are updated, as it determines whether a database needs updating. * tables are updated, as it determines whether a database needs updating.
*/ */
public static final int VERSION = 27; public static final int VERSION = 28;
/** /**
* Database name (must be unique) * Database name (must be unique)
@ -345,6 +345,12 @@ public class Database extends AbstractDatabase {
} catch (SQLiteException e) { } catch (SQLiteException e) {
Log.e("astrid", "db-upgrade-" + oldVersion + "-" + newVersion, e); Log.e("astrid", "db-upgrade-" + oldVersion + "-" + newVersion, e);
} }
case 27: try {
database.execSQL("ALTER TABLE " + Task.TABLE.name + " ADD " +
Task.SOCIAL_REMINDER.accept(visitor, null));
} catch (SQLiteException e) {
Log.e("astrid", "db-upgrade-" + oldVersion + "-" + newVersion, e);
}
return true; return true;
} }

@ -12,6 +12,8 @@ public class StatisticsConstants {
public static final String ACTFM_TASK_COMMENT = "actfm-task-comment"; public static final String ACTFM_TASK_COMMENT = "actfm-task-comment";
public static final String ACTFM_NEW_USER = "actfm-new-user"; public static final String ACTFM_NEW_USER = "actfm-new-user";
public static final String TASK_COMPLETED_V2 = "task-completed-v2"; public static final String TASK_COMPLETED_V2 = "task-completed-v2";
public static final String TASK_COMPLETED_ONE_DAY = "task-completed-one-day";
public static final String TASK_COMPLETED_ONE_WEEK = "task-completed-one-week";
public static final String USER_FIRST_TASK = "user-first-task"; public static final String USER_FIRST_TASK = "user-first-task";
public static final String USER_FIRST_LIST = "user-first-list"; public static final String USER_FIRST_LIST = "user-first-list";
public static final String LOST_TASKS_RESTORED = "lost-tasks-restored"; public static final String LOST_TASKS_RESTORED = "lost-tasks-restored";

@ -121,10 +121,27 @@ public class TaskService {
* @param item * @param item
*/ */
public void setComplete(Task item, boolean completed) { public void setComplete(Task item, boolean completed) {
if(completed) if(completed) {
item.setValue(Task.COMPLETION_DATE, DateUtilities.now()); item.setValue(Task.COMPLETION_DATE, DateUtilities.now());
else
long reminderLast = item.getValue(Task.REMINDER_LAST);
String socialReminder = item.getValue(Task.SOCIAL_REMINDER);
if (reminderLast > 0) {
long diff = DateUtilities.now() - reminderLast;
if (diff > 0 && diff < DateUtilities.ONE_DAY) {
// within one day of last reminder
StatisticsService.reportEvent(StatisticsConstants.TASK_COMPLETED_ONE_DAY, "social", socialReminder); //$NON-NLS-1$
}
if (diff > 0 && diff < DateUtilities.ONE_WEEK) {
// within one week of last reminder
StatisticsService.reportEvent(StatisticsConstants.TASK_COMPLETED_ONE_WEEK, "social", socialReminder); //$NON-NLS-1$
}
}
StatisticsService.reportEvent(StatisticsConstants.TASK_COMPLETED_V2);
} else {
item.setValue(Task.COMPLETION_DATE, 0L); item.setValue(Task.COMPLETION_DATE, 0L);
}
taskDao.save(item); taskDao.save(item);
} }

@ -125,6 +125,8 @@ public class ABTests {
public static final String AB_FEATURED_LISTS = "android_featured_lists"; //$NON-NLS-1$ public static final String AB_FEATURED_LISTS = "android_featured_lists"; //$NON-NLS-1$
public static final String AB_SOCIAL_REMINDERS = "android_social_reminders"; //$NON-NLS-1$
private void initialize() { private void initialize() {
addTest(AB_FEATURED_LISTS, new int[] { 1, 1 }, addTest(AB_FEATURED_LISTS, new int[] { 1, 1 },
@ -135,5 +137,8 @@ public class ABTests {
addTest(AB_CALENDAR_REMINDERS, new int[] { 3, 1 }, addTest(AB_CALENDAR_REMINDERS, new int[] { 3, 1 },
new int[] { 3, 1 }, new String[] { "no-cal-reminders", "show-cal-reminders" }); //$NON-NLS-1$ //$NON-NLS-2$ new int[] { 3, 1 }, new String[] { "no-cal-reminders", "show-cal-reminders" }); //$NON-NLS-1$ //$NON-NLS-2$
addTest(AB_SOCIAL_REMINDERS, new int[] { 1, 1 },
new int[] { 1, 1 }, new String[] { "no-faces", "show-faces" }); //$NON-NLS-1$ //$NON-NLS-2$
} }
} }

@ -81,6 +81,9 @@ public class AstridPreferences {
Preferences.setIfUnset(prefs, editor, r, R.string.p_calendar_reminders, Preferences.setIfUnset(prefs, editor, r, R.string.p_calendar_reminders,
ABChooser.readChoiceForTest(ABTests.AB_CALENDAR_REMINDERS) != 0); ABChooser.readChoiceForTest(ABTests.AB_CALENDAR_REMINDERS) != 0);
Preferences.setIfUnset(prefs, editor, r, R.string.p_social_reminders,
ABChooser.readChoiceForTest(ABTests.AB_SOCIAL_REMINDERS) != 0);
if ("white-blue".equals(Preferences.getStringValue(R.string.p_theme))) { //$NON-NLS-1$ migrate from when white-blue wasn't the default if ("white-blue".equals(Preferences.getStringValue(R.string.p_theme))) { //$NON-NLS-1$ migrate from when white-blue wasn't the default
Preferences.setString(R.string.p_theme, ThemeService.THEME_WHITE); Preferences.setString(R.string.p_theme, ThemeService.THEME_WHITE);
} }

Loading…
Cancel
Save