diff --git a/res/values/strings.xml b/res/values/strings.xml
index 50cffcb181..e092f940fa 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -42,6 +42,11 @@
Incoming SMS
outgoing SMS
+
+ (image)
+ (audio)
+ (image)
+
Can\'t find an app to select media.
@@ -311,6 +316,7 @@
Left the group...
Secure session ended.
+ Draft:
You do not have an identity key.
diff --git a/src/org/thoughtcrime/securesms/ConversationActivity.java b/src/org/thoughtcrime/securesms/ConversationActivity.java
index b02ae89263..458a322c0f 100644
--- a/src/org/thoughtcrime/securesms/ConversationActivity.java
+++ b/src/org/thoughtcrime/securesms/ConversationActivity.java
@@ -71,7 +71,9 @@ import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.DraftDatabase;
import org.thoughtcrime.securesms.database.DraftDatabase.Draft;
+import org.thoughtcrime.securesms.database.DraftDatabase.Drafts;
import org.thoughtcrime.securesms.database.GroupDatabase;
+import org.thoughtcrime.securesms.database.MmsSmsColumns.Types;
import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.thoughtcrime.securesms.mms.AttachmentManager;
import org.thoughtcrime.securesms.mms.AttachmentTypeSelectorAdapter;
@@ -111,7 +113,6 @@ import org.whispersystems.libaxolotl.state.SessionStore;
import org.whispersystems.textsecure.api.push.PushAddress;
import java.io.IOException;
-import java.util.LinkedList;
import java.util.List;
import static org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
@@ -914,8 +915,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
builder.show();
}
- private List getDraftsForCurrentState() {
- List drafts = new LinkedList<>();
+ private Drafts getDraftsForCurrentState() {
+ Drafts drafts = new Drafts();
if (!Util.isEmpty(composeText)) {
drafts.add(new Draft(Draft.TEXT, composeText.getText().toString()));
@@ -934,27 +935,22 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
if (this.threadId <= 0 || this.recipients == null || this.recipients.isEmpty())
return;
- final List drafts = getDraftsForCurrentState();
-
- if (drafts.size() <= 0)
- return;
+ final Drafts drafts = getDraftsForCurrentState();
final long thisThreadId = this.threadId;
final MasterSecret thisMasterSecret = this.masterSecret.parcelClone();
new AsyncTask() {
- @Override
- protected void onPostExecute(Void aVoid) {
- super.onPostExecute(aVoid);
- Toast.makeText(ConversationActivity.this,
- R.string.ConversationActivity_saved_draft,
- Toast.LENGTH_SHORT).show();
- }
-
@Override
protected Void doInBackground(Void... params) {
MasterCipher masterCipher = new MasterCipher(thisMasterSecret);
DatabaseFactory.getDraftDatabase(ConversationActivity.this).insertDrafts(masterCipher, thisThreadId, drafts);
+ ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(ConversationActivity.this);
+ if (drafts.size() > 0) {
+ threadDatabase.updateSnippet(thisThreadId, drafts.getSnippet(ConversationActivity.this), Types.BASE_DRAFT_TYPE);
+ } else {
+ threadDatabase.update(thisThreadId);
+ }
MemoryCleaner.clean(thisMasterSecret);
return null;
}
diff --git a/src/org/thoughtcrime/securesms/ConversationListItem.java b/src/org/thoughtcrime/securesms/ConversationListItem.java
index b5f8e660f8..2c4fe44c01 100644
--- a/src/org/thoughtcrime/securesms/ConversationListItem.java
+++ b/src/org/thoughtcrime/securesms/ConversationListItem.java
@@ -35,6 +35,7 @@ import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
+import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.model.ThreadRecord;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.Recipients;
@@ -42,6 +43,7 @@ import org.thoughtcrime.securesms.util.DateUtils;
import org.thoughtcrime.securesms.util.Emoji;
import java.util.Set;
+import java.util.concurrent.ThreadFactory;
/**
* A view that displays the element in a list of multiple conversation threads.
@@ -102,10 +104,10 @@ public class ConversationListItem extends RelativeLayout
this.recipients.addListener(this);
this.fromView.setText(formatFrom(recipients, count, read));
- this.subjectView.setText(Emoji.getInstance(context).emojify(thread.getDisplayBody(),
- Emoji.EMOJI_SMALL,
- new Emoji.InvalidatingPageLoadedListener(subjectView)),
- TextView.BufferType.SPANNABLE);
+ this.subjectView.setText(Emoji.getInstance(context).emojify(thread.getDisplayBody(),
+ Emoji.EMOJI_SMALL,
+ new Emoji.InvalidatingPageLoadedListener(subjectView)),
+ TextView.BufferType.SPANNABLE);
if (thread.getDate() > 0)
this.dateView.setText(DateUtils.getBetterRelativeTimeSpanString(getContext(), thread.getDate()));
diff --git a/src/org/thoughtcrime/securesms/database/DraftDatabase.java b/src/org/thoughtcrime/securesms/database/DraftDatabase.java
index 9e2d6d6a2d..6a4c5a05ad 100644
--- a/src/org/thoughtcrime/securesms/database/DraftDatabase.java
+++ b/src/org/thoughtcrime/securesms/database/DraftDatabase.java
@@ -7,6 +7,7 @@ import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
+import org.thoughtcrime.securesms.R;
import org.whispersystems.libaxolotl.InvalidMessageException;
import org.thoughtcrime.securesms.crypto.MasterCipher;
@@ -98,5 +99,37 @@ public class DraftDatabase extends Database {
public String getValue() {
return value;
}
+
+ public String getSnippet(Context context) {
+ switch (type) {
+ case TEXT: return value;
+ case IMAGE: return context.getString(R.string.DraftDatabase_Draft_image_snippet);
+ case VIDEO: return context.getString(R.string.DraftDatabase_Draft_video_snippet);
+ case AUDIO: return context.getString(R.string.DraftDatabase_Draft_audio_snippet);
+ default: return null;
+ }
+ }
+ }
+
+ public static class Drafts extends LinkedList {
+ private Draft getDraftOfType(String type) {
+ for (Draft draft : this) {
+ if (Draft.TEXT.equals(draft.getType())) {
+ return draft;
+ }
+ }
+ return null;
+ }
+
+ public String getSnippet(Context context) {
+ Draft textDraft = getDraftOfType(Draft.TEXT);
+ if (textDraft != null) {
+ return textDraft.getSnippet(context);
+ } else if (size() > 0) {
+ return get(0).getSnippet(context);
+ } else {
+ return "";
+ }
+ }
}
}
diff --git a/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java b/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java
index 6df6772add..df57508904 100644
--- a/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java
+++ b/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java
@@ -25,6 +25,7 @@ public interface MmsSmsColumns {
protected static final long BASE_SENT_FAILED_TYPE = 24;
protected static final long BASE_PENDING_SECURE_SMS_FALLBACK = 25;
protected static final long BASE_PENDING_INSECURE_SMS_FALLBACK = 26;
+ public static final long BASE_DRAFT_TYPE = 27;
protected static final long[] OUTGOING_MESSAGE_TYPES = {BASE_OUTBOX_TYPE, BASE_SENT_TYPE,
BASE_SENDING_TYPE, BASE_SENT_FAILED_TYPE,
@@ -63,6 +64,10 @@ public interface MmsSmsColumns {
protected static final long ENCRYPTION_REMOTE_DUPLICATE_BIT = 0x04000000;
protected static final long ENCRYPTION_REMOTE_LEGACY_BIT = 0x02000000;
+ public static boolean isDraftMessageType(long type) {
+ return (type & BASE_TYPE_MASK) == BASE_DRAFT_TYPE;
+ }
+
public static boolean isFailedMessageType(long type) {
return (type & BASE_TYPE_MASK) == BASE_SENT_FAILED_TYPE;
}
diff --git a/src/org/thoughtcrime/securesms/database/ThreadDatabase.java b/src/org/thoughtcrime/securesms/database/ThreadDatabase.java
index c0562ca0c9..27e603ffa2 100644
--- a/src/org/thoughtcrime/securesms/database/ThreadDatabase.java
+++ b/src/org/thoughtcrime/securesms/database/ThreadDatabase.java
@@ -115,7 +115,7 @@ public class ThreadDatabase extends Database {
private void updateThread(long threadId, long count, String body, long date, long type)
{
- ContentValues contentValues = new ContentValues(3);
+ ContentValues contentValues = new ContentValues(4);
contentValues.put(DATE, date - date % 1000);
contentValues.put(MESSAGE_COUNT, count);
contentValues.put(SNIPPET, body);
@@ -126,6 +126,15 @@ public class ThreadDatabase extends Database {
notifyConversationListListeners();
}
+ public void updateSnippet(long threadId, String snippet, long type) {
+ ContentValues contentValues = new ContentValues(3);
+ contentValues.put(SNIPPET, snippet);
+ contentValues.put(SNIPPET_TYPE, type);
+ SQLiteDatabase db = databaseHelper.getWritableDatabase();
+ db.update(TABLE_NAME, contentValues, ID + " = ?", new String[] {threadId + ""});
+ notifyConversationListListeners();
+ }
+
private void deleteThread(long threadId) {
SQLiteDatabase db = databaseHelper.getWritableDatabase();
db.delete(TABLE_NAME, ID_WHERE, new String[] {threadId+""});
diff --git a/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java b/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java
index bfef51224b..fa2c7c30f2 100644
--- a/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java
+++ b/src/org/thoughtcrime/securesms/database/model/ThreadRecord.java
@@ -72,6 +72,9 @@ public class ThreadRecord extends DisplayRecord {
return emphasisAdded(context.getString(R.string.TheadRecord_secure_session_ended));
} else if (MmsSmsColumns.Types.isLegacyType(type)) {
return emphasisAdded(context.getString(R.string.MessageRecord_message_encrypted_with_a_legacy_protocol_version_that_is_no_longer_supported));
+ } else if (MmsSmsColumns.Types.isDraftMessageType(type)) {
+ String draftText = context.getString(R.string.ThreadRecord_draft);
+ return emphasisAdded(draftText + " " + getBody().getBody(), 0, draftText.length());
} else {
if (TextUtils.isEmpty(getBody().getBody())) {
return new SpannableString(context.getString(R.string.MessageNotifier_no_subject));
@@ -82,10 +85,13 @@ public class ThreadRecord extends DisplayRecord {
}
private SpannableString emphasisAdded(String sequence) {
+ return emphasisAdded(sequence, 0, sequence.length());
+ }
+
+ private SpannableString emphasisAdded(String sequence, int start, int end) {
SpannableString spannable = new SpannableString(sequence);
- spannable.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0,
- sequence.length(),
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ spannable.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC),
+ start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return spannable;
}