diff --git a/jni/dc_wrapper.c b/jni/dc_wrapper.c index 9d25ef6873..3c8a40bb7d 100644 --- a/jni/dc_wrapper.c +++ b/jni/dc_wrapper.c @@ -1918,6 +1918,21 @@ JNIEXPORT jboolean Java_com_b44t_messenger_DcContact_isVerified(JNIEnv *env, job } +JNIEXPORT jstring Java_com_b44t_messenger_DcContact_getVerifierAddr(JNIEnv *env, jobject obj) +{ + char* temp = dc_contact_get_verifier_addr(get_dc_contact(env, obj)); + jstring ret = JSTRING_NEW(temp); + dc_str_unref(temp); + return ret; +} + + +JNIEXPORT jint Java_com_b44t_messenger_DcContact_getVerifierId(JNIEnv *env, jobject obj) +{ + return dc_contact_get_verifier_id(get_dc_contact(env, obj)); +} + + /******************************************************************************* * DcLot ******************************************************************************/ diff --git a/res/layout/profile_settings_item.xml b/res/layout/profile_settings_item.xml index 37b3c06b40..1a57eec3ad 100644 --- a/res/layout/profile_settings_item.xml +++ b/res/layout/profile_settings_item.xml @@ -10,6 +10,7 @@ diff --git a/src/com/b44t/messenger/DcContact.java b/src/com/b44t/messenger/DcContact.java index 3fc164b3fd..2460468ca4 100644 --- a/src/com/b44t/messenger/DcContact.java +++ b/src/com/b44t/messenger/DcContact.java @@ -58,6 +58,8 @@ public String toString() { public native boolean wasSeenRecently(); public native boolean isBlocked (); public native boolean isVerified (); + public native String getVerifierAddr(); + public native int getVerifierId (); // working with raw c-data private long contactCPtr; // CAVE: the name is referenced in the JNI diff --git a/src/org/thoughtcrime/securesms/ProfileSettingsAdapter.java b/src/org/thoughtcrime/securesms/ProfileSettingsAdapter.java index 68766932aa..669f087da7 100644 --- a/src/org/thoughtcrime/securesms/ProfileSettingsAdapter.java +++ b/src/org/thoughtcrime/securesms/ProfileSettingsAdapter.java @@ -32,6 +32,8 @@ public class ProfileSettingsAdapter extends RecyclerView.Adapter implements StickyHeaderAdapter { + public static final int SETTING_VERIFIED = 118; + public static final int SETTING_LAST_SEEN = 119; public static final int SETTING_SEND_MESSAGE = 120; private final @NonNull Context context; @@ -61,21 +63,25 @@ static class ItemData { int chatlistIndex; int settingsId; String label; + int labelColor; + int iconLeft; - ItemData(int type, int settingsId, String label) { - this(type, 0, 0, settingsId, label); + ItemData(int type, int settingsId, String label, int labelColor, int iconLeft) { + this(type, 0, 0, settingsId, label, labelColor, iconLeft); } ItemData(int type, int contactId, int chatlistIndex) { - this(type, contactId, chatlistIndex, 0, null); + this(type, contactId, chatlistIndex, 0, null, 0, 0); } - ItemData(int type, int contactId, int chatlistIndex, int settingsId, @Nullable String label) { + ItemData(int type, int contactId, int chatlistIndex, int settingsId, @Nullable String label, int labelColor, int iconLeft) { this.type = type; this.contactId = contactId; this.chatlistIndex = chatlistIndex; this.settingsId = settingsId; this.label = label; + this.labelColor = labelColor; + this.iconLeft = iconLeft; } }; @@ -191,7 +197,7 @@ else if(holder.itemView instanceof ProfileSettingsItem) { int settingsId = itemData.get(i).settingsId; ProfileSettingsItem profileSettingsItem = (ProfileSettingsItem) holder.itemView; profileSettingsItem.setOnClickListener(view -> clickListener.onSettingsClicked(settingsId)); - profileSettingsItem.set(itemData.get(i).label); + profileSettingsItem.set(itemData.get(i).label, itemData.get(i).labelColor, itemData.get(i).iconLeft); } } @@ -235,13 +241,7 @@ public void onBindHeaderViewHolder(HeaderViewHolder viewHolder, int position) { txt = context.getString(R.string.profile_shared_chats); break; case ItemData.TYPE_PRIMARY_SETTING: - long lastSeen = (itemDataContact!=null? itemDataContact.getLastSeen() : 0); - if (lastSeen == 0) { - txt = context.getString(R.string.last_seen_unknown); - } - else { - txt = context.getString(R.string.last_seen_at, DateUtils.getExtendedTimeSpanString(context, locale, lastSeen)); - } + txt = context.getString(R.string.info); break; case ItemData.TYPE_STATUS: txt = context.getString(R.string.pref_default_status_label); @@ -312,12 +312,31 @@ else if (sharedChats!=null && dcContact!=null) { itemDataContact = dcContact; if (!chatIsDeviceTalk) { - itemData.add(new ItemData(ItemData.TYPE_PRIMARY_SETTING, SETTING_SEND_MESSAGE, context.getString(R.string.send_message))); + if (dcContact.isVerified()) { + String verifiedInfo = context.getString(R.string.verified); + if (!dcContact.getVerifierAddr().isEmpty()) { + verifiedInfo = context.getString(R.string.verified_by, dcContact.getVerifierAddr()); + } + itemData.add(new ItemData(ItemData.TYPE_PRIMARY_SETTING, SETTING_VERIFIED, verifiedInfo, 0, R.drawable.ic_verified)); + } + + long lastSeenTimestamp = (itemDataContact!=null? itemDataContact.getLastSeen() : 0); + String lastSeenTxt; + if (lastSeenTimestamp == 0) { + lastSeenTxt = context.getString(R.string.last_seen_unknown); + } + else { + lastSeenTxt = context.getString(R.string.last_seen_at, DateUtils.getExtendedTimeSpanString(context, locale, lastSeenTimestamp)); + } + itemData.add(new ItemData(ItemData.TYPE_PRIMARY_SETTING, SETTING_LAST_SEEN, lastSeenTxt, 0, 0)); + + + itemData.add(new ItemData(ItemData.TYPE_PRIMARY_SETTING, SETTING_SEND_MESSAGE, context.getString(R.string.send_message), R.color.delta_accent, 0)); } itemDataStatusText = dcContact.getStatus(); if (!itemDataStatusText.isEmpty()) { - itemData.add(new ItemData(ItemData.TYPE_STATUS, 0, itemDataStatusText)); + itemData.add(new ItemData(ItemData.TYPE_STATUS, 0, itemDataStatusText, 0, 0)); } itemDataSharedChats = sharedChats; diff --git a/src/org/thoughtcrime/securesms/ProfileSettingsFragment.java b/src/org/thoughtcrime/securesms/ProfileSettingsFragment.java index 2030e4a153..43eac0415c 100644 --- a/src/org/thoughtcrime/securesms/ProfileSettingsFragment.java +++ b/src/org/thoughtcrime/securesms/ProfileSettingsFragment.java @@ -146,6 +146,9 @@ public void onSettingsClicked(int settingsId) { case ProfileSettingsAdapter.SETTING_SEND_MESSAGE: onSendMessage(); break; + case ProfileSettingsAdapter.SETTING_VERIFIED: + onVerifiedByClicked(); + break; } } @@ -233,6 +236,18 @@ public void onSharedChatClicked(int chatId) { getActivity().finish(); } + private void onVerifiedByClicked() { + DcContact dcContact = dcContext.getContact(contactId); + if (dcContact.isVerified()) { + int verifierId = dcContact.getVerifierId(); + if (verifierId != 0 && verifierId != contactId) { + Intent intent = new Intent(getContext(), ProfileActivity.class); + intent.putExtra(ProfileActivity.CONTACT_ID_EXTRA, verifierId); + startActivity(intent); + } + } + } + private void onSendMessage() { DcContact dcContact = dcContext.getContact(contactId); int chatId = dcContext.createChatByContactId(dcContact.getId()); diff --git a/src/org/thoughtcrime/securesms/ProfileSettingsItem.java b/src/org/thoughtcrime/securesms/ProfileSettingsItem.java index c14a029a0d..8b113c29de 100644 --- a/src/org/thoughtcrime/securesms/ProfileSettingsItem.java +++ b/src/org/thoughtcrime/securesms/ProfileSettingsItem.java @@ -5,6 +5,10 @@ import android.widget.LinearLayout; import android.widget.TextView; +import androidx.core.content.ContextCompat; + +import org.thoughtcrime.securesms.util.ResUtil; + public class ProfileSettingsItem extends LinearLayout { private TextView labelView; @@ -23,7 +27,15 @@ protected void onFinishInflate() { labelView = findViewById(R.id.label); } - public void set(String label) { + public void set(String label, int labelColor, int iconLeft) { labelView.setText(label==null? "" : label); + labelView.setCompoundDrawablesWithIntrinsicBounds(iconLeft, 0,0,0); + + // we need different color getters as `labelColor` is `R.color.name` while default is `R.attr.name` + if (labelColor != 0) { + labelView.setTextColor(ContextCompat.getColor(getContext(), labelColor)); + } else { + labelView.setTextColor(ResUtil.getColor(getContext(), R.attr.emoji_text_color)); + } } }