Display thumbnail previews for images in conversation list.

Closes #4262
// FREEBIE
pull/1/head
Moxie Marlinspike 9 years ago
parent 15c6f18750
commit 5111fe2e95

@ -22,66 +22,81 @@
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dip"
android:layout_marginLeft="4dip"
android:layout_marginRight="8dip"
android:layout_marginBottom="4dip"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/contact_photo_image"
android:orientation="vertical">
<RelativeLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="4dip"
android:layout_marginRight="8dip"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/contact_photo_image"
android:weightSum="1"
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1"
android:gravity="bottom">
<org.thoughtcrime.securesms.components.FromTextView
android:id="@+id/from"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@+id/thumbnail"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?attr/conversation_list_item_contact_color"
android:singleLine="true"
tools:text="Jules Bonnot"
android:ellipsize="end"
android:drawablePadding="5dp"/>
<org.thoughtcrime.securesms.components.FromTextView
android:id="@+id/from"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?attr/conversation_list_item_contact_color"
android:singleLine="true"
tools:text="Jules Bonnot"
android:ellipsize="end"
android:drawablePadding="5dp"/>
<ImageView android:id="@+id/error"
android:layout_height="20dp"
android:layout_width="20dp"
android:layout_alignParentLeft="true"
android:layout_below="@id/from"
android:paddingBottom="3dp"
android:visibility="gone"
tools:visibility="visible"
android:src="@drawable/ic_action_warning_red"
android:contentDescription="@string/conversation_list_item_view__error_alert" />
<ImageView android:id="@+id/error"
android:layout_marginLeft="3dip"
android:layout_height="match_parent"
android:layout_width="20sp"
android:visibility="gone"
android:src="@drawable/ic_action_warning_red"
android:contentDescription="@string/conversation_list_item_view__error_alert" />
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/subject"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/from"
android:layout_toRightOf="@id/error"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?attr/conversation_list_item_subject_color"
android:fontFamily="sans-serif-light"
android:singleLine="true"
tools:text="Wheels arrive at 3pm flat. This is a somewhat longer message."
android:ellipsize="end" />
<TextView android:id="@+id/date"
android:layout_marginLeft="3dip"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?attr/conversation_list_item_date_color"
android:fontFamily="sans-serif-light"
tools:text="30 mins"
android:singleLine="true"
android:layout_gravity="top" />
</LinearLayout>
<org.thoughtcrime.securesms.components.ThumbnailView
android:id="@+id/thumbnail"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_horizontal"
android:layout_marginRight="5dip"
android:layout_marginLeft="5dip"
android:layout_toLeftOf="@+id/date"
android:layout_alignParentTop="true"
android:layout_marginTop="5dip"
android:contentDescription="@string/conversation_activity__attachment_thumbnail"
app:backgroundColorHint="?conversation_background"
android:visibility="gone"
tools:src="@drawable/ic_video_light"
tools:visibility="visible" />
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/subject"
android:layout_width="match_parent"
<TextView android:id="@id/date"
android:layout_marginLeft="3dip"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_above="@id/subject"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?attr/conversation_list_item_subject_color"
android:textColor="?attr/conversation_list_item_date_color"
android:fontFamily="sans-serif-light"
android:singleLine="true"
tools:text="Wheels arrive at 3pm flat."
android:ellipsize="end" />
tools:text="30 mins"
android:singleLine="true"/>
</LinearLayout>
</RelativeLayout>
</org.thoughtcrime.securesms.ConversationListItem>

@ -449,6 +449,7 @@
<string name="ThreadRecord_called">You called</string>
<string name="ThreadRecord_called_you">Called you</string>
<string name="ThreadRecord_missed_call">Missed call</string>
<string name="ThreadRecord_media_message">Media message</string>
<!-- VerifyIdentityActivity -->
<string name="VerifyIdentityActivity_you_do_not_have_an_identity_key">You do not have an identity key.</string>

@ -1080,7 +1080,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
if (threadId == -1) threadId = threadDatabase.getThreadIdFor(getRecipients(), thisDistributionType);
draftDatabase.insertDrafts(new MasterCipher(thisMasterSecret), threadId, drafts);
threadDatabase.updateSnippet(threadId, drafts.getSnippet(ConversationActivity.this), System.currentTimeMillis(), Types.BASE_DRAFT_TYPE);
threadDatabase.updateSnippet(threadId, drafts.getSnippet(ConversationActivity.this),
drafts.getUriSnippet(ConversationActivity.this),
System.currentTimeMillis(), Types.BASE_DRAFT_TYPE);
} else if (threadId > 0) {
threadDatabase.update(threadId);
}

@ -47,6 +47,7 @@ import java.util.Set;
public class ConversationListAdapter extends CursorRecyclerViewAdapter<ConversationListAdapter.ViewHolder> {
private final ThreadDatabase threadDatabase;
private final MasterSecret masterSecret;
private final MasterCipher masterCipher;
private final Locale locale;
private final Context context;
@ -86,6 +87,7 @@ public class ConversationListAdapter extends CursorRecyclerViewAdapter<Conversat
@Nullable Cursor cursor,
@Nullable ItemClickListener clickListener) {
super(context, cursor);
this.masterSecret = masterSecret;
this.masterCipher = new MasterCipher(masterSecret);
this.context = context;
this.threadDatabase = DatabaseFactory.getThreadDatabase(context);
@ -109,7 +111,7 @@ public class ConversationListAdapter extends CursorRecyclerViewAdapter<Conversat
ThreadDatabase.Reader reader = threadDatabase.readerFor(cursor, masterCipher);
ThreadRecord record = reader.getCurrent();
viewHolder.getItem().set(record, locale, batchSet, batchMode);
viewHolder.getItem().set(masterSecret, record, locale, batchSet, batchMode);
}
public void toggleThreadInBatchSet(long threadId) {

@ -25,12 +25,16 @@ import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Handler;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
import org.thoughtcrime.securesms.components.AvatarImageView;
import org.thoughtcrime.securesms.components.FromTextView;
import org.thoughtcrime.securesms.components.ThumbnailView;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.model.ThreadRecord;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.util.DateUtils;
@ -64,6 +68,7 @@ public class ConversationListItem extends RelativeLayout
private TextView dateView;
private boolean read;
private AvatarImageView contactPhotoImage;
private ThumbnailView thumbnailView;
private final @DrawableRes int readBackground;
private final @DrawableRes int unreadBackround;
@ -88,9 +93,12 @@ public class ConversationListItem extends RelativeLayout
this.fromView = (FromTextView) findViewById(R.id.from);
this.dateView = (TextView) findViewById(R.id.date);
this.contactPhotoImage = (AvatarImageView) findViewById(R.id.contact_photo_image);
this.thumbnailView = (ThumbnailView) findViewById(R.id.thumbnail);
}
public void set(ThreadRecord thread, Locale locale, Set<Long> selectedThreads, boolean batchMode) {
public void set(@NonNull MasterSecret masterSecret, @NonNull ThreadRecord thread,
@NonNull Locale locale, @NonNull Set<Long> selectedThreads, boolean batchMode)
{
this.selectedThreads = selectedThreads;
this.recipients = thread.getRecipients();
this.threadId = thread.getThreadId();
@ -109,6 +117,7 @@ public class ConversationListItem extends RelativeLayout
dateView.setTypeface(read ? LIGHT_TYPEFACE : BOLD_TYPEFACE);
}
setThumbnailSnippet(masterSecret, thread);
setBatchState(batchMode);
setBackground(thread);
setRippleColor(recipients);
@ -136,6 +145,23 @@ public class ConversationListItem extends RelativeLayout
return distributionType;
}
private void setThumbnailSnippet(MasterSecret masterSecret, ThreadRecord thread) {
if (thread.getSnippetUri() != null) {
this.thumbnailView.setVisibility(View.VISIBLE);
this.thumbnailView.setImageResource(masterSecret, thread.getSnippetUri());
LayoutParams subjectParams = (RelativeLayout.LayoutParams)this.subjectView.getLayoutParams();
subjectParams.addRule(RelativeLayout.LEFT_OF, R.id.thumbnail);
this.subjectView.setLayoutParams(subjectParams);
} else {
this.thumbnailView.setVisibility(View.GONE);
LayoutParams subjectParams = (RelativeLayout.LayoutParams)this.subjectView.getLayoutParams();
subjectParams.addRule(RelativeLayout.LEFT_OF, 0);
this.subjectView.setLayoutParams(subjectParams);
}
}
private void setBackground(ThreadRecord thread) {
if (thread.isRead()) setBackgroundResource(readBackground);
else setBackgroundResource(unreadBackround);

@ -5,6 +5,7 @@ import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.support.annotation.NonNull;
@ -124,6 +125,15 @@ public class ThumbnailView extends FrameLayout {
else Glide.clear(image);
}
public void setImageResource(@NonNull MasterSecret masterSecret, @NonNull Uri uri) {
if (transferControls.isPresent()) getTransferControls().setVisibility(View.GONE);
Glide.with(getContext()).load(new DecryptableUri(masterSecret, uri))
.crossFade()
.transform(new RoundedCorners(getContext(), true, radius, backgroundColorHint))
.into(image);
}
public void setThumbnailClickListener(SlideClickListener listener) {
this.thumbnailClickListener = listener;
}

@ -266,6 +266,7 @@ public class AttachmentDatabase extends Database {
partData.first.delete();
} else {
notifyConversationListeners(DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(mmsId));
notifyConversationListListeners();
}
thumbnailExecutor.submit(new ThumbnailFetchCallable(masterSecret, attachmentId));

@ -46,28 +46,29 @@ import ws.com.google.android.mms.ContentType;
public class DatabaseFactory {
private static final int INTRODUCED_IDENTITIES_VERSION = 2;
private static final int INTRODUCED_INDEXES_VERSION = 3;
private static final int INTRODUCED_DATE_SENT_VERSION = 4;
private static final int INTRODUCED_DRAFTS_VERSION = 5;
private static final int INTRODUCED_NEW_TYPES_VERSION = 6;
private static final int INTRODUCED_MMS_BODY_VERSION = 7;
private static final int INTRODUCED_MMS_FROM_VERSION = 8;
private static final int INTRODUCED_TOFU_IDENTITY_VERSION = 9;
private static final int INTRODUCED_PUSH_DATABASE_VERSION = 10;
private static final int INTRODUCED_GROUP_DATABASE_VERSION = 11;
private static final int INTRODUCED_PUSH_FIX_VERSION = 12;
private static final int INTRODUCED_DELIVERY_RECEIPTS = 13;
private static final int INTRODUCED_PART_DATA_SIZE_VERSION = 14;
private static final int INTRODUCED_THUMBNAILS_VERSION = 15;
private static final int INTRODUCED_IDENTITY_COLUMN_VERSION = 16;
private static final int INTRODUCED_UNIQUE_PART_IDS_VERSION = 17;
private static final int INTRODUCED_RECIPIENT_PREFS_DB = 18;
private static final int INTRODUCED_ENVELOPE_CONTENT_VERSION = 19;
private static final int INTRODUCED_COLOR_PREFERENCE_VERSION = 20;
private static final int INTRODUCED_DB_OPTIMIZATIONS_VERSION = 21;
private static final int INTRODUCED_INVITE_REMINDERS_VERSION = 22;
private static final int DATABASE_VERSION = 22;
private static final int INTRODUCED_IDENTITIES_VERSION = 2;
private static final int INTRODUCED_INDEXES_VERSION = 3;
private static final int INTRODUCED_DATE_SENT_VERSION = 4;
private static final int INTRODUCED_DRAFTS_VERSION = 5;
private static final int INTRODUCED_NEW_TYPES_VERSION = 6;
private static final int INTRODUCED_MMS_BODY_VERSION = 7;
private static final int INTRODUCED_MMS_FROM_VERSION = 8;
private static final int INTRODUCED_TOFU_IDENTITY_VERSION = 9;
private static final int INTRODUCED_PUSH_DATABASE_VERSION = 10;
private static final int INTRODUCED_GROUP_DATABASE_VERSION = 11;
private static final int INTRODUCED_PUSH_FIX_VERSION = 12;
private static final int INTRODUCED_DELIVERY_RECEIPTS = 13;
private static final int INTRODUCED_PART_DATA_SIZE_VERSION = 14;
private static final int INTRODUCED_THUMBNAILS_VERSION = 15;
private static final int INTRODUCED_IDENTITY_COLUMN_VERSION = 16;
private static final int INTRODUCED_UNIQUE_PART_IDS_VERSION = 17;
private static final int INTRODUCED_RECIPIENT_PREFS_DB = 18;
private static final int INTRODUCED_ENVELOPE_CONTENT_VERSION = 19;
private static final int INTRODUCED_COLOR_PREFERENCE_VERSION = 20;
private static final int INTRODUCED_DB_OPTIMIZATIONS_VERSION = 21;
private static final int INTRODUCED_INVITE_REMINDERS_VERSION = 22;
private static final int INTRODUCED_CONVERSATION_LIST_THUMBNAILS_VERSION = 23;
private static final int DATABASE_VERSION = 23;
private static final String DATABASE_NAME = "messages.db";
private static final Object lock = new Object();
@ -773,6 +774,10 @@ public class DatabaseFactory {
db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN seen_invite_reminder INTEGER DEFAULT 0");
}
if (oldVersion < INTRODUCED_CONVERSATION_LIST_THUMBNAILS_VERSION) {
db.execSQL("ALTER TABLE thread ADD COLUMN snippet_uri TEXT DEFAULT NULL");
}
db.setTransactionSuccessful();
db.endTransaction();
}

@ -5,6 +5,8 @@ import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.util.Log;
import org.thoughtcrime.securesms.R;
@ -136,7 +138,7 @@ public class DraftDatabase extends Database {
public static class Drafts extends LinkedList<Draft> {
private Draft getDraftOfType(String type) {
for (Draft draft : this) {
if (Draft.TEXT.equals(draft.getType())) {
if (type.equals(draft.getType())) {
return draft;
}
}
@ -153,5 +155,15 @@ public class DraftDatabase extends Database {
return "";
}
}
public @Nullable Uri getUriSnippet(Context context) {
Draft imageDraft = getDraftOfType(Draft.IMAGE);
if (imageDraft != null && imageDraft.getValue() != null) {
return Uri.parse(imageDraft.getValue());
}
return null;
}
}
}

@ -791,14 +791,14 @@ public class MmsDatabase extends MessagingDatabase {
addressDatabase.insertAddressesForId(messageId, addresses);
partsDatabase.insertAttachmentsForMessage(masterSecret, messageId, attachments);
notifyConversationListeners(contentValues.getAsLong(THREAD_ID));
DatabaseFactory.getThreadDatabase(context).update(contentValues.getAsLong(THREAD_ID));
db.setTransactionSuccessful();
return messageId;
} finally {
db.endTransaction();
}
notifyConversationListeners(contentValues.getAsLong(THREAD_ID));
DatabaseFactory.getThreadDatabase(context).update(contentValues.getAsLong(THREAD_ID));
}
}
public boolean delete(long messageId) {

@ -22,6 +22,7 @@ import android.database.Cursor;
import android.database.MergeCursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
@ -29,8 +30,11 @@ import android.util.Log;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.crypto.MasterCipher;
import org.thoughtcrime.securesms.database.model.DisplayRecord;
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.ThreadRecord;
import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.Recipients;
@ -45,6 +49,8 @@ import java.util.Set;
public class ThreadDatabase extends Database {
private static final String TAG = ThreadDatabase.class.getSimpleName();
static final String TABLE_NAME = "thread";
public static final String ID = "_id";
public static final String DATE = "date";
@ -55,14 +61,14 @@ public class ThreadDatabase extends Database {
public static final String READ = "read";
private static final String TYPE = "type";
private static final String ERROR = "error";
private static final String HAS_ATTACHMENT = "has_attachment";
public static final String SNIPPET_TYPE = "snippet_type";
private static final String SNIPPET_URI = "snippet_uri";
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY, " +
DATE + " INTEGER DEFAULT 0, " + MESSAGE_COUNT + " INTEGER DEFAULT 0, " +
RECIPIENT_IDS + " TEXT, " + SNIPPET + " TEXT, " + SNIPPET_CHARSET + " INTEGER DEFAULT 0, " +
READ + " INTEGER DEFAULT 1, " + TYPE + " INTEGER DEFAULT 0, " + ERROR + " INTEGER DEFAULT 0, " +
SNIPPET_TYPE + " INTEGER DEFAULT 0);";
SNIPPET_TYPE + " INTEGER DEFAULT 0, " + SNIPPET_URI + " TEXT DEFAULT NULL);";
public static final String[] CREATE_INDEXS = {
"CREATE INDEX IF NOT EXISTS thread_recipient_ids_index ON " + TABLE_NAME + " (" + RECIPIENT_IDS + ");",
@ -73,7 +79,7 @@ public class ThreadDatabase extends Database {
}
private long[] getRecipientIds(Recipients recipients) {
Set<Long> recipientSet = new HashSet<Long>();
Set<Long> recipientSet = new HashSet<>();
List<Recipient> recipientList = recipients.getRecipientsList();
for (Recipient recipient : recipientList) {
@ -118,12 +124,13 @@ public class ThreadDatabase extends Database {
return db.insert(TABLE_NAME, null, contentValues);
}
private void updateThread(long threadId, long count, String body, long date, long type)
private void updateThread(long threadId, long count, String body, @Nullable Uri attachment, long date, long type)
{
ContentValues contentValues = new ContentValues(4);
contentValues.put(DATE, date - date % 1000);
contentValues.put(MESSAGE_COUNT, count);
contentValues.put(SNIPPET, body);
contentValues.put(SNIPPET_URI, attachment == null ? null : attachment.toString());
contentValues.put(SNIPPET_TYPE, type);
SQLiteDatabase db = databaseHelper.getWritableDatabase();
@ -131,12 +138,13 @@ public class ThreadDatabase extends Database {
notifyConversationListListeners();
}
public void updateSnippet(long threadId, String snippet, long date, long type) {
public void updateSnippet(long threadId, String snippet, @Nullable Uri attachment, long date, long type) {
ContentValues contentValues = new ContentValues(3);
contentValues.put(DATE, date - date % 1000);
contentValues.put(SNIPPET, snippet);
contentValues.put(SNIPPET_TYPE, type);
contentValues.put(SNIPPET_URI, attachment == null ? null : attachment.toString());
SQLiteDatabase db = databaseHelper.getWritableDatabase();
db.update(TABLE_NAME, contentValues, ID + " = ?", new String[] {threadId + ""});
notifyConversationListListeners();
@ -144,7 +152,7 @@ public class ThreadDatabase extends Database {
private void deleteThread(long threadId) {
SQLiteDatabase db = databaseHelper.getWritableDatabase();
db.delete(TABLE_NAME, ID_WHERE, new String[] {threadId+""});
db.delete(TABLE_NAME, ID_WHERE, new String[] {threadId + ""});
notifyConversationListListeners();
}
@ -247,7 +255,7 @@ public class ThreadDatabase extends Database {
contentValues.put(READ, 0);
SQLiteDatabase db = databaseHelper.getWritableDatabase();
db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {threadId+""});
db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {threadId + ""});
notifyConversationListListeners();
}
@ -256,7 +264,7 @@ public class ThreadDatabase extends Database {
contentValues.put(TYPE, distributionType);
SQLiteDatabase db = databaseHelper.getWritableDatabase();
db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {threadId+""});
db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {threadId + ""});
notifyConversationListListeners();
}
@ -413,7 +421,7 @@ public class ThreadDatabase extends Database {
if (record.isPush()) timestamp = record.getDateSent();
else timestamp = record.getDateReceived();
updateThread(threadId, count, record.getBody().getBody(), timestamp, record.getType());
updateThread(threadId, count, record.getBody().getBody(), getAttachmentUriFor(record), timestamp, record.getType());
notifyConversationListListeners();
return false;
} else {
@ -427,6 +435,15 @@ public class ThreadDatabase extends Database {
}
}
private @Nullable Uri getAttachmentUriFor(MessageRecord record) {
if (!record.isMms() || record.isMmsNotification()) return null;
SlideDeck slideDeck = ((MediaMmsMessageRecord)record).getSlideDeck();
Slide thumbnail = slideDeck.getThumbnailSlide();
return thumbnail != null ? thumbnail.getThumbnailUri() : null;
}
public static interface ProgressListener {
public void onProgress(int complete, int total);
}
@ -459,9 +476,9 @@ public class ThreadDatabase extends Database {
}
public ThreadRecord getCurrent() {
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.ID));
String recipientId = cursor.getString(cursor.getColumnIndexOrThrow(ThreadDatabase.RECIPIENT_IDS));
Recipients recipients = RecipientFactory.getRecipientsForIds(context, recipientId, true);
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.ID));
String recipientId = cursor.getString(cursor.getColumnIndexOrThrow(ThreadDatabase.RECIPIENT_IDS));
Recipients recipients = RecipientFactory.getRecipientsForIds(context, recipientId, true);
DisplayRecord.Body body = getPlaintextBody(cursor);
long date = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.DATE));
@ -469,8 +486,9 @@ public class ThreadDatabase extends Database {
long read = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.READ));
long type = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.SNIPPET_TYPE));
int distributionType = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.TYPE));
Uri snippetUri = getSnippetUri(cursor);
return new ThreadRecord(context, body, recipients, date, count,
return new ThreadRecord(context, body, snippetUri, recipients, date, count,
read == 1, threadId, type, distributionType);
}
@ -492,6 +510,19 @@ public class ThreadDatabase extends Database {
}
}
private @Nullable Uri getSnippetUri(Cursor cursor) {
if (cursor.isNull(cursor.getColumnIndexOrThrow(ThreadDatabase.SNIPPET_URI))) {
return null;
}
try {
return Uri.parse(cursor.getString(cursor.getColumnIndexOrThrow(ThreadDatabase.SNIPPET_URI)));
} catch (IllegalArgumentException e) {
Log.w(TAG, e);
return null;
}
}
public void close() {
cursor.close();
}

@ -17,6 +17,9 @@
package org.thoughtcrime.securesms.database.model;
import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
@ -36,22 +39,28 @@ import org.thoughtcrime.securesms.util.GroupUtil;
*/
public class ThreadRecord extends DisplayRecord {
private final Context context;
private final long count;
private final boolean read;
private final int distributionType;
private @NonNull final Context context;
private @Nullable final Uri snippetUri;
private final long count;
private final boolean read;
private final int distributionType;
public ThreadRecord(Context context, Body body, Recipients recipients, long date,
long count, boolean read, long threadId, long snippetType,
int distributionType)
public ThreadRecord(@NonNull Context context, @NonNull Body body, @Nullable Uri snippetUri,
@NonNull Recipients recipients, long date, long count, boolean read,
long threadId, long snippetType, int distributionType)
{
super(context, body, recipients, date, date, threadId, snippetType);
this.context = context.getApplicationContext();
this.snippetUri = snippetUri;
this.count = count;
this.read = read;
this.distributionType = distributionType;
}
public @Nullable Uri getSnippetUri() {
return snippetUri;
}
@Override
public SpannableString getDisplayBody() {
if (SmsDatabase.Types.isDecryptInProgressType(type)) {
@ -83,7 +92,7 @@ public class ThreadRecord extends DisplayRecord {
return emphasisAdded(context.getString(org.thoughtcrime.securesms.R.string.ThreadRecord_missed_call));
} else {
if (TextUtils.isEmpty(getBody().getBody())) {
return new SpannableString(context.getString(R.string.MessageNotifier_no_subject));
return new SpannableString(emphasisAdded(context.getString(R.string.ThreadRecord_media_message)));
} else {
return new SpannableString(getBody().getBody());
}

Loading…
Cancel
Save