Add unread mention badging to conversation list.

main
Cody Henthorne 2022-10-13 10:25:52 -04:00 zatwierdzone przez Alex Hart
rodzic ea9bf0ccd5
commit 341b8effcf
15 zmienionych plików z 194 dodań i 127 usunięć

Wyświetl plik

@ -36,7 +36,7 @@ public final class ConversationScrollToView extends FrameLayout {
unreadCount = findViewById(R.id.conversation_scroll_to_count); unreadCount = findViewById(R.id.conversation_scroll_to_count);
scrollButton = findViewById(R.id.conversation_scroll_to_button); scrollButton = findViewById(R.id.conversation_scroll_to_button);
if (attrs != null) { if (attrs != null && !isInEditMode()) {
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ConversationScrollToView); TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ConversationScrollToView);
int srcId = array.getResourceId(R.styleable.ConversationScrollToView_cstv_scroll_button_src, 0); int srcId = array.getResourceId(R.styleable.ConversationScrollToView_cstv_scroll_button_src, 0);

Wyświetl plik

@ -18,7 +18,7 @@ open class SimpleEmojiTextView @JvmOverloads constructor(
private val sizeChangeDebouncer: ThrottledDebouncer = ThrottledDebouncer(200) private val sizeChangeDebouncer: ThrottledDebouncer = ThrottledDebouncer(200)
init { init {
isEmojiCompatEnabled = SignalStore.settings().isPreferSystemEmoji isEmojiCompatEnabled = isInEditMode || SignalStore.settings().isPreferSystemEmoji
} }
override fun setText(text: CharSequence?, type: BufferType?) { override fun setText(text: CharSequence?, type: BufferType?) {

Wyświetl plik

@ -357,9 +357,9 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
giphyMp4ProjectionRecycler = initializeGiphyMp4(); giphyMp4ProjectionRecycler = initializeGiphyMp4();
this.groupViewModel = new ViewModelProvider(getParentFragment(), new ConversationGroupViewModel.Factory()).get(ConversationGroupViewModel.class); this.groupViewModel = new ViewModelProvider(getParentFragment(), (ViewModelProvider.Factory) new ConversationGroupViewModel.Factory()).get(ConversationGroupViewModel.class);
this.messageCountsViewModel = new ViewModelProvider(getParentFragment()).get(MessageCountsViewModel.class); this.messageCountsViewModel = new ViewModelProvider(getParentFragment()).get(MessageCountsViewModel.class);
this.conversationViewModel = new ViewModelProvider(getParentFragment(), new ConversationViewModel.Factory()).get(ConversationViewModel.class); this.conversationViewModel = new ViewModelProvider(getParentFragment(), (ViewModelProvider.Factory) new ConversationViewModel.Factory()).get(ConversationViewModel.class);
disposables.add(conversationViewModel.getChatColors().subscribe(chatColors -> { disposables.add(conversationViewModel.getChatColors().subscribe(chatColors -> {
recyclerViewColorizer.setChatColors(chatColors); recyclerViewColorizer.setChatColors(chatColors);

Wyświetl plik

@ -124,7 +124,7 @@ public class ConversationListArchiveFragment extends ConversationListFragment im
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
@Override @Override
protected void onItemSwiped(long threadId, int unreadCount) { protected void onItemSwiped(long threadId, int unreadCount, int unreadSelfMentionsCount) {
archiveDecoration.onArchiveStarted(); archiveDecoration.onArchiveStarted();
itemAnimator.enable(); itemAnimator.enable();

Wyświetl plik

@ -40,7 +40,6 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@ -76,6 +75,7 @@ import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode; import org.greenrobot.eventbus.ThreadMode;
import org.signal.core.util.DimensionUnit; import org.signal.core.util.DimensionUnit;
import org.signal.core.util.Stopwatch;
import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.concurrent.SignalExecutors;
import org.signal.core.util.concurrent.SimpleTask; import org.signal.core.util.concurrent.SimpleTask;
import org.signal.core.util.logging.Log; import org.signal.core.util.logging.Log;
@ -156,7 +156,6 @@ import org.thoughtcrime.securesms.util.SignalLocalMetrics;
import org.thoughtcrime.securesms.util.SignalProxyUtil; import org.thoughtcrime.securesms.util.SignalProxyUtil;
import org.thoughtcrime.securesms.util.SnapToTopDataObserver; import org.thoughtcrime.securesms.util.SnapToTopDataObserver;
import org.thoughtcrime.securesms.util.StickyHeaderDecoration; import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
import org.signal.core.util.Stopwatch;
import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util; import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil; import org.thoughtcrime.securesms.util.ViewUtil;
@ -1394,7 +1393,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode
} }
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
protected void onItemSwiped(long threadId, int unreadCount) { protected void onItemSwiped(long threadId, int unreadCount, int unreadSelfMentionsCount) {
archiveDecoration.onArchiveStarted(); archiveDecoration.onArchiveStarted();
itemAnimator.enable(); itemAnimator.enable();
@ -1434,7 +1433,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode
threadDatabase.restorePins(pinnedThreadIds); threadDatabase.restorePins(pinnedThreadIds);
if (unreadCount > 0) { if (unreadCount > 0) {
threadDatabase.incrementUnread(threadId, unreadCount); threadDatabase.incrementUnread(threadId, unreadCount, unreadSelfMentionsCount);
ApplicationDependencies.getMessageNotifier().updateNotification(context); ApplicationDependencies.getMessageNotifier().updateNotification(context);
} }
@ -1558,10 +1557,9 @@ public class ConversationListFragment extends MainFragment implements ActionMode
} }
private void onTrueSwipe(RecyclerView.ViewHolder viewHolder) { private void onTrueSwipe(RecyclerView.ViewHolder viewHolder) {
final long threadId = ((ConversationListItem) viewHolder.itemView).getThreadId(); ThreadRecord thread = ((ConversationListItem) viewHolder.itemView).getThread();
final int unreadCount = ((ConversationListItem) viewHolder.itemView).getUnreadCount();
onItemSwiped(threadId, unreadCount); onItemSwiped(thread.getThreadId(), thread.getUnreadCount(), thread.getUnreadSelfMentionsCount());
} }
@Override @Override

Wyświetl plik

@ -117,6 +117,7 @@ public final class ConversationListItem extends ConstraintLayout implements Bind
private View checkContainer; private View checkContainer;
private View uncheckedView; private View uncheckedView;
private View checkedView; private View checkedView;
private View unreadMentions;
private int thumbSize; private int thumbSize;
private GlideLiveDataTarget thumbTarget; private GlideLiveDataTarget thumbTarget;
@ -149,6 +150,7 @@ public final class ConversationListItem extends ConstraintLayout implements Bind
this.checkContainer = findViewById(R.id.conversation_list_item_check_container); this.checkContainer = findViewById(R.id.conversation_list_item_check_container);
this.uncheckedView = findViewById(R.id.conversation_list_item_unchecked); this.uncheckedView = findViewById(R.id.conversation_list_item_unchecked);
this.checkedView = findViewById(R.id.conversation_list_item_checked); this.checkedView = findViewById(R.id.conversation_list_item_checked);
this.unreadMentions = findViewById(R.id.conversation_list_item_unread_mentions_indicator);
this.thumbSize = (int) DimensionUnit.SP.toPixels(16f); this.thumbSize = (int) DimensionUnit.SP.toPixels(16f);
this.thumbTarget = new GlideLiveDataTarget(thumbSize, thumbSize); this.thumbTarget = new GlideLiveDataTarget(thumbSize, thumbSize);
@ -277,6 +279,7 @@ public final class ConversationListItem extends ConstraintLayout implements Bind
dateView.setText(""); dateView.setText("");
archivedView.setVisibility(GONE); archivedView.setVisibility(GONE);
unreadIndicator.setVisibility(GONE); unreadIndicator.setVisibility(GONE);
unreadMentions.setVisibility(GONE);
deliveryStatusIndicator.setNone(); deliveryStatusIndicator.setNone();
alertView.setNone(); alertView.setNone();
@ -304,6 +307,7 @@ public final class ConversationListItem extends ConstraintLayout implements Bind
dateView.setText(DateUtils.getBriefRelativeTimeSpanString(getContext(), locale, messageResult.getReceivedTimestampMs())); dateView.setText(DateUtils.getBriefRelativeTimeSpanString(getContext(), locale, messageResult.getReceivedTimestampMs()));
archivedView.setVisibility(GONE); archivedView.setVisibility(GONE);
unreadIndicator.setVisibility(GONE); unreadIndicator.setVisibility(GONE);
unreadMentions.setVisibility(GONE);
deliveryStatusIndicator.setNone(); deliveryStatusIndicator.setNone();
alertView.setNone(); alertView.setNone();
@ -464,13 +468,21 @@ public final class ConversationListItem extends ConstraintLayout implements Bind
private void setUnreadIndicator(ThreadRecord thread) { private void setUnreadIndicator(ThreadRecord thread) {
if (thread.isRead()) { if (thread.isRead()) {
unreadIndicator.setVisibility(View.GONE); unreadIndicator.setVisibility(View.GONE);
unreadMentions.setVisibility(View.GONE);
return; return;
} }
unreadIndicator.setText(unreadCount > 0 ? String.valueOf(unreadCount) : " "); if (thread.getUnreadSelfMentionsCount() > 0) {
unreadMentions.setVisibility(View.VISIBLE);
unreadIndicator.setVisibility(thread.getUnreadCount() == 1 ? View.GONE : View.VISIBLE);
} else {
unreadMentions.setVisibility(View.GONE);
unreadIndicator.setVisibility(View.VISIBLE); unreadIndicator.setVisibility(View.VISIBLE);
} }
unreadIndicator.setText(unreadCount > 0 ? String.valueOf(unreadCount) : " ");
}
private void onRecipientChanged(@NonNull Recipient recipient) { private void onRecipientChanged(@NonNull Recipient recipient) {
if (this.recipient == null || !this.recipient.getId().equals(recipient.getId())) { if (this.recipient == null || !this.recipient.getId().equals(recipient.getId())) {
Log.w(TAG, "Bad change! Local recipient doesn't match. Ignoring. Local: " + (this.recipient == null ? "null" : this.recipient.getId()) + ", Changed: " + recipient.getId()); Log.w(TAG, "Bad change! Local recipient doesn't match. Ignoring. Local: " + (this.recipient == null ? "null" : this.recipient.getId()) + ", Changed: " + recipient.getId());

Wyświetl plik

@ -1988,7 +1988,8 @@ public class MmsDatabase extends MessageDatabase {
boolean isNotStoryGroupReply = retrieved.getParentStoryId() == null || !retrieved.getParentStoryId().isGroupReply(); boolean isNotStoryGroupReply = retrieved.getParentStoryId() == null || !retrieved.getParentStoryId().isGroupReply();
if (!Types.isExpirationTimerUpdate(mailbox) && !retrieved.getStoryType().isStory() && isNotStoryGroupReply) { if (!Types.isExpirationTimerUpdate(mailbox) && !retrieved.getStoryType().isStory() && isNotStoryGroupReply) {
SignalDatabase.threads().incrementUnread(threadId, 1); boolean incrementUnreadMentions = !retrieved.getMentions().isEmpty() && retrieved.getMentions().stream().anyMatch(m -> m.getRecipientId().equals(Recipient.self().getId()));
SignalDatabase.threads().incrementUnread(threadId, 1, incrementUnreadMentions ? 1 : 0);
SignalDatabase.threads().update(threadId, true); SignalDatabase.threads().update(threadId, true);
} }
@ -2098,7 +2099,7 @@ public class MmsDatabase extends MessageDatabase {
notifyConversationListeners(threadId); notifyConversationListeners(threadId);
if (org.thoughtcrime.securesms.util.Util.isDefaultSmsProvider(context)) { if (org.thoughtcrime.securesms.util.Util.isDefaultSmsProvider(context)) {
SignalDatabase.threads().incrementUnread(threadId, 1); SignalDatabase.threads().incrementUnread(threadId, 1, 0);
} }
SignalDatabase.threads().update(threadId, true); SignalDatabase.threads().update(threadId, true);

Wyświetl plik

@ -741,7 +741,7 @@ public class SmsDatabase extends MessageDatabase {
db.insert(TABLE_NAME, null, values); db.insert(TABLE_NAME, null, values);
SignalDatabase.threads().incrementUnread(threadId, 1); SignalDatabase.threads().incrementUnread(threadId, 1, 0);
} }
SignalDatabase.threads().update(threadId, true); SignalDatabase.threads().update(threadId, true);
@ -818,7 +818,7 @@ public class SmsDatabase extends MessageDatabase {
db.insert(TABLE_NAME, null, values); db.insert(TABLE_NAME, null, values);
SignalDatabase.threads().incrementUnread(threadId, 1); SignalDatabase.threads().incrementUnread(threadId, 1, 0);
} }
SignalDatabase.threads().update(threadId, true); SignalDatabase.threads().update(threadId, true);
@ -890,7 +890,7 @@ public class SmsDatabase extends MessageDatabase {
long messageId = db.insert(TABLE_NAME, null, values); long messageId = db.insert(TABLE_NAME, null, values);
if (unread) { if (unread) {
SignalDatabase.threads().incrementUnread(threadId, 1); SignalDatabase.threads().incrementUnread(threadId, 1, 0);
} }
SignalDatabase.threads().update(threadId, true); SignalDatabase.threads().update(threadId, true);
@ -1278,7 +1278,7 @@ public class SmsDatabase extends MessageDatabase {
long messageId = db.insert(TABLE_NAME, null, values); long messageId = db.insert(TABLE_NAME, null, values);
if (unread) { if (unread) {
SignalDatabase.threads().incrementUnread(threadId, 1); SignalDatabase.threads().incrementUnread(threadId, 1, 0);
} }
if (!silent) { if (!silent) {
@ -1324,7 +1324,7 @@ public class SmsDatabase extends MessageDatabase {
long messageId = db.insert(TABLE_NAME, null, values); long messageId = db.insert(TABLE_NAME, null, values);
SignalDatabase.threads().incrementUnread(threadId, 1); SignalDatabase.threads().incrementUnread(threadId, 1, 0);
SignalDatabase.threads().update(threadId, true); SignalDatabase.threads().update(threadId, true);
notifyConversationListeners(threadId); notifyConversationListeners(threadId);
@ -1348,7 +1348,7 @@ public class SmsDatabase extends MessageDatabase {
databaseHelper.getSignalWritableDatabase().insert(TABLE_NAME, null, values); databaseHelper.getSignalWritableDatabase().insert(TABLE_NAME, null, values);
SignalDatabase.threads().incrementUnread(threadId, 1); SignalDatabase.threads().incrementUnread(threadId, 1, 0);
SignalDatabase.threads().update(threadId, true); SignalDatabase.threads().update(threadId, true);
notifyConversationListeners(threadId); notifyConversationListeners(threadId);

Wyświetl plik

@ -118,6 +118,7 @@ public class ThreadDatabase extends Database {
public static final String HAS_SENT = "has_sent"; public static final String HAS_SENT = "has_sent";
private static final String LAST_SCROLLED = "last_scrolled"; private static final String LAST_SCROLLED = "last_scrolled";
static final String PINNED = "pinned"; static final String PINNED = "pinned";
private static final String UNREAD_SELF_MENTION_COUNT = "unread_self_mention_count";
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
DATE + " INTEGER DEFAULT 0, " + DATE + " INTEGER DEFAULT 0, " +
@ -141,7 +142,8 @@ public class ThreadDatabase extends Database {
READ_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + READ_RECEIPT_COUNT + " INTEGER DEFAULT 0, " +
UNREAD_COUNT + " INTEGER DEFAULT 0, " + UNREAD_COUNT + " INTEGER DEFAULT 0, " +
LAST_SCROLLED + " INTEGER DEFAULT 0, " + LAST_SCROLLED + " INTEGER DEFAULT 0, " +
PINNED + " INTEGER DEFAULT 0);"; PINNED + " INTEGER DEFAULT 0, " +
UNREAD_SELF_MENTION_COUNT + " INTEGER DEFAULT 0);";
public static final String[] CREATE_INDEXS = { public static final String[] CREATE_INDEXS = {
"CREATE INDEX IF NOT EXISTS thread_recipient_id_index ON " + TABLE_NAME + " (" + RECIPIENT_ID + ");", "CREATE INDEX IF NOT EXISTS thread_recipient_id_index ON " + TABLE_NAME + " (" + RECIPIENT_ID + ");",
@ -151,7 +153,8 @@ public class ThreadDatabase extends Database {
private static final String[] THREAD_PROJECTION = { private static final String[] THREAD_PROJECTION = {
ID, DATE, MEANINGFUL_MESSAGES, RECIPIENT_ID, SNIPPET, SNIPPET_CHARSET, READ, UNREAD_COUNT, TYPE, ERROR, SNIPPET_TYPE, ID, DATE, MEANINGFUL_MESSAGES, RECIPIENT_ID, SNIPPET, SNIPPET_CHARSET, READ, UNREAD_COUNT, TYPE, ERROR, SNIPPET_TYPE,
SNIPPET_URI, SNIPPET_CONTENT_TYPE, SNIPPET_EXTRAS, ARCHIVED, STATUS, DELIVERY_RECEIPT_COUNT, EXPIRES_IN, LAST_SEEN, READ_RECEIPT_COUNT, LAST_SCROLLED, PINNED SNIPPET_URI, SNIPPET_CONTENT_TYPE, SNIPPET_EXTRAS, ARCHIVED, STATUS, DELIVERY_RECEIPT_COUNT, EXPIRES_IN, LAST_SEEN,
READ_RECEIPT_COUNT, LAST_SCROLLED, PINNED, UNREAD_SELF_MENTION_COUNT
}; };
private static final List<String> TYPED_THREAD_PROJECTION = Stream.of(THREAD_PROJECTION) private static final List<String> TYPED_THREAD_PROJECTION = Stream.of(THREAD_PROJECTION)
@ -371,6 +374,7 @@ public class ThreadDatabase extends Database {
ContentValues contentValues = new ContentValues(1); ContentValues contentValues = new ContentValues(1);
contentValues.put(READ, ReadStatus.READ.serialize()); contentValues.put(READ, ReadStatus.READ.serialize());
contentValues.put(UNREAD_COUNT, 0); contentValues.put(UNREAD_COUNT, 0);
contentValues.put(UNREAD_SELF_MENTION_COUNT, 0);
db.update(TABLE_NAME, contentValues, null, null); db.update(TABLE_NAME, contentValues, null, null);
@ -464,9 +468,11 @@ public class ThreadDatabase extends Database {
SignalDatabase.mms().setReactionsSeen(threadId, sinceTimestamp); SignalDatabase.mms().setReactionsSeen(threadId, sinceTimestamp);
int unreadCount = SignalDatabase.mmsSms().getUnreadCount(threadId); int unreadCount = SignalDatabase.mmsSms().getUnreadCount(threadId);
contentValues.put(UNREAD_COUNT, unreadCount); contentValues.put(UNREAD_COUNT, unreadCount);
int unreadMentionsCount = SignalDatabase.mms().getUnreadMentionCount(threadId);
contentValues.put(UNREAD_SELF_MENTION_COUNT, unreadMentionsCount);
db.update(TABLE_NAME, contentValues, ID_WHERE, SqlUtil.buildArgs(threadId)); db.update(TABLE_NAME, contentValues, ID_WHERE, SqlUtil.buildArgs(threadId));
if (previous != null && previous.isForcedUnread()) { if (previous != null && previous.isForcedUnread()) {
@ -549,14 +555,15 @@ public class ThreadDatabase extends Database {
} }
} }
public void incrementUnread(long threadId, int amount) { public void incrementUnread(long threadId, int unreadAmount, int unreadSelfMentionAmount) {
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
db.execSQL("UPDATE " + TABLE_NAME + " SET " + db.execSQL("UPDATE " + TABLE_NAME + " SET " +
READ + " = " + ReadStatus.UNREAD.serialize() + ", " + READ + " = " + ReadStatus.UNREAD.serialize() + ", " +
UNREAD_COUNT + " = " + UNREAD_COUNT + " + ?, " + UNREAD_COUNT + " = " + UNREAD_COUNT + " + ?, " +
UNREAD_SELF_MENTION_COUNT + " = " + UNREAD_SELF_MENTION_COUNT + " + ?, " +
LAST_SCROLLED + " = ? " + LAST_SCROLLED + " = ? " +
"WHERE " + ID + " = ?", "WHERE " + ID + " = ?",
SqlUtil.buildArgs(amount, 0, threadId)); SqlUtil.buildArgs(unreadAmount, unreadSelfMentionAmount, 0, threadId));
} }
public void setDistributionType(long threadId, int distributionType) { public void setDistributionType(long threadId, int distributionType) {
@ -1225,10 +1232,12 @@ public class ThreadDatabase extends Database {
void updateReadState(long threadId) { void updateReadState(long threadId) {
ThreadRecord previous = getThreadRecord(threadId); ThreadRecord previous = getThreadRecord(threadId);
int unreadCount = SignalDatabase.mmsSms().getUnreadCount(threadId); int unreadCount = SignalDatabase.mmsSms().getUnreadCount(threadId);
int unreadMentionsCount = SignalDatabase.mms().getUnreadMentionCount(threadId);
ContentValues contentValues = new ContentValues(); ContentValues contentValues = new ContentValues();
contentValues.put(READ, unreadCount == 0 ? ReadStatus.READ.serialize() : ReadStatus.UNREAD.serialize()); contentValues.put(READ, unreadCount == 0 ? ReadStatus.READ.serialize() : ReadStatus.UNREAD.serialize());
contentValues.put(UNREAD_COUNT, unreadCount); contentValues.put(UNREAD_COUNT, unreadCount);
contentValues.put(UNREAD_SELF_MENTION_COUNT, unreadMentionsCount);
databaseHelper.getSignalWritableDatabase().update(TABLE_NAME, contentValues, ID_WHERE, SqlUtil.buildArgs(threadId)); databaseHelper.getSignalWritableDatabase().update(TABLE_NAME, contentValues, ID_WHERE, SqlUtil.buildArgs(threadId));
@ -1317,9 +1326,11 @@ public class ThreadDatabase extends Database {
} else { } else {
if (threadId != null) { if (threadId != null) {
int unreadCount = SignalDatabase.mmsSms().getUnreadCount(threadId); int unreadCount = SignalDatabase.mmsSms().getUnreadCount(threadId);
int unreadMentionsCount = SignalDatabase.mms().getUnreadMentionCount(threadId);
values.put(READ, unreadCount == 0 ? ReadStatus.READ.serialize() : ReadStatus.UNREAD.serialize()); values.put(READ, unreadCount == 0 ? ReadStatus.READ.serialize() : ReadStatus.UNREAD.serialize());
values.put(UNREAD_COUNT, unreadCount); values.put(UNREAD_COUNT, unreadCount);
values.put(UNREAD_SELF_MENTION_COUNT, unreadMentionsCount);
} }
} }
@ -1723,6 +1734,7 @@ public class ThreadDatabase extends Database {
.setUnreadCount(cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.UNREAD_COUNT))) .setUnreadCount(cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.UNREAD_COUNT)))
.setForcedUnread(cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.READ)) == ReadStatus.FORCED_UNREAD.serialize()) .setForcedUnread(cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.READ)) == ReadStatus.FORCED_UNREAD.serialize())
.setPinned(CursorUtil.requireBoolean(cursor, ThreadDatabase.PINNED)) .setPinned(CursorUtil.requireBoolean(cursor, ThreadDatabase.PINNED))
.setUnreadSelfMentionsCount(CursorUtil.requireInt(cursor, ThreadDatabase.UNREAD_SELF_MENTION_COUNT))
.setExtra(extra) .setExtra(extra)
.build(); .build();
} }

Wyświetl plik

@ -56,6 +56,7 @@ public final class ThreadRecord {
private final long expiresIn; private final long expiresIn;
private final long lastSeen; private final long lastSeen;
private final boolean isPinned; private final boolean isPinned;
private final int unreadSelfMentionsCount;
private ThreadRecord(@NonNull Builder builder) { private ThreadRecord(@NonNull Builder builder) {
this.threadId = builder.threadId; this.threadId = builder.threadId;
@ -77,6 +78,7 @@ public final class ThreadRecord {
this.expiresIn = builder.expiresIn; this.expiresIn = builder.expiresIn;
this.lastSeen = builder.lastSeen; this.lastSeen = builder.lastSeen;
this.isPinned = builder.isPinned; this.isPinned = builder.isPinned;
this.unreadSelfMentionsCount = builder.unreadSelfMentionsCount;
} }
public long getThreadId() { public long getThreadId() {
@ -103,10 +105,6 @@ public final class ThreadRecord {
return contentType; return contentType;
} }
public boolean hasMeaningfulMessages() {
return meaningfulMessages;
}
public int getUnreadCount() { public int getUnreadCount() {
return unreadCount; return unreadCount;
} }
@ -207,10 +205,6 @@ public final class ThreadRecord {
} }
} }
public boolean isGv2Invite() {
return extra != null && extra.isGv2Invite();
}
public boolean isMessageRequestAccepted() { public boolean isMessageRequestAccepted() {
if (extra != null) return extra.isMessageRequestAccepted(); if (extra != null) return extra.isMessageRequestAccepted();
else return true; else return true;
@ -220,6 +214,10 @@ public final class ThreadRecord {
return isPinned; return isPinned;
} }
public int getUnreadSelfMentionsCount() {
return unreadSelfMentionsCount;
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;
@ -241,6 +239,7 @@ public final class ThreadRecord {
isPinned == that.isPinned && isPinned == that.isPinned &&
body.equals(that.body) && body.equals(that.body) &&
recipient.equals(that.recipient) && recipient.equals(that.recipient) &&
unreadSelfMentionsCount == that.unreadSelfMentionsCount &&
Objects.equals(snippetUri, that.snippetUri) && Objects.equals(snippetUri, that.snippetUri) &&
Objects.equals(contentType, that.contentType) && Objects.equals(contentType, that.contentType) &&
Objects.equals(extra, that.extra); Objects.equals(extra, that.extra);
@ -266,7 +265,8 @@ public final class ThreadRecord {
archived, archived,
expiresIn, expiresIn,
lastSeen, lastSeen,
isPinned); isPinned,
unreadSelfMentionsCount);
} }
public static class Builder { public static class Builder {
@ -289,6 +289,7 @@ public final class ThreadRecord {
private long expiresIn; private long expiresIn;
private long lastSeen; private long lastSeen;
private boolean isPinned; private boolean isPinned;
private int unreadSelfMentionsCount;
public Builder(long threadId) { public Builder(long threadId) {
this.threadId = threadId; this.threadId = threadId;
@ -389,6 +390,11 @@ public final class ThreadRecord {
return this; return this;
} }
public Builder setUnreadSelfMentionsCount(int unreadSelfMentionsCount) {
this.unreadSelfMentionsCount = unreadSelfMentionsCount;
return this;
}
public ThreadRecord build() { public ThreadRecord build() {
if (distributionType == ThreadDatabase.DistributionTypes.CONVERSATION) { if (distributionType == ThreadDatabase.DistributionTypes.CONVERSATION) {
Preconditions.checkArgument(threadId > 0); Preconditions.checkArgument(threadId > 0);

Wyświetl plik

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12dp"
android:height="12dp"
android:viewportWidth="12"
android:viewportHeight="12">
<path
android:fillColor="#FF000000"
android:pathData="M11,5.44c0,1.96 -0.87,3.27 -2.31,3.27 -0.7,0 -1.3,-0.42 -1.38,-1.03h-0.05c-0.26,0.62 -0.84,0.98 -1.56,0.98 -1.28,0 -2.14,-1.05 -2.14,-2.61s0.88,-2.54 2.14,-2.54c0.66,0 1.25,0.34 1.49,0.87h0.05v-0.75h0.93v3.6c0,0.4 0.22,0.68 0.69,0.68 0.73,0 1.27,-0.9 1.27,-2.49 0,-2.23 -1.69,-3.73 -4.14,-3.73S1.88,3.51 1.88,6.08c0,2.78 1.85,4.31 4.32,4.31 0.82,0 1.66,-0.12 2.06,-0.29v0.77c-0.54,0.19 -1.28,0.3 -2.07,0.3 -3,0 -5.18,-1.82 -5.18,-5.13C1.01,2.98 3.1,0.92 6.08,0.92s4.92,1.81 4.92,4.52ZM4.55,6.07c0,1.07 0.49,1.72 1.3,1.72s1.38,-0.67 1.38,-1.72 -0.53,-1.71 -1.37,-1.71 -1.31,0.64 -1.31,1.71Z"/>
</vector>

Wyświetl plik

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:fillColor="#FF000000"
android:pathData="M18.33,9.07c0,3.27 -1.45,5.45 -3.85,5.45 -1.17,0 -2.17,-0.7 -2.29,-1.72h-0.08c-0.44,1.03 -1.39,1.63 -2.6,1.63 -2.13,0 -3.56,-1.75 -3.56,-4.35s1.46,-4.23 3.56,-4.23c1.1,0 2.09,0.57 2.48,1.44h0.08v-1.25h1.55v6.01c0,0.67 0.37,1.14 1.16,1.14 1.22,0 2.12,-1.49 2.12,-4.14 0,-3.71 -2.82,-6.22 -6.9,-6.22S3.12,5.86 3.12,10.13c0,4.64 3.09,7.18 7.2,7.18 1.37,0 2.76,-0.19 3.43,-0.49v1.29c-0.9,0.32 -2.13,0.5 -3.45,0.5 -4.99,0 -8.63,-3.04 -8.63,-8.54C1.67,4.97 5.15,1.54 10.13,1.54s8.21,3.02 8.21,7.53ZM7.59,10.12c0,1.78 0.82,2.87 2.16,2.87s2.3,-1.12 2.3,-2.87 -0.89,-2.85 -2.28,-2.85 -2.18,1.06 -2.18,2.85Z"/>
</vector>

Wyświetl plik

@ -73,10 +73,11 @@
android:layout_marginEnd="10dp" android:layout_marginEnd="10dp"
android:layout_marginBottom="12dp" android:layout_marginBottom="12dp"
android:visibility="invisible" android:visibility="invisible"
app:cstv_scroll_button_src="@drawable/ic_at_24" app:cstv_scroll_button_src="@drawable/ic_at_20"
app:layout_constraintBottom_toTopOf="@id/scroll_to_bottom" app:layout_constraintBottom_toTopOf="@id/scroll_to_bottom"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_goneMarginBottom="20dp" /> app:layout_goneMarginBottom="20dp"
tools:visibility="visible" />
<org.thoughtcrime.securesms.components.ConversationScrollToView <org.thoughtcrime.securesms.components.ConversationScrollToView
android:id="@+id/scroll_to_bottom" android:id="@+id/scroll_to_bottom"
@ -87,7 +88,8 @@
android:visibility="invisible" android:visibility="invisible"
app:cstv_scroll_button_src="@drawable/ic_chevron_down_20" app:cstv_scroll_button_src="@drawable/ic_chevron_down_20"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" /> app:layout_constraintEnd_toEndOf="parent"
tools:visibility="visible" />
<org.thoughtcrime.securesms.components.menu.SignalBottomActionBar <org.thoughtcrime.securesms.components.menu.SignalBottomActionBar
android:id="@+id/conversation_bottom_action_bar" android:id="@+id/conversation_bottom_action_bar"

Wyświetl plik

@ -137,6 +137,7 @@
android:layout_marginStart="12dp" android:layout_marginStart="12dp"
android:layout_marginTop="6dp" android:layout_marginTop="6dp"
android:gravity="center" android:gravity="center"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/conversation_list_item_date"> app:layout_constraintTop_toBottomOf="@id/conversation_list_item_date">
@ -147,12 +148,27 @@
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
app:iconColor="@color/signal_colorOnSurfaceVariant" /> app:iconColor="@color/signal_colorOnSurfaceVariant" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/conversation_list_item_unread_mentions_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:background="@drawable/unread_count_background_new"
android:includeFontPadding="false"
android:minWidth="18dp"
android:minHeight="18dp"
android:padding="3dp"
android:visibility="gone"
app:srcCompat="@drawable/ic_at_12"
app:tint="@color/signal_colorOnPrimary"
tools:visibility="visible" />
<TextView <TextView
android:id="@+id/conversation_list_item_unread_indicator" android:id="@+id/conversation_list_item_unread_indicator"
style="@style/Signal.Text.LabelMedium" style="@style/Signal.Text.LabelMedium"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="12dp" android:layout_marginStart="6dp"
android:background="@drawable/unread_count_background_new" android:background="@drawable/unread_count_background_new"
android:includeFontPadding="false" android:includeFontPadding="false"
android:minWidth="18dp" android:minWidth="18dp"

Wyświetl plik

@ -9,9 +9,10 @@
<ImageButton <ImageButton
android:id="@+id/conversation_scroll_to_button" android:id="@+id/conversation_scroll_to_button"
android:layout_width="32dp" android:layout_width="36dp"
android:layout_height="32dp" android:layout_height="36dp"
android:layout_gravity="bottom|center" android:layout_gravity="bottom|center"
android:layout_marginTop="9dp"
android:layout_marginBottom="4dp" android:layout_marginBottom="4dp"
android:background="@drawable/scroll_to_bottom_background_normal" android:background="@drawable/scroll_to_bottom_background_normal"
android:contentDescription="@string/conversation_fragment__scroll_to_the_bottom_content_description" android:contentDescription="@string/conversation_fragment__scroll_to_the_bottom_content_description"
@ -24,12 +25,13 @@
android:id="@+id/conversation_scroll_to_count" android:id="@+id/conversation_scroll_to_count"
style="@style/Signal.Text.Caption" style="@style/Signal.Text.Caption"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="16dp" android:layout_height="18dp"
android:layout_gravity="top|center" android:layout_gravity="top|center"
android:layout_marginBottom="26dp" android:layout_marginBottom="26dp"
android:background="@drawable/unread_count_background" android:background="@drawable/unread_count_background"
android:elevation="1dp" android:elevation="1dp"
android:gravity="center" android:gravity="center"
android:minWidth="18dp"
android:paddingLeft="4dp" android:paddingLeft="4dp"
android:paddingRight="4dp" android:paddingRight="4dp"
android:textColor="@color/core_white" android:textColor="@color/core_white"