AB test the social reminders

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

@ -121,6 +121,11 @@ public final class Task extends RemoteModel {
public static final LongProperty REMINDER_LAST = new LongProperty(
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) */
public static final LongProperty REMINDER_SNOOZE = new LongProperty(
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_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
*/
@ -244,6 +256,7 @@ public final class Task extends RemoteModel {
defaultValues.put(REMINDER_PERIOD.name, 0);
defaultValues.put(REMINDER_FLAGS.name, 0);
defaultValues.put(REMINDER_LAST.name, 0);
defaultValues.put(SOCIAL_REMINDER.name, REMINDER_SOCIAL_UNSEEN);
defaultValues.put(REMINDER_SNOOZE.name, 0);
defaultValues.put(ESTIMATED_SECONDS.name, 0);
defaultValues.put(ELAPSED_SECONDS.name, 0);

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

@ -7,6 +7,7 @@ package com.todoroo.astrid.reminders;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.concurrent.atomic.AtomicBoolean;
import org.json.JSONArray;
import org.json.JSONException;
@ -114,9 +115,8 @@ public class ReminderDialog extends Dialog {
findViewById(R.id.reminder_complete).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
Task task = new Task();
task.setId(taskId);
PluginServices.getTaskService().setComplete(task, true);
Task task = taskService.fetchById(taskId, Task.ID, Task.REMINDER_LAST, Task.SOCIAL_REMINDER);
taskService.setComplete(task, true);
activity.sendBroadcast(new Intent(AstridApiConstants.BROADCAST_EVENT_REFRESH));
Toast.makeText(activity,
R.string.rmd_NoA_completed_toast,
@ -147,19 +147,22 @@ public class ReminderDialog extends Dialog {
private void setupSpeechBubble(Activity activity, long taskId) {
((TextView) findViewById(R.id.reminder_message)).setText(
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>();
addSharedWithFaces(taskId, pictureUrls);
AtomicBoolean isSharedTask = new AtomicBoolean(false);
addSharedWithFaces(task, pictureUrls, isSharedTask);
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();
LinearLayout layout = new LinearLayout(activity);
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(
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++) {
JSONObject person = array.getJSONObject(i);
if (person.has("picture")) { //$NON-NLS-1$
if (person.optLong("id") == ActFmPreferenceService.userId()) //$NON-NLS-1$
continue;
isSharedTask.set(true);
String pictureUrl = person.getString("picture"); //$NON-NLS-1$
if (!TextUtils.isEmpty(pictureUrl)) {
pictureUrls.add(pictureUrl);
@ -205,20 +216,19 @@ public class ReminderDialog extends Dialog {
}
}
private void addSharedWithFaces(long taskId, LinkedHashSet<String> pictureUrls) {
Task t = taskService.fetchById(taskId, Task.SHARED_WITH);
private void addSharedWithFaces(Task t, LinkedHashSet<String> pictureUrls, AtomicBoolean isSharedTask) {
try {
JSONObject sharedWith = new JSONObject(t.getValue(Task.SHARED_WITH));
if (sharedWith.has("p")) { //$NON-NLS-1$
JSONArray people = sharedWith.getJSONArray("p"); //$NON-NLS-1$
addPicturesFromJSONArray(people, pictureUrls);
addPicturesFromJSONArray(people, pictureUrls, isSharedTask);
}
} 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);
try {
TagData td = new TagData();
@ -226,7 +236,7 @@ public class ReminderDialog extends Dialog {
td.readFromCursor(tags);
try {
JSONArray people = new JSONArray(td.getValue(TagData.MEMBERS));
addPicturesFromJSONArray(people, pictureUrls);
addPicturesFromJSONArray(people, pictureUrls, isSharedTask);
} catch (JSONException e) {
//
}

@ -67,6 +67,9 @@
<!-- show featured lists -->
<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 -->
<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.notes.NotesAction;
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.ThemeService;
import com.todoroo.astrid.tags.TagService;
@ -139,6 +137,8 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
Task.NOTES,
Task.USER_ID,
Task.USER,
Task.REMINDER_LAST,
Task.SOCIAL_REMINDER,
TASK_RABBIT_ID, // Task rabbit metadata id (non-zero means it exists)
TAGS // Concatenated list of tags
};
@ -1212,9 +1212,6 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
completedItems.put(task.getId(), 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
* 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)
@ -345,6 +345,12 @@ public class Database extends AbstractDatabase {
} catch (SQLiteException 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;
}

@ -12,6 +12,8 @@ public class StatisticsConstants {
public static final String ACTFM_TASK_COMMENT = "actfm-task-comment";
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_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_LIST = "user-first-list";
public static final String LOST_TASKS_RESTORED = "lost-tasks-restored";

@ -121,10 +121,27 @@ public class TaskService {
* @param item
*/
public void setComplete(Task item, boolean completed) {
if(completed)
if(completed) {
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);
}
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_SOCIAL_REMINDERS = "android_social_reminders"; //$NON-NLS-1$
private void initialize() {
addTest(AB_FEATURED_LISTS, new int[] { 1, 1 },
@ -135,5 +137,8 @@ public class ABTests {
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$
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,
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
Preferences.setString(R.string.p_theme, ThemeService.THEME_WHITE);
}

Loading…
Cancel
Save