Deleted all the taskrabbit and ideas tab code

pull/14/head
Sam Bosley 11 years ago
parent ed28d46293
commit d97f5c2a06

@ -112,8 +112,6 @@ public class EditPeopleControlSet extends PopupControlSet {
private boolean assignedToMe = false;
private AssignedToUser taskRabbitUser = null;
private AssignedToUser contactPickerUser = null;
private boolean loadedUI = false;
@ -315,19 +313,6 @@ public class EditPeopleControlSet extends PopupControlSet {
if (addContactPicker)
coreUsers.add(contactsIndex, contactPickerUser);
for (AssignedChangedListener l : listeners) {
if (l.shouldShowTaskRabbit()) {
taskRabbitUser = new AssignedToUser(activity.getString(R.string.actfm_EPA_task_rabbit), new JSONObject().put("default_picture", R.drawable.task_rabbit_image));
int taskRabbitIndex = addUnassigned ? 3 : 2;
if (!addContactPicker)
taskRabbitIndex--;
if(l.didPostToTaskRabbit()){
coreUsers.add(taskRabbitIndex, taskRabbitUser);
assignedIndex = taskRabbitIndex;
}
}
}
if (assignedIndex == 0) {
assignedIndex = findAssignedIndex(t, coreUsers, listUsers, astridUsers);
}
@ -653,7 +638,7 @@ public class EditPeopleControlSet extends PopupControlSet {
return true;
AssignedToUser item = (AssignedToUser) assignedList.getAdapter().getItem(assignedList.getCheckedItemPosition());
if (item != null) {
if (item.equals(taskRabbitUser) || item.equals(contactPickerUser)) { //don't want to ever set the user as the task rabbit user
if (item.equals(contactPickerUser)) { //don't want to ever set the user as the task rabbit user
return true;
}
userJson = item.user;

@ -23,7 +23,6 @@ import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Join;
import com.todoroo.andlib.sql.Order;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.sql.QueryTemplate;
@ -39,13 +38,11 @@ import com.todoroo.astrid.api.FilterListItem;
import com.todoroo.astrid.api.PermaSql;
import com.todoroo.astrid.dao.StoreObjectDao;
import com.todoroo.astrid.dao.TaskDao.TaskCriteria;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.StoreObject;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import com.todoroo.astrid.service.TagDataService;
import com.todoroo.astrid.service.ThemeService;
import com.todoroo.astrid.taskrabbit.TaskRabbitMetadata;
/**
* Exposes Astrid's built in filters to the {@link FilterListFragment}
@ -160,11 +157,9 @@ public final class CustomFilterExposer extends BroadcastReceiver implements Astr
int themeFlags = ThemeService.getFilterThemeFlags();
Filter f = new Filter(r.getString(R.string.BFE_Assigned),
r.getString(R.string.BFE_Assigned),
new QueryTemplate().join(Join.left(Metadata.TABLE, Criterion.and(Metadata.KEY.eq(TaskRabbitMetadata.METADATA_KEY), Task.ID.eq(Metadata.TASK))))
.where(Criterion.and(TaskCriteria.isActive(),
new QueryTemplate().where(Criterion.and(TaskCriteria.isActive(),
Criterion.or(Task.CREATOR_ID.eq(0), Task.CREATOR_ID.eq(ActFmPreferenceService.userId())),
Criterion.or(Task.USER_ID.neq(0),
TaskRabbitMetadata.ID.gt(0)))),
Task.USER_ID.neq(0))),
null);
f.listingIcon = ((BitmapDrawable)r.getDrawable(
ThemeService.getDrawable(R.drawable.filter_assigned, themeFlags))).getBitmap();

@ -1,925 +0,0 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.taskrabbit;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow.OnDismissListener;
import android.widget.TextView;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.MenuItem;
import com.timsu.astrid.R;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.service.ExceptionService;
import com.todoroo.andlib.service.RestClient;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DialogUtilities;
import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.activity.TaskEditFragment;
import com.todoroo.astrid.dao.Database;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.helper.TaskEditControlSet;
import com.todoroo.astrid.reminders.Notifications;
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.taskrabbit.TaskRabbitLocationManager.LocationResult;
import com.todoroo.astrid.ui.ErrorCatchingListView;
import com.todoroo.astrid.ui.FragmentPopover;
import com.todoroo.astrid.welcome.HelpInfoPopover;
public class TaskRabbitActivity extends SherlockFragmentActivity {
public interface TaskRabbitSetListener {
public void readFromModel(JSONObject json, String key, int mode);
public void saveToDatabase(JSONObject json, String key) throws JSONException;
public void postToTaskRabbit(JSONObject json, String key) throws JSONException;
}
public interface ActivityResultSetListener {
public boolean activityResult (int requestCode, int resultCode, Intent data);
}
/** task model */
Task model = null;
@Autowired
private RestClient restClient;
@Autowired
private Database database;
@Autowired
private TaskService taskService;
@Autowired
private ExceptionService exceptionService;
/** true if editing started with a new task */
boolean isNewTask = false;
private EditText taskTitle;
private Button taskButton;
private LinearLayout taskControls;
private LinearLayout descriptionControls;
private Location currentLocation;
private FragmentPopover menuPopover;
private TextView menuTitle;
private ListView menuList;
private ArrayAdapter<String> adapter;
private TaskRabbitLocationManager locationManager;
private int currentSelectedItem = 0;
private View menuNav;
private ImageView menuNavDisclosure;
private boolean didReportStatistics = false;
private final List<TaskRabbitSetListener> controls = Collections.synchronizedList(new ArrayList<TaskRabbitSetListener>());
private LinearLayout row;
public static final int REQUEST_CODE_TASK_RABBIT_OAUTH = 5;
public static final int REQUEST_CODE_ENABLE_GPS = 6;
public static final int MESSAGE_CODE_SUCCESS = 1;
public static final int MESSAGE_CODE_FAILURE = -1;
public static final int MESSAGE_CODE_INTERNET_FAILURE = -2;
public static final int MESSAGE_CODE_LOCATION_FAILURE = -3;
/** Act.fm current user name */
public static final String TASK_RABBIT_TOKEN = "task_rabbit_token"; //$NON-NLS-1$
private static final String TASK_RABBIT_POPOVER_PREF = "task_rabbit_popover"; //$NON-NLS-1$
private static final String TASK_RABBIT_DIALOG_INTRO_PREF = "task_rabbit_popover"; //$NON-NLS-1$
private static final String TASK_RABBIT_PREF_CITY_NAME = "task_rabbit_city_name"; //$NON-NLS-1$
private static final String TASK_RABBIT_PREF_CITY_ID = "task_rabbit_city_id"; //$NON-NLS-1$
private static final String TASK_RABBIT_PREF_CITY_LAT = "task_rabbit_city_lat"; //$NON-NLS-1$
private static final String TASK_RABBIT_PREF_CITY_LNG = "task_rabbit_city_lng"; //$NON-NLS-1$
public static final String CITY_NAME = "name"; //$NON-NLS-1$
public static final String CITY_LAT = "lat"; //$NON-NLS-1$
public static final String CITY_LNG = "lng"; //$NON-NLS-1$
public static final String LOCATION_CONTAINER = "other_locations_attributes"; //$NON-NLS-1$
// Non-production values
public static final String TASK_RABBIT_URL = "http://rs-astrid-api.taskrabbit.com"; //$NON-NLS-1$
public static final String TASK_RABBIT_CLIENT_ID = "fDTmGeR0uNCvoxopNyqsRWae8xOvbOBqC7jmHaxv"; //$NON-NLS-1$
public static final String TASK_RABBIT_CLIENT_APPLICATION_ID = "XBpKshU8utH5eaNmhky9N8aAId5rSLTh04Hi60Co"; //$NON-NLS-1$
public static final String TASK_RABBIT_ID = "id"; //$NON-NLS-1$
private TaskRabbitTaskContainer taskRabbitTask;
private boolean showingNoGPSAlertMessage = false;
public TaskRabbitActivity() {
DependencyInjectionService.getInstance().inject(this);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
setupForDialogOrFullscreen();
super.onCreate(savedInstanceState);
loadLocation();
setContentView(R.layout.task_rabbit_enter);
}
public void showAddListPopover() {
if (!Preferences.getBoolean(TASK_RABBIT_POPOVER_PREF, false)) {
ActionBar actionBar = getSupportActionBar();
HelpInfoPopover.showPopover(this, actionBar.getCustomView().findViewById(R.id.menu_nav), R.string.help_popover_taskrabbit_type, null);
Preferences.setBoolean(TASK_RABBIT_POPOVER_PREF, true);
}
}
public void showIntroDialog() {
if (!Preferences.getBoolean(TASK_RABBIT_DIALOG_INTRO_PREF, false)) {
if (TaskRabbitLocationManager.supportsCurrentLocation(currentLocation)) {
AlertDialog.Builder adb = new AlertDialog.Builder(TaskRabbitActivity.this);
adb.setTitle(R.string.tr_alert_intro_title);
adb.setMessage(getString(R.string.tr_alert_intro_location));
adb.setPositiveButton(getString(R.string.tr_alert_button_close), new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, final int id) {
showAddListPopover();
}
});
adb.show();
}
else {
final AlertDialog adb = new AlertDialog.Builder(TaskRabbitActivity.this)
.setTitle(R.string.tr_alert_intro_title)
.setMessage(R.string.tr_alert_intro_no_location)
.setPositiveButton(getString(R.string.tr_alert_button_close),null)
.show();
((TextView) adb.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
}
Preferences.setBoolean(TASK_RABBIT_DIALOG_INTRO_PREF, true);
}
}
@Override
public void onResume() {
super.onResume();
StatisticsService.sessionStart(this);
if (!didReportStatistics) {
StatisticsService.reportEvent(StatisticsConstants.TASK_RABBIT_VIEW);
didReportStatistics = true;
}
populateFields();
if (!showingNoGPSAlertMessage)
showIntroDialog();
}
@Override
public void onStop() {
super.onStop();
StatisticsService.sessionStop(this);
}
@Override
public void onPause() {
super.onPause();
StatisticsService.sessionPause();
}
@Override
public void onDestroy() {
super.onDestroy();
try {
taskRabbitTask.setLocalTaskData(serializeToJSON().toString());
TaskRabbitDataService.getInstance().saveTaskAndMetadata(taskRabbitTask);
} catch (JSONException e) {
e.printStackTrace();
}
}
protected void populateFields() {
loadItem(getIntent());
taskRabbitTask = TaskRabbitDataService.getInstance().getContainerForTask(model);
setUpUIComponents();
}
/*
* ======================================================================
* =============================================== model reading / saving
* ======================================================================
*/
/**
* Loads action item from the given intent
*
* @param intent
*/
@SuppressWarnings("nls")
protected void loadItem(Intent intent) {
if (model != null) {
// came from bundle
isNewTask = (model.getValue(Task.TITLE).length() == 0);
return;
}
long idParam = intent.getLongExtra(TaskEditFragment.TOKEN_ID, -1L);
database.openForReading();
if (idParam > -1L) {
model = taskService.fetchById(idParam, Task.PROPERTIES);
if (model == null) {
this.onBackPressed();
}
}
// not found by id or was never passed an id
if (model == null) {
String valuesAsString = intent.getStringExtra(TaskEditFragment.TOKEN_VALUES);
ContentValues values = null;
try {
if (valuesAsString != null)
values = AndroidUtilities.contentValuesFromSerializedString(valuesAsString);
} catch (Exception e) {
// oops, can't serialize
}
model = TaskService.createWithValues(values, null);
}
if (model == null) {
exceptionService.reportError("task-edit-no-task",
new NullPointerException("model"));
onBackPressed();
return;
}
// clear notification
Notifications.cancelNotifications(model.getId());
}
private void setupForDialogOrFullscreen() {
ThemeService.applyTheme(this);
}
private void setUpControls() {
TypedArray arrays = getResources().obtainTypedArray(R.array.tr_default_set);
TypedArray arrayType = getResources().obtainTypedArray(R.array.tr_default_array);
for (int i = 0; i < arrays.length(); i++) {
int titleID = arrays.getResourceId(i, 0);
int arrayID = arrayType.getResourceId(i, 0);
if (arrayID == R.string.tr_set_key_location) {
TaskRabbitLocationControlSet set = new TaskRabbitLocationControlSet(this, R.layout.task_rabbit_row, titleID, i);
set.location = currentLocation;
controls.add(set);
}
else if(arrayID == R.string.tr_set_key_deadline) {
TaskRabbitDeadlineControlSet deadlineControl = new TaskRabbitDeadlineControlSet(
this, R.layout.control_set_deadline,
R.layout.task_rabbit_row);
controls.add(deadlineControl);
deadlineControl.readFromTask(model);
}
else if(arrayID == R.string.tr_set_key_name) {
TaskRabbitNameControlSet nameControlSet = new TaskRabbitNameControlSet(this,
R.layout.control_set_notes, R.layout.task_rabbit_row, titleID);
controls.add(nameControlSet);
}
else if(arrayID == R.string.tr_set_key_description) {
TaskRabbitNameControlSet descriptionControlSet = new TaskRabbitNameControlSet(this,
R.layout.control_set_notes, R.layout.task_rabbit_row_description, titleID);
try {
descriptionControlSet.readFromModel(new JSONObject().put(getString(arrayID), model.getValue(Task.NOTES)), getString(arrayID), currentSelectedItem);
} catch (JSONException e) {
e.printStackTrace();
}
controls.add(descriptionControlSet);
}
else {
TaskRabbitSpinnerControlSet set = new TaskRabbitSpinnerControlSet(this, R.layout.task_rabbit_spinner, titleID, i);
controls.add(set);
}
}
if(TextUtils.isEmpty(taskTitle.getText())) {
taskTitle.setText(model.getValue(Task.TITLE));
}
populateFields(taskRabbitTask);
displayViewsForMode(currentSelectedItem);
}
private void displayViewsForMode(int mode) {
taskControls.removeAllViews();
descriptionControls.removeAllViews();
if (row == null) {
row = new LinearLayout(this);
row.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
row.setOrientation(LinearLayout.HORIZONTAL);
}
else {
row.removeAllViews();
}
if (menuTitle != null) {
menuTitle.setText(getResources().getStringArray(R.array.tr_preset_types)[mode]);
}
int[] presetValues = getPresetValues(mode);
TypedArray keys = getResources().obtainTypedArray(R.array.tr_default_set_key);
JSONObject parameters = defaultValuesToJSON(keys, presetValues);
for (int i = 0; i < controls.size(); i++) {
if (presetValues[i] == -1) continue;
TaskRabbitSetListener set = controls.get(i);
int arrayID = keys.getResourceId(i, 0);
if (arrayID == R.string.tr_set_key_cost_in_cents || arrayID == R.string.tr_set_key_named_price) {
if(row.getParent() == null)
taskControls.addView(row);
else {
// View separator = getLayoutInflater().inflate(R.layout.tea_separator, row);
// separator.setLayoutParams(new LayoutParams(1, LayoutParams.FILL_PARENT));
}
LinearLayout displayRow = (LinearLayout)((TaskEditControlSet)set).getDisplayView();
LinearLayout.LayoutParams layoutParams= null;
if(arrayID == R.string.tr_set_key_named_price) {
layoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT, 1);
displayRow.findViewById(R.id.display_row_body).setPadding(5, 0, 10, 0);
displayRow.setMinimumWidth(130);
}
else {
layoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT, 1);
displayRow.findViewById(R.id.display_row_body).setPadding(10, 0, 5, 0);
}
row.addView(displayRow, layoutParams);
}
else if (arrayID == R.string.tr_set_key_description) {
descriptionControls.addView(((TaskEditControlSet)set).getDisplayView());
}
else {
taskControls.addView(((TaskEditControlSet)set).getDisplayView());
}
((TaskRabbitSetListener) set).readFromModel(parameters, getString(arrayID), currentSelectedItem);
}
}
private JSONObject defaultValuesToJSON (TypedArray keys, int[] presetValues) {
JSONObject parameters = new JSONObject();
for(int i = 0; i < keys.length(); i++) {
try {
int arrayID = keys.getResourceId(i, 0);
parameters.put(getString(arrayID), (presetValues[i]));
} catch (JSONException e) {
e.printStackTrace();
}
}
return parameters;
}
/** Initialize UI components */
private void setUpUIComponents() {
if (taskTitle == null){
taskTitle = (EditText) findViewById(R.id.task_title);
taskControls = (LinearLayout) findViewById(R.id.task_controls);
descriptionControls = (LinearLayout)findViewById(R.id.description_controls);
taskButton = (Button) findViewById(R.id.task_button);
taskButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
submitTaskRabbit();
}
});
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setCustomView(R.layout.task_rabbit_header_view);
View customView = actionBar.getCustomView();
menuNav = customView.findViewById(R.id.menu_nav);
menuNavDisclosure = (ImageView) customView.findViewById(R.id.menu_disclosure_arrow);
menuTitle = (TextView) customView.findViewById(R.id.task_rabbit_title);
menuNav.setOnClickListener(menuClickListener);
createMenuPopover();
}
setUpControls();
}
}
private void populateFields(TaskRabbitTaskContainer container) {
if (container == null) {
return;
}
if(taskRabbitTask.getTaskID() != TaskRabbitTaskContainer.NO_ID) {
taskButton.setText(getString(R.string.tr_button_already_posted));
taskButton.setEnabled(false);
}
else {
taskButton.setEnabled(true);
}
JSONObject jsonData = container.getLocalTaskData();
synchronized (controls) {
if(jsonData != null) {
String[] keys = getResources().getStringArray(R.array.tr_default_set_key);
currentSelectedItem = jsonData.optInt(getString(R.string.tr_set_key_type));
String title = jsonData.optString(getString(R.string.tr_set_key_name));
if (!TextUtils.isEmpty(title)) {
taskTitle.setText(title);
}
for (int i = 0; i < controls.size(); i++) {
TaskRabbitSetListener set = (TaskRabbitSetListener) controls.get(i);
set.readFromModel(jsonData, keys[i], currentSelectedItem);
}
}
}
}
/* saving/converting task rabbit data */
private JSONObject localParamsToJSON () throws JSONException {
JSONObject parameters = new JSONObject();
int[] presetValues = getPresetValues(currentSelectedItem);
String[] keys = getResources().getStringArray(R.array.tr_default_set_key);
if (menuTitle != null) {
String descriptionKey = getString(R.string.tr_set_key_description);
String category = String.format("Category: %s\n", menuTitle.getText().toString()); //$NON-NLS-1$
parameters.put(descriptionKey, category);
}
for (int i = 0; i < controls.size(); i++) {
if (presetValues[i] == -1) continue;
TaskRabbitSetListener set = controls.get(i);
set.postToTaskRabbit(parameters, keys[i]);
}
if (parameters.optJSONArray(LOCATION_CONTAINER) == null) {
parameters.put(getString(R.string.tr_attr_city_id), Preferences.getInt(TASK_RABBIT_PREF_CITY_ID, 1));
parameters.put(getString(R.string.tr_attr_city_lat), true);
}
parameters.put(getString(R.string.tr_set_key_name), taskTitle.getText().toString());
parameters.put(getString(R.string.tr_set_key_name), taskTitle.getText().toString());
return new JSONObject().put("task", parameters); //$NON-NLS-1$
}
private int[] getPresetValues(int mode) {
TypedArray arrays = getResources().obtainTypedArray(R.array.tr_default_type_array);
int[] presetValues = getResources().getIntArray(arrays.getResourceId(mode, 0));
return presetValues;
}
private String serializeToJSON () throws JSONException {
JSONObject parameters = new JSONObject();
String[] keys = getResources().getStringArray(R.array.tr_default_set_key);
for (int i = 0; i < controls.size(); i++) {
TaskRabbitSetListener set = controls.get(i);
set.saveToDatabase(parameters, keys[i]);
}
parameters.put(getString(R.string.tr_set_key_type), currentSelectedItem);
parameters.put(getString(R.string.tr_set_key_name), taskTitle.getText().toString());
return parameters.toString();
}
private HttpEntity getTaskBody() {
try {
return new StringEntity(localParamsToJSON().toString());
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
private ProgressDialog progressDialog;
@SuppressWarnings("nls")
protected void submitTaskRabbit(){
if(!Preferences.isSet(TASK_RABBIT_TOKEN)){
loginTaskRabbit();
}
else if (!supportsSelectedLocation()){
Message successMessage = new Message();
successMessage.what = MESSAGE_CODE_LOCATION_FAILURE;
handler.sendMessage(successMessage);
}
else {
if(progressDialog == null)
progressDialog = DialogUtilities.progressDialog(this,
getString(R.string.DLG_please_wait));
new Thread(new Runnable() {
@Override
public void run() {
boolean success = false;
String urlCall = "tasks/";
if (taskRabbitTask.getTaskID() > 0) urlCall += taskRabbitTask.getTaskID();
urlCall += String.format("?client_id=%s&client_application=%s", TASK_RABBIT_CLIENT_ID, TASK_RABBIT_CLIENT_APPLICATION_ID);
Header authorization = new BasicHeader("Authorization", "OAuth " + Preferences.getStringValue(TASK_RABBIT_TOKEN));
Header contentType = new BasicHeader("Content-Type", "application/json");
HttpEntity taskBody = getTaskBody();
String response = null;
try {
response = restClient.post(taskRabbitURL(urlCall), taskBody, contentType, authorization);
Log.e("The response", "The post response: " + response);
JSONObject taskResponse = new JSONObject(response);
if(taskResponse.has(TASK_RABBIT_ID)){
taskRabbitTask.setRemoteTaskData(response);
taskRabbitTask.setTaskID(taskResponse.optString(TASK_RABBIT_ID));
Message successMessage = new Message();
successMessage.what = MESSAGE_CODE_SUCCESS;
handler.sendMessage(successMessage);
success = true;
}
}
catch (UnknownHostException e) {
Message failureMessage = new Message();
failureMessage.what = MESSAGE_CODE_INTERNET_FAILURE;
handler.sendMessage(failureMessage);
}
catch (Exception e){
Message failureMessage = new Message();
failureMessage.what = MESSAGE_CODE_FAILURE;
handler.sendMessage(failureMessage);
}
finally {
StatisticsService.reportEvent(StatisticsConstants.TASK_RABBIT_POST, "success", new Boolean(success).toString());
runOnUiThread(new Runnable() {
public void run() {
if (progressDialog != null) {
DialogUtilities.dismissDialog(TaskRabbitActivity.this, progressDialog);
}
}
});
}
}
}).start();
}
try {
taskRabbitTask.setLocalTaskData(serializeToJSON().toString());
} catch (JSONException e) {
e.printStackTrace();
}
//submit!
}
private final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
String alertMessage = null;
switch (msg.what) {
case MESSAGE_CODE_FAILURE:
{
alertMessage = getString(R.string.tr_alert_message_fail);
break;
}
case MESSAGE_CODE_INTERNET_FAILURE:
{
alertMessage = getString(R.string.tr_alert_internet_message_fail);
break;
}
case MESSAGE_CODE_LOCATION_FAILURE:
{
final AlertDialog adb = new AlertDialog.Builder(TaskRabbitActivity.this)
.setMessage(R.string.tr_alert_location_not_supported_message)
.setPositiveButton(getString(R.string.tr_alert_button_close),null)
.show();
((TextView) adb.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
return;
}
case MESSAGE_CODE_SUCCESS:
{
TaskRabbitDataService.getInstance().saveTaskAndMetadata(taskRabbitTask);
Intent data = new Intent();
data.putExtra(TaskRabbitControlSet.DATA_RESPONSE, taskRabbitTask.getRemoteTaskData().toString());
TaskRabbitActivity.this.setResult(Activity.RESULT_OK, data);
TaskRabbitActivity.this.finish();
return;
}
}
AlertDialog.Builder adb = new AlertDialog.Builder(TaskRabbitActivity.this);
adb.setTitle(getString(R.string.tr_alert_title_fail));
adb.setMessage(alertMessage);
adb.setPositiveButton(getString(R.string.tr_alert_button_close),null);
adb.show();
}
};
/* login methods */
protected void loginTaskRabbit() {
Intent intent = new Intent(this,
TaskRabbitOAuthLoginActivity.class);
try {
String url = String.format(TASK_RABBIT_URL + "/api/authorize?client_id=%s&client_application=%s", TASK_RABBIT_CLIENT_ID, TASK_RABBIT_CLIENT_APPLICATION_ID); //$NON-NLS-1$
intent.putExtra(TaskRabbitOAuthLoginActivity.URL_TOKEN, url);
this.startActivityForResult(intent, REQUEST_CODE_TASK_RABBIT_OAUTH);
StatisticsService.reportEvent(StatisticsConstants.TASK_RABBIT_LOGIN);
} catch (Exception e) {
e.printStackTrace();
}
}
private void loadLocation() {
if (locationManager == null) {
locationManager = new TaskRabbitLocationManager(this);
if (!locationManager.isLocationUpdatesEnabled()) {
buildAlertMessageNoGps();
showingNoGPSAlertMessage = true;
}
}
currentLocation = locationManager.getLastKnownLocation();
if (currentLocation == null) {
locationManager.getLocation(new LocationResult(){
@Override
public void gotLocation(final Location location){
//Got the location!
currentLocation = location;
updateControlSetLocation(currentLocation);
}
}
);
}
else {
updateControlSetLocation(currentLocation);
}
}
@SuppressWarnings("nls")
private void buildAlertMessageNoGps() {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(getString(R.string.tr_alert_gps_title))
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, final int id) {
startActivityForResult(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS), REQUEST_CODE_ENABLE_GPS);
showingNoGPSAlertMessage = false;
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, final int id) {
dialog.cancel();
showingNoGPSAlertMessage = false;
showIntroDialog();
}
});
final AlertDialog alert = builder.create();
alert.show();
}
protected void saveUserInfo(String response) throws Exception {
JSONObject userObject = new JSONObject(response);
JSONObject cityObject = userObject.getJSONObject("city"); //$NON-NLS-1$
if (cityObject.has(CITY_NAME)){
Preferences.setString(TASK_RABBIT_PREF_CITY_NAME, cityObject.getString(CITY_NAME));
}
if (cityObject.has(TASK_RABBIT_ID)){
Preferences.setInt(TASK_RABBIT_PREF_CITY_ID, cityObject.getInt(TASK_RABBIT_ID));
}
if (cityObject.has(CITY_LAT)){
Preferences.setString(TASK_RABBIT_PREF_CITY_LAT, String.valueOf(cityObject.getDouble(CITY_LAT)));
}
if (cityObject.has(CITY_LNG)){
Preferences.setString(TASK_RABBIT_PREF_CITY_LNG, String.valueOf(cityObject.getDouble(CITY_LNG)));
}
}
private String taskRabbitURL(String method) {
return TASK_RABBIT_URL + "/api/v1/"+ method; //$NON-NLS-1$
}
@SuppressWarnings("nls")
@Override
public void onActivityResult (int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_TASK_RABBIT_OAUTH && resultCode == Activity.RESULT_OK){
String result = data.getStringExtra(TaskRabbitOAuthLoginActivity.DATA_RESPONSE);
String key = "access_token="; //$NON-NLS-1$
if(result.contains(key)) {
try {
result = result.substring(result.indexOf(key)+key.length());
Preferences.setString(TASK_RABBIT_TOKEN, result);
String url = String.format("%s?oauth_token=%s&client_application=%s",taskRabbitURL("account"), Preferences.getStringValue(TASK_RABBIT_TOKEN), TASK_RABBIT_CLIENT_APPLICATION_ID);
String response = restClient.get(url);
saveUserInfo(response);//;
}
catch (Exception e){
e.printStackTrace();
}
return;
}
}
else if (requestCode == REQUEST_CODE_ENABLE_GPS) {
loadLocation();
}
else {
for (TaskRabbitSetListener set : controls) {
if (set instanceof ActivityResultSetListener) {
if (((ActivityResultSetListener) set).activityResult(requestCode, resultCode, data))
return;
}
}
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case android.R.id.home:
finish();
break;
}
return super.onOptionsItemSelected(item);
}
/* location calls */
private boolean supportsSelectedLocation() {
for (TaskRabbitSetListener controlSet : controls) {
if (TaskRabbitLocationControlSet.class.isAssignableFrom(controlSet.getClass())) {
TaskRabbitLocationControlSet locationControlSet = (TaskRabbitLocationControlSet) controlSet;
if(!TaskRabbitLocationManager.supportsCurrentLocation(locationControlSet.location) && locationControlSet.getDisplayView().getParent() != null) {
return false;
}
}
}
return true;
}
public void updateControlSetLocation (Location location) {
for (TaskRabbitSetListener controlSet : controls) {
if (TaskRabbitLocationControlSet.class.isAssignableFrom(controlSet.getClass())) {
((TaskRabbitLocationControlSet) controlSet).updateCurrentLocation(location);
}
}
}
public boolean isLoggedIn() {
return !TextUtils.isEmpty(Preferences.getStringValue(TASK_RABBIT_TOKEN));
}
/* Menu Popover */
private void setMenuDropdownSelected(boolean selected) {
int oldTextColor = menuTitle.getTextColors().getDefaultColor();
int textStyle = (selected ? R.style.TextAppearance_ActionBar_ListsHeader_Selected :
R.style.TextAppearance_ActionBar_ListsHeader);
TypedValue listDisclosure = new TypedValue();
getTheme().resolveAttribute(R.attr.asListsDisclosure, listDisclosure, false);
menuTitle.setTextAppearance(this, textStyle);
menuNav.setBackgroundColor(selected ? oldTextColor : android.R.color.transparent);
menuNavDisclosure.setSelected(selected);
}
private final OnClickListener menuClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
setMenuDropdownSelected(true);
menuPopover.show(v);
}
};
private void createMenuPopover() {
menuPopover = new FragmentPopover(this, R.layout.task_rabbit_menu_popover);
menuPopover.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss() {
setMenuDropdownSelected(false);
}
});
setupListView();
menuPopover.setContent(menuList);
}
private void setupListView() {
String[] keys = getResources().getStringArray(R.array.tr_preset_types);
if (adapter == null) {
adapter = new ArrayAdapter<String>(this, R.layout.task_rabbit_menu_row, keys);
menuList = new ErrorCatchingListView(this);
menuList.setAdapter(adapter);
menuList.setCacheColorHint(Color.TRANSPARENT);
menuList.setSelection(0);
menuList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
currentSelectedItem = position;
displayViewsForMode(position);
menuPopover.dismiss();
}
});
}
else {
adapter = new ArrayAdapter<String>(this, R.layout.task_rabbit_menu_row, keys);
menuList.setAdapter(adapter);
}
}
}

@ -1,292 +0,0 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.taskrabbit;
import java.util.Locale;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Intent;
import android.location.Location;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;
import com.timsu.astrid.R;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.service.RestClient;
import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.actfm.EditPeopleControlSet.AssignedChangedListener;
import com.todoroo.astrid.activity.TaskEditFragment;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.helper.TaskEditControlSet;
public class TaskRabbitControlSet extends TaskEditControlSet implements AssignedChangedListener {
public interface TaskRabbitSetListener {
public void readFromModel(JSONObject json, String key);
public void saveToJSON(JSONObject json, String key) throws JSONException;
public void writeToJSON(JSONObject json, String key) throws JSONException;
}
public interface ActivityResultSetListener {
public boolean activityResult (int requestCode, int resultCode, Intent data);
}
/** task model */
private Task model = null;
@Autowired
private RestClient restClient;
private Location currentLocation;
public boolean isEnabledForTRLocation = false;
public static final String LOCATION_ENABLED = "location_enabled"; //$NON-NLS-1$
private final Fragment fragment;
protected final TextView displayText;
private TaskRabbitLocationManager locationManager;
public static final int REQUEST_CODE_TASK_RABBIT_ACTIVITY = 5;
public static final String DATA_RESPONSE = "response"; //$NON-NLS-1$
/** Act.fm current user name */
private TaskRabbitTaskContainer taskRabbitTask;
public TaskRabbitControlSet(Fragment fragment, int displayViewLayout) {
super(fragment.getActivity(), displayViewLayout);
this.fragment = fragment;
DependencyInjectionService.getInstance().inject(this);
displayText = (TextView) getView().findViewById(R.id.display_row_title);
if (displayText != null) {
displayText.setMaxLines(2);
}
if (getView() != null) {
getView().setOnClickListener(getDisplayClickListener());
}
loadLocation();
}
protected void refreshDisplayView() {
JSONObject remoteData = taskRabbitTask.getRemoteTaskData();
updateDisplay(remoteData);
}
@Override
public void readFromTask(Task task) {
model = task;
taskRabbitTask = TaskRabbitDataService.getInstance().getContainerForTask(model);
updateTaskRow(taskRabbitTask);
}
public void showTaskRabbitActivity() {
Intent intent = new Intent(fragment.getActivity(), TaskRabbitActivity.class);
intent.putExtra(TaskEditFragment.TOKEN_ID, model.getId());
intent.putExtra(LOCATION_ENABLED, isEnabledForTRLocation);
fragment.startActivityForResult(intent, REQUEST_CODE_TASK_RABBIT_ACTIVITY);
}
protected OnClickListener getDisplayClickListener() {
return new OnClickListener() {
@Override
public void onClick(View v) {
showTaskRabbitActivity();
}
};
}
@Override
protected void readFromTaskOnInitialize() {
// Nothing, we don't lazy load this control set yet
}
@Override
protected String writeToModelAfterInitialized(Task task) {
// Nothing, we don't lazy load this control set yet
return null;
}
@Override
protected void afterInflate() {
// Nothing, we don't lazy load this control set yet
}
@Override
public String writeToModel(Task task) {
return null;
}
private void updateTaskRow(TaskRabbitTaskContainer container) {
displayText.setText(fragment.getString(R.string.tr_display_status));
JSONObject remoteData = container.getRemoteTaskData();
updateDisplay(remoteData);
updateStatus(remoteData);
}
/* message callbacks */
/**
* Show toast for task edit canceling
*/
private void showSuccessToast() {
Toast.makeText(ContextManager.getContext(),
ContextManager.getString(R.string.tr_success_toast),
Toast.LENGTH_SHORT).show();
}
private final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0: break;
case 1:
showSuccessToast();
updateDisplay(taskRabbitTask.getRemoteTaskData());
break;
}
}
};
private String taskRabbitURL(String method) {
return String.format("%s/api/v1/%s?client_id=%s&client_application=%s", TaskRabbitActivity.TASK_RABBIT_URL, method, TaskRabbitActivity.TASK_RABBIT_CLIENT_ID, TaskRabbitActivity.TASK_RABBIT_CLIENT_APPLICATION_ID); //$NON-NLS-1$
}
/** Fire task rabbit if assigned **/
@Override
public boolean showTaskRabbitForUser(String name, JSONObject json) {
Activity fragActivity = fragment.getActivity();
if (fragActivity != null && name.equals(fragActivity.getString(R.string.actfm_EPA_task_rabbit))) {
showTaskRabbitActivity();
return true;
}
return false;
}
public boolean activityResult (int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_TASK_RABBIT_ACTIVITY ){
if (resultCode == Activity.RESULT_OK) {
String result = data.getStringExtra(TaskRabbitOAuthLoginActivity.DATA_RESPONSE);
if (!TextUtils.isEmpty(result)) {
try {
Message successMessage = new Message();
successMessage.what = 1;
handler.sendMessageDelayed(successMessage, 500);
return true;
}
catch (Exception e){
e.printStackTrace();
}
}
}
else {
updateDisplay(null);
}
return true;
}
return false;
}
/*
*
*/
public void updateDisplay(JSONObject json) {
if (fragment.getActivity() != null) {
String stateKey = fragment.getActivity().getString(R.string.tr_attr_state_label);
if (json != null && json.has(stateKey)) {
String status = json.optString(stateKey);
TextView statusText = (TextView) getDisplayView().findViewById(R.id.display_row_edit);
statusText.setText(status);
getDisplayView().setVisibility(View.VISIBLE);
}
else if (taskRabbitTask != null && taskRabbitTask.getLocalTaskData() != null) {
TextView statusText = (TextView) getDisplayView().findViewById(R.id.display_row_edit);
statusText.setText(fragment.getActivity().getString(R.string.tr_status_draft));
getDisplayView().setVisibility(View.VISIBLE);
}
else {
getDisplayView().setVisibility(View.GONE);
}
}
}
protected void updateStatus(JSONObject json){
if (json == null) return;
final long taskID = json.optLong(TaskRabbitActivity.TASK_RABBIT_ID);
if (taskID == TaskRabbitTaskContainer.NO_ID) return;
new Thread(new Runnable() {
@Override
public void run() {
try {
String response = restClient.get(taskRabbitURL("tasks/" + taskID)); //$NON-NLS-1$
JSONObject taskResponse = new JSONObject(response);
if(taskResponse.has(TaskRabbitActivity.TASK_RABBIT_ID)){
taskRabbitTask.setRemoteTaskData(response);
taskRabbitTask.setTaskID(taskResponse.optString(TaskRabbitActivity.TASK_RABBIT_ID));
Message successMessage = new Message();
successMessage.what = 2;
handler.sendMessage(successMessage);
}
}
catch (Exception e){
e.printStackTrace();
Message failureMessage = new Message();
failureMessage.what = 0;
handler.sendMessage(failureMessage);
}
}
}).start();
//submit!
}
public boolean isLoggedIn() {
return !TextUtils.isEmpty(Preferences.getStringValue(TaskRabbitActivity.TASK_RABBIT_TOKEN));
}
@Override
public boolean shouldShowTaskRabbit() {
if(Locale.getDefault().getCountry().equals("US")) return true; //$NON-NLS-1$
return false;
}
private void loadLocation() {
locationManager = new TaskRabbitLocationManager(fragment.getActivity());
currentLocation = locationManager.getLastKnownLocation();
isEnabledForTRLocation = TaskRabbitLocationManager.supportsCurrentLocation(currentLocation);
}
@Override
public boolean didPostToTaskRabbit() {
if (taskRabbitTask == null) return false;
return taskRabbitTask.getTaskID() != TaskRabbitTaskContainer.NO_ID;
}
}

@ -1,89 +0,0 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.taskrabbit;
import java.util.ArrayList;
import android.content.Context;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Query;
import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.service.MetadataService;
public final class TaskRabbitDataService {
// --- singleton
private static TaskRabbitDataService instance = null;
public static synchronized TaskRabbitDataService getInstance() {
if(instance == null)
instance = new TaskRabbitDataService(ContextManager.getContext());
return instance;
}
// --- instance variables
protected final Context context;
@Autowired
private TaskDao taskDao;
@Autowired
private MetadataService metadataService;
private TaskRabbitDataService(Context context) {
this.context = context;
DependencyInjectionService.getInstance().inject(this);
}
// --- task and metadata methods
/**
* Saves a task and its metadata
* @param task
*/
public void saveTaskAndMetadata(TaskRabbitTaskContainer task) {
taskDao.save(task.task);
task.metadata.add(task.trTask);
// note we don't include note metadata, since we only receive deltas
metadataService.synchronizeMetadata(task.task.getId(), task.metadata,
MetadataCriteria.withKey(TaskRabbitMetadata.METADATA_KEY), true);
}
/**
* Reads a task and its metadata
* @param task
* @return
*/
public TaskRabbitTaskContainer getContainerForTask(Task task) {
// read tags, notes, etc
ArrayList<Metadata> metadata = new ArrayList<Metadata>();
TodorooCursor<Metadata> metadataCursor = metadataService.query(Query.select(Metadata.PROPERTIES).
where(Criterion.and(MetadataCriteria.byTask(task.getId()),
MetadataCriteria.withKey(TaskRabbitMetadata.METADATA_KEY))));
try {
for(metadataCursor.moveToFirst(); !metadataCursor.isAfterLast(); metadataCursor.moveToNext()) {
metadata.add(new Metadata(metadataCursor));
}
} finally {
metadataCursor.close();
}
if (metadata.size() == 0) return new TaskRabbitTaskContainer(task);
return new TaskRabbitTaskContainer(task, metadata.get(0));
}
}

@ -1,120 +0,0 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.taskrabbit;
import java.util.Date;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.timsu.astrid.R;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.andlib.utility.DialogUtilities;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.taskrabbit.TaskRabbitActivity.TaskRabbitSetListener;
import com.todoroo.astrid.ui.DateAndTimePicker;
import com.todoroo.astrid.ui.PopupControlSet;
public class TaskRabbitDeadlineControlSet extends PopupControlSet implements TaskRabbitSetListener{
private final DateAndTimePicker dateAndTimePicker;
public TaskRabbitDeadlineControlSet(Activity activity, int viewLayout, int displayViewLayout) {
super(activity, viewLayout, displayViewLayout, 0);
dateAndTimePicker = (DateAndTimePicker) getView().findViewById(R.id.date_and_time);
this.displayText.setText(activity.getString(R.string.TEA_when_header_label));
Button okButton = (Button) LayoutInflater.from(activity).inflate(R.layout.control_dialog_ok, null);
okButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onOkClick();
DialogUtilities.dismissDialog(TaskRabbitDeadlineControlSet.this.activity, TaskRabbitDeadlineControlSet.this.dialog);
}
});
LinearLayout body = (LinearLayout) getView().findViewById(R.id.datetime_body);
body.addView(okButton);
}
@Override
protected void refreshDisplayView() {
TextView dateDisplay = (TextView) getDisplayView().findViewById(R.id.display_row_edit);
String toDisplay = dateAndTimePicker.getDisplayString(activity, false, false);
if (dateDisplay != null)
dateDisplay.setText(toDisplay);
}
@Override
public void readFromTask(Task task) {
long dueDate = task.getValue(Task.DUE_DATE);
dateAndTimePicker.initializeWithDate(dueDate);
refreshDisplayView();
}
@Override
public String writeToModel(Task task) {
return null;
}
@Override
public void readFromModel(JSONObject json, String key, int mode) {
long dateValue = json.optLong(key);
Date currentDate = null;
if (dateValue < 24) {
if(dateAndTimePicker.constructDueDate() > 0) return;
currentDate = new Date();
currentDate.setHours((int)dateValue);
currentDate.setMinutes(0);
currentDate.setSeconds(0);
}
else {
currentDate = new Date(dateValue);
}
dateAndTimePicker.initializeWithDate(DateUtilities.dateToUnixtime(currentDate)+ DateUtilities.ONE_DAY);
refreshDisplayView();
}
@Override
protected void afterInflate() {
// Nothing, we don't lazy load this control set yet
}
@Override
protected void readFromTaskOnInitialize() {
// Nothing, we don't lazy load this control set yet
}
@Override
protected String writeToModelAfterInitialized(Task task) {
// Nothing, we don't lazy load this control set yet
return null;
}
@Override
public void saveToDatabase(JSONObject json, String key) throws JSONException {
json.put(key, dateAndTimePicker.constructDueDate()/1000);
}
@Override
public void postToTaskRabbit(JSONObject json, String key) throws JSONException {
long dueDate = dateAndTimePicker.constructDueDate()/1000;
json.put(key, dueDate);
}
}

@ -1,226 +0,0 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.taskrabbit;
import java.util.HashMap;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.timsu.astrid.R;
import com.todoroo.andlib.utility.DialogUtilities;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.helper.TaskEditControlSet;
import com.todoroo.astrid.taskrabbit.TaskRabbitActivity.ActivityResultSetListener;
import com.todoroo.astrid.taskrabbit.TaskRabbitActivity.TaskRabbitSetListener;
public class TaskRabbitLocationControlSet extends TaskEditControlSet implements TaskRabbitSetListener, ActivityResultSetListener {
private final TextView displayText;
private final TextView displayEdit;
private final Activity activity;
private String locationName;
public Location location;
public JSONObject manualEntry = null;
public int REQUEST_CODE_TASK_RABBIT_LOCATION = 6;
public TaskRabbitLocationControlSet(final Activity activity , int viewLayout, int title, int setID) {
super(activity, viewLayout);
this.activity = activity;
REQUEST_CODE_TASK_RABBIT_LOCATION += setID;
displayText = (TextView) getDisplayView().findViewById(R.id.display_row_title);
displayText.setText(activity.getString(title));
displayEdit = (TextView) getDisplayView().findViewById(R.id.display_row_edit);
displayEdit.setText(getLocationText());
this.getView().setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
Class.forName("com.google.android.maps.MapView"); //$NON-NLS-1$
Intent mapIntent = new Intent(activity, TaskRabbitMapActivity.class);
activity.startActivityForResult(mapIntent, REQUEST_CODE_TASK_RABBIT_LOCATION);
} catch (Exception e) {
manualLocationEntry();
}
}
});
}
@SuppressWarnings("nls")
protected void manualLocationEntry() {
LinearLayout layout = new LinearLayout(activity);
layout.setOrientation(LinearLayout.VERTICAL);
LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT);
final String[] fields = new String[] { "Name","Address", "City", "State", "Zip" };
final HashMap<String, EditText> views = new HashMap<String, EditText>();
for(String field : fields) {
EditText et = new EditText(activity);
et.setHint(field);
et.setLayoutParams(lp);
views.put(field, et);
layout.addView(et);
}
DialogUtilities.viewDialog(activity, "Enter Location", layout, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
displayEdit.setText(views.get("Address").getText());
manualEntry = new JSONObject();
for(String field : fields)
try {
manualEntry.put(field.toLowerCase(), views.get(field).getText());
} catch (JSONException e) {
// fail
}
}
}, null);
}
private void parseTaskLocation(JSONObject json) {
if (json == null) return;
if (json.has(TaskRabbitActivity.CITY_NAME))
locationName = json.optString(TaskRabbitActivity.CITY_NAME);
if(json.has(TaskRabbitActivity.CITY_LNG)) {
location = new Location(""); //$NON-NLS-1$
location.setLongitude(json.optInt(TaskRabbitActivity.CITY_LNG));
location.setLatitude(json.optInt(TaskRabbitActivity.CITY_LAT));
}
}
public String getLocationText () {
if (!TextUtils.isEmpty(locationName))
return locationName;
return activity.getString(R.string.tr_default_location_name);
}
public boolean activityResult (int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_TASK_RABBIT_LOCATION && resultCode == Activity.RESULT_OK) {
int lng = data.getIntExtra(TaskRabbitActivity.CITY_LNG, 0);
int lat = data.getIntExtra(TaskRabbitActivity.CITY_LAT, 0);
locationName = data.getStringExtra(TaskRabbitActivity.CITY_NAME);
location = new Location(""); //$NON-NLS-1$
location.setLatitude(locationToDouble(lat));
location.setLongitude(locationToDouble(lng));
displayEdit.setText(getLocationText());
manualEntry = null;
return true;
}
return false;
}
public static double locationToDouble(int location) {
return (location+ 0.0) / 1e6;
}
public static int locationToInt(double location) {
return (int)(location * 1e6);
}
@Override
public void readFromModel(JSONObject json, String key, int mode) {
parseTaskLocation(json.optJSONObject(key));
displayEdit.setText(getLocationText());
}
public void updateCurrentLocation(Location currentLocation) {
if (location == null) {
location = currentLocation;
}
}
@Override
public void saveToDatabase(JSONObject json, String key) throws JSONException {
json.put(key, getTaskLocation());
}
@Override
public void postToTaskRabbit(JSONObject json, String key) throws JSONException {
JSONArray locations = json.optJSONArray(TaskRabbitActivity.LOCATION_CONTAINER);
if (locations == null) {
locations = new JSONArray();
}
locations.put(getTaskLocation());
json.put(TaskRabbitActivity.LOCATION_CONTAINER, locations);
}
private JSONObject getTaskLocation() {
if(manualEntry != null)
return manualEntry;
try {
JSONObject locationObject = new JSONObject();
if(!TextUtils.isEmpty(locationName)){
locationObject.put(TaskRabbitActivity.CITY_NAME, locationName);
}
else {
locationObject.put(TaskRabbitActivity.CITY_NAME, displayText.getText().toString());
}
if(location != null) {
locationObject.put(TaskRabbitActivity.CITY_LNG, location.getLongitude());
locationObject.put(TaskRabbitActivity.CITY_LAT, location.getLatitude());
}
return locationObject;
}
catch (JSONException e) {
e.printStackTrace();
}
return null;
}
//don't need these
@Override
public void readFromTask(Task task) {
//
}
@Override
protected void afterInflate() {
// Nothing, we don't lazy load this control set yet
}
@Override
protected void readFromTaskOnInitialize() {
// Nothing, we don't lazy load this control set yet
}
@Override
protected String writeToModelAfterInitialized(Task task) {
// Nothing, we don't lazy load this control set yet
return null;
}
@Override
public String writeToModel(Task task) {
return null;
}
}

@ -1,131 +0,0 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.taskrabbit;
import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import com.timsu.astrid.data.location.GeoPoint;
public class TaskRabbitLocationManager {
Timer timer1;
LocationManager lm;
LocationResult locationResult;
boolean network_enabled=false;
Context context;
private static final int RADIUS_250_MILES = 400000;
public TaskRabbitLocationManager(Context context) {
this.context = context;
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
}
private static final GeoPoint[] supportedLocations = {
new GeoPoint(42358430, -71059770), //BOS
new GeoPoint(37739230, -122439880), //SF
new GeoPoint(40714350, -74005970), //NYC
new GeoPoint(41878110, -87629800), //CHI
new GeoPoint(34052230, -118243680), //LA
new GeoPoint(33717470, -117831140), //OC
new GeoPoint(30267150, -97743060), //AUSTIN
new GeoPoint(45523450, -122676210), //PORTLAND
new GeoPoint(47606210, -122332070), //SEA
new GeoPoint(29424120, -98493630) //SAN ANTONIO
};
public boolean isLocationUpdatesEnabled() {
boolean provider_enabled = false;
try {
provider_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch (Exception ex) {
// suppress
}
return provider_enabled;
}
public Location getLastKnownLocation()
{
if(!isNetworkProviderEnabled())
return null;
else {
return lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
}
public static boolean supportsCurrentLocation(Location location) {
if (location == null) return false;
for (GeoPoint point : supportedLocations){
Location city = new Location(""); //$NON-NLS-1$
city.setLatitude(point.getLatitudeE6()/1E6);
city.setLongitude(point.getLongitudeE6()/1E6);
float distance = location.distanceTo(city);
if (distance < RADIUS_250_MILES) {
return true;
}
}
return false;
}
public boolean getLocation(LocationResult result)
{
locationResult = result;
if(!isNetworkProviderEnabled())
return false;
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
timer1=new Timer();
timer1.schedule(new GetLastLocation(), 20000);
return true;
}
private boolean isNetworkProviderEnabled() {
try {
return lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch (Exception ex) {
// suppress
}
return false;
}
private final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(locationListener);
}
public void onProviderDisabled(String provider) { /**/ }
public void onProviderEnabled(String provider) { /**/ }
public void onStatusChanged(String provider, int status, Bundle extras) { /**/ }
};
class GetLastLocation extends TimerTask {
@Override
public void run() {
lm.removeUpdates(locationListener);
Location net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if(net_loc!=null){
locationResult.gotLocation(net_loc);
return;
}
locationResult.gotLocation(null);
}
}
public static abstract class LocationResult{
public abstract void gotLocation(Location location);
}
}

@ -1,297 +0,0 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.taskrabbit;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.timsu.astrid.R;
public class TaskRabbitMapActivity extends MapActivity implements LocationListener {
private MapView mapView;
private MapController mapController;
public Location currentLocation;
private LocationManager locationManager;
private EditText searchText;
private TaskRabbitMapOverlayItem currentOverlayItem;
private String locationAddress;
private static final int LOCATION_SEARCH_SUCCESS = 1;
private static final int LOCATION_SEARCH_FAIL = -1;
// Production value
private static final String MAPS_API_KEY = "0J-miH1uUbgVV5xsNNmvSIzb4DIENVCMERxB7gw"; //$NON-NLS-1$
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.task_rabbit_map_activity);
mapView = new MapView(this, MAPS_API_KEY);
mapView.setClickable(true);
mapView.setBuiltInZoomControls(true);
LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, 12.0f);
((LinearLayout) findViewById(R.id.task_rabbit_map_parent)).addView(mapView, 0, lp);
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
currentLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
mapController = mapView.getController();
if(currentLocation != null) {
updateLocationOverlay();
locationAddress = getAddressFromLocation(currentLocation);
mapController.setZoom(17);
mapView.invalidate();
}
else {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
}
searchText=(EditText)findViewById(R.id.search_text);
ImageButton searchButton=(ImageButton)findViewById(R.id.search_button);
searchButton.setImageResource(android.R.drawable.ic_menu_search);
searchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
searchLocation();
}
});
}
public String getSearchText() {
return searchText.getText().toString();
}
public void setSearchTextForCurrentAddress() {
if(!TextUtils.isEmpty(locationAddress)) {
searchText.setText(locationAddress);
}
}
private final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case LOCATION_SEARCH_SUCCESS:
mapView.invalidate();
currentOverlayItem.onTap(0);
// What to do when ready, example:
break;
case LOCATION_SEARCH_FAIL:
AlertDialog.Builder adb = new AlertDialog.Builder(TaskRabbitMapActivity.this);
adb.setTitle(getString(R.string.tr_alert_location_fail_title));
adb.setMessage(getString(R.string.tr_alert_location_fail_message));
adb.setPositiveButton(R.string.DLG_close, null);
adb.show();
}
}
};
private void searchLocation() {
Thread thread = new Thread() {
@Override
public void run() {
List<Address> addresses = null;
try {
Geocoder geoCoder = new Geocoder(
TaskRabbitMapActivity.this, Locale.getDefault());
addresses = geoCoder.getFromLocationName(
searchText.getText().toString(), 5);
} catch (IOException e) {
e.printStackTrace();
}
if (addresses != null && addresses.size() > 0) {
updateAddress(addresses.get(0));
currentLocation = new Location("");
currentLocation.setLatitude(addresses.get(0).getLatitude());
currentLocation.setLongitude(addresses.get(0).getLongitude());
mapController.setZoom(12);
updateLocationOverlay();
Message successMessage = new Message();
successMessage.what = LOCATION_SEARCH_SUCCESS;
handler.sendMessage(successMessage);
} else {
Message failureMessage = new Message();
failureMessage.what = LOCATION_SEARCH_FAIL;
handler.sendMessage(failureMessage);
}
}
};
thread.start();
}
protected OverlayItem createOverlayItem(GeoPoint q) {
OverlayItem overlayitem = new OverlayItem(q, getString(R.string.tr_alert_location_clicked_title),
getString(R.string.tr_alert_location_clicked_message));
return overlayitem;
}
public String getAddressFromLocation(Location location){
try {
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
// Acquire a reference to the system Location Manager
List<Address> addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
if (addresses != null){
for (Address address : addresses){
return updateAddress(address);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return ""; //$NON-NLS-1$
}
private String updateAddress(Address address){
String addressString = null;
if(address.getLocality() != null && address.getPostalCode() != null){
addressString = ""; //$NON-NLS-1$
for (int i = 0; i < address.getMaxAddressLineIndex(); i++){
addressString += address.getAddressLine(i) + ", "; //$NON-NLS-1$
}
}
return addressString;
}
@Override
protected boolean isRouteDisplayed() {
return false;
}
private void updateLocationOverlay() {
if (currentLocation == null) { return; };
List<Overlay> mapOverlays = mapView.getOverlays();
Drawable drawable = this.getResources().getDrawable(android.R.drawable.star_big_on);
currentOverlayItem = new TaskRabbitMapOverlayItem(drawable, this);
GeoPoint point = locationToGeoPoint(currentLocation);
OverlayItem overlayitem = createOverlayItem(point);
currentOverlayItem.addOverlay(overlayitem);
mapOverlays.clear();
mapOverlays.add(currentOverlayItem);
mapController.animateTo(point);
}
public void didSelectItem (final OverlayItem selectedItem) {
AlertDialog.Builder dialogPrompt = new AlertDialog.Builder(this);
dialogPrompt.setTitle(getString(R.string.tr_alert_location_clicked_title));
Location location = geoPointToLocation(selectedItem.getPoint());
locationAddress = getAddressFromLocation(location);
setSearchTextForCurrentAddress();
dialogPrompt.setMessage(locationAddress);
dialogPrompt.setIcon(
android.R.drawable.ic_dialog_alert).setPositiveButton(
android.R.string.ok, new DialogInterface.OnClickListener() {
@SuppressWarnings("nls")
public void onClick(DialogInterface dialog, int which) {
Intent data = new Intent();
data.putExtra("lat",selectedItem.getPoint().getLatitudeE6());
data.putExtra("lng",selectedItem.getPoint().getLongitudeE6());
data.putExtra("name", getSearchText());
setResult(Activity.RESULT_OK, data);
finish();
}
}).setNegativeButton(android.R.string.cancel, null);
dialogPrompt.show();
}
private Location geoPointToLocation(GeoPoint geoPoint) {
Location location = new Location(""); //$NON-NLS-1$
location.setLatitude(((long)geoPoint.getLatitudeE6())/1E6);
location.setLongitude(((long)geoPoint.getLongitudeE6())/1E6);
return location;
}
private GeoPoint locationToGeoPoint(Location lastKnownLocation) {
GeoPoint point = new GeoPoint((int)(lastKnownLocation.getLatitude()*1E6),(int)(lastKnownLocation.getLongitude()*1E6));
return point;
}
@Override
public void onLocationChanged(Location location) {
if (location != null) {
locationManager.removeUpdates(this);
this.currentLocation = location;
updateLocationOverlay();
}
}
@Override
public void onProviderDisabled(String provider) {
//
}
@Override
public void onProviderEnabled(String provider) {
//
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
//
}
}

@ -1,72 +0,0 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.taskrabbit;
import java.util.ArrayList;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;
public class TaskRabbitMapOverlayItem extends ItemizedOverlay<OverlayItem> {
private final ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
private final TaskRabbitMapActivity mActivity;
private ImageView dragImage = null;
private OverlayItem selectedItem = null;
public TaskRabbitMapOverlayItem(Drawable defaultMarker, TaskRabbitMapActivity activity) {
super(boundCenterBottom(defaultMarker));
mActivity = activity;
getDragImage();
}
public ImageView getDragImage() {
if (dragImage == null) {
dragImage= new ImageView(mActivity);
dragImage.setImageDrawable(mActivity.getResources().getDrawable(
android.R.drawable.star_big_on));
dragImage.setLayoutParams(new RelativeLayout.LayoutParams(50, 50));
}
return dragImage;
}
public void addOverlay(OverlayItem overlay) {
mOverlays.add(overlay);
populate();
}
@Override
protected OverlayItem createItem(int i) {
return mOverlays.get(i);
}
@Override
public int size() {
return mOverlays.size();
}
@Override
protected boolean onTap(int index) {
if (index >= mOverlays.size()) {
return false;
}
selectedItem = mOverlays.get(index);
if (mActivity != null)
mActivity.didSelectItem(selectedItem);
return true;
}
}

@ -1,50 +0,0 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.taskrabbit;
import com.todoroo.andlib.data.AbstractModel;
import com.todoroo.andlib.data.Property.StringProperty;
import com.todoroo.astrid.data.Metadata;
/**
* Metadata entries for a GTasks Task
* @author Tim Su <tim@todoroo.com>
*
*/
public class TaskRabbitMetadata {
static final int VALUE_UNSET = -1;
/** metadata key */
public static final String METADATA_KEY = "taskrabbit"; //$NON-NLS-1$
/** task id in taskrabbit */
public static final StringProperty ID = new StringProperty(Metadata.TABLE,
Metadata.VALUE1.name);
public static final StringProperty DATA_LOCAL = new StringProperty(Metadata.TABLE,
Metadata.VALUE2.name);
public static final StringProperty DATA_REMOTE = new StringProperty(Metadata.TABLE,
Metadata.VALUE3.name);
/**
* Creates default GTasks metadata item
* @param taskId if > 0, will set metadata task field
* @return
*/
public static Metadata createEmptyMetadata(long taskId) {
Metadata metadata = new Metadata();
metadata.setValue(Metadata.KEY, TaskRabbitMetadata.METADATA_KEY);
metadata.setValue(ID, ""); //$NON-NLS-1$
metadata.setValue(DATA_LOCAL, ""); //$NON-NLS-1$
metadata.setValue(DATA_REMOTE, ""); //$NON-NLS-1$
if(taskId > AbstractModel.NO_ID)
metadata.setValue(Metadata.TASK, taskId);
return metadata;
}
}

@ -1,201 +0,0 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.taskrabbit;
import java.io.ByteArrayOutputStream;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.text.TextUtils;
import android.util.Base64;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import com.timsu.astrid.R;
import com.todoroo.astrid.actfm.ActFmCameraModule;
import com.todoroo.astrid.actfm.ActFmCameraModule.CameraResultCallback;
import com.todoroo.astrid.actfm.ActFmCameraModule.ClearImageCallback;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.taskrabbit.TaskRabbitActivity.ActivityResultSetListener;
import com.todoroo.astrid.taskrabbit.TaskRabbitActivity.TaskRabbitSetListener;
import com.todoroo.astrid.ui.PopupControlSet;
public class TaskRabbitNameControlSet extends PopupControlSet implements TaskRabbitSetListener, ActivityResultSetListener{
protected final EditText editText;
protected final TextView notesPreview;
private final ImageButton pictureButton;
private Bitmap pendingCommentPicture = null;
public TaskRabbitNameControlSet(Activity activity, int viewLayout,
int displayViewLayout, int titleID) {
super(activity, viewLayout, displayViewLayout, titleID);
editText = (EditText) getView().findViewById(R.id.notes);
notesPreview = (TextView) getDisplayView().findViewById(R.id.display_row_edit);
displayText.setText(activity.getString(titleID));
editText.setMaxLines(Integer.MAX_VALUE);
pictureButton = (ImageButton) getDisplayView().findViewById(R.id.picture);
if (pictureButton != null) {
final ClearImageCallback clearImage = new ClearImageCallback() {
@Override
public void clearImage() {
pendingCommentPicture = null;
pictureButton.setImageResource(R.drawable.camera_button);
}
};
pictureButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (pendingCommentPicture != null)
ActFmCameraModule.showPictureLauncher(TaskRabbitNameControlSet.this.activity, clearImage);
else
ActFmCameraModule.showPictureLauncher(TaskRabbitNameControlSet.this.activity, null);
}
});
}
}
@Override
protected void additionalDialogSetup() {
dialog.getWindow()
.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
}
@Override
public void saveToDatabase(JSONObject json, String key) throws JSONException {
json.put(key, editText.getText().toString());
}
@Override
@SuppressWarnings("nls")
public void postToTaskRabbit(JSONObject json, String key) throws JSONException {
String nameKey = activity.getString(R.string.tr_set_key_description);
if (key.equals(activity.getString(R.string.tr_set_key_name)) && json.has(nameKey)) {
json.put(nameKey, json.optString(nameKey, "") + "\nRestaurant Name: " + editText.getText().toString());
}
else {
json.put(nameKey, json.optString(nameKey, "") + "\n" + editText.getText().toString());
}
if (pendingCommentPicture != null) {
String picture = buildPictureData(pendingCommentPicture);
JSONObject pictureArray = new JSONObject();
pictureArray.put("image", picture);
json.put("uploaded_photos_attributes", new JSONObject().put("1", pictureArray));
}
}
public static String buildPictureData(Bitmap bitmap) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if(bitmap.getWidth() > 512 || bitmap.getHeight() > 512) {
float scale = Math.min(512f / bitmap.getWidth(), 512f / bitmap.getHeight());
bitmap = Bitmap.createScaledBitmap(bitmap, (int)(scale * bitmap.getWidth()),
(int)(scale * bitmap.getHeight()), false);
}
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos);
byte[] bytes = baos.toByteArray();
return Base64.encodeToString(bytes, Base64.DEFAULT);
}
@Override
public void readFromModel(JSONObject json, String key, int mode) {
if (json.optInt(key, -1) == 0) {
editText.setHint(displayText.getText().toString());
return;
}
String value = json.optString(key, ""); //$NON-NLS-1$
if (!TextUtils.isEmpty(value)) {
editText.setTextKeepState(value);
notesPreview.setText(value);
}
}
@Override
public boolean activityResult (int requestCode, int resultCode, Intent data) {
if (pictureButton != null) {
CameraResultCallback callback = new CameraResultCallback() {
@Override
public void handleCameraResult(Bitmap bitmap) {
pendingCommentPicture = bitmap;
pictureButton.setImageBitmap(pendingCommentPicture);
}
};
return (ActFmCameraModule.activityResult(activity,
requestCode, resultCode, data, callback));
}
return false;
}
@Override
protected void refreshDisplayView() {
notesPreview.setText(editText.getText());
}
@Override
public void readFromTask(Task task) {
//
}
@Override
protected void readFromTaskOnInitialize() {
// Nothing, we don't lazy load this control set yet
}
@Override
public String writeToModel(Task task) {
return null;
}
@Override
protected String writeToModelAfterInitialized(Task task) {
// Nothing, we don't lazy load this control set yet
return null;
}
@Override
protected void afterInflate() {
// Nothing, we don't lazy load this control set yet
}
@Override
protected boolean onOkClick() {
InputMethodManager imm = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
return super.onOkClick();
}
@Override
protected void onCancelClick() {
super.onCancelClick();
InputMethodManager imm = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
}
public boolean hasNotes() {
return !TextUtils.isEmpty(editText.getText());
}
}

@ -1,118 +0,0 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.taskrabbit;
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.http.SslError;
import android.os.Bundle;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.timsu.astrid.R;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.service.RestClient;
import com.todoroo.andlib.utility.DialogUtilities;
/**
* This activity displays a <code>WebView</code> that allows users to log in to
* the synchronization provider requested. A callback method determines whether
* their login was successful and therefore whether to dismiss the dialog.
*
* @author timsu
*
*/
public class TaskRabbitOAuthLoginActivity extends SherlockFragmentActivity {
/**
* URL to display
*/
public static final String URL_TOKEN = "u"; //$NON-NLS-1$
/**
* Resultant URL data
*/
public static final String DATA_RESPONSE = "response"; //$NON-NLS-1$
@Autowired
RestClient restClient;
ProgressDialog pd;
// --- ui initialization
@SuppressWarnings("nls")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DependencyInjectionService.getInstance().inject(this);
setContentView(R.layout.oauth_login_activity);
getSupportActionBar().setTitle(R.string.actfm_OLA_prompt);
final String urlParam = getIntent().getStringExtra(URL_TOKEN);
final WebView webView = (WebView) findViewById(R.id.browser);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setSavePassword(false);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setSupportZoom(true);
webView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
System.err.println("hey error. " + errorCode + ": " + description);
}
@Override
public void onReceivedSslError(WebView view,
SslErrorHandler handler, SslError error) {
handler.proceed();
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.contains("?client_id=")
&& (url.lastIndexOf("?client_id=") != url.indexOf("?client_id="))) {
String redirectUrl = url.substring(0,
url.lastIndexOf("?client_id="));
webView.loadUrl(redirectUrl);
return true;
}
return super.shouldOverrideUrlLoading(view, url);
}
@Override
public void onLoadResource(WebView view, String url) {
super.onLoadResource(view, url);
}
@Override
public void onPageFinished(WebView view, final String url) {
super.onPageFinished(view, url);
pd.dismiss();
if (url.contains("access_token=")) {
String token = url.substring(url.indexOf("access_token="),
url.length());
Intent intent = new Intent();
intent.putExtra(DATA_RESPONSE, token);
setResult(RESULT_OK, intent);
finish();
}
}
});
pd = DialogUtilities.progressDialog(this, getString(R.string.DLG_wait));
webView.loadUrl(urlParam);
}
}

@ -1,222 +0,0 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.taskrabbit;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.res.TypedArray;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import com.timsu.astrid.R;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.helper.TaskEditControlSet;
import com.todoroo.astrid.taskrabbit.TaskRabbitActivity.TaskRabbitSetListener;
public class TaskRabbitSpinnerControlSet extends TaskEditControlSet implements TaskRabbitSetListener{
private final Spinner spinner;
private final int titleID;
private final TextView displayText;
private final TextView displayEdit;
private ArrayAdapter<String> adapter;
private final Activity activity;
public TaskRabbitSpinnerControlSet(final Activity activity, int viewLayout, int title, int setID) {
super(activity, viewLayout);
this.titleID = title;
this.activity = activity;
// DependencyInjectionService.getInstance().inject(this);
// spinner = new Spinner(fragment.activity);
spinner = (Spinner) getDisplayView().findViewById(R.id.spinner);
spinner.setPrompt(activity.getString(title));
displayEdit = (TextView) getDisplayView().findViewById(R.id.display_row_edit);
displayText = (TextView) getDisplayView().findViewById(R.id.display_row_title);
displayText.setText(title);
String[] listTypes = getStringDefaultArray(setID, R.array.tr_default_array);
adapter = new ArrayAdapter<String>(
activity, android.R.layout.simple_spinner_item, listTypes);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
spinner.setAdapter(adapter);
}
});
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
displayEdit.setText(getDisplayEditText());
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
//
}
});
getView().setOnClickListener(getDisplayClickListener());
}
protected OnClickListener getDisplayClickListener() {
return new OnClickListener() {
@Override
public void onClick(View v) {
spinner.performClick();
}
};
}
public String[] getStringDefaultArray(int position, int arrayType) {
TypedArray arrays = activity.getResources().obtainTypedArray(arrayType);
int arrayID = arrays.getResourceId(position, -1);
return activity.getResources().getStringArray(arrayID);
}
public void resetAdapter(String[] items) {
if (adapter == null) return;
adapter = new ArrayAdapter<String>(
activity, android.R.layout.simple_spinner_item, items);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
spinner.setAdapter(adapter);
spinner.setSelection(0); // plus 1 for the no selection item
}
});
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
displayEdit.setText(getDisplayEditText());
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
//
}
});
}
public int selectedPosition() {
return spinner.getSelectedItemPosition();
}
@Override
public void readFromModel(JSONObject json, String key, int mode) {
if (titleID == R.string.tr_set_named_price){
String[] listTypes = getStringDefaultArray(mode, R.array.tr_default_price_type_array);
resetAdapter(listTypes);
}
else if (titleID == R.string.tr_set_skill_required){
String[] listTypes = getStringDefaultArray(mode, R.array.tr_default_skill_type_array);
resetAdapter(listTypes);
}
int intValue = json.optInt(key, 0);
if (intValue < spinner.getCount()) {
spinner.setSelection(intValue);
displayEdit.setText(getDisplayEditText());
}
}
private String getDisplayEditText() {
if(titleID == R.string.tr_set_cost_in_cents) {
return activity.getResources().getStringArray(R.array.tr_default_cost_in_cents_display)[spinner.getSelectedItemPosition()];
}
else {
return spinner.getSelectedItem().toString();
}
}
@Override
public void saveToDatabase(JSONObject json, String key) throws JSONException {
json.put(key, spinner.getSelectedItemPosition());
}
public int parseToDollars (String conversion){
int index = conversion.lastIndexOf('$');
String cents = conversion.substring(index+1);
if(TextUtils.isEmpty(cents)) return 0;
return Integer.parseInt(cents);
}
@Override
@SuppressWarnings("nls")
public void postToTaskRabbit(JSONObject json, String key) throws JSONException {
if(spinner.getSelectedItem() != null){
String spinnerString = spinner.getSelectedItem().toString();
if (titleID == R.string.tr_set_cost_in_cents) {
int cents = parseToDollars(spinnerString) *100;
json.put(key, cents);
}
else if (titleID == R.string.tr_set_named_price) {
json.put(key, parseToDollars(spinnerString));
}
else if (key.contains("description")) {
String description = json.optString("description", "");
description += String.format("\n%S %S", key, spinner.getSelectedItem().toString());
}
else {
json.put(key, spinnerString);
}
}
}
@Override
public void readFromTask(Task task) {
return;
}
@Override
protected void readFromTaskOnInitialize() {
// Nothing, we don't lazy load this control set yet
}
@Override
protected String writeToModelAfterInitialized(Task task) {
// Nothing, we don't lazy load this control set yet
return null;
}
@Override
protected void afterInflate() {
// Nothing, we don't lazy load this control set yet
}
@Override
public String writeToModel(Task task) {
return null;
}
}

@ -1,89 +0,0 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.taskrabbit;
import java.util.ArrayList;
import org.json.JSONObject;
import android.text.TextUtils;
import android.util.Log;
import com.todoroo.andlib.data.Property.StringProperty;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.sync.SyncContainer;
/**
* RTM Task Container
*
* @author Tim Su <tim@todoroo.com>
*
*/
public class TaskRabbitTaskContainer extends SyncContainer {
public static final int NO_ID = 0;
public Metadata trTask;
public TaskRabbitTaskContainer(Task task, Metadata trTask) {
this.task = task;
this.trTask = trTask;
if(this.trTask == null) {
this.trTask = TaskRabbitMetadata.createEmptyMetadata(task.getId());
}
this.metadata = new ArrayList<Metadata>();
}
public TaskRabbitTaskContainer(Task task) {
this(task, null);
}
public JSONObject getLocalTaskData() {
return getJSONData(TaskRabbitMetadata.DATA_LOCAL);
}
public JSONObject getRemoteTaskData() {
return getJSONData(TaskRabbitMetadata.DATA_REMOTE);
}
public long getTaskID() {
if(TextUtils.isEmpty(trTask.getValue(TaskRabbitMetadata.ID)))
return NO_ID;
try {
return Long.parseLong(trTask.getValue(TaskRabbitMetadata.ID));
} catch (Exception e) {
return NO_ID;
}
}
private JSONObject getJSONData(StringProperty key) {
if(trTask.containsNonNullValue(key)) {
String jsonString = trTask.getValue(key);
if (!TextUtils.isEmpty(jsonString)) {
try {
return new JSONObject(jsonString);
} catch (Exception e) {
Log.e("Task Rabbit task container", //$NON-NLS-1$
e.toString());
}
}
}
return null;
}
public void setTaskID(String taskID) {
trTask.setValue(TaskRabbitMetadata.ID, taskID);
}
public void setLocalTaskData(String taskData) {
trTask.setValue(TaskRabbitMetadata.DATA_LOCAL, taskData);
}
public void setRemoteTaskData(String taskData) {
trTask.setValue(TaskRabbitMetadata.DATA_REMOTE, taskData);
}
public boolean isTaskRabbit() {
return getTaskID() > 0;
}
}

@ -1,443 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file contains task rabbit keys and strings.
Currently does not need to be translated because it's only enabled in US
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- ============================================================ MILK == -->
<string-array name="tr_preset_types">
<item>@string/tr_type_virtual</item>
<item>@string/tr_type_food_delivery</item>
<item>@string/tr_type_cleaning</item>
<item>@string/tr_type_donations</item>
<item>@string/tr_type_delivery</item>
<item>@string/tr_type_handyman</item>
<item>@string/tr_type_shopping</item>
<item>@string/tr_type_something_else</item>
</string-array>
<!-- Preference Key (do not translate) -->
<string name="tr_type_virtual">Virtual task</string>
<string name="tr_type_food_delivery">Food Delivery</string>
<string name="tr_type_cleaning">Cleaning</string>
<string name="tr_type_donations">Donations</string>
<string name="tr_type_delivery">Delivery</string>
<string name="tr_type_handyman">Handyman</string>
<string name="tr_type_shopping">Shopping</string>
<string name="tr_type_something_else">Something else</string>
<array name="tr_default_type_array">
<item>@array/tr_default_type_virtual</item>
<item>@array/tr_default_type_food_delivery</item>
<item>@array/tr_default_type_cleaning</item>
<item>@array/tr_default_type_donations</item>
<item>@array/tr_default_type_delivery</item>
<item>@array/tr_default_type_handyman</item>
<item>@array/tr_default_type_shopping</item>
<item>@array/tr_default_type_something_else</item>
</array>
<array name="tr_default_type_virtual">
<item>-1</item>
<item>-1</item>
<item>0</item>
<item>1</item>
<item>-1</item>
<item>10</item>
<item>-1</item>
<item>0</item>
<item>2</item>
<item>0</item>
</array>
<array name="tr_default_type_food_delivery">
<item>0</item>
<item>-1</item>
<item>-1</item>
<item>-1</item>
<item>-1</item>
<item>10</item>
<item>0</item>
<item>1</item>
<item>2</item>
<item>0</item>
</array>
<array name="tr_default_type_cleaning">
<item>-1</item>
<item>0</item>
<item>-1</item>
<item>-1</item>
<item>0</item>
<item>10</item>
<item>-1</item>
<item>0</item>
<item>2</item>
<item>0</item>
</array>
<array name="tr_default_type_donations">
<item>-1</item>
<item>0</item>
<item>-1</item>
<item>-1</item>
<item>-1</item>
<item>10</item>
<item>0</item>
<item>0</item>
<item>2</item>
<item>0</item>
</array>
<array name="tr_default_type_delivery">
<item>-1</item>
<item>0</item>
<item>-1</item>
<item>-1</item>
<item>-1</item>
<item>10</item>
<item>0</item>
<item>0</item>
<item>2</item>
<item>0</item>
</array>
<array name="tr_default_type_handyman">
<item>-1</item>
<item>0</item>
<item>0</item>
<item>-1</item>
<item>-1</item>
<item>10</item>
<item>-1</item>
<item>1</item>
<item>2</item>
<item>0</item>
</array>
<array name="tr_default_type_shopping">
<item>-1</item>
<item>0</item>
<item>-1</item>
<item>-1</item>
<item>-1</item>
<item>10</item>
<item>0</item>
<item>2</item>
<item>2</item>
<item>0</item>
</array>
<array name="tr_default_type_something_else">
<item>-1</item>
<item>0</item>
<item>-1</item>
<item>-1</item>
<item>-1</item>
<item>10</item>
<item>0</item>
<item>2</item>
<item>2</item>
<item>0</item>
</array>
<!-- Preference Key (do not translate) -->
<string name="tr_attr_name">name</string>
<string name="tr_attr_id">id</string>
<!-- Preference Key (do not translate) -->
<string name="tr_attr_state">state</string>
<string name="tr_attr_state_label">state_label</string>
<!-- Preference Key (do not translate) -->
<string name="tr_attr_city">city</string>
<string name="tr_attr_city_id">city_id</string>
<string name="tr_attr_city_name">name</string>
<string name="tr_attr_city_lng">lng</string>
<string name="tr_attr_city_lat">lat</string>
<string name="tr_attr_city_virtual">virtual</string>
<string-array name="tr_default_set">
<item>@string/tr_set_name</item>
<item>@string/tr_set_location</item>
<item>@string/tr_set_skill_required</item>
<item>@string/tr_set_duration</item>
<item>@string/tr_set_supplies</item>
<item>@string/tr_set_deadline</item>
<item>@string/tr_set_drop_off</item>
<item>@string/tr_set_cost_in_cents</item>
<item>@string/tr_set_named_price</item>
<item>@string/tr_set_description</item>
</string-array>
<!-- Control set title (do not translate) -->
<string name="tr_set_type">Type</string>
<string name="tr_set_name">Restaurant Name</string>
<string name="tr_set_location">Location</string>
<string name="tr_set_skill_required">Skill Required</string>
<string name="tr_set_duration">Duration</string>
<string name="tr_set_supplies">Supplies</string>
<string name="tr_set_deadline">Deadline</string>
<string name="tr_set_drop_off">Dropoff</string>
<string name="tr_set_cost_in_cents">Expenses</string>
<string name="tr_set_named_price">I\'ll Pay</string>
<string name="tr_set_description">Description</string>
<string-array name="tr_default_set_key">
<item>@string/tr_set_key_name</item>
<item>@string/tr_set_key_location</item>
<item>@string/tr_set_key_skill_required</item>
<item>@string/tr_set_key_duration</item>
<item>@string/tr_set_key_supplies</item>
<item>@string/tr_set_key_deadline</item>
<item>@string/tr_set_key_drop_off</item>
<item>@string/tr_set_key_cost_in_cents</item>
<item>@string/tr_set_key_named_price</item>
<item>@string/tr_set_key_description</item>
</string-array>
<!-- Control set key for json (do not translate) -->
<string name="tr_set_key_type">type</string>
<string name="tr_set_key_name">name</string>
<string name="tr_set_key_location">location</string>
<string name="tr_set_key_skill_required">description:skill_required</string>
<string name="tr_set_key_duration">description:duration</string>
<string name="tr_set_key_supplies">description:supplies</string>
<string name="tr_set_key_deadline">complete_by_time</string>
<string name="tr_set_key_drop_off">location</string>
<string name="tr_set_key_cost_in_cents">cost_in_cents</string>
<string name="tr_set_key_named_price">named_price</string>
<string name="tr_set_key_description">description</string>
<array name="tr_default_array">
<item>@string/tr_set_key_name</item>
<item>@string/tr_set_key_location</item>
<item>@array/tr_default_skill_virtual</item>
<item>@array/tr_default_duration</item>
<item>@array/tr_default_supplies</item>
<item>@string/tr_set_key_deadline</item>
<item>@string/tr_set_key_location</item>
<item>@array/tr_default_cost_in_cents</item>
<item>@array/tr_default_named_price</item>
<item>@string/tr_set_key_description</item>
</array>
<!-- Default options -->
<array name="tr_default_skill_type_array">
<item>@array/tr_default_skill_virtual</item>
<item>@array/tr_default_named_price</item>
<item>@array/tr_default_named_price</item>
<item>@array/tr_default_named_price</item>
<item>@array/tr_default_named_price</item>
<item>@array/tr_default_skill_handyman</item>
<item>@array/tr_default_named_price</item>
<item>@array/tr_default_named_price</item>
</array>
<string-array name="tr_default_skill_virtual">
<item>@string/tr_default_skill_none</item>
<item>@string/tr_default_skill_research</item>
<item>@string/tr_default_skill_phone_calls</item>
<item>@string/tr_default_skill_event_planning</item>
<item>@string/tr_default_skill_usability_testing</item>
<item>@string/tr_default_skill_craigslist</item>
<item>@string/tr_default_skill_help</item>
<item>@string/tr_default_skill_ebay_help</item>
</string-array>
<string-array name="tr_default_skill_handyman">
<item>@string/tr_default_skill_none</item>
<item>@string/tr_default_skill_carpentry</item>
<item>@string/tr_default_skill_assembly_repair</item>
<item>@string/tr_default_skill_plumbing</item>
<item>@string/tr_default_skill_ikea_assembly</item>
<item>@string/tr_default_skill_heavy_lifting</item>
</string-array>
<!-- Skills Needed -->
<string name="tr_default_skill_none">None</string>
<string name="tr_default_skill_research">Research</string>
<string name="tr_default_skill_phone_calls">Phone Calls</string>
<string name="tr_default_skill_event_planning">Event Planning</string>
<string name="tr_default_skill_usability_testing">Usability Testing</string>
<string name="tr_default_skill_craigslist">Craigslist</string>
<string name="tr_default_skill_help">Help</string>
<string name="tr_default_skill_ebay_help">eBay Help</string>
<string name="tr_default_skill_carpentry">Carpentry</string>
<string name="tr_default_skill_assembly_repair">Assembly and Repair</string>
<string name="tr_default_skill_plumbing">Plumbing</string>
<string name="tr_default_skill_ikea_assembly">IKEA assembly</string>
<string name="tr_default_skill_heavy_lifting">Heavy lifting</string>
<string-array name="tr_default_supplies">
<item>@string/tr_default_supplies_provided</item>
<item>@string/tr_default_supplies_not_provided</item>
</string-array>
<!-- Supplies provided -->
<string name="tr_default_supplies_provided">Supplies will be provided</string>
<string name="tr_default_supplies_not_provided">Supplies will NOT be provided</string>
<string-array name="tr_default_cost_in_cents">
<item>@string/tr_default_cost_in_cents_0</item>
<item>@string/tr_default_cost_in_cents_25</item>
<item>@string/tr_default_cost_in_cents_50</item>
<item>@string/tr_default_cost_in_cents_100</item>
<item>@string/tr_default_cost_in_cents_101</item>
</string-array>
<string-array name="tr_default_cost_in_cents_display">
<item>@string/tr_default_cost_in_cents_0_display</item>
<item>@string/tr_default_cost_in_cents_25_display</item>
<item>@string/tr_default_cost_in_cents_50_display</item>
<item>@string/tr_default_cost_in_cents_100_display</item>
<item>@string/tr_default_cost_in_cents_101_display</item>
</string-array>
<!-- cost_in_cents -->
<string name="tr_default_cost_in_cents_0">$0</string>
<string name="tr_default_cost_in_cents_25">Less than $25</string>
<string name="tr_default_cost_in_cents_50">Less than $50</string>
<string name="tr_default_cost_in_cents_100">Less than $100</string>
<string name="tr_default_cost_in_cents_101">More than $100</string>
<!-- cost_in_cents display -->
<string name="tr_default_cost_in_cents_0_display">$0</string>
<string name="tr_default_cost_in_cents_25_display">&lt; $25</string>
<string name="tr_default_cost_in_cents_50_display">&lt; $50</string>
<string name="tr_default_cost_in_cents_100_display">&lt; $100</string>
<string name="tr_default_cost_in_cents_101_display">&gt; $100</string>
<string-array name="tr_default_duration">
<item>@string/tr_default_duration_0</item>
<item>@string/tr_default_duration_1</item>
<item>@string/tr_default_duration_3</item>
<item>@string/tr_default_duration_6</item>
<item>@string/tr_default_duration_10</item>
</string-array>
<!-- Duration -->
<string name="tr_default_duration_0">Less than 1 hour</string>
<string name="tr_default_duration_1">1 - 3 hours</string>
<string name="tr_default_duration_3">3 - 6 hours</string>
<string name="tr_default_duration_6">More than 6 hours</string>
<string name="tr_default_duration_10">I do not know</string>
<array name="tr_default_price_type_array">
<item>@array/tr_type_default_price_virtual</item>
<item>@array/tr_default_named_price</item>
<item>@array/tr_type_default_price_cleaning</item>
<item>@array/tr_default_named_price</item>
<item>@array/tr_default_named_price</item>
<item>@array/tr_type_default_price_handyman</item>
<item>@array/tr_default_named_price</item>
<item>@array/tr_default_named_price</item>
</array>
<string-array name="tr_type_default_price_virtual">
<item>$15</item>
<item>$20</item>
<item>$25</item>
<item>$30</item>
<item>$35</item>
<item>$45</item>
<item>$55</item>
</string-array>
<string-array name="tr_default_named_price">
<item>$10</item>
<item>$15</item>
<item>$20</item>
<item>$25</item>
<item>$30</item>
<item>$40</item>
<item>$50</item>
</string-array>
<string-array name="tr_type_default_price_cleaning">
<item>$40</item>
<item>$50</item>
<item>$60</item>
<item>$70</item>
<item>$80</item>
<item>$90</item>
<item>$100</item>
</string-array>
<string-array name="tr_type_default_price_handyman">
<item>$20</item>
<item>$30</item>
<item>$40</item>
<item>$45</item>
<item>$50</item>
<item>$70</item>
<item>$95</item>
</string-array>
<string name="tr_default_cost_in_cents_25_display">&lt; $25</string>
<string name="tr_default_cost_in_cents_50_display">&lt; $50</string>
<string name="tr_default_cost_in_cents_100_display">&lt; $100</string>
<string name="tr_default_cost_in_cents_101_display">&gt; $100</string>
<!-- Task Rabbit activity messages -->
<string name="tr_button_already_posted">Already Posted!</string>
<string name="tr_status_draft">draft</string>
<string name="tr_alert_title_fail">Error posting task</string>
<string name="tr_alert_message_fail">Please try again</string>
<string name="tr_alert_button_close">Close</string>
<string name="tr_alert_gps_title">Wireless Network Location Provider needs to be enabled in order to add location based tasks. Do you want to enable it?</string>
<string name="tr_alert_gps_yes">Yes</string>
<string name="tr_alert_gps_no">No</string>
<string name="tr_alert_internet_message_fail">Internet connection could not be found. Please check your connection and try again.</string>
<string name="tr_alert_intro_title">Welcome to TaskRabbit!</string>
<string name="tr_alert_intro_location">TaskRabbit is an inexpensive way to delegate tasks to trustworthy people in your area.</string>
<string name="tr_alert_intro_no_location">TaskRabbit is an inexpensive way to delegate tasks to trustworthy people but it isn\'t yet available in your location. You can use it to assign virtual tasks or tasks in <a href="http://www.taskrabbit.com/pickacity">supported locations</a></string>
<string name="tr_alert_location_not_supported_title">Location not supported</string>
<string name="tr_alert_location_not_supported_message">TaskRabbit isn\'t yet supported in your current location. Please choose a <a href="http://www.taskrabbit.com/pickacity">supported location</a> or set type to virtual before posting this task</string>
<string name="tr_default_location_name">Current Location</string>
<!-- Task Rabbit control set toast -->
<string name="tr_success_toast">Task posted to TaskRabbit successfully!</string>
<string name="tr_display_status">TaskRabbit Status</string>
<!-- Task Rabbit Map Activity -->
<string name="tr_alert_location_fail_title">No Location Found</string>
<string name="tr_alert_location_fail_message">Sorry, could not find the location for the address you entered</string>
<string name="tr_alert_location_clicked_title">Use this location</string>
<string name="tr_alert_location_clicked_message">Use this location for TaskRabbit</string>
</resources>

@ -59,9 +59,6 @@
<!-- show friends view preference -->
<string name="p_show_friends_view">show_friends_view</string>
<!-- show ideas tab preference -->
<string name="p_ideas_tab_enabled">ideas_tab_enabled</string>
<!-- force tablets to use phone layout -->
<string name="p_force_phone_layout">force_phone_layout</string>
@ -412,9 +409,6 @@
<!-- Anonymous usage statistics -->
<string name="p_statistics">statistics</string>
<!-- Ideas tab autoloading -->
<string name="p_autoIdea">ideaauto</string>
<!-- ================================================= NEW USER EXPERIENCE -->
<!-- Preference Keys (do not translate) -->

@ -86,11 +86,6 @@
android:key="@string/p_time_increment"
android:title="@string/EPr_time_increment"
android:defaultValue="true"/>
<com.todoroo.astrid.ui.MultilineCheckboxPreference
android:key="@string/p_autoIdea"
android:title="@string/EPr_ideaAuto_title"
android:defaultValue="true" />
</PreferenceScreen>

@ -21,11 +21,6 @@
android:key="@string/p_calendar_reminders"
android:title="@string/CRA_calendar_reminders_pref_title" />
<CheckBoxPreference
android:key="@string/p_ideas_tab_enabled"
android:title="@string/EPr_ideas_tab_enabled"
android:summary="@string/EPr_ideas_tab_description" />
<CheckBoxPreference
android:title="@string/EPr_cal_end_or_start_at_due_time"
android:key = "@string/p_end_at_deadline" />

@ -571,8 +571,6 @@ public class EditPreferences extends TodorooPreferenceActivity {
}
else if (booleanPreference(preference, value, R.string.p_statistics,
R.string.EPr_statistics_desc_disabled, R.string.EPr_statistics_desc_enabled));
else if (booleanPreference(preference, value, R.string.p_autoIdea,
R.string.EPr_ideaAuto_desc_disabled, R.string.EPr_ideaAuto_desc_enabled));
else if (booleanPreference(preference, value, R.string.p_field_missed_calls,
R.string.MCA_missed_calls_pref_desc_disabled, R.string.MCA_missed_calls_pref_desc_enabled));
else if (booleanPreference(preference, value, R.string.p_calendar_reminders,

@ -11,7 +11,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicReference;
import android.app.Activity;
@ -91,7 +90,6 @@ import com.todoroo.astrid.service.StatisticsService;
import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.service.ThemeService;
import com.todoroo.astrid.tags.TagsControlSet;
import com.todoroo.astrid.taskrabbit.TaskRabbitControlSet;
import com.todoroo.astrid.timers.TimerActionControlSet;
import com.todoroo.astrid.timers.TimerControlSet;
import com.todoroo.astrid.timers.TimerPlugin;
@ -106,8 +104,6 @@ import com.todoroo.astrid.ui.NestableViewPager;
import com.todoroo.astrid.ui.PopupControlSet;
import com.todoroo.astrid.ui.ReminderControlSet;
import com.todoroo.astrid.ui.TaskEditMoreControls;
import com.todoroo.astrid.ui.WebServicesView;
import com.todoroo.astrid.utility.Constants;
import com.todoroo.astrid.utility.Flags;
import com.todoroo.astrid.voice.VoiceInputAssistant;
import com.todoroo.astrid.voice.VoiceRecognizer;
@ -198,7 +194,6 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
public static final int TAB_VIEW_UPDATES = 0;
public static final int TAB_VIEW_MORE = 1;
public static final int TAB_VIEW_WEB_SERVICES = 2;
@Autowired
private ExceptionService exceptionService;
@ -226,7 +221,6 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
private ImageButton voiceAddNoteButton;
private EditPeopleControlSet peopleControlSet = null;
private TaskRabbitControlSet taskRabbitControl = null;
private EditNotesControlSet notesControlSet = null;
private HideUntilControlSet hideUntilControls = null;
private TagsControlSet tagsControlSet = null;
@ -267,8 +261,6 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
private int commentIcon = R.drawable.comment_dark_blue;
private WebServicesView webServices = null;
private int tabStyle = 0;
private boolean moreSectionHasControls;
@ -380,12 +372,7 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
long idParam = getActivity().getIntent().getLongExtra(TOKEN_ID, -1L);
boolean hasTitle = !TextUtils.isEmpty(model.getValue(Task.TITLE));
if(hasTitle && Preferences.getBoolean(R.string.p_ideas_tab_enabled, false) && Constants.MARKET_STRATEGY.allowIdeasTab())
tabStyle = (TaskEditViewPager.TAB_SHOW_ACTIVITY | TaskEditViewPager.TAB_SHOW_WEB);
else
tabStyle = TaskEditViewPager.TAB_SHOW_ACTIVITY;
tabStyle = TaskEditViewPager.TAB_SHOW_ACTIVITY;
if (!showEditComments)
tabStyle &= ~TaskEditViewPager.TAB_SHOW_ACTIVITY;
@ -407,20 +394,6 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
if (editNotes != null)
editNotes.addListener(this);
if(hasTitle) {
if(webServices == null) {
webServices = new WebServicesView(getActivity());
webServices.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
webServices.setPadding(10, 5, 10, 10);
webServices.taskRabbitControl = taskRabbitControl;
webServices.setTask(model);
} else {
webServices.refresh();
}
}
if (tabStyle == 0) {
return;
}
@ -505,11 +478,6 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
R.layout.control_set_assigned,
R.layout.control_set_default_display,
R.string.actfm_EPA_assign_label_long, REQUEST_LOG_IN);
if(Locale.getDefault().getCountry().equals("US")) { //$NON-NLS-1$
taskRabbitControl = new TaskRabbitControlSet(this, R.layout.control_set_default_display);
controls.add(taskRabbitControl);
peopleControlSet.addListener(taskRabbitControl);
}
controls.add(peopleControlSet);
controlSetMap.put(getString(R.string.TEA_ctrl_who_pref),
peopleControlSet);
@ -660,11 +628,6 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
break; // As soon as we hit the hide section, we're done
} else if (item.equals(moreSectionTrigger)) {
section = moreControls;
if (taskRabbitControl != null) {
taskRabbitControl.getDisplayView().setVisibility(View.GONE);
section.addView(taskRabbitControl.getDisplayView());
}
} else {
View controlSet = null;
TaskEditControlSet curr = controlSetMap.get(item);
@ -843,10 +806,6 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
model = null;
uuid = RemoteModel.NO_UUID;
populateFields(intent);
if (webServices != null) {
webServices.setTask(model);
webServices.reset();
}
loadMoreContainer();
}
@ -1261,9 +1220,7 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
if (editNotes == null)
instantiateEditNotes();
if (taskRabbitControl != null && taskRabbitControl.activityResult(requestCode, resultCode, data)) {
return;
} else if (editNotes != null && editNotes.activityResult(requestCode, resultCode, data)) {
if (editNotes != null && editNotes.activityResult(requestCode, resultCode, data)) {
return;
} else if (requestCode == REQUEST_VOICE_RECOG
&& resultCode == Activity.RESULT_OK) {
@ -1339,8 +1296,6 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
return TAB_VIEW_UPDATES;
case TaskEditViewPager.TAB_SHOW_MORE:
return TAB_VIEW_MORE;
case TaskEditViewPager.TAB_SHOW_WEB:
return TAB_VIEW_WEB_SERVICES;
}
// error experienced
@ -1360,10 +1315,7 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
return moreControls;
case TAB_VIEW_UPDATES:
return editNotes;
case TAB_VIEW_WEB_SERVICES:
return webServices;
}
return null;
}
@ -1378,8 +1330,6 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
case TAB_VIEW_UPDATES:
view = editNotes;
break;
case TAB_VIEW_WEB_SERVICES:
view = webServices;
}
if (view == null || mPager == null) return;
@ -1424,28 +1374,9 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
@Override
public void onPageSelected(final int position) {
final Runnable onPageSelected = new Runnable() {
@Override
public void run() {
setPagerHeightForPosition(position);
NestableScrollView scrollView = (NestableScrollView)getView().findViewById(R.id.edit_scroll);
if(getTabForPosition(position) == TAB_VIEW_WEB_SERVICES)
scrollView.setScrollabelViews(webServices.getScrollableViews());
else
scrollView.setScrollabelViews(null);
}
};
if(getTabForPosition(position) == TAB_VIEW_WEB_SERVICES)
webServices.onPageSelected(new Runnable() {
@Override
public void run() {
onPageSelected.run();
}
});
else
onPageSelected.run();
setPagerHeightForPosition(position);
NestableScrollView scrollView = (NestableScrollView)getView().findViewById(R.id.edit_scroll);
scrollView.setScrollabelViews(null);
}
@Override

@ -23,7 +23,6 @@ public class TaskEditViewPager extends PagerAdapter implements TitleProvider {
public static final int TAB_SHOW_ACTIVITY = 1 << 0;
public static final int TAB_SHOW_MORE = 1 << 1;
public static final int TAB_SHOW_WEB = 1 << 2;
public TaskEditViewPager(Context context, int tabStyleMask) {
ArrayList<String> titleList = new ArrayList<String>();
@ -31,8 +30,6 @@ public class TaskEditViewPager extends PagerAdapter implements TitleProvider {
titleList.add(context.getString(R.string.TEA_tab_activity));
if ((tabStyleMask & TAB_SHOW_MORE) > 0)
titleList.add(context.getString(R.string.TEA_tab_more));
if ((tabStyleMask & TAB_SHOW_WEB) > 0)
titleList.add(context.getString(R.string.TEA_tab_web));
titles = titleList.toArray(new String[titleList.size()]);
}

@ -109,7 +109,6 @@ import com.todoroo.astrid.subtasks.SubtasksListFragment;
import com.todoroo.astrid.subtasks.SubtasksUpdater;
import com.todoroo.astrid.sync.SyncProviderPreferences;
import com.todoroo.astrid.tags.TaskToTagMetadata;
import com.todoroo.astrid.taskrabbit.TaskRabbitMetadata;
import com.todoroo.astrid.timers.TimerPlugin;
import com.todoroo.astrid.ui.QuickAddBar;
import com.todoroo.astrid.utility.AstridPreferences;
@ -971,8 +970,6 @@ public class TaskListFragment extends SherlockListFragment implements OnScrollLi
});
}
public static final String TR_METADATA_JOIN = "for_taskrab"; //$NON-NLS-1$
public static final String TAGS_METADATA_JOIN = "for_tags"; //$NON-NLS-1$
public static final String USER_IMAGE_JOIN = "for_images"; // //$NON-NLS-1$
@ -1030,10 +1027,7 @@ public class TaskListFragment extends SherlockListFragment implements OnScrollLi
// TODO: For now, we'll modify the query to join and include the task rabbit and tag data here.
// Eventually, we might consider restructuring things so that this query is constructed elsewhere.
String joinedQuery =
Join.left(Metadata.TABLE.as(TR_METADATA_JOIN),
Criterion.and(Field.field(TR_METADATA_JOIN + "." + Metadata.KEY.name).eq(TaskRabbitMetadata.METADATA_KEY),
Task.ID.eq(Field.field(TR_METADATA_JOIN + "." + Metadata.TASK.name)))).toString()
+ Join.left(Metadata.TABLE.as(TAGS_METADATA_JOIN),
Join.left(Metadata.TABLE.as(TAGS_METADATA_JOIN),
tagsJoinCriterion).toString() //$NON-NLS-1$
+ Join.left(User.TABLE.as(USER_IMAGE_JOIN),
Task.USER_ID.eq(Field.field(USER_IMAGE_JOIN + "." + User.UUID.name))).toString()

@ -74,7 +74,6 @@ import com.todoroo.astrid.api.TaskAction;
import com.todoroo.astrid.api.TaskDecoration;
import com.todoroo.astrid.api.TaskDecorationExposer;
import com.todoroo.astrid.core.LinkActionExposer;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.RemoteModel;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.TaskAttachment;
@ -109,8 +108,6 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
public static final String BROADCAST_EXTRA_TASK = "model"; //$NON-NLS-1$
@SuppressWarnings("nls")
private static final LongProperty TASK_RABBIT_ID = Metadata.ID.cloneAs(TaskListFragment.TR_METADATA_JOIN, "taskRabId");
@SuppressWarnings("nls")
private static final StringProperty TAGS = new StringProperty(null, "group_concat(" + TaskListFragment.TAGS_METADATA_JOIN + "." + TaskToTagMetadata.TAG_NAME.name + ", ' | ')").as("tags");
@SuppressWarnings("nls")
@ -145,7 +142,6 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
Task.SOCIAL_REMINDER,
PICTURE,
HAS_NOTES_PROPERTY, // Whether or not the task has notes
TASK_RABBIT_ID, // Task rabbit metadata id (non-zero means it exists)
TAGS, // Concatenated list of tags
FILE_ID_PROPERTY // File id
};
@ -415,7 +411,6 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
ViewHolder viewHolder = ((ViewHolder)view.getTag());
if (!titleOnlyLayout) {
viewHolder.isTaskRabbit = (cursor.get(TASK_RABBIT_ID) > 0);
viewHolder.tagsString = cursor.get(TAGS);
viewHolder.imageUrl = RemoteModel.PictureHelper.getPictureUrlFromCursor(cursor, PICTURE, RemoteModel.PICTURE_THUMB);
viewHolder.hasFiles = cursor.get(FILE_ID_PROPERTY) > 0;
@ -463,7 +458,6 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
public LinearLayout taskRow;
public View taskActionContainer;
public ImageView taskActionIcon;
public boolean isTaskRabbit; // From join query, not part of the task model
public String tagsString; // From join query, not part of the task model
public String imageUrl; // From join query, not part of the task model
public boolean hasFiles; // From join query, not part of the task model
@ -1120,7 +1114,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
// image view
final AsyncImageView pictureView = viewHolder.picture; {
if (pictureView != null) {
if(Task.USER_ID_SELF.equals(task.getValue(Task.USER_ID)) && !viewHolder.isTaskRabbit) {
if(Task.USER_ID_SELF.equals(task.getValue(Task.USER_ID))) {
pictureView.setVisibility(View.GONE);
if (viewHolder.pictureBorder != null)
viewHolder.pictureBorder.setVisibility(View.GONE);
@ -1129,9 +1123,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
if (viewHolder.pictureBorder != null)
viewHolder.pictureBorder.setVisibility(View.VISIBLE);
pictureView.setUrl(null);
if (viewHolder.isTaskRabbit) {
pictureView.setDefaultImageResource(R.drawable.task_rabbit_image);
} else if (Task.USER_ID_UNASSIGNED.equals(task.getValue(Task.USER_ID)))
if (Task.USER_ID_UNASSIGNED.equals(task.getValue(Task.USER_ID)))
pictureView.setDefaultImageDrawable(ResourceDrawableCache.getImageDrawableFromId(resources, R.drawable.icn_anyone_transparent));
else {
pictureView.setDefaultImageDrawable(ResourceDrawableCache.getImageDrawableFromId(resources, R.drawable.icn_default_person_image));

@ -193,7 +193,6 @@ public abstract class MarketStrategy {
R.string.p_voicePrefSection,
R.string.p_end_at_deadline,
R.string.p_field_missed_calls,
R.string.p_ideas_tab_enabled,
R.string.p_rmd_vibrate,
R.string.gcal_p_default,
R.string.p_theme_widget,

@ -1,651 +0,0 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.ui;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.timsu.astrid.R;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.service.ExceptionService;
import com.todoroo.andlib.service.RestClient;
import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.helper.AmazonRequestsHelper;
import com.todoroo.astrid.helper.AsyncImageView;
import com.todoroo.astrid.service.StatisticsConstants;
import com.todoroo.astrid.service.StatisticsService;
import com.todoroo.astrid.taskrabbit.TaskRabbitControlSet;
import com.todoroo.astrid.utility.Constants;
import com.todoroo.astrid.utility.StringEscapeUtils;
@SuppressWarnings("nls")
public class WebServicesView extends LinearLayout {
private static final String ASSOCIATE_TAG = "wwwtodoroocom-20";
private static final int ROW_HEIGHT = 100;
private static final int ID_AMAZON = 0x3423712;
private static final int ID_GOOGLE = 0x3487532;
private static final String GOOGLE_SEARCH_URL = "https://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=";
private Task task;
private final DisplayMetrics metrics = new DisplayMetrics();
private LayoutInflater inflater;
private Activity activity;
public TaskRabbitControlSet taskRabbitControl;
private final AtomicBoolean notConnected = new AtomicBoolean(false);
private boolean pageLoaded = false;
private LinearLayout.LayoutParams rowParams;
@Autowired RestClient restClient;
@Autowired ExceptionService exceptionService;
public WebServicesView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialize();
}
public WebServicesView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}
public WebServicesView(Context context) {
super(context);
initialize();
}
public void setTask(Task task) {
this.task = task;
}
public int[] getScrollableViews() {
return new int[] { ID_AMAZON, ID_GOOGLE };
}
/**
* Initialize view
*/
private void initialize() {
DependencyInjectionService.getInstance().inject(this);
setOrientation(LinearLayout.VERTICAL);
activity = (Activity) getContext();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
inflater = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
rowParams = new LinearLayout.LayoutParams(
Math.round(metrics.widthPixels * 0.75f),
Math.round(ROW_HEIGHT * metrics.density));
rowParams.rightMargin = Math.round(10 * metrics.density);
if (!Preferences.getBoolean(R.string.p_autoIdea, true)) {
View loadButton = inflater.inflate(R.layout.web_services_load_button, null);
initializeTaskRabbit();
addView(loadButton);
loadButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
refresh();
}
});
}
}
public void reset() {
if (!Preferences.getBoolean(R.string.p_autoIdea, true)) {
removeAllViews();
initialize();
} else {
refresh();
}
}
public void onPageSelected(Runnable runnable) {
if(!pageLoaded && Preferences.getBoolean(R.string.p_autoIdea, true))
refresh();
runnable.run();
}
public void refresh() {
if(TextUtils.isEmpty(task.getValue(Task.TITLE)))
return;
pageLoaded = true;
removeAllViews();
initializeTaskRabbit();
initializeAmazon();
addSectionDivider();
initializeGoogleSearch();
}
private void showNotConnected() {
ImageView imageView = new ImageView(getContext());
imageView.setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
imageView.setImageResource(R.drawable.icon);
imageView.setPadding(20, 50, 20, 20);
imageView.setScaleType(ScaleType.CENTER);
addView(imageView);
TextView textView = new TextView(getContext());
textView.setTextAppearance(getContext(), R.style.TextAppearance_Medium);
textView.setText(R.string.WSV_not_online);
textView.setGravity(Gravity.CENTER);
textView.setPadding(20, 50, 20, 20);
addView(textView);
}
protected void initializeAmazon() {
addSectionHeader("Amazon.com");
final LinearLayout body = addHorizontalScroller(ID_AMAZON);
new Thread() {
@Override
public void run() {
try {
AmazonRequestsHelper helper = AmazonRequestsHelper.getInstance(
Constants.AWS_ENDPOINT, Constants.AWS_ACCESS_KEY_ID,
Constants.AWS_SECRET_KEY_ID);
Map<String, String> params = new HashMap<String, String>();
params.put("Service", "AWSECommerceService");
params.put("Version", "2011-08-01");
params.put("Operation", "ItemSearch");
params.put("Availability", "Available");
params.put("ResponseGroup", "Medium");
params.put("Keywords", task.getValue(Task.TITLE));
params.put("SearchIndex", "All");
params.put("AssociateTag", ASSOCIATE_TAG);
String requestUrl = helper.sign(params);
String result = restClient.get(requestUrl);
activity.runOnUiThread(new AmazonSearchResultsProcessor(body,
result));
} catch (Exception e) {
displayError(e, body);
}
}
}.start();
}
private class AmazonSearchResultsProcessor implements Runnable {
private final LinearLayout body;
private final String searchResults;
public AmazonSearchResultsProcessor(LinearLayout body,
String searchResults) {
this.body = body;
this.searchResults = searchResults;
}
@Override
public void run() {
try {
body.removeAllViews();
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(new StringReader(searchResults));
int eventType = xpp.getEventType();
HashMap<String, String> attributes = new HashMap<String, String>();
ArrayList<String> authors = new ArrayList<String>();
while (eventType != XmlPullParser.END_DOCUMENT) {
if(eventType == XmlPullParser.START_TAG) {
if("Title".equals(xpp.getName()))
attributes.put("title", xpp.nextText());
else if("FormattedPrice".equals(xpp.getName()))
attributes.put("price", xpp.nextText());
else if("DetailPageURL".equals(xpp.getName()))
attributes.put("url", xpp.nextText());
else if("Brand".equals(xpp.getName()) ||
"Studio".equals(xpp.getName()) ||
"Label".equals(xpp.getName()))
attributes.put("subtitle", xpp.nextText());
else if("Author".equals(xpp.getName()) ||
"Director".equals(xpp.getName()) ||
"Artist".equals(xpp.getName()))
authors.add(xpp.nextText());
else if("MediumImage".equals(xpp.getName())) {
xpp.next();
attributes.put("image", xpp.nextText());
}
else if("LowestNewPrice".equals(xpp.getName())) {
xpp.next();
attributes.put("lowestNew", xpp.nextText());
}
else if("LowestUsedPrice".equals(xpp.getName())) {
xpp.next();
attributes.put("lowestUsed", xpp.nextText());
}
else if("TotalNew".equals(xpp.getName()))
attributes.put("totalNew", xpp.nextText());
else if("TotalUsed".equals(xpp.getName()))
attributes.put("totalUsed", xpp.nextText());
else if("Error".equals(xpp.getName())) {
xpp.next();
String code = xpp.nextText();
String message = xpp.nextText();
throw new AmazonException(code, message);
}
} else if(eventType == XmlPullParser.END_TAG) {
if("Item".equals(xpp.getName())) {
renderItem(attributes, authors);
attributes.clear();
authors.clear();
}
}
eventType = xpp.next();
}
} catch (AmazonException e) {
if(!"AWS.ECommerceService.NoExactMatches".equals(e.getCode()))
exceptionService.reportError("amazon-error", e);
} catch (Exception e) {
exceptionService.reportError("amazon-other-error", e);
}
try {
String moreLabel = "Show all results";
String url = String.format("http://www.amazon.com/s/?field-keywords=%s&tag=%s",
URLEncoder.encode(task.getValue(Task.TITLE), "UTF-8"), ASSOCIATE_TAG);
View view = inflateRow(body, null, moreLabel, "",
new LinkTag(url, "amazon-more", null));
view.setBackgroundColor(Color.argb(128, 128, 128, 128));
} catch (UnsupportedEncodingException e) {
//
}
}
private void renderItem(HashMap<String, String> attributes,
ArrayList<String> authors) {
View view = inflater.inflate(R.layout.web_service_amazon_row, body, false);
((AsyncImageView)view.findViewById(R.id.image)).setUrl(
attributes.get("image"));
((TextView)view.findViewById(R.id.title)).setText(
attributes.get("title"));
((TextView)view.findViewById(R.id.price)).setText(
attributes.get("price"));
view.setTag(new LinkTag(attributes.get("url"),
"amazon", attributes.get("price")));
String subtitle = attributes.get("subtitle");
if(authors.size() > 0) {
StringBuilder sb = new StringBuilder();
for(String author : authors) {
sb.append(author).append(", ");
}
subtitle = sb.toString().substring(0, sb.length() - 2);
}
((TextView)view.findViewById(R.id.subtitle)).setText(subtitle);
String newAndUsed = null;
if(attributes.containsKey("lowestNew") || attributes.containsKey("lowestUsed")) {
int lowestNew = Integer.MAX_VALUE;
try {
lowestNew = attributes.containsKey("lowestNew") ?
Integer.parseInt(attributes.get("lowestNew")) : Integer.MAX_VALUE;
} catch (NumberFormatException e) {
// text, i.e. "too low to display"
}
int lowestUsed = Integer.MAX_VALUE;
try {
lowestUsed = attributes.containsKey("lowestUsed") ?
Integer.parseInt(attributes.get("lowestUsed")) : Integer.MAX_VALUE;
} catch (NumberFormatException e) {
// text, i.e. "too low to display"
}
int lowest = Math.min(lowestNew, lowestUsed);
int total = 0;
if(attributes.containsKey("totalNew"))
total += Integer.parseInt(attributes.get("totalNew"));
if(attributes.containsKey("totalUsed"))
total += Integer.parseInt(attributes.get("totalUsed"));
String price = String.format("$%.2f", lowest / 100f);
if(!price.equals(attributes.get("price")))
newAndUsed = String.format("%d New & Used from %s", total, price);
}
((TextView)view.findViewById(R.id.new_and_used)).setText(newAndUsed);
view.setOnClickListener(linkClickListener);
view.setLayoutParams(rowParams);
body.addView(view);
}
}
private class AmazonException extends Exception {
private static final long serialVersionUID = -6974618119363113454L;
private final String code;
public AmazonException(String code, String message) {
super(message);
this.code = code;
}
public String getCode() {
return code;
}
}
/**
* Initialize Google search results
*/
protected void initializeGoogleSearch() {
addSectionHeader("Google Search");
final LinearLayout body = addHorizontalScroller(ID_GOOGLE);
new Thread() {
@Override
public void run() {
try {
String url = GOOGLE_SEARCH_URL +
URLEncoder.encode(task.getValue(Task.TITLE), "UTF-8");
String result = restClient.get(url);
final JSONObject searchResults = new JSONObject(result);
activity.runOnUiThread(new GoogleSearchResultsProcessor(body,
searchResults.getJSONObject("responseData")));
} catch (Exception e) {
displayError(e, body);
}
}
}.start();
}
private class GoogleSearchResultsProcessor implements Runnable {
private final LinearLayout body;
private final JSONObject searchResults;
public GoogleSearchResultsProcessor(LinearLayout body,
JSONObject searchResults) {
this.body = body;
this.searchResults = searchResults;
}
public void run() {
body.removeAllViews();
try {
JSONArray results = searchResults.getJSONArray("results");
for(int i = 0; i < results.length(); i++) {
JSONObject result = results.getJSONObject(i);
String title = StringEscapeUtils.unescapeHtml(result.getString("titleNoFormatting"));
inflateRow(body, null, title,
result.getString("visibleUrl"),
new LinkTag(result.getString("url"),
"google", null));
}
JSONObject cursor = searchResults.getJSONObject("cursor");
String moreLabel = "Show more results";
if(results.length() == 0)
moreLabel = "Search Google";
String url = cursor.getString("moreResultsUrl");
View view = inflateRow(body, null, moreLabel, "",
new LinkTag(url, "google-more", null));
view.setBackgroundColor(Color.argb(128, 128, 128, 128));
} catch (JSONException e) {
displayError(e, body);
}
}
}
/**
* Initialize Google search results
*/
protected void initializeTaskRabbit() {
if(taskRabbitControl != null && taskRabbitControl.isEnabledForTRLocation == true) {
addSectionHeader("Outsource this task to someone");
final LinearLayout body = new LinearLayout(activity);
body.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,
ROW_HEIGHT));
body.setOrientation(LinearLayout.VERTICAL);
ImageView imageView = new ImageView(getContext());
imageView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
ROW_HEIGHT));
imageView.setImageResource(R.drawable.task_rabbit_logo);
imageView.setScaleType(ScaleType.CENTER_INSIDE);
body.addView(imageView);
body.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
taskRabbitControl.showTaskRabbitActivity();
}
});
addView(body);
addSectionDivider();
}
}
protected View inflateRow(ViewGroup body, String imageUrl, String title, String subtitle,
LinkTag tag) {
View view = inflater.inflate(R.layout.web_service_row, body, false);
AsyncImageView imageView = (AsyncImageView)view.findViewById(R.id.image);
if(imageUrl == null)
imageView.setVisibility(View.GONE);
else
imageView.setUrl(imageUrl);
((TextView)view.findViewById(R.id.title)).setText(title);
((TextView)view.findViewById(R.id.subtitle)).setText(subtitle);
view.setOnClickListener(linkClickListener);
view.setTag(tag);
view.setLayoutParams(rowParams);
body.addView(view);
return view;
}
private class LinkTag {
private final String url;
private final String service;
private String price;
public LinkTag(String url, String servce, String price) {
this.url = url;
this.service = servce;
this.price = price;
}
}
public OnClickListener linkClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
if(v.getTag() instanceof LinkTag) {
LinkTag tag = (LinkTag) v.getTag();
if(tag.price != null) {
try {
double price = Double.parseDouble(tag.price.replaceAll("[^.\\d]", ""));
if(price < 5)
tag.price = "$0 - $4";
else if(price < 10)
tag.price = "$5 - $9";
else if(price < 25)
tag.price = "$10 - $24";
else if(price < 50)
tag.price = "$25 - $49";
else if(price < 100)
tag.price = "$50 - $99";
else if(price < 500)
tag.price = "$100 - $499";
else
tag.price = "$500+";
} catch(Exception e) {
tag.price = null;
}
}
StatisticsService.reportEvent(StatisticsConstants.IDEAS_LINK_CLICKED,
"service", tag.service, "price", tag.price);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(tag.url));
activity.startActivity(intent);
}
}
};
protected void displayError(final Exception exception, final LinearLayout body) {
if(exception instanceof IOException) {
if(notConnected.getAndSet(true))
return;
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
removeAllViews();
initializeTaskRabbit();
showNotConnected();
}
});
return;
}
exceptionService.reportError("web-service-error", exception);
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
body.removeAllViews();
if (Constants.DEBUG) {
TextView textView = new TextView(getContext());
textView.setTextAppearance(getContext(), R.style.TextAppearance_Medium);
textView.setText(exception.getClass().getSimpleName() + ": " +
exception.getLocalizedMessage());
textView.setLines(2);
body.addView(textView);
}
}
});
}
protected LinearLayout addHorizontalScroller(int id) {
HorizontalScrollView scroll = new HorizontalScrollView(getContext());
scroll.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
scroll.setId(id);
scroll.setScrollbarFadingEnabled(false);
addView(scroll);
LinearLayout body = new LinearLayout(getContext());
body.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT,
Math.round(ROW_HEIGHT * metrics.density)));
scroll.addView(body);
ProgressBar progressBar = new ProgressBar(getContext());
progressBar.setIndeterminate(true);
LayoutParams layoutParams = new LinearLayout.LayoutParams(metrics.widthPixels,
Math.round(10 * metrics.density));
layoutParams.gravity = Gravity.CENTER;
progressBar.setLayoutParams(layoutParams);
progressBar.setIndeterminateDrawable(getResources().getDrawable(
android.R.drawable.progress_indeterminate_horizontal));
body.addView(progressBar);
return body;
}
private View addSectionDivider() {
View view = new View(getContext());
LayoutParams mlp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 1);
mlp.setMargins(10, 20, 10, 20);
view.setLayoutParams(mlp);
view.setBackgroundColor(Color.GRAY);
addView(view);
return view;
}
private void addSectionHeader(String string) {
TextView textView = new TextView(getContext());
textView.setText(string);
textView.setTextAppearance(getContext(), R.style.TextAppearance_GEN_EditLabel);
addView(textView);
}
}

@ -99,9 +99,6 @@ public class AstridDefaultPreferenceSpec extends AstridPreferenceSpec {
setPreference(prefs, editor, r, R.string.p_rmd_persistent, true, ifUnset);
setPreference(prefs, editor, r, R.string.p_ideas_tab_enabled, false, ifUnset);
setPreference(prefs, editor, r, R.string.p_autoIdea, false, ifUnset);
setPreference(prefs, editor, r, R.string.p_show_today_filter, true, ifUnset);
setPreference(prefs, editor, r, R.string.p_show_recently_modified_filter, true, ifUnset);
setPreference(prefs, editor, r, R.string.p_show_ive_assigned_filter, true, ifUnset);

@ -87,9 +87,6 @@ public class AstridLitePreferenceSpec extends AstridPreferenceSpec {
setPreference(prefs, editor, r, R.string.p_rmd_persistent, true, ifUnset);
setPreference(prefs, editor, r, R.string.p_ideas_tab_enabled, false, ifUnset);
setPreference(prefs, editor, r, R.string.p_autoIdea, false, ifUnset);
setPreference(prefs, editor, r, R.string.p_calendar_reminders, true, ifUnset);
setPreference(prefs, editor, r, R.string.p_use_filters, false, ifUnset);

Loading…
Cancel
Save