diff --git a/src/main/java/com/b44t/messenger/DcMsg.java b/src/main/java/com/b44t/messenger/DcMsg.java index c141d8e2e..4195d90a6 100644 --- a/src/main/java/com/b44t/messenger/DcMsg.java +++ b/src/main/java/com/b44t/messenger/DcMsg.java @@ -18,6 +18,7 @@ public class DcMsg { public final static int DC_MSG_VOICE = 41; public final static int DC_MSG_VIDEO = 50; public final static int DC_MSG_FILE = 60; + public final static int DC_MSG_CALL = 71; public final static int DC_MSG_WEBXDC = 80; public final static int DC_MSG_VCARD = 90; diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java b/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java index 10fdabb75..c67484595 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java @@ -366,7 +366,7 @@ public class ConversationFragment extends MessageSelectorFragment } static boolean canEditMsg(DcMsg dcMsg) { - return dcMsg.isOutgoing() && !dcMsg.isInfo() && !dcMsg.hasHtml() && !dcMsg.getText().isEmpty(); + return dcMsg.isOutgoing() && !dcMsg.isInfo() && dcMsg.getType() != DcMsg.DC_MSG_CALL && !dcMsg.hasHtml() && !dcMsg.getText().isEmpty(); } public void handleClearChat() { diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationItem.java b/src/main/java/org/thoughtcrime/securesms/ConversationItem.java index ca91a36f4..fa60d4f1b 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationItem.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationItem.java @@ -48,6 +48,7 @@ import org.thoughtcrime.securesms.audio.AudioSlidePlayer; import org.thoughtcrime.securesms.components.AudioView; import org.thoughtcrime.securesms.components.AvatarImageView; import org.thoughtcrime.securesms.components.BorderlessImageView; +import org.thoughtcrime.securesms.components.CallItemView; import org.thoughtcrime.securesms.components.ConversationItemFooter; import org.thoughtcrime.securesms.components.ConversationItemThumbnail; import org.thoughtcrime.securesms.components.DocumentView; @@ -117,6 +118,7 @@ public class ConversationItem extends BaseConversationItem private @NonNull Stub webxdcViewStub; private Stub stickerStub; private Stub vcardViewStub; + private Stub callViewStub; private @Nullable EventListener eventListener; private int measureCalls; @@ -151,6 +153,7 @@ public class ConversationItem extends BaseConversationItem this.webxdcViewStub = new Stub<>(findViewById(R.id.webxdc_view_stub)); this.stickerStub = new Stub<>(findViewById(R.id.sticker_view_stub)); this.vcardViewStub = new Stub<>(findViewById(R.id.vcard_view_stub)); + this.callViewStub = new Stub<>(findViewById(R.id.call_view_stub)); this.groupSenderHolder = findViewById(R.id.group_sender_holder); this.quoteView = findViewById(R.id.quote_view); this.container = findViewById(R.id.container); @@ -321,6 +324,11 @@ public class ConversationItem extends BaseConversationItem vcardViewStub.get().setFocusable(!shouldInterceptClicks(messageRecord) && batchSelected.isEmpty()); vcardViewStub.get().setClickable(batchSelected.isEmpty()); } + + if (callViewStub.resolved()) { + callViewStub.get().setFocusable(!shouldInterceptClicks(messageRecord) && batchSelected.isEmpty()); + callViewStub.get().setClickable(batchSelected.isEmpty()); + } } private void setContentDescription() { @@ -337,6 +345,8 @@ public class ConversationItem extends BaseConversationItem desc += webxdcViewStub.get().getDescription() + "\n"; } else if (vcardViewStub.resolved() && vcardViewStub.get().getVisibility() == View.VISIBLE) { desc += vcardViewStub.get().getDescription() + "\n"; + } else if (callViewStub.resolved() && callViewStub.get().getVisibility() == View.VISIBLE) { + desc += callViewStub.get().getDescription() + "\n"; } else if (mediaThumbnailStub.resolved() && mediaThumbnailStub.get().getVisibility() == View.VISIBLE) { desc += mediaThumbnailStub.get().getDescription() + "\n"; } else if (stickerStub.resolved() && stickerStub.get().getVisibility() == View.VISIBLE) { @@ -398,7 +408,7 @@ public class ConversationItem extends BaseConversationItem String text = messageRecord.getText(); - if (text.isEmpty()) { + if (messageRecord.getType()==DcMsg.DC_MSG_CALL || text.isEmpty()) { bodyText.setVisibility(View.GONE); } else { @@ -489,6 +499,7 @@ public class ConversationItem extends BaseConversationItem if (webxdcViewStub.resolved()) webxdcViewStub.get().setVisibility(View.GONE); if (stickerStub.resolved()) stickerStub.get().setVisibility(View.GONE); if (vcardViewStub.resolved()) vcardViewStub.get().setVisibility(View.GONE); + if (callViewStub.resolved()) callViewStub.get().setVisibility(View.GONE); //noinspection ConstantConditions int duration = messageRecord.getDuration(); @@ -514,6 +525,7 @@ public class ConversationItem extends BaseConversationItem if (webxdcViewStub.resolved()) webxdcViewStub.get().setVisibility(View.GONE); if (stickerStub.resolved()) stickerStub.get().setVisibility(View.GONE); if (vcardViewStub.resolved()) vcardViewStub.get().setVisibility(View.GONE); + if (callViewStub.resolved()) callViewStub.get().setVisibility(View.GONE); //noinspection ConstantConditions documentViewStub.get().setDocument(new DocumentSlide(context, messageRecord)); @@ -532,6 +544,7 @@ public class ConversationItem extends BaseConversationItem if (documentViewStub.resolved()) documentViewStub.get().setVisibility(View.GONE); if (stickerStub.resolved()) stickerStub.get().setVisibility(View.GONE); if (vcardViewStub.resolved()) vcardViewStub.get().setVisibility(View.GONE); + if (callViewStub.resolved()) callViewStub.get().setVisibility(View.GONE); webxdcViewStub.get().setWebxdc(messageRecord, context.getString(R.string.webxdc_app)); webxdcViewStub.get().setWebxdcClickListener(new ThumbnailClickListener()); @@ -549,6 +562,7 @@ public class ConversationItem extends BaseConversationItem if (documentViewStub.resolved()) documentViewStub.get().setVisibility(View.GONE); if (webxdcViewStub.resolved()) webxdcViewStub.get().setVisibility(View.GONE); if (stickerStub.resolved()) stickerStub.get().setVisibility(View.GONE); + if (callViewStub.resolved()) callViewStub.get().setVisibility(View.GONE); vcardViewStub.get().setVcard(glideRequests, new VcardSlide(context, messageRecord), rpc); vcardViewStub.get().setVcardClickListener(new ThumbnailClickListener()); @@ -560,6 +574,23 @@ public class ConversationItem extends BaseConversationItem ViewUtil.updateLayoutParams(groupSenderHolder, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); footer.setVisibility(VISIBLE); } + else if (messageRecord.getType()==DcMsg.DC_MSG_CALL) { + callViewStub.get().setVisibility(View.VISIBLE); + if (mediaThumbnailStub.resolved()) mediaThumbnailStub.get().setVisibility(View.GONE); + if (audioViewStub.resolved()) audioViewStub.get().setVisibility(View.GONE); + if (documentViewStub.resolved()) documentViewStub.get().setVisibility(View.GONE); + if (webxdcViewStub.resolved()) webxdcViewStub.get().setVisibility(View.GONE); + if (stickerStub.resolved()) stickerStub.get().setVisibility(View.GONE); + if (vcardViewStub.resolved()) vcardViewStub.get().setVisibility(View.GONE); + + callViewStub.get().setCallItem(messageRecord); + callViewStub.get().setOnClickListener(passthroughClickListener); + callViewStub.get().setOnLongClickListener(passthroughClickListener); + + callViewStub.get().setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS); + + ViewUtil.updateLayoutParams(groupSenderHolder, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + } else if (hasThumbnail(messageRecord)) { mediaThumbnailStub.get().setVisibility(View.VISIBLE); if (audioViewStub.resolved()) audioViewStub.get().setVisibility(View.GONE); @@ -567,6 +598,7 @@ public class ConversationItem extends BaseConversationItem if (webxdcViewStub.resolved()) webxdcViewStub.get().setVisibility(View.GONE); if (stickerStub.resolved()) stickerStub.get().setVisibility(View.GONE); if (vcardViewStub.resolved()) vcardViewStub.get().setVisibility(View.GONE); + if (callViewStub.resolved()) callViewStub.get().setVisibility(View.GONE); Slide slide = MediaUtil.getSlideForMsg(context, messageRecord); @@ -606,6 +638,7 @@ public class ConversationItem extends BaseConversationItem if (webxdcViewStub.resolved()) webxdcViewStub.get().setVisibility(View.GONE); if (mediaThumbnailStub.resolved()) mediaThumbnailStub.get().setVisibility(View.GONE); if (vcardViewStub.resolved()) vcardViewStub.get().setVisibility(View.GONE); + if (callViewStub.resolved()) callViewStub.get().setVisibility(View.GONE); bodyBubble.setBackgroundColor(Color.TRANSPARENT); @@ -626,6 +659,7 @@ public class ConversationItem extends BaseConversationItem if (documentViewStub.resolved()) documentViewStub.get().setVisibility(View.GONE); if (webxdcViewStub.resolved()) webxdcViewStub.get().setVisibility(View.GONE); if (vcardViewStub.resolved()) vcardViewStub.get().setVisibility(View.GONE); + if (callViewStub.resolved()) callViewStub.get().setVisibility(View.GONE); ViewUtil.updateLayoutParams(bodyText, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); ViewUtil.updateLayoutParams(groupSenderHolder, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); @@ -779,6 +813,8 @@ public class ConversationItem extends BaseConversationItem return stickerStub.get().getFooter(); } else if (hasOnlyThumbnail(messageRecord) && TextUtils.isEmpty(messageRecord.getText())) { return mediaThumbnailStub.get().getFooter(); + } else if (messageRecord.getType()==DcMsg.DC_MSG_CALL) { + return callViewStub.get().getFooter(); } else { return footer; } @@ -880,6 +916,7 @@ public class ConversationItem extends BaseConversationItem else if (documentViewStub.resolved()) documentViewStub.get().performClick(); else if (webxdcViewStub.resolved()) webxdcViewStub.get().performClick(); else if (vcardViewStub.resolved()) vcardViewStub.get().performClick(); + else if (callViewStub.resolved()) callViewStub.get().performClick(); } /// Event handlers diff --git a/src/main/java/org/thoughtcrime/securesms/components/CallItemView.java b/src/main/java/org/thoughtcrime/securesms/components/CallItemView.java new file mode 100644 index 000000000..aa4584648 --- /dev/null +++ b/src/main/java/org/thoughtcrime/securesms/components/CallItemView.java @@ -0,0 +1,72 @@ +package org.thoughtcrime.securesms.components; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Color; +import android.util.AttributeSet; +import android.util.Log; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.b44t.messenger.DcMsg; + +import org.thoughtcrime.securesms.R; + +public class CallItemView extends FrameLayout { + private static final String TAG = CallItemView.class.getSimpleName(); + + private final @NonNull ImageView icon; + private final @NonNull TextView title; + private final @NonNull ConversationItemFooter footer; + + public CallItemView(Context context) { + this(context, null); + } + + public CallItemView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public CallItemView(final Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + inflate(context, R.layout.call_item_view, this); + + this.icon = findViewById(R.id.call_icon); + this.title = findViewById(R.id.title); + this.footer = findViewById(R.id.footer); + } + + public void setCallItem(final @NonNull DcMsg dcMsg) { + title.setText(dcMsg.getText()); + if (dcMsg.isOutgoing()) { + int[] attrs = new int[]{ + R.attr.conversation_item_outgoing_text_secondary_color, + }; + try (TypedArray ta = getContext().obtainStyledAttributes(attrs)) { + footer.setTextColor(ta.getColor(0, Color.BLACK)); + icon.setColorFilter(ta.getColor(0, Color.BLACK)); + } + } else { + int[] attrs = new int[]{ + R.attr.conversation_item_incoming_text_secondary_color, + }; + try (TypedArray ta = getContext().obtainStyledAttributes(attrs)) { + footer.setTextColor(ta.getColor(0, Color.BLACK)); + } + icon.setColorFilter(getResources().getColor(R.color.delta_accent_darker)); + } + } + + public ConversationItemFooter getFooter() { + return footer; + } + + public String getDescription() { + return title.getText() + "\n" + footer.getDescription(); + } +} diff --git a/src/main/java/org/thoughtcrime/securesms/components/ConversationItemFooter.java b/src/main/java/org/thoughtcrime/securesms/components/ConversationItemFooter.java index 8caa030f8..f74c0ce6b 100644 --- a/src/main/java/org/thoughtcrime/securesms/components/ConversationItemFooter.java +++ b/src/main/java/org/thoughtcrime/securesms/components/ConversationItemFooter.java @@ -54,8 +54,7 @@ public class ConversationItemFooter extends LinearLayout { if (attrs != null) { try (TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.ConversationItemFooter, 0, 0)) { - textColor = typedArray.getInt(R.styleable.ConversationItemFooter_footer_text_color, getResources().getColor(R.color.core_white)); - setTextColor(textColor); + setTextColor(typedArray.getInt(R.styleable.ConversationItemFooter_footer_text_color, getResources().getColor(R.color.core_white))); } } } @@ -77,7 +76,8 @@ public class ConversationItemFooter extends LinearLayout { presentDeliveryStatus(messageRecord); } - private void setTextColor(int color) { + public void setTextColor(int color) { + textColor = color; dateView.setTextColor(color); editedView.setTextColor(color); bookmarkIndicatorView.setColorFilter(color); diff --git a/src/main/res/layout/call_item_view.xml b/src/main/res/layout/call_item_view.xml new file mode 100644 index 000000000..66064b7e4 --- /dev/null +++ b/src/main/res/layout/call_item_view.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + diff --git a/src/main/res/layout/conversation_item_call.xml b/src/main/res/layout/conversation_item_call.xml new file mode 100644 index 000000000..15a28934f --- /dev/null +++ b/src/main/res/layout/conversation_item_call.xml @@ -0,0 +1,9 @@ + + diff --git a/src/main/res/layout/conversation_item_received.xml b/src/main/res/layout/conversation_item_received.xml index 19cb8a2bc..b4633d688 100644 --- a/src/main/res/layout/conversation_item_received.xml +++ b/src/main/res/layout/conversation_item_received.xml @@ -172,6 +172,16 @@ android:layout_marginLeft="@dimen/message_bubble_horizontal_padding" android:layout_marginRight="@dimen/message_bubble_horizontal_padding" /> + + + +