diff --git a/jni/dc_wrapper.c b/jni/dc_wrapper.c index a479b09e3..b33ce19b3 100644 --- a/jni/dc_wrapper.c +++ b/jni/dc_wrapper.c @@ -391,12 +391,6 @@ JNIEXPORT void Java_com_b44t_messenger_DcContext_marknoticedChat(JNIEnv *env, jo } -JNIEXPORT void Java_com_b44t_messenger_DcContext_marknoticedContact(JNIEnv *env, jobject obj, jint contact_id) -{ - dc_marknoticed_contact(get_dc_context(env, obj), contact_id); -} - - JNIEXPORT void Java_com_b44t_messenger_DcContext_setChatVisibility(JNIEnv *env, jobject obj, jint chat_id, jint visibility) { dc_set_chat_visibility(get_dc_context(env, obj), chat_id, visibility); @@ -409,12 +403,6 @@ JNIEXPORT jint Java_com_b44t_messenger_DcContext_createChatByContactId(JNIEnv *e } -JNIEXPORT jint Java_com_b44t_messenger_DcContext_createChatByMsgId(JNIEnv *env, jobject obj, jint msg_id) -{ - return (jint)dc_create_chat_by_msg_id(get_dc_context(env, obj), msg_id); -} - - JNIEXPORT jint Java_com_b44t_messenger_DcContext_createGroupChat(JNIEnv *env, jobject obj, jboolean verified, jstring name) { CHAR_REF(name); @@ -481,6 +469,12 @@ JNIEXPORT void Java_com_b44t_messenger_DcContext_deleteChat(JNIEnv *env, jobject /* DcContext - handle messages */ +JNIEXPORT jint Java_com_b44t_messenger_DcContext_decideOnContactRequest(JNIEnv *env, jobject obj, jint msg_id, jint decision) +{ + return (jint)dc_decide_on_contact_request(get_dc_context(env, obj), msg_id, decision); +} + + JNIEXPORT jint Java_com_b44t_messenger_DcContext_getFreshMsgCount(JNIEnv *env, jobject obj, jint chat_id) { return dc_get_fresh_msg_cnt(get_dc_context(env, obj), chat_id); @@ -493,7 +487,6 @@ JNIEXPORT jint Java_com_b44t_messenger_DcContext_estimateDeletionCount(JNIEnv *e } - JNIEXPORT jlong Java_com_b44t_messenger_DcContext_getMsgCPtr(JNIEnv *env, jobject obj, jint id) { return (jlong)dc_get_msg(get_dc_context(env, obj), id); @@ -1026,9 +1019,9 @@ JNIEXPORT jint Java_com_b44t_messenger_DcChat_getId(JNIEnv *env, jobject obj) } -JNIEXPORT jboolean Java_com_b44t_messenger_DcChat_isGroup(JNIEnv *env, jobject obj) +JNIEXPORT jint Java_com_b44t_messenger_DcChat_getType(JNIEnv *env, jobject obj) { - return dc_chat_get_type(get_dc_chat(env, obj)) == DC_CHAT_TYPE_GROUP; + return dc_chat_get_type(get_dc_chat(env, obj)); } @@ -1245,6 +1238,12 @@ JNIEXPORT jint Java_com_b44t_messenger_DcMsg_getChatId(JNIEnv *env, jobject obj) } +JNIEXPORT jint Java_com_b44t_messenger_DcMsg_getRealChatId(JNIEnv *env, jobject obj) +{ + return dc_msg_get_real_chat_id(get_dc_msg(env, obj)); +} + + JNIEXPORT jint Java_com_b44t_messenger_DcMsg_getFromId(JNIEnv *env, jobject obj) { return dc_msg_get_from_id(get_dc_msg(env, obj)); @@ -1298,6 +1297,18 @@ JNIEXPORT jstring Java_com_b44t_messenger_DcMsg_getSummarytext(JNIEnv *env, jobj } +JNIEXPORT jstring Java_com_b44t_messenger_DcMsg_getOverrideSenderName(JNIEnv *env, jobject obj) +{ + char* temp = dc_msg_get_override_sender_name(get_dc_msg(env, obj)); + jstring ret = NULL; + if (temp) { + JSTRING_NEW(temp); + } + dc_str_unref(temp); + return ret; // null if there is no override-sender-name +} + + JNIEXPORT jint Java_com_b44t_messenger_DcMsg_showPadlock(JNIEnv *env, jobject obj) { return dc_msg_get_showpadlock(get_dc_msg(env, obj)); @@ -1451,7 +1462,6 @@ JNIEXPORT jstring Java_com_b44t_messenger_DcMsg_getError(JNIEnv *env, jobject ob } - /******************************************************************************* * DcContact ******************************************************************************/ diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index e85be47e2..f85d1186e 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -185,6 +185,8 @@ Im Chat zeigen Teilen + + Blockieren Kontakt blockieren Kontakt nicht mehr blockieren Wiedergabe @@ -332,6 +334,11 @@ Kann Anhang nicht laden + + Mailingliste + Mailingliste \"%1$s\" anzeigen? + + Standorte im Zeitrahmen anzeigen Spuren anzeigen diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 686d80c47..90f13d62c 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -197,6 +197,8 @@ Показать в чате Поделиться + + Заблокировать Заблокировать контакт Разблокировать контакт Воспроизвести @@ -358,6 +360,11 @@ Не удалось загрузить вложение + + Список рассылки + Показывать список рассылки «%1$s»? + + Показать местоположения с интервалом времени Показывать маршруты diff --git a/res/values/strings.xml b/res/values/strings.xml index e73306ff3..d7833e141 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -187,6 +187,8 @@ Show in chat Share + + Block Block contact Unblock contact Play @@ -334,6 +336,11 @@ Failed to load attachment + + Mailing list + Show mailing list \"%1$s\"? + + Show locations in time frame Show traces diff --git a/src/com/b44t/messenger/DcChat.java b/src/com/b44t/messenger/DcChat.java index 9d779e7d8..68f106b75 100644 --- a/src/com/b44t/messenger/DcChat.java +++ b/src/com/b44t/messenger/DcChat.java @@ -1,9 +1,12 @@ package com.b44t.messenger; -import org.thoughtcrime.securesms.connect.ApplicationDcContext; - public class DcChat { + public static final int DC_CHAT_TYPE_UNDEFINED = 0; + public static final int DC_CHAT_TYPE_SINGLE = 100; + public static final int DC_CHAT_TYPE_GROUP = 120; + public static final int DC_CHAT_TYPE_MAILINGLIST = 140; + public static final int DC_CHAT_NO_CHAT = 0; public final static int DC_CHAT_ID_DEADDROP = 1; public final static int DC_CHAT_ID_ARCHIVED_LINK = 6; @@ -25,7 +28,7 @@ public class DcChat { } public native int getId (); - public native boolean isGroup (); + public native int getType (); public native int getVisibility (); public native String getName (); public native String getProfileImage (); @@ -38,11 +41,27 @@ public class DcChat { public native boolean isSendingLocations(); public native boolean isMuted (); + + // aliases and higher-level tools + + public boolean isGroup() { + // isMultiUser() might fit better, + // however, would result in lots of code changes, so we leave this as is for now. + int type = getType(); + return type == DC_CHAT_TYPE_GROUP || type == DC_CHAT_TYPE_MAILINGLIST; + } + + public boolean isMailingList() { + return getType() == DC_CHAT_TYPE_MAILINGLIST; + } + public boolean canVideochat() { return canSend() && !isGroup() && !isSelfTalk(); } + // working with raw c-data + private long chatCPtr; // CAVE: the name is referenced in the JNI private native void unrefChatCPtr(); public long getChatCPtr () { return chatCPtr; } diff --git a/src/com/b44t/messenger/DcContext.java b/src/com/b44t/messenger/DcContext.java index 3fd26f31c..796eee355 100644 --- a/src/com/b44t/messenger/DcContext.java +++ b/src/com/b44t/messenger/DcContext.java @@ -71,6 +71,10 @@ public class DcContext { public final static int DC_MEDIA_QUALITY_BALANCED = 0; public final static int DC_MEDIA_QUALITY_WORSE = 1; + public final static int DC_DECISION_START_CHAT = 0; + public final static int DC_DECISION_BLOCK = 1; + public final static int DC_DECISION_NOT_NOW = 2; + public DcContext(String osName, String dbfile) { contextCPtr = createContextCPtr(osName, dbfile); } @@ -132,11 +136,9 @@ public class DcContext { public native String getChatEncrInfo (int chat_id); public native void markseenMsgs (int msg_ids[]); public native void marknoticedChat (int chat_id); - public native void marknoticedContact (int contact_id); public native void setChatVisibility (int chat_id, int visibility); public native int getChatIdByContactId (int contact_id); public native int createChatByContactId(int contact_id); - public native int createChatByMsgId (int msg_id); public native int createGroupChat (boolean verified, String name); public native boolean isContactInChat (int chat_id, int contact_id); public native int addContactToChat (int chat_id, int contact_id); @@ -155,6 +157,7 @@ public class DcContext { public native boolean setChatEphemeralTimer (int chat_id, int timer); public native boolean setChatMuteDuration (int chat_id, long duration); public native void deleteChat (int chat_id); + public native int decideOnContactRequest(int msg_id, int decision); public @NonNull DcMsg getMsg (int msg_id) { return new DcMsg(getMsgCPtr(msg_id)); } public native String getMsgInfo (int id); public native String getMsgHtml (int msg_id); diff --git a/src/com/b44t/messenger/DcMsg.java b/src/com/b44t/messenger/DcMsg.java index 25c47ee13..657bb5116 100644 --- a/src/com/b44t/messenger/DcMsg.java +++ b/src/com/b44t/messenger/DcMsg.java @@ -3,6 +3,7 @@ package com.b44t.messenger; import android.util.Log; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import org.thoughtcrime.securesms.connect.ApplicationDcContext; @@ -98,6 +99,7 @@ public class DcMsg { public native int getType (); public native int getState (); public native int getChatId (); + public native int getRealChatId (); public native int getFromId (); public native int getWidth (int def); public native int getHeight (int def); @@ -127,6 +129,16 @@ public class DcMsg { public void setQuote (DcMsg quote) { setQuoteCPtr(quote.msgCPtr); } public native String getQuotedText (); public native String getError (); + private native @Nullable String getOverrideSenderName(); + + public @NonNull String getSenderName(@NonNull DcContact dcContact) { + String overrideName = getOverrideSenderName(); + if (overrideName != null) { + return overrideName; + } else { + return dcContact.getDisplayName(); + } + } public DcMsg getQuotedMsg () { long cPtr = getQuotedMsgCPtr(); diff --git a/src/org/thoughtcrime/securesms/ConversationActivity.java b/src/org/thoughtcrime/securesms/ConversationActivity.java index 73df0c842..63c96a7d7 100644 --- a/src/org/thoughtcrime/securesms/ConversationActivity.java +++ b/src/org/thoughtcrime/securesms/ConversationActivity.java @@ -476,7 +476,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity } if (isGroupConversation()) { - if (isActiveGroup()) { + if (!dcChat.isMailingList()) { // Leaving mailing lists is currently not supported inflater.inflate(R.menu.conversation_push_group_options, menu); } } @@ -1021,10 +1021,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity composeText.append(name + "\n" + mail); } - private boolean isActiveGroup() { - return dcChat.isGroup(); - } - private boolean isGroupConversation() { return dcChat.isGroup(); } diff --git a/src/org/thoughtcrime/securesms/ConversationItem.java b/src/org/thoughtcrime/securesms/ConversationItem.java index 5051ca971..264ee1c39 100644 --- a/src/org/thoughtcrime/securesms/ConversationItem.java +++ b/src/org/thoughtcrime/securesms/ConversationItem.java @@ -43,6 +43,7 @@ import androidx.appcompat.app.AlertDialog; import com.b44t.messenger.DcChat; import com.b44t.messenger.DcContact; +import com.b44t.messenger.DcContext; import com.b44t.messenger.DcMsg; import org.thoughtcrime.securesms.audio.AudioSlidePlayer; @@ -657,7 +658,7 @@ public class ConversationItem extends LinearLayout this.groupSender.setTextColor(context.getResources().getColor(R.color.unknown_sender)); } else if (groupThread && !messageRecord.isOutgoing() && dcContact !=null) { - this.groupSender.setText(dcContact.getDisplayName()); + this.groupSender.setText(messageRecord.getSenderName(dcContact)); this.groupSender.setTextColor(dcContact.getArgbColor()); } @@ -729,9 +730,10 @@ public class ConversationItem extends LinearLayout /// Event handlers private void handleDeadDropClick() { + ConversationListFragment.DeaddropQuestionHelper helper = new ConversationListFragment.DeaddropQuestionHelper(context, messageRecord); new AlertDialog.Builder(context) .setPositiveButton(android.R.string.ok, (dialog, which) -> { - int chatId = dcContext.createChatByMsgId(messageRecord.getId()); + int chatId = dcContext.decideOnContactRequest(messageRecord.getId(), DcContext.DC_DECISION_START_CHAT); if( chatId != 0 ) { Intent intent = new Intent(context, ConversationActivity.class); intent.putExtra(ConversationActivity.CHAT_ID_EXTRA, chatId); @@ -739,10 +741,8 @@ public class ConversationItem extends LinearLayout } }) .setNegativeButton(android.R.string.cancel, null) - .setNeutralButton(R.string.menu_block_contact, (dialog, which) -> { - dcContext.blockContact(messageRecord.getFromId(), 1); - }) - .setMessage(context.getString(R.string.ask_start_chat_with, dcContext.getContact(messageRecord.getFromId()).getDisplayName())) + .setNeutralButton(helper.answerBlock, (dialog, which) -> dcContext.decideOnContactRequest(messageRecord.getId(), DcContext.DC_DECISION_BLOCK)) + .setMessage(helper.question) .show(); } diff --git a/src/org/thoughtcrime/securesms/ConversationListAdapter.java b/src/org/thoughtcrime/securesms/ConversationListAdapter.java index 98a686335..240f345a0 100644 --- a/src/org/thoughtcrime/securesms/ConversationListAdapter.java +++ b/src/org/thoughtcrime/securesms/ConversationListAdapter.java @@ -17,14 +17,14 @@ package org.thoughtcrime.securesms; import android.content.Context; -import android.database.Cursor; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.recyclerview.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + import com.b44t.messenger.DcChat; import com.b44t.messenger.DcChatlist; import com.b44t.messenger.DcLot; @@ -182,16 +182,6 @@ class ConversationListAdapter extends RecyclerView.Adapter { this.notifyDataSetChanged(); } - int getDeaddropContactId() - { - for (int i = 0; i < dcChatlist.getCnt(); i++) { - if (dcChatlist.getChatId(i) == DcChat.DC_CHAT_ID_DEADDROP) { - return dcContext.getMsg(dcChatlist.getMsgId(i)).getFromId(); - } - } - return 0; - } - interface ItemClickListener { void onItemClick(ConversationListItem item); void onItemLongClick(ConversationListItem item); diff --git a/src/org/thoughtcrime/securesms/ConversationListFragment.java b/src/org/thoughtcrime/securesms/ConversationListFragment.java index 08a1f8b14..54f468e09 100644 --- a/src/org/thoughtcrime/securesms/ConversationListFragment.java +++ b/src/org/thoughtcrime/securesms/ConversationListFragment.java @@ -25,22 +25,6 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.b44t.messenger.DcEvent; -import com.google.android.material.snackbar.Snackbar; - -import androidx.core.content.ContextCompat; -import androidx.fragment.app.Fragment; -import androidx.loader.app.LoaderManager; -import androidx.loader.content.Loader; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.view.ActionMode; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.Menu; @@ -50,11 +34,26 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.view.ActionMode; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.Fragment; +import androidx.loader.app.LoaderManager; +import androidx.loader.content.Loader; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + import com.b44t.messenger.DcChat; import com.b44t.messenger.DcChatlist; import com.b44t.messenger.DcContact; import com.b44t.messenger.DcContext; +import com.b44t.messenger.DcEvent; import com.b44t.messenger.DcEventCenter; +import com.b44t.messenger.DcMsg; +import com.google.android.material.snackbar.Snackbar; import org.thoughtcrime.securesms.ConversationListAdapter.ItemClickListener; import org.thoughtcrime.securesms.components.recyclerview.DeleteItemAnimator; @@ -68,7 +67,6 @@ import org.thoughtcrime.securesms.util.RelayUtil; import org.thoughtcrime.securesms.util.SendRelayedMessageUtil; import org.thoughtcrime.securesms.util.Util; import org.thoughtcrime.securesms.util.ViewUtil; -import org.thoughtcrime.securesms.util.guava.Optional; import org.thoughtcrime.securesms.util.task.SnackbarAsyncTask; import org.thoughtcrime.securesms.util.views.ProgressDialog; @@ -300,7 +298,7 @@ public class ConversationListFragment extends Fragment protected void executeAction(@Nullable Void parameter) { for (long chatId : selectedConversations) { if (chatId == DcChat.DC_CHAT_ID_DEADDROP) { - dcContext.marknoticedContact(getListAdapter().getDeaddropContactId()); + dcContext.marknoticedChat(DcChat.DC_CHAT_ID_DEADDROP); } else { dcContext.setChatVisibility((int)chatId, @@ -348,7 +346,7 @@ public class ConversationListFragment extends Fragment protected Void doInBackground(Void... params) { for (long chatId : selectedConversations) { if (chatId == DcChat.DC_CHAT_ID_DEADDROP) { - dcContext.marknoticedContact(getListAdapter().getDeaddropContactId()); + dcContext.marknoticedChat(DcChat.DC_CHAT_ID_DEADDROP); } else { dcContext.notificationCenter.removeNotifications((int) chatId); @@ -432,23 +430,18 @@ public class ConversationListFragment extends Fragment if (chatId == DcChat.DC_CHAT_ID_DEADDROP) { DcContext dcContext = DcHelper.getContext(getActivity()); - int msgId = item.getMsgId(); - int contactId = item.getContactId(); - DcContact contact = dcContext.getContact(contactId); + final int msgId = item.getMsgId(); + DeaddropQuestionHelper helper = new DeaddropQuestionHelper(getContext(), dcContext.getMsg(msgId)); new AlertDialog.Builder(getActivity()) - .setMessage(getActivity().getString(R.string.ask_start_chat_with, contact.getNameNAddr())) .setPositiveButton(android.R.string.ok, (dialog, which) -> { - int belongingChatId = dcContext.createChatByMsgId(msgId); + int belongingChatId = dcContext.decideOnContactRequest(msgId, DcContext.DC_DECISION_START_CHAT); if (belongingChatId != 0) { handleCreateConversation(belongingChatId); } }) - .setNegativeButton(R.string.not_now, (dialog, which) -> { - dcContext.marknoticedContact(contactId); - }) - .setNeutralButton(R.string.menu_block_contact, (dialog, which) -> { - dcContext.blockContact(contactId, 1); - }) + .setNegativeButton(R.string.not_now, (dialog, which) -> dcContext.decideOnContactRequest(msgId, DcContext.DC_DECISION_NOT_NOW)) + .setNeutralButton(helper.answerBlock, (dialog, which) -> dcContext.decideOnContactRequest(msgId, DcContext.DC_DECISION_BLOCK)) + .setMessage(helper.question) .show(); return; } @@ -484,6 +477,25 @@ public class ConversationListFragment extends Fragment } } + static class DeaddropQuestionHelper { + public String question; + public String answerBlock; + + DeaddropQuestionHelper(Context context, DcMsg dcMsg) { + DcContext dcContext = DcHelper.getContext(context); + DcChat dcChat = dcContext.getChat(dcMsg.getRealChatId()); + + if (dcChat.isMailingList()) { + question = context.getString(R.string.ask_show_mailing_list, dcChat.getName()); + answerBlock = context.getString(R.string.block); + } else { + DcContact dcContact = dcContext.getContact(dcMsg.getFromId()); + question = context.getString(R.string.ask_start_chat_with, dcMsg.getSenderName(dcContact)); + answerBlock = context.getString(R.string.menu_block_contact); + } + } + }; + @Override public void onSwitchToArchive() { ((ConversationSelectedListener)getActivity()).onSwitchToArchive(); diff --git a/src/org/thoughtcrime/securesms/ConversationListItem.java b/src/org/thoughtcrime/securesms/ConversationListItem.java index f224a877e..daf3d110d 100644 --- a/src/org/thoughtcrime/securesms/ConversationListItem.java +++ b/src/org/thoughtcrime/securesms/ConversationListItem.java @@ -38,7 +38,6 @@ import com.amulyakhare.textdrawable.TextDrawable; import com.annimon.stream.Stream; import com.b44t.messenger.DcChat; import com.b44t.messenger.DcContact; -import com.b44t.messenger.DcContext; import com.b44t.messenger.DcLot; import com.b44t.messenger.DcMsg; @@ -250,11 +249,6 @@ public class ConversationListItem extends RelativeLayout return msgId; } - public int getContactId() { - DcContext dcContext = DcHelper.getContext(getContext()); - return dcContext.getMsg(msgId).getFromId(); - } - private void setStatusIcons(int visibility, int state, int unreadCount) { if (visibility==DcChat.DC_CHAT_VISIBILITY_ARCHIVED) { diff --git a/src/org/thoughtcrime/securesms/ConversationTitleView.java b/src/org/thoughtcrime/securesms/ConversationTitleView.java index 1aed7be7b..90949278e 100644 --- a/src/org/thoughtcrime/securesms/ConversationTitleView.java +++ b/src/org/thoughtcrime/securesms/ConversationTitleView.java @@ -1,14 +1,15 @@ package org.thoughtcrime.securesms; import android.content.Context; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import android.util.AttributeSet; import android.view.View; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.b44t.messenger.DcChat; import com.b44t.messenger.DcContact; import com.b44t.messenger.DcContext; @@ -73,7 +74,9 @@ public class ConversationTitleView extends RelativeLayout { String subtitleStr = "ErrSubtitle"; int[] chatContacts = dcContext.getChatContacts(chatId); - if( dcChat.isGroup() ) { + if (dcChat.isMailingList()) { + subtitleStr = context.getString(R.string.mailing_list); + } else if( dcChat.isGroup() ) { subtitleStr = context.getResources().getQuantityString(R.plurals.n_members, chatContacts.length, chatContacts.length); } else if( chatContacts.length>=1 ) { if( dcChat.isSelfTalk() ) { diff --git a/src/org/thoughtcrime/securesms/ProfileActivity.java b/src/org/thoughtcrime/securesms/ProfileActivity.java index f72a73420..a876ab5e0 100644 --- a/src/org/thoughtcrime/securesms/ProfileActivity.java +++ b/src/org/thoughtcrime/securesms/ProfileActivity.java @@ -67,6 +67,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity private int chatId; private boolean chatIsGroup; private boolean chatIsDeviceTalk; + private boolean chatIsMailingList; private int contactId; private boolean fromChat; @@ -200,6 +201,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity contactId = getIntent().getIntExtra(CONTACT_ID_EXTRA, 0); chatIsGroup = false; chatIsDeviceTalk = false; + chatIsMailingList= false; fromChat = getIntent().getBooleanExtra(FROM_CHAT, false); if (contactId!=0) { @@ -209,13 +211,14 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity DcChat dcChat = dcContext.getChat(chatId); chatIsGroup = dcChat.isGroup(); chatIsDeviceTalk = dcChat.isDeviceTalk(); + chatIsMailingList = dcChat.isMailingList(); if(!chatIsGroup) { final int[] members = dcContext.getChatContacts(chatId); contactId = members.length>=1? members[0] : 0; } } - if(!isGlobalProfile() && !isSelfProfile() && !chatIsDeviceTalk) { + if(!isGlobalProfile() && !isSelfProfile() && !chatIsDeviceTalk && !chatIsMailingList) { tabs.add(TAB_SETTINGS); } tabs.add(TAB_GALLERY); @@ -306,7 +309,9 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity if(isContactProfile()) { return getString(contactId==DcContact.DC_CONTACT_ID_SELF? R.string.self : R.string.tab_contact); } - else { + else if (chatIsMailingList) { + return getString(R.string.mailing_list); + } else { return getString(R.string.tab_group); } diff --git a/src/org/thoughtcrime/securesms/ProfileSettingsAdapter.java b/src/org/thoughtcrime/securesms/ProfileSettingsAdapter.java index 4cd78fe4f..7354b25ce 100644 --- a/src/org/thoughtcrime/securesms/ProfileSettingsAdapter.java +++ b/src/org/thoughtcrime/securesms/ProfileSettingsAdapter.java @@ -1,14 +1,15 @@ package org.thoughtcrime.securesms; import android.content.Context; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.recyclerview.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + import com.b44t.messenger.DcChat; import com.b44t.messenger.DcChatlist; import com.b44t.messenger.DcContact; @@ -50,6 +51,7 @@ public class ProfileSettingsAdapter extends RecyclerView.Adapter private int itemDataMemberCount; private DcChatlist itemDataSharedChats; private DcContact itemDataContact; + private boolean isMailingList; private final Set selectedMembers; private final LayoutInflater layoutInflater; @@ -214,7 +216,11 @@ public class ProfileSettingsAdapter extends RecyclerView.Adapter String txt = ""; switch(getItemViewType(position)) { case ItemData.TYPE_MEMBER: - txt = context.getResources().getQuantityString(R.plurals.n_members, (int) itemDataMemberCount, (int) itemDataMemberCount); + if (isMailingList) { + txt = context.getString(R.string.contacts_headline); + } else { + txt = context.getResources().getQuantityString(R.plurals.n_members, (int) itemDataMemberCount, (int) itemDataMemberCount); + } break; case ItemData.TYPE_SHARED_CHAT: txt = context.getString(R.string.profile_shared_chats); @@ -260,13 +266,18 @@ public class ProfileSettingsAdapter extends RecyclerView.Adapter itemDataMemberCount = 0; itemDataSharedChats = null; itemDataContact = null; + isMailingList = false; if (memberList!=null) { itemDataMemberCount = memberList.length; - itemData.add(new ItemData(ItemData.TYPE_MEMBER, DcContact.DC_CONTACT_ID_ADD_MEMBER, 0)); - itemData.add(new ItemData(ItemData.TYPE_MEMBER, DcContact.DC_CONTACT_ID_QR_INVITE, 0)); - for (int i = 0; i < memberList.length; i++) { - itemData.add(new ItemData(ItemData.TYPE_MEMBER, memberList[i], 0)); + if (dcChat.isMailingList()) { + isMailingList = true; + } else { + itemData.add(new ItemData(ItemData.TYPE_MEMBER, DcContact.DC_CONTACT_ID_ADD_MEMBER, 0)); + itemData.add(new ItemData(ItemData.TYPE_MEMBER, DcContact.DC_CONTACT_ID_QR_INVITE, 0)); + } + for (int value : memberList) { + itemData.add(new ItemData(ItemData.TYPE_MEMBER, value, 0)); } // itemData.add(new ItemData(ItemData.TYPE_SECONDARY_SETTING, SETTING_GROUP_NAME_N_IMAGE, context.getString(R.string.menu_group_name_and_image))); } diff --git a/src/org/thoughtcrime/securesms/ProfileSettingsFragment.java b/src/org/thoughtcrime/securesms/ProfileSettingsFragment.java index 849a0cde5..7fe8cc87d 100644 --- a/src/org/thoughtcrime/securesms/ProfileSettingsFragment.java +++ b/src/org/thoughtcrime/securesms/ProfileSettingsFragment.java @@ -5,13 +5,6 @@ import android.content.Intent; import android.content.res.Configuration; import android.os.Build; import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.view.ActionMode; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; @@ -20,6 +13,14 @@ import android.view.ViewGroup; import android.view.Window; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.view.ActionMode; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + import com.b44t.messenger.DcChat; import com.b44t.messenger.DcChatlist; import com.b44t.messenger.DcContact; @@ -262,6 +263,8 @@ public class ProfileSettingsFragment extends Fragment @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { mode.getMenuInflater().inflate(R.menu.profile_context, menu); + DcChat dcChat = dcContext.getChat(chatId); + menu.findItem(R.id.delete).setVisible(!dcChat.isMailingList()); mode.setTitle("1"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { diff --git a/src/org/thoughtcrime/securesms/connect/ApplicationDcContext.java b/src/org/thoughtcrime/securesms/connect/ApplicationDcContext.java index 4edc2b90f..57fe21e05 100644 --- a/src/org/thoughtcrime/securesms/connect/ApplicationDcContext.java +++ b/src/org/thoughtcrime/securesms/connect/ApplicationDcContext.java @@ -3,13 +3,11 @@ package org.thoughtcrime.securesms.connect; import android.app.Activity; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; import android.os.Build; import android.os.Environment; -import android.preference.PreferenceManager; import android.provider.Settings; import android.util.Log; import android.webkit.MimeTypeMap; @@ -39,7 +37,6 @@ import org.thoughtcrime.securesms.util.Util; import java.io.File; import java.util.Date; import java.util.HashMap; -import java.util.Set; import org.thoughtcrime.securesms.ZhvActivity; diff --git a/src/org/thoughtcrime/securesms/contacts/ContactSelectionListAdapter.java b/src/org/thoughtcrime/securesms/contacts/ContactSelectionListAdapter.java index 1887ab27b..4f3311cfc 100644 --- a/src/org/thoughtcrime/securesms/contacts/ContactSelectionListAdapter.java +++ b/src/org/thoughtcrime/securesms/contacts/ContactSelectionListAdapter.java @@ -17,10 +17,6 @@ package org.thoughtcrime.securesms.contacts; import android.content.Context; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.recyclerview.widget.RecyclerView; import android.text.TextUtils; import android.util.SparseIntArray; import android.view.LayoutInflater; @@ -28,6 +24,10 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + import com.b44t.messenger.DcContact; import org.thoughtcrime.securesms.R; @@ -173,6 +173,7 @@ public class ContactSelectionListAdapter extends RecyclerView.Adapter return; } int adapterPosition = getAdapterPosition(); + if (adapterPosition < 0) return; int contactId = getContactId(adapterPosition); boolean enabled = actionModeSelection.indexOfKey(adapterPosition) > -1; if (enabled) { diff --git a/src/org/thoughtcrime/securesms/notifications/NotificationCenter.java b/src/org/thoughtcrime/securesms/notifications/NotificationCenter.java index 21359548e..63554ec08 100644 --- a/src/org/thoughtcrime/securesms/notifications/NotificationCenter.java +++ b/src/org/thoughtcrime/securesms/notifications/NotificationCenter.java @@ -331,7 +331,7 @@ public class NotificationCenter { DcMsg dcMsg = dcContext.getMsg(msgId); String line = privacy.isDisplayMessage()? dcMsg.getSummarytext(2000) : context.getString(R.string.notify_new_message); if (dcChat.isGroup() && privacy.isDisplayContact()) { - line = dcContext.getContact(dcMsg.getFromId()).getDisplayName() + ": " + line; + line = dcMsg.getSenderName(dcContext.getContact(dcMsg.getFromId())) + ": " + line; } // play signal? @@ -368,7 +368,7 @@ public class NotificationCenter { // prepend the sender in the ticker also for one-to-one chats (for group-chats, this is already done) String tickerLine = line; if (!dcChat.isGroup() && privacy.isDisplayContact()) { - line = dcContext.getContact(dcMsg.getFromId()).getDisplayName() + ": " + line; + line = dcMsg.getSenderName(dcContext.getContact(dcMsg.getFromId())) + ": " + line; } builder.setTicker(tickerLine);