diff --git a/astrid/plugin-src/com/todoroo/astrid/notes/EditNoteActivity.java b/astrid/plugin-src/com/todoroo/astrid/notes/EditNoteActivity.java
index c99c3072d..1be082b5d 100644
--- a/astrid/plugin-src/com/todoroo/astrid/notes/EditNoteActivity.java
+++ b/astrid/plugin-src/com/todoroo/astrid/notes/EditNoteActivity.java
@@ -499,7 +499,7 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
String commentPicture = u.getValue(Update.PICTURE);
- Spanned title = UpdateAdapter.getUpdateComment(u, user, linkColor, UpdateAdapter.FROM_TASK_VIEW);
+ Spanned title = UpdateAdapter.getUpdateComment(null, u, user, linkColor, UpdateAdapter.FROM_TASK_VIEW);
return new NoteOrUpdate(user.optString("picture"),
title,
commentPicture,
diff --git a/astrid/res/values/strings-updates.xml b/astrid/res/values/strings-updates.xml
index e60a3c2e9..0e83d4b71 100644
--- a/astrid/res/values/strings-updates.xml
+++ b/astrid/res/values/strings-updates.xml
@@ -4,19 +4,22 @@
+
+
%1$s is now friends with %2$s
%1$s wants to be friends with you
%1$s has confirmed your friendship request
%1$s created this task
- %1$s created %2$s
- %1$s added %2$s to this list
- %1$s completed %2$s. Huzzah!
- %1$s un-completed %2$s.
- %1$s added %2$s to %4$s
- %1$s added %2$s to this list
- %1$s assigned %2$s to %4$s
+ %1$s created $link_task
+ %1$s added $link_task to this list
+ %1$s completed $link_task. Huzzah!
+ %1$s un-completed $link_task.
+ %1$s added $link_task to %4$s
+ %1$s added $link_task to this list
+ %1$s assigned $link_task to %4$s
%1$s commented: %3$s
- %1$s Re: %2$s: %3$s
+ %1$s Re: $link_task: %3$s
%1$s Re: %2$s: %3$s
%1$s created this list
%1$s created the list %2$s
diff --git a/astrid/src/com/todoroo/astrid/adapter/UpdateAdapter.java b/astrid/src/com/todoroo/astrid/adapter/UpdateAdapter.java
index ccde95303..6a80afe14 100644
--- a/astrid/src/com/todoroo/astrid/adapter/UpdateAdapter.java
+++ b/astrid/src/com/todoroo/astrid/adapter/UpdateAdapter.java
@@ -1,6 +1,8 @@
package com.todoroo.astrid.adapter;
import java.io.IOException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.json.JSONException;
import org.json.JSONObject;
@@ -11,9 +13,13 @@ import android.content.DialogInterface;
import android.database.Cursor;
import android.support.v4.app.Fragment;
import android.text.Html;
+import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.format.DateUtils;
+import android.text.method.LinkMovementMethod;
+import android.text.style.ClickableSpan;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
@@ -29,6 +35,9 @@ import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.actfm.sync.ActFmPreferenceService;
+import com.todoroo.astrid.activity.AstridActivity;
+import com.todoroo.astrid.core.PluginServices;
+import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.Update;
import com.todoroo.astrid.helper.AsyncImageView;
import com.todoroo.astrid.helper.ImageDiskCache;
@@ -44,12 +53,16 @@ public class UpdateAdapter extends CursorAdapter {
// --- instance variables
protected final Fragment fragment;
+ protected final AstridActivity activity;
private final int resource;
private final LayoutInflater inflater;
private final ImageDiskCache imageCache;
private final String linkColor;
private final String fromView;
+ private static final String TARGET_LINK_PREFIX = "$link_"; //$NON-NLS-1$
+ private static final Pattern TARGET_LINK_PATTERN = Pattern.compile("\\" + TARGET_LINK_PREFIX + "(\\w*)"); //$NON-NLS-1$//$NON-NLS-2$
+ private static final String TASK_LINK_TYPE = "task"; //$NON-NLS-1$
private static final String UPDATE_FRIENDS = "friends"; //$NON-NLS-1$
private static final String UPDATE_REQUEST_FRIENDSHIP = "request_friendship"; //$NON-NLS-1$
@@ -94,7 +107,7 @@ public class UpdateAdapter extends CursorAdapter {
this.resource = resource;
this.fragment = fragment;
-
+ this.activity = (AstridActivity) fragment.getActivity();
}
public static String getLinkColor(Fragment f) {
@@ -150,7 +163,8 @@ public class UpdateAdapter extends CursorAdapter {
// name
final TextView nameView = (TextView)view.findViewById(R.id.title); {
- nameView.setText(getUpdateComment(update, user, linkColor, fromView));
+ nameView.setText(getUpdateComment(activity, update, user, linkColor, fromView));
+ nameView.setMovementMethod(new LinkMovementMethod());
}
@@ -164,6 +178,11 @@ public class UpdateAdapter extends CursorAdapter {
}
+ @Override
+ public boolean isEnabled(int position) {
+ return false;
+ }
+
public static void setupImagePopupForCommentView(View view, AsyncImageView commentPictureView, final String updatePicture,
final String message, final Fragment fragment, ImageDiskCache imageCache) {
if (!TextUtils.isEmpty(updatePicture) && !"null".equals(updatePicture)) { //$NON-NLS-1$
@@ -211,7 +230,7 @@ public class UpdateAdapter extends CursorAdapter {
}
@SuppressWarnings("nls")
- public static Spanned getUpdateComment (Update update, JSONObject user, String linkColor, String fromView) {
+ public static Spanned getUpdateComment (final AstridActivity activity, Update update, JSONObject user, String linkColor, String fromView) {
if (user == null) {
user = ActFmPreferenceService.userFromModel(update);
}
@@ -222,13 +241,14 @@ public class UpdateAdapter extends CursorAdapter {
otherUser = new JSONObject();
}
- return getUpdateComment(update.getValue(Update.ACTION_CODE),
+ return getUpdateComment(activity, update, update.getValue(Update.ACTION_CODE),
user.optString("name"), update.getValue(Update.TARGET_NAME),
update.getValue(Update.MESSAGE), otherUser.optString("name"),
update.getValue(Update.ACTION), linkColor, fromView);
}
- public static Spanned getUpdateComment (String actionCode, String user, String targetName, String message, String otherUser, String action, String linkColor, String fromView) {
+ public static Spanned getUpdateComment (final AstridActivity activity, Update update, String actionCode, String user, String targetName,
+ String message, String otherUser, String action, String linkColor, String fromView) {
if (TextUtils.isEmpty(user)) {
user = ContextManager.getString(R.string.ENA_no_user);
}
@@ -294,6 +314,69 @@ public class UpdateAdapter extends CursorAdapter {
return Html.fromHtml(String.format("%s %s", userLink, action)); //$NON-NLS-1$
}
- return Html.fromHtml(ContextManager.getString(commentResource, userLink, targetNameLink, message, otherUserLink));
+ String original = ContextManager.getString(commentResource, userLink, targetNameLink, message, otherUserLink);
+ int taskLinkIndex = original.indexOf(TARGET_LINK_PREFIX);
+
+ if (taskLinkIndex < 0)
+ return Html.fromHtml(original);
+
+ String[] components = original.split(" "); //$NON-NLS-1$
+ SpannableStringBuilder builder = new SpannableStringBuilder();
+ StringBuilder htmlStringBuilder = new StringBuilder();
+
+ for (String comp : components) {
+ Matcher m = TARGET_LINK_PATTERN.matcher(comp);
+ if (m.find()) {
+ builder.append(Html.fromHtml(htmlStringBuilder.toString()));
+ htmlStringBuilder.setLength(0);
+
+ String linkType = m.group(1);
+ CharSequence link = getLinkSpan(activity, update, actionCode, user,
+ targetName, message, otherUser, action, linkColor, linkType);
+ if (link != null) {
+ builder.append(link);
+ if (!m.hitEnd()) {
+ builder.append(comp.substring(m.end()));
+ }
+ builder.append(' ');
+ }
+ } else {
+ htmlStringBuilder.append(comp);
+ htmlStringBuilder.append(' ');
+ }
+ }
+
+ if (htmlStringBuilder.length() > 0)
+ builder.append(Html.fromHtml(htmlStringBuilder.toString()));
+
+ return builder;
+ }
+
+ private static CharSequence getLinkSpan(final AstridActivity activity, Update update, String actionCode, String user, String targetName,
+ String message, String otherUser, String action, String linkColor, String linkType) {
+ if (TASK_LINK_TYPE.equals(linkType)) {
+ long taskId = update.getValue(Update.TASK_LOCAL);
+ if (taskId <= 0) {
+ Task local = PluginServices.getTaskService().fetchByRemoteId(update.getValue(Update.TASK), Task.ID);
+ if (local != null)
+ taskId = local.getId();
+ }
+
+ final long taskIdToUse = taskId;
+
+ if (taskId > 0) {
+ SpannableString taskSpan = new SpannableString(targetName);
+ taskSpan.setSpan(new ClickableSpan() {
+ @Override
+ public void onClick(View widget) {
+ activity.onTaskListItemClicked(taskIdToUse);
+ }
+ }, 0, targetName.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+ return taskSpan;
+ } else {
+ return Html.fromHtml(linkify(targetName, linkColor));
+ }
+ }
+ return null;
}
}
diff --git a/astrid/src/com/todoroo/astrid/service/TaskService.java b/astrid/src/com/todoroo/astrid/service/TaskService.java
index ae00dedc9..e44a72e37 100644
--- a/astrid/src/com/todoroo/astrid/service/TaskService.java
+++ b/astrid/src/com/todoroo/astrid/service/TaskService.java
@@ -88,6 +88,25 @@ public class TaskService {
return taskDao.fetch(id, properties);
}
+ /**
+ *
+ * @param remoteId
+ * @param properties
+ * @return item, or null if it doesn't exist
+ */
+ public Task fetchByRemoteId(long remoteId, Property>... properties) {
+ TodorooCursor task = query(Query.select(properties).where(Task.REMOTE_ID.eq(remoteId)));
+ try {
+ if (task.getCount() > 0) {
+ task.moveToFirst();
+ return new Task(task);
+ }
+ return null;
+ } finally {
+ task.close();
+ }
+ }
+
/**
* Mark the given task as completed and save it.
*