diff --git a/api/src/com/todoroo/astrid/data/Update.java b/api/src/com/todoroo/astrid/data/Update.java index cc4a00620..64fc5ca17 100644 --- a/api/src/com/todoroo/astrid/data/Update.java +++ b/api/src/com/todoroo/astrid/data/Update.java @@ -67,6 +67,14 @@ public class Update extends RemoteModel { public static final StringProperty USER = new StringProperty( TABLE, USER_JSON_PROPERTY_NAME); + /** Other user id */ + public static final LongProperty OTHER_USER_ID = new LongProperty( + TABLE, "other_user_id"); + + /** Other User Object (JSON) */ + public static final StringProperty OTHER_USER = new StringProperty( + TABLE, "other_user"); + /** Action text */ public static final StringProperty ACTION = new StringProperty( TABLE, "action"); @@ -116,6 +124,8 @@ public class Update extends RemoteModel { defaultValues.put(TAGS_LOCAL.name, 0); defaultValues.put(USER_ID.name, 0); defaultValues.put(USER.name, ""); + defaultValues.put(OTHER_USER_ID.name, 0); + defaultValues.put(OTHER_USER.name, ""); defaultValues.put(ACTION.name, ""); defaultValues.put(ACTION_CODE.name, ""); defaultValues.put(MESSAGE.name, ""); diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/TagUpdatesFragment.java b/astrid/plugin-src/com/todoroo/astrid/actfm/TagUpdatesFragment.java index 1752b5445..07ec8ee2e 100644 --- a/astrid/plugin-src/com/todoroo/astrid/actfm/TagUpdatesFragment.java +++ b/astrid/plugin-src/com/todoroo/astrid/actfm/TagUpdatesFragment.java @@ -1,9 +1,11 @@ package com.todoroo.astrid.actfm; +import greendroid.widget.AsyncImageView; import android.app.Activity; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; +import android.graphics.Color; import android.os.Bundle; import android.support.v4.app.ActionBar; import android.support.v4.app.ListFragment; @@ -30,6 +32,7 @@ import com.timsu.astrid.R; import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.DependencyInjectionService; +import com.todoroo.andlib.utility.AndroidUtilities; import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.Preferences; import com.todoroo.astrid.actfm.ActFmCameraModule.CameraResultCallback; @@ -47,6 +50,7 @@ import com.todoroo.astrid.helper.ProgressBarSyncResultCallback; import com.todoroo.astrid.service.StatisticsConstants; import com.todoroo.astrid.service.StatisticsService; import com.todoroo.astrid.service.TagDataService; +import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.utility.Flags; public class TagUpdatesFragment extends ListFragment { @@ -126,6 +130,24 @@ public class TagUpdatesFragment extends ListFragment { String title = (tagData == null) ? getString(R.string.TLA_all_activity) : getString(R.string.tag_updates_title, tagData.getValue(TagData.NAME)); ((TextView) ab.getCustomView().findViewById(R.id.title)).setText(title); } + + if (AndroidUtilities.isTabletSized(getActivity()) && tagData != null) { + getView().setBackgroundColor(Color.rgb(200, 200, 200)); + TextView tagTitle = (TextView) getView().findViewById(R.id.tag_title); + String tagName = tagData.getValue(TagData.NAME); + tagTitle.setText(tagName); + TextView descriptionTitle = (TextView) getView().findViewById(R.id.tag_description); + descriptionTitle.setText(tagData.getValue(TagData.TAG_DESCRIPTION)); + + AsyncImageView imageView = (AsyncImageView) getView().findViewById(R.id.tag_picture); + imageView.setDefaultImageResource(TagService.getDefaultImageIDForTag(tagName)); + imageView.setUrl(tagData.getValue(TagData.PICTURE)); + } + else { + getView().findViewById(R.id.tag_header).setVisibility(View.GONE); + getView().findViewById(R.id.activity_header).setVisibility(View.GONE); + } + final ImageButton commentButton = (ImageButton) getView().findViewById(R.id.commentButton); addCommentField = (EditText) getView().findViewById(R.id.commentField); addCommentField.setOnEditorActionListener(new OnEditorActionListener() { @@ -190,9 +212,10 @@ public class TagUpdatesFragment extends ListFragment { if(updateAdapter == null) { TodorooCursor currentCursor = tagDataService.getUpdates(tagData); getActivity().startManagingCursor(currentCursor); + String fromUpdateClass = (tagData == null) ? UpdateAdapter.FROM_RECENT_ACTIVITY_VIEW : UpdateAdapter.FROM_TAG_VIEW; updateAdapter = new UpdateAdapter(this, R.layout.update_adapter_row, - currentCursor, false, null); + currentCursor, false, null, fromUpdateClass); ((ListView) getView().findViewById(android.R.id.list)).setAdapter(updateAdapter); } else { Cursor cursor = updateAdapter.getCursor(); diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmSyncService.java b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmSyncService.java index f58173faa..424439b0e 100644 --- a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmSyncService.java +++ b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmSyncService.java @@ -1116,6 +1116,9 @@ public final class ActFmSyncService { public static void updateFromJson(JSONObject json, Update model) throws JSONException { model.setValue(Update.REMOTE_ID, json.getLong("id")); readUser(json.getJSONObject("user"), model, Update.USER_ID, Update.USER); + if (json.has("other_user")) { + readUser(json.getJSONObject("other_user"), model, Update.OTHER_USER_ID, Update.OTHER_USER); + } model.setValue(Update.ACTION, json.getString("action")); model.setValue(Update.ACTION_CODE, json.getString("action_code")); model.setValue(Update.TARGET_NAME, json.getString("target_name")); diff --git a/astrid/plugin-src/com/todoroo/astrid/notes/EditNoteActivity.java b/astrid/plugin-src/com/todoroo/astrid/notes/EditNoteActivity.java index a283fc700..894d56626 100644 --- a/astrid/plugin-src/com/todoroo/astrid/notes/EditNoteActivity.java +++ b/astrid/plugin-src/com/todoroo/astrid/notes/EditNoteActivity.java @@ -18,6 +18,8 @@ import android.graphics.Bitmap; import android.graphics.Color; import android.support.v4.app.Fragment; import android.text.Editable; +import android.text.Html; +import android.text.Spanned; import android.text.TextUtils; import android.text.TextWatcher; import android.text.format.DateUtils; @@ -49,6 +51,7 @@ import com.todoroo.astrid.actfm.ActFmCameraModule.CameraResultCallback; import com.todoroo.astrid.actfm.ActFmCameraModule.ClearImageCallback; import com.todoroo.astrid.actfm.sync.ActFmPreferenceService; import com.todoroo.astrid.actfm.sync.ActFmSyncService; +import com.todoroo.astrid.adapter.UpdateAdapter; import com.todoroo.astrid.core.PluginServices; import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria; import com.todoroo.astrid.dao.UpdateDao; @@ -91,6 +94,7 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene private final Fragment fragment; private final ImageDiskCache imageCache; private final int cameraButton; + private final String linkColor; private final List listeners = new LinkedList(); @@ -105,6 +109,8 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene imageCache = ImageDiskCache.getInstance(); this.fragment = fragment; + linkColor = UpdateAdapter.getLinkColor(fragment); + cameraButton = getDefaultCameraButton(); DependencyInjectionService.getInstance().inject(this); @@ -267,7 +273,7 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene Update update = new Update(); for(updates.moveToFirst(); !updates.isAfterLast(); updates.moveToNext()) { update.readFromCursor(updates); - NoteOrUpdate noa = NoteOrUpdate.fromUpdate(update); + NoteOrUpdate noa = NoteOrUpdate.fromUpdate(update, linkColor); if(noa != null) items.add(noa); } @@ -343,18 +349,8 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene // name final TextView nameView = (TextView)view.findViewById(R.id.title); { - if (TextUtils.isEmpty(item.title)) { - nameView.setText(fragment.getActivity().getString(R.string.ENA_no_user)); - } - else { - nameView.setText(item.title); - } - } - - // description - final TextView descriptionView = (TextView)view.findViewById(R.id.description); { - descriptionView.setText(item.body); - Linkify.addLinks(descriptionView, Linkify.ALL); + nameView.setText(item.title); + Linkify.addLinks(nameView, Linkify.ALL); } // date @@ -433,8 +429,7 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene private String getPictureHashForUpdate(Update u) { - String s = u.getValue(Update.TASK) + "" + u.getValue(Update.CREATION_DATE); - return s; + return String.format("%s%s", u.getValue(Update.TASK), u.getValue(Update.CREATION_DATE)); //$NON-NLS-1$ } private void addComment(String message, String actionCode, boolean usePicture) { // Allow for users to just add picture @@ -491,17 +486,15 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene private static class NoteOrUpdate { private final String picture; - private final String title; - private final String body; + private final Spanned title; private final String commentPicture; private final long createdAt; - public NoteOrUpdate(String picture, String title, String body, String commentPicture, + public NoteOrUpdate(String picture, Spanned title, String commentPicture, long createdAt) { super(); this.picture = picture; this.title = title; - this.body = body; this.commentPicture = commentPicture; this.createdAt = createdAt; } @@ -511,43 +504,26 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene m.setValue(NoteMetadata.THUMBNAIL, ""); //$NON-NLS-1$ if(!m.containsNonNullValue(NoteMetadata.COMMENT_PICTURE)) m.setValue(NoteMetadata.COMMENT_PICTURE, ""); //$NON-NLS-1$ - + Spanned title = Html.fromHtml(String.format("%s\n%s", m.getValue(NoteMetadata.TITLE), m.getValue(NoteMetadata.BODY))); //$NON-NLS-1$ return new NoteOrUpdate(m.getValue(NoteMetadata.THUMBNAIL), - m.getValue(NoteMetadata.TITLE), - m.getValue(NoteMetadata.BODY), + title, m.getValue(NoteMetadata.COMMENT_PICTURE), m.getValue(Metadata.CREATION_DATE)); } @SuppressWarnings("nls") - public static NoteOrUpdate fromUpdate(Update u) { + public static NoteOrUpdate fromUpdate(Update u, String linkColor) { JSONObject user = ActFmPreferenceService.userFromModel(u); - String description = u.getValue(Update.ACTION); - String message = u.getValue(Update.MESSAGE); - if(u.getValue(Update.ACTION_CODE).equals("task_comment")) - description = message; - else if(!TextUtils.isEmpty(message) && !TextUtils.isEmpty(description)) - description += " " + message; - else - description += message; - - if(TextUtils.isEmpty(description)) - return null; - String commentPicture = u.getValue(Update.PICTURE); + Spanned title = UpdateAdapter.getUpdateComment(u, user, linkColor, UpdateAdapter.FROM_TASK_VIEW); return new NoteOrUpdate(user.optString("picture"), - user.optString("name", ""), - description, + title, commentPicture, u.getValue(Update.CREATION_DATE)); } - @Override - public String toString() { - return title + ": " + body; //$NON-NLS-1$ - } } public void addListener(UpdatesChangedListener listener) { diff --git a/astrid/res/layout-land/task_list_wrapper_activity_3pane.xml b/astrid/res/layout-land/task_list_wrapper_activity_3pane.xml index 007509d14..5618cc6b5 100644 --- a/astrid/res/layout-land/task_list_wrapper_activity_3pane.xml +++ b/astrid/res/layout-land/task_list_wrapper_activity_3pane.xml @@ -23,7 +23,7 @@ diff --git a/astrid/res/layout/tag_updates_fragment.xml b/astrid/res/layout/tag_updates_fragment.xml index f423d154b..2ec85a3e2 100644 --- a/astrid/res/layout/tag_updates_fragment.xml +++ b/astrid/res/layout/tag_updates_fragment.xml @@ -1,10 +1,71 @@ + + + + + + + + + + + + + + + + + + + + android:padding="3dip" + android:paddingBottom="5dip" > @@ -42,9 +103,9 @@ android:layout_gravity="top" android:layout_marginRight="3dip" android:layout_weight="1" + android:background="@android:color/transparent" android:paddingBottom="2dip" android:scaleType="centerInside" - android:background="@android:color/transparent" android:src="@drawable/camera_button" /> @@ -53,16 +114,16 @@ android:id="@+id/commentField" android:layout_width="wrap_content" android:layout_height="39dip" + android:layout_marginBottom="2dip" android:layout_marginLeft="1dip" android:layout_marginRight="1dip" - android:layout_marginBottom="2dip" android:layout_weight="100" android:autoText="true" android:background="@drawable/footer_comment_edittext" android:capitalize="sentences" android:hint="@string/TVA_add_comment" - android:textColor="@android:color/black" android:paddingLeft="10dip" + android:textColor="@android:color/black" android:textSize="16sp" /> @@ -75,7 +136,7 @@ android:layout_marginLeft="3dip" android:layout_weight="1" android:background="?attr/asAddButtonImg" - android:scaleType="center"/> + android:scaleType="center" /> \ No newline at end of file diff --git a/astrid/res/layout/update_adapter_row.xml b/astrid/res/layout/update_adapter_row.xml index 543d499e4..773793923 100644 --- a/astrid/res/layout/update_adapter_row.xml +++ b/astrid/res/layout/update_adapter_row.xml @@ -37,40 +37,31 @@ android:textSize="16sp"/> - - + + - - diff --git a/astrid/res/values/strings-updates.xml b/astrid/res/values/strings-updates.xml new file mode 100644 index 000000000..979e97c7b --- /dev/null +++ b/astrid/res/values/strings-updates.xml @@ -0,0 +1,23 @@ + + + + + + + + + %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 added %2$s to this list + %1$s completed %2$s. Huzzah! + %1$s un-completed %2$s. + %1$s added %4$s to %2$s + %1$s added %4$s to this list + %1$s assigned %4$s to %2$s + %1$s commented: %3$s + %1$s Re: %2$s: %3$s + %1$s Re: %2$s: %3$s + + diff --git a/astrid/src/com/todoroo/astrid/adapter/UpdateAdapter.java b/astrid/src/com/todoroo/astrid/adapter/UpdateAdapter.java index b47d348d1..1ead3861e 100644 --- a/astrid/src/com/todoroo/astrid/adapter/UpdateAdapter.java +++ b/astrid/src/com/todoroo/astrid/adapter/UpdateAdapter.java @@ -4,6 +4,7 @@ import greendroid.widget.AsyncImageView; import java.io.IOException; +import org.json.JSONException; import org.json.JSONObject; import android.app.AlertDialog; @@ -12,8 +13,11 @@ import android.content.DialogInterface; import android.content.res.Resources; import android.database.Cursor; import android.support.v4.app.Fragment; +import android.text.Html; +import android.text.Spanned; import android.text.TextUtils; import android.text.format.DateUtils; +import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; @@ -24,6 +28,7 @@ import android.widget.TextView; import com.timsu.astrid.R; import com.todoroo.andlib.data.TodorooCursor; +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; @@ -45,7 +50,23 @@ public class UpdateAdapter extends CursorAdapter { private final int resource; private final LayoutInflater inflater; private final ImageDiskCache imageCache; + private final String linkColor; + private final String fromView; + + 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_CONFIRMED_FRIENDSHIP = "confirmed_friendship"; //$NON-NLS-1$ + private static final String UPDATE_TASK_CREATED = "task_created"; + private static final String UPDATE_TASK_COMPLETED = "task_completed"; + private static final String UPDATE_TASK_UNCOMPLETED = "task_uncompleted"; + private static final String UPDATE_TASK_TAGGED = "task_tagged"; + private static final String UPDATE_TASK_ASSIGNED = "task_assigned"; + private static final String UPDATE_TASK_COMMENT = "task_comment"; + private static final String UPDATE_TAG_COMMENT = "tag_comment"; + public static final String FROM_TAG_VIEW = "from_tag"; + public static final String FROM_TASK_VIEW = "from_task"; + public static final String FROM_RECENT_ACTIVITY_VIEW = "from_recent_activity"; /** * Constructor * @@ -61,16 +82,26 @@ public class UpdateAdapter extends CursorAdapter { */ public UpdateAdapter(Fragment fragment, int resource, Cursor c, boolean autoRequery, - OnCompletedTaskListener onCompletedTaskListener) { + OnCompletedTaskListener onCompletedTaskListener, String fromView) { super(fragment.getActivity(), c, autoRequery); DependencyInjectionService.getInstance().inject(this); + linkColor = getLinkColor(fragment); + inflater = (LayoutInflater) fragment.getActivity().getSystemService( Context.LAYOUT_INFLATER_SERVICE); imageCache = ImageDiskCache.getInstance(); + this.fromView = fromView; this.resource = resource; this.fragment = fragment; + + } + + public static String getLinkColor(Fragment f) { + TypedValue colorType = new TypedValue(); + f.getActivity().getTheme().resolveAttribute(R.attr.asDetailsColor, colorType, false); + return "#" + Integer.toHexString(colorType.data).substring(2); } /* ====================================================================== @@ -158,29 +189,9 @@ public class UpdateAdapter extends CursorAdapter { // name final TextView nameView = (TextView)view.findViewById(R.id.title); { - String nameValue = user.optString("name"); - if(update.getValue(Update.ACTION_CODE).equals("task_comment")) - nameValue = r.getString(R.string.UAd_title_comment, nameValue, - update.getValue(Update.TARGET_NAME)); - if(TextUtils.isEmpty(nameValue)){ - nameView.setText(fragment.getActivity().getString(R.string.ENA_no_user)); - } - else { - nameView.setText(nameValue); - } + nameView.setText(getUpdateComment(update, user, linkColor, fromView)); } - // description - final TextView descriptionView = (TextView)view.findViewById(R.id.description); { - String description = update.getValue(Update.ACTION); - String message = update.getValue(Update.MESSAGE); - if(update.getValue(Update.ACTION_CODE).equals("task_comment") || - update.getValue(Update.ACTION_CODE).equals("tag_comment")) - description = message; - else if(!TextUtils.isEmpty(message)) - description += " " + message; - descriptionView.setText(description); - } // date final TextView date = (TextView)view.findViewById(R.id.date); { @@ -192,4 +203,84 @@ public class UpdateAdapter extends CursorAdapter { } + public static String linkify (String string, String linkColor) { + return String.format("%s", linkColor, string); //$NON-NLS-1$ + } + + public static Spanned getUpdateComment (Update update, JSONObject user, String linkColor, String fromView) { + if (user == null) { + user = ActFmPreferenceService.userFromModel(update); + } + JSONObject otherUser = null; + try { + otherUser = new JSONObject(update.getValue(Update.OTHER_USER)); + } catch (JSONException e) { + otherUser = new JSONObject(); + } + + return getUpdateComment(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) { + if (TextUtils.isEmpty(user)) { + user = ContextManager.getString(R.string.ENA_no_user); + } + + String userLink = linkify(user, linkColor); + String targetNameLink = linkify(targetName, linkColor); + String otherUserLink = linkify(otherUser, linkColor); + + int commentResource = 0; + if (actionCode.equals(UPDATE_FRIENDS)) { + commentResource = R.string.update_string_friends; + } + else if (actionCode.equals(UPDATE_REQUEST_FRIENDSHIP)) { + commentResource = R.string.update_string_request_friendship; + } + else if (actionCode.equals(UPDATE_CONFIRMED_FRIENDSHIP)) { + commentResource = R.string.update_string_confirmed_friendship; + } + else if (actionCode.equals(UPDATE_TASK_CREATED)) { + if (fromView.equals(FROM_TAG_VIEW)) + commentResource = R.string.update_string_task_created_on_list; + else + commentResource = R.string.update_string_task_created; + } + else if (actionCode.equals(UPDATE_TASK_COMPLETED)) { + commentResource = R.string.update_string_task_completed; + } + else if (actionCode.equals(UPDATE_TASK_UNCOMPLETED)) { + commentResource = R.string.update_string_task_uncompleted; + } + else if (actionCode.equals(UPDATE_TASK_TAGGED) && !TextUtils.isEmpty(otherUser)) { + if (fromView.equals(FROM_TAG_VIEW)) + commentResource = R.string.update_string_task_tagged_list; + else + commentResource = R.string.update_string_task_tagged; + } + else if (actionCode.equals(UPDATE_TASK_ASSIGNED) && !TextUtils.isEmpty(otherUser)) { + commentResource = R.string.update_string_task_assigned; + } + else if (actionCode.equals(UPDATE_TASK_COMMENT)) { + if (fromView.equals(FROM_TASK_VIEW)) + commentResource = R.string.update_string_default_comment; + else + commentResource = R.string.update_string_task_comment; + + } + else if (actionCode.equals(UPDATE_TAG_COMMENT)) { + if (fromView.equals(FROM_TAG_VIEW)) + commentResource = R.string.update_string_default_comment; + + else + commentResource = R.string.update_string_tag_comment; + + } + + if (commentResource == 0) { + return Html.fromHtml(String.format("%s %s", userLink, action)); //$NON-NLS-1$ + } + + return Html.fromHtml(ContextManager.getString(commentResource, userLink, targetNameLink, message, otherUserLink)); + } } diff --git a/astrid/src/com/todoroo/astrid/dao/Database.java b/astrid/src/com/todoroo/astrid/dao/Database.java index 15884005c..fc46c89e5 100644 --- a/astrid/src/com/todoroo/astrid/dao/Database.java +++ b/astrid/src/com/todoroo/astrid/dao/Database.java @@ -37,7 +37,7 @@ public class Database extends AbstractDatabase { * Database version number. This variable must be updated when database * tables are updated, as it determines whether a database needs updating. */ - public static final int VERSION = 21; + public static final int VERSION = 22; /** * Database name (must be unique) @@ -293,6 +293,15 @@ public class Database extends AbstractDatabase { } catch (SQLiteException e) { Log.e("astrid", "db-upgrade-" + oldVersion + "-" + newVersion, e); } + case 21: try { + for(Property property : new Property[] { Update.OTHER_USER_ID, Update.OTHER_USER }) + database.execSQL("ALTER TABLE " + Update.TABLE.name + " ADD " + + property.accept(visitor, null)); + + } + catch (SQLiteException e) { + Log.e("astrid", "db-upgrade-" + oldVersion + "-" + newVersion, e); + } return true; }