diff --git a/astrid/AndroidManifest.xml b/astrid/AndroidManifest.xml
index 452ff2be2..16bf4d4ec 100644
--- a/astrid/AndroidManifest.xml
+++ b/astrid/AndroidManifest.xml
@@ -54,7 +54,7 @@
+ android:label="@string/app_name" android:debuggable="true">
@@ -337,11 +337,7 @@
-
-
-
-
+ android:theme="@style/Theme" />
diff --git a/astrid/common-src/com/todoroo/andlib/data/AbstractModel.java b/astrid/common-src/com/todoroo/andlib/data/AbstractModel.java
index 7bba4e675..cd3a3f6db 100644
--- a/astrid/common-src/com/todoroo/andlib/data/AbstractModel.java
+++ b/astrid/common-src/com/todoroo/andlib/data/AbstractModel.java
@@ -338,7 +338,12 @@ public abstract class AbstractModel implements Parcelable {
public synchronized void save(Property> property, ContentValues newStore, Object value) {
this.store = newStore;
- property.accept(this, value);
+
+ // we don't allow null values, as they indicate unset properties
+ // when the database was written
+
+ if(value != null)
+ property.accept(this, value);
}
public Void visitDouble(Property property, Object value) {
diff --git a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevControlSet.java b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevControlSet.java
index 86e6de628..26e7feeac 100644
--- a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevControlSet.java
+++ b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevControlSet.java
@@ -59,6 +59,8 @@ public class ProducteevControlSet implements TaskEditControlSet {
@Autowired
MetadataService metadataService;
+ private int lastDashboardSelection = 0;
+
public ProducteevControlSet(final Activity activity, ViewGroup parent) {
DependencyInjectionService.getInstance().inject(this);
@@ -92,10 +94,10 @@ public class ProducteevControlSet implements TaskEditControlSet {
dialog.cancel();
} else {
// create the real dashboard, select it in the spinner and refresh responsiblespinner
- ProgressDialog progressDialog = null;
+ ProgressDialog progressDialog = dialogUtilites.progressDialog(context,
+ context.getString(R.string.DLG_wait));
try {
- progressDialog = dialogUtilites.progressDialog(context,
- context.getString(R.string.DLG_wait));
+ progressDialog.show();
JSONObject newDashJSON = ProducteevSyncProvider.getInvoker().dashboardsCreate(newDashboardName).getJSONObject("dashboard");
StoreObject local = ProducteevDataService.getInstance().updateDashboards(newDashJSON, true);
if (local != null) {
@@ -127,6 +129,7 @@ public class ProducteevControlSet implements TaskEditControlSet {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
+ dashboardSelector.setSelection(lastDashboardSelection);
}
};
dialogUtilites.viewDialog(ProducteevControlSet.this.activity,
@@ -136,6 +139,7 @@ public class ProducteevControlSet implements TaskEditControlSet {
cancelListener);
} else {
refreshResponsibleSpinner(dashboard.getUsers());
+ lastDashboardSelection = position;
}
}
diff --git a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevDetailExposer.java b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevDetailExposer.java
index 5362eaa45..545a3f822 100644
--- a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevDetailExposer.java
+++ b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevDetailExposer.java
@@ -7,6 +7,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import com.timsu.astrid.R;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.astrid.adapter.TaskAdapter;
import com.todoroo.astrid.api.AstridApiConstants;
@@ -64,6 +65,9 @@ public class ProducteevDetailExposer extends BroadcastReceiver implements Detail
long responsibleId = -1;
if(metadata.containsNonNullValue(ProducteevTask.RESPONSIBLE_ID))
responsibleId = metadata.getValue(ProducteevTask.RESPONSIBLE_ID);
+ long creatorId = -1;
+ if(metadata.containsNonNullValue(ProducteevTask.CREATOR_ID))
+ creatorId = metadata.getValue(ProducteevTask.CREATOR_ID);
// display dashboard if not "no sync" or "default"
StoreObject ownerDashboard = null;
@@ -86,14 +90,21 @@ public class ProducteevDetailExposer extends BroadcastReceiver implements Detail
// display responsible user if not current one
if(responsibleId > 0 && ownerDashboard != null && responsibleId !=
Preferences.getLong(ProducteevUtilities.PREF_USER_ID, 0L)) {
- String users = ";" + ownerDashboard.getValue(ProducteevDashboard.USERS); //$NON-NLS-1$
- int index = users.indexOf(";" + responsibleId + ","); //$NON-NLS-1$ //$NON-NLS-2$
- if(index > -1) {
- String user = users.substring(users.indexOf(',', index) + 1,
- users.indexOf(';', index + 1));
+ String user = getUserFromDashboard(ownerDashboard, responsibleId);
+ if(user != null)
builder.append(" ").append(user).append(TaskAdapter.DETAIL_SEPARATOR); //$NON-NLS-1$
- }
}
+
+ // display creator user if not the current one
+ if(creatorId > 0 && ownerDashboard != null && creatorId !=
+ Preferences.getLong(ProducteevUtilities.PREF_USER_ID, 0L)) {
+ String user = getUserFromDashboard(ownerDashboard, creatorId);
+ if(user != null)
+ builder.append(" ").append( //$NON-NLS-1$
+ context.getString(R.string.producteev_PDE_task_from, user)).
+ append(TaskAdapter.DETAIL_SEPARATOR);
+ }
+
} else {
TodorooCursor notesCursor = ProducteevDataService.getInstance().getTaskNotesCursor(id);
try {
@@ -112,6 +123,16 @@ public class ProducteevDetailExposer extends BroadcastReceiver implements Detail
return result.substring(0, result.length() - TaskAdapter.DETAIL_SEPARATOR.length());
}
+ /** Try and find user in the dashboard. return null if un-findable */
+ private String getUserFromDashboard(StoreObject dashboard, long userId) {
+ String users = ";" + dashboard.getValue(ProducteevDashboard.USERS); //$NON-NLS-1$
+ int index = users.indexOf(";" + userId + ","); //$NON-NLS-1$ //$NON-NLS-2$
+ if(index > -1)
+ return users.substring(users.indexOf(',', index) + 1,
+ users.indexOf(';', index + 1));
+ return null;
+ }
+
@Override
public String getPluginIdentifier() {
return ProducteevUtilities.IDENTIFIER;
diff --git a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevFilterExposer.java b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevFilterExposer.java
index a5bc993a0..384547c5c 100644
--- a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevFilterExposer.java
+++ b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevFilterExposer.java
@@ -3,8 +3,8 @@
*/
package com.todoroo.astrid.producteev;
-import java.util.Map.Entry;
import java.util.TreeMap;
+import java.util.Map.Entry;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
@@ -39,7 +39,7 @@ public class ProducteevFilterExposer extends BroadcastReceiver {
/**
* @param context
*/
- private Filter filterFromList(Context context, ProducteevDashboard dashboard) {
+ public static Filter filterFromList(Context context, ProducteevDashboard dashboard) {
String dashboardTitle = dashboard.getName();
String title = dashboard.getName();
ContentValues values = new ContentValues();
diff --git a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevUtilities.java b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevUtilities.java
index f73a39823..6d3e0e669 100644
--- a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevUtilities.java
+++ b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevUtilities.java
@@ -41,6 +41,10 @@ public class ProducteevUtilities extends SyncProviderUtilities {
public static final String PREF_SERVER_LAST_SYNC = IDENTIFIER + "_last_server"; //$NON-NLS-1$
+ public static final String PREF_SERVER_LAST_NOTIFICATION = IDENTIFIER + "_last_notification"; //$NON-NLS-1$
+
+ public static final String PREF_SERVER_LAST_ACTIVITY = IDENTIFIER + "_last_activity"; //$NON-NLS-1$
+
/** Producteev user's default dashboard. This is different from the
* preference key, which indicates where user wants to put new tasks */
public static final String PREF_DEFAULT_DASHBOARD = IDENTIFIER + "_defaultdash"; //$NON-NLS-1$
diff --git a/astrid/plugin-src/com/todoroo/astrid/producteev/api/ProducteevInvoker.java b/astrid/plugin-src/com/todoroo/astrid/producteev/api/ProducteevInvoker.java
index 1448456b9..9d2995f40 100644
--- a/astrid/plugin-src/com/todoroo/astrid/producteev/api/ProducteevInvoker.java
+++ b/astrid/plugin-src/com/todoroo/astrid/producteev/api/ProducteevInvoker.java
@@ -111,6 +111,31 @@ public class ProducteevInvoker {
"since", since), "dashboards");
}
+ /**
+ * create a dasbhoard
+ *
+ * @param name
+ * @return the new created dashboard as JSONObject
+ */
+ public JSONObject dashboardsCreate(String name) throws ApiServiceException, IOException {
+ return callAuthenticated("dashboards/create.json",
+ "token", token,
+ "title", name);
+ }
+
+ /**
+ * return the list of users who can access a specific dashboard
+ *
+ * @param idDashboard
+ * @param dashboard array-information about the dashboard, if this ...
+ */
+ public JSONArray dashboardsAccess(long idDashboard, String dashboard) throws ApiServiceException, IOException {
+ return getResponse(callAuthenticated("dashboards/access.json",
+ "token", token,
+ "id_dashboard", idDashboard,
+ "dashboard", dashboard),"dashboard");
+ }
+
// --- tasks
/**
@@ -374,44 +399,49 @@ public class ProducteevInvoker {
"title", title);
}
- // --- users
+ // --- notifications/activities
/**
- * get a user
+ * get every activities
*
- * @param idColleague
- *
- * @return array information about the user
+ * @param dashboardId (optional) if not null, this function only returns notifications for this specific dashboard
+ * @param lastId (optional) this function returns only activities later than this id
*/
- public JSONObject usersView(Long idColleague) throws ApiServiceException, IOException {
- return callAuthenticated("users/view.json",
+ public JSONArray activitiesShowActivities(Long dashboardId, Long lastId) throws ApiResponseParseException, ApiServiceException, IOException {
+ return getResponse(callAuthenticated("activities/show_activities.json",
"token", token,
- "id_colleague", idColleague);
+ "id_dashboard", dashboardId,
+ "last_id", lastId), "activities");
}
/**
- * create a dasbhoard
- *
- * @param name
- * @return the new created dashboard as JSONObject
+ * get every notification for the current user
+ * @param dashboardId
+ * @param lastId
+ * @return
+ * @throws ApiResponseParseException
+ * @throws ApiServiceException
+ * @throws IOException
*/
- public JSONObject dashboardsCreate(String name) throws ApiServiceException, IOException {
- return callAuthenticated("dashboards/create.json",
- "token", token,
- "title", name);
+ public JSONArray activitiesShowNotifications(Long dashboardId, Long lastId) throws ApiResponseParseException, ApiServiceException, IOException {
+ return getResponse(callAuthenticated("activities/show_notifications.json",
+ "token", token,
+ "id_dashboard", dashboardId,
+ "last_id", lastId), "activities");
}
+ // --- users
/**
- * return the list of users who can access a specific dashboard
+ * get a user
*
- * @param idDashboard
- * @param dashboard array-information about the dashboard, if this ...
+ * @param idColleague
+ *
+ * @return array information about the user
*/
- public JSONArray dashboardsAccess(long idDashboard, String dashboard) throws ApiServiceException, IOException {
- return getResponse(callAuthenticated("dashboards/access.json",
- "token", token,
- "id_dashboard", idDashboard,
- "dashboard", dashboard),"dashboard");
+ public JSONObject usersView(Long idColleague) throws ApiServiceException, IOException {
+ return callAuthenticated("users/view.json",
+ "token", token,
+ "id_colleague", idColleague);
}
// --- invocation
diff --git a/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevSyncProvider.java b/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevSyncProvider.java
index a1558ba1f..b4d7f5834 100644
--- a/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevSyncProvider.java
+++ b/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevSyncProvider.java
@@ -27,15 +27,19 @@ import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.service.ExceptionService;
+import com.todoroo.andlib.service.NotificationManager;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.andlib.utility.DialogUtilities;
+import com.todoroo.astrid.activity.ShortcutActivity;
import com.todoroo.astrid.api.AstridApiConstants;
+import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.TaskContainer;
import com.todoroo.astrid.common.SyncProvider;
import com.todoroo.astrid.model.Metadata;
import com.todoroo.astrid.model.StoreObject;
import com.todoroo.astrid.model.Task;
+import com.todoroo.astrid.producteev.ProducteevFilterExposer;
import com.todoroo.astrid.producteev.ProducteevLoginActivity;
import com.todoroo.astrid.producteev.ProducteevPreferences;
import com.todoroo.astrid.producteev.ProducteevUtilities;
@@ -46,6 +50,7 @@ import com.todoroo.astrid.producteev.api.ProducteevInvoker;
import com.todoroo.astrid.rmilk.data.MilkNote;
import com.todoroo.astrid.service.AstridDependencyInjector;
import com.todoroo.astrid.tags.TagService;
+import com.todoroo.astrid.utility.Constants;
import com.todoroo.astrid.utility.Preferences;
@SuppressWarnings("nls")
@@ -85,6 +90,9 @@ public class ProducteevSyncProvider extends SyncProvider notificationsList = parseActivities(notifications);
+ // update lastIds
+ if (notifications.length() > 0) {
+ lastNotificationId = ""+notifications.getJSONObject(0).getJSONObject("activity").getLong("id_activity");
+ }
+
+// JSONArray activities = invoker.activitiesShowActivities(null, (lastActivityId == 0 ? null : new Long(lastActivityId)));
+// int activitiesCount = (activities == null ? 0 : activities.length());
+// ArrayList activitiesList = parseActivities(activities);
+// // update lastIds
+// if (activities.length() > 0) {
+// lastActivityId = activities.getJSONObject(0).getJSONObject("activity").getLong("id_activity");
+// }
+
+ // display notifications from producteev-log
+ Context context = ContextManager.getContext();
+ final NotificationManager nm = new NotificationManager.AndroidNotificationManager(context);
+ for (int i = 0; i< notificationsList.size(); i++) {
+ long id_dashboard = notifications.getJSONObject(i).getJSONObject("activity").getLong("id_dashboard");
+ String dashboardName = null;
+ StoreObject[] dashboardsData = ProducteevDataService.getInstance().getDashboards();
+ ProducteevDashboard dashboard = null;
+ if (dashboardsData != null) {
+ for (int j=0; i]+>", "");
+ PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
+ notification.setLatestEventInfo(context, contentTitle, message, contentIntent);
+
+ nm.notify(Constants.NOTIFICATION_PRODUCTEEV_NOTIFICATIONS-i, notification);
+ }
+ }
+
+ // store lastIds in Preferences
+ Preferences.setString(ProducteevUtilities.PREF_SERVER_LAST_NOTIFICATION, lastNotificationId);
+ Preferences.setString(ProducteevUtilities.PREF_SERVER_LAST_ACTIVITY, lastActivityId);
+
FlurryAgent.onEvent("pdv-sync-finished"); //$NON-NLS-1$
} catch (IllegalStateException e) {
// occurs when application was closed
@@ -255,6 +324,21 @@ public class ProducteevSyncProvider extends SyncProvider
-
-
-
+
+
Producteev
@@ -15,6 +15,12 @@
Assigned To \'%s\'
+
+
+ from %s
+
+
+ Add a Comment
@@ -33,10 +39,7 @@
Name for new Workspace
-
- new
-
-
+
Default Workspace
@@ -89,9 +92,12 @@
-
+
Astrid: Producteev
+
+ %s tasks updated / click for more details
+
Connection Error! Check your Internet connection.
diff --git a/astrid/src/com/todoroo/astrid/activity/TaskEditActivity.java b/astrid/src/com/todoroo/astrid/activity/TaskEditActivity.java
index f52d5020b..0f8d2881d 100644
--- a/astrid/src/com/todoroo/astrid/activity/TaskEditActivity.java
+++ b/astrid/src/com/todoroo/astrid/activity/TaskEditActivity.java
@@ -58,6 +58,7 @@ import android.widget.LinearLayout;
import android.widget.RemoteViews;
import android.widget.Spinner;
import android.widget.TabHost;
+import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
import android.widget.ToggleButton;
@@ -253,6 +254,8 @@ public final class TaskEditActivity extends TabActivity {
AddOn producteevAddon = addOnService.getAddOn(AddOnService.PRODUCTEEV_PACKAGE, "Producteev"); //$NON-NLS-1$
if (addOnService.isInstalled(producteevAddon) && ProducteevUtilities.INSTANCE.isLoggedIn()) {
controls.add(new ProducteevControlSet(this, addonsAddons));
+ ((TextView)findViewById(R.id.notes)).setHint(R.string.producteev_TEA_notes);
+ ((TextView)findViewById(R.id.notes_label)).setHint(R.string.producteev_TEA_notes);
}
} catch (Exception e) {
Log.e("astrid-error", "loading-control-set", e); //$NON-NLS-1$ //$NON-NLS-2$
@@ -790,7 +793,7 @@ public final class TaskEditActivity extends TabActivity {
Task.URGENCY_TOMORROW);
String dayAfterTomorrow = DateUtils.getDayOfWeekString(
new Date(DateUtilities.now() + 2 * DateUtilities.ONE_DAY).getDay() +
- Calendar.SUNDAY, 0);
+ Calendar.SUNDAY, DateUtils.FORMAT_ABBREV_ALL);
urgencyValues[3] = new UrgencyValue(dayAfterTomorrow,
Task.URGENCY_DAY_AFTER);
urgencyValues[4] = new UrgencyValue(labels[4],
diff --git a/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java b/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java
index 2bbba4b56..a574089ca 100644
--- a/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java
+++ b/astrid/src/com/todoroo/astrid/activity/TaskListActivity.java
@@ -78,6 +78,7 @@ import com.todoroo.astrid.reminders.ReminderService;
import com.todoroo.astrid.reminders.ReminderService.AlarmScheduler;
import com.todoroo.astrid.rmilk.MilkPreferences;
import com.todoroo.astrid.service.AddOnService;
+import com.todoroo.astrid.service.AstridDependencyInjector;
import com.todoroo.astrid.service.MetadataService;
import com.todoroo.astrid.service.StartupService;
import com.todoroo.astrid.service.TaskService;
@@ -161,6 +162,10 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
* ======================================================= initialization
* ====================================================================== */
+ static {
+ AstridDependencyInjector.initialize();
+ }
+
public TaskListActivity() {
DependencyInjectionService.getInstance().inject(this);
}
diff --git a/astrid/src/com/todoroo/astrid/utility/Constants.java b/astrid/src/com/todoroo/astrid/utility/Constants.java
index e700e0eaa..5d3cc181d 100644
--- a/astrid/src/com/todoroo/astrid/utility/Constants.java
+++ b/astrid/src/com/todoroo/astrid/utility/Constants.java
@@ -53,4 +53,7 @@ public final class Constants {
/** Notification Manager id for locale */
public static final int NOTIFICATION_LOCALE = -3;
+ /** Notification Manager id for producteev notifications*/
+ public static final int NOTIFICATION_PRODUCTEEV_NOTIFICATIONS = -4;
+
}
diff --git a/astrid/src/com/todoroo/astrid/widget/TasksWidget.java b/astrid/src/com/todoroo/astrid/widget/TasksWidget.java
index 388f10984..3f18083ec 100644
--- a/astrid/src/com/todoroo/astrid/widget/TasksWidget.java
+++ b/astrid/src/com/todoroo/astrid/widget/TasksWidget.java
@@ -51,12 +51,13 @@ public class TasksWidget extends AppWidgetProvider {
int[] appWidgetIds) {
try {
+ ContextManager.setContext(context);
super.onUpdate(context, appWidgetManager, appWidgetIds);
// Start in service to prevent Application Not Responding timeout
updateWidgets(context);
- } catch (SecurityException e) {
- // :(
+ } catch (Exception e) {
+ Log.e("astrid-update-widget", "widget update error", e); //$NON-NLS-1$
}
}
@@ -65,7 +66,7 @@ public class TasksWidget extends AppWidgetProvider {
* @param id
*/
public static void updateWidgets(Context context) {
- context.startService(new Intent(ContextManager.getContext(),
+ context.startService(new Intent(context,
TasksWidget.UpdateService.class));
}
@@ -178,7 +179,7 @@ public class TasksWidget extends AppWidgetProvider {
}
Intent listIntent = new Intent(context, TaskListActivity.class);
- listIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ listIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
if(filter != null) {
listIntent.putExtra(TaskListActivity.TOKEN_FILTER, filter);
listIntent.setType(filter.sqlQuery);
@@ -188,7 +189,7 @@ public class TasksWidget extends AppWidgetProvider {
views.setOnClickPendingIntent(R.id.taskbody, pendingIntent);
Intent editIntent = new Intent(context, TaskEditActivity.class);
- editIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ editIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
if(filter != null && filter.valuesForNewTasks != null) {
String values = AndroidUtilities.contentValuesToSerializedString(filter.valuesForNewTasks);
editIntent.putExtra(TaskEditActivity.TOKEN_VALUES, values);