Compare commits

...

3 commits

Author SHA1 Message Date
adb
5b62f7bf25
Merge pull request #3920 from deltachat/adb/issue-3916
improve displaying of call messages
2025-09-19 20:17:54 +02:00
adbenitez
df6c858b92 improve displaying of calls messages 2025-09-19 18:44:06 +02:00
adbenitez
c9816ae785 don't allow to edit call messages 2025-09-19 14:29:46 +02:00
9 changed files with 194 additions and 5 deletions

View file

@ -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;

View file

@ -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() {

View file

@ -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<WebxdcView> webxdcViewStub;
private Stub<BorderlessImageView> stickerStub;
private Stub<VcardView> vcardViewStub;
private Stub<CallItemView> 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

View file

@ -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();
}
}

View file

@ -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);

View file

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minWidth="210dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:focusable="true">
<LinearLayout android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="16dp"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:singleLine="true"
android:fontFamily="sans-serif"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="?conversation_item_outgoing_text_primary_color"
tools:text="Incoming call" />
<org.thoughtcrime.securesms.components.ConversationItemFooter
android:id="@+id/footer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:gravity="start"
android:clipChildren="false"
android:clipToPadding="false"
/>
</LinearLayout>
<ImageView
android:id="@+id/call_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:contentDescription="@null"
android:src="@drawable/baseline_call_24"
/>
</LinearLayout>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<org.thoughtcrime.securesms.components.CallItemView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/call_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
tools:visibility="visible"/>

View file

@ -172,6 +172,16 @@
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
android:layout_marginRight="@dimen/message_bubble_horizontal_padding" />
<ViewStub
android:id="@+id/call_view_stub"
android:layout="@layout/conversation_item_call"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/message_bubble_top_padding"
android:layout_marginBottom="@dimen/message_bubble_collapsed_footer_padding"
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
android:layout_marginRight="@dimen/message_bubble_horizontal_padding" />
<org.thoughtcrime.securesms.components.emoji.AutoScaledEmojiTextView
android:id="@+id/conversation_item_body"
android:layout_width="wrap_content"

View file

@ -154,6 +154,16 @@
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
android:layout_marginRight="@dimen/message_bubble_horizontal_padding" />
<ViewStub
android:id="@+id/call_view_stub"
android:layout="@layout/conversation_item_call"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/message_bubble_top_padding"
android:layout_marginBottom="@dimen/message_bubble_collapsed_footer_padding"
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
android:layout_marginRight="@dimen/message_bubble_horizontal_padding" />
<org.thoughtcrime.securesms.components.emoji.AutoScaledEmojiTextView
android:id="@+id/conversation_item_body"
android:layout_width="wrap_content"