Brighten light theme

1) Brighten background color

2) Add unread indicator in conversation list

3) Eliminate some conversation list overdraw
This commit is contained in:
Moxie Marlinspike 2017-11-13 18:01:05 -08:00
parent 03573df00f
commit 534dec282f
26 changed files with 151 additions and 156 deletions

View File

@ -5,7 +5,6 @@
<item>
<selector>
<item android:drawable="@color/textsecure_primary_alpha33" android:state_selected="true" />
<item android:drawable="@color/conversation_list_item_background_read_dark" />
</selector>
</item>
</ripple>

View File

@ -5,7 +5,6 @@
<item>
<selector>
<item android:drawable="@color/textsecure_primary_alpha33" android:state_selected="true" />
<item android:drawable="@color/conversation_list_item_background_read_light" />
</selector>
</item>
</ripple>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/textsecure_primary">
<item android:id="@android:id/mask" android:drawable="@android:color/black" />
<item>
<selector>
<item android:drawable="@color/textsecure_primary_alpha33" android:state_selected="true" />
<item android:drawable="@color/conversation_list_item_background_unread_light" />
</selector>
</item>
</ripple>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/textsecure_primary">
<item android:id="@android:id/mask" android:drawable="@android:color/black" />
<item>
<selector>
<item android:drawable="@color/textsecure_primary_alpha33" android:state_selected="true" />
<item android:drawable="@color/conversation_list_item_background_unread_dark" />
</selector>
</item>
</ripple>

View File

@ -3,5 +3,4 @@
<item android:drawable="@color/textsecure_primary_alpha33" android:state_selected="true" />
<item android:drawable="@color/textsecure_primary_alpha33" android:state_pressed="true" />
<item android:drawable="@color/signal_primary_alpha_focus" android:state_focused="true" />
<item android:drawable="@color/conversation_list_item_background_read_dark" />
</selector>

View File

@ -3,5 +3,4 @@
<item android:drawable="@color/textsecure_primary_alpha33" android:state_selected="true" />
<item android:drawable="@color/textsecure_primary_alpha33" android:state_pressed="true" />
<item android:drawable="@color/signal_primary_alpha_focus" android:state_focused="true" />
<item android:drawable="@color/conversation_list_item_background_read_light" />
</selector>

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/textsecure_primary_alpha33" android:state_selected="true" />
<item android:drawable="@color/textsecure_primary_alpha33" android:state_pressed="true" />
<item android:drawable="@color/signal_primary_alpha_focus" android:state_focused="true" />
<item android:drawable="@color/conversation_list_item_background_unread_light" />
</selector>

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/textsecure_primary_alpha33" android:state_selected="true" />
<item android:drawable="@color/textsecure_primary_alpha33" android:state_pressed="true" />
<item android:drawable="@color/signal_primary_alpha_focus" android:state_focused="true" />
<item android:drawable="@color/conversation_list_item_background_unread_dark" />
</selector>

View File

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<org.thoughtcrime.securesms.components.InputAwareLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer
android:id="@+id/quick_attachment_drawer"

View File

@ -1,10 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@android:id/list"

View File

@ -10,7 +10,6 @@
android:gravity="center_vertical"
android:orientation="horizontal"
android:clickable="true"
android:background="?android:windowBackground"
android:padding="5dp"
android:clipChildren="false"
android:clipToPadding="false">

View File

@ -3,6 +3,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:background="?attr/conversation_list_item_background"
android:layout_width="match_parent"
android:focusable="true"
android:nextFocusRight="@+id/fab"
@ -144,5 +145,13 @@
android:layout_alignWithParentIfMissing="true"
app:iconColor="?attr/conversation_list_item_subject_color"/>
<ImageView android:id="@+id/unread_indicator"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_below="@id/date"
android:layout_toLeftOf="@id/archived"
android:layout_toStartOf="@id/archived"
android:layout_alignWithParentIfMissing="true"/>
</RelativeLayout>
</org.thoughtcrime.securesms.ConversationListItem>

View File

@ -2,10 +2,7 @@
<resources>
<attr name="theme_type" format="string"/>
<attr name="attachment_type_selector_background" format="color"/>
<attr name="conversation_list_item_background_selected" format="reference"/>
<attr name="conversation_list_item_background_read" format="reference"/>
<attr name="conversation_list_item_background_unread" format="reference"/>
<attr name="conversation_list_item_count_color" format="reference|color"/>
<attr name="conversation_list_item_background" format="reference"/>
<attr name="conversation_list_item_contact_color" format="reference|color"/>
<attr name="conversation_list_item_subject_color" format="reference|color"/>
<attr name="conversation_list_item_date_color" format="reference|color"/>

View File

@ -27,14 +27,6 @@
<color name="conversation_compose_divider">#32000000</color>
<color name="conversation_list_item_background_read_light">@color/gray5</color>
<color name="conversation_list_item_background_unread_light">#ffffffff</color>
<color name="conversation_list_item_background_read_dark">#ff000000</color>
<color name="conversation_list_item_background_unread_dark">#ff333333</color>
<!--<color name="conversation_list_divider_light">#15000000</color>-->
<!--<color name="conversation_list_divider_dark">#22ffffff</color>-->
<color name="textsecure_holo_blue_light">#ff33b5e5</color>
<color name="dark_action_bar">#ff111111</color>

View File

@ -110,15 +110,12 @@
<item name="colorAccent">@color/textsecure_primary_dark</item>
<item name="colorControlActivated">@color/signal_primary</item>
<item name="colorControlHighlight">@color/signal_primary</item>
<item name="android:windowBackground">@color/gray5</item>
<item name="android:windowBackground">@color/white</item>
<item name="alertDialogTheme">@style/AppCompatAlertDialogStyleLight</item>
<item name="android:alertDialogTheme">@style/AppCompatDialogStyleLight</item>
<!--<item name="android:windowContentOverlay">@drawable/compat_actionbar_shadow_background</item>-->
<item name="attachment_type_selector_background">@color/white</item>
<item name="conversation_list_item_background_selected">@drawable/list_selected_holo_light</item>
<item name="conversation_list_item_background_unread">@drawable/conversation_list_item_unread_background</item>
<item name="conversation_list_item_background_read">@drawable/conversation_list_item_read_background</item>
<item name="conversation_list_item_count_color">#66333333</item>
<item name="conversation_list_item_background">@drawable/conversation_list_item_background</item>
<item name="conversation_list_item_contact_color">#FF333333</item>
<item name="conversation_list_item_subject_color">#FF444444</item>
<item name="conversation_list_item_date_color">#ff999999</item>
@ -129,7 +126,7 @@
<item name="conversation_group_member_name">#99000000</item>
<item name="conversation_background">#eeeeee</item>
<item name="conversation_background">@color/gray5</item>
<item name="conversation_editor_background">#22000000</item>
<item name="conversation_editor_text_color">#ff111111</item>
<item name="conversation_transport_sms_indicator">@drawable/ic_send_sms_insecure</item>
@ -240,10 +237,7 @@
<item name="android:windowBackground">@color/black</item>
<item name="alertDialogTheme">@style/AppCompatAlertDialogStyleDark</item>
<item name="android:alertDialogTheme">@style/AppCompatDialogStyleDark</item>
<item name="conversation_list_item_background_selected">@drawable/list_selected_holo_dark</item>
<item name="conversation_list_item_background_unread">@drawable/conversation_list_item_unread_background_dark</item>
<item name="conversation_list_item_background_read">@drawable/conversation_list_item_read_background_dark</item>
<item name="conversation_list_item_count_color">#66dddddd</item>
<item name="conversation_list_item_background">@drawable/conversation_list_item_background_dark</item>
<item name="conversation_list_item_contact_color">#ffdddddd</item>
<item name="conversation_list_item_subject_color">#ffdddddd</item>
<item name="conversation_list_item_date_color">#ffdddddd</item>
@ -277,7 +271,7 @@
<item name="fab_color">@color/textsecure_primary_dark</item>
<item name="lower_right_divet">@drawable/divet_lower_right_light</item>
<item name="conversation_background">#22ffffff</item>
<item name="conversation_background">@color/black</item>
<item name="conversation_editor_background">#22ffffff</item>
<item name="conversation_editor_text_color">#ffeeeeee</item>
<item name="conversation_transport_sms_indicator">@drawable/ic_send_sms_insecure_dark</item>

View File

@ -265,6 +265,12 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR_OVERLAY);
setContentView(R.layout.conversation_activity);
TypedArray typedArray = obtainStyledAttributes(new int[] {R.attr.conversation_background});
int color = typedArray.getColor(0, Color.WHITE);
typedArray.recycle();
getWindow().getDecorView().setBackgroundColor(color);
fragment = initFragment(R.id.fragment_content, new ConversationFragment(),
masterSecret, dynamicLanguage.getCurrentLocale());

View File

@ -240,9 +240,7 @@ public class ConversationItem extends LinearLayout
}
private void initializeAttributes() {
final int[] attributes = new int[] {R.attr.conversation_item_bubble_background,
R.attr.conversation_list_item_background_selected,
R.attr.conversation_item_background};
final int[] attributes = new int[] {R.attr.conversation_item_bubble_background};
final TypedArray attrs = context.obtainStyledAttributes(attributes);
defaultBubbleColor = attrs.getColor(0, Color.WHITE);

View File

@ -1,5 +1,5 @@
/**
* Copyright (C) 2014 Open Whisper Systems
/*
* Copyright (C) 2014-2017 Open Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -31,7 +31,6 @@ import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
@ -117,9 +116,8 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
}
private void initializeSearchListener() {
searchAction.setOnClickListener(v -> {
searchToolbar.display(searchAction.getX() + (searchAction.getWidth() / 2), searchAction.getY() + (searchAction.getHeight() / 2));
});
searchAction.setOnClickListener(v -> searchToolbar.display(searchAction.getX() + (searchAction.getWidth() / 2),
searchAction.getY() + (searchAction.getHeight() / 2)));
searchToolbar.setListener(new SearchToolbar.SearchListener() {
@Override
@ -235,12 +233,7 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
super.onChange(selfChange);
Log.w(TAG, "Detected android contact data changed, refreshing cache");
Recipient.clearCache(ConversationListActivity.this);
ConversationListActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
fragment.getListAdapter().notifyDataSetChanged();
}
});
ConversationListActivity.this.runOnUiThread(() -> fragment.getListAdapter().notifyDataSetChanged());
}
};

View File

@ -130,7 +130,7 @@ public class ConversationListFragment extends Fragment
TypedArray typedArray = getContext().obtainStyledAttributes(new int[]{R.attr.conversation_list_item_divider});
Drawable itemDrawable = typedArray.getDrawable(0);
DividerItemDecoration itemDecoration = new DividerItemDecoration(getActivity(), LinearLayoutManager.VERTICAL);
itemDecoration.setDrawable(itemDrawable);
if (itemDrawable != null) itemDecoration.setDrawable(itemDrawable);
list.addItemDecoration(itemDecoration);
typedArray.recycle();
@ -472,8 +472,8 @@ public class ConversationListFragment extends Fragment
@SuppressLint("StaticFieldLeak")
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
final long threadId = ((ConversationListItem)viewHolder.itemView).getThreadId();
final boolean read = ((ConversationListItem)viewHolder.itemView).getRead();
final long threadId = ((ConversationListItem)viewHolder.itemView).getThreadId();
final int unreadCount = ((ConversationListItem)viewHolder.itemView).getUnreadCount();
if (archive) {
new SnackbarAsyncTask<Long>(getView(),
@ -503,7 +503,7 @@ public class ConversationListFragment extends Fragment
protected void executeAction(@Nullable Long parameter) {
DatabaseFactory.getThreadDatabase(getActivity()).archiveConversation(threadId);
if (!read) {
if (unreadCount > 0) {
List<MarkedMessageInfo> messageIds = DatabaseFactory.getThreadDatabase(getActivity()).setRead(threadId, false);
MessageNotifier.updateNotification(getActivity(), masterSecret);
MarkReadReceiver.process(getActivity(), messageIds);
@ -514,8 +514,8 @@ public class ConversationListFragment extends Fragment
protected void reverseAction(@Nullable Long parameter) {
DatabaseFactory.getThreadDatabase(getActivity()).unarchiveConversation(threadId);
if (!read) {
DatabaseFactory.getThreadDatabase(getActivity()).setUnread(threadId);
if (unreadCount > 0) {
DatabaseFactory.getThreadDatabase(getActivity()).incrementUnread(threadId, unreadCount);
MessageNotifier.updateNotification(getActivity(), masterSecret);
}
}
@ -560,7 +560,7 @@ public class ConversationListFragment extends Fragment
}
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2011 Whisper Systems
* Copyright (C) 2014-2017 Open Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -19,17 +19,20 @@ package org.thoughtcrime.securesms;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.RippleDrawable;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.amulyakhare.textdrawable.TextDrawable;
import org.thoughtcrime.securesms.components.AlertView;
import org.thoughtcrime.securesms.components.AvatarImageView;
import org.thoughtcrime.securesms.components.DeliveryStatusView;
@ -41,7 +44,6 @@ import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
import org.thoughtcrime.securesms.util.DateUtils;
import org.thoughtcrime.securesms.util.ResUtil;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
@ -50,17 +52,11 @@ import java.util.Set;
import static org.thoughtcrime.securesms.util.SpanUtil.color;
/**
* A view that displays the element in a list of multiple conversation threads.
* Used by SecureSMS's ListActivity via a ConversationListAdapter.
*
* @author Moxie Marlinspike
*/
public class ConversationListItem extends RelativeLayout
implements RecipientModifiedListener,
BindableConversationListItem, Unbindable
{
@SuppressWarnings("unused")
private final static String TAG = ConversationListItem.class.getSimpleName();
private final static Typeface BOLD_TYPEFACE = Typeface.create("sans-serif", Typeface.BOLD);
@ -76,15 +72,13 @@ public class ConversationListItem extends RelativeLayout
private TextView archivedView;
private DeliveryStatusView deliveryStatusIndicator;
private AlertView alertView;
private ImageView unreadIndicator;
private long lastSeen;
private boolean read;
private int unreadCount;
private AvatarImageView contactPhotoImage;
private ThumbnailView thumbnailView;
private final @DrawableRes int readBackground;
private final @DrawableRes int unreadBackround;
private int distributionType;
public ConversationListItem(Context context) {
@ -93,8 +87,6 @@ public class ConversationListItem extends RelativeLayout
public ConversationListItem(Context context, AttributeSet attrs) {
super(context, attrs);
readBackground = ResUtil.getDrawableRes(context, R.attr.conversation_list_item_background_read);
unreadBackround = ResUtil.getDrawableRes(context, R.attr.conversation_list_item_background_unread);
}
@Override
@ -107,7 +99,8 @@ public class ConversationListItem extends RelativeLayout
this.alertView = findViewById(R.id.indicators_parent);
this.contactPhotoImage = findViewById(R.id.contact_photo_image);
this.thumbnailView = findViewById(R.id.thumbnail);
this.archivedView = ViewUtil.findById(this, R.id.archived);
this.archivedView = findViewById(R.id.archived);
this.unreadIndicator = findViewById(R.id.unread_indicator);
thumbnailView.setClickable(false);
ViewUtil.setTextViewGravityStart(this.fromView, getContext());
@ -123,20 +116,20 @@ public class ConversationListItem extends RelativeLayout
this.recipient = thread.getRecipient();
this.threadId = thread.getThreadId();
this.glideRequests = glideRequests;
this.read = thread.isRead();
this.unreadCount = thread.getUnreadCount();
this.distributionType = thread.getDistributionType();
this.lastSeen = thread.getLastSeen();
this.recipient.addListener(this);
this.fromView.setText(recipient, read);
this.fromView.setText(recipient, unreadCount == 0);
this.subjectView.setText(thread.getDisplayBody());
this.subjectView.setTypeface(read ? LIGHT_TYPEFACE : BOLD_TYPEFACE);
// this.subjectView.setTypeface(read ? LIGHT_TYPEFACE : BOLD_TYPEFACE);
if (thread.getDate() > 0) {
CharSequence date = DateUtils.getBriefRelativeTimeSpanString(getContext(), locale, thread.getDate());
dateView.setText(read ? date : color(getResources().getColor(R.color.textsecure_primary), date));
dateView.setTypeface(read ? LIGHT_TYPEFACE : BOLD_TYPEFACE);
dateView.setText(unreadCount == 0 ? date : color(getResources().getColor(R.color.textsecure_primary_dark), date));
dateView.setTypeface(unreadCount == 0 ? LIGHT_TYPEFACE : BOLD_TYPEFACE);
}
if (thread.isArchived()) {
@ -148,8 +141,8 @@ public class ConversationListItem extends RelativeLayout
setStatusIcons(thread);
setThumbnailSnippet(masterSecret, thread);
setBatchState(batchMode);
setBackground(thread);
setRippleColor(recipient);
setUnreadIndicator(thread);
this.contactPhotoImage.setAvatar(glideRequests, recipient, true);
}
@ -170,8 +163,8 @@ public class ConversationListItem extends RelativeLayout
return threadId;
}
public boolean getRead() {
return read;
public int getUnreadCount() {
return unreadCount;
}
public int getDistributionType() {
@ -226,12 +219,6 @@ public class ConversationListItem extends RelativeLayout
}
}
private void setBackground(ThreadRecord thread) {
if (thread.isRead()) setBackgroundResource(readBackground);
else setBackgroundResource(unreadBackround);
}
@TargetApi(VERSION_CODES.LOLLIPOP)
private void setRippleColor(Recipient recipient) {
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
((RippleDrawable)(getBackground()).mutate())
@ -239,10 +226,27 @@ public class ConversationListItem extends RelativeLayout
}
}
private void setUnreadIndicator(ThreadRecord thread) {
if (thread.isOutgoing() || thread.getUnreadCount() == 0) {
unreadIndicator.setVisibility(View.GONE);
return;
}
unreadIndicator.setImageDrawable(TextDrawable.builder()
.beginConfig()
.width(ViewUtil.dpToPx(getContext(), 24))
.height(ViewUtil.dpToPx(getContext(), 24))
.textColor(Color.WHITE)
.bold()
.endConfig()
.buildRound(String.valueOf(thread.getUnreadCount()), getResources().getColor(R.color.textsecure_primary_dark)));
unreadIndicator.setVisibility(View.VISIBLE);
}
@Override
public void onModified(final Recipient recipient) {
Util.runOnMain(() -> {
fromView.setText(recipient, read);
fromView.setText(recipient, unreadCount == 0);
contactPhotoImage.setAvatar(glideRequests, recipient, true);
setRippleColor(recipient);
});

View File

@ -85,7 +85,7 @@ public class ShareListItem extends RelativeLayout
}
private void setBackground() {
int[] attributes = new int[]{R.attr.conversation_list_item_background_read};
int[] attributes = new int[]{R.attr.conversation_list_item_background};
TypedArray drawables = context.obtainStyledAttributes(attributes);
setBackgroundDrawable(drawables.getDrawable(0));

View File

@ -109,7 +109,8 @@ public class DatabaseFactory {
private static final int UNSEEN_NUMBER_OFFER = 43;
private static final int READ_RECEIPTS = 44;
private static final int GROUP_RECEIPT_TRACKING = 45;
private static final int DATABASE_VERSION = 45;
private static final int UNREAD_COUNT_VERSION = 46;
private static final int DATABASE_VERSION = 46;
private static final String DATABASE_NAME = "messages.db";
private static final Object lock = new Object();
@ -1346,6 +1347,33 @@ public class DatabaseFactory {
db.execSQL("CREATE INDEX IF NOT EXISTS group_receipt_mms_id_index ON group_receipts (mms_id)");
}
if (oldVersion < UNREAD_COUNT_VERSION) {
db.execSQL("ALTER TABLE thread ADD COLUMN unread_count INTEGER DEFAULT 0");
try (Cursor cursor = db.query("thread", new String[] {"_id"}, "read = 0", null, null, null, null)) {
while (cursor != null && cursor.moveToNext()) {
long threadId = cursor.getLong(0);
int unreadCount = 0;
try (Cursor smsCursor = db.rawQuery("SELECT COUNT(*) FROM sms WHERE thread_id = ? AND read = '0'", new String[] {String.valueOf(threadId)})) {
if (smsCursor != null && smsCursor.moveToFirst()) {
unreadCount += smsCursor.getInt(0);
}
}
try (Cursor mmsCursor = db.rawQuery("SELECT COUNT(*) FROM mms WHERE thread_id = ? AND read = '0'", new String[] {String.valueOf(threadId)})) {
if (mmsCursor != null && mmsCursor.moveToFirst()) {
unreadCount += mmsCursor.getInt(0);
}
}
db.execSQL("UPDATE thread SET unread_count = ? WHERE _id = ?",
new String[] {String.valueOf(unreadCount),
String.valueOf(threadId)});
}
}
}
db.setTransactionSuccessful();
db.endTransaction();
}

View File

@ -677,7 +677,7 @@ public class MmsDatabase extends MessagingDatabase {
long messageId = insertMediaMessage(masterSecret, retrieved.getBody(), retrieved.getAttachments(), contentValues, null);
if (!Types.isExpirationTimerUpdate(mailbox)) {
DatabaseFactory.getThreadDatabase(context).setUnread(threadId);
DatabaseFactory.getThreadDatabase(context).incrementUnread(threadId, 1);
DatabaseFactory.getThreadDatabase(context).update(threadId, true);
}
@ -775,7 +775,7 @@ public class MmsDatabase extends MessagingDatabase {
DatabaseFactory.getThreadDatabase(context).update(threadId, true);
if (org.thoughtcrime.securesms.util.Util.isDefaultSmsProvider(context)) {
DatabaseFactory.getThreadDatabase(context).setUnread(threadId);
DatabaseFactory.getThreadDatabase(context).incrementUnread(threadId, 1);
}
jobManager.add(new TrimThreadJob(context, threadId));

View File

@ -1,5 +1,6 @@
/**
/*
* Copyright (C) 2011 Whisper Systems
* Copyright (C) 2013 - 2017 Open Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -486,7 +487,7 @@ public class SmsDatabase extends MessagingDatabase {
jobManager.add(new TrimThreadJob(context, threadId));
if (unread) {
DatabaseFactory.getThreadDatabase(context).setUnread(threadId);
DatabaseFactory.getThreadDatabase(context).incrementUnread(threadId, 1);
}
return new Pair<>(messageId, threadId);
@ -561,7 +562,7 @@ public class SmsDatabase extends MessagingDatabase {
long messageId = db.insert(TABLE_NAME, null, values);
if (unread) {
DatabaseFactory.getThreadDatabase(context).setUnread(threadId);
DatabaseFactory.getThreadDatabase(context).incrementUnread(threadId, 1);
}
if (!message.isIdentityUpdate() && !message.isIdentityVerified() && !message.isIdentityDefault()) {

View File

@ -1,5 +1,6 @@
/**
/*
* Copyright (C) 2011 Whisper Systems
* Copyright (C) 2013-2017 Open Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -65,6 +66,7 @@ public class ThreadDatabase extends Database {
public static final String SNIPPET = "snippet";
private static final String SNIPPET_CHARSET = "snippet_cs";
public static final String READ = "read";
public static final String UNREAD_COUNT = "unread_count";
public static final String TYPE = "type";
private static final String ERROR = "error";
public static final String SNIPPET_TYPE = "snippet_type";
@ -86,15 +88,15 @@ public class ThreadDatabase extends Database {
ARCHIVED + " INTEGER DEFAULT 0, " + STATUS + " INTEGER DEFAULT 0, " +
DELIVERY_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + EXPIRES_IN + " INTEGER DEFAULT 0, " +
LAST_SEEN + " INTEGER DEFAULT 0, " + HAS_SENT + " INTEGER DEFAULT 0, " +
READ_RECEIPT_COUNT + " INTEGER DEFAULT 0);";
READ_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + UNREAD_COUNT + " INTEGER DEFAULT 0);";
public static final String[] CREATE_INDEXS = {
static final String[] CREATE_INDEXS = {
"CREATE INDEX IF NOT EXISTS thread_recipient_ids_index ON " + TABLE_NAME + " (" + ADDRESS + ");",
"CREATE INDEX IF NOT EXISTS archived_count_index ON " + TABLE_NAME + " (" + ARCHIVED + ", " + MESSAGE_COUNT + ");",
};
private static final String[] THREAD_PROJECTION = {
ID, DATE, MESSAGE_COUNT, ADDRESS, SNIPPET, SNIPPET_CHARSET, READ, TYPE, ERROR, SNIPPET_TYPE,
ID, DATE, MESSAGE_COUNT, ADDRESS, SNIPPET, SNIPPET_CHARSET, READ, UNREAD_COUNT, TYPE, ERROR, SNIPPET_TYPE,
SNIPPET_URI, ARCHIVED, STATUS, DELIVERY_RECEIPT_COUNT, EXPIRES_IN, LAST_SEEN, READ_RECEIPT_COUNT
};
@ -248,6 +250,7 @@ public class ThreadDatabase extends Database {
SQLiteDatabase db = databaseHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues(1);
contentValues.put(READ, 1);
contentValues.put(UNREAD_COUNT, 0);
db.update(TABLE_NAME, contentValues, null, null);
@ -265,6 +268,7 @@ public class ThreadDatabase extends Database {
public List<MarkedMessageInfo> setRead(long threadId, boolean lastSeen) {
ContentValues contentValues = new ContentValues(1);
contentValues.put(READ, 1);
contentValues.put(UNREAD_COUNT, 0);
if (lastSeen) {
contentValues.put(LAST_SEEN, System.currentTimeMillis());
@ -284,13 +288,22 @@ public class ThreadDatabase extends Database {
}};
}
public void setUnread(long threadId) {
ContentValues contentValues = new ContentValues(1);
contentValues.put(READ, 0);
// public void setUnread(long threadId, int unreadCount) {
// ContentValues contentValues = new ContentValues(1);
// contentValues.put(READ, 0);
// contentValues.put(UNREAD_COUNT, unreadCount);
//
// SQLiteDatabase db = databaseHelper.getWritableDatabase();
// db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {threadId + ""});
// notifyConversationListListeners();
// }
public void incrementUnread(long threadId, int amount) {
SQLiteDatabase db = databaseHelper.getWritableDatabase();
db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {threadId + ""});
notifyConversationListListeners();
db.execSQL("UPDATE " + TABLE_NAME + " SET " + READ + " = 0, " +
UNREAD_COUNT + " = " + UNREAD_COUNT + " + ? WHERE " + ID + " = ?",
new String[] {String.valueOf(amount),
String.valueOf(threadId)});
}
public void setDistributionType(long threadId, int distributionType) {
@ -530,11 +543,12 @@ public class ThreadDatabase extends Database {
notifyConversationListeners(threadId);
}
public void updateReadState(long threadId) {
void updateReadState(long threadId) {
int unreadCount = DatabaseFactory.getMmsSmsDatabase(context).getUnreadCount(threadId);
ContentValues contentValues = new ContentValues();
contentValues.put(READ, unreadCount == 0);
contentValues.put(UNREAD_COUNT, unreadCount);
databaseHelper.getWritableDatabase().update(TABLE_NAME, contentValues,ID_WHERE,
new String[] {String.valueOf(threadId)});
@ -595,8 +609,8 @@ public class ThreadDatabase extends Database {
" ORDER BY " + TABLE_NAME + "." + DATE + " DESC";
}
public static interface ProgressListener {
public void onProgress(int complete, int total);
public interface ProgressListener {
void onProgress(int complete, int total);
}
public Reader readerFor(Cursor cursor, MasterCipher masterCipher) {
@ -648,7 +662,7 @@ public class ThreadDatabase extends Database {
DisplayRecord.Body body = getPlaintextBody(cursor);
long date = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.DATE));
long count = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.MESSAGE_COUNT));
long read = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.READ));
int unreadCount = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.UNREAD_COUNT));
long type = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.SNIPPET_TYPE));
boolean archived = cursor.getInt(cursor.getColumnIndex(ThreadDatabase.ARCHIVED)) != 0;
int status = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.STATUS));
@ -662,9 +676,9 @@ public class ThreadDatabase extends Database {
readReceiptCount = 0;
}
return new ThreadRecord(context, body, snippetUri, recipient, date, count, read == 1,
threadId, deliveryReceiptCount, status, type, distributionType, archived,
expiresIn, lastSeen, readReceiptCount);
return new ThreadRecord(context, body, snippetUri, recipient, date, count,
unreadCount, threadId, deliveryReceiptCount, status, type,
distributionType, archived, expiresIn, lastSeen, readReceiptCount);
}
private DisplayRecord.Body getPlaintextBody(Cursor cursor) {

View File

@ -1,5 +1,6 @@
/**
/*
* Copyright (C) 2012 Moxie Marlinspike
* Copyright (C) 2013-2017 Open Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -42,14 +43,14 @@ public class ThreadRecord extends DisplayRecord {
private @NonNull final Context context;
private @Nullable final Uri snippetUri;
private final long count;
private final boolean read;
private final int unreadCount;
private final int distributionType;
private final boolean archived;
private final long expiresIn;
private final long lastSeen;
public ThreadRecord(@NonNull Context context, @NonNull Body body, @Nullable Uri snippetUri,
@NonNull Recipient recipient, long date, long count, boolean read,
@NonNull Recipient recipient, long date, long count, int unreadCount,
long threadId, int deliveryReceiptCount, int status, long snippetType,
int distributionType, boolean archived, long expiresIn, long lastSeen,
int readReceiptCount)
@ -58,7 +59,7 @@ public class ThreadRecord extends DisplayRecord {
this.context = context.getApplicationContext();
this.snippetUri = snippetUri;
this.count = count;
this.read = read;
this.unreadCount = unreadCount;
this.distributionType = distributionType;
this.archived = archived;
this.expiresIn = expiresIn;
@ -134,8 +135,8 @@ public class ThreadRecord extends DisplayRecord {
return count;
}
public boolean isRead() {
return read;
public int getUnreadCount() {
return unreadCount;
}
public long getDate() {