Merge remote-tracking branch 'upstream/main'

This commit is contained in:
adbenitez
2024-01-31 01:29:44 -05:00
5 changed files with 119 additions and 66 deletions
+18 -1
View File
@@ -24,16 +24,33 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/self_avatar_container"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="45dp">
<org.thoughtcrime.securesms.components.AvatarView
android:id="@+id/self_avatar"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_gravity="center_vertical"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:clickable="true"
app:inverted="true"
android:contentDescription="@string/pref_profile_info_headline" />
<ImageView android:id="@+id/unread_indicator"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginLeft="20dp"
android:layout_marginStart="20dp"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginBottom="16dp"
android:contentDescription="@null"
android:visibility="gone"
/>
</RelativeLayout>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView style="@style/TextSecure.TitleTextStyle"
android:id="@+id/toolbar_title"
@@ -28,6 +28,8 @@ import static org.thoughtcrime.securesms.util.RelayUtil.isRelayingMessageContent
import static org.thoughtcrime.securesms.util.RelayUtil.resetRelayingMessageContent;
import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -48,6 +50,8 @@ import androidx.appcompat.widget.Toolbar;
import androidx.appcompat.widget.TooltipCompat;
import androidx.core.view.MenuCompat;
import com.amulyakhare.textdrawable.TextDrawable;
import com.b44t.messenger.DcAccounts;
import com.b44t.messenger.DcContact;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcMsg;
@@ -71,6 +75,7 @@ import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.Prefs;
import org.thoughtcrime.securesms.util.SendRelayedMessageUtil;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import java.io.FileOutputStream;
import java.io.InputStream;
@@ -89,10 +94,12 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
private ConversationListFragment conversationListFragment;
public TextView title;
private AvatarView selfAvatar;
private ImageView unreadIndicator;
private SearchFragment searchFragment;
private SearchToolbar searchToolbar;
private ImageView searchAction;
private ViewGroup fragmentContainer;
private ViewGroup selfAvatarContainer;
@Override
protected void onPreCreate() {
@@ -131,6 +138,8 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
selfAvatar = findViewById(R.id.self_avatar);
selfAvatarContainer = findViewById(R.id.self_avatar_container);
unreadIndicator = findViewById(R.id.unread_indicator);
title = findViewById(R.id.toolbar_title);
searchToolbar = findViewById(R.id.search_toolbar);
searchAction = findViewById(R.id.search_action);
@@ -231,6 +240,7 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
}
refreshAvatar();
refreshUnreadIndicator();
refreshTitle();
handleOpenpgp4fpr();
if (isDirectSharing(this)) {
@@ -266,9 +276,9 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
public void refreshAvatar() {
if (isRelayingMessageContent(this)) {
selfAvatar.setVisibility(View.GONE);
selfAvatarContainer.setVisibility(View.GONE);
} else {
selfAvatar.setVisibility(View.VISIBLE);
selfAvatarContainer.setVisibility(View.VISIBLE);
DcContext dcContext = DcHelper.getContext(this);
DcContact self = dcContext.getContact(DcContact.DC_CONTACT_ID_SELF);
String name = dcContext.getConfig("displayname");
@@ -279,6 +289,39 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
}
}
public void refreshUnreadIndicator() {
int unreadCount = 0;
DcAccounts dcAccounts = DcHelper.getAccounts(this);
int skipId = dcAccounts.getSelectedAccount().getAccountId();
for (int accountId : dcAccounts.getAll()) {
if (accountId != skipId) {
unreadCount += dcAccounts.getAccount(accountId).getFreshMsgs().length;
}
}
if(unreadCount == 0) {
unreadIndicator.setVisibility(View.GONE);
} else {
boolean isDarkTheme = DynamicTheme.isDarkTheme(this);
int badgeColor = Color.WHITE;
if (isDarkTheme) {
final TypedArray attrs = obtainStyledAttributes(new int[] {
R.attr.conversation_list_item_unreadcount_color,
});
badgeColor = attrs.getColor(0, Color.BLACK);
}
unreadIndicator.setImageDrawable(TextDrawable.builder()
.beginConfig()
.width(ViewUtil.dpToPx(this, 20))
.height(ViewUtil.dpToPx(this, 20))
.textColor(isDarkTheme? Color.WHITE : Color.BLACK)
.bold()
.endConfig()
.buildRound(String.valueOf(unreadCount), badgeColor));
unreadIndicator.setVisibility(View.VISIBLE);
}
}
@Override
public void onResume() {
super.onResume();
@@ -409,7 +452,7 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
private void handleResetRelaying() {
resetRelayingMessageContent(this);
refreshTitle();
selfAvatar.setVisibility(View.VISIBLE);
selfAvatarContainer.setVisibility(View.VISIBLE);
conversationListFragment.onNewIntent();
invalidateOptionsMenu();
}
@@ -112,11 +112,11 @@ public class ConversationListFragment extends Fragment
archive = getArguments().getBoolean(ARCHIVE, false);
DcEventCenter eventCenter = DcHelper.getEventCenter(getActivity());
eventCenter.addMultiAccountObserver(DcContext.DC_EVENT_INCOMING_MSG, this);
eventCenter.addMultiAccountObserver(DcContext.DC_EVENT_MSGS_NOTICED, this);
eventCenter.addObserver(DcContext.DC_EVENT_CHAT_MODIFIED, this);
eventCenter.addObserver(DcContext.DC_EVENT_CONTACTS_CHANGED, this);
eventCenter.addObserver(DcContext.DC_EVENT_INCOMING_MSG, this);
eventCenter.addObserver(DcContext.DC_EVENT_MSGS_CHANGED, this);
eventCenter.addObserver(DcContext.DC_EVENT_MSGS_NOTICED, this);
eventCenter.addObserver(DcContext.DC_EVENT_MSG_DELIVERED, this);
eventCenter.addObserver(DcContext.DC_EVENT_MSG_FAILED, this);
eventCenter.addObserver(DcContext.DC_EVENT_MSG_READ, this);
@@ -632,7 +632,13 @@ public class ConversationListFragment extends Fragment
@Override
public void handleEvent(@NonNull DcEvent event) {
if (event.getId() == DcContext.DC_EVENT_CONNECTIVITY_CHANGED) {
if (event.getAccountId() != DcHelper.getContext(getActivity()).getAccountId()) {
Activity activity = getActivity();
if (activity instanceof ConversationListActivity) {
((ConversationListActivity) activity).refreshUnreadIndicator();
}
} else if (event.getId() == DcContext.DC_EVENT_CONNECTIVITY_CHANGED) {
Activity activity = getActivity();
if (activity instanceof ConversationListActivity) {
((ConversationListActivity) activity).refreshTitle();
@@ -39,8 +39,9 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv
recyclerView.setAdapter(adapter);
refreshData();
DcEventCenter eventCenter = DcHelper.getEventCenter(requireActivity());
eventCenter.addObserver(DcContext.DC_EVENT_CONNECTIVITY_CHANGED, this);
eventCenter.addObserver(DcContext.DC_EVENT_INCOMING_MSG, this);
eventCenter.addMultiAccountObserver(DcContext.DC_EVENT_CONNECTIVITY_CHANGED, this);
eventCenter.addMultiAccountObserver(DcContext.DC_EVENT_INCOMING_MSG, this);
eventCenter.addMultiAccountObserver(DcContext.DC_EVENT_MSGS_NOTICED, this);
}
@NonNull
@@ -62,11 +63,13 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv
}
@Override
public void handleEvent(@NonNull DcEvent event) {
public void onDestroy() {
super.onDestroy();
DcHelper.getEventCenter(requireActivity()).removeObservers(this);
}
@Override
public void handleEvent2(@NonNull DcEvent event) {
public void handleEvent(@NonNull DcEvent event) {
refreshData();
}
@@ -17,14 +17,13 @@ import java.util.ArrayList;
import java.util.Hashtable;
public class DcEventCenter {
private @NonNull final Hashtable<Integer, ArrayList<DcEventDelegate>> allObservers = new Hashtable<>();
private @NonNull final Hashtable<Integer, ArrayList<DcEventDelegate>> currentAccountObservers = new Hashtable<>();
private @NonNull final Hashtable<Integer, ArrayList<DcEventDelegate>> multiAccountObservers = new Hashtable<>();
private final Object LOCK = new Object();
private final @NonNull ApplicationContext context;
public interface DcEventDelegate {
void handleEvent(@NonNull DcEvent event);
default void handleEvent2(@NonNull DcEvent event) {
}
default boolean runOnMain() {
return true;
}
@@ -35,10 +34,18 @@ public class DcEventCenter {
}
public void addObserver(int eventId, @NonNull DcEventDelegate observer) {
addObserver(currentAccountObservers, eventId, observer);
}
public void addMultiAccountObserver(int eventId, @NonNull DcEventDelegate observer) {
addObserver(multiAccountObservers, eventId, observer);
}
private void addObserver(Hashtable<Integer, ArrayList<DcEventDelegate>> observers, int eventId, @NonNull DcEventDelegate observer) {
synchronized (LOCK) {
ArrayList<DcEventDelegate> idObservers = allObservers.get(eventId);
ArrayList<DcEventDelegate> idObservers = observers.get(eventId);
if (idObservers == null) {
allObservers.put(eventId, (idObservers = new ArrayList<>()));
observers.put(eventId, (idObservers = new ArrayList<>()));
}
idObservers.add(observer);
}
@@ -46,7 +53,11 @@ public class DcEventCenter {
public void removeObserver(int eventId, DcEventDelegate observer) {
synchronized (LOCK) {
ArrayList<DcEventDelegate> idObservers = allObservers.get(eventId);
ArrayList<DcEventDelegate> idObservers = currentAccountObservers.get(eventId);
if (idObservers != null) {
idObservers.remove(observer);
}
idObservers = multiAccountObservers.get(eventId);
if (idObservers != null) {
idObservers.remove(observer);
}
@@ -55,8 +66,14 @@ public class DcEventCenter {
public void removeObservers(DcEventDelegate observer) {
synchronized (LOCK) {
for(Integer eventId : allObservers.keySet()) {
ArrayList<DcEventDelegate> idObservers = allObservers.get(eventId);
for(Integer eventId : currentAccountObservers.keySet()) {
ArrayList<DcEventDelegate> idObservers = currentAccountObservers.get(eventId);
if (idObservers != null) {
idObservers.remove(observer);
}
}
for(Integer eventId : multiAccountObservers.keySet()) {
ArrayList<DcEventDelegate> idObservers = multiAccountObservers.get(eventId);
if (idObservers != null) {
idObservers.remove(observer);
}
@@ -64,41 +81,17 @@ public class DcEventCenter {
}
}
public void sendToObservers(@NonNull DcEvent event) {
synchronized (LOCK) {
ArrayList<DcEventDelegate> idObservers = allObservers.get(event.getId());
if (idObservers != null) {
for (DcEventDelegate observer : idObservers) {
// using try/catch blocks as under some circumstances eg. getContext() may return NULL -
// and as this function is used virtually everywhere, also in libs,
// it's not feasible to check all single occurrences.
if(observer.runOnMain()) {
Util.runOnMain(() -> {
try {
observer.handleEvent(event);
}
catch(Exception e) {
e.printStackTrace();
}
});
} else {
Util.runOnBackground(() -> {
try {
observer.handleEvent(event);
}
catch (Exception e) {
e.printStackTrace();
}
});
}
}
}
}
private void sendToMultiAccountObservers(@NonNull DcEvent event) {
sendToObservers(multiAccountObservers, event);
}
public void sendToObservers2(@NonNull DcEvent event) {
private void sendToCurrentAccountObservers(@NonNull DcEvent event) {
sendToObservers(currentAccountObservers, event);
}
private void sendToObservers(Hashtable<Integer, ArrayList<DcEventDelegate>> observers, @NonNull DcEvent event) {
synchronized (LOCK) {
ArrayList<DcEventDelegate> idObservers = allObservers.get(event.getId());
ArrayList<DcEventDelegate> idObservers = observers.get(event.getId());
if (idObservers != null) {
for (DcEventDelegate observer : idObservers) {
// using try/catch blocks as under some circumstances eg. getContext() may return NULL -
@@ -107,7 +100,7 @@ public class DcEventCenter {
if(observer.runOnMain()) {
Util.runOnMain(() -> {
try {
observer.handleEvent2(event);
observer.handleEvent(event);
}
catch(Exception e) {
e.printStackTrace();
@@ -116,7 +109,7 @@ public class DcEventCenter {
} else {
Util.runOnBackground(() -> {
try {
observer.handleEvent2(event);
observer.handleEvent(event);
}
catch (Exception e) {
e.printStackTrace();
@@ -173,7 +166,7 @@ public class DcEventCenter {
int accountId = event.getAccountId();
int id = event.getId();
sendToObservers2(event);
sendToMultiAccountObservers(event);
switch (id) {
case DcContext.DC_EVENT_INCOMING_MSG:
@@ -185,7 +178,7 @@ public class DcEventCenter {
break;
case DcContext.DC_EVENT_IMEX_PROGRESS:
sendToObservers(event);
sendToCurrentAccountObservers(event);
return 0;
}
@@ -210,18 +203,9 @@ public class DcEventCenter {
handleError(id, event.getData2Str());
break;
case DcContext.DC_EVENT_INCOMING_MSG:
sendToObservers(event);
default:
sendToCurrentAccountObservers(event);
break;
case DcContext.DC_EVENT_MSGS_NOTICED:
sendToObservers(event);
break;
default: {
sendToObservers(event);
}
break;
}
if (id == DcContext.DC_EVENT_CHAT_MODIFIED) {