diff --git a/CHANGELOG.md b/CHANGELOG.md index 67033b4a2..5ccb31acd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * Mark external links with " ↗" to make them clear * Make QR code larger on "Add Second Device" screen * Add indication for blocked contacts in user profile +* Allow to start calls with video disabled * Show hint for empty contact search results * Fix: Show dialog if pasted QR codes are invalid * Fix: Refresh chat list when returning from conversation if selected profile changed @@ -22,6 +23,7 @@ * Fix mailto handling * Fix layout problems inside in-chat apps * Avoid crash when the app is minimized with profile switcher or reactions dialogs open +* Remove "trash icon" option from contact selection list when adding members to group * Update to core 2.40.0 ## v2.35.0 diff --git a/src/main/assets/calls/index.html b/src/main/assets/calls/index.html index 96fbfcbd8..6b01902e9 100644 --- a/src/main/assets/calls/index.html +++ b/src/main/assets/calls/index.html @@ -1,6 +1,6 @@ - + - - - - + +
diff --git a/src/main/java/org/thoughtcrime/securesms/ContactSelectionListFragment.java b/src/main/java/org/thoughtcrime/securesms/ContactSelectionListFragment.java index bf4cf95ca..ff45edbae 100644 --- a/src/main/java/org/thoughtcrime/securesms/ContactSelectionListFragment.java +++ b/src/main/java/org/thoughtcrime/securesms/ContactSelectionListFragment.java @@ -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; } diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java b/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java index e6cb30b9d..0a77b617c 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java @@ -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(); diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationItem.java b/src/main/java/org/thoughtcrime/securesms/ConversationItem.java index d388cc226..bd0c7dc14 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationItem.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationItem.java @@ -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); } } } diff --git a/src/main/java/org/thoughtcrime/securesms/calls/CallActivity.java b/src/main/java/org/thoughtcrime/securesms/calls/CallActivity.java index 0b9595921..b7da6e461 100644 --- a/src/main/java/org/thoughtcrime/securesms/calls/CallActivity.java +++ b/src/main/java/org/thoughtcrime/securesms/calls/CallActivity.java @@ -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); } diff --git a/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java b/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java index f84e2385b..3ef0e237f 100644 --- a/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java +++ b/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java @@ -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); } diff --git a/src/main/java/org/thoughtcrime/securesms/components/CallItemView.java b/src/main/java/org/thoughtcrime/securesms/components/CallItemView.java index a66f54790..1cc06bec5 100644 --- a/src/main/java/org/thoughtcrime/securesms/components/CallItemView.java +++ b/src/main/java/org/thoughtcrime/securesms/components/CallItemView.java @@ -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[]{ diff --git a/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCenter.java b/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCenter.java index 7bdd7b18d..323862231 100644 --- a/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCenter.java +++ b/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCenter.java @@ -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) { diff --git a/src/main/res/layout/call_item_view.xml b/src/main/res/layout/call_item_view.xml index 66064b7e4..32aea6633 100644 --- a/src/main/res/layout/call_item_view.xml +++ b/src/main/res/layout/call_item_view.xml @@ -44,7 +44,6 @@ android:layout_width="30dp" android:layout_height="30dp" android:contentDescription="@null" - android:src="@drawable/baseline_call_24" /> diff --git a/src/main/res/menu/conversation.xml b/src/main/res/menu/conversation.xml index cbe09e6f7..879e60b2e 100644 --- a/src/main/res/menu/conversation.xml +++ b/src/main/res/menu/conversation.xml @@ -26,9 +26,22 @@ app:showAsAction="always"/> + android:title="@string/start_call" + app:showAsAction="always" + android:icon="@drawable/baseline_call_24"> + + + + + + diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index d611028b6..dc5f359b8 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -380,6 +380,8 @@ Call + Audio Call + Video Call Answer diff --git a/src/main/res/values/themes.xml b/src/main/res/values/themes.xml index d12710d85..2b049601a 100644 --- a/src/main/res/values/themes.xml +++ b/src/main/res/values/themes.xml @@ -133,6 +133,7 @@ @drawable/ic_reply_white_24dp @color/delta_primary + @color/black @color/grey_700 @color/grey_100 @@ -243,6 +244,7 @@ @drawable/ic_reply_white_24dp @color/core_white + @color/white @color/grey_100 ?icon_tint