mirror of https://github.com/tasks/tasks
Deleted all the taskrabbit and ideas tab code
parent
ed28d46293
commit
d97f5c2a06
@ -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">< $25</string>
|
|
||||||
<string name="tr_default_cost_in_cents_50_display">< $50</string>
|
|
||||||
<string name="tr_default_cost_in_cents_100_display">< $100</string>
|
|
||||||
<string name="tr_default_cost_in_cents_101_display">> $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">< $25</string>
|
|
||||||
<string name="tr_default_cost_in_cents_50_display">< $50</string>
|
|
||||||
<string name="tr_default_cost_in_cents_100_display">< $100</string>
|
|
||||||
<string name="tr_default_cost_in_cents_101_display">> $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>
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue