From 1e4c8bc29120cd649dc582b54f3021fc3e0c527a Mon Sep 17 00:00:00 2001 From: adbenitez Date: Tue, 27 Jan 2026 19:05:38 +0100 Subject: [PATCH 01/29] use event emmiter before DcAccounts creation --- jni/dc_wrapper.c | 40 +++++++++++++++++- .../java/com/b44t/messenger/DcAccounts.java | 6 +-- .../com/b44t/messenger/DcEventChannel.java | 27 ++++++++++++ .../securesms/ApplicationContext.java | 41 +++++++++++-------- .../securesms/connect/DcEventCenter.java | 32 ++++++++------- 5 files changed, 110 insertions(+), 36 deletions(-) create mode 100644 src/main/java/com/b44t/messenger/DcEventChannel.java diff --git a/jni/dc_wrapper.c b/jni/dc_wrapper.c index b51257bdb..eccca6f8a 100644 --- a/jni/dc_wrapper.c +++ b/jni/dc_wrapper.c @@ -153,6 +153,42 @@ static uint32_t* jintArray2uint32Pointer(JNIEnv* env, jintArray ja, int* ret_icn } +/************************************************************ + * DcEventChannel + ************************************************************/ + +static dc_event_channel_t* get_dc_event_channel(JNIEnv *env, jobject obj) +{ + static jfieldID fid = 0; + if (fid==0) { + jclass cls = (*env)->GetObjectClass(env, obj); + fid = (*env)->GetFieldID(env, cls, "eventChannelCPtr", "J" /*Signature, J=long*/); + } + if (fid) { + return (dc_event_channel_t*)(*env)->GetLongField(env, obj, fid); + } + return NULL; +} + + +JNIEXPORT jlong Java_com_b44t_messenger_DcEventChannel_createEventChannelCPtr(JNIEnv *env, jobject obj) +{ + return (jlong)dc_event_channel_new(); +} + + +JNIEXPORT void Java_com_b44t_messenger_DcEventChannel_unrefEventChannelCPtr(JNIEnv *env, jobject obj) +{ + dc_event_channel_unref(get_dc_event_channel(env, obj)); +} + + +JNIEXPORT jlong Java_com_b44t_messenger_DcEventChannel_getEventEmitterCPtr(JNIEnv *env, jobject obj) +{ + return (jlong)dc_event_channel_get_event_emitter(get_dc_event_channel(env, obj)); +} + + /******************************************************************************* * DcAccounts ******************************************************************************/ @@ -172,11 +208,11 @@ static dc_accounts_t* get_dc_accounts(JNIEnv *env, jobject obj) } -JNIEXPORT jlong Java_com_b44t_messenger_DcAccounts_createAccountsCPtr(JNIEnv *env, jobject obj, jstring dir) +JNIEXPORT jlong Java_com_b44t_messenger_DcAccounts_createAccountsCPtr(JNIEnv *env, jobject obj, jstring dir, jobject chanObj) { CHAR_REF(dir); int writable = 1; - jlong accountsCPtr = (jlong)dc_accounts_new(dirPtr, writable); + jlong accountsCPtr = (jlong)dc_accounts_new_with_event_channel(dirPtr, writable, get_dc_event_channel(env, chanObj)); CHAR_UNREF(dir); return accountsCPtr; } diff --git a/src/main/java/com/b44t/messenger/DcAccounts.java b/src/main/java/com/b44t/messenger/DcAccounts.java index 669048b12..8a08984d3 100644 --- a/src/main/java/com/b44t/messenger/DcAccounts.java +++ b/src/main/java/com/b44t/messenger/DcAccounts.java @@ -2,8 +2,8 @@ package com.b44t.messenger; public class DcAccounts { - public DcAccounts(String dir) { - accountsCPtr = createAccountsCPtr(dir); + public DcAccounts(String dir, DcEventChannel channel) { + accountsCPtr = createAccountsCPtr(dir, channel); if (accountsCPtr == 0) throw new RuntimeException("createAccountsCPtr() returned null pointer"); } @@ -38,7 +38,7 @@ public class DcAccounts { // working with raw c-data private long accountsCPtr; // CAVE: the name is referenced in the JNI - private native long createAccountsCPtr (String dir); + private native long createAccountsCPtr (String dir, DcEventChannel channel); private native void unrefAccountsCPtr (); private native long getEventEmitterCPtr (); private native long getJsonrpcInstanceCPtr (); diff --git a/src/main/java/com/b44t/messenger/DcEventChannel.java b/src/main/java/com/b44t/messenger/DcEventChannel.java new file mode 100644 index 000000000..2c3ece1dd --- /dev/null +++ b/src/main/java/com/b44t/messenger/DcEventChannel.java @@ -0,0 +1,27 @@ +package com.b44t.messenger; + +public class DcEventChannel { + + public DcEventChannel() { + eventChannelCPtr = createEventChannelCPtr(); + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + if (eventChannelCPtr != 0) { + unrefEventChannelCPtr(); + eventChannelCPtr = 0; + } + } + + public DcEventEmitter getEventEmitter() { + return new DcEventEmitter(getEventEmitterCPtr()); + } + + // working with raw c-data + private long eventChannelCPtr; // CAVE: the name is referenced in the JNI + private native long createEventChannelCPtr (); + private native void unrefEventChannelCPtr (); + private native long getEventEmitterCPtr (); +} diff --git a/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 6476842a3..37ade8c06 100644 --- a/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -23,6 +23,7 @@ import androidx.work.WorkManager; import com.b44t.messenger.DcAccounts; import com.b44t.messenger.DcContext; import com.b44t.messenger.DcEvent; +import com.b44t.messenger.DcEventChannel; import com.b44t.messenger.DcEventEmitter; import com.b44t.messenger.FFITransport; @@ -173,7 +174,29 @@ public class ApplicationContext extends MultiDexApplication { Util.runOnBackground(() -> { synchronized (initLock) { try { - dcAccounts = new DcAccounts(new File(getFilesDir(), "accounts").getAbsolutePath()); + DcEventChannel eventChannel = new DcEventChannel(); + DcEventEmitter emitter = eventChannel.getEventEmitter(); + eventCenter = new DcEventCenter(this); + + new Thread(() -> { + Log.i(TAG, "Starting event loop"); + while (true) { + DcEvent event = emitter.getNextEvent(); + if (event == null) { + break; + } + if (isInitialized) { + eventCenter.handleEvent(event); + } else { + // not fully initialized, only handle logging events, + // ex. account migrations during DcAccounts initialization + eventCenter.handleLogging(event); + } + } + Log.i("DeltaChat", "shutting down event handler"); + }, "eventThread").start(); + + dcAccounts = new DcAccounts(new File(getFilesDir(), "accounts").getAbsolutePath(), eventChannel); Log.i(TAG, "DcAccounts created"); rpc = new Rpc(new FFITransport(dcAccounts.getJsonrpcInstance())); Log.i(TAG, "Rpc created"); @@ -213,28 +236,12 @@ public class ApplicationContext extends MultiDexApplication { } dcContext = dcAccounts.getSelectedAccount(); notificationCenter = new NotificationCenter(this); - eventCenter = new DcEventCenter(this); dcLocationManager = new DcLocationManager(this, dcContext); - // Mark as initialized before starting threads that depend on it isInitialized = true; initLock.notifyAll(); Log.i(TAG, "DcAccounts initialization complete"); - new Thread(() -> { - Log.i(TAG, "Starting event loop"); - DcEventEmitter emitter = dcAccounts.getEventEmitter(); - Log.i(TAG, "DcEventEmitter obtained"); - while (true) { - DcEvent event = emitter.getNextEvent(); - if (event==null) { - break; - } - eventCenter.handleEvent(event); - } - Log.i("DeltaChat", "shutting down event handler"); - }, "eventThread").start(); - // set translations before starting I/O to avoid sending untranslated MDNs (issue #2288) DcHelper.setStockTranslations(this); diff --git a/src/main/java/org/thoughtcrime/securesms/connect/DcEventCenter.java b/src/main/java/org/thoughtcrime/securesms/connect/DcEventCenter.java index 560f67888..f766a2e53 100644 --- a/src/main/java/org/thoughtcrime/securesms/connect/DcEventCenter.java +++ b/src/main/java/org/thoughtcrime/securesms/connect/DcEventCenter.java @@ -164,6 +164,23 @@ public class DcEventCenter { }); } + public void handleLogging(@NonNull DcEvent event) { + final String logPrefix = "[accId="+event.getAccountId()+ "] "; + switch (event.getId()) { + case DcContext.DC_EVENT_INFO: + Log.i("DeltaChat", logPrefix + event.getData2Str()); + break; + + case DcContext.DC_EVENT_WARNING: + Log.w("DeltaChat", logPrefix + event.getData2Str()); + break; + + case DcContext.DC_EVENT_ERROR: + Log.e("DeltaChat", logPrefix + event.getData2Str()); + break; + } + } + public long handleEvent(@NonNull DcEvent event) { int accountId = event.getAccountId(); int id = event.getId(); @@ -205,20 +222,7 @@ public class DcEventCenter { return 0; } - final String logPrefix = "[accId="+accountId + "] "; - switch (id) { - case DcContext.DC_EVENT_INFO: - Log.i("DeltaChat", logPrefix + event.getData2Str()); - break; - - case DcContext.DC_EVENT_WARNING: - Log.w("DeltaChat", logPrefix + event.getData2Str()); - break; - - case DcContext.DC_EVENT_ERROR: - Log.e("DeltaChat", logPrefix + event.getData2Str()); - break; - } + handleLogging(event); if (accountId != context.getDcContext().getAccountId()) { return 0; From 18e145faafbc0f6b579a1f0388cb8d2f7236f1d3 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Thu, 29 Jan 2026 02:17:06 +0100 Subject: [PATCH 02/29] avoid custom constructor in AccountSelectionListFragment --- .../AccountSelectionListFragment.java | 35 ++++++++++++------- .../securesms/connect/AccountManager.java | 2 +- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/thoughtcrime/securesms/accounts/AccountSelectionListFragment.java b/src/main/java/org/thoughtcrime/securesms/accounts/AccountSelectionListFragment.java index 7e4e2adff..014ce8308 100644 --- a/src/main/java/org/thoughtcrime/securesms/accounts/AccountSelectionListFragment.java +++ b/src/main/java/org/thoughtcrime/securesms/accounts/AccountSelectionListFragment.java @@ -47,15 +47,20 @@ import chat.delta.rpc.RpcException; public class AccountSelectionListFragment extends DialogFragment implements DcEventCenter.DcEventDelegate { private static final String TAG = AccountSelectionListFragment.class.getSimpleName(); - private final ConversationListActivity activity; + private static final String ARG_SELECT_ONLY = "select_only"; private RecyclerView recyclerView; private AccountSelectionListAdapter adapter; - private final boolean selectOnly; - public AccountSelectionListFragment(ConversationListActivity activity, boolean selectOnly) { - super(); - this.activity = activity; - this.selectOnly = selectOnly; + public static AccountSelectionListFragment newInstance(boolean selectOnly) { + AccountSelectionListFragment fragment = new AccountSelectionListFragment(); + Bundle args = new Bundle(); + args.putBoolean(ARG_SELECT_ONLY, selectOnly); + fragment.setArguments(args); + return fragment; + } + + private boolean selectOnly() { + return getArguments() != null && getArguments().getBoolean(ARG_SELECT_ONLY, false); } @NonNull @@ -64,7 +69,7 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity()) .setTitle(R.string.switch_account) .setNegativeButton(R.string.cancel, null); - if (!selectOnly) { + if (!selectOnly()) { builder.setNeutralButton(R.string.connectivity, ((dialog, which) -> { startActivity(new Intent(getActivity(), ConnectivityActivity.class)); })); @@ -99,23 +104,24 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv private void refreshData() { if (adapter == null) return; + boolean selOnly = selectOnly(); DcAccounts accounts = DcHelper.getAccounts(getActivity()); int[] accountIds = accounts.getAll(); - int[] ids = new int[(selectOnly? 0 : 1) + accountIds.length]; + int[] ids = new int[(selOnly? 0 : 1) + accountIds.length]; int j = 0; for (int accountId : accountIds) { ids[j++] = accountId; } - if (!selectOnly) ids[j] = DC_CONTACT_ID_ADD_ACCOUNT; + if (!selOnly) ids[j] = DC_CONTACT_ID_ADD_ACCOUNT; adapter.changeData(ids, accounts.getSelectedAccount().getAccountId()); } @Override public void onCreateContextMenu(@NonNull ContextMenu menu, @NonNull View v, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); - if (selectOnly) return; + if (selectOnly()) return; requireActivity().getMenuInflater().inflate(R.menu.account_item_context, menu); @@ -179,6 +185,7 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv } private void onSetTag(int accountId) { + ConversationListActivity activity = (ConversationListActivity)requireActivity(); AccountSelectionListFragment.this.dismiss(); DcContext dcContext = DcHelper.getAccounts(activity).getAccount(accountId); @@ -194,14 +201,15 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv .setPositiveButton(android.R.string.ok, (d, b) -> { String newTag = inputField.getText().toString().trim(); dcContext.setConfig(CONFIG_PRIVATE_TAG, newTag); - AccountManager.getInstance().showSwitchAccountMenu(activity, selectOnly); + AccountManager.getInstance().showSwitchAccountMenu(activity, selectOnly()); }) - .setNegativeButton(R.string.cancel, (d, b) -> AccountManager.getInstance().showSwitchAccountMenu(activity, selectOnly)) + .setNegativeButton(R.string.cancel, (d, b) -> AccountManager.getInstance().showSwitchAccountMenu(activity, selectOnly())) .show(); } private void onDeleteProfile(int accountId) { AccountSelectionListFragment.this.dismiss(); + ConversationListActivity activity = (ConversationListActivity)requireActivity(); DcAccounts accounts = DcHelper.getAccounts(activity); Rpc rpc = DcHelper.getRpc(activity); @@ -236,7 +244,7 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv AlertDialog dialog = new AlertDialog.Builder(activity) .setTitle(R.string.delete_account) .setView(dialogView) - .setNegativeButton(R.string.cancel, (d, which) -> AccountManager.getInstance().showSwitchAccountMenu(activity, selectOnly)) + .setNegativeButton(R.string.cancel, (d, which) -> AccountManager.getInstance().showSwitchAccountMenu(activity, selectOnly())) .setPositiveButton(R.string.delete, (d2, w2) -> activity.onDeleteProfile(accountId)) .show(); Util.redPositiveButton(dialog); @@ -254,6 +262,7 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv @Override public void onItemClick(AccountSelectionListItem contact) { AccountSelectionListFragment.this.dismiss(); + ConversationListActivity activity = (ConversationListActivity)requireActivity(); int accountId = contact.getAccountId(); if (accountId == DC_CONTACT_ID_ADD_ACCOUNT) { AccountManager.getInstance().switchAccountAndStartActivity(activity, 0); diff --git a/src/main/java/org/thoughtcrime/securesms/connect/AccountManager.java b/src/main/java/org/thoughtcrime/securesms/connect/AccountManager.java index 2bdebe7fe..de8901b52 100644 --- a/src/main/java/org/thoughtcrime/securesms/connect/AccountManager.java +++ b/src/main/java/org/thoughtcrime/securesms/connect/AccountManager.java @@ -138,7 +138,7 @@ public class AccountManager { // ui public void showSwitchAccountMenu(ConversationListActivity activity, boolean selectOnly) { - AccountSelectionListFragment dialog = new AccountSelectionListFragment(activity, selectOnly); + AccountSelectionListFragment dialog = AccountSelectionListFragment.newInstance(selectOnly); dialog.show(((FragmentActivity) activity).getSupportFragmentManager(), null); } From 1f9264225bbff41b548f5908246e582f4c376952 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Thu, 29 Jan 2026 03:30:17 +0100 Subject: [PATCH 03/29] remove custom constructor in ReactionsDetailsFragment --- .../securesms/ConversationFragment.java | 2 +- .../reactions/ReactionsDetailsFragment.java | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java b/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java index d28040736..30832749d 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java @@ -869,7 +869,7 @@ public class ConversationFragment extends MessageSelectorFragment @Override public void onReactionClicked(DcMsg messageRecord) { - ReactionsDetailsFragment dialog = new ReactionsDetailsFragment(messageRecord.getId()); + ReactionsDetailsFragment dialog = ReactionsDetailsFragment.newInstance(messageRecord.getId()); dialog.show(getActivity().getSupportFragmentManager(), null); } } diff --git a/src/main/java/org/thoughtcrime/securesms/reactions/ReactionsDetailsFragment.java b/src/main/java/org/thoughtcrime/securesms/reactions/ReactionsDetailsFragment.java index 91edc2e18..1288e9afc 100644 --- a/src/main/java/org/thoughtcrime/securesms/reactions/ReactionsDetailsFragment.java +++ b/src/main/java/org/thoughtcrime/securesms/reactions/ReactionsDetailsFragment.java @@ -36,19 +36,24 @@ import chat.delta.rpc.types.Reactions; public class ReactionsDetailsFragment extends DialogFragment implements DcEventCenter.DcEventDelegate { private static final String TAG = ReactionsDetailsFragment.class.getSimpleName(); + private static final String ARG_MSG_ID = "msg_id"; private RecyclerView recyclerView; private ReactionRecipientsAdapter adapter; - private final int msgId; + private int msgId; - public ReactionsDetailsFragment(int msgId) { - super(); - this.msgId = msgId; + public static ReactionsDetailsFragment newInstance(int msgId) { + ReactionsDetailsFragment fragment = new ReactionsDetailsFragment(); + Bundle args = new Bundle(); + args.putInt(ARG_MSG_ID, msgId); + fragment.setArguments(args); + return fragment; } @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { + msgId = getArguments() != null? getArguments().getInt(ARG_MSG_ID, 0) : 0; adapter = new ReactionRecipientsAdapter(requireActivity(), GlideApp.with(requireActivity()), new ListClickListener()); LayoutInflater inflater = requireActivity().getLayoutInflater(); From 2e9aa79b02bb503b746b89da56fe4bc6b0377cc0 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Thu, 29 Jan 2026 03:44:42 +0100 Subject: [PATCH 04/29] simplify changes in AccountSelectionListFragment --- .../AccountSelectionListFragment.java | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/thoughtcrime/securesms/accounts/AccountSelectionListFragment.java b/src/main/java/org/thoughtcrime/securesms/accounts/AccountSelectionListFragment.java index 014ce8308..1506980cf 100644 --- a/src/main/java/org/thoughtcrime/securesms/accounts/AccountSelectionListFragment.java +++ b/src/main/java/org/thoughtcrime/securesms/accounts/AccountSelectionListFragment.java @@ -50,6 +50,7 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv private static final String ARG_SELECT_ONLY = "select_only"; private RecyclerView recyclerView; private AccountSelectionListAdapter adapter; + private boolean selectOnly; public static AccountSelectionListFragment newInstance(boolean selectOnly) { AccountSelectionListFragment fragment = new AccountSelectionListFragment(); @@ -59,17 +60,14 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv return fragment; } - private boolean selectOnly() { - return getArguments() != null && getArguments().getBoolean(ARG_SELECT_ONLY, false); - } - @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { + selectOnly = getArguments() != null && getArguments().getBoolean(ARG_SELECT_ONLY, false); AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity()) .setTitle(R.string.switch_account) .setNegativeButton(R.string.cancel, null); - if (!selectOnly()) { + if (!selectOnly) { builder.setNeutralButton(R.string.connectivity, ((dialog, which) -> { startActivity(new Intent(getActivity(), ConnectivityActivity.class)); })); @@ -104,24 +102,23 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv private void refreshData() { if (adapter == null) return; - boolean selOnly = selectOnly(); DcAccounts accounts = DcHelper.getAccounts(getActivity()); int[] accountIds = accounts.getAll(); - int[] ids = new int[(selOnly? 0 : 1) + accountIds.length]; + int[] ids = new int[(selectOnly? 0 : 1) + accountIds.length]; int j = 0; for (int accountId : accountIds) { ids[j++] = accountId; } - if (!selOnly) ids[j] = DC_CONTACT_ID_ADD_ACCOUNT; + if (!selectOnly) ids[j] = DC_CONTACT_ID_ADD_ACCOUNT; adapter.changeData(ids, accounts.getSelectedAccount().getAccountId()); } @Override public void onCreateContextMenu(@NonNull ContextMenu menu, @NonNull View v, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); - if (selectOnly()) return; + if (selectOnly) return; requireActivity().getMenuInflater().inflate(R.menu.account_item_context, menu); @@ -201,9 +198,9 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv .setPositiveButton(android.R.string.ok, (d, b) -> { String newTag = inputField.getText().toString().trim(); dcContext.setConfig(CONFIG_PRIVATE_TAG, newTag); - AccountManager.getInstance().showSwitchAccountMenu(activity, selectOnly()); + AccountManager.getInstance().showSwitchAccountMenu(activity, selectOnly); }) - .setNegativeButton(R.string.cancel, (d, b) -> AccountManager.getInstance().showSwitchAccountMenu(activity, selectOnly())) + .setNegativeButton(R.string.cancel, (d, b) -> AccountManager.getInstance().showSwitchAccountMenu(activity, selectOnly)) .show(); } @@ -244,7 +241,7 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv AlertDialog dialog = new AlertDialog.Builder(activity) .setTitle(R.string.delete_account) .setView(dialogView) - .setNegativeButton(R.string.cancel, (d, which) -> AccountManager.getInstance().showSwitchAccountMenu(activity, selectOnly())) + .setNegativeButton(R.string.cancel, (d, which) -> AccountManager.getInstance().showSwitchAccountMenu(activity, selectOnly)) .setPositiveButton(R.string.delete, (d2, w2) -> activity.onDeleteProfile(accountId)) .show(); Util.redPositiveButton(dialog); From 8d5a55c24c35039bdd57dfab48321ed28d5126f8 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Thu, 29 Jan 2026 03:47:53 +0100 Subject: [PATCH 05/29] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e98854105..97aa1dc23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ * Fix: Update menu when using "select all" in contact selection * Fix: Avoid empty profiles after using "add as second device" from welcome screen * Fix multi-device seen messages synchronization when using multiple relays +* Avoid crash when the app is minimized with profile switcher or reactions dialogs open * Update to core 2.39.0 ## v2.35.0 From d574d3359660515328d8a5eeebcec1a97af0c491 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Thu, 29 Jan 2026 18:30:57 +0100 Subject: [PATCH 06/29] title-case the message-info send/received titles we nowhere in the app use lower case field names --- src/main/res/values/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 2f31a6eaa..d611028b6 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -1088,8 +1088,8 @@ Name Select Group Image Export Backup - sent - received + Sent + Received Open the Log Folder Open Current Logfile Tray icon cannot be disabled as Delta Chat was started with the --minimized option. From 84894ff53831e48c3014b4fd8d7a0e6c3f407fb4 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Fri, 30 Jan 2026 20:17:04 +0100 Subject: [PATCH 07/29] fix mailto handling and remove unused code --- src/main/AndroidManifest.xml | 1 + .../securesms/NewConversationActivity.java | 46 ------------------- 2 files changed, 1 insertion(+), 46 deletions(-) diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 70645bbf7..896a25645 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -93,6 +93,7 @@ + diff --git a/src/main/java/org/thoughtcrime/securesms/NewConversationActivity.java b/src/main/java/org/thoughtcrime/securesms/NewConversationActivity.java index b8180cb98..6743a12df 100644 --- a/src/main/java/org/thoughtcrime/securesms/NewConversationActivity.java +++ b/src/main/java/org/thoughtcrime/securesms/NewConversationActivity.java @@ -22,10 +22,7 @@ import static org.thoughtcrime.securesms.util.ShareUtil.acquireRelayMessageConte import static org.thoughtcrime.securesms.util.ShareUtil.isRelayingMessageContent; import android.content.Intent; -import android.net.Uri; import android.os.Bundle; -import android.util.Log; -import android.widget.Toast; import androidx.appcompat.app.AlertDialog; @@ -37,7 +34,6 @@ import com.google.zxing.integration.android.IntentResult; import org.thoughtcrime.securesms.connect.DcHelper; import org.thoughtcrime.securesms.qr.QrActivity; import org.thoughtcrime.securesms.qr.QrCodeHandler; -import org.thoughtcrime.securesms.util.MailtoUtil; import chat.delta.rpc.types.SecurejoinSource; import chat.delta.rpc.types.SecurejoinUiPath; @@ -57,48 +53,6 @@ public class NewConversationActivity extends ContactSelectionActivity { super.onCreate(bundle, ready); assert getSupportActionBar() != null; getSupportActionBar().setDisplayHomeAsUpEnabled(true); - handleIntent(); - } - - private void handleIntent() { - Intent intent = getIntent(); - String action = intent.getAction(); - if(Intent.ACTION_VIEW.equals(action) || Intent.ACTION_SENDTO.equals(action)) { - try { - Uri uri = intent.getData(); - if(uri != null) { - String scheme = uri.getScheme(); - if(MailtoUtil.isMailto(uri)) { - String textToShare = MailtoUtil.getText(uri); - String[] recipientsArray = MailtoUtil.getRecipients(uri); - if (recipientsArray.length >= 1) { - if (!textToShare.isEmpty()) { - getIntent().putExtra(TEXT_EXTRA, textToShare); - } - final String addr = recipientsArray[0]; - final DcContext dcContext = DcHelper.getContext(this); - int contactId = dcContext.lookupContactIdByAddr(addr); - if (contactId == 0 && dcContext.mayBeValidAddr(addr)) { - contactId = dcContext.createContact(null, recipientsArray[0]); - } - if (contactId == 0) { - Toast.makeText(this, R.string.bad_email_address, Toast.LENGTH_LONG).show(); - } else { - onContactSelected(contactId); - } - } else { - Intent shareIntent = new Intent(this, ShareActivity.class); - shareIntent.putExtra(Intent.EXTRA_TEXT, textToShare); - startActivity(shareIntent); - finish(); - } - } - } - } - catch(Exception e) { - Log.e(TAG, "start activity from external 'mailto:' link failed", e); - } - } } @Override From de47feac40c2078135fe30ec9ebb4661f13a8463 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Fri, 30 Jan 2026 20:21:48 +0100 Subject: [PATCH 08/29] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97aa1dc23..aa86f63fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ * Fix: Update menu when using "select all" in contact selection * Fix: Avoid empty profiles after using "add as second device" from welcome screen * Fix multi-device seen messages synchronization when using multiple relays +* Fix mailto handling * Avoid crash when the app is minimized with profile switcher or reactions dialogs open * Update to core 2.39.0 From 473c28ab07025e2923a6a5ebe620307f56951a9e Mon Sep 17 00:00:00 2001 From: adbenitez Date: Mon, 2 Feb 2026 20:31:42 +0100 Subject: [PATCH 09/29] Fix layout problems inside in-chat apps --- CHANGELOG.md | 1 + .../securesms/WebViewActivity.java | 2 +- .../thoughtcrime/securesms/util/ViewUtil.java | 26 +++++++++++++++++-- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97aa1dc23..4105a035c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ * Fix: Update menu when using "select all" in contact selection * Fix: Avoid empty profiles after using "add as second device" from welcome screen * Fix multi-device seen messages synchronization when using multiple relays +* Fix layout problems inside in-chat apps * Avoid crash when the app is minimized with profile switcher or reactions dialogs open * Update to core 2.39.0 diff --git a/src/main/java/org/thoughtcrime/securesms/WebViewActivity.java b/src/main/java/org/thoughtcrime/securesms/WebViewActivity.java index 42d1fc410..87094a35d 100644 --- a/src/main/java/org/thoughtcrime/securesms/WebViewActivity.java +++ b/src/main/java/org/thoughtcrime/securesms/WebViewActivity.java @@ -77,7 +77,7 @@ public class WebViewActivity extends PassphraseRequiredActionBarActivity findViewById(R.id.status_bar_background).setBackgroundResource(R.drawable.search_toolbar_shadow); } else { // add padding to avoid content hidden behind system bars - ViewUtil.applyWindowInsets(findViewById(R.id.content_container)); + ViewUtil.applyWindowInsets(findViewById(R.id.content_container), true, true, true, true, true); } webView.setWebViewClient(new WebViewClient() { diff --git a/src/main/java/org/thoughtcrime/securesms/util/ViewUtil.java b/src/main/java/org/thoughtcrime/securesms/util/ViewUtil.java index 122cd38e0..91c4d3a6b 100644 --- a/src/main/java/org/thoughtcrime/securesms/util/ViewUtil.java +++ b/src/main/java/org/thoughtcrime/securesms/util/ViewUtil.java @@ -390,11 +390,27 @@ public class ViewUtil { /** * Apply window insets to a view by adding padding to avoid drawing elements behind system bars. * Convenience method that applies insets to all sides. + * IME insets are propagated to child views. * * @param view The view to apply insets to */ public static void applyWindowInsets(@NonNull View view) { - applyWindowInsets(view, true, true, true, true); + applyWindowInsets(view, true, true, true, true, false); + } + + /** + * Apply window insets to a view by adding padding to avoid drawing elements behind system bars. + * + * IME insets are propagated to child views. + * + * @param view The view to apply insets to + * @param left Whether to apply left inset + * @param top Whether to apply top inset + * @param right Whether to apply right inset + * @param bottom Whether to apply bottom inset + */ + public static void applyWindowInsets(@NonNull View view, boolean left, boolean top, boolean right, boolean bottom) { + applyWindowInsets(view, left, top, right, bottom, false); } /** @@ -408,8 +424,9 @@ public class ViewUtil { * @param top Whether to apply top inset * @param right Whether to apply right inset * @param bottom Whether to apply bottom inset + * @param consumeImeInsets Whether to consume IME insets so they don't propagate to child views */ - public static void applyWindowInsets(@NonNull View view, boolean left, boolean top, boolean right, boolean bottom) { + public static void applyWindowInsets(@NonNull View view, boolean left, boolean top, boolean right, boolean bottom, boolean consumeImeInsets) { // Only enable on API 30+ where WindowInsets APIs work correctly if (!isEdgeToEdgeSupported()) return; @@ -442,6 +459,11 @@ public class ViewUtil { bottom ? basePaddingBottom + insets.bottom : basePaddingBottom ); + if (consumeImeInsets) { + windowInsets = new WindowInsetsCompat.Builder(windowInsets) + .setInsets(WindowInsetsCompat.Type.ime(), Insets.NONE) + .build(); + } return windowInsets; }); From 9d4e0e4e21fb23a1c0733a5667838483581ed04f Mon Sep 17 00:00:00 2001 From: adbenitez Date: Tue, 3 Feb 2026 00:40:00 +0100 Subject: [PATCH 10/29] remove deselected members --- .../ContactMultiSelectionActivity.java | 3 +++ .../ContactSelectionListFragment.java | 15 ++++++++++++ .../securesms/ProfileFragment.java | 24 +++++++++++++++---- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/thoughtcrime/securesms/ContactMultiSelectionActivity.java b/src/main/java/org/thoughtcrime/securesms/ContactMultiSelectionActivity.java index 9654c0249..8767ea736 100644 --- a/src/main/java/org/thoughtcrime/securesms/ContactMultiSelectionActivity.java +++ b/src/main/java/org/thoughtcrime/securesms/ContactMultiSelectionActivity.java @@ -34,6 +34,7 @@ import java.util.List; public class ContactMultiSelectionActivity extends ContactSelectionActivity { public static final String CONTACTS_EXTRA = "contacts_extra"; + public static final String DESELECTED_CONTACTS_EXTRA = "deselected_contacts_extra"; @Override protected void onCreate(Bundle icicle, boolean ready) { @@ -71,7 +72,9 @@ public class ContactMultiSelectionActivity extends ContactSelectionActivity { private void saveSelection() { Intent resultIntent = getIntent(); List selectedContacts = contactsFragment.getSelectedContacts(); + List deselectedContacts = contactsFragment.getDeselectedContacts(); resultIntent.putIntegerArrayListExtra(CONTACTS_EXTRA, new ArrayList<>(selectedContacts)); + resultIntent.putIntegerArrayListExtra(DESELECTED_CONTACTS_EXTRA, new ArrayList<>(deselectedContacts)); setResult(RESULT_OK, resultIntent); } } diff --git a/src/main/java/org/thoughtcrime/securesms/ContactSelectionListFragment.java b/src/main/java/org/thoughtcrime/securesms/ContactSelectionListFragment.java index 4c6f11bb0..bf4cf95ca 100644 --- a/src/main/java/org/thoughtcrime/securesms/ContactSelectionListFragment.java +++ b/src/main/java/org/thoughtcrime/securesms/ContactSelectionListFragment.java @@ -58,6 +58,7 @@ import org.thoughtcrime.securesms.util.Util; import org.thoughtcrime.securesms.util.ViewUtil; import java.util.ArrayList; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; @@ -83,6 +84,7 @@ public class ContactSelectionListFragment extends Fragment private DcContext dcContext; private Set selectedContacts; + private Set deselectedContacts; private OnContactSelectedListener onContactSelectedListener; private String cursorFilter; private RecyclerView recyclerView; @@ -226,6 +228,15 @@ public class ContactSelectionListFragment extends Fragment return selected; } + public @NonNull List getDeselectedContacts() { + List deselected = new LinkedList<>(); + if (deselectedContacts != null) { + deselected.addAll(deselectedContacts); + } + + return deselected; + } + private boolean isMulti() { return getActivity().getIntent().getBooleanExtra(MULTI_SELECT, false); } @@ -241,6 +252,7 @@ public class ContactSelectionListFragment extends Fragment isMulti(), true); selectedContacts = adapter.getSelectedContacts(); + deselectedContacts = new HashSet<>(); ArrayList preselectedContacts = getActivity().getIntent().getIntegerArrayListExtra(PRESELECTED_CONTACTS); if(preselectedContacts!=null) { selectedContacts.addAll(preselectedContacts); @@ -309,12 +321,14 @@ public class ContactSelectionListFragment extends Fragment } selectedContacts.add(contactId); + deselectedContacts.remove(contactId); contact.setChecked(true); if (onContactSelectedListener != null) { onContactSelectedListener.onContactSelected(contactId); } } else { selectedContacts.remove(contactId); + deselectedContacts.add(contactId); contact.setChecked(false); if (onContactSelectedListener != null) { onContactSelectedListener.onContactDeselected(contactId); @@ -355,6 +369,7 @@ public class ContactSelectionListFragment extends Fragment int contactId = data.getIntExtra(NewContactActivity.CONTACT_ID_EXTRA, 0); if (contactId != 0) { selectedContacts.add(contactId); + deselectedContacts.remove(contactId); } getLoaderManager().restartLoader(0, null, ContactSelectionListFragment.this); } diff --git a/src/main/java/org/thoughtcrime/securesms/ProfileFragment.java b/src/main/java/org/thoughtcrime/securesms/ProfileFragment.java index e9c9a19c5..6c9e38f6b 100644 --- a/src/main/java/org/thoughtcrime/securesms/ProfileFragment.java +++ b/src/main/java/org/thoughtcrime/securesms/ProfileFragment.java @@ -310,11 +310,27 @@ public class ProfileFragment extends Fragment super.onActivityResult(requestCode, resultCode, data); if (requestCode==REQUEST_CODE_PICK_CONTACT && resultCode==Activity.RESULT_OK && data!=null) { List selected = data.getIntegerArrayListExtra(ContactMultiSelectionActivity.CONTACTS_EXTRA); - if(selected == null) return; + List deselected = data.getIntegerArrayListExtra(ContactMultiSelectionActivity.DESELECTED_CONTACTS_EXTRA); Util.runOnAnyBackgroundThread(() -> { - for (Integer contactId : selected) { - if (contactId!=null) { - dcContext.addContactToChat(chatId, contactId); + if (deselected != null) { + // Remove members that were deselected + int[] members = dcContext.getChatContacts(chatId); + for (int contactId : deselected) { + for (int memberId : members) { + if (memberId == contactId) { + dcContext.removeContactFromChat(chatId, memberId); + break; + } + } + } + } + + if (selected != null) { + // Add new members + for (Integer contactId : selected) { + if (contactId != null) { + dcContext.addContactToChat(chatId, contactId); + } } } }); From 7fa04dc3c0de09d96c044f1f55e0bd847de818c9 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Tue, 3 Feb 2026 01:03:05 +0100 Subject: [PATCH 11/29] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97aa1dc23..794f842cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ * Fix: Refresh chat list when returning from conversation if selected profile changed * Fix: Update menu when using "select all" in contact selection * Fix: Avoid empty profiles after using "add as second device" from welcome screen +* Fix: Remove from group deselected members in the contact selection list * Fix multi-device seen messages synchronization when using multiple relays * Avoid crash when the app is minimized with profile switcher or reactions dialogs open * Update to core 2.39.0 From 15c60c6b12612029fe22e1dca70643b963691528 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Tue, 3 Feb 2026 20:57:47 +0100 Subject: [PATCH 12/29] fix mailto handling --- .../thoughtcrime/securesms/ShareActivity.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/thoughtcrime/securesms/ShareActivity.java b/src/main/java/org/thoughtcrime/securesms/ShareActivity.java index 3cc0ed8c3..e35d89c14 100644 --- a/src/main/java/org/thoughtcrime/securesms/ShareActivity.java +++ b/src/main/java/org/thoughtcrime/securesms/ShareActivity.java @@ -104,24 +104,23 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity implement resolvedExtras = new ArrayList<>(); List streamExtras = new ArrayList<>(); + if (MailtoUtil.isMailto(getIntent().getData())) { + String[] extraEmail = getIntent().getStringArrayExtra(Intent.EXTRA_EMAIL); + if (extraEmail == null || extraEmail.length == 0) { + getIntent().putExtra(Intent.EXTRA_EMAIL, MailtoUtil.getRecipients(getIntent().getData())); + } + String text = getIntent().getStringExtra(Intent.EXTRA_TEXT); + if (text == null || text.isEmpty()) { + getIntent().putExtra(Intent.EXTRA_TEXT, MailtoUtil.getText(getIntent().getData())); + } + } + if (Intent.ACTION_SEND.equals(getIntent().getAction()) && getIntent().getParcelableExtra(Intent.EXTRA_STREAM) != null) { Uri uri = getIntent().getParcelableExtra(Intent.EXTRA_STREAM); streamExtras.add(uri); } else if (getIntent().getParcelableArrayListExtra(Intent.EXTRA_STREAM) != null) { streamExtras = getIntent().getParcelableArrayListExtra(Intent.EXTRA_STREAM); - } else { - Uri uri = getIntent().getData(); - if (MailtoUtil.isMailto(uri)) { - String[] extraEmail = getIntent().getStringArrayExtra(Intent.EXTRA_EMAIL); - if (extraEmail == null || extraEmail.length == 0) { - getIntent().putExtra(Intent.EXTRA_EMAIL, MailtoUtil.getRecipients(uri)); - } - String text = getIntent().getStringExtra(Intent.EXTRA_TEXT); - if (text == null || text.isEmpty()) { - getIntent().putExtra(Intent.EXTRA_TEXT, MailtoUtil.getText(uri)); - } - } } if (needsFilePermission(streamExtras)) { @@ -263,6 +262,7 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity implement } chatId = dcContext.createChatByContactId(contactId); + accId = dcContext.getAccountId(); } Intent composeIntent; if (accId != -1 && chatId != -1) { From 688a103c10501ba22d98fc4e9d907bb97d42e861 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Wed, 4 Feb 2026 16:45:29 +0100 Subject: [PATCH 13/29] hide delete-contact icon in ContactSelectionListFragment --- .../org/thoughtcrime/securesms/ContactSelectionListFragment.java | 1 + 1 file changed, 1 insertion(+) 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; } From 134145d1667e34da1888f2dbfb47760b1962f79a Mon Sep 17 00:00:00 2001 From: adbenitez Date: Wed, 4 Feb 2026 17:13:48 +0100 Subject: [PATCH 14/29] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49355a928..7196ced7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,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.39.0 ## v2.35.0 From df7d80319ca1eee563bcf5e2ad57218889d09c71 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Wed, 4 Feb 2026 19:36:34 +0100 Subject: [PATCH 15/29] show menu to select audio/video call modes --- .../securesms/ConversationActivity.java | 7 +++++-- .../thoughtcrime/securesms/calls/CallUtil.java | 6 +++--- src/main/res/menu/conversation.xml | 17 ++++++++++++++--- src/main/res/values/strings.xml | 2 ++ 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java b/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java index b11340984..d481dd062 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, true); + return true; + } else if (itemId == R.id.menu_start_video_call) { + CallUtil.startCall(this, chatId, false); return true; } else if (itemId == R.id.menu_all_media) { handleAllMedia(); diff --git a/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java b/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java index f84e2385b..b1494f786 100644 --- a/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java +++ b/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java @@ -18,19 +18,19 @@ 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 audioOnly) { 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, audioOnly); }) .execute(); } - public static void startCall(Context context, int accId, int chatId) { + public static void startCall(Context context, int accId, int chatId, boolean audioOnly) { Intent intent = new Intent(context, CallActivity.class); intent.setAction(Intent.ACTION_VIEW); intent.putExtra(CallActivity.EXTRA_ACCOUNT_ID, accId); diff --git a/src/main/res/menu/conversation.xml b/src/main/res/menu/conversation.xml index cbe09e6f7..678d48f3d 100644 --- a/src/main/res/menu/conversation.xml +++ b/src/main/res/menu/conversation.xml @@ -26,9 +26,20 @@ app:showAsAction="always"/> + android:title="@string/start_call" + app:showAsAction="always" + android:icon="@drawable/baseline_call_24"> + + + + + Call + Audio Call + Video Call Answer From 41d94ae3ee2f715750b2fe5d6dad945f4ba8c0da Mon Sep 17 00:00:00 2001 From: adbenitez Date: Wed, 4 Feb 2026 22:14:50 +0100 Subject: [PATCH 16/29] if it is an audio-only call start with video disabled --- src/main/java/org/thoughtcrime/securesms/ConversationItem.java | 2 +- src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationItem.java b/src/main/java/org/thoughtcrime/securesms/ConversationItem.java index d388cc226..bdd12795a 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationItem.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationItem.java @@ -998,7 +998,7 @@ public class ConversationItem extends BaseConversationItem int callId = messageRecord.getId(); CallUtil.openCall(getContext(), accId, chatId, callId, callInfo.sdpOffer); } else { - CallUtil.startCall(getContext(), accId, chatId); + CallUtil.startCall(getContext(), accId, chatId, false); // TODO: core api needed to get if call message is audio-only } } } diff --git a/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java b/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java index b1494f786..f4db9d2db 100644 --- a/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java +++ b/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java @@ -35,7 +35,8 @@ public class CallUtil { intent.setAction(Intent.ACTION_VIEW); intent.putExtra(CallActivity.EXTRA_ACCOUNT_ID, accId); intent.putExtra(CallActivity.EXTRA_CHAT_ID, chatId); - intent.putExtra(CallActivity.EXTRA_HASH, "#startCall"); + String query = audioOnly? "?noOutgoingVideoInitially" : ""; + intent.putExtra(CallActivity.EXTRA_HASH, query + "#startCall"); context.startActivity(intent); } From dd0e847976a8905bc1ab6f30a6d8556b3fd4d89a Mon Sep 17 00:00:00 2001 From: adbenitez Date: Wed, 4 Feb 2026 23:17:42 +0100 Subject: [PATCH 17/29] take into consideration if the call is audio/video call when accepting it --- .../thoughtcrime/securesms/ConversationItem.java | 2 +- .../securesms/calls/CallActivity.java | 6 +++++- .../thoughtcrime/securesms/calls/CallUtil.java | 4 ++-- .../notifications/NotificationCenter.java | 16 +++++++++++++--- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationItem.java b/src/main/java/org/thoughtcrime/securesms/ConversationItem.java index bdd12795a..821ade706 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationItem.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationItem.java @@ -998,7 +998,7 @@ public class ConversationItem extends BaseConversationItem int callId = messageRecord.getId(); CallUtil.openCall(getContext(), accId, chatId, callId, callInfo.sdpOffer); } else { - CallUtil.startCall(getContext(), accId, chatId, false); // TODO: core api needed to get if call message is audio-only + 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 d20eb88a7..158f8609e 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_AUDIO_ONLY = "audio_only"; private DcContext dcContext; private Rpc rpc; private int accId; private int chatId; private int callId; + private boolean audioOnly; 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; + audioOnly = bundle.getBoolean(EXTRA_AUDIO_ONLY, false); String hash = bundle.getString(EXTRA_HASH, ""); + String query = audioOnly? "?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(); } diff --git a/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java b/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java index f4db9d2db..0e2b79875 100644 --- a/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java +++ b/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java @@ -35,8 +35,8 @@ public class CallUtil { intent.setAction(Intent.ACTION_VIEW); intent.putExtra(CallActivity.EXTRA_ACCOUNT_ID, accId); intent.putExtra(CallActivity.EXTRA_CHAT_ID, chatId); - String query = audioOnly? "?noOutgoingVideoInitially" : ""; - intent.putExtra(CallActivity.EXTRA_HASH, query + "#startCall"); + intent.putExtra(CallActivity.EXTRA_AUDIO_ONLY, audioOnly); + intent.putExtra(CallActivity.EXTRA_HASH, "#startCall"); context.startActivity(intent); } diff --git a/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCenter.java b/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCenter.java index 7bdd7b18d..dbbdceeac 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 audioOnly) { 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_AUDIO_ONLY, audioOnly); 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 audioOnly; + try { + audioOnly = !context.getRpc().callInfo(accId, callId).hasVideo; + } catch (RpcException e) { + Log.e(TAG, "Rpc.callInfo() failed", e); + audioOnly = true; + } 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, audioOnly); 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, audioOnly)).build()); Bitmap bitmap = getAvatar(dcChat); if (bitmap != null) { From 11f73a88e834da25d534623c4401adcaa7190f57 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Wed, 4 Feb 2026 23:31:30 +0100 Subject: [PATCH 18/29] update deltachat-core-rust to 'chore(release): prepare for 2.40.0' of 'v2.40.0' --- jni/deltachat-core-rust | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jni/deltachat-core-rust b/jni/deltachat-core-rust index baeb31b5f..b72a677f4 160000 --- a/jni/deltachat-core-rust +++ b/jni/deltachat-core-rust @@ -1 +1 @@ -Subproject commit baeb31b5faa28d9cfc35ed5bb27a974d980dad6d +Subproject commit b72a677f4c1b643fa56a4d15aefbf043fc5c9ee2 From 5d7ab84efc590656305f0affc163ab2fb4121d5d Mon Sep 17 00:00:00 2001 From: adbenitez Date: Wed, 4 Feb 2026 23:35:14 +0100 Subject: [PATCH 19/29] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49355a928..67033b4a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,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 -* Update to core 2.39.0 +* Update to core 2.40.0 ## v2.35.0 2026-01 From 64bbe9866db8d799f5ca353626a69deb093941fb Mon Sep 17 00:00:00 2001 From: adbenitez Date: Wed, 4 Feb 2026 23:38:33 +0100 Subject: [PATCH 20/29] update translations --- src/main/res/values-de/strings.xml | 4 +- src/main/res/values-fa/strings.xml | 46 +++++++++-- src/main/res/values-fr/strings.xml | 32 ++++++-- src/main/res/values-it/strings.xml | 1 + src/main/res/values-lt/strings.xml | 58 ++++++++++++-- src/main/res/values-nl/strings.xml | 4 +- src/main/res/values-pl/strings.xml | 5 +- src/main/res/values-sv/strings.xml | 124 +++++++++++++++++++++++++++++ src/main/res/values-uk/strings.xml | 49 +++++++----- 9 files changed, 277 insertions(+), 46 deletions(-) diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index 7bb396928..99a5d88e6 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -1088,8 +1088,8 @@ Name Gruppenbild auswählen Backup exportieren - gesendet - empfangen + Gesendet + Empfangen Log-Ordner öffnen Aktuelle Logdatei öffnen Benachrichtigungssymbol kann nicht deaktiviert werden, da Delta Chat mit der Option --minimized gestartet wurde. diff --git a/src/main/res/values-fa/strings.xml b/src/main/res/values-fa/strings.xml index 0705846c7..455cdbd38 100644 --- a/src/main/res/values-fa/strings.xml +++ b/src/main/res/values-fa/strings.xml @@ -21,10 +21,10 @@ هیچ‌کدام خودکار سخت‌گیرانه - گشودن + بازکردن بارگیری در حال بارگیری… - گشودن پیوست + بازکردن پیوست پیوستن پیوستن مجدد حذف @@ -54,7 +54,7 @@ سکوت بی‌صدا پیام‌های ناپدید شونده - این روی تمام عضو‌های این گپ، اگر از دلتاچت استفاده کنند، اعمال می‌شود. ولی همچنان می‌توانند پیام‌ها را رونوشت، ذخیره و هدایت کنند. + شامل همه کسانی که در این گفتگو حضور دارند می‌شود. آن‌ها همچنان می‌توانند پیام‌ها را هدایت و ذخیره کرده یا از آن‌ها رونوشت بگیرند. ذخیره گپ رسانه @@ -76,9 +76,9 @@ فعال کردن بارگیری تصاویر از بیرون - تصاویر مربوط به نشانی‌های اینترنتی دیگر می‌توانند برای ردیابی شما استفاده شوند. \n\n این تنظیم‌ها همچنین برای بارگیری فونت‌ها و دیگر محتواها استفاده می‌شوند. اگر غیرفعال باشد ممکن است همچنان تصویر‌های درون پیام و تصویر‌های بارگیری شده را ببینید. \n\n آيا تصاویر خارجی بارگیری شوند؟ + تصاویر مربوط به نشانی‌های اینترنتی دیگر می‌توانند برای ردیابی شما استفاده شوند. \n\n این تنظیمات همچنین برای بارگیری فونت‌ها و دیگر محتواها استفاده می‌شود. اگر غیرفعال باشد ممکن است همچنان تصویر‌های درون پیام و تصویر‌های بارگیری شده را ببینید. \n\n آيا تصاویر خارجی بارگیری شوند؟ همیشه - تصاویر دوردست همیشه بار شوند + تصاویر با منبع بیرونی همیشه بارگیری شوند همین یک بار نمایش هشدار اکنون نه @@ -208,6 +208,8 @@ برنامه برنامه‌ها + آدرس مخزن برنامه‌ها + اگر آن را تنظیم کنید، از این آدرس برای مخزن برنامه‌ها به جای آدرس پیش‌فرض استفاده می‌شود برای به اشتراک گذاری روی «ارسال» بزنید خانه بازی‌ها @@ -629,6 +631,7 @@ گفتگو غیرمتمرکز و ایمن اسکن کردن کد دعوت ورود + این برای کاربر‌های حرفه‌ای است:\n\n • از یک آدرس که در برنامه‌ای دیگر استفاده می‌کنید استفاده نکنید.\n\n • ارائه‌دهندهٔ رایانامه کلاسیک اجازه خواهد داد که گپ‌ها بدون رمزنگاری سراسری باشند. این گپ‌ها به وسیلهٔ یک نماد نامه نشانه‌گذاری می‌شوند. ورودی IMAP Login Name IMAP Server @@ -653,6 +656,19 @@ می‌خواهید از پروکسی «%1$s» استفاده کنید؟ دوست‌هایتان می‌توانند با اسکن کردن کد QR این پروکسی را اضافه کنند. اشتراک گذاشتن پیوند + پروکسی فعال شده + شما از یک پروکسی استفاده می‌کنید. اگر مشکل وصل شدن داری، یک پروکسی دیگر استفاده کنید. + + رله‌ها + اضافه کردن رله + حذف رله + ویرایش رله + + اضافه کردن این رله؟ + کیو‌آر کد اسکن شده دارای یک رلهٔ معتبر نیست. + + حذف کردن رلهٔ «%1$s»؟\n\n مخاطب‌های شما تنها در صورتی می‌توانند با شما ارتباط برقرار کنند که قبلا از طریق یک رلهٔ دیگر با آن‌ها تماس داشته‌اید.\n\n در صورت تردید، این رله را بعدا حذف کنید. + بررسی‌های گواهینامه لطفاً یک نشانی رایانامهٔ معتبر وارد کنید لطفا یک کارساز / نشانی آی‌پی صحیح وارد کنید @@ -716,6 +732,7 @@ درخواست مسدود کردن عکس گرفتن از صفحه در لیست اخیر و درون نرم‌افزار برای اعمال کردن تنظیم‌های امنیت صفحه لطفا نرم‌افزار را بسته و دوباره باز کنید. اعلان‌ها + اشاره‌ها(منشن‌ها) در گروه‌های بی‌صدا شده، برای پیام‌های مستقیم به خودتان، مانند پاسخ‌ها یا واکنش‌ها، اعلان دریافت کنید. نمایش اولویت @@ -766,6 +783,8 @@ اگر این گزینه را غیر فعال می‌کنید از اینکه سرور شما و حساب‌هایتان هم بر این اساس تنظیم شده باشند.\n\n در غیر این صورت ممکن است هیچ چیز کار نکند. حالت چند دستگاهی + همگام‌سازی پیام‌های شما با دیگر دستگاه‌هایتان. در صورت اضافه کردن دستگاه دوم به صورت خودکار فعال می‌شود. + حالت چند دستگاهی زمانی که از یک نمایه روی چند دستگاه استفاده می‌کنید باید فعال شود. تنها در صورتی این تنظیم را غیرفعال کنید که این نمایه را از روی همهٔ دیگر دستگاه‌هایتان حذف کرده‌اید. \n\n غیرفعال کردن حالت چند دستگاهی زمانی که یک نمایه را روی چند دستگاه دارید باعث می‌شود که بعضی پیام‌ها گم شوند و همچنین مشکل‌های دیگری به وجود می‌آورد. انتقال خودکار به پوشه دلتاچت فقط پوشه دلتاچت را بررسی کن نمایش رایانامه‌های معمولی @@ -773,6 +792,7 @@ برای مخاطبین پذیرفته شده همه ویژگی‌های آزمایشی + این ویژگی‌ها ممکن است ناپایدار باشند و همچنین ممکن است بعدا تغییر کنند یا حذف شوند هم‌رسانی زندهٔ به‌فرمان مکان پس‌زمینه پیش‌فرض رنگ پیش‌فرض @@ -796,7 +816,16 @@ نمایش نمادک در زیر صفحه ویرایش نمایه غیر فعال‌سازی IMAP IDLE + استفاده نکردن از افزونهٔ IMAP IDLE حتی در صورتی که ارائه‌دهنده از آن پشتیبانی می‌کند. فعال‌سازی این گزینه باعث می‌شوند دریافت پیام‌ها به تاخیر بیوفتد. تنها برای آزمایش آن را فعال کنید. ارسال آمار برای توسعه‌دهندگان دلتاچت + آیا می‌خواهید با فرستادن آمار استفادهٔ هفتگی به بهبود دلتاچت کمک کنید؟ 👈این‌جا را بزنید...👉 + می‌خواهید با فرستادن گزارش‌های ناشناس استفادهٔ هفتگی به بهبود دلتاچت کمک کنید؟ + ممنون! هر زمان که خواستید می‌توانید فرستادن آمار‌ها را در «تنظیم‌ها - پیشرفته» غیرفعال کنید\n\n علاوه بر این، تمایل دارید ۵ دقیقه در یک تحقیق علمی راجع به امنیت دلتاچت شرکت کنید؟ + ارسال آمار‌ها قبلا فعال شدن است.\n\n می‌خواهید آن را غیر فعال کنید؟ + غیرفعال کردن + ادامه‌دادن به ارسال + این پیوست شامل آمار استفادهٔ ناشناس است که به ما کمک می‌کند دلتاچت را بهبود دهیم. برای اطلاعات بیش‌تر https://delta.chat/help#statssending را ببینید. متشکریم! + نتایج جستجو شکلکی پیدا نشد @@ -829,6 +858,8 @@ آیا می‌خواهید %1$d پیام را اکنون و تمام پیام‌های آیندهٔ «%2$s» را پاک کنید؟/n/n⚠️ این شامل رایانامه‌ها، رسانه و «پیام‌های ذخیره شده» در همه پوشه‌های کارساز(سرور) می‌شود/n/n⚠️ اگر می‌خواهید داده‌ها در کارساز باقی بمانند از این قابلیت استفاده نکنید/n/n⚠️ اگر به‌جز دلتاچت از دیگر نرم‌افزارهای رایانامه هم استفاده می‌کنید این قابلیت را به کار نگیرید. این شامل رایانامه‌ها، رسانه‌ها و «پیام‌های ذخیره شده» در تمام پوشه‌های کارساز(سرور) می‌شود. اگر می‌خواهید داده‌ها را در کارساز نگه دارید از این قابلیت استفاده نکنید. اگر از دیگر نرم‌افزارهای رایانامه به‌جز دلتاچت استفاده می‌کنید هم از این قابلیت استفاده نکنید. + فعال‌سازی حذف بلافاصله + اگر حذف بلافاصله را فعال کنید، نمی‌توانید این نمایه را روی چند دستگاه داشته باشید. متوجه هستم، همه پیام‌ها حذف شوند یک بار بعد از بارگیری @@ -949,6 +980,7 @@ اثر انگشت دیگران برای ارتباط با شما می‌توانند این کد کیوآر را اسکن کنند. \n\n می‌توان کد کیوآر را در اینجا غیر فعال کنید و با اسکن کردن مجدد، آن را فعال کنید. این کد کیوآر می‌تواند توسط دیگران و برای پیوستن به گروه «%1$s» اسکن شود.\n\n شما می‌تواند این کد کیوآر را در اینجا غیرفعال کنید و با اسکن کردن مجدد، آن را فعال نمایید. + این کد کیوآر می‌تواند توسط بقیه برای پیوستن به کانال «%1$s» اسکن شود. \n\n می‌توانید آن را بازنشانی کنید تا کد یا پیوند دعوت فعلی از کار بیوفتد. غیرفعال کردن کد کیوآر این کد کیو‌آر بازنشانی شده است و دیگر فعال نیست. فعال کردن کد کیوآر @@ -959,6 +991,7 @@ کد دعوت کیوآر برای عضو شدن در گروه\"%1$s\" این را اسکن کنید. + برای ملحق شدن به کانال «%1$s» اسکن کنید کد دعوت کیوآر برای ارتباط با %1$s این را اسکن کنید. @@ -972,10 +1005,13 @@ کاربر %1$s شما را دعوت کرده است تا عضو این گروه شوید. در انتظار دستگاه %2$s برای پاسخگویی... + + %1$sشما را به این کانال دعوت کرده است.\n\n منتظر دستگاه %2$s برای پاسخ‌دادن هستیم... کاربر %1$s پاسخ داد، در انتظار اضافه شدن به گروه... در حال برقراری ارتباط، لطفا صبر کنید... %1$s تأیید شد. + شما این مخاطب را مسدود کردید. احراز هویت شده توسط %1$s تأیید شده توسط من diff --git a/src/main/res/values-fr/strings.xml b/src/main/res/values-fr/strings.xml index f73b0fb2c..771acd9b1 100644 --- a/src/main/res/values-fr/strings.xml +++ b/src/main/res/values-fr/strings.xml @@ -199,6 +199,7 @@ Vidéo Documents Contact + Robot Caméra Enregistrer @@ -218,6 +219,8 @@ Appli Applis + URL du catalogue des apps + Si elle est définit l\'URL sera utilisée à la place de l\'URL par défaut. Appuyez \"Envoyer\" pour partager Accueil Jeux @@ -350,7 +353,7 @@ Messages de l\'appareil Messages générés localement Les messages dans cette discussion sont générés localement par votre application Delta Chat. Cela vous permet de recevoir des informations concernant les mises à jour et problèmes rencontrés à l\'utilisation. - Gardez contact !\n\n🙌 Cliquez sur « code QR » sur la page d\'accueil des deux appareils. Sélectionnez « Scanner le code QR » sur un des appareils et positionnez les deux appareils l\'un vers l\'autre\n\n🌍 Si vous n\'êtes pas dans la même pièce, vous pouvez scanner le code QR pendant un appel vidéo ou partager un lien d\'invitation à partir de « Scanner le code QR »\n\n Profitez ensuite de votre expérience de messagerie sur le plus grand réseau décentralisé du monde : les emails. Contrairement aux autres applications populaires, tout cela se fait sans contrôle centralisé, suivi ou revente de vos données, celles de vos amis, collègues ou famille à de grandes entreprises. + Entrez en contact !\n\n🙌 Cliquez sur « code QR » sur la page d\'accueil des deux appareils. Sélectionnez « Scanner le code QR » sur un des appareils et positionnez les deux appareils l\'un vers l\'autre\n\n🌍 Si vous n\'êtes pas dans la même pièce, vous pouvez scanner le code QR pendant un appel vidéo ou partager un lien d\'invitation à partir de « Scanner le code QR »\n\n Profitez ensuite de votre expérience de messagerie sur le plus grand réseau décentralisé du monde : les emails. Contrairement aux autres applications populaires, tout cela se fait sans contrôle centralisé, suivi ou revente de vos données, celles de vos amis, collègues ou famille à de grandes entreprises. Mettre à jour le contact Épingler la discussion @@ -366,7 +369,7 @@ Ajouter à l\'écran d\'accueil Faire un don - ❤️ On dirait que vous aimez bien Delta Chat!\n\nMerci de considérer une donation à Delta Chat afin d\'assurer qu\'il reste libre et gratuit pour tout le monde.\n\nBien que Delta Chat est gratuit à l\'utilisation et un logiciel libre, le développer coûte de l\'argent. Aidez-nous à garder Delta Chat indépendent et le rendre encore plus incroyable dans le future.\n\nhttps://delta.chat/donate + ❤️ On dirait que vous aimez bien Delta Chat!\n\nMerci de considérer une donation à Delta Chat afin d\'assurer qu\'il reste libre et gratuit pour tout le monde.\n\nBien que Delta Chat soit gratuit à l\'utilisation et un logiciel libre, le développer coûte de l\'argent. Aidez-nous à garder Delta Chat indépendant et le rendre encore plus incroyable dans le futur.\n\nhttps://delta.chat/donate Désactiver pour 1 heure Désactiver pour 8 heures @@ -398,6 +401,9 @@ Appel rejeté Appel annulé Appel manqué + + %1$s, %2$s + Êtes-vous sûr de vouloir quitter la discussion ? @@ -657,7 +663,7 @@ Entrer le lien du proxy ici Proxy invalide ou non supporté Sauver les proxy - Effacer le proxy + Supprimer le proxy Voulez-vous vraiment supprimer « %1$s » ? Voulez-vous utilser le proxy \"%1$s\" ? Vos amis peuvent ajouter ce proxy en scannant le code QR. @@ -671,6 +677,10 @@ Modifier le relais Ajouter le relais ? + Le QR code scanné ne renvoie pas vers un relai valide. + + Supprimer le relai \"%1$s\"\n\nVos contacts ne peuvent vous contacter que si vous les avez déjà contactés depuis un autre relai.\n\nDans le doute, supprimez le relai plus tard. + Vérification du certificat Entrez une adresse email valide Entre un serveur / adresse IP valide @@ -946,7 +956,7 @@ Vous avez réglé le temps d\'affichage des messages éphémères à %1$s semaines. Minuterie des messages éphémères réglée à %1$s semaines par %2$s. - Les messages de cette conversation utilise le mail classique et ne sont pas chiffrés de bout-en-bout. + Les messages de cette conversation utilisent le mail classique et ne sont pas chiffrés de bout-en-bout. Les messages sont désormais garantis chiffrés de bout en bout. Appuyer pour en savoir plus. Il n\'est pas garanti que tous les messages de cette discussion sont chiffrés de bout en bout.\n\nLe chiffrement de bout en bout assure la confidentialité des messages échangés par les membres d\'une discussion. Même votre fournisseur de courriel ne peut pas les lire. ⚠️ %1$s nécessite un chiffrement de bout en bout qui n\'est pas encore configuré sur cette discussion. Appuyez pour en savoir plus. @@ -996,7 +1006,7 @@ Scanner pour discuter avec %1$s Pas de connexion Internet, ne peut pas effectuer la configuration du QR code. Créer une nouvelle adresse de courriel sur « %1$s » et se connecter ici ? - Choisissez un nom que vos contacts reconnaîtrons. Vous pouvez également définir une image pour votre profil. + Choisissez un nom que vos contacts reconnaîtront. Vous pouvez également définir une image pour votre profil. Veuillez saisir un nom. Le code QR scanné ne peut pas être utilisé pour ouvrir un nouveau compte. @@ -1146,9 +1156,17 @@ Toutes les %1$d heures en moyenne Dernièrement vu à %1$s Paramètres du système + + Éditer le type, les badges, les prévisualisation et plus encore. Raccourcis + + Utiliser la fonction \"Ajouter au Widget\" de Delta Chat pour ajouter un élément. + + Retirer du Widget + + Ajouter au Widget Delta Chat utilise votre appareil photo pour prendre des photos et des vidéos et les envoyer, ainsi que pour scanner des QR codes. Delta Chat a besoin de votre autorisation pour partager votre position pour la durée d\'activation du partage de position. @@ -1163,11 +1181,13 @@ Utiliser une connexion en arrière plan Requiert la désactivation des optimisations de battterie, utilisez cette option si les notifications sont en retard. Forcer une connexion en arrière plan + Entraîne une notification permanente. + Pour maintenir une connexion à votre serveur de courriel et recevoir les messages en arrière-plan, ignorez l\'optimisation de la batterie à l\'étape suivante.\n\nDelta Chat utilise peu de ressources et prend garde à ne pas vider votre batterie. Touchez ici pour recevoir des messages pendant que DeltaChat est en arrière-plan. Vous avez déjà autorisé Delta Chat à recevoir des messages en arrière plan.\n\nSi vous ne les recevez toujours pas en arrière plan, vérifiez les paramètres de votre système. - Quoi de neuf?\n\n💯 Le chiffrement de bout-en-bout est maintenant fiable et péreint. 🔒Fini les cadenas !\n\n✉️ Les mails sans chiffrement de bout-en-bout sont maintenant marqués par une icône de mail \n\n😻 Nouvelle fenêtre de profil améliorée pour tous les contactsn\n🔲 Un nouveau button pour l\'accès rapide aux applis utilisés dans une discussion\n\n❤️ Merci de considérer à faire une donation afin que nous restions indépendents et continuons à améliorer Delta Chat: %1$s + Quoi de neuf?\n\n💯 Le chiffrement de bout-en-bout est maintenant fiable et pérenne. 🔒Fini les cadenas !\n\n✉️ Les mails sans chiffrement de bout-en-bout sont maintenant marqués par une icône de mail \n\n😻 Nouvelle fenêtre de profil améliorée pour tous les contacts \n\n🔲 Nouveau bouton pour l\'accès rapide aux applis utilisées dans une discussion\n\n❤️ Merci d\'envisager de faire une donation afin que nous restions indépendants et continuions à améliorer Delta Chat: %1$s diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml index efe839553..dfbf7f009 100644 --- a/src/main/res/values-it/strings.xml +++ b/src/main/res/values-it/strings.xml @@ -1019,6 +1019,7 @@ %1$s ha risposto, in attesa di essere aggiunto al gruppo… Impostazione della crittografia end-to-end, attendere... %1$s introdotto. + Hai bloccato il contatto Introdotto da %1$s Introdotto da me diff --git a/src/main/res/values-lt/strings.xml b/src/main/res/values-lt/strings.xml index b3f2cdcf2..d47146b3b 100644 --- a/src/main/res/values-lt/strings.xml +++ b/src/main/res/values-lt/strings.xml @@ -5,6 +5,10 @@ Gerai Atsisakyti Išvalyti paiešką + + Nuoroda + + Skenuoti Taip Ne Įjungta @@ -47,6 +51,7 @@ Šie nustatymai taikomi visiems Delta Chat besinaudojantiems dalyviams. Vis dėlto, jie gali kopijuoti, įrašyti ir persiųsti žinutes arba naudoti kitas el. pašto kliento programas. Įrašyti Medija + Programėlės ir medija Profilis Visi profiliai Dabartinis profilis @@ -83,7 +88,7 @@ El. pašto adresas Blogas el. pašto adresas. Slaptažodis - Esamas slaptažodis + Dabartinis slaptažodis Dabar Dėmesio @@ -176,7 +181,7 @@ Privati programėlė - Privačios programėlės + Programėlės Žaidimai Dydis @@ -207,8 +212,11 @@ Pridėti adresatą rankiniu būdu Naujas pokalbis Nauja grupė + Dubliuoti pokalbį Pridėti gavėjus + + Naujas el. laiškas Tema Siųsti @@ -227,6 +235,7 @@ Ištrinti šią vietą? Išsamesnė žinutės informacija Kopijuoti į iškarpinę + Kiekvienas, turintis šią nuorodą, gali peržiūrėti jūsų profilį ar pradėti su jumis pokalbį. Bendrinkite ją tik su žmonėmis, kuriais pasitikite. Kopijuoti žymėjimą Kopijuoti nuorodą Kopijuoti tekstą @@ -241,6 +250,7 @@ Eksportuoti priedą Eksportuoti priedus Visa medija + Visos programėlės ir medija Rodyti pokalbyje Bendrinti @@ -255,7 +265,7 @@ Slinkti į viršų Žinynas - Kas yra „Webxdc“? + Apie programėles Privatumo politika Žymėti viską Taisyti vardą @@ -360,6 +370,7 @@ Bendrinti su Žinutė Archyvuotas + Užklausa Žinučių nėra. Žinutės, kurias siunčiu asmeniškai sau Jei archyvuosite pokalbius, jie bus rodomi čia. @@ -406,7 +417,6 @@ Čia bus rodomi šiame pokalbyje bendrinti paveikslai. Čia bus rodomi šiame pokalbyje bendrinti vaizdo įrašai. Čia bus rodomi šiame pokalbyje bendrinti garso įrašų failai ir balso žinutės. - Čia bus rodomos šiame pokalbyje bendrintos privačios programėlės. Čia bus rodoma bet kuriame pokalbyje bendrinama medija. Medijos peržiūra Siųsti žinutę @@ -415,8 +425,15 @@ Pridėti antrąjį įrenginį Įsitikinkite, kad abu įrenginiai yra prisijungę prie to pačio belaidžio (Wi-Fi) arba laidinio tinklo + Tai sukuria QR kodą, kurį antrasis įrenginys gali nuskenuoti, kad nukopijuotų profilį.\n\nĮsitikinkite, kad joks pašalinis stebėtojas ar kamera nematys lango, kuris bus parodytas paspaudus mygtuką. + Įsidiekite Delta Chat kitame savo įrenginyje (https://get.delta.chat) + + Paleiskite Delta Chat, bakstelėkite „Aš jau turiu profilį / Pridėti kaip antrąjį įrenginį“ ir nuskenuokite čia rodomą kodą + + Nuskenuokite norėdami nustatyti antrąjį įrenginį, skirtą %1$s Pridėti kaip antrąjį įrenginį Pirmajame įrenginyje pereikite į „Nustatymai / Pridėti antrąjį įrenginį“ ir nuskenuokite ten rodomą kodą + Nutraukti antrojo įrenginio nustatymą? Ruošiama paskyra… Nesklandumų šalinimas @@ -426,6 +443,8 @@ Gaunamosios žinutės Siunčiamosios žinutės + + Saugykla ties %1$s Jungiamumas Neprisijungta @@ -437,6 +456,7 @@ Prisijungta Siunčiama… Paskutinė žinutė sėkmingai išsiųsta. + Jūsų teikėjas nepalaiko šios ypatybės. Žinutės @@ -444,14 +464,21 @@ Sukurti naują profilį Aš jau turiu profilį + + Naudoti klasikinį el. paštą kaip retransliavimą Jūsų profilis %1$s privatumo politika + + Sutinku ir sukurti profilį Naudoti kitą serverį + Išvardyti retransliavimo serverius + Saugūs decentralizuoti pokalbiai Skenuoti pakvietimo kodą Prisijungti + Šis prisijungimas skirtas patyrusiems naudotojams:\n\n• Nenaudokite adreso, kurį naudojate kitoje programoje.\n\n• Klasikinis el. pašto serveris leidžia pokalbius be ištisinio šifravimo, pažymėtus voko piktograma. Gauta IMAP prisijungimo vardas IMAP serveris @@ -468,10 +495,13 @@ Naudoti įgaliotąjį serverį Pridėti įgaliotąjį serverį Palaikomi įgaliotųjų serverių tipai: HTTP(S), SOCKS5 ir Shadowsocks. + Įveskite čia įgaliotojo serverio nuorodą Įrašyti įgaliotieji serveriai Ištrinti įgaliotąjį serverį Ar tikrai norite ištrinti „%1$s“? Ar norite naudoti įgaliotąjį serverį „%1$s“? + + Retransliavimai Liudijimų patikrinimai Įveskite teisingą el. pašto adresą. Įveskite teisingą serverį / IP adresą @@ -523,6 +553,8 @@ Prašyti blokuoti ekrano kopijas paskiausiųjų sąraše ir programėlės viduje Norėdami pritaikyti ekrano saugumo nustatymą, paleiskite programėlę iš naujo. Pranešimai + Paminėjimai + Grupėse, kuriose išjungti pranešimai, pranešti apie jums adresuotas žinutes, tokias kaip atsakymai ar reakcijos Rodyti Pirmenybė Įjungti sistemos pranešimus apie naujas žinutes @@ -558,7 +590,8 @@ Kita Atsarginė kopija Padaro atsarginę pokalbių kopiją į išorinę saugyklą - Atsarginė kopija padeda jums nusistatyti naują diegimą šiame ar kitame įrenginyje.\n\nAtsarginėje kopijoje bus visos žinutės, adresatai ir pokalbiai bei jūsų ištisinė Autocrypt sąranka. Atsarginės kopijos failą laikykite saugioje vietoje arba kaip įmanoma greičiau jį ištrinkite. + Atsarginė kopija padeda jums nusistatyti naują diegimą šiame ar kitame įrenginyje.\n\nAtsarginėje kopijoje bus visos žinutės, adresatai ir pokalbiai bei jūsų ištisinio perdavimo „Autocrypt“ sąranka. Atsarginės kopijos failą laikykite saugioje vietoje arba kaip įmanoma greičiau jį ištrinkite. + Eksportuoti šį profilį Eksportuoti visas %1$d paskyras Pradėti daryti atsarginę kopiją @@ -568,6 +601,8 @@ Naudoti numatytąjį paveikslą Pasirinkti iš galerijos Jeigu išjungiate šį parametrą, įsitikinkite, kad jūsų serveris ir kiti klientai yra sukonfigūruoti atitinkamai.\n\nPriešingu atveju, tai gali iš viso neveikti. + + Kelių įrenginių veiksena Automatiniai perkėlimai į DeltaChat aplanką Rodyti klasikinius el. laiškus Ne, tik pokalbius @@ -579,7 +614,7 @@ Tinkintas paveikslas Tinkinta spalva Eksportavimas nutrauktas. - Automatinis žinučių atsisiuntimas + Automatinis žinučių atsiuntimas Iki %1$s Iki %1$s, iš esmės, blogos kokybės paveikslus @@ -587,7 +622,9 @@ Atsiuntimas nepavyko %1$s žinutė - Ištrinti profilio paveikslą + Pasirinkti profilio nuotrauką + Pasirinkite naują profilio nuotrauką + Ištrinti profilio nuotrauką Rodyti dėklo piktogramą Taisyti profilį Siųsti statistiką Delta Chat plėtotojams @@ -671,6 +708,9 @@ Jūs nustatėte išnykstančių žinučių laikmatį į %1$s sav. %2$s nustatė išnykstančių žinučių laikmatį į %1$s sav. + Žinutės šiame pokalbyje naudoja klasikinius el. laiškus ir nėra šifruotos ištisinio perdavimo būdu. + Žinutės yra šifruotos ištisinio perdavimo būdu. Bakstelėkite norėdami sužinoti daugiau. + Visos žinutės šiame pokalbyje yra šifruotos ištisinio perdavimo būdu.\n\nIštisinis šifravimas išlaiko žinutes tarp jūsų ir jūsų pokalbio partnerių privačias. Netgi serveriai, teikėjai ar retransliavimai negali jų perskaityti. Sužinoti daugiau @@ -698,9 +738,10 @@ Nuskenuokite tai, norėdami prisijungti prie \"%1$s\" grupės. QR pakvietimo kodas - Nuskenuokite tai, norėdami užmegzti kontaktą su %1$s + Nuskenuokite norėdami pradėti pokalbį su %1$s Nėra interneto ryšio, nepavyksta atlikti QR kodo sąrankos. Sukurti naują el. pašto adresą ties „%1$s“ ir prisijungti ten? + Nusistatykite vardą, kurį jūsų adresatai atpažins. Taip pat galite nusistatyti profilio nuotrauką. Įrašykite vardą. Nuskenuotas QR kodas negali būti naudojamas naujos paskyros nustatymui. @@ -797,6 +838,7 @@ Delta Chat naudoja mikrofoną, kad įrašytų ir siųstų balso žinutes bei vaizdo įrašus su garsu. Delta Chat leis jums pasirinkti, kurias nuotraukas iš savo kolekcijos išsiųsti. Delta Chat nori įrašyti paveikslus į jūsų nuotraukų kolekciją. + Naudoti foninį ryšį Norėdami palaikyti ryšį su savo el. pašto serveriu ir gauti žinutes fone, kitame žingsnyje nepaisykite akumuliatoriaus optimizavimų (leiskite vykdyti programą fone).\n\nDelta Chat naudoja nedaug išteklių ir rūpinasi, kad neeikvotų jūsų akumuliatoriaus energijos. Bakstelėkite čia, norėdami gauti žinutes, kol Delta Chat veikia fone. diff --git a/src/main/res/values-nl/strings.xml b/src/main/res/values-nl/strings.xml index c472438c7..de791caa0 100644 --- a/src/main/res/values-nl/strings.xml +++ b/src/main/res/values-nl/strings.xml @@ -1088,8 +1088,8 @@ Naam Kies een groepsafbeelding Reservekopie exporteren - verstuurd - ontvangen + Verstuurd + Ontvangen Map met logbestanden openen Huidig logbestand openen Het systeemvakpictogram is uitgeschakeld omdat Delta Chat is gestart met de optie --minimized diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml index 9496acdf7..4664c6989 100644 --- a/src/main/res/values-pl/strings.xml +++ b/src/main/res/values-pl/strings.xml @@ -1036,6 +1036,7 @@ Użytkownik %1$s odpowiedział, czekając na dodanie do grupy… Ustanawiam połączenie, proszę czekać… Kontakt %1$s zweryfikowany. + Zablokowano kontakt Kontakt zweryfikowany przez %1$s Kontakt zweryfikowany przez ciebie @@ -1121,8 +1122,8 @@ Nazwa Wybierz obraz grupy Eksport kopii zapasowej - wysłane - odebrane + Wysłana + Odebrana Otwórz folder dziennika Otwórz bieżący plik dziennika Ikona w zasobniku nie może być wyłączona, ponieważ Delta Chat został uruchomiony z opcją --minimized. diff --git a/src/main/res/values-sv/strings.xml b/src/main/res/values-sv/strings.xml index bb3bd4e8a..206057aab 100644 --- a/src/main/res/values-sv/strings.xml +++ b/src/main/res/values-sv/strings.xml @@ -5,6 +5,10 @@ OK Avbryt Rensa sök + + Länk + + Skanna Ja Nej Välj @@ -24,29 +28,40 @@ Anslut Återanslut Ta bort + Ta bort för mig + Ta bort för alla Info Uppdatera Emoji Bilaga + + Vill du bifoga \"%1$s\"? Tillbaka Stäng Stäng fönster Vidarebefordra Skapa + Återställ Senare Skicka igen + Redigerad + Redigera meddelande Arkivera Avarkivera Tyst + Tystad Försvinnande meddelanden Dessa inställningar tillämpas för alla deltagare som använder Delta Chat. De kan dock kopiera, spara och vidarebefordra meddelanden eller använda andra e-postklienter. Spara Chatt Media + Appar & Media Profil + Alla profiler + Aktuell profil Huvudmeny Starta chatt Visa hela meddelandet... @@ -79,6 +94,8 @@ Kan inte hitta någon app som hanterar denna typ av data. Ingen webbläsare installerad. Kunde inte hitta %1$s. + + Kan inte spara %1$s. Kopierad till urklipp. Kontakter E-postadress @@ -99,6 +116,16 @@ Sågs senast %1$s Sågs senast: Okänt + + + %d sekund + %d sekunder + + + + %d minut + %d minuter + %d min @@ -122,6 +149,10 @@ %d meddelande %d meddelanden + + %d reaktion + %d reaktioner + %d medlem %d medlemmar @@ -135,6 +166,7 @@ %dmarkerade %d markerad + Markerat: Jag Utkast Bild @@ -168,10 +200,25 @@ Bilder och videor Arkiv Filer + Skicka originalfiler och okomprimerade bilder + + Välj från Filer + Välj från Galleri App Appar + URL till appväljare + Om angivet, kommer URL:en att användas som appväljare istället för standardväljare + Tryck \"Skicka\" för att dela + Hem + Spel + Verktyg + Storlek + Publicerad + Lägg till i chatten + + Bläddra Okänd Grön @@ -199,9 +246,24 @@ Manuellt tillagda kontakter kan användas för att sms:a till klassisk e-post och är inte garanterat totalsträckskrypterat. Ny chatt Ny grupp + + Chatta med... Klona chatt + + Kanal + + Kanaler + + Ny kanal Lägg till mottagare + + Kanalnamn + E-post + + Ny e-post + + Ämne Skicka Byt emoji-tangentbord Redigera grupp @@ -211,6 +273,7 @@ Avarkivera chatt Lägg till bilaga Lämna grupp + Lämna kanalen Ta bort chatt Rensa chatt @@ -219,6 +282,7 @@ Meddelandedetaljer Kopiera till urklipp Dela inbjudningslänk + Vem som helst med den här länken kan se din profil och börja chatta med dig. Dela den bara med personer som du litar på. Bjud in vänner Kontakta mig på Delta Chat:\n%1$s @@ -236,6 +300,7 @@ Exportera bilaga Exportera bilaga All media + Alla appar & media Visa i chatten Visa app i chatt @@ -257,6 +322,10 @@ Välj chatt Välj flera Redigera namn + + Ange ett chattnamn som kommer att visas för dig istället för \"%1$s\". Lämnas tomt om du vill använda kontaktens valda namn. + + Chattnamn för \"%1$s\" Inställningar Avancerat Visa profil @@ -266,6 +335,7 @@ Mer alternativ Lär stavning Hoppa till meddelande + Hoppa till ursprungligt meddelande Kopiera JSON Ersätt utkast Dela plats med alla gruppmedlemmar @@ -288,6 +358,8 @@ Lägg till på hemskärmen Donera + ❤️ Det verkar som att du gillar Delta Chat!\n\nVänligen överväg att donera för att hjälpa till att säkerställa att Delta Chat förblir gratis för alla.\n\nÄven om Delta Chat är gratis att använda och öppen källkod, kostar utvecklingen pengar. Hjälp oss att hålla Delta Chat oberoende och göra det ännu bättre i framtiden.\n\nhttps://delta.chat/donate + Tysta 1 timma Tysta 8 timmar Tysta 1 dag @@ -306,6 +378,29 @@ Filen är sparad i \"%1$s\". + + Ring upp + + Svara + + Avböj + Utgående samtal + Inkommande samtal + Nekade samtal + Avbrutna samtal + Missade samtal + + %1$s, %2$s + + + + Vill du verkligen lämna? + + Vill du ta bort %d chatt? + Vill du ta bort %d chattar? + + Vill du ta bort chatten\"%1$s\"? + Vill du ta bort detta meddelande? Vill du ta bort %d meddelande? Vill du ta bort %d meddelanden? @@ -320,6 +415,8 @@ Chatta med %1$s ? Ta bort %1$s från gruppen? + + Vill du ta bort %1$s från kanalen? Vill du öppna denna länk? @@ -347,6 +444,8 @@ Skicka ett meddelande till %1$s. + + Kanaler är ett en-till-många-verktyg för att skicka ut dina meddelanden. Komponera det första meddelandet, så att andra kan svara inom denna grupp.\n\n• Det är okej om inte alla medlemmar använder Delta Chat.\n\n• Det kan ta en stund innan det första meddelandet levereras. Svep för att avbryta Tryck och håll ner för att spela in ett röstmeddelande, släpp för att skicka. @@ -356,6 +455,7 @@ Meddelande Arkiverat Efterfråga + Inkludera förfrågningar i räknare och meddelanden Inga meddelanden. Meddelanden jag skickat till mig själv Arkiverde chattar kommer att visas här. @@ -384,6 +484,9 @@ Skicka \"%1$s\" till... Skicka meddelande till... + Realtidsappar + Aktivera realtidsanslutningar för appar som är kopplade till chattar. Om detta är aktiverat kan chattpartners kanske få reda på din IP-adress när du startar en app. + Visa platser inom tidsramen Visa spår @@ -406,6 +509,10 @@ Sök filer Sök efter chattar, kontakter och meddelanden Inga resultat hittades för \" %s \" + + Olästa + + Gruppnamn Gruppbild @@ -417,6 +524,8 @@ Du måste vara medlem i gruppen för att utföra denna åtgärd. Kryptering Delade chattar + + Tidigare medlemmar Kontakt Grupp Galleri @@ -430,6 +539,7 @@ Ljudfiler och röstmeddelanden delade i denna chatt kommer att visas här. Appar delade i denna chatt kommer att visas här. Media delad i någon chatt kommer att visas här. + Dokument och andra filer som bifogas en chatt visas här. Appar som tas emot eller skickas i en chatt visas här. Förhandsvisning av media @@ -451,6 +561,7 @@ Lägg till som andra enhet På den första enheten går du till \"Inställningar / Lägg till en andra enhet\" och skannar koden som visas där Vill du kopiera profilen från den andra enheten till den här enheten? + Profilen du vill importera är från en nyare version av Delta Chat. \n\nFör att fortsätta konfigurera den andra enheten måste du uppdatera den här enheten till den senaste versionen av Delta Chat. Vill du avbryta konfigurationen av den andra enheten? Detta kommer att ogiltigförklara QR-koden som kopierats till urklipp. ℹ️ Profilen överförd till din andra enhet. @@ -515,6 +626,7 @@ Säker decentraliserad chatt Skanna inbjudningskod Logga in + Denna inloggning är för avancerade användare:\n\n- Använd inte en adress som du använder i en annan app.\n\n- Klassisk e-postserver tillåter chattar utan totalsträckskryptering, markerad med en e-postikon. Inkorg IMAP inloggningsnamn IMAP server @@ -526,6 +638,18 @@ SMTP server SMTP port SMTP säkerhet + + Proxy + Använd proxy + Lägg till proxy + Proxytyper som stöds: HTTP(S), SOCKS5 och Shadowsocks. + Ange proxylänk här + Ogiltig proxy eller stöd saknas + Sparade proxyer + Ta bort proxy + Vill du verkligen ta bort \"%1$s\"? + Vill du använda proxyn \"%1$s\"? + Dina vänner kan lägga till denna proxy genom att skanna QR-koden. Certifikatkontroller Ange en giltig e-postadress Ange en giltig server/IP-adress diff --git a/src/main/res/values-uk/strings.xml b/src/main/res/values-uk/strings.xml index ee7c73a0d..e2a7ef4e5 100644 --- a/src/main/res/values-uk/strings.xml +++ b/src/main/res/values-uk/strings.xml @@ -420,18 +420,18 @@ Ви впевнені, що хочете піти? - ¿Видалити %d чат на всіх Ваших пристроях? - ¿Видалити %d чати на всіх Ваших пристроях? - ¿Видалити %d чатів на всіх Ваших пристроях? - ¿Видалити %d чатів на всіх Ваших пристроях? + Видалити %d чат? + Видалити %d чати? + Видалити %d чатів? + Видалити %d чатів? Видалити чат \"%1$s\" на всіх ваших пристроях? - Видалити повідомлення на всіх ваших пристроях? + Видалити це повідомлення? - ¿Видалити %d повідомлення на всіх Ваших пристроях? - ¿Видалити %d повідомлення на всіх Ваших пристроях? - ¿Видалити %d повідомлень на всіх Ваших пристроях? - ¿Видалити %d повідомлень на всіх Ваших пристроях? + Видалити %d повідомлення? + Видалити %d повідомлення? + Видалити %d повідомлень? + Видалити %d повідомлень? Переслати повідомлення %1$s? Переслати повідомлення в %1$d? @@ -439,7 +439,7 @@ Заблокувати цей контакт?\n\nПрямі повідомлення або групи, створені заблокованими контактами, не відображатимуться.\n\nІнші групи із заблокованими контактами все одно показуватимуть свої повідомлення. Розблокувати цей контакт? Видалити контакти?\n\nКонтакти з поточними чатами неможливо видалити остаточно. - Видалити %1$s?\n\nКонтакти з поточними чатами не можна видалити назавжди. + Видалити контакт %1$s?\n\nКонтакти з поточними чатами не можна видалити назавжди. Створити чат з %1$s? Видалити %1$s із групи? @@ -593,7 +593,7 @@ Скануйте, щоб налаштувати другий пристрій %1$s Додати як другий пристрій - На першому пристрої перейдіть до «Налаштування / Додати другий пристрій» і відскануйте показаний там код + На першому пристрої запустіть Delta Chat, перейдіть до «Налаштування / Додати другий пристрій» і відскануйте зображений код Скопіювати профіль з іншого пристрою на цей? Профіль, який ви хочете імпортувати, належить до новішої версії Delta Chat.\n\nЩоб продовжити налаштування другого пристрою, будь ласка, оновіть його до останньої версії Delta Chat. Скасувати налаштування другого пристрою? @@ -636,7 +636,7 @@ У мене вже є профіль - Транспорт через класичну електронну пошту + Використовувати класичну пошту як транспортний сервер Ваш профіль @@ -686,7 +686,7 @@ Ваші друзі можуть додати цей проксі, відсканувавши QR-код. Поділитися посиланням Проксі увімкнено - Ви використовуєте проксі-сервер. Якщо у вас проблеми з підключенням, спробуйте інший проксі. + Ви використовуєте проксі-сервер. Якщо у вас проблеми зі зʼєднанням, спробуйте інший проксі. Транспортні сервери Додати транспортний сервер @@ -705,7 +705,7 @@ Вкажіть дійсну адресу електронної пошти та пароль Відновити з резервної копії Знайдена резервна копія \"%1$s\".\n\nВідновити з неї всі дані й параметри? - Резервних копій не знайдено.\n\nПомістіть резервну копію в папку \"%1$s\" та спробуйте знову запустити відновлення. + Жодної резервної копії не знайдено. \n\nПомістіть резервну копію в теку \"%1$s\" та спробуйте знову. Не вдалося увійти як \"%1$s\". Будь ласка, перевірте правильність адреси електронної пошти та паролю. @@ -812,7 +812,7 @@ Якщо ви змінюєте цей параметр, переконайтеся, що Ваш сервер та інші Ваші клієнти налаштовані відповідним чином.\n\nІнакше щось може взагалі не працювати. Режим роботи з декількома пристроями - Синхронізуйте свій повідомлення з іншими пристроями. Автоматично вмикається після додавання другого пристрою + Синхронізуйте свої повідомлення з іншими пристроями. Автоматично вмикається після додавання іншими пристроями Режим декількох пристроїв має бути увімкнений, якщо ви використовуєте один і той самий профіль на декількох пристроях. Вимикайте цей параметр, лише якщо ви видалили цей профіль з усіх інших пристроїв.\n\nВимкнення режиму декількох пристроїв під час використання профілю на декількох пристроях призведе до пропусків повідомлення та інших проблем. Автоматично пересувати до папки DeltaChat Збирати лише з теки DeltaChat. @@ -847,7 +847,13 @@ Вимкнути IMAP IDLE Не використовувати розширення IMAP IDLE навіть якщо сервер підтримує його. Увімкнення цієї опції затримає отримання повідомлень, вмикайте її лише для тестування. Надсилати статистику розробникам Delta Chat - У вкладенні міститься анонімна статистика використання, яка допоможе нам покращити Delta Chat. Дякуємо! + Хочете допомогти покращити Delta Chat та підтримати дослідження, надсилаючи щотижневу анонімну статистику використання?\n\n 👉 Тисніть сюди… 👈 + Хочете допомогти покращити Delta Chat та підтримати дослідження, надсилаючи щотижневу анонімну статистику використання? + Дякуємо! Ви завжди маєте змогу це вимкнути у розділі \"Налаштування > Додатково\"\n\n Чи маєте Ви 5 хвилин для участі в науковому дослідженні стосовно безпеки Delta Chat? + Надсилання статистики вже активне.\n\n Ви хочете її припинити? + Припинити + Продовжити + У вкладенні міститься анонімна статистика використання, яка допомагає нам покращити Delta Chat. Дивіться https://delta.чат/help#statssending для отримання додаткової інформації. Дякуємо! Результати пошуку @@ -878,7 +884,7 @@ Ви хочете видалити %1$d повідомлень зараз і всі нові повідомлення \"%2$s\" у майбутньому?\n\n- Це включає всі медіа\n\n- Повідомлення буде видалено незалежно від того, чи були вони переглянуті чи ні\n\n- \"Збережені повідомлення\" буде пропущено при локальному видаленні - Ви хочете видалити %1$d повідмолень зараз і всі нові повідомлення \"%2$s\" в майбутньому?\n\n⚠️ Сюди входять електронні листи, медіа та \"Збережені повідомлення\" у всіх папках сервера\n\n⚠️ Не використовуйте цю функцію, якщо ви хочете зберегти дані на сервері або якщо ви також використовуєте класичні поштові клієнти + Ви хочете видалити %1$d повідмолень зараз і всі нові повідомлення \"%2$s\" в майбутньому?\n\n⚠️ Сюди входять електронні листи, медіа та \"Збережені повідомлення\" у всіх теках сервера\n\n⚠️ Не використовуйте цю функцію, якщо ви хочете зберегти дані на сервері або якщо ви також використовуєте класичні поштові клієнти Сюди входять електронні листи, медіафайли та \"Збережені повідомлення\" у всіх папках сервера. Не використовуйте цю функцію, якщо ви хочете зберігати дані на сервері або якщо ви використовуєте класичні поштові клієнти Увімкнути одномоментне видалення @@ -976,7 +982,7 @@ Ви видалили чат \"Збережені повідомлення\".\n\nℹ️ Аби використовувати функцію \"Збережені повідомлення\" знову, створіть новий чат самі із собою. - ⚠️ Сховище вашого провайдера електронної пошти майже заповнено, уже використовується %1$s%%.\n\nМожливо, Ви не зможете отримувати повідомлення, коли сховище буде заповнене.\n\n👉 Перевірте, чи можна видалити старі дані у веб-інтерфейсі провайдера та ввімкніть \"Налаштування / Видалити старі повідомлення\". Ви можете будь-коли перевірити своє поточне використання сховища в \"Налаштування / Підключення\". + ⚠️ Сховище вашого провайдера електронної пошти майже заповнено, уже використовується %1$s%%.\n\nМожливо, Ви не зможете отримувати повідомлення, коли сховище буде заповнене.\n\n👉 Перевірте, чи можна видалити старі дані у веб-інтерфейсі провайдера та ввімкніть \"Налаштування / Видалити старі повідомлення\". Ви можете будь-коли перевірити своє поточне використання сховища в \"Налаштування / Зʼєднання\". ⚠️ Дата й час на вашому пристрої видаються неточними (%1$s).\n\nНалаштуйте свій годинник ⏰🔧 для правильного отримання повідомлень. ⚠️ Ваша версія Delta Chat може бути застарілою.\n\nЦе може спричинити проблеми, оскільки Ваші співрозмовники в чаті використовують новіші версії, а Вам не вистачає найновіших функцій 😳 \nПеревірте оновлення на https://get.delta.chat або в магазині додатків. @@ -1030,6 +1036,7 @@ %1$s відповіли, очікуємо на додавання до групи… Встановлення гарантованого наскрізного шифрування, будь ласка, зачекайте... %1$s представлено! + Ви заблокували контакт Представни·ця: %1$s Представлено мною @@ -1051,7 +1058,7 @@ Тільки ім\'я Без імені або повідомлення Сповіщення вимкнено - Увімкніть \"Примусове фонове підключення\" для надійних сповіщень + Увімкніть \"Примусове фонове зʼєднання\" для надійних сповіщень Нові повідомлення У вас нові повідомлення @@ -1115,8 +1122,8 @@ Імʼя Вибрати емблему групи Експорт резервної копії - надіслано - отримано + Надіслано + Отримано Відкрити папку журналів Відкрити поточний файл журналу Іконку в треї не можна вимкнути, оскільки Delta Chat було запущено за допомогою параметра --minimized. From a31d7d6d3e34f7e3d22c37b8269b2ecf7ad1a528 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Wed, 4 Feb 2026 23:39:04 +0100 Subject: [PATCH 21/29] update the RPC bindings --- src/main/java/chat/delta/rpc/Rpc.java | 4 ++-- src/main/java/chat/delta/rpc/types/CallInfo.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/chat/delta/rpc/Rpc.java b/src/main/java/chat/delta/rpc/Rpc.java index 4cccc26ce..ee42f8652 100644 --- a/src/main/java/chat/delta/rpc/Rpc.java +++ b/src/main/java/chat/delta/rpc/Rpc.java @@ -1315,8 +1315,8 @@ public class Rpc { } /** Starts an outgoing call. */ - public Integer placeOutgoingCall(Integer accountId, Integer chatId, String placeCallInfo) throws RpcException { - return transport.callForResult(new TypeReference(){}, "place_outgoing_call", mapper.valueToTree(accountId), mapper.valueToTree(chatId), mapper.valueToTree(placeCallInfo)); + public Integer placeOutgoingCall(Integer accountId, Integer chatId, String placeCallInfo, Boolean hasVideo) throws RpcException { + return transport.callForResult(new TypeReference(){}, "place_outgoing_call", mapper.valueToTree(accountId), mapper.valueToTree(chatId), mapper.valueToTree(placeCallInfo), mapper.valueToTree(hasVideo)); } /** Accepts an incoming call. */ diff --git a/src/main/java/chat/delta/rpc/types/CallInfo.java b/src/main/java/chat/delta/rpc/types/CallInfo.java index 124a75dfb..6693a03f7 100644 --- a/src/main/java/chat/delta/rpc/types/CallInfo.java +++ b/src/main/java/chat/delta/rpc/types/CallInfo.java @@ -2,7 +2,7 @@ package chat.delta.rpc.types; public class CallInfo { - /** True if SDP offer has a video. */ + /** True if the call is started as a video call. */ public Boolean hasVideo; /** * SDP offer. From 4ec49a031c2245e692ab156ef208c62375e1d0d8 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Thu, 5 Feb 2026 00:24:51 +0100 Subject: [PATCH 22/29] adapt to new Rpc.placeOutgoingCall API --- .../java/org/thoughtcrime/securesms/calls/CallActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/thoughtcrime/securesms/calls/CallActivity.java b/src/main/java/org/thoughtcrime/securesms/calls/CallActivity.java index d20eb88a7..0b9595921 100644 --- a/src/main/java/org/thoughtcrime/securesms/calls/CallActivity.java +++ b/src/main/java/org/thoughtcrime/securesms/calls/CallActivity.java @@ -168,7 +168,7 @@ public class CallActivity extends WebViewActivity implements DcEventCenter.DcEve @JavascriptInterface public void startCall(String payload) { try { - callId = rpc.placeOutgoingCall(accId, chatId, payload); + callId = rpc.placeOutgoingCall(accId, chatId, payload, true); } catch (RpcException e) { Log.e(TAG, "Error", e); } From 3ac49e3e5896916ff9ed20736ccccc3a17f9b246 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Thu, 5 Feb 2026 01:20:11 +0100 Subject: [PATCH 23/29] set the call mode when calling Rpc.placeOutgoingCall --- .../java/org/thoughtcrime/securesms/calls/CallActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/thoughtcrime/securesms/calls/CallActivity.java b/src/main/java/org/thoughtcrime/securesms/calls/CallActivity.java index 713b6c001..58e2caa29 100644 --- a/src/main/java/org/thoughtcrime/securesms/calls/CallActivity.java +++ b/src/main/java/org/thoughtcrime/securesms/calls/CallActivity.java @@ -172,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, !audioOnly); } catch (RpcException e) { Log.e(TAG, "Error", e); } From f470e92300da350770863a418767147503235d66 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Thu, 5 Feb 2026 01:35:20 +0100 Subject: [PATCH 24/29] show different icon depending on voice/video call modes --- src/main/java/org/thoughtcrime/securesms/ConversationItem.java | 2 +- src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java | 3 ++- .../org/thoughtcrime/securesms/components/CallItemView.java | 2 ++ src/main/res/layout/call_item_view.xml | 1 - 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationItem.java b/src/main/java/org/thoughtcrime/securesms/ConversationItem.java index 821ade706..ccdcdacf4 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationItem.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationItem.java @@ -996,7 +996,7 @@ 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, !callInfo.hasVideo); } diff --git a/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java b/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java index 0e2b79875..c78ef385e 100644 --- a/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java +++ b/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java @@ -40,7 +40,7 @@ public class CallUtil { 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 audioOnly) { String base64 = Base64.encodeToString(payload.getBytes(StandardCharsets.UTF_8), Base64.NO_WRAP); String hash = ""; try { @@ -54,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_AUDIO_ONLY, audioOnly); 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/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" /> From 8999f54ba27cf0a14cd2c0f749595c33169a94a5 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Thu, 5 Feb 2026 01:40:27 +0100 Subject: [PATCH 25/29] upgrade calls web app --- src/main/assets/calls/index.html | 64 +++----------------------------- 1 file changed, 5 insertions(+), 59 deletions(-) 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 @@ - + - - - - + +
From fc69212a51252658b0c523dd5ff1013de1af11b8 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Thu, 5 Feb 2026 01:41:29 +0100 Subject: [PATCH 26/29] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67033b4a2..bd61bf594 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 From 3847e20d187e0665915e4424f0a7833acdd98b8e Mon Sep 17 00:00:00 2001 From: adbenitez Date: Thu, 5 Feb 2026 02:31:38 +0100 Subject: [PATCH 27/29] set tint for icons in the call submenu --- src/main/res/menu/conversation.xml | 2 ++ src/main/res/values/attrs.xml | 1 + src/main/res/values/themes.xml | 2 ++ 3 files changed, 5 insertions(+) diff --git a/src/main/res/menu/conversation.xml b/src/main/res/menu/conversation.xml index 678d48f3d..879e60b2e 100644 --- a/src/main/res/menu/conversation.xml +++ b/src/main/res/menu/conversation.xml @@ -33,10 +33,12 @@ diff --git a/src/main/res/values/attrs.xml b/src/main/res/values/attrs.xml index 706be4654..dcc89a380 100644 --- a/src/main/res/values/attrs.xml +++ b/src/main/res/values/attrs.xml @@ -79,6 +79,7 @@ + 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 From 006f8ae826aabacec04fd161e04ba7247badc3b6 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Thu, 5 Feb 2026 16:37:42 +0100 Subject: [PATCH 28/29] use hasVideo instead of audioOnly --- .../securesms/ConversationActivity.java | 4 ++-- .../thoughtcrime/securesms/ConversationItem.java | 4 ++-- .../thoughtcrime/securesms/calls/CallActivity.java | 10 +++++----- .../org/thoughtcrime/securesms/calls/CallUtil.java | 12 ++++++------ .../notifications/NotificationCenter.java | 14 +++++++------- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java b/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java index d481dd062..0bf5acc9a 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java @@ -567,10 +567,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity WebxdcActivity.openMaps(this, chatId); return true; } else if (itemId == R.id.menu_start_audio_call) { - CallUtil.startCall(this, chatId, true); + CallUtil.startCall(this, chatId, false); return true; } else if (itemId == R.id.menu_start_video_call) { - CallUtil.startCall(this, chatId, false); + 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 ccdcdacf4..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, !callInfo.hasVideo); + CallUtil.openCall(getContext(), accId, chatId, callId, callInfo.sdpOffer, callInfo.hasVideo); } else { - CallUtil.startCall(getContext(), accId, chatId, !callInfo.hasVideo); + 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 58e2caa29..b7da6e461 100644 --- a/src/main/java/org/thoughtcrime/securesms/calls/CallActivity.java +++ b/src/main/java/org/thoughtcrime/securesms/calls/CallActivity.java @@ -43,14 +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_AUDIO_ONLY = "audio_only"; + 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 audioOnly; + private boolean hasVideo; private boolean ended = false; @SuppressLint("SetJavaScriptEnabled") @@ -60,9 +60,9 @@ public class CallActivity extends WebViewActivity implements DcEventCenter.DcEve Bundle bundle = getIntent().getExtras(); assert bundle != null; - audioOnly = bundle.getBoolean(EXTRA_AUDIO_ONLY, false); + hasVideo = bundle.getBoolean(EXTRA_HAS_VIDEO, true); String hash = bundle.getString(EXTRA_HASH, ""); - String query = audioOnly? "?noOutgoingVideoInitially" : ""; + 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); @@ -172,7 +172,7 @@ public class CallActivity extends WebViewActivity implements DcEventCenter.DcEve @JavascriptInterface public void startCall(String payload) { try { - callId = rpc.placeOutgoingCall(accId, chatId, payload, !audioOnly); + 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 c78ef385e..3ef0e237f 100644 --- a/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java +++ b/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java @@ -18,29 +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, boolean audioOnly) { + 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, audioOnly); + startCall(activity, accId, chatId, hasVideo); }) .execute(); } - public static void startCall(Context context, int accId, int chatId, boolean audioOnly) { + 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_AUDIO_ONLY, audioOnly); + 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, boolean audioOnly) { + 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 { @@ -54,7 +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_AUDIO_ONLY, audioOnly); + 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/notifications/NotificationCenter.java b/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCenter.java index dbbdceeac..323862231 100644 --- a/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCenter.java +++ b/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCenter.java @@ -166,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, boolean audioOnly) { + 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) @@ -186,7 +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_AUDIO_ONLY, audioOnly); + intent.putExtra(CallActivity.EXTRA_HAS_VIDEO, hasVideo); intent.setPackage(context.getPackageName()); return TaskStackBuilder.create(context) .addNextIntentWithParentStack(chatIntent) @@ -430,12 +430,12 @@ public class NotificationCenter { Util.runOnAnyBackgroundThread(() -> { NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); DcContext dcContext = context.getDcAccounts().getAccount(accId); - boolean audioOnly; + boolean hasVideo; try { - audioOnly = !context.getRpc().callInfo(accId, callId).hasVideo; + hasVideo = context.getRpc().callInfo(accId, callId).hasVideo; } catch (RpcException e) { Log.e(TAG, "Rpc.callInfo() failed", e); - audioOnly = true; + hasVideo = false; } int chatId = dcContext.getMsg(callId).getChatId(); DcChat dcChat = dcContext.getChat(chatId); @@ -444,7 +444,7 @@ public class NotificationCenter { String notificationChannel = getCallNotificationChannel(notificationManager, chatData, name); PendingIntent declineCallIntent = getDeclineCallIntent(chatData, callId); - PendingIntent openCallIntent = getOpenCallIntent(chatData, callId, payload, false, audioOnly); + PendingIntent openCallIntent = getOpenCallIntent(chatData, callId, payload, false, hasVideo); NotificationCompat.Builder builder = new NotificationCompat.Builder(context, notificationChannel) .setSmallIcon(R.drawable.icon_notification) @@ -469,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, audioOnly)).build()); + getOpenCallIntent(chatData, callId, payload, true, hasVideo)).build()); Bitmap bitmap = getAvatar(dcChat); if (bitmap != null) { From 14f55ca6b1be89bbae1ef7ee46fedabac89f2550 Mon Sep 17 00:00:00 2001 From: adbenitez Date: Thu, 5 Feb 2026 17:25:20 +0100 Subject: [PATCH 29/29] prepare 2.40.0 --- CHANGELOG.md | 3 ++- build.gradle | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ccb31acd..426e5f680 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Delta Chat Android Changelog -## Unreleased +## v2.40.0 +2026-02 * Improve switch speed when changing profiles * Allow to switch profile when sharing or forwarding diff --git a/build.gradle b/build.gradle index 44b9ff39a..2907c985e 100644 --- a/build.gradle +++ b/build.gradle @@ -27,8 +27,8 @@ android { useLibrary 'org.apache.http.legacy' defaultConfig { - versionCode 740 - versionName "2.35.0" + versionCode 741 + versionName "2.40.0" applicationId "com.b44t.messenger" multiDexEnabled true