mirror of
https://github.com/ArcaneChat/android.git
synced 2026-07-03 14:05:24 +02:00
Merge branch 'main' into wch423/edge-to-edge-device-channel
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -129,6 +129,7 @@ public class ContactSelectionListFragment extends Fragment
|
||||
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
|
||||
MenuInflater inflater = getActivity().getMenuInflater();
|
||||
inflater.inflate(R.menu.contact_list, menu);
|
||||
menu.findItem(R.id.menu_delete_selected).setVisible(!isMulti());
|
||||
updateActionModeState(actionMode);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -566,8 +566,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
} else if (itemId == R.id.menu_show_map) {
|
||||
WebxdcActivity.openMaps(this, chatId);
|
||||
return true;
|
||||
} else if (itemId == R.id.menu_start_call) {
|
||||
CallUtil.startCall(this, chatId);
|
||||
} else if (itemId == R.id.menu_start_audio_call) {
|
||||
CallUtil.startCall(this, chatId, false);
|
||||
return true;
|
||||
} else if (itemId == R.id.menu_start_video_call) {
|
||||
CallUtil.startCall(this, chatId, true);
|
||||
return true;
|
||||
} else if (itemId == R.id.menu_all_media) {
|
||||
handleAllMedia();
|
||||
|
||||
@@ -996,9 +996,9 @@ public class ConversationItem extends BaseConversationItem
|
||||
int chatId = messageRecord.getChatId();
|
||||
if (!messageRecord.isOutgoing() && callInfo.state instanceof CallState.Alerting) {
|
||||
int callId = messageRecord.getId();
|
||||
CallUtil.openCall(getContext(), accId, chatId, callId, callInfo.sdpOffer);
|
||||
CallUtil.openCall(getContext(), accId, chatId, callId, callInfo.sdpOffer, callInfo.hasVideo);
|
||||
} else {
|
||||
CallUtil.startCall(getContext(), accId, chatId);
|
||||
CallUtil.startCall(getContext(), accId, chatId, callInfo.hasVideo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,12 +43,14 @@ public class CallActivity extends WebViewActivity implements DcEventCenter.DcEve
|
||||
public static final String EXTRA_CHAT_ID = "chat_id";
|
||||
public static final String EXTRA_CALL_ID = "call_id";
|
||||
public static final String EXTRA_HASH = "hash";
|
||||
public static final String EXTRA_HAS_VIDEO = "has_video";
|
||||
|
||||
private DcContext dcContext;
|
||||
private Rpc rpc;
|
||||
private int accId;
|
||||
private int chatId;
|
||||
private int callId;
|
||||
private boolean hasVideo;
|
||||
private boolean ended = false;
|
||||
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
@@ -58,7 +60,9 @@ public class CallActivity extends WebViewActivity implements DcEventCenter.DcEve
|
||||
|
||||
Bundle bundle = getIntent().getExtras();
|
||||
assert bundle != null;
|
||||
hasVideo = bundle.getBoolean(EXTRA_HAS_VIDEO, true);
|
||||
String hash = bundle.getString(EXTRA_HASH, "");
|
||||
String query = hasVideo? "" : "?noOutgoingVideoInitially";
|
||||
accId = bundle.getInt(EXTRA_ACCOUNT_ID, -1);
|
||||
chatId = bundle.getInt(EXTRA_CHAT_ID, 0);
|
||||
callId = bundle.getInt(EXTRA_CALL_ID, 0);
|
||||
@@ -94,7 +98,7 @@ public class CallActivity extends WebViewActivity implements DcEventCenter.DcEve
|
||||
.withPermanentDenialDialog(getString(R.string.perm_explain_access_to_camera_denied))
|
||||
.onAllGranted(() -> {
|
||||
String url = "file:///android_asset/calls/index.html";
|
||||
webView.loadUrl(url + hash);
|
||||
webView.loadUrl(url + query + hash);
|
||||
}).onAnyDenied(this::finish)
|
||||
.execute();
|
||||
}
|
||||
@@ -168,7 +172,7 @@ public class CallActivity extends WebViewActivity implements DcEventCenter.DcEve
|
||||
@JavascriptInterface
|
||||
public void startCall(String payload) {
|
||||
try {
|
||||
callId = rpc.placeOutgoingCall(accId, chatId, payload, true);
|
||||
callId = rpc.placeOutgoingCall(accId, chatId, payload, hasVideo);
|
||||
} catch (RpcException e) {
|
||||
Log.e(TAG, "Error", e);
|
||||
}
|
||||
|
||||
@@ -18,28 +18,29 @@ import java.nio.charset.StandardCharsets;
|
||||
public class CallUtil {
|
||||
private static final String TAG = CallUtil.class.getSimpleName();
|
||||
|
||||
public static void startCall(Activity activity, int chatId) {
|
||||
public static void startCall(Activity activity, int chatId, boolean hasVideo) {
|
||||
Permissions.with(activity)
|
||||
.request(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO)
|
||||
.ifNecessary()
|
||||
.withPermanentDenialDialog(activity.getString(R.string.perm_explain_access_to_camera_denied))
|
||||
.onAllGranted(() -> {
|
||||
int accId = DcHelper.getContext(activity).getAccountId();
|
||||
startCall(activity, accId, chatId);
|
||||
startCall(activity, accId, chatId, hasVideo);
|
||||
})
|
||||
.execute();
|
||||
}
|
||||
|
||||
public static void startCall(Context context, int accId, int chatId) {
|
||||
public static void startCall(Context context, int accId, int chatId, boolean hasVideo) {
|
||||
Intent intent = new Intent(context, CallActivity.class);
|
||||
intent.setAction(Intent.ACTION_VIEW);
|
||||
intent.putExtra(CallActivity.EXTRA_ACCOUNT_ID, accId);
|
||||
intent.putExtra(CallActivity.EXTRA_CHAT_ID, chatId);
|
||||
intent.putExtra(CallActivity.EXTRA_HAS_VIDEO, hasVideo);
|
||||
intent.putExtra(CallActivity.EXTRA_HASH, "#startCall");
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
public static void openCall(Context context, int accId, int chatId, int callId, String payload) {
|
||||
public static void openCall(Context context, int accId, int chatId, int callId, String payload, boolean hasVideo) {
|
||||
String base64 = Base64.encodeToString(payload.getBytes(StandardCharsets.UTF_8), Base64.NO_WRAP);
|
||||
String hash = "";
|
||||
try {
|
||||
@@ -53,6 +54,7 @@ public class CallUtil {
|
||||
intent.putExtra(CallActivity.EXTRA_ACCOUNT_ID, accId);
|
||||
intent.putExtra(CallActivity.EXTRA_CHAT_ID, chatId);
|
||||
intent.putExtra(CallActivity.EXTRA_CALL_ID, callId);
|
||||
intent.putExtra(CallActivity.EXTRA_HAS_VIDEO, hasVideo);
|
||||
intent.putExtra(CallActivity.EXTRA_HASH, hash);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
@@ -71,6 +71,8 @@ public class CallItemView extends FrameLayout {
|
||||
title.setText(isOutgoing? R.string.outgoing_call : R.string.incoming_call);
|
||||
}
|
||||
|
||||
icon.setImageResource(callInfo.hasVideo? R.drawable.ic_videocam_white_24dp : R.drawable.baseline_call_24);
|
||||
|
||||
int[] attrs;
|
||||
if (isOutgoing) {
|
||||
attrs = new int[]{
|
||||
|
||||
@@ -61,6 +61,8 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import chat.delta.rpc.RpcException;
|
||||
|
||||
public class NotificationCenter {
|
||||
private static final String TAG = NotificationCenter.class.getSimpleName();
|
||||
@NonNull private final ApplicationContext context;
|
||||
@@ -164,7 +166,7 @@ public class NotificationCenter {
|
||||
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | IntentUtils.FLAG_MUTABLE());
|
||||
}
|
||||
|
||||
public PendingIntent getOpenCallIntent(ChatData chatData, int callId, String payload, boolean autoAccept) {
|
||||
public PendingIntent getOpenCallIntent(ChatData chatData, int callId, String payload, boolean autoAccept, boolean hasVideo) {
|
||||
final Intent chatIntent = new Intent(context, ConversationActivity.class)
|
||||
.putExtra(ConversationActivity.ACCOUNT_ID_EXTRA, chatData.accountId)
|
||||
.putExtra(ConversationActivity.CHAT_ID_EXTRA, chatData.chatId)
|
||||
@@ -184,6 +186,7 @@ public class NotificationCenter {
|
||||
intent.putExtra(CallActivity.EXTRA_CHAT_ID, chatData.chatId);
|
||||
intent.putExtra(CallActivity.EXTRA_CALL_ID, callId);
|
||||
intent.putExtra(CallActivity.EXTRA_HASH, hash);
|
||||
intent.putExtra(CallActivity.EXTRA_HAS_VIDEO, hasVideo);
|
||||
intent.setPackage(context.getPackageName());
|
||||
return TaskStackBuilder.create(context)
|
||||
.addNextIntentWithParentStack(chatIntent)
|
||||
@@ -427,6 +430,13 @@ public class NotificationCenter {
|
||||
Util.runOnAnyBackgroundThread(() -> {
|
||||
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
||||
DcContext dcContext = context.getDcAccounts().getAccount(accId);
|
||||
boolean hasVideo;
|
||||
try {
|
||||
hasVideo = context.getRpc().callInfo(accId, callId).hasVideo;
|
||||
} catch (RpcException e) {
|
||||
Log.e(TAG, "Rpc.callInfo() failed", e);
|
||||
hasVideo = false;
|
||||
}
|
||||
int chatId = dcContext.getMsg(callId).getChatId();
|
||||
DcChat dcChat = dcContext.getChat(chatId);
|
||||
String name = dcChat.getName();
|
||||
@@ -434,7 +444,7 @@ public class NotificationCenter {
|
||||
String notificationChannel = getCallNotificationChannel(notificationManager, chatData, name);
|
||||
|
||||
PendingIntent declineCallIntent = getDeclineCallIntent(chatData, callId);
|
||||
PendingIntent openCallIntent = getOpenCallIntent(chatData, callId, payload, false);
|
||||
PendingIntent openCallIntent = getOpenCallIntent(chatData, callId, payload, false, hasVideo);
|
||||
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, notificationChannel)
|
||||
.setSmallIcon(R.drawable.icon_notification)
|
||||
@@ -459,7 +469,7 @@ public class NotificationCenter {
|
||||
new NotificationCompat.Action.Builder(
|
||||
R.drawable.baseline_call_24,
|
||||
context.getString(R.string.answer_call),
|
||||
getOpenCallIntent(chatData, callId, payload, true)).build());
|
||||
getOpenCallIntent(chatData, callId, payload, true, hasVideo)).build());
|
||||
|
||||
Bitmap bitmap = getAvatar(dcChat);
|
||||
if (bitmap != null) {
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/baseline_call_24"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -26,9 +26,22 @@
|
||||
app:showAsAction="always"/>
|
||||
|
||||
<item android:id="@+id/menu_start_call"
|
||||
android:title="@string/start_call"
|
||||
android:icon="@drawable/baseline_call_24"
|
||||
app:showAsAction="always" />
|
||||
android:title="@string/start_call"
|
||||
app:showAsAction="always"
|
||||
android:icon="@drawable/baseline_call_24">
|
||||
<menu>
|
||||
<item android:id="@+id/menu_start_audio_call"
|
||||
android:title="@string/start_audio_call"
|
||||
android:icon="@drawable/baseline_call_24"
|
||||
app:iconTint="?attr/menu_icon_tint"
|
||||
/>
|
||||
<item android:id="@+id/menu_start_video_call"
|
||||
android:title="@string/start_video_call"
|
||||
android:icon="@drawable/ic_videocam_white_24dp"
|
||||
app:iconTint="?attr/menu_icon_tint"
|
||||
/>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item android:id="@+id/menu_all_media"
|
||||
android:title="@string/apps_and_media"
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
<attr name="menu_reply_icon" format="reference" />
|
||||
|
||||
<attr name="pref_icon_tint" format="color"/>
|
||||
<attr name="menu_icon_tint" format="color" />
|
||||
|
||||
<attr name="quote_missing_icon_color" format="color" />
|
||||
<attr name="quote_dismiss_button_tint" format="color" />
|
||||
|
||||
@@ -380,6 +380,8 @@
|
||||
|
||||
<!-- the action "to call someone", used as a tooltip for the "phone" icon. not: "the call" -->
|
||||
<string name="start_call">Call</string>
|
||||
<string name="start_audio_call">Audio Call</string>
|
||||
<string name="start_video_call">Video Call</string>
|
||||
<!-- the action "to answer" or to "accept" or to "pick up" a call. not: "the answer" -->
|
||||
<string name="answer_call">Answer</string>
|
||||
<!-- the action "to decline" a call, not: "the decline" -->
|
||||
|
||||
@@ -133,6 +133,7 @@
|
||||
<item name="menu_reply_icon">@drawable/ic_reply_white_24dp</item>
|
||||
|
||||
<item name="pref_icon_tint">@color/delta_primary</item>
|
||||
<item name="menu_icon_tint">@color/black</item>
|
||||
<item name="icon_tint">@color/grey_700</item>
|
||||
<item name="icon_tint_dark">@color/grey_100</item>
|
||||
|
||||
@@ -243,6 +244,7 @@
|
||||
<item name="menu_reply_icon">@drawable/ic_reply_white_24dp</item>
|
||||
|
||||
<item name="pref_icon_tint">@color/core_white</item>
|
||||
<item name="menu_icon_tint">@color/white</item>
|
||||
<item name="icon_tint">@color/grey_100</item>
|
||||
<item name="icon_tint_dark">?icon_tint</item>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user