Merge pull request #175 from sbosley/120413_sb_comment_links

In comments, make links to tasks.
pull/14/head
sbosley 13 years ago
commit 35734273f0

@ -499,7 +499,7 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
String commentPicture = u.getValue(Update.PICTURE); 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"), return new NoteOrUpdate(user.optString("picture"),
title, title,
commentPicture, commentPicture,

@ -4,19 +4,22 @@
<!-- Update string from activity codes %1$s - user, %2$s - target name, %3$s - message, %4$s - other_user--> <!-- Update string from activity codes %1$s - user, %2$s - target name, %3$s - message, %4$s - other_user-->
<!-- NOTE TO TRANSLATORS: things beginning with $link_ are special tokens we use for string formatting.
Please do not translate this part of the string. -->
<string name="update_string_friends">%1$s is now friends with %2$s</string> <string name="update_string_friends">%1$s is now friends with %2$s</string>
<string name="update_string_request_friendship">%1$s wants to be friends with you</string> <string name="update_string_request_friendship">%1$s wants to be friends with you</string>
<string name="update_string_confirmed_friendship">%1$s has confirmed your friendship request</string> <string name="update_string_confirmed_friendship">%1$s has confirmed your friendship request</string>
<string name="update_string_task_created">%1$s created this task</string> <string name="update_string_task_created">%1$s created this task</string>
<string name="update_string_task_created_global">%1$s created %2$s</string> <string name="update_string_task_created_global">%1$s created $link_task</string>
<string name="update_string_task_created_on_list">%1$s added %2$s to this list</string> <string name="update_string_task_created_on_list">%1$s added $link_task to this list</string>
<string name="update_string_task_completed">%1$s completed %2$s. Huzzah!</string> <string name="update_string_task_completed">%1$s completed $link_task. Huzzah!</string>
<string name="update_string_task_uncompleted">%1$s un-completed %2$s.</string> <string name="update_string_task_uncompleted">%1$s un-completed $link_task.</string>
<string name="update_string_task_tagged">%1$s added %2$s to %4$s</string> <string name="update_string_task_tagged">%1$s added $link_task to %4$s</string>
<string name="update_string_task_tagged_list">%1$s added %2$s to this list</string> <string name="update_string_task_tagged_list">%1$s added $link_task to this list</string>
<string name="update_string_task_assigned">%1$s assigned %2$s to %4$s</string> <string name="update_string_task_assigned">%1$s assigned $link_task to %4$s</string>
<string name="update_string_default_comment">%1$s commented: %3$s</string> <string name="update_string_default_comment">%1$s commented: %3$s</string>
<string name="update_string_task_comment">%1$s Re: %2$s: %3$s</string> <string name="update_string_task_comment">%1$s Re: $link_task: %3$s</string>
<string name="update_string_tag_comment">%1$s Re: %2$s: %3$s</string> <string name="update_string_tag_comment">%1$s Re: %2$s: %3$s</string>
<string name="update_string_tag_created">%1$s created this list</string> <string name="update_string_tag_created">%1$s created this list</string>
<string name="update_string_tag_created_global">%1$s created the list %2$s</string> <string name="update_string_tag_created_global">%1$s created the list %2$s</string>

@ -1,6 +1,8 @@
package com.todoroo.astrid.adapter; package com.todoroo.astrid.adapter;
import java.io.IOException; import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -11,9 +13,13 @@ import android.content.DialogInterface;
import android.database.Cursor; import android.database.Cursor;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.text.Html; import android.text.Html;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned; import android.text.Spanned;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -29,6 +35,9 @@ import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.actfm.sync.ActFmPreferenceService; 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.data.Update;
import com.todoroo.astrid.helper.AsyncImageView; import com.todoroo.astrid.helper.AsyncImageView;
import com.todoroo.astrid.helper.ImageDiskCache; import com.todoroo.astrid.helper.ImageDiskCache;
@ -44,12 +53,16 @@ public class UpdateAdapter extends CursorAdapter {
// --- instance variables // --- instance variables
protected final Fragment fragment; protected final Fragment fragment;
protected final AstridActivity activity;
private final int resource; private final int resource;
private final LayoutInflater inflater; private final LayoutInflater inflater;
private final ImageDiskCache imageCache; private final ImageDiskCache imageCache;
private final String linkColor; private final String linkColor;
private final String fromView; 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_FRIENDS = "friends"; //$NON-NLS-1$
private static final String UPDATE_REQUEST_FRIENDSHIP = "request_friendship"; //$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.resource = resource;
this.fragment = fragment; this.fragment = fragment;
this.activity = (AstridActivity) fragment.getActivity();
} }
public static String getLinkColor(Fragment f) { public static String getLinkColor(Fragment f) {
@ -150,7 +163,8 @@ public class UpdateAdapter extends CursorAdapter {
// name // name
final TextView nameView = (TextView)view.findViewById(R.id.title); { 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, public static void setupImagePopupForCommentView(View view, AsyncImageView commentPictureView, final String updatePicture,
final String message, final Fragment fragment, ImageDiskCache imageCache) { final String message, final Fragment fragment, ImageDiskCache imageCache) {
if (!TextUtils.isEmpty(updatePicture) && !"null".equals(updatePicture)) { //$NON-NLS-1$ if (!TextUtils.isEmpty(updatePicture) && !"null".equals(updatePicture)) { //$NON-NLS-1$
@ -211,7 +230,7 @@ public class UpdateAdapter extends CursorAdapter {
} }
@SuppressWarnings("nls") @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) { if (user == null) {
user = ActFmPreferenceService.userFromModel(update); user = ActFmPreferenceService.userFromModel(update);
} }
@ -222,13 +241,14 @@ public class UpdateAdapter extends CursorAdapter {
otherUser = new JSONObject(); 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), user.optString("name"), update.getValue(Update.TARGET_NAME),
update.getValue(Update.MESSAGE), otherUser.optString("name"), update.getValue(Update.MESSAGE), otherUser.optString("name"),
update.getValue(Update.ACTION), linkColor, fromView); 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)) { if (TextUtils.isEmpty(user)) {
user = ContextManager.getString(R.string.ENA_no_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(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;
} }
} }

@ -88,6 +88,25 @@ public class TaskService {
return taskDao.fetch(id, properties); 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> 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. * Mark the given task as completed and save it.
* *

Loading…
Cancel
Save