allow to pick call and call back by clicking call messages

This commit is contained in:
adbenitez 2025-09-27 19:43:00 +02:00
parent b28fb4ac9e
commit 02a1c86f01
3 changed files with 75 additions and 7 deletions

View file

@ -70,11 +70,14 @@ import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.views.Stub;
import org.thoughtcrime.securesms.videochat.VideochatUtil;
import java.util.List;
import java.util.Set;
import chat.delta.rpc.RpcException;
import chat.delta.rpc.types.CallInfo;
import chat.delta.rpc.types.CallState;
import chat.delta.rpc.types.Reactions;
import chat.delta.rpc.types.VcardContact;
@ -589,7 +592,7 @@ public class ConversationItem extends BaseConversationItem
} catch (RpcException e) {
Log.e(TAG, "Error in Rpc.callInfo", e);
}
callViewStub.get().setOnClickListener(passthroughClickListener);
callViewStub.get().setCallClickListener(new CallClickListener());
callViewStub.get().setOnLongClickListener(passthroughClickListener);
callViewStub.get().setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
@ -983,4 +986,21 @@ public class ConversationItem extends BaseConversationItem
}
}
}
private class CallClickListener implements CallItemView.CallClickListener {
public void onClick(final View v, final CallInfo callInfo) {
if (shouldInterceptClicks(messageRecord) || !batchSelected.isEmpty()) {
performClick();
} else {
int accId = dcContext.getAccountId();
int chatId = messageRecord.getChatId();
if (!messageRecord.isOutgoing() && callInfo.state instanceof CallState.Alerting) {
int callId = messageRecord.getId();
VideochatUtil.openCall(getContext(), accId, chatId, callId, callInfo.sdpOffer);
} else {
VideochatUtil.startCall(getContext(), accId, chatId);
}
}
}
}
}

View file

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
@ -21,6 +22,8 @@ public class CallItemView extends FrameLayout {
private final @NonNull ImageView icon;
private final @NonNull TextView title;
private final @NonNull ConversationItemFooter footer;
private CallInfo callInfo;
private CallClickListener viewListener;
public CallItemView(Context context) {
this(context, null);
@ -38,9 +41,20 @@ public class CallItemView extends FrameLayout {
this.icon = findViewById(R.id.call_icon);
this.title = findViewById(R.id.title);
this.footer = findViewById(R.id.footer);
setOnClickListener(v -> {
if (viewListener != null && callInfo != null) {
viewListener.onClick(v, callInfo);
}
});
}
public void setCallClickListener(CallClickListener listener) {
viewListener = listener;
}
public void setCallItem(boolean isOutgoing, CallInfo callInfo) {
this.callInfo = callInfo;
if (callInfo.state instanceof CallState.Missed) {
title.setText(R.string.missed_call);
} else if (callInfo.state instanceof CallState.Cancelled) {
@ -77,4 +91,8 @@ public class CallItemView extends FrameLayout {
public String getDescription() {
return title.getText() + "\n" + footer.getDescription();
}
public interface CallClickListener {
void onClick(View v, CallInfo callInfo);
}
}

View file

@ -2,13 +2,21 @@ package org.thoughtcrime.securesms.videochat;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.Base64;
import android.util.Log;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.permissions.Permissions;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class VideochatUtil {
private static final String TAG = VideochatUtil.class.getSimpleName();
public static void startCall(Activity activity, int chatId) {
Permissions.with(activity)
@ -17,14 +25,36 @@ public class VideochatUtil {
.withPermanentDenialDialog(activity.getString(R.string.perm_explain_access_to_camera_denied))
.onAllGranted(() -> {
int accId = DcHelper.getContext(activity).getAccountId();
Intent intent = new Intent(activity, VideochatActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra(VideochatActivity.EXTRA_ACCOUNT_ID, accId);
intent.putExtra(VideochatActivity.EXTRA_CHAT_ID, chatId);
intent.putExtra(VideochatActivity.EXTRA_HASH, "#startCall");
activity.startActivity(intent);
startCall(activity, accId, chatId);
})
.execute();
}
public static void startCall(Context context, int accId, int chatId) {
Intent intent = new Intent(context, VideochatActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra(VideochatActivity.EXTRA_ACCOUNT_ID, accId);
intent.putExtra(VideochatActivity.EXTRA_CHAT_ID, chatId);
intent.putExtra(VideochatActivity.EXTRA_HASH, "#startCall");
context.startActivity(intent);
}
public static void openCall(Context context, int accId, int chatId, int callId, String payload) {
String base64 = Base64.encodeToString(payload.getBytes(StandardCharsets.UTF_8), Base64.NO_WRAP);
String hash = "";
try {
hash = "#offerIncomingCall=" + URLEncoder.encode(base64, "UTF-8");
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Error", e);
}
Intent intent = new Intent(context, VideochatActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra(VideochatActivity.EXTRA_ACCOUNT_ID, accId);
intent.putExtra(VideochatActivity.EXTRA_CHAT_ID, chatId);
intent.putExtra(VideochatActivity.EXTRA_CALL_ID, callId);
intent.putExtra(VideochatActivity.EXTRA_HASH, hash);
context.startActivity(intent);
}
}