diff --git a/CHANGELOG-upstream.md b/CHANGELOG-upstream.md index e98854105..426e5f680 100644 --- a/CHANGELOG-upstream.md +++ b/CHANGELOG-upstream.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 @@ -12,13 +13,19 @@ * 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 * 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 -* Update to core 2.39.0 +* Fix mailto handling +* Fix layout problems inside in-chat apps +* Avoid crash when the app is minimized with profile switcher or reactions dialogs open +* Remove "trash icon" option from contact selection list when adding members to group +* Update to core 2.40.0 ## v2.35.0 2026-01 diff --git a/build.gradle b/build.gradle index 3147cd0c0..67b0fa447 100644 --- a/build.gradle +++ b/build.gradle @@ -33,8 +33,8 @@ android { useLibrary 'org.apache.http.legacy' defaultConfig { - versionCode 30000736 - versionName "2.36.0" + versionCode 30000737 + versionName "2.40.0" applicationId "chat.delta.lite" multiDexEnabled true diff --git a/jni/dc_wrapper.c b/jni/dc_wrapper.c index bffc41121..1bd4a07f8 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/jni/deltachat-core-rust b/jni/deltachat-core-rust index 8b2e88f45..5cdbc9d73 160000 --- a/jni/deltachat-core-rust +++ b/jni/deltachat-core-rust @@ -1 +1 @@ -Subproject commit 8b2e88f45a7576efa001e2b138a964d036f2f2de +Subproject commit 5cdbc9d736c7a2ae68a8080b54f6cd72f219b8ec diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index dd6bae671..c02237106 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -92,6 +92,7 @@ + diff --git a/src/main/assets/calls/index.html b/src/main/assets/calls/index.html index 96fbfcbd8..6b01902e9 100644 --- a/src/main/assets/calls/index.html +++ b/src/main/assets/calls/index.html @@ -1,6 +1,6 @@ - + - - - - + +
diff --git a/src/main/java/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. diff --git a/src/main/java/com/b44t/messenger/DcAccounts.java b/src/main/java/com/b44t/messenger/DcAccounts.java index c7e3c121c..27ec0a981 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"); } @@ -46,7 +46,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 637540eeb..6e00f1da1 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; @@ -196,7 +197,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"); @@ -236,28 +259,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/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..ff45edbae 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; @@ -127,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; } @@ -226,6 +229,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 +253,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 +322,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 +370,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/ConversationActivity.java b/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java index f1d89690c..bcf7f35e0 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java @@ -569,8 +569,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity } else if (itemId == R.id.menu_show_map) { WebxdcActivity.openMaps(this, chatId); return true; - } else if (itemId == R.id.menu_start_call) { - CallUtil.startCall(this, chatId); + } else if (itemId == R.id.menu_start_audio_call) { + CallUtil.startCall(this, chatId, false); + return true; + } else if (itemId == R.id.menu_start_video_call) { + CallUtil.startCall(this, chatId, true); return true; } else if (itemId == R.id.menu_all_media) { handleAllMedia(); diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java b/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java index 1cbce4a76..774e04004 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java @@ -891,7 +891,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/ConversationItem.java b/src/main/java/org/thoughtcrime/securesms/ConversationItem.java index b851ed8a8..dffda6132 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationItem.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationItem.java @@ -1000,9 +1000,9 @@ public class ConversationItem extends BaseConversationItem int chatId = messageRecord.getChatId(); if (!messageRecord.isOutgoing() && callInfo.state instanceof CallState.Alerting) { int callId = messageRecord.getId(); - CallUtil.openCall(getContext(), accId, chatId, callId, callInfo.sdpOffer); + CallUtil.openCall(getContext(), accId, chatId, callId, callInfo.sdpOffer, callInfo.hasVideo); } else { - CallUtil.startCall(getContext(), accId, chatId); + CallUtil.startCall(getContext(), accId, chatId, callInfo.hasVideo); } } } diff --git a/src/main/java/org/thoughtcrime/securesms/NewConversationActivity.java b/src/main/java/org/thoughtcrime/securesms/NewConversationActivity.java index 587737955..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,53 +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(); - } - } else if(scheme != null && scheme.startsWith("http")) { - Intent shareIntent = new Intent(this, ShareActivity.class); - shareIntent.putExtra(Intent.EXTRA_TEXT, uri.toString()); - startActivity(shareIntent); - finish(); - } - } - } - catch(Exception e) { - Log.e(TAG, "start activity from external 'mailto:' link failed", e); - } - } } @Override 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); + } } } }); diff --git a/src/main/java/org/thoughtcrime/securesms/ShareActivity.java b/src/main/java/org/thoughtcrime/securesms/ShareActivity.java index f661934f1..154f67cc9 100644 --- a/src/main/java/org/thoughtcrime/securesms/ShareActivity.java +++ b/src/main/java/org/thoughtcrime/securesms/ShareActivity.java @@ -104,26 +104,25 @@ 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)); - } - } else if (uri != null) { - streamExtras.add(uri); - } + } else if (uri != null) { + streamExtras.add(uri); } if (needsFilePermission(streamExtras)) { @@ -265,6 +264,7 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity implement } chatId = dcContext.createChatByContactId(contactId); + accId = dcContext.getAccountId(); } Intent composeIntent; if (accId != -1 && chatId != -1) { 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/accounts/AccountSelectionListFragment.java b/src/main/java/org/thoughtcrime/securesms/accounts/AccountSelectionListFragment.java index d33a14cf1..6cfed6fa1 100644 --- a/src/main/java/org/thoughtcrime/securesms/accounts/AccountSelectionListFragment.java +++ b/src/main/java/org/thoughtcrime/securesms/accounts/AccountSelectionListFragment.java @@ -47,21 +47,24 @@ 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; + private 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; } @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()) + 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) { @@ -179,6 +182,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); @@ -202,6 +206,7 @@ public class AccountSelectionListFragment extends DialogFragment implements DcEv private void onDeleteProfile(int accountId) { AccountSelectionListFragment.this.dismiss(); + ConversationListActivity activity = (ConversationListActivity)requireActivity(); DcAccounts accounts = DcHelper.getAccounts(activity); Rpc rpc = DcHelper.getRpc(activity); @@ -254,6 +259,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/calls/CallActivity.java b/src/main/java/org/thoughtcrime/securesms/calls/CallActivity.java index d20eb88a7..b7da6e461 100644 --- a/src/main/java/org/thoughtcrime/securesms/calls/CallActivity.java +++ b/src/main/java/org/thoughtcrime/securesms/calls/CallActivity.java @@ -43,12 +43,14 @@ public class CallActivity extends WebViewActivity implements DcEventCenter.DcEve public static final String EXTRA_CHAT_ID = "chat_id"; public static final String EXTRA_CALL_ID = "call_id"; public static final String EXTRA_HASH = "hash"; + public static final String EXTRA_HAS_VIDEO = "has_video"; private DcContext dcContext; private Rpc rpc; private int accId; private int chatId; private int callId; + private boolean hasVideo; private boolean ended = false; @SuppressLint("SetJavaScriptEnabled") @@ -58,7 +60,9 @@ public class CallActivity extends WebViewActivity implements DcEventCenter.DcEve Bundle bundle = getIntent().getExtras(); assert bundle != null; + hasVideo = bundle.getBoolean(EXTRA_HAS_VIDEO, true); String hash = bundle.getString(EXTRA_HASH, ""); + String query = hasVideo? "" : "?noOutgoingVideoInitially"; accId = bundle.getInt(EXTRA_ACCOUNT_ID, -1); chatId = bundle.getInt(EXTRA_CHAT_ID, 0); callId = bundle.getInt(EXTRA_CALL_ID, 0); @@ -94,7 +98,7 @@ public class CallActivity extends WebViewActivity implements DcEventCenter.DcEve .withPermanentDenialDialog(getString(R.string.perm_explain_access_to_camera_denied)) .onAllGranted(() -> { String url = "file:///android_asset/calls/index.html"; - webView.loadUrl(url + hash); + webView.loadUrl(url + query + hash); }).onAnyDenied(this::finish) .execute(); } @@ -168,7 +172,7 @@ public class CallActivity extends WebViewActivity implements DcEventCenter.DcEve @JavascriptInterface public void startCall(String payload) { try { - callId = rpc.placeOutgoingCall(accId, chatId, payload); + callId = rpc.placeOutgoingCall(accId, chatId, payload, hasVideo); } catch (RpcException e) { Log.e(TAG, "Error", e); } diff --git a/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java b/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java index f84e2385b..3ef0e237f 100644 --- a/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java +++ b/src/main/java/org/thoughtcrime/securesms/calls/CallUtil.java @@ -18,28 +18,29 @@ import java.nio.charset.StandardCharsets; public class CallUtil { private static final String TAG = CallUtil.class.getSimpleName(); - public static void startCall(Activity activity, int chatId) { + public static void startCall(Activity activity, int chatId, boolean hasVideo) { Permissions.with(activity) .request(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO) .ifNecessary() .withPermanentDenialDialog(activity.getString(R.string.perm_explain_access_to_camera_denied)) .onAllGranted(() -> { int accId = DcHelper.getContext(activity).getAccountId(); - startCall(activity, accId, chatId); + startCall(activity, accId, chatId, hasVideo); }) .execute(); } - public static void startCall(Context context, int accId, int chatId) { + public static void startCall(Context context, int accId, int chatId, boolean hasVideo) { Intent intent = new Intent(context, CallActivity.class); intent.setAction(Intent.ACTION_VIEW); intent.putExtra(CallActivity.EXTRA_ACCOUNT_ID, accId); intent.putExtra(CallActivity.EXTRA_CHAT_ID, chatId); + intent.putExtra(CallActivity.EXTRA_HAS_VIDEO, hasVideo); intent.putExtra(CallActivity.EXTRA_HASH, "#startCall"); context.startActivity(intent); } - public static void openCall(Context context, int accId, int chatId, int callId, String payload) { + public static void openCall(Context context, int accId, int chatId, int callId, String payload, boolean hasVideo) { String base64 = Base64.encodeToString(payload.getBytes(StandardCharsets.UTF_8), Base64.NO_WRAP); String hash = ""; try { @@ -53,6 +54,7 @@ public class CallUtil { intent.putExtra(CallActivity.EXTRA_ACCOUNT_ID, accId); intent.putExtra(CallActivity.EXTRA_CHAT_ID, chatId); intent.putExtra(CallActivity.EXTRA_CALL_ID, callId); + intent.putExtra(CallActivity.EXTRA_HAS_VIDEO, hasVideo); intent.putExtra(CallActivity.EXTRA_HASH, hash); context.startActivity(intent); } diff --git a/src/main/java/org/thoughtcrime/securesms/components/CallItemView.java b/src/main/java/org/thoughtcrime/securesms/components/CallItemView.java index a66f54790..1cc06bec5 100644 --- a/src/main/java/org/thoughtcrime/securesms/components/CallItemView.java +++ b/src/main/java/org/thoughtcrime/securesms/components/CallItemView.java @@ -71,6 +71,8 @@ public class CallItemView extends FrameLayout { title.setText(isOutgoing? R.string.outgoing_call : R.string.incoming_call); } + icon.setImageResource(callInfo.hasVideo? R.drawable.ic_videocam_white_24dp : R.drawable.baseline_call_24); + int[] attrs; if (isOutgoing) { attrs = new int[]{ diff --git a/src/main/java/org/thoughtcrime/securesms/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); } 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; diff --git a/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCenter.java b/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCenter.java index 46794435f..ef685cfb9 100644 --- a/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCenter.java +++ b/src/main/java/org/thoughtcrime/securesms/notifications/NotificationCenter.java @@ -61,6 +61,8 @@ import java.util.HashMap; import java.util.List; import java.util.concurrent.TimeUnit; +import chat.delta.rpc.RpcException; + public class NotificationCenter { private static final String TAG = NotificationCenter.class.getSimpleName(); @NonNull private final ApplicationContext context; @@ -164,7 +166,7 @@ public class NotificationCenter { return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | IntentUtils.FLAG_MUTABLE()); } - public PendingIntent getOpenCallIntent(ChatData chatData, int callId, String payload, boolean autoAccept) { + public PendingIntent getOpenCallIntent(ChatData chatData, int callId, String payload, boolean autoAccept, boolean hasVideo) { final Intent chatIntent = new Intent(context, ConversationActivity.class) .putExtra(ConversationActivity.ACCOUNT_ID_EXTRA, chatData.accountId) .putExtra(ConversationActivity.CHAT_ID_EXTRA, chatData.chatId) @@ -184,6 +186,7 @@ public class NotificationCenter { intent.putExtra(CallActivity.EXTRA_CHAT_ID, chatData.chatId); intent.putExtra(CallActivity.EXTRA_CALL_ID, callId); intent.putExtra(CallActivity.EXTRA_HASH, hash); + intent.putExtra(CallActivity.EXTRA_HAS_VIDEO, hasVideo); intent.setPackage(context.getPackageName()); return TaskStackBuilder.create(context) .addNextIntentWithParentStack(chatIntent) @@ -427,6 +430,13 @@ public class NotificationCenter { Util.runOnAnyBackgroundThread(() -> { NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); DcContext dcContext = context.getDcAccounts().getAccount(accId); + boolean hasVideo; + try { + hasVideo = context.getRpc().callInfo(accId, callId).hasVideo; + } catch (RpcException e) { + Log.e(TAG, "Rpc.callInfo() failed", e); + hasVideo = false; + } int chatId = dcContext.getMsg(callId).getChatId(); DcChat dcChat = dcContext.getChat(chatId); String name = dcChat.getName(); @@ -434,7 +444,7 @@ public class NotificationCenter { String notificationChannel = getCallNotificationChannel(notificationManager, chatData, name); PendingIntent declineCallIntent = getDeclineCallIntent(chatData, callId); - PendingIntent openCallIntent = getOpenCallIntent(chatData, callId, payload, false); + PendingIntent openCallIntent = getOpenCallIntent(chatData, callId, payload, false, hasVideo); NotificationCompat.Builder builder = new NotificationCompat.Builder(context, notificationChannel) .setSmallIcon(R.drawable.icon_notification) @@ -459,7 +469,7 @@ public class NotificationCenter { new NotificationCompat.Action.Builder( R.drawable.ic_videocam_white_24dp, context.getString(R.string.answer_call), - getOpenCallIntent(chatData, callId, payload, true)).build()); + getOpenCallIntent(chatData, callId, payload, true, hasVideo)).build()); Bitmap bitmap = getAvatar(dcChat); if (bitmap != null) { diff --git a/src/main/java/org/thoughtcrime/securesms/reactions/ReactionsDetailsFragment.java b/src/main/java/org/thoughtcrime/securesms/reactions/ReactionsDetailsFragment.java index 7cc1a104e..29225a944 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(); 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; }); diff --git a/src/main/res/layout/call_item_view.xml b/src/main/res/layout/call_item_view.xml index fbaef931e..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/ic_videocam_white_24dp" /> diff --git a/src/main/res/menu/conversation.xml b/src/main/res/menu/conversation.xml index 636436bcc..879e60b2e 100644 --- a/src/main/res/menu/conversation.xml +++ b/src/main/res/menu/conversation.xml @@ -26,9 +26,22 @@ app:showAsAction="always"/> + android:title="@string/start_call" + app:showAsAction="always" + android:icon="@drawable/baseline_call_24"> + + + + + 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 affdf3993..015de91b7 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 @@ -399,6 +402,9 @@ Appel rejeté Appel annulé Appel manqué + + %1$s, %2$s + Êtes-vous sûr de vouloir quitter la discussion ? @@ -658,7 +664,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. @@ -672,6 +678,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 @@ -947,7 +957,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. @@ -997,7 +1007,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. @@ -1147,9 +1157,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. @@ -1164,11 +1182,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 e51e962b9..668c59b15 100644 --- a/src/main/res/values-it/strings.xml +++ b/src/main/res/values-it/strings.xml @@ -1020,6 +1020,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. diff --git a/src/main/res/values/attrs.xml b/src/main/res/values/attrs.xml index 5ddd252fd..241eadb24 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/strings.xml b/src/main/res/values/strings.xml index be2e72152..b0ab9b9b1 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -380,6 +380,8 @@ Call + Audio Call + Video Call Answer @@ -1088,8 +1090,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. diff --git a/src/main/res/values/themes.xml b/src/main/res/values/themes.xml index 47e807318..447962128 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/def_primary + @color/black @color/grey_700 @color/grey_100 @@ -243,6 +244,7 @@ @drawable/ic_reply_white_24dp @color/def_primary + @color/white @color/grey_100 ?icon_tint